elysia 2.0.0-exp.60 → 2.0.0-exp.62
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/utils.d.ts +1 -1
- package/dist/adapter/web-standard/handler.js +13 -9
- package/dist/adapter/web-standard/handler.mjs +14 -10
- package/dist/base.d.ts +24 -9
- package/dist/base.js +33 -17
- package/dist/base.mjs +34 -18
- package/dist/compile/aot-capture.js +1 -1
- package/dist/compile/aot-capture.mjs +2 -2
- package/dist/compile/handler/descriptor.d.ts +1 -1
- package/dist/compile/handler/descriptor.js +5 -4
- package/dist/compile/handler/descriptor.mjs +5 -4
- package/dist/compile/handler/frozen-validator.d.ts +3 -2
- package/dist/compile/handler/frozen-validator.js +35 -5
- package/dist/compile/handler/frozen-validator.mjs +34 -5
- package/dist/compile/handler/index.d.ts +1 -1
- package/dist/compile/handler/jit.js +8 -9
- package/dist/compile/handler/jit.mjs +9 -10
- package/dist/compile/handler/params.js +3 -3
- package/dist/compile/handler/params.mjs +4 -4
- package/dist/compile/handler/utils.d.ts +1 -1
- package/dist/compile/handler/utils.js +6 -2
- package/dist/compile/handler/utils.mjs +6 -2
- package/dist/compile/lexer.d.ts +1 -1
- package/dist/context.d.ts +6 -2
- package/dist/context.js +11 -0
- package/dist/context.mjs +11 -0
- package/dist/cookie/cookie.js +1 -0
- package/dist/cookie/cookie.mjs +1 -0
- package/dist/error.d.ts +138 -5
- package/dist/error.js +73 -0
- package/dist/error.mjs +73 -1
- package/dist/handler/error.d.ts +20 -1
- package/dist/handler/error.js +120 -8
- package/dist/handler/error.mjs +119 -9
- package/dist/handler/fetch.js +18 -8
- package/dist/handler/fetch.mjs +18 -8
- package/dist/handler/utils.js +2 -1
- package/dist/handler/utils.mjs +3 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -0
- package/dist/index.mjs +2 -2
- package/dist/package.js +1 -1
- package/dist/package.mjs +1 -1
- package/dist/plugin/aot/core.d.ts +4 -3
- package/dist/plugin/aot/core.js +4 -4
- package/dist/plugin/aot/core.mjs +5 -5
- package/dist/route-table.d.ts +1 -1
- package/dist/sucrose.d.ts +2 -8
- package/dist/sucrose.js +124 -19
- package/dist/sucrose.mjs +124 -19
- package/dist/type/bridge.d.ts +6 -6
- package/dist/type/coerce.js +9 -4
- package/dist/type/coerce.mjs +9 -4
- package/dist/type/constants.d.ts +1 -1
- package/dist/type/elysia/array-string.js +29 -2
- package/dist/type/elysia/array-string.mjs +30 -3
- package/dist/type/elysia/file-type.js +11 -1
- package/dist/type/elysia/file-type.mjs +11 -1
- package/dist/type/elysia/form.js +2 -1
- package/dist/type/elysia/form.mjs +2 -1
- package/dist/type/elysia/object-string.js +26 -2
- package/dist/type/elysia/object-string.mjs +27 -3
- package/dist/type/validator/index.js +11 -13
- package/dist/type/validator/index.mjs +12 -14
- package/dist/types.d.ts +106 -20
- package/dist/universal/constants.d.ts +2 -1
- package/dist/universal/constants.js +3 -1
- package/dist/universal/constants.mjs +2 -1
- package/dist/universal/file.js +1 -0
- package/dist/universal/file.mjs +1 -0
- package/dist/universal/index.d.ts +1 -1
- package/dist/utils.d.ts +4 -6
- package/dist/utils.js +10 -12
- package/dist/utils.mjs +8 -12
- package/dist/validator/route.js +9 -9
- package/dist/validator/route.mjs +9 -9
- package/dist/ws/route.js +1 -1
- package/dist/ws/route.mjs +1 -1
- package/package.json +2 -8
package/dist/adapter/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseCookie } from "../cookie/types.js";
|
|
2
|
-
import { StatusMap } from "../constants.js";
|
|
3
2
|
import { ElysiaFile } from "../universal/file.js";
|
|
3
|
+
import { StatusMap } from "../constants.js";
|
|
4
4
|
import { HTTPHeaders } from "../types.js";
|
|
5
5
|
import { Context } from "../context.js";
|
|
6
6
|
//#region src/adapter/utils.d.ts
|
|
@@ -21,20 +21,24 @@ function handleElysiaFile(file, set = { headers: require_utils.nullObject() }, r
|
|
|
21
21
|
});
|
|
22
22
|
return require_adapter_utils.handleFile(file.value, set, request);
|
|
23
23
|
}
|
|
24
|
+
function responseTag(response) {
|
|
25
|
+
if (response == null) return;
|
|
26
|
+
return Object.getPrototypeOf(response)?.constructor?.name;
|
|
27
|
+
}
|
|
24
28
|
function mapResponseWithSet(response, set, request, owned) {
|
|
25
29
|
require_adapter_utils.handleSet(set);
|
|
26
30
|
const headers = set.headers;
|
|
27
|
-
switch (response
|
|
31
|
+
switch (responseTag(response)) {
|
|
28
32
|
case "String":
|
|
29
33
|
if (!require_universal_constants.isBun && !headers["content-type"]) require_adapter_utils.materializeSetHeaders(set)["content-type"] = "text/plain";
|
|
30
34
|
return new Response(response, set);
|
|
31
35
|
case "Array": return Response.json(response, set);
|
|
36
|
+
case "ElysiaForm": return new Response(require_utils.formToFormData(response), set);
|
|
32
37
|
case "Object":
|
|
33
|
-
if (response["~ely-form"]) return new Response(require_utils.formToFormData(response), set);
|
|
34
38
|
if (typeof response?.next === "function") return handleStream(response, set, request, void 0, owned);
|
|
35
39
|
return Response.json(response, set);
|
|
36
40
|
case "Number":
|
|
37
|
-
case "Boolean": return new Response(response.toString(), set);
|
|
41
|
+
case "Boolean": return new Response(typeof response === "boolean" ? response ? "true" : "false" : response.toString(), set);
|
|
38
42
|
case "ElysiaFile": return handleElysiaFile(response, set, request);
|
|
39
43
|
case "File":
|
|
40
44
|
case "Blob": return require_adapter_utils.handleFile(response, set, request);
|
|
@@ -66,14 +70,13 @@ function mapResponse(response, set, request, owned) {
|
|
|
66
70
|
}
|
|
67
71
|
const textHeaders = require_universal_constants.isBun ? void 0 : textPlainInit;
|
|
68
72
|
function mapCompactResponse(response, request, owned) {
|
|
69
|
-
switch (response
|
|
73
|
+
switch (responseTag(response)) {
|
|
70
74
|
case "String": return new Response(response, textHeaders);
|
|
71
75
|
case "Array": return Response.json(response);
|
|
72
|
-
case "
|
|
73
|
-
|
|
74
|
-
return Response.json(response);
|
|
76
|
+
case "ElysiaForm": return new Response(require_utils.formToFormData(response));
|
|
77
|
+
case "Object": return Response.json(response);
|
|
75
78
|
case "Number":
|
|
76
|
-
case "Boolean": return new Response(response.toString());
|
|
79
|
+
case "Boolean": return new Response(typeof response === "boolean" ? response ? "true" : "false" : response.toString());
|
|
77
80
|
case "ElysiaFile": return handleElysiaFile(response, void 0, request);
|
|
78
81
|
case "File":
|
|
79
82
|
case "Blob": return require_adapter_utils.handleFile(response, void 0, request);
|
|
@@ -126,11 +129,12 @@ function mapFallback(response, set, request, owned = false) {
|
|
|
126
129
|
headers: response.headers ? { ...response.headers } : {}
|
|
127
130
|
}, request, owned);
|
|
128
131
|
if (response instanceof require_universal_file.ElysiaFile) return handleElysiaFile(response, void 0, request);
|
|
132
|
+
if (require_utils.isElysiaForm(response)) return new Response(require_utils.formToFormData(response), set);
|
|
129
133
|
if (typeof response?.next === "function" || response instanceof ReadableStream) return handleStream(response, set, request, void 0, owned);
|
|
130
134
|
if (typeof response?.then === "function") return response.then((x) => set ? mapResponse(x, set, request, owned) : mapCompactResponse(x, request, owned));
|
|
131
135
|
if (Array.isArray(response)) return Response.json(response);
|
|
132
136
|
if (typeof response?.toResponse === "function") return set ? mapResponse(response.toResponse(), set, request, owned) : mapCompactResponse(response.toResponse(), request, owned);
|
|
133
|
-
if (response
|
|
137
|
+
if (responseTag(response) === "Cookie") return set ? mapResponse(response.value, set, request, owned) : mapCompactResponse(response.value, request, owned);
|
|
134
138
|
return new Response(response, set);
|
|
135
139
|
}
|
|
136
140
|
const handleResponse = require_adapter_utils.createResponseHandler({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isBun } from "../../universal/constants.mjs";
|
|
2
2
|
import { ElysiaFile, mime } from "../../universal/file.mjs";
|
|
3
|
-
import { formToFormData, isNotEmpty, nullObject } from "../../utils.mjs";
|
|
3
|
+
import { formToFormData, isElysiaForm, isNotEmpty, nullObject } from "../../utils.mjs";
|
|
4
4
|
import { ElysiaStatus, PROBLEM_JSON, internalServerErrorBody } from "../../error.mjs";
|
|
5
5
|
import { defaultHeaders } from "../default-headers.mjs";
|
|
6
6
|
import { createResponseHandler, createStreamHandler, handleFile, handleSet, materializeSetHeaders } from "../utils.mjs";
|
|
@@ -20,20 +20,24 @@ function handleElysiaFile(file, set = { headers: nullObject() }, request) {
|
|
|
20
20
|
});
|
|
21
21
|
return handleFile(file.value, set, request);
|
|
22
22
|
}
|
|
23
|
+
function responseTag(response) {
|
|
24
|
+
if (response == null) return;
|
|
25
|
+
return Object.getPrototypeOf(response)?.constructor?.name;
|
|
26
|
+
}
|
|
23
27
|
function mapResponseWithSet(response, set, request, owned) {
|
|
24
28
|
handleSet(set);
|
|
25
29
|
const headers = set.headers;
|
|
26
|
-
switch (response
|
|
30
|
+
switch (responseTag(response)) {
|
|
27
31
|
case "String":
|
|
28
32
|
if (!isBun && !headers["content-type"]) materializeSetHeaders(set)["content-type"] = "text/plain";
|
|
29
33
|
return new Response(response, set);
|
|
30
34
|
case "Array": return Response.json(response, set);
|
|
35
|
+
case "ElysiaForm": return new Response(formToFormData(response), set);
|
|
31
36
|
case "Object":
|
|
32
|
-
if (response["~ely-form"]) return new Response(formToFormData(response), set);
|
|
33
37
|
if (typeof response?.next === "function") return handleStream(response, set, request, void 0, owned);
|
|
34
38
|
return Response.json(response, set);
|
|
35
39
|
case "Number":
|
|
36
|
-
case "Boolean": return new Response(response.toString(), set);
|
|
40
|
+
case "Boolean": return new Response(typeof response === "boolean" ? response ? "true" : "false" : response.toString(), set);
|
|
37
41
|
case "ElysiaFile": return handleElysiaFile(response, set, request);
|
|
38
42
|
case "File":
|
|
39
43
|
case "Blob": return handleFile(response, set, request);
|
|
@@ -65,14 +69,13 @@ function mapResponse(response, set, request, owned) {
|
|
|
65
69
|
}
|
|
66
70
|
const textHeaders = isBun ? void 0 : textPlainInit;
|
|
67
71
|
function mapCompactResponse(response, request, owned) {
|
|
68
|
-
switch (response
|
|
72
|
+
switch (responseTag(response)) {
|
|
69
73
|
case "String": return new Response(response, textHeaders);
|
|
70
74
|
case "Array": return Response.json(response);
|
|
71
|
-
case "
|
|
72
|
-
|
|
73
|
-
return Response.json(response);
|
|
75
|
+
case "ElysiaForm": return new Response(formToFormData(response));
|
|
76
|
+
case "Object": return Response.json(response);
|
|
74
77
|
case "Number":
|
|
75
|
-
case "Boolean": return new Response(response.toString());
|
|
78
|
+
case "Boolean": return new Response(typeof response === "boolean" ? response ? "true" : "false" : response.toString());
|
|
76
79
|
case "ElysiaFile": return handleElysiaFile(response, void 0, request);
|
|
77
80
|
case "File":
|
|
78
81
|
case "Blob": return handleFile(response, void 0, request);
|
|
@@ -125,11 +128,12 @@ function mapFallback(response, set, request, owned = false) {
|
|
|
125
128
|
headers: response.headers ? { ...response.headers } : {}
|
|
126
129
|
}, request, owned);
|
|
127
130
|
if (response instanceof ElysiaFile) return handleElysiaFile(response, void 0, request);
|
|
131
|
+
if (isElysiaForm(response)) return new Response(formToFormData(response), set);
|
|
128
132
|
if (typeof response?.next === "function" || response instanceof ReadableStream) return handleStream(response, set, request, void 0, owned);
|
|
129
133
|
if (typeof response?.then === "function") return response.then((x) => set ? mapResponse(x, set, request, owned) : mapCompactResponse(x, request, owned));
|
|
130
134
|
if (Array.isArray(response)) return Response.json(response);
|
|
131
135
|
if (typeof response?.toResponse === "function") return set ? mapResponse(response.toResponse(), set, request, owned) : mapCompactResponse(response.toResponse(), request, owned);
|
|
132
|
-
if (response
|
|
136
|
+
if (responseTag(response) === "Cookie") return set ? mapResponse(response.value, set, request, owned) : mapCompactResponse(response.value, request, owned);
|
|
133
137
|
return new Response(response, set);
|
|
134
138
|
}
|
|
135
139
|
const handleResponse = createResponseHandler({
|
package/dist/base.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { ElysiaStatus } from "./error.js";
|
|
2
1
|
import { TraceCapability, TraceHandler } from "./trace.js";
|
|
3
2
|
import { ListenCallback, Serve, Server } from "./universal/server.js";
|
|
4
|
-
import { AddRoute, AddWSRoute, AfterHandler, AfterResponseHandler, AnyErrorConstructor, AnyLocalHook, BodyHandler, CompiledHandler, CreateEden, DefaultEphemeral, DefaultMetadata, DefaultSingleton, DefinitionBase, DocumentDecoration, ElysiaConfig, ElysiaHandlerToResponseSchemaAmbiguous, EphemeralType, ErrorDefinitionEntry, ErrorHandler, EventScope, ExcludeElysiaResponse, ExtractErrorFromHandle, GlobalHookReturn, GracefulHandler, GuardHookSingleton, GuardLocalHook, HTTPMethod, HistoryEntry, HookContextSchema, HookContextSingleton, InlineHandler, InlineHandlerNonMacro, InputSchema, InputSchemaKey, InternalRoute, IntersectIfObjectSchema, JoinPath, LocalHook, LocalHookReturn, Macro, MacroSchemaChannel, MacroToContext, MacroToProperty, MapResponse, MaybeArray, MaybePromise, MergeElysiaInstances, MergeSchema, MergeScopedSchemas, MetadataBase, NonResolvableMacroKey, ObjectMacroDefs, OptionalHandler, PluginHookReturn, PreHandler, Prettify, PublicRoute, ResolveRouteErrors, RouteBase, ScopedHookReturn, ScopedMapDeriveReturn, SingletonBase, StaticMapAliases, TransformHandler, UnionResponseStatus, UnwrapRoute, WrapFn } from "./types.js";
|
|
5
3
|
import { ChainNode } from "./utils.js";
|
|
4
|
+
import { AddRoute, AddWSRoute, AfterHandler, AfterResponseHandler, AnyErrorConstructor, AnyLocalHook, BodyHandler, CompiledHandler, CreateEden, DefaultEphemeral, DefaultMetadata, DefaultSingleton, DefinitionBase, DocumentDecoration, ElysiaConfig, ElysiaHandlerToResponseSchemaAmbiguous, EphemeralType, ErrorDefinitionEntry, ErrorHandler, EventScope, ExcludeElysiaResponse, ExtractErrorFromHandle, GlobalHookReturn, GracefulHandler, GuardHookSingleton, GuardLocalHook, HTTPMethod, HistoryEntry, HookContextSchema, HookContextSingleton, InlineHandler, InlineHandlerNonMacro, InputSchema, InputSchemaKey, InternalRoute, IntersectIfObjectSchema, JoinPath, LocalHook, LocalHookReturn, Macro, MacroSchemaChannel, MacroToContext, MacroToProperty, MapResponse, MaybeArray, MaybePromise, MergeElysiaInstances, MergeSchema, MergeScopedSchemas, MetadataBase, NonResolvableMacroKey, ObjectMacroDefs, OptionalHandler, PluginHookReturn, PreHandler, Prettify, PublicRoute, ResolveRouteErrors, RouteBase, ScopedHookReturn, ScopedMapDeriveReturn, SingletonBase, StaticMapAliases, TransformHandler, UnionResponseStatus, UnwrapRoute, WrapFn } from "./types.js";
|
|
5
|
+
import { ElysiaStatus } from "./error.js";
|
|
6
6
|
import { Context, ErrorContext, LifecycleContext } from "./context.js";
|
|
7
7
|
import { AnySchema } from "./type/types.js";
|
|
8
8
|
import { AotFingerprint, CompilerSession, ProgramId } from "./compile/aot.js";
|
|
@@ -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'];
|
|
@@ -559,7 +559,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
|
|
|
559
559
|
parser: Metadata['parser'];
|
|
560
560
|
response: Metadata['response'];
|
|
561
561
|
}, Routes, Ephemeral, Volatile>;
|
|
562
|
-
'~applyMacro'(input: Partial<AnyLocalHook>, toApply?: Partial<AnyLocalHook>, iteration?: number, seen?: Set<string | Partial<any
|
|
562
|
+
'~applyMacro'(input: Partial<AnyLocalHook>, toApply?: Partial<AnyLocalHook>, iteration?: number, seen?: Set<string | Partial<any>>, insertions?: Map<string, number>): Partial<AnyLocalHook>;
|
|
563
563
|
/**
|
|
564
564
|
* Merge a plugin instance
|
|
565
565
|
*/
|
|
@@ -869,6 +869,21 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
|
|
|
869
869
|
get fetch(): (request: Request, ...rest: any[]) => MaybePromise<Response>;
|
|
870
870
|
get handle(): (url: string | Request, options?: RequestInit) => Promise<Response>;
|
|
871
871
|
listen(options: string | number | Partial<Serve>, callback?: ListenCallback): this;
|
|
872
|
+
/**
|
|
873
|
+
* Add a higher order function over Elysia.fetch
|
|
874
|
+
*
|
|
875
|
+
* @example
|
|
876
|
+
* ```ts
|
|
877
|
+
* const ctx = new AsyncLocalStorage<{ counter: number }>()
|
|
878
|
+
*
|
|
879
|
+
* new Elysia()
|
|
880
|
+
* .wrap(
|
|
881
|
+
* (fetch) => (request) =>
|
|
882
|
+
* ctx.run({ counter: 0 }, () => fetch(request))
|
|
883
|
+
* )
|
|
884
|
+
* .get('/', () => ctx.getStore())
|
|
885
|
+
* ```
|
|
886
|
+
*/
|
|
872
887
|
wrap<T extends (...params: any) => MaybePromise<Response> = (request: Request, ...rest: any[]) => MaybePromise<Response>>(callback: WrapFn<T>): this;
|
|
873
888
|
/**
|
|
874
889
|
* ### cleanup | Life cycle event
|
package/dist/base.js
CHANGED
|
@@ -502,7 +502,7 @@ var Elysia = class Elysia {
|
|
|
502
502
|
require_utils.invalidateMacroEpoch();
|
|
503
503
|
return this;
|
|
504
504
|
}
|
|
505
|
-
"~applyMacro"(input, toApply = input, iteration = 0, seen = /* @__PURE__ */ new Set()) {
|
|
505
|
+
"~applyMacro"(input, toApply = input, iteration = 0, seen = /* @__PURE__ */ new Set(), insertions = /* @__PURE__ */ new Map()) {
|
|
506
506
|
if (iteration >= 16) return input;
|
|
507
507
|
const macro = this["~ext"]?.macro;
|
|
508
508
|
if (!macro) return input;
|
|
@@ -547,14 +547,14 @@ var Elysia = class Elysia {
|
|
|
547
547
|
continue;
|
|
548
548
|
}
|
|
549
549
|
if (k in macro) {
|
|
550
|
-
this["~applyMacro"](input, { [k]: v }, iteration + 1, seen);
|
|
550
|
+
this["~applyMacro"](input, { [k]: v }, iteration + 1, seen, insertions);
|
|
551
551
|
delete input[key];
|
|
552
552
|
continue;
|
|
553
553
|
}
|
|
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,23 +564,24 @@ 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
|
}
|
|
571
|
-
if (k
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
571
|
+
if (require_utils.eventProperties.has(k) || k === "derive") {
|
|
572
|
+
const incoming = Array.isArray(v) ? v : [v];
|
|
573
|
+
const existing = k in input ? Array.isArray(input[k]) ? input[k] : [input[k]] : [];
|
|
574
|
+
const added = [];
|
|
575
|
+
for (const fn of incoming) if (!existing.includes(fn) && !added.includes(fn)) added.push(fn);
|
|
576
|
+
const at = insertions.get(k) ?? 0;
|
|
577
|
+
input[k] = [
|
|
578
|
+
...existing.slice(0, at),
|
|
579
|
+
...added,
|
|
580
|
+
...existing.slice(at)
|
|
581
|
+
];
|
|
582
|
+
insertions.set(k, at + added.length);
|
|
583
|
+
} else if (k in input) {
|
|
584
|
+
if (Array.isArray(input[k])) {
|
|
584
585
|
if (Array.isArray(v)) {
|
|
585
586
|
for (const item of v) if (!input[k].some((e) => e === item)) input[k].unshift(item);
|
|
586
587
|
} else if (!input[k].some((item) => item === v)) input[k].unshift(v);
|
|
@@ -1511,6 +1512,21 @@ var Elysia = class Elysia {
|
|
|
1511
1512
|
if (!require_compile_aot.Capture.isAotBuildEnv()) listen(this, options, callback);
|
|
1512
1513
|
return this;
|
|
1513
1514
|
}
|
|
1515
|
+
/**
|
|
1516
|
+
* Add a higher order function over Elysia.fetch
|
|
1517
|
+
*
|
|
1518
|
+
* @example
|
|
1519
|
+
* ```ts
|
|
1520
|
+
* const ctx = new AsyncLocalStorage<{ counter: number }>()
|
|
1521
|
+
*
|
|
1522
|
+
* new Elysia()
|
|
1523
|
+
* .wrap(
|
|
1524
|
+
* (fetch) => (request) =>
|
|
1525
|
+
* ctx.run({ counter: 0 }, () => fetch(request))
|
|
1526
|
+
* )
|
|
1527
|
+
* .get('/', () => ctx.getStore())
|
|
1528
|
+
* ```
|
|
1529
|
+
*/
|
|
1514
1530
|
wrap(callback) {
|
|
1515
1531
|
this.#assertMutable("wrap");
|
|
1516
1532
|
if (this.#fetchFn && !this.#pending) console.warn("[Elysia] .wrap() was called after the fetch handler was built");
|
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";
|
|
@@ -499,7 +499,7 @@ var Elysia = class Elysia {
|
|
|
499
499
|
invalidateMacroEpoch();
|
|
500
500
|
return this;
|
|
501
501
|
}
|
|
502
|
-
"~applyMacro"(input, toApply = input, iteration = 0, seen = /* @__PURE__ */ new Set()) {
|
|
502
|
+
"~applyMacro"(input, toApply = input, iteration = 0, seen = /* @__PURE__ */ new Set(), insertions = /* @__PURE__ */ new Map()) {
|
|
503
503
|
if (iteration >= 16) return input;
|
|
504
504
|
const macro = this["~ext"]?.macro;
|
|
505
505
|
if (!macro) return input;
|
|
@@ -544,14 +544,14 @@ var Elysia = class Elysia {
|
|
|
544
544
|
continue;
|
|
545
545
|
}
|
|
546
546
|
if (k in macro) {
|
|
547
|
-
this["~applyMacro"](input, { [k]: v }, iteration + 1, seen);
|
|
547
|
+
this["~applyMacro"](input, { [k]: v }, iteration + 1, seen, insertions);
|
|
548
548
|
delete input[key];
|
|
549
549
|
continue;
|
|
550
550
|
}
|
|
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,23 +561,24 @@ 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
|
}
|
|
568
|
-
if (k
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
568
|
+
if (eventProperties.has(k) || k === "derive") {
|
|
569
|
+
const incoming = Array.isArray(v) ? v : [v];
|
|
570
|
+
const existing = k in input ? Array.isArray(input[k]) ? input[k] : [input[k]] : [];
|
|
571
|
+
const added = [];
|
|
572
|
+
for (const fn of incoming) if (!existing.includes(fn) && !added.includes(fn)) added.push(fn);
|
|
573
|
+
const at = insertions.get(k) ?? 0;
|
|
574
|
+
input[k] = [
|
|
575
|
+
...existing.slice(0, at),
|
|
576
|
+
...added,
|
|
577
|
+
...existing.slice(at)
|
|
578
|
+
];
|
|
579
|
+
insertions.set(k, at + added.length);
|
|
580
|
+
} else if (k in input) {
|
|
581
|
+
if (Array.isArray(input[k])) {
|
|
581
582
|
if (Array.isArray(v)) {
|
|
582
583
|
for (const item of v) if (!input[k].some((e) => e === item)) input[k].unshift(item);
|
|
583
584
|
} else if (!input[k].some((item) => item === v)) input[k].unshift(v);
|
|
@@ -1508,6 +1509,21 @@ var Elysia = class Elysia {
|
|
|
1508
1509
|
if (!Capture.isAotBuildEnv()) listen(this, options, callback);
|
|
1509
1510
|
return this;
|
|
1510
1511
|
}
|
|
1512
|
+
/**
|
|
1513
|
+
* Add a higher order function over Elysia.fetch
|
|
1514
|
+
*
|
|
1515
|
+
* @example
|
|
1516
|
+
* ```ts
|
|
1517
|
+
* const ctx = new AsyncLocalStorage<{ counter: number }>()
|
|
1518
|
+
*
|
|
1519
|
+
* new Elysia()
|
|
1520
|
+
* .wrap(
|
|
1521
|
+
* (fetch) => (request) =>
|
|
1522
|
+
* ctx.run({ counter: 0 }, () => fetch(request))
|
|
1523
|
+
* )
|
|
1524
|
+
* .get('/', () => ctx.getStore())
|
|
1525
|
+
* ```
|
|
1526
|
+
*/
|
|
1511
1527
|
wrap(callback) {
|
|
1512
1528
|
this.#assertMutable("wrap");
|
|
1513
1529
|
if (this.#fetchFn && !this.#pending) console.warn("[Elysia] .wrap() was called after the fetch handler was built");
|
|
@@ -282,7 +282,7 @@ function captureBridgeFree(aot, slot, rawSchema) {
|
|
|
282
282
|
path: aot.path,
|
|
283
283
|
slot
|
|
284
284
|
}, { bridgeFree });
|
|
285
|
-
if (bridgeFree && !require_compile_handler_frozen_validator.
|
|
285
|
+
if (bridgeFree && !require_compile_handler_frozen_validator.isCompactWalkable(coerced)) warnCompactErrorLoss(aot, slot);
|
|
286
286
|
}
|
|
287
287
|
}
|
|
288
288
|
function beginValidatorCapture() {
|
|
@@ -2,7 +2,7 @@ import { nullObject } from "../utils.mjs";
|
|
|
2
2
|
import { env } from "../universal/env.mjs";
|
|
3
3
|
import { Capture, CompilerState, aotActivationError, captureImpl, setCaptureImpl } from "./aot.mjs";
|
|
4
4
|
import { isAsyncPredicate } from "../type/elysia/file-type.mjs";
|
|
5
|
-
import { isCapturedBridgeFree,
|
|
5
|
+
import { isCapturedBridgeFree, isCompactWalkable } from "./handler/frozen-validator.mjs";
|
|
6
6
|
import { buildCoercedFromPlan, captureCoercePlan } from "../type/coerce.mjs";
|
|
7
7
|
import { applyPrecomputed, buildDefaultClonerSource, buildObjectDefaultMergeSource, canonical, createMergerFromSource, setDefaultProbeImpl, verifyPreallocatableDefault } from "../type/validator/default-precompute.mjs";
|
|
8
8
|
import { collectExternals } from "./aot-reconstruct.mjs";
|
|
@@ -280,7 +280,7 @@ function captureBridgeFree(aot, slot, rawSchema) {
|
|
|
280
280
|
path: aot.path,
|
|
281
281
|
slot
|
|
282
282
|
}, { bridgeFree });
|
|
283
|
-
if (bridgeFree && !
|
|
283
|
+
if (bridgeFree && !isCompactWalkable(coerced)) warnCompactErrorLoss(aot, slot);
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
286
|
function beginValidatorCapture() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TraceEvent } from "../../trace.js";
|
|
2
|
-
import { AnyLocalHook, MaybeArray } from "../../types.js";
|
|
3
2
|
import { CompactBeforeHandlePrefix } from "../../utils.js";
|
|
3
|
+
import { AnyLocalHook, MaybeArray } from "../../types.js";
|
|
4
4
|
import { CompiledCookieConfig } from "../../cookie/config.js";
|
|
5
5
|
import { AnyElysia } from "../../base.js";
|
|
6
6
|
import { ElysiaAdapter } from "../../adapter/index.js";
|
|
@@ -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));
|
|
@@ -11,6 +11,7 @@ interface SlotCheckClean {
|
|
|
11
11
|
decode?: (value: unknown) => unknown;
|
|
12
12
|
}
|
|
13
13
|
declare function isCompactDiagnosable(schema: any): boolean;
|
|
14
|
+
declare function isCompactWalkable(schema: any): boolean;
|
|
14
15
|
declare class FrozenSlotValidator {
|
|
15
16
|
#private;
|
|
16
17
|
isAsync: boolean;
|
|
@@ -32,8 +33,8 @@ interface FrozenRouteValidatorShape {
|
|
|
32
33
|
response?: Record<number, FrozenSlotValidator>;
|
|
33
34
|
}
|
|
34
35
|
declare const isStandardSchema: (schema: unknown) => schema is object & Record<"~standard", unknown>;
|
|
35
|
-
declare function
|
|
36
|
+
declare function mergeSchemasAllStandard(schemas: Array<Record<string, unknown>> | undefined): boolean;
|
|
36
37
|
declare function buildFrozenRouteValidator(hook: AnyLocalHook, root: AnyElysia, method: HTTPMethod, path: string): FrozenRouteValidatorShape | undefined;
|
|
37
38
|
declare function isCapturedBridgeFree(c: CapturedValidator, schema: unknown, coerced?: unknown): boolean;
|
|
38
39
|
//#endregion
|
|
39
|
-
export { buildFrozenRouteValidator, isBridgeNotInitialized, isCapturedBridgeFree, isCompactDiagnosable, isStandardSchema,
|
|
40
|
+
export { buildFrozenRouteValidator, isBridgeNotInitialized, isCapturedBridgeFree, isCompactDiagnosable, isCompactWalkable, isStandardSchema, mergeSchemasAllStandard };
|
|
@@ -55,17 +55,30 @@ const typeError = (schema, instancePath, schemaPath) => ({
|
|
|
55
55
|
**/
|
|
56
56
|
function walkCompactError(schema, value, instancePath, schemaPath) {
|
|
57
57
|
if (!schema || typeof schema !== "object") return;
|
|
58
|
+
const elyTyp = schema["~elyTyp"];
|
|
59
|
+
if (schema.anyOf && (elyTyp === require_type_constants.ELYSIA_TYPES.ObjectString || elyTyp === require_type_constants.ELYSIA_TYPES.ArrayString)) {
|
|
60
|
+
let decoded = value;
|
|
61
|
+
if (typeof value === "string") try {
|
|
62
|
+
decoded = JSON.parse(value);
|
|
63
|
+
} catch {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
else if (value === void 0) return;
|
|
67
|
+
return walkCompactError(schema.anyOf[0], decoded, instancePath, `${schemaPath}/anyOf/0`);
|
|
68
|
+
}
|
|
58
69
|
const type = schema.type;
|
|
59
70
|
if (type === "object") {
|
|
60
71
|
if (typeof value !== "object" || value === null || Array.isArray(value)) return typeError(schema, instancePath, schemaPath);
|
|
61
72
|
const required = schema.required;
|
|
62
73
|
if (Array.isArray(required)) {
|
|
63
|
-
|
|
74
|
+
let missing;
|
|
75
|
+
for (const key of required) if (!(key in value)) (missing ??= []).push(key);
|
|
76
|
+
if (missing) return {
|
|
64
77
|
keyword: "required",
|
|
65
78
|
schemaPath,
|
|
66
79
|
instancePath,
|
|
67
|
-
params: { requiredProperties:
|
|
68
|
-
message: `must have required properties ${
|
|
80
|
+
params: { requiredProperties: missing },
|
|
81
|
+
message: `must have required properties ${missing.join(", ")}`
|
|
69
82
|
};
|
|
70
83
|
}
|
|
71
84
|
const properties = schema.properties;
|
|
@@ -121,6 +134,22 @@ function isCompactDiagnosable(schema) {
|
|
|
121
134
|
if (type === "array") return isCompactDiagnosable(schema.items);
|
|
122
135
|
return type === "string" || type === "number" || type === "integer" || type === "boolean" || type === "null";
|
|
123
136
|
}
|
|
137
|
+
function isCompactWalkable(schema) {
|
|
138
|
+
if (!schema || typeof schema !== "object") return false;
|
|
139
|
+
const elyTyp = schema["~elyTyp"];
|
|
140
|
+
if (schema.anyOf && (elyTyp === require_type_constants.ELYSIA_TYPES.ObjectString || elyTyp === require_type_constants.ELYSIA_TYPES.ArrayString)) return isCompactWalkable(schema.anyOf[0]);
|
|
141
|
+
if (schema.anyOf || schema.oneOf || schema.allOf) return false;
|
|
142
|
+
const type = schema.type;
|
|
143
|
+
if (type === "object") {
|
|
144
|
+
const properties = schema.properties;
|
|
145
|
+
if (properties) {
|
|
146
|
+
for (const key in properties) if (!isCompactWalkable(properties[key])) return false;
|
|
147
|
+
}
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
if (type === "array") return isCompactWalkable(schema.items);
|
|
151
|
+
return type === "string" || type === "number" || type === "integer" || type === "boolean" || type === "null";
|
|
152
|
+
}
|
|
124
153
|
var FrozenSlotValidator = class {
|
|
125
154
|
#check;
|
|
126
155
|
#clean;
|
|
@@ -224,7 +253,7 @@ const REQUEST_SLOTS = [
|
|
|
224
253
|
"cookie"
|
|
225
254
|
];
|
|
226
255
|
const isStandardSchema = (schema) => schema != null && typeof schema === "object" && "~standard" in schema;
|
|
227
|
-
function
|
|
256
|
+
function mergeSchemasAllStandard(schemas) {
|
|
228
257
|
if (!schemas || schemas.length === 0) return true;
|
|
229
258
|
for (const entry of schemas) for (const key in entry) {
|
|
230
259
|
const value = entry[key];
|
|
@@ -315,5 +344,6 @@ exports.buildFrozenRouteValidator = buildFrozenRouteValidator;
|
|
|
315
344
|
exports.isBridgeNotInitialized = isBridgeNotInitialized;
|
|
316
345
|
exports.isCapturedBridgeFree = isCapturedBridgeFree;
|
|
317
346
|
exports.isCompactDiagnosable = isCompactDiagnosable;
|
|
347
|
+
exports.isCompactWalkable = isCompactWalkable;
|
|
318
348
|
exports.isStandardSchema = isStandardSchema;
|
|
319
|
-
exports.
|
|
349
|
+
exports.mergeSchemasAllStandard = mergeSchemasAllStandard;
|