elysia 2.0.0-exp.27 → 2.0.0-exp.29
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/base.d.ts +1 -1
- package/dist/base.js +82 -19
- package/dist/base.mjs +82 -19
- package/dist/compile/aot.d.ts +17 -3
- package/dist/compile/aot.js +51 -0
- package/dist/compile/aot.mjs +49 -1
- package/dist/compile/handler/frozen-validator.d.ts +3 -13
- package/dist/compile/handler/frozen-validator.js +27 -39
- package/dist/compile/handler/frozen-validator.mjs +28 -40
- package/dist/compile/handler/utils.js +17 -59
- package/dist/compile/handler/utils.mjs +1 -43
- package/dist/compile/lexer.d.ts +7 -0
- package/dist/compile/lexer.js +53 -0
- package/dist/compile/lexer.mjs +48 -0
- package/dist/error.js +2 -2
- package/dist/error.mjs +2 -2
- package/dist/index.d.ts +4 -4
- package/dist/trace.js +3 -3
- package/dist/trace.mjs +1 -1
- package/dist/type/coerce-plan.d.ts +33 -0
- package/dist/type/coerce-plan.js +92 -0
- package/dist/type/coerce-plan.mjs +86 -0
- package/dist/type/coerce.d.ts +4 -18
- package/dist/type/coerce.js +8 -51
- package/dist/type/coerce.mjs +5 -48
- package/dist/type/elysia/array-string.js +1 -1
- package/dist/type/elysia/array-string.mjs +1 -1
- package/dist/type/elysia/file-type.d.ts +1 -1
- package/dist/type/elysia/files.js +1 -1
- package/dist/type/elysia/files.mjs +1 -1
- package/dist/type/elysia/integer-string.js +1 -1
- package/dist/type/elysia/integer-string.mjs +1 -1
- package/dist/type/elysia/numeric-enum.js +1 -1
- package/dist/type/elysia/numeric-enum.mjs +1 -1
- package/dist/type/elysia/numeric.js +1 -1
- package/dist/type/elysia/numeric.mjs +1 -1
- package/dist/type/exports.js +5 -5
- package/dist/type/exports.mjs +5 -5
- package/dist/type/index.js +5 -5
- package/dist/type/index.mjs +5 -5
- package/dist/type/validator/default-precompute.js +3 -3
- package/dist/type/validator/default-precompute.mjs +3 -3
- package/dist/type/validator/index.d.ts +1 -1
- package/dist/type/validator/index.js +1 -1
- package/dist/type/validator/index.mjs +2 -2
- package/dist/type/validator/string-codec-aot.d.ts +1 -2
- package/dist/type/validator/string-codec-aot.js +2 -43
- package/dist/type/validator/string-codec-aot.mjs +1 -42
- package/dist/types.d.ts +2 -2
- package/dist/utils.d.ts +1 -1
- package/dist/validator/index.d.ts +1 -1
- package/dist/ws/route.js +1 -1
- package/dist/ws/route.mjs +1 -1
- package/package.json +1 -1
package/dist/base.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ElysiaStatus } from "./error.js";
|
|
2
2
|
import { TraceHandler } from "./trace.js";
|
|
3
|
+
import { AnySchema } from "./type/types.js";
|
|
3
4
|
import { ListenCallback, Serve, Server } from "./universal/server.js";
|
|
4
5
|
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, 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, SingletonBase, TransformHandler, UnionResponseStatus, UnwrapRoute, WrapFn } from "./types.js";
|
|
5
|
-
import { AnySchema } from "./type/types.js";
|
|
6
6
|
import { ChainNode } from "./utils.js";
|
|
7
7
|
import { Context, ErrorContext, LifecycleContext } from "./context.js";
|
|
8
8
|
import { WSHandlerResponse, WSLocalHook, WSMessageHandler } from "./ws/types.js";
|
package/dist/base.js
CHANGED
|
@@ -766,27 +766,29 @@ var Elysia = class Elysia {
|
|
|
766
766
|
this.#routerBuilt = false;
|
|
767
767
|
this.#buildRouter();
|
|
768
768
|
}
|
|
769
|
-
#add(method, path, fn,
|
|
769
|
+
#add(method, path, hookOrFn, fn, hasHook = fn !== void 0) {
|
|
770
770
|
if (this["~Prefix"]) path = require_utils.joinPath(this["~Prefix"], path);
|
|
771
771
|
else if (path && path.charCodeAt(0) !== 47) path = "/" + path;
|
|
772
|
+
const handler = hasHook ? fn : hookOrFn;
|
|
773
|
+
const hook = hasHook ? hookOrFn : void 0;
|
|
772
774
|
const appHook = this["~hookChain"];
|
|
773
775
|
(this.#history ??= []).push(appHook ? [
|
|
774
776
|
method,
|
|
775
777
|
path,
|
|
776
|
-
|
|
778
|
+
handler,
|
|
777
779
|
this,
|
|
778
780
|
hook,
|
|
779
781
|
appHook
|
|
780
782
|
] : hook ? [
|
|
781
783
|
method,
|
|
782
784
|
path,
|
|
783
|
-
|
|
785
|
+
handler,
|
|
784
786
|
this,
|
|
785
787
|
hook
|
|
786
788
|
] : [
|
|
787
789
|
method,
|
|
788
790
|
path,
|
|
789
|
-
|
|
791
|
+
handler,
|
|
790
792
|
this
|
|
791
793
|
]);
|
|
792
794
|
this.#cachedRoutes = void 0;
|
|
@@ -832,38 +834,37 @@ var Elysia = class Elysia {
|
|
|
832
834
|
* Registered reusable models (via `.model()`), keyed by name.
|
|
833
835
|
*/
|
|
834
836
|
get models() {
|
|
835
|
-
return this["~ext"]?.models ??
|
|
837
|
+
return this["~ext"]?.models ?? require_utils.nullObject();
|
|
836
838
|
}
|
|
837
839
|
Ref(key) {
|
|
838
840
|
return require_type_bridge.Ref(key);
|
|
839
841
|
}
|
|
840
842
|
get(path, hookOrFn, fn) {
|
|
841
|
-
return
|
|
843
|
+
return this.#add(require_constants.MethodMap.GET, path, hookOrFn, fn);
|
|
842
844
|
}
|
|
843
845
|
post(path, hookOrFn, fn) {
|
|
844
|
-
return
|
|
846
|
+
return this.#add(require_constants.MethodMap.POST, path, hookOrFn, fn);
|
|
845
847
|
}
|
|
846
848
|
put(path, hookOrFn, fn) {
|
|
847
|
-
return
|
|
849
|
+
return this.#add(require_constants.MethodMap.PUT, path, hookOrFn, fn);
|
|
848
850
|
}
|
|
849
851
|
patch(path, hookOrFn, fn) {
|
|
850
|
-
return
|
|
852
|
+
return this.#add(require_constants.MethodMap.PATCH, path, hookOrFn, fn);
|
|
851
853
|
}
|
|
852
854
|
delete(path, hookOrFn, fn) {
|
|
853
|
-
return
|
|
855
|
+
return this.#add(require_constants.MethodMap.DELETE, path, hookOrFn, fn);
|
|
854
856
|
}
|
|
855
857
|
options(path, hookOrFn, fn) {
|
|
856
|
-
return
|
|
858
|
+
return this.#add(require_constants.MethodMap.OPTIONS, path, hookOrFn, fn);
|
|
857
859
|
}
|
|
858
860
|
head(path, hookOrFn, fn) {
|
|
859
|
-
return
|
|
861
|
+
return this.#add(require_constants.MethodMap.HEAD, path, hookOrFn, fn);
|
|
860
862
|
}
|
|
861
863
|
method(method, path, hookOrFn, fn) {
|
|
862
|
-
return
|
|
864
|
+
return this.#add(method, path, hookOrFn, fn);
|
|
863
865
|
}
|
|
864
866
|
all(path, hookOrFn, fn) {
|
|
865
|
-
|
|
866
|
-
else this.#add("*", path, fn, hookOrFn);
|
|
867
|
+
this.#add("*", path, hookOrFn, fn);
|
|
867
868
|
return this;
|
|
868
869
|
}
|
|
869
870
|
ws(path, optionsOrHandler, handler) {
|
|
@@ -879,7 +880,7 @@ var Elysia = class Elysia {
|
|
|
879
880
|
opts = require_utils.nullObject();
|
|
880
881
|
opts.message = optionsOrHandler;
|
|
881
882
|
} else opts = optionsOrHandler;
|
|
882
|
-
this.#add("WS", path, void 0,
|
|
883
|
+
this.#add("WS", path, opts, void 0, true);
|
|
883
884
|
return this;
|
|
884
885
|
}
|
|
885
886
|
mount(path, handleOrConfig, config) {
|
|
@@ -943,7 +944,12 @@ var Elysia = class Elysia {
|
|
|
943
944
|
if (this.#compiled?.[index]) return this.#compiled[index];
|
|
944
945
|
const compiled = this.#compiled ??= new Array(this.#history.length);
|
|
945
946
|
if (immediate) {
|
|
946
|
-
|
|
947
|
+
let handler;
|
|
948
|
+
try {
|
|
949
|
+
handler = require_compile_handler_index.compileHandler(this.#history[index], this, precomputedStatic);
|
|
950
|
+
} catch (error) {
|
|
951
|
+
throw new Error(`[Elysia] Failed to compile route ${require_utils.mapMethodBack(route[0])} ${route[1]}: ${error?.message ?? error}`, { cause: error });
|
|
952
|
+
}
|
|
947
953
|
compiled[index] = handler;
|
|
948
954
|
this.#saveHandler(route[0], route[1], handler);
|
|
949
955
|
return handler;
|
|
@@ -953,7 +959,12 @@ var Elysia = class Elysia {
|
|
|
953
959
|
#jitHandler(index, route, precomputedStatic, aliases) {
|
|
954
960
|
return (context) => {
|
|
955
961
|
if (this.#compiled[index]) return this.#compiled[index](context);
|
|
956
|
-
|
|
962
|
+
let handler;
|
|
963
|
+
try {
|
|
964
|
+
handler = require_compile_handler_index.compileHandler(this.#history[index], this, precomputedStatic);
|
|
965
|
+
} catch (error) {
|
|
966
|
+
throw new Error(`[Elysia] Failed to compile route ${require_utils.mapMethodBack(route[0])} ${route[1]}: ${error?.message ?? error}`, { cause: error });
|
|
967
|
+
}
|
|
957
968
|
this.#compiled[index] = handler;
|
|
958
969
|
if (aliases) {
|
|
959
970
|
this.#initMap();
|
|
@@ -999,6 +1010,58 @@ var Elysia = class Elysia {
|
|
|
999
1010
|
return r instanceof Promise ? r.then(Elysia.#toHeadResponse) : Elysia.#toHeadResponse(r);
|
|
1000
1011
|
});
|
|
1001
1012
|
}
|
|
1013
|
+
#chainRefMemo;
|
|
1014
|
+
static #slotHasString(h) {
|
|
1015
|
+
if (!h || typeof h !== "object") return false;
|
|
1016
|
+
for (const key of require_utils.schemaProperties) {
|
|
1017
|
+
const v = h[key];
|
|
1018
|
+
if (typeof v === "string") return true;
|
|
1019
|
+
if (key === "response" && v && typeof v === "object") {
|
|
1020
|
+
const record = v;
|
|
1021
|
+
if ("~kind" in record || "~elyAcl" in record || "~standard" in record) continue;
|
|
1022
|
+
for (const status in record) if (typeof record[status] === "string") return true;
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
return false;
|
|
1026
|
+
}
|
|
1027
|
+
static #hookHasString(h) {
|
|
1028
|
+
if (Elysia.#slotHasString(h)) return true;
|
|
1029
|
+
const schemas = h?.schemas;
|
|
1030
|
+
if (Array.isArray(schemas)) {
|
|
1031
|
+
for (let s = 0; s < schemas.length; s++) if (Elysia.#slotHasString(schemas[s])) return true;
|
|
1032
|
+
}
|
|
1033
|
+
return false;
|
|
1034
|
+
}
|
|
1035
|
+
#chainHasModelRef(start) {
|
|
1036
|
+
if (!start) return false;
|
|
1037
|
+
const memo = this.#chainRefMemo ??= /* @__PURE__ */ new WeakMap();
|
|
1038
|
+
const cached = memo.get(start);
|
|
1039
|
+
if (cached !== void 0) return cached;
|
|
1040
|
+
let found = false;
|
|
1041
|
+
const stack = [start];
|
|
1042
|
+
while (stack.length) {
|
|
1043
|
+
const node = stack.pop();
|
|
1044
|
+
if (!node) continue;
|
|
1045
|
+
if ("combine" in node) {
|
|
1046
|
+
stack.push(node.combine);
|
|
1047
|
+
stack.push(node.over);
|
|
1048
|
+
} else {
|
|
1049
|
+
if (Elysia.#hookHasString(node.added)) {
|
|
1050
|
+
found = true;
|
|
1051
|
+
break;
|
|
1052
|
+
}
|
|
1053
|
+
stack.push(node.parent);
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
memo.set(start, found);
|
|
1057
|
+
return found;
|
|
1058
|
+
}
|
|
1059
|
+
#routeMayHaveModelRef(route) {
|
|
1060
|
+
if (this["~ext"]?.macro || this["~scopeChildren"]) return true;
|
|
1061
|
+
if (require_compile_handler_index.localMacroRoot(route[7] ?? route[3] ?? this, this)["~ext"]?.macro) return true;
|
|
1062
|
+
if (Elysia.#hookHasString(route[4])) return true;
|
|
1063
|
+
return this.#chainHasModelRef(route[5]) || this.#chainHasModelRef(route[6]) || this.#chainHasModelRef(this["~hookChain"]);
|
|
1064
|
+
}
|
|
1002
1065
|
#assertRouteModelRefs(route, method) {
|
|
1003
1066
|
const models = this["~ext"]?.models;
|
|
1004
1067
|
const path = route[1];
|
|
@@ -1039,7 +1102,7 @@ var Elysia = class Elysia {
|
|
|
1039
1102
|
const route = this.#history[i];
|
|
1040
1103
|
const m = route[0] === "WS" ? "WS" : require_utils.mapMethodBack(route[0]);
|
|
1041
1104
|
const key = m + " " + route[1];
|
|
1042
|
-
this.#assertRouteModelRefs(route, m);
|
|
1105
|
+
if (this.#routeMayHaveModelRef(route)) this.#assertRouteModelRefs(route, m);
|
|
1043
1106
|
if (seen.has(key)) {
|
|
1044
1107
|
hasDuplicate = true;
|
|
1045
1108
|
if (!require_error.isProduction()) {
|
package/dist/base.mjs
CHANGED
|
@@ -763,27 +763,29 @@ var Elysia = class Elysia {
|
|
|
763
763
|
this.#routerBuilt = false;
|
|
764
764
|
this.#buildRouter();
|
|
765
765
|
}
|
|
766
|
-
#add(method, path, fn,
|
|
766
|
+
#add(method, path, hookOrFn, fn, hasHook = fn !== void 0) {
|
|
767
767
|
if (this["~Prefix"]) path = joinPath(this["~Prefix"], path);
|
|
768
768
|
else if (path && path.charCodeAt(0) !== 47) path = "/" + path;
|
|
769
|
+
const handler = hasHook ? fn : hookOrFn;
|
|
770
|
+
const hook = hasHook ? hookOrFn : void 0;
|
|
769
771
|
const appHook = this["~hookChain"];
|
|
770
772
|
(this.#history ??= []).push(appHook ? [
|
|
771
773
|
method,
|
|
772
774
|
path,
|
|
773
|
-
|
|
775
|
+
handler,
|
|
774
776
|
this,
|
|
775
777
|
hook,
|
|
776
778
|
appHook
|
|
777
779
|
] : hook ? [
|
|
778
780
|
method,
|
|
779
781
|
path,
|
|
780
|
-
|
|
782
|
+
handler,
|
|
781
783
|
this,
|
|
782
784
|
hook
|
|
783
785
|
] : [
|
|
784
786
|
method,
|
|
785
787
|
path,
|
|
786
|
-
|
|
788
|
+
handler,
|
|
787
789
|
this
|
|
788
790
|
]);
|
|
789
791
|
this.#cachedRoutes = void 0;
|
|
@@ -829,38 +831,37 @@ var Elysia = class Elysia {
|
|
|
829
831
|
* Registered reusable models (via `.model()`), keyed by name.
|
|
830
832
|
*/
|
|
831
833
|
get models() {
|
|
832
|
-
return this["~ext"]?.models ??
|
|
834
|
+
return this["~ext"]?.models ?? nullObject();
|
|
833
835
|
}
|
|
834
836
|
Ref(key) {
|
|
835
837
|
return Ref(key);
|
|
836
838
|
}
|
|
837
839
|
get(path, hookOrFn, fn) {
|
|
838
|
-
return
|
|
840
|
+
return this.#add(MethodMap.GET, path, hookOrFn, fn);
|
|
839
841
|
}
|
|
840
842
|
post(path, hookOrFn, fn) {
|
|
841
|
-
return
|
|
843
|
+
return this.#add(MethodMap.POST, path, hookOrFn, fn);
|
|
842
844
|
}
|
|
843
845
|
put(path, hookOrFn, fn) {
|
|
844
|
-
return
|
|
846
|
+
return this.#add(MethodMap.PUT, path, hookOrFn, fn);
|
|
845
847
|
}
|
|
846
848
|
patch(path, hookOrFn, fn) {
|
|
847
|
-
return
|
|
849
|
+
return this.#add(MethodMap.PATCH, path, hookOrFn, fn);
|
|
848
850
|
}
|
|
849
851
|
delete(path, hookOrFn, fn) {
|
|
850
|
-
return
|
|
852
|
+
return this.#add(MethodMap.DELETE, path, hookOrFn, fn);
|
|
851
853
|
}
|
|
852
854
|
options(path, hookOrFn, fn) {
|
|
853
|
-
return
|
|
855
|
+
return this.#add(MethodMap.OPTIONS, path, hookOrFn, fn);
|
|
854
856
|
}
|
|
855
857
|
head(path, hookOrFn, fn) {
|
|
856
|
-
return
|
|
858
|
+
return this.#add(MethodMap.HEAD, path, hookOrFn, fn);
|
|
857
859
|
}
|
|
858
860
|
method(method, path, hookOrFn, fn) {
|
|
859
|
-
return
|
|
861
|
+
return this.#add(method, path, hookOrFn, fn);
|
|
860
862
|
}
|
|
861
863
|
all(path, hookOrFn, fn) {
|
|
862
|
-
|
|
863
|
-
else this.#add("*", path, fn, hookOrFn);
|
|
864
|
+
this.#add("*", path, hookOrFn, fn);
|
|
864
865
|
return this;
|
|
865
866
|
}
|
|
866
867
|
ws(path, optionsOrHandler, handler) {
|
|
@@ -876,7 +877,7 @@ var Elysia = class Elysia {
|
|
|
876
877
|
opts = nullObject();
|
|
877
878
|
opts.message = optionsOrHandler;
|
|
878
879
|
} else opts = optionsOrHandler;
|
|
879
|
-
this.#add("WS", path, void 0,
|
|
880
|
+
this.#add("WS", path, opts, void 0, true);
|
|
880
881
|
return this;
|
|
881
882
|
}
|
|
882
883
|
mount(path, handleOrConfig, config) {
|
|
@@ -940,7 +941,12 @@ var Elysia = class Elysia {
|
|
|
940
941
|
if (this.#compiled?.[index]) return this.#compiled[index];
|
|
941
942
|
const compiled = this.#compiled ??= new Array(this.#history.length);
|
|
942
943
|
if (immediate) {
|
|
943
|
-
|
|
944
|
+
let handler;
|
|
945
|
+
try {
|
|
946
|
+
handler = compileHandler(this.#history[index], this, precomputedStatic);
|
|
947
|
+
} catch (error) {
|
|
948
|
+
throw new Error(`[Elysia] Failed to compile route ${mapMethodBack(route[0])} ${route[1]}: ${error?.message ?? error}`, { cause: error });
|
|
949
|
+
}
|
|
944
950
|
compiled[index] = handler;
|
|
945
951
|
this.#saveHandler(route[0], route[1], handler);
|
|
946
952
|
return handler;
|
|
@@ -950,7 +956,12 @@ var Elysia = class Elysia {
|
|
|
950
956
|
#jitHandler(index, route, precomputedStatic, aliases) {
|
|
951
957
|
return (context) => {
|
|
952
958
|
if (this.#compiled[index]) return this.#compiled[index](context);
|
|
953
|
-
|
|
959
|
+
let handler;
|
|
960
|
+
try {
|
|
961
|
+
handler = compileHandler(this.#history[index], this, precomputedStatic);
|
|
962
|
+
} catch (error) {
|
|
963
|
+
throw new Error(`[Elysia] Failed to compile route ${mapMethodBack(route[0])} ${route[1]}: ${error?.message ?? error}`, { cause: error });
|
|
964
|
+
}
|
|
954
965
|
this.#compiled[index] = handler;
|
|
955
966
|
if (aliases) {
|
|
956
967
|
this.#initMap();
|
|
@@ -996,6 +1007,58 @@ var Elysia = class Elysia {
|
|
|
996
1007
|
return r instanceof Promise ? r.then(Elysia.#toHeadResponse) : Elysia.#toHeadResponse(r);
|
|
997
1008
|
});
|
|
998
1009
|
}
|
|
1010
|
+
#chainRefMemo;
|
|
1011
|
+
static #slotHasString(h) {
|
|
1012
|
+
if (!h || typeof h !== "object") return false;
|
|
1013
|
+
for (const key of schemaProperties) {
|
|
1014
|
+
const v = h[key];
|
|
1015
|
+
if (typeof v === "string") return true;
|
|
1016
|
+
if (key === "response" && v && typeof v === "object") {
|
|
1017
|
+
const record = v;
|
|
1018
|
+
if ("~kind" in record || "~elyAcl" in record || "~standard" in record) continue;
|
|
1019
|
+
for (const status in record) if (typeof record[status] === "string") return true;
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
return false;
|
|
1023
|
+
}
|
|
1024
|
+
static #hookHasString(h) {
|
|
1025
|
+
if (Elysia.#slotHasString(h)) return true;
|
|
1026
|
+
const schemas = h?.schemas;
|
|
1027
|
+
if (Array.isArray(schemas)) {
|
|
1028
|
+
for (let s = 0; s < schemas.length; s++) if (Elysia.#slotHasString(schemas[s])) return true;
|
|
1029
|
+
}
|
|
1030
|
+
return false;
|
|
1031
|
+
}
|
|
1032
|
+
#chainHasModelRef(start) {
|
|
1033
|
+
if (!start) return false;
|
|
1034
|
+
const memo = this.#chainRefMemo ??= /* @__PURE__ */ new WeakMap();
|
|
1035
|
+
const cached = memo.get(start);
|
|
1036
|
+
if (cached !== void 0) return cached;
|
|
1037
|
+
let found = false;
|
|
1038
|
+
const stack = [start];
|
|
1039
|
+
while (stack.length) {
|
|
1040
|
+
const node = stack.pop();
|
|
1041
|
+
if (!node) continue;
|
|
1042
|
+
if ("combine" in node) {
|
|
1043
|
+
stack.push(node.combine);
|
|
1044
|
+
stack.push(node.over);
|
|
1045
|
+
} else {
|
|
1046
|
+
if (Elysia.#hookHasString(node.added)) {
|
|
1047
|
+
found = true;
|
|
1048
|
+
break;
|
|
1049
|
+
}
|
|
1050
|
+
stack.push(node.parent);
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
memo.set(start, found);
|
|
1054
|
+
return found;
|
|
1055
|
+
}
|
|
1056
|
+
#routeMayHaveModelRef(route) {
|
|
1057
|
+
if (this["~ext"]?.macro || this["~scopeChildren"]) return true;
|
|
1058
|
+
if (localMacroRoot(route[7] ?? route[3] ?? this, this)["~ext"]?.macro) return true;
|
|
1059
|
+
if (Elysia.#hookHasString(route[4])) return true;
|
|
1060
|
+
return this.#chainHasModelRef(route[5]) || this.#chainHasModelRef(route[6]) || this.#chainHasModelRef(this["~hookChain"]);
|
|
1061
|
+
}
|
|
999
1062
|
#assertRouteModelRefs(route, method) {
|
|
1000
1063
|
const models = this["~ext"]?.models;
|
|
1001
1064
|
const path = route[1];
|
|
@@ -1036,7 +1099,7 @@ var Elysia = class Elysia {
|
|
|
1036
1099
|
const route = this.#history[i];
|
|
1037
1100
|
const m = route[0] === "WS" ? "WS" : mapMethodBack(route[0]);
|
|
1038
1101
|
const key = m + " " + route[1];
|
|
1039
|
-
this.#assertRouteModelRefs(route, m);
|
|
1102
|
+
if (this.#routeMayHaveModelRef(route)) this.#assertRouteModelRefs(route, m);
|
|
1040
1103
|
if (seen.has(key)) {
|
|
1041
1104
|
hasDuplicate = true;
|
|
1042
1105
|
if (!isProduction()) {
|
package/dist/compile/aot.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { CoercePlan } from "../type/coerce.js";
|
|
2
|
-
|
|
1
|
+
import { CoercePlan } from "../type/coerce-plan.js";
|
|
3
2
|
//#region src/compile/aot.d.ts
|
|
4
3
|
type ValidatorSlot = 'body' | 'query' | 'params' | 'headers' | 'cookie' | `response:${number}`;
|
|
5
4
|
type FrozenCheckFactory = (External: unknown) => (value: unknown) => boolean;
|
|
@@ -115,6 +114,7 @@ declare const Source: {
|
|
|
115
114
|
readonly mirrorFactory: (source: string, hasExternals: boolean) => string;
|
|
116
115
|
readonly bothFactory: (identifier: string, checkDefs: string, checkValue: string, mirrorSource: string, mirrorHasExternals: boolean) => string;
|
|
117
116
|
};
|
|
117
|
+
declare function collectMirrorUnions(schema: any, out?: unknown[][]): unknown[][];
|
|
118
118
|
declare function instantiateFrozenMirror(frozen: FrozenMirror, schema: unknown): (value: unknown) => unknown;
|
|
119
119
|
declare function instantiateFrozenDecodeMirror(frozen: FrozenMirror, schema: unknown, dir?: 'decode' | 'encode'): (value: unknown) => unknown;
|
|
120
120
|
declare const instantiateFrozenEncodeMirror: (frozen: FrozenMirror, schema: unknown) => ((value: unknown) => unknown);
|
|
@@ -123,6 +123,20 @@ declare function instantiateFrozenBoth(frozen: FrozenValidator, checkSchema: unk
|
|
|
123
123
|
check?: (value: unknown) => boolean;
|
|
124
124
|
clean?: (value: unknown) => unknown;
|
|
125
125
|
};
|
|
126
|
+
interface StringCodecNode {
|
|
127
|
+
inner: any;
|
|
128
|
+
codec: any;
|
|
129
|
+
open: number;
|
|
130
|
+
}
|
|
131
|
+
declare function collectStringCodecNodes(schema: any, out?: StringCodecNode[]): StringCodecNode[];
|
|
132
|
+
/**
|
|
133
|
+
* Overwrite every ObjectString/ArrayString node's `~refine[0].check` and
|
|
134
|
+
* `~codec.decode` with the baked `ic` closures. After this runs, the node no
|
|
135
|
+
* longer calls the constructor's live `typebox/value` Check/Decode
|
|
136
|
+
*
|
|
137
|
+
* Iterate in reverse so nested codecs reconstruct bottom-up.
|
|
138
|
+
*/
|
|
139
|
+
declare function reconstructInnerCodecs(ic: NonNullable<FrozenValidator['ic']>, schema: any): void;
|
|
126
140
|
/**
|
|
127
141
|
* verify that mirror unions can be reconstructed in build time
|
|
128
142
|
*
|
|
@@ -216,4 +230,4 @@ declare const Capture: {
|
|
|
216
230
|
*/
|
|
217
231
|
declare const resetCaptureLifecycleForTests: () => void;
|
|
218
232
|
//#endregion
|
|
219
|
-
export { Capture, CapturedHandler, CapturedMirror, CapturedValidator, CheckBuildResult, Compiled, CompiledSnapshot, EMPTY_EXTERNALS, FrozenBothFactory, FrozenCheckFactory, FrozenHandler, FrozenMirror, FrozenMirrorFactory, FrozenValidator, HandlerManifest, Source, ValidatorManifest, ValidatorSlot, beginValidatorCapture, collectExternals, endHandlerCapture, endValidatorCapture, externalsMatch, instantiateFrozenBoth, instantiateFrozenDecodeMirror, instantiateFrozenEncodeMirror, instantiateFrozenMirror, reconstructCheck, resetCaptureLifecycleForTests };
|
|
233
|
+
export { Capture, CapturedHandler, CapturedMirror, CapturedValidator, CheckBuildResult, Compiled, CompiledSnapshot, EMPTY_EXTERNALS, FrozenBothFactory, FrozenCheckFactory, FrozenHandler, FrozenMirror, FrozenMirrorFactory, FrozenValidator, HandlerManifest, Source, StringCodecNode, ValidatorManifest, ValidatorSlot, beginValidatorCapture, collectExternals, collectMirrorUnions, collectStringCodecNodes, endHandlerCapture, endValidatorCapture, externalsMatch, instantiateFrozenBoth, instantiateFrozenDecodeMirror, instantiateFrozenEncodeMirror, instantiateFrozenMirror, reconstructCheck, reconstructInnerCodecs, resetCaptureLifecycleForTests };
|
package/dist/compile/aot.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
2
|
const require_utils = require('../utils.js');
|
|
3
|
+
const require_type_constants = require('../type/constants.js');
|
|
3
4
|
const require_universal_env = require('../universal/env.js');
|
|
4
5
|
|
|
5
6
|
//#region src/compile/aot.ts
|
|
@@ -201,6 +202,53 @@ const EMPTY_EXTERNALS = Object.freeze([]);
|
|
|
201
202
|
function instantiateFrozenBoth(frozen, checkSchema, mirrorSchema) {
|
|
202
203
|
return frozen.cm(frozen.e ? collectExternals(checkSchema) : EMPTY_EXTERNALS, frozen.u ? { unions: buildUnions(frozen.u, mirrorSchema) } : void 0);
|
|
203
204
|
}
|
|
205
|
+
function collectStringCodecNodes(schema, out = []) {
|
|
206
|
+
if (!schema || typeof schema !== "object") return out;
|
|
207
|
+
const ely = schema["~elyTyp"];
|
|
208
|
+
if (ely === require_type_constants.ELYSIA_TYPES.ObjectString || ely === require_type_constants.ELYSIA_TYPES.ArrayString) {
|
|
209
|
+
const inner = schema.anyOf?.[0];
|
|
210
|
+
const codec = schema.anyOf?.[1];
|
|
211
|
+
if (inner && codec?.["~codec"] && codec["~refine"]) out.push({
|
|
212
|
+
inner,
|
|
213
|
+
codec,
|
|
214
|
+
open: ely === require_type_constants.ELYSIA_TYPES.ObjectString ? 123 : 91
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
if (schema.properties) for (const k in schema.properties) collectStringCodecNodes(schema.properties[k], out);
|
|
218
|
+
const items = schema.items;
|
|
219
|
+
if (Array.isArray(items)) for (const it of items) collectStringCodecNodes(it, out);
|
|
220
|
+
else if (items) collectStringCodecNodes(items, out);
|
|
221
|
+
if (Array.isArray(schema.anyOf)) for (const b of schema.anyOf) collectStringCodecNodes(b, out);
|
|
222
|
+
return out;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Overwrite every ObjectString/ArrayString node's `~refine[0].check` and
|
|
226
|
+
* `~codec.decode` with the baked `ic` closures. After this runs, the node no
|
|
227
|
+
* longer calls the constructor's live `typebox/value` Check/Decode
|
|
228
|
+
*
|
|
229
|
+
* Iterate in reverse so nested codecs reconstruct bottom-up.
|
|
230
|
+
*/
|
|
231
|
+
function reconstructInnerCodecs(ic, schema) {
|
|
232
|
+
const nodes = collectStringCodecNodes(schema);
|
|
233
|
+
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
234
|
+
const entry = ic[i];
|
|
235
|
+
const node = nodes[i];
|
|
236
|
+
if (!entry || !node) continue;
|
|
237
|
+
const innerSchema = node.inner;
|
|
238
|
+
const innerCheck = entry.c(entry.e ? collectExternals(innerSchema) : []);
|
|
239
|
+
const innerMirror = entry.d.x ? instantiateFrozenDecodeMirror(entry.d, innerSchema) : entry.d.s;
|
|
240
|
+
const open = entry.o;
|
|
241
|
+
node.codec["~refine"][0].check = (v) => {
|
|
242
|
+
if (v.charCodeAt(0) !== open) return false;
|
|
243
|
+
try {
|
|
244
|
+
return innerCheck(JSON.parse(v));
|
|
245
|
+
} catch {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
node.codec["~codec"].decode = (v) => innerMirror(JSON.parse(v));
|
|
250
|
+
}
|
|
251
|
+
}
|
|
204
252
|
/**
|
|
205
253
|
* verify that mirror unions can be reconstructed in build time
|
|
206
254
|
*
|
|
@@ -299,6 +347,8 @@ exports.EMPTY_EXTERNALS = EMPTY_EXTERNALS;
|
|
|
299
347
|
exports.Source = Source;
|
|
300
348
|
exports.beginValidatorCapture = beginValidatorCapture;
|
|
301
349
|
exports.collectExternals = collectExternals;
|
|
350
|
+
exports.collectMirrorUnions = collectMirrorUnions;
|
|
351
|
+
exports.collectStringCodecNodes = collectStringCodecNodes;
|
|
302
352
|
exports.endHandlerCapture = endHandlerCapture;
|
|
303
353
|
exports.endValidatorCapture = endValidatorCapture;
|
|
304
354
|
exports.externalsMatch = externalsMatch;
|
|
@@ -307,4 +357,5 @@ exports.instantiateFrozenDecodeMirror = instantiateFrozenDecodeMirror;
|
|
|
307
357
|
exports.instantiateFrozenEncodeMirror = instantiateFrozenEncodeMirror;
|
|
308
358
|
exports.instantiateFrozenMirror = instantiateFrozenMirror;
|
|
309
359
|
exports.reconstructCheck = reconstructCheck;
|
|
360
|
+
exports.reconstructInnerCodecs = reconstructInnerCodecs;
|
|
310
361
|
exports.resetCaptureLifecycleForTests = resetCaptureLifecycleForTests;
|
package/dist/compile/aot.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { nullObject } from "../utils.mjs";
|
|
2
|
+
import { ELYSIA_TYPES } from "../type/constants.mjs";
|
|
2
3
|
import { env } from "../universal/env.mjs";
|
|
3
4
|
|
|
4
5
|
//#region src/compile/aot.ts
|
|
@@ -200,6 +201,53 @@ const EMPTY_EXTERNALS = Object.freeze([]);
|
|
|
200
201
|
function instantiateFrozenBoth(frozen, checkSchema, mirrorSchema) {
|
|
201
202
|
return frozen.cm(frozen.e ? collectExternals(checkSchema) : EMPTY_EXTERNALS, frozen.u ? { unions: buildUnions(frozen.u, mirrorSchema) } : void 0);
|
|
202
203
|
}
|
|
204
|
+
function collectStringCodecNodes(schema, out = []) {
|
|
205
|
+
if (!schema || typeof schema !== "object") return out;
|
|
206
|
+
const ely = schema["~elyTyp"];
|
|
207
|
+
if (ely === ELYSIA_TYPES.ObjectString || ely === ELYSIA_TYPES.ArrayString) {
|
|
208
|
+
const inner = schema.anyOf?.[0];
|
|
209
|
+
const codec = schema.anyOf?.[1];
|
|
210
|
+
if (inner && codec?.["~codec"] && codec["~refine"]) out.push({
|
|
211
|
+
inner,
|
|
212
|
+
codec,
|
|
213
|
+
open: ely === ELYSIA_TYPES.ObjectString ? 123 : 91
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
if (schema.properties) for (const k in schema.properties) collectStringCodecNodes(schema.properties[k], out);
|
|
217
|
+
const items = schema.items;
|
|
218
|
+
if (Array.isArray(items)) for (const it of items) collectStringCodecNodes(it, out);
|
|
219
|
+
else if (items) collectStringCodecNodes(items, out);
|
|
220
|
+
if (Array.isArray(schema.anyOf)) for (const b of schema.anyOf) collectStringCodecNodes(b, out);
|
|
221
|
+
return out;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Overwrite every ObjectString/ArrayString node's `~refine[0].check` and
|
|
225
|
+
* `~codec.decode` with the baked `ic` closures. After this runs, the node no
|
|
226
|
+
* longer calls the constructor's live `typebox/value` Check/Decode
|
|
227
|
+
*
|
|
228
|
+
* Iterate in reverse so nested codecs reconstruct bottom-up.
|
|
229
|
+
*/
|
|
230
|
+
function reconstructInnerCodecs(ic, schema) {
|
|
231
|
+
const nodes = collectStringCodecNodes(schema);
|
|
232
|
+
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
233
|
+
const entry = ic[i];
|
|
234
|
+
const node = nodes[i];
|
|
235
|
+
if (!entry || !node) continue;
|
|
236
|
+
const innerSchema = node.inner;
|
|
237
|
+
const innerCheck = entry.c(entry.e ? collectExternals(innerSchema) : []);
|
|
238
|
+
const innerMirror = entry.d.x ? instantiateFrozenDecodeMirror(entry.d, innerSchema) : entry.d.s;
|
|
239
|
+
const open = entry.o;
|
|
240
|
+
node.codec["~refine"][0].check = (v) => {
|
|
241
|
+
if (v.charCodeAt(0) !== open) return false;
|
|
242
|
+
try {
|
|
243
|
+
return innerCheck(JSON.parse(v));
|
|
244
|
+
} catch {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
node.codec["~codec"].decode = (v) => innerMirror(JSON.parse(v));
|
|
249
|
+
}
|
|
250
|
+
}
|
|
203
251
|
/**
|
|
204
252
|
* verify that mirror unions can be reconstructed in build time
|
|
205
253
|
*
|
|
@@ -292,4 +340,4 @@ const Capture = {
|
|
|
292
340
|
const resetCaptureLifecycleForTests = () => void 0;
|
|
293
341
|
|
|
294
342
|
//#endregion
|
|
295
|
-
export { Capture, Compiled, EMPTY_EXTERNALS, Source, beginValidatorCapture, collectExternals, endHandlerCapture, endValidatorCapture, externalsMatch, instantiateFrozenBoth, instantiateFrozenDecodeMirror, instantiateFrozenEncodeMirror, instantiateFrozenMirror, reconstructCheck, resetCaptureLifecycleForTests };
|
|
343
|
+
export { Capture, Compiled, EMPTY_EXTERNALS, Source, beginValidatorCapture, collectExternals, collectMirrorUnions, collectStringCodecNodes, endHandlerCapture, endValidatorCapture, externalsMatch, instantiateFrozenBoth, instantiateFrozenDecodeMirror, instantiateFrozenEncodeMirror, instantiateFrozenMirror, reconstructCheck, reconstructInnerCodecs, resetCaptureLifecycleForTests };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AnyLocalHook, HTTPMethod } from "../../types.js";
|
|
2
1
|
import { CapturedValidator, FrozenValidator } from "../aot.js";
|
|
2
|
+
import { AnyLocalHook, HTTPMethod } from "../../types.js";
|
|
3
3
|
import { AnyElysia } from "../../base.js";
|
|
4
4
|
|
|
5
5
|
//#region src/compile/handler/frozen-validator.d.ts
|
|
@@ -8,7 +8,7 @@ declare class FrozenSlotValidator {
|
|
|
8
8
|
#private;
|
|
9
9
|
isAsync: boolean;
|
|
10
10
|
schema: unknown;
|
|
11
|
-
constructor(frozen: FrozenValidator, schema: unknown, normalize: boolean | 'exactMirror' | 'typebox' | undefined);
|
|
11
|
+
constructor(frozen: FrozenValidator, schema: unknown, raw: unknown, normalize: boolean | 'exactMirror' | 'typebox' | undefined);
|
|
12
12
|
Check(value: unknown): boolean;
|
|
13
13
|
Errors(): unknown[];
|
|
14
14
|
From(value: unknown, type?: string): unknown;
|
|
@@ -22,19 +22,9 @@ interface FrozenRouteValidatorShape {
|
|
|
22
22
|
cookie?: FrozenSlotValidator;
|
|
23
23
|
response?: Record<number, FrozenSlotValidator>;
|
|
24
24
|
}
|
|
25
|
-
/**
|
|
26
|
-
* Attempt to build an entire route validator bridge-free.
|
|
27
|
-
*
|
|
28
|
-
* Returns `undefined` (caller falls back to the wired `RouteValidator`) unless
|
|
29
|
-
* EVERY declared slot — request and response — is bridge-free-complete. All or
|
|
30
|
-
* nothing per route: a partial mix would still drag the bridge for one slot,
|
|
31
|
-
* defeating the point, and the handler factory expects one uniform validator.
|
|
32
|
-
*/
|
|
33
25
|
declare function buildFrozenRouteValidator(hook: AnyLocalHook, root: AnyElysia, method: HTTPMethod, path: string): FrozenRouteValidatorShape | undefined;
|
|
34
26
|
/**
|
|
35
|
-
* Build-time twin of `isBridgeFreeComplete`, operating on the captured entry
|
|
36
|
-
* its schema. The build plugin can aggregate this across every slot to decide
|
|
37
|
-
* whether a manifest is "fully bridge-free"
|
|
27
|
+
* Build-time twin of `isBridgeFreeComplete`, operating on the captured entry & its schema
|
|
38
28
|
*/
|
|
39
29
|
declare function isCapturedBridgeFree(c: CapturedValidator, schema: unknown): boolean;
|
|
40
30
|
//#endregion
|