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

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.
Files changed (43) hide show
  1. package/README.md +91 -6
  2. package/dist/{boss-D-fGtVgM.d.ts → boss-BO8ty33K.d.ts} +45 -5
  3. package/dist/config/index.d.ts +36 -0
  4. package/dist/config/index.js +15 -6
  5. package/dist/config/index.js.map +1 -1
  6. package/dist/env/index.d.ts +29 -3
  7. package/dist/env/index.js +13 -13
  8. package/dist/env/index.js.map +1 -1
  9. package/dist/env/loader.d.ts +87 -0
  10. package/dist/env/loader.js +70 -0
  11. package/dist/env/loader.js.map +1 -0
  12. package/dist/event/index.d.ts +3 -70
  13. package/dist/event/index.js +10 -1
  14. package/dist/event/index.js.map +1 -1
  15. package/dist/event/sse/client.d.ts +82 -0
  16. package/dist/event/sse/client.js +115 -0
  17. package/dist/event/sse/client.js.map +1 -0
  18. package/dist/event/sse/index.d.ts +40 -0
  19. package/dist/event/sse/index.js +92 -0
  20. package/dist/event/sse/index.js.map +1 -0
  21. package/dist/job/index.d.ts +34 -3
  22. package/dist/job/index.js +18 -9
  23. package/dist/job/index.js.map +1 -1
  24. package/dist/middleware/index.d.ts +102 -11
  25. package/dist/middleware/index.js +2 -2
  26. package/dist/middleware/index.js.map +1 -1
  27. package/dist/nextjs/index.d.ts +2 -2
  28. package/dist/nextjs/index.js +1 -1
  29. package/dist/nextjs/index.js.map +1 -1
  30. package/dist/nextjs/server.d.ts +2 -2
  31. package/dist/nextjs/server.js +4 -1
  32. package/dist/nextjs/server.js.map +1 -1
  33. package/dist/route/index.d.ts +72 -13
  34. package/dist/route/index.js +82 -27
  35. package/dist/route/index.js.map +1 -1
  36. package/dist/route/types.d.ts +2 -31
  37. package/dist/router-Di7ENoah.d.ts +151 -0
  38. package/dist/server/index.d.ts +82 -6
  39. package/dist/server/index.js +175 -14
  40. package/dist/server/index.js.map +1 -1
  41. package/dist/types-B-e_f2dQ.d.ts +121 -0
  42. package/dist/{types-DRG2XMTR.d.ts → types-D_N_U-Py.d.ts} +76 -3
  43. package/package.json +18 -3
@@ -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
  */
@@ -304,16 +336,20 @@ function isRouteDef(value) {
304
336
  function isNamedMiddleware(value) {
305
337
  return value !== null && typeof value === "object" && "name" in value && "handler" in value && "_name" in value;
306
338
  }
307
- function registerRoutes(app, router, namedMiddlewares) {
339
+ function registerRoutes(app, router, namedMiddlewares, collectedRoutes) {
340
+ const routes = collectedRoutes ?? [];
308
341
  const allNamedMiddlewares = [
309
342
  ...namedMiddlewares ?? [],
310
343
  ...router._globalMiddlewares.map((mw) => ({ name: mw.name, handler: mw.handler }))
311
344
  ];
312
345
  for (const [name, routeOrRouter] of Object.entries(router.routes)) {
313
346
  if (isRouter(routeOrRouter)) {
314
- registerRoutes(app, routeOrRouter, allNamedMiddlewares);
347
+ registerRoutes(app, routeOrRouter, allNamedMiddlewares, routes);
315
348
  } else if (isRouteDef(routeOrRouter)) {
316
- registerRoute(app, name, routeOrRouter, allNamedMiddlewares);
349
+ const registered = registerRoute(app, name, routeOrRouter, allNamedMiddlewares);
350
+ if (registered) {
351
+ routes.push(registered);
352
+ }
317
353
  } else {
318
354
  logger.warn(`Unknown route type for "${name}" - skipping`, {
319
355
  type: typeof routeOrRouter
@@ -322,9 +358,10 @@ function registerRoutes(app, router, namedMiddlewares) {
322
358
  }
323
359
  if (router._packageRouters && router._packageRouters.length > 0) {
324
360
  for (const pkgRouter of router._packageRouters) {
325
- registerRoutes(app, pkgRouter, allNamedMiddlewares);
361
+ registerRoutes(app, pkgRouter, allNamedMiddlewares, routes);
326
362
  }
327
363
  }
364
+ return routes;
328
365
  }
329
366
  function registerRoute(app, name, routeDef, namedMiddlewares) {
330
367
  const { method, path, input, middlewares = [], skipMiddlewares, handler } = routeDef;
@@ -333,15 +370,22 @@ function registerRoute(app, name, routeDef, namedMiddlewares) {
333
370
  method,
334
371
  path
335
372
  });
336
- return;
373
+ return null;
337
374
  }
338
375
  const wrappedHandler = async (c) => {
339
- const context = await createRouteBuilderContext(c, input || {});
376
+ const { context, responseMeta } = await createRouteBuilderContext(c, input || {});
340
377
  const result = await handler(context);
341
378
  if (result instanceof Response) {
342
379
  return result;
343
380
  }
344
- return c.json(result);
381
+ if (responseMeta.isEmpty) {
382
+ return c.body(null, responseMeta.status);
383
+ }
384
+ const hasCustomHeaders = Object.keys(responseMeta.headers).length > 0;
385
+ if (hasCustomHeaders) {
386
+ return c.json(result, responseMeta.status, responseMeta.headers);
387
+ }
388
+ return c.json(result, responseMeta.status);
345
389
  };
346
390
  const allMiddlewares = [];
347
391
  const registeredNames = /* @__PURE__ */ new Set();
@@ -387,6 +431,7 @@ function registerRoute(app, name, routeDef, namedMiddlewares) {
387
431
  app[methodLower](path, wrappedHandler);
388
432
  }
389
433
  logger.debug(`Registered route: ${method} ${path}`, { name });
434
+ return { method, path, name };
390
435
  }
391
436
  async function createRouteBuilderContext(c, input) {
392
437
  const params = validateField(input.params, c.req.param(), "path parameters");
@@ -398,38 +443,47 @@ async function createRouteBuilderContext(c, input) {
398
443
  const rawBody = await parseJsonBody(c);
399
444
  body = validateField(input.body, rawBody, "request body");
400
445
  }
401
- return {
402
- data: async () => ({
403
- params,
404
- query,
405
- body,
406
- headers,
407
- cookies
408
- }),
446
+ let cachedData = null;
447
+ const responseMeta = {
448
+ status: 200,
449
+ headers: {},
450
+ isEmpty: false
451
+ };
452
+ const context = {
453
+ data: async () => {
454
+ if (!cachedData) {
455
+ cachedData = { params, query, body, headers, cookies };
456
+ }
457
+ return cachedData;
458
+ },
409
459
  json: (data, status, resHeaders) => {
410
460
  return c.json(data, status, resHeaders);
411
461
  },
412
462
  created: (data, location) => {
413
- const resHeaders = {};
463
+ responseMeta.status = 201;
414
464
  if (location) {
415
- resHeaders["Location"] = location;
465
+ responseMeta.headers["Location"] = location;
416
466
  }
417
- return c.json(data, 201, resHeaders);
467
+ return data;
418
468
  },
419
469
  accepted: (data) => {
470
+ responseMeta.status = 202;
420
471
  if (data === void 0) {
421
- return c.body(null, 202);
472
+ responseMeta.isEmpty = true;
473
+ return void 0;
422
474
  }
423
- return c.json(data, 202);
475
+ return data;
424
476
  },
425
477
  noContent: () => {
426
- return c.body(null, 204);
478
+ responseMeta.status = 204;
479
+ responseMeta.isEmpty = true;
427
480
  },
428
481
  notModified: () => {
429
- return c.body(null, 304);
482
+ responseMeta.status = 304;
483
+ responseMeta.isEmpty = true;
430
484
  },
431
485
  paginated: (data, page, limit, total) => {
432
- return c.json({
486
+ return {
433
487
  items: data,
434
488
  pagination: {
435
489
  page,
@@ -437,13 +491,14 @@ async function createRouteBuilderContext(c, input) {
437
491
  total,
438
492
  totalPages: Math.ceil(total / limit)
439
493
  }
440
- }, 200);
494
+ };
441
495
  },
442
496
  redirect: (url, status) => {
443
497
  return c.redirect(url, status);
444
498
  },
445
499
  raw: c
446
500
  };
501
+ return { context, responseMeta };
447
502
  }
448
503
 
449
504
  // src/route/define-middleware.ts
@@ -502,6 +557,6 @@ function isHttpMethod(value) {
502
557
  var Nullable = (schema) => Type.Union([schema, Type.Null()]);
503
558
  var OptionalNullable = (schema) => Type.Optional(Type.Union([schema, Type.Null()]));
504
559
 
505
- export { Nullable, OptionalNullable, RouteBuilder, defineMiddleware, defineMiddlewareFactory, defineRouter, isHttpMethod, registerRoutes, route };
560
+ export { Nullable, OptionalNullable, defineMiddleware, defineMiddlewareFactory, defineRouter, isHttpMethod, registerRoutes, route };
506
561
  //# sourceMappingURL=index.js.map
507
562
  //# 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 * Registered route information for logging\n */\nexport interface RegisteredRoute\n{\n method: HttpMethod;\n path: string;\n name: string;\n}\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 * @param collectedRoutes\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 collectedRoutes?: RegisteredRoute[]\n): RegisteredRoute[]\n{\n // Use provided array or create new one (top-level call)\n const routes = collectedRoutes ?? [];\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, routes);\n }\n else if (isRouteDef(routeOrRouter))\n {\n // Single route - register\n const registered = registerRoute(app, name, routeOrRouter, allNamedMiddlewares);\n if (registered)\n {\n routes.push(registered);\n }\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, routes);\n }\n }\n\n return routes;\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): RegisteredRoute | null\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 null;\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 return { 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 };
@@ -0,0 +1,151 @@
1
+ import { TSchema } from '@sinclair/typebox';
2
+
3
+ /**
4
+ * Event System Types
5
+ */
6
+
7
+ /**
8
+ * Pub/Sub capable cache interface for multi-instance events
9
+ */
10
+ interface PubSubCache {
11
+ /**
12
+ * Publish a message to a channel
13
+ */
14
+ publish(channel: string, message: unknown): Promise<void>;
15
+ /**
16
+ * Subscribe to a channel
17
+ */
18
+ subscribe(channel: string, handler: (message: unknown) => void | Promise<void>): Promise<void>;
19
+ }
20
+ /**
21
+ * Event handler function type
22
+ */
23
+ type EventHandler<TPayload> = (payload: TPayload) => void | Promise<void>;
24
+ /**
25
+ * Job queue sender function type (used by job module)
26
+ */
27
+ type JobQueueSender = (queueName: string, payload: unknown) => Promise<void>;
28
+ /**
29
+ * Event definition interface
30
+ */
31
+ interface EventDef<TPayload = void> {
32
+ /**
33
+ * Unique event name
34
+ */
35
+ readonly name: string;
36
+ /**
37
+ * TypeBox payload schema (optional)
38
+ */
39
+ readonly schema?: TSchema;
40
+ /**
41
+ * Subscribe to this event (in-memory handler)
42
+ */
43
+ subscribe: (handler: EventHandler<TPayload>) => () => void;
44
+ /**
45
+ * Unsubscribe all handlers
46
+ */
47
+ unsubscribeAll: () => void;
48
+ /**
49
+ * Emit the event (triggers all subscribers and queued jobs)
50
+ */
51
+ emit: TPayload extends void ? () => Promise<void> : (payload: TPayload) => Promise<void>;
52
+ /**
53
+ * Enable cache-based pub/sub for multi-instance support
54
+ * Must await before emitting events to ensure subscription is ready
55
+ */
56
+ useCache: (cache: PubSubCache) => Promise<EventDef<TPayload>>;
57
+ /**
58
+ * Internal: Register a job queue to receive this event
59
+ * Called by job registration system
60
+ */
61
+ _registerJobQueue: (queueName: string, sender: JobQueueSender) => void;
62
+ /**
63
+ * Type inference helper
64
+ */
65
+ _payload: TPayload;
66
+ }
67
+ /**
68
+ * Infer payload type from EventDef
69
+ */
70
+ type InferEventPayload$1<TEvent> = TEvent extends EventDef<infer TPayload> ? TPayload : never;
71
+
72
+ /**
73
+ * Event Router
74
+ *
75
+ * Type-safe event router for SSE subscription
76
+ *
77
+ * @example
78
+ * ```typescript
79
+ * import { defineEvent, defineEventRouter } from '@spfn/core/event';
80
+ * import { Type } from '@sinclair/typebox';
81
+ *
82
+ * const userCreated = defineEvent('user.created', Type.Object({
83
+ * userId: Type.String(),
84
+ * }));
85
+ *
86
+ * const orderPlaced = defineEvent('order.placed', Type.Object({
87
+ * orderId: Type.String(),
88
+ * amount: Type.Number(),
89
+ * }));
90
+ *
91
+ * export const eventRouter = defineEventRouter({
92
+ * userCreated,
93
+ * orderPlaced,
94
+ * });
95
+ *
96
+ * export type EventRouter = typeof eventRouter;
97
+ * ```
98
+ */
99
+
100
+ /**
101
+ * Event Router Definition
102
+ */
103
+ interface EventRouterDef<TEvents extends Record<string, EventDef<any>>> {
104
+ /**
105
+ * Event definitions
106
+ */
107
+ readonly events: TEvents;
108
+ /**
109
+ * Event names as array
110
+ */
111
+ readonly eventNames: (keyof TEvents)[];
112
+ /**
113
+ * Type inference helper - payload types by event name
114
+ */
115
+ readonly _types: {
116
+ [K in keyof TEvents]: TEvents[K]['_payload'];
117
+ };
118
+ }
119
+ /**
120
+ * Infer event names from EventRouter
121
+ */
122
+ type InferEventNames<T> = T extends EventRouterDef<infer E> ? keyof E & string : never;
123
+ /**
124
+ * Infer payload type for specific event
125
+ */
126
+ type InferEventPayload<T extends EventRouterDef<any>, K extends InferEventNames<T>> = T['_types'][K];
127
+ /**
128
+ * Infer all event payloads map
129
+ */
130
+ type InferEventPayloads<T extends EventRouterDef<any>> = T['_types'];
131
+ /**
132
+ * Define an event router for SSE subscription
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * export const eventRouter = defineEventRouter({
137
+ * userCreated,
138
+ * orderPlaced,
139
+ * });
140
+ *
141
+ * // Type inference
142
+ * type Names = InferEventNames<typeof eventRouter>;
143
+ * // 'userCreated' | 'orderPlaced'
144
+ *
145
+ * type Payload = InferEventPayload<typeof eventRouter, 'userCreated'>;
146
+ * // { userId: string }
147
+ * ```
148
+ */
149
+ declare function defineEventRouter<TEvents extends Record<string, EventDef<any>>>(events: TEvents): EventRouterDef<TEvents>;
150
+
151
+ export { type EventRouterDef as E, type InferEventNames as I, type JobQueueSender as J, type PubSubCache as P, type EventDef as a, type InferEventPayload as b, type InferEventPayloads as c, defineEventRouter as d, type EventHandler as e, type InferEventPayload$1 as f };