@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
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
|
|
2
3
|
import { Schema } from "../schema.model.ts";
|
|
3
4
|
import { CreateSchema } from "./schema.create.ts";
|
|
4
5
|
|
|
5
6
|
describe("schema", () => {
|
|
6
|
-
test("create", () => {
|
|
7
|
+
test("create", async () => {
|
|
7
8
|
const schema = new Schema({
|
|
8
9
|
name: "test_schema",
|
|
9
10
|
owner: "test",
|
|
@@ -15,6 +16,8 @@ describe("schema", () => {
|
|
|
15
16
|
schema,
|
|
16
17
|
});
|
|
17
18
|
|
|
19
|
+
await assertValidSql(change.serialize());
|
|
20
|
+
|
|
18
21
|
expect(change.serialize()).toBe(
|
|
19
22
|
"CREATE SCHEMA test_schema AUTHORIZATION test",
|
|
20
23
|
);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
|
|
2
3
|
import { Schema } from "../schema.model.ts";
|
|
3
4
|
import { DropSchema } from "./schema.drop.ts";
|
|
4
5
|
|
|
5
6
|
describe("schema", () => {
|
|
6
|
-
test("drop", () => {
|
|
7
|
+
test("drop", async () => {
|
|
7
8
|
const schema = new Schema({
|
|
8
9
|
name: "test_schema",
|
|
9
10
|
owner: "test",
|
|
@@ -15,6 +16,8 @@ describe("schema", () => {
|
|
|
15
16
|
schema,
|
|
16
17
|
});
|
|
17
18
|
|
|
19
|
+
await assertValidSql(change.serialize());
|
|
20
|
+
|
|
18
21
|
expect(change.serialize()).toBe("DROP SCHEMA test_schema");
|
|
19
22
|
});
|
|
20
23
|
});
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import type { DefaultPrivilegeState } from "../base.default-privileges.ts";
|
|
2
1
|
import { diffObjects } from "../base.diff.ts";
|
|
3
2
|
import {
|
|
4
3
|
diffPrivileges,
|
|
5
|
-
|
|
4
|
+
emitObjectPrivilegeChanges,
|
|
6
5
|
} from "../base.privilege-diff.ts";
|
|
7
|
-
import type {
|
|
6
|
+
import type { ObjectDiffContext } from "../diff-context.ts";
|
|
8
7
|
import { AlterSchemaChangeOwner } from "./changes/schema.alter.ts";
|
|
9
8
|
import {
|
|
10
9
|
CreateCommentOnSchema,
|
|
@@ -29,12 +28,10 @@ import type { Schema } from "./schema.model.ts";
|
|
|
29
28
|
* @returns A list of changes to apply to main to make it match branch.
|
|
30
29
|
*/
|
|
31
30
|
export function diffSchemas(
|
|
32
|
-
ctx:
|
|
33
|
-
|
|
34
|
-
currentUser
|
|
35
|
-
|
|
36
|
-
mainRoles: Record<string, Role>;
|
|
37
|
-
},
|
|
31
|
+
ctx: Pick<
|
|
32
|
+
ObjectDiffContext,
|
|
33
|
+
"version" | "currentUser" | "defaultPrivilegeState"
|
|
34
|
+
>,
|
|
38
35
|
main: Record<string, Schema>,
|
|
39
36
|
branch: Record<string, Schema>,
|
|
40
37
|
): SchemaChange[] {
|
|
@@ -60,61 +57,33 @@ export function diffSchemas(
|
|
|
60
57
|
"schema",
|
|
61
58
|
"",
|
|
62
59
|
);
|
|
60
|
+
const creatorFilteredDefaults =
|
|
61
|
+
sc.owner !== ctx.currentUser
|
|
62
|
+
? effectiveDefaults.filter((p) => p.grantee !== ctx.currentUser)
|
|
63
|
+
: effectiveDefaults;
|
|
63
64
|
const desiredPrivileges = sc.privileges;
|
|
64
65
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
65
66
|
// and shouldn't be compared. Use the schema owner as the reference.
|
|
66
67
|
const privilegeResults = diffPrivileges(
|
|
67
|
-
|
|
68
|
+
creatorFilteredDefaults,
|
|
68
69
|
desiredPrivileges,
|
|
69
70
|
sc.owner,
|
|
70
|
-
ctx.mainRoles,
|
|
71
71
|
);
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Generate revoke changes
|
|
91
|
-
if (result.revokes.length > 0) {
|
|
92
|
-
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
93
|
-
for (const [grantable, list] of revokeGroups) {
|
|
94
|
-
void grantable;
|
|
95
|
-
changes.push(
|
|
96
|
-
new RevokeSchemaPrivileges({
|
|
97
|
-
schema: sc,
|
|
98
|
-
grantee,
|
|
99
|
-
privileges: list,
|
|
100
|
-
version: ctx.version,
|
|
101
|
-
}),
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Generate revoke grant option changes
|
|
107
|
-
if (result.revokeGrantOption.length > 0) {
|
|
108
|
-
changes.push(
|
|
109
|
-
new RevokeGrantOptionSchemaPrivileges({
|
|
110
|
-
schema: sc,
|
|
111
|
-
grantee,
|
|
112
|
-
privilegeNames: result.revokeGrantOption,
|
|
113
|
-
version: ctx.version,
|
|
114
|
-
}),
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
73
|
+
changes.push(
|
|
74
|
+
...(emitObjectPrivilegeChanges(
|
|
75
|
+
privilegeResults,
|
|
76
|
+
sc,
|
|
77
|
+
sc,
|
|
78
|
+
"schema",
|
|
79
|
+
{
|
|
80
|
+
Grant: GrantSchemaPrivileges,
|
|
81
|
+
Revoke: RevokeSchemaPrivileges,
|
|
82
|
+
RevokeGrantOption: RevokeGrantOptionSchemaPrivileges,
|
|
83
|
+
},
|
|
84
|
+
ctx.version,
|
|
85
|
+
) as SchemaChange[]),
|
|
86
|
+
);
|
|
118
87
|
}
|
|
119
88
|
|
|
120
89
|
for (const schemaId of dropped) {
|
|
@@ -151,54 +120,22 @@ export function diffSchemas(
|
|
|
151
120
|
mainSchema.privileges,
|
|
152
121
|
branchSchema.privileges,
|
|
153
122
|
branchSchema.owner,
|
|
154
|
-
ctx.mainRoles,
|
|
155
123
|
);
|
|
156
124
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Generate revoke changes
|
|
175
|
-
if (result.revokes.length > 0) {
|
|
176
|
-
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
177
|
-
for (const [grantable, list] of revokeGroups) {
|
|
178
|
-
void grantable;
|
|
179
|
-
changes.push(
|
|
180
|
-
new RevokeSchemaPrivileges({
|
|
181
|
-
schema: mainSchema,
|
|
182
|
-
grantee,
|
|
183
|
-
privileges: list,
|
|
184
|
-
version: ctx.version,
|
|
185
|
-
}),
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Generate revoke grant option changes
|
|
191
|
-
if (result.revokeGrantOption.length > 0) {
|
|
192
|
-
changes.push(
|
|
193
|
-
new RevokeGrantOptionSchemaPrivileges({
|
|
194
|
-
schema: mainSchema,
|
|
195
|
-
grantee,
|
|
196
|
-
privilegeNames: result.revokeGrantOption,
|
|
197
|
-
version: ctx.version,
|
|
198
|
-
}),
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
125
|
+
changes.push(
|
|
126
|
+
...(emitObjectPrivilegeChanges(
|
|
127
|
+
privilegeResults,
|
|
128
|
+
branchSchema,
|
|
129
|
+
mainSchema,
|
|
130
|
+
"schema",
|
|
131
|
+
{
|
|
132
|
+
Grant: GrantSchemaPrivileges,
|
|
133
|
+
Revoke: RevokeSchemaPrivileges,
|
|
134
|
+
RevokeGrantOption: RevokeGrantOptionSchemaPrivileges,
|
|
135
|
+
},
|
|
136
|
+
ctx.version,
|
|
137
|
+
) as SchemaChange[]),
|
|
138
|
+
);
|
|
202
139
|
|
|
203
140
|
// Note: Schema renaming would also use ALTER SCHEMA ... RENAME TO ...
|
|
204
141
|
// But since our Schema model uses 'schema' as the identity field,
|
|
@@ -86,7 +86,7 @@ export async function extractSchemas(pool: Pool): Promise<Schema[]> {
|
|
|
86
86
|
)
|
|
87
87
|
order by x.grantee, x.privilege_type
|
|
88
88
|
)
|
|
89
|
-
from lateral aclexplode(nspacl) as x(grantor, grantee, privilege_type, is_grantable)
|
|
89
|
+
from lateral aclexplode(COALESCE(nspacl, acldefault('n', nspowner))) as x(grantor, grantee, privilege_type, is_grantable)
|
|
90
90
|
), '[]'
|
|
91
91
|
) as privileges
|
|
92
92
|
from
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
|
|
2
3
|
import { Sequence, type SequenceProps } from "../sequence.model.ts";
|
|
3
4
|
import {
|
|
4
5
|
AlterSequenceSetOptions,
|
|
@@ -7,7 +8,7 @@ import {
|
|
|
7
8
|
|
|
8
9
|
describe.concurrent("sequence", () => {
|
|
9
10
|
describe("alter", () => {
|
|
10
|
-
test("set owned by table column", () => {
|
|
11
|
+
test("set owned by table column", async () => {
|
|
11
12
|
const props: Omit<
|
|
12
13
|
SequenceProps,
|
|
13
14
|
"owned_by_schema" | "owned_by_table" | "owned_by_column"
|
|
@@ -38,12 +39,14 @@ describe.concurrent("sequence", () => {
|
|
|
38
39
|
ownedBy: { schema: "public", table: "t", column: "id" },
|
|
39
40
|
});
|
|
40
41
|
|
|
42
|
+
await assertValidSql(change.serialize());
|
|
43
|
+
|
|
41
44
|
expect(change.serialize()).toBe(
|
|
42
45
|
"ALTER SEQUENCE public.test_sequence OWNED BY public.t.id",
|
|
43
46
|
);
|
|
44
47
|
});
|
|
45
48
|
|
|
46
|
-
test("owned by none", () => {
|
|
49
|
+
test("owned by none", async () => {
|
|
47
50
|
const sequence = new Sequence({
|
|
48
51
|
schema: "public",
|
|
49
52
|
name: "s",
|
|
@@ -63,14 +66,15 @@ describe.concurrent("sequence", () => {
|
|
|
63
66
|
owner: "test",
|
|
64
67
|
});
|
|
65
68
|
const change = new AlterSequenceSetOwnedBy({ sequence, ownedBy: null });
|
|
69
|
+
await assertValidSql(change.serialize());
|
|
66
70
|
expect(change.serialize()).toBe("ALTER SEQUENCE public.s OWNED BY NONE");
|
|
67
71
|
});
|
|
68
72
|
|
|
69
|
-
test("drop + create sequence (handled in diff)", () => {
|
|
73
|
+
test("drop + create sequence (handled in diff)", async () => {
|
|
70
74
|
expect(1).toBe(1);
|
|
71
75
|
});
|
|
72
76
|
|
|
73
|
-
test("alter options: increment, min/max, start, cache, cycle", () => {
|
|
77
|
+
test("alter options: increment, min/max, start, cache, cycle", async () => {
|
|
74
78
|
const sequence = new Sequence({
|
|
75
79
|
schema: "public",
|
|
76
80
|
name: "s",
|
|
@@ -105,12 +109,13 @@ describe.concurrent("sequence", () => {
|
|
|
105
109
|
"CYCLE",
|
|
106
110
|
],
|
|
107
111
|
});
|
|
112
|
+
await assertValidSql(change.serialize());
|
|
108
113
|
expect(change.serialize()).toBe(
|
|
109
114
|
"ALTER SEQUENCE public.s INCREMENT BY 2 MINVALUE 5 MAXVALUE 100 START WITH 10 CACHE 3 CYCLE",
|
|
110
115
|
);
|
|
111
116
|
});
|
|
112
117
|
|
|
113
|
-
test("alter options: reset to defaults uses NO MINVALUE/NO MAXVALUE", () => {
|
|
118
|
+
test("alter options: reset to defaults uses NO MINVALUE/NO MAXVALUE", async () => {
|
|
114
119
|
const sequence = new Sequence({
|
|
115
120
|
schema: "public",
|
|
116
121
|
name: "s",
|
|
@@ -143,6 +148,7 @@ describe.concurrent("sequence", () => {
|
|
|
143
148
|
"NO CYCLE",
|
|
144
149
|
],
|
|
145
150
|
});
|
|
151
|
+
await assertValidSql(change.serialize());
|
|
146
152
|
expect(change.serialize()).toBe(
|
|
147
153
|
"ALTER SEQUENCE public.s INCREMENT BY 1 NO MINVALUE NO MAXVALUE START WITH 1 CACHE 1 NO CYCLE",
|
|
148
154
|
);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
|
|
2
3
|
import { Sequence } from "../sequence.model.ts";
|
|
3
4
|
import { CreateSequence } from "./sequence.create.ts";
|
|
4
5
|
|
|
5
6
|
describe("sequence", () => {
|
|
6
|
-
test("create minimal (all defaults elided)", () => {
|
|
7
|
+
test("create minimal (all defaults elided)", async () => {
|
|
7
8
|
const sequence = new Sequence({
|
|
8
9
|
schema: "public",
|
|
9
10
|
name: "s_min",
|
|
@@ -24,10 +25,11 @@ describe("sequence", () => {
|
|
|
24
25
|
});
|
|
25
26
|
|
|
26
27
|
const change = new CreateSequence({ sequence });
|
|
28
|
+
await assertValidSql(change.serialize());
|
|
27
29
|
expect(change.serialize()).toBe("CREATE SEQUENCE public.s_min");
|
|
28
30
|
});
|
|
29
31
|
|
|
30
|
-
test("create", () => {
|
|
32
|
+
test("create", async () => {
|
|
31
33
|
const sequence = new Sequence({
|
|
32
34
|
schema: "public",
|
|
33
35
|
name: "test_sequence",
|
|
@@ -51,12 +53,14 @@ describe("sequence", () => {
|
|
|
51
53
|
sequence,
|
|
52
54
|
});
|
|
53
55
|
|
|
56
|
+
await assertValidSql(change.serialize());
|
|
57
|
+
|
|
54
58
|
expect(change.serialize()).toBe(
|
|
55
59
|
"CREATE SEQUENCE public.test_sequence AS integer",
|
|
56
60
|
);
|
|
57
61
|
});
|
|
58
62
|
|
|
59
|
-
test("create with all options", () => {
|
|
63
|
+
test("create with all options", async () => {
|
|
60
64
|
const sequence = new Sequence({
|
|
61
65
|
schema: "public",
|
|
62
66
|
name: "s_all",
|
|
@@ -77,6 +81,7 @@ describe("sequence", () => {
|
|
|
77
81
|
});
|
|
78
82
|
|
|
79
83
|
const change = new CreateSequence({ sequence });
|
|
84
|
+
await assertValidSql(change.serialize());
|
|
80
85
|
expect(change.serialize()).toBe(
|
|
81
86
|
"CREATE SEQUENCE public.s_all AS integer INCREMENT BY 2 MINVALUE 5 MAXVALUE 100 START WITH 10 CACHE 3 CYCLE",
|
|
82
87
|
);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { assertValidSql } from "../../../test-utils/assert-valid-sql.ts";
|
|
2
3
|
import { Sequence } from "../sequence.model.ts";
|
|
3
4
|
import { DropSequence } from "./sequence.drop.ts";
|
|
4
5
|
|
|
5
6
|
describe("sequence", () => {
|
|
6
|
-
test("drop", () => {
|
|
7
|
+
test("drop", async () => {
|
|
7
8
|
const sequence = new Sequence({
|
|
8
9
|
schema: "public",
|
|
9
10
|
name: "test_sequence",
|
|
@@ -27,6 +28,8 @@ describe("sequence", () => {
|
|
|
27
28
|
sequence,
|
|
28
29
|
});
|
|
29
30
|
|
|
31
|
+
await assertValidSql(change.serialize());
|
|
32
|
+
|
|
30
33
|
expect(change.serialize()).toBe("DROP SEQUENCE public.test_sequence");
|
|
31
34
|
});
|
|
32
35
|
});
|
|
@@ -5,8 +5,17 @@ import {
|
|
|
5
5
|
AlterSequenceSetOptions,
|
|
6
6
|
AlterSequenceSetOwnedBy,
|
|
7
7
|
} from "./changes/sequence.alter.ts";
|
|
8
|
+
import {
|
|
9
|
+
CreateCommentOnSequence,
|
|
10
|
+
DropCommentOnSequence,
|
|
11
|
+
} from "./changes/sequence.comment.ts";
|
|
8
12
|
import { CreateSequence } from "./changes/sequence.create.ts";
|
|
9
13
|
import { DropSequence } from "./changes/sequence.drop.ts";
|
|
14
|
+
import {
|
|
15
|
+
GrantSequencePrivileges,
|
|
16
|
+
RevokeGrantOptionSequencePrivileges,
|
|
17
|
+
RevokeSequencePrivileges,
|
|
18
|
+
} from "./changes/sequence.privilege.ts";
|
|
10
19
|
import { diffSequences } from "./sequence.diff.ts";
|
|
11
20
|
import { Sequence, type SequenceProps } from "./sequence.model.ts";
|
|
12
21
|
|
|
@@ -138,4 +147,109 @@ describe.concurrent("sequence.diff", () => {
|
|
|
138
147
|
expect(changes).toHaveLength(1);
|
|
139
148
|
expect(changes[0]).toBeInstanceOf(DropSequence);
|
|
140
149
|
});
|
|
150
|
+
|
|
151
|
+
test("create with comment emits CreateCommentOnSequence", () => {
|
|
152
|
+
const s = new Sequence({ ...base, comment: "my seq" });
|
|
153
|
+
const changes = diffSequences(testContext, {}, { [s.stableId]: s });
|
|
154
|
+
expect(changes[0]).toBeInstanceOf(CreateSequence);
|
|
155
|
+
expect(changes.some((c) => c instanceof CreateCommentOnSequence)).toBe(
|
|
156
|
+
true,
|
|
157
|
+
);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
test("create with owned-by emits AlterSequenceSetOwnedBy", () => {
|
|
161
|
+
const s = new Sequence({
|
|
162
|
+
...base,
|
|
163
|
+
owned_by_schema: "public",
|
|
164
|
+
owned_by_table: "t",
|
|
165
|
+
owned_by_column: "id",
|
|
166
|
+
});
|
|
167
|
+
const changes = diffSequences(testContext, {}, { [s.stableId]: s });
|
|
168
|
+
expect(changes[0]).toBeInstanceOf(CreateSequence);
|
|
169
|
+
expect(changes.some((c) => c instanceof AlterSequenceSetOwnedBy)).toBe(
|
|
170
|
+
true,
|
|
171
|
+
);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test("create with privileges emits grant, revoke, and revoke grant option", () => {
|
|
175
|
+
const dpState = new DefaultPrivilegeState({});
|
|
176
|
+
dpState.applyGrant("postgres", "S", null, "role_revoke_me", [
|
|
177
|
+
{ privilege: "USAGE", grantable: false },
|
|
178
|
+
]);
|
|
179
|
+
dpState.applyGrant("postgres", "S", null, "role_downgrade", [
|
|
180
|
+
{ privilege: "USAGE", grantable: true },
|
|
181
|
+
]);
|
|
182
|
+
const ctx = { ...testContext, defaultPrivilegeState: dpState };
|
|
183
|
+
const s = new Sequence({
|
|
184
|
+
...base,
|
|
185
|
+
privileges: [
|
|
186
|
+
{ grantee: "role_grant_me", privilege: "USAGE", grantable: false },
|
|
187
|
+
{ grantee: "role_downgrade", privilege: "USAGE", grantable: false },
|
|
188
|
+
],
|
|
189
|
+
});
|
|
190
|
+
const changes = diffSequences(ctx, {}, { [s.stableId]: s });
|
|
191
|
+
expect(changes[0]).toBeInstanceOf(CreateSequence);
|
|
192
|
+
expect(changes.some((c) => c instanceof GrantSequencePrivileges)).toBe(
|
|
193
|
+
true,
|
|
194
|
+
);
|
|
195
|
+
expect(changes.some((c) => c instanceof RevokeSequencePrivileges)).toBe(
|
|
196
|
+
true,
|
|
197
|
+
);
|
|
198
|
+
expect(
|
|
199
|
+
changes.some((c) => c instanceof RevokeGrantOptionSequencePrivileges),
|
|
200
|
+
).toBe(true);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test("alter comment emits create and drop comment", () => {
|
|
204
|
+
const main = new Sequence(base);
|
|
205
|
+
const withComment = new Sequence({ ...base, comment: "my seq" });
|
|
206
|
+
|
|
207
|
+
const addComment = diffSequences(
|
|
208
|
+
testContext,
|
|
209
|
+
{ [main.stableId]: main },
|
|
210
|
+
{ [withComment.stableId]: withComment },
|
|
211
|
+
);
|
|
212
|
+
expect(addComment[0]).toBeInstanceOf(CreateCommentOnSequence);
|
|
213
|
+
|
|
214
|
+
const dropComment = diffSequences(
|
|
215
|
+
testContext,
|
|
216
|
+
{ [withComment.stableId]: withComment },
|
|
217
|
+
{ [main.stableId]: main },
|
|
218
|
+
);
|
|
219
|
+
expect(dropComment[0]).toBeInstanceOf(DropCommentOnSequence);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test("alter privileges emits grant, revoke, and revoke grant option", () => {
|
|
223
|
+
const main = new Sequence({
|
|
224
|
+
...base,
|
|
225
|
+
privileges: [
|
|
226
|
+
{ grantee: "role_a", privilege: "USAGE", grantable: false },
|
|
227
|
+
{ grantee: "role_b", privilege: "USAGE", grantable: true },
|
|
228
|
+
{ grantee: "role_removed", privilege: "USAGE", grantable: false },
|
|
229
|
+
],
|
|
230
|
+
});
|
|
231
|
+
const branch = new Sequence({
|
|
232
|
+
...base,
|
|
233
|
+
privileges: [
|
|
234
|
+
{ grantee: "role_a", privilege: "USAGE", grantable: true },
|
|
235
|
+
{ grantee: "role_b", privilege: "USAGE", grantable: false },
|
|
236
|
+
{ grantee: "role_new", privilege: "USAGE", grantable: false },
|
|
237
|
+
],
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
const changes = diffSequences(
|
|
241
|
+
testContext,
|
|
242
|
+
{ [main.stableId]: main },
|
|
243
|
+
{ [branch.stableId]: branch },
|
|
244
|
+
);
|
|
245
|
+
expect(changes.some((c) => c instanceof GrantSequencePrivileges)).toBe(
|
|
246
|
+
true,
|
|
247
|
+
);
|
|
248
|
+
expect(changes.some((c) => c instanceof RevokeSequencePrivileges)).toBe(
|
|
249
|
+
true,
|
|
250
|
+
);
|
|
251
|
+
expect(
|
|
252
|
+
changes.some((c) => c instanceof RevokeGrantOptionSequencePrivileges),
|
|
253
|
+
).toBe(true);
|
|
254
|
+
});
|
|
141
255
|
});
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import type { DefaultPrivilegeState } from "../base.default-privileges.ts";
|
|
2
1
|
import { diffObjects } from "../base.diff.ts";
|
|
3
2
|
import {
|
|
4
3
|
diffPrivileges,
|
|
5
|
-
|
|
4
|
+
emitObjectPrivilegeChanges,
|
|
6
5
|
} from "../base.privilege-diff.ts";
|
|
7
|
-
import type {
|
|
6
|
+
import type { ObjectDiffContext } from "../diff-context.ts";
|
|
8
7
|
import type { Table } from "../table/table.model.ts";
|
|
9
8
|
import { hasNonAlterableChanges } from "../utils.ts";
|
|
10
9
|
import {
|
|
@@ -35,12 +34,10 @@ import type { Sequence } from "./sequence.model.ts";
|
|
|
35
34
|
* @returns A list of changes to apply to main to make it match branch.
|
|
36
35
|
*/
|
|
37
36
|
export function diffSequences(
|
|
38
|
-
ctx:
|
|
39
|
-
|
|
40
|
-
currentUser
|
|
41
|
-
|
|
42
|
-
mainRoles: Record<string, Role>;
|
|
43
|
-
},
|
|
37
|
+
ctx: Pick<
|
|
38
|
+
ObjectDiffContext,
|
|
39
|
+
"version" | "currentUser" | "defaultPrivilegeState"
|
|
40
|
+
>,
|
|
44
41
|
main: Record<string, Sequence>,
|
|
45
42
|
branch: Record<string, Sequence>,
|
|
46
43
|
branchTables: Record<string, Table> = {},
|
|
@@ -83,62 +80,33 @@ export function diffSequences(
|
|
|
83
80
|
"sequence",
|
|
84
81
|
createdSeq.schema ?? "",
|
|
85
82
|
);
|
|
83
|
+
const creatorFilteredDefaults =
|
|
84
|
+
createdSeq.owner !== ctx.currentUser
|
|
85
|
+
? effectiveDefaults.filter((p) => p.grantee !== ctx.currentUser)
|
|
86
|
+
: effectiveDefaults;
|
|
86
87
|
const desiredPrivileges = createdSeq.privileges;
|
|
87
88
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
88
89
|
// and shouldn't be compared. Use the sequence owner as the reference.
|
|
89
|
-
// Superuser privileges are filtered inside diffPrivileges.
|
|
90
90
|
const privilegeResults = diffPrivileges(
|
|
91
|
-
|
|
91
|
+
creatorFilteredDefaults,
|
|
92
92
|
desiredPrivileges,
|
|
93
93
|
createdSeq.owner,
|
|
94
|
-
ctx.mainRoles,
|
|
95
94
|
);
|
|
96
95
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Generate revoke changes
|
|
115
|
-
if (result.revokes.length > 0) {
|
|
116
|
-
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
117
|
-
for (const [grantable, list] of revokeGroups) {
|
|
118
|
-
void grantable;
|
|
119
|
-
changes.push(
|
|
120
|
-
new RevokeSequencePrivileges({
|
|
121
|
-
sequence: createdSeq,
|
|
122
|
-
grantee,
|
|
123
|
-
privileges: list,
|
|
124
|
-
version: ctx.version,
|
|
125
|
-
}),
|
|
126
|
-
);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Generate revoke grant option changes
|
|
131
|
-
if (result.revokeGrantOption.length > 0) {
|
|
132
|
-
changes.push(
|
|
133
|
-
new RevokeGrantOptionSequencePrivileges({
|
|
134
|
-
sequence: createdSeq,
|
|
135
|
-
grantee,
|
|
136
|
-
privilegeNames: result.revokeGrantOption,
|
|
137
|
-
version: ctx.version,
|
|
138
|
-
}),
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
96
|
+
changes.push(
|
|
97
|
+
...(emitObjectPrivilegeChanges(
|
|
98
|
+
privilegeResults,
|
|
99
|
+
createdSeq,
|
|
100
|
+
createdSeq,
|
|
101
|
+
"sequence",
|
|
102
|
+
{
|
|
103
|
+
Grant: GrantSequencePrivileges,
|
|
104
|
+
Revoke: RevokeSequencePrivileges,
|
|
105
|
+
RevokeGrantOption: RevokeGrantOptionSequencePrivileges,
|
|
106
|
+
},
|
|
107
|
+
ctx.version,
|
|
108
|
+
) as SequenceChange[]),
|
|
109
|
+
);
|
|
142
110
|
}
|
|
143
111
|
|
|
144
112
|
for (const sequenceId of dropped) {
|
|
@@ -295,59 +263,26 @@ export function diffSequences(
|
|
|
295
263
|
// PRIVILEGES
|
|
296
264
|
// Filter out owner privileges - owner always has ALL privileges implicitly
|
|
297
265
|
// and shouldn't be compared. Use branch owner as the reference.
|
|
298
|
-
// Superuser privileges are filtered inside diffPrivileges.
|
|
299
266
|
const privilegeResults = diffPrivileges(
|
|
300
267
|
mainSequence.privileges,
|
|
301
268
|
branchSequence.privileges,
|
|
302
269
|
branchSequence.owner,
|
|
303
|
-
ctx.mainRoles,
|
|
304
270
|
);
|
|
305
271
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// Generate revoke changes
|
|
324
|
-
if (result.revokes.length > 0) {
|
|
325
|
-
const revokeGroups = groupPrivilegesByGrantable(result.revokes);
|
|
326
|
-
for (const [grantable, list] of revokeGroups) {
|
|
327
|
-
void grantable;
|
|
328
|
-
changes.push(
|
|
329
|
-
new RevokeSequencePrivileges({
|
|
330
|
-
sequence: mainSequence,
|
|
331
|
-
grantee,
|
|
332
|
-
privileges: list,
|
|
333
|
-
version: ctx.version,
|
|
334
|
-
}),
|
|
335
|
-
);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
// Generate revoke grant option changes
|
|
340
|
-
if (result.revokeGrantOption.length > 0) {
|
|
341
|
-
changes.push(
|
|
342
|
-
new RevokeGrantOptionSequencePrivileges({
|
|
343
|
-
sequence: mainSequence,
|
|
344
|
-
grantee,
|
|
345
|
-
privilegeNames: result.revokeGrantOption,
|
|
346
|
-
version: ctx.version,
|
|
347
|
-
}),
|
|
348
|
-
);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
272
|
+
changes.push(
|
|
273
|
+
...(emitObjectPrivilegeChanges(
|
|
274
|
+
privilegeResults,
|
|
275
|
+
branchSequence,
|
|
276
|
+
mainSequence,
|
|
277
|
+
"sequence",
|
|
278
|
+
{
|
|
279
|
+
Grant: GrantSequencePrivileges,
|
|
280
|
+
Revoke: RevokeSequencePrivileges,
|
|
281
|
+
RevokeGrantOption: RevokeGrantOptionSequencePrivileges,
|
|
282
|
+
},
|
|
283
|
+
ctx.version,
|
|
284
|
+
) as SequenceChange[]),
|
|
285
|
+
);
|
|
351
286
|
|
|
352
287
|
// Note: Sequence renaming would also use ALTER SEQUENCE ... RENAME TO ...
|
|
353
288
|
// But since our Sequence model uses 'name' as the identity field,
|