@supabase/pg-delta 1.0.0-alpha.22 → 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 (220) 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/package.json +1 -1
  123. package/src/core/catalog.model.ts +1 -0
  124. package/src/core/integrations/filter/dsl.test.ts +27 -0
  125. package/src/core/integrations/filter/flatten.ts +16 -0
  126. package/src/core/objects/aggregate/aggregate.diff.ts +33 -0
  127. package/src/core/objects/aggregate/aggregate.model.ts +22 -1
  128. package/src/core/objects/aggregate/changes/aggregate.base.ts +5 -1
  129. package/src/core/objects/aggregate/changes/aggregate.security-label.ts +99 -0
  130. package/src/core/objects/aggregate/changes/aggregate.types.ts +3 -1
  131. package/src/core/objects/base.model.ts +2 -0
  132. package/src/core/objects/domain/changes/domain.base.ts +5 -1
  133. package/src/core/objects/domain/changes/domain.security-label.test.ts +56 -0
  134. package/src/core/objects/domain/changes/domain.security-label.ts +77 -0
  135. package/src/core/objects/domain/changes/domain.types.ts +3 -1
  136. package/src/core/objects/domain/domain.diff.ts +33 -0
  137. package/src/core/objects/domain/domain.model.ts +22 -1
  138. package/src/core/objects/event-trigger/changes/event-trigger.base.ts +1 -1
  139. package/src/core/objects/event-trigger/changes/event-trigger.security-label.ts +95 -0
  140. package/src/core/objects/event-trigger/changes/event-trigger.types.ts +3 -1
  141. package/src/core/objects/event-trigger/event-trigger.diff.ts +33 -0
  142. package/src/core/objects/event-trigger/event-trigger.model.ts +22 -1
  143. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.ts +5 -1
  144. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.ts +95 -0
  145. package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.ts +3 -1
  146. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +33 -0
  147. package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +24 -1
  148. package/src/core/objects/materialized-view/changes/materialized-view.base.ts +5 -1
  149. package/src/core/objects/materialized-view/changes/materialized-view.security-label.test.ts +63 -0
  150. package/src/core/objects/materialized-view/changes/materialized-view.security-label.ts +95 -0
  151. package/src/core/objects/materialized-view/changes/materialized-view.types.ts +3 -1
  152. package/src/core/objects/materialized-view/materialized-view.diff.ts +37 -0
  153. package/src/core/objects/materialized-view/materialized-view.model.ts +25 -4
  154. package/src/core/objects/procedure/changes/procedure.base.ts +5 -1
  155. package/src/core/objects/procedure/changes/procedure.security-label.ts +105 -0
  156. package/src/core/objects/procedure/changes/procedure.types.ts +3 -1
  157. package/src/core/objects/procedure/procedure.diff.ts +33 -0
  158. package/src/core/objects/procedure/procedure.model.ts +23 -2
  159. package/src/core/objects/publication/changes/publication.base.ts +1 -1
  160. package/src/core/objects/publication/changes/publication.security-label.ts +95 -0
  161. package/src/core/objects/publication/changes/publication.types.ts +3 -1
  162. package/src/core/objects/publication/publication.diff.ts +33 -0
  163. package/src/core/objects/publication/publication.model.ts +24 -1
  164. package/src/core/objects/role/changes/role.base.ts +2 -1
  165. package/src/core/objects/role/changes/role.security-label.ts +77 -0
  166. package/src/core/objects/role/changes/role.types.ts +3 -1
  167. package/src/core/objects/role/role.diff.ts +33 -0
  168. package/src/core/objects/role/role.model.ts +32 -0
  169. package/src/core/objects/schema/changes/schema.alter.test.ts +1 -0
  170. package/src/core/objects/schema/changes/schema.base.ts +5 -1
  171. package/src/core/objects/schema/changes/schema.create.test.ts +1 -0
  172. package/src/core/objects/schema/changes/schema.drop.test.ts +1 -0
  173. package/src/core/objects/schema/changes/schema.security-label.test.ts +76 -0
  174. package/src/core/objects/schema/changes/schema.security-label.ts +77 -0
  175. package/src/core/objects/schema/changes/schema.types.ts +3 -1
  176. package/src/core/objects/schema/schema.diff.test.ts +1 -0
  177. package/src/core/objects/schema/schema.diff.ts +43 -1
  178. package/src/core/objects/schema/schema.model.ts +21 -1
  179. package/src/core/objects/security-label.types.test.ts +106 -0
  180. package/src/core/objects/security-label.types.ts +61 -0
  181. package/src/core/objects/sequence/changes/sequence.base.ts +5 -1
  182. package/src/core/objects/sequence/changes/sequence.security-label.test.ts +58 -0
  183. package/src/core/objects/sequence/changes/sequence.security-label.ts +92 -0
  184. package/src/core/objects/sequence/changes/sequence.types.ts +3 -1
  185. package/src/core/objects/sequence/sequence.diff.ts +33 -0
  186. package/src/core/objects/sequence/sequence.model.ts +22 -1
  187. package/src/core/objects/subscription/changes/subscription.base.ts +1 -1
  188. package/src/core/objects/subscription/changes/subscription.security-label.ts +95 -0
  189. package/src/core/objects/subscription/changes/subscription.types.ts +3 -1
  190. package/src/core/objects/subscription/subscription.diff.ts +33 -0
  191. package/src/core/objects/subscription/subscription.model.ts +22 -1
  192. package/src/core/objects/table/changes/table.base.ts +5 -1
  193. package/src/core/objects/table/changes/table.security-label.test.ts +140 -0
  194. package/src/core/objects/table/changes/table.security-label.ts +183 -0
  195. package/src/core/objects/table/changes/table.types.ts +3 -1
  196. package/src/core/objects/table/table.diff.ts +87 -0
  197. package/src/core/objects/table/table.model.ts +42 -2
  198. package/src/core/objects/type/composite-type/changes/composite-type.base.ts +5 -1
  199. package/src/core/objects/type/composite-type/changes/composite-type.security-label.ts +95 -0
  200. package/src/core/objects/type/composite-type/changes/composite-type.types.ts +3 -1
  201. package/src/core/objects/type/composite-type/composite-type.diff.ts +33 -0
  202. package/src/core/objects/type/composite-type/composite-type.model.ts +26 -2
  203. package/src/core/objects/type/enum/changes/enum.base.ts +5 -1
  204. package/src/core/objects/type/enum/changes/enum.security-label.ts +77 -0
  205. package/src/core/objects/type/enum/changes/enum.types.ts +3 -1
  206. package/src/core/objects/type/enum/enum.diff.ts +33 -0
  207. package/src/core/objects/type/enum/enum.model.ts +25 -1
  208. package/src/core/objects/type/range/changes/range.base.ts +5 -1
  209. package/src/core/objects/type/range/changes/range.security-label.ts +77 -0
  210. package/src/core/objects/type/range/changes/range.types.ts +3 -1
  211. package/src/core/objects/type/range/range.diff.ts +33 -0
  212. package/src/core/objects/type/range/range.model.ts +22 -1
  213. package/src/core/objects/utils.ts +3 -0
  214. package/src/core/objects/view/changes/view.base.ts +5 -1
  215. package/src/core/objects/view/changes/view.security-label.test.ts +64 -0
  216. package/src/core/objects/view/changes/view.security-label.ts +77 -0
  217. package/src/core/objects/view/changes/view.types.ts +3 -1
  218. package/src/core/objects/view/view.diff.ts +31 -0
  219. package/src/core/objects/view/view.model.ts +25 -2
  220. package/src/core/plan/sql-format/fixtures.ts +1 -0
@@ -0,0 +1,28 @@
1
+ import type { SecurityLabelProps } from "../../security-label.types.ts";
2
+ import type { Role } from "../role.model.ts";
3
+ import { CreateRoleChange, DropRoleChange } from "./role.base.ts";
4
+ export type SecurityLabelRole = CreateSecurityLabelOnRole | DropSecurityLabelOnRole;
5
+ export declare class CreateSecurityLabelOnRole extends CreateRoleChange {
6
+ readonly role: Role;
7
+ readonly securityLabel: SecurityLabelProps;
8
+ readonly scope: "security_label";
9
+ constructor(props: {
10
+ role: Role;
11
+ securityLabel: SecurityLabelProps;
12
+ });
13
+ get creates(): `securityLabel:${string}::provider:${string}`[];
14
+ get requires(): `role:${string}`[];
15
+ serialize(): string;
16
+ }
17
+ export declare class DropSecurityLabelOnRole extends DropRoleChange {
18
+ readonly role: Role;
19
+ readonly securityLabel: SecurityLabelProps;
20
+ readonly scope: "security_label";
21
+ constructor(props: {
22
+ role: Role;
23
+ securityLabel: SecurityLabelProps;
24
+ });
25
+ get drops(): `securityLabel:${string}::provider:${string}`[];
26
+ get requires(): (`securityLabel:${string}::provider:${string}` | `role:${string}`)[];
27
+ serialize(): string;
28
+ }
@@ -0,0 +1,61 @@
1
+ import { quoteLiteral } from "../../base.change.js";
2
+ import { stableId } from "../../utils.js";
3
+ import { CreateRoleChange, DropRoleChange } from "./role.base.js";
4
+ export class CreateSecurityLabelOnRole extends CreateRoleChange {
5
+ role;
6
+ securityLabel;
7
+ scope = "security_label";
8
+ constructor(props) {
9
+ super();
10
+ this.role = props.role;
11
+ this.securityLabel = props.securityLabel;
12
+ }
13
+ get creates() {
14
+ return [
15
+ stableId.securityLabel(this.role.stableId, this.securityLabel.provider),
16
+ ];
17
+ }
18
+ get requires() {
19
+ return [this.role.stableId];
20
+ }
21
+ serialize() {
22
+ return [
23
+ "SECURITY LABEL FOR",
24
+ this.securityLabel.provider,
25
+ "ON ROLE",
26
+ this.role.name,
27
+ "IS",
28
+ quoteLiteral(this.securityLabel.label),
29
+ ].join(" ");
30
+ }
31
+ }
32
+ export class DropSecurityLabelOnRole extends DropRoleChange {
33
+ role;
34
+ securityLabel;
35
+ scope = "security_label";
36
+ constructor(props) {
37
+ super();
38
+ this.role = props.role;
39
+ this.securityLabel = props.securityLabel;
40
+ }
41
+ get drops() {
42
+ return [
43
+ stableId.securityLabel(this.role.stableId, this.securityLabel.provider),
44
+ ];
45
+ }
46
+ get requires() {
47
+ return [
48
+ stableId.securityLabel(this.role.stableId, this.securityLabel.provider),
49
+ this.role.stableId,
50
+ ];
51
+ }
52
+ serialize() {
53
+ return [
54
+ "SECURITY LABEL FOR",
55
+ this.securityLabel.provider,
56
+ "ON ROLE",
57
+ this.role.name,
58
+ "IS NULL",
59
+ ].join(" ");
60
+ }
61
+ }
@@ -3,5 +3,6 @@ import type { CommentRole } from "./role.comment.ts";
3
3
  import type { CreateRole } from "./role.create.ts";
4
4
  import type { DropRole } from "./role.drop.ts";
5
5
  import type { RolePrivilege } from "./role.privilege.ts";
6
+ import type { SecurityLabelRole } from "./role.security-label.ts";
6
7
  /** Union of all role-related change variants (`objectType: "role"`). @category Change Types */
7
- export type RoleChange = AlterRole | CommentRole | CreateRole | DropRole | RolePrivilege;
8
+ export type RoleChange = AlterRole | CommentRole | CreateRole | DropRole | RolePrivilege | SecurityLabelRole;
@@ -1,9 +1,11 @@
1
1
  import { diffObjects } from "../base.diff.js";
2
+ import { diffSecurityLabels } from "../security-label.types.js";
2
3
  import { AlterRoleSetConfig, AlterRoleSetOptions, } from "./changes/role.alter.js";
3
4
  import { CreateCommentOnRole, DropCommentOnRole, } from "./changes/role.comment.js";
4
5
  import { CreateRole } from "./changes/role.create.js";
5
6
  import { DropRole } from "./changes/role.drop.js";
6
7
  import { GrantRoleDefaultPrivileges, GrantRoleMembership, RevokeRoleDefaultPrivileges, RevokeRoleMembership, RevokeRoleMembershipOptions, } from "./changes/role.privilege.js";
8
+ import { CreateSecurityLabelOnRole, DropSecurityLabelOnRole, } from "./changes/role.security-label.js";
7
9
  /**
8
10
  * Diff two sets of roles from main and branch catalogs.
9
11
  *
@@ -31,6 +33,12 @@ export function diffRoles(ctx, main, branch) {
31
33
  if (role.comment !== null) {
32
34
  changes.push(new CreateCommentOnRole({ role }));
33
35
  }
36
+ for (const label of role.security_labels) {
37
+ changes.push(new CreateSecurityLabelOnRole({
38
+ role,
39
+ securityLabel: label,
40
+ }));
41
+ }
34
42
  // MEMBERSHIPS: Grant memberships immediately after role creation.
35
43
  // Members are already deduplicated by the Role model constructor.
36
44
  for (const membership of role.members) {
@@ -171,6 +179,14 @@ export function diffRoles(ctx, main, branch) {
171
179
  changes.push(new CreateCommentOnRole({ role: branchRole }));
172
180
  }
173
181
  }
182
+ // SECURITY LABELS
183
+ changes.push(...diffSecurityLabels(mainRole.security_labels, branchRole.security_labels, (securityLabel) => new CreateSecurityLabelOnRole({
184
+ role: branchRole,
185
+ securityLabel,
186
+ }), (securityLabel) => new DropSecurityLabelOnRole({
187
+ role: mainRole,
188
+ securityLabel,
189
+ })));
174
190
  // MEMBERSHIPS
175
191
  // Members are already deduplicated by the Role model constructor.
176
192
  const mainMembers = new Map(mainRole.members.map((m) => [m.member, m]));
@@ -1,6 +1,7 @@
1
1
  import type { Pool } from "pg";
2
2
  import z from "zod";
3
3
  import { BasePgModel } from "../base.model.ts";
4
+ import { type SecurityLabelProps } from "../security-label.types.ts";
4
5
  declare const rolePropsSchema: z.ZodObject<{
5
6
  name: z.ZodString;
6
7
  is_superuser: z.ZodBoolean;
@@ -36,6 +37,10 @@ declare const rolePropsSchema: z.ZodObject<{
36
37
  }, z.z.core.$strip>>;
37
38
  is_implicit: z.ZodBoolean;
38
39
  }, z.z.core.$strip>>;
40
+ security_labels: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
41
+ provider: z.ZodString;
42
+ label: z.ZodString;
43
+ }, z.z.core.$strip>>>>;
39
44
  }, z.z.core.$strip>;
40
45
  export type RoleProps = z.infer<typeof rolePropsSchema>;
41
46
  export declare class Role extends BasePgModel {
@@ -52,6 +57,7 @@ export declare class Role extends BasePgModel {
52
57
  readonly comment: RoleProps["comment"];
53
58
  readonly members: RoleProps["members"];
54
59
  readonly default_privileges: RoleProps["default_privileges"];
60
+ readonly security_labels: SecurityLabelProps[];
55
61
  constructor(props: RoleProps);
56
62
  get stableId(): `role:${string}`;
57
63
  get identityFields(): {
@@ -84,6 +90,10 @@ export declare class Role extends BasePgModel {
84
90
  objtype: "n" | "r" | "f" | "S" | "T";
85
91
  grantee: string;
86
92
  }[];
93
+ security_labels: {
94
+ provider: string;
95
+ label: string;
96
+ }[];
87
97
  };
88
98
  }
89
99
  export declare function extractRoles(pool: Pool): Promise<Role[]>;
@@ -1,6 +1,7 @@
1
1
  import { sql } from "@ts-safeql/sql-tag";
2
2
  import z from "zod";
3
3
  import { BasePgModel } from "../base.model.js";
4
+ import { securityLabelPropsSchema, } from "../security-label.types.js";
4
5
  const membershipInfoSchema = z.object({
5
6
  member: z.string(),
6
7
  grantor: z.string(),
@@ -29,6 +30,7 @@ const rolePropsSchema = z.object({
29
30
  comment: z.string().nullable(),
30
31
  members: z.array(membershipInfoSchema),
31
32
  default_privileges: z.array(defaultPrivilegeSchema),
33
+ security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
32
34
  });
33
35
  export class Role extends BasePgModel {
34
36
  name;
@@ -44,6 +46,7 @@ export class Role extends BasePgModel {
44
46
  comment;
45
47
  members;
46
48
  default_privileges;
49
+ security_labels;
47
50
  constructor(props) {
48
51
  super();
49
52
  // Identity fields
@@ -61,6 +64,7 @@ export class Role extends BasePgModel {
61
64
  this.comment = props.comment;
62
65
  this.members = deduplicateMembers(props.members);
63
66
  this.default_privileges = props.default_privileges;
67
+ this.security_labels = props.security_labels ?? [];
64
68
  }
65
69
  get stableId() {
66
70
  return `role:${this.name}`;
@@ -106,6 +110,7 @@ export class Role extends BasePgModel {
106
110
  comment: this.comment,
107
111
  members: sortedMembers,
108
112
  default_privileges: sortedDefaultPrivs,
113
+ security_labels: this.security_labels,
109
114
  };
110
115
  }
111
116
  }
@@ -200,6 +205,18 @@ export async function extractRoles(pool) {
200
205
  r.rolbypassrls AS can_bypass_rls,
201
206
  r.rolconfig AS config,
202
207
  obj_description(r.oid, 'pg_authid') AS comment,
208
+ COALESCE(
209
+ (
210
+ SELECT json_agg(
211
+ json_build_object('provider', sl.provider, 'label', sl.label)
212
+ ORDER BY sl.provider
213
+ )
214
+ FROM pg_catalog.pg_shseclabel sl
215
+ WHERE sl.objoid = r.oid
216
+ AND sl.classoid = 'pg_authid'::regclass
217
+ ),
218
+ '[]'::json
219
+ ) AS security_labels,
203
220
  COALESCE(rm.members, '[]') AS members,
204
221
  COALESCE(
205
222
  (
@@ -322,6 +339,18 @@ export async function extractRoles(pool) {
322
339
  r.rolbypassrls AS can_bypass_rls,
323
340
  r.rolconfig AS config,
324
341
  obj_description(r.oid, 'pg_authid') AS comment,
342
+ COALESCE(
343
+ (
344
+ SELECT json_agg(
345
+ json_build_object('provider', sl.provider, 'label', sl.label)
346
+ ORDER BY sl.provider
347
+ )
348
+ FROM pg_catalog.pg_shseclabel sl
349
+ WHERE sl.objoid = r.oid
350
+ AND sl.classoid = 'pg_authid'::regclass
351
+ ),
352
+ '[]'::json
353
+ ) AS security_labels,
325
354
  COALESCE(rm.members, '[]') AS members,
326
355
  COALESCE(
327
356
  (
@@ -2,7 +2,7 @@ import { BaseChange } from "../../base.change.ts";
2
2
  import type { Schema } from "../schema.model.ts";
3
3
  declare abstract class BaseSchemaChange extends BaseChange {
4
4
  abstract readonly schema: Schema;
5
- abstract readonly scope: "object" | "comment" | "privilege";
5
+ abstract readonly scope: "object" | "comment" | "privilege" | "security_label";
6
6
  readonly objectType: "schema";
7
7
  }
8
8
  export declare abstract class CreateSchemaChange extends BaseSchemaChange {
@@ -0,0 +1,28 @@
1
+ import type { SecurityLabelProps } from "../../security-label.types.ts";
2
+ import type { Schema } from "../schema.model.ts";
3
+ import { CreateSchemaChange, DropSchemaChange } from "./schema.base.ts";
4
+ export type SecurityLabelSchema = CreateSecurityLabelOnSchema | DropSecurityLabelOnSchema;
5
+ export declare class CreateSecurityLabelOnSchema extends CreateSchemaChange {
6
+ readonly schema: Schema;
7
+ readonly securityLabel: SecurityLabelProps;
8
+ readonly scope: "security_label";
9
+ constructor(props: {
10
+ schema: Schema;
11
+ securityLabel: SecurityLabelProps;
12
+ });
13
+ get creates(): `securityLabel:${string}::provider:${string}`[];
14
+ get requires(): `schema:${string}`[];
15
+ serialize(): string;
16
+ }
17
+ export declare class DropSecurityLabelOnSchema extends DropSchemaChange {
18
+ readonly schema: Schema;
19
+ readonly securityLabel: SecurityLabelProps;
20
+ readonly scope: "security_label";
21
+ constructor(props: {
22
+ schema: Schema;
23
+ securityLabel: SecurityLabelProps;
24
+ });
25
+ get drops(): `securityLabel:${string}::provider:${string}`[];
26
+ get requires(): (`schema:${string}` | `securityLabel:${string}::provider:${string}`)[];
27
+ serialize(): string;
28
+ }
@@ -0,0 +1,61 @@
1
+ import { quoteLiteral } from "../../base.change.js";
2
+ import { stableId } from "../../utils.js";
3
+ import { CreateSchemaChange, DropSchemaChange } from "./schema.base.js";
4
+ export class CreateSecurityLabelOnSchema extends CreateSchemaChange {
5
+ schema;
6
+ securityLabel;
7
+ scope = "security_label";
8
+ constructor(props) {
9
+ super();
10
+ this.schema = props.schema;
11
+ this.securityLabel = props.securityLabel;
12
+ }
13
+ get creates() {
14
+ return [
15
+ stableId.securityLabel(this.schema.stableId, this.securityLabel.provider),
16
+ ];
17
+ }
18
+ get requires() {
19
+ return [this.schema.stableId];
20
+ }
21
+ serialize() {
22
+ return [
23
+ "SECURITY LABEL FOR",
24
+ this.securityLabel.provider,
25
+ "ON SCHEMA",
26
+ this.schema.name,
27
+ "IS",
28
+ quoteLiteral(this.securityLabel.label),
29
+ ].join(" ");
30
+ }
31
+ }
32
+ export class DropSecurityLabelOnSchema extends DropSchemaChange {
33
+ schema;
34
+ securityLabel;
35
+ scope = "security_label";
36
+ constructor(props) {
37
+ super();
38
+ this.schema = props.schema;
39
+ this.securityLabel = props.securityLabel;
40
+ }
41
+ get drops() {
42
+ return [
43
+ stableId.securityLabel(this.schema.stableId, this.securityLabel.provider),
44
+ ];
45
+ }
46
+ get requires() {
47
+ return [
48
+ stableId.securityLabel(this.schema.stableId, this.securityLabel.provider),
49
+ this.schema.stableId,
50
+ ];
51
+ }
52
+ serialize() {
53
+ return [
54
+ "SECURITY LABEL FOR",
55
+ this.securityLabel.provider,
56
+ "ON SCHEMA",
57
+ this.schema.name,
58
+ "IS NULL",
59
+ ].join(" ");
60
+ }
61
+ }
@@ -3,5 +3,6 @@ import type { CommentSchema } from "./schema.comment.ts";
3
3
  import type { CreateSchema } from "./schema.create.ts";
4
4
  import type { DropSchema } from "./schema.drop.ts";
5
5
  import type { SchemaPrivilege } from "./schema.privilege.ts";
6
+ import type { SecurityLabelSchema } from "./schema.security-label.ts";
6
7
  /** Union of all schema-related change variants (`objectType: "schema"`). @category Change Types */
7
- export type SchemaChange = AlterSchema | CommentSchema | CreateSchema | DropSchema | SchemaPrivilege;
8
+ export type SchemaChange = AlterSchema | CommentSchema | CreateSchema | DropSchema | SchemaPrivilege | SecurityLabelSchema;
@@ -1,10 +1,12 @@
1
1
  import { diffObjects } from "../base.diff.js";
2
2
  import { diffPrivileges, emitObjectPrivilegeChanges, } from "../base.privilege-diff.js";
3
+ import { diffSecurityLabels } from "../security-label.types.js";
3
4
  import { AlterSchemaChangeOwner } from "./changes/schema.alter.js";
4
5
  import { CreateCommentOnSchema, DropCommentOnSchema, } from "./changes/schema.comment.js";
5
6
  import { CreateSchema } from "./changes/schema.create.js";
6
7
  import { DropSchema } from "./changes/schema.drop.js";
7
8
  import { GrantSchemaPrivileges, RevokeGrantOptionSchemaPrivileges, RevokeSchemaPrivileges, } from "./changes/schema.privilege.js";
9
+ import { CreateSecurityLabelOnSchema, DropSecurityLabelOnSchema, } from "./changes/schema.security-label.js";
8
10
  /**
9
11
  * Diff two sets of schemas from main and branch catalogs.
10
12
  *
@@ -22,6 +24,12 @@ export function diffSchemas(ctx, main, branch) {
22
24
  if (sc.comment !== null) {
23
25
  changes.push(new CreateCommentOnSchema({ schema: sc }));
24
26
  }
27
+ for (const label of sc.security_labels) {
28
+ changes.push(new CreateSecurityLabelOnSchema({
29
+ schema: sc,
30
+ securityLabel: label,
31
+ }));
32
+ }
25
33
  // PRIVILEGES: For created objects, compare against default privileges state
26
34
  // The migration script will run ALTER DEFAULT PRIVILEGES before CREATE (via constraint spec),
27
35
  // so objects are created with the default privileges state in effect.
@@ -43,7 +51,14 @@ export function diffSchemas(ctx, main, branch) {
43
51
  }, ctx.version));
44
52
  }
45
53
  for (const schemaId of dropped) {
46
- changes.push(new DropSchema({ schema: main[schemaId] }));
54
+ const mainSchema = main[schemaId];
55
+ for (const label of mainSchema.security_labels) {
56
+ changes.push(new DropSecurityLabelOnSchema({
57
+ schema: mainSchema,
58
+ securityLabel: label,
59
+ }));
60
+ }
61
+ changes.push(new DropSchema({ schema: mainSchema }));
47
62
  }
48
63
  for (const schemaId of altered) {
49
64
  const mainSchema = main[schemaId];
@@ -64,6 +79,14 @@ export function diffSchemas(ctx, main, branch) {
64
79
  changes.push(new CreateCommentOnSchema({ schema: branchSchema }));
65
80
  }
66
81
  }
82
+ // SECURITY LABELS
83
+ changes.push(...diffSecurityLabels(mainSchema.security_labels, branchSchema.security_labels, (securityLabel) => new CreateSecurityLabelOnSchema({
84
+ schema: branchSchema,
85
+ securityLabel,
86
+ }), (securityLabel) => new DropSecurityLabelOnSchema({
87
+ schema: mainSchema,
88
+ securityLabel,
89
+ })));
67
90
  // PRIVILEGES
68
91
  // Filter out owner privileges - owner always has ALL privileges implicitly
69
92
  // and shouldn't be compared. Use branch owner as the reference.
@@ -2,6 +2,7 @@ import type { Pool } from "pg";
2
2
  import z from "zod";
3
3
  import { BasePgModel } from "../base.model.ts";
4
4
  import { type PrivilegeProps } from "../base.privilege-diff.ts";
5
+ import { type SecurityLabelProps } from "../security-label.types.ts";
5
6
  /**
6
7
  * All properties exposed by CREATE SCHEMA statement are included in diff output.
7
8
  * https://www.postgresql.org/docs/current/sql-createschema.html
@@ -19,6 +20,10 @@ declare const schemaPropsSchema: z.ZodObject<{
19
20
  grantable: z.ZodBoolean;
20
21
  columns: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
21
22
  }, z.z.core.$strip>>;
23
+ security_labels: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
24
+ provider: z.ZodString;
25
+ label: z.ZodString;
26
+ }, z.z.core.$strip>>>>;
22
27
  }, z.z.core.$strip>;
23
28
  type SchemaPrivilegeProps = PrivilegeProps;
24
29
  export type SchemaProps = z.infer<typeof schemaPropsSchema>;
@@ -27,6 +32,7 @@ export declare class Schema extends BasePgModel {
27
32
  readonly owner: SchemaProps["owner"];
28
33
  readonly comment: SchemaProps["comment"];
29
34
  readonly privileges: SchemaPrivilegeProps[];
35
+ readonly security_labels: SecurityLabelProps[];
30
36
  constructor(props: SchemaProps);
31
37
  get stableId(): `schema:${string}`;
32
38
  get identityFields(): {
@@ -41,6 +47,10 @@ export declare class Schema extends BasePgModel {
41
47
  grantable: boolean;
42
48
  columns?: string[] | null | undefined;
43
49
  }[];
50
+ security_labels: {
51
+ provider: string;
52
+ label: string;
53
+ }[];
44
54
  };
45
55
  }
46
56
  export declare function extractSchemas(pool: Pool): Promise<Schema[]>;
@@ -2,6 +2,7 @@ import { sql } from "@ts-safeql/sql-tag";
2
2
  import z from "zod";
3
3
  import { BasePgModel } from "../base.model.js";
4
4
  import { privilegePropsSchema, } from "../base.privilege-diff.js";
5
+ import { securityLabelPropsSchema, } from "../security-label.types.js";
5
6
  /**
6
7
  * All properties exposed by CREATE SCHEMA statement are included in diff output.
7
8
  * https://www.postgresql.org/docs/current/sql-createschema.html
@@ -14,12 +15,14 @@ const schemaPropsSchema = z.object({
14
15
  owner: z.string(),
15
16
  comment: z.string().nullable(),
16
17
  privileges: z.array(privilegePropsSchema),
18
+ security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
17
19
  });
18
20
  export class Schema extends BasePgModel {
19
21
  name;
20
22
  owner;
21
23
  comment;
22
24
  privileges;
25
+ security_labels;
23
26
  constructor(props) {
24
27
  super();
25
28
  // Identity fields
@@ -28,6 +31,7 @@ export class Schema extends BasePgModel {
28
31
  this.owner = props.owner;
29
32
  this.comment = props.comment;
30
33
  this.privileges = props.privileges;
34
+ this.security_labels = props.security_labels ?? [];
31
35
  }
32
36
  get stableId() {
33
37
  return `schema:${this.name}`;
@@ -42,6 +46,7 @@ export class Schema extends BasePgModel {
42
46
  owner: this.owner,
43
47
  comment: this.comment,
44
48
  privileges: this.privileges,
49
+ security_labels: this.security_labels,
45
50
  };
46
51
  }
47
52
  }
@@ -72,7 +77,19 @@ export async function extractSchemas(pool) {
72
77
  )
73
78
  from lateral aclexplode(COALESCE(nspacl, acldefault('n', nspowner))) as x(grantor, grantee, privilege_type, is_grantable)
74
79
  ), '[]'
75
- ) as privileges
80
+ ) as privileges,
81
+ coalesce(
82
+ (
83
+ select json_agg(
84
+ json_build_object('provider', sl.provider, 'label', sl.label)
85
+ order by sl.provider
86
+ )
87
+ from pg_catalog.pg_seclabel sl
88
+ where sl.objoid = pg_namespace.oid
89
+ and sl.classoid = 'pg_namespace'::regclass
90
+ and sl.objsubid = 0
91
+ ), '[]'
92
+ ) as security_labels
76
93
  from
77
94
  pg_catalog.pg_namespace
78
95
  left outer join extension_oids e on e.objid = oid
@@ -0,0 +1,20 @@
1
+ import { z } from "zod";
2
+ export declare const securityLabelPropsSchema: z.ZodObject<{
3
+ provider: z.ZodString;
4
+ label: z.ZodString;
5
+ }, z.core.$strip>;
6
+ export type SecurityLabelProps = z.infer<typeof securityLabelPropsSchema>;
7
+ export declare function normalizeSecurityLabels(labels: readonly SecurityLabelProps[]): SecurityLabelProps[];
8
+ /**
9
+ * Pure helper: compares two arrays of security labels keyed by provider and
10
+ * returns a deterministic list of create/drop changes.
11
+ *
12
+ * - Labels present only on `branch` → emit create (via makeCreate).
13
+ * - Labels present only on `main` → emit drop (via makeDrop).
14
+ * - Labels with differing `label` under the same provider → emit create
15
+ * (PostgreSQL's SECURITY LABEL … IS '…' overwrites, so no separate alter).
16
+ * - Unchanged labels → nothing.
17
+ *
18
+ * Output order: by provider ascending.
19
+ */
20
+ export declare function diffSecurityLabels<C>(main: readonly SecurityLabelProps[], branch: readonly SecurityLabelProps[], makeCreate: (props: SecurityLabelProps) => C, makeDrop: (props: SecurityLabelProps) => C): C[];
@@ -0,0 +1,46 @@
1
+ import { z } from "zod";
2
+ export const securityLabelPropsSchema = z.object({
3
+ provider: z.string(),
4
+ label: z.string(),
5
+ });
6
+ export function normalizeSecurityLabels(labels) {
7
+ return [...labels].sort((a, b) => a.provider.localeCompare(b.provider));
8
+ }
9
+ /**
10
+ * Pure helper: compares two arrays of security labels keyed by provider and
11
+ * returns a deterministic list of create/drop changes.
12
+ *
13
+ * - Labels present only on `branch` → emit create (via makeCreate).
14
+ * - Labels present only on `main` → emit drop (via makeDrop).
15
+ * - Labels with differing `label` under the same provider → emit create
16
+ * (PostgreSQL's SECURITY LABEL … IS '…' overwrites, so no separate alter).
17
+ * - Unchanged labels → nothing.
18
+ *
19
+ * Output order: by provider ascending.
20
+ */
21
+ export function diffSecurityLabels(main, branch, makeCreate, makeDrop) {
22
+ const mainByProvider = new Map(main.map((l) => [l.provider, l.label]));
23
+ const branchByProvider = new Map(branch.map((l) => [l.provider, l.label]));
24
+ const providers = new Set([
25
+ ...mainByProvider.keys(),
26
+ ...branchByProvider.keys(),
27
+ ]);
28
+ const sortedProviders = [...providers].sort();
29
+ const out = [];
30
+ for (const provider of sortedProviders) {
31
+ const mainLabel = mainByProvider.get(provider);
32
+ const branchLabel = branchByProvider.get(provider);
33
+ if (mainLabel === undefined && branchLabel !== undefined) {
34
+ out.push(makeCreate({ provider, label: branchLabel }));
35
+ }
36
+ else if (mainLabel !== undefined && branchLabel === undefined) {
37
+ out.push(makeDrop({ provider, label: mainLabel }));
38
+ }
39
+ else if (mainLabel !== undefined &&
40
+ branchLabel !== undefined &&
41
+ mainLabel !== branchLabel) {
42
+ out.push(makeCreate({ provider, label: branchLabel }));
43
+ }
44
+ }
45
+ return out;
46
+ }
@@ -2,7 +2,7 @@ import { BaseChange } from "../../base.change.ts";
2
2
  import type { Sequence } from "../sequence.model.ts";
3
3
  declare abstract class BaseSequenceChange extends BaseChange {
4
4
  abstract readonly sequence: Sequence;
5
- abstract readonly scope: "object" | "comment" | "privilege";
5
+ abstract readonly scope: "object" | "comment" | "privilege" | "security_label";
6
6
  readonly objectType: "sequence";
7
7
  }
8
8
  export declare abstract class CreateSequenceChange extends BaseSequenceChange {
@@ -0,0 +1,28 @@
1
+ import type { SecurityLabelProps } from "../../security-label.types.ts";
2
+ import type { Sequence } from "../sequence.model.ts";
3
+ import { CreateSequenceChange, DropSequenceChange } from "./sequence.base.ts";
4
+ export type SecurityLabelSequence = CreateSecurityLabelOnSequence | DropSecurityLabelOnSequence;
5
+ export declare class CreateSecurityLabelOnSequence extends CreateSequenceChange {
6
+ readonly sequence: Sequence;
7
+ readonly securityLabel: SecurityLabelProps;
8
+ readonly scope: "security_label";
9
+ constructor(props: {
10
+ sequence: Sequence;
11
+ securityLabel: SecurityLabelProps;
12
+ });
13
+ get creates(): `securityLabel:${string}::provider:${string}`[];
14
+ get requires(): `sequence:${string}`[];
15
+ serialize(): string;
16
+ }
17
+ export declare class DropSecurityLabelOnSequence extends DropSequenceChange {
18
+ readonly sequence: Sequence;
19
+ readonly securityLabel: SecurityLabelProps;
20
+ readonly scope: "security_label";
21
+ constructor(props: {
22
+ sequence: Sequence;
23
+ securityLabel: SecurityLabelProps;
24
+ });
25
+ get drops(): `securityLabel:${string}::provider:${string}`[];
26
+ get requires(): (`securityLabel:${string}::provider:${string}` | `sequence:${string}`)[];
27
+ serialize(): string;
28
+ }