@taserjs/router 0.0.5 → 0.1.0

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 (68) hide show
  1. package/dist/cjs/builder/app.cjs +5 -0
  2. package/dist/cjs/builder/app.cjs.map +1 -1
  3. package/dist/cjs/builder/app.d.cts +7 -7
  4. package/dist/cjs/builder/factories.cjs +4 -4
  5. package/dist/cjs/builder/factories.cjs.map +1 -1
  6. package/dist/cjs/builder/factories.d.cts +5 -51
  7. package/dist/cjs/builder/route.cjs +22 -1
  8. package/dist/cjs/builder/route.cjs.map +1 -1
  9. package/dist/cjs/builder/route.d.cts +1 -2
  10. package/dist/cjs/builder/router.cjs +3 -5
  11. package/dist/cjs/builder/router.cjs.map +1 -1
  12. package/dist/cjs/builder/router.d.cts +11 -12
  13. package/dist/cjs/define/middleware.cjs +2 -2
  14. package/dist/cjs/define/middleware.cjs.map +1 -1
  15. package/dist/cjs/define/middleware.d.cts +10 -8
  16. package/dist/cjs/index.cjs +0 -12
  17. package/dist/cjs/index.d.cts +4 -4
  18. package/dist/cjs/reply.cjs +8 -19
  19. package/dist/cjs/reply.d.cts +1 -2
  20. package/dist/cjs/stream.cjs +8 -31
  21. package/dist/cjs/stream.d.cts +1 -1
  22. package/dist/cjs/types/app.d.cts +3 -21
  23. package/dist/cjs/types/index.d.cts +29 -7
  24. package/dist/cjs/types/returns.d.cts +6 -9
  25. package/dist/cjs/types/type-utils.d.cts +7 -5
  26. package/dist/cjs/types/units.cjs.map +1 -1
  27. package/dist/cjs/types/units.d.cts +4 -10
  28. package/dist/esm/builder/app.d.ts +7 -7
  29. package/dist/esm/builder/app.js +5 -1
  30. package/dist/esm/builder/app.js.map +1 -1
  31. package/dist/esm/builder/factories.d.ts +5 -51
  32. package/dist/esm/builder/factories.js +4 -4
  33. package/dist/esm/builder/factories.js.map +1 -1
  34. package/dist/esm/builder/route.d.ts +1 -2
  35. package/dist/esm/builder/route.js +22 -1
  36. package/dist/esm/builder/route.js.map +1 -1
  37. package/dist/esm/builder/router.d.ts +11 -12
  38. package/dist/esm/builder/router.js +3 -5
  39. package/dist/esm/builder/router.js.map +1 -1
  40. package/dist/esm/define/middleware.d.ts +10 -8
  41. package/dist/esm/define/middleware.js +2 -2
  42. package/dist/esm/define/middleware.js.map +1 -1
  43. package/dist/esm/index.d.ts +4 -4
  44. package/dist/esm/index.js +2 -2
  45. package/dist/esm/reply.d.ts +1 -2
  46. package/dist/esm/reply.js +1 -2
  47. package/dist/esm/stream.d.ts +1 -1
  48. package/dist/esm/stream.js +1 -2
  49. package/dist/esm/types/app.d.ts +3 -21
  50. package/dist/esm/types/index.d.ts +29 -7
  51. package/dist/esm/types/returns.d.ts +6 -9
  52. package/dist/esm/types/type-utils.d.ts +7 -5
  53. package/dist/esm/types/units.d.ts +4 -10
  54. package/dist/esm/types/units.js.map +1 -1
  55. package/package.json +3 -3
  56. package/src/builder/app.ts +16 -5
  57. package/src/builder/factories.ts +28 -155
  58. package/src/builder/route.ts +25 -1
  59. package/src/builder/router.ts +24 -157
  60. package/src/define/middleware.ts +115 -123
  61. package/src/index.ts +5 -9
  62. package/src/reply.ts +1 -11
  63. package/src/stream.ts +1 -1
  64. package/src/types/app.ts +3 -22
  65. package/src/types/index.ts +83 -13
  66. package/src/types/returns.ts +7 -76
  67. package/src/types/type-utils.ts +9 -4
  68. package/src/types/units.ts +34 -10
@@ -1,26 +1,16 @@
1
- import { RouteManifestShape } from '@taserjs/router-core';
1
+ import { CookieRuntimeConfig, RouteManifestShape } from '@taserjs/router-core';
2
2
  import { ResponseValidationFailureHandler } from '@taserjs/router-utils';
3
3
  import { TaserApp } from '../builder/app.js';
4
4
  import { ReturnsMap } from './returns.js';
5
5
  import { Schema } from './schema.js';
6
6
  export type CreateTaserAppOptions = {
7
- basePath?: string;
8
7
  response?: {
9
8
  /** Validate handler replies against returns maps. Default true. */
10
9
  validate?: boolean;
11
10
  onValidationFailure?: ResponseValidationFailureHandler;
12
11
  };
13
12
  /** Global cookie defaults and signing secret. Per-call `ctx.cookies.set` options override defaults. */
14
- cookies?: {
15
- secret?: string | BufferSource;
16
- path?: string;
17
- httpOnly?: boolean;
18
- sameSite?: "Strict" | "Lax" | "None" | "strict" | "lax" | "none";
19
- secure?: boolean;
20
- domain?: string;
21
- maxAge?: number;
22
- expires?: Date;
23
- };
13
+ cookies?: CookieRuntimeConfig;
24
14
  };
25
15
  export type ContextDefinition<TBoot extends Record<string, unknown> = Record<string, never>, TReq extends Record<string, unknown> = Record<string, never>> = {
26
16
  boot?: () => TBoot | Promise<TBoot>;
@@ -31,17 +21,9 @@ export type OnErrorOptions<TResponses extends ReturnsMap = ReturnsMap> = {
31
21
  responses?: TResponses;
32
22
  handle: (error: unknown, ctx?: unknown) => Response | Promise<Response>;
33
23
  };
34
- export type InferAppManifest<TApp> = TApp extends TaserApp<infer TManifest> ? TManifest : TApp extends {
24
+ export type InferAppManifest<TApp> = TApp extends TaserApp<infer TManifest, any> ? TManifest : TApp extends {
35
25
  manifest: infer TManifest;
36
26
  } ? TManifest : TApp extends RouteManifestShape ? TApp : never;
37
- export type TaserHandler<TFrameworkApp> = {
38
- /**
39
- * Mount the Taser handler on a framework app.
40
- * Use universal wildcard patterns (`/*`, `/prefix/*`) for Hono/Fastify.
41
- * Use framework-native splat patterns for Express (e.g. `/{*splat}`, `/*splat`).
42
- */
43
- mount(pattern: string, frameworkApp: TFrameworkApp): void;
44
- };
45
27
  export type { RouteManifestShape } from '@taserjs/router-core';
46
28
  export type { Schema };
47
29
  export type { TaserApp } from '../builder/app.js';
@@ -1,13 +1,13 @@
1
1
  import { Awaitable, TaserCookieJar, TaserHeaders } from '@taserjs/router-core';
2
2
  import { RouterRegister } from '../register.js';
3
- import { MergeMiddlewareField, MergeMiddlewareInputField, MergePart, RequestShape, RuntimeContextFields, Simplify, UnionToIntersection } from './type-utils.js';
3
+ import { MergeMiddlewareField, MergeMiddlewareInputField, MergePart, RequestShape, Simplify, UnionToIntersection, UnitRuntimeContext } from './type-utils.js';
4
4
  import { ReturnsMap, ValidHandlerReply } from './returns.js';
5
5
  import { Schema } from './schema.js';
6
6
  import { AppContext, ExtractState, HandlerContext, HandlerUnit, InlineMiddlewareOptions, Method, MiddlewareDefinition, MiddlewareReturnFromParts, MiddlewareUnit, ValidatorParts } from './units.js';
7
7
  export type { Awaitable } from '@taserjs/router-core';
8
8
  export type { SchemaRequestShape, InferInput, InferOutput, Schema, StandardSchemaV1, } from './schema.js';
9
9
  export type { RouterRegister } from '../register.js';
10
- export type { MergeMiddlewareField, MergeMiddlewareInputField, MergePart, RequestShape, Simplify, UnwrapPart, } from './type-utils.js';
10
+ export type { MergeMiddlewareField, MergeMiddlewareInputField, MergePart, RequestShape, Simplify, UnitRuntimeContext, UnwrapPart, } from './type-utils.js';
11
11
  export type { EmptyReturns, EnforceHandlerReply, HandlerReply, HasReturns, MergeReturns, ReplyFor, ReturnsMap, StatusCode, ValidHandlerReply, } from './returns.js';
12
12
  export type { AppContext, ExtractState, HandlerContext, HandlerUnit, HttpMethod, InlineMiddlewareOptions, IsUnknown, Method, MiddlewareDefinition, MiddlewareNext, MiddlewareReturnFromParts, MiddlewareUnit, NextFn, NextResult, StandaloneMiddlewareContext, StateBrand, ValidatorParts, } from './units.js';
13
13
  export type RoutePath = RouterRegister extends {
@@ -57,9 +57,11 @@ type RouteParent<Path extends RoutePath, TMethod extends Method> = RouteEntry<Pa
57
57
  type RouteLayoutChain<Path extends RoutePath, TMethod extends Method> = RouteEntry<Path, TMethod> extends {
58
58
  layoutChain: infer Chain extends readonly LayoutId[];
59
59
  } ? Chain : RouteParent<Path, TMethod> extends LayoutId ? readonly [RouteParent<Path, TMethod>] : readonly [];
60
- type RouteResolvedField<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], Field extends "query" | "params" | "body" | "state"> = MergeMiddlewareField<ResolveLayoutChainMiddlewares<RouteLayoutChain<Path, TMethod>>, Field> & MergeMiddlewareField<Acc, Field>;
60
+ export type RouteLayoutMiddlewares<Path extends RoutePath, TMethod extends Method> = ResolveLayoutChainMiddlewares<RouteLayoutChain<Path, TMethod>>;
61
+ export type RouteLayoutField<Path extends RoutePath, TMethod extends Method, Field extends "query" | "params" | "body" | "state"> = MergeMiddlewareField<RouteLayoutMiddlewares<Path, TMethod>, Field>;
62
+ export type RouteLayoutInputField<Path extends RoutePath, TMethod extends Method, Field extends "query" | "params" | "body"> = MergeMiddlewareInputField<RouteLayoutMiddlewares<Path, TMethod>, Field>;
63
+ type RouteResolvedField<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], Field extends "query" | "params" | "body" | "state"> = RouteLayoutField<Path, TMethod, Field> & MergeMiddlewareField<Acc, Field>;
61
64
  type RouteChainField<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], Field extends "query" | "params" | "body" | "state"> = RouteResolvedField<Path, TMethod, Acc, Field>;
62
- type UnitRuntimeContext = Omit<RuntimeContextFields, "var">;
63
65
  export type RouteChainContext<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], TQuery, TParams, TBody, TAppContext extends Record<string, unknown> = AppContext> = Simplify<TAppContext & UnitRuntimeContext & {
64
66
  query: Simplify<MergePart<TQuery, RouteChainField<Path, TMethod, Acc, "query">>>;
65
67
  params: Simplify<ResolveParams<PathParams<Path>, MergePart<TParams, RouteChainField<Path, TMethod, Acc, "params">>>>;
@@ -105,7 +107,7 @@ export type RouteHandleContextWithoutBody<Path extends RoutePath, TMethod extend
105
107
  headers: TaserHeaders;
106
108
  cookies: TaserCookieJar;
107
109
  }>;
108
- type RouteResolvedInputField<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], Field extends "query" | "params" | "body"> = MergeMiddlewareInputField<ResolveLayoutChainMiddlewares<RouteLayoutChain<Path, TMethod>>, Field> & MergeMiddlewareInputField<Acc, Field>;
110
+ type RouteResolvedInputField<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], Field extends "query" | "params" | "body"> = RouteLayoutInputField<Path, TMethod, Field> & MergeMiddlewareInputField<Acc, Field>;
109
111
  type IsNever<T> = [T] extends [never] ? true : false;
110
112
  type IsEmptyObject<T> = [keyof T] extends [never] ? true : false;
111
113
  export type IsLayoutAllowed<TRequiredLayouts, TChain extends readonly LayoutId[]> = [
@@ -139,7 +141,8 @@ export type InferRouteInputFromPath<Path extends RoutePath, TMethod extends Meth
139
141
  Input: infer I;
140
142
  };
141
143
  } ? I : never : never;
142
- type MiddlewareChainField<Layout extends LayoutId, Acc extends readonly unknown[], Field extends "query" | "params" | "body" | "state"> = MergeMiddlewareField<ResolveLayoutMiddlewares<LayoutParent<Layout>>, Field> & MergeMiddlewareField<Acc, Field>;
144
+ export type MiddlewareLayoutField<Layout extends LayoutId, Field extends "query" | "params" | "body" | "state"> = MergeMiddlewareField<ResolveLayoutMiddlewares<LayoutParent<Layout>>, Field>;
145
+ type MiddlewareChainField<Layout extends LayoutId, Acc extends readonly unknown[], Field extends "query" | "params" | "body" | "state"> = MiddlewareLayoutField<Layout, Field> & MergeMiddlewareField<Acc, Field>;
143
146
  export type MiddlewareChainContext<Layout extends LayoutId, Acc extends readonly unknown[], TQuery, TParams, TBody, TAppContext extends Record<string, unknown> = AppContext> = Simplify<TAppContext & UnitRuntimeContext & {
144
147
  query: Simplify<MergePart<TQuery, MiddlewareChainField<Layout, Acc, "query">>>;
145
148
  params: Simplify<MergePart<TParams, MiddlewareChainField<Layout, Acc, "params">>>;
@@ -178,6 +181,7 @@ export type RouteExport<Path extends RoutePath, TMethod extends Method, Acc exte
178
181
  readonly middlewares: readonly MiddlewareDefinition[];
179
182
  readonly handlerMiddlewares: readonly MiddlewareDefinition[];
180
183
  readonly returns?: TReturns;
184
+ readonly bodyMode?: "json" | "form" | "urlencoded";
181
185
  handler: (ctx: unknown) => Awaitable<Response>;
182
186
  readonly $Infer: {
183
187
  Context: TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS" ? RouteHandleContextWithoutBody<Path, TMethod, Acc, {}> : RouteHandleContext<Path, TMethod, Acc, {}>;
@@ -198,7 +202,7 @@ type RouteHandleResult<Path extends RoutePath, TMethod extends Method, Acc exten
198
202
  Output: TOutput;
199
203
  };
200
204
  };
201
- export type RouteBuilder<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[] = readonly [], Validators extends ValidatorParts = {}, TReturns extends ReturnsMap = {}, TAppContext extends Record<string, unknown> = AppContext> = {
205
+ export type RouteBuilderBase<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[] = readonly [], Validators extends ValidatorParts = {}, TReturns extends ReturnsMap = {}, TAppContext extends Record<string, unknown> = AppContext> = {
202
206
  readonly path: Path;
203
207
  readonly method: TMethod;
204
208
  readonly $Infer: {
@@ -206,6 +210,14 @@ export type RouteBuilder<Path extends RoutePath, TMethod extends Method, Acc ext
206
210
  Input: TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS" ? RouteHandleInputWithoutBody<Path, TMethod, Acc, Validators> : RouteHandleInput<Path, TMethod, Acc, Validators>;
207
211
  Output: TReturns;
208
212
  };
213
+ query<TQuery, TQueryIn = unknown>(schema: Schema<TQuery, TQueryIn>): RouteBuilder<Path, TMethod, Acc, Omit<Validators, "query" | "queryIn"> & {
214
+ query: TQuery;
215
+ queryIn: TQueryIn;
216
+ }, TReturns, TAppContext>;
217
+ params<TParams, TParamsIn = unknown>(schema: Schema<TParams, TParamsIn>): RouteBuilder<Path, TMethod, Acc, Omit<Validators, "params" | "paramsIn"> & {
218
+ params: TParams;
219
+ paramsIn: TParamsIn;
220
+ }, TReturns, TAppContext>;
209
221
  returns<const M extends ReturnsMap>(map: M): RouteBuilder<Path, TMethod, Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>;
210
222
  use<TAcc, UReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(unit: MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequiredState>, ..._assert: [
211
223
  IsLayoutAllowed<TRequiredLayouts, RouteLayoutChain<Path, TMethod>>,
@@ -231,6 +243,16 @@ export type RouteBuilder<Path extends RoutePath, TMethod extends Method, Acc ext
231
243
  ]): RouteHandleResult<Path, TMethod, Acc, Validators, TReturns, R, TAppContext>;
232
244
  handler<HandlerAcc extends readonly unknown[] = readonly [], HandlerValidators extends ValidatorParts = ValidatorParts, HReturns extends ReturnsMap = {}, HOutput = Response>(unit: HandlerUnit<HandlerAcc, HandlerValidators, HReturns, HOutput>): RouteHandleResult<Path, TMethod, readonly [...Acc, ...HandlerAcc], Validators, Omit<TReturns, keyof HReturns> & HReturns, HOutput, TAppContext>;
233
245
  };
246
+ export type RouteBuilder<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[] = readonly [], Validators extends ValidatorParts = {}, TReturns extends ReturnsMap = {}, TAppContext extends Record<string, unknown> = AppContext> = RouteBuilderBase<Path, TMethod, Acc, Validators, TReturns, TAppContext> & (TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS" ? {} : {
247
+ body<TBody, TBodyIn = unknown>(schema: Schema<TBody, TBodyIn>): RouteBuilder<Path, TMethod, Acc, Omit<Validators, "body" | "bodyIn"> & {
248
+ body: TBody;
249
+ bodyIn: TBodyIn;
250
+ }, TReturns, TAppContext>;
251
+ body<Mode extends "json" | "form" | "urlencoded", TBody, TBodyIn = unknown>(mode: Mode, schema: Schema<TBody, TBodyIn>): RouteBuilder<Path, TMethod, Acc, Omit<Validators, "body" | "bodyIn"> & {
252
+ body: TBody;
253
+ bodyIn: TBodyIn;
254
+ }, TReturns, TAppContext>;
255
+ });
234
256
  export type HandlerBuilder<Acc extends readonly unknown[] = readonly [], Validators extends ValidatorParts = {}, TReturns extends ReturnsMap = {}, TAppContext extends Record<string, unknown> = AppContext> = {
235
257
  returns<const M extends ReturnsMap>(map: M): HandlerBuilder<Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>;
236
258
  use<TAcc, UReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(unit: MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequiredState>, ..._assert: [IsStateSatisfied<MergeMiddlewareField<Acc, "state">, TRequiredState>] extends [
@@ -1,21 +1,18 @@
1
- import { ReplyOf } from '@taserjs/router-utils';
1
+ import { ReplyOf } from '@taserjs/router-utils/reply';
2
+ import { StatusCode } from '@taserjs/router-utils';
2
3
  import { Simplify } from './type-utils.js';
3
4
  import { Schema, InferOutput } from './schema.js';
4
- /**
5
- * Known HTTP status codes. `number & {}` allows custom codes while keeping
6
- * literal autocomplete / inference for well-known values.
7
- */
8
- export type StatusCode = 100 | 101 | 102 | 103 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 226 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 421 | 422 | 423 | 424 | 425 | 426 | 428 | 429 | 431 | 451 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 | (number & {});
5
+ export type { StatusCode };
9
6
  /** Status-code → Standard Schema map for route/middleware/handler outputs. */
10
7
  export type ReturnsMap = {
11
- readonly [K in StatusCode]?: Schema<unknown>;
8
+ readonly [status: number]: Schema<unknown> | undefined;
12
9
  };
13
10
  /** Later map wins on overlapping status keys. */
14
11
  export type MergeReturns<A extends ReturnsMap, B extends ReturnsMap> = Omit<A, keyof B> & B;
15
12
  /** Typed reply union for statuses declared in a returns map. */
16
13
  export type ReplyFor<M extends ReturnsMap> = {
17
- [S in keyof M]-?: S extends StatusCode ? M[S] extends Schema<unknown> ? ReplyOf<S, Simplify<InferOutput<M[S]>>> : never : never;
18
- }[keyof M];
14
+ [S in keyof M & number]: M[S] extends Schema<unknown> ? ReplyOf<S, Simplify<InferOutput<M[S]>>> : never;
15
+ }[keyof M & number];
19
16
  export type EmptyReturns = {};
20
17
  /** True when no status schemas have been declared yet. */
21
18
  export type HasReturns<M extends ReturnsMap> = [keyof M] extends [never] ? false : true;
@@ -1,5 +1,7 @@
1
- export type Method = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD";
2
- export type HttpMethod = Method;
1
+ import { TaserCookieJar, TaserHeaders } from '@taserjs/router-core';
2
+ import { HttpMethod, HttpVerb } from '@taserjs/router-utils/http';
3
+ export type Method = HttpMethod;
4
+ export type { HttpMethod, HttpVerb };
3
5
  export type MiddlewareFieldName = "query" | "params" | "body" | "state";
4
6
  export type MiddlewareInputFieldName = "query" | "params" | "body";
5
7
  export type UnwrapPart<T> = unknown extends T ? {} : T;
@@ -41,8 +43,8 @@ export type RuntimeContextFields = {
41
43
  request: Request;
42
44
  method: Method;
43
45
  url: URL;
44
- headers: import('@taserjs/router-core').TaserHeaders;
45
- cookies: import('@taserjs/router-core').TaserCookieJar;
46
+ headers: TaserHeaders;
47
+ cookies: TaserCookieJar;
46
48
  var: Record<string, unknown>;
47
49
  };
48
- export {};
50
+ export type UnitRuntimeContext = Omit<RuntimeContextFields, "var">;
@@ -1 +1 @@
1
- {"version":3,"file":"units.cjs","names":[],"sources":["../../../src/types/units.ts"],"sourcesContent":["import type { Awaitable, TaserCookieJar, TaserHeaders } from \"@taserjs/router-core\";\n\nimport type {\n MergeMiddlewareField,\n MergePart,\n RequestShape,\n RuntimeContextFields,\n Simplify,\n UnwrapPart,\n} from \"./type-utils.js\";\nimport type { ReturnsMap } from \"./returns.js\";\nimport type { Schema } from \"./schema.js\";\n\nexport type { HttpMethod, Method } from \"./type-utils.js\";\nexport type {\n EmptyReturns,\n MergeReturns,\n ReturnsMap,\n HandlerReply,\n HasReturns,\n StatusCode,\n ValidHandlerReply,\n EnforceHandlerReply,\n} from \"./returns.js\";\n\n/** Default empty app context for standalone units without a bound router instance. */\nexport type AppContext = Record<never, never>;\n\nexport type ValidatorParts = {\n query?: unknown;\n params?: unknown;\n body?: unknown;\n queryIn?: unknown;\n paramsIn?: unknown;\n bodyIn?: unknown;\n};\n\nexport declare const StateBrand: unique symbol;\n\nexport type NextResult<TState = unknown> = Response & {\n readonly [StateBrand]?: TState;\n};\n\nexport type ExtractState<T> = [Extract<Awaited<T>, { [StateBrand]?: unknown }>] extends [never]\n ? {}\n : Extract<Awaited<T>, { [StateBrand]?: unknown }> extends { [StateBrand]?: infer S }\n ? [S] extends [never]\n ? {}\n : S\n : {};\n\nexport type IsUnknown<T> = [unknown] extends [T] ? true : false;\n\nexport type NextFn<TExpectedState = unknown> =\n IsUnknown<TExpectedState> extends true\n ? <S extends Record<string, unknown> = {}>(state?: S) => Promise<NextResult<S>>\n : (state: TExpectedState) => Promise<NextResult<TExpectedState>>;\n\nexport type MiddlewareNext = NextFn;\n\nexport type MiddlewareDefinition = {\n query?: unknown;\n params?: unknown;\n body?: unknown;\n returns?: ReturnsMap;\n handler: (ctx: unknown, next: MiddlewareNext) => Awaitable<Response | unknown>;\n};\n\nexport type MiddlewareReturnFromParts<\n TQuery,\n TParams,\n TBody,\n TState,\n TQueryIn = TQuery,\n TParamsIn = TParams,\n TBodyIn = TBody,\n> = {\n query: Simplify<UnwrapPart<TQuery>>;\n params: Simplify<UnwrapPart<TParams>>;\n body: Simplify<UnwrapPart<TBody>>;\n state: Simplify<UnwrapPart<TState>>;\n /** Pre-parse shapes merged into route `$Infer.Input`. */\n input: {\n query: RequestShape<TQueryIn, TQuery>;\n params: RequestShape<TParamsIn, TParams>;\n body: RequestShape<TBodyIn, TBody>;\n };\n};\n\ntype UnitRuntimeContext = Omit<RuntimeContextFields, \"var\">;\n\nexport type StandaloneMiddlewareContext<\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TAppContext extends Record<string, unknown> = AppContext,\n TState = {},\n> = Simplify<\n TAppContext &\n UnitRuntimeContext & {\n query: Simplify<UnwrapPart<TQuery>>;\n params: Simplify<UnwrapPart<TParams>>;\n body: Simplify<UnwrapPart<TBody>>;\n state: Simplify<UnwrapPart<TState>>;\n headers: TaserHeaders;\n cookies: TaserCookieJar;\n }\n>;\n\nexport type HandlerContext<\n Acc extends readonly unknown[],\n Validators extends ValidatorParts,\n TAppContext extends Record<string, unknown> = AppContext,\n> = Simplify<\n TAppContext &\n UnitRuntimeContext & {\n query: Simplify<\n MergePart<\n Validators extends { query?: infer Q } ? Q : unknown,\n MergeMiddlewareField<Acc, \"query\">\n >\n >;\n params: Simplify<\n MergePart<\n Validators extends { params?: infer P } ? P : unknown,\n MergeMiddlewareField<Acc, \"params\">\n >\n >;\n body: Simplify<\n MergePart<\n Validators extends { body?: infer B } ? B : unknown,\n MergeMiddlewareField<Acc, \"body\">\n >\n >;\n state: Simplify<MergeMiddlewareField<Acc, \"state\">>;\n headers: TaserHeaders;\n cookies: TaserCookieJar;\n }\n>;\n\nexport type MiddlewareUnit<\n TAcc = unknown,\n TReturns extends ReturnsMap = {},\n TRequiredLayouts = unknown,\n TRequiredState = unknown,\n> = MiddlewareDefinition & {\n readonly __middlewareAcc: TAcc;\n readonly __returns?: TReturns;\n readonly __requiredLayouts?: TRequiredLayouts;\n readonly __requiredState?: TRequiredState;\n};\n\nexport type HandlerUnit<\n _Acc extends readonly unknown[],\n _Validators extends ValidatorParts,\n TReturns extends ReturnsMap = {},\n TOutput = Response,\n> = {\n readonly __returns?: TReturns;\n readonly $Infer: {\n Output: TOutput;\n };\n middlewares: readonly MiddlewareDefinition[];\n handler: (ctx: unknown) => Awaitable<Response>;\n returns?: ReturnsMap;\n query?: Schema<unknown>;\n params?: Schema<unknown>;\n body?: Schema<unknown>;\n};\n\nexport type InlineMiddlewareOptions<\n Ctx = unknown,\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TReturns extends ReturnsMap = {},\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n R = unknown,\n> = {\n query?: Schema<TQuery, TQueryIn>;\n params?: Schema<TParams, TParamsIn>;\n body?: Schema<TBody, TBodyIn>;\n returns?: TReturns;\n handler: (ctx: Ctx, next: NextFn) => Awaitable<R>;\n};\n\nexport function isHandlerUnit(\n value: unknown,\n): value is HandlerUnit<readonly unknown[], ValidatorParts> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"handler\" in value &&\n \"middlewares\" in value &&\n Array.isArray((value as HandlerUnit<readonly unknown[], ValidatorParts>).middlewares)\n );\n}\n"],"mappings":";AA4LA,SAAgB,cACd,OAC0D;CAC1D,OACE,OAAO,UAAU,YACjB,UAAU,QACV,aAAa,SACb,iBAAiB,SACjB,MAAM,QAAS,MAA0D,WAAW;AAExF"}
1
+ {"version":3,"file":"units.cjs","names":[],"sources":["../../../src/types/units.ts"],"sourcesContent":["import type {\n Awaitable,\n MiddlewareDefinition as CoreMiddlewareDefinition,\n TaserCookieJar,\n TaserHeaders,\n} from \"@taserjs/router-core\";\n\nimport type {\n MergeMiddlewareField,\n MergePart,\n RequestShape,\n Simplify,\n UnitRuntimeContext,\n UnwrapPart,\n} from \"./type-utils.js\";\nimport type { ReturnsMap } from \"./returns.js\";\nimport type { Schema } from \"./schema.js\";\n\nexport type { HttpMethod, Method } from \"./type-utils.js\";\nexport type {\n EmptyReturns,\n MergeReturns,\n ReturnsMap,\n HandlerReply,\n HasReturns,\n StatusCode,\n ValidHandlerReply,\n EnforceHandlerReply,\n} from \"./returns.js\";\n\n/** Default empty app context for standalone units without a bound router instance. */\nexport type AppContext = Record<never, never>;\n\nexport type ValidatorParts = {\n query?: unknown;\n params?: unknown;\n body?: unknown;\n queryIn?: unknown;\n paramsIn?: unknown;\n bodyIn?: unknown;\n};\n\nexport declare const StateBrand: unique symbol;\n\nexport type NextResult<TState = unknown> = Response & {\n readonly [StateBrand]?: TState;\n};\n\nexport type ExtractState<T> = [Extract<Awaited<T>, { [StateBrand]?: unknown }>] extends [never]\n ? {}\n : Extract<Awaited<T>, { [StateBrand]?: unknown }> extends { [StateBrand]?: infer S }\n ? [S] extends [never]\n ? {}\n : S\n : {};\n\nexport type IsUnknown<T> = [unknown] extends [T] ? true : false;\n\nexport type NextFn<TExpectedState = unknown> =\n IsUnknown<TExpectedState> extends true\n ? <S extends Record<string, unknown> = {}>(state?: S) => Promise<NextResult<S>>\n : (state: TExpectedState) => Promise<NextResult<TExpectedState>>;\n\nexport type MiddlewareNext = NextFn;\n\nexport type MiddlewareDefinition = CoreMiddlewareDefinition<ReturnsMap>;\n\nexport type MiddlewareReturnFromParts<\n TQuery,\n TParams,\n TBody,\n TState,\n TQueryIn = TQuery,\n TParamsIn = TParams,\n TBodyIn = TBody,\n> = {\n query: Simplify<UnwrapPart<TQuery>>;\n params: Simplify<UnwrapPart<TParams>>;\n body: Simplify<UnwrapPart<TBody>>;\n state: Simplify<UnwrapPart<TState>>;\n /** Pre-parse shapes merged into route `$Infer.Input`. */\n input: {\n query: RequestShape<TQueryIn, TQuery>;\n params: RequestShape<TParamsIn, TParams>;\n body: RequestShape<TBodyIn, TBody>;\n };\n};\n\nexport type DefineMiddlewareResult<\n TQuery,\n TParams,\n TBody,\n TState,\n R,\n TQueryIn = TQuery,\n TParamsIn = TParams,\n TBodyIn = TBody,\n TReturns extends ReturnsMap = {},\n TLayout = null,\n TRequires = {},\n> = MiddlewareUnit<\n MiddlewareReturnFromParts<\n TQuery,\n TParams,\n TBody,\n IsUnknown<TState> extends true ? ExtractState<R> : TState,\n TQueryIn,\n TParamsIn,\n TBodyIn\n >,\n TReturns,\n TLayout,\n TRequires\n>;\n\nexport type StandaloneMiddlewareContext<\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TAppContext extends Record<string, unknown> = AppContext,\n TState = {},\n> = Simplify<\n TAppContext &\n UnitRuntimeContext & {\n query: Simplify<UnwrapPart<TQuery>>;\n params: Simplify<UnwrapPart<TParams>>;\n body: Simplify<UnwrapPart<TBody>>;\n state: Simplify<UnwrapPart<TState>>;\n headers: TaserHeaders;\n cookies: TaserCookieJar;\n }\n>;\n\nexport type HandlerContext<\n Acc extends readonly unknown[],\n Validators extends ValidatorParts,\n TAppContext extends Record<string, unknown> = AppContext,\n> = Simplify<\n TAppContext &\n UnitRuntimeContext & {\n query: Simplify<\n MergePart<\n Validators extends { query?: infer Q } ? Q : unknown,\n MergeMiddlewareField<Acc, \"query\">\n >\n >;\n params: Simplify<\n MergePart<\n Validators extends { params?: infer P } ? P : unknown,\n MergeMiddlewareField<Acc, \"params\">\n >\n >;\n body: Simplify<\n MergePart<\n Validators extends { body?: infer B } ? B : unknown,\n MergeMiddlewareField<Acc, \"body\">\n >\n >;\n state: Simplify<MergeMiddlewareField<Acc, \"state\">>;\n headers: TaserHeaders;\n cookies: TaserCookieJar;\n }\n>;\n\nexport type MiddlewareUnit<\n TAcc = unknown,\n TReturns extends ReturnsMap = {},\n TRequiredLayouts = unknown,\n TRequiredState = unknown,\n> = MiddlewareDefinition & {\n readonly __middlewareAcc: TAcc;\n readonly __returns?: TReturns;\n readonly __requiredLayouts?: TRequiredLayouts;\n readonly __requiredState?: TRequiredState;\n};\n\nexport type HandlerUnit<\n _Acc extends readonly unknown[],\n _Validators extends ValidatorParts,\n TReturns extends ReturnsMap = {},\n TOutput = Response,\n> = {\n readonly __returns?: TReturns;\n readonly $Infer: {\n Output: TOutput;\n };\n middlewares: readonly MiddlewareDefinition[];\n handler: (ctx: unknown) => Awaitable<Response>;\n returns?: ReturnsMap;\n query?: Schema<unknown>;\n params?: Schema<unknown>;\n body?: Schema<unknown>;\n};\n\nexport type InlineMiddlewareOptions<\n Ctx = unknown,\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TReturns extends ReturnsMap = {},\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n R = unknown,\n> = {\n query?: Schema<TQuery, TQueryIn>;\n params?: Schema<TParams, TParamsIn>;\n body?: Schema<TBody, TBodyIn>;\n returns?: TReturns;\n handler: (ctx: Ctx, next: NextFn) => Awaitable<R>;\n};\n\nexport function isHandlerUnit(\n value: unknown,\n): value is HandlerUnit<readonly unknown[], ValidatorParts> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"handler\" in value &&\n \"middlewares\" in value &&\n Array.isArray((value as HandlerUnit<readonly unknown[], ValidatorParts>).middlewares)\n );\n}\n"],"mappings":";AAoNA,SAAgB,cACd,OAC0D;CAC1D,OACE,OAAO,UAAU,YACjB,UAAU,QACV,aAAa,SACb,iBAAiB,SACjB,MAAM,QAAS,MAA0D,WAAW;AAExF"}
@@ -1,5 +1,5 @@
1
- import { Awaitable, TaserCookieJar, TaserHeaders } from '@taserjs/router-core';
2
- import { MergeMiddlewareField, MergePart, RequestShape, RuntimeContextFields, Simplify, UnwrapPart } from './type-utils.js';
1
+ import { Awaitable, MiddlewareDefinition as CoreMiddlewareDefinition, TaserCookieJar, TaserHeaders } from '@taserjs/router-core';
2
+ import { MergeMiddlewareField, MergePart, RequestShape, Simplify, UnitRuntimeContext, UnwrapPart } from './type-utils.js';
3
3
  import { ReturnsMap } from './returns.js';
4
4
  import { Schema } from './schema.js';
5
5
  export type { HttpMethod, Method } from './type-utils.js';
@@ -28,13 +28,7 @@ export type ExtractState<T> = [Extract<Awaited<T>, {
28
28
  export type IsUnknown<T> = [unknown] extends [T] ? true : false;
29
29
  export type NextFn<TExpectedState = unknown> = IsUnknown<TExpectedState> extends true ? <S extends Record<string, unknown> = {}>(state?: S) => Promise<NextResult<S>> : (state: TExpectedState) => Promise<NextResult<TExpectedState>>;
30
30
  export type MiddlewareNext = NextFn;
31
- export type MiddlewareDefinition = {
32
- query?: unknown;
33
- params?: unknown;
34
- body?: unknown;
35
- returns?: ReturnsMap;
36
- handler: (ctx: unknown, next: MiddlewareNext) => Awaitable<Response | unknown>;
37
- };
31
+ export type MiddlewareDefinition = CoreMiddlewareDefinition<ReturnsMap>;
38
32
  export type MiddlewareReturnFromParts<TQuery, TParams, TBody, TState, TQueryIn = TQuery, TParamsIn = TParams, TBodyIn = TBody> = {
39
33
  query: Simplify<UnwrapPart<TQuery>>;
40
34
  params: Simplify<UnwrapPart<TParams>>;
@@ -47,7 +41,7 @@ export type MiddlewareReturnFromParts<TQuery, TParams, TBody, TState, TQueryIn =
47
41
  body: RequestShape<TBodyIn, TBody>;
48
42
  };
49
43
  };
50
- type UnitRuntimeContext = Omit<RuntimeContextFields, "var">;
44
+ export type DefineMiddlewareResult<TQuery, TParams, TBody, TState, R, TQueryIn = TQuery, TParamsIn = TParams, TBodyIn = TBody, TReturns extends ReturnsMap = {}, TLayout = null, TRequires = {}> = MiddlewareUnit<MiddlewareReturnFromParts<TQuery, TParams, TBody, IsUnknown<TState> extends true ? ExtractState<R> : TState, TQueryIn, TParamsIn, TBodyIn>, TReturns, TLayout, TRequires>;
51
45
  export type StandaloneMiddlewareContext<TQuery = unknown, TParams = unknown, TBody = unknown, TAppContext extends Record<string, unknown> = AppContext, TState = {}> = Simplify<TAppContext & UnitRuntimeContext & {
52
46
  query: Simplify<UnwrapPart<TQuery>>;
53
47
  params: Simplify<UnwrapPart<TParams>>;
@@ -1,11 +1,11 @@
1
1
  import { RouteManifestShape, TaserRuntime } from '@taserjs/router-core';
2
- declare class TaserServeView {
3
- protected readonly runtime: TaserRuntime;
4
- readonly fetch: (request: Request, env?: unknown, executionCtx?: unknown) => Promise<Response> | Response;
5
- constructor(runtime: TaserRuntime);
2
+ export declare class TaserServeView<THasNotFound extends boolean = boolean> {
3
+ protected readonly runtime: TaserRuntime<THasNotFound>;
4
+ readonly fetch: (request: Request, env?: unknown, executionCtx?: unknown) => THasNotFound extends true ? Promise<Response> | Response : Promise<Response | undefined> | Response | undefined;
5
+ readonly request: (path: string, init?: RequestInit) => THasNotFound extends true ? Promise<Response> : Promise<Response | undefined>;
6
+ constructor(runtime: TaserRuntime<THasNotFound>);
6
7
  }
7
- export declare class TaserApp<TManifest extends RouteManifestShape = RouteManifestShape> extends TaserServeView {
8
+ export declare class TaserApp<TManifest extends RouteManifestShape = RouteManifestShape, THasNotFound extends boolean = boolean> extends TaserServeView<THasNotFound> {
8
9
  readonly __manifest?: TManifest;
9
- constructor(runtime: TaserRuntime, manifest?: TManifest);
10
+ constructor(runtime: TaserRuntime<THasNotFound>, manifest?: TManifest);
10
11
  }
11
- export {};
@@ -2,11 +2,15 @@
2
2
  var TaserServeView = class {
3
3
  runtime;
4
4
  fetch;
5
+ request;
5
6
  constructor(runtime) {
6
7
  this.runtime = runtime;
7
8
  this.fetch = (request, env, executionCtx) => {
8
9
  return this.runtime.fetch(request, env, executionCtx);
9
10
  };
11
+ this.request = (path, init) => {
12
+ return this.runtime.request(path, init);
13
+ };
10
14
  }
11
15
  };
12
16
  var TaserApp = class extends TaserServeView {
@@ -17,6 +21,6 @@ var TaserApp = class extends TaserServeView {
17
21
  }
18
22
  };
19
23
  //#endregion
20
- export { TaserApp };
24
+ export { TaserApp, TaserServeView };
21
25
 
22
26
  //# sourceMappingURL=app.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","names":[],"sources":["../../../src/builder/app.ts"],"sourcesContent":["import type { RouteManifestShape, TaserRuntime } from \"@taserjs/router-core\";\n\nclass TaserServeView {\n readonly fetch: (\n request: Request,\n env?: unknown,\n executionCtx?: unknown,\n ) => Promise<Response> | Response;\n\n constructor(protected readonly runtime: TaserRuntime) {\n this.fetch = (request: Request, env?: unknown, executionCtx?: unknown) => {\n return this.runtime.fetch(request, env, executionCtx as never);\n };\n }\n}\n\nexport class TaserApp<\n TManifest extends RouteManifestShape = RouteManifestShape,\n> extends TaserServeView {\n readonly __manifest?: TManifest;\n\n constructor(runtime: TaserRuntime, manifest?: TManifest) {\n super(runtime);\n if (manifest !== undefined) {\n this.__manifest = manifest;\n }\n }\n}\n"],"mappings":";AAEA,IAAM,iBAAN,MAAqB;CAOY;CAN/B;CAMA,YAAY,SAA0C;EAAvB,KAAA,UAAA;EAC7B,KAAK,SAAS,SAAkB,KAAe,iBAA2B;GACxE,OAAO,KAAK,QAAQ,MAAM,SAAS,KAAK,YAAqB;EAC/D;CACF;AACF;AAEA,IAAa,WAAb,cAEU,eAAe;CACvB;CAEA,YAAY,SAAuB,UAAsB;EACvD,MAAM,OAAO;EACb,IAAI,aAAa,KAAA,GACf,KAAK,aAAa;CAEtB;AACF"}
1
+ {"version":3,"file":"app.js","names":[],"sources":["../../../src/builder/app.ts"],"sourcesContent":["import type { RouteManifestShape, TaserRuntime } from \"@taserjs/router-core\";\n\nexport class TaserServeView<THasNotFound extends boolean = boolean> {\n readonly fetch: (\n request: Request,\n env?: unknown,\n executionCtx?: unknown,\n ) => THasNotFound extends true\n ? Promise<Response> | Response\n : Promise<Response | undefined> | Response | undefined;\n\n readonly request: (\n path: string,\n init?: RequestInit,\n ) => THasNotFound extends true ? Promise<Response> : Promise<Response | undefined>;\n\n constructor(protected readonly runtime: TaserRuntime<THasNotFound>) {\n this.fetch = (request: Request, env?: unknown, executionCtx?: unknown) => {\n return this.runtime.fetch(request, env, executionCtx as never);\n };\n this.request = (path: string, init?: RequestInit) => {\n return this.runtime.request(path, init);\n };\n }\n}\n\nexport class TaserApp<\n TManifest extends RouteManifestShape = RouteManifestShape,\n THasNotFound extends boolean = boolean,\n> extends TaserServeView<THasNotFound> {\n readonly __manifest?: TManifest;\n\n constructor(runtime: TaserRuntime<THasNotFound>, manifest?: TManifest) {\n super(runtime);\n if (manifest !== undefined) {\n this.__manifest = manifest;\n }\n }\n}\n"],"mappings":";AAEA,IAAa,iBAAb,MAAoE;CAcnC;CAb/B;CAQA;CAKA,YAAY,SAAwD;EAArC,KAAA,UAAA;EAC7B,KAAK,SAAS,SAAkB,KAAe,iBAA2B;GACxE,OAAO,KAAK,QAAQ,MAAM,SAAS,KAAK,YAAqB;EAC/D;EACA,KAAK,WAAW,MAAc,SAAuB;GACnD,OAAO,KAAK,QAAQ,QAAQ,MAAM,IAAI;EACxC;CACF;AACF;AAEA,IAAa,WAAb,cAGU,eAA6B;CACrC;CAEA,YAAY,SAAqC,UAAsB;EACrE,MAAM,OAAO;EACb,IAAI,aAAa,KAAA,GACf,KAAK,aAAa;CAEtB;AACF"}
@@ -1,54 +1,9 @@
1
- import { RouteBuilder, RoutePath, Schema } from '../types/index.js';
1
+ import { RouteBuilder, RoutePath } from '../types/index.js';
2
2
  import { AppContext, HttpMethod } from '../types/units.js';
3
- type WithoutBodyOptions<TQuery, TParams, TQueryIn = unknown, TParamsIn = unknown> = {
4
- query?: Schema<TQuery, TQueryIn>;
5
- params?: Schema<TParams, TParamsIn>;
6
- };
7
- type WithBodyOptions<TQuery, TParams, TBody, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown> = WithoutBodyOptions<TQuery, TParams, TQueryIn, TParamsIn> & {
8
- body?: Schema<TBody, TBodyIn>;
9
- };
10
- export type CreateWithoutBodyRoute<M extends "GET" | "DELETE" | "OPTIONS" | "HEAD", TAppContext extends Record<string, unknown> = AppContext> = {
11
- <const Path extends RoutePath>(path: Path): RouteBuilder<Path, M, readonly [], {}, {}, TAppContext>;
12
- <const Path extends RoutePath, TQuery = unknown, TParams = unknown, TQueryIn = unknown, TParamsIn = unknown>(path: Path, options: WithoutBodyOptions<TQuery, TParams, TQueryIn, TParamsIn>): RouteBuilder<Path, M, readonly [], {
13
- query: TQuery;
14
- params: TParams;
15
- queryIn: TQueryIn;
16
- paramsIn: TParamsIn;
17
- }, {}, TAppContext>;
18
- };
19
- export type CreateWithBodyRoute<M extends "POST" | "PUT" | "PATCH", TAppContext extends Record<string, unknown> = AppContext> = {
20
- <const Path extends RoutePath>(path: Path): RouteBuilder<Path, M, readonly [], {}, {}, TAppContext>;
21
- <const Path extends RoutePath, TQuery = unknown, TParams = unknown, TBody = unknown, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown>(path: Path, options: WithBodyOptions<TQuery, TParams, TBody, TQueryIn, TParamsIn, TBodyIn>): RouteBuilder<Path, M, readonly [], {
22
- query: TQuery;
23
- params: TParams;
24
- body: TBody;
25
- queryIn: TQueryIn;
26
- paramsIn: TParamsIn;
27
- bodyIn: TBodyIn;
28
- }, {}, TAppContext>;
29
- };
30
- export type CreateAnyRoute<TAppContext extends Record<string, unknown> = AppContext> = {
31
- <const Path extends RoutePath, const Methods extends readonly HttpMethod[]>(path: Path, methods: Methods): RouteBuilder<Path, Methods[number], readonly [], {}, {}, TAppContext>;
32
- <const Path extends RoutePath, const Methods extends readonly HttpMethod[], TQuery = unknown, TParams = unknown, TBody = unknown, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown>(path: Path, methods: Methods, options: WithBodyOptions<TQuery, TParams, TBody, TQueryIn, TParamsIn, TBodyIn>): RouteBuilder<Path, Methods[number], readonly [], {
33
- query: TQuery;
34
- params: TParams;
35
- body: TBody;
36
- queryIn: TQueryIn;
37
- paramsIn: TParamsIn;
38
- bodyIn: TBodyIn;
39
- }, {}, TAppContext>;
40
- };
41
- export type CreateAllRoute<TAppContext extends Record<string, unknown> = AppContext> = {
42
- <const Path extends RoutePath>(path: Path): RouteBuilder<Path, HttpMethod, readonly [], {}, {}, TAppContext>;
43
- <const Path extends RoutePath, TQuery = unknown, TParams = unknown, TBody = unknown, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown>(path: Path, options: WithBodyOptions<TQuery, TParams, TBody, TQueryIn, TParamsIn, TBodyIn>): RouteBuilder<Path, HttpMethod, readonly [], {
44
- query: TQuery;
45
- params: TParams;
46
- body: TBody;
47
- queryIn: TQueryIn;
48
- paramsIn: TParamsIn;
49
- bodyIn: TBodyIn;
50
- }, {}, TAppContext>;
51
- };
3
+ export type CreateWithoutBodyRoute<M extends "GET" | "DELETE" | "OPTIONS" | "HEAD", TAppContext extends Record<string, unknown> = AppContext> = <const Path extends RoutePath>(path: Path) => RouteBuilder<Path, M, readonly [], {}, {}, TAppContext>;
4
+ export type CreateWithBodyRoute<M extends "POST" | "PUT" | "PATCH", TAppContext extends Record<string, unknown> = AppContext> = <const Path extends RoutePath>(path: Path) => RouteBuilder<Path, M, readonly [], {}, {}, TAppContext>;
5
+ export type CreateAnyRoute<TAppContext extends Record<string, unknown> = AppContext> = <const Path extends RoutePath, const Methods extends readonly HttpMethod[]>(path: Path, methods: Methods) => RouteBuilder<Path, Methods[number], readonly [], {}, {}, TAppContext>;
6
+ export type CreateAllRoute<TAppContext extends Record<string, unknown> = AppContext> = <const Path extends RoutePath>(path: Path) => RouteBuilder<Path, HttpMethod, readonly [], {}, {}, TAppContext>;
52
7
  export declare const createGetRoute: CreateWithoutBodyRoute<"GET", AppContext>;
53
8
  export declare const createDeleteRoute: CreateWithoutBodyRoute<"DELETE", AppContext>;
54
9
  export declare const createOptionsRoute: CreateWithoutBodyRoute<"OPTIONS", AppContext>;
@@ -58,4 +13,3 @@ export declare const createPutRoute: CreateWithBodyRoute<"PUT", AppContext>;
58
13
  export declare const createPatchRoute: CreateWithBodyRoute<"PATCH", AppContext>;
59
14
  export declare const createAnyRoute: CreateAnyRoute;
60
15
  export declare const createAllRoute: CreateAllRoute;
61
- export {};
@@ -1,10 +1,10 @@
1
1
  import { createRouteBuilder } from "./route.js";
2
2
  //#region src/builder/factories.ts
3
3
  function createWithoutBodyRoute(method) {
4
- return ((path, options) => createRouteBuilder(path, method, options));
4
+ return ((path) => createRouteBuilder(path, method));
5
5
  }
6
6
  function createWithBodyRoute(method) {
7
- return ((path, options) => createRouteBuilder(path, method, options));
7
+ return ((path) => createRouteBuilder(path, method));
8
8
  }
9
9
  var createGetRoute = createWithoutBodyRoute("GET");
10
10
  var createDeleteRoute = createWithoutBodyRoute("DELETE");
@@ -13,8 +13,8 @@ var createHeadRoute = createWithoutBodyRoute("HEAD");
13
13
  var createPostRoute = createWithBodyRoute("POST");
14
14
  var createPutRoute = createWithBodyRoute("PUT");
15
15
  var createPatchRoute = createWithBodyRoute("PATCH");
16
- var createAnyRoute = ((path, methods, options) => createRouteBuilder(path, "ANY", options, methods));
17
- var createAllRoute = ((path, options) => createRouteBuilder(path, "ALL", options));
16
+ var createAnyRoute = ((path, methods) => createRouteBuilder(path, "ANY", methods));
17
+ var createAllRoute = ((path) => createRouteBuilder(path, "ALL"));
18
18
  //#endregion
19
19
  export { createAllRoute, createAnyRoute, createDeleteRoute, createGetRoute, createHeadRoute, createOptionsRoute, createPatchRoute, createPostRoute, createPutRoute };
20
20
 
@@ -1 +1 @@
1
- {"version":3,"file":"factories.js","names":[],"sources":["../../../src/builder/factories.ts"],"sourcesContent":["import { createRouteBuilder } from \"./route.js\";\nimport type { RouteBuilder, RoutePath, Schema } from \"../types/index.js\";\nimport type { AppContext, HttpMethod } from \"../types/units.js\";\n\ntype WithoutBodyOptions<TQuery, TParams, TQueryIn = unknown, TParamsIn = unknown> = {\n query?: Schema<TQuery, TQueryIn>;\n params?: Schema<TParams, TParamsIn>;\n};\n\ntype WithBodyOptions<\n TQuery,\n TParams,\n TBody,\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n> = WithoutBodyOptions<TQuery, TParams, TQueryIn, TParamsIn> & {\n body?: Schema<TBody, TBodyIn>;\n};\n\nexport type CreateWithoutBodyRoute<\n M extends \"GET\" | \"DELETE\" | \"OPTIONS\" | \"HEAD\",\n TAppContext extends Record<string, unknown> = AppContext,\n> = {\n <const Path extends RoutePath>(\n path: Path,\n ): RouteBuilder<Path, M, readonly [], {}, {}, TAppContext>;\n <\n const Path extends RoutePath,\n TQuery = unknown,\n TParams = unknown,\n TQueryIn = unknown,\n TParamsIn = unknown,\n >(\n path: Path,\n options: WithoutBodyOptions<TQuery, TParams, TQueryIn, TParamsIn>,\n ): RouteBuilder<\n Path,\n M,\n readonly [],\n {\n query: TQuery;\n params: TParams;\n queryIn: TQueryIn;\n paramsIn: TParamsIn;\n },\n {},\n TAppContext\n >;\n};\n\nexport type CreateWithBodyRoute<\n M extends \"POST\" | \"PUT\" | \"PATCH\",\n TAppContext extends Record<string, unknown> = AppContext,\n> = {\n <const Path extends RoutePath>(\n path: Path,\n ): RouteBuilder<Path, M, readonly [], {}, {}, TAppContext>;\n <\n const Path extends RoutePath,\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n >(\n path: Path,\n options: WithBodyOptions<TQuery, TParams, TBody, TQueryIn, TParamsIn, TBodyIn>,\n ): RouteBuilder<\n Path,\n M,\n readonly [],\n {\n query: TQuery;\n params: TParams;\n body: TBody;\n queryIn: TQueryIn;\n paramsIn: TParamsIn;\n bodyIn: TBodyIn;\n },\n {},\n TAppContext\n >;\n};\n\nexport type CreateAnyRoute<TAppContext extends Record<string, unknown> = AppContext> = {\n <const Path extends RoutePath, const Methods extends readonly HttpMethod[]>(\n path: Path,\n methods: Methods,\n ): RouteBuilder<Path, Methods[number], readonly [], {}, {}, TAppContext>;\n <\n const Path extends RoutePath,\n const Methods extends readonly HttpMethod[],\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n >(\n path: Path,\n methods: Methods,\n options: WithBodyOptions<TQuery, TParams, TBody, TQueryIn, TParamsIn, TBodyIn>,\n ): RouteBuilder<\n Path,\n Methods[number],\n readonly [],\n {\n query: TQuery;\n params: TParams;\n body: TBody;\n queryIn: TQueryIn;\n paramsIn: TParamsIn;\n bodyIn: TBodyIn;\n },\n {},\n TAppContext\n >;\n};\n\nexport type CreateAllRoute<TAppContext extends Record<string, unknown> = AppContext> = {\n <const Path extends RoutePath>(\n path: Path,\n ): RouteBuilder<Path, HttpMethod, readonly [], {}, {}, TAppContext>;\n <\n const Path extends RoutePath,\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n >(\n path: Path,\n options: WithBodyOptions<TQuery, TParams, TBody, TQueryIn, TParamsIn, TBodyIn>,\n ): RouteBuilder<\n Path,\n HttpMethod,\n readonly [],\n {\n query: TQuery;\n params: TParams;\n body: TBody;\n queryIn: TQueryIn;\n paramsIn: TParamsIn;\n bodyIn: TBodyIn;\n },\n {},\n TAppContext\n >;\n};\n\nfunction createWithoutBodyRoute<M extends \"GET\" | \"DELETE\" | \"OPTIONS\" | \"HEAD\">(\n method: M,\n): CreateWithoutBodyRoute<M> {\n return ((path: string, options?: WithoutBodyOptions<unknown, unknown>) =>\n createRouteBuilder(path, method, options)) as unknown as CreateWithoutBodyRoute<M>;\n}\n\nfunction createWithBodyRoute<M extends \"POST\" | \"PUT\" | \"PATCH\">(\n method: M,\n): CreateWithBodyRoute<M> {\n return ((path: string, options?: WithBodyOptions<unknown, unknown, unknown>) =>\n createRouteBuilder(path, method, options)) as unknown as CreateWithBodyRoute<M>;\n}\n\nexport const createGetRoute = createWithoutBodyRoute(\"GET\");\nexport const createDeleteRoute = createWithoutBodyRoute(\"DELETE\");\nexport const createOptionsRoute = createWithoutBodyRoute(\"OPTIONS\");\nexport const createHeadRoute = createWithoutBodyRoute(\"HEAD\");\nexport const createPostRoute = createWithBodyRoute(\"POST\");\nexport const createPutRoute = createWithBodyRoute(\"PUT\");\nexport const createPatchRoute = createWithBodyRoute(\"PATCH\");\n\nexport const createAnyRoute: CreateAnyRoute = ((\n path: string,\n methods: readonly HttpMethod[],\n options?: WithBodyOptions<unknown, unknown, unknown>,\n) => createRouteBuilder(path, \"ANY\", options, methods)) as unknown as CreateAnyRoute;\n\nexport const createAllRoute: CreateAllRoute = ((\n path: string,\n options?: WithBodyOptions<unknown, unknown, unknown>,\n) => createRouteBuilder(path, \"ALL\", options)) as unknown as CreateAllRoute;\n"],"mappings":";;AAyJA,SAAS,uBACP,QAC2B;CAC3B,SAAS,MAAc,YACrB,mBAAmB,MAAM,QAAQ,OAAO;AAC5C;AAEA,SAAS,oBACP,QACwB;CACxB,SAAS,MAAc,YACrB,mBAAmB,MAAM,QAAQ,OAAO;AAC5C;AAEA,IAAa,iBAAiB,uBAAuB,KAAK;AAC1D,IAAa,oBAAoB,uBAAuB,QAAQ;AAChE,IAAa,qBAAqB,uBAAuB,SAAS;AAClE,IAAa,kBAAkB,uBAAuB,MAAM;AAC5D,IAAa,kBAAkB,oBAAoB,MAAM;AACzD,IAAa,iBAAiB,oBAAoB,KAAK;AACvD,IAAa,mBAAmB,oBAAoB,OAAO;AAE3D,IAAa,mBACX,MACA,SACA,YACG,mBAAmB,MAAM,OAAO,SAAS,OAAO;AAErD,IAAa,mBACX,MACA,YACG,mBAAmB,MAAM,OAAO,OAAO"}
1
+ {"version":3,"file":"factories.js","names":[],"sources":["../../../src/builder/factories.ts"],"sourcesContent":["import { createRouteBuilder } from \"./route.js\";\nimport type { RouteBuilder, RoutePath } from \"../types/index.js\";\nimport type { AppContext, HttpMethod } from \"../types/units.js\";\n\nexport type CreateWithoutBodyRoute<\n M extends \"GET\" | \"DELETE\" | \"OPTIONS\" | \"HEAD\",\n TAppContext extends Record<string, unknown> = AppContext,\n> = <const Path extends RoutePath>(\n path: Path,\n) => RouteBuilder<Path, M, readonly [], {}, {}, TAppContext>;\n\nexport type CreateWithBodyRoute<\n M extends \"POST\" | \"PUT\" | \"PATCH\",\n TAppContext extends Record<string, unknown> = AppContext,\n> = <const Path extends RoutePath>(\n path: Path,\n) => RouteBuilder<Path, M, readonly [], {}, {}, TAppContext>;\n\nexport type CreateAnyRoute<TAppContext extends Record<string, unknown> = AppContext> = <\n const Path extends RoutePath,\n const Methods extends readonly HttpMethod[],\n>(\n path: Path,\n methods: Methods,\n) => RouteBuilder<Path, Methods[number], readonly [], {}, {}, TAppContext>;\n\nexport type CreateAllRoute<TAppContext extends Record<string, unknown> = AppContext> = <\n const Path extends RoutePath,\n>(\n path: Path,\n) => RouteBuilder<Path, HttpMethod, readonly [], {}, {}, TAppContext>;\n\nfunction createWithoutBodyRoute<M extends \"GET\" | \"DELETE\" | \"OPTIONS\" | \"HEAD\">(\n method: M,\n): CreateWithoutBodyRoute<M> {\n return ((path: string) =>\n createRouteBuilder(path, method)) as unknown as CreateWithoutBodyRoute<M>;\n}\n\nfunction createWithBodyRoute<M extends \"POST\" | \"PUT\" | \"PATCH\">(\n method: M,\n): CreateWithBodyRoute<M> {\n return ((path: string) => createRouteBuilder(path, method)) as unknown as CreateWithBodyRoute<M>;\n}\n\nexport const createGetRoute = createWithoutBodyRoute(\"GET\");\nexport const createDeleteRoute = createWithoutBodyRoute(\"DELETE\");\nexport const createOptionsRoute = createWithoutBodyRoute(\"OPTIONS\");\nexport const createHeadRoute = createWithoutBodyRoute(\"HEAD\");\nexport const createPostRoute = createWithBodyRoute(\"POST\");\nexport const createPutRoute = createWithBodyRoute(\"PUT\");\nexport const createPatchRoute = createWithBodyRoute(\"PATCH\");\n\nexport const createAnyRoute: CreateAnyRoute = ((path: string, methods: readonly HttpMethod[]) =>\n createRouteBuilder(path, \"ANY\", methods)) as unknown as CreateAnyRoute;\n\nexport const createAllRoute: CreateAllRoute = ((path: string) =>\n createRouteBuilder(path, \"ALL\")) as unknown as CreateAllRoute;\n"],"mappings":";;AAgCA,SAAS,uBACP,QAC2B;CAC3B,SAAS,SACP,mBAAmB,MAAM,MAAM;AACnC;AAEA,SAAS,oBACP,QACwB;CACxB,SAAS,SAAiB,mBAAmB,MAAM,MAAM;AAC3D;AAEA,IAAa,iBAAiB,uBAAuB,KAAK;AAC1D,IAAa,oBAAoB,uBAAuB,QAAQ;AAChE,IAAa,qBAAqB,uBAAuB,SAAS;AAClE,IAAa,kBAAkB,uBAAuB,MAAM;AAC5D,IAAa,kBAAkB,oBAAoB,MAAM;AACzD,IAAa,iBAAiB,oBAAoB,KAAK;AACvD,IAAa,mBAAmB,oBAAoB,OAAO;AAE3D,IAAa,mBAAmC,MAAc,YAC5D,mBAAmB,MAAM,OAAO,OAAO;AAEzC,IAAa,mBAAmC,SAC9C,mBAAmB,MAAM,KAAK"}
@@ -1,5 +1,4 @@
1
1
  import { Method, RouteBuilder, RoutePath, ValidatorParts } from '../types/index.js';
2
2
  import { HttpMethod } from '../types/units.js';
3
- import { SchemaValidators } from '../define/validators.js';
4
3
  /** Shared internal builder — not part of the public `@taserjs/router` API. */
5
- export declare function createRouteBuilder(path: string, method: HttpMethod | "ANY" | "ALL", validators?: SchemaValidators, methods?: readonly HttpMethod[]): RouteBuilder<RoutePath, Method, readonly [], ValidatorParts>;
4
+ export declare function createRouteBuilder(path: string, method: HttpMethod | "ANY" | "ALL", methods?: readonly HttpMethod[]): RouteBuilder<RoutePath, Method, readonly [], ValidatorParts>;
@@ -22,12 +22,32 @@ function buildRouteBase(path, method, methods, middlewares) {
22
22
  };
23
23
  }
24
24
  /** Shared internal builder — not part of the public `@taserjs/router` API. */
25
- function createRouteBuilder(path, method, validators = {}, methods) {
25
+ function createRouteBuilder(path, method, methods) {
26
26
  const middlewares = [];
27
27
  let routeReturns = {};
28
+ const validators = {};
29
+ let bodyMode;
28
30
  const builder = {
29
31
  path,
30
32
  method,
33
+ query(schema) {
34
+ validators.query = schema;
35
+ return builder;
36
+ },
37
+ params(schema) {
38
+ validators.params = schema;
39
+ return builder;
40
+ },
41
+ body(modeOrSchema, schema) {
42
+ if (typeof modeOrSchema === "string") {
43
+ bodyMode = modeOrSchema;
44
+ if (schema !== void 0) validators.body = schema;
45
+ } else {
46
+ bodyMode = "json";
47
+ validators.body = modeOrSchema;
48
+ }
49
+ return builder;
50
+ },
31
51
  returns(map) {
32
52
  routeReturns = {
33
53
  ...routeReturns,
@@ -68,6 +88,7 @@ function createRouteBuilder(path, method, validators = {}, methods) {
68
88
  handler: unit.handler,
69
89
  ...routeSchemas,
70
90
  ...handlerSchemas,
91
+ ...bodyMode ? { bodyMode } : {},
71
92
  ...returns ? { returns } : {}
72
93
  };
73
94
  }
@@ -1 +1 @@
1
- {"version":3,"file":"route.js","names":[],"sources":["../../../src/builder/route.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport {\n collectReturnsFromDefinitions,\n hasInputSchemas,\n mergeReturnsMaps,\n withAuto422,\n} from \"@taserjs/router-utils\";\n\nimport type {\n Method,\n RouteBuilder,\n RoutePath,\n ReturnsMap,\n ValidatorParts,\n} from \"../types/index.js\";\nimport type { HttpMethod, MiddlewareDefinition } from \"../types/units.js\";\nimport { isHandlerUnit } from \"../types/units.js\";\nimport { HANDLER_SCHEMA_KEY_MAP } from \"./constants.js\";\nimport { pickDefinedSchemas, type SchemaValidators } from \"../define/validators.js\";\n\nfunction toUtilsMap(map: ReturnsMap | undefined): Record<number, StandardSchemaV1> {\n if (!map) {\n return {};\n }\n const out: Record<number, StandardSchemaV1> = {};\n for (const [key, schema] of Object.entries(map)) {\n if (schema !== undefined) {\n out[Number(key)] = schema;\n }\n }\n return out;\n}\n\nfunction buildEffectiveReturns(args: {\n middlewareReturns: ReturnsMap;\n routeReturns: ReturnsMap;\n handlerMiddlewareReturns: ReturnsMap;\n handlerReturns: ReturnsMap | undefined;\n schemas: {\n query?: unknown;\n params?: unknown;\n body?: unknown;\n handlerQuery?: unknown;\n handlerParams?: unknown;\n handlerBody?: unknown;\n middlewares?: readonly MiddlewareDefinition[];\n handlerMiddlewares?: readonly MiddlewareDefinition[];\n };\n}): Record<number, StandardSchemaV1> | undefined {\n const merged = mergeReturnsMaps(\n toUtilsMap(args.middlewareReturns),\n toUtilsMap(args.routeReturns),\n toUtilsMap(args.handlerMiddlewareReturns),\n toUtilsMap(args.handlerReturns),\n );\n const with422 = withAuto422(merged, hasInputSchemas(args.schemas));\n return Object.keys(with422).length > 0 ? with422 : undefined;\n}\n\nfunction buildRouteBase(\n path: string,\n method: HttpMethod | \"ANY\" | \"ALL\",\n methods: readonly HttpMethod[] | undefined,\n middlewares: MiddlewareDefinition[],\n) {\n return {\n path,\n method,\n ...(methods ? { methods: [...methods] } : {}),\n middlewares: [...middlewares],\n };\n}\n\n/** Shared internal builder — not part of the public `@taserjs/router` API. */\nexport function createRouteBuilder(\n path: string,\n method: HttpMethod | \"ANY\" | \"ALL\",\n validators: SchemaValidators = {},\n methods?: readonly HttpMethod[],\n): RouteBuilder<RoutePath, Method, readonly [], ValidatorParts> {\n const middlewares: MiddlewareDefinition[] = [];\n let routeReturns: Record<number, StandardSchemaV1> = {};\n\n const builder = {\n path,\n method,\n returns(map: ReturnsMap) {\n routeReturns = { ...routeReturns, ...toUtilsMap(map) };\n return builder;\n },\n use(definition: MiddlewareDefinition) {\n middlewares.push(definition);\n return builder;\n },\n handler(fnOrUnit: ((ctx: unknown) => unknown) | unknown) {\n const routeSchemas = pickDefinedSchemas(validators);\n const base = buildRouteBase(path, method, methods, middlewares);\n\n const unit = isHandlerUnit(fnOrUnit)\n ? fnOrUnit\n : {\n handler: fnOrUnit as (ctx: unknown) => Response | Promise<Response>,\n middlewares: [] as MiddlewareDefinition[],\n returns: undefined as ReturnsMap | undefined,\n };\n\n const handlerSchemas = isHandlerUnit(fnOrUnit)\n ? pickDefinedSchemas(fnOrUnit, HANDLER_SCHEMA_KEY_MAP)\n : {};\n\n const returns = buildEffectiveReturns({\n middlewareReturns: collectReturnsFromDefinitions(middlewares),\n routeReturns,\n handlerMiddlewareReturns: collectReturnsFromDefinitions(unit.middlewares),\n handlerReturns: unit.returns,\n schemas: {\n ...validators,\n handlerQuery: (unit as any).query,\n handlerParams: (unit as any).params,\n handlerBody: (unit as any).body,\n middlewares,\n handlerMiddlewares: unit.middlewares,\n },\n });\n\n return {\n ...base,\n handlerMiddlewares: [...unit.middlewares],\n handler: unit.handler,\n ...routeSchemas,\n ...handlerSchemas,\n ...(returns ? { returns } : {}),\n };\n },\n };\n\n return builder as unknown as RouteBuilder<RoutePath, Method, readonly [], ValidatorParts>;\n}\n"],"mappings":";;;;;AAoBA,SAAS,WAAW,KAA+D;CACjF,IAAI,CAAC,KACH,OAAO,CAAC;CAEV,MAAM,MAAwC,CAAC;CAC/C,KAAK,MAAM,CAAC,KAAK,WAAW,OAAO,QAAQ,GAAG,GAC5C,IAAI,WAAW,KAAA,GACb,IAAI,OAAO,GAAG,KAAK;CAGvB,OAAO;AACT;AAEA,SAAS,sBAAsB,MAekB;CAO/C,MAAM,UAAU,YAND,iBACb,WAAW,KAAK,iBAAiB,GACjC,WAAW,KAAK,YAAY,GAC5B,WAAW,KAAK,wBAAwB,GACxC,WAAW,KAAK,cAAc,CAEJ,GAAQ,gBAAgB,KAAK,OAAO,CAAC;CACjE,OAAO,OAAO,KAAK,OAAO,CAAC,CAAC,SAAS,IAAI,UAAU,KAAA;AACrD;AAEA,SAAS,eACP,MACA,QACA,SACA,aACA;CACA,OAAO;EACL;EACA;EACA,GAAI,UAAU,EAAE,SAAS,CAAC,GAAG,OAAO,EAAE,IAAI,CAAC;EAC3C,aAAa,CAAC,GAAG,WAAW;CAC9B;AACF;;AAGA,SAAgB,mBACd,MACA,QACA,aAA+B,CAAC,GAChC,SAC8D;CAC9D,MAAM,cAAsC,CAAC;CAC7C,IAAI,eAAiD,CAAC;CAEtD,MAAM,UAAU;EACd;EACA;EACA,QAAQ,KAAiB;GACvB,eAAe;IAAE,GAAG;IAAc,GAAG,WAAW,GAAG;GAAE;GACrD,OAAO;EACT;EACA,IAAI,YAAkC;GACpC,YAAY,KAAK,UAAU;GAC3B,OAAO;EACT;EACA,QAAQ,UAAiD;GACvD,MAAM,eAAe,mBAAmB,UAAU;GAClD,MAAM,OAAO,eAAe,MAAM,QAAQ,SAAS,WAAW;GAE9D,MAAM,OAAO,cAAc,QAAQ,IAC/B,WACA;IACE,SAAS;IACT,aAAa,CAAC;IACd,SAAS,KAAA;GACX;GAEJ,MAAM,iBAAiB,cAAc,QAAQ,IACzC,mBAAmB,UAAU,sBAAsB,IACnD,CAAC;GAEL,MAAM,UAAU,sBAAsB;IACpC,mBAAmB,8BAA8B,WAAW;IAC5D;IACA,0BAA0B,8BAA8B,KAAK,WAAW;IACxE,gBAAgB,KAAK;IACrB,SAAS;KACP,GAAG;KACH,cAAe,KAAa;KAC5B,eAAgB,KAAa;KAC7B,aAAc,KAAa;KAC3B;KACA,oBAAoB,KAAK;IAC3B;GACF,CAAC;GAED,OAAO;IACL,GAAG;IACH,oBAAoB,CAAC,GAAG,KAAK,WAAW;IACxC,SAAS,KAAK;IACd,GAAG;IACH,GAAG;IACH,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;GAC/B;EACF;CACF;CAEA,OAAO;AACT"}
1
+ {"version":3,"file":"route.js","names":[],"sources":["../../../src/builder/route.ts"],"sourcesContent":["import type { StandardSchemaV1 } from \"@standard-schema/spec\";\nimport {\n collectReturnsFromDefinitions,\n hasInputSchemas,\n mergeReturnsMaps,\n withAuto422,\n} from \"@taserjs/router-utils\";\nimport type { BodyMode } from \"@taserjs/router-core\";\n\nimport type {\n Method,\n RouteBuilder,\n RoutePath,\n ReturnsMap,\n ValidatorParts,\n Schema,\n} from \"../types/index.js\";\nimport type { HttpMethod, MiddlewareDefinition } from \"../types/units.js\";\nimport { isHandlerUnit } from \"../types/units.js\";\nimport { HANDLER_SCHEMA_KEY_MAP } from \"./constants.js\";\nimport { pickDefinedSchemas, type SchemaValidators } from \"../define/validators.js\";\n\nfunction toUtilsMap(map: ReturnsMap | undefined): Record<number, StandardSchemaV1> {\n if (!map) {\n return {};\n }\n const out: Record<number, StandardSchemaV1> = {};\n for (const [key, schema] of Object.entries(map)) {\n if (schema !== undefined) {\n out[Number(key)] = schema;\n }\n }\n return out;\n}\n\nfunction buildEffectiveReturns(args: {\n middlewareReturns: ReturnsMap;\n routeReturns: ReturnsMap;\n handlerMiddlewareReturns: ReturnsMap;\n handlerReturns: ReturnsMap | undefined;\n schemas: {\n query?: unknown;\n params?: unknown;\n body?: unknown;\n handlerQuery?: unknown;\n handlerParams?: unknown;\n handlerBody?: unknown;\n middlewares?: readonly MiddlewareDefinition[];\n handlerMiddlewares?: readonly MiddlewareDefinition[];\n };\n}): Record<number, StandardSchemaV1> | undefined {\n const merged = mergeReturnsMaps(\n toUtilsMap(args.middlewareReturns),\n toUtilsMap(args.routeReturns),\n toUtilsMap(args.handlerMiddlewareReturns),\n toUtilsMap(args.handlerReturns),\n );\n const with422 = withAuto422(merged, hasInputSchemas(args.schemas));\n return Object.keys(with422).length > 0 ? with422 : undefined;\n}\n\nfunction buildRouteBase(\n path: string,\n method: HttpMethod | \"ANY\" | \"ALL\",\n methods: readonly HttpMethod[] | undefined,\n middlewares: MiddlewareDefinition[],\n) {\n return {\n path,\n method,\n ...(methods ? { methods: [...methods] } : {}),\n middlewares: [...middlewares],\n };\n}\n\n/** Shared internal builder — not part of the public `@taserjs/router` API. */\nexport function createRouteBuilder(\n path: string,\n method: HttpMethod | \"ANY\" | \"ALL\",\n methods?: readonly HttpMethod[],\n): RouteBuilder<RoutePath, Method, readonly [], ValidatorParts> {\n const middlewares: MiddlewareDefinition[] = [];\n let routeReturns: Record<number, StandardSchemaV1> = {};\n const validators: SchemaValidators = {};\n let bodyMode: BodyMode | undefined;\n\n const builder = {\n path,\n method,\n query(schema: Schema<unknown>) {\n validators.query = schema;\n return builder;\n },\n params(schema: Schema<unknown>) {\n validators.params = schema;\n return builder;\n },\n body(modeOrSchema: BodyMode | Schema<unknown>, schema?: Schema<unknown>) {\n if (typeof modeOrSchema === \"string\") {\n bodyMode = modeOrSchema as BodyMode;\n if (schema !== undefined) {\n validators.body = schema;\n }\n } else {\n bodyMode = \"json\";\n validators.body = modeOrSchema;\n }\n return builder;\n },\n returns(map: ReturnsMap) {\n routeReturns = { ...routeReturns, ...toUtilsMap(map) };\n return builder;\n },\n use(definition: MiddlewareDefinition) {\n middlewares.push(definition);\n return builder;\n },\n handler(fnOrUnit: ((ctx: unknown) => unknown) | unknown) {\n const routeSchemas = pickDefinedSchemas(validators);\n const base = buildRouteBase(path, method, methods, middlewares);\n\n const unit = isHandlerUnit(fnOrUnit)\n ? fnOrUnit\n : {\n handler: fnOrUnit as (ctx: unknown) => Response | Promise<Response>,\n middlewares: [] as MiddlewareDefinition[],\n returns: undefined as ReturnsMap | undefined,\n };\n\n const handlerSchemas = isHandlerUnit(fnOrUnit)\n ? pickDefinedSchemas(fnOrUnit, HANDLER_SCHEMA_KEY_MAP)\n : {};\n\n const returns = buildEffectiveReturns({\n middlewareReturns: collectReturnsFromDefinitions(middlewares),\n routeReturns,\n handlerMiddlewareReturns: collectReturnsFromDefinitions(unit.middlewares),\n handlerReturns: unit.returns,\n schemas: {\n ...validators,\n handlerQuery: (unit as any).query,\n handlerParams: (unit as any).params,\n handlerBody: (unit as any).body,\n middlewares,\n handlerMiddlewares: unit.middlewares,\n },\n });\n\n return {\n ...base,\n handlerMiddlewares: [...unit.middlewares],\n handler: unit.handler,\n ...routeSchemas,\n ...handlerSchemas,\n ...(bodyMode ? { bodyMode } : {}),\n ...(returns ? { returns } : {}),\n };\n },\n };\n\n return builder as unknown as RouteBuilder<RoutePath, Method, readonly [], ValidatorParts>;\n}\n"],"mappings":";;;;;AAsBA,SAAS,WAAW,KAA+D;CACjF,IAAI,CAAC,KACH,OAAO,CAAC;CAEV,MAAM,MAAwC,CAAC;CAC/C,KAAK,MAAM,CAAC,KAAK,WAAW,OAAO,QAAQ,GAAG,GAC5C,IAAI,WAAW,KAAA,GACb,IAAI,OAAO,GAAG,KAAK;CAGvB,OAAO;AACT;AAEA,SAAS,sBAAsB,MAekB;CAO/C,MAAM,UAAU,YAND,iBACb,WAAW,KAAK,iBAAiB,GACjC,WAAW,KAAK,YAAY,GAC5B,WAAW,KAAK,wBAAwB,GACxC,WAAW,KAAK,cAAc,CAEJ,GAAQ,gBAAgB,KAAK,OAAO,CAAC;CACjE,OAAO,OAAO,KAAK,OAAO,CAAC,CAAC,SAAS,IAAI,UAAU,KAAA;AACrD;AAEA,SAAS,eACP,MACA,QACA,SACA,aACA;CACA,OAAO;EACL;EACA;EACA,GAAI,UAAU,EAAE,SAAS,CAAC,GAAG,OAAO,EAAE,IAAI,CAAC;EAC3C,aAAa,CAAC,GAAG,WAAW;CAC9B;AACF;;AAGA,SAAgB,mBACd,MACA,QACA,SAC8D;CAC9D,MAAM,cAAsC,CAAC;CAC7C,IAAI,eAAiD,CAAC;CACtD,MAAM,aAA+B,CAAC;CACtC,IAAI;CAEJ,MAAM,UAAU;EACd;EACA;EACA,MAAM,QAAyB;GAC7B,WAAW,QAAQ;GACnB,OAAO;EACT;EACA,OAAO,QAAyB;GAC9B,WAAW,SAAS;GACpB,OAAO;EACT;EACA,KAAK,cAA0C,QAA0B;GACvE,IAAI,OAAO,iBAAiB,UAAU;IACpC,WAAW;IACX,IAAI,WAAW,KAAA,GACb,WAAW,OAAO;GAEtB,OAAO;IACL,WAAW;IACX,WAAW,OAAO;GACpB;GACA,OAAO;EACT;EACA,QAAQ,KAAiB;GACvB,eAAe;IAAE,GAAG;IAAc,GAAG,WAAW,GAAG;GAAE;GACrD,OAAO;EACT;EACA,IAAI,YAAkC;GACpC,YAAY,KAAK,UAAU;GAC3B,OAAO;EACT;EACA,QAAQ,UAAiD;GACvD,MAAM,eAAe,mBAAmB,UAAU;GAClD,MAAM,OAAO,eAAe,MAAM,QAAQ,SAAS,WAAW;GAE9D,MAAM,OAAO,cAAc,QAAQ,IAC/B,WACA;IACE,SAAS;IACT,aAAa,CAAC;IACd,SAAS,KAAA;GACX;GAEJ,MAAM,iBAAiB,cAAc,QAAQ,IACzC,mBAAmB,UAAU,sBAAsB,IACnD,CAAC;GAEL,MAAM,UAAU,sBAAsB;IACpC,mBAAmB,8BAA8B,WAAW;IAC5D;IACA,0BAA0B,8BAA8B,KAAK,WAAW;IACxE,gBAAgB,KAAK;IACrB,SAAS;KACP,GAAG;KACH,cAAe,KAAa;KAC5B,eAAgB,KAAa;KAC7B,aAAc,KAAa;KAC3B;KACA,oBAAoB,KAAK;IAC3B;GACF,CAAC;GAED,OAAO;IACL,GAAG;IACH,oBAAoB,CAAC,GAAG,KAAK,WAAW;IACxC,SAAS,KAAK;IACd,GAAG;IACH,GAAG;IACH,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;IAC/B,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;GAC/B;EACF;CACF;CAEA,OAAO;AACT"}
@@ -1,8 +1,8 @@
1
- import { createTaserCompatHandler, NotFoundHandler, OnErrorHandler, RouteManifestShape } from '@taserjs/router-core';
2
- import { DefineMiddlewareOptions, MultiScopedMiddlewareOptions, ScopedMiddlewareOptions } from '../define/middleware.js';
1
+ import { NotFoundHandler, OnErrorHandler, RouteManifestShape } from '@taserjs/router-core';
2
+ import { DefineMiddlewareFn } from '../define/middleware.js';
3
3
  import { TaserApp } from './app.js';
4
4
  import { ContextDefinition, CreateTaserAppOptions, OnErrorOptions } from '../types/app.js';
5
- import { AppContext, ExtractState, IsUnknown, MiddlewareReturnFromParts, MiddlewareUnit } from '../types/units.js';
5
+ import { AppContext } from '../types/units.js';
6
6
  import { HandlerBuilder, LayoutId, MiddlewareBuilder } from '../types/index.js';
7
7
  import { ReturnsMap } from '../types/returns.js';
8
8
  import { Schema } from '../types/schema.js';
@@ -13,12 +13,12 @@ type RouterState = {
13
13
  onError?: OnErrorHandler;
14
14
  notFound?: NotFoundHandler;
15
15
  };
16
- export declare class TaserRouter<TAppContext extends Record<string, unknown> = AppContext> {
16
+ export declare class TaserRouter<TAppContext extends Record<string, unknown> = AppContext, THasNotFound extends boolean = false> {
17
17
  private readonly state;
18
18
  constructor(options?: CreateTaserAppOptions, state?: Partial<Omit<RouterState, "options">>);
19
- context<TBoot extends Record<string, unknown>, TReq extends Record<string, unknown>>(definition: ContextDefinition<TBoot, TReq>): TaserRouter<TBoot & TReq>;
19
+ context<TBoot extends Record<string, unknown>, TReq extends Record<string, unknown>>(definition: ContextDefinition<TBoot, TReq>): TaserRouter<TBoot & TReq, THasNotFound>;
20
20
  onError<TResponses extends ReturnsMap = ReturnsMap>(options: OnErrorOptions<TResponses> | OnErrorOptions<TResponses>["handle"]): this;
21
- notFound(handler: (ctx: unknown) => Response | Promise<Response> | unknown): this;
21
+ notFound(handler: (ctx: unknown) => Response | Promise<Response> | unknown): TaserRouter<TAppContext, true>;
22
22
  get: CreateWithoutBodyRoute<"GET", TAppContext>;
23
23
  post: CreateWithBodyRoute<"POST", TAppContext>;
24
24
  put: CreateWithBodyRoute<"PUT", TAppContext>;
@@ -38,11 +38,10 @@ export declare class TaserRouter<TAppContext extends Record<string, unknown> = A
38
38
  params: TParams;
39
39
  body: TBody;
40
40
  }, {}, TAppContext>;
41
- defineMiddleware(middleware: Parameters<typeof createTaserCompatHandler>[0]): MiddlewareUnit<MiddlewareReturnFromParts<unknown, unknown, unknown, {}>, {}, null, {}>;
42
- defineMiddleware<const Layout extends LayoutId, TState = unknown, TRequires = {}, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(layout: Layout, options: ScopedMiddlewareOptions<Layout, TState, TRequires, TQuery, TParams, TBody, TReturns, TQueryIn, TParamsIn, TBodyIn, TAppContext, R>): MiddlewareUnit<MiddlewareReturnFromParts<TQuery, TParams, TBody, IsUnknown<TState> extends true ? ExtractState<R> : TState, TQueryIn, TParamsIn, TBodyIn>, TReturns, Layout, TRequires>;
43
- defineMiddleware<const Layouts extends readonly [LayoutId, ...LayoutId[]], TState = unknown, TRequires = {}, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(layouts: Layouts, options: MultiScopedMiddlewareOptions<Layouts, TState, TRequires, TQuery, TParams, TBody, TReturns, TQueryIn, TParamsIn, TBodyIn, TAppContext, R>): MiddlewareUnit<MiddlewareReturnFromParts<TQuery, TParams, TBody, IsUnknown<TState> extends true ? ExtractState<R> : TState, TQueryIn, TParamsIn, TBodyIn>, TReturns, Layouts, TRequires>;
44
- defineMiddleware<TState = unknown, TRequires = {}, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(options: DefineMiddlewareOptions<TState, TRequires, TQuery, TParams, TBody, TReturns, TQueryIn, TParamsIn, TBodyIn, TAppContext, R>): MiddlewareUnit<MiddlewareReturnFromParts<TQuery, TParams, TBody, IsUnknown<TState> extends true ? ExtractState<R> : TState, TQueryIn, TParamsIn, TBodyIn>, TReturns, null, TRequires>;
45
- create<const TManifest extends RouteManifestShape>(manifest: TManifest): TaserApp<TManifest>;
41
+ defineMiddleware: DefineMiddlewareFn<TAppContext>;
42
+ create<const TManifest extends RouteManifestShape>(manifest: TManifest, runtimeOptions?: {
43
+ basePath?: string;
44
+ }): TaserApp<TManifest, THasNotFound>;
46
45
  }
47
- export declare function createTaserApp(options?: CreateTaserAppOptions): TaserRouter;
46
+ export declare function createTaserApp(options?: CreateTaserAppOptions): TaserRouter<AppContext, false>;
48
47
  export {};
@@ -47,14 +47,12 @@ var TaserRouter = class {
47
47
  defineHandler(options) {
48
48
  return options === void 0 ? defineHandler() : defineHandler(options);
49
49
  }
50
- defineMiddleware(first, second) {
51
- return defineMiddleware(first, second);
52
- }
53
- create(manifest) {
50
+ defineMiddleware = defineMiddleware;
51
+ create(manifest, runtimeOptions) {
54
52
  const definition = this.state.contextDef;
55
53
  const validateResponse = this.state.options.response?.validate ?? true;
56
54
  const onValidationFailure = this.state.options.response?.onValidationFailure;
57
- const basePath = this.state.options.basePath;
55
+ const basePath = runtimeOptions?.basePath;
58
56
  const hasCustomContext = definition.boot !== void 0 || definition.request !== void 0;
59
57
  let bootContextResolved;
60
58
  let bootPromise;