@supabase/pg-delta 1.0.0-alpha.2 → 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 (464) 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/integrations/supabase.js +2 -0
  7. package/dist/core/objects/table/table.model.d.ts +4 -2
  8. package/dist/core/objects/table/table.model.js +3 -0
  9. package/dist/core/objects/trigger/changes/trigger.alter.js +23 -0
  10. package/dist/core/objects/trigger/changes/trigger.create.js +2 -1
  11. package/dist/core/objects/trigger/trigger.model.d.ts +1 -0
  12. package/dist/core/objects/trigger/trigger.model.js +3 -0
  13. package/dist/core/plan/apply.js +3 -3
  14. package/dist/core/plan/create.js +34 -15
  15. package/dist/core/plan/sql-format/constants.d.ts +2 -0
  16. package/dist/core/plan/sql-format/constants.js +11 -0
  17. package/dist/core/plan/sql-format/fixtures.d.ts +2 -0
  18. package/dist/core/plan/sql-format/fixtures.js +2449 -0
  19. package/dist/core/plan/sql-format/format-utils.d.ts +37 -0
  20. package/dist/core/plan/sql-format/format-utils.js +274 -0
  21. package/dist/core/plan/sql-format/formatters.d.ts +20 -0
  22. package/dist/core/plan/sql-format/formatters.js +737 -0
  23. package/dist/core/plan/sql-format/index.d.ts +2 -0
  24. package/dist/core/plan/sql-format/index.js +98 -0
  25. package/dist/core/plan/sql-format/keyword-case.d.ts +2 -0
  26. package/dist/core/plan/sql-format/keyword-case.js +868 -0
  27. package/dist/core/plan/sql-format/protect.d.ts +3 -0
  28. package/dist/core/plan/sql-format/protect.js +269 -0
  29. package/dist/core/plan/sql-format/sql-scanner.d.ts +59 -0
  30. package/dist/core/plan/sql-format/sql-scanner.js +202 -0
  31. package/dist/core/plan/sql-format/tokenizer.d.ts +22 -0
  32. package/dist/core/plan/sql-format/tokenizer.js +118 -0
  33. package/dist/core/plan/sql-format/types.d.ts +28 -0
  34. package/dist/core/plan/sql-format/types.js +1 -0
  35. package/dist/core/plan/sql-format/wrap.d.ts +2 -0
  36. package/dist/core/plan/sql-format/wrap.js +165 -0
  37. package/dist/core/plan/sql-format.d.ts +2 -0
  38. package/dist/core/plan/sql-format.js +1 -0
  39. package/dist/core/plan/statements.d.ts +2 -1
  40. package/dist/core/plan/statements.js +6 -2
  41. package/dist/core/postgres-config.d.ts +15 -0
  42. package/dist/core/postgres-config.js +30 -0
  43. package/dist/index.d.ts +2 -0
  44. package/dist/index.js +1 -0
  45. package/package.json +37 -22
  46. package/src/cli/app.ts +28 -0
  47. package/src/cli/bin/cli.ts +9 -0
  48. package/src/cli/commands/apply.ts +101 -0
  49. package/src/cli/commands/plan.ts +195 -0
  50. package/src/cli/commands/sync.ts +185 -0
  51. package/src/cli/formatters/index.ts +5 -0
  52. package/src/cli/formatters/tree/tree-builder.ts +380 -0
  53. package/src/cli/formatters/tree/tree-renderer.ts +372 -0
  54. package/src/cli/formatters/tree/tree.ts +237 -0
  55. package/src/cli/utils/integrations.ts +42 -0
  56. package/src/cli/utils.ts +231 -0
  57. package/src/core/catalog.diff.ts +246 -0
  58. package/src/core/catalog.model.ts +384 -0
  59. package/src/core/change.types.ts +44 -0
  60. package/src/core/context.ts +26 -0
  61. package/src/core/depend.ts +1870 -0
  62. package/src/core/expand-replace-dependencies.ts +380 -0
  63. package/src/core/fingerprint.ts +204 -0
  64. package/src/core/integrations/filter/dsl.ts +204 -0
  65. package/src/core/integrations/filter/extractors.ts +145 -0
  66. package/src/core/integrations/filter/filter.types.ts +3 -0
  67. package/src/core/integrations/integration-dsl.ts +24 -0
  68. package/src/core/integrations/integration.types.ts +7 -0
  69. package/src/core/integrations/serialize/dsl.ts +77 -0
  70. package/src/core/integrations/serialize/serialize.types.ts +3 -0
  71. package/src/core/integrations/supabase.ts +121 -0
  72. package/src/core/objects/aggregate/aggregate.diff.test.ts +215 -0
  73. package/src/core/objects/aggregate/aggregate.diff.ts +278 -0
  74. package/src/core/objects/aggregate/aggregate.model.ts +317 -0
  75. package/src/core/objects/aggregate/changes/aggregate.alter.test.ts +64 -0
  76. package/src/core/objects/aggregate/changes/aggregate.alter.ts +32 -0
  77. package/src/core/objects/aggregate/changes/aggregate.base.ts +20 -0
  78. package/src/core/objects/aggregate/changes/aggregate.comment.test.ts +86 -0
  79. package/src/core/objects/aggregate/changes/aggregate.comment.ts +62 -0
  80. package/src/core/objects/aggregate/changes/aggregate.create.test.ts +101 -0
  81. package/src/core/objects/aggregate/changes/aggregate.create.ts +329 -0
  82. package/src/core/objects/aggregate/changes/aggregate.drop.test.ts +78 -0
  83. package/src/core/objects/aggregate/changes/aggregate.drop.ts +32 -0
  84. package/src/core/objects/aggregate/changes/aggregate.privilege.test.ts +130 -0
  85. package/src/core/objects/aggregate/changes/aggregate.privilege.ts +146 -0
  86. package/src/core/objects/aggregate/changes/aggregate.types.ts +12 -0
  87. package/src/core/objects/base.change.ts +62 -0
  88. package/src/core/objects/base.default-privileges.ts +204 -0
  89. package/src/core/objects/base.diff.ts +20 -0
  90. package/src/core/objects/base.model.ts +82 -0
  91. package/src/core/objects/base.privilege-diff.ts +299 -0
  92. package/src/core/objects/base.privilege.ts +184 -0
  93. package/src/core/objects/collation/changes/collation.alter.test.ts +63 -0
  94. package/src/core/objects/collation/changes/collation.alter.ts +79 -0
  95. package/src/core/objects/collation/changes/collation.base.ts +20 -0
  96. package/src/core/objects/collation/changes/collation.comment.ts +68 -0
  97. package/src/core/objects/collation/changes/collation.create.test.ts +51 -0
  98. package/src/core/objects/collation/changes/collation.create.ts +106 -0
  99. package/src/core/objects/collation/changes/collation.drop.test.ts +28 -0
  100. package/src/core/objects/collation/changes/collation.drop.ts +37 -0
  101. package/src/core/objects/collation/changes/collation.types.ts +10 -0
  102. package/src/core/objects/collation/collation.diff.test.ts +100 -0
  103. package/src/core/objects/collation/collation.diff.ts +126 -0
  104. package/src/core/objects/collation/collation.model.ts +224 -0
  105. package/src/core/objects/domain/changes/domain.alter.test.ts +316 -0
  106. package/src/core/objects/domain/changes/domain.alter.ts +286 -0
  107. package/src/core/objects/domain/changes/domain.base.ts +20 -0
  108. package/src/core/objects/domain/changes/domain.comment.ts +59 -0
  109. package/src/core/objects/domain/changes/domain.create.test.ts +65 -0
  110. package/src/core/objects/domain/changes/domain.create.ts +118 -0
  111. package/src/core/objects/domain/changes/domain.drop.test.ts +30 -0
  112. package/src/core/objects/domain/changes/domain.drop.ts +34 -0
  113. package/src/core/objects/domain/changes/domain.privilege.ts +171 -0
  114. package/src/core/objects/domain/changes/domain.types.ts +12 -0
  115. package/src/core/objects/domain/domain.diff.test.ts +284 -0
  116. package/src/core/objects/domain/domain.diff.ts +358 -0
  117. package/src/core/objects/domain/domain.model.ts +190 -0
  118. package/src/core/objects/event-trigger/changes/event-trigger.alter.test.ts +50 -0
  119. package/src/core/objects/event-trigger/changes/event-trigger.alter.ts +82 -0
  120. package/src/core/objects/event-trigger/changes/event-trigger.base.ts +20 -0
  121. package/src/core/objects/event-trigger/changes/event-trigger.comment.ts +66 -0
  122. package/src/core/objects/event-trigger/changes/event-trigger.create.test.ts +24 -0
  123. package/src/core/objects/event-trigger/changes/event-trigger.create.ts +72 -0
  124. package/src/core/objects/event-trigger/changes/event-trigger.drop.test.ts +22 -0
  125. package/src/core/objects/event-trigger/changes/event-trigger.drop.ts +34 -0
  126. package/src/core/objects/event-trigger/changes/event-trigger.types.ts +10 -0
  127. package/src/core/objects/event-trigger/event-trigger.diff.test.ts +126 -0
  128. package/src/core/objects/event-trigger/event-trigger.diff.ts +126 -0
  129. package/src/core/objects/event-trigger/event-trigger.model.ts +106 -0
  130. package/src/core/objects/extension/changes/extension.alter.test.ts +58 -0
  131. package/src/core/objects/extension/changes/extension.alter.ts +78 -0
  132. package/src/core/objects/extension/changes/extension.base.ts +20 -0
  133. package/src/core/objects/extension/changes/extension.comment.ts +64 -0
  134. package/src/core/objects/extension/changes/extension.create.test.ts +25 -0
  135. package/src/core/objects/extension/changes/extension.create.ts +63 -0
  136. package/src/core/objects/extension/changes/extension.drop.test.ts +23 -0
  137. package/src/core/objects/extension/changes/extension.drop.ts +34 -0
  138. package/src/core/objects/extension/changes/extension.types.ts +10 -0
  139. package/src/core/objects/extension/extension.diff.test.ts +42 -0
  140. package/src/core/objects/extension/extension.diff.ts +90 -0
  141. package/src/core/objects/extension/extension.model.ts +280 -0
  142. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.test.ts +125 -0
  143. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.ts +101 -0
  144. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.base.ts +20 -0
  145. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.comment.ts +72 -0
  146. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.test.ts +125 -0
  147. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.ts +95 -0
  148. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.test.ts +23 -0
  149. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.ts +36 -0
  150. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.privilege.ts +172 -0
  151. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.types.ts +12 -0
  152. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.test.ts +179 -0
  153. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.ts +341 -0
  154. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.ts +149 -0
  155. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper.types.ts +10 -0
  156. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.test.ts +309 -0
  157. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.ts +341 -0
  158. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.ts +20 -0
  159. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.comment.ts +72 -0
  160. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.test.ts +201 -0
  161. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.ts +81 -0
  162. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.test.ts +43 -0
  163. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.ts +37 -0
  164. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.privilege.ts +181 -0
  165. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.ts +12 -0
  166. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.test.ts +813 -0
  167. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +406 -0
  168. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +242 -0
  169. package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.test.ts +168 -0
  170. package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.ts +126 -0
  171. package/src/core/objects/foreign-data-wrapper/server/changes/server.base.ts +20 -0
  172. package/src/core/objects/foreign-data-wrapper/server/changes/server.comment.ts +60 -0
  173. package/src/core/objects/foreign-data-wrapper/server/changes/server.create.test.ts +131 -0
  174. package/src/core/objects/foreign-data-wrapper/server/changes/server.create.ts +81 -0
  175. package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.test.ts +24 -0
  176. package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.ts +34 -0
  177. package/src/core/objects/foreign-data-wrapper/server/changes/server.privilege.ts +164 -0
  178. package/src/core/objects/foreign-data-wrapper/server/changes/server.types.ts +12 -0
  179. package/src/core/objects/foreign-data-wrapper/server/server.diff.test.ts +167 -0
  180. package/src/core/objects/foreign-data-wrapper/server/server.diff.ts +317 -0
  181. package/src/core/objects/foreign-data-wrapper/server/server.model.ts +133 -0
  182. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.test.ts +82 -0
  183. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.ts +69 -0
  184. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.base.ts +20 -0
  185. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.test.ts +85 -0
  186. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.ts +66 -0
  187. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.test.ts +53 -0
  188. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.ts +40 -0
  189. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.types.ts +8 -0
  190. package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.diff.test.ts +77 -0
  191. package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.diff.ts +107 -0
  192. package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.model.ts +96 -0
  193. package/src/core/objects/index/changes/index.alter.test.ts +200 -0
  194. package/src/core/objects/index/changes/index.alter.ts +144 -0
  195. package/src/core/objects/index/changes/index.base.ts +20 -0
  196. package/src/core/objects/index/changes/index.comment.ts +63 -0
  197. package/src/core/objects/index/changes/index.create.test.ts +66 -0
  198. package/src/core/objects/index/changes/index.create.ts +68 -0
  199. package/src/core/objects/index/changes/index.drop.test.ts +44 -0
  200. package/src/core/objects/index/changes/index.drop.ts +34 -0
  201. package/src/core/objects/index/changes/index.types.ts +6 -0
  202. package/src/core/objects/index/changes/utils.ts +16 -0
  203. package/src/core/objects/index/index.diff.test.ts +153 -0
  204. package/src/core/objects/index/index.diff.ts +243 -0
  205. package/src/core/objects/index/index.model.ts +370 -0
  206. package/src/core/objects/language/changes/language.alter.test.ts +33 -0
  207. package/src/core/objects/language/changes/language.alter.ts +53 -0
  208. package/src/core/objects/language/changes/language.base.ts +20 -0
  209. package/src/core/objects/language/changes/language.comment.ts +58 -0
  210. package/src/core/objects/language/changes/language.create.test.ts +27 -0
  211. package/src/core/objects/language/changes/language.create.ts +104 -0
  212. package/src/core/objects/language/changes/language.drop.test.ts +25 -0
  213. package/src/core/objects/language/changes/language.drop.ts +39 -0
  214. package/src/core/objects/language/changes/language.privilege.ts +172 -0
  215. package/src/core/objects/language/changes/language.types.ts +12 -0
  216. package/src/core/objects/language/language.diff.test.ts +53 -0
  217. package/src/core/objects/language/language.diff.ts +176 -0
  218. package/src/core/objects/language/language.model.ts +150 -0
  219. package/src/core/objects/materialized-view/changes/materialized-view.alter.test.ts +123 -0
  220. package/src/core/objects/materialized-view/changes/materialized-view.alter.ts +113 -0
  221. package/src/core/objects/materialized-view/changes/materialized-view.base.ts +20 -0
  222. package/src/core/objects/materialized-view/changes/materialized-view.comment.ts +176 -0
  223. package/src/core/objects/materialized-view/changes/materialized-view.create.test.ts +64 -0
  224. package/src/core/objects/materialized-view/changes/materialized-view.create.ts +93 -0
  225. package/src/core/objects/materialized-view/changes/materialized-view.drop.test.ts +34 -0
  226. package/src/core/objects/materialized-view/changes/materialized-view.drop.ts +60 -0
  227. package/src/core/objects/materialized-view/changes/materialized-view.privilege.ts +212 -0
  228. package/src/core/objects/materialized-view/changes/materialized-view.types.ts +12 -0
  229. package/src/core/objects/materialized-view/materialized-view.diff.test.ts +102 -0
  230. package/src/core/objects/materialized-view/materialized-view.diff.ts +451 -0
  231. package/src/core/objects/materialized-view/materialized-view.model.ts +258 -0
  232. package/src/core/objects/procedure/changes/procedure.alter.test.ts +1005 -0
  233. package/src/core/objects/procedure/changes/procedure.alter.ts +287 -0
  234. package/src/core/objects/procedure/changes/procedure.base.ts +20 -0
  235. package/src/core/objects/procedure/changes/procedure.comment.ts +70 -0
  236. package/src/core/objects/procedure/changes/procedure.create.test.ts +48 -0
  237. package/src/core/objects/procedure/changes/procedure.create.ts +92 -0
  238. package/src/core/objects/procedure/changes/procedure.drop.test.ts +85 -0
  239. package/src/core/objects/procedure/changes/procedure.drop.ts +49 -0
  240. package/src/core/objects/procedure/changes/procedure.privilege.ts +188 -0
  241. package/src/core/objects/procedure/changes/procedure.types.ts +12 -0
  242. package/src/core/objects/procedure/procedure.diff.test.ts +161 -0
  243. package/src/core/objects/procedure/procedure.diff.ts +404 -0
  244. package/src/core/objects/procedure/procedure.model.ts +264 -0
  245. package/src/core/objects/procedure/utils.ts +58 -0
  246. package/src/core/objects/publication/changes/publication.alter.test.ts +223 -0
  247. package/src/core/objects/publication/changes/publication.alter.ts +243 -0
  248. package/src/core/objects/publication/changes/publication.base.ts +20 -0
  249. package/src/core/objects/publication/changes/publication.comment.test.ts +70 -0
  250. package/src/core/objects/publication/changes/publication.comment.ts +64 -0
  251. package/src/core/objects/publication/changes/publication.create.test.ts +87 -0
  252. package/src/core/objects/publication/changes/publication.create.ts +82 -0
  253. package/src/core/objects/publication/changes/publication.drop.test.ts +46 -0
  254. package/src/core/objects/publication/changes/publication.drop.ts +29 -0
  255. package/src/core/objects/publication/changes/publication.types.ts +26 -0
  256. package/src/core/objects/publication/publication.diff.test.ts +292 -0
  257. package/src/core/objects/publication/publication.diff.ts +253 -0
  258. package/src/core/objects/publication/publication.model.ts +206 -0
  259. package/src/core/objects/publication/utils.ts +55 -0
  260. package/src/core/objects/rls-policy/changes/rls-policy.alter.test.ts +250 -0
  261. package/src/core/objects/rls-policy/changes/rls-policy.alter.ts +128 -0
  262. package/src/core/objects/rls-policy/changes/rls-policy.base.ts +20 -0
  263. package/src/core/objects/rls-policy/changes/rls-policy.comment.ts +69 -0
  264. package/src/core/objects/rls-policy/changes/rls-policy.create.test.ts +74 -0
  265. package/src/core/objects/rls-policy/changes/rls-policy.create.ts +100 -0
  266. package/src/core/objects/rls-policy/changes/rls-policy.drop.test.ts +28 -0
  267. package/src/core/objects/rls-policy/changes/rls-policy.drop.ts +39 -0
  268. package/src/core/objects/rls-policy/changes/rls-policy.types.ts +10 -0
  269. package/src/core/objects/rls-policy/rls-policy.diff.test.ts +79 -0
  270. package/src/core/objects/rls-policy/rls-policy.diff.ts +121 -0
  271. package/src/core/objects/rls-policy/rls-policy.model.ts +140 -0
  272. package/src/core/objects/role/changes/role.alter.test.ts +346 -0
  273. package/src/core/objects/role/changes/role.alter.ts +110 -0
  274. package/src/core/objects/role/changes/role.base.ts +24 -0
  275. package/src/core/objects/role/changes/role.comment.ts +55 -0
  276. package/src/core/objects/role/changes/role.create.test.ts +52 -0
  277. package/src/core/objects/role/changes/role.create.ts +102 -0
  278. package/src/core/objects/role/changes/role.drop.test.ts +29 -0
  279. package/src/core/objects/role/changes/role.drop.ts +34 -0
  280. package/src/core/objects/role/changes/role.privilege.ts +376 -0
  281. package/src/core/objects/role/changes/role.types.ts +12 -0
  282. package/src/core/objects/role/role.diff.test.ts +44 -0
  283. package/src/core/objects/role/role.diff.ts +479 -0
  284. package/src/core/objects/role/role.model.ts +344 -0
  285. package/src/core/objects/rule/changes/rule.alter.test.ts +78 -0
  286. package/src/core/objects/rule/changes/rule.alter.ts +72 -0
  287. package/src/core/objects/rule/changes/rule.base.ts +20 -0
  288. package/src/core/objects/rule/changes/rule.comment.test.ts +55 -0
  289. package/src/core/objects/rule/changes/rule.comment.ts +62 -0
  290. package/src/core/objects/rule/changes/rule.create.test.ts +59 -0
  291. package/src/core/objects/rule/changes/rule.create.ts +42 -0
  292. package/src/core/objects/rule/changes/rule.drop.test.ts +38 -0
  293. package/src/core/objects/rule/changes/rule.drop.ts +29 -0
  294. package/src/core/objects/rule/changes/rule.types.ts +12 -0
  295. package/src/core/objects/rule/rule.diff.test.ts +132 -0
  296. package/src/core/objects/rule/rule.diff.ts +79 -0
  297. package/src/core/objects/rule/rule.model.ts +173 -0
  298. package/src/core/objects/schema/changes/schema.alter.test.ts +28 -0
  299. package/src/core/objects/schema/changes/schema.alter.ts +45 -0
  300. package/src/core/objects/schema/changes/schema.base.ts +20 -0
  301. package/src/core/objects/schema/changes/schema.comment.ts +56 -0
  302. package/src/core/objects/schema/changes/schema.create.test.ts +22 -0
  303. package/src/core/objects/schema/changes/schema.create.ts +47 -0
  304. package/src/core/objects/schema/changes/schema.drop.test.ts +20 -0
  305. package/src/core/objects/schema/changes/schema.drop.ts +34 -0
  306. package/src/core/objects/schema/changes/schema.privilege.ts +175 -0
  307. package/src/core/objects/schema/changes/schema.types.ts +12 -0
  308. package/src/core/objects/schema/schema.diff.test.ts +42 -0
  309. package/src/core/objects/schema/schema.diff.ts +209 -0
  310. package/src/core/objects/schema/schema.model.ts +107 -0
  311. package/src/core/objects/sequence/changes/sequence.alter.test.ts +151 -0
  312. package/src/core/objects/sequence/changes/sequence.alter.ts +115 -0
  313. package/src/core/objects/sequence/changes/sequence.base.ts +20 -0
  314. package/src/core/objects/sequence/changes/sequence.comment.ts +60 -0
  315. package/src/core/objects/sequence/changes/sequence.create.test.ts +84 -0
  316. package/src/core/objects/sequence/changes/sequence.create.ts +111 -0
  317. package/src/core/objects/sequence/changes/sequence.drop.test.ts +32 -0
  318. package/src/core/objects/sequence/changes/sequence.drop.ts +37 -0
  319. package/src/core/objects/sequence/changes/sequence.privilege.ts +179 -0
  320. package/src/core/objects/sequence/changes/sequence.types.ts +12 -0
  321. package/src/core/objects/sequence/sequence.diff.test.ts +141 -0
  322. package/src/core/objects/sequence/sequence.diff.ts +359 -0
  323. package/src/core/objects/sequence/sequence.model.ts +185 -0
  324. package/src/core/objects/subscription/changes/subscription.alter.test.ts +124 -0
  325. package/src/core/objects/subscription/changes/subscription.alter.ts +110 -0
  326. package/src/core/objects/subscription/changes/subscription.base.ts +20 -0
  327. package/src/core/objects/subscription/changes/subscription.comment.test.ts +67 -0
  328. package/src/core/objects/subscription/changes/subscription.comment.ts +64 -0
  329. package/src/core/objects/subscription/changes/subscription.create.test.ts +77 -0
  330. package/src/core/objects/subscription/changes/subscription.create.ts +69 -0
  331. package/src/core/objects/subscription/changes/subscription.drop.test.ts +46 -0
  332. package/src/core/objects/subscription/changes/subscription.drop.ts +20 -0
  333. package/src/core/objects/subscription/changes/subscription.types.ts +22 -0
  334. package/src/core/objects/subscription/subscription.diff.test.ts +232 -0
  335. package/src/core/objects/subscription/subscription.diff.ts +241 -0
  336. package/src/core/objects/subscription/subscription.model.ts +190 -0
  337. package/src/core/objects/subscription/utils.ts +156 -0
  338. package/src/core/objects/table/changes/table.alter.test.ts +823 -0
  339. package/src/core/objects/table/changes/table.alter.ts +806 -0
  340. package/src/core/objects/table/changes/table.base.ts +20 -0
  341. package/src/core/objects/table/changes/table.comment.ts +266 -0
  342. package/src/core/objects/table/changes/table.create.test.ts +150 -0
  343. package/src/core/objects/table/changes/table.create.ts +188 -0
  344. package/src/core/objects/table/changes/table.drop.test.ts +34 -0
  345. package/src/core/objects/table/changes/table.drop.ts +45 -0
  346. package/src/core/objects/table/changes/table.privilege.ts +200 -0
  347. package/src/core/objects/table/changes/table.types.ts +12 -0
  348. package/src/core/objects/table/table.diff.test.ts +711 -0
  349. package/src/core/objects/table/table.diff.ts +953 -0
  350. package/src/core/objects/table/table.model.ts +460 -0
  351. package/src/core/objects/trigger/changes/trigger.alter.test.ts +46 -0
  352. package/src/core/objects/trigger/changes/trigger.alter.ts +76 -0
  353. package/src/core/objects/trigger/changes/trigger.base.ts +20 -0
  354. package/src/core/objects/trigger/changes/trigger.comment.ts +64 -0
  355. package/src/core/objects/trigger/changes/trigger.create.test.ts +43 -0
  356. package/src/core/objects/trigger/changes/trigger.create.ts +85 -0
  357. package/src/core/objects/trigger/changes/trigger.drop.test.ts +43 -0
  358. package/src/core/objects/trigger/changes/trigger.drop.ts +39 -0
  359. package/src/core/objects/trigger/changes/trigger.types.ts +10 -0
  360. package/src/core/objects/trigger/trigger.diff.test.ts +83 -0
  361. package/src/core/objects/trigger/trigger.diff.ts +116 -0
  362. package/src/core/objects/trigger/trigger.model.ts +252 -0
  363. package/src/core/objects/type/composite-type/changes/composite-type.alter.test.ts +202 -0
  364. package/src/core/objects/type/composite-type/changes/composite-type.alter.ts +174 -0
  365. package/src/core/objects/type/composite-type/changes/composite-type.base.ts +20 -0
  366. package/src/core/objects/type/composite-type/changes/composite-type.comment.ts +145 -0
  367. package/src/core/objects/type/composite-type/changes/composite-type.create.test.ts +101 -0
  368. package/src/core/objects/type/composite-type/changes/composite-type.create.ts +95 -0
  369. package/src/core/objects/type/composite-type/changes/composite-type.drop.test.ts +33 -0
  370. package/src/core/objects/type/composite-type/changes/composite-type.drop.ts +37 -0
  371. package/src/core/objects/type/composite-type/changes/composite-type.privilege.ts +175 -0
  372. package/src/core/objects/type/composite-type/changes/composite-type.types.ts +12 -0
  373. package/src/core/objects/type/composite-type/composite-type.diff.test.ts +191 -0
  374. package/src/core/objects/type/composite-type/composite-type.diff.ts +372 -0
  375. package/src/core/objects/type/composite-type/composite-type.model.ts +252 -0
  376. package/src/core/objects/type/enum/changes/enum.alter.test.ts +104 -0
  377. package/src/core/objects/type/enum/changes/enum.alter.ts +91 -0
  378. package/src/core/objects/type/enum/changes/enum.base.ts +20 -0
  379. package/src/core/objects/type/enum/changes/enum.comment.ts +64 -0
  380. package/src/core/objects/type/enum/changes/enum.create.test.ts +28 -0
  381. package/src/core/objects/type/enum/changes/enum.create.ts +56 -0
  382. package/src/core/objects/type/enum/changes/enum.drop.test.ts +25 -0
  383. package/src/core/objects/type/enum/changes/enum.drop.ts +34 -0
  384. package/src/core/objects/type/enum/changes/enum.privilege.ts +175 -0
  385. package/src/core/objects/type/enum/changes/enum.types.ts +12 -0
  386. package/src/core/objects/type/enum/enum.diff.test.ts +191 -0
  387. package/src/core/objects/type/enum/enum.diff.ts +396 -0
  388. package/src/core/objects/type/enum/enum.model.ts +194 -0
  389. package/src/core/objects/type/range/changes/range.alter.test.ts +27 -0
  390. package/src/core/objects/type/range/changes/range.alter.ts +51 -0
  391. package/src/core/objects/type/range/changes/range.base.ts +20 -0
  392. package/src/core/objects/type/range/changes/range.comment.ts +64 -0
  393. package/src/core/objects/type/range/changes/range.create.test.ts +51 -0
  394. package/src/core/objects/type/range/changes/range.create.ts +151 -0
  395. package/src/core/objects/type/range/changes/range.drop.test.ts +26 -0
  396. package/src/core/objects/type/range/changes/range.drop.ts +34 -0
  397. package/src/core/objects/type/range/changes/range.privilege.ts +175 -0
  398. package/src/core/objects/type/range/changes/range.types.ts +12 -0
  399. package/src/core/objects/type/range/range.diff.test.ts +70 -0
  400. package/src/core/objects/type/range/range.diff.ts +259 -0
  401. package/src/core/objects/type/range/range.model.ts +187 -0
  402. package/src/core/objects/type/type.types.ts +5 -0
  403. package/src/core/objects/utils.ts +171 -0
  404. package/src/core/objects/view/changes/view.alter.test.ts +110 -0
  405. package/src/core/objects/view/changes/view.alter.ts +112 -0
  406. package/src/core/objects/view/changes/view.base.ts +20 -0
  407. package/src/core/objects/view/changes/view.comment.ts +59 -0
  408. package/src/core/objects/view/changes/view.create.test.ts +65 -0
  409. package/src/core/objects/view/changes/view.create.ts +73 -0
  410. package/src/core/objects/view/changes/view.drop.test.ts +34 -0
  411. package/src/core/objects/view/changes/view.drop.ts +40 -0
  412. package/src/core/objects/view/changes/view.privilege.ts +200 -0
  413. package/src/core/objects/view/changes/view.types.ts +12 -0
  414. package/src/core/objects/view/view.diff.test.ts +91 -0
  415. package/src/core/objects/view/view.diff.ts +365 -0
  416. package/src/core/objects/view/view.model.ts +276 -0
  417. package/src/core/plan/apply.ts +190 -0
  418. package/src/core/plan/create.ts +432 -0
  419. package/src/core/plan/hierarchy.ts +574 -0
  420. package/src/core/plan/index.ts +29 -0
  421. package/src/core/plan/io.ts +20 -0
  422. package/src/core/plan/risk.ts +48 -0
  423. package/src/core/plan/serialize.ts +195 -0
  424. package/src/core/plan/sql-format/constants.ts +13 -0
  425. package/src/core/plan/sql-format/fixtures.ts +2806 -0
  426. package/src/core/plan/sql-format/format-comment-literals.test.ts +96 -0
  427. package/src/core/plan/sql-format/format-functions.test.ts +127 -0
  428. package/src/core/plan/sql-format/format-lowercase-coverage.test.ts +67 -0
  429. package/src/core/plan/sql-format/format-off.test.ts +809 -0
  430. package/src/core/plan/sql-format/format-pretty-lower-leading.test.ts +1056 -0
  431. package/src/core/plan/sql-format/format-pretty-narrow.test.ts +1283 -0
  432. package/src/core/plan/sql-format/format-pretty-preserve.test.ts +1052 -0
  433. package/src/core/plan/sql-format/format-pretty-upper.test.ts +1045 -0
  434. package/src/core/plan/sql-format/format-stress.test.ts +616 -0
  435. package/src/core/plan/sql-format/format-utils.test.ts +91 -0
  436. package/src/core/plan/sql-format/format-utils.ts +391 -0
  437. package/src/core/plan/sql-format/formatters.ts +921 -0
  438. package/src/core/plan/sql-format/index.ts +149 -0
  439. package/src/core/plan/sql-format/keyword-case.test.ts +118 -0
  440. package/src/core/plan/sql-format/keyword-case.ts +1085 -0
  441. package/src/core/plan/sql-format/protect.test.ts +127 -0
  442. package/src/core/plan/sql-format/protect.ts +337 -0
  443. package/src/core/plan/sql-format/sql-scanner.test.ts +240 -0
  444. package/src/core/plan/sql-format/sql-scanner.ts +252 -0
  445. package/src/core/plan/sql-format/tokenizer.test.ts +68 -0
  446. package/src/core/plan/sql-format/tokenizer.ts +152 -0
  447. package/src/core/plan/sql-format/types.ts +31 -0
  448. package/src/core/plan/sql-format/wrap.test.ts +119 -0
  449. package/src/core/plan/sql-format/wrap.ts +196 -0
  450. package/src/core/plan/sql-format.ts +2 -0
  451. package/src/core/plan/statements.ts +22 -0
  452. package/src/core/plan/types.ts +165 -0
  453. package/src/core/postgres-config.ts +169 -0
  454. package/src/core/sort/custom-constraints.ts +161 -0
  455. package/src/core/sort/debug-visualization.ts +239 -0
  456. package/src/core/sort/dependency-filter.ts +224 -0
  457. package/src/core/sort/graph-builder.ts +223 -0
  458. package/src/core/sort/graph-utils.ts +51 -0
  459. package/src/core/sort/logical-sort.ts +590 -0
  460. package/src/core/sort/sort-changes.ts +234 -0
  461. package/src/core/sort/topological-sort.ts +184 -0
  462. package/src/core/sort/types.ts +112 -0
  463. package/src/core/sort/utils.ts +69 -0
  464. package/src/index.ts +14 -0
@@ -0,0 +1,737 @@
1
+ import { formatColumnList, formatKeyValueItems, formatListItems, formatMixedItems, indentString, joinHeaderAndClauses, } from "./format-utils.js";
2
+ import { findClausePositions, findTopLevelParen, scanTokens, skipQualifiedName, sliceClauses, splitByCommas, } from "./tokenizer.js";
3
+ // ── Module-level keyword sets (hoisted to avoid per-call allocations) ────────
4
+ const DOMAIN_CLAUSE_KEYWORDS = new Set(["COLLATE", "DEFAULT", "CHECK"]);
5
+ const FUNCTION_CLAUSE_KEYWORDS = new Set([
6
+ "RETURNS",
7
+ "LANGUAGE",
8
+ "TRANSFORM",
9
+ "WINDOW",
10
+ "IMMUTABLE",
11
+ "STABLE",
12
+ "VOLATILE",
13
+ "LEAKPROOF",
14
+ "CALLED",
15
+ "STRICT",
16
+ "SECURITY",
17
+ "PARALLEL",
18
+ "COST",
19
+ "ROWS",
20
+ "SUPPORT",
21
+ "SET",
22
+ "AS",
23
+ ]);
24
+ const POLICY_CLAUSE_KEYWORDS = new Set(["FOR", "TO", "USING", "WITH"]);
25
+ const TRIGGER_CLAUSE_KEYWORDS = new Set([
26
+ "BEFORE",
27
+ "AFTER",
28
+ "INSTEAD",
29
+ "FOR",
30
+ "WHEN",
31
+ "EXECUTE",
32
+ ]);
33
+ const EVENT_TRIGGER_CLAUSE_KEYWORDS = new Set(["ON", "WHEN", "EXECUTE"]);
34
+ const INDEX_CLAUSE_KEYWORDS = new Set(["WHERE", "WITH", "TABLESPACE"]);
35
+ const LANGUAGE_CLAUSE_KEYWORDS = new Set(["HANDLER", "INLINE", "VALIDATOR"]);
36
+ const MATVIEW_CLAUSE_KEYWORDS = new Set(["WITH", "AS"]);
37
+ const SUBSCRIPTION_CLAUSE_KEYWORDS = new Set([
38
+ "CONNECTION",
39
+ "PUBLICATION",
40
+ "WITH",
41
+ ]);
42
+ const FDW_CLAUSE_KEYWORDS = new Set(["HANDLER", "VALIDATOR", "OPTIONS"]);
43
+ const EXPANDABLE_KEYWORDS = new Set(["OPTIONS", "WITH", "SET"]);
44
+ // ── Formatters ───────────────────────────────────────────────────────────────
45
+ export function formatCreateDomain(statement, tokens, options) {
46
+ if (tokens.length < 2)
47
+ return null;
48
+ if (tokens[0].upper !== "CREATE" || tokens[1].upper !== "DOMAIN") {
49
+ return null;
50
+ }
51
+ // Domain has a special NOT NULL compound clause that findClausePositions
52
+ // can't handle generically, so we keep a custom scan here.
53
+ const clauseStarts = [];
54
+ for (let i = 0; i < tokens.length; i += 1) {
55
+ if (tokens[i].depth !== 0)
56
+ continue;
57
+ const upper = tokens[i].upper;
58
+ if (DOMAIN_CLAUSE_KEYWORDS.has(upper)) {
59
+ clauseStarts.push(tokens[i].start);
60
+ continue;
61
+ }
62
+ if (upper === "NOT" &&
63
+ tokens[i + 1]?.upper === "NULL" &&
64
+ tokens[i + 1]?.depth === 0) {
65
+ clauseStarts.push(tokens[i].start);
66
+ i += 1;
67
+ }
68
+ }
69
+ if (clauseStarts.length === 0)
70
+ return null;
71
+ clauseStarts.sort((a, b) => a - b);
72
+ const prefix = statement.slice(0, clauseStarts[0]).trim();
73
+ const clauses = sliceClauses(statement, clauseStarts);
74
+ return joinHeaderAndClauses(prefix, clauses, options);
75
+ }
76
+ export function formatCreateEnum(statement, tokens, options) {
77
+ if (tokens.length < 4)
78
+ return null;
79
+ if (tokens[0].upper !== "CREATE" || tokens[1].upper !== "TYPE") {
80
+ return null;
81
+ }
82
+ const enumToken = tokens.find((token, index) => token.upper === "ENUM" && tokens[index - 1]?.upper === "AS");
83
+ if (!enumToken)
84
+ return null;
85
+ const parens = findTopLevelParen(statement, enumToken.end);
86
+ if (!parens)
87
+ return null;
88
+ const { open, close } = parens;
89
+ const header = statement.slice(0, open).trim();
90
+ const content = statement.slice(open + 1, close).trim();
91
+ const suffix = statement.slice(close + 1).trim();
92
+ const items = splitByCommas(content);
93
+ const indent = indentString(options.indent);
94
+ const listLines = formatListItems(items, indent, options.commaStyle);
95
+ const lines = [`${header} (`, ...listLines, `)${suffix ? ` ${suffix}` : ""}`];
96
+ return lines.join("\n");
97
+ }
98
+ export function formatCreateCompositeType(statement, tokens, options) {
99
+ if (tokens.length < 3)
100
+ return null;
101
+ if (tokens[0].upper !== "CREATE" || tokens[1].upper !== "TYPE") {
102
+ return null;
103
+ }
104
+ const asToken = tokens.find((token) => token.upper === "AS");
105
+ if (!asToken)
106
+ return null;
107
+ const asIndex = tokens.indexOf(asToken);
108
+ const nextToken = tokens[asIndex + 1];
109
+ if (nextToken?.upper === "ENUM" || nextToken?.upper === "RANGE") {
110
+ return null;
111
+ }
112
+ const parens = findTopLevelParen(statement, asToken.end);
113
+ if (!parens)
114
+ return null;
115
+ const { open, close } = parens;
116
+ const header = statement.slice(0, open).trim();
117
+ const content = statement.slice(open + 1, close).trim();
118
+ const suffix = statement.slice(close + 1).trim();
119
+ const formattedColumns = formatColumnList(content, options);
120
+ if (!formattedColumns)
121
+ return null;
122
+ const lines = [
123
+ `${header} (`,
124
+ ...formattedColumns,
125
+ `)${suffix ? ` ${suffix}` : ""}`,
126
+ ];
127
+ return lines.join("\n");
128
+ }
129
+ export function formatCreateTable(statement, tokens, options) {
130
+ if (tokens.length < 3)
131
+ return null;
132
+ if (tokens[0].upper !== "CREATE")
133
+ return null;
134
+ const tableToken = tokens.find((token, index) => {
135
+ if (token.upper !== "TABLE")
136
+ return false;
137
+ if (index > 0 && tokens[index - 1].upper === "RETURNS")
138
+ return false;
139
+ return true;
140
+ });
141
+ if (!tableToken)
142
+ return null;
143
+ const parens = findTopLevelParen(statement, tableToken.end);
144
+ if (!parens)
145
+ return null;
146
+ const { open, close } = parens;
147
+ const hasPartitionBeforeColumns = tokens.some((token) => token.depth === 0 && token.upper === "PARTITION" && token.start < open);
148
+ if (hasPartitionBeforeColumns)
149
+ return null;
150
+ const header = statement.slice(0, open).trim();
151
+ const content = statement.slice(open + 1, close).trim();
152
+ const suffix = statement.slice(close + 1).trim();
153
+ const formattedColumns = formatColumnList(content, options);
154
+ if (!formattedColumns)
155
+ return null;
156
+ const lines = [
157
+ `${header} (`,
158
+ ...formattedColumns,
159
+ `)${suffix ? ` ${suffix}` : ""}`,
160
+ ];
161
+ return lines.join("\n");
162
+ }
163
+ export function formatCreateRange(statement, tokens, options) {
164
+ if (tokens.length < 4)
165
+ return null;
166
+ if (tokens[0].upper !== "CREATE" || tokens[1].upper !== "TYPE") {
167
+ return null;
168
+ }
169
+ const rangeToken = tokens.find((token, index) => token.upper === "RANGE" && tokens[index - 1]?.upper === "AS");
170
+ if (!rangeToken)
171
+ return null;
172
+ const parens = findTopLevelParen(statement, rangeToken.end);
173
+ if (!parens)
174
+ return null;
175
+ const { open, close } = parens;
176
+ const header = statement.slice(0, open).trim();
177
+ const content = statement.slice(open + 1, close).trim();
178
+ const suffix = statement.slice(close + 1).trim();
179
+ const items = splitByCommas(content);
180
+ if (items.length === 0)
181
+ return null;
182
+ const formattedItems = formatKeyValueItems(items, options);
183
+ const lines = [
184
+ `${header} (`,
185
+ ...formattedItems,
186
+ `)${suffix ? ` ${suffix}` : ""}`,
187
+ ];
188
+ return lines.join("\n");
189
+ }
190
+ export function formatCreateCollation(statement, tokens, options) {
191
+ if (tokens.length < 3)
192
+ return null;
193
+ if (tokens[0].upper !== "CREATE" || tokens[1].upper !== "COLLATION") {
194
+ return null;
195
+ }
196
+ const parens = findTopLevelParen(statement, tokens[1].end);
197
+ if (!parens)
198
+ return null;
199
+ const { open, close } = parens;
200
+ const header = statement.slice(0, open).trim();
201
+ const content = statement.slice(open + 1, close).trim();
202
+ const suffix = statement.slice(close + 1).trim();
203
+ const items = splitByCommas(content);
204
+ if (items.length === 0)
205
+ return null;
206
+ const formattedItems = formatKeyValueItems(items, options);
207
+ const lines = [
208
+ `${header} (`,
209
+ ...formattedItems,
210
+ `)${suffix ? ` ${suffix}` : ""}`,
211
+ ];
212
+ return lines.join("\n");
213
+ }
214
+ export function formatCreateFunction(statement, tokens, options) {
215
+ if (tokens.length < 3)
216
+ return null;
217
+ if (tokens[0].upper !== "CREATE")
218
+ return null;
219
+ let cursor = 1;
220
+ if (tokens[cursor]?.upper === "OR" &&
221
+ tokens[cursor + 1]?.upper === "REPLACE") {
222
+ cursor += 2;
223
+ }
224
+ const objectToken = tokens[cursor];
225
+ if (!objectToken ||
226
+ (objectToken.upper !== "FUNCTION" && objectToken.upper !== "PROCEDURE")) {
227
+ return null;
228
+ }
229
+ const parens = findTopLevelParen(statement, objectToken.end);
230
+ if (!parens)
231
+ return null;
232
+ const { open, close } = parens;
233
+ const header = statement.slice(0, open).trim();
234
+ const argContent = statement.slice(open + 1, close).trim();
235
+ const postArgs = statement.slice(close + 1).trim();
236
+ const indent = indentString(options.indent);
237
+ const lines = [];
238
+ if (argContent.length === 0) {
239
+ lines.push(`${header}()`);
240
+ }
241
+ else {
242
+ const formattedArgs = formatColumnList(argContent, options);
243
+ if (formattedArgs) {
244
+ lines.push(`${header} (`, ...formattedArgs, `)`);
245
+ }
246
+ else {
247
+ lines.push(`${header}(${argContent})`);
248
+ }
249
+ }
250
+ if (postArgs.length === 0) {
251
+ return lines.join("\n");
252
+ }
253
+ // Function/procedure has special compound clauses (NOT LEAKPROOF, placeholders)
254
+ // that require a custom scan rather than the generic findClausePositions.
255
+ const postTokens = scanTokens(postArgs);
256
+ const clauseStarts = [];
257
+ for (let i = 0; i < postTokens.length; i += 1) {
258
+ const tok = postTokens[i];
259
+ if (tok.depth !== 0)
260
+ continue;
261
+ if (tok.upper === "NOT" && postTokens[i + 1]?.upper === "LEAKPROOF") {
262
+ clauseStarts.push(tok.start);
263
+ i += 1;
264
+ continue;
265
+ }
266
+ if (FUNCTION_CLAUSE_KEYWORDS.has(tok.upper)) {
267
+ clauseStarts.push(tok.start);
268
+ continue;
269
+ }
270
+ if (tok.value.startsWith("__PGDELTA_PLACEHOLDER_")) {
271
+ clauseStarts.push(tok.start);
272
+ }
273
+ }
274
+ if (clauseStarts.length === 0) {
275
+ lines[lines.length - 1] += ` ${postArgs}`;
276
+ return lines.join("\n");
277
+ }
278
+ clauseStarts.sort((a, b) => a - b);
279
+ const beforeFirstClause = postArgs.slice(0, clauseStarts[0]).trim();
280
+ if (beforeFirstClause.length > 0) {
281
+ lines[lines.length - 1] += ` ${beforeFirstClause}`;
282
+ }
283
+ const clauses = sliceClauses(postArgs, clauseStarts);
284
+ for (const clause of clauses) {
285
+ const clauseTokens = scanTokens(clause);
286
+ if (clauseTokens.length >= 2 &&
287
+ clauseTokens[0].upper === "RETURNS" &&
288
+ clauseTokens[1].upper === "TABLE") {
289
+ const tableParens = findTopLevelParen(clause, clauseTokens[1].end);
290
+ if (tableParens) {
291
+ const innerContent = clause
292
+ .slice(tableParens.open + 1, tableParens.close)
293
+ .trim();
294
+ const afterTable = clause.slice(tableParens.close + 1).trim();
295
+ if (innerContent.length > 0) {
296
+ const formattedCols = formatColumnList(innerContent, {
297
+ ...options,
298
+ indent: options.indent * 2,
299
+ });
300
+ if (formattedCols) {
301
+ lines.push(`${indent}RETURNS TABLE (`, ...formattedCols, `${indent})`);
302
+ }
303
+ else {
304
+ lines.push(`${indent}RETURNS TABLE (${innerContent})`);
305
+ }
306
+ }
307
+ else {
308
+ lines.push(`${indent}RETURNS TABLE ()`);
309
+ }
310
+ if (afterTable.length > 0) {
311
+ lines[lines.length - 1] += ` ${afterTable}`;
312
+ }
313
+ continue;
314
+ }
315
+ }
316
+ lines.push(`${indent}${clause}`);
317
+ }
318
+ return lines.join("\n");
319
+ }
320
+ export function formatCreatePolicy(statement, tokens, options) {
321
+ if (tokens.length < 3)
322
+ return null;
323
+ if (tokens[0].upper !== "CREATE" || tokens[1].upper !== "POLICY") {
324
+ return null;
325
+ }
326
+ // Policy has special WITH CHECK handling that requires a custom scan.
327
+ const clauseStarts = [];
328
+ for (let i = 2; i < tokens.length; i += 1) {
329
+ if (tokens[i].depth !== 0)
330
+ continue;
331
+ const upper = tokens[i].upper;
332
+ if (upper === "AS" &&
333
+ (tokens[i + 1]?.upper === "PERMISSIVE" ||
334
+ tokens[i + 1]?.upper === "RESTRICTIVE")) {
335
+ clauseStarts.push(tokens[i].start);
336
+ continue;
337
+ }
338
+ if (upper === "WITH" && tokens[i + 1]?.upper === "CHECK") {
339
+ clauseStarts.push(tokens[i].start);
340
+ continue;
341
+ }
342
+ if (upper === "WITH")
343
+ continue;
344
+ if (POLICY_CLAUSE_KEYWORDS.has(upper)) {
345
+ clauseStarts.push(tokens[i].start);
346
+ }
347
+ }
348
+ if (clauseStarts.length === 0)
349
+ return null;
350
+ clauseStarts.sort((a, b) => a - b);
351
+ const header = statement.slice(0, clauseStarts[0]).trim();
352
+ const clauses = sliceClauses(statement, clauseStarts);
353
+ return joinHeaderAndClauses(header, clauses, options);
354
+ }
355
+ export function formatCreateTrigger(statement, tokens, options) {
356
+ if (tokens.length < 3)
357
+ return null;
358
+ if (tokens[0].upper !== "CREATE")
359
+ return null;
360
+ let triggerIndex = -1;
361
+ for (let i = 1; i < Math.min(5, tokens.length); i += 1) {
362
+ if (tokens[i].upper === "TRIGGER") {
363
+ triggerIndex = i;
364
+ break;
365
+ }
366
+ }
367
+ if (triggerIndex === -1)
368
+ return null;
369
+ const nameToken = tokens[triggerIndex + 1];
370
+ if (!nameToken)
371
+ return null;
372
+ const headerEnd = nameToken.end;
373
+ const rest = statement.slice(headerEnd).trim();
374
+ const header = statement.slice(0, headerEnd).trim();
375
+ if (rest.length === 0)
376
+ return null;
377
+ const restTokens = scanTokens(rest);
378
+ const clauseKeywords = tokens[triggerIndex - 1]?.upper === "EVENT"
379
+ ? EVENT_TRIGGER_CLAUSE_KEYWORDS
380
+ : TRIGGER_CLAUSE_KEYWORDS;
381
+ const positions = findClausePositions(restTokens, clauseKeywords);
382
+ if (positions.length === 0)
383
+ return null;
384
+ const clauses = sliceClauses(rest, positions);
385
+ return joinHeaderAndClauses(header, clauses, options);
386
+ }
387
+ export function formatCreateIndex(statement, tokens, options) {
388
+ if (tokens.length < 3)
389
+ return null;
390
+ if (tokens[0].upper !== "CREATE")
391
+ return null;
392
+ let indexIndex = -1;
393
+ for (let i = 1; i < Math.min(4, tokens.length); i += 1) {
394
+ if (tokens[i].upper === "INDEX") {
395
+ indexIndex = i;
396
+ break;
397
+ }
398
+ }
399
+ if (indexIndex === -1)
400
+ return null;
401
+ const parens = findTopLevelParen(statement, tokens[indexIndex].end);
402
+ if (!parens)
403
+ return null;
404
+ let headerEnd = parens.close + 1;
405
+ const afterParens = statement.slice(headerEnd).trim();
406
+ const afterTokens = scanTokens(afterParens);
407
+ if (afterTokens.length > 0 && afterTokens[0].upper === "INCLUDE") {
408
+ const includeParens = findTopLevelParen(afterParens, afterTokens[0].end);
409
+ if (includeParens) {
410
+ headerEnd =
411
+ headerEnd + afterParens.slice(0, includeParens.close + 1).length;
412
+ }
413
+ }
414
+ const restText = statement.slice(headerEnd).trim();
415
+ if (restText.length === 0)
416
+ return null;
417
+ const restTokens = scanTokens(restText);
418
+ const positions = findClausePositions(restTokens, INDEX_CLAUSE_KEYWORDS);
419
+ if (positions.length === 0)
420
+ return null;
421
+ const header = statement.slice(0, headerEnd).trim();
422
+ const clauses = sliceClauses(restText, positions);
423
+ return joinHeaderAndClauses(header, clauses, options);
424
+ }
425
+ export function formatAlterTable(statement, tokens, options) {
426
+ if (tokens.length < 3)
427
+ return null;
428
+ if (tokens[0].upper !== "ALTER" || tokens[1].upper !== "TABLE") {
429
+ return null;
430
+ }
431
+ let cursor = 2;
432
+ if (tokens[cursor]?.upper === "IF" &&
433
+ tokens[cursor + 1]?.upper === "EXISTS") {
434
+ cursor += 2;
435
+ }
436
+ if (tokens[cursor]?.upper === "ONLY") {
437
+ cursor += 1;
438
+ }
439
+ if (cursor >= tokens.length)
440
+ return null;
441
+ cursor = skipQualifiedName(statement, tokens, cursor);
442
+ if (cursor >= tokens.length)
443
+ return null;
444
+ const headerEnd = tokens[cursor].start;
445
+ const header = statement.slice(0, headerEnd).trim();
446
+ const action = statement.slice(headerEnd).trim();
447
+ if (action.length === 0)
448
+ return null;
449
+ const indent = indentString(options.indent);
450
+ return `${header}\n${indent}${action}`;
451
+ }
452
+ export function formatCreateAggregate(statement, tokens, options) {
453
+ if (tokens.length < 3)
454
+ return null;
455
+ if (tokens[0].upper !== "CREATE" || tokens[1].upper !== "AGGREGATE") {
456
+ return null;
457
+ }
458
+ // Find the argument list parentheses first (e.g. array_cat_agg(anycompatiblearray))
459
+ const argParens = findTopLevelParen(statement, tokens[1].end);
460
+ if (!argParens)
461
+ return null;
462
+ // Find the options parentheses after the argument list
463
+ const optParens = findTopLevelParen(statement, argParens.close + 1);
464
+ if (!optParens)
465
+ return null;
466
+ const { open, close } = optParens;
467
+ const header = statement.slice(0, open).trim();
468
+ const content = statement.slice(open + 1, close).trim();
469
+ const suffix = statement.slice(close + 1).trim();
470
+ const items = splitByCommas(content);
471
+ if (items.length === 0)
472
+ return null;
473
+ const formattedItems = formatMixedItems(items, options);
474
+ const lines = [
475
+ `${header} (`,
476
+ ...formattedItems,
477
+ `)${suffix ? ` ${suffix}` : ""}`,
478
+ ];
479
+ return lines.join("\n");
480
+ }
481
+ export function formatCreateLanguage(statement, tokens, options) {
482
+ if (tokens.length < 3)
483
+ return null;
484
+ if (tokens[0].upper !== "CREATE")
485
+ return null;
486
+ // Find LANGUAGE token (may be preceded by TRUSTED)
487
+ let langIndex = -1;
488
+ for (let i = 1; i < Math.min(4, tokens.length); i += 1) {
489
+ if (tokens[i].upper === "LANGUAGE") {
490
+ langIndex = i;
491
+ break;
492
+ }
493
+ }
494
+ if (langIndex === -1)
495
+ return null;
496
+ // Must have a name token after LANGUAGE
497
+ const nameToken = tokens[langIndex + 1];
498
+ if (!nameToken)
499
+ return null;
500
+ const headerEnd = nameToken.end;
501
+ const rest = statement.slice(headerEnd).trim();
502
+ const header = statement.slice(0, headerEnd).trim();
503
+ if (rest.length === 0)
504
+ return null;
505
+ const restTokens = scanTokens(rest);
506
+ const positions = findClausePositions(restTokens, LANGUAGE_CLAUSE_KEYWORDS);
507
+ if (positions.length === 0)
508
+ return null;
509
+ const clauses = sliceClauses(rest, positions);
510
+ return joinHeaderAndClauses(header, clauses, options);
511
+ }
512
+ export function formatCreateMaterializedView(statement, tokens, options) {
513
+ if (tokens.length < 4)
514
+ return null;
515
+ if (tokens[0].upper !== "CREATE")
516
+ return null;
517
+ // Find MATERIALIZED VIEW sequence
518
+ let viewIndex = -1;
519
+ for (let i = 1; i < Math.min(5, tokens.length); i += 1) {
520
+ if (tokens[i].upper === "MATERIALIZED" && tokens[i + 1]?.upper === "VIEW") {
521
+ viewIndex = i + 1; // point to VIEW
522
+ break;
523
+ }
524
+ }
525
+ if (viewIndex === -1)
526
+ return null;
527
+ // Find schema-qualified name after VIEW
528
+ let cursor = viewIndex + 1;
529
+ if (cursor >= tokens.length)
530
+ return null;
531
+ cursor = skipQualifiedName(statement, tokens, cursor);
532
+ const nameEnd = tokens[cursor - 1].end;
533
+ const rest = statement.slice(nameEnd).trim();
534
+ const header = statement.slice(0, nameEnd).trim();
535
+ if (rest.length === 0)
536
+ return null;
537
+ // Materialized view has special placeholder handling for protected view bodies
538
+ const restTokens = scanTokens(rest);
539
+ const clauseStarts = [];
540
+ for (let i = 0; i < restTokens.length; i += 1) {
541
+ if (restTokens[i].depth !== 0)
542
+ continue;
543
+ if (MATVIEW_CLAUSE_KEYWORDS.has(restTokens[i].upper)) {
544
+ clauseStarts.push(restTokens[i].start);
545
+ }
546
+ // Handle placeholder for protected view body
547
+ if (restTokens[i].value.startsWith("__PGDELTA_PLACEHOLDER_")) {
548
+ clauseStarts.push(restTokens[i].start);
549
+ }
550
+ }
551
+ if (clauseStarts.length === 0)
552
+ return null;
553
+ clauseStarts.sort((a, b) => a - b);
554
+ const clauses = sliceClauses(rest, clauseStarts);
555
+ return joinHeaderAndClauses(header, clauses, options);
556
+ }
557
+ export function formatCreateSubscription(statement, tokens, options) {
558
+ if (tokens.length < 3)
559
+ return null;
560
+ if (tokens[0].upper !== "CREATE" || tokens[1].upper !== "SUBSCRIPTION") {
561
+ return null;
562
+ }
563
+ // Name is the token after SUBSCRIPTION
564
+ const nameToken = tokens[2];
565
+ if (!nameToken)
566
+ return null;
567
+ const headerEnd = nameToken.end;
568
+ const rest = statement.slice(headerEnd).trim();
569
+ const header = statement.slice(0, headerEnd).trim();
570
+ if (rest.length === 0)
571
+ return null;
572
+ const restTokens = scanTokens(rest);
573
+ const positions = findClausePositions(restTokens, SUBSCRIPTION_CLAUSE_KEYWORDS);
574
+ if (positions.length === 0)
575
+ return null;
576
+ const clauses = sliceClauses(rest, positions);
577
+ return joinHeaderAndClauses(header, clauses, options, expandOptionsClause);
578
+ }
579
+ export function formatCreateFDW(statement, tokens, options) {
580
+ if (tokens.length < 5)
581
+ return null;
582
+ if (tokens[0].upper !== "CREATE")
583
+ return null;
584
+ // Must be CREATE FOREIGN DATA WRAPPER (not CREATE SERVER ... FOREIGN DATA WRAPPER)
585
+ if (tokens[1].upper !== "FOREIGN" ||
586
+ tokens[2]?.upper !== "DATA" ||
587
+ tokens[3]?.upper !== "WRAPPER") {
588
+ return null;
589
+ }
590
+ // Name is the token after WRAPPER
591
+ const nameToken = tokens[4];
592
+ if (!nameToken)
593
+ return null;
594
+ const headerEnd = nameToken.end;
595
+ const rest = statement.slice(headerEnd).trim();
596
+ const header = statement.slice(0, headerEnd).trim();
597
+ if (rest.length === 0)
598
+ return null;
599
+ const restTokens = scanTokens(rest);
600
+ const positions = findClausePositions(restTokens, FDW_CLAUSE_KEYWORDS);
601
+ if (positions.length === 0)
602
+ return null;
603
+ const clauses = sliceClauses(rest, positions);
604
+ return joinHeaderAndClauses(header, clauses, options, expandOptionsClause);
605
+ }
606
+ export function formatCreateServer(statement, tokens, options) {
607
+ if (tokens.length < 3)
608
+ return null;
609
+ if (tokens[0].upper !== "CREATE" || tokens[1].upper !== "SERVER") {
610
+ return null;
611
+ }
612
+ // Name is the token after SERVER
613
+ const nameToken = tokens[2];
614
+ if (!nameToken)
615
+ return null;
616
+ const headerEnd = nameToken.end;
617
+ const rest = statement.slice(headerEnd).trim();
618
+ const header = statement.slice(0, headerEnd).trim();
619
+ if (rest.length === 0)
620
+ return null;
621
+ // Server has a multi-keyword clause (FOREIGN DATA WRAPPER) requiring custom scan
622
+ const restTokens = scanTokens(rest);
623
+ const clauseStarts = [];
624
+ for (let i = 0; i < restTokens.length; i += 1) {
625
+ if (restTokens[i].depth !== 0)
626
+ continue;
627
+ const upper = restTokens[i].upper;
628
+ if (upper === "TYPE" || upper === "VERSION" || upper === "OPTIONS") {
629
+ clauseStarts.push(restTokens[i].start);
630
+ continue;
631
+ }
632
+ // Handle FOREIGN DATA WRAPPER as a clause start
633
+ if (upper === "FOREIGN" &&
634
+ restTokens[i + 1]?.upper === "DATA" &&
635
+ restTokens[i + 2]?.upper === "WRAPPER") {
636
+ clauseStarts.push(restTokens[i].start);
637
+ }
638
+ }
639
+ if (clauseStarts.length === 0)
640
+ return null;
641
+ clauseStarts.sort((a, b) => a - b);
642
+ const clauses = sliceClauses(rest, clauseStarts);
643
+ return joinHeaderAndClauses(header, clauses, options, expandOptionsClause);
644
+ }
645
+ export function formatAlterGeneric(statement, tokens, options) {
646
+ if (tokens.length < 3)
647
+ return null;
648
+ if (tokens[0].upper !== "ALTER")
649
+ return null;
650
+ // Already handled by formatAlterTable
651
+ if (tokens[1].upper === "TABLE")
652
+ return null;
653
+ // Map of ALTER types to the number of type-keyword tokens
654
+ // e.g. ALTER DOMAIN = 1, ALTER FOREIGN DATA WRAPPER = 3, ALTER MATERIALIZED VIEW = 2
655
+ let typeTokenCount = 0;
656
+ const t1 = tokens[1]?.upper;
657
+ if (t1 === "DOMAIN" || t1 === "SUBSCRIPTION" || t1 === "SERVER") {
658
+ typeTokenCount = 1;
659
+ }
660
+ else if (t1 === "MATERIALIZED" && tokens[2]?.upper === "VIEW") {
661
+ typeTokenCount = 2;
662
+ }
663
+ else if (t1 === "FOREIGN") {
664
+ if (tokens[2]?.upper === "TABLE") {
665
+ typeTokenCount = 2;
666
+ }
667
+ else if (tokens[2]?.upper === "DATA" && tokens[3]?.upper === "WRAPPER") {
668
+ typeTokenCount = 3;
669
+ }
670
+ else {
671
+ return null;
672
+ }
673
+ }
674
+ else if (t1 === "EVENT" && tokens[2]?.upper === "TRIGGER") {
675
+ typeTokenCount = 2;
676
+ }
677
+ else {
678
+ return null;
679
+ }
680
+ // cursor now points to the first token after the type keywords
681
+ let cursor = 1 + typeTokenCount;
682
+ // Skip IF EXISTS
683
+ if (tokens[cursor]?.upper === "IF" &&
684
+ tokens[cursor + 1]?.upper === "EXISTS") {
685
+ cursor += 2;
686
+ }
687
+ if (cursor >= tokens.length)
688
+ return null;
689
+ // Skip the name (may be schema-qualified)
690
+ cursor = skipQualifiedName(statement, tokens, cursor);
691
+ if (cursor >= tokens.length)
692
+ return null;
693
+ const headerEnd = tokens[cursor].start;
694
+ const header = statement.slice(0, headerEnd).trim();
695
+ const action = statement.slice(headerEnd).trim();
696
+ if (action.length === 0)
697
+ return null;
698
+ const indent = indentString(options.indent);
699
+ const expandedLines = expandOptionsClause(action, indent, options);
700
+ return [header, ...expandedLines].join("\n");
701
+ }
702
+ /**
703
+ * If a clause contains a parenthesized options list (e.g. OPTIONS(...), WITH(...), SET(...))
704
+ * and it has multiple comma-separated items, expand them one per line.
705
+ * Returns an array of properly indented lines that should be pushed directly into the output.
706
+ *
707
+ * Also used as a `clauseTransform` callback for `joinHeaderAndClauses`.
708
+ */
709
+ function expandOptionsClause(clause, baseIndent, options) {
710
+ const clauseTokens = scanTokens(clause);
711
+ if (clauseTokens.length === 0)
712
+ return [`${baseIndent}${clause}`];
713
+ const firstUpper = clauseTokens[0].upper;
714
+ if (!EXPANDABLE_KEYWORDS.has(firstUpper)) {
715
+ return [`${baseIndent}${clause}`];
716
+ }
717
+ const parens = findTopLevelParen(clause, clauseTokens[0].end);
718
+ if (!parens)
719
+ return [`${baseIndent}${clause}`];
720
+ const { open, close } = parens;
721
+ const content = clause.slice(open + 1, close).trim();
722
+ const suffix = clause.slice(close + 1).trim();
723
+ const keyword = clause.slice(0, open).trim();
724
+ const items = splitByCommas(content);
725
+ if (items.length <= 1)
726
+ return [`${baseIndent}${clause}`];
727
+ const innerIndent = `${baseIndent}${indentString(options.indent)}`;
728
+ const formattedItems = formatMixedItems(items, options, innerIndent);
729
+ return [
730
+ `${baseIndent}${keyword} (`,
731
+ ...formattedItems,
732
+ `${baseIndent})${suffix ? ` ${suffix}` : ""}`,
733
+ ];
734
+ }
735
+ export function formatGeneric(statement, _tokens, _options) {
736
+ return statement.trim();
737
+ }