@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
@@ -157,6 +157,7 @@ export async function createEmptyCatalog(version, currentUser) {
157
157
  owner: currentUser,
158
158
  comment: "standard public schema",
159
159
  privileges: [],
160
+ security_labels: [],
160
161
  });
161
162
  return new Catalog({
162
163
  aggregates: {},
@@ -75,6 +75,19 @@ export function flattenChange(change) {
75
75
  }
76
76
  }
77
77
  }
78
+ else if (key === "securityLabel" &&
79
+ value &&
80
+ typeof value === "object" &&
81
+ !Array.isArray(value)) {
82
+ // Security labels are change-level metadata, so expose provider/label as
83
+ // bare keys for filters like { scope: "security_label", provider: "..." }.
84
+ for (const [subKey, subValue] of Object.entries(value)) {
85
+ const flatVal = toFlatValue(subValue);
86
+ if (flatVal !== undefined) {
87
+ flat[subKey] = flatVal;
88
+ }
89
+ }
90
+ }
78
91
  else {
79
92
  const flatVal = toFlatValue(value);
80
93
  if (flatVal !== undefined) {
@@ -1,11 +1,13 @@
1
1
  import { diffObjects } from "../base.diff.js";
2
2
  import { diffPrivileges, emitObjectPrivilegeChanges, filterPublicBuiltInDefaults, } from "../base.privilege-diff.js";
3
+ import { diffSecurityLabels } from "../security-label.types.js";
3
4
  import { deepEqual, hasNonAlterableChanges } from "../utils.js";
4
5
  import { AlterAggregateChangeOwner } from "./changes/aggregate.alter.js";
5
6
  import { CreateCommentOnAggregate, DropCommentOnAggregate, } from "./changes/aggregate.comment.js";
6
7
  import { CreateAggregate } from "./changes/aggregate.create.js";
7
8
  import { DropAggregate } from "./changes/aggregate.drop.js";
8
9
  import { GrantAggregatePrivileges, RevokeAggregatePrivileges, RevokeGrantOptionAggregatePrivileges, } from "./changes/aggregate.privilege.js";
10
+ import { CreateSecurityLabelOnAggregate, DropSecurityLabelOnAggregate, } from "./changes/aggregate.security-label.js";
9
11
  export function diffAggregates(ctx, main, branch) {
10
12
  const { created, dropped, altered } = diffObjects(main, branch);
11
13
  const changes = [];
@@ -23,6 +25,12 @@ export function diffAggregates(ctx, main, branch) {
23
25
  if (aggregate.comment !== null) {
24
26
  changes.push(new CreateCommentOnAggregate({ aggregate }));
25
27
  }
28
+ for (const label of aggregate.security_labels) {
29
+ changes.push(new CreateSecurityLabelOnAggregate({
30
+ aggregate,
31
+ securityLabel: label,
32
+ }));
33
+ }
26
34
  // PRIVILEGES: For created objects, compare against default privileges state
27
35
  // The migration script will run ALTER DEFAULT PRIVILEGES before CREATE (via constraint spec),
28
36
  // so objects are created with the default privileges state in effect.
@@ -113,6 +121,14 @@ export function diffAggregates(ctx, main, branch) {
113
121
  changes.push(new CreateCommentOnAggregate({ aggregate: branchAggregate }));
114
122
  }
115
123
  }
124
+ // SECURITY LABELS
125
+ changes.push(...diffSecurityLabels(mainAggregate.security_labels, branchAggregate.security_labels, (securityLabel) => new CreateSecurityLabelOnAggregate({
126
+ aggregate: branchAggregate,
127
+ securityLabel,
128
+ }), (securityLabel) => new DropSecurityLabelOnAggregate({
129
+ aggregate: mainAggregate,
130
+ securityLabel,
131
+ })));
116
132
  // PRIVILEGES
117
133
  // Filter out PUBLIC's built-in default EXECUTE privilege from main catalog
118
134
  // (PostgreSQL grants it automatically, so we shouldn't compare it)
@@ -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
  declare const aggregatePropsSchema: z.ZodObject<{
6
7
  schema: z.ZodString;
7
8
  name: z.ZodString;
@@ -71,6 +72,10 @@ declare const aggregatePropsSchema: z.ZodObject<{
71
72
  grantable: z.ZodBoolean;
72
73
  columns: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
73
74
  }, z.z.core.$strip>>;
75
+ security_labels: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
76
+ provider: z.ZodString;
77
+ label: z.ZodString;
78
+ }, z.z.core.$strip>>>>;
74
79
  }, z.z.core.$strip>;
75
80
  type AggregatePrivilegeProps = PrivilegeProps;
76
81
  type AggregateProps = z.infer<typeof aggregatePropsSchema>;
@@ -116,6 +121,7 @@ export declare class Aggregate extends BasePgModel {
116
121
  readonly owner: AggregateProps["owner"];
117
122
  readonly comment: AggregateProps["comment"];
118
123
  readonly privileges: AggregatePrivilegeProps[];
124
+ readonly security_labels: SecurityLabelProps[];
119
125
  constructor(props: AggregateProps);
120
126
  get stableId(): `aggregate:${string}`;
121
127
  get identityFields(): {
@@ -168,6 +174,10 @@ export declare class Aggregate extends BasePgModel {
168
174
  grantable: boolean;
169
175
  columns?: string[] | null | undefined;
170
176
  }[];
177
+ security_labels: {
178
+ provider: string;
179
+ label: string;
180
+ }[];
171
181
  };
172
182
  }
173
183
  export declare function extractAggregates(pool: Pool): Promise<Aggregate[]>;
@@ -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
  const AggregateKindSchema = z.enum([
6
7
  "n", // normal aggregate
7
8
  "o", // ordered-set aggregate
@@ -66,6 +67,7 @@ const aggregatePropsSchema = z.object({
66
67
  owner: z.string(),
67
68
  comment: z.string().nullable(),
68
69
  privileges: z.array(privilegePropsSchema),
70
+ security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
69
71
  });
70
72
  export class Aggregate extends BasePgModel {
71
73
  schema;
@@ -109,6 +111,7 @@ export class Aggregate extends BasePgModel {
109
111
  owner;
110
112
  comment;
111
113
  privileges;
114
+ security_labels;
112
115
  constructor(props) {
113
116
  super();
114
117
  this.schema = props.schema;
@@ -153,6 +156,7 @@ export class Aggregate extends BasePgModel {
153
156
  this.owner = props.owner;
154
157
  this.comment = props.comment;
155
158
  this.privileges = props.privileges;
159
+ this.security_labels = props.security_labels ?? [];
156
160
  }
157
161
  get stableId() {
158
162
  const normalized = this.identityArguments;
@@ -206,6 +210,7 @@ export class Aggregate extends BasePgModel {
206
210
  owner: this.owner,
207
211
  comment: this.comment,
208
212
  privileges: this.privileges,
213
+ security_labels: this.security_labels,
209
214
  };
210
215
  }
211
216
  }
@@ -275,7 +280,20 @@ select
275
280
  )
276
281
  from lateral aclexplode(COALESCE(p.proacl, acldefault('f', p.proowner))) as x(grantor, grantee, privilege_type, is_grantable)
277
282
  ), '[]'
278
- ) as privileges
283
+ ) as privileges,
284
+ coalesce(
285
+ (
286
+ select json_agg(
287
+ json_build_object('provider', sl.provider, 'label', sl.label)
288
+ order by sl.provider
289
+ )
290
+ from pg_catalog.pg_seclabel sl
291
+ where sl.objoid = p.oid
292
+ and sl.classoid = 'pg_proc'::regclass
293
+ and sl.objsubid = 0
294
+ ),
295
+ '[]'::json
296
+ ) as security_labels
279
297
  from
280
298
  pg_catalog.pg_proc p
281
299
  inner join pg_catalog.pg_aggregate a on a.aggfnoid = p.oid
@@ -2,7 +2,7 @@ import { BaseChange } from "../../base.change.ts";
2
2
  import type { Aggregate } from "../aggregate.model.ts";
3
3
  declare abstract class BaseAggregateChange extends BaseChange {
4
4
  abstract readonly aggregate: Aggregate;
5
- abstract readonly scope: "object" | "comment" | "privilege";
5
+ abstract readonly scope: "object" | "comment" | "privilege" | "security_label";
6
6
  readonly objectType: "aggregate";
7
7
  }
8
8
  export declare abstract class CreateAggregateChange extends BaseAggregateChange {
@@ -0,0 +1,28 @@
1
+ import type { SecurityLabelProps } from "../../security-label.types.ts";
2
+ import type { Aggregate } from "../aggregate.model.ts";
3
+ import { CreateAggregateChange, DropAggregateChange } from "./aggregate.base.ts";
4
+ export type SecurityLabelAggregate = CreateSecurityLabelOnAggregate | DropSecurityLabelOnAggregate;
5
+ export declare class CreateSecurityLabelOnAggregate extends CreateAggregateChange {
6
+ readonly aggregate: Aggregate;
7
+ readonly securityLabel: SecurityLabelProps;
8
+ readonly scope: "security_label";
9
+ constructor(props: {
10
+ aggregate: Aggregate;
11
+ securityLabel: SecurityLabelProps;
12
+ });
13
+ get creates(): `securityLabel:${string}::provider:${string}`[];
14
+ get requires(): `aggregate:${string}`[];
15
+ serialize(): string;
16
+ }
17
+ export declare class DropSecurityLabelOnAggregate extends DropAggregateChange {
18
+ readonly aggregate: Aggregate;
19
+ readonly securityLabel: SecurityLabelProps;
20
+ readonly scope: "security_label";
21
+ constructor(props: {
22
+ aggregate: Aggregate;
23
+ securityLabel: SecurityLabelProps;
24
+ });
25
+ get drops(): `securityLabel:${string}::provider:${string}`[];
26
+ get requires(): (`securityLabel:${string}::provider:${string}` | `aggregate:${string}`)[];
27
+ serialize(): string;
28
+ }
@@ -0,0 +1,64 @@
1
+ import { quoteLiteral } from "../../base.change.js";
2
+ import { stableId } from "../../utils.js";
3
+ import { CreateAggregateChange, DropAggregateChange, } from "./aggregate.base.js";
4
+ function aggregateIdentity(a) {
5
+ return `${a.schema}.${a.name}(${a.identityArguments})`;
6
+ }
7
+ export class CreateSecurityLabelOnAggregate extends CreateAggregateChange {
8
+ aggregate;
9
+ securityLabel;
10
+ scope = "security_label";
11
+ constructor(props) {
12
+ super();
13
+ this.aggregate = props.aggregate;
14
+ this.securityLabel = props.securityLabel;
15
+ }
16
+ get creates() {
17
+ return [
18
+ stableId.securityLabel(this.aggregate.stableId, this.securityLabel.provider),
19
+ ];
20
+ }
21
+ get requires() {
22
+ return [this.aggregate.stableId];
23
+ }
24
+ serialize() {
25
+ return [
26
+ "SECURITY LABEL FOR",
27
+ this.securityLabel.provider,
28
+ "ON AGGREGATE",
29
+ aggregateIdentity(this.aggregate),
30
+ "IS",
31
+ quoteLiteral(this.securityLabel.label),
32
+ ].join(" ");
33
+ }
34
+ }
35
+ export class DropSecurityLabelOnAggregate extends DropAggregateChange {
36
+ aggregate;
37
+ securityLabel;
38
+ scope = "security_label";
39
+ constructor(props) {
40
+ super();
41
+ this.aggregate = props.aggregate;
42
+ this.securityLabel = props.securityLabel;
43
+ }
44
+ get drops() {
45
+ return [
46
+ stableId.securityLabel(this.aggregate.stableId, this.securityLabel.provider),
47
+ ];
48
+ }
49
+ get requires() {
50
+ return [
51
+ stableId.securityLabel(this.aggregate.stableId, this.securityLabel.provider),
52
+ this.aggregate.stableId,
53
+ ];
54
+ }
55
+ serialize() {
56
+ return [
57
+ "SECURITY LABEL FOR",
58
+ this.securityLabel.provider,
59
+ "ON AGGREGATE",
60
+ aggregateIdentity(this.aggregate),
61
+ "IS NULL",
62
+ ].join(" ");
63
+ }
64
+ }
@@ -3,5 +3,6 @@ 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
  /** Union of all aggregate-related change variants (`objectType: "aggregate"`). @category Change Types */
7
- export type AggregateChange = AlterAggregate | CommentAggregate | CreateAggregate | DropAggregate | AggregatePrivilege;
8
+ export type AggregateChange = AlterAggregate | CommentAggregate | CreateAggregate | DropAggregate | AggregatePrivilege | SecurityLabelAggregate;
@@ -16,6 +16,10 @@ export declare const columnPropsSchema: z.ZodObject<{
16
16
  collation: z.ZodNullable<z.ZodString>;
17
17
  default: z.ZodNullable<z.ZodString>;
18
18
  comment: z.ZodNullable<z.ZodString>;
19
+ security_labels: z.ZodOptional<z.ZodArray<z.ZodObject<{
20
+ provider: z.ZodString;
21
+ label: z.ZodString;
22
+ }, z.z.core.$strip>>>;
19
23
  }, z.z.core.$strip>;
20
24
  export type ColumnProps = z.infer<typeof columnPropsSchema>;
21
25
  export declare function normalizeColumns(columns: ColumnProps[]): {
@@ -34,6 +38,10 @@ export declare function normalizeColumns(columns: ColumnProps[]): {
34
38
  collation: string | null;
35
39
  default: string | null;
36
40
  comment: string | null;
41
+ security_labels?: {
42
+ provider: string;
43
+ label: string;
44
+ }[] | undefined;
37
45
  }[];
38
46
  /**
39
47
  * Interface for table-like objects that have columns (tables, views, materialized views).
@@ -1,4 +1,5 @@
1
1
  import z from "zod";
2
+ import { securityLabelPropsSchema } from "./security-label.types.js";
2
3
  import { deepEqual } from "./utils.js";
3
4
  export const columnPropsSchema = z.object({
4
5
  name: z.string(),
@@ -17,6 +18,7 @@ export const columnPropsSchema = z.object({
17
18
  collation: z.string().nullable(),
18
19
  default: z.string().nullable(),
19
20
  comment: z.string().nullable(),
21
+ security_labels: z.array(securityLabelPropsSchema).optional(),
20
22
  });
21
23
  export function normalizeColumns(columns) {
22
24
  return columns
@@ -2,7 +2,7 @@ import { BaseChange } from "../../base.change.ts";
2
2
  import type { Domain } from "../domain.model.ts";
3
3
  declare abstract class BaseDomainChange extends BaseChange {
4
4
  abstract readonly domain: Domain;
5
- abstract readonly scope: "object" | "comment" | "privilege";
5
+ abstract readonly scope: "object" | "comment" | "privilege" | "security_label";
6
6
  readonly objectType: "domain";
7
7
  }
8
8
  export declare abstract class CreateDomainChange extends BaseDomainChange {
@@ -0,0 +1,28 @@
1
+ import type { SecurityLabelProps } from "../../security-label.types.ts";
2
+ import type { Domain } from "../domain.model.ts";
3
+ import { CreateDomainChange, DropDomainChange } from "./domain.base.ts";
4
+ export type SecurityLabelDomain = CreateSecurityLabelOnDomain | DropSecurityLabelOnDomain;
5
+ export declare class CreateSecurityLabelOnDomain extends CreateDomainChange {
6
+ readonly domain: Domain;
7
+ readonly securityLabel: SecurityLabelProps;
8
+ readonly scope: "security_label";
9
+ constructor(props: {
10
+ domain: Domain;
11
+ securityLabel: SecurityLabelProps;
12
+ });
13
+ get creates(): `securityLabel:${string}::provider:${string}`[];
14
+ get requires(): `domain:${string}`[];
15
+ serialize(): string;
16
+ }
17
+ export declare class DropSecurityLabelOnDomain extends DropDomainChange {
18
+ readonly domain: Domain;
19
+ readonly securityLabel: SecurityLabelProps;
20
+ readonly scope: "security_label";
21
+ constructor(props: {
22
+ domain: Domain;
23
+ securityLabel: SecurityLabelProps;
24
+ });
25
+ get drops(): `securityLabel:${string}::provider:${string}`[];
26
+ get requires(): (`securityLabel:${string}::provider:${string}` | `domain:${string}`)[];
27
+ serialize(): string;
28
+ }
@@ -0,0 +1,61 @@
1
+ import { quoteLiteral } from "../../base.change.js";
2
+ import { stableId } from "../../utils.js";
3
+ import { CreateDomainChange, DropDomainChange } from "./domain.base.js";
4
+ export class CreateSecurityLabelOnDomain extends CreateDomainChange {
5
+ domain;
6
+ securityLabel;
7
+ scope = "security_label";
8
+ constructor(props) {
9
+ super();
10
+ this.domain = props.domain;
11
+ this.securityLabel = props.securityLabel;
12
+ }
13
+ get creates() {
14
+ return [
15
+ stableId.securityLabel(this.domain.stableId, this.securityLabel.provider),
16
+ ];
17
+ }
18
+ get requires() {
19
+ return [this.domain.stableId];
20
+ }
21
+ serialize() {
22
+ return [
23
+ "SECURITY LABEL FOR",
24
+ this.securityLabel.provider,
25
+ "ON DOMAIN",
26
+ `${this.domain.schema}.${this.domain.name}`,
27
+ "IS",
28
+ quoteLiteral(this.securityLabel.label),
29
+ ].join(" ");
30
+ }
31
+ }
32
+ export class DropSecurityLabelOnDomain extends DropDomainChange {
33
+ domain;
34
+ securityLabel;
35
+ scope = "security_label";
36
+ constructor(props) {
37
+ super();
38
+ this.domain = props.domain;
39
+ this.securityLabel = props.securityLabel;
40
+ }
41
+ get drops() {
42
+ return [
43
+ stableId.securityLabel(this.domain.stableId, this.securityLabel.provider),
44
+ ];
45
+ }
46
+ get requires() {
47
+ return [
48
+ stableId.securityLabel(this.domain.stableId, this.securityLabel.provider),
49
+ this.domain.stableId,
50
+ ];
51
+ }
52
+ serialize() {
53
+ return [
54
+ "SECURITY LABEL FOR",
55
+ this.securityLabel.provider,
56
+ "ON DOMAIN",
57
+ `${this.domain.schema}.${this.domain.name}`,
58
+ "IS NULL",
59
+ ].join(" ");
60
+ }
61
+ }
@@ -3,5 +3,6 @@ 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
  /** Union of all domain-related change variants (`objectType: "domain"`). @category Change Types */
7
- export type DomainChange = AlterDomain | CommentDomain | CreateDomain | DropDomain | DomainPrivilege;
8
+ export type DomainChange = AlterDomain | CommentDomain | CreateDomain | DropDomain | DomainPrivilege | SecurityLabelDomain;
@@ -1,10 +1,12 @@
1
1
  import { diffObjects } from "../base.diff.js";
2
2
  import { diffPrivileges, emitObjectPrivilegeChanges, filterPublicBuiltInDefaults, } from "../base.privilege-diff.js";
3
+ import { diffSecurityLabels } from "../security-label.types.js";
3
4
  import { AlterDomainAddConstraint, AlterDomainChangeOwner, AlterDomainDropConstraint, AlterDomainDropDefault, AlterDomainDropNotNull, AlterDomainSetDefault, AlterDomainSetNotNull, AlterDomainValidateConstraint, } from "./changes/domain.alter.js";
4
5
  import { CreateCommentOnDomain, DropCommentOnDomain, } from "./changes/domain.comment.js";
5
6
  import { CreateDomain } from "./changes/domain.create.js";
6
7
  import { DropDomain } from "./changes/domain.drop.js";
7
8
  import { GrantDomainPrivileges, RevokeDomainPrivileges, RevokeGrantOptionDomainPrivileges, } from "./changes/domain.privilege.js";
9
+ import { CreateSecurityLabelOnDomain, DropSecurityLabelOnDomain, } from "./changes/domain.security-label.js";
8
10
  /**
9
11
  * Diff two sets of domains from main and branch catalogs.
10
12
  *
@@ -30,6 +32,12 @@ export function diffDomains(ctx, main, branch) {
30
32
  if (newDomain.comment !== null) {
31
33
  changes.push(new CreateCommentOnDomain({ domain: newDomain }));
32
34
  }
35
+ for (const label of newDomain.security_labels) {
36
+ changes.push(new CreateSecurityLabelOnDomain({
37
+ domain: newDomain,
38
+ securityLabel: label,
39
+ }));
40
+ }
33
41
  // For unvalidated constraints, CREATE DOMAIN cannot specify NOT VALID.
34
42
  // Add them after creation and validate to match branch state semantics.
35
43
  // For already validated constraints, they are emitted inline in CREATE DOMAIN.
@@ -164,6 +172,14 @@ export function diffDomains(ctx, main, branch) {
164
172
  changes.push(new CreateCommentOnDomain({ domain: branchDomain }));
165
173
  }
166
174
  }
175
+ // SECURITY LABELS
176
+ changes.push(...diffSecurityLabels(mainDomain.security_labels, branchDomain.security_labels, (securityLabel) => new CreateSecurityLabelOnDomain({
177
+ domain: branchDomain,
178
+ securityLabel,
179
+ }), (securityLabel) => new DropSecurityLabelOnDomain({
180
+ domain: mainDomain,
181
+ securityLabel,
182
+ })));
167
183
  // PRIVILEGES
168
184
  // Filter out PUBLIC's built-in default USAGE privilege from main catalog
169
185
  // (PostgreSQL grants it automatically, so we shouldn't compare it)
@@ -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
  declare const domainConstraintPropsSchema: z.ZodObject<{
6
7
  name: z.ZodString;
7
8
  validated: z.ZodBoolean;
@@ -36,6 +37,10 @@ declare const domainPropsSchema: z.ZodObject<{
36
37
  grantable: z.ZodBoolean;
37
38
  columns: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
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 DomainConstraintProps = z.infer<typeof domainConstraintPropsSchema>;
41
46
  type DomainPrivilegeProps = PrivilegeProps;
@@ -61,6 +66,7 @@ export declare class Domain extends BasePgModel {
61
66
  readonly comment: DomainProps["comment"];
62
67
  readonly constraints: DomainConstraintProps[];
63
68
  readonly privileges: DomainPrivilegeProps[];
69
+ readonly security_labels: SecurityLabelProps[];
64
70
  constructor(props: DomainProps);
65
71
  get stableId(): `domain:${string}`;
66
72
  get identityFields(): {
@@ -91,6 +97,10 @@ export declare class Domain extends BasePgModel {
91
97
  grantable: boolean;
92
98
  columns?: string[] | null | undefined;
93
99
  }[];
100
+ security_labels: {
101
+ provider: string;
102
+ label: string;
103
+ }[];
94
104
  };
95
105
  }
96
106
  /**
@@ -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
  const domainConstraintPropsSchema = z.object({
6
7
  name: z.string(),
7
8
  validated: z.boolean(),
@@ -25,6 +26,7 @@ const domainPropsSchema = z.object({
25
26
  comment: z.string().nullable(),
26
27
  constraints: z.array(domainConstraintPropsSchema),
27
28
  privileges: z.array(privilegePropsSchema),
29
+ security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
28
30
  });
29
31
  /**
30
32
  * A domain is a user-defined data type that is based on another underlying type.
@@ -47,6 +49,7 @@ export class Domain extends BasePgModel {
47
49
  comment;
48
50
  constraints;
49
51
  privileges;
52
+ security_labels;
50
53
  constructor(props) {
51
54
  super();
52
55
  // Identity fields
@@ -66,6 +69,7 @@ export class Domain extends BasePgModel {
66
69
  this.comment = props.comment;
67
70
  this.constraints = props.constraints;
68
71
  this.privileges = props.privileges;
72
+ this.security_labels = props.security_labels ?? [];
69
73
  }
70
74
  get stableId() {
71
75
  return `domain:${this.schema}.${this.name}`;
@@ -90,6 +94,7 @@ export class Domain extends BasePgModel {
90
94
  comment: this.comment,
91
95
  constraints: this.constraints,
92
96
  privileges: this.privileges,
97
+ security_labels: this.security_labels,
93
98
  };
94
99
  }
95
100
  }
@@ -152,7 +157,20 @@ export async function extractDomains(pool) {
152
157
  )
153
158
  from lateral aclexplode(COALESCE(t.typacl, acldefault('T', t.typowner))) as x(grantor, grantee, privilege_type, is_grantable)
154
159
  ), '[]'
155
- ) as privileges
160
+ ) as privileges,
161
+ coalesce(
162
+ (
163
+ select json_agg(
164
+ json_build_object('provider', sl.provider, 'label', sl.label)
165
+ order by sl.provider
166
+ )
167
+ from pg_catalog.pg_seclabel sl
168
+ where sl.objoid = t.oid
169
+ and sl.classoid = 'pg_type'::regclass
170
+ and sl.objsubid = 0
171
+ ),
172
+ '[]'::json
173
+ ) as security_labels
156
174
  from
157
175
  pg_catalog.pg_type t
158
176
  inner join pg_catalog.pg_type bt on bt.oid = t.typbasetype
@@ -2,7 +2,7 @@ import { BaseChange } from "../../base.change.ts";
2
2
  import type { EventTrigger } from "../event-trigger.model.ts";
3
3
  declare abstract class BaseEventTriggerChange extends BaseChange {
4
4
  abstract readonly eventTrigger: EventTrigger;
5
- abstract readonly scope: "object" | "comment";
5
+ abstract readonly scope: "object" | "comment" | "security_label";
6
6
  readonly objectType: "event_trigger";
7
7
  }
8
8
  export declare abstract class CreateEventTriggerChange extends BaseEventTriggerChange {
@@ -0,0 +1,28 @@
1
+ import type { SecurityLabelProps } from "../../security-label.types.ts";
2
+ import type { EventTrigger } from "../event-trigger.model.ts";
3
+ import { CreateEventTriggerChange, DropEventTriggerChange } from "./event-trigger.base.ts";
4
+ export type SecurityLabelEventTrigger = CreateSecurityLabelOnEventTrigger | DropSecurityLabelOnEventTrigger;
5
+ export declare class CreateSecurityLabelOnEventTrigger extends CreateEventTriggerChange {
6
+ readonly eventTrigger: EventTrigger;
7
+ readonly securityLabel: SecurityLabelProps;
8
+ readonly scope: "security_label";
9
+ constructor(props: {
10
+ eventTrigger: EventTrigger;
11
+ securityLabel: SecurityLabelProps;
12
+ });
13
+ get creates(): `securityLabel:${string}::provider:${string}`[];
14
+ get requires(): `eventTrigger:${string}`[];
15
+ serialize(): string;
16
+ }
17
+ export declare class DropSecurityLabelOnEventTrigger extends DropEventTriggerChange {
18
+ readonly eventTrigger: EventTrigger;
19
+ readonly securityLabel: SecurityLabelProps;
20
+ readonly scope: "security_label";
21
+ constructor(props: {
22
+ eventTrigger: EventTrigger;
23
+ securityLabel: SecurityLabelProps;
24
+ });
25
+ get drops(): `securityLabel:${string}::provider:${string}`[];
26
+ get requires(): (`securityLabel:${string}::provider:${string}` | `eventTrigger:${string}`)[];
27
+ serialize(): string;
28
+ }