From a689417aed1ac54e94395ee9106358436825ca96 Mon Sep 17 00:00:00 2001 From: Dominic Ferrando Date: Fri, 26 Jun 2026 13:03:54 -0400 Subject: [PATCH] Some cleanup and add server timing --- .gitignore | 2 ++ apps/api/package.json | 1 + apps/api/src/env.ts | 8 ++++---- apps/api/src/server.ts | 25 ++++++++++++------------- bun.lock | 3 +++ 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index a14702c..57be201 100644 --- a/.gitignore +++ b/.gitignore @@ -17,8 +17,10 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json # dotenv environment variable files .env +.env.development .env.development.local .env.test.local +.env.production .env.production.local .env.local diff --git a/apps/api/package.json b/apps/api/package.json index 6429e4f..7c8884e 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -17,6 +17,7 @@ "@blade-and-brawn/calculator": "workspace:*", "@blade-and-brawn/commerce": "workspace:*", "@blade-and-brawn/domain": "workspace:*", + "@elysia/server-timing": "^1.4.1", "@elysiajs/cors": "^1.4.2", "elysia": "^1.4.29", "ml-levenberg-marquardt": "^5.0.1", diff --git a/apps/api/src/env.ts b/apps/api/src/env.ts index 9d7fc3a..03f3c0d 100644 --- a/apps/api/src/env.ts +++ b/apps/api/src/env.ts @@ -4,7 +4,7 @@ function requireEnv(key: string): string { return val; } -function optionEnv(key: string, fallback: string): string { +function optionEnv(key: string, fallback: string = ""): string { const val = Bun.env[key]; if (!val) return fallback; return val; @@ -16,7 +16,7 @@ export const env = { WEBFLOW_SITE_ID: requireEnv("WEBFLOW_SITE_ID"), WEBFLOW_COLLECTION_ID: requireEnv("WEBFLOW_COLLECTION_ID"), WEBFLOW_AUTH: requireEnv("WEBFLOW_AUTH"), - WEBFLOW_WEBHOOK_SECRET: requireEnv("WEBFLOW_WEBHOOK_SECRET"), - LOG_LEVEL: optionEnv("LOG_LEVEL", "info"), - NODE_ENV: optionEnv("NODE_ENV", "development") + WEBFLOW_WEBHOOK_SECRET: optionEnv("WEBFLOW_WEBHOOK_SECRET"), + NODE_ENV: optionEnv("NODE_ENV", "development"), + LOG_LEVEL: optionEnv("LOG_LEVEL", "info") }; diff --git a/apps/api/src/server.ts b/apps/api/src/server.ts index 06454a8..a1f2169 100644 --- a/apps/api/src/server.ts +++ b/apps/api/src/server.ts @@ -23,10 +23,11 @@ import zipcodesUs from "zipcodes-us"; import z from "zod"; import pino from "pino"; import { env } from "./env"; +import serverTiming from "@elysia/server-timing"; const log = pino({ level: env.LOG_LEVEL, - transport: env.NODE_ENV === "development" + transport: env.NODE_ENV != "production" ? { target: "pino-pretty" } : undefined, }); @@ -54,10 +55,7 @@ const productSyncer = new ProductSyncer(printful, webflow, log); // ELYSIA // ----------- export const app = new Elysia() - .derive(() => ({ - startTime: Date.now(), - requestId: crypto.randomUUID(), - })) + .use(serverTiming()) .use( cors({ origin: [ @@ -83,28 +81,29 @@ export const app = new Elysia() WebflowError, }) - .onError(({ code, error, startTime, requestId }) => { - const duration = Date.now() - (startTime ?? Date.now()); + .onError(({ code, error }) => { switch (code) { case "PrintfulError": case "WebflowError": log.error( - { requestId, duration, upstreamStatus: error.status, payload: error.payload }, + { upstreamStatus: error.status, payload: error.payload }, error.message, ); return status(502, { error: error.message }); + case "NOT_FOUND": + return status(404, { error: "Not found" }); + case "VALIDATION": + return status(400, { error: error.message }); default: - log.error({ requestId, duration, err: error }, "unhandled error"); + log.error({ err: error }, "unhandled error"); } }) - .onAfterHandle(({ request, set, startTime, requestId }) => { + .onAfterHandle(({ request, set }) => { log.info({ - requestId, method: request.method, path: new URL(request.url).pathname, - status: set.status ?? 200, - duration: Date.now() - startTime, + status: set.status ?? 200 }, "request"); }) diff --git a/bun.lock b/bun.lock index 7ec9ea3..61cfcf2 100644 --- a/bun.lock +++ b/bun.lock @@ -15,6 +15,7 @@ "@blade-and-brawn/calculator": "workspace:*", "@blade-and-brawn/commerce": "workspace:*", "@blade-and-brawn/domain": "workspace:*", + "@elysia/server-timing": "^1.4.1", "@elysiajs/cors": "^1.4.2", "elysia": "^1.4.29", "ml-levenberg-marquardt": "^5.0.1", @@ -88,6 +89,8 @@ "@elysia/eden": ["@elysia/eden@1.4.10", "", { "peerDependencies": { "elysia": ">=1.4.19" } }, "sha512-vcZXQcW6wZj6rhTxaiTkuCbVuS/yAJQ9jqCM6b83a5hu99F5Aj3HOyWXL17iod2Rz+pJpYsQGX0XaeoCsMpw2g=="], + "@elysia/server-timing": ["@elysia/server-timing@1.4.1", "", { "peerDependencies": { "elysia": ">= 1.4.0" } }, "sha512-+NDGhslxN0HZuyT8o4dt+hgib9bzsMuvxTE5bPrDhFFRl1duCNosseW3wE76pmwle8+m9+1aOeZ28mZAv51ggQ=="], + "@elysiajs/cors": ["@elysiajs/cors@1.4.2", "", { "peerDependencies": { "elysia": ">= 1.4.0" } }, "sha512-FTCcbH35brTLigF1W7BYySRZomgI/dBEMK9BgK9RP9Nez7zmpGh4koL/Yr1BFv8nYz7CfhRvcM8d/c+XnwMaVQ=="], "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="],