elysia 2.0.0-beta.2 → 2.0.0-beta.21
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/bun/index.d.ts +18 -2
- package/dist/adapter/bun/index.js +467 -110
- package/dist/adapter/bun/index.mjs +467 -112
- package/dist/adapter/types.d.ts +2 -21
- package/dist/adapter/utils.d.ts +14 -3
- package/dist/adapter/utils.js +146 -87
- package/dist/adapter/utils.mjs +148 -90
- package/dist/adapter/web-standard/handler.d.ts +1 -1
- package/dist/adapter/web-standard/handler.js +47 -36
- package/dist/adapter/web-standard/handler.mjs +48 -37
- package/dist/adapter/web-standard/index.js +2 -30
- package/dist/adapter/web-standard/index.mjs +2 -30
- package/dist/adapter/web-standard/utils.js +5 -18
- package/dist/adapter/web-standard/utils.mjs +5 -18
- package/dist/base.d.ts +99 -67
- package/dist/base.js +678 -510
- package/dist/base.mjs +682 -514
- package/dist/compile/aot-capture.d.ts +2 -13
- package/dist/compile/aot-capture.js +26 -69
- package/dist/compile/aot-capture.mjs +28 -67
- package/dist/compile/aot-emit.d.ts +9 -7
- package/dist/compile/aot-emit.js +42 -19
- package/dist/compile/aot-emit.mjs +42 -20
- package/dist/compile/aot.d.ts +17 -19
- package/dist/compile/aot.js +41 -51
- package/dist/compile/aot.mjs +39 -49
- package/dist/compile/handler/descriptor.d.ts +9 -12
- package/dist/compile/handler/descriptor.js +19 -44
- package/dist/compile/handler/descriptor.mjs +20 -42
- package/dist/compile/handler/frozen-validator.d.ts +5 -10
- package/dist/compile/handler/frozen-validator.js +55 -105
- package/dist/compile/handler/frozen-validator.mjs +53 -105
- package/dist/compile/handler/index.d.ts +7 -5
- package/dist/compile/handler/index.js +270 -111
- package/dist/compile/handler/index.mjs +270 -113
- package/dist/compile/handler/jit.d.ts +19 -17
- package/dist/compile/handler/jit.js +222 -149
- package/dist/compile/handler/jit.mjs +224 -152
- package/dist/compile/handler/params.d.ts +1 -4
- package/dist/compile/handler/params.js +10 -5
- package/dist/compile/handler/params.mjs +14 -8
- package/dist/compile/handler/reconstruct.d.ts +2 -2
- package/dist/compile/handler/reconstruct.js +6 -4
- package/dist/compile/handler/reconstruct.mjs +6 -4
- package/dist/compile/handler/static-clone-resolver.d.ts +6 -0
- package/dist/compile/handler/static-clone-resolver.js +8 -0
- package/dist/compile/handler/static-clone-resolver.mjs +7 -0
- package/dist/compile/handler/utils.d.ts +22 -11
- package/dist/compile/handler/utils.js +159 -253
- package/dist/compile/handler/utils.mjs +155 -252
- package/dist/compile/jit-probe.d.ts +2 -2
- package/dist/compile/jit-probe.js +2 -3
- package/dist/compile/jit-probe.mjs +2 -3
- package/dist/compile/lexer.d.ts +7 -4
- package/dist/compile/lexer.js +268 -6
- package/dist/compile/lexer.mjs +268 -4
- package/dist/compile/utils.js +7 -4
- package/dist/compile/utils.mjs +7 -4
- package/dist/compiled.d.ts +0 -1
- package/dist/compiled.js +0 -1
- package/dist/compiled.mjs +0 -1
- package/dist/context.d.ts +14 -4
- package/dist/context.js +17 -32
- package/dist/context.mjs +19 -34
- package/dist/cookie/config.d.ts +7 -2
- package/dist/cookie/config.js +76 -16
- package/dist/cookie/config.mjs +77 -18
- package/dist/cookie/cookie.d.ts +1 -1
- package/dist/cookie/cookie.js +8 -10
- package/dist/cookie/cookie.mjs +8 -10
- package/dist/cookie/crypto.d.ts +8 -7
- package/dist/cookie/crypto.js +51 -40
- package/dist/cookie/crypto.mjs +51 -41
- package/dist/cookie/error.d.ts +1 -2
- package/dist/cookie/error.js +6 -4
- package/dist/cookie/error.mjs +6 -4
- package/dist/cookie/lib.js +7 -2
- package/dist/cookie/lib.mjs +7 -2
- package/dist/cookie/serialize.js +1 -1
- package/dist/cookie/serialize.mjs +1 -1
- package/dist/cookie/types.d.ts +10 -0
- package/dist/cookie/utils.d.ts +4 -8
- package/dist/cookie/utils.js +86 -52
- package/dist/cookie/utils.mjs +89 -54
- package/dist/error.d.ts +113 -103
- package/dist/error.js +181 -117
- package/dist/error.mjs +179 -118
- package/dist/generation.d.ts +2 -2
- package/dist/handler/error.d.ts +26 -15
- package/dist/handler/error.js +77 -96
- package/dist/handler/error.mjs +74 -97
- package/dist/handler/fetch.js +87 -108
- package/dist/handler/fetch.mjs +89 -110
- package/dist/handler/utils.d.ts +12 -6
- package/dist/handler/utils.js +84 -28
- package/dist/handler/utils.mjs +80 -28
- package/dist/index.d.ts +12 -12
- package/dist/index.js +2 -9
- package/dist/index.mjs +1 -1
- package/dist/memory.js +1 -1
- package/dist/memory.mjs +1 -1
- package/dist/package.js +1 -1
- package/dist/package.mjs +1 -1
- package/dist/plugin/aot/bun.d.ts +8 -1
- package/dist/plugin/aot/bun.js +16 -9
- package/dist/plugin/aot/bun.mjs +17 -10
- package/dist/plugin/aot/core.d.ts +52 -60
- package/dist/plugin/aot/core.js +208 -109
- package/dist/plugin/aot/core.mjs +205 -111
- package/dist/plugin/aot/esbuild.js +8 -5
- package/dist/plugin/aot/esbuild.mjs +9 -6
- package/dist/plugin/aot/hooks.d.ts +6 -17
- package/dist/plugin/aot/hooks.js +36 -14
- package/dist/plugin/aot/hooks.mjs +37 -16
- package/dist/plugin/aot/rspack-loader.d.ts +1 -5
- package/dist/plugin/aot/rspack-loader.js +1 -10
- package/dist/plugin/aot/rspack-loader.mjs +1 -10
- package/dist/plugin/aot/rspack.js +2 -5
- package/dist/plugin/aot/rspack.mjs +3 -6
- package/dist/plugin/aot/source.d.ts +6 -42
- package/dist/plugin/aot/source.js +71 -71
- package/dist/plugin/aot/source.mjs +72 -72
- package/dist/plugin/aot/treeshake.js +2 -6
- package/dist/plugin/aot/treeshake.mjs +2 -6
- package/dist/plugin/aot/unplugin.d.ts +1 -4
- package/dist/plugin/aot/unplugin.js +4 -13
- package/dist/plugin/aot/unplugin.mjs +4 -13
- package/dist/plugin/aot/vite.d.ts +2 -6
- package/dist/plugin/aot/worker.js +2 -2
- package/dist/plugin/aot/worker.mjs +2 -2
- package/dist/plugin/auto-head.js +1 -10
- package/dist/plugin/auto-head.mjs +1 -10
- package/dist/plugin/trace.d.ts +2 -1
- package/dist/route-table.d.ts +3 -0
- package/dist/route-table.js +16 -11
- package/dist/route-table.mjs +16 -11
- package/dist/schema-snapshot.d.ts +0 -4
- package/dist/schema-snapshot.js +32 -49
- package/dist/schema-snapshot.mjs +32 -49
- package/dist/sucrose.d.ts +6 -55
- package/dist/sucrose.js +103 -731
- package/dist/sucrose.mjs +102 -724
- package/dist/trace.d.ts +5 -8
- package/dist/trace.js +23 -134
- package/dist/trace.mjs +24 -135
- package/dist/type/bridge-live.d.ts +4 -2
- package/dist/type/bridge-live.js +6 -3
- package/dist/type/bridge-live.mjs +4 -2
- package/dist/type/bridge.d.ts +6 -4
- package/dist/type/bridge.js +17 -9
- package/dist/type/bridge.mjs +5 -3
- package/dist/type/coerce-plan.d.ts +5 -5
- package/dist/type/coerce-plan.js +41 -39
- package/dist/type/coerce-plan.mjs +43 -39
- package/dist/type/coerce.d.ts +3 -7
- package/dist/type/coerce.js +18 -75
- package/dist/type/coerce.mjs +19 -76
- package/dist/type/compat.d.ts +3 -0
- package/dist/type/compat.js +23 -14
- package/dist/type/compat.mjs +20 -10
- package/dist/type/elysia/array-buffer.d.ts +4 -1
- package/dist/type/elysia/array-buffer.js +17 -17
- package/dist/type/elysia/array-buffer.mjs +17 -17
- package/dist/type/elysia/array-string.js +2 -40
- package/dist/type/elysia/array-string.mjs +2 -39
- package/dist/type/elysia/array.js +5 -9
- package/dist/type/elysia/array.mjs +5 -9
- package/dist/type/elysia/boolean-string.js +2 -3
- package/dist/type/elysia/boolean-string.mjs +1 -1
- package/dist/type/elysia/boolean.js +3 -12
- package/dist/type/elysia/boolean.mjs +3 -11
- package/dist/type/elysia/cookie.d.ts +3 -4
- package/dist/type/elysia/cookie.js +5 -15
- package/dist/type/elysia/cookie.mjs +5 -15
- package/dist/type/elysia/date.js +13 -20
- package/dist/type/elysia/date.mjs +10 -16
- package/dist/type/elysia/file-type.d.ts +11 -4
- package/dist/type/elysia/file-type.js +17 -2
- package/dist/type/elysia/file-type.mjs +17 -3
- package/dist/type/elysia/file.d.ts +1 -3
- package/dist/type/elysia/file.js +11 -27
- package/dist/type/elysia/file.mjs +11 -12
- package/dist/type/elysia/files.js +7 -11
- package/dist/type/elysia/files.mjs +7 -10
- package/dist/type/elysia/form.js +2 -3
- package/dist/type/elysia/form.mjs +3 -3
- package/dist/type/elysia/integer-string.d.ts +1 -1
- package/dist/type/elysia/integer-string.js +4 -30
- package/dist/type/elysia/integer-string.mjs +5 -30
- package/dist/type/elysia/integer.js +3 -12
- package/dist/type/elysia/integer.mjs +3 -11
- package/dist/type/elysia/intersect.js +0 -5
- package/dist/type/elysia/intersect.mjs +0 -5
- package/dist/type/elysia/json-string.d.ts +7 -0
- package/dist/type/elysia/json-string.js +47 -0
- package/dist/type/elysia/json-string.mjs +46 -0
- package/dist/type/elysia/keep-config.d.ts +14 -0
- package/dist/type/elysia/keep-config.js +62 -0
- package/dist/type/elysia/keep-config.mjs +53 -0
- package/dist/type/elysia/maybe-empty.js +3 -4
- package/dist/type/elysia/maybe-empty.mjs +1 -1
- package/dist/type/elysia/nullable.js +2 -3
- package/dist/type/elysia/nullable.mjs +1 -1
- package/dist/type/elysia/number.d.ts +2 -1
- package/dist/type/elysia/number.js +19 -11
- package/dist/type/elysia/number.mjs +18 -10
- package/dist/type/elysia/numeric-enum.d.ts +1 -1
- package/dist/type/elysia/numeric-enum.js +4 -5
- package/dist/type/elysia/numeric-enum.mjs +3 -3
- package/dist/type/elysia/numeric.d.ts +4 -2
- package/dist/type/elysia/numeric.js +20 -17
- package/dist/type/elysia/numeric.mjs +19 -16
- package/dist/type/elysia/object-string.js +2 -37
- package/dist/type/elysia/object-string.mjs +2 -36
- package/dist/type/elysia/object.js +5 -9
- package/dist/type/elysia/object.mjs +5 -9
- package/dist/type/elysia/optional.js +8 -8
- package/dist/type/elysia/optional.mjs +7 -7
- package/dist/type/elysia/problem.d.ts +20 -0
- package/dist/type/elysia/problem.js +25 -0
- package/dist/type/elysia/problem.mjs +24 -0
- package/dist/type/elysia/string.js +4 -3
- package/dist/type/elysia/string.mjs +4 -2
- package/dist/type/elysia/uint8-array.d.ts +1 -1
- package/dist/type/elysia/uint8-array.js +5 -20
- package/dist/type/elysia/uint8-array.mjs +5 -19
- package/dist/type/elysia/union-enum.js +7 -8
- package/dist/type/elysia/union-enum.mjs +6 -6
- package/dist/type/elysia/union.js +0 -5
- package/dist/type/elysia/union.mjs +0 -5
- package/dist/type/elysia/utils.d.ts +2 -4
- package/dist/type/elysia/utils.js +10 -21
- package/dist/type/elysia/utils.mjs +7 -15
- package/dist/type/exports.d.ts +4 -2
- package/dist/type/exports.js +23 -2
- package/dist/type/exports.mjs +11 -2
- package/dist/type/index.d.ts +10 -2
- package/dist/type/index.js +62 -15
- package/dist/type/index.mjs +65 -11
- package/dist/type/shared.d.ts +3 -9
- package/dist/type/shared.js +44 -97
- package/dist/type/shared.mjs +43 -97
- package/dist/type/sync-require.d.ts +11 -0
- package/dist/type/sync-require.js +14 -0
- package/dist/type/sync-require.mjs +12 -0
- package/dist/type/typebox-system-lite.d.ts +2 -0
- package/dist/type/typebox-system-lite.js +34 -0
- package/dist/type/typebox-system-lite.mjs +3 -0
- package/dist/type/typebox-system-require.d.ts +7 -0
- package/dist/type/typebox-system-require.js +24 -0
- package/dist/type/typebox-system-require.mjs +23 -0
- package/dist/type/typebox-type-live.d.ts +11 -0
- package/dist/type/typebox-type-live.js +45 -0
- package/dist/type/typebox-type-live.mjs +20 -0
- package/dist/type/typebox-type.d.ts +34 -0
- package/dist/type/typebox-type.js +199 -0
- package/dist/type/typebox-type.mjs +86 -0
- package/dist/type/typebox-value-live.d.ts +11 -0
- package/dist/type/typebox-value-live.js +31 -0
- package/dist/type/typebox-value-live.mjs +13 -0
- package/dist/type/typebox-value-ops.d.ts +4 -0
- package/dist/type/typebox-value-ops.js +90 -0
- package/dist/type/typebox-value-ops.mjs +5 -0
- package/dist/type/typebox-value-require.d.ts +8 -0
- package/dist/type/typebox-value-require.js +28 -0
- package/dist/type/typebox-value-require.mjs +25 -0
- package/dist/type/typebox-value.d.ts +35 -0
- package/dist/type/typebox-value.js +161 -0
- package/dist/type/typebox-value.mjs +74 -0
- package/dist/type/utils.js +1 -10
- package/dist/type/utils.mjs +1 -10
- package/dist/type/validator/clean-safe.d.ts +2 -4
- package/dist/type/validator/clean-safe.js +15 -11
- package/dist/type/validator/clean-safe.mjs +16 -10
- package/dist/type/validator/custom-error.js +12 -16
- package/dist/type/validator/custom-error.mjs +11 -14
- package/dist/type/validator/default-precompute.d.ts +9 -1
- package/dist/type/validator/default-precompute.js +40 -77
- package/dist/type/validator/default-precompute.mjs +37 -74
- package/dist/type/validator/exact-mirror-live.d.ts +8 -0
- package/dist/type/validator/exact-mirror-live.js +22 -0
- package/dist/type/validator/exact-mirror-live.mjs +17 -0
- package/dist/type/validator/exact-mirror-require.d.ts +4 -0
- package/dist/type/validator/exact-mirror-require.js +11 -0
- package/dist/type/validator/exact-mirror-require.mjs +9 -0
- package/dist/type/validator/exact-mirror.js +8 -8
- package/dist/type/validator/exact-mirror.mjs +9 -8
- package/dist/type/validator/frozen-check.js +5 -6
- package/dist/type/validator/frozen-check.mjs +6 -7
- package/dist/type/validator/index.d.ts +1 -0
- package/dist/type/validator/index.js +169 -166
- package/dist/type/validator/index.mjs +162 -158
- package/dist/type/validator/string-codec-aot.d.ts +2 -1
- package/dist/type/validator/string-codec-aot.js +8 -2
- package/dist/type/validator/string-codec-aot.mjs +7 -2
- package/dist/type/validator/validator-cache.d.ts +5 -4
- package/dist/type/validator/validator-cache.js +41 -24
- package/dist/type/validator/validator-cache.mjs +40 -22
- package/dist/types.d.ts +263 -95
- 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/env.js +2 -3
- package/dist/universal/env.mjs +2 -3
- package/dist/universal/file.d.ts +6 -4
- package/dist/universal/file.js +11 -16
- package/dist/universal/file.mjs +12 -16
- package/dist/universal/index.d.ts +2 -2
- package/dist/universal/is-production.d.ts +1 -2
- package/dist/universal/is-production.js +1 -3
- package/dist/universal/is-production.mjs +2 -3
- package/dist/universal/server.d.ts +0 -272
- package/dist/utils.d.ts +43 -7
- package/dist/utils.js +181 -126
- package/dist/utils.mjs +168 -126
- package/dist/validator/index.d.ts +1 -1
- package/dist/validator/index.js +17 -30
- package/dist/validator/index.mjs +18 -31
- package/dist/validator/route.js +2 -1
- package/dist/validator/route.mjs +2 -1
- package/dist/ws/context.d.ts +8 -1
- package/dist/ws/context.js +68 -44
- package/dist/ws/context.mjs +67 -44
- package/dist/ws/parser.js +10 -20
- package/dist/ws/parser.mjs +10 -20
- package/dist/ws/route.d.ts +2 -2
- package/dist/ws/route.js +249 -141
- package/dist/ws/route.mjs +254 -146
- package/dist/ws/types.d.ts +2 -2
- package/package.json +23 -49
- package/dist/compile/analysis-cache.d.ts +0 -6
- package/dist/compile/analysis-cache.js +0 -12
- package/dist/compile/analysis-cache.mjs +0 -11
- package/dist/cookie/index.d.ts +0 -7
- package/dist/cookie/index.js +0 -13
- package/dist/cookie/index.mjs +0 -7
- package/dist/handler/index.d.ts +0 -2
- package/dist/handler/index.js +0 -5
- package/dist/handler/index.mjs +0 -3
package/dist/plugin/aot/core.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { isStandardSchema, mergeSchemasAllStandard } from "../../compile/handler/frozen-validator.mjs";
|
|
1
|
+
import { REQUEST_SLOTS, isResponseMap, isStandardSchema, mergeSchemasAllStandard, resolveModelRef } from "../../compile/handler/frozen-validator.mjs";
|
|
2
2
|
import { composeRouteHook } from "../../compile/handler/index.mjs";
|
|
3
3
|
import { captureArtifacts, compileToSource, replayStubbability } from "./source.mjs";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
|
-
import { existsSync, realpathSync } from "node:fs";
|
|
6
|
-
import { dirname, join, resolve } from "node:path";
|
|
7
|
-
import { pathToFileURL } from "node:url";
|
|
5
|
+
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
6
|
+
import { dirname, extname, join, resolve } from "node:path";
|
|
7
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
8
8
|
import { Worker } from "node:worker_threads";
|
|
9
9
|
|
|
10
10
|
//#region src/plugin/aot/core.ts
|
|
@@ -18,8 +18,31 @@ function findPackageRoot(from = process.cwd()) {
|
|
|
18
18
|
return dir;
|
|
19
19
|
}
|
|
20
20
|
const resolveEntry = (entry) => resolve(findPackageRoot(), entry);
|
|
21
|
+
/** @internal Resolve the package condition used to evaluate an AOT entry. */
|
|
22
|
+
const resolveEntryModuleKind = (entry) => {
|
|
23
|
+
const entryPath = resolveEntry(entry);
|
|
24
|
+
switch (extname(entryPath)) {
|
|
25
|
+
case ".cjs":
|
|
26
|
+
case ".cts": return "cjs";
|
|
27
|
+
case ".mjs":
|
|
28
|
+
case ".mts":
|
|
29
|
+
case ".ts":
|
|
30
|
+
case ".tsx": return "esm";
|
|
31
|
+
case ".js":
|
|
32
|
+
case ".jsx": {
|
|
33
|
+
const packagePath = join(findPackageRoot(dirname(entryPath)), "package.json");
|
|
34
|
+
if (!existsSync(packagePath)) return "cjs";
|
|
35
|
+
const pkg = JSON.parse(readFileSync(packagePath, "utf8"));
|
|
36
|
+
if (pkg.type === "module") return "esm";
|
|
37
|
+
if (pkg.type === void 0 || pkg.type === "commonjs") return "cjs";
|
|
38
|
+
throw new Error(`[elysia-aot] package.json has unsupported "type" ${JSON.stringify(pkg.type)} for JavaScript entry ${JSON.stringify(entryPath)}.`);
|
|
39
|
+
}
|
|
40
|
+
default: throw new Error(`[elysia-aot] entry ${JSON.stringify(entryPath)} has an ambiguous module condition. Use a .cjs/.cts CommonJS entry or a .mjs/.mts/.ts/.tsx ESM entry; .js/.jsx follows the nearest package.json "type".`);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
21
43
|
const NO_STUB = {
|
|
22
44
|
jit: false,
|
|
45
|
+
staticClone: false,
|
|
23
46
|
ws: false,
|
|
24
47
|
reconstruct: false,
|
|
25
48
|
cookie: false,
|
|
@@ -27,6 +50,8 @@ const NO_STUB = {
|
|
|
27
50
|
sucrose: false,
|
|
28
51
|
compat: false,
|
|
29
52
|
bridge: false,
|
|
53
|
+
typeboxValue: false,
|
|
54
|
+
exactMirror: false,
|
|
30
55
|
adapter: false,
|
|
31
56
|
isProduction: false
|
|
32
57
|
};
|
|
@@ -47,20 +72,23 @@ const NO_STUB = {
|
|
|
47
72
|
* is not active, so the bridge must stay wired the ordinary way. No compat
|
|
48
73
|
* stub, no reroute.
|
|
49
74
|
*/
|
|
50
|
-
function planFromReport(strip, report, hasWS, mayTrace, aliases, allBridgeFree, zeroCapture, adapterStub = false, productionStub = true) {
|
|
75
|
+
function planFromReport(strip, report, hasWS, mayTrace, aliases, allBridgeFree, zeroCapture, adapterStub = false, productionStub = true, wsCookie = false, exactMirror = false) {
|
|
51
76
|
const jit = report.jit;
|
|
52
77
|
if (strip === true && !jit) throw new Error(`[elysia-aot] strip: true requires every route to be covered by the AOT handler manifest, but handler JIT is still reachable (${report.reasons.join(", ") || "unknown"}). Use strip: 'auto' to skip stubbing when the app is not fully precompiled.`);
|
|
53
78
|
const mode = !jit ? "off" : allBridgeFree ? "sealed" : hasWS && zeroCapture ? "off" : "wired";
|
|
54
79
|
return {
|
|
55
80
|
plan: {
|
|
56
81
|
jit,
|
|
82
|
+
staticClone: jit && !aliases.has("scl"),
|
|
57
83
|
ws: !hasWS,
|
|
58
84
|
reconstruct: jit && !aliases.has("va") && !aliases.has("cc") && !aliases.has("tr"),
|
|
59
|
-
cookie: jit && !aliases.has("cc"),
|
|
85
|
+
cookie: jit && !aliases.has("cc") && !wsCookie,
|
|
60
86
|
trace: !aliases.has("tr") && (jit || !mayTrace),
|
|
61
87
|
sucrose: jit,
|
|
62
88
|
compat: mode !== "off",
|
|
63
89
|
bridge: mode === "wired",
|
|
90
|
+
typeboxValue: mode !== "sealed",
|
|
91
|
+
exactMirror: exactMirror && mode !== "sealed",
|
|
64
92
|
adapter: adapterStub,
|
|
65
93
|
isProduction: productionStub
|
|
66
94
|
},
|
|
@@ -71,71 +99,48 @@ function adapterConstantsSource(target) {
|
|
|
71
99
|
if (target === "bun") return "import { BunAdapter } from './bun/index'\nexport const defaultAdapter = BunAdapter\n";
|
|
72
100
|
return "import { WebStandardAdapter } from './web-standard/index'\nexport const defaultAdapter = WebStandardAdapter\n";
|
|
73
101
|
}
|
|
74
|
-
/** Filter matching elysia's own `adapter/constants` module (src + dist). */
|
|
75
102
|
const ADAPTER_CONSTANTS_FILTER = /[\\/]elysia[\\/](dist|src)[\\/]adapter[\\/]constants\.(m?js|ts)$/;
|
|
76
103
|
const ADAPTER_BUN_FILTER = /[\\/]elysia[\\/](dist|src)[\\/]adapter[\\/]bun[\\/]index\.(m?js|ts)$/;
|
|
77
104
|
const IS_PRODUCTION_FILTER = /[\\/]elysia[\\/](dist|src)[\\/]universal[\\/]is-production\.(m?js|ts)$/;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
* monorepos, linked installs). Used by esbuild as a broad pre-filter
|
|
83
|
-
*
|
|
84
|
-
* The caller must further check that the path is under the resolved elysia package root
|
|
85
|
-
* to avoid matching user code in a directory that happens to be named "elysia"
|
|
86
|
-
*
|
|
87
|
-
* @internal
|
|
88
|
-
*/
|
|
105
|
+
const TYPEBOX_TYPE_FILTER = /[\\/]elysia[\\/](dist|src)[\\/]type[\\/]typebox-type\.(m?js|ts)$/;
|
|
106
|
+
const TYPEBOX_SYSTEM_LITE_FILTER = /[\\/]elysia[\\/](dist|src)[\\/]type[\\/]typebox-system-lite\.(m?js|ts)$/;
|
|
107
|
+
const TYPEBOX_REQUIRE_FILTER = /[\\/]elysia[\\/](dist|src)[\\/]type[\\/]typebox-value-require\.(m?js|ts)$/;
|
|
108
|
+
const EXACT_MIRROR_REQUIRE_FILTER = /[\\/]elysia[\\/](dist|src)[\\/]type[\\/]validator[\\/]exact-mirror-require\.(m?js|ts)$/;
|
|
89
109
|
const ELYSIA_MODULE_FILTER = /[\\/]elysia[\\/](dist|src)[\\/].+\.(m?js|ts)x?$/;
|
|
90
|
-
|
|
91
|
-
* Build a predicate that returns `true` only for modules that are under the
|
|
92
|
-
* resolved elysia package root (i.e. actually elysia's own files).
|
|
93
|
-
*
|
|
94
|
-
* Anchoring to the real package root prevents user projects rooted in a
|
|
95
|
-
* directory named `elysia` (like this repo itself) from having their code
|
|
96
|
-
* rewritten.
|
|
97
|
-
*
|
|
98
|
-
* Pass the result to both the esbuild `filter` (convert to RegExp via
|
|
99
|
-
* `makeElysiaModuleFilterRegex`) and the Vite transform (`isElysiaModule`).
|
|
100
|
-
*/
|
|
101
|
-
function resolveElysiaRoot(from = process.cwd()) {
|
|
110
|
+
function resolveElysiaRoot(from) {
|
|
102
111
|
try {
|
|
103
112
|
return dirname(createRequire(join(from, "package.json")).resolve("elysia/package.json"));
|
|
104
113
|
} catch {
|
|
105
114
|
return from;
|
|
106
115
|
}
|
|
107
116
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
117
|
+
function resolveExactMirror(from) {
|
|
118
|
+
try {
|
|
119
|
+
createRequire(join(resolveElysiaRoot(from), "package.json")).resolve("exact-mirror");
|
|
120
|
+
return true;
|
|
121
|
+
} catch {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
112
125
|
function makeIsElysiaModule(elysiaRoot) {
|
|
113
126
|
const root = elysiaRoot.replace(/\\/g, "/");
|
|
114
127
|
return (path) => {
|
|
115
128
|
return path.replace(/\\/g, "/").startsWith(root + "/") && ELYSIA_MODULE_FILTER.test(path);
|
|
116
129
|
};
|
|
117
130
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
* so the `onLoad` pre-filter is as tight as possible. esbuild uses this as an
|
|
121
|
-
* initial path filter before calling the callback, so we still double-check
|
|
122
|
-
* with `makeIsElysiaModule` inside the callback.
|
|
123
|
-
*/
|
|
124
|
-
function makeElysiaModuleFilterRegex(elysiaRoot) {
|
|
125
|
-
const escaped = elysiaRoot.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
126
|
-
return new RegExp("^" + escaped + "[\\\\/](dist|src)[\\\\/].+\\.(m?js|ts)x?$");
|
|
127
|
-
}
|
|
128
|
-
function rewriteIsProductionCalls(code) {
|
|
129
|
-
return code.replace(/(?<![.?])\bisProduction\(\)/g, "true");
|
|
130
|
-
}
|
|
131
|
-
const bunAdapterStubSource = "const e=(t)=>{throw new Error(`[elysia-aot] Bun adapter was stripped for target 'web-standard' .listen() is unavailable; use the exported fetch handler or rebuild with a different target.`)}\nexport const BunAdapter={name:'bun',runtime:'bun',isWebStandard:true,parse:{},response:{},listen:e}\nexport function collectStaticRoutes(){}\n";
|
|
131
|
+
const rewriteIsProductionCalls = (code) => code.replace(/(?<![.?])\bisProduction\(\)/g, "true");
|
|
132
|
+
const bunAdapterStubSource = "const e=(t)=>{throw new Error(`[elysia-aot] Bun adapter was stripped for target 'web-standard' .listen() is unavailable; use the exported fetch handler or rebuild with a different target.`)}\nexport const BunAdapter={parse:{},response:{},listen:e}\nexport function collectStaticRoutes(){}\n";
|
|
132
133
|
const STUB_SOURCES = {
|
|
134
|
+
staticClone: [{
|
|
135
|
+
filter: /[\\/]elysia[\\/](dist|src)[\\/]compile[\\/]handler[\\/]static-clone-resolver\.(m?js|ts)$/,
|
|
136
|
+
source: `export const staticCloneResolver = undefined\n`
|
|
137
|
+
}],
|
|
133
138
|
jit: [{
|
|
134
139
|
filter: /[\\/]elysia[\\/](dist|src)[\\/]compile[\\/]handler[\\/]jit\.(m?js|ts)$/,
|
|
135
140
|
source: "const e=()=>{throw new Error(\"[elysia-aot] handler compiler JIT was stripped (strip mode) but a route needed runtime compilation. Rebuild with strip:false.\")}\nexport function compileHandlerJit(){return e()}\nexport function createInlineHandler(){return e()}\nexport function setCaptureHeaderShorthand(){}\n"
|
|
136
141
|
}, {
|
|
137
142
|
filter: /[\\/]elysia[\\/](dist|src)[\\/]compile[\\/]handler[\\/]descriptor\.(m?js|ts)$/,
|
|
138
|
-
source: "const e=()=>{throw new Error(\"[elysia-aot] handler compiler JIT was stripped (strip mode) but a route needed runtime compilation. Rebuild with strip:false.\")}\nexport function describeRoute(){return e()}\nexport const routeDescriptors=new WeakMap()\
|
|
143
|
+
source: "const e=()=>{throw new Error(\"[elysia-aot] handler compiler JIT was stripped (strip mode) but a route needed runtime compilation. Rebuild with strip:false.\")}\nexport function describeRoute(){return e()}\nexport const routeDescriptors=new WeakMap()\n"
|
|
139
144
|
}],
|
|
140
145
|
ws: [{
|
|
141
146
|
filter: /[\\/]elysia[\\/](dist|src)[\\/]ws[\\/]route\.(m?js|ts)$/,
|
|
@@ -145,13 +150,20 @@ const STUB_SOURCES = {
|
|
|
145
150
|
filter: /[\\/]elysia[\\/](dist|src)[\\/]compile[\\/]handler[\\/]reconstruct\.(m?js|ts)$/,
|
|
146
151
|
source: "const e=()=>{throw new Error(\"[elysia-aot] handler reconstruction was stripped (strip mode) but a route needed it. Rebuild with strip:false.\")}\nexport class Reconstrct {\n static validator(){return e()}\n static cookie(){return e()}\n static trace(){return e()}\n}\n"
|
|
147
152
|
}],
|
|
148
|
-
cookie: [
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
cookie: [
|
|
154
|
+
{
|
|
155
|
+
filter: /[\\/]elysia[\\/](dist|src)[\\/]cookie[\\/]crypto\.(m?js|ts)$/,
|
|
156
|
+
source: `export function resolvePendingCookie(){throw new Error("[elysia-aot] cookie support was stripped (strip mode) but a signed cookie was read. Rebuild with strip:false.")}\n`
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
filter: /[\\/]elysia[\\/](dist|src)[\\/]cookie[\\/]utils\.(m?js|ts)$/,
|
|
160
|
+
source: "const e=()=>{throw new Error(\"[elysia-aot] cookie support was stripped (strip mode) but a route used cookies. Rebuild with strip:false.\")}\nexport const hasSyncHmac=false\nexport function parseCookieRaw(){return e()}\nexport function parseCookieRawSync(){return e()}\nexport function parseCookieRawSigned(){return e()}\nexport function parseCookieRawLazy(){return e()}\nexport function parseCookieRawDeferred(){return e()}\nexport function buildCookieJar(){return e()}\nexport function signCookieValues(){return e()}\n"
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
filter: /[\\/]elysia[\\/](dist|src)[\\/]cookie[\\/]config\.(m?js|ts)$/,
|
|
164
|
+
source: "const e=()=>{throw new Error(\"[elysia-aot] cookie support was stripped (strip mode) but a route used cookies. Rebuild with strip:false.\")}\nexport function compileCookieConfig(){return e()}\n"
|
|
165
|
+
}
|
|
166
|
+
],
|
|
155
167
|
trace: [{
|
|
156
168
|
filter: /[\\/]elysia[\\/](dist|src)[\\/]trace\.(m?js|ts)$/,
|
|
157
169
|
source: "const e=()=>{throw new Error(\"[elysia-aot] trace support was stripped (strip mode) but a route used trace. Rebuild with strip:false.\")}\nexport function createTracer(){return e()}\nexport function unionTracePhases(){return new Set()}\n"
|
|
@@ -159,9 +171,6 @@ const STUB_SOURCES = {
|
|
|
159
171
|
sucrose: [{
|
|
160
172
|
filter: /[\\/]elysia[\\/](dist|src)[\\/]memory\.(m?js|ts)$/,
|
|
161
173
|
source: "import { clearContextCache } from './context'\nimport { Validator } from './validator'\nexport function flushMemory() {\n clearContextCache()\n Validator.clear()\n}\n"
|
|
162
|
-
}, {
|
|
163
|
-
filter: /[\\/]elysia[\\/](dist|src)[\\/]compile[\\/]analysis-cache\.(m?js|ts)$/,
|
|
164
|
-
source: "import { clearHandlerAnalysisCaches } from './handler/index'\nimport { clearFlattenChainMemo } from '../utils'\nexport function clearAuthoringAnalysisCaches(root) {\n clearHandlerAnalysisCaches(root)\n clearFlattenChainMemo(root)\n}\n"
|
|
165
174
|
}],
|
|
166
175
|
compat: [{
|
|
167
176
|
filter: /[\\/]elysia[\\/](dist|src)[\\/]type[\\/]compat\.(m?js|ts)$/,
|
|
@@ -170,11 +179,23 @@ const STUB_SOURCES = {
|
|
|
170
179
|
bridge: [{
|
|
171
180
|
filter: /[\\/]elysia[\\/](dist|src)[\\/]type[\\/]bridge\.(m?js|ts)$/,
|
|
172
181
|
source: `export * from './bridge-live'\n`
|
|
182
|
+
}],
|
|
183
|
+
typeboxValue: [{
|
|
184
|
+
filter: /[\\/]elysia[\\/](dist|src)[\\/]type[\\/]typebox-value\.(m?js|ts)$/,
|
|
185
|
+
source: `export * from './typebox-value-live'\n`
|
|
186
|
+
}],
|
|
187
|
+
exactMirror: [{
|
|
188
|
+
filter: /[\\/]elysia[\\/](dist|src)[\\/]type[\\/]validator[\\/]exact-mirror\.(m?js|ts)$/,
|
|
189
|
+
source: `export * from './exact-mirror-live'\n`
|
|
173
190
|
}]
|
|
174
191
|
};
|
|
175
192
|
const alignStubExtensions = (stubSource, targetPath) => {
|
|
176
193
|
const ext = targetPath.slice(targetPath.lastIndexOf("."));
|
|
177
194
|
if (ext !== ".mjs" && ext !== ".js" && ext !== ".cjs") return stubSource;
|
|
195
|
+
if (ext !== ".mjs") {
|
|
196
|
+
const reexport = /^export \* from '(\.[^']+)'\n$/.exec(stubSource);
|
|
197
|
+
if (reexport) return `let m;const t=()=>m??=require('${reexport[1]}${ext}'),d=(o,k)=>Reflect.getOwnPropertyDescriptor(o,k)\nmodule.exports=new Proxy({},{get:(_,k)=>t()[k],has:(_,k)=>k in t(),ownKeys:()=>Reflect.ownKeys(t()),getOwnPropertyDescriptor:(o,k)=>{let x=d(o,k);if(x)return x;x=d(t(),k);if(x)x.configurable=true;return x},preventExtensions:o=>{for(const k of Reflect.ownKeys(t()))Object.defineProperty(o,k,d(t(),k));return Reflect.preventExtensions(o)}})\n`;
|
|
198
|
+
}
|
|
178
199
|
return stubSource.replace(/(from ')(\.[^']+)(')/g, (_m, open, spec, close) => open + (spec === "./validator" ? spec + "/index" : spec) + ext + close);
|
|
179
200
|
};
|
|
180
201
|
const OVERRIDE_MAP = {
|
|
@@ -202,6 +223,10 @@ const OVERRIDE_MAP = {
|
|
|
202
223
|
leaf: "boolean-string",
|
|
203
224
|
export: "BooleanString"
|
|
204
225
|
},
|
|
226
|
+
Composite: {
|
|
227
|
+
leaf: "keep-config",
|
|
228
|
+
export: "CompositeType"
|
|
229
|
+
},
|
|
205
230
|
Cookie: {
|
|
206
231
|
leaf: "cookie",
|
|
207
232
|
export: "Cookie"
|
|
@@ -210,6 +235,10 @@ const OVERRIDE_MAP = {
|
|
|
210
235
|
leaf: "date",
|
|
211
236
|
export: "DateType"
|
|
212
237
|
},
|
|
238
|
+
Evaluate: {
|
|
239
|
+
leaf: "keep-config",
|
|
240
|
+
export: "EvaluateType"
|
|
241
|
+
},
|
|
213
242
|
File: {
|
|
214
243
|
leaf: "file",
|
|
215
244
|
export: "File"
|
|
@@ -230,10 +259,18 @@ const OVERRIDE_MAP = {
|
|
|
230
259
|
leaf: "integer-string",
|
|
231
260
|
export: "IntegerString"
|
|
232
261
|
},
|
|
262
|
+
Interface: {
|
|
263
|
+
leaf: "keep-config",
|
|
264
|
+
export: "InterfaceType"
|
|
265
|
+
},
|
|
233
266
|
Intersect: {
|
|
234
267
|
leaf: "intersect",
|
|
235
268
|
export: "Intersect"
|
|
236
269
|
},
|
|
270
|
+
Mapped: {
|
|
271
|
+
leaf: "keep-config",
|
|
272
|
+
export: "MappedType"
|
|
273
|
+
},
|
|
237
274
|
MaybeEmpty: {
|
|
238
275
|
leaf: "maybe-empty",
|
|
239
276
|
export: "MaybeEmpty"
|
|
@@ -266,10 +303,34 @@ const OVERRIDE_MAP = {
|
|
|
266
303
|
leaf: "object-string",
|
|
267
304
|
export: "ObjectString"
|
|
268
305
|
},
|
|
306
|
+
Omit: {
|
|
307
|
+
leaf: "keep-config",
|
|
308
|
+
export: "OmitType"
|
|
309
|
+
},
|
|
269
310
|
Optional: {
|
|
270
311
|
leaf: "optional",
|
|
271
312
|
export: "Optional"
|
|
272
313
|
},
|
|
314
|
+
Partial: {
|
|
315
|
+
leaf: "keep-config",
|
|
316
|
+
export: "PartialType"
|
|
317
|
+
},
|
|
318
|
+
Pick: {
|
|
319
|
+
leaf: "keep-config",
|
|
320
|
+
export: "PickType"
|
|
321
|
+
},
|
|
322
|
+
Problem: {
|
|
323
|
+
leaf: "problem",
|
|
324
|
+
export: "Problem"
|
|
325
|
+
},
|
|
326
|
+
ReadonlyObject: {
|
|
327
|
+
leaf: "keep-config",
|
|
328
|
+
export: "ReadonlyObjectType"
|
|
329
|
+
},
|
|
330
|
+
Required: {
|
|
331
|
+
leaf: "keep-config",
|
|
332
|
+
export: "RequiredType"
|
|
333
|
+
},
|
|
273
334
|
String: {
|
|
274
335
|
leaf: "string",
|
|
275
336
|
export: "StringType"
|
|
@@ -288,17 +349,20 @@ const OVERRIDE_MAP = {
|
|
|
288
349
|
}
|
|
289
350
|
};
|
|
290
351
|
const requireFromHere = createRequire(import.meta.url);
|
|
291
|
-
const
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
352
|
+
const moduleMeta = import.meta;
|
|
353
|
+
const loadedModuleCondition = import.meta.url.endsWith(".js") ? "cjs" : "esm";
|
|
354
|
+
const resolveSpecifier = (specifier, moduleCondition) => {
|
|
355
|
+
if (moduleCondition === "cjs") return requireFromHere.resolve(specifier);
|
|
356
|
+
if (moduleMeta.resolve) {
|
|
357
|
+
const url = moduleMeta.resolve(specifier);
|
|
358
|
+
return url.startsWith("file://") ? fileURLToPath(url) : url;
|
|
296
359
|
}
|
|
360
|
+
if (moduleCondition === "esm") throw new Error("[elysia-aot] CommonJS-loaded build plugin cannot resolve the ESM package condition. Load the build plugin through import for an ESM entry.");
|
|
297
361
|
return requireFromHere.resolve(specifier);
|
|
298
362
|
};
|
|
299
|
-
async function generateVirtualType(
|
|
300
|
-
const typePath = resolveSpecifier(
|
|
301
|
-
const typeboxPath = resolveSpecifier("typebox/type");
|
|
363
|
+
async function generateVirtualType(moduleCondition) {
|
|
364
|
+
const typePath = resolveSpecifier("elysia/type", moduleCondition);
|
|
365
|
+
const typeboxPath = resolveSpecifier("typebox/type", moduleCondition);
|
|
302
366
|
const ext = typePath.slice(typePath.lastIndexOf("."));
|
|
303
367
|
const leafDir = join(dirname(typePath), "elysia");
|
|
304
368
|
const typebox = await import(pathToFileURL(typeboxPath).href);
|
|
@@ -314,13 +378,6 @@ async function generateVirtualType(typeSpecifier = "elysia/type") {
|
|
|
314
378
|
return source;
|
|
315
379
|
}
|
|
316
380
|
const _importedEntries = /* @__PURE__ */ new Set();
|
|
317
|
-
let activeGenerationWorkers = 0;
|
|
318
|
-
let lastGenerationWorkerExit;
|
|
319
|
-
/** @internal Test diagnostic for deterministic worker cleanup. */
|
|
320
|
-
const getAotWorkerDiagnostics = () => ({
|
|
321
|
-
activeWorkers: activeGenerationWorkers,
|
|
322
|
-
lastExit: lastGenerationWorkerExit
|
|
323
|
-
});
|
|
324
381
|
/**
|
|
325
382
|
* Extension mirroring the running module's own build output, so a sibling
|
|
326
383
|
* source file can be resolved from `import.meta.url` in `.mjs`/`.js`/`.ts`
|
|
@@ -334,16 +391,15 @@ const workerUrl = () => {
|
|
|
334
391
|
return new URL("./worker" + siblingModuleExt(moduleUrl), moduleUrl);
|
|
335
392
|
};
|
|
336
393
|
/** @internal Re-evaluate an entry in a disposable worker for watch rebuilds. */
|
|
337
|
-
async function generateCompiledArtifactsIsolated(file, options) {
|
|
394
|
+
async function generateCompiledArtifactsIsolated(file, options, moduleCondition = resolveEntryModuleKind(file)) {
|
|
338
395
|
const entry = resolveEntry(file);
|
|
339
396
|
console.warn("[elysia-aot] re-evaluating \"" + entry + "\" in an isolated worker for rebuild. Top-level side effects run only inside the worker.");
|
|
340
397
|
const worker = new Worker(workerUrl(), { workerData: {
|
|
341
398
|
file: entry,
|
|
342
|
-
options
|
|
399
|
+
options,
|
|
400
|
+
moduleCondition
|
|
343
401
|
} });
|
|
344
|
-
activeGenerationWorkers++;
|
|
345
402
|
const exit = new Promise((resolve) => worker.once("exit", resolve));
|
|
346
|
-
lastGenerationWorkerExit = exit;
|
|
347
403
|
try {
|
|
348
404
|
return await new Promise((resolve, reject) => {
|
|
349
405
|
let received = false;
|
|
@@ -365,19 +421,34 @@ async function generateCompiledArtifactsIsolated(file, options) {
|
|
|
365
421
|
await worker.terminate();
|
|
366
422
|
} finally {
|
|
367
423
|
await exit;
|
|
368
|
-
activeGenerationWorkers--;
|
|
369
424
|
}
|
|
370
425
|
}
|
|
371
426
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
const
|
|
377
|
-
if (
|
|
378
|
-
|
|
427
|
+
const validatorSlotKey = ({ method, path, slot }) => `${method}\0${path}\0${slot}`;
|
|
428
|
+
/** @internal Exact logical-slot gate used by AOT mode selection. */
|
|
429
|
+
function validatorSlotSetsMatch(expected, captured) {
|
|
430
|
+
const expectedKeys = new Set(expected.map(validatorSlotKey));
|
|
431
|
+
const capturedKeys = new Set(captured.map(validatorSlotKey));
|
|
432
|
+
if (expectedKeys.size !== capturedKeys.size) return false;
|
|
433
|
+
for (const key of expectedKeys) if (!capturedKeys.has(key)) return false;
|
|
434
|
+
return true;
|
|
379
435
|
}
|
|
380
|
-
|
|
436
|
+
/**
|
|
437
|
+
* The manifest is one flat `method -> path` table with no per-app namespace,
|
|
438
|
+
* bound to whichever app builds a router first, so a mounted sub-app (a second
|
|
439
|
+
* Elysia building on its own schedule) is not representable
|
|
440
|
+
*
|
|
441
|
+
* refuse at build time rather than ship a coin flip
|
|
442
|
+
*/
|
|
443
|
+
const assertNoMount = (app, entry) => {
|
|
444
|
+
const routes = app["~routes"];
|
|
445
|
+
const mounted = [];
|
|
446
|
+
for (const route of routes) if (route[2]?.["~mount"] && !mounted.includes(route[1])) mounted.push(route[1]);
|
|
447
|
+
if (!mounted.length) return;
|
|
448
|
+
throw new Error(`[elysia-aot] "${entry}" mounts a sub-app (${mounted.join(", ")}). AOT cannot compile a mounted sub-app. Compose with .use() instead of .mount(), or disable AOT plugin`);
|
|
449
|
+
};
|
|
450
|
+
async function generateCompiledArtifacts(file, options, moduleCondition = resolveEntryModuleKind(file)) {
|
|
451
|
+
if (moduleCondition !== loadedModuleCondition) throw new Error(`[elysia-aot] entry uses the ${moduleCondition === "cjs" ? "CommonJS \"require\"" : "ESM \"import\""} package condition, but the AOT build plugin was loaded through ${loadedModuleCondition === "cjs" ? "CommonJS \"require\"" : "ESM \"import\""}; entry: ${JSON.stringify(resolveEntry(file))}. Load the plugin through ${moduleCondition === "cjs" ? "require()" : "import"} so capture and generated registration share one Elysia module instance.`);
|
|
381
452
|
const previousAotBuild = process.env.ELYSIA_AOT_BUILD;
|
|
382
453
|
process.env.ELYSIA_AOT_BUILD = "1";
|
|
383
454
|
const previousAotVerbose = process.env.ELYSIA_AOT_VERBOSE;
|
|
@@ -386,14 +457,15 @@ async function generateCompiledArtifacts(file, options) {
|
|
|
386
457
|
try {
|
|
387
458
|
const entry = resolveEntry(file);
|
|
388
459
|
const entryReal = realPath(entry);
|
|
389
|
-
if (_importedEntries.has(entryReal)) return generateCompiledArtifactsIsolated(file, options);
|
|
460
|
+
if (_importedEntries.has(entryReal)) return generateCompiledArtifactsIsolated(file, options, moduleCondition);
|
|
390
461
|
_importedEntries.add(entryReal);
|
|
391
462
|
const mod = await import(entry);
|
|
392
463
|
const app = mod.app ?? mod.default;
|
|
393
464
|
if (!app || typeof app.compile !== "function") throw new Error(`[elysia-aot] "${entry}" must export an Elysia app`);
|
|
394
465
|
const typedApp = app;
|
|
466
|
+
assertNoMount(typedApp, entry);
|
|
395
467
|
const sourceOptions = {
|
|
396
|
-
|
|
468
|
+
moduleCondition,
|
|
397
469
|
registerFrom: options?.registerFrom,
|
|
398
470
|
reconstructFrom: options?.reconstructFrom,
|
|
399
471
|
lazy: options?.lazy,
|
|
@@ -402,10 +474,13 @@ async function generateCompiledArtifacts(file, options) {
|
|
|
402
474
|
const strip = options?.strip ?? "auto";
|
|
403
475
|
const adapterStub = options?.target === "bun" ? "bun" : options?.target === "node" || options?.target === "workerd" ? "web-standard" : false;
|
|
404
476
|
const productionStub = options?.production !== false;
|
|
477
|
+
const exactMirror = resolveExactMirror(entry);
|
|
405
478
|
if (strip === false) return {
|
|
406
479
|
source: await compileToSource(typedApp, sourceOptions),
|
|
407
480
|
stub: {
|
|
408
481
|
...NO_STUB,
|
|
482
|
+
typeboxValue: true,
|
|
483
|
+
exactMirror,
|
|
409
484
|
adapter: adapterStub,
|
|
410
485
|
isProduction: productionStub
|
|
411
486
|
},
|
|
@@ -415,32 +490,51 @@ async function generateCompiledArtifacts(file, options) {
|
|
|
415
490
|
const report = replayStubbability(typedApp, artifacts.handlers);
|
|
416
491
|
const aliases = /* @__PURE__ */ new Set();
|
|
417
492
|
for (const handler of artifacts.handlers) if (handler.alias) for (const name of handler.alias.split(",")) aliases.add(name);
|
|
418
|
-
const
|
|
419
|
-
const
|
|
493
|
+
const history = typedApp["~routes"];
|
|
494
|
+
const hasWS = !!typedApp["~hasWS"] || history.some((route) => route[0] === "WS");
|
|
420
495
|
const mayTrace = !!typedApp["~hasTrace"] || history.some((route) => (route?.[4])?.trace?.length || route?.[2]?.["~mount"]);
|
|
421
|
-
|
|
496
|
+
const expectedSlots = [];
|
|
497
|
+
const declaredTypeBoxSlots = /* @__PURE__ */ new Set();
|
|
422
498
|
let routesForbidSeal = false;
|
|
499
|
+
let wsCookie = false;
|
|
423
500
|
for (const route of history) {
|
|
501
|
+
const method = route[0];
|
|
502
|
+
const path = route[1];
|
|
503
|
+
const expectTypeBoxSlot = (slot) => {
|
|
504
|
+
const identity = {
|
|
505
|
+
method,
|
|
506
|
+
path,
|
|
507
|
+
slot
|
|
508
|
+
};
|
|
509
|
+
const key = validatorSlotKey(identity);
|
|
510
|
+
if (declaredTypeBoxSlots.has(key)) routesForbidSeal = true;
|
|
511
|
+
else {
|
|
512
|
+
declaredTypeBoxSlots.add(key);
|
|
513
|
+
expectedSlots.push(identity);
|
|
514
|
+
}
|
|
515
|
+
};
|
|
424
516
|
const [, , , instance, hook, appHook, inheritedChain, macroScope] = route;
|
|
425
517
|
const hooks = composeRouteHook(instance, hook, appHook, inheritedChain, typedApp, macroScope);
|
|
518
|
+
if (method === "WS" && (hook?.cookie !== void 0 || hooks?.cookie !== void 0)) wsCookie = true;
|
|
426
519
|
if (!hooks) continue;
|
|
427
520
|
let routeHasTypeBoxDirectSlot = false;
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
]) {
|
|
435
|
-
const value = hooks[slot];
|
|
436
|
-
if (value === void 0) continue;
|
|
437
|
-
if (isStandardSchema(value)) continue;
|
|
521
|
+
const classify = (schema, slot) => {
|
|
522
|
+
if (schema === void 0) {
|
|
523
|
+
routesForbidSeal = true;
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
if (isStandardSchema(schema)) return;
|
|
438
527
|
routeHasTypeBoxDirectSlot = true;
|
|
439
|
-
|
|
528
|
+
expectTypeBoxSlot(slot);
|
|
529
|
+
};
|
|
530
|
+
for (const slot of REQUEST_SLOTS) {
|
|
531
|
+
const value = hooks[slot];
|
|
532
|
+
if (value !== void 0) classify(resolveModelRef(value, typedApp), slot);
|
|
440
533
|
}
|
|
441
|
-
if (hooks.response !== void 0
|
|
442
|
-
|
|
443
|
-
|
|
534
|
+
if (hooks.response !== void 0) {
|
|
535
|
+
const response = resolveModelRef(hooks.response, typedApp);
|
|
536
|
+
if (isResponseMap(response)) for (const status in response) classify(resolveModelRef(response[status], typedApp), `response:${status}`);
|
|
537
|
+
else classify(response, "response:200");
|
|
444
538
|
}
|
|
445
539
|
const mergeSchemas = hooks.schemas;
|
|
446
540
|
if (Array.isArray(mergeSchemas) && mergeSchemas.length > 0) {
|
|
@@ -448,13 +542,13 @@ async function generateCompiledArtifacts(file, options) {
|
|
|
448
542
|
}
|
|
449
543
|
}
|
|
450
544
|
if (typedApp["~config"]?.normalize === "typebox") routesForbidSeal = true;
|
|
451
|
-
const
|
|
452
|
-
const { plan: stub, mode } = planFromReport(strip, report, hasWS, mayTrace, aliases, (artifacts.handlers.
|
|
545
|
+
const validatorSlotsMatch = validatorSlotSetsMatch(expectedSlots, artifacts.validators);
|
|
546
|
+
const { plan: stub, mode } = planFromReport(strip, report, hasWS, mayTrace, aliases, (artifacts.handlers.some((h) => h.code) || artifacts.validators.length > 0) && !routesForbidSeal && validatorSlotsMatch && artifacts.validators.every((v) => v.bridgeFree === true), !artifacts.handlers.some((h) => h.code) && artifacts.validators.length === 0, adapterStub, productionStub, wsCookie, exactMirror);
|
|
453
547
|
if (options?.target === "workerd") {
|
|
454
548
|
if (!report.jit) throw new Error(`[elysia-aot] target 'workerd' but handler JIT is still reachable (${report.reasons.join(", ") || "unknown"}). Every route must be captured into the AOT manifest.`);
|
|
455
|
-
if (
|
|
549
|
+
if (!validatorSlotsMatch) console.warn("[elysia-aot] target 'workerd': captured validator slots do not exactly match declared slots; unfrozen slots compile at runtime and will fail on workerd.");
|
|
456
550
|
}
|
|
457
|
-
const virtualType = mode === "off" ? void 0 : await generateVirtualType(
|
|
551
|
+
const virtualType = mode === "off" ? void 0 : await generateVirtualType(moduleCondition);
|
|
458
552
|
return {
|
|
459
553
|
source: artifacts.source,
|
|
460
554
|
stub,
|
|
@@ -478,4 +572,4 @@ const realPath = (path) => {
|
|
|
478
572
|
};
|
|
479
573
|
|
|
480
574
|
//#endregion
|
|
481
|
-
export { ADAPTER_BUN_FILTER, ADAPTER_CONSTANTS_FILTER, ELYSIA_MODULE_FILTER, IS_PRODUCTION_FILTER, NO_STUB, OVERRIDE_MAP, SOURCE_REGEX, STUB_SOURCES, adapterConstantsSource, alignStubExtensions, bunAdapterStubSource, generateCompiledArtifacts, generateCompiledArtifactsIsolated, generateVirtualType,
|
|
575
|
+
export { ADAPTER_BUN_FILTER, ADAPTER_CONSTANTS_FILTER, ELYSIA_MODULE_FILTER, EXACT_MIRROR_REQUIRE_FILTER, IS_PRODUCTION_FILTER, NO_STUB, OVERRIDE_MAP, SOURCE_REGEX, STUB_SOURCES, TYPEBOX_REQUIRE_FILTER, TYPEBOX_SYSTEM_LITE_FILTER, TYPEBOX_TYPE_FILTER, adapterConstantsSource, alignStubExtensions, bunAdapterStubSource, generateCompiledArtifacts, generateCompiledArtifactsIsolated, generateVirtualType, makeIsElysiaModule, planFromReport, realPath, resolveElysiaRoot, resolveEntry, resolveEntryModuleKind, resolveExactMirror, rewriteIsProductionCalls, siblingModuleExt, validatorSlotSetsMatch };
|
|
@@ -28,7 +28,11 @@ let node_fs_promises = require("node:fs/promises");
|
|
|
28
28
|
const aot = (entry, options) => ({
|
|
29
29
|
name: "elysia-aot",
|
|
30
30
|
async setup(build) {
|
|
31
|
-
const
|
|
31
|
+
const entryPath = require_plugin_aot_core.resolveEntry(entry);
|
|
32
|
+
const moduleCondition = require_plugin_aot_core.resolveEntryModuleKind(entryPath);
|
|
33
|
+
if (build.initialOptions?.conditions?.includes("types")) throw new Error("[elysia-aot] esbuild conditions includes 'types'; this selects declaration files as runtime inputs. Remove the conflicting condition.");
|
|
34
|
+
if (moduleCondition === "cjs" && build.initialOptions?.conditions?.includes("import")) throw new Error("[elysia-aot] esbuild conditions includes 'import' for a CommonJS entry; this would load two Elysia module instances. Remove the conflicting condition.");
|
|
35
|
+
const hooks = require_plugin_aot_hooks.createAotPluginHooks(entry, options, moduleCondition);
|
|
32
36
|
let initial = true;
|
|
33
37
|
build.onStart(async () => {
|
|
34
38
|
if (initial) {
|
|
@@ -37,10 +41,9 @@ const aot = (entry, options) => ({
|
|
|
37
41
|
}
|
|
38
42
|
await hooks.buildStart();
|
|
39
43
|
});
|
|
40
|
-
await require_plugin_aot_hooks.setupAotOnLoad(build, hooks,
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
});
|
|
44
|
+
await require_plugin_aot_hooks.setupAotOnLoad(build, hooks, (path) => (0, node_fs_promises.readFile)(path, "utf8"), (0, node_path.dirname)(entryPath));
|
|
45
|
+
const allowedKinds = moduleCondition === "cjs" ? new Set(["require-call", "require-resolve"]) : new Set(["import-statement", "dynamic-import"]);
|
|
46
|
+
build.onResolve({ filter: /^elysia(?:\/.*)?$/ }, (args) => allowedKinds.has(args.kind) ? void 0 : { errors: [{ text: `[elysia-aot] ${args.path} uses esbuild edge kind ${JSON.stringify(args.kind)}, which conflicts with the ${JSON.stringify(moduleCondition)} entry module condition. Use one consistent import/require condition for Elysia.` }] });
|
|
44
47
|
}
|
|
45
48
|
});
|
|
46
49
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { resolveEntry } from "./core.mjs";
|
|
1
|
+
import { resolveEntry, resolveEntryModuleKind } from "./core.mjs";
|
|
2
2
|
import { createAotPluginHooks, setupAotOnLoad } from "./hooks.mjs";
|
|
3
3
|
import { dirname } from "node:path";
|
|
4
4
|
import { readFile } from "node:fs/promises";
|
|
@@ -26,7 +26,11 @@ import { readFile } from "node:fs/promises";
|
|
|
26
26
|
const aot = (entry, options) => ({
|
|
27
27
|
name: "elysia-aot",
|
|
28
28
|
async setup(build) {
|
|
29
|
-
const
|
|
29
|
+
const entryPath = resolveEntry(entry);
|
|
30
|
+
const moduleCondition = resolveEntryModuleKind(entryPath);
|
|
31
|
+
if (build.initialOptions?.conditions?.includes("types")) throw new Error("[elysia-aot] esbuild conditions includes 'types'; this selects declaration files as runtime inputs. Remove the conflicting condition.");
|
|
32
|
+
if (moduleCondition === "cjs" && build.initialOptions?.conditions?.includes("import")) throw new Error("[elysia-aot] esbuild conditions includes 'import' for a CommonJS entry; this would load two Elysia module instances. Remove the conflicting condition.");
|
|
33
|
+
const hooks = createAotPluginHooks(entry, options, moduleCondition);
|
|
30
34
|
let initial = true;
|
|
31
35
|
build.onStart(async () => {
|
|
32
36
|
if (initial) {
|
|
@@ -35,10 +39,9 @@ const aot = (entry, options) => ({
|
|
|
35
39
|
}
|
|
36
40
|
await hooks.buildStart();
|
|
37
41
|
});
|
|
38
|
-
await setupAotOnLoad(build, hooks,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
});
|
|
42
|
+
await setupAotOnLoad(build, hooks, (path) => readFile(path, "utf8"), dirname(entryPath));
|
|
43
|
+
const allowedKinds = moduleCondition === "cjs" ? new Set(["require-call", "require-resolve"]) : new Set(["import-statement", "dynamic-import"]);
|
|
44
|
+
build.onResolve({ filter: /^elysia(?:\/.*)?$/ }, (args) => allowedKinds.has(args.kind) ? void 0 : { errors: [{ text: `[elysia-aot] ${args.path} uses esbuild edge kind ${JSON.stringify(args.kind)}, which conflicts with the ${JSON.stringify(moduleCondition)} entry module condition. Use one consistent import/require condition for Elysia.` }] });
|
|
42
45
|
}
|
|
43
46
|
});
|
|
44
47
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AotModuleCondition } from "./source.js";
|
|
1
2
|
import { ElysiaAotOptions } from "./core.js";
|
|
2
3
|
|
|
3
4
|
//#region src/plugin/aot/hooks.d.ts
|
|
@@ -6,23 +7,11 @@ interface AotPluginHooks {
|
|
|
6
7
|
buildEnd(): void;
|
|
7
8
|
resolveId(id: string): string | undefined;
|
|
8
9
|
load(id: string): string | undefined;
|
|
9
|
-
transform(code: string, id: string): string | undefined
|
|
10
|
+
transform(code: string, id: string): string | undefined;
|
|
10
11
|
isTransformCandidate(id: string): boolean;
|
|
11
12
|
}
|
|
12
|
-
declare const createAotPluginHooks: (entry: string, options?: ElysiaAotOptions) => AotPluginHooks;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
readText: (path: string) => Promise<string>;
|
|
16
|
-
/**
|
|
17
|
-
* resolveDir for the manifest/virtual-type module loads.
|
|
18
|
-
* esbuild needs `dirname(entryPath)` so relative imports in the manifest
|
|
19
|
-
* resolve correctly; Bun does not use it (pass undefined for Bun).
|
|
20
|
-
*/
|
|
21
|
-
resolveDir?: string;
|
|
22
|
-
}
|
|
23
|
-
declare function setupAotOnLoad(build: any, hooks: AotPluginHooks, {
|
|
24
|
-
readText,
|
|
25
|
-
resolveDir
|
|
26
|
-
}: AotOnLoadAdapterOptions): Promise<void>;
|
|
13
|
+
declare const createAotPluginHooks: (entry: string, options?: ElysiaAotOptions, moduleCondition?: AotModuleCondition) => AotPluginHooks;
|
|
14
|
+
declare const createTypeboxWiringHooks: () => AotPluginHooks;
|
|
15
|
+
declare function setupAotOnLoad(build: any, hooks: AotPluginHooks, readText: (path: string) => Promise<string>, resolveDir?: string): Promise<void>;
|
|
27
16
|
//#endregion
|
|
28
|
-
export {
|
|
17
|
+
export { AotPluginHooks, createAotPluginHooks, createTypeboxWiringHooks, setupAotOnLoad };
|