@supabase/pg-delta 1.0.0-alpha.4 → 1.0.0-alpha.6

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 (359) hide show
  1. package/README.md +40 -23
  2. package/dist/cli/app.js +26 -3
  3. package/dist/cli/bin/cli.js +5 -0
  4. package/dist/cli/commands/catalog-export.d.ts +5 -0
  5. package/dist/cli/commands/catalog-export.js +64 -0
  6. package/dist/cli/commands/declarative-apply.d.ts +6 -0
  7. package/dist/cli/commands/declarative-apply.js +288 -0
  8. package/dist/cli/commands/declarative-export.d.ts +5 -0
  9. package/dist/cli/commands/declarative-export.js +245 -0
  10. package/dist/cli/commands/plan.js +19 -6
  11. package/dist/cli/exit-code.d.ts +2 -0
  12. package/dist/cli/exit-code.js +7 -0
  13. package/dist/cli/formatters/tree/tree.js +3 -2
  14. package/dist/cli/utils/apply-display.d.ts +52 -0
  15. package/dist/cli/utils/apply-display.js +183 -0
  16. package/dist/cli/utils/export-display.d.ts +43 -0
  17. package/dist/cli/utils/export-display.js +202 -0
  18. package/dist/cli/utils/resolve-input.d.ts +7 -0
  19. package/dist/cli/utils/resolve-input.js +13 -0
  20. package/dist/core/catalog-export/index.d.ts +11 -0
  21. package/dist/core/catalog-export/index.js +10 -0
  22. package/dist/core/catalog.diff.d.ts +1 -0
  23. package/dist/core/catalog.diff.js +64 -48
  24. package/dist/core/catalog.model.d.ts +14 -1
  25. package/dist/core/catalog.model.js +103 -1
  26. package/dist/core/catalog.snapshot.d.ts +66 -0
  27. package/dist/core/catalog.snapshot.js +206 -0
  28. package/dist/core/declarative-apply/discover-sql.d.ts +18 -0
  29. package/dist/core/declarative-apply/discover-sql.js +86 -0
  30. package/dist/core/declarative-apply/extract-catalog-providers.d.ts +23 -0
  31. package/dist/core/declarative-apply/extract-catalog-providers.js +159 -0
  32. package/dist/core/declarative-apply/index.d.ts +49 -0
  33. package/dist/core/declarative-apply/index.js +134 -0
  34. package/dist/core/declarative-apply/round-apply.d.ts +100 -0
  35. package/dist/core/declarative-apply/round-apply.js +378 -0
  36. package/dist/core/export/file-mapper.d.ts +71 -0
  37. package/dist/core/export/file-mapper.js +474 -0
  38. package/dist/core/export/grouper.d.ts +13 -0
  39. package/dist/core/export/grouper.js +76 -0
  40. package/dist/core/export/index.d.ts +45 -0
  41. package/dist/core/export/index.js +63 -0
  42. package/dist/core/export/types.d.ts +84 -0
  43. package/dist/core/export/types.js +25 -0
  44. package/dist/core/fixtures/empty-catalogs/postgres-15-16-baseline.json +287 -0
  45. package/dist/core/integrations/filter/dsl.d.ts +38 -1
  46. package/dist/core/integrations/filter/dsl.js +20 -2
  47. package/dist/core/integrations/filter/extractors.js +42 -0
  48. package/dist/core/integrations/integration-dsl.d.ts +10 -0
  49. package/dist/core/integrations/supabase.d.ts +8 -0
  50. package/dist/core/integrations/supabase.js +9 -0
  51. package/dist/core/objects/aggregate/aggregate.diff.d.ts +2 -8
  52. package/dist/core/objects/aggregate/aggregate.diff.js +16 -70
  53. package/dist/core/objects/aggregate/aggregate.model.d.ts +8 -8
  54. package/dist/core/objects/aggregate/aggregate.model.js +1 -1
  55. package/dist/core/objects/aggregate/changes/aggregate.create.js +1 -1
  56. package/dist/core/objects/aggregate/changes/aggregate.drop.js +1 -1
  57. package/dist/core/objects/base.privilege-diff.d.ts +38 -13
  58. package/dist/core/objects/base.privilege-diff.js +104 -22
  59. package/dist/core/objects/base.privilege.d.ts +1 -0
  60. package/dist/core/objects/base.privilege.js +9 -2
  61. package/dist/core/objects/collation/collation.diff.d.ts +2 -3
  62. package/dist/core/objects/diff-context.d.ts +15 -0
  63. package/dist/core/objects/diff-context.js +1 -0
  64. package/dist/core/objects/domain/changes/domain.create.js +4 -2
  65. package/dist/core/objects/domain/domain.diff.d.ts +2 -8
  66. package/dist/core/objects/domain/domain.diff.js +16 -77
  67. package/dist/core/objects/domain/domain.model.js +1 -1
  68. package/dist/core/objects/event-trigger/event-trigger.diff.d.ts +2 -3
  69. package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.d.ts +2 -8
  70. package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.js +13 -77
  71. package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.js +2 -2
  72. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.d.ts +2 -8
  73. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.js +16 -77
  74. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.js +1 -1
  75. package/dist/core/objects/foreign-data-wrapper/server/server.diff.d.ts +2 -8
  76. package/dist/core/objects/foreign-data-wrapper/server/server.diff.js +13 -77
  77. package/dist/core/objects/language/language.diff.d.ts +2 -5
  78. package/dist/core/objects/language/language.diff.js +7 -39
  79. package/dist/core/objects/materialized-view/materialized-view.diff.d.ts +2 -8
  80. package/dist/core/objects/materialized-view/materialized-view.diff.js +16 -158
  81. package/dist/core/objects/materialized-view/materialized-view.model.d.ts +3 -3
  82. package/dist/core/objects/materialized-view/materialized-view.model.js +1 -1
  83. package/dist/core/objects/procedure/changes/procedure.alter.js +12 -12
  84. package/dist/core/objects/procedure/procedure.diff.d.ts +2 -8
  85. package/dist/core/objects/procedure/procedure.diff.js +16 -77
  86. package/dist/core/objects/procedure/procedure.model.d.ts +9 -9
  87. package/dist/core/objects/procedure/procedure.model.js +1 -1
  88. package/dist/core/objects/publication/changes/publication.alter.d.ts +0 -9
  89. package/dist/core/objects/publication/changes/publication.alter.js +0 -14
  90. package/dist/core/objects/publication/changes/publication.types.d.ts +2 -2
  91. package/dist/core/objects/publication/publication.diff.d.ts +2 -3
  92. package/dist/core/objects/publication/publication.diff.js +8 -13
  93. package/dist/core/objects/rls-policy/changes/rls-policy.alter.js +3 -3
  94. package/dist/core/objects/rls-policy/rls-policy.model.d.ts +2 -2
  95. package/dist/core/objects/role/role.diff.js +22 -1
  96. package/dist/core/objects/role/role.model.d.ts +4 -3
  97. package/dist/core/objects/role/role.model.js +118 -12
  98. package/dist/core/objects/rule/rule.model.d.ts +1 -1
  99. package/dist/core/objects/schema/schema.diff.d.ts +2 -8
  100. package/dist/core/objects/schema/schema.diff.js +16 -77
  101. package/dist/core/objects/schema/schema.model.js +1 -1
  102. package/dist/core/objects/sequence/sequence.diff.d.ts +2 -8
  103. package/dist/core/objects/sequence/sequence.diff.js +16 -79
  104. package/dist/core/objects/sequence/sequence.model.js +1 -1
  105. package/dist/core/objects/subscription/subscription.diff.d.ts +2 -3
  106. package/dist/core/objects/table/changes/table.create.js +3 -0
  107. package/dist/core/objects/table/table.diff.d.ts +2 -8
  108. package/dist/core/objects/table/table.diff.js +26 -157
  109. package/dist/core/objects/table/table.model.d.ts +23 -22
  110. package/dist/core/objects/table/table.model.js +1 -1
  111. package/dist/core/objects/trigger/changes/trigger.create.js +2 -4
  112. package/dist/core/objects/trigger/trigger.model.d.ts +8 -0
  113. package/dist/core/objects/trigger/trigger.model.js +11 -0
  114. package/dist/core/objects/type/composite-type/composite-type.diff.d.ts +2 -8
  115. package/dist/core/objects/type/composite-type/composite-type.diff.js +16 -77
  116. package/dist/core/objects/type/composite-type/composite-type.model.d.ts +3 -3
  117. package/dist/core/objects/type/composite-type/composite-type.model.js +2 -1
  118. package/dist/core/objects/type/enum/enum.diff.d.ts +2 -8
  119. package/dist/core/objects/type/enum/enum.diff.js +25 -112
  120. package/dist/core/objects/type/enum/enum.model.js +1 -1
  121. package/dist/core/objects/type/range/changes/range.create.js +6 -3
  122. package/dist/core/objects/type/range/range.diff.d.ts +2 -8
  123. package/dist/core/objects/type/range/range.diff.js +16 -77
  124. package/dist/core/objects/type/range/range.model.js +1 -1
  125. package/dist/core/objects/view/view.diff.d.ts +2 -8
  126. package/dist/core/objects/view/view.diff.js +16 -158
  127. package/dist/core/objects/view/view.model.d.ts +18 -4
  128. package/dist/core/objects/view/view.model.js +3 -13
  129. package/dist/core/plan/apply.js +9 -26
  130. package/dist/core/plan/create.d.ts +19 -6
  131. package/dist/core/plan/create.js +134 -174
  132. package/dist/core/plan/serialize.js +16 -4
  133. package/dist/core/plan/sql-format/fixtures.js +3 -5
  134. package/dist/core/plan/sql-format/keyword-case.js +26 -1
  135. package/dist/core/plan/ssl-config.d.ts +32 -0
  136. package/dist/core/plan/ssl-config.js +115 -0
  137. package/dist/core/plan/types.d.ts +6 -0
  138. package/dist/core/postgres-config.d.ts +14 -0
  139. package/dist/core/postgres-config.js +53 -2
  140. package/dist/core/sort/graph-builder.js +10 -0
  141. package/dist/core/sort/logical-sort.js +31 -23
  142. package/dist/core/test-utils/assert-valid-sql.d.ts +10 -0
  143. package/dist/core/test-utils/assert-valid-sql.js +19 -0
  144. package/dist/index.d.ts +6 -0
  145. package/dist/index.js +6 -1
  146. package/package.json +21 -4
  147. package/src/cli/app.ts +27 -3
  148. package/src/cli/bin/cli.ts +6 -0
  149. package/src/cli/commands/catalog-export.ts +78 -0
  150. package/src/cli/commands/declarative-apply.diagnostics.test.ts +77 -0
  151. package/src/cli/commands/declarative-apply.ts +380 -0
  152. package/src/cli/commands/declarative-export.ts +330 -0
  153. package/src/cli/commands/plan.ts +28 -7
  154. package/src/cli/exit-code.test.ts +19 -0
  155. package/src/cli/exit-code.ts +7 -0
  156. package/src/cli/formatters/tree/tree.ts +3 -2
  157. package/src/cli/utils/apply-display.test.ts +348 -0
  158. package/src/cli/utils/apply-display.ts +238 -0
  159. package/src/cli/utils/export-display.test.ts +103 -0
  160. package/src/cli/utils/export-display.ts +275 -0
  161. package/src/cli/utils/integrations.test.ts +44 -0
  162. package/src/cli/utils/resolve-input.test.ts +38 -0
  163. package/src/cli/utils/resolve-input.ts +17 -0
  164. package/src/core/catalog-export/index.ts +20 -0
  165. package/src/core/catalog.diff.ts +79 -78
  166. package/src/core/catalog.model.test.ts +122 -0
  167. package/src/core/catalog.model.ts +127 -1
  168. package/src/core/catalog.snapshot.test.ts +464 -0
  169. package/src/core/catalog.snapshot.ts +289 -0
  170. package/src/core/declarative-apply/discover-sql.test.ts +103 -0
  171. package/src/core/declarative-apply/discover-sql.ts +107 -0
  172. package/src/core/declarative-apply/extract-catalog-providers.ts +220 -0
  173. package/src/core/declarative-apply/index.test.ts +67 -0
  174. package/src/core/declarative-apply/index.ts +205 -0
  175. package/src/core/declarative-apply/round-apply.test.ts +504 -0
  176. package/src/core/declarative-apply/round-apply.ts +562 -0
  177. package/src/core/expand-replace-dependencies.test.ts +70 -0
  178. package/src/core/export/file-mapper.test.ts +816 -0
  179. package/src/core/export/file-mapper.ts +574 -0
  180. package/src/core/export/grouper.ts +108 -0
  181. package/src/core/export/index.ts +129 -0
  182. package/src/core/export/types.ts +104 -0
  183. package/src/core/fixtures/empty-catalogs/postgres-15-16-baseline.json +287 -0
  184. package/src/core/integrations/filter/dsl.test.ts +211 -0
  185. package/src/core/integrations/filter/dsl.ts +65 -3
  186. package/src/core/integrations/filter/extractors.test.ts +244 -0
  187. package/src/core/integrations/filter/extractors.ts +42 -0
  188. package/src/core/integrations/integration-dsl.ts +10 -0
  189. package/src/core/integrations/serialize/dsl.test.ts +91 -0
  190. package/src/core/integrations/supabase.ts +9 -0
  191. package/src/core/objects/aggregate/aggregate.diff.ts +39 -95
  192. package/src/core/objects/aggregate/aggregate.model.ts +1 -1
  193. package/src/core/objects/aggregate/changes/aggregate.alter.test.ts +3 -1
  194. package/src/core/objects/aggregate/changes/aggregate.comment.test.ts +5 -2
  195. package/src/core/objects/aggregate/changes/aggregate.create.test.ts +6 -3
  196. package/src/core/objects/aggregate/changes/aggregate.create.ts +1 -1
  197. package/src/core/objects/aggregate/changes/aggregate.drop.test.ts +7 -3
  198. package/src/core/objects/aggregate/changes/aggregate.drop.ts +1 -1
  199. package/src/core/objects/aggregate/changes/aggregate.privilege.test.ts +9 -3
  200. package/src/core/objects/base.privilege-diff.ts +178 -30
  201. package/src/core/objects/base.privilege.ts +9 -2
  202. package/src/core/objects/collation/changes/collation.alter.test.ts +7 -2
  203. package/src/core/objects/collation/changes/collation.create.test.ts +7 -2
  204. package/src/core/objects/collation/changes/collation.drop.test.ts +4 -1
  205. package/src/core/objects/collation/collation.diff.test.ts +9 -12
  206. package/src/core/objects/collation/collation.diff.ts +2 -1
  207. package/src/core/objects/diff-context.ts +16 -0
  208. package/src/core/objects/domain/changes/domain.alter.test.ts +28 -9
  209. package/src/core/objects/domain/changes/domain.create.test.ts +32 -2
  210. package/src/core/objects/domain/changes/domain.create.ts +7 -1
  211. package/src/core/objects/domain/changes/domain.drop.test.ts +4 -1
  212. package/src/core/objects/domain/domain.diff.ts +39 -102
  213. package/src/core/objects/domain/domain.model.ts +1 -1
  214. package/src/core/objects/event-trigger/changes/event-trigger.alter.test.ts +10 -3
  215. package/src/core/objects/event-trigger/changes/event-trigger.create.test.ts +4 -1
  216. package/src/core/objects/event-trigger/changes/event-trigger.drop.test.ts +4 -1
  217. package/src/core/objects/event-trigger/event-trigger.diff.test.ts +12 -7
  218. package/src/core/objects/event-trigger/event-trigger.diff.ts +2 -1
  219. package/src/core/objects/extension/changes/extension.alter.test.ts +7 -2
  220. package/src/core/objects/extension/changes/extension.create.test.ts +4 -1
  221. package/src/core/objects/extension/changes/extension.drop.test.ts +4 -1
  222. package/src/core/objects/extension/extension.model.test.ts +98 -0
  223. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.test.ts +16 -5
  224. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.test.ts +51 -16
  225. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.test.ts +4 -1
  226. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.test.ts +111 -4
  227. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.ts +31 -101
  228. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.ts +2 -2
  229. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.test.ts +46 -15
  230. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.test.ts +13 -4
  231. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.test.ts +4 -1
  232. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +39 -102
  233. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +1 -1
  234. package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.test.ts +22 -7
  235. package/src/core/objects/foreign-data-wrapper/server/changes/server.create.test.ts +19 -6
  236. package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.test.ts +4 -1
  237. package/src/core/objects/foreign-data-wrapper/server/server.diff.test.ts +95 -0
  238. package/src/core/objects/foreign-data-wrapper/server/server.diff.ts +31 -101
  239. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.test.ts +13 -4
  240. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.test.ts +16 -5
  241. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.test.ts +10 -3
  242. package/src/core/objects/index/changes/index.alter.test.ts +13 -4
  243. package/src/core/objects/index/changes/index.create.test.ts +4 -1
  244. package/src/core/objects/index/changes/index.drop.test.ts +4 -1
  245. package/src/core/objects/language/changes/language.alter.test.ts +4 -1
  246. package/src/core/objects/language/changes/language.create.test.ts +4 -1
  247. package/src/core/objects/language/changes/language.drop.test.ts +4 -1
  248. package/src/core/objects/language/language.diff.test.ts +86 -4
  249. package/src/core/objects/language/language.diff.ts +17 -49
  250. package/src/core/objects/materialized-view/changes/materialized-view.alter.test.ts +10 -3
  251. package/src/core/objects/materialized-view/changes/materialized-view.create.test.ts +7 -2
  252. package/src/core/objects/materialized-view/changes/materialized-view.drop.test.ts +4 -1
  253. package/src/core/objects/materialized-view/materialized-view.diff.test.ts +162 -0
  254. package/src/core/objects/materialized-view/materialized-view.diff.ts +41 -191
  255. package/src/core/objects/materialized-view/materialized-view.model.ts +1 -1
  256. package/src/core/objects/procedure/changes/procedure.alter.test.ts +121 -49
  257. package/src/core/objects/procedure/changes/procedure.alter.ts +15 -12
  258. package/src/core/objects/procedure/changes/procedure.create.test.ts +4 -1
  259. package/src/core/objects/procedure/changes/procedure.drop.test.ts +7 -2
  260. package/src/core/objects/procedure/procedure.diff.ts +39 -102
  261. package/src/core/objects/procedure/procedure.model.ts +1 -1
  262. package/src/core/objects/publication/changes/publication.alter.test.ts +15 -21
  263. package/src/core/objects/publication/changes/publication.alter.ts +0 -18
  264. package/src/core/objects/publication/changes/publication.comment.test.ts +5 -2
  265. package/src/core/objects/publication/changes/publication.create.test.ts +5 -2
  266. package/src/core/objects/publication/changes/publication.drop.test.ts +3 -1
  267. package/src/core/objects/publication/changes/publication.types.ts +0 -2
  268. package/src/core/objects/publication/publication.diff.test.ts +24 -19
  269. package/src/core/objects/publication/publication.diff.ts +9 -15
  270. package/src/core/objects/rls-policy/changes/rls-policy.alter.test.ts +31 -14
  271. package/src/core/objects/rls-policy/changes/rls-policy.alter.ts +3 -3
  272. package/src/core/objects/rls-policy/changes/rls-policy.create.test.ts +10 -3
  273. package/src/core/objects/rls-policy/changes/rls-policy.drop.test.ts +4 -1
  274. package/src/core/objects/role/changes/role.alter.test.ts +31 -15
  275. package/src/core/objects/role/changes/role.create.test.ts +6 -2
  276. package/src/core/objects/role/changes/role.drop.test.ts +4 -1
  277. package/src/core/objects/role/role.diff.test.ts +235 -0
  278. package/src/core/objects/role/role.diff.ts +21 -1
  279. package/src/core/objects/role/role.model.ts +122 -14
  280. package/src/core/objects/rule/changes/rule.alter.test.ts +7 -3
  281. package/src/core/objects/rule/changes/rule.comment.test.ts +5 -2
  282. package/src/core/objects/rule/changes/rule.create.test.ts +6 -2
  283. package/src/core/objects/rule/changes/rule.drop.test.ts +3 -1
  284. package/src/core/objects/schema/changes/schema.alter.test.ts +4 -1
  285. package/src/core/objects/schema/changes/schema.create.test.ts +4 -1
  286. package/src/core/objects/schema/changes/schema.drop.test.ts +4 -1
  287. package/src/core/objects/schema/schema.diff.ts +39 -102
  288. package/src/core/objects/schema/schema.model.ts +1 -1
  289. package/src/core/objects/sequence/changes/sequence.alter.test.ts +11 -5
  290. package/src/core/objects/sequence/changes/sequence.create.test.ts +8 -3
  291. package/src/core/objects/sequence/changes/sequence.drop.test.ts +4 -1
  292. package/src/core/objects/sequence/sequence.diff.test.ts +114 -0
  293. package/src/core/objects/sequence/sequence.diff.ts +39 -104
  294. package/src/core/objects/sequence/sequence.model.ts +1 -1
  295. package/src/core/objects/subscription/changes/subscription.alter.test.ts +15 -5
  296. package/src/core/objects/subscription/changes/subscription.comment.test.ts +5 -2
  297. package/src/core/objects/subscription/changes/subscription.create.test.ts +5 -2
  298. package/src/core/objects/subscription/changes/subscription.drop.test.ts +3 -1
  299. package/src/core/objects/subscription/subscription.diff.test.ts +16 -11
  300. package/src/core/objects/subscription/subscription.diff.ts +2 -1
  301. package/src/core/objects/table/changes/table.alter.test.ts +38 -15
  302. package/src/core/objects/table/changes/table.create.test.ts +41 -3
  303. package/src/core/objects/table/changes/table.create.ts +4 -0
  304. package/src/core/objects/table/changes/table.drop.test.ts +3 -1
  305. package/src/core/objects/table/table.diff.test.ts +157 -0
  306. package/src/core/objects/table/table.diff.ts +54 -190
  307. package/src/core/objects/table/table.model.ts +1 -1
  308. package/src/core/objects/trigger/changes/trigger.alter.test.ts +8 -4
  309. package/src/core/objects/trigger/changes/trigger.create.test.ts +5 -1
  310. package/src/core/objects/trigger/changes/trigger.create.ts +7 -4
  311. package/src/core/objects/trigger/changes/trigger.drop.test.ts +5 -1
  312. package/src/core/objects/trigger/trigger.diff.test.ts +1 -0
  313. package/src/core/objects/trigger/trigger.model.ts +12 -0
  314. package/src/core/objects/type/composite-type/changes/composite-type.alter.test.ts +10 -4
  315. package/src/core/objects/type/composite-type/changes/composite-type.create.test.ts +7 -2
  316. package/src/core/objects/type/composite-type/changes/composite-type.drop.test.ts +4 -1
  317. package/src/core/objects/type/composite-type/composite-type.diff.test.ts +78 -0
  318. package/src/core/objects/type/composite-type/composite-type.diff.ts +39 -101
  319. package/src/core/objects/type/composite-type/composite-type.model.ts +2 -1
  320. package/src/core/objects/type/enum/changes/enum.alter.test.ts +14 -5
  321. package/src/core/objects/type/enum/changes/enum.create.test.ts +4 -1
  322. package/src/core/objects/type/enum/changes/enum.drop.test.ts +4 -1
  323. package/src/core/objects/type/enum/enum.diff.test.ts +181 -0
  324. package/src/core/objects/type/enum/enum.diff.ts +58 -146
  325. package/src/core/objects/type/enum/enum.model.ts +1 -1
  326. package/src/core/objects/type/range/changes/range.alter.test.ts +3 -1
  327. package/src/core/objects/type/range/changes/range.create.test.ts +5 -2
  328. package/src/core/objects/type/range/changes/range.create.ts +6 -2
  329. package/src/core/objects/type/range/changes/range.drop.test.ts +3 -1
  330. package/src/core/objects/type/range/range.diff.test.ts +77 -0
  331. package/src/core/objects/type/range/range.diff.ts +39 -101
  332. package/src/core/objects/type/range/range.model.ts +1 -1
  333. package/src/core/objects/view/changes/view.alter.test.ts +8 -3
  334. package/src/core/objects/view/changes/view.create.test.ts +7 -2
  335. package/src/core/objects/view/changes/view.drop.test.ts +4 -1
  336. package/src/core/objects/view/view.diff.test.ts +82 -0
  337. package/src/core/objects/view/view.diff.ts +41 -191
  338. package/src/core/objects/view/view.model.ts +3 -17
  339. package/src/core/plan/apply.ts +9 -27
  340. package/src/core/plan/create.ts +173 -237
  341. package/src/core/plan/serialize.test.ts +317 -0
  342. package/src/core/plan/serialize.ts +18 -4
  343. package/src/core/plan/sql-format/fixtures.ts +2 -5
  344. package/src/core/plan/sql-format/format-lowercase-coverage.test.ts +52 -0
  345. package/src/core/plan/sql-format/format-off.test.ts +14 -17
  346. package/src/core/plan/sql-format/format-pretty-lower-leading.test.ts +27 -22
  347. package/src/core/plan/sql-format/format-pretty-narrow.test.ts +17 -21
  348. package/src/core/plan/sql-format/format-pretty-preserve.test.ts +25 -20
  349. package/src/core/plan/sql-format/format-pretty-upper.test.ts +23 -20
  350. package/src/core/plan/sql-format/keyword-case.ts +36 -1
  351. package/src/core/plan/ssl-config.ts +172 -0
  352. package/src/core/plan/types.ts +6 -0
  353. package/src/core/postgres-config.ts +71 -2
  354. package/src/core/sort/graph-builder.ts +12 -0
  355. package/src/core/sort/logical-sort.test.ts +371 -0
  356. package/src/core/sort/logical-sort.ts +32 -25
  357. package/src/core/sort/topological-sort.test.ts +275 -0
  358. package/src/core/test-utils/assert-valid-sql.ts +20 -0
  359. package/src/index.ts +26 -2
@@ -0,0 +1,91 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import type { Change } from "../../change.types.ts";
3
+ import { compileSerializeDSL } from "./dsl.ts";
4
+
5
+ function makeChange(
6
+ type: string,
7
+ operation: string,
8
+ serializeFn: (opts?: Record<string, unknown>) => string,
9
+ ): Change {
10
+ return {
11
+ objectType: type,
12
+ operation,
13
+ scope: "object",
14
+ schema: { name: "test" },
15
+ serialize: serializeFn,
16
+ } as unknown as Change;
17
+ }
18
+
19
+ describe("compileSerializeDSL", () => {
20
+ test("matching rule applies its options", () => {
21
+ const serializer = compileSerializeDSL([
22
+ {
23
+ when: { type: "schema" as const, operation: "create" as const },
24
+ options: { skipAuthorization: true },
25
+ },
26
+ ]);
27
+
28
+ const change = makeChange("schema", "create", (opts) =>
29
+ opts?.skipAuthorization
30
+ ? "CREATE SCHEMA test"
31
+ : "CREATE SCHEMA test AUTHORIZATION owner",
32
+ );
33
+
34
+ expect(serializer(change)).toBe("CREATE SCHEMA test");
35
+ });
36
+
37
+ test("no matching rule uses default serialization", () => {
38
+ const serializer = compileSerializeDSL([
39
+ {
40
+ when: { type: "table" as const },
41
+ options: { skipAuthorization: true },
42
+ },
43
+ ]);
44
+
45
+ const change = makeChange("schema", "create", (opts) =>
46
+ opts?.skipAuthorization
47
+ ? "CREATE SCHEMA test"
48
+ : "CREATE SCHEMA test AUTHORIZATION owner",
49
+ );
50
+
51
+ expect(serializer(change)).toBe("CREATE SCHEMA test AUTHORIZATION owner");
52
+ });
53
+
54
+ test("first matching rule wins", () => {
55
+ const serializer = compileSerializeDSL([
56
+ {
57
+ when: { type: "schema" as const },
58
+ options: { skipAuthorization: true },
59
+ },
60
+ {
61
+ when: { type: "schema" as const },
62
+ options: { skipAuthorization: false },
63
+ },
64
+ ]);
65
+
66
+ const change = makeChange("schema", "create", (opts) =>
67
+ opts?.skipAuthorization ? "WITHOUT AUTH" : "WITH AUTH",
68
+ );
69
+
70
+ expect(serializer(change)).toBe("WITHOUT AUTH");
71
+ });
72
+
73
+ test("skips non-matching first rule and applies second", () => {
74
+ const serializer = compileSerializeDSL([
75
+ {
76
+ when: { type: "table" as const },
77
+ options: { skipAuthorization: true },
78
+ },
79
+ {
80
+ when: { type: "schema" as const },
81
+ options: { skipAuthorization: false },
82
+ },
83
+ ]);
84
+
85
+ const change = makeChange("schema", "create", (opts) =>
86
+ opts?.skipAuthorization ? "WITHOUT AUTH" : "WITH AUTH",
87
+ );
88
+
89
+ expect(serializer(change)).toBe("WITH AUTH");
90
+ });
91
+ });
@@ -58,7 +58,16 @@ const SUPABASE_SYSTEM_ROLES = [
58
58
  "supabase_superuser",
59
59
  ] as const;
60
60
 
61
+ /**
62
+ * To generate the emptyCatalog snapshot, run catalog-export against a fresh
63
+ * supabase/postgres container:
64
+ *
65
+ * pgdelta catalog-export --target postgres://postgres:postgres@localhost:54322/postgres --output supabase-baseline.json
66
+ *
67
+ * Then import and assign the JSON content to the emptyCatalog field below.
68
+ */
61
69
  export const supabase: IntegrationDSL = {
70
+ // TODO: emptyCatalog: undefined -- populate by running catalog-export on a clean Supabase container
62
71
  filter: {
63
72
  or: [
64
73
  {
@@ -1,11 +1,10 @@
1
- import type { DefaultPrivilegeState } from "../base.default-privileges.ts";
2
1
  import { diffObjects } from "../base.diff.ts";
3
2
  import {
4
3
  diffPrivileges,
4
+ emitObjectPrivilegeChanges,
5
5
  filterPublicBuiltInDefaults,
6
- groupPrivilegesByGrantable,
7
6
  } from "../base.privilege-diff.ts";
8
- import type { Role } from "../role/role.model.ts";
7
+ import type { ObjectDiffContext } from "../diff-context.ts";
9
8
  import { deepEqual, hasNonAlterableChanges } from "../utils.ts";
10
9
  import type { Aggregate } from "./aggregate.model.ts";
11
10
  import { AlterAggregateChangeOwner } from "./changes/aggregate.alter.ts";
@@ -23,12 +22,10 @@ import {
23
22
  import type { AggregateChange } from "./changes/aggregate.types.ts";
24
23
 
25
24
  export function diffAggregates(
26
- ctx: {
27
- version: number;
28
- currentUser: string;
29
- defaultPrivilegeState: DefaultPrivilegeState;
30
- mainRoles: Record<string, Role>;
31
- },
25
+ ctx: Pick<
26
+ ObjectDiffContext,
27
+ "version" | "currentUser" | "defaultPrivilegeState"
28
+ >,
32
29
  main: Record<string, Aggregate>,
33
30
  branch: Record<string, Aggregate>,
34
31
  ): AggregateChange[] {
@@ -65,6 +62,10 @@ export function diffAggregates(
65
62
  "aggregate",
66
63
  aggregate.schema ?? "",
67
64
  );
65
+ const creatorFilteredDefaults =
66
+ aggregate.owner !== ctx.currentUser
67
+ ? effectiveDefaults.filter((p) => p.grantee !== ctx.currentUser)
68
+ : effectiveDefaults;
68
69
  // Filter out PUBLIC's built-in default EXECUTE privilege (PostgreSQL grants it automatically)
69
70
  // Reference: https://www.postgresql.org/docs/17/ddl-priv.html Table 5.2
70
71
  // This prevents generating unnecessary "GRANT EXECUTE TO PUBLIC" statements
@@ -75,55 +76,25 @@ export function diffAggregates(
75
76
  // Filter out owner privileges - owner always has ALL privileges implicitly
76
77
  // and shouldn't be compared. Use the aggregate owner as the reference.
77
78
  const privilegeResults = diffPrivileges(
78
- effectiveDefaults,
79
+ filterPublicBuiltInDefaults("aggregate", creatorFilteredDefaults),
79
80
  desiredPrivileges,
80
81
  aggregate.owner,
81
- ctx.mainRoles,
82
82
  );
83
83
 
84
- // Generate grant changes
85
- for (const [grantee, result] of privilegeResults) {
86
- if (result.grants.length > 0) {
87
- const grantGroups = groupPrivilegesByGrantable(result.grants);
88
- for (const [, list] of grantGroups) {
89
- changes.push(
90
- new GrantAggregatePrivileges({
91
- aggregate,
92
- grantee,
93
- privileges: list,
94
- version: ctx.version,
95
- }),
96
- );
97
- }
98
- }
99
-
100
- // Generate revoke changes
101
- if (result.revokes.length > 0) {
102
- const revokeGroups = groupPrivilegesByGrantable(result.revokes);
103
- for (const [, list] of revokeGroups) {
104
- changes.push(
105
- new RevokeAggregatePrivileges({
106
- aggregate,
107
- grantee,
108
- privileges: list,
109
- version: ctx.version,
110
- }),
111
- );
112
- }
113
- }
114
-
115
- // Generate revoke grant option changes
116
- if (result.revokeGrantOption.length > 0) {
117
- changes.push(
118
- new RevokeGrantOptionAggregatePrivileges({
119
- aggregate,
120
- grantee,
121
- privilegeNames: result.revokeGrantOption,
122
- version: ctx.version,
123
- }),
124
- );
125
- }
126
- }
84
+ changes.push(
85
+ ...(emitObjectPrivilegeChanges(
86
+ privilegeResults,
87
+ aggregate,
88
+ aggregate,
89
+ "aggregate",
90
+ {
91
+ Grant: GrantAggregatePrivileges,
92
+ Revoke: RevokeAggregatePrivileges,
93
+ RevokeGrantOption: RevokeGrantOptionAggregatePrivileges,
94
+ },
95
+ ctx.version,
96
+ ) as AggregateChange[]),
97
+ );
127
98
  }
128
99
 
129
100
  for (const aggregateId of dropped) {
@@ -229,49 +200,22 @@ export function diffAggregates(
229
200
  mainPrivilegesFiltered,
230
201
  branchPrivilegesFiltered,
231
202
  branchAggregate.owner,
232
- ctx.mainRoles,
233
203
  );
234
204
 
235
- for (const [grantee, result] of privilegeResults) {
236
- if (result.grants.length > 0) {
237
- const grantGroups = groupPrivilegesByGrantable(result.grants);
238
- for (const [, list] of grantGroups) {
239
- changes.push(
240
- new GrantAggregatePrivileges({
241
- aggregate: branchAggregate,
242
- grantee,
243
- privileges: list,
244
- version: ctx.version,
245
- }),
246
- );
247
- }
248
- }
249
-
250
- if (result.revokes.length > 0) {
251
- const revokeGroups = groupPrivilegesByGrantable(result.revokes);
252
- for (const [, list] of revokeGroups) {
253
- changes.push(
254
- new RevokeAggregatePrivileges({
255
- aggregate: mainAggregate,
256
- grantee,
257
- privileges: list,
258
- version: ctx.version,
259
- }),
260
- );
261
- }
262
- }
263
-
264
- if (result.revokeGrantOption.length > 0) {
265
- changes.push(
266
- new RevokeGrantOptionAggregatePrivileges({
267
- aggregate: mainAggregate,
268
- grantee,
269
- privilegeNames: result.revokeGrantOption,
270
- version: ctx.version,
271
- }),
272
- );
273
- }
274
- }
205
+ changes.push(
206
+ ...(emitObjectPrivilegeChanges(
207
+ privilegeResults,
208
+ branchAggregate,
209
+ mainAggregate,
210
+ "aggregate",
211
+ {
212
+ Grant: GrantAggregatePrivileges,
213
+ Revoke: RevokeAggregatePrivileges,
214
+ RevokeGrantOption: RevokeGrantOptionAggregatePrivileges,
215
+ },
216
+ ctx.version,
217
+ ) as AggregateChange[]),
218
+ );
275
219
  }
276
220
 
277
221
  return changes;
@@ -292,7 +292,7 @@ select
292
292
  )
293
293
  order by x.grantee, x.privilege_type
294
294
  )
295
- from lateral aclexplode(p.proacl) as x(grantor, grantee, privilege_type, is_grantable)
295
+ from lateral aclexplode(COALESCE(p.proacl, acldefault('f', p.proowner))) as x(grantor, grantee, privilege_type, is_grantable)
296
296
  ), '[]'
297
297
  ) as privileges
298
298
  from
@@ -1,4 +1,5 @@
1
1
  import { describe, expect, test } from "bun:test";
2
+ import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
2
3
  import { Aggregate } from "../aggregate.model.ts";
3
4
  import { AlterAggregateChangeOwner } from "./aggregate.alter.ts";
4
5
 
@@ -49,7 +50,7 @@ const base: AggregateProps = {
49
50
  };
50
51
 
51
52
  describe("aggregate.alter", () => {
52
- test("serialize owner change", () => {
53
+ test("serialize owner change", async () => {
53
54
  const aggregate = new Aggregate(base);
54
55
  const change = new AlterAggregateChangeOwner({
55
56
  aggregate,
@@ -57,6 +58,7 @@ describe("aggregate.alter", () => {
57
58
  });
58
59
 
59
60
  expect(change.requires).toEqual([aggregate.stableId]);
61
+ await assertValidSql(change.serialize());
60
62
  expect(change.serialize()).toBe(
61
63
  "ALTER AGGREGATE public.agg_sum(integer) OWNER TO owner2",
62
64
  );
@@ -1,4 +1,5 @@
1
1
  import { describe, expect, test } from "bun:test";
2
+ import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
2
3
  import { stableId } from "../../utils.ts";
3
4
  import { Aggregate } from "../aggregate.model.ts";
4
5
  import {
@@ -59,18 +60,19 @@ const makeAggregate = (override: Partial<AggregateProps> = {}) =>
59
60
  });
60
61
 
61
62
  describe("aggregate.comment", () => {
62
- test("create comment serializes and tracks dependencies", () => {
63
+ test("create comment serializes and tracks dependencies", async () => {
63
64
  const aggregate = makeAggregate({ comment: "aggregate's total" });
64
65
  const change = new CreateCommentOnAggregate({ aggregate });
65
66
 
66
67
  expect(change.creates).toEqual([stableId.comment(aggregate.stableId)]);
67
68
  expect(change.requires).toEqual([aggregate.stableId]);
69
+ await assertValidSql(change.serialize());
68
70
  expect(change.serialize()).toBe(
69
71
  "COMMENT ON AGGREGATE public.agg_sum(integer) IS 'aggregate''s total'",
70
72
  );
71
73
  });
72
74
 
73
- test("drop comment serializes and tracks dependencies", () => {
75
+ test("drop comment serializes and tracks dependencies", async () => {
74
76
  const aggregate = makeAggregate({ comment: "some comment" });
75
77
  const change = new DropCommentOnAggregate({ aggregate });
76
78
 
@@ -79,6 +81,7 @@ describe("aggregate.comment", () => {
79
81
  stableId.comment(aggregate.stableId),
80
82
  aggregate.stableId,
81
83
  ]);
84
+ await assertValidSql(change.serialize());
82
85
  expect(change.serialize()).toBe(
83
86
  "COMMENT ON AGGREGATE public.agg_sum(integer) IS NULL",
84
87
  );
@@ -1,4 +1,5 @@
1
1
  import { describe, expect, test } from "bun:test";
2
+ import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
2
3
  import { Aggregate } from "../aggregate.model.ts";
3
4
  import { CreateAggregate } from "./aggregate.create.ts";
4
5
 
@@ -55,17 +56,18 @@ const makeAggregate = (override: Partial<AggregateProps> = {}) =>
55
56
  });
56
57
 
57
58
  describe("aggregate.create", () => {
58
- test("serialize minimal aggregate", () => {
59
+ test("serialize minimal aggregate", async () => {
59
60
  const aggregate = makeAggregate();
60
61
  const change = new CreateAggregate({ aggregate });
61
62
 
62
63
  expect(change.creates).toEqual([aggregate.stableId]);
64
+ await assertValidSql(change.serialize());
63
65
  expect(change.serialize()).toMatchInlineSnapshot(
64
66
  `"CREATE AGGREGATE public.agg_sum(integer) (SFUNC = pg_catalog.int4pl, STYPE = integer)"`,
65
67
  );
66
68
  });
67
69
 
68
- test("serialize aggregate with optional clauses and or replace", () => {
70
+ test("serialize aggregate with optional clauses and or replace", async () => {
69
71
  const aggregate = makeAggregate({
70
72
  name: "agg_full",
71
73
  transition_function: "public.sum_int8(bigint,bigint)",
@@ -94,8 +96,9 @@ describe("aggregate.create", () => {
94
96
 
95
97
  const change = new CreateAggregate({ aggregate, orReplace: true });
96
98
 
99
+ await assertValidSql(change.serialize());
97
100
  expect(change.serialize()).toMatchInlineSnapshot(
98
- `"CREATE OR REPLACE AGGREGATE public.agg_full(integer) (SFUNC = public.sum_int8, STYPE = bigint, SSPACE = 8, FINALFUNC = public.finalize, FINALFUNC_EXTRA, FINALFUNC_MODIFY = READ_WRITE, COMBINEFUNC = public.combine, SERIALFUNC = public.serialize_state, DESERIALFUNC = public.deserialize_state, INITCOND = '0', MSFUNC = public.msum, MINVFUNC = public.minv, MSTYPE = pg_catalog.bigint, MSSPACE = 16, MFINALFUNC = public.mfinal, MFINALFUNC_EXTRA, MFINALFUNC_MODIFY = SHAREABLE, MINITCOND = '0', SORTOP = OPERATOR(pg_catalog.<), PARALLEL SAFE, STRICT, HYPOTHETICAL)"`,
101
+ `"CREATE OR REPLACE AGGREGATE public.agg_full(integer) (SFUNC = public.sum_int8, STYPE = bigint, SSPACE = 8, FINALFUNC = public.finalize, FINALFUNC_EXTRA, FINALFUNC_MODIFY = READ_WRITE, COMBINEFUNC = public.combine, SERIALFUNC = public.serialize_state, DESERIALFUNC = public.deserialize_state, INITCOND = '0', MSFUNC = public.msum, MINVFUNC = public.minv, MSTYPE = pg_catalog.bigint, MSSPACE = 16, MFINALFUNC = public.mfinal, MFINALFUNC_EXTRA, MFINALFUNC_MODIFY = SHAREABLE, MINITCOND = '0', SORTOP = OPERATOR(pg_catalog.<), PARALLEL = SAFE, STRICT, HYPOTHETICAL)"`,
99
102
  );
100
103
  });
101
104
  });
@@ -275,7 +275,7 @@ export class CreateAggregate extends CreateAggregateChange {
275
275
 
276
276
  if (this.aggregate.parallel_safety !== "u") {
277
277
  clauses.push(
278
- `PARALLEL ${formatParallel(this.aggregate.parallel_safety)}`,
278
+ `PARALLEL = ${formatParallel(this.aggregate.parallel_safety)}`,
279
279
  );
280
280
  }
281
281
 
@@ -1,4 +1,5 @@
1
1
  import { describe, expect, test } from "bun:test";
2
+ import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
2
3
  import { Aggregate } from "../aggregate.model.ts";
3
4
  import { DropAggregate } from "./aggregate.drop.ts";
4
5
 
@@ -55,16 +56,17 @@ const makeAggregate = (override: Partial<AggregateProps> = {}) =>
55
56
  });
56
57
 
57
58
  describe("aggregate.drop", () => {
58
- test("serialize drop for aggregate with arguments", () => {
59
+ test("serialize drop for aggregate with arguments", async () => {
59
60
  const aggregate = makeAggregate();
60
61
  const change = new DropAggregate({ aggregate });
61
62
 
62
63
  expect(change.drops).toEqual([aggregate.stableId]);
63
64
  expect(change.requires).toEqual([aggregate.stableId]);
65
+ await assertValidSql(change.serialize());
64
66
  expect(change.serialize()).toBe("DROP AGGREGATE public.agg_sum(integer)");
65
67
  });
66
68
 
67
- test("serialize drop for aggregate without arguments", () => {
69
+ test("serialize drop for aggregate without arguments", async () => {
68
70
  const aggregate = makeAggregate({
69
71
  name: "agg_no_args",
70
72
  identity_arguments: "",
@@ -73,6 +75,8 @@ describe("aggregate.drop", () => {
73
75
  });
74
76
  const change = new DropAggregate({ aggregate });
75
77
 
76
- expect(change.serialize()).toBe("DROP AGGREGATE public.agg_no_args()");
78
+ await assertValidSql(change.serialize());
79
+
80
+ expect(change.serialize()).toBe("DROP AGGREGATE public.agg_no_args(*)");
77
81
  });
78
82
  });
@@ -26,7 +26,7 @@ export class DropAggregate extends DropAggregateChange {
26
26
  serialize(): string {
27
27
  const signature = this.aggregate.identityArguments;
28
28
  const qualifiedName = `${this.aggregate.schema}.${this.aggregate.name}`;
29
- const withArgs = signature.length > 0 ? `(${signature})` : "()";
29
+ const withArgs = signature.length > 0 ? `(${signature})` : "(*)";
30
30
  return `DROP AGGREGATE ${qualifiedName}${withArgs}`;
31
31
  }
32
32
  }
@@ -1,4 +1,5 @@
1
1
  import { describe, expect, test } from "bun:test";
2
+ import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
2
3
  import { stableId } from "../../utils.ts";
3
4
  import { Aggregate } from "../aggregate.model.ts";
4
5
  import {
@@ -54,7 +55,7 @@ const base: AggregateProps = {
54
55
  };
55
56
 
56
57
  describe("aggregate.privilege", () => {
57
- test("grant privileges without grant option", () => {
58
+ test("grant privileges without grant option", async () => {
58
59
  const aggregate = new Aggregate(base);
59
60
  const change = new GrantAggregatePrivileges({
60
61
  aggregate,
@@ -70,12 +71,13 @@ describe("aggregate.privilege", () => {
70
71
  aggregate.stableId,
71
72
  stableId.role("role_exec"),
72
73
  ]);
74
+ await assertValidSql(change.serialize());
73
75
  expect(change.serialize()).toBe(
74
76
  "GRANT ALL ON FUNCTION public.agg_sum(integer) TO role_exec",
75
77
  );
76
78
  });
77
79
 
78
- test("grant privileges with grant option", () => {
80
+ test("grant privileges with grant option", async () => {
79
81
  const aggregate = new Aggregate(base);
80
82
  const change = new GrantAggregatePrivileges({
81
83
  aggregate,
@@ -83,12 +85,14 @@ describe("aggregate.privilege", () => {
83
85
  privileges: [{ privilege: "EXECUTE", grantable: true }],
84
86
  });
85
87
 
88
+ await assertValidSql(change.serialize());
89
+
86
90
  expect(change.serialize()).toBe(
87
91
  "GRANT ALL ON FUNCTION public.agg_sum(integer) TO role_exec WITH GRANT OPTION",
88
92
  );
89
93
  });
90
94
 
91
- test("revoke privileges and grant option", () => {
95
+ test("revoke privileges and grant option", async () => {
92
96
  const aggregate = new Aggregate(base);
93
97
  const revoke = new RevokeAggregatePrivileges({
94
98
  aggregate,
@@ -105,6 +109,7 @@ describe("aggregate.privilege", () => {
105
109
  aggregate.stableId,
106
110
  stableId.role("role_old"),
107
111
  ]);
112
+ await assertValidSql(revoke.serialize());
108
113
  expect(revoke.serialize()).toBe(
109
114
  "REVOKE ALL ON FUNCTION public.agg_sum(integer) FROM role_old",
110
115
  );
@@ -123,6 +128,7 @@ describe("aggregate.privilege", () => {
123
128
  aggregate.stableId,
124
129
  stableId.role("role_with_option"),
125
130
  ]);
131
+ await assertValidSql(revokeGrantOption.serialize());
126
132
  expect(revokeGrantOption.serialize()).toBe(
127
133
  "REVOKE GRANT OPTION FOR ALL ON FUNCTION public.agg_sum(integer) FROM role_with_option",
128
134
  );