@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,8 @@ 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 ExtractRetryOptions } from "../extract-with-retry.ts";
|
|
6
|
+
import { type SecurityLabelProps } from "../security-label.types.ts";
|
|
5
7
|
declare const procedurePropsSchema: z.ZodObject<{
|
|
6
8
|
schema: z.ZodString;
|
|
7
9
|
name: z.ZodString;
|
|
@@ -56,6 +58,10 @@ declare const procedurePropsSchema: z.ZodObject<{
|
|
|
56
58
|
grantable: z.ZodBoolean;
|
|
57
59
|
columns: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
|
|
58
60
|
}, z.z.core.$strip>>;
|
|
61
|
+
security_labels: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
62
|
+
provider: z.ZodString;
|
|
63
|
+
label: z.ZodString;
|
|
64
|
+
}, z.z.core.$strip>>>>;
|
|
59
65
|
}, z.z.core.$strip>;
|
|
60
66
|
type ProcedurePrivilegeProps = PrivilegeProps;
|
|
61
67
|
export type ProcedureProps = z.infer<typeof procedurePropsSchema>;
|
|
@@ -89,6 +95,7 @@ export declare class Procedure extends BasePgModel {
|
|
|
89
95
|
readonly owner: ProcedureProps["owner"];
|
|
90
96
|
readonly comment: ProcedureProps["comment"];
|
|
91
97
|
readonly privileges: ProcedurePrivilegeProps[];
|
|
98
|
+
readonly security_labels: SecurityLabelProps[];
|
|
92
99
|
constructor(props: ProcedureProps);
|
|
93
100
|
get stableId(): `procedure:${string}`;
|
|
94
101
|
get identityFields(): {
|
|
@@ -126,7 +133,11 @@ export declare class Procedure extends BasePgModel {
|
|
|
126
133
|
grantable: boolean;
|
|
127
134
|
columns?: string[] | null | undefined;
|
|
128
135
|
}[];
|
|
136
|
+
security_labels: {
|
|
137
|
+
provider: string;
|
|
138
|
+
label: string;
|
|
139
|
+
}[];
|
|
129
140
|
};
|
|
130
141
|
}
|
|
131
|
-
export declare function extractProcedures(pool: Pool): Promise<Procedure[]>;
|
|
142
|
+
export declare function extractProcedures(pool: Pool, options?: ExtractRetryOptions): Promise<Procedure[]>;
|
|
132
143
|
export {};
|
|
@@ -2,6 +2,8 @@ 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 { extractWithDefinitionRetry, } from "../extract-with-retry.js";
|
|
6
|
+
import { securityLabelPropsSchema, } from "../security-label.types.js";
|
|
5
7
|
const FunctionKindSchema = z.enum([
|
|
6
8
|
"f", // function
|
|
7
9
|
"p", // procedure
|
|
@@ -55,6 +57,15 @@ const procedurePropsSchema = z.object({
|
|
|
55
57
|
owner: z.string(),
|
|
56
58
|
comment: z.string().nullable(),
|
|
57
59
|
privileges: z.array(privilegePropsSchema),
|
|
60
|
+
security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
|
|
61
|
+
});
|
|
62
|
+
// pg_get_functiondef(oid) can return NULL when the function (its pg_proc
|
|
63
|
+
// row) is dropped between catalog scan and resolution, or under transient
|
|
64
|
+
// catalog state. An unreadable function cannot be diffed, so we accept NULL
|
|
65
|
+
// here and filter the row out at extraction time rather than crashing the
|
|
66
|
+
// whole catalog parse with a ZodError.
|
|
67
|
+
const procedureRowSchema = procedurePropsSchema.extend({
|
|
68
|
+
definition: z.string().nullable(),
|
|
58
69
|
});
|
|
59
70
|
export class Procedure extends BasePgModel {
|
|
60
71
|
schema;
|
|
@@ -86,6 +97,7 @@ export class Procedure extends BasePgModel {
|
|
|
86
97
|
owner;
|
|
87
98
|
comment;
|
|
88
99
|
privileges;
|
|
100
|
+
security_labels;
|
|
89
101
|
constructor(props) {
|
|
90
102
|
super();
|
|
91
103
|
// Identity fields
|
|
@@ -119,6 +131,7 @@ export class Procedure extends BasePgModel {
|
|
|
119
131
|
this.owner = props.owner;
|
|
120
132
|
this.comment = props.comment;
|
|
121
133
|
this.privileges = props.privileges;
|
|
134
|
+
this.security_labels = props.security_labels ?? [];
|
|
122
135
|
}
|
|
123
136
|
get stableId() {
|
|
124
137
|
const args = this.argument_types?.join(",") ?? "";
|
|
@@ -160,11 +173,17 @@ export class Procedure extends BasePgModel {
|
|
|
160
173
|
owner: this.owner,
|
|
161
174
|
comment: this.comment,
|
|
162
175
|
privileges: this.privileges,
|
|
176
|
+
security_labels: this.security_labels,
|
|
163
177
|
};
|
|
164
178
|
}
|
|
165
179
|
}
|
|
166
|
-
export async function extractProcedures(pool) {
|
|
167
|
-
const
|
|
180
|
+
export async function extractProcedures(pool, options) {
|
|
181
|
+
const procedureRows = await extractWithDefinitionRetry({
|
|
182
|
+
label: "procedures",
|
|
183
|
+
options,
|
|
184
|
+
hasNullDefinition: (row) => row.definition === null,
|
|
185
|
+
query: async () => {
|
|
186
|
+
const result = await pool.query(sql `
|
|
168
187
|
with extension_oids as (
|
|
169
188
|
select
|
|
170
189
|
objid
|
|
@@ -224,7 +243,20 @@ select
|
|
|
224
243
|
)
|
|
225
244
|
from lateral aclexplode(COALESCE(p.proacl, acldefault('f', p.proowner))) as x(grantor, grantee, privilege_type, is_grantable)
|
|
226
245
|
), '[]'
|
|
227
|
-
) as privileges
|
|
246
|
+
) as privileges,
|
|
247
|
+
coalesce(
|
|
248
|
+
(
|
|
249
|
+
select json_agg(
|
|
250
|
+
json_build_object('provider', sl.provider, 'label', sl.label)
|
|
251
|
+
order by sl.provider
|
|
252
|
+
)
|
|
253
|
+
from pg_catalog.pg_seclabel sl
|
|
254
|
+
where sl.objoid = p.oid
|
|
255
|
+
and sl.classoid = 'pg_proc'::regclass
|
|
256
|
+
and sl.objsubid = 0
|
|
257
|
+
),
|
|
258
|
+
'[]'::json
|
|
259
|
+
) as security_labels
|
|
228
260
|
from
|
|
229
261
|
pg_catalog.pg_proc p
|
|
230
262
|
inner join pg_catalog.pg_language l on l.oid = p.prolang
|
|
@@ -236,7 +268,9 @@ from
|
|
|
236
268
|
order by
|
|
237
269
|
1, 2
|
|
238
270
|
`);
|
|
239
|
-
|
|
240
|
-
|
|
271
|
+
return result.rows.map((row) => procedureRowSchema.parse(row));
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
const validatedRows = procedureRows.filter((row) => row.definition !== null);
|
|
241
275
|
return validatedRows.map((row) => new Procedure(row));
|
|
242
276
|
}
|
|
@@ -2,7 +2,7 @@ import { BaseChange } from "../../base.change.ts";
|
|
|
2
2
|
import type { Publication } from "../publication.model.ts";
|
|
3
3
|
declare abstract class BasePublicationChange extends BaseChange {
|
|
4
4
|
abstract readonly publication: Publication;
|
|
5
|
-
abstract readonly scope: "object" | "comment";
|
|
5
|
+
abstract readonly scope: "object" | "comment" | "security_label";
|
|
6
6
|
readonly objectType: "publication";
|
|
7
7
|
}
|
|
8
8
|
export declare abstract class CreatePublicationChange extends BasePublicationChange {
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { SecurityLabelProps } from "../../security-label.types.ts";
|
|
2
|
+
import type { Publication } from "../publication.model.ts";
|
|
3
|
+
import { CreatePublicationChange, DropPublicationChange } from "./publication.base.ts";
|
|
4
|
+
export type SecurityLabelPublication = CreateSecurityLabelOnPublication | DropSecurityLabelOnPublication;
|
|
5
|
+
export declare class CreateSecurityLabelOnPublication extends CreatePublicationChange {
|
|
6
|
+
readonly publication: Publication;
|
|
7
|
+
readonly securityLabel: SecurityLabelProps;
|
|
8
|
+
readonly scope: "security_label";
|
|
9
|
+
constructor(props: {
|
|
10
|
+
publication: Publication;
|
|
11
|
+
securityLabel: SecurityLabelProps;
|
|
12
|
+
});
|
|
13
|
+
get creates(): `securityLabel:${string}::provider:${string}`[];
|
|
14
|
+
get requires(): `publication:${string}`[];
|
|
15
|
+
serialize(): string;
|
|
16
|
+
}
|
|
17
|
+
export declare class DropSecurityLabelOnPublication extends DropPublicationChange {
|
|
18
|
+
readonly publication: Publication;
|
|
19
|
+
readonly securityLabel: SecurityLabelProps;
|
|
20
|
+
readonly scope: "security_label";
|
|
21
|
+
constructor(props: {
|
|
22
|
+
publication: Publication;
|
|
23
|
+
securityLabel: SecurityLabelProps;
|
|
24
|
+
});
|
|
25
|
+
get drops(): `securityLabel:${string}::provider:${string}`[];
|
|
26
|
+
get requires(): (`securityLabel:${string}::provider:${string}` | `publication:${string}`)[];
|
|
27
|
+
serialize(): string;
|
|
28
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { quoteLiteral } from "../../base.change.js";
|
|
2
|
+
import { stableId } from "../../utils.js";
|
|
3
|
+
import { CreatePublicationChange, DropPublicationChange, } from "./publication.base.js";
|
|
4
|
+
export class CreateSecurityLabelOnPublication extends CreatePublicationChange {
|
|
5
|
+
publication;
|
|
6
|
+
securityLabel;
|
|
7
|
+
scope = "security_label";
|
|
8
|
+
constructor(props) {
|
|
9
|
+
super();
|
|
10
|
+
this.publication = props.publication;
|
|
11
|
+
this.securityLabel = props.securityLabel;
|
|
12
|
+
}
|
|
13
|
+
get creates() {
|
|
14
|
+
return [
|
|
15
|
+
stableId.securityLabel(this.publication.stableId, this.securityLabel.provider),
|
|
16
|
+
];
|
|
17
|
+
}
|
|
18
|
+
get requires() {
|
|
19
|
+
return [this.publication.stableId];
|
|
20
|
+
}
|
|
21
|
+
serialize() {
|
|
22
|
+
return [
|
|
23
|
+
"SECURITY LABEL FOR",
|
|
24
|
+
this.securityLabel.provider,
|
|
25
|
+
"ON PUBLICATION",
|
|
26
|
+
this.publication.name,
|
|
27
|
+
"IS",
|
|
28
|
+
quoteLiteral(this.securityLabel.label),
|
|
29
|
+
].join(" ");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export class DropSecurityLabelOnPublication extends DropPublicationChange {
|
|
33
|
+
publication;
|
|
34
|
+
securityLabel;
|
|
35
|
+
scope = "security_label";
|
|
36
|
+
constructor(props) {
|
|
37
|
+
super();
|
|
38
|
+
this.publication = props.publication;
|
|
39
|
+
this.securityLabel = props.securityLabel;
|
|
40
|
+
}
|
|
41
|
+
get drops() {
|
|
42
|
+
return [
|
|
43
|
+
stableId.securityLabel(this.publication.stableId, this.securityLabel.provider),
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
get requires() {
|
|
47
|
+
return [
|
|
48
|
+
stableId.securityLabel(this.publication.stableId, this.securityLabel.provider),
|
|
49
|
+
this.publication.stableId,
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
serialize() {
|
|
53
|
+
return [
|
|
54
|
+
"SECURITY LABEL FOR",
|
|
55
|
+
this.securityLabel.provider,
|
|
56
|
+
"ON PUBLICATION",
|
|
57
|
+
this.publication.name,
|
|
58
|
+
"IS NULL",
|
|
59
|
+
].join(" ");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -2,5 +2,6 @@ import type { AlterPublicationAddSchemas, AlterPublicationAddTables, AlterPublic
|
|
|
2
2
|
import type { CommentPublication } from "./publication.comment.ts";
|
|
3
3
|
import type { CreatePublication } from "./publication.create.ts";
|
|
4
4
|
import type { DropPublication } from "./publication.drop.ts";
|
|
5
|
+
import type { SecurityLabelPublication } from "./publication.security-label.ts";
|
|
5
6
|
/** Union of all publication-related change variants (`objectType: "publication"`). @category Change Types */
|
|
6
|
-
export type PublicationChange = AlterPublicationAddSchemas | AlterPublicationAddTables | AlterPublicationDropSchemas | AlterPublicationDropTables | AlterPublicationSetList | AlterPublicationSetOptions | AlterPublicationSetOwner | CommentPublication | CreatePublication | DropPublication;
|
|
7
|
+
export type PublicationChange = AlterPublicationAddSchemas | AlterPublicationAddTables | AlterPublicationDropSchemas | AlterPublicationDropTables | AlterPublicationSetList | AlterPublicationSetOptions | AlterPublicationSetOwner | CommentPublication | CreatePublication | DropPublication | SecurityLabelPublication;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { diffObjects } from "../base.diff.js";
|
|
2
|
+
import { diffSecurityLabels } from "../security-label.types.js";
|
|
2
3
|
import { deepEqual } from "../utils.js";
|
|
3
4
|
import { AlterPublicationAddSchemas, AlterPublicationAddTables, AlterPublicationDropSchemas, AlterPublicationDropTables, AlterPublicationSetOptions, AlterPublicationSetOwner, } from "./changes/publication.alter.js";
|
|
4
5
|
import { CreateCommentOnPublication, DropCommentOnPublication, } from "./changes/publication.comment.js";
|
|
5
6
|
import { CreatePublication } from "./changes/publication.create.js";
|
|
6
7
|
import { DropPublication } from "./changes/publication.drop.js";
|
|
8
|
+
import { CreateSecurityLabelOnPublication, DropSecurityLabelOnPublication, } from "./changes/publication.security-label.js";
|
|
7
9
|
export function diffPublications(ctx, main, branch) {
|
|
8
10
|
const { created, dropped, altered } = diffObjects(main, branch);
|
|
9
11
|
const changes = [];
|
|
@@ -21,6 +23,12 @@ export function diffPublications(ctx, main, branch) {
|
|
|
21
23
|
if (publication.comment !== null) {
|
|
22
24
|
changes.push(new CreateCommentOnPublication({ publication }));
|
|
23
25
|
}
|
|
26
|
+
for (const label of publication.security_labels) {
|
|
27
|
+
changes.push(new CreateSecurityLabelOnPublication({
|
|
28
|
+
publication,
|
|
29
|
+
securityLabel: label,
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
24
32
|
}
|
|
25
33
|
for (const id of dropped) {
|
|
26
34
|
changes.push(new DropPublication({ publication: main[id] }));
|
|
@@ -107,6 +115,14 @@ export function diffPublications(ctx, main, branch) {
|
|
|
107
115
|
changes.push(new CreateCommentOnPublication({ publication: branchPublication }));
|
|
108
116
|
}
|
|
109
117
|
}
|
|
118
|
+
// SECURITY LABELS
|
|
119
|
+
changes.push(...diffSecurityLabels(mainPublication.security_labels, branchPublication.security_labels, (securityLabel) => new CreateSecurityLabelOnPublication({
|
|
120
|
+
publication: branchPublication,
|
|
121
|
+
securityLabel,
|
|
122
|
+
}), (securityLabel) => new DropSecurityLabelOnPublication({
|
|
123
|
+
publication: mainPublication,
|
|
124
|
+
securityLabel,
|
|
125
|
+
})));
|
|
110
126
|
}
|
|
111
127
|
return changes;
|
|
112
128
|
}
|
|
@@ -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 publicationTablePropsSchema: z.ZodObject<{
|
|
5
6
|
schema: z.ZodString;
|
|
6
7
|
name: z.ZodString;
|
|
@@ -24,6 +25,10 @@ declare const publicationPropsSchema: z.ZodObject<{
|
|
|
24
25
|
row_filter: z.ZodNullable<z.ZodString>;
|
|
25
26
|
}, z.z.core.$strip>>;
|
|
26
27
|
schemas: z.ZodArray<z.ZodString>;
|
|
28
|
+
security_labels: z.ZodOptional<z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
29
|
+
provider: z.ZodString;
|
|
30
|
+
label: z.ZodString;
|
|
31
|
+
}, z.z.core.$strip>>>>;
|
|
27
32
|
}, z.z.core.$strip>;
|
|
28
33
|
export type PublicationTableProps = z.infer<typeof publicationTablePropsSchema>;
|
|
29
34
|
export type PublicationProps = z.infer<typeof publicationPropsSchema>;
|
|
@@ -44,6 +49,7 @@ export declare class Publication extends BasePgModel {
|
|
|
44
49
|
readonly publish_via_partition_root: PublicationProps["publish_via_partition_root"];
|
|
45
50
|
readonly tables: PublicationTableProps[];
|
|
46
51
|
readonly schemas: PublicationProps["schemas"];
|
|
52
|
+
readonly security_labels: SecurityLabelProps[];
|
|
47
53
|
constructor(props: PublicationProps);
|
|
48
54
|
get stableId(): `publication:${string}`;
|
|
49
55
|
get identityFields(): {
|
|
@@ -65,6 +71,10 @@ export declare class Publication extends BasePgModel {
|
|
|
65
71
|
row_filter: string | null;
|
|
66
72
|
}[];
|
|
67
73
|
schemas: string[];
|
|
74
|
+
security_labels: {
|
|
75
|
+
provider: string;
|
|
76
|
+
label: string;
|
|
77
|
+
}[];
|
|
68
78
|
};
|
|
69
79
|
stableSnapshot(): {
|
|
70
80
|
identity: {
|
|
@@ -78,6 +88,10 @@ export declare class Publication extends BasePgModel {
|
|
|
78
88
|
row_filter: string | null;
|
|
79
89
|
}[];
|
|
80
90
|
schemas: string[];
|
|
91
|
+
security_labels: {
|
|
92
|
+
provider: string;
|
|
93
|
+
label: string;
|
|
94
|
+
}[];
|
|
81
95
|
owner: string;
|
|
82
96
|
comment: string | null;
|
|
83
97
|
all_tables: boolean;
|
|
@@ -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 { normalizeSecurityLabels, securityLabelPropsSchema, } from "../security-label.types.js";
|
|
4
5
|
const publicationTablePropsSchema = z.object({
|
|
5
6
|
schema: z.string(),
|
|
6
7
|
name: z.string(),
|
|
@@ -19,6 +20,7 @@ const publicationPropsSchema = z.object({
|
|
|
19
20
|
publish_via_partition_root: z.boolean(),
|
|
20
21
|
tables: z.array(publicationTablePropsSchema),
|
|
21
22
|
schemas: z.array(z.string()),
|
|
23
|
+
security_labels: z.array(securityLabelPropsSchema).default([]).optional(),
|
|
22
24
|
});
|
|
23
25
|
/**
|
|
24
26
|
* Logical replication publication definition extracted from pg_publication.
|
|
@@ -37,6 +39,7 @@ export class Publication extends BasePgModel {
|
|
|
37
39
|
publish_via_partition_root;
|
|
38
40
|
tables;
|
|
39
41
|
schemas;
|
|
42
|
+
security_labels;
|
|
40
43
|
constructor(props) {
|
|
41
44
|
super();
|
|
42
45
|
this.name = props.name;
|
|
@@ -60,6 +63,7 @@ export class Publication extends BasePgModel {
|
|
|
60
63
|
return a.schema.localeCompare(b.schema) || a.name.localeCompare(b.name);
|
|
61
64
|
});
|
|
62
65
|
this.schemas = [...props.schemas].sort((a, b) => a.localeCompare(b));
|
|
66
|
+
this.security_labels = props.security_labels ?? [];
|
|
63
67
|
}
|
|
64
68
|
get stableId() {
|
|
65
69
|
return `publication:${this.name}`;
|
|
@@ -81,6 +85,7 @@ export class Publication extends BasePgModel {
|
|
|
81
85
|
publish_via_partition_root: this.publish_via_partition_root,
|
|
82
86
|
tables: this.tables,
|
|
83
87
|
schemas: this.schemas,
|
|
88
|
+
security_labels: this.security_labels,
|
|
84
89
|
};
|
|
85
90
|
}
|
|
86
91
|
stableSnapshot() {
|
|
@@ -98,6 +103,7 @@ export class Publication extends BasePgModel {
|
|
|
98
103
|
...this.dataFields,
|
|
99
104
|
tables: normalizedTables.sort((a, b) => a.schema.localeCompare(b.schema) || a.name.localeCompare(b.name)),
|
|
100
105
|
schemas: [...this.schemas].sort((a, b) => a.localeCompare(b)),
|
|
106
|
+
security_labels: normalizeSecurityLabels(this.security_labels),
|
|
101
107
|
},
|
|
102
108
|
};
|
|
103
109
|
}
|
|
@@ -173,7 +179,20 @@ export async function extractPublications(pool) {
|
|
|
173
179
|
where s.pnpubid = p.oid
|
|
174
180
|
),
|
|
175
181
|
'[]'::json
|
|
176
|
-
) as schemas
|
|
182
|
+
) as schemas,
|
|
183
|
+
coalesce(
|
|
184
|
+
(
|
|
185
|
+
select json_agg(
|
|
186
|
+
json_build_object('provider', sl.provider, 'label', sl.label)
|
|
187
|
+
order by sl.provider
|
|
188
|
+
)
|
|
189
|
+
from pg_catalog.pg_seclabel sl
|
|
190
|
+
where sl.objoid = p.oid
|
|
191
|
+
and sl.classoid = 'pg_publication'::regclass
|
|
192
|
+
and sl.objsubid = 0
|
|
193
|
+
),
|
|
194
|
+
'[]'::json
|
|
195
|
+
) as security_labels
|
|
177
196
|
from pg_publication p
|
|
178
197
|
left join extension_oids e on e.objid = p.oid
|
|
179
198
|
where e.objid is null
|
|
@@ -35,7 +35,19 @@ export function diffRlsPolicies(main, branch) {
|
|
|
35
35
|
"permissive",
|
|
36
36
|
];
|
|
37
37
|
const nonAlterablePropsChanged = hasNonAlterableChanges(mainRlsPolicy, branchRlsPolicy, NON_ALTERABLE_FIELDS, {});
|
|
38
|
-
|
|
38
|
+
// The set of relations and procedures that the policy's USING / WITH
|
|
39
|
+
// CHECK expressions reference is recorded by PostgreSQL in pg_depend
|
|
40
|
+
// (recordDependencyOnExpr at policy creation). When that set changes
|
|
41
|
+
// it is unsafe to ALTER POLICY in place: the old reference target may
|
|
42
|
+
// be dropped in the same plan, and the new reference target may only
|
|
43
|
+
// exist after the create phase. Drop+create lets the sort phase order
|
|
44
|
+
// the policy's drop before the referenced object's drop and the
|
|
45
|
+
// policy's recreate after the referenced object's create.
|
|
46
|
+
const referencedDependenciesChanged = hasNonAlterableChanges(mainRlsPolicy, branchRlsPolicy, ["referenced_procedures", "referenced_relations"], {
|
|
47
|
+
referenced_procedures: deepEqual,
|
|
48
|
+
referenced_relations: deepEqual,
|
|
49
|
+
});
|
|
50
|
+
if (nonAlterablePropsChanged || referencedDependenciesChanged) {
|
|
39
51
|
// Replace the entire RLS policy (drop + create)
|
|
40
52
|
changes.push(new DropRlsPolicy({ policy: mainRlsPolicy }), new CreateRlsPolicy({ policy: branchRlsPolicy }));
|
|
41
53
|
}
|
|
@@ -2,7 +2,7 @@ import { BaseChange } from "../../base.change.ts";
|
|
|
2
2
|
import type { Role } from "../role.model.ts";
|
|
3
3
|
declare abstract class BaseRoleChange extends BaseChange {
|
|
4
4
|
abstract readonly role: Role;
|
|
5
|
-
abstract readonly scope: "object" | "comment" | "membership" | "default_privilege";
|
|
5
|
+
abstract readonly scope: "object" | "comment" | "membership" | "default_privilege" | "security_label";
|
|
6
6
|
readonly objectType: "role";
|
|
7
7
|
}
|
|
8
8
|
export declare abstract class CreateRoleChange extends BaseRoleChange {
|
|
@@ -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[]>;
|