@xemahq/biome-database-nest 0.37.0 → 1.0.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 +58 -0
- package/dist/index.d.ts +9 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -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 +4 -1
- package/dist/lib/bootstrap.d.ts.map +1 -1
- package/dist/lib/bootstrap.js +27 -17
- package/dist/lib/bootstrap.js.map +1 -1
- package/dist/lib/credential-client.d.ts +5 -1
- package/dist/lib/credential-client.d.ts.map +1 -1
- package/dist/lib/credential-client.js +7 -2
- package/dist/lib/credential-client.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 +5 -0
- package/dist/lib/nest/biome-database.module.d.ts.map +1 -1
- package/dist/lib/nest/biome-database.module.js +53 -6
- 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 +78 -20
- 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 +8 -8
|
@@ -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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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export declare class SdkOwnedTableNotCreatedByOwnerError extends Error {
|
|
2
|
+
readonly table: string;
|
|
3
|
+
readonly owner: string;
|
|
4
|
+
readonly code = "SDK_OWNED_TABLE_NOT_CREATED_BY_OWNER";
|
|
5
|
+
constructor(table: string, owner: string);
|
|
6
|
+
}
|
|
7
|
+
export declare class SdkOwnedMigrationsUnknownToImageError extends Error {
|
|
8
|
+
readonly migrationIds: readonly string[];
|
|
9
|
+
readonly code = "SDK_OWNED_MIGRATIONS_UNKNOWN_TO_IMAGE";
|
|
10
|
+
constructor(migrationIds: readonly string[]);
|
|
11
|
+
}
|
|
12
|
+
export declare class SdkOwnedMigrationChangedError extends Error {
|
|
13
|
+
readonly migrationId: string;
|
|
14
|
+
readonly code = "SDK_OWNED_MIGRATION_CHANGED";
|
|
15
|
+
constructor(migrationId: string);
|
|
16
|
+
}
|
|
17
|
+
export declare class ServiceMigrationTouchesSdkOwnedTableError extends Error {
|
|
18
|
+
readonly migration: string;
|
|
19
|
+
readonly table: string;
|
|
20
|
+
readonly owner: string;
|
|
21
|
+
readonly code = "SERVICE_MIGRATION_TOUCHES_SDK_OWNED_TABLE";
|
|
22
|
+
constructor(migration: string, table: string, owner: string);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=sdk-owned-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-owned-errors.d.ts","sourceRoot":"","sources":["../../src/lib/sdk-owned-errors.ts"],"names":[],"mappings":"AAQA,qBAAa,mCAAoC,SAAQ,KAAK;aAI1C,KAAK,EAAE,MAAM;aACb,KAAK,EAAE,MAAM;IAJ/B,SAAgB,IAAI,0CAA0C;gBAG5C,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM;CAShC;AAOD,qBAAa,qCAAsC,SAAQ,KAAK;aAG3B,YAAY,EAAE,SAAS,MAAM,EAAE;IAFlE,SAAgB,IAAI,2CAA2C;gBAE5B,YAAY,EAAE,SAAS,MAAM,EAAE;CAQnE;AAOD,qBAAa,6BAA8B,SAAQ,KAAK;aAGnB,WAAW,EAAE,MAAM;IAFtD,SAAgB,IAAI,iCAAiC;gBAElB,WAAW,EAAE,MAAM;CAOvD;AAQD,qBAAa,yCAA0C,SAAQ,KAAK;aAIhD,SAAS,EAAE,MAAM;aACjB,KAAK,EAAE,MAAM;aACb,KAAK,EAAE,MAAM;IAL/B,SAAgB,IAAI,+CAA+C;gBAGjD,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM;CAShC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ServiceMigrationTouchesSdkOwnedTableError = exports.SdkOwnedMigrationChangedError = exports.SdkOwnedMigrationsUnknownToImageError = exports.SdkOwnedTableNotCreatedByOwnerError = void 0;
|
|
4
|
+
const RESET_REMEDY = 'The remedy is a reset of this database schema, so the owning SDK creates its tables and records them. Never edit the ledger by hand.';
|
|
5
|
+
class SdkOwnedTableNotCreatedByOwnerError extends Error {
|
|
6
|
+
table;
|
|
7
|
+
owner;
|
|
8
|
+
code = 'SDK_OWNED_TABLE_NOT_CREATED_BY_OWNER';
|
|
9
|
+
constructor(table, owner) {
|
|
10
|
+
super(`[biome-database] SDK_OWNED_TABLE_NOT_CREATED_BY_OWNER: table "${table}" is owned by the SDK "${owner}", ` +
|
|
11
|
+
`it already exists in this schema, and the ledger has no record of "${owner}" creating it. ` +
|
|
12
|
+
`Only "${owner}" creates "${table}"; a table created by anything else is refused, not adopted. ${RESET_REMEDY}`);
|
|
13
|
+
this.table = table;
|
|
14
|
+
this.owner = owner;
|
|
15
|
+
this.name = 'SdkOwnedTableNotCreatedByOwnerError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.SdkOwnedTableNotCreatedByOwnerError = SdkOwnedTableNotCreatedByOwnerError;
|
|
19
|
+
class SdkOwnedMigrationsUnknownToImageError extends Error {
|
|
20
|
+
migrationIds;
|
|
21
|
+
code = 'SDK_OWNED_MIGRATIONS_UNKNOWN_TO_IMAGE';
|
|
22
|
+
constructor(migrationIds) {
|
|
23
|
+
super(`[biome-database] SDK_OWNED_MIGRATIONS_UNKNOWN_TO_IMAGE: the ledger records SDK-owned migrations this image does not ship: ` +
|
|
24
|
+
`${migrationIds.join(', ')}. The database is newer than this image, or this image no longer mounts an SDK whose tables remain. ` +
|
|
25
|
+
'Roll forward to an image that ships them; an image that dropped the SDK needs a reset of this database schema. Never edit the ledger by hand.');
|
|
26
|
+
this.migrationIds = migrationIds;
|
|
27
|
+
this.name = 'SdkOwnedMigrationsUnknownToImageError';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.SdkOwnedMigrationsUnknownToImageError = SdkOwnedMigrationsUnknownToImageError;
|
|
31
|
+
class SdkOwnedMigrationChangedError extends Error {
|
|
32
|
+
migrationId;
|
|
33
|
+
code = 'SDK_OWNED_MIGRATION_CHANGED';
|
|
34
|
+
constructor(migrationId) {
|
|
35
|
+
super(`[biome-database] SDK_OWNED_MIGRATION_CHANGED: "${migrationId}" was applied to this schema with different SQL than this image ships. ` +
|
|
36
|
+
`A released SDK-owned migration is immutable. ${RESET_REMEDY}`);
|
|
37
|
+
this.migrationId = migrationId;
|
|
38
|
+
this.name = 'SdkOwnedMigrationChangedError';
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.SdkOwnedMigrationChangedError = SdkOwnedMigrationChangedError;
|
|
42
|
+
class ServiceMigrationTouchesSdkOwnedTableError extends Error {
|
|
43
|
+
migration;
|
|
44
|
+
table;
|
|
45
|
+
owner;
|
|
46
|
+
code = 'SERVICE_MIGRATION_TOUCHES_SDK_OWNED_TABLE';
|
|
47
|
+
constructor(migration, table, owner) {
|
|
48
|
+
super(`[biome-database] SERVICE_MIGRATION_TOUCHES_SDK_OWNED_TABLE: prisma/migrations/${migration}/migration.sql names "${table}", ` +
|
|
49
|
+
`which the SDK "${owner}" owns. A service migration may name an SDK-owned table only inside the body of a function it creates ` +
|
|
50
|
+
'(read at call time). Shape changes belong to a new migration in the owning SDK.');
|
|
51
|
+
this.migration = migration;
|
|
52
|
+
this.table = table;
|
|
53
|
+
this.owner = owner;
|
|
54
|
+
this.name = 'ServiceMigrationTouchesSdkOwnedTableError';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
exports.ServiceMigrationTouchesSdkOwnedTableError = ServiceMigrationTouchesSdkOwnedTableError;
|
|
58
|
+
//# sourceMappingURL=sdk-owned-errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-owned-errors.js","sourceRoot":"","sources":["../../src/lib/sdk-owned-errors.ts"],"names":[],"mappings":";;;AAAA,MAAM,YAAY,GAChB,sIAAsI,CAAC;AAOzI,MAAa,mCAAoC,SAAQ,KAAK;IAI1C;IACA;IAJF,IAAI,GAAG,sCAAsC,CAAC;IAE9D,YACkB,KAAa,EACb,KAAa;QAE7B,KAAK,CACH,iEAAiE,KAAK,0BAA0B,KAAK,KAAK;YACxG,sEAAsE,KAAK,iBAAiB;YAC5F,SAAS,KAAK,cAAc,KAAK,gEAAgE,YAAY,EAAE,CAClH,CAAC;QAPc,UAAK,GAAL,KAAK,CAAQ;QACb,UAAK,GAAL,KAAK,CAAQ;QAO7B,IAAI,CAAC,IAAI,GAAG,qCAAqC,CAAC;IACpD,CAAC;CACF;AAdD,kFAcC;AAOD,MAAa,qCAAsC,SAAQ,KAAK;IAG3B;IAFnB,IAAI,GAAG,uCAAuC,CAAC;IAE/D,YAAmC,YAA+B;QAChE,KAAK,CACH,4HAA4H;YAC1H,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,sGAAsG;YAChI,+IAA+I,CAClJ,CAAC;QAL+B,iBAAY,GAAZ,YAAY,CAAmB;QAMhE,IAAI,CAAC,IAAI,GAAG,uCAAuC,CAAC;IACtD,CAAC;CACF;AAXD,sFAWC;AAOD,MAAa,6BAA8B,SAAQ,KAAK;IAGnB;IAFnB,IAAI,GAAG,6BAA6B,CAAC;IAErD,YAAmC,WAAmB;QACpD,KAAK,CACH,kDAAkD,WAAW,yEAAyE;YACpI,gDAAgD,YAAY,EAAE,CACjE,CAAC;QAJ+B,gBAAW,GAAX,WAAW,CAAQ;QAKpD,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAC;IAC9C,CAAC;CACF;AAVD,sEAUC;AAQD,MAAa,yCAA0C,SAAQ,KAAK;IAIhD;IACA;IACA;IALF,IAAI,GAAG,2CAA2C,CAAC;IAEnE,YACkB,SAAiB,EACjB,KAAa,EACb,KAAa;QAE7B,KAAK,CACH,iFAAiF,SAAS,yBAAyB,KAAK,KAAK;YAC3H,kBAAkB,KAAK,wGAAwG;YAC/H,iFAAiF,CACpF,CAAC;QARc,cAAS,GAAT,SAAS,CAAQ;QACjB,UAAK,GAAL,KAAK,CAAQ;QACb,UAAK,GAAL,KAAK,CAAQ;QAO7B,IAAI,CAAC,IAAI,GAAG,2CAA2C,CAAC;IAC1D,CAAC;CACF;AAfD,8FAeC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { OwnedTableShape } from './owned-table-shape';
|
|
2
|
+
export interface SdkOwnedMigration {
|
|
3
|
+
readonly version: string;
|
|
4
|
+
readonly sql: string;
|
|
5
|
+
readonly creates: readonly string[];
|
|
6
|
+
}
|
|
7
|
+
export interface SdkOwnedMigrationSet {
|
|
8
|
+
readonly owner: string;
|
|
9
|
+
readonly migrations: readonly SdkOwnedMigration[];
|
|
10
|
+
readonly tables: readonly OwnedTableShape[];
|
|
11
|
+
}
|
|
12
|
+
export declare class SdkOwnedMigrationSetInvalidError extends Error {
|
|
13
|
+
readonly code = "SDK_OWNED_MIGRATION_SET_INVALID";
|
|
14
|
+
constructor(owner: string, detail: string);
|
|
15
|
+
}
|
|
16
|
+
export declare function sdkOwnedMigrationId(owner: string, version: string): string;
|
|
17
|
+
export declare function sdkOwnedMigrationDigests(set: SdkOwnedMigrationSet): Record<string, string>;
|
|
18
|
+
export declare function assertSdkOwnedMigrationSets(sets: readonly SdkOwnedMigrationSet[]): void;
|
|
19
|
+
//# sourceMappingURL=sdk-owned-migration-set.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-owned-migration-set.d.ts","sourceRoot":"","sources":["../../src/lib/sdk-owned-migration-set.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAa3D,MAAM,WAAW,iBAAiB;IAEhC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAErB,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAQD,MAAM,WAAW,oBAAoB;IAEnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAElD,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;CAC7C;AAGD,qBAAa,gCAAiC,SAAQ,KAAK;IACzD,SAAgB,IAAI,qCAAqC;gBAEtC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAMjD;AAGD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE1E;AAQD,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,oBAAoB,GACxB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIxB;AAiED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,SAAS,oBAAoB,EAAE,GACpC,IAAI,CAoBN"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SdkOwnedMigrationSetInvalidError = void 0;
|
|
4
|
+
exports.sdkOwnedMigrationId = sdkOwnedMigrationId;
|
|
5
|
+
exports.sdkOwnedMigrationDigests = sdkOwnedMigrationDigests;
|
|
6
|
+
exports.assertSdkOwnedMigrationSets = assertSdkOwnedMigrationSets;
|
|
7
|
+
const ledger_rows_1 = require("./ledger-rows");
|
|
8
|
+
const OWNER_PATTERN = /^[a-z][a-z0-9-]{0,63}$/u;
|
|
9
|
+
const VERSION_PATTERN = /^[0-9]{4}-[a-z0-9][a-z0-9-]{0,48}$/u;
|
|
10
|
+
const TABLE_PATTERN = /^[a-z][a-z0-9_]{0,62}$/u;
|
|
11
|
+
const IF_NOT_EXISTS_PATTERN = /\bIF\s+NOT\s+EXISTS\b/iu;
|
|
12
|
+
class SdkOwnedMigrationSetInvalidError extends Error {
|
|
13
|
+
code = 'SDK_OWNED_MIGRATION_SET_INVALID';
|
|
14
|
+
constructor(owner, detail) {
|
|
15
|
+
super(`[biome-database] SDK_OWNED_MIGRATION_SET_INVALID: the migration set of "${owner}" ${detail}.`);
|
|
16
|
+
this.name = 'SdkOwnedMigrationSetInvalidError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.SdkOwnedMigrationSetInvalidError = SdkOwnedMigrationSetInvalidError;
|
|
20
|
+
function sdkOwnedMigrationId(owner, version) {
|
|
21
|
+
return `sdk-${owner}-${version}`;
|
|
22
|
+
}
|
|
23
|
+
function sdkOwnedMigrationDigests(set) {
|
|
24
|
+
return Object.fromEntries(set.migrations.map((migration) => [migration.version, (0, ledger_rows_1.sha256)(migration.sql)]));
|
|
25
|
+
}
|
|
26
|
+
function assertSet(set) {
|
|
27
|
+
if (!OWNER_PATTERN.test(set.owner)) {
|
|
28
|
+
throw new SdkOwnedMigrationSetInvalidError(set.owner, 'has an invalid owner');
|
|
29
|
+
}
|
|
30
|
+
const versions = set.migrations.map((migration) => migration.version);
|
|
31
|
+
for (const version of versions) {
|
|
32
|
+
if (!VERSION_PATTERN.test(version)) {
|
|
33
|
+
throw new SdkOwnedMigrationSetInvalidError(set.owner, `has an invalid version "${version}"`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (new Set(versions).size !== versions.length) {
|
|
37
|
+
throw new SdkOwnedMigrationSetInvalidError(set.owner, 'declares a migration version twice');
|
|
38
|
+
}
|
|
39
|
+
if (versions.join() !== [...versions].sort().join()) {
|
|
40
|
+
throw new SdkOwnedMigrationSetInvalidError(set.owner, 'does not list its migrations in version order');
|
|
41
|
+
}
|
|
42
|
+
for (const migration of set.migrations) {
|
|
43
|
+
if (IF_NOT_EXISTS_PATTERN.test(migration.sql)) {
|
|
44
|
+
throw new SdkOwnedMigrationSetInvalidError(set.owner, `uses IF NOT EXISTS in ${migration.version}; an SDK-owned object that already exists must fail the migration`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const created = set.migrations.flatMap((migration) => migration.creates);
|
|
48
|
+
const tables = set.tables.map((table) => table.name);
|
|
49
|
+
for (const table of tables) {
|
|
50
|
+
if (!TABLE_PATTERN.test(table)) {
|
|
51
|
+
throw new SdkOwnedMigrationSetInvalidError(set.owner, `has an invalid table name "${table}"`);
|
|
52
|
+
}
|
|
53
|
+
const creators = created.filter((name) => name === table).length;
|
|
54
|
+
if (creators !== 1) {
|
|
55
|
+
throw new SdkOwnedMigrationSetInvalidError(set.owner, `names ${creators} migrations that create "${table}"; exactly one must`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const undeclared = created.find((name) => !tables.includes(name));
|
|
59
|
+
if (undeclared !== undefined) {
|
|
60
|
+
throw new SdkOwnedMigrationSetInvalidError(set.owner, `creates "${undeclared}" without declaring its shape`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function assertSdkOwnedMigrationSets(sets) {
|
|
64
|
+
const ownerOfTable = new Map();
|
|
65
|
+
const owners = new Set();
|
|
66
|
+
for (const set of sets) {
|
|
67
|
+
assertSet(set);
|
|
68
|
+
if (owners.has(set.owner)) {
|
|
69
|
+
throw new SdkOwnedMigrationSetInvalidError(set.owner, 'is listed twice');
|
|
70
|
+
}
|
|
71
|
+
owners.add(set.owner);
|
|
72
|
+
for (const table of set.tables) {
|
|
73
|
+
const other = ownerOfTable.get(table.name);
|
|
74
|
+
if (other !== undefined) {
|
|
75
|
+
throw new SdkOwnedMigrationSetInvalidError(set.owner, `claims "${table.name}", which "${other}" owns`);
|
|
76
|
+
}
|
|
77
|
+
ownerOfTable.set(table.name, set.owner);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=sdk-owned-migration-set.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-owned-migration-set.js","sourceRoot":"","sources":["../../src/lib/sdk-owned-migration-set.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type OperatorMigrationDatabase } from './ledger-rows';
|
|
2
|
+
import { type SdkOwnedMigrationSet } from './sdk-owned-migration-set';
|
|
3
|
+
export declare function sdkOwnedTableOwners(sets: readonly SdkOwnedMigrationSet[]): Map<string, string>;
|
|
4
|
+
export declare function applySdkOwnedMigrations(database: OperatorMigrationDatabase, sets: readonly SdkOwnedMigrationSet[]): Promise<void>;
|
|
5
|
+
//# sourceMappingURL=sdk-owned-migrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-owned-migrations.d.ts","sourceRoot":"","sources":["../../src/lib/sdk-owned-migrations.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,yBAAyB,EAC/B,MAAM,eAAe,CAAC;AAYvB,OAAO,EAGL,KAAK,oBAAoB,EAC1B,MAAM,2BAA2B,CAAC;AAcnC,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,SAAS,oBAAoB,EAAE,GACpC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAQrB;AAsCD,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,yBAAyB,EACnC,IAAI,EAAE,SAAS,oBAAoB,EAAE,GACpC,OAAO,CAAC,IAAI,CAAC,CAqCf"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sdkOwnedTableOwners = sdkOwnedTableOwners;
|
|
4
|
+
exports.applySdkOwnedMigrations = applySdkOwnedMigrations;
|
|
5
|
+
const ledger_rows_1 = require("./ledger-rows");
|
|
6
|
+
const operator_migration_1 = require("./operator-migration");
|
|
7
|
+
const operator_migration_ledger_1 = require("./operator-migration-ledger");
|
|
8
|
+
const owned_table_shape_1 = require("./owned-table-shape");
|
|
9
|
+
const sdk_owned_errors_1 = require("./sdk-owned-errors");
|
|
10
|
+
const sdk_owned_migration_set_1 = require("./sdk-owned-migration-set");
|
|
11
|
+
function migrationIdsOf(sets) {
|
|
12
|
+
return sets.flatMap((set) => set.migrations.map((migration) => (0, sdk_owned_migration_set_1.sdkOwnedMigrationId)(set.owner, migration.version)));
|
|
13
|
+
}
|
|
14
|
+
function sdkOwnedTableOwners(sets) {
|
|
15
|
+
const all = [operator_migration_ledger_1.operatorMigrationLedgerMigrations, ...sets];
|
|
16
|
+
(0, sdk_owned_migration_set_1.assertSdkOwnedMigrationSets)(all);
|
|
17
|
+
return new Map(all.flatMap((set) => set.tables.map((table) => [table.name, set.owner])));
|
|
18
|
+
}
|
|
19
|
+
async function assertLedgerKnownToImage(database, sets) {
|
|
20
|
+
const known = new Set(migrationIdsOf([operator_migration_ledger_1.operatorMigrationLedgerMigrations, ...sets]));
|
|
21
|
+
const recorded = await database.query(`SELECT migration_id FROM "${operator_migration_ledger_1.OPERATOR_MIGRATION_LEDGER_TABLE}" WHERE phase = $1 ORDER BY migration_id`, [ledger_rows_1.OperatorMigrationPhase.Applied]);
|
|
22
|
+
const unknown = recorded.rows
|
|
23
|
+
.map((row) => row.migration_id)
|
|
24
|
+
.filter((migrationId) => !known.has(migrationId));
|
|
25
|
+
if (unknown.length > 0) {
|
|
26
|
+
throw new sdk_owned_errors_1.SdkOwnedMigrationsUnknownToImageError(unknown);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async function applySdkOwnedMigrations(database, sets) {
|
|
30
|
+
sdkOwnedTableOwners(sets);
|
|
31
|
+
await assertLedgerKnownToImage(database, sets);
|
|
32
|
+
for (const set of sets) {
|
|
33
|
+
for (const migration of set.migrations) {
|
|
34
|
+
const migrationId = (0, sdk_owned_migration_set_1.sdkOwnedMigrationId)(set.owner, migration.version);
|
|
35
|
+
const artifactSha256 = (0, ledger_rows_1.sha256)(migration.sql);
|
|
36
|
+
await (0, operator_migration_1.inMigrationTransaction)(database, migrationId, async (tx) => {
|
|
37
|
+
const recorded = await (0, ledger_rows_1.readPhase)(tx, migrationId, ledger_rows_1.OperatorMigrationPhase.Applied);
|
|
38
|
+
if (recorded !== null) {
|
|
39
|
+
if (recorded !== artifactSha256) {
|
|
40
|
+
throw new sdk_owned_errors_1.SdkOwnedMigrationChangedError(migrationId);
|
|
41
|
+
}
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
for (const table of migration.creates) {
|
|
45
|
+
if (await (0, owned_table_shape_1.ownedTableExists)(tx, table)) {
|
|
46
|
+
throw new sdk_owned_errors_1.SdkOwnedTableNotCreatedByOwnerError(table, set.owner);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
await tx.query(migration.sql);
|
|
50
|
+
await (0, ledger_rows_1.recordPhase)(tx, migrationId, ledger_rows_1.OperatorMigrationPhase.Applied, artifactSha256);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
for (const table of set.tables) {
|
|
54
|
+
await (0, owned_table_shape_1.assertOwnedTableShape)(database, table);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=sdk-owned-migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk-owned-migrations.js","sourceRoot":"","sources":["../../src/lib/sdk-owned-migrations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function sdkOwnedTableNamedByMigration(sql: string, tables: readonly string[]): string | undefined;
|
|
2
|
+
export declare function assertServiceMigrationsLeaveSdkOwnedTablesAlone(workspaceDir: string, ownerOfTable: ReadonlyMap<string, string>): Promise<void>;
|
|
3
|
+
//# sourceMappingURL=service-migration-scan.d.ts.map
|