@xemahq/biome-database-nest 0.5.2 → 0.6.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 +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/nest/org-erasure.module.d.ts +20 -0
- package/dist/lib/nest/org-erasure.module.d.ts.map +1 -0
- package/dist/lib/nest/org-erasure.module.js +69 -0
- package/dist/lib/nest/org-erasure.module.js.map +1 -0
- package/dist/lib/tenant-isolation/org-erasure.d.ts +17 -0
- package/dist/lib/tenant-isolation/org-erasure.d.ts.map +1 -0
- package/dist/lib/tenant-isolation/org-erasure.js +71 -0
- package/dist/lib/tenant-isolation/org-erasure.js.map +1 -0
- package/package.json +6 -2
package/dist/index.d.ts
CHANGED
|
@@ -10,4 +10,6 @@ export { TenantIsolationMode, TENANT_ISOLATION_MODE_ENV_VAR, resolveTenantIsolat
|
|
|
10
10
|
export { TenantIsolationError, TenantIsolationViolationKind, formatTenantIsolationViolation, type TenantIsolationViolation, } from './lib/tenant-isolation/tenant-isolation-error';
|
|
11
11
|
export { PrismaModelOperation, scopeArgsToOrg, type OrgScopeOutcome, type OrgScopeRequest, } from './lib/tenant-isolation/org-scope';
|
|
12
12
|
export { DEFAULT_ORG_FIELD, collectOrgScopedModels, createTenantIsolationExtension, type CreateTenantIsolationExtensionOptions, type TenantIsolationExtensionDefinition, type TenantIsolationLogger, type TenantIsolationQueryContext, } from './lib/tenant-isolation/tenant-isolation.extension';
|
|
13
|
+
export { eraseOrgData, OrgErasureBlockedError, type EraseOrgDataOptions, type OrgErasureReport, } from './lib/tenant-isolation/org-erasure';
|
|
14
|
+
export { OrgErasureModule, OrgErasureController, ORG_ERASURE_RUNNER, ORG_DATA_ERASURE_CAPABILITY, ORG_ERASURE_ROUTE_PATH, type OrgErasureModuleOptions, type OrgErasureRunner, } from './lib/nest/org-erasure.module';
|
|
13
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EACL,iCAAiC,EACjC,KAAK,mBAAmB,GACzB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,yBAAyB,EACzB,KAAK,2BAA2B,GACjC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,0BAA0B,EAC1B,8BAA8B,EAC9B,KAAK,4BAA4B,GAClC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,uBAAuB,EACvB,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,GACpC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,0BAA0B,GAChC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,wBAAwB,EACxB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,EAC/B,KAAK,+BAA+B,EACpC,KAAK,6BAA6B,EAClC,KAAK,eAAe,GACrB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,0BAA0B,GAC3B,MAAM,8CAA8C,CAAC;AACtD,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,8BAA8B,EAC9B,KAAK,wBAAwB,GAC9B,MAAM,+CAA+C,CAAC;AACvD,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,8BAA8B,EAC9B,KAAK,qCAAqC,EAC1C,KAAK,kCAAkC,EACvC,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,GACjC,MAAM,mDAAmD,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EACL,iCAAiC,EACjC,KAAK,mBAAmB,GACzB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,wBAAwB,EACxB,+BAA+B,GAChC,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,yBAAyB,EACzB,KAAK,2BAA2B,GACjC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,0BAA0B,EAC1B,8BAA8B,EAC9B,KAAK,4BAA4B,GAClC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,uBAAuB,EACvB,KAAK,wBAAwB,EAC7B,KAAK,8BAA8B,GACpC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,KAAK,0BAA0B,GAChC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,wBAAwB,EACxB,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC1B,KAAK,0BAA0B,EAC/B,KAAK,+BAA+B,EACpC,KAAK,6BAA6B,EAClC,KAAK,eAAe,GACrB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,0BAA0B,GAC3B,MAAM,8CAA8C,CAAC;AACtD,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,8BAA8B,EAC9B,KAAK,wBAAwB,GAC9B,MAAM,+CAA+C,CAAC;AACvD,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,eAAe,GACrB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,8BAA8B,EAC9B,KAAK,qCAAqC,EAC1C,KAAK,kCAAkC,EACvC,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,GACjC,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACtB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,kBAAkB,EAClB,2BAA2B,EAC3B,sBAAsB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,GACtB,MAAM,+BAA+B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
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.bootstrapBiomeDatabases = exports.ORG_DATABASE_POOL_SERVICE_NAME = exports.resolveControlPlaneBaseUrl = exports.fetchSystemDatabaseConfig = exports.createBiomePrismaAdapterFromEnv = exports.createBiomePrismaAdapter = exports.resolveBiomeDatabaseConfigFromEnv = exports.deriveBiomeSchemaName = exports.DEFAULT_BIOME_DB_KEY = void 0;
|
|
3
|
+
exports.ORG_ERASURE_ROUTE_PATH = exports.ORG_DATA_ERASURE_CAPABILITY = exports.ORG_ERASURE_RUNNER = exports.OrgErasureController = exports.OrgErasureModule = exports.OrgErasureBlockedError = exports.eraseOrgData = 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.bootstrapBiomeDatabases = exports.ORG_DATABASE_POOL_SERVICE_NAME = exports.resolveControlPlaneBaseUrl = exports.fetchSystemDatabaseConfig = exports.createBiomePrismaAdapterFromEnv = exports.createBiomePrismaAdapter = exports.resolveBiomeDatabaseConfigFromEnv = exports.deriveBiomeSchemaName = exports.DEFAULT_BIOME_DB_KEY = void 0;
|
|
4
4
|
var schema_name_1 = require("./lib/schema-name");
|
|
5
5
|
Object.defineProperty(exports, "DEFAULT_BIOME_DB_KEY", { enumerable: true, get: function () { return schema_name_1.DEFAULT_BIOME_DB_KEY; } });
|
|
6
6
|
Object.defineProperty(exports, "deriveBiomeSchemaName", { enumerable: true, get: function () { return schema_name_1.deriveBiomeSchemaName; } });
|
|
@@ -36,4 +36,13 @@ var tenant_isolation_extension_1 = require("./lib/tenant-isolation/tenant-isolat
|
|
|
36
36
|
Object.defineProperty(exports, "DEFAULT_ORG_FIELD", { enumerable: true, get: function () { return tenant_isolation_extension_1.DEFAULT_ORG_FIELD; } });
|
|
37
37
|
Object.defineProperty(exports, "collectOrgScopedModels", { enumerable: true, get: function () { return tenant_isolation_extension_1.collectOrgScopedModels; } });
|
|
38
38
|
Object.defineProperty(exports, "createTenantIsolationExtension", { enumerable: true, get: function () { return tenant_isolation_extension_1.createTenantIsolationExtension; } });
|
|
39
|
+
var org_erasure_1 = require("./lib/tenant-isolation/org-erasure");
|
|
40
|
+
Object.defineProperty(exports, "eraseOrgData", { enumerable: true, get: function () { return org_erasure_1.eraseOrgData; } });
|
|
41
|
+
Object.defineProperty(exports, "OrgErasureBlockedError", { enumerable: true, get: function () { return org_erasure_1.OrgErasureBlockedError; } });
|
|
42
|
+
var org_erasure_module_1 = require("./lib/nest/org-erasure.module");
|
|
43
|
+
Object.defineProperty(exports, "OrgErasureModule", { enumerable: true, get: function () { return org_erasure_module_1.OrgErasureModule; } });
|
|
44
|
+
Object.defineProperty(exports, "OrgErasureController", { enumerable: true, get: function () { return org_erasure_module_1.OrgErasureController; } });
|
|
45
|
+
Object.defineProperty(exports, "ORG_ERASURE_RUNNER", { enumerable: true, get: function () { return org_erasure_module_1.ORG_ERASURE_RUNNER; } });
|
|
46
|
+
Object.defineProperty(exports, "ORG_DATA_ERASURE_CAPABILITY", { enumerable: true, get: function () { return org_erasure_module_1.ORG_DATA_ERASURE_CAPABILITY; } });
|
|
47
|
+
Object.defineProperty(exports, "ORG_ERASURE_ROUTE_PATH", { enumerable: true, get: function () { return org_erasure_module_1.ORG_ERASURE_ROUTE_PATH; } });
|
|
39
48
|
//# sourceMappingURL=index.js.map
|
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,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;AAIzB,0EAI0C;AAHxC,4HAAA,mBAAmB,OAAA;AACnB,6HAAA,oBAAoB,OAAA;AAGtB,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,gGAQ2D;AAPzD,+HAAA,iBAAiB,OAAA;AACjB,oIAAA,sBAAsB,OAAA;AACtB,4IAAA,8BAA8B,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,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;AAIzB,0EAI0C;AAHxC,4HAAA,mBAAmB,OAAA;AACnB,6HAAA,oBAAoB,OAAA;AAGtB,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,gGAQ2D;AAPzD,+HAAA,iBAAiB,OAAA;AACjB,oIAAA,sBAAsB,OAAA;AACtB,4IAAA,8BAA8B,OAAA;AAMhC,kEAK4C;AAJ1C,2GAAA,YAAY,OAAA;AACZ,qHAAA,sBAAsB,OAAA;AAIxB,oEAQuC;AAPrC,sHAAA,gBAAgB,OAAA;AAChB,0HAAA,oBAAoB,OAAA;AACpB,wHAAA,kBAAkB,OAAA;AAClB,iIAAA,2BAA2B,OAAA;AAC3B,4HAAA,sBAAsB,OAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type DynamicModule, type Type } from '@nestjs/common';
|
|
2
|
+
import { type EraseOrgDataOptions, type OrgErasureReport } from '../tenant-isolation/org-erasure';
|
|
3
|
+
export declare const ORG_ERASURE_RUNNER: unique symbol;
|
|
4
|
+
export declare const ORG_DATA_ERASURE_CAPABILITY = "xema.org-data-erasure";
|
|
5
|
+
export declare const ORG_ERASURE_ROUTE_PATH = "internal/org-erasure";
|
|
6
|
+
export interface OrgErasureRunner {
|
|
7
|
+
erase(orgId: string): Promise<OrgErasureReport>;
|
|
8
|
+
}
|
|
9
|
+
export declare class OrgErasureController {
|
|
10
|
+
private readonly runner;
|
|
11
|
+
constructor(runner: OrgErasureRunner);
|
|
12
|
+
erase(orgId: string): Promise<OrgErasureReport>;
|
|
13
|
+
}
|
|
14
|
+
export interface OrgErasureModuleOptions extends EraseOrgDataOptions {
|
|
15
|
+
readonly prismaServiceToken: Type<unknown> | string | symbol;
|
|
16
|
+
}
|
|
17
|
+
export declare class OrgErasureModule {
|
|
18
|
+
static forRoot(options: OrgErasureModuleOptions): DynamicModule;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=org-erasure.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org-erasure.module.d.ts","sourceRoot":"","sources":["../../../src/lib/nest/org-erasure.module.ts"],"names":[],"mappings":"AAoBA,OAAO,EAML,KAAK,aAAa,EAClB,KAAK,IAAI,EACV,MAAM,gBAAgB,CAAC;AAIxB,OAAO,EAEL,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACtB,MAAM,iCAAiC,CAAC;AAKzC,eAAO,MAAM,kBAAkB,eAE9B,CAAC;AAUF,eAAO,MAAM,2BAA2B,0BAA0B,CAAC;AAGnE,eAAO,MAAM,sBAAsB,yBAAyB,CAAC;AAE7D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACjD;AAED,qBAEa,oBAAoB;IAED,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,gBAAgB;IASvE,KAAK,CAAiB,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAGhE;AAED,MAAM,WAAW,uBAAwB,SAAQ,mBAAmB;IAMlE,QAAQ,CAAC,kBAAkB,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,MAAM,GAAG,MAAM,CAAC;CAC9D;AAQD,qBAAa,gBAAgB;IAC3B,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,uBAAuB,GAAG,aAAa;CAiBhE"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.OrgErasureModule = exports.OrgErasureController = exports.ORG_ERASURE_ROUTE_PATH = exports.ORG_DATA_ERASURE_CAPABILITY = exports.ORG_ERASURE_RUNNER = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
18
|
+
const xema_decorators_1 = require("@xemahq/xema-decorators");
|
|
19
|
+
const org_erasure_1 = require("../tenant-isolation/org-erasure");
|
|
20
|
+
exports.ORG_ERASURE_RUNNER = Symbol.for('@xemahq/biome-database-nest/org-erasure-runner');
|
|
21
|
+
exports.ORG_DATA_ERASURE_CAPABILITY = 'xema.org-data-erasure';
|
|
22
|
+
exports.ORG_ERASURE_ROUTE_PATH = 'internal/org-erasure';
|
|
23
|
+
let OrgErasureController = class OrgErasureController {
|
|
24
|
+
runner;
|
|
25
|
+
constructor(runner) {
|
|
26
|
+
this.runner = runner;
|
|
27
|
+
}
|
|
28
|
+
erase(orgId) {
|
|
29
|
+
return this.runner.erase(orgId);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
exports.OrgErasureController = OrgErasureController;
|
|
33
|
+
__decorate([
|
|
34
|
+
(0, xema_decorators_1.XemaInternalRoute)({ audience: xema_decorators_1.InternalRouteAudience.Service }),
|
|
35
|
+
(0, common_1.Post)(':orgId'),
|
|
36
|
+
(0, swagger_1.ApiOperation)({
|
|
37
|
+
summary: "Erase every row belonging to an org across this service's org-scoped models",
|
|
38
|
+
}),
|
|
39
|
+
__param(0, (0, common_1.Param)('orgId')),
|
|
40
|
+
__metadata("design:type", Function),
|
|
41
|
+
__metadata("design:paramtypes", [String]),
|
|
42
|
+
__metadata("design:returntype", Promise)
|
|
43
|
+
], OrgErasureController.prototype, "erase", null);
|
|
44
|
+
exports.OrgErasureController = OrgErasureController = __decorate([
|
|
45
|
+
(0, swagger_1.ApiTags)('org-erasure'),
|
|
46
|
+
(0, common_1.Controller)('internal/org-erasure'),
|
|
47
|
+
__param(0, (0, common_1.Inject)(exports.ORG_ERASURE_RUNNER)),
|
|
48
|
+
__metadata("design:paramtypes", [Object])
|
|
49
|
+
], OrgErasureController);
|
|
50
|
+
class OrgErasureModule {
|
|
51
|
+
static forRoot(options) {
|
|
52
|
+
const { prismaServiceToken, ...eraseOptions } = options;
|
|
53
|
+
return {
|
|
54
|
+
module: OrgErasureModule,
|
|
55
|
+
controllers: [OrgErasureController],
|
|
56
|
+
providers: [
|
|
57
|
+
{
|
|
58
|
+
provide: exports.ORG_ERASURE_RUNNER,
|
|
59
|
+
useFactory: (prisma) => ({
|
|
60
|
+
erase: (orgId) => (0, org_erasure_1.eraseOrgData)(prisma.asSystem(), orgId, eraseOptions),
|
|
61
|
+
}),
|
|
62
|
+
inject: [prismaServiceToken],
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.OrgErasureModule = OrgErasureModule;
|
|
69
|
+
//# sourceMappingURL=org-erasure.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org-erasure.module.js","sourceRoot":"","sources":["../../../src/lib/nest/org-erasure.module.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAoBA,2CAQwB;AACxB,6CAAwD;AACxD,6DAAmF;AAEnF,iEAIyC;AAK5B,QAAA,kBAAkB,GAAG,MAAM,CAAC,GAAG,CAC1C,gDAAgD,CACjD,CAAC;AAUW,QAAA,2BAA2B,GAAG,uBAAuB,CAAC;AAGtD,QAAA,sBAAsB,GAAG,sBAAsB,CAAC;AAQtD,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAEgB;IAD/C,YAC+C,MAAwB;QAAxB,WAAM,GAAN,MAAM,CAAkB;IACpE,CAAC;IAQJ,KAAK,CAAiB,KAAa;QACjC,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAClC,CAAC;CACF,CAAA;AAdY,oDAAoB;AAW/B;IANC,IAAA,mCAAiB,EAAC,EAAE,QAAQ,EAAE,uCAAqB,CAAC,OAAO,EAAE,CAAC;IAC9D,IAAA,aAAI,EAAC,QAAQ,CAAC;IACd,IAAA,sBAAY,EAAC;QACZ,OAAO,EACL,6EAA6E;KAChF,CAAC;IACK,WAAA,IAAA,cAAK,EAAC,OAAO,CAAC,CAAA;;;;iDAEpB;+BAbU,oBAAoB;IAFhC,IAAA,iBAAO,EAAC,aAAa,CAAC;IACtB,IAAA,mBAAU,EAAC,sBAAsB,CAAC;IAG9B,WAAA,IAAA,eAAM,EAAC,0BAAkB,CAAC,CAAA;;GAFlB,oBAAoB,CAchC;AAiBD,MAAa,gBAAgB;IAC3B,MAAM,CAAC,OAAO,CAAC,OAAgC;QAC7C,MAAM,EAAE,kBAAkB,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC;QACxD,OAAO;YACL,MAAM,EAAE,gBAAgB;YACxB,WAAW,EAAE,CAAC,oBAAoB,CAAC;YACnC,SAAS,EAAE;gBACT;oBACE,OAAO,EAAE,0BAAkB;oBAC3B,UAAU,EAAE,CAAC,MAAwB,EAAoB,EAAE,CAAC,CAAC;wBAC3D,KAAK,EAAE,CAAC,KAAa,EAA6B,EAAE,CAClD,IAAA,0BAAY,EAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC;qBACvD,CAAC;oBACF,MAAM,EAAE,CAAC,kBAAkB,CAAC;iBAC7B;aACF;SACF,CAAC;IACJ,CAAC;CACF;AAlBD,4CAkBC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface EraseOrgDataOptions {
|
|
2
|
+
readonly orgField?: string;
|
|
3
|
+
readonly exemptModels?: readonly string[];
|
|
4
|
+
}
|
|
5
|
+
export interface OrgErasureReport {
|
|
6
|
+
readonly orgId: string;
|
|
7
|
+
readonly deletedByModel: Readonly<Record<string, number>>;
|
|
8
|
+
readonly totalDeleted: number;
|
|
9
|
+
readonly passes: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class OrgErasureBlockedError extends Error {
|
|
12
|
+
readonly orgId: string;
|
|
13
|
+
readonly blockedModels: readonly string[];
|
|
14
|
+
constructor(orgId: string, blockedModels: readonly string[]);
|
|
15
|
+
}
|
|
16
|
+
export declare function eraseOrgData(client: unknown, orgId: string, options?: EraseOrgDataOptions): Promise<OrgErasureReport>;
|
|
17
|
+
//# sourceMappingURL=org-erasure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org-erasure.d.ts","sourceRoot":"","sources":["../../../src/lib/tenant-isolation/org-erasure.ts"],"names":[],"mappings":"AA8BA,MAAM,WAAW,mBAAmB;IAElC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAQ3B,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3C;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC1D,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAE9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAGD,qBAAa,sBAAuB,SAAQ,KAAK;IAE7C,QAAQ,CAAC,KAAK,EAAE,MAAM;IACtB,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE;gBADhC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,SAAS,MAAM,EAAE;CAY5C;AA2BD,wBAAsB,YAAY,CAChC,MAAM,EAAE,OAAO,EACf,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,gBAAgB,CAAC,CA0D3B"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OrgErasureBlockedError = void 0;
|
|
4
|
+
exports.eraseOrgData = eraseOrgData;
|
|
5
|
+
const tenant_isolation_extension_1 = require("./tenant-isolation.extension");
|
|
6
|
+
const PRISMA_FK_VIOLATION_CODE = 'P2003';
|
|
7
|
+
class OrgErasureBlockedError extends Error {
|
|
8
|
+
orgId;
|
|
9
|
+
blockedModels;
|
|
10
|
+
constructor(orgId, blockedModels) {
|
|
11
|
+
super(`[org-erasure] could not erase org "${orgId}": models [${blockedModels.join(', ')}] remain blocked by a foreign key after a no-progress pass. This means a ` +
|
|
12
|
+
`non-org-scoped table references these org rows, or the org-scoped models ` +
|
|
13
|
+
`form a delete cycle. Add an onDelete rule or a service-specific eraser — ` +
|
|
14
|
+
`erasure MUST NOT leave a silent partial.`);
|
|
15
|
+
this.orgId = orgId;
|
|
16
|
+
this.blockedModels = blockedModels;
|
|
17
|
+
this.name = 'OrgErasureBlockedError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.OrgErasureBlockedError = OrgErasureBlockedError;
|
|
21
|
+
function delegateKeyForModel(modelName) {
|
|
22
|
+
return modelName.charAt(0).toLowerCase() + modelName.slice(1);
|
|
23
|
+
}
|
|
24
|
+
function isForeignKeyViolation(error) {
|
|
25
|
+
return (typeof error === 'object' &&
|
|
26
|
+
error !== null &&
|
|
27
|
+
error.code === PRISMA_FK_VIOLATION_CODE);
|
|
28
|
+
}
|
|
29
|
+
async function eraseOrgData(client, orgId, options = {}) {
|
|
30
|
+
const orgField = options.orgField ?? tenant_isolation_extension_1.DEFAULT_ORG_FIELD;
|
|
31
|
+
if (orgId.trim() === '') {
|
|
32
|
+
throw new Error('[org-erasure] orgId must be a non-empty string.');
|
|
33
|
+
}
|
|
34
|
+
const scoped = (0, tenant_isolation_extension_1.collectOrgScopedModels)(client, orgField, options.exemptModels ?? []);
|
|
35
|
+
const deletedByModel = {};
|
|
36
|
+
let remaining = [...scoped];
|
|
37
|
+
let passes = 0;
|
|
38
|
+
while (remaining.length > 0) {
|
|
39
|
+
passes += 1;
|
|
40
|
+
const blocked = [];
|
|
41
|
+
let progressed = false;
|
|
42
|
+
for (const modelName of remaining) {
|
|
43
|
+
const delegate = client[delegateKeyForModel(modelName)];
|
|
44
|
+
if (delegate?.deleteMany === undefined) {
|
|
45
|
+
throw new Error(`[org-erasure] Prisma client has no deleteMany delegate for model ` +
|
|
46
|
+
`"${modelName}" (looked up "${delegateKeyForModel(modelName)}").`);
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const { count } = await delegate.deleteMany({
|
|
50
|
+
where: { [orgField]: orgId },
|
|
51
|
+
});
|
|
52
|
+
deletedByModel[modelName] = (deletedByModel[modelName] ?? 0) + count;
|
|
53
|
+
progressed = true;
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
if (isForeignKeyViolation(error)) {
|
|
57
|
+
blocked.push(modelName);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (!progressed && blocked.length > 0) {
|
|
64
|
+
throw new OrgErasureBlockedError(orgId, blocked);
|
|
65
|
+
}
|
|
66
|
+
remaining = blocked;
|
|
67
|
+
}
|
|
68
|
+
const totalDeleted = Object.values(deletedByModel).reduce((sum, n) => sum + n, 0);
|
|
69
|
+
return { orgId, deletedByModel, totalDeleted, passes };
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=org-erasure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"org-erasure.js","sourceRoot":"","sources":["../../../src/lib/tenant-isolation/org-erasure.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.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Layer 1 SDK that centralizes ALL database concerns for Xema biome services. Provides the single correct construction of a schema-qualified Prisma driver-adapter (the second-arg `{ schema }` that makes `@prisma/adapter-pg` qualify `biome_<id>.<table>` instead of `public.<table>`), the per-biome schema-naming convention, env/control-plane config resolution, and a boot-time bootstrap that creates the schema and runs migrations. Biomes carry zero DB boilerplate.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Neuralchowder Inc. <developer@xema.dev> (https://xema.dev)",
|
|
@@ -23,11 +23,13 @@
|
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@nestjs/common": "11.1.13",
|
|
25
25
|
"@nestjs/core": "11.1.13",
|
|
26
|
+
"@nestjs/swagger": "11.2.6",
|
|
26
27
|
"@types/jest": "^30.0.0",
|
|
27
28
|
"@types/node": "25.2.3",
|
|
28
29
|
"@types/pg": "^8.16.0",
|
|
29
30
|
"@xemahq/identity-client": "^0.3.5",
|
|
30
31
|
"@xemahq/kernel-contracts": "^0.48.0",
|
|
32
|
+
"@xemahq/xema-decorators": "^0.2.0",
|
|
31
33
|
"jest": "^30.3.0",
|
|
32
34
|
"prettier": "3.6.2",
|
|
33
35
|
"ts-jest": "^29.4.9",
|
|
@@ -37,11 +39,13 @@
|
|
|
37
39
|
"peerDependencies": {
|
|
38
40
|
"@nestjs/common": "^10 || ^11",
|
|
39
41
|
"@nestjs/core": "^10 || ^11",
|
|
42
|
+
"@nestjs/swagger": "^10 || ^11",
|
|
40
43
|
"@prisma/adapter-pg": "^7",
|
|
41
44
|
"@prisma/client": "^7",
|
|
42
45
|
"@xemahq/identity-client": "^0.3.0",
|
|
43
46
|
"@xemahq/kernel-contracts": ">=0.13.0",
|
|
44
|
-
"@xemahq/service-registry-nest": ">=0.2.0"
|
|
47
|
+
"@xemahq/service-registry-nest": ">=0.2.0",
|
|
48
|
+
"@xemahq/xema-decorators": ">=0.2.0"
|
|
45
49
|
},
|
|
46
50
|
"dependencies": {
|
|
47
51
|
"@xemahq/migration-runner-prisma": "^0.1.2",
|