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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (359) hide show
  1. package/README.md +40 -23
  2. package/dist/cli/app.js +26 -3
  3. package/dist/cli/bin/cli.js +5 -0
  4. package/dist/cli/commands/catalog-export.d.ts +5 -0
  5. package/dist/cli/commands/catalog-export.js +64 -0
  6. package/dist/cli/commands/declarative-apply.d.ts +6 -0
  7. package/dist/cli/commands/declarative-apply.js +288 -0
  8. package/dist/cli/commands/declarative-export.d.ts +5 -0
  9. package/dist/cli/commands/declarative-export.js +245 -0
  10. package/dist/cli/commands/plan.js +19 -6
  11. package/dist/cli/exit-code.d.ts +2 -0
  12. package/dist/cli/exit-code.js +7 -0
  13. package/dist/cli/formatters/tree/tree.js +3 -2
  14. package/dist/cli/utils/apply-display.d.ts +52 -0
  15. package/dist/cli/utils/apply-display.js +183 -0
  16. package/dist/cli/utils/export-display.d.ts +43 -0
  17. package/dist/cli/utils/export-display.js +202 -0
  18. package/dist/cli/utils/resolve-input.d.ts +7 -0
  19. package/dist/cli/utils/resolve-input.js +13 -0
  20. package/dist/core/catalog-export/index.d.ts +11 -0
  21. package/dist/core/catalog-export/index.js +10 -0
  22. package/dist/core/catalog.diff.d.ts +1 -0
  23. package/dist/core/catalog.diff.js +64 -48
  24. package/dist/core/catalog.model.d.ts +14 -1
  25. package/dist/core/catalog.model.js +103 -1
  26. package/dist/core/catalog.snapshot.d.ts +66 -0
  27. package/dist/core/catalog.snapshot.js +206 -0
  28. package/dist/core/declarative-apply/discover-sql.d.ts +18 -0
  29. package/dist/core/declarative-apply/discover-sql.js +86 -0
  30. package/dist/core/declarative-apply/extract-catalog-providers.d.ts +23 -0
  31. package/dist/core/declarative-apply/extract-catalog-providers.js +159 -0
  32. package/dist/core/declarative-apply/index.d.ts +49 -0
  33. package/dist/core/declarative-apply/index.js +134 -0
  34. package/dist/core/declarative-apply/round-apply.d.ts +100 -0
  35. package/dist/core/declarative-apply/round-apply.js +378 -0
  36. package/dist/core/export/file-mapper.d.ts +71 -0
  37. package/dist/core/export/file-mapper.js +474 -0
  38. package/dist/core/export/grouper.d.ts +13 -0
  39. package/dist/core/export/grouper.js +76 -0
  40. package/dist/core/export/index.d.ts +45 -0
  41. package/dist/core/export/index.js +63 -0
  42. package/dist/core/export/types.d.ts +84 -0
  43. package/dist/core/export/types.js +25 -0
  44. package/dist/core/fixtures/empty-catalogs/postgres-15-16-baseline.json +287 -0
  45. package/dist/core/integrations/filter/dsl.d.ts +38 -1
  46. package/dist/core/integrations/filter/dsl.js +20 -2
  47. package/dist/core/integrations/filter/extractors.js +42 -0
  48. package/dist/core/integrations/integration-dsl.d.ts +10 -0
  49. package/dist/core/integrations/supabase.d.ts +8 -0
  50. package/dist/core/integrations/supabase.js +9 -0
  51. package/dist/core/objects/aggregate/aggregate.diff.d.ts +2 -8
  52. package/dist/core/objects/aggregate/aggregate.diff.js +16 -70
  53. package/dist/core/objects/aggregate/aggregate.model.d.ts +8 -8
  54. package/dist/core/objects/aggregate/aggregate.model.js +1 -1
  55. package/dist/core/objects/aggregate/changes/aggregate.create.js +1 -1
  56. package/dist/core/objects/aggregate/changes/aggregate.drop.js +1 -1
  57. package/dist/core/objects/base.privilege-diff.d.ts +38 -13
  58. package/dist/core/objects/base.privilege-diff.js +104 -22
  59. package/dist/core/objects/base.privilege.d.ts +1 -0
  60. package/dist/core/objects/base.privilege.js +9 -2
  61. package/dist/core/objects/collation/collation.diff.d.ts +2 -3
  62. package/dist/core/objects/diff-context.d.ts +15 -0
  63. package/dist/core/objects/diff-context.js +1 -0
  64. package/dist/core/objects/domain/changes/domain.create.js +4 -2
  65. package/dist/core/objects/domain/domain.diff.d.ts +2 -8
  66. package/dist/core/objects/domain/domain.diff.js +16 -77
  67. package/dist/core/objects/domain/domain.model.js +1 -1
  68. package/dist/core/objects/event-trigger/event-trigger.diff.d.ts +2 -3
  69. package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.d.ts +2 -8
  70. package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.js +13 -77
  71. package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.js +2 -2
  72. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.d.ts +2 -8
  73. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.js +16 -77
  74. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.js +1 -1
  75. package/dist/core/objects/foreign-data-wrapper/server/server.diff.d.ts +2 -8
  76. package/dist/core/objects/foreign-data-wrapper/server/server.diff.js +13 -77
  77. package/dist/core/objects/language/language.diff.d.ts +2 -5
  78. package/dist/core/objects/language/language.diff.js +7 -39
  79. package/dist/core/objects/materialized-view/materialized-view.diff.d.ts +2 -8
  80. package/dist/core/objects/materialized-view/materialized-view.diff.js +16 -158
  81. package/dist/core/objects/materialized-view/materialized-view.model.d.ts +3 -3
  82. package/dist/core/objects/materialized-view/materialized-view.model.js +1 -1
  83. package/dist/core/objects/procedure/changes/procedure.alter.js +12 -12
  84. package/dist/core/objects/procedure/procedure.diff.d.ts +2 -8
  85. package/dist/core/objects/procedure/procedure.diff.js +16 -77
  86. package/dist/core/objects/procedure/procedure.model.d.ts +9 -9
  87. package/dist/core/objects/procedure/procedure.model.js +1 -1
  88. package/dist/core/objects/publication/changes/publication.alter.d.ts +0 -9
  89. package/dist/core/objects/publication/changes/publication.alter.js +0 -14
  90. package/dist/core/objects/publication/changes/publication.types.d.ts +2 -2
  91. package/dist/core/objects/publication/publication.diff.d.ts +2 -3
  92. package/dist/core/objects/publication/publication.diff.js +8 -13
  93. package/dist/core/objects/rls-policy/changes/rls-policy.alter.js +3 -3
  94. package/dist/core/objects/rls-policy/rls-policy.model.d.ts +2 -2
  95. package/dist/core/objects/role/role.diff.js +22 -1
  96. package/dist/core/objects/role/role.model.d.ts +4 -3
  97. package/dist/core/objects/role/role.model.js +118 -12
  98. package/dist/core/objects/rule/rule.model.d.ts +1 -1
  99. package/dist/core/objects/schema/schema.diff.d.ts +2 -8
  100. package/dist/core/objects/schema/schema.diff.js +16 -77
  101. package/dist/core/objects/schema/schema.model.js +1 -1
  102. package/dist/core/objects/sequence/sequence.diff.d.ts +2 -8
  103. package/dist/core/objects/sequence/sequence.diff.js +16 -79
  104. package/dist/core/objects/sequence/sequence.model.js +1 -1
  105. package/dist/core/objects/subscription/subscription.diff.d.ts +2 -3
  106. package/dist/core/objects/table/changes/table.create.js +3 -0
  107. package/dist/core/objects/table/table.diff.d.ts +2 -8
  108. package/dist/core/objects/table/table.diff.js +26 -157
  109. package/dist/core/objects/table/table.model.d.ts +23 -22
  110. package/dist/core/objects/table/table.model.js +1 -1
  111. package/dist/core/objects/trigger/changes/trigger.create.js +2 -4
  112. package/dist/core/objects/trigger/trigger.model.d.ts +8 -0
  113. package/dist/core/objects/trigger/trigger.model.js +11 -0
  114. package/dist/core/objects/type/composite-type/composite-type.diff.d.ts +2 -8
  115. package/dist/core/objects/type/composite-type/composite-type.diff.js +16 -77
  116. package/dist/core/objects/type/composite-type/composite-type.model.d.ts +3 -3
  117. package/dist/core/objects/type/composite-type/composite-type.model.js +2 -1
  118. package/dist/core/objects/type/enum/enum.diff.d.ts +2 -8
  119. package/dist/core/objects/type/enum/enum.diff.js +25 -112
  120. package/dist/core/objects/type/enum/enum.model.js +1 -1
  121. package/dist/core/objects/type/range/changes/range.create.js +6 -3
  122. package/dist/core/objects/type/range/range.diff.d.ts +2 -8
  123. package/dist/core/objects/type/range/range.diff.js +16 -77
  124. package/dist/core/objects/type/range/range.model.js +1 -1
  125. package/dist/core/objects/view/view.diff.d.ts +2 -8
  126. package/dist/core/objects/view/view.diff.js +16 -158
  127. package/dist/core/objects/view/view.model.d.ts +18 -4
  128. package/dist/core/objects/view/view.model.js +3 -13
  129. package/dist/core/plan/apply.js +9 -26
  130. package/dist/core/plan/create.d.ts +19 -6
  131. package/dist/core/plan/create.js +134 -174
  132. package/dist/core/plan/serialize.js +16 -4
  133. package/dist/core/plan/sql-format/fixtures.js +3 -5
  134. package/dist/core/plan/sql-format/keyword-case.js +26 -1
  135. package/dist/core/plan/ssl-config.d.ts +32 -0
  136. package/dist/core/plan/ssl-config.js +115 -0
  137. package/dist/core/plan/types.d.ts +6 -0
  138. package/dist/core/postgres-config.d.ts +14 -0
  139. package/dist/core/postgres-config.js +53 -2
  140. package/dist/core/sort/graph-builder.js +10 -0
  141. package/dist/core/sort/logical-sort.js +31 -23
  142. package/dist/core/test-utils/assert-valid-sql.d.ts +10 -0
  143. package/dist/core/test-utils/assert-valid-sql.js +19 -0
  144. package/dist/index.d.ts +6 -0
  145. package/dist/index.js +6 -1
  146. package/package.json +21 -4
  147. package/src/cli/app.ts +27 -3
  148. package/src/cli/bin/cli.ts +6 -0
  149. package/src/cli/commands/catalog-export.ts +78 -0
  150. package/src/cli/commands/declarative-apply.diagnostics.test.ts +77 -0
  151. package/src/cli/commands/declarative-apply.ts +380 -0
  152. package/src/cli/commands/declarative-export.ts +330 -0
  153. package/src/cli/commands/plan.ts +28 -7
  154. package/src/cli/exit-code.test.ts +19 -0
  155. package/src/cli/exit-code.ts +7 -0
  156. package/src/cli/formatters/tree/tree.ts +3 -2
  157. package/src/cli/utils/apply-display.test.ts +348 -0
  158. package/src/cli/utils/apply-display.ts +238 -0
  159. package/src/cli/utils/export-display.test.ts +103 -0
  160. package/src/cli/utils/export-display.ts +275 -0
  161. package/src/cli/utils/integrations.test.ts +44 -0
  162. package/src/cli/utils/resolve-input.test.ts +38 -0
  163. package/src/cli/utils/resolve-input.ts +17 -0
  164. package/src/core/catalog-export/index.ts +20 -0
  165. package/src/core/catalog.diff.ts +79 -78
  166. package/src/core/catalog.model.test.ts +122 -0
  167. package/src/core/catalog.model.ts +127 -1
  168. package/src/core/catalog.snapshot.test.ts +464 -0
  169. package/src/core/catalog.snapshot.ts +289 -0
  170. package/src/core/declarative-apply/discover-sql.test.ts +103 -0
  171. package/src/core/declarative-apply/discover-sql.ts +107 -0
  172. package/src/core/declarative-apply/extract-catalog-providers.ts +220 -0
  173. package/src/core/declarative-apply/index.test.ts +67 -0
  174. package/src/core/declarative-apply/index.ts +205 -0
  175. package/src/core/declarative-apply/round-apply.test.ts +504 -0
  176. package/src/core/declarative-apply/round-apply.ts +562 -0
  177. package/src/core/expand-replace-dependencies.test.ts +70 -0
  178. package/src/core/export/file-mapper.test.ts +816 -0
  179. package/src/core/export/file-mapper.ts +574 -0
  180. package/src/core/export/grouper.ts +108 -0
  181. package/src/core/export/index.ts +129 -0
  182. package/src/core/export/types.ts +104 -0
  183. package/src/core/fixtures/empty-catalogs/postgres-15-16-baseline.json +287 -0
  184. package/src/core/integrations/filter/dsl.test.ts +211 -0
  185. package/src/core/integrations/filter/dsl.ts +65 -3
  186. package/src/core/integrations/filter/extractors.test.ts +244 -0
  187. package/src/core/integrations/filter/extractors.ts +42 -0
  188. package/src/core/integrations/integration-dsl.ts +10 -0
  189. package/src/core/integrations/serialize/dsl.test.ts +91 -0
  190. package/src/core/integrations/supabase.ts +9 -0
  191. package/src/core/objects/aggregate/aggregate.diff.ts +39 -95
  192. package/src/core/objects/aggregate/aggregate.model.ts +1 -1
  193. package/src/core/objects/aggregate/changes/aggregate.alter.test.ts +3 -1
  194. package/src/core/objects/aggregate/changes/aggregate.comment.test.ts +5 -2
  195. package/src/core/objects/aggregate/changes/aggregate.create.test.ts +6 -3
  196. package/src/core/objects/aggregate/changes/aggregate.create.ts +1 -1
  197. package/src/core/objects/aggregate/changes/aggregate.drop.test.ts +7 -3
  198. package/src/core/objects/aggregate/changes/aggregate.drop.ts +1 -1
  199. package/src/core/objects/aggregate/changes/aggregate.privilege.test.ts +9 -3
  200. package/src/core/objects/base.privilege-diff.ts +178 -30
  201. package/src/core/objects/base.privilege.ts +9 -2
  202. package/src/core/objects/collation/changes/collation.alter.test.ts +7 -2
  203. package/src/core/objects/collation/changes/collation.create.test.ts +7 -2
  204. package/src/core/objects/collation/changes/collation.drop.test.ts +4 -1
  205. package/src/core/objects/collation/collation.diff.test.ts +9 -12
  206. package/src/core/objects/collation/collation.diff.ts +2 -1
  207. package/src/core/objects/diff-context.ts +16 -0
  208. package/src/core/objects/domain/changes/domain.alter.test.ts +28 -9
  209. package/src/core/objects/domain/changes/domain.create.test.ts +32 -2
  210. package/src/core/objects/domain/changes/domain.create.ts +7 -1
  211. package/src/core/objects/domain/changes/domain.drop.test.ts +4 -1
  212. package/src/core/objects/domain/domain.diff.ts +39 -102
  213. package/src/core/objects/domain/domain.model.ts +1 -1
  214. package/src/core/objects/event-trigger/changes/event-trigger.alter.test.ts +10 -3
  215. package/src/core/objects/event-trigger/changes/event-trigger.create.test.ts +4 -1
  216. package/src/core/objects/event-trigger/changes/event-trigger.drop.test.ts +4 -1
  217. package/src/core/objects/event-trigger/event-trigger.diff.test.ts +12 -7
  218. package/src/core/objects/event-trigger/event-trigger.diff.ts +2 -1
  219. package/src/core/objects/extension/changes/extension.alter.test.ts +7 -2
  220. package/src/core/objects/extension/changes/extension.create.test.ts +4 -1
  221. package/src/core/objects/extension/changes/extension.drop.test.ts +4 -1
  222. package/src/core/objects/extension/extension.model.test.ts +98 -0
  223. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.test.ts +16 -5
  224. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.test.ts +51 -16
  225. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.test.ts +4 -1
  226. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.test.ts +111 -4
  227. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.ts +31 -101
  228. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.ts +2 -2
  229. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.test.ts +46 -15
  230. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.test.ts +13 -4
  231. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.test.ts +4 -1
  232. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +39 -102
  233. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +1 -1
  234. package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.test.ts +22 -7
  235. package/src/core/objects/foreign-data-wrapper/server/changes/server.create.test.ts +19 -6
  236. package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.test.ts +4 -1
  237. package/src/core/objects/foreign-data-wrapper/server/server.diff.test.ts +95 -0
  238. package/src/core/objects/foreign-data-wrapper/server/server.diff.ts +31 -101
  239. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.test.ts +13 -4
  240. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.test.ts +16 -5
  241. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.test.ts +10 -3
  242. package/src/core/objects/index/changes/index.alter.test.ts +13 -4
  243. package/src/core/objects/index/changes/index.create.test.ts +4 -1
  244. package/src/core/objects/index/changes/index.drop.test.ts +4 -1
  245. package/src/core/objects/language/changes/language.alter.test.ts +4 -1
  246. package/src/core/objects/language/changes/language.create.test.ts +4 -1
  247. package/src/core/objects/language/changes/language.drop.test.ts +4 -1
  248. package/src/core/objects/language/language.diff.test.ts +86 -4
  249. package/src/core/objects/language/language.diff.ts +17 -49
  250. package/src/core/objects/materialized-view/changes/materialized-view.alter.test.ts +10 -3
  251. package/src/core/objects/materialized-view/changes/materialized-view.create.test.ts +7 -2
  252. package/src/core/objects/materialized-view/changes/materialized-view.drop.test.ts +4 -1
  253. package/src/core/objects/materialized-view/materialized-view.diff.test.ts +162 -0
  254. package/src/core/objects/materialized-view/materialized-view.diff.ts +41 -191
  255. package/src/core/objects/materialized-view/materialized-view.model.ts +1 -1
  256. package/src/core/objects/procedure/changes/procedure.alter.test.ts +121 -49
  257. package/src/core/objects/procedure/changes/procedure.alter.ts +15 -12
  258. package/src/core/objects/procedure/changes/procedure.create.test.ts +4 -1
  259. package/src/core/objects/procedure/changes/procedure.drop.test.ts +7 -2
  260. package/src/core/objects/procedure/procedure.diff.ts +39 -102
  261. package/src/core/objects/procedure/procedure.model.ts +1 -1
  262. package/src/core/objects/publication/changes/publication.alter.test.ts +15 -21
  263. package/src/core/objects/publication/changes/publication.alter.ts +0 -18
  264. package/src/core/objects/publication/changes/publication.comment.test.ts +5 -2
  265. package/src/core/objects/publication/changes/publication.create.test.ts +5 -2
  266. package/src/core/objects/publication/changes/publication.drop.test.ts +3 -1
  267. package/src/core/objects/publication/changes/publication.types.ts +0 -2
  268. package/src/core/objects/publication/publication.diff.test.ts +24 -19
  269. package/src/core/objects/publication/publication.diff.ts +9 -15
  270. package/src/core/objects/rls-policy/changes/rls-policy.alter.test.ts +31 -14
  271. package/src/core/objects/rls-policy/changes/rls-policy.alter.ts +3 -3
  272. package/src/core/objects/rls-policy/changes/rls-policy.create.test.ts +10 -3
  273. package/src/core/objects/rls-policy/changes/rls-policy.drop.test.ts +4 -1
  274. package/src/core/objects/role/changes/role.alter.test.ts +31 -15
  275. package/src/core/objects/role/changes/role.create.test.ts +6 -2
  276. package/src/core/objects/role/changes/role.drop.test.ts +4 -1
  277. package/src/core/objects/role/role.diff.test.ts +235 -0
  278. package/src/core/objects/role/role.diff.ts +21 -1
  279. package/src/core/objects/role/role.model.ts +122 -14
  280. package/src/core/objects/rule/changes/rule.alter.test.ts +7 -3
  281. package/src/core/objects/rule/changes/rule.comment.test.ts +5 -2
  282. package/src/core/objects/rule/changes/rule.create.test.ts +6 -2
  283. package/src/core/objects/rule/changes/rule.drop.test.ts +3 -1
  284. package/src/core/objects/schema/changes/schema.alter.test.ts +4 -1
  285. package/src/core/objects/schema/changes/schema.create.test.ts +4 -1
  286. package/src/core/objects/schema/changes/schema.drop.test.ts +4 -1
  287. package/src/core/objects/schema/schema.diff.ts +39 -102
  288. package/src/core/objects/schema/schema.model.ts +1 -1
  289. package/src/core/objects/sequence/changes/sequence.alter.test.ts +11 -5
  290. package/src/core/objects/sequence/changes/sequence.create.test.ts +8 -3
  291. package/src/core/objects/sequence/changes/sequence.drop.test.ts +4 -1
  292. package/src/core/objects/sequence/sequence.diff.test.ts +114 -0
  293. package/src/core/objects/sequence/sequence.diff.ts +39 -104
  294. package/src/core/objects/sequence/sequence.model.ts +1 -1
  295. package/src/core/objects/subscription/changes/subscription.alter.test.ts +15 -5
  296. package/src/core/objects/subscription/changes/subscription.comment.test.ts +5 -2
  297. package/src/core/objects/subscription/changes/subscription.create.test.ts +5 -2
  298. package/src/core/objects/subscription/changes/subscription.drop.test.ts +3 -1
  299. package/src/core/objects/subscription/subscription.diff.test.ts +16 -11
  300. package/src/core/objects/subscription/subscription.diff.ts +2 -1
  301. package/src/core/objects/table/changes/table.alter.test.ts +38 -15
  302. package/src/core/objects/table/changes/table.create.test.ts +41 -3
  303. package/src/core/objects/table/changes/table.create.ts +4 -0
  304. package/src/core/objects/table/changes/table.drop.test.ts +3 -1
  305. package/src/core/objects/table/table.diff.test.ts +157 -0
  306. package/src/core/objects/table/table.diff.ts +54 -190
  307. package/src/core/objects/table/table.model.ts +1 -1
  308. package/src/core/objects/trigger/changes/trigger.alter.test.ts +8 -4
  309. package/src/core/objects/trigger/changes/trigger.create.test.ts +5 -1
  310. package/src/core/objects/trigger/changes/trigger.create.ts +7 -4
  311. package/src/core/objects/trigger/changes/trigger.drop.test.ts +5 -1
  312. package/src/core/objects/trigger/trigger.diff.test.ts +1 -0
  313. package/src/core/objects/trigger/trigger.model.ts +12 -0
  314. package/src/core/objects/type/composite-type/changes/composite-type.alter.test.ts +10 -4
  315. package/src/core/objects/type/composite-type/changes/composite-type.create.test.ts +7 -2
  316. package/src/core/objects/type/composite-type/changes/composite-type.drop.test.ts +4 -1
  317. package/src/core/objects/type/composite-type/composite-type.diff.test.ts +78 -0
  318. package/src/core/objects/type/composite-type/composite-type.diff.ts +39 -101
  319. package/src/core/objects/type/composite-type/composite-type.model.ts +2 -1
  320. package/src/core/objects/type/enum/changes/enum.alter.test.ts +14 -5
  321. package/src/core/objects/type/enum/changes/enum.create.test.ts +4 -1
  322. package/src/core/objects/type/enum/changes/enum.drop.test.ts +4 -1
  323. package/src/core/objects/type/enum/enum.diff.test.ts +181 -0
  324. package/src/core/objects/type/enum/enum.diff.ts +58 -146
  325. package/src/core/objects/type/enum/enum.model.ts +1 -1
  326. package/src/core/objects/type/range/changes/range.alter.test.ts +3 -1
  327. package/src/core/objects/type/range/changes/range.create.test.ts +5 -2
  328. package/src/core/objects/type/range/changes/range.create.ts +6 -2
  329. package/src/core/objects/type/range/changes/range.drop.test.ts +3 -1
  330. package/src/core/objects/type/range/range.diff.test.ts +77 -0
  331. package/src/core/objects/type/range/range.diff.ts +39 -101
  332. package/src/core/objects/type/range/range.model.ts +1 -1
  333. package/src/core/objects/view/changes/view.alter.test.ts +8 -3
  334. package/src/core/objects/view/changes/view.create.test.ts +7 -2
  335. package/src/core/objects/view/changes/view.drop.test.ts +4 -1
  336. package/src/core/objects/view/view.diff.test.ts +82 -0
  337. package/src/core/objects/view/view.diff.ts +41 -191
  338. package/src/core/objects/view/view.model.ts +3 -17
  339. package/src/core/plan/apply.ts +9 -27
  340. package/src/core/plan/create.ts +173 -237
  341. package/src/core/plan/serialize.test.ts +317 -0
  342. package/src/core/plan/serialize.ts +18 -4
  343. package/src/core/plan/sql-format/fixtures.ts +2 -5
  344. package/src/core/plan/sql-format/format-lowercase-coverage.test.ts +52 -0
  345. package/src/core/plan/sql-format/format-off.test.ts +14 -17
  346. package/src/core/plan/sql-format/format-pretty-lower-leading.test.ts +27 -22
  347. package/src/core/plan/sql-format/format-pretty-narrow.test.ts +17 -21
  348. package/src/core/plan/sql-format/format-pretty-preserve.test.ts +25 -20
  349. package/src/core/plan/sql-format/format-pretty-upper.test.ts +23 -20
  350. package/src/core/plan/sql-format/keyword-case.ts +36 -1
  351. package/src/core/plan/ssl-config.ts +172 -0
  352. package/src/core/plan/types.ts +6 -0
  353. package/src/core/postgres-config.ts +71 -2
  354. package/src/core/sort/graph-builder.ts +12 -0
  355. package/src/core/sort/logical-sort.test.ts +371 -0
  356. package/src/core/sort/logical-sort.ts +32 -25
  357. package/src/core/sort/topological-sort.test.ts +275 -0
  358. package/src/core/test-utils/assert-valid-sql.ts +20 -0
  359. package/src/index.ts +26 -2
package/README.md CHANGED
@@ -2,13 +2,14 @@
2
2
 
3
3
  PostgreSQL migrations made easy.
4
4
 
5
- Generate migration scripts by comparing two PostgreSQL databases. Automatically detects schema differences and creates safe, ordered migration scripts.
5
+ Generate migration scripts by comparing two PostgreSQL databases. Automatically detects schema differences and creates safe, ordered migration scripts. Supports both imperative diff-based migrations and declarative file-based schema management.
6
6
 
7
7
  ## Features
8
8
 
9
9
  - 🔍 Compare databases and generate migration scripts automatically
10
10
  - 🔒 Safety-first: detects data-loss operations and requires explicit confirmation
11
11
  - 📋 Plan-based workflow: preview changes before applying, store plans for version control
12
+ - 📁 Declarative schemas: export/apply schemas as version-controlled `.sql` files
12
13
  - 🎯 Integration DSL: filter and customize serialization with JSON-based rules
13
14
  - 🛠️ Developer-friendly: interactive CLI with tree-formatted change previews
14
15
 
@@ -28,7 +29,9 @@ npx @supabase/pg-delta --source <source> --target <target>
28
29
 
29
30
  ### CLI Usage
30
31
 
31
- The CLI provides three main commands:
32
+ The CLI provides two paradigms: **imperative** (diff-based migrations) and **declarative** (file-based schemas).
33
+
34
+ #### Imperative: diff-based migrations
32
35
 
33
36
  **Sync (default)** - Plan and apply changes in one go:
34
37
 
@@ -47,37 +50,47 @@ pg-delta plan \
47
50
  --output plan.json
48
51
  ```
49
52
 
50
- **Plan (SQL output with formatting)** - Opt-in post-formatting for SQL scripts:
53
+ **Apply** - Apply a previously created plan:
51
54
 
52
55
  ```bash
53
- pg-delta plan \
56
+ pg-delta apply \
57
+ --plan plan.json \
54
58
  --source postgresql://user:pass@localhost:5432/source_db \
55
- --target postgresql://user:pass@localhost:5432/target_db \
56
- --format sql \
57
- --sql-format \
58
- --sql-format-options '{"keywordCase":"upper","maxWidth":100}'
59
+ --target postgresql://user:pass@localhost:5432/target_db
59
60
  ```
60
61
 
61
- Available SQL format options (JSON):
62
- - `keywordCase`: `upper` | `lower` | `preserve`
63
- - `indent`: number of spaces per level
64
- - `maxWidth`: line width for wrapping
65
- - `commaStyle`: `trailing` | `leading`
66
- - `alignColumns`: boolean
67
- - `alignKeyValues`: boolean
68
- - `preserveRoutineBodies`: boolean
69
- - `preserveViewBodies`: boolean
70
- - `preserveRuleBodies`: boolean
62
+ #### Declarative: file-based schemas
71
63
 
72
- **Apply** - Apply a previously created plan:
64
+ **Declarative export** - Export a database schema as `.sql` files:
73
65
 
74
66
  ```bash
75
- pg-delta apply \
76
- --plan plan.json \
77
- --source postgresql://user:pass@localhost:5432/source_db \
78
- --target postgresql://user:pass@localhost:5432/target_db
67
+ pg-delta declarative export \
68
+ --target postgresql://user:pass@localhost:5432/mydb \
69
+ --output ./declarative-schemas/
79
70
  ```
80
71
 
72
+ **Declarative apply** - Apply `.sql` files to a database:
73
+
74
+ ```bash
75
+ pg-delta declarative apply \
76
+ --path ./declarative-schemas/ \
77
+ --target postgresql://user:pass@localhost:5432/fresh_db
78
+ ```
79
+
80
+ #### Utilities
81
+
82
+ **Catalog export** - Snapshot a database catalog to JSON for offline diffing:
83
+
84
+ ```bash
85
+ pg-delta catalog-export \
86
+ --target postgresql://user:pass@localhost:5432/mydb \
87
+ --output snapshot.json
88
+ ```
89
+
90
+ The snapshot can be used as `--source` or `--target` for `plan` and `declarative export`, enabling offline diffs without a live database connection.
91
+
92
+ See the [Workflow Guide](./docs/workflow.md) for end-to-end examples combining these commands.
93
+
81
94
  ### Using Integrations
82
95
 
83
96
  Use built-in integrations or custom JSON files:
@@ -128,6 +141,7 @@ if (planResult) {
128
141
 
129
142
  ## Documentation
130
143
 
144
+ - [Workflow Guide](./docs/workflow.md) - Full flow documentation for all commands and end-to-end workflows
131
145
  - [CLI Reference](./docs/cli.md) - Complete CLI documentation with all commands and options
132
146
  - [API Reference](./docs/api.md) - Programmatic API documentation
133
147
  - [Integrations](./docs/integrations.md) - Using and creating integrations with the DSL system
@@ -160,6 +174,9 @@ See [Integrations Documentation](./docs/integrations.md) for complete details.
160
174
  - Compare database states and review differences
161
175
  - Automate migration creation in CI/CD pipelines
162
176
  - Maintain schema version control with plan files
177
+ - Export and version-control schemas as declarative `.sql` files
178
+ - Apply declarative schemas to fresh databases (provisioning, restore)
179
+ - Snapshot databases for offline, reproducible diffs
163
180
  - Filter platform-specific changes (e.g., Supabase system schemas)
164
181
 
165
182
  ## Contributing
package/dist/cli/app.js CHANGED
@@ -1,12 +1,33 @@
1
1
  import { buildApplication, buildRouteMap } from "@stricli/core";
2
2
  import { applyCommand } from "./commands/apply.js";
3
+ import { catalogExportCommand } from "./commands/catalog-export.js";
4
+ import { declarativeApplyCommand } from "./commands/declarative-apply.js";
5
+ import { declarativeExportCommand } from "./commands/declarative-export.js";
3
6
  import { planCommand } from "./commands/plan.js";
4
7
  import { syncCommand } from "./commands/sync.js";
8
+ const declarativeRouteMap = buildRouteMap({
9
+ routes: {
10
+ apply: declarativeApplyCommand,
11
+ export: declarativeExportCommand,
12
+ },
13
+ docs: {
14
+ brief: "Declarative schema management",
15
+ fullDescription: `
16
+ Manage declarative SQL schemas.
17
+
18
+ Commands:
19
+ apply - Apply a declarative SQL schema to a database
20
+ export - Export a declarative schema from a database diff
21
+ `.trim(),
22
+ },
23
+ });
5
24
  const root = buildRouteMap({
6
25
  routes: {
7
26
  plan: planCommand,
8
27
  apply: applyCommand,
9
28
  sync: syncCommand,
29
+ declarative: declarativeRouteMap,
30
+ "catalog-export": catalogExportCommand,
10
31
  },
11
32
  defaultCommand: "sync",
12
33
  docs: {
@@ -15,9 +36,11 @@ const root = buildRouteMap({
15
36
  pgdelta generates migration scripts by comparing two PostgreSQL databases.
16
37
 
17
38
  Commands:
18
- plan - Compute schema diff and preview changes
19
- apply - Apply a plan's migration script to a database
20
- sync - Plan and apply changes in one go
39
+ plan - Compute schema diff and preview changes
40
+ apply - Apply a plan's migration script to a database
41
+ sync - Plan and apply changes in one go
42
+ declarative - Declarative schema (apply | export)
43
+ catalog-export - Export a database catalog as a snapshot JSON file
21
44
  `.trim(),
22
45
  },
23
46
  });
@@ -1,7 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import { run } from "@stricli/core";
3
3
  import { app } from "../app.js";
4
+ import { getCommandExitCode } from "../exit-code.js";
4
5
  await run(app, process.argv.slice(2), { process }).catch((error) => {
5
6
  console.error(error);
6
7
  process.exit(1);
7
8
  });
9
+ const code = getCommandExitCode();
10
+ if (code !== undefined) {
11
+ process.exitCode = code;
12
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Catalog export command - extract a database catalog and save as a snapshot JSON file.
3
+ */
4
+ import { type CommandContext } from "@stricli/core";
5
+ export declare const catalogExportCommand: import("@stricli/core").Command<CommandContext>;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Catalog export command - extract a database catalog and save as a snapshot JSON file.
3
+ */
4
+ import { writeFile } from "node:fs/promises";
5
+ import { buildCommand } from "@stricli/core";
6
+ import { extractCatalog } from "../../core/catalog.model.js";
7
+ import { serializeCatalog, stringifyCatalogSnapshot, } from "../../core/catalog.snapshot.js";
8
+ import { createManagedPool } from "../../core/postgres-config.js";
9
+ export const catalogExportCommand = buildCommand({
10
+ parameters: {
11
+ flags: {
12
+ target: {
13
+ kind: "parsed",
14
+ brief: "Target database connection URL to extract the catalog from",
15
+ parse: String,
16
+ },
17
+ output: {
18
+ kind: "parsed",
19
+ brief: "Output file path for the catalog snapshot JSON",
20
+ parse: String,
21
+ },
22
+ role: {
23
+ kind: "parsed",
24
+ brief: "Role to use when extracting the catalog (SET ROLE)",
25
+ parse: String,
26
+ optional: true,
27
+ },
28
+ },
29
+ aliases: {
30
+ t: "target",
31
+ o: "output",
32
+ },
33
+ },
34
+ docs: {
35
+ brief: "Export a database catalog as a snapshot JSON file",
36
+ fullDescription: `
37
+ Extract the full catalog from a live PostgreSQL database and save it
38
+ as a JSON snapshot file. The snapshot can later be used as --source or
39
+ --target for the plan and declarative export commands, enabling
40
+ offline diffing without a live database connection.
41
+
42
+ Use cases:
43
+ - Snapshot template1 for use as an empty-database baseline
44
+ - Snapshot a production database to generate revert migrations
45
+ - Snapshot any state for reproducible offline diffs
46
+ `.trim(),
47
+ },
48
+ async func(flags) {
49
+ const { pool, close } = await createManagedPool(flags.target, {
50
+ role: flags.role,
51
+ label: "target",
52
+ });
53
+ try {
54
+ const catalog = await extractCatalog(pool);
55
+ const snapshot = serializeCatalog(catalog);
56
+ const json = stringifyCatalogSnapshot(snapshot);
57
+ await writeFile(flags.output, json, "utf-8");
58
+ this.process.stdout.write(`Catalog snapshot written to ${flags.output}\n`);
59
+ }
60
+ finally {
61
+ await close();
62
+ }
63
+ },
64
+ });
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Declarative-apply command - apply a declarative SQL schema to a database
3
+ * using pg-topo static analysis + round-based execution.
4
+ */
5
+ import { type CommandContext } from "@stricli/core";
6
+ export declare const declarativeApplyCommand: import("@stricli/core").Command<CommandContext>;
@@ -0,0 +1,288 @@
1
+ /**
2
+ * Declarative-apply command - apply a declarative SQL schema to a database
3
+ * using pg-topo static analysis + round-based execution.
4
+ */
5
+ import { readFile } from "node:fs/promises";
6
+ import { buildCommand } from "@stricli/core";
7
+ import chalk from "chalk";
8
+ import { loadDeclarativeSchema } from "../../core/declarative-apply/discover-sql.js";
9
+ import { applyDeclarativeSchema, } from "../../core/declarative-apply/index.js";
10
+ import { buildDiagnosticDisplayItems, formatStatementError, positionToLineColumn, requiredObjectKeyFromDiagnostic, resolveSqlFilePath, } from "../utils/apply-display.js";
11
+ export const declarativeApplyCommand = buildCommand({
12
+ parameters: {
13
+ flags: {
14
+ path: {
15
+ kind: "parsed",
16
+ brief: "Path to the declarative schema directory (containing .sql files) or a single .sql file",
17
+ parse: String,
18
+ },
19
+ target: {
20
+ kind: "parsed",
21
+ brief: "Target database connection URL to apply the schema to",
22
+ parse: String,
23
+ },
24
+ "max-rounds": {
25
+ kind: "parsed",
26
+ brief: "Maximum number of application rounds before giving up (default: 100)",
27
+ parse: Number,
28
+ optional: true,
29
+ },
30
+ "no-validate-functions": {
31
+ kind: "boolean",
32
+ brief: "Skip final function body validation pass",
33
+ optional: true,
34
+ },
35
+ verbose: {
36
+ kind: "boolean",
37
+ brief: "Show detailed per-round progress",
38
+ optional: true,
39
+ },
40
+ "ungroup-diagnostics": {
41
+ kind: "boolean",
42
+ brief: "Show full per-diagnostic detail instead of grouped summary output",
43
+ optional: true,
44
+ },
45
+ },
46
+ aliases: {
47
+ p: "path",
48
+ t: "target",
49
+ v: "verbose",
50
+ },
51
+ },
52
+ docs: {
53
+ brief: "Apply a declarative SQL schema to a database",
54
+ fullDescription: `
55
+ Apply SQL files from a declarative schema directory to a target database.
56
+
57
+ Uses pg-topo for static dependency analysis and topological ordering,
58
+ then applies statements round-by-round to handle any remaining
59
+ dependency gaps. Statements that fail with dependency errors are
60
+ deferred to subsequent rounds until all succeed or no progress is made.
61
+
62
+ Function body checks are disabled during rounds to avoid false failures
63
+ from functions referencing not-yet-created objects. A final validation
64
+ pass re-runs all function/procedure definitions with body checks enabled.
65
+
66
+ Exit codes:
67
+ 0 - Success (all statements applied)
68
+ 1 - Error (hard failures or validation errors)
69
+ 2 - Stuck (dependency cycle or unresolvable ordering)
70
+
71
+ Tip: Use DEBUG=pg-delta:declarative-apply for detailed defer/skip/fail logs (which statements are deferred and why).
72
+ `.trim(),
73
+ },
74
+ async func(flags) {
75
+ const verbose = !!flags.verbose;
76
+ const ungroupDiagnostics = !!flags["ungroup-diagnostics"];
77
+ const onRoundComplete = verbose
78
+ ? (round) => {
79
+ const parts = [
80
+ `Round ${round.round}:`,
81
+ chalk.green(`${round.applied} applied`),
82
+ ];
83
+ if (round.deferred > 0) {
84
+ parts.push(chalk.yellow(`${round.deferred} deferred`));
85
+ }
86
+ if (round.failed > 0) {
87
+ parts.push(chalk.red(`${round.failed} failed`));
88
+ }
89
+ this.process.stdout.write(`${parts.join(" ")}\n`);
90
+ }
91
+ : undefined;
92
+ this.process.stdout.write(`Analyzing SQL files in ${flags.path}...\n`);
93
+ let content;
94
+ try {
95
+ content = await loadDeclarativeSchema(flags.path);
96
+ }
97
+ catch (error) {
98
+ this.process.stderr.write(`Error: ${error instanceof Error ? error.message : String(error)}\n`);
99
+ process.exitCode = 1;
100
+ return;
101
+ }
102
+ if (content.length === 0) {
103
+ this.process.stderr.write(`No .sql files found in '${flags.path}'. Pass a directory containing .sql files or a single .sql file.\n`);
104
+ process.exitCode = 1;
105
+ return;
106
+ }
107
+ let result;
108
+ try {
109
+ result = await applyDeclarativeSchema({
110
+ content,
111
+ targetUrl: flags.target,
112
+ maxRounds: flags["max-rounds"],
113
+ validateFunctionBodies: !flags["no-validate-functions"],
114
+ onRoundComplete,
115
+ });
116
+ }
117
+ catch (error) {
118
+ this.process.stderr.write(`Error: ${error instanceof Error ? error.message : String(error)}\n`);
119
+ process.exitCode = 1;
120
+ return;
121
+ }
122
+ // Report pg-topo diagnostics grouped by severity (least noisy first).
123
+ // UNKNOWN_STATEMENT_CLASS is always hidden; DUPLICATE_PRODUCER,
124
+ // CYCLE_EDGE_SKIPPED, and UNRESOLVED_DEPENDENCY are verbose-only.
125
+ const diagnosticDisplayOrder = {
126
+ UNKNOWN_STATEMENT_CLASS: 0,
127
+ DUPLICATE_PRODUCER: 1,
128
+ CYCLE_EDGE_SKIPPED: 2,
129
+ UNRESOLVED_DEPENDENCY: 3,
130
+ };
131
+ const diagnosticColor = {
132
+ DUPLICATE_PRODUCER: chalk.yellow,
133
+ CYCLE_EDGE_SKIPPED: chalk.red,
134
+ UNRESOLVED_DEPENDENCY: chalk.dim,
135
+ };
136
+ const verboseOnlyCodes = new Set([
137
+ "UNRESOLVED_DEPENDENCY",
138
+ "DUPLICATE_PRODUCER",
139
+ "CYCLE_EDGE_SKIPPED",
140
+ ]);
141
+ const warnings = result.diagnostics
142
+ .filter((d) => d.code !== "UNKNOWN_STATEMENT_CLASS" &&
143
+ (verbose || !verboseOnlyCodes.has(d.code)))
144
+ .sort((a, b) => (diagnosticDisplayOrder[a.code] ?? 99) -
145
+ (diagnosticDisplayOrder[b.code] ?? 99));
146
+ if (warnings.length > 0 && verbose) {
147
+ const fileContentCache = new Map();
148
+ for (const diag of warnings) {
149
+ const id = diag.statementId;
150
+ if (id &&
151
+ id.sourceOffset != null &&
152
+ id.filePath &&
153
+ !fileContentCache.has(id.filePath)) {
154
+ // Try to resolve the exact file path of the statement to get the exact location of the error
155
+ try {
156
+ const fullPath = await resolveSqlFilePath(flags.path, id.filePath);
157
+ const content = await readFile(fullPath, "utf-8");
158
+ fileContentCache.set(id.filePath, content);
159
+ }
160
+ catch {
161
+ // Fall back to statementIndex display
162
+ }
163
+ }
164
+ }
165
+ this.process.stderr.write(chalk.yellow(`\n${warnings.length} diagnostic(s) from static analysis:\n`));
166
+ const entries = warnings.map((diag) => {
167
+ let location;
168
+ if (diag.statementId) {
169
+ const id = diag.statementId;
170
+ const offset = id.sourceOffset;
171
+ const content = offset != null ? fileContentCache.get(id.filePath) : undefined;
172
+ if (content != null && offset != null) {
173
+ const { line, column } = positionToLineColumn(content, offset + 1);
174
+ location = `${id.filePath}:${line}:${column}`;
175
+ }
176
+ else {
177
+ location = `${id.filePath}:${id.statementIndex}`;
178
+ }
179
+ }
180
+ return {
181
+ diagnostic: diag,
182
+ location,
183
+ requiredObjectKey: requiredObjectKeyFromDiagnostic(diag),
184
+ };
185
+ });
186
+ const displayItems = buildDiagnosticDisplayItems(entries, !ungroupDiagnostics);
187
+ let lastCode = "";
188
+ const previewLimit = 5;
189
+ for (const item of displayItems) {
190
+ if (item.code !== lastCode) {
191
+ if (lastCode !== "") {
192
+ this.process.stderr.write("\n");
193
+ }
194
+ lastCode = item.code;
195
+ }
196
+ const colorFn = diagnosticColor[item.code] ?? chalk.yellow;
197
+ const location = item.locations.length > 0 ? ` (${item.locations[0]})` : "";
198
+ const occurrences = !ungroupDiagnostics && item.locations.length > 1
199
+ ? ` x${item.locations.length}`
200
+ : "";
201
+ this.process.stderr.write(colorFn(` [${item.code}]${location}${occurrences} ${item.message}\n`));
202
+ if (!ungroupDiagnostics && item.requiredObjectKey) {
203
+ this.process.stderr.write(colorFn(` -> Object: ${item.requiredObjectKey}\n`));
204
+ }
205
+ if (!ungroupDiagnostics && item.locations.length > 1) {
206
+ for (const locationEntry of item.locations.slice(0, previewLimit)) {
207
+ this.process.stderr.write(colorFn(` at ${locationEntry}\n`));
208
+ }
209
+ const remaining = item.locations.length - previewLimit;
210
+ if (remaining > 0) {
211
+ this.process.stderr.write(colorFn(` ... and ${remaining} more location(s)\n`));
212
+ }
213
+ }
214
+ if (item.suggestedFix) {
215
+ this.process.stderr.write(colorFn(` -> Fix: ${item.suggestedFix}\n`));
216
+ }
217
+ }
218
+ this.process.stderr.write("\n");
219
+ }
220
+ const { apply } = result;
221
+ // Summary
222
+ this.process.stdout.write("\n");
223
+ this.process.stdout.write(`Statements: ${result.totalStatements} total, ${apply.totalApplied} applied`);
224
+ if (apply.totalSkipped > 0) {
225
+ this.process.stdout.write(`, ${apply.totalSkipped} skipped`);
226
+ }
227
+ this.process.stdout.write("\n");
228
+ this.process.stdout.write(`Rounds: ${apply.totalRounds}\n`);
229
+ switch (apply.status) {
230
+ case "success": {
231
+ this.process.stdout.write(chalk.green("All statements applied successfully.\n"));
232
+ if (apply.validationErrors && apply.validationErrors.length > 0) {
233
+ this.process.stderr.write(chalk.yellow(`\n${apply.validationErrors.length} function body validation error(s):\n`));
234
+ for (const err of apply.validationErrors) {
235
+ const formatted = await formatStatementError(err, flags.path);
236
+ this.process.stderr.write(chalk.yellow(formatted));
237
+ this.process.stderr.write("\n\n");
238
+ }
239
+ process.exitCode = 1;
240
+ }
241
+ else {
242
+ process.exitCode = 0;
243
+ }
244
+ break;
245
+ }
246
+ case "stuck": {
247
+ this.process.stderr.write(chalk.red(`\nStuck after ${apply.totalRounds} round(s). ${apply.stuckStatements?.length ?? 0} statement(s) could not be applied:\n`));
248
+ if (apply.stuckStatements) {
249
+ for (const stuck of apply.stuckStatements) {
250
+ const formatted = await formatStatementError(stuck, flags.path);
251
+ this.process.stderr.write(chalk.red(formatted));
252
+ this.process.stderr.write("\n\n");
253
+ }
254
+ }
255
+ if (apply.errors && apply.errors.length > 0) {
256
+ this.process.stderr.write(chalk.red(`\nAdditionally, ${apply.errors.length} statement(s) had non-dependency errors:\n`));
257
+ for (const err of apply.errors) {
258
+ const formatted = await formatStatementError(err, flags.path);
259
+ this.process.stderr.write(chalk.red(formatted));
260
+ this.process.stderr.write("\n\n");
261
+ }
262
+ }
263
+ process.exitCode = 2;
264
+ break;
265
+ }
266
+ case "error": {
267
+ this.process.stderr.write(chalk.red(`\nCompleted with errors. ${apply.errors?.length ?? 0} statement(s) failed:\n`));
268
+ if (apply.errors) {
269
+ for (const err of apply.errors) {
270
+ const formatted = await formatStatementError(err, flags.path);
271
+ this.process.stderr.write(chalk.red(formatted));
272
+ this.process.stderr.write("\n\n");
273
+ }
274
+ }
275
+ if (apply.validationErrors && apply.validationErrors.length > 0) {
276
+ this.process.stderr.write(chalk.yellow(`\n${apply.validationErrors.length} function body validation error(s):\n`));
277
+ for (const err of apply.validationErrors) {
278
+ const formatted = await formatStatementError(err, flags.path);
279
+ this.process.stderr.write(chalk.yellow(formatted));
280
+ this.process.stderr.write("\n\n");
281
+ }
282
+ }
283
+ process.exitCode = 1;
284
+ break;
285
+ }
286
+ }
287
+ },
288
+ });
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Declarative export command - export a declarative SQL schema from a database diff.
3
+ */
4
+ import { type CommandContext } from "@stricli/core";
5
+ export declare const declarativeExportCommand: import("@stricli/core").Command<CommandContext>;