@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,160 @@
1
+ import {
2
+ createTaserRuntime,
3
+ type NotFoundHandler,
4
+ type OnErrorHandler,
5
+ type RouteManifestShape,
6
+ } from '@taserjs/router-core'
7
+ import { normalizeOnError } from '@taserjs/router-utils'
8
+
9
+ import {
10
+ createAllRoute,
11
+ createAnyRoute,
12
+ createDeleteRoute,
13
+ createGetRoute,
14
+ createHeadRoute,
15
+ createOptionsRoute,
16
+ createPatchRoute,
17
+ createPostRoute,
18
+ createPutRoute,
19
+ } from './factories.js'
20
+ import { defineHandler } from './define/handler.js'
21
+ import { defineMiddleware } from './define/middleware.js'
22
+ import { createMiddleware } from './middleware.js'
23
+ import { TaserApp } from './taser-app.js'
24
+ import type {
25
+ ContextDefinition,
26
+ CreateTaserAppOptions,
27
+ OnErrorOptions,
28
+ } from './types/app.js'
29
+ import type { AppContext } from './types/units.js'
30
+ import type { HandlerBuilder, LayoutId, MiddlewareBuilder } from './types/index.js'
31
+ import type { Schema } from './types/schema.js'
32
+ import type {
33
+ CreateAllRoute,
34
+ CreateAnyRoute,
35
+ CreateWithBodyRoute,
36
+ CreateWithoutBodyRoute,
37
+ } from './factories.js'
38
+
39
+ function toOnErrorHandler(
40
+ onErrorOptions: OnErrorOptions | OnErrorOptions['handle'],
41
+ ): OnErrorHandler {
42
+ return normalizeOnError(onErrorOptions)
43
+ }
44
+
45
+ type RouterState = {
46
+ options: CreateTaserAppOptions
47
+ contextDef: ContextDefinition<Record<string, unknown>, Record<string, unknown>>
48
+ onError?: OnErrorHandler
49
+ notFound?: NotFoundHandler
50
+ }
51
+
52
+ const emptyContext: ContextDefinition<Record<string, unknown>, Record<string, unknown>> = {}
53
+
54
+ export class TaserRouter<TAppContext extends Record<string, unknown> = AppContext> {
55
+ private readonly state: RouterState
56
+
57
+ constructor(options: CreateTaserAppOptions = {}, state?: Partial<Omit<RouterState, 'options'>>) {
58
+ this.state = {
59
+ options,
60
+ contextDef: state?.contextDef ?? emptyContext,
61
+ ...(state?.onError !== undefined ? { onError: state.onError } : {}),
62
+ ...(state?.notFound !== undefined ? { notFound: state.notFound } : {}),
63
+ }
64
+ }
65
+
66
+ context<
67
+ TBoot extends Record<string, unknown>,
68
+ TReq extends Record<string, unknown>,
69
+ >(definition: ContextDefinition<TBoot, TReq>): TaserRouter<TBoot & TReq> {
70
+ this.state.contextDef = definition
71
+ return this as unknown as TaserRouter<TBoot & TReq>
72
+ }
73
+
74
+ onError<TResponses extends import('./types/returns.js').ReturnsMap = import('./types/returns.js').ReturnsMap>(
75
+ options: OnErrorOptions<TResponses> | OnErrorOptions<TResponses>['handle'],
76
+ ): this {
77
+ this.state.onError = toOnErrorHandler(options)
78
+ return this
79
+ }
80
+
81
+ notFound(
82
+ handler: (ctx: unknown) => Response | Promise<Response> | unknown,
83
+ ): this {
84
+ this.state.notFound = ctx => handler(ctx)
85
+ return this
86
+ }
87
+
88
+ get: CreateWithoutBodyRoute<'GET', TAppContext> = createGetRoute as CreateWithoutBodyRoute<'GET', TAppContext>
89
+ post: CreateWithBodyRoute<'POST', TAppContext> = createPostRoute as CreateWithBodyRoute<'POST', TAppContext>
90
+ put: CreateWithBodyRoute<'PUT', TAppContext> = createPutRoute as CreateWithBodyRoute<'PUT', TAppContext>
91
+ patch: CreateWithBodyRoute<'PATCH', TAppContext> = createPatchRoute as CreateWithBodyRoute<'PATCH', TAppContext>
92
+ delete: CreateWithoutBodyRoute<'DELETE', TAppContext> = createDeleteRoute as CreateWithoutBodyRoute<'DELETE', TAppContext>
93
+ options: CreateWithoutBodyRoute<'OPTIONS', TAppContext> = createOptionsRoute as CreateWithoutBodyRoute<'OPTIONS', TAppContext>
94
+ head: CreateWithoutBodyRoute<'HEAD', TAppContext> = createHeadRoute as CreateWithoutBodyRoute<'HEAD', TAppContext>
95
+ any: CreateAnyRoute<TAppContext> = createAnyRoute as CreateAnyRoute<TAppContext>
96
+ all: CreateAllRoute<TAppContext> = createAllRoute as CreateAllRoute<TAppContext>
97
+
98
+ middleware<const Layout extends LayoutId>(layout: Layout): MiddlewareBuilder<Layout, readonly [], TAppContext> {
99
+ return createMiddleware(layout) as MiddlewareBuilder<Layout, readonly [], TAppContext>
100
+ }
101
+
102
+ defineHandler<
103
+ TQuery = unknown,
104
+ TParams = unknown,
105
+ TBody = unknown,
106
+ >(
107
+ options?: {
108
+ query?: Schema<TQuery>
109
+ params?: Schema<TParams>
110
+ body?: Schema<TBody>
111
+ },
112
+ ): HandlerBuilder<
113
+ readonly [],
114
+ { query: TQuery, params: TParams, body: TBody },
115
+ {},
116
+ TAppContext
117
+ > {
118
+ return options === undefined
119
+ ? defineHandler<TAppContext>()
120
+ : defineHandler<TAppContext>(options)
121
+ }
122
+
123
+ defineMiddleware(): ReturnType<typeof defineMiddleware<TAppContext>> {
124
+ return defineMiddleware<TAppContext>()
125
+ }
126
+
127
+ create<const TManifest extends RouteManifestShape>(manifest: TManifest): TaserApp<TManifest> {
128
+ const definition = this.state.contextDef
129
+ const validateResponse = this.state.options.response?.validate ?? true
130
+ const onValidationFailure = this.state.options.response?.onValidationFailure
131
+ const bootPromise = Promise.resolve(
132
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
133
+ definition.boot?.() ?? ({} as Record<string, unknown>),
134
+ )
135
+
136
+ const runtime = createTaserRuntime(
137
+ manifest,
138
+ async ({ native }) => {
139
+ const bootContext = await bootPromise
140
+ const requestContext = await definition.request?.({ native }) ?? {}
141
+ return { ...bootContext, ...requestContext }
142
+ },
143
+ {
144
+ response: {
145
+ validate: validateResponse,
146
+ ...(onValidationFailure !== undefined ? { onValidationFailure } : {}),
147
+ },
148
+ ...(this.state.onError !== undefined ? { onError: this.state.onError } : {}),
149
+ ...(this.state.notFound !== undefined ? { notFound: this.state.notFound } : {}),
150
+ ...(this.state.options.cookies !== undefined ? { cookies: this.state.options.cookies } : {}),
151
+ },
152
+ )
153
+
154
+ return new TaserApp(runtime, manifest)
155
+ }
156
+ }
157
+
158
+ export function createTaserApp(options: CreateTaserAppOptions = {}): TaserRouter {
159
+ return new TaserRouter(options)
160
+ }
@@ -0,0 +1,65 @@
1
+ import type { ResponseValidationFailureHandler } from '@taserjs/router-utils'
2
+
3
+ import type { TaserApp } from '../taser-app.js'
4
+ import type { ReturnsMap } from './returns.js'
5
+ import type { Schema } from './schema.js'
6
+
7
+ export type CreateTaserAppOptions = {
8
+ response?: {
9
+ /** Validate handler replies against returns maps. Default true. */
10
+ validate?: boolean
11
+ onValidationFailure?: ResponseValidationFailureHandler
12
+ }
13
+ /** Global cookie defaults and signing secret. Per-call `ctx.cookies.set` options override defaults. */
14
+ cookies?: {
15
+ secret?: string | BufferSource
16
+ path?: string
17
+ httpOnly?: boolean
18
+ sameSite?: 'Strict' | 'Lax' | 'None' | 'strict' | 'lax' | 'none'
19
+ secure?: boolean
20
+ domain?: string
21
+ maxAge?: number
22
+ expires?: Date
23
+ }
24
+ }
25
+
26
+ export type CreateContextArgs = {
27
+ native?: import('./units.js').NativeContext
28
+ }
29
+
30
+ export type ContextDefinition<
31
+ TBoot extends Record<string, unknown> = Record<string, never>,
32
+ TReq extends Record<string, unknown> = Record<string, never>,
33
+ > = {
34
+ boot?: () => TBoot | Promise<TBoot>
35
+ request?: (args: CreateContextArgs) => TReq | Promise<TReq>
36
+ }
37
+
38
+ export type InferAppContext<
39
+ T extends ContextDefinition<Record<string, unknown>, Record<string, unknown>>,
40
+ > = T extends ContextDefinition<infer TBoot, infer TReq> ? TBoot & TReq : Record<string, never>
41
+
42
+ export type OnErrorOptions<TResponses extends ReturnsMap = ReturnsMap> = {
43
+ responses?: TResponses
44
+ handle: (
45
+ error: unknown,
46
+ ctx?: unknown,
47
+ ) => Response | Promise<Response>
48
+ }
49
+
50
+ export type InferAppManifest<TApp> = TApp extends TaserApp<infer TManifest> ? TManifest : never
51
+
52
+ export type TaserHandler<TFrameworkApp> = {
53
+ /**
54
+ * Mount the Taser handler on a framework app.
55
+ * Use universal wildcard patterns (`/*`, `/prefix/*`) for Hono/Fastify.
56
+ * Use framework-native splat patterns for Express (e.g. `/{*splat}`, `/*splat`).
57
+ */
58
+ mount(pattern: string, frameworkApp: TFrameworkApp): void
59
+ }
60
+
61
+ export type { RouteManifestShape } from '@taserjs/router-core'
62
+
63
+ export type { Schema }
64
+
65
+ export type { TaserApp, TaserMountedApp, TaserNativeBound } from '../taser-app.js'