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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (463) hide show
  1. package/README.md +22 -0
  2. package/dist/cli/bin/cli.js +0 -0
  3. package/dist/cli/commands/plan.js +21 -0
  4. package/dist/cli/utils.d.ts +2 -0
  5. package/dist/cli/utils.js +1 -1
  6. package/dist/core/objects/table/table.model.d.ts +4 -2
  7. package/dist/core/objects/table/table.model.js +3 -0
  8. package/dist/core/objects/trigger/changes/trigger.alter.js +23 -0
  9. package/dist/core/objects/trigger/changes/trigger.create.js +2 -1
  10. package/dist/core/objects/trigger/trigger.model.d.ts +1 -0
  11. package/dist/core/objects/trigger/trigger.model.js +3 -0
  12. package/dist/core/plan/apply.js +3 -3
  13. package/dist/core/plan/create.js +34 -15
  14. package/dist/core/plan/sql-format/constants.d.ts +2 -0
  15. package/dist/core/plan/sql-format/constants.js +11 -0
  16. package/dist/core/plan/sql-format/fixtures.d.ts +2 -0
  17. package/dist/core/plan/sql-format/fixtures.js +2449 -0
  18. package/dist/core/plan/sql-format/format-utils.d.ts +37 -0
  19. package/dist/core/plan/sql-format/format-utils.js +274 -0
  20. package/dist/core/plan/sql-format/formatters.d.ts +20 -0
  21. package/dist/core/plan/sql-format/formatters.js +737 -0
  22. package/dist/core/plan/sql-format/index.d.ts +2 -0
  23. package/dist/core/plan/sql-format/index.js +98 -0
  24. package/dist/core/plan/sql-format/keyword-case.d.ts +2 -0
  25. package/dist/core/plan/sql-format/keyword-case.js +868 -0
  26. package/dist/core/plan/sql-format/protect.d.ts +3 -0
  27. package/dist/core/plan/sql-format/protect.js +269 -0
  28. package/dist/core/plan/sql-format/sql-scanner.d.ts +59 -0
  29. package/dist/core/plan/sql-format/sql-scanner.js +202 -0
  30. package/dist/core/plan/sql-format/tokenizer.d.ts +22 -0
  31. package/dist/core/plan/sql-format/tokenizer.js +118 -0
  32. package/dist/core/plan/sql-format/types.d.ts +28 -0
  33. package/dist/core/plan/sql-format/types.js +1 -0
  34. package/dist/core/plan/sql-format/wrap.d.ts +2 -0
  35. package/dist/core/plan/sql-format/wrap.js +165 -0
  36. package/dist/core/plan/sql-format.d.ts +2 -0
  37. package/dist/core/plan/sql-format.js +1 -0
  38. package/dist/core/plan/statements.d.ts +2 -1
  39. package/dist/core/plan/statements.js +6 -2
  40. package/dist/core/postgres-config.d.ts +15 -0
  41. package/dist/core/postgres-config.js +30 -0
  42. package/dist/index.d.ts +2 -0
  43. package/dist/index.js +1 -0
  44. package/package.json +37 -22
  45. package/src/cli/app.ts +28 -0
  46. package/src/cli/bin/cli.ts +9 -0
  47. package/src/cli/commands/apply.ts +101 -0
  48. package/src/cli/commands/plan.ts +195 -0
  49. package/src/cli/commands/sync.ts +185 -0
  50. package/src/cli/formatters/index.ts +5 -0
  51. package/src/cli/formatters/tree/tree-builder.ts +380 -0
  52. package/src/cli/formatters/tree/tree-renderer.ts +372 -0
  53. package/src/cli/formatters/tree/tree.ts +237 -0
  54. package/src/cli/utils/integrations.ts +42 -0
  55. package/src/cli/utils.ts +231 -0
  56. package/src/core/catalog.diff.ts +246 -0
  57. package/src/core/catalog.model.ts +384 -0
  58. package/src/core/change.types.ts +44 -0
  59. package/src/core/context.ts +26 -0
  60. package/src/core/depend.ts +1870 -0
  61. package/src/core/expand-replace-dependencies.ts +380 -0
  62. package/src/core/fingerprint.ts +204 -0
  63. package/src/core/integrations/filter/dsl.ts +204 -0
  64. package/src/core/integrations/filter/extractors.ts +145 -0
  65. package/src/core/integrations/filter/filter.types.ts +3 -0
  66. package/src/core/integrations/integration-dsl.ts +24 -0
  67. package/src/core/integrations/integration.types.ts +7 -0
  68. package/src/core/integrations/serialize/dsl.ts +77 -0
  69. package/src/core/integrations/serialize/serialize.types.ts +3 -0
  70. package/src/core/integrations/supabase.ts +121 -0
  71. package/src/core/objects/aggregate/aggregate.diff.test.ts +215 -0
  72. package/src/core/objects/aggregate/aggregate.diff.ts +278 -0
  73. package/src/core/objects/aggregate/aggregate.model.ts +317 -0
  74. package/src/core/objects/aggregate/changes/aggregate.alter.test.ts +64 -0
  75. package/src/core/objects/aggregate/changes/aggregate.alter.ts +32 -0
  76. package/src/core/objects/aggregate/changes/aggregate.base.ts +20 -0
  77. package/src/core/objects/aggregate/changes/aggregate.comment.test.ts +86 -0
  78. package/src/core/objects/aggregate/changes/aggregate.comment.ts +62 -0
  79. package/src/core/objects/aggregate/changes/aggregate.create.test.ts +101 -0
  80. package/src/core/objects/aggregate/changes/aggregate.create.ts +329 -0
  81. package/src/core/objects/aggregate/changes/aggregate.drop.test.ts +78 -0
  82. package/src/core/objects/aggregate/changes/aggregate.drop.ts +32 -0
  83. package/src/core/objects/aggregate/changes/aggregate.privilege.test.ts +130 -0
  84. package/src/core/objects/aggregate/changes/aggregate.privilege.ts +146 -0
  85. package/src/core/objects/aggregate/changes/aggregate.types.ts +12 -0
  86. package/src/core/objects/base.change.ts +62 -0
  87. package/src/core/objects/base.default-privileges.ts +204 -0
  88. package/src/core/objects/base.diff.ts +20 -0
  89. package/src/core/objects/base.model.ts +82 -0
  90. package/src/core/objects/base.privilege-diff.ts +299 -0
  91. package/src/core/objects/base.privilege.ts +184 -0
  92. package/src/core/objects/collation/changes/collation.alter.test.ts +63 -0
  93. package/src/core/objects/collation/changes/collation.alter.ts +79 -0
  94. package/src/core/objects/collation/changes/collation.base.ts +20 -0
  95. package/src/core/objects/collation/changes/collation.comment.ts +68 -0
  96. package/src/core/objects/collation/changes/collation.create.test.ts +51 -0
  97. package/src/core/objects/collation/changes/collation.create.ts +106 -0
  98. package/src/core/objects/collation/changes/collation.drop.test.ts +28 -0
  99. package/src/core/objects/collation/changes/collation.drop.ts +37 -0
  100. package/src/core/objects/collation/changes/collation.types.ts +10 -0
  101. package/src/core/objects/collation/collation.diff.test.ts +100 -0
  102. package/src/core/objects/collation/collation.diff.ts +126 -0
  103. package/src/core/objects/collation/collation.model.ts +224 -0
  104. package/src/core/objects/domain/changes/domain.alter.test.ts +316 -0
  105. package/src/core/objects/domain/changes/domain.alter.ts +286 -0
  106. package/src/core/objects/domain/changes/domain.base.ts +20 -0
  107. package/src/core/objects/domain/changes/domain.comment.ts +59 -0
  108. package/src/core/objects/domain/changes/domain.create.test.ts +65 -0
  109. package/src/core/objects/domain/changes/domain.create.ts +118 -0
  110. package/src/core/objects/domain/changes/domain.drop.test.ts +30 -0
  111. package/src/core/objects/domain/changes/domain.drop.ts +34 -0
  112. package/src/core/objects/domain/changes/domain.privilege.ts +171 -0
  113. package/src/core/objects/domain/changes/domain.types.ts +12 -0
  114. package/src/core/objects/domain/domain.diff.test.ts +284 -0
  115. package/src/core/objects/domain/domain.diff.ts +358 -0
  116. package/src/core/objects/domain/domain.model.ts +190 -0
  117. package/src/core/objects/event-trigger/changes/event-trigger.alter.test.ts +50 -0
  118. package/src/core/objects/event-trigger/changes/event-trigger.alter.ts +82 -0
  119. package/src/core/objects/event-trigger/changes/event-trigger.base.ts +20 -0
  120. package/src/core/objects/event-trigger/changes/event-trigger.comment.ts +66 -0
  121. package/src/core/objects/event-trigger/changes/event-trigger.create.test.ts +24 -0
  122. package/src/core/objects/event-trigger/changes/event-trigger.create.ts +72 -0
  123. package/src/core/objects/event-trigger/changes/event-trigger.drop.test.ts +22 -0
  124. package/src/core/objects/event-trigger/changes/event-trigger.drop.ts +34 -0
  125. package/src/core/objects/event-trigger/changes/event-trigger.types.ts +10 -0
  126. package/src/core/objects/event-trigger/event-trigger.diff.test.ts +126 -0
  127. package/src/core/objects/event-trigger/event-trigger.diff.ts +126 -0
  128. package/src/core/objects/event-trigger/event-trigger.model.ts +106 -0
  129. package/src/core/objects/extension/changes/extension.alter.test.ts +58 -0
  130. package/src/core/objects/extension/changes/extension.alter.ts +78 -0
  131. package/src/core/objects/extension/changes/extension.base.ts +20 -0
  132. package/src/core/objects/extension/changes/extension.comment.ts +64 -0
  133. package/src/core/objects/extension/changes/extension.create.test.ts +25 -0
  134. package/src/core/objects/extension/changes/extension.create.ts +63 -0
  135. package/src/core/objects/extension/changes/extension.drop.test.ts +23 -0
  136. package/src/core/objects/extension/changes/extension.drop.ts +34 -0
  137. package/src/core/objects/extension/changes/extension.types.ts +10 -0
  138. package/src/core/objects/extension/extension.diff.test.ts +42 -0
  139. package/src/core/objects/extension/extension.diff.ts +90 -0
  140. package/src/core/objects/extension/extension.model.ts +280 -0
  141. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.test.ts +125 -0
  142. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.ts +101 -0
  143. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.base.ts +20 -0
  144. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.comment.ts +72 -0
  145. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.test.ts +125 -0
  146. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.ts +95 -0
  147. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.test.ts +23 -0
  148. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.ts +36 -0
  149. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.privilege.ts +172 -0
  150. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.types.ts +12 -0
  151. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.test.ts +179 -0
  152. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.ts +341 -0
  153. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.ts +149 -0
  154. package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper.types.ts +10 -0
  155. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.test.ts +309 -0
  156. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.ts +341 -0
  157. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.ts +20 -0
  158. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.comment.ts +72 -0
  159. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.test.ts +201 -0
  160. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.ts +81 -0
  161. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.test.ts +43 -0
  162. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.ts +37 -0
  163. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.privilege.ts +181 -0
  164. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.ts +12 -0
  165. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.test.ts +813 -0
  166. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +406 -0
  167. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +242 -0
  168. package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.test.ts +168 -0
  169. package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.ts +126 -0
  170. package/src/core/objects/foreign-data-wrapper/server/changes/server.base.ts +20 -0
  171. package/src/core/objects/foreign-data-wrapper/server/changes/server.comment.ts +60 -0
  172. package/src/core/objects/foreign-data-wrapper/server/changes/server.create.test.ts +131 -0
  173. package/src/core/objects/foreign-data-wrapper/server/changes/server.create.ts +81 -0
  174. package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.test.ts +24 -0
  175. package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.ts +34 -0
  176. package/src/core/objects/foreign-data-wrapper/server/changes/server.privilege.ts +164 -0
  177. package/src/core/objects/foreign-data-wrapper/server/changes/server.types.ts +12 -0
  178. package/src/core/objects/foreign-data-wrapper/server/server.diff.test.ts +167 -0
  179. package/src/core/objects/foreign-data-wrapper/server/server.diff.ts +317 -0
  180. package/src/core/objects/foreign-data-wrapper/server/server.model.ts +133 -0
  181. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.test.ts +82 -0
  182. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.ts +69 -0
  183. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.base.ts +20 -0
  184. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.test.ts +85 -0
  185. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.ts +66 -0
  186. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.test.ts +53 -0
  187. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.ts +40 -0
  188. package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.types.ts +8 -0
  189. package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.diff.test.ts +77 -0
  190. package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.diff.ts +107 -0
  191. package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.model.ts +96 -0
  192. package/src/core/objects/index/changes/index.alter.test.ts +200 -0
  193. package/src/core/objects/index/changes/index.alter.ts +144 -0
  194. package/src/core/objects/index/changes/index.base.ts +20 -0
  195. package/src/core/objects/index/changes/index.comment.ts +63 -0
  196. package/src/core/objects/index/changes/index.create.test.ts +66 -0
  197. package/src/core/objects/index/changes/index.create.ts +68 -0
  198. package/src/core/objects/index/changes/index.drop.test.ts +44 -0
  199. package/src/core/objects/index/changes/index.drop.ts +34 -0
  200. package/src/core/objects/index/changes/index.types.ts +6 -0
  201. package/src/core/objects/index/changes/utils.ts +16 -0
  202. package/src/core/objects/index/index.diff.test.ts +153 -0
  203. package/src/core/objects/index/index.diff.ts +243 -0
  204. package/src/core/objects/index/index.model.ts +370 -0
  205. package/src/core/objects/language/changes/language.alter.test.ts +33 -0
  206. package/src/core/objects/language/changes/language.alter.ts +53 -0
  207. package/src/core/objects/language/changes/language.base.ts +20 -0
  208. package/src/core/objects/language/changes/language.comment.ts +58 -0
  209. package/src/core/objects/language/changes/language.create.test.ts +27 -0
  210. package/src/core/objects/language/changes/language.create.ts +104 -0
  211. package/src/core/objects/language/changes/language.drop.test.ts +25 -0
  212. package/src/core/objects/language/changes/language.drop.ts +39 -0
  213. package/src/core/objects/language/changes/language.privilege.ts +172 -0
  214. package/src/core/objects/language/changes/language.types.ts +12 -0
  215. package/src/core/objects/language/language.diff.test.ts +53 -0
  216. package/src/core/objects/language/language.diff.ts +176 -0
  217. package/src/core/objects/language/language.model.ts +150 -0
  218. package/src/core/objects/materialized-view/changes/materialized-view.alter.test.ts +123 -0
  219. package/src/core/objects/materialized-view/changes/materialized-view.alter.ts +113 -0
  220. package/src/core/objects/materialized-view/changes/materialized-view.base.ts +20 -0
  221. package/src/core/objects/materialized-view/changes/materialized-view.comment.ts +176 -0
  222. package/src/core/objects/materialized-view/changes/materialized-view.create.test.ts +64 -0
  223. package/src/core/objects/materialized-view/changes/materialized-view.create.ts +93 -0
  224. package/src/core/objects/materialized-view/changes/materialized-view.drop.test.ts +34 -0
  225. package/src/core/objects/materialized-view/changes/materialized-view.drop.ts +60 -0
  226. package/src/core/objects/materialized-view/changes/materialized-view.privilege.ts +212 -0
  227. package/src/core/objects/materialized-view/changes/materialized-view.types.ts +12 -0
  228. package/src/core/objects/materialized-view/materialized-view.diff.test.ts +102 -0
  229. package/src/core/objects/materialized-view/materialized-view.diff.ts +451 -0
  230. package/src/core/objects/materialized-view/materialized-view.model.ts +258 -0
  231. package/src/core/objects/procedure/changes/procedure.alter.test.ts +1005 -0
  232. package/src/core/objects/procedure/changes/procedure.alter.ts +287 -0
  233. package/src/core/objects/procedure/changes/procedure.base.ts +20 -0
  234. package/src/core/objects/procedure/changes/procedure.comment.ts +70 -0
  235. package/src/core/objects/procedure/changes/procedure.create.test.ts +48 -0
  236. package/src/core/objects/procedure/changes/procedure.create.ts +92 -0
  237. package/src/core/objects/procedure/changes/procedure.drop.test.ts +85 -0
  238. package/src/core/objects/procedure/changes/procedure.drop.ts +49 -0
  239. package/src/core/objects/procedure/changes/procedure.privilege.ts +188 -0
  240. package/src/core/objects/procedure/changes/procedure.types.ts +12 -0
  241. package/src/core/objects/procedure/procedure.diff.test.ts +161 -0
  242. package/src/core/objects/procedure/procedure.diff.ts +404 -0
  243. package/src/core/objects/procedure/procedure.model.ts +264 -0
  244. package/src/core/objects/procedure/utils.ts +58 -0
  245. package/src/core/objects/publication/changes/publication.alter.test.ts +223 -0
  246. package/src/core/objects/publication/changes/publication.alter.ts +243 -0
  247. package/src/core/objects/publication/changes/publication.base.ts +20 -0
  248. package/src/core/objects/publication/changes/publication.comment.test.ts +70 -0
  249. package/src/core/objects/publication/changes/publication.comment.ts +64 -0
  250. package/src/core/objects/publication/changes/publication.create.test.ts +87 -0
  251. package/src/core/objects/publication/changes/publication.create.ts +82 -0
  252. package/src/core/objects/publication/changes/publication.drop.test.ts +46 -0
  253. package/src/core/objects/publication/changes/publication.drop.ts +29 -0
  254. package/src/core/objects/publication/changes/publication.types.ts +26 -0
  255. package/src/core/objects/publication/publication.diff.test.ts +292 -0
  256. package/src/core/objects/publication/publication.diff.ts +253 -0
  257. package/src/core/objects/publication/publication.model.ts +206 -0
  258. package/src/core/objects/publication/utils.ts +55 -0
  259. package/src/core/objects/rls-policy/changes/rls-policy.alter.test.ts +250 -0
  260. package/src/core/objects/rls-policy/changes/rls-policy.alter.ts +128 -0
  261. package/src/core/objects/rls-policy/changes/rls-policy.base.ts +20 -0
  262. package/src/core/objects/rls-policy/changes/rls-policy.comment.ts +69 -0
  263. package/src/core/objects/rls-policy/changes/rls-policy.create.test.ts +74 -0
  264. package/src/core/objects/rls-policy/changes/rls-policy.create.ts +100 -0
  265. package/src/core/objects/rls-policy/changes/rls-policy.drop.test.ts +28 -0
  266. package/src/core/objects/rls-policy/changes/rls-policy.drop.ts +39 -0
  267. package/src/core/objects/rls-policy/changes/rls-policy.types.ts +10 -0
  268. package/src/core/objects/rls-policy/rls-policy.diff.test.ts +79 -0
  269. package/src/core/objects/rls-policy/rls-policy.diff.ts +121 -0
  270. package/src/core/objects/rls-policy/rls-policy.model.ts +140 -0
  271. package/src/core/objects/role/changes/role.alter.test.ts +346 -0
  272. package/src/core/objects/role/changes/role.alter.ts +110 -0
  273. package/src/core/objects/role/changes/role.base.ts +24 -0
  274. package/src/core/objects/role/changes/role.comment.ts +55 -0
  275. package/src/core/objects/role/changes/role.create.test.ts +52 -0
  276. package/src/core/objects/role/changes/role.create.ts +102 -0
  277. package/src/core/objects/role/changes/role.drop.test.ts +29 -0
  278. package/src/core/objects/role/changes/role.drop.ts +34 -0
  279. package/src/core/objects/role/changes/role.privilege.ts +376 -0
  280. package/src/core/objects/role/changes/role.types.ts +12 -0
  281. package/src/core/objects/role/role.diff.test.ts +44 -0
  282. package/src/core/objects/role/role.diff.ts +479 -0
  283. package/src/core/objects/role/role.model.ts +344 -0
  284. package/src/core/objects/rule/changes/rule.alter.test.ts +78 -0
  285. package/src/core/objects/rule/changes/rule.alter.ts +72 -0
  286. package/src/core/objects/rule/changes/rule.base.ts +20 -0
  287. package/src/core/objects/rule/changes/rule.comment.test.ts +55 -0
  288. package/src/core/objects/rule/changes/rule.comment.ts +62 -0
  289. package/src/core/objects/rule/changes/rule.create.test.ts +59 -0
  290. package/src/core/objects/rule/changes/rule.create.ts +42 -0
  291. package/src/core/objects/rule/changes/rule.drop.test.ts +38 -0
  292. package/src/core/objects/rule/changes/rule.drop.ts +29 -0
  293. package/src/core/objects/rule/changes/rule.types.ts +12 -0
  294. package/src/core/objects/rule/rule.diff.test.ts +132 -0
  295. package/src/core/objects/rule/rule.diff.ts +79 -0
  296. package/src/core/objects/rule/rule.model.ts +173 -0
  297. package/src/core/objects/schema/changes/schema.alter.test.ts +28 -0
  298. package/src/core/objects/schema/changes/schema.alter.ts +45 -0
  299. package/src/core/objects/schema/changes/schema.base.ts +20 -0
  300. package/src/core/objects/schema/changes/schema.comment.ts +56 -0
  301. package/src/core/objects/schema/changes/schema.create.test.ts +22 -0
  302. package/src/core/objects/schema/changes/schema.create.ts +47 -0
  303. package/src/core/objects/schema/changes/schema.drop.test.ts +20 -0
  304. package/src/core/objects/schema/changes/schema.drop.ts +34 -0
  305. package/src/core/objects/schema/changes/schema.privilege.ts +175 -0
  306. package/src/core/objects/schema/changes/schema.types.ts +12 -0
  307. package/src/core/objects/schema/schema.diff.test.ts +42 -0
  308. package/src/core/objects/schema/schema.diff.ts +209 -0
  309. package/src/core/objects/schema/schema.model.ts +107 -0
  310. package/src/core/objects/sequence/changes/sequence.alter.test.ts +151 -0
  311. package/src/core/objects/sequence/changes/sequence.alter.ts +115 -0
  312. package/src/core/objects/sequence/changes/sequence.base.ts +20 -0
  313. package/src/core/objects/sequence/changes/sequence.comment.ts +60 -0
  314. package/src/core/objects/sequence/changes/sequence.create.test.ts +84 -0
  315. package/src/core/objects/sequence/changes/sequence.create.ts +111 -0
  316. package/src/core/objects/sequence/changes/sequence.drop.test.ts +32 -0
  317. package/src/core/objects/sequence/changes/sequence.drop.ts +37 -0
  318. package/src/core/objects/sequence/changes/sequence.privilege.ts +179 -0
  319. package/src/core/objects/sequence/changes/sequence.types.ts +12 -0
  320. package/src/core/objects/sequence/sequence.diff.test.ts +141 -0
  321. package/src/core/objects/sequence/sequence.diff.ts +359 -0
  322. package/src/core/objects/sequence/sequence.model.ts +185 -0
  323. package/src/core/objects/subscription/changes/subscription.alter.test.ts +124 -0
  324. package/src/core/objects/subscription/changes/subscription.alter.ts +110 -0
  325. package/src/core/objects/subscription/changes/subscription.base.ts +20 -0
  326. package/src/core/objects/subscription/changes/subscription.comment.test.ts +67 -0
  327. package/src/core/objects/subscription/changes/subscription.comment.ts +64 -0
  328. package/src/core/objects/subscription/changes/subscription.create.test.ts +77 -0
  329. package/src/core/objects/subscription/changes/subscription.create.ts +69 -0
  330. package/src/core/objects/subscription/changes/subscription.drop.test.ts +46 -0
  331. package/src/core/objects/subscription/changes/subscription.drop.ts +20 -0
  332. package/src/core/objects/subscription/changes/subscription.types.ts +22 -0
  333. package/src/core/objects/subscription/subscription.diff.test.ts +232 -0
  334. package/src/core/objects/subscription/subscription.diff.ts +241 -0
  335. package/src/core/objects/subscription/subscription.model.ts +190 -0
  336. package/src/core/objects/subscription/utils.ts +156 -0
  337. package/src/core/objects/table/changes/table.alter.test.ts +823 -0
  338. package/src/core/objects/table/changes/table.alter.ts +806 -0
  339. package/src/core/objects/table/changes/table.base.ts +20 -0
  340. package/src/core/objects/table/changes/table.comment.ts +266 -0
  341. package/src/core/objects/table/changes/table.create.test.ts +150 -0
  342. package/src/core/objects/table/changes/table.create.ts +188 -0
  343. package/src/core/objects/table/changes/table.drop.test.ts +34 -0
  344. package/src/core/objects/table/changes/table.drop.ts +45 -0
  345. package/src/core/objects/table/changes/table.privilege.ts +200 -0
  346. package/src/core/objects/table/changes/table.types.ts +12 -0
  347. package/src/core/objects/table/table.diff.test.ts +711 -0
  348. package/src/core/objects/table/table.diff.ts +953 -0
  349. package/src/core/objects/table/table.model.ts +460 -0
  350. package/src/core/objects/trigger/changes/trigger.alter.test.ts +46 -0
  351. package/src/core/objects/trigger/changes/trigger.alter.ts +76 -0
  352. package/src/core/objects/trigger/changes/trigger.base.ts +20 -0
  353. package/src/core/objects/trigger/changes/trigger.comment.ts +64 -0
  354. package/src/core/objects/trigger/changes/trigger.create.test.ts +43 -0
  355. package/src/core/objects/trigger/changes/trigger.create.ts +85 -0
  356. package/src/core/objects/trigger/changes/trigger.drop.test.ts +43 -0
  357. package/src/core/objects/trigger/changes/trigger.drop.ts +39 -0
  358. package/src/core/objects/trigger/changes/trigger.types.ts +10 -0
  359. package/src/core/objects/trigger/trigger.diff.test.ts +83 -0
  360. package/src/core/objects/trigger/trigger.diff.ts +116 -0
  361. package/src/core/objects/trigger/trigger.model.ts +252 -0
  362. package/src/core/objects/type/composite-type/changes/composite-type.alter.test.ts +202 -0
  363. package/src/core/objects/type/composite-type/changes/composite-type.alter.ts +174 -0
  364. package/src/core/objects/type/composite-type/changes/composite-type.base.ts +20 -0
  365. package/src/core/objects/type/composite-type/changes/composite-type.comment.ts +145 -0
  366. package/src/core/objects/type/composite-type/changes/composite-type.create.test.ts +101 -0
  367. package/src/core/objects/type/composite-type/changes/composite-type.create.ts +95 -0
  368. package/src/core/objects/type/composite-type/changes/composite-type.drop.test.ts +33 -0
  369. package/src/core/objects/type/composite-type/changes/composite-type.drop.ts +37 -0
  370. package/src/core/objects/type/composite-type/changes/composite-type.privilege.ts +175 -0
  371. package/src/core/objects/type/composite-type/changes/composite-type.types.ts +12 -0
  372. package/src/core/objects/type/composite-type/composite-type.diff.test.ts +191 -0
  373. package/src/core/objects/type/composite-type/composite-type.diff.ts +372 -0
  374. package/src/core/objects/type/composite-type/composite-type.model.ts +252 -0
  375. package/src/core/objects/type/enum/changes/enum.alter.test.ts +104 -0
  376. package/src/core/objects/type/enum/changes/enum.alter.ts +91 -0
  377. package/src/core/objects/type/enum/changes/enum.base.ts +20 -0
  378. package/src/core/objects/type/enum/changes/enum.comment.ts +64 -0
  379. package/src/core/objects/type/enum/changes/enum.create.test.ts +28 -0
  380. package/src/core/objects/type/enum/changes/enum.create.ts +56 -0
  381. package/src/core/objects/type/enum/changes/enum.drop.test.ts +25 -0
  382. package/src/core/objects/type/enum/changes/enum.drop.ts +34 -0
  383. package/src/core/objects/type/enum/changes/enum.privilege.ts +175 -0
  384. package/src/core/objects/type/enum/changes/enum.types.ts +12 -0
  385. package/src/core/objects/type/enum/enum.diff.test.ts +191 -0
  386. package/src/core/objects/type/enum/enum.diff.ts +396 -0
  387. package/src/core/objects/type/enum/enum.model.ts +194 -0
  388. package/src/core/objects/type/range/changes/range.alter.test.ts +27 -0
  389. package/src/core/objects/type/range/changes/range.alter.ts +51 -0
  390. package/src/core/objects/type/range/changes/range.base.ts +20 -0
  391. package/src/core/objects/type/range/changes/range.comment.ts +64 -0
  392. package/src/core/objects/type/range/changes/range.create.test.ts +51 -0
  393. package/src/core/objects/type/range/changes/range.create.ts +151 -0
  394. package/src/core/objects/type/range/changes/range.drop.test.ts +26 -0
  395. package/src/core/objects/type/range/changes/range.drop.ts +34 -0
  396. package/src/core/objects/type/range/changes/range.privilege.ts +175 -0
  397. package/src/core/objects/type/range/changes/range.types.ts +12 -0
  398. package/src/core/objects/type/range/range.diff.test.ts +70 -0
  399. package/src/core/objects/type/range/range.diff.ts +259 -0
  400. package/src/core/objects/type/range/range.model.ts +187 -0
  401. package/src/core/objects/type/type.types.ts +5 -0
  402. package/src/core/objects/utils.ts +171 -0
  403. package/src/core/objects/view/changes/view.alter.test.ts +110 -0
  404. package/src/core/objects/view/changes/view.alter.ts +112 -0
  405. package/src/core/objects/view/changes/view.base.ts +20 -0
  406. package/src/core/objects/view/changes/view.comment.ts +59 -0
  407. package/src/core/objects/view/changes/view.create.test.ts +65 -0
  408. package/src/core/objects/view/changes/view.create.ts +73 -0
  409. package/src/core/objects/view/changes/view.drop.test.ts +34 -0
  410. package/src/core/objects/view/changes/view.drop.ts +40 -0
  411. package/src/core/objects/view/changes/view.privilege.ts +200 -0
  412. package/src/core/objects/view/changes/view.types.ts +12 -0
  413. package/src/core/objects/view/view.diff.test.ts +91 -0
  414. package/src/core/objects/view/view.diff.ts +365 -0
  415. package/src/core/objects/view/view.model.ts +276 -0
  416. package/src/core/plan/apply.ts +190 -0
  417. package/src/core/plan/create.ts +432 -0
  418. package/src/core/plan/hierarchy.ts +574 -0
  419. package/src/core/plan/index.ts +29 -0
  420. package/src/core/plan/io.ts +20 -0
  421. package/src/core/plan/risk.ts +48 -0
  422. package/src/core/plan/serialize.ts +195 -0
  423. package/src/core/plan/sql-format/constants.ts +13 -0
  424. package/src/core/plan/sql-format/fixtures.ts +2806 -0
  425. package/src/core/plan/sql-format/format-comment-literals.test.ts +96 -0
  426. package/src/core/plan/sql-format/format-functions.test.ts +127 -0
  427. package/src/core/plan/sql-format/format-lowercase-coverage.test.ts +67 -0
  428. package/src/core/plan/sql-format/format-off.test.ts +809 -0
  429. package/src/core/plan/sql-format/format-pretty-lower-leading.test.ts +1056 -0
  430. package/src/core/plan/sql-format/format-pretty-narrow.test.ts +1283 -0
  431. package/src/core/plan/sql-format/format-pretty-preserve.test.ts +1052 -0
  432. package/src/core/plan/sql-format/format-pretty-upper.test.ts +1045 -0
  433. package/src/core/plan/sql-format/format-stress.test.ts +616 -0
  434. package/src/core/plan/sql-format/format-utils.test.ts +91 -0
  435. package/src/core/plan/sql-format/format-utils.ts +391 -0
  436. package/src/core/plan/sql-format/formatters.ts +921 -0
  437. package/src/core/plan/sql-format/index.ts +149 -0
  438. package/src/core/plan/sql-format/keyword-case.test.ts +118 -0
  439. package/src/core/plan/sql-format/keyword-case.ts +1085 -0
  440. package/src/core/plan/sql-format/protect.test.ts +127 -0
  441. package/src/core/plan/sql-format/protect.ts +337 -0
  442. package/src/core/plan/sql-format/sql-scanner.test.ts +240 -0
  443. package/src/core/plan/sql-format/sql-scanner.ts +252 -0
  444. package/src/core/plan/sql-format/tokenizer.test.ts +68 -0
  445. package/src/core/plan/sql-format/tokenizer.ts +152 -0
  446. package/src/core/plan/sql-format/types.ts +31 -0
  447. package/src/core/plan/sql-format/wrap.test.ts +119 -0
  448. package/src/core/plan/sql-format/wrap.ts +196 -0
  449. package/src/core/plan/sql-format.ts +2 -0
  450. package/src/core/plan/statements.ts +22 -0
  451. package/src/core/plan/types.ts +165 -0
  452. package/src/core/postgres-config.ts +169 -0
  453. package/src/core/sort/custom-constraints.ts +161 -0
  454. package/src/core/sort/debug-visualization.ts +239 -0
  455. package/src/core/sort/dependency-filter.ts +224 -0
  456. package/src/core/sort/graph-builder.ts +223 -0
  457. package/src/core/sort/graph-utils.ts +51 -0
  458. package/src/core/sort/logical-sort.ts +590 -0
  459. package/src/core/sort/sort-changes.ts +234 -0
  460. package/src/core/sort/topological-sort.ts +184 -0
  461. package/src/core/sort/types.ts +112 -0
  462. package/src/core/sort/utils.ts +69 -0
  463. package/src/index.ts +14 -0
@@ -0,0 +1,358 @@
1
+ import type { DefaultPrivilegeState } from "../base.default-privileges.ts";
2
+ import { diffObjects } from "../base.diff.ts";
3
+ import {
4
+ diffPrivileges,
5
+ filterPublicBuiltInDefaults,
6
+ groupPrivilegesByGrantable,
7
+ } from "../base.privilege-diff.ts";
8
+ import type { Role } from "../role/role.model.ts";
9
+ import {
10
+ AlterDomainAddConstraint,
11
+ AlterDomainChangeOwner,
12
+ AlterDomainDropConstraint,
13
+ AlterDomainDropDefault,
14
+ AlterDomainDropNotNull,
15
+ AlterDomainSetDefault,
16
+ AlterDomainSetNotNull,
17
+ AlterDomainValidateConstraint,
18
+ } from "./changes/domain.alter.ts";
19
+ import {
20
+ CreateCommentOnDomain,
21
+ DropCommentOnDomain,
22
+ } from "./changes/domain.comment.ts";
23
+ import { CreateDomain } from "./changes/domain.create.ts";
24
+ import { DropDomain } from "./changes/domain.drop.ts";
25
+ import {
26
+ GrantDomainPrivileges,
27
+ RevokeDomainPrivileges,
28
+ RevokeGrantOptionDomainPrivileges,
29
+ } from "./changes/domain.privilege.ts";
30
+ import type { DomainChange } from "./changes/domain.types.ts";
31
+ import type { Domain } from "./domain.model.ts";
32
+
33
+ /**
34
+ * Diff two sets of domains from main and branch catalogs.
35
+ *
36
+ * @param ctx - Context containing version, currentUser, and defaultPrivilegeState
37
+ * @param main - The domains in the main catalog.
38
+ * @param branch - The domains in the branch catalog.
39
+ * @returns A list of changes to apply to main to make it match branch.
40
+ */
41
+ export function diffDomains(
42
+ ctx: {
43
+ version: number;
44
+ currentUser: string;
45
+ defaultPrivilegeState: DefaultPrivilegeState;
46
+ mainRoles: Record<string, Role>;
47
+ },
48
+ main: Record<string, Domain>,
49
+ branch: Record<string, Domain>,
50
+ ): DomainChange[] {
51
+ const { created, dropped, altered } = diffObjects(main, branch);
52
+
53
+ const changes: DomainChange[] = [];
54
+
55
+ for (const domainId of created) {
56
+ const newDomain = branch[domainId];
57
+ changes.push(new CreateDomain({ domain: newDomain }));
58
+
59
+ // OWNER: If the domain should be owned by someone other than the current user,
60
+ // emit ALTER DOMAIN ... OWNER TO after creation
61
+ if (newDomain.owner !== ctx.currentUser) {
62
+ changes.push(
63
+ new AlterDomainChangeOwner({
64
+ domain: newDomain,
65
+ owner: newDomain.owner,
66
+ }),
67
+ );
68
+ }
69
+
70
+ if (newDomain.comment !== null) {
71
+ changes.push(new CreateCommentOnDomain({ domain: newDomain }));
72
+ }
73
+ // For unvalidated constraints, CREATE DOMAIN cannot specify NOT VALID.
74
+ // Add them after creation and validate to match branch state semantics.
75
+ // For already validated constraints, they are emitted inline in CREATE DOMAIN.
76
+ if (newDomain.constraints && newDomain.constraints.length > 0) {
77
+ for (const c of newDomain.constraints) {
78
+ if (c.validated === false) {
79
+ changes.push(
80
+ new AlterDomainAddConstraint({ domain: newDomain, constraint: c }),
81
+ );
82
+ changes.push(
83
+ new AlterDomainValidateConstraint({
84
+ domain: newDomain,
85
+ constraint: c,
86
+ }),
87
+ );
88
+ }
89
+ }
90
+ }
91
+
92
+ // PRIVILEGES: For created objects, compare against default privileges state
93
+ // The migration script will run ALTER DEFAULT PRIVILEGES before CREATE (via constraint spec),
94
+ // so objects are created with the default privileges state in effect.
95
+ // We compare default privileges against desired privileges to generate REVOKE/GRANT statements
96
+ // needed to reach the final desired state.
97
+ const effectiveDefaults = ctx.defaultPrivilegeState.getEffectiveDefaults(
98
+ ctx.currentUser,
99
+ "domain",
100
+ newDomain.schema ?? "",
101
+ );
102
+ // Filter out PUBLIC's built-in default USAGE privilege (PostgreSQL grants it automatically)
103
+ // Reference: https://www.postgresql.org/docs/17/ddl-priv.html Table 5.2
104
+ // This prevents generating unnecessary "GRANT USAGE TO PUBLIC" statements
105
+ const desiredPrivileges = filterPublicBuiltInDefaults(
106
+ "domain",
107
+ newDomain.privileges,
108
+ );
109
+ // Filter out owner privileges - owner always has ALL privileges implicitly
110
+ // and shouldn't be compared. Use the domain owner as the reference.
111
+ const privilegeResults = diffPrivileges(
112
+ effectiveDefaults,
113
+ desiredPrivileges,
114
+ newDomain.owner,
115
+ ctx.mainRoles,
116
+ );
117
+
118
+ // Generate grant changes
119
+ for (const [grantee, result] of privilegeResults) {
120
+ if (result.grants.length > 0) {
121
+ const grantGroups = groupPrivilegesByGrantable(result.grants);
122
+ for (const [grantable, list] of grantGroups) {
123
+ void grantable;
124
+ changes.push(
125
+ new GrantDomainPrivileges({
126
+ domain: newDomain,
127
+ grantee,
128
+ privileges: list,
129
+ version: ctx.version,
130
+ }),
131
+ );
132
+ }
133
+ }
134
+
135
+ // Generate revoke changes
136
+ if (result.revokes.length > 0) {
137
+ const revokeGroups = groupPrivilegesByGrantable(result.revokes);
138
+ for (const [grantable, list] of revokeGroups) {
139
+ void grantable;
140
+ changes.push(
141
+ new RevokeDomainPrivileges({
142
+ domain: newDomain,
143
+ grantee,
144
+ privileges: list,
145
+ version: ctx.version,
146
+ }),
147
+ );
148
+ }
149
+ }
150
+
151
+ // Generate revoke grant option changes
152
+ if (result.revokeGrantOption.length > 0) {
153
+ changes.push(
154
+ new RevokeGrantOptionDomainPrivileges({
155
+ domain: newDomain,
156
+ grantee,
157
+ privilegeNames: result.revokeGrantOption,
158
+ version: ctx.version,
159
+ }),
160
+ );
161
+ }
162
+ }
163
+ }
164
+
165
+ for (const domainId of dropped) {
166
+ changes.push(new DropDomain({ domain: main[domainId] }));
167
+ }
168
+
169
+ for (const domainId of altered) {
170
+ const mainDomain = main[domainId];
171
+ const branchDomain = branch[domainId];
172
+
173
+ // DEFAULT
174
+ if (mainDomain.default_value !== branchDomain.default_value) {
175
+ if (branchDomain.default_value === null) {
176
+ changes.push(new AlterDomainDropDefault({ domain: mainDomain }));
177
+ } else {
178
+ changes.push(
179
+ new AlterDomainSetDefault({
180
+ domain: mainDomain,
181
+ defaultValue: branchDomain.default_value,
182
+ }),
183
+ );
184
+ }
185
+ }
186
+
187
+ // NOT NULL
188
+ if (mainDomain.not_null !== branchDomain.not_null) {
189
+ if (branchDomain.not_null) {
190
+ changes.push(new AlterDomainSetNotNull({ domain: mainDomain }));
191
+ } else {
192
+ changes.push(new AlterDomainDropNotNull({ domain: mainDomain }));
193
+ }
194
+ }
195
+
196
+ // DOMAIN CONSTRAINTS
197
+ const mainByName = new Map(mainDomain.constraints.map((c) => [c.name, c]));
198
+ const branchByName = new Map(
199
+ branchDomain.constraints.map((c) => [c.name, c]),
200
+ );
201
+
202
+ // Note: Constraint renames are modeled as drop+add because name is part
203
+ // of the identity we diff on. No dedicated rename class is generated here.
204
+
205
+ // Created
206
+ for (const [name, c] of branchByName) {
207
+ if (!mainByName.has(name)) {
208
+ changes.push(
209
+ new AlterDomainAddConstraint({
210
+ domain: branchDomain,
211
+ constraint: c,
212
+ }),
213
+ );
214
+ if (!c.validated) {
215
+ changes.push(
216
+ new AlterDomainValidateConstraint({
217
+ domain: branchDomain,
218
+ constraint: c,
219
+ }),
220
+ );
221
+ }
222
+ }
223
+ }
224
+
225
+ // Dropped
226
+ for (const [name, c] of mainByName) {
227
+ if (!branchByName.has(name)) {
228
+ changes.push(
229
+ new AlterDomainDropConstraint({
230
+ domain: mainDomain,
231
+ constraint: c,
232
+ }),
233
+ );
234
+ }
235
+ }
236
+
237
+ // Altered (drop + add for now)
238
+ for (const [name, mainC] of mainByName) {
239
+ const branchC = branchByName.get(name);
240
+ if (!branchC) continue;
241
+ const changed =
242
+ mainC.validated !== branchC.validated ||
243
+ mainC.is_local !== branchC.is_local ||
244
+ mainC.no_inherit !== branchC.no_inherit ||
245
+ mainC.check_expression !== branchC.check_expression;
246
+ if (changed) {
247
+ changes.push(
248
+ new AlterDomainDropConstraint({
249
+ domain: mainDomain,
250
+ constraint: mainC,
251
+ }),
252
+ );
253
+ changes.push(
254
+ new AlterDomainAddConstraint({
255
+ domain: branchDomain,
256
+ constraint: branchC,
257
+ }),
258
+ );
259
+ if (!branchC.validated) {
260
+ changes.push(
261
+ new AlterDomainValidateConstraint({
262
+ domain: branchDomain,
263
+ constraint: branchC,
264
+ }),
265
+ );
266
+ }
267
+ }
268
+ }
269
+
270
+ // OWNER
271
+ if (mainDomain.owner !== branchDomain.owner) {
272
+ changes.push(
273
+ new AlterDomainChangeOwner({
274
+ domain: mainDomain,
275
+ owner: branchDomain.owner,
276
+ }),
277
+ );
278
+ }
279
+
280
+ // COMMENT
281
+ if (mainDomain.comment !== branchDomain.comment) {
282
+ if (branchDomain.comment === null) {
283
+ changes.push(new DropCommentOnDomain({ domain: mainDomain }));
284
+ } else {
285
+ changes.push(new CreateCommentOnDomain({ domain: branchDomain }));
286
+ }
287
+ }
288
+
289
+ // PRIVILEGES
290
+ // Filter out PUBLIC's built-in default USAGE privilege from main catalog
291
+ // (PostgreSQL grants it automatically, so we shouldn't compare it)
292
+ const mainPrivilegesFiltered = filterPublicBuiltInDefaults(
293
+ "domain",
294
+ mainDomain.privileges,
295
+ );
296
+ // Filter out PUBLIC's built-in default USAGE privilege from branch catalog
297
+ const branchPrivilegesFiltered = filterPublicBuiltInDefaults(
298
+ "domain",
299
+ branchDomain.privileges,
300
+ );
301
+ // Filter out owner privileges - owner always has ALL privileges implicitly
302
+ // and shouldn't be compared. Use branch owner as the reference.
303
+ const privilegeResults = diffPrivileges(
304
+ mainPrivilegesFiltered,
305
+ branchPrivilegesFiltered,
306
+ branchDomain.owner,
307
+ ctx.mainRoles,
308
+ );
309
+
310
+ for (const [grantee, result] of privilegeResults) {
311
+ // Generate grant changes
312
+ if (result.grants.length > 0) {
313
+ const grantGroups = groupPrivilegesByGrantable(result.grants);
314
+ for (const [grantable, list] of grantGroups) {
315
+ void grantable;
316
+ changes.push(
317
+ new GrantDomainPrivileges({
318
+ domain: branchDomain,
319
+ grantee,
320
+ privileges: list,
321
+ version: ctx.version,
322
+ }),
323
+ );
324
+ }
325
+ }
326
+
327
+ // Generate revoke changes
328
+ if (result.revokes.length > 0) {
329
+ const revokeGroups = groupPrivilegesByGrantable(result.revokes);
330
+ for (const [grantable, list] of revokeGroups) {
331
+ void grantable;
332
+ changes.push(
333
+ new RevokeDomainPrivileges({
334
+ domain: mainDomain,
335
+ grantee,
336
+ privileges: list,
337
+ version: ctx.version,
338
+ }),
339
+ );
340
+ }
341
+ }
342
+
343
+ // Generate revoke grant option changes
344
+ if (result.revokeGrantOption.length > 0) {
345
+ changes.push(
346
+ new RevokeGrantOptionDomainPrivileges({
347
+ domain: mainDomain,
348
+ grantee,
349
+ privilegeNames: result.revokeGrantOption,
350
+ version: ctx.version,
351
+ }),
352
+ );
353
+ }
354
+ }
355
+ }
356
+
357
+ return changes;
358
+ }
@@ -0,0 +1,190 @@
1
+ import { sql } from "@ts-safeql/sql-tag";
2
+ import type { Pool } from "pg";
3
+ import z from "zod";
4
+ import { BasePgModel } from "../base.model.ts";
5
+ import {
6
+ type PrivilegeProps,
7
+ privilegePropsSchema,
8
+ } from "../base.privilege-diff.ts";
9
+
10
+ const domainConstraintPropsSchema = z.object({
11
+ name: z.string(),
12
+ validated: z.boolean(),
13
+ is_local: z.boolean(),
14
+ no_inherit: z.boolean(),
15
+ check_expression: z.string().nullable(),
16
+ });
17
+
18
+ const domainPropsSchema = z.object({
19
+ schema: z.string(),
20
+ name: z.string(),
21
+ base_type: z.string(),
22
+ base_type_schema: z.string(),
23
+ base_type_str: z.string().optional(),
24
+ not_null: z.boolean(),
25
+ type_modifier: z.number().nullable(),
26
+ array_dimensions: z.number().nullable(),
27
+ collation: z.string().nullable(),
28
+ default_bin: z.string().nullable(),
29
+ default_value: z.string().nullable(),
30
+ owner: z.string(),
31
+ comment: z.string().nullable(),
32
+ constraints: z.array(domainConstraintPropsSchema),
33
+ privileges: z.array(privilegePropsSchema),
34
+ });
35
+
36
+ export type DomainConstraintProps = z.infer<typeof domainConstraintPropsSchema>;
37
+ type DomainPrivilegeProps = PrivilegeProps;
38
+ export type DomainProps = z.infer<typeof domainPropsSchema>;
39
+
40
+ /**
41
+ * A domain is a user-defined data type that is based on another underlying type.
42
+ *
43
+ * @see https://www.postgresql.org/docs/17/domains.html
44
+ */
45
+ export class Domain extends BasePgModel {
46
+ public readonly schema: DomainProps["schema"];
47
+ public readonly name: DomainProps["name"];
48
+ public readonly base_type: DomainProps["base_type"];
49
+ public readonly base_type_schema: DomainProps["base_type_schema"];
50
+ public readonly base_type_str?: DomainProps["base_type_str"];
51
+ public readonly not_null: DomainProps["not_null"];
52
+ public readonly type_modifier: DomainProps["type_modifier"];
53
+ public readonly array_dimensions: DomainProps["array_dimensions"];
54
+ public readonly collation: DomainProps["collation"];
55
+ public readonly default_bin: DomainProps["default_bin"];
56
+ public readonly default_value: DomainProps["default_value"];
57
+ public readonly owner: DomainProps["owner"];
58
+ public readonly comment: DomainProps["comment"];
59
+ public readonly constraints: DomainConstraintProps[];
60
+ public readonly privileges: DomainPrivilegeProps[];
61
+
62
+ constructor(props: DomainProps) {
63
+ super();
64
+
65
+ // Identity fields
66
+ this.schema = props.schema;
67
+ this.name = props.name;
68
+
69
+ // Data fields
70
+ this.base_type = props.base_type;
71
+ this.base_type_schema = props.base_type_schema;
72
+ this.base_type_str = props.base_type_str;
73
+ this.not_null = props.not_null;
74
+ this.type_modifier = props.type_modifier;
75
+ this.array_dimensions = props.array_dimensions;
76
+ this.collation = props.collation;
77
+ this.default_bin = props.default_bin;
78
+ this.default_value = props.default_value;
79
+ this.owner = props.owner;
80
+ this.comment = props.comment;
81
+ this.constraints = props.constraints;
82
+ this.privileges = props.privileges;
83
+ }
84
+
85
+ get stableId(): `domain:${string}` {
86
+ return `domain:${this.schema}.${this.name}`;
87
+ }
88
+
89
+ get identityFields() {
90
+ return {
91
+ schema: this.schema,
92
+ name: this.name,
93
+ };
94
+ }
95
+
96
+ get dataFields() {
97
+ return {
98
+ base_type: this.base_type,
99
+ base_type_schema: this.base_type_schema,
100
+ not_null: this.not_null,
101
+ type_modifier: this.type_modifier,
102
+ array_dimensions: this.array_dimensions,
103
+ collation: this.collation,
104
+ default_bin: this.default_bin,
105
+ default_value: this.default_value,
106
+ owner: this.owner,
107
+ comment: this.comment,
108
+ constraints: this.constraints,
109
+ privileges: this.privileges,
110
+ };
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Extract all domains from the database.
116
+ *
117
+ * @param sql - The SQL client.
118
+ * @returns A list of domains.
119
+ */
120
+ export async function extractDomains(pool: Pool): Promise<Domain[]> {
121
+ const { rows: domainRows } = await pool.query<DomainProps>(sql`
122
+ with extension_oids as (
123
+ select
124
+ objid
125
+ from
126
+ pg_depend d
127
+ where
128
+ d.refclassid = 'pg_extension'::regclass
129
+ and d.classid = 'pg_type'::regclass
130
+ )
131
+ select
132
+ t.typnamespace::regnamespace::text as schema,
133
+ quote_ident(t.typname) as name,
134
+ bt.typname as base_type,
135
+ bt.typnamespace::regnamespace::text as base_type_schema,
136
+ format_type(t.typbasetype, t.typtypmod) as base_type_str,
137
+ t.typnotnull as not_null,
138
+ t.typtypmod as type_modifier,
139
+ t.typndims as array_dimensions,
140
+ case when t.typcollation <> bt.typcollation then quote_ident(c.collname) else null end as collation,
141
+ pg_get_expr(t.typdefaultbin, 0) as default_bin,
142
+ t.typdefault as default_value,
143
+ t.typowner::regrole::text as owner,
144
+ obj_description(t.oid, 'pg_type') as comment,
145
+ coalesce(
146
+ (
147
+ select json_agg(
148
+ json_build_object(
149
+ 'name', quote_ident(con.conname),
150
+ 'validated', con.convalidated,
151
+ 'is_local', con.conislocal,
152
+ 'no_inherit', con.connoinherit,
153
+ 'check_expression', pg_get_expr(con.conbin, 0)
154
+ )
155
+ order by con.conname
156
+ )
157
+ from pg_catalog.pg_constraint con
158
+ where con.contypid = t.oid
159
+ ), '[]'
160
+ ) as constraints,
161
+ coalesce(
162
+ (
163
+ select json_agg(
164
+ json_build_object(
165
+ 'grantee', case when x.grantee = 0 then 'PUBLIC' else x.grantee::regrole::text end,
166
+ 'privilege', x.privilege_type,
167
+ 'grantable', x.is_grantable
168
+ )
169
+ order by x.grantee, x.privilege_type
170
+ )
171
+ from lateral aclexplode(t.typacl) as x(grantor, grantee, privilege_type, is_grantable)
172
+ ), '[]'
173
+ ) as privileges
174
+ from
175
+ pg_catalog.pg_type t
176
+ inner join pg_catalog.pg_type bt on bt.oid = t.typbasetype
177
+ left join pg_catalog.pg_collation c on c.oid = t.typcollation
178
+ left outer join extension_oids e on t.oid = e.objid
179
+ where not t.typnamespace::regnamespace::text like any(array['pg\\_%', 'information\\_schema'])
180
+ and e.objid is null
181
+ and t.typtype = 'd'
182
+ order by
183
+ 1, 2
184
+ `);
185
+ // Validate and parse each row using the Zod schema
186
+ const validatedRows = domainRows.map((row: unknown) =>
187
+ domainPropsSchema.parse(row),
188
+ );
189
+ return validatedRows.map((row: DomainProps) => new Domain(row));
190
+ }
@@ -0,0 +1,50 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { EventTrigger } from "../event-trigger.model.ts";
3
+ import {
4
+ AlterEventTriggerChangeOwner,
5
+ AlterEventTriggerSetEnabled,
6
+ } from "./event-trigger.alter.ts";
7
+
8
+ describe("event trigger alter change", () => {
9
+ const baseEventTrigger = new EventTrigger({
10
+ name: "ddl_logger",
11
+ event: "ddl_command_start",
12
+ function_schema: "public",
13
+ function_name: "log_ddl",
14
+ enabled: "O",
15
+ tags: null,
16
+ owner: "postgres",
17
+ comment: null,
18
+ });
19
+
20
+ test("serialize owner change", () => {
21
+ const change = new AlterEventTriggerChangeOwner({
22
+ eventTrigger: baseEventTrigger,
23
+ owner: "new_owner",
24
+ });
25
+
26
+ expect(change.serialize()).toBe(
27
+ "ALTER EVENT TRIGGER ddl_logger OWNER TO new_owner",
28
+ );
29
+ });
30
+
31
+ test("serialize disable", () => {
32
+ const change = new AlterEventTriggerSetEnabled({
33
+ eventTrigger: baseEventTrigger,
34
+ enabled: "D",
35
+ });
36
+
37
+ expect(change.serialize()).toBe("ALTER EVENT TRIGGER ddl_logger DISABLE");
38
+ });
39
+
40
+ test("serialize enable always", () => {
41
+ const change = new AlterEventTriggerSetEnabled({
42
+ eventTrigger: baseEventTrigger,
43
+ enabled: "A",
44
+ });
45
+
46
+ expect(change.serialize()).toBe(
47
+ "ALTER EVENT TRIGGER ddl_logger ENABLE ALWAYS",
48
+ );
49
+ });
50
+ });
@@ -0,0 +1,82 @@
1
+ import type { EventTrigger } from "../event-trigger.model.ts";
2
+ import { AlterEventTriggerChange } from "./event-trigger.base.ts";
3
+
4
+ /**
5
+ * Alter an event trigger.
6
+ *
7
+ * @see https://www.postgresql.org/docs/17/sql-altereventtrigger.html
8
+ *
9
+ * Synopsis
10
+ * ```sql
11
+ * ALTER EVENT TRIGGER name DISABLE
12
+ * ALTER EVENT TRIGGER name ENABLE [ REPLICA | ALWAYS ]
13
+ * ALTER EVENT TRIGGER name OWNER TO { newowner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
14
+ * ALTER EVENT TRIGGER name RENAME TO newname
15
+ * ```
16
+ */
17
+
18
+ export type AlterEventTrigger =
19
+ | AlterEventTriggerChangeOwner
20
+ | AlterEventTriggerSetEnabled;
21
+
22
+ /**
23
+ * ALTER EVENT TRIGGER ... OWNER TO ...
24
+ */
25
+ export class AlterEventTriggerChangeOwner extends AlterEventTriggerChange {
26
+ public readonly eventTrigger: EventTrigger;
27
+ public readonly owner: string;
28
+ public readonly scope = "object" as const;
29
+
30
+ constructor(props: { eventTrigger: EventTrigger; owner: string }) {
31
+ super();
32
+ this.eventTrigger = props.eventTrigger;
33
+ this.owner = props.owner;
34
+ }
35
+
36
+ get requires() {
37
+ return [this.eventTrigger.stableId];
38
+ }
39
+
40
+ serialize(): string {
41
+ return [
42
+ "ALTER EVENT TRIGGER",
43
+ this.eventTrigger.name,
44
+ "OWNER TO",
45
+ this.owner,
46
+ ].join(" ");
47
+ }
48
+ }
49
+
50
+ const ENABLED_SQL = {
51
+ O: "ENABLE",
52
+ D: "DISABLE",
53
+ R: "ENABLE REPLICA",
54
+ A: "ENABLE ALWAYS",
55
+ } as const;
56
+
57
+ /**
58
+ * ALTER EVENT TRIGGER ... ENABLE/DISABLE ...
59
+ */
60
+ export class AlterEventTriggerSetEnabled extends AlterEventTriggerChange {
61
+ public readonly eventTrigger: EventTrigger;
62
+ public readonly enabled: EventTrigger["enabled"];
63
+ public readonly scope = "object" as const;
64
+
65
+ constructor(props: {
66
+ eventTrigger: EventTrigger;
67
+ enabled: EventTrigger["enabled"];
68
+ }) {
69
+ super();
70
+ this.eventTrigger = props.eventTrigger;
71
+ this.enabled = props.enabled;
72
+ }
73
+
74
+ get requires() {
75
+ return [this.eventTrigger.stableId];
76
+ }
77
+
78
+ serialize(): string {
79
+ const clause = ENABLED_SQL[this.enabled];
80
+ return ["ALTER EVENT TRIGGER", this.eventTrigger.name, clause].join(" ");
81
+ }
82
+ }
@@ -0,0 +1,20 @@
1
+ import { BaseChange } from "../../base.change.ts";
2
+ import type { EventTrigger } from "../event-trigger.model.ts";
3
+
4
+ abstract class BaseEventTriggerChange extends BaseChange {
5
+ abstract readonly eventTrigger: EventTrigger;
6
+ abstract readonly scope: "object" | "comment";
7
+ readonly objectType = "event_trigger" as const;
8
+ }
9
+
10
+ export abstract class CreateEventTriggerChange extends BaseEventTriggerChange {
11
+ readonly operation = "create" as const;
12
+ }
13
+
14
+ export abstract class AlterEventTriggerChange extends BaseEventTriggerChange {
15
+ readonly operation = "alter" as const;
16
+ }
17
+
18
+ export abstract class DropEventTriggerChange extends BaseEventTriggerChange {
19
+ readonly operation = "drop" as const;
20
+ }