@supabase/pg-delta 1.0.0-alpha.4 → 1.0.0-alpha.6
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/README.md +40 -23
- package/dist/cli/app.js +26 -3
- package/dist/cli/bin/cli.js +5 -0
- package/dist/cli/commands/catalog-export.d.ts +5 -0
- package/dist/cli/commands/catalog-export.js +64 -0
- package/dist/cli/commands/declarative-apply.d.ts +6 -0
- package/dist/cli/commands/declarative-apply.js +288 -0
- package/dist/cli/commands/declarative-export.d.ts +5 -0
- package/dist/cli/commands/declarative-export.js +245 -0
- package/dist/cli/commands/plan.js +19 -6
- package/dist/cli/exit-code.d.ts +2 -0
- package/dist/cli/exit-code.js +7 -0
- package/dist/cli/formatters/tree/tree.js +3 -2
- package/dist/cli/utils/apply-display.d.ts +52 -0
- package/dist/cli/utils/apply-display.js +183 -0
- package/dist/cli/utils/export-display.d.ts +43 -0
- package/dist/cli/utils/export-display.js +202 -0
- package/dist/cli/utils/resolve-input.d.ts +7 -0
- package/dist/cli/utils/resolve-input.js +13 -0
- package/dist/core/catalog-export/index.d.ts +11 -0
- package/dist/core/catalog-export/index.js +10 -0
- package/dist/core/catalog.diff.d.ts +1 -0
- package/dist/core/catalog.diff.js +64 -48
- package/dist/core/catalog.model.d.ts +14 -1
- package/dist/core/catalog.model.js +103 -1
- package/dist/core/catalog.snapshot.d.ts +66 -0
- package/dist/core/catalog.snapshot.js +206 -0
- package/dist/core/declarative-apply/discover-sql.d.ts +18 -0
- package/dist/core/declarative-apply/discover-sql.js +86 -0
- package/dist/core/declarative-apply/extract-catalog-providers.d.ts +23 -0
- package/dist/core/declarative-apply/extract-catalog-providers.js +159 -0
- package/dist/core/declarative-apply/index.d.ts +49 -0
- package/dist/core/declarative-apply/index.js +134 -0
- package/dist/core/declarative-apply/round-apply.d.ts +100 -0
- package/dist/core/declarative-apply/round-apply.js +378 -0
- package/dist/core/export/file-mapper.d.ts +71 -0
- package/dist/core/export/file-mapper.js +474 -0
- package/dist/core/export/grouper.d.ts +13 -0
- package/dist/core/export/grouper.js +76 -0
- package/dist/core/export/index.d.ts +45 -0
- package/dist/core/export/index.js +63 -0
- package/dist/core/export/types.d.ts +84 -0
- package/dist/core/export/types.js +25 -0
- package/dist/core/fixtures/empty-catalogs/postgres-15-16-baseline.json +287 -0
- package/dist/core/integrations/filter/dsl.d.ts +38 -1
- package/dist/core/integrations/filter/dsl.js +20 -2
- package/dist/core/integrations/filter/extractors.js +42 -0
- package/dist/core/integrations/integration-dsl.d.ts +10 -0
- package/dist/core/integrations/supabase.d.ts +8 -0
- package/dist/core/integrations/supabase.js +9 -0
- package/dist/core/objects/aggregate/aggregate.diff.d.ts +2 -8
- package/dist/core/objects/aggregate/aggregate.diff.js +16 -70
- package/dist/core/objects/aggregate/aggregate.model.d.ts +8 -8
- package/dist/core/objects/aggregate/aggregate.model.js +1 -1
- package/dist/core/objects/aggregate/changes/aggregate.create.js +1 -1
- package/dist/core/objects/aggregate/changes/aggregate.drop.js +1 -1
- package/dist/core/objects/base.privilege-diff.d.ts +38 -13
- package/dist/core/objects/base.privilege-diff.js +104 -22
- package/dist/core/objects/base.privilege.d.ts +1 -0
- package/dist/core/objects/base.privilege.js +9 -2
- package/dist/core/objects/collation/collation.diff.d.ts +2 -3
- package/dist/core/objects/diff-context.d.ts +15 -0
- package/dist/core/objects/diff-context.js +1 -0
- package/dist/core/objects/domain/changes/domain.create.js +4 -2
- package/dist/core/objects/domain/domain.diff.d.ts +2 -8
- package/dist/core/objects/domain/domain.diff.js +16 -77
- package/dist/core/objects/domain/domain.model.js +1 -1
- package/dist/core/objects/event-trigger/event-trigger.diff.d.ts +2 -3
- package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.d.ts +2 -8
- package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.js +13 -77
- package/dist/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.js +2 -2
- package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.d.ts +2 -8
- package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.js +16 -77
- package/dist/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.js +1 -1
- package/dist/core/objects/foreign-data-wrapper/server/server.diff.d.ts +2 -8
- package/dist/core/objects/foreign-data-wrapper/server/server.diff.js +13 -77
- package/dist/core/objects/language/language.diff.d.ts +2 -5
- package/dist/core/objects/language/language.diff.js +7 -39
- package/dist/core/objects/materialized-view/materialized-view.diff.d.ts +2 -8
- package/dist/core/objects/materialized-view/materialized-view.diff.js +16 -158
- package/dist/core/objects/materialized-view/materialized-view.model.d.ts +3 -3
- package/dist/core/objects/materialized-view/materialized-view.model.js +1 -1
- package/dist/core/objects/procedure/changes/procedure.alter.js +12 -12
- package/dist/core/objects/procedure/procedure.diff.d.ts +2 -8
- package/dist/core/objects/procedure/procedure.diff.js +16 -77
- package/dist/core/objects/procedure/procedure.model.d.ts +9 -9
- package/dist/core/objects/procedure/procedure.model.js +1 -1
- package/dist/core/objects/publication/changes/publication.alter.d.ts +0 -9
- package/dist/core/objects/publication/changes/publication.alter.js +0 -14
- package/dist/core/objects/publication/changes/publication.types.d.ts +2 -2
- package/dist/core/objects/publication/publication.diff.d.ts +2 -3
- package/dist/core/objects/publication/publication.diff.js +8 -13
- package/dist/core/objects/rls-policy/changes/rls-policy.alter.js +3 -3
- package/dist/core/objects/rls-policy/rls-policy.model.d.ts +2 -2
- package/dist/core/objects/role/role.diff.js +22 -1
- package/dist/core/objects/role/role.model.d.ts +4 -3
- package/dist/core/objects/role/role.model.js +118 -12
- package/dist/core/objects/rule/rule.model.d.ts +1 -1
- package/dist/core/objects/schema/schema.diff.d.ts +2 -8
- package/dist/core/objects/schema/schema.diff.js +16 -77
- package/dist/core/objects/schema/schema.model.js +1 -1
- package/dist/core/objects/sequence/sequence.diff.d.ts +2 -8
- package/dist/core/objects/sequence/sequence.diff.js +16 -79
- package/dist/core/objects/sequence/sequence.model.js +1 -1
- package/dist/core/objects/subscription/subscription.diff.d.ts +2 -3
- package/dist/core/objects/table/changes/table.create.js +3 -0
- package/dist/core/objects/table/table.diff.d.ts +2 -8
- package/dist/core/objects/table/table.diff.js +26 -157
- package/dist/core/objects/table/table.model.d.ts +23 -22
- package/dist/core/objects/table/table.model.js +1 -1
- package/dist/core/objects/trigger/changes/trigger.create.js +2 -4
- package/dist/core/objects/trigger/trigger.model.d.ts +8 -0
- package/dist/core/objects/trigger/trigger.model.js +11 -0
- package/dist/core/objects/type/composite-type/composite-type.diff.d.ts +2 -8
- package/dist/core/objects/type/composite-type/composite-type.diff.js +16 -77
- package/dist/core/objects/type/composite-type/composite-type.model.d.ts +3 -3
- package/dist/core/objects/type/composite-type/composite-type.model.js +2 -1
- package/dist/core/objects/type/enum/enum.diff.d.ts +2 -8
- package/dist/core/objects/type/enum/enum.diff.js +25 -112
- package/dist/core/objects/type/enum/enum.model.js +1 -1
- package/dist/core/objects/type/range/changes/range.create.js +6 -3
- package/dist/core/objects/type/range/range.diff.d.ts +2 -8
- package/dist/core/objects/type/range/range.diff.js +16 -77
- package/dist/core/objects/type/range/range.model.js +1 -1
- package/dist/core/objects/view/view.diff.d.ts +2 -8
- package/dist/core/objects/view/view.diff.js +16 -158
- package/dist/core/objects/view/view.model.d.ts +18 -4
- package/dist/core/objects/view/view.model.js +3 -13
- package/dist/core/plan/apply.js +9 -26
- package/dist/core/plan/create.d.ts +19 -6
- package/dist/core/plan/create.js +134 -174
- package/dist/core/plan/serialize.js +16 -4
- package/dist/core/plan/sql-format/fixtures.js +3 -5
- package/dist/core/plan/sql-format/keyword-case.js +26 -1
- package/dist/core/plan/ssl-config.d.ts +32 -0
- package/dist/core/plan/ssl-config.js +115 -0
- package/dist/core/plan/types.d.ts +6 -0
- package/dist/core/postgres-config.d.ts +14 -0
- package/dist/core/postgres-config.js +53 -2
- package/dist/core/sort/graph-builder.js +10 -0
- package/dist/core/sort/logical-sort.js +31 -23
- package/dist/core/test-utils/assert-valid-sql.d.ts +10 -0
- package/dist/core/test-utils/assert-valid-sql.js +19 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -1
- package/package.json +21 -4
- package/src/cli/app.ts +27 -3
- package/src/cli/bin/cli.ts +6 -0
- package/src/cli/commands/catalog-export.ts +78 -0
- package/src/cli/commands/declarative-apply.diagnostics.test.ts +77 -0
- package/src/cli/commands/declarative-apply.ts +380 -0
- package/src/cli/commands/declarative-export.ts +330 -0
- package/src/cli/commands/plan.ts +28 -7
- package/src/cli/exit-code.test.ts +19 -0
- package/src/cli/exit-code.ts +7 -0
- package/src/cli/formatters/tree/tree.ts +3 -2
- package/src/cli/utils/apply-display.test.ts +348 -0
- package/src/cli/utils/apply-display.ts +238 -0
- package/src/cli/utils/export-display.test.ts +103 -0
- package/src/cli/utils/export-display.ts +275 -0
- package/src/cli/utils/integrations.test.ts +44 -0
- package/src/cli/utils/resolve-input.test.ts +38 -0
- package/src/cli/utils/resolve-input.ts +17 -0
- package/src/core/catalog-export/index.ts +20 -0
- package/src/core/catalog.diff.ts +79 -78
- package/src/core/catalog.model.test.ts +122 -0
- package/src/core/catalog.model.ts +127 -1
- package/src/core/catalog.snapshot.test.ts +464 -0
- package/src/core/catalog.snapshot.ts +289 -0
- package/src/core/declarative-apply/discover-sql.test.ts +103 -0
- package/src/core/declarative-apply/discover-sql.ts +107 -0
- package/src/core/declarative-apply/extract-catalog-providers.ts +220 -0
- package/src/core/declarative-apply/index.test.ts +67 -0
- package/src/core/declarative-apply/index.ts +205 -0
- package/src/core/declarative-apply/round-apply.test.ts +504 -0
- package/src/core/declarative-apply/round-apply.ts +562 -0
- package/src/core/expand-replace-dependencies.test.ts +70 -0
- package/src/core/export/file-mapper.test.ts +816 -0
- package/src/core/export/file-mapper.ts +574 -0
- package/src/core/export/grouper.ts +108 -0
- package/src/core/export/index.ts +129 -0
- package/src/core/export/types.ts +104 -0
- package/src/core/fixtures/empty-catalogs/postgres-15-16-baseline.json +287 -0
- package/src/core/integrations/filter/dsl.test.ts +211 -0
- package/src/core/integrations/filter/dsl.ts +65 -3
- package/src/core/integrations/filter/extractors.test.ts +244 -0
- package/src/core/integrations/filter/extractors.ts +42 -0
- package/src/core/integrations/integration-dsl.ts +10 -0
- package/src/core/integrations/serialize/dsl.test.ts +91 -0
- package/src/core/integrations/supabase.ts +9 -0
- package/src/core/objects/aggregate/aggregate.diff.ts +39 -95
- package/src/core/objects/aggregate/aggregate.model.ts +1 -1
- package/src/core/objects/aggregate/changes/aggregate.alter.test.ts +3 -1
- package/src/core/objects/aggregate/changes/aggregate.comment.test.ts +5 -2
- package/src/core/objects/aggregate/changes/aggregate.create.test.ts +6 -3
- package/src/core/objects/aggregate/changes/aggregate.create.ts +1 -1
- package/src/core/objects/aggregate/changes/aggregate.drop.test.ts +7 -3
- package/src/core/objects/aggregate/changes/aggregate.drop.ts +1 -1
- package/src/core/objects/aggregate/changes/aggregate.privilege.test.ts +9 -3
- package/src/core/objects/base.privilege-diff.ts +178 -30
- package/src/core/objects/base.privilege.ts +9 -2
- package/src/core/objects/collation/changes/collation.alter.test.ts +7 -2
- package/src/core/objects/collation/changes/collation.create.test.ts +7 -2
- package/src/core/objects/collation/changes/collation.drop.test.ts +4 -1
- package/src/core/objects/collation/collation.diff.test.ts +9 -12
- package/src/core/objects/collation/collation.diff.ts +2 -1
- package/src/core/objects/diff-context.ts +16 -0
- package/src/core/objects/domain/changes/domain.alter.test.ts +28 -9
- package/src/core/objects/domain/changes/domain.create.test.ts +32 -2
- package/src/core/objects/domain/changes/domain.create.ts +7 -1
- package/src/core/objects/domain/changes/domain.drop.test.ts +4 -1
- package/src/core/objects/domain/domain.diff.ts +39 -102
- package/src/core/objects/domain/domain.model.ts +1 -1
- package/src/core/objects/event-trigger/changes/event-trigger.alter.test.ts +10 -3
- package/src/core/objects/event-trigger/changes/event-trigger.create.test.ts +4 -1
- package/src/core/objects/event-trigger/changes/event-trigger.drop.test.ts +4 -1
- package/src/core/objects/event-trigger/event-trigger.diff.test.ts +12 -7
- package/src/core/objects/event-trigger/event-trigger.diff.ts +2 -1
- package/src/core/objects/extension/changes/extension.alter.test.ts +7 -2
- package/src/core/objects/extension/changes/extension.create.test.ts +4 -1
- package/src/core/objects/extension/changes/extension.drop.test.ts +4 -1
- package/src/core/objects/extension/extension.model.test.ts +98 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.test.ts +16 -5
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.test.ts +51 -16
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.test.ts +4 -1
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.test.ts +111 -4
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.ts +31 -101
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.ts +2 -2
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.test.ts +46 -15
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.test.ts +13 -4
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.test.ts +4 -1
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +39 -102
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +1 -1
- package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.test.ts +22 -7
- package/src/core/objects/foreign-data-wrapper/server/changes/server.create.test.ts +19 -6
- package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.test.ts +4 -1
- package/src/core/objects/foreign-data-wrapper/server/server.diff.test.ts +95 -0
- package/src/core/objects/foreign-data-wrapper/server/server.diff.ts +31 -101
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.test.ts +13 -4
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.test.ts +16 -5
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.test.ts +10 -3
- package/src/core/objects/index/changes/index.alter.test.ts +13 -4
- package/src/core/objects/index/changes/index.create.test.ts +4 -1
- package/src/core/objects/index/changes/index.drop.test.ts +4 -1
- package/src/core/objects/language/changes/language.alter.test.ts +4 -1
- package/src/core/objects/language/changes/language.create.test.ts +4 -1
- package/src/core/objects/language/changes/language.drop.test.ts +4 -1
- package/src/core/objects/language/language.diff.test.ts +86 -4
- package/src/core/objects/language/language.diff.ts +17 -49
- package/src/core/objects/materialized-view/changes/materialized-view.alter.test.ts +10 -3
- package/src/core/objects/materialized-view/changes/materialized-view.create.test.ts +7 -2
- package/src/core/objects/materialized-view/changes/materialized-view.drop.test.ts +4 -1
- package/src/core/objects/materialized-view/materialized-view.diff.test.ts +162 -0
- package/src/core/objects/materialized-view/materialized-view.diff.ts +41 -191
- package/src/core/objects/materialized-view/materialized-view.model.ts +1 -1
- package/src/core/objects/procedure/changes/procedure.alter.test.ts +121 -49
- package/src/core/objects/procedure/changes/procedure.alter.ts +15 -12
- package/src/core/objects/procedure/changes/procedure.create.test.ts +4 -1
- package/src/core/objects/procedure/changes/procedure.drop.test.ts +7 -2
- package/src/core/objects/procedure/procedure.diff.ts +39 -102
- package/src/core/objects/procedure/procedure.model.ts +1 -1
- package/src/core/objects/publication/changes/publication.alter.test.ts +15 -21
- package/src/core/objects/publication/changes/publication.alter.ts +0 -18
- package/src/core/objects/publication/changes/publication.comment.test.ts +5 -2
- package/src/core/objects/publication/changes/publication.create.test.ts +5 -2
- package/src/core/objects/publication/changes/publication.drop.test.ts +3 -1
- package/src/core/objects/publication/changes/publication.types.ts +0 -2
- package/src/core/objects/publication/publication.diff.test.ts +24 -19
- package/src/core/objects/publication/publication.diff.ts +9 -15
- package/src/core/objects/rls-policy/changes/rls-policy.alter.test.ts +31 -14
- package/src/core/objects/rls-policy/changes/rls-policy.alter.ts +3 -3
- package/src/core/objects/rls-policy/changes/rls-policy.create.test.ts +10 -3
- package/src/core/objects/rls-policy/changes/rls-policy.drop.test.ts +4 -1
- package/src/core/objects/role/changes/role.alter.test.ts +31 -15
- package/src/core/objects/role/changes/role.create.test.ts +6 -2
- package/src/core/objects/role/changes/role.drop.test.ts +4 -1
- package/src/core/objects/role/role.diff.test.ts +235 -0
- package/src/core/objects/role/role.diff.ts +21 -1
- package/src/core/objects/role/role.model.ts +122 -14
- package/src/core/objects/rule/changes/rule.alter.test.ts +7 -3
- package/src/core/objects/rule/changes/rule.comment.test.ts +5 -2
- package/src/core/objects/rule/changes/rule.create.test.ts +6 -2
- package/src/core/objects/rule/changes/rule.drop.test.ts +3 -1
- package/src/core/objects/schema/changes/schema.alter.test.ts +4 -1
- package/src/core/objects/schema/changes/schema.create.test.ts +4 -1
- package/src/core/objects/schema/changes/schema.drop.test.ts +4 -1
- package/src/core/objects/schema/schema.diff.ts +39 -102
- package/src/core/objects/schema/schema.model.ts +1 -1
- package/src/core/objects/sequence/changes/sequence.alter.test.ts +11 -5
- package/src/core/objects/sequence/changes/sequence.create.test.ts +8 -3
- package/src/core/objects/sequence/changes/sequence.drop.test.ts +4 -1
- package/src/core/objects/sequence/sequence.diff.test.ts +114 -0
- package/src/core/objects/sequence/sequence.diff.ts +39 -104
- package/src/core/objects/sequence/sequence.model.ts +1 -1
- package/src/core/objects/subscription/changes/subscription.alter.test.ts +15 -5
- package/src/core/objects/subscription/changes/subscription.comment.test.ts +5 -2
- package/src/core/objects/subscription/changes/subscription.create.test.ts +5 -2
- package/src/core/objects/subscription/changes/subscription.drop.test.ts +3 -1
- package/src/core/objects/subscription/subscription.diff.test.ts +16 -11
- package/src/core/objects/subscription/subscription.diff.ts +2 -1
- package/src/core/objects/table/changes/table.alter.test.ts +38 -15
- package/src/core/objects/table/changes/table.create.test.ts +41 -3
- package/src/core/objects/table/changes/table.create.ts +4 -0
- package/src/core/objects/table/changes/table.drop.test.ts +3 -1
- package/src/core/objects/table/table.diff.test.ts +157 -0
- package/src/core/objects/table/table.diff.ts +54 -190
- package/src/core/objects/table/table.model.ts +1 -1
- package/src/core/objects/trigger/changes/trigger.alter.test.ts +8 -4
- package/src/core/objects/trigger/changes/trigger.create.test.ts +5 -1
- package/src/core/objects/trigger/changes/trigger.create.ts +7 -4
- package/src/core/objects/trigger/changes/trigger.drop.test.ts +5 -1
- package/src/core/objects/trigger/trigger.diff.test.ts +1 -0
- package/src/core/objects/trigger/trigger.model.ts +12 -0
- package/src/core/objects/type/composite-type/changes/composite-type.alter.test.ts +10 -4
- package/src/core/objects/type/composite-type/changes/composite-type.create.test.ts +7 -2
- package/src/core/objects/type/composite-type/changes/composite-type.drop.test.ts +4 -1
- package/src/core/objects/type/composite-type/composite-type.diff.test.ts +78 -0
- package/src/core/objects/type/composite-type/composite-type.diff.ts +39 -101
- package/src/core/objects/type/composite-type/composite-type.model.ts +2 -1
- package/src/core/objects/type/enum/changes/enum.alter.test.ts +14 -5
- package/src/core/objects/type/enum/changes/enum.create.test.ts +4 -1
- package/src/core/objects/type/enum/changes/enum.drop.test.ts +4 -1
- package/src/core/objects/type/enum/enum.diff.test.ts +181 -0
- package/src/core/objects/type/enum/enum.diff.ts +58 -146
- package/src/core/objects/type/enum/enum.model.ts +1 -1
- package/src/core/objects/type/range/changes/range.alter.test.ts +3 -1
- package/src/core/objects/type/range/changes/range.create.test.ts +5 -2
- package/src/core/objects/type/range/changes/range.create.ts +6 -2
- package/src/core/objects/type/range/changes/range.drop.test.ts +3 -1
- package/src/core/objects/type/range/range.diff.test.ts +77 -0
- package/src/core/objects/type/range/range.diff.ts +39 -101
- package/src/core/objects/type/range/range.model.ts +1 -1
- package/src/core/objects/view/changes/view.alter.test.ts +8 -3
- package/src/core/objects/view/changes/view.create.test.ts +7 -2
- package/src/core/objects/view/changes/view.drop.test.ts +4 -1
- package/src/core/objects/view/view.diff.test.ts +82 -0
- package/src/core/objects/view/view.diff.ts +41 -191
- package/src/core/objects/view/view.model.ts +3 -17
- package/src/core/plan/apply.ts +9 -27
- package/src/core/plan/create.ts +173 -237
- package/src/core/plan/serialize.test.ts +317 -0
- package/src/core/plan/serialize.ts +18 -4
- package/src/core/plan/sql-format/fixtures.ts +2 -5
- package/src/core/plan/sql-format/format-lowercase-coverage.test.ts +52 -0
- package/src/core/plan/sql-format/format-off.test.ts +14 -17
- package/src/core/plan/sql-format/format-pretty-lower-leading.test.ts +27 -22
- package/src/core/plan/sql-format/format-pretty-narrow.test.ts +17 -21
- package/src/core/plan/sql-format/format-pretty-preserve.test.ts +25 -20
- package/src/core/plan/sql-format/format-pretty-upper.test.ts +23 -20
- package/src/core/plan/sql-format/keyword-case.ts +36 -1
- package/src/core/plan/ssl-config.ts +172 -0
- package/src/core/plan/types.ts +6 -0
- package/src/core/postgres-config.ts +71 -2
- package/src/core/sort/graph-builder.ts +12 -0
- package/src/core/sort/logical-sort.test.ts +371 -0
- package/src/core/sort/logical-sort.ts +32 -25
- package/src/core/sort/topological-sort.test.ts +275 -0
- package/src/core/test-utils/assert-valid-sql.ts +20 -0
- package/src/index.ts +26 -2
|
@@ -13,10 +13,10 @@ declare const compositeTypePropsSchema: z.ZodObject<{
|
|
|
13
13
|
has_subclasses: z.ZodBoolean;
|
|
14
14
|
is_populated: z.ZodBoolean;
|
|
15
15
|
replica_identity: z.ZodEnum<{
|
|
16
|
-
f: "f";
|
|
17
16
|
n: "n";
|
|
18
17
|
i: "i";
|
|
19
18
|
d: "d";
|
|
19
|
+
f: "f";
|
|
20
20
|
}>;
|
|
21
21
|
is_partition: z.ZodBoolean;
|
|
22
22
|
options: z.ZodNullable<z.ZodArray<z.ZodString>>;
|
|
@@ -82,7 +82,7 @@ export declare class CompositeType extends BasePgModel implements TableLikeObjec
|
|
|
82
82
|
has_triggers: boolean;
|
|
83
83
|
has_subclasses: boolean;
|
|
84
84
|
is_populated: boolean;
|
|
85
|
-
replica_identity: "
|
|
85
|
+
replica_identity: "n" | "i" | "d" | "f";
|
|
86
86
|
is_partition: boolean;
|
|
87
87
|
options: string[] | null;
|
|
88
88
|
partition_bound: string | null;
|
|
@@ -129,7 +129,7 @@ export declare class CompositeType extends BasePgModel implements TableLikeObjec
|
|
|
129
129
|
has_triggers: boolean;
|
|
130
130
|
has_subclasses: boolean;
|
|
131
131
|
is_populated: boolean;
|
|
132
|
-
replica_identity: "
|
|
132
|
+
replica_identity: "n" | "i" | "d" | "f";
|
|
133
133
|
is_partition: boolean;
|
|
134
134
|
options: string[] | null;
|
|
135
135
|
partition_bound: string | null;
|
|
@@ -136,6 +136,7 @@ export async function extractCompositeTypes(pool) {
|
|
|
136
136
|
c.relowner::regrole::text AS owner,
|
|
137
137
|
obj_description(c.reltype, 'pg_type') AS comment,
|
|
138
138
|
c.relacl AS relacl, -- used by privileges LATERAL
|
|
139
|
+
c.relowner AS relowner,
|
|
139
140
|
c.oid AS oid
|
|
140
141
|
FROM pg_catalog.pg_class c
|
|
141
142
|
LEFT JOIN extension_oids e ON c.reltype = e.objid
|
|
@@ -173,7 +174,7 @@ export async function extractCompositeTypes(pool) {
|
|
|
173
174
|
)
|
|
174
175
|
ORDER BY x.grantee, x.privilege_type
|
|
175
176
|
) AS privileges
|
|
176
|
-
FROM LATERAL aclexplode(ct.relacl) AS x(grantor, grantee, privilege_type, is_grantable)
|
|
177
|
+
FROM LATERAL aclexplode(COALESCE(ct.relacl, acldefault('T', ct.relowner))) AS x(grantor, grantee, privilege_type, is_grantable)
|
|
177
178
|
) priv ON TRUE
|
|
178
179
|
|
|
179
180
|
-- columns as a per-row LATERAL subquery (so no GROUP BY needed)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { Role } from "../../role/role.model.ts";
|
|
1
|
+
import type { ObjectDiffContext } from "../../diff-context.ts";
|
|
3
2
|
import type { EnumChange } from "./changes/enum.types.ts";
|
|
4
3
|
import type { Enum } from "./enum.model.ts";
|
|
5
4
|
/**
|
|
@@ -10,9 +9,4 @@ import type { Enum } from "./enum.model.ts";
|
|
|
10
9
|
* @param branch - The enums in the branch catalog.
|
|
11
10
|
* @returns A list of changes to apply to main to make it match branch.
|
|
12
11
|
*/
|
|
13
|
-
export declare function diffEnums(ctx:
|
|
14
|
-
version: number;
|
|
15
|
-
currentUser: string;
|
|
16
|
-
defaultPrivilegeState: DefaultPrivilegeState;
|
|
17
|
-
mainRoles: Record<string, Role>;
|
|
18
|
-
}, main: Record<string, Enum>, branch: Record<string, Enum>): EnumChange[];
|
|
12
|
+
export declare function diffEnums(ctx: Pick<ObjectDiffContext, "version" | "currentUser" | "defaultPrivilegeState">, main: Record<string, Enum>, branch: Record<string, Enum>): EnumChange[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { diffObjects } from "../../base.diff.js";
|
|
2
|
-
import { diffPrivileges,
|
|
2
|
+
import { diffPrivileges, emitObjectPrivilegeChanges, filterPublicBuiltInDefaults, } from "../../base.privilege-diff.js";
|
|
3
3
|
import { AlterEnumAddValue, AlterEnumChangeOwner, } from "./changes/enum.alter.js";
|
|
4
4
|
import { CreateCommentOnEnum, DropCommentOnEnum, } from "./changes/enum.comment.js";
|
|
5
5
|
import { CreateEnum } from "./changes/enum.create.js";
|
|
@@ -36,50 +36,21 @@ export function diffEnums(ctx, main, branch) {
|
|
|
36
36
|
// We compare default privileges against desired privileges to generate REVOKE/GRANT statements
|
|
37
37
|
// needed to reach the final desired state.
|
|
38
38
|
const effectiveDefaults = ctx.defaultPrivilegeState.getEffectiveDefaults(ctx.currentUser, "enum", createdEnum.schema ?? "");
|
|
39
|
+
const creatorFilteredDefaults = createdEnum.owner !== ctx.currentUser
|
|
40
|
+
? effectiveDefaults.filter((p) => p.grantee !== ctx.currentUser)
|
|
41
|
+
: effectiveDefaults;
|
|
39
42
|
// Filter out PUBLIC's built-in default USAGE privilege (PostgreSQL grants it automatically)
|
|
40
43
|
// Reference: https://www.postgresql.org/docs/17/ddl-priv.html Table 5.2
|
|
41
44
|
// This prevents generating unnecessary "GRANT USAGE TO PUBLIC" statements
|
|
42
45
|
const desiredPrivileges = filterPublicBuiltInDefaults("enum", createdEnum.privileges);
|
|
43
46
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
44
47
|
// and shouldn't be compared. Use the enum owner as the reference.
|
|
45
|
-
const privilegeResults = diffPrivileges(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
void grantable;
|
|
52
|
-
changes.push(new GrantEnumPrivileges({
|
|
53
|
-
enum: createdEnum,
|
|
54
|
-
grantee,
|
|
55
|
-
privileges: list,
|
|
56
|
-
version: ctx.version,
|
|
57
|
-
}));
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
// Generate revoke changes
|
|
61
|
-
if (result.revokes.length > 0) {
|
|
62
|
-
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
63
|
-
for (const [grantable, list] of revokeGroups) {
|
|
64
|
-
void grantable;
|
|
65
|
-
changes.push(new RevokeEnumPrivileges({
|
|
66
|
-
enum: createdEnum,
|
|
67
|
-
grantee,
|
|
68
|
-
privileges: list,
|
|
69
|
-
version: ctx.version,
|
|
70
|
-
}));
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
// Generate revoke grant option changes
|
|
74
|
-
if (result.revokeGrantOption.length > 0) {
|
|
75
|
-
changes.push(new RevokeGrantOptionEnumPrivileges({
|
|
76
|
-
enum: createdEnum,
|
|
77
|
-
grantee,
|
|
78
|
-
privilegeNames: result.revokeGrantOption,
|
|
79
|
-
version: ctx.version,
|
|
80
|
-
}));
|
|
81
|
-
}
|
|
82
|
-
}
|
|
48
|
+
const privilegeResults = diffPrivileges(filterPublicBuiltInDefaults("enum", creatorFilteredDefaults), desiredPrivileges, createdEnum.owner);
|
|
49
|
+
changes.push(...emitObjectPrivilegeChanges(privilegeResults, createdEnum, createdEnum, "enum", {
|
|
50
|
+
Grant: GrantEnumPrivileges,
|
|
51
|
+
Revoke: RevokeEnumPrivileges,
|
|
52
|
+
RevokeGrantOption: RevokeGrantOptionEnumPrivileges,
|
|
53
|
+
}, ctx.version));
|
|
83
54
|
}
|
|
84
55
|
for (const enumId of dropped) {
|
|
85
56
|
changes.push(new DropEnum({ enum: main[enumId] }));
|
|
@@ -105,42 +76,16 @@ export function diffEnums(ctx, main, branch) {
|
|
|
105
76
|
changes.push(new CreateCommentOnEnum({ enum: branchEnum }));
|
|
106
77
|
}
|
|
107
78
|
const effectiveDefaults = ctx.defaultPrivilegeState.getEffectiveDefaults(ctx.currentUser, "enum", branchEnum.schema ?? "");
|
|
79
|
+
const creatorFilteredDefaults = branchEnum.owner !== ctx.currentUser
|
|
80
|
+
? effectiveDefaults.filter((p) => p.grantee !== ctx.currentUser)
|
|
81
|
+
: effectiveDefaults;
|
|
108
82
|
const desiredPrivileges = filterPublicBuiltInDefaults("enum", branchEnum.privileges);
|
|
109
|
-
const privilegeResults = diffPrivileges(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
changes.push(new GrantEnumPrivileges({
|
|
116
|
-
enum: branchEnum,
|
|
117
|
-
grantee,
|
|
118
|
-
privileges: list,
|
|
119
|
-
version: ctx.version,
|
|
120
|
-
}));
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
if (result.revokes.length > 0) {
|
|
124
|
-
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
125
|
-
for (const [grantable, list] of revokeGroups) {
|
|
126
|
-
void grantable;
|
|
127
|
-
changes.push(new RevokeEnumPrivileges({
|
|
128
|
-
enum: branchEnum,
|
|
129
|
-
grantee,
|
|
130
|
-
privileges: list,
|
|
131
|
-
version: ctx.version,
|
|
132
|
-
}));
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
if (result.revokeGrantOption.length > 0) {
|
|
136
|
-
changes.push(new RevokeGrantOptionEnumPrivileges({
|
|
137
|
-
enum: branchEnum,
|
|
138
|
-
grantee,
|
|
139
|
-
privilegeNames: result.revokeGrantOption,
|
|
140
|
-
version: ctx.version,
|
|
141
|
-
}));
|
|
142
|
-
}
|
|
143
|
-
}
|
|
83
|
+
const privilegeResults = diffPrivileges(filterPublicBuiltInDefaults("enum", creatorFilteredDefaults), desiredPrivileges, branchEnum.owner);
|
|
84
|
+
changes.push(...emitObjectPrivilegeChanges(privilegeResults, branchEnum, branchEnum, "enum", {
|
|
85
|
+
Grant: GrantEnumPrivileges,
|
|
86
|
+
Revoke: RevokeEnumPrivileges,
|
|
87
|
+
RevokeGrantOption: RevokeGrantOptionEnumPrivileges,
|
|
88
|
+
}, ctx.version));
|
|
144
89
|
continue;
|
|
145
90
|
}
|
|
146
91
|
// OWNER
|
|
@@ -169,44 +114,12 @@ export function diffEnums(ctx, main, branch) {
|
|
|
169
114
|
const branchPrivilegesFiltered = filterPublicBuiltInDefaults("enum", branchEnum.privileges);
|
|
170
115
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
171
116
|
// and shouldn't be compared. Use branch owner as the reference.
|
|
172
|
-
const privilegeResults = diffPrivileges(mainPrivilegesFiltered, branchPrivilegesFiltered, branchEnum.owner
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
void grantable;
|
|
179
|
-
changes.push(new GrantEnumPrivileges({
|
|
180
|
-
enum: branchEnum,
|
|
181
|
-
grantee,
|
|
182
|
-
privileges: list,
|
|
183
|
-
version: ctx.version,
|
|
184
|
-
}));
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
// Generate revoke changes
|
|
188
|
-
if (result.revokes.length > 0) {
|
|
189
|
-
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
190
|
-
for (const [grantable, list] of revokeGroups) {
|
|
191
|
-
void grantable;
|
|
192
|
-
changes.push(new RevokeEnumPrivileges({
|
|
193
|
-
enum: mainEnum,
|
|
194
|
-
grantee,
|
|
195
|
-
privileges: list,
|
|
196
|
-
version: ctx.version,
|
|
197
|
-
}));
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
// Generate revoke grant option changes
|
|
201
|
-
if (result.revokeGrantOption.length > 0) {
|
|
202
|
-
changes.push(new RevokeGrantOptionEnumPrivileges({
|
|
203
|
-
enum: mainEnum,
|
|
204
|
-
grantee,
|
|
205
|
-
privilegeNames: result.revokeGrantOption,
|
|
206
|
-
version: ctx.version,
|
|
207
|
-
}));
|
|
208
|
-
}
|
|
209
|
-
}
|
|
117
|
+
const privilegeResults = diffPrivileges(mainPrivilegesFiltered, branchPrivilegesFiltered, branchEnum.owner);
|
|
118
|
+
changes.push(...emitObjectPrivilegeChanges(privilegeResults, branchEnum, mainEnum, "enum", {
|
|
119
|
+
Grant: GrantEnumPrivileges,
|
|
120
|
+
Revoke: RevokeEnumPrivileges,
|
|
121
|
+
RevokeGrantOption: RevokeGrantOptionEnumPrivileges,
|
|
122
|
+
}, ctx.version));
|
|
210
123
|
// Note: Enum renaming would also use ALTER TYPE ... RENAME TO ...
|
|
211
124
|
// But since our Enum model uses 'name' as the identity field,
|
|
212
125
|
// a name change would be handled as drop + create by diffObjects()
|
|
@@ -119,7 +119,7 @@ select
|
|
|
119
119
|
)
|
|
120
120
|
order by x.grantee, x.privilege_type
|
|
121
121
|
)
|
|
122
|
-
from lateral aclexplode(t.typacl) as x(grantor, grantee, privilege_type, is_grantable)
|
|
122
|
+
from lateral aclexplode(COALESCE(t.typacl, acldefault('T', t.typowner))) as x(grantor, grantee, privilege_type, is_grantable)
|
|
123
123
|
), '[]'
|
|
124
124
|
) as privileges
|
|
125
125
|
from
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isUserDefinedTypeSchema, parseProcedureReference, stableId, } from "../../../utils.js";
|
|
1
|
+
import { isUserDefinedTypeSchema, parseProcedureReference, parseTypeString, stableId, } from "../../../utils.js";
|
|
2
2
|
import { CreateRangeChange } from "./range.base.js";
|
|
3
3
|
/**
|
|
4
4
|
* Create a range type.
|
|
@@ -74,8 +74,11 @@ export class CreateRange extends CreateRangeChange {
|
|
|
74
74
|
const name = `${this.range.schema}.${this.range.name}`;
|
|
75
75
|
const prefix = ["CREATE TYPE", name, "AS RANGE"].join(" ");
|
|
76
76
|
const opts = [];
|
|
77
|
-
// Required subtype
|
|
78
|
-
const
|
|
77
|
+
// Required subtype (format_type may already return schema-qualified name)
|
|
78
|
+
const alreadyQualified = parseTypeString(this.range.subtype_str);
|
|
79
|
+
const subtypeQualified = !alreadyQualified &&
|
|
80
|
+
this.range.subtype_schema &&
|
|
81
|
+
this.range.subtype_schema !== "pg_catalog"
|
|
79
82
|
? `${this.range.subtype_schema}.${this.range.subtype_str}`
|
|
80
83
|
: this.range.subtype_str;
|
|
81
84
|
opts.push(`SUBTYPE = ${subtypeQualified}`);
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { Role } from "../../role/role.model.ts";
|
|
1
|
+
import type { ObjectDiffContext } from "../../diff-context.ts";
|
|
3
2
|
import type { RangeChange } from "./changes/range.types.ts";
|
|
4
3
|
import type { Range } from "./range.model.ts";
|
|
5
4
|
/**
|
|
@@ -10,9 +9,4 @@ import type { Range } from "./range.model.ts";
|
|
|
10
9
|
* @param branch - The ranges in the branch catalog.
|
|
11
10
|
* @returns A list of changes to apply to main to make it match branch.
|
|
12
11
|
*/
|
|
13
|
-
export declare function diffRanges(ctx:
|
|
14
|
-
version: number;
|
|
15
|
-
currentUser: string;
|
|
16
|
-
defaultPrivilegeState: DefaultPrivilegeState;
|
|
17
|
-
mainRoles: Record<string, Role>;
|
|
18
|
-
}, main: Record<string, Range>, branch: Record<string, Range>): RangeChange[];
|
|
12
|
+
export declare function diffRanges(ctx: Pick<ObjectDiffContext, "version" | "currentUser" | "defaultPrivilegeState">, main: Record<string, Range>, branch: Record<string, Range>): RangeChange[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { diffObjects } from "../../base.diff.js";
|
|
2
|
-
import { diffPrivileges,
|
|
2
|
+
import { diffPrivileges, emitObjectPrivilegeChanges, filterPublicBuiltInDefaults, } from "../../base.privilege-diff.js";
|
|
3
3
|
import { hasNonAlterableChanges } from "../../utils.js";
|
|
4
4
|
import { AlterRangeChangeOwner } from "./changes/range.alter.js";
|
|
5
5
|
import { CreateCommentOnRange, DropCommentOnRange, } from "./changes/range.comment.js";
|
|
@@ -37,50 +37,21 @@ export function diffRanges(ctx, main, branch) {
|
|
|
37
37
|
// We compare default privileges against desired privileges to generate REVOKE/GRANT statements
|
|
38
38
|
// needed to reach the final desired state.
|
|
39
39
|
const effectiveDefaults = ctx.defaultPrivilegeState.getEffectiveDefaults(ctx.currentUser, "range", createdRange.schema ?? "");
|
|
40
|
+
const creatorFilteredDefaults = createdRange.owner !== ctx.currentUser
|
|
41
|
+
? effectiveDefaults.filter((p) => p.grantee !== ctx.currentUser)
|
|
42
|
+
: effectiveDefaults;
|
|
40
43
|
// Filter out PUBLIC's built-in default USAGE privilege (PostgreSQL grants it automatically)
|
|
41
44
|
// Reference: https://www.postgresql.org/docs/17/ddl-priv.html Table 5.2
|
|
42
45
|
// This prevents generating unnecessary "GRANT USAGE TO PUBLIC" statements
|
|
43
46
|
const desiredPrivileges = filterPublicBuiltInDefaults("range", createdRange.privileges);
|
|
44
47
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
45
48
|
// and shouldn't be compared. Use the range owner as the reference.
|
|
46
|
-
const privilegeResults = diffPrivileges(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
void grantable;
|
|
53
|
-
changes.push(new GrantRangePrivileges({
|
|
54
|
-
range: createdRange,
|
|
55
|
-
grantee,
|
|
56
|
-
privileges: list,
|
|
57
|
-
version: ctx.version,
|
|
58
|
-
}));
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
// Generate revoke changes
|
|
62
|
-
if (result.revokes.length > 0) {
|
|
63
|
-
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
64
|
-
for (const [grantable, list] of revokeGroups) {
|
|
65
|
-
void grantable;
|
|
66
|
-
changes.push(new RevokeRangePrivileges({
|
|
67
|
-
range: createdRange,
|
|
68
|
-
grantee,
|
|
69
|
-
privileges: list,
|
|
70
|
-
version: ctx.version,
|
|
71
|
-
}));
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
// Generate revoke grant option changes
|
|
75
|
-
if (result.revokeGrantOption.length > 0) {
|
|
76
|
-
changes.push(new RevokeGrantOptionRangePrivileges({
|
|
77
|
-
range: createdRange,
|
|
78
|
-
grantee,
|
|
79
|
-
privilegeNames: result.revokeGrantOption,
|
|
80
|
-
version: ctx.version,
|
|
81
|
-
}));
|
|
82
|
-
}
|
|
83
|
-
}
|
|
49
|
+
const privilegeResults = diffPrivileges(filterPublicBuiltInDefaults("range", creatorFilteredDefaults), desiredPrivileges, createdRange.owner);
|
|
50
|
+
changes.push(...emitObjectPrivilegeChanges(privilegeResults, createdRange, createdRange, "range", {
|
|
51
|
+
Grant: GrantRangePrivileges,
|
|
52
|
+
Revoke: RevokeRangePrivileges,
|
|
53
|
+
RevokeGrantOption: RevokeGrantOptionRangePrivileges,
|
|
54
|
+
}, ctx.version));
|
|
84
55
|
}
|
|
85
56
|
for (const id of dropped) {
|
|
86
57
|
changes.push(new DropRange({ range: main[id] }));
|
|
@@ -128,44 +99,12 @@ export function diffRanges(ctx, main, branch) {
|
|
|
128
99
|
const branchPrivilegesFiltered = filterPublicBuiltInDefaults("range", branchRange.privileges);
|
|
129
100
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
130
101
|
// and shouldn't be compared. Use branch owner as the reference.
|
|
131
|
-
const privilegeResults = diffPrivileges(mainPrivilegesFiltered, branchPrivilegesFiltered, branchRange.owner
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
void grantable;
|
|
138
|
-
changes.push(new GrantRangePrivileges({
|
|
139
|
-
range: branchRange,
|
|
140
|
-
grantee,
|
|
141
|
-
privileges: list,
|
|
142
|
-
version: ctx.version,
|
|
143
|
-
}));
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
// Generate revoke changes
|
|
147
|
-
if (result.revokes.length > 0) {
|
|
148
|
-
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
149
|
-
for (const [grantable, list] of revokeGroups) {
|
|
150
|
-
void grantable;
|
|
151
|
-
changes.push(new RevokeRangePrivileges({
|
|
152
|
-
range: mainRange,
|
|
153
|
-
grantee,
|
|
154
|
-
privileges: list,
|
|
155
|
-
version: ctx.version,
|
|
156
|
-
}));
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
// Generate revoke grant option changes
|
|
160
|
-
if (result.revokeGrantOption.length > 0) {
|
|
161
|
-
changes.push(new RevokeGrantOptionRangePrivileges({
|
|
162
|
-
range: mainRange,
|
|
163
|
-
grantee,
|
|
164
|
-
privilegeNames: result.revokeGrantOption,
|
|
165
|
-
version: ctx.version,
|
|
166
|
-
}));
|
|
167
|
-
}
|
|
168
|
-
}
|
|
102
|
+
const privilegeResults = diffPrivileges(mainPrivilegesFiltered, branchPrivilegesFiltered, branchRange.owner);
|
|
103
|
+
changes.push(...emitObjectPrivilegeChanges(privilegeResults, branchRange, mainRange, "range", {
|
|
104
|
+
Grant: GrantRangePrivileges,
|
|
105
|
+
Revoke: RevokeRangePrivileges,
|
|
106
|
+
RevokeGrantOption: RevokeGrantOptionRangePrivileges,
|
|
107
|
+
}, ctx.version));
|
|
169
108
|
}
|
|
170
109
|
}
|
|
171
110
|
return changes;
|
|
@@ -140,7 +140,7 @@ select
|
|
|
140
140
|
)
|
|
141
141
|
order by x.grantee, x.privilege_type
|
|
142
142
|
)
|
|
143
|
-
from lateral aclexplode(t.typacl) as x(grantor, grantee, privilege_type, is_grantable)
|
|
143
|
+
from lateral aclexplode(COALESCE(t.typacl, acldefault('T', t.typowner))) as x(grantor, grantee, privilege_type, is_grantable)
|
|
144
144
|
), '[]'
|
|
145
145
|
) as privileges
|
|
146
146
|
from pg_catalog.pg_range r
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { Role } from "../role/role.model.ts";
|
|
1
|
+
import type { ObjectDiffContext } from "../diff-context.ts";
|
|
3
2
|
import type { ViewChange } from "./changes/view.types.ts";
|
|
4
3
|
import type { View } from "./view.model.ts";
|
|
5
4
|
/**
|
|
@@ -10,9 +9,4 @@ import type { View } from "./view.model.ts";
|
|
|
10
9
|
* @param branch - The views in the branch catalog.
|
|
11
10
|
* @returns A list of changes to apply to main to make it match branch.
|
|
12
11
|
*/
|
|
13
|
-
export declare function diffViews(ctx:
|
|
14
|
-
version: number;
|
|
15
|
-
currentUser: string;
|
|
16
|
-
defaultPrivilegeState: DefaultPrivilegeState;
|
|
17
|
-
mainRoles: Record<string, Role>;
|
|
18
|
-
}, main: Record<string, View>, branch: Record<string, View>): ViewChange[];
|
|
12
|
+
export declare function diffViews(ctx: Pick<ObjectDiffContext, "version" | "currentUser" | "defaultPrivilegeState">, main: Record<string, View>, branch: Record<string, View>): ViewChange[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { diffObjects } from "../base.diff.js";
|
|
2
|
-
import { diffPrivileges,
|
|
2
|
+
import { diffPrivileges, emitColumnPrivilegeChanges, } from "../base.privilege-diff.js";
|
|
3
3
|
import { deepEqual, hasNonAlterableChanges } from "../utils.js";
|
|
4
4
|
import { AlterViewChangeOwner, AlterViewResetOptions, AlterViewSetOptions, } from "./changes/view.alter.js";
|
|
5
5
|
import { CreateCommentOnView, DropCommentOnView, } from "./changes/view.comment.js";
|
|
@@ -34,87 +34,18 @@ export function diffViews(ctx, main, branch) {
|
|
|
34
34
|
// We compare default privileges against desired privileges to generate REVOKE/GRANT statements
|
|
35
35
|
// needed to reach the final desired state.
|
|
36
36
|
const effectiveDefaults = ctx.defaultPrivilegeState.getEffectiveDefaults(ctx.currentUser, "view", v.schema ?? "");
|
|
37
|
+
const creatorFilteredDefaults = v.owner !== ctx.currentUser
|
|
38
|
+
? effectiveDefaults.filter((p) => p.grantee !== ctx.currentUser)
|
|
39
|
+
: effectiveDefaults;
|
|
37
40
|
const desiredPrivileges = v.privileges;
|
|
38
41
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
39
42
|
// and shouldn't be compared. Use the view owner as the reference.
|
|
40
|
-
const privilegeResults = diffPrivileges(
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
for (const [grantable, privSet] of group.byGrant) {
|
|
47
|
-
const privileges = Array.from(privSet).map((priv) => ({
|
|
48
|
-
privilege: priv,
|
|
49
|
-
grantable,
|
|
50
|
-
}));
|
|
51
|
-
changes.push(new GrantViewPrivileges({
|
|
52
|
-
view: v,
|
|
53
|
-
grantee,
|
|
54
|
-
privileges,
|
|
55
|
-
columns: group.columns,
|
|
56
|
-
version: ctx.version,
|
|
57
|
-
}));
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
// Generate revoke changes
|
|
62
|
-
if (result.revokes.length > 0) {
|
|
63
|
-
const revokeGroups = groupPrivilegesByColumns(result.revokes);
|
|
64
|
-
for (const [, group] of revokeGroups) {
|
|
65
|
-
const allPrivileges = new Set();
|
|
66
|
-
for (const [, privSet] of group.byGrant) {
|
|
67
|
-
for (const priv of privSet) {
|
|
68
|
-
allPrivileges.add(priv);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
const privileges = Array.from(allPrivileges).map((priv) => ({
|
|
72
|
-
privilege: priv,
|
|
73
|
-
grantable: false,
|
|
74
|
-
}));
|
|
75
|
-
changes.push(new RevokeViewPrivileges({
|
|
76
|
-
view: v,
|
|
77
|
-
grantee,
|
|
78
|
-
privileges,
|
|
79
|
-
columns: group.columns,
|
|
80
|
-
version: ctx.version,
|
|
81
|
-
}));
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
// Generate revoke grant option changes
|
|
85
|
-
if (result.revokeGrantOption.length > 0) {
|
|
86
|
-
const revokeGrantGroups = new Map();
|
|
87
|
-
for (const r of result.revokeGrantOption) {
|
|
88
|
-
// For revoke grant option, we need to find the columns from the effective defaults
|
|
89
|
-
const originalPriv = effectiveDefaults.find((p) => p.grantee === grantee && p.privilege === r);
|
|
90
|
-
const key = originalPriv?.columns
|
|
91
|
-
? originalPriv.columns.sort().join(",")
|
|
92
|
-
: "";
|
|
93
|
-
if (!revokeGrantGroups.has(key)) {
|
|
94
|
-
revokeGrantGroups.set(key, {
|
|
95
|
-
columns: originalPriv?.columns
|
|
96
|
-
? [...originalPriv.columns]
|
|
97
|
-
: undefined,
|
|
98
|
-
privileges: new Set(),
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
const group = revokeGrantGroups.get(key);
|
|
102
|
-
if (!group)
|
|
103
|
-
continue;
|
|
104
|
-
group.privileges.add(r);
|
|
105
|
-
}
|
|
106
|
-
for (const [, group] of revokeGrantGroups) {
|
|
107
|
-
const privilegeNames = Array.from(group.privileges);
|
|
108
|
-
changes.push(new RevokeGrantOptionViewPrivileges({
|
|
109
|
-
view: v,
|
|
110
|
-
grantee,
|
|
111
|
-
privilegeNames,
|
|
112
|
-
columns: group.columns,
|
|
113
|
-
version: ctx.version,
|
|
114
|
-
}));
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
43
|
+
const privilegeResults = diffPrivileges(creatorFilteredDefaults, desiredPrivileges, v.owner);
|
|
44
|
+
changes.push(...emitColumnPrivilegeChanges(privilegeResults, v, v, "view", {
|
|
45
|
+
Grant: GrantViewPrivileges,
|
|
46
|
+
Revoke: RevokeViewPrivileges,
|
|
47
|
+
RevokeGrantOption: RevokeGrantOptionViewPrivileges,
|
|
48
|
+
}, effectiveDefaults, ctx.version));
|
|
118
49
|
}
|
|
119
50
|
for (const viewId of dropped) {
|
|
120
51
|
changes.push(new DropView({ view: main[viewId] }));
|
|
@@ -185,85 +116,12 @@ export function diffViews(ctx, main, branch) {
|
|
|
185
116
|
// PRIVILEGES (unified object and column privileges)
|
|
186
117
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
187
118
|
// and shouldn't be compared. Use branch owner as the reference.
|
|
188
|
-
const privilegeResults = diffPrivileges(mainView.privileges, branchView.privileges, branchView.owner
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
for (const [grantable, privSet] of group.byGrant) {
|
|
195
|
-
const privileges = Array.from(privSet).map((priv) => ({
|
|
196
|
-
privilege: priv,
|
|
197
|
-
grantable,
|
|
198
|
-
}));
|
|
199
|
-
changes.push(new GrantViewPrivileges({
|
|
200
|
-
view: branchView,
|
|
201
|
-
grantee,
|
|
202
|
-
privileges,
|
|
203
|
-
columns: group.columns,
|
|
204
|
-
version: ctx.version,
|
|
205
|
-
}));
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
// Generate revoke changes
|
|
210
|
-
if (result.revokes.length > 0) {
|
|
211
|
-
const revokeGroups = groupPrivilegesByColumns(result.revokes);
|
|
212
|
-
for (const [, group] of revokeGroups) {
|
|
213
|
-
// Collapse all grantable groups into a single revoke (grantable: false)
|
|
214
|
-
const allPrivileges = new Set();
|
|
215
|
-
for (const [, privSet] of group.byGrant) {
|
|
216
|
-
for (const priv of privSet) {
|
|
217
|
-
allPrivileges.add(priv);
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
const privileges = Array.from(allPrivileges).map((priv) => ({
|
|
221
|
-
privilege: priv,
|
|
222
|
-
grantable: false,
|
|
223
|
-
}));
|
|
224
|
-
changes.push(new RevokeViewPrivileges({
|
|
225
|
-
view: mainView,
|
|
226
|
-
grantee,
|
|
227
|
-
privileges,
|
|
228
|
-
columns: group.columns,
|
|
229
|
-
version: ctx.version,
|
|
230
|
-
}));
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
// Generate revoke grant option changes
|
|
234
|
-
if (result.revokeGrantOption.length > 0) {
|
|
235
|
-
const revokeGrantGroups = new Map();
|
|
236
|
-
for (const r of result.revokeGrantOption) {
|
|
237
|
-
// For revoke grant option, we need to find the columns from the original privilege
|
|
238
|
-
const originalPriv = mainView.privileges.find((p) => p.grantee === grantee && p.privilege === r);
|
|
239
|
-
const key = originalPriv?.columns
|
|
240
|
-
? originalPriv.columns.sort().join(",")
|
|
241
|
-
: "";
|
|
242
|
-
if (!revokeGrantGroups.has(key)) {
|
|
243
|
-
revokeGrantGroups.set(key, {
|
|
244
|
-
columns: originalPriv?.columns
|
|
245
|
-
? [...originalPriv.columns]
|
|
246
|
-
: undefined,
|
|
247
|
-
privileges: new Set(),
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
const group = revokeGrantGroups.get(key);
|
|
251
|
-
if (!group)
|
|
252
|
-
continue;
|
|
253
|
-
group.privileges.add(r);
|
|
254
|
-
}
|
|
255
|
-
for (const [, group] of revokeGrantGroups) {
|
|
256
|
-
const privilegeNames = Array.from(group.privileges);
|
|
257
|
-
changes.push(new RevokeGrantOptionViewPrivileges({
|
|
258
|
-
view: mainView,
|
|
259
|
-
grantee,
|
|
260
|
-
privilegeNames,
|
|
261
|
-
columns: group.columns,
|
|
262
|
-
version: ctx.version,
|
|
263
|
-
}));
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
}
|
|
119
|
+
const privilegeResults = diffPrivileges(mainView.privileges, branchView.privileges, branchView.owner);
|
|
120
|
+
changes.push(...emitColumnPrivilegeChanges(privilegeResults, branchView, mainView, "view", {
|
|
121
|
+
Grant: GrantViewPrivileges,
|
|
122
|
+
Revoke: RevokeViewPrivileges,
|
|
123
|
+
RevokeGrantOption: RevokeGrantOptionViewPrivileges,
|
|
124
|
+
}, mainView.privileges, ctx.version));
|
|
267
125
|
}
|
|
268
126
|
}
|
|
269
127
|
return changes;
|