@supabase/pg-delta 1.0.0-alpha.3 → 1.0.0-alpha.4
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 +22 -0
- package/dist/cli/bin/cli.js +0 -0
- package/dist/cli/commands/plan.js +21 -0
- package/dist/cli/utils.d.ts +2 -0
- package/dist/cli/utils.js +1 -1
- package/dist/core/objects/table/table.model.d.ts +4 -2
- package/dist/core/objects/table/table.model.js +3 -0
- package/dist/core/objects/trigger/changes/trigger.alter.js +23 -0
- package/dist/core/objects/trigger/changes/trigger.create.js +2 -1
- package/dist/core/objects/trigger/trigger.model.d.ts +1 -0
- package/dist/core/objects/trigger/trigger.model.js +3 -0
- package/dist/core/plan/apply.js +3 -3
- package/dist/core/plan/create.js +34 -15
- package/dist/core/plan/sql-format/constants.d.ts +2 -0
- package/dist/core/plan/sql-format/constants.js +11 -0
- package/dist/core/plan/sql-format/fixtures.d.ts +2 -0
- package/dist/core/plan/sql-format/fixtures.js +2449 -0
- package/dist/core/plan/sql-format/format-utils.d.ts +37 -0
- package/dist/core/plan/sql-format/format-utils.js +274 -0
- package/dist/core/plan/sql-format/formatters.d.ts +20 -0
- package/dist/core/plan/sql-format/formatters.js +737 -0
- package/dist/core/plan/sql-format/index.d.ts +2 -0
- package/dist/core/plan/sql-format/index.js +98 -0
- package/dist/core/plan/sql-format/keyword-case.d.ts +2 -0
- package/dist/core/plan/sql-format/keyword-case.js +868 -0
- package/dist/core/plan/sql-format/protect.d.ts +3 -0
- package/dist/core/plan/sql-format/protect.js +269 -0
- package/dist/core/plan/sql-format/sql-scanner.d.ts +59 -0
- package/dist/core/plan/sql-format/sql-scanner.js +202 -0
- package/dist/core/plan/sql-format/tokenizer.d.ts +22 -0
- package/dist/core/plan/sql-format/tokenizer.js +118 -0
- package/dist/core/plan/sql-format/types.d.ts +28 -0
- package/dist/core/plan/sql-format/types.js +1 -0
- package/dist/core/plan/sql-format/wrap.d.ts +2 -0
- package/dist/core/plan/sql-format/wrap.js +165 -0
- package/dist/core/plan/sql-format.d.ts +2 -0
- package/dist/core/plan/sql-format.js +1 -0
- package/dist/core/plan/statements.d.ts +2 -1
- package/dist/core/plan/statements.js +6 -2
- package/dist/core/postgres-config.d.ts +15 -0
- package/dist/core/postgres-config.js +30 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/package.json +37 -22
- package/src/cli/app.ts +28 -0
- package/src/cli/bin/cli.ts +9 -0
- package/src/cli/commands/apply.ts +101 -0
- package/src/cli/commands/plan.ts +195 -0
- package/src/cli/commands/sync.ts +185 -0
- package/src/cli/formatters/index.ts +5 -0
- package/src/cli/formatters/tree/tree-builder.ts +380 -0
- package/src/cli/formatters/tree/tree-renderer.ts +372 -0
- package/src/cli/formatters/tree/tree.ts +237 -0
- package/src/cli/utils/integrations.ts +42 -0
- package/src/cli/utils.ts +231 -0
- package/src/core/catalog.diff.ts +246 -0
- package/src/core/catalog.model.ts +384 -0
- package/src/core/change.types.ts +44 -0
- package/src/core/context.ts +26 -0
- package/src/core/depend.ts +1870 -0
- package/src/core/expand-replace-dependencies.ts +380 -0
- package/src/core/fingerprint.ts +204 -0
- package/src/core/integrations/filter/dsl.ts +204 -0
- package/src/core/integrations/filter/extractors.ts +145 -0
- package/src/core/integrations/filter/filter.types.ts +3 -0
- package/src/core/integrations/integration-dsl.ts +24 -0
- package/src/core/integrations/integration.types.ts +7 -0
- package/src/core/integrations/serialize/dsl.ts +77 -0
- package/src/core/integrations/serialize/serialize.types.ts +3 -0
- package/src/core/integrations/supabase.ts +121 -0
- package/src/core/objects/aggregate/aggregate.diff.test.ts +215 -0
- package/src/core/objects/aggregate/aggregate.diff.ts +278 -0
- package/src/core/objects/aggregate/aggregate.model.ts +317 -0
- package/src/core/objects/aggregate/changes/aggregate.alter.test.ts +64 -0
- package/src/core/objects/aggregate/changes/aggregate.alter.ts +32 -0
- package/src/core/objects/aggregate/changes/aggregate.base.ts +20 -0
- package/src/core/objects/aggregate/changes/aggregate.comment.test.ts +86 -0
- package/src/core/objects/aggregate/changes/aggregate.comment.ts +62 -0
- package/src/core/objects/aggregate/changes/aggregate.create.test.ts +101 -0
- package/src/core/objects/aggregate/changes/aggregate.create.ts +329 -0
- package/src/core/objects/aggregate/changes/aggregate.drop.test.ts +78 -0
- package/src/core/objects/aggregate/changes/aggregate.drop.ts +32 -0
- package/src/core/objects/aggregate/changes/aggregate.privilege.test.ts +130 -0
- package/src/core/objects/aggregate/changes/aggregate.privilege.ts +146 -0
- package/src/core/objects/aggregate/changes/aggregate.types.ts +12 -0
- package/src/core/objects/base.change.ts +62 -0
- package/src/core/objects/base.default-privileges.ts +204 -0
- package/src/core/objects/base.diff.ts +20 -0
- package/src/core/objects/base.model.ts +82 -0
- package/src/core/objects/base.privilege-diff.ts +299 -0
- package/src/core/objects/base.privilege.ts +184 -0
- package/src/core/objects/collation/changes/collation.alter.test.ts +63 -0
- package/src/core/objects/collation/changes/collation.alter.ts +79 -0
- package/src/core/objects/collation/changes/collation.base.ts +20 -0
- package/src/core/objects/collation/changes/collation.comment.ts +68 -0
- package/src/core/objects/collation/changes/collation.create.test.ts +51 -0
- package/src/core/objects/collation/changes/collation.create.ts +106 -0
- package/src/core/objects/collation/changes/collation.drop.test.ts +28 -0
- package/src/core/objects/collation/changes/collation.drop.ts +37 -0
- package/src/core/objects/collation/changes/collation.types.ts +10 -0
- package/src/core/objects/collation/collation.diff.test.ts +100 -0
- package/src/core/objects/collation/collation.diff.ts +126 -0
- package/src/core/objects/collation/collation.model.ts +224 -0
- package/src/core/objects/domain/changes/domain.alter.test.ts +316 -0
- package/src/core/objects/domain/changes/domain.alter.ts +286 -0
- package/src/core/objects/domain/changes/domain.base.ts +20 -0
- package/src/core/objects/domain/changes/domain.comment.ts +59 -0
- package/src/core/objects/domain/changes/domain.create.test.ts +65 -0
- package/src/core/objects/domain/changes/domain.create.ts +118 -0
- package/src/core/objects/domain/changes/domain.drop.test.ts +30 -0
- package/src/core/objects/domain/changes/domain.drop.ts +34 -0
- package/src/core/objects/domain/changes/domain.privilege.ts +171 -0
- package/src/core/objects/domain/changes/domain.types.ts +12 -0
- package/src/core/objects/domain/domain.diff.test.ts +284 -0
- package/src/core/objects/domain/domain.diff.ts +358 -0
- package/src/core/objects/domain/domain.model.ts +190 -0
- package/src/core/objects/event-trigger/changes/event-trigger.alter.test.ts +50 -0
- package/src/core/objects/event-trigger/changes/event-trigger.alter.ts +82 -0
- package/src/core/objects/event-trigger/changes/event-trigger.base.ts +20 -0
- package/src/core/objects/event-trigger/changes/event-trigger.comment.ts +66 -0
- package/src/core/objects/event-trigger/changes/event-trigger.create.test.ts +24 -0
- package/src/core/objects/event-trigger/changes/event-trigger.create.ts +72 -0
- package/src/core/objects/event-trigger/changes/event-trigger.drop.test.ts +22 -0
- package/src/core/objects/event-trigger/changes/event-trigger.drop.ts +34 -0
- package/src/core/objects/event-trigger/changes/event-trigger.types.ts +10 -0
- package/src/core/objects/event-trigger/event-trigger.diff.test.ts +126 -0
- package/src/core/objects/event-trigger/event-trigger.diff.ts +126 -0
- package/src/core/objects/event-trigger/event-trigger.model.ts +106 -0
- package/src/core/objects/extension/changes/extension.alter.test.ts +58 -0
- package/src/core/objects/extension/changes/extension.alter.ts +78 -0
- package/src/core/objects/extension/changes/extension.base.ts +20 -0
- package/src/core/objects/extension/changes/extension.comment.ts +64 -0
- package/src/core/objects/extension/changes/extension.create.test.ts +25 -0
- package/src/core/objects/extension/changes/extension.create.ts +63 -0
- package/src/core/objects/extension/changes/extension.drop.test.ts +23 -0
- package/src/core/objects/extension/changes/extension.drop.ts +34 -0
- package/src/core/objects/extension/changes/extension.types.ts +10 -0
- package/src/core/objects/extension/extension.diff.test.ts +42 -0
- package/src/core/objects/extension/extension.diff.ts +90 -0
- package/src/core/objects/extension/extension.model.ts +280 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.test.ts +125 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.alter.ts +101 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.base.ts +20 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.comment.ts +72 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.test.ts +125 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.create.ts +95 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.test.ts +23 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.drop.ts +36 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.privilege.ts +172 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/changes/foreign-data-wrapper.types.ts +12 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.test.ts +179 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.ts +341 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.model.ts +149 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper.types.ts +10 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.test.ts +309 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.alter.ts +341 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.base.ts +20 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.comment.ts +72 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.test.ts +201 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.create.ts +81 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.test.ts +43 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.drop.ts +37 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.privilege.ts +181 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/changes/foreign-table.types.ts +12 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.test.ts +813 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.diff.ts +406 -0
- package/src/core/objects/foreign-data-wrapper/foreign-table/foreign-table.model.ts +242 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.test.ts +168 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.alter.ts +126 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.base.ts +20 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.comment.ts +60 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.create.test.ts +131 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.create.ts +81 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.test.ts +24 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.drop.ts +34 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.privilege.ts +164 -0
- package/src/core/objects/foreign-data-wrapper/server/changes/server.types.ts +12 -0
- package/src/core/objects/foreign-data-wrapper/server/server.diff.test.ts +167 -0
- package/src/core/objects/foreign-data-wrapper/server/server.diff.ts +317 -0
- package/src/core/objects/foreign-data-wrapper/server/server.model.ts +133 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.test.ts +82 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.alter.ts +69 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.base.ts +20 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.test.ts +85 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.create.ts +66 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.test.ts +53 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.drop.ts +40 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/changes/user-mapping.types.ts +8 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.diff.test.ts +77 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.diff.ts +107 -0
- package/src/core/objects/foreign-data-wrapper/user-mapping/user-mapping.model.ts +96 -0
- package/src/core/objects/index/changes/index.alter.test.ts +200 -0
- package/src/core/objects/index/changes/index.alter.ts +144 -0
- package/src/core/objects/index/changes/index.base.ts +20 -0
- package/src/core/objects/index/changes/index.comment.ts +63 -0
- package/src/core/objects/index/changes/index.create.test.ts +66 -0
- package/src/core/objects/index/changes/index.create.ts +68 -0
- package/src/core/objects/index/changes/index.drop.test.ts +44 -0
- package/src/core/objects/index/changes/index.drop.ts +34 -0
- package/src/core/objects/index/changes/index.types.ts +6 -0
- package/src/core/objects/index/changes/utils.ts +16 -0
- package/src/core/objects/index/index.diff.test.ts +153 -0
- package/src/core/objects/index/index.diff.ts +243 -0
- package/src/core/objects/index/index.model.ts +370 -0
- package/src/core/objects/language/changes/language.alter.test.ts +33 -0
- package/src/core/objects/language/changes/language.alter.ts +53 -0
- package/src/core/objects/language/changes/language.base.ts +20 -0
- package/src/core/objects/language/changes/language.comment.ts +58 -0
- package/src/core/objects/language/changes/language.create.test.ts +27 -0
- package/src/core/objects/language/changes/language.create.ts +104 -0
- package/src/core/objects/language/changes/language.drop.test.ts +25 -0
- package/src/core/objects/language/changes/language.drop.ts +39 -0
- package/src/core/objects/language/changes/language.privilege.ts +172 -0
- package/src/core/objects/language/changes/language.types.ts +12 -0
- package/src/core/objects/language/language.diff.test.ts +53 -0
- package/src/core/objects/language/language.diff.ts +176 -0
- package/src/core/objects/language/language.model.ts +150 -0
- package/src/core/objects/materialized-view/changes/materialized-view.alter.test.ts +123 -0
- package/src/core/objects/materialized-view/changes/materialized-view.alter.ts +113 -0
- package/src/core/objects/materialized-view/changes/materialized-view.base.ts +20 -0
- package/src/core/objects/materialized-view/changes/materialized-view.comment.ts +176 -0
- package/src/core/objects/materialized-view/changes/materialized-view.create.test.ts +64 -0
- package/src/core/objects/materialized-view/changes/materialized-view.create.ts +93 -0
- package/src/core/objects/materialized-view/changes/materialized-view.drop.test.ts +34 -0
- package/src/core/objects/materialized-view/changes/materialized-view.drop.ts +60 -0
- package/src/core/objects/materialized-view/changes/materialized-view.privilege.ts +212 -0
- package/src/core/objects/materialized-view/changes/materialized-view.types.ts +12 -0
- package/src/core/objects/materialized-view/materialized-view.diff.test.ts +102 -0
- package/src/core/objects/materialized-view/materialized-view.diff.ts +451 -0
- package/src/core/objects/materialized-view/materialized-view.model.ts +258 -0
- package/src/core/objects/procedure/changes/procedure.alter.test.ts +1005 -0
- package/src/core/objects/procedure/changes/procedure.alter.ts +287 -0
- package/src/core/objects/procedure/changes/procedure.base.ts +20 -0
- package/src/core/objects/procedure/changes/procedure.comment.ts +70 -0
- package/src/core/objects/procedure/changes/procedure.create.test.ts +48 -0
- package/src/core/objects/procedure/changes/procedure.create.ts +92 -0
- package/src/core/objects/procedure/changes/procedure.drop.test.ts +85 -0
- package/src/core/objects/procedure/changes/procedure.drop.ts +49 -0
- package/src/core/objects/procedure/changes/procedure.privilege.ts +188 -0
- package/src/core/objects/procedure/changes/procedure.types.ts +12 -0
- package/src/core/objects/procedure/procedure.diff.test.ts +161 -0
- package/src/core/objects/procedure/procedure.diff.ts +404 -0
- package/src/core/objects/procedure/procedure.model.ts +264 -0
- package/src/core/objects/procedure/utils.ts +58 -0
- package/src/core/objects/publication/changes/publication.alter.test.ts +223 -0
- package/src/core/objects/publication/changes/publication.alter.ts +243 -0
- package/src/core/objects/publication/changes/publication.base.ts +20 -0
- package/src/core/objects/publication/changes/publication.comment.test.ts +70 -0
- package/src/core/objects/publication/changes/publication.comment.ts +64 -0
- package/src/core/objects/publication/changes/publication.create.test.ts +87 -0
- package/src/core/objects/publication/changes/publication.create.ts +82 -0
- package/src/core/objects/publication/changes/publication.drop.test.ts +46 -0
- package/src/core/objects/publication/changes/publication.drop.ts +29 -0
- package/src/core/objects/publication/changes/publication.types.ts +26 -0
- package/src/core/objects/publication/publication.diff.test.ts +292 -0
- package/src/core/objects/publication/publication.diff.ts +253 -0
- package/src/core/objects/publication/publication.model.ts +206 -0
- package/src/core/objects/publication/utils.ts +55 -0
- package/src/core/objects/rls-policy/changes/rls-policy.alter.test.ts +250 -0
- package/src/core/objects/rls-policy/changes/rls-policy.alter.ts +128 -0
- package/src/core/objects/rls-policy/changes/rls-policy.base.ts +20 -0
- package/src/core/objects/rls-policy/changes/rls-policy.comment.ts +69 -0
- package/src/core/objects/rls-policy/changes/rls-policy.create.test.ts +74 -0
- package/src/core/objects/rls-policy/changes/rls-policy.create.ts +100 -0
- package/src/core/objects/rls-policy/changes/rls-policy.drop.test.ts +28 -0
- package/src/core/objects/rls-policy/changes/rls-policy.drop.ts +39 -0
- package/src/core/objects/rls-policy/changes/rls-policy.types.ts +10 -0
- package/src/core/objects/rls-policy/rls-policy.diff.test.ts +79 -0
- package/src/core/objects/rls-policy/rls-policy.diff.ts +121 -0
- package/src/core/objects/rls-policy/rls-policy.model.ts +140 -0
- package/src/core/objects/role/changes/role.alter.test.ts +346 -0
- package/src/core/objects/role/changes/role.alter.ts +110 -0
- package/src/core/objects/role/changes/role.base.ts +24 -0
- package/src/core/objects/role/changes/role.comment.ts +55 -0
- package/src/core/objects/role/changes/role.create.test.ts +52 -0
- package/src/core/objects/role/changes/role.create.ts +102 -0
- package/src/core/objects/role/changes/role.drop.test.ts +29 -0
- package/src/core/objects/role/changes/role.drop.ts +34 -0
- package/src/core/objects/role/changes/role.privilege.ts +376 -0
- package/src/core/objects/role/changes/role.types.ts +12 -0
- package/src/core/objects/role/role.diff.test.ts +44 -0
- package/src/core/objects/role/role.diff.ts +479 -0
- package/src/core/objects/role/role.model.ts +344 -0
- package/src/core/objects/rule/changes/rule.alter.test.ts +78 -0
- package/src/core/objects/rule/changes/rule.alter.ts +72 -0
- package/src/core/objects/rule/changes/rule.base.ts +20 -0
- package/src/core/objects/rule/changes/rule.comment.test.ts +55 -0
- package/src/core/objects/rule/changes/rule.comment.ts +62 -0
- package/src/core/objects/rule/changes/rule.create.test.ts +59 -0
- package/src/core/objects/rule/changes/rule.create.ts +42 -0
- package/src/core/objects/rule/changes/rule.drop.test.ts +38 -0
- package/src/core/objects/rule/changes/rule.drop.ts +29 -0
- package/src/core/objects/rule/changes/rule.types.ts +12 -0
- package/src/core/objects/rule/rule.diff.test.ts +132 -0
- package/src/core/objects/rule/rule.diff.ts +79 -0
- package/src/core/objects/rule/rule.model.ts +173 -0
- package/src/core/objects/schema/changes/schema.alter.test.ts +28 -0
- package/src/core/objects/schema/changes/schema.alter.ts +45 -0
- package/src/core/objects/schema/changes/schema.base.ts +20 -0
- package/src/core/objects/schema/changes/schema.comment.ts +56 -0
- package/src/core/objects/schema/changes/schema.create.test.ts +22 -0
- package/src/core/objects/schema/changes/schema.create.ts +47 -0
- package/src/core/objects/schema/changes/schema.drop.test.ts +20 -0
- package/src/core/objects/schema/changes/schema.drop.ts +34 -0
- package/src/core/objects/schema/changes/schema.privilege.ts +175 -0
- package/src/core/objects/schema/changes/schema.types.ts +12 -0
- package/src/core/objects/schema/schema.diff.test.ts +42 -0
- package/src/core/objects/schema/schema.diff.ts +209 -0
- package/src/core/objects/schema/schema.model.ts +107 -0
- package/src/core/objects/sequence/changes/sequence.alter.test.ts +151 -0
- package/src/core/objects/sequence/changes/sequence.alter.ts +115 -0
- package/src/core/objects/sequence/changes/sequence.base.ts +20 -0
- package/src/core/objects/sequence/changes/sequence.comment.ts +60 -0
- package/src/core/objects/sequence/changes/sequence.create.test.ts +84 -0
- package/src/core/objects/sequence/changes/sequence.create.ts +111 -0
- package/src/core/objects/sequence/changes/sequence.drop.test.ts +32 -0
- package/src/core/objects/sequence/changes/sequence.drop.ts +37 -0
- package/src/core/objects/sequence/changes/sequence.privilege.ts +179 -0
- package/src/core/objects/sequence/changes/sequence.types.ts +12 -0
- package/src/core/objects/sequence/sequence.diff.test.ts +141 -0
- package/src/core/objects/sequence/sequence.diff.ts +359 -0
- package/src/core/objects/sequence/sequence.model.ts +185 -0
- package/src/core/objects/subscription/changes/subscription.alter.test.ts +124 -0
- package/src/core/objects/subscription/changes/subscription.alter.ts +110 -0
- package/src/core/objects/subscription/changes/subscription.base.ts +20 -0
- package/src/core/objects/subscription/changes/subscription.comment.test.ts +67 -0
- package/src/core/objects/subscription/changes/subscription.comment.ts +64 -0
- package/src/core/objects/subscription/changes/subscription.create.test.ts +77 -0
- package/src/core/objects/subscription/changes/subscription.create.ts +69 -0
- package/src/core/objects/subscription/changes/subscription.drop.test.ts +46 -0
- package/src/core/objects/subscription/changes/subscription.drop.ts +20 -0
- package/src/core/objects/subscription/changes/subscription.types.ts +22 -0
- package/src/core/objects/subscription/subscription.diff.test.ts +232 -0
- package/src/core/objects/subscription/subscription.diff.ts +241 -0
- package/src/core/objects/subscription/subscription.model.ts +190 -0
- package/src/core/objects/subscription/utils.ts +156 -0
- package/src/core/objects/table/changes/table.alter.test.ts +823 -0
- package/src/core/objects/table/changes/table.alter.ts +806 -0
- package/src/core/objects/table/changes/table.base.ts +20 -0
- package/src/core/objects/table/changes/table.comment.ts +266 -0
- package/src/core/objects/table/changes/table.create.test.ts +150 -0
- package/src/core/objects/table/changes/table.create.ts +188 -0
- package/src/core/objects/table/changes/table.drop.test.ts +34 -0
- package/src/core/objects/table/changes/table.drop.ts +45 -0
- package/src/core/objects/table/changes/table.privilege.ts +200 -0
- package/src/core/objects/table/changes/table.types.ts +12 -0
- package/src/core/objects/table/table.diff.test.ts +711 -0
- package/src/core/objects/table/table.diff.ts +953 -0
- package/src/core/objects/table/table.model.ts +460 -0
- package/src/core/objects/trigger/changes/trigger.alter.test.ts +46 -0
- package/src/core/objects/trigger/changes/trigger.alter.ts +76 -0
- package/src/core/objects/trigger/changes/trigger.base.ts +20 -0
- package/src/core/objects/trigger/changes/trigger.comment.ts +64 -0
- package/src/core/objects/trigger/changes/trigger.create.test.ts +43 -0
- package/src/core/objects/trigger/changes/trigger.create.ts +85 -0
- package/src/core/objects/trigger/changes/trigger.drop.test.ts +43 -0
- package/src/core/objects/trigger/changes/trigger.drop.ts +39 -0
- package/src/core/objects/trigger/changes/trigger.types.ts +10 -0
- package/src/core/objects/trigger/trigger.diff.test.ts +83 -0
- package/src/core/objects/trigger/trigger.diff.ts +116 -0
- package/src/core/objects/trigger/trigger.model.ts +252 -0
- package/src/core/objects/type/composite-type/changes/composite-type.alter.test.ts +202 -0
- package/src/core/objects/type/composite-type/changes/composite-type.alter.ts +174 -0
- package/src/core/objects/type/composite-type/changes/composite-type.base.ts +20 -0
- package/src/core/objects/type/composite-type/changes/composite-type.comment.ts +145 -0
- package/src/core/objects/type/composite-type/changes/composite-type.create.test.ts +101 -0
- package/src/core/objects/type/composite-type/changes/composite-type.create.ts +95 -0
- package/src/core/objects/type/composite-type/changes/composite-type.drop.test.ts +33 -0
- package/src/core/objects/type/composite-type/changes/composite-type.drop.ts +37 -0
- package/src/core/objects/type/composite-type/changes/composite-type.privilege.ts +175 -0
- package/src/core/objects/type/composite-type/changes/composite-type.types.ts +12 -0
- package/src/core/objects/type/composite-type/composite-type.diff.test.ts +191 -0
- package/src/core/objects/type/composite-type/composite-type.diff.ts +372 -0
- package/src/core/objects/type/composite-type/composite-type.model.ts +252 -0
- package/src/core/objects/type/enum/changes/enum.alter.test.ts +104 -0
- package/src/core/objects/type/enum/changes/enum.alter.ts +91 -0
- package/src/core/objects/type/enum/changes/enum.base.ts +20 -0
- package/src/core/objects/type/enum/changes/enum.comment.ts +64 -0
- package/src/core/objects/type/enum/changes/enum.create.test.ts +28 -0
- package/src/core/objects/type/enum/changes/enum.create.ts +56 -0
- package/src/core/objects/type/enum/changes/enum.drop.test.ts +25 -0
- package/src/core/objects/type/enum/changes/enum.drop.ts +34 -0
- package/src/core/objects/type/enum/changes/enum.privilege.ts +175 -0
- package/src/core/objects/type/enum/changes/enum.types.ts +12 -0
- package/src/core/objects/type/enum/enum.diff.test.ts +191 -0
- package/src/core/objects/type/enum/enum.diff.ts +396 -0
- package/src/core/objects/type/enum/enum.model.ts +194 -0
- package/src/core/objects/type/range/changes/range.alter.test.ts +27 -0
- package/src/core/objects/type/range/changes/range.alter.ts +51 -0
- package/src/core/objects/type/range/changes/range.base.ts +20 -0
- package/src/core/objects/type/range/changes/range.comment.ts +64 -0
- package/src/core/objects/type/range/changes/range.create.test.ts +51 -0
- package/src/core/objects/type/range/changes/range.create.ts +151 -0
- package/src/core/objects/type/range/changes/range.drop.test.ts +26 -0
- package/src/core/objects/type/range/changes/range.drop.ts +34 -0
- package/src/core/objects/type/range/changes/range.privilege.ts +175 -0
- package/src/core/objects/type/range/changes/range.types.ts +12 -0
- package/src/core/objects/type/range/range.diff.test.ts +70 -0
- package/src/core/objects/type/range/range.diff.ts +259 -0
- package/src/core/objects/type/range/range.model.ts +187 -0
- package/src/core/objects/type/type.types.ts +5 -0
- package/src/core/objects/utils.ts +171 -0
- package/src/core/objects/view/changes/view.alter.test.ts +110 -0
- package/src/core/objects/view/changes/view.alter.ts +112 -0
- package/src/core/objects/view/changes/view.base.ts +20 -0
- package/src/core/objects/view/changes/view.comment.ts +59 -0
- package/src/core/objects/view/changes/view.create.test.ts +65 -0
- package/src/core/objects/view/changes/view.create.ts +73 -0
- package/src/core/objects/view/changes/view.drop.test.ts +34 -0
- package/src/core/objects/view/changes/view.drop.ts +40 -0
- package/src/core/objects/view/changes/view.privilege.ts +200 -0
- package/src/core/objects/view/changes/view.types.ts +12 -0
- package/src/core/objects/view/view.diff.test.ts +91 -0
- package/src/core/objects/view/view.diff.ts +365 -0
- package/src/core/objects/view/view.model.ts +276 -0
- package/src/core/plan/apply.ts +190 -0
- package/src/core/plan/create.ts +432 -0
- package/src/core/plan/hierarchy.ts +574 -0
- package/src/core/plan/index.ts +29 -0
- package/src/core/plan/io.ts +20 -0
- package/src/core/plan/risk.ts +48 -0
- package/src/core/plan/serialize.ts +195 -0
- package/src/core/plan/sql-format/constants.ts +13 -0
- package/src/core/plan/sql-format/fixtures.ts +2806 -0
- package/src/core/plan/sql-format/format-comment-literals.test.ts +96 -0
- package/src/core/plan/sql-format/format-functions.test.ts +127 -0
- package/src/core/plan/sql-format/format-lowercase-coverage.test.ts +67 -0
- package/src/core/plan/sql-format/format-off.test.ts +809 -0
- package/src/core/plan/sql-format/format-pretty-lower-leading.test.ts +1056 -0
- package/src/core/plan/sql-format/format-pretty-narrow.test.ts +1283 -0
- package/src/core/plan/sql-format/format-pretty-preserve.test.ts +1052 -0
- package/src/core/plan/sql-format/format-pretty-upper.test.ts +1045 -0
- package/src/core/plan/sql-format/format-stress.test.ts +616 -0
- package/src/core/plan/sql-format/format-utils.test.ts +91 -0
- package/src/core/plan/sql-format/format-utils.ts +391 -0
- package/src/core/plan/sql-format/formatters.ts +921 -0
- package/src/core/plan/sql-format/index.ts +149 -0
- package/src/core/plan/sql-format/keyword-case.test.ts +118 -0
- package/src/core/plan/sql-format/keyword-case.ts +1085 -0
- package/src/core/plan/sql-format/protect.test.ts +127 -0
- package/src/core/plan/sql-format/protect.ts +337 -0
- package/src/core/plan/sql-format/sql-scanner.test.ts +240 -0
- package/src/core/plan/sql-format/sql-scanner.ts +252 -0
- package/src/core/plan/sql-format/tokenizer.test.ts +68 -0
- package/src/core/plan/sql-format/tokenizer.ts +152 -0
- package/src/core/plan/sql-format/types.ts +31 -0
- package/src/core/plan/sql-format/wrap.test.ts +119 -0
- package/src/core/plan/sql-format/wrap.ts +196 -0
- package/src/core/plan/sql-format.ts +2 -0
- package/src/core/plan/statements.ts +22 -0
- package/src/core/plan/types.ts +165 -0
- package/src/core/postgres-config.ts +169 -0
- package/src/core/sort/custom-constraints.ts +161 -0
- package/src/core/sort/debug-visualization.ts +239 -0
- package/src/core/sort/dependency-filter.ts +224 -0
- package/src/core/sort/graph-builder.ts +223 -0
- package/src/core/sort/graph-utils.ts +51 -0
- package/src/core/sort/logical-sort.ts +590 -0
- package/src/core/sort/sort-changes.ts +234 -0
- package/src/core/sort/topological-sort.ts +184 -0
- package/src/core/sort/types.ts +112 -0
- package/src/core/sort/utils.ts +69 -0
- package/src/index.ts +14 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatObjectPrivilegeList,
|
|
3
|
+
getObjectKindPrefix,
|
|
4
|
+
} from "../../base.privilege.ts";
|
|
5
|
+
import { stableId } from "../../utils.ts";
|
|
6
|
+
import type { Aggregate } from "../aggregate.model.ts";
|
|
7
|
+
import { AlterAggregateChange } from "./aggregate.base.ts";
|
|
8
|
+
|
|
9
|
+
export type AggregatePrivilege =
|
|
10
|
+
| GrantAggregatePrivileges
|
|
11
|
+
| RevokeAggregatePrivileges
|
|
12
|
+
| RevokeGrantOptionAggregatePrivileges;
|
|
13
|
+
|
|
14
|
+
export class GrantAggregatePrivileges extends AlterAggregateChange {
|
|
15
|
+
public readonly aggregate: Aggregate;
|
|
16
|
+
public readonly grantee: string;
|
|
17
|
+
public readonly privileges: { privilege: string; grantable: boolean }[];
|
|
18
|
+
public readonly version: number | undefined;
|
|
19
|
+
public readonly scope = "privilege" as const;
|
|
20
|
+
|
|
21
|
+
constructor(props: {
|
|
22
|
+
aggregate: Aggregate;
|
|
23
|
+
grantee: string;
|
|
24
|
+
privileges: { privilege: string; grantable: boolean }[];
|
|
25
|
+
version?: number;
|
|
26
|
+
}) {
|
|
27
|
+
super();
|
|
28
|
+
this.aggregate = props.aggregate;
|
|
29
|
+
this.grantee = props.grantee;
|
|
30
|
+
this.privileges = props.privileges;
|
|
31
|
+
this.version = props.version;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
get creates() {
|
|
35
|
+
return [stableId.acl(this.aggregate.stableId, this.grantee)];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
get requires() {
|
|
39
|
+
return [this.aggregate.stableId, stableId.role(this.grantee)];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
serialize(): string {
|
|
43
|
+
const hasGrantable = this.privileges.some((p) => p.grantable);
|
|
44
|
+
const hasBase = this.privileges.some((p) => !p.grantable);
|
|
45
|
+
if (hasGrantable && hasBase) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
"GrantAggregatePrivileges expects privileges with uniform grantable flag",
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
const withGrant = hasGrantable ? " WITH GRANT OPTION" : "";
|
|
51
|
+
const kindPrefix = getObjectKindPrefix("FUNCTION");
|
|
52
|
+
const list = this.privileges.map((p) => p.privilege);
|
|
53
|
+
const privSql = formatObjectPrivilegeList("FUNCTION", list, this.version);
|
|
54
|
+
const aggregateName = `${this.aggregate.schema}.${this.aggregate.name}`;
|
|
55
|
+
const signature = this.aggregate.identityArguments;
|
|
56
|
+
const qualified = `${aggregateName}(${signature})`;
|
|
57
|
+
return `GRANT ${privSql} ${kindPrefix} ${qualified} TO ${this.grantee}${withGrant}`;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export class RevokeAggregatePrivileges extends AlterAggregateChange {
|
|
62
|
+
public readonly aggregate: Aggregate;
|
|
63
|
+
public readonly grantee: string;
|
|
64
|
+
public readonly privileges: { privilege: string; grantable: boolean }[];
|
|
65
|
+
public readonly version: number | undefined;
|
|
66
|
+
public readonly scope = "privilege" as const;
|
|
67
|
+
|
|
68
|
+
constructor(props: {
|
|
69
|
+
aggregate: Aggregate;
|
|
70
|
+
grantee: string;
|
|
71
|
+
privileges: { privilege: string; grantable: boolean }[];
|
|
72
|
+
version?: number;
|
|
73
|
+
}) {
|
|
74
|
+
super();
|
|
75
|
+
this.aggregate = props.aggregate;
|
|
76
|
+
this.grantee = props.grantee;
|
|
77
|
+
this.privileges = props.privileges;
|
|
78
|
+
this.version = props.version;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
get drops() {
|
|
82
|
+
// Return ACL ID for dependency tracking, even though this is an ALTER operation
|
|
83
|
+
// Phase assignment now uses operation type, so this won't affect phase placement
|
|
84
|
+
return [stableId.acl(this.aggregate.stableId, this.grantee)];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
get requires() {
|
|
88
|
+
return [
|
|
89
|
+
stableId.acl(this.aggregate.stableId, this.grantee),
|
|
90
|
+
this.aggregate.stableId,
|
|
91
|
+
stableId.role(this.grantee),
|
|
92
|
+
];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
serialize(): string {
|
|
96
|
+
const kindPrefix = getObjectKindPrefix("FUNCTION");
|
|
97
|
+
const list = this.privileges.map((p) => p.privilege);
|
|
98
|
+
const privSql = formatObjectPrivilegeList("FUNCTION", list, this.version);
|
|
99
|
+
const aggregateName = `${this.aggregate.schema}.${this.aggregate.name}`;
|
|
100
|
+
const signature = this.aggregate.identityArguments;
|
|
101
|
+
const qualified = `${aggregateName}(${signature})`;
|
|
102
|
+
return `REVOKE ${privSql} ${kindPrefix} ${qualified} FROM ${this.grantee}`;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export class RevokeGrantOptionAggregatePrivileges extends AlterAggregateChange {
|
|
107
|
+
public readonly aggregate: Aggregate;
|
|
108
|
+
public readonly grantee: string;
|
|
109
|
+
public readonly privilegeNames: string[];
|
|
110
|
+
public readonly version: number | undefined;
|
|
111
|
+
public readonly scope = "privilege" as const;
|
|
112
|
+
|
|
113
|
+
constructor(props: {
|
|
114
|
+
aggregate: Aggregate;
|
|
115
|
+
grantee: string;
|
|
116
|
+
privilegeNames: string[];
|
|
117
|
+
version?: number;
|
|
118
|
+
}) {
|
|
119
|
+
super();
|
|
120
|
+
this.aggregate = props.aggregate;
|
|
121
|
+
this.grantee = props.grantee;
|
|
122
|
+
this.privilegeNames = [...new Set(props.privilegeNames)].sort();
|
|
123
|
+
this.version = props.version;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
get requires() {
|
|
127
|
+
return [
|
|
128
|
+
stableId.acl(this.aggregate.stableId, this.grantee),
|
|
129
|
+
this.aggregate.stableId,
|
|
130
|
+
stableId.role(this.grantee),
|
|
131
|
+
];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
serialize(): string {
|
|
135
|
+
const kindPrefix = getObjectKindPrefix("FUNCTION");
|
|
136
|
+
const privSql = formatObjectPrivilegeList(
|
|
137
|
+
"FUNCTION",
|
|
138
|
+
this.privilegeNames,
|
|
139
|
+
this.version,
|
|
140
|
+
);
|
|
141
|
+
const aggregateName = `${this.aggregate.schema}.${this.aggregate.name}`;
|
|
142
|
+
const signature = this.aggregate.identityArguments;
|
|
143
|
+
const qualified = `${aggregateName}(${signature})`;
|
|
144
|
+
return `REVOKE GRANT OPTION FOR ${privSql} ${kindPrefix} ${qualified} FROM ${this.grantee}`;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AlterAggregate } from "./aggregate.alter.ts";
|
|
2
|
+
import type { CommentAggregate } from "./aggregate.comment.ts";
|
|
3
|
+
import type { CreateAggregate } from "./aggregate.create.ts";
|
|
4
|
+
import type { DropAggregate } from "./aggregate.drop.ts";
|
|
5
|
+
import type { AggregatePrivilege } from "./aggregate.privilege.ts";
|
|
6
|
+
|
|
7
|
+
export type AggregateChange =
|
|
8
|
+
| AlterAggregate
|
|
9
|
+
| CommentAggregate
|
|
10
|
+
| CreateAggregate
|
|
11
|
+
| DropAggregate
|
|
12
|
+
| AggregatePrivilege;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
type ChangeOperation = "create" | "alter" | "drop";
|
|
2
|
+
|
|
3
|
+
export abstract class BaseChange {
|
|
4
|
+
/**
|
|
5
|
+
* The operation of the change.
|
|
6
|
+
*/
|
|
7
|
+
abstract readonly operation: ChangeOperation;
|
|
8
|
+
/**
|
|
9
|
+
* The type of the object targeted by the change.
|
|
10
|
+
*/
|
|
11
|
+
abstract readonly objectType: string;
|
|
12
|
+
/**
|
|
13
|
+
* The scope of the change.
|
|
14
|
+
*/
|
|
15
|
+
abstract readonly scope: string;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A unique identifier for the change.
|
|
19
|
+
*/
|
|
20
|
+
get changeId(): string {
|
|
21
|
+
return `${this.operation}:${this.scope}:${this.objectType}:${this.serialize()}`;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Stable identifiers this change creates.
|
|
26
|
+
*
|
|
27
|
+
* Defaults to an empty array. Override in subclasses that create objects.
|
|
28
|
+
*/
|
|
29
|
+
get creates(): string[] {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Stable identifiers this change drops.
|
|
35
|
+
*
|
|
36
|
+
* Defaults to an empty array. Override in subclasses that remove objects.
|
|
37
|
+
*/
|
|
38
|
+
get drops(): string[] {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Stable identifiers this change requires to exist beforehand.
|
|
44
|
+
*
|
|
45
|
+
* Defaults to an empty array. Override in subclasses that have prerequisites.
|
|
46
|
+
*/
|
|
47
|
+
get requires(): string[] {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Serialize the change into a single SQL statement.
|
|
53
|
+
*/
|
|
54
|
+
abstract serialize(options?: Record<string, unknown>): string;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Port of string literal quoting: doubles single quotes inside and wraps with single quotes
|
|
59
|
+
*/
|
|
60
|
+
export function quoteLiteral(value: string): string {
|
|
61
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
62
|
+
}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import type { PrivilegeProps } from "./base.privilege-diff.ts";
|
|
2
|
+
import type { Role } from "./role/role.model.ts";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Maps object type names to PostgreSQL default privilege objtype codes.
|
|
6
|
+
* Used to look up default privileges for different object types.
|
|
7
|
+
*/
|
|
8
|
+
function objectTypeToObjtype(objectType: string): string | null {
|
|
9
|
+
switch (objectType) {
|
|
10
|
+
case "table":
|
|
11
|
+
return "r"; // Relations (tables)
|
|
12
|
+
case "view":
|
|
13
|
+
return "r"; // Views are also relations
|
|
14
|
+
case "materialized_view":
|
|
15
|
+
return "r"; // Materialized views are also relations
|
|
16
|
+
case "sequence":
|
|
17
|
+
return "S"; // Sequences
|
|
18
|
+
case "procedure":
|
|
19
|
+
case "function":
|
|
20
|
+
case "aggregate":
|
|
21
|
+
return "f"; // Functions/routines
|
|
22
|
+
case "type":
|
|
23
|
+
case "domain":
|
|
24
|
+
case "enum":
|
|
25
|
+
case "range":
|
|
26
|
+
case "composite_type":
|
|
27
|
+
return "T"; // Types
|
|
28
|
+
case "schema":
|
|
29
|
+
return "n"; // Schemas
|
|
30
|
+
default:
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Tracks the effective state of default privileges as changes are processed.
|
|
37
|
+
* This allows us to compute what default privileges would be in effect at any point
|
|
38
|
+
* in the migration script, accounting for ALTER DEFAULT PRIVILEGES statements.
|
|
39
|
+
*/
|
|
40
|
+
export class DefaultPrivilegeState {
|
|
41
|
+
private state: Map<
|
|
42
|
+
string,
|
|
43
|
+
Map<string, Map<string | null, Map<string, Set<string>>>>
|
|
44
|
+
> = new Map(); // role -> objtype -> schema -> grantee -> privileges
|
|
45
|
+
|
|
46
|
+
constructor(initialRoles: Record<string, Role>) {
|
|
47
|
+
// Initialize state from roles' default_privileges
|
|
48
|
+
for (const [_roleId, role] of Object.entries(initialRoles)) {
|
|
49
|
+
const roleName = role.name;
|
|
50
|
+
if (!this.state.has(roleName)) {
|
|
51
|
+
this.state.set(roleName, new Map());
|
|
52
|
+
}
|
|
53
|
+
// biome-ignore lint/style/noNonNullAssertion: roleName is guaranteed to be in the state
|
|
54
|
+
const roleState = this.state.get(roleName)!;
|
|
55
|
+
|
|
56
|
+
for (const defPriv of role.default_privileges) {
|
|
57
|
+
if (!roleState.has(defPriv.objtype)) {
|
|
58
|
+
roleState.set(defPriv.objtype, new Map());
|
|
59
|
+
}
|
|
60
|
+
// biome-ignore lint/style/noNonNullAssertion: objtype is guaranteed to be in the state
|
|
61
|
+
const objtypeState = roleState.get(defPriv.objtype)!;
|
|
62
|
+
|
|
63
|
+
const schemaKey = defPriv.in_schema ?? null;
|
|
64
|
+
if (!objtypeState.has(schemaKey)) {
|
|
65
|
+
objtypeState.set(schemaKey, new Map());
|
|
66
|
+
}
|
|
67
|
+
// biome-ignore lint/style/noNonNullAssertion: schemaKey is guaranteed to be in the state
|
|
68
|
+
const schemaState = objtypeState.get(schemaKey)!;
|
|
69
|
+
|
|
70
|
+
if (!schemaState.has(defPriv.grantee)) {
|
|
71
|
+
schemaState.set(defPriv.grantee, new Set());
|
|
72
|
+
}
|
|
73
|
+
// biome-ignore lint/style/noNonNullAssertion: grantee is guaranteed to be in the state
|
|
74
|
+
const privileges = schemaState.get(defPriv.grantee)!;
|
|
75
|
+
|
|
76
|
+
for (const priv of defPriv.privileges) {
|
|
77
|
+
const key = `${priv.privilege}:${priv.grantable}`;
|
|
78
|
+
privileges.add(key);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Apply a GrantRoleDefaultPrivileges change to the state.
|
|
86
|
+
*/
|
|
87
|
+
applyGrant(
|
|
88
|
+
roleName: string,
|
|
89
|
+
objtype: string,
|
|
90
|
+
inSchema: string | null,
|
|
91
|
+
grantee: string,
|
|
92
|
+
privileges: { privilege: string; grantable: boolean }[],
|
|
93
|
+
): void {
|
|
94
|
+
if (!this.state.has(roleName)) {
|
|
95
|
+
this.state.set(roleName, new Map());
|
|
96
|
+
}
|
|
97
|
+
// biome-ignore lint/style/noNonNullAssertion: roleName is guaranteed to be in the state
|
|
98
|
+
const roleState = this.state.get(roleName)!;
|
|
99
|
+
|
|
100
|
+
if (!roleState.has(objtype)) {
|
|
101
|
+
roleState.set(objtype, new Map());
|
|
102
|
+
}
|
|
103
|
+
// biome-ignore lint/style/noNonNullAssertion: objtype is guaranteed to be in the state
|
|
104
|
+
const objtypeState = roleState.get(objtype)!;
|
|
105
|
+
|
|
106
|
+
const schemaKey = inSchema ?? null;
|
|
107
|
+
if (!objtypeState.has(schemaKey)) {
|
|
108
|
+
objtypeState.set(schemaKey, new Map());
|
|
109
|
+
}
|
|
110
|
+
// biome-ignore lint/style/noNonNullAssertion: schemaKey is guaranteed to be in the state
|
|
111
|
+
const schemaState = objtypeState.get(schemaKey)!;
|
|
112
|
+
|
|
113
|
+
if (!schemaState.has(grantee)) {
|
|
114
|
+
schemaState.set(grantee, new Set());
|
|
115
|
+
}
|
|
116
|
+
// biome-ignore lint/style/noNonNullAssertion: grantee is guaranteed to be in the state
|
|
117
|
+
const privilegesSet = schemaState.get(grantee)!;
|
|
118
|
+
|
|
119
|
+
for (const priv of privileges) {
|
|
120
|
+
const key = `${priv.privilege}:${priv.grantable}`;
|
|
121
|
+
privilegesSet.add(key);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Apply a RevokeRoleDefaultPrivileges change to the state.
|
|
127
|
+
*/
|
|
128
|
+
applyRevoke(
|
|
129
|
+
roleName: string,
|
|
130
|
+
objtype: string,
|
|
131
|
+
inSchema: string | null,
|
|
132
|
+
grantee: string,
|
|
133
|
+
privileges: { privilege: string; grantable: boolean }[],
|
|
134
|
+
): void {
|
|
135
|
+
const roleState = this.state.get(roleName);
|
|
136
|
+
if (!roleState) return;
|
|
137
|
+
|
|
138
|
+
const objtypeState = roleState.get(objtype);
|
|
139
|
+
if (!objtypeState) return;
|
|
140
|
+
|
|
141
|
+
const schemaKey = inSchema ?? null;
|
|
142
|
+
const schemaState = objtypeState.get(schemaKey);
|
|
143
|
+
if (!schemaState) return;
|
|
144
|
+
|
|
145
|
+
const privilegesSet = schemaState.get(grantee);
|
|
146
|
+
if (!privilegesSet) return;
|
|
147
|
+
|
|
148
|
+
for (const priv of privileges) {
|
|
149
|
+
const key = `${priv.privilege}:${priv.grantable}`;
|
|
150
|
+
privilegesSet.delete(key);
|
|
151
|
+
// Also remove base privilege if grantable was revoked
|
|
152
|
+
if (priv.grantable) {
|
|
153
|
+
const baseKey = `${priv.privilege}:false`;
|
|
154
|
+
privilegesSet.delete(baseKey);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Get effective default privileges for a given object creation.
|
|
161
|
+
*/
|
|
162
|
+
getEffectiveDefaults(
|
|
163
|
+
currentUser: string,
|
|
164
|
+
objectType: string,
|
|
165
|
+
objectSchema: string,
|
|
166
|
+
): PrivilegeProps[] {
|
|
167
|
+
const objtype = objectTypeToObjtype(objectType);
|
|
168
|
+
if (!objtype) return [];
|
|
169
|
+
|
|
170
|
+
const roleState = this.state.get(currentUser);
|
|
171
|
+
if (!roleState) return [];
|
|
172
|
+
|
|
173
|
+
const objtypeState = roleState.get(objtype);
|
|
174
|
+
if (!objtypeState) return [];
|
|
175
|
+
|
|
176
|
+
const defaultPrivs: PrivilegeProps[] = [];
|
|
177
|
+
|
|
178
|
+
// Check schema-specific first, then global (null schema)
|
|
179
|
+
const schemasToCheck = [objectSchema, null];
|
|
180
|
+
for (const schemaKey of schemasToCheck) {
|
|
181
|
+
const schemaState = objtypeState.get(schemaKey);
|
|
182
|
+
if (!schemaState) continue;
|
|
183
|
+
|
|
184
|
+
for (const [grantee, privilegesSet] of schemaState.entries()) {
|
|
185
|
+
for (const privKey of privilegesSet) {
|
|
186
|
+
const [privilege, grantableStr] = privKey.split(":");
|
|
187
|
+
const grantable = grantableStr === "true";
|
|
188
|
+
defaultPrivs.push({
|
|
189
|
+
grantee,
|
|
190
|
+
privilege,
|
|
191
|
+
grantable,
|
|
192
|
+
columns: null,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// Schema-specific takes precedence, so break after first match
|
|
197
|
+
if (schemaKey === objectSchema && schemaState.size > 0) {
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return defaultPrivs;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { BasePgModel } from "./base.model.ts";
|
|
2
|
+
|
|
3
|
+
export function diffObjects<T extends BasePgModel>(
|
|
4
|
+
main: Record<string, T>,
|
|
5
|
+
branch: Record<string, T>,
|
|
6
|
+
) {
|
|
7
|
+
const mainIds = new Set(Object.keys(main));
|
|
8
|
+
const branchIds = new Set(Object.keys(branch));
|
|
9
|
+
|
|
10
|
+
const created = [...branchIds.difference(mainIds)];
|
|
11
|
+
const dropped = [...mainIds.difference(branchIds)];
|
|
12
|
+
const altered = [...mainIds.intersection(branchIds)].filter((id) => {
|
|
13
|
+
const mainModel = main[id];
|
|
14
|
+
const branchModel = branch[id];
|
|
15
|
+
|
|
16
|
+
return !mainModel.equals(branchModel);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
return { created, dropped, altered };
|
|
20
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
import { deepEqual } from "./utils.ts";
|
|
3
|
+
|
|
4
|
+
export const columnPropsSchema = z.object({
|
|
5
|
+
name: z.string(),
|
|
6
|
+
position: z.number(),
|
|
7
|
+
data_type: z.string(),
|
|
8
|
+
data_type_str: z.string(),
|
|
9
|
+
is_custom_type: z.boolean(),
|
|
10
|
+
custom_type_type: z.string().nullable(),
|
|
11
|
+
custom_type_category: z.string().nullable(),
|
|
12
|
+
custom_type_schema: z.string().nullable(),
|
|
13
|
+
custom_type_name: z.string().nullable(),
|
|
14
|
+
not_null: z.boolean(),
|
|
15
|
+
is_identity: z.boolean(),
|
|
16
|
+
is_identity_always: z.boolean(),
|
|
17
|
+
is_generated: z.boolean(),
|
|
18
|
+
collation: z.string().nullable(),
|
|
19
|
+
default: z.string().nullable(),
|
|
20
|
+
comment: z.string().nullable(),
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export type ColumnProps = z.infer<typeof columnPropsSchema>;
|
|
24
|
+
|
|
25
|
+
export function normalizeColumns(columns: ColumnProps[]) {
|
|
26
|
+
return columns
|
|
27
|
+
.map((column) => {
|
|
28
|
+
const { position: _position, ...rest } = column;
|
|
29
|
+
return rest;
|
|
30
|
+
})
|
|
31
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Interface for table-like objects that have columns (tables, views, materialized views).
|
|
36
|
+
* In PostgreSQL, these are relations with relkind in ('r', 'p', 'v', 'm').
|
|
37
|
+
*/
|
|
38
|
+
export interface TableLikeObject {
|
|
39
|
+
readonly columns: ColumnProps[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export abstract class BasePgModel {
|
|
43
|
+
/**
|
|
44
|
+
* Database-portable stable identifier for dependency resolution.
|
|
45
|
+
* This identifier remains constant across database dumps/restores and
|
|
46
|
+
* is used for cross-database dependency resolution.
|
|
47
|
+
*/
|
|
48
|
+
abstract get stableId(): string;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Get all identity fields and their values.
|
|
52
|
+
* Subclasses should override this to return the identity fields.
|
|
53
|
+
*/
|
|
54
|
+
abstract get identityFields(): Record<string, unknown>;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Get all data fields and their values.
|
|
58
|
+
* Subclasses should override this to return the data fields.
|
|
59
|
+
*/
|
|
60
|
+
abstract get dataFields(): Record<string, unknown>;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Compare this object with another BasePgModel for equality based on stableId and dataFields.
|
|
64
|
+
*/
|
|
65
|
+
equals(other: BasePgModel): boolean {
|
|
66
|
+
return (
|
|
67
|
+
this.stableId === other.stableId &&
|
|
68
|
+
deepEqual(this.dataFields, other.dataFields)
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Stable representation used for equality/fingerprints.
|
|
74
|
+
* Subclasses can override to normalize unstable fields.
|
|
75
|
+
*/
|
|
76
|
+
stableSnapshot() {
|
|
77
|
+
return {
|
|
78
|
+
identity: this.identityFields,
|
|
79
|
+
data: this.dataFields,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|