@taserjs/router 0.1.7 → 0.1.8
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/dist/cjs/define/middleware.cjs.map +1 -1
- package/dist/cjs/define/middleware.d.cts +17 -17
- package/dist/cjs/index.d.cts +5 -1
- package/dist/cjs/middleware/hono-mw.cjs.map +1 -1
- package/dist/cjs/middleware/hono-mw.d.cts +2 -1
- package/dist/cjs/types/index.d.cts +43 -54
- package/dist/cjs/types/type-utils.d.cts +3 -3
- package/dist/cjs/types/units.d.cts +4 -4
- package/dist/esm/define/middleware.d.ts +17 -17
- package/dist/esm/define/middleware.js.map +1 -1
- package/dist/esm/index.d.ts +5 -1
- package/dist/esm/middleware/hono-mw.d.ts +2 -1
- package/dist/esm/middleware/hono-mw.js.map +1 -1
- package/dist/esm/types/index.d.ts +43 -54
- package/dist/esm/types/type-utils.d.ts +3 -3
- package/dist/esm/types/units.d.ts +4 -4
- package/package.json +3 -3
- package/src/define/middleware.ts +56 -56
- package/src/index.ts +3 -0
- package/src/middleware/hono-mw.ts +5 -3
- package/src/types/index.ts +74 -90
- package/src/types/type-utils.ts +1 -1
- package/src/types/units.ts +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.cjs","names":[],"sources":["../../../src/define/middleware.ts"],"sourcesContent":["import { createMiddlewareUnitBuilder } from \"../builder/middleware-unit.js\";\nimport type {\n DefineMiddlewareResult,\n ExtractState,\n IsUnknown,\n MiddlewareRequirements,\n MiddlewareUnitBuilder,\n NextFn,\n StandaloneMiddlewareContext,\n} from \"../types/units.js\";\nimport type {\n AppContext,\n LayoutId,\n ResolveLayoutMiddlewaresState,\n ResolveLayoutsState,\n} from \"../types/index.js\";\n\nexport interface MiddlewareFn<TAppContext extends Record<string, unknown> = AppContext> {\n /**\n *
|
|
1
|
+
{"version":3,"file":"middleware.cjs","names":[],"sources":["../../../src/define/middleware.ts"],"sourcesContent":["import { createMiddlewareUnitBuilder } from \"../builder/middleware-unit.js\";\nimport type {\n DefineMiddlewareResult,\n ExtractState,\n IsUnknown,\n MiddlewareRequirements,\n MiddlewareUnitBuilder,\n NextFn,\n StandaloneMiddlewareContext,\n} from \"../types/units.js\";\nimport type {\n AppContext,\n LayoutId,\n ResolveLayoutMiddlewaresState,\n ResolveLayoutsState,\n} from \"../types/index.js\";\n\nexport interface MiddlewareFn<TAppContext extends Record<string, unknown> = AppContext> {\n /**\n * Defines a standalone, unscoped middleware using a short function signature.\n *\n * @example\n * ```ts\n * const auth = middleware((ctx, next) => {\n * return next({ user: \"alice\" });\n * });\n * ```\n */\n <TState = unknown, TRequires extends MiddlewareRequirements = {}, R = unknown>(\n fn: (\n ctx: StandaloneMiddlewareContext<unknown, unknown, unknown, TAppContext, {}, TRequires>,\n next: NextFn<NoInfer<TState>>,\n ) => R,\n ): DefineMiddlewareResult<\n unknown,\n unknown,\n unknown,\n IsUnknown<TState> extends true ? ExtractState<R> : TState,\n R,\n unknown,\n unknown,\n unknown,\n {},\n null,\n TRequires\n >;\n\n /**\n * Constructs a fluent unscoped middleware builder, with optional explicit State generic.\n *\n * @example\n * ```ts\n * const auth = middleware<{ user: string }>()\n * .query(z.object({ token: z.string() }))\n * .body(\"form\", z.object({ file: z.instanceof(File) }))\n * .returns({ 401: z.string() })\n * .handler(async (ctx, next) => next({ user: \"alice\" }));\n * ```\n */\n <TState = unknown>(): MiddlewareUnitBuilder<\n unknown,\n unknown,\n unknown,\n {},\n null,\n {},\n TAppContext,\n {},\n unknown,\n unknown,\n unknown,\n TState\n >;\n\n /**\n * Defines a standalone middleware scoped to a single layout branch using a short function signature.\n */\n <\n const Layout extends LayoutId,\n TState = unknown,\n TRequires extends MiddlewareRequirements = {},\n R = unknown,\n >(\n layout: Layout,\n fn: (\n ctx: StandaloneMiddlewareContext<\n unknown,\n unknown,\n unknown,\n TAppContext,\n ResolveLayoutMiddlewaresState<Layout>,\n TRequires\n >,\n next: NextFn<NoInfer<TState>>,\n ) => R,\n ): DefineMiddlewareResult<\n unknown,\n unknown,\n unknown,\n IsUnknown<TState> extends true ? ExtractState<R> : TState,\n R,\n unknown,\n unknown,\n unknown,\n {},\n Layout,\n TRequires\n >;\n\n /**\n * Defines a standalone middleware scoped to multiple layout branches using a short function signature.\n */\n <\n const Layouts extends readonly [LayoutId, ...LayoutId[]],\n TState = unknown,\n TRequires extends MiddlewareRequirements = {},\n R = unknown,\n >(\n layouts: Layouts,\n fn: (\n ctx: StandaloneMiddlewareContext<\n unknown,\n unknown,\n unknown,\n TAppContext,\n ResolveLayoutsState<Layouts>,\n TRequires\n >,\n next: NextFn<NoInfer<TState>>,\n ) => R,\n ): DefineMiddlewareResult<\n unknown,\n unknown,\n unknown,\n IsUnknown<TState> extends true ? ExtractState<R> : TState,\n R,\n unknown,\n unknown,\n unknown,\n {},\n Layouts,\n TRequires\n >;\n\n /**\n * Constructs a fluent middleware builder scoped to a single layout branch, with optional explicit State generic.\n */\n <const Layout extends LayoutId, TState = unknown>(\n layout: Layout,\n ): MiddlewareUnitBuilder<\n unknown,\n unknown,\n unknown,\n {},\n Layout,\n {},\n TAppContext,\n ResolveLayoutMiddlewaresState<Layout>,\n unknown,\n unknown,\n unknown,\n TState\n >;\n\n /**\n * Constructs a fluent middleware builder scoped to multiple layout branches (branch union), with optional explicit State generic.\n */\n <const Layouts extends readonly [LayoutId, ...LayoutId[]], TState = unknown>(\n layouts: Layouts,\n ): MiddlewareUnitBuilder<\n unknown,\n unknown,\n unknown,\n {},\n Layouts,\n {},\n TAppContext,\n ResolveLayoutsState<Layouts>,\n unknown,\n unknown,\n unknown,\n TState\n >;\n}\n\nexport const middleware: MiddlewareFn<AppContext> = function middleware(\n first?: any,\n second?: any,\n): any {\n if (first === undefined) {\n return createMiddlewareUnitBuilder();\n }\n\n if (typeof first === \"string\" || Array.isArray(first)) {\n if (typeof second === \"function\") {\n return {\n handler: second,\n __middlewareAcc: undefined as unknown,\n __requiredLayouts: first,\n };\n }\n return createMiddlewareUnitBuilder(first);\n }\n\n if (typeof first === \"function\") {\n return {\n handler: first,\n __middlewareAcc: undefined as unknown,\n };\n }\n\n return createMiddlewareUnitBuilder();\n};\n"],"mappings":";;AAyLA,IAAa,aAAuC,SAAS,WAC3D,OACA,QACK;CACL,IAAI,UAAU,KAAA,GACZ,OAAO,wBAAA,4BAA4B;CAGrC,IAAI,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;EACrD,IAAI,OAAO,WAAW,YACpB,OAAO;GACL,SAAS;GACT,iBAAiB,KAAA;GACjB,mBAAmB;EACrB;EAEF,OAAO,wBAAA,4BAA4B,KAAK;CAC1C;CAEA,IAAI,OAAO,UAAU,YACnB,OAAO;EACL,SAAS;EACT,iBAAiB,KAAA;CACnB;CAGF,OAAO,wBAAA,4BAA4B;AACrC"}
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { DefineMiddlewareResult, ExtractState, IsUnknown, MiddlewareRequirements, MiddlewareUnitBuilder, NextFn, StandaloneMiddlewareContext } from '../types/units.js';
|
|
2
2
|
import { AppContext, LayoutId, ResolveLayoutMiddlewaresState, ResolveLayoutsState } from '../types/index.js';
|
|
3
3
|
export interface MiddlewareFn<TAppContext extends Record<string, unknown> = AppContext> {
|
|
4
|
+
/**
|
|
5
|
+
* Defines a standalone, unscoped middleware using a short function signature.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const auth = middleware((ctx, next) => {
|
|
10
|
+
* return next({ user: "alice" });
|
|
11
|
+
* });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
<TState = unknown, TRequires extends MiddlewareRequirements = {}, R = unknown>(fn: (ctx: StandaloneMiddlewareContext<unknown, unknown, unknown, TAppContext, {}, TRequires>, next: NextFn<NoInfer<TState>>) => R): DefineMiddlewareResult<unknown, unknown, unknown, IsUnknown<TState> extends true ? ExtractState<R> : TState, R, unknown, unknown, unknown, {}, null, TRequires>;
|
|
4
15
|
/**
|
|
5
16
|
* Constructs a fluent unscoped middleware builder, with optional explicit State generic.
|
|
6
17
|
*
|
|
@@ -14,14 +25,6 @@ export interface MiddlewareFn<TAppContext extends Record<string, unknown> = AppC
|
|
|
14
25
|
* ```
|
|
15
26
|
*/
|
|
16
27
|
<TState = unknown>(): MiddlewareUnitBuilder<unknown, unknown, unknown, {}, null, {}, TAppContext, {}, unknown, unknown, unknown, TState>;
|
|
17
|
-
/**
|
|
18
|
-
* Constructs a fluent middleware builder scoped to a single layout branch, with optional explicit State generic.
|
|
19
|
-
*/
|
|
20
|
-
<const Layout extends LayoutId, TState = unknown>(layout: Layout): MiddlewareUnitBuilder<unknown, unknown, unknown, {}, Layout, {}, TAppContext, ResolveLayoutMiddlewaresState<Layout>, unknown, unknown, unknown, TState>;
|
|
21
|
-
/**
|
|
22
|
-
* Constructs a fluent middleware builder scoped to multiple layout branches (branch union), with optional explicit State generic.
|
|
23
|
-
*/
|
|
24
|
-
<const Layouts extends readonly [LayoutId, ...LayoutId[]], TState = unknown>(layouts: Layouts): MiddlewareUnitBuilder<unknown, unknown, unknown, {}, Layouts, {}, TAppContext, ResolveLayoutsState<Layouts>, unknown, unknown, unknown, TState>;
|
|
25
28
|
/**
|
|
26
29
|
* Defines a standalone middleware scoped to a single layout branch using a short function signature.
|
|
27
30
|
*/
|
|
@@ -31,15 +34,12 @@ export interface MiddlewareFn<TAppContext extends Record<string, unknown> = AppC
|
|
|
31
34
|
*/
|
|
32
35
|
<const Layouts extends readonly [LayoutId, ...LayoutId[]], TState = unknown, TRequires extends MiddlewareRequirements = {}, R = unknown>(layouts: Layouts, fn: (ctx: StandaloneMiddlewareContext<unknown, unknown, unknown, TAppContext, ResolveLayoutsState<Layouts>, TRequires>, next: NextFn<NoInfer<TState>>) => R): DefineMiddlewareResult<unknown, unknown, unknown, IsUnknown<TState> extends true ? ExtractState<R> : TState, R, unknown, unknown, unknown, {}, Layouts, TRequires>;
|
|
33
36
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* @example
|
|
37
|
-
* ```ts
|
|
38
|
-
* const auth = middleware((ctx, next) => {
|
|
39
|
-
* return next({ user: "alice" });
|
|
40
|
-
* });
|
|
41
|
-
* ```
|
|
37
|
+
* Constructs a fluent middleware builder scoped to a single layout branch, with optional explicit State generic.
|
|
42
38
|
*/
|
|
43
|
-
<
|
|
39
|
+
<const Layout extends LayoutId, TState = unknown>(layout: Layout): MiddlewareUnitBuilder<unknown, unknown, unknown, {}, Layout, {}, TAppContext, ResolveLayoutMiddlewaresState<Layout>, unknown, unknown, unknown, TState>;
|
|
40
|
+
/**
|
|
41
|
+
* Constructs a fluent middleware builder scoped to multiple layout branches (branch union), with optional explicit State generic.
|
|
42
|
+
*/
|
|
43
|
+
<const Layouts extends readonly [LayoutId, ...LayoutId[]], TState = unknown>(layouts: Layouts): MiddlewareUnitBuilder<unknown, unknown, unknown, {}, Layouts, {}, TAppContext, ResolveLayoutsState<Layouts>, unknown, unknown, unknown, TState>;
|
|
44
44
|
}
|
|
45
45
|
export declare const middleware: MiddlewareFn<AppContext>;
|
package/dist/cjs/index.d.cts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export interface RouterRegister {
|
|
2
2
|
}
|
|
3
|
-
export
|
|
3
|
+
export interface RouterMiddlewaresRegister {
|
|
4
|
+
}
|
|
5
|
+
export interface RouterRoutesRegister {
|
|
6
|
+
}
|
|
7
|
+
export type { AppContext, EmptyAppContext, HttpMethod, InferInput, InferOutput, InferRouteContext, InferRouteInput, InferRouteInputFromPath, InferRouteOutput, LayoutBuilder, LayoutId, LayoutMiddlewaresMap, LayoutTree, Method, MiddlewareBuilder, MiddlewareDefinition, MiddlewareUnit, MiddlewareUnitBuilder, PathParams, ReturnsMap, RouteByPathMethod, RouteDefinition, RouteExport, RoutePath, Schema, Simplify, StatusCode, } from './types/index.js';
|
|
4
8
|
export type { ContextDefinition, CreateTaserAppOptions, InferAppContext, InferAppManifest, OnErrorOptions, RouteManifestShape, } from './types/app.js';
|
|
5
9
|
export { ValidationError, validationErrorSchema } from '@taserjs/router-utils';
|
|
6
10
|
export type { ResponseValidationFailureHandler, SuccessStatusCode } from '@taserjs/router-utils';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hono-mw.cjs","names":[],"sources":["../../../src/middleware/hono-mw.ts"],"sourcesContent":["import { createTaserCompatHandler } from \"@taserjs/router-core\";\nimport type { MiddlewareHandler } from \"hono\";\n\n/**\n * Adapts a standard Web / Hono-compatible middleware function `(c, next) => ...`\n * into a Taser-compatible middleware handler function `(ctx, next) => Promise<Response>`.\n *\n * @example\n * ```ts\n * import { honoMw } from \"@taserjs/router\";\n * import { cors } from \"hono/cors\";\n *\n * const app = t.get(\"/hello\").use(honoMw(cors()));\n * // or\n * const customCors = middleware(honoMw(cors()));\n * ```\n */\nexport function honoMw(\n middleware: MiddlewareHandler,\n): (ctx: unknown, next:
|
|
1
|
+
{"version":3,"file":"hono-mw.cjs","names":[],"sources":["../../../src/middleware/hono-mw.ts"],"sourcesContent":["import { createTaserCompatHandler } from \"@taserjs/router-core\";\nimport type { MiddlewareHandler } from \"hono\";\n\nimport type { NextFn } from \"../types/units.js\";\n\n/**\n * Adapts a standard Web / Hono-compatible middleware function `(c, next) => ...`\n * into a Taser-compatible middleware handler function `(ctx, next) => Promise<Response>`.\n *\n * @example\n * ```ts\n * import { honoMw } from \"@taserjs/router\";\n * import { cors } from \"hono/cors\";\n *\n * const app = t.get(\"/hello\").use(honoMw(cors()));\n * // or\n * const customCors = middleware(honoMw(cors()));\n * ```\n */\nexport function honoMw<TState extends Record<string, unknown> = {}>(\n middleware: MiddlewareHandler,\n): (ctx: unknown, next: NextFn<TState>) => Promise<Response> {\n return createTaserCompatHandler(middleware) as (ctx: unknown, next: NextFn<TState>) => Promise<Response>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAmBA,SAAgB,OACd,YAC2D;CAC3D,QAAA,GAAA,qBAAA,yBAAA,CAAgC,UAAU;AAC5C"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MiddlewareHandler } from 'hono';
|
|
2
|
+
import { NextFn } from '../types/units.js';
|
|
2
3
|
/**
|
|
3
4
|
* Adapts a standard Web / Hono-compatible middleware function `(c, next) => ...`
|
|
4
5
|
* into a Taser-compatible middleware handler function `(ctx, next) => Promise<Response>`.
|
|
@@ -13,4 +14,4 @@ import { MiddlewareHandler } from 'hono';
|
|
|
13
14
|
* const customCors = middleware(honoMw(cors()));
|
|
14
15
|
* ```
|
|
15
16
|
*/
|
|
16
|
-
export declare function honoMw(middleware: MiddlewareHandler): (ctx: unknown, next:
|
|
17
|
+
export declare function honoMw<TState extends Record<string, unknown> = {}>(middleware: MiddlewareHandler): (ctx: unknown, next: NextFn<TState>) => Promise<Response>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Awaitable, TaserCookieJar, TaserHeaders } from '@taserjs/router-core';
|
|
2
|
-
import { RouterRegister } from '../index.js';
|
|
2
|
+
import { RouterMiddlewaresRegister, RouterRegister, RouterRoutesRegister } from '../index.js';
|
|
3
3
|
import { MergeMiddlewareField, MergeMiddlewareInputField, MergePart, RequestShape, Simplify, UnionToIntersection, UnitRuntimeContext } from './type-utils.js';
|
|
4
4
|
import { ReturnsMap, ValidHandlerReply } from './returns.js';
|
|
5
5
|
import { Schema } from './schema.js';
|
|
@@ -21,7 +21,14 @@ export type LayoutId = RouterRegister extends {
|
|
|
21
21
|
export type LayoutTree = RouterRegister extends {
|
|
22
22
|
LayoutTree: infer T;
|
|
23
23
|
} ? T : Record<never, never>;
|
|
24
|
-
export type
|
|
24
|
+
export type LayoutMiddlewaresMap = RouterMiddlewaresRegister extends {
|
|
25
|
+
LayoutMiddlewares: infer M;
|
|
26
|
+
} ? M : RouterRegister extends {
|
|
27
|
+
LayoutMiddlewares: infer M;
|
|
28
|
+
} ? M : Record<never, never>;
|
|
29
|
+
export type RouteByPathMethod = RouterRoutesRegister extends {
|
|
30
|
+
RouteByPathMethod: infer R;
|
|
31
|
+
} ? R : RouterRegister extends {
|
|
25
32
|
RouteByPathMethod: infer R;
|
|
26
33
|
} ? R : Record<never, never>;
|
|
27
34
|
export type LayoutBuilder<TAppContext extends Record<string, unknown> = AppContext> = <const Layout extends LayoutId>(layout: Layout) => MiddlewareBuilder<Layout, readonly [], TAppContext>;
|
|
@@ -33,19 +40,16 @@ type ParseParam<Segment extends string> = Segment extends "*" ? {
|
|
|
33
40
|
type ParseParamsFromSegments<S extends string> = S extends `${infer Segment}/${infer Rest}` ? ParseParam<Segment> & ParseParamsFromSegments<Rest> : ParseParam<S>;
|
|
34
41
|
export type PathParams<Path extends string> = Path extends `/${infer Rest}` ? ParseParamsFromSegments<Rest> : {};
|
|
35
42
|
export type ResolveParams<TPathParams, TSchemaParams> = TSchemaParams extends Record<string, unknown> ? [keyof TSchemaParams] extends [never] ? TPathParams : Simplify<Omit<TPathParams, keyof TSchemaParams> & TSchemaParams> : TPathParams;
|
|
36
|
-
type
|
|
37
|
-
|
|
38
|
-
} ?
|
|
39
|
-
type
|
|
40
|
-
parent: infer Parent extends LayoutId | null;
|
|
41
|
-
} ? Parent : null;
|
|
42
|
-
type LayoutMiddlewares<Layout extends LayoutId> = LayoutTree[Layout]["middlewares"] extends {
|
|
43
|
+
type LayoutParent<Layout extends LayoutId> = Layout extends keyof LayoutTree ? LayoutTree[Layout] extends {
|
|
44
|
+
parent: infer P extends LayoutId;
|
|
45
|
+
} ? P : null : null;
|
|
46
|
+
type LayoutMiddlewares<Layout extends LayoutId> = [Layout] extends [keyof LayoutMiddlewaresMap] ? LayoutMiddlewaresMap[Layout] extends {
|
|
43
47
|
readonly __acc?: infer Acc extends readonly unknown[];
|
|
44
|
-
} ? Acc :
|
|
45
|
-
type ResolveLayoutMiddlewares<Layout extends LayoutId | null, Depth extends readonly unknown[] = []> = Depth["length"] extends 10 ? readonly [] : Layout extends LayoutId ? readonly [
|
|
46
|
-
...ResolveLayoutMiddlewares<
|
|
48
|
+
} ? Acc : LayoutMiddlewaresMap[Layout] extends readonly unknown[] ? LayoutMiddlewaresMap[Layout] : readonly [] : readonly [];
|
|
49
|
+
type ResolveLayoutMiddlewares<Layout extends LayoutId | null, Depth extends readonly unknown[] = []> = Depth["length"] extends 10 ? readonly [] : [Layout] extends [LayoutId] ? LayoutParent<Layout> extends infer Parent extends LayoutId ? readonly [
|
|
50
|
+
...ResolveLayoutMiddlewares<Parent, [...Depth, unknown]>,
|
|
47
51
|
...LayoutMiddlewares<Layout>
|
|
48
|
-
] : readonly [];
|
|
52
|
+
] : readonly [...LayoutMiddlewares<Layout>] : readonly [];
|
|
49
53
|
export type ResolveLayoutIdChain<L extends LayoutId | null, Depth extends readonly unknown[] = []> = Depth["length"] extends 10 ? readonly [] : L extends LayoutId ? readonly [...ResolveLayoutIdChain<LayoutParent<L>, [...Depth, unknown]>, L] : readonly [];
|
|
50
54
|
export type ResolveLayoutMiddlewaresState<Layout extends LayoutId | null> = Layout extends LayoutId ? MergeMiddlewareField<ResolveLayoutMiddlewares<Layout>, "state"> : {};
|
|
51
55
|
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> : {};
|
|
@@ -60,21 +64,18 @@ type ResolveLayoutChainMiddlewares<Chain extends readonly LayoutId[]> = Chain ex
|
|
|
60
64
|
type RouteEntry<Path extends RoutePath, TMethod extends Method> = RouteByPathMethod[Path] extends {
|
|
61
65
|
[K in TMethod]: infer Entry;
|
|
62
66
|
} ? Entry : never;
|
|
63
|
-
type RouteParent<Path extends RoutePath, TMethod extends Method> = RouteEntry<Path, TMethod> extends {
|
|
64
|
-
parent: infer Parent extends LayoutId | null;
|
|
65
|
-
} ? Parent : null;
|
|
66
67
|
type RouteLayoutChain<Path extends RoutePath, TMethod extends Method> = RouteEntry<Path, TMethod> extends {
|
|
67
|
-
|
|
68
|
-
} ? Chain :
|
|
68
|
+
layouts: infer Chain extends readonly LayoutId[];
|
|
69
|
+
} ? Chain : readonly [];
|
|
69
70
|
export type RouteLayoutMiddlewares<Path extends RoutePath, TMethod extends Method> = ResolveLayoutChainMiddlewares<RouteLayoutChain<Path, TMethod>>;
|
|
70
71
|
export type RouteLayoutField<Path extends RoutePath, TMethod extends Method, Field extends "query" | "params" | "body" | "state"> = MergeMiddlewareField<RouteLayoutMiddlewares<Path, TMethod>, Field>;
|
|
71
72
|
export type RouteLayoutInputField<Path extends RoutePath, TMethod extends Method, Field extends "query" | "params" | "body"> = MergeMiddlewareInputField<RouteLayoutMiddlewares<Path, TMethod>, Field>;
|
|
72
73
|
type RouteResolvedField<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], Field extends "query" | "params" | "body" | "state"> = RouteLayoutField<Path, TMethod, Field> & MergeMiddlewareField<Acc, Field>;
|
|
73
74
|
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 & {
|
|
74
|
-
query:
|
|
75
|
-
params:
|
|
76
|
-
body:
|
|
77
|
-
state:
|
|
75
|
+
query: MergePart<TQuery, RouteResolvedField<Path, TMethod, Acc, "query">>;
|
|
76
|
+
params: ResolveParams<PathParams<Path>, MergePart<TParams, RouteResolvedField<Path, TMethod, Acc, "params">>>;
|
|
77
|
+
body: MergePart<TBody, RouteResolvedField<Path, TMethod, Acc, "body">>;
|
|
78
|
+
state: RouteResolvedField<Path, TMethod, Acc, "state">;
|
|
78
79
|
headers: TaserHeaders;
|
|
79
80
|
cookies: TaserCookieJar;
|
|
80
81
|
}>;
|
|
@@ -167,23 +168,23 @@ export type InferRouteInputFromPath<Path extends RoutePath, TMethod extends Meth
|
|
|
167
168
|
Input: infer I;
|
|
168
169
|
};
|
|
169
170
|
} ? I : never : never;
|
|
170
|
-
export type MiddlewareLayoutField<Layout extends LayoutId, Field extends "query" | "params" | "body" | "state"> = MergeMiddlewareField<ResolveLayoutMiddlewares<
|
|
171
|
+
export type MiddlewareLayoutField<Layout extends LayoutId, Field extends "query" | "params" | "body" | "state"> = [LayoutParent<Layout>] extends [infer Parent extends LayoutId] ? MergeMiddlewareField<ResolveLayoutMiddlewares<Parent>, Field> : {};
|
|
171
172
|
type MiddlewareChainField<Layout extends LayoutId, Acc extends readonly unknown[], Field extends "query" | "params" | "body" | "state"> = MiddlewareLayoutField<Layout, Field> & MergeMiddlewareField<Acc, Field>;
|
|
172
|
-
export type MiddlewareChainContext<Layout extends LayoutId, Acc extends readonly unknown[], TQuery, TParams, TBody, TAppContext extends Record<string, unknown> = AppContext> = Simplify<TAppContext &
|
|
173
|
+
export type MiddlewareChainContext<Layout extends LayoutId, Acc extends readonly unknown[], TQuery = unknown, TParams = unknown, TBody = unknown, TAppContext extends Record<string, unknown> = AppContext> = Simplify<TAppContext & {
|
|
174
|
+
readonly request: Request;
|
|
175
|
+
readonly method: Method;
|
|
176
|
+
readonly url: URL;
|
|
177
|
+
readonly headers: TaserHeaders;
|
|
178
|
+
readonly cookies: TaserCookieJar;
|
|
173
179
|
query: Simplify<MergePart<TQuery, MiddlewareChainField<Layout, Acc, "query">>>;
|
|
174
180
|
params: Simplify<MergePart<TParams, MiddlewareChainField<Layout, Acc, "params">>>;
|
|
175
181
|
body: Simplify<MergePart<TBody, MiddlewareChainField<Layout, Acc, "body">>>;
|
|
176
182
|
state: Simplify<MiddlewareChainField<Layout, Acc, "state">>;
|
|
177
|
-
headers: TaserHeaders;
|
|
178
|
-
cookies: TaserCookieJar;
|
|
179
183
|
}>;
|
|
180
184
|
export type MiddlewareBuilder<Layout extends LayoutId, Acc extends readonly unknown[] = readonly [], TAppContext extends Record<string, unknown> = AppContext> = {
|
|
181
185
|
readonly layout: Layout;
|
|
182
186
|
readonly middlewares: readonly MiddlewareDefinition[];
|
|
183
187
|
readonly __acc?: Acc;
|
|
184
|
-
readonly $Infer: {
|
|
185
|
-
Context: MiddlewareChainContext<Layout, Acc, unknown, unknown, unknown, TAppContext>;
|
|
186
|
-
};
|
|
187
188
|
use<TAcc, TReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequires extends MiddlewareRequirements = {}>(unit: [
|
|
188
189
|
IsLayoutAllowed<TRequiredLayouts, ResolveLayoutIdChain<Layout>>,
|
|
189
190
|
IsRequirementsSatisfied<{
|
|
@@ -192,19 +193,18 @@ export type MiddlewareBuilder<Layout extends LayoutId, Acc extends readonly unkn
|
|
|
192
193
|
body: MiddlewareChainField<Layout, Acc, "body">;
|
|
193
194
|
state: MiddlewareChainField<Layout, Acc, "state">;
|
|
194
195
|
}, TRequires>
|
|
195
|
-
] extends [true, true] ? MiddlewareUnit<TAcc, TReturns, TRequiredLayouts, TRequires> :
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}): MiddlewareBuilder<Layout, readonly [...Acc,
|
|
207
|
-
use<R = unknown>(fn: (ctx: MiddlewareChainContext<Layout, Acc, unknown, unknown, unknown, TAppContext>, next: NextFn) => Awaitable<R>): MiddlewareBuilder<Layout, readonly [...Acc, MiddlewareReturnFromParts<unknown, unknown, unknown, ExtractState<R>>], TAppContext>;
|
|
196
|
+
] extends [true, true] ? MiddlewareUnit<TAcc, TReturns, TRequiredLayouts, TRequires> : never): MiddlewareBuilder<Layout, readonly [...Acc, TAcc], TAppContext>;
|
|
197
|
+
use<R = unknown>(fn: (ctx: Simplify<TAppContext & {
|
|
198
|
+
readonly request: Request;
|
|
199
|
+
readonly method: Method;
|
|
200
|
+
readonly url: URL;
|
|
201
|
+
readonly headers: TaserHeaders;
|
|
202
|
+
readonly cookies: TaserCookieJar;
|
|
203
|
+
query: Simplify<MergePart<unknown, MiddlewareChainField<Layout, Acc, "query">>>;
|
|
204
|
+
params: Simplify<MergePart<unknown, MiddlewareChainField<Layout, Acc, "params">>>;
|
|
205
|
+
body: Simplify<MergePart<unknown, MiddlewareChainField<Layout, Acc, "body">>>;
|
|
206
|
+
state: Simplify<MiddlewareChainField<Layout, Acc, "state">>;
|
|
207
|
+
}>, next: NextFn) => Awaitable<R>): MiddlewareBuilder<Layout, readonly [...Acc, MiddlewareReturnFromParts<unknown, unknown, unknown, ExtractState<R>>], TAppContext>;
|
|
208
208
|
};
|
|
209
209
|
export type RouteExport<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], TReturns extends ReturnsMap = {}, TOutput = Response> = {
|
|
210
210
|
readonly path: Path;
|
|
@@ -274,18 +274,7 @@ export type RouteMiddlewareBuilder<Path extends RoutePath, TMethod extends Metho
|
|
|
274
274
|
body: RouteResolvedField<Path, TMethod, Acc, "body">;
|
|
275
275
|
state: RouteResolvedField<Path, TMethod, Acc, "state">;
|
|
276
276
|
}, TRequires>
|
|
277
|
-
] extends [true, true] ? MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequires> :
|
|
278
|
-
error: "Middleware cannot be attached to this route";
|
|
279
|
-
requiredLayouts: TRequiredLayouts;
|
|
280
|
-
routeLayoutChain: RouteLayoutChain<Path, TMethod>;
|
|
281
|
-
requirements: TRequires;
|
|
282
|
-
actual: {
|
|
283
|
-
query: RouteResolvedField<Path, TMethod, Acc, "query">;
|
|
284
|
-
params: ResolveParams<PathParams<Path>, RouteResolvedField<Path, TMethod, Acc, "params">>;
|
|
285
|
-
body: RouteResolvedField<Path, TMethod, Acc, "body">;
|
|
286
|
-
state: RouteResolvedField<Path, TMethod, Acc, "state">;
|
|
287
|
-
};
|
|
288
|
-
}): RouteMiddlewareBuilder<Path, TMethod, readonly [...Acc, TAcc], Validators, Omit<TReturns, keyof UReturns> & UReturns, TAppContext>;
|
|
277
|
+
] extends [true, true] ? MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequires> : never): RouteMiddlewareBuilder<Path, TMethod, readonly [...Acc, TAcc], Validators, Omit<TReturns, keyof UReturns> & UReturns, TAppContext>;
|
|
289
278
|
use<R = unknown>(fn: (ctx: RouteChainContext<Path, TMethod, Acc, unknown, unknown, unknown, TAppContext>, next: NextFn) => Awaitable<R>): RouteMiddlewareBuilder<Path, TMethod, readonly [...Acc, MiddlewareReturnFromParts<unknown, unknown, unknown, ExtractState<R>>], Validators, TReturns, TAppContext>;
|
|
290
279
|
};
|
|
291
280
|
export type RouteBuilder<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[] = readonly [], Validators extends ValidatorParts = {}, TReturns extends ReturnsMap = {}, TAppContext extends Record<string, unknown> = AppContext> = RouteMiddlewareBuilder<Path, TMethod, Acc, Validators, TReturns, TAppContext>;
|
|
@@ -7,9 +7,9 @@ export type MiddlewareInputFieldName = "query" | "params" | "body";
|
|
|
7
7
|
export type UnwrapPart<T> = unknown extends T ? {} : T;
|
|
8
8
|
export type MergePart<T, Base> = unknown extends T ? Base : Base & T;
|
|
9
9
|
/** Collapse intersections so `Omit`/`keyof` treat the result as one object type. */
|
|
10
|
-
export type Simplify<T> = {
|
|
11
|
-
[K in keyof
|
|
12
|
-
}
|
|
10
|
+
export type Simplify<T> = [T] extends [infer U] ? {
|
|
11
|
+
[K in keyof U]: U[K];
|
|
12
|
+
} : never;
|
|
13
13
|
/**
|
|
14
14
|
* Request prop: when schema input is `unknown` (e.g. zod coerce),
|
|
15
15
|
* fall back to the validated output type.
|
|
@@ -26,10 +26,10 @@ export type IsUnknown<T> = [unknown] extends [T] ? true : false;
|
|
|
26
26
|
export type NextFn<TExpectedState = unknown> = IsUnknown<TExpectedState> extends true ? <S extends Record<string, unknown> = {}>(state?: S) => Promise<NextResult<S>> : (state: TExpectedState) => Promise<NextResult<TExpectedState>>;
|
|
27
27
|
export type MiddlewareDefinition = CoreMiddlewareDefinition<ReturnsMap>;
|
|
28
28
|
export type MiddlewareReturnFromParts<TQuery, TParams, TBody, TState, TQueryIn = TQuery, TParamsIn = TParams, TBodyIn = TBody> = {
|
|
29
|
-
query:
|
|
30
|
-
params:
|
|
31
|
-
body:
|
|
32
|
-
state:
|
|
29
|
+
query: UnwrapPart<TQuery>;
|
|
30
|
+
params: UnwrapPart<TParams>;
|
|
31
|
+
body: UnwrapPart<TBody>;
|
|
32
|
+
state: UnwrapPart<TState>;
|
|
33
33
|
/** Pre-parse shapes merged into route `$Infer.Input`. */
|
|
34
34
|
input: {
|
|
35
35
|
query: RequestShape<TQueryIn, TQuery>;
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { DefineMiddlewareResult, ExtractState, IsUnknown, MiddlewareRequirements, MiddlewareUnitBuilder, NextFn, StandaloneMiddlewareContext } from '../types/units.js';
|
|
2
2
|
import { AppContext, LayoutId, ResolveLayoutMiddlewaresState, ResolveLayoutsState } from '../types/index.js';
|
|
3
3
|
export interface MiddlewareFn<TAppContext extends Record<string, unknown> = AppContext> {
|
|
4
|
+
/**
|
|
5
|
+
* Defines a standalone, unscoped middleware using a short function signature.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* const auth = middleware((ctx, next) => {
|
|
10
|
+
* return next({ user: "alice" });
|
|
11
|
+
* });
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
<TState = unknown, TRequires extends MiddlewareRequirements = {}, R = unknown>(fn: (ctx: StandaloneMiddlewareContext<unknown, unknown, unknown, TAppContext, {}, TRequires>, next: NextFn<NoInfer<TState>>) => R): DefineMiddlewareResult<unknown, unknown, unknown, IsUnknown<TState> extends true ? ExtractState<R> : TState, R, unknown, unknown, unknown, {}, null, TRequires>;
|
|
4
15
|
/**
|
|
5
16
|
* Constructs a fluent unscoped middleware builder, with optional explicit State generic.
|
|
6
17
|
*
|
|
@@ -14,14 +25,6 @@ export interface MiddlewareFn<TAppContext extends Record<string, unknown> = AppC
|
|
|
14
25
|
* ```
|
|
15
26
|
*/
|
|
16
27
|
<TState = unknown>(): MiddlewareUnitBuilder<unknown, unknown, unknown, {}, null, {}, TAppContext, {}, unknown, unknown, unknown, TState>;
|
|
17
|
-
/**
|
|
18
|
-
* Constructs a fluent middleware builder scoped to a single layout branch, with optional explicit State generic.
|
|
19
|
-
*/
|
|
20
|
-
<const Layout extends LayoutId, TState = unknown>(layout: Layout): MiddlewareUnitBuilder<unknown, unknown, unknown, {}, Layout, {}, TAppContext, ResolveLayoutMiddlewaresState<Layout>, unknown, unknown, unknown, TState>;
|
|
21
|
-
/**
|
|
22
|
-
* Constructs a fluent middleware builder scoped to multiple layout branches (branch union), with optional explicit State generic.
|
|
23
|
-
*/
|
|
24
|
-
<const Layouts extends readonly [LayoutId, ...LayoutId[]], TState = unknown>(layouts: Layouts): MiddlewareUnitBuilder<unknown, unknown, unknown, {}, Layouts, {}, TAppContext, ResolveLayoutsState<Layouts>, unknown, unknown, unknown, TState>;
|
|
25
28
|
/**
|
|
26
29
|
* Defines a standalone middleware scoped to a single layout branch using a short function signature.
|
|
27
30
|
*/
|
|
@@ -31,15 +34,12 @@ export interface MiddlewareFn<TAppContext extends Record<string, unknown> = AppC
|
|
|
31
34
|
*/
|
|
32
35
|
<const Layouts extends readonly [LayoutId, ...LayoutId[]], TState = unknown, TRequires extends MiddlewareRequirements = {}, R = unknown>(layouts: Layouts, fn: (ctx: StandaloneMiddlewareContext<unknown, unknown, unknown, TAppContext, ResolveLayoutsState<Layouts>, TRequires>, next: NextFn<NoInfer<TState>>) => R): DefineMiddlewareResult<unknown, unknown, unknown, IsUnknown<TState> extends true ? ExtractState<R> : TState, R, unknown, unknown, unknown, {}, Layouts, TRequires>;
|
|
33
36
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* @example
|
|
37
|
-
* ```ts
|
|
38
|
-
* const auth = middleware((ctx, next) => {
|
|
39
|
-
* return next({ user: "alice" });
|
|
40
|
-
* });
|
|
41
|
-
* ```
|
|
37
|
+
* Constructs a fluent middleware builder scoped to a single layout branch, with optional explicit State generic.
|
|
42
38
|
*/
|
|
43
|
-
<
|
|
39
|
+
<const Layout extends LayoutId, TState = unknown>(layout: Layout): MiddlewareUnitBuilder<unknown, unknown, unknown, {}, Layout, {}, TAppContext, ResolveLayoutMiddlewaresState<Layout>, unknown, unknown, unknown, TState>;
|
|
40
|
+
/**
|
|
41
|
+
* Constructs a fluent middleware builder scoped to multiple layout branches (branch union), with optional explicit State generic.
|
|
42
|
+
*/
|
|
43
|
+
<const Layouts extends readonly [LayoutId, ...LayoutId[]], TState = unknown>(layouts: Layouts): MiddlewareUnitBuilder<unknown, unknown, unknown, {}, Layouts, {}, TAppContext, ResolveLayoutsState<Layouts>, unknown, unknown, unknown, TState>;
|
|
44
44
|
}
|
|
45
45
|
export declare const middleware: MiddlewareFn<AppContext>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","names":[],"sources":["../../../src/define/middleware.ts"],"sourcesContent":["import { createMiddlewareUnitBuilder } from \"../builder/middleware-unit.js\";\nimport type {\n DefineMiddlewareResult,\n ExtractState,\n IsUnknown,\n MiddlewareRequirements,\n MiddlewareUnitBuilder,\n NextFn,\n StandaloneMiddlewareContext,\n} from \"../types/units.js\";\nimport type {\n AppContext,\n LayoutId,\n ResolveLayoutMiddlewaresState,\n ResolveLayoutsState,\n} from \"../types/index.js\";\n\nexport interface MiddlewareFn<TAppContext extends Record<string, unknown> = AppContext> {\n /**\n *
|
|
1
|
+
{"version":3,"file":"middleware.js","names":[],"sources":["../../../src/define/middleware.ts"],"sourcesContent":["import { createMiddlewareUnitBuilder } from \"../builder/middleware-unit.js\";\nimport type {\n DefineMiddlewareResult,\n ExtractState,\n IsUnknown,\n MiddlewareRequirements,\n MiddlewareUnitBuilder,\n NextFn,\n StandaloneMiddlewareContext,\n} from \"../types/units.js\";\nimport type {\n AppContext,\n LayoutId,\n ResolveLayoutMiddlewaresState,\n ResolveLayoutsState,\n} from \"../types/index.js\";\n\nexport interface MiddlewareFn<TAppContext extends Record<string, unknown> = AppContext> {\n /**\n * Defines a standalone, unscoped middleware using a short function signature.\n *\n * @example\n * ```ts\n * const auth = middleware((ctx, next) => {\n * return next({ user: \"alice\" });\n * });\n * ```\n */\n <TState = unknown, TRequires extends MiddlewareRequirements = {}, R = unknown>(\n fn: (\n ctx: StandaloneMiddlewareContext<unknown, unknown, unknown, TAppContext, {}, TRequires>,\n next: NextFn<NoInfer<TState>>,\n ) => R,\n ): DefineMiddlewareResult<\n unknown,\n unknown,\n unknown,\n IsUnknown<TState> extends true ? ExtractState<R> : TState,\n R,\n unknown,\n unknown,\n unknown,\n {},\n null,\n TRequires\n >;\n\n /**\n * Constructs a fluent unscoped middleware builder, with optional explicit State generic.\n *\n * @example\n * ```ts\n * const auth = middleware<{ user: string }>()\n * .query(z.object({ token: z.string() }))\n * .body(\"form\", z.object({ file: z.instanceof(File) }))\n * .returns({ 401: z.string() })\n * .handler(async (ctx, next) => next({ user: \"alice\" }));\n * ```\n */\n <TState = unknown>(): MiddlewareUnitBuilder<\n unknown,\n unknown,\n unknown,\n {},\n null,\n {},\n TAppContext,\n {},\n unknown,\n unknown,\n unknown,\n TState\n >;\n\n /**\n * Defines a standalone middleware scoped to a single layout branch using a short function signature.\n */\n <\n const Layout extends LayoutId,\n TState = unknown,\n TRequires extends MiddlewareRequirements = {},\n R = unknown,\n >(\n layout: Layout,\n fn: (\n ctx: StandaloneMiddlewareContext<\n unknown,\n unknown,\n unknown,\n TAppContext,\n ResolveLayoutMiddlewaresState<Layout>,\n TRequires\n >,\n next: NextFn<NoInfer<TState>>,\n ) => R,\n ): DefineMiddlewareResult<\n unknown,\n unknown,\n unknown,\n IsUnknown<TState> extends true ? ExtractState<R> : TState,\n R,\n unknown,\n unknown,\n unknown,\n {},\n Layout,\n TRequires\n >;\n\n /**\n * Defines a standalone middleware scoped to multiple layout branches using a short function signature.\n */\n <\n const Layouts extends readonly [LayoutId, ...LayoutId[]],\n TState = unknown,\n TRequires extends MiddlewareRequirements = {},\n R = unknown,\n >(\n layouts: Layouts,\n fn: (\n ctx: StandaloneMiddlewareContext<\n unknown,\n unknown,\n unknown,\n TAppContext,\n ResolveLayoutsState<Layouts>,\n TRequires\n >,\n next: NextFn<NoInfer<TState>>,\n ) => R,\n ): DefineMiddlewareResult<\n unknown,\n unknown,\n unknown,\n IsUnknown<TState> extends true ? ExtractState<R> : TState,\n R,\n unknown,\n unknown,\n unknown,\n {},\n Layouts,\n TRequires\n >;\n\n /**\n * Constructs a fluent middleware builder scoped to a single layout branch, with optional explicit State generic.\n */\n <const Layout extends LayoutId, TState = unknown>(\n layout: Layout,\n ): MiddlewareUnitBuilder<\n unknown,\n unknown,\n unknown,\n {},\n Layout,\n {},\n TAppContext,\n ResolveLayoutMiddlewaresState<Layout>,\n unknown,\n unknown,\n unknown,\n TState\n >;\n\n /**\n * Constructs a fluent middleware builder scoped to multiple layout branches (branch union), with optional explicit State generic.\n */\n <const Layouts extends readonly [LayoutId, ...LayoutId[]], TState = unknown>(\n layouts: Layouts,\n ): MiddlewareUnitBuilder<\n unknown,\n unknown,\n unknown,\n {},\n Layouts,\n {},\n TAppContext,\n ResolveLayoutsState<Layouts>,\n unknown,\n unknown,\n unknown,\n TState\n >;\n}\n\nexport const middleware: MiddlewareFn<AppContext> = function middleware(\n first?: any,\n second?: any,\n): any {\n if (first === undefined) {\n return createMiddlewareUnitBuilder();\n }\n\n if (typeof first === \"string\" || Array.isArray(first)) {\n if (typeof second === \"function\") {\n return {\n handler: second,\n __middlewareAcc: undefined as unknown,\n __requiredLayouts: first,\n };\n }\n return createMiddlewareUnitBuilder(first);\n }\n\n if (typeof first === \"function\") {\n return {\n handler: first,\n __middlewareAcc: undefined as unknown,\n };\n }\n\n return createMiddlewareUnitBuilder();\n};\n"],"mappings":";;AAyLA,IAAa,aAAuC,SAAS,WAC3D,OACA,QACK;CACL,IAAI,UAAU,KAAA,GACZ,OAAO,4BAA4B;CAGrC,IAAI,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;EACrD,IAAI,OAAO,WAAW,YACpB,OAAO;GACL,SAAS;GACT,iBAAiB,KAAA;GACjB,mBAAmB;EACrB;EAEF,OAAO,4BAA4B,KAAK;CAC1C;CAEA,IAAI,OAAO,UAAU,YACnB,OAAO;EACL,SAAS;EACT,iBAAiB,KAAA;CACnB;CAGF,OAAO,4BAA4B;AACrC"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export interface RouterRegister {
|
|
2
2
|
}
|
|
3
|
-
export
|
|
3
|
+
export interface RouterMiddlewaresRegister {
|
|
4
|
+
}
|
|
5
|
+
export interface RouterRoutesRegister {
|
|
6
|
+
}
|
|
7
|
+
export type { AppContext, EmptyAppContext, HttpMethod, InferInput, InferOutput, InferRouteContext, InferRouteInput, InferRouteInputFromPath, InferRouteOutput, LayoutBuilder, LayoutId, LayoutMiddlewaresMap, LayoutTree, Method, MiddlewareBuilder, MiddlewareDefinition, MiddlewareUnit, MiddlewareUnitBuilder, PathParams, ReturnsMap, RouteByPathMethod, RouteDefinition, RouteExport, RoutePath, Schema, Simplify, StatusCode, } from './types/index.js';
|
|
4
8
|
export type { ContextDefinition, CreateTaserAppOptions, InferAppContext, InferAppManifest, OnErrorOptions, RouteManifestShape, } from './types/app.js';
|
|
5
9
|
export { ValidationError, validationErrorSchema } from '@taserjs/router-utils';
|
|
6
10
|
export type { ResponseValidationFailureHandler, SuccessStatusCode } from '@taserjs/router-utils';
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MiddlewareHandler } from 'hono';
|
|
2
|
+
import { NextFn } from '../types/units.js';
|
|
2
3
|
/**
|
|
3
4
|
* Adapts a standard Web / Hono-compatible middleware function `(c, next) => ...`
|
|
4
5
|
* into a Taser-compatible middleware handler function `(ctx, next) => Promise<Response>`.
|
|
@@ -13,4 +14,4 @@ import { MiddlewareHandler } from 'hono';
|
|
|
13
14
|
* const customCors = middleware(honoMw(cors()));
|
|
14
15
|
* ```
|
|
15
16
|
*/
|
|
16
|
-
export declare function honoMw(middleware: MiddlewareHandler): (ctx: unknown, next:
|
|
17
|
+
export declare function honoMw<TState extends Record<string, unknown> = {}>(middleware: MiddlewareHandler): (ctx: unknown, next: NextFn<TState>) => Promise<Response>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hono-mw.js","names":[],"sources":["../../../src/middleware/hono-mw.ts"],"sourcesContent":["import { createTaserCompatHandler } from \"@taserjs/router-core\";\nimport type { MiddlewareHandler } from \"hono\";\n\n/**\n * Adapts a standard Web / Hono-compatible middleware function `(c, next) => ...`\n * into a Taser-compatible middleware handler function `(ctx, next) => Promise<Response>`.\n *\n * @example\n * ```ts\n * import { honoMw } from \"@taserjs/router\";\n * import { cors } from \"hono/cors\";\n *\n * const app = t.get(\"/hello\").use(honoMw(cors()));\n * // or\n * const customCors = middleware(honoMw(cors()));\n * ```\n */\nexport function honoMw(\n middleware: MiddlewareHandler,\n): (ctx: unknown, next:
|
|
1
|
+
{"version":3,"file":"hono-mw.js","names":[],"sources":["../../../src/middleware/hono-mw.ts"],"sourcesContent":["import { createTaserCompatHandler } from \"@taserjs/router-core\";\nimport type { MiddlewareHandler } from \"hono\";\n\nimport type { NextFn } from \"../types/units.js\";\n\n/**\n * Adapts a standard Web / Hono-compatible middleware function `(c, next) => ...`\n * into a Taser-compatible middleware handler function `(ctx, next) => Promise<Response>`.\n *\n * @example\n * ```ts\n * import { honoMw } from \"@taserjs/router\";\n * import { cors } from \"hono/cors\";\n *\n * const app = t.get(\"/hello\").use(honoMw(cors()));\n * // or\n * const customCors = middleware(honoMw(cors()));\n * ```\n */\nexport function honoMw<TState extends Record<string, unknown> = {}>(\n middleware: MiddlewareHandler,\n): (ctx: unknown, next: NextFn<TState>) => Promise<Response> {\n return createTaserCompatHandler(middleware) as (ctx: unknown, next: NextFn<TState>) => Promise<Response>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAmBA,SAAgB,OACd,YAC2D;CAC3D,OAAO,yBAAyB,UAAU;AAC5C"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Awaitable, TaserCookieJar, TaserHeaders } from '@taserjs/router-core';
|
|
2
|
-
import { RouterRegister } from '../index.js';
|
|
2
|
+
import { RouterMiddlewaresRegister, RouterRegister, RouterRoutesRegister } from '../index.js';
|
|
3
3
|
import { MergeMiddlewareField, MergeMiddlewareInputField, MergePart, RequestShape, Simplify, UnionToIntersection, UnitRuntimeContext } from './type-utils.js';
|
|
4
4
|
import { ReturnsMap, ValidHandlerReply } from './returns.js';
|
|
5
5
|
import { Schema } from './schema.js';
|
|
@@ -21,7 +21,14 @@ export type LayoutId = RouterRegister extends {
|
|
|
21
21
|
export type LayoutTree = RouterRegister extends {
|
|
22
22
|
LayoutTree: infer T;
|
|
23
23
|
} ? T : Record<never, never>;
|
|
24
|
-
export type
|
|
24
|
+
export type LayoutMiddlewaresMap = RouterMiddlewaresRegister extends {
|
|
25
|
+
LayoutMiddlewares: infer M;
|
|
26
|
+
} ? M : RouterRegister extends {
|
|
27
|
+
LayoutMiddlewares: infer M;
|
|
28
|
+
} ? M : Record<never, never>;
|
|
29
|
+
export type RouteByPathMethod = RouterRoutesRegister extends {
|
|
30
|
+
RouteByPathMethod: infer R;
|
|
31
|
+
} ? R : RouterRegister extends {
|
|
25
32
|
RouteByPathMethod: infer R;
|
|
26
33
|
} ? R : Record<never, never>;
|
|
27
34
|
export type LayoutBuilder<TAppContext extends Record<string, unknown> = AppContext> = <const Layout extends LayoutId>(layout: Layout) => MiddlewareBuilder<Layout, readonly [], TAppContext>;
|
|
@@ -33,19 +40,16 @@ type ParseParam<Segment extends string> = Segment extends "*" ? {
|
|
|
33
40
|
type ParseParamsFromSegments<S extends string> = S extends `${infer Segment}/${infer Rest}` ? ParseParam<Segment> & ParseParamsFromSegments<Rest> : ParseParam<S>;
|
|
34
41
|
export type PathParams<Path extends string> = Path extends `/${infer Rest}` ? ParseParamsFromSegments<Rest> : {};
|
|
35
42
|
export type ResolveParams<TPathParams, TSchemaParams> = TSchemaParams extends Record<string, unknown> ? [keyof TSchemaParams] extends [never] ? TPathParams : Simplify<Omit<TPathParams, keyof TSchemaParams> & TSchemaParams> : TPathParams;
|
|
36
|
-
type
|
|
37
|
-
|
|
38
|
-
} ?
|
|
39
|
-
type
|
|
40
|
-
parent: infer Parent extends LayoutId | null;
|
|
41
|
-
} ? Parent : null;
|
|
42
|
-
type LayoutMiddlewares<Layout extends LayoutId> = LayoutTree[Layout]["middlewares"] extends {
|
|
43
|
+
type LayoutParent<Layout extends LayoutId> = Layout extends keyof LayoutTree ? LayoutTree[Layout] extends {
|
|
44
|
+
parent: infer P extends LayoutId;
|
|
45
|
+
} ? P : null : null;
|
|
46
|
+
type LayoutMiddlewares<Layout extends LayoutId> = [Layout] extends [keyof LayoutMiddlewaresMap] ? LayoutMiddlewaresMap[Layout] extends {
|
|
43
47
|
readonly __acc?: infer Acc extends readonly unknown[];
|
|
44
|
-
} ? Acc :
|
|
45
|
-
type ResolveLayoutMiddlewares<Layout extends LayoutId | null, Depth extends readonly unknown[] = []> = Depth["length"] extends 10 ? readonly [] : Layout extends LayoutId ? readonly [
|
|
46
|
-
...ResolveLayoutMiddlewares<
|
|
48
|
+
} ? Acc : LayoutMiddlewaresMap[Layout] extends readonly unknown[] ? LayoutMiddlewaresMap[Layout] : readonly [] : readonly [];
|
|
49
|
+
type ResolveLayoutMiddlewares<Layout extends LayoutId | null, Depth extends readonly unknown[] = []> = Depth["length"] extends 10 ? readonly [] : [Layout] extends [LayoutId] ? LayoutParent<Layout> extends infer Parent extends LayoutId ? readonly [
|
|
50
|
+
...ResolveLayoutMiddlewares<Parent, [...Depth, unknown]>,
|
|
47
51
|
...LayoutMiddlewares<Layout>
|
|
48
|
-
] : readonly [];
|
|
52
|
+
] : readonly [...LayoutMiddlewares<Layout>] : readonly [];
|
|
49
53
|
export type ResolveLayoutIdChain<L extends LayoutId | null, Depth extends readonly unknown[] = []> = Depth["length"] extends 10 ? readonly [] : L extends LayoutId ? readonly [...ResolveLayoutIdChain<LayoutParent<L>, [...Depth, unknown]>, L] : readonly [];
|
|
50
54
|
export type ResolveLayoutMiddlewaresState<Layout extends LayoutId | null> = Layout extends LayoutId ? MergeMiddlewareField<ResolveLayoutMiddlewares<Layout>, "state"> : {};
|
|
51
55
|
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> : {};
|
|
@@ -60,21 +64,18 @@ type ResolveLayoutChainMiddlewares<Chain extends readonly LayoutId[]> = Chain ex
|
|
|
60
64
|
type RouteEntry<Path extends RoutePath, TMethod extends Method> = RouteByPathMethod[Path] extends {
|
|
61
65
|
[K in TMethod]: infer Entry;
|
|
62
66
|
} ? Entry : never;
|
|
63
|
-
type RouteParent<Path extends RoutePath, TMethod extends Method> = RouteEntry<Path, TMethod> extends {
|
|
64
|
-
parent: infer Parent extends LayoutId | null;
|
|
65
|
-
} ? Parent : null;
|
|
66
67
|
type RouteLayoutChain<Path extends RoutePath, TMethod extends Method> = RouteEntry<Path, TMethod> extends {
|
|
67
|
-
|
|
68
|
-
} ? Chain :
|
|
68
|
+
layouts: infer Chain extends readonly LayoutId[];
|
|
69
|
+
} ? Chain : readonly [];
|
|
69
70
|
export type RouteLayoutMiddlewares<Path extends RoutePath, TMethod extends Method> = ResolveLayoutChainMiddlewares<RouteLayoutChain<Path, TMethod>>;
|
|
70
71
|
export type RouteLayoutField<Path extends RoutePath, TMethod extends Method, Field extends "query" | "params" | "body" | "state"> = MergeMiddlewareField<RouteLayoutMiddlewares<Path, TMethod>, Field>;
|
|
71
72
|
export type RouteLayoutInputField<Path extends RoutePath, TMethod extends Method, Field extends "query" | "params" | "body"> = MergeMiddlewareInputField<RouteLayoutMiddlewares<Path, TMethod>, Field>;
|
|
72
73
|
type RouteResolvedField<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], Field extends "query" | "params" | "body" | "state"> = RouteLayoutField<Path, TMethod, Field> & MergeMiddlewareField<Acc, Field>;
|
|
73
74
|
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 & {
|
|
74
|
-
query:
|
|
75
|
-
params:
|
|
76
|
-
body:
|
|
77
|
-
state:
|
|
75
|
+
query: MergePart<TQuery, RouteResolvedField<Path, TMethod, Acc, "query">>;
|
|
76
|
+
params: ResolveParams<PathParams<Path>, MergePart<TParams, RouteResolvedField<Path, TMethod, Acc, "params">>>;
|
|
77
|
+
body: MergePart<TBody, RouteResolvedField<Path, TMethod, Acc, "body">>;
|
|
78
|
+
state: RouteResolvedField<Path, TMethod, Acc, "state">;
|
|
78
79
|
headers: TaserHeaders;
|
|
79
80
|
cookies: TaserCookieJar;
|
|
80
81
|
}>;
|
|
@@ -167,23 +168,23 @@ export type InferRouteInputFromPath<Path extends RoutePath, TMethod extends Meth
|
|
|
167
168
|
Input: infer I;
|
|
168
169
|
};
|
|
169
170
|
} ? I : never : never;
|
|
170
|
-
export type MiddlewareLayoutField<Layout extends LayoutId, Field extends "query" | "params" | "body" | "state"> = MergeMiddlewareField<ResolveLayoutMiddlewares<
|
|
171
|
+
export type MiddlewareLayoutField<Layout extends LayoutId, Field extends "query" | "params" | "body" | "state"> = [LayoutParent<Layout>] extends [infer Parent extends LayoutId] ? MergeMiddlewareField<ResolveLayoutMiddlewares<Parent>, Field> : {};
|
|
171
172
|
type MiddlewareChainField<Layout extends LayoutId, Acc extends readonly unknown[], Field extends "query" | "params" | "body" | "state"> = MiddlewareLayoutField<Layout, Field> & MergeMiddlewareField<Acc, Field>;
|
|
172
|
-
export type MiddlewareChainContext<Layout extends LayoutId, Acc extends readonly unknown[], TQuery, TParams, TBody, TAppContext extends Record<string, unknown> = AppContext> = Simplify<TAppContext &
|
|
173
|
+
export type MiddlewareChainContext<Layout extends LayoutId, Acc extends readonly unknown[], TQuery = unknown, TParams = unknown, TBody = unknown, TAppContext extends Record<string, unknown> = AppContext> = Simplify<TAppContext & {
|
|
174
|
+
readonly request: Request;
|
|
175
|
+
readonly method: Method;
|
|
176
|
+
readonly url: URL;
|
|
177
|
+
readonly headers: TaserHeaders;
|
|
178
|
+
readonly cookies: TaserCookieJar;
|
|
173
179
|
query: Simplify<MergePart<TQuery, MiddlewareChainField<Layout, Acc, "query">>>;
|
|
174
180
|
params: Simplify<MergePart<TParams, MiddlewareChainField<Layout, Acc, "params">>>;
|
|
175
181
|
body: Simplify<MergePart<TBody, MiddlewareChainField<Layout, Acc, "body">>>;
|
|
176
182
|
state: Simplify<MiddlewareChainField<Layout, Acc, "state">>;
|
|
177
|
-
headers: TaserHeaders;
|
|
178
|
-
cookies: TaserCookieJar;
|
|
179
183
|
}>;
|
|
180
184
|
export type MiddlewareBuilder<Layout extends LayoutId, Acc extends readonly unknown[] = readonly [], TAppContext extends Record<string, unknown> = AppContext> = {
|
|
181
185
|
readonly layout: Layout;
|
|
182
186
|
readonly middlewares: readonly MiddlewareDefinition[];
|
|
183
187
|
readonly __acc?: Acc;
|
|
184
|
-
readonly $Infer: {
|
|
185
|
-
Context: MiddlewareChainContext<Layout, Acc, unknown, unknown, unknown, TAppContext>;
|
|
186
|
-
};
|
|
187
188
|
use<TAcc, TReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequires extends MiddlewareRequirements = {}>(unit: [
|
|
188
189
|
IsLayoutAllowed<TRequiredLayouts, ResolveLayoutIdChain<Layout>>,
|
|
189
190
|
IsRequirementsSatisfied<{
|
|
@@ -192,19 +193,18 @@ export type MiddlewareBuilder<Layout extends LayoutId, Acc extends readonly unkn
|
|
|
192
193
|
body: MiddlewareChainField<Layout, Acc, "body">;
|
|
193
194
|
state: MiddlewareChainField<Layout, Acc, "state">;
|
|
194
195
|
}, TRequires>
|
|
195
|
-
] extends [true, true] ? MiddlewareUnit<TAcc, TReturns, TRequiredLayouts, TRequires> :
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}): MiddlewareBuilder<Layout, readonly [...Acc,
|
|
207
|
-
use<R = unknown>(fn: (ctx: MiddlewareChainContext<Layout, Acc, unknown, unknown, unknown, TAppContext>, next: NextFn) => Awaitable<R>): MiddlewareBuilder<Layout, readonly [...Acc, MiddlewareReturnFromParts<unknown, unknown, unknown, ExtractState<R>>], TAppContext>;
|
|
196
|
+
] extends [true, true] ? MiddlewareUnit<TAcc, TReturns, TRequiredLayouts, TRequires> : never): MiddlewareBuilder<Layout, readonly [...Acc, TAcc], TAppContext>;
|
|
197
|
+
use<R = unknown>(fn: (ctx: Simplify<TAppContext & {
|
|
198
|
+
readonly request: Request;
|
|
199
|
+
readonly method: Method;
|
|
200
|
+
readonly url: URL;
|
|
201
|
+
readonly headers: TaserHeaders;
|
|
202
|
+
readonly cookies: TaserCookieJar;
|
|
203
|
+
query: Simplify<MergePart<unknown, MiddlewareChainField<Layout, Acc, "query">>>;
|
|
204
|
+
params: Simplify<MergePart<unknown, MiddlewareChainField<Layout, Acc, "params">>>;
|
|
205
|
+
body: Simplify<MergePart<unknown, MiddlewareChainField<Layout, Acc, "body">>>;
|
|
206
|
+
state: Simplify<MiddlewareChainField<Layout, Acc, "state">>;
|
|
207
|
+
}>, next: NextFn) => Awaitable<R>): MiddlewareBuilder<Layout, readonly [...Acc, MiddlewareReturnFromParts<unknown, unknown, unknown, ExtractState<R>>], TAppContext>;
|
|
208
208
|
};
|
|
209
209
|
export type RouteExport<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], TReturns extends ReturnsMap = {}, TOutput = Response> = {
|
|
210
210
|
readonly path: Path;
|
|
@@ -274,18 +274,7 @@ export type RouteMiddlewareBuilder<Path extends RoutePath, TMethod extends Metho
|
|
|
274
274
|
body: RouteResolvedField<Path, TMethod, Acc, "body">;
|
|
275
275
|
state: RouteResolvedField<Path, TMethod, Acc, "state">;
|
|
276
276
|
}, TRequires>
|
|
277
|
-
] extends [true, true] ? MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequires> :
|
|
278
|
-
error: "Middleware cannot be attached to this route";
|
|
279
|
-
requiredLayouts: TRequiredLayouts;
|
|
280
|
-
routeLayoutChain: RouteLayoutChain<Path, TMethod>;
|
|
281
|
-
requirements: TRequires;
|
|
282
|
-
actual: {
|
|
283
|
-
query: RouteResolvedField<Path, TMethod, Acc, "query">;
|
|
284
|
-
params: ResolveParams<PathParams<Path>, RouteResolvedField<Path, TMethod, Acc, "params">>;
|
|
285
|
-
body: RouteResolvedField<Path, TMethod, Acc, "body">;
|
|
286
|
-
state: RouteResolvedField<Path, TMethod, Acc, "state">;
|
|
287
|
-
};
|
|
288
|
-
}): RouteMiddlewareBuilder<Path, TMethod, readonly [...Acc, TAcc], Validators, Omit<TReturns, keyof UReturns> & UReturns, TAppContext>;
|
|
277
|
+
] extends [true, true] ? MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequires> : never): RouteMiddlewareBuilder<Path, TMethod, readonly [...Acc, TAcc], Validators, Omit<TReturns, keyof UReturns> & UReturns, TAppContext>;
|
|
289
278
|
use<R = unknown>(fn: (ctx: RouteChainContext<Path, TMethod, Acc, unknown, unknown, unknown, TAppContext>, next: NextFn) => Awaitable<R>): RouteMiddlewareBuilder<Path, TMethod, readonly [...Acc, MiddlewareReturnFromParts<unknown, unknown, unknown, ExtractState<R>>], Validators, TReturns, TAppContext>;
|
|
290
279
|
};
|
|
291
280
|
export type RouteBuilder<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[] = readonly [], Validators extends ValidatorParts = {}, TReturns extends ReturnsMap = {}, TAppContext extends Record<string, unknown> = AppContext> = RouteMiddlewareBuilder<Path, TMethod, Acc, Validators, TReturns, TAppContext>;
|
|
@@ -7,9 +7,9 @@ export type MiddlewareInputFieldName = "query" | "params" | "body";
|
|
|
7
7
|
export type UnwrapPart<T> = unknown extends T ? {} : T;
|
|
8
8
|
export type MergePart<T, Base> = unknown extends T ? Base : Base & T;
|
|
9
9
|
/** Collapse intersections so `Omit`/`keyof` treat the result as one object type. */
|
|
10
|
-
export type Simplify<T> = {
|
|
11
|
-
[K in keyof
|
|
12
|
-
}
|
|
10
|
+
export type Simplify<T> = [T] extends [infer U] ? {
|
|
11
|
+
[K in keyof U]: U[K];
|
|
12
|
+
} : never;
|
|
13
13
|
/**
|
|
14
14
|
* Request prop: when schema input is `unknown` (e.g. zod coerce),
|
|
15
15
|
* fall back to the validated output type.
|
|
@@ -26,10 +26,10 @@ export type IsUnknown<T> = [unknown] extends [T] ? true : false;
|
|
|
26
26
|
export type NextFn<TExpectedState = unknown> = IsUnknown<TExpectedState> extends true ? <S extends Record<string, unknown> = {}>(state?: S) => Promise<NextResult<S>> : (state: TExpectedState) => Promise<NextResult<TExpectedState>>;
|
|
27
27
|
export type MiddlewareDefinition = CoreMiddlewareDefinition<ReturnsMap>;
|
|
28
28
|
export type MiddlewareReturnFromParts<TQuery, TParams, TBody, TState, TQueryIn = TQuery, TParamsIn = TParams, TBodyIn = TBody> = {
|
|
29
|
-
query:
|
|
30
|
-
params:
|
|
31
|
-
body:
|
|
32
|
-
state:
|
|
29
|
+
query: UnwrapPart<TQuery>;
|
|
30
|
+
params: UnwrapPart<TParams>;
|
|
31
|
+
body: UnwrapPart<TBody>;
|
|
32
|
+
state: UnwrapPart<TState>;
|
|
33
33
|
/** Pre-parse shapes merged into route `$Infer.Input`. */
|
|
34
34
|
input: {
|
|
35
35
|
query: RequestShape<TQueryIn, TQuery>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taserjs/router",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
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.1.
|
|
151
|
-
"@taserjs/router-utils": "0.1.
|
|
150
|
+
"@taserjs/router-core": "0.1.8",
|
|
151
|
+
"@taserjs/router-utils": "0.1.8"
|
|
152
152
|
},
|
|
153
153
|
"devDependencies": {
|
|
154
154
|
"@tanstack/vite-config": "^0.6.0",
|
package/src/define/middleware.ts
CHANGED
|
@@ -17,66 +17,55 @@ import type {
|
|
|
17
17
|
|
|
18
18
|
export interface MiddlewareFn<TAppContext extends Record<string, unknown> = AppContext> {
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* Defines a standalone, unscoped middleware using a short function signature.
|
|
21
21
|
*
|
|
22
22
|
* @example
|
|
23
23
|
* ```ts
|
|
24
|
-
* const auth = middleware
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* .returns({ 401: z.string() })
|
|
28
|
-
* .handler(async (ctx, next) => next({ user: "alice" }));
|
|
24
|
+
* const auth = middleware((ctx, next) => {
|
|
25
|
+
* return next({ user: "alice" });
|
|
26
|
+
* });
|
|
29
27
|
* ```
|
|
30
28
|
*/
|
|
31
|
-
<TState = unknown>(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
{},
|
|
38
|
-
TAppContext,
|
|
39
|
-
{},
|
|
29
|
+
<TState = unknown, TRequires extends MiddlewareRequirements = {}, R = unknown>(
|
|
30
|
+
fn: (
|
|
31
|
+
ctx: StandaloneMiddlewareContext<unknown, unknown, unknown, TAppContext, {}, TRequires>,
|
|
32
|
+
next: NextFn<NoInfer<TState>>,
|
|
33
|
+
) => R,
|
|
34
|
+
): DefineMiddlewareResult<
|
|
40
35
|
unknown,
|
|
41
36
|
unknown,
|
|
42
37
|
unknown,
|
|
43
|
-
TState
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Constructs a fluent middleware builder scoped to a single layout branch, with optional explicit State generic.
|
|
48
|
-
*/
|
|
49
|
-
<const Layout extends LayoutId, TState = unknown>(
|
|
50
|
-
layout: Layout,
|
|
51
|
-
): MiddlewareUnitBuilder<
|
|
38
|
+
IsUnknown<TState> extends true ? ExtractState<R> : TState,
|
|
39
|
+
R,
|
|
52
40
|
unknown,
|
|
53
41
|
unknown,
|
|
54
42
|
unknown,
|
|
55
43
|
{},
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
TAppContext,
|
|
59
|
-
ResolveLayoutMiddlewaresState<Layout>,
|
|
60
|
-
unknown,
|
|
61
|
-
unknown,
|
|
62
|
-
unknown,
|
|
63
|
-
TState
|
|
44
|
+
null,
|
|
45
|
+
TRequires
|
|
64
46
|
>;
|
|
65
47
|
|
|
66
48
|
/**
|
|
67
|
-
* Constructs a fluent middleware builder
|
|
49
|
+
* Constructs a fluent unscoped middleware builder, with optional explicit State generic.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* const auth = middleware<{ user: string }>()
|
|
54
|
+
* .query(z.object({ token: z.string() }))
|
|
55
|
+
* .body("form", z.object({ file: z.instanceof(File) }))
|
|
56
|
+
* .returns({ 401: z.string() })
|
|
57
|
+
* .handler(async (ctx, next) => next({ user: "alice" }));
|
|
58
|
+
* ```
|
|
68
59
|
*/
|
|
69
|
-
<
|
|
70
|
-
layouts: Layouts,
|
|
71
|
-
): MiddlewareUnitBuilder<
|
|
60
|
+
<TState = unknown>(): MiddlewareUnitBuilder<
|
|
72
61
|
unknown,
|
|
73
62
|
unknown,
|
|
74
63
|
unknown,
|
|
75
64
|
{},
|
|
76
|
-
|
|
65
|
+
null,
|
|
77
66
|
{},
|
|
78
67
|
TAppContext,
|
|
79
|
-
|
|
68
|
+
{},
|
|
80
69
|
unknown,
|
|
81
70
|
unknown,
|
|
82
71
|
unknown,
|
|
@@ -154,32 +143,43 @@ export interface MiddlewareFn<TAppContext extends Record<string, unknown> = AppC
|
|
|
154
143
|
>;
|
|
155
144
|
|
|
156
145
|
/**
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
* @example
|
|
160
|
-
* ```ts
|
|
161
|
-
* const auth = middleware((ctx, next) => {
|
|
162
|
-
* return next({ user: "alice" });
|
|
163
|
-
* });
|
|
164
|
-
* ```
|
|
146
|
+
* Constructs a fluent middleware builder scoped to a single layout branch, with optional explicit State generic.
|
|
165
147
|
*/
|
|
166
|
-
<
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
next: NextFn<NoInfer<TState>>,
|
|
170
|
-
) => R,
|
|
171
|
-
): DefineMiddlewareResult<
|
|
148
|
+
<const Layout extends LayoutId, TState = unknown>(
|
|
149
|
+
layout: Layout,
|
|
150
|
+
): MiddlewareUnitBuilder<
|
|
172
151
|
unknown,
|
|
173
152
|
unknown,
|
|
174
153
|
unknown,
|
|
175
|
-
|
|
176
|
-
|
|
154
|
+
{},
|
|
155
|
+
Layout,
|
|
156
|
+
{},
|
|
157
|
+
TAppContext,
|
|
158
|
+
ResolveLayoutMiddlewaresState<Layout>,
|
|
159
|
+
unknown,
|
|
160
|
+
unknown,
|
|
161
|
+
unknown,
|
|
162
|
+
TState
|
|
163
|
+
>;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Constructs a fluent middleware builder scoped to multiple layout branches (branch union), with optional explicit State generic.
|
|
167
|
+
*/
|
|
168
|
+
<const Layouts extends readonly [LayoutId, ...LayoutId[]], TState = unknown>(
|
|
169
|
+
layouts: Layouts,
|
|
170
|
+
): MiddlewareUnitBuilder<
|
|
177
171
|
unknown,
|
|
178
172
|
unknown,
|
|
179
173
|
unknown,
|
|
180
174
|
{},
|
|
181
|
-
|
|
182
|
-
|
|
175
|
+
Layouts,
|
|
176
|
+
{},
|
|
177
|
+
TAppContext,
|
|
178
|
+
ResolveLayoutsState<Layouts>,
|
|
179
|
+
unknown,
|
|
180
|
+
unknown,
|
|
181
|
+
unknown,
|
|
182
|
+
TState
|
|
183
183
|
>;
|
|
184
184
|
}
|
|
185
185
|
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export interface RouterRegister {}
|
|
2
|
+
export interface RouterMiddlewaresRegister {}
|
|
3
|
+
export interface RouterRoutesRegister {}
|
|
2
4
|
export type {
|
|
3
5
|
AppContext,
|
|
4
6
|
EmptyAppContext,
|
|
@@ -11,6 +13,7 @@ export type {
|
|
|
11
13
|
InferRouteOutput,
|
|
12
14
|
LayoutBuilder,
|
|
13
15
|
LayoutId,
|
|
16
|
+
LayoutMiddlewaresMap,
|
|
14
17
|
LayoutTree,
|
|
15
18
|
Method,
|
|
16
19
|
MiddlewareBuilder,
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createTaserCompatHandler } from "@taserjs/router-core";
|
|
2
2
|
import type { MiddlewareHandler } from "hono";
|
|
3
3
|
|
|
4
|
+
import type { NextFn } from "../types/units.js";
|
|
5
|
+
|
|
4
6
|
/**
|
|
5
7
|
* Adapts a standard Web / Hono-compatible middleware function `(c, next) => ...`
|
|
6
8
|
* into a Taser-compatible middleware handler function `(ctx, next) => Promise<Response>`.
|
|
@@ -15,8 +17,8 @@ import type { MiddlewareHandler } from "hono";
|
|
|
15
17
|
* const customCors = middleware(honoMw(cors()));
|
|
16
18
|
* ```
|
|
17
19
|
*/
|
|
18
|
-
export function honoMw(
|
|
20
|
+
export function honoMw<TState extends Record<string, unknown> = {}>(
|
|
19
21
|
middleware: MiddlewareHandler,
|
|
20
|
-
): (ctx: unknown, next:
|
|
21
|
-
return createTaserCompatHandler(middleware) as (ctx: unknown, next:
|
|
22
|
+
): (ctx: unknown, next: NextFn<TState>) => Promise<Response> {
|
|
23
|
+
return createTaserCompatHandler(middleware) as (ctx: unknown, next: NextFn<TState>) => Promise<Response>;
|
|
22
24
|
}
|
package/src/types/index.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { Awaitable, TaserCookieJar, TaserHeaders } from "@taserjs/router-core";
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
RouterMiddlewaresRegister,
|
|
4
|
+
RouterRegister,
|
|
5
|
+
RouterRoutesRegister,
|
|
6
|
+
} from "../index.js";
|
|
3
7
|
import type {
|
|
4
8
|
MergeMiddlewareField,
|
|
5
9
|
MergeMiddlewareInputField,
|
|
@@ -74,9 +78,18 @@ export type AppContext = RouterRegister extends { AppContext: infer C } ? C : Em
|
|
|
74
78
|
export type RoutePath = RouterRegister extends { RoutePath: infer P } ? P : never;
|
|
75
79
|
export type LayoutId = RouterRegister extends { LayoutId: infer L } ? L : never;
|
|
76
80
|
export type LayoutTree = RouterRegister extends { LayoutTree: infer T } ? T : Record<never, never>;
|
|
77
|
-
export type
|
|
81
|
+
export type LayoutMiddlewaresMap = RouterMiddlewaresRegister extends {
|
|
82
|
+
LayoutMiddlewares: infer M;
|
|
83
|
+
}
|
|
84
|
+
? M
|
|
85
|
+
: RouterRegister extends { LayoutMiddlewares: infer M }
|
|
86
|
+
? M
|
|
87
|
+
: Record<never, never>;
|
|
88
|
+
export type RouteByPathMethod = RouterRoutesRegister extends { RouteByPathMethod: infer R }
|
|
78
89
|
? R
|
|
79
|
-
:
|
|
90
|
+
: RouterRegister extends { RouteByPathMethod: infer R }
|
|
91
|
+
? R
|
|
92
|
+
: Record<never, never>;
|
|
80
93
|
|
|
81
94
|
export type LayoutBuilder<TAppContext extends Record<string, unknown> = AppContext> = <
|
|
82
95
|
const Layout extends LayoutId,
|
|
@@ -107,40 +120,32 @@ export type ResolveParams<TPathParams, TSchemaParams> =
|
|
|
107
120
|
: Simplify<Omit<TPathParams, keyof TSchemaParams> & TSchemaParams>
|
|
108
121
|
: TPathParams;
|
|
109
122
|
|
|
110
|
-
type
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
? LP
|
|
114
|
-
: {};
|
|
115
|
-
|
|
116
|
-
type LayoutParent<Layout extends LayoutId> = Layout extends keyof LayoutParentsMap
|
|
117
|
-
? LayoutParentsMap[Layout] extends LayoutId
|
|
118
|
-
? LayoutParentsMap[Layout]
|
|
123
|
+
type LayoutParent<Layout extends LayoutId> = Layout extends keyof LayoutTree
|
|
124
|
+
? LayoutTree[Layout] extends { parent: infer P extends LayoutId }
|
|
125
|
+
? P
|
|
119
126
|
: null
|
|
120
|
-
:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
: null;
|
|
125
|
-
|
|
126
|
-
type LayoutMiddlewares<Layout extends LayoutId> = LayoutTree[Layout]["middlewares"] extends {
|
|
127
|
-
readonly __acc?: infer Acc extends readonly unknown[];
|
|
128
|
-
}
|
|
129
|
-
? Acc
|
|
130
|
-
: LayoutTree[Layout]["middlewares"] extends infer Acc extends readonly unknown[]
|
|
127
|
+
: null;
|
|
128
|
+
|
|
129
|
+
type LayoutMiddlewares<Layout extends LayoutId> = [Layout] extends [keyof LayoutMiddlewaresMap]
|
|
130
|
+
? LayoutMiddlewaresMap[Layout] extends { readonly __acc?: infer Acc extends readonly unknown[] }
|
|
131
131
|
? Acc
|
|
132
|
-
: readonly []
|
|
132
|
+
: LayoutMiddlewaresMap[Layout] extends readonly unknown[]
|
|
133
|
+
? LayoutMiddlewaresMap[Layout]
|
|
134
|
+
: readonly []
|
|
135
|
+
: readonly [];
|
|
133
136
|
|
|
134
137
|
type ResolveLayoutMiddlewares<
|
|
135
138
|
Layout extends LayoutId | null,
|
|
136
139
|
Depth extends readonly unknown[] = [],
|
|
137
140
|
> = Depth["length"] extends 10
|
|
138
141
|
? readonly []
|
|
139
|
-
: Layout extends LayoutId
|
|
140
|
-
?
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
142
|
+
: [Layout] extends [LayoutId]
|
|
143
|
+
? LayoutParent<Layout> extends infer Parent extends LayoutId
|
|
144
|
+
? readonly [
|
|
145
|
+
...ResolveLayoutMiddlewares<Parent, [...Depth, unknown]>,
|
|
146
|
+
...LayoutMiddlewares<Layout>,
|
|
147
|
+
]
|
|
148
|
+
: readonly [...LayoutMiddlewares<Layout>]
|
|
144
149
|
: readonly [];
|
|
145
150
|
|
|
146
151
|
export type ResolveLayoutIdChain<
|
|
@@ -184,17 +189,10 @@ type RouteEntry<Path extends RoutePath, TMethod extends Method> = RouteByPathMet
|
|
|
184
189
|
? Entry
|
|
185
190
|
: never;
|
|
186
191
|
|
|
187
|
-
type RouteParent<Path extends RoutePath, TMethod extends Method> =
|
|
188
|
-
RouteEntry<Path, TMethod> extends { parent: infer Parent extends LayoutId | null }
|
|
189
|
-
? Parent
|
|
190
|
-
: null;
|
|
191
|
-
|
|
192
192
|
type RouteLayoutChain<Path extends RoutePath, TMethod extends Method> =
|
|
193
|
-
RouteEntry<Path, TMethod> extends {
|
|
193
|
+
RouteEntry<Path, TMethod> extends { layouts: infer Chain extends readonly LayoutId[] }
|
|
194
194
|
? Chain
|
|
195
|
-
:
|
|
196
|
-
? readonly [RouteParent<Path, TMethod>]
|
|
197
|
-
: readonly [];
|
|
195
|
+
: readonly [];
|
|
198
196
|
|
|
199
197
|
export type RouteLayoutMiddlewares<
|
|
200
198
|
Path extends RoutePath,
|
|
@@ -231,15 +229,13 @@ export type RouteChainContext<
|
|
|
231
229
|
> = Simplify<
|
|
232
230
|
TAppContext &
|
|
233
231
|
UnitRuntimeContext & {
|
|
234
|
-
query:
|
|
235
|
-
params:
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
MergePart<TParams, RouteResolvedField<Path, TMethod, Acc, "params">>
|
|
239
|
-
>
|
|
232
|
+
query: MergePart<TQuery, RouteResolvedField<Path, TMethod, Acc, "query">>;
|
|
233
|
+
params: ResolveParams<
|
|
234
|
+
PathParams<Path>,
|
|
235
|
+
MergePart<TParams, RouteResolvedField<Path, TMethod, Acc, "params">>
|
|
240
236
|
>;
|
|
241
|
-
body:
|
|
242
|
-
state:
|
|
237
|
+
body: MergePart<TBody, RouteResolvedField<Path, TMethod, Acc, "body">>;
|
|
238
|
+
state: RouteResolvedField<Path, TMethod, Acc, "state">;
|
|
243
239
|
headers: TaserHeaders;
|
|
244
240
|
cookies: TaserCookieJar;
|
|
245
241
|
}
|
|
@@ -496,7 +492,9 @@ export type InferRouteInputFromPath<Path extends RoutePath, TMethod extends Meth
|
|
|
496
492
|
export type MiddlewareLayoutField<
|
|
497
493
|
Layout extends LayoutId,
|
|
498
494
|
Field extends "query" | "params" | "body" | "state",
|
|
499
|
-
> =
|
|
495
|
+
> = [LayoutParent<Layout>] extends [infer Parent extends LayoutId]
|
|
496
|
+
? MergeMiddlewareField<ResolveLayoutMiddlewares<Parent>, Field>
|
|
497
|
+
: {};
|
|
500
498
|
|
|
501
499
|
type MiddlewareChainField<
|
|
502
500
|
Layout extends LayoutId,
|
|
@@ -507,20 +505,22 @@ type MiddlewareChainField<
|
|
|
507
505
|
export type MiddlewareChainContext<
|
|
508
506
|
Layout extends LayoutId,
|
|
509
507
|
Acc extends readonly unknown[],
|
|
510
|
-
TQuery,
|
|
511
|
-
TParams,
|
|
512
|
-
TBody,
|
|
508
|
+
TQuery = unknown,
|
|
509
|
+
TParams = unknown,
|
|
510
|
+
TBody = unknown,
|
|
513
511
|
TAppContext extends Record<string, unknown> = AppContext,
|
|
514
512
|
> = Simplify<
|
|
515
|
-
TAppContext &
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
513
|
+
TAppContext & {
|
|
514
|
+
readonly request: Request;
|
|
515
|
+
readonly method: Method;
|
|
516
|
+
readonly url: URL;
|
|
517
|
+
readonly headers: TaserHeaders;
|
|
518
|
+
readonly cookies: TaserCookieJar;
|
|
519
|
+
query: Simplify<MergePart<TQuery, MiddlewareChainField<Layout, Acc, "query">>>;
|
|
520
|
+
params: Simplify<MergePart<TParams, MiddlewareChainField<Layout, Acc, "params">>>;
|
|
521
|
+
body: Simplify<MergePart<TBody, MiddlewareChainField<Layout, Acc, "body">>>;
|
|
522
|
+
state: Simplify<MiddlewareChainField<Layout, Acc, "state">>;
|
|
523
|
+
}
|
|
524
524
|
>;
|
|
525
525
|
|
|
526
526
|
export type MiddlewareBuilder<
|
|
@@ -531,9 +531,6 @@ export type MiddlewareBuilder<
|
|
|
531
531
|
readonly layout: Layout;
|
|
532
532
|
readonly middlewares: readonly MiddlewareDefinition[];
|
|
533
533
|
readonly __acc?: Acc;
|
|
534
|
-
readonly $Infer: {
|
|
535
|
-
Context: MiddlewareChainContext<Layout, Acc, unknown, unknown, unknown, TAppContext>;
|
|
536
|
-
};
|
|
537
534
|
use<
|
|
538
535
|
TAcc,
|
|
539
536
|
TReturns extends ReturnsMap = {},
|
|
@@ -553,22 +550,23 @@ export type MiddlewareBuilder<
|
|
|
553
550
|
>,
|
|
554
551
|
] extends [true, true]
|
|
555
552
|
? MiddlewareUnit<TAcc, TReturns, TRequiredLayouts, TRequires>
|
|
556
|
-
:
|
|
557
|
-
error: "Middleware cannot be attached to this layout";
|
|
558
|
-
requiredLayouts: TRequiredLayouts;
|
|
559
|
-
layoutChain: ResolveLayoutIdChain<Layout>;
|
|
560
|
-
requirements: TRequires;
|
|
561
|
-
actual: {
|
|
562
|
-
query: MiddlewareChainField<Layout, Acc, "query">;
|
|
563
|
-
params: MiddlewareChainField<Layout, Acc, "params">;
|
|
564
|
-
body: MiddlewareChainField<Layout, Acc, "body">;
|
|
565
|
-
state: MiddlewareChainField<Layout, Acc, "state">;
|
|
566
|
-
};
|
|
567
|
-
},
|
|
553
|
+
: never,
|
|
568
554
|
): MiddlewareBuilder<Layout, readonly [...Acc, TAcc], TAppContext>;
|
|
569
555
|
use<R = unknown>(
|
|
570
556
|
fn: (
|
|
571
|
-
ctx:
|
|
557
|
+
ctx: Simplify<
|
|
558
|
+
TAppContext & {
|
|
559
|
+
readonly request: Request;
|
|
560
|
+
readonly method: Method;
|
|
561
|
+
readonly url: URL;
|
|
562
|
+
readonly headers: TaserHeaders;
|
|
563
|
+
readonly cookies: TaserCookieJar;
|
|
564
|
+
query: Simplify<MergePart<unknown, MiddlewareChainField<Layout, Acc, "query">>>;
|
|
565
|
+
params: Simplify<MergePart<unknown, MiddlewareChainField<Layout, Acc, "params">>>;
|
|
566
|
+
body: Simplify<MergePart<unknown, MiddlewareChainField<Layout, Acc, "body">>>;
|
|
567
|
+
state: Simplify<MiddlewareChainField<Layout, Acc, "state">>;
|
|
568
|
+
}
|
|
569
|
+
>,
|
|
572
570
|
next: NextFn,
|
|
573
571
|
) => Awaitable<R>,
|
|
574
572
|
): MiddlewareBuilder<
|
|
@@ -747,21 +745,7 @@ export type RouteMiddlewareBuilder<
|
|
|
747
745
|
>,
|
|
748
746
|
] extends [true, true]
|
|
749
747
|
? MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequires>
|
|
750
|
-
:
|
|
751
|
-
error: "Middleware cannot be attached to this route";
|
|
752
|
-
requiredLayouts: TRequiredLayouts;
|
|
753
|
-
routeLayoutChain: RouteLayoutChain<Path, TMethod>;
|
|
754
|
-
requirements: TRequires;
|
|
755
|
-
actual: {
|
|
756
|
-
query: RouteResolvedField<Path, TMethod, Acc, "query">;
|
|
757
|
-
params: ResolveParams<
|
|
758
|
-
PathParams<Path>,
|
|
759
|
-
RouteResolvedField<Path, TMethod, Acc, "params">
|
|
760
|
-
>;
|
|
761
|
-
body: RouteResolvedField<Path, TMethod, Acc, "body">;
|
|
762
|
-
state: RouteResolvedField<Path, TMethod, Acc, "state">;
|
|
763
|
-
};
|
|
764
|
-
},
|
|
748
|
+
: never,
|
|
765
749
|
): RouteMiddlewareBuilder<
|
|
766
750
|
Path,
|
|
767
751
|
TMethod,
|
package/src/types/type-utils.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type UnwrapPart<T> = unknown extends T ? {} : T;
|
|
|
13
13
|
export type MergePart<T, Base> = unknown extends T ? Base : Base & T;
|
|
14
14
|
|
|
15
15
|
/** Collapse intersections so `Omit`/`keyof` treat the result as one object type. */
|
|
16
|
-
export type Simplify<T> = { [K in keyof
|
|
16
|
+
export type Simplify<T> = [T] extends [infer U] ? { [K in keyof U]: U[K] } : never;
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Request prop: when schema input is `unknown` (e.g. zod coerce),
|
package/src/types/units.ts
CHANGED
|
@@ -68,10 +68,10 @@ export type MiddlewareReturnFromParts<
|
|
|
68
68
|
TParamsIn = TParams,
|
|
69
69
|
TBodyIn = TBody,
|
|
70
70
|
> = {
|
|
71
|
-
query:
|
|
72
|
-
params:
|
|
73
|
-
body:
|
|
74
|
-
state:
|
|
71
|
+
query: UnwrapPart<TQuery>;
|
|
72
|
+
params: UnwrapPart<TParams>;
|
|
73
|
+
body: UnwrapPart<TBody>;
|
|
74
|
+
state: UnwrapPart<TState>;
|
|
75
75
|
/** Pre-parse shapes merged into route `$Infer.Input`. */
|
|
76
76
|
input: {
|
|
77
77
|
query: RequestShape<TQueryIn, TQuery>;
|