@taserjs/router 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +24 -0
  3. package/dist/cjs/constants.cjs +17 -0
  4. package/dist/cjs/constants.cjs.map +1 -0
  5. package/dist/cjs/constants.d.cts +8 -0
  6. package/dist/cjs/create-context.cjs +8 -0
  7. package/dist/cjs/create-context.cjs.map +1 -0
  8. package/dist/cjs/create-context.d.cts +5 -0
  9. package/dist/cjs/define/handler.cjs +38 -0
  10. package/dist/cjs/define/handler.cjs.map +1 -0
  11. package/dist/cjs/define/handler.d.cts +13 -0
  12. package/dist/cjs/define/middleware.cjs +36 -0
  13. package/dist/cjs/define/middleware.cjs.map +1 -0
  14. package/dist/cjs/define/middleware.d.cts +85 -0
  15. package/dist/cjs/define/validators.cjs +14 -0
  16. package/dist/cjs/define/validators.cjs.map +1 -0
  17. package/dist/cjs/define/validators.d.cts +8 -0
  18. package/dist/cjs/factories.cjs +29 -0
  19. package/dist/cjs/factories.cjs.map +1 -0
  20. package/dist/cjs/factories.d.cts +61 -0
  21. package/dist/cjs/index.cjs +42 -0
  22. package/dist/cjs/index.d.cts +12 -0
  23. package/dist/cjs/middleware/auth.cjs +34 -0
  24. package/dist/cjs/middleware/auth.cjs.map +1 -0
  25. package/dist/cjs/middleware/auth.d.cts +9 -0
  26. package/dist/cjs/middleware/body-limit.cjs +12 -0
  27. package/dist/cjs/middleware/body-limit.cjs.map +1 -0
  28. package/dist/cjs/middleware/body-limit.d.cts +3 -0
  29. package/dist/cjs/middleware/compress.cjs +12 -0
  30. package/dist/cjs/middleware/compress.cjs.map +1 -0
  31. package/dist/cjs/middleware/compress.d.cts +3 -0
  32. package/dist/cjs/middleware/cors.cjs +12 -0
  33. package/dist/cjs/middleware/cors.cjs.map +1 -0
  34. package/dist/cjs/middleware/cors.d.cts +3 -0
  35. package/dist/cjs/middleware/csrf.cjs +12 -0
  36. package/dist/cjs/middleware/csrf.cjs.map +1 -0
  37. package/dist/cjs/middleware/csrf.d.cts +3 -0
  38. package/dist/cjs/middleware/etag.cjs +12 -0
  39. package/dist/cjs/middleware/etag.cjs.map +1 -0
  40. package/dist/cjs/middleware/etag.d.cts +3 -0
  41. package/dist/cjs/middleware/jwk.cjs +25 -0
  42. package/dist/cjs/middleware/jwk.cjs.map +1 -0
  43. package/dist/cjs/middleware/jwk.d.cts +15 -0
  44. package/dist/cjs/middleware/jwt.cjs +16 -0
  45. package/dist/cjs/middleware/jwt.cjs.map +1 -0
  46. package/dist/cjs/middleware/jwt.d.cts +10 -0
  47. package/dist/cjs/middleware/secure-headers.cjs +12 -0
  48. package/dist/cjs/middleware/secure-headers.cjs.map +1 -0
  49. package/dist/cjs/middleware/secure-headers.d.cts +3 -0
  50. package/dist/cjs/middleware/timing.cjs +12 -0
  51. package/dist/cjs/middleware/timing.cjs.map +1 -0
  52. package/dist/cjs/middleware/timing.d.cts +3 -0
  53. package/dist/cjs/middleware.cjs +17 -0
  54. package/dist/cjs/middleware.cjs.map +1 -0
  55. package/dist/cjs/middleware.d.cts +2 -0
  56. package/dist/cjs/register.d.cts +2 -0
  57. package/dist/cjs/route.cjs +94 -0
  58. package/dist/cjs/route.cjs.map +1 -0
  59. package/dist/cjs/route.d.cts +5 -0
  60. package/dist/cjs/taser-app.cjs +42 -0
  61. package/dist/cjs/taser-app.cjs.map +1 -0
  62. package/dist/cjs/taser-app.d.cts +21 -0
  63. package/dist/cjs/taser-router.cjs +83 -0
  64. package/dist/cjs/taser-router.cjs.map +1 -0
  65. package/dist/cjs/taser-router.d.cts +44 -0
  66. package/dist/cjs/types/app.d.cts +46 -0
  67. package/dist/cjs/types/index.d.cts +305 -0
  68. package/dist/cjs/types/returns.d.cts +37 -0
  69. package/dist/cjs/types/schema.d.cts +14 -0
  70. package/dist/cjs/types/type-utils.d.cts +52 -0
  71. package/dist/cjs/types/units.cjs +8 -0
  72. package/dist/cjs/types/units.cjs.map +1 -0
  73. package/dist/cjs/types/units.d.cts +98 -0
  74. package/dist/esm/constants.d.ts +8 -0
  75. package/dist/esm/constants.js +16 -0
  76. package/dist/esm/constants.js.map +1 -0
  77. package/dist/esm/create-context.d.ts +5 -0
  78. package/dist/esm/create-context.js +8 -0
  79. package/dist/esm/create-context.js.map +1 -0
  80. package/dist/esm/define/handler.d.ts +13 -0
  81. package/dist/esm/define/handler.js +38 -0
  82. package/dist/esm/define/handler.js.map +1 -0
  83. package/dist/esm/define/middleware.d.ts +85 -0
  84. package/dist/esm/define/middleware.js +36 -0
  85. package/dist/esm/define/middleware.js.map +1 -0
  86. package/dist/esm/define/validators.d.ts +8 -0
  87. package/dist/esm/define/validators.js +14 -0
  88. package/dist/esm/define/validators.js.map +1 -0
  89. package/dist/esm/factories.d.ts +61 -0
  90. package/dist/esm/factories.js +21 -0
  91. package/dist/esm/factories.js.map +1 -0
  92. package/dist/esm/index.d.ts +12 -0
  93. package/dist/esm/index.js +8 -0
  94. package/dist/esm/middleware/auth.d.ts +9 -0
  95. package/dist/esm/middleware/auth.js +33 -0
  96. package/dist/esm/middleware/auth.js.map +1 -0
  97. package/dist/esm/middleware/body-limit.d.ts +3 -0
  98. package/dist/esm/middleware/body-limit.js +11 -0
  99. package/dist/esm/middleware/body-limit.js.map +1 -0
  100. package/dist/esm/middleware/compress.d.ts +3 -0
  101. package/dist/esm/middleware/compress.js +11 -0
  102. package/dist/esm/middleware/compress.js.map +1 -0
  103. package/dist/esm/middleware/cors.d.ts +3 -0
  104. package/dist/esm/middleware/cors.js +11 -0
  105. package/dist/esm/middleware/cors.js.map +1 -0
  106. package/dist/esm/middleware/csrf.d.ts +3 -0
  107. package/dist/esm/middleware/csrf.js +11 -0
  108. package/dist/esm/middleware/csrf.js.map +1 -0
  109. package/dist/esm/middleware/etag.d.ts +3 -0
  110. package/dist/esm/middleware/etag.js +11 -0
  111. package/dist/esm/middleware/etag.js.map +1 -0
  112. package/dist/esm/middleware/jwk.d.ts +15 -0
  113. package/dist/esm/middleware/jwk.js +24 -0
  114. package/dist/esm/middleware/jwk.js.map +1 -0
  115. package/dist/esm/middleware/jwt.d.ts +10 -0
  116. package/dist/esm/middleware/jwt.js +15 -0
  117. package/dist/esm/middleware/jwt.js.map +1 -0
  118. package/dist/esm/middleware/secure-headers.d.ts +3 -0
  119. package/dist/esm/middleware/secure-headers.js +11 -0
  120. package/dist/esm/middleware/secure-headers.js.map +1 -0
  121. package/dist/esm/middleware/timing.d.ts +3 -0
  122. package/dist/esm/middleware/timing.js +11 -0
  123. package/dist/esm/middleware/timing.js.map +1 -0
  124. package/dist/esm/middleware.d.ts +2 -0
  125. package/dist/esm/middleware.js +17 -0
  126. package/dist/esm/middleware.js.map +1 -0
  127. package/dist/esm/register.d.ts +2 -0
  128. package/dist/esm/route.d.ts +5 -0
  129. package/dist/esm/route.js +94 -0
  130. package/dist/esm/route.js.map +1 -0
  131. package/dist/esm/taser-app.d.ts +21 -0
  132. package/dist/esm/taser-app.js +40 -0
  133. package/dist/esm/taser-app.js.map +1 -0
  134. package/dist/esm/taser-router.d.ts +44 -0
  135. package/dist/esm/taser-router.js +82 -0
  136. package/dist/esm/taser-router.js.map +1 -0
  137. package/dist/esm/types/app.d.ts +46 -0
  138. package/dist/esm/types/index.d.ts +305 -0
  139. package/dist/esm/types/returns.d.ts +37 -0
  140. package/dist/esm/types/schema.d.ts +14 -0
  141. package/dist/esm/types/type-utils.d.ts +52 -0
  142. package/dist/esm/types/units.d.ts +98 -0
  143. package/dist/esm/types/units.js +8 -0
  144. package/dist/esm/types/units.js.map +1 -0
  145. package/package.json +149 -0
  146. package/src/constants.ts +10 -0
  147. package/src/create-context.ts +19 -0
  148. package/src/define/handler.ts +72 -0
  149. package/src/define/middleware.ts +289 -0
  150. package/src/define/validators.ts +22 -0
  151. package/src/factories.ts +183 -0
  152. package/src/index.ts +44 -0
  153. package/src/middleware/auth.ts +51 -0
  154. package/src/middleware/body-limit.ts +11 -0
  155. package/src/middleware/compress.ts +11 -0
  156. package/src/middleware/cors.ts +11 -0
  157. package/src/middleware/csrf.ts +11 -0
  158. package/src/middleware/etag.ts +11 -0
  159. package/src/middleware/jwk.ts +47 -0
  160. package/src/middleware/jwt.ts +18 -0
  161. package/src/middleware/secure-headers.ts +11 -0
  162. package/src/middleware/timing.ts +11 -0
  163. package/src/middleware.ts +19 -0
  164. package/src/register.ts +1 -0
  165. package/src/route.ts +145 -0
  166. package/src/taser-app.ts +43 -0
  167. package/src/taser-router.ts +160 -0
  168. package/src/types/app.ts +65 -0
  169. package/src/types/index.ts +1064 -0
  170. package/src/types/returns.ts +135 -0
  171. package/src/types/schema.ts +22 -0
  172. package/src/types/type-utils.ts +86 -0
  173. package/src/types/units.ts +167 -0
@@ -0,0 +1,135 @@
1
+ import type { ReplyOf } from '@taserjs/router-utils'
2
+
3
+ import type { Simplify } from './type-utils.js'
4
+ import type { Schema } from './schema.js'
5
+ import type { InferOutput } from './schema.js'
6
+
7
+ /**
8
+ * Known HTTP status codes. `number & {}` allows custom codes while keeping
9
+ * literal autocomplete / inference for well-known values.
10
+ */
11
+ export type StatusCode
12
+ = | 100
13
+ | 101
14
+ | 102
15
+ | 103
16
+ | 200
17
+ | 201
18
+ | 202
19
+ | 203
20
+ | 204
21
+ | 205
22
+ | 206
23
+ | 207
24
+ | 208
25
+ | 226
26
+ | 300
27
+ | 301
28
+ | 302
29
+ | 303
30
+ | 304
31
+ | 305
32
+ | 306
33
+ | 307
34
+ | 308
35
+ | 400
36
+ | 401
37
+ | 402
38
+ | 403
39
+ | 404
40
+ | 405
41
+ | 406
42
+ | 407
43
+ | 408
44
+ | 409
45
+ | 410
46
+ | 411
47
+ | 412
48
+ | 413
49
+ | 414
50
+ | 415
51
+ | 416
52
+ | 417
53
+ | 418
54
+ | 421
55
+ | 422
56
+ | 423
57
+ | 424
58
+ | 425
59
+ | 426
60
+ | 428
61
+ | 429
62
+ | 431
63
+ | 451
64
+ | 500
65
+ | 501
66
+ | 502
67
+ | 503
68
+ | 504
69
+ | 505
70
+ | 506
71
+ | 507
72
+ | 508
73
+ | 510
74
+ | 511
75
+ | (number & {})
76
+
77
+ /** Status-code → Standard Schema map for route/middleware/handler outputs. */
78
+ export type ReturnsMap = {
79
+ readonly [K in StatusCode]?: Schema<unknown>
80
+ }
81
+
82
+ /** Later map wins on overlapping status keys. */
83
+ export type MergeReturns<
84
+ A extends ReturnsMap,
85
+ B extends ReturnsMap,
86
+ > = Omit<A, keyof B> & B
87
+
88
+ /** Typed reply union for statuses declared in a returns map. */
89
+ export type ReplyResultFor<M extends ReturnsMap> = {
90
+ [S in keyof M]-?: S extends StatusCode
91
+ ? M[S] extends Schema<unknown>
92
+ ? ReplyOf<S, Simplify<InferOutput<M[S]>>>
93
+ : never
94
+ : never
95
+ }[keyof M]
96
+
97
+ export type EmptyReturns = {}
98
+
99
+ /** True when no status schemas have been declared yet. */
100
+ export type HasReturns<M extends ReturnsMap> = [keyof M] extends [never] ? false : true
101
+
102
+ /**
103
+ * Validate a concrete reply `R` against returns map `M`.
104
+ * Declared statuses must match schema output; undeclared statuses stay open
105
+ * (same rule as runtime `validateReply`).
106
+ */
107
+ export type ValidHandlerReply<R, M extends ReturnsMap> = R extends ReplyOf<infer S, infer B>
108
+ ? S extends keyof M
109
+ ? M[S] extends Schema<unknown>
110
+ ? B extends Simplify<InferOutput<M[S]>>
111
+ ? R
112
+ : never
113
+ : R
114
+ : R
115
+ : R extends Response
116
+ ? R
117
+ : never
118
+
119
+ /**
120
+ * Narrow a handler return so declared statuses are schema-checked without
121
+ * breaking multi-status unions (avoids circular `R extends …<R>` constraints).
122
+ */
123
+ export type EnforceHandlerReply<R, M extends ReturnsMap>
124
+ = [R] extends [ValidHandlerReply<R, M>]
125
+ ? R
126
+ : ValidHandlerReply<R, M>
127
+
128
+ /**
129
+ * Expected `.handler` return type for a returns map.
130
+ * Prefer constraining handler generics with {@link EnforceHandlerReply}.
131
+ */
132
+ export type HandlerReply<M extends ReturnsMap>
133
+ = HasReturns<M> extends true
134
+ ? ReplyResultFor<M> | Response
135
+ : Response
@@ -0,0 +1,22 @@
1
+ import type { StandardSchemaV1 } from '@standard-schema/spec'
2
+
3
+ import type { RequestShape } from './type-utils.js'
4
+
5
+ export type { StandardSchemaV1 } from '@standard-schema/spec'
6
+
7
+ /**
8
+ * A Standard Schema validator.
9
+ * `TOutput` is the validated/output type; `TInput` is the pre-parse input (request shape).
10
+ */
11
+ export type Schema<TOutput = unknown, TInput = unknown> = StandardSchemaV1<TInput, TOutput>
12
+
13
+ /** Infers the output type from a Standard Schema. */
14
+ export type InferOutput<S> = S extends StandardSchemaV1<unknown, infer O> ? O : never
15
+
16
+ /** Infers the input type from a Standard Schema. */
17
+ export type InferInput<S> = S extends StandardSchemaV1<infer I, unknown> ? I : never
18
+
19
+ /** Pre-parse request shape from a Standard Schema. */
20
+ export type SchemaRequestShape<S> = S extends StandardSchemaV1<infer I, infer O>
21
+ ? RequestShape<I, O>
22
+ : S
@@ -0,0 +1,86 @@
1
+ export type Method = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'OPTIONS' | 'HEAD'
2
+ export type HttpMethod = Method
3
+
4
+ export type MiddlewareFieldName
5
+ = | 'query'
6
+ | 'params'
7
+ | 'body'
8
+ | 'state'
9
+ | 'ctx'
10
+
11
+ export type MiddlewareInputFieldName = 'query' | 'params' | 'body'
12
+
13
+ export type UnwrapPart<T> = unknown extends T ? {} : T
14
+
15
+ export type MergePart<T, Base> = unknown extends T ? Base : Base & T
16
+
17
+ /** Collapse intersections so `Omit`/`keyof` treat the result as one object type. */
18
+ export type Simplify<T> = { [K in keyof T]: T[K] } & {}
19
+
20
+ /**
21
+ * Request prop: when schema input is `unknown` (e.g. zod coerce),
22
+ * fall back to the validated output type.
23
+ */
24
+ type RequestPropType<TIn, TOut> = [unknown] extends [Exclude<TIn, undefined>]
25
+ ? TOut
26
+ : TIn
27
+
28
+ /**
29
+ * Pre-parse request shape. Prefer input types (defaults → optional),
30
+ * but replace `unknown` input props with output types.
31
+ */
32
+ export type RequestShape<TIn, TOut> = unknown extends TIn
33
+ ? UnwrapPart<TOut>
34
+ : Simplify<{
35
+ [K in keyof TIn]: K extends keyof TOut
36
+ ? RequestPropType<TIn[K], TOut[K]>
37
+ : TIn[K]
38
+ }>
39
+
40
+ export type UnionToIntersection<U>
41
+ = (U extends unknown ? (value: U) => void : never) extends (value: infer Value) => void ? Value : never
42
+
43
+ export type MiddlewareField<
44
+ Middleware,
45
+ Field extends MiddlewareFieldName,
46
+ > = Field extends 'query'
47
+ ? Middleware extends { query: infer Query } ? Query : {}
48
+ : Field extends 'params'
49
+ ? Middleware extends { params: infer Params } ? Params : {}
50
+ : Field extends 'body'
51
+ ? Middleware extends { body: infer Body } ? Body : {}
52
+ : Field extends 'state'
53
+ ? Middleware extends { state: infer State } ? State : {}
54
+ : Field extends 'ctx'
55
+ ? Middleware extends { ctx: infer Ctx } ? Ctx : {}
56
+ : {}
57
+
58
+ export type MiddlewareInputField<
59
+ Middleware,
60
+ Field extends MiddlewareInputFieldName,
61
+ > = Middleware extends { input: { [K in Field]: infer V } } ? V : {}
62
+
63
+ export type MergeMiddlewareField<
64
+ Middlewares extends readonly unknown[],
65
+ Field extends MiddlewareFieldName,
66
+ > = [Middlewares] extends [readonly []]
67
+ ? {}
68
+ : UnionToIntersection<MiddlewareField<Middlewares[number], Field>>
69
+
70
+ export type MergeMiddlewareInputField<
71
+ Middlewares extends readonly unknown[],
72
+ Field extends MiddlewareInputFieldName,
73
+ > = [Middlewares] extends [readonly []]
74
+ ? {}
75
+ : UnionToIntersection<MiddlewareInputField<Middlewares[number], Field>>
76
+
77
+ export type RuntimeContextFields<TNative = unknown> = {
78
+ request: Request
79
+ method: Method
80
+ url: URL
81
+ headers: import('@taserjs/router-core').TaserHeaders
82
+ cookies: import('@taserjs/router-core').TaserCookieJar
83
+ reply: typeof import('@taserjs/router-utils').reply
84
+ var: Record<string, unknown>
85
+ native?: TNative
86
+ }
@@ -0,0 +1,167 @@
1
+ import type { Awaitable, TaserCookieJar, TaserHeaders } from '@taserjs/router-core'
2
+ import type { ReplyResult } from '@taserjs/router-utils'
3
+
4
+ import type { RouterRegister } from '../register.js'
5
+ import type {
6
+ MergeMiddlewareField,
7
+ MergePart,
8
+ RequestShape,
9
+ RuntimeContextFields,
10
+ Simplify,
11
+ UnwrapPart,
12
+ } from './type-utils.js'
13
+ import type { ReturnsMap } from './returns.js'
14
+ import type { Schema } from './schema.js'
15
+
16
+ export type { HttpMethod, Method } from './type-utils.js'
17
+ export type { EmptyReturns, MergeReturns, ReturnsMap, HandlerReply, HasReturns, StatusCode, ValidHandlerReply, EnforceHandlerReply } from './returns.js'
18
+
19
+ /** Default empty app context for standalone units without a bound router instance. */
20
+ export type AppContext = Record<never, never>
21
+
22
+ export type NativeContext = RouterRegister extends { NativeContext: infer N } ? N : unknown
23
+
24
+ export type ValidatorParts = {
25
+ query?: unknown
26
+ params?: unknown
27
+ body?: unknown
28
+ queryIn?: unknown
29
+ paramsIn?: unknown
30
+ bodyIn?: unknown
31
+ }
32
+
33
+ export type MiddlewareNext = {
34
+ (args?: { state?: unknown, ctx?: unknown }): Promise<ReplyResult>
35
+ }
36
+
37
+ export type MiddlewareDefinition = {
38
+ state?: unknown
39
+ ctx?: unknown
40
+ query?: unknown
41
+ params?: unknown
42
+ body?: unknown
43
+ returns?: ReturnsMap
44
+ handler: (
45
+ ctx: unknown,
46
+ next: MiddlewareNext,
47
+ ) => Awaitable<ReplyResult | Response | unknown>
48
+ }
49
+
50
+ export type MiddlewareReturnFromParts<
51
+ TQuery,
52
+ TParams,
53
+ TBody,
54
+ TState,
55
+ TCtx = unknown,
56
+ TQueryIn = TQuery,
57
+ TParamsIn = TParams,
58
+ TBodyIn = TBody,
59
+ > = {
60
+ query: Simplify<UnwrapPart<TQuery>>
61
+ params: Simplify<UnwrapPart<TParams>>
62
+ body: Simplify<UnwrapPart<TBody>>
63
+ state: Simplify<UnwrapPart<TState>>
64
+ ctx: Simplify<UnwrapPart<TCtx>>
65
+ /** Pre-parse shapes merged into route `$Infer.Input`. */
66
+ input: {
67
+ query: RequestShape<TQueryIn, TQuery>
68
+ params: RequestShape<TParamsIn, TParams>
69
+ body: RequestShape<TBodyIn, TBody>
70
+ }
71
+ }
72
+
73
+ type UnitRuntimeContext = RuntimeContextFields<NativeContext>
74
+
75
+ export type StandaloneMiddlewareContext<
76
+ TQuery = unknown,
77
+ TParams = unknown,
78
+ TBody = unknown,
79
+ TAppContext extends Record<string, unknown> = AppContext,
80
+ > = Simplify<
81
+ TAppContext & UnitRuntimeContext & {
82
+ query: Simplify<UnwrapPart<TQuery>>
83
+ params: Simplify<UnwrapPart<TParams>>
84
+ body: Simplify<UnwrapPart<TBody>>
85
+ state: {}
86
+ headers: TaserHeaders
87
+ cookies: TaserCookieJar
88
+ }
89
+ >
90
+
91
+ export type HandlerContext<
92
+ Acc extends readonly unknown[],
93
+ Validators extends ValidatorParts,
94
+ TAppContext extends Record<string, unknown> = AppContext,
95
+ > = Simplify<
96
+ TAppContext
97
+ & UnitRuntimeContext
98
+ & MergeMiddlewareField<Acc, 'ctx'>
99
+ & {
100
+ query: Simplify<MergePart<
101
+ Validators extends { query?: infer Q } ? Q : unknown,
102
+ MergeMiddlewareField<Acc, 'query'>
103
+ >>
104
+ params: Simplify<MergePart<
105
+ Validators extends { params?: infer P } ? P : unknown,
106
+ MergeMiddlewareField<Acc, 'params'>
107
+ >>
108
+ body: Simplify<MergePart<
109
+ Validators extends { body?: infer B } ? B : unknown,
110
+ MergeMiddlewareField<Acc, 'body'>
111
+ >>
112
+ state: Simplify<MergeMiddlewareField<Acc, 'state'>>
113
+ headers: TaserHeaders
114
+ cookies: TaserCookieJar
115
+ }
116
+ >
117
+
118
+ export type MiddlewareUnit<
119
+ TAcc = unknown,
120
+ TReturns extends ReturnsMap = {},
121
+ > = MiddlewareDefinition & {
122
+ readonly __middlewareAcc: TAcc
123
+ readonly __returns?: TReturns
124
+ }
125
+
126
+ export type HandlerUnit<
127
+ _Acc extends readonly unknown[],
128
+ _Validators extends ValidatorParts,
129
+ TReturns extends ReturnsMap = {},
130
+ TOutput = Response,
131
+ > = {
132
+ readonly __returns?: TReturns
133
+ readonly $Infer: {
134
+ Output: TOutput
135
+ }
136
+ middlewares: readonly MiddlewareDefinition[]
137
+ handler: (ctx: unknown) => Awaitable<ReplyResult | Response>
138
+ returns?: ReturnsMap
139
+ query?: Schema<unknown>
140
+ params?: Schema<unknown>
141
+ body?: Schema<unknown>
142
+ }
143
+
144
+ export type InlineMiddlewareOptions = {
145
+ state?: Schema<unknown>
146
+ ctx?: Schema<unknown>
147
+ query?: Schema<unknown>
148
+ params?: Schema<unknown>
149
+ body?: Schema<unknown>
150
+ returns?: ReturnsMap
151
+ handler: (
152
+ ctx: unknown,
153
+ next: MiddlewareNext,
154
+ ) => Awaitable<unknown>
155
+ }
156
+
157
+ export function isHandlerUnit(
158
+ value: unknown,
159
+ ): value is HandlerUnit<readonly unknown[], ValidatorParts> {
160
+ return (
161
+ typeof value === 'object'
162
+ && value !== null
163
+ && 'handler' in value
164
+ && 'middlewares' in value
165
+ && Array.isArray((value as HandlerUnit<readonly unknown[], ValidatorParts>).middlewares)
166
+ )
167
+ }