@supabase/pg-delta 1.0.0-alpha.21 → 1.0.0-alpha.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/catalog.diff.js +4 -3
- package/dist/core/catalog.model.d.ts +8 -1
- package/dist/core/catalog.model.js +10 -8
- package/dist/core/expand-replace-dependencies.js +23 -0
- package/dist/core/integrations/filter/flatten.js +13 -0
- package/dist/core/objects/aggregate/aggregate.diff.js +16 -0
- package/dist/core/objects/aggregate/aggregate.model.d.ts +10 -0
- package/dist/core/objects/aggregate/aggregate.model.js +19 -1
- package/dist/core/objects/aggregate/changes/aggregate.base.d.ts +1 -1
- package/dist/core/objects/aggregate/changes/aggregate.security-label.d.ts +28 -0
- package/dist/core/objects/aggregate/changes/aggregate.security-label.js +64 -0
- package/dist/core/objects/aggregate/changes/aggregate.types.d.ts +2 -1
- package/dist/core/objects/base.model.d.ts +8 -0
- package/dist/core/objects/base.model.js +2 -0
- package/dist/core/objects/domain/changes/domain.base.d.ts +1 -1
- package/dist/core/objects/domain/changes/domain.security-label.d.ts +28 -0
- package/dist/core/objects/domain/changes/domain.security-label.js +61 -0
- package/dist/core/objects/domain/changes/domain.types.d.ts +2 -1
- package/dist/core/objects/domain/domain.diff.js +16 -0
- package/dist/core/objects/domain/domain.model.d.ts +10 -0
- package/dist/core/objects/domain/domain.model.js +19 -1
- package/dist/core/objects/event-trigger/changes/event-trigger.base.d.ts +1 -1
- package/dist/core/objects/event-trigger/changes/event-trigger.security-label.d.ts +28 -0
- package/dist/core/objects/event-trigger/changes/event-trigger.security-label.js +61 -0
- package/dist/core/objects/event-trigger/changes/event-trigger.types.d.ts +2 -1
- package/dist/core/objects/event-trigger/event-trigger.diff.js +16 -0
- package/dist/core/objects/event-trigger/event-trigger.model.d.ts +10 -0
- package/dist/core/objects/event-trigger/event-trigger.model.js +19 -1
- package/dist/core/objects/extract-with-retry.d.ts +36 -0
- package/dist/core/objects/extract-with-retry.js +51 -0
- package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.d.ts +1 -1
- package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.d.ts +28 -0
- package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.js +61 -0
- package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.d.ts +2 -1
- package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.js +16 -0
- package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.d.ts +22 -0
- package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.js +20 -1
- package/dist/core/objects/index/index.diff.js +0 -1
- package/dist/core/objects/index/index.model.d.ts +2 -3
- package/dist/core/objects/index/index.model.js +17 -6
- package/dist/core/objects/materialized-view/changes/materialized-view.base.d.ts +1 -1
- package/dist/core/objects/materialized-view/changes/materialized-view.security-label.d.ts +28 -0
- package/dist/core/objects/materialized-view/changes/materialized-view.security-label.js +61 -0
- package/dist/core/objects/materialized-view/changes/materialized-view.types.d.ts +2 -1
- package/dist/core/objects/materialized-view/materialized-view.diff.js +18 -0
- package/dist/core/objects/materialized-view/materialized-view.model.d.ts +24 -1
- package/dist/core/objects/materialized-view/materialized-view.model.js +40 -5
- package/dist/core/objects/procedure/changes/procedure.base.d.ts +1 -1
- package/dist/core/objects/procedure/changes/procedure.security-label.d.ts +28 -0
- package/dist/core/objects/procedure/changes/procedure.security-label.js +69 -0
- package/dist/core/objects/procedure/changes/procedure.types.d.ts +2 -1
- package/dist/core/objects/procedure/procedure.diff.js +16 -0
- package/dist/core/objects/procedure/procedure.model.d.ts +12 -1
- package/dist/core/objects/procedure/procedure.model.js +39 -5
- package/dist/core/objects/publication/changes/publication.base.d.ts +1 -1
- package/dist/core/objects/publication/changes/publication.security-label.d.ts +28 -0
- package/dist/core/objects/publication/changes/publication.security-label.js +61 -0
- package/dist/core/objects/publication/changes/publication.types.d.ts +2 -1
- package/dist/core/objects/publication/publication.diff.js +16 -0
- package/dist/core/objects/publication/publication.model.d.ts +14 -0
- package/dist/core/objects/publication/publication.model.js +20 -1
- package/dist/core/objects/rls-policy/rls-policy.diff.js +13 -1
- package/dist/core/objects/role/changes/role.base.d.ts +1 -1
- package/dist/core/objects/role/changes/role.security-label.d.ts +28 -0
- package/dist/core/objects/role/changes/role.security-label.js +61 -0
- package/dist/core/objects/role/changes/role.types.d.ts +2 -1
- package/dist/core/objects/role/role.diff.js +16 -0
- package/dist/core/objects/role/role.model.d.ts +10 -0
- package/dist/core/objects/role/role.model.js +29 -0
- package/dist/core/objects/rule/rule.model.d.ts +2 -1
- package/dist/core/objects/rule/rule.model.js +20 -3
- package/dist/core/objects/schema/changes/schema.base.d.ts +1 -1
- package/dist/core/objects/schema/changes/schema.security-label.d.ts +28 -0
- package/dist/core/objects/schema/changes/schema.security-label.js +61 -0
- package/dist/core/objects/schema/changes/schema.types.d.ts +2 -1
- package/dist/core/objects/schema/schema.diff.js +24 -1
- package/dist/core/objects/schema/schema.model.d.ts +10 -0
- package/dist/core/objects/schema/schema.model.js +18 -1
- package/dist/core/objects/security-label.types.d.ts +20 -0
- package/dist/core/objects/security-label.types.js +46 -0
- package/dist/core/objects/sequence/changes/sequence.base.d.ts +1 -1
- package/dist/core/objects/sequence/changes/sequence.security-label.d.ts +28 -0
- package/dist/core/objects/sequence/changes/sequence.security-label.js +61 -0
- package/dist/core/objects/sequence/changes/sequence.types.d.ts +2 -1
- package/dist/core/objects/sequence/sequence.diff.d.ts +2 -1
- package/dist/core/objects/sequence/sequence.diff.js +44 -4
- package/dist/core/objects/sequence/sequence.model.d.ts +10 -0
- package/dist/core/objects/sequence/sequence.model.js +19 -1
- package/dist/core/objects/subscription/changes/subscription.base.d.ts +1 -1
- package/dist/core/objects/subscription/changes/subscription.security-label.d.ts +28 -0
- package/dist/core/objects/subscription/changes/subscription.security-label.js +61 -0
- package/dist/core/objects/subscription/changes/subscription.types.d.ts +2 -1
- package/dist/core/objects/subscription/subscription.diff.js +16 -0
- package/dist/core/objects/subscription/subscription.model.d.ts +10 -0
- package/dist/core/objects/subscription/subscription.model.js +19 -1
- package/dist/core/objects/table/changes/table.alter.d.ts +12 -1
- package/dist/core/objects/table/changes/table.alter.js +20 -2
- package/dist/core/objects/table/changes/table.base.d.ts +1 -1
- package/dist/core/objects/table/changes/table.security-label.d.ts +63 -0
- package/dist/core/objects/table/changes/table.security-label.js +134 -0
- package/dist/core/objects/table/changes/table.types.d.ts +2 -1
- package/dist/core/objects/table/table.diff.js +68 -15
- package/dist/core/objects/table/table.model.d.ts +36 -1
- package/dist/core/objects/table/table.model.js +74 -7
- package/dist/core/objects/trigger/trigger.model.d.ts +2 -1
- package/dist/core/objects/trigger/trigger.model.js +20 -4
- package/dist/core/objects/type/composite-type/changes/composite-type.base.d.ts +1 -1
- package/dist/core/objects/type/composite-type/changes/composite-type.security-label.d.ts +28 -0
- package/dist/core/objects/type/composite-type/changes/composite-type.security-label.js +61 -0
- package/dist/core/objects/type/composite-type/changes/composite-type.types.d.ts +2 -1
- package/dist/core/objects/type/composite-type/composite-type.diff.js +16 -0
- package/dist/core/objects/type/composite-type/composite-type.model.d.ts +22 -0
- package/dist/core/objects/type/composite-type/composite-type.model.js +22 -2
- package/dist/core/objects/type/enum/changes/enum.base.d.ts +1 -1
- package/dist/core/objects/type/enum/changes/enum.security-label.d.ts +28 -0
- package/dist/core/objects/type/enum/changes/enum.security-label.js +61 -0
- package/dist/core/objects/type/enum/changes/enum.types.d.ts +2 -1
- package/dist/core/objects/type/enum/enum.diff.js +16 -0
- package/dist/core/objects/type/enum/enum.model.d.ts +10 -0
- package/dist/core/objects/type/enum/enum.model.js +20 -1
- package/dist/core/objects/type/range/changes/range.base.d.ts +1 -1
- package/dist/core/objects/type/range/changes/range.security-label.d.ts +28 -0
- package/dist/core/objects/type/range/changes/range.security-label.js +61 -0
- package/dist/core/objects/type/range/changes/range.types.d.ts +2 -1
- package/dist/core/objects/type/range/range.diff.js +16 -0
- package/dist/core/objects/type/range/range.model.d.ts +10 -0
- package/dist/core/objects/type/range/range.model.js +19 -1
- package/dist/core/objects/utils.d.ts +2 -0
- package/dist/core/objects/utils.js +6 -0
- package/dist/core/objects/view/changes/view.base.d.ts +1 -1
- package/dist/core/objects/view/changes/view.security-label.d.ts +28 -0
- package/dist/core/objects/view/changes/view.security-label.js +61 -0
- package/dist/core/objects/view/changes/view.types.d.ts +2 -1
- package/dist/core/objects/view/view.diff.js +13 -0
- package/dist/core/objects/view/view.model.d.ts +28 -1
- package/dist/core/objects/view/view.model.js +40 -5
- package/dist/core/plan/create.js +3 -1
- package/dist/core/plan/sql-format/fixtures.js +1 -0
- package/dist/core/plan/types.d.ts +8 -0
- package/dist/core/{post-diff-cycle-breaking.d.ts → post-diff-normalization.d.ts} +8 -1
- package/dist/core/post-diff-normalization.js +202 -0
- package/dist/core/sort/cycle-breakers.js +1 -1
- package/dist/core/sort/utils.d.ts +10 -0
- package/dist/core/sort/utils.js +28 -0
- package/package.json +1 -1
- package/src/core/catalog.diff.ts +4 -2
- package/src/core/catalog.model.ts +21 -8
- package/src/core/expand-replace-dependencies.test.ts +131 -0
- package/src/core/expand-replace-dependencies.ts +24 -0
- package/src/core/integrations/filter/dsl.test.ts +27 -0
- package/src/core/integrations/filter/flatten.ts +16 -0
- package/src/core/objects/aggregate/aggregate.diff.ts +33 -0
- package/src/core/objects/aggregate/aggregate.model.ts +22 -1
- package/src/core/objects/aggregate/changes/aggregate.base.ts +5 -1
- package/src/core/objects/aggregate/changes/aggregate.security-label.ts +99 -0
- package/src/core/objects/aggregate/changes/aggregate.types.ts +3 -1
- package/src/core/objects/base.model.ts +2 -0
- package/src/core/objects/domain/changes/domain.base.ts +5 -1
- package/src/core/objects/domain/changes/domain.security-label.test.ts +56 -0
- package/src/core/objects/domain/changes/domain.security-label.ts +77 -0
- package/src/core/objects/domain/changes/domain.types.ts +3 -1
- package/src/core/objects/domain/domain.diff.ts +33 -0
- package/src/core/objects/domain/domain.model.ts +22 -1
- package/src/core/objects/event-trigger/changes/event-trigger.base.ts +1 -1
- package/src/core/objects/event-trigger/changes/event-trigger.security-label.ts +95 -0
- package/src/core/objects/event-trigger/changes/event-trigger.types.ts +3 -1
- package/src/core/objects/event-trigger/event-trigger.diff.ts +33 -0
- package/src/core/objects/event-trigger/event-trigger.model.ts +22 -1
- package/src/core/objects/extract-with-retry.test.ts +143 -0
- package/src/core/objects/extract-with-retry.ts +87 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.ts +5 -1
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.ts +95 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.ts +3 -1
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +33 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +24 -1
- package/src/core/objects/index/index.diff.ts +0 -1
- package/src/core/objects/index/index.model.test.ts +37 -1
- package/src/core/objects/index/index.model.ts +25 -6
- package/src/core/objects/materialized-view/changes/materialized-view.base.ts +5 -1
- package/src/core/objects/materialized-view/changes/materialized-view.security-label.test.ts +63 -0
- package/src/core/objects/materialized-view/changes/materialized-view.security-label.ts +95 -0
- package/src/core/objects/materialized-view/changes/materialized-view.types.ts +3 -1
- package/src/core/objects/materialized-view/materialized-view.diff.ts +37 -0
- package/src/core/objects/materialized-view/materialized-view.model.test.ts +93 -0
- package/src/core/objects/materialized-view/materialized-view.model.ts +52 -8
- package/src/core/objects/procedure/changes/procedure.base.ts +5 -1
- package/src/core/objects/procedure/changes/procedure.security-label.ts +105 -0
- package/src/core/objects/procedure/changes/procedure.types.ts +3 -1
- package/src/core/objects/procedure/procedure.diff.ts +33 -0
- package/src/core/objects/procedure/procedure.model.test.ts +117 -0
- package/src/core/objects/procedure/procedure.model.ts +51 -7
- package/src/core/objects/publication/changes/publication.base.ts +1 -1
- package/src/core/objects/publication/changes/publication.security-label.ts +95 -0
- package/src/core/objects/publication/changes/publication.types.ts +3 -1
- package/src/core/objects/publication/publication.diff.ts +33 -0
- package/src/core/objects/publication/publication.model.ts +24 -1
- package/src/core/objects/rls-policy/rls-policy.diff.ts +19 -1
- package/src/core/objects/role/changes/role.base.ts +2 -1
- package/src/core/objects/role/changes/role.security-label.ts +77 -0
- package/src/core/objects/role/changes/role.types.ts +3 -1
- package/src/core/objects/role/role.diff.ts +33 -0
- package/src/core/objects/role/role.model.ts +32 -0
- package/src/core/objects/rule/rule.model.test.ts +99 -0
- package/src/core/objects/rule/rule.model.ts +28 -4
- package/src/core/objects/schema/changes/schema.alter.test.ts +1 -0
- package/src/core/objects/schema/changes/schema.base.ts +5 -1
- package/src/core/objects/schema/changes/schema.create.test.ts +1 -0
- package/src/core/objects/schema/changes/schema.drop.test.ts +1 -0
- package/src/core/objects/schema/changes/schema.security-label.test.ts +76 -0
- package/src/core/objects/schema/changes/schema.security-label.ts +77 -0
- package/src/core/objects/schema/changes/schema.types.ts +3 -1
- package/src/core/objects/schema/schema.diff.test.ts +1 -0
- package/src/core/objects/schema/schema.diff.ts +43 -1
- package/src/core/objects/schema/schema.model.ts +21 -1
- package/src/core/objects/security-label.types.test.ts +106 -0
- package/src/core/objects/security-label.types.ts +61 -0
- package/src/core/objects/sequence/changes/sequence.base.ts +5 -1
- package/src/core/objects/sequence/changes/sequence.security-label.test.ts +58 -0
- package/src/core/objects/sequence/changes/sequence.security-label.ts +92 -0
- package/src/core/objects/sequence/changes/sequence.types.ts +3 -1
- package/src/core/objects/sequence/sequence.diff.test.ts +87 -0
- package/src/core/objects/sequence/sequence.diff.ts +64 -6
- package/src/core/objects/sequence/sequence.model.ts +22 -1
- package/src/core/objects/subscription/changes/subscription.base.ts +1 -1
- package/src/core/objects/subscription/changes/subscription.security-label.ts +95 -0
- package/src/core/objects/subscription/changes/subscription.types.ts +3 -1
- package/src/core/objects/subscription/subscription.diff.ts +33 -0
- package/src/core/objects/subscription/subscription.model.ts +22 -1
- package/src/core/objects/table/changes/table.alter.test.ts +13 -21
- package/src/core/objects/table/changes/table.alter.ts +30 -3
- package/src/core/objects/table/changes/table.base.ts +5 -1
- package/src/core/objects/table/changes/table.security-label.test.ts +140 -0
- package/src/core/objects/table/changes/table.security-label.ts +183 -0
- package/src/core/objects/table/changes/table.types.ts +3 -1
- package/src/core/objects/table/table.diff.ts +111 -19
- package/src/core/objects/table/table.model.test.ts +209 -0
- package/src/core/objects/table/table.model.ts +94 -9
- package/src/core/objects/trigger/trigger.model.test.ts +113 -0
- package/src/core/objects/trigger/trigger.model.ts +28 -5
- package/src/core/objects/type/composite-type/changes/composite-type.base.ts +5 -1
- package/src/core/objects/type/composite-type/changes/composite-type.security-label.ts +95 -0
- package/src/core/objects/type/composite-type/changes/composite-type.types.ts +3 -1
- package/src/core/objects/type/composite-type/composite-type.diff.ts +33 -0
- package/src/core/objects/type/composite-type/composite-type.model.ts +26 -2
- package/src/core/objects/type/enum/changes/enum.base.ts +5 -1
- package/src/core/objects/type/enum/changes/enum.security-label.ts +77 -0
- package/src/core/objects/type/enum/changes/enum.types.ts +3 -1
- package/src/core/objects/type/enum/enum.diff.ts +33 -0
- package/src/core/objects/type/enum/enum.model.ts +25 -1
- package/src/core/objects/type/range/changes/range.base.ts +5 -1
- package/src/core/objects/type/range/changes/range.security-label.ts +77 -0
- package/src/core/objects/type/range/changes/range.types.ts +3 -1
- package/src/core/objects/type/range/range.diff.ts +33 -0
- package/src/core/objects/type/range/range.model.ts +22 -1
- package/src/core/objects/utils.ts +6 -0
- package/src/core/objects/view/changes/view.base.ts +5 -1
- package/src/core/objects/view/changes/view.security-label.test.ts +64 -0
- package/src/core/objects/view/changes/view.security-label.ts +77 -0
- package/src/core/objects/view/changes/view.types.ts +3 -1
- package/src/core/objects/view/view.diff.ts +31 -0
- package/src/core/objects/view/view.model.test.ts +90 -0
- package/src/core/objects/view/view.model.ts +53 -7
- package/src/core/plan/create.ts +3 -1
- package/src/core/plan/sql-format/fixtures.ts +1 -0
- package/src/core/plan/types.ts +8 -0
- package/src/core/{post-diff-cycle-breaking.test.ts → post-diff-normalization.test.ts} +168 -4
- package/src/core/post-diff-normalization.ts +260 -0
- package/src/core/sort/cycle-breakers.ts +1 -1
- package/src/core/sort/utils.ts +38 -0
- package/dist/core/post-diff-cycle-breaking.js +0 -100
- package/src/core/post-diff-cycle-breaking.ts +0 -138
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { quoteLiteral } from "../../base.change.js";
|
|
2
|
+
import { stableId } from "../../utils.js";
|
|
3
|
+
import { CreateEventTriggerChange, DropEventTriggerChange, } from "./event-trigger.base.js";
|
|
4
|
+
export class CreateSecurityLabelOnEventTrigger extends CreateEventTriggerChange {
|
|
5
|
+
eventTrigger;
|
|
6
|
+
securityLabel;
|
|
7
|
+
scope = "security_label";
|
|
8
|
+
constructor(props) {
|
|
9
|
+
super();
|
|
10
|
+
this.eventTrigger = props.eventTrigger;
|
|
11
|
+
this.securityLabel = props.securityLabel;
|
|
12
|
+
}
|
|
13
|
+
get creates() {
|
|
14
|
+
return [
|
|
15
|
+
stableId.securityLabel(this.eventTrigger.stableId, this.securityLabel.provider),
|
|
16
|
+
];
|
|
17
|
+
}
|
|
18
|
+
get requires() {
|
|
19
|
+
return [this.eventTrigger.stableId];
|
|
20
|
+
}
|
|
21
|
+
serialize() {
|
|
22
|
+
return [
|
|
23
|
+
"SECURITY LABEL FOR",
|
|
24
|
+
this.securityLabel.provider,
|
|
25
|
+
"ON EVENT TRIGGER",
|
|
26
|
+
this.eventTrigger.name,
|
|
27
|
+
"IS",
|
|
28
|
+
quoteLiteral(this.securityLabel.label),
|
|
29
|
+
].join(" ");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export class DropSecurityLabelOnEventTrigger extends DropEventTriggerChange {
|
|
33
|
+
eventTrigger;
|
|
34
|
+
securityLabel;
|
|
35
|
+
scope = "security_label";
|
|
36
|
+
constructor(props) {
|
|
37
|
+
super();
|
|
38
|
+
this.eventTrigger = props.eventTrigger;
|
|
39
|
+
this.securityLabel = props.securityLabel;
|
|
40
|
+
}
|
|
41
|
+
get drops() {
|
|
42
|
+
return [
|
|
43
|
+
stableId.securityLabel(this.eventTrigger.stableId, this.securityLabel.provider),
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
get requires() {
|
|
47
|
+
return [
|
|
48
|
+
stableId.securityLabel(this.eventTrigger.stableId, this.securityLabel.provider),
|
|
49
|
+
this.eventTrigger.stableId,
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
serialize() {
|
|
53
|
+
return [
|
|
54
|
+
"SECURITY LABEL FOR",
|
|
55
|
+
this.securityLabel.provider,
|
|
56
|
+
"ON EVENT TRIGGER",
|
|
57
|
+
this.eventTrigger.name,
|
|
58
|
+
"IS NULL",
|
|
59
|
+
].join(" ");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -2,5 +2,6 @@ import type { AlterEventTrigger } from "./event-trigger.alter.ts";
|
|
|
2
2
|
import type { CommentEventTrigger } from "./event-trigger.comment.ts";
|
|
3
3
|
import type { CreateEventTrigger } from "./event-trigger.create.ts";
|
|
4
4
|
import type { DropEventTrigger } from "./event-trigger.drop.ts";
|
|
5
|
+
import type { SecurityLabelEventTrigger } from "./event-trigger.security-label.ts";
|
|
5
6
|
/** Union of all event-trigger-related change variants (`objectType: "event_trigger"`). @category Change Types */
|
|
6
|
-
export type EventTriggerChange = AlterEventTrigger | CommentEventTrigger | CreateEventTrigger | DropEventTrigger;
|
|
7
|
+
export type EventTriggerChange = AlterEventTrigger | CommentEventTrigger | CreateEventTrigger | DropEventTrigger | SecurityLabelEventTrigger;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { diffObjects } from "../base.diff.js";
|
|
2
|
+
import { diffSecurityLabels } from "../security-label.types.js";
|
|
2
3
|
import { deepEqual, hasNonAlterableChanges } from "../utils.js";
|
|
3
4
|
import { AlterEventTriggerChangeOwner, AlterEventTriggerSetEnabled, } from "./changes/event-trigger.alter.js";
|
|
4
5
|
import { CreateCommentOnEventTrigger, DropCommentOnEventTrigger, } from "./changes/event-trigger.comment.js";
|
|
5
6
|
import { CreateEventTrigger } from "./changes/event-trigger.create.js";
|
|
6
7
|
import { DropEventTrigger } from "./changes/event-trigger.drop.js";
|
|
8
|
+
import { CreateSecurityLabelOnEventTrigger, DropSecurityLabelOnEventTrigger, } from "./changes/event-trigger.security-label.js";
|
|
7
9
|
/**
|
|
8
10
|
* Diff two sets of event triggers from main and branch catalogs.
|
|
9
11
|
*
|
|
@@ -29,6 +31,12 @@ export function diffEventTriggers(ctx, main, branch) {
|
|
|
29
31
|
if (eventTrigger.comment !== null) {
|
|
30
32
|
changes.push(new CreateCommentOnEventTrigger({ eventTrigger }));
|
|
31
33
|
}
|
|
34
|
+
for (const label of eventTrigger.security_labels) {
|
|
35
|
+
changes.push(new CreateSecurityLabelOnEventTrigger({
|
|
36
|
+
eventTrigger,
|
|
37
|
+
securityLabel: label,
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
32
40
|
}
|
|
33
41
|
for (const eventTriggerId of dropped) {
|
|
34
42
|
changes.push(new DropEventTrigger({ eventTrigger: main[eventTriggerId] }));
|
|
@@ -76,6 +84,14 @@ export function diffEventTriggers(ctx, main, branch) {
|
|
|
76
84
|
}));
|
|
77
85
|
}
|
|
78
86
|
}
|
|
87
|
+
// SECURITY LABELS
|
|
88
|
+
changes.push(...diffSecurityLabels(mainEventTrigger.security_labels, branchEventTrigger.security_labels, (securityLabel) => new CreateSecurityLabelOnEventTrigger({
|
|
89
|
+
eventTrigger: branchEventTrigger,
|
|
90
|
+
securityLabel,
|
|
91
|
+
}), (securityLabel) => new DropSecurityLabelOnEventTrigger({
|
|
92
|
+
eventTrigger: mainEventTrigger,
|
|
93
|
+
securityLabel,
|
|
94
|
+
})));
|
|
79
95
|
}
|
|
80
96
|
return changes;
|
|
81
97
|
}
|
|
@@ -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 eventTriggerPropsSchema: z.ZodObject<{
|
|
5
6
|
name: z.ZodString;
|
|
6
7
|
event: z.ZodString;
|
|
@@ -15,6 +16,10 @@ declare const eventTriggerPropsSchema: z.ZodObject<{
|
|
|
15
16
|
tags: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
16
17
|
owner: z.ZodString;
|
|
17
18
|
comment: z.ZodNullable<z.ZodString>;
|
|
19
|
+
security_labels: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
20
|
+
provider: z.ZodString;
|
|
21
|
+
label: z.ZodString;
|
|
22
|
+
}, z.z.core.$strip>>>>;
|
|
18
23
|
}, z.z.core.$strip>;
|
|
19
24
|
export type EventTriggerProps = z.infer<typeof eventTriggerPropsSchema>;
|
|
20
25
|
export declare class EventTrigger extends BasePgModel {
|
|
@@ -26,6 +31,7 @@ export declare class EventTrigger extends BasePgModel {
|
|
|
26
31
|
readonly tags: EventTriggerProps["tags"];
|
|
27
32
|
readonly owner: EventTriggerProps["owner"];
|
|
28
33
|
readonly comment: EventTriggerProps["comment"];
|
|
34
|
+
readonly security_labels: SecurityLabelProps[];
|
|
29
35
|
constructor(props: EventTriggerProps);
|
|
30
36
|
get stableId(): `eventTrigger:${string}`;
|
|
31
37
|
get identityFields(): {
|
|
@@ -39,6 +45,10 @@ export declare class EventTrigger extends BasePgModel {
|
|
|
39
45
|
tags: string[] | null;
|
|
40
46
|
owner: string;
|
|
41
47
|
comment: string | null;
|
|
48
|
+
security_labels: {
|
|
49
|
+
provider: string;
|
|
50
|
+
label: string;
|
|
51
|
+
}[];
|
|
42
52
|
};
|
|
43
53
|
}
|
|
44
54
|
export declare function extractEventTriggers(pool: Pool): Promise<EventTrigger[]>;
|
|
@@ -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 EventTriggerEnabledSchema = z.enum([
|
|
5
6
|
"O", // ORIGIN - trigger fires in origin mode
|
|
6
7
|
"D", // DISABLED - trigger does not fire
|
|
@@ -16,6 +17,7 @@ const eventTriggerPropsSchema = z.object({
|
|
|
16
17
|
tags: z.array(z.string()).nullable(),
|
|
17
18
|
owner: z.string(),
|
|
18
19
|
comment: z.string().nullable(),
|
|
20
|
+
security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
|
|
19
21
|
});
|
|
20
22
|
export class EventTrigger extends BasePgModel {
|
|
21
23
|
name;
|
|
@@ -26,6 +28,7 @@ export class EventTrigger extends BasePgModel {
|
|
|
26
28
|
tags;
|
|
27
29
|
owner;
|
|
28
30
|
comment;
|
|
31
|
+
security_labels;
|
|
29
32
|
constructor(props) {
|
|
30
33
|
super();
|
|
31
34
|
// Identity fields
|
|
@@ -38,6 +41,7 @@ export class EventTrigger extends BasePgModel {
|
|
|
38
41
|
this.tags = props.tags;
|
|
39
42
|
this.owner = props.owner;
|
|
40
43
|
this.comment = props.comment;
|
|
44
|
+
this.security_labels = props.security_labels ?? [];
|
|
41
45
|
}
|
|
42
46
|
get stableId() {
|
|
43
47
|
return `eventTrigger:${this.name}`;
|
|
@@ -56,6 +60,7 @@ export class EventTrigger extends BasePgModel {
|
|
|
56
60
|
tags: this.tags,
|
|
57
61
|
owner: this.owner,
|
|
58
62
|
comment: this.comment,
|
|
63
|
+
security_labels: this.security_labels,
|
|
59
64
|
};
|
|
60
65
|
}
|
|
61
66
|
}
|
|
@@ -75,7 +80,20 @@ select
|
|
|
75
80
|
et.evtenabled as enabled,
|
|
76
81
|
et.evttags as tags,
|
|
77
82
|
et.evtowner::regrole::text as owner,
|
|
78
|
-
obj_description(et.oid, 'pg_event_trigger') as comment
|
|
83
|
+
obj_description(et.oid, 'pg_event_trigger') as comment,
|
|
84
|
+
coalesce(
|
|
85
|
+
(
|
|
86
|
+
select json_agg(
|
|
87
|
+
json_build_object('provider', sl.provider, 'label', sl.label)
|
|
88
|
+
order by sl.provider
|
|
89
|
+
)
|
|
90
|
+
from pg_catalog.pg_seclabel sl
|
|
91
|
+
where sl.objoid = et.oid
|
|
92
|
+
and sl.classoid = 'pg_event_trigger'::regclass
|
|
93
|
+
and sl.objsubid = 0
|
|
94
|
+
),
|
|
95
|
+
'[]'::json
|
|
96
|
+
) as security_labels
|
|
79
97
|
from pg_catalog.pg_event_trigger et
|
|
80
98
|
join pg_catalog.pg_proc p on p.oid = et.evtfoid
|
|
81
99
|
left join extension_oids e on e.objid = et.oid
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export interface ExtractRetryOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Number of retry attempts to make when a `pg_get_*def()` call returns NULL
|
|
4
|
+
* for at least one row. Total attempts is `retries + 1`. Negative values are
|
|
5
|
+
* clamped to 0. When this option is undefined the value is read from the
|
|
6
|
+
* `PGDELTA_EXTRACT_RETRIES` environment variable, falling back to a default
|
|
7
|
+
* of 1 (i.e. the first attempt plus one retry, 2 attempts total).
|
|
8
|
+
*/
|
|
9
|
+
retries?: number;
|
|
10
|
+
/**
|
|
11
|
+
* Delay between retry attempts in milliseconds; the actual wait is
|
|
12
|
+
* `backoffMs * attemptNumber` (linear). Defaults to 50. Set to 0 in tests.
|
|
13
|
+
*/
|
|
14
|
+
backoffMs?: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function resolveExtractRetries(option?: number): number;
|
|
17
|
+
/**
|
|
18
|
+
* Runs `query()` up to `retries + 1` times, retrying as long as at least one
|
|
19
|
+
* row in the result satisfies `hasNullDefinition`. The retry exists because
|
|
20
|
+
* `pg_get_<x>def()` can return NULL transiently when the underlying catalog
|
|
21
|
+
* row is dropped concurrently or the catalog state is in flux; in practice a
|
|
22
|
+
* second attempt either no longer sees the dropped row or succeeds in
|
|
23
|
+
* resolving the definition.
|
|
24
|
+
*
|
|
25
|
+
* Returns the rows from the first attempt with no offenders, or — once
|
|
26
|
+
* retries are exhausted — the rows from the final attempt (still containing
|
|
27
|
+
* offenders). The caller is responsible for the final filter so this helper
|
|
28
|
+
* works for both flat schemas (definition on the row) and nested schemas
|
|
29
|
+
* (definition on a child collection, e.g. table constraints).
|
|
30
|
+
*/
|
|
31
|
+
export declare function extractWithDefinitionRetry<TRow>(params: {
|
|
32
|
+
label: string;
|
|
33
|
+
query: () => Promise<TRow[]>;
|
|
34
|
+
hasNullDefinition: (row: TRow) => boolean;
|
|
35
|
+
options?: ExtractRetryOptions;
|
|
36
|
+
}): Promise<TRow[]>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import debug from "debug";
|
|
2
|
+
const log = debug("pg-delta:extract");
|
|
3
|
+
const DEFAULT_RETRIES = 1;
|
|
4
|
+
const DEFAULT_BACKOFF_MS = 50;
|
|
5
|
+
export function resolveExtractRetries(option) {
|
|
6
|
+
if (typeof option === "number" && Number.isFinite(option)) {
|
|
7
|
+
return Math.max(0, Math.floor(option));
|
|
8
|
+
}
|
|
9
|
+
const envVal = process.env.PGDELTA_EXTRACT_RETRIES;
|
|
10
|
+
if (envVal !== undefined && envVal !== "") {
|
|
11
|
+
const n = Number(envVal);
|
|
12
|
+
if (Number.isFinite(n))
|
|
13
|
+
return Math.max(0, Math.floor(n));
|
|
14
|
+
}
|
|
15
|
+
return DEFAULT_RETRIES;
|
|
16
|
+
}
|
|
17
|
+
const sleep = (ms) => ms > 0 ? new Promise((r) => setTimeout(r, ms)) : Promise.resolve();
|
|
18
|
+
/**
|
|
19
|
+
* Runs `query()` up to `retries + 1` times, retrying as long as at least one
|
|
20
|
+
* row in the result satisfies `hasNullDefinition`. The retry exists because
|
|
21
|
+
* `pg_get_<x>def()` can return NULL transiently when the underlying catalog
|
|
22
|
+
* row is dropped concurrently or the catalog state is in flux; in practice a
|
|
23
|
+
* second attempt either no longer sees the dropped row or succeeds in
|
|
24
|
+
* resolving the definition.
|
|
25
|
+
*
|
|
26
|
+
* Returns the rows from the first attempt with no offenders, or — once
|
|
27
|
+
* retries are exhausted — the rows from the final attempt (still containing
|
|
28
|
+
* offenders). The caller is responsible for the final filter so this helper
|
|
29
|
+
* works for both flat schemas (definition on the row) and nested schemas
|
|
30
|
+
* (definition on a child collection, e.g. table constraints).
|
|
31
|
+
*/
|
|
32
|
+
export async function extractWithDefinitionRetry(params) {
|
|
33
|
+
const retries = resolveExtractRetries(params.options?.retries);
|
|
34
|
+
const backoffMs = params.options?.backoffMs ?? DEFAULT_BACKOFF_MS;
|
|
35
|
+
const maxAttempts = retries + 1;
|
|
36
|
+
let rows = [];
|
|
37
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
38
|
+
rows = await params.query();
|
|
39
|
+
const offenders = rows.filter(params.hasNullDefinition).length;
|
|
40
|
+
if (offenders === 0)
|
|
41
|
+
return rows;
|
|
42
|
+
if (attempt < maxAttempts) {
|
|
43
|
+
log("%s: pg_get_*def() returned NULL for %d row(s) on attempt %d/%d; retrying", params.label, offenders, attempt, maxAttempts);
|
|
44
|
+
await sleep(backoffMs * attempt);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
log("%s: pg_get_*def() returned NULL for %d row(s) after %d attempt(s); skipping", params.label, offenders, maxAttempts);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return rows;
|
|
51
|
+
}
|
package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { BaseChange } from "../../../base.change.ts";
|
|
|
2
2
|
import type { ForeignTable } from "../foreign-table.model.ts";
|
|
3
3
|
declare abstract class BaseForeignTableChange extends BaseChange {
|
|
4
4
|
abstract readonly foreignTable: ForeignTable;
|
|
5
|
-
abstract readonly scope: "object" | "comment" | "privilege";
|
|
5
|
+
abstract readonly scope: "object" | "comment" | "privilege" | "security_label";
|
|
6
6
|
readonly objectType: "foreign_table";
|
|
7
7
|
}
|
|
8
8
|
export declare abstract class CreateForeignTableChange extends BaseForeignTableChange {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { SecurityLabelProps } from "../../../security-label.types.ts";
|
|
2
|
+
import type { ForeignTable } from "../foreign-table.model.ts";
|
|
3
|
+
import { CreateForeignTableChange, DropForeignTableChange } from "./foreign-table.base.ts";
|
|
4
|
+
export type SecurityLabelForeignTable = CreateSecurityLabelOnForeignTable | DropSecurityLabelOnForeignTable;
|
|
5
|
+
export declare class CreateSecurityLabelOnForeignTable extends CreateForeignTableChange {
|
|
6
|
+
readonly foreignTable: ForeignTable;
|
|
7
|
+
readonly securityLabel: SecurityLabelProps;
|
|
8
|
+
readonly scope: "security_label";
|
|
9
|
+
constructor(props: {
|
|
10
|
+
foreignTable: ForeignTable;
|
|
11
|
+
securityLabel: SecurityLabelProps;
|
|
12
|
+
});
|
|
13
|
+
get creates(): `securityLabel:${string}::provider:${string}`[];
|
|
14
|
+
get requires(): `foreignTable:${string}`[];
|
|
15
|
+
serialize(): string;
|
|
16
|
+
}
|
|
17
|
+
export declare class DropSecurityLabelOnForeignTable extends DropForeignTableChange {
|
|
18
|
+
readonly foreignTable: ForeignTable;
|
|
19
|
+
readonly securityLabel: SecurityLabelProps;
|
|
20
|
+
readonly scope: "security_label";
|
|
21
|
+
constructor(props: {
|
|
22
|
+
foreignTable: ForeignTable;
|
|
23
|
+
securityLabel: SecurityLabelProps;
|
|
24
|
+
});
|
|
25
|
+
get drops(): `securityLabel:${string}::provider:${string}`[];
|
|
26
|
+
get requires(): (`securityLabel:${string}::provider:${string}` | `foreignTable:${string}`)[];
|
|
27
|
+
serialize(): string;
|
|
28
|
+
}
|
package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.security-label.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { quoteLiteral } from "../../../base.change.js";
|
|
2
|
+
import { stableId } from "../../../utils.js";
|
|
3
|
+
import { CreateForeignTableChange, DropForeignTableChange, } from "./foreign-table.base.js";
|
|
4
|
+
export class CreateSecurityLabelOnForeignTable extends CreateForeignTableChange {
|
|
5
|
+
foreignTable;
|
|
6
|
+
securityLabel;
|
|
7
|
+
scope = "security_label";
|
|
8
|
+
constructor(props) {
|
|
9
|
+
super();
|
|
10
|
+
this.foreignTable = props.foreignTable;
|
|
11
|
+
this.securityLabel = props.securityLabel;
|
|
12
|
+
}
|
|
13
|
+
get creates() {
|
|
14
|
+
return [
|
|
15
|
+
stableId.securityLabel(this.foreignTable.stableId, this.securityLabel.provider),
|
|
16
|
+
];
|
|
17
|
+
}
|
|
18
|
+
get requires() {
|
|
19
|
+
return [this.foreignTable.stableId];
|
|
20
|
+
}
|
|
21
|
+
serialize() {
|
|
22
|
+
return [
|
|
23
|
+
"SECURITY LABEL FOR",
|
|
24
|
+
this.securityLabel.provider,
|
|
25
|
+
"ON FOREIGN TABLE",
|
|
26
|
+
`${this.foreignTable.schema}.${this.foreignTable.name}`,
|
|
27
|
+
"IS",
|
|
28
|
+
quoteLiteral(this.securityLabel.label),
|
|
29
|
+
].join(" ");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export class DropSecurityLabelOnForeignTable extends DropForeignTableChange {
|
|
33
|
+
foreignTable;
|
|
34
|
+
securityLabel;
|
|
35
|
+
scope = "security_label";
|
|
36
|
+
constructor(props) {
|
|
37
|
+
super();
|
|
38
|
+
this.foreignTable = props.foreignTable;
|
|
39
|
+
this.securityLabel = props.securityLabel;
|
|
40
|
+
}
|
|
41
|
+
get drops() {
|
|
42
|
+
return [
|
|
43
|
+
stableId.securityLabel(this.foreignTable.stableId, this.securityLabel.provider),
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
get requires() {
|
|
47
|
+
return [
|
|
48
|
+
stableId.securityLabel(this.foreignTable.stableId, this.securityLabel.provider),
|
|
49
|
+
this.foreignTable.stableId,
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
serialize() {
|
|
53
|
+
return [
|
|
54
|
+
"SECURITY LABEL FOR",
|
|
55
|
+
this.securityLabel.provider,
|
|
56
|
+
"ON FOREIGN TABLE",
|
|
57
|
+
`${this.foreignTable.schema}.${this.foreignTable.name}`,
|
|
58
|
+
"IS NULL",
|
|
59
|
+
].join(" ");
|
|
60
|
+
}
|
|
61
|
+
}
|
package/dist/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.d.ts
CHANGED
|
@@ -3,5 +3,6 @@ import type { CommentForeignTable } from "./foreign-table.comment.ts";
|
|
|
3
3
|
import type { CreateForeignTable } from "./foreign-table.create.ts";
|
|
4
4
|
import type { DropForeignTable } from "./foreign-table.drop.ts";
|
|
5
5
|
import type { ForeignTablePrivilege } from "./foreign-table.privilege.ts";
|
|
6
|
+
import type { SecurityLabelForeignTable } from "./foreign-table.security-label.ts";
|
|
6
7
|
/** Union of all foreign-table-related change variants (`objectType: "foreign_table"`). @category Change Types */
|
|
7
|
-
export type ForeignTableChange = AlterForeignTable | CommentForeignTable | CreateForeignTable | DropForeignTable | ForeignTablePrivilege;
|
|
8
|
+
export type ForeignTableChange = AlterForeignTable | CommentForeignTable | CreateForeignTable | DropForeignTable | ForeignTablePrivilege | SecurityLabelForeignTable;
|
|
@@ -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 { AlterForeignTableAddColumn, AlterForeignTableAlterColumnDropDefault, AlterForeignTableAlterColumnDropNotNull, AlterForeignTableAlterColumnSetDefault, AlterForeignTableAlterColumnSetNotNull, AlterForeignTableAlterColumnType, AlterForeignTableChangeOwner, AlterForeignTableDropColumn, AlterForeignTableSetOptions, } from "./changes/foreign-table.alter.js";
|
|
4
5
|
import { CreateCommentOnForeignTable, DropCommentOnForeignTable, } from "./changes/foreign-table.comment.js";
|
|
5
6
|
import { CreateForeignTable } from "./changes/foreign-table.create.js";
|
|
6
7
|
import { DropForeignTable } from "./changes/foreign-table.drop.js";
|
|
7
8
|
import { GrantForeignTablePrivileges, RevokeForeignTablePrivileges, RevokeGrantOptionForeignTablePrivileges, } from "./changes/foreign-table.privilege.js";
|
|
9
|
+
import { CreateSecurityLabelOnForeignTable, DropSecurityLabelOnForeignTable, } from "./changes/foreign-table.security-label.js";
|
|
8
10
|
/**
|
|
9
11
|
* Diff two sets of foreign tables from main and branch catalogs.
|
|
10
12
|
*
|
|
@@ -30,6 +32,12 @@ export function diffForeignTables(ctx, main, branch) {
|
|
|
30
32
|
if (createdTable.comment !== null) {
|
|
31
33
|
changes.push(new CreateCommentOnForeignTable({ foreignTable: createdTable }));
|
|
32
34
|
}
|
|
35
|
+
for (const label of createdTable.security_labels) {
|
|
36
|
+
changes.push(new CreateSecurityLabelOnForeignTable({
|
|
37
|
+
foreignTable: createdTable,
|
|
38
|
+
securityLabel: label,
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
33
41
|
// PRIVILEGES: For created objects, compare against default privileges state
|
|
34
42
|
const effectiveDefaults = ctx.defaultPrivilegeState.getEffectiveDefaults(ctx.currentUser, "foreign_table", createdTable.schema ?? "");
|
|
35
43
|
const creatorFilteredDefaults = createdTable.owner !== ctx.currentUser
|
|
@@ -148,6 +156,14 @@ export function diffForeignTables(ctx, main, branch) {
|
|
|
148
156
|
changes.push(new CreateCommentOnForeignTable({ foreignTable: branchTable }));
|
|
149
157
|
}
|
|
150
158
|
}
|
|
159
|
+
// SECURITY LABELS
|
|
160
|
+
changes.push(...diffSecurityLabels(mainTable.security_labels, branchTable.security_labels, (securityLabel) => new CreateSecurityLabelOnForeignTable({
|
|
161
|
+
foreignTable: branchTable,
|
|
162
|
+
securityLabel,
|
|
163
|
+
}), (securityLabel) => new DropSecurityLabelOnForeignTable({
|
|
164
|
+
foreignTable: mainTable,
|
|
165
|
+
securityLabel,
|
|
166
|
+
})));
|
|
151
167
|
// PRIVILEGES
|
|
152
168
|
const mainPrivilegesFiltered = filterPublicBuiltInDefaults("foreign_table", mainTable.privileges);
|
|
153
169
|
const branchPrivilegesFiltered = filterPublicBuiltInDefaults("foreign_table", branchTable.privileges);
|
|
@@ -2,6 +2,7 @@ import type { Pool } from "pg";
|
|
|
2
2
|
import z from "zod";
|
|
3
3
|
import { BasePgModel, type TableLikeObject } 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 FOREIGN TABLE statement are included in diff output.
|
|
7
8
|
* https://www.postgresql.org/docs/17/sql-createforeigntable.html
|
|
@@ -36,6 +37,10 @@ declare const foreignTablePropsSchema: z.ZodObject<{
|
|
|
36
37
|
collation: z.ZodNullable<z.ZodString>;
|
|
37
38
|
default: z.ZodNullable<z.ZodString>;
|
|
38
39
|
comment: z.ZodNullable<z.ZodString>;
|
|
40
|
+
security_labels: z.ZodOptional<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
|
privileges: z.ZodArray<z.ZodObject<{
|
|
41
46
|
grantee: z.ZodString;
|
|
@@ -43,6 +48,10 @@ declare const foreignTablePropsSchema: z.ZodObject<{
|
|
|
43
48
|
grantable: z.ZodBoolean;
|
|
44
49
|
columns: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
|
|
45
50
|
}, z.z.core.$strip>>;
|
|
51
|
+
security_labels: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
52
|
+
provider: z.ZodString;
|
|
53
|
+
label: z.ZodString;
|
|
54
|
+
}, z.z.core.$strip>>>>;
|
|
46
55
|
}, z.z.core.$strip>;
|
|
47
56
|
type ForeignTablePrivilegeProps = PrivilegeProps;
|
|
48
57
|
export type ForeignTableProps = z.infer<typeof foreignTablePropsSchema>;
|
|
@@ -55,6 +64,7 @@ export declare class ForeignTable extends BasePgModel implements TableLikeObject
|
|
|
55
64
|
readonly comment: ForeignTableProps["comment"];
|
|
56
65
|
readonly columns: ForeignTableProps["columns"];
|
|
57
66
|
readonly privileges: ForeignTablePrivilegeProps[];
|
|
67
|
+
readonly security_labels: SecurityLabelProps[];
|
|
58
68
|
constructor(props: ForeignTableProps);
|
|
59
69
|
get stableId(): `foreignTable:${string}`;
|
|
60
70
|
get identityFields(): {
|
|
@@ -83,6 +93,10 @@ export declare class ForeignTable extends BasePgModel implements TableLikeObject
|
|
|
83
93
|
collation: string | null;
|
|
84
94
|
default: string | null;
|
|
85
95
|
comment: string | null;
|
|
96
|
+
security_labels?: {
|
|
97
|
+
provider: string;
|
|
98
|
+
label: string;
|
|
99
|
+
}[] | undefined;
|
|
86
100
|
}[];
|
|
87
101
|
privileges: {
|
|
88
102
|
grantee: string;
|
|
@@ -90,6 +104,10 @@ export declare class ForeignTable extends BasePgModel implements TableLikeObject
|
|
|
90
104
|
grantable: boolean;
|
|
91
105
|
columns?: string[] | null | undefined;
|
|
92
106
|
}[];
|
|
107
|
+
security_labels: {
|
|
108
|
+
provider: string;
|
|
109
|
+
label: string;
|
|
110
|
+
}[];
|
|
93
111
|
};
|
|
94
112
|
stableSnapshot(): {
|
|
95
113
|
identity: {
|
|
@@ -100,6 +118,10 @@ export declare class ForeignTable extends BasePgModel implements TableLikeObject
|
|
|
100
118
|
columns: {
|
|
101
119
|
[x: string]: unknown;
|
|
102
120
|
}[];
|
|
121
|
+
security_labels: {
|
|
122
|
+
provider: string;
|
|
123
|
+
label: string;
|
|
124
|
+
}[];
|
|
103
125
|
owner: string;
|
|
104
126
|
server: string;
|
|
105
127
|
options: string[] | null;
|