@nest-boot/row-level-security 7.3.1 → 8.0.0-beta.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 (103) hide show
  1. package/dist/decorators/policy.decorator.d.ts +4 -4
  2. package/dist/decorators/policy.decorator.js +25 -31
  3. package/dist/decorators/policy.decorator.js.map +1 -1
  4. package/dist/enums/policy-command.enum.js +2 -5
  5. package/dist/enums/policy-command.enum.js.map +1 -1
  6. package/dist/enums/policy-mode.enum.js +2 -5
  7. package/dist/enums/policy-mode.enum.js.map +1 -1
  8. package/dist/enums/row-level-security-role.enum.js +2 -5
  9. package/dist/enums/row-level-security-role.enum.js.map +1 -1
  10. package/dist/index.d.ts +11 -11
  11. package/dist/index.js +11 -27
  12. package/dist/index.js.map +1 -1
  13. package/dist/interfaces/index.d.ts +4 -4
  14. package/dist/interfaces/index.js +3 -19
  15. package/dist/interfaces/index.js.map +1 -1
  16. package/dist/interfaces/policy-metadata.interface.d.ts +2 -2
  17. package/dist/interfaces/policy-metadata.interface.js +1 -2
  18. package/dist/interfaces/policy-options.interface.d.ts +2 -2
  19. package/dist/interfaces/policy-options.interface.js +1 -2
  20. package/dist/interfaces/policy-sql-options.interface.d.ts +2 -2
  21. package/dist/interfaces/policy-sql-options.interface.js +1 -2
  22. package/dist/interfaces/row-level-security-migration-generator.interface.d.ts +1 -1
  23. package/dist/interfaces/row-level-security-migration-generator.interface.js +1 -2
  24. package/dist/row-level-security-driver.d.ts +4 -3
  25. package/dist/row-level-security-driver.js +8 -19
  26. package/dist/row-level-security-driver.js.map +1 -1
  27. package/dist/row-level-security-migration-generator.d.ts +1 -1
  28. package/dist/row-level-security-migration-generator.js +40 -41
  29. package/dist/row-level-security-migration-generator.js.map +1 -1
  30. package/dist/row-level-security-migration.d.ts +1 -1
  31. package/dist/row-level-security-migration.js +9 -13
  32. package/dist/row-level-security-migration.js.map +1 -1
  33. package/dist/row-level-security-migrator.d.ts +2 -2
  34. package/dist/row-level-security-migrator.js +9 -13
  35. package/dist/row-level-security-migrator.js.map +1 -1
  36. package/dist/row-level-security.d.ts +1 -1
  37. package/dist/row-level-security.js +19 -23
  38. package/dist/row-level-security.js.map +1 -1
  39. package/dist/utils/assert-identifier.js +1 -4
  40. package/dist/utils/assert-identifier.js.map +1 -1
  41. package/dist/utils/assert-snake-case.js +1 -4
  42. package/dist/utils/assert-snake-case.js.map +1 -1
  43. package/dist/utils/create-policy-bootstrap-sql-statements.js +1 -4
  44. package/dist/utils/create-policy-bootstrap-sql-statements.js.map +1 -1
  45. package/dist/utils/create-policy-down-sql.d.ts +1 -1
  46. package/dist/utils/create-policy-down-sql.js +5 -8
  47. package/dist/utils/create-policy-down-sql.js.map +1 -1
  48. package/dist/utils/create-policy-privilege-down-sql-statements.d.ts +1 -1
  49. package/dist/utils/create-policy-privilege-down-sql-statements.js +19 -22
  50. package/dist/utils/create-policy-privilege-down-sql-statements.js.map +1 -1
  51. package/dist/utils/create-policy-role-sql-statements.js +8 -13
  52. package/dist/utils/create-policy-role-sql-statements.js.map +1 -1
  53. package/dist/utils/create-policy-up-sql-statements.d.ts +1 -1
  54. package/dist/utils/create-policy-up-sql-statements.js +26 -29
  55. package/dist/utils/create-policy-up-sql-statements.js.map +1 -1
  56. package/dist/utils/create-row-level-security-transaction-setup.js +15 -18
  57. package/dist/utils/create-row-level-security-transaction-setup.js.map +1 -1
  58. package/dist/utils/escape-sql-literal.js +1 -4
  59. package/dist/utils/escape-sql-literal.js.map +1 -1
  60. package/dist/utils/index.d.ts +12 -12
  61. package/dist/utils/index.js +11 -27
  62. package/dist/utils/index.js.map +1 -1
  63. package/dist/utils/is-postgres-keyword-requiring-quote.js +1 -4
  64. package/dist/utils/is-postgres-keyword-requiring-quote.js.map +1 -1
  65. package/dist/utils/normalize-postgres-type-alias.util.js +1 -4
  66. package/dist/utils/normalize-postgres-type-alias.util.js.map +1 -1
  67. package/dist/utils/quote-identifier.js +3 -6
  68. package/dist/utils/quote-identifier.js.map +1 -1
  69. package/dist/utils/quote-qualified-identifier.js +3 -6
  70. package/dist/utils/quote-qualified-identifier.js.map +1 -1
  71. package/dist/utils/row-level-security-context-builder.d.ts +1 -1
  72. package/dist/utils/row-level-security-context-builder.js +7 -13
  73. package/dist/utils/row-level-security-context-builder.js.map +1 -1
  74. package/dist/utils/row-level-security-context-builder.types.js +1 -2
  75. package/package.json +31 -31
  76. package/dist/decorators/policy.decorator.spec.d.ts +0 -1
  77. package/dist/decorators/policy.decorator.spec.js +0 -550
  78. package/dist/decorators/policy.decorator.spec.js.map +0 -1
  79. package/dist/index.spec.d.ts +0 -1
  80. package/dist/index.spec.js +0 -64
  81. package/dist/index.spec.js.map +0 -1
  82. package/dist/row-level-security-driver.spec.d.ts +0 -1
  83. package/dist/row-level-security-driver.spec.js +0 -267
  84. package/dist/row-level-security-driver.spec.js.map +0 -1
  85. package/dist/row-level-security-migration-generator.spec.d.ts +0 -1
  86. package/dist/row-level-security-migration-generator.spec.js +0 -1135
  87. package/dist/row-level-security-migration-generator.spec.js.map +0 -1
  88. package/dist/row-level-security-migration.spec.d.ts +0 -1
  89. package/dist/row-level-security-migration.spec.js +0 -32
  90. package/dist/row-level-security-migration.spec.js.map +0 -1
  91. package/dist/row-level-security.spec.d.ts +0 -1
  92. package/dist/row-level-security.spec.js +0 -52
  93. package/dist/row-level-security.spec.js.map +0 -1
  94. package/dist/tsconfig.build.tsbuildinfo +0 -1
  95. package/dist/utils/normalize-postgres-type-alias.spec.d.ts +0 -1
  96. package/dist/utils/normalize-postgres-type-alias.spec.js +0 -28
  97. package/dist/utils/normalize-postgres-type-alias.spec.js.map +0 -1
  98. package/dist/utils/policy-migration-sql.spec.d.ts +0 -1
  99. package/dist/utils/policy-migration-sql.spec.js +0 -273
  100. package/dist/utils/policy-migration-sql.spec.js.map +0 -1
  101. package/dist/utils/row-level-security-context-builder.spec.d.ts +0 -1
  102. package/dist/utils/row-level-security-context-builder.spec.js +0 -40
  103. package/dist/utils/row-level-security-context-builder.spec.js.map +0 -1
@@ -1 +0,0 @@
1
- export {};
@@ -1,28 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const normalize_postgres_type_alias_util_1 = require("./normalize-postgres-type-alias.util");
4
- describe("normalizePostgresTypeAlias", () => {
5
- it.each([
6
- ["bool", "boolean"],
7
- ["bpchar", "character"],
8
- ["char", "character"],
9
- ["decimal", "numeric"],
10
- ["float4", "real"],
11
- ["float8", "double precision"],
12
- ["int", "integer"],
13
- ["int4", "integer"],
14
- ["int2", "smallint"],
15
- ["int8", "bigint"],
16
- ["timetz", "time with time zone"],
17
- ["timestamptz", "timestamp with time zone"],
18
- ["varbit", "bit varying"],
19
- ["varchar", "character varying"],
20
- ["varchar(255)", "character varying"],
21
- ])("normalizes %s to %s", (type, normalizedType) => {
22
- expect((0, normalize_postgres_type_alias_util_1.normalizePostgresTypeAlias)(type)).toBe(normalizedType);
23
- });
24
- it("preserves canonical PostgreSQL types", () => {
25
- expect((0, normalize_postgres_type_alias_util_1.normalizePostgresTypeAlias)("uuid")).toBe("uuid");
26
- });
27
- });
28
- //# sourceMappingURL=normalize-postgres-type-alias.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"normalize-postgres-type-alias.spec.js","sourceRoot":"","sources":["../../src/utils/normalize-postgres-type-alias.spec.ts"],"names":[],"mappings":";;AAAA,6FAAkF;AAElF,QAAQ,CAAC,4BAA4B,EAAE,GAAG,EAAE;IAC1C,EAAE,CAAC,IAAI,CAAC;QACN,CAAC,MAAM,EAAE,SAAS,CAAC;QACnB,CAAC,QAAQ,EAAE,WAAW,CAAC;QACvB,CAAC,MAAM,EAAE,WAAW,CAAC;QACrB,CAAC,SAAS,EAAE,SAAS,CAAC;QACtB,CAAC,QAAQ,EAAE,MAAM,CAAC;QAClB,CAAC,QAAQ,EAAE,kBAAkB,CAAC;QAC9B,CAAC,KAAK,EAAE,SAAS,CAAC;QAClB,CAAC,MAAM,EAAE,SAAS,CAAC;QACnB,CAAC,MAAM,EAAE,UAAU,CAAC;QACpB,CAAC,MAAM,EAAE,QAAQ,CAAC;QAClB,CAAC,QAAQ,EAAE,qBAAqB,CAAC;QACjC,CAAC,aAAa,EAAE,0BAA0B,CAAC;QAC3C,CAAC,QAAQ,EAAE,aAAa,CAAC;QACzB,CAAC,SAAS,EAAE,mBAAmB,CAAC;QAChC,CAAC,cAAc,EAAE,mBAAmB,CAAC;KACtC,CAAC,CAAC,qBAAqB,EAAE,CAAC,IAAI,EAAE,cAAc,EAAE,EAAE;QACjD,MAAM,CAAC,IAAA,+DAA0B,EAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,CAAC,IAAA,+DAA0B,EAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1 +0,0 @@
1
- export {};
@@ -1,273 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const policy_command_enum_1 = require("../enums/policy-command.enum");
4
- const policy_mode_enum_1 = require("../enums/policy-mode.enum");
5
- const create_policy_bootstrap_sql_statements_1 = require("./create-policy-bootstrap-sql-statements");
6
- const create_policy_down_sql_1 = require("./create-policy-down-sql");
7
- const create_policy_privilege_down_sql_statements_1 = require("./create-policy-privilege-down-sql-statements");
8
- const create_policy_role_sql_statements_1 = require("./create-policy-role-sql-statements");
9
- const create_policy_up_sql_statements_1 = require("./create-policy-up-sql-statements");
10
- describe("policy migration SQL", () => {
11
- it("generates row level security bootstrap SQL", () => {
12
- const statements = (0, create_policy_bootstrap_sql_statements_1.createPolicyBootstrapSqlStatements)();
13
- expect(statements).toEqual([]);
14
- expect(statements.join("\n")).not.toContain("grant all on all tables");
15
- expect(statements.join("\n")).not.toContain("get_context");
16
- });
17
- it("does not generate role bootstrap SQL for anonymous and custom policy roles", () => {
18
- const statements = (0, create_policy_role_sql_statements_1.createPolicyRoleUpSqlStatements)([
19
- "authenticated",
20
- "workspace_admin",
21
- ]);
22
- expect(statements).toEqual([]);
23
- expect(statements.join("\n")).not.toContain("create role");
24
- expect(statements.join("\n")).not.toContain("current_user");
25
- expect(statements.join("\n")).not.toContain("grant usage on schema app");
26
- });
27
- it("does not generate role down SQL", () => {
28
- const statements = (0, create_policy_role_sql_statements_1.createPolicyRoleDownSqlStatements)(["workspace_admin"]);
29
- expect(statements).toEqual([]);
30
- expect((0, create_policy_role_sql_statements_1.createPolicyRoleDownSqlStatements)()).toEqual([]);
31
- expect(statements.join("\n")).not.toContain("drop role");
32
- expect(statements.join("\n")).not.toContain("current_user");
33
- expect(statements.join("\n")).not.toContain("revoke usage on schema app");
34
- });
35
- it("generates role down SQL for an explicit anonymous role", () => {
36
- const statements = (0, create_policy_role_sql_statements_1.createPolicyRoleDownSqlStatements)(["anonymous"]);
37
- expect(statements).toEqual([]);
38
- });
39
- it("normalizes policy role names with anonymous first and public skipped", () => {
40
- expect((0, create_policy_role_sql_statements_1.getPolicyRoleNames)()).toEqual(["anonymous"]);
41
- expect((0, create_policy_role_sql_statements_1.getPolicyRoleNames)([
42
- "workspace_admin",
43
- "public",
44
- "authenticated",
45
- "workspace_admin",
46
- ])).toEqual(["anonymous", "authenticated", "workspace_admin"]);
47
- });
48
- it("generates policy up SQL", () => {
49
- const statements = (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)({
50
- schemaName: "public",
51
- tableName: "workspace_member",
52
- policyName: "workspace_member_user_select_policy",
53
- command: policy_command_enum_1.PolicyCommand.SELECT,
54
- using: `((select current_setting('app.user_id', true)::bigint) = "user_id")`,
55
- });
56
- expect(statements).toEqual([
57
- 'alter table "public"."workspace_member" enable row level security;',
58
- 'drop policy if exists workspace_member_user_select_policy on "public"."workspace_member";',
59
- 'create policy workspace_member_user_select_policy on "public"."workspace_member" as permissive for select using ((select current_setting(\'app.user_id\', true)::bigint) = "user_id");',
60
- ]);
61
- });
62
- it("generates policy SQL for explicit roles", () => {
63
- const statements = (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)({
64
- schemaName: "public",
65
- tableName: "workspace_member",
66
- policyName: "workspace_member_user_select_policy",
67
- command: policy_command_enum_1.PolicyCommand.SELECT,
68
- using: `((select current_setting('app.user_id', true)::bigint) = "user_id")`,
69
- roles: ["authenticated", "anonymous"],
70
- });
71
- expect(statements[2]).toBe('drop policy if exists workspace_member_user_select_policy on "public"."workspace_member";');
72
- });
73
- it("wraps raw using predicates in parentheses", () => {
74
- const statements = (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)({
75
- schemaName: "public",
76
- tableName: "user",
77
- policyName: "user_select_authenticated_policy",
78
- command: policy_command_enum_1.PolicyCommand.SELECT,
79
- using: "true",
80
- roles: ["authenticated"],
81
- });
82
- expect(statements).toContain('create policy user_select_authenticated_policy on "public"."user" as permissive for select to authenticated using (true);');
83
- });
84
- it("generates table grants for explicit policy roles", () => {
85
- const statements = (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)({
86
- schemaName: "public",
87
- tableName: "workspace_member",
88
- policyName: "workspace_member_user_select_policy",
89
- command: policy_command_enum_1.PolicyCommand.SELECT,
90
- using: `((select current_setting('app.user_id', true)::bigint) = "user_id")`,
91
- roles: ["authenticated", "anonymous"],
92
- });
93
- expect(statements).toEqual([
94
- 'alter table "public"."workspace_member" enable row level security;',
95
- 'grant select on table "public"."workspace_member" to authenticated, anonymous;',
96
- 'drop policy if exists workspace_member_user_select_policy on "public"."workspace_member";',
97
- 'create policy workspace_member_user_select_policy on "public"."workspace_member" as permissive for select to authenticated, anonymous using ((select current_setting(\'app.user_id\', true)::bigint) = "user_id");',
98
- ]);
99
- });
100
- it("generates sequence grants for explicit insert policy roles", () => {
101
- const statements = (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)({
102
- schemaName: "public",
103
- tableName: "workspace_member",
104
- policyName: "workspace_member_insert_policy",
105
- command: policy_command_enum_1.PolicyCommand.INSERT,
106
- withCheck: "true",
107
- roles: ["authenticated"],
108
- });
109
- expect(statements).toContain('grant insert on table "public"."workspace_member" to authenticated;');
110
- expect(statements).toEqual(expect.arrayContaining([
111
- expect.stringContaining("pg_get_serial_sequence"),
112
- expect.stringContaining("grant usage, select on sequence %s to authenticated"),
113
- ]));
114
- });
115
- it.each([
116
- [policy_command_enum_1.PolicyCommand.SELECT, "revoke select on table"],
117
- [policy_command_enum_1.PolicyCommand.INSERT, "revoke insert on table"],
118
- [policy_command_enum_1.PolicyCommand.UPDATE, "revoke select, update on table"],
119
- [policy_command_enum_1.PolicyCommand.DELETE, "revoke select, delete on table"],
120
- [policy_command_enum_1.PolicyCommand.ALL, "revoke select, insert, update, delete on table"],
121
- ])("generates policy privilege revoke SQL for %s", (command, expected) => {
122
- const statements = (0, create_policy_privilege_down_sql_statements_1.createPolicyPrivilegeDownSqlStatements)({
123
- schemaName: "public",
124
- tableName: "workspace_member",
125
- policyName: "workspace_member_policy",
126
- command,
127
- roles: ["authenticated"],
128
- });
129
- expect(statements[0]).toContain(expected);
130
- if (command === policy_command_enum_1.PolicyCommand.INSERT || command === policy_command_enum_1.PolicyCommand.ALL) {
131
- expect(statements).toEqual(expect.arrayContaining([
132
- expect.stringContaining("revoke usage, select on sequence %s from authenticated"),
133
- ]));
134
- }
135
- else {
136
- expect(statements).toHaveLength(1);
137
- }
138
- });
139
- it("does not generate policy privilege revoke SQL without explicit roles", () => {
140
- expect((0, create_policy_privilege_down_sql_statements_1.createPolicyPrivilegeDownSqlStatements)({
141
- schemaName: "public",
142
- tableName: "workspace_member",
143
- policyName: "workspace_member_policy",
144
- })).toEqual([]);
145
- });
146
- it("defaults policy privilege revoke SQL to all command privileges", () => {
147
- expect((0, create_policy_privilege_down_sql_statements_1.createPolicyPrivilegeDownSqlStatements)({
148
- schemaName: "public",
149
- tableName: "workspace_member",
150
- policyName: "workspace_member_policy",
151
- roles: ["authenticated"],
152
- })).toEqual(expect.arrayContaining([
153
- expect.stringContaining('revoke select, insert, update, delete on table "public"."workspace_member" from authenticated;'),
154
- expect.stringContaining("revoke usage, select on sequence %s from authenticated"),
155
- ]));
156
- });
157
- it("keeps policy privilege grants required by preserved policies", () => {
158
- const statements = (0, create_policy_privilege_down_sql_statements_1.createPolicyPrivilegeDownSqlStatements)({
159
- schemaName: "public",
160
- tableName: "workspace_member",
161
- policyName: "workspace_member_all_policy",
162
- command: policy_command_enum_1.PolicyCommand.ALL,
163
- roles: ["authenticated", "workspace_admin"],
164
- }, [
165
- {
166
- schemaName: "public",
167
- tableName: "workspace_member",
168
- policyName: "workspace_member_insert_policy",
169
- command: policy_command_enum_1.PolicyCommand.INSERT,
170
- withCheck: "true",
171
- roles: ["authenticated"],
172
- },
173
- ]);
174
- expect(statements).toEqual(expect.arrayContaining([
175
- 'revoke select, update, delete on table "public"."workspace_member" from authenticated;',
176
- 'revoke select, insert, update, delete on table "public"."workspace_member" from workspace_admin;',
177
- ]));
178
- expect(statements).toEqual(expect.arrayContaining([
179
- expect.stringContaining("revoke usage, select on sequence %s from workspace_admin"),
180
- ]));
181
- expect(statements).toEqual(expect.not.arrayContaining([
182
- expect.stringContaining("revoke usage, select on sequence %s from authenticated"),
183
- ]));
184
- });
185
- it("generates restrictive policy SQL", () => {
186
- const statements = (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)({
187
- schemaName: "public",
188
- tableName: "workspace_member",
189
- policyName: "tenant_required_policy",
190
- mode: policy_mode_enum_1.PolicyMode.RESTRICTIVE,
191
- using: `((select current_setting('app.tenant_id', true)::bigint) is not null)`,
192
- });
193
- expect(statements[2]).toBe('create policy tenant_required_policy on "public"."workspace_member" as restrictive for all using ((select current_setting(\'app.tenant_id\', true)::bigint) is not null);');
194
- });
195
- it("generates insert policy SQL with only a with check predicate", () => {
196
- const statements = (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)({
197
- schemaName: "public",
198
- tableName: "workspace_member",
199
- policyName: "workspace_member_insert_policy",
200
- command: policy_command_enum_1.PolicyCommand.INSERT,
201
- withCheck: ` true `,
202
- });
203
- expect(statements[2]).toBe('create policy workspace_member_insert_policy on "public"."workspace_member" as permissive for insert with check (true);');
204
- });
205
- it.each([
206
- [
207
- "select without using",
208
- {
209
- schemaName: "public",
210
- tableName: "workspace_member",
211
- policyName: "workspace_member_select_policy",
212
- command: policy_command_enum_1.PolicyCommand.SELECT,
213
- },
214
- "Policy using expression is required",
215
- ],
216
- [
217
- "delete with withCheck",
218
- {
219
- schemaName: "public",
220
- tableName: "workspace_member",
221
- policyName: "workspace_member_delete_policy",
222
- command: policy_command_enum_1.PolicyCommand.DELETE,
223
- using: "true",
224
- withCheck: "true",
225
- },
226
- "Policy withCheck is not allowed for delete",
227
- ],
228
- [
229
- "insert with using",
230
- {
231
- schemaName: "public",
232
- tableName: "workspace_member",
233
- policyName: "workspace_member_insert_policy",
234
- command: policy_command_enum_1.PolicyCommand.INSERT,
235
- using: "true",
236
- withCheck: "true",
237
- },
238
- "Policy using is not allowed for insert",
239
- ],
240
- [
241
- "insert without withCheck",
242
- {
243
- schemaName: "public",
244
- tableName: "workspace_member",
245
- policyName: "workspace_member_insert_policy",
246
- command: policy_command_enum_1.PolicyCommand.INSERT,
247
- },
248
- "Policy withCheck expression is required",
249
- ],
250
- [
251
- "all without predicates",
252
- {
253
- schemaName: "public",
254
- tableName: "workspace_member",
255
- policyName: "workspace_member_all_policy",
256
- },
257
- "Policy using or withCheck expression is required",
258
- ],
259
- ])("rejects %s", (_name, options, message) => {
260
- expect(() => (0, create_policy_up_sql_statements_1.createPolicyUpSqlStatements)(options)).toThrow(message);
261
- });
262
- it("generates guarded policy down SQL", () => {
263
- const sql = (0, create_policy_down_sql_1.createPolicyDownSql)({
264
- schemaName: "public",
265
- tableName: "workspace_member",
266
- policyName: "workspace_member_user_select_policy",
267
- });
268
- expect(sql).toContain('to_regclass(\'"public"."workspace_member"\')');
269
- expect(sql).toContain('drop policy if exists workspace_member_user_select_policy on "public"."workspace_member"');
270
- expect(sql).toContain("disable row level security");
271
- });
272
- });
273
- //# sourceMappingURL=policy-migration-sql.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"policy-migration-sql.spec.js","sourceRoot":"","sources":["../../src/utils/policy-migration-sql.spec.ts"],"names":[],"mappings":"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"}
@@ -1,40 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const row_level_security_context_builder_1 = require("./row-level-security-context-builder");
4
- describe("RowLevelSecurityContextBuilder", () => {
5
- it("generates transaction-local tenant context SQL", () => {
6
- const builder = new row_level_security_context_builder_1.RowLevelSecurityContextBuilder();
7
- builder.set("request_id", "1");
8
- builder.set("tenant_id", "42");
9
- expect(builder.entries()).toEqual([
10
- ["request_id", "1"],
11
- ["tenant_id", "42"],
12
- ]);
13
- expect(builder.toSQL()).toBe("SELECT set_config('app.request_id', '1', true),set_config('app.tenant_id', '42', true);");
14
- });
15
- it("ignores null and undefined values", () => {
16
- const builder = new row_level_security_context_builder_1.RowLevelSecurityContextBuilder();
17
- builder.set("request_id", undefined);
18
- builder.set("tenant_id", null);
19
- builder.set("is_enabled", false);
20
- expect(builder.entries()).toEqual([["is_enabled", "false"]]);
21
- expect(builder.toSQL()).toBe("SELECT set_config('app.is_enabled', 'false', true);");
22
- });
23
- it("renders no-op SQL when every value is nullish", () => {
24
- const builder = new row_level_security_context_builder_1.RowLevelSecurityContextBuilder();
25
- builder.set("request_id", undefined);
26
- builder.set("tenant_id", null);
27
- expect(builder.entries()).toEqual([]);
28
- expect(builder.toSQL()).toBe("SELECT 1;");
29
- });
30
- it("escapes string values for SQL literals", () => {
31
- const builder = new row_level_security_context_builder_1.RowLevelSecurityContextBuilder();
32
- builder.set("user_name", "O'Connor");
33
- expect(builder.toSQL()).toBe("SELECT set_config('app.user_name', 'O''Connor', true);");
34
- });
35
- it("rejects non snake_case context keys", () => {
36
- const builder = new row_level_security_context_builder_1.RowLevelSecurityContextBuilder();
37
- expect(() => builder.set("userId", "1")).toThrow("Row level security context key must be snake_case");
38
- });
39
- });
40
- //# sourceMappingURL=row-level-security-context-builder.spec.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"row-level-security-context-builder.spec.js","sourceRoot":"","sources":["../../src/utils/row-level-security-context-builder.spec.ts"],"names":[],"mappings":";;AAAA,6FAAsF;AAEtF,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,OAAO,GAAG,IAAI,mEAA8B,EAAE,CAAC;QAErD,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAE/B,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC;YAChC,CAAC,YAAY,EAAE,GAAG,CAAC;YACnB,CAAC,WAAW,EAAE,IAAI,CAAC;SACpB,CAAC,CAAC;QACH,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAC1B,yFAAyF,CAC1F,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,OAAO,GAAG,IAAI,mEAA8B,EAAE,CAAC;QAErD,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QAEjC,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAC7D,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAC1B,qDAAqD,CACtD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,OAAO,GAAG,IAAI,mEAA8B,EAAE,CAAC;QAErD,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAE/B,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,OAAO,GAAG,IAAI,mEAA8B,EAAE,CAAC;QAErD,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QAErC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAC1B,wDAAwD,CACzD,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;QAC7C,MAAM,OAAO,GAAG,IAAI,mEAA8B,EAAE,CAAC;QAErD,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,QAAiB,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CACvD,mDAAmD,CACpD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}