@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,84 @@
1
+ /**
2
+ * Type definitions for declarative schema export.
3
+ */
4
+ export declare const CATEGORY_PRIORITY: {
5
+ readonly cluster: 0;
6
+ readonly schema: 1;
7
+ readonly extensions: 2;
8
+ readonly types: 3;
9
+ readonly sequences: 4;
10
+ readonly tables: 5;
11
+ readonly foreign_tables: 6;
12
+ readonly views: 7;
13
+ readonly matviews: 8;
14
+ readonly functions: 9;
15
+ readonly procedures: 10;
16
+ readonly aggregates: 11;
17
+ readonly domains: 12;
18
+ readonly collations: 13;
19
+ readonly publications: 14;
20
+ readonly subscriptions: 15;
21
+ readonly event_triggers: 16;
22
+ };
23
+ export type FileCategory = keyof typeof CATEGORY_PRIORITY;
24
+ export interface FileMetadata {
25
+ objectType: string;
26
+ schemaName?: string;
27
+ objectName?: string;
28
+ }
29
+ export interface FileEntry {
30
+ path: string;
31
+ order: number;
32
+ statements: number;
33
+ sql: string;
34
+ metadata: FileMetadata;
35
+ }
36
+ export interface DeclarativeSchemaOutput {
37
+ version: 1;
38
+ mode: "declarative";
39
+ generatedAt: string;
40
+ source: {
41
+ fingerprint: string;
42
+ };
43
+ target: {
44
+ fingerprint: string;
45
+ };
46
+ files: FileEntry[];
47
+ }
48
+ /** A regex pattern with a group name used as the directory or file name. */
49
+ export interface GroupingPattern {
50
+ /** Regex to test against the object name. Strings are compiled to RegExp. */
51
+ pattern: string | RegExp;
52
+ /** Group name used as the directory or file name. */
53
+ name: string;
54
+ }
55
+ export interface Grouping {
56
+ /** How grouped entities are organized on disk. */
57
+ mode: "single-file" | "subdirectory";
58
+ /**
59
+ * Regex-based patterns to match object names.
60
+ * First matching pattern wins -- ordering controls priority.
61
+ *
62
+ * Examples:
63
+ * - `{ pattern: /^project/, name: "project" }` – prefix
64
+ * - `{ pattern: /organization/, name: "organization" }` – contains
65
+ * - `{ pattern: /tokens$/, name: "tokens" }` – suffix
66
+ */
67
+ groupPatterns?: GroupingPattern[];
68
+ /**
69
+ * Automatically detect partitioned tables and group partitions with
70
+ * their parent table. Defaults to `true`.
71
+ */
72
+ autoGroupPartitions?: boolean;
73
+ /**
74
+ * Schemas to flatten: all objects are merged into one file per category.
75
+ * e.g. `schemas/partman/tables.sql` instead of `schemas/partman/tables/foo.sql`.
76
+ * Useful for small or extension schemas that don't need per-object files.
77
+ */
78
+ flatSchemas?: string[];
79
+ }
80
+ export interface FilePath {
81
+ path: string;
82
+ category: FileCategory;
83
+ metadata: FileMetadata;
84
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Type definitions for declarative schema export.
3
+ */
4
+ // ============================================================================
5
+ // File Categories
6
+ // ============================================================================
7
+ export const CATEGORY_PRIORITY = {
8
+ cluster: 0,
9
+ schema: 1,
10
+ extensions: 2,
11
+ types: 3,
12
+ sequences: 4,
13
+ tables: 5,
14
+ foreign_tables: 6,
15
+ views: 7,
16
+ matviews: 8,
17
+ functions: 9,
18
+ procedures: 10,
19
+ aggregates: 11,
20
+ domains: 12,
21
+ collations: 13,
22
+ publications: 14,
23
+ subscriptions: 15,
24
+ event_triggers: 16,
25
+ };
@@ -0,0 +1,287 @@
1
+ {
2
+ "version": 150014,
3
+ "currentUser": "postgres",
4
+ "aggregates": {},
5
+ "collations": {},
6
+ "compositeTypes": {},
7
+ "domains": {},
8
+ "enums": {},
9
+ "extensions": {
10
+ "extension:plpgsql": {
11
+ "name": "plpgsql",
12
+ "schema": "pg_catalog",
13
+ "relocatable": false,
14
+ "version": "1.0",
15
+ "owner": "postgres",
16
+ "comment": "PL/pgSQL procedural language",
17
+ "members": [
18
+ "procedure:pg_catalog.plpgsql_call_handler()",
19
+ "procedure:pg_catalog.plpgsql_inline_handler(internal)",
20
+ "procedure:pg_catalog.plpgsql_validator(oid)"
21
+ ]
22
+ }
23
+ },
24
+ "procedures": {},
25
+ "indexes": {},
26
+ "materializedViews": {},
27
+ "subscriptions": {},
28
+ "publications": {},
29
+ "rlsPolicies": {},
30
+ "roles": {
31
+ "role:postgres": {
32
+ "name": "postgres",
33
+ "is_superuser": true,
34
+ "can_inherit": true,
35
+ "can_create_roles": true,
36
+ "can_create_databases": true,
37
+ "can_login": true,
38
+ "can_replicate": true,
39
+ "connection_limit": -1,
40
+ "can_bypass_rls": true,
41
+ "config": null,
42
+ "comment": null,
43
+ "members": [],
44
+ "default_privileges": [
45
+ {
46
+ "in_schema": null,
47
+ "objtype": "S",
48
+ "grantee": "postgres",
49
+ "privileges": [
50
+ {
51
+ "privilege": "USAGE",
52
+ "grantable": false
53
+ }
54
+ ],
55
+ "is_implicit": true
56
+ },
57
+ {
58
+ "in_schema": null,
59
+ "objtype": "T",
60
+ "grantee": "PUBLIC",
61
+ "privileges": [
62
+ {
63
+ "privilege": "USAGE",
64
+ "grantable": false
65
+ }
66
+ ],
67
+ "is_implicit": true
68
+ },
69
+ {
70
+ "in_schema": null,
71
+ "objtype": "T",
72
+ "grantee": "postgres",
73
+ "privileges": [
74
+ {
75
+ "privilege": "USAGE",
76
+ "grantable": false
77
+ }
78
+ ],
79
+ "is_implicit": true
80
+ },
81
+ {
82
+ "in_schema": null,
83
+ "objtype": "f",
84
+ "grantee": "PUBLIC",
85
+ "privileges": [
86
+ {
87
+ "privilege": "EXECUTE",
88
+ "grantable": false
89
+ }
90
+ ],
91
+ "is_implicit": true
92
+ },
93
+ {
94
+ "in_schema": null,
95
+ "objtype": "f",
96
+ "grantee": "postgres",
97
+ "privileges": [
98
+ {
99
+ "privilege": "EXECUTE",
100
+ "grantable": false
101
+ }
102
+ ],
103
+ "is_implicit": true
104
+ },
105
+ {
106
+ "in_schema": null,
107
+ "objtype": "n",
108
+ "grantee": "postgres",
109
+ "privileges": [
110
+ {
111
+ "privilege": "CREATE",
112
+ "grantable": false
113
+ },
114
+ {
115
+ "privilege": "USAGE",
116
+ "grantable": false
117
+ }
118
+ ],
119
+ "is_implicit": true
120
+ },
121
+ {
122
+ "in_schema": null,
123
+ "objtype": "r",
124
+ "grantee": "postgres",
125
+ "privileges": [
126
+ {
127
+ "privilege": "DELETE",
128
+ "grantable": false
129
+ },
130
+ {
131
+ "privilege": "INSERT",
132
+ "grantable": false
133
+ },
134
+ {
135
+ "privilege": "REFERENCES",
136
+ "grantable": false
137
+ },
138
+ {
139
+ "privilege": "SELECT",
140
+ "grantable": false
141
+ },
142
+ {
143
+ "privilege": "TRIGGER",
144
+ "grantable": false
145
+ },
146
+ {
147
+ "privilege": "TRUNCATE",
148
+ "grantable": false
149
+ },
150
+ {
151
+ "privilege": "UPDATE",
152
+ "grantable": false
153
+ }
154
+ ],
155
+ "is_implicit": true
156
+ }
157
+ ]
158
+ }
159
+ },
160
+ "schemas": {
161
+ "schema:public": {
162
+ "name": "public",
163
+ "owner": "pg_database_owner",
164
+ "comment": "standard public schema",
165
+ "privileges": [
166
+ {
167
+ "grantee": "PUBLIC",
168
+ "privilege": "USAGE",
169
+ "grantable": false
170
+ },
171
+ {
172
+ "grantee": "pg_database_owner",
173
+ "privilege": "CREATE",
174
+ "grantable": false
175
+ },
176
+ {
177
+ "grantee": "pg_database_owner",
178
+ "privilege": "USAGE",
179
+ "grantable": false
180
+ }
181
+ ]
182
+ }
183
+ },
184
+ "sequences": {},
185
+ "tables": {},
186
+ "triggers": {},
187
+ "eventTriggers": {},
188
+ "rules": {},
189
+ "ranges": {},
190
+ "views": {},
191
+ "foreignDataWrappers": {},
192
+ "servers": {},
193
+ "userMappings": {},
194
+ "foreignTables": {},
195
+ "depends": [
196
+ {
197
+ "dependent_stable_id": "acl:schema:public::grantee:pg_database_owner",
198
+ "referenced_stable_id": "role:pg_database_owner",
199
+ "deptype": "n"
200
+ },
201
+ {
202
+ "dependent_stable_id": "acl:schema:public::grantee:pg_database_owner",
203
+ "referenced_stable_id": "schema:public",
204
+ "deptype": "n"
205
+ },
206
+ {
207
+ "dependent_stable_id": "acl:schema:public::grantee:PUBLIC",
208
+ "referenced_stable_id": "role:PUBLIC",
209
+ "deptype": "n"
210
+ },
211
+ {
212
+ "dependent_stable_id": "acl:schema:public::grantee:PUBLIC",
213
+ "referenced_stable_id": "schema:public",
214
+ "deptype": "n"
215
+ },
216
+ {
217
+ "dependent_stable_id": "comment:extension:plpgsql",
218
+ "referenced_stable_id": "extension:plpgsql",
219
+ "deptype": "a"
220
+ },
221
+ {
222
+ "dependent_stable_id": "comment:language:plpgsql",
223
+ "referenced_stable_id": "language:plpgsql",
224
+ "deptype": "a"
225
+ },
226
+ {
227
+ "dependent_stable_id": "comment:language:sql",
228
+ "referenced_stable_id": "language:sql",
229
+ "deptype": "a"
230
+ },
231
+ {
232
+ "dependent_stable_id": "language:plpgsql",
233
+ "referenced_stable_id": "procedure:pg_catalog.plpgsql_call_handler()",
234
+ "deptype": "n"
235
+ },
236
+ {
237
+ "dependent_stable_id": "language:plpgsql",
238
+ "referenced_stable_id": "procedure:pg_catalog.plpgsql_inline_handler(internal)",
239
+ "deptype": "n"
240
+ },
241
+ {
242
+ "dependent_stable_id": "language:plpgsql",
243
+ "referenced_stable_id": "procedure:pg_catalog.plpgsql_validator(oid)",
244
+ "deptype": "n"
245
+ },
246
+ {
247
+ "dependent_stable_id": "language:plpgsql",
248
+ "referenced_stable_id": "role:postgres",
249
+ "deptype": "n"
250
+ },
251
+ {
252
+ "dependent_stable_id": "membership:pg_read_all_settings->pg_monitor",
253
+ "referenced_stable_id": "role:pg_monitor",
254
+ "deptype": "n"
255
+ },
256
+ {
257
+ "dependent_stable_id": "membership:pg_read_all_settings->pg_monitor",
258
+ "referenced_stable_id": "role:pg_read_all_settings",
259
+ "deptype": "n"
260
+ },
261
+ {
262
+ "dependent_stable_id": "membership:pg_read_all_stats->pg_monitor",
263
+ "referenced_stable_id": "role:pg_monitor",
264
+ "deptype": "n"
265
+ },
266
+ {
267
+ "dependent_stable_id": "membership:pg_read_all_stats->pg_monitor",
268
+ "referenced_stable_id": "role:pg_read_all_stats",
269
+ "deptype": "n"
270
+ },
271
+ {
272
+ "dependent_stable_id": "membership:pg_stat_scan_tables->pg_monitor",
273
+ "referenced_stable_id": "role:pg_monitor",
274
+ "deptype": "n"
275
+ },
276
+ {
277
+ "dependent_stable_id": "membership:pg_stat_scan_tables->pg_monitor",
278
+ "referenced_stable_id": "role:pg_stat_scan_tables",
279
+ "deptype": "n"
280
+ },
281
+ {
282
+ "dependent_stable_id": "schema:public",
283
+ "referenced_stable_id": "role:pg_database_owner",
284
+ "deptype": "n"
285
+ }
286
+ ]
287
+ }
@@ -19,12 +19,40 @@ type ExtractedProperties = {
19
19
  schema?: string | string[];
20
20
  owner?: string | string[];
21
21
  member?: string | string[];
22
+ grantee?: string | string[];
23
+ publication?: string | string[];
24
+ extension?: string | string[];
25
+ procedureLanguage?: string | string[];
26
+ eventTriggerName?: string | string[];
27
+ procedureBinaryPath?: string | string[];
28
+ triggerFunctionSchema?: string | string[];
29
+ };
30
+ /**
31
+ * Special properties that use custom matching logic (not extractor-based).
32
+ */
33
+ type SpecialProperties = {
34
+ /**
35
+ * Prefix match on `change.requires`.
36
+ * Matches when any element of `change.requires` starts with any of the given prefixes.
37
+ * Useful for excluding changes that depend on specific schemas/types.
38
+ *
39
+ * @example Filter out changes that require auth or extensions types:
40
+ * ```ts
41
+ * { not: { requiresMatching: ["type:auth.", "type:extensions."] } }
42
+ * ```
43
+ */
44
+ requiresMatching?: string[];
22
45
  };
23
46
  /**
24
47
  * Property pattern - matches against change properties.
25
48
  * Multiple properties are combined with AND (all must match).
26
49
  */
27
- type PropertyPattern = CoreProperties & ExtractedProperties & {
50
+ type PropertyPattern = CoreProperties & ExtractedProperties & SpecialProperties & {
51
+ /**
52
+ * When true, exclusions from this filter cascade to dependents (requires/pg_depend).
53
+ * Default false for DSL filters (opt-in).
54
+ */
55
+ cascade?: boolean;
28
56
  and?: never;
29
57
  or?: never;
30
58
  not?: never;
@@ -35,28 +63,37 @@ type PropertyPattern = CoreProperties & ExtractedProperties & {
35
63
  */
36
64
  type CompositionPattern = ({
37
65
  and: FilterPattern[];
66
+ cascade?: boolean;
38
67
  or?: never;
39
68
  not?: never;
40
69
  } & {
41
70
  [K in keyof CoreProperties]?: never;
42
71
  } & {
43
72
  [K in keyof ExtractedProperties]?: never;
73
+ } & {
74
+ [K in keyof SpecialProperties]?: never;
44
75
  }) | ({
45
76
  or: FilterPattern[];
77
+ cascade?: boolean;
46
78
  and?: never;
47
79
  not?: never;
48
80
  } & {
49
81
  [K in keyof CoreProperties]?: never;
50
82
  } & {
51
83
  [K in keyof ExtractedProperties]?: never;
84
+ } & {
85
+ [K in keyof SpecialProperties]?: never;
52
86
  }) | ({
53
87
  not: FilterPattern;
88
+ cascade?: boolean;
54
89
  and?: never;
55
90
  or?: never;
56
91
  } & {
57
92
  [K in keyof CoreProperties]?: never;
58
93
  } & {
59
94
  [K in keyof ExtractedProperties]?: never;
95
+ } & {
96
+ [K in keyof SpecialProperties]?: never;
60
97
  });
61
98
  /**
62
99
  * Filter pattern DSL.
@@ -43,10 +43,28 @@ export function evaluatePattern(pattern, change) {
43
43
  return false;
44
44
  }
45
45
  }
46
+ // Match requiresMatching (special property - prefix match on change.requires)
47
+ if (pattern.requiresMatching) {
48
+ const requires = change.requires ?? [];
49
+ const prefixes = pattern.requiresMatching;
50
+ const hasMatch = requires.some((r) => prefixes.some((p) => r.startsWith(p)));
51
+ if (!hasMatch) {
52
+ return false;
53
+ }
54
+ }
46
55
  // Match extracted properties
47
56
  for (const [key, value] of Object.entries(pattern)) {
48
- // Skip composition operators and core properties
49
- if (["and", "or", "not", "type", "operation", "scope"].includes(key)) {
57
+ // Skip composition operators, core properties, special properties, and cascade
58
+ if ([
59
+ "and",
60
+ "or",
61
+ "not",
62
+ "type",
63
+ "operation",
64
+ "scope",
65
+ "requiresMatching",
66
+ "cascade",
67
+ ].includes(key)) {
50
68
  continue;
51
69
  }
52
70
  // Check if this is a registered property extractor
@@ -11,6 +11,48 @@ export const PROPERTY_EXTRACTORS = {
11
11
  }
12
12
  return null;
13
13
  },
14
+ grantee: (change) => {
15
+ if (change.scope === "privilege" && "grantee" in change) {
16
+ return change.grantee;
17
+ }
18
+ return null;
19
+ },
20
+ publication: (change) => {
21
+ if (change.objectType === "publication") {
22
+ return change.publication.name;
23
+ }
24
+ return null;
25
+ },
26
+ extension: (change) => {
27
+ if (change.objectType === "extension") {
28
+ return change.extension.name;
29
+ }
30
+ return null;
31
+ },
32
+ procedureLanguage: (change) => {
33
+ if (change.objectType === "procedure") {
34
+ return change.procedure.language;
35
+ }
36
+ return null;
37
+ },
38
+ eventTriggerName: (change) => {
39
+ if (change.objectType === "event_trigger") {
40
+ return change.eventTrigger.name;
41
+ }
42
+ return null;
43
+ },
44
+ procedureBinaryPath: (change) => {
45
+ if (change.objectType === "procedure") {
46
+ return change.procedure.binary_path ?? null;
47
+ }
48
+ return null;
49
+ },
50
+ triggerFunctionSchema: (change) => {
51
+ if (change.objectType === "trigger") {
52
+ return change.trigger.function_schema;
53
+ }
54
+ return null;
55
+ },
14
56
  };
15
57
  export function getSchema(change) {
16
58
  switch (change.objectType) {
@@ -3,6 +3,7 @@
3
3
  *
4
4
  * Combines filter and serialization DSLs into a single serializable structure.
5
5
  */
6
+ import type { CatalogSnapshot } from "../catalog.snapshot.ts";
6
7
  import type { FilterDSL } from "./filter/dsl.ts";
7
8
  import type { SerializeDSL } from "./serialize/dsl.ts";
8
9
  /**
@@ -19,4 +20,13 @@ export type IntegrationDSL = {
19
20
  * If not provided, changes are serialized with default options.
20
21
  */
21
22
  serialize?: SerializeDSL;
23
+ /**
24
+ * Baseline catalog snapshot for this integration.
25
+ *
26
+ * When `--source` is omitted, this snapshot is deserialized and used as the
27
+ * source catalog instead of `createEmptyCatalog`. This lets integrations
28
+ * define what "empty" means for their platform (e.g. Supabase ships with
29
+ * pre-existing schemas, extensions, and roles).
30
+ */
31
+ emptyCatalog?: CatalogSnapshot;
22
32
  };
@@ -7,4 +7,12 @@
7
7
  * - Skips authorization for schema creates owned by Supabase system roles
8
8
  */
9
9
  import type { IntegrationDSL } from "./integration-dsl.ts";
10
+ /**
11
+ * To generate the emptyCatalog snapshot, run catalog-export against a fresh
12
+ * supabase/postgres container:
13
+ *
14
+ * pgdelta catalog-export --target postgres://postgres:postgres@localhost:54322/postgres --output supabase-baseline.json
15
+ *
16
+ * Then import and assign the JSON content to the emptyCatalog field below.
17
+ */
10
18
  export declare const supabase: IntegrationDSL;
@@ -53,7 +53,16 @@ const SUPABASE_SYSTEM_ROLES = [
53
53
  "supabase_storage_admin",
54
54
  "supabase_superuser",
55
55
  ];
56
+ /**
57
+ * To generate the emptyCatalog snapshot, run catalog-export against a fresh
58
+ * supabase/postgres container:
59
+ *
60
+ * pgdelta catalog-export --target postgres://postgres:postgres@localhost:54322/postgres --output supabase-baseline.json
61
+ *
62
+ * Then import and assign the JSON content to the emptyCatalog field below.
63
+ */
56
64
  export const supabase = {
65
+ // TODO: emptyCatalog: undefined -- populate by running catalog-export on a clean Supabase container
57
66
  filter: {
58
67
  or: [
59
68
  {
@@ -1,10 +1,4 @@
1
- import type { DefaultPrivilegeState } from "../base.default-privileges.ts";
2
- import type { Role } from "../role/role.model.ts";
1
+ import type { ObjectDiffContext } from "../diff-context.ts";
3
2
  import type { Aggregate } from "./aggregate.model.ts";
4
3
  import type { AggregateChange } from "./changes/aggregate.types.ts";
5
- export declare function diffAggregates(ctx: {
6
- version: number;
7
- currentUser: string;
8
- defaultPrivilegeState: DefaultPrivilegeState;
9
- mainRoles: Record<string, Role>;
10
- }, main: Record<string, Aggregate>, branch: Record<string, Aggregate>): AggregateChange[];
4
+ export declare function diffAggregates(ctx: Pick<ObjectDiffContext, "version" | "currentUser" | "defaultPrivilegeState">, main: Record<string, Aggregate>, branch: Record<string, Aggregate>): AggregateChange[];