@spfn/core 0.2.0-beta.2 → 0.2.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -162,14 +162,46 @@ var RouteBuilder = class _RouteBuilder {
162
162
  /**
163
163
  * Define handler function
164
164
  *
165
+ * Response type is automatically inferred from the return value.
166
+ * Use helper methods like `c.created()`, `c.paginated()` for proper type inference.
167
+ *
165
168
  * @example
166
169
  * ```ts
170
+ * // Direct return - type inferred from data
167
171
  * route.get('/users/:id')
168
172
  * .input({ params: Type.Object({ id: Type.String() }) })
169
173
  * .handler(async (c) => {
170
174
  * const { params } = await c.data();
171
- * const user = await getUser(params.id);
172
- * return user; // Type inferred!
175
+ * return await getUser(params.id); // Type: User
176
+ * })
177
+ *
178
+ * // Using c.created() - returns data with 201 status, type preserved
179
+ * route.post('/users')
180
+ * .input({ body: Type.Object({ name: Type.String() }) })
181
+ * .handler(async (c) => {
182
+ * const { body } = await c.data();
183
+ * return c.created(await createUser(body)); // Type: User
184
+ * })
185
+ *
186
+ * // Using c.paginated() - returns PaginatedResult<T>
187
+ * route.get('/users')
188
+ * .handler(async (c) => {
189
+ * const users = await getUsers();
190
+ * return c.paginated(users, 1, 20, 100); // Type: PaginatedResult<User>
191
+ * })
192
+ *
193
+ * // Using c.noContent() - returns void
194
+ * route.delete('/users/:id')
195
+ * .handler(async (c) => {
196
+ * await deleteUser(params.id);
197
+ * return c.noContent(); // Type: void
198
+ * })
199
+ *
200
+ * // Using c.json() - returns Response (type inference lost)
201
+ * // Use only when you need custom status codes not covered by helpers
202
+ * route.get('/custom')
203
+ * .handler(async (c) => {
204
+ * return c.json({ data }, 418); // Type: Response
173
205
  * })
174
206
  * ```
175
207
  */
@@ -336,12 +368,19 @@ function registerRoute(app, name, routeDef, namedMiddlewares) {
336
368
  return;
337
369
  }
338
370
  const wrappedHandler = async (c) => {
339
- const context = await createRouteBuilderContext(c, input || {});
371
+ const { context, responseMeta } = await createRouteBuilderContext(c, input || {});
340
372
  const result = await handler(context);
341
373
  if (result instanceof Response) {
342
374
  return result;
343
375
  }
344
- return c.json(result);
376
+ if (responseMeta.isEmpty) {
377
+ return c.body(null, responseMeta.status);
378
+ }
379
+ const hasCustomHeaders = Object.keys(responseMeta.headers).length > 0;
380
+ if (hasCustomHeaders) {
381
+ return c.json(result, responseMeta.status, responseMeta.headers);
382
+ }
383
+ return c.json(result, responseMeta.status);
345
384
  };
346
385
  const allMiddlewares = [];
347
386
  const registeredNames = /* @__PURE__ */ new Set();
@@ -398,38 +437,47 @@ async function createRouteBuilderContext(c, input) {
398
437
  const rawBody = await parseJsonBody(c);
399
438
  body = validateField(input.body, rawBody, "request body");
400
439
  }
401
- return {
402
- data: async () => ({
403
- params,
404
- query,
405
- body,
406
- headers,
407
- cookies
408
- }),
440
+ let cachedData = null;
441
+ const responseMeta = {
442
+ status: 200,
443
+ headers: {},
444
+ isEmpty: false
445
+ };
446
+ const context = {
447
+ data: async () => {
448
+ if (!cachedData) {
449
+ cachedData = { params, query, body, headers, cookies };
450
+ }
451
+ return cachedData;
452
+ },
409
453
  json: (data, status, resHeaders) => {
410
454
  return c.json(data, status, resHeaders);
411
455
  },
412
456
  created: (data, location) => {
413
- const resHeaders = {};
457
+ responseMeta.status = 201;
414
458
  if (location) {
415
- resHeaders["Location"] = location;
459
+ responseMeta.headers["Location"] = location;
416
460
  }
417
- return c.json(data, 201, resHeaders);
461
+ return data;
418
462
  },
419
463
  accepted: (data) => {
464
+ responseMeta.status = 202;
420
465
  if (data === void 0) {
421
- return c.body(null, 202);
466
+ responseMeta.isEmpty = true;
467
+ return void 0;
422
468
  }
423
- return c.json(data, 202);
469
+ return data;
424
470
  },
425
471
  noContent: () => {
426
- return c.body(null, 204);
472
+ responseMeta.status = 204;
473
+ responseMeta.isEmpty = true;
427
474
  },
428
475
  notModified: () => {
429
- return c.body(null, 304);
476
+ responseMeta.status = 304;
477
+ responseMeta.isEmpty = true;
430
478
  },
431
479
  paginated: (data, page, limit, total) => {
432
- return c.json({
480
+ return {
433
481
  items: data,
434
482
  pagination: {
435
483
  page,
@@ -437,13 +485,14 @@ async function createRouteBuilderContext(c, input) {
437
485
  total,
438
486
  totalPages: Math.ceil(total / limit)
439
487
  }
440
- }, 200);
488
+ };
441
489
  },
442
490
  redirect: (url, status) => {
443
491
  return c.redirect(url, status);
444
492
  },
445
493
  raw: c
446
494
  };
495
+ return { context, responseMeta };
447
496
  }
448
497
 
449
498
  // src/route/define-middleware.ts
@@ -502,6 +551,6 @@ function isHttpMethod(value) {
502
551
  var Nullable = (schema) => Type.Union([schema, Type.Null()]);
503
552
  var OptionalNullable = (schema) => Type.Optional(Type.Union([schema, Type.Null()]));
504
553
 
505
- export { Nullable, OptionalNullable, RouteBuilder, defineMiddleware, defineMiddlewareFactory, defineRouter, isHttpMethod, registerRoutes, route };
554
+ export { Nullable, OptionalNullable, defineMiddleware, defineMiddlewareFactory, defineRouter, isHttpMethod, registerRoutes, route };
506
555
  //# sourceMappingURL=index.js.map
507
556
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/route/route-builder.ts","../../src/route/router.ts","../../src/route/validation.ts","../../src/route/register-routes.ts","../../src/route/define-middleware.ts","../../src/route/helpers.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Route Builder\n *\n * Provides tRPC-style chainable API for route definition\n */\n\nimport type { MiddlewareHandler } from 'hono';\nimport type { NamedMiddleware } from './define-middleware';\nimport type { RouteInput } from './route-input';\nimport type { RouteBuilderContext } from './context';\nimport type { HttpMethod } from './types';\n\n/**\n * Route handler function\n */\nexport type RouteHandlerFn<\n TInput extends RouteInput = RouteInput,\n TInterceptor extends RouteInput = {},\n TResponse = unknown\n> = (c: RouteBuilderContext<TInput, TInterceptor>) => Response | Promise<Response> | TResponse | Promise<TResponse>;\n\n/**\n * Route definition result\n *\n * Contains all information needed for type inference and registration\n */\nexport type RouteDef<\n TInput extends RouteInput = RouteInput,\n TInterceptor extends RouteInput = {},\n TResponse = unknown\n> = {\n method?: HttpMethod;\n path?: string;\n input?: TInput;\n interceptor?: TInterceptor;\n middlewares?: (MiddlewareHandler | NamedMiddleware<string>)[];\n skipMiddlewares?: string[] | '*';\n handler: RouteHandlerFn<TInput, TInterceptor, TResponse>;\n\n // Type inference helpers\n _input: TInput;\n _interceptor: TInterceptor;\n _response: TResponse;\n};\n\n/**\n * Route builder with chainable API (tRPC-style)\n */\nexport class RouteBuilder<\n TInput extends RouteInput = {},\n TInterceptor extends RouteInput = {},\n TResponse = never\n>\n{\n public _method?: HttpMethod;\n public _path?: string;\n public _input?: TInput;\n public _interceptor?: TInterceptor;\n public _middlewares?: (MiddlewareHandler | NamedMiddleware<string>)[];\n public _skipMiddlewares?: string[] | '*';\n\n /**\n * Create a new RouteBuilder with copied properties and optional overrides\n */\n private clone<\n TNewInput extends RouteInput = TInput,\n TNewInterceptor extends RouteInput = TInterceptor\n >(\n overrides?: Partial<{\n input: TNewInput;\n interceptor: TNewInterceptor;\n middlewares: (MiddlewareHandler | NamedMiddleware<string>)[];\n skipMiddlewares: string[] | '*';\n }>\n ): RouteBuilder<TNewInput, TNewInterceptor, TResponse>\n {\n const builder = new RouteBuilder<TNewInput, TNewInterceptor, TResponse>();\n builder._method = this._method;\n builder._path = this._path;\n builder._input = (overrides?.input ?? this._input) as TNewInput | undefined;\n builder._interceptor = (overrides?.interceptor ?? this._interceptor) as TNewInterceptor | undefined;\n builder._middlewares = overrides?.middlewares ?? this._middlewares;\n builder._skipMiddlewares = overrides?.skipMiddlewares ?? this._skipMiddlewares;\n return builder;\n }\n\n /**\n * Define input schemas\n *\n * @example\n * ```ts\n * route.get('/users/:id')\n * .input({\n * params: Type.Object({ id: Type.String() }),\n * query: Type.Object({ page: Type.Number() }),\n * headers: Type.Object({ authorization: Type.String() })\n * })\n * .handler(async (c) => {\n * const { params, query, headers } = await c.data();\n * // params = { id: string }\n * // query = { page: number }\n * // headers = { authorization: string }\n * })\n * ```\n */\n input<TNewInput extends RouteInput>(input: TNewInput): RouteBuilder<TNewInput, TInterceptor, TResponse>\n {\n return this.clone({ input });\n }\n\n /**\n * Define fields injected by interceptors\n *\n * These fields are:\n * - Available in the handler (merged with input)\n * - Excluded from client types (codegen uses only input)\n * - Not validated by route input schema (injected by middleware)\n *\n * Use this when middleware/interceptors add fields to the request\n * before it reaches the handler.\n *\n * @example\n * ```ts\n * // Auth interceptor injects crypto key fields\n * route.post('/_auth/login')\n * .input({\n * body: Type.Object({\n * email: Type.String(),\n * password: Type.String()\n * })\n * })\n * .interceptor({\n * body: Type.Object({\n * publicKey: Type.String(),\n * keyId: Type.String(),\n * fingerprint: Type.String()\n * })\n * })\n * .handler(async (c) => {\n * const { body } = await c.data();\n * // body type: { email, password, publicKey, keyId, fingerprint }\n * // Client only sees: { email, password }\n * return loginService(body);\n * });\n * ```\n */\n interceptor<TNewInterceptor extends RouteInput>(\n interceptor: TNewInterceptor\n ): RouteBuilder<TInput, TNewInterceptor, TResponse>\n {\n return this.clone({ interceptor });\n }\n\n /**\n * Add middlewares to the route\n *\n * Accepts both regular middleware handlers and named middlewares (NamedMiddleware).\n * Named middlewares that are already registered globally will be automatically\n * deduplicated to prevent double execution.\n *\n * @example\n * ```ts\n * import { authenticate } from '@spfn/auth/server/middleware';\n *\n * // With NamedMiddleware (auto-deduped if registered globally)\n * route.get('/users')\n * .use([authenticate, RateLimitMiddleware()])\n *\n * // With regular middleware handlers\n * route.get('/users')\n * .use([AuthMiddleware(), RateLimitMiddleware()])\n * ```\n */\n middleware(middlewares: (MiddlewareHandler | NamedMiddleware<string>)[]): RouteBuilder<TInput, TInterceptor, TResponse>\n {\n return this.clone({ middlewares });\n }\n\n /**\n * Add middlewares to the route (alias for `.middleware()`)\n *\n * Accepts both regular middleware handlers and named middlewares (NamedMiddleware).\n * Named middlewares that are already registered globally will be automatically\n * deduplicated to prevent double execution.\n *\n * @example\n * ```ts\n * import { authenticate } from '@spfn/auth/server/middleware';\n *\n * // With NamedMiddleware (auto-deduped if registered globally)\n * route.get('/users')\n * .use([authenticate, RateLimitMiddleware()])\n *\n * // With regular middleware handlers\n * route.get('/users')\n * .use([AuthMiddleware(), RateLimitMiddleware()])\n * ```\n */\n use(middlewares: (MiddlewareHandler | NamedMiddleware<string>)[]): RouteBuilder<TInput, TInterceptor, TResponse>\n {\n return this.middleware(middlewares);\n }\n\n /**\n * Skip server-level named middlewares\n *\n * Useful for public endpoints that should bypass auth or rate limiting\n *\n * @param middlewareNames - Array of middleware names to skip, or '*' to skip all\n *\n * @example\n * ```ts\n * // Skip specific middlewares\n * route.get('/health')\n * .skip(['auth', 'rateLimit'])\n * .handler(async (c) => c.json({ status: 'ok' }));\n *\n * // Skip only auth (still apply rate limiting)\n * route.get('/public-data')\n * .skip(['auth'])\n * .handler(async (c) => { ... });\n *\n * // Skip all middlewares\n * route.get('/public-health')\n * .skip('*')\n * .handler(async (c) => c.json({ status: 'ok' }));\n * ```\n */\n skip(middlewareNames: string[] | '*'): RouteBuilder<TInput, TInterceptor, TResponse>\n {\n return this.clone({ skipMiddlewares: middlewareNames });\n }\n\n /**\n * Define handler function\n *\n * @example\n * ```ts\n * route.get('/users/:id')\n * .input({ params: Type.Object({ id: Type.String() }) })\n * .handler(async (c) => {\n * const { params } = await c.data();\n * const user = await getUser(params.id);\n * return user; // Type inferred!\n * })\n * ```\n */\n handler<THandlerResponse>(\n fn: RouteHandlerFn<TInput, TInterceptor, THandlerResponse>\n ): RouteDef<TInput, TInterceptor, THandlerResponse>\n {\n return {\n method: this._method,\n path: this._path,\n input: this._input,\n interceptor: this._interceptor,\n middlewares: this._middlewares,\n skipMiddlewares: this._skipMiddlewares,\n handler: fn,\n _input: {} as TInput,\n _interceptor: {} as TInterceptor,\n _response: {} as THandlerResponse,\n };\n }\n}\n\n/**\n * Create a route definition with HTTP method shortcuts\n */\nfunction createMethodRoute(method: HttpMethod): (path: string) => RouteBuilder\n{\n return (path: string) =>\n {\n const builder = new RouteBuilder();\n builder._method = method;\n builder._path = path;\n return builder;\n };\n}\n\n/**\n * Route builder entry point\n *\n * @example\n * ```ts\n * // GET request\n * export const getUser = route.get('/users/:id')\n * .input({ params: Type.Object({ id: Type.String() }) })\n * .handler(async (c) => {\n * const { params } = await c.data();\n * return await db.user.findUnique({ where: { id: params.id } });\n * });\n *\n * // POST request\n * export const createUser = route.post('/users')\n * .input({ body: Type.Object({ name: Type.String(), email: Type.String() }) })\n * .handler(async (c) => {\n * const { body } = await c.data();\n * return c.created(await db.user.create({ data: body }));\n * });\n * ```\n */\nexport const route = {\n get: createMethodRoute('GET'),\n post: createMethodRoute('POST'),\n put: createMethodRoute('PUT'),\n patch: createMethodRoute('PATCH'),\n delete: createMethodRoute('DELETE'),\n};","/**\n * Router Definition\n *\n * Provides router composition and middleware management\n */\n\nimport type { NamedMiddleware } from './define-middleware';\nimport type { RouteDef } from './route-builder';\n\n/**\n * Router definition - holds all routes\n */\nexport interface Router<TRoutes extends Record<string, RouteDef<any, any, any> | Router<any>>> {\n routes: TRoutes;\n _routes: TRoutes;\n _packageRouters: Router<any>[];\n _globalMiddlewares: NamedMiddleware<string>[];\n\n /**\n * Register package routers (type-hidden)\n *\n * Package routes are:\n * - Recognized by RPC proxy and backend\n * - NOT exposed in client types (use package's own API like authApi, cmsApi)\n *\n * @example\n * ```ts\n * import { authRouter } from '@spfn/auth/server';\n * import { cmsAppRouter } from '@spfn/cms/server';\n *\n * export const appRouter = defineRouter({\n * getRoot,\n * getHealth,\n * })\n * .packages([authRouter, cmsAppRouter]);\n *\n * // Client usage:\n * // api.getRoot.call({}) - app routes\n * // authApi.login.call({}) - package API\n * ```\n */\n packages(routers: Router<any>[]): Router<TRoutes>;\n\n /**\n * Register global middlewares\n *\n * Applied to all routes unless explicitly skipped via .skip()\n *\n * @example\n * ```ts\n * import { authMiddleware, loggingMiddleware } from './middlewares';\n *\n * export const appRouter = defineRouter({\n * getRoot,\n * getHealth,\n * })\n * .packages([authRouter])\n * .use([authMiddleware, loggingMiddleware]);\n * ```\n */\n use(middlewares: NamedMiddleware<string>[]): Router<TRoutes>;\n}\n\n/**\n * Create a Router instance with chainable methods\n */\nfunction createRouterInstance<TRoutes extends Record<string, RouteDef<any, any, any> | Router<any>>>(\n routes: TRoutes,\n packageRouters: Router<any>[] = [],\n globalMiddlewares: NamedMiddleware<string>[] = []\n): Router<TRoutes>\n{\n return {\n routes,\n _routes: routes,\n _packageRouters: packageRouters,\n _globalMiddlewares: globalMiddlewares,\n\n packages(routers: Router<any>[]): Router<TRoutes>\n {\n const newPackageRouters = [...this._packageRouters, ...routers];\n\n // Also include nested package routers if any\n for (const pkgRouter of routers)\n {\n if (pkgRouter._packageRouters?.length > 0)\n {\n newPackageRouters.push(...pkgRouter._packageRouters);\n }\n }\n\n return createRouterInstance(this.routes, newPackageRouters, this._globalMiddlewares);\n },\n\n use(middlewares: NamedMiddleware<string>[]): Router<TRoutes>\n {\n return createRouterInstance(this.routes, this._packageRouters, [...this._globalMiddlewares, ...middlewares]);\n },\n };\n}\n\n/**\n * Define a router with multiple routes (tRPC-style)\n *\n * Supports chainable API for packages and middlewares:\n *\n * @example\n * ```ts\n * // Basic usage\n * export const appRouter = defineRouter({\n * getRoot,\n * getHealth,\n * listExamples,\n * });\n *\n * // With package routers (type-hidden)\n * export const appRouter = defineRouter({\n * getRoot,\n * getHealth,\n * })\n * .packages([authRouter, cmsAppRouter]);\n *\n * // With global middlewares\n * export const appRouter = defineRouter({\n * getRoot,\n * getHealth,\n * })\n * .packages([authRouter])\n * .use([authMiddleware, loggingMiddleware]);\n *\n * export type AppRouter = typeof appRouter;\n * ```\n *\n * Package routes:\n * - Recognized by RPC proxy and backend for routing\n * - NOT included in AppRouter type (use authApi, cmsApi instead)\n * - Prevents confusion between app API and package APIs\n */\nexport function defineRouter<TRoutes extends Record<string, RouteDef<any, any, any> | Router<any>>>(\n routes: TRoutes\n): Router<TRoutes>\n{\n return createRouterInstance(routes);\n}","/**\n * Route Input Validation\n *\n * Provides unified validation logic for route input fields\n */\n\nimport type { TSchema } from '@sinclair/typebox';\nimport { Value } from '@sinclair/typebox/value';\nimport type { Context } from 'hono';\nimport { ValidationError } from '@spfn/core/errors';\n\n/**\n * Validation error field info\n */\ninterface ValidationFieldError\n{\n path: string;\n message: string;\n value: unknown;\n}\n\n/**\n * Validate a value against a TypeBox schema\n *\n * @param schema - TypeBox schema to validate against\n * @param rawValue - Raw value to validate\n * @param fieldName - Field name for error messages\n * @returns Validated and converted value\n * @throws ValidationError if validation fails\n */\nexport function validateField<T extends Record<string, unknown>>(\n schema: TSchema | undefined,\n rawValue: Record<string, unknown>,\n fieldName: string\n): T\n{\n if (!schema)\n {\n return {} as T;\n }\n\n const converted = Value.Convert(schema, rawValue);\n const errors = [...Value.Errors(schema, converted)];\n\n if (errors.length > 0)\n {\n throw new ValidationError({\n message: `Invalid ${fieldName}`,\n fields: errors.map((e): ValidationFieldError => ({\n path: e.path,\n message: e.message,\n value: e.value,\n })),\n });\n }\n\n return converted as T;\n}\n\n/**\n * Extract query parameters from request URL\n *\n * Handles array values (multiple params with same key)\n */\nexport function extractQueryParams(c: Context): Record<string, string | string[]>\n{\n const url = new URL(c.req.url);\n const queryObj: Record<string, string | string[]> = {};\n\n url.searchParams.forEach((v, k) =>\n {\n const existing = queryObj[k];\n if (existing)\n {\n queryObj[k] = Array.isArray(existing) ? [...existing, v] : [existing, v];\n }\n else\n {\n queryObj[k] = v;\n }\n });\n\n return queryObj;\n}\n\n/**\n * Extract headers from request (lowercase keys)\n */\nexport function extractHeaders(c: Context): Record<string, string>\n{\n const rawHeaders: Record<string, string> = {};\n\n c.req.raw.headers.forEach((value, key) =>\n {\n rawHeaders[key.toLowerCase()] = value;\n });\n\n return rawHeaders;\n}\n\n/**\n * Extract and parse cookies from request\n */\nexport function extractCookies(c: Context): Record<string, string>\n{\n const cookieHeader = c.req.header('cookie');\n const rawCookies: Record<string, string> = {};\n\n if (cookieHeader)\n {\n cookieHeader.split(';').forEach(cookie =>\n {\n const [key, value] = cookie.trim().split('=');\n if (key && value)\n {\n rawCookies[key] = decodeURIComponent(value);\n }\n });\n }\n\n return rawCookies;\n}\n\n/**\n * Parse JSON body from request\n *\n * @throws ValidationError if JSON parsing fails\n */\nexport async function parseJsonBody(c: Context): Promise<Record<string, unknown>>\n{\n try\n {\n return await c.req.json();\n }\n catch (error)\n {\n throw new ValidationError({\n message: 'Invalid JSON body',\n fields: [{\n path: '/',\n message: 'Failed to parse JSON',\n value: error instanceof Error ? error.message : 'Unknown error',\n }],\n });\n }\n}","/**\n * Route Registration for define-route style routing\n *\n * Registers routes defined with route.get()...handler() to Hono app\n */\n\nimport type { Context, Hono, MiddlewareHandler } from 'hono';\nimport type { ContentfulStatusCode, RedirectStatusCode } from 'hono/utils/http-status';\nimport { logger } from '@spfn/core/logger';\nimport type { NamedMiddleware } from './define-middleware';\nimport type { RouteInput } from './route-input';\nimport type { RouteBuilderContext } from './context';\nimport type { RouteDef } from './route-builder';\nimport type { Router } from './router';\nimport type { HttpMethod } from './types';\nimport {\n validateField,\n extractQueryParams,\n extractHeaders,\n extractCookies,\n parseJsonBody,\n} from './validation';\n\n/**\n * Type guard to check if value is a Router\n */\nfunction isRouter(value: unknown): value is Router<any>\n{\n return value !== null &&\n typeof value === 'object' &&\n 'routes' in value &&\n '_routes' in value;\n}\n\n/**\n * Type guard to check if value is a RouteDef\n */\nfunction isRouteDef(value: unknown): value is RouteDef<any>\n{\n return value !== null &&\n typeof value === 'object' &&\n 'handler' in value;\n}\n\n/**\n * Type guard to check if value is a NamedMiddleware\n */\nfunction isNamedMiddleware(value: unknown): value is NamedMiddleware<any>\n{\n return value !== null &&\n typeof value === 'object' &&\n 'name' in value &&\n 'handler' in value &&\n '_name' in value;\n}\n\n/**\n * Register routes from defineRouter() to Hono app\n *\n * @param app - Hono app instance\n * @param router - Router definition\n * @param namedMiddlewares - Optional server-level named middlewares\n *\n * @example\n * ```ts\n * const appRouter = defineRouter({\n * getUser: route.get('/users/:id')...\n * createUser: route.post('/users')...\n * });\n *\n * const app = new Hono();\n * const namedMiddlewares = [\n * { name: 'auth', handler: AuthMiddleware() },\n * { name: 'rateLimit', handler: RateLimitMiddleware() },\n * ];\n * registerRoutes(app, appRouter, namedMiddlewares);\n * ```\n */\nexport function registerRoutes<TRoutes extends Record<string, RouteDef<any> | Router<any>>>(\n app: Hono,\n router: Router<TRoutes>,\n namedMiddlewares?: ReadonlyArray<{ name: string; handler: MiddlewareHandler }>\n): void\n{\n // Merge router's global middlewares with provided named middlewares\n const allNamedMiddlewares = [\n ...(namedMiddlewares ?? []),\n ...router._globalMiddlewares.map(mw => ({ name: mw.name, handler: mw.handler })),\n ];\n\n // 1. Register routes from router.routes\n for (const [name, routeOrRouter] of Object.entries(router.routes))\n {\n if (isRouter(routeOrRouter))\n {\n // Nested router - recursively register\n registerRoutes(app, routeOrRouter, allNamedMiddlewares);\n }\n else if (isRouteDef(routeOrRouter))\n {\n // Single route - register\n registerRoute(app, name, routeOrRouter, allNamedMiddlewares);\n }\n else\n {\n logger.warn(`Unknown route type for \"${name}\" - skipping`, {\n type: typeof routeOrRouter,\n });\n }\n }\n\n // 2. Register routes from package routers (_packageRouters)\n if (router._packageRouters && router._packageRouters.length > 0)\n {\n for (const pkgRouter of router._packageRouters)\n {\n registerRoutes(app, pkgRouter, allNamedMiddlewares);\n }\n }\n}\n\n/**\n * Register a single route\n */\nfunction registerRoute(\n app: Hono,\n name: string,\n routeDef: RouteDef<any>,\n namedMiddlewares?: ReadonlyArray<{ name: string; handler: MiddlewareHandler }>\n): void\n{\n const { method, path, input, middlewares = [], skipMiddlewares, handler } = routeDef;\n\n if (!method || !path)\n {\n logger.warn(`Route \"${name}\" is missing method or path - skipping`, {\n method,\n path,\n });\n\n return;\n }\n\n // Create wrapped handler with validation\n const wrappedHandler = async (c: Context) =>\n {\n // Create RouteBuilderContext with validation\n const context = await createRouteBuilderContext(c, input || {});\n\n // Call user handler\n const result = await handler(context);\n\n // If handler returns Response, use it directly\n if (result instanceof Response)\n {\n return result;\n }\n\n // Otherwise, return data as JSON directly (no wrapper)\n return c.json(result);\n };\n\n // Collect all middlewares: server-level (filtered) + route-level\n const allMiddlewares: MiddlewareHandler[] = [];\n\n // Track registered middlewares for deduplication\n const registeredNames = new Set<string>();\n const registeredHandlers = new Set<MiddlewareHandler>();\n\n // Check if skipping all middlewares\n const skipAll = skipMiddlewares === '*';\n\n // Add server-level named middlewares (skip those in skipMiddlewares or if '*')\n if (namedMiddlewares && namedMiddlewares.length > 0)\n {\n if (skipAll)\n {\n logger.debug(`⏭️ Skipping all middlewares (*) for route: ${method} ${path}`, { name });\n }\n else\n {\n const skipSet = new Set(Array.isArray(skipMiddlewares) ? skipMiddlewares : []);\n for (const middleware of namedMiddlewares)\n {\n if (!skipSet.has(middleware.name))\n {\n allMiddlewares.push(middleware.handler);\n registeredNames.add(middleware.name);\n registeredHandlers.add(middleware.handler);\n }\n else\n {\n logger.debug(`⏭️ Skipping middleware '${middleware.name}' for route: ${method} ${path}`, { name });\n }\n }\n }\n }\n\n // Add route-level middlewares (with deduplication by name or handler reference)\n for (const mw of middlewares)\n {\n if (isNamedMiddleware(mw))\n {\n // Named middleware: deduplicate by name\n if (registeredNames.has(mw.name))\n {\n logger.debug(`🔄 Skipping duplicate middleware '${mw.name}' for route: ${method} ${path}`, { name });\n continue;\n }\n registeredNames.add(mw.name);\n allMiddlewares.push(mw.handler);\n }\n else\n {\n // Regular middleware: deduplicate by handler reference\n if (registeredHandlers.has(mw))\n {\n logger.debug(`🔄 Skipping duplicate middleware handler for route: ${method} ${path}`, { name });\n continue;\n }\n registeredHandlers.add(mw);\n allMiddlewares.push(mw);\n }\n }\n\n // Register to Hono with correct HTTP method\n const methodLower = method.toLowerCase() as Lowercase<HttpMethod>;\n\n if (allMiddlewares.length > 0)\n {\n // Register with middlewares\n app[methodLower](path, ...allMiddlewares, wrappedHandler);\n }\n else\n {\n // Register without middlewares\n app[methodLower](path, wrappedHandler);\n }\n\n logger.debug(`Registered route: ${method} ${path}`, { name });\n}\n\n/**\n * Create RouteBuilderContext from Hono Context\n *\n * Validates params, query, body, headers, cookies and returns structured input\n */\nasync function createRouteBuilderContext<TInput extends RouteInput>(\n c: Context,\n input: TInput\n): Promise<RouteBuilderContext<TInput>>\n{\n // Validate and extract all input fields\n const params = validateField(input.params, c.req.param(), 'path parameters');\n const query = validateField(input.query, extractQueryParams(c), 'query parameters');\n const headers = validateField(input.headers, extractHeaders(c), 'headers');\n const cookies = validateField(input.cookies, extractCookies(c), 'cookies');\n\n // Body requires async parsing\n let body: Record<string, unknown> = {};\n if (input.body)\n {\n const rawBody = await parseJsonBody(c);\n body = validateField(input.body, rawBody, 'request body');\n }\n\n // Create context with structured data()\n return {\n data: async () => ({\n params,\n query,\n body,\n headers,\n cookies,\n }),\n\n json: (data, status, resHeaders) =>\n {\n return c.json(data, status, resHeaders);\n },\n\n created: (data, location) =>\n {\n const resHeaders: Record<string, string> = {};\n if (location)\n {\n resHeaders['Location'] = location;\n }\n\n return c.json(data, 201 as ContentfulStatusCode, resHeaders);\n },\n\n accepted: (data) =>\n {\n if (data === undefined)\n {\n return c.body(null, 202 as ContentfulStatusCode);\n }\n\n return c.json(data, 202 as ContentfulStatusCode);\n },\n\n noContent: () =>\n {\n return c.body(null, 204 as ContentfulStatusCode);\n },\n\n notModified: () =>\n {\n return c.body(null, 304 as ContentfulStatusCode);\n },\n\n paginated: (data, page, limit, total) =>\n {\n return c.json({\n items: data,\n pagination: {\n page,\n limit,\n total,\n totalPages: Math.ceil(total / limit),\n },\n }, 200 as ContentfulStatusCode);\n },\n\n redirect: (url, status) =>\n {\n return c.redirect(url, status as RedirectStatusCode);\n },\n\n raw: c,\n };\n}","/**\n * Middleware Definition Helper\n *\n * Provides type-safe middleware definition with name inference\n */\n\nimport type { MiddlewareHandler } from 'hono';\n\n/**\n * Named middleware with type inference\n *\n * @example\n * ```ts\n * export const authMiddleware = defineMiddleware('auth', async (c, next) => {\n * // auth logic\n * c.set('user', { id: 1 });\n * await next();\n * });\n *\n * export const rateLimitMiddleware = defineMiddleware('rateLimit', async (c, next) => {\n * // rate limit logic\n * await next();\n * });\n * ```\n */\nexport type NamedMiddleware<TName extends string = string> = {\n name: TName;\n handler: MiddlewareHandler;\n _name: TName; // Type inference helper\n};\n\n/**\n * Named middleware factory with type inference\n *\n * Factory function that creates middleware instances with parameters\n *\n * @example\n * ```ts\n * export const requirePermissions = defineMiddleware('permission',\n * (...permissions: string[]) => async (c, next) => {\n * // permission check logic\n * await next();\n * }\n * );\n * ```\n */\nexport type NamedMiddlewareFactory<TName extends string = string, TArgs extends any[] = any[]> = {\n name: TName;\n _name: TName; // Type inference helper\n} & ((...args: TArgs) => MiddlewareHandler);\n\n/**\n * Define a named middleware\n *\n * Creates a middleware with a unique name that can be referenced\n * in route-level skip() calls with full type safety.\n *\n * Supports two patterns:\n * 1. Regular middleware: Direct middleware handler\n * 2. Factory middleware: Function that creates middleware with parameters\n *\n * @param name - Unique middleware name\n * @param handler - Middleware handler function\n * @returns Named middleware with type inference\n *\n * @example\n * ```ts\n * // Regular middleware\n * export const authMiddleware = defineMiddleware('auth', async (c, next) => {\n * const token = c.req.header('authorization');\n * if (!token) {\n * return c.json({ error: 'Unauthorized' }, 401);\n * }\n * c.set('user', await verifyToken(token));\n * await next();\n * });\n *\n * // Factory middleware\n * export const requirePermissions = defineMiddleware('permission',\n * (...permissions: string[]) => async (c, next) => {\n * const user = c.get('user');\n * if (!hasPermissions(user, permissions)) {\n * return c.json({ error: 'Forbidden' }, 403);\n * }\n * await next();\n * }\n * );\n *\n * // server.config.ts\n * export default defineServerConfig()\n * .middlewares([authMiddleware])\n * .routes(appRouter)\n * .build();\n *\n * // routes.ts - skip by name\n * export const publicRoute = route.get('/health')\n * .skip(['auth']) // ✅ Type-safe! Autocomplete!\n * .handler(async (c) => c.success({ status: 'ok' }));\n *\n * // Use factory middleware inline\n * export const protectedRoute = route.get('/admin')\n * .use([requirePermissions('admin:write')])\n * .handler(async (c) => { ... });\n * ```\n */\nexport function defineMiddleware<TName extends string>(\n name: TName,\n handler: MiddlewareHandler\n): NamedMiddleware<TName>;\n\nexport function defineMiddleware<TName extends string, TArgs extends any[]>(\n name: TName,\n factory: (...args: TArgs) => MiddlewareHandler\n): NamedMiddlewareFactory<TName, TArgs>;\n\nexport function defineMiddleware<TName extends string, TArgs extends any[] = []>(\n name: TName,\n handlerOrFactory: MiddlewareHandler | ((...args: TArgs) => MiddlewareHandler)\n): NamedMiddleware<TName> | NamedMiddlewareFactory<TName, TArgs>\n{\n // Distinguish between regular middleware and factory by parameter count\n // MiddlewareHandler always has exactly 2 parameters: (c, next)\n // Factory has any other number of parameters\n if (typeof handlerOrFactory === 'function')\n {\n const paramCount = handlerOrFactory.length;\n\n // Regular middleware handler (c, next) => ...\n if (paramCount === 2)\n {\n return {\n name,\n handler: handlerOrFactory as MiddlewareHandler,\n _name: name as TName,\n };\n }\n // Factory (...args) => (c, next) => ...\n else\n {\n // Create a new wrapper function to avoid \"Cannot assign to read only property 'name'\" error\n const factory = handlerOrFactory as (...args: TArgs) => MiddlewareHandler;\n const wrapper = (...args: TArgs) => factory(...args);\n\n // Use Object.defineProperty to set name property (which is read-only by default)\n Object.defineProperty(wrapper, 'name', {\n value: name,\n writable: false,\n enumerable: false,\n configurable: true,\n });\n\n Object.defineProperty(wrapper, '_name', {\n value: name as TName,\n writable: false,\n enumerable: false,\n configurable: true,\n });\n\n return wrapper as NamedMiddlewareFactory<TName, TArgs>;\n }\n }\n\n // Fallback: treat as regular middleware\n return {\n name,\n handler: handlerOrFactory as MiddlewareHandler,\n _name: name as TName,\n };\n}\n\n/**\n * Define a middleware factory explicitly\n *\n * Use this when your factory function has exactly 2 parameters,\n * which would be incorrectly detected as a regular middleware handler.\n *\n * @param name - Unique middleware name\n * @param factory - Factory function that returns a middleware handler\n * @returns Named middleware factory with type inference\n *\n * @example\n * ```ts\n * // Factory with 2 params (would be misdetected by defineMiddleware)\n * export const rateLimiter = defineMiddlewareFactory('rateLimit',\n * (limit: number, window: number) => async (c, next) => {\n * // rate limit logic using limit and window\n * await next();\n * }\n * );\n *\n * // Usage\n * route.get('/api')\n * .use([rateLimiter(100, 60000)]) // 100 requests per minute\n * .handler(...)\n * ```\n */\nexport function defineMiddlewareFactory<TName extends string, TArgs extends unknown[]>(\n name: TName,\n factory: (...args: TArgs) => MiddlewareHandler\n): NamedMiddlewareFactory<TName, TArgs>\n{\n const wrapper = (...args: TArgs) => factory(...args);\n\n Object.defineProperty(wrapper, 'name', {\n value: name,\n writable: false,\n enumerable: false,\n configurable: true,\n });\n\n Object.defineProperty(wrapper, '_name', {\n value: name as TName,\n writable: false,\n enumerable: false,\n configurable: true,\n });\n\n return wrapper as NamedMiddlewareFactory<TName, TArgs>;\n}\n\n/**\n * Extract middleware names from an array of named middlewares\n *\n * @example\n * ```ts\n * type Middlewares = [\n * NamedMiddleware<'auth'>,\n * NamedMiddleware<'rateLimit'>\n * ];\n * type Names = ExtractMiddlewareNames<Middlewares>; // 'auth' | 'rateLimit'\n * ```\n */\nexport type ExtractMiddlewareNames<T extends readonly NamedMiddleware<string>[]> =\n T[number]['_name'];","/**\n * Route Helper Functions\n *\n * Type guards and TypeBox utilities\n */\n\nimport type { TSchema } from '@sinclair/typebox';\nimport { Type } from '@sinclair/typebox';\nimport type { HttpMethod } from './types';\n\n/**\n * Type guard for HttpMethod\n */\nexport function isHttpMethod(value: unknown): value is HttpMethod\n{\n return (\n typeof value === 'string' &&\n ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].includes(value)\n );\n}\n\n/**\n * Nullable - Creates a union of T | null\n *\n * @example\n * ```typescript\n * // string | null\n * firstName: Nullable(Type.String())\n * ```\n */\nexport const Nullable = <T extends TSchema>(schema: T) =>\n Type.Union([schema, Type.Null()]);\n\n/**\n * OptionalNullable - Creates a union of T | null | undefined\n *\n * @example\n * ```typescript\n * // string | null | undefined\n * lastName: OptionalNullable(Type.String())\n * ```\n */\nexport const OptionalNullable = <T extends TSchema>(schema: T) =>\n Type.Optional(Type.Union([schema, Type.Null()]));"]}
1
+ {"version":3,"sources":["../../src/route/route-builder.ts","../../src/route/router.ts","../../src/route/validation.ts","../../src/route/register-routes.ts","../../src/route/define-middleware.ts","../../src/route/helpers.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Route Builder\n *\n * Provides tRPC-style chainable API for route definition\n */\n\nimport type { MiddlewareHandler } from 'hono';\nimport type { NamedMiddleware } from './define-middleware';\nimport type { RouteInput } from './route-input';\nimport type { RouteBuilderContext } from './context';\nimport type { HttpMethod } from './types';\n\n/**\n * Route handler function\n */\nexport type RouteHandlerFn<\n TInput extends RouteInput = RouteInput,\n TInterceptor extends RouteInput = {},\n TResponse = unknown\n> = (c: RouteBuilderContext<TInput, TInterceptor>) => Response | Promise<Response> | TResponse | Promise<TResponse>;\n\n/**\n * Route definition result\n *\n * Contains all information needed for type inference and registration\n */\nexport type RouteDef<\n TInput extends RouteInput = RouteInput,\n TInterceptor extends RouteInput = {},\n TResponse = unknown\n> = {\n method?: HttpMethod;\n path?: string;\n input?: TInput;\n interceptor?: TInterceptor;\n middlewares?: (MiddlewareHandler | NamedMiddleware<string>)[];\n skipMiddlewares?: string[] | '*';\n handler: RouteHandlerFn<TInput, TInterceptor, TResponse>;\n\n // Type inference helpers\n _input: TInput;\n _interceptor: TInterceptor;\n _response: TResponse;\n};\n\n/**\n * Route builder with chainable API (tRPC-style)\n */\nexport class RouteBuilder<\n TInput extends RouteInput = {},\n TInterceptor extends RouteInput = {},\n TResponse = never\n>\n{\n public _method?: HttpMethod;\n public _path?: string;\n public _input?: TInput;\n public _interceptor?: TInterceptor;\n public _middlewares?: (MiddlewareHandler | NamedMiddleware<string>)[];\n public _skipMiddlewares?: string[] | '*';\n\n /**\n * Create a new RouteBuilder with copied properties and optional overrides\n */\n private clone<\n TNewInput extends RouteInput = TInput,\n TNewInterceptor extends RouteInput = TInterceptor\n >(\n overrides?: Partial<{\n input: TNewInput;\n interceptor: TNewInterceptor;\n middlewares: (MiddlewareHandler | NamedMiddleware<string>)[];\n skipMiddlewares: string[] | '*';\n }>\n ): RouteBuilder<TNewInput, TNewInterceptor, TResponse>\n {\n const builder = new RouteBuilder<TNewInput, TNewInterceptor, TResponse>();\n builder._method = this._method;\n builder._path = this._path;\n builder._input = (overrides?.input ?? this._input) as TNewInput | undefined;\n builder._interceptor = (overrides?.interceptor ?? this._interceptor) as TNewInterceptor | undefined;\n builder._middlewares = overrides?.middlewares ?? this._middlewares;\n builder._skipMiddlewares = overrides?.skipMiddlewares ?? this._skipMiddlewares;\n return builder;\n }\n\n /**\n * Define input schemas\n *\n * @example\n * ```ts\n * route.get('/users/:id')\n * .input({\n * params: Type.Object({ id: Type.String() }),\n * query: Type.Object({ page: Type.Number() }),\n * headers: Type.Object({ authorization: Type.String() })\n * })\n * .handler(async (c) => {\n * const { params, query, headers } = await c.data();\n * // params = { id: string }\n * // query = { page: number }\n * // headers = { authorization: string }\n * })\n * ```\n */\n input<TNewInput extends RouteInput>(input: TNewInput): RouteBuilder<TNewInput, TInterceptor, TResponse>\n {\n return this.clone({ input });\n }\n\n /**\n * Define fields injected by interceptors\n *\n * These fields are:\n * - Available in the handler (merged with input)\n * - Excluded from client types (codegen uses only input)\n * - Not validated by route input schema (injected by middleware)\n *\n * Use this when middleware/interceptors add fields to the request\n * before it reaches the handler.\n *\n * @example\n * ```ts\n * // Auth interceptor injects crypto key fields\n * route.post('/_auth/login')\n * .input({\n * body: Type.Object({\n * email: Type.String(),\n * password: Type.String()\n * })\n * })\n * .interceptor({\n * body: Type.Object({\n * publicKey: Type.String(),\n * keyId: Type.String(),\n * fingerprint: Type.String()\n * })\n * })\n * .handler(async (c) => {\n * const { body } = await c.data();\n * // body type: { email, password, publicKey, keyId, fingerprint }\n * // Client only sees: { email, password }\n * return loginService(body);\n * });\n * ```\n */\n interceptor<TNewInterceptor extends RouteInput>(\n interceptor: TNewInterceptor\n ): RouteBuilder<TInput, TNewInterceptor, TResponse>\n {\n return this.clone({ interceptor });\n }\n\n /**\n * Add middlewares to the route\n *\n * Accepts both regular middleware handlers and named middlewares (NamedMiddleware).\n * Named middlewares that are already registered globally will be automatically\n * deduplicated to prevent double execution.\n *\n * @example\n * ```ts\n * import { authenticate } from '@spfn/auth/server/middleware';\n *\n * // With NamedMiddleware (auto-deduped if registered globally)\n * route.get('/users')\n * .use([authenticate, RateLimitMiddleware()])\n *\n * // With regular middleware handlers\n * route.get('/users')\n * .use([AuthMiddleware(), RateLimitMiddleware()])\n * ```\n */\n middleware(middlewares: (MiddlewareHandler | NamedMiddleware<string>)[]): RouteBuilder<TInput, TInterceptor, TResponse>\n {\n return this.clone({ middlewares });\n }\n\n /**\n * Add middlewares to the route (alias for `.middleware()`)\n *\n * Accepts both regular middleware handlers and named middlewares (NamedMiddleware).\n * Named middlewares that are already registered globally will be automatically\n * deduplicated to prevent double execution.\n *\n * @example\n * ```ts\n * import { authenticate } from '@spfn/auth/server/middleware';\n *\n * // With NamedMiddleware (auto-deduped if registered globally)\n * route.get('/users')\n * .use([authenticate, RateLimitMiddleware()])\n *\n * // With regular middleware handlers\n * route.get('/users')\n * .use([AuthMiddleware(), RateLimitMiddleware()])\n * ```\n */\n use(middlewares: (MiddlewareHandler | NamedMiddleware<string>)[]): RouteBuilder<TInput, TInterceptor, TResponse>\n {\n return this.middleware(middlewares);\n }\n\n /**\n * Skip server-level named middlewares\n *\n * Useful for public endpoints that should bypass auth or rate limiting\n *\n * @param middlewareNames - Array of middleware names to skip, or '*' to skip all\n *\n * @example\n * ```ts\n * // Skip specific middlewares\n * route.get('/health')\n * .skip(['auth', 'rateLimit'])\n * .handler(async (c) => c.json({ status: 'ok' }));\n *\n * // Skip only auth (still apply rate limiting)\n * route.get('/public-data')\n * .skip(['auth'])\n * .handler(async (c) => { ... });\n *\n * // Skip all middlewares\n * route.get('/public-health')\n * .skip('*')\n * .handler(async (c) => c.json({ status: 'ok' }));\n * ```\n */\n skip(middlewareNames: string[] | '*'): RouteBuilder<TInput, TInterceptor, TResponse>\n {\n return this.clone({ skipMiddlewares: middlewareNames });\n }\n\n /**\n * Define handler function\n *\n * Response type is automatically inferred from the return value.\n * Use helper methods like `c.created()`, `c.paginated()` for proper type inference.\n *\n * @example\n * ```ts\n * // Direct return - type inferred from data\n * route.get('/users/:id')\n * .input({ params: Type.Object({ id: Type.String() }) })\n * .handler(async (c) => {\n * const { params } = await c.data();\n * return await getUser(params.id); // Type: User\n * })\n *\n * // Using c.created() - returns data with 201 status, type preserved\n * route.post('/users')\n * .input({ body: Type.Object({ name: Type.String() }) })\n * .handler(async (c) => {\n * const { body } = await c.data();\n * return c.created(await createUser(body)); // Type: User\n * })\n *\n * // Using c.paginated() - returns PaginatedResult<T>\n * route.get('/users')\n * .handler(async (c) => {\n * const users = await getUsers();\n * return c.paginated(users, 1, 20, 100); // Type: PaginatedResult<User>\n * })\n *\n * // Using c.noContent() - returns void\n * route.delete('/users/:id')\n * .handler(async (c) => {\n * await deleteUser(params.id);\n * return c.noContent(); // Type: void\n * })\n *\n * // Using c.json() - returns Response (type inference lost)\n * // Use only when you need custom status codes not covered by helpers\n * route.get('/custom')\n * .handler(async (c) => {\n * return c.json({ data }, 418); // Type: Response\n * })\n * ```\n */\n handler<THandlerResponse>(\n fn: RouteHandlerFn<TInput, TInterceptor, THandlerResponse>\n ): RouteDef<TInput, TInterceptor, THandlerResponse>\n {\n return {\n method: this._method,\n path: this._path,\n input: this._input,\n interceptor: this._interceptor,\n middlewares: this._middlewares,\n skipMiddlewares: this._skipMiddlewares,\n handler: fn,\n _input: {} as TInput,\n _interceptor: {} as TInterceptor,\n _response: {} as THandlerResponse,\n };\n }\n}\n\n/**\n * Create a route definition with HTTP method shortcuts\n */\nfunction createMethodRoute(method: HttpMethod): (path: string) => RouteBuilder\n{\n return (path: string) =>\n {\n const builder = new RouteBuilder();\n builder._method = method;\n builder._path = path;\n return builder;\n };\n}\n\n/**\n * Route builder entry point\n *\n * @example\n * ```ts\n * // GET request\n * export const getUser = route.get('/users/:id')\n * .input({ params: Type.Object({ id: Type.String() }) })\n * .handler(async (c) => {\n * const { params } = await c.data();\n * return await db.user.findUnique({ where: { id: params.id } });\n * });\n *\n * // POST request\n * export const createUser = route.post('/users')\n * .input({ body: Type.Object({ name: Type.String(), email: Type.String() }) })\n * .handler(async (c) => {\n * const { body } = await c.data();\n * return c.created(await db.user.create({ data: body }));\n * });\n * ```\n */\nexport const route = {\n get: createMethodRoute('GET'),\n post: createMethodRoute('POST'),\n put: createMethodRoute('PUT'),\n patch: createMethodRoute('PATCH'),\n delete: createMethodRoute('DELETE'),\n};","/**\n * Router Definition\n *\n * Provides router composition and middleware management\n */\n\nimport type { NamedMiddleware } from './define-middleware';\nimport type { RouteDef } from './route-builder';\n\n/**\n * Router definition - holds all routes\n */\nexport interface Router<TRoutes extends Record<string, RouteDef<any, any, any> | Router<any>>> {\n routes: TRoutes;\n _routes: TRoutes;\n _packageRouters: Router<any>[];\n _globalMiddlewares: NamedMiddleware<string>[];\n\n /**\n * Register package routers (type-hidden)\n *\n * Package routes are:\n * - Recognized by RPC proxy and backend\n * - NOT exposed in client types (use package's own API like authApi, cmsApi)\n *\n * @example\n * ```ts\n * import { authRouter } from '@spfn/auth/server';\n * import { cmsAppRouter } from '@spfn/cms/server';\n *\n * export const appRouter = defineRouter({\n * getRoot,\n * getHealth,\n * })\n * .packages([authRouter, cmsAppRouter]);\n *\n * // Client usage:\n * // api.getRoot.call({}) - app routes\n * // authApi.login.call({}) - package API\n * ```\n */\n packages(routers: Router<any>[]): Router<TRoutes>;\n\n /**\n * Register global middlewares\n *\n * Applied to all routes unless explicitly skipped via .skip()\n *\n * @example\n * ```ts\n * import { authMiddleware, loggingMiddleware } from './middlewares';\n *\n * export const appRouter = defineRouter({\n * getRoot,\n * getHealth,\n * })\n * .packages([authRouter])\n * .use([authMiddleware, loggingMiddleware]);\n * ```\n */\n use(middlewares: NamedMiddleware<string>[]): Router<TRoutes>;\n}\n\n/**\n * Create a Router instance with chainable methods\n */\nfunction createRouterInstance<TRoutes extends Record<string, RouteDef<any, any, any> | Router<any>>>(\n routes: TRoutes,\n packageRouters: Router<any>[] = [],\n globalMiddlewares: NamedMiddleware<string>[] = []\n): Router<TRoutes>\n{\n return {\n routes,\n _routes: routes,\n _packageRouters: packageRouters,\n _globalMiddlewares: globalMiddlewares,\n\n packages(routers: Router<any>[]): Router<TRoutes>\n {\n const newPackageRouters = [...this._packageRouters, ...routers];\n\n // Also include nested package routers if any\n for (const pkgRouter of routers)\n {\n if (pkgRouter._packageRouters?.length > 0)\n {\n newPackageRouters.push(...pkgRouter._packageRouters);\n }\n }\n\n return createRouterInstance(this.routes, newPackageRouters, this._globalMiddlewares);\n },\n\n use(middlewares: NamedMiddleware<string>[]): Router<TRoutes>\n {\n return createRouterInstance(this.routes, this._packageRouters, [...this._globalMiddlewares, ...middlewares]);\n },\n };\n}\n\n/**\n * Define a router with multiple routes (tRPC-style)\n *\n * Supports chainable API for packages and middlewares:\n *\n * @example\n * ```ts\n * // Basic usage\n * export const appRouter = defineRouter({\n * getRoot,\n * getHealth,\n * listExamples,\n * });\n *\n * // With package routers (type-hidden)\n * export const appRouter = defineRouter({\n * getRoot,\n * getHealth,\n * })\n * .packages([authRouter, cmsAppRouter]);\n *\n * // With global middlewares\n * export const appRouter = defineRouter({\n * getRoot,\n * getHealth,\n * })\n * .packages([authRouter])\n * .use([authMiddleware, loggingMiddleware]);\n *\n * export type AppRouter = typeof appRouter;\n * ```\n *\n * Package routes:\n * - Recognized by RPC proxy and backend for routing\n * - NOT included in AppRouter type (use authApi, cmsApi instead)\n * - Prevents confusion between app API and package APIs\n */\nexport function defineRouter<TRoutes extends Record<string, RouteDef<any, any, any> | Router<any>>>(\n routes: TRoutes\n): Router<TRoutes>\n{\n return createRouterInstance(routes);\n}","/**\n * Route Input Validation\n *\n * Provides unified validation logic for route input fields\n */\n\nimport type { TSchema } from '@sinclair/typebox';\nimport { Value } from '@sinclair/typebox/value';\nimport type { Context } from 'hono';\nimport { ValidationError } from '@spfn/core/errors';\n\n/**\n * Validation error field info\n */\ninterface ValidationFieldError\n{\n path: string;\n message: string;\n value: unknown;\n}\n\n/**\n * Validate a value against a TypeBox schema\n *\n * @param schema - TypeBox schema to validate against\n * @param rawValue - Raw value to validate\n * @param fieldName - Field name for error messages\n * @returns Validated and converted value\n * @throws ValidationError if validation fails\n */\nexport function validateField<T extends Record<string, unknown>>(\n schema: TSchema | undefined,\n rawValue: Record<string, unknown>,\n fieldName: string\n): T\n{\n if (!schema)\n {\n return {} as T;\n }\n\n const converted = Value.Convert(schema, rawValue);\n const errors = [...Value.Errors(schema, converted)];\n\n if (errors.length > 0)\n {\n throw new ValidationError({\n message: `Invalid ${fieldName}`,\n fields: errors.map((e): ValidationFieldError => ({\n path: e.path,\n message: e.message,\n value: e.value,\n })),\n });\n }\n\n return converted as T;\n}\n\n/**\n * Extract query parameters from request URL\n *\n * Handles array values (multiple params with same key)\n */\nexport function extractQueryParams(c: Context): Record<string, string | string[]>\n{\n const url = new URL(c.req.url);\n const queryObj: Record<string, string | string[]> = {};\n\n url.searchParams.forEach((v, k) =>\n {\n const existing = queryObj[k];\n if (existing)\n {\n queryObj[k] = Array.isArray(existing) ? [...existing, v] : [existing, v];\n }\n else\n {\n queryObj[k] = v;\n }\n });\n\n return queryObj;\n}\n\n/**\n * Extract headers from request (lowercase keys)\n */\nexport function extractHeaders(c: Context): Record<string, string>\n{\n const rawHeaders: Record<string, string> = {};\n\n c.req.raw.headers.forEach((value, key) =>\n {\n rawHeaders[key.toLowerCase()] = value;\n });\n\n return rawHeaders;\n}\n\n/**\n * Extract and parse cookies from request\n */\nexport function extractCookies(c: Context): Record<string, string>\n{\n const cookieHeader = c.req.header('cookie');\n const rawCookies: Record<string, string> = {};\n\n if (cookieHeader)\n {\n cookieHeader.split(';').forEach(cookie =>\n {\n const [key, value] = cookie.trim().split('=');\n if (key && value)\n {\n rawCookies[key] = decodeURIComponent(value);\n }\n });\n }\n\n return rawCookies;\n}\n\n/**\n * Parse JSON body from request\n *\n * @throws ValidationError if JSON parsing fails\n */\nexport async function parseJsonBody(c: Context): Promise<Record<string, unknown>>\n{\n try\n {\n return await c.req.json();\n }\n catch (error)\n {\n throw new ValidationError({\n message: 'Invalid JSON body',\n fields: [{\n path: '/',\n message: 'Failed to parse JSON',\n value: error instanceof Error ? error.message : 'Unknown error',\n }],\n });\n }\n}","/**\n * Route Registration for define-route style routing\n *\n * Registers routes defined with route.get()...handler() to Hono app\n */\n\nimport type { Context, Hono, MiddlewareHandler } from 'hono';\nimport type { ContentfulStatusCode, RedirectStatusCode } from 'hono/utils/http-status';\nimport { logger } from '@spfn/core/logger';\nimport type { NamedMiddleware } from './define-middleware';\nimport type { RouteInput } from './route-input';\nimport type { RouteBuilderContext } from './context';\nimport type { RouteDef } from './route-builder';\nimport type { Router } from './router';\nimport type { HttpMethod } from './types';\nimport {\n validateField,\n extractQueryParams,\n extractHeaders,\n extractCookies,\n parseJsonBody,\n} from './validation';\n\n/**\n * Type guard to check if value is a Router\n */\nfunction isRouter(value: unknown): value is Router<any>\n{\n return value !== null &&\n typeof value === 'object' &&\n 'routes' in value &&\n '_routes' in value;\n}\n\n/**\n * Type guard to check if value is a RouteDef\n */\nfunction isRouteDef(value: unknown): value is RouteDef<any>\n{\n return value !== null &&\n typeof value === 'object' &&\n 'handler' in value;\n}\n\n/**\n * Type guard to check if value is a NamedMiddleware\n */\nfunction isNamedMiddleware(value: unknown): value is NamedMiddleware<any>\n{\n return value !== null &&\n typeof value === 'object' &&\n 'name' in value &&\n 'handler' in value &&\n '_name' in value;\n}\n\n/**\n * Register routes from defineRouter() to Hono app\n *\n * @param app - Hono app instance\n * @param router - Router definition\n * @param namedMiddlewares - Optional server-level named middlewares\n *\n * @example\n * ```ts\n * const appRouter = defineRouter({\n * getUser: route.get('/users/:id')...\n * createUser: route.post('/users')...\n * });\n *\n * const app = new Hono();\n * const namedMiddlewares = [\n * { name: 'auth', handler: AuthMiddleware() },\n * { name: 'rateLimit', handler: RateLimitMiddleware() },\n * ];\n * registerRoutes(app, appRouter, namedMiddlewares);\n * ```\n */\nexport function registerRoutes<TRoutes extends Record<string, RouteDef<any> | Router<any>>>(\n app: Hono,\n router: Router<TRoutes>,\n namedMiddlewares?: ReadonlyArray<{ name: string; handler: MiddlewareHandler }>\n): void\n{\n // Merge router's global middlewares with provided named middlewares\n const allNamedMiddlewares = [\n ...(namedMiddlewares ?? []),\n ...router._globalMiddlewares.map(mw => ({ name: mw.name, handler: mw.handler })),\n ];\n\n // 1. Register routes from router.routes\n for (const [name, routeOrRouter] of Object.entries(router.routes))\n {\n if (isRouter(routeOrRouter))\n {\n // Nested router - recursively register\n registerRoutes(app, routeOrRouter, allNamedMiddlewares);\n }\n else if (isRouteDef(routeOrRouter))\n {\n // Single route - register\n registerRoute(app, name, routeOrRouter, allNamedMiddlewares);\n }\n else\n {\n logger.warn(`Unknown route type for \"${name}\" - skipping`, {\n type: typeof routeOrRouter,\n });\n }\n }\n\n // 2. Register routes from package routers (_packageRouters)\n if (router._packageRouters && router._packageRouters.length > 0)\n {\n for (const pkgRouter of router._packageRouters)\n {\n registerRoutes(app, pkgRouter, allNamedMiddlewares);\n }\n }\n}\n\n/**\n * Register a single route\n */\nfunction registerRoute(\n app: Hono,\n name: string,\n routeDef: RouteDef<any>,\n namedMiddlewares?: ReadonlyArray<{ name: string; handler: MiddlewareHandler }>\n): void\n{\n const { method, path, input, middlewares = [], skipMiddlewares, handler } = routeDef;\n\n if (!method || !path)\n {\n logger.warn(`Route \"${name}\" is missing method or path - skipping`, {\n method,\n path,\n });\n\n return;\n }\n\n // Create wrapped handler with validation\n const wrappedHandler = async (c: Context) =>\n {\n // Create RouteBuilderContext with validation\n const { context, responseMeta } = await createRouteBuilderContext(c, input || {});\n\n // Call user handler\n const result = await handler(context);\n\n // If handler returns Response, use it directly (e.g., c.json(), c.redirect())\n if (result instanceof Response)\n {\n return result;\n }\n\n // Handle empty responses (noContent, notModified, accepted without data)\n if (responseMeta.isEmpty)\n {\n return c.body(null, responseMeta.status);\n }\n\n // Return data as JSON with status and headers from helper methods\n const hasCustomHeaders = Object.keys(responseMeta.headers).length > 0;\n\n if (hasCustomHeaders)\n {\n return c.json(result, responseMeta.status, responseMeta.headers);\n }\n\n return c.json(result, responseMeta.status);\n };\n\n // Collect all middlewares: server-level (filtered) + route-level\n const allMiddlewares: MiddlewareHandler[] = [];\n\n // Track registered middlewares for deduplication\n const registeredNames = new Set<string>();\n const registeredHandlers = new Set<MiddlewareHandler>();\n\n // Check if skipping all middlewares\n const skipAll = skipMiddlewares === '*';\n\n // Add server-level named middlewares (skip those in skipMiddlewares or if '*')\n if (namedMiddlewares && namedMiddlewares.length > 0)\n {\n if (skipAll)\n {\n logger.debug(`⏭️ Skipping all middlewares (*) for route: ${method} ${path}`, { name });\n }\n else\n {\n const skipSet = new Set(Array.isArray(skipMiddlewares) ? skipMiddlewares : []);\n for (const middleware of namedMiddlewares)\n {\n if (!skipSet.has(middleware.name))\n {\n allMiddlewares.push(middleware.handler);\n registeredNames.add(middleware.name);\n registeredHandlers.add(middleware.handler);\n }\n else\n {\n logger.debug(`⏭️ Skipping middleware '${middleware.name}' for route: ${method} ${path}`, { name });\n }\n }\n }\n }\n\n // Add route-level middlewares (with deduplication by name or handler reference)\n for (const mw of middlewares)\n {\n if (isNamedMiddleware(mw))\n {\n // Named middleware: deduplicate by name\n if (registeredNames.has(mw.name))\n {\n logger.debug(`🔄 Skipping duplicate middleware '${mw.name}' for route: ${method} ${path}`, { name });\n continue;\n }\n registeredNames.add(mw.name);\n allMiddlewares.push(mw.handler);\n }\n else\n {\n // Regular middleware: deduplicate by handler reference\n if (registeredHandlers.has(mw))\n {\n logger.debug(`🔄 Skipping duplicate middleware handler for route: ${method} ${path}`, { name });\n continue;\n }\n registeredHandlers.add(mw);\n allMiddlewares.push(mw);\n }\n }\n\n // Register to Hono with correct HTTP method\n const methodLower = method.toLowerCase() as Lowercase<HttpMethod>;\n\n if (allMiddlewares.length > 0)\n {\n // Register with middlewares\n app[methodLower](path, ...allMiddlewares, wrappedHandler);\n }\n else\n {\n // Register without middlewares\n app[methodLower](path, wrappedHandler);\n }\n\n logger.debug(`Registered route: ${method} ${path}`, { name });\n}\n\n/**\n * Response metadata set by helper methods\n */\ninterface ResponseMeta\n{\n status: ContentfulStatusCode;\n headers: Record<string, string>;\n isEmpty: boolean;\n}\n\n/**\n * Create RouteBuilderContext from Hono Context\n *\n * Validates params, query, body, headers, cookies and returns structured input.\n * Helper methods (created, accepted, etc.) return data directly for type inference,\n * while storing response metadata internally for later use.\n */\nasync function createRouteBuilderContext<TInput extends RouteInput>(\n c: Context,\n input: TInput\n): Promise<{ context: RouteBuilderContext<TInput>; responseMeta: ResponseMeta }>\n{\n // Validate and extract all input fields\n const params = validateField(input.params, c.req.param(), 'path parameters');\n const query = validateField(input.query, extractQueryParams(c), 'query parameters');\n const headers = validateField(input.headers, extractHeaders(c), 'headers');\n const cookies = validateField(input.cookies, extractCookies(c), 'cookies');\n\n // Body requires async parsing\n let body: Record<string, unknown> = {};\n if (input.body)\n {\n const rawBody = await parseJsonBody(c);\n body = validateField(input.body, rawBody, 'request body');\n }\n\n // Cache for data() - avoid creating new object on each call\n let cachedData: any = null;\n\n // Response metadata - set by helper methods, used when building final Response\n const responseMeta: ResponseMeta = {\n status: 200 as ContentfulStatusCode,\n headers: {},\n isEmpty: false,\n };\n\n // Create context with structured data()\n const context: RouteBuilderContext<TInput> = {\n data: async () =>\n {\n if (!cachedData)\n {\n cachedData = { params, query, body, headers, cookies };\n }\n return cachedData;\n },\n\n json: (data, status, resHeaders) =>\n {\n return c.json(data, status, resHeaders);\n },\n\n created: <T>(data: T, location?: string): T =>\n {\n responseMeta.status = 201 as ContentfulStatusCode;\n if (location)\n {\n responseMeta.headers['Location'] = location;\n }\n return data;\n },\n\n accepted: <T>(data?: T): any =>\n {\n responseMeta.status = 202 as ContentfulStatusCode;\n if (data === undefined)\n {\n responseMeta.isEmpty = true;\n return undefined;\n }\n return data;\n },\n\n noContent: (): void =>\n {\n responseMeta.status = 204 as ContentfulStatusCode;\n responseMeta.isEmpty = true;\n },\n\n notModified: (): void =>\n {\n responseMeta.status = 304 as ContentfulStatusCode;\n responseMeta.isEmpty = true;\n },\n\n paginated: <T>(data: T[], page: number, limit: number, total: number) =>\n {\n return {\n items: data,\n pagination: {\n page,\n limit,\n total,\n totalPages: Math.ceil(total / limit),\n },\n };\n },\n\n redirect: (url, status) =>\n {\n return c.redirect(url, status as RedirectStatusCode);\n },\n\n raw: c,\n };\n\n return { context, responseMeta };\n}","/**\n * Middleware Definition Helper\n *\n * Provides type-safe middleware definition with name inference\n */\n\nimport type { MiddlewareHandler } from 'hono';\n\n/**\n * Named middleware with type inference\n *\n * @example\n * ```ts\n * export const authMiddleware = defineMiddleware('auth', async (c, next) => {\n * // auth logic\n * c.set('user', { id: 1 });\n * await next();\n * });\n *\n * export const rateLimitMiddleware = defineMiddleware('rateLimit', async (c, next) => {\n * // rate limit logic\n * await next();\n * });\n * ```\n */\nexport type NamedMiddleware<TName extends string = string> = {\n name: TName;\n handler: MiddlewareHandler;\n _name: TName; // Type inference helper\n};\n\n/**\n * Named middleware factory with type inference\n *\n * Factory function that creates middleware instances with parameters\n *\n * @example\n * ```ts\n * export const requirePermissions = defineMiddleware('permission',\n * (...permissions: string[]) => async (c, next) => {\n * // permission check logic\n * await next();\n * }\n * );\n * ```\n */\nexport type NamedMiddlewareFactory<TName extends string = string, TArgs extends any[] = any[]> = {\n name: TName;\n _name: TName; // Type inference helper\n} & ((...args: TArgs) => MiddlewareHandler);\n\n/**\n * Define a named middleware\n *\n * Creates a middleware with a unique name that can be referenced\n * in route-level skip() calls with full type safety.\n *\n * Supports two patterns:\n * 1. Regular middleware: Direct middleware handler\n * 2. Factory middleware: Function that creates middleware with parameters\n *\n * @param name - Unique middleware name\n * @param handler - Middleware handler function\n * @returns Named middleware with type inference\n *\n * @example\n * ```ts\n * // Regular middleware\n * export const authMiddleware = defineMiddleware('auth', async (c, next) => {\n * const token = c.req.header('authorization');\n * if (!token) {\n * return c.json({ error: 'Unauthorized' }, 401);\n * }\n * c.set('user', await verifyToken(token));\n * await next();\n * });\n *\n * // Factory middleware\n * export const requirePermissions = defineMiddleware('permission',\n * (...permissions: string[]) => async (c, next) => {\n * const user = c.get('user');\n * if (!hasPermissions(user, permissions)) {\n * return c.json({ error: 'Forbidden' }, 403);\n * }\n * await next();\n * }\n * );\n *\n * // server.config.ts\n * export default defineServerConfig()\n * .middlewares([authMiddleware])\n * .routes(appRouter)\n * .build();\n *\n * // routes.ts - skip by name\n * export const publicRoute = route.get('/health')\n * .skip(['auth']) // ✅ Type-safe! Autocomplete!\n * .handler(async (c) => c.success({ status: 'ok' }));\n *\n * // Use factory middleware inline\n * export const protectedRoute = route.get('/admin')\n * .use([requirePermissions('admin:write')])\n * .handler(async (c) => { ... });\n * ```\n */\nexport function defineMiddleware<TName extends string>(\n name: TName,\n handler: MiddlewareHandler\n): NamedMiddleware<TName>;\n\nexport function defineMiddleware<TName extends string, TArgs extends any[]>(\n name: TName,\n factory: (...args: TArgs) => MiddlewareHandler\n): NamedMiddlewareFactory<TName, TArgs>;\n\nexport function defineMiddleware<TName extends string, TArgs extends any[] = []>(\n name: TName,\n handlerOrFactory: MiddlewareHandler | ((...args: TArgs) => MiddlewareHandler)\n): NamedMiddleware<TName> | NamedMiddlewareFactory<TName, TArgs>\n{\n // Distinguish between regular middleware and factory by parameter count\n // MiddlewareHandler always has exactly 2 parameters: (c, next)\n // Factory has any other number of parameters\n if (typeof handlerOrFactory === 'function')\n {\n const paramCount = handlerOrFactory.length;\n\n // Regular middleware handler (c, next) => ...\n if (paramCount === 2)\n {\n return {\n name,\n handler: handlerOrFactory as MiddlewareHandler,\n _name: name as TName,\n };\n }\n // Factory (...args) => (c, next) => ...\n else\n {\n // Create a new wrapper function to avoid \"Cannot assign to read only property 'name'\" error\n const factory = handlerOrFactory as (...args: TArgs) => MiddlewareHandler;\n const wrapper = (...args: TArgs) => factory(...args);\n\n // Use Object.defineProperty to set name property (which is read-only by default)\n Object.defineProperty(wrapper, 'name', {\n value: name,\n writable: false,\n enumerable: false,\n configurable: true,\n });\n\n Object.defineProperty(wrapper, '_name', {\n value: name as TName,\n writable: false,\n enumerable: false,\n configurable: true,\n });\n\n return wrapper as NamedMiddlewareFactory<TName, TArgs>;\n }\n }\n\n // Fallback: treat as regular middleware\n return {\n name,\n handler: handlerOrFactory as MiddlewareHandler,\n _name: name as TName,\n };\n}\n\n/**\n * Define a middleware factory explicitly\n *\n * Use this when your factory function has exactly 2 parameters,\n * which would be incorrectly detected as a regular middleware handler.\n *\n * @param name - Unique middleware name\n * @param factory - Factory function that returns a middleware handler\n * @returns Named middleware factory with type inference\n *\n * @example\n * ```ts\n * // Factory with 2 params (would be misdetected by defineMiddleware)\n * export const rateLimiter = defineMiddlewareFactory('rateLimit',\n * (limit: number, window: number) => async (c, next) => {\n * // rate limit logic using limit and window\n * await next();\n * }\n * );\n *\n * // Usage\n * route.get('/api')\n * .use([rateLimiter(100, 60000)]) // 100 requests per minute\n * .handler(...)\n * ```\n */\nexport function defineMiddlewareFactory<TName extends string, TArgs extends unknown[]>(\n name: TName,\n factory: (...args: TArgs) => MiddlewareHandler\n): NamedMiddlewareFactory<TName, TArgs>\n{\n const wrapper = (...args: TArgs) => factory(...args);\n\n Object.defineProperty(wrapper, 'name', {\n value: name,\n writable: false,\n enumerable: false,\n configurable: true,\n });\n\n Object.defineProperty(wrapper, '_name', {\n value: name as TName,\n writable: false,\n enumerable: false,\n configurable: true,\n });\n\n return wrapper as NamedMiddlewareFactory<TName, TArgs>;\n}\n\n/**\n * Extract middleware names from an array of named middlewares\n *\n * @example\n * ```ts\n * type Middlewares = [\n * NamedMiddleware<'auth'>,\n * NamedMiddleware<'rateLimit'>\n * ];\n * type Names = ExtractMiddlewareNames<Middlewares>; // 'auth' | 'rateLimit'\n * ```\n */\nexport type ExtractMiddlewareNames<T extends readonly NamedMiddleware<string>[]> =\n T[number]['_name'];","/**\n * Route Helper Functions\n *\n * Type guards and TypeBox utilities\n */\n\nimport type { TSchema } from '@sinclair/typebox';\nimport { Type } from '@sinclair/typebox';\nimport type { HttpMethod } from './types';\n\n/**\n * Type guard for HttpMethod\n */\nexport function isHttpMethod(value: unknown): value is HttpMethod\n{\n return (\n typeof value === 'string' &&\n ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].includes(value)\n );\n}\n\n/**\n * Nullable - Creates a union of T | null\n *\n * @example\n * ```typescript\n * // string | null\n * firstName: Nullable(Type.String())\n * ```\n */\nexport const Nullable = <T extends TSchema>(schema: T) =>\n Type.Union([schema, Type.Null()]);\n\n/**\n * OptionalNullable - Creates a union of T | null | undefined\n *\n * @example\n * ```typescript\n * // string | null | undefined\n * lastName: OptionalNullable(Type.String())\n * ```\n */\nexport const OptionalNullable = <T extends TSchema>(schema: T) =>\n Type.Optional(Type.Union([schema, Type.Null()]));"]}
@@ -1,38 +1,9 @@
1
1
  /**
2
2
  * Route Type Definitions
3
3
  */
4
- type HeaderRecord = Record<string, string | string[]>;
5
- type RouteMeta = {
6
- public?: boolean;
7
- skipMiddlewares?: string[];
8
- tags?: string[];
9
- description?: string;
10
- deprecated?: boolean;
11
- };
12
4
  /**
13
- * Extract data type from ApiSuccessResponse<T>
14
- *
15
- * If response type is ApiSuccessResponse<T>, extracts T (the data field type).
16
- * Otherwise, returns the response type as-is.
5
+ * Supported HTTP methods for route definitions
17
6
  */
18
- type InferResponseData<T> = T extends {
19
- success: true;
20
- data: infer D;
21
- } ? D : T;
22
7
  type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
23
- /**
24
- * Route metadata for codegen
25
- */
26
- interface RouteMetadata {
27
- method: string;
28
- path: string;
29
- }
30
- /**
31
- * Router metadata containing all routes
32
- */
33
- interface RouterMetadata {
34
- routes: Record<string, RouteMetadata>;
35
- routerTypeName: string;
36
- }
37
8
 
38
- export type { HeaderRecord, HttpMethod, InferResponseData, RouteMeta, RouteMetadata, RouterMetadata };
9
+ export type { HttpMethod };
@@ -2,7 +2,7 @@ import { MiddlewareHandler, Hono } from 'hono';
2
2
  import { cors } from 'hono/cors';
3
3
  import { serve } from '@hono/node-server';
4
4
  import { NamedMiddleware, Router } from '@spfn/core/route';
5
- import { J as JobRouter, B as BossConfig } from '../boss-D-fGtVgM.js';
5
+ import { J as JobRouter, B as BossOptions } from '../boss-BO8ty33K.js';
6
6
  import '@sinclair/typebox';
7
7
  import 'pg-boss';
8
8
 
@@ -117,7 +117,7 @@ interface ServerConfig {
117
117
  * pg-boss configuration options
118
118
  * Only used if jobs router is provided
119
119
  */
120
- jobsConfig?: Omit<BossConfig, 'connectionString'>;
120
+ jobsConfig?: Omit<BossOptions, 'connectionString'>;
121
121
  /**
122
122
  * Enable debug mode (default: NODE_ENV === 'development')
123
123
  */
@@ -545,7 +545,7 @@ declare class ServerConfigBuilder {
545
545
  * .build();
546
546
  * ```
547
547
  */
548
- jobs(router: JobRouter<any>, config?: Omit<BossConfig, 'connectionString'>): this;
548
+ jobs(router: JobRouter<any>, config?: Omit<BossOptions, 'connectionString'>): this;
549
549
  /**
550
550
  * Enable/disable debug mode
551
551
  */
@@ -592,10 +592,10 @@ declare class ServerConfigBuilder {
592
592
  *
593
593
  * const appRouter = defineRouter({
594
594
  * getUser: route.get('/users/:id')
595
- * .input(Type.Object({ id: Type.String() }))
595
+ * .input({ params: Type.Object({ id: Type.String() }) })
596
596
  * .handler(async (c) => {
597
- * const { id } = await c.data();
598
- * return c.success({ id, name: 'John' });
597
+ * const { params } = await c.data();
598
+ * return { id: params.id, name: 'John' };
599
599
  * }),
600
600
  * });
601
601
  *
@@ -540,18 +540,18 @@ function isDebugMode(config2) {
540
540
  var jobLogger = logger.child("@spfn/core:job");
541
541
  var bossInstance = null;
542
542
  var bossConfig = null;
543
- async function initBoss(config2) {
543
+ async function initBoss(options) {
544
544
  if (bossInstance) {
545
545
  jobLogger.warn("pg-boss already initialized, returning existing instance");
546
546
  return bossInstance;
547
547
  }
548
548
  jobLogger.info("Initializing pg-boss...");
549
- bossConfig = config2;
549
+ bossConfig = options;
550
550
  bossInstance = new PgBoss({
551
- connectionString: config2.connectionString,
552
- schema: config2.schema ?? "spfn_queue",
553
- maintenanceIntervalSeconds: config2.maintenanceIntervalSeconds ?? 120,
554
- monitorIntervalSeconds: config2.monitorIntervalSeconds
551
+ connectionString: options.connectionString,
552
+ schema: options.schema ?? "spfn_queue",
553
+ maintenanceIntervalSeconds: options.maintenanceIntervalSeconds ?? 120,
554
+ monitorIntervalSeconds: options.monitorIntervalSeconds
555
555
  });
556
556
  bossInstance.on("error", (error) => {
557
557
  jobLogger.error("pg-boss error:", error);