@taserjs/router 0.0.3 → 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/dist/cjs/define/middleware.cjs +13 -3
- package/dist/cjs/define/middleware.cjs.map +1 -1
- package/dist/cjs/define/middleware.d.cts +21 -4
- package/dist/cjs/types/index.d.cts +41 -4
- package/dist/cjs/types/units.cjs.map +1 -1
- package/dist/cjs/types/units.d.cts +5 -3
- package/dist/esm/define/middleware.d.ts +21 -4
- package/dist/esm/define/middleware.js +13 -3
- package/dist/esm/define/middleware.js.map +1 -1
- package/dist/esm/types/index.d.ts +41 -4
- package/dist/esm/types/units.d.ts +5 -3
- package/dist/esm/types/units.js.map +1 -1
- package/package.json +3 -3
- package/src/define/middleware.ts +197 -7
- package/src/types/index.ts +101 -6
- package/src/types/units.ts +6 -1
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
let _taserjs_router_core = require("@taserjs/router-core");
|
|
2
2
|
//#region src/define/middleware.ts
|
|
3
|
-
function defineMiddleware(
|
|
4
|
-
if (typeof
|
|
5
|
-
const
|
|
3
|
+
function defineMiddleware(first, second) {
|
|
4
|
+
if (typeof first === "string" || Array.isArray(first)) {
|
|
5
|
+
const options = second;
|
|
6
|
+
return {
|
|
7
|
+
...options,
|
|
8
|
+
__middlewareAcc: void 0,
|
|
9
|
+
...options?.returns ? { __returns: options.returns } : {},
|
|
10
|
+
__requiredLayouts: first
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
if (typeof first === "function") {
|
|
14
|
+
const honoMiddleware = first;
|
|
6
15
|
return defineMiddleware({ handler: (ctx, next) => (0, _taserjs_router_core.createTaserCompatHandler)(honoMiddleware)(ctx, next) });
|
|
7
16
|
}
|
|
17
|
+
const options = first;
|
|
8
18
|
return {
|
|
9
19
|
...options,
|
|
10
20
|
__middlewareAcc: void 0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.cjs","names":[],"sources":["../../../src/define/middleware.ts"],"sourcesContent":["import { createTaserCompatHandler, type Awaitable } from \"@taserjs/router-core\";\n\nimport type { ReturnsMap } from \"../types/returns.js\";\nimport type {\n AppContext,\n ExtractState,\n IsUnknown,\n MiddlewareReturnFromParts,\n MiddlewareUnit,\n NextFn,\n StandaloneMiddlewareContext,\n} from \"../types/units.js\";\nimport type { Schema } from \"../types/schema.js\";\n\ntype HonoMiddlewareHandler = Parameters<typeof createTaserCompatHandler>[0];\n\ntype HonoMiddlewareUnit = MiddlewareUnit
|
|
1
|
+
{"version":3,"file":"middleware.cjs","names":[],"sources":["../../../src/define/middleware.ts"],"sourcesContent":["import { createTaserCompatHandler, type Awaitable } from \"@taserjs/router-core\";\n\nimport type { ReturnsMap } from \"../types/returns.js\";\nimport type {\n AppContext,\n ExtractState,\n IsUnknown,\n MiddlewareReturnFromParts,\n MiddlewareUnit,\n NextFn,\n StandaloneMiddlewareContext,\n} from \"../types/units.js\";\nimport type {\n LayoutId,\n ResolveLayoutMiddlewaresState,\n ResolveLayoutsState,\n} from \"../types/index.js\";\nimport type { Schema } from \"../types/schema.js\";\n\ntype HonoMiddlewareHandler = Parameters<typeof createTaserCompatHandler>[0];\n\ntype HonoMiddlewareUnit = MiddlewareUnit<\n MiddlewareReturnFromParts<unknown, unknown, unknown, {}>,\n {},\n null,\n {}\n>;\n\nexport type DefineMiddlewareOptions<\n TState = unknown,\n TRequires = {},\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TReturns extends ReturnsMap = {},\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n TAppContext extends Record<string, unknown> = AppContext,\n R = unknown,\n> = {\n query?: Schema<TQuery, TQueryIn>;\n params?: Schema<TParams, TParamsIn>;\n body?: Schema<TBody, TBodyIn>;\n returns?: TReturns;\n handler: (\n ctx: StandaloneMiddlewareContext<TQuery, TParams, TBody, TAppContext, TRequires>,\n next: NextFn<NoInfer<TState>>,\n ) => Awaitable<R>;\n};\n\nexport type ScopedMiddlewareOptions<\n Layout extends LayoutId,\n TState = unknown,\n TRequires = {},\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TReturns extends ReturnsMap = {},\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n TAppContext extends Record<string, unknown> = AppContext,\n R = unknown,\n> = {\n query?: Schema<TQuery, TQueryIn>;\n params?: Schema<TParams, TParamsIn>;\n body?: Schema<TBody, TBodyIn>;\n returns?: TReturns;\n handler: (\n ctx: StandaloneMiddlewareContext<\n TQuery,\n TParams,\n TBody,\n TAppContext,\n ResolveLayoutMiddlewaresState<Layout> & TRequires\n >,\n next: NextFn<NoInfer<TState>>,\n ) => Awaitable<R>;\n};\n\nexport type MultiScopedMiddlewareOptions<\n Layouts extends readonly LayoutId[],\n TState = unknown,\n TRequires = {},\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TReturns extends ReturnsMap = {},\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n TAppContext extends Record<string, unknown> = AppContext,\n R = unknown,\n> = {\n query?: Schema<TQuery, TQueryIn>;\n params?: Schema<TParams, TParamsIn>;\n body?: Schema<TBody, TBodyIn>;\n returns?: TReturns;\n handler: (\n ctx: StandaloneMiddlewareContext<\n TQuery,\n TParams,\n TBody,\n TAppContext,\n ResolveLayoutsState<Layouts> & TRequires\n >,\n next: NextFn<NoInfer<TState>>,\n ) => Awaitable<R>;\n};\n\nexport function defineMiddleware(middleware: HonoMiddlewareHandler): HonoMiddlewareUnit;\n\nexport function defineMiddleware<\n const Layout extends LayoutId,\n TState = unknown,\n TRequires = {},\n TAppContext extends Record<string, unknown> = AppContext,\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TReturns extends ReturnsMap = {},\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n R = unknown,\n>(\n layout: Layout,\n options: ScopedMiddlewareOptions<\n Layout,\n TState,\n TRequires,\n TQuery,\n TParams,\n TBody,\n TReturns,\n TQueryIn,\n TParamsIn,\n TBodyIn,\n TAppContext,\n R\n >,\n): MiddlewareUnit<\n MiddlewareReturnFromParts<\n TQuery,\n TParams,\n TBody,\n IsUnknown<TState> extends true ? ExtractState<R> : TState,\n TQueryIn,\n TParamsIn,\n TBodyIn\n >,\n TReturns,\n Layout,\n TRequires\n>;\n\nexport function defineMiddleware<\n const Layouts extends readonly [LayoutId, ...LayoutId[]],\n TState = unknown,\n TRequires = {},\n TAppContext extends Record<string, unknown> = AppContext,\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TReturns extends ReturnsMap = {},\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n R = unknown,\n>(\n layouts: Layouts,\n options: MultiScopedMiddlewareOptions<\n Layouts,\n TState,\n TRequires,\n TQuery,\n TParams,\n TBody,\n TReturns,\n TQueryIn,\n TParamsIn,\n TBodyIn,\n TAppContext,\n R\n >,\n): MiddlewareUnit<\n MiddlewareReturnFromParts<\n TQuery,\n TParams,\n TBody,\n IsUnknown<TState> extends true ? ExtractState<R> : TState,\n TQueryIn,\n TParamsIn,\n TBodyIn\n >,\n TReturns,\n Layouts,\n TRequires\n>;\n\nexport function defineMiddleware<\n TState = unknown,\n TRequires = {},\n TAppContext extends Record<string, unknown> = AppContext,\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TReturns extends ReturnsMap = {},\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n R = unknown,\n>(\n options: DefineMiddlewareOptions<\n TState,\n TRequires,\n TQuery,\n TParams,\n TBody,\n TReturns,\n TQueryIn,\n TParamsIn,\n TBodyIn,\n TAppContext,\n R\n >,\n): MiddlewareUnit<\n MiddlewareReturnFromParts<\n TQuery,\n TParams,\n TBody,\n IsUnknown<TState> extends true ? ExtractState<R> : TState,\n TQueryIn,\n TParamsIn,\n TBodyIn\n >,\n TReturns,\n null,\n TRequires\n>;\n\nexport function defineMiddleware(\n first:\n | string\n | readonly string[]\n | HonoMiddlewareHandler\n | DefineMiddlewareOptions<any, any, any, any, any, any, any, any, any, any, any>,\n second?: DefineMiddlewareOptions<any, any, any, any, any, any, any, any, any, any, any>,\n): unknown {\n if (typeof first === \"string\" || Array.isArray(first)) {\n const options = second!;\n const unit = {\n ...options,\n __middlewareAcc: undefined as unknown,\n ...(options?.returns ? { __returns: options.returns } : {}),\n __requiredLayouts: first,\n };\n return unit;\n }\n\n if (typeof first === \"function\") {\n const honoMiddleware = first as HonoMiddlewareHandler;\n return defineMiddleware({\n handler: (ctx, next) => createTaserCompatHandler(honoMiddleware)(ctx, next),\n });\n }\n\n const options = first as DefineMiddlewareOptions<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >;\n const unit = {\n ...options,\n __middlewareAcc: undefined as unknown,\n ...(options.returns ? { __returns: options.returns } : {}),\n };\n\n return unit;\n}\n"],"mappings":";;AAkPA,SAAgB,iBACd,OAKA,QACS;CACT,IAAI,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;EACrD,MAAM,UAAU;EAOhB,OAAO;GALL,GAAG;GACH,iBAAiB,KAAA;GACjB,GAAI,SAAS,UAAU,EAAE,WAAW,QAAQ,QAAQ,IAAI,CAAC;GACzD,mBAAmB;EAEd;CACT;CAEA,IAAI,OAAO,UAAU,YAAY;EAC/B,MAAM,iBAAiB;EACvB,OAAO,iBAAiB,EACtB,UAAU,KAAK,UAAA,GAAA,qBAAA,yBAAA,CAAkC,cAAc,CAAC,CAAC,KAAK,IAAI,EAC5E,CAAC;CACH;CAEA,MAAM,UAAU;CAmBhB,OAAO;EALL,GAAG;EACH,iBAAiB,KAAA;EACjB,GAAI,QAAQ,UAAU,EAAE,WAAW,QAAQ,QAAQ,IAAI,CAAC;CAGnD;AACT"}
|
|
@@ -1,16 +1,33 @@
|
|
|
1
1
|
import { createTaserCompatHandler, Awaitable } from '@taserjs/router-core';
|
|
2
2
|
import { ReturnsMap } from '../types/returns.js';
|
|
3
3
|
import { AppContext, ExtractState, IsUnknown, MiddlewareReturnFromParts, MiddlewareUnit, NextFn, StandaloneMiddlewareContext } from '../types/units.js';
|
|
4
|
+
import { LayoutId, ResolveLayoutMiddlewaresState, ResolveLayoutsState } from '../types/index.js';
|
|
4
5
|
import { Schema } from '../types/schema.js';
|
|
5
6
|
type HonoMiddlewareHandler = Parameters<typeof createTaserCompatHandler>[0];
|
|
6
|
-
type HonoMiddlewareUnit = MiddlewareUnit<MiddlewareReturnFromParts<unknown, unknown, unknown, {}
|
|
7
|
-
export type DefineMiddlewareOptions<TState = unknown, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, TAppContext extends Record<string, unknown> = AppContext, R = unknown> = {
|
|
7
|
+
type HonoMiddlewareUnit = MiddlewareUnit<MiddlewareReturnFromParts<unknown, unknown, unknown, {}>, {}, null, {}>;
|
|
8
|
+
export type DefineMiddlewareOptions<TState = unknown, TRequires = {}, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, TAppContext extends Record<string, unknown> = AppContext, R = unknown> = {
|
|
8
9
|
query?: Schema<TQuery, TQueryIn>;
|
|
9
10
|
params?: Schema<TParams, TParamsIn>;
|
|
10
11
|
body?: Schema<TBody, TBodyIn>;
|
|
11
12
|
returns?: TReturns;
|
|
12
|
-
handler: (ctx: StandaloneMiddlewareContext<TQuery, TParams, TBody, TAppContext>, next: NextFn<NoInfer<TState>>) => Awaitable<R>;
|
|
13
|
+
handler: (ctx: StandaloneMiddlewareContext<TQuery, TParams, TBody, TAppContext, TRequires>, next: NextFn<NoInfer<TState>>) => Awaitable<R>;
|
|
14
|
+
};
|
|
15
|
+
export type ScopedMiddlewareOptions<Layout extends LayoutId, TState = unknown, TRequires = {}, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, TAppContext extends Record<string, unknown> = AppContext, R = unknown> = {
|
|
16
|
+
query?: Schema<TQuery, TQueryIn>;
|
|
17
|
+
params?: Schema<TParams, TParamsIn>;
|
|
18
|
+
body?: Schema<TBody, TBodyIn>;
|
|
19
|
+
returns?: TReturns;
|
|
20
|
+
handler: (ctx: StandaloneMiddlewareContext<TQuery, TParams, TBody, TAppContext, ResolveLayoutMiddlewaresState<Layout> & TRequires>, next: NextFn<NoInfer<TState>>) => Awaitable<R>;
|
|
21
|
+
};
|
|
22
|
+
export type MultiScopedMiddlewareOptions<Layouts extends readonly LayoutId[], TState = unknown, TRequires = {}, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, TAppContext extends Record<string, unknown> = AppContext, R = unknown> = {
|
|
23
|
+
query?: Schema<TQuery, TQueryIn>;
|
|
24
|
+
params?: Schema<TParams, TParamsIn>;
|
|
25
|
+
body?: Schema<TBody, TBodyIn>;
|
|
26
|
+
returns?: TReturns;
|
|
27
|
+
handler: (ctx: StandaloneMiddlewareContext<TQuery, TParams, TBody, TAppContext, ResolveLayoutsState<Layouts> & TRequires>, next: NextFn<NoInfer<TState>>) => Awaitable<R>;
|
|
13
28
|
};
|
|
14
29
|
export declare function defineMiddleware(middleware: HonoMiddlewareHandler): HonoMiddlewareUnit;
|
|
15
|
-
export declare function defineMiddleware<TState = unknown, TAppContext extends Record<string, unknown> = AppContext, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(options:
|
|
30
|
+
export declare function defineMiddleware<const Layout extends LayoutId, TState = unknown, TRequires = {}, TAppContext extends Record<string, unknown> = AppContext, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(layout: Layout, options: ScopedMiddlewareOptions<Layout, TState, TRequires, TQuery, TParams, TBody, TReturns, TQueryIn, TParamsIn, TBodyIn, TAppContext, R>): MiddlewareUnit<MiddlewareReturnFromParts<TQuery, TParams, TBody, IsUnknown<TState> extends true ? ExtractState<R> : TState, TQueryIn, TParamsIn, TBodyIn>, TReturns, Layout, TRequires>;
|
|
31
|
+
export declare function defineMiddleware<const Layouts extends readonly [LayoutId, ...LayoutId[]], TState = unknown, TRequires = {}, TAppContext extends Record<string, unknown> = AppContext, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(layouts: Layouts, options: MultiScopedMiddlewareOptions<Layouts, TState, TRequires, TQuery, TParams, TBody, TReturns, TQueryIn, TParamsIn, TBodyIn, TAppContext, R>): MiddlewareUnit<MiddlewareReturnFromParts<TQuery, TParams, TBody, IsUnknown<TState> extends true ? ExtractState<R> : TState, TQueryIn, TParamsIn, TBodyIn>, TReturns, Layouts, TRequires>;
|
|
32
|
+
export declare function defineMiddleware<TState = unknown, TRequires = {}, TAppContext extends Record<string, unknown> = AppContext, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(options: DefineMiddlewareOptions<TState, TRequires, TQuery, TParams, TBody, TReturns, TQueryIn, TParamsIn, TBodyIn, TAppContext, R>): MiddlewareUnit<MiddlewareReturnFromParts<TQuery, TParams, TBody, IsUnknown<TState> extends true ? ExtractState<R> : TState, TQueryIn, TParamsIn, TBodyIn>, TReturns, null, TRequires>;
|
|
16
33
|
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Awaitable, TaserCookieJar, TaserHeaders } from '@taserjs/router-core';
|
|
2
2
|
import { RouterRegister } from '../register.js';
|
|
3
|
-
import { MergeMiddlewareField, MergeMiddlewareInputField, MergePart, RequestShape, RuntimeContextFields, Simplify } from './type-utils.js';
|
|
3
|
+
import { MergeMiddlewareField, MergeMiddlewareInputField, MergePart, RequestShape, RuntimeContextFields, Simplify, UnionToIntersection } from './type-utils.js';
|
|
4
4
|
import { ReturnsMap, ValidHandlerReply } from './returns.js';
|
|
5
5
|
import { Schema } from './schema.js';
|
|
6
6
|
import { AppContext, ExtractState, HandlerContext, HandlerUnit, InlineMiddlewareOptions, Method, MiddlewareDefinition, MiddlewareReturnFromParts, MiddlewareUnit, NativeContext, ValidatorParts } from './units.js';
|
|
@@ -36,6 +36,9 @@ type ResolveLayoutMiddlewares<Layout extends LayoutId | null> = Layout extends n
|
|
|
36
36
|
...ResolveLayoutMiddlewares<LayoutParent<Layout>>,
|
|
37
37
|
...LayoutTree[Layout]["middlewares"]
|
|
38
38
|
] : readonly [];
|
|
39
|
+
export type ResolveLayoutIdChain<L extends LayoutId | null> = L extends null ? readonly [] : L extends LayoutId ? readonly [...ResolveLayoutIdChain<LayoutParent<L>>, L] : readonly [];
|
|
40
|
+
export type ResolveLayoutMiddlewaresState<Layout extends LayoutId | null> = Layout extends LayoutId ? MergeMiddlewareField<ResolveLayoutMiddlewares<Layout>, "state"> : {};
|
|
41
|
+
export type ResolveLayoutsState<Layouts extends LayoutId | readonly LayoutId[]> = Layouts extends LayoutId ? ResolveLayoutMiddlewaresState<Layouts> : Layouts extends readonly LayoutId[] ? UnionToIntersection<Layouts[number] extends infer L extends LayoutId ? ResolveLayoutMiddlewaresState<L> : never> : {};
|
|
39
42
|
/** Fold layout middleware Acc from a route's layoutChain (shallow → deep). */
|
|
40
43
|
type ResolveLayoutChainMiddlewares<Chain extends readonly LayoutId[]> = Chain extends readonly [
|
|
41
44
|
infer Head extends LayoutId,
|
|
@@ -104,6 +107,10 @@ export type RouteHandleContextWithoutBody<Path extends RoutePath, TMethod extend
|
|
|
104
107
|
type RouteResolvedInputField<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], Field extends "query" | "params" | "body"> = MergeMiddlewareInputField<ResolveLayoutChainMiddlewares<RouteLayoutChain<Path, TMethod>>, Field> & MergeMiddlewareInputField<Acc, Field>;
|
|
105
108
|
type IsNever<T> = [T] extends [never] ? true : false;
|
|
106
109
|
type IsEmptyObject<T> = [keyof T] extends [never] ? true : false;
|
|
110
|
+
export type IsLayoutAllowed<TRequiredLayouts, TChain extends readonly LayoutId[]> = [
|
|
111
|
+
TRequiredLayouts
|
|
112
|
+
] extends [never] ? true : [unknown] extends [TRequiredLayouts] ? true : [null] extends [TRequiredLayouts] ? true : [undefined] extends [TRequiredLayouts] ? true : TRequiredLayouts extends LayoutId ? TRequiredLayouts extends TChain[number] ? true : false : TRequiredLayouts extends readonly LayoutId[] ? [TRequiredLayouts[number] & TChain[number]] extends [never] ? false : true : true;
|
|
113
|
+
export type IsStateSatisfied<TActualState, TRequiredState> = [TRequiredState] extends [never] ? true : [unknown] extends [TRequiredState] ? true : [null] extends [TRequiredState] ? true : [undefined] extends [TRequiredState] ? true : [IsEmptyObject<TRequiredState>] extends [true] ? true : [TActualState] extends [TRequiredState] ? true : false;
|
|
107
114
|
type InputFacet<T, K extends string> = IsNever<T> extends true ? {} : IsEmptyObject<T> extends true ? {} : {
|
|
108
115
|
[Key in K]: T;
|
|
109
116
|
};
|
|
@@ -146,7 +153,18 @@ export type MiddlewareBuilder<Layout extends LayoutId, Acc extends readonly unkn
|
|
|
146
153
|
readonly $Infer: {
|
|
147
154
|
Context: MiddlewareChainContext<Layout, Acc, unknown, unknown, unknown, TAppContext>;
|
|
148
155
|
};
|
|
149
|
-
use<TAcc, TReturns extends ReturnsMap = {}>(unit: MiddlewareUnit<TAcc, TReturns
|
|
156
|
+
use<TAcc, TReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(unit: MiddlewareUnit<TAcc, TReturns, TRequiredLayouts, TRequiredState>, ..._assert: [
|
|
157
|
+
IsLayoutAllowed<TRequiredLayouts, ResolveLayoutIdChain<Layout>>,
|
|
158
|
+
IsStateSatisfied<MiddlewareChainField<Layout, Acc, "state">, TRequiredState>
|
|
159
|
+
] extends [true, true] ? [] : [
|
|
160
|
+
{
|
|
161
|
+
error: "Middleware cannot be attached to this layout";
|
|
162
|
+
requiredLayouts: TRequiredLayouts;
|
|
163
|
+
layoutChain: ResolveLayoutIdChain<Layout>;
|
|
164
|
+
requiredState: TRequiredState;
|
|
165
|
+
actualState: MiddlewareChainField<Layout, Acc, "state">;
|
|
166
|
+
}
|
|
167
|
+
]): MiddlewareBuilder<Layout, readonly [...Acc, TAcc], TAppContext>;
|
|
150
168
|
use<TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(options: InlineMiddlewareOptions<MiddlewareChainContext<Layout, Acc, TQuery, TParams, TBody, TAppContext>, TQuery, TParams, TBody, TReturns, TQueryIn, TParamsIn, TBodyIn, R>): MiddlewareBuilder<Layout, readonly [
|
|
151
169
|
...Acc,
|
|
152
170
|
MiddlewareReturnFromParts<TQuery, TParams, TBody, ExtractState<R>, TQueryIn, TParamsIn, TBodyIn>
|
|
@@ -186,7 +204,18 @@ export type RouteBuilder<Path extends RoutePath, TMethod extends Method, Acc ext
|
|
|
186
204
|
Context: TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS" ? RouteHandleContextWithoutBody<Path, TMethod, Acc, Validators, TAppContext> : RouteHandleContext<Path, TMethod, Acc, Validators, TAppContext>;
|
|
187
205
|
};
|
|
188
206
|
returns<const M extends ReturnsMap>(map: M): RouteBuilder<Path, TMethod, Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>;
|
|
189
|
-
use<TAcc, UReturns extends ReturnsMap = {}>(unit: MiddlewareUnit<TAcc, UReturns
|
|
207
|
+
use<TAcc, UReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(unit: MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequiredState>, ..._assert: [
|
|
208
|
+
IsLayoutAllowed<TRequiredLayouts, RouteLayoutChain<Path, TMethod>>,
|
|
209
|
+
IsStateSatisfied<RouteResolvedField<Path, TMethod, Acc, "state">, TRequiredState>
|
|
210
|
+
] extends [true, true] ? [] : [
|
|
211
|
+
{
|
|
212
|
+
error: "Middleware cannot be attached to this route";
|
|
213
|
+
requiredLayouts: TRequiredLayouts;
|
|
214
|
+
routeLayoutChain: RouteLayoutChain<Path, TMethod>;
|
|
215
|
+
requiredState: TRequiredState;
|
|
216
|
+
actualState: RouteResolvedField<Path, TMethod, Acc, "state">;
|
|
217
|
+
}
|
|
218
|
+
]): RouteBuilder<Path, TMethod, readonly [...Acc, TAcc], Validators, Omit<TReturns, keyof UReturns> & UReturns, TAppContext>;
|
|
190
219
|
use<TQuery = unknown, TParams = unknown, TBody = unknown, UReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(options: InlineMiddlewareOptions<RouteChainContext<Path, TMethod, Acc, TQuery, TParams, TBody, TAppContext>, TQuery, TParams, TBody, UReturns, TQueryIn, TParamsIn, TBodyIn, R>): RouteBuilder<Path, TMethod, readonly [
|
|
191
220
|
...Acc,
|
|
192
221
|
MiddlewareReturnFromParts<TQuery, TParams, TBody, ExtractState<R>, TQueryIn, TParamsIn, TBodyIn>
|
|
@@ -201,7 +230,15 @@ export type RouteBuilder<Path extends RoutePath, TMethod extends Method, Acc ext
|
|
|
201
230
|
};
|
|
202
231
|
export type HandlerBuilder<Acc extends readonly unknown[] = readonly [], Validators extends ValidatorParts = {}, TReturns extends ReturnsMap = {}, TAppContext extends Record<string, unknown> = AppContext> = {
|
|
203
232
|
returns<const M extends ReturnsMap>(map: M): HandlerBuilder<Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>;
|
|
204
|
-
use<TAcc, UReturns extends ReturnsMap = {}>(unit: MiddlewareUnit<TAcc, UReturns
|
|
233
|
+
use<TAcc, UReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(unit: MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequiredState>, ..._assert: [IsStateSatisfied<MergeMiddlewareField<Acc, "state">, TRequiredState>] extends [
|
|
234
|
+
true
|
|
235
|
+
] ? [] : [
|
|
236
|
+
{
|
|
237
|
+
error: "Middleware cannot be attached to this handler";
|
|
238
|
+
requiredState: TRequiredState;
|
|
239
|
+
actualState: MergeMiddlewareField<Acc, "state">;
|
|
240
|
+
}
|
|
241
|
+
]): HandlerBuilder<readonly [...Acc, TAcc], Validators, Omit<TReturns, keyof UReturns> & UReturns, TAppContext>;
|
|
205
242
|
use<TQuery = unknown, TParams = unknown, TBody = unknown, UReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(options: InlineMiddlewareOptions<HandlerContext<Acc, {
|
|
206
243
|
query: TQuery;
|
|
207
244
|
params: TParams;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"units.cjs","names":[],"sources":["../../../src/types/units.ts"],"sourcesContent":["import type { Awaitable, TaserCookieJar, TaserHeaders } from \"@taserjs/router-core\";\nimport type { ReplyResult } from \"@taserjs/router-utils\";\n\nimport type { RouterRegister } from \"../register.js\";\nimport type {\n MergeMiddlewareField,\n MergePart,\n RequestShape,\n RuntimeContextFields,\n Simplify,\n UnwrapPart,\n} from \"./type-utils.js\";\nimport type { ReturnsMap } from \"./returns.js\";\nimport type { Schema } from \"./schema.js\";\n\nexport type { HttpMethod, Method } from \"./type-utils.js\";\nexport type {\n EmptyReturns,\n MergeReturns,\n ReturnsMap,\n HandlerReply,\n HasReturns,\n StatusCode,\n ValidHandlerReply,\n EnforceHandlerReply,\n} from \"./returns.js\";\n\n/** Default empty app context for standalone units without a bound router instance. */\nexport type AppContext = Record<never, never>;\n\nexport type NativeContext = RouterRegister extends { NativeContext: infer N } ? N : unknown;\n\nexport type ValidatorParts = {\n query?: unknown;\n params?: unknown;\n body?: unknown;\n queryIn?: unknown;\n paramsIn?: unknown;\n bodyIn?: unknown;\n};\n\nexport declare const StateBrand: unique symbol;\n\nexport type NextResult<TState = unknown> = ReplyResult & {\n readonly [StateBrand]?: TState;\n};\n\nexport type ExtractState<T> = [Extract<Awaited<T>, { [StateBrand]?: unknown }>] extends [never]\n ? {}\n : Extract<Awaited<T>, { [StateBrand]?: unknown }> extends { [StateBrand]?: infer S }\n ? [S] extends [never]\n ? {}\n : S\n : {};\n\nexport type IsUnknown<T> = [unknown] extends [T] ? true : false;\n\nexport type NextFn<TExpectedState = unknown> =\n IsUnknown<TExpectedState> extends true\n ? <S extends Record<string, unknown> = {}>(state?: S) => Promise<NextResult<S>>\n : (state: TExpectedState) => Promise<NextResult<TExpectedState>>;\n\nexport type MiddlewareNext = NextFn;\n\nexport type MiddlewareDefinition = {\n query?: unknown;\n params?: unknown;\n body?: unknown;\n returns?: ReturnsMap;\n handler: (ctx: unknown, next: MiddlewareNext) => Awaitable<ReplyResult | Response | unknown>;\n};\n\nexport type MiddlewareReturnFromParts<\n TQuery,\n TParams,\n TBody,\n TState,\n TQueryIn = TQuery,\n TParamsIn = TParams,\n TBodyIn = TBody,\n> = {\n query: Simplify<UnwrapPart<TQuery>>;\n params: Simplify<UnwrapPart<TParams>>;\n body: Simplify<UnwrapPart<TBody>>;\n state: Simplify<UnwrapPart<TState>>;\n /** Pre-parse shapes merged into route `$Infer.Input`. */\n input: {\n query: RequestShape<TQueryIn, TQuery>;\n params: RequestShape<TParamsIn, TParams>;\n body: RequestShape<TBodyIn, TBody>;\n };\n};\n\ntype UnitRuntimeContext = Omit<RuntimeContextFields<NativeContext>, \"var\">;\n\nexport type StandaloneMiddlewareContext<\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TAppContext extends Record<string, unknown> = AppContext,\n> = Simplify<\n TAppContext &\n UnitRuntimeContext & {\n query: Simplify<UnwrapPart<TQuery>>;\n params: Simplify<UnwrapPart<TParams>>;\n body: Simplify<UnwrapPart<TBody>>;\n state:
|
|
1
|
+
{"version":3,"file":"units.cjs","names":[],"sources":["../../../src/types/units.ts"],"sourcesContent":["import type { Awaitable, TaserCookieJar, TaserHeaders } from \"@taserjs/router-core\";\nimport type { ReplyResult } from \"@taserjs/router-utils\";\n\nimport type { RouterRegister } from \"../register.js\";\nimport type {\n MergeMiddlewareField,\n MergePart,\n RequestShape,\n RuntimeContextFields,\n Simplify,\n UnwrapPart,\n} from \"./type-utils.js\";\nimport type { ReturnsMap } from \"./returns.js\";\nimport type { Schema } from \"./schema.js\";\n\nexport type { HttpMethod, Method } from \"./type-utils.js\";\nexport type {\n EmptyReturns,\n MergeReturns,\n ReturnsMap,\n HandlerReply,\n HasReturns,\n StatusCode,\n ValidHandlerReply,\n EnforceHandlerReply,\n} from \"./returns.js\";\n\n/** Default empty app context for standalone units without a bound router instance. */\nexport type AppContext = Record<never, never>;\n\nexport type NativeContext = RouterRegister extends { NativeContext: infer N } ? N : unknown;\n\nexport type ValidatorParts = {\n query?: unknown;\n params?: unknown;\n body?: unknown;\n queryIn?: unknown;\n paramsIn?: unknown;\n bodyIn?: unknown;\n};\n\nexport declare const StateBrand: unique symbol;\n\nexport type NextResult<TState = unknown> = ReplyResult & {\n readonly [StateBrand]?: TState;\n};\n\nexport type ExtractState<T> = [Extract<Awaited<T>, { [StateBrand]?: unknown }>] extends [never]\n ? {}\n : Extract<Awaited<T>, { [StateBrand]?: unknown }> extends { [StateBrand]?: infer S }\n ? [S] extends [never]\n ? {}\n : S\n : {};\n\nexport type IsUnknown<T> = [unknown] extends [T] ? true : false;\n\nexport type NextFn<TExpectedState = unknown> =\n IsUnknown<TExpectedState> extends true\n ? <S extends Record<string, unknown> = {}>(state?: S) => Promise<NextResult<S>>\n : (state: TExpectedState) => Promise<NextResult<TExpectedState>>;\n\nexport type MiddlewareNext = NextFn;\n\nexport type MiddlewareDefinition = {\n query?: unknown;\n params?: unknown;\n body?: unknown;\n returns?: ReturnsMap;\n handler: (ctx: unknown, next: MiddlewareNext) => Awaitable<ReplyResult | Response | unknown>;\n};\n\nexport type MiddlewareReturnFromParts<\n TQuery,\n TParams,\n TBody,\n TState,\n TQueryIn = TQuery,\n TParamsIn = TParams,\n TBodyIn = TBody,\n> = {\n query: Simplify<UnwrapPart<TQuery>>;\n params: Simplify<UnwrapPart<TParams>>;\n body: Simplify<UnwrapPart<TBody>>;\n state: Simplify<UnwrapPart<TState>>;\n /** Pre-parse shapes merged into route `$Infer.Input`. */\n input: {\n query: RequestShape<TQueryIn, TQuery>;\n params: RequestShape<TParamsIn, TParams>;\n body: RequestShape<TBodyIn, TBody>;\n };\n};\n\ntype UnitRuntimeContext = Omit<RuntimeContextFields<NativeContext>, \"var\">;\n\nexport type StandaloneMiddlewareContext<\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TAppContext extends Record<string, unknown> = AppContext,\n TState = {},\n> = Simplify<\n TAppContext &\n UnitRuntimeContext & {\n query: Simplify<UnwrapPart<TQuery>>;\n params: Simplify<UnwrapPart<TParams>>;\n body: Simplify<UnwrapPart<TBody>>;\n state: Simplify<UnwrapPart<TState>>;\n headers: TaserHeaders;\n cookies: TaserCookieJar;\n }\n>;\n\nexport type HandlerContext<\n Acc extends readonly unknown[],\n Validators extends ValidatorParts,\n TAppContext extends Record<string, unknown> = AppContext,\n> = Simplify<\n TAppContext &\n UnitRuntimeContext & {\n query: Simplify<\n MergePart<\n Validators extends { query?: infer Q } ? Q : unknown,\n MergeMiddlewareField<Acc, \"query\">\n >\n >;\n params: Simplify<\n MergePart<\n Validators extends { params?: infer P } ? P : unknown,\n MergeMiddlewareField<Acc, \"params\">\n >\n >;\n body: Simplify<\n MergePart<\n Validators extends { body?: infer B } ? B : unknown,\n MergeMiddlewareField<Acc, \"body\">\n >\n >;\n state: Simplify<MergeMiddlewareField<Acc, \"state\">>;\n headers: TaserHeaders;\n cookies: TaserCookieJar;\n }\n>;\n\nexport type MiddlewareUnit<\n TAcc = unknown,\n TReturns extends ReturnsMap = {},\n TRequiredLayouts = unknown,\n TRequiredState = unknown,\n> = MiddlewareDefinition & {\n readonly __middlewareAcc: TAcc;\n readonly __returns?: TReturns;\n readonly __requiredLayouts?: TRequiredLayouts;\n readonly __requiredState?: TRequiredState;\n};\n\nexport type HandlerUnit<\n _Acc extends readonly unknown[],\n _Validators extends ValidatorParts,\n TReturns extends ReturnsMap = {},\n TOutput = Response,\n> = {\n readonly __returns?: TReturns;\n readonly $Infer: {\n Output: TOutput;\n };\n middlewares: readonly MiddlewareDefinition[];\n handler: (ctx: unknown) => Awaitable<ReplyResult | Response>;\n returns?: ReturnsMap;\n query?: Schema<unknown>;\n params?: Schema<unknown>;\n body?: Schema<unknown>;\n};\n\nexport type InlineMiddlewareOptions<\n Ctx = unknown,\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TReturns extends ReturnsMap = {},\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n R = unknown,\n> = {\n query?: Schema<TQuery, TQueryIn>;\n params?: Schema<TParams, TParamsIn>;\n body?: Schema<TBody, TBodyIn>;\n returns?: TReturns;\n handler: (ctx: Ctx, next: NextFn) => Awaitable<R>;\n};\n\nexport function isHandlerUnit(\n value: unknown,\n): value is HandlerUnit<readonly unknown[], ValidatorParts> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"handler\" in value &&\n \"middlewares\" in value &&\n Array.isArray((value as HandlerUnit<readonly unknown[], ValidatorParts>).middlewares)\n );\n}\n"],"mappings":";AAgMA,SAAgB,cACd,OAC0D;CAC1D,OACE,OAAO,UAAU,YACjB,UAAU,QACV,aAAa,SACb,iBAAiB,SACjB,MAAM,QAAS,MAA0D,WAAW;AAExF"}
|
|
@@ -53,11 +53,11 @@ export type MiddlewareReturnFromParts<TQuery, TParams, TBody, TState, TQueryIn =
|
|
|
53
53
|
};
|
|
54
54
|
};
|
|
55
55
|
type UnitRuntimeContext = Omit<RuntimeContextFields<NativeContext>, "var">;
|
|
56
|
-
export type StandaloneMiddlewareContext<TQuery = unknown, TParams = unknown, TBody = unknown, TAppContext extends Record<string, unknown> = AppContext> = Simplify<TAppContext & UnitRuntimeContext & {
|
|
56
|
+
export type StandaloneMiddlewareContext<TQuery = unknown, TParams = unknown, TBody = unknown, TAppContext extends Record<string, unknown> = AppContext, TState = {}> = Simplify<TAppContext & UnitRuntimeContext & {
|
|
57
57
|
query: Simplify<UnwrapPart<TQuery>>;
|
|
58
58
|
params: Simplify<UnwrapPart<TParams>>;
|
|
59
59
|
body: Simplify<UnwrapPart<TBody>>;
|
|
60
|
-
state:
|
|
60
|
+
state: Simplify<UnwrapPart<TState>>;
|
|
61
61
|
headers: TaserHeaders;
|
|
62
62
|
cookies: TaserCookieJar;
|
|
63
63
|
}>;
|
|
@@ -75,9 +75,11 @@ export type HandlerContext<Acc extends readonly unknown[], Validators extends Va
|
|
|
75
75
|
headers: TaserHeaders;
|
|
76
76
|
cookies: TaserCookieJar;
|
|
77
77
|
}>;
|
|
78
|
-
export type MiddlewareUnit<TAcc = unknown, TReturns extends ReturnsMap = {}> = MiddlewareDefinition & {
|
|
78
|
+
export type MiddlewareUnit<TAcc = unknown, TReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown> = MiddlewareDefinition & {
|
|
79
79
|
readonly __middlewareAcc: TAcc;
|
|
80
80
|
readonly __returns?: TReturns;
|
|
81
|
+
readonly __requiredLayouts?: TRequiredLayouts;
|
|
82
|
+
readonly __requiredState?: TRequiredState;
|
|
81
83
|
};
|
|
82
84
|
export type HandlerUnit<_Acc extends readonly unknown[], _Validators extends ValidatorParts, TReturns extends ReturnsMap = {}, TOutput = Response> = {
|
|
83
85
|
readonly __returns?: TReturns;
|
|
@@ -1,16 +1,33 @@
|
|
|
1
1
|
import { createTaserCompatHandler, Awaitable } from '@taserjs/router-core';
|
|
2
2
|
import { ReturnsMap } from '../types/returns.js';
|
|
3
3
|
import { AppContext, ExtractState, IsUnknown, MiddlewareReturnFromParts, MiddlewareUnit, NextFn, StandaloneMiddlewareContext } from '../types/units.js';
|
|
4
|
+
import { LayoutId, ResolveLayoutMiddlewaresState, ResolveLayoutsState } from '../types/index.js';
|
|
4
5
|
import { Schema } from '../types/schema.js';
|
|
5
6
|
type HonoMiddlewareHandler = Parameters<typeof createTaserCompatHandler>[0];
|
|
6
|
-
type HonoMiddlewareUnit = MiddlewareUnit<MiddlewareReturnFromParts<unknown, unknown, unknown, {}
|
|
7
|
-
export type DefineMiddlewareOptions<TState = unknown, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, TAppContext extends Record<string, unknown> = AppContext, R = unknown> = {
|
|
7
|
+
type HonoMiddlewareUnit = MiddlewareUnit<MiddlewareReturnFromParts<unknown, unknown, unknown, {}>, {}, null, {}>;
|
|
8
|
+
export type DefineMiddlewareOptions<TState = unknown, TRequires = {}, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, TAppContext extends Record<string, unknown> = AppContext, R = unknown> = {
|
|
8
9
|
query?: Schema<TQuery, TQueryIn>;
|
|
9
10
|
params?: Schema<TParams, TParamsIn>;
|
|
10
11
|
body?: Schema<TBody, TBodyIn>;
|
|
11
12
|
returns?: TReturns;
|
|
12
|
-
handler: (ctx: StandaloneMiddlewareContext<TQuery, TParams, TBody, TAppContext>, next: NextFn<NoInfer<TState>>) => Awaitable<R>;
|
|
13
|
+
handler: (ctx: StandaloneMiddlewareContext<TQuery, TParams, TBody, TAppContext, TRequires>, next: NextFn<NoInfer<TState>>) => Awaitable<R>;
|
|
14
|
+
};
|
|
15
|
+
export type ScopedMiddlewareOptions<Layout extends LayoutId, TState = unknown, TRequires = {}, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, TAppContext extends Record<string, unknown> = AppContext, R = unknown> = {
|
|
16
|
+
query?: Schema<TQuery, TQueryIn>;
|
|
17
|
+
params?: Schema<TParams, TParamsIn>;
|
|
18
|
+
body?: Schema<TBody, TBodyIn>;
|
|
19
|
+
returns?: TReturns;
|
|
20
|
+
handler: (ctx: StandaloneMiddlewareContext<TQuery, TParams, TBody, TAppContext, ResolveLayoutMiddlewaresState<Layout> & TRequires>, next: NextFn<NoInfer<TState>>) => Awaitable<R>;
|
|
21
|
+
};
|
|
22
|
+
export type MultiScopedMiddlewareOptions<Layouts extends readonly LayoutId[], TState = unknown, TRequires = {}, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, TAppContext extends Record<string, unknown> = AppContext, R = unknown> = {
|
|
23
|
+
query?: Schema<TQuery, TQueryIn>;
|
|
24
|
+
params?: Schema<TParams, TParamsIn>;
|
|
25
|
+
body?: Schema<TBody, TBodyIn>;
|
|
26
|
+
returns?: TReturns;
|
|
27
|
+
handler: (ctx: StandaloneMiddlewareContext<TQuery, TParams, TBody, TAppContext, ResolveLayoutsState<Layouts> & TRequires>, next: NextFn<NoInfer<TState>>) => Awaitable<R>;
|
|
13
28
|
};
|
|
14
29
|
export declare function defineMiddleware(middleware: HonoMiddlewareHandler): HonoMiddlewareUnit;
|
|
15
|
-
export declare function defineMiddleware<TState = unknown, TAppContext extends Record<string, unknown> = AppContext, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(options:
|
|
30
|
+
export declare function defineMiddleware<const Layout extends LayoutId, TState = unknown, TRequires = {}, TAppContext extends Record<string, unknown> = AppContext, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(layout: Layout, options: ScopedMiddlewareOptions<Layout, TState, TRequires, TQuery, TParams, TBody, TReturns, TQueryIn, TParamsIn, TBodyIn, TAppContext, R>): MiddlewareUnit<MiddlewareReturnFromParts<TQuery, TParams, TBody, IsUnknown<TState> extends true ? ExtractState<R> : TState, TQueryIn, TParamsIn, TBodyIn>, TReturns, Layout, TRequires>;
|
|
31
|
+
export declare function defineMiddleware<const Layouts extends readonly [LayoutId, ...LayoutId[]], TState = unknown, TRequires = {}, TAppContext extends Record<string, unknown> = AppContext, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(layouts: Layouts, options: MultiScopedMiddlewareOptions<Layouts, TState, TRequires, TQuery, TParams, TBody, TReturns, TQueryIn, TParamsIn, TBodyIn, TAppContext, R>): MiddlewareUnit<MiddlewareReturnFromParts<TQuery, TParams, TBody, IsUnknown<TState> extends true ? ExtractState<R> : TState, TQueryIn, TParamsIn, TBodyIn>, TReturns, Layouts, TRequires>;
|
|
32
|
+
export declare function defineMiddleware<TState = unknown, TRequires = {}, TAppContext extends Record<string, unknown> = AppContext, TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(options: DefineMiddlewareOptions<TState, TRequires, TQuery, TParams, TBody, TReturns, TQueryIn, TParamsIn, TBodyIn, TAppContext, R>): MiddlewareUnit<MiddlewareReturnFromParts<TQuery, TParams, TBody, IsUnknown<TState> extends true ? ExtractState<R> : TState, TQueryIn, TParamsIn, TBodyIn>, TReturns, null, TRequires>;
|
|
16
33
|
export {};
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import { createTaserCompatHandler } from "@taserjs/router-core";
|
|
2
2
|
//#region src/define/middleware.ts
|
|
3
|
-
function defineMiddleware(
|
|
4
|
-
if (typeof
|
|
5
|
-
const
|
|
3
|
+
function defineMiddleware(first, second) {
|
|
4
|
+
if (typeof first === "string" || Array.isArray(first)) {
|
|
5
|
+
const options = second;
|
|
6
|
+
return {
|
|
7
|
+
...options,
|
|
8
|
+
__middlewareAcc: void 0,
|
|
9
|
+
...options?.returns ? { __returns: options.returns } : {},
|
|
10
|
+
__requiredLayouts: first
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
if (typeof first === "function") {
|
|
14
|
+
const honoMiddleware = first;
|
|
6
15
|
return defineMiddleware({ handler: (ctx, next) => createTaserCompatHandler(honoMiddleware)(ctx, next) });
|
|
7
16
|
}
|
|
17
|
+
const options = first;
|
|
8
18
|
return {
|
|
9
19
|
...options,
|
|
10
20
|
__middlewareAcc: void 0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","names":[],"sources":["../../../src/define/middleware.ts"],"sourcesContent":["import { createTaserCompatHandler, type Awaitable } from \"@taserjs/router-core\";\n\nimport type { ReturnsMap } from \"../types/returns.js\";\nimport type {\n AppContext,\n ExtractState,\n IsUnknown,\n MiddlewareReturnFromParts,\n MiddlewareUnit,\n NextFn,\n StandaloneMiddlewareContext,\n} from \"../types/units.js\";\nimport type { Schema } from \"../types/schema.js\";\n\ntype HonoMiddlewareHandler = Parameters<typeof createTaserCompatHandler>[0];\n\ntype HonoMiddlewareUnit = MiddlewareUnit
|
|
1
|
+
{"version":3,"file":"middleware.js","names":[],"sources":["../../../src/define/middleware.ts"],"sourcesContent":["import { createTaserCompatHandler, type Awaitable } from \"@taserjs/router-core\";\n\nimport type { ReturnsMap } from \"../types/returns.js\";\nimport type {\n AppContext,\n ExtractState,\n IsUnknown,\n MiddlewareReturnFromParts,\n MiddlewareUnit,\n NextFn,\n StandaloneMiddlewareContext,\n} from \"../types/units.js\";\nimport type {\n LayoutId,\n ResolveLayoutMiddlewaresState,\n ResolveLayoutsState,\n} from \"../types/index.js\";\nimport type { Schema } from \"../types/schema.js\";\n\ntype HonoMiddlewareHandler = Parameters<typeof createTaserCompatHandler>[0];\n\ntype HonoMiddlewareUnit = MiddlewareUnit<\n MiddlewareReturnFromParts<unknown, unknown, unknown, {}>,\n {},\n null,\n {}\n>;\n\nexport type DefineMiddlewareOptions<\n TState = unknown,\n TRequires = {},\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TReturns extends ReturnsMap = {},\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n TAppContext extends Record<string, unknown> = AppContext,\n R = unknown,\n> = {\n query?: Schema<TQuery, TQueryIn>;\n params?: Schema<TParams, TParamsIn>;\n body?: Schema<TBody, TBodyIn>;\n returns?: TReturns;\n handler: (\n ctx: StandaloneMiddlewareContext<TQuery, TParams, TBody, TAppContext, TRequires>,\n next: NextFn<NoInfer<TState>>,\n ) => Awaitable<R>;\n};\n\nexport type ScopedMiddlewareOptions<\n Layout extends LayoutId,\n TState = unknown,\n TRequires = {},\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TReturns extends ReturnsMap = {},\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n TAppContext extends Record<string, unknown> = AppContext,\n R = unknown,\n> = {\n query?: Schema<TQuery, TQueryIn>;\n params?: Schema<TParams, TParamsIn>;\n body?: Schema<TBody, TBodyIn>;\n returns?: TReturns;\n handler: (\n ctx: StandaloneMiddlewareContext<\n TQuery,\n TParams,\n TBody,\n TAppContext,\n ResolveLayoutMiddlewaresState<Layout> & TRequires\n >,\n next: NextFn<NoInfer<TState>>,\n ) => Awaitable<R>;\n};\n\nexport type MultiScopedMiddlewareOptions<\n Layouts extends readonly LayoutId[],\n TState = unknown,\n TRequires = {},\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TReturns extends ReturnsMap = {},\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n TAppContext extends Record<string, unknown> = AppContext,\n R = unknown,\n> = {\n query?: Schema<TQuery, TQueryIn>;\n params?: Schema<TParams, TParamsIn>;\n body?: Schema<TBody, TBodyIn>;\n returns?: TReturns;\n handler: (\n ctx: StandaloneMiddlewareContext<\n TQuery,\n TParams,\n TBody,\n TAppContext,\n ResolveLayoutsState<Layouts> & TRequires\n >,\n next: NextFn<NoInfer<TState>>,\n ) => Awaitable<R>;\n};\n\nexport function defineMiddleware(middleware: HonoMiddlewareHandler): HonoMiddlewareUnit;\n\nexport function defineMiddleware<\n const Layout extends LayoutId,\n TState = unknown,\n TRequires = {},\n TAppContext extends Record<string, unknown> = AppContext,\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TReturns extends ReturnsMap = {},\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n R = unknown,\n>(\n layout: Layout,\n options: ScopedMiddlewareOptions<\n Layout,\n TState,\n TRequires,\n TQuery,\n TParams,\n TBody,\n TReturns,\n TQueryIn,\n TParamsIn,\n TBodyIn,\n TAppContext,\n R\n >,\n): MiddlewareUnit<\n MiddlewareReturnFromParts<\n TQuery,\n TParams,\n TBody,\n IsUnknown<TState> extends true ? ExtractState<R> : TState,\n TQueryIn,\n TParamsIn,\n TBodyIn\n >,\n TReturns,\n Layout,\n TRequires\n>;\n\nexport function defineMiddleware<\n const Layouts extends readonly [LayoutId, ...LayoutId[]],\n TState = unknown,\n TRequires = {},\n TAppContext extends Record<string, unknown> = AppContext,\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TReturns extends ReturnsMap = {},\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n R = unknown,\n>(\n layouts: Layouts,\n options: MultiScopedMiddlewareOptions<\n Layouts,\n TState,\n TRequires,\n TQuery,\n TParams,\n TBody,\n TReturns,\n TQueryIn,\n TParamsIn,\n TBodyIn,\n TAppContext,\n R\n >,\n): MiddlewareUnit<\n MiddlewareReturnFromParts<\n TQuery,\n TParams,\n TBody,\n IsUnknown<TState> extends true ? ExtractState<R> : TState,\n TQueryIn,\n TParamsIn,\n TBodyIn\n >,\n TReturns,\n Layouts,\n TRequires\n>;\n\nexport function defineMiddleware<\n TState = unknown,\n TRequires = {},\n TAppContext extends Record<string, unknown> = AppContext,\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TReturns extends ReturnsMap = {},\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n R = unknown,\n>(\n options: DefineMiddlewareOptions<\n TState,\n TRequires,\n TQuery,\n TParams,\n TBody,\n TReturns,\n TQueryIn,\n TParamsIn,\n TBodyIn,\n TAppContext,\n R\n >,\n): MiddlewareUnit<\n MiddlewareReturnFromParts<\n TQuery,\n TParams,\n TBody,\n IsUnknown<TState> extends true ? ExtractState<R> : TState,\n TQueryIn,\n TParamsIn,\n TBodyIn\n >,\n TReturns,\n null,\n TRequires\n>;\n\nexport function defineMiddleware(\n first:\n | string\n | readonly string[]\n | HonoMiddlewareHandler\n | DefineMiddlewareOptions<any, any, any, any, any, any, any, any, any, any, any>,\n second?: DefineMiddlewareOptions<any, any, any, any, any, any, any, any, any, any, any>,\n): unknown {\n if (typeof first === \"string\" || Array.isArray(first)) {\n const options = second!;\n const unit = {\n ...options,\n __middlewareAcc: undefined as unknown,\n ...(options?.returns ? { __returns: options.returns } : {}),\n __requiredLayouts: first,\n };\n return unit;\n }\n\n if (typeof first === \"function\") {\n const honoMiddleware = first as HonoMiddlewareHandler;\n return defineMiddleware({\n handler: (ctx, next) => createTaserCompatHandler(honoMiddleware)(ctx, next),\n });\n }\n\n const options = first as DefineMiddlewareOptions<\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any,\n any\n >;\n const unit = {\n ...options,\n __middlewareAcc: undefined as unknown,\n ...(options.returns ? { __returns: options.returns } : {}),\n };\n\n return unit;\n}\n"],"mappings":";;AAkPA,SAAgB,iBACd,OAKA,QACS;CACT,IAAI,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;EACrD,MAAM,UAAU;EAOhB,OAAO;GALL,GAAG;GACH,iBAAiB,KAAA;GACjB,GAAI,SAAS,UAAU,EAAE,WAAW,QAAQ,QAAQ,IAAI,CAAC;GACzD,mBAAmB;EAEd;CACT;CAEA,IAAI,OAAO,UAAU,YAAY;EAC/B,MAAM,iBAAiB;EACvB,OAAO,iBAAiB,EACtB,UAAU,KAAK,SAAS,yBAAyB,cAAc,CAAC,CAAC,KAAK,IAAI,EAC5E,CAAC;CACH;CAEA,MAAM,UAAU;CAmBhB,OAAO;EALL,GAAG;EACH,iBAAiB,KAAA;EACjB,GAAI,QAAQ,UAAU,EAAE,WAAW,QAAQ,QAAQ,IAAI,CAAC;CAGnD;AACT"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Awaitable, TaserCookieJar, TaserHeaders } from '@taserjs/router-core';
|
|
2
2
|
import { RouterRegister } from '../register.js';
|
|
3
|
-
import { MergeMiddlewareField, MergeMiddlewareInputField, MergePart, RequestShape, RuntimeContextFields, Simplify } from './type-utils.js';
|
|
3
|
+
import { MergeMiddlewareField, MergeMiddlewareInputField, MergePart, RequestShape, RuntimeContextFields, Simplify, UnionToIntersection } from './type-utils.js';
|
|
4
4
|
import { ReturnsMap, ValidHandlerReply } from './returns.js';
|
|
5
5
|
import { Schema } from './schema.js';
|
|
6
6
|
import { AppContext, ExtractState, HandlerContext, HandlerUnit, InlineMiddlewareOptions, Method, MiddlewareDefinition, MiddlewareReturnFromParts, MiddlewareUnit, NativeContext, ValidatorParts } from './units.js';
|
|
@@ -36,6 +36,9 @@ type ResolveLayoutMiddlewares<Layout extends LayoutId | null> = Layout extends n
|
|
|
36
36
|
...ResolveLayoutMiddlewares<LayoutParent<Layout>>,
|
|
37
37
|
...LayoutTree[Layout]["middlewares"]
|
|
38
38
|
] : readonly [];
|
|
39
|
+
export type ResolveLayoutIdChain<L extends LayoutId | null> = L extends null ? readonly [] : L extends LayoutId ? readonly [...ResolveLayoutIdChain<LayoutParent<L>>, L] : readonly [];
|
|
40
|
+
export type ResolveLayoutMiddlewaresState<Layout extends LayoutId | null> = Layout extends LayoutId ? MergeMiddlewareField<ResolveLayoutMiddlewares<Layout>, "state"> : {};
|
|
41
|
+
export type ResolveLayoutsState<Layouts extends LayoutId | readonly LayoutId[]> = Layouts extends LayoutId ? ResolveLayoutMiddlewaresState<Layouts> : Layouts extends readonly LayoutId[] ? UnionToIntersection<Layouts[number] extends infer L extends LayoutId ? ResolveLayoutMiddlewaresState<L> : never> : {};
|
|
39
42
|
/** Fold layout middleware Acc from a route's layoutChain (shallow → deep). */
|
|
40
43
|
type ResolveLayoutChainMiddlewares<Chain extends readonly LayoutId[]> = Chain extends readonly [
|
|
41
44
|
infer Head extends LayoutId,
|
|
@@ -104,6 +107,10 @@ export type RouteHandleContextWithoutBody<Path extends RoutePath, TMethod extend
|
|
|
104
107
|
type RouteResolvedInputField<Path extends RoutePath, TMethod extends Method, Acc extends readonly unknown[], Field extends "query" | "params" | "body"> = MergeMiddlewareInputField<ResolveLayoutChainMiddlewares<RouteLayoutChain<Path, TMethod>>, Field> & MergeMiddlewareInputField<Acc, Field>;
|
|
105
108
|
type IsNever<T> = [T] extends [never] ? true : false;
|
|
106
109
|
type IsEmptyObject<T> = [keyof T] extends [never] ? true : false;
|
|
110
|
+
export type IsLayoutAllowed<TRequiredLayouts, TChain extends readonly LayoutId[]> = [
|
|
111
|
+
TRequiredLayouts
|
|
112
|
+
] extends [never] ? true : [unknown] extends [TRequiredLayouts] ? true : [null] extends [TRequiredLayouts] ? true : [undefined] extends [TRequiredLayouts] ? true : TRequiredLayouts extends LayoutId ? TRequiredLayouts extends TChain[number] ? true : false : TRequiredLayouts extends readonly LayoutId[] ? [TRequiredLayouts[number] & TChain[number]] extends [never] ? false : true : true;
|
|
113
|
+
export type IsStateSatisfied<TActualState, TRequiredState> = [TRequiredState] extends [never] ? true : [unknown] extends [TRequiredState] ? true : [null] extends [TRequiredState] ? true : [undefined] extends [TRequiredState] ? true : [IsEmptyObject<TRequiredState>] extends [true] ? true : [TActualState] extends [TRequiredState] ? true : false;
|
|
107
114
|
type InputFacet<T, K extends string> = IsNever<T> extends true ? {} : IsEmptyObject<T> extends true ? {} : {
|
|
108
115
|
[Key in K]: T;
|
|
109
116
|
};
|
|
@@ -146,7 +153,18 @@ export type MiddlewareBuilder<Layout extends LayoutId, Acc extends readonly unkn
|
|
|
146
153
|
readonly $Infer: {
|
|
147
154
|
Context: MiddlewareChainContext<Layout, Acc, unknown, unknown, unknown, TAppContext>;
|
|
148
155
|
};
|
|
149
|
-
use<TAcc, TReturns extends ReturnsMap = {}>(unit: MiddlewareUnit<TAcc, TReturns
|
|
156
|
+
use<TAcc, TReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(unit: MiddlewareUnit<TAcc, TReturns, TRequiredLayouts, TRequiredState>, ..._assert: [
|
|
157
|
+
IsLayoutAllowed<TRequiredLayouts, ResolveLayoutIdChain<Layout>>,
|
|
158
|
+
IsStateSatisfied<MiddlewareChainField<Layout, Acc, "state">, TRequiredState>
|
|
159
|
+
] extends [true, true] ? [] : [
|
|
160
|
+
{
|
|
161
|
+
error: "Middleware cannot be attached to this layout";
|
|
162
|
+
requiredLayouts: TRequiredLayouts;
|
|
163
|
+
layoutChain: ResolveLayoutIdChain<Layout>;
|
|
164
|
+
requiredState: TRequiredState;
|
|
165
|
+
actualState: MiddlewareChainField<Layout, Acc, "state">;
|
|
166
|
+
}
|
|
167
|
+
]): MiddlewareBuilder<Layout, readonly [...Acc, TAcc], TAppContext>;
|
|
150
168
|
use<TQuery = unknown, TParams = unknown, TBody = unknown, TReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(options: InlineMiddlewareOptions<MiddlewareChainContext<Layout, Acc, TQuery, TParams, TBody, TAppContext>, TQuery, TParams, TBody, TReturns, TQueryIn, TParamsIn, TBodyIn, R>): MiddlewareBuilder<Layout, readonly [
|
|
151
169
|
...Acc,
|
|
152
170
|
MiddlewareReturnFromParts<TQuery, TParams, TBody, ExtractState<R>, TQueryIn, TParamsIn, TBodyIn>
|
|
@@ -186,7 +204,18 @@ export type RouteBuilder<Path extends RoutePath, TMethod extends Method, Acc ext
|
|
|
186
204
|
Context: TMethod extends "GET" | "DELETE" | "HEAD" | "OPTIONS" ? RouteHandleContextWithoutBody<Path, TMethod, Acc, Validators, TAppContext> : RouteHandleContext<Path, TMethod, Acc, Validators, TAppContext>;
|
|
187
205
|
};
|
|
188
206
|
returns<const M extends ReturnsMap>(map: M): RouteBuilder<Path, TMethod, Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>;
|
|
189
|
-
use<TAcc, UReturns extends ReturnsMap = {}>(unit: MiddlewareUnit<TAcc, UReturns
|
|
207
|
+
use<TAcc, UReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(unit: MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequiredState>, ..._assert: [
|
|
208
|
+
IsLayoutAllowed<TRequiredLayouts, RouteLayoutChain<Path, TMethod>>,
|
|
209
|
+
IsStateSatisfied<RouteResolvedField<Path, TMethod, Acc, "state">, TRequiredState>
|
|
210
|
+
] extends [true, true] ? [] : [
|
|
211
|
+
{
|
|
212
|
+
error: "Middleware cannot be attached to this route";
|
|
213
|
+
requiredLayouts: TRequiredLayouts;
|
|
214
|
+
routeLayoutChain: RouteLayoutChain<Path, TMethod>;
|
|
215
|
+
requiredState: TRequiredState;
|
|
216
|
+
actualState: RouteResolvedField<Path, TMethod, Acc, "state">;
|
|
217
|
+
}
|
|
218
|
+
]): RouteBuilder<Path, TMethod, readonly [...Acc, TAcc], Validators, Omit<TReturns, keyof UReturns> & UReturns, TAppContext>;
|
|
190
219
|
use<TQuery = unknown, TParams = unknown, TBody = unknown, UReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(options: InlineMiddlewareOptions<RouteChainContext<Path, TMethod, Acc, TQuery, TParams, TBody, TAppContext>, TQuery, TParams, TBody, UReturns, TQueryIn, TParamsIn, TBodyIn, R>): RouteBuilder<Path, TMethod, readonly [
|
|
191
220
|
...Acc,
|
|
192
221
|
MiddlewareReturnFromParts<TQuery, TParams, TBody, ExtractState<R>, TQueryIn, TParamsIn, TBodyIn>
|
|
@@ -201,7 +230,15 @@ export type RouteBuilder<Path extends RoutePath, TMethod extends Method, Acc ext
|
|
|
201
230
|
};
|
|
202
231
|
export type HandlerBuilder<Acc extends readonly unknown[] = readonly [], Validators extends ValidatorParts = {}, TReturns extends ReturnsMap = {}, TAppContext extends Record<string, unknown> = AppContext> = {
|
|
203
232
|
returns<const M extends ReturnsMap>(map: M): HandlerBuilder<Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>;
|
|
204
|
-
use<TAcc, UReturns extends ReturnsMap = {}>(unit: MiddlewareUnit<TAcc, UReturns
|
|
233
|
+
use<TAcc, UReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(unit: MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequiredState>, ..._assert: [IsStateSatisfied<MergeMiddlewareField<Acc, "state">, TRequiredState>] extends [
|
|
234
|
+
true
|
|
235
|
+
] ? [] : [
|
|
236
|
+
{
|
|
237
|
+
error: "Middleware cannot be attached to this handler";
|
|
238
|
+
requiredState: TRequiredState;
|
|
239
|
+
actualState: MergeMiddlewareField<Acc, "state">;
|
|
240
|
+
}
|
|
241
|
+
]): HandlerBuilder<readonly [...Acc, TAcc], Validators, Omit<TReturns, keyof UReturns> & UReturns, TAppContext>;
|
|
205
242
|
use<TQuery = unknown, TParams = unknown, TBody = unknown, UReturns extends ReturnsMap = {}, TQueryIn = unknown, TParamsIn = unknown, TBodyIn = unknown, R = unknown>(options: InlineMiddlewareOptions<HandlerContext<Acc, {
|
|
206
243
|
query: TQuery;
|
|
207
244
|
params: TParams;
|
|
@@ -53,11 +53,11 @@ export type MiddlewareReturnFromParts<TQuery, TParams, TBody, TState, TQueryIn =
|
|
|
53
53
|
};
|
|
54
54
|
};
|
|
55
55
|
type UnitRuntimeContext = Omit<RuntimeContextFields<NativeContext>, "var">;
|
|
56
|
-
export type StandaloneMiddlewareContext<TQuery = unknown, TParams = unknown, TBody = unknown, TAppContext extends Record<string, unknown> = AppContext> = Simplify<TAppContext & UnitRuntimeContext & {
|
|
56
|
+
export type StandaloneMiddlewareContext<TQuery = unknown, TParams = unknown, TBody = unknown, TAppContext extends Record<string, unknown> = AppContext, TState = {}> = Simplify<TAppContext & UnitRuntimeContext & {
|
|
57
57
|
query: Simplify<UnwrapPart<TQuery>>;
|
|
58
58
|
params: Simplify<UnwrapPart<TParams>>;
|
|
59
59
|
body: Simplify<UnwrapPart<TBody>>;
|
|
60
|
-
state:
|
|
60
|
+
state: Simplify<UnwrapPart<TState>>;
|
|
61
61
|
headers: TaserHeaders;
|
|
62
62
|
cookies: TaserCookieJar;
|
|
63
63
|
}>;
|
|
@@ -75,9 +75,11 @@ export type HandlerContext<Acc extends readonly unknown[], Validators extends Va
|
|
|
75
75
|
headers: TaserHeaders;
|
|
76
76
|
cookies: TaserCookieJar;
|
|
77
77
|
}>;
|
|
78
|
-
export type MiddlewareUnit<TAcc = unknown, TReturns extends ReturnsMap = {}> = MiddlewareDefinition & {
|
|
78
|
+
export type MiddlewareUnit<TAcc = unknown, TReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown> = MiddlewareDefinition & {
|
|
79
79
|
readonly __middlewareAcc: TAcc;
|
|
80
80
|
readonly __returns?: TReturns;
|
|
81
|
+
readonly __requiredLayouts?: TRequiredLayouts;
|
|
82
|
+
readonly __requiredState?: TRequiredState;
|
|
81
83
|
};
|
|
82
84
|
export type HandlerUnit<_Acc extends readonly unknown[], _Validators extends ValidatorParts, TReturns extends ReturnsMap = {}, TOutput = Response> = {
|
|
83
85
|
readonly __returns?: TReturns;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"units.js","names":[],"sources":["../../../src/types/units.ts"],"sourcesContent":["import type { Awaitable, TaserCookieJar, TaserHeaders } from \"@taserjs/router-core\";\nimport type { ReplyResult } from \"@taserjs/router-utils\";\n\nimport type { RouterRegister } from \"../register.js\";\nimport type {\n MergeMiddlewareField,\n MergePart,\n RequestShape,\n RuntimeContextFields,\n Simplify,\n UnwrapPart,\n} from \"./type-utils.js\";\nimport type { ReturnsMap } from \"./returns.js\";\nimport type { Schema } from \"./schema.js\";\n\nexport type { HttpMethod, Method } from \"./type-utils.js\";\nexport type {\n EmptyReturns,\n MergeReturns,\n ReturnsMap,\n HandlerReply,\n HasReturns,\n StatusCode,\n ValidHandlerReply,\n EnforceHandlerReply,\n} from \"./returns.js\";\n\n/** Default empty app context for standalone units without a bound router instance. */\nexport type AppContext = Record<never, never>;\n\nexport type NativeContext = RouterRegister extends { NativeContext: infer N } ? N : unknown;\n\nexport type ValidatorParts = {\n query?: unknown;\n params?: unknown;\n body?: unknown;\n queryIn?: unknown;\n paramsIn?: unknown;\n bodyIn?: unknown;\n};\n\nexport declare const StateBrand: unique symbol;\n\nexport type NextResult<TState = unknown> = ReplyResult & {\n readonly [StateBrand]?: TState;\n};\n\nexport type ExtractState<T> = [Extract<Awaited<T>, { [StateBrand]?: unknown }>] extends [never]\n ? {}\n : Extract<Awaited<T>, { [StateBrand]?: unknown }> extends { [StateBrand]?: infer S }\n ? [S] extends [never]\n ? {}\n : S\n : {};\n\nexport type IsUnknown<T> = [unknown] extends [T] ? true : false;\n\nexport type NextFn<TExpectedState = unknown> =\n IsUnknown<TExpectedState> extends true\n ? <S extends Record<string, unknown> = {}>(state?: S) => Promise<NextResult<S>>\n : (state: TExpectedState) => Promise<NextResult<TExpectedState>>;\n\nexport type MiddlewareNext = NextFn;\n\nexport type MiddlewareDefinition = {\n query?: unknown;\n params?: unknown;\n body?: unknown;\n returns?: ReturnsMap;\n handler: (ctx: unknown, next: MiddlewareNext) => Awaitable<ReplyResult | Response | unknown>;\n};\n\nexport type MiddlewareReturnFromParts<\n TQuery,\n TParams,\n TBody,\n TState,\n TQueryIn = TQuery,\n TParamsIn = TParams,\n TBodyIn = TBody,\n> = {\n query: Simplify<UnwrapPart<TQuery>>;\n params: Simplify<UnwrapPart<TParams>>;\n body: Simplify<UnwrapPart<TBody>>;\n state: Simplify<UnwrapPart<TState>>;\n /** Pre-parse shapes merged into route `$Infer.Input`. */\n input: {\n query: RequestShape<TQueryIn, TQuery>;\n params: RequestShape<TParamsIn, TParams>;\n body: RequestShape<TBodyIn, TBody>;\n };\n};\n\ntype UnitRuntimeContext = Omit<RuntimeContextFields<NativeContext>, \"var\">;\n\nexport type StandaloneMiddlewareContext<\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TAppContext extends Record<string, unknown> = AppContext,\n> = Simplify<\n TAppContext &\n UnitRuntimeContext & {\n query: Simplify<UnwrapPart<TQuery>>;\n params: Simplify<UnwrapPart<TParams>>;\n body: Simplify<UnwrapPart<TBody>>;\n state:
|
|
1
|
+
{"version":3,"file":"units.js","names":[],"sources":["../../../src/types/units.ts"],"sourcesContent":["import type { Awaitable, TaserCookieJar, TaserHeaders } from \"@taserjs/router-core\";\nimport type { ReplyResult } from \"@taserjs/router-utils\";\n\nimport type { RouterRegister } from \"../register.js\";\nimport type {\n MergeMiddlewareField,\n MergePart,\n RequestShape,\n RuntimeContextFields,\n Simplify,\n UnwrapPart,\n} from \"./type-utils.js\";\nimport type { ReturnsMap } from \"./returns.js\";\nimport type { Schema } from \"./schema.js\";\n\nexport type { HttpMethod, Method } from \"./type-utils.js\";\nexport type {\n EmptyReturns,\n MergeReturns,\n ReturnsMap,\n HandlerReply,\n HasReturns,\n StatusCode,\n ValidHandlerReply,\n EnforceHandlerReply,\n} from \"./returns.js\";\n\n/** Default empty app context for standalone units without a bound router instance. */\nexport type AppContext = Record<never, never>;\n\nexport type NativeContext = RouterRegister extends { NativeContext: infer N } ? N : unknown;\n\nexport type ValidatorParts = {\n query?: unknown;\n params?: unknown;\n body?: unknown;\n queryIn?: unknown;\n paramsIn?: unknown;\n bodyIn?: unknown;\n};\n\nexport declare const StateBrand: unique symbol;\n\nexport type NextResult<TState = unknown> = ReplyResult & {\n readonly [StateBrand]?: TState;\n};\n\nexport type ExtractState<T> = [Extract<Awaited<T>, { [StateBrand]?: unknown }>] extends [never]\n ? {}\n : Extract<Awaited<T>, { [StateBrand]?: unknown }> extends { [StateBrand]?: infer S }\n ? [S] extends [never]\n ? {}\n : S\n : {};\n\nexport type IsUnknown<T> = [unknown] extends [T] ? true : false;\n\nexport type NextFn<TExpectedState = unknown> =\n IsUnknown<TExpectedState> extends true\n ? <S extends Record<string, unknown> = {}>(state?: S) => Promise<NextResult<S>>\n : (state: TExpectedState) => Promise<NextResult<TExpectedState>>;\n\nexport type MiddlewareNext = NextFn;\n\nexport type MiddlewareDefinition = {\n query?: unknown;\n params?: unknown;\n body?: unknown;\n returns?: ReturnsMap;\n handler: (ctx: unknown, next: MiddlewareNext) => Awaitable<ReplyResult | Response | unknown>;\n};\n\nexport type MiddlewareReturnFromParts<\n TQuery,\n TParams,\n TBody,\n TState,\n TQueryIn = TQuery,\n TParamsIn = TParams,\n TBodyIn = TBody,\n> = {\n query: Simplify<UnwrapPart<TQuery>>;\n params: Simplify<UnwrapPart<TParams>>;\n body: Simplify<UnwrapPart<TBody>>;\n state: Simplify<UnwrapPart<TState>>;\n /** Pre-parse shapes merged into route `$Infer.Input`. */\n input: {\n query: RequestShape<TQueryIn, TQuery>;\n params: RequestShape<TParamsIn, TParams>;\n body: RequestShape<TBodyIn, TBody>;\n };\n};\n\ntype UnitRuntimeContext = Omit<RuntimeContextFields<NativeContext>, \"var\">;\n\nexport type StandaloneMiddlewareContext<\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TAppContext extends Record<string, unknown> = AppContext,\n TState = {},\n> = Simplify<\n TAppContext &\n UnitRuntimeContext & {\n query: Simplify<UnwrapPart<TQuery>>;\n params: Simplify<UnwrapPart<TParams>>;\n body: Simplify<UnwrapPart<TBody>>;\n state: Simplify<UnwrapPart<TState>>;\n headers: TaserHeaders;\n cookies: TaserCookieJar;\n }\n>;\n\nexport type HandlerContext<\n Acc extends readonly unknown[],\n Validators extends ValidatorParts,\n TAppContext extends Record<string, unknown> = AppContext,\n> = Simplify<\n TAppContext &\n UnitRuntimeContext & {\n query: Simplify<\n MergePart<\n Validators extends { query?: infer Q } ? Q : unknown,\n MergeMiddlewareField<Acc, \"query\">\n >\n >;\n params: Simplify<\n MergePart<\n Validators extends { params?: infer P } ? P : unknown,\n MergeMiddlewareField<Acc, \"params\">\n >\n >;\n body: Simplify<\n MergePart<\n Validators extends { body?: infer B } ? B : unknown,\n MergeMiddlewareField<Acc, \"body\">\n >\n >;\n state: Simplify<MergeMiddlewareField<Acc, \"state\">>;\n headers: TaserHeaders;\n cookies: TaserCookieJar;\n }\n>;\n\nexport type MiddlewareUnit<\n TAcc = unknown,\n TReturns extends ReturnsMap = {},\n TRequiredLayouts = unknown,\n TRequiredState = unknown,\n> = MiddlewareDefinition & {\n readonly __middlewareAcc: TAcc;\n readonly __returns?: TReturns;\n readonly __requiredLayouts?: TRequiredLayouts;\n readonly __requiredState?: TRequiredState;\n};\n\nexport type HandlerUnit<\n _Acc extends readonly unknown[],\n _Validators extends ValidatorParts,\n TReturns extends ReturnsMap = {},\n TOutput = Response,\n> = {\n readonly __returns?: TReturns;\n readonly $Infer: {\n Output: TOutput;\n };\n middlewares: readonly MiddlewareDefinition[];\n handler: (ctx: unknown) => Awaitable<ReplyResult | Response>;\n returns?: ReturnsMap;\n query?: Schema<unknown>;\n params?: Schema<unknown>;\n body?: Schema<unknown>;\n};\n\nexport type InlineMiddlewareOptions<\n Ctx = unknown,\n TQuery = unknown,\n TParams = unknown,\n TBody = unknown,\n TReturns extends ReturnsMap = {},\n TQueryIn = unknown,\n TParamsIn = unknown,\n TBodyIn = unknown,\n R = unknown,\n> = {\n query?: Schema<TQuery, TQueryIn>;\n params?: Schema<TParams, TParamsIn>;\n body?: Schema<TBody, TBodyIn>;\n returns?: TReturns;\n handler: (ctx: Ctx, next: NextFn) => Awaitable<R>;\n};\n\nexport function isHandlerUnit(\n value: unknown,\n): value is HandlerUnit<readonly unknown[], ValidatorParts> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"handler\" in value &&\n \"middlewares\" in value &&\n Array.isArray((value as HandlerUnit<readonly unknown[], ValidatorParts>).middlewares)\n );\n}\n"],"mappings":";AAgMA,SAAgB,cACd,OAC0D;CAC1D,OACE,OAAO,UAAU,YACjB,UAAU,QACV,aAAa,SACb,iBAAiB,SACjB,MAAM,QAAS,MAA0D,WAAW;AAExF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taserjs/router",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Type-safe Node.js router with runtime validation and middleware",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"repository": {
|
|
@@ -147,8 +147,8 @@
|
|
|
147
147
|
"dependencies": {
|
|
148
148
|
"@standard-schema/spec": "^1.1.0",
|
|
149
149
|
"hono": "^4.10.3",
|
|
150
|
-
"@taserjs/router-core": "0.0.
|
|
151
|
-
"@taserjs/router-utils": "0.0.
|
|
150
|
+
"@taserjs/router-core": "0.0.4",
|
|
151
|
+
"@taserjs/router-utils": "0.0.4"
|
|
152
152
|
},
|
|
153
153
|
"devDependencies": {
|
|
154
154
|
"@tanstack/vite-config": "^0.6.0",
|
package/src/define/middleware.ts
CHANGED
|
@@ -10,14 +10,25 @@ import type {
|
|
|
10
10
|
NextFn,
|
|
11
11
|
StandaloneMiddlewareContext,
|
|
12
12
|
} from "../types/units.js";
|
|
13
|
+
import type {
|
|
14
|
+
LayoutId,
|
|
15
|
+
ResolveLayoutMiddlewaresState,
|
|
16
|
+
ResolveLayoutsState,
|
|
17
|
+
} from "../types/index.js";
|
|
13
18
|
import type { Schema } from "../types/schema.js";
|
|
14
19
|
|
|
15
20
|
type HonoMiddlewareHandler = Parameters<typeof createTaserCompatHandler>[0];
|
|
16
21
|
|
|
17
|
-
type HonoMiddlewareUnit = MiddlewareUnit<
|
|
22
|
+
type HonoMiddlewareUnit = MiddlewareUnit<
|
|
23
|
+
MiddlewareReturnFromParts<unknown, unknown, unknown, {}>,
|
|
24
|
+
{},
|
|
25
|
+
null,
|
|
26
|
+
{}
|
|
27
|
+
>;
|
|
18
28
|
|
|
19
29
|
export type DefineMiddlewareOptions<
|
|
20
30
|
TState = unknown,
|
|
31
|
+
TRequires = {},
|
|
21
32
|
TQuery = unknown,
|
|
22
33
|
TParams = unknown,
|
|
23
34
|
TBody = unknown,
|
|
@@ -33,7 +44,67 @@ export type DefineMiddlewareOptions<
|
|
|
33
44
|
body?: Schema<TBody, TBodyIn>;
|
|
34
45
|
returns?: TReturns;
|
|
35
46
|
handler: (
|
|
36
|
-
ctx: StandaloneMiddlewareContext<TQuery, TParams, TBody, TAppContext>,
|
|
47
|
+
ctx: StandaloneMiddlewareContext<TQuery, TParams, TBody, TAppContext, TRequires>,
|
|
48
|
+
next: NextFn<NoInfer<TState>>,
|
|
49
|
+
) => Awaitable<R>;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export type ScopedMiddlewareOptions<
|
|
53
|
+
Layout extends LayoutId,
|
|
54
|
+
TState = unknown,
|
|
55
|
+
TRequires = {},
|
|
56
|
+
TQuery = unknown,
|
|
57
|
+
TParams = unknown,
|
|
58
|
+
TBody = unknown,
|
|
59
|
+
TReturns extends ReturnsMap = {},
|
|
60
|
+
TQueryIn = unknown,
|
|
61
|
+
TParamsIn = unknown,
|
|
62
|
+
TBodyIn = unknown,
|
|
63
|
+
TAppContext extends Record<string, unknown> = AppContext,
|
|
64
|
+
R = unknown,
|
|
65
|
+
> = {
|
|
66
|
+
query?: Schema<TQuery, TQueryIn>;
|
|
67
|
+
params?: Schema<TParams, TParamsIn>;
|
|
68
|
+
body?: Schema<TBody, TBodyIn>;
|
|
69
|
+
returns?: TReturns;
|
|
70
|
+
handler: (
|
|
71
|
+
ctx: StandaloneMiddlewareContext<
|
|
72
|
+
TQuery,
|
|
73
|
+
TParams,
|
|
74
|
+
TBody,
|
|
75
|
+
TAppContext,
|
|
76
|
+
ResolveLayoutMiddlewaresState<Layout> & TRequires
|
|
77
|
+
>,
|
|
78
|
+
next: NextFn<NoInfer<TState>>,
|
|
79
|
+
) => Awaitable<R>;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export type MultiScopedMiddlewareOptions<
|
|
83
|
+
Layouts extends readonly LayoutId[],
|
|
84
|
+
TState = unknown,
|
|
85
|
+
TRequires = {},
|
|
86
|
+
TQuery = unknown,
|
|
87
|
+
TParams = unknown,
|
|
88
|
+
TBody = unknown,
|
|
89
|
+
TReturns extends ReturnsMap = {},
|
|
90
|
+
TQueryIn = unknown,
|
|
91
|
+
TParamsIn = unknown,
|
|
92
|
+
TBodyIn = unknown,
|
|
93
|
+
TAppContext extends Record<string, unknown> = AppContext,
|
|
94
|
+
R = unknown,
|
|
95
|
+
> = {
|
|
96
|
+
query?: Schema<TQuery, TQueryIn>;
|
|
97
|
+
params?: Schema<TParams, TParamsIn>;
|
|
98
|
+
body?: Schema<TBody, TBodyIn>;
|
|
99
|
+
returns?: TReturns;
|
|
100
|
+
handler: (
|
|
101
|
+
ctx: StandaloneMiddlewareContext<
|
|
102
|
+
TQuery,
|
|
103
|
+
TParams,
|
|
104
|
+
TBody,
|
|
105
|
+
TAppContext,
|
|
106
|
+
ResolveLayoutsState<Layouts> & TRequires
|
|
107
|
+
>,
|
|
37
108
|
next: NextFn<NoInfer<TState>>,
|
|
38
109
|
) => Awaitable<R>;
|
|
39
110
|
};
|
|
@@ -41,7 +112,96 @@ export type DefineMiddlewareOptions<
|
|
|
41
112
|
export function defineMiddleware(middleware: HonoMiddlewareHandler): HonoMiddlewareUnit;
|
|
42
113
|
|
|
43
114
|
export function defineMiddleware<
|
|
115
|
+
const Layout extends LayoutId,
|
|
116
|
+
TState = unknown,
|
|
117
|
+
TRequires = {},
|
|
118
|
+
TAppContext extends Record<string, unknown> = AppContext,
|
|
119
|
+
TQuery = unknown,
|
|
120
|
+
TParams = unknown,
|
|
121
|
+
TBody = unknown,
|
|
122
|
+
TReturns extends ReturnsMap = {},
|
|
123
|
+
TQueryIn = unknown,
|
|
124
|
+
TParamsIn = unknown,
|
|
125
|
+
TBodyIn = unknown,
|
|
126
|
+
R = unknown,
|
|
127
|
+
>(
|
|
128
|
+
layout: Layout,
|
|
129
|
+
options: ScopedMiddlewareOptions<
|
|
130
|
+
Layout,
|
|
131
|
+
TState,
|
|
132
|
+
TRequires,
|
|
133
|
+
TQuery,
|
|
134
|
+
TParams,
|
|
135
|
+
TBody,
|
|
136
|
+
TReturns,
|
|
137
|
+
TQueryIn,
|
|
138
|
+
TParamsIn,
|
|
139
|
+
TBodyIn,
|
|
140
|
+
TAppContext,
|
|
141
|
+
R
|
|
142
|
+
>,
|
|
143
|
+
): MiddlewareUnit<
|
|
144
|
+
MiddlewareReturnFromParts<
|
|
145
|
+
TQuery,
|
|
146
|
+
TParams,
|
|
147
|
+
TBody,
|
|
148
|
+
IsUnknown<TState> extends true ? ExtractState<R> : TState,
|
|
149
|
+
TQueryIn,
|
|
150
|
+
TParamsIn,
|
|
151
|
+
TBodyIn
|
|
152
|
+
>,
|
|
153
|
+
TReturns,
|
|
154
|
+
Layout,
|
|
155
|
+
TRequires
|
|
156
|
+
>;
|
|
157
|
+
|
|
158
|
+
export function defineMiddleware<
|
|
159
|
+
const Layouts extends readonly [LayoutId, ...LayoutId[]],
|
|
44
160
|
TState = unknown,
|
|
161
|
+
TRequires = {},
|
|
162
|
+
TAppContext extends Record<string, unknown> = AppContext,
|
|
163
|
+
TQuery = unknown,
|
|
164
|
+
TParams = unknown,
|
|
165
|
+
TBody = unknown,
|
|
166
|
+
TReturns extends ReturnsMap = {},
|
|
167
|
+
TQueryIn = unknown,
|
|
168
|
+
TParamsIn = unknown,
|
|
169
|
+
TBodyIn = unknown,
|
|
170
|
+
R = unknown,
|
|
171
|
+
>(
|
|
172
|
+
layouts: Layouts,
|
|
173
|
+
options: MultiScopedMiddlewareOptions<
|
|
174
|
+
Layouts,
|
|
175
|
+
TState,
|
|
176
|
+
TRequires,
|
|
177
|
+
TQuery,
|
|
178
|
+
TParams,
|
|
179
|
+
TBody,
|
|
180
|
+
TReturns,
|
|
181
|
+
TQueryIn,
|
|
182
|
+
TParamsIn,
|
|
183
|
+
TBodyIn,
|
|
184
|
+
TAppContext,
|
|
185
|
+
R
|
|
186
|
+
>,
|
|
187
|
+
): MiddlewareUnit<
|
|
188
|
+
MiddlewareReturnFromParts<
|
|
189
|
+
TQuery,
|
|
190
|
+
TParams,
|
|
191
|
+
TBody,
|
|
192
|
+
IsUnknown<TState> extends true ? ExtractState<R> : TState,
|
|
193
|
+
TQueryIn,
|
|
194
|
+
TParamsIn,
|
|
195
|
+
TBodyIn
|
|
196
|
+
>,
|
|
197
|
+
TReturns,
|
|
198
|
+
Layouts,
|
|
199
|
+
TRequires
|
|
200
|
+
>;
|
|
201
|
+
|
|
202
|
+
export function defineMiddleware<
|
|
203
|
+
TState = unknown,
|
|
204
|
+
TRequires = {},
|
|
45
205
|
TAppContext extends Record<string, unknown> = AppContext,
|
|
46
206
|
TQuery = unknown,
|
|
47
207
|
TParams = unknown,
|
|
@@ -54,6 +214,7 @@ export function defineMiddleware<
|
|
|
54
214
|
>(
|
|
55
215
|
options: DefineMiddlewareOptions<
|
|
56
216
|
TState,
|
|
217
|
+
TRequires,
|
|
57
218
|
TQuery,
|
|
58
219
|
TParams,
|
|
59
220
|
TBody,
|
|
@@ -74,21 +235,50 @@ export function defineMiddleware<
|
|
|
74
235
|
TParamsIn,
|
|
75
236
|
TBodyIn
|
|
76
237
|
>,
|
|
77
|
-
TReturns
|
|
238
|
+
TReturns,
|
|
239
|
+
null,
|
|
240
|
+
TRequires
|
|
78
241
|
>;
|
|
79
242
|
|
|
80
243
|
export function defineMiddleware(
|
|
81
|
-
|
|
244
|
+
first:
|
|
245
|
+
| string
|
|
246
|
+
| readonly string[]
|
|
82
247
|
| HonoMiddlewareHandler
|
|
83
|
-
| DefineMiddlewareOptions<any, any, any, any, any, any, any, any, any, any>,
|
|
248
|
+
| DefineMiddlewareOptions<any, any, any, any, any, any, any, any, any, any, any>,
|
|
249
|
+
second?: DefineMiddlewareOptions<any, any, any, any, any, any, any, any, any, any, any>,
|
|
84
250
|
): unknown {
|
|
85
|
-
if (typeof
|
|
86
|
-
const
|
|
251
|
+
if (typeof first === "string" || Array.isArray(first)) {
|
|
252
|
+
const options = second!;
|
|
253
|
+
const unit = {
|
|
254
|
+
...options,
|
|
255
|
+
__middlewareAcc: undefined as unknown,
|
|
256
|
+
...(options?.returns ? { __returns: options.returns } : {}),
|
|
257
|
+
__requiredLayouts: first,
|
|
258
|
+
};
|
|
259
|
+
return unit;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (typeof first === "function") {
|
|
263
|
+
const honoMiddleware = first as HonoMiddlewareHandler;
|
|
87
264
|
return defineMiddleware({
|
|
88
265
|
handler: (ctx, next) => createTaserCompatHandler(honoMiddleware)(ctx, next),
|
|
89
266
|
});
|
|
90
267
|
}
|
|
91
268
|
|
|
269
|
+
const options = first as DefineMiddlewareOptions<
|
|
270
|
+
any,
|
|
271
|
+
any,
|
|
272
|
+
any,
|
|
273
|
+
any,
|
|
274
|
+
any,
|
|
275
|
+
any,
|
|
276
|
+
any,
|
|
277
|
+
any,
|
|
278
|
+
any,
|
|
279
|
+
any,
|
|
280
|
+
any
|
|
281
|
+
>;
|
|
92
282
|
const unit = {
|
|
93
283
|
...options,
|
|
94
284
|
__middlewareAcc: undefined as unknown,
|
package/src/types/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
RequestShape,
|
|
8
8
|
RuntimeContextFields,
|
|
9
9
|
Simplify,
|
|
10
|
+
UnionToIntersection,
|
|
10
11
|
} from "./type-utils.js";
|
|
11
12
|
import type { ReturnsMap, ValidHandlerReply } from "./returns.js";
|
|
12
13
|
import type { Schema } from "./schema.js";
|
|
@@ -111,6 +112,27 @@ type ResolveLayoutMiddlewares<Layout extends LayoutId | null> = Layout extends n
|
|
|
111
112
|
]
|
|
112
113
|
: readonly [];
|
|
113
114
|
|
|
115
|
+
export type ResolveLayoutIdChain<L extends LayoutId | null> = L extends null
|
|
116
|
+
? readonly []
|
|
117
|
+
: L extends LayoutId
|
|
118
|
+
? readonly [...ResolveLayoutIdChain<LayoutParent<L>>, L]
|
|
119
|
+
: readonly [];
|
|
120
|
+
|
|
121
|
+
export type ResolveLayoutMiddlewaresState<Layout extends LayoutId | null> = Layout extends LayoutId
|
|
122
|
+
? MergeMiddlewareField<ResolveLayoutMiddlewares<Layout>, "state">
|
|
123
|
+
: {};
|
|
124
|
+
|
|
125
|
+
export type ResolveLayoutsState<Layouts extends LayoutId | readonly LayoutId[]> =
|
|
126
|
+
Layouts extends LayoutId
|
|
127
|
+
? ResolveLayoutMiddlewaresState<Layouts>
|
|
128
|
+
: Layouts extends readonly LayoutId[]
|
|
129
|
+
? UnionToIntersection<
|
|
130
|
+
Layouts[number] extends infer L extends LayoutId
|
|
131
|
+
? ResolveLayoutMiddlewaresState<L>
|
|
132
|
+
: never
|
|
133
|
+
>
|
|
134
|
+
: {};
|
|
135
|
+
|
|
114
136
|
/** Fold layout middleware Acc from a route's layoutChain (shallow → deep). */
|
|
115
137
|
type ResolveLayoutChainMiddlewares<Chain extends readonly LayoutId[]> = Chain extends readonly [
|
|
116
138
|
infer Head extends LayoutId,
|
|
@@ -268,6 +290,40 @@ type IsNever<T> = [T] extends [never] ? true : false;
|
|
|
268
290
|
|
|
269
291
|
type IsEmptyObject<T> = [keyof T] extends [never] ? true : false;
|
|
270
292
|
|
|
293
|
+
export type IsLayoutAllowed<TRequiredLayouts, TChain extends readonly LayoutId[]> = [
|
|
294
|
+
TRequiredLayouts,
|
|
295
|
+
] extends [never]
|
|
296
|
+
? true
|
|
297
|
+
: [unknown] extends [TRequiredLayouts]
|
|
298
|
+
? true
|
|
299
|
+
: [null] extends [TRequiredLayouts]
|
|
300
|
+
? true
|
|
301
|
+
: [undefined] extends [TRequiredLayouts]
|
|
302
|
+
? true
|
|
303
|
+
: TRequiredLayouts extends LayoutId
|
|
304
|
+
? TRequiredLayouts extends TChain[number]
|
|
305
|
+
? true
|
|
306
|
+
: false
|
|
307
|
+
: TRequiredLayouts extends readonly LayoutId[]
|
|
308
|
+
? [TRequiredLayouts[number] & TChain[number]] extends [never]
|
|
309
|
+
? false
|
|
310
|
+
: true
|
|
311
|
+
: true;
|
|
312
|
+
|
|
313
|
+
export type IsStateSatisfied<TActualState, TRequiredState> = [TRequiredState] extends [never]
|
|
314
|
+
? true
|
|
315
|
+
: [unknown] extends [TRequiredState]
|
|
316
|
+
? true
|
|
317
|
+
: [null] extends [TRequiredState]
|
|
318
|
+
? true
|
|
319
|
+
: [undefined] extends [TRequiredState]
|
|
320
|
+
? true
|
|
321
|
+
: [IsEmptyObject<TRequiredState>] extends [true]
|
|
322
|
+
? true
|
|
323
|
+
: [TActualState] extends [TRequiredState]
|
|
324
|
+
? true
|
|
325
|
+
: false;
|
|
326
|
+
|
|
271
327
|
type InputFacet<T, K extends string> =
|
|
272
328
|
IsNever<T> extends true ? {} : IsEmptyObject<T> extends true ? {} : { [Key in K]: T };
|
|
273
329
|
|
|
@@ -380,8 +436,22 @@ export type MiddlewareBuilder<
|
|
|
380
436
|
readonly $Infer: {
|
|
381
437
|
Context: MiddlewareChainContext<Layout, Acc, unknown, unknown, unknown, TAppContext>;
|
|
382
438
|
};
|
|
383
|
-
use<TAcc, TReturns extends ReturnsMap = {}>(
|
|
384
|
-
unit: MiddlewareUnit<TAcc, TReturns>,
|
|
439
|
+
use<TAcc, TReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(
|
|
440
|
+
unit: MiddlewareUnit<TAcc, TReturns, TRequiredLayouts, TRequiredState>,
|
|
441
|
+
..._assert: [
|
|
442
|
+
IsLayoutAllowed<TRequiredLayouts, ResolveLayoutIdChain<Layout>>,
|
|
443
|
+
IsStateSatisfied<MiddlewareChainField<Layout, Acc, "state">, TRequiredState>,
|
|
444
|
+
] extends [true, true]
|
|
445
|
+
? []
|
|
446
|
+
: [
|
|
447
|
+
{
|
|
448
|
+
error: "Middleware cannot be attached to this layout";
|
|
449
|
+
requiredLayouts: TRequiredLayouts;
|
|
450
|
+
layoutChain: ResolveLayoutIdChain<Layout>;
|
|
451
|
+
requiredState: TRequiredState;
|
|
452
|
+
actualState: MiddlewareChainField<Layout, Acc, "state">;
|
|
453
|
+
},
|
|
454
|
+
]
|
|
385
455
|
): MiddlewareBuilder<Layout, readonly [...Acc, TAcc], TAppContext>;
|
|
386
456
|
use<
|
|
387
457
|
TQuery = unknown,
|
|
@@ -489,8 +559,22 @@ export type RouteBuilder<
|
|
|
489
559
|
returns<const M extends ReturnsMap>(
|
|
490
560
|
map: M,
|
|
491
561
|
): RouteBuilder<Path, TMethod, Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>;
|
|
492
|
-
use<TAcc, UReturns extends ReturnsMap = {}>(
|
|
493
|
-
unit: MiddlewareUnit<TAcc, UReturns>,
|
|
562
|
+
use<TAcc, UReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(
|
|
563
|
+
unit: MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequiredState>,
|
|
564
|
+
..._assert: [
|
|
565
|
+
IsLayoutAllowed<TRequiredLayouts, RouteLayoutChain<Path, TMethod>>,
|
|
566
|
+
IsStateSatisfied<RouteResolvedField<Path, TMethod, Acc, "state">, TRequiredState>,
|
|
567
|
+
] extends [true, true]
|
|
568
|
+
? []
|
|
569
|
+
: [
|
|
570
|
+
{
|
|
571
|
+
error: "Middleware cannot be attached to this route";
|
|
572
|
+
requiredLayouts: TRequiredLayouts;
|
|
573
|
+
routeLayoutChain: RouteLayoutChain<Path, TMethod>;
|
|
574
|
+
requiredState: TRequiredState;
|
|
575
|
+
actualState: RouteResolvedField<Path, TMethod, Acc, "state">;
|
|
576
|
+
},
|
|
577
|
+
]
|
|
494
578
|
): RouteBuilder<
|
|
495
579
|
Path,
|
|
496
580
|
TMethod,
|
|
@@ -581,8 +665,19 @@ export type HandlerBuilder<
|
|
|
581
665
|
returns<const M extends ReturnsMap>(
|
|
582
666
|
map: M,
|
|
583
667
|
): HandlerBuilder<Acc, Validators, Omit<TReturns, keyof M> & M, TAppContext>;
|
|
584
|
-
use<TAcc, UReturns extends ReturnsMap = {}>(
|
|
585
|
-
unit: MiddlewareUnit<TAcc, UReturns>,
|
|
668
|
+
use<TAcc, UReturns extends ReturnsMap = {}, TRequiredLayouts = unknown, TRequiredState = unknown>(
|
|
669
|
+
unit: MiddlewareUnit<TAcc, UReturns, TRequiredLayouts, TRequiredState>,
|
|
670
|
+
..._assert: [IsStateSatisfied<MergeMiddlewareField<Acc, "state">, TRequiredState>] extends [
|
|
671
|
+
true,
|
|
672
|
+
]
|
|
673
|
+
? []
|
|
674
|
+
: [
|
|
675
|
+
{
|
|
676
|
+
error: "Middleware cannot be attached to this handler";
|
|
677
|
+
requiredState: TRequiredState;
|
|
678
|
+
actualState: MergeMiddlewareField<Acc, "state">;
|
|
679
|
+
},
|
|
680
|
+
]
|
|
586
681
|
): HandlerBuilder<
|
|
587
682
|
readonly [...Acc, TAcc],
|
|
588
683
|
Validators,
|
package/src/types/units.ts
CHANGED
|
@@ -98,13 +98,14 @@ export type StandaloneMiddlewareContext<
|
|
|
98
98
|
TParams = unknown,
|
|
99
99
|
TBody = unknown,
|
|
100
100
|
TAppContext extends Record<string, unknown> = AppContext,
|
|
101
|
+
TState = {},
|
|
101
102
|
> = Simplify<
|
|
102
103
|
TAppContext &
|
|
103
104
|
UnitRuntimeContext & {
|
|
104
105
|
query: Simplify<UnwrapPart<TQuery>>;
|
|
105
106
|
params: Simplify<UnwrapPart<TParams>>;
|
|
106
107
|
body: Simplify<UnwrapPart<TBody>>;
|
|
107
|
-
state:
|
|
108
|
+
state: Simplify<UnwrapPart<TState>>;
|
|
108
109
|
headers: TaserHeaders;
|
|
109
110
|
cookies: TaserCookieJar;
|
|
110
111
|
}
|
|
@@ -144,9 +145,13 @@ export type HandlerContext<
|
|
|
144
145
|
export type MiddlewareUnit<
|
|
145
146
|
TAcc = unknown,
|
|
146
147
|
TReturns extends ReturnsMap = {},
|
|
148
|
+
TRequiredLayouts = unknown,
|
|
149
|
+
TRequiredState = unknown,
|
|
147
150
|
> = MiddlewareDefinition & {
|
|
148
151
|
readonly __middlewareAcc: TAcc;
|
|
149
152
|
readonly __returns?: TReturns;
|
|
153
|
+
readonly __requiredLayouts?: TRequiredLayouts;
|
|
154
|
+
readonly __requiredState?: TRequiredState;
|
|
150
155
|
};
|
|
151
156
|
|
|
152
157
|
export type HandlerUnit<
|