elysia 2.0.0-exp.35 → 2.0.0-exp.36
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 +34 -6
- package/dist/base.js +16 -3
- package/dist/base.mjs +17 -4
- package/dist/compile/aot-capture.js +12 -5
- package/dist/compile/aot-capture.mjs +11 -4
- package/dist/compile/aot-reconstruct.d.ts +54 -0
- package/dist/compile/aot-reconstruct.js +249 -0
- package/dist/compile/aot-reconstruct.mjs +234 -0
- package/dist/compile/aot.d.ts +25 -49
- package/dist/compile/aot.js +13 -217
- package/dist/compile/aot.mjs +13 -207
- package/dist/compile/handler/frozen-validator.js +5 -5
- package/dist/compile/handler/frozen-validator.mjs +6 -6
- package/dist/compile/handler/jit.js +1 -1
- package/dist/compile/handler/jit.mjs +1 -1
- package/dist/compile/handler/utils.d.ts +5 -2
- package/dist/compile/handler/utils.js +63 -5
- package/dist/compile/handler/utils.mjs +61 -5
- package/dist/plugin/core.d.ts +35 -5
- package/dist/plugin/core.js +6 -3
- package/dist/plugin/core.mjs +6 -4
- package/dist/plugin/source.d.ts +9 -0
- package/dist/plugin/source.js +14 -11
- package/dist/plugin/source.mjs +4 -1
- package/dist/type/bridge.d.ts +6 -6
- package/dist/type/constants.d.ts +1 -1
- package/dist/type/types.d.ts +1 -1
- package/dist/type/validator/custom-error.js +1 -1
- package/dist/type/validator/custom-error.mjs +2 -2
- package/dist/type/validator/frozen-check.js +3 -3
- package/dist/type/validator/frozen-check.mjs +1 -1
- package/dist/type/validator/index.d.ts +2 -3
- package/dist/type/validator/index.js +5 -11
- package/dist/type/validator/index.mjs +7 -12
- package/dist/type/validator/string-codec-aot.d.ts +2 -2
- package/dist/type/validator/string-codec-aot.js +5 -6
- package/dist/type/validator/string-codec-aot.mjs +4 -4
- package/dist/types.d.ts +1 -1
- package/dist/utils.d.ts +5 -1
- package/dist/utils.js +6 -0
- package/dist/utils.mjs +4 -1
- package/dist/ws/route.js +6 -3
- package/dist/ws/route.mjs +8 -5
- package/package.json +6 -1
package/dist/base.d.ts
CHANGED
|
@@ -53,6 +53,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
|
|
|
53
53
|
};
|
|
54
54
|
'~hasWS'?: boolean;
|
|
55
55
|
'~hasDynamicWS'?: boolean;
|
|
56
|
+
'~hasTrace'?: boolean;
|
|
56
57
|
'~scopeChild'?: boolean;
|
|
57
58
|
'~scopeChildren'?: AnyElysia[];
|
|
58
59
|
constructor(config?: ElysiaConfig<BasePath, Scope>);
|
|
@@ -203,12 +204,39 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
|
|
|
203
204
|
derive<const Derivative extends Record<string, unknown> | ElysiaStatus<any, any, any> | void>(scope: 'local', transform: (context: Context<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>>) => MaybePromise<Derivative>): LocalHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ExtractErrorFromHandle<Derivative>, ExcludeElysiaResponse<Derivative>>;
|
|
204
205
|
derive<const Derivative extends Record<string, unknown> | ElysiaStatus<any, any, any> | void>(scope: 'plugin', transform: (context: LifecycleContext<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>, undefined, 'plugin'>) => MaybePromise<Derivative>): PluginHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ExtractErrorFromHandle<Derivative>, ExcludeElysiaResponse<Derivative>>;
|
|
205
206
|
derive<const Derivative extends Record<string, unknown> | ElysiaStatus<any, any, any> | void>(scope: 'global', transform: (context: LifecycleContext<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>, undefined, 'global'>) => MaybePromise<Derivative>): GlobalHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ExtractErrorFromHandle<Derivative>, ExcludeElysiaResponse<Derivative>>;
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
207
|
+
mapDerive<const Derivative extends Record<string, unknown> | ElysiaStatus<any, any, any> | void>(transform: (context: Context<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>>) => MaybePromise<Derivative>): Elysia<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, {
|
|
208
|
+
derive: ExcludeElysiaResponse<Derivative>;
|
|
209
|
+
schema: Volatile['schema'];
|
|
210
|
+
schemas: Volatile['schemas'];
|
|
211
|
+
response: UnionResponseStatus<Volatile['response'], ExtractErrorFromHandle<Derivative>>;
|
|
212
|
+
error: Volatile['error'];
|
|
213
|
+
}>;
|
|
214
|
+
mapDerive<const Derivative extends Record<string, unknown> | ElysiaStatus<any, any, any> | void>(scope: 'local', transform: (context: Context<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>>) => MaybePromise<Derivative>): Elysia<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, {
|
|
215
|
+
derive: ExcludeElysiaResponse<Derivative>;
|
|
216
|
+
schema: Volatile['schema'];
|
|
217
|
+
schemas: Volatile['schemas'];
|
|
218
|
+
response: UnionResponseStatus<Volatile['response'], ExtractErrorFromHandle<Derivative>>;
|
|
219
|
+
error: Volatile['error'];
|
|
220
|
+
}>;
|
|
221
|
+
mapDerive<const Derivative extends Record<string, unknown> | ElysiaStatus<any, any, any> | void>(scope: 'plugin', transform: (context: LifecycleContext<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>, undefined, 'plugin'>) => MaybePromise<Derivative>): Elysia<BasePath, Scope, Singleton, Definitions, Metadata, Routes, {
|
|
222
|
+
derive: ExcludeElysiaResponse<Derivative>;
|
|
223
|
+
schema: Ephemeral['schema'];
|
|
224
|
+
schemas: Ephemeral['schemas'];
|
|
225
|
+
response: UnionResponseStatus<Ephemeral['response'], ExtractErrorFromHandle<Derivative>>;
|
|
226
|
+
error: Ephemeral['error'];
|
|
227
|
+
}, Volatile>;
|
|
228
|
+
mapDerive<const Derivative extends Record<string, unknown> | ElysiaStatus<any, any, any> | void>(scope: 'global', transform: (context: LifecycleContext<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>, undefined, 'global'>) => MaybePromise<Derivative>): Elysia<BasePath, Scope, {
|
|
229
|
+
decorator: Singleton['decorator'];
|
|
230
|
+
store: Singleton['store'];
|
|
231
|
+
derive: ExcludeElysiaResponse<Derivative>;
|
|
232
|
+
}, Definitions, {
|
|
233
|
+
schema: Metadata['schema'];
|
|
234
|
+
schemas: Metadata['schemas'];
|
|
235
|
+
macro: Metadata['macro'];
|
|
236
|
+
macroFn: Metadata['macroFn'];
|
|
237
|
+
parser: Metadata['parser'];
|
|
238
|
+
response: UnionResponseStatus<Metadata['response'], ExtractErrorFromHandle<Derivative>>;
|
|
239
|
+
}, Routes, Ephemeral, Volatile>;
|
|
212
240
|
afterHandle<const Handler extends MaybeArray<AfterHandler<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>>>>(fn: Handler): LocalHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ElysiaHandlerToResponseSchemaAmbiguous<Handler>>;
|
|
213
241
|
afterHandle<const Handler extends MaybeArray<AfterHandler<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>>>>(scope: 'local', fn: Handler): LocalHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ElysiaHandlerToResponseSchemaAmbiguous<Handler>>;
|
|
214
242
|
afterHandle<const Handler extends MaybeArray<AfterHandler<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>, undefined, 'plugin'>>>(scope: 'plugin', fn: Handler): PluginHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ElysiaHandlerToResponseSchemaAmbiguous<Handler>>;
|
package/dist/base.js
CHANGED
|
@@ -143,6 +143,7 @@ var Elysia = class Elysia {
|
|
|
143
143
|
#on(type, fn, scope = this["~config"]?.as) {
|
|
144
144
|
const added = require_utils.nullObject();
|
|
145
145
|
added[type] = fn;
|
|
146
|
+
if (type === "trace") this["~hasTrace"] = true;
|
|
146
147
|
this["~hookChain"] = {
|
|
147
148
|
added,
|
|
148
149
|
parent: this["~hookChain"],
|
|
@@ -217,6 +218,17 @@ var Elysia = class Elysia {
|
|
|
217
218
|
}
|
|
218
219
|
return result;
|
|
219
220
|
}
|
|
221
|
+
mapDerive(scopeOrFn, fn) {
|
|
222
|
+
const result = this.#onBranch("beforeHandle", scopeOrFn, fn);
|
|
223
|
+
const node = this["~hookChain"];
|
|
224
|
+
if (node?.added) {
|
|
225
|
+
const d = fn ?? scopeOrFn;
|
|
226
|
+
const entries = node.added["~deriveEntries"] ??= [];
|
|
227
|
+
if (Array.isArray(d)) for (const f of d) entries.push(require_utils.mapDeriveEntry(f));
|
|
228
|
+
else entries.push(require_utils.mapDeriveEntry(d));
|
|
229
|
+
}
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
220
232
|
afterHandle(scopeOrFn, fn) {
|
|
221
233
|
return this.#onBranch("afterHandle", scopeOrFn, fn);
|
|
222
234
|
}
|
|
@@ -368,6 +380,7 @@ var Elysia = class Elysia {
|
|
|
368
380
|
}
|
|
369
381
|
hook = promoted;
|
|
370
382
|
}
|
|
383
|
+
if (hook.trace) this["~hasTrace"] = true;
|
|
371
384
|
this["~hookChain"] = {
|
|
372
385
|
added: hook,
|
|
373
386
|
parent: this["~hookChain"],
|
|
@@ -548,6 +561,7 @@ var Elysia = class Elysia {
|
|
|
548
561
|
if (addedByThisCall) for (const h of addedByThisCall) this.#childrenHash.delete(h);
|
|
549
562
|
throw new Error(`[Elysia] Macro "${macroName}" can be only define once`);
|
|
550
563
|
}
|
|
564
|
+
if (app["~hasTrace"]) this["~hasTrace"] = true;
|
|
551
565
|
if (app.#history) {
|
|
552
566
|
if (app["~hasWS"]) this["~hasWS"] = true;
|
|
553
567
|
const history = this.#history ??= [];
|
|
@@ -682,10 +696,10 @@ var Elysia = class Elysia {
|
|
|
682
696
|
continue;
|
|
683
697
|
}
|
|
684
698
|
if (key === "~deriveEntries") {
|
|
685
|
-
const entries = added[
|
|
699
|
+
const entries = added[key];
|
|
686
700
|
if (!entries) continue;
|
|
687
701
|
const target = isGlobal ? globalEvents ??= require_utils.nullObject() : pluginEvents ??= require_utils.nullObject();
|
|
688
|
-
const list = target[
|
|
702
|
+
const list = target[key] ??= [];
|
|
689
703
|
for (let j = 0; j < entries.length; j++) list.push(entries[j]);
|
|
690
704
|
continue;
|
|
691
705
|
}
|
|
@@ -1256,7 +1270,6 @@ var Elysia = class Elysia {
|
|
|
1256
1270
|
return r;
|
|
1257
1271
|
}
|
|
1258
1272
|
};
|
|
1259
|
-
Elysia.prototype.mapDerive = Elysia.prototype.derive;
|
|
1260
1273
|
|
|
1261
1274
|
//#endregion
|
|
1262
1275
|
exports.Elysia = Elysia;
|
package/dist/base.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isBun } from "./universal/constants.mjs";
|
|
2
2
|
import { MethodMap, isDynamicRegex, needEncodeRegex } from "./constants.mjs";
|
|
3
|
-
import { clonePlainDecorators, clonePlainDeep, coalesceStandaloneSchemas, createErrorEventHandler, eventProperties, fnOrigin, fnv1a, getLoosePath, guardNonPlainLeaves, hookToGuard, invalidateMacroEpoch, isEmpty, isNotEmpty, isRecordNumber, joinPath, macroOrigin, mapMethodBack, mergeDeep, mergeResponse, nullObject, pushField, schemaProperties, serializeMacroSeed } from "./utils.mjs";
|
|
3
|
+
import { clonePlainDecorators, clonePlainDeep, coalesceStandaloneSchemas, createErrorEventHandler, eventProperties, fnOrigin, fnv1a, getLoosePath, guardNonPlainLeaves, hookToGuard, invalidateMacroEpoch, isEmpty, isNotEmpty, isRecordNumber, joinPath, macroOrigin, mapDeriveEntry, mapMethodBack, mergeDeep, mergeResponse, nullObject, pushField, schemaProperties, serializeMacroSeed } from "./utils.mjs";
|
|
4
4
|
import { Ref } from "./type/bridge.mjs";
|
|
5
5
|
import { Capture } from "./compile/aot.mjs";
|
|
6
6
|
import { compileHandler, composeRouteHook, localMacroRoot, resolveLocalHook } from "./compile/handler/index.mjs";
|
|
@@ -140,6 +140,7 @@ var Elysia = class Elysia {
|
|
|
140
140
|
#on(type, fn, scope = this["~config"]?.as) {
|
|
141
141
|
const added = nullObject();
|
|
142
142
|
added[type] = fn;
|
|
143
|
+
if (type === "trace") this["~hasTrace"] = true;
|
|
143
144
|
this["~hookChain"] = {
|
|
144
145
|
added,
|
|
145
146
|
parent: this["~hookChain"],
|
|
@@ -214,6 +215,17 @@ var Elysia = class Elysia {
|
|
|
214
215
|
}
|
|
215
216
|
return result;
|
|
216
217
|
}
|
|
218
|
+
mapDerive(scopeOrFn, fn) {
|
|
219
|
+
const result = this.#onBranch("beforeHandle", scopeOrFn, fn);
|
|
220
|
+
const node = this["~hookChain"];
|
|
221
|
+
if (node?.added) {
|
|
222
|
+
const d = fn ?? scopeOrFn;
|
|
223
|
+
const entries = node.added["~deriveEntries"] ??= [];
|
|
224
|
+
if (Array.isArray(d)) for (const f of d) entries.push(mapDeriveEntry(f));
|
|
225
|
+
else entries.push(mapDeriveEntry(d));
|
|
226
|
+
}
|
|
227
|
+
return result;
|
|
228
|
+
}
|
|
217
229
|
afterHandle(scopeOrFn, fn) {
|
|
218
230
|
return this.#onBranch("afterHandle", scopeOrFn, fn);
|
|
219
231
|
}
|
|
@@ -365,6 +377,7 @@ var Elysia = class Elysia {
|
|
|
365
377
|
}
|
|
366
378
|
hook = promoted;
|
|
367
379
|
}
|
|
380
|
+
if (hook.trace) this["~hasTrace"] = true;
|
|
368
381
|
this["~hookChain"] = {
|
|
369
382
|
added: hook,
|
|
370
383
|
parent: this["~hookChain"],
|
|
@@ -545,6 +558,7 @@ var Elysia = class Elysia {
|
|
|
545
558
|
if (addedByThisCall) for (const h of addedByThisCall) this.#childrenHash.delete(h);
|
|
546
559
|
throw new Error(`[Elysia] Macro "${macroName}" can be only define once`);
|
|
547
560
|
}
|
|
561
|
+
if (app["~hasTrace"]) this["~hasTrace"] = true;
|
|
548
562
|
if (app.#history) {
|
|
549
563
|
if (app["~hasWS"]) this["~hasWS"] = true;
|
|
550
564
|
const history = this.#history ??= [];
|
|
@@ -679,10 +693,10 @@ var Elysia = class Elysia {
|
|
|
679
693
|
continue;
|
|
680
694
|
}
|
|
681
695
|
if (key === "~deriveEntries") {
|
|
682
|
-
const entries = added[
|
|
696
|
+
const entries = added[key];
|
|
683
697
|
if (!entries) continue;
|
|
684
698
|
const target = isGlobal ? globalEvents ??= nullObject() : pluginEvents ??= nullObject();
|
|
685
|
-
const list = target[
|
|
699
|
+
const list = target[key] ??= [];
|
|
686
700
|
for (let j = 0; j < entries.length; j++) list.push(entries[j]);
|
|
687
701
|
continue;
|
|
688
702
|
}
|
|
@@ -1253,7 +1267,6 @@ var Elysia = class Elysia {
|
|
|
1253
1267
|
return r;
|
|
1254
1268
|
}
|
|
1255
1269
|
};
|
|
1256
|
-
Elysia.prototype.mapDerive = Elysia.prototype.derive;
|
|
1257
1270
|
|
|
1258
1271
|
//#endregion
|
|
1259
1272
|
export { Elysia };
|
|
@@ -4,15 +4,21 @@ const require_compile_aot = require('./aot.js');
|
|
|
4
4
|
const require_compile_handler_frozen_validator = require('./handler/frozen-validator.js');
|
|
5
5
|
const require_type_coerce = require('../type/coerce.js');
|
|
6
6
|
const require_type_validator_default_precompute = require('../type/validator/default-precompute.js');
|
|
7
|
+
const require_compile_aot_reconstruct = require('./aot-reconstruct.js');
|
|
7
8
|
const require_type_validator_frozen_check = require('../type/validator/frozen-check.js');
|
|
8
9
|
const require_type_validator_custom_error = require('../type/validator/custom-error.js');
|
|
9
|
-
const require_type_validator_string_codec_aot = require('../type/validator/string-codec-aot.js');
|
|
10
10
|
const require_type_validator_index = require('../type/validator/index.js');
|
|
11
|
+
const require_type_validator_string_codec_aot = require('../type/validator/string-codec-aot.js');
|
|
11
12
|
let typebox_schema = require("typebox/schema");
|
|
12
13
|
let exact_mirror = require("exact-mirror");
|
|
13
14
|
exact_mirror = require_runtime.__toESM(exact_mirror);
|
|
14
15
|
|
|
15
16
|
//#region src/compile/aot-capture.ts
|
|
17
|
+
function externalsShape(schema) {
|
|
18
|
+
let out = "";
|
|
19
|
+
for (const e of require_compile_aot_reconstruct.collectExternals(schema)) out += e instanceof RegExp ? "r" : typeof e === "function" ? "f" : "v";
|
|
20
|
+
return out;
|
|
21
|
+
}
|
|
16
22
|
function sourceOnlyValidator(schema) {
|
|
17
23
|
const buildResult = (0, typebox_schema.Build)(schema);
|
|
18
24
|
let full;
|
|
@@ -27,7 +33,7 @@ function maybeCapture(args) {
|
|
|
27
33
|
const { aot, slot, hasRef, originalSchema, schema, hasCodec, hasDefault, coerces, normalize, buildResult } = args;
|
|
28
34
|
if (hasCodec && !hasRef && coerces && normalize !== false && normalize !== "typebox") {
|
|
29
35
|
const plan = require_type_coerce.captureCoercePlan(originalSchema, schema);
|
|
30
|
-
if (plan &&
|
|
36
|
+
if (plan && externalsShape(require_type_coerce.buildCoercedFromPlan(originalSchema, plan)) === externalsShape(schema)) require_compile_aot.Capture.set({
|
|
31
37
|
method: aot.method,
|
|
32
38
|
path: aot.path,
|
|
33
39
|
slot
|
|
@@ -101,7 +107,7 @@ function captureMirror(schema, aot, slot, sanitize) {
|
|
|
101
107
|
hasExternals: false
|
|
102
108
|
} });
|
|
103
109
|
else if (ext.unions && !ext.hof) {
|
|
104
|
-
const u =
|
|
110
|
+
const u = require_compile_aot_reconstruct.captureMirrorUnions(schema, ext.unions);
|
|
105
111
|
if (u) require_compile_aot.Capture.set({
|
|
106
112
|
method: aot.method,
|
|
107
113
|
path: aot.path,
|
|
@@ -126,11 +132,11 @@ function captureCodecMirror(schema, aot, slot, sanitize, dir) {
|
|
|
126
132
|
});
|
|
127
133
|
if (typeof emitted?.source === "string") {
|
|
128
134
|
const ext = emitted.externals;
|
|
129
|
-
if (ext?.codecs && !ext.hof &&
|
|
135
|
+
if (ext?.codecs && !ext.hof && require_compile_aot_reconstruct.captureMirrorCodecs(schema, ext.codecs, dir)) {
|
|
130
136
|
let u;
|
|
131
137
|
let freezable = true;
|
|
132
138
|
if (ext.unions && ext.unions.length) {
|
|
133
|
-
u =
|
|
139
|
+
u = require_compile_aot_reconstruct.captureMirrorUnions(schema, ext.unions);
|
|
134
140
|
if (!u) freezable = false;
|
|
135
141
|
}
|
|
136
142
|
if (freezable) {
|
|
@@ -170,6 +176,7 @@ const impl = {
|
|
|
170
176
|
};
|
|
171
177
|
function installCaptureImpl() {
|
|
172
178
|
require_compile_aot.setCaptureImpl(impl);
|
|
179
|
+
require_compile_aot_reconstruct.installReconstructImpl();
|
|
173
180
|
}
|
|
174
181
|
installCaptureImpl();
|
|
175
182
|
|
|
@@ -2,14 +2,20 @@ import { Capture, setCaptureImpl } from "./aot.mjs";
|
|
|
2
2
|
import { isCapturedBridgeFree } from "./handler/frozen-validator.mjs";
|
|
3
3
|
import { buildCoercedFromPlan, captureCoercePlan } from "../type/coerce.mjs";
|
|
4
4
|
import { buildDefaultClonerSource, buildObjectDefaultMergeSource, verifyPreallocatableDefault } from "../type/validator/default-precompute.mjs";
|
|
5
|
+
import { captureMirrorCodecs, captureMirrorUnions, collectExternals, installReconstructImpl } from "./aot-reconstruct.mjs";
|
|
5
6
|
import { buildFrozenCheck } from "../type/validator/frozen-check.mjs";
|
|
6
7
|
import { captureCustomErrors } from "../type/validator/custom-error.mjs";
|
|
8
|
+
import { isAsyncPredicate } from "../type/validator/index.mjs";
|
|
7
9
|
import { captureStringCodecEntries } from "../type/validator/string-codec-aot.mjs";
|
|
8
|
-
import { externalsShape, isAsyncPredicate } from "../type/validator/index.mjs";
|
|
9
10
|
import { Build, Compile } from "typebox/schema";
|
|
10
11
|
import createMirror from "exact-mirror";
|
|
11
12
|
|
|
12
13
|
//#region src/compile/aot-capture.ts
|
|
14
|
+
function externalsShape(schema) {
|
|
15
|
+
let out = "";
|
|
16
|
+
for (const e of collectExternals(schema)) out += e instanceof RegExp ? "r" : typeof e === "function" ? "f" : "v";
|
|
17
|
+
return out;
|
|
18
|
+
}
|
|
13
19
|
function sourceOnlyValidator(schema) {
|
|
14
20
|
const buildResult = Build(schema);
|
|
15
21
|
let full;
|
|
@@ -98,7 +104,7 @@ function captureMirror(schema, aot, slot, sanitize) {
|
|
|
98
104
|
hasExternals: false
|
|
99
105
|
} });
|
|
100
106
|
else if (ext.unions && !ext.hof) {
|
|
101
|
-
const u =
|
|
107
|
+
const u = captureMirrorUnions(schema, ext.unions);
|
|
102
108
|
if (u) Capture.set({
|
|
103
109
|
method: aot.method,
|
|
104
110
|
path: aot.path,
|
|
@@ -123,11 +129,11 @@ function captureCodecMirror(schema, aot, slot, sanitize, dir) {
|
|
|
123
129
|
});
|
|
124
130
|
if (typeof emitted?.source === "string") {
|
|
125
131
|
const ext = emitted.externals;
|
|
126
|
-
if (ext?.codecs && !ext.hof &&
|
|
132
|
+
if (ext?.codecs && !ext.hof && captureMirrorCodecs(schema, ext.codecs, dir)) {
|
|
127
133
|
let u;
|
|
128
134
|
let freezable = true;
|
|
129
135
|
if (ext.unions && ext.unions.length) {
|
|
130
|
-
u =
|
|
136
|
+
u = captureMirrorUnions(schema, ext.unions);
|
|
131
137
|
if (!u) freezable = false;
|
|
132
138
|
}
|
|
133
139
|
if (freezable) {
|
|
@@ -167,6 +173,7 @@ const impl = {
|
|
|
167
173
|
};
|
|
168
174
|
function installCaptureImpl() {
|
|
169
175
|
setCaptureImpl(impl);
|
|
176
|
+
installReconstructImpl();
|
|
170
177
|
}
|
|
171
178
|
installCaptureImpl();
|
|
172
179
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { CheckBuildResult, FrozenMirror, FrozenValidator, ReconstructImpl, StringCodecNode } from "./aot.js";
|
|
2
|
+
|
|
3
|
+
//#region src/compile/aot-reconstruct.d.ts
|
|
4
|
+
declare function reconstructCheck(build: CheckBuildResult): {
|
|
5
|
+
defs: string;
|
|
6
|
+
value: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Rebuild TypeBox `External[]` for `schema` in `BuildSchema` traversal order:
|
|
10
|
+
* object (patternProperties → properties) → array (items) → string (pattern) →
|
|
11
|
+
* guard → const → enum → not/allOf/anyOf/oneOf → refine LAST.
|
|
12
|
+
*/
|
|
13
|
+
declare function collectExternals(schema: any, out?: unknown[]): unknown[];
|
|
14
|
+
declare function externalsMatch(a: unknown[], b: unknown[]): boolean;
|
|
15
|
+
declare const Source: {
|
|
16
|
+
readonly checkFactory: (identifier: string, code: string) => string;
|
|
17
|
+
readonly checkCode: (defs: string, value: string) => string;
|
|
18
|
+
readonly handlerFactory: (alias: string, code: string) => string;
|
|
19
|
+
readonly mirrorFactory: (source: string, hasExternals: boolean) => string;
|
|
20
|
+
readonly bothFactory: (identifier: string, checkDefs: string, checkValue: string, mirrorSource: string, mirrorHasExternals: boolean) => string;
|
|
21
|
+
};
|
|
22
|
+
declare function collectMirrorUnions(schema: any, out?: unknown[][]): unknown[][];
|
|
23
|
+
declare function instantiateFrozenMirror(frozen: FrozenMirror, schema: unknown): (value: unknown) => unknown;
|
|
24
|
+
declare function instantiateFrozenDecodeMirror(frozen: FrozenMirror, schema: unknown, dir?: 'decode' | 'encode'): (value: unknown) => unknown;
|
|
25
|
+
declare const instantiateFrozenEncodeMirror: (frozen: FrozenMirror, schema: unknown) => ((value: unknown) => unknown);
|
|
26
|
+
declare function instantiateFrozenBoth(frozen: FrozenValidator, checkSchema: unknown, mirrorSchema: unknown): {
|
|
27
|
+
check?: (value: unknown) => boolean;
|
|
28
|
+
clean?: (value: unknown) => unknown;
|
|
29
|
+
};
|
|
30
|
+
declare function collectStringCodecNodes(schema: any, out?: StringCodecNode[]): StringCodecNode[];
|
|
31
|
+
/**
|
|
32
|
+
* Overwrite every ObjectString/ArrayString node's `~refine[0].check` and
|
|
33
|
+
* `~codec.decode` with the baked `ic` closures. After this runs, the node no
|
|
34
|
+
* longer calls the constructor's live `typebox/value` Check/Decode
|
|
35
|
+
*
|
|
36
|
+
* Iterate in reverse so nested codecs reconstruct bottom-up.
|
|
37
|
+
*/
|
|
38
|
+
declare function reconstructInnerCodecs(ic: NonNullable<FrozenValidator['ic']>, schema: any): void;
|
|
39
|
+
/**
|
|
40
|
+
* verify that mirror unions can be reconstructed in build time
|
|
41
|
+
*
|
|
42
|
+
* return undefined if not reconstructable
|
|
43
|
+
* `truthUnions` is `mir.externals.unions` (compiled branches).
|
|
44
|
+
*/
|
|
45
|
+
declare function captureMirrorUnions(schema: unknown, truthUnions: any[][]): {
|
|
46
|
+
identifier: string;
|
|
47
|
+
code: string;
|
|
48
|
+
}[][] | undefined;
|
|
49
|
+
declare function captureMirrorCodecs(schema: unknown, truthCodecs: Function[], dir?: 'decode' | 'encode'): boolean;
|
|
50
|
+
/** Runtime reconstruction table the generated manifest module registers. */
|
|
51
|
+
declare const Reconstruct: ReconstructImpl;
|
|
52
|
+
declare function installReconstructImpl(): void;
|
|
53
|
+
//#endregion
|
|
54
|
+
export { Reconstruct, Source, captureMirrorCodecs, captureMirrorUnions, collectExternals, collectMirrorUnions, collectStringCodecNodes, externalsMatch, installReconstructImpl, instantiateFrozenBoth, instantiateFrozenDecodeMirror, instantiateFrozenEncodeMirror, instantiateFrozenMirror, reconstructCheck, reconstructInnerCodecs };
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
const require_type_constants = require('../type/constants.js');
|
|
3
|
+
const require_compile_aot = require('./aot.js');
|
|
4
|
+
|
|
5
|
+
//#region src/compile/aot-reconstruct.ts
|
|
6
|
+
/**
|
|
7
|
+
* Frozen-manifest reconstruction + source emitters.
|
|
8
|
+
*
|
|
9
|
+
* Kept out of `aot.ts` so apps that never load a generated manifest module
|
|
10
|
+
* tree-shake it: runtime call sites reach these through `reconstruct()`
|
|
11
|
+
* (see `aot.ts`), wired by the generated `elysia/reconstruct`
|
|
12
|
+
*
|
|
13
|
+
* Everything here is pure (no module state): the stateful registration goes
|
|
14
|
+
* through `Compiled` from `registerFrom`, so a duplicate copy of this module
|
|
15
|
+
* resolving from another elysia install still reconstructs correctly.
|
|
16
|
+
*/
|
|
17
|
+
function reconstructCheck(build) {
|
|
18
|
+
const defs = build.functions.join(";\n");
|
|
19
|
+
if (!build.useUnevaluated) {
|
|
20
|
+
const single = /^([A-Za-z_$][\w$]*)\(value\)$/.exec(build.entry.trim());
|
|
21
|
+
if (single) return {
|
|
22
|
+
defs,
|
|
23
|
+
value: single[1]
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
defs,
|
|
28
|
+
value: `(value) => { ${(build.useUnevaluated ? "const context = new CheckContext({}, {});\n" : "") + `return ${build.entry}`} }`
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const checkCode = (defs, value) => `${defs}; return ${value}`;
|
|
32
|
+
function reconstructCheckCode(build) {
|
|
33
|
+
const { defs, value } = reconstructCheck(build);
|
|
34
|
+
return checkCode(defs, value);
|
|
35
|
+
}
|
|
36
|
+
const checkFactorySource = (identifier, code) => `function(${identifier}){${code}}`;
|
|
37
|
+
const handlerFactorySource = (alias, code) => `function(h${alias ? "," + alias : ""}){return ${code}}`;
|
|
38
|
+
const isValueLikeExternal = (v) => v === null || typeof v !== "object" && typeof v !== "function";
|
|
39
|
+
/**
|
|
40
|
+
* Rebuild TypeBox `External[]` for `schema` in `BuildSchema` traversal order:
|
|
41
|
+
* object (patternProperties → properties) → array (items) → string (pattern) →
|
|
42
|
+
* guard → const → enum → not/allOf/anyOf/oneOf → refine LAST.
|
|
43
|
+
*/
|
|
44
|
+
function collectExternals(schema, out = []) {
|
|
45
|
+
if (!schema || typeof schema !== "object") return out;
|
|
46
|
+
const pp = schema.patternProperties;
|
|
47
|
+
if (pp) for (const pattern in pp) {
|
|
48
|
+
out.push(new RegExp(pattern, "u"));
|
|
49
|
+
collectExternals(pp[pattern], out);
|
|
50
|
+
}
|
|
51
|
+
if (schema.properties) for (const k in schema.properties) collectExternals(schema.properties[k], out);
|
|
52
|
+
const items = schema.items;
|
|
53
|
+
if (Array.isArray(items)) for (const it of items) collectExternals(it, out);
|
|
54
|
+
else if (items) collectExternals(items, out);
|
|
55
|
+
if (typeof schema.pattern === "string") out.push(new RegExp(schema.pattern, "u"));
|
|
56
|
+
if (schema["~guard"]) out.push(schema);
|
|
57
|
+
if ("const" in schema && !isValueLikeExternal(schema.const)) out.push(schema.const);
|
|
58
|
+
if (Array.isArray(schema.enum)) {
|
|
59
|
+
for (const o of schema.enum) if (!isValueLikeExternal(o)) out.push(o);
|
|
60
|
+
}
|
|
61
|
+
if (schema.not) collectExternals(schema.not, out);
|
|
62
|
+
if (Array.isArray(schema.allOf)) for (const s of schema.allOf) collectExternals(s, out);
|
|
63
|
+
if (Array.isArray(schema.anyOf)) for (const s of schema.anyOf) collectExternals(s, out);
|
|
64
|
+
if (Array.isArray(schema.oneOf)) for (const s of schema.oneOf) collectExternals(s, out);
|
|
65
|
+
if (schema["~refine"]) out.push(schema["~refine"]);
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
function externalsMatch(a, b) {
|
|
69
|
+
if (a.length !== b.length) return false;
|
|
70
|
+
for (let i = 0; i < a.length; i++) {
|
|
71
|
+
const x = a[i];
|
|
72
|
+
const y = b[i];
|
|
73
|
+
if (x === y) continue;
|
|
74
|
+
if (x instanceof RegExp && y instanceof RegExp) {
|
|
75
|
+
if (x.source !== y.source || x.flags !== y.flags) return false;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (Array.isArray(x) && Array.isArray(y)) {
|
|
79
|
+
if (x.length !== y.length) return false;
|
|
80
|
+
let ok = true;
|
|
81
|
+
for (let j = 0; j < x.length; j++) if (x[j] !== y[j]) {
|
|
82
|
+
ok = false;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
if (ok) continue;
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
const mirrorFactorySource = (source, hasExternals) => hasExternals ? `function(d){${source}}` : `function(v){${source}}`;
|
|
92
|
+
const bothFactorySource = (identifier, checkDefs, checkValue, mirrorSource, mirrorHasExternals) => `function(${identifier},d){${checkDefs}; return{check:${checkValue},clean:${mirrorHasExternals ? `(function(d){${mirrorSource}})(d)` : `function(v){${mirrorSource}}`}}}`;
|
|
93
|
+
const Source = {
|
|
94
|
+
checkFactory: checkFactorySource,
|
|
95
|
+
checkCode,
|
|
96
|
+
handlerFactory: handlerFactorySource,
|
|
97
|
+
mirrorFactory: mirrorFactorySource,
|
|
98
|
+
bothFactory: bothFactorySource
|
|
99
|
+
};
|
|
100
|
+
function collectMirrorUnions(schema, out = []) {
|
|
101
|
+
if (!schema || typeof schema !== "object") return out;
|
|
102
|
+
if (schema.type === "object" && schema.properties) for (const key in schema.properties) collectMirrorUnions(schema.properties[key], out);
|
|
103
|
+
else if (schema.type === "array" && schema.items) if (Array.isArray(schema.items)) for (const it of schema.items) collectMirrorUnions(it, out);
|
|
104
|
+
else collectMirrorUnions(schema.items, out);
|
|
105
|
+
else if (Array.isArray(schema.anyOf)) {
|
|
106
|
+
out.push(schema.anyOf);
|
|
107
|
+
for (const b of schema.anyOf) {
|
|
108
|
+
collectMirrorUnions(b, out);
|
|
109
|
+
collectMirrorUnions(b, out);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
114
|
+
function collectMirrorCodecs(schema, out = [], dir = "decode") {
|
|
115
|
+
if (!schema || typeof schema !== "object") return out;
|
|
116
|
+
const codec = schema["~codec"];
|
|
117
|
+
if (codec && typeof codec[dir] === "function" && out.indexOf(codec[dir]) === -1) out.push(codec[dir]);
|
|
118
|
+
if (schema.type === "object" && schema.properties) for (const key in schema.properties) collectMirrorCodecs(schema.properties[key], out, dir);
|
|
119
|
+
else if (schema.type === "array" && schema.items) if (Array.isArray(schema.items)) for (const it of schema.items) collectMirrorCodecs(it, out, dir);
|
|
120
|
+
else collectMirrorCodecs(schema.items, out, dir);
|
|
121
|
+
else if (Array.isArray(schema.anyOf)) for (const b of schema.anyOf) collectMirrorCodecs(b, out, dir);
|
|
122
|
+
return out;
|
|
123
|
+
}
|
|
124
|
+
function buildUnions(u, schema) {
|
|
125
|
+
const branchSchemas = collectMirrorUnions(schema);
|
|
126
|
+
return u.map((branches, ui) => branches.map((factory, i) => ({ Check: factory(collectExternals(branchSchemas[ui][i])) })));
|
|
127
|
+
}
|
|
128
|
+
function instantiateFrozenMirror(frozen, schema) {
|
|
129
|
+
if (!frozen.u) return frozen.s;
|
|
130
|
+
return frozen.s({ unions: buildUnions(frozen.u, schema) });
|
|
131
|
+
}
|
|
132
|
+
function instantiateFrozenDecodeMirror(frozen, schema, dir = "decode") {
|
|
133
|
+
const d = { codecs: collectMirrorCodecs(schema, [], dir) };
|
|
134
|
+
if (frozen.u) d.unions = buildUnions(frozen.u, schema);
|
|
135
|
+
return frozen.s(d);
|
|
136
|
+
}
|
|
137
|
+
const instantiateFrozenEncodeMirror = (frozen, schema) => instantiateFrozenDecodeMirror(frozen, schema, "encode");
|
|
138
|
+
function instantiateFrozenBoth(frozen, checkSchema, mirrorSchema) {
|
|
139
|
+
return frozen.cm(frozen.e ? collectExternals(checkSchema) : require_compile_aot.EMPTY_EXTERNALS, frozen.u ? { unions: buildUnions(frozen.u, mirrorSchema) } : void 0);
|
|
140
|
+
}
|
|
141
|
+
function collectStringCodecNodes(schema, out = []) {
|
|
142
|
+
if (!schema || typeof schema !== "object") return out;
|
|
143
|
+
const ely = schema["~elyTyp"];
|
|
144
|
+
if (ely === require_type_constants.ELYSIA_TYPES.ObjectString || ely === require_type_constants.ELYSIA_TYPES.ArrayString) {
|
|
145
|
+
const inner = schema.anyOf?.[0];
|
|
146
|
+
const codec = schema.anyOf?.[1];
|
|
147
|
+
if (inner && codec?.["~codec"] && codec["~refine"]) out.push({
|
|
148
|
+
inner,
|
|
149
|
+
codec,
|
|
150
|
+
open: ely === require_type_constants.ELYSIA_TYPES.ObjectString ? 123 : 91
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
if (schema.properties) for (const k in schema.properties) collectStringCodecNodes(schema.properties[k], out);
|
|
154
|
+
const items = schema.items;
|
|
155
|
+
if (Array.isArray(items)) for (const it of items) collectStringCodecNodes(it, out);
|
|
156
|
+
else if (items) collectStringCodecNodes(items, out);
|
|
157
|
+
if (Array.isArray(schema.anyOf)) for (const b of schema.anyOf) collectStringCodecNodes(b, out);
|
|
158
|
+
return out;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Overwrite every ObjectString/ArrayString node's `~refine[0].check` and
|
|
162
|
+
* `~codec.decode` with the baked `ic` closures. After this runs, the node no
|
|
163
|
+
* longer calls the constructor's live `typebox/value` Check/Decode
|
|
164
|
+
*
|
|
165
|
+
* Iterate in reverse so nested codecs reconstruct bottom-up.
|
|
166
|
+
*/
|
|
167
|
+
function reconstructInnerCodecs(ic, schema) {
|
|
168
|
+
const nodes = collectStringCodecNodes(schema);
|
|
169
|
+
for (let i = nodes.length - 1; i >= 0; i--) {
|
|
170
|
+
const entry = ic[i];
|
|
171
|
+
const node = nodes[i];
|
|
172
|
+
if (!entry || !node) continue;
|
|
173
|
+
const innerSchema = node.inner;
|
|
174
|
+
const innerCheck = entry.c(entry.e ? collectExternals(innerSchema) : []);
|
|
175
|
+
const innerMirror = entry.d.x ? instantiateFrozenDecodeMirror(entry.d, innerSchema) : entry.d.s;
|
|
176
|
+
const open = entry.o;
|
|
177
|
+
node.codec["~refine"][0].check = (v) => {
|
|
178
|
+
if (v.charCodeAt(0) !== open) return false;
|
|
179
|
+
try {
|
|
180
|
+
return innerCheck(JSON.parse(v));
|
|
181
|
+
} catch {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
node.codec["~codec"].decode = (v) => innerMirror(JSON.parse(v));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* verify that mirror unions can be reconstructed in build time
|
|
190
|
+
*
|
|
191
|
+
* return undefined if not reconstructable
|
|
192
|
+
* `truthUnions` is `mir.externals.unions` (compiled branches).
|
|
193
|
+
*/
|
|
194
|
+
function captureMirrorUnions(schema, truthUnions) {
|
|
195
|
+
const branchSchemas = collectMirrorUnions(schema);
|
|
196
|
+
if (branchSchemas.length !== truthUnions.length) return;
|
|
197
|
+
const u = [];
|
|
198
|
+
for (let ui = 0; ui < truthUnions.length; ui++) {
|
|
199
|
+
if (!branchSchemas[ui] || branchSchemas[ui].length !== truthUnions[ui].length) return;
|
|
200
|
+
const branch = [];
|
|
201
|
+
for (let i = 0; i < truthUnions[ui].length; i++) {
|
|
202
|
+
const build = truthUnions[ui][i]?.buildResult;
|
|
203
|
+
if (!build?.functions?.length || !build.entry) return;
|
|
204
|
+
if (!externalsMatch(collectExternals(branchSchemas[ui][i]), build.external.variables)) return;
|
|
205
|
+
branch.push({
|
|
206
|
+
identifier: build.external.identifier,
|
|
207
|
+
code: reconstructCheckCode(build)
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
u.push(branch);
|
|
211
|
+
}
|
|
212
|
+
return u;
|
|
213
|
+
}
|
|
214
|
+
function captureMirrorCodecs(schema, truthCodecs, dir = "decode") {
|
|
215
|
+
const codecs = collectMirrorCodecs(schema, [], dir);
|
|
216
|
+
if (codecs.length !== truthCodecs.length) return false;
|
|
217
|
+
for (let i = 0; i < codecs.length; i++) if (codecs[i] !== truthCodecs[i]) return false;
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
/** Runtime reconstruction table the generated manifest module registers. */
|
|
221
|
+
const Reconstruct = {
|
|
222
|
+
collectExternals,
|
|
223
|
+
collectMirrorUnions,
|
|
224
|
+
collectStringCodecNodes,
|
|
225
|
+
instantiateFrozenMirror,
|
|
226
|
+
instantiateFrozenDecodeMirror,
|
|
227
|
+
instantiateFrozenBoth,
|
|
228
|
+
reconstructInnerCodecs
|
|
229
|
+
};
|
|
230
|
+
function installReconstructImpl() {
|
|
231
|
+
require_compile_aot.Compiled.reconstruct = Reconstruct;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
//#endregion
|
|
235
|
+
exports.Reconstruct = Reconstruct;
|
|
236
|
+
exports.Source = Source;
|
|
237
|
+
exports.captureMirrorCodecs = captureMirrorCodecs;
|
|
238
|
+
exports.captureMirrorUnions = captureMirrorUnions;
|
|
239
|
+
exports.collectExternals = collectExternals;
|
|
240
|
+
exports.collectMirrorUnions = collectMirrorUnions;
|
|
241
|
+
exports.collectStringCodecNodes = collectStringCodecNodes;
|
|
242
|
+
exports.externalsMatch = externalsMatch;
|
|
243
|
+
exports.installReconstructImpl = installReconstructImpl;
|
|
244
|
+
exports.instantiateFrozenBoth = instantiateFrozenBoth;
|
|
245
|
+
exports.instantiateFrozenDecodeMirror = instantiateFrozenDecodeMirror;
|
|
246
|
+
exports.instantiateFrozenEncodeMirror = instantiateFrozenEncodeMirror;
|
|
247
|
+
exports.instantiateFrozenMirror = instantiateFrozenMirror;
|
|
248
|
+
exports.reconstructCheck = reconstructCheck;
|
|
249
|
+
exports.reconstructInnerCodecs = reconstructInnerCodecs;
|