@xemahq/biome-database-nest 0.36.0 → 0.38.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 +55 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/biome-migrations.d.ts +11 -0
- package/dist/lib/biome-migrations.d.ts.map +1 -0
- package/dist/lib/biome-migrations.js +51 -0
- package/dist/lib/biome-migrations.js.map +1 -0
- package/dist/lib/bootstrap.d.ts +2 -0
- package/dist/lib/bootstrap.d.ts.map +1 -1
- package/dist/lib/bootstrap.js +22 -12
- package/dist/lib/bootstrap.js.map +1 -1
- package/dist/lib/ledger-rows.d.ts +14 -0
- package/dist/lib/ledger-rows.d.ts.map +1 -0
- package/dist/lib/ledger-rows.js +44 -0
- package/dist/lib/ledger-rows.js.map +1 -0
- package/dist/lib/nest/biome-database.module.d.ts.map +1 -1
- package/dist/lib/nest/biome-database.module.js +30 -5
- package/dist/lib/nest/biome-database.module.js.map +1 -1
- package/dist/lib/nest/sdk-owned-contribution.d.ts +25 -0
- package/dist/lib/nest/sdk-owned-contribution.d.ts.map +1 -0
- package/dist/lib/nest/sdk-owned-contribution.js +71 -0
- package/dist/lib/nest/sdk-owned-contribution.js.map +1 -0
- package/dist/lib/operator-migration-ledger.d.ts +4 -2
- package/dist/lib/operator-migration-ledger.d.ts.map +1 -1
- package/dist/lib/operator-migration-ledger.js +79 -9
- package/dist/lib/operator-migration-ledger.js.map +1 -1
- package/dist/lib/operator-migration.d.ts +4 -8
- package/dist/lib/operator-migration.d.ts.map +1 -1
- package/dist/lib/operator-migration.js +16 -44
- package/dist/lib/operator-migration.js.map +1 -1
- package/dist/lib/owned-table-shape.d.ts +33 -0
- package/dist/lib/owned-table-shape.d.ts.map +1 -0
- package/dist/lib/owned-table-shape.js +137 -0
- package/dist/lib/owned-table-shape.js.map +1 -0
- package/dist/lib/sdk-owned-errors.d.ts +24 -0
- package/dist/lib/sdk-owned-errors.d.ts.map +1 -0
- package/dist/lib/sdk-owned-errors.js +58 -0
- package/dist/lib/sdk-owned-errors.js.map +1 -0
- package/dist/lib/sdk-owned-migration-set.d.ts +19 -0
- package/dist/lib/sdk-owned-migration-set.d.ts.map +1 -0
- package/dist/lib/sdk-owned-migration-set.js +81 -0
- package/dist/lib/sdk-owned-migration-set.js.map +1 -0
- package/dist/lib/sdk-owned-migrations.d.ts +5 -0
- package/dist/lib/sdk-owned-migrations.d.ts.map +1 -0
- package/dist/lib/sdk-owned-migrations.js +58 -0
- package/dist/lib/sdk-owned-migrations.js.map +1 -0
- package/dist/lib/service-migration-scan.d.ts +3 -0
- package/dist/lib/service-migration-scan.d.ts.map +1 -0
- package/dist/lib/service-migration-scan.js +164 -0
- package/dist/lib/service-migration-scan.js.map +1 -0
- package/package.json +7 -7
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { SdkOwnedMigrationSet } from '../sdk-owned-migration-set';
|
|
2
|
+
import type { Provider } from '@nestjs/common';
|
|
3
|
+
declare const CONTRIBUTION_BRAND: unique symbol;
|
|
4
|
+
export interface SdkOwnedMigrationContribution {
|
|
5
|
+
readonly [CONTRIBUTION_BRAND]: true;
|
|
6
|
+
readonly set: SdkOwnedMigrationSet;
|
|
7
|
+
}
|
|
8
|
+
export interface AppliedSdkOwnedMigrations {
|
|
9
|
+
readonly extraction: boolean;
|
|
10
|
+
readonly owners: readonly string[];
|
|
11
|
+
}
|
|
12
|
+
export declare const APPLIED_SDK_OWNED_MIGRATIONS: unique symbol;
|
|
13
|
+
export declare class SdkOwnedMigrationsNotAppliedError extends Error {
|
|
14
|
+
readonly code = "SDK_OWNED_MIGRATIONS_NOT_APPLIED";
|
|
15
|
+
constructor(owner: string, reason: string);
|
|
16
|
+
}
|
|
17
|
+
export declare class SdkOwnedMigrationsConflictError extends Error {
|
|
18
|
+
readonly code = "SDK_OWNED_MIGRATIONS_CONFLICT";
|
|
19
|
+
constructor(owner: string);
|
|
20
|
+
}
|
|
21
|
+
export declare function contributeSdkOwnedMigrations(set: SdkOwnedMigrationSet): Provider[];
|
|
22
|
+
export declare function isSdkOwnedMigrationContribution(value: unknown): value is SdkOwnedMigrationContribution;
|
|
23
|
+
export declare function mergeSdkOwnedMigrations(contributed: readonly SdkOwnedMigrationSet[]): SdkOwnedMigrationSet[];
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=sdk-owned-contribution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-owned-contribution.d.ts","sourceRoot":"","sources":["../../../src/lib/nest/sdk-owned-contribution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,QAAA,MAAM,kBAAkB,eAEvB,CAAC;AAOF,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,CAAC,kBAAkB,CAAC,EAAE,IAAI,CAAC;IACpC,QAAQ,CAAC,GAAG,EAAE,oBAAoB,CAAC;CACpC;AAQD,MAAM,WAAW,yBAAyB;IAExC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAOD,eAAO,MAAM,4BAA4B,eAExC,CAAC;AAGF,qBAAa,iCAAkC,SAAQ,KAAK;IAC1D,SAAgB,IAAI,sCAAsC;gBAEvC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAOjD;AAGD,qBAAa,+BAAgC,SAAQ,KAAK;IACxD,SAAgB,IAAI,mCAAmC;gBAEpC,KAAK,EAAE,MAAM;CAOjC;AAUD,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,oBAAoB,GACxB,QAAQ,EAAE,CA8BZ;AAGD,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,6BAA6B,CAMxC;AAOD,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,SAAS,oBAAoB,EAAE,GAC3C,oBAAoB,EAAE,CAgBxB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SdkOwnedMigrationsConflictError = exports.SdkOwnedMigrationsNotAppliedError = exports.APPLIED_SDK_OWNED_MIGRATIONS = void 0;
|
|
4
|
+
exports.contributeSdkOwnedMigrations = contributeSdkOwnedMigrations;
|
|
5
|
+
exports.isSdkOwnedMigrationContribution = isSdkOwnedMigrationContribution;
|
|
6
|
+
exports.mergeSdkOwnedMigrations = mergeSdkOwnedMigrations;
|
|
7
|
+
const CONTRIBUTION_BRAND = Symbol.for('xema.biome-database-nest.sdk-owned-migration-contribution');
|
|
8
|
+
exports.APPLIED_SDK_OWNED_MIGRATIONS = Symbol.for('@xemahq/biome-database-nest:applied-sdk-owned-migrations');
|
|
9
|
+
class SdkOwnedMigrationsNotAppliedError extends Error {
|
|
10
|
+
code = 'SDK_OWNED_MIGRATIONS_NOT_APPLIED';
|
|
11
|
+
constructor(owner, reason) {
|
|
12
|
+
super(`[biome-database] SDK_OWNED_MIGRATIONS_NOT_APPLIED: the "${owner}" tables ` +
|
|
13
|
+
`were not created at boot: ${reason}`);
|
|
14
|
+
this.name = 'SdkOwnedMigrationsNotAppliedError';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.SdkOwnedMigrationsNotAppliedError = SdkOwnedMigrationsNotAppliedError;
|
|
18
|
+
class SdkOwnedMigrationsConflictError extends Error {
|
|
19
|
+
code = 'SDK_OWNED_MIGRATIONS_CONFLICT';
|
|
20
|
+
constructor(owner) {
|
|
21
|
+
super(`[biome-database] SDK_OWNED_MIGRATIONS_CONFLICT: two different migration ` +
|
|
22
|
+
`sets are contributed for the owner "${owner}".`);
|
|
23
|
+
this.name = 'SdkOwnedMigrationsConflictError';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.SdkOwnedMigrationsConflictError = SdkOwnedMigrationsConflictError;
|
|
27
|
+
function contributeSdkOwnedMigrations(set) {
|
|
28
|
+
const contribution = {
|
|
29
|
+
[CONTRIBUTION_BRAND]: true,
|
|
30
|
+
set,
|
|
31
|
+
};
|
|
32
|
+
return [
|
|
33
|
+
{
|
|
34
|
+
provide: Symbol(`sdk-owned-migrations:${set.owner}`),
|
|
35
|
+
useValue: contribution,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
provide: Symbol(`sdk-owned-migrations-guard:${set.owner}`),
|
|
39
|
+
useFactory: (applied) => {
|
|
40
|
+
if (applied === undefined) {
|
|
41
|
+
throw new SdkOwnedMigrationsNotAppliedError(set.owner, 'no BiomeDatabaseModule (or XemaDatabaseModule) is mounted in this graph.');
|
|
42
|
+
}
|
|
43
|
+
if (!applied.extraction && !applied.owners.includes(set.owner)) {
|
|
44
|
+
throw new SdkOwnedMigrationsNotAppliedError(set.owner, 'the migration phase ran without them.');
|
|
45
|
+
}
|
|
46
|
+
return true;
|
|
47
|
+
},
|
|
48
|
+
inject: [{ token: exports.APPLIED_SDK_OWNED_MIGRATIONS, optional: true }],
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
function isSdkOwnedMigrationContribution(value) {
|
|
53
|
+
return (typeof value === 'object' &&
|
|
54
|
+
value !== null &&
|
|
55
|
+
value[CONTRIBUTION_BRAND] === true);
|
|
56
|
+
}
|
|
57
|
+
function mergeSdkOwnedMigrations(contributed) {
|
|
58
|
+
const byOwner = new Map();
|
|
59
|
+
for (const set of contributed) {
|
|
60
|
+
const existing = byOwner.get(set.owner);
|
|
61
|
+
if (existing === undefined) {
|
|
62
|
+
byOwner.set(set.owner, set);
|
|
63
|
+
}
|
|
64
|
+
else if (existing !== set &&
|
|
65
|
+
JSON.stringify(existing) !== JSON.stringify(set)) {
|
|
66
|
+
throw new SdkOwnedMigrationsConflictError(set.owner);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return [...byOwner.values()].sort((a, b) => a.owner < b.owner ? -1 : a.owner > b.owner ? 1 : 0);
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=sdk-owned-contribution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-owned-contribution.js","sourceRoot":"","sources":["../../../src/lib/nest/sdk-owned-contribution.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type
|
|
2
|
-
|
|
1
|
+
import { type OperatorMigrationDatabase } from './ledger-rows';
|
|
2
|
+
import { type SdkOwnedMigrationSet } from './sdk-owned-migration-set';
|
|
3
|
+
export declare const OPERATOR_MIGRATION_LEDGER_TABLE = "xema_operator_migrations";
|
|
4
|
+
export declare const operatorMigrationLedgerMigrations: SdkOwnedMigrationSet;
|
|
3
5
|
export declare function ensureOperatorMigrationLedger(database: OperatorMigrationDatabase): Promise<void>;
|
|
4
6
|
//# sourceMappingURL=operator-migration-ledger.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operator-migration-ledger.d.ts","sourceRoot":"","sources":["../../src/lib/operator-migration-ledger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"operator-migration-ledger.d.ts","sourceRoot":"","sources":["../../src/lib/operator-migration-ledger.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,yBAAyB,EAC/B,MAAM,eAAe,CAAC;AAGvB,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,2BAA2B,CAAC;AAInC,eAAO,MAAM,+BAA+B,6BAA6B,CAAC;AA4B1E,eAAO,MAAM,iCAAiC,EAAE,oBAwC/C,CAAC;AAwBF,wBAAsB,6BAA6B,CACjD,QAAQ,EAAE,yBAAyB,GAClC,OAAO,CAAC,IAAI,CAAC,CA4Df"}
|
|
@@ -1,30 +1,100 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.operatorMigrationLedgerMigrations = exports.OPERATOR_MIGRATION_LEDGER_TABLE = void 0;
|
|
4
4
|
exports.ensureOperatorMigrationLedger = ensureOperatorMigrationLedger;
|
|
5
|
+
const ledger_rows_1 = require("./ledger-rows");
|
|
6
|
+
const owned_table_shape_1 = require("./owned-table-shape");
|
|
7
|
+
const sdk_owned_errors_1 = require("./sdk-owned-errors");
|
|
8
|
+
const sdk_owned_migration_set_1 = require("./sdk-owned-migration-set");
|
|
5
9
|
const LEDGER_LOCK_KEY = 'xema:operator-migration-ledger';
|
|
6
|
-
exports.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
exports.OPERATOR_MIGRATION_LEDGER_TABLE = 'xema_operator_migrations';
|
|
11
|
+
const LEDGER_MIGRATION = {
|
|
12
|
+
version: '0001-operator-migration-ledger',
|
|
13
|
+
creates: [exports.OPERATOR_MIGRATION_LEDGER_TABLE],
|
|
14
|
+
sql: `
|
|
15
|
+
CREATE TABLE "xema_operator_migrations" (
|
|
16
|
+
"migration_id" TEXT NOT NULL,
|
|
17
|
+
"phase" TEXT NOT NULL,
|
|
18
|
+
"artifact_sha256" CHAR(64) NOT NULL,
|
|
19
|
+
"completed_at" TIMESTAMPTZ(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
11
20
|
CONSTRAINT "xema_operator_migrations_pkey" PRIMARY KEY ("migration_id", "phase"),
|
|
12
21
|
CONSTRAINT "xema_operator_migrations_id_ck"
|
|
13
22
|
CHECK ("migration_id" ~ '^[a-z][a-z0-9-]{0,126}$'),
|
|
14
23
|
CONSTRAINT "xema_operator_migrations_phase_ck"
|
|
15
|
-
CHECK ("phase" IN ('verified', 'contracted')),
|
|
24
|
+
CHECK ("phase" IN ('verified', 'contracted', 'applied')),
|
|
16
25
|
CONSTRAINT "xema_operator_migrations_hash_ck"
|
|
17
26
|
CHECK ("artifact_sha256" ~ '^[a-f0-9]{64}$')
|
|
18
|
-
)
|
|
27
|
+
);
|
|
28
|
+
`,
|
|
29
|
+
};
|
|
30
|
+
exports.operatorMigrationLedgerMigrations = {
|
|
31
|
+
owner: 'biome-database',
|
|
32
|
+
migrations: [LEDGER_MIGRATION],
|
|
33
|
+
tables: [
|
|
34
|
+
{
|
|
35
|
+
name: exports.OPERATOR_MIGRATION_LEDGER_TABLE,
|
|
36
|
+
columns: [
|
|
37
|
+
{ name: 'migration_id', type: 'text', notNull: true, default: null },
|
|
38
|
+
{ name: 'phase', type: 'text', notNull: true, default: null },
|
|
39
|
+
{
|
|
40
|
+
name: 'artifact_sha256',
|
|
41
|
+
type: 'character(64)',
|
|
42
|
+
notNull: true,
|
|
43
|
+
default: null,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'completed_at',
|
|
47
|
+
type: 'timestamp(3) with time zone',
|
|
48
|
+
notNull: true,
|
|
49
|
+
default: 'CURRENT_TIMESTAMP',
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
primaryKey: ['migration_id', 'phase'],
|
|
53
|
+
checks: [
|
|
54
|
+
{
|
|
55
|
+
name: 'xema_operator_migrations_id_ck',
|
|
56
|
+
definition: `CHECK ((migration_id ~ '^[a-z][a-z0-9-]{0,126}$'::text))`,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'xema_operator_migrations_phase_ck',
|
|
60
|
+
definition: `CHECK ((phase = ANY (ARRAY['verified'::text, 'contracted'::text, 'applied'::text])))`,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'xema_operator_migrations_hash_ck',
|
|
64
|
+
definition: `CHECK ((artifact_sha256 ~ '^[a-f0-9]{64}$'::text))`,
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
indexes: [],
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
};
|
|
71
|
+
const LEDGER_MIGRATION_ID = (0, sdk_owned_migration_set_1.sdkOwnedMigrationId)(exports.operatorMigrationLedgerMigrations.owner, LEDGER_MIGRATION.version);
|
|
19
72
|
const ensuredDatabases = new WeakSet();
|
|
20
73
|
async function ensureOperatorMigrationLedger(database) {
|
|
21
74
|
if (ensuredDatabases.has(database)) {
|
|
22
75
|
return;
|
|
23
76
|
}
|
|
77
|
+
const artifactSha256 = (0, ledger_rows_1.sha256)(LEDGER_MIGRATION.sql);
|
|
24
78
|
await database.query('BEGIN');
|
|
25
79
|
try {
|
|
26
80
|
await database.query(`SELECT pg_advisory_xact_lock(hashtextextended($1, 0))`, [LEDGER_LOCK_KEY]);
|
|
27
|
-
await
|
|
81
|
+
const created = !(await (0, owned_table_shape_1.ownedTableExists)(database, exports.OPERATOR_MIGRATION_LEDGER_TABLE));
|
|
82
|
+
if (created) {
|
|
83
|
+
await database.query(LEDGER_MIGRATION.sql);
|
|
84
|
+
}
|
|
85
|
+
for (const table of exports.operatorMigrationLedgerMigrations.tables) {
|
|
86
|
+
await (0, owned_table_shape_1.assertOwnedTableShape)(database, table);
|
|
87
|
+
}
|
|
88
|
+
if (created) {
|
|
89
|
+
await (0, ledger_rows_1.recordPhase)(database, LEDGER_MIGRATION_ID, ledger_rows_1.OperatorMigrationPhase.Applied, artifactSha256);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
const recorded = await (0, ledger_rows_1.readPhase)(database, LEDGER_MIGRATION_ID, ledger_rows_1.OperatorMigrationPhase.Applied);
|
|
93
|
+
if (recorded === null) {
|
|
94
|
+
throw new sdk_owned_errors_1.SdkOwnedTableNotCreatedByOwnerError(exports.OPERATOR_MIGRATION_LEDGER_TABLE, exports.operatorMigrationLedgerMigrations.owner);
|
|
95
|
+
}
|
|
96
|
+
(0, ledger_rows_1.assertArtifactMatches)(LEDGER_MIGRATION_ID, ledger_rows_1.OperatorMigrationPhase.Applied, recorded, artifactSha256);
|
|
97
|
+
}
|
|
28
98
|
await database.query('COMMIT');
|
|
29
99
|
}
|
|
30
100
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operator-migration-ledger.js","sourceRoot":"","sources":["../../src/lib/operator-migration-ledger.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"operator-migration-ledger.js","sourceRoot":"","sources":["../../src/lib/operator-migration-ledger.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
import { Client
|
|
1
|
+
import { Client } from 'pg';
|
|
2
|
+
import { assertArtifactMatches, OperatorMigrationPhase, readPhase, recordPhase, sha256, type OperatorMigrationDatabase } from './ledger-rows';
|
|
2
3
|
export declare enum OperatorMigrationMode {
|
|
3
4
|
DryRun = "dry-run",
|
|
4
5
|
Apply = "apply",
|
|
5
6
|
Verify = "verify",
|
|
6
7
|
Contract = "contract"
|
|
7
8
|
}
|
|
8
|
-
export declare enum OperatorMigrationPhase {
|
|
9
|
-
Verified = "verified",
|
|
10
|
-
Contracted = "contracted"
|
|
11
|
-
}
|
|
12
|
-
export interface OperatorMigrationDatabase {
|
|
13
|
-
query<R extends QueryResultRow = QueryResultRow>(queryText: string, values?: unknown[]): Promise<QueryResult<R>>;
|
|
14
|
-
}
|
|
15
9
|
export interface VerifyOperatorMigrationOptions {
|
|
16
10
|
readonly database: OperatorMigrationDatabase;
|
|
17
11
|
readonly migrationId: string;
|
|
@@ -45,4 +39,6 @@ export declare function verifyOperatorMigration(options: VerifyOperatorMigration
|
|
|
45
39
|
export declare function contractOperatorMigration(options: ContractOperatorMigrationOptions): Promise<{
|
|
46
40
|
readonly artifactSha256: string;
|
|
47
41
|
}>;
|
|
42
|
+
export declare function inMigrationTransaction(database: OperatorMigrationDatabase, migrationId: string, work: (database: OperatorMigrationDatabase) => Promise<void>): Promise<void>;
|
|
43
|
+
export { assertArtifactMatches, OperatorMigrationPhase, readPhase, recordPhase, sha256, type OperatorMigrationDatabase, };
|
|
48
44
|
//# sourceMappingURL=operator-migration.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operator-migration.d.ts","sourceRoot":"","sources":["../../src/lib/operator-migration.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"operator-migration.d.ts","sourceRoot":"","sources":["../../src/lib/operator-migration.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAC;AAE5B,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,SAAS,EACT,WAAW,EACX,MAAM,EACN,KAAK,yBAAyB,EAC/B,MAAM,eAAe,CAAC;AAIvB,oBAAY,qBAAqB;IAC/B,MAAM,YAAY;IAClB,KAAK,UAAU;IACf,MAAM,WAAW;IACjB,QAAQ,aAAa;CACtB;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAC;IAC7C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,yBAAyB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACzE;AAED,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAC;IAC7C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,gCAAgC,CAAC,CAAC;IACjD,QAAQ,CAAC,QAAQ,EAAE,yBAAyB,CAAC;IAC7C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,yBAAyB,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;CACnE;AAED,MAAM,WAAW,kCAAkC;IAEjD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,2BAA2B,CAAC,CAAC,CAC5C,SAAQ,kCAAkC;IAC1C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;CAChD;AAKD,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,qBAAqB,CAgBvB;AAgCD,wBAAsB,2BAA2B,CAC/C,OAAO,GAAE,kCAAuC,GAC/C,OAAO,CAAC,MAAM,CAAC,CAajB;AASD,wBAAsB,oBAAoB,CAAC,CAAC,EAC1C,OAAO,EAAE,2BAA2B,CAAC,CAAC,CAAC,GACtC,OAAO,CAAC,CAAC,CAAC,CAgBZ;AAUD,wBAAsB,yBAAyB,CAAC,CAAC,EAC/C,OAAO,EAAE,gCAAgC,CAAC,CAAC,CAAC,GAC3C,OAAO,CAAC,CAAC,CAAC,CAsBZ;AAED,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC;IAAE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC,CAgB9C;AAED,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC;IAAE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAAC,CAmC9C;AAED,wBAAsB,sBAAsB,CAC1C,QAAQ,EAAE,yBAAyB,EACnC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,CAAC,QAAQ,EAAE,yBAAyB,KAAK,OAAO,CAAC,IAAI,CAAC,GAC3D,OAAO,CAAC,IAAI,CAAC,CAuBf;AAgDD,OAAO,EACL,qBAAqB,EACrB,sBAAsB,EACtB,SAAS,EACT,WAAW,EACX,MAAM,EACN,KAAK,yBAAyB,GAC/B,CAAC"}
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.OperatorMigrationPhase = exports.OperatorMigrationMode = void 0;
|
|
3
|
+
exports.sha256 = exports.recordPhase = exports.readPhase = exports.OperatorMigrationPhase = exports.assertArtifactMatches = exports.OperatorMigrationMode = void 0;
|
|
4
4
|
exports.parseOperatorMigrationMode = parseOperatorMigrationMode;
|
|
5
5
|
exports.openOperatorMigrationClient = openOperatorMigrationClient;
|
|
6
6
|
exports.runOperatorMigration = runOperatorMigration;
|
|
7
7
|
exports.withOperatorMigrationLock = withOperatorMigrationLock;
|
|
8
8
|
exports.verifyOperatorMigration = verifyOperatorMigration;
|
|
9
9
|
exports.contractOperatorMigration = contractOperatorMigration;
|
|
10
|
-
|
|
10
|
+
exports.inMigrationTransaction = inMigrationTransaction;
|
|
11
11
|
const platform_common_1 = require("@xemahq/platform-common");
|
|
12
12
|
const pg_1 = require("pg");
|
|
13
|
+
const ledger_rows_1 = require("./ledger-rows");
|
|
14
|
+
Object.defineProperty(exports, "assertArtifactMatches", { enumerable: true, get: function () { return ledger_rows_1.assertArtifactMatches; } });
|
|
15
|
+
Object.defineProperty(exports, "OperatorMigrationPhase", { enumerable: true, get: function () { return ledger_rows_1.OperatorMigrationPhase; } });
|
|
16
|
+
Object.defineProperty(exports, "readPhase", { enumerable: true, get: function () { return ledger_rows_1.readPhase; } });
|
|
17
|
+
Object.defineProperty(exports, "recordPhase", { enumerable: true, get: function () { return ledger_rows_1.recordPhase; } });
|
|
18
|
+
Object.defineProperty(exports, "sha256", { enumerable: true, get: function () { return ledger_rows_1.sha256; } });
|
|
13
19
|
const operator_migration_ledger_1 = require("./operator-migration-ledger");
|
|
14
20
|
const session_timezone_1 = require("./session-timezone");
|
|
15
21
|
var OperatorMigrationMode;
|
|
@@ -19,13 +25,7 @@ var OperatorMigrationMode;
|
|
|
19
25
|
OperatorMigrationMode["Verify"] = "verify";
|
|
20
26
|
OperatorMigrationMode["Contract"] = "contract";
|
|
21
27
|
})(OperatorMigrationMode || (exports.OperatorMigrationMode = OperatorMigrationMode = {}));
|
|
22
|
-
var OperatorMigrationPhase;
|
|
23
|
-
(function (OperatorMigrationPhase) {
|
|
24
|
-
OperatorMigrationPhase["Verified"] = "verified";
|
|
25
|
-
OperatorMigrationPhase["Contracted"] = "contracted";
|
|
26
|
-
})(OperatorMigrationPhase || (exports.OperatorMigrationPhase = OperatorMigrationPhase = {}));
|
|
27
28
|
const MIGRATION_ID_PATTERN = /^[a-z][a-z0-9-]{0,126}$/u;
|
|
28
|
-
const SHA256_PATTERN = /^[a-f0-9]{64}$/u;
|
|
29
29
|
const DATABASE_URL_ENV_VAR = 'DATABASE_URL';
|
|
30
30
|
function parseOperatorMigrationMode(argv) {
|
|
31
31
|
const modeArguments = argv.filter((value) => value.startsWith('--mode='));
|
|
@@ -84,24 +84,24 @@ async function withOperatorMigrationLock(options) {
|
|
|
84
84
|
return result;
|
|
85
85
|
}
|
|
86
86
|
async function verifyOperatorMigration(options) {
|
|
87
|
-
const artifactSha256 = sha256(options.verificationArtifact);
|
|
87
|
+
const artifactSha256 = (0, ledger_rows_1.sha256)(options.verificationArtifact);
|
|
88
88
|
await inMigrationTransaction(options.database, options.migrationId, async (database) => {
|
|
89
89
|
await options.verify(database);
|
|
90
|
-
await recordPhase(database, options.migrationId, OperatorMigrationPhase.Verified, artifactSha256);
|
|
90
|
+
await (0, ledger_rows_1.recordPhase)(database, options.migrationId, ledger_rows_1.OperatorMigrationPhase.Verified, artifactSha256);
|
|
91
91
|
});
|
|
92
92
|
return { artifactSha256 };
|
|
93
93
|
}
|
|
94
94
|
async function contractOperatorMigration(options) {
|
|
95
|
-
const artifactSha256 = sha256(options.contractionSql);
|
|
95
|
+
const artifactSha256 = (0, ledger_rows_1.sha256)(options.contractionSql);
|
|
96
96
|
await inMigrationTransaction(options.database, options.migrationId, async (database) => {
|
|
97
|
-
await requirePhase(database, options.migrationId, OperatorMigrationPhase.Verified);
|
|
98
|
-
const existing = await readPhase(database, options.migrationId, OperatorMigrationPhase.Contracted);
|
|
97
|
+
await requirePhase(database, options.migrationId, ledger_rows_1.OperatorMigrationPhase.Verified);
|
|
98
|
+
const existing = await (0, ledger_rows_1.readPhase)(database, options.migrationId, ledger_rows_1.OperatorMigrationPhase.Contracted);
|
|
99
99
|
if (existing !== null) {
|
|
100
|
-
assertArtifactMatches(options.migrationId, OperatorMigrationPhase.Contracted, existing, artifactSha256);
|
|
100
|
+
(0, ledger_rows_1.assertArtifactMatches)(options.migrationId, ledger_rows_1.OperatorMigrationPhase.Contracted, existing, artifactSha256);
|
|
101
101
|
return;
|
|
102
102
|
}
|
|
103
103
|
await database.query(options.contractionSql);
|
|
104
|
-
await recordPhase(database, options.migrationId, OperatorMigrationPhase.Contracted, artifactSha256);
|
|
104
|
+
await (0, ledger_rows_1.recordPhase)(database, options.migrationId, ledger_rows_1.OperatorMigrationPhase.Contracted, artifactSha256);
|
|
105
105
|
});
|
|
106
106
|
return { artifactSha256 };
|
|
107
107
|
}
|
|
@@ -139,36 +139,11 @@ async function releaseSessionLock(database, lockKey, workError) {
|
|
|
139
139
|
throw unlockError;
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
|
-
async function recordPhase(database, migrationId, phase, artifactSha256) {
|
|
143
|
-
const existing = await readPhase(database, migrationId, phase);
|
|
144
|
-
if (existing !== null) {
|
|
145
|
-
assertArtifactMatches(migrationId, phase, existing, artifactSha256);
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
await database.query(`INSERT INTO xema_operator_migrations
|
|
149
|
-
(migration_id, phase, artifact_sha256)
|
|
150
|
-
VALUES ($1, $2, $3)`, [migrationId, phase, artifactSha256]);
|
|
151
|
-
}
|
|
152
142
|
async function requirePhase(database, migrationId, phase) {
|
|
153
|
-
if ((await readPhase(database, migrationId, phase)) === null) {
|
|
143
|
+
if ((await (0, ledger_rows_1.readPhase)(database, migrationId, phase)) === null) {
|
|
154
144
|
throw new Error(`Operator migration ${migrationId} has not completed phase ${phase}.`);
|
|
155
145
|
}
|
|
156
146
|
}
|
|
157
|
-
async function readPhase(database, migrationId, phase) {
|
|
158
|
-
const result = await database.query(`SELECT artifact_sha256
|
|
159
|
-
FROM xema_operator_migrations
|
|
160
|
-
WHERE migration_id = $1 AND phase = $2`, [migrationId, phase]);
|
|
161
|
-
const value = result.rows[0]?.artifact_sha256 ?? null;
|
|
162
|
-
if (value !== null && !SHA256_PATTERN.test(value)) {
|
|
163
|
-
throw new Error(`Operator migration ledger contains an invalid artifact hash for ${migrationId}/${phase}.`);
|
|
164
|
-
}
|
|
165
|
-
return value;
|
|
166
|
-
}
|
|
167
|
-
function assertArtifactMatches(migrationId, phase, recorded, expected) {
|
|
168
|
-
if (recorded !== expected) {
|
|
169
|
-
throw new Error(`Operator migration ${migrationId}/${phase} is already recorded for a different artifact.`);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
147
|
function assertMigrationId(migrationId) {
|
|
173
148
|
if (!MIGRATION_ID_PATTERN.test(migrationId)) {
|
|
174
149
|
throw new Error(`Invalid operator migration id: ${migrationId}.`);
|
|
@@ -177,7 +152,4 @@ function assertMigrationId(migrationId) {
|
|
|
177
152
|
function migrationLockKey(migrationId) {
|
|
178
153
|
return `xema:operator-migration:${migrationId}`;
|
|
179
154
|
}
|
|
180
|
-
function sha256(value) {
|
|
181
|
-
return (0, node_crypto_1.createHash)('sha256').update(value).digest('hex');
|
|
182
|
-
}
|
|
183
155
|
//# sourceMappingURL=operator-migration.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"operator-migration.js","sourceRoot":"","sources":["../../src/lib/operator-migration.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"operator-migration.js","sourceRoot":"","sources":["../../src/lib/operator-migration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { OperatorMigrationDatabase } from './ledger-rows';
|
|
2
|
+
export interface OwnedColumnShape {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly type: string;
|
|
5
|
+
readonly notNull: boolean;
|
|
6
|
+
readonly default: string | null;
|
|
7
|
+
}
|
|
8
|
+
export interface OwnedCheckShape {
|
|
9
|
+
readonly name: string;
|
|
10
|
+
readonly definition: string;
|
|
11
|
+
}
|
|
12
|
+
export interface OwnedIndexShape {
|
|
13
|
+
readonly name: string;
|
|
14
|
+
readonly unique: boolean;
|
|
15
|
+
readonly columns: readonly string[];
|
|
16
|
+
readonly predicate: string | null;
|
|
17
|
+
}
|
|
18
|
+
export interface OwnedTableShape {
|
|
19
|
+
readonly name: string;
|
|
20
|
+
readonly columns: readonly OwnedColumnShape[];
|
|
21
|
+
readonly primaryKey: readonly string[];
|
|
22
|
+
readonly checks: readonly OwnedCheckShape[];
|
|
23
|
+
readonly indexes: readonly OwnedIndexShape[];
|
|
24
|
+
}
|
|
25
|
+
export declare class SdkOwnedTableShapeError extends Error {
|
|
26
|
+
readonly table: string;
|
|
27
|
+
readonly detail: string;
|
|
28
|
+
readonly code = "SDK_OWNED_TABLE_SHAPE_MISMATCH";
|
|
29
|
+
constructor(table: string, detail: string);
|
|
30
|
+
}
|
|
31
|
+
export declare function ownedTableExists(database: OperatorMigrationDatabase, table: string): Promise<boolean>;
|
|
32
|
+
export declare function assertOwnedTableShape(database: OperatorMigrationDatabase, expected: OwnedTableShape): Promise<void>;
|
|
33
|
+
//# sourceMappingURL=owned-table-shape.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"owned-table-shape.d.ts","sourceRoot":"","sources":["../../src/lib/owned-table-shape.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAM/D,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAGD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAOD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAYD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAE9C,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5C,QAAQ,CAAC,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;CAC9C;AAGD,qBAAa,uBAAwB,SAAQ,KAAK;aAI9B,KAAK,EAAE,MAAM;aACb,MAAM,EAAE,MAAM;IAJhC,SAAgB,IAAI,oCAAoC;gBAGtC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM;CASjC;AA4DD,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,yBAAyB,EACnC,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC,CAMlB;AA0JD,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,yBAAyB,EACnC,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,IAAI,CAAC,CAcf"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SdkOwnedTableShapeError = void 0;
|
|
4
|
+
exports.ownedTableExists = ownedTableExists;
|
|
5
|
+
exports.assertOwnedTableShape = assertOwnedTableShape;
|
|
6
|
+
class SdkOwnedTableShapeError extends Error {
|
|
7
|
+
table;
|
|
8
|
+
detail;
|
|
9
|
+
code = 'SDK_OWNED_TABLE_SHAPE_MISMATCH';
|
|
10
|
+
constructor(table, detail) {
|
|
11
|
+
super(`[biome-database] SDK_OWNED_TABLE_SHAPE_MISMATCH: table "${table}" is owned by an SDK and does not have the shape that SDK creates: ${detail}. ` +
|
|
12
|
+
'Nothing but the owning SDK may create or alter an SDK-owned table (no schema.prisma model, no service migration, no manual DDL). ' +
|
|
13
|
+
'The remedy is a reset of this database schema so the SDK creates the table.');
|
|
14
|
+
this.table = table;
|
|
15
|
+
this.detail = detail;
|
|
16
|
+
this.name = 'SdkOwnedTableShapeError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.SdkOwnedTableShapeError = SdkOwnedTableShapeError;
|
|
20
|
+
const CURRENT_SCHEMA_TABLE = `to_regclass(quote_ident(current_schema()) || '.' || quote_ident($1))`;
|
|
21
|
+
const COLUMNS_SQL = `SELECT a.attname::text AS name,
|
|
22
|
+
format_type(a.atttypid, a.atttypmod) AS type,
|
|
23
|
+
a.attnotnull AS not_null,
|
|
24
|
+
pg_get_expr(d.adbin, d.adrelid) AS default_sql
|
|
25
|
+
FROM pg_attribute a
|
|
26
|
+
LEFT JOIN pg_attrdef d ON d.adrelid = a.attrelid AND d.adnum = a.attnum
|
|
27
|
+
WHERE a.attrelid = ${CURRENT_SCHEMA_TABLE}
|
|
28
|
+
AND a.attnum > 0
|
|
29
|
+
AND NOT a.attisdropped`;
|
|
30
|
+
const CONSTRAINTS_SQL = `SELECT c.conname::text AS name,
|
|
31
|
+
c.contype::text AS kind,
|
|
32
|
+
pg_get_constraintdef(c.oid) AS definition,
|
|
33
|
+
(SELECT array_agg(att.attname::text ORDER BY k.ord)
|
|
34
|
+
FROM unnest(c.conkey) WITH ORDINALITY AS k(attnum, ord)
|
|
35
|
+
JOIN pg_attribute att
|
|
36
|
+
ON att.attrelid = c.conrelid AND att.attnum = k.attnum) AS columns
|
|
37
|
+
FROM pg_constraint c
|
|
38
|
+
WHERE c.conrelid = ${CURRENT_SCHEMA_TABLE}
|
|
39
|
+
AND c.contype <> 'n'`;
|
|
40
|
+
const INDEXES_SQL = `SELECT ic.relname::text AS name,
|
|
41
|
+
i.indisunique AS is_unique,
|
|
42
|
+
i.indisprimary AS is_primary,
|
|
43
|
+
(SELECT array_agg(pg_get_indexdef(i.indexrelid, k.n, true) ORDER BY k.n)
|
|
44
|
+
FROM generate_series(1, i.indnkeyatts) AS k(n)) AS columns,
|
|
45
|
+
pg_get_expr(i.indpred, i.indrelid) AS predicate
|
|
46
|
+
FROM pg_index i
|
|
47
|
+
JOIN pg_class ic ON ic.oid = i.indexrelid
|
|
48
|
+
WHERE i.indrelid = ${CURRENT_SCHEMA_TABLE}`;
|
|
49
|
+
async function ownedTableExists(database, table) {
|
|
50
|
+
const result = await database.query(`SELECT ${CURRENT_SCHEMA_TABLE} IS NOT NULL AS present`, [table]);
|
|
51
|
+
return result.rows[0]?.present === true;
|
|
52
|
+
}
|
|
53
|
+
function sameList(a, b) {
|
|
54
|
+
return a.length === b.length && a.every((value, index) => value === b[index]);
|
|
55
|
+
}
|
|
56
|
+
function assertColumns(expected, observed) {
|
|
57
|
+
for (const column of expected.columns) {
|
|
58
|
+
const actual = observed.find((candidate) => candidate.name === column.name);
|
|
59
|
+
if (actual === undefined) {
|
|
60
|
+
throw new SdkOwnedTableShapeError(expected.name, `column "${column.name}" is missing`);
|
|
61
|
+
}
|
|
62
|
+
if (actual.type !== column.type) {
|
|
63
|
+
throw new SdkOwnedTableShapeError(expected.name, `column "${column.name}" has type ${actual.type}, expected ${column.type}`);
|
|
64
|
+
}
|
|
65
|
+
if (actual.not_null !== column.notNull) {
|
|
66
|
+
throw new SdkOwnedTableShapeError(expected.name, `column "${column.name}" ${column.notNull
|
|
67
|
+
? 'is nullable, expected NOT NULL'
|
|
68
|
+
: 'is NOT NULL, expected nullable'}`);
|
|
69
|
+
}
|
|
70
|
+
if (actual.default_sql !== column.default) {
|
|
71
|
+
throw new SdkOwnedTableShapeError(expected.name, `column "${column.name}" has default ${actual.default_sql ?? 'none'}, expected ${column.default ?? 'none'}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const unexpected = observed.find((candidate) => !expected.columns.some((column) => column.name === candidate.name));
|
|
75
|
+
if (unexpected !== undefined) {
|
|
76
|
+
throw new SdkOwnedTableShapeError(expected.name, `column "${unexpected.name}" is not part of the table`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function assertConstraints(expected, observed) {
|
|
80
|
+
const foreign = observed.find((constraint) => !['p', 'c', 'u'].includes(constraint.kind));
|
|
81
|
+
if (foreign !== undefined) {
|
|
82
|
+
throw new SdkOwnedTableShapeError(expected.name, `constraint "${foreign.name}" (${foreign.definition}) is not part of the table`);
|
|
83
|
+
}
|
|
84
|
+
const primaryKey = observed.find((constraint) => constraint.kind === 'p')?.columns ?? [];
|
|
85
|
+
if (!sameList(primaryKey, expected.primaryKey)) {
|
|
86
|
+
throw new SdkOwnedTableShapeError(expected.name, `the primary key is (${primaryKey.join(', ')}), expected (${expected.primaryKey.join(', ')})`);
|
|
87
|
+
}
|
|
88
|
+
const checks = observed.filter((constraint) => constraint.kind === 'c');
|
|
89
|
+
for (const check of expected.checks) {
|
|
90
|
+
const actual = checks.find((candidate) => candidate.name === check.name);
|
|
91
|
+
if (actual === undefined) {
|
|
92
|
+
throw new SdkOwnedTableShapeError(expected.name, `CHECK constraint "${check.name}" is missing`);
|
|
93
|
+
}
|
|
94
|
+
if (actual.definition !== check.definition) {
|
|
95
|
+
throw new SdkOwnedTableShapeError(expected.name, `CHECK constraint "${check.name}" is ${actual.definition}, expected ${check.definition}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const unexpected = checks.find((candidate) => !expected.checks.some((check) => check.name === candidate.name));
|
|
99
|
+
if (unexpected !== undefined) {
|
|
100
|
+
throw new SdkOwnedTableShapeError(expected.name, `CHECK constraint "${unexpected.name}" is not part of the table`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function assertIndexes(expected, observed) {
|
|
104
|
+
const indexes = observed.filter((index) => !index.is_primary);
|
|
105
|
+
for (const index of expected.indexes) {
|
|
106
|
+
const actual = indexes.find((candidate) => candidate.name === index.name);
|
|
107
|
+
if (actual === undefined) {
|
|
108
|
+
throw new SdkOwnedTableShapeError(expected.name, `index "${index.name}" is missing`);
|
|
109
|
+
}
|
|
110
|
+
if (actual.is_unique !== index.unique ||
|
|
111
|
+
!sameList(actual.columns, index.columns) ||
|
|
112
|
+
actual.predicate !== index.predicate) {
|
|
113
|
+
throw new SdkOwnedTableShapeError(expected.name, `index "${index.name}" is ${describeIndex(actual.is_unique, actual.columns, actual.predicate)}, ` +
|
|
114
|
+
`expected ${describeIndex(index.unique, index.columns, index.predicate)}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
const unexpected = indexes.find((candidate) => !expected.indexes.some((index) => index.name === candidate.name));
|
|
118
|
+
if (unexpected !== undefined) {
|
|
119
|
+
throw new SdkOwnedTableShapeError(expected.name, `index "${unexpected.name}" is not part of the table`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function describeIndex(unique, columns, predicate) {
|
|
123
|
+
return `${unique ? 'UNIQUE ' : ''}(${columns.join(', ')})${predicate === null ? '' : ` WHERE ${predicate}`}`;
|
|
124
|
+
}
|
|
125
|
+
async function assertOwnedTableShape(database, expected) {
|
|
126
|
+
if (!(await ownedTableExists(database, expected.name))) {
|
|
127
|
+
throw new SdkOwnedTableShapeError(expected.name, 'the table is missing');
|
|
128
|
+
}
|
|
129
|
+
const regclass = [expected.name];
|
|
130
|
+
const columns = await database.query(COLUMNS_SQL, regclass);
|
|
131
|
+
assertColumns(expected, columns.rows);
|
|
132
|
+
const constraints = await database.query(CONSTRAINTS_SQL, regclass);
|
|
133
|
+
assertConstraints(expected, constraints.rows);
|
|
134
|
+
const indexes = await database.query(INDEXES_SQL, regclass);
|
|
135
|
+
assertIndexes(expected, indexes.rows);
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=owned-table-shape.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"owned-table-shape.js","sourceRoot":"","sources":["../../src/lib/owned-table-shape.ts"],"names":[],"mappings":"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"}
|