@anthonyalayo/drizzle-kit 1.0.1

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 (161) hide show
  1. package/.gitignore +25 -0
  2. package/README.md +79 -0
  3. package/build.dev.ts +51 -0
  4. package/build.ts +112 -0
  5. package/imports-checker/analyze.ts +78 -0
  6. package/imports-checker/checker.ts +296 -0
  7. package/imports-checker/grammar/grammar.ohm +121 -0
  8. package/imports-checker/grammar/grammar.ohm-bundle.d.ts +164 -0
  9. package/imports-checker/grammar/grammar.ohm-bundle.js +753 -0
  10. package/imports-checker/index.ts +48 -0
  11. package/package.json +142 -0
  12. package/patches/difflib@0.2.4.patch +31 -0
  13. package/src/@types/utils.ts +58 -0
  14. package/src/api.ts +504 -0
  15. package/src/cli/commands/_es5.ts +2 -0
  16. package/src/cli/commands/check.ts +52 -0
  17. package/src/cli/commands/drop.ts +60 -0
  18. package/src/cli/commands/introspect.ts +772 -0
  19. package/src/cli/commands/libSqlPushUtils.ts +355 -0
  20. package/src/cli/commands/migrate.ts +1526 -0
  21. package/src/cli/commands/mysqlIntrospect.ts +53 -0
  22. package/src/cli/commands/mysqlPushUtils.ts +352 -0
  23. package/src/cli/commands/mysqlUp.ts +102 -0
  24. package/src/cli/commands/pgIntrospect.ts +55 -0
  25. package/src/cli/commands/pgPushUtils.ts +269 -0
  26. package/src/cli/commands/pgUp.ts +217 -0
  27. package/src/cli/commands/push.ts +637 -0
  28. package/src/cli/commands/singlestoreIntrospect.ts +53 -0
  29. package/src/cli/commands/singlestorePushUtils.ts +456 -0
  30. package/src/cli/commands/singlestoreUp.ts +1 -0
  31. package/src/cli/commands/sqliteIntrospect.ts +96 -0
  32. package/src/cli/commands/sqlitePushUtils.ts +322 -0
  33. package/src/cli/commands/sqliteUp.ts +52 -0
  34. package/src/cli/commands/utils.ts +858 -0
  35. package/src/cli/connections.ts +914 -0
  36. package/src/cli/index.ts +48 -0
  37. package/src/cli/schema.ts +794 -0
  38. package/src/cli/selector-ui.ts +38 -0
  39. package/src/cli/utils.ts +112 -0
  40. package/src/cli/validations/cli.ts +79 -0
  41. package/src/cli/validations/common.ts +193 -0
  42. package/src/cli/validations/libsql.ts +27 -0
  43. package/src/cli/validations/mysql.ts +61 -0
  44. package/src/cli/validations/outputs.ts +91 -0
  45. package/src/cli/validations/postgres.ts +83 -0
  46. package/src/cli/validations/singlestore.ts +61 -0
  47. package/src/cli/validations/sqlite.ts +104 -0
  48. package/src/cli/validations/studio.ts +24 -0
  49. package/src/cli/views.ts +658 -0
  50. package/src/extensions/getTablesFilterByExtensions.ts +16 -0
  51. package/src/extensions/vector.ts +10 -0
  52. package/src/global.ts +61 -0
  53. package/src/index.ts +326 -0
  54. package/src/introspect-mysql.ts +1030 -0
  55. package/src/introspect-pg.ts +1435 -0
  56. package/src/introspect-singlestore.ts +913 -0
  57. package/src/introspect-sqlite.ts +533 -0
  58. package/src/jsonDiffer.js +882 -0
  59. package/src/jsonStatements.ts +3590 -0
  60. package/src/loader.mjs +57 -0
  61. package/src/migrationPreparator.ts +217 -0
  62. package/src/schemaValidator.ts +23 -0
  63. package/src/serializer/index.ts +142 -0
  64. package/src/serializer/mysqlImports.ts +38 -0
  65. package/src/serializer/mysqlSchema.ts +423 -0
  66. package/src/serializer/mysqlSerializer.ts +999 -0
  67. package/src/serializer/pgImports.ts +106 -0
  68. package/src/serializer/pgSchema.ts +937 -0
  69. package/src/serializer/pgSerializer.ts +2223 -0
  70. package/src/serializer/singlestoreImports.ts +38 -0
  71. package/src/serializer/singlestoreSchema.ts +257 -0
  72. package/src/serializer/singlestoreSerializer.ts +767 -0
  73. package/src/serializer/sqliteImports.ts +41 -0
  74. package/src/serializer/sqliteSchema.ts +352 -0
  75. package/src/serializer/sqliteSerializer.ts +931 -0
  76. package/src/serializer/studio.ts +694 -0
  77. package/src/serializer/utils.ts +45 -0
  78. package/src/simulator.ts +157 -0
  79. package/src/snapshotsDiffer.ts +4398 -0
  80. package/src/sqlgenerator.ts +4212 -0
  81. package/src/statementCombiner.ts +597 -0
  82. package/src/utils/certs.ts +44 -0
  83. package/src/utils/words.ts +1333 -0
  84. package/src/utils.ts +370 -0
  85. package/tests/bin.test.ts +58 -0
  86. package/tests/cli/d1http.config.ts +12 -0
  87. package/tests/cli/drizzle.config.ts +9 -0
  88. package/tests/cli/durable-sqlite.config.ts +7 -0
  89. package/tests/cli/expo.config.ts +7 -0
  90. package/tests/cli/postgres.config.ts +13 -0
  91. package/tests/cli/postgres2.config.ts +17 -0
  92. package/tests/cli/schema.ts +1 -0
  93. package/tests/cli/turso.config.ts +10 -0
  94. package/tests/cli-export.test.ts +79 -0
  95. package/tests/cli-generate.test.ts +259 -0
  96. package/tests/cli-migrate.test.ts +103 -0
  97. package/tests/cli-push.test.ts +126 -0
  98. package/tests/common.ts +15 -0
  99. package/tests/indexes/common.ts +21 -0
  100. package/tests/indexes/pg.test.ts +245 -0
  101. package/tests/introspect/libsql.test.ts +35 -0
  102. package/tests/introspect/mysql.test.ts +319 -0
  103. package/tests/introspect/pg.test.ts +894 -0
  104. package/tests/introspect/singlestore.test.ts +275 -0
  105. package/tests/introspect/sqlite.test.ts +122 -0
  106. package/tests/libsql-checks.test.ts +308 -0
  107. package/tests/libsql-statements.test.ts +989 -0
  108. package/tests/libsql-views.test.ts +218 -0
  109. package/tests/migrate/libsq-schema.ts +6 -0
  110. package/tests/migrate/libsql-migrate.test.ts +58 -0
  111. package/tests/migrate/migrations/0000_little_blizzard.sql +4 -0
  112. package/tests/migrate/migrations/0001_nebulous_storm.sql +10 -0
  113. package/tests/migrate/migrations/meta/0000_snapshot.json +40 -0
  114. package/tests/migrate/migrations/meta/0001_snapshot.json +40 -0
  115. package/tests/migrate/migrations/meta/_journal.json +20 -0
  116. package/tests/mysql-checks.test.ts +291 -0
  117. package/tests/mysql-generated.test.ts +1290 -0
  118. package/tests/mysql-schemas.test.ts +156 -0
  119. package/tests/mysql-views.test.ts +553 -0
  120. package/tests/mysql.test.ts +863 -0
  121. package/tests/pg-array.test.ts +368 -0
  122. package/tests/pg-checks.test.ts +329 -0
  123. package/tests/pg-columns.test.ts +484 -0
  124. package/tests/pg-domains.test.ts +306 -0
  125. package/tests/pg-enums.test.ts +751 -0
  126. package/tests/pg-generated.test.ts +529 -0
  127. package/tests/pg-identity.test.ts +447 -0
  128. package/tests/pg-schemas.test.ts +105 -0
  129. package/tests/pg-sequences.test.ts +298 -0
  130. package/tests/pg-tables.test.ts +1021 -0
  131. package/tests/pg-views.test.ts +1929 -0
  132. package/tests/push/common.ts +58 -0
  133. package/tests/push/libsql.test.ts +1400 -0
  134. package/tests/push/mysql-push.test.ts +345 -0
  135. package/tests/push/mysql.test.ts +788 -0
  136. package/tests/push/pg.test.ts +4341 -0
  137. package/tests/push/singlestore-push.test.ts +894 -0
  138. package/tests/push/singlestore.test.ts +444 -0
  139. package/tests/push/sqlite.test.ts +1613 -0
  140. package/tests/rls/pg-policy.test.ts +1656 -0
  141. package/tests/rls/pg-role.test.ts +234 -0
  142. package/tests/schemaDiffer.ts +2852 -0
  143. package/tests/singlestore-generated.test.ts +1290 -0
  144. package/tests/singlestore-schemas.test.ts +155 -0
  145. package/tests/singlestore.test.ts +978 -0
  146. package/tests/sqlite-checks.test.ts +308 -0
  147. package/tests/sqlite-columns.test.ts +1049 -0
  148. package/tests/sqlite-generated.test.ts +1726 -0
  149. package/tests/sqlite-tables.test.ts +637 -0
  150. package/tests/sqlite-views.test.ts +218 -0
  151. package/tests/statements-combiner/libsql-statements-combiner.test.ts +1812 -0
  152. package/tests/statements-combiner/singlestore-statements-combiner.test.ts +882 -0
  153. package/tests/statements-combiner/sqlite-statements-combiner.test.ts +1211 -0
  154. package/tests/test/sqlite.test.ts +39 -0
  155. package/tests/testsinglestore.ts +29 -0
  156. package/tests/validations.test.ts +869 -0
  157. package/tests/wrap-param.test.ts +16 -0
  158. package/tsconfig.build.json +4 -0
  159. package/tsconfig.cli-types.json +9 -0
  160. package/tsconfig.json +28 -0
  161. package/vitest.config.ts +34 -0
@@ -0,0 +1,1656 @@
1
+ import { sql } from 'drizzle-orm';
2
+ import { integer, pgPolicy, pgRole, pgSchema, pgTable } from 'drizzle-orm/pg-core';
3
+ import { diffTestSchemas } from 'tests/schemaDiffer';
4
+ import { expect, test } from 'vitest';
5
+
6
+ test('add policy + enable rls', async (t) => {
7
+ const schema1 = {
8
+ users: pgTable('users', {
9
+ id: integer('id').primaryKey(),
10
+ }),
11
+ };
12
+
13
+ const schema2 = {
14
+ users: pgTable('users', {
15
+ id: integer('id').primaryKey(),
16
+ }, () => ({
17
+ rls: pgPolicy('test', { as: 'permissive' }),
18
+ })),
19
+ };
20
+
21
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
22
+
23
+ expect(sqlStatements).toStrictEqual([
24
+ 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;',
25
+ 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR ALL TO public;',
26
+ ]);
27
+ expect(statements).toStrictEqual([
28
+ {
29
+ schema: '',
30
+ tableName: 'users',
31
+ type: 'enable_rls',
32
+ },
33
+ {
34
+ data: {
35
+ as: 'PERMISSIVE',
36
+ for: 'ALL',
37
+ name: 'test',
38
+ to: ['public'],
39
+ on: undefined,
40
+ using: undefined,
41
+ withCheck: undefined,
42
+ },
43
+ schema: '',
44
+ tableName: 'users',
45
+ type: 'create_policy',
46
+ },
47
+ ]);
48
+ });
49
+
50
+ test('drop policy + disable rls', async (t) => {
51
+ const schema1 = {
52
+ users: pgTable('users', {
53
+ id: integer('id').primaryKey(),
54
+ }, () => ({
55
+ rls: pgPolicy('test', { as: 'permissive' }),
56
+ })),
57
+ };
58
+
59
+ const schema2 = {
60
+ users: pgTable('users', {
61
+ id: integer('id').primaryKey(),
62
+ }),
63
+ };
64
+
65
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
66
+
67
+ expect(sqlStatements).toStrictEqual([
68
+ 'ALTER TABLE "users" DISABLE ROW LEVEL SECURITY;',
69
+ 'DROP POLICY "test" ON "users" CASCADE;',
70
+ ]);
71
+ expect(statements).toStrictEqual([
72
+ {
73
+ schema: '',
74
+ tableName: 'users',
75
+ type: 'disable_rls',
76
+ },
77
+ {
78
+ data: {
79
+ as: 'PERMISSIVE',
80
+ for: 'ALL',
81
+ name: 'test',
82
+ to: ['public'],
83
+ on: undefined,
84
+ using: undefined,
85
+ withCheck: undefined,
86
+ },
87
+ schema: '',
88
+ tableName: 'users',
89
+ type: 'drop_policy',
90
+ },
91
+ ]);
92
+ });
93
+
94
+ test('add policy without enable rls', async (t) => {
95
+ const schema1 = {
96
+ users: pgTable('users', {
97
+ id: integer('id').primaryKey(),
98
+ }, () => ({
99
+ rls: pgPolicy('test', { as: 'permissive' }),
100
+ })),
101
+ };
102
+
103
+ const schema2 = {
104
+ users: pgTable('users', {
105
+ id: integer('id').primaryKey(),
106
+ }, () => ({
107
+ rls: pgPolicy('test', { as: 'permissive' }),
108
+ newrls: pgPolicy('newRls'),
109
+ })),
110
+ };
111
+
112
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
113
+
114
+ expect(sqlStatements).toStrictEqual([
115
+ 'CREATE POLICY "newRls" ON "users" AS PERMISSIVE FOR ALL TO public;',
116
+ ]);
117
+ expect(statements).toStrictEqual([
118
+ {
119
+ data: {
120
+ as: 'PERMISSIVE',
121
+ for: 'ALL',
122
+ name: 'newRls',
123
+ to: ['public'],
124
+ on: undefined,
125
+ using: undefined,
126
+ withCheck: undefined,
127
+ },
128
+ schema: '',
129
+ tableName: 'users',
130
+ type: 'create_policy',
131
+ },
132
+ ]);
133
+ });
134
+
135
+ test('drop policy without disable rls', async (t) => {
136
+ const schema1 = {
137
+ users: pgTable('users', {
138
+ id: integer('id').primaryKey(),
139
+ }, () => ({
140
+ rls: pgPolicy('test', { as: 'permissive' }),
141
+ oldRls: pgPolicy('oldRls'),
142
+ })),
143
+ };
144
+
145
+ const schema2 = {
146
+ users: pgTable('users', {
147
+ id: integer('id').primaryKey(),
148
+ }, () => ({
149
+ rls: pgPolicy('test', { as: 'permissive' }),
150
+ })),
151
+ };
152
+
153
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
154
+
155
+ expect(sqlStatements).toStrictEqual([
156
+ 'DROP POLICY "oldRls" ON "users" CASCADE;',
157
+ ]);
158
+ expect(statements).toStrictEqual([
159
+ {
160
+ data: {
161
+ as: 'PERMISSIVE',
162
+ for: 'ALL',
163
+ name: 'oldRls',
164
+ to: ['public'],
165
+ using: undefined,
166
+ on: undefined,
167
+ withCheck: undefined,
168
+ },
169
+ schema: '',
170
+ tableName: 'users',
171
+ type: 'drop_policy',
172
+ },
173
+ ]);
174
+ });
175
+
176
+ test('alter policy without recreation: changing roles', async (t) => {
177
+ const schema1 = {
178
+ users: pgTable('users', {
179
+ id: integer('id').primaryKey(),
180
+ }, () => ({
181
+ rls: pgPolicy('test', { as: 'permissive' }),
182
+ })),
183
+ };
184
+
185
+ const schema2 = {
186
+ users: pgTable('users', {
187
+ id: integer('id').primaryKey(),
188
+ }, () => ({
189
+ rls: pgPolicy('test', { as: 'permissive', to: 'current_role' }),
190
+ })),
191
+ };
192
+
193
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
194
+
195
+ expect(sqlStatements).toStrictEqual([
196
+ 'ALTER POLICY "test" ON "users" TO current_role;',
197
+ ]);
198
+ expect(statements).toStrictEqual([
199
+ {
200
+ newData: 'test--PERMISSIVE--ALL--current_role--undefined--undefined--undefined',
201
+ oldData: 'test--PERMISSIVE--ALL--public--undefined--undefined--undefined',
202
+ schema: '',
203
+ tableName: 'users',
204
+ type: 'alter_policy',
205
+ },
206
+ ]);
207
+ });
208
+
209
+ test('alter policy without recreation: changing using', async (t) => {
210
+ const schema1 = {
211
+ users: pgTable('users', {
212
+ id: integer('id').primaryKey(),
213
+ }, () => ({
214
+ rls: pgPolicy('test', { as: 'permissive' }),
215
+ })),
216
+ };
217
+
218
+ const schema2 = {
219
+ users: pgTable('users', {
220
+ id: integer('id').primaryKey(),
221
+ }, () => ({
222
+ rls: pgPolicy('test', { as: 'permissive', using: sql`true` }),
223
+ })),
224
+ };
225
+
226
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
227
+
228
+ expect(sqlStatements).toStrictEqual([
229
+ 'ALTER POLICY "test" ON "users" TO public USING (true);',
230
+ ]);
231
+ expect(statements).toStrictEqual([
232
+ {
233
+ newData: 'test--PERMISSIVE--ALL--public--true--undefined--undefined',
234
+ oldData: 'test--PERMISSIVE--ALL--public--undefined--undefined--undefined',
235
+ schema: '',
236
+ tableName: 'users',
237
+ type: 'alter_policy',
238
+ },
239
+ ]);
240
+ });
241
+
242
+ test('alter policy without recreation: changing with check', async (t) => {
243
+ const schema1 = {
244
+ users: pgTable('users', {
245
+ id: integer('id').primaryKey(),
246
+ }, () => ({
247
+ rls: pgPolicy('test', { as: 'permissive' }),
248
+ })),
249
+ };
250
+
251
+ const schema2 = {
252
+ users: pgTable('users', {
253
+ id: integer('id').primaryKey(),
254
+ }, () => ({
255
+ rls: pgPolicy('test', { as: 'permissive', withCheck: sql`true` }),
256
+ })),
257
+ };
258
+
259
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
260
+
261
+ expect(sqlStatements).toStrictEqual([
262
+ 'ALTER POLICY "test" ON "users" TO public WITH CHECK (true);',
263
+ ]);
264
+ expect(statements).toStrictEqual([
265
+ {
266
+ newData: 'test--PERMISSIVE--ALL--public--undefined--true--undefined',
267
+ oldData: 'test--PERMISSIVE--ALL--public--undefined--undefined--undefined',
268
+ schema: '',
269
+ tableName: 'users',
270
+ type: 'alter_policy',
271
+ },
272
+ ]);
273
+ });
274
+
275
+ ///
276
+
277
+ test('alter policy with recreation: changing as', async (t) => {
278
+ const schema1 = {
279
+ users: pgTable('users', {
280
+ id: integer('id').primaryKey(),
281
+ }, () => ({
282
+ rls: pgPolicy('test', { as: 'permissive' }),
283
+ })),
284
+ };
285
+
286
+ const schema2 = {
287
+ users: pgTable('users', {
288
+ id: integer('id').primaryKey(),
289
+ }, () => ({
290
+ rls: pgPolicy('test', { as: 'restrictive' }),
291
+ })),
292
+ };
293
+
294
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
295
+
296
+ expect(sqlStatements).toStrictEqual([
297
+ 'DROP POLICY "test" ON "users" CASCADE;',
298
+ 'CREATE POLICY "test" ON "users" AS RESTRICTIVE FOR ALL TO public;',
299
+ ]);
300
+ expect(statements).toStrictEqual([
301
+ {
302
+ data: {
303
+ as: 'PERMISSIVE',
304
+ for: 'ALL',
305
+ name: 'test',
306
+ to: ['public'],
307
+ using: undefined,
308
+ on: undefined,
309
+ withCheck: undefined,
310
+ },
311
+ schema: '',
312
+ tableName: 'users',
313
+ type: 'drop_policy',
314
+ },
315
+ {
316
+ data: {
317
+ as: 'RESTRICTIVE',
318
+ for: 'ALL',
319
+ name: 'test',
320
+ to: ['public'],
321
+ on: undefined,
322
+ using: undefined,
323
+ withCheck: undefined,
324
+ },
325
+ schema: '',
326
+ tableName: 'users',
327
+ type: 'create_policy',
328
+ },
329
+ ]);
330
+ });
331
+
332
+ test('alter policy with recreation: changing for', async (t) => {
333
+ const schema1 = {
334
+ users: pgTable('users', {
335
+ id: integer('id').primaryKey(),
336
+ }, () => ({
337
+ rls: pgPolicy('test', { as: 'permissive' }),
338
+ })),
339
+ };
340
+
341
+ const schema2 = {
342
+ users: pgTable('users', {
343
+ id: integer('id').primaryKey(),
344
+ }, () => ({
345
+ rls: pgPolicy('test', { as: 'permissive', for: 'delete' }),
346
+ })),
347
+ };
348
+
349
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
350
+
351
+ expect(sqlStatements).toStrictEqual([
352
+ 'DROP POLICY "test" ON "users" CASCADE;',
353
+ 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR DELETE TO public;',
354
+ ]);
355
+ expect(statements).toStrictEqual([
356
+ {
357
+ data: {
358
+ as: 'PERMISSIVE',
359
+ for: 'ALL',
360
+ name: 'test',
361
+ to: ['public'],
362
+ on: undefined,
363
+ using: undefined,
364
+ withCheck: undefined,
365
+ },
366
+ schema: '',
367
+ tableName: 'users',
368
+ type: 'drop_policy',
369
+ },
370
+ {
371
+ data: {
372
+ as: 'PERMISSIVE',
373
+ for: 'DELETE',
374
+ name: 'test',
375
+ to: ['public'],
376
+ on: undefined,
377
+ using: undefined,
378
+ withCheck: undefined,
379
+ },
380
+ schema: '',
381
+ tableName: 'users',
382
+ type: 'create_policy',
383
+ },
384
+ ]);
385
+ });
386
+
387
+ test('alter policy with recreation: changing both "as" and "for"', async (t) => {
388
+ const schema1 = {
389
+ users: pgTable('users', {
390
+ id: integer('id').primaryKey(),
391
+ }, () => ({
392
+ rls: pgPolicy('test', { as: 'permissive' }),
393
+ })),
394
+ };
395
+
396
+ const schema2 = {
397
+ users: pgTable('users', {
398
+ id: integer('id').primaryKey(),
399
+ }, () => ({
400
+ rls: pgPolicy('test', { as: 'restrictive', for: 'insert' }),
401
+ })),
402
+ };
403
+
404
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
405
+
406
+ expect(sqlStatements).toStrictEqual([
407
+ 'DROP POLICY "test" ON "users" CASCADE;',
408
+ 'CREATE POLICY "test" ON "users" AS RESTRICTIVE FOR INSERT TO public;',
409
+ ]);
410
+ expect(statements).toStrictEqual([
411
+ {
412
+ data: {
413
+ as: 'PERMISSIVE',
414
+ for: 'ALL',
415
+ name: 'test',
416
+ to: ['public'],
417
+ using: undefined,
418
+ on: undefined,
419
+ withCheck: undefined,
420
+ },
421
+ schema: '',
422
+ tableName: 'users',
423
+ type: 'drop_policy',
424
+ },
425
+ {
426
+ data: {
427
+ as: 'RESTRICTIVE',
428
+ for: 'INSERT',
429
+ name: 'test',
430
+ to: ['public'],
431
+ using: undefined,
432
+ on: undefined,
433
+ withCheck: undefined,
434
+ },
435
+ schema: '',
436
+ tableName: 'users',
437
+ type: 'create_policy',
438
+ },
439
+ ]);
440
+ });
441
+
442
+ test('alter policy with recreation: changing all fields', async (t) => {
443
+ const schema1 = {
444
+ users: pgTable('users', {
445
+ id: integer('id').primaryKey(),
446
+ }, () => ({
447
+ rls: pgPolicy('test', { as: 'permissive', for: 'select', using: sql`true` }),
448
+ })),
449
+ };
450
+
451
+ const schema2 = {
452
+ users: pgTable('users', {
453
+ id: integer('id').primaryKey(),
454
+ }, () => ({
455
+ rls: pgPolicy('test', { as: 'restrictive', to: 'current_role', withCheck: sql`true` }),
456
+ })),
457
+ };
458
+
459
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
460
+
461
+ expect(sqlStatements).toStrictEqual([
462
+ 'DROP POLICY "test" ON "users" CASCADE;',
463
+ 'CREATE POLICY "test" ON "users" AS RESTRICTIVE FOR ALL TO current_role WITH CHECK (true);',
464
+ ]);
465
+ expect(statements).toStrictEqual([
466
+ {
467
+ data: {
468
+ as: 'PERMISSIVE',
469
+ for: 'SELECT',
470
+ name: 'test',
471
+ to: ['public'],
472
+ using: 'true',
473
+ on: undefined,
474
+ withCheck: undefined,
475
+ },
476
+ schema: '',
477
+ tableName: 'users',
478
+ type: 'drop_policy',
479
+ },
480
+ {
481
+ data: {
482
+ as: 'RESTRICTIVE',
483
+ for: 'ALL',
484
+ name: 'test',
485
+ on: undefined,
486
+ to: ['current_role'],
487
+ using: undefined,
488
+ withCheck: 'true',
489
+ },
490
+ schema: '',
491
+ tableName: 'users',
492
+ type: 'create_policy',
493
+ },
494
+ ]);
495
+ });
496
+
497
+ test('rename policy', async (t) => {
498
+ const schema1 = {
499
+ users: pgTable('users', {
500
+ id: integer('id').primaryKey(),
501
+ }, () => ({
502
+ rls: pgPolicy('test', { as: 'permissive' }),
503
+ })),
504
+ };
505
+
506
+ const schema2 = {
507
+ users: pgTable('users', {
508
+ id: integer('id').primaryKey(),
509
+ }, () => ({
510
+ rls: pgPolicy('newName', { as: 'permissive' }),
511
+ })),
512
+ };
513
+
514
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, [
515
+ 'public.users.test->public.users.newName',
516
+ ]);
517
+
518
+ expect(sqlStatements).toStrictEqual([
519
+ 'ALTER POLICY "test" ON "users" RENAME TO "newName";',
520
+ ]);
521
+ expect(statements).toStrictEqual([
522
+ {
523
+ newName: 'newName',
524
+ oldName: 'test',
525
+ schema: '',
526
+ tableName: 'users',
527
+ type: 'rename_policy',
528
+ },
529
+ ]);
530
+ });
531
+
532
+ test('rename policy in renamed table', async (t) => {
533
+ const schema1 = {
534
+ users: pgTable('users', {
535
+ id: integer('id').primaryKey(),
536
+ }, () => ({
537
+ rls: pgPolicy('test', { as: 'permissive' }),
538
+ })),
539
+ };
540
+
541
+ const schema2 = {
542
+ users: pgTable('users2', {
543
+ id: integer('id').primaryKey(),
544
+ }, () => ({
545
+ rls: pgPolicy('newName', { as: 'permissive' }),
546
+ })),
547
+ };
548
+
549
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, [
550
+ 'public.users->public.users2',
551
+ 'public.users2.test->public.users2.newName',
552
+ ]);
553
+
554
+ expect(sqlStatements).toStrictEqual([
555
+ 'ALTER TABLE "users" RENAME TO "users2";',
556
+ 'ALTER POLICY "test" ON "users2" RENAME TO "newName";',
557
+ ]);
558
+ expect(statements).toStrictEqual([
559
+ {
560
+ fromSchema: '',
561
+ tableNameFrom: 'users',
562
+ tableNameTo: 'users2',
563
+ toSchema: '',
564
+ type: 'rename_table',
565
+ },
566
+ {
567
+ newName: 'newName',
568
+ oldName: 'test',
569
+ schema: '',
570
+ tableName: 'users2',
571
+ type: 'rename_policy',
572
+ },
573
+ ]);
574
+ });
575
+
576
+ test('create table with a policy', async (t) => {
577
+ const schema1 = {};
578
+
579
+ const schema2 = {
580
+ users: pgTable('users2', {
581
+ id: integer('id').primaryKey(),
582
+ }, () => ({
583
+ rls: pgPolicy('test', { as: 'permissive' }),
584
+ })),
585
+ };
586
+
587
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
588
+
589
+ expect(sqlStatements).toStrictEqual([
590
+ 'CREATE TABLE "users2" (\n\t"id" integer PRIMARY KEY NOT NULL\n);\n',
591
+ 'ALTER TABLE "users2" ENABLE ROW LEVEL SECURITY;',
592
+ 'CREATE POLICY "test" ON "users2" AS PERMISSIVE FOR ALL TO public;',
593
+ ]);
594
+ expect(statements).toStrictEqual([
595
+ {
596
+ columns: [
597
+ {
598
+ name: 'id',
599
+ notNull: true,
600
+ primaryKey: true,
601
+ type: 'integer',
602
+ },
603
+ ],
604
+ compositePKs: [],
605
+ checkConstraints: [],
606
+ compositePkName: '',
607
+ policies: [
608
+ 'test--PERMISSIVE--ALL--public--undefined--undefined--undefined',
609
+ ],
610
+ schema: '',
611
+ tableName: 'users2',
612
+ isRLSEnabled: false,
613
+ type: 'create_table',
614
+ uniqueConstraints: [],
615
+ },
616
+ {
617
+ data: {
618
+ as: 'PERMISSIVE',
619
+ for: 'ALL',
620
+ name: 'test',
621
+ to: [
622
+ 'public',
623
+ ],
624
+ on: undefined,
625
+ using: undefined,
626
+ withCheck: undefined,
627
+ },
628
+ schema: '',
629
+ tableName: 'users2',
630
+ type: 'create_policy',
631
+ },
632
+ ]);
633
+ });
634
+
635
+ test('drop table with a policy', async (t) => {
636
+ const schema1 = {
637
+ users: pgTable('users2', {
638
+ id: integer('id').primaryKey(),
639
+ }, () => ({
640
+ rls: pgPolicy('test', { as: 'permissive' }),
641
+ })),
642
+ };
643
+
644
+ const schema2 = {};
645
+
646
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
647
+
648
+ expect(sqlStatements).toStrictEqual([
649
+ 'DROP POLICY "test" ON "users2" CASCADE;',
650
+ 'DROP TABLE "users2" CASCADE;',
651
+ ]);
652
+ expect(statements).toStrictEqual([
653
+ {
654
+ policies: [
655
+ 'test--PERMISSIVE--ALL--public--undefined--undefined--undefined',
656
+ ],
657
+ schema: '',
658
+ tableName: 'users2',
659
+ type: 'drop_table',
660
+ },
661
+ ]);
662
+ });
663
+
664
+ test('add policy with multiple "to" roles', async (t) => {
665
+ const schema1 = {
666
+ users: pgTable('users', {
667
+ id: integer('id').primaryKey(),
668
+ }),
669
+ };
670
+
671
+ const role = pgRole('manager').existing();
672
+
673
+ const schema2 = {
674
+ role,
675
+ users: pgTable('users', {
676
+ id: integer('id').primaryKey(),
677
+ }, () => ({
678
+ rls: pgPolicy('test', { to: ['current_role', role] }),
679
+ })),
680
+ };
681
+
682
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
683
+
684
+ expect(sqlStatements).toStrictEqual([
685
+ 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;',
686
+ 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR ALL TO current_role, "manager";',
687
+ ]);
688
+ expect(statements).toStrictEqual([
689
+ {
690
+ schema: '',
691
+ tableName: 'users',
692
+ type: 'enable_rls',
693
+ },
694
+ {
695
+ data: {
696
+ as: 'PERMISSIVE',
697
+ for: 'ALL',
698
+ name: 'test',
699
+ on: undefined,
700
+ to: ['current_role', 'manager'],
701
+ using: undefined,
702
+ withCheck: undefined,
703
+ },
704
+ schema: '',
705
+ tableName: 'users',
706
+ type: 'create_policy',
707
+ },
708
+ ]);
709
+ });
710
+
711
+ test('create table with rls enabled', async (t) => {
712
+ const schema1 = {};
713
+
714
+ const schema2 = {
715
+ users: pgTable('users', {
716
+ id: integer('id').primaryKey(),
717
+ }).enableRLS(),
718
+ };
719
+
720
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
721
+
722
+ expect(sqlStatements).toStrictEqual([
723
+ `CREATE TABLE "users" (\n\t"id" integer PRIMARY KEY NOT NULL\n);
724
+ `,
725
+ 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;',
726
+ ]);
727
+ });
728
+
729
+ test('enable rls force', async (t) => {
730
+ const schema1 = {
731
+ users: pgTable('users', {
732
+ id: integer('id').primaryKey(),
733
+ }),
734
+ };
735
+
736
+ const schema2 = {
737
+ users: pgTable('users', {
738
+ id: integer('id').primaryKey(),
739
+ }).enableRLS(),
740
+ };
741
+
742
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
743
+
744
+ expect(sqlStatements).toStrictEqual(['ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;']);
745
+ });
746
+
747
+ test('disable rls force', async (t) => {
748
+ const schema1 = {
749
+ users: pgTable('users', {
750
+ id: integer('id').primaryKey(),
751
+ }).enableRLS(),
752
+ };
753
+
754
+ const schema2 = {
755
+ users: pgTable('users', {
756
+ id: integer('id').primaryKey(),
757
+ }),
758
+ };
759
+
760
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
761
+
762
+ expect(sqlStatements).toStrictEqual(['ALTER TABLE "users" DISABLE ROW LEVEL SECURITY;']);
763
+ });
764
+
765
+ test('drop policy with enabled rls', async (t) => {
766
+ const schema1 = {
767
+ users: pgTable('users', {
768
+ id: integer('id').primaryKey(),
769
+ }, () => ({
770
+ rls: pgPolicy('test', { to: ['current_role', role] }),
771
+ })).enableRLS(),
772
+ };
773
+
774
+ const role = pgRole('manager').existing();
775
+
776
+ const schema2 = {
777
+ role,
778
+ users: pgTable('users', {
779
+ id: integer('id').primaryKey(),
780
+ }).enableRLS(),
781
+ };
782
+
783
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
784
+
785
+ expect(sqlStatements).toStrictEqual([
786
+ 'DROP POLICY "test" ON "users" CASCADE;',
787
+ ]);
788
+ });
789
+
790
+ test('add policy with enabled rls', async (t) => {
791
+ const schema1 = {
792
+ users: pgTable('users', {
793
+ id: integer('id').primaryKey(),
794
+ }).enableRLS(),
795
+ };
796
+
797
+ const role = pgRole('manager').existing();
798
+
799
+ const schema2 = {
800
+ role,
801
+ users: pgTable('users', {
802
+ id: integer('id').primaryKey(),
803
+ }, () => ({
804
+ rls: pgPolicy('test', { to: ['current_role', role] }),
805
+ })).enableRLS(),
806
+ };
807
+
808
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
809
+
810
+ expect(sqlStatements).toStrictEqual([
811
+ 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR ALL TO current_role, "manager";',
812
+ ]);
813
+ });
814
+
815
+ test('add policy + link table', async (t) => {
816
+ const schema1 = {
817
+ users: pgTable('users', {
818
+ id: integer('id').primaryKey(),
819
+ }),
820
+ };
821
+
822
+ const users = pgTable('users', {
823
+ id: integer('id').primaryKey(),
824
+ });
825
+
826
+ const schema2 = {
827
+ users,
828
+ rls: pgPolicy('test', { as: 'permissive' }).link(users),
829
+ };
830
+
831
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
832
+
833
+ expect(sqlStatements).toStrictEqual([
834
+ 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;',
835
+ 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR ALL TO public;',
836
+ ]);
837
+ expect(statements).toStrictEqual([
838
+ {
839
+ schema: '',
840
+ tableName: 'users',
841
+ type: 'enable_rls',
842
+ },
843
+ {
844
+ data: {
845
+ as: 'PERMISSIVE',
846
+ for: 'ALL',
847
+ name: 'test',
848
+ to: ['public'],
849
+ on: undefined,
850
+ using: undefined,
851
+ withCheck: undefined,
852
+ },
853
+ schema: '',
854
+ tableName: 'users',
855
+ type: 'create_policy',
856
+ },
857
+ ]);
858
+ });
859
+
860
+ test('link table', async (t) => {
861
+ const schema1 = {
862
+ users: pgTable('users', {
863
+ id: integer('id').primaryKey(),
864
+ }),
865
+ rls: pgPolicy('test', { as: 'permissive' }),
866
+ };
867
+
868
+ const users = pgTable('users', {
869
+ id: integer('id').primaryKey(),
870
+ });
871
+
872
+ const schema2 = {
873
+ users,
874
+ rls: pgPolicy('test', { as: 'permissive' }).link(users),
875
+ };
876
+
877
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
878
+
879
+ expect(sqlStatements).toStrictEqual([
880
+ 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;',
881
+ 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR ALL TO public;',
882
+ ]);
883
+ expect(statements).toStrictEqual([
884
+ {
885
+ schema: '',
886
+ tableName: 'users',
887
+ type: 'enable_rls',
888
+ },
889
+ {
890
+ data: {
891
+ as: 'PERMISSIVE',
892
+ for: 'ALL',
893
+ name: 'test',
894
+ to: ['public'],
895
+ on: undefined,
896
+ using: undefined,
897
+ withCheck: undefined,
898
+ },
899
+ schema: '',
900
+ tableName: 'users',
901
+ type: 'create_policy',
902
+ },
903
+ ]);
904
+ });
905
+
906
+ test('unlink table', async (t) => {
907
+ const users = pgTable('users', {
908
+ id: integer('id').primaryKey(),
909
+ });
910
+
911
+ const schema1 = {
912
+ users,
913
+ rls: pgPolicy('test', { as: 'permissive' }).link(users),
914
+ };
915
+
916
+ const schema2 = {
917
+ users,
918
+ rls: pgPolicy('test', { as: 'permissive' }),
919
+ };
920
+
921
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
922
+
923
+ expect(sqlStatements).toStrictEqual([
924
+ 'ALTER TABLE "users" DISABLE ROW LEVEL SECURITY;',
925
+ 'DROP POLICY "test" ON "users" CASCADE;',
926
+ ]);
927
+ expect(statements).toStrictEqual([
928
+ {
929
+ schema: '',
930
+ tableName: 'users',
931
+ type: 'disable_rls',
932
+ },
933
+ {
934
+ data: {
935
+ as: 'PERMISSIVE',
936
+ for: 'ALL',
937
+ name: 'test',
938
+ to: ['public'],
939
+ on: undefined,
940
+ using: undefined,
941
+ withCheck: undefined,
942
+ },
943
+ schema: '',
944
+ tableName: 'users',
945
+ type: 'drop_policy',
946
+ },
947
+ ]);
948
+ });
949
+
950
+ test('drop policy with link', async (t) => {
951
+ const users = pgTable('users', {
952
+ id: integer('id').primaryKey(),
953
+ });
954
+
955
+ const schema1 = {
956
+ users,
957
+ rls: pgPolicy('test', { as: 'permissive' }).link(users),
958
+ };
959
+
960
+ const schema2 = {
961
+ users,
962
+ };
963
+
964
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
965
+
966
+ expect(sqlStatements).toStrictEqual([
967
+ 'ALTER TABLE "users" DISABLE ROW LEVEL SECURITY;',
968
+ 'DROP POLICY "test" ON "users" CASCADE;',
969
+ ]);
970
+ expect(statements).toStrictEqual([
971
+ {
972
+ schema: '',
973
+ tableName: 'users',
974
+ type: 'disable_rls',
975
+ },
976
+ {
977
+ data: {
978
+ as: 'PERMISSIVE',
979
+ for: 'ALL',
980
+ name: 'test',
981
+ to: ['public'],
982
+ on: undefined,
983
+ using: undefined,
984
+ withCheck: undefined,
985
+ },
986
+ schema: '',
987
+ tableName: 'users',
988
+ type: 'drop_policy',
989
+ },
990
+ ]);
991
+ });
992
+
993
+ test('add policy in table and with link table', async (t) => {
994
+ const schema1 = {
995
+ users: pgTable('users', {
996
+ id: integer('id').primaryKey(),
997
+ }),
998
+ };
999
+ const users = pgTable('users', {
1000
+ id: integer('id').primaryKey(),
1001
+ }, () => [
1002
+ pgPolicy('test1', { to: 'current_user' }),
1003
+ ]);
1004
+
1005
+ const schema2 = {
1006
+ users,
1007
+ rls: pgPolicy('test', { as: 'permissive' }).link(users),
1008
+ };
1009
+
1010
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
1011
+
1012
+ expect(sqlStatements).toStrictEqual([
1013
+ 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;',
1014
+ 'CREATE POLICY "test1" ON "users" AS PERMISSIVE FOR ALL TO current_user;',
1015
+ 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR ALL TO public;',
1016
+ ]);
1017
+ expect(statements).toStrictEqual([
1018
+ {
1019
+ schema: '',
1020
+ tableName: 'users',
1021
+ type: 'enable_rls',
1022
+ },
1023
+ {
1024
+ data: {
1025
+ as: 'PERMISSIVE',
1026
+ for: 'ALL',
1027
+ name: 'test1',
1028
+ to: ['current_user'],
1029
+ on: undefined,
1030
+ using: undefined,
1031
+ withCheck: undefined,
1032
+ },
1033
+ schema: '',
1034
+ tableName: 'users',
1035
+ type: 'create_policy',
1036
+ },
1037
+ {
1038
+ data: {
1039
+ as: 'PERMISSIVE',
1040
+ for: 'ALL',
1041
+ name: 'test',
1042
+ to: ['public'],
1043
+ using: undefined,
1044
+ on: undefined,
1045
+ withCheck: undefined,
1046
+ },
1047
+ schema: '',
1048
+ tableName: 'users',
1049
+ type: 'create_policy',
1050
+ },
1051
+ ]);
1052
+ });
1053
+
1054
+ test('link non-schema table', async (t) => {
1055
+ const users = pgTable('users', {
1056
+ id: integer('id').primaryKey(),
1057
+ });
1058
+
1059
+ const schema1 = {};
1060
+
1061
+ const schema2 = {
1062
+ rls: pgPolicy('test', { as: 'permissive' }).link(users),
1063
+ };
1064
+
1065
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
1066
+
1067
+ expect(sqlStatements).toStrictEqual([
1068
+ 'CREATE POLICY "test" ON "public"."users" AS PERMISSIVE FOR ALL TO public;',
1069
+ ]);
1070
+ expect(statements).toStrictEqual([
1071
+ {
1072
+ data: {
1073
+ as: 'PERMISSIVE',
1074
+ for: 'ALL',
1075
+ name: 'test',
1076
+ on: '"public"."users"',
1077
+ to: [
1078
+ 'public',
1079
+ ],
1080
+ using: undefined,
1081
+ withCheck: undefined,
1082
+ },
1083
+ tableName: '"public"."users"',
1084
+ type: 'create_ind_policy',
1085
+ },
1086
+ ]);
1087
+ });
1088
+
1089
+ test('unlink non-schema table', async (t) => {
1090
+ const users = pgTable('users', {
1091
+ id: integer('id').primaryKey(),
1092
+ });
1093
+
1094
+ const schema1 = {
1095
+ rls: pgPolicy('test', { as: 'permissive' }).link(users),
1096
+ };
1097
+
1098
+ const schema2 = {
1099
+ rls: pgPolicy('test', { as: 'permissive' }),
1100
+ };
1101
+
1102
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
1103
+
1104
+ expect(sqlStatements).toStrictEqual([
1105
+ 'DROP POLICY "test" ON "public"."users" CASCADE;',
1106
+ ]);
1107
+ expect(statements).toStrictEqual([
1108
+ {
1109
+ data: {
1110
+ as: 'PERMISSIVE',
1111
+ for: 'ALL',
1112
+ name: 'test',
1113
+ on: '"public"."users"',
1114
+ to: [
1115
+ 'public',
1116
+ ],
1117
+ using: undefined,
1118
+ withCheck: undefined,
1119
+ },
1120
+ tableName: '"public"."users"',
1121
+ type: 'drop_ind_policy',
1122
+ },
1123
+ ]);
1124
+ });
1125
+
1126
+ test('add policy + link non-schema table', async (t) => {
1127
+ const schema1 = {
1128
+ users: pgTable('users', {
1129
+ id: integer('id').primaryKey(),
1130
+ }),
1131
+ };
1132
+
1133
+ const cities = pgTable('cities', {
1134
+ id: integer('id').primaryKey(),
1135
+ });
1136
+
1137
+ const schema2 = {
1138
+ users: pgTable('users', {
1139
+ id: integer('id').primaryKey(),
1140
+ }, (t) => [
1141
+ pgPolicy('test2'),
1142
+ ]),
1143
+ rls: pgPolicy('test', { as: 'permissive' }).link(cities),
1144
+ };
1145
+
1146
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
1147
+
1148
+ expect(sqlStatements).toStrictEqual([
1149
+ 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;',
1150
+ 'CREATE POLICY "test2" ON "users" AS PERMISSIVE FOR ALL TO public;',
1151
+ 'CREATE POLICY "test" ON "public"."cities" AS PERMISSIVE FOR ALL TO public;',
1152
+ ]);
1153
+ expect(statements).toStrictEqual([
1154
+ {
1155
+ schema: '',
1156
+ tableName: 'users',
1157
+ type: 'enable_rls',
1158
+ },
1159
+ {
1160
+ data: {
1161
+ as: 'PERMISSIVE',
1162
+ for: 'ALL',
1163
+ name: 'test2',
1164
+ on: undefined,
1165
+ to: [
1166
+ 'public',
1167
+ ],
1168
+ using: undefined,
1169
+ withCheck: undefined,
1170
+ },
1171
+ schema: '',
1172
+ tableName: 'users',
1173
+ type: 'create_policy',
1174
+ },
1175
+ {
1176
+ data: {
1177
+ as: 'PERMISSIVE',
1178
+ for: 'ALL',
1179
+ name: 'test',
1180
+ on: '"public"."cities"',
1181
+ to: [
1182
+ 'public',
1183
+ ],
1184
+ using: undefined,
1185
+ withCheck: undefined,
1186
+ },
1187
+ tableName: '"public"."cities"',
1188
+ type: 'create_ind_policy',
1189
+ },
1190
+ ]);
1191
+ });
1192
+
1193
+ test('add policy + link non-schema table from auth schema', async (t) => {
1194
+ const schema1 = {
1195
+ users: pgTable('users', {
1196
+ id: integer('id').primaryKey(),
1197
+ }),
1198
+ };
1199
+
1200
+ const authSchema = pgSchema('auth');
1201
+
1202
+ const cities = authSchema.table('cities', {
1203
+ id: integer('id').primaryKey(),
1204
+ });
1205
+
1206
+ const schema2 = {
1207
+ users: pgTable('users', {
1208
+ id: integer('id').primaryKey(),
1209
+ }, (t) => [
1210
+ pgPolicy('test2'),
1211
+ ]),
1212
+ rls: pgPolicy('test', { as: 'permissive' }).link(cities),
1213
+ };
1214
+
1215
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
1216
+
1217
+ expect(sqlStatements).toStrictEqual([
1218
+ 'ALTER TABLE "users" ENABLE ROW LEVEL SECURITY;',
1219
+ 'CREATE POLICY "test2" ON "users" AS PERMISSIVE FOR ALL TO public;',
1220
+ 'CREATE POLICY "test" ON "auth"."cities" AS PERMISSIVE FOR ALL TO public;',
1221
+ ]);
1222
+ expect(statements).toStrictEqual([
1223
+ {
1224
+ schema: '',
1225
+ tableName: 'users',
1226
+ type: 'enable_rls',
1227
+ },
1228
+ {
1229
+ data: {
1230
+ as: 'PERMISSIVE',
1231
+ for: 'ALL',
1232
+ name: 'test2',
1233
+ on: undefined,
1234
+ to: [
1235
+ 'public',
1236
+ ],
1237
+ using: undefined,
1238
+ withCheck: undefined,
1239
+ },
1240
+ schema: '',
1241
+ tableName: 'users',
1242
+ type: 'create_policy',
1243
+ },
1244
+ {
1245
+ data: {
1246
+ as: 'PERMISSIVE',
1247
+ for: 'ALL',
1248
+ name: 'test',
1249
+ on: '"auth"."cities"',
1250
+ to: [
1251
+ 'public',
1252
+ ],
1253
+ using: undefined,
1254
+ withCheck: undefined,
1255
+ },
1256
+ tableName: '"auth"."cities"',
1257
+ type: 'create_ind_policy',
1258
+ },
1259
+ ]);
1260
+ });
1261
+
1262
+ test('rename policy that is linked', async (t) => {
1263
+ const users = pgTable('users', {
1264
+ id: integer('id').primaryKey(),
1265
+ });
1266
+
1267
+ const schema1 = {
1268
+ rls: pgPolicy('test', { as: 'permissive' }).link(users),
1269
+ };
1270
+
1271
+ const schema2 = {
1272
+ rls: pgPolicy('newName', { as: 'permissive' }).link(users),
1273
+ };
1274
+
1275
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, [
1276
+ '"public"."users".test->"public"."users".newName',
1277
+ ]);
1278
+
1279
+ expect(sqlStatements).toStrictEqual([
1280
+ 'ALTER POLICY "test" ON "public"."users" RENAME TO "newName";',
1281
+ ]);
1282
+ expect(statements).toStrictEqual([
1283
+ {
1284
+ newName: 'newName',
1285
+ oldName: 'test',
1286
+ tableKey: '"public"."users"',
1287
+ type: 'rename_ind_policy',
1288
+ },
1289
+ ]);
1290
+ });
1291
+
1292
+ test('alter policy that is linked', async (t) => {
1293
+ const users = pgTable('users', {
1294
+ id: integer('id').primaryKey(),
1295
+ });
1296
+
1297
+ const schema1 = {
1298
+ rls: pgPolicy('test', { as: 'permissive' }).link(users),
1299
+ };
1300
+
1301
+ const schema2 = {
1302
+ rls: pgPolicy('test', { as: 'permissive', to: 'current_role' }).link(users),
1303
+ };
1304
+
1305
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
1306
+
1307
+ expect(sqlStatements).toStrictEqual([
1308
+ 'ALTER POLICY "test" ON "public"."users" TO current_role;',
1309
+ ]);
1310
+ expect(statements).toStrictEqual([
1311
+ {
1312
+ newData: {
1313
+ as: 'PERMISSIVE',
1314
+ for: 'ALL',
1315
+ name: 'test',
1316
+ on: '"public"."users"',
1317
+ to: [
1318
+ 'current_role',
1319
+ ],
1320
+ using: undefined,
1321
+ withCheck: undefined,
1322
+ },
1323
+ oldData: {
1324
+ as: 'PERMISSIVE',
1325
+ for: 'ALL',
1326
+ name: 'test',
1327
+ on: '"public"."users"',
1328
+ to: [
1329
+ 'public',
1330
+ ],
1331
+ using: undefined,
1332
+ withCheck: undefined,
1333
+ },
1334
+ type: 'alter_ind_policy',
1335
+ },
1336
+ ]);
1337
+ });
1338
+
1339
+ test('alter policy that is linked: withCheck', async (t) => {
1340
+ const users = pgTable('users', {
1341
+ id: integer('id').primaryKey(),
1342
+ });
1343
+
1344
+ const schema1 = {
1345
+ rls: pgPolicy('test', { as: 'permissive', withCheck: sql`true` }).link(users),
1346
+ };
1347
+
1348
+ const schema2 = {
1349
+ rls: pgPolicy('test', { as: 'permissive', withCheck: sql`false` }).link(users),
1350
+ };
1351
+
1352
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
1353
+
1354
+ expect(sqlStatements).toStrictEqual([
1355
+ 'ALTER POLICY "test" ON "public"."users" TO public WITH CHECK (false);',
1356
+ ]);
1357
+ expect(statements).toStrictEqual([
1358
+ {
1359
+ newData: {
1360
+ as: 'PERMISSIVE',
1361
+ for: 'ALL',
1362
+ name: 'test',
1363
+ on: '"public"."users"',
1364
+ to: [
1365
+ 'public',
1366
+ ],
1367
+ using: undefined,
1368
+ withCheck: 'false',
1369
+ },
1370
+ oldData: {
1371
+ as: 'PERMISSIVE',
1372
+ for: 'ALL',
1373
+ name: 'test',
1374
+ on: '"public"."users"',
1375
+ to: [
1376
+ 'public',
1377
+ ],
1378
+ using: undefined,
1379
+ withCheck: 'true',
1380
+ },
1381
+ type: 'alter_ind_policy',
1382
+ },
1383
+ ]);
1384
+ });
1385
+
1386
+ test('alter policy that is linked: using', async (t) => {
1387
+ const users = pgTable('users', {
1388
+ id: integer('id').primaryKey(),
1389
+ });
1390
+
1391
+ const schema1 = {
1392
+ rls: pgPolicy('test', { as: 'permissive', using: sql`true` }).link(users),
1393
+ };
1394
+
1395
+ const schema2 = {
1396
+ rls: pgPolicy('test', { as: 'permissive', using: sql`false` }).link(users),
1397
+ };
1398
+
1399
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
1400
+
1401
+ expect(sqlStatements).toStrictEqual([
1402
+ 'ALTER POLICY "test" ON "public"."users" TO public USING (false);',
1403
+ ]);
1404
+ expect(statements).toStrictEqual([
1405
+ {
1406
+ newData: {
1407
+ as: 'PERMISSIVE',
1408
+ for: 'ALL',
1409
+ name: 'test',
1410
+ on: '"public"."users"',
1411
+ to: [
1412
+ 'public',
1413
+ ],
1414
+ using: 'false',
1415
+ withCheck: undefined,
1416
+ },
1417
+ oldData: {
1418
+ as: 'PERMISSIVE',
1419
+ for: 'ALL',
1420
+ name: 'test',
1421
+ on: '"public"."users"',
1422
+ to: [
1423
+ 'public',
1424
+ ],
1425
+ using: 'true',
1426
+ withCheck: undefined,
1427
+ },
1428
+ type: 'alter_ind_policy',
1429
+ },
1430
+ ]);
1431
+ });
1432
+
1433
+ test('alter policy that is linked: using', async (t) => {
1434
+ const users = pgTable('users', {
1435
+ id: integer('id').primaryKey(),
1436
+ });
1437
+
1438
+ const schema1 = {
1439
+ rls: pgPolicy('test', { for: 'insert' }).link(users),
1440
+ };
1441
+
1442
+ const schema2 = {
1443
+ rls: pgPolicy('test', { for: 'delete' }).link(users),
1444
+ };
1445
+
1446
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
1447
+
1448
+ expect(sqlStatements).toStrictEqual([
1449
+ 'DROP POLICY "test" ON "public"."users" CASCADE;',
1450
+ 'CREATE POLICY "test" ON "public"."users" AS PERMISSIVE FOR DELETE TO public;',
1451
+ ]);
1452
+ expect(statements).toStrictEqual([
1453
+ {
1454
+ data: {
1455
+ as: 'PERMISSIVE',
1456
+ for: 'INSERT',
1457
+ name: 'test',
1458
+ on: '"public"."users"',
1459
+ to: [
1460
+ 'public',
1461
+ ],
1462
+ using: undefined,
1463
+ withCheck: undefined,
1464
+ },
1465
+ tableName: '"public"."users"',
1466
+ type: 'drop_ind_policy',
1467
+ },
1468
+ {
1469
+ data: {
1470
+ as: 'PERMISSIVE',
1471
+ for: 'DELETE',
1472
+ name: 'test',
1473
+ on: '"public"."users"',
1474
+ to: [
1475
+ 'public',
1476
+ ],
1477
+ using: undefined,
1478
+ withCheck: undefined,
1479
+ },
1480
+ tableName: '"public"."users"',
1481
+ type: 'create_ind_policy',
1482
+ },
1483
+ ]);
1484
+ });
1485
+
1486
+ ////
1487
+
1488
+ test('alter policy in the table', async (t) => {
1489
+ const schema1 = {
1490
+ users: pgTable('users', {
1491
+ id: integer('id').primaryKey(),
1492
+ }, (t) => [
1493
+ pgPolicy('test', { as: 'permissive' }),
1494
+ ]),
1495
+ };
1496
+
1497
+ const schema2 = {
1498
+ users: pgTable('users', {
1499
+ id: integer('id').primaryKey(),
1500
+ }, (t) => [
1501
+ pgPolicy('test', { as: 'permissive', to: 'current_role' }),
1502
+ ]),
1503
+ };
1504
+
1505
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
1506
+
1507
+ expect(sqlStatements).toStrictEqual([
1508
+ 'ALTER POLICY "test" ON "users" TO current_role;',
1509
+ ]);
1510
+ expect(statements).toStrictEqual([
1511
+ {
1512
+ newData: 'test--PERMISSIVE--ALL--current_role--undefined--undefined--undefined',
1513
+ oldData: 'test--PERMISSIVE--ALL--public--undefined--undefined--undefined',
1514
+ schema: '',
1515
+ tableName: 'users',
1516
+ type: 'alter_policy',
1517
+ },
1518
+ ]);
1519
+ });
1520
+
1521
+ test('alter policy in the table: withCheck', async (t) => {
1522
+ const users = pgTable('users', {
1523
+ id: integer('id').primaryKey(),
1524
+ });
1525
+
1526
+ const schema1 = {
1527
+ users: pgTable('users', {
1528
+ id: integer('id').primaryKey(),
1529
+ }, (t) => [
1530
+ pgPolicy('test', { as: 'permissive', withCheck: sql`true` }),
1531
+ ]),
1532
+ };
1533
+
1534
+ const schema2 = {
1535
+ users: pgTable('users', {
1536
+ id: integer('id').primaryKey(),
1537
+ }, (t) => [
1538
+ pgPolicy('test', { as: 'permissive', withCheck: sql`false` }),
1539
+ ]),
1540
+ };
1541
+
1542
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
1543
+
1544
+ expect(sqlStatements).toStrictEqual([
1545
+ 'ALTER POLICY "test" ON "users" TO public WITH CHECK (false);',
1546
+ ]);
1547
+ expect(statements).toStrictEqual([
1548
+ {
1549
+ newData: 'test--PERMISSIVE--ALL--public--undefined--false--undefined',
1550
+ oldData: 'test--PERMISSIVE--ALL--public--undefined--true--undefined',
1551
+ schema: '',
1552
+ tableName: 'users',
1553
+ type: 'alter_policy',
1554
+ },
1555
+ ]);
1556
+ });
1557
+
1558
+ test('alter policy in the table: using', async (t) => {
1559
+ const users = pgTable('users', {
1560
+ id: integer('id').primaryKey(),
1561
+ });
1562
+
1563
+ const schema1 = {
1564
+ users: pgTable('users', {
1565
+ id: integer('id').primaryKey(),
1566
+ }, (t) => [
1567
+ pgPolicy('test', { as: 'permissive', using: sql`true` }),
1568
+ ]),
1569
+ };
1570
+
1571
+ const schema2 = {
1572
+ users: pgTable('users', {
1573
+ id: integer('id').primaryKey(),
1574
+ }, (t) => [
1575
+ pgPolicy('test', { as: 'permissive', using: sql`false` }),
1576
+ ]),
1577
+ };
1578
+
1579
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
1580
+
1581
+ expect(sqlStatements).toStrictEqual([
1582
+ 'ALTER POLICY "test" ON "users" TO public USING (false);',
1583
+ ]);
1584
+ expect(statements).toStrictEqual([
1585
+ {
1586
+ newData: 'test--PERMISSIVE--ALL--public--false--undefined--undefined',
1587
+ oldData: 'test--PERMISSIVE--ALL--public--true--undefined--undefined',
1588
+ schema: '',
1589
+ tableName: 'users',
1590
+ type: 'alter_policy',
1591
+ },
1592
+ ]);
1593
+ });
1594
+
1595
+ test('alter policy in the table: using', async (t) => {
1596
+ const users = pgTable('users', {
1597
+ id: integer('id').primaryKey(),
1598
+ });
1599
+
1600
+ const schema1 = {
1601
+ users: pgTable('users', {
1602
+ id: integer('id').primaryKey(),
1603
+ }, (t) => [
1604
+ pgPolicy('test', { for: 'insert' }),
1605
+ ]),
1606
+ };
1607
+
1608
+ const schema2 = {
1609
+ users: pgTable('users', {
1610
+ id: integer('id').primaryKey(),
1611
+ }, (t) => [
1612
+ pgPolicy('test', { for: 'delete' }),
1613
+ ]),
1614
+ };
1615
+
1616
+ const { statements, sqlStatements } = await diffTestSchemas(schema1, schema2, []);
1617
+
1618
+ expect(sqlStatements).toStrictEqual([
1619
+ 'DROP POLICY "test" ON "users" CASCADE;',
1620
+ 'CREATE POLICY "test" ON "users" AS PERMISSIVE FOR DELETE TO public;',
1621
+ ]);
1622
+ expect(statements).toStrictEqual([
1623
+ {
1624
+ data: {
1625
+ as: 'PERMISSIVE',
1626
+ for: 'INSERT',
1627
+ name: 'test',
1628
+ on: undefined,
1629
+ to: [
1630
+ 'public',
1631
+ ],
1632
+ using: undefined,
1633
+ withCheck: undefined,
1634
+ },
1635
+ schema: '',
1636
+ tableName: 'users',
1637
+ type: 'drop_policy',
1638
+ },
1639
+ {
1640
+ data: {
1641
+ as: 'PERMISSIVE',
1642
+ for: 'DELETE',
1643
+ name: 'test',
1644
+ on: undefined,
1645
+ to: [
1646
+ 'public',
1647
+ ],
1648
+ using: undefined,
1649
+ withCheck: undefined,
1650
+ },
1651
+ schema: '',
1652
+ tableName: 'users',
1653
+ type: 'create_policy',
1654
+ },
1655
+ ]);
1656
+ });