@taserjs/router 0.0.2 → 0.0.4
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.
- package/README.md +2 -0
- package/dist/cjs/constants.cjs.map +1 -1
- package/dist/cjs/create-context.cjs.map +1 -1
- package/dist/cjs/define/handler.cjs.map +1 -1
- package/dist/cjs/define/middleware.cjs +18 -27
- package/dist/cjs/define/middleware.cjs.map +1 -1
- package/dist/cjs/define/middleware.d.cts +27 -79
- package/dist/cjs/define/validators.cjs.map +1 -1
- package/dist/cjs/factories.cjs.map +1 -1
- package/dist/cjs/factories.d.cts +2 -2
- package/dist/cjs/index.cjs +1 -2
- package/dist/cjs/index.d.cts +1 -1
- package/dist/cjs/middleware/body-limit.cjs +2 -2
- package/dist/cjs/middleware/body-limit.cjs.map +1 -1
- package/dist/cjs/middleware/compress.cjs +2 -2
- package/dist/cjs/middleware/compress.cjs.map +1 -1
- package/dist/cjs/middleware/cors.cjs +2 -2
- package/dist/cjs/middleware/cors.cjs.map +1 -1
- package/dist/cjs/middleware/csrf.cjs +2 -2
- package/dist/cjs/middleware/csrf.cjs.map +1 -1
- package/dist/cjs/middleware/etag.cjs +2 -2
- package/dist/cjs/middleware/etag.cjs.map +1 -1
- package/dist/cjs/middleware/jwk.cjs +11 -4
- package/dist/cjs/middleware/jwk.cjs.map +1 -1
- package/dist/cjs/middleware/jwk.d.cts +4 -5
- package/dist/cjs/middleware/jwt.cjs +11 -5
- package/dist/cjs/middleware/jwt.cjs.map +1 -1
- package/dist/cjs/middleware/jwt.d.cts +7 -5
- package/dist/cjs/middleware/secure-headers.cjs +2 -2
- package/dist/cjs/middleware/secure-headers.cjs.map +1 -1
- package/dist/cjs/middleware/timing.cjs +2 -2
- package/dist/cjs/middleware/timing.cjs.map +1 -1
- package/dist/cjs/middleware/wrap-hono.cjs +9 -0
- package/dist/cjs/middleware/wrap-hono.cjs.map +1 -0
- package/dist/cjs/middleware/wrap-hono.d.cts +3 -0
- package/dist/cjs/middleware.cjs.map +1 -1
- package/dist/cjs/reply.d.cts +1 -1
- package/dist/cjs/route.cjs.map +1 -1
- package/dist/cjs/route.d.cts +1 -1
- package/dist/cjs/stream.d.cts +1 -1
- package/dist/cjs/taser-app.cjs +0 -6
- package/dist/cjs/taser-app.cjs.map +1 -1
- package/dist/cjs/taser-app.d.cts +0 -3
- package/dist/cjs/taser-router.cjs +9 -10
- package/dist/cjs/taser-router.cjs.map +1 -1
- package/dist/cjs/taser-router.d.cts +9 -11
- package/dist/cjs/types/app.d.cts +3 -2
- package/dist/cjs/types/index.d.cts +94 -143
- package/dist/cjs/types/type-utils.d.cts +8 -10
- package/dist/cjs/types/units.cjs.map +1 -1
- package/dist/cjs/types/units.d.cts +32 -27
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/create-context.js.map +1 -1
- package/dist/esm/define/handler.js.map +1 -1
- package/dist/esm/define/middleware.d.ts +27 -79
- package/dist/esm/define/middleware.js +18 -27
- package/dist/esm/define/middleware.js.map +1 -1
- package/dist/esm/define/validators.js.map +1 -1
- package/dist/esm/factories.d.ts +2 -2
- package/dist/esm/factories.js.map +1 -1
- package/dist/esm/index.d.ts +1 -1
- package/dist/esm/index.js +3 -3
- package/dist/esm/middleware/body-limit.js +1 -1
- package/dist/esm/middleware/body-limit.js.map +1 -1
- package/dist/esm/middleware/compress.js +1 -1
- package/dist/esm/middleware/compress.js.map +1 -1
- package/dist/esm/middleware/cors.js +1 -1
- package/dist/esm/middleware/cors.js.map +1 -1
- package/dist/esm/middleware/csrf.js +1 -1
- package/dist/esm/middleware/csrf.js.map +1 -1
- package/dist/esm/middleware/etag.js +1 -1
- package/dist/esm/middleware/etag.js.map +1 -1
- package/dist/esm/middleware/jwk.d.ts +4 -5
- package/dist/esm/middleware/jwk.js +11 -4
- package/dist/esm/middleware/jwk.js.map +1 -1
- package/dist/esm/middleware/jwt.d.ts +7 -5
- package/dist/esm/middleware/jwt.js +11 -5
- package/dist/esm/middleware/jwt.js.map +1 -1
- package/dist/esm/middleware/secure-headers.js +1 -1
- package/dist/esm/middleware/secure-headers.js.map +1 -1
- package/dist/esm/middleware/timing.js +1 -1
- package/dist/esm/middleware/timing.js.map +1 -1
- package/dist/esm/middleware/wrap-hono.d.ts +3 -0
- package/dist/esm/middleware/wrap-hono.js +9 -0
- package/dist/esm/middleware/wrap-hono.js.map +1 -0
- package/dist/esm/middleware.js.map +1 -1
- package/dist/esm/reply.d.ts +1 -1
- package/dist/esm/route.d.ts +1 -1
- package/dist/esm/route.js.map +1 -1
- package/dist/esm/stream.d.ts +1 -1
- package/dist/esm/taser-app.d.ts +0 -3
- package/dist/esm/taser-app.js +1 -6
- package/dist/esm/taser-app.js.map +1 -1
- package/dist/esm/taser-router.d.ts +9 -11
- package/dist/esm/taser-router.js +7 -8
- package/dist/esm/taser-router.js.map +1 -1
- package/dist/esm/types/app.d.ts +3 -2
- package/dist/esm/types/index.d.ts +94 -143
- package/dist/esm/types/type-utils.d.ts +8 -10
- package/dist/esm/types/units.d.ts +32 -27
- package/dist/esm/types/units.js.map +1 -1
- package/package.json +17 -17
- package/src/constants.ts +6 -6
- package/src/create-context.ts +8 -8
- package/src/define/handler.ts +24 -34
- package/src/define/middleware.ts +222 -222
- package/src/define/validators.ts +10 -10
- package/src/factories.ts +63 -61
- package/src/index.ts +12 -12
- package/src/middleware/body-limit.ts +5 -5
- package/src/middleware/compress.ts +5 -5
- package/src/middleware/cors.ts +5 -5
- package/src/middleware/csrf.ts +5 -5
- package/src/middleware/etag.ts +5 -5
- package/src/middleware/jwk.ts +33 -26
- package/src/middleware/jwt.ts +26 -10
- package/src/middleware/secure-headers.ts +5 -5
- package/src/middleware/timing.ts +5 -5
- package/src/middleware/wrap-hono.ts +12 -0
- package/src/middleware.ts +7 -7
- package/src/reply.ts +2 -6
- package/src/route.ts +45 -48
- package/src/stream.ts +1 -7
- package/src/taser-app.ts +13 -18
- package/src/taser-router.ts +103 -98
- package/src/types/app.ts +33 -35
- package/src/types/index.ts +403 -731
- package/src/types/returns.ts +92 -97
- package/src/types/schema.ts +8 -9
- package/src/types/type-utils.ts +42 -45
- package/src/types/units.ts +140 -104
- package/dist/cjs/middleware/auth.cjs +0 -34
- package/dist/cjs/middleware/auth.cjs.map +0 -1
- package/dist/cjs/middleware/auth.d.cts +0 -9
- package/dist/esm/middleware/auth.d.ts +0 -9
- package/dist/esm/middleware/auth.js +0 -33
- package/dist/esm/middleware/auth.js.map +0 -1
- package/src/middleware/auth.ts +0 -51
package/src/route.ts
CHANGED
|
@@ -1,62 +1,59 @@
|
|
|
1
|
-
import type { StandardSchemaV1 } from
|
|
1
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
2
2
|
import {
|
|
3
3
|
collectReturnsFromDefinitions,
|
|
4
4
|
hasInputSchemas,
|
|
5
5
|
mergeReturnsMaps,
|
|
6
6
|
withAuto422,
|
|
7
|
-
} from
|
|
7
|
+
} from "@taserjs/router-utils";
|
|
8
8
|
|
|
9
|
-
import type { Method, RouteBuilder, RoutePath, ReturnsMap, ValidatorParts } from
|
|
10
|
-
import type { HttpMethod, MiddlewareDefinition } from
|
|
11
|
-
import { isHandlerUnit } from
|
|
12
|
-
import { HANDLER_SCHEMA_KEY_MAP } from
|
|
13
|
-
import {
|
|
14
|
-
pickDefinedSchemas,
|
|
15
|
-
type SchemaValidators,
|
|
16
|
-
} from './define/validators.js'
|
|
9
|
+
import type { Method, RouteBuilder, RoutePath, ReturnsMap, ValidatorParts } from "./types/index.js";
|
|
10
|
+
import type { HttpMethod, MiddlewareDefinition } from "./types/units.js";
|
|
11
|
+
import { isHandlerUnit } from "./types/units.js";
|
|
12
|
+
import { HANDLER_SCHEMA_KEY_MAP } from "./constants.js";
|
|
13
|
+
import { pickDefinedSchemas, type SchemaValidators } from "./define/validators.js";
|
|
17
14
|
|
|
18
15
|
function toUtilsMap(map: ReturnsMap | undefined): Record<number, StandardSchemaV1> {
|
|
19
16
|
if (!map) {
|
|
20
|
-
return {}
|
|
17
|
+
return {};
|
|
21
18
|
}
|
|
22
|
-
const out: Record<number, StandardSchemaV1> = {}
|
|
19
|
+
const out: Record<number, StandardSchemaV1> = {};
|
|
23
20
|
for (const [key, schema] of Object.entries(map)) {
|
|
24
21
|
if (schema !== undefined) {
|
|
25
|
-
out[Number(key)] = schema
|
|
22
|
+
out[Number(key)] = schema;
|
|
26
23
|
}
|
|
27
24
|
}
|
|
28
|
-
return out
|
|
25
|
+
return out;
|
|
29
26
|
}
|
|
30
27
|
|
|
31
28
|
function buildEffectiveReturns(args: {
|
|
32
|
-
middlewareReturns: ReturnsMap
|
|
33
|
-
routeReturns: ReturnsMap
|
|
34
|
-
handlerMiddlewareReturns: ReturnsMap
|
|
35
|
-
handlerReturns: ReturnsMap | undefined
|
|
29
|
+
middlewareReturns: ReturnsMap;
|
|
30
|
+
routeReturns: ReturnsMap;
|
|
31
|
+
handlerMiddlewareReturns: ReturnsMap;
|
|
32
|
+
handlerReturns: ReturnsMap | undefined;
|
|
36
33
|
schemas: {
|
|
37
|
-
query?: unknown
|
|
38
|
-
params?: unknown
|
|
39
|
-
body?: unknown
|
|
40
|
-
handlerQuery?: unknown
|
|
41
|
-
handlerParams?: unknown
|
|
42
|
-
handlerBody?: unknown
|
|
43
|
-
middlewares?: readonly MiddlewareDefinition[]
|
|
44
|
-
handlerMiddlewares?: readonly MiddlewareDefinition[]
|
|
45
|
-
}
|
|
34
|
+
query?: unknown;
|
|
35
|
+
params?: unknown;
|
|
36
|
+
body?: unknown;
|
|
37
|
+
handlerQuery?: unknown;
|
|
38
|
+
handlerParams?: unknown;
|
|
39
|
+
handlerBody?: unknown;
|
|
40
|
+
middlewares?: readonly MiddlewareDefinition[];
|
|
41
|
+
handlerMiddlewares?: readonly MiddlewareDefinition[];
|
|
42
|
+
};
|
|
46
43
|
}): Record<number, StandardSchemaV1> | undefined {
|
|
47
44
|
const merged = mergeReturnsMaps(
|
|
48
45
|
toUtilsMap(args.middlewareReturns),
|
|
49
46
|
toUtilsMap(args.routeReturns),
|
|
50
47
|
toUtilsMap(args.handlerMiddlewareReturns),
|
|
51
48
|
toUtilsMap(args.handlerReturns),
|
|
52
|
-
)
|
|
53
|
-
const with422 = withAuto422(merged, hasInputSchemas(args.schemas))
|
|
54
|
-
return Object.keys(with422).length > 0 ? with422 : undefined
|
|
49
|
+
);
|
|
50
|
+
const with422 = withAuto422(merged, hasInputSchemas(args.schemas));
|
|
51
|
+
return Object.keys(with422).length > 0 ? with422 : undefined;
|
|
55
52
|
}
|
|
56
53
|
|
|
57
54
|
function buildRouteBase(
|
|
58
55
|
path: string,
|
|
59
|
-
method: HttpMethod |
|
|
56
|
+
method: HttpMethod | "ANY" | "ALL",
|
|
60
57
|
methods: readonly HttpMethod[] | undefined,
|
|
61
58
|
middlewares: MiddlewareDefinition[],
|
|
62
59
|
) {
|
|
@@ -65,36 +62,36 @@ function buildRouteBase(
|
|
|
65
62
|
method,
|
|
66
63
|
...(methods ? { methods: [...methods] } : {}),
|
|
67
64
|
middlewares: [...middlewares],
|
|
68
|
-
}
|
|
65
|
+
};
|
|
69
66
|
}
|
|
70
67
|
|
|
71
68
|
/** Shared internal builder — not part of the public `@taserjs/router` API. */
|
|
72
69
|
export function createRouteBuilder(
|
|
73
70
|
path: string,
|
|
74
|
-
method: HttpMethod |
|
|
71
|
+
method: HttpMethod | "ANY" | "ALL",
|
|
75
72
|
validators: SchemaValidators = {},
|
|
76
73
|
methods?: readonly HttpMethod[],
|
|
77
74
|
): RouteBuilder<RoutePath, Method, readonly [], ValidatorParts> {
|
|
78
|
-
const middlewares: MiddlewareDefinition[] = []
|
|
79
|
-
let routeReturns: Record<number, StandardSchemaV1> = {}
|
|
75
|
+
const middlewares: MiddlewareDefinition[] = [];
|
|
76
|
+
let routeReturns: Record<number, StandardSchemaV1> = {};
|
|
80
77
|
|
|
81
78
|
const builder = {
|
|
82
79
|
path,
|
|
83
80
|
method,
|
|
84
81
|
returns(map: ReturnsMap) {
|
|
85
|
-
routeReturns = { ...routeReturns, ...toUtilsMap(map) }
|
|
86
|
-
return builder
|
|
82
|
+
routeReturns = { ...routeReturns, ...toUtilsMap(map) };
|
|
83
|
+
return builder;
|
|
87
84
|
},
|
|
88
85
|
use(definition: MiddlewareDefinition) {
|
|
89
|
-
middlewares.push(definition)
|
|
90
|
-
return builder
|
|
86
|
+
middlewares.push(definition);
|
|
87
|
+
return builder;
|
|
91
88
|
},
|
|
92
89
|
handler(fnOrUnit: ((ctx: unknown) => unknown) | unknown) {
|
|
93
|
-
const routeSchemas = pickDefinedSchemas(validators)
|
|
94
|
-
const base = buildRouteBase(path, method, methods, middlewares)
|
|
90
|
+
const routeSchemas = pickDefinedSchemas(validators);
|
|
91
|
+
const base = buildRouteBase(path, method, methods, middlewares);
|
|
95
92
|
|
|
96
93
|
if (isHandlerUnit(fnOrUnit)) {
|
|
97
|
-
const handlerSchemas = pickDefinedSchemas(fnOrUnit, HANDLER_SCHEMA_KEY_MAP)
|
|
94
|
+
const handlerSchemas = pickDefinedSchemas(fnOrUnit, HANDLER_SCHEMA_KEY_MAP);
|
|
98
95
|
const returns = buildEffectiveReturns({
|
|
99
96
|
middlewareReturns: collectReturnsFromDefinitions(middlewares),
|
|
100
97
|
routeReturns: routeReturns,
|
|
@@ -108,7 +105,7 @@ export function createRouteBuilder(
|
|
|
108
105
|
middlewares,
|
|
109
106
|
handlerMiddlewares: fnOrUnit.middlewares,
|
|
110
107
|
},
|
|
111
|
-
})
|
|
108
|
+
});
|
|
112
109
|
|
|
113
110
|
return {
|
|
114
111
|
...base,
|
|
@@ -117,7 +114,7 @@ export function createRouteBuilder(
|
|
|
117
114
|
...routeSchemas,
|
|
118
115
|
...handlerSchemas,
|
|
119
116
|
...(returns ? { returns } : {}),
|
|
120
|
-
}
|
|
117
|
+
};
|
|
121
118
|
}
|
|
122
119
|
|
|
123
120
|
const returns = buildEffectiveReturns({
|
|
@@ -129,7 +126,7 @@ export function createRouteBuilder(
|
|
|
129
126
|
...validators,
|
|
130
127
|
middlewares,
|
|
131
128
|
},
|
|
132
|
-
})
|
|
129
|
+
});
|
|
133
130
|
|
|
134
131
|
return {
|
|
135
132
|
...base,
|
|
@@ -137,9 +134,9 @@ export function createRouteBuilder(
|
|
|
137
134
|
handler: fnOrUnit as (ctx: unknown) => Response | Promise<Response>,
|
|
138
135
|
...routeSchemas,
|
|
139
136
|
...(returns ? { returns } : {}),
|
|
140
|
-
}
|
|
137
|
+
};
|
|
141
138
|
},
|
|
142
|
-
}
|
|
139
|
+
};
|
|
143
140
|
|
|
144
|
-
return builder as unknown as RouteBuilder<RoutePath, Method, readonly [], ValidatorParts
|
|
141
|
+
return builder as unknown as RouteBuilder<RoutePath, Method, readonly [], ValidatorParts>;
|
|
145
142
|
}
|
package/src/stream.ts
CHANGED
package/src/taser-app.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import type { TaserRuntime } from
|
|
2
|
-
import type { RouteManifestShape } from
|
|
1
|
+
import type { TaserRuntime } from "@taserjs/router-core";
|
|
2
|
+
import type { RouteManifestShape } from "@taserjs/router-core";
|
|
3
3
|
|
|
4
4
|
class TaserServeView {
|
|
5
|
-
constructor(protected readonly runtime: TaserRuntime) {
|
|
5
|
+
constructor(protected readonly runtime: TaserRuntime) {}
|
|
6
6
|
|
|
7
7
|
fetch(request: Request, env?: unknown, executionCtx?: unknown): Promise<Response> {
|
|
8
|
-
return this.runtime.fetch(request, env, executionCtx as never)
|
|
8
|
+
return this.runtime.fetch(request, env, executionCtx as never);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
native(native: unknown): TaserNativeBound {
|
|
12
|
-
return new TaserNativeBound(this.runtime, native)
|
|
12
|
+
return new TaserNativeBound(this.runtime, native);
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
|
|
@@ -17,27 +17,22 @@ export class TaserNativeBound {
|
|
|
17
17
|
constructor(
|
|
18
18
|
private readonly runtime: TaserRuntime,
|
|
19
19
|
private readonly boundNative: unknown,
|
|
20
|
-
) {
|
|
20
|
+
) {}
|
|
21
21
|
|
|
22
22
|
fetch(request: Request, env?: unknown, executionCtx?: unknown): Promise<Response> {
|
|
23
|
-
return this.runtime.native(this.boundNative).fetch(request, env, executionCtx as never)
|
|
23
|
+
return this.runtime.native(this.boundNative).fetch(request, env, executionCtx as never);
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
export class
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
readonly __manifest?: TManifest
|
|
27
|
+
export class TaserApp<
|
|
28
|
+
TManifest extends RouteManifestShape = RouteManifestShape,
|
|
29
|
+
> extends TaserServeView {
|
|
30
|
+
readonly __manifest?: TManifest;
|
|
31
31
|
|
|
32
32
|
constructor(runtime: TaserRuntime, manifest?: TManifest) {
|
|
33
|
-
super(runtime)
|
|
33
|
+
super(runtime);
|
|
34
34
|
if (manifest !== undefined) {
|
|
35
|
-
this.__manifest = manifest
|
|
35
|
+
this.__manifest = manifest;
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
base(prefix: string): TaserMountedApp {
|
|
40
|
-
this.runtime.registerRoutePrefix(prefix)
|
|
41
|
-
return new TaserMountedApp(this.runtime)
|
|
42
|
-
}
|
|
43
38
|
}
|
package/src/taser-router.ts
CHANGED
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
type NotFoundHandler,
|
|
4
4
|
type OnErrorHandler,
|
|
5
5
|
type RouteManifestShape,
|
|
6
|
-
} from
|
|
7
|
-
import { normalizeOnError } from
|
|
6
|
+
} from "@taserjs/router-core";
|
|
7
|
+
import { normalizeOnError } from "@taserjs/router-utils";
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
10
|
createAllRoute,
|
|
@@ -16,145 +16,150 @@ import {
|
|
|
16
16
|
createPatchRoute,
|
|
17
17
|
createPostRoute,
|
|
18
18
|
createPutRoute,
|
|
19
|
-
} from
|
|
20
|
-
import { defineHandler } from
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import type {
|
|
25
|
-
|
|
26
|
-
|
|
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'
|
|
19
|
+
} from "./factories.js";
|
|
20
|
+
import { defineHandler } from "./define/handler.js";
|
|
21
|
+
import { createMiddleware } from "./middleware.js";
|
|
22
|
+
import { TaserApp } from "./taser-app.js";
|
|
23
|
+
import type { ContextDefinition, CreateTaserAppOptions, OnErrorOptions } from "./types/app.js";
|
|
24
|
+
import type { AppContext } from "./types/units.js";
|
|
25
|
+
import type { HandlerBuilder, LayoutId, MiddlewareBuilder } from "./types/index.js";
|
|
26
|
+
import type { Schema } from "./types/schema.js";
|
|
32
27
|
import type {
|
|
33
28
|
CreateAllRoute,
|
|
34
29
|
CreateAnyRoute,
|
|
35
30
|
CreateWithBodyRoute,
|
|
36
31
|
CreateWithoutBodyRoute,
|
|
37
|
-
} from
|
|
32
|
+
} from "./factories.js";
|
|
38
33
|
|
|
39
34
|
function toOnErrorHandler(
|
|
40
|
-
onErrorOptions: OnErrorOptions | OnErrorOptions[
|
|
35
|
+
onErrorOptions: OnErrorOptions | OnErrorOptions["handle"],
|
|
41
36
|
): OnErrorHandler {
|
|
42
|
-
return normalizeOnError(onErrorOptions)
|
|
37
|
+
return normalizeOnError(onErrorOptions);
|
|
43
38
|
}
|
|
44
39
|
|
|
45
40
|
type RouterState = {
|
|
46
|
-
options: CreateTaserAppOptions
|
|
47
|
-
contextDef: ContextDefinition<Record<string, unknown>, Record<string, unknown
|
|
48
|
-
onError?: OnErrorHandler
|
|
49
|
-
notFound?: NotFoundHandler
|
|
50
|
-
}
|
|
41
|
+
options: CreateTaserAppOptions;
|
|
42
|
+
contextDef: ContextDefinition<Record<string, unknown>, Record<string, unknown>>;
|
|
43
|
+
onError?: OnErrorHandler;
|
|
44
|
+
notFound?: NotFoundHandler;
|
|
45
|
+
};
|
|
51
46
|
|
|
52
|
-
const emptyContext: ContextDefinition<Record<string, unknown>, Record<string, unknown>> = {}
|
|
47
|
+
const emptyContext: ContextDefinition<Record<string, unknown>, Record<string, unknown>> = {};
|
|
53
48
|
|
|
54
49
|
export class TaserRouter<TAppContext extends Record<string, unknown> = AppContext> {
|
|
55
|
-
private readonly state: RouterState
|
|
50
|
+
private readonly state: RouterState;
|
|
56
51
|
|
|
57
|
-
constructor(options: CreateTaserAppOptions = {}, state?: Partial<Omit<RouterState,
|
|
52
|
+
constructor(options: CreateTaserAppOptions = {}, state?: Partial<Omit<RouterState, "options">>) {
|
|
58
53
|
this.state = {
|
|
59
54
|
options,
|
|
60
55
|
contextDef: state?.contextDef ?? emptyContext,
|
|
61
56
|
...(state?.onError !== undefined ? { onError: state.onError } : {}),
|
|
62
57
|
...(state?.notFound !== undefined ? { notFound: state.notFound } : {}),
|
|
63
|
-
}
|
|
58
|
+
};
|
|
64
59
|
}
|
|
65
60
|
|
|
66
|
-
context<
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
this
|
|
71
|
-
return this as unknown as TaserRouter<TBoot & TReq>
|
|
61
|
+
context<TBoot extends Record<string, unknown>, TReq extends Record<string, unknown>>(
|
|
62
|
+
definition: ContextDefinition<TBoot, TReq>,
|
|
63
|
+
): TaserRouter<TBoot & TReq> {
|
|
64
|
+
this.state.contextDef = definition;
|
|
65
|
+
return this as unknown as TaserRouter<TBoot & TReq>;
|
|
72
66
|
}
|
|
73
67
|
|
|
74
|
-
onError<
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
68
|
+
onError<
|
|
69
|
+
TResponses extends import("./types/returns.js").ReturnsMap =
|
|
70
|
+
import("./types/returns.js").ReturnsMap,
|
|
71
|
+
>(options: OnErrorOptions<TResponses> | OnErrorOptions<TResponses>["handle"]): this {
|
|
72
|
+
this.state.onError = toOnErrorHandler(options);
|
|
73
|
+
return this;
|
|
79
74
|
}
|
|
80
75
|
|
|
81
|
-
notFound(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
this.state.notFound = ctx => handler(ctx)
|
|
85
|
-
return this
|
|
76
|
+
notFound(handler: (ctx: unknown) => Response | Promise<Response> | unknown): this {
|
|
77
|
+
this.state.notFound = (ctx) => handler(ctx);
|
|
78
|
+
return this;
|
|
86
79
|
}
|
|
87
80
|
|
|
88
|
-
get: CreateWithoutBodyRoute<
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
81
|
+
get: CreateWithoutBodyRoute<"GET", TAppContext> = createGetRoute as CreateWithoutBodyRoute<
|
|
82
|
+
"GET",
|
|
83
|
+
TAppContext
|
|
84
|
+
>;
|
|
85
|
+
post: CreateWithBodyRoute<"POST", TAppContext> = createPostRoute as CreateWithBodyRoute<
|
|
86
|
+
"POST",
|
|
87
|
+
TAppContext
|
|
88
|
+
>;
|
|
89
|
+
put: CreateWithBodyRoute<"PUT", TAppContext> = createPutRoute as CreateWithBodyRoute<
|
|
90
|
+
"PUT",
|
|
91
|
+
TAppContext
|
|
92
|
+
>;
|
|
93
|
+
patch: CreateWithBodyRoute<"PATCH", TAppContext> = createPatchRoute as CreateWithBodyRoute<
|
|
94
|
+
"PATCH",
|
|
95
|
+
TAppContext
|
|
96
|
+
>;
|
|
97
|
+
delete: CreateWithoutBodyRoute<"DELETE", TAppContext> =
|
|
98
|
+
createDeleteRoute as CreateWithoutBodyRoute<"DELETE", TAppContext>;
|
|
99
|
+
options: CreateWithoutBodyRoute<"OPTIONS", TAppContext> =
|
|
100
|
+
createOptionsRoute as CreateWithoutBodyRoute<"OPTIONS", TAppContext>;
|
|
101
|
+
head: CreateWithoutBodyRoute<"HEAD", TAppContext> = createHeadRoute as CreateWithoutBodyRoute<
|
|
102
|
+
"HEAD",
|
|
103
|
+
TAppContext
|
|
104
|
+
>;
|
|
105
|
+
any: CreateAnyRoute<TAppContext> = createAnyRoute as CreateAnyRoute<TAppContext>;
|
|
106
|
+
all: CreateAllRoute<TAppContext> = createAllRoute as CreateAllRoute<TAppContext>;
|
|
107
|
+
|
|
108
|
+
middleware<const Layout extends LayoutId>(
|
|
109
|
+
layout: Layout,
|
|
110
|
+
): MiddlewareBuilder<Layout, readonly [], TAppContext> {
|
|
111
|
+
return createMiddleware(layout) as MiddlewareBuilder<Layout, readonly [], TAppContext>;
|
|
100
112
|
}
|
|
101
113
|
|
|
102
|
-
defineHandler<
|
|
103
|
-
TQuery
|
|
104
|
-
TParams
|
|
105
|
-
TBody
|
|
106
|
-
|
|
107
|
-
options?: {
|
|
108
|
-
query?: Schema<TQuery>
|
|
109
|
-
params?: Schema<TParams>
|
|
110
|
-
body?: Schema<TBody>
|
|
111
|
-
},
|
|
112
|
-
): HandlerBuilder<
|
|
114
|
+
defineHandler<TQuery = unknown, TParams = unknown, TBody = unknown>(options?: {
|
|
115
|
+
query?: Schema<TQuery>;
|
|
116
|
+
params?: Schema<TParams>;
|
|
117
|
+
body?: Schema<TBody>;
|
|
118
|
+
}): HandlerBuilder<
|
|
113
119
|
readonly [],
|
|
114
|
-
{ query: TQuery
|
|
120
|
+
{ query: TQuery; params: TParams; body: TBody },
|
|
115
121
|
{},
|
|
116
122
|
TAppContext
|
|
117
123
|
> {
|
|
118
124
|
return options === undefined
|
|
119
125
|
? defineHandler<TAppContext>()
|
|
120
|
-
: defineHandler<TAppContext>(options)
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
defineMiddleware(): ReturnType<typeof defineMiddleware<TAppContext>> {
|
|
124
|
-
return defineMiddleware<TAppContext>()
|
|
126
|
+
: defineHandler<TAppContext>(options);
|
|
125
127
|
}
|
|
126
128
|
|
|
127
129
|
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
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
...(
|
|
130
|
+
const definition = this.state.contextDef;
|
|
131
|
+
const validateResponse = this.state.options.response?.validate ?? true;
|
|
132
|
+
const onValidationFailure = this.state.options.response?.onValidationFailure;
|
|
133
|
+
const basePath = this.state.options.basePath;
|
|
134
|
+
|
|
135
|
+
const hasCustomContext = definition.boot !== undefined || definition.request !== undefined;
|
|
136
|
+
const bootPromise = hasCustomContext
|
|
137
|
+
? Promise.resolve(definition.boot?.() ?? ({} as Record<string, unknown>))
|
|
138
|
+
: undefined;
|
|
139
|
+
|
|
140
|
+
const contextFactory = hasCustomContext
|
|
141
|
+
? async ({ native }: { native?: unknown } = {}) => {
|
|
142
|
+
const bootContext = (await bootPromise) ?? {};
|
|
143
|
+
const requestContext = (await definition.request?.({ native: native as never })) ?? {};
|
|
144
|
+
return { ...bootContext, ...requestContext };
|
|
145
|
+
}
|
|
146
|
+
: () => ({});
|
|
147
|
+
|
|
148
|
+
const runtime = createTaserRuntime(manifest, contextFactory, {
|
|
149
|
+
...(basePath !== undefined ? { basePath } : {}),
|
|
150
|
+
response: {
|
|
151
|
+
validate: validateResponse,
|
|
152
|
+
...(onValidationFailure !== undefined ? { onValidationFailure } : {}),
|
|
151
153
|
},
|
|
152
|
-
|
|
154
|
+
...(this.state.onError !== undefined ? { onError: this.state.onError } : {}),
|
|
155
|
+
...(this.state.notFound !== undefined ? { notFound: this.state.notFound } : {}),
|
|
156
|
+
...(this.state.options.cookies !== undefined ? { cookies: this.state.options.cookies } : {}),
|
|
157
|
+
});
|
|
153
158
|
|
|
154
|
-
return new TaserApp(runtime, manifest)
|
|
159
|
+
return new TaserApp(runtime, manifest);
|
|
155
160
|
}
|
|
156
161
|
}
|
|
157
162
|
|
|
158
163
|
export function createTaserApp(options: CreateTaserAppOptions = {}): TaserRouter {
|
|
159
|
-
return new TaserRouter(options)
|
|
164
|
+
return new TaserRouter(options);
|
|
160
165
|
}
|
package/src/types/app.ts
CHANGED
|
@@ -1,53 +1,51 @@
|
|
|
1
|
-
import type { ResponseValidationFailureHandler } from
|
|
1
|
+
import type { ResponseValidationFailureHandler } from "@taserjs/router-utils";
|
|
2
2
|
|
|
3
|
-
import type { TaserApp } from
|
|
4
|
-
import type { ReturnsMap } from
|
|
5
|
-
import type { Schema } from
|
|
3
|
+
import type { TaserApp } from "../taser-app.js";
|
|
4
|
+
import type { ReturnsMap } from "./returns.js";
|
|
5
|
+
import type { Schema } from "./schema.js";
|
|
6
6
|
|
|
7
7
|
export type CreateTaserAppOptions = {
|
|
8
|
+
basePath?: string;
|
|
8
9
|
response?: {
|
|
9
10
|
/** Validate handler replies against returns maps. Default true. */
|
|
10
|
-
validate?: boolean
|
|
11
|
-
onValidationFailure?: ResponseValidationFailureHandler
|
|
12
|
-
}
|
|
11
|
+
validate?: boolean;
|
|
12
|
+
onValidationFailure?: ResponseValidationFailureHandler;
|
|
13
|
+
};
|
|
13
14
|
/** Global cookie defaults and signing secret. Per-call `ctx.cookies.set` options override defaults. */
|
|
14
15
|
cookies?: {
|
|
15
|
-
secret?: string | BufferSource
|
|
16
|
-
path?: string
|
|
17
|
-
httpOnly?: boolean
|
|
18
|
-
sameSite?:
|
|
19
|
-
secure?: boolean
|
|
20
|
-
domain?: string
|
|
21
|
-
maxAge?: number
|
|
22
|
-
expires?: Date
|
|
23
|
-
}
|
|
24
|
-
}
|
|
16
|
+
secret?: string | BufferSource;
|
|
17
|
+
path?: string;
|
|
18
|
+
httpOnly?: boolean;
|
|
19
|
+
sameSite?: "Strict" | "Lax" | "None" | "strict" | "lax" | "none";
|
|
20
|
+
secure?: boolean;
|
|
21
|
+
domain?: string;
|
|
22
|
+
maxAge?: number;
|
|
23
|
+
expires?: Date;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
25
26
|
|
|
26
27
|
export type CreateContextArgs = {
|
|
27
|
-
native?: import(
|
|
28
|
-
}
|
|
28
|
+
native?: import("./units.js").NativeContext;
|
|
29
|
+
};
|
|
29
30
|
|
|
30
31
|
export type ContextDefinition<
|
|
31
32
|
TBoot extends Record<string, unknown> = Record<string, never>,
|
|
32
33
|
TReq extends Record<string, unknown> = Record<string, never>,
|
|
33
34
|
> = {
|
|
34
|
-
boot?: () => TBoot | Promise<TBoot
|
|
35
|
-
request?: (args: CreateContextArgs) => TReq | Promise<TReq
|
|
36
|
-
}
|
|
35
|
+
boot?: () => TBoot | Promise<TBoot>;
|
|
36
|
+
request?: (args: CreateContextArgs) => TReq | Promise<TReq>;
|
|
37
|
+
};
|
|
37
38
|
|
|
38
39
|
export type InferAppContext<
|
|
39
40
|
T extends ContextDefinition<Record<string, unknown>, Record<string, unknown>>,
|
|
40
|
-
> = T extends ContextDefinition<infer TBoot, infer TReq> ? TBoot & TReq : Record<string, never
|
|
41
|
+
> = T extends ContextDefinition<infer TBoot, infer TReq> ? TBoot & TReq : Record<string, never>;
|
|
41
42
|
|
|
42
43
|
export type OnErrorOptions<TResponses extends ReturnsMap = ReturnsMap> = {
|
|
43
|
-
responses?: TResponses
|
|
44
|
-
handle: (
|
|
45
|
-
|
|
46
|
-
ctx?: unknown,
|
|
47
|
-
) => Response | Promise<Response>
|
|
48
|
-
}
|
|
44
|
+
responses?: TResponses;
|
|
45
|
+
handle: (error: unknown, ctx?: unknown) => Response | Promise<Response>;
|
|
46
|
+
};
|
|
49
47
|
|
|
50
|
-
export type InferAppManifest<TApp> = TApp extends TaserApp<infer TManifest> ? TManifest : never
|
|
48
|
+
export type InferAppManifest<TApp> = TApp extends TaserApp<infer TManifest> ? TManifest : never;
|
|
51
49
|
|
|
52
50
|
export type TaserHandler<TFrameworkApp> = {
|
|
53
51
|
/**
|
|
@@ -55,11 +53,11 @@ export type TaserHandler<TFrameworkApp> = {
|
|
|
55
53
|
* Use universal wildcard patterns (`/*`, `/prefix/*`) for Hono/Fastify.
|
|
56
54
|
* Use framework-native splat patterns for Express (e.g. `/{*splat}`, `/*splat`).
|
|
57
55
|
*/
|
|
58
|
-
mount(pattern: string, frameworkApp: TFrameworkApp): void
|
|
59
|
-
}
|
|
56
|
+
mount(pattern: string, frameworkApp: TFrameworkApp): void;
|
|
57
|
+
};
|
|
60
58
|
|
|
61
|
-
export type { RouteManifestShape } from
|
|
59
|
+
export type { RouteManifestShape } from "@taserjs/router-core";
|
|
62
60
|
|
|
63
|
-
export type { Schema }
|
|
61
|
+
export type { Schema };
|
|
64
62
|
|
|
65
|
-
export type { TaserApp,
|
|
63
|
+
export type { TaserApp, TaserNativeBound } from "../taser-app.js";
|