From a9751e5619a1e87859b984b3cc8feabd071107f1 Mon Sep 17 00:00:00 2001 From: Paul Mulligan Date: Thu, 9 Apr 2026 17:26:48 -0400 Subject: [PATCH 1/2] feat: add request ID middleware to generated project templates Co-Authored-By: Claude Opus 4.6 (1M context) --- scripts/setup-project.sh | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/scripts/setup-project.sh b/scripts/setup-project.sh index a42ada7..5168ca9 100644 --- a/scripts/setup-project.sh +++ b/scripts/setup-project.sh @@ -172,6 +172,7 @@ if [[ "$PLATFORM" == "cloudflare" ]]; then import { Hono } from 'hono'; import { cors } from 'hono/cors'; import { logger } from 'hono/logger'; +import { requestId } from 'hono/request-id'; import { secureHeaders } from 'hono/secure-headers'; type Bindings = { @@ -187,9 +188,14 @@ const app = new Hono<{ Bindings: Bindings }>(); app.use('*', logger()); app.use('*', cors()); app.use('*', secureHeaders()); +app.use('*', requestId()); app.get('/health', (c) => { - return c.json({ status: 'ok', timestamp: new Date().toISOString() }); + return c.json({ + status: 'ok', + requestId: c.get('requestId'), + timestamp: new Date().toISOString(), + }); }); app.get('/', (c) => { @@ -203,6 +209,7 @@ else import { Hono } from 'hono'; import { cors } from 'hono/cors'; import { logger } from 'hono/logger'; +import { requestId } from 'hono/request-id'; import { secureHeaders } from 'hono/secure-headers'; import { serve } from '@hono/node-server'; @@ -211,9 +218,14 @@ const app = new Hono(); app.use('*', logger()); app.use('*', cors()); app.use('*', secureHeaders()); +app.use('*', requestId()); app.get('/health', (c) => { - return c.json({ status: 'ok', timestamp: new Date().toISOString() }); + return c.json({ + status: 'ok', + requestId: c.get('requestId'), + timestamp: new Date().toISOString(), + }); }); app.get('/', (c) => { @@ -297,10 +309,17 @@ TSEOF write_file "$API_DIR/tests/unit/health.test.ts" << 'HTEOF' import { describe, it, expect } from 'vitest'; import { Hono } from 'hono'; +import { requestId } from 'hono/request-id'; describe('Health endpoint', () => { const app = new Hono(); - app.get('/health', (c) => c.json({ status: 'ok' })); + app.use('*', requestId()); + app.get('/health', (c) => + c.json({ + status: 'ok', + requestId: c.get('requestId'), + }), + ); it('should return ok status', async () => { const res = await app.request('/health'); @@ -308,6 +327,19 @@ describe('Health endpoint', () => { const body = await res.json(); expect(body.status).toBe('ok'); }); + + it('should return a requestId', async () => { + const res = await app.request('/health'); + const body = await res.json(); + expect(body.requestId).toBeDefined(); + expect(typeof body.requestId).toBe('string'); + expect(body.requestId.length).toBeGreaterThan(0); + }); + + it('should include X-Request-Id response header', async () => { + const res = await app.request('/health'); + expect(res.headers.get('X-Request-Id')).toBeDefined(); + }); }); HTEOF From 7bf65744e41ff467eeb3aa8c262e8b19090dc90e Mon Sep 17 00:00:00 2001 From: Paul Mulligan Date: Thu, 9 Apr 2026 17:31:37 -0400 Subject: [PATCH 2/2] fix: use correct null check for X-Request-Id header assertion Co-Authored-By: Claude Opus 4.6 (1M context) --- scripts/setup-project.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/setup-project.sh b/scripts/setup-project.sh index 5168ca9..82faf79 100644 --- a/scripts/setup-project.sh +++ b/scripts/setup-project.sh @@ -338,7 +338,7 @@ describe('Health endpoint', () => { it('should include X-Request-Id response header', async () => { const res = await app.request('/health'); - expect(res.headers.get('X-Request-Id')).toBeDefined(); + expect(res.headers.get('X-Request-Id')).not.toBeNull(); }); }); HTEOF