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

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
@@ -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 {
3
4
  CompositeType,
4
5
  type CompositeTypeProps,
@@ -12,7 +13,7 @@ import {
12
13
 
13
14
  describe.concurrent("composite-type", () => {
14
15
  describe("alter", () => {
15
- test("change owner", () => {
16
+ test("change owner", async () => {
16
17
  const props: Omit<CompositeTypeProps, "owner"> = {
17
18
  schema: "public",
18
19
  name: "test_type",
@@ -40,13 +41,15 @@ describe.concurrent("composite-type", () => {
40
41
  owner: "new_owner",
41
42
  });
42
43
 
44
+ await assertValidSql(change.serialize());
45
+
43
46
  expect(change.serialize()).toBe(
44
47
  "ALTER TYPE public.test_type OWNER TO new_owner",
45
48
  );
46
49
  });
47
50
  });
48
51
 
49
- test("add attribute", () => {
52
+ test("add attribute", async () => {
50
53
  const base = {
51
54
  schema: "public",
52
55
  name: "ct",
@@ -93,12 +96,13 @@ describe.concurrent("composite-type", () => {
93
96
  compositeType: branch,
94
97
  attribute: branch.columns[0],
95
98
  });
99
+ await assertValidSql(change.serialize());
96
100
  expect(change.serialize()).toBe(
97
101
  "ALTER TYPE public.ct ADD ATTRIBUTE a text",
98
102
  );
99
103
  });
100
104
 
101
- test("drop attribute", () => {
105
+ test("drop attribute", async () => {
102
106
  const base = {
103
107
  schema: "public",
104
108
  name: "ct",
@@ -145,10 +149,11 @@ describe.concurrent("composite-type", () => {
145
149
  compositeType: main,
146
150
  attribute: main.columns[0],
147
151
  });
152
+ await assertValidSql(change.serialize());
148
153
  expect(change.serialize()).toBe("ALTER TYPE public.ct DROP ATTRIBUTE a");
149
154
  });
150
155
 
151
- test("alter attribute type and collation", () => {
156
+ test("alter attribute type and collation", async () => {
152
157
  const base = {
153
158
  schema: "public",
154
159
  name: "ct",
@@ -195,6 +200,7 @@ describe.concurrent("composite-type", () => {
195
200
  compositeType: branch,
196
201
  attribute: branch.columns[0],
197
202
  });
203
+ await assertValidSql(change.serialize());
198
204
  expect(change.serialize()).toBe(
199
205
  'ALTER TYPE public.ct ALTER ATTRIBUTE a TYPE text COLLATE "en_US"',
200
206
  );
@@ -1,9 +1,10 @@
1
1
  import { describe, expect, test } from "bun:test";
2
+ import { assertValidSql } from "../../../../test-utils/assert-valid-sql.ts";
2
3
  import { CompositeType } from "../composite-type.model.ts";
3
4
  import { CreateCompositeType } from "./composite-type.create.ts";
4
5
 
5
6
  describe("composite-type", () => {
6
- test("create", () => {
7
+ test("create", async () => {
7
8
  const compositeType = new CompositeType({
8
9
  schema: "public",
9
10
  name: "test_type",
@@ -47,12 +48,14 @@ describe("composite-type", () => {
47
48
  compositeType,
48
49
  });
49
50
 
51
+ await assertValidSql(change.serialize());
52
+
50
53
  expect(change.serialize()).toBe(
51
54
  "CREATE TYPE public.test_type AS (id integer)",
52
55
  );
53
56
  });
54
57
 
55
- test("create with collate", () => {
58
+ test("create with collate", async () => {
56
59
  const compositeType = new CompositeType({
57
60
  schema: "public",
58
61
  name: "test_type",
@@ -94,6 +97,8 @@ describe("composite-type", () => {
94
97
 
95
98
  const change = new CreateCompositeType({ compositeType });
96
99
 
100
+ await assertValidSql(change.serialize());
101
+
97
102
  expect(change.serialize()).toBe(
98
103
  'CREATE TYPE public.test_type AS (name text COLLATE "en_US")',
99
104
  );
@@ -1,9 +1,10 @@
1
1
  import { describe, expect, test } from "bun:test";
2
+ import { assertValidSql } from "../../../../test-utils/assert-valid-sql.ts";
2
3
  import { CompositeType } from "../composite-type.model.ts";
3
4
  import { DropCompositeType } from "./composite-type.drop.ts";
4
5
 
5
6
  describe("composite-type", () => {
6
- test("drop", () => {
7
+ test("drop", async () => {
7
8
  const compositeType = new CompositeType({
8
9
  schema: "public",
9
10
  name: "test_type",
@@ -28,6 +29,8 @@ describe("composite-type", () => {
28
29
  compositeType,
29
30
  });
30
31
 
32
+ await assertValidSql(change.serialize());
33
+
31
34
  expect(change.serialize()).toBe("DROP TYPE public.test_type");
32
35
  });
33
36
  });
@@ -6,8 +6,17 @@ import {
6
6
  AlterCompositeTypeChangeOwner,
7
7
  AlterCompositeTypeDropAttribute,
8
8
  } from "./changes/composite-type.alter.ts";
9
+ import {
10
+ CreateCommentOnCompositeType,
11
+ DropCommentOnCompositeType,
12
+ } from "./changes/composite-type.comment.ts";
9
13
  import { CreateCompositeType } from "./changes/composite-type.create.ts";
10
14
  import { DropCompositeType } from "./changes/composite-type.drop.ts";
15
+ import {
16
+ GrantCompositeTypePrivileges,
17
+ RevokeCompositeTypePrivileges,
18
+ RevokeGrantOptionCompositeTypePrivileges,
19
+ } from "./changes/composite-type.privilege.ts";
11
20
  import { diffCompositeTypes } from "./composite-type.diff.ts";
12
21
  import {
13
22
  CompositeType,
@@ -188,4 +197,73 @@ describe.concurrent("composite-type.diff", () => {
188
197
  changes.some((c) => c instanceof AlterCompositeTypeAlterAttributeType),
189
198
  ).toBe(true);
190
199
  });
200
+
201
+ test("created with privileges emits grant/revoke/revoke grant option", () => {
202
+ const ct = new CompositeType({
203
+ ...base,
204
+ privileges: [
205
+ { grantee: "role_usage", privilege: "USAGE", grantable: false },
206
+ { grantee: "role_grant", privilege: "USAGE", grantable: true },
207
+ ],
208
+ });
209
+ const changes = diffCompositeTypes(testContext, {}, { [ct.stableId]: ct });
210
+ expect(changes[0]).toBeInstanceOf(CreateCompositeType);
211
+ expect(changes.some((c) => c instanceof GrantCompositeTypePrivileges)).toBe(
212
+ true,
213
+ );
214
+ });
215
+
216
+ test("altered comment emits create/drop comment", () => {
217
+ const main = new CompositeType(base);
218
+ const withComment = new CompositeType({ ...base, comment: "my type" });
219
+
220
+ const addComment = diffCompositeTypes(
221
+ testContext,
222
+ { [main.stableId]: main },
223
+ { [withComment.stableId]: withComment },
224
+ );
225
+ expect(addComment[0]).toBeInstanceOf(CreateCommentOnCompositeType);
226
+
227
+ const dropComment = diffCompositeTypes(
228
+ testContext,
229
+ { [withComment.stableId]: withComment },
230
+ { [main.stableId]: main },
231
+ );
232
+ expect(dropComment[0]).toBeInstanceOf(DropCommentOnCompositeType);
233
+ });
234
+
235
+ test("altered privileges emit grant, revoke, and revoke grant option", () => {
236
+ const main = new CompositeType({
237
+ ...base,
238
+ privileges: [
239
+ { grantee: "role_usage", privilege: "USAGE", grantable: false },
240
+ { grantee: "role_with_option", privilege: "USAGE", grantable: true },
241
+ { grantee: "role_removed", privilege: "USAGE", grantable: false },
242
+ ],
243
+ });
244
+ const branch = new CompositeType({
245
+ ...base,
246
+ privileges: [
247
+ { grantee: "role_usage", privilege: "USAGE", grantable: true },
248
+ { grantee: "role_with_option", privilege: "USAGE", grantable: false },
249
+ { grantee: "role_new", privilege: "USAGE", grantable: false },
250
+ ],
251
+ });
252
+ const changes = diffCompositeTypes(
253
+ testContext,
254
+ { [main.stableId]: main },
255
+ { [branch.stableId]: branch },
256
+ );
257
+ expect(changes.some((c) => c instanceof GrantCompositeTypePrivileges)).toBe(
258
+ true,
259
+ );
260
+ expect(
261
+ changes.some((c) => c instanceof RevokeCompositeTypePrivileges),
262
+ ).toBe(true);
263
+ expect(
264
+ changes.some(
265
+ (c) => c instanceof RevokeGrantOptionCompositeTypePrivileges,
266
+ ),
267
+ ).toBe(true);
268
+ });
191
269
  });
@@ -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 {
11
10
  AlterCompositeTypeAddAttribute,
@@ -38,12 +37,10 @@ import type { CompositeType } from "./composite-type.model.ts";
38
37
  * @returns A list of changes to apply to main to make it match branch.
39
38
  */
40
39
  export function diffCompositeTypes(
41
- ctx: {
42
- version: number;
43
- currentUser: string;
44
- defaultPrivilegeState: DefaultPrivilegeState;
45
- mainRoles: Record<string, Role>;
46
- },
40
+ ctx: Pick<
41
+ ObjectDiffContext,
42
+ "version" | "currentUser" | "defaultPrivilegeState"
43
+ >,
47
44
  main: Record<string, CompositeType>,
48
45
  branch: Record<string, CompositeType>,
49
46
  ): CompositeTypeChange[] {
@@ -92,6 +89,10 @@ export function diffCompositeTypes(
92
89
  "composite_type",
93
90
  ct.schema ?? "",
94
91
  );
92
+ const creatorFilteredDefaults =
93
+ ct.owner !== ctx.currentUser
94
+ ? effectiveDefaults.filter((p) => p.grantee !== ctx.currentUser)
95
+ : effectiveDefaults;
95
96
  // Filter out PUBLIC's built-in default USAGE privilege (PostgreSQL grants it automatically)
96
97
  // Reference: https://www.postgresql.org/docs/17/ddl-priv.html Table 5.2
97
98
  // This prevents generating unnecessary "GRANT USAGE TO PUBLIC" statements
@@ -102,56 +103,25 @@ export function diffCompositeTypes(
102
103
  // Filter out owner privileges - owner always has ALL privileges implicitly
103
104
  // and shouldn't be compared. Use the composite type owner as the reference.
104
105
  const privilegeResults = diffPrivileges(
105
- effectiveDefaults,
106
+ filterPublicBuiltInDefaults("composite_type", creatorFilteredDefaults),
106
107
  desiredPrivileges,
107
108
  ct.owner,
108
109
  );
109
110
 
110
- // Generate grant changes
111
- for (const [grantee, result] of privilegeResults) {
112
- if (result.grants.length > 0) {
113
- const grantGroups = groupPrivilegesByGrantable(result.grants);
114
- for (const [grantable, list] of grantGroups) {
115
- void grantable;
116
- changes.push(
117
- new GrantCompositeTypePrivileges({
118
- compositeType: ct,
119
- grantee,
120
- privileges: list,
121
- version: ctx.version,
122
- }),
123
- );
124
- }
125
- }
126
-
127
- // Generate revoke changes
128
- if (result.revokes.length > 0) {
129
- const revokeGroups = groupPrivilegesByGrantable(result.revokes);
130
- for (const [grantable, list] of revokeGroups) {
131
- void grantable;
132
- changes.push(
133
- new RevokeCompositeTypePrivileges({
134
- compositeType: ct,
135
- grantee,
136
- privileges: list,
137
- version: ctx.version,
138
- }),
139
- );
140
- }
141
- }
142
-
143
- // Generate revoke grant option changes
144
- if (result.revokeGrantOption.length > 0) {
145
- changes.push(
146
- new RevokeGrantOptionCompositeTypePrivileges({
147
- compositeType: ct,
148
- grantee,
149
- privilegeNames: result.revokeGrantOption,
150
- version: ctx.version,
151
- }),
152
- );
153
- }
154
- }
111
+ changes.push(
112
+ ...(emitObjectPrivilegeChanges(
113
+ privilegeResults,
114
+ ct,
115
+ ct,
116
+ "compositeType",
117
+ {
118
+ Grant: GrantCompositeTypePrivileges,
119
+ Revoke: RevokeCompositeTypePrivileges,
120
+ RevokeGrantOption: RevokeGrantOptionCompositeTypePrivileges,
121
+ },
122
+ ctx.version,
123
+ ) as CompositeTypeChange[]),
124
+ );
155
125
  }
156
126
 
157
127
  for (const compositeTypeId of dropped) {
@@ -313,54 +283,22 @@ export function diffCompositeTypes(
313
283
  mainPrivilegesFiltered,
314
284
  branchPrivilegesFiltered,
315
285
  branchCompositeType.owner,
316
- ctx.mainRoles,
317
286
  );
318
287
 
319
- for (const [grantee, result] of privilegeResults) {
320
- // Generate grant changes
321
- if (result.grants.length > 0) {
322
- const grantGroups = groupPrivilegesByGrantable(result.grants);
323
- for (const [grantable, list] of grantGroups) {
324
- void grantable;
325
- changes.push(
326
- new GrantCompositeTypePrivileges({
327
- compositeType: branchCompositeType,
328
- grantee,
329
- privileges: list,
330
- version: ctx.version,
331
- }),
332
- );
333
- }
334
- }
335
-
336
- // Generate revoke changes
337
- if (result.revokes.length > 0) {
338
- const revokeGroups = groupPrivilegesByGrantable(result.revokes);
339
- for (const [grantable, list] of revokeGroups) {
340
- void grantable;
341
- changes.push(
342
- new RevokeCompositeTypePrivileges({
343
- compositeType: mainCompositeType,
344
- grantee,
345
- privileges: list,
346
- version: ctx.version,
347
- }),
348
- );
349
- }
350
- }
351
-
352
- // Generate revoke grant option changes
353
- if (result.revokeGrantOption.length > 0) {
354
- changes.push(
355
- new RevokeGrantOptionCompositeTypePrivileges({
356
- compositeType: mainCompositeType,
357
- grantee,
358
- privilegeNames: result.revokeGrantOption,
359
- version: ctx.version,
360
- }),
361
- );
362
- }
363
- }
288
+ changes.push(
289
+ ...(emitObjectPrivilegeChanges(
290
+ privilegeResults,
291
+ branchCompositeType,
292
+ mainCompositeType,
293
+ "compositeType",
294
+ {
295
+ Grant: GrantCompositeTypePrivileges,
296
+ Revoke: RevokeCompositeTypePrivileges,
297
+ RevokeGrantOption: RevokeGrantOptionCompositeTypePrivileges,
298
+ },
299
+ ctx.version,
300
+ ) as CompositeTypeChange[]),
301
+ );
364
302
 
365
303
  // Note: Composite type renaming would also use ALTER TYPE ... RENAME TO ...
366
304
  // But since our CompositeType model uses 'name' as the identity field,
@@ -164,6 +164,7 @@ export async function extractCompositeTypes(
164
164
  c.relowner::regrole::text AS owner,
165
165
  obj_description(c.reltype, 'pg_type') AS comment,
166
166
  c.relacl AS relacl, -- used by privileges LATERAL
167
+ c.relowner AS relowner,
167
168
  c.oid AS oid
168
169
  FROM pg_catalog.pg_class c
169
170
  LEFT JOIN extension_oids e ON c.reltype = e.objid
@@ -201,7 +202,7 @@ export async function extractCompositeTypes(
201
202
  )
202
203
  ORDER BY x.grantee, x.privilege_type
203
204
  ) AS privileges
204
- FROM LATERAL aclexplode(ct.relacl) AS x(grantor, grantee, privilege_type, is_grantable)
205
+ FROM LATERAL aclexplode(COALESCE(ct.relacl, acldefault('T', ct.relowner))) AS x(grantor, grantee, privilege_type, is_grantable)
205
206
  ) priv ON TRUE
206
207
 
207
208
  -- columns as a per-row LATERAL subquery (so no GROUP BY needed)
@@ -1,10 +1,11 @@
1
1
  import { describe, expect, test } from "bun:test";
2
+ import { assertValidSql } from "../../../../test-utils/assert-valid-sql.ts";
2
3
  import { Enum, type EnumProps } from "../enum.model.ts";
3
4
  import { AlterEnumAddValue, AlterEnumChangeOwner } from "./enum.alter.ts";
4
5
 
5
6
  describe.concurrent("enum", () => {
6
7
  describe("alter", () => {
7
- test("change owner", () => {
8
+ test("change owner", async () => {
8
9
  const props: Omit<EnumProps, "owner"> = {
9
10
  schema: "public",
10
11
  name: "test_enum",
@@ -24,12 +25,14 @@ describe.concurrent("enum", () => {
24
25
  owner: "new_owner",
25
26
  });
26
27
 
28
+ await assertValidSql(change.serialize());
29
+
27
30
  expect(change.serialize()).toBe(
28
31
  "ALTER TYPE public.test_enum OWNER TO new_owner",
29
32
  );
30
33
  });
31
34
 
32
- test("add value", () => {
35
+ test("add value", async () => {
33
36
  const props: EnumProps = {
34
37
  schema: "public",
35
38
  name: "test_enum",
@@ -44,12 +47,14 @@ describe.concurrent("enum", () => {
44
47
  const main = new Enum(props);
45
48
  const change = new AlterEnumAddValue({ enum: main, newValue: "value3" });
46
49
 
50
+ await assertValidSql(change.serialize());
51
+
47
52
  expect(change.serialize()).toBe(
48
53
  "ALTER TYPE public.test_enum ADD VALUE 'value3'",
49
54
  );
50
55
  });
51
56
 
52
- test("add value before", () => {
57
+ test("add value before", async () => {
53
58
  const props: EnumProps = {
54
59
  schema: "public",
55
60
  name: "test_enum",
@@ -68,12 +73,14 @@ describe.concurrent("enum", () => {
68
73
  position: { before: "value2" },
69
74
  });
70
75
 
76
+ await assertValidSql(change.serialize());
77
+
71
78
  expect(change.serialize()).toBe(
72
79
  "ALTER TYPE public.test_enum ADD VALUE 'value1_5' BEFORE 'value2'",
73
80
  );
74
81
  });
75
82
 
76
- test("add value after", () => {
83
+ test("add value after", async () => {
77
84
  const props: EnumProps = {
78
85
  schema: "public",
79
86
  name: "test_enum",
@@ -92,12 +99,14 @@ describe.concurrent("enum", () => {
92
99
  position: { after: "value1" },
93
100
  });
94
101
 
102
+ await assertValidSql(change.serialize());
103
+
95
104
  expect(change.serialize()).toBe(
96
105
  "ALTER TYPE public.test_enum ADD VALUE 'value1_5' AFTER 'value1'",
97
106
  );
98
107
  });
99
108
 
100
- test("complex enum changes are not auto-replaced", () => {
109
+ test("complex enum changes are not auto-replaced", async () => {
101
110
  expect(1).toBe(1);
102
111
  });
103
112
  });
@@ -1,9 +1,10 @@
1
1
  import { describe, expect, test } from "bun:test";
2
+ import { assertValidSql } from "../../../../test-utils/assert-valid-sql.ts";
2
3
  import { Enum } from "../enum.model.ts";
3
4
  import { CreateEnum } from "./enum.create.ts";
4
5
 
5
6
  describe("enum", () => {
6
- test("create", () => {
7
+ test("create", async () => {
7
8
  const enumType = new Enum({
8
9
  schema: "public",
9
10
  name: "test_enum",
@@ -21,6 +22,8 @@ describe("enum", () => {
21
22
  enum: enumType,
22
23
  });
23
24
 
25
+ await assertValidSql(change.serialize());
26
+
24
27
  expect(change.serialize()).toBe(
25
28
  "CREATE TYPE public.test_enum AS ENUM ('value1', 'value2', 'value3')",
26
29
  );
@@ -1,9 +1,10 @@
1
1
  import { describe, expect, test } from "bun:test";
2
+ import { assertValidSql } from "../../../../test-utils/assert-valid-sql.ts";
2
3
  import { Enum } from "../enum.model.ts";
3
4
  import { DropEnum } from "./enum.drop.ts";
4
5
 
5
6
  describe("enum", () => {
6
- test("drop", () => {
7
+ test("drop", async () => {
7
8
  const enumType = new Enum({
8
9
  schema: "public",
9
10
  name: "test_enum",
@@ -20,6 +21,8 @@ describe("enum", () => {
20
21
  enum: enumType,
21
22
  });
22
23
 
24
+ await assertValidSql(change.serialize());
25
+
23
26
  expect(change.serialize()).toBe("DROP TYPE public.test_enum");
24
27
  });
25
28
  });