@supacloud/compiler 0.38.2 → 0.39.0
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/README.md +8 -0
- package/dist/cli.js +204 -149
- package/dist/client-schema-boundaries.d.ts +3 -0
- package/dist/index.js +190 -135
- package/dist/migration-elysia-version.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1432,9 +1432,9 @@ function renderApplication(graph, options) {
|
|
|
1432
1432
|
"}",
|
|
1433
1433
|
"",
|
|
1434
1434
|
"export async function initializeApplication(services: Record<string, unknown>): Promise<void> {",
|
|
1435
|
-
' const initializers = [services
|
|
1435
|
+
' const initializers = [services["environmentInitializer"] ?? services["supacloud.environment-initializer"], services["appInitializer"] ?? services["supacloud.app-initializer"]];',
|
|
1436
1436
|
" for (const group of initializers) {",
|
|
1437
|
-
" if (
|
|
1437
|
+
" if (isUnknownArray(group)) {",
|
|
1438
1438
|
" for (const init of group) {",
|
|
1439
1439
|
" if (isFunction(init)) await init();",
|
|
1440
1440
|
" }",
|
|
@@ -1445,21 +1445,21 @@ function renderApplication(graph, options) {
|
|
|
1445
1445
|
"}",
|
|
1446
1446
|
"",
|
|
1447
1447
|
"export async function destroyApplication(services: Record<string, unknown>): Promise<void> {",
|
|
1448
|
-
' const destroyRef = (Object.prototype.propertyIsEnumerable.call(services, "destroyRef") ? services
|
|
1448
|
+
' const destroyRef = (Object.prototype.propertyIsEnumerable.call(services, "destroyRef") ? services["destroyRef"] : undefined)',
|
|
1449
1449
|
' ?? (Object.prototype.propertyIsEnumerable.call(services, "supacloud.destroy-ref") ? services["supacloud.destroy-ref"] : undefined);',
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1450
|
+
' if (isRecord(destroyRef) && isFunction(destroyRef["destroy"])) {',
|
|
1451
|
+
' await destroyRef["destroy"]();',
|
|
1452
|
+
' } else if (isRecord(destroyRef) && isUnknownArray(destroyRef["_teardowns"])) {',
|
|
1453
|
+
' for (const teardown of [...destroyRef["_teardowns"]].reverse()) {',
|
|
1454
1454
|
" if (isFunction(teardown)) await teardown();",
|
|
1455
1455
|
" }",
|
|
1456
1456
|
" }",
|
|
1457
1457
|
" const instances = Object.values(services);",
|
|
1458
1458
|
" for (const inst of instances.reverse()) {",
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1459
|
+
' if (isRecord(inst) && isFunction(inst["onDestroy"])) {',
|
|
1460
|
+
' await inst["onDestroy"]();',
|
|
1461
|
+
' } else if (isRecord(inst) && isFunction(inst["ngOnDestroy"])) {',
|
|
1462
|
+
' await inst["ngOnDestroy"]();',
|
|
1463
1463
|
" }",
|
|
1464
1464
|
" }",
|
|
1465
1465
|
"}",
|
|
@@ -1856,7 +1856,7 @@ class ModuleGenerator {
|
|
|
1856
1856
|
return "undefined";
|
|
1857
1857
|
});
|
|
1858
1858
|
const callArgs = invokerArgs.length > 0 ? invokerArgs.join(", ") : "req";
|
|
1859
|
-
fields.push(`invoker: async (ctrl: unknown, req: { params?: Record<string, unknown>; query?: Record<string, unknown>; body?: unknown; headers?: Record<string, unknown>; cookie?: Record<string, unknown>; context?: unknown }) => { ` + `if (!isRecord(ctrl)) throw new TypeError("Route controller is not an object"); ` + `const handler = ctrl[${JSON.stringify(route.handler)}]; ` + `if (
|
|
1859
|
+
fields.push(`invoker: async (ctrl: unknown, req: { params?: Record<string, unknown>; query?: Record<string, unknown>; body?: unknown; headers?: Record<string, unknown>; cookie?: Record<string, unknown>; context?: unknown }) => { ` + `if (!isRecord(ctrl)) throw new TypeError("Route controller is not an object"); ` + `const handler = ctrl[${JSON.stringify(route.handler)}]; ` + `if (!isFunction(handler)) throw new TypeError("Route handler ${route.handler} is not callable"); ` + `return await Reflect.apply(handler, ctrl, [${callArgs}]); }`);
|
|
1860
1860
|
if (route.contract !== undefined) {
|
|
1861
1861
|
fields.push(`contract: ${JSON.stringify(route.contract)}`);
|
|
1862
1862
|
}
|
|
@@ -2028,7 +2028,7 @@ ${indent(item, 2)}`).join(",")}
|
|
|
2028
2028
|
if (emitted.constLine)
|
|
2029
2029
|
lines.push(emitted.constLine);
|
|
2030
2030
|
if (scoped) {
|
|
2031
|
-
lines.push(`scope[${JSON.stringify(emitted.key)}] = [...(
|
|
2031
|
+
lines.push(`scope[${JSON.stringify(emitted.key)}] = [...(isUnknownArray(scope[${JSON.stringify(emitted.key)}]) ? scope[${JSON.stringify(emitted.key)}] : []), ${emitted.expr}];`);
|
|
2032
2032
|
}
|
|
2033
2033
|
const list = multiGroups.get(emitted.key) ?? [];
|
|
2034
2034
|
list.push(emitted.expr);
|
|
@@ -2070,14 +2070,14 @@ ${indent(item, 2)}`).join(",")}
|
|
|
2070
2070
|
continue;
|
|
2071
2071
|
const key = camelName(token);
|
|
2072
2072
|
const expression = this.depExpr(token, scopeKind, this.depOptions(node, token));
|
|
2073
|
-
if (expression === `services
|
|
2073
|
+
if (expression === `services[${JSON.stringify(key)}]` || expression === `(services[${JSON.stringify(key)}] ?? undefined)`) {
|
|
2074
2074
|
if (!returns.has(key))
|
|
2075
2075
|
borrowed.add(key);
|
|
2076
2076
|
}
|
|
2077
2077
|
}
|
|
2078
2078
|
}
|
|
2079
2079
|
if (borrowed.size > 0) {
|
|
2080
|
-
const descriptors = [...borrowed].map((key) => `${key}: { value: deps
|
|
2080
|
+
const descriptors = [...borrowed].map((key) => `${key}: { value: deps[${JSON.stringify(key)}] }`);
|
|
2081
2081
|
lines.push(`return retainPlatformDependencies(Object.defineProperties({ ${entries.join(", ")} }, { ${descriptors.join(", ")} }), deps);`);
|
|
2082
2082
|
} else {
|
|
2083
2083
|
lines.push(`return retainPlatformDependencies({ ${entries.join(", ")} }, deps);`);
|
|
@@ -2183,34 +2183,34 @@ ${indent(item, 2)}`).join(",")}
|
|
|
2183
2183
|
}
|
|
2184
2184
|
}
|
|
2185
2185
|
if (own && factoryOfScope(own.scope) === "services" && kind !== "services" && !isSkipSelf && !isSelf) {
|
|
2186
|
-
return `services
|
|
2186
|
+
return `services[${JSON.stringify(camelName(token))}]`;
|
|
2187
2187
|
}
|
|
2188
2188
|
if (isSelf) {
|
|
2189
|
-
return isOptional ? "undefined" : `services
|
|
2189
|
+
return isOptional ? "undefined" : `services[${JSON.stringify(camelName(token))}]`;
|
|
2190
2190
|
}
|
|
2191
2191
|
for (const importName of this.module.imports) {
|
|
2192
2192
|
const imported = this.graph.modules.find((m) => m.name === importName);
|
|
2193
2193
|
if (!imported?.exports.includes(token))
|
|
2194
2194
|
continue;
|
|
2195
2195
|
if (kind === "services")
|
|
2196
|
-
return `imported
|
|
2197
|
-
return `imported
|
|
2196
|
+
return `imported[${JSON.stringify(importName)}][${JSON.stringify(camelName(token))}]`;
|
|
2197
|
+
return `imported[${JSON.stringify(importName)}][${JSON.stringify(camelName(token))}]`;
|
|
2198
2198
|
}
|
|
2199
2199
|
for (const mod of this.graph.modules) {
|
|
2200
2200
|
const rootProv = mod.providers.find((p) => p.token === token && p.providedIn === "root");
|
|
2201
2201
|
if (rootProv) {
|
|
2202
|
-
return `imported
|
|
2202
|
+
return `imported[${JSON.stringify(mod.name)}][${JSON.stringify(camelName(token))}]`;
|
|
2203
2203
|
}
|
|
2204
2204
|
}
|
|
2205
2205
|
if (isSelf)
|
|
2206
|
-
return isOptional ? "undefined" : `services
|
|
2206
|
+
return isOptional ? "undefined" : `services[${JSON.stringify(camelName(token))}]`;
|
|
2207
2207
|
if (kind === "services")
|
|
2208
|
-
return isOptional ? `(deps
|
|
2208
|
+
return isOptional ? `(deps[${JSON.stringify(camelName(token))}] ?? undefined)` : `deps[${JSON.stringify(camelName(token))}]`;
|
|
2209
2209
|
if (isSkipSelf) {
|
|
2210
|
-
const external = `platformDependencies.get(services)
|
|
2210
|
+
const external = `platformDependencies.get(services)?.[${JSON.stringify(camelName(token))}]`;
|
|
2211
2211
|
return isOptional ? `(${external} ?? undefined)` : external;
|
|
2212
2212
|
}
|
|
2213
|
-
return isOptional ? `(services
|
|
2213
|
+
return isOptional ? `(services[${JSON.stringify(camelName(token))}] ?? undefined)` : `services[${JSON.stringify(camelName(token))}]`;
|
|
2214
2214
|
}
|
|
2215
2215
|
}
|
|
2216
2216
|
function orderProviders(providers) {
|
|
@@ -3725,9 +3725,13 @@ function isFunction(value: unknown): value is (...args: unknown[]) => unknown {
|
|
|
3725
3725
|
return typeof value === "function";
|
|
3726
3726
|
}
|
|
3727
3727
|
|
|
3728
|
+
function isUnknownArray(value: unknown): value is unknown[] {
|
|
3729
|
+
return Array.isArray(value);
|
|
3730
|
+
}
|
|
3731
|
+
|
|
3728
3732
|
function resolveFactoryValue(value: unknown): unknown {
|
|
3729
|
-
if (!isRecord(value) || !isFunction(value
|
|
3730
|
-
return value
|
|
3733
|
+
if (!isRecord(value) || !isFunction(value["factory"])) return undefined;
|
|
3734
|
+
return value["factory"]();
|
|
3731
3735
|
}
|
|
3732
3736
|
|
|
3733
3737
|
const scopeDestructions = new WeakMap<object, Promise<void>>();
|
|
@@ -3750,14 +3754,14 @@ function destroyScopeInstances(
|
|
|
3750
3754
|
for (const entry of [...plan].reverse()) {
|
|
3751
3755
|
const value = scope[entry.key];
|
|
3752
3756
|
const instance = entry.index === undefined ? value
|
|
3753
|
-
:
|
|
3757
|
+
: isUnknownArray(value) ? value[entry.index] : undefined;
|
|
3754
3758
|
if (seen.has(instance)) continue;
|
|
3755
3759
|
seen.add(instance);
|
|
3756
3760
|
try {
|
|
3757
|
-
if (isRecord(instance) && isFunction(instance
|
|
3758
|
-
await instance
|
|
3759
|
-
} else if (isRecord(instance) && isFunction(instance
|
|
3760
|
-
await instance
|
|
3761
|
+
if (isRecord(instance) && isFunction(instance["onDestroy"])) {
|
|
3762
|
+
await instance["onDestroy"]();
|
|
3763
|
+
} else if (isRecord(instance) && isFunction(instance["ngOnDestroy"])) {
|
|
3764
|
+
await instance["ngOnDestroy"]();
|
|
3761
3765
|
}
|
|
3762
3766
|
} catch (error) {
|
|
3763
3767
|
errors.push(error);
|
|
@@ -3780,11 +3784,11 @@ async function initializeServiceInstances(
|
|
|
3780
3784
|
const value = services[entry.key];
|
|
3781
3785
|
const instance = entry.index === undefined
|
|
3782
3786
|
? value
|
|
3783
|
-
:
|
|
3787
|
+
: isUnknownArray(value) ? value[entry.index] : undefined;
|
|
3784
3788
|
if (seen.has(instance)) continue;
|
|
3785
3789
|
seen.add(instance);
|
|
3786
|
-
if (!isRecord(instance) || !isFunction(instance
|
|
3787
|
-
await instance
|
|
3790
|
+
if (!isRecord(instance) || !isFunction(instance["onInit"])) continue;
|
|
3791
|
+
await instance["onInit"]();
|
|
3788
3792
|
}
|
|
3789
3793
|
}
|
|
3790
3794
|
|
|
@@ -3798,13 +3802,13 @@ async function destroyServiceInstances(
|
|
|
3798
3802
|
const value = services[entry.key];
|
|
3799
3803
|
const instance = entry.index === undefined
|
|
3800
3804
|
? value
|
|
3801
|
-
:
|
|
3805
|
+
: isUnknownArray(value) ? value[entry.index] : undefined;
|
|
3802
3806
|
if (seen.has(instance)) continue;
|
|
3803
3807
|
seen.add(instance);
|
|
3804
3808
|
if (!isRecord(instance)) continue;
|
|
3805
|
-
const hook = isFunction(instance
|
|
3806
|
-
? instance
|
|
3807
|
-
: isFunction(instance
|
|
3809
|
+
const hook = isFunction(instance["onDestroy"])
|
|
3810
|
+
? instance["onDestroy"]
|
|
3811
|
+
: isFunction(instance["ngOnDestroy"]) ? instance["ngOnDestroy"] : undefined;
|
|
3808
3812
|
if (!hook) continue;
|
|
3809
3813
|
try {
|
|
3810
3814
|
await hook.call(instance);
|
|
@@ -4036,7 +4040,7 @@ var init_graphql_options = __esm(() => {
|
|
|
4036
4040
|
});
|
|
4037
4041
|
|
|
4038
4042
|
// src/graphql-inputs.ts
|
|
4039
|
-
import { resolve as
|
|
4043
|
+
import { resolve as resolve5 } from "node:path";
|
|
4040
4044
|
import * as ts10 from "@typescript/typescript6";
|
|
4041
4045
|
function graphqlInputPaths(options) {
|
|
4042
4046
|
if (!options.graphql)
|
|
@@ -4046,9 +4050,9 @@ function graphqlInputPaths(options) {
|
|
|
4046
4050
|
} catch {
|
|
4047
4051
|
return [];
|
|
4048
4052
|
}
|
|
4049
|
-
const root =
|
|
4050
|
-
const schema =
|
|
4051
|
-
const documents = ts10.sys.readDirectory(root, [".graphql", ".gql"], ["**/node_modules/**", "**/.git/**",
|
|
4053
|
+
const root = resolve5(options.rootDir);
|
|
4054
|
+
const schema = resolve5(root, options.graphql.schema);
|
|
4055
|
+
const documents = ts10.sys.readDirectory(root, [".graphql", ".gql"], ["**/node_modules/**", "**/.git/**", resolve5(options.outDir)], options.graphql.documents ?? ["**/*.graphql", "**/*.gql"]).map((path) => resolve5(path)).filter((path) => path !== schema);
|
|
4052
4056
|
return [schema, ...[...new Set(documents)].sort()];
|
|
4053
4057
|
}
|
|
4054
4058
|
var init_graphql_inputs = __esm(() => {
|
|
@@ -4057,9 +4061,9 @@ var init_graphql_inputs = __esm(() => {
|
|
|
4057
4061
|
|
|
4058
4062
|
// src/graphql-runtime.ts
|
|
4059
4063
|
import * as ts11 from "@typescript/typescript6";
|
|
4060
|
-
import { resolve as
|
|
4064
|
+
import { resolve as resolve6 } from "node:path";
|
|
4061
4065
|
function renderGraphqlValidators(source, operationNames) {
|
|
4062
|
-
const fileName =
|
|
4066
|
+
const fileName = resolve6("/__supacloud_graphql__/contracts.ts");
|
|
4063
4067
|
const options = {
|
|
4064
4068
|
strict: true,
|
|
4065
4069
|
noUncheckedIndexedAccess: true,
|
|
@@ -4075,7 +4079,7 @@ function renderGraphqlValidators(source, operationNames) {
|
|
|
4075
4079
|
};
|
|
4076
4080
|
const host = ts11.createCompilerHost(options);
|
|
4077
4081
|
const getSourceFile = host.getSourceFile.bind(host);
|
|
4078
|
-
host.getSourceFile = (path, languageVersion, onError, shouldCreateNewSourceFile) =>
|
|
4082
|
+
host.getSourceFile = (path, languageVersion, onError, shouldCreateNewSourceFile) => resolve6(path) === fileName ? ts11.createSourceFile(path, source, languageVersion, true) : getSourceFile(path, languageVersion, onError, shouldCreateNewSourceFile);
|
|
4079
4083
|
const program = ts11.createProgram([fileName], options, host);
|
|
4080
4084
|
const diagnostics = ts11.getPreEmitDiagnostics(program);
|
|
4081
4085
|
if (diagnostics.length) {
|
|
@@ -14608,7 +14612,7 @@ var init_delivery_schema = __esm(() => {
|
|
|
14608
14612
|
import { createHash as createHash7 } from "node:crypto";
|
|
14609
14613
|
import { constants } from "node:fs";
|
|
14610
14614
|
import { lstat, mkdir as mkdir2, open, readFile as readFile3, readdir, realpath, rename as rename2, rm, writeFile as writeFile2 } from "node:fs/promises";
|
|
14611
|
-
import { dirname as dirname4, isAbsolute, join as join5, relative as relative5, resolve as
|
|
14615
|
+
import { dirname as dirname4, isAbsolute, join as join5, relative as relative5, resolve as resolve8, sep as sep5 } from "node:path";
|
|
14612
14616
|
function canonical2(value) {
|
|
14613
14617
|
return JSON.stringify(value, (_key, item) => item !== null && typeof item === "object" && !Array.isArray(item) ? Object.fromEntries(Object.entries(item).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) : item);
|
|
14614
14618
|
}
|
|
@@ -14671,7 +14675,7 @@ async function reserveOutput(project, requested) {
|
|
|
14671
14675
|
if (!inside(project, requested))
|
|
14672
14676
|
throw new Error("Delivery output must be inside the application project.");
|
|
14673
14677
|
const base = await realpath(project);
|
|
14674
|
-
const path =
|
|
14678
|
+
const path = resolve8(base, relative5(project, requested));
|
|
14675
14679
|
if (relative5(base, path).split(sep5).some((part) => part === ".git" || part === "node_modules")) {
|
|
14676
14680
|
throw new Error("Delivery output cannot use repository or dependency internals.");
|
|
14677
14681
|
}
|
|
@@ -15753,9 +15757,9 @@ var init_delivery_files2 = __esm(() => {
|
|
|
15753
15757
|
|
|
15754
15758
|
// node_modules/@supacloud/delivery/src/delivery-artifact.ts
|
|
15755
15759
|
import { readdir as readdir2, realpath as realpath2 } from "node:fs/promises";
|
|
15756
|
-
import { basename, dirname as dirname6, join as join8, resolve as
|
|
15760
|
+
import { basename, dirname as dirname6, join as join8, resolve as resolve10 } from "node:path";
|
|
15757
15761
|
async function readDeliveryManifest(manifestPath) {
|
|
15758
|
-
const selected =
|
|
15762
|
+
const selected = resolve10(manifestPath);
|
|
15759
15763
|
const root = await realpath2(dirname6(selected));
|
|
15760
15764
|
const manifest = parseDeliveryBuildManifest(JSON.parse((await readBoundedOwned(root, join8(root, basename(selected)), JSON_LIMIT)).toString("utf8")));
|
|
15761
15765
|
return { root, manifest };
|
|
@@ -16173,13 +16177,13 @@ var init_delivery_migration_archive2 = __esm(() => {
|
|
|
16173
16177
|
// src/fixes.ts
|
|
16174
16178
|
import { createHash as createHash8, randomUUID } from "node:crypto";
|
|
16175
16179
|
import { lstat as lstat2, readFile as readFile6, realpath as realpath4, rename as rename4, unlink as unlink2, writeFile as writeFile3 } from "node:fs/promises";
|
|
16176
|
-
import { dirname as dirname8, isAbsolute as isAbsolute3, relative as relative8, resolve as
|
|
16180
|
+
import { dirname as dirname8, isAbsolute as isAbsolute3, relative as relative8, resolve as resolve13, sep as sep8 } from "node:path";
|
|
16177
16181
|
import * as ts15 from "@typescript/typescript6";
|
|
16178
16182
|
async function applyDiagnosticFix(fix, options = {}) {
|
|
16179
16183
|
if (!fix || typeof fix.targetFile !== "string")
|
|
16180
16184
|
throw new Error("Invalid DiagnosticFix");
|
|
16181
16185
|
const root = await realpath4(options.rootDir ?? process.cwd());
|
|
16182
|
-
const file =
|
|
16186
|
+
const file = resolve13(root, fix.targetFile);
|
|
16183
16187
|
const stat = await lstat2(file);
|
|
16184
16188
|
const resolved = await realpath4(file);
|
|
16185
16189
|
const relativePath = relative8(root, resolved);
|
|
@@ -16352,8 +16356,8 @@ function moduleObjects(source) {
|
|
|
16352
16356
|
}
|
|
16353
16357
|
function importSymbol(source, path, symbol) {
|
|
16354
16358
|
identifier2(symbol);
|
|
16355
|
-
const current =
|
|
16356
|
-
const target =
|
|
16359
|
+
const current = resolve13(source.fileName).replace(/\.(tsx?|mts|cts)$/, "");
|
|
16360
|
+
const target = resolve13(dirname8(source.fileName), path).replace(/\.(tsx?|mts|cts)$/, "");
|
|
16357
16361
|
if (current === target)
|
|
16358
16362
|
return source.text;
|
|
16359
16363
|
const matches = source.statements.filter((item) => ts15.isImportDeclaration(item) && ts15.isStringLiteral(item.moduleSpecifier) && item.moduleSpecifier.text === path);
|
|
@@ -16830,7 +16834,7 @@ var init_release_evidence = __esm(() => {
|
|
|
16830
16834
|
|
|
16831
16835
|
// src/graphql-schema.ts
|
|
16832
16836
|
import { mkdir as mkdir5, readFile as readFile12 } from "node:fs/promises";
|
|
16833
|
-
import { dirname as dirname11, resolve as
|
|
16837
|
+
import { dirname as dirname11, resolve as resolve21 } from "node:path";
|
|
16834
16838
|
async function pullGraphqlSchema(options) {
|
|
16835
16839
|
assertGraphqlOptions({ schema: options.output });
|
|
16836
16840
|
const endpoint = new URL(options.url);
|
|
@@ -16870,7 +16874,7 @@ async function pullGraphqlSchema(options) {
|
|
|
16870
16874
|
throw new Error("GraphQL schema export failed. Verify caller grants and enable introspection only in the intended development environment.");
|
|
16871
16875
|
}
|
|
16872
16876
|
const schema = lexicographicSortSchema(buildClientSchema(data));
|
|
16873
|
-
const path =
|
|
16877
|
+
const path = resolve21(options.output);
|
|
16874
16878
|
const content = path.endsWith(".json") ? JSON.stringify(introspectionFromSchema(schema), null, 2) + `
|
|
16875
16879
|
` : `# GENERATED BY supacloud-compiler graphql-schema. DO NOT EDIT.
|
|
16876
16880
|
# Database First: change database declarations, apply migrations, then re-export for the intended role.
|
|
@@ -16900,7 +16904,7 @@ var init_graphql_schema = __esm(() => {
|
|
|
16900
16904
|
// src/database-contracts.ts
|
|
16901
16905
|
import { createHash as createHash11 } from "node:crypto";
|
|
16902
16906
|
import { mkdir as mkdir6, readFile as readFile13 } from "node:fs/promises";
|
|
16903
|
-
import { dirname as dirname12, relative as relative12, resolve as
|
|
16907
|
+
import { dirname as dirname12, relative as relative12, resolve as resolve22 } from "node:path";
|
|
16904
16908
|
import * as ts17 from "@typescript/typescript6";
|
|
16905
16909
|
function hash3(value) {
|
|
16906
16910
|
return createHash11("sha256").update(value).digest("hex");
|
|
@@ -16928,18 +16932,18 @@ function parseDatabaseContractsOptions(value, directory) {
|
|
|
16928
16932
|
throw new TypeError("migrations must be an ordered list of SQL files");
|
|
16929
16933
|
}
|
|
16930
16934
|
return {
|
|
16931
|
-
rootDir:
|
|
16932
|
-
outDir:
|
|
16933
|
-
postgrestTypes:
|
|
16934
|
-
drizzleSchema:
|
|
16935
|
+
rootDir: resolve22(directory, field("rootDir")),
|
|
16936
|
+
outDir: resolve22(directory, field("outDir")),
|
|
16937
|
+
postgrestTypes: resolve22(directory, field("postgrestTypes")),
|
|
16938
|
+
drizzleSchema: resolve22(directory, field("drizzleSchema")),
|
|
16935
16939
|
role: field("role"),
|
|
16936
|
-
graphql: { ...graphql, schema:
|
|
16937
|
-
migrations: migrations.map((file) =>
|
|
16940
|
+
graphql: { ...graphql, schema: resolve22(directory, graphql.schema) },
|
|
16941
|
+
migrations: migrations.map((file) => resolve22(directory, file))
|
|
16938
16942
|
};
|
|
16939
16943
|
}
|
|
16940
16944
|
async function generateDatabaseContracts(options, check = false) {
|
|
16941
|
-
const rootDir =
|
|
16942
|
-
const postgrestTypes =
|
|
16945
|
+
const rootDir = resolve22(options.rootDir), outDir = resolve22(options.outDir);
|
|
16946
|
+
const postgrestTypes = resolve22(rootDir, options.postgrestTypes), drizzleSchema = resolve22(rootDir, options.drizzleSchema);
|
|
16943
16947
|
const snapshot = await readFile13(postgrestTypes, "utf8");
|
|
16944
16948
|
const syntax = ts17.createSourceFile(postgrestTypes, snapshot, ts17.ScriptTarget.Latest, true);
|
|
16945
16949
|
const database = syntax.statements.find((node) => (ts17.isTypeAliasDeclaration(node) || ts17.isInterfaceDeclaration(node)) && node.name.text === "Database" && node.modifiers?.some((modifier) => modifier.kind === ts17.SyntaxKind.ExportKeyword));
|
|
@@ -16967,7 +16971,7 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
16967
16971
|
}
|
|
16968
16972
|
const inputs = {};
|
|
16969
16973
|
const addInput = async (path) => {
|
|
16970
|
-
const absolute =
|
|
16974
|
+
const absolute = resolve22(rootDir, path);
|
|
16971
16975
|
inputs[relative12(rootDir, absolute).replaceAll("\\", "/")] = hash3(await readFile13(absolute, "utf8"));
|
|
16972
16976
|
};
|
|
16973
16977
|
await addInput(postgrestTypes);
|
|
@@ -16984,8 +16988,8 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
16984
16988
|
if (!source.isDeclarationFile && !source.fileName.includes("/node_modules/"))
|
|
16985
16989
|
await addInput(source.fileName);
|
|
16986
16990
|
}
|
|
16987
|
-
await addInput(
|
|
16988
|
-
if (new Set(options.migrations.map((path) =>
|
|
16991
|
+
await addInput(resolve22(rootDir, options.graphql.schema));
|
|
16992
|
+
if (new Set(options.migrations.map((path) => resolve22(rootDir, path))).size !== options.migrations.length) {
|
|
16989
16993
|
throw new Error("Duplicate migration in database contracts configuration");
|
|
16990
16994
|
}
|
|
16991
16995
|
for (const path of options.migrations)
|
|
@@ -17006,14 +17010,14 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
17006
17010
|
version: 1,
|
|
17007
17011
|
role: options.role,
|
|
17008
17012
|
inputs: Object.fromEntries(Object.entries(inputs).sort(([a], [b]) => a.localeCompare(b))),
|
|
17009
|
-
migrationOrder: options.migrations.map((path) => relative12(rootDir,
|
|
17013
|
+
migrationOrder: options.migrations.map((path) => relative12(rootDir, resolve22(rootDir, path)).replaceAll("\\", "/")),
|
|
17010
17014
|
outputs: Object.fromEntries(Object.entries(files).sort(([a], [b]) => a.localeCompare(b)).map(([file, text]) => [file, hash3(text)]))
|
|
17011
17015
|
};
|
|
17012
17016
|
files["database.manifest.json"] = JSON.stringify(manifest, null, 2) + `
|
|
17013
17017
|
`;
|
|
17014
17018
|
const mismatches = [];
|
|
17015
17019
|
for (const [file, content] of Object.entries(files)) {
|
|
17016
|
-
const path =
|
|
17020
|
+
const path = resolve22(outDir, file);
|
|
17017
17021
|
let current;
|
|
17018
17022
|
try {
|
|
17019
17023
|
current = await readFile13(path, "utf8");
|
|
@@ -17027,12 +17031,12 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
17027
17031
|
if (!check) {
|
|
17028
17032
|
await mkdir6(outDir, { recursive: true });
|
|
17029
17033
|
for (const [file, content] of Object.entries(files))
|
|
17030
|
-
await writeFileIfChanged(
|
|
17034
|
+
await writeFileIfChanged(resolve22(outDir, file), content);
|
|
17031
17035
|
}
|
|
17032
17036
|
return { upToDate: mismatches.length === 0, mismatches, written: check ? [] : mismatches, manifest };
|
|
17033
17037
|
}
|
|
17034
17038
|
async function runDatabaseContractsFile(path, check = false) {
|
|
17035
|
-
const absolute =
|
|
17039
|
+
const absolute = resolve22(path);
|
|
17036
17040
|
const value = JSON.parse(await readFile13(absolute, "utf8"));
|
|
17037
17041
|
return generateDatabaseContracts(parseDatabaseContractsOptions(value, dirname12(absolute)), check);
|
|
17038
17042
|
}
|
|
@@ -20476,6 +20480,55 @@ function isAnyKeyword(node) {
|
|
|
20476
20480
|
|
|
20477
20481
|
// src/compile.ts
|
|
20478
20482
|
init_route_contracts();
|
|
20483
|
+
|
|
20484
|
+
// src/client-schema-boundaries.ts
|
|
20485
|
+
import { resolve as resolve4 } from "node:path";
|
|
20486
|
+
function validateClientSchemaBoundaries(graph, options) {
|
|
20487
|
+
if (!options.generateClient)
|
|
20488
|
+
return [];
|
|
20489
|
+
const identity = (path) => resolve4(options.rootDir, path).replace(/\.(?:[cm]?ts|[cm]?js)$/, "");
|
|
20490
|
+
const runtimeModules = new Set(graph.modules.flatMap((module) => [
|
|
20491
|
+
module.file,
|
|
20492
|
+
...module.controllers.map((controller) => controller.file),
|
|
20493
|
+
...module.providers.map((provider) => provider.file)
|
|
20494
|
+
]).filter((file) => typeof file === "string").map(identity));
|
|
20495
|
+
const diagnostics = [];
|
|
20496
|
+
const seen = new Set;
|
|
20497
|
+
for (const module of graph.modules) {
|
|
20498
|
+
for (const controller of module.controllers) {
|
|
20499
|
+
for (const route of controller.routes) {
|
|
20500
|
+
const symbols = [
|
|
20501
|
+
route.body,
|
|
20502
|
+
route.params,
|
|
20503
|
+
route.query,
|
|
20504
|
+
route.headers,
|
|
20505
|
+
route.cookie,
|
|
20506
|
+
...route.responses && Object.keys(route.responses).length ? Object.values(route.responses) : [route.response]
|
|
20507
|
+
];
|
|
20508
|
+
for (const symbol of symbols) {
|
|
20509
|
+
if (!symbol)
|
|
20510
|
+
continue;
|
|
20511
|
+
const importedFrom = controller.schemaImports?.[symbol];
|
|
20512
|
+
if (!importedFrom || !runtimeModules.has(identity(importedFrom)))
|
|
20513
|
+
continue;
|
|
20514
|
+
const key = `${identity(importedFrom)}:${symbol}`;
|
|
20515
|
+
if (seen.has(key))
|
|
20516
|
+
continue;
|
|
20517
|
+
seen.add(key);
|
|
20518
|
+
diagnostics.push({
|
|
20519
|
+
severity: "warn",
|
|
20520
|
+
code: "client-schema-runtime-import",
|
|
20521
|
+
file: controller.file,
|
|
20522
|
+
message: `Generated client schema "${symbol}" imports application runtime module "${importedFrom}". Move the schema to a shared contract-only module and import it into the controller. This also avoids checking server decorators in the browser TypeScript project.`
|
|
20523
|
+
});
|
|
20524
|
+
}
|
|
20525
|
+
}
|
|
20526
|
+
}
|
|
20527
|
+
}
|
|
20528
|
+
return diagnostics;
|
|
20529
|
+
}
|
|
20530
|
+
|
|
20531
|
+
// src/compile.ts
|
|
20479
20532
|
function withDefaultGovernance(options) {
|
|
20480
20533
|
return options.commandCapabilities === undefined ? { ...options, commandCapabilities: {
|
|
20481
20534
|
requirePersistentAdapters: true,
|
|
@@ -20493,7 +20546,8 @@ async function compileProject(options) {
|
|
|
20493
20546
|
const graph = await analyzeProject(options.rootDir, options.include, options.cache, options.changedPaths);
|
|
20494
20547
|
const diagnostics = [
|
|
20495
20548
|
...graph.diagnostics ?? [],
|
|
20496
|
-
...validateGraph(graph, options)
|
|
20549
|
+
...validateGraph(graph, options),
|
|
20550
|
+
...validateClientSchemaBoundaries(graph, options)
|
|
20497
20551
|
];
|
|
20498
20552
|
if (diagnostics.some((item) => item.code === "runtime-injection-disallowed")) {
|
|
20499
20553
|
return { diagnostics, graph, written: [] };
|
|
@@ -20556,7 +20610,8 @@ async function checkProject(options) {
|
|
|
20556
20610
|
const graph = await analyzeProject(options.rootDir, options.include, options.cache, options.changedPaths);
|
|
20557
20611
|
const diagnostics = [
|
|
20558
20612
|
...graph.diagnostics ?? [],
|
|
20559
|
-
...validateGraph(graph, options)
|
|
20613
|
+
...validateGraph(graph, options),
|
|
20614
|
+
...validateClientSchemaBoundaries(graph, options)
|
|
20560
20615
|
];
|
|
20561
20616
|
if (diagnostics.some((item) => item.code === "runtime-injection-disallowed")) {
|
|
20562
20617
|
return { diagnostics, graph, upToDate: false, mismatches: ["Runtime DI must be migrated to constructor injection."] };
|
|
@@ -20884,7 +20939,7 @@ function formatDeliveryPlan(result) {
|
|
|
20884
20939
|
// src/delivery-build.ts
|
|
20885
20940
|
import { mkdir as mkdir3, mkdtemp, readFile as readFile5, realpath as realpath3, rename as rename3, rm as rm2 } from "node:fs/promises";
|
|
20886
20941
|
import { readFileSync as readFileSync3 } from "node:fs";
|
|
20887
|
-
import { dirname as dirname7, join as join9, relative as relative7, resolve as
|
|
20942
|
+
import { dirname as dirname7, join as join9, relative as relative7, resolve as resolve12, sep as sep7 } from "node:path";
|
|
20888
20943
|
import * as ts14 from "@typescript/typescript6";
|
|
20889
20944
|
|
|
20890
20945
|
// src/delivery-build-schema.ts
|
|
@@ -20926,7 +20981,7 @@ function renderDeliveryTarget(graph, target, options) {
|
|
|
20926
20981
|
init_delivery_files2();
|
|
20927
20982
|
import { isBuiltin } from "node:module";
|
|
20928
20983
|
import { readFile as readFile4 } from "node:fs/promises";
|
|
20929
|
-
import { join as join7, resolve as
|
|
20984
|
+
import { join as join7, resolve as resolve9 } from "node:path";
|
|
20930
20985
|
import * as ts13 from "@typescript/typescript6";
|
|
20931
20986
|
|
|
20932
20987
|
// src/delivery-imports.ts
|
|
@@ -21103,7 +21158,7 @@ async function bundleDeliveryTarget(name, code, project, generatedDirectory, opt
|
|
|
21103
21158
|
async function bundleDeliveryTargetInProcess(name, code, project, generatedDirectory, options) {
|
|
21104
21159
|
const inputs = new Map;
|
|
21105
21160
|
const workingDirectory = process.cwd();
|
|
21106
|
-
const entry =
|
|
21161
|
+
const entry = resolve9(generatedDirectory, `delivery-${name}.ts`);
|
|
21107
21162
|
const entryPattern = new RegExp(`^${entry.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}$`);
|
|
21108
21163
|
const result = await Bun.build({
|
|
21109
21164
|
entrypoints: [entry],
|
|
@@ -21126,7 +21181,7 @@ async function bundleDeliveryTargetInProcess(name, code, project, generatedDirec
|
|
|
21126
21181
|
if (args.path === entry)
|
|
21127
21182
|
return { contents: code, loader: "ts" };
|
|
21128
21183
|
const bytes = await readFile4(args.path);
|
|
21129
|
-
inputs.set(
|
|
21184
|
+
inputs.set(resolve9(args.path), digest(bytes));
|
|
21130
21185
|
return { contents: staticDeliveryImports(args.path, bytes), loader: args.loader };
|
|
21131
21186
|
});
|
|
21132
21187
|
}
|
|
@@ -21136,7 +21191,7 @@ async function bundleDeliveryTargetInProcess(name, code, project, generatedDirec
|
|
|
21136
21191
|
throw new Error("Independent bundle failed or has no dependency metadata.");
|
|
21137
21192
|
const runtimeImports = new Set;
|
|
21138
21193
|
for (const [path, metadata] of Object.entries(result.metafile.inputs)) {
|
|
21139
|
-
if (
|
|
21194
|
+
if (resolve9(workingDirectory, path) !== entry && !inputs.has(resolve9(workingDirectory, path))) {
|
|
21140
21195
|
throw new Error("Bundler reported an input that was not captured by the delivery snapshot.");
|
|
21141
21196
|
}
|
|
21142
21197
|
for (const imported of metadata.imports) {
|
|
@@ -21475,14 +21530,14 @@ interface DeliveryWorkerHost {
|
|
|
21475
21530
|
|
|
21476
21531
|
// src/delivery-migrations.ts
|
|
21477
21532
|
init_delivery_files2();
|
|
21478
|
-
import { resolve as
|
|
21533
|
+
import { resolve as resolve11 } from "node:path";
|
|
21479
21534
|
async function prepareDeliveryMigrations(project, generatedRoot, declarations = []) {
|
|
21480
21535
|
const entries = [];
|
|
21481
21536
|
const files = new Map;
|
|
21482
21537
|
const inputs = new Map;
|
|
21483
21538
|
let totalBytes = 0;
|
|
21484
21539
|
for (const declaration of [...declarations].sort((a, b) => BigInt(a.version) < BigInt(b.version) ? -1 : BigInt(a.version) > BigInt(b.version) ? 1 : 0)) {
|
|
21485
|
-
const source =
|
|
21540
|
+
const source = resolve11(project, declaration.source);
|
|
21486
21541
|
if (!inside(project, source) || inside(generatedRoot, source))
|
|
21487
21542
|
throw new Error("Invalid migration source.");
|
|
21488
21543
|
const bytes = await readBoundedOwned(project, source, 1048576);
|
|
@@ -21533,7 +21588,7 @@ async function buildDeliveryProject(options, delivery) {
|
|
|
21533
21588
|
const settings = parseDeliveryOptions(delivery);
|
|
21534
21589
|
if (typeof Bun === "undefined")
|
|
21535
21590
|
throw new Error("Independent delivery builds require Bun.");
|
|
21536
|
-
const configPath = ts14.findConfigFile(
|
|
21591
|
+
const configPath = ts14.findConfigFile(resolve12(options.rootDir), ts14.sys.fileExists);
|
|
21537
21592
|
if (!configPath)
|
|
21538
21593
|
throw new Error("Independent delivery builds require a project tsconfig.json.");
|
|
21539
21594
|
const lexicalProject = dirname7(configPath);
|
|
@@ -21541,11 +21596,11 @@ async function buildDeliveryProject(options, delivery) {
|
|
|
21541
21596
|
const sourceRoot = await realpath3(options.rootDir);
|
|
21542
21597
|
if (!inside(project, sourceRoot))
|
|
21543
21598
|
throw new Error("Application sources must be inside the project.");
|
|
21544
|
-
const requested =
|
|
21599
|
+
const requested = resolve12(options.outDir, "delivery");
|
|
21545
21600
|
if (!inside(lexicalProject, requested))
|
|
21546
21601
|
throw new Error("Output must be inside the application project.");
|
|
21547
|
-
const buildRoot =
|
|
21548
|
-
const generatedRoot =
|
|
21602
|
+
const buildRoot = resolve12(project, relative7(lexicalProject, requested));
|
|
21603
|
+
const generatedRoot = resolve12(project, relative7(lexicalProject, options.outDir));
|
|
21549
21604
|
if (inside(generatedRoot, sourceRoot))
|
|
21550
21605
|
throw new Error("Output must not contain the application source root.");
|
|
21551
21606
|
const configInputs = new Map;
|
|
@@ -21553,7 +21608,7 @@ async function buildDeliveryProject(options, delivery) {
|
|
|
21553
21608
|
...ts14.sys,
|
|
21554
21609
|
readFile(path) {
|
|
21555
21610
|
const contents = readFileSync3(path, "utf8");
|
|
21556
|
-
configInputs.set(
|
|
21611
|
+
configInputs.set(resolve12(path), digest(contents));
|
|
21557
21612
|
return contents;
|
|
21558
21613
|
},
|
|
21559
21614
|
onUnRecoverableConfigFileDiagnostic() {
|
|
@@ -21591,7 +21646,7 @@ async function buildDeliveryProject(options, delivery) {
|
|
|
21591
21646
|
if (!target || (kind === "worker" ? target.kind !== "jobs" : target.kind === "jobs")) {
|
|
21592
21647
|
throw new Error("Delivery host kind does not match its target.");
|
|
21593
21648
|
}
|
|
21594
|
-
const path =
|
|
21649
|
+
const path = resolve12(sourceRoot, app.source);
|
|
21595
21650
|
if (inside(generatedRoot, path) || !/\.[cm]?ts$/.test(path))
|
|
21596
21651
|
throw new Error("Hosts require application TypeScript source.");
|
|
21597
21652
|
hosts.set(app.target, { path, kind, hash: digest(await readOwned(sourceRoot, path)) });
|
|
@@ -21718,7 +21773,7 @@ async function buildDeliveryProject(options, delivery) {
|
|
|
21718
21773
|
}));
|
|
21719
21774
|
const assetInputs = {};
|
|
21720
21775
|
for (const asset of assets.filter((asset) => asset.target === target.name)) {
|
|
21721
|
-
const path =
|
|
21776
|
+
const path = resolve12(sourceRoot, asset.source);
|
|
21722
21777
|
const bytes = await readOwned(sourceRoot, path);
|
|
21723
21778
|
const hash = digest(bytes);
|
|
21724
21779
|
const previousHash = snapshots.get(path);
|
|
@@ -22053,12 +22108,12 @@ init_release_evidence();
|
|
|
22053
22108
|
|
|
22054
22109
|
// src/watch.ts
|
|
22055
22110
|
import { existsSync as existsSync4, watch } from "node:fs";
|
|
22056
|
-
import { dirname as dirname9, relative as relative10, resolve as
|
|
22111
|
+
import { dirname as dirname9, relative as relative10, resolve as resolve15, sep as sep10 } from "node:path";
|
|
22057
22112
|
|
|
22058
22113
|
// src/incremental.ts
|
|
22059
22114
|
import { createHash as createHash9 } from "node:crypto";
|
|
22060
22115
|
import { access as access3, readdir as readdir3, readFile as readFile7 } from "node:fs/promises";
|
|
22061
|
-
import { isAbsolute as isAbsolute4, relative as relative9, resolve as
|
|
22116
|
+
import { isAbsolute as isAbsolute4, relative as relative9, resolve as resolve14, sep as sep9 } from "node:path";
|
|
22062
22117
|
init_graphql_inputs();
|
|
22063
22118
|
function createDependencyGraphCache() {
|
|
22064
22119
|
return {
|
|
@@ -22139,11 +22194,11 @@ async function readSourceBytes(path) {
|
|
|
22139
22194
|
return readFile7(path);
|
|
22140
22195
|
}
|
|
22141
22196
|
async function updateSnapshot(previous, options, changedPaths) {
|
|
22142
|
-
const rootDir =
|
|
22143
|
-
const outDir =
|
|
22197
|
+
const rootDir = resolve14(options.rootDir);
|
|
22198
|
+
const outDir = resolve14(options.outDir);
|
|
22144
22199
|
const files = { ...previous.files };
|
|
22145
22200
|
await Promise.all(changedPaths.map(async (changedPath) => {
|
|
22146
|
-
const absolutePath = isAbsolute4(changedPath) ?
|
|
22201
|
+
const absolutePath = isAbsolute4(changedPath) ? resolve14(changedPath) : resolve14(rootDir, changedPath);
|
|
22147
22202
|
const relativeChangedPath = relative9(rootDir, absolutePath);
|
|
22148
22203
|
if (relativeChangedPath === ".." || relativeChangedPath.startsWith(`..${sep9}`))
|
|
22149
22204
|
return;
|
|
@@ -22161,8 +22216,8 @@ async function updateSnapshot(previous, options, changedPaths) {
|
|
|
22161
22216
|
return { files, optionsKey: optionsKeyOf(options) };
|
|
22162
22217
|
}
|
|
22163
22218
|
async function createSnapshot(options) {
|
|
22164
|
-
const rootDir =
|
|
22165
|
-
const outDir =
|
|
22219
|
+
const rootDir = resolve14(options.rootDir);
|
|
22220
|
+
const outDir = resolve14(options.outDir);
|
|
22166
22221
|
const paths = await listSourceFiles(rootDir, outDir);
|
|
22167
22222
|
const files = {};
|
|
22168
22223
|
const entries = await Promise.all(paths.map(async (path) => {
|
|
@@ -22185,8 +22240,8 @@ async function createSnapshot(options) {
|
|
|
22185
22240
|
}
|
|
22186
22241
|
function optionsKeyOf(options) {
|
|
22187
22242
|
return JSON.stringify({
|
|
22188
|
-
rootDir:
|
|
22189
|
-
outDir:
|
|
22243
|
+
rootDir: resolve14(options.rootDir),
|
|
22244
|
+
outDir: resolve14(options.outDir),
|
|
22190
22245
|
include: options.include,
|
|
22191
22246
|
strict: options.strict,
|
|
22192
22247
|
writeOnError: options.writeOnError,
|
|
@@ -22210,7 +22265,7 @@ async function listSourceFiles(rootDir, outDir) {
|
|
|
22210
22265
|
const result = [];
|
|
22211
22266
|
const visit = async (directory) => {
|
|
22212
22267
|
for (const entry of await readdir3(directory, { withFileTypes: true })) {
|
|
22213
|
-
const path =
|
|
22268
|
+
const path = resolve14(directory, entry.name);
|
|
22214
22269
|
if (entry.isDirectory()) {
|
|
22215
22270
|
if (entry.name === "node_modules" || entry.name === ".git" || path === outDir)
|
|
22216
22271
|
continue;
|
|
@@ -22345,8 +22400,8 @@ function isCompilerConfigurationPath(rootDir, changedPath) {
|
|
|
22345
22400
|
].includes(relativePath) || /^tsconfig\.[^/]+\.json$/.test(relativePath);
|
|
22346
22401
|
}
|
|
22347
22402
|
function watchProject(options) {
|
|
22348
|
-
const rootDir =
|
|
22349
|
-
const outDir =
|
|
22403
|
+
const rootDir = resolve15(options.rootDir);
|
|
22404
|
+
const outDir = resolve15(options.outDir);
|
|
22350
22405
|
const debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;
|
|
22351
22406
|
let timer;
|
|
22352
22407
|
let closed = false;
|
|
@@ -22356,7 +22411,7 @@ function watchProject(options) {
|
|
|
22356
22411
|
const pendingPaths = new Set;
|
|
22357
22412
|
let watcher;
|
|
22358
22413
|
let schemaWatcher;
|
|
22359
|
-
const schemaPath = options.graphql ?
|
|
22414
|
+
const schemaPath = options.graphql ? resolve15(rootDir, options.graphql.schema) : undefined;
|
|
22360
22415
|
const incremental = createIncrementalCompiler();
|
|
22361
22416
|
let initialEvent;
|
|
22362
22417
|
let resolveReady = () => {
|
|
@@ -22466,7 +22521,7 @@ function watchProject(options) {
|
|
|
22466
22521
|
watcher = watch(rootDir, { recursive: true }, (_eventType, filename) => {
|
|
22467
22522
|
if (!filename)
|
|
22468
22523
|
return schedule();
|
|
22469
|
-
const changedPath =
|
|
22524
|
+
const changedPath = resolve15(rootDir, filename.toString());
|
|
22470
22525
|
const relativePath = relative10(outDir, changedPath);
|
|
22471
22526
|
if (!relativePath.startsWith("..") && relativePath !== "")
|
|
22472
22527
|
return;
|
|
@@ -22479,7 +22534,7 @@ function watchProject(options) {
|
|
|
22479
22534
|
while (!existsSync4(directory) && dirname9(directory) !== directory)
|
|
22480
22535
|
directory = dirname9(directory);
|
|
22481
22536
|
schemaWatcher = watch(directory, { recursive: true }, (_eventType, filename) => {
|
|
22482
|
-
if (!filename ||
|
|
22537
|
+
if (!filename || resolve15(directory, filename.toString()) === schemaPath)
|
|
22483
22538
|
schedule(schemaPath);
|
|
22484
22539
|
});
|
|
22485
22540
|
}
|
|
@@ -22502,19 +22557,19 @@ function watchProject(options) {
|
|
|
22502
22557
|
}
|
|
22503
22558
|
// src/migrations.ts
|
|
22504
22559
|
import { rename as rename5, readFile as readFile9, writeFile as writeFile4, rm as rm3 } from "node:fs/promises";
|
|
22505
|
-
import { relative as relative11, resolve as
|
|
22560
|
+
import { relative as relative11, resolve as resolve17 } from "node:path";
|
|
22506
22561
|
import * as ts16 from "@typescript/typescript6";
|
|
22507
22562
|
|
|
22508
22563
|
// src/migration-policy.ts
|
|
22509
22564
|
import { readFile as readFile8 } from "node:fs/promises";
|
|
22510
22565
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
22511
|
-
import { resolve as
|
|
22566
|
+
import { resolve as resolve16 } from "node:path";
|
|
22512
22567
|
|
|
22513
22568
|
// src/migration-app-version.ts
|
|
22514
22569
|
var MIGRATION_APP_VERSION = "0.23.0";
|
|
22515
22570
|
|
|
22516
22571
|
// src/migration-elysia-version.ts
|
|
22517
|
-
var MIGRATION_ELYSIA_VERSION = "0.
|
|
22572
|
+
var MIGRATION_ELYSIA_VERSION = "0.26.0";
|
|
22518
22573
|
|
|
22519
22574
|
// src/migration-policy.ts
|
|
22520
22575
|
var cachedCompilerVersion;
|
|
@@ -22541,7 +22596,7 @@ async function checkMigrationDependencies(rootDir) {
|
|
|
22541
22596
|
const problems = [];
|
|
22542
22597
|
for (const [name, expected] of Object.entries(migrationDependencies())) {
|
|
22543
22598
|
try {
|
|
22544
|
-
const manifest = JSON.parse(await readFile8(
|
|
22599
|
+
const manifest = JSON.parse(await readFile8(resolve16(rootDir, "node_modules", name, "package.json"), "utf8"));
|
|
22545
22600
|
if (!manifest || typeof manifest !== "object" || !("name" in manifest) || manifest.name !== name || !("version" in manifest) || manifest.version !== expected) {
|
|
22546
22601
|
problems.push(`${name}: requires tested installed version ${expected}`);
|
|
22547
22602
|
}
|
|
@@ -22656,10 +22711,10 @@ function createMigrationProgram(fileNames, sourceOverrides, rootDir) {
|
|
|
22656
22711
|
const fileExists = host.fileExists.bind(host);
|
|
22657
22712
|
const readFile = host.readFile.bind(host);
|
|
22658
22713
|
const currentDirectory = host.getCurrentDirectory.bind(host);
|
|
22659
|
-
host.fileExists = (fileName) => sourceOverrides.has(
|
|
22660
|
-
host.readFile = (fileName) => sourceOverrides.get(
|
|
22714
|
+
host.fileExists = (fileName) => sourceOverrides.has(resolve17(fileName)) || fileExists(fileName);
|
|
22715
|
+
host.readFile = (fileName) => sourceOverrides.get(resolve17(fileName)) ?? readFile(fileName);
|
|
22661
22716
|
host.getSourceFile = (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {
|
|
22662
|
-
const source = sourceOverrides.get(
|
|
22717
|
+
const source = sourceOverrides.get(resolve17(fileName));
|
|
22663
22718
|
return source === undefined ? getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile) : ts16.createSourceFile(fileName, source, languageVersion, true);
|
|
22664
22719
|
};
|
|
22665
22720
|
host.getCurrentDirectory = () => rootDir ?? currentDirectory();
|
|
@@ -22685,7 +22740,7 @@ function planRouteResponseMigration(sourceFiles, checker, rootDir, includedFiles
|
|
|
22685
22740
|
issues.push(issue);
|
|
22686
22741
|
};
|
|
22687
22742
|
for (const sourceFile of sourceFiles) {
|
|
22688
|
-
const sourcePath =
|
|
22743
|
+
const sourcePath = resolve17(sourceFile.fileName);
|
|
22689
22744
|
if (!includedFiles.has(sourcePath))
|
|
22690
22745
|
continue;
|
|
22691
22746
|
const visit = (node) => {
|
|
@@ -22693,7 +22748,7 @@ function planRouteResponseMigration(sourceFiles, checker, rootDir, includedFiles
|
|
|
22693
22748
|
const options = node.arguments[1];
|
|
22694
22749
|
const object = options && resolveStaticObjectLiteral2(options, checker);
|
|
22695
22750
|
if (object) {
|
|
22696
|
-
const objectPath =
|
|
22751
|
+
const objectPath = resolve17(object.getSourceFile().fileName);
|
|
22697
22752
|
const properties = routeResponseProperties(object);
|
|
22698
22753
|
if (properties.response) {
|
|
22699
22754
|
if (!includedFiles.has(objectPath)) {
|
|
@@ -22736,13 +22791,13 @@ function planRouteResponseMigration(sourceFiles, checker, rootDir, includedFiles
|
|
|
22736
22791
|
line: lineOf2(sourceFile, response)
|
|
22737
22792
|
});
|
|
22738
22793
|
} else {
|
|
22739
|
-
const replacements = replacementsByFile.get(
|
|
22794
|
+
const replacements = replacementsByFile.get(resolve17(sourceFile.fileName)) ?? [];
|
|
22740
22795
|
replacements.push({
|
|
22741
22796
|
start: response.getStart(sourceFile),
|
|
22742
22797
|
end: response.getEnd(),
|
|
22743
22798
|
text: `responses: { 200: ${response.initializer.getText(sourceFile)} }`
|
|
22744
22799
|
});
|
|
22745
|
-
replacementsByFile.set(
|
|
22800
|
+
replacementsByFile.set(resolve17(sourceFile.fileName), replacements);
|
|
22746
22801
|
}
|
|
22747
22802
|
}
|
|
22748
22803
|
return { replacementsByFile, issues };
|
|
@@ -22755,7 +22810,7 @@ function applyReplacements(source, replacements) {
|
|
|
22755
22810
|
return content;
|
|
22756
22811
|
}
|
|
22757
22812
|
function migrateRouteResponse(source, fileName) {
|
|
22758
|
-
const absoluteFile =
|
|
22813
|
+
const absoluteFile = resolve17(fileName);
|
|
22759
22814
|
const sourceOverrides = new Map([[absoluteFile, source]]);
|
|
22760
22815
|
const program = createMigrationProgram([absoluteFile], sourceOverrides);
|
|
22761
22816
|
const sourceFile = program.getSourceFile(absoluteFile);
|
|
@@ -22771,7 +22826,7 @@ function migrateRouteResponse(source, fileName) {
|
|
|
22771
22826
|
}]
|
|
22772
22827
|
};
|
|
22773
22828
|
}
|
|
22774
|
-
const plan = planRouteResponseMigration([sourceFile], program.getTypeChecker(),
|
|
22829
|
+
const plan = planRouteResponseMigration([sourceFile], program.getTypeChecker(), resolve17("."), new Set([absoluteFile]));
|
|
22775
22830
|
const replacements = plan.replacementsByFile.get(absoluteFile) ?? [];
|
|
22776
22831
|
return {
|
|
22777
22832
|
changed: replacements.length > 0,
|
|
@@ -22781,7 +22836,7 @@ function migrateRouteResponse(source, fileName) {
|
|
|
22781
22836
|
};
|
|
22782
22837
|
}
|
|
22783
22838
|
function migrateRouteResponseProject(files, rootDir, sourceByPath) {
|
|
22784
|
-
const absoluteFiles = files.map((file) =>
|
|
22839
|
+
const absoluteFiles = files.map((file) => resolve17(file));
|
|
22785
22840
|
const program = createMigrationProgram(absoluteFiles, sourceByPath, rootDir);
|
|
22786
22841
|
const sourceFiles = absoluteFiles.map((file) => program.getSourceFile(file)).filter((file) => file !== undefined);
|
|
22787
22842
|
const plan = planRouteResponseMigration(sourceFiles, program.getTypeChecker(), rootDir, new Set(absoluteFiles));
|
|
@@ -22794,11 +22849,11 @@ function migrateRouteResponseProject(files, rootDir, sourceByPath) {
|
|
|
22794
22849
|
changed: replacements.length > 0,
|
|
22795
22850
|
content: applyReplacements(source, replacements),
|
|
22796
22851
|
replacements: replacements.length,
|
|
22797
|
-
issues: plan.issues.filter((issue) =>
|
|
22852
|
+
issues: plan.issues.filter((issue) => resolve17(rootDir, issue.file) === file)
|
|
22798
22853
|
});
|
|
22799
22854
|
}
|
|
22800
22855
|
for (const issue of plan.issues) {
|
|
22801
|
-
const path =
|
|
22856
|
+
const path = resolve17(rootDir, issue.file);
|
|
22802
22857
|
if (!results.has(path) && sourceByPath.has(path)) {
|
|
22803
22858
|
results.set(path, {
|
|
22804
22859
|
changed: false,
|
|
@@ -22836,7 +22891,7 @@ async function writeAtomically(path, content) {
|
|
|
22836
22891
|
}
|
|
22837
22892
|
}
|
|
22838
22893
|
async function migrateProject(options) {
|
|
22839
|
-
const rootDir =
|
|
22894
|
+
const rootDir = resolve17(options.rootDir);
|
|
22840
22895
|
let migrations = SUPACLOUD_MIGRATIONS;
|
|
22841
22896
|
const preflightIssues = [];
|
|
22842
22897
|
if (options.fromVersion !== undefined || options.toVersion !== undefined) {
|
|
@@ -22892,7 +22947,7 @@ async function migrateProject(options) {
|
|
|
22892
22947
|
}
|
|
22893
22948
|
};
|
|
22894
22949
|
for (const filePath of files) {
|
|
22895
|
-
sourceByPath.set(
|
|
22950
|
+
sourceByPath.set(resolve17(filePath), await readFile9(filePath, "utf8"));
|
|
22896
22951
|
}
|
|
22897
22952
|
const originalSources = new Map(sourceByPath);
|
|
22898
22953
|
const writtenFiles = new Set;
|
|
@@ -22901,7 +22956,7 @@ async function migrateProject(options) {
|
|
|
22901
22956
|
if (projectResults)
|
|
22902
22957
|
appendIssues(projectResults.issues);
|
|
22903
22958
|
for (const filePath of files) {
|
|
22904
|
-
const absoluteFile =
|
|
22959
|
+
const absoluteFile = resolve17(filePath);
|
|
22905
22960
|
const file = relative11(rootDir, absoluteFile) || absoluteFile;
|
|
22906
22961
|
const before = sourceByPath.get(absoluteFile);
|
|
22907
22962
|
if (before === undefined)
|
|
@@ -22962,11 +23017,11 @@ async function migrateProject(options) {
|
|
|
22962
23017
|
// src/migration-assess.ts
|
|
22963
23018
|
import { createHash as createHash10 } from "node:crypto";
|
|
22964
23019
|
import { readFile as readFile11 } from "node:fs/promises";
|
|
22965
|
-
import { join as join10, resolve as
|
|
23020
|
+
import { join as join10, resolve as resolve19 } from "node:path";
|
|
22966
23021
|
|
|
22967
23022
|
// src/openapi-tools.ts
|
|
22968
23023
|
import { mkdir as mkdir4, readFile as readFile10, rename as rename6, unlink as unlink3, writeFile as writeFile5 } from "node:fs/promises";
|
|
22969
|
-
import { dirname as dirname10, resolve as
|
|
23024
|
+
import { dirname as dirname10, resolve as resolve18 } from "node:path";
|
|
22970
23025
|
import { pathToFileURL } from "node:url";
|
|
22971
23026
|
|
|
22972
23027
|
class OpenApiDocumentError extends Error {
|
|
@@ -23357,7 +23412,7 @@ function serializeOpenApiJson(document, space = 2) {
|
|
|
23357
23412
|
}
|
|
23358
23413
|
async function readOpenApiJson(path) {
|
|
23359
23414
|
try {
|
|
23360
|
-
const value = JSON.parse(await readFile10(
|
|
23415
|
+
const value = JSON.parse(await readFile10(resolve18(path), "utf8"));
|
|
23361
23416
|
return parseOpenApiDocument(value);
|
|
23362
23417
|
} catch (error) {
|
|
23363
23418
|
if (error instanceof OpenApiDocumentError)
|
|
@@ -23366,7 +23421,7 @@ async function readOpenApiJson(path) {
|
|
|
23366
23421
|
}
|
|
23367
23422
|
}
|
|
23368
23423
|
async function writeOpenApiJson(document, outputPath, space = 2) {
|
|
23369
|
-
const path =
|
|
23424
|
+
const path = resolve18(outputPath);
|
|
23370
23425
|
const content = serializeOpenApiJson(document, space);
|
|
23371
23426
|
await mkdir4(dirname10(path), { recursive: true });
|
|
23372
23427
|
try {
|
|
@@ -23387,7 +23442,7 @@ async function writeOpenApiJson(document, outputPath, space = 2) {
|
|
|
23387
23442
|
}
|
|
23388
23443
|
async function loadGeneratedOpenApiDocument(modulePath) {
|
|
23389
23444
|
try {
|
|
23390
|
-
const moduleUrl = pathToFileURL(
|
|
23445
|
+
const moduleUrl = pathToFileURL(resolve18(modulePath));
|
|
23391
23446
|
moduleUrl.searchParams.set("supacloud-openapi-export", "1");
|
|
23392
23447
|
const loaded = await import(moduleUrl.href);
|
|
23393
23448
|
if (!isRecord(loaded))
|
|
@@ -23490,11 +23545,11 @@ function overallStatus(findings) {
|
|
|
23490
23545
|
return findings.reduce((current, finding) => STATUS_PRIORITY[finding.status] > STATUS_PRIORITY[current] ? finding.status : current, "compatible");
|
|
23491
23546
|
}
|
|
23492
23547
|
async function assessMigration(options) {
|
|
23493
|
-
const projectDir =
|
|
23548
|
+
const projectDir = resolve19(options.projectDir);
|
|
23494
23549
|
const compile = {
|
|
23495
23550
|
...options.compile,
|
|
23496
|
-
rootDir:
|
|
23497
|
-
outDir:
|
|
23551
|
+
rootDir: resolve19(options.compile.rootDir),
|
|
23552
|
+
outDir: resolve19(options.compile.outDir)
|
|
23498
23553
|
};
|
|
23499
23554
|
const findings = [];
|
|
23500
23555
|
const dependencyProblems = await checkMigrationDependencies(projectDir);
|
|
@@ -23574,8 +23629,8 @@ async function assessMigration(options) {
|
|
|
23574
23629
|
}
|
|
23575
23630
|
let openApi;
|
|
23576
23631
|
if (options.baselineOpenApiPath && options.currentOpenApiPath) {
|
|
23577
|
-
const baselinePath =
|
|
23578
|
-
const currentPath =
|
|
23632
|
+
const baselinePath = resolve19(projectDir, options.baselineOpenApiPath);
|
|
23633
|
+
const currentPath = resolve19(projectDir, options.currentOpenApiPath);
|
|
23579
23634
|
try {
|
|
23580
23635
|
const diff = diffOpenApiDocuments(await readOpenApiJson(baselinePath), await readOpenApiJson(currentPath));
|
|
23581
23636
|
openApi = {
|
|
@@ -23664,7 +23719,7 @@ init_validate();
|
|
|
23664
23719
|
// src/config.ts
|
|
23665
23720
|
init_graphql_options();
|
|
23666
23721
|
import { existsSync as existsSync5 } from "node:fs";
|
|
23667
|
-
import { join as join11, resolve as
|
|
23722
|
+
import { join as join11, resolve as resolve20 } from "node:path";
|
|
23668
23723
|
import { pathToFileURL as pathToFileURL2 } from "node:url";
|
|
23669
23724
|
var DEFAULT_SUPACLOUD_CONFIG = {
|
|
23670
23725
|
graphql: false,
|
|
@@ -23757,8 +23812,8 @@ function validateGovernanceConfig(config) {
|
|
|
23757
23812
|
function resolveSupacloudConfig(config = {}, cwd = process.cwd()) {
|
|
23758
23813
|
const resolved = defineSupacloudConfig(config);
|
|
23759
23814
|
return {
|
|
23760
|
-
rootDir:
|
|
23761
|
-
outDir:
|
|
23815
|
+
rootDir: resolve20(cwd, resolved.root ?? DEFAULT_SUPACLOUD_CONFIG.root),
|
|
23816
|
+
outDir: resolve20(cwd, resolved.outDir ?? DEFAULT_SUPACLOUD_CONFIG.outDir),
|
|
23762
23817
|
include: resolved.include ?? [...DEFAULT_SUPACLOUD_CONFIG.include],
|
|
23763
23818
|
strict: resolved.strict ?? DEFAULT_SUPACLOUD_CONFIG.strict,
|
|
23764
23819
|
requireRouteContracts: resolved.requireRouteContracts ?? DEFAULT_SUPACLOUD_CONFIG.requireRouteContracts,
|
|
@@ -23776,7 +23831,7 @@ function resolveSupacloudConfig(config = {}, cwd = process.cwd()) {
|
|
|
23776
23831
|
treeShakeUnusedProviders: resolved.treeShakeUnusedProviders ?? DEFAULT_SUPACLOUD_CONFIG.treeShakeUnusedProviders,
|
|
23777
23832
|
graphql: resolved.graphql ? {
|
|
23778
23833
|
...resolved.graphql,
|
|
23779
|
-
schema:
|
|
23834
|
+
schema: resolve20(cwd, resolved.graphql.schema)
|
|
23780
23835
|
} : undefined
|
|
23781
23836
|
};
|
|
23782
23837
|
}
|