@taserjs/router 0.1.4 → 0.1.6

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 (127) hide show
  1. package/dist/cjs/builder/factories.cjs.map +1 -1
  2. package/dist/cjs/builder/factories.d.cts +9 -9
  3. package/dist/cjs/builder/middleware-unit.cjs +21 -12
  4. package/dist/cjs/builder/middleware-unit.cjs.map +1 -1
  5. package/dist/cjs/builder/middleware-unit.d.cts +1 -18
  6. package/dist/cjs/builder/middleware.cjs +1 -0
  7. package/dist/cjs/builder/middleware.cjs.map +1 -1
  8. package/dist/cjs/builder/route.cjs +1 -0
  9. package/dist/cjs/builder/route.cjs.map +1 -1
  10. package/dist/cjs/builder/router.cjs +1 -16
  11. package/dist/cjs/builder/router.cjs.map +1 -1
  12. package/dist/cjs/builder/router.d.cts +6 -17
  13. package/dist/cjs/builder/standalone.cjs +43 -0
  14. package/dist/cjs/builder/standalone.cjs.map +1 -0
  15. package/dist/cjs/builder/standalone.d.cts +28 -0
  16. package/dist/cjs/define/middleware.cjs +2 -3
  17. package/dist/cjs/define/middleware.cjs.map +1 -1
  18. package/dist/cjs/define/middleware.d.cts +15 -16
  19. package/dist/cjs/index.cjs +13 -2
  20. package/dist/cjs/index.d.cts +5 -3
  21. package/dist/cjs/middleware/body-limit.cjs +1 -1
  22. package/dist/cjs/middleware/body-limit.cjs.map +1 -1
  23. package/dist/cjs/middleware/body-limit.d.cts +1 -1
  24. package/dist/cjs/middleware/compress.cjs +1 -1
  25. package/dist/cjs/middleware/compress.cjs.map +1 -1
  26. package/dist/cjs/middleware/compress.d.cts +1 -1
  27. package/dist/cjs/middleware/cors.cjs +1 -1
  28. package/dist/cjs/middleware/cors.cjs.map +1 -1
  29. package/dist/cjs/middleware/cors.d.cts +1 -1
  30. package/dist/cjs/middleware/csrf.cjs +1 -1
  31. package/dist/cjs/middleware/csrf.cjs.map +1 -1
  32. package/dist/cjs/middleware/csrf.d.cts +1 -1
  33. package/dist/cjs/middleware/etag.cjs +1 -1
  34. package/dist/cjs/middleware/etag.cjs.map +1 -1
  35. package/dist/cjs/middleware/etag.d.cts +1 -1
  36. package/dist/cjs/middleware/hono-mw.cjs +1 -1
  37. package/dist/cjs/middleware/hono-mw.cjs.map +1 -1
  38. package/dist/cjs/middleware/hono-mw.d.cts +1 -1
  39. package/dist/cjs/middleware/jwk.cjs +1 -1
  40. package/dist/cjs/middleware/jwk.cjs.map +1 -1
  41. package/dist/cjs/middleware/jwt.cjs +1 -1
  42. package/dist/cjs/middleware/jwt.cjs.map +1 -1
  43. package/dist/cjs/middleware/secure-headers.cjs +1 -1
  44. package/dist/cjs/middleware/secure-headers.cjs.map +1 -1
  45. package/dist/cjs/middleware/secure-headers.d.cts +1 -1
  46. package/dist/cjs/middleware/timing.cjs +1 -1
  47. package/dist/cjs/middleware/timing.cjs.map +1 -1
  48. package/dist/cjs/middleware/timing.d.cts +1 -1
  49. package/dist/cjs/types/index.d.cts +27 -17
  50. package/dist/cjs/types/type-utils.d.cts +2 -2
  51. package/dist/cjs/types/units.d.cts +17 -19
  52. package/dist/esm/builder/factories.d.ts +9 -9
  53. package/dist/esm/builder/factories.js.map +1 -1
  54. package/dist/esm/builder/middleware-unit.d.ts +1 -18
  55. package/dist/esm/builder/middleware-unit.js +21 -12
  56. package/dist/esm/builder/middleware-unit.js.map +1 -1
  57. package/dist/esm/builder/middleware.js +1 -0
  58. package/dist/esm/builder/middleware.js.map +1 -1
  59. package/dist/esm/builder/route.js +1 -0
  60. package/dist/esm/builder/route.js.map +1 -1
  61. package/dist/esm/builder/router.d.ts +6 -17
  62. package/dist/esm/builder/router.js +1 -16
  63. package/dist/esm/builder/router.js.map +1 -1
  64. package/dist/esm/builder/standalone.d.ts +28 -0
  65. package/dist/esm/builder/standalone.js +32 -0
  66. package/dist/esm/builder/standalone.js.map +1 -0
  67. package/dist/esm/define/middleware.d.ts +15 -16
  68. package/dist/esm/define/middleware.js +2 -3
  69. package/dist/esm/define/middleware.js.map +1 -1
  70. package/dist/esm/index.d.ts +5 -3
  71. package/dist/esm/index.js +2 -2
  72. package/dist/esm/middleware/body-limit.d.ts +1 -1
  73. package/dist/esm/middleware/body-limit.js +2 -2
  74. package/dist/esm/middleware/body-limit.js.map +1 -1
  75. package/dist/esm/middleware/compress.d.ts +1 -1
  76. package/dist/esm/middleware/compress.js +2 -2
  77. package/dist/esm/middleware/compress.js.map +1 -1
  78. package/dist/esm/middleware/cors.d.ts +1 -1
  79. package/dist/esm/middleware/cors.js +2 -2
  80. package/dist/esm/middleware/cors.js.map +1 -1
  81. package/dist/esm/middleware/csrf.d.ts +1 -1
  82. package/dist/esm/middleware/csrf.js +2 -2
  83. package/dist/esm/middleware/csrf.js.map +1 -1
  84. package/dist/esm/middleware/etag.d.ts +1 -1
  85. package/dist/esm/middleware/etag.js +2 -2
  86. package/dist/esm/middleware/etag.js.map +1 -1
  87. package/dist/esm/middleware/hono-mw.d.ts +1 -1
  88. package/dist/esm/middleware/hono-mw.js +1 -1
  89. package/dist/esm/middleware/hono-mw.js.map +1 -1
  90. package/dist/esm/middleware/jwk.js +2 -2
  91. package/dist/esm/middleware/jwk.js.map +1 -1
  92. package/dist/esm/middleware/jwt.js +2 -2
  93. package/dist/esm/middleware/jwt.js.map +1 -1
  94. package/dist/esm/middleware/secure-headers.d.ts +1 -1
  95. package/dist/esm/middleware/secure-headers.js +2 -2
  96. package/dist/esm/middleware/secure-headers.js.map +1 -1
  97. package/dist/esm/middleware/timing.d.ts +1 -1
  98. package/dist/esm/middleware/timing.js +2 -2
  99. package/dist/esm/middleware/timing.js.map +1 -1
  100. package/dist/esm/types/index.d.ts +27 -17
  101. package/dist/esm/types/type-utils.d.ts +2 -2
  102. package/dist/esm/types/units.d.ts +17 -19
  103. package/package.json +3 -3
  104. package/src/builder/factories.ts +2 -2
  105. package/src/builder/middleware-unit.ts +22 -11
  106. package/src/builder/middleware.ts +2 -0
  107. package/src/builder/route.ts +2 -0
  108. package/src/builder/router.ts +7 -60
  109. package/src/builder/standalone.ts +70 -0
  110. package/src/define/middleware.ts +37 -18
  111. package/src/index.ts +26 -2
  112. package/src/middleware/body-limit.ts +2 -2
  113. package/src/middleware/compress.ts +2 -2
  114. package/src/middleware/cors.ts +2 -2
  115. package/src/middleware/csrf.ts +2 -2
  116. package/src/middleware/etag.ts +2 -2
  117. package/src/middleware/hono-mw.ts +1 -1
  118. package/src/middleware/jwk.ts +2 -2
  119. package/src/middleware/jwt.ts +2 -2
  120. package/src/middleware/secure-headers.ts +2 -2
  121. package/src/middleware/timing.ts +2 -2
  122. package/src/types/index.ts +53 -28
  123. package/src/types/type-utils.ts +8 -4
  124. package/src/types/units.ts +46 -22
  125. package/dist/cjs/register.d.cts +0 -2
  126. package/dist/esm/register.d.ts +0 -2
  127. package/src/register.ts +0 -1
@@ -1,8 +1,5 @@
1
- import { type Awaitable } from "@taserjs/router-core";
2
-
3
1
  import { createMiddlewareUnitBuilder } from "../builder/middleware-unit.js";
4
2
  import type {
5
- AppContext,
6
3
  DefineMiddlewareResult,
7
4
  ExtractState,
8
5
  IsUnknown,
@@ -11,30 +8,44 @@ import type {
11
8
  StandaloneMiddlewareContext,
12
9
  } from "../types/units.js";
13
10
  import type {
11
+ AppContext,
14
12
  LayoutId,
15
13
  ResolveLayoutMiddlewaresState,
16
14
  ResolveLayoutsState,
17
15
  } from "../types/index.js";
18
16
 
19
- export interface DefineMiddlewareFn<TAppContext extends Record<string, unknown> = AppContext> {
17
+ export interface MiddlewareFn<TAppContext extends Record<string, unknown> = AppContext> {
20
18
  /**
21
- * Constructs a fluent unscoped middleware builder.
19
+ * Constructs a fluent unscoped middleware builder, with optional explicit State generic.
22
20
  *
23
21
  * @example
24
22
  * ```ts
25
- * const auth = defineMiddleware()
23
+ * const auth = middleware<{ user: string }>()
26
24
  * .query(z.object({ token: z.string() }))
27
25
  * .body("form", z.object({ file: z.instanceof(File) }))
28
26
  * .returns({ 401: z.string() })
29
27
  * .handler(async (ctx, next) => next({ user: "alice" }));
30
28
  * ```
31
29
  */
32
- (): MiddlewareUnitBuilder<unknown, unknown, unknown, {}, null, {}, TAppContext>;
30
+ <TState = unknown>(): MiddlewareUnitBuilder<
31
+ unknown,
32
+ unknown,
33
+ unknown,
34
+ {},
35
+ null,
36
+ {},
37
+ TAppContext,
38
+ {},
39
+ unknown,
40
+ unknown,
41
+ unknown,
42
+ TState
43
+ >;
33
44
 
34
45
  /**
35
- * Constructs a fluent middleware builder scoped to a single layout branch.
46
+ * Constructs a fluent middleware builder scoped to a single layout branch, with optional explicit State generic.
36
47
  */
37
- <const Layout extends LayoutId>(
48
+ <const Layout extends LayoutId, TState = unknown>(
38
49
  layout: Layout,
39
50
  ): MiddlewareUnitBuilder<
40
51
  unknown,
@@ -44,13 +55,17 @@ export interface DefineMiddlewareFn<TAppContext extends Record<string, unknown>
44
55
  Layout,
45
56
  {},
46
57
  TAppContext,
47
- ResolveLayoutMiddlewaresState<Layout>
58
+ ResolveLayoutMiddlewaresState<Layout>,
59
+ unknown,
60
+ unknown,
61
+ unknown,
62
+ TState
48
63
  >;
49
64
 
50
65
  /**
51
- * Constructs a fluent middleware builder scoped to multiple layout branches (branch union).
66
+ * Constructs a fluent middleware builder scoped to multiple layout branches (branch union), with optional explicit State generic.
52
67
  */
53
- <const Layouts extends readonly [LayoutId, ...LayoutId[]]>(
68
+ <const Layouts extends readonly [LayoutId, ...LayoutId[]], TState = unknown>(
54
69
  layouts: Layouts,
55
70
  ): MiddlewareUnitBuilder<
56
71
  unknown,
@@ -60,7 +75,11 @@ export interface DefineMiddlewareFn<TAppContext extends Record<string, unknown>
60
75
  Layouts,
61
76
  {},
62
77
  TAppContext,
63
- ResolveLayoutsState<Layouts>
78
+ ResolveLayoutsState<Layouts>,
79
+ unknown,
80
+ unknown,
81
+ unknown,
82
+ TState
64
83
  >;
65
84
 
66
85
  /**
@@ -77,7 +96,7 @@ export interface DefineMiddlewareFn<TAppContext extends Record<string, unknown>
77
96
  ResolveLayoutMiddlewaresState<Layout> & TRequires
78
97
  >,
79
98
  next: NextFn<NoInfer<TState>>,
80
- ) => Awaitable<R>,
99
+ ) => R,
81
100
  ): DefineMiddlewareResult<
82
101
  unknown,
83
102
  unknown,
@@ -111,7 +130,7 @@ export interface DefineMiddlewareFn<TAppContext extends Record<string, unknown>
111
130
  ResolveLayoutsState<Layouts> & TRequires
112
131
  >,
113
132
  next: NextFn<NoInfer<TState>>,
114
- ) => Awaitable<R>,
133
+ ) => R,
115
134
  ): DefineMiddlewareResult<
116
135
  unknown,
117
136
  unknown,
@@ -131,7 +150,7 @@ export interface DefineMiddlewareFn<TAppContext extends Record<string, unknown>
131
150
  *
132
151
  * @example
133
152
  * ```ts
134
- * const auth = defineMiddleware((ctx, next) => {
153
+ * const auth = middleware((ctx, next) => {
135
154
  * return next({ user: "alice" });
136
155
  * });
137
156
  * ```
@@ -140,7 +159,7 @@ export interface DefineMiddlewareFn<TAppContext extends Record<string, unknown>
140
159
  fn: (
141
160
  ctx: StandaloneMiddlewareContext<unknown, unknown, unknown, TAppContext, TRequires>,
142
161
  next: NextFn<NoInfer<TState>>,
143
- ) => Awaitable<R>,
162
+ ) => R,
144
163
  ): DefineMiddlewareResult<
145
164
  unknown,
146
165
  unknown,
@@ -156,7 +175,7 @@ export interface DefineMiddlewareFn<TAppContext extends Record<string, unknown>
156
175
  >;
157
176
  }
158
177
 
159
- export const defineMiddleware: DefineMiddlewareFn<AppContext> = function defineMiddleware(
178
+ export const middleware: MiddlewareFn<AppContext> = function middleware(
160
179
  first?: any,
161
180
  second?: any,
162
181
  ): any {
package/src/index.ts CHANGED
@@ -1,17 +1,25 @@
1
- export type { RouterRegister } from "./register.js";
1
+ export interface RouterRegister {}
2
2
  export type {
3
+ AppContext,
4
+ EmptyAppContext,
3
5
  HttpMethod,
4
6
  InferInput,
5
7
  InferOutput,
6
8
  InferRouteContext,
7
9
  InferRouteInput,
10
+ InferRouteInputFromPath,
8
11
  InferRouteOutput,
12
+ LayoutBuilder,
13
+ LayoutId,
14
+ LayoutTree,
9
15
  Method,
16
+ MiddlewareBuilder,
10
17
  MiddlewareDefinition,
11
18
  MiddlewareUnit,
12
19
  MiddlewareUnitBuilder,
13
20
  PathParams,
14
21
  ReturnsMap,
22
+ RouteByPathMethod,
15
23
  RouteDefinition,
16
24
  RouteExport,
17
25
  RoutePath,
@@ -31,10 +39,26 @@ export type {
31
39
  export { ValidationError, validationErrorSchema } from "@taserjs/router-utils";
32
40
  export type { ResponseValidationFailureHandler, SuccessStatusCode } from "@taserjs/router-utils";
33
41
 
42
+ export {
43
+ all,
44
+ any,
45
+ del,
46
+ get,
47
+ head,
48
+ layout,
49
+ middleware,
50
+ options,
51
+ patch,
52
+ post,
53
+ put,
54
+ t,
55
+ type TaserNamespace,
56
+ } from "./builder/standalone.js";
57
+
34
58
  export { createTaserApp, TaserRouter } from "./builder/router.js";
35
59
  export { TaserApp } from "./builder/app.js";
36
60
  export { createContext } from "./context/create-context.js";
37
- export { defineMiddleware } from "./define/middleware.js";
38
61
  export { honoMw } from "./middleware/hono-mw.js";
62
+ export type { MiddlewareFn } from "./define/middleware.js";
39
63
 
40
64
  export type { TaserCookieJar, TaserHeaders } from "@taserjs/router-core";
@@ -1,10 +1,10 @@
1
1
  import { bodyLimit as honoBodyLimit } from "hono/body-limit";
2
2
 
3
- import { defineMiddleware } from "../define/middleware.js";
3
+ import { middleware } from "../define/middleware.js";
4
4
  import { honoMw } from "./hono-mw.js";
5
5
 
6
6
  export function bodyLimit(...args: Parameters<typeof honoBodyLimit>) {
7
- return defineMiddleware(honoMw(honoBodyLimit(...args)));
7
+ return middleware(honoMw(honoBodyLimit(...args)));
8
8
  }
9
9
 
10
10
  export type BodyLimitOptions = Parameters<typeof honoBodyLimit>[0];
@@ -1,10 +1,10 @@
1
1
  import { compress as honoCompress } from "hono/compress";
2
2
 
3
- import { defineMiddleware } from "../define/middleware.js";
3
+ import { middleware } from "../define/middleware.js";
4
4
  import { honoMw } from "./hono-mw.js";
5
5
 
6
6
  export function compress(...args: Parameters<typeof honoCompress>) {
7
- return defineMiddleware(honoMw(honoCompress(...args)));
7
+ return middleware(honoMw(honoCompress(...args)));
8
8
  }
9
9
 
10
10
  export type CompressOptions = NonNullable<Parameters<typeof honoCompress>[0]>;
@@ -1,10 +1,10 @@
1
1
  import { cors as honoCors } from "hono/cors";
2
2
 
3
- import { defineMiddleware } from "../define/middleware.js";
3
+ import { middleware } from "../define/middleware.js";
4
4
  import { honoMw } from "./hono-mw.js";
5
5
 
6
6
  export function cors(...args: Parameters<typeof honoCors>) {
7
- return defineMiddleware(honoMw(honoCors(...args)));
7
+ return middleware(honoMw(honoCors(...args)));
8
8
  }
9
9
 
10
10
  export type CorsOptions = NonNullable<Parameters<typeof honoCors>[0]>;
@@ -1,10 +1,10 @@
1
1
  import { csrf as honoCsrf } from "hono/csrf";
2
2
 
3
- import { defineMiddleware } from "../define/middleware.js";
3
+ import { middleware } from "../define/middleware.js";
4
4
  import { honoMw } from "./hono-mw.js";
5
5
 
6
6
  export function csrf(...args: Parameters<typeof honoCsrf>) {
7
- return defineMiddleware(honoMw(honoCsrf(...args)));
7
+ return middleware(honoMw(honoCsrf(...args)));
8
8
  }
9
9
 
10
10
  export type CsrfOptions = NonNullable<Parameters<typeof honoCsrf>[0]>;
@@ -1,10 +1,10 @@
1
1
  import { etag as honoEtag } from "hono/etag";
2
2
 
3
- import { defineMiddleware } from "../define/middleware.js";
3
+ import { middleware } from "../define/middleware.js";
4
4
  import { honoMw } from "./hono-mw.js";
5
5
 
6
6
  export function etag(...args: Parameters<typeof honoEtag>) {
7
- return defineMiddleware(honoMw(honoEtag(...args)));
7
+ return middleware(honoMw(honoEtag(...args)));
8
8
  }
9
9
 
10
10
  export type EtagOptions = NonNullable<Parameters<typeof honoEtag>[0]>;
@@ -12,7 +12,7 @@ import type { MiddlewareHandler } from "hono";
12
12
  *
13
13
  * const app = t.get("/hello").use(honoMw(cors()));
14
14
  * // or
15
- * const customCors = defineMiddleware(honoMw(cors()));
15
+ * const customCors = middleware(honoMw(cors()));
16
16
  * ```
17
17
  */
18
18
  export function honoMw(
@@ -1,6 +1,6 @@
1
1
  import { jwk as honoJwk } from "hono/jwk";
2
2
 
3
- import { defineMiddleware } from "../define/middleware.js";
3
+ import { middleware } from "../define/middleware.js";
4
4
  import { honoMw } from "./hono-mw.js";
5
5
  import type { JwtMiddlewareUnit, JwtPayloadState } from "./jwt.js";
6
6
 
@@ -42,7 +42,7 @@ export function jwk<TPayload = Record<string, unknown>>(
42
42
  const safeInit = init?.headers !== undefined ? { headers: init.headers } : undefined;
43
43
  const mw = honoMw(honoJwk(honoOptions, safeInit));
44
44
 
45
- return defineMiddleware<JwtPayloadState<TPayload>>((ctx, next) =>
45
+ return middleware<JwtPayloadState<TPayload>>((ctx, next) =>
46
46
  mw(ctx, async () => {
47
47
  const payload = (ctx as unknown as { var: { jwtPayload?: unknown } }).var.jwtPayload;
48
48
  return next({ jwtPayload: payload as TPayload });
@@ -1,6 +1,6 @@
1
1
  import { jwt as honoJwt } from "hono/jwt";
2
2
 
3
- import { defineMiddleware } from "../define/middleware.js";
3
+ import { middleware } from "../define/middleware.js";
4
4
  import type { MiddlewareReturnFromParts, MiddlewareUnit } from "../types/units.js";
5
5
  import { honoMw } from "./hono-mw.js";
6
6
 
@@ -22,7 +22,7 @@ export function jwt<TPayload = Record<string, unknown>>(
22
22
  options: JwtOptions,
23
23
  ): JwtMiddlewareUnit<TPayload> {
24
24
  const mw = honoMw(honoJwt(options));
25
- return defineMiddleware<JwtPayloadState<TPayload>>((ctx, next) =>
25
+ return middleware<JwtPayloadState<TPayload>>((ctx, next) =>
26
26
  mw(ctx, async () => {
27
27
  const payload = (ctx as unknown as { var: { jwtPayload?: unknown } }).var.jwtPayload;
28
28
  return next({ jwtPayload: payload as TPayload });
@@ -1,10 +1,10 @@
1
1
  import { secureHeaders as honoSecureHeaders } from "hono/secure-headers";
2
2
 
3
- import { defineMiddleware } from "../define/middleware.js";
3
+ import { middleware } from "../define/middleware.js";
4
4
  import { honoMw } from "./hono-mw.js";
5
5
 
6
6
  export function secureHeaders(...args: Parameters<typeof honoSecureHeaders>) {
7
- return defineMiddleware(honoMw(honoSecureHeaders(...args)));
7
+ return middleware(honoMw(honoSecureHeaders(...args)));
8
8
  }
9
9
 
10
10
  export type SecureHeadersOptions = NonNullable<Parameters<typeof honoSecureHeaders>[0]>;
@@ -1,10 +1,10 @@
1
1
  import { timing as honoTiming } from "hono/timing";
2
2
 
3
- import { defineMiddleware } from "../define/middleware.js";
3
+ import { middleware } from "../define/middleware.js";
4
4
  import { honoMw } from "./hono-mw.js";
5
5
 
6
6
  export function timing(...args: Parameters<typeof honoTiming>) {
7
- return defineMiddleware(honoMw(honoTiming(...args)));
7
+ return middleware(honoMw(honoTiming(...args)));
8
8
  }
9
9
 
10
10
  export type TimingOptions = NonNullable<Parameters<typeof honoTiming>[0]>;
@@ -1,5 +1,5 @@
1
1
  import type { Awaitable, TaserCookieJar, TaserHeaders } from "@taserjs/router-core";
2
- import type { RouterRegister } from "../register.js";
2
+ import type { RouterRegister } from "../index.js";
3
3
  import type {
4
4
  MergeMiddlewareField,
5
5
  MergeMiddlewareInputField,
@@ -12,7 +12,7 @@ import type {
12
12
  import type { ReturnsMap, ValidHandlerReply } from "./returns.js";
13
13
  import type { Schema } from "./schema.js";
14
14
  import type {
15
- AppContext,
15
+ EmptyAppContext,
16
16
  ExtractState,
17
17
  Method,
18
18
  MiddlewareDefinition,
@@ -30,7 +30,6 @@ export type {
30
30
  Schema,
31
31
  StandardSchemaV1,
32
32
  } from "./schema.js";
33
- export type { RouterRegister } from "../register.js";
34
33
  export type {
35
34
  MergeMiddlewareField,
36
35
  MergeMiddlewareInputField,
@@ -52,13 +51,12 @@ export type {
52
51
  ValidHandlerReply,
53
52
  } from "./returns.js";
54
53
  export type {
55
- AppContext,
54
+ EmptyAppContext,
56
55
  ExtractState,
57
56
  HttpMethod,
58
57
  IsUnknown,
59
58
  Method,
60
59
  MiddlewareDefinition,
61
- MiddlewareNext,
62
60
  MiddlewareReturnFromParts,
63
61
  MiddlewareUnit,
64
62
  MiddlewareUnitBuilder,
@@ -69,6 +67,8 @@ export type {
69
67
  ValidatorParts,
70
68
  } from "./units.js";
71
69
 
70
+ export type AppContext = RouterRegister extends { AppContext: infer C } ? C : EmptyAppContext;
71
+
72
72
  export type RoutePath = RouterRegister extends { RoutePath: infer P } ? P : never;
73
73
  export type LayoutId = RouterRegister extends { LayoutId: infer L } ? L : never;
74
74
  export type LayoutTree = RouterRegister extends { LayoutTree: infer T } ? T : Record<never, never>;
@@ -76,6 +76,12 @@ export type RouteByPathMethod = RouterRegister extends { RouteByPathMethod: infe
76
76
  ? R
77
77
  : Record<never, never>;
78
78
 
79
+ export type LayoutBuilder<TAppContext extends Record<string, unknown> = AppContext> = <
80
+ const Layout extends LayoutId,
81
+ >(
82
+ layout: Layout,
83
+ ) => MiddlewareBuilder<Layout, readonly [], TAppContext>;
84
+
79
85
  type ParseParam<Segment extends string> = Segment extends "*"
80
86
  ? { _splat: string }
81
87
  : Segment extends `:${infer Name extends string}`
@@ -99,25 +105,49 @@ export type ResolveParams<TPathParams, TSchemaParams> =
99
105
  : Simplify<Omit<TPathParams, keyof TSchemaParams> & TSchemaParams>
100
106
  : TPathParams;
101
107
 
102
- type LayoutParent<Layout extends LayoutId> = LayoutTree[Layout] extends {
103
- parent: infer Parent extends LayoutId | null;
108
+ type LayoutParentsMap = RouterRegister extends {
109
+ LayoutParents: infer LP extends Record<string, unknown>;
104
110
  }
105
- ? Parent
106
- : null;
111
+ ? LP
112
+ : {};
113
+
114
+ type LayoutParent<Layout extends LayoutId> = Layout extends keyof LayoutParentsMap
115
+ ? LayoutParentsMap[Layout] extends LayoutId
116
+ ? LayoutParentsMap[Layout]
117
+ : null
118
+ : LayoutTree[Layout] extends {
119
+ parent: infer Parent extends LayoutId | null;
120
+ }
121
+ ? Parent
122
+ : null;
123
+
124
+ type LayoutMiddlewares<Layout extends LayoutId> = LayoutTree[Layout]["middlewares"] extends {
125
+ readonly __acc?: infer Acc extends readonly unknown[];
126
+ }
127
+ ? Acc
128
+ : LayoutTree[Layout]["middlewares"] extends infer Acc extends readonly unknown[]
129
+ ? Acc
130
+ : readonly [];
107
131
 
108
- type ResolveLayoutMiddlewares<Layout extends LayoutId | null> = Layout extends null
132
+ type ResolveLayoutMiddlewares<
133
+ Layout extends LayoutId | null,
134
+ Depth extends readonly unknown[] = [],
135
+ > = Depth["length"] extends 10
109
136
  ? readonly []
110
137
  : Layout extends LayoutId
111
138
  ? readonly [
112
- ...ResolveLayoutMiddlewares<LayoutParent<Layout>>,
113
- ...LayoutTree[Layout]["middlewares"],
139
+ ...ResolveLayoutMiddlewares<LayoutParent<Layout>, [...Depth, unknown]>,
140
+ ...LayoutMiddlewares<Layout>,
114
141
  ]
115
142
  : readonly [];
116
143
 
117
- export type ResolveLayoutIdChain<L extends LayoutId | null> = L extends null
144
+ export type ResolveLayoutIdChain<
145
+ L extends LayoutId | null,
146
+ Depth extends readonly unknown[] = [],
147
+ > = Depth["length"] extends 10
118
148
  ? readonly []
119
149
  : L extends LayoutId
120
- ? readonly [...ResolveLayoutIdChain<LayoutParent<L>>, L]
150
+ ? readonly [...ResolveLayoutIdChain<LayoutParent<L>, [...Depth, unknown]>, L]
121
151
  : readonly [];
122
152
 
123
153
  export type ResolveLayoutMiddlewaresState<Layout extends LayoutId | null> = Layout extends LayoutId
@@ -141,7 +171,7 @@ type ResolveLayoutChainMiddlewares<Chain extends readonly LayoutId[]> = Chain ex
141
171
  ...infer Rest,
142
172
  ]
143
173
  ? readonly [
144
- ...LayoutTree[Head]["middlewares"],
174
+ ...LayoutMiddlewares<Head>,
145
175
  ...ResolveLayoutChainMiddlewares<Rest extends readonly LayoutId[] ? Rest : readonly []>,
146
176
  ]
147
177
  : readonly [];
@@ -188,13 +218,6 @@ type RouteResolvedField<
188
218
  Field extends "query" | "params" | "body" | "state",
189
219
  > = RouteLayoutField<Path, TMethod, Field> & MergeMiddlewareField<Acc, Field>;
190
220
 
191
- type RouteChainField<
192
- Path extends RoutePath,
193
- TMethod extends Method,
194
- Acc extends readonly unknown[],
195
- Field extends "query" | "params" | "body" | "state",
196
- > = RouteResolvedField<Path, TMethod, Acc, Field>;
197
-
198
221
  export type RouteChainContext<
199
222
  Path extends RoutePath,
200
223
  TMethod extends Method,
@@ -206,15 +229,15 @@ export type RouteChainContext<
206
229
  > = Simplify<
207
230
  TAppContext &
208
231
  UnitRuntimeContext & {
209
- query: Simplify<MergePart<TQuery, RouteChainField<Path, TMethod, Acc, "query">>>;
232
+ query: Simplify<MergePart<TQuery, RouteResolvedField<Path, TMethod, Acc, "query">>>;
210
233
  params: Simplify<
211
234
  ResolveParams<
212
235
  PathParams<Path>,
213
- MergePart<TParams, RouteChainField<Path, TMethod, Acc, "params">>
236
+ MergePart<TParams, RouteResolvedField<Path, TMethod, Acc, "params">>
214
237
  >
215
238
  >;
216
- body: Simplify<MergePart<TBody, RouteChainField<Path, TMethod, Acc, "body">>>;
217
- state: Simplify<RouteChainField<Path, TMethod, Acc, "state">>;
239
+ body: Simplify<MergePart<TBody, RouteResolvedField<Path, TMethod, Acc, "body">>>;
240
+ state: Simplify<RouteResolvedField<Path, TMethod, Acc, "state">>;
218
241
  headers: TaserHeaders;
219
242
  cookies: TaserCookieJar;
220
243
  }
@@ -455,9 +478,10 @@ export type MiddlewareBuilder<
455
478
  Layout extends LayoutId,
456
479
  Acc extends readonly unknown[] = readonly [],
457
480
  TAppContext extends Record<string, unknown> = AppContext,
458
- > = Acc & {
481
+ > = {
459
482
  readonly layout: Layout;
460
483
  readonly middlewares: readonly MiddlewareDefinition[];
484
+ readonly __acc?: Acc;
461
485
  readonly $Infer: {
462
486
  Context: MiddlewareChainContext<Layout, Acc, unknown, unknown, unknown, TAppContext>;
463
487
  };
@@ -496,11 +520,12 @@ export type RouteExport<
496
520
  Acc extends readonly unknown[],
497
521
  TReturns extends ReturnsMap = {},
498
522
  TOutput = Response,
499
- > = Acc & {
523
+ > = {
500
524
  readonly path: Path;
501
525
  readonly method: TMethod | "ANY" | "ALL";
502
526
  readonly methods?: readonly Method[];
503
527
  readonly middlewares: readonly MiddlewareDefinition[];
528
+ readonly __acc?: Acc;
504
529
  readonly returns?: TReturns;
505
530
  readonly bodyMode?: "json" | "form" | "urlencoded";
506
531
  handler: (ctx: unknown) => Awaitable<Response>;
@@ -63,16 +63,20 @@ export type MiddlewareInputField<
63
63
  export type MergeMiddlewareField<
64
64
  Middlewares extends readonly unknown[],
65
65
  Field extends MiddlewareFieldName,
66
- > = [Middlewares] extends [readonly []]
66
+ > = Middlewares extends readonly []
67
67
  ? {}
68
- : UnionToIntersection<MiddlewareField<Middlewares[number], Field>>;
68
+ : Middlewares extends readonly [infer Head, ...infer Tail]
69
+ ? MiddlewareField<Head, Field> & MergeMiddlewareField<Tail, Field>
70
+ : MiddlewareField<Middlewares[number], Field>;
69
71
 
70
72
  export type MergeMiddlewareInputField<
71
73
  Middlewares extends readonly unknown[],
72
74
  Field extends MiddlewareInputFieldName,
73
- > = [Middlewares] extends [readonly []]
75
+ > = Middlewares extends readonly []
74
76
  ? {}
75
- : UnionToIntersection<MiddlewareInputField<Middlewares[number], Field>>;
77
+ : Middlewares extends readonly [infer Head, ...infer Tail]
78
+ ? MiddlewareInputField<Head, Field> & MergeMiddlewareInputField<Tail, Field>
79
+ : MiddlewareInputField<Middlewares[number], Field>;
76
80
 
77
81
  export type RuntimeContextFields = {
78
82
  request: Request;