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

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 (463) hide show
  1. package/README.md +22 -0
  2. package/dist/cli/bin/cli.js +0 -0
  3. package/dist/cli/commands/plan.js +21 -0
  4. package/dist/cli/utils.d.ts +2 -0
  5. package/dist/cli/utils.js +1 -1
  6. package/dist/core/objects/table/table.model.d.ts +4 -2
  7. package/dist/core/objects/table/table.model.js +3 -0
  8. package/dist/core/objects/trigger/changes/trigger.alter.js +23 -0
  9. package/dist/core/objects/trigger/changes/trigger.create.js +2 -1
  10. package/dist/core/objects/trigger/trigger.model.d.ts +1 -0
  11. package/dist/core/objects/trigger/trigger.model.js +3 -0
  12. package/dist/core/plan/apply.js +3 -3
  13. package/dist/core/plan/create.js +34 -15
  14. package/dist/core/plan/sql-format/constants.d.ts +2 -0
  15. package/dist/core/plan/sql-format/constants.js +11 -0
  16. package/dist/core/plan/sql-format/fixtures.d.ts +2 -0
  17. package/dist/core/plan/sql-format/fixtures.js +2449 -0
  18. package/dist/core/plan/sql-format/format-utils.d.ts +37 -0
  19. package/dist/core/plan/sql-format/format-utils.js +274 -0
  20. package/dist/core/plan/sql-format/formatters.d.ts +20 -0
  21. package/dist/core/plan/sql-format/formatters.js +737 -0
  22. package/dist/core/plan/sql-format/index.d.ts +2 -0
  23. package/dist/core/plan/sql-format/index.js +98 -0
  24. package/dist/core/plan/sql-format/keyword-case.d.ts +2 -0
  25. package/dist/core/plan/sql-format/keyword-case.js +868 -0
  26. package/dist/core/plan/sql-format/protect.d.ts +3 -0
  27. package/dist/core/plan/sql-format/protect.js +269 -0
  28. package/dist/core/plan/sql-format/sql-scanner.d.ts +59 -0
  29. package/dist/core/plan/sql-format/sql-scanner.js +202 -0
  30. package/dist/core/plan/sql-format/tokenizer.d.ts +22 -0
  31. package/dist/core/plan/sql-format/tokenizer.js +118 -0
  32. package/dist/core/plan/sql-format/types.d.ts +28 -0
  33. package/dist/core/plan/sql-format/types.js +1 -0
  34. package/dist/core/plan/sql-format/wrap.d.ts +2 -0
  35. package/dist/core/plan/sql-format/wrap.js +165 -0
  36. package/dist/core/plan/sql-format.d.ts +2 -0
  37. package/dist/core/plan/sql-format.js +1 -0
  38. package/dist/core/plan/statements.d.ts +2 -1
  39. package/dist/core/plan/statements.js +6 -2
  40. package/dist/core/postgres-config.d.ts +15 -0
  41. package/dist/core/postgres-config.js +30 -0
  42. package/dist/index.d.ts +2 -0
  43. package/dist/index.js +1 -0
  44. package/package.json +37 -22
  45. package/src/cli/app.ts +28 -0
  46. package/src/cli/bin/cli.ts +9 -0
  47. package/src/cli/commands/apply.ts +101 -0
  48. package/src/cli/commands/plan.ts +195 -0
  49. package/src/cli/commands/sync.ts +185 -0
  50. package/src/cli/formatters/index.ts +5 -0
  51. package/src/cli/formatters/tree/tree-builder.ts +380 -0
  52. package/src/cli/formatters/tree/tree-renderer.ts +372 -0
  53. package/src/cli/formatters/tree/tree.ts +237 -0
  54. package/src/cli/utils/integrations.ts +42 -0
  55. package/src/cli/utils.ts +231 -0
  56. package/src/core/catalog.diff.ts +246 -0
  57. package/src/core/catalog.model.ts +384 -0
  58. package/src/core/change.types.ts +44 -0
  59. package/src/core/context.ts +26 -0
  60. package/src/core/depend.ts +1870 -0
  61. package/src/core/expand-replace-dependencies.ts +380 -0
  62. package/src/core/fingerprint.ts +204 -0
  63. package/src/core/integrations/filter/dsl.ts +204 -0
  64. package/src/core/integrations/filter/extractors.ts +145 -0
  65. package/src/core/integrations/filter/filter.types.ts +3 -0
  66. package/src/core/integrations/integration-dsl.ts +24 -0
  67. package/src/core/integrations/integration.types.ts +7 -0
  68. package/src/core/integrations/serialize/dsl.ts +77 -0
  69. package/src/core/integrations/serialize/serialize.types.ts +3 -0
  70. package/src/core/integrations/supabase.ts +121 -0
  71. package/src/core/objects/aggregate/aggregate.diff.test.ts +215 -0
  72. package/src/core/objects/aggregate/aggregate.diff.ts +278 -0
  73. package/src/core/objects/aggregate/aggregate.model.ts +317 -0
  74. package/src/core/objects/aggregate/changes/aggregate.alter.test.ts +64 -0
  75. package/src/core/objects/aggregate/changes/aggregate.alter.ts +32 -0
  76. package/src/core/objects/aggregate/changes/aggregate.base.ts +20 -0
  77. package/src/core/objects/aggregate/changes/aggregate.comment.test.ts +86 -0
  78. package/src/core/objects/aggregate/changes/aggregate.comment.ts +62 -0
  79. package/src/core/objects/aggregate/changes/aggregate.create.test.ts +101 -0
  80. package/src/core/objects/aggregate/changes/aggregate.create.ts +329 -0
  81. package/src/core/objects/aggregate/changes/aggregate.drop.test.ts +78 -0
  82. package/src/core/objects/aggregate/changes/aggregate.drop.ts +32 -0
  83. package/src/core/objects/aggregate/changes/aggregate.privilege.test.ts +130 -0
  84. package/src/core/objects/aggregate/changes/aggregate.privilege.ts +146 -0
  85. package/src/core/objects/aggregate/changes/aggregate.types.ts +12 -0
  86. package/src/core/objects/base.change.ts +62 -0
  87. package/src/core/objects/base.default-privileges.ts +204 -0
  88. package/src/core/objects/base.diff.ts +20 -0
  89. package/src/core/objects/base.model.ts +82 -0
  90. package/src/core/objects/base.privilege-diff.ts +299 -0
  91. package/src/core/objects/base.privilege.ts +184 -0
  92. package/src/core/objects/collation/changes/collation.alter.test.ts +63 -0
  93. package/src/core/objects/collation/changes/collation.alter.ts +79 -0
  94. package/src/core/objects/collation/changes/collation.base.ts +20 -0
  95. package/src/core/objects/collation/changes/collation.comment.ts +68 -0
  96. package/src/core/objects/collation/changes/collation.create.test.ts +51 -0
  97. package/src/core/objects/collation/changes/collation.create.ts +106 -0
  98. package/src/core/objects/collation/changes/collation.drop.test.ts +28 -0
  99. package/src/core/objects/collation/changes/collation.drop.ts +37 -0
  100. package/src/core/objects/collation/changes/collation.types.ts +10 -0
  101. package/src/core/objects/collation/collation.diff.test.ts +100 -0
  102. package/src/core/objects/collation/collation.diff.ts +126 -0
  103. package/src/core/objects/collation/collation.model.ts +224 -0
  104. package/src/core/objects/domain/changes/domain.alter.test.ts +316 -0
  105. package/src/core/objects/domain/changes/domain.alter.ts +286 -0
  106. package/src/core/objects/domain/changes/domain.base.ts +20 -0
  107. package/src/core/objects/domain/changes/domain.comment.ts +59 -0
  108. package/src/core/objects/domain/changes/domain.create.test.ts +65 -0
  109. package/src/core/objects/domain/changes/domain.create.ts +118 -0
  110. package/src/core/objects/domain/changes/domain.drop.test.ts +30 -0
  111. package/src/core/objects/domain/changes/domain.drop.ts +34 -0
  112. package/src/core/objects/domain/changes/domain.privilege.ts +171 -0
  113. package/src/core/objects/domain/changes/domain.types.ts +12 -0
  114. package/src/core/objects/domain/domain.diff.test.ts +284 -0
  115. package/src/core/objects/domain/domain.diff.ts +358 -0
  116. package/src/core/objects/domain/domain.model.ts +190 -0
  117. package/src/core/objects/event-trigger/changes/event-trigger.alter.test.ts +50 -0
  118. package/src/core/objects/event-trigger/changes/event-trigger.alter.ts +82 -0
  119. package/src/core/objects/event-trigger/changes/event-trigger.base.ts +20 -0
  120. package/src/core/objects/event-trigger/changes/event-trigger.comment.ts +66 -0
  121. package/src/core/objects/event-trigger/changes/event-trigger.create.test.ts +24 -0
  122. package/src/core/objects/event-trigger/changes/event-trigger.create.ts +72 -0
  123. package/src/core/objects/event-trigger/changes/event-trigger.drop.test.ts +22 -0
  124. package/src/core/objects/event-trigger/changes/event-trigger.drop.ts +34 -0
  125. package/src/core/objects/event-trigger/changes/event-trigger.types.ts +10 -0
  126. package/src/core/objects/event-trigger/event-trigger.diff.test.ts +126 -0
  127. package/src/core/objects/event-trigger/event-trigger.diff.ts +126 -0
  128. package/src/core/objects/event-trigger/event-trigger.model.ts +106 -0
  129. package/src/core/objects/extension/changes/extension.alter.test.ts +58 -0
  130. package/src/core/objects/extension/changes/extension.alter.ts +78 -0
  131. package/src/core/objects/extension/changes/extension.base.ts +20 -0
  132. package/src/core/objects/extension/changes/extension.comment.ts +64 -0
  133. package/src/core/objects/extension/changes/extension.create.test.ts +25 -0
  134. package/src/core/objects/extension/changes/extension.create.ts +63 -0
  135. package/src/core/objects/extension/changes/extension.drop.test.ts +23 -0
  136. package/src/core/objects/extension/changes/extension.drop.ts +34 -0
  137. package/src/core/objects/extension/changes/extension.types.ts +10 -0
  138. package/src/core/objects/extension/extension.diff.test.ts +42 -0
  139. package/src/core/objects/extension/extension.diff.ts +90 -0
  140. package/src/core/objects/extension/extension.model.ts +280 -0
  141. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.test.ts +125 -0
  142. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.ts +101 -0
  143. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.base.ts +20 -0
  144. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.comment.ts +72 -0
  145. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.test.ts +125 -0
  146. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.ts +95 -0
  147. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.test.ts +23 -0
  148. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.ts +36 -0
  149. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.privilege.ts +172 -0
  150. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.types.ts +12 -0
  151. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.test.ts +179 -0
  152. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.ts +341 -0
  153. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.ts +149 -0
  154. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper.types.ts +10 -0
  155. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.test.ts +309 -0
  156. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.ts +341 -0
  157. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.ts +20 -0
  158. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.comment.ts +72 -0
  159. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.test.ts +201 -0
  160. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.ts +81 -0
  161. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.test.ts +43 -0
  162. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.ts +37 -0
  163. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.privilege.ts +181 -0
  164. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.ts +12 -0
  165. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.test.ts +813 -0
  166. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +406 -0
  167. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +242 -0
  168. package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.test.ts +168 -0
  169. package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.ts +126 -0
  170. package/src/core/objects/foreign-data-wrapper/server/changes/server.base.ts +20 -0
  171. package/src/core/objects/foreign-data-wrapper/server/changes/server.comment.ts +60 -0
  172. package/src/core/objects/foreign-data-wrapper/server/changes/server.create.test.ts +131 -0
  173. package/src/core/objects/foreign-data-wrapper/server/changes/server.create.ts +81 -0
  174. package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.test.ts +24 -0
  175. package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.ts +34 -0
  176. package/src/core/objects/foreign-data-wrapper/server/changes/server.privilege.ts +164 -0
  177. package/src/core/objects/foreign-data-wrapper/server/changes/server.types.ts +12 -0
  178. package/src/core/objects/foreign-data-wrapper/server/server.diff.test.ts +167 -0
  179. package/src/core/objects/foreign-data-wrapper/server/server.diff.ts +317 -0
  180. package/src/core/objects/foreign-data-wrapper/server/server.model.ts +133 -0
  181. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.test.ts +82 -0
  182. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.ts +69 -0
  183. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.base.ts +20 -0
  184. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.test.ts +85 -0
  185. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.ts +66 -0
  186. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.test.ts +53 -0
  187. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.ts +40 -0
  188. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.types.ts +8 -0
  189. package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.diff.test.ts +77 -0
  190. package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.diff.ts +107 -0
  191. package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.model.ts +96 -0
  192. package/src/core/objects/index/changes/index.alter.test.ts +200 -0
  193. package/src/core/objects/index/changes/index.alter.ts +144 -0
  194. package/src/core/objects/index/changes/index.base.ts +20 -0
  195. package/src/core/objects/index/changes/index.comment.ts +63 -0
  196. package/src/core/objects/index/changes/index.create.test.ts +66 -0
  197. package/src/core/objects/index/changes/index.create.ts +68 -0
  198. package/src/core/objects/index/changes/index.drop.test.ts +44 -0
  199. package/src/core/objects/index/changes/index.drop.ts +34 -0
  200. package/src/core/objects/index/changes/index.types.ts +6 -0
  201. package/src/core/objects/index/changes/utils.ts +16 -0
  202. package/src/core/objects/index/index.diff.test.ts +153 -0
  203. package/src/core/objects/index/index.diff.ts +243 -0
  204. package/src/core/objects/index/index.model.ts +370 -0
  205. package/src/core/objects/language/changes/language.alter.test.ts +33 -0
  206. package/src/core/objects/language/changes/language.alter.ts +53 -0
  207. package/src/core/objects/language/changes/language.base.ts +20 -0
  208. package/src/core/objects/language/changes/language.comment.ts +58 -0
  209. package/src/core/objects/language/changes/language.create.test.ts +27 -0
  210. package/src/core/objects/language/changes/language.create.ts +104 -0
  211. package/src/core/objects/language/changes/language.drop.test.ts +25 -0
  212. package/src/core/objects/language/changes/language.drop.ts +39 -0
  213. package/src/core/objects/language/changes/language.privilege.ts +172 -0
  214. package/src/core/objects/language/changes/language.types.ts +12 -0
  215. package/src/core/objects/language/language.diff.test.ts +53 -0
  216. package/src/core/objects/language/language.diff.ts +176 -0
  217. package/src/core/objects/language/language.model.ts +150 -0
  218. package/src/core/objects/materialized-view/changes/materialized-view.alter.test.ts +123 -0
  219. package/src/core/objects/materialized-view/changes/materialized-view.alter.ts +113 -0
  220. package/src/core/objects/materialized-view/changes/materialized-view.base.ts +20 -0
  221. package/src/core/objects/materialized-view/changes/materialized-view.comment.ts +176 -0
  222. package/src/core/objects/materialized-view/changes/materialized-view.create.test.ts +64 -0
  223. package/src/core/objects/materialized-view/changes/materialized-view.create.ts +93 -0
  224. package/src/core/objects/materialized-view/changes/materialized-view.drop.test.ts +34 -0
  225. package/src/core/objects/materialized-view/changes/materialized-view.drop.ts +60 -0
  226. package/src/core/objects/materialized-view/changes/materialized-view.privilege.ts +212 -0
  227. package/src/core/objects/materialized-view/changes/materialized-view.types.ts +12 -0
  228. package/src/core/objects/materialized-view/materialized-view.diff.test.ts +102 -0
  229. package/src/core/objects/materialized-view/materialized-view.diff.ts +451 -0
  230. package/src/core/objects/materialized-view/materialized-view.model.ts +258 -0
  231. package/src/core/objects/procedure/changes/procedure.alter.test.ts +1005 -0
  232. package/src/core/objects/procedure/changes/procedure.alter.ts +287 -0
  233. package/src/core/objects/procedure/changes/procedure.base.ts +20 -0
  234. package/src/core/objects/procedure/changes/procedure.comment.ts +70 -0
  235. package/src/core/objects/procedure/changes/procedure.create.test.ts +48 -0
  236. package/src/core/objects/procedure/changes/procedure.create.ts +92 -0
  237. package/src/core/objects/procedure/changes/procedure.drop.test.ts +85 -0
  238. package/src/core/objects/procedure/changes/procedure.drop.ts +49 -0
  239. package/src/core/objects/procedure/changes/procedure.privilege.ts +188 -0
  240. package/src/core/objects/procedure/changes/procedure.types.ts +12 -0
  241. package/src/core/objects/procedure/procedure.diff.test.ts +161 -0
  242. package/src/core/objects/procedure/procedure.diff.ts +404 -0
  243. package/src/core/objects/procedure/procedure.model.ts +264 -0
  244. package/src/core/objects/procedure/utils.ts +58 -0
  245. package/src/core/objects/publication/changes/publication.alter.test.ts +223 -0
  246. package/src/core/objects/publication/changes/publication.alter.ts +243 -0
  247. package/src/core/objects/publication/changes/publication.base.ts +20 -0
  248. package/src/core/objects/publication/changes/publication.comment.test.ts +70 -0
  249. package/src/core/objects/publication/changes/publication.comment.ts +64 -0
  250. package/src/core/objects/publication/changes/publication.create.test.ts +87 -0
  251. package/src/core/objects/publication/changes/publication.create.ts +82 -0
  252. package/src/core/objects/publication/changes/publication.drop.test.ts +46 -0
  253. package/src/core/objects/publication/changes/publication.drop.ts +29 -0
  254. package/src/core/objects/publication/changes/publication.types.ts +26 -0
  255. package/src/core/objects/publication/publication.diff.test.ts +292 -0
  256. package/src/core/objects/publication/publication.diff.ts +253 -0
  257. package/src/core/objects/publication/publication.model.ts +206 -0
  258. package/src/core/objects/publication/utils.ts +55 -0
  259. package/src/core/objects/rls-policy/changes/rls-policy.alter.test.ts +250 -0
  260. package/src/core/objects/rls-policy/changes/rls-policy.alter.ts +128 -0
  261. package/src/core/objects/rls-policy/changes/rls-policy.base.ts +20 -0
  262. package/src/core/objects/rls-policy/changes/rls-policy.comment.ts +69 -0
  263. package/src/core/objects/rls-policy/changes/rls-policy.create.test.ts +74 -0
  264. package/src/core/objects/rls-policy/changes/rls-policy.create.ts +100 -0
  265. package/src/core/objects/rls-policy/changes/rls-policy.drop.test.ts +28 -0
  266. package/src/core/objects/rls-policy/changes/rls-policy.drop.ts +39 -0
  267. package/src/core/objects/rls-policy/changes/rls-policy.types.ts +10 -0
  268. package/src/core/objects/rls-policy/rls-policy.diff.test.ts +79 -0
  269. package/src/core/objects/rls-policy/rls-policy.diff.ts +121 -0
  270. package/src/core/objects/rls-policy/rls-policy.model.ts +140 -0
  271. package/src/core/objects/role/changes/role.alter.test.ts +346 -0
  272. package/src/core/objects/role/changes/role.alter.ts +110 -0
  273. package/src/core/objects/role/changes/role.base.ts +24 -0
  274. package/src/core/objects/role/changes/role.comment.ts +55 -0
  275. package/src/core/objects/role/changes/role.create.test.ts +52 -0
  276. package/src/core/objects/role/changes/role.create.ts +102 -0
  277. package/src/core/objects/role/changes/role.drop.test.ts +29 -0
  278. package/src/core/objects/role/changes/role.drop.ts +34 -0
  279. package/src/core/objects/role/changes/role.privilege.ts +376 -0
  280. package/src/core/objects/role/changes/role.types.ts +12 -0
  281. package/src/core/objects/role/role.diff.test.ts +44 -0
  282. package/src/core/objects/role/role.diff.ts +479 -0
  283. package/src/core/objects/role/role.model.ts +344 -0
  284. package/src/core/objects/rule/changes/rule.alter.test.ts +78 -0
  285. package/src/core/objects/rule/changes/rule.alter.ts +72 -0
  286. package/src/core/objects/rule/changes/rule.base.ts +20 -0
  287. package/src/core/objects/rule/changes/rule.comment.test.ts +55 -0
  288. package/src/core/objects/rule/changes/rule.comment.ts +62 -0
  289. package/src/core/objects/rule/changes/rule.create.test.ts +59 -0
  290. package/src/core/objects/rule/changes/rule.create.ts +42 -0
  291. package/src/core/objects/rule/changes/rule.drop.test.ts +38 -0
  292. package/src/core/objects/rule/changes/rule.drop.ts +29 -0
  293. package/src/core/objects/rule/changes/rule.types.ts +12 -0
  294. package/src/core/objects/rule/rule.diff.test.ts +132 -0
  295. package/src/core/objects/rule/rule.diff.ts +79 -0
  296. package/src/core/objects/rule/rule.model.ts +173 -0
  297. package/src/core/objects/schema/changes/schema.alter.test.ts +28 -0
  298. package/src/core/objects/schema/changes/schema.alter.ts +45 -0
  299. package/src/core/objects/schema/changes/schema.base.ts +20 -0
  300. package/src/core/objects/schema/changes/schema.comment.ts +56 -0
  301. package/src/core/objects/schema/changes/schema.create.test.ts +22 -0
  302. package/src/core/objects/schema/changes/schema.create.ts +47 -0
  303. package/src/core/objects/schema/changes/schema.drop.test.ts +20 -0
  304. package/src/core/objects/schema/changes/schema.drop.ts +34 -0
  305. package/src/core/objects/schema/changes/schema.privilege.ts +175 -0
  306. package/src/core/objects/schema/changes/schema.types.ts +12 -0
  307. package/src/core/objects/schema/schema.diff.test.ts +42 -0
  308. package/src/core/objects/schema/schema.diff.ts +209 -0
  309. package/src/core/objects/schema/schema.model.ts +107 -0
  310. package/src/core/objects/sequence/changes/sequence.alter.test.ts +151 -0
  311. package/src/core/objects/sequence/changes/sequence.alter.ts +115 -0
  312. package/src/core/objects/sequence/changes/sequence.base.ts +20 -0
  313. package/src/core/objects/sequence/changes/sequence.comment.ts +60 -0
  314. package/src/core/objects/sequence/changes/sequence.create.test.ts +84 -0
  315. package/src/core/objects/sequence/changes/sequence.create.ts +111 -0
  316. package/src/core/objects/sequence/changes/sequence.drop.test.ts +32 -0
  317. package/src/core/objects/sequence/changes/sequence.drop.ts +37 -0
  318. package/src/core/objects/sequence/changes/sequence.privilege.ts +179 -0
  319. package/src/core/objects/sequence/changes/sequence.types.ts +12 -0
  320. package/src/core/objects/sequence/sequence.diff.test.ts +141 -0
  321. package/src/core/objects/sequence/sequence.diff.ts +359 -0
  322. package/src/core/objects/sequence/sequence.model.ts +185 -0
  323. package/src/core/objects/subscription/changes/subscription.alter.test.ts +124 -0
  324. package/src/core/objects/subscription/changes/subscription.alter.ts +110 -0
  325. package/src/core/objects/subscription/changes/subscription.base.ts +20 -0
  326. package/src/core/objects/subscription/changes/subscription.comment.test.ts +67 -0
  327. package/src/core/objects/subscription/changes/subscription.comment.ts +64 -0
  328. package/src/core/objects/subscription/changes/subscription.create.test.ts +77 -0
  329. package/src/core/objects/subscription/changes/subscription.create.ts +69 -0
  330. package/src/core/objects/subscription/changes/subscription.drop.test.ts +46 -0
  331. package/src/core/objects/subscription/changes/subscription.drop.ts +20 -0
  332. package/src/core/objects/subscription/changes/subscription.types.ts +22 -0
  333. package/src/core/objects/subscription/subscription.diff.test.ts +232 -0
  334. package/src/core/objects/subscription/subscription.diff.ts +241 -0
  335. package/src/core/objects/subscription/subscription.model.ts +190 -0
  336. package/src/core/objects/subscription/utils.ts +156 -0
  337. package/src/core/objects/table/changes/table.alter.test.ts +823 -0
  338. package/src/core/objects/table/changes/table.alter.ts +806 -0
  339. package/src/core/objects/table/changes/table.base.ts +20 -0
  340. package/src/core/objects/table/changes/table.comment.ts +266 -0
  341. package/src/core/objects/table/changes/table.create.test.ts +150 -0
  342. package/src/core/objects/table/changes/table.create.ts +188 -0
  343. package/src/core/objects/table/changes/table.drop.test.ts +34 -0
  344. package/src/core/objects/table/changes/table.drop.ts +45 -0
  345. package/src/core/objects/table/changes/table.privilege.ts +200 -0
  346. package/src/core/objects/table/changes/table.types.ts +12 -0
  347. package/src/core/objects/table/table.diff.test.ts +711 -0
  348. package/src/core/objects/table/table.diff.ts +953 -0
  349. package/src/core/objects/table/table.model.ts +460 -0
  350. package/src/core/objects/trigger/changes/trigger.alter.test.ts +46 -0
  351. package/src/core/objects/trigger/changes/trigger.alter.ts +76 -0
  352. package/src/core/objects/trigger/changes/trigger.base.ts +20 -0
  353. package/src/core/objects/trigger/changes/trigger.comment.ts +64 -0
  354. package/src/core/objects/trigger/changes/trigger.create.test.ts +43 -0
  355. package/src/core/objects/trigger/changes/trigger.create.ts +85 -0
  356. package/src/core/objects/trigger/changes/trigger.drop.test.ts +43 -0
  357. package/src/core/objects/trigger/changes/trigger.drop.ts +39 -0
  358. package/src/core/objects/trigger/changes/trigger.types.ts +10 -0
  359. package/src/core/objects/trigger/trigger.diff.test.ts +83 -0
  360. package/src/core/objects/trigger/trigger.diff.ts +116 -0
  361. package/src/core/objects/trigger/trigger.model.ts +252 -0
  362. package/src/core/objects/type/composite-type/changes/composite-type.alter.test.ts +202 -0
  363. package/src/core/objects/type/composite-type/changes/composite-type.alter.ts +174 -0
  364. package/src/core/objects/type/composite-type/changes/composite-type.base.ts +20 -0
  365. package/src/core/objects/type/composite-type/changes/composite-type.comment.ts +145 -0
  366. package/src/core/objects/type/composite-type/changes/composite-type.create.test.ts +101 -0
  367. package/src/core/objects/type/composite-type/changes/composite-type.create.ts +95 -0
  368. package/src/core/objects/type/composite-type/changes/composite-type.drop.test.ts +33 -0
  369. package/src/core/objects/type/composite-type/changes/composite-type.drop.ts +37 -0
  370. package/src/core/objects/type/composite-type/changes/composite-type.privilege.ts +175 -0
  371. package/src/core/objects/type/composite-type/changes/composite-type.types.ts +12 -0
  372. package/src/core/objects/type/composite-type/composite-type.diff.test.ts +191 -0
  373. package/src/core/objects/type/composite-type/composite-type.diff.ts +372 -0
  374. package/src/core/objects/type/composite-type/composite-type.model.ts +252 -0
  375. package/src/core/objects/type/enum/changes/enum.alter.test.ts +104 -0
  376. package/src/core/objects/type/enum/changes/enum.alter.ts +91 -0
  377. package/src/core/objects/type/enum/changes/enum.base.ts +20 -0
  378. package/src/core/objects/type/enum/changes/enum.comment.ts +64 -0
  379. package/src/core/objects/type/enum/changes/enum.create.test.ts +28 -0
  380. package/src/core/objects/type/enum/changes/enum.create.ts +56 -0
  381. package/src/core/objects/type/enum/changes/enum.drop.test.ts +25 -0
  382. package/src/core/objects/type/enum/changes/enum.drop.ts +34 -0
  383. package/src/core/objects/type/enum/changes/enum.privilege.ts +175 -0
  384. package/src/core/objects/type/enum/changes/enum.types.ts +12 -0
  385. package/src/core/objects/type/enum/enum.diff.test.ts +191 -0
  386. package/src/core/objects/type/enum/enum.diff.ts +396 -0
  387. package/src/core/objects/type/enum/enum.model.ts +194 -0
  388. package/src/core/objects/type/range/changes/range.alter.test.ts +27 -0
  389. package/src/core/objects/type/range/changes/range.alter.ts +51 -0
  390. package/src/core/objects/type/range/changes/range.base.ts +20 -0
  391. package/src/core/objects/type/range/changes/range.comment.ts +64 -0
  392. package/src/core/objects/type/range/changes/range.create.test.ts +51 -0
  393. package/src/core/objects/type/range/changes/range.create.ts +151 -0
  394. package/src/core/objects/type/range/changes/range.drop.test.ts +26 -0
  395. package/src/core/objects/type/range/changes/range.drop.ts +34 -0
  396. package/src/core/objects/type/range/changes/range.privilege.ts +175 -0
  397. package/src/core/objects/type/range/changes/range.types.ts +12 -0
  398. package/src/core/objects/type/range/range.diff.test.ts +70 -0
  399. package/src/core/objects/type/range/range.diff.ts +259 -0
  400. package/src/core/objects/type/range/range.model.ts +187 -0
  401. package/src/core/objects/type/type.types.ts +5 -0
  402. package/src/core/objects/utils.ts +171 -0
  403. package/src/core/objects/view/changes/view.alter.test.ts +110 -0
  404. package/src/core/objects/view/changes/view.alter.ts +112 -0
  405. package/src/core/objects/view/changes/view.base.ts +20 -0
  406. package/src/core/objects/view/changes/view.comment.ts +59 -0
  407. package/src/core/objects/view/changes/view.create.test.ts +65 -0
  408. package/src/core/objects/view/changes/view.create.ts +73 -0
  409. package/src/core/objects/view/changes/view.drop.test.ts +34 -0
  410. package/src/core/objects/view/changes/view.drop.ts +40 -0
  411. package/src/core/objects/view/changes/view.privilege.ts +200 -0
  412. package/src/core/objects/view/changes/view.types.ts +12 -0
  413. package/src/core/objects/view/view.diff.test.ts +91 -0
  414. package/src/core/objects/view/view.diff.ts +365 -0
  415. package/src/core/objects/view/view.model.ts +276 -0
  416. package/src/core/plan/apply.ts +190 -0
  417. package/src/core/plan/create.ts +432 -0
  418. package/src/core/plan/hierarchy.ts +574 -0
  419. package/src/core/plan/index.ts +29 -0
  420. package/src/core/plan/io.ts +20 -0
  421. package/src/core/plan/risk.ts +48 -0
  422. package/src/core/plan/serialize.ts +195 -0
  423. package/src/core/plan/sql-format/constants.ts +13 -0
  424. package/src/core/plan/sql-format/fixtures.ts +2806 -0
  425. package/src/core/plan/sql-format/format-comment-literals.test.ts +96 -0
  426. package/src/core/plan/sql-format/format-functions.test.ts +127 -0
  427. package/src/core/plan/sql-format/format-lowercase-coverage.test.ts +67 -0
  428. package/src/core/plan/sql-format/format-off.test.ts +809 -0
  429. package/src/core/plan/sql-format/format-pretty-lower-leading.test.ts +1056 -0
  430. package/src/core/plan/sql-format/format-pretty-narrow.test.ts +1283 -0
  431. package/src/core/plan/sql-format/format-pretty-preserve.test.ts +1052 -0
  432. package/src/core/plan/sql-format/format-pretty-upper.test.ts +1045 -0
  433. package/src/core/plan/sql-format/format-stress.test.ts +616 -0
  434. package/src/core/plan/sql-format/format-utils.test.ts +91 -0
  435. package/src/core/plan/sql-format/format-utils.ts +391 -0
  436. package/src/core/plan/sql-format/formatters.ts +921 -0
  437. package/src/core/plan/sql-format/index.ts +149 -0
  438. package/src/core/plan/sql-format/keyword-case.test.ts +118 -0
  439. package/src/core/plan/sql-format/keyword-case.ts +1085 -0
  440. package/src/core/plan/sql-format/protect.test.ts +127 -0
  441. package/src/core/plan/sql-format/protect.ts +337 -0
  442. package/src/core/plan/sql-format/sql-scanner.test.ts +240 -0
  443. package/src/core/plan/sql-format/sql-scanner.ts +252 -0
  444. package/src/core/plan/sql-format/tokenizer.test.ts +68 -0
  445. package/src/core/plan/sql-format/tokenizer.ts +152 -0
  446. package/src/core/plan/sql-format/types.ts +31 -0
  447. package/src/core/plan/sql-format/wrap.test.ts +119 -0
  448. package/src/core/plan/sql-format/wrap.ts +196 -0
  449. package/src/core/plan/sql-format.ts +2 -0
  450. package/src/core/plan/statements.ts +22 -0
  451. package/src/core/plan/types.ts +165 -0
  452. package/src/core/postgres-config.ts +169 -0
  453. package/src/core/sort/custom-constraints.ts +161 -0
  454. package/src/core/sort/debug-visualization.ts +239 -0
  455. package/src/core/sort/dependency-filter.ts +224 -0
  456. package/src/core/sort/graph-builder.ts +223 -0
  457. package/src/core/sort/graph-utils.ts +51 -0
  458. package/src/core/sort/logical-sort.ts +590 -0
  459. package/src/core/sort/sort-changes.ts +234 -0
  460. package/src/core/sort/topological-sort.ts +184 -0
  461. package/src/core/sort/types.ts +112 -0
  462. package/src/core/sort/utils.ts +69 -0
  463. package/src/index.ts +14 -0
@@ -0,0 +1,574 @@
1
+ /**
2
+ * Hierarchical grouping of changes for tree display.
3
+ */
4
+
5
+ import type { Change } from "../change.types.ts";
6
+ import type { DiffContext } from "../context.ts";
7
+ import {
8
+ AlterTableAddColumn,
9
+ AlterTableAlterColumnDropDefault,
10
+ AlterTableAlterColumnDropNotNull,
11
+ AlterTableAlterColumnSetDefault,
12
+ AlterTableAlterColumnSetNotNull,
13
+ AlterTableAlterColumnType,
14
+ AlterTableDropColumn,
15
+ } from "../objects/table/changes/table.alter.ts";
16
+ import { CreateTable } from "../objects/table/changes/table.create.ts";
17
+ import { getObjectSchema, getParentInfo } from "./serialize.ts";
18
+ import type {
19
+ ChangeGroup,
20
+ ClusterGroup,
21
+ HierarchicalPlan,
22
+ MaterializedViewChildren,
23
+ SchemaGroup,
24
+ TableChildren,
25
+ TypeGroup,
26
+ } from "./types.ts";
27
+
28
+ // ============================================================================
29
+ // Empty Structure Factories
30
+ // ============================================================================
31
+
32
+ /**
33
+ * Create an empty ChangeGroup.
34
+ */
35
+ function emptyChangeGroup(): ChangeGroup {
36
+ return { create: [], alter: [], drop: [] };
37
+ }
38
+
39
+ /**
40
+ * Create an empty TableChildren structure.
41
+ */
42
+ function emptyTableChildren(): TableChildren {
43
+ return {
44
+ changes: emptyChangeGroup(),
45
+ columns: emptyChangeGroup(),
46
+ indexes: emptyChangeGroup(),
47
+ triggers: emptyChangeGroup(),
48
+ rules: emptyChangeGroup(),
49
+ policies: emptyChangeGroup(),
50
+ partitions: {},
51
+ };
52
+ }
53
+
54
+ /**
55
+ * Create an empty MaterializedViewChildren structure.
56
+ */
57
+ function emptyMaterializedViewChildren(): MaterializedViewChildren {
58
+ return {
59
+ changes: emptyChangeGroup(),
60
+ indexes: emptyChangeGroup(),
61
+ };
62
+ }
63
+
64
+ /**
65
+ * Create an empty TypeGroup structure.
66
+ */
67
+ function emptyTypeGroup(): TypeGroup {
68
+ return {
69
+ enums: emptyChangeGroup(),
70
+ composites: emptyChangeGroup(),
71
+ ranges: emptyChangeGroup(),
72
+ domains: emptyChangeGroup(),
73
+ };
74
+ }
75
+
76
+ /**
77
+ * Create an empty SchemaGroup structure.
78
+ */
79
+ function emptySchemaGroup(): SchemaGroup {
80
+ return {
81
+ changes: emptyChangeGroup(),
82
+ tables: {},
83
+ views: {},
84
+ materializedViews: {},
85
+ functions: emptyChangeGroup(),
86
+ procedures: emptyChangeGroup(),
87
+ aggregates: emptyChangeGroup(),
88
+ sequences: emptyChangeGroup(),
89
+ types: emptyTypeGroup(),
90
+ collations: emptyChangeGroup(),
91
+ foreignTables: {},
92
+ };
93
+ }
94
+
95
+ /**
96
+ * Create an empty ClusterGroup structure.
97
+ */
98
+ function emptyClusterGroup(): ClusterGroup {
99
+ return {
100
+ roles: emptyChangeGroup(),
101
+ extensions: emptyChangeGroup(),
102
+ eventTriggers: emptyChangeGroup(),
103
+ publications: emptyChangeGroup(),
104
+ subscriptions: emptyChangeGroup(),
105
+ foreignDataWrappers: emptyChangeGroup(),
106
+ servers: emptyChangeGroup(),
107
+ userMappings: emptyChangeGroup(),
108
+ };
109
+ }
110
+
111
+ // ============================================================================
112
+ // Helpers
113
+ // ============================================================================
114
+
115
+ /**
116
+ * Add a change to a ChangeGroup based on its operation.
117
+ */
118
+ function addToChangeGroup(group: ChangeGroup, change: Change): void {
119
+ group[change.operation].push({ original: change });
120
+ }
121
+
122
+ /**
123
+ * Check if a Change is a column operation (ADD/DROP/ALTER COLUMN).
124
+ * Uses instanceof checks for type safety.
125
+ */
126
+ function isColumnOperation(change: Change): string | null {
127
+ if (change.objectType !== "table") {
128
+ return null;
129
+ }
130
+
131
+ if (
132
+ change instanceof AlterTableAddColumn ||
133
+ change instanceof AlterTableDropColumn ||
134
+ change instanceof AlterTableAlterColumnType ||
135
+ change instanceof AlterTableAlterColumnSetDefault ||
136
+ change instanceof AlterTableAlterColumnDropDefault ||
137
+ change instanceof AlterTableAlterColumnSetNotNull ||
138
+ change instanceof AlterTableAlterColumnDropNotNull
139
+ ) {
140
+ return change.column.name;
141
+ }
142
+
143
+ return null;
144
+ }
145
+
146
+ /**
147
+ * Check if a Change creates a partition table.
148
+ * Returns the parent table name if it's a partition, null otherwise.
149
+ * Uses instanceof checks for type safety.
150
+ *
151
+ * IMPORTANT: This function should ONLY be called for table changes.
152
+ * Materialized views and other object types should never reach this function.
153
+ */
154
+ function isPartitionTable(change: Change): string | null {
155
+ // First check: must be a table change
156
+ if (change.objectType !== "table") {
157
+ return null;
158
+ }
159
+
160
+ // Second check: must be a CreateTable change (only CreateTable can create partitions)
161
+ // Use instanceof to safely verify the change type
162
+ if (!(change instanceof CreateTable)) {
163
+ return null;
164
+ }
165
+
166
+ // Third check: verify the table is actually marked as a partition
167
+ // Both is_partition flag AND parent_name must be set
168
+ if (!change.table.is_partition || !change.table.parent_name) {
169
+ return null;
170
+ }
171
+
172
+ return change.table.parent_name;
173
+ }
174
+
175
+ /**
176
+ * Check if a table name (from an AlterTable change) is an existing partition.
177
+ * Checks both mainCatalog and branchCatalog to see if the table is a partition.
178
+ * Returns the parent table name if found, null otherwise.
179
+ */
180
+ function isExistingPartition(
181
+ ctx: DiffContext,
182
+ schemaName: string,
183
+ tableName: string,
184
+ ): string | null {
185
+ const tableKey = `${schemaName}.${tableName}`;
186
+
187
+ // Check branchCatalog first (target state - where partitions should be)
188
+ const branchTable = ctx.branchCatalog.tables[tableKey];
189
+ if (branchTable?.is_partition && branchTable.parent_name) {
190
+ return branchTable.parent_name;
191
+ }
192
+
193
+ // Also check mainCatalog (source state)
194
+ const mainTable = ctx.mainCatalog.tables[tableKey];
195
+ if (mainTable?.is_partition && mainTable.parent_name) {
196
+ return mainTable.parent_name;
197
+ }
198
+
199
+ return null;
200
+ }
201
+
202
+ // ============================================================================
203
+ // Main Grouping Function
204
+ // ============================================================================
205
+
206
+ /**
207
+ * Group changes into a hierarchical structure for tree display.
208
+ *
209
+ * This function takes original Change objects (not SerializedChange) to enable
210
+ * detection of column operations, partitions, and other type-specific details.
211
+ *
212
+ * Organizes changes by:
213
+ * 1. Cluster-wide vs schema-scoped
214
+ * 2. Schema > Object Type > Object Name
215
+ * 3. Parent > Child (e.g., Table > Index, Table > Column)
216
+ * 4. Partitioned Table > Partition
217
+ */
218
+ export function groupChangesHierarchically(
219
+ ctx: DiffContext,
220
+ changes: Change[],
221
+ ): HierarchicalPlan {
222
+ const result: HierarchicalPlan = {
223
+ cluster: emptyClusterGroup(),
224
+ schemas: {},
225
+ };
226
+
227
+ for (const change of changes) {
228
+ const columnName = isColumnOperation(change);
229
+ // Check for partitions: either creating a new partition (CreateTable) or any change on an existing partition
230
+ let partitionOf: string | null = null;
231
+ const changeSchema = getObjectSchema(change);
232
+ if (change.objectType === "table" && changeSchema) {
233
+ // First check if this is a CreateTable creating a partition
234
+ partitionOf = isPartitionTable(change);
235
+ // If not, check if this table is an existing partition (for any table change including privilege changes)
236
+ if (!partitionOf) {
237
+ partitionOf = isExistingPartition(ctx, changeSchema, change.table.name);
238
+ }
239
+ }
240
+
241
+ if (!changeSchema) {
242
+ addClusterChange(result.cluster, change);
243
+ continue;
244
+ }
245
+
246
+ if (!result.schemas[changeSchema]) {
247
+ result.schemas[changeSchema] = emptySchemaGroup();
248
+ }
249
+ const schemaGroup = result.schemas[changeSchema];
250
+
251
+ const parent = getParentInfo(change);
252
+ if (parent) {
253
+ addChildChange(schemaGroup, change);
254
+ continue;
255
+ }
256
+
257
+ addSchemaLevelChange(schemaGroup, change, {
258
+ columnName,
259
+ partitionOf,
260
+ });
261
+ }
262
+
263
+ return result;
264
+ }
265
+
266
+ // ============================================================================
267
+ // Add Functions (exhaustive on object types)
268
+ // ============================================================================
269
+
270
+ /**
271
+ * Add a change to the cluster group (exhaustive on cluster-wide types).
272
+ */
273
+ function addClusterChange(cluster: ClusterGroup, change: Change): void {
274
+ const objectType = change.objectType;
275
+
276
+ switch (objectType) {
277
+ case "role":
278
+ addToChangeGroup(cluster.roles, change);
279
+ break;
280
+ case "extension":
281
+ addToChangeGroup(cluster.extensions, change);
282
+ break;
283
+ case "event_trigger":
284
+ addToChangeGroup(cluster.eventTriggers, change);
285
+ break;
286
+ case "language":
287
+ // Languages are cluster-wide, but we don't have a group for them yet
288
+ break;
289
+ case "publication":
290
+ addToChangeGroup(cluster.publications, change);
291
+ break;
292
+ case "subscription":
293
+ addToChangeGroup(cluster.subscriptions, change);
294
+ break;
295
+ case "foreign_data_wrapper":
296
+ addToChangeGroup(cluster.foreignDataWrappers, change);
297
+ break;
298
+ case "server":
299
+ addToChangeGroup(cluster.servers, change);
300
+ break;
301
+ case "user_mapping":
302
+ addToChangeGroup(cluster.userMappings, change);
303
+ break;
304
+ case "aggregate":
305
+ case "collation":
306
+ case "composite_type":
307
+ case "domain":
308
+ case "enum":
309
+ case "foreign_table":
310
+ case "index":
311
+ case "materialized_view":
312
+ case "procedure":
313
+ case "range":
314
+ case "rls_policy":
315
+ case "rule":
316
+ case "schema":
317
+ case "sequence":
318
+ case "table":
319
+ case "trigger":
320
+ case "view":
321
+ // These have schemas and shouldn't be added to cluster group
322
+ break;
323
+ default: {
324
+ const _exhaustive: never = objectType;
325
+ throw new Error(`Unhandled object type: ${_exhaustive}`);
326
+ }
327
+ }
328
+ }
329
+
330
+ /**
331
+ * Add a child change (index, trigger, policy, rule) to its parent (exhaustive).
332
+ */
333
+ function addChildChange(schema: SchemaGroup, change: Change): void {
334
+ const parentInfo = getParentInfo(change);
335
+ if (!parentInfo) return;
336
+
337
+ const parentName = parentInfo.name;
338
+ const parentType = parentInfo.type;
339
+
340
+ let parentGroup: TableChildren | MaterializedViewChildren;
341
+
342
+ switch (parentType) {
343
+ case "table":
344
+ if (!schema.tables[parentName]) {
345
+ schema.tables[parentName] = emptyTableChildren();
346
+ }
347
+ parentGroup = schema.tables[parentName];
348
+ break;
349
+ case "view":
350
+ if (!schema.views[parentName]) {
351
+ schema.views[parentName] = emptyTableChildren();
352
+ }
353
+ parentGroup = schema.views[parentName];
354
+ break;
355
+ case "materialized_view":
356
+ if (!schema.materializedViews[parentName]) {
357
+ schema.materializedViews[parentName] = emptyMaterializedViewChildren();
358
+ }
359
+ parentGroup = schema.materializedViews[parentName];
360
+ break;
361
+ case "foreign_table":
362
+ if (!schema.foreignTables[parentName]) {
363
+ schema.foreignTables[parentName] = emptyTableChildren();
364
+ }
365
+ parentGroup = schema.foreignTables[parentName];
366
+ break;
367
+ default: {
368
+ const _exhaustive: never = parentType;
369
+ throw new Error(`Unhandled parent type: ${_exhaustive}`);
370
+ }
371
+ }
372
+
373
+ const objectType = change.objectType;
374
+
375
+ switch (objectType) {
376
+ case "index":
377
+ addToChangeGroup(parentGroup.indexes, change);
378
+ break;
379
+ case "trigger":
380
+ if ("triggers" in parentGroup) {
381
+ addToChangeGroup(parentGroup.triggers, change);
382
+ }
383
+ break;
384
+ case "rule":
385
+ if ("rules" in parentGroup) {
386
+ addToChangeGroup(parentGroup.rules, change);
387
+ }
388
+ break;
389
+ case "rls_policy":
390
+ if ("policies" in parentGroup) {
391
+ addToChangeGroup(parentGroup.policies, change);
392
+ }
393
+ break;
394
+ case "aggregate":
395
+ case "collation":
396
+ case "composite_type":
397
+ case "domain":
398
+ case "enum":
399
+ case "event_trigger":
400
+ case "extension":
401
+ case "foreign_data_wrapper":
402
+ case "foreign_table":
403
+ case "language":
404
+ case "materialized_view":
405
+ case "procedure":
406
+ case "publication":
407
+ case "range":
408
+ case "role":
409
+ case "schema":
410
+ case "sequence":
411
+ case "server":
412
+ case "subscription":
413
+ case "table":
414
+ case "user_mapping":
415
+ case "view":
416
+ break;
417
+ default: {
418
+ const _exhaustive: never = objectType;
419
+ throw new Error(`Unhandled object type: ${_exhaustive}`);
420
+ }
421
+ }
422
+ }
423
+
424
+ /**
425
+ * Enrichment info detected from original Change objects.
426
+ */
427
+ interface ChangeEnrichment {
428
+ columnName: string | null;
429
+ partitionOf: string | null;
430
+ }
431
+
432
+ /**
433
+ * Add a schema-level change to the appropriate group (exhaustive).
434
+ */
435
+ function addSchemaLevelChange(
436
+ schema: SchemaGroup,
437
+ change: Change,
438
+ enrichment: ChangeEnrichment,
439
+ ): void {
440
+ const objectType = change.objectType;
441
+
442
+ switch (objectType) {
443
+ case "schema":
444
+ addToChangeGroup(schema.changes, change);
445
+ break;
446
+ case "table": {
447
+ // Verify the original change is actually a table change
448
+ // (safeguard against materialized views or other objects being incorrectly routed here)
449
+ if (change.objectType !== "table") {
450
+ // This shouldn't happen, but if it does, skip this change
451
+ // It will be handled by its correct objectType case
452
+ break;
453
+ }
454
+
455
+ if (enrichment.columnName) {
456
+ const tableName = change.table.name;
457
+ if (!schema.tables[tableName]) {
458
+ schema.tables[tableName] = emptyTableChildren();
459
+ }
460
+ addToChangeGroup(schema.tables[tableName].columns, change);
461
+ break;
462
+ }
463
+
464
+ if (enrichment.partitionOf) {
465
+ // For CreateTable changes, verify it's actually a partition
466
+ if (change instanceof CreateTable) {
467
+ // Additional verification: ensure the table is actually marked as a partition
468
+ if (!change.table.is_partition || !change.table.parent_name) {
469
+ // Table has parent_name but is_partition is false (inheritance, not partitioning)
470
+ // Treat as regular table change
471
+ const tableName = change.table.name;
472
+ if (!schema.tables[tableName]) {
473
+ schema.tables[tableName] = emptyTableChildren();
474
+ }
475
+ addToChangeGroup(schema.tables[tableName].changes, change);
476
+ break;
477
+ }
478
+ }
479
+ // For AlterTable changes on existing partitions, enrichment.partitionOf comes from catalog lookup
480
+ // which is already verified, so we can trust it
481
+
482
+ const parentName = enrichment.partitionOf;
483
+ if (!schema.tables[parentName]) {
484
+ schema.tables[parentName] = emptyTableChildren();
485
+ }
486
+ const partitionName = change.table.name;
487
+ if (!schema.tables[parentName].partitions[partitionName]) {
488
+ schema.tables[parentName].partitions[partitionName] =
489
+ emptyTableChildren();
490
+ }
491
+ addToChangeGroup(
492
+ schema.tables[parentName].partitions[partitionName].changes,
493
+ change,
494
+ );
495
+ break;
496
+ }
497
+
498
+ const tableName = change.table.name;
499
+ if (!schema.tables[tableName]) {
500
+ schema.tables[tableName] = emptyTableChildren();
501
+ }
502
+ addToChangeGroup(schema.tables[tableName].changes, change);
503
+ break;
504
+ }
505
+ case "view": {
506
+ const viewName = change.view.name;
507
+ if (!schema.views[viewName]) {
508
+ schema.views[viewName] = emptyTableChildren();
509
+ }
510
+ addToChangeGroup(schema.views[viewName].changes, change);
511
+ break;
512
+ }
513
+ case "materialized_view": {
514
+ const matviewName = change.materializedView.name;
515
+ if (!schema.materializedViews[matviewName]) {
516
+ schema.materializedViews[matviewName] = emptyMaterializedViewChildren();
517
+ }
518
+ addToChangeGroup(schema.materializedViews[matviewName].changes, change);
519
+ break;
520
+ }
521
+ case "foreign_table": {
522
+ const ftName = change.foreignTable.name;
523
+ if (!schema.foreignTables[ftName]) {
524
+ schema.foreignTables[ftName] = emptyTableChildren();
525
+ }
526
+ addToChangeGroup(schema.foreignTables[ftName].changes, change);
527
+ break;
528
+ }
529
+ case "procedure":
530
+ addToChangeGroup(schema.functions, change);
531
+ break;
532
+ case "aggregate":
533
+ addToChangeGroup(schema.aggregates, change);
534
+ break;
535
+ case "sequence":
536
+ addToChangeGroup(schema.sequences, change);
537
+ break;
538
+ case "enum":
539
+ addToChangeGroup(schema.types.enums, change);
540
+ break;
541
+ case "composite_type":
542
+ addToChangeGroup(schema.types.composites, change);
543
+ break;
544
+ case "range":
545
+ addToChangeGroup(schema.types.ranges, change);
546
+ break;
547
+ case "domain":
548
+ addToChangeGroup(schema.types.domains, change);
549
+ break;
550
+ case "collation":
551
+ addToChangeGroup(schema.collations, change);
552
+ break;
553
+ case "extension":
554
+ break;
555
+ case "index":
556
+ case "trigger":
557
+ case "rule":
558
+ case "rls_policy":
559
+ break;
560
+ case "event_trigger":
561
+ case "foreign_data_wrapper":
562
+ case "language":
563
+ case "publication":
564
+ case "role":
565
+ case "server":
566
+ case "subscription":
567
+ case "user_mapping":
568
+ break;
569
+ default: {
570
+ const _exhaustive: never = objectType;
571
+ throw new Error(`Unhandled object type: ${_exhaustive}`);
572
+ }
573
+ }
574
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Plan module - create and organize migration plans.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * import { createPlan, groupChangesHierarchically } from "./plan";
7
+ *
8
+ * const planResult = await createPlan(fromUrl, toUrl);
9
+ * if (planResult) {
10
+ * const { plan, sortedChanges, ctx } = planResult;
11
+ * const hierarchy = groupChangesHierarchically(ctx, sortedChanges);
12
+ * console.log(plan.statements);
13
+ * }
14
+ * ```
15
+ */
16
+
17
+ // Plan creation
18
+ export { createPlan } from "./create.ts";
19
+ // Hierarchical grouping
20
+
21
+ // Plan I/O
22
+ export { deserializePlan, serializePlan } from "./io.ts";
23
+ // Types
24
+ export type {
25
+ ChangeEntry,
26
+ ChangeGroup,
27
+ HierarchicalPlan,
28
+ Plan,
29
+ } from "./types.ts";
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Plan I/O utilities for serializing and deserializing plans to/from JSON.
3
+ */
4
+
5
+ import { type Plan, PlanSchema } from "./types.ts";
6
+
7
+ /**
8
+ * Serialize a plan to JSON string.
9
+ */
10
+ export function serializePlan(plan: Plan): string {
11
+ return JSON.stringify(plan, null, 2);
12
+ }
13
+
14
+ /**
15
+ * Deserialize a plan from JSON string.
16
+ */
17
+ export function deserializePlan(json: string): Plan {
18
+ const parsed = JSON.parse(json);
19
+ return PlanSchema.parse(parsed);
20
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Risk classification for migration plans.
3
+ * Identifies data-loss operations that require explicit confirmation.
4
+ */
5
+
6
+ import type { Change } from "../change.types.ts";
7
+ import { DropSequence } from "../objects/sequence/changes/sequence.drop.ts";
8
+ import { AlterTableDropColumn } from "../objects/table/changes/table.alter.ts";
9
+ import { DropTable } from "../objects/table/changes/table.drop.ts";
10
+ import type { PlanRisk } from "./types.ts";
11
+
12
+ /**
13
+ * Classify a single change for data-loss risk.
14
+ */
15
+ function classifyChangeRisk(change: Change): string | null {
16
+ if (change instanceof DropTable) {
17
+ return `drop table ${change.table.schema}.${change.table.name}`;
18
+ }
19
+
20
+ if (change instanceof AlterTableDropColumn) {
21
+ return `drop column ${change.column.name} on ${change.table.schema}.${change.table.name}`;
22
+ }
23
+
24
+ if (change instanceof DropSequence) {
25
+ return `drop sequence ${change.sequence.schema}.${change.sequence.name}`;
26
+ }
27
+
28
+ // Extend here if TRUNCATE or other data-loss operations are added.
29
+ return null;
30
+ }
31
+
32
+ /**
33
+ * Classify all changes for data-loss risk.
34
+ */
35
+ export function classifyChangesRisk(changes: Change[]): PlanRisk {
36
+ const statements: string[] = [];
37
+
38
+ for (const change of changes) {
39
+ const reason = classifyChangeRisk(change);
40
+ if (reason) statements.push(reason);
41
+ }
42
+
43
+ if (statements.length > 0) {
44
+ return { level: "data_loss", statements };
45
+ }
46
+
47
+ return { level: "safe" };
48
+ }