@supacloud/compiler 0.54.0 → 0.55.1
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 +5 -0
- package/dist/cli.js +115 -49
- package/dist/database-contract-manifest.d.ts +9 -0
- package/dist/database-contracts.d.ts +9 -27
- package/dist/index.d.ts +2 -0
- package/dist/index.js +117 -49
- package/dist/migration-app-version.d.ts +1 -1
- package/dist/migration-elysia-version.d.ts +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -85,6 +85,11 @@ attempts. The default policy requires `requireRouteEffects`,
|
|
|
85
85
|
|
|
86
86
|
## Unified Database Contracts
|
|
87
87
|
|
|
88
|
+
Database contracts are protocol-aware: configure only the database sources the
|
|
89
|
+
application uses (`postgrestTypes`, `drizzleSchema`, or `graphql`). The generated
|
|
90
|
+
`database.manifest.json` is a TypeBox-validated, fingerprinted build boundary;
|
|
91
|
+
consumers must reject it when its schema or migration fingerprint is stale.
|
|
92
|
+
|
|
88
93
|
`supacloud-compiler database-contracts database-contracts.json` generates a shared
|
|
89
94
|
type entry point while preserving PostgREST, Drizzle and GraphQL native types:
|
|
90
95
|
|
package/dist/cli.js
CHANGED
|
@@ -2123,6 +2123,9 @@ class ModuleGenerator {
|
|
|
2123
2123
|
const idempotency = route.idempotency ?? command?.idempotency ?? featureTransition?.idempotency;
|
|
2124
2124
|
const responseEntries = normalizedResponseEntries(route.responses);
|
|
2125
2125
|
const hasResponseMap = responseEntries.length > 0;
|
|
2126
|
+
const handlerParams = route.handlerParams ?? [];
|
|
2127
|
+
const needsContext = handlerParams.some((parameter) => parameter.kind === "context");
|
|
2128
|
+
const direct = factoryOfScope(controller.scope) === "services" && route.command === undefined && route.effect === undefined && (this.module.aspects?.length ?? 0) === 0 && !handlerParams.some((parameter) => parameter.kind === "cookie") && (route.aspects?.length ?? 0) === 0 && !hasResponseMap && route.parse !== "none" && !needsContext && (route.guards?.length ?? 0) === 0 && (route.canMatch?.length ?? 0) === 0 && (route.canDeactivate?.length ?? 0) === 0 && (route.resolvers === undefined || Object.keys(route.resolvers).length === 0) && (route.paramTransforms === undefined || Object.keys(route.paramTransforms).length === 0) && (route.queryTransforms === undefined || Object.keys(route.queryTransforms).length === 0) && (route.paramDefaults === undefined || Object.keys(route.paramDefaults).length === 0) && (route.queryDefaults === undefined || Object.keys(route.queryDefaults).length === 0);
|
|
2126
2129
|
const fields = [
|
|
2127
2130
|
`method: ${JSON.stringify(route.method)}`,
|
|
2128
2131
|
`path: ${JSON.stringify(route.path)}`,
|
|
@@ -2192,7 +2195,7 @@ class ModuleGenerator {
|
|
|
2192
2195
|
fields.push(`aspects: ${this.renderAspects(route.aspects)}`);
|
|
2193
2196
|
fields.push(`aspectPipeline: ${this.renderAspectPipeline(route.aspects)}`);
|
|
2194
2197
|
}
|
|
2195
|
-
const invokerArgs =
|
|
2198
|
+
const invokerArgs = handlerParams.map((hp) => {
|
|
2196
2199
|
if (hp.kind === "param") {
|
|
2197
2200
|
const accessor = `req.params?.[${JSON.stringify(hp.bindingName ?? hp.name)}]`;
|
|
2198
2201
|
const fallback = hp.default !== undefined ? JSON.stringify(hp.default) : "undefined";
|
|
@@ -2232,7 +2235,17 @@ class ModuleGenerator {
|
|
|
2232
2235
|
return "undefined";
|
|
2233
2236
|
});
|
|
2234
2237
|
const callArgs = invokerArgs.length > 0 ? invokerArgs.join(", ") : "req";
|
|
2235
|
-
fields.push(`invoker:
|
|
2238
|
+
fields.push(`invoker: (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 handler.call(ctrl, ${callArgs}); }`);
|
|
2239
|
+
if (direct) {
|
|
2240
|
+
const directArgs = invokerArgs.map((argument) => argument.replaceAll("req.", "context.").replaceAll("req)", "context)"));
|
|
2241
|
+
const directCallArgs = directArgs.length > 0 ? directArgs.join(", ") : "";
|
|
2242
|
+
const directContext = directArgs.length > 0 ? "const context = ctx as { params?: Record<string, unknown>; query?: Record<string, unknown>; body?: unknown; headers?: Record<string, unknown>; cookie?: Record<string, unknown>; context?: unknown }; " : "";
|
|
2243
|
+
fields.push(`directInvoker: (ctrl: unknown, ctx: 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"); ` + `${directContext}return handler.call(ctrl, ${directCallArgs}); }`);
|
|
2244
|
+
fields.push(`directInvokerFast: (ctrl: Record<string, unknown>, handler: (...args: unknown[]) => unknown, ctx: unknown) => { ` + `${directContext}return handler.call(ctrl, ${directCallArgs}); }`);
|
|
2245
|
+
fields.push('executionMode: "direct"');
|
|
2246
|
+
} else {
|
|
2247
|
+
fields.push('executionMode: "pipeline"');
|
|
2248
|
+
}
|
|
2236
2249
|
if (route.contract !== undefined) {
|
|
2237
2250
|
fields.push(`contract: ${JSON.stringify(route.contract)}`);
|
|
2238
2251
|
}
|
|
@@ -4068,7 +4081,7 @@ var HEADER = "// GENERATED BY @supacloud/compiler — do not edit", INTERFACES =
|
|
|
4068
4081
|
data?: Record<string, unknown>;
|
|
4069
4082
|
aspects?: CompiledAspect[];
|
|
4070
4083
|
aspectPipeline?: CompiledAspectPipeline;
|
|
4071
|
-
invoker
|
|
4084
|
+
invoker: (
|
|
4072
4085
|
controller: unknown,
|
|
4073
4086
|
request: {
|
|
4074
4087
|
params?: Record<string, unknown>;
|
|
@@ -4079,6 +4092,9 @@ var HEADER = "// GENERATED BY @supacloud/compiler — do not edit", INTERFACES =
|
|
|
4079
4092
|
context?: unknown;
|
|
4080
4093
|
},
|
|
4081
4094
|
) => Promise<unknown> | unknown;
|
|
4095
|
+
directInvoker?: (controller: unknown, context: unknown) => Promise<unknown> | unknown;
|
|
4096
|
+
directInvokerFast?: (controller: Record<string, unknown>, handler: (...args: unknown[]) => unknown, context: unknown) => Promise<unknown> | unknown;
|
|
4097
|
+
executionMode?: "direct" | "pipeline";
|
|
4082
4098
|
}
|
|
4083
4099
|
|
|
4084
4100
|
export interface CompiledCommand {
|
|
@@ -18187,6 +18203,27 @@ var init_release_evidence_cli = __esm(() => {
|
|
|
18187
18203
|
init_release_evidence();
|
|
18188
18204
|
});
|
|
18189
18205
|
|
|
18206
|
+
// src/database-contract-manifest.ts
|
|
18207
|
+
function parseDatabaseContractManifest(value) {
|
|
18208
|
+
if (!Check2(databaseContractManifestSchema, value)) {
|
|
18209
|
+
throw new TypeError("Invalid database contract manifest");
|
|
18210
|
+
}
|
|
18211
|
+
return value;
|
|
18212
|
+
}
|
|
18213
|
+
var databaseContractManifestSchema;
|
|
18214
|
+
var init_database_contract_manifest = __esm(() => {
|
|
18215
|
+
init_build();
|
|
18216
|
+
init_value2();
|
|
18217
|
+
databaseContractManifestSchema = _Object_({
|
|
18218
|
+
version: Literal(1),
|
|
18219
|
+
role: String2({ minLength: 1 }),
|
|
18220
|
+
fingerprint: String2({ pattern: "^[a-f0-9]{64}$" }),
|
|
18221
|
+
inputs: Record(String2({ minLength: 1 }), String2({ pattern: "^[a-f0-9]{64}$" })),
|
|
18222
|
+
migrationOrder: _Array_(String2({ minLength: 1 })),
|
|
18223
|
+
outputs: Record(String2({ minLength: 1 }), String2({ pattern: "^[a-f0-9]{64}$" }))
|
|
18224
|
+
});
|
|
18225
|
+
});
|
|
18226
|
+
|
|
18190
18227
|
// src/database-contracts.ts
|
|
18191
18228
|
import { createHash as createHash13 } from "node:crypto";
|
|
18192
18229
|
import { mkdir as mkdir5, readFile as readFile14 } from "node:fs/promises";
|
|
@@ -18211,8 +18248,23 @@ function parseDatabaseContractsOptions(value, directory) {
|
|
|
18211
18248
|
throw new TypeError(`Missing database contracts ${name}`);
|
|
18212
18249
|
return result;
|
|
18213
18250
|
};
|
|
18214
|
-
const
|
|
18215
|
-
|
|
18251
|
+
const optionalPath = (name) => {
|
|
18252
|
+
if (!Object.hasOwn(value, name))
|
|
18253
|
+
return;
|
|
18254
|
+
return field(name);
|
|
18255
|
+
};
|
|
18256
|
+
const postgrestTypes = optionalPath("postgrestTypes");
|
|
18257
|
+
const drizzleSchema = optionalPath("drizzleSchema");
|
|
18258
|
+
const graphqlPresent = Object.hasOwn(value, "graphql");
|
|
18259
|
+
if (!postgrestTypes && !drizzleSchema && !graphqlPresent) {
|
|
18260
|
+
throw new TypeError("Database contracts require postgrestTypes, drizzleSchema, or graphql");
|
|
18261
|
+
}
|
|
18262
|
+
let graphql;
|
|
18263
|
+
if (graphqlPresent) {
|
|
18264
|
+
const candidate = Reflect.get(value, "graphql");
|
|
18265
|
+
assertGraphqlOptions(candidate);
|
|
18266
|
+
graphql = { ...candidate, schema: resolve25(directory, candidate.schema) };
|
|
18267
|
+
}
|
|
18216
18268
|
const migrations = Reflect.get(value, "migrations");
|
|
18217
18269
|
if (!Array.isArray(migrations) || !migrations.every((entry) => typeof entry === "string" && entry.endsWith(".sql"))) {
|
|
18218
18270
|
throw new TypeError("migrations must be an ordered list of SQL files");
|
|
@@ -18220,22 +18272,20 @@ function parseDatabaseContractsOptions(value, directory) {
|
|
|
18220
18272
|
return {
|
|
18221
18273
|
rootDir: resolve25(directory, field("rootDir")),
|
|
18222
18274
|
outDir: resolve25(directory, field("outDir")),
|
|
18223
|
-
postgrestTypes: resolve25(directory,
|
|
18224
|
-
drizzleSchema: resolve25(directory,
|
|
18275
|
+
...postgrestTypes ? { postgrestTypes: resolve25(directory, postgrestTypes) } : {},
|
|
18276
|
+
...drizzleSchema ? { drizzleSchema: resolve25(directory, drizzleSchema) } : {},
|
|
18225
18277
|
role: field("role"),
|
|
18226
|
-
graphql
|
|
18278
|
+
...graphql ? { graphql } : {},
|
|
18227
18279
|
migrations: migrations.map((file) => resolve25(directory, file))
|
|
18228
18280
|
};
|
|
18229
18281
|
}
|
|
18230
|
-
async function
|
|
18231
|
-
const
|
|
18232
|
-
const
|
|
18233
|
-
const snapshot = await readFile14(postgrestTypes, "utf8");
|
|
18234
|
-
const syntax = ts18.createSourceFile(postgrestTypes, snapshot, ts18.ScriptTarget.Latest, true);
|
|
18282
|
+
async function assertPostgrestSnapshot(path) {
|
|
18283
|
+
const snapshot = await readFile14(path, "utf8");
|
|
18284
|
+
const syntax = ts18.createSourceFile(path, snapshot, ts18.ScriptTarget.Latest, true);
|
|
18235
18285
|
const database = syntax.statements.find((node) => (ts18.isTypeAliasDeclaration(node) || ts18.isInterfaceDeclaration(node)) && node.name.text === "Database" && node.modifiers?.some((modifier) => modifier.kind === ts18.SyntaxKind.ExportKeyword));
|
|
18236
18286
|
if (!database)
|
|
18237
18287
|
throw new Error("PostgREST snapshot must export Database from the official type generator");
|
|
18238
|
-
const program = ts18.createProgram([
|
|
18288
|
+
const program = ts18.createProgram([path], {
|
|
18239
18289
|
strict: true,
|
|
18240
18290
|
noEmit: true,
|
|
18241
18291
|
skipLibCheck: true,
|
|
@@ -18246,11 +18296,17 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
18246
18296
|
});
|
|
18247
18297
|
if (ts18.getPreEmitDiagnostics(program).length)
|
|
18248
18298
|
throw new Error("PostgREST snapshot has TypeScript errors");
|
|
18249
|
-
|
|
18250
|
-
|
|
18251
|
-
|
|
18252
|
-
|
|
18253
|
-
|
|
18299
|
+
}
|
|
18300
|
+
async function generateDatabaseContracts(options, check = false) {
|
|
18301
|
+
const rootDir = resolve25(options.rootDir), outDir = resolve25(options.outDir);
|
|
18302
|
+
const postgrestTypes = options.postgrestTypes ? resolve25(rootDir, options.postgrestTypes) : undefined;
|
|
18303
|
+
const drizzleSchema = options.drizzleSchema ? resolve25(rootDir, options.drizzleSchema) : undefined;
|
|
18304
|
+
if (!postgrestTypes && !drizzleSchema && !options.graphql) {
|
|
18305
|
+
throw new TypeError("Database contracts require postgrestTypes, drizzleSchema, or graphql");
|
|
18306
|
+
}
|
|
18307
|
+
if (postgrestTypes)
|
|
18308
|
+
await assertPostgrestSnapshot(postgrestTypes);
|
|
18309
|
+
const artifacts = options.graphql ? await renderGraphql({ rootDir, outDir, graphql: options.graphql }) : { diagnostics: [], files: {} };
|
|
18254
18310
|
if (artifacts.diagnostics.some((item) => item.severity === "error")) {
|
|
18255
18311
|
throw new Error(artifacts.diagnostics.map((item) => item.message).join(`
|
|
18256
18312
|
`));
|
|
@@ -18260,38 +18316,42 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
18260
18316
|
const absolute = resolve25(rootDir, path);
|
|
18261
18317
|
inputs[relative13(rootDir, absolute).replaceAll("\\", "/")] = hash4(await readFile14(absolute, "utf8"));
|
|
18262
18318
|
};
|
|
18263
|
-
|
|
18264
|
-
|
|
18265
|
-
|
|
18266
|
-
|
|
18267
|
-
|
|
18268
|
-
|
|
18269
|
-
|
|
18270
|
-
|
|
18271
|
-
|
|
18272
|
-
|
|
18273
|
-
|
|
18274
|
-
|
|
18275
|
-
|
|
18319
|
+
if (postgrestTypes)
|
|
18320
|
+
await addInput(postgrestTypes);
|
|
18321
|
+
if (drizzleSchema) {
|
|
18322
|
+
await addInput(drizzleSchema);
|
|
18323
|
+
const drizzleProgram = ts18.createProgram([drizzleSchema], {
|
|
18324
|
+
noEmit: true,
|
|
18325
|
+
moduleResolution: ts18.ModuleResolutionKind.Bundler,
|
|
18326
|
+
module: ts18.ModuleKind.ESNext,
|
|
18327
|
+
target: ts18.ScriptTarget.ES2022,
|
|
18328
|
+
types: [],
|
|
18329
|
+
skipLibCheck: true
|
|
18330
|
+
});
|
|
18331
|
+
for (const source of drizzleProgram.getSourceFiles()) {
|
|
18332
|
+
if (!source.isDeclarationFile && !source.fileName.includes("/node_modules/"))
|
|
18333
|
+
await addInput(source.fileName);
|
|
18334
|
+
}
|
|
18276
18335
|
}
|
|
18277
|
-
|
|
18336
|
+
if (options.graphql)
|
|
18337
|
+
await addInput(resolve25(rootDir, options.graphql.schema));
|
|
18278
18338
|
if (new Set(options.migrations.map((path) => resolve25(rootDir, path))).size !== options.migrations.length) {
|
|
18279
18339
|
throw new Error("Duplicate migration in database contracts configuration");
|
|
18280
18340
|
}
|
|
18281
18341
|
for (const path of options.migrations)
|
|
18282
18342
|
await addInput(path);
|
|
18283
|
-
const
|
|
18284
|
-
|
|
18285
|
-
|
|
18286
|
-
|
|
18287
|
-
|
|
18288
|
-
|
|
18289
|
-
|
|
18290
|
-
|
|
18291
|
-
|
|
18292
|
-
|
|
18293
|
-
`
|
|
18294
|
-
|
|
18343
|
+
const barrel = ["// GENERATED BY @supacloud/compiler database-contracts. Do not edit."];
|
|
18344
|
+
if (postgrestTypes) {
|
|
18345
|
+
barrel.push(`export type { Database } from ${JSON.stringify(importPath(outDir, postgrestTypes))};`);
|
|
18346
|
+
barrel.push('export type { QueryData, QueryResult, QueryError } from "@supabase/supabase-js";');
|
|
18347
|
+
}
|
|
18348
|
+
if (drizzleSchema)
|
|
18349
|
+
barrel.push(`export type DrizzleSchema = typeof import(${JSON.stringify(importPath(outDir, drizzleSchema))});`);
|
|
18350
|
+
if (options.graphql)
|
|
18351
|
+
barrel.push('export * from "./graphql";');
|
|
18352
|
+
barrel.push("");
|
|
18353
|
+
const files = { ...artifacts.files, "database.ts": barrel.join(`
|
|
18354
|
+
`) };
|
|
18295
18355
|
const manifest = {
|
|
18296
18356
|
version: 1,
|
|
18297
18357
|
role: options.role,
|
|
@@ -18299,7 +18359,12 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
18299
18359
|
migrationOrder: options.migrations.map((path) => relative13(rootDir, resolve25(rootDir, path)).replaceAll("\\", "/")),
|
|
18300
18360
|
outputs: Object.fromEntries(Object.entries(files).sort(([a], [b]) => a.localeCompare(b)).map(([file, text]) => [file, hash4(text)]))
|
|
18301
18361
|
};
|
|
18302
|
-
|
|
18362
|
+
const fingerprint = hash4(JSON.stringify({
|
|
18363
|
+
inputs: manifest.inputs,
|
|
18364
|
+
migrationOrder: manifest.migrationOrder
|
|
18365
|
+
}));
|
|
18366
|
+
const typedManifest = parseDatabaseContractManifest({ ...manifest, fingerprint });
|
|
18367
|
+
files["database.manifest.json"] = JSON.stringify(typedManifest, null, 2) + `
|
|
18303
18368
|
`;
|
|
18304
18369
|
const mismatches = [];
|
|
18305
18370
|
for (const [file, content] of Object.entries(files)) {
|
|
@@ -18319,7 +18384,7 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
18319
18384
|
for (const [file, content] of Object.entries(files))
|
|
18320
18385
|
await writeFileIfChanged(resolve25(outDir, file), content);
|
|
18321
18386
|
}
|
|
18322
|
-
return { upToDate: mismatches.length === 0, mismatches, written: check ? [] : mismatches, manifest };
|
|
18387
|
+
return { upToDate: mismatches.length === 0, mismatches, written: check ? [] : mismatches, manifest: typedManifest };
|
|
18323
18388
|
}
|
|
18324
18389
|
async function runDatabaseContractsFile(path, check = false) {
|
|
18325
18390
|
const absolute = resolve25(path);
|
|
@@ -18330,6 +18395,7 @@ var init_database_contracts = __esm(() => {
|
|
|
18330
18395
|
init_graphql();
|
|
18331
18396
|
init_generate();
|
|
18332
18397
|
init_graphql_options();
|
|
18398
|
+
init_database_contract_manifest();
|
|
18333
18399
|
});
|
|
18334
18400
|
|
|
18335
18401
|
// src/graphql-schema.ts
|
|
@@ -25818,10 +25884,10 @@ import { readFileSync as readFileSync4 } from "node:fs";
|
|
|
25818
25884
|
import { resolve as resolve19 } from "node:path";
|
|
25819
25885
|
|
|
25820
25886
|
// src/migration-app-version.ts
|
|
25821
|
-
var MIGRATION_APP_VERSION = "0.36.
|
|
25887
|
+
var MIGRATION_APP_VERSION = "0.36.1";
|
|
25822
25888
|
|
|
25823
25889
|
// src/migration-elysia-version.ts
|
|
25824
|
-
var MIGRATION_ELYSIA_VERSION = "0.38.
|
|
25890
|
+
var MIGRATION_ELYSIA_VERSION = "0.38.2";
|
|
25825
25891
|
|
|
25826
25892
|
// src/migration-policy.ts
|
|
25827
25893
|
var cachedCompilerVersion;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface DatabaseContractManifest {
|
|
2
|
+
readonly version: 1;
|
|
3
|
+
readonly role: string;
|
|
4
|
+
readonly fingerprint: string;
|
|
5
|
+
readonly inputs: Readonly<Record<string, string>>;
|
|
6
|
+
readonly migrationOrder: readonly string[];
|
|
7
|
+
readonly outputs: Readonly<Record<string, string>>;
|
|
8
|
+
}
|
|
9
|
+
export declare function parseDatabaseContractManifest(value: unknown): DatabaseContractManifest;
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
import { type DatabaseContractManifest } from "./database-contract-manifest";
|
|
1
2
|
import type { GraphqlOptions } from "./types";
|
|
2
3
|
export interface DatabaseContractsOptions {
|
|
3
4
|
rootDir: string;
|
|
4
5
|
outDir: string;
|
|
5
|
-
/**
|
|
6
|
-
postgrestTypes
|
|
7
|
-
/**
|
|
8
|
-
drizzleSchema
|
|
6
|
+
/** Official PostgREST snapshot. Omit when the project does not use PostgREST. */
|
|
7
|
+
postgrestTypes?: string;
|
|
8
|
+
/** Drizzle query-builder module. Omit when the project does not use Drizzle. */
|
|
9
|
+
drizzleSchema?: string;
|
|
9
10
|
/** Explicit identity/role label for reviewing snapshot provenance. Not an authorization proof. */
|
|
10
11
|
role: string;
|
|
11
|
-
graphql
|
|
12
|
+
/** Role-scoped pg_graphql snapshot exported by graphql-schema. Omit when GraphQL is unused. */
|
|
13
|
+
graphql?: GraphqlOptions;
|
|
12
14
|
/** Ordered complete migration history. */
|
|
13
15
|
migrations: readonly string[];
|
|
14
16
|
}
|
|
@@ -18,31 +20,11 @@ export declare function generateDatabaseContracts(options: DatabaseContractsOpti
|
|
|
18
20
|
upToDate: boolean;
|
|
19
21
|
mismatches: string[];
|
|
20
22
|
written: string[];
|
|
21
|
-
manifest:
|
|
22
|
-
version: number;
|
|
23
|
-
role: string;
|
|
24
|
-
inputs: {
|
|
25
|
-
[k: string]: string;
|
|
26
|
-
};
|
|
27
|
-
migrationOrder: string[];
|
|
28
|
-
outputs: {
|
|
29
|
-
[k: string]: string;
|
|
30
|
-
};
|
|
31
|
-
};
|
|
23
|
+
manifest: DatabaseContractManifest;
|
|
32
24
|
}>;
|
|
33
25
|
export declare function runDatabaseContractsFile(path: string, check?: boolean): Promise<{
|
|
34
26
|
upToDate: boolean;
|
|
35
27
|
mismatches: string[];
|
|
36
28
|
written: string[];
|
|
37
|
-
manifest:
|
|
38
|
-
version: number;
|
|
39
|
-
role: string;
|
|
40
|
-
inputs: {
|
|
41
|
-
[k: string]: string;
|
|
42
|
-
};
|
|
43
|
-
migrationOrder: string[];
|
|
44
|
-
outputs: {
|
|
45
|
-
[k: string]: string;
|
|
46
|
-
};
|
|
47
|
-
};
|
|
29
|
+
manifest: DatabaseContractManifest;
|
|
48
30
|
}>;
|
package/dist/index.d.ts
CHANGED
|
@@ -60,3 +60,5 @@ export type { PullGraphqlSchemaOptions } from "./graphql-schema";
|
|
|
60
60
|
export { checkGraphqlCompatibility, createRoleSnapshotReport, diffGraphqlSchemas, graphqlFeatureMatrix, introspectionQuery, readGraphqlSchema, schemaFromSource, } from "./graphql-governance";
|
|
61
61
|
export type { GraphqlCompatibilityReport, GraphqlFeatureMatrix, GraphqlGovernanceDiagnostic, GraphqlGovernancePolicy, GraphqlOperationReport, GraphqlRoleSnapshot, GraphqlRoleSnapshotReport, GraphqlSchemaChange, GraphqlSchemaDiff, } from "./graphql-governance";
|
|
62
62
|
export { generateDatabaseContracts, parseDatabaseContractsOptions, runDatabaseContractsFile, type DatabaseContractsOptions } from "./database-contracts";
|
|
63
|
+
export { parseDatabaseContractManifest } from "./database-contract-manifest";
|
|
64
|
+
export type { DatabaseContractManifest } from "./database-contract-manifest";
|
package/dist/index.js
CHANGED
|
@@ -2122,6 +2122,9 @@ class ModuleGenerator {
|
|
|
2122
2122
|
const idempotency = route.idempotency ?? command?.idempotency ?? featureTransition?.idempotency;
|
|
2123
2123
|
const responseEntries = normalizedResponseEntries(route.responses);
|
|
2124
2124
|
const hasResponseMap = responseEntries.length > 0;
|
|
2125
|
+
const handlerParams = route.handlerParams ?? [];
|
|
2126
|
+
const needsContext = handlerParams.some((parameter) => parameter.kind === "context");
|
|
2127
|
+
const direct = factoryOfScope(controller.scope) === "services" && route.command === undefined && route.effect === undefined && (this.module.aspects?.length ?? 0) === 0 && !handlerParams.some((parameter) => parameter.kind === "cookie") && (route.aspects?.length ?? 0) === 0 && !hasResponseMap && route.parse !== "none" && !needsContext && (route.guards?.length ?? 0) === 0 && (route.canMatch?.length ?? 0) === 0 && (route.canDeactivate?.length ?? 0) === 0 && (route.resolvers === undefined || Object.keys(route.resolvers).length === 0) && (route.paramTransforms === undefined || Object.keys(route.paramTransforms).length === 0) && (route.queryTransforms === undefined || Object.keys(route.queryTransforms).length === 0) && (route.paramDefaults === undefined || Object.keys(route.paramDefaults).length === 0) && (route.queryDefaults === undefined || Object.keys(route.queryDefaults).length === 0);
|
|
2125
2128
|
const fields = [
|
|
2126
2129
|
`method: ${JSON.stringify(route.method)}`,
|
|
2127
2130
|
`path: ${JSON.stringify(route.path)}`,
|
|
@@ -2191,7 +2194,7 @@ class ModuleGenerator {
|
|
|
2191
2194
|
fields.push(`aspects: ${this.renderAspects(route.aspects)}`);
|
|
2192
2195
|
fields.push(`aspectPipeline: ${this.renderAspectPipeline(route.aspects)}`);
|
|
2193
2196
|
}
|
|
2194
|
-
const invokerArgs =
|
|
2197
|
+
const invokerArgs = handlerParams.map((hp) => {
|
|
2195
2198
|
if (hp.kind === "param") {
|
|
2196
2199
|
const accessor = `req.params?.[${JSON.stringify(hp.bindingName ?? hp.name)}]`;
|
|
2197
2200
|
const fallback = hp.default !== undefined ? JSON.stringify(hp.default) : "undefined";
|
|
@@ -2231,7 +2234,17 @@ class ModuleGenerator {
|
|
|
2231
2234
|
return "undefined";
|
|
2232
2235
|
});
|
|
2233
2236
|
const callArgs = invokerArgs.length > 0 ? invokerArgs.join(", ") : "req";
|
|
2234
|
-
fields.push(`invoker:
|
|
2237
|
+
fields.push(`invoker: (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 handler.call(ctrl, ${callArgs}); }`);
|
|
2238
|
+
if (direct) {
|
|
2239
|
+
const directArgs = invokerArgs.map((argument) => argument.replaceAll("req.", "context.").replaceAll("req)", "context)"));
|
|
2240
|
+
const directCallArgs = directArgs.length > 0 ? directArgs.join(", ") : "";
|
|
2241
|
+
const directContext = directArgs.length > 0 ? "const context = ctx as { params?: Record<string, unknown>; query?: Record<string, unknown>; body?: unknown; headers?: Record<string, unknown>; cookie?: Record<string, unknown>; context?: unknown }; " : "";
|
|
2242
|
+
fields.push(`directInvoker: (ctrl: unknown, ctx: 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"); ` + `${directContext}return handler.call(ctrl, ${directCallArgs}); }`);
|
|
2243
|
+
fields.push(`directInvokerFast: (ctrl: Record<string, unknown>, handler: (...args: unknown[]) => unknown, ctx: unknown) => { ` + `${directContext}return handler.call(ctrl, ${directCallArgs}); }`);
|
|
2244
|
+
fields.push('executionMode: "direct"');
|
|
2245
|
+
} else {
|
|
2246
|
+
fields.push('executionMode: "pipeline"');
|
|
2247
|
+
}
|
|
2235
2248
|
if (route.contract !== undefined) {
|
|
2236
2249
|
fields.push(`contract: ${JSON.stringify(route.contract)}`);
|
|
2237
2250
|
}
|
|
@@ -4067,7 +4080,7 @@ var HEADER = "// GENERATED BY @supacloud/compiler — do not edit", INTERFACES =
|
|
|
4067
4080
|
data?: Record<string, unknown>;
|
|
4068
4081
|
aspects?: CompiledAspect[];
|
|
4069
4082
|
aspectPipeline?: CompiledAspectPipeline;
|
|
4070
|
-
invoker
|
|
4083
|
+
invoker: (
|
|
4071
4084
|
controller: unknown,
|
|
4072
4085
|
request: {
|
|
4073
4086
|
params?: Record<string, unknown>;
|
|
@@ -4078,6 +4091,9 @@ var HEADER = "// GENERATED BY @supacloud/compiler — do not edit", INTERFACES =
|
|
|
4078
4091
|
context?: unknown;
|
|
4079
4092
|
},
|
|
4080
4093
|
) => Promise<unknown> | unknown;
|
|
4094
|
+
directInvoker?: (controller: unknown, context: unknown) => Promise<unknown> | unknown;
|
|
4095
|
+
directInvokerFast?: (controller: Record<string, unknown>, handler: (...args: unknown[]) => unknown, context: unknown) => Promise<unknown> | unknown;
|
|
4096
|
+
executionMode?: "direct" | "pipeline";
|
|
4081
4097
|
}
|
|
4082
4098
|
|
|
4083
4099
|
export interface CompiledCommand {
|
|
@@ -18219,6 +18235,27 @@ var init_graphql_schema = __esm(() => {
|
|
|
18219
18235
|
init_graphql_schema_hashes();
|
|
18220
18236
|
});
|
|
18221
18237
|
|
|
18238
|
+
// src/database-contract-manifest.ts
|
|
18239
|
+
function parseDatabaseContractManifest(value) {
|
|
18240
|
+
if (!Check2(databaseContractManifestSchema, value)) {
|
|
18241
|
+
throw new TypeError("Invalid database contract manifest");
|
|
18242
|
+
}
|
|
18243
|
+
return value;
|
|
18244
|
+
}
|
|
18245
|
+
var databaseContractManifestSchema;
|
|
18246
|
+
var init_database_contract_manifest = __esm(() => {
|
|
18247
|
+
init_build();
|
|
18248
|
+
init_value2();
|
|
18249
|
+
databaseContractManifestSchema = _Object_({
|
|
18250
|
+
version: Literal(1),
|
|
18251
|
+
role: String2({ minLength: 1 }),
|
|
18252
|
+
fingerprint: String2({ pattern: "^[a-f0-9]{64}$" }),
|
|
18253
|
+
inputs: Record(String2({ minLength: 1 }), String2({ pattern: "^[a-f0-9]{64}$" })),
|
|
18254
|
+
migrationOrder: _Array_(String2({ minLength: 1 })),
|
|
18255
|
+
outputs: Record(String2({ minLength: 1 }), String2({ pattern: "^[a-f0-9]{64}$" }))
|
|
18256
|
+
});
|
|
18257
|
+
});
|
|
18258
|
+
|
|
18222
18259
|
// src/database-contracts.ts
|
|
18223
18260
|
import { createHash as createHash12 } from "node:crypto";
|
|
18224
18261
|
import { mkdir as mkdir6, readFile as readFile14 } from "node:fs/promises";
|
|
@@ -18243,8 +18280,23 @@ function parseDatabaseContractsOptions(value, directory) {
|
|
|
18243
18280
|
throw new TypeError(`Missing database contracts ${name}`);
|
|
18244
18281
|
return result;
|
|
18245
18282
|
};
|
|
18246
|
-
const
|
|
18247
|
-
|
|
18283
|
+
const optionalPath = (name) => {
|
|
18284
|
+
if (!Object.hasOwn(value, name))
|
|
18285
|
+
return;
|
|
18286
|
+
return field(name);
|
|
18287
|
+
};
|
|
18288
|
+
const postgrestTypes = optionalPath("postgrestTypes");
|
|
18289
|
+
const drizzleSchema = optionalPath("drizzleSchema");
|
|
18290
|
+
const graphqlPresent = Object.hasOwn(value, "graphql");
|
|
18291
|
+
if (!postgrestTypes && !drizzleSchema && !graphqlPresent) {
|
|
18292
|
+
throw new TypeError("Database contracts require postgrestTypes, drizzleSchema, or graphql");
|
|
18293
|
+
}
|
|
18294
|
+
let graphql;
|
|
18295
|
+
if (graphqlPresent) {
|
|
18296
|
+
const candidate = Reflect.get(value, "graphql");
|
|
18297
|
+
assertGraphqlOptions(candidate);
|
|
18298
|
+
graphql = { ...candidate, schema: resolve24(directory, candidate.schema) };
|
|
18299
|
+
}
|
|
18248
18300
|
const migrations = Reflect.get(value, "migrations");
|
|
18249
18301
|
if (!Array.isArray(migrations) || !migrations.every((entry) => typeof entry === "string" && entry.endsWith(".sql"))) {
|
|
18250
18302
|
throw new TypeError("migrations must be an ordered list of SQL files");
|
|
@@ -18252,22 +18304,20 @@ function parseDatabaseContractsOptions(value, directory) {
|
|
|
18252
18304
|
return {
|
|
18253
18305
|
rootDir: resolve24(directory, field("rootDir")),
|
|
18254
18306
|
outDir: resolve24(directory, field("outDir")),
|
|
18255
|
-
postgrestTypes: resolve24(directory,
|
|
18256
|
-
drizzleSchema: resolve24(directory,
|
|
18307
|
+
...postgrestTypes ? { postgrestTypes: resolve24(directory, postgrestTypes) } : {},
|
|
18308
|
+
...drizzleSchema ? { drizzleSchema: resolve24(directory, drizzleSchema) } : {},
|
|
18257
18309
|
role: field("role"),
|
|
18258
|
-
graphql
|
|
18310
|
+
...graphql ? { graphql } : {},
|
|
18259
18311
|
migrations: migrations.map((file) => resolve24(directory, file))
|
|
18260
18312
|
};
|
|
18261
18313
|
}
|
|
18262
|
-
async function
|
|
18263
|
-
const
|
|
18264
|
-
const
|
|
18265
|
-
const snapshot = await readFile14(postgrestTypes, "utf8");
|
|
18266
|
-
const syntax = ts18.createSourceFile(postgrestTypes, snapshot, ts18.ScriptTarget.Latest, true);
|
|
18314
|
+
async function assertPostgrestSnapshot(path) {
|
|
18315
|
+
const snapshot = await readFile14(path, "utf8");
|
|
18316
|
+
const syntax = ts18.createSourceFile(path, snapshot, ts18.ScriptTarget.Latest, true);
|
|
18267
18317
|
const database = syntax.statements.find((node) => (ts18.isTypeAliasDeclaration(node) || ts18.isInterfaceDeclaration(node)) && node.name.text === "Database" && node.modifiers?.some((modifier) => modifier.kind === ts18.SyntaxKind.ExportKeyword));
|
|
18268
18318
|
if (!database)
|
|
18269
18319
|
throw new Error("PostgREST snapshot must export Database from the official type generator");
|
|
18270
|
-
const program = ts18.createProgram([
|
|
18320
|
+
const program = ts18.createProgram([path], {
|
|
18271
18321
|
strict: true,
|
|
18272
18322
|
noEmit: true,
|
|
18273
18323
|
skipLibCheck: true,
|
|
@@ -18278,11 +18328,17 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
18278
18328
|
});
|
|
18279
18329
|
if (ts18.getPreEmitDiagnostics(program).length)
|
|
18280
18330
|
throw new Error("PostgREST snapshot has TypeScript errors");
|
|
18281
|
-
|
|
18282
|
-
|
|
18283
|
-
|
|
18284
|
-
|
|
18285
|
-
|
|
18331
|
+
}
|
|
18332
|
+
async function generateDatabaseContracts(options, check = false) {
|
|
18333
|
+
const rootDir = resolve24(options.rootDir), outDir = resolve24(options.outDir);
|
|
18334
|
+
const postgrestTypes = options.postgrestTypes ? resolve24(rootDir, options.postgrestTypes) : undefined;
|
|
18335
|
+
const drizzleSchema = options.drizzleSchema ? resolve24(rootDir, options.drizzleSchema) : undefined;
|
|
18336
|
+
if (!postgrestTypes && !drizzleSchema && !options.graphql) {
|
|
18337
|
+
throw new TypeError("Database contracts require postgrestTypes, drizzleSchema, or graphql");
|
|
18338
|
+
}
|
|
18339
|
+
if (postgrestTypes)
|
|
18340
|
+
await assertPostgrestSnapshot(postgrestTypes);
|
|
18341
|
+
const artifacts = options.graphql ? await renderGraphql({ rootDir, outDir, graphql: options.graphql }) : { diagnostics: [], files: {} };
|
|
18286
18342
|
if (artifacts.diagnostics.some((item) => item.severity === "error")) {
|
|
18287
18343
|
throw new Error(artifacts.diagnostics.map((item) => item.message).join(`
|
|
18288
18344
|
`));
|
|
@@ -18292,38 +18348,42 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
18292
18348
|
const absolute = resolve24(rootDir, path);
|
|
18293
18349
|
inputs[relative12(rootDir, absolute).replaceAll("\\", "/")] = hash4(await readFile14(absolute, "utf8"));
|
|
18294
18350
|
};
|
|
18295
|
-
|
|
18296
|
-
|
|
18297
|
-
|
|
18298
|
-
|
|
18299
|
-
|
|
18300
|
-
|
|
18301
|
-
|
|
18302
|
-
|
|
18303
|
-
|
|
18304
|
-
|
|
18305
|
-
|
|
18306
|
-
|
|
18307
|
-
|
|
18351
|
+
if (postgrestTypes)
|
|
18352
|
+
await addInput(postgrestTypes);
|
|
18353
|
+
if (drizzleSchema) {
|
|
18354
|
+
await addInput(drizzleSchema);
|
|
18355
|
+
const drizzleProgram = ts18.createProgram([drizzleSchema], {
|
|
18356
|
+
noEmit: true,
|
|
18357
|
+
moduleResolution: ts18.ModuleResolutionKind.Bundler,
|
|
18358
|
+
module: ts18.ModuleKind.ESNext,
|
|
18359
|
+
target: ts18.ScriptTarget.ES2022,
|
|
18360
|
+
types: [],
|
|
18361
|
+
skipLibCheck: true
|
|
18362
|
+
});
|
|
18363
|
+
for (const source of drizzleProgram.getSourceFiles()) {
|
|
18364
|
+
if (!source.isDeclarationFile && !source.fileName.includes("/node_modules/"))
|
|
18365
|
+
await addInput(source.fileName);
|
|
18366
|
+
}
|
|
18308
18367
|
}
|
|
18309
|
-
|
|
18368
|
+
if (options.graphql)
|
|
18369
|
+
await addInput(resolve24(rootDir, options.graphql.schema));
|
|
18310
18370
|
if (new Set(options.migrations.map((path) => resolve24(rootDir, path))).size !== options.migrations.length) {
|
|
18311
18371
|
throw new Error("Duplicate migration in database contracts configuration");
|
|
18312
18372
|
}
|
|
18313
18373
|
for (const path of options.migrations)
|
|
18314
18374
|
await addInput(path);
|
|
18315
|
-
const
|
|
18316
|
-
|
|
18317
|
-
|
|
18318
|
-
|
|
18319
|
-
|
|
18320
|
-
|
|
18321
|
-
|
|
18322
|
-
|
|
18323
|
-
|
|
18324
|
-
|
|
18325
|
-
`
|
|
18326
|
-
|
|
18375
|
+
const barrel = ["// GENERATED BY @supacloud/compiler database-contracts. Do not edit."];
|
|
18376
|
+
if (postgrestTypes) {
|
|
18377
|
+
barrel.push(`export type { Database } from ${JSON.stringify(importPath(outDir, postgrestTypes))};`);
|
|
18378
|
+
barrel.push('export type { QueryData, QueryResult, QueryError } from "@supabase/supabase-js";');
|
|
18379
|
+
}
|
|
18380
|
+
if (drizzleSchema)
|
|
18381
|
+
barrel.push(`export type DrizzleSchema = typeof import(${JSON.stringify(importPath(outDir, drizzleSchema))});`);
|
|
18382
|
+
if (options.graphql)
|
|
18383
|
+
barrel.push('export * from "./graphql";');
|
|
18384
|
+
barrel.push("");
|
|
18385
|
+
const files = { ...artifacts.files, "database.ts": barrel.join(`
|
|
18386
|
+
`) };
|
|
18327
18387
|
const manifest = {
|
|
18328
18388
|
version: 1,
|
|
18329
18389
|
role: options.role,
|
|
@@ -18331,7 +18391,12 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
18331
18391
|
migrationOrder: options.migrations.map((path) => relative12(rootDir, resolve24(rootDir, path)).replaceAll("\\", "/")),
|
|
18332
18392
|
outputs: Object.fromEntries(Object.entries(files).sort(([a], [b]) => a.localeCompare(b)).map(([file, text]) => [file, hash4(text)]))
|
|
18333
18393
|
};
|
|
18334
|
-
|
|
18394
|
+
const fingerprint = hash4(JSON.stringify({
|
|
18395
|
+
inputs: manifest.inputs,
|
|
18396
|
+
migrationOrder: manifest.migrationOrder
|
|
18397
|
+
}));
|
|
18398
|
+
const typedManifest = parseDatabaseContractManifest({ ...manifest, fingerprint });
|
|
18399
|
+
files["database.manifest.json"] = JSON.stringify(typedManifest, null, 2) + `
|
|
18335
18400
|
`;
|
|
18336
18401
|
const mismatches = [];
|
|
18337
18402
|
for (const [file, content] of Object.entries(files)) {
|
|
@@ -18351,7 +18416,7 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
18351
18416
|
for (const [file, content] of Object.entries(files))
|
|
18352
18417
|
await writeFileIfChanged(resolve24(outDir, file), content);
|
|
18353
18418
|
}
|
|
18354
|
-
return { upToDate: mismatches.length === 0, mismatches, written: check ? [] : mismatches, manifest };
|
|
18419
|
+
return { upToDate: mismatches.length === 0, mismatches, written: check ? [] : mismatches, manifest: typedManifest };
|
|
18355
18420
|
}
|
|
18356
18421
|
async function runDatabaseContractsFile(path, check = false) {
|
|
18357
18422
|
const absolute = resolve24(path);
|
|
@@ -18362,6 +18427,7 @@ var init_database_contracts = __esm(() => {
|
|
|
18362
18427
|
init_graphql();
|
|
18363
18428
|
init_generate();
|
|
18364
18429
|
init_graphql_options();
|
|
18430
|
+
init_database_contract_manifest();
|
|
18365
18431
|
});
|
|
18366
18432
|
|
|
18367
18433
|
// src/analyze.ts
|
|
@@ -25070,10 +25136,10 @@ import { readFileSync as readFileSync4 } from "node:fs";
|
|
|
25070
25136
|
import { resolve as resolve17 } from "node:path";
|
|
25071
25137
|
|
|
25072
25138
|
// src/migration-app-version.ts
|
|
25073
|
-
var MIGRATION_APP_VERSION = "0.36.
|
|
25139
|
+
var MIGRATION_APP_VERSION = "0.36.1";
|
|
25074
25140
|
|
|
25075
25141
|
// src/migration-elysia-version.ts
|
|
25076
|
-
var MIGRATION_ELYSIA_VERSION = "0.38.
|
|
25142
|
+
var MIGRATION_ELYSIA_VERSION = "0.38.2";
|
|
25077
25143
|
|
|
25078
25144
|
// src/migration-policy.ts
|
|
25079
25145
|
var cachedCompilerVersion;
|
|
@@ -26869,6 +26935,7 @@ function introspectionQuery() {
|
|
|
26869
26935
|
|
|
26870
26936
|
// src/index.ts
|
|
26871
26937
|
init_database_contracts();
|
|
26938
|
+
init_database_contract_manifest();
|
|
26872
26939
|
export {
|
|
26873
26940
|
ANGULAR_ENTERPRISE_RULES,
|
|
26874
26941
|
APPLICATION_DEVELOPMENT_ARCHIVE_MAX_BYTES2 as APPLICATION_DEVELOPMENT_ARCHIVE_MAX_BYTES,
|
|
@@ -26955,6 +27022,7 @@ export {
|
|
|
26955
27022
|
migrateProject,
|
|
26956
27023
|
migrateRouteResponse,
|
|
26957
27024
|
parseApplicationDevelopmentContext,
|
|
27025
|
+
parseDatabaseContractManifest,
|
|
26958
27026
|
parseDatabaseContractsOptions,
|
|
26959
27027
|
parseDeliveryBuildManifest,
|
|
26960
27028
|
parseDeliveryBuildResult,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const MIGRATION_APP_VERSION = "0.36.
|
|
1
|
+
export declare const MIGRATION_APP_VERSION = "0.36.1";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const MIGRATION_ELYSIA_VERSION = "0.38.
|
|
1
|
+
export declare const MIGRATION_ELYSIA_VERSION = "0.38.2";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supacloud/compiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.55.1",
|
|
4
4
|
"description": "Static compiler for @supacloud/app metadata: builds the application graph from AST, validates it, and generates reflection-free factory code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"directory": "packages/compiler"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@supacloud/db": "0.20.
|
|
60
|
+
"@supacloud/db": "0.20.5",
|
|
61
61
|
"@supacloud/delivery": "0.24.0",
|
|
62
62
|
"typebox": "1.4.3",
|
|
63
63
|
"@graphql-codegen/core": "^6.2.2",
|