@stratum-hq/db-adapters 0.3.1 → 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/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -6
- package/dist/index.js.map +1 -1
- package/dist/rls/session.d.ts +14 -0
- package/dist/rls/session.d.ts.map +1 -1
- package/dist/rls/session.js +31 -0
- package/dist/rls/session.js.map +1 -1
- package/package.json +8 -1
- package/dist/__tests__/base-adapter.test.d.ts +0 -2
- package/dist/__tests__/base-adapter.test.d.ts.map +0 -1
- package/dist/__tests__/base-adapter.test.js +0 -194
- package/dist/__tests__/base-adapter.test.js.map +0 -1
- package/dist/__tests__/database-manager.test.d.ts +0 -2
- package/dist/__tests__/database-manager.test.d.ts.map +0 -1
- package/dist/__tests__/database-manager.test.js +0 -110
- package/dist/__tests__/database-manager.test.js.map +0 -1
- package/dist/__tests__/drizzle.test.d.ts +0 -2
- package/dist/__tests__/drizzle.test.d.ts.map +0 -1
- package/dist/__tests__/drizzle.test.js +0 -177
- package/dist/__tests__/drizzle.test.js.map +0 -1
- package/dist/__tests__/pool-manager.test.d.ts +0 -2
- package/dist/__tests__/pool-manager.test.d.ts.map +0 -1
- package/dist/__tests__/pool-manager.test.js +0 -171
- package/dist/__tests__/pool-manager.test.js.map +0 -1
- package/dist/__tests__/rls-manager.test.d.ts +0 -2
- package/dist/__tests__/rls-manager.test.d.ts.map +0 -1
- package/dist/__tests__/rls-manager.test.js +0 -180
- package/dist/__tests__/rls-manager.test.js.map +0 -1
- package/dist/__tests__/rls-session.test.d.ts +0 -2
- package/dist/__tests__/rls-session.test.d.ts.map +0 -1
- package/dist/__tests__/rls-session.test.js +0 -97
- package/dist/__tests__/rls-session.test.js.map +0 -1
- package/dist/__tests__/schema-manager.test.d.ts +0 -2
- package/dist/__tests__/schema-manager.test.d.ts.map +0 -1
- package/dist/__tests__/schema-manager.test.js +0 -116
- package/dist/__tests__/schema-manager.test.js.map +0 -1
- package/dist/__tests__/schema-session.test.d.ts +0 -2
- package/dist/__tests__/schema-session.test.d.ts.map +0 -1
- package/dist/__tests__/schema-session.test.js +0 -23
- package/dist/__tests__/schema-session.test.js.map +0 -1
- package/dist/__tests__/sequelize.test.d.ts +0 -2
- package/dist/__tests__/sequelize.test.d.ts.map +0 -1
- package/dist/__tests__/sequelize.test.js +0 -150
- package/dist/__tests__/sequelize.test.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
export { BaseAdapter } from "./base-adapter.js";
|
|
2
2
|
export { RawAdapter, createTenantPool } from "./adapters/raw.js";
|
|
3
|
-
export { PrismaAdapter, withTenant } from "./adapters/prisma.js";
|
|
3
|
+
export { PrismaAdapter, withTenant as prismaWithTenant } from "./adapters/prisma.js";
|
|
4
4
|
export { SchemaRawAdapter, createSchemaTenantPool, } from "./adapters/schema-raw.js";
|
|
5
5
|
export { SchemaPrismaAdapter, withSchemaTenant, } from "./adapters/schema-prisma.js";
|
|
6
6
|
export { createPolicy, dropPolicy, enableRLS, disableRLS, isRLSEnabled, } from "./rls/manager.js";
|
|
7
|
-
export { setTenantContext, resetTenantContext, getCurrentTenantId, } from "./rls/session.js";
|
|
7
|
+
export { setTenantContext, resetTenantContext, withTenantContext, withRlsBypass, getCurrentTenantId, } from "./rls/session.js";
|
|
8
8
|
export { createSchema, dropSchema, schemaExists, listTenantSchemas, replicateTableToSchema, tenantSchemaName, } from "./schema/manager.js";
|
|
9
9
|
export { setSchemaSearchPath, resetSearchPath, getCurrentSearchPath, } from "./schema/session.js";
|
|
10
|
-
export { addTenantColumn, enableRLS as
|
|
10
|
+
export { addTenantColumn, enableRLS as enableRLSForMigration, createIsolationPolicy, migrateTable, } from "./migration-helpers.js";
|
|
11
11
|
export { getDatabaseName, databaseExists, createDatabase, dropDatabase, } from "./database/manager.js";
|
|
12
12
|
export { DatabasePoolManager } from "./database/pool-manager.js";
|
|
13
13
|
export type { DatabasePoolManagerOptions } from "./database/pool-manager.js";
|
|
14
14
|
export { DatabaseRawAdapter } from "./adapters/database-raw.js";
|
|
15
15
|
export { DatabasePrismaAdapter } from "./adapters/database-prisma.js";
|
|
16
|
-
export { SequelizeAdapter, withTenantScope } from "./adapters/sequelize.js";
|
|
17
|
-
export { DrizzleAdapter, withTenant as
|
|
16
|
+
export { SequelizeAdapter, withTenantScope as sequelizeWithTenantScope } from "./adapters/sequelize.js";
|
|
17
|
+
export { DrizzleAdapter, withTenant as drizzleWithTenant, withTenantScope as drizzleWithTenantScope, } from "./adapters/drizzle.js";
|
|
18
18
|
export type { DrizzleLike } from "./adapters/drizzle.js";
|
|
19
19
|
//# 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,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,UAAU,IAAI,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACrF,OAAO,EACL,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EACL,YAAY,EACZ,UAAU,EACV,SAAS,EACT,UAAU,EACV,YAAY,GACb,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,aAAa,EACb,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,eAAe,EACf,SAAS,IAAI,qBAAqB,EAClC,qBAAqB,EACrB,YAAY,GACb,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EACL,eAAe,EACf,cAAc,EACd,cAAc,EACd,YAAY,GACb,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,YAAY,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AAE7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,eAAe,IAAI,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACxG,OAAO,EACL,cAAc,EACd,UAAU,IAAI,iBAAiB,EAC/B,eAAe,IAAI,sBAAsB,GAC1C,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.drizzleWithTenantScope = exports.drizzleWithTenant = exports.DrizzleAdapter = exports.sequelizeWithTenantScope = exports.SequelizeAdapter = exports.DatabasePrismaAdapter = exports.DatabaseRawAdapter = exports.DatabasePoolManager = exports.dropDatabase = exports.createDatabase = exports.databaseExists = exports.getDatabaseName = exports.migrateTable = exports.createIsolationPolicy = exports.enableRLSForMigration = exports.addTenantColumn = exports.getCurrentSearchPath = exports.resetSearchPath = exports.setSchemaSearchPath = exports.tenantSchemaName = exports.replicateTableToSchema = exports.listTenantSchemas = exports.schemaExists = exports.dropSchema = exports.createSchema = exports.getCurrentTenantId = exports.withRlsBypass = exports.withTenantContext = exports.resetTenantContext = exports.setTenantContext = exports.isRLSEnabled = exports.disableRLS = exports.enableRLS = exports.dropPolicy = exports.createPolicy = exports.withSchemaTenant = exports.SchemaPrismaAdapter = exports.createSchemaTenantPool = exports.SchemaRawAdapter = exports.prismaWithTenant = exports.PrismaAdapter = exports.createTenantPool = exports.RawAdapter = exports.BaseAdapter = void 0;
|
|
4
4
|
var base_adapter_js_1 = require("./base-adapter.js");
|
|
5
5
|
Object.defineProperty(exports, "BaseAdapter", { enumerable: true, get: function () { return base_adapter_js_1.BaseAdapter; } });
|
|
6
6
|
var raw_js_1 = require("./adapters/raw.js");
|
|
@@ -8,7 +8,7 @@ Object.defineProperty(exports, "RawAdapter", { enumerable: true, get: function (
|
|
|
8
8
|
Object.defineProperty(exports, "createTenantPool", { enumerable: true, get: function () { return raw_js_1.createTenantPool; } });
|
|
9
9
|
var prisma_js_1 = require("./adapters/prisma.js");
|
|
10
10
|
Object.defineProperty(exports, "PrismaAdapter", { enumerable: true, get: function () { return prisma_js_1.PrismaAdapter; } });
|
|
11
|
-
Object.defineProperty(exports, "
|
|
11
|
+
Object.defineProperty(exports, "prismaWithTenant", { enumerable: true, get: function () { return prisma_js_1.withTenant; } });
|
|
12
12
|
var schema_raw_js_1 = require("./adapters/schema-raw.js");
|
|
13
13
|
Object.defineProperty(exports, "SchemaRawAdapter", { enumerable: true, get: function () { return schema_raw_js_1.SchemaRawAdapter; } });
|
|
14
14
|
Object.defineProperty(exports, "createSchemaTenantPool", { enumerable: true, get: function () { return schema_raw_js_1.createSchemaTenantPool; } });
|
|
@@ -24,6 +24,8 @@ Object.defineProperty(exports, "isRLSEnabled", { enumerable: true, get: function
|
|
|
24
24
|
var session_js_1 = require("./rls/session.js");
|
|
25
25
|
Object.defineProperty(exports, "setTenantContext", { enumerable: true, get: function () { return session_js_1.setTenantContext; } });
|
|
26
26
|
Object.defineProperty(exports, "resetTenantContext", { enumerable: true, get: function () { return session_js_1.resetTenantContext; } });
|
|
27
|
+
Object.defineProperty(exports, "withTenantContext", { enumerable: true, get: function () { return session_js_1.withTenantContext; } });
|
|
28
|
+
Object.defineProperty(exports, "withRlsBypass", { enumerable: true, get: function () { return session_js_1.withRlsBypass; } });
|
|
27
29
|
Object.defineProperty(exports, "getCurrentTenantId", { enumerable: true, get: function () { return session_js_1.getCurrentTenantId; } });
|
|
28
30
|
var manager_js_2 = require("./schema/manager.js");
|
|
29
31
|
Object.defineProperty(exports, "createSchema", { enumerable: true, get: function () { return manager_js_2.createSchema; } });
|
|
@@ -38,7 +40,7 @@ Object.defineProperty(exports, "resetSearchPath", { enumerable: true, get: funct
|
|
|
38
40
|
Object.defineProperty(exports, "getCurrentSearchPath", { enumerable: true, get: function () { return session_js_2.getCurrentSearchPath; } });
|
|
39
41
|
var migration_helpers_js_1 = require("./migration-helpers.js");
|
|
40
42
|
Object.defineProperty(exports, "addTenantColumn", { enumerable: true, get: function () { return migration_helpers_js_1.addTenantColumn; } });
|
|
41
|
-
Object.defineProperty(exports, "
|
|
43
|
+
Object.defineProperty(exports, "enableRLSForMigration", { enumerable: true, get: function () { return migration_helpers_js_1.enableRLS; } });
|
|
42
44
|
Object.defineProperty(exports, "createIsolationPolicy", { enumerable: true, get: function () { return migration_helpers_js_1.createIsolationPolicy; } });
|
|
43
45
|
Object.defineProperty(exports, "migrateTable", { enumerable: true, get: function () { return migration_helpers_js_1.migrateTable; } });
|
|
44
46
|
// DB_PER_TENANT isolation
|
|
@@ -55,9 +57,9 @@ var database_prisma_js_1 = require("./adapters/database-prisma.js");
|
|
|
55
57
|
Object.defineProperty(exports, "DatabasePrismaAdapter", { enumerable: true, get: function () { return database_prisma_js_1.DatabasePrismaAdapter; } });
|
|
56
58
|
var sequelize_js_1 = require("./adapters/sequelize.js");
|
|
57
59
|
Object.defineProperty(exports, "SequelizeAdapter", { enumerable: true, get: function () { return sequelize_js_1.SequelizeAdapter; } });
|
|
58
|
-
Object.defineProperty(exports, "
|
|
60
|
+
Object.defineProperty(exports, "sequelizeWithTenantScope", { enumerable: true, get: function () { return sequelize_js_1.withTenantScope; } });
|
|
59
61
|
var drizzle_js_1 = require("./adapters/drizzle.js");
|
|
60
62
|
Object.defineProperty(exports, "DrizzleAdapter", { enumerable: true, get: function () { return drizzle_js_1.DrizzleAdapter; } });
|
|
61
|
-
Object.defineProperty(exports, "
|
|
62
|
-
Object.defineProperty(exports, "
|
|
63
|
+
Object.defineProperty(exports, "drizzleWithTenant", { enumerable: true, get: function () { return drizzle_js_1.withTenant; } });
|
|
64
|
+
Object.defineProperty(exports, "drizzleWithTenantScope", { enumerable: true, get: function () { return drizzle_js_1.withTenantScope; } });
|
|
63
65
|
//# 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,qDAAgD;AAAvC,8GAAA,WAAW,OAAA;AAEpB,4CAAiE;AAAxD,oGAAA,UAAU,OAAA;AAAE,0GAAA,gBAAgB,OAAA;AACrC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,qDAAgD;AAAvC,8GAAA,WAAW,OAAA;AAEpB,4CAAiE;AAAxD,oGAAA,UAAU,OAAA;AAAE,0GAAA,gBAAgB,OAAA;AACrC,kDAAqF;AAA5E,0GAAA,aAAa,OAAA;AAAE,6GAAA,UAAU,OAAoB;AACtD,0DAGkC;AAFhC,iHAAA,gBAAgB,OAAA;AAChB,uHAAA,sBAAsB,OAAA;AAExB,gEAGqC;AAFnC,uHAAA,mBAAmB,OAAA;AACnB,oHAAA,gBAAgB,OAAA;AAGlB,+CAM0B;AALxB,0GAAA,YAAY,OAAA;AACZ,wGAAA,UAAU,OAAA;AACV,uGAAA,SAAS,OAAA;AACT,wGAAA,UAAU,OAAA;AACV,0GAAA,YAAY,OAAA;AAGd,+CAM0B;AALxB,8GAAA,gBAAgB,OAAA;AAChB,gHAAA,kBAAkB,OAAA;AAClB,+GAAA,iBAAiB,OAAA;AACjB,2GAAA,aAAa,OAAA;AACb,gHAAA,kBAAkB,OAAA;AAGpB,kDAO6B;AAN3B,0GAAA,YAAY,OAAA;AACZ,wGAAA,UAAU,OAAA;AACV,0GAAA,YAAY,OAAA;AACZ,+GAAA,iBAAiB,OAAA;AACjB,oHAAA,sBAAsB,OAAA;AACtB,8GAAA,gBAAgB,OAAA;AAGlB,kDAI6B;AAH3B,iHAAA,mBAAmB,OAAA;AACnB,6GAAA,eAAe,OAAA;AACf,kHAAA,oBAAoB,OAAA;AAGtB,+DAKgC;AAJ9B,uHAAA,eAAe,OAAA;AACf,6HAAA,SAAS,OAAyB;AAClC,6HAAA,qBAAqB,OAAA;AACrB,oHAAA,YAAY,OAAA;AAGd,0BAA0B;AAC1B,oDAK+B;AAJ7B,6GAAA,eAAe,OAAA;AACf,4GAAA,cAAc,OAAA;AACd,4GAAA,cAAc,OAAA;AACd,0GAAA,YAAY,OAAA;AAGd,8DAAiE;AAAxD,sHAAA,mBAAmB,OAAA;AAG5B,8DAAgE;AAAvD,qHAAA,kBAAkB,OAAA;AAC3B,oEAAsE;AAA7D,2HAAA,qBAAqB,OAAA;AAC9B,wDAAwG;AAA/F,gHAAA,gBAAgB,OAAA;AAAE,wHAAA,eAAe,OAA4B;AACtE,oDAI+B;AAH7B,4GAAA,cAAc,OAAA;AACd,+GAAA,UAAU,OAAqB;AAC/B,oHAAA,eAAe,OAA0B"}
|
package/dist/rls/session.d.ts
CHANGED
|
@@ -2,5 +2,19 @@ import pg from "pg";
|
|
|
2
2
|
export declare function setTenantContext(client: pg.PoolClient, tenantId: string): Promise<void>;
|
|
3
3
|
export declare function resetTenantContext(client: pg.PoolClient): Promise<void>;
|
|
4
4
|
export declare function withTenantContext<T>(pool: pg.Pool, tenantId: string, fn: (client: pg.PoolClient) => Promise<T>): Promise<T>;
|
|
5
|
+
/**
|
|
6
|
+
* Runs `fn` inside a transaction with the RLS bypass flag set, so control-plane
|
|
7
|
+
* / system operations that legitimately span tenant boundaries (provisioning,
|
|
8
|
+
* cascade ops, ancestry reads) can see and write all rows.
|
|
9
|
+
*
|
|
10
|
+
* The flag is set with `SET LOCAL` semantics (set_config third arg `true`), so it
|
|
11
|
+
* is transaction scoped and cannot leak into a later request that reuses the same
|
|
12
|
+
* pooled connection. This is the audited system path referenced by the RLS
|
|
13
|
+
* policies (which admit `current_setting('app.bypass_rls', true) = 'on'`).
|
|
14
|
+
*
|
|
15
|
+
* Use sparingly and only for operations that are known to require cross-tenant
|
|
16
|
+
* access. Tenant-scoped work should use `withTenantContext` instead.
|
|
17
|
+
*/
|
|
18
|
+
export declare function withRlsBypass<T>(pool: pg.Pool, fn: (client: pg.PoolClient) => Promise<T>): Promise<T>;
|
|
5
19
|
export declare function getCurrentTenantId(client: pg.PoolClient): Promise<string | null>;
|
|
6
20
|
//# sourceMappingURL=session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/rls/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,EAAE,CAAC,UAAU,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7E;AAED,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,GACxC,OAAO,CAAC,CAAC,CAAC,CAcZ;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,EAAE,CAAC,UAAU,GACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAMxB"}
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/rls/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,EAAE,CAAC,UAAU,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7E;AAED,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,GACxC,OAAO,CAAC,CAAC,CAAC,CAcZ;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,GACxC,OAAO,CAAC,CAAC,CAAC,CAcZ;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,EAAE,CAAC,UAAU,GACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAMxB"}
|
package/dist/rls/session.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.setTenantContext = setTenantContext;
|
|
4
4
|
exports.resetTenantContext = resetTenantContext;
|
|
5
5
|
exports.withTenantContext = withTenantContext;
|
|
6
|
+
exports.withRlsBypass = withRlsBypass;
|
|
6
7
|
exports.getCurrentTenantId = getCurrentTenantId;
|
|
7
8
|
async function setTenantContext(client, tenantId) {
|
|
8
9
|
await client.query("SELECT set_config('app.current_tenant_id', $1, true)", [tenantId]);
|
|
@@ -27,6 +28,36 @@ async function withTenantContext(pool, tenantId, fn) {
|
|
|
27
28
|
client.release();
|
|
28
29
|
}
|
|
29
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Runs `fn` inside a transaction with the RLS bypass flag set, so control-plane
|
|
33
|
+
* / system operations that legitimately span tenant boundaries (provisioning,
|
|
34
|
+
* cascade ops, ancestry reads) can see and write all rows.
|
|
35
|
+
*
|
|
36
|
+
* The flag is set with `SET LOCAL` semantics (set_config third arg `true`), so it
|
|
37
|
+
* is transaction scoped and cannot leak into a later request that reuses the same
|
|
38
|
+
* pooled connection. This is the audited system path referenced by the RLS
|
|
39
|
+
* policies (which admit `current_setting('app.bypass_rls', true) = 'on'`).
|
|
40
|
+
*
|
|
41
|
+
* Use sparingly and only for operations that are known to require cross-tenant
|
|
42
|
+
* access. Tenant-scoped work should use `withTenantContext` instead.
|
|
43
|
+
*/
|
|
44
|
+
async function withRlsBypass(pool, fn) {
|
|
45
|
+
const client = await pool.connect();
|
|
46
|
+
try {
|
|
47
|
+
await client.query("BEGIN");
|
|
48
|
+
await client.query("SELECT set_config('app.bypass_rls', 'on', true)");
|
|
49
|
+
const result = await fn(client);
|
|
50
|
+
await client.query("COMMIT");
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
await client.query("ROLLBACK");
|
|
55
|
+
throw err;
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
client.release();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
30
61
|
async function getCurrentTenantId(client) {
|
|
31
62
|
const res = await client.query(`SELECT current_setting('app.current_tenant_id', true) AS current_setting`);
|
|
32
63
|
const value = res.rows[0]?.current_setting;
|
package/dist/rls/session.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/rls/session.ts"],"names":[],"mappings":";;AAEA,4CAKC;AAED,gDAEC;AAED,8CAkBC;AAED,gDAQC;
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/rls/session.ts"],"names":[],"mappings":";;AAEA,4CAKC;AAED,gDAEC;AAED,8CAkBC;AAeD,sCAiBC;AAED,gDAQC;AAvEM,KAAK,UAAU,gBAAgB,CACpC,MAAqB,EACrB,QAAgB;IAEhB,MAAM,MAAM,CAAC,KAAK,CAAC,sDAAsD,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AACzF,CAAC;AAEM,KAAK,UAAU,kBAAkB,CAAC,MAAqB;IAC5D,MAAM,MAAM,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;AAC7E,CAAC;AAEM,KAAK,UAAU,iBAAiB,CACrC,IAAa,EACb,QAAgB,EAChB,EAAyC;IAEzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5B,MAAM,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC/B,MAAM,GAAG,CAAC;IACZ,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACI,KAAK,UAAU,aAAa,CACjC,IAAa,EACb,EAAyC;IAEzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5B,MAAM,MAAM,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACtE,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC7B,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC/B,MAAM,GAAG,CAAC;IACZ,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,OAAO,EAAE,CAAC;IACnB,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,kBAAkB,CACtC,MAAqB;IAErB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,KAAK,CAC5B,0EAA0E,CAC3E,CAAC;IACF,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC;IAC3C,OAAO,KAAK,IAAI,IAAI,CAAC;AACvB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stratum-hq/db-adapters",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "Stratum PostgreSQL adapters for tenant-scoped query isolation",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"multi-tenancy",
|
|
@@ -58,6 +58,13 @@
|
|
|
58
58
|
"typescript": "^5.4.0",
|
|
59
59
|
"vitest": "^1.6.0"
|
|
60
60
|
},
|
|
61
|
+
"license": "MIT",
|
|
62
|
+
"author": "Christian Crank",
|
|
63
|
+
"homepage": "https://github.com/stratum-hq/Stratum/tree/main/packages/db-adapters#readme",
|
|
64
|
+
"bugs": "https://github.com/stratum-hq/Stratum/issues",
|
|
65
|
+
"engines": {
|
|
66
|
+
"node": ">=20.0.0"
|
|
67
|
+
},
|
|
61
68
|
"repository": {
|
|
62
69
|
"type": "git",
|
|
63
70
|
"url": "https://github.com/stratum-hq/Stratum.git",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base-adapter.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/base-adapter.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const vitest_1 = require("vitest");
|
|
4
|
-
const base_adapter_js_1 = require("../base-adapter.js");
|
|
5
|
-
// ---------------------------------------------------------------------------
|
|
6
|
-
// Mock pg
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
|
-
const mockQuery = vitest_1.vi.fn();
|
|
9
|
-
const mockRelease = vitest_1.vi.fn();
|
|
10
|
-
const mockConnect = vitest_1.vi.fn();
|
|
11
|
-
// Create a mock Pool class that will be used directly
|
|
12
|
-
class MockPool {
|
|
13
|
-
connect = mockConnect;
|
|
14
|
-
}
|
|
15
|
-
vitest_1.vi.mock("pg", () => {
|
|
16
|
-
return { default: { Pool: MockPool }, Pool: MockPool };
|
|
17
|
-
});
|
|
18
|
-
// ---------------------------------------------------------------------------
|
|
19
|
-
// Concrete subclass for testing the abstract BaseAdapter
|
|
20
|
-
// ---------------------------------------------------------------------------
|
|
21
|
-
class TestAdapter extends base_adapter_js_1.BaseAdapter {
|
|
22
|
-
// Expose executeWithTenantContext publicly for testing
|
|
23
|
-
async runWithTenant(tenantId, fn) {
|
|
24
|
-
return this.executeWithTenantContext(tenantId, fn);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
// ---------------------------------------------------------------------------
|
|
28
|
-
// Helpers
|
|
29
|
-
// ---------------------------------------------------------------------------
|
|
30
|
-
function makeMockClient() {
|
|
31
|
-
const client = {
|
|
32
|
-
query: mockQuery,
|
|
33
|
-
release: mockRelease,
|
|
34
|
-
};
|
|
35
|
-
return client;
|
|
36
|
-
}
|
|
37
|
-
// ---------------------------------------------------------------------------
|
|
38
|
-
// Tests
|
|
39
|
-
// ---------------------------------------------------------------------------
|
|
40
|
-
(0, vitest_1.describe)("BaseAdapter", () => {
|
|
41
|
-
let adapter;
|
|
42
|
-
(0, vitest_1.beforeEach)(() => {
|
|
43
|
-
vitest_1.vi.clearAllMocks();
|
|
44
|
-
const mockClient = makeMockClient();
|
|
45
|
-
mockConnect.mockResolvedValue(mockClient);
|
|
46
|
-
mockQuery.mockResolvedValue({ rows: [] });
|
|
47
|
-
const pool = new MockPool();
|
|
48
|
-
adapter = new TestAdapter(pool);
|
|
49
|
-
});
|
|
50
|
-
(0, vitest_1.describe)("executeWithTenantContext", () => {
|
|
51
|
-
(0, vitest_1.it)("acquires a client from the pool", async () => {
|
|
52
|
-
await adapter.runWithTenant("tenant-1", async () => "result");
|
|
53
|
-
(0, vitest_1.expect)(mockConnect).toHaveBeenCalledTimes(1);
|
|
54
|
-
});
|
|
55
|
-
(0, vitest_1.it)("begins a transaction", async () => {
|
|
56
|
-
await adapter.runWithTenant("tenant-1", async () => "result");
|
|
57
|
-
(0, vitest_1.expect)(mockQuery).toHaveBeenCalledWith("BEGIN");
|
|
58
|
-
});
|
|
59
|
-
(0, vitest_1.it)("sets tenant context with correct SQL and parameters", async () => {
|
|
60
|
-
await adapter.runWithTenant("tenant-abc", async () => "ok");
|
|
61
|
-
(0, vitest_1.expect)(mockQuery).toHaveBeenCalledWith("SELECT set_config('app.current_tenant_id', $1, true)", ["tenant-abc"]);
|
|
62
|
-
});
|
|
63
|
-
(0, vitest_1.it)("executes the provided query function", async () => {
|
|
64
|
-
const queryFn = vitest_1.vi.fn().mockResolvedValue("my-result");
|
|
65
|
-
await adapter.runWithTenant("tenant-1", queryFn);
|
|
66
|
-
(0, vitest_1.expect)(queryFn).toHaveBeenCalledTimes(1);
|
|
67
|
-
});
|
|
68
|
-
(0, vitest_1.it)("passes the client to the query function", async () => {
|
|
69
|
-
const queryFn = vitest_1.vi.fn().mockResolvedValue("ok");
|
|
70
|
-
await adapter.runWithTenant("tenant-1", queryFn);
|
|
71
|
-
// The queryFn receives the mock client
|
|
72
|
-
const passedClient = queryFn.mock.calls[0][0];
|
|
73
|
-
(0, vitest_1.expect)(passedClient.query).toBeDefined();
|
|
74
|
-
(0, vitest_1.expect)(passedClient.release).toBeDefined();
|
|
75
|
-
});
|
|
76
|
-
(0, vitest_1.it)("commits the transaction on success", async () => {
|
|
77
|
-
await adapter.runWithTenant("tenant-1", async () => "ok");
|
|
78
|
-
const queryCalls = mockQuery.mock.calls.map((c) => c[0]);
|
|
79
|
-
(0, vitest_1.expect)(queryCalls).toContain("COMMIT");
|
|
80
|
-
});
|
|
81
|
-
(0, vitest_1.it)("returns the result from the query function", async () => {
|
|
82
|
-
const result = await adapter.runWithTenant("tenant-1", async () => ({ data: [1, 2, 3] }));
|
|
83
|
-
(0, vitest_1.expect)(result).toEqual({ data: [1, 2, 3] });
|
|
84
|
-
});
|
|
85
|
-
(0, vitest_1.it)("executes in the correct order: BEGIN, set_config, queryFn, COMMIT", async () => {
|
|
86
|
-
const callOrder = [];
|
|
87
|
-
mockQuery.mockImplementation(async (sql) => {
|
|
88
|
-
if (typeof sql === "string") {
|
|
89
|
-
if (sql === "BEGIN")
|
|
90
|
-
callOrder.push("BEGIN");
|
|
91
|
-
else if (sql.includes("set_config"))
|
|
92
|
-
callOrder.push("SET_CONFIG");
|
|
93
|
-
else if (sql === "COMMIT")
|
|
94
|
-
callOrder.push("COMMIT");
|
|
95
|
-
else if (sql === "ROLLBACK")
|
|
96
|
-
callOrder.push("ROLLBACK");
|
|
97
|
-
else if (sql === "RESET app.current_tenant_id")
|
|
98
|
-
callOrder.push("RESET");
|
|
99
|
-
}
|
|
100
|
-
return { rows: [] };
|
|
101
|
-
});
|
|
102
|
-
await adapter.runWithTenant("tenant-1", async () => {
|
|
103
|
-
callOrder.push("QUERY_FN");
|
|
104
|
-
return "done";
|
|
105
|
-
});
|
|
106
|
-
(0, vitest_1.expect)(callOrder).toEqual([
|
|
107
|
-
"BEGIN",
|
|
108
|
-
"SET_CONFIG",
|
|
109
|
-
"QUERY_FN",
|
|
110
|
-
"COMMIT",
|
|
111
|
-
"RESET",
|
|
112
|
-
]);
|
|
113
|
-
});
|
|
114
|
-
(0, vitest_1.it)("rolls back on error from query function", async () => {
|
|
115
|
-
const error = new Error("query failed");
|
|
116
|
-
await (0, vitest_1.expect)(adapter.runWithTenant("tenant-1", async () => {
|
|
117
|
-
throw error;
|
|
118
|
-
})).rejects.toThrow("query failed");
|
|
119
|
-
(0, vitest_1.expect)(mockQuery).toHaveBeenCalledWith("ROLLBACK");
|
|
120
|
-
});
|
|
121
|
-
(0, vitest_1.it)("does not commit when query function throws", async () => {
|
|
122
|
-
try {
|
|
123
|
-
await adapter.runWithTenant("tenant-1", async () => {
|
|
124
|
-
throw new Error("fail");
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
catch {
|
|
128
|
-
// expected
|
|
129
|
-
}
|
|
130
|
-
const queryCalls = mockQuery.mock.calls.map((c) => c[0]);
|
|
131
|
-
(0, vitest_1.expect)(queryCalls).not.toContain("COMMIT");
|
|
132
|
-
});
|
|
133
|
-
(0, vitest_1.it)("resets tenant context in finally block on success", async () => {
|
|
134
|
-
await adapter.runWithTenant("tenant-1", async () => "ok");
|
|
135
|
-
(0, vitest_1.expect)(mockQuery).toHaveBeenCalledWith("RESET app.current_tenant_id");
|
|
136
|
-
});
|
|
137
|
-
(0, vitest_1.it)("resets tenant context in finally block on error", async () => {
|
|
138
|
-
try {
|
|
139
|
-
await adapter.runWithTenant("tenant-1", async () => {
|
|
140
|
-
throw new Error("boom");
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
catch {
|
|
144
|
-
// expected
|
|
145
|
-
}
|
|
146
|
-
(0, vitest_1.expect)(mockQuery).toHaveBeenCalledWith("RESET app.current_tenant_id");
|
|
147
|
-
});
|
|
148
|
-
(0, vitest_1.it)("releases the client on success", async () => {
|
|
149
|
-
await adapter.runWithTenant("tenant-1", async () => "ok");
|
|
150
|
-
(0, vitest_1.expect)(mockRelease).toHaveBeenCalledTimes(1);
|
|
151
|
-
});
|
|
152
|
-
(0, vitest_1.it)("releases the client on error", async () => {
|
|
153
|
-
try {
|
|
154
|
-
await adapter.runWithTenant("tenant-1", async () => {
|
|
155
|
-
throw new Error("fail");
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
catch {
|
|
159
|
-
// expected
|
|
160
|
-
}
|
|
161
|
-
(0, vitest_1.expect)(mockRelease).toHaveBeenCalledTimes(1);
|
|
162
|
-
});
|
|
163
|
-
(0, vitest_1.it)("still releases client if RESET query fails", async () => {
|
|
164
|
-
let callCount = 0;
|
|
165
|
-
mockQuery.mockImplementation(async (sql) => {
|
|
166
|
-
callCount++;
|
|
167
|
-
if (typeof sql === "string" && sql.includes("RESET")) {
|
|
168
|
-
throw new Error("connection broken");
|
|
169
|
-
}
|
|
170
|
-
return { rows: [] };
|
|
171
|
-
});
|
|
172
|
-
await adapter.runWithTenant("tenant-1", async () => "ok");
|
|
173
|
-
// Client should still be released even though RESET threw
|
|
174
|
-
(0, vitest_1.expect)(mockRelease).toHaveBeenCalledTimes(1);
|
|
175
|
-
});
|
|
176
|
-
(0, vitest_1.it)("propagates the original error even if ROLLBACK fails", async () => {
|
|
177
|
-
mockQuery.mockImplementation(async (sql) => {
|
|
178
|
-
if (typeof sql === "string" && sql === "ROLLBACK") {
|
|
179
|
-
throw new Error("rollback failed");
|
|
180
|
-
}
|
|
181
|
-
return { rows: [] };
|
|
182
|
-
});
|
|
183
|
-
// The queryFn throws — we want the original error, but ROLLBACK also throws.
|
|
184
|
-
// In the current implementation, ROLLBACK failure replaces the original error
|
|
185
|
-
// because there's no catch around ROLLBACK. Let's verify behavior:
|
|
186
|
-
await (0, vitest_1.expect)(adapter.runWithTenant("tenant-1", async () => {
|
|
187
|
-
throw new Error("original error");
|
|
188
|
-
})).rejects.toThrow();
|
|
189
|
-
// Client should still be released
|
|
190
|
-
(0, vitest_1.expect)(mockRelease).toHaveBeenCalledTimes(1);
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
//# sourceMappingURL=base-adapter.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base-adapter.test.js","sourceRoot":"","sources":["../../src/__tests__/base-adapter.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"database-manager.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/database-manager.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const vitest_1 = require("vitest");
|
|
4
|
-
const manager_js_1 = require("../database/manager.js");
|
|
5
|
-
// ---------------------------------------------------------------------------
|
|
6
|
-
// getDatabaseName
|
|
7
|
-
// ---------------------------------------------------------------------------
|
|
8
|
-
(0, vitest_1.describe)("getDatabaseName", () => {
|
|
9
|
-
(0, vitest_1.it)("returns correct name for a simple slug", () => {
|
|
10
|
-
(0, vitest_1.expect)((0, manager_js_1.getDatabaseName)("acme")).toBe("stratum_tenant_acme");
|
|
11
|
-
});
|
|
12
|
-
(0, vitest_1.it)("handles slugs with numbers and underscores", () => {
|
|
13
|
-
(0, vitest_1.expect)((0, manager_js_1.getDatabaseName)("acme_corp_2")).toBe("stratum_tenant_acme_corp_2");
|
|
14
|
-
});
|
|
15
|
-
(0, vitest_1.it)("throws on slug with hyphens", () => {
|
|
16
|
-
(0, vitest_1.expect)(() => (0, manager_js_1.getDatabaseName)("acme-corp")).toThrow(/Invalid tenant slug/);
|
|
17
|
-
});
|
|
18
|
-
(0, vitest_1.it)("throws on slug starting with a number", () => {
|
|
19
|
-
(0, vitest_1.expect)(() => (0, manager_js_1.getDatabaseName)("1acme")).toThrow(/Invalid tenant slug/);
|
|
20
|
-
});
|
|
21
|
-
(0, vitest_1.it)("throws on empty slug", () => {
|
|
22
|
-
(0, vitest_1.expect)(() => (0, manager_js_1.getDatabaseName)("")).toThrow(/Invalid tenant slug/);
|
|
23
|
-
});
|
|
24
|
-
(0, vitest_1.it)("throws on slug with uppercase letters", () => {
|
|
25
|
-
(0, vitest_1.expect)(() => (0, manager_js_1.getDatabaseName)("Acme")).toThrow(/Invalid tenant slug/);
|
|
26
|
-
});
|
|
27
|
-
(0, vitest_1.it)("throws on slug that is too long (> 63 chars)", () => {
|
|
28
|
-
// 64 chars: 'a' + 63 'x'
|
|
29
|
-
const longSlug = "a" + "x".repeat(63);
|
|
30
|
-
(0, vitest_1.expect)(() => (0, manager_js_1.getDatabaseName)(longSlug)).toThrow(/Invalid tenant slug/);
|
|
31
|
-
});
|
|
32
|
-
(0, vitest_1.it)("accepts maximum-length slug (63 chars)", () => {
|
|
33
|
-
const maxSlug = "a" + "x".repeat(62); // 63 chars total
|
|
34
|
-
(0, vitest_1.expect)((0, manager_js_1.getDatabaseName)(maxSlug)).toBe(`stratum_tenant_${maxSlug}`);
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
// ---------------------------------------------------------------------------
|
|
38
|
-
// databaseExists
|
|
39
|
-
// ---------------------------------------------------------------------------
|
|
40
|
-
(0, vitest_1.describe)("databaseExists", () => {
|
|
41
|
-
function makeClient(exists) {
|
|
42
|
-
return {
|
|
43
|
-
query: vitest_1.vi.fn().mockResolvedValue({ rows: [{ exists }] }),
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
(0, vitest_1.it)("returns true when database exists", async () => {
|
|
47
|
-
const client = makeClient(true);
|
|
48
|
-
const result = await (0, manager_js_1.databaseExists)(client, "acme");
|
|
49
|
-
(0, vitest_1.expect)(result).toBe(true);
|
|
50
|
-
(0, vitest_1.expect)(client.query).toHaveBeenCalledWith(vitest_1.expect.stringContaining("pg_database"), ["stratum_tenant_acme"]);
|
|
51
|
-
});
|
|
52
|
-
(0, vitest_1.it)("returns false when database does not exist", async () => {
|
|
53
|
-
const client = makeClient(false);
|
|
54
|
-
const result = await (0, manager_js_1.databaseExists)(client, "acme");
|
|
55
|
-
(0, vitest_1.expect)(result).toBe(false);
|
|
56
|
-
});
|
|
57
|
-
(0, vitest_1.it)("throws on invalid slug", async () => {
|
|
58
|
-
const client = makeClient(false);
|
|
59
|
-
await (0, vitest_1.expect)((0, manager_js_1.databaseExists)(client, "bad-slug")).rejects.toThrow(/Invalid tenant slug/);
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
// ---------------------------------------------------------------------------
|
|
63
|
-
// createDatabase
|
|
64
|
-
// ---------------------------------------------------------------------------
|
|
65
|
-
(0, vitest_1.describe)("createDatabase", () => {
|
|
66
|
-
function makeClient() {
|
|
67
|
-
return {
|
|
68
|
-
query: vitest_1.vi.fn().mockResolvedValue({}),
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
(0, vitest_1.it)("issues CREATE DATABASE with correct name", async () => {
|
|
72
|
-
const client = makeClient();
|
|
73
|
-
await (0, manager_js_1.createDatabase)(client, "acme");
|
|
74
|
-
(0, vitest_1.expect)(client.query).toHaveBeenCalledWith('CREATE DATABASE "stratum_tenant_acme"');
|
|
75
|
-
});
|
|
76
|
-
(0, vitest_1.it)("includes TEMPLATE clause when templateDb is provided", async () => {
|
|
77
|
-
const client = makeClient();
|
|
78
|
-
await (0, manager_js_1.createDatabase)(client, "acme", "stratum_base");
|
|
79
|
-
(0, vitest_1.expect)(client.query).toHaveBeenCalledWith('CREATE DATABASE "stratum_tenant_acme" TEMPLATE "stratum_base"');
|
|
80
|
-
});
|
|
81
|
-
(0, vitest_1.it)("throws on invalid template database name", async () => {
|
|
82
|
-
const client = makeClient();
|
|
83
|
-
await (0, vitest_1.expect)((0, manager_js_1.createDatabase)(client, "acme", "bad-template!")).rejects.toThrow(/Invalid template database name/);
|
|
84
|
-
(0, vitest_1.expect)(client.query).not.toHaveBeenCalled();
|
|
85
|
-
});
|
|
86
|
-
(0, vitest_1.it)("throws on invalid slug", async () => {
|
|
87
|
-
const client = makeClient();
|
|
88
|
-
await (0, vitest_1.expect)((0, manager_js_1.createDatabase)(client, "bad-slug")).rejects.toThrow(/Invalid tenant slug/);
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
// ---------------------------------------------------------------------------
|
|
92
|
-
// dropDatabase
|
|
93
|
-
// ---------------------------------------------------------------------------
|
|
94
|
-
(0, vitest_1.describe)("dropDatabase", () => {
|
|
95
|
-
function makeClient() {
|
|
96
|
-
return {
|
|
97
|
-
query: vitest_1.vi.fn().mockResolvedValue({}),
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
(0, vitest_1.it)("issues DROP DATABASE IF EXISTS with correct name", async () => {
|
|
101
|
-
const client = makeClient();
|
|
102
|
-
await (0, manager_js_1.dropDatabase)(client, "acme");
|
|
103
|
-
(0, vitest_1.expect)(client.query).toHaveBeenCalledWith('DROP DATABASE IF EXISTS "stratum_tenant_acme"');
|
|
104
|
-
});
|
|
105
|
-
(0, vitest_1.it)("throws on invalid slug", async () => {
|
|
106
|
-
const client = makeClient();
|
|
107
|
-
await (0, vitest_1.expect)((0, manager_js_1.dropDatabase)(client, "bad slug")).rejects.toThrow(/Invalid tenant slug/);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
//# sourceMappingURL=database-manager.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"database-manager.test.js","sourceRoot":"","sources":["../../src/__tests__/database-manager.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"drizzle.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/drizzle.test.ts"],"names":[],"mappings":""}
|