@xemahq/biome-database-nest 0.9.0 → 0.10.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/dist/index.d.ts +3 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -15
- package/dist/index.js.map +1 -1
- package/dist/lib/bootstrap.d.ts +3 -16
- package/dist/lib/bootstrap.d.ts.map +1 -1
- package/dist/lib/bootstrap.js +12 -71
- package/dist/lib/bootstrap.js.map +1 -1
- package/dist/lib/config.d.ts +0 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +7 -10
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/control-plane-client.d.ts +0 -1
- package/dist/lib/control-plane-client.d.ts.map +1 -1
- package/dist/lib/control-plane-client.js +3 -13
- package/dist/lib/control-plane-client.js.map +1 -1
- package/dist/lib/migration-mode.d.ts +1 -117
- package/dist/lib/migration-mode.d.ts.map +1 -1
- package/dist/lib/migration-mode.js +1 -48
- package/dist/lib/migration-mode.js.map +1 -1
- package/dist/lib/nest/biome-database.module.d.ts +3 -8
- package/dist/lib/nest/biome-database.module.d.ts.map +1 -1
- package/dist/lib/nest/biome-database.module.js +1 -2
- package/dist/lib/nest/biome-database.module.js.map +1 -1
- package/package.json +4 -3
- package/src/index.ts +112 -0
- package/src/lib/adapter.ts +114 -0
- package/src/lib/bootstrap.ts +433 -0
- package/src/lib/config.ts +183 -0
- package/src/lib/control-plane-client.ts +121 -0
- package/src/lib/control-plane-discovery.ts +34 -0
- package/src/lib/identifier.ts +177 -0
- package/src/lib/migration-mode.ts +25 -0
- package/src/lib/nest/biome-database.module.ts +175 -0
- package/src/lib/nest/org-erasure.module.ts +124 -0
- package/src/lib/nest/prisma-service-factory.ts +376 -0
- package/src/lib/role-names.ts +77 -0
- package/src/lib/schema-name.ts +62 -0
- package/src/lib/tenant-isolation/org-erasure.ts +158 -0
- package/src/lib/tenant-isolation/org-scope.ts +305 -0
- package/src/lib/tenant-isolation/tenant-isolation-error.ts +79 -0
- package/src/lib/tenant-isolation/tenant-isolation-mode.ts +55 -0
- package/src/lib/tenant-isolation/tenant-isolation.extension.ts +203 -0
- package/src/lib/tenant-isolation/unscoped-models.ts +269 -0
- package/dist/lib/credential-generation.d.ts +0 -4
- package/dist/lib/credential-generation.d.ts.map +0 -1
- package/dist/lib/credential-generation.js +0 -24
- package/dist/lib/credential-generation.js.map +0 -1
- package/dist/lib/external-runtime-verifier.d.ts +0 -3
- package/dist/lib/external-runtime-verifier.d.ts.map +0 -1
- package/dist/lib/external-runtime-verifier.js +0 -860
- package/dist/lib/external-runtime-verifier.js.map +0 -1
- package/dist/lib/response-envelope.d.ts +0 -2
- package/dist/lib/response-envelope.d.ts.map +0 -1
- package/dist/lib/response-envelope.js +0 -6
- package/dist/lib/response-envelope.js.map +0 -1
|
@@ -1,120 +1,4 @@
|
|
|
1
1
|
export declare enum BiomeDatabaseMigrationMode {
|
|
2
|
-
ApplicationManaged = "application-managed"
|
|
3
|
-
ExternallyManaged = "externally-managed"
|
|
4
|
-
}
|
|
5
|
-
export declare enum RuntimeDatabaseCredentialSource {
|
|
6
|
-
ControlPlane = "control-plane",
|
|
7
|
-
Environment = "environment"
|
|
8
|
-
}
|
|
9
|
-
export declare enum RuntimeTablePrivilege {
|
|
10
|
-
Select = "SELECT",
|
|
11
|
-
Insert = "INSERT",
|
|
12
|
-
Update = "UPDATE",
|
|
13
|
-
Delete = "DELETE"
|
|
14
|
-
}
|
|
15
|
-
export declare enum RuntimeSequencePrivilege {
|
|
16
|
-
Usage = "USAGE",
|
|
17
|
-
Select = "SELECT",
|
|
18
|
-
Update = "UPDATE"
|
|
19
|
-
}
|
|
20
|
-
export declare enum RuntimeWritableRelationKind {
|
|
21
|
-
View = "view",
|
|
22
|
-
ForeignTable = "foreign-table"
|
|
23
|
-
}
|
|
24
|
-
export interface RuntimeWritableRelationExpectation {
|
|
25
|
-
readonly kind: RuntimeWritableRelationKind;
|
|
26
|
-
readonly name: string;
|
|
27
|
-
readonly privileges: readonly RuntimeTablePrivilege[];
|
|
28
|
-
}
|
|
29
|
-
export declare enum RuntimeExtensionObjectKind {
|
|
30
|
-
Type = "type",
|
|
31
|
-
Function = "function",
|
|
32
|
-
Table = "table",
|
|
33
|
-
Sequence = "sequence"
|
|
34
|
-
}
|
|
35
|
-
export declare enum RuntimeExtensionTypePrivilege {
|
|
36
|
-
Usage = "USAGE"
|
|
37
|
-
}
|
|
38
|
-
export declare enum RuntimeExtensionFunctionPrivilege {
|
|
39
|
-
Execute = "EXECUTE"
|
|
40
|
-
}
|
|
41
|
-
export declare enum RuntimeExtensionTablePrivilege {
|
|
42
|
-
Select = "SELECT"
|
|
43
|
-
}
|
|
44
|
-
export declare enum RuntimeExtensionSequencePrivilege {
|
|
45
|
-
Select = "SELECT"
|
|
46
|
-
}
|
|
47
|
-
export type RuntimeExtensionObjectExpectation = {
|
|
48
|
-
readonly kind: RuntimeExtensionObjectKind.Type;
|
|
49
|
-
readonly name: string;
|
|
50
|
-
readonly privileges: readonly [RuntimeExtensionTypePrivilege.Usage];
|
|
51
|
-
} | {
|
|
52
|
-
readonly kind: RuntimeExtensionObjectKind.Function;
|
|
53
|
-
readonly name: string;
|
|
54
|
-
readonly identityArguments: string;
|
|
55
|
-
readonly privileges: readonly [RuntimeExtensionFunctionPrivilege.Execute];
|
|
56
|
-
} | {
|
|
57
|
-
readonly kind: RuntimeExtensionObjectKind.Table;
|
|
58
|
-
readonly name: string;
|
|
59
|
-
readonly privileges: readonly [RuntimeExtensionTablePrivilege.Select];
|
|
60
|
-
} | {
|
|
61
|
-
readonly kind: RuntimeExtensionObjectKind.Sequence;
|
|
62
|
-
readonly name: string;
|
|
63
|
-
readonly privileges: readonly [RuntimeExtensionSequencePrivilege.Select];
|
|
64
|
-
};
|
|
65
|
-
export interface RuntimeDatabaseExtensionDependency {
|
|
66
|
-
readonly name: string;
|
|
67
|
-
readonly schema: string;
|
|
68
|
-
readonly version: string;
|
|
69
|
-
readonly objects: readonly RuntimeExtensionObjectExpectation[];
|
|
70
|
-
}
|
|
71
|
-
export interface RuntimeDatabaseFunctionExpectation {
|
|
72
|
-
readonly name: string;
|
|
73
|
-
readonly identityArguments: string;
|
|
74
|
-
readonly privileges: readonly [RuntimeExtensionFunctionPrivilege.Execute];
|
|
75
|
-
}
|
|
76
|
-
export interface RuntimeDatabaseAccessExpectation {
|
|
77
|
-
readonly tablePrivileges: readonly RuntimeTablePrivilege[];
|
|
78
|
-
readonly sequencePrivileges: readonly RuntimeSequencePrivilege[];
|
|
79
|
-
readonly writableRelations: readonly RuntimeWritableRelationExpectation[];
|
|
80
|
-
readonly authorizedRoleMemberships: readonly [];
|
|
81
|
-
readonly targetFunctions: readonly RuntimeDatabaseFunctionExpectation[];
|
|
82
|
-
readonly extensionDependencies: readonly RuntimeDatabaseExtensionDependency[];
|
|
83
|
-
}
|
|
84
|
-
export interface RuntimeDatabaseTarget {
|
|
85
|
-
readonly database: string;
|
|
86
|
-
readonly schema: string;
|
|
87
|
-
readonly applicationName: string;
|
|
88
|
-
readonly expectedRole: string;
|
|
89
|
-
readonly credentialGeneration: number;
|
|
90
|
-
}
|
|
91
|
-
export interface AppliedPrismaMigration {
|
|
92
|
-
readonly id: string;
|
|
93
|
-
readonly name: string;
|
|
94
|
-
readonly checksum: string;
|
|
95
|
-
readonly startedAt: string;
|
|
96
|
-
readonly finishedAt: string;
|
|
97
|
-
readonly appliedStepsCount: number;
|
|
98
|
-
}
|
|
99
|
-
export interface MigrationCompatibilityContext {
|
|
100
|
-
readonly target: RuntimeDatabaseTarget;
|
|
101
|
-
readonly currentRole: string;
|
|
102
|
-
readonly appliedMigrations: readonly AppliedPrismaMigration[];
|
|
103
|
-
readonly observedLedgerDigest: string;
|
|
104
|
-
}
|
|
105
|
-
export type MigrationCompatibilityProof = {
|
|
106
|
-
readonly compatible: true;
|
|
107
|
-
readonly verifierId: string;
|
|
108
|
-
readonly expectedState: string;
|
|
109
|
-
readonly observedLedgerDigest: string;
|
|
110
|
-
} | {
|
|
111
|
-
readonly compatible: false;
|
|
112
|
-
readonly verifierId: string;
|
|
113
|
-
readonly reason: string;
|
|
114
|
-
readonly observedLedgerDigest: string;
|
|
115
|
-
};
|
|
116
|
-
export interface MigrationCompatibilityExpectation {
|
|
117
|
-
readonly verifierId: string;
|
|
118
|
-
readonly verify: (context: MigrationCompatibilityContext) => MigrationCompatibilityProof | Promise<MigrationCompatibilityProof>;
|
|
2
|
+
ApplicationManaged = "application-managed"
|
|
119
3
|
}
|
|
120
4
|
//# sourceMappingURL=migration-mode.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-mode.d.ts","sourceRoot":"","sources":["../../src/lib/migration-mode.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"migration-mode.d.ts","sourceRoot":"","sources":["../../src/lib/migration-mode.ts"],"names":[],"mappings":"AAsBA,oBAAY,0BAA0B;IACpC,kBAAkB,wBAAwB;CAC3C"}
|
|
@@ -1,55 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.BiomeDatabaseMigrationMode = void 0;
|
|
4
4
|
var BiomeDatabaseMigrationMode;
|
|
5
5
|
(function (BiomeDatabaseMigrationMode) {
|
|
6
6
|
BiomeDatabaseMigrationMode["ApplicationManaged"] = "application-managed";
|
|
7
|
-
BiomeDatabaseMigrationMode["ExternallyManaged"] = "externally-managed";
|
|
8
7
|
})(BiomeDatabaseMigrationMode || (exports.BiomeDatabaseMigrationMode = BiomeDatabaseMigrationMode = {}));
|
|
9
|
-
var RuntimeDatabaseCredentialSource;
|
|
10
|
-
(function (RuntimeDatabaseCredentialSource) {
|
|
11
|
-
RuntimeDatabaseCredentialSource["ControlPlane"] = "control-plane";
|
|
12
|
-
RuntimeDatabaseCredentialSource["Environment"] = "environment";
|
|
13
|
-
})(RuntimeDatabaseCredentialSource || (exports.RuntimeDatabaseCredentialSource = RuntimeDatabaseCredentialSource = {}));
|
|
14
|
-
var RuntimeTablePrivilege;
|
|
15
|
-
(function (RuntimeTablePrivilege) {
|
|
16
|
-
RuntimeTablePrivilege["Select"] = "SELECT";
|
|
17
|
-
RuntimeTablePrivilege["Insert"] = "INSERT";
|
|
18
|
-
RuntimeTablePrivilege["Update"] = "UPDATE";
|
|
19
|
-
RuntimeTablePrivilege["Delete"] = "DELETE";
|
|
20
|
-
})(RuntimeTablePrivilege || (exports.RuntimeTablePrivilege = RuntimeTablePrivilege = {}));
|
|
21
|
-
var RuntimeSequencePrivilege;
|
|
22
|
-
(function (RuntimeSequencePrivilege) {
|
|
23
|
-
RuntimeSequencePrivilege["Usage"] = "USAGE";
|
|
24
|
-
RuntimeSequencePrivilege["Select"] = "SELECT";
|
|
25
|
-
RuntimeSequencePrivilege["Update"] = "UPDATE";
|
|
26
|
-
})(RuntimeSequencePrivilege || (exports.RuntimeSequencePrivilege = RuntimeSequencePrivilege = {}));
|
|
27
|
-
var RuntimeWritableRelationKind;
|
|
28
|
-
(function (RuntimeWritableRelationKind) {
|
|
29
|
-
RuntimeWritableRelationKind["View"] = "view";
|
|
30
|
-
RuntimeWritableRelationKind["ForeignTable"] = "foreign-table";
|
|
31
|
-
})(RuntimeWritableRelationKind || (exports.RuntimeWritableRelationKind = RuntimeWritableRelationKind = {}));
|
|
32
|
-
var RuntimeExtensionObjectKind;
|
|
33
|
-
(function (RuntimeExtensionObjectKind) {
|
|
34
|
-
RuntimeExtensionObjectKind["Type"] = "type";
|
|
35
|
-
RuntimeExtensionObjectKind["Function"] = "function";
|
|
36
|
-
RuntimeExtensionObjectKind["Table"] = "table";
|
|
37
|
-
RuntimeExtensionObjectKind["Sequence"] = "sequence";
|
|
38
|
-
})(RuntimeExtensionObjectKind || (exports.RuntimeExtensionObjectKind = RuntimeExtensionObjectKind = {}));
|
|
39
|
-
var RuntimeExtensionTypePrivilege;
|
|
40
|
-
(function (RuntimeExtensionTypePrivilege) {
|
|
41
|
-
RuntimeExtensionTypePrivilege["Usage"] = "USAGE";
|
|
42
|
-
})(RuntimeExtensionTypePrivilege || (exports.RuntimeExtensionTypePrivilege = RuntimeExtensionTypePrivilege = {}));
|
|
43
|
-
var RuntimeExtensionFunctionPrivilege;
|
|
44
|
-
(function (RuntimeExtensionFunctionPrivilege) {
|
|
45
|
-
RuntimeExtensionFunctionPrivilege["Execute"] = "EXECUTE";
|
|
46
|
-
})(RuntimeExtensionFunctionPrivilege || (exports.RuntimeExtensionFunctionPrivilege = RuntimeExtensionFunctionPrivilege = {}));
|
|
47
|
-
var RuntimeExtensionTablePrivilege;
|
|
48
|
-
(function (RuntimeExtensionTablePrivilege) {
|
|
49
|
-
RuntimeExtensionTablePrivilege["Select"] = "SELECT";
|
|
50
|
-
})(RuntimeExtensionTablePrivilege || (exports.RuntimeExtensionTablePrivilege = RuntimeExtensionTablePrivilege = {}));
|
|
51
|
-
var RuntimeExtensionSequencePrivilege;
|
|
52
|
-
(function (RuntimeExtensionSequencePrivilege) {
|
|
53
|
-
RuntimeExtensionSequencePrivilege["Select"] = "SELECT";
|
|
54
|
-
})(RuntimeExtensionSequencePrivilege || (exports.RuntimeExtensionSequencePrivilege = RuntimeExtensionSequencePrivilege = {}));
|
|
55
8
|
//# sourceMappingURL=migration-mode.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-mode.js","sourceRoot":"","sources":["../../src/lib/migration-mode.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"migration-mode.js","sourceRoot":"","sources":["../../src/lib/migration-mode.ts"],"names":[],"mappings":";;;AAsBA,IAAY,0BAEX;AAFD,WAAY,0BAA0B;IACpC,wEAA0C,CAAA;AAC5C,CAAC,EAFW,0BAA0B,0CAA1B,0BAA0B,QAErC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { DynamicModule } from '@nestjs/common';
|
|
2
|
-
import type { BiomeDatabaseDeclaration, ExternallyManagedBiomeDatabaseDeclaration } from '../bootstrap';
|
|
3
1
|
import { BiomeDatabaseMigrationMode } from '../migration-mode';
|
|
2
|
+
import type { BiomeDatabaseDeclaration } from '../bootstrap';
|
|
3
|
+
import type { DynamicModule } from '@nestjs/common';
|
|
4
4
|
export declare const BIOME_DATABASE_READY: unique symbol;
|
|
5
5
|
interface BiomeDatabaseModuleCommonOptions {
|
|
6
6
|
readonly biomeId: string;
|
|
@@ -10,12 +10,7 @@ export interface ApplicationManagedBiomeDatabaseModuleOptions extends BiomeDatab
|
|
|
10
10
|
readonly databases: readonly BiomeDatabaseDeclaration[];
|
|
11
11
|
readonly requiredExtensions?: readonly string[];
|
|
12
12
|
}
|
|
13
|
-
export
|
|
14
|
-
readonly migrationMode: BiomeDatabaseMigrationMode.ExternallyManaged;
|
|
15
|
-
readonly databases: readonly ExternallyManagedBiomeDatabaseDeclaration[];
|
|
16
|
-
readonly requiredExtensions?: never;
|
|
17
|
-
}
|
|
18
|
-
export type BiomeDatabaseModuleOptions = ApplicationManagedBiomeDatabaseModuleOptions | ExternallyManagedBiomeDatabaseModuleOptions;
|
|
13
|
+
export type BiomeDatabaseModuleOptions = ApplicationManagedBiomeDatabaseModuleOptions;
|
|
19
14
|
export declare class BiomeDatabaseModule {
|
|
20
15
|
static forRoot(opts: BiomeDatabaseModuleOptions): DynamicModule;
|
|
21
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"biome-database.module.d.ts","sourceRoot":"","sources":["../../../src/lib/nest/biome-database.module.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"biome-database.module.d.ts","sourceRoot":"","sources":["../../../src/lib/nest/biome-database.module.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAE/D,OAAO,KAAK,EACV,wBAAwB,EACzB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAYpD,eAAO,MAAM,oBAAoB,eAEhC,CAAC;AAEF,UAAU,gCAAgC;IAExC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,4CACf,SAAQ,gCAAgC;IACxC,QAAQ,CAAC,aAAa,EAAE,0BAA0B,CAAC,kBAAkB,CAAC;IAKtE,QAAQ,CAAC,SAAS,EAAE,SAAS,wBAAwB,EAAE,CAAC;IAMxD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACjD;AAID,MAAM,MAAM,0BAA0B,GACpC,4CAA4C,CAAC;AA6C/C,qBACa,mBAAmB;IAC9B,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,0BAA0B,GAAG,aAAa;CA0EhE"}
|
|
@@ -16,8 +16,7 @@ const migration_mode_1 = require("../migration-mode");
|
|
|
16
16
|
exports.BIOME_DATABASE_READY = Symbol.for('@xemahq/biome-database-nest:ready');
|
|
17
17
|
let BiomeDatabaseModule = BiomeDatabaseModule_1 = class BiomeDatabaseModule {
|
|
18
18
|
static forRoot(opts) {
|
|
19
|
-
if (opts.migrationMode !== migration_mode_1.BiomeDatabaseMigrationMode.ApplicationManaged
|
|
20
|
-
opts.migrationMode !== migration_mode_1.BiomeDatabaseMigrationMode.ExternallyManaged) {
|
|
19
|
+
if (opts.migrationMode !== migration_mode_1.BiomeDatabaseMigrationMode.ApplicationManaged) {
|
|
21
20
|
throw new Error('[biome-database] migrationMode is required and must be a BiomeDatabaseMigrationMode.');
|
|
22
21
|
}
|
|
23
22
|
if (opts.databases.length === 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"biome-database.module.js","sourceRoot":"","sources":["../../../src/lib/nest/biome-database.module.ts"],"names":[],"mappings":";;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"biome-database.module.js","sourceRoot":"","sources":["../../../src/lib/nest/biome-database.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAwC;AACxC,6DAAmE;AACnE,yEAGuC;AAEvC,4CAAuD;AACvD,sDAA+D;AAiBlD,QAAA,oBAAoB,GAAG,MAAM,CAAC,GAAG,CAC5C,mCAAmC,CACpC,CAAC;AAwEK,IAAM,mBAAmB,2BAAzB,MAAM,mBAAmB;IAC9B,MAAM,CAAC,OAAO,CAAC,IAAgC;QAC7C,IACE,IAAI,CAAC,aAAa,KAAK,2CAA0B,CAAC,kBAAkB,EACpE,CAAC;YACD,MAAM,IAAI,KAAK,CACb,sFAAsF,CACvF,CAAC;QACJ,CAAC;QACD,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,4FAA4F,CAC7F,CAAC;QACJ,CAAC;QACD,MAAM,SAAS,GAEX,IAAI,CAAC,SAAS,CAAC;QAQnB,IAAI,IAAA,2CAAmB,GAAE,EAAE,CAAC;YAC1B,OAAO;gBACL,MAAM,EAAE,qBAAmB;gBAC3B,MAAM,EAAE,IAAI;gBACZ,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,4BAAoB,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;gBAC9D,OAAO,EAAE,CAAC,4BAAoB,CAAC;aAChC,CAAC;QACJ,CAAC;QAED,OAAO;YACL,MAAM,EAAE,qBAAmB;YAC3B,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,4BAAoB;oBAC7B,UAAU,EAAE,KAAK,EACf,iBAA2C,EAC3C,WAAwB,EACT,EAAE;wBACjB,IACE,IAAI,CAAC,aAAa;4BAClB,2CAA0B,CAAC,kBAAkB,EAC7C,CAAC;4BACD,MAAM,IAAA,mCAAuB,EAAC;gCAC5B,OAAO,EAAE,IAAI,CAAC,OAAO;gCACrB,aAAa,EAAE,IAAI,CAAC,aAAa;gCACjC,SAAS,EAAE,SAAgD;gCAC3D,GAAG,CAAC,IAAI,CAAC,kBAAkB,KAAK,SAAS;oCACvC,CAAC,CAAC,EAAE,kBAAkB,EAAE,IAAI,CAAC,kBAAkB,EAAE;oCACjD,CAAC,CAAC,EAAE,CAAC;gCACP,YAAY,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,cAAc,EAAE;gCACtD,WAAW;6BACZ,CAAC,CAAC;wBACL,CAAC;6BAAM,CAAC;4BACN,MAAM,IAAA,mCAAuB,EAAC;gCAC5B,OAAO,EAAE,IAAI,CAAC,OAAO;gCACrB,aAAa,EAAE,IAAI,CAAC,aAAa;gCACjC,SAAS,EACP,SAAS;gCACX,YAAY,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,cAAc,EAAE;gCACtD,WAAW;6BACZ,CAAC,CAAC;wBACL,CAAC;wBACD,OAAO,IAAI,CAAC;oBACd,CAAC;oBACD,MAAM,EAAE,CAAC,0CAAwB,EAAE,0CAAkB,CAAC;iBACvD;aACF;YACD,OAAO,EAAE,CAAC,4BAAoB,CAAC;SAChC,CAAC;IACJ,CAAC;CACF,CAAA;AA3EY,kDAAmB;8BAAnB,mBAAmB;IAD/B,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,mBAAmB,CA2E/B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xemahq/biome-database-nest",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
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)",
|
|
@@ -18,7 +18,8 @@
|
|
|
18
18
|
"main": "dist/index.js",
|
|
19
19
|
"types": "dist/index.d.ts",
|
|
20
20
|
"files": [
|
|
21
|
-
"dist"
|
|
21
|
+
"dist",
|
|
22
|
+
"src"
|
|
22
23
|
],
|
|
23
24
|
"devDependencies": {
|
|
24
25
|
"@nestjs/common": "11.1.13",
|
|
@@ -49,7 +50,7 @@
|
|
|
49
50
|
},
|
|
50
51
|
"dependencies": {
|
|
51
52
|
"@xemahq/migration-runner-prisma": "^0.1.2",
|
|
52
|
-
"@xemahq/platform-common": "^0.
|
|
53
|
+
"@xemahq/platform-common": "^0.6.1",
|
|
53
54
|
"pg": "8.16.3"
|
|
54
55
|
},
|
|
55
56
|
"exports": {
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
export { DEFAULT_BIOME_DB_KEY, deriveBiomeSchemaName } from './lib/schema-name';
|
|
2
|
+
export {
|
|
3
|
+
composeIdentifier,
|
|
4
|
+
fitIdentifier,
|
|
5
|
+
IDENTIFIER_HASH_LENGTH,
|
|
6
|
+
POSTGRES_MAX_IDENTIFIER_LENGTH,
|
|
7
|
+
sanitizeIdentifierChars,
|
|
8
|
+
sanitizeIdentifierSegment,
|
|
9
|
+
type ComposeIdentifierInput,
|
|
10
|
+
type FitIdentifierInput,
|
|
11
|
+
} from './lib/identifier';
|
|
12
|
+
export {
|
|
13
|
+
rolesForSchema,
|
|
14
|
+
schemaRoleBase,
|
|
15
|
+
schemaRoleName,
|
|
16
|
+
SchemaRoleKind,
|
|
17
|
+
SCHEMA_ROLE_BASE_MAX_LENGTH,
|
|
18
|
+
SCHEMA_ROLE_SUFFIX_LENGTH,
|
|
19
|
+
type SchemaRoleNames,
|
|
20
|
+
} from './lib/role-names';
|
|
21
|
+
export {
|
|
22
|
+
resolveBiomeDatabaseConfigFromEnv,
|
|
23
|
+
type BiomeDatabaseConfig,
|
|
24
|
+
} from './lib/config';
|
|
25
|
+
export {
|
|
26
|
+
createBiomePrismaAdapter,
|
|
27
|
+
createBiomePrismaAdapterFromEnv,
|
|
28
|
+
} from './lib/adapter';
|
|
29
|
+
export {
|
|
30
|
+
fetchSystemDatabaseConfig,
|
|
31
|
+
type SystemDatabaseConfigRequest,
|
|
32
|
+
} from './lib/control-plane-client';
|
|
33
|
+
export {
|
|
34
|
+
resolveControlPlaneBaseUrl,
|
|
35
|
+
ORG_DATABASE_POOL_SERVICE_NAME,
|
|
36
|
+
type ControlPlaneDiscoveryOptions,
|
|
37
|
+
} from './lib/control-plane-discovery';
|
|
38
|
+
export {
|
|
39
|
+
bootstrapBiomeDatabases,
|
|
40
|
+
type BiomeDatabaseDeclaration,
|
|
41
|
+
type BootstrapBiomeDatabasesOptions,
|
|
42
|
+
} from './lib/bootstrap';
|
|
43
|
+
export { BiomeDatabaseMigrationMode } from './lib/migration-mode';
|
|
44
|
+
export {
|
|
45
|
+
BiomeDatabaseModule,
|
|
46
|
+
BIOME_DATABASE_READY,
|
|
47
|
+
type BiomeDatabaseModuleOptions,
|
|
48
|
+
} from './lib/nest/biome-database.module';
|
|
49
|
+
export {
|
|
50
|
+
createBiomePrismaService,
|
|
51
|
+
type BiomePrismaClient,
|
|
52
|
+
type BiomePrismaClientCtor,
|
|
53
|
+
type BiomePrismaServiceInstance,
|
|
54
|
+
type CreateBiomePrismaServiceOptions,
|
|
55
|
+
type TenantIsolationServiceOptions,
|
|
56
|
+
type TenantScopedApi,
|
|
57
|
+
} from './lib/nest/prisma-service-factory';
|
|
58
|
+
export {
|
|
59
|
+
TenantIsolationMode,
|
|
60
|
+
TENANT_ISOLATION_MODE_ENV_VAR,
|
|
61
|
+
resolveTenantIsolationMode,
|
|
62
|
+
} from './lib/tenant-isolation/tenant-isolation-mode';
|
|
63
|
+
export {
|
|
64
|
+
TenantIsolationError,
|
|
65
|
+
TenantIsolationViolationKind,
|
|
66
|
+
formatTenantIsolationViolation,
|
|
67
|
+
type TenantIsolationViolation,
|
|
68
|
+
} from './lib/tenant-isolation/tenant-isolation-error';
|
|
69
|
+
export {
|
|
70
|
+
PrismaModelOperation,
|
|
71
|
+
scopeArgsToOrg,
|
|
72
|
+
type OrgScopeOutcome,
|
|
73
|
+
type OrgScopeRequest,
|
|
74
|
+
} from './lib/tenant-isolation/org-scope';
|
|
75
|
+
export {
|
|
76
|
+
DEFAULT_ORG_FIELD,
|
|
77
|
+
collectOrgScopedModels,
|
|
78
|
+
createTenantIsolationExtension,
|
|
79
|
+
readRuntimeModels,
|
|
80
|
+
type CreateTenantIsolationExtensionOptions,
|
|
81
|
+
type RuntimeDataModelField,
|
|
82
|
+
type RuntimeDataModelModel,
|
|
83
|
+
type TenantIsolationExtensionDefinition,
|
|
84
|
+
type TenantIsolationLogger,
|
|
85
|
+
type TenantIsolationQueryContext,
|
|
86
|
+
} from './lib/tenant-isolation/tenant-isolation.extension';
|
|
87
|
+
export {
|
|
88
|
+
assertUnscopedModelsDeclared,
|
|
89
|
+
collectUnscopableModels,
|
|
90
|
+
formatUnscopedModelReport,
|
|
91
|
+
normalizeUnscopedModelDeclarations,
|
|
92
|
+
UndeclaredUnscopedModelsError,
|
|
93
|
+
type AssertUnscopedModelsOptions,
|
|
94
|
+
type NormalizedUnscopedModelDeclaration,
|
|
95
|
+
type UnscopedModelDeclaration,
|
|
96
|
+
type UnscopedModelDeclarations,
|
|
97
|
+
} from './lib/tenant-isolation/unscoped-models';
|
|
98
|
+
export {
|
|
99
|
+
eraseOrgData,
|
|
100
|
+
OrgErasureBlockedError,
|
|
101
|
+
type EraseOrgDataOptions,
|
|
102
|
+
type OrgErasureReport,
|
|
103
|
+
} from './lib/tenant-isolation/org-erasure';
|
|
104
|
+
export {
|
|
105
|
+
OrgErasureModule,
|
|
106
|
+
OrgErasureController,
|
|
107
|
+
ORG_ERASURE_RUNNER,
|
|
108
|
+
ORG_DATA_ERASURE_CAPABILITY,
|
|
109
|
+
ORG_ERASURE_ROUTE_PATH,
|
|
110
|
+
type OrgErasureModuleOptions,
|
|
111
|
+
type OrgErasureRunner,
|
|
112
|
+
} from './lib/nest/org-erasure.module';
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { PrismaPg } from '@prisma/adapter-pg';
|
|
2
|
+
import {
|
|
3
|
+
composeBiomeDatabaseUrl,
|
|
4
|
+
ensureBiomeDbSearchPath,
|
|
5
|
+
} from '@xemahq/platform-common';
|
|
6
|
+
|
|
7
|
+
import type { BiomeDatabaseConfig } from './config';
|
|
8
|
+
import { resolveBiomeDatabaseConfigFromEnv } from './config';
|
|
9
|
+
|
|
10
|
+
const DEFAULT_POOL_MAX = 3;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Build a connection string from a {@link BiomeDatabaseConfig}, with `?schema=`
|
|
14
|
+
* when a per-biome schema is set and the libpq `search_path` option applied so
|
|
15
|
+
* RAW queries also resolve to the biome schema.
|
|
16
|
+
*
|
|
17
|
+
* @throws if the config is missing a part required to form a URL.
|
|
18
|
+
*/
|
|
19
|
+
function buildBiomeConnectionString(config: BiomeDatabaseConfig): string {
|
|
20
|
+
const url = composeBiomeDatabaseUrl({
|
|
21
|
+
user: config.username,
|
|
22
|
+
password: config.password,
|
|
23
|
+
host: config.host,
|
|
24
|
+
port: String(config.port),
|
|
25
|
+
database: config.database,
|
|
26
|
+
...(config.schema !== undefined ? { schema: config.schema } : {}),
|
|
27
|
+
...(config.sslParams !== undefined ? { sslParams: config.sslParams } : {}),
|
|
28
|
+
});
|
|
29
|
+
if (url === null) {
|
|
30
|
+
throw new Error(
|
|
31
|
+
'createBiomePrismaAdapter: incomplete BiomeDatabaseConfig — ' +
|
|
32
|
+
'host/port/database/username/password are all required.',
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
return ensureBiomeDbSearchPath(url);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Construct a {@link PrismaPg} driver-adapter pool whose Prisma Client qualifies
|
|
40
|
+
* ORM table names with the biome schema.
|
|
41
|
+
*
|
|
42
|
+
* THIS IS THE CENTRALIZED FIX. `@prisma/adapter-pg` (Prisma 7) ignores BOTH the
|
|
43
|
+
* URL `?schema=` and the connection `search_path` when qualifying ORM-emitted
|
|
44
|
+
* SQL — it falls back to `public.<table>` unless the schema is passed as the
|
|
45
|
+
* SECOND constructor argument. Passing `{ schema }` here makes Prisma emit
|
|
46
|
+
* `biome_<id>.<table>`. `ensureBiomeDbSearchPath` separately fixes RAW queries.
|
|
47
|
+
* Constructing the adapter correctly is the ONLY thing this function does, so
|
|
48
|
+
* the correct construction is the only construction a biome can perform.
|
|
49
|
+
*/
|
|
50
|
+
export function createBiomePrismaAdapter(config: BiomeDatabaseConfig): PrismaPg {
|
|
51
|
+
const connectionString = buildBiomeConnectionString(config);
|
|
52
|
+
return new PrismaPg(
|
|
53
|
+
{
|
|
54
|
+
connectionString,
|
|
55
|
+
min: 1,
|
|
56
|
+
max: config.poolMax ?? DEFAULT_POOL_MAX,
|
|
57
|
+
idleTimeoutMillis: 30_000,
|
|
58
|
+
},
|
|
59
|
+
config.schema !== undefined ? { schema: config.schema } : undefined,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Construct the schema-qualified adapter from the environment — the path the
|
|
65
|
+
* unchanged-shape `PrismaService` calls at construction time (post-bootstrap,
|
|
66
|
+
* where `DATABASE_URL`/`DB_*` are guaranteed set).
|
|
67
|
+
*
|
|
68
|
+
* Resolution order:
|
|
69
|
+
* 1. If `DATABASE_URL` (or `DATABASE_URL_<KEY>` for a non-default key) is set,
|
|
70
|
+
* use it directly as the connection string (still applying
|
|
71
|
+
* `ensureBiomeDbSearchPath` + the `{ schema }` second-arg from `DB_SCHEMA`).
|
|
72
|
+
* 2. Otherwise compose from the discrete `DB_*` vars.
|
|
73
|
+
*
|
|
74
|
+
* @throws if neither a `DATABASE_URL` nor a complete `DB_*` set is present.
|
|
75
|
+
*/
|
|
76
|
+
export function createBiomePrismaAdapterFromEnv(
|
|
77
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
78
|
+
dbKey?: string,
|
|
79
|
+
): PrismaPg {
|
|
80
|
+
const isDefault = dbKey === undefined || dbKey === '' || dbKey === 'primary';
|
|
81
|
+
const upperSuffix = isDefault
|
|
82
|
+
? ''
|
|
83
|
+
: `_${dbKey!.toUpperCase().replace(/[^A-Z0-9]/g, '_')}`;
|
|
84
|
+
|
|
85
|
+
const directUrl = env[`DATABASE_URL${upperSuffix}`];
|
|
86
|
+
const schema = env[`DB_SCHEMA${upperSuffix}`];
|
|
87
|
+
const poolMaxRaw = env[`DB_POOL_MAX${upperSuffix}`] ?? env.DB_POOL_MAX;
|
|
88
|
+
const poolMax =
|
|
89
|
+
poolMaxRaw !== undefined && poolMaxRaw !== ''
|
|
90
|
+
? Number.parseInt(poolMaxRaw, 10)
|
|
91
|
+
: DEFAULT_POOL_MAX;
|
|
92
|
+
|
|
93
|
+
if (directUrl !== undefined && directUrl !== '') {
|
|
94
|
+
const connectionString = ensureBiomeDbSearchPath(directUrl);
|
|
95
|
+
return new PrismaPg(
|
|
96
|
+
{
|
|
97
|
+
connectionString,
|
|
98
|
+
min: 1,
|
|
99
|
+
max: poolMax,
|
|
100
|
+
idleTimeoutMillis: 30_000,
|
|
101
|
+
},
|
|
102
|
+
schema !== undefined && schema !== '' ? { schema } : undefined,
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const config = resolveBiomeDatabaseConfigFromEnv(env, dbKey);
|
|
107
|
+
if (config === null) {
|
|
108
|
+
throw new Error(
|
|
109
|
+
`createBiomePrismaAdapterFromEnv: no DATABASE_URL${upperSuffix} and no ` +
|
|
110
|
+
`DB_HOST${upperSuffix}/DB_HOST in the environment — cannot construct an adapter.`,
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
return createBiomePrismaAdapter(config);
|
|
114
|
+
}
|