@supacloud/compiler 0.54.0 → 0.55.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 +5 -0
- package/dist/cli.js +95 -45
- 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 +97 -45
- 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
|
@@ -18187,6 +18187,27 @@ var init_release_evidence_cli = __esm(() => {
|
|
|
18187
18187
|
init_release_evidence();
|
|
18188
18188
|
});
|
|
18189
18189
|
|
|
18190
|
+
// src/database-contract-manifest.ts
|
|
18191
|
+
function parseDatabaseContractManifest(value) {
|
|
18192
|
+
if (!Check2(databaseContractManifestSchema, value)) {
|
|
18193
|
+
throw new TypeError("Invalid database contract manifest");
|
|
18194
|
+
}
|
|
18195
|
+
return value;
|
|
18196
|
+
}
|
|
18197
|
+
var databaseContractManifestSchema;
|
|
18198
|
+
var init_database_contract_manifest = __esm(() => {
|
|
18199
|
+
init_build();
|
|
18200
|
+
init_value2();
|
|
18201
|
+
databaseContractManifestSchema = _Object_({
|
|
18202
|
+
version: Literal(1),
|
|
18203
|
+
role: String2({ minLength: 1 }),
|
|
18204
|
+
fingerprint: String2({ pattern: "^[a-f0-9]{64}$" }),
|
|
18205
|
+
inputs: Record(String2({ minLength: 1 }), String2({ pattern: "^[a-f0-9]{64}$" })),
|
|
18206
|
+
migrationOrder: _Array_(String2({ minLength: 1 })),
|
|
18207
|
+
outputs: Record(String2({ minLength: 1 }), String2({ pattern: "^[a-f0-9]{64}$" }))
|
|
18208
|
+
});
|
|
18209
|
+
});
|
|
18210
|
+
|
|
18190
18211
|
// src/database-contracts.ts
|
|
18191
18212
|
import { createHash as createHash13 } from "node:crypto";
|
|
18192
18213
|
import { mkdir as mkdir5, readFile as readFile14 } from "node:fs/promises";
|
|
@@ -18211,8 +18232,23 @@ function parseDatabaseContractsOptions(value, directory) {
|
|
|
18211
18232
|
throw new TypeError(`Missing database contracts ${name}`);
|
|
18212
18233
|
return result;
|
|
18213
18234
|
};
|
|
18214
|
-
const
|
|
18215
|
-
|
|
18235
|
+
const optionalPath = (name) => {
|
|
18236
|
+
if (!Object.hasOwn(value, name))
|
|
18237
|
+
return;
|
|
18238
|
+
return field(name);
|
|
18239
|
+
};
|
|
18240
|
+
const postgrestTypes = optionalPath("postgrestTypes");
|
|
18241
|
+
const drizzleSchema = optionalPath("drizzleSchema");
|
|
18242
|
+
const graphqlPresent = Object.hasOwn(value, "graphql");
|
|
18243
|
+
if (!postgrestTypes && !drizzleSchema && !graphqlPresent) {
|
|
18244
|
+
throw new TypeError("Database contracts require postgrestTypes, drizzleSchema, or graphql");
|
|
18245
|
+
}
|
|
18246
|
+
let graphql;
|
|
18247
|
+
if (graphqlPresent) {
|
|
18248
|
+
const candidate = Reflect.get(value, "graphql");
|
|
18249
|
+
assertGraphqlOptions(candidate);
|
|
18250
|
+
graphql = { ...candidate, schema: resolve25(directory, candidate.schema) };
|
|
18251
|
+
}
|
|
18216
18252
|
const migrations = Reflect.get(value, "migrations");
|
|
18217
18253
|
if (!Array.isArray(migrations) || !migrations.every((entry) => typeof entry === "string" && entry.endsWith(".sql"))) {
|
|
18218
18254
|
throw new TypeError("migrations must be an ordered list of SQL files");
|
|
@@ -18220,22 +18256,20 @@ function parseDatabaseContractsOptions(value, directory) {
|
|
|
18220
18256
|
return {
|
|
18221
18257
|
rootDir: resolve25(directory, field("rootDir")),
|
|
18222
18258
|
outDir: resolve25(directory, field("outDir")),
|
|
18223
|
-
postgrestTypes: resolve25(directory,
|
|
18224
|
-
drizzleSchema: resolve25(directory,
|
|
18259
|
+
...postgrestTypes ? { postgrestTypes: resolve25(directory, postgrestTypes) } : {},
|
|
18260
|
+
...drizzleSchema ? { drizzleSchema: resolve25(directory, drizzleSchema) } : {},
|
|
18225
18261
|
role: field("role"),
|
|
18226
|
-
graphql
|
|
18262
|
+
...graphql ? { graphql } : {},
|
|
18227
18263
|
migrations: migrations.map((file) => resolve25(directory, file))
|
|
18228
18264
|
};
|
|
18229
18265
|
}
|
|
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);
|
|
18266
|
+
async function assertPostgrestSnapshot(path) {
|
|
18267
|
+
const snapshot = await readFile14(path, "utf8");
|
|
18268
|
+
const syntax = ts18.createSourceFile(path, snapshot, ts18.ScriptTarget.Latest, true);
|
|
18235
18269
|
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
18270
|
if (!database)
|
|
18237
18271
|
throw new Error("PostgREST snapshot must export Database from the official type generator");
|
|
18238
|
-
const program = ts18.createProgram([
|
|
18272
|
+
const program = ts18.createProgram([path], {
|
|
18239
18273
|
strict: true,
|
|
18240
18274
|
noEmit: true,
|
|
18241
18275
|
skipLibCheck: true,
|
|
@@ -18246,11 +18280,17 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
18246
18280
|
});
|
|
18247
18281
|
if (ts18.getPreEmitDiagnostics(program).length)
|
|
18248
18282
|
throw new Error("PostgREST snapshot has TypeScript errors");
|
|
18249
|
-
|
|
18250
|
-
|
|
18251
|
-
|
|
18252
|
-
|
|
18253
|
-
|
|
18283
|
+
}
|
|
18284
|
+
async function generateDatabaseContracts(options, check = false) {
|
|
18285
|
+
const rootDir = resolve25(options.rootDir), outDir = resolve25(options.outDir);
|
|
18286
|
+
const postgrestTypes = options.postgrestTypes ? resolve25(rootDir, options.postgrestTypes) : undefined;
|
|
18287
|
+
const drizzleSchema = options.drizzleSchema ? resolve25(rootDir, options.drizzleSchema) : undefined;
|
|
18288
|
+
if (!postgrestTypes && !drizzleSchema && !options.graphql) {
|
|
18289
|
+
throw new TypeError("Database contracts require postgrestTypes, drizzleSchema, or graphql");
|
|
18290
|
+
}
|
|
18291
|
+
if (postgrestTypes)
|
|
18292
|
+
await assertPostgrestSnapshot(postgrestTypes);
|
|
18293
|
+
const artifacts = options.graphql ? await renderGraphql({ rootDir, outDir, graphql: options.graphql }) : { diagnostics: [], files: {} };
|
|
18254
18294
|
if (artifacts.diagnostics.some((item) => item.severity === "error")) {
|
|
18255
18295
|
throw new Error(artifacts.diagnostics.map((item) => item.message).join(`
|
|
18256
18296
|
`));
|
|
@@ -18260,38 +18300,42 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
18260
18300
|
const absolute = resolve25(rootDir, path);
|
|
18261
18301
|
inputs[relative13(rootDir, absolute).replaceAll("\\", "/")] = hash4(await readFile14(absolute, "utf8"));
|
|
18262
18302
|
};
|
|
18263
|
-
|
|
18264
|
-
|
|
18265
|
-
|
|
18266
|
-
|
|
18267
|
-
|
|
18268
|
-
|
|
18269
|
-
|
|
18270
|
-
|
|
18271
|
-
|
|
18272
|
-
|
|
18273
|
-
|
|
18274
|
-
|
|
18275
|
-
|
|
18303
|
+
if (postgrestTypes)
|
|
18304
|
+
await addInput(postgrestTypes);
|
|
18305
|
+
if (drizzleSchema) {
|
|
18306
|
+
await addInput(drizzleSchema);
|
|
18307
|
+
const drizzleProgram = ts18.createProgram([drizzleSchema], {
|
|
18308
|
+
noEmit: true,
|
|
18309
|
+
moduleResolution: ts18.ModuleResolutionKind.Bundler,
|
|
18310
|
+
module: ts18.ModuleKind.ESNext,
|
|
18311
|
+
target: ts18.ScriptTarget.ES2022,
|
|
18312
|
+
types: [],
|
|
18313
|
+
skipLibCheck: true
|
|
18314
|
+
});
|
|
18315
|
+
for (const source of drizzleProgram.getSourceFiles()) {
|
|
18316
|
+
if (!source.isDeclarationFile && !source.fileName.includes("/node_modules/"))
|
|
18317
|
+
await addInput(source.fileName);
|
|
18318
|
+
}
|
|
18276
18319
|
}
|
|
18277
|
-
|
|
18320
|
+
if (options.graphql)
|
|
18321
|
+
await addInput(resolve25(rootDir, options.graphql.schema));
|
|
18278
18322
|
if (new Set(options.migrations.map((path) => resolve25(rootDir, path))).size !== options.migrations.length) {
|
|
18279
18323
|
throw new Error("Duplicate migration in database contracts configuration");
|
|
18280
18324
|
}
|
|
18281
18325
|
for (const path of options.migrations)
|
|
18282
18326
|
await addInput(path);
|
|
18283
|
-
const
|
|
18284
|
-
|
|
18285
|
-
|
|
18286
|
-
|
|
18287
|
-
|
|
18288
|
-
|
|
18289
|
-
|
|
18290
|
-
|
|
18291
|
-
|
|
18292
|
-
|
|
18293
|
-
`
|
|
18294
|
-
|
|
18327
|
+
const barrel = ["// GENERATED BY @supacloud/compiler database-contracts. Do not edit."];
|
|
18328
|
+
if (postgrestTypes) {
|
|
18329
|
+
barrel.push(`export type { Database } from ${JSON.stringify(importPath(outDir, postgrestTypes))};`);
|
|
18330
|
+
barrel.push('export type { QueryData, QueryResult, QueryError } from "@supabase/supabase-js";');
|
|
18331
|
+
}
|
|
18332
|
+
if (drizzleSchema)
|
|
18333
|
+
barrel.push(`export type DrizzleSchema = typeof import(${JSON.stringify(importPath(outDir, drizzleSchema))});`);
|
|
18334
|
+
if (options.graphql)
|
|
18335
|
+
barrel.push('export * from "./graphql";');
|
|
18336
|
+
barrel.push("");
|
|
18337
|
+
const files = { ...artifacts.files, "database.ts": barrel.join(`
|
|
18338
|
+
`) };
|
|
18295
18339
|
const manifest = {
|
|
18296
18340
|
version: 1,
|
|
18297
18341
|
role: options.role,
|
|
@@ -18299,7 +18343,12 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
18299
18343
|
migrationOrder: options.migrations.map((path) => relative13(rootDir, resolve25(rootDir, path)).replaceAll("\\", "/")),
|
|
18300
18344
|
outputs: Object.fromEntries(Object.entries(files).sort(([a], [b]) => a.localeCompare(b)).map(([file, text]) => [file, hash4(text)]))
|
|
18301
18345
|
};
|
|
18302
|
-
|
|
18346
|
+
const fingerprint = hash4(JSON.stringify({
|
|
18347
|
+
inputs: manifest.inputs,
|
|
18348
|
+
migrationOrder: manifest.migrationOrder
|
|
18349
|
+
}));
|
|
18350
|
+
const typedManifest = parseDatabaseContractManifest({ ...manifest, fingerprint });
|
|
18351
|
+
files["database.manifest.json"] = JSON.stringify(typedManifest, null, 2) + `
|
|
18303
18352
|
`;
|
|
18304
18353
|
const mismatches = [];
|
|
18305
18354
|
for (const [file, content] of Object.entries(files)) {
|
|
@@ -18319,7 +18368,7 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
18319
18368
|
for (const [file, content] of Object.entries(files))
|
|
18320
18369
|
await writeFileIfChanged(resolve25(outDir, file), content);
|
|
18321
18370
|
}
|
|
18322
|
-
return { upToDate: mismatches.length === 0, mismatches, written: check ? [] : mismatches, manifest };
|
|
18371
|
+
return { upToDate: mismatches.length === 0, mismatches, written: check ? [] : mismatches, manifest: typedManifest };
|
|
18323
18372
|
}
|
|
18324
18373
|
async function runDatabaseContractsFile(path, check = false) {
|
|
18325
18374
|
const absolute = resolve25(path);
|
|
@@ -18330,6 +18379,7 @@ var init_database_contracts = __esm(() => {
|
|
|
18330
18379
|
init_graphql();
|
|
18331
18380
|
init_generate();
|
|
18332
18381
|
init_graphql_options();
|
|
18382
|
+
init_database_contract_manifest();
|
|
18333
18383
|
});
|
|
18334
18384
|
|
|
18335
18385
|
// src/graphql-schema.ts
|
|
@@ -25821,7 +25871,7 @@ import { resolve as resolve19 } from "node:path";
|
|
|
25821
25871
|
var MIGRATION_APP_VERSION = "0.36.0";
|
|
25822
25872
|
|
|
25823
25873
|
// src/migration-elysia-version.ts
|
|
25824
|
-
var MIGRATION_ELYSIA_VERSION = "0.38.
|
|
25874
|
+
var MIGRATION_ELYSIA_VERSION = "0.38.1";
|
|
25825
25875
|
|
|
25826
25876
|
// src/migration-policy.ts
|
|
25827
25877
|
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
|
@@ -18219,6 +18219,27 @@ var init_graphql_schema = __esm(() => {
|
|
|
18219
18219
|
init_graphql_schema_hashes();
|
|
18220
18220
|
});
|
|
18221
18221
|
|
|
18222
|
+
// src/database-contract-manifest.ts
|
|
18223
|
+
function parseDatabaseContractManifest(value) {
|
|
18224
|
+
if (!Check2(databaseContractManifestSchema, value)) {
|
|
18225
|
+
throw new TypeError("Invalid database contract manifest");
|
|
18226
|
+
}
|
|
18227
|
+
return value;
|
|
18228
|
+
}
|
|
18229
|
+
var databaseContractManifestSchema;
|
|
18230
|
+
var init_database_contract_manifest = __esm(() => {
|
|
18231
|
+
init_build();
|
|
18232
|
+
init_value2();
|
|
18233
|
+
databaseContractManifestSchema = _Object_({
|
|
18234
|
+
version: Literal(1),
|
|
18235
|
+
role: String2({ minLength: 1 }),
|
|
18236
|
+
fingerprint: String2({ pattern: "^[a-f0-9]{64}$" }),
|
|
18237
|
+
inputs: Record(String2({ minLength: 1 }), String2({ pattern: "^[a-f0-9]{64}$" })),
|
|
18238
|
+
migrationOrder: _Array_(String2({ minLength: 1 })),
|
|
18239
|
+
outputs: Record(String2({ minLength: 1 }), String2({ pattern: "^[a-f0-9]{64}$" }))
|
|
18240
|
+
});
|
|
18241
|
+
});
|
|
18242
|
+
|
|
18222
18243
|
// src/database-contracts.ts
|
|
18223
18244
|
import { createHash as createHash12 } from "node:crypto";
|
|
18224
18245
|
import { mkdir as mkdir6, readFile as readFile14 } from "node:fs/promises";
|
|
@@ -18243,8 +18264,23 @@ function parseDatabaseContractsOptions(value, directory) {
|
|
|
18243
18264
|
throw new TypeError(`Missing database contracts ${name}`);
|
|
18244
18265
|
return result;
|
|
18245
18266
|
};
|
|
18246
|
-
const
|
|
18247
|
-
|
|
18267
|
+
const optionalPath = (name) => {
|
|
18268
|
+
if (!Object.hasOwn(value, name))
|
|
18269
|
+
return;
|
|
18270
|
+
return field(name);
|
|
18271
|
+
};
|
|
18272
|
+
const postgrestTypes = optionalPath("postgrestTypes");
|
|
18273
|
+
const drizzleSchema = optionalPath("drizzleSchema");
|
|
18274
|
+
const graphqlPresent = Object.hasOwn(value, "graphql");
|
|
18275
|
+
if (!postgrestTypes && !drizzleSchema && !graphqlPresent) {
|
|
18276
|
+
throw new TypeError("Database contracts require postgrestTypes, drizzleSchema, or graphql");
|
|
18277
|
+
}
|
|
18278
|
+
let graphql;
|
|
18279
|
+
if (graphqlPresent) {
|
|
18280
|
+
const candidate = Reflect.get(value, "graphql");
|
|
18281
|
+
assertGraphqlOptions(candidate);
|
|
18282
|
+
graphql = { ...candidate, schema: resolve24(directory, candidate.schema) };
|
|
18283
|
+
}
|
|
18248
18284
|
const migrations = Reflect.get(value, "migrations");
|
|
18249
18285
|
if (!Array.isArray(migrations) || !migrations.every((entry) => typeof entry === "string" && entry.endsWith(".sql"))) {
|
|
18250
18286
|
throw new TypeError("migrations must be an ordered list of SQL files");
|
|
@@ -18252,22 +18288,20 @@ function parseDatabaseContractsOptions(value, directory) {
|
|
|
18252
18288
|
return {
|
|
18253
18289
|
rootDir: resolve24(directory, field("rootDir")),
|
|
18254
18290
|
outDir: resolve24(directory, field("outDir")),
|
|
18255
|
-
postgrestTypes: resolve24(directory,
|
|
18256
|
-
drizzleSchema: resolve24(directory,
|
|
18291
|
+
...postgrestTypes ? { postgrestTypes: resolve24(directory, postgrestTypes) } : {},
|
|
18292
|
+
...drizzleSchema ? { drizzleSchema: resolve24(directory, drizzleSchema) } : {},
|
|
18257
18293
|
role: field("role"),
|
|
18258
|
-
graphql
|
|
18294
|
+
...graphql ? { graphql } : {},
|
|
18259
18295
|
migrations: migrations.map((file) => resolve24(directory, file))
|
|
18260
18296
|
};
|
|
18261
18297
|
}
|
|
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);
|
|
18298
|
+
async function assertPostgrestSnapshot(path) {
|
|
18299
|
+
const snapshot = await readFile14(path, "utf8");
|
|
18300
|
+
const syntax = ts18.createSourceFile(path, snapshot, ts18.ScriptTarget.Latest, true);
|
|
18267
18301
|
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
18302
|
if (!database)
|
|
18269
18303
|
throw new Error("PostgREST snapshot must export Database from the official type generator");
|
|
18270
|
-
const program = ts18.createProgram([
|
|
18304
|
+
const program = ts18.createProgram([path], {
|
|
18271
18305
|
strict: true,
|
|
18272
18306
|
noEmit: true,
|
|
18273
18307
|
skipLibCheck: true,
|
|
@@ -18278,11 +18312,17 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
18278
18312
|
});
|
|
18279
18313
|
if (ts18.getPreEmitDiagnostics(program).length)
|
|
18280
18314
|
throw new Error("PostgREST snapshot has TypeScript errors");
|
|
18281
|
-
|
|
18282
|
-
|
|
18283
|
-
|
|
18284
|
-
|
|
18285
|
-
|
|
18315
|
+
}
|
|
18316
|
+
async function generateDatabaseContracts(options, check = false) {
|
|
18317
|
+
const rootDir = resolve24(options.rootDir), outDir = resolve24(options.outDir);
|
|
18318
|
+
const postgrestTypes = options.postgrestTypes ? resolve24(rootDir, options.postgrestTypes) : undefined;
|
|
18319
|
+
const drizzleSchema = options.drizzleSchema ? resolve24(rootDir, options.drizzleSchema) : undefined;
|
|
18320
|
+
if (!postgrestTypes && !drizzleSchema && !options.graphql) {
|
|
18321
|
+
throw new TypeError("Database contracts require postgrestTypes, drizzleSchema, or graphql");
|
|
18322
|
+
}
|
|
18323
|
+
if (postgrestTypes)
|
|
18324
|
+
await assertPostgrestSnapshot(postgrestTypes);
|
|
18325
|
+
const artifacts = options.graphql ? await renderGraphql({ rootDir, outDir, graphql: options.graphql }) : { diagnostics: [], files: {} };
|
|
18286
18326
|
if (artifacts.diagnostics.some((item) => item.severity === "error")) {
|
|
18287
18327
|
throw new Error(artifacts.diagnostics.map((item) => item.message).join(`
|
|
18288
18328
|
`));
|
|
@@ -18292,38 +18332,42 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
18292
18332
|
const absolute = resolve24(rootDir, path);
|
|
18293
18333
|
inputs[relative12(rootDir, absolute).replaceAll("\\", "/")] = hash4(await readFile14(absolute, "utf8"));
|
|
18294
18334
|
};
|
|
18295
|
-
|
|
18296
|
-
|
|
18297
|
-
|
|
18298
|
-
|
|
18299
|
-
|
|
18300
|
-
|
|
18301
|
-
|
|
18302
|
-
|
|
18303
|
-
|
|
18304
|
-
|
|
18305
|
-
|
|
18306
|
-
|
|
18307
|
-
|
|
18335
|
+
if (postgrestTypes)
|
|
18336
|
+
await addInput(postgrestTypes);
|
|
18337
|
+
if (drizzleSchema) {
|
|
18338
|
+
await addInput(drizzleSchema);
|
|
18339
|
+
const drizzleProgram = ts18.createProgram([drizzleSchema], {
|
|
18340
|
+
noEmit: true,
|
|
18341
|
+
moduleResolution: ts18.ModuleResolutionKind.Bundler,
|
|
18342
|
+
module: ts18.ModuleKind.ESNext,
|
|
18343
|
+
target: ts18.ScriptTarget.ES2022,
|
|
18344
|
+
types: [],
|
|
18345
|
+
skipLibCheck: true
|
|
18346
|
+
});
|
|
18347
|
+
for (const source of drizzleProgram.getSourceFiles()) {
|
|
18348
|
+
if (!source.isDeclarationFile && !source.fileName.includes("/node_modules/"))
|
|
18349
|
+
await addInput(source.fileName);
|
|
18350
|
+
}
|
|
18308
18351
|
}
|
|
18309
|
-
|
|
18352
|
+
if (options.graphql)
|
|
18353
|
+
await addInput(resolve24(rootDir, options.graphql.schema));
|
|
18310
18354
|
if (new Set(options.migrations.map((path) => resolve24(rootDir, path))).size !== options.migrations.length) {
|
|
18311
18355
|
throw new Error("Duplicate migration in database contracts configuration");
|
|
18312
18356
|
}
|
|
18313
18357
|
for (const path of options.migrations)
|
|
18314
18358
|
await addInput(path);
|
|
18315
|
-
const
|
|
18316
|
-
|
|
18317
|
-
|
|
18318
|
-
|
|
18319
|
-
|
|
18320
|
-
|
|
18321
|
-
|
|
18322
|
-
|
|
18323
|
-
|
|
18324
|
-
|
|
18325
|
-
`
|
|
18326
|
-
|
|
18359
|
+
const barrel = ["// GENERATED BY @supacloud/compiler database-contracts. Do not edit."];
|
|
18360
|
+
if (postgrestTypes) {
|
|
18361
|
+
barrel.push(`export type { Database } from ${JSON.stringify(importPath(outDir, postgrestTypes))};`);
|
|
18362
|
+
barrel.push('export type { QueryData, QueryResult, QueryError } from "@supabase/supabase-js";');
|
|
18363
|
+
}
|
|
18364
|
+
if (drizzleSchema)
|
|
18365
|
+
barrel.push(`export type DrizzleSchema = typeof import(${JSON.stringify(importPath(outDir, drizzleSchema))});`);
|
|
18366
|
+
if (options.graphql)
|
|
18367
|
+
barrel.push('export * from "./graphql";');
|
|
18368
|
+
barrel.push("");
|
|
18369
|
+
const files = { ...artifacts.files, "database.ts": barrel.join(`
|
|
18370
|
+
`) };
|
|
18327
18371
|
const manifest = {
|
|
18328
18372
|
version: 1,
|
|
18329
18373
|
role: options.role,
|
|
@@ -18331,7 +18375,12 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
18331
18375
|
migrationOrder: options.migrations.map((path) => relative12(rootDir, resolve24(rootDir, path)).replaceAll("\\", "/")),
|
|
18332
18376
|
outputs: Object.fromEntries(Object.entries(files).sort(([a], [b]) => a.localeCompare(b)).map(([file, text]) => [file, hash4(text)]))
|
|
18333
18377
|
};
|
|
18334
|
-
|
|
18378
|
+
const fingerprint = hash4(JSON.stringify({
|
|
18379
|
+
inputs: manifest.inputs,
|
|
18380
|
+
migrationOrder: manifest.migrationOrder
|
|
18381
|
+
}));
|
|
18382
|
+
const typedManifest = parseDatabaseContractManifest({ ...manifest, fingerprint });
|
|
18383
|
+
files["database.manifest.json"] = JSON.stringify(typedManifest, null, 2) + `
|
|
18335
18384
|
`;
|
|
18336
18385
|
const mismatches = [];
|
|
18337
18386
|
for (const [file, content] of Object.entries(files)) {
|
|
@@ -18351,7 +18400,7 @@ async function generateDatabaseContracts(options, check = false) {
|
|
|
18351
18400
|
for (const [file, content] of Object.entries(files))
|
|
18352
18401
|
await writeFileIfChanged(resolve24(outDir, file), content);
|
|
18353
18402
|
}
|
|
18354
|
-
return { upToDate: mismatches.length === 0, mismatches, written: check ? [] : mismatches, manifest };
|
|
18403
|
+
return { upToDate: mismatches.length === 0, mismatches, written: check ? [] : mismatches, manifest: typedManifest };
|
|
18355
18404
|
}
|
|
18356
18405
|
async function runDatabaseContractsFile(path, check = false) {
|
|
18357
18406
|
const absolute = resolve24(path);
|
|
@@ -18362,6 +18411,7 @@ var init_database_contracts = __esm(() => {
|
|
|
18362
18411
|
init_graphql();
|
|
18363
18412
|
init_generate();
|
|
18364
18413
|
init_graphql_options();
|
|
18414
|
+
init_database_contract_manifest();
|
|
18365
18415
|
});
|
|
18366
18416
|
|
|
18367
18417
|
// src/analyze.ts
|
|
@@ -25073,7 +25123,7 @@ import { resolve as resolve17 } from "node:path";
|
|
|
25073
25123
|
var MIGRATION_APP_VERSION = "0.36.0";
|
|
25074
25124
|
|
|
25075
25125
|
// src/migration-elysia-version.ts
|
|
25076
|
-
var MIGRATION_ELYSIA_VERSION = "0.38.
|
|
25126
|
+
var MIGRATION_ELYSIA_VERSION = "0.38.1";
|
|
25077
25127
|
|
|
25078
25128
|
// src/migration-policy.ts
|
|
25079
25129
|
var cachedCompilerVersion;
|
|
@@ -26869,6 +26919,7 @@ function introspectionQuery() {
|
|
|
26869
26919
|
|
|
26870
26920
|
// src/index.ts
|
|
26871
26921
|
init_database_contracts();
|
|
26922
|
+
init_database_contract_manifest();
|
|
26872
26923
|
export {
|
|
26873
26924
|
ANGULAR_ENTERPRISE_RULES,
|
|
26874
26925
|
APPLICATION_DEVELOPMENT_ARCHIVE_MAX_BYTES2 as APPLICATION_DEVELOPMENT_ARCHIVE_MAX_BYTES,
|
|
@@ -26955,6 +27006,7 @@ export {
|
|
|
26955
27006
|
migrateProject,
|
|
26956
27007
|
migrateRouteResponse,
|
|
26957
27008
|
parseApplicationDevelopmentContext,
|
|
27009
|
+
parseDatabaseContractManifest,
|
|
26958
27010
|
parseDatabaseContractsOptions,
|
|
26959
27011
|
parseDeliveryBuildManifest,
|
|
26960
27012
|
parseDeliveryBuildResult,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const MIGRATION_ELYSIA_VERSION = "0.38.
|
|
1
|
+
export declare const MIGRATION_ELYSIA_VERSION = "0.38.1";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supacloud/compiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.55.0",
|
|
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",
|