elysia 2.0.0-exp.60 → 2.0.0-exp.61
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/adapter/web-standard/handler.js +2 -2
- package/dist/adapter/web-standard/handler.mjs +2 -2
- package/dist/base.d.ts +6 -6
- package/dist/base.js +2 -2
- package/dist/base.mjs +3 -3
- package/dist/compile/handler/descriptor.js +5 -4
- package/dist/compile/handler/descriptor.mjs +5 -4
- package/dist/compile/handler/frozen-validator.d.ts +2 -2
- package/dist/compile/handler/frozen-validator.js +2 -2
- package/dist/compile/handler/frozen-validator.mjs +2 -2
- package/dist/compile/handler/jit.js +4 -2
- package/dist/compile/handler/jit.mjs +4 -2
- package/dist/compile/handler/utils.js +1 -0
- package/dist/compile/handler/utils.mjs +1 -0
- package/dist/context.d.ts +5 -1
- package/dist/context.js +11 -0
- package/dist/context.mjs +11 -0
- package/dist/handler/fetch.js +16 -10
- package/dist/handler/fetch.mjs +16 -10
- package/dist/package.js +1 -1
- package/dist/package.mjs +1 -1
- package/dist/plugin/aot/core.js +3 -3
- package/dist/plugin/aot/core.mjs +4 -4
- package/dist/sucrose.d.ts +2 -8
- package/dist/sucrose.js +6 -3
- package/dist/sucrose.mjs +6 -3
- package/dist/type/constants.d.ts +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +3 -3
- package/dist/utils.mjs +3 -3
- package/dist/validator/route.js +9 -9
- package/dist/validator/route.mjs +9 -9
- package/package.json +1 -1
|
@@ -34,7 +34,7 @@ function mapResponseWithSet(response, set, request, owned) {
|
|
|
34
34
|
if (typeof response?.next === "function") return handleStream(response, set, request, void 0, owned);
|
|
35
35
|
return Response.json(response, set);
|
|
36
36
|
case "Number":
|
|
37
|
-
case "Boolean": return new Response(response.toString(), set);
|
|
37
|
+
case "Boolean": return new Response(typeof response === "boolean" ? response ? "true" : "false" : response.toString(), set);
|
|
38
38
|
case "ElysiaFile": return handleElysiaFile(response, set, request);
|
|
39
39
|
case "File":
|
|
40
40
|
case "Blob": return require_adapter_utils.handleFile(response, set, request);
|
|
@@ -73,7 +73,7 @@ function mapCompactResponse(response, request, owned) {
|
|
|
73
73
|
if (response["~ely-form"]) return new Response(require_utils.formToFormData(response));
|
|
74
74
|
return Response.json(response);
|
|
75
75
|
case "Number":
|
|
76
|
-
case "Boolean": return new Response(response.toString());
|
|
76
|
+
case "Boolean": return new Response(typeof response === "boolean" ? response ? "true" : "false" : response.toString());
|
|
77
77
|
case "ElysiaFile": return handleElysiaFile(response, void 0, request);
|
|
78
78
|
case "File":
|
|
79
79
|
case "Blob": return require_adapter_utils.handleFile(response, void 0, request);
|
|
@@ -33,7 +33,7 @@ function mapResponseWithSet(response, set, request, owned) {
|
|
|
33
33
|
if (typeof response?.next === "function") return handleStream(response, set, request, void 0, owned);
|
|
34
34
|
return Response.json(response, set);
|
|
35
35
|
case "Number":
|
|
36
|
-
case "Boolean": return new Response(response.toString(), set);
|
|
36
|
+
case "Boolean": return new Response(typeof response === "boolean" ? response ? "true" : "false" : response.toString(), set);
|
|
37
37
|
case "ElysiaFile": return handleElysiaFile(response, set, request);
|
|
38
38
|
case "File":
|
|
39
39
|
case "Blob": return handleFile(response, set, request);
|
|
@@ -72,7 +72,7 @@ function mapCompactResponse(response, request, owned) {
|
|
|
72
72
|
if (response["~ely-form"]) return new Response(formToFormData(response));
|
|
73
73
|
return Response.json(response);
|
|
74
74
|
case "Number":
|
|
75
|
-
case "Boolean": return new Response(response.toString());
|
|
75
|
+
case "Boolean": return new Response(typeof response === "boolean" ? response ? "true" : "false" : response.toString());
|
|
76
76
|
case "ElysiaFile": return handleElysiaFile(response, void 0, request);
|
|
77
77
|
case "File":
|
|
78
78
|
case "Blob": return handleFile(response, void 0, request);
|
package/dist/base.d.ts
CHANGED
|
@@ -391,7 +391,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
|
|
|
391
391
|
* them with `.use()` instead.
|
|
392
392
|
*/
|
|
393
393
|
guard<const Input extends Metadata['macro'] & InputSchema<keyof Definitions['typebox'] & string>, const Schema extends MergeSchema<UnwrapRoute<Input, Definitions['typebox'], BasePath>, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['schemas'] & Ephemeral['schemas'] & Volatile['schemas'], const MacroContext extends ({} extends Metadata['macroFn'] ? {} : MacroToContext<Metadata['macroFn'], Omit<Input, NonResolvableMacroKey>, Definitions['typebox']>), const BeforeHandle extends MaybeArray<OptionalHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const AfterHandle extends MaybeArray<AfterHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const ErrorHandle extends MaybeArray<ErrorHandler<Definitions['error'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>>(hook: GuardLocalHook<Input, Schema & MacroContext, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>, keyof Metadata['parser'], BeforeHandle, AfterHandle, ErrorHandle> & {
|
|
394
|
-
schema: '
|
|
394
|
+
schema: 'merge';
|
|
395
395
|
}): Elysia<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, {
|
|
396
396
|
derive: Volatile['derive'] & MacroContext['resolve'];
|
|
397
397
|
schema: Volatile['schema'];
|
|
@@ -407,7 +407,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
|
|
|
407
407
|
error: Volatile['error'];
|
|
408
408
|
}>;
|
|
409
409
|
guard<const Input extends Metadata['macro'] & InputSchema<keyof Definitions['typebox'] & string>, const Schema extends MergeSchema<UnwrapRoute<Input, Definitions['typebox'], BasePath>, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['schemas'] & Ephemeral['schemas'] & Volatile['schemas'], const MacroContext extends ({} extends Metadata['macroFn'] ? {} : MacroToContext<Metadata['macroFn'], Omit<Input, NonResolvableMacroKey>, Definitions['typebox']>), const BeforeHandle extends MaybeArray<OptionalHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const AfterHandle extends MaybeArray<AfterHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const ErrorHandle extends MaybeArray<ErrorHandler<Definitions['error'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const NewElysia extends AnyElysia>(hook: GuardLocalHook<Input, Schema & MacroContext, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>, keyof Metadata['parser'], BeforeHandle, AfterHandle, ErrorHandle> & {
|
|
410
|
-
schema: '
|
|
410
|
+
schema: 'merge';
|
|
411
411
|
}, run: (group: Elysia<BasePath, Scope, {
|
|
412
412
|
decorator: Singleton['decorator'];
|
|
413
413
|
store: Singleton['store'];
|
|
@@ -433,7 +433,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
|
|
|
433
433
|
response: Metadata['response'] & MacroContext['response'] & ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle> & ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle> & ElysiaHandlerToResponseSchemaAmbiguous<ErrorHandle>;
|
|
434
434
|
}, {}, Ephemeral, Volatile>) => NewElysia): Elysia<BasePath, Scope, Singleton, Definitions, Metadata, Routes & NewElysia['~Routes'], Ephemeral, Volatile>;
|
|
435
435
|
guard<const Input extends Metadata['macro'] & InputSchema<keyof Definitions['typebox'] & string>, const Schema extends MergeSchema<UnwrapRoute<Input, Definitions['typebox'], BasePath>, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['schemas'] & Ephemeral['schemas'] & Volatile['schemas'], const MacroContext extends ({} extends Metadata['macroFn'] ? {} : MacroToContext<Metadata['macroFn'], Omit<Input, NonResolvableMacroKey>, Definitions['typebox']>), const BeforeHandle extends MaybeArray<OptionalHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const AfterHandle extends MaybeArray<AfterHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const ErrorHandle extends MaybeArray<ErrorHandler<Definitions['error'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>>(scope: 'local', hook: GuardLocalHook<Input, Schema & MacroContext, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>, keyof Metadata['parser'], BeforeHandle, AfterHandle, ErrorHandle> & {
|
|
436
|
-
schema: '
|
|
436
|
+
schema: 'merge';
|
|
437
437
|
}): Elysia<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, {
|
|
438
438
|
derive: Volatile['derive'] & MacroContext['resolve'];
|
|
439
439
|
schema: Volatile['schema'];
|
|
@@ -449,7 +449,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
|
|
|
449
449
|
error: Volatile['error'];
|
|
450
450
|
}>;
|
|
451
451
|
guard<const Input extends Metadata['macro'] & InputSchema<keyof Definitions['typebox'] & string>, const Schema extends MergeSchema<UnwrapRoute<Input, Definitions['typebox'], BasePath>, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['schemas'] & Ephemeral['schemas'] & Volatile['schemas'], const MacroContext extends ({} extends Metadata['macroFn'] ? {} : MacroToContext<Metadata['macroFn'], Omit<Input, NonResolvableMacroKey>, Definitions['typebox']>), const BeforeHandle extends MaybeArray<OptionalHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const AfterHandle extends MaybeArray<AfterHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const ErrorHandle extends MaybeArray<ErrorHandler<Definitions['error'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>>(scope: 'plugin', hook: GuardLocalHook<Input, Schema & MacroContext, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>, keyof Metadata['parser'], BeforeHandle, AfterHandle, ErrorHandle> & {
|
|
452
|
-
schema: '
|
|
452
|
+
schema: 'merge';
|
|
453
453
|
}): Elysia<BasePath, Scope, Singleton, Definitions, Metadata, Routes, {
|
|
454
454
|
derive: Ephemeral['derive'] & MacroContext['resolve'];
|
|
455
455
|
schema: Ephemeral['schema'];
|
|
@@ -465,7 +465,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
|
|
|
465
465
|
error: Ephemeral['error'];
|
|
466
466
|
}, Volatile>;
|
|
467
467
|
guard<const Input extends Metadata['macro'] & InputSchema<keyof Definitions['typebox'] & string>, const Schema extends MergeSchema<UnwrapRoute<Input, Definitions['typebox'], BasePath>, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['schemas'] & Ephemeral['schemas'] & Volatile['schemas'], const MacroContext extends ({} extends Metadata['macroFn'] ? {} : MacroToContext<Metadata['macroFn'], Omit<Input, NonResolvableMacroKey>, Definitions['typebox']>), const BeforeHandle extends MaybeArray<OptionalHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const AfterHandle extends MaybeArray<AfterHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const ErrorHandle extends MaybeArray<ErrorHandler<Definitions['error'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>>(scope: 'global', hook: GuardLocalHook<Input, Schema & MacroContext, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>, keyof Metadata['parser'], BeforeHandle, AfterHandle, ErrorHandle> & {
|
|
468
|
-
schema: '
|
|
468
|
+
schema: 'merge';
|
|
469
469
|
}): Elysia<BasePath, Scope, {
|
|
470
470
|
decorator: Singleton['decorator'];
|
|
471
471
|
store: Singleton['store'];
|
|
@@ -499,7 +499,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
|
|
|
499
499
|
response: Metadata['response'];
|
|
500
500
|
}, {}, Ephemeral, Volatile>) => NewElysia): Elysia<BasePath, Scope, Singleton, Definitions, Metadata, Routes & NewElysia['~Routes'], Ephemeral, Volatile>;
|
|
501
501
|
group<const Prefix extends string, const Input extends Metadata['macro'] & InputSchema<keyof Definitions['typebox'] & string>, const Schema extends MergeSchema<UnwrapRoute<Input, Definitions['typebox'], JoinPath<BasePath, Prefix>>, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['schemas'] & Ephemeral['schemas'] & Volatile['schemas'], const MacroContext extends ({} extends Metadata['macroFn'] ? {} : MacroToContext<Metadata['macroFn'], Omit<Input, NonResolvableMacroKey>, Definitions['typebox']>), const BeforeHandle extends MaybeArray<OptionalHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const AfterHandle extends MaybeArray<AfterHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const ErrorHandle extends MaybeArray<ErrorHandler<Definitions['error'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const NewElysia extends AnyElysia>(prefix: Prefix, schema: GuardLocalHook<Input, Schema & MacroContext, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>, keyof Metadata['parser'], BeforeHandle, AfterHandle, ErrorHandle> & {
|
|
502
|
-
schema: '
|
|
502
|
+
schema: 'merge';
|
|
503
503
|
}, run: (group: Elysia<JoinPath<BasePath, Prefix>, Scope, {
|
|
504
504
|
decorator: Singleton['decorator'];
|
|
505
505
|
store: Singleton['store'];
|
package/dist/base.js
CHANGED
|
@@ -554,7 +554,7 @@ var Elysia = class Elysia {
|
|
|
554
554
|
if (k === "schema") {
|
|
555
555
|
const incoming = Array.isArray(v) ? v : [v];
|
|
556
556
|
if (!input.schemas) input.schemas = [];
|
|
557
|
-
require_utils.
|
|
557
|
+
require_utils.coalesceSchemas(input.schemas, incoming);
|
|
558
558
|
delete input[key];
|
|
559
559
|
continue;
|
|
560
560
|
}
|
|
@@ -564,7 +564,7 @@ var Elysia = class Elysia {
|
|
|
564
564
|
continue;
|
|
565
565
|
}
|
|
566
566
|
input.schemas ??= [];
|
|
567
|
-
require_utils.
|
|
567
|
+
require_utils.coalesceSchemas(input.schemas, [{ [k]: v }]);
|
|
568
568
|
delete input[key];
|
|
569
569
|
continue;
|
|
570
570
|
}
|
package/dist/base.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isBun } from "./universal/constants.mjs";
|
|
2
|
-
import { clonePlainDecorators, clonePlainDeep,
|
|
2
|
+
import { clonePlainDecorators, clonePlainDeep, coalesceSchemas, createErrorEventHandler, eventProperties, fnOrigin, fnv1a, getLoosePath, guardNonPlainLeaves, hookToGuard, invalidateMacroEpoch, isEmpty, isNotEmpty, isRecordNumber, joinPath, macroOrigin, mapDeriveEntry, mergeDeep, mergeResponse, nullObject, pushField, schemaProperties, serializeMacroSeed } from "./utils.mjs";
|
|
3
3
|
import { Ref } from "./type/bridge.mjs";
|
|
4
4
|
import { isProduction } from "./universal/is-production.mjs";
|
|
5
5
|
import { Capture, Compiled, beginCompilerSession, createAotFingerprint, createProgramId, endCompilerSession } from "./compile/aot.mjs";
|
|
@@ -551,7 +551,7 @@ var Elysia = class Elysia {
|
|
|
551
551
|
if (k === "schema") {
|
|
552
552
|
const incoming = Array.isArray(v) ? v : [v];
|
|
553
553
|
if (!input.schemas) input.schemas = [];
|
|
554
|
-
|
|
554
|
+
coalesceSchemas(input.schemas, incoming);
|
|
555
555
|
delete input[key];
|
|
556
556
|
continue;
|
|
557
557
|
}
|
|
@@ -561,7 +561,7 @@ var Elysia = class Elysia {
|
|
|
561
561
|
continue;
|
|
562
562
|
}
|
|
563
563
|
input.schemas ??= [];
|
|
564
|
-
|
|
564
|
+
coalesceSchemas(input.schemas, [{ [k]: v }]);
|
|
565
565
|
delete input[key];
|
|
566
566
|
continue;
|
|
567
567
|
}
|
|
@@ -97,9 +97,9 @@ function describeRoute(input) {
|
|
|
97
97
|
if (hook && typeof hook.parse === "function") hook.parse = [hook.parse];
|
|
98
98
|
const parseLength = Array.isArray(hook?.parse) ? hook.parse.length : 0;
|
|
99
99
|
const parseFirst = Array.isArray(hook?.parse) ? hook.parse[0] : hook?.parse;
|
|
100
|
-
const
|
|
100
|
+
const hasMergeBody = !!hook?.schemas?.some((s) => s?.body);
|
|
101
101
|
const bodylessMethod = method === "GET" || method === "HEAD";
|
|
102
|
-
const hasBody = !!hook?.body ||
|
|
102
|
+
const hasBody = !!hook?.body || hasMergeBody || !bodylessMethod && (parseLength > 0 || inference.body) && parseFirst !== "none";
|
|
103
103
|
const bodyValiIsAsync = hasBody && (isAsyncValidator(vali?.body) || mayReturnPromiseValidator(vali?.body));
|
|
104
104
|
const headersValiIsAsync = vali?.headers && (isAsyncValidator(vali?.headers) || mayReturnPromiseValidator(vali?.headers));
|
|
105
105
|
const paramsValiIsAsync = vali?.params && (isAsyncValidator(vali?.params) || mayReturnPromiseValidator(vali?.params));
|
|
@@ -113,7 +113,8 @@ function describeRoute(input) {
|
|
|
113
113
|
const asyncCookieSign = hasCookieSign && !syncCookieSign;
|
|
114
114
|
const lazyCookieVerify = syncCookieSign && cookieConfig?.verify === "lazy" && !vali?.cookie;
|
|
115
115
|
const hasErrorHook = !!hook?.error?.length;
|
|
116
|
-
const
|
|
116
|
+
const hasStaticAfterResponse = !!hook?.afterResponse?.length;
|
|
117
|
+
const hasAfterResponse = hasStaticAfterResponse || !!inference.afterResponse;
|
|
117
118
|
const hasBeforeHandle = !!beforeHandlePrefix?.length || !!hook?.beforeHandle?.length;
|
|
118
119
|
const hasAfterHandle = !!hook?.afterHandle?.length;
|
|
119
120
|
const hasMapResponse = !!hook?.mapResponse?.length;
|
|
@@ -137,7 +138,7 @@ function describeRoute(input) {
|
|
|
137
138
|
}
|
|
138
139
|
const handlerIsAsync = isHandleFunction && require_compile_utils.isAsyncFunction(handler);
|
|
139
140
|
const errorHookForcesAsync = hasErrorHook && (hasAfterHandle || hasMapResponse || hasResponseValidator || require_compile_utils.isAsyncLifecycle(hook?.error) || lifecycleMayReturnPromise(hook?.error, false));
|
|
140
|
-
const afterResponseForcesAsync =
|
|
141
|
+
const afterResponseForcesAsync = hasStaticAfterResponse && require_compile_utils.isAsyncLifecycle(hook?.afterResponse) || hasAfterResponse && (hasAfterHandle || hasMapResponse || hasResponseValidator || hasErrorHook);
|
|
141
142
|
const traceForcesAsync = (traceHandleOn || phaseOn("error") || phaseOn("afterResponse")) && isHandleFunction && !handlerIsAsync && (require_compile_utils.mayReturnPromise(handler) || mayReturnIdentifier(handler));
|
|
142
143
|
const handlerResultObserved = isHandleFunction && !handlerIsAsync && (hasResponseValidator || hasAfterHandle || hasMapResponse) && (require_compile_utils.mayReturnPromise(handler) || mayReturnIdentifier(handler));
|
|
143
144
|
const lifecycleForcesAsync = !!hook && ((beforeHandlePrefix ? compactPrefixForcesAsync(beforeHandlePrefix) : false) || lifecycleMayReturnPromise(hook.beforeHandle, true) || lifecycleMayReturnPromise(hook.transform, false) || lifecycleMayReturnPromise(hook.afterHandle, true) || lifecycleMayReturnPromise(hook.mapResponse, true));
|
|
@@ -96,9 +96,9 @@ function describeRoute(input) {
|
|
|
96
96
|
if (hook && typeof hook.parse === "function") hook.parse = [hook.parse];
|
|
97
97
|
const parseLength = Array.isArray(hook?.parse) ? hook.parse.length : 0;
|
|
98
98
|
const parseFirst = Array.isArray(hook?.parse) ? hook.parse[0] : hook?.parse;
|
|
99
|
-
const
|
|
99
|
+
const hasMergeBody = !!hook?.schemas?.some((s) => s?.body);
|
|
100
100
|
const bodylessMethod = method === "GET" || method === "HEAD";
|
|
101
|
-
const hasBody = !!hook?.body ||
|
|
101
|
+
const hasBody = !!hook?.body || hasMergeBody || !bodylessMethod && (parseLength > 0 || inference.body) && parseFirst !== "none";
|
|
102
102
|
const bodyValiIsAsync = hasBody && (isAsyncValidator(vali?.body) || mayReturnPromiseValidator(vali?.body));
|
|
103
103
|
const headersValiIsAsync = vali?.headers && (isAsyncValidator(vali?.headers) || mayReturnPromiseValidator(vali?.headers));
|
|
104
104
|
const paramsValiIsAsync = vali?.params && (isAsyncValidator(vali?.params) || mayReturnPromiseValidator(vali?.params));
|
|
@@ -112,7 +112,8 @@ function describeRoute(input) {
|
|
|
112
112
|
const asyncCookieSign = hasCookieSign && !syncCookieSign;
|
|
113
113
|
const lazyCookieVerify = syncCookieSign && cookieConfig?.verify === "lazy" && !vali?.cookie;
|
|
114
114
|
const hasErrorHook = !!hook?.error?.length;
|
|
115
|
-
const
|
|
115
|
+
const hasStaticAfterResponse = !!hook?.afterResponse?.length;
|
|
116
|
+
const hasAfterResponse = hasStaticAfterResponse || !!inference.afterResponse;
|
|
116
117
|
const hasBeforeHandle = !!beforeHandlePrefix?.length || !!hook?.beforeHandle?.length;
|
|
117
118
|
const hasAfterHandle = !!hook?.afterHandle?.length;
|
|
118
119
|
const hasMapResponse = !!hook?.mapResponse?.length;
|
|
@@ -136,7 +137,7 @@ function describeRoute(input) {
|
|
|
136
137
|
}
|
|
137
138
|
const handlerIsAsync = isHandleFunction && isAsyncFunction(handler);
|
|
138
139
|
const errorHookForcesAsync = hasErrorHook && (hasAfterHandle || hasMapResponse || hasResponseValidator || isAsyncLifecycle(hook?.error) || lifecycleMayReturnPromise(hook?.error, false));
|
|
139
|
-
const afterResponseForcesAsync =
|
|
140
|
+
const afterResponseForcesAsync = hasStaticAfterResponse && isAsyncLifecycle(hook?.afterResponse) || hasAfterResponse && (hasAfterHandle || hasMapResponse || hasResponseValidator || hasErrorHook);
|
|
140
141
|
const traceForcesAsync = (traceHandleOn || phaseOn("error") || phaseOn("afterResponse")) && isHandleFunction && !handlerIsAsync && (mayReturnPromise(handler) || mayReturnIdentifier(handler));
|
|
141
142
|
const handlerResultObserved = isHandleFunction && !handlerIsAsync && (hasResponseValidator || hasAfterHandle || hasMapResponse) && (mayReturnPromise(handler) || mayReturnIdentifier(handler));
|
|
142
143
|
const lifecycleForcesAsync = !!hook && ((beforeHandlePrefix ? compactPrefixForcesAsync(beforeHandlePrefix) : false) || lifecycleMayReturnPromise(hook.beforeHandle, true) || lifecycleMayReturnPromise(hook.transform, false) || lifecycleMayReturnPromise(hook.afterHandle, true) || lifecycleMayReturnPromise(hook.mapResponse, true));
|
|
@@ -32,8 +32,8 @@ interface FrozenRouteValidatorShape {
|
|
|
32
32
|
response?: Record<number, FrozenSlotValidator>;
|
|
33
33
|
}
|
|
34
34
|
declare const isStandardSchema: (schema: unknown) => schema is object & Record<"~standard", unknown>;
|
|
35
|
-
declare function
|
|
35
|
+
declare function mergeSchemasAllStandard(schemas: Array<Record<string, unknown>> | undefined): boolean;
|
|
36
36
|
declare function buildFrozenRouteValidator(hook: AnyLocalHook, root: AnyElysia, method: HTTPMethod, path: string): FrozenRouteValidatorShape | undefined;
|
|
37
37
|
declare function isCapturedBridgeFree(c: CapturedValidator, schema: unknown, coerced?: unknown): boolean;
|
|
38
38
|
//#endregion
|
|
39
|
-
export { buildFrozenRouteValidator, isBridgeNotInitialized, isCapturedBridgeFree, isCompactDiagnosable, isStandardSchema,
|
|
39
|
+
export { buildFrozenRouteValidator, isBridgeNotInitialized, isCapturedBridgeFree, isCompactDiagnosable, isStandardSchema, mergeSchemasAllStandard };
|
|
@@ -224,7 +224,7 @@ const REQUEST_SLOTS = [
|
|
|
224
224
|
"cookie"
|
|
225
225
|
];
|
|
226
226
|
const isStandardSchema = (schema) => schema != null && typeof schema === "object" && "~standard" in schema;
|
|
227
|
-
function
|
|
227
|
+
function mergeSchemasAllStandard(schemas) {
|
|
228
228
|
if (!schemas || schemas.length === 0) return true;
|
|
229
229
|
for (const entry of schemas) for (const key in entry) {
|
|
230
230
|
const value = entry[key];
|
|
@@ -316,4 +316,4 @@ exports.isBridgeNotInitialized = isBridgeNotInitialized;
|
|
|
316
316
|
exports.isCapturedBridgeFree = isCapturedBridgeFree;
|
|
317
317
|
exports.isCompactDiagnosable = isCompactDiagnosable;
|
|
318
318
|
exports.isStandardSchema = isStandardSchema;
|
|
319
|
-
exports.
|
|
319
|
+
exports.mergeSchemasAllStandard = mergeSchemasAllStandard;
|
|
@@ -223,7 +223,7 @@ const REQUEST_SLOTS = [
|
|
|
223
223
|
"cookie"
|
|
224
224
|
];
|
|
225
225
|
const isStandardSchema = (schema) => schema != null && typeof schema === "object" && "~standard" in schema;
|
|
226
|
-
function
|
|
226
|
+
function mergeSchemasAllStandard(schemas) {
|
|
227
227
|
if (!schemas || schemas.length === 0) return true;
|
|
228
228
|
for (const entry of schemas) for (const key in entry) {
|
|
229
229
|
const value = entry[key];
|
|
@@ -310,4 +310,4 @@ function isCapturedBridgeFree(c, schema, coerced = schema) {
|
|
|
310
310
|
}
|
|
311
311
|
|
|
312
312
|
//#endregion
|
|
313
|
-
export { buildFrozenRouteValidator, isBridgeNotInitialized, isCapturedBridgeFree, isCompactDiagnosable, isStandardSchema,
|
|
313
|
+
export { buildFrozenRouteValidator, isBridgeNotInitialized, isCapturedBridgeFree, isCompactDiagnosable, isStandardSchema, mergeSchemasAllStandard };
|
|
@@ -158,6 +158,8 @@ const createInlineHandlerWithDefaultHeaders = (map, h) => ((c) => {
|
|
|
158
158
|
});
|
|
159
159
|
function compileHandlerJit({ method, path, handler, root, errorRoot, hook, adapter, isHandleFunction, isStaticResponse, isPromiseHandler, state }) {
|
|
160
160
|
const { vali, inference, cookieConfig, beforeHandlePrefix, traceHandlers, tracePhases, hasAnyPhase, traceHandleOn, descriptor: { async: isAsync, responseMode, hasBody, bodyValiIsAsync, headersValiIsAsync, paramsValiIsAsync, queryValiIsAsync, cookieValiIsAsync: cookieValidIsAsync, responseValiAsync, hasCookieSign, syncCookieSign, asyncCookieSign, lazyCookieVerify, hasErrorHook, hasAfterResponse, hasBeforeHandle, hasAfterHandle, hasMapResponse, hasResponseValidator, hasTrace, traceCount, hasLifecycleHook, callHandlerSyncOnAsync, syncErrorHook, syncAfterResponse } } = state;
|
|
161
|
+
const hasStaticAfterResponse = !!hook?.afterResponse?.length;
|
|
162
|
+
const hasDynamicAfterResponse = !!inference.afterResponse;
|
|
161
163
|
const seenKeys = new Set(["rt", "fre"]);
|
|
162
164
|
const paramValues = [errorRoot, require_handler_utils.finalizeRouteError];
|
|
163
165
|
const aliasKeys = [];
|
|
@@ -350,7 +352,7 @@ function compileHandlerJit({ method, path, handler, root, errorRoot, hook, adapt
|
|
|
350
352
|
if (isStaticResponse || isPromiseHandler) link(require_compile_handler_utils.cloneResponse, "cr");
|
|
351
353
|
const handleInstruction = isHandleFunction ? "h(c)" : isStaticResponse ? "cr(h)" : isPromiseHandler ? "h.then(cr)" : "h";
|
|
352
354
|
const mapReturn = hasSet ? `rm(${handleInstruction},c.set,c.request,true)\n` : `rc(${handleInstruction},c.request,true)\n`;
|
|
353
|
-
if (
|
|
355
|
+
if (hasStaticAfterResponse) link(hook.afterResponse, "ar");
|
|
354
356
|
const drainTraceStream = traceHandleOn ? `let _ser\nif(_trs){try{for await(const v of _trs){}}catch(_te){_ser=_te}}\n` : "";
|
|
355
357
|
const resolveHandlePostDrain = traceHandleOn ? (() => {
|
|
356
358
|
let s = "";
|
|
@@ -358,7 +360,7 @@ function compileHandlerJit({ method, path, handler, root, errorRoot, hook, adapt
|
|
|
358
360
|
return s;
|
|
359
361
|
})() : "";
|
|
360
362
|
const traceNeedsSchedule = traceHandleOn || phaseOn("afterResponse");
|
|
361
|
-
const scheduleAfterResponse = hasAfterResponse || traceNeedsSchedule ? "c._arf=true\nqueueMicrotask(async()=>{if(_stl){try{for await(const v of _stl){}}catch{}}\n" + drainTraceStream + resolveHandlePostDrain + beginTrace("afterResponse", hook?.afterResponse?.length ?? 0) + (
|
|
363
|
+
const scheduleAfterResponse = hasAfterResponse || traceNeedsSchedule ? "c._arf=true\nqueueMicrotask(async()=>{if(_stl){try{for await(const v of _stl){}}catch{}}\n" + drainTraceStream + resolveHandlePostDrain + beginTrace("afterResponse", hook?.afterResponse?.length ?? 0) + (hasStaticAfterResponse ? require_compile_handler_utils.mapAfterResponse(hook.afterResponse, [buildReport("afterResponse")]) : "") + (hasDynamicAfterResponse ? `if(c['~afterResponse'])for(let i=0;i<c['~afterResponse'].length;i++){try{await c['~afterResponse'][i](c)}catch{}}\n` : "") + endTrace("afterResponse") + `})\n` : "";
|
|
362
364
|
const dedupSchedule = !!scheduleAfterResponse && (hasErrorHook || hasTrace) && !syncAfterResponse && !syncErrorHook;
|
|
363
365
|
const scheduleDecl = dedupSchedule ? `function _sc(){\n${scheduleAfterResponse}}\n` : "";
|
|
364
366
|
const schedule = dedupSchedule ? `_sc()\n` : scheduleAfterResponse;
|
|
@@ -157,6 +157,8 @@ const createInlineHandlerWithDefaultHeaders = (map, h) => ((c) => {
|
|
|
157
157
|
});
|
|
158
158
|
function compileHandlerJit({ method, path, handler, root, errorRoot, hook, adapter, isHandleFunction, isStaticResponse, isPromiseHandler, state }) {
|
|
159
159
|
const { vali, inference, cookieConfig, beforeHandlePrefix, traceHandlers, tracePhases, hasAnyPhase, traceHandleOn, descriptor: { async: isAsync, responseMode, hasBody, bodyValiIsAsync, headersValiIsAsync, paramsValiIsAsync, queryValiIsAsync, cookieValiIsAsync: cookieValidIsAsync, responseValiAsync, hasCookieSign, syncCookieSign, asyncCookieSign, lazyCookieVerify, hasErrorHook, hasAfterResponse, hasBeforeHandle, hasAfterHandle, hasMapResponse, hasResponseValidator, hasTrace, traceCount, hasLifecycleHook, callHandlerSyncOnAsync, syncErrorHook, syncAfterResponse } } = state;
|
|
160
|
+
const hasStaticAfterResponse = !!hook?.afterResponse?.length;
|
|
161
|
+
const hasDynamicAfterResponse = !!inference.afterResponse;
|
|
160
162
|
const seenKeys = new Set(["rt", "fre"]);
|
|
161
163
|
const paramValues = [errorRoot, finalizeRouteError];
|
|
162
164
|
const aliasKeys = [];
|
|
@@ -349,7 +351,7 @@ function compileHandlerJit({ method, path, handler, root, errorRoot, hook, adapt
|
|
|
349
351
|
if (isStaticResponse || isPromiseHandler) link(cloneResponse, "cr");
|
|
350
352
|
const handleInstruction = isHandleFunction ? "h(c)" : isStaticResponse ? "cr(h)" : isPromiseHandler ? "h.then(cr)" : "h";
|
|
351
353
|
const mapReturn = hasSet ? `rm(${handleInstruction},c.set,c.request,true)\n` : `rc(${handleInstruction},c.request,true)\n`;
|
|
352
|
-
if (
|
|
354
|
+
if (hasStaticAfterResponse) link(hook.afterResponse, "ar");
|
|
353
355
|
const drainTraceStream = traceHandleOn ? `let _ser\nif(_trs){try{for await(const v of _trs){}}catch(_te){_ser=_te}}\n` : "";
|
|
354
356
|
const resolveHandlePostDrain = traceHandleOn ? (() => {
|
|
355
357
|
let s = "";
|
|
@@ -357,7 +359,7 @@ function compileHandlerJit({ method, path, handler, root, errorRoot, hook, adapt
|
|
|
357
359
|
return s;
|
|
358
360
|
})() : "";
|
|
359
361
|
const traceNeedsSchedule = traceHandleOn || phaseOn("afterResponse");
|
|
360
|
-
const scheduleAfterResponse = hasAfterResponse || traceNeedsSchedule ? "c._arf=true\nqueueMicrotask(async()=>{if(_stl){try{for await(const v of _stl){}}catch{}}\n" + drainTraceStream + resolveHandlePostDrain + beginTrace("afterResponse", hook?.afterResponse?.length ?? 0) + (
|
|
362
|
+
const scheduleAfterResponse = hasAfterResponse || traceNeedsSchedule ? "c._arf=true\nqueueMicrotask(async()=>{if(_stl){try{for await(const v of _stl){}}catch{}}\n" + drainTraceStream + resolveHandlePostDrain + beginTrace("afterResponse", hook?.afterResponse?.length ?? 0) + (hasStaticAfterResponse ? mapAfterResponse(hook.afterResponse, [buildReport("afterResponse")]) : "") + (hasDynamicAfterResponse ? `if(c['~afterResponse'])for(let i=0;i<c['~afterResponse'].length;i++){try{await c['~afterResponse'][i](c)}catch{}}\n` : "") + endTrace("afterResponse") + `})\n` : "";
|
|
361
363
|
const dedupSchedule = !!scheduleAfterResponse && (hasErrorHook || hasTrace) && !syncAfterResponse && !syncErrorHook;
|
|
362
364
|
const scheduleDecl = dedupSchedule ? `function _sc(){\n${scheduleAfterResponse}}\n` : "";
|
|
363
365
|
const schedule = dedupSchedule ? `_sc()\n` : scheduleAfterResponse;
|
|
@@ -62,6 +62,7 @@ function replaceDeriveContext(context, derivative) {
|
|
|
62
62
|
Object.assign(next, derivative);
|
|
63
63
|
next.request = context.request;
|
|
64
64
|
next["~sig"] = context["~sig"];
|
|
65
|
+
next["~afterResponse"] = context["~afterResponse"];
|
|
65
66
|
next.store = context.store;
|
|
66
67
|
next.set = context.set;
|
|
67
68
|
next.body = context.body;
|
|
@@ -61,6 +61,7 @@ function replaceDeriveContext(context, derivative) {
|
|
|
61
61
|
Object.assign(next, derivative);
|
|
62
62
|
next.request = context.request;
|
|
63
63
|
next["~sig"] = context["~sig"];
|
|
64
|
+
next["~afterResponse"] = context["~afterResponse"];
|
|
64
65
|
next.store = context.store;
|
|
65
66
|
next.set = context.set;
|
|
66
67
|
next.body = context.body;
|
package/dist/context.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Cookie } from "./cookie/cookie.js";
|
|
|
3
3
|
import { StatusMap } from "./constants.js";
|
|
4
4
|
import { SelectiveStatus, status } from "./error.js";
|
|
5
5
|
import { Server } from "./universal/server.js";
|
|
6
|
-
import { DefaultSingleton, HTTPHeaders, InputSchema, Prettify, ResolvePath, RouteSchema, SingletonBase } from "./types.js";
|
|
6
|
+
import { AfterResponseHandler, DefaultSingleton, HTTPHeaders, InputSchema, MaybePromise, Prettify, ResolvePath, RouteSchema, SingletonBase } from "./types.js";
|
|
7
7
|
import { redirect } from "./utils.js";
|
|
8
8
|
import { AnyElysia } from "./base.js";
|
|
9
9
|
|
|
@@ -25,6 +25,10 @@ interface ContextBase<in out Route extends RouteSchema, in out Singleton extends
|
|
|
25
25
|
cookie?: Record<string, BaseCookie>;
|
|
26
26
|
};
|
|
27
27
|
status: {} extends Route['response'] ? typeof status : SelectiveStatus<Route['response']>;
|
|
28
|
+
/**
|
|
29
|
+
* Append a callback to run after the response is sent
|
|
30
|
+
*/
|
|
31
|
+
defer(fn: AfterResponseHandler<Route, Singleton>): MaybePromise<void>;
|
|
28
32
|
/**
|
|
29
33
|
* Path extracted from incoming URL
|
|
30
34
|
*
|
package/dist/context.js
CHANGED
|
@@ -8,12 +8,22 @@ const require_adapter_default_headers = require('./adapter/default-headers.js');
|
|
|
8
8
|
let contextCache = /* @__PURE__ */ new WeakMap();
|
|
9
9
|
let sharedEmptyDecorator = null;
|
|
10
10
|
let sharedEmptyContext = null;
|
|
11
|
+
const defer = {
|
|
12
|
+
configurable: true,
|
|
13
|
+
get() {
|
|
14
|
+
const queue = this["~afterResponse"] ??= [];
|
|
15
|
+
const append = (fn) => queue.push(fn);
|
|
16
|
+
Object.defineProperty(this, "defer", { value: append });
|
|
17
|
+
return append;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
11
20
|
function buildEmptyDecorator() {
|
|
12
21
|
class Decorator {}
|
|
13
22
|
Object.assign(Decorator.prototype, {
|
|
14
23
|
status: require_error.status,
|
|
15
24
|
redirect: require_utils.redirect
|
|
16
25
|
});
|
|
26
|
+
Object.defineProperty(Decorator.prototype, "defer", defer);
|
|
17
27
|
return Decorator;
|
|
18
28
|
}
|
|
19
29
|
function createBaseContext(app) {
|
|
@@ -28,6 +38,7 @@ function createBaseContext(app) {
|
|
|
28
38
|
status: require_error.status,
|
|
29
39
|
redirect: require_utils.redirect
|
|
30
40
|
});
|
|
41
|
+
Object.defineProperty(Decorator.prototype, "defer", defer);
|
|
31
42
|
return Decorator;
|
|
32
43
|
}
|
|
33
44
|
function clearContextCache() {
|
package/dist/context.mjs
CHANGED
|
@@ -7,12 +7,22 @@ import { defaultHeaders } from "./adapter/default-headers.mjs";
|
|
|
7
7
|
let contextCache = /* @__PURE__ */ new WeakMap();
|
|
8
8
|
let sharedEmptyDecorator = null;
|
|
9
9
|
let sharedEmptyContext = null;
|
|
10
|
+
const defer = {
|
|
11
|
+
configurable: true,
|
|
12
|
+
get() {
|
|
13
|
+
const queue = this["~afterResponse"] ??= [];
|
|
14
|
+
const append = (fn) => queue.push(fn);
|
|
15
|
+
Object.defineProperty(this, "defer", { value: append });
|
|
16
|
+
return append;
|
|
17
|
+
}
|
|
18
|
+
};
|
|
10
19
|
function buildEmptyDecorator() {
|
|
11
20
|
class Decorator {}
|
|
12
21
|
Object.assign(Decorator.prototype, {
|
|
13
22
|
status,
|
|
14
23
|
redirect
|
|
15
24
|
});
|
|
25
|
+
Object.defineProperty(Decorator.prototype, "defer", defer);
|
|
16
26
|
return Decorator;
|
|
17
27
|
}
|
|
18
28
|
function createBaseContext(app) {
|
|
@@ -27,6 +37,7 @@ function createBaseContext(app) {
|
|
|
27
37
|
status,
|
|
28
38
|
redirect
|
|
29
39
|
});
|
|
40
|
+
Object.defineProperty(Decorator.prototype, "defer", defer);
|
|
30
41
|
return Decorator;
|
|
31
42
|
}
|
|
32
43
|
function clearContextCache() {
|
package/dist/handler/fetch.js
CHANGED
|
@@ -15,7 +15,8 @@ deuri = require_runtime.__toESM(deuri);
|
|
|
15
15
|
//#region src/handler/fetch.ts
|
|
16
16
|
function extractPath(url, context, pathStart) {
|
|
17
17
|
const s = url.indexOf("/", pathStart);
|
|
18
|
-
|
|
18
|
+
const q = context.qi = url.indexOf("?", s);
|
|
19
|
+
return context.path = q === -1 ? url.slice(s) : url.substring(s, q);
|
|
19
20
|
}
|
|
20
21
|
function notFound(context) {
|
|
21
22
|
const set = context.set;
|
|
@@ -162,18 +163,23 @@ function createFetchHandler(app) {
|
|
|
162
163
|
const traceAfterResponsePhase = hasTrace && (tracePhases === null || tracePhases.has("afterResponse"));
|
|
163
164
|
const tracerFactories = hasTrace ? traceHandlers.map((fn) => traceProvider.createTracer(fn)) : void 0;
|
|
164
165
|
const afterResponses = hook?.afterResponse;
|
|
165
|
-
const afterResponse =
|
|
166
|
+
const afterResponse = (context, status) => {
|
|
166
167
|
if (context._arf) return;
|
|
168
|
+
const queue = context["~afterResponse"];
|
|
169
|
+
if (!afterResponses?.length && !traceAfterResponsePhase && !queue?.length) return;
|
|
167
170
|
context._arf = true;
|
|
168
171
|
if (status !== void 0) context.set.status = status;
|
|
169
172
|
queueMicrotask(async () => {
|
|
170
|
-
if (afterResponses)
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
173
|
+
if (afterResponses?.length || queue?.length) require_adapter_utils.materializeSetHeaders(context.set);
|
|
174
|
+
if (afterResponses) for (let i = 0; i < afterResponses.length; i++) try {
|
|
175
|
+
await afterResponses[i](context);
|
|
176
|
+
} catch (e) {
|
|
177
|
+
console.error(e);
|
|
178
|
+
}
|
|
179
|
+
if (queue) for (let i = 0; i < queue.length; i++) try {
|
|
180
|
+
await queue[i](context);
|
|
181
|
+
} catch (e) {
|
|
182
|
+
console.error(e);
|
|
177
183
|
}
|
|
178
184
|
if (traceAfterResponsePhase) {
|
|
179
185
|
let cache = context.trace;
|
|
@@ -198,7 +204,7 @@ function createFetchHandler(app) {
|
|
|
198
204
|
}
|
|
199
205
|
}
|
|
200
206
|
});
|
|
201
|
-
}
|
|
207
|
+
};
|
|
202
208
|
app["~finalizeError"] = (context, error) => finalizeError(context, handleError, afterResponse, error);
|
|
203
209
|
if (traceRequestPhase) {
|
|
204
210
|
const onRequests = hook?.request ?? [];
|
package/dist/handler/fetch.mjs
CHANGED
|
@@ -12,7 +12,8 @@ import decodeComponent from "deuri";
|
|
|
12
12
|
//#region src/handler/fetch.ts
|
|
13
13
|
function extractPath(url, context, pathStart) {
|
|
14
14
|
const s = url.indexOf("/", pathStart);
|
|
15
|
-
|
|
15
|
+
const q = context.qi = url.indexOf("?", s);
|
|
16
|
+
return context.path = q === -1 ? url.slice(s) : url.substring(s, q);
|
|
16
17
|
}
|
|
17
18
|
function notFound(context) {
|
|
18
19
|
const set = context.set;
|
|
@@ -159,18 +160,23 @@ function createFetchHandler(app) {
|
|
|
159
160
|
const traceAfterResponsePhase = hasTrace && (tracePhases === null || tracePhases.has("afterResponse"));
|
|
160
161
|
const tracerFactories = hasTrace ? traceHandlers.map((fn) => traceProvider.createTracer(fn)) : void 0;
|
|
161
162
|
const afterResponses = hook?.afterResponse;
|
|
162
|
-
const afterResponse =
|
|
163
|
+
const afterResponse = (context, status) => {
|
|
163
164
|
if (context._arf) return;
|
|
165
|
+
const queue = context["~afterResponse"];
|
|
166
|
+
if (!afterResponses?.length && !traceAfterResponsePhase && !queue?.length) return;
|
|
164
167
|
context._arf = true;
|
|
165
168
|
if (status !== void 0) context.set.status = status;
|
|
166
169
|
queueMicrotask(async () => {
|
|
167
|
-
if (afterResponses)
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
170
|
+
if (afterResponses?.length || queue?.length) materializeSetHeaders(context.set);
|
|
171
|
+
if (afterResponses) for (let i = 0; i < afterResponses.length; i++) try {
|
|
172
|
+
await afterResponses[i](context);
|
|
173
|
+
} catch (e) {
|
|
174
|
+
console.error(e);
|
|
175
|
+
}
|
|
176
|
+
if (queue) for (let i = 0; i < queue.length; i++) try {
|
|
177
|
+
await queue[i](context);
|
|
178
|
+
} catch (e) {
|
|
179
|
+
console.error(e);
|
|
174
180
|
}
|
|
175
181
|
if (traceAfterResponsePhase) {
|
|
176
182
|
let cache = context.trace;
|
|
@@ -195,7 +201,7 @@ function createFetchHandler(app) {
|
|
|
195
201
|
}
|
|
196
202
|
}
|
|
197
203
|
});
|
|
198
|
-
}
|
|
204
|
+
};
|
|
199
205
|
app["~finalizeError"] = (context, error) => finalizeError(context, handleError, afterResponse, error);
|
|
200
206
|
if (traceRequestPhase) {
|
|
201
207
|
const onRequests = hook?.request ?? [];
|
package/dist/package.js
CHANGED
package/dist/package.mjs
CHANGED
package/dist/plugin/aot/core.js
CHANGED
|
@@ -444,9 +444,9 @@ async function generateCompiledArtifacts(file, options) {
|
|
|
444
444
|
routeHasTypeBoxDirectSlot = true;
|
|
445
445
|
expectedSlots++;
|
|
446
446
|
}
|
|
447
|
-
const
|
|
448
|
-
if (Array.isArray(
|
|
449
|
-
if (routeHasTypeBoxDirectSlot || !require_compile_handler_frozen_validator.
|
|
447
|
+
const mergeSchemas = hooks.schemas;
|
|
448
|
+
if (Array.isArray(mergeSchemas) && mergeSchemas.length > 0) {
|
|
449
|
+
if (routeHasTypeBoxDirectSlot || !require_compile_handler_frozen_validator.mergeSchemasAllStandard(mergeSchemas)) routesForbidSeal = true;
|
|
450
450
|
}
|
|
451
451
|
}
|
|
452
452
|
if (typedApp["~config"]?.normalize === "typebox") routesForbidSeal = true;
|
package/dist/plugin/aot/core.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isStandardSchema,
|
|
1
|
+
import { isStandardSchema, mergeSchemasAllStandard } from "../../compile/handler/frozen-validator.mjs";
|
|
2
2
|
import { composeRouteHook } from "../../compile/handler/index.mjs";
|
|
3
3
|
import { captureArtifacts, compileToSource, replayStubbability } from "./source.mjs";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
@@ -442,9 +442,9 @@ async function generateCompiledArtifacts(file, options) {
|
|
|
442
442
|
routeHasTypeBoxDirectSlot = true;
|
|
443
443
|
expectedSlots++;
|
|
444
444
|
}
|
|
445
|
-
const
|
|
446
|
-
if (Array.isArray(
|
|
447
|
-
if (routeHasTypeBoxDirectSlot || !
|
|
445
|
+
const mergeSchemas = hooks.schemas;
|
|
446
|
+
if (Array.isArray(mergeSchemas) && mergeSchemas.length > 0) {
|
|
447
|
+
if (routeHasTypeBoxDirectSlot || !mergeSchemasAllStandard(mergeSchemas)) routesForbidSeal = true;
|
|
448
448
|
}
|
|
449
449
|
}
|
|
450
450
|
if (typedApp["~config"]?.normalize === "typebox") routesForbidSeal = true;
|
package/dist/sucrose.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ declare namespace Sucrose {
|
|
|
9
9
|
cookie: boolean;
|
|
10
10
|
set: boolean;
|
|
11
11
|
route: boolean;
|
|
12
|
+
afterResponse?: boolean;
|
|
12
13
|
}
|
|
13
14
|
type LifeCycle = Partial<Partial<AppHook>>;
|
|
14
15
|
}
|
|
@@ -67,14 +68,7 @@ declare function retrieveRootparameters(parameter: string): {
|
|
|
67
68
|
declare function findAlias(type: string, body: string, seen?: Set<string>): string[];
|
|
68
69
|
declare function removeDefaultParameter(parameter: string): string;
|
|
69
70
|
declare function clearSucroseCache(delay?: number | null): void;
|
|
70
|
-
declare const mergeInference: (a: Sucrose.Inference, b: Sucrose.Inference) =>
|
|
71
|
-
body: boolean;
|
|
72
|
-
cookie: boolean;
|
|
73
|
-
headers: boolean;
|
|
74
|
-
query: boolean;
|
|
75
|
-
set: boolean;
|
|
76
|
-
route: boolean;
|
|
77
|
-
};
|
|
71
|
+
declare const mergeInference: (a: Sucrose.Inference, b: Sucrose.Inference) => Sucrose.Inference;
|
|
78
72
|
declare function sucrose(handler: Handler | undefined, lifeCycle: Sucrose.LifeCycle | undefined): Sucrose.Inference;
|
|
79
73
|
//#endregion
|
|
80
74
|
export { Sucrose, bracketPairRange, bracketPairRangeReverse, clearSucroseCache, findAlias, mergeInference, removeColonAlias, removeDefaultParameter, retrieveRootparameters, separateFunction, sucrose };
|
package/dist/sucrose.js
CHANGED
|
@@ -272,6 +272,7 @@ function removeDefaultParameter(parameter) {
|
|
|
272
272
|
}
|
|
273
273
|
function markAllAccessed(i) {
|
|
274
274
|
i.query = i.headers = i.body = i.cookie = i.set = i.route = true;
|
|
275
|
+
i.afterResponse = true;
|
|
275
276
|
}
|
|
276
277
|
const DEFAULT_CACHE_LIMIT = 1024;
|
|
277
278
|
const globalSourceCache = /* @__PURE__ */ new Map();
|
|
@@ -305,7 +306,8 @@ const mergeInference = (a, b) => ({
|
|
|
305
306
|
headers: a.headers || b.headers,
|
|
306
307
|
query: a.query || b.query,
|
|
307
308
|
set: a.set || b.set,
|
|
308
|
-
route: a.route || b.route
|
|
309
|
+
route: a.route || b.route,
|
|
310
|
+
...a.afterResponse || b.afterResponse ? { afterResponse: true } : {}
|
|
309
311
|
});
|
|
310
312
|
const defaultSucrose = () => ({
|
|
311
313
|
query: false,
|
|
@@ -563,6 +565,7 @@ const channel = (value) => {
|
|
|
563
565
|
case "cookie":
|
|
564
566
|
case "set":
|
|
565
567
|
case "route": return value;
|
|
568
|
+
case "defer": return "afterResponse";
|
|
566
569
|
}
|
|
567
570
|
};
|
|
568
571
|
function computedDestructuringChannel(tokens, index) {
|
|
@@ -731,7 +734,7 @@ function inferFunction(source) {
|
|
|
731
734
|
const key = property?.k === "s" && channel(property.value);
|
|
732
735
|
if (key && tokens[next + 2]?.value === "]") inference[key] = true;
|
|
733
736
|
else markAllAccessed(inference);
|
|
734
|
-
if (inference.query && inference.headers && inference.body && inference.cookie && inference.set && inference.route) break;
|
|
737
|
+
if (inference.query && inference.headers && inference.body && inference.cookie && inference.set && inference.route && inference.afterResponse) break;
|
|
735
738
|
continue;
|
|
736
739
|
}
|
|
737
740
|
if (tokens[i - 1]?.value === "=" && (tokens[i - 2]?.k === "i" || tokens[i - 2]?.value === "}")) continue;
|
|
@@ -790,7 +793,7 @@ function sucrose(handler, lifeCycle) {
|
|
|
790
793
|
inference = mergeInference(inference, inferred);
|
|
791
794
|
merged = true;
|
|
792
795
|
} else inference = inferred;
|
|
793
|
-
if (inference.query && inference.headers && inference.body && inference.cookie && inference.set && inference.route) break;
|
|
796
|
+
if (inference.query && inference.headers && inference.body && inference.cookie && inference.set && inference.route && inference.afterResponse) break;
|
|
794
797
|
}
|
|
795
798
|
} finally {
|
|
796
799
|
events.length = 0;
|
package/dist/sucrose.mjs
CHANGED
|
@@ -271,6 +271,7 @@ function removeDefaultParameter(parameter) {
|
|
|
271
271
|
}
|
|
272
272
|
function markAllAccessed(i) {
|
|
273
273
|
i.query = i.headers = i.body = i.cookie = i.set = i.route = true;
|
|
274
|
+
i.afterResponse = true;
|
|
274
275
|
}
|
|
275
276
|
const DEFAULT_CACHE_LIMIT = 1024;
|
|
276
277
|
const globalSourceCache = /* @__PURE__ */ new Map();
|
|
@@ -304,7 +305,8 @@ const mergeInference = (a, b) => ({
|
|
|
304
305
|
headers: a.headers || b.headers,
|
|
305
306
|
query: a.query || b.query,
|
|
306
307
|
set: a.set || b.set,
|
|
307
|
-
route: a.route || b.route
|
|
308
|
+
route: a.route || b.route,
|
|
309
|
+
...a.afterResponse || b.afterResponse ? { afterResponse: true } : {}
|
|
308
310
|
});
|
|
309
311
|
const defaultSucrose = () => ({
|
|
310
312
|
query: false,
|
|
@@ -562,6 +564,7 @@ const channel = (value) => {
|
|
|
562
564
|
case "cookie":
|
|
563
565
|
case "set":
|
|
564
566
|
case "route": return value;
|
|
567
|
+
case "defer": return "afterResponse";
|
|
565
568
|
}
|
|
566
569
|
};
|
|
567
570
|
function computedDestructuringChannel(tokens, index) {
|
|
@@ -730,7 +733,7 @@ function inferFunction(source) {
|
|
|
730
733
|
const key = property?.k === "s" && channel(property.value);
|
|
731
734
|
if (key && tokens[next + 2]?.value === "]") inference[key] = true;
|
|
732
735
|
else markAllAccessed(inference);
|
|
733
|
-
if (inference.query && inference.headers && inference.body && inference.cookie && inference.set && inference.route) break;
|
|
736
|
+
if (inference.query && inference.headers && inference.body && inference.cookie && inference.set && inference.route && inference.afterResponse) break;
|
|
734
737
|
continue;
|
|
735
738
|
}
|
|
736
739
|
if (tokens[i - 1]?.value === "=" && (tokens[i - 2]?.k === "i" || tokens[i - 2]?.value === "}")) continue;
|
|
@@ -789,7 +792,7 @@ function sucrose(handler, lifeCycle) {
|
|
|
789
792
|
inference = mergeInference(inference, inferred);
|
|
790
793
|
merged = true;
|
|
791
794
|
} else inference = inferred;
|
|
792
|
-
if (inference.query && inference.headers && inference.body && inference.cookie && inference.set && inference.route) break;
|
|
795
|
+
if (inference.query && inference.headers && inference.body && inference.cookie && inference.set && inference.route && inference.afterResponse) break;
|
|
793
796
|
}
|
|
794
797
|
} finally {
|
|
795
798
|
events.length = 0;
|
package/dist/type/constants.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ declare const ELYSIA_TYPES: {
|
|
|
17
17
|
readonly NoValidate: 15;
|
|
18
18
|
};
|
|
19
19
|
type ELYSIA_TYPES = typeof ELYSIA_TYPES;
|
|
20
|
-
declare const primitiveElysiaTypes: Set<
|
|
20
|
+
declare const primitiveElysiaTypes: Set<1 | 2 | 6 | 3 | 10 | 11 | 13 | 14>;
|
|
21
21
|
declare const noEnumerable: {
|
|
22
22
|
readonly enumerable: false;
|
|
23
23
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -187,7 +187,7 @@ type IsAny<T> = 0 extends 1 & T ? true : false;
|
|
|
187
187
|
type IsTuple<T> = T extends readonly any[] ? number extends T['length'] ? false : true : false;
|
|
188
188
|
type Replace<Original, Target, With> = IsAny<Target> extends true ? Original : Original extends Record<string, unknown> ? { [K in keyof Original]: Original[K] extends Target ? With : Original[K] } : Original extends Target ? With : Original;
|
|
189
189
|
type EventScope = 'global' | 'local' | 'plugin';
|
|
190
|
-
type GuardSchemaType = 'override' | '
|
|
190
|
+
type GuardSchemaType = 'override' | 'merge';
|
|
191
191
|
type ElysiaFormData<T extends Record<keyof any, unknown>> = FormData & {
|
|
192
192
|
['~ely-form']: Replace<T, Blob | ElysiaFile, File> extends infer A ? { [key in keyof A]: IsTuple<A[key]> extends true ? A[key][number] extends Blob | ElysiaFile ? File[] : A[key] : A[key] } : T;
|
|
193
193
|
};
|
|
@@ -287,7 +287,7 @@ type LocalHook<Input extends BaseMacro, Schema extends RouteSchemaWithResolvedMa
|
|
|
287
287
|
tags?: DocumentDecoration['tags'];
|
|
288
288
|
} & (Input extends any ? Input : Prettify<Input>);
|
|
289
289
|
type AnyLocalHook = LocalHook<any, any, any, any, any>;
|
|
290
|
-
type GuardLocalHook<Input extends BaseMacro | undefined, Schema extends RouteSchema, Singleton extends SingletonBase, Parser extends keyof any, BeforeHandle extends MaybeArray<OptionalHandler<any, any>>, AfterHandle extends MaybeArray<AfterHandler<any, any>>, ErrorHandle extends MaybeArray<ErrorHandler<any, any, any>>, GuardType extends GuardSchemaType = '
|
|
290
|
+
type GuardLocalHook<Input extends BaseMacro | undefined, Schema extends RouteSchema, Singleton extends SingletonBase, Parser extends keyof any, BeforeHandle extends MaybeArray<OptionalHandler<any, any>>, AfterHandle extends MaybeArray<AfterHandler<any, any>>, ErrorHandle extends MaybeArray<ErrorHandler<any, any, any>>, GuardType extends GuardSchemaType = 'merge'> = (Input extends any ? Input : Prettify<Input>) & {
|
|
291
291
|
/**
|
|
292
292
|
* @default 'override'
|
|
293
293
|
* @since 1.3.0
|
package/dist/utils.d.ts
CHANGED
|
@@ -156,7 +156,7 @@ declare const eventProperties: Set<string>;
|
|
|
156
156
|
declare function hookToGuard(a: Partial<AppHook & Macro> & {
|
|
157
157
|
schema?: GuardSchemaType;
|
|
158
158
|
}): Partial<AppHook & Macro>;
|
|
159
|
-
declare function
|
|
159
|
+
declare function coalesceSchemas(existing: any[], incoming: any[]): void;
|
|
160
160
|
declare function mergeHook(a: Partial<AppHook>, b: Partial<AppHook> | undefined, reverse?: boolean, dedup?: boolean): Partial<AppHook>;
|
|
161
161
|
declare const createErrorEventHandler: (fn: EventFn<"error">, error: Error) => (context: Context) => unknown;
|
|
162
162
|
declare function mergeDeep<A extends Record<string, any>, B extends Record<string, any>>(target: A, source: B, skipKeys?: string[], override?: boolean, mergeArray?: boolean, seen?: WeakSet<object>, cloneAdopt?: {
|
|
@@ -177,4 +177,4 @@ declare namespace prefix {
|
|
|
177
177
|
}
|
|
178
178
|
declare function serializeMacroSeed(_key: string, value: unknown): unknown;
|
|
179
179
|
//#endregion
|
|
180
|
-
export { ChainNode, CompactBeforeHandleChunk, CompactBeforeHandlePrefix, DeriveEntry, bytes, clearFlattenChainMemo, cloneHook, clonePlainDecorators, clonePlainDeep,
|
|
180
|
+
export { ChainNode, CompactBeforeHandleChunk, CompactBeforeHandlePrefix, DeriveEntry, bytes, clearFlattenChainMemo, cloneHook, clonePlainDecorators, clonePlainDeep, coalesceSchemas, compactBeforeHandleConflicts, compactBeforeHandlePrefix, constantTimeEqual, createErrorEventHandler, deriveEntryFn, eventProperties, evictOldestHalf, flattenChain, flattenChainMemo, flattenChainMemoReadonly, fnOrigin, fnv1a, form, formToFormData, getLoosePath, guardNonPlainLeaves, hookToGuard, invalidateMacroEpoch, isBlob, isByteStream, isCompactBeforeHandleOnly, isEmpty, isLocalScope, isMapDeriveEntry, isNotEmpty, isRecordNumber, joinPath, macroEpoch, macroOrigin, mapDeriveEntry, mergeArray, mergeDeep, mergeHook, mergeResponse, nullObject, prefix, pushField, redirect, replaceUrlPath, requestId, schemaProperties, serializeMacroSeed, sse };
|
package/dist/utils.js
CHANGED
|
@@ -455,7 +455,7 @@ const eventProperties = new Set([
|
|
|
455
455
|
"error"
|
|
456
456
|
]);
|
|
457
457
|
function hookToGuard(a) {
|
|
458
|
-
if (a.schema !== "
|
|
458
|
+
if (a.schema !== "merge") return a;
|
|
459
459
|
if (a.body || a.headers || a.params || a.query || a.cookie || a.response) {
|
|
460
460
|
a.schemas ??= [];
|
|
461
461
|
const schema = Object.create(null);
|
|
@@ -487,7 +487,7 @@ function hookToGuard(a) {
|
|
|
487
487
|
}
|
|
488
488
|
return a;
|
|
489
489
|
}
|
|
490
|
-
function
|
|
490
|
+
function coalesceSchemas(existing, incoming) {
|
|
491
491
|
for (const entry of incoming) {
|
|
492
492
|
if (!entry || typeof entry !== "object") continue;
|
|
493
493
|
let merged = false;
|
|
@@ -690,7 +690,7 @@ exports.clearFlattenChainMemo = clearFlattenChainMemo;
|
|
|
690
690
|
exports.cloneHook = cloneHook;
|
|
691
691
|
exports.clonePlainDecorators = clonePlainDecorators;
|
|
692
692
|
exports.clonePlainDeep = clonePlainDeep;
|
|
693
|
-
exports.
|
|
693
|
+
exports.coalesceSchemas = coalesceSchemas;
|
|
694
694
|
exports.compactBeforeHandleConflicts = compactBeforeHandleConflicts;
|
|
695
695
|
exports.compactBeforeHandlePrefix = compactBeforeHandlePrefix;
|
|
696
696
|
exports.constantTimeEqual = constantTimeEqual;
|
package/dist/utils.mjs
CHANGED
|
@@ -454,7 +454,7 @@ const eventProperties = new Set([
|
|
|
454
454
|
"error"
|
|
455
455
|
]);
|
|
456
456
|
function hookToGuard(a) {
|
|
457
|
-
if (a.schema !== "
|
|
457
|
+
if (a.schema !== "merge") return a;
|
|
458
458
|
if (a.body || a.headers || a.params || a.query || a.cookie || a.response) {
|
|
459
459
|
a.schemas ??= [];
|
|
460
460
|
const schema = Object.create(null);
|
|
@@ -486,7 +486,7 @@ function hookToGuard(a) {
|
|
|
486
486
|
}
|
|
487
487
|
return a;
|
|
488
488
|
}
|
|
489
|
-
function
|
|
489
|
+
function coalesceSchemas(existing, incoming) {
|
|
490
490
|
for (const entry of incoming) {
|
|
491
491
|
if (!entry || typeof entry !== "object") continue;
|
|
492
492
|
let merged = false;
|
|
@@ -684,4 +684,4 @@ function serializeMacroSeed(_key, value) {
|
|
|
684
684
|
}
|
|
685
685
|
|
|
686
686
|
//#endregion
|
|
687
|
-
export { bytes, clearFlattenChainMemo, cloneHook, clonePlainDecorators, clonePlainDeep,
|
|
687
|
+
export { bytes, clearFlattenChainMemo, cloneHook, clonePlainDecorators, clonePlainDeep, coalesceSchemas, compactBeforeHandleConflicts, compactBeforeHandlePrefix, constantTimeEqual, createErrorEventHandler, deriveEntryFn, eventProperties, evictOldestHalf, flattenChain, flattenChainMemo, flattenChainMemoReadonly, fnOrigin, fnv1a, form, formToFormData, getLoosePath, guardNonPlainLeaves, hookToGuard, invalidateMacroEpoch, isBlob, isByteStream, isCompactBeforeHandleOnly, isEmpty, isLocalScope, isMapDeriveEntry, isNotEmpty, isRecordNumber, joinPath, macroEpoch, macroOrigin, mapDeriveEntry, mergeArray, mergeDeep, mergeHook, mergeResponse, nullObject, prefix, pushField, redirect, replaceUrlPath, requestId, schemaProperties, serializeMacroSeed, sse };
|
package/dist/validator/route.js
CHANGED
|
@@ -5,7 +5,7 @@ const require_validator_index = require('./index.js');
|
|
|
5
5
|
|
|
6
6
|
//#region src/validator/route.ts
|
|
7
7
|
const isTb = (schema) => "~kind" in schema;
|
|
8
|
-
function
|
|
8
|
+
function pickMerge(schemas, key) {
|
|
9
9
|
if (!schemas) return;
|
|
10
10
|
const result = [];
|
|
11
11
|
for (let i = 0; i < schemas.length; i++) {
|
|
@@ -26,23 +26,23 @@ const SLOTS = [
|
|
|
26
26
|
var RouteValidator = class {
|
|
27
27
|
constructor(route, options) {
|
|
28
28
|
if (!route) return;
|
|
29
|
-
const
|
|
29
|
+
const mergeSchemas = options?.schemas;
|
|
30
30
|
for (const [slot, coerce] of SLOTS) {
|
|
31
|
-
const
|
|
32
|
-
if (!route[slot] && !
|
|
33
|
-
const reference = require_validator_index.Validator.reference(route[slot] ??
|
|
34
|
-
const coerces = isTb(reference) ? coerce(reference) :
|
|
31
|
+
const merge = pickMerge(mergeSchemas, slot);
|
|
32
|
+
if (!route[slot] && !merge?.length) continue;
|
|
33
|
+
const reference = require_validator_index.Validator.reference(route[slot] ?? merge[0], options?.models);
|
|
34
|
+
const coerces = isTb(reference) ? coerce(reference) : merge?.find(isTb) ? coerce(merge.find(isTb)) : void 0;
|
|
35
35
|
this[slot] = require_validator_index.Validator.create(route[slot], {
|
|
36
36
|
...options,
|
|
37
37
|
slot,
|
|
38
|
-
schemas:
|
|
38
|
+
schemas: merge,
|
|
39
39
|
coerces
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
|
-
const
|
|
42
|
+
const responseMerge = pickMerge(mergeSchemas, "response");
|
|
43
43
|
this.response = require_validator_index.Validator.response(route.response, {
|
|
44
44
|
...options,
|
|
45
|
-
schemas:
|
|
45
|
+
schemas: responseMerge
|
|
46
46
|
});
|
|
47
47
|
}
|
|
48
48
|
};
|
package/dist/validator/route.mjs
CHANGED
|
@@ -4,7 +4,7 @@ import { Validator } from "./index.mjs";
|
|
|
4
4
|
|
|
5
5
|
//#region src/validator/route.ts
|
|
6
6
|
const isTb = (schema) => "~kind" in schema;
|
|
7
|
-
function
|
|
7
|
+
function pickMerge(schemas, key) {
|
|
8
8
|
if (!schemas) return;
|
|
9
9
|
const result = [];
|
|
10
10
|
for (let i = 0; i < schemas.length; i++) {
|
|
@@ -25,23 +25,23 @@ const SLOTS = [
|
|
|
25
25
|
var RouteValidator = class {
|
|
26
26
|
constructor(route, options) {
|
|
27
27
|
if (!route) return;
|
|
28
|
-
const
|
|
28
|
+
const mergeSchemas = options?.schemas;
|
|
29
29
|
for (const [slot, coerce] of SLOTS) {
|
|
30
|
-
const
|
|
31
|
-
if (!route[slot] && !
|
|
32
|
-
const reference = Validator.reference(route[slot] ??
|
|
33
|
-
const coerces = isTb(reference) ? coerce(reference) :
|
|
30
|
+
const merge = pickMerge(mergeSchemas, slot);
|
|
31
|
+
if (!route[slot] && !merge?.length) continue;
|
|
32
|
+
const reference = Validator.reference(route[slot] ?? merge[0], options?.models);
|
|
33
|
+
const coerces = isTb(reference) ? coerce(reference) : merge?.find(isTb) ? coerce(merge.find(isTb)) : void 0;
|
|
34
34
|
this[slot] = Validator.create(route[slot], {
|
|
35
35
|
...options,
|
|
36
36
|
slot,
|
|
37
|
-
schemas:
|
|
37
|
+
schemas: merge,
|
|
38
38
|
coerces
|
|
39
39
|
});
|
|
40
40
|
}
|
|
41
|
-
const
|
|
41
|
+
const responseMerge = pickMerge(mergeSchemas, "response");
|
|
42
42
|
this.response = Validator.response(route.response, {
|
|
43
43
|
...options,
|
|
44
|
-
schemas:
|
|
44
|
+
schemas: responseMerge
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
47
|
};
|