@xemahq/biome-database-nest 0.16.11 → 0.16.13
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 +7 -40
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/bootstrap.d.ts +2 -0
- package/dist/lib/bootstrap.d.ts.map +1 -1
- package/dist/lib/bootstrap.js +53 -8
- package/dist/lib/bootstrap.js.map +1 -1
- package/dist/lib/migration-history.d.ts +13 -0
- package/dist/lib/migration-history.d.ts.map +1 -0
- package/dist/lib/migration-history.js +88 -0
- package/dist/lib/migration-history.js.map +1 -0
- package/dist/lib/operator-migration.d.ts +33 -0
- package/dist/lib/operator-migration.d.ts.map +1 -0
- package/dist/lib/operator-migration.js +112 -0
- package/dist/lib/operator-migration.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,33 +28,16 @@
|
|
|
28
28
|
|
|
29
29
|
## Overview
|
|
30
30
|
|
|
31
|
-
Gives a Xema biome service
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
A biome carries **no** database configuration: no host, no credential, no URL,
|
|
37
|
-
no schema name, nothing to put in a Helm chart or a secret. Those are facts the
|
|
38
|
-
platform owns, and a biome that had to know them would be a biome that breaks
|
|
39
|
-
when they change.
|
|
40
|
-
|
|
41
|
-
## What a biome gets
|
|
42
|
-
|
|
43
|
-
- **A database of its own, on first boot.** The pool binds the service to it and
|
|
44
|
-
holds it there, so the name can never silently move to an empty schema.
|
|
45
|
-
- **A schema-qualified Prisma client**, already pointed at that database.
|
|
46
|
-
- **Migrations applied at boot** — `prisma migrate deploy`, which THROWS on
|
|
47
|
-
failure, so a bad migration stops the pod becoming ready instead of half-
|
|
48
|
-
applying under live traffic.
|
|
49
|
-
- **More than one database when it needs one.** A biome that ships several API
|
|
50
|
-
services gives each its own; a single service that needs a second declares a
|
|
51
|
-
`dbKey`. Physically these are schemas in the shared `xema_biomes` database —
|
|
52
|
-
`biome_<biomeId>` for the primary, `biome_<biomeId>__<dbKey>` for the rest.
|
|
31
|
+
Gives a Xema biome service explicit database ownership without coupling it to a
|
|
32
|
+
deployment environment. It supplies schema-qualified Prisma wiring, validates
|
|
33
|
+
image/schema compatibility, and provides a governed lifecycle for data
|
|
34
|
+
cutovers that require an operator between expansion and contraction.
|
|
53
35
|
|
|
54
36
|
## When to use it
|
|
55
37
|
|
|
56
|
-
Use it
|
|
57
|
-
|
|
38
|
+
- Use it when a NestJS biome service stores data or owns database migrations.
|
|
39
|
+
- Use its operator lifecycle when a destructive contraction must wait for a
|
|
40
|
+
verified backfill instead of running automatically at application startup.
|
|
58
41
|
|
|
59
42
|
## Installation
|
|
60
43
|
|
|
@@ -64,8 +47,6 @@ pnpm add @xemahq/biome-database-nest
|
|
|
64
47
|
|
|
65
48
|
## Usage
|
|
66
49
|
|
|
67
|
-
The whole integration:
|
|
68
|
-
|
|
69
50
|
```ts
|
|
70
51
|
import {
|
|
71
52
|
BiomeDatabaseMigrationMode,
|
|
@@ -79,20 +60,6 @@ BiomeDatabaseModule.forRoot({
|
|
|
79
60
|
});
|
|
80
61
|
```
|
|
81
62
|
|
|
82
|
-
`biomeId` names the database this service owns; it is pinned by the pool on
|
|
83
|
-
first resolve, so changing it later is refused rather than silently pointing the
|
|
84
|
-
service at a fresh empty schema. `workspaceDir` is where the Prisma schema and
|
|
85
|
-
`migrations/` live.
|
|
86
|
-
|
|
87
|
-
A second database for the same service:
|
|
88
|
-
|
|
89
|
-
```ts
|
|
90
|
-
databases: [
|
|
91
|
-
{ workspaceDir: process.cwd() },
|
|
92
|
-
{ key: 'analytics', workspaceDir: `${process.cwd()}/analytics` },
|
|
93
|
-
],
|
|
94
|
-
```
|
|
95
|
-
|
|
96
63
|
## Peer requirements
|
|
97
64
|
|
|
98
65
|
- NestJS 10 or 11 and Prisma 7.
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,9 @@ export { createBiomePrismaAdapter, createBiomePrismaAdapterFromEnv, } from './li
|
|
|
6
6
|
export { fetchSystemDatabaseConfig, type SystemDatabaseConfigRequest, } from './lib/control-plane-client';
|
|
7
7
|
export { resolveControlPlaneBaseUrl, ORG_DATABASE_POOL_SERVICE_NAME, type ControlPlaneDiscoveryOptions, } from './lib/control-plane-discovery';
|
|
8
8
|
export { bootstrapBiomeDatabases, type BiomeDatabaseDeclaration, type BootstrapBiomeDatabasesOptions, } from './lib/bootstrap';
|
|
9
|
+
export type { PrismaMigrationHistoryPolicy } from './lib/migration-history';
|
|
9
10
|
export { BiomeDatabaseMigrationMode } from './lib/migration-mode';
|
|
11
|
+
export { contractOperatorMigration, OperatorMigrationMode, OperatorMigrationPhase, parseOperatorMigrationMode, verifyOperatorMigration, type ContractOperatorMigrationOptions, type OperatorMigrationDatabase, type VerifyOperatorMigrationOptions, } from './lib/operator-migration';
|
|
10
12
|
export { BiomeDatabaseModule, BIOME_DATABASE_READY, type ApplicationManagedBiomeDatabaseModuleOptions, type BiomeDatabaseModuleOptions, } from './lib/nest/biome-database.module';
|
|
11
13
|
export { createBiomePrismaService, type BiomePrismaClient, type BiomePrismaClientCtor, type BiomePrismaServiceInstance, type CreateBiomePrismaServiceOptions, type TenantIsolationServiceOptions, type TenantScopedApi, } from './lib/nest/prisma-service-factory';
|
|
12
14
|
export { TenantIsolationMode, TENANT_ISOLATION_MODE_ENV_VAR, resolveTenantIsolationMode, } from './lib/tenant-isolation/tenant-isolation-mode';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.ORG_ERASURE_ROUTE_PATH = exports.ORG_DATA_ERASURE_CAPABILITY = exports.ORG_ERASURE_RUNNER = exports.OrgErasureController = exports.OrgErasureModule = exports.ORGANIZATION_PROTECTED_ERROR_CODE = exports.IDENTITY_SERVICE_NAME = exports.ProtectedOrgErasureRefusedError = exports.OrgProtectionUnavailableError = void 0;
|
|
3
|
+
exports.OrgErasureBlockedError = exports.eraseOrgData = exports.assertOrgErasureMatchesModels = exports.UndeclaredUnscopedModelsError = exports.normalizeUnscopedModelDeclarations = exports.formatUnscopedModelReport = exports.collectUnscopableModels = exports.assertUnscopedModelsDeclared = exports.readRuntimeModels = exports.createTenantIsolationExtension = exports.collectOrgScopedModels = exports.DEFAULT_ORG_FIELD = exports.scopeArgsToOrg = exports.PrismaModelOperation = exports.formatTenantIsolationViolation = exports.TenantIsolationViolationKind = exports.TenantIsolationError = exports.resolveTenantIsolationMode = exports.TENANT_ISOLATION_MODE_ENV_VAR = exports.TenantIsolationMode = exports.createBiomePrismaService = exports.BIOME_DATABASE_READY = exports.BiomeDatabaseModule = exports.verifyOperatorMigration = exports.parseOperatorMigrationMode = exports.OperatorMigrationPhase = exports.OperatorMigrationMode = exports.contractOperatorMigration = exports.BiomeDatabaseMigrationMode = exports.bootstrapBiomeDatabases = exports.ORG_DATABASE_POOL_SERVICE_NAME = exports.resolveControlPlaneBaseUrl = exports.fetchSystemDatabaseConfig = exports.createBiomePrismaAdapterFromEnv = exports.createBiomePrismaAdapter = exports.resolveBiomeDatabaseConfigFromEnv = exports.SCHEMA_ROLE_SUFFIX_LENGTH = exports.SCHEMA_ROLE_BASE_MAX_LENGTH = exports.SchemaRoleKind = exports.schemaRoleName = exports.schemaRoleBase = exports.rolesForSchema = exports.sanitizeIdentifierSegment = exports.sanitizeIdentifierChars = exports.POSTGRES_MAX_IDENTIFIER_LENGTH = exports.IDENTIFIER_HASH_LENGTH = exports.fitIdentifier = exports.composeIdentifier = exports.deriveBiomeSchemaName = exports.DEFAULT_BIOME_DB_KEY = void 0;
|
|
4
|
+
exports.ORG_ERASURE_ROUTE_PATH = exports.ORG_DATA_ERASURE_CAPABILITY = exports.ORG_ERASURE_RUNNER = exports.OrgErasureController = exports.OrgErasureModule = exports.ORGANIZATION_PROTECTED_ERROR_CODE = exports.IDENTITY_SERVICE_NAME = exports.ProtectedOrgErasureRefusedError = exports.OrgProtectionUnavailableError = exports.OrgProtectionGuard = exports.IdentityOrgProtectionProbe = exports.assertOrgNotProtected = exports.eraseOwnedAuthoredResourceGraph = exports.OrgErasureMatchesNothingError = void 0;
|
|
5
5
|
var schema_name_1 = require("./lib/schema-name");
|
|
6
6
|
Object.defineProperty(exports, "DEFAULT_BIOME_DB_KEY", { enumerable: true, get: function () { return schema_name_1.DEFAULT_BIOME_DB_KEY; } });
|
|
7
7
|
Object.defineProperty(exports, "deriveBiomeSchemaName", { enumerable: true, get: function () { return schema_name_1.deriveBiomeSchemaName; } });
|
|
@@ -33,6 +33,12 @@ var bootstrap_1 = require("./lib/bootstrap");
|
|
|
33
33
|
Object.defineProperty(exports, "bootstrapBiomeDatabases", { enumerable: true, get: function () { return bootstrap_1.bootstrapBiomeDatabases; } });
|
|
34
34
|
var migration_mode_1 = require("./lib/migration-mode");
|
|
35
35
|
Object.defineProperty(exports, "BiomeDatabaseMigrationMode", { enumerable: true, get: function () { return migration_mode_1.BiomeDatabaseMigrationMode; } });
|
|
36
|
+
var operator_migration_1 = require("./lib/operator-migration");
|
|
37
|
+
Object.defineProperty(exports, "contractOperatorMigration", { enumerable: true, get: function () { return operator_migration_1.contractOperatorMigration; } });
|
|
38
|
+
Object.defineProperty(exports, "OperatorMigrationMode", { enumerable: true, get: function () { return operator_migration_1.OperatorMigrationMode; } });
|
|
39
|
+
Object.defineProperty(exports, "OperatorMigrationPhase", { enumerable: true, get: function () { return operator_migration_1.OperatorMigrationPhase; } });
|
|
40
|
+
Object.defineProperty(exports, "parseOperatorMigrationMode", { enumerable: true, get: function () { return operator_migration_1.parseOperatorMigrationMode; } });
|
|
41
|
+
Object.defineProperty(exports, "verifyOperatorMigration", { enumerable: true, get: function () { return operator_migration_1.verifyOperatorMigration; } });
|
|
36
42
|
var biome_database_module_1 = require("./lib/nest/biome-database.module");
|
|
37
43
|
Object.defineProperty(exports, "BiomeDatabaseModule", { enumerable: true, get: function () { return biome_database_module_1.BiomeDatabaseModule; } });
|
|
38
44
|
Object.defineProperty(exports, "BIOME_DATABASE_READY", { enumerable: true, get: function () { return biome_database_module_1.BIOME_DATABASE_READY; } });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,iDAAgF;AAAvE,mHAAA,oBAAoB,OAAA;AAAE,oHAAA,qBAAqB,OAAA;AACpD,+CAS0B;AARxB,+GAAA,iBAAiB,OAAA;AACjB,2GAAA,aAAa,OAAA;AACb,oHAAA,sBAAsB,OAAA;AACtB,4HAAA,8BAA8B,OAAA;AAC9B,qHAAA,uBAAuB,OAAA;AACvB,uHAAA,yBAAyB,OAAA;AAI3B,+CAQ0B;AAPxB,4GAAA,cAAc,OAAA;AACd,4GAAA,cAAc,OAAA;AACd,4GAAA,cAAc,OAAA;AACd,4GAAA,cAAc,OAAA;AACd,yHAAA,2BAA2B,OAAA;AAC3B,uHAAA,yBAAyB,OAAA;AAG3B,uCAGsB;AAFpB,2HAAA,iCAAiC,OAAA;AAGnC,yCAGuB;AAFrB,mHAAA,wBAAwB,OAAA;AACxB,0HAAA,+BAA+B,OAAA;AAEjC,mEAGoC;AAFlC,iIAAA,yBAAyB,OAAA;AAG3B,yEAIuC;AAHrC,qIAAA,0BAA0B,OAAA;AAC1B,yIAAA,8BAA8B,OAAA;AAGhC,6CAIyB;AAHvB,oHAAA,uBAAuB,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,iDAAgF;AAAvE,mHAAA,oBAAoB,OAAA;AAAE,oHAAA,qBAAqB,OAAA;AACpD,+CAS0B;AARxB,+GAAA,iBAAiB,OAAA;AACjB,2GAAA,aAAa,OAAA;AACb,oHAAA,sBAAsB,OAAA;AACtB,4HAAA,8BAA8B,OAAA;AAC9B,qHAAA,uBAAuB,OAAA;AACvB,uHAAA,yBAAyB,OAAA;AAI3B,+CAQ0B;AAPxB,4GAAA,cAAc,OAAA;AACd,4GAAA,cAAc,OAAA;AACd,4GAAA,cAAc,OAAA;AACd,4GAAA,cAAc,OAAA;AACd,yHAAA,2BAA2B,OAAA;AAC3B,uHAAA,yBAAyB,OAAA;AAG3B,uCAGsB;AAFpB,2HAAA,iCAAiC,OAAA;AAGnC,yCAGuB;AAFrB,mHAAA,wBAAwB,OAAA;AACxB,0HAAA,+BAA+B,OAAA;AAEjC,mEAGoC;AAFlC,iIAAA,yBAAyB,OAAA;AAG3B,yEAIuC;AAHrC,qIAAA,0BAA0B,OAAA;AAC1B,yIAAA,8BAA8B,OAAA;AAGhC,6CAIyB;AAHvB,oHAAA,uBAAuB,OAAA;AAKzB,uDAAkE;AAAzD,4HAAA,0BAA0B,OAAA;AACnC,+DASkC;AARhC,+HAAA,yBAAyB,OAAA;AACzB,2HAAA,qBAAqB,OAAA;AACrB,4HAAA,sBAAsB,OAAA;AACtB,gIAAA,0BAA0B,OAAA;AAC1B,6HAAA,uBAAuB,OAAA;AAKzB,0EAK0C;AAJxC,4HAAA,mBAAmB,OAAA;AACnB,6HAAA,oBAAoB,OAAA;AAItB,4EAQ2C;AAPzC,kIAAA,wBAAwB,OAAA;AAQ1B,sFAIsD;AAHpD,4HAAA,mBAAmB,OAAA;AACnB,sIAAA,6BAA6B,OAAA;AAC7B,mIAAA,0BAA0B,OAAA;AAE5B,wFAKuD;AAJrD,8HAAA,oBAAoB,OAAA;AACpB,sIAAA,4BAA4B,OAAA;AAC5B,wIAAA,8BAA8B,OAAA;AAGhC,8DAK0C;AAJxC,iHAAA,oBAAoB,OAAA;AACpB,2GAAA,cAAc,OAAA;AAIhB,gGAW2D;AAVzD,+HAAA,iBAAiB,OAAA;AACjB,oIAAA,sBAAsB,OAAA;AACtB,4IAAA,8BAA8B,OAAA;AAC9B,+HAAA,iBAAiB,OAAA;AAQnB,0EAUgD;AAT9C,+HAAA,4BAA4B,OAAA;AAC5B,0HAAA,uBAAuB,OAAA;AACvB,4HAAA,yBAAyB,OAAA;AACzB,qIAAA,kCAAkC,OAAA;AAClC,gIAAA,6BAA6B,OAAA;AAM/B,kEAO4C;AAN1C,4HAAA,6BAA6B,OAAA;AAC7B,2GAAA,YAAY,OAAA;AACZ,qHAAA,sBAAsB,OAAA;AACtB,4HAAA,6BAA6B,OAAA;AAI/B,sGAI8D;AAH5D,gJAAA,+BAA+B,OAAA;AAIjC,4DASmC;AARjC,uHAAA,qBAAqB,OAAA;AACrB,4HAAA,0BAA0B,OAAA;AAC1B,oHAAA,kBAAkB,OAAA;AAClB,+HAAA,6BAA6B,OAAA;AAC7B,iIAAA,+BAA+B,OAAA;AAC/B,uHAAA,qBAAqB,OAAA;AACrB,mIAAA,iCAAiC,OAAA;AAGnC,oEAQuC;AAPrC,sHAAA,gBAAgB,OAAA;AAChB,0HAAA,oBAAoB,OAAA;AACpB,wHAAA,kBAAkB,OAAA;AAClB,iIAAA,2BAA2B,OAAA;AAC3B,4HAAA,sBAAsB,OAAA"}
|
package/dist/lib/bootstrap.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { type ControlPlaneDiscoveryOptions } from './control-plane-discovery';
|
|
2
|
+
import { type PrismaMigrationHistoryPolicy } from './migration-history';
|
|
2
3
|
import type { BiomeDatabaseMigrationMode } from './migration-mode';
|
|
3
4
|
import type { KernelState } from '@xemahq/kernel-contracts/kernel-state';
|
|
4
5
|
export interface BiomeDatabaseDeclaration {
|
|
5
6
|
readonly key?: string;
|
|
6
7
|
readonly workspaceDir: string;
|
|
8
|
+
readonly historyPolicy?: PrismaMigrationHistoryPolicy;
|
|
7
9
|
}
|
|
8
10
|
interface BootstrapBiomeDatabasesCommonOptions {
|
|
9
11
|
readonly biomeId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/lib/bootstrap.ts"],"names":[],"mappings":"AAgBA,OAAO,EAEL,KAAK,4BAA4B,EAClC,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/lib/bootstrap.ts"],"names":[],"mappings":"AAgBA,OAAO,EAEL,KAAK,4BAA4B,EAClC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAGL,KAAK,4BAA4B,EAClC,MAAM,qBAAqB,CAAC;AAI7B,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uCAAuC,CAAC;AAGzE,MAAM,WAAW,wBAAwB;IAEvC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAO9B,QAAQ,CAAC,aAAa,CAAC,EAAE,4BAA4B,CAAC;CACvD;AAGD,UAAU,oCAAoC;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAMzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAOzD,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAElC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,4BAA4B,CAAC;CAC/D;AAED,MAAM,WAAW,kCACf,SAAQ,oCAAoC;IAC5C,QAAQ,CAAC,aAAa,EAAE,0BAA0B,CAAC,kBAAkB,CAAC;IACtE,QAAQ,CAAC,SAAS,EAAE,SAAS,wBAAwB,EAAE,CAAC;IAWxD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACjD;AAGD,MAAM,MAAM,8BAA8B,GACxC,kCAAkC,CAAC;AA0XrC,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,8BAA8B,GACnC,OAAO,CAAC,IAAI,CAAC,CA4Cf"}
|
package/dist/lib/bootstrap.js
CHANGED
|
@@ -13,6 +13,7 @@ const pg_1 = require("pg");
|
|
|
13
13
|
const config_1 = require("./config");
|
|
14
14
|
const control_plane_client_1 = require("./control-plane-client");
|
|
15
15
|
const control_plane_discovery_1 = require("./control-plane-discovery");
|
|
16
|
+
const migration_history_1 = require("./migration-history");
|
|
16
17
|
const schema_name_1 = require("./schema-name");
|
|
17
18
|
const LOG_PREFIX = '[biome-database]';
|
|
18
19
|
const bootstrapLogger = new common_1.Logger('BiomeDatabaseBootstrap');
|
|
@@ -72,6 +73,16 @@ function buildPgSsl(config) {
|
|
|
72
73
|
rejectUnauthorized: verify,
|
|
73
74
|
};
|
|
74
75
|
}
|
|
76
|
+
function createDirectPgClient(config) {
|
|
77
|
+
return new pg_1.Client({
|
|
78
|
+
host: config.host,
|
|
79
|
+
port: config.port,
|
|
80
|
+
database: config.database,
|
|
81
|
+
user: config.username,
|
|
82
|
+
password: config.password,
|
|
83
|
+
ssl: buildPgSsl(config),
|
|
84
|
+
});
|
|
85
|
+
}
|
|
75
86
|
function isValidExtensionName(name) {
|
|
76
87
|
return /^[a-z0-9_]+$/i.test(name);
|
|
77
88
|
}
|
|
@@ -81,14 +92,7 @@ async function ensureSchemaExists(biomeId, key, config, requiredExtensions) {
|
|
|
81
92
|
if (!hasSchema && requiredExtensions.length === 0) {
|
|
82
93
|
return;
|
|
83
94
|
}
|
|
84
|
-
const client =
|
|
85
|
-
host: config.host,
|
|
86
|
-
port: config.port,
|
|
87
|
-
database: config.database,
|
|
88
|
-
user: config.username,
|
|
89
|
-
password: config.password,
|
|
90
|
-
ssl: buildPgSsl(config),
|
|
91
|
-
});
|
|
95
|
+
const client = createDirectPgClient(config);
|
|
92
96
|
await client.connect();
|
|
93
97
|
try {
|
|
94
98
|
for (const ext of requiredExtensions) {
|
|
@@ -142,6 +146,46 @@ async function runMigrations(biomeId, key, workspaceDir, migrateUrl) {
|
|
|
142
146
|
throw new Error(`${LOG_PREFIX} biome=${biomeId} key=${key}: migrations failed (exit ${result.exitCode}):\n${result.output}`);
|
|
143
147
|
}
|
|
144
148
|
}
|
|
149
|
+
function quotePostgresIdentifier(identifier) {
|
|
150
|
+
return `"${identifier.replaceAll('"', '""')}"`;
|
|
151
|
+
}
|
|
152
|
+
async function readAppliedMigrationNames(biomeId, key, config) {
|
|
153
|
+
const schema = config.schema ?? 'public';
|
|
154
|
+
const client = createDirectPgClient(config);
|
|
155
|
+
await client.connect();
|
|
156
|
+
try {
|
|
157
|
+
const result = await client.query(`SELECT migration_name
|
|
158
|
+
FROM ${quotePostgresIdentifier(schema)}."_prisma_migrations"
|
|
159
|
+
WHERE finished_at IS NOT NULL
|
|
160
|
+
AND rolled_back_at IS NULL
|
|
161
|
+
ORDER BY migration_name ASC`);
|
|
162
|
+
return result.rows.map((row) => row.migration_name);
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
throw new Error(`${LOG_PREFIX} biome=${biomeId} key=${key}: cannot prove applied ` +
|
|
166
|
+
`migration history in schema "${schema}": ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
167
|
+
}
|
|
168
|
+
finally {
|
|
169
|
+
await client.end();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async function assertDatabaseMatchesImage(biomeId, key, declaration, config) {
|
|
173
|
+
const [localMigrationNames, appliedMigrationNames] = await Promise.all([
|
|
174
|
+
(0, migration_history_1.readLocalPrismaMigrationNames)(declaration.workspaceDir),
|
|
175
|
+
readAppliedMigrationNames(biomeId, key, config),
|
|
176
|
+
]);
|
|
177
|
+
(0, migration_history_1.assertMigrationHistoryCompatible)({
|
|
178
|
+
biomeId,
|
|
179
|
+
key,
|
|
180
|
+
localMigrationNames,
|
|
181
|
+
appliedMigrationNames,
|
|
182
|
+
...(declaration.historyPolicy === undefined
|
|
183
|
+
? {}
|
|
184
|
+
: { historyPolicy: declaration.historyPolicy }),
|
|
185
|
+
});
|
|
186
|
+
bootstrapLogger.log(`${LOG_PREFIX} biome=${biomeId} key=${key}: migration history ` +
|
|
187
|
+
`compatible (${appliedMigrationNames.length} applied)`);
|
|
188
|
+
}
|
|
145
189
|
function buildRuntimeUrl(biomeId, key, config, directUrl) {
|
|
146
190
|
if (config.poolerHost === undefined || config.poolerHost === '') {
|
|
147
191
|
return (0, platform_common_1.ensureBiomeDbSearchPath)(directUrl);
|
|
@@ -184,6 +228,7 @@ async function bootstrapBiomeDatabases(opts) {
|
|
|
184
228
|
const directUrl = buildDirectConnectionUrl(opts.biomeId, key, config);
|
|
185
229
|
await ensureSchemaExists(opts.biomeId, key, config, opts.requiredExtensions ?? []);
|
|
186
230
|
await runMigrations(opts.biomeId, key, decl.workspaceDir, directUrl);
|
|
231
|
+
await assertDatabaseMatchesImage(opts.biomeId, key, decl, config);
|
|
187
232
|
const runtimeUrl = buildRuntimeUrl(opts.biomeId, key, config, directUrl);
|
|
188
233
|
exportResolvedEnv(key, config, runtimeUrl);
|
|
189
234
|
bootstrapLogger.log(`${LOG_PREFIX} biome=${opts.biomeId} key=${key}: bootstrap complete`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/lib/bootstrap.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/lib/bootstrap.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface PrismaMigrationHistoryPolicy {
|
|
2
|
+
readonly supersededMigrationNames: readonly string[];
|
|
3
|
+
}
|
|
4
|
+
export interface MigrationHistoryCompatibilityInput {
|
|
5
|
+
readonly biomeId: string;
|
|
6
|
+
readonly key: string;
|
|
7
|
+
readonly localMigrationNames: readonly string[];
|
|
8
|
+
readonly appliedMigrationNames: readonly string[];
|
|
9
|
+
readonly historyPolicy?: PrismaMigrationHistoryPolicy;
|
|
10
|
+
}
|
|
11
|
+
export declare function readLocalPrismaMigrationNames(workspaceDir: string): Promise<readonly string[]>;
|
|
12
|
+
export declare function assertMigrationHistoryCompatible(input: MigrationHistoryCompatibilityInput): void;
|
|
13
|
+
//# sourceMappingURL=migration-history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-history.d.ts","sourceRoot":"","sources":["../../src/lib/migration-history.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,wBAAwB,EAAE,SAAS,MAAM,EAAE,CAAC;CACtD;AAED,MAAM,WAAW,kCAAkC;IACjD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;IAChD,QAAQ,CAAC,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC;IAClD,QAAQ,CAAC,aAAa,CAAC,EAAE,4BAA4B,CAAC;CACvD;AAgCD,wBAAsB,6BAA6B,CACjD,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAgC5B;AAaD,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,kCAAkC,GACxC,IAAI,CAmDN"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readLocalPrismaMigrationNames = readLocalPrismaMigrationNames;
|
|
4
|
+
exports.assertMigrationHistoryCompatible = assertMigrationHistoryCompatible;
|
|
5
|
+
const promises_1 = require("node:fs/promises");
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const MIGRATION_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]*$/u;
|
|
8
|
+
function assertMigrationName(name, source) {
|
|
9
|
+
if (!MIGRATION_NAME_PATTERN.test(name)) {
|
|
10
|
+
throw new Error(`[biome-database] ${source} contains invalid migration name ` +
|
|
11
|
+
`"${name}". Migration names must match ${MIGRATION_NAME_PATTERN}.`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function assertNoDuplicates(names, source) {
|
|
15
|
+
const seen = new Set();
|
|
16
|
+
for (const name of names) {
|
|
17
|
+
assertMigrationName(name, source);
|
|
18
|
+
if (seen.has(name)) {
|
|
19
|
+
throw new Error(`[biome-database] ${source} contains duplicate migration "${name}".`);
|
|
20
|
+
}
|
|
21
|
+
seen.add(name);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async function readLocalPrismaMigrationNames(workspaceDir) {
|
|
25
|
+
const migrationsDir = (0, node_path_1.join)(workspaceDir, 'prisma', 'migrations');
|
|
26
|
+
let entries;
|
|
27
|
+
try {
|
|
28
|
+
entries = await (0, promises_1.readdir)(migrationsDir, { withFileTypes: true });
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
throw new Error(`[biome-database] cannot read Prisma migrations at ${migrationsDir}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
32
|
+
}
|
|
33
|
+
const migrationNames = [];
|
|
34
|
+
for (const entry of entries) {
|
|
35
|
+
if (!entry.isDirectory()) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
assertMigrationName(entry.name, `local history at ${migrationsDir}`);
|
|
39
|
+
const migrationEntries = await (0, promises_1.readdir)((0, node_path_1.join)(migrationsDir, entry.name));
|
|
40
|
+
if (!migrationEntries.includes('migration.sql')) {
|
|
41
|
+
throw new Error(`[biome-database] local migration directory "${entry.name}" at ` +
|
|
42
|
+
`${migrationsDir} has no migration.sql; refusing an incomplete ` +
|
|
43
|
+
'migration image.');
|
|
44
|
+
}
|
|
45
|
+
migrationNames.push(entry.name);
|
|
46
|
+
}
|
|
47
|
+
return migrationNames.sort();
|
|
48
|
+
}
|
|
49
|
+
function assertMigrationHistoryCompatible(input) {
|
|
50
|
+
const local = [...input.localMigrationNames].sort();
|
|
51
|
+
const applied = [...input.appliedMigrationNames].sort();
|
|
52
|
+
const superseded = [
|
|
53
|
+
...(input.historyPolicy?.supersededMigrationNames ?? []),
|
|
54
|
+
].sort();
|
|
55
|
+
assertNoDuplicates(local, 'local Prisma migration history');
|
|
56
|
+
assertNoDuplicates(applied, 'applied Prisma migration history');
|
|
57
|
+
assertNoDuplicates(superseded, 'superseded migration policy');
|
|
58
|
+
const localSet = new Set(local);
|
|
59
|
+
const appliedSet = new Set(applied);
|
|
60
|
+
const supersededSet = new Set(superseded);
|
|
61
|
+
const stalePolicy = superseded.filter((name) => localSet.has(name));
|
|
62
|
+
if (stalePolicy.length > 0) {
|
|
63
|
+
throw new Error(`[biome-database] biome=${input.biomeId} key=${input.key}: ` +
|
|
64
|
+
'MIGRATION_HISTORY_POLICY_STALE: superseded migrations are still ' +
|
|
65
|
+
`shipped locally: ${stalePolicy.join(', ')}. Remove the stale policy ` +
|
|
66
|
+
'entries; a migration cannot be both active and superseded.');
|
|
67
|
+
}
|
|
68
|
+
const absentFromDatabase = local.filter((name) => !appliedSet.has(name));
|
|
69
|
+
const absentFromImage = applied.filter((name) => !localSet.has(name) && !supersededSet.has(name));
|
|
70
|
+
if (absentFromDatabase.length === 0 && absentFromImage.length === 0) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const details = [
|
|
74
|
+
absentFromImage.length > 0
|
|
75
|
+
? `applied-but-absent-from-image=[${absentFromImage.join(', ')}]`
|
|
76
|
+
: undefined,
|
|
77
|
+
absentFromDatabase.length > 0
|
|
78
|
+
? `shipped-but-not-applied=[${absentFromDatabase.join(', ')}]`
|
|
79
|
+
: undefined,
|
|
80
|
+
].filter((detail) => detail !== undefined);
|
|
81
|
+
throw new Error(`[biome-database] biome=${input.biomeId} key=${input.key}: ` +
|
|
82
|
+
`MIGRATION_HISTORY_INCOMPATIBLE: ${details.join('; ')}. Refusing to ` +
|
|
83
|
+
'start because this image and database do not describe the same schema. ' +
|
|
84
|
+
'Roll forward to a compatible image. For a deliberate migration-history ' +
|
|
85
|
+
'squash, complete the Prisma baseline procedure and declare every removed ' +
|
|
86
|
+
'directory in historyPolicy.supersededMigrationNames.');
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=migration-history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migration-history.js","sourceRoot":"","sources":["../../src/lib/migration-history.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { QueryResult, QueryResultRow } from 'pg';
|
|
2
|
+
export declare enum OperatorMigrationMode {
|
|
3
|
+
DryRun = "dry-run",
|
|
4
|
+
Apply = "apply",
|
|
5
|
+
Verify = "verify",
|
|
6
|
+
Contract = "contract"
|
|
7
|
+
}
|
|
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
|
+
export interface VerifyOperatorMigrationOptions {
|
|
16
|
+
readonly database: OperatorMigrationDatabase;
|
|
17
|
+
readonly migrationId: string;
|
|
18
|
+
readonly verificationArtifact: string;
|
|
19
|
+
readonly verify: (database: OperatorMigrationDatabase) => Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
export interface ContractOperatorMigrationOptions {
|
|
22
|
+
readonly database: OperatorMigrationDatabase;
|
|
23
|
+
readonly migrationId: string;
|
|
24
|
+
readonly contractionSql: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function parseOperatorMigrationMode(argv: readonly string[]): OperatorMigrationMode;
|
|
27
|
+
export declare function verifyOperatorMigration(options: VerifyOperatorMigrationOptions): Promise<{
|
|
28
|
+
readonly artifactSha256: string;
|
|
29
|
+
}>;
|
|
30
|
+
export declare function contractOperatorMigration(options: ContractOperatorMigrationOptions): Promise<{
|
|
31
|
+
readonly artifactSha256: string;
|
|
32
|
+
}>;
|
|
33
|
+
//# sourceMappingURL=operator-migration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operator-migration.d.ts","sourceRoot":"","sources":["../../src/lib/operator-migration.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AAEtD,oBAAY,qBAAqB;IAC/B,MAAM,YAAY;IAClB,KAAK,UAAU;IACf,MAAM,WAAW;IACjB,QAAQ,aAAa;CACtB;AAED,oBAAY,sBAAsB;IAChC,QAAQ,aAAa;IACrB,UAAU,eAAe;CAC1B;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,CAAC,CAAC,SAAS,cAAc,GAAG,cAAc,EAC7C,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,OAAO,EAAE,GACjB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;CAC5B;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;AAKD,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,SAAS,MAAM,EAAE,GACtB,qBAAqB,CAYvB;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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OperatorMigrationPhase = exports.OperatorMigrationMode = void 0;
|
|
4
|
+
exports.parseOperatorMigrationMode = parseOperatorMigrationMode;
|
|
5
|
+
exports.verifyOperatorMigration = verifyOperatorMigration;
|
|
6
|
+
exports.contractOperatorMigration = contractOperatorMigration;
|
|
7
|
+
const node_crypto_1 = require("node:crypto");
|
|
8
|
+
var OperatorMigrationMode;
|
|
9
|
+
(function (OperatorMigrationMode) {
|
|
10
|
+
OperatorMigrationMode["DryRun"] = "dry-run";
|
|
11
|
+
OperatorMigrationMode["Apply"] = "apply";
|
|
12
|
+
OperatorMigrationMode["Verify"] = "verify";
|
|
13
|
+
OperatorMigrationMode["Contract"] = "contract";
|
|
14
|
+
})(OperatorMigrationMode || (exports.OperatorMigrationMode = OperatorMigrationMode = {}));
|
|
15
|
+
var OperatorMigrationPhase;
|
|
16
|
+
(function (OperatorMigrationPhase) {
|
|
17
|
+
OperatorMigrationPhase["Verified"] = "verified";
|
|
18
|
+
OperatorMigrationPhase["Contracted"] = "contracted";
|
|
19
|
+
})(OperatorMigrationPhase || (exports.OperatorMigrationPhase = OperatorMigrationPhase = {}));
|
|
20
|
+
const MIGRATION_ID_PATTERN = /^[a-z][a-z0-9-]{0,126}$/u;
|
|
21
|
+
const SHA256_PATTERN = /^[a-f0-9]{64}$/u;
|
|
22
|
+
function parseOperatorMigrationMode(argv) {
|
|
23
|
+
const modeArguments = argv.filter((value) => value.startsWith('--mode='));
|
|
24
|
+
if (modeArguments.length !== 1) {
|
|
25
|
+
throw new Error(`Exactly one operator migration mode is required: --mode=${Object.values(OperatorMigrationMode).join('|')}.`);
|
|
26
|
+
}
|
|
27
|
+
const value = modeArguments[0]?.slice('--mode='.length) ?? '';
|
|
28
|
+
if (!Object.values(OperatorMigrationMode).includes(value)) {
|
|
29
|
+
throw new Error(`Unsupported operator migration mode: ${value}.`);
|
|
30
|
+
}
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
async function verifyOperatorMigration(options) {
|
|
34
|
+
const artifactSha256 = sha256(options.verificationArtifact);
|
|
35
|
+
await inMigrationTransaction(options.database, options.migrationId, async (database) => {
|
|
36
|
+
await options.verify(database);
|
|
37
|
+
await recordPhase(database, options.migrationId, OperatorMigrationPhase.Verified, artifactSha256);
|
|
38
|
+
});
|
|
39
|
+
return { artifactSha256 };
|
|
40
|
+
}
|
|
41
|
+
async function contractOperatorMigration(options) {
|
|
42
|
+
const artifactSha256 = sha256(options.contractionSql);
|
|
43
|
+
await inMigrationTransaction(options.database, options.migrationId, async (database) => {
|
|
44
|
+
await requirePhase(database, options.migrationId, OperatorMigrationPhase.Verified);
|
|
45
|
+
const existing = await readPhase(database, options.migrationId, OperatorMigrationPhase.Contracted);
|
|
46
|
+
if (existing !== null) {
|
|
47
|
+
assertArtifactMatches(options.migrationId, OperatorMigrationPhase.Contracted, existing, artifactSha256);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
await database.query(options.contractionSql);
|
|
51
|
+
await recordPhase(database, options.migrationId, OperatorMigrationPhase.Contracted, artifactSha256);
|
|
52
|
+
});
|
|
53
|
+
return { artifactSha256 };
|
|
54
|
+
}
|
|
55
|
+
async function inMigrationTransaction(database, migrationId, work) {
|
|
56
|
+
assertMigrationId(migrationId);
|
|
57
|
+
await database.query('BEGIN');
|
|
58
|
+
try {
|
|
59
|
+
await database.query('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE');
|
|
60
|
+
await database.query(`SELECT pg_advisory_xact_lock(hashtextextended($1, 0))`, [`xema:operator-migration:${migrationId}`]);
|
|
61
|
+
await work(database);
|
|
62
|
+
await database.query('COMMIT');
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
try {
|
|
66
|
+
await database.query('ROLLBACK');
|
|
67
|
+
}
|
|
68
|
+
catch (rollbackError) {
|
|
69
|
+
throw new AggregateError([error, rollbackError], `Operator migration ${migrationId} failed and its transaction could not be rolled back.`);
|
|
70
|
+
}
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async function recordPhase(database, migrationId, phase, artifactSha256) {
|
|
75
|
+
const existing = await readPhase(database, migrationId, phase);
|
|
76
|
+
if (existing !== null) {
|
|
77
|
+
assertArtifactMatches(migrationId, phase, existing, artifactSha256);
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
await database.query(`INSERT INTO xema_operator_migrations
|
|
81
|
+
(migration_id, phase, artifact_sha256)
|
|
82
|
+
VALUES ($1, $2, $3)`, [migrationId, phase, artifactSha256]);
|
|
83
|
+
}
|
|
84
|
+
async function requirePhase(database, migrationId, phase) {
|
|
85
|
+
if ((await readPhase(database, migrationId, phase)) === null) {
|
|
86
|
+
throw new Error(`Operator migration ${migrationId} has not completed phase ${phase}.`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function readPhase(database, migrationId, phase) {
|
|
90
|
+
const result = await database.query(`SELECT artifact_sha256
|
|
91
|
+
FROM xema_operator_migrations
|
|
92
|
+
WHERE migration_id = $1 AND phase = $2`, [migrationId, phase]);
|
|
93
|
+
const value = result.rows[0]?.artifact_sha256 ?? null;
|
|
94
|
+
if (value !== null && !SHA256_PATTERN.test(value)) {
|
|
95
|
+
throw new Error(`Operator migration ledger contains an invalid artifact hash for ${migrationId}/${phase}.`);
|
|
96
|
+
}
|
|
97
|
+
return value;
|
|
98
|
+
}
|
|
99
|
+
function assertArtifactMatches(migrationId, phase, recorded, expected) {
|
|
100
|
+
if (recorded !== expected) {
|
|
101
|
+
throw new Error(`Operator migration ${migrationId}/${phase} is already recorded for a different artifact.`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function assertMigrationId(migrationId) {
|
|
105
|
+
if (!MIGRATION_ID_PATTERN.test(migrationId)) {
|
|
106
|
+
throw new Error(`Invalid operator migration id: ${migrationId}.`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function sha256(value) {
|
|
110
|
+
return (0, node_crypto_1.createHash)('sha256').update(value).digest('hex');
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=operator-migration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operator-migration.js","sourceRoot":"","sources":["../../src/lib/operator-migration.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xemahq/biome-database-nest",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.13",
|
|
4
4
|
"description": "Explicit database migration ownership, least-privilege runtime verification, and schema-qualified Prisma wiring for Xema biome services.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Neuralchowder Inc. <developer@xema.dev> (https://xema.dev)",
|