@supabase/pg-delta 1.0.0-alpha.22 → 1.0.0-alpha.24

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 (228) hide show
  1. package/dist/core/catalog.model.js +1 -0
  2. package/dist/core/integrations/filter/flatten.js +13 -0
  3. package/dist/core/objects/aggregate/aggregate.diff.js +16 -0
  4. package/dist/core/objects/aggregate/aggregate.model.d.ts +10 -0
  5. package/dist/core/objects/aggregate/aggregate.model.js +19 -1
  6. package/dist/core/objects/aggregate/changes/aggregate.base.d.ts +1 -1
  7. package/dist/core/objects/aggregate/changes/aggregate.security-label.d.ts +28 -0
  8. package/dist/core/objects/aggregate/changes/aggregate.security-label.js +64 -0
  9. package/dist/core/objects/aggregate/changes/aggregate.types.d.ts +2 -1
  10. package/dist/core/objects/base.model.d.ts +8 -0
  11. package/dist/core/objects/base.model.js +2 -0
  12. package/dist/core/objects/domain/changes/domain.base.d.ts +1 -1
  13. package/dist/core/objects/domain/changes/domain.security-label.d.ts +28 -0
  14. package/dist/core/objects/domain/changes/domain.security-label.js +61 -0
  15. package/dist/core/objects/domain/changes/domain.types.d.ts +2 -1
  16. package/dist/core/objects/domain/domain.diff.js +16 -0
  17. package/dist/core/objects/domain/domain.model.d.ts +10 -0
  18. package/dist/core/objects/domain/domain.model.js +19 -1
  19. package/dist/core/objects/event-trigger/changes/event-trigger.base.d.ts +1 -1
  20. package/dist/core/objects/event-trigger/changes/event-trigger.security-label.d.ts +28 -0
  21. package/dist/core/objects/event-trigger/changes/event-trigger.security-label.js +61 -0
  22. package/dist/core/objects/event-trigger/changes/event-trigger.types.d.ts +2 -1
  23. package/dist/core/objects/event-trigger/event-trigger.diff.js +16 -0
  24. package/dist/core/objects/event-trigger/event-trigger.model.d.ts +10 -0
  25. package/dist/core/objects/event-trigger/event-trigger.model.js +19 -1
  26. package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.d.ts +1 -1
  27. package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.d.ts +28 -0
  28. package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.js +61 -0
  29. package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.d.ts +2 -1
  30. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.js +16 -0
  31. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.d.ts +22 -0
  32. package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.js +20 -1
  33. package/dist/core/objects/materialized-view/changes/materialized-view.base.d.ts +1 -1
  34. package/dist/core/objects/materialized-view/changes/materialized-view.security-label.d.ts +28 -0
  35. package/dist/core/objects/materialized-view/changes/materialized-view.security-label.js +61 -0
  36. package/dist/core/objects/materialized-view/changes/materialized-view.types.d.ts +2 -1
  37. package/dist/core/objects/materialized-view/materialized-view.diff.js +18 -0
  38. package/dist/core/objects/materialized-view/materialized-view.model.d.ts +22 -0
  39. package/dist/core/objects/materialized-view/materialized-view.model.js +20 -1
  40. package/dist/core/objects/procedure/changes/procedure.base.d.ts +1 -1
  41. package/dist/core/objects/procedure/changes/procedure.security-label.d.ts +28 -0
  42. package/dist/core/objects/procedure/changes/procedure.security-label.js +69 -0
  43. package/dist/core/objects/procedure/changes/procedure.types.d.ts +2 -1
  44. package/dist/core/objects/procedure/procedure.diff.js +16 -0
  45. package/dist/core/objects/procedure/procedure.model.d.ts +10 -0
  46. package/dist/core/objects/procedure/procedure.model.js +19 -1
  47. package/dist/core/objects/publication/changes/publication.base.d.ts +1 -1
  48. package/dist/core/objects/publication/changes/publication.security-label.d.ts +28 -0
  49. package/dist/core/objects/publication/changes/publication.security-label.js +61 -0
  50. package/dist/core/objects/publication/changes/publication.types.d.ts +2 -1
  51. package/dist/core/objects/publication/publication.diff.js +16 -0
  52. package/dist/core/objects/publication/publication.model.d.ts +14 -0
  53. package/dist/core/objects/publication/publication.model.js +20 -1
  54. package/dist/core/objects/role/changes/role.base.d.ts +1 -1
  55. package/dist/core/objects/role/changes/role.security-label.d.ts +28 -0
  56. package/dist/core/objects/role/changes/role.security-label.js +61 -0
  57. package/dist/core/objects/role/changes/role.types.d.ts +2 -1
  58. package/dist/core/objects/role/role.diff.js +16 -0
  59. package/dist/core/objects/role/role.model.d.ts +10 -0
  60. package/dist/core/objects/role/role.model.js +29 -0
  61. package/dist/core/objects/schema/changes/schema.base.d.ts +1 -1
  62. package/dist/core/objects/schema/changes/schema.security-label.d.ts +28 -0
  63. package/dist/core/objects/schema/changes/schema.security-label.js +61 -0
  64. package/dist/core/objects/schema/changes/schema.types.d.ts +2 -1
  65. package/dist/core/objects/schema/schema.diff.js +24 -1
  66. package/dist/core/objects/schema/schema.model.d.ts +10 -0
  67. package/dist/core/objects/schema/schema.model.js +18 -1
  68. package/dist/core/objects/security-label.types.d.ts +20 -0
  69. package/dist/core/objects/security-label.types.js +46 -0
  70. package/dist/core/objects/sequence/changes/sequence.base.d.ts +1 -1
  71. package/dist/core/objects/sequence/changes/sequence.security-label.d.ts +28 -0
  72. package/dist/core/objects/sequence/changes/sequence.security-label.js +61 -0
  73. package/dist/core/objects/sequence/changes/sequence.types.d.ts +2 -1
  74. package/dist/core/objects/sequence/sequence.diff.js +16 -0
  75. package/dist/core/objects/sequence/sequence.model.d.ts +10 -0
  76. package/dist/core/objects/sequence/sequence.model.js +19 -1
  77. package/dist/core/objects/subscription/changes/subscription.base.d.ts +1 -1
  78. package/dist/core/objects/subscription/changes/subscription.security-label.d.ts +28 -0
  79. package/dist/core/objects/subscription/changes/subscription.security-label.js +61 -0
  80. package/dist/core/objects/subscription/changes/subscription.types.d.ts +2 -1
  81. package/dist/core/objects/subscription/subscription.diff.js +16 -0
  82. package/dist/core/objects/subscription/subscription.model.d.ts +10 -0
  83. package/dist/core/objects/subscription/subscription.model.js +19 -1
  84. package/dist/core/objects/table/changes/table.base.d.ts +1 -1
  85. package/dist/core/objects/table/changes/table.security-label.d.ts +63 -0
  86. package/dist/core/objects/table/changes/table.security-label.js +134 -0
  87. package/dist/core/objects/table/changes/table.types.d.ts +2 -1
  88. package/dist/core/objects/table/table.diff.js +49 -0
  89. package/dist/core/objects/table/table.model.d.ts +30 -0
  90. package/dist/core/objects/table/table.model.js +34 -2
  91. package/dist/core/objects/type/composite-type/changes/composite-type.base.d.ts +1 -1
  92. package/dist/core/objects/type/composite-type/changes/composite-type.security-label.d.ts +28 -0
  93. package/dist/core/objects/type/composite-type/changes/composite-type.security-label.js +61 -0
  94. package/dist/core/objects/type/composite-type/changes/composite-type.types.d.ts +2 -1
  95. package/dist/core/objects/type/composite-type/composite-type.diff.js +16 -0
  96. package/dist/core/objects/type/composite-type/composite-type.model.d.ts +22 -0
  97. package/dist/core/objects/type/composite-type/composite-type.model.js +22 -2
  98. package/dist/core/objects/type/enum/changes/enum.base.d.ts +1 -1
  99. package/dist/core/objects/type/enum/changes/enum.security-label.d.ts +28 -0
  100. package/dist/core/objects/type/enum/changes/enum.security-label.js +61 -0
  101. package/dist/core/objects/type/enum/changes/enum.types.d.ts +2 -1
  102. package/dist/core/objects/type/enum/enum.diff.js +16 -0
  103. package/dist/core/objects/type/enum/enum.model.d.ts +10 -0
  104. package/dist/core/objects/type/enum/enum.model.js +20 -1
  105. package/dist/core/objects/type/range/changes/range.base.d.ts +1 -1
  106. package/dist/core/objects/type/range/changes/range.security-label.d.ts +28 -0
  107. package/dist/core/objects/type/range/changes/range.security-label.js +61 -0
  108. package/dist/core/objects/type/range/changes/range.types.d.ts +2 -1
  109. package/dist/core/objects/type/range/range.diff.js +16 -0
  110. package/dist/core/objects/type/range/range.model.d.ts +10 -0
  111. package/dist/core/objects/type/range/range.model.js +19 -1
  112. package/dist/core/objects/utils.d.ts +1 -0
  113. package/dist/core/objects/utils.js +3 -0
  114. package/dist/core/objects/view/changes/view.base.d.ts +1 -1
  115. package/dist/core/objects/view/changes/view.security-label.d.ts +28 -0
  116. package/dist/core/objects/view/changes/view.security-label.js +61 -0
  117. package/dist/core/objects/view/changes/view.types.d.ts +2 -1
  118. package/dist/core/objects/view/view.diff.js +13 -0
  119. package/dist/core/objects/view/view.model.d.ts +26 -0
  120. package/dist/core/objects/view/view.model.js +20 -1
  121. package/dist/core/plan/sql-format/fixtures.js +1 -0
  122. package/dist/core/post-diff-normalization.d.ts +7 -0
  123. package/dist/core/post-diff-normalization.js +33 -4
  124. package/dist/core/sort/cycle-breakers.js +139 -17
  125. package/package.json +1 -1
  126. package/src/core/catalog.model.ts +1 -0
  127. package/src/core/integrations/filter/dsl.test.ts +27 -0
  128. package/src/core/integrations/filter/flatten.ts +16 -0
  129. package/src/core/objects/aggregate/aggregate.diff.ts +33 -0
  130. package/src/core/objects/aggregate/aggregate.model.ts +22 -1
  131. package/src/core/objects/aggregate/changes/aggregate.base.ts +5 -1
  132. package/src/core/objects/aggregate/changes/aggregate.security-label.ts +99 -0
  133. package/src/core/objects/aggregate/changes/aggregate.types.ts +3 -1
  134. package/src/core/objects/base.model.ts +2 -0
  135. package/src/core/objects/domain/changes/domain.base.ts +5 -1
  136. package/src/core/objects/domain/changes/domain.security-label.test.ts +56 -0
  137. package/src/core/objects/domain/changes/domain.security-label.ts +77 -0
  138. package/src/core/objects/domain/changes/domain.types.ts +3 -1
  139. package/src/core/objects/domain/domain.diff.ts +33 -0
  140. package/src/core/objects/domain/domain.model.ts +22 -1
  141. package/src/core/objects/event-trigger/changes/event-trigger.base.ts +1 -1
  142. package/src/core/objects/event-trigger/changes/event-trigger.security-label.ts +95 -0
  143. package/src/core/objects/event-trigger/changes/event-trigger.types.ts +3 -1
  144. package/src/core/objects/event-trigger/event-trigger.diff.ts +33 -0
  145. package/src/core/objects/event-trigger/event-trigger.model.ts +22 -1
  146. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.ts +5 -1
  147. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.ts +95 -0
  148. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.ts +3 -1
  149. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +33 -0
  150. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +24 -1
  151. package/src/core/objects/materialized-view/changes/materialized-view.base.ts +5 -1
  152. package/src/core/objects/materialized-view/changes/materialized-view.security-label.test.ts +63 -0
  153. package/src/core/objects/materialized-view/changes/materialized-view.security-label.ts +95 -0
  154. package/src/core/objects/materialized-view/changes/materialized-view.types.ts +3 -1
  155. package/src/core/objects/materialized-view/materialized-view.diff.ts +37 -0
  156. package/src/core/objects/materialized-view/materialized-view.model.ts +25 -4
  157. package/src/core/objects/procedure/changes/procedure.base.ts +5 -1
  158. package/src/core/objects/procedure/changes/procedure.security-label.ts +105 -0
  159. package/src/core/objects/procedure/changes/procedure.types.ts +3 -1
  160. package/src/core/objects/procedure/procedure.diff.ts +33 -0
  161. package/src/core/objects/procedure/procedure.model.ts +23 -2
  162. package/src/core/objects/publication/changes/publication.base.ts +1 -1
  163. package/src/core/objects/publication/changes/publication.security-label.ts +95 -0
  164. package/src/core/objects/publication/changes/publication.types.ts +3 -1
  165. package/src/core/objects/publication/publication.diff.ts +33 -0
  166. package/src/core/objects/publication/publication.model.ts +24 -1
  167. package/src/core/objects/role/changes/role.base.ts +2 -1
  168. package/src/core/objects/role/changes/role.security-label.ts +77 -0
  169. package/src/core/objects/role/changes/role.types.ts +3 -1
  170. package/src/core/objects/role/role.diff.ts +33 -0
  171. package/src/core/objects/role/role.model.ts +32 -0
  172. package/src/core/objects/schema/changes/schema.alter.test.ts +1 -0
  173. package/src/core/objects/schema/changes/schema.base.ts +5 -1
  174. package/src/core/objects/schema/changes/schema.create.test.ts +1 -0
  175. package/src/core/objects/schema/changes/schema.drop.test.ts +1 -0
  176. package/src/core/objects/schema/changes/schema.security-label.test.ts +76 -0
  177. package/src/core/objects/schema/changes/schema.security-label.ts +77 -0
  178. package/src/core/objects/schema/changes/schema.types.ts +3 -1
  179. package/src/core/objects/schema/schema.diff.test.ts +1 -0
  180. package/src/core/objects/schema/schema.diff.ts +43 -1
  181. package/src/core/objects/schema/schema.model.ts +21 -1
  182. package/src/core/objects/security-label.types.test.ts +106 -0
  183. package/src/core/objects/security-label.types.ts +61 -0
  184. package/src/core/objects/sequence/changes/sequence.base.ts +5 -1
  185. package/src/core/objects/sequence/changes/sequence.security-label.test.ts +58 -0
  186. package/src/core/objects/sequence/changes/sequence.security-label.ts +92 -0
  187. package/src/core/objects/sequence/changes/sequence.types.ts +3 -1
  188. package/src/core/objects/sequence/sequence.diff.ts +33 -0
  189. package/src/core/objects/sequence/sequence.model.ts +22 -1
  190. package/src/core/objects/subscription/changes/subscription.base.ts +1 -1
  191. package/src/core/objects/subscription/changes/subscription.security-label.ts +95 -0
  192. package/src/core/objects/subscription/changes/subscription.types.ts +3 -1
  193. package/src/core/objects/subscription/subscription.diff.ts +33 -0
  194. package/src/core/objects/subscription/subscription.model.ts +22 -1
  195. package/src/core/objects/table/changes/table.base.ts +5 -1
  196. package/src/core/objects/table/changes/table.security-label.test.ts +140 -0
  197. package/src/core/objects/table/changes/table.security-label.ts +183 -0
  198. package/src/core/objects/table/changes/table.types.ts +3 -1
  199. package/src/core/objects/table/table.diff.ts +87 -0
  200. package/src/core/objects/table/table.model.ts +42 -2
  201. package/src/core/objects/type/composite-type/changes/composite-type.base.ts +5 -1
  202. package/src/core/objects/type/composite-type/changes/composite-type.security-label.ts +95 -0
  203. package/src/core/objects/type/composite-type/changes/composite-type.types.ts +3 -1
  204. package/src/core/objects/type/composite-type/composite-type.diff.ts +33 -0
  205. package/src/core/objects/type/composite-type/composite-type.model.ts +26 -2
  206. package/src/core/objects/type/enum/changes/enum.base.ts +5 -1
  207. package/src/core/objects/type/enum/changes/enum.security-label.ts +77 -0
  208. package/src/core/objects/type/enum/changes/enum.types.ts +3 -1
  209. package/src/core/objects/type/enum/enum.diff.ts +33 -0
  210. package/src/core/objects/type/enum/enum.model.ts +25 -1
  211. package/src/core/objects/type/range/changes/range.base.ts +5 -1
  212. package/src/core/objects/type/range/changes/range.security-label.ts +77 -0
  213. package/src/core/objects/type/range/changes/range.types.ts +3 -1
  214. package/src/core/objects/type/range/range.diff.ts +33 -0
  215. package/src/core/objects/type/range/range.model.ts +22 -1
  216. package/src/core/objects/utils.ts +3 -0
  217. package/src/core/objects/view/changes/view.base.ts +5 -1
  218. package/src/core/objects/view/changes/view.security-label.test.ts +64 -0
  219. package/src/core/objects/view/changes/view.security-label.ts +77 -0
  220. package/src/core/objects/view/changes/view.types.ts +3 -1
  221. package/src/core/objects/view/view.diff.ts +31 -0
  222. package/src/core/objects/view/view.model.ts +25 -2
  223. package/src/core/plan/sql-format/fixtures.ts +1 -0
  224. package/src/core/post-diff-normalization.test.ts +123 -0
  225. package/src/core/post-diff-normalization.ts +40 -4
  226. package/src/core/sort/cycle-breakers.test.ts +236 -2
  227. package/src/core/sort/cycle-breakers.ts +184 -24
  228. package/src/core/sort/sort-changes.test.ts +317 -0
@@ -4,6 +4,7 @@ import {
4
4
  emitColumnPrivilegeChanges,
5
5
  } from "../base.privilege-diff.ts";
6
6
  import type { ObjectDiffContext } from "../diff-context.ts";
7
+ import { diffSecurityLabels } from "../security-label.types.ts";
7
8
  import { deepEqual } from "../utils.ts";
8
9
  import {
9
10
  AlterTableAddColumn,
@@ -47,6 +48,12 @@ import {
47
48
  RevokeGrantOptionTablePrivileges,
48
49
  RevokeTablePrivileges,
49
50
  } from "./changes/table.privilege.ts";
51
+ import {
52
+ CreateSecurityLabelOnColumn,
53
+ CreateSecurityLabelOnTable,
54
+ DropSecurityLabelOnColumn,
55
+ DropSecurityLabelOnTable,
56
+ } from "./changes/table.security-label.ts";
50
57
  import type { TableChange } from "./changes/table.types.ts";
51
58
  import { Table } from "./table.model.ts";
52
59
 
@@ -279,6 +286,29 @@ export function diffTables(
279
286
  }
280
287
  }
281
288
 
289
+ // Table security labels on creation
290
+ for (const label of branchTable.security_labels) {
291
+ changes.push(
292
+ new CreateSecurityLabelOnTable({
293
+ table: branchTable,
294
+ securityLabel: label,
295
+ }),
296
+ );
297
+ }
298
+
299
+ // Column security labels on creation
300
+ for (const col of branchTable.columns) {
301
+ for (const label of col.security_labels ?? []) {
302
+ changes.push(
303
+ new CreateSecurityLabelOnColumn({
304
+ table: branchTable,
305
+ column: col,
306
+ securityLabel: label,
307
+ }),
308
+ );
309
+ }
310
+ }
311
+
282
312
  // PRIVILEGES: For created objects, compare against default privileges state
283
313
  // The migration script will run ALTER DEFAULT PRIVILEGES before CREATE (via constraint spec),
284
314
  // so objects are created with the default privileges state in effect.
@@ -440,6 +470,26 @@ export function diffTables(
440
470
  }
441
471
  }
442
472
 
473
+ // TABLE SECURITY LABELS
474
+ changes.push(
475
+ ...diffSecurityLabels<
476
+ CreateSecurityLabelOnTable | DropSecurityLabelOnTable
477
+ >(
478
+ mainTable.security_labels,
479
+ branchTable.security_labels,
480
+ (securityLabel) =>
481
+ new CreateSecurityLabelOnTable({
482
+ table: branchTable,
483
+ securityLabel,
484
+ }),
485
+ (securityLabel) =>
486
+ new DropSecurityLabelOnTable({
487
+ table: mainTable,
488
+ securityLabel,
489
+ }),
490
+ ),
491
+ );
492
+
443
493
  // PARTITION ATTACH/DETACH
444
494
  const mainIsPartition = Boolean(
445
495
  mainTable.parent_schema && mainTable.parent_name,
@@ -886,6 +936,43 @@ export function diffTables(
886
936
  );
887
937
  }
888
938
  }
939
+
940
+ // SECURITY LABELS on column
941
+ changes.push(
942
+ ...diffSecurityLabels<
943
+ CreateSecurityLabelOnColumn | DropSecurityLabelOnColumn
944
+ >(
945
+ mainCol.security_labels ?? [],
946
+ branchCol.security_labels ?? [],
947
+ (securityLabel) =>
948
+ new CreateSecurityLabelOnColumn({
949
+ table: branchTable,
950
+ column: branchCol,
951
+ securityLabel,
952
+ }),
953
+ (securityLabel) =>
954
+ new DropSecurityLabelOnColumn({
955
+ table: mainTable,
956
+ column: mainCol,
957
+ securityLabel,
958
+ }),
959
+ ),
960
+ );
961
+ }
962
+
963
+ // Added columns with security labels (for created columns on existing tables)
964
+ for (const [name, col] of branchCols) {
965
+ if (!mainCols.has(name)) {
966
+ for (const label of col.security_labels ?? []) {
967
+ changes.push(
968
+ new CreateSecurityLabelOnColumn({
969
+ table: branchTable,
970
+ column: col,
971
+ securityLabel: label,
972
+ }),
973
+ );
974
+ }
975
+ }
889
976
  }
890
977
 
891
978
  // PRIVILEGES (unified object and column privileges)
@@ -16,6 +16,11 @@ import {
16
16
  type ExtractRetryOptions,
17
17
  extractWithDefinitionRetry,
18
18
  } from "../extract-with-retry.ts";
19
+ import {
20
+ normalizeSecurityLabels,
21
+ type SecurityLabelProps,
22
+ securityLabelPropsSchema,
23
+ } from "../security-label.types.ts";
19
24
 
20
25
  const RelationPersistenceSchema = z.enum([
21
26
  "p", // permanent
@@ -119,6 +124,7 @@ const tablePropsSchema = z.object({
119
124
  columns: z.array(columnPropsSchema),
120
125
  constraints: z.array(tableConstraintPropsSchema).optional(),
121
126
  privileges: z.array(privilegePropsSchema),
127
+ security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
122
128
  });
123
129
 
124
130
  const tableRowSchema = tablePropsSchema.extend({
@@ -126,6 +132,10 @@ const tableRowSchema = tablePropsSchema.extend({
126
132
  });
127
133
 
128
134
  type TablePrivilegeProps = PrivilegeProps;
135
+ /**
136
+ * Table input props. `security_labels` is optional on direct construction
137
+ * (defaults to `[]`); extraction always produces it via the Zod default.
138
+ */
129
139
  export type TableProps = z.infer<typeof tablePropsSchema>;
130
140
  type TableRow = z.infer<typeof tableRowSchema>;
131
141
 
@@ -153,6 +163,7 @@ export class Table extends BasePgModel implements TableLikeObject {
153
163
  public readonly columns: TableProps["columns"];
154
164
  public readonly constraints: TableConstraintProps[];
155
165
  public readonly privileges: TablePrivilegeProps[];
166
+ public readonly security_labels: SecurityLabelProps[];
156
167
 
157
168
  constructor(props: TableProps) {
158
169
  super();
@@ -183,6 +194,7 @@ export class Table extends BasePgModel implements TableLikeObject {
183
194
  this.columns = props.columns;
184
195
  this.constraints = props.constraints ?? [];
185
196
  this.privileges = props.privileges;
197
+ this.security_labels = props.security_labels ?? [];
186
198
  }
187
199
 
188
200
  get stableId(): `table:${string}` {
@@ -214,6 +226,7 @@ export class Table extends BasePgModel implements TableLikeObject {
214
226
  columns: this.columns,
215
227
  constraints: this.constraints,
216
228
  privileges: this.privileges,
229
+ security_labels: this.security_labels,
217
230
  };
218
231
  }
219
232
 
@@ -233,6 +246,7 @@ export class Table extends BasePgModel implements TableLikeObject {
233
246
  options: this.options ? [...this.options].sort() : this.options,
234
247
  constraints: normalizeConstraints(),
235
248
  privileges: normalizePrivileges(this.privileges),
249
+ security_labels: normalizeSecurityLabels(this.security_labels),
236
250
  },
237
251
  };
238
252
  }
@@ -446,7 +460,20 @@ select
446
460
  and a.attcollation <> t2.typcollation
447
461
  ),
448
462
  'default', pg_get_expr(ad.adbin, ad.adrelid),
449
- 'comment', col_description(a.attrelid, a.attnum)
463
+ 'comment', col_description(a.attrelid, a.attnum),
464
+ 'security_labels', coalesce(
465
+ (
466
+ select json_agg(
467
+ json_build_object('provider', sl.provider, 'label', sl.label)
468
+ order by sl.provider
469
+ )
470
+ from pg_catalog.pg_seclabel sl
471
+ where sl.objoid = t.oid
472
+ and sl.classoid = 'pg_class'::regclass
473
+ and sl.objsubid = a.attnum
474
+ ),
475
+ '[]'::json
476
+ )
450
477
  )
451
478
  end
452
479
  order by a.attnum
@@ -486,7 +513,20 @@ select
486
513
  join lateral aclexplode(src.acl) as x(grantor, grantee, privilege_type, is_grantable) on true
487
514
  group by x.grantee, x.privilege_type
488
515
  ) as grp
489
- ), '[]') as privileges
516
+ ), '[]') as privileges,
517
+ coalesce(
518
+ (
519
+ select json_agg(
520
+ json_build_object('provider', sl.provider, 'label', sl.label)
521
+ order by sl.provider
522
+ )
523
+ from pg_catalog.pg_seclabel sl
524
+ where sl.objoid = t.oid
525
+ and sl.classoid = 'pg_class'::regclass
526
+ and sl.objsubid = 0
527
+ ),
528
+ '[]'::json
529
+ ) as security_labels
490
530
  from
491
531
  tables t
492
532
  left join pg_attribute a on a.attrelid = t.oid and a.attnum > 0 and not a.attisdropped
@@ -3,7 +3,11 @@ import type { CompositeType } from "../composite-type.model.ts";
3
3
 
4
4
  abstract class BaseCompositeTypeChange extends BaseChange {
5
5
  abstract readonly compositeType: CompositeType;
6
- abstract readonly scope: "object" | "comment" | "privilege";
6
+ abstract readonly scope:
7
+ | "object"
8
+ | "comment"
9
+ | "privilege"
10
+ | "security_label";
7
11
  readonly objectType: "composite_type" = "composite_type";
8
12
  }
9
13
 
@@ -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 { CompositeType } from "../composite-type.model.ts";
5
+ import {
6
+ CreateCompositeTypeChange,
7
+ DropCompositeTypeChange,
8
+ } from "./composite-type.base.ts";
9
+
10
+ export type SecurityLabelCompositeType =
11
+ | CreateSecurityLabelOnCompositeType
12
+ | DropSecurityLabelOnCompositeType;
13
+
14
+ export class CreateSecurityLabelOnCompositeType extends CreateCompositeTypeChange {
15
+ public readonly compositeType: CompositeType;
16
+ public readonly securityLabel: SecurityLabelProps;
17
+ public readonly scope = "security_label" as const;
18
+
19
+ constructor(props: {
20
+ compositeType: CompositeType;
21
+ securityLabel: SecurityLabelProps;
22
+ }) {
23
+ super();
24
+ this.compositeType = props.compositeType;
25
+ this.securityLabel = props.securityLabel;
26
+ }
27
+
28
+ get creates() {
29
+ return [
30
+ stableId.securityLabel(
31
+ this.compositeType.stableId,
32
+ this.securityLabel.provider,
33
+ ),
34
+ ];
35
+ }
36
+
37
+ get requires() {
38
+ return [this.compositeType.stableId];
39
+ }
40
+
41
+ serialize(): string {
42
+ return [
43
+ "SECURITY LABEL FOR",
44
+ this.securityLabel.provider,
45
+ "ON TYPE",
46
+ `${this.compositeType.schema}.${this.compositeType.name}`,
47
+ "IS",
48
+ quoteLiteral(this.securityLabel.label),
49
+ ].join(" ");
50
+ }
51
+ }
52
+
53
+ export class DropSecurityLabelOnCompositeType extends DropCompositeTypeChange {
54
+ public readonly compositeType: CompositeType;
55
+ public readonly securityLabel: SecurityLabelProps;
56
+ public readonly scope = "security_label" as const;
57
+
58
+ constructor(props: {
59
+ compositeType: CompositeType;
60
+ securityLabel: SecurityLabelProps;
61
+ }) {
62
+ super();
63
+ this.compositeType = props.compositeType;
64
+ this.securityLabel = props.securityLabel;
65
+ }
66
+
67
+ get drops() {
68
+ return [
69
+ stableId.securityLabel(
70
+ this.compositeType.stableId,
71
+ this.securityLabel.provider,
72
+ ),
73
+ ];
74
+ }
75
+
76
+ get requires() {
77
+ return [
78
+ stableId.securityLabel(
79
+ this.compositeType.stableId,
80
+ this.securityLabel.provider,
81
+ ),
82
+ this.compositeType.stableId,
83
+ ];
84
+ }
85
+
86
+ serialize(): string {
87
+ return [
88
+ "SECURITY LABEL FOR",
89
+ this.securityLabel.provider,
90
+ "ON TYPE",
91
+ `${this.compositeType.schema}.${this.compositeType.name}`,
92
+ "IS NULL",
93
+ ].join(" ");
94
+ }
95
+ }
@@ -3,6 +3,7 @@ import type { CommentCompositeType } from "./composite-type.comment.ts";
3
3
  import type { CreateCompositeType } from "./composite-type.create.ts";
4
4
  import type { DropCompositeType } from "./composite-type.drop.ts";
5
5
  import type { CompositeTypePrivilege } from "./composite-type.privilege.ts";
6
+ import type { SecurityLabelCompositeType } from "./composite-type.security-label.ts";
6
7
 
7
8
  /** Union of all composite-type-related change variants (`objectType: "composite_type"`). @category Change Types */
8
9
  export type CompositeTypeChange =
@@ -10,4 +11,5 @@ export type CompositeTypeChange =
10
11
  | CommentCompositeType
11
12
  | CreateCompositeType
12
13
  | DropCompositeType
13
- | CompositeTypePrivilege;
14
+ | CompositeTypePrivilege
15
+ | SecurityLabelCompositeType;
@@ -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 { deepEqual, hasNonAlterableChanges } from "../../utils.ts";
9
10
  import {
10
11
  AlterCompositeTypeAddAttribute,
@@ -25,6 +26,10 @@ import {
25
26
  RevokeCompositeTypePrivileges,
26
27
  RevokeGrantOptionCompositeTypePrivileges,
27
28
  } from "./changes/composite-type.privilege.ts";
29
+ import {
30
+ CreateSecurityLabelOnCompositeType,
31
+ DropSecurityLabelOnCompositeType,
32
+ } from "./changes/composite-type.security-label.ts";
28
33
  import type { CompositeTypeChange } from "./changes/composite-type.types.ts";
29
34
  import type { CompositeType } from "./composite-type.model.ts";
30
35
 
@@ -67,6 +72,14 @@ export function diffCompositeTypes(
67
72
  if (ct.comment !== null) {
68
73
  changes.push(new CreateCommentOnCompositeType({ compositeType: ct }));
69
74
  }
75
+ for (const label of ct.security_labels) {
76
+ changes.push(
77
+ new CreateSecurityLabelOnCompositeType({
78
+ compositeType: ct,
79
+ securityLabel: label,
80
+ }),
81
+ );
82
+ }
70
83
  // Attribute comments on creation
71
84
  for (const attr of ct.columns) {
72
85
  if (attr.comment !== null) {
@@ -189,6 +202,26 @@ export function diffCompositeTypes(
189
202
  }
190
203
  }
191
204
 
205
+ // SECURITY LABELS
206
+ changes.push(
207
+ ...diffSecurityLabels<
208
+ CreateSecurityLabelOnCompositeType | DropSecurityLabelOnCompositeType
209
+ >(
210
+ mainCompositeType.security_labels,
211
+ branchCompositeType.security_labels,
212
+ (securityLabel) =>
213
+ new CreateSecurityLabelOnCompositeType({
214
+ compositeType: branchCompositeType,
215
+ securityLabel,
216
+ }),
217
+ (securityLabel) =>
218
+ new DropSecurityLabelOnCompositeType({
219
+ compositeType: mainCompositeType,
220
+ securityLabel,
221
+ }),
222
+ ),
223
+ );
224
+
192
225
  // ATTRIBUTE diffs
193
226
  const mainAttrs = new Map(
194
227
  mainCompositeType.columns.map((c) => [c.name, c]),
@@ -10,6 +10,11 @@ import {
10
10
  type PrivilegeProps,
11
11
  privilegePropsSchema,
12
12
  } from "../../base.privilege-diff.ts";
13
+ import {
14
+ normalizeSecurityLabels,
15
+ type SecurityLabelProps,
16
+ securityLabelPropsSchema,
17
+ } from "../../security-label.types.ts";
13
18
  import { ReplicaIdentitySchema } from "../../table/table.model.ts";
14
19
 
15
20
  const compositeTypePropsSchema = z.object({
@@ -30,6 +35,7 @@ const compositeTypePropsSchema = z.object({
30
35
  comment: z.string().nullable(),
31
36
  columns: z.array(columnPropsSchema),
32
37
  privileges: z.array(privilegePropsSchema),
38
+ security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
33
39
  });
34
40
 
35
41
  type CompositeTypePrivilegeProps = PrivilegeProps;
@@ -53,6 +59,7 @@ export class CompositeType extends BasePgModel implements TableLikeObject {
53
59
  public readonly comment: CompositeTypeProps["comment"];
54
60
  public readonly columns: CompositeTypeProps["columns"];
55
61
  public readonly privileges: CompositeTypePrivilegeProps[];
62
+ public readonly security_labels: SecurityLabelProps[];
56
63
 
57
64
  constructor(props: CompositeTypeProps) {
58
65
  super();
@@ -77,6 +84,7 @@ export class CompositeType extends BasePgModel implements TableLikeObject {
77
84
  this.comment = props.comment;
78
85
  this.columns = props.columns;
79
86
  this.privileges = props.privileges;
87
+ this.security_labels = props.security_labels ?? [];
80
88
  }
81
89
 
82
90
  get stableId(): `type:${string}` {
@@ -107,6 +115,7 @@ export class CompositeType extends BasePgModel implements TableLikeObject {
107
115
  comment: this.comment,
108
116
  columns: this.columns,
109
117
  privileges: this.privileges,
118
+ security_labels: this.security_labels,
110
119
  };
111
120
  }
112
121
 
@@ -131,6 +140,7 @@ export class CompositeType extends BasePgModel implements TableLikeObject {
131
140
  data: {
132
141
  ...this.dataFields,
133
142
  columns: normalizeColumns(),
143
+ security_labels: normalizeSecurityLabels(this.security_labels),
134
144
  },
135
145
  };
136
146
  }
@@ -165,7 +175,8 @@ export async function extractCompositeTypes(
165
175
  obj_description(c.reltype, 'pg_type') AS comment,
166
176
  c.relacl AS relacl, -- used by privileges LATERAL
167
177
  c.relowner AS relowner,
168
- c.oid AS oid
178
+ c.oid AS oid,
179
+ c.reltype AS reltype
169
180
  FROM pg_catalog.pg_class c
170
181
  LEFT JOIN extension_oids e ON c.reltype = e.objid
171
182
  WHERE NOT c.relnamespace::regnamespace::text LIKE ANY (ARRAY['pg\\_%', 'information\\_schema'])
@@ -189,7 +200,20 @@ export async function extractCompositeTypes(
189
200
  ct.owner,
190
201
  ct.comment,
191
202
  COALESCE(priv.privileges, '[]') AS privileges,
192
- COALESCE(cols.columns, '[]') AS columns
203
+ COALESCE(cols.columns, '[]') AS columns,
204
+ COALESCE(
205
+ (
206
+ SELECT json_agg(
207
+ json_build_object('provider', sl.provider, 'label', sl.label)
208
+ ORDER BY sl.provider
209
+ )
210
+ FROM pg_catalog.pg_seclabel sl
211
+ WHERE sl.objoid = ct.reltype
212
+ AND sl.classoid = 'pg_type'::regclass
213
+ AND sl.objsubid = 0
214
+ ),
215
+ '[]'::json
216
+ ) AS security_labels
193
217
  FROM composite_types ct
194
218
 
195
219
  -- privileges as a per-row LATERAL subquery
@@ -3,7 +3,11 @@ import type { Enum } from "../enum.model.ts";
3
3
 
4
4
  abstract class BaseEnumChange extends BaseChange {
5
5
  abstract readonly enum: Enum;
6
- abstract readonly scope: "object" | "comment" | "privilege";
6
+ abstract readonly scope:
7
+ | "object"
8
+ | "comment"
9
+ | "privilege"
10
+ | "security_label";
7
11
  readonly objectType: "enum" = "enum";
8
12
  }
9
13
 
@@ -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 { Enum } from "../enum.model.ts";
5
+ import { CreateEnumChange, DropEnumChange } from "./enum.base.ts";
6
+
7
+ export type SecurityLabelEnum =
8
+ | CreateSecurityLabelOnEnum
9
+ | DropSecurityLabelOnEnum;
10
+
11
+ export class CreateSecurityLabelOnEnum extends CreateEnumChange {
12
+ public readonly enum: Enum;
13
+ public readonly securityLabel: SecurityLabelProps;
14
+ public readonly scope = "security_label" as const;
15
+
16
+ constructor(props: { enum: Enum; securityLabel: SecurityLabelProps }) {
17
+ super();
18
+ this.enum = props.enum;
19
+ this.securityLabel = props.securityLabel;
20
+ }
21
+
22
+ get creates() {
23
+ return [
24
+ stableId.securityLabel(this.enum.stableId, this.securityLabel.provider),
25
+ ];
26
+ }
27
+
28
+ get requires() {
29
+ return [this.enum.stableId];
30
+ }
31
+
32
+ serialize(): string {
33
+ return [
34
+ "SECURITY LABEL FOR",
35
+ this.securityLabel.provider,
36
+ "ON TYPE",
37
+ `${this.enum.schema}.${this.enum.name}`,
38
+ "IS",
39
+ quoteLiteral(this.securityLabel.label),
40
+ ].join(" ");
41
+ }
42
+ }
43
+
44
+ export class DropSecurityLabelOnEnum extends DropEnumChange {
45
+ public readonly enum: Enum;
46
+ public readonly securityLabel: SecurityLabelProps;
47
+ public readonly scope = "security_label" as const;
48
+
49
+ constructor(props: { enum: Enum; securityLabel: SecurityLabelProps }) {
50
+ super();
51
+ this.enum = props.enum;
52
+ this.securityLabel = props.securityLabel;
53
+ }
54
+
55
+ get drops() {
56
+ return [
57
+ stableId.securityLabel(this.enum.stableId, this.securityLabel.provider),
58
+ ];
59
+ }
60
+
61
+ get requires() {
62
+ return [
63
+ stableId.securityLabel(this.enum.stableId, this.securityLabel.provider),
64
+ this.enum.stableId,
65
+ ];
66
+ }
67
+
68
+ serialize(): string {
69
+ return [
70
+ "SECURITY LABEL FOR",
71
+ this.securityLabel.provider,
72
+ "ON TYPE",
73
+ `${this.enum.schema}.${this.enum.name}`,
74
+ "IS NULL",
75
+ ].join(" ");
76
+ }
77
+ }
@@ -3,6 +3,7 @@ import type { CommentEnum } from "./enum.comment.ts";
3
3
  import type { CreateEnum } from "./enum.create.ts";
4
4
  import type { DropEnum } from "./enum.drop.ts";
5
5
  import type { EnumPrivilege } from "./enum.privilege.ts";
6
+ import type { SecurityLabelEnum } from "./enum.security-label.ts";
6
7
 
7
8
  /** Union of all enum-related change variants (`objectType: "enum"`). @category Change Types */
8
9
  export type EnumChange =
@@ -10,4 +11,5 @@ export type EnumChange =
10
11
  | CommentEnum
11
12
  | CreateEnum
12
13
  | DropEnum
13
- | EnumPrivilege;
14
+ | EnumPrivilege
15
+ | SecurityLabelEnum;
@@ -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
  AlterEnumAddValue,
10
11
  AlterEnumChangeOwner,
@@ -20,6 +21,10 @@ import {
20
21
  RevokeEnumPrivileges,
21
22
  RevokeGrantOptionEnumPrivileges,
22
23
  } from "./changes/enum.privilege.ts";
24
+ import {
25
+ CreateSecurityLabelOnEnum,
26
+ DropSecurityLabelOnEnum,
27
+ } from "./changes/enum.security-label.ts";
23
28
  import type { EnumChange } from "./changes/enum.types.ts";
24
29
  import type { Enum } from "./enum.model.ts";
25
30
 
@@ -61,6 +66,14 @@ export function diffEnums(
61
66
  if (createdEnum.comment !== null) {
62
67
  changes.push(new CreateCommentOnEnum({ enum: createdEnum }));
63
68
  }
69
+ for (const label of createdEnum.security_labels) {
70
+ changes.push(
71
+ new CreateSecurityLabelOnEnum({
72
+ enum: createdEnum,
73
+ securityLabel: label,
74
+ }),
75
+ );
76
+ }
64
77
 
65
78
  // PRIVILEGES: For created objects, compare against default privileges state
66
79
  // The migration script will run ALTER DEFAULT PRIVILEGES before CREATE (via constraint spec),
@@ -196,6 +209,26 @@ export function diffEnums(
196
209
  }
197
210
  }
198
211
 
212
+ // SECURITY LABELS
213
+ changes.push(
214
+ ...diffSecurityLabels<
215
+ CreateSecurityLabelOnEnum | DropSecurityLabelOnEnum
216
+ >(
217
+ mainEnum.security_labels,
218
+ branchEnum.security_labels,
219
+ (securityLabel) =>
220
+ new CreateSecurityLabelOnEnum({
221
+ enum: branchEnum,
222
+ securityLabel,
223
+ }),
224
+ (securityLabel) =>
225
+ new DropSecurityLabelOnEnum({
226
+ enum: mainEnum,
227
+ securityLabel,
228
+ }),
229
+ ),
230
+ );
231
+
199
232
  // PRIVILEGES
200
233
  // Filter out PUBLIC's built-in default USAGE privilege from main catalog
201
234
  // (PostgreSQL grants it automatically, so we shouldn't compare it)