@taserjs/router 0.0.3 → 0.0.5

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 (160) hide show
  1. package/dist/cjs/builder/app.cjs +22 -0
  2. package/dist/cjs/builder/app.cjs.map +1 -0
  3. package/dist/cjs/builder/app.d.cts +11 -0
  4. package/dist/cjs/{constants.cjs → builder/constants.cjs} +1 -1
  5. package/dist/cjs/builder/constants.cjs.map +1 -0
  6. package/dist/cjs/{factories.cjs → builder/factories.cjs} +1 -1
  7. package/dist/cjs/builder/factories.cjs.map +1 -0
  8. package/dist/cjs/{factories.d.cts → builder/factories.d.cts} +2 -2
  9. package/dist/cjs/{middleware.cjs → builder/middleware.cjs} +1 -1
  10. package/dist/cjs/builder/middleware.cjs.map +1 -0
  11. package/dist/cjs/{middleware.d.cts → builder/middleware.d.cts} +1 -1
  12. package/dist/cjs/{route.cjs → builder/route.cjs} +19 -33
  13. package/dist/cjs/builder/route.cjs.map +1 -0
  14. package/dist/cjs/{route.d.cts → builder/route.d.cts} +3 -3
  15. package/dist/cjs/{taser-router.cjs → builder/router.cjs} +38 -11
  16. package/dist/cjs/builder/router.cjs.map +1 -0
  17. package/dist/cjs/builder/router.d.cts +48 -0
  18. package/dist/cjs/{create-context.cjs → context/create-context.cjs} +1 -1
  19. package/dist/cjs/context/create-context.cjs.map +1 -0
  20. package/dist/cjs/{create-context.d.cts → context/create-context.d.cts} +2 -2
  21. package/dist/cjs/define/middleware.cjs +13 -3
  22. package/dist/cjs/define/middleware.cjs.map +1 -1
  23. package/dist/cjs/define/middleware.d.cts +21 -4
  24. package/dist/cjs/define/validators.cjs +1 -1
  25. package/dist/cjs/define/validators.cjs.map +1 -1
  26. package/dist/cjs/define/validators.d.cts +1 -1
  27. package/dist/cjs/index.cjs +6 -16
  28. package/dist/cjs/index.d.cts +6 -7
  29. package/dist/cjs/middleware/body-limit.cjs +2 -2
  30. package/dist/cjs/middleware/body-limit.cjs.map +1 -1
  31. package/dist/cjs/middleware/compress.cjs +2 -2
  32. package/dist/cjs/middleware/compress.cjs.map +1 -1
  33. package/dist/cjs/middleware/cors.cjs +2 -2
  34. package/dist/cjs/middleware/cors.cjs.map +1 -1
  35. package/dist/cjs/middleware/csrf.cjs +2 -2
  36. package/dist/cjs/middleware/csrf.cjs.map +1 -1
  37. package/dist/cjs/middleware/etag.cjs +2 -2
  38. package/dist/cjs/middleware/etag.cjs.map +1 -1
  39. package/dist/cjs/middleware/jwk.cjs +2 -8
  40. package/dist/cjs/middleware/jwk.cjs.map +1 -1
  41. package/dist/cjs/middleware/jwt.cjs +2 -8
  42. package/dist/cjs/middleware/jwt.cjs.map +1 -1
  43. package/dist/cjs/middleware/secure-headers.cjs +2 -2
  44. package/dist/cjs/middleware/secure-headers.cjs.map +1 -1
  45. package/dist/cjs/middleware/timing.cjs +2 -2
  46. package/dist/cjs/middleware/timing.cjs.map +1 -1
  47. package/dist/cjs/middleware/wrap-hono.cjs +10 -0
  48. package/dist/cjs/middleware/wrap-hono.cjs.map +1 -1
  49. package/dist/cjs/middleware/wrap-hono.d.cts +4 -0
  50. package/dist/cjs/types/app.d.cts +7 -7
  51. package/dist/cjs/types/index.d.cts +73 -17
  52. package/dist/cjs/types/returns.d.cts +2 -2
  53. package/dist/cjs/types/type-utils.d.cts +1 -2
  54. package/dist/cjs/types/units.cjs.map +1 -1
  55. package/dist/cjs/types/units.d.cts +9 -12
  56. package/dist/esm/builder/app.d.ts +11 -0
  57. package/dist/esm/builder/app.js +22 -0
  58. package/dist/esm/builder/app.js.map +1 -0
  59. package/dist/esm/{constants.js → builder/constants.js} +1 -1
  60. package/dist/esm/builder/constants.js.map +1 -0
  61. package/dist/esm/{factories.d.ts → builder/factories.d.ts} +2 -2
  62. package/dist/esm/{factories.js → builder/factories.js} +1 -1
  63. package/dist/esm/builder/factories.js.map +1 -0
  64. package/dist/esm/{middleware.d.ts → builder/middleware.d.ts} +1 -1
  65. package/dist/esm/{middleware.js → builder/middleware.js} +1 -1
  66. package/dist/esm/builder/middleware.js.map +1 -0
  67. package/dist/esm/{route.d.ts → builder/route.d.ts} +3 -3
  68. package/dist/esm/{route.js → builder/route.js} +19 -33
  69. package/dist/esm/builder/route.js.map +1 -0
  70. package/dist/esm/builder/router.d.ts +48 -0
  71. package/dist/esm/{taser-router.js → builder/router.js} +37 -10
  72. package/dist/esm/builder/router.js.map +1 -0
  73. package/dist/esm/{create-context.d.ts → context/create-context.d.ts} +2 -2
  74. package/dist/esm/{create-context.js → context/create-context.js} +1 -1
  75. package/dist/esm/context/create-context.js.map +1 -0
  76. package/dist/esm/define/middleware.d.ts +21 -4
  77. package/dist/esm/define/middleware.js +13 -3
  78. package/dist/esm/define/middleware.js.map +1 -1
  79. package/dist/esm/define/validators.d.ts +1 -1
  80. package/dist/esm/define/validators.js +1 -1
  81. package/dist/esm/define/validators.js.map +1 -1
  82. package/dist/esm/index.d.ts +6 -7
  83. package/dist/esm/index.js +5 -6
  84. package/dist/esm/middleware/body-limit.js +2 -2
  85. package/dist/esm/middleware/body-limit.js.map +1 -1
  86. package/dist/esm/middleware/compress.js +2 -2
  87. package/dist/esm/middleware/compress.js.map +1 -1
  88. package/dist/esm/middleware/cors.js +2 -2
  89. package/dist/esm/middleware/cors.js.map +1 -1
  90. package/dist/esm/middleware/csrf.js +2 -2
  91. package/dist/esm/middleware/csrf.js.map +1 -1
  92. package/dist/esm/middleware/etag.js +2 -2
  93. package/dist/esm/middleware/etag.js.map +1 -1
  94. package/dist/esm/middleware/jwk.js +2 -8
  95. package/dist/esm/middleware/jwk.js.map +1 -1
  96. package/dist/esm/middleware/jwt.js +2 -8
  97. package/dist/esm/middleware/jwt.js.map +1 -1
  98. package/dist/esm/middleware/secure-headers.js +2 -2
  99. package/dist/esm/middleware/secure-headers.js.map +1 -1
  100. package/dist/esm/middleware/timing.js +2 -2
  101. package/dist/esm/middleware/timing.js.map +1 -1
  102. package/dist/esm/middleware/wrap-hono.d.ts +4 -0
  103. package/dist/esm/middleware/wrap-hono.js +10 -1
  104. package/dist/esm/middleware/wrap-hono.js.map +1 -1
  105. package/dist/esm/types/app.d.ts +7 -7
  106. package/dist/esm/types/index.d.ts +73 -17
  107. package/dist/esm/types/returns.d.ts +2 -2
  108. package/dist/esm/types/type-utils.d.ts +1 -2
  109. package/dist/esm/types/units.d.ts +9 -12
  110. package/dist/esm/types/units.js.map +1 -1
  111. package/package.json +3 -3
  112. package/src/builder/app.ts +28 -0
  113. package/src/{factories.ts → builder/factories.ts} +2 -2
  114. package/src/{middleware.ts → builder/middleware.ts} +2 -2
  115. package/src/{route.ts → builder/route.ts} +30 -34
  116. package/src/builder/router.ts +347 -0
  117. package/src/{create-context.ts → context/create-context.ts} +2 -2
  118. package/src/define/middleware.ts +197 -7
  119. package/src/define/validators.ts +1 -1
  120. package/src/index.ts +9 -12
  121. package/src/middleware/body-limit.ts +2 -2
  122. package/src/middleware/compress.ts +2 -2
  123. package/src/middleware/cors.ts +2 -2
  124. package/src/middleware/csrf.ts +2 -2
  125. package/src/middleware/etag.ts +2 -2
  126. package/src/middleware/jwk.ts +2 -7
  127. package/src/middleware/jwt.ts +2 -7
  128. package/src/middleware/secure-headers.ts +2 -2
  129. package/src/middleware/timing.ts +2 -2
  130. package/src/middleware/wrap-hono.ts +13 -0
  131. package/src/types/app.ts +12 -8
  132. package/src/types/index.ts +145 -16
  133. package/src/types/returns.ts +2 -2
  134. package/src/types/type-utils.ts +1 -2
  135. package/src/types/units.ts +10 -9
  136. package/dist/cjs/constants.cjs.map +0 -1
  137. package/dist/cjs/create-context.cjs.map +0 -1
  138. package/dist/cjs/factories.cjs.map +0 -1
  139. package/dist/cjs/middleware.cjs.map +0 -1
  140. package/dist/cjs/route.cjs.map +0 -1
  141. package/dist/cjs/taser-app.cjs +0 -36
  142. package/dist/cjs/taser-app.cjs.map +0 -1
  143. package/dist/cjs/taser-app.d.cts +0 -18
  144. package/dist/cjs/taser-router.cjs.map +0 -1
  145. package/dist/cjs/taser-router.d.cts +0 -42
  146. package/dist/esm/constants.js.map +0 -1
  147. package/dist/esm/create-context.js.map +0 -1
  148. package/dist/esm/factories.js.map +0 -1
  149. package/dist/esm/middleware.js.map +0 -1
  150. package/dist/esm/route.js.map +0 -1
  151. package/dist/esm/taser-app.d.ts +0 -18
  152. package/dist/esm/taser-app.js +0 -35
  153. package/dist/esm/taser-app.js.map +0 -1
  154. package/dist/esm/taser-router.d.ts +0 -42
  155. package/dist/esm/taser-router.js.map +0 -1
  156. package/src/taser-app.ts +0 -38
  157. package/src/taser-router.ts +0 -165
  158. /package/dist/cjs/{constants.d.cts → builder/constants.d.cts} +0 -0
  159. /package/dist/esm/{constants.d.ts → builder/constants.d.ts} +0 -0
  160. /package/src/{constants.ts → builder/constants.ts} +0 -0
@@ -1,9 +1,9 @@
1
1
  import { wrapHonoMiddleware } from "./wrap-hono.js";
2
2
  import { csrf as csrf$1 } from "hono/csrf";
3
3
  //#region src/middleware/csrf.ts
4
- var honoCsrfMiddleware = wrapHonoMiddleware(csrf$1);
4
+ var wrapped = wrapHonoMiddleware(csrf$1);
5
5
  function csrf(...args) {
6
- return honoCsrfMiddleware(...args);
6
+ return wrapped(...args);
7
7
  }
8
8
  //#endregion
9
9
  export { csrf };
@@ -1 +1 @@
1
- {"version":3,"file":"csrf.js","names":[],"sources":["../../../src/middleware/csrf.ts"],"sourcesContent":["import { csrf as honoCsrf } from \"hono/csrf\";\n\nimport { wrapHonoMiddleware } from \"./wrap-hono.js\";\n\nconst honoCsrfMiddleware = wrapHonoMiddleware(honoCsrf);\n\nexport function csrf(...args: Parameters<typeof honoCsrf>) {\n return honoCsrfMiddleware(...args);\n}\n\nexport type CsrfOptions = NonNullable<Parameters<typeof honoCsrf>[0]>;\n"],"mappings":";;;AAIA,IAAM,qBAAqB,mBAAmB,MAAQ;AAEtD,SAAgB,KAAK,GAAG,MAAmC;CACzD,OAAO,mBAAmB,GAAG,IAAI;AACnC"}
1
+ {"version":3,"file":"csrf.js","names":[],"sources":["../../../src/middleware/csrf.ts"],"sourcesContent":["import { csrf as honoCsrf } from \"hono/csrf\";\n\nimport { wrapHonoMiddleware } from \"./wrap-hono.js\";\n\nconst wrapped = wrapHonoMiddleware(honoCsrf);\n\nexport function csrf(...args: Parameters<typeof honoCsrf>) {\n return wrapped(...args);\n}\n\nexport type CsrfOptions = NonNullable<Parameters<typeof honoCsrf>[0]>;\n"],"mappings":";;;AAIA,IAAM,UAAU,mBAAmB,MAAQ;AAE3C,SAAgB,KAAK,GAAG,MAAmC;CACzD,OAAO,QAAQ,GAAG,IAAI;AACxB"}
@@ -1,9 +1,9 @@
1
1
  import { wrapHonoMiddleware } from "./wrap-hono.js";
2
2
  import { etag as etag$1 } from "hono/etag";
3
3
  //#region src/middleware/etag.ts
4
- var honoEtagMiddleware = wrapHonoMiddleware(etag$1);
4
+ var wrapped = wrapHonoMiddleware(etag$1);
5
5
  function etag(...args) {
6
- return honoEtagMiddleware(...args);
6
+ return wrapped(...args);
7
7
  }
8
8
  //#endregion
9
9
  export { etag };
@@ -1 +1 @@
1
- {"version":3,"file":"etag.js","names":[],"sources":["../../../src/middleware/etag.ts"],"sourcesContent":["import { etag as honoEtag } from \"hono/etag\";\n\nimport { wrapHonoMiddleware } from \"./wrap-hono.js\";\n\nconst honoEtagMiddleware = wrapHonoMiddleware(honoEtag);\n\nexport function etag(...args: Parameters<typeof honoEtag>) {\n return honoEtagMiddleware(...args);\n}\n\nexport type EtagOptions = NonNullable<Parameters<typeof honoEtag>[0]>;\n"],"mappings":";;;AAIA,IAAM,qBAAqB,mBAAmB,MAAQ;AAEtD,SAAgB,KAAK,GAAG,MAAmC;CACzD,OAAO,mBAAmB,GAAG,IAAI;AACnC"}
1
+ {"version":3,"file":"etag.js","names":[],"sources":["../../../src/middleware/etag.ts"],"sourcesContent":["import { etag as honoEtag } from \"hono/etag\";\n\nimport { wrapHonoMiddleware } from \"./wrap-hono.js\";\n\nconst wrapped = wrapHonoMiddleware(honoEtag);\n\nexport function etag(...args: Parameters<typeof honoEtag>) {\n return wrapped(...args);\n}\n\nexport type EtagOptions = NonNullable<Parameters<typeof honoEtag>[0]>;\n"],"mappings":";;;AAIA,IAAM,UAAU,mBAAmB,MAAQ;AAE3C,SAAgB,KAAK,GAAG,MAAmC;CACzD,OAAO,QAAQ,GAAG,IAAI;AACxB"}
@@ -1,5 +1,5 @@
1
1
  import { defineMiddleware } from "../define/middleware.js";
2
- import { createTaserCompatHandler } from "@taserjs/router-core";
2
+ import { extractJwtPayload } from "./wrap-hono.js";
3
3
  import { jwk as jwk$1 } from "hono/jwk";
4
4
  //#region src/middleware/jwk.ts
5
5
  function assertJwksScheme(jwksUri, allowInsecure) {
@@ -17,13 +17,7 @@ function jwk(options, init) {
17
17
  const jwksUri = options.jwks_uri;
18
18
  if (typeof jwksUri === "string") assertJwksScheme(jwksUri, options.allowInsecure ?? false);
19
19
  const { allowInsecure: _allowInsecure, ...honoOptions } = options;
20
- const honoMw = jwk$1(honoOptions, init?.headers !== void 0 ? { headers: init.headers } : void 0);
21
- return defineMiddleware({ handler: (ctx, next) => {
22
- return createTaserCompatHandler(honoMw)(ctx, async () => {
23
- const payload = ctx.var.jwtPayload;
24
- return next({ jwtPayload: payload });
25
- });
26
- } });
20
+ return defineMiddleware({ handler: extractJwtPayload(jwk$1(honoOptions, init?.headers !== void 0 ? { headers: init.headers } : void 0)) });
27
21
  }
28
22
  //#endregion
29
23
  export { jwk };
@@ -1 +1 @@
1
- {"version":3,"file":"jwk.js","names":[],"sources":["../../../src/middleware/jwk.ts"],"sourcesContent":["import { createTaserCompatHandler } from \"@taserjs/router-core\";\nimport type { MiddlewareHandler } from \"hono\";\nimport { jwk as honoJwk } from \"hono/jwk\";\n\nimport { defineMiddleware } from \"../define/middleware.js\";\nimport type { JwtMiddlewareUnit, JwtPayloadState } from \"./jwt.js\";\n\nexport type JwkOptions = Parameters<typeof honoJwk>[0];\n\nexport type JwkRequestInit = Pick<RequestInit, \"headers\">;\n\nexport type JwkMiddlewareOptions = JwkOptions & {\n /** Allow `http://` JWKS URLs (local dev). Default false — requires `https://`. */\n allowInsecure?: boolean;\n};\n\nfunction assertJwksScheme(jwksUri: string, allowInsecure: boolean): void {\n const scheme = new URL(jwksUri).protocol.replace(\":\", \"\");\n if (scheme === \"https\") {\n return;\n }\n if (scheme === \"http\" && allowInsecure) {\n return;\n }\n throw new Error(`JWKS URL must use https:// (or http:// with allowInsecure: true): \"${jwksUri}\"`);\n}\n\n/**\n * JWK auth middleware. Invalid or missing tokens return **401** (Hono).\n * Successfully decoded payload is placed in `ctx.state.jwtPayload`.\n * Static `jwks_uri` must use HTTPS unless `allowInsecure: true`.\n */\nexport function jwk<TPayload = Record<string, unknown>>(\n options: JwkMiddlewareOptions,\n init?: JwkRequestInit,\n): JwtMiddlewareUnit<TPayload> {\n const jwksUri = options.jwks_uri;\n if (typeof jwksUri === \"string\") {\n assertJwksScheme(jwksUri, options.allowInsecure ?? false);\n }\n\n const { allowInsecure: _allowInsecure, ...honoOptions } = options;\n const safeInit = init?.headers !== undefined ? { headers: init.headers } : undefined;\n const honoMw: MiddlewareHandler = honoJwk(honoOptions, safeInit);\n\n return defineMiddleware<JwtPayloadState<TPayload>>({\n handler: (ctx, next) => {\n return createTaserCompatHandler(honoMw)(ctx, async () => {\n const payload = (ctx as unknown as { var: { jwtPayload?: unknown } }).var.jwtPayload;\n return next({ jwtPayload: payload as TPayload });\n });\n },\n });\n}\n"],"mappings":";;;;AAgBA,SAAS,iBAAiB,SAAiB,eAA8B;CACvE,MAAM,SAAS,IAAI,IAAI,OAAO,CAAC,CAAC,SAAS,QAAQ,KAAK,EAAE;CACxD,IAAI,WAAW,SACb;CAEF,IAAI,WAAW,UAAU,eACvB;CAEF,MAAM,IAAI,MAAM,sEAAsE,QAAQ,EAAE;AAClG;;;;;;AAOA,SAAgB,IACd,SACA,MAC6B;CAC7B,MAAM,UAAU,QAAQ;CACxB,IAAI,OAAO,YAAY,UACrB,iBAAiB,SAAS,QAAQ,iBAAiB,KAAK;CAG1D,MAAM,EAAE,eAAe,gBAAgB,GAAG,gBAAgB;CAE1D,MAAM,SAA4B,MAAQ,aADzB,MAAM,YAAY,KAAA,IAAY,EAAE,SAAS,KAAK,QAAQ,IAAI,KAAA,CACZ;CAE/D,OAAO,iBAA4C,EACjD,UAAU,KAAK,SAAS;EACtB,OAAO,yBAAyB,MAAM,CAAC,CAAC,KAAK,YAAY;GACvD,MAAM,UAAW,IAAqD,IAAI;GAC1E,OAAO,KAAK,EAAE,YAAY,QAAoB,CAAC;EACjD,CAAC;CACH,EACF,CAAC;AACH"}
1
+ {"version":3,"file":"jwk.js","names":[],"sources":["../../../src/middleware/jwk.ts"],"sourcesContent":["import type { MiddlewareHandler } from \"hono\";\nimport { jwk as honoJwk } from \"hono/jwk\";\n\nimport { defineMiddleware } from \"../define/middleware.js\";\nimport type { JwtMiddlewareUnit, JwtPayloadState } from \"./jwt.js\";\nimport { extractJwtPayload } from \"./wrap-hono.js\";\n\nexport type JwkOptions = Parameters<typeof honoJwk>[0];\n\nexport type JwkRequestInit = Pick<RequestInit, \"headers\">;\n\nexport type JwkMiddlewareOptions = JwkOptions & {\n /** Allow `http://` JWKS URLs (local dev). Default false — requires `https://`. */\n allowInsecure?: boolean;\n};\n\nfunction assertJwksScheme(jwksUri: string, allowInsecure: boolean): void {\n const scheme = new URL(jwksUri).protocol.replace(\":\", \"\");\n if (scheme === \"https\") {\n return;\n }\n if (scheme === \"http\" && allowInsecure) {\n return;\n }\n throw new Error(`JWKS URL must use https:// (or http:// with allowInsecure: true): \"${jwksUri}\"`);\n}\n\n/**\n * JWK auth middleware. Invalid or missing tokens return **401** (Hono).\n * Successfully decoded payload is placed in `ctx.state.jwtPayload`.\n * Static `jwks_uri` must use HTTPS unless `allowInsecure: true`.\n */\nexport function jwk<TPayload = Record<string, unknown>>(\n options: JwkMiddlewareOptions,\n init?: JwkRequestInit,\n): JwtMiddlewareUnit<TPayload> {\n const jwksUri = options.jwks_uri;\n if (typeof jwksUri === \"string\") {\n assertJwksScheme(jwksUri, options.allowInsecure ?? false);\n }\n\n const { allowInsecure: _allowInsecure, ...honoOptions } = options;\n const safeInit = init?.headers !== undefined ? { headers: init.headers } : undefined;\n const honoMw: MiddlewareHandler = honoJwk(honoOptions, safeInit);\n\n return defineMiddleware<JwtPayloadState<TPayload>>({\n handler: extractJwtPayload<TPayload>(honoMw),\n });\n}\n"],"mappings":";;;;AAgBA,SAAS,iBAAiB,SAAiB,eAA8B;CACvE,MAAM,SAAS,IAAI,IAAI,OAAO,CAAC,CAAC,SAAS,QAAQ,KAAK,EAAE;CACxD,IAAI,WAAW,SACb;CAEF,IAAI,WAAW,UAAU,eACvB;CAEF,MAAM,IAAI,MAAM,sEAAsE,QAAQ,EAAE;AAClG;;;;;;AAOA,SAAgB,IACd,SACA,MAC6B;CAC7B,MAAM,UAAU,QAAQ;CACxB,IAAI,OAAO,YAAY,UACrB,iBAAiB,SAAS,QAAQ,iBAAiB,KAAK;CAG1D,MAAM,EAAE,eAAe,gBAAgB,GAAG,gBAAgB;CAI1D,OAAO,iBAA4C,EACjD,SAAS,kBAHuB,MAAQ,aADzB,MAAM,YAAY,KAAA,IAAY,EAAE,SAAS,KAAK,QAAQ,IAAI,KAAA,CAIpC,CAAM,EAC7C,CAAC;AACH"}
@@ -1,5 +1,5 @@
1
1
  import { defineMiddleware } from "../define/middleware.js";
2
- import { createTaserCompatHandler } from "@taserjs/router-core";
2
+ import { extractJwtPayload } from "./wrap-hono.js";
3
3
  import { jwt as jwt$1 } from "hono/jwt";
4
4
  //#region src/middleware/jwt.ts
5
5
  /**
@@ -7,13 +7,7 @@ import { jwt as jwt$1 } from "hono/jwt";
7
7
  * Successfully decoded payload is placed in `ctx.state.jwtPayload`.
8
8
  */
9
9
  function jwt(options) {
10
- const honoMw = jwt$1(options);
11
- return defineMiddleware({ handler: (ctx, next) => {
12
- return createTaserCompatHandler(honoMw)(ctx, async () => {
13
- const payload = ctx.var.jwtPayload;
14
- return next({ jwtPayload: payload });
15
- });
16
- } });
10
+ return defineMiddleware({ handler: extractJwtPayload(jwt$1(options)) });
17
11
  }
18
12
  //#endregion
19
13
  export { jwt };
@@ -1 +1 @@
1
- {"version":3,"file":"jwt.js","names":[],"sources":["../../../src/middleware/jwt.ts"],"sourcesContent":["import { createTaserCompatHandler } from \"@taserjs/router-core\";\nimport type { MiddlewareHandler } from \"hono\";\nimport { jwt as honoJwt } from \"hono/jwt\";\n\nimport { defineMiddleware } from \"../define/middleware.js\";\nimport type { MiddlewareReturnFromParts, MiddlewareUnit } from \"../types/units.js\";\n\nexport type JwtPayloadState<TPayload> = {\n jwtPayload: TPayload;\n};\n\nexport type JwtMiddlewareUnit<TPayload> = MiddlewareUnit<\n MiddlewareReturnFromParts<unknown, unknown, unknown, JwtPayloadState<TPayload>>\n>;\n\nexport type JwtOptions = Parameters<typeof honoJwt>[0];\n\n/**\n * JWT auth middleware. Invalid or missing tokens return **401** (Hono).\n * Successfully decoded payload is placed in `ctx.state.jwtPayload`.\n */\nexport function jwt<TPayload = Record<string, unknown>>(\n options: JwtOptions,\n): JwtMiddlewareUnit<TPayload> {\n const honoMw: MiddlewareHandler = honoJwt(options);\n return defineMiddleware<JwtPayloadState<TPayload>>({\n handler: (ctx, next) => {\n return createTaserCompatHandler(honoMw)(ctx, async () => {\n const payload = (ctx as unknown as { var: { jwtPayload?: unknown } }).var.jwtPayload;\n return next({ jwtPayload: payload as TPayload });\n });\n },\n });\n}\n"],"mappings":";;;;;;;;AAqBA,SAAgB,IACd,SAC6B;CAC7B,MAAM,SAA4B,MAAQ,OAAO;CACjD,OAAO,iBAA4C,EACjD,UAAU,KAAK,SAAS;EACtB,OAAO,yBAAyB,MAAM,CAAC,CAAC,KAAK,YAAY;GACvD,MAAM,UAAW,IAAqD,IAAI;GAC1E,OAAO,KAAK,EAAE,YAAY,QAAoB,CAAC;EACjD,CAAC;CACH,EACF,CAAC;AACH"}
1
+ {"version":3,"file":"jwt.js","names":[],"sources":["../../../src/middleware/jwt.ts"],"sourcesContent":["import type { MiddlewareHandler } from \"hono\";\nimport { jwt as honoJwt } from \"hono/jwt\";\n\nimport { defineMiddleware } from \"../define/middleware.js\";\nimport type { MiddlewareReturnFromParts, MiddlewareUnit } from \"../types/units.js\";\nimport { extractJwtPayload } from \"./wrap-hono.js\";\n\nexport type JwtPayloadState<TPayload> = {\n jwtPayload: TPayload;\n};\n\nexport type JwtMiddlewareUnit<TPayload> = MiddlewareUnit<\n MiddlewareReturnFromParts<unknown, unknown, unknown, JwtPayloadState<TPayload>>\n>;\n\nexport type JwtOptions = Parameters<typeof honoJwt>[0];\n\n/**\n * JWT auth middleware. Invalid or missing tokens return **401** (Hono).\n * Successfully decoded payload is placed in `ctx.state.jwtPayload`.\n */\nexport function jwt<TPayload = Record<string, unknown>>(\n options: JwtOptions,\n): JwtMiddlewareUnit<TPayload> {\n const honoMw: MiddlewareHandler = honoJwt(options);\n return defineMiddleware<JwtPayloadState<TPayload>>({\n handler: extractJwtPayload<TPayload>(honoMw),\n });\n}\n"],"mappings":";;;;;;;;AAqBA,SAAgB,IACd,SAC6B;CAE7B,OAAO,iBAA4C,EACjD,SAAS,kBAFuB,MAAQ,OAEH,CAAM,EAC7C,CAAC;AACH"}
@@ -1,9 +1,9 @@
1
1
  import { wrapHonoMiddleware } from "./wrap-hono.js";
2
2
  import { secureHeaders as secureHeaders$1 } from "hono/secure-headers";
3
3
  //#region src/middleware/secure-headers.ts
4
- var honoSecureHeadersMiddleware = wrapHonoMiddleware(secureHeaders$1);
4
+ var wrapped = wrapHonoMiddleware(secureHeaders$1);
5
5
  function secureHeaders(...args) {
6
- return honoSecureHeadersMiddleware(...args);
6
+ return wrapped(...args);
7
7
  }
8
8
  //#endregion
9
9
  export { secureHeaders };
@@ -1 +1 @@
1
- {"version":3,"file":"secure-headers.js","names":[],"sources":["../../../src/middleware/secure-headers.ts"],"sourcesContent":["import { secureHeaders as honoSecureHeaders } from \"hono/secure-headers\";\n\nimport { wrapHonoMiddleware } from \"./wrap-hono.js\";\n\nconst honoSecureHeadersMiddleware = wrapHonoMiddleware(honoSecureHeaders);\n\nexport function secureHeaders(...args: Parameters<typeof honoSecureHeaders>) {\n return honoSecureHeadersMiddleware(...args);\n}\n\nexport type SecureHeadersOptions = NonNullable<Parameters<typeof honoSecureHeaders>[0]>;\n"],"mappings":";;;AAIA,IAAM,8BAA8B,mBAAmB,eAAiB;AAExE,SAAgB,cAAc,GAAG,MAA4C;CAC3E,OAAO,4BAA4B,GAAG,IAAI;AAC5C"}
1
+ {"version":3,"file":"secure-headers.js","names":[],"sources":["../../../src/middleware/secure-headers.ts"],"sourcesContent":["import { secureHeaders as honoSecureHeaders } from \"hono/secure-headers\";\n\nimport { wrapHonoMiddleware } from \"./wrap-hono.js\";\n\nconst wrapped = wrapHonoMiddleware(honoSecureHeaders);\n\nexport function secureHeaders(...args: Parameters<typeof honoSecureHeaders>) {\n return wrapped(...args);\n}\n\nexport type SecureHeadersOptions = NonNullable<Parameters<typeof honoSecureHeaders>[0]>;\n"],"mappings":";;;AAIA,IAAM,UAAU,mBAAmB,eAAiB;AAEpD,SAAgB,cAAc,GAAG,MAA4C;CAC3E,OAAO,QAAQ,GAAG,IAAI;AACxB"}
@@ -1,9 +1,9 @@
1
1
  import { wrapHonoMiddleware } from "./wrap-hono.js";
2
2
  import { timing as timing$1 } from "hono/timing";
3
3
  //#region src/middleware/timing.ts
4
- var honoTimingMiddleware = wrapHonoMiddleware(timing$1);
4
+ var wrapped = wrapHonoMiddleware(timing$1);
5
5
  function timing(...args) {
6
- return honoTimingMiddleware(...args);
6
+ return wrapped(...args);
7
7
  }
8
8
  //#endregion
9
9
  export { timing };
@@ -1 +1 @@
1
- {"version":3,"file":"timing.js","names":[],"sources":["../../../src/middleware/timing.ts"],"sourcesContent":["import { timing as honoTiming } from \"hono/timing\";\n\nimport { wrapHonoMiddleware } from \"./wrap-hono.js\";\n\nconst honoTimingMiddleware = wrapHonoMiddleware(honoTiming);\n\nexport function timing(...args: Parameters<typeof honoTiming>) {\n return honoTimingMiddleware(...args);\n}\n\nexport type TimingOptions = NonNullable<Parameters<typeof honoTiming>[0]>;\n"],"mappings":";;;AAIA,IAAM,uBAAuB,mBAAmB,QAAU;AAE1D,SAAgB,OAAO,GAAG,MAAqC;CAC7D,OAAO,qBAAqB,GAAG,IAAI;AACrC"}
1
+ {"version":3,"file":"timing.js","names":[],"sources":["../../../src/middleware/timing.ts"],"sourcesContent":["import { timing as honoTiming } from \"hono/timing\";\n\nimport { wrapHonoMiddleware } from \"./wrap-hono.js\";\n\nconst wrapped = wrapHonoMiddleware(honoTiming);\n\nexport function timing(...args: Parameters<typeof honoTiming>) {\n return wrapped(...args);\n}\n\nexport type TimingOptions = NonNullable<Parameters<typeof honoTiming>[0]>;\n"],"mappings":";;;AAIA,IAAM,UAAU,mBAAmB,QAAU;AAE7C,SAAgB,OAAO,GAAG,MAAqC;CAC7D,OAAO,QAAQ,GAAG,IAAI;AACxB"}
@@ -1,3 +1,7 @@
1
1
  import { MiddlewareHandler } from 'hono';
2
2
  import { MiddlewareReturnFromParts, MiddlewareUnit } from '../types/units.js';
3
3
  export declare function wrapHonoMiddleware<F extends (...args: never[]) => MiddlewareHandler>(honoFactory: F): (...args: Parameters<F>) => MiddlewareUnit<MiddlewareReturnFromParts<unknown, unknown, unknown, {}>>;
4
+ /** Extracts the jwtPayload from Hono's variable bag and forwards it into Taser's state via next(). */
5
+ export declare function extractJwtPayload<TPayload>(honoMw: MiddlewareHandler): (ctx: unknown, next: (state: {
6
+ jwtPayload: TPayload;
7
+ }) => unknown) => unknown;
@@ -1,9 +1,18 @@
1
1
  import { defineMiddleware } from "../define/middleware.js";
2
+ import { createTaserCompatHandler } from "@taserjs/router-core";
2
3
  //#region src/middleware/wrap-hono.ts
3
4
  function wrapHonoMiddleware(honoFactory) {
4
5
  return (...args) => defineMiddleware(honoFactory(...args));
5
6
  }
7
+ /** Extracts the jwtPayload from Hono's variable bag and forwards it into Taser's state via next(). */
8
+ function extractJwtPayload(honoMw) {
9
+ const taserHandler = createTaserCompatHandler(honoMw);
10
+ return (ctx, next) => taserHandler(ctx, async () => {
11
+ const payload = ctx.var.jwtPayload;
12
+ return next({ jwtPayload: payload });
13
+ });
14
+ }
6
15
  //#endregion
7
- export { wrapHonoMiddleware };
16
+ export { extractJwtPayload, wrapHonoMiddleware };
8
17
 
9
18
  //# sourceMappingURL=wrap-hono.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"wrap-hono.js","names":[],"sources":["../../../src/middleware/wrap-hono.ts"],"sourcesContent":["import type { MiddlewareHandler } from \"hono\";\n\nimport { defineMiddleware } from \"../define/middleware.js\";\nimport type { MiddlewareReturnFromParts, MiddlewareUnit } from \"../types/units.js\";\n\nexport function wrapHonoMiddleware<F extends (...args: never[]) => MiddlewareHandler>(\n honoFactory: F,\n): (\n ...args: Parameters<F>\n) => MiddlewareUnit<MiddlewareReturnFromParts<unknown, unknown, unknown, {}>> {\n return (...args) => defineMiddleware(honoFactory(...args));\n}\n"],"mappings":";;AAKA,SAAgB,mBACd,aAG4E;CAC5E,QAAQ,GAAG,SAAS,iBAAiB,YAAY,GAAG,IAAI,CAAC;AAC3D"}
1
+ {"version":3,"file":"wrap-hono.js","names":[],"sources":["../../../src/middleware/wrap-hono.ts"],"sourcesContent":["import { createTaserCompatHandler } from \"@taserjs/router-core\";\nimport type { MiddlewareHandler } from \"hono\";\n\nimport { defineMiddleware } from \"../define/middleware.js\";\nimport type { MiddlewareReturnFromParts, MiddlewareUnit } from \"../types/units.js\";\n\nexport function wrapHonoMiddleware<F extends (...args: never[]) => MiddlewareHandler>(\n honoFactory: F,\n): (\n ...args: Parameters<F>\n) => MiddlewareUnit<MiddlewareReturnFromParts<unknown, unknown, unknown, {}>> {\n return (...args) => defineMiddleware(honoFactory(...args));\n}\n\n/** Extracts the jwtPayload from Hono's variable bag and forwards it into Taser's state via next(). */\nexport function extractJwtPayload<TPayload>(\n honoMw: MiddlewareHandler,\n): (ctx: unknown, next: (state: { jwtPayload: TPayload }) => unknown) => unknown {\n const taserHandler = createTaserCompatHandler(honoMw);\n return (ctx, next) =>\n taserHandler(ctx, async () => {\n const payload = (ctx as unknown as { var: { jwtPayload?: unknown } }).var.jwtPayload;\n return next({ jwtPayload: payload as TPayload });\n });\n}\n"],"mappings":";;;AAMA,SAAgB,mBACd,aAG4E;CAC5E,QAAQ,GAAG,SAAS,iBAAiB,YAAY,GAAG,IAAI,CAAC;AAC3D;;AAGA,SAAgB,kBACd,QAC+E;CAC/E,MAAM,eAAe,yBAAyB,MAAM;CACpD,QAAQ,KAAK,SACX,aAAa,KAAK,YAAY;EAC5B,MAAM,UAAW,IAAqD,IAAI;EAC1E,OAAO,KAAK,EAAE,YAAY,QAAoB,CAAC;CACjD,CAAC;AACL"}
@@ -1,5 +1,6 @@
1
+ import { RouteManifestShape } from '@taserjs/router-core';
1
2
  import { ResponseValidationFailureHandler } from '@taserjs/router-utils';
2
- import { TaserApp } from '../taser-app.js';
3
+ import { TaserApp } from '../builder/app.js';
3
4
  import { ReturnsMap } from './returns.js';
4
5
  import { Schema } from './schema.js';
5
6
  export type CreateTaserAppOptions = {
@@ -21,19 +22,18 @@ export type CreateTaserAppOptions = {
21
22
  expires?: Date;
22
23
  };
23
24
  };
24
- export type CreateContextArgs = {
25
- native?: import('./units.js').NativeContext;
26
- };
27
25
  export type ContextDefinition<TBoot extends Record<string, unknown> = Record<string, never>, TReq extends Record<string, unknown> = Record<string, never>> = {
28
26
  boot?: () => TBoot | Promise<TBoot>;
29
- request?: (args: CreateContextArgs) => TReq | Promise<TReq>;
27
+ request?: (req: Request) => TReq | Promise<TReq>;
30
28
  };
31
29
  export type InferAppContext<T extends ContextDefinition<Record<string, unknown>, Record<string, unknown>>> = T extends ContextDefinition<infer TBoot, infer TReq> ? TBoot & TReq : Record<string, never>;
32
30
  export type OnErrorOptions<TResponses extends ReturnsMap = ReturnsMap> = {
33
31
  responses?: TResponses;
34
32
  handle: (error: unknown, ctx?: unknown) => Response | Promise<Response>;
35
33
  };
36
- export type InferAppManifest<TApp> = TApp extends TaserApp<infer TManifest> ? TManifest : never;
34
+ export type InferAppManifest<TApp> = TApp extends TaserApp<infer TManifest> ? TManifest : TApp extends {
35
+ manifest: infer TManifest;
36
+ } ? TManifest : TApp extends RouteManifestShape ? TApp : never;
37
37
  export type TaserHandler<TFrameworkApp> = {
38
38
  /**
39
39
  * Mount the Taser handler on a framework app.
@@ -44,4 +44,4 @@ export type TaserHandler<TFrameworkApp> = {
44
44
  };
45
45
  export type { RouteManifestShape } from '@taserjs/router-core';
46
46
  export type { Schema };
47
- export type { TaserApp, TaserNativeBound } from '../taser-app.js';
47
+ export type { TaserApp } from '../builder/app.js';
@@ -1,15 +1,15 @@
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 } from './type-utils.js';
3
+ import { MergeMiddlewareField, MergeMiddlewareInputField, MergePart, RequestShape, RuntimeContextFields, Simplify, UnionToIntersection } from './type-utils.js';
4
4
  import { ReturnsMap, ValidHandlerReply } from './returns.js';
5
5
  import { Schema } from './schema.js';
6
- import { AppContext, ExtractState, HandlerContext, HandlerUnit, InlineMiddlewareOptions, Method, MiddlewareDefinition, MiddlewareReturnFromParts, MiddlewareUnit, NativeContext, ValidatorParts } from './units.js';
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
10
  export type { MergeMiddlewareField, MergeMiddlewareInputField, MergePart, RequestShape, Simplify, UnwrapPart, } from './type-utils.js';
11
- export type { EmptyReturns, EnforceHandlerReply, HandlerReply, HasReturns, MergeReturns, ReplyResultFor, ReturnsMap, StatusCode, ValidHandlerReply, } from './returns.js';
12
- export type { AppContext, ExtractState, HandlerContext, HandlerUnit, HttpMethod, InlineMiddlewareOptions, IsUnknown, Method, MiddlewareDefinition, MiddlewareNext, MiddlewareReturnFromParts, MiddlewareUnit, NativeContext, NextFn, NextResult, StandaloneMiddlewareContext, StateBrand, ValidatorParts, } from './units.js';
11
+ export type { EmptyReturns, EnforceHandlerReply, HandlerReply, HasReturns, MergeReturns, ReplyFor, ReturnsMap, StatusCode, ValidHandlerReply, } from './returns.js';
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 {
14
14
  RoutePath: infer P;
15
15
  } ? P : never;
@@ -29,6 +29,7 @@ type ParseParam<Segment extends string> = Segment extends "*" ? {
29
29
  } : {};
30
30
  type ParseParamsFromSegments<S extends string> = S extends `${infer Segment}/${infer Rest}` ? ParseParam<Segment> & ParseParamsFromSegments<Rest> : ParseParam<S>;
31
31
  export type PathParams<Path extends string> = Path extends `/${infer Rest}` ? ParseParamsFromSegments<Rest> : {};
32
+ export type ResolveParams<TPathParams, TSchemaParams> = TSchemaParams extends Record<string, unknown> ? [keyof TSchemaParams] extends [never] ? TPathParams : Simplify<Omit<TPathParams, keyof TSchemaParams> & TSchemaParams> : TPathParams;
32
33
  type LayoutParent<Layout extends LayoutId> = LayoutTree[Layout] extends {
33
34
  parent: infer Parent extends LayoutId | null;
34
35
  } ? Parent : null;
@@ -36,6 +37,9 @@ type ResolveLayoutMiddlewares<Layout extends LayoutId | null> = Layout extends n
36
37
  ...ResolveLayoutMiddlewares<LayoutParent<Layout>>,
37
38
  ...LayoutTree[Layout]["middlewares"]
38
39
  ] : readonly [];
40
+ export type ResolveLayoutIdChain<L extends LayoutId | null> = L extends null ? readonly [] : L extends LayoutId ? readonly [...ResolveLayoutIdChain<LayoutParent<L>>, L] : readonly [];
41
+ export type ResolveLayoutMiddlewaresState<Layout extends LayoutId | null> = Layout extends LayoutId ? MergeMiddlewareField<ResolveLayoutMiddlewares<Layout>, "state"> : {};
42
+ export type ResolveLayoutsState<Layouts extends LayoutId | readonly LayoutId[]> = Layouts extends LayoutId ? ResolveLayoutMiddlewaresState<Layouts> : Layouts extends readonly LayoutId[] ? UnionToIntersection<Layouts[number] extends infer L extends LayoutId ? ResolveLayoutMiddlewaresState<L> : never> : {};
39
43
  /** Fold layout middleware Acc from a route's layoutChain (shallow → deep). */
40
44
  type ResolveLayoutChainMiddlewares<Chain extends readonly LayoutId[]> = Chain extends readonly [
41
45
  infer Head extends LayoutId,
@@ -55,10 +59,10 @@ type RouteLayoutChain<Path extends RoutePath, TMethod extends Method> = RouteEnt
55
59
  } ? Chain : RouteParent<Path, TMethod> extends LayoutId ? readonly [RouteParent<Path, TMethod>] : readonly [];
56
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>;
57
61
  type RouteChainField<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], Field extends "query" | "params" | "body" | "state"> = RouteResolvedField<Path, TMethod, Acc, Field>;
58
- type UnitRuntimeContext = Omit<RuntimeContextFields<NativeContext>, "var">;
62
+ type UnitRuntimeContext = Omit<RuntimeContextFields, "var">;
59
63
  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 & {
60
64
  query: Simplify<MergePart<TQuery, RouteChainField<Path, TMethod, Acc, "query">>>;
61
- params: Simplify<PathParams<Path> & MergePart<TParams, RouteChainField<Path, TMethod, Acc, "params">>>;
65
+ params: Simplify<ResolveParams<PathParams<Path>, MergePart<TParams, RouteChainField<Path, TMethod, Acc, "params">>>>;
62
66
  body: Simplify<MergePart<TBody, RouteChainField<Path, TMethod, Acc, "body">>>;
63
67
  state: Simplify<RouteChainField<Path, TMethod, Acc, "state">>;
64
68
  headers: TaserHeaders;
@@ -74,9 +78,9 @@ export type RouteHandleContext<Path extends RoutePath, TMethod extends Method, A
74
78
  query: Simplify<MergePart<Validators extends {
75
79
  query?: infer Q;
76
80
  } ? Q : unknown, RouteResolvedField<Path, TMethod, Acc, "query">>>;
77
- params: Simplify<PathParams<Path> & MergePart<Validators extends {
81
+ params: Simplify<ResolveParams<PathParams<Path>, MergePart<Validators extends {
78
82
  params?: infer P;
79
- } ? P : unknown, RouteResolvedField<Path, TMethod, Acc, "params">>>;
83
+ } ? P : unknown, RouteResolvedField<Path, TMethod, Acc, "params">>>>;
80
84
  body: Simplify<MergePart<Validators extends {
81
85
  body?: infer B;
82
86
  } ? B : unknown, RouteResolvedField<Path, TMethod, Acc, "body">>>;
@@ -93,9 +97,9 @@ export type RouteHandleContextWithoutBody<Path extends RoutePath, TMethod extend
93
97
  query: Simplify<MergePart<Validators extends {
94
98
  query?: infer Q;
95
99
  } ? Q : unknown, RouteResolvedField<Path, TMethod, Acc, "query">>>;
96
- params: Simplify<PathParams<Path> & MergePart<Validators extends {
100
+ params: Simplify<ResolveParams<PathParams<Path>, MergePart<Validators extends {
97
101
  params?: infer P;
98
- } ? P : unknown, RouteResolvedField<Path, TMethod, Acc, "params">>>;
102
+ } ? P : unknown, RouteResolvedField<Path, TMethod, Acc, "params">>>>;
99
103
  body: never;
100
104
  state: Simplify<RouteResolvedField<Path, TMethod, Acc, "state">>;
101
105
  headers: TaserHeaders;
@@ -104,6 +108,10 @@ export type RouteHandleContextWithoutBody<Path extends RoutePath, TMethod extend
104
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>;
105
109
  type IsNever<T> = [T] extends [never] ? true : false;
106
110
  type IsEmptyObject<T> = [keyof T] extends [never] ? true : false;
111
+ export type IsLayoutAllowed<TRequiredLayouts, TChain extends readonly LayoutId[]> = [
112
+ TRequiredLayouts
113
+ ] extends [never] ? true : [unknown] extends [TRequiredLayouts] ? true : [null] extends [TRequiredLayouts] ? true : [undefined] extends [TRequiredLayouts] ? true : TRequiredLayouts extends LayoutId ? TRequiredLayouts extends TChain[number] ? true : false : TRequiredLayouts extends readonly LayoutId[] ? [TRequiredLayouts[number] & TChain[number]] extends [never] ? false : true : true;
114
+ export type IsStateSatisfied<TActualState, TRequiredState> = [TRequiredState] extends [never] ? true : [unknown] extends [TRequiredState] ? true : [null] extends [TRequiredState] ? true : [undefined] extends [TRequiredState] ? true : [IsEmptyObject<TRequiredState>] extends [true] ? true : [TActualState] extends [TRequiredState] ? true : false;
107
115
  type InputFacet<T, K extends string> = IsNever<T> extends true ? {} : IsEmptyObject<T> extends true ? {} : {
108
116
  [Key in K]: T;
109
117
  };
@@ -112,11 +120,11 @@ type RouteQueryInput<Path extends RoutePath, TMethod extends Method, Acc extends
112
120
  } ? QI : unknown, Validators extends {
113
121
  query?: infer Q;
114
122
  } ? Q : unknown>, RouteResolvedInputField<Path, TMethod, Acc, "query">>>;
115
- type RouteParamsInput<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], Validators extends ValidatorParts> = Simplify<PathParams<Path> & MergePart<RequestShape<Validators extends {
123
+ type RouteParamsInput<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], Validators extends ValidatorParts> = Simplify<ResolveParams<PathParams<Path>, MergePart<RequestShape<Validators extends {
116
124
  paramsIn?: infer PI;
117
125
  } ? PI : unknown, Validators extends {
118
126
  params?: infer P;
119
- } ? P : unknown>, RouteResolvedInputField<Path, TMethod, Acc, "params">>>;
127
+ } ? P : unknown>, RouteResolvedInputField<Path, TMethod, Acc, "params">>>>;
120
128
  type RouteBodyInput<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], Validators extends ValidatorParts> = Simplify<MergePart<RequestShape<Validators extends {
121
129
  bodyIn?: infer BI;
122
130
  } ? BI : unknown, Validators extends {
@@ -124,7 +132,7 @@ type RouteBodyInput<Path extends RoutePath, TMethod extends Method, Acc extends
124
132
  } ? B : unknown>, RouteResolvedInputField<Path, TMethod, Acc, "body">>>;
125
133
  export type RouteHandleInputWithoutBody<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], Validators extends ValidatorParts = {}> = Simplify<InputFacet<RouteQueryInput<Path, TMethod, Acc, Validators>, "query"> & InputFacet<RouteParamsInput<Path, TMethod, Acc, Validators>, "params">>;
126
134
  export type RouteHandleInput<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], Validators extends ValidatorParts = {}> = Simplify<RouteHandleInputWithoutBody<Path, TMethod, Acc, Validators> & InputFacet<RouteBodyInput<Path, TMethod, Acc, Validators>, "body">>;
127
- export type InferRouteInput<Path extends RoutePath, TMethod extends Method> = RouteEntry<Path, TMethod> extends {
135
+ export type InferRouteInputFromPath<Path extends RoutePath, TMethod extends Method> = RouteEntry<Path, TMethod> extends {
128
136
  route: infer Route;
129
137
  } ? Route extends {
130
138
  $Infer: {
@@ -146,7 +154,18 @@ export type MiddlewareBuilder<Layout extends LayoutId, Acc extends readonly unkn
146
154
  readonly $Infer: {
147
155
  Context: MiddlewareChainContext<Layout, Acc, unknown, unknown, unknown, TAppContext>;
148
156
  };
149
- use<TAcc, TReturns extends ReturnsMap = {}>(unit: MiddlewareUnit<TAcc, TReturns>): MiddlewareBuilder<Layout, readonly [...Acc, TAcc], TAppContext>;
157
+ use<TAcc, TReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(unit: MiddlewareUnit<TAcc, TReturns, TRequiredLayouts, TRequiredState>, ..._assert: [
158
+ IsLayoutAllowed<TRequiredLayouts, ResolveLayoutIdChain<Layout>>,
159
+ IsStateSatisfied<MiddlewareChainField<Layout, Acc, "state">, TRequiredState>
160
+ ] extends [true, true] ? [] : [
161
+ {
162
+ error: "Middleware cannot be attached to this layout";
163
+ requiredLayouts: TRequiredLayouts;
164
+ layoutChain: ResolveLayoutIdChain<Layout>;
165
+ requiredState: TRequiredState;
166
+ actualState: MiddlewareChainField<Layout, Acc, "state">;
167
+ }
168
+ ]): MiddlewareBuilder<Layout, readonly [...Acc, TAcc], TAppContext>;
150
169
  use<TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(options: InlineMiddlewareOptions<MiddlewareChainContext<Layout, Acc, TQuery, TParams, TBody, TAppContext>, TQuery, TParams, TBody, TReturns, TQueryIn, TParamsIn, TBodyIn, R>): MiddlewareBuilder<Layout, readonly [
151
170
  ...Acc,
152
171
  MiddlewareReturnFromParts<TQuery, TParams, TBody, ExtractState<R>, TQueryIn, TParamsIn, TBodyIn>
@@ -162,7 +181,7 @@ export type RouteExport<Path extends RoutePath, TMethod extends Method, Acc exte
162
181
  handler: (ctx: unknown) => Awaitable<Response>;
163
182
  readonly $Infer: {
164
183
  Context: TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS" ? RouteHandleContextWithoutBody<Path, TMethod, Acc, {}> : RouteHandleContext<Path, TMethod, Acc, {}>;
165
- /** Concrete handler reply (`ReplyOf` union) for client inference. */
184
+ Input: TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS" ? RouteHandleInputWithoutBody<Path, TMethod, Acc, {}> : RouteHandleInput<Path, TMethod, Acc, {}>;
166
185
  Output: TOutput;
167
186
  };
168
187
  query?: Schema<unknown>;
@@ -184,9 +203,22 @@ export type RouteBuilder<Path extends RoutePath, TMethod extends Method, Acc ext
184
203
  readonly method: TMethod;
185
204
  readonly $Infer: {
186
205
  Context: TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS" ? RouteHandleContextWithoutBody<Path, TMethod, Acc, Validators, TAppContext> : RouteHandleContext<Path, TMethod, Acc, Validators, TAppContext>;
206
+ Input: TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS" ? RouteHandleInputWithoutBody<Path, TMethod, Acc, Validators> : RouteHandleInput<Path, TMethod, Acc, Validators>;
207
+ Output: TReturns;
187
208
  };
188
209
  returns<const M extends ReturnsMap>(map: M): RouteBuilder<Path, TMethod, Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>;
189
- use<TAcc, UReturns extends ReturnsMap = {}>(unit: MiddlewareUnit<TAcc, UReturns>): RouteBuilder<Path, TMethod, readonly [...Acc, TAcc], Validators, Omit<TReturns, keyof UReturns> & UReturns, TAppContext>;
210
+ use<TAcc, UReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(unit: MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequiredState>, ..._assert: [
211
+ IsLayoutAllowed<TRequiredLayouts, RouteLayoutChain<Path, TMethod>>,
212
+ IsStateSatisfied<RouteResolvedField<Path, TMethod, Acc, "state">, TRequiredState>
213
+ ] extends [true, true] ? [] : [
214
+ {
215
+ error: "Middleware cannot be attached to this route";
216
+ requiredLayouts: TRequiredLayouts;
217
+ routeLayoutChain: RouteLayoutChain<Path, TMethod>;
218
+ requiredState: TRequiredState;
219
+ actualState: RouteResolvedField<Path, TMethod, Acc, "state">;
220
+ }
221
+ ]): RouteBuilder<Path, TMethod, readonly [...Acc, TAcc], Validators, Omit<TReturns, keyof UReturns> & UReturns, TAppContext>;
190
222
  use<TQuery = unknown, TParams = unknown, TBody = unknown, UReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(options: InlineMiddlewareOptions<RouteChainContext<Path, TMethod, Acc, TQuery, TParams, TBody, TAppContext>, TQuery, TParams, TBody, UReturns, TQueryIn, TParamsIn, TBodyIn, R>): RouteBuilder<Path, TMethod, readonly [
191
223
  ...Acc,
192
224
  MiddlewareReturnFromParts<TQuery, TParams, TBody, ExtractState<R>, TQueryIn, TParamsIn, TBodyIn>
@@ -201,7 +233,15 @@ export type RouteBuilder<Path extends RoutePath, TMethod extends Method, Acc ext
201
233
  };
202
234
  export type HandlerBuilder<Acc extends readonly unknown[] = readonly [], Validators extends ValidatorParts = {}, TReturns extends ReturnsMap = {}, TAppContext extends Record<string, unknown> = AppContext> = {
203
235
  returns<const M extends ReturnsMap>(map: M): HandlerBuilder<Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>;
204
- use<TAcc, UReturns extends ReturnsMap = {}>(unit: MiddlewareUnit<TAcc, UReturns>): HandlerBuilder<readonly [...Acc, TAcc], Validators, Omit<TReturns, keyof UReturns> & UReturns, TAppContext>;
236
+ use<TAcc, UReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(unit: MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequiredState>, ..._assert: [IsStateSatisfied<MergeMiddlewareField<Acc, "state">, TRequiredState>] extends [
237
+ true
238
+ ] ? [] : [
239
+ {
240
+ error: "Middleware cannot be attached to this handler";
241
+ requiredState: TRequiredState;
242
+ actualState: MergeMiddlewareField<Acc, "state">;
243
+ }
244
+ ]): HandlerBuilder<readonly [...Acc, TAcc], Validators, Omit<TReturns, keyof UReturns> & UReturns, TAppContext>;
205
245
  use<TQuery = unknown, TParams = unknown, TBody = unknown, UReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(options: InlineMiddlewareOptions<HandlerContext<Acc, {
206
246
  query: TQuery;
207
247
  params: TParams;
@@ -217,3 +257,19 @@ export type HandlerBuilder<Acc extends readonly unknown[] = readonly [], Validat
217
257
  }
218
258
  ]): HandlerUnit<Acc, Validators, TReturns, R>;
219
259
  };
260
+ export type RouteDefinition<Path extends RoutePath = RoutePath, TMethod extends Method = Method, Acc extends readonly unknown[] = readonly unknown[], Validators extends ValidatorParts = ValidatorParts, TReturns extends ReturnsMap = ReturnsMap, TOutput = Response, TAppContext extends Record<string, unknown> = AppContext> = RouteHandleResult<Path, TMethod, Acc, Validators, TReturns, TOutput, TAppContext>;
261
+ export type InferRouteContext<R> = R extends {
262
+ $Infer: {
263
+ Context: infer C;
264
+ };
265
+ } ? C : never;
266
+ export type InferRouteInput<R> = R extends {
267
+ $Infer: {
268
+ Input: infer I;
269
+ };
270
+ } ? I : never;
271
+ export type InferRouteOutput<R> = R extends {
272
+ $Infer: {
273
+ Output: infer O;
274
+ };
275
+ } ? O : never;
@@ -13,7 +13,7 @@ export type ReturnsMap = {
13
13
  /** Later map wins on overlapping status keys. */
14
14
  export type MergeReturns<A extends ReturnsMap, B extends ReturnsMap> = Omit<A, keyof B> & B;
15
15
  /** Typed reply union for statuses declared in a returns map. */
16
- export type ReplyResultFor<M extends ReturnsMap> = {
16
+ export type ReplyFor<M extends ReturnsMap> = {
17
17
  [S in keyof M]-?: S extends StatusCode ? M[S] extends Schema<unknown> ? ReplyOf<S, Simplify<InferOutput<M[S]>>> : never : never;
18
18
  }[keyof M];
19
19
  export type EmptyReturns = {};
@@ -34,4 +34,4 @@ export type EnforceHandlerReply<R, M extends ReturnsMap> = [R] extends [ValidHan
34
34
  * Expected `.handler` return type for a returns map.
35
35
  * Prefer constraining handler generics with {@link EnforceHandlerReply}.
36
36
  */
37
- export type HandlerReply<M extends ReturnsMap> = HasReturns<M> extends true ? ReplyResultFor<M> | Response : Response;
37
+ export type HandlerReply<M extends ReturnsMap> = HasReturns<M> extends true ? ReplyFor<M> | Response : Response;
@@ -37,13 +37,12 @@ export type MiddlewareInputField<Middleware, Field extends MiddlewareInputFieldN
37
37
  } ? V : {};
38
38
  export type MergeMiddlewareField<Middlewares extends readonly unknown[], Field extends MiddlewareFieldName> = [Middlewares] extends [readonly []] ? {} : UnionToIntersection<MiddlewareField<Middlewares[number], Field>>;
39
39
  export type MergeMiddlewareInputField<Middlewares extends readonly unknown[], Field extends MiddlewareInputFieldName> = [Middlewares] extends [readonly []] ? {} : UnionToIntersection<MiddlewareInputField<Middlewares[number], Field>>;
40
- export type RuntimeContextFields<TNative = unknown> = {
40
+ export type RuntimeContextFields = {
41
41
  request: Request;
42
42
  method: Method;
43
43
  url: URL;
44
44
  headers: import('@taserjs/router-core').TaserHeaders;
45
45
  cookies: import('@taserjs/router-core').TaserCookieJar;
46
46
  var: Record<string, unknown>;
47
- native?: TNative;
48
47
  };
49
48
  export {};
@@ -1,6 +1,4 @@
1
1
  import { Awaitable, TaserCookieJar, TaserHeaders } from '@taserjs/router-core';
2
- import { ReplyResult } from '@taserjs/router-utils';
3
- import { RouterRegister } from '../register.js';
4
2
  import { MergeMiddlewareField, MergePart, RequestShape, RuntimeContextFields, Simplify, UnwrapPart } from './type-utils.js';
5
3
  import { ReturnsMap } from './returns.js';
6
4
  import { Schema } from './schema.js';
@@ -8,9 +6,6 @@ export type { HttpMethod, Method } from './type-utils.js';
8
6
  export type { EmptyReturns, MergeReturns, ReturnsMap, HandlerReply, HasReturns, StatusCode, ValidHandlerReply, EnforceHandlerReply, } from './returns.js';
9
7
  /** Default empty app context for standalone units without a bound router instance. */
10
8
  export type AppContext = Record<never, never>;
11
- export type NativeContext = RouterRegister extends {
12
- NativeContext: infer N;
13
- } ? N : unknown;
14
9
  export type ValidatorParts = {
15
10
  query?: unknown;
16
11
  params?: unknown;
@@ -20,7 +15,7 @@ export type ValidatorParts = {
20
15
  bodyIn?: unknown;
21
16
  };
22
17
  export declare const StateBrand: unique symbol;
23
- export type NextResult<TState = unknown> = ReplyResult & {
18
+ export type NextResult<TState = unknown> = Response & {
24
19
  readonly [StateBrand]?: TState;
25
20
  };
26
21
  export type ExtractState<T> = [Extract<Awaited<T>, {
@@ -38,7 +33,7 @@ export type MiddlewareDefinition = {
38
33
  params?: unknown;
39
34
  body?: unknown;
40
35
  returns?: ReturnsMap;
41
- handler: (ctx: unknown, next: MiddlewareNext) => Awaitable<ReplyResult | Response | unknown>;
36
+ handler: (ctx: unknown, next: MiddlewareNext) => Awaitable<Response | unknown>;
42
37
  };
43
38
  export type MiddlewareReturnFromParts<TQuery, TParams, TBody, TState, TQueryIn = TQuery, TParamsIn = TParams, TBodyIn = TBody> = {
44
39
  query: Simplify<UnwrapPart<TQuery>>;
@@ -52,12 +47,12 @@ export type MiddlewareReturnFromParts<TQuery, TParams, TBody, TState, TQueryIn =
52
47
  body: RequestShape<TBodyIn, TBody>;
53
48
  };
54
49
  };
55
- type UnitRuntimeContext = Omit<RuntimeContextFields<NativeContext>, "var">;
56
- export type StandaloneMiddlewareContext<TQuery = unknown, TParams = unknown, TBody = unknown, TAppContext extends Record<string, unknown> = AppContext> = Simplify<TAppContext & UnitRuntimeContext & {
50
+ type UnitRuntimeContext = Omit<RuntimeContextFields, "var">;
51
+ export type StandaloneMiddlewareContext<TQuery = unknown, TParams = unknown, TBody = unknown, TAppContext extends Record<string, unknown> = AppContext, TState = {}> = Simplify<TAppContext & UnitRuntimeContext & {
57
52
  query: Simplify<UnwrapPart<TQuery>>;
58
53
  params: Simplify<UnwrapPart<TParams>>;
59
54
  body: Simplify<UnwrapPart<TBody>>;
60
- state: {};
55
+ state: Simplify<UnwrapPart<TState>>;
61
56
  headers: TaserHeaders;
62
57
  cookies: TaserCookieJar;
63
58
  }>;
@@ -75,9 +70,11 @@ export type HandlerContext<Acc extends readonly unknown[], Validators extends Va
75
70
  headers: TaserHeaders;
76
71
  cookies: TaserCookieJar;
77
72
  }>;
78
- export type MiddlewareUnit<TAcc = unknown, TReturns extends ReturnsMap = {}> = MiddlewareDefinition & {
73
+ export type MiddlewareUnit<TAcc = unknown, TReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown> = MiddlewareDefinition & {
79
74
  readonly __middlewareAcc: TAcc;
80
75
  readonly __returns?: TReturns;
76
+ readonly __requiredLayouts?: TRequiredLayouts;
77
+ readonly __requiredState?: TRequiredState;
81
78
  };
82
79
  export type HandlerUnit<_Acc extends readonly unknown[], _Validators extends ValidatorParts, TReturns extends ReturnsMap = {}, TOutput = Response> = {
83
80
  readonly __returns?: TReturns;
@@ -85,7 +82,7 @@ export type HandlerUnit<_Acc extends readonly unknown[], _Validators extends Val
85
82
  Output: TOutput;
86
83
  };
87
84
  middlewares: readonly MiddlewareDefinition[];
88
- handler: (ctx: unknown) => Awaitable<ReplyResult | Response>;
85
+ handler: (ctx: unknown) => Awaitable<Response>;
89
86
  returns?: ReturnsMap;
90
87
  query?: Schema<unknown>;
91
88
  params?: Schema<unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"units.js","names":[],"sources":["../../../src/types/units.ts"],"sourcesContent":["import type { Awaitable, TaserCookieJar, TaserHeaders } from \"@taserjs/router-core\";\nimport type { ReplyResult } from \"@taserjs/router-utils\";\n\nimport type { RouterRegister } from \"../register.js\";\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 NativeContext = RouterRegister extends { NativeContext: infer N } ? N : unknown;\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> = ReplyResult & {\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<ReplyResult | 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<NativeContext>, \"var\">;\n\nexport type StandaloneMiddlewareContext<\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TAppContext extends Record<string, unknown> = AppContext,\n> = Simplify<\n TAppContext &\n UnitRuntimeContext & {\n query: Simplify<UnwrapPart<TQuery>>;\n params: Simplify<UnwrapPart<TParams>>;\n body: Simplify<UnwrapPart<TBody>>;\n state: {};\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> = MiddlewareDefinition & {\n readonly __middlewareAcc: TAcc;\n readonly __returns?: TReturns;\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<ReplyResult | 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":";AA2LA,SAAgB,cACd,OAC0D;CAC1D,OACE,OAAO,UAAU,YACjB,UAAU,QACV,aAAa,SACb,iBAAiB,SACjB,MAAM,QAAS,MAA0D,WAAW;AAExF"}
1
+ {"version":3,"file":"units.js","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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taserjs/router",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Type-safe Node.js router with runtime validation and middleware",
5
5
  "license": "ISC",
6
6
  "repository": {
@@ -147,8 +147,8 @@
147
147
  "dependencies": {
148
148
  "@standard-schema/spec": "^1.1.0",
149
149
  "hono": "^4.10.3",
150
- "@taserjs/router-core": "0.0.3",
151
- "@taserjs/router-utils": "0.0.3"
150
+ "@taserjs/router-utils": "0.0.5",
151
+ "@taserjs/router-core": "0.0.5"
152
152
  },
153
153
  "devDependencies": {
154
154
  "@tanstack/vite-config": "^0.6.0",