@supabase/pg-delta 1.0.0-alpha.21 → 1.0.0-alpha.23

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 (271) hide show
  1. package/dist/core/catalog.diff.js +4 -3
  2. package/dist/core/catalog.model.d.ts +8 -1
  3. package/dist/core/catalog.model.js +10 -8
  4. package/dist/core/expand-replace-dependencies.js +23 -0
  5. package/dist/core/integrations/filter/flatten.js +13 -0
  6. package/dist/core/objects/aggregate/aggregate.diff.js +16 -0
  7. package/dist/core/objects/aggregate/aggregate.model.d.ts +10 -0
  8. package/dist/core/objects/aggregate/aggregate.model.js +19 -1
  9. package/dist/core/objects/aggregate/changes/aggregate.base.d.ts +1 -1
  10. package/dist/core/objects/aggregate/changes/aggregate.security-label.d.ts +28 -0
  11. package/dist/core/objects/aggregate/changes/aggregate.security-label.js +64 -0
  12. package/dist/core/objects/aggregate/changes/aggregate.types.d.ts +2 -1
  13. package/dist/core/objects/base.model.d.ts +8 -0
  14. package/dist/core/objects/base.model.js +2 -0
  15. package/dist/core/objects/domain/changes/domain.base.d.ts +1 -1
  16. package/dist/core/objects/domain/changes/domain.security-label.d.ts +28 -0
  17. package/dist/core/objects/domain/changes/domain.security-label.js +61 -0
  18. package/dist/core/objects/domain/changes/domain.types.d.ts +2 -1
  19. package/dist/core/objects/domain/domain.diff.js +16 -0
  20. package/dist/core/objects/domain/domain.model.d.ts +10 -0
  21. package/dist/core/objects/domain/domain.model.js +19 -1
  22. package/dist/core/objects/event-trigger/changes/event-trigger.base.d.ts +1 -1
  23. package/dist/core/objects/event-trigger/changes/event-trigger.security-label.d.ts +28 -0
  24. package/dist/core/objects/event-trigger/changes/event-trigger.security-label.js +61 -0
  25. package/dist/core/objects/event-trigger/changes/event-trigger.types.d.ts +2 -1
  26. package/dist/core/objects/event-trigger/event-trigger.diff.js +16 -0
  27. package/dist/core/objects/event-trigger/event-trigger.model.d.ts +10 -0
  28. package/dist/core/objects/event-trigger/event-trigger.model.js +19 -1
  29. package/dist/core/objects/extract-with-retry.d.ts +36 -0
  30. package/dist/core/objects/extract-with-retry.js +51 -0
  31. package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.d.ts +1 -1
  32. package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.d.ts +28 -0
  33. package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.js +61 -0
  34. package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.d.ts +2 -1
  35. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.js +16 -0
  36. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.d.ts +22 -0
  37. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.js +20 -1
  38. package/dist/core/objects/index/index.diff.js +0 -1
  39. package/dist/core/objects/index/index.model.d.ts +2 -3
  40. package/dist/core/objects/index/index.model.js +17 -6
  41. package/dist/core/objects/materialized-view/changes/materialized-view.base.d.ts +1 -1
  42. package/dist/core/objects/materialized-view/changes/materialized-view.security-label.d.ts +28 -0
  43. package/dist/core/objects/materialized-view/changes/materialized-view.security-label.js +61 -0
  44. package/dist/core/objects/materialized-view/changes/materialized-view.types.d.ts +2 -1
  45. package/dist/core/objects/materialized-view/materialized-view.diff.js +18 -0
  46. package/dist/core/objects/materialized-view/materialized-view.model.d.ts +24 -1
  47. package/dist/core/objects/materialized-view/materialized-view.model.js +40 -5
  48. package/dist/core/objects/procedure/changes/procedure.base.d.ts +1 -1
  49. package/dist/core/objects/procedure/changes/procedure.security-label.d.ts +28 -0
  50. package/dist/core/objects/procedure/changes/procedure.security-label.js +69 -0
  51. package/dist/core/objects/procedure/changes/procedure.types.d.ts +2 -1
  52. package/dist/core/objects/procedure/procedure.diff.js +16 -0
  53. package/dist/core/objects/procedure/procedure.model.d.ts +12 -1
  54. package/dist/core/objects/procedure/procedure.model.js +39 -5
  55. package/dist/core/objects/publication/changes/publication.base.d.ts +1 -1
  56. package/dist/core/objects/publication/changes/publication.security-label.d.ts +28 -0
  57. package/dist/core/objects/publication/changes/publication.security-label.js +61 -0
  58. package/dist/core/objects/publication/changes/publication.types.d.ts +2 -1
  59. package/dist/core/objects/publication/publication.diff.js +16 -0
  60. package/dist/core/objects/publication/publication.model.d.ts +14 -0
  61. package/dist/core/objects/publication/publication.model.js +20 -1
  62. package/dist/core/objects/rls-policy/rls-policy.diff.js +13 -1
  63. package/dist/core/objects/role/changes/role.base.d.ts +1 -1
  64. package/dist/core/objects/role/changes/role.security-label.d.ts +28 -0
  65. package/dist/core/objects/role/changes/role.security-label.js +61 -0
  66. package/dist/core/objects/role/changes/role.types.d.ts +2 -1
  67. package/dist/core/objects/role/role.diff.js +16 -0
  68. package/dist/core/objects/role/role.model.d.ts +10 -0
  69. package/dist/core/objects/role/role.model.js +29 -0
  70. package/dist/core/objects/rule/rule.model.d.ts +2 -1
  71. package/dist/core/objects/rule/rule.model.js +20 -3
  72. package/dist/core/objects/schema/changes/schema.base.d.ts +1 -1
  73. package/dist/core/objects/schema/changes/schema.security-label.d.ts +28 -0
  74. package/dist/core/objects/schema/changes/schema.security-label.js +61 -0
  75. package/dist/core/objects/schema/changes/schema.types.d.ts +2 -1
  76. package/dist/core/objects/schema/schema.diff.js +24 -1
  77. package/dist/core/objects/schema/schema.model.d.ts +10 -0
  78. package/dist/core/objects/schema/schema.model.js +18 -1
  79. package/dist/core/objects/security-label.types.d.ts +20 -0
  80. package/dist/core/objects/security-label.types.js +46 -0
  81. package/dist/core/objects/sequence/changes/sequence.base.d.ts +1 -1
  82. package/dist/core/objects/sequence/changes/sequence.security-label.d.ts +28 -0
  83. package/dist/core/objects/sequence/changes/sequence.security-label.js +61 -0
  84. package/dist/core/objects/sequence/changes/sequence.types.d.ts +2 -1
  85. package/dist/core/objects/sequence/sequence.diff.d.ts +2 -1
  86. package/dist/core/objects/sequence/sequence.diff.js +44 -4
  87. package/dist/core/objects/sequence/sequence.model.d.ts +10 -0
  88. package/dist/core/objects/sequence/sequence.model.js +19 -1
  89. package/dist/core/objects/subscription/changes/subscription.base.d.ts +1 -1
  90. package/dist/core/objects/subscription/changes/subscription.security-label.d.ts +28 -0
  91. package/dist/core/objects/subscription/changes/subscription.security-label.js +61 -0
  92. package/dist/core/objects/subscription/changes/subscription.types.d.ts +2 -1
  93. package/dist/core/objects/subscription/subscription.diff.js +16 -0
  94. package/dist/core/objects/subscription/subscription.model.d.ts +10 -0
  95. package/dist/core/objects/subscription/subscription.model.js +19 -1
  96. package/dist/core/objects/table/changes/table.alter.d.ts +12 -1
  97. package/dist/core/objects/table/changes/table.alter.js +20 -2
  98. package/dist/core/objects/table/changes/table.base.d.ts +1 -1
  99. package/dist/core/objects/table/changes/table.security-label.d.ts +63 -0
  100. package/dist/core/objects/table/changes/table.security-label.js +134 -0
  101. package/dist/core/objects/table/changes/table.types.d.ts +2 -1
  102. package/dist/core/objects/table/table.diff.js +68 -15
  103. package/dist/core/objects/table/table.model.d.ts +36 -1
  104. package/dist/core/objects/table/table.model.js +74 -7
  105. package/dist/core/objects/trigger/trigger.model.d.ts +2 -1
  106. package/dist/core/objects/trigger/trigger.model.js +20 -4
  107. package/dist/core/objects/type/composite-type/changes/composite-type.base.d.ts +1 -1
  108. package/dist/core/objects/type/composite-type/changes/composite-type.security-label.d.ts +28 -0
  109. package/dist/core/objects/type/composite-type/changes/composite-type.security-label.js +61 -0
  110. package/dist/core/objects/type/composite-type/changes/composite-type.types.d.ts +2 -1
  111. package/dist/core/objects/type/composite-type/composite-type.diff.js +16 -0
  112. package/dist/core/objects/type/composite-type/composite-type.model.d.ts +22 -0
  113. package/dist/core/objects/type/composite-type/composite-type.model.js +22 -2
  114. package/dist/core/objects/type/enum/changes/enum.base.d.ts +1 -1
  115. package/dist/core/objects/type/enum/changes/enum.security-label.d.ts +28 -0
  116. package/dist/core/objects/type/enum/changes/enum.security-label.js +61 -0
  117. package/dist/core/objects/type/enum/changes/enum.types.d.ts +2 -1
  118. package/dist/core/objects/type/enum/enum.diff.js +16 -0
  119. package/dist/core/objects/type/enum/enum.model.d.ts +10 -0
  120. package/dist/core/objects/type/enum/enum.model.js +20 -1
  121. package/dist/core/objects/type/range/changes/range.base.d.ts +1 -1
  122. package/dist/core/objects/type/range/changes/range.security-label.d.ts +28 -0
  123. package/dist/core/objects/type/range/changes/range.security-label.js +61 -0
  124. package/dist/core/objects/type/range/changes/range.types.d.ts +2 -1
  125. package/dist/core/objects/type/range/range.diff.js +16 -0
  126. package/dist/core/objects/type/range/range.model.d.ts +10 -0
  127. package/dist/core/objects/type/range/range.model.js +19 -1
  128. package/dist/core/objects/utils.d.ts +2 -0
  129. package/dist/core/objects/utils.js +6 -0
  130. package/dist/core/objects/view/changes/view.base.d.ts +1 -1
  131. package/dist/core/objects/view/changes/view.security-label.d.ts +28 -0
  132. package/dist/core/objects/view/changes/view.security-label.js +61 -0
  133. package/dist/core/objects/view/changes/view.types.d.ts +2 -1
  134. package/dist/core/objects/view/view.diff.js +13 -0
  135. package/dist/core/objects/view/view.model.d.ts +28 -1
  136. package/dist/core/objects/view/view.model.js +40 -5
  137. package/dist/core/plan/create.js +3 -1
  138. package/dist/core/plan/sql-format/fixtures.js +1 -0
  139. package/dist/core/plan/types.d.ts +8 -0
  140. package/dist/core/{post-diff-cycle-breaking.d.ts → post-diff-normalization.d.ts} +8 -1
  141. package/dist/core/post-diff-normalization.js +202 -0
  142. package/dist/core/sort/cycle-breakers.js +1 -1
  143. package/dist/core/sort/utils.d.ts +10 -0
  144. package/dist/core/sort/utils.js +28 -0
  145. package/package.json +1 -1
  146. package/src/core/catalog.diff.ts +4 -2
  147. package/src/core/catalog.model.ts +21 -8
  148. package/src/core/expand-replace-dependencies.test.ts +131 -0
  149. package/src/core/expand-replace-dependencies.ts +24 -0
  150. package/src/core/integrations/filter/dsl.test.ts +27 -0
  151. package/src/core/integrations/filter/flatten.ts +16 -0
  152. package/src/core/objects/aggregate/aggregate.diff.ts +33 -0
  153. package/src/core/objects/aggregate/aggregate.model.ts +22 -1
  154. package/src/core/objects/aggregate/changes/aggregate.base.ts +5 -1
  155. package/src/core/objects/aggregate/changes/aggregate.security-label.ts +99 -0
  156. package/src/core/objects/aggregate/changes/aggregate.types.ts +3 -1
  157. package/src/core/objects/base.model.ts +2 -0
  158. package/src/core/objects/domain/changes/domain.base.ts +5 -1
  159. package/src/core/objects/domain/changes/domain.security-label.test.ts +56 -0
  160. package/src/core/objects/domain/changes/domain.security-label.ts +77 -0
  161. package/src/core/objects/domain/changes/domain.types.ts +3 -1
  162. package/src/core/objects/domain/domain.diff.ts +33 -0
  163. package/src/core/objects/domain/domain.model.ts +22 -1
  164. package/src/core/objects/event-trigger/changes/event-trigger.base.ts +1 -1
  165. package/src/core/objects/event-trigger/changes/event-trigger.security-label.ts +95 -0
  166. package/src/core/objects/event-trigger/changes/event-trigger.types.ts +3 -1
  167. package/src/core/objects/event-trigger/event-trigger.diff.ts +33 -0
  168. package/src/core/objects/event-trigger/event-trigger.model.ts +22 -1
  169. package/src/core/objects/extract-with-retry.test.ts +143 -0
  170. package/src/core/objects/extract-with-retry.ts +87 -0
  171. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.ts +5 -1
  172. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.ts +95 -0
  173. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.ts +3 -1
  174. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +33 -0
  175. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +24 -1
  176. package/src/core/objects/index/index.diff.ts +0 -1
  177. package/src/core/objects/index/index.model.test.ts +37 -1
  178. package/src/core/objects/index/index.model.ts +25 -6
  179. package/src/core/objects/materialized-view/changes/materialized-view.base.ts +5 -1
  180. package/src/core/objects/materialized-view/changes/materialized-view.security-label.test.ts +63 -0
  181. package/src/core/objects/materialized-view/changes/materialized-view.security-label.ts +95 -0
  182. package/src/core/objects/materialized-view/changes/materialized-view.types.ts +3 -1
  183. package/src/core/objects/materialized-view/materialized-view.diff.ts +37 -0
  184. package/src/core/objects/materialized-view/materialized-view.model.test.ts +93 -0
  185. package/src/core/objects/materialized-view/materialized-view.model.ts +52 -8
  186. package/src/core/objects/procedure/changes/procedure.base.ts +5 -1
  187. package/src/core/objects/procedure/changes/procedure.security-label.ts +105 -0
  188. package/src/core/objects/procedure/changes/procedure.types.ts +3 -1
  189. package/src/core/objects/procedure/procedure.diff.ts +33 -0
  190. package/src/core/objects/procedure/procedure.model.test.ts +117 -0
  191. package/src/core/objects/procedure/procedure.model.ts +51 -7
  192. package/src/core/objects/publication/changes/publication.base.ts +1 -1
  193. package/src/core/objects/publication/changes/publication.security-label.ts +95 -0
  194. package/src/core/objects/publication/changes/publication.types.ts +3 -1
  195. package/src/core/objects/publication/publication.diff.ts +33 -0
  196. package/src/core/objects/publication/publication.model.ts +24 -1
  197. package/src/core/objects/rls-policy/rls-policy.diff.ts +19 -1
  198. package/src/core/objects/role/changes/role.base.ts +2 -1
  199. package/src/core/objects/role/changes/role.security-label.ts +77 -0
  200. package/src/core/objects/role/changes/role.types.ts +3 -1
  201. package/src/core/objects/role/role.diff.ts +33 -0
  202. package/src/core/objects/role/role.model.ts +32 -0
  203. package/src/core/objects/rule/rule.model.test.ts +99 -0
  204. package/src/core/objects/rule/rule.model.ts +28 -4
  205. package/src/core/objects/schema/changes/schema.alter.test.ts +1 -0
  206. package/src/core/objects/schema/changes/schema.base.ts +5 -1
  207. package/src/core/objects/schema/changes/schema.create.test.ts +1 -0
  208. package/src/core/objects/schema/changes/schema.drop.test.ts +1 -0
  209. package/src/core/objects/schema/changes/schema.security-label.test.ts +76 -0
  210. package/src/core/objects/schema/changes/schema.security-label.ts +77 -0
  211. package/src/core/objects/schema/changes/schema.types.ts +3 -1
  212. package/src/core/objects/schema/schema.diff.test.ts +1 -0
  213. package/src/core/objects/schema/schema.diff.ts +43 -1
  214. package/src/core/objects/schema/schema.model.ts +21 -1
  215. package/src/core/objects/security-label.types.test.ts +106 -0
  216. package/src/core/objects/security-label.types.ts +61 -0
  217. package/src/core/objects/sequence/changes/sequence.base.ts +5 -1
  218. package/src/core/objects/sequence/changes/sequence.security-label.test.ts +58 -0
  219. package/src/core/objects/sequence/changes/sequence.security-label.ts +92 -0
  220. package/src/core/objects/sequence/changes/sequence.types.ts +3 -1
  221. package/src/core/objects/sequence/sequence.diff.test.ts +87 -0
  222. package/src/core/objects/sequence/sequence.diff.ts +64 -6
  223. package/src/core/objects/sequence/sequence.model.ts +22 -1
  224. package/src/core/objects/subscription/changes/subscription.base.ts +1 -1
  225. package/src/core/objects/subscription/changes/subscription.security-label.ts +95 -0
  226. package/src/core/objects/subscription/changes/subscription.types.ts +3 -1
  227. package/src/core/objects/subscription/subscription.diff.ts +33 -0
  228. package/src/core/objects/subscription/subscription.model.ts +22 -1
  229. package/src/core/objects/table/changes/table.alter.test.ts +13 -21
  230. package/src/core/objects/table/changes/table.alter.ts +30 -3
  231. package/src/core/objects/table/changes/table.base.ts +5 -1
  232. package/src/core/objects/table/changes/table.security-label.test.ts +140 -0
  233. package/src/core/objects/table/changes/table.security-label.ts +183 -0
  234. package/src/core/objects/table/changes/table.types.ts +3 -1
  235. package/src/core/objects/table/table.diff.ts +111 -19
  236. package/src/core/objects/table/table.model.test.ts +209 -0
  237. package/src/core/objects/table/table.model.ts +94 -9
  238. package/src/core/objects/trigger/trigger.model.test.ts +113 -0
  239. package/src/core/objects/trigger/trigger.model.ts +28 -5
  240. package/src/core/objects/type/composite-type/changes/composite-type.base.ts +5 -1
  241. package/src/core/objects/type/composite-type/changes/composite-type.security-label.ts +95 -0
  242. package/src/core/objects/type/composite-type/changes/composite-type.types.ts +3 -1
  243. package/src/core/objects/type/composite-type/composite-type.diff.ts +33 -0
  244. package/src/core/objects/type/composite-type/composite-type.model.ts +26 -2
  245. package/src/core/objects/type/enum/changes/enum.base.ts +5 -1
  246. package/src/core/objects/type/enum/changes/enum.security-label.ts +77 -0
  247. package/src/core/objects/type/enum/changes/enum.types.ts +3 -1
  248. package/src/core/objects/type/enum/enum.diff.ts +33 -0
  249. package/src/core/objects/type/enum/enum.model.ts +25 -1
  250. package/src/core/objects/type/range/changes/range.base.ts +5 -1
  251. package/src/core/objects/type/range/changes/range.security-label.ts +77 -0
  252. package/src/core/objects/type/range/changes/range.types.ts +3 -1
  253. package/src/core/objects/type/range/range.diff.ts +33 -0
  254. package/src/core/objects/type/range/range.model.ts +22 -1
  255. package/src/core/objects/utils.ts +6 -0
  256. package/src/core/objects/view/changes/view.base.ts +5 -1
  257. package/src/core/objects/view/changes/view.security-label.test.ts +64 -0
  258. package/src/core/objects/view/changes/view.security-label.ts +77 -0
  259. package/src/core/objects/view/changes/view.types.ts +3 -1
  260. package/src/core/objects/view/view.diff.ts +31 -0
  261. package/src/core/objects/view/view.model.test.ts +90 -0
  262. package/src/core/objects/view/view.model.ts +53 -7
  263. package/src/core/plan/create.ts +3 -1
  264. package/src/core/plan/sql-format/fixtures.ts +1 -0
  265. package/src/core/plan/types.ts +8 -0
  266. package/src/core/{post-diff-cycle-breaking.test.ts → post-diff-normalization.test.ts} +168 -4
  267. package/src/core/post-diff-normalization.ts +260 -0
  268. package/src/core/sort/cycle-breakers.ts +1 -1
  269. package/src/core/sort/utils.ts +38 -0
  270. package/dist/core/post-diff-cycle-breaking.js +0 -100
  271. package/src/core/post-diff-cycle-breaking.ts +0 -138
@@ -6,6 +6,10 @@ import {
6
6
  type PrivilegeProps,
7
7
  privilegePropsSchema,
8
8
  } from "../base.privilege-diff.ts";
9
+ import {
10
+ type SecurityLabelProps,
11
+ securityLabelPropsSchema,
12
+ } from "../security-label.types.ts";
9
13
 
10
14
  const AggregateKindSchema = z.enum([
11
15
  "n", // normal aggregate
@@ -75,6 +79,7 @@ const aggregatePropsSchema = z.object({
75
79
  owner: z.string(),
76
80
  comment: z.string().nullable(),
77
81
  privileges: z.array(privilegePropsSchema),
82
+ security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
78
83
  });
79
84
 
80
85
  type AggregatePrivilegeProps = PrivilegeProps;
@@ -122,6 +127,7 @@ export class Aggregate extends BasePgModel {
122
127
  public readonly owner: AggregateProps["owner"];
123
128
  public readonly comment: AggregateProps["comment"];
124
129
  public readonly privileges: AggregatePrivilegeProps[];
130
+ public readonly security_labels: SecurityLabelProps[];
125
131
 
126
132
  constructor(props: AggregateProps) {
127
133
  super();
@@ -168,6 +174,7 @@ export class Aggregate extends BasePgModel {
168
174
  this.owner = props.owner;
169
175
  this.comment = props.comment;
170
176
  this.privileges = props.privileges;
177
+ this.security_labels = props.security_labels ?? [];
171
178
  }
172
179
 
173
180
  get stableId(): `aggregate:${string}` {
@@ -224,6 +231,7 @@ export class Aggregate extends BasePgModel {
224
231
  owner: this.owner,
225
232
  comment: this.comment,
226
233
  privileges: this.privileges,
234
+ security_labels: this.security_labels,
227
235
  };
228
236
  }
229
237
  }
@@ -294,7 +302,20 @@ select
294
302
  )
295
303
  from lateral aclexplode(COALESCE(p.proacl, acldefault('f', p.proowner))) as x(grantor, grantee, privilege_type, is_grantable)
296
304
  ), '[]'
297
- ) as privileges
305
+ ) as privileges,
306
+ coalesce(
307
+ (
308
+ select json_agg(
309
+ json_build_object('provider', sl.provider, 'label', sl.label)
310
+ order by sl.provider
311
+ )
312
+ from pg_catalog.pg_seclabel sl
313
+ where sl.objoid = p.oid
314
+ and sl.classoid = 'pg_proc'::regclass
315
+ and sl.objsubid = 0
316
+ ),
317
+ '[]'::json
318
+ ) as security_labels
298
319
  from
299
320
  pg_catalog.pg_proc p
300
321
  inner join pg_catalog.pg_aggregate a on a.aggfnoid = p.oid
@@ -3,7 +3,11 @@ import type { Aggregate } from "../aggregate.model.ts";
3
3
 
4
4
  abstract class BaseAggregateChange extends BaseChange {
5
5
  abstract readonly aggregate: Aggregate;
6
- abstract readonly scope: "object" | "comment" | "privilege";
6
+ abstract readonly scope:
7
+ | "object"
8
+ | "comment"
9
+ | "privilege"
10
+ | "security_label";
7
11
  readonly objectType: "aggregate" = "aggregate";
8
12
  }
9
13
 
@@ -0,0 +1,99 @@
1
+ import { quoteLiteral } from "../../base.change.ts";
2
+ import type { SecurityLabelProps } from "../../security-label.types.ts";
3
+ import { stableId } from "../../utils.ts";
4
+ import type { Aggregate } from "../aggregate.model.ts";
5
+ import {
6
+ CreateAggregateChange,
7
+ DropAggregateChange,
8
+ } from "./aggregate.base.ts";
9
+
10
+ export type SecurityLabelAggregate =
11
+ | CreateSecurityLabelOnAggregate
12
+ | DropSecurityLabelOnAggregate;
13
+
14
+ function aggregateIdentity(a: Aggregate): string {
15
+ return `${a.schema}.${a.name}(${a.identityArguments})`;
16
+ }
17
+
18
+ export class CreateSecurityLabelOnAggregate extends CreateAggregateChange {
19
+ public readonly aggregate: Aggregate;
20
+ public readonly securityLabel: SecurityLabelProps;
21
+ public readonly scope = "security_label" as const;
22
+
23
+ constructor(props: {
24
+ aggregate: Aggregate;
25
+ securityLabel: SecurityLabelProps;
26
+ }) {
27
+ super();
28
+ this.aggregate = props.aggregate;
29
+ this.securityLabel = props.securityLabel;
30
+ }
31
+
32
+ get creates() {
33
+ return [
34
+ stableId.securityLabel(
35
+ this.aggregate.stableId,
36
+ this.securityLabel.provider,
37
+ ),
38
+ ];
39
+ }
40
+
41
+ get requires() {
42
+ return [this.aggregate.stableId];
43
+ }
44
+
45
+ serialize(): string {
46
+ return [
47
+ "SECURITY LABEL FOR",
48
+ this.securityLabel.provider,
49
+ "ON AGGREGATE",
50
+ aggregateIdentity(this.aggregate),
51
+ "IS",
52
+ quoteLiteral(this.securityLabel.label),
53
+ ].join(" ");
54
+ }
55
+ }
56
+
57
+ export class DropSecurityLabelOnAggregate extends DropAggregateChange {
58
+ public readonly aggregate: Aggregate;
59
+ public readonly securityLabel: SecurityLabelProps;
60
+ public readonly scope = "security_label" as const;
61
+
62
+ constructor(props: {
63
+ aggregate: Aggregate;
64
+ securityLabel: SecurityLabelProps;
65
+ }) {
66
+ super();
67
+ this.aggregate = props.aggregate;
68
+ this.securityLabel = props.securityLabel;
69
+ }
70
+
71
+ get drops() {
72
+ return [
73
+ stableId.securityLabel(
74
+ this.aggregate.stableId,
75
+ this.securityLabel.provider,
76
+ ),
77
+ ];
78
+ }
79
+
80
+ get requires() {
81
+ return [
82
+ stableId.securityLabel(
83
+ this.aggregate.stableId,
84
+ this.securityLabel.provider,
85
+ ),
86
+ this.aggregate.stableId,
87
+ ];
88
+ }
89
+
90
+ serialize(): string {
91
+ return [
92
+ "SECURITY LABEL FOR",
93
+ this.securityLabel.provider,
94
+ "ON AGGREGATE",
95
+ aggregateIdentity(this.aggregate),
96
+ "IS NULL",
97
+ ].join(" ");
98
+ }
99
+ }
@@ -3,6 +3,7 @@ import type { CommentAggregate } from "./aggregate.comment.ts";
3
3
  import type { CreateAggregate } from "./aggregate.create.ts";
4
4
  import type { DropAggregate } from "./aggregate.drop.ts";
5
5
  import type { AggregatePrivilege } from "./aggregate.privilege.ts";
6
+ import type { SecurityLabelAggregate } from "./aggregate.security-label.ts";
6
7
 
7
8
  /** Union of all aggregate-related change variants (`objectType: "aggregate"`). @category Change Types */
8
9
  export type AggregateChange =
@@ -10,4 +11,5 @@ export type AggregateChange =
10
11
  | CommentAggregate
11
12
  | CreateAggregate
12
13
  | DropAggregate
13
- | AggregatePrivilege;
14
+ | AggregatePrivilege
15
+ | SecurityLabelAggregate;
@@ -1,4 +1,5 @@
1
1
  import z from "zod";
2
+ import { securityLabelPropsSchema } from "./security-label.types.ts";
2
3
  import { deepEqual } from "./utils.ts";
3
4
 
4
5
  export const columnPropsSchema = z.object({
@@ -18,6 +19,7 @@ export const columnPropsSchema = z.object({
18
19
  collation: z.string().nullable(),
19
20
  default: z.string().nullable(),
20
21
  comment: z.string().nullable(),
22
+ security_labels: z.array(securityLabelPropsSchema).optional(),
21
23
  });
22
24
 
23
25
  export type ColumnProps = z.infer<typeof columnPropsSchema>;
@@ -3,7 +3,11 @@ import type { Domain } from "../domain.model.ts";
3
3
 
4
4
  abstract class BaseDomainChange extends BaseChange {
5
5
  abstract readonly domain: Domain;
6
- abstract readonly scope: "object" | "comment" | "privilege";
6
+ abstract readonly scope:
7
+ | "object"
8
+ | "comment"
9
+ | "privilege"
10
+ | "security_label";
7
11
  readonly objectType: "domain" = "domain";
8
12
  }
9
13
 
@@ -0,0 +1,56 @@
1
+ import { describe, expect, test } from "bun:test";
2
+ import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
3
+ import { stableId } from "../../utils.ts";
4
+ import { Domain, type DomainProps } from "../domain.model.ts";
5
+ import {
6
+ CreateSecurityLabelOnDomain,
7
+ DropSecurityLabelOnDomain,
8
+ } from "./domain.security-label.ts";
9
+
10
+ const makeDomain = (): Domain =>
11
+ new Domain({
12
+ schema: "public",
13
+ name: "email_t",
14
+ base_type: "text",
15
+ base_type_schema: "pg_catalog",
16
+ not_null: false,
17
+ type_modifier: -1,
18
+ array_dimensions: 0,
19
+ collation: null,
20
+ default_bin: null,
21
+ default_value: null,
22
+ owner: "postgres",
23
+ comment: null,
24
+ constraints: [],
25
+ privileges: [],
26
+ } as DomainProps);
27
+
28
+ describe("domain.security-label", () => {
29
+ test("create serializes", async () => {
30
+ const domain = makeDomain();
31
+ const change = new CreateSecurityLabelOnDomain({
32
+ domain,
33
+ securityLabel: { provider: "dummy", label: "classified" },
34
+ });
35
+ expect(change.scope).toBe("security_label");
36
+ expect(change.creates).toEqual([
37
+ stableId.securityLabel(domain.stableId, "dummy"),
38
+ ]);
39
+ await assertValidSql(change.serialize());
40
+ expect(change.serialize()).toBe(
41
+ "SECURITY LABEL FOR dummy ON DOMAIN public.email_t IS 'classified'",
42
+ );
43
+ });
44
+
45
+ test("drop serializes to IS NULL", async () => {
46
+ const domain = makeDomain();
47
+ const change = new DropSecurityLabelOnDomain({
48
+ domain,
49
+ securityLabel: { provider: "dummy", label: "x" },
50
+ });
51
+ await assertValidSql(change.serialize());
52
+ expect(change.serialize()).toBe(
53
+ "SECURITY LABEL FOR dummy ON DOMAIN public.email_t IS NULL",
54
+ );
55
+ });
56
+ });
@@ -0,0 +1,77 @@
1
+ import { quoteLiteral } from "../../base.change.ts";
2
+ import type { SecurityLabelProps } from "../../security-label.types.ts";
3
+ import { stableId } from "../../utils.ts";
4
+ import type { Domain } from "../domain.model.ts";
5
+ import { CreateDomainChange, DropDomainChange } from "./domain.base.ts";
6
+
7
+ export type SecurityLabelDomain =
8
+ | CreateSecurityLabelOnDomain
9
+ | DropSecurityLabelOnDomain;
10
+
11
+ export class CreateSecurityLabelOnDomain extends CreateDomainChange {
12
+ public readonly domain: Domain;
13
+ public readonly securityLabel: SecurityLabelProps;
14
+ public readonly scope = "security_label" as const;
15
+
16
+ constructor(props: { domain: Domain; securityLabel: SecurityLabelProps }) {
17
+ super();
18
+ this.domain = props.domain;
19
+ this.securityLabel = props.securityLabel;
20
+ }
21
+
22
+ get creates() {
23
+ return [
24
+ stableId.securityLabel(this.domain.stableId, this.securityLabel.provider),
25
+ ];
26
+ }
27
+
28
+ get requires() {
29
+ return [this.domain.stableId];
30
+ }
31
+
32
+ serialize(): string {
33
+ return [
34
+ "SECURITY LABEL FOR",
35
+ this.securityLabel.provider,
36
+ "ON DOMAIN",
37
+ `${this.domain.schema}.${this.domain.name}`,
38
+ "IS",
39
+ quoteLiteral(this.securityLabel.label),
40
+ ].join(" ");
41
+ }
42
+ }
43
+
44
+ export class DropSecurityLabelOnDomain extends DropDomainChange {
45
+ public readonly domain: Domain;
46
+ public readonly securityLabel: SecurityLabelProps;
47
+ public readonly scope = "security_label" as const;
48
+
49
+ constructor(props: { domain: Domain; securityLabel: SecurityLabelProps }) {
50
+ super();
51
+ this.domain = props.domain;
52
+ this.securityLabel = props.securityLabel;
53
+ }
54
+
55
+ get drops() {
56
+ return [
57
+ stableId.securityLabel(this.domain.stableId, this.securityLabel.provider),
58
+ ];
59
+ }
60
+
61
+ get requires() {
62
+ return [
63
+ stableId.securityLabel(this.domain.stableId, this.securityLabel.provider),
64
+ this.domain.stableId,
65
+ ];
66
+ }
67
+
68
+ serialize(): string {
69
+ return [
70
+ "SECURITY LABEL FOR",
71
+ this.securityLabel.provider,
72
+ "ON DOMAIN",
73
+ `${this.domain.schema}.${this.domain.name}`,
74
+ "IS NULL",
75
+ ].join(" ");
76
+ }
77
+ }
@@ -3,6 +3,7 @@ import type { CommentDomain } from "./domain.comment.ts";
3
3
  import type { CreateDomain } from "./domain.create.ts";
4
4
  import type { DropDomain } from "./domain.drop.ts";
5
5
  import type { DomainPrivilege } from "./domain.privilege.ts";
6
+ import type { SecurityLabelDomain } from "./domain.security-label.ts";
6
7
 
7
8
  /** Union of all domain-related change variants (`objectType: "domain"`). @category Change Types */
8
9
  export type DomainChange =
@@ -10,4 +11,5 @@ export type DomainChange =
10
11
  | CommentDomain
11
12
  | CreateDomain
12
13
  | DropDomain
13
- | DomainPrivilege;
14
+ | DomainPrivilege
15
+ | SecurityLabelDomain;
@@ -5,6 +5,7 @@ import {
5
5
  filterPublicBuiltInDefaults,
6
6
  } from "../base.privilege-diff.ts";
7
7
  import type { ObjectDiffContext } from "../diff-context.ts";
8
+ import { diffSecurityLabels } from "../security-label.types.ts";
8
9
  import {
9
10
  AlterDomainAddConstraint,
10
11
  AlterDomainChangeOwner,
@@ -26,6 +27,10 @@ import {
26
27
  RevokeDomainPrivileges,
27
28
  RevokeGrantOptionDomainPrivileges,
28
29
  } from "./changes/domain.privilege.ts";
30
+ import {
31
+ CreateSecurityLabelOnDomain,
32
+ DropSecurityLabelOnDomain,
33
+ } from "./changes/domain.security-label.ts";
29
34
  import type { DomainChange } from "./changes/domain.types.ts";
30
35
  import type { Domain } from "./domain.model.ts";
31
36
 
@@ -67,6 +72,14 @@ export function diffDomains(
67
72
  if (newDomain.comment !== null) {
68
73
  changes.push(new CreateCommentOnDomain({ domain: newDomain }));
69
74
  }
75
+ for (const label of newDomain.security_labels) {
76
+ changes.push(
77
+ new CreateSecurityLabelOnDomain({
78
+ domain: newDomain,
79
+ securityLabel: label,
80
+ }),
81
+ );
82
+ }
70
83
  // For unvalidated constraints, CREATE DOMAIN cannot specify NOT VALID.
71
84
  // Add them after creation and validate to match branch state semantics.
72
85
  // For already validated constraints, they are emitted inline in CREATE DOMAIN.
@@ -255,6 +268,26 @@ export function diffDomains(
255
268
  }
256
269
  }
257
270
 
271
+ // SECURITY LABELS
272
+ changes.push(
273
+ ...diffSecurityLabels<
274
+ CreateSecurityLabelOnDomain | DropSecurityLabelOnDomain
275
+ >(
276
+ mainDomain.security_labels,
277
+ branchDomain.security_labels,
278
+ (securityLabel) =>
279
+ new CreateSecurityLabelOnDomain({
280
+ domain: branchDomain,
281
+ securityLabel,
282
+ }),
283
+ (securityLabel) =>
284
+ new DropSecurityLabelOnDomain({
285
+ domain: mainDomain,
286
+ securityLabel,
287
+ }),
288
+ ),
289
+ );
290
+
258
291
  // PRIVILEGES
259
292
  // Filter out PUBLIC's built-in default USAGE privilege from main catalog
260
293
  // (PostgreSQL grants it automatically, so we shouldn't compare it)
@@ -6,6 +6,10 @@ import {
6
6
  type PrivilegeProps,
7
7
  privilegePropsSchema,
8
8
  } from "../base.privilege-diff.ts";
9
+ import {
10
+ type SecurityLabelProps,
11
+ securityLabelPropsSchema,
12
+ } from "../security-label.types.ts";
9
13
 
10
14
  const domainConstraintPropsSchema = z.object({
11
15
  name: z.string(),
@@ -31,6 +35,7 @@ const domainPropsSchema = z.object({
31
35
  comment: z.string().nullable(),
32
36
  constraints: z.array(domainConstraintPropsSchema),
33
37
  privileges: z.array(privilegePropsSchema),
38
+ security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
34
39
  });
35
40
 
36
41
  export type DomainConstraintProps = z.infer<typeof domainConstraintPropsSchema>;
@@ -58,6 +63,7 @@ export class Domain extends BasePgModel {
58
63
  public readonly comment: DomainProps["comment"];
59
64
  public readonly constraints: DomainConstraintProps[];
60
65
  public readonly privileges: DomainPrivilegeProps[];
66
+ public readonly security_labels: SecurityLabelProps[];
61
67
 
62
68
  constructor(props: DomainProps) {
63
69
  super();
@@ -80,6 +86,7 @@ export class Domain extends BasePgModel {
80
86
  this.comment = props.comment;
81
87
  this.constraints = props.constraints;
82
88
  this.privileges = props.privileges;
89
+ this.security_labels = props.security_labels ?? [];
83
90
  }
84
91
 
85
92
  get stableId(): `domain:${string}` {
@@ -107,6 +114,7 @@ export class Domain extends BasePgModel {
107
114
  comment: this.comment,
108
115
  constraints: this.constraints,
109
116
  privileges: this.privileges,
117
+ security_labels: this.security_labels,
110
118
  };
111
119
  }
112
120
  }
@@ -170,7 +178,20 @@ export async function extractDomains(pool: Pool): Promise<Domain[]> {
170
178
  )
171
179
  from lateral aclexplode(COALESCE(t.typacl, acldefault('T', t.typowner))) as x(grantor, grantee, privilege_type, is_grantable)
172
180
  ), '[]'
173
- ) as privileges
181
+ ) as privileges,
182
+ coalesce(
183
+ (
184
+ select json_agg(
185
+ json_build_object('provider', sl.provider, 'label', sl.label)
186
+ order by sl.provider
187
+ )
188
+ from pg_catalog.pg_seclabel sl
189
+ where sl.objoid = t.oid
190
+ and sl.classoid = 'pg_type'::regclass
191
+ and sl.objsubid = 0
192
+ ),
193
+ '[]'::json
194
+ ) as security_labels
174
195
  from
175
196
  pg_catalog.pg_type t
176
197
  inner join pg_catalog.pg_type bt on bt.oid = t.typbasetype
@@ -3,7 +3,7 @@ import type { EventTrigger } from "../event-trigger.model.ts";
3
3
 
4
4
  abstract class BaseEventTriggerChange extends BaseChange {
5
5
  abstract readonly eventTrigger: EventTrigger;
6
- abstract readonly scope: "object" | "comment";
6
+ abstract readonly scope: "object" | "comment" | "security_label";
7
7
  readonly objectType = "event_trigger" as const;
8
8
  }
9
9
 
@@ -0,0 +1,95 @@
1
+ import { quoteLiteral } from "../../base.change.ts";
2
+ import type { SecurityLabelProps } from "../../security-label.types.ts";
3
+ import { stableId } from "../../utils.ts";
4
+ import type { EventTrigger } from "../event-trigger.model.ts";
5
+ import {
6
+ CreateEventTriggerChange,
7
+ DropEventTriggerChange,
8
+ } from "./event-trigger.base.ts";
9
+
10
+ export type SecurityLabelEventTrigger =
11
+ | CreateSecurityLabelOnEventTrigger
12
+ | DropSecurityLabelOnEventTrigger;
13
+
14
+ export class CreateSecurityLabelOnEventTrigger extends CreateEventTriggerChange {
15
+ public readonly eventTrigger: EventTrigger;
16
+ public readonly securityLabel: SecurityLabelProps;
17
+ public readonly scope = "security_label" as const;
18
+
19
+ constructor(props: {
20
+ eventTrigger: EventTrigger;
21
+ securityLabel: SecurityLabelProps;
22
+ }) {
23
+ super();
24
+ this.eventTrigger = props.eventTrigger;
25
+ this.securityLabel = props.securityLabel;
26
+ }
27
+
28
+ get creates() {
29
+ return [
30
+ stableId.securityLabel(
31
+ this.eventTrigger.stableId,
32
+ this.securityLabel.provider,
33
+ ),
34
+ ];
35
+ }
36
+
37
+ get requires() {
38
+ return [this.eventTrigger.stableId];
39
+ }
40
+
41
+ serialize(): string {
42
+ return [
43
+ "SECURITY LABEL FOR",
44
+ this.securityLabel.provider,
45
+ "ON EVENT TRIGGER",
46
+ this.eventTrigger.name,
47
+ "IS",
48
+ quoteLiteral(this.securityLabel.label),
49
+ ].join(" ");
50
+ }
51
+ }
52
+
53
+ export class DropSecurityLabelOnEventTrigger extends DropEventTriggerChange {
54
+ public readonly eventTrigger: EventTrigger;
55
+ public readonly securityLabel: SecurityLabelProps;
56
+ public readonly scope = "security_label" as const;
57
+
58
+ constructor(props: {
59
+ eventTrigger: EventTrigger;
60
+ securityLabel: SecurityLabelProps;
61
+ }) {
62
+ super();
63
+ this.eventTrigger = props.eventTrigger;
64
+ this.securityLabel = props.securityLabel;
65
+ }
66
+
67
+ get drops() {
68
+ return [
69
+ stableId.securityLabel(
70
+ this.eventTrigger.stableId,
71
+ this.securityLabel.provider,
72
+ ),
73
+ ];
74
+ }
75
+
76
+ get requires() {
77
+ return [
78
+ stableId.securityLabel(
79
+ this.eventTrigger.stableId,
80
+ this.securityLabel.provider,
81
+ ),
82
+ this.eventTrigger.stableId,
83
+ ];
84
+ }
85
+
86
+ serialize(): string {
87
+ return [
88
+ "SECURITY LABEL FOR",
89
+ this.securityLabel.provider,
90
+ "ON EVENT TRIGGER",
91
+ this.eventTrigger.name,
92
+ "IS NULL",
93
+ ].join(" ");
94
+ }
95
+ }
@@ -2,10 +2,12 @@ import type { AlterEventTrigger } from "./event-trigger.alter.ts";
2
2
  import type { CommentEventTrigger } from "./event-trigger.comment.ts";
3
3
  import type { CreateEventTrigger } from "./event-trigger.create.ts";
4
4
  import type { DropEventTrigger } from "./event-trigger.drop.ts";
5
+ import type { SecurityLabelEventTrigger } from "./event-trigger.security-label.ts";
5
6
 
6
7
  /** Union of all event-trigger-related change variants (`objectType: "event_trigger"`). @category Change Types */
7
8
  export type EventTriggerChange =
8
9
  | AlterEventTrigger
9
10
  | CommentEventTrigger
10
11
  | CreateEventTrigger
11
- | DropEventTrigger;
12
+ | DropEventTrigger
13
+ | SecurityLabelEventTrigger;
@@ -1,5 +1,6 @@
1
1
  import { diffObjects } from "../base.diff.ts";
2
2
  import type { ObjectDiffContext } from "../diff-context.ts";
3
+ import { diffSecurityLabels } from "../security-label.types.ts";
3
4
  import { deepEqual, hasNonAlterableChanges } from "../utils.ts";
4
5
  import {
5
6
  AlterEventTriggerChangeOwner,
@@ -11,6 +12,10 @@ import {
11
12
  } from "./changes/event-trigger.comment.ts";
12
13
  import { CreateEventTrigger } from "./changes/event-trigger.create.ts";
13
14
  import { DropEventTrigger } from "./changes/event-trigger.drop.ts";
15
+ import {
16
+ CreateSecurityLabelOnEventTrigger,
17
+ DropSecurityLabelOnEventTrigger,
18
+ } from "./changes/event-trigger.security-label.ts";
14
19
  import type { EventTriggerChange } from "./changes/event-trigger.types.ts";
15
20
  import type { EventTrigger } from "./event-trigger.model.ts";
16
21
 
@@ -49,6 +54,14 @@ export function diffEventTriggers(
49
54
  if (eventTrigger.comment !== null) {
50
55
  changes.push(new CreateCommentOnEventTrigger({ eventTrigger }));
51
56
  }
57
+ for (const label of eventTrigger.security_labels) {
58
+ changes.push(
59
+ new CreateSecurityLabelOnEventTrigger({
60
+ eventTrigger,
61
+ securityLabel: label,
62
+ }),
63
+ );
64
+ }
52
65
  }
53
66
 
54
67
  for (const eventTriggerId of dropped) {
@@ -121,6 +134,26 @@ export function diffEventTriggers(
121
134
  );
122
135
  }
123
136
  }
137
+
138
+ // SECURITY LABELS
139
+ changes.push(
140
+ ...diffSecurityLabels<
141
+ CreateSecurityLabelOnEventTrigger | DropSecurityLabelOnEventTrigger
142
+ >(
143
+ mainEventTrigger.security_labels,
144
+ branchEventTrigger.security_labels,
145
+ (securityLabel) =>
146
+ new CreateSecurityLabelOnEventTrigger({
147
+ eventTrigger: branchEventTrigger,
148
+ securityLabel,
149
+ }),
150
+ (securityLabel) =>
151
+ new DropSecurityLabelOnEventTrigger({
152
+ eventTrigger: mainEventTrigger,
153
+ securityLabel,
154
+ }),
155
+ ),
156
+ );
124
157
  }
125
158
 
126
159
  return changes;