@stratum-hq/db-adapters 0.4.0 → 1.1.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.
Files changed (76) hide show
  1. package/README.md +22 -4
  2. package/dist/adapters/database-prisma.d.ts +4 -2
  3. package/dist/adapters/database-prisma.d.ts.map +1 -1
  4. package/dist/adapters/database-prisma.js +19 -6
  5. package/dist/adapters/database-prisma.js.map +1 -1
  6. package/dist/adapters/drizzle.d.ts +2 -2
  7. package/dist/adapters/drizzle.d.ts.map +1 -1
  8. package/dist/adapters/drizzle.js +9 -8
  9. package/dist/adapters/drizzle.js.map +1 -1
  10. package/dist/adapters/prisma.d.ts +1 -1
  11. package/dist/adapters/prisma.d.ts.map +1 -1
  12. package/dist/adapters/prisma.js +12 -5
  13. package/dist/adapters/prisma.js.map +1 -1
  14. package/dist/adapters/schema-prisma.d.ts +36 -4
  15. package/dist/adapters/schema-prisma.d.ts.map +1 -1
  16. package/dist/adapters/schema-prisma.js +55 -17
  17. package/dist/adapters/schema-prisma.js.map +1 -1
  18. package/dist/adapters/schema-raw.d.ts +14 -3
  19. package/dist/adapters/schema-raw.d.ts.map +1 -1
  20. package/dist/adapters/schema-raw.js +9 -5
  21. package/dist/adapters/schema-raw.js.map +1 -1
  22. package/dist/database/manager.d.ts.map +1 -1
  23. package/dist/database/manager.js +7 -1
  24. package/dist/database/manager.js.map +1 -1
  25. package/dist/database/pool-manager.d.ts.map +1 -1
  26. package/dist/database/pool-manager.js +2 -3
  27. package/dist/database/pool-manager.js.map +1 -1
  28. package/dist/index.d.ts +5 -4
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +6 -6
  31. package/dist/index.js.map +1 -1
  32. package/dist/schema/manager.d.ts +1 -0
  33. package/dist/schema/manager.d.ts.map +1 -1
  34. package/dist/schema/manager.js +11 -2
  35. package/dist/schema/manager.js.map +1 -1
  36. package/dist/schema/session.d.ts +10 -1
  37. package/dist/schema/session.d.ts.map +1 -1
  38. package/dist/schema/session.js +24 -4
  39. package/dist/schema/session.js.map +1 -1
  40. package/package.json +10 -2
  41. package/dist/__tests__/base-adapter.test.d.ts +0 -2
  42. package/dist/__tests__/base-adapter.test.d.ts.map +0 -1
  43. package/dist/__tests__/base-adapter.test.js +0 -194
  44. package/dist/__tests__/base-adapter.test.js.map +0 -1
  45. package/dist/__tests__/database-manager.test.d.ts +0 -2
  46. package/dist/__tests__/database-manager.test.d.ts.map +0 -1
  47. package/dist/__tests__/database-manager.test.js +0 -110
  48. package/dist/__tests__/database-manager.test.js.map +0 -1
  49. package/dist/__tests__/drizzle.test.d.ts +0 -2
  50. package/dist/__tests__/drizzle.test.d.ts.map +0 -1
  51. package/dist/__tests__/drizzle.test.js +0 -177
  52. package/dist/__tests__/drizzle.test.js.map +0 -1
  53. package/dist/__tests__/pool-manager.test.d.ts +0 -2
  54. package/dist/__tests__/pool-manager.test.d.ts.map +0 -1
  55. package/dist/__tests__/pool-manager.test.js +0 -171
  56. package/dist/__tests__/pool-manager.test.js.map +0 -1
  57. package/dist/__tests__/rls-manager.test.d.ts +0 -2
  58. package/dist/__tests__/rls-manager.test.d.ts.map +0 -1
  59. package/dist/__tests__/rls-manager.test.js +0 -180
  60. package/dist/__tests__/rls-manager.test.js.map +0 -1
  61. package/dist/__tests__/rls-session.test.d.ts +0 -2
  62. package/dist/__tests__/rls-session.test.d.ts.map +0 -1
  63. package/dist/__tests__/rls-session.test.js +0 -97
  64. package/dist/__tests__/rls-session.test.js.map +0 -1
  65. package/dist/__tests__/schema-manager.test.d.ts +0 -2
  66. package/dist/__tests__/schema-manager.test.d.ts.map +0 -1
  67. package/dist/__tests__/schema-manager.test.js +0 -116
  68. package/dist/__tests__/schema-manager.test.js.map +0 -1
  69. package/dist/__tests__/schema-session.test.d.ts +0 -2
  70. package/dist/__tests__/schema-session.test.d.ts.map +0 -1
  71. package/dist/__tests__/schema-session.test.js +0 -23
  72. package/dist/__tests__/schema-session.test.js.map +0 -1
  73. package/dist/__tests__/sequelize.test.d.ts +0 -2
  74. package/dist/__tests__/sequelize.test.d.ts.map +0 -1
  75. package/dist/__tests__/sequelize.test.js +0 -150
  76. package/dist/__tests__/sequelize.test.js.map +0 -1
@@ -1,97 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const vitest_1 = require("vitest");
4
- const session_js_1 = require("../rls/session.js");
5
- // ---------------------------------------------------------------------------
6
- // Mock pg.PoolClient
7
- // ---------------------------------------------------------------------------
8
- function makeMockClient() {
9
- return {
10
- query: vitest_1.vi.fn().mockResolvedValue({ rows: [], rowCount: 0 }),
11
- };
12
- }
13
- // ---------------------------------------------------------------------------
14
- // Tests
15
- // ---------------------------------------------------------------------------
16
- (0, vitest_1.describe)("RLS Session", () => {
17
- let client;
18
- (0, vitest_1.beforeEach)(() => {
19
- client = makeMockClient();
20
- });
21
- // -----------------------------------------------------------------------
22
- // setTenantContext
23
- // -----------------------------------------------------------------------
24
- (0, vitest_1.describe)("setTenantContext", () => {
25
- (0, vitest_1.it)("sets the correct session variable via set_config", async () => {
26
- await (0, session_js_1.setTenantContext)(client, "tenant-abc-123");
27
- const call = client.query.mock.calls[0];
28
- (0, vitest_1.expect)(call[0]).toBe("SELECT set_config('app.current_tenant_id', $1, true)");
29
- (0, vitest_1.expect)(call[1]).toEqual(["tenant-abc-123"]);
30
- });
31
- (0, vitest_1.it)("passes the tenant ID as a parameterized value", async () => {
32
- await (0, session_js_1.setTenantContext)(client, "f47ac10b-58cc-4372-a567-0e02b2c3d479");
33
- const params = client.query.mock
34
- .calls[0][1];
35
- (0, vitest_1.expect)(params).toEqual(["f47ac10b-58cc-4372-a567-0e02b2c3d479"]);
36
- });
37
- (0, vitest_1.it)("uses transaction-scoped scope (third arg true)", async () => {
38
- await (0, session_js_1.setTenantContext)(client, "any-tenant");
39
- const sql = client.query.mock.calls[0][0];
40
- // The third argument to set_config is `true`, meaning transaction-scoped
41
- // so context is automatically cleared when the transaction ends
42
- (0, vitest_1.expect)(sql).toContain("true");
43
- });
44
- });
45
- // -----------------------------------------------------------------------
46
- // resetTenantContext
47
- // -----------------------------------------------------------------------
48
- (0, vitest_1.describe)("resetTenantContext", () => {
49
- (0, vitest_1.it)("resets the session variable via set_config with empty string", async () => {
50
- await (0, session_js_1.resetTenantContext)(client);
51
- const call = client.query.mock.calls[0];
52
- (0, vitest_1.expect)(call[0]).toBe("SELECT set_config('app.current_tenant_id', '', true)");
53
- });
54
- });
55
- // -----------------------------------------------------------------------
56
- // getCurrentTenantId
57
- // -----------------------------------------------------------------------
58
- (0, vitest_1.describe)("getCurrentTenantId", () => {
59
- (0, vitest_1.it)("reads the session variable via current_setting", async () => {
60
- client.query.mockResolvedValueOnce({
61
- rows: [{ current_setting: "tenant-xyz" }],
62
- });
63
- await (0, session_js_1.getCurrentTenantId)(client);
64
- const sql = client.query.mock.calls[0][0];
65
- (0, vitest_1.expect)(sql).toContain("current_setting('app.current_tenant_id'");
66
- });
67
- (0, vitest_1.it)("returns the tenant ID when set", async () => {
68
- client.query.mockResolvedValueOnce({
69
- rows: [{ current_setting: "tenant-xyz" }],
70
- });
71
- const result = await (0, session_js_1.getCurrentTenantId)(client);
72
- (0, vitest_1.expect)(result).toBe("tenant-xyz");
73
- });
74
- (0, vitest_1.it)("returns null when the setting is empty string", async () => {
75
- client.query.mockResolvedValueOnce({
76
- rows: [{ current_setting: "" }],
77
- });
78
- const result = await (0, session_js_1.getCurrentTenantId)(client);
79
- (0, vitest_1.expect)(result).toBeNull();
80
- });
81
- (0, vitest_1.it)("returns null when rows are empty", async () => {
82
- client.query.mockResolvedValueOnce({
83
- rows: [],
84
- });
85
- const result = await (0, session_js_1.getCurrentTenantId)(client);
86
- (0, vitest_1.expect)(result).toBeNull();
87
- });
88
- (0, vitest_1.it)("returns null when current_setting is null", async () => {
89
- client.query.mockResolvedValueOnce({
90
- rows: [{ current_setting: null }],
91
- });
92
- const result = await (0, session_js_1.getCurrentTenantId)(client);
93
- (0, vitest_1.expect)(result).toBeNull();
94
- });
95
- });
96
- });
97
- //# sourceMappingURL=rls-session.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rls-session.test.js","sourceRoot":"","sources":["../../src/__tests__/rls-session.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=schema-manager.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema-manager.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/schema-manager.test.ts"],"names":[],"mappings":""}
@@ -1,116 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const vitest_1 = require("vitest");
4
- const manager_js_1 = require("../schema/manager.js");
5
- // ---------------------------------------------------------------------------
6
- // Helpers
7
- // ---------------------------------------------------------------------------
8
- function makeClient(queryResults = {}) {
9
- const query = vitest_1.vi.fn(async (sql) => {
10
- // Return the configured result or a sensible default
11
- for (const [pattern, result] of Object.entries(queryResults)) {
12
- if (sql.includes(pattern)) {
13
- return result;
14
- }
15
- }
16
- return { rows: [], rowCount: 0 };
17
- });
18
- return { query };
19
- }
20
- // ---------------------------------------------------------------------------
21
- // tenantSchemaName
22
- // ---------------------------------------------------------------------------
23
- (0, vitest_1.describe)("tenantSchemaName", () => {
24
- (0, vitest_1.it)("prepends tenant_ to a simple slug", () => {
25
- (0, vitest_1.expect)((0, manager_js_1.tenantSchemaName)("acme")).toBe("tenant_acme");
26
- });
27
- (0, vitest_1.it)("handles slugs with underscores and digits", () => {
28
- (0, vitest_1.expect)((0, manager_js_1.tenantSchemaName)("acme_corp_2024")).toBe("tenant_acme_corp_2024");
29
- });
30
- });
31
- // ---------------------------------------------------------------------------
32
- // createSchema
33
- // ---------------------------------------------------------------------------
34
- (0, vitest_1.describe)("createSchema", () => {
35
- (0, vitest_1.it)("executes CREATE SCHEMA IF NOT EXISTS with the correct name", async () => {
36
- const client = makeClient();
37
- await (0, manager_js_1.createSchema)(client, "acme");
38
- (0, vitest_1.expect)(client.query).toHaveBeenCalledWith("CREATE SCHEMA IF NOT EXISTS tenant_acme");
39
- });
40
- (0, vitest_1.it)("rejects an invalid slug that produces an invalid schema name", async () => {
41
- const client = makeClient();
42
- // Injecting SQL-special characters via an invalid slug
43
- await (0, vitest_1.expect)((0, manager_js_1.createSchema)(client, "bad; DROP TABLE tenants--")).rejects.toThrow("Invalid schema name");
44
- });
45
- });
46
- // ---------------------------------------------------------------------------
47
- // dropSchema
48
- // ---------------------------------------------------------------------------
49
- (0, vitest_1.describe)("dropSchema", () => {
50
- (0, vitest_1.it)("executes DROP SCHEMA IF EXISTS … CASCADE", async () => {
51
- const client = makeClient();
52
- await (0, manager_js_1.dropSchema)(client, "acme");
53
- (0, vitest_1.expect)(client.query).toHaveBeenCalledWith("DROP SCHEMA IF EXISTS tenant_acme CASCADE");
54
- });
55
- });
56
- // ---------------------------------------------------------------------------
57
- // schemaExists
58
- // ---------------------------------------------------------------------------
59
- (0, vitest_1.describe)("schemaExists", () => {
60
- (0, vitest_1.it)("returns true when count > 0", async () => {
61
- const client = makeClient({ pg_namespace: { rows: [{ count: "1" }], rowCount: 1 } });
62
- const result = await (0, manager_js_1.schemaExists)(client, "acme");
63
- (0, vitest_1.expect)(result).toBe(true);
64
- });
65
- (0, vitest_1.it)("returns false when count is 0", async () => {
66
- const client = makeClient({ pg_namespace: { rows: [{ count: "0" }], rowCount: 1 } });
67
- const result = await (0, manager_js_1.schemaExists)(client, "acme");
68
- (0, vitest_1.expect)(result).toBe(false);
69
- });
70
- (0, vitest_1.it)("uses parameterized query with the full schema name", async () => {
71
- const client = makeClient({ pg_namespace: { rows: [{ count: "0" }], rowCount: 1 } });
72
- await (0, manager_js_1.schemaExists)(client, "acme");
73
- (0, vitest_1.expect)(client.query).toHaveBeenCalledWith(vitest_1.expect.stringContaining("pg_namespace"), ["tenant_acme"]);
74
- });
75
- });
76
- // ---------------------------------------------------------------------------
77
- // listTenantSchemas
78
- // ---------------------------------------------------------------------------
79
- (0, vitest_1.describe)("listTenantSchemas", () => {
80
- (0, vitest_1.it)("returns schema names from pg_namespace", async () => {
81
- const client = makeClient({
82
- pg_namespace: {
83
- rows: [{ nspname: "tenant_acme" }, { nspname: "tenant_beta" }],
84
- rowCount: 2,
85
- },
86
- });
87
- const schemas = await (0, manager_js_1.listTenantSchemas)(client);
88
- (0, vitest_1.expect)(schemas).toEqual(["tenant_acme", "tenant_beta"]);
89
- });
90
- (0, vitest_1.it)("returns empty array when no tenant schemas exist", async () => {
91
- const client = makeClient({
92
- pg_namespace: { rows: [], rowCount: 0 },
93
- });
94
- const schemas = await (0, manager_js_1.listTenantSchemas)(client);
95
- (0, vitest_1.expect)(schemas).toEqual([]);
96
- });
97
- });
98
- // ---------------------------------------------------------------------------
99
- // replicateTableToSchema
100
- // ---------------------------------------------------------------------------
101
- (0, vitest_1.describe)("replicateTableToSchema", () => {
102
- (0, vitest_1.it)("executes CREATE TABLE … LIKE public.tableName", async () => {
103
- const client = makeClient();
104
- await (0, manager_js_1.replicateTableToSchema)(client, "orders", "tenant_acme");
105
- (0, vitest_1.expect)(client.query).toHaveBeenCalledWith("CREATE TABLE IF NOT EXISTS tenant_acme.orders (LIKE public.orders INCLUDING ALL)");
106
- });
107
- (0, vitest_1.it)("rejects an invalid table name", async () => {
108
- const client = makeClient();
109
- await (0, vitest_1.expect)((0, manager_js_1.replicateTableToSchema)(client, "orders; DROP TABLE tenants--", "tenant_acme")).rejects.toThrow("Invalid table name");
110
- });
111
- (0, vitest_1.it)("rejects an invalid schema name", async () => {
112
- const client = makeClient();
113
- await (0, vitest_1.expect)((0, manager_js_1.replicateTableToSchema)(client, "orders", "bad schema name")).rejects.toThrow("Invalid schema name");
114
- });
115
- });
116
- //# sourceMappingURL=schema-manager.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema-manager.test.js","sourceRoot":"","sources":["../../src/__tests__/schema-manager.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=schema-session.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema-session.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/schema-session.test.ts"],"names":[],"mappings":""}
@@ -1,23 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const vitest_1 = require("vitest");
4
- const session_js_1 = require("../schema/session.js");
5
- function makeClient() {
6
- const query = vitest_1.vi.fn(async () => ({ rows: [], rowCount: 0 }));
7
- return { query };
8
- }
9
- (0, vitest_1.describe)("setSchemaSearchPath", () => {
10
- (0, vitest_1.it)("sets the search_path for a valid tenant slug", async () => {
11
- const client = makeClient();
12
- await (0, session_js_1.setSchemaSearchPath)(client, "acme_corp_2024");
13
- (0, vitest_1.expect)(client.query).toHaveBeenCalledWith("SET LOCAL search_path TO tenant_acme_corp_2024, public");
14
- });
15
- (0, vitest_1.it)("rejects a slug outside the canonical charset before issuing any query", async () => {
16
- const client = makeClient();
17
- // Anything with characters outside the slug charset must never reach the
18
- // search_path statement (the schema name is interpolated, not bound).
19
- await (0, vitest_1.expect)((0, session_js_1.setSchemaSearchPath)(client, "bad; DROP TABLE tenants--")).rejects.toThrow(/Invalid tenant slug/);
20
- (0, vitest_1.expect)(client.query).not.toHaveBeenCalled();
21
- });
22
- });
23
- //# sourceMappingURL=schema-session.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"schema-session.test.js","sourceRoot":"","sources":["../../src/__tests__/schema-session.test.ts"],"names":[],"mappings":";;AAAA,mCAAkD;AAClD,qDAA2D;AAG3D,SAAS,UAAU;IACjB,MAAM,KAAK,GAAG,WAAE,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7D,OAAO,EAAE,KAAK,EAA8B,CAAC;AAC/C,CAAC;AAED,IAAA,iBAAQ,EAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,IAAA,WAAE,EAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,IAAA,gCAAmB,EAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;QACpD,IAAA,eAAM,EAAC,MAAM,CAAC,KAAK,CAAC,CAAC,oBAAoB,CACvC,wDAAwD,CACzD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,yEAAyE;QACzE,sEAAsE;QACtE,MAAM,IAAA,eAAM,EACV,IAAA,gCAAmB,EAAC,MAAM,EAAE,2BAA2B,CAAC,CACzD,CAAC,OAAO,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC;QACzC,IAAA,eAAM,EAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=sequelize.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sequelize.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/sequelize.test.ts"],"names":[],"mappings":""}
@@ -1,150 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const vitest_1 = require("vitest");
4
- const sequelize_js_1 = require("../adapters/sequelize.js");
5
- const base_adapter_js_1 = require("../base-adapter.js");
6
- // ---------------------------------------------------------------------------
7
- // Mock pg
8
- // ---------------------------------------------------------------------------
9
- class MockPool {
10
- }
11
- vitest_1.vi.mock("pg", () => {
12
- return { default: { Pool: MockPool }, Pool: MockPool };
13
- });
14
- function createMockSequelize() {
15
- const queries = [];
16
- return {
17
- queries,
18
- query: async (sql, options) => {
19
- queries.push({ sql, options });
20
- return [[], 0];
21
- },
22
- transaction: async (fn) => fn({}),
23
- addHook: vitest_1.vi.fn(),
24
- };
25
- }
26
- // ---------------------------------------------------------------------------
27
- // Tests
28
- // ---------------------------------------------------------------------------
29
- (0, vitest_1.describe)("SequelizeAdapter", () => {
30
- let pool;
31
- let adapter;
32
- (0, vitest_1.beforeEach)(() => {
33
- vitest_1.vi.clearAllMocks();
34
- pool = new MockPool();
35
- adapter = new sequelize_js_1.SequelizeAdapter(pool);
36
- });
37
- (0, vitest_1.it)("extends BaseAdapter", () => {
38
- (0, vitest_1.expect)(adapter).toBeInstanceOf(base_adapter_js_1.BaseAdapter);
39
- });
40
- (0, vitest_1.describe)("withTenantScope (method)", () => {
41
- (0, vitest_1.it)("returns a new wrapped object, not the original instance", () => {
42
- const mock = createMockSequelize();
43
- const result = adapter.withTenantScope(mock, () => "tenant-1");
44
- (0, vitest_1.expect)(result).not.toBe(mock);
45
- });
46
- (0, vitest_1.it)("returned object exposes query, transaction, and addHook", () => {
47
- const mock = createMockSequelize();
48
- const result = adapter.withTenantScope(mock, () => "tenant-1");
49
- (0, vitest_1.expect)(typeof result.query).toBe("function");
50
- (0, vitest_1.expect)(typeof result.transaction).toBe("function");
51
- (0, vitest_1.expect)(typeof result.addHook).toBe("function");
52
- });
53
- (0, vitest_1.it)("wrapped query calls transaction() and sets set_config inside it", async () => {
54
- const mock = createMockSequelize();
55
- const transactionSpy = vitest_1.vi.spyOn(mock, "transaction");
56
- const wrapped = adapter.withTenantScope(mock, () => "tenant-abc");
57
- await wrapped.query("SELECT 1");
58
- (0, vitest_1.expect)(transactionSpy).toHaveBeenCalledTimes(1);
59
- (0, vitest_1.expect)(mock.queries).toHaveLength(2);
60
- (0, vitest_1.expect)(mock.queries[0].sql).toContain("set_config");
61
- (0, vitest_1.expect)(mock.queries[0].sql).toContain("app.current_tenant_id");
62
- (0, vitest_1.expect)(mock.queries[1].sql).toBe("SELECT 1");
63
- });
64
- (0, vitest_1.it)("set_config receives tenant ID as bind parameter", async () => {
65
- const mock = createMockSequelize();
66
- const wrapped = adapter.withTenantScope(mock, () => "tenant-xyz");
67
- await wrapped.query("SELECT 1");
68
- (0, vitest_1.expect)(mock.queries[0].options).toMatchObject({ bind: ["tenant-xyz"] });
69
- });
70
- (0, vitest_1.it)("passes transaction handle to both set_config and the actual query", async () => {
71
- const fakeT = { id: "fake-transaction" };
72
- const mock = createMockSequelize();
73
- mock.transaction = async (fn) => fn(fakeT);
74
- const wrapped = adapter.withTenantScope(mock, () => "tenant-1");
75
- await wrapped.query("SELECT 1");
76
- (0, vitest_1.expect)(mock.queries[0].options).toMatchObject({ transaction: fakeT });
77
- (0, vitest_1.expect)(mock.queries[1].options).toMatchObject({ transaction: fakeT });
78
- });
79
- (0, vitest_1.it)("merges caller-supplied options with transaction handle", async () => {
80
- const mock = createMockSequelize();
81
- const wrapped = adapter.withTenantScope(mock, () => "tenant-1");
82
- await wrapped.query("SELECT 1", { type: "SELECT" });
83
- // The actual query (index 1) should carry both caller options and transaction
84
- (0, vitest_1.expect)(mock.queries[1].options).toMatchObject({ type: "SELECT" });
85
- (0, vitest_1.expect)(mock.queries[1].options).toHaveProperty("transaction");
86
- });
87
- (0, vitest_1.it)("reads tenant ID lazily from contextFn on each query call", async () => {
88
- let currentTenant = "tenant-1";
89
- const mock = createMockSequelize();
90
- const wrapped = adapter.withTenantScope(mock, () => currentTenant);
91
- await wrapped.query("SELECT 1");
92
- (0, vitest_1.expect)(mock.queries[0].options).toMatchObject({ bind: ["tenant-1"] });
93
- currentTenant = "tenant-2";
94
- mock.queries.length = 0;
95
- await wrapped.query("SELECT 2");
96
- (0, vitest_1.expect)(mock.queries[0].options).toMatchObject({ bind: ["tenant-2"] });
97
- });
98
- (0, vitest_1.it)("throws when contextFn returns empty string", async () => {
99
- const mock = createMockSequelize();
100
- const wrapped = adapter.withTenantScope(mock, () => "");
101
- await (0, vitest_1.expect)(wrapped.query("SELECT 1")).rejects.toThrow("Tenant context is required for database operations.");
102
- });
103
- (0, vitest_1.it)("propagates errors thrown by set_config", async () => {
104
- const mock = createMockSequelize();
105
- mock.transaction = async (fn) => fn({});
106
- mock.query = vitest_1.vi.fn().mockRejectedValueOnce(new Error("set_config failed"));
107
- const wrapped = adapter.withTenantScope(mock, () => "tenant-1");
108
- await (0, vitest_1.expect)(wrapped.query("SELECT 1")).rejects.toThrow("set_config failed");
109
- });
110
- (0, vitest_1.it)("delegates transaction() to the original instance", async () => {
111
- const mock = createMockSequelize();
112
- const transactionSpy = vitest_1.vi.spyOn(mock, "transaction");
113
- const wrapped = adapter.withTenantScope(mock, () => "tenant-1");
114
- const fn = async (_t) => "result";
115
- await wrapped.transaction(fn);
116
- (0, vitest_1.expect)(transactionSpy).toHaveBeenCalledWith(fn);
117
- });
118
- (0, vitest_1.it)("delegates addHook() to the original instance", () => {
119
- const mock = createMockSequelize();
120
- const wrapped = adapter.withTenantScope(mock, () => "tenant-1");
121
- const hookFn = vitest_1.vi.fn();
122
- wrapped.addHook("beforeFind", hookFn);
123
- (0, vitest_1.expect)(mock.addHook).toHaveBeenCalledWith("beforeFind", hookFn);
124
- });
125
- });
126
- });
127
- (0, vitest_1.describe)("withTenantScope (convenience function)", () => {
128
- (0, vitest_1.it)("returns a new wrapped object, not the original instance", () => {
129
- const mock = createMockSequelize();
130
- const pool = new MockPool();
131
- const result = (0, sequelize_js_1.withTenantScope)(mock, () => "tenant-1", pool);
132
- (0, vitest_1.expect)(result).not.toBe(mock);
133
- });
134
- (0, vitest_1.it)("wrapped query calls transaction() with set_config", async () => {
135
- const mock = createMockSequelize();
136
- const transactionSpy = vitest_1.vi.spyOn(mock, "transaction");
137
- const pool = new MockPool();
138
- const wrapped = (0, sequelize_js_1.withTenantScope)(mock, () => "fn-tenant", pool);
139
- await wrapped.query("SELECT 1");
140
- (0, vitest_1.expect)(transactionSpy).toHaveBeenCalledTimes(1);
141
- (0, vitest_1.expect)(mock.queries[0].options).toMatchObject({ bind: ["fn-tenant"] });
142
- });
143
- (0, vitest_1.it)("throws when contextFn returns empty string", async () => {
144
- const mock = createMockSequelize();
145
- const pool = new MockPool();
146
- const wrapped = (0, sequelize_js_1.withTenantScope)(mock, () => "", pool);
147
- await (0, vitest_1.expect)(wrapped.query("SELECT 1")).rejects.toThrow("Tenant context is required for database operations.");
148
- });
149
- });
150
- //# sourceMappingURL=sequelize.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sequelize.test.js","sourceRoot":"","sources":["../../src/__tests__/sequelize.test.ts"],"names":[],"mappings":"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"}