@supabase/pg-delta 1.0.0-alpha.3 → 1.0.0-alpha.5
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 +41 -2
- 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 +40 -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/cli/utils.d.ts +2 -0
- package/dist/cli/utils.js +1 -1
- 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 +25 -22
- package/dist/core/objects/table/table.model.js +4 -1
- package/dist/core/objects/trigger/changes/trigger.alter.js +23 -0
- package/dist/core/objects/trigger/changes/trigger.create.js +4 -5
- package/dist/core/objects/trigger/trigger.model.d.ts +9 -0
- package/dist/core/objects/trigger/trigger.model.js +14 -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 +11 -28
- package/dist/core/plan/create.d.ts +19 -6
- package/dist/core/plan/create.js +134 -155
- package/dist/core/plan/serialize.js +16 -4
- 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 +2447 -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 +893 -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/ssl-config.d.ts +32 -0
- package/dist/core/plan/ssl-config.js +115 -0
- package/dist/core/plan/statements.d.ts +2 -1
- package/dist/core/plan/statements.js +6 -2
- package/dist/core/plan/types.d.ts +6 -0
- package/dist/core/postgres-config.d.ts +29 -0
- package/dist/core/postgres-config.js +83 -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 +8 -0
- package/dist/index.js +7 -1
- package/package.json +54 -22
- package/src/cli/app.ts +52 -0
- package/src/cli/bin/cli.ts +15 -0
- package/src/cli/commands/apply.ts +101 -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 +216 -0
- package/src/cli/commands/sync.ts +185 -0
- package/src/cli/exit-code.test.ts +19 -0
- package/src/cli/exit-code.ts +7 -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 +238 -0
- 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/integrations.ts +42 -0
- package/src/cli/utils/resolve-input.test.ts +38 -0
- package/src/cli/utils/resolve-input.ts +17 -0
- package/src/cli/utils.ts +231 -0
- package/src/core/catalog-export/index.ts +20 -0
- package/src/core/catalog.diff.ts +247 -0
- package/src/core/catalog.model.test.ts +122 -0
- package/src/core/catalog.model.ts +510 -0
- package/src/core/catalog.snapshot.test.ts +464 -0
- package/src/core/catalog.snapshot.ts +289 -0
- package/src/core/change.types.ts +44 -0
- package/src/core/context.ts +26 -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/depend.ts +1870 -0
- package/src/core/expand-replace-dependencies.test.ts +70 -0
- package/src/core/expand-replace-dependencies.ts +380 -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/fingerprint.ts +204 -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 +266 -0
- package/src/core/integrations/filter/extractors.test.ts +244 -0
- package/src/core/integrations/filter/extractors.ts +187 -0
- package/src/core/integrations/filter/filter.types.ts +3 -0
- package/src/core/integrations/integration-dsl.ts +34 -0
- package/src/core/integrations/integration.types.ts +7 -0
- package/src/core/integrations/serialize/dsl.test.ts +91 -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 +130 -0
- package/src/core/objects/aggregate/aggregate.diff.test.ts +215 -0
- package/src/core/objects/aggregate/aggregate.diff.ts +222 -0
- package/src/core/objects/aggregate/aggregate.model.ts +317 -0
- package/src/core/objects/aggregate/changes/aggregate.alter.test.ts +66 -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 +89 -0
- package/src/core/objects/aggregate/changes/aggregate.comment.ts +62 -0
- package/src/core/objects/aggregate/changes/aggregate.create.test.ts +104 -0
- package/src/core/objects/aggregate/changes/aggregate.create.ts +329 -0
- package/src/core/objects/aggregate/changes/aggregate.drop.test.ts +82 -0
- package/src/core/objects/aggregate/changes/aggregate.drop.ts +32 -0
- package/src/core/objects/aggregate/changes/aggregate.privilege.test.ts +136 -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 +447 -0
- package/src/core/objects/base.privilege.ts +191 -0
- package/src/core/objects/collation/changes/collation.alter.test.ts +68 -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 +56 -0
- package/src/core/objects/collation/changes/collation.create.ts +106 -0
- package/src/core/objects/collation/changes/collation.drop.test.ts +31 -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 +97 -0
- package/src/core/objects/collation/collation.diff.ts +127 -0
- package/src/core/objects/collation/collation.model.ts +224 -0
- package/src/core/objects/diff-context.ts +16 -0
- package/src/core/objects/domain/changes/domain.alter.test.ts +335 -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 +95 -0
- package/src/core/objects/domain/changes/domain.create.ts +124 -0
- package/src/core/objects/domain/changes/domain.drop.test.ts +33 -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 +295 -0
- package/src/core/objects/domain/domain.model.ts +190 -0
- package/src/core/objects/event-trigger/changes/event-trigger.alter.test.ts +57 -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 +27 -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 +25 -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 +131 -0
- package/src/core/objects/event-trigger/event-trigger.diff.ts +127 -0
- package/src/core/objects/event-trigger/event-trigger.model.ts +106 -0
- package/src/core/objects/extension/changes/extension.alter.test.ts +63 -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 +28 -0
- package/src/core/objects/extension/changes/extension.create.ts +63 -0
- package/src/core/objects/extension/changes/extension.drop.test.ts +26 -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.test.ts +98 -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 +136 -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 +160 -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 +26 -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 +286 -0
- package/src/core/objects/foreign-data-wrapper/foreign-data-wrapper/foreign-data-wrapper.diff.ts +271 -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 +340 -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 +210 -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 +46 -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 +343 -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 +183 -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 +144 -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 +27 -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 +262 -0
- package/src/core/objects/foreign-data-wrapper/server/server.diff.ts +247 -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 +91 -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 +96 -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 +60 -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 +209 -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 +69 -0
- package/src/core/objects/index/changes/index.create.ts +68 -0
- package/src/core/objects/index/changes/index.drop.test.ts +47 -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 +36 -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 +30 -0
- package/src/core/objects/language/changes/language.create.ts +104 -0
- package/src/core/objects/language/changes/language.drop.test.ts +28 -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 +135 -0
- package/src/core/objects/language/language.diff.ts +144 -0
- package/src/core/objects/language/language.model.ts +150 -0
- package/src/core/objects/materialized-view/changes/materialized-view.alter.test.ts +130 -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 +69 -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 +37 -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 +264 -0
- package/src/core/objects/materialized-view/materialized-view.diff.ts +301 -0
- package/src/core/objects/materialized-view/materialized-view.model.ts +258 -0
- package/src/core/objects/procedure/changes/procedure.alter.test.ts +1077 -0
- package/src/core/objects/procedure/changes/procedure.alter.ts +290 -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 +51 -0
- package/src/core/objects/procedure/changes/procedure.create.ts +92 -0
- package/src/core/objects/procedure/changes/procedure.drop.test.ts +90 -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 +341 -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 +217 -0
- package/src/core/objects/publication/changes/publication.alter.ts +225 -0
- package/src/core/objects/publication/changes/publication.base.ts +20 -0
- package/src/core/objects/publication/changes/publication.comment.test.ts +73 -0
- package/src/core/objects/publication/changes/publication.comment.ts +64 -0
- package/src/core/objects/publication/changes/publication.create.test.ts +90 -0
- package/src/core/objects/publication/changes/publication.create.ts +82 -0
- package/src/core/objects/publication/changes/publication.drop.test.ts +48 -0
- package/src/core/objects/publication/changes/publication.drop.ts +29 -0
- package/src/core/objects/publication/changes/publication.types.ts +24 -0
- package/src/core/objects/publication/publication.diff.test.ts +297 -0
- package/src/core/objects/publication/publication.diff.ts +247 -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 +267 -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 +81 -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 +31 -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 +362 -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 +56 -0
- package/src/core/objects/role/changes/role.create.ts +102 -0
- package/src/core/objects/role/changes/role.drop.test.ts +32 -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 +279 -0
- package/src/core/objects/role/role.diff.ts +499 -0
- package/src/core/objects/role/role.model.ts +452 -0
- package/src/core/objects/rule/changes/rule.alter.test.ts +82 -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 +58 -0
- package/src/core/objects/rule/changes/rule.comment.ts +62 -0
- package/src/core/objects/rule/changes/rule.create.test.ts +63 -0
- package/src/core/objects/rule/changes/rule.create.ts +42 -0
- package/src/core/objects/rule/changes/rule.drop.test.ts +40 -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 +31 -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 +25 -0
- package/src/core/objects/schema/changes/schema.create.ts +47 -0
- package/src/core/objects/schema/changes/schema.drop.test.ts +23 -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 +146 -0
- package/src/core/objects/schema/schema.model.ts +107 -0
- package/src/core/objects/sequence/changes/sequence.alter.test.ts +157 -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 +89 -0
- package/src/core/objects/sequence/changes/sequence.create.ts +111 -0
- package/src/core/objects/sequence/changes/sequence.drop.test.ts +35 -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 +255 -0
- package/src/core/objects/sequence/sequence.diff.ts +294 -0
- package/src/core/objects/sequence/sequence.model.ts +185 -0
- package/src/core/objects/subscription/changes/subscription.alter.test.ts +134 -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 +70 -0
- package/src/core/objects/subscription/changes/subscription.comment.ts +64 -0
- package/src/core/objects/subscription/changes/subscription.create.test.ts +80 -0
- package/src/core/objects/subscription/changes/subscription.create.ts +69 -0
- package/src/core/objects/subscription/changes/subscription.drop.test.ts +48 -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 +237 -0
- package/src/core/objects/subscription/subscription.diff.ts +242 -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 +846 -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 +188 -0
- package/src/core/objects/table/changes/table.create.ts +192 -0
- package/src/core/objects/table/changes/table.drop.test.ts +36 -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 +868 -0
- package/src/core/objects/table/table.diff.ts +817 -0
- package/src/core/objects/table/table.model.ts +460 -0
- package/src/core/objects/trigger/changes/trigger.alter.test.ts +50 -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 +47 -0
- package/src/core/objects/trigger/changes/trigger.create.ts +88 -0
- package/src/core/objects/trigger/changes/trigger.drop.test.ts +47 -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 +84 -0
- package/src/core/objects/trigger/trigger.diff.ts +116 -0
- package/src/core/objects/trigger/trigger.model.ts +264 -0
- package/src/core/objects/type/composite-type/changes/composite-type.alter.test.ts +208 -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 +106 -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 +36 -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 +269 -0
- package/src/core/objects/type/composite-type/composite-type.diff.ts +310 -0
- package/src/core/objects/type/composite-type/composite-type.model.ts +253 -0
- package/src/core/objects/type/enum/changes/enum.alter.test.ts +113 -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 +31 -0
- package/src/core/objects/type/enum/changes/enum.create.ts +56 -0
- package/src/core/objects/type/enum/changes/enum.drop.test.ts +28 -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 +372 -0
- package/src/core/objects/type/enum/enum.diff.ts +308 -0
- package/src/core/objects/type/enum/enum.model.ts +194 -0
- package/src/core/objects/type/range/changes/range.alter.test.ts +29 -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 +54 -0
- package/src/core/objects/type/range/changes/range.create.ts +155 -0
- package/src/core/objects/type/range/changes/range.drop.test.ts +28 -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 +147 -0
- package/src/core/objects/type/range/range.diff.ts +197 -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 +115 -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 +70 -0
- package/src/core/objects/view/changes/view.create.ts +73 -0
- package/src/core/objects/view/changes/view.drop.test.ts +37 -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 +173 -0
- package/src/core/objects/view/view.diff.ts +215 -0
- package/src/core/objects/view/view.model.ts +262 -0
- package/src/core/plan/apply.ts +172 -0
- package/src/core/plan/create.ts +368 -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.test.ts +317 -0
- package/src/core/plan/serialize.ts +209 -0
- package/src/core/plan/sql-format/constants.ts +13 -0
- package/src/core/plan/sql-format/fixtures.ts +2803 -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 +119 -0
- package/src/core/plan/sql-format/format-off.test.ts +806 -0
- package/src/core/plan/sql-format/format-pretty-lower-leading.test.ts +1061 -0
- package/src/core/plan/sql-format/format-pretty-narrow.test.ts +1279 -0
- package/src/core/plan/sql-format/format-pretty-preserve.test.ts +1057 -0
- package/src/core/plan/sql-format/format-pretty-upper.test.ts +1048 -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 +1120 -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/ssl-config.ts +172 -0
- package/src/core/plan/statements.ts +22 -0
- package/src/core/plan/types.ts +171 -0
- package/src/core/postgres-config.ts +238 -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 +235 -0
- package/src/core/sort/graph-utils.ts +51 -0
- package/src/core/sort/logical-sort.test.ts +371 -0
- package/src/core/sort/logical-sort.ts +597 -0
- package/src/core/sort/sort-changes.ts +234 -0
- package/src/core/sort/topological-sort.test.ts +275 -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/core/test-utils/assert-valid-sql.ts +20 -0
- package/src/index.ts +38 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { indentString } from "./format-utils.js";
|
|
2
|
+
import { isWordChar, walkSql } from "./sql-scanner.js";
|
|
3
|
+
/**
|
|
4
|
+
* Keywords that are preferred break points when wrapping long lines.
|
|
5
|
+
* The wrapper will prefer to break just before one of these keywords
|
|
6
|
+
* rather than at an arbitrary whitespace position.
|
|
7
|
+
*/
|
|
8
|
+
const WRAP_PREFERRED_KEYWORDS = new Set([
|
|
9
|
+
"ADD",
|
|
10
|
+
"CHECK",
|
|
11
|
+
"CONNECTION",
|
|
12
|
+
"CONSTRAINT",
|
|
13
|
+
"DEFERRABLE",
|
|
14
|
+
"FOREIGN",
|
|
15
|
+
"HANDLER",
|
|
16
|
+
"INCLUDE",
|
|
17
|
+
"INITIALLY",
|
|
18
|
+
"INLINE",
|
|
19
|
+
"MATCH",
|
|
20
|
+
"NOT",
|
|
21
|
+
"ON",
|
|
22
|
+
"OPTIONS",
|
|
23
|
+
"PUBLICATION",
|
|
24
|
+
"REFERENCES",
|
|
25
|
+
"REFERENCING",
|
|
26
|
+
"SET",
|
|
27
|
+
"USING",
|
|
28
|
+
"VALIDATOR",
|
|
29
|
+
"WHERE",
|
|
30
|
+
"WITH",
|
|
31
|
+
]);
|
|
32
|
+
export function wrapStatement(statement, options, noWrapPlaceholders) {
|
|
33
|
+
const lines = statement.split(/\r?\n/);
|
|
34
|
+
const wrapped = [];
|
|
35
|
+
for (const line of lines) {
|
|
36
|
+
if (line.trim().startsWith("--")) {
|
|
37
|
+
wrapped.push(line);
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (hasNoWrapPlaceholder(line, noWrapPlaceholders)) {
|
|
41
|
+
wrapped.push(line);
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
wrapped.push(...wrapLine(line, options));
|
|
45
|
+
}
|
|
46
|
+
return wrapped.join("\n");
|
|
47
|
+
}
|
|
48
|
+
function hasNoWrapPlaceholder(line, placeholders) {
|
|
49
|
+
for (const token of placeholders) {
|
|
50
|
+
if (line.includes(token))
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
function wrapLine(line, options) {
|
|
56
|
+
const maxWidth = options.maxWidth;
|
|
57
|
+
if (maxWidth <= 0 || line.length <= maxWidth) {
|
|
58
|
+
return [line];
|
|
59
|
+
}
|
|
60
|
+
const indentMatch = line.match(/^\s*/);
|
|
61
|
+
const baseIndent = indentMatch ? indentMatch[0] : "";
|
|
62
|
+
const continuationIndent = `${baseIndent}${indentString(options.indent)}`;
|
|
63
|
+
let remaining = line;
|
|
64
|
+
const output = [];
|
|
65
|
+
while (remaining.length > maxWidth) {
|
|
66
|
+
const breakpoint = findWrapPosition(remaining, maxWidth);
|
|
67
|
+
if (breakpoint <= 0)
|
|
68
|
+
break;
|
|
69
|
+
const head = remaining.slice(0, breakpoint).trimEnd();
|
|
70
|
+
const tail = remaining.slice(breakpoint).trimStart();
|
|
71
|
+
output.push(head);
|
|
72
|
+
const next = `${continuationIndent}${tail}`;
|
|
73
|
+
if (next.length >= remaining.length) {
|
|
74
|
+
remaining = next;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
remaining = next;
|
|
78
|
+
}
|
|
79
|
+
output.push(remaining);
|
|
80
|
+
return output;
|
|
81
|
+
}
|
|
82
|
+
/** Words that should not be separated from the previous word when wrapping (e.g. CREATE PUBLICATION, COMMENT ON). */
|
|
83
|
+
const KEEP_WITH_PREVIOUS = new Set([
|
|
84
|
+
"PUBLICATION",
|
|
85
|
+
"TABLE",
|
|
86
|
+
"VIEW",
|
|
87
|
+
"SCHEMA",
|
|
88
|
+
"INDEX",
|
|
89
|
+
"OR", // CREATE OR REPLACE
|
|
90
|
+
"ON", // COMMENT ON
|
|
91
|
+
]);
|
|
92
|
+
function getPreviousWord(text, beforeIndex) {
|
|
93
|
+
let end = beforeIndex - 1;
|
|
94
|
+
while (end >= 0 && (text[end] === " " || text[end] === "\t")) {
|
|
95
|
+
end -= 1;
|
|
96
|
+
}
|
|
97
|
+
if (end < 0 || !isWordChar(text[end]))
|
|
98
|
+
return null;
|
|
99
|
+
let start = end;
|
|
100
|
+
while (start > 0 && isWordChar(text[start - 1])) {
|
|
101
|
+
start -= 1;
|
|
102
|
+
}
|
|
103
|
+
return text.slice(start, end + 1).toUpperCase();
|
|
104
|
+
}
|
|
105
|
+
function findWrapPosition(text, maxWidth) {
|
|
106
|
+
/** Last whitespace at depth 0 (preferred — avoids splitting parenthesized expressions) */
|
|
107
|
+
let lastTopLevelWhitespace = -1;
|
|
108
|
+
/** Last whitespace at any depth (fallback when no depth-0 break exists) */
|
|
109
|
+
let lastAnyWhitespace = -1;
|
|
110
|
+
let lastKeywordBoundary = -1;
|
|
111
|
+
/** First (leftmost) top-level comma within maxWidth — break there so each clause gets its own line */
|
|
112
|
+
let firstComma = -1;
|
|
113
|
+
// Never break within the leading indent — that would produce an empty head line
|
|
114
|
+
const contentStart = text.search(/\S/);
|
|
115
|
+
if (contentStart < 0)
|
|
116
|
+
return -1; // all whitespace
|
|
117
|
+
walkSql(text, (index, char, depth) => {
|
|
118
|
+
if (index > maxWidth)
|
|
119
|
+
return false;
|
|
120
|
+
// Skip positions within leading indent
|
|
121
|
+
if (index < contentStart)
|
|
122
|
+
return true;
|
|
123
|
+
// Prefer breaking after the first top-level comma so comma-separated clauses (e.g. publication tables) each get their own line
|
|
124
|
+
if (char === "," && depth === 0 && firstComma < 0) {
|
|
125
|
+
firstComma = index + 1; // position after the comma
|
|
126
|
+
}
|
|
127
|
+
if (char === " " || char === "\t") {
|
|
128
|
+
lastAnyWhitespace = index;
|
|
129
|
+
if (depth === 0) {
|
|
130
|
+
lastTopLevelWhitespace = index;
|
|
131
|
+
}
|
|
132
|
+
// Check if the next word is a preferred keyword
|
|
133
|
+
const nextWordStart = index + 1;
|
|
134
|
+
if (nextWordStart < text.length && isWordChar(text[nextWordStart])) {
|
|
135
|
+
let wordEnd = nextWordStart + 1;
|
|
136
|
+
while (wordEnd < text.length && isWordChar(text[wordEnd])) {
|
|
137
|
+
wordEnd += 1;
|
|
138
|
+
}
|
|
139
|
+
const word = text.slice(nextWordStart, wordEnd).toUpperCase();
|
|
140
|
+
if (WRAP_PREFERRED_KEYWORDS.has(word)) {
|
|
141
|
+
// Don't break between CREATE and object type, COMMENT and ON, or ALL and ON (GRANT/REVOKE ALL ON)
|
|
142
|
+
const prev = getPreviousWord(text, index);
|
|
143
|
+
if (prev !== null &&
|
|
144
|
+
((prev === "CREATE" && KEEP_WITH_PREVIOUS.has(word)) ||
|
|
145
|
+
((prev === "COMMENT" || prev === "ALL") && word === "ON"))) {
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
lastKeywordBoundary = index;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return true;
|
|
153
|
+
}, { trackDepth: true });
|
|
154
|
+
// Prefer: 1) comma, 2) keyword boundary, 3) depth-0 whitespace, 4) any whitespace
|
|
155
|
+
if (firstComma > 0 && firstComma <= maxWidth) {
|
|
156
|
+
return firstComma;
|
|
157
|
+
}
|
|
158
|
+
if (lastKeywordBoundary > 0 && lastKeywordBoundary <= maxWidth) {
|
|
159
|
+
return lastKeywordBoundary;
|
|
160
|
+
}
|
|
161
|
+
if (lastTopLevelWhitespace > 0) {
|
|
162
|
+
return lastTopLevelWhitespace;
|
|
163
|
+
}
|
|
164
|
+
return lastAnyWhitespace;
|
|
165
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { formatSqlStatements } from "./sql-format/index.js";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSL configuration parsing for PostgreSQL connection URLs.
|
|
3
|
+
*
|
|
4
|
+
* Supports sslmode and certificate paths (URL params or env). Used by plan,
|
|
5
|
+
* apply, and catalog-export when connecting to source/target databases.
|
|
6
|
+
*/
|
|
7
|
+
/** Parsed SSL options for the pg client plus URL with SSL params stripped (internal). */
|
|
8
|
+
type SslConfig = {
|
|
9
|
+
ssl?: boolean | {
|
|
10
|
+
rejectUnauthorized: boolean;
|
|
11
|
+
ca?: string;
|
|
12
|
+
cert?: string;
|
|
13
|
+
key?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Custom server identity check function.
|
|
16
|
+
* Used to skip hostname verification for verify-ca mode.
|
|
17
|
+
* Returns undefined to indicate success (no error).
|
|
18
|
+
*/
|
|
19
|
+
checkServerIdentity?: () => undefined;
|
|
20
|
+
};
|
|
21
|
+
cleanedUrl: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Parse SSL configuration from a PostgreSQL connection URL.
|
|
25
|
+
* Supports sslmode (require, verify-ca, verify-full, prefer, disable).
|
|
26
|
+
* Certificates can be provided via:
|
|
27
|
+
* - Query string parameters (file paths): sslrootcert, sslcert, sslkey (preferred)
|
|
28
|
+
* - Environment variables (content): PGDELTA_SOURCE_SSLROOTCERT/SSLCERT/SSLKEY or PGDELTA_TARGET_SSLROOTCERT/SSLCERT/SSLKEY
|
|
29
|
+
* Returns SSL options for the postgres.js library and a cleaned URL without SSL-related query parameters.
|
|
30
|
+
*/
|
|
31
|
+
export declare function parseSslConfig(url: string, connectionType: "source" | "target"): Promise<SslConfig>;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSL configuration parsing for PostgreSQL connection URLs.
|
|
3
|
+
*
|
|
4
|
+
* Supports sslmode and certificate paths (URL params or env). Used by plan,
|
|
5
|
+
* apply, and catalog-export when connecting to source/target databases.
|
|
6
|
+
*/
|
|
7
|
+
import { readFile } from "node:fs/promises";
|
|
8
|
+
/**
|
|
9
|
+
* Parse SSL configuration from a PostgreSQL connection URL.
|
|
10
|
+
* Supports sslmode (require, verify-ca, verify-full, prefer, disable).
|
|
11
|
+
* Certificates can be provided via:
|
|
12
|
+
* - Query string parameters (file paths): sslrootcert, sslcert, sslkey (preferred)
|
|
13
|
+
* - Environment variables (content): PGDELTA_SOURCE_SSLROOTCERT/SSLCERT/SSLKEY or PGDELTA_TARGET_SSLROOTCERT/SSLCERT/SSLKEY
|
|
14
|
+
* Returns SSL options for the postgres.js library and a cleaned URL without SSL-related query parameters.
|
|
15
|
+
*/
|
|
16
|
+
export async function parseSslConfig(url, connectionType) {
|
|
17
|
+
const urlObj = new URL(url);
|
|
18
|
+
const sslmode = urlObj.searchParams.get("sslmode");
|
|
19
|
+
const sslrootcert = urlObj.searchParams.get("sslrootcert");
|
|
20
|
+
const sslcert = urlObj.searchParams.get("sslcert");
|
|
21
|
+
const sslkey = urlObj.searchParams.get("sslkey");
|
|
22
|
+
// Remove SSL-related query parameters since we parse them ourselves
|
|
23
|
+
urlObj.searchParams.delete("sslmode");
|
|
24
|
+
urlObj.searchParams.delete("sslrootcert");
|
|
25
|
+
urlObj.searchParams.delete("sslcert");
|
|
26
|
+
urlObj.searchParams.delete("sslkey");
|
|
27
|
+
const cleanedUrl = urlObj.toString();
|
|
28
|
+
// Handle different SSL modes
|
|
29
|
+
if (sslmode === "disable") {
|
|
30
|
+
return { cleanedUrl, ssl: false };
|
|
31
|
+
}
|
|
32
|
+
if (sslmode === "require" ||
|
|
33
|
+
sslmode === "prefer" ||
|
|
34
|
+
sslmode === "verify-ca" ||
|
|
35
|
+
sslmode === "verify-full") {
|
|
36
|
+
// Helper function to get certificate value: query param (file path) takes precedence over env var (content)
|
|
37
|
+
const getCertValue = async (queryParam, envVarName) => {
|
|
38
|
+
// Prefer query parameter (file path)
|
|
39
|
+
if (queryParam) {
|
|
40
|
+
try {
|
|
41
|
+
return await readFile(queryParam, "utf-8");
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
throw new Error(`Failed to read certificate file '${queryParam}': ${error instanceof Error ? error.message : String(error)}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// Fallback to environment variable (content)
|
|
48
|
+
const envValue = process.env[envVarName];
|
|
49
|
+
return envValue || undefined;
|
|
50
|
+
};
|
|
51
|
+
const hasExplicitVerification = sslmode === "verify-ca" || sslmode === "verify-full";
|
|
52
|
+
// Get CA certificate value.
|
|
53
|
+
// - verify-ca/verify-full: check query param first, then env var
|
|
54
|
+
// - require/prefer: only check query param (libpq backward compatibility
|
|
55
|
+
// requires an explicit root CA *file*, not a global env var)
|
|
56
|
+
const caEnvVar = connectionType === "source"
|
|
57
|
+
? "PGDELTA_SOURCE_SSLROOTCERT"
|
|
58
|
+
: "PGDELTA_TARGET_SSLROOTCERT";
|
|
59
|
+
let caValue;
|
|
60
|
+
if (sslrootcert) {
|
|
61
|
+
// Explicit file path in query param — always honour it
|
|
62
|
+
caValue = await getCertValue(sslrootcert, caEnvVar);
|
|
63
|
+
}
|
|
64
|
+
else if (hasExplicitVerification) {
|
|
65
|
+
// verify-ca / verify-full without file path — fall back to env var
|
|
66
|
+
caValue = await getCertValue(null, caEnvVar);
|
|
67
|
+
}
|
|
68
|
+
// require/prefer without sslrootcert: no CA cert, no verification
|
|
69
|
+
// Determine if we should verify the CA chain
|
|
70
|
+
// From PostgreSQL docs: "if a root CA file exists, the behavior of sslmode=require
|
|
71
|
+
// will be the same as that of verify-ca"
|
|
72
|
+
const hasLibpqCompatibility = (sslmode === "require" || sslmode === "prefer") && caValue !== undefined;
|
|
73
|
+
const shouldVerifyCa = hasExplicitVerification || hasLibpqCompatibility;
|
|
74
|
+
// Determine if we should verify hostname
|
|
75
|
+
// - verify-full: verify both CA and hostname
|
|
76
|
+
// - verify-ca: verify CA only (skip hostname)
|
|
77
|
+
// - require/prefer with CA (libpq compat): behaves like verify-ca (skip hostname)
|
|
78
|
+
const shouldVerifyHostname = sslmode === "verify-full";
|
|
79
|
+
const ssl = {
|
|
80
|
+
rejectUnauthorized: shouldVerifyCa,
|
|
81
|
+
};
|
|
82
|
+
// Add CA certificate if verifying
|
|
83
|
+
if (shouldVerifyCa && caValue) {
|
|
84
|
+
ssl.ca = caValue;
|
|
85
|
+
}
|
|
86
|
+
// For verify-ca and libpq compatibility mode: skip hostname verification
|
|
87
|
+
// This matches PostgreSQL semantics where verify-ca only checks the CA chain
|
|
88
|
+
if (shouldVerifyCa && !shouldVerifyHostname) {
|
|
89
|
+
ssl.checkServerIdentity = () => undefined;
|
|
90
|
+
}
|
|
91
|
+
// Get client certificate (optional, for mutual TLS)
|
|
92
|
+
const certEnvVar = connectionType === "source"
|
|
93
|
+
? "PGDELTA_SOURCE_SSLCERT"
|
|
94
|
+
: "PGDELTA_TARGET_SSLCERT";
|
|
95
|
+
const certValue = await getCertValue(sslcert, certEnvVar);
|
|
96
|
+
if (certValue) {
|
|
97
|
+
ssl.cert = certValue;
|
|
98
|
+
}
|
|
99
|
+
// Get client key (optional, for mutual TLS, required if cert is provided)
|
|
100
|
+
const keyEnvVar = connectionType === "source"
|
|
101
|
+
? "PGDELTA_SOURCE_SSLKEY"
|
|
102
|
+
: "PGDELTA_TARGET_SSLKEY";
|
|
103
|
+
const keyValue = await getCertValue(sslkey, keyEnvVar);
|
|
104
|
+
if (keyValue) {
|
|
105
|
+
ssl.key = keyValue;
|
|
106
|
+
}
|
|
107
|
+
// Warn if cert is provided without key (or vice versa)
|
|
108
|
+
if ((ssl.cert && !ssl.key) || (!ssl.cert && ssl.key)) {
|
|
109
|
+
throw new Error("Both client certificate and key must be provided together for mutual TLS");
|
|
110
|
+
}
|
|
111
|
+
return { ssl, cleanedUrl };
|
|
112
|
+
}
|
|
113
|
+
// No sslmode specified or invalid value - explicitly disable SSL
|
|
114
|
+
return { cleanedUrl, ssl: false };
|
|
115
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SQL script formatting utilities.
|
|
3
3
|
*/
|
|
4
|
+
import { type SqlFormatOptions } from "./sql-format.ts";
|
|
4
5
|
/**
|
|
5
6
|
* Format an array of SQL statements into a single script string.
|
|
6
7
|
* Statements are joined with double newlines and the script ends with a semicolon.
|
|
7
8
|
*/
|
|
8
|
-
export declare function formatSqlScript(statements: string[]): string;
|
|
9
|
+
export declare function formatSqlScript(statements: string[], options?: SqlFormatOptions): string;
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* SQL script formatting utilities.
|
|
3
3
|
*/
|
|
4
|
+
import { formatSqlStatements } from "./sql-format.js";
|
|
4
5
|
const STATEMENT_DELIMITER = ";\n\n";
|
|
5
6
|
/**
|
|
6
7
|
* Format an array of SQL statements into a single script string.
|
|
7
8
|
* Statements are joined with double newlines and the script ends with a semicolon.
|
|
8
9
|
*/
|
|
9
|
-
export function formatSqlScript(statements) {
|
|
10
|
+
export function formatSqlScript(statements, options) {
|
|
10
11
|
if (statements.length === 0)
|
|
11
12
|
return "";
|
|
12
|
-
|
|
13
|
+
const formatted = options
|
|
14
|
+
? formatSqlStatements(statements, options)
|
|
15
|
+
: statements;
|
|
16
|
+
return `${formatted.join(STATEMENT_DELIMITER)};`;
|
|
13
17
|
}
|
|
@@ -138,5 +138,11 @@ export interface CreatePlanOptions {
|
|
|
138
138
|
serialize?: SerializeDSL | ChangeSerializer;
|
|
139
139
|
/** Role to use when executing the migration (SET ROLE will be added to statements) */
|
|
140
140
|
role?: string;
|
|
141
|
+
/**
|
|
142
|
+
* When true, don't subtract privileges covered by ALTER DEFAULT PRIVILEGES
|
|
143
|
+
* from explicit GRANTs during diffing. Use this for declarative export where
|
|
144
|
+
* the output must be self-contained and not rely on statement execution order.
|
|
145
|
+
*/
|
|
146
|
+
skipDefaultPrivilegeSubtraction?: boolean;
|
|
141
147
|
}
|
|
142
148
|
export {};
|
|
@@ -20,4 +20,33 @@ interface CreatePoolOptions extends Partial<PoolConfig> {
|
|
|
20
20
|
* Create a Pool with custom type handlers and optional event listeners.
|
|
21
21
|
*/
|
|
22
22
|
export declare function createPool(connectionString: string, options?: CreatePoolOptions): Pool;
|
|
23
|
+
/**
|
|
24
|
+
* End a pool and wait for all client sockets to fully close.
|
|
25
|
+
*
|
|
26
|
+
* pg-pool's `pool.end()` resolves once clients are removed from its
|
|
27
|
+
* internal bookkeeping, but the underlying `client.end()` calls (which
|
|
28
|
+
* close the TCP/TLS sockets) are fired asynchronously *after* that.
|
|
29
|
+
* If the server (e.g. a test container) is stopped right after
|
|
30
|
+
* `pool.end()` resolves, the still-open sockets receive an unexpected
|
|
31
|
+
* RST and emit unhandled "Connection terminated unexpectedly" errors.
|
|
32
|
+
*
|
|
33
|
+
* This helper waits for every `remove` event — which pg-pool emits
|
|
34
|
+
* inside each `client.end()` callback — ensuring all sockets are
|
|
35
|
+
* truly closed before it resolves.
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* Create a pool from a connection URL with standard session setup:
|
|
39
|
+
* SSL parsing, search_path isolation, optional SET ROLE, and 57P01 suppression.
|
|
40
|
+
*
|
|
41
|
+
* Returns the pool and a `close` function that properly waits for all sockets
|
|
42
|
+
* to close (via {@link endPool}).
|
|
43
|
+
*/
|
|
44
|
+
export declare function createManagedPool(url: string, options?: {
|
|
45
|
+
role?: string;
|
|
46
|
+
label?: "source" | "target";
|
|
47
|
+
}): Promise<{
|
|
48
|
+
pool: Pool;
|
|
49
|
+
close: () => Promise<void>;
|
|
50
|
+
}>;
|
|
51
|
+
export declare function endPool(pool: Pool): Promise<void>;
|
|
23
52
|
export {};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* PostgreSQL connection configuration with custom type handlers.
|
|
3
3
|
*/
|
|
4
|
-
import { Pool, types } from "pg";
|
|
4
|
+
import { escapeIdentifier, Pool, types } from "pg";
|
|
5
|
+
import { parseSslConfig } from "./plan/ssl-config.js";
|
|
5
6
|
// ============================================================================
|
|
6
7
|
// Array Parser
|
|
7
8
|
// ============================================================================
|
|
@@ -92,12 +93,20 @@ types.setTypeParser(1005, (val) => parseArray(val, parseIntElement)); // int2[]
|
|
|
92
93
|
types.setTypeParser(1007, (val) => parseArray(val, parseIntElement)); // int4[]
|
|
93
94
|
// @ts-expect-error - pg types expects TypeId but raw OID numbers work fine
|
|
94
95
|
types.setTypeParser(1016, (val) => parseArray(val, parseIntElement)); // int8[]
|
|
96
|
+
const DEFAULT_POOL_MAX = Number(process.env.PGDELTA_POOL_MAX) || 5;
|
|
97
|
+
const DEFAULT_CONNECTION_TIMEOUT_MS = Number(process.env.PGDELTA_CONNECTION_TIMEOUT_MS) || 3_000;
|
|
98
|
+
const DEFAULT_CONNECT_TIMEOUT_MS = Number(process.env.PGDELTA_CONNECT_TIMEOUT_MS) || 2_500;
|
|
95
99
|
/**
|
|
96
100
|
* Create a Pool with custom type handlers and optional event listeners.
|
|
97
101
|
*/
|
|
98
102
|
export function createPool(connectionString, options) {
|
|
99
103
|
const { onConnect, onError, onAcquire, onRemove, ...config } = options ?? {};
|
|
100
|
-
const pool = new Pool({
|
|
104
|
+
const pool = new Pool({
|
|
105
|
+
connectionString,
|
|
106
|
+
max: DEFAULT_POOL_MAX,
|
|
107
|
+
connectionTimeoutMillis: DEFAULT_CONNECTION_TIMEOUT_MS,
|
|
108
|
+
...config,
|
|
109
|
+
});
|
|
101
110
|
if (onConnect)
|
|
102
111
|
pool.on("connect", onConnect);
|
|
103
112
|
if (onError)
|
|
@@ -108,3 +117,75 @@ export function createPool(connectionString, options) {
|
|
|
108
117
|
pool.on("remove", onRemove);
|
|
109
118
|
return pool;
|
|
110
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* End a pool and wait for all client sockets to fully close.
|
|
122
|
+
*
|
|
123
|
+
* pg-pool's `pool.end()` resolves once clients are removed from its
|
|
124
|
+
* internal bookkeeping, but the underlying `client.end()` calls (which
|
|
125
|
+
* close the TCP/TLS sockets) are fired asynchronously *after* that.
|
|
126
|
+
* If the server (e.g. a test container) is stopped right after
|
|
127
|
+
* `pool.end()` resolves, the still-open sockets receive an unexpected
|
|
128
|
+
* RST and emit unhandled "Connection terminated unexpectedly" errors.
|
|
129
|
+
*
|
|
130
|
+
* This helper waits for every `remove` event — which pg-pool emits
|
|
131
|
+
* inside each `client.end()` callback — ensuring all sockets are
|
|
132
|
+
* truly closed before it resolves.
|
|
133
|
+
*/
|
|
134
|
+
/**
|
|
135
|
+
* Create a pool from a connection URL with standard session setup:
|
|
136
|
+
* SSL parsing, search_path isolation, optional SET ROLE, and 57P01 suppression.
|
|
137
|
+
*
|
|
138
|
+
* Returns the pool and a `close` function that properly waits for all sockets
|
|
139
|
+
* to close (via {@link endPool}).
|
|
140
|
+
*/
|
|
141
|
+
export async function createManagedPool(url, options) {
|
|
142
|
+
const sslConfig = await parseSslConfig(url, options?.label ?? "target");
|
|
143
|
+
const pool = createPool(sslConfig.cleanedUrl, {
|
|
144
|
+
...(sslConfig.ssl !== undefined ? { ssl: sslConfig.ssl } : {}),
|
|
145
|
+
onError: (err) => {
|
|
146
|
+
if (err.code !== "57P01") {
|
|
147
|
+
console.error("Pool error:", err);
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
onConnect: async (client) => {
|
|
151
|
+
await client.query("SET search_path = ''");
|
|
152
|
+
if (options?.role) {
|
|
153
|
+
await client.query(`SET ROLE ${escapeIdentifier(options.role)}`);
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
// Eagerly validate connectivity so SSL/auth failures surface immediately
|
|
158
|
+
// instead of hanging on the first real query. node-pg's connectionTimeoutMillis
|
|
159
|
+
// is not reliably enforced under Bun when SSL negotiation hangs.
|
|
160
|
+
const label = options?.label ?? "target";
|
|
161
|
+
const timeoutMs = DEFAULT_CONNECT_TIMEOUT_MS;
|
|
162
|
+
try {
|
|
163
|
+
const client = await Promise.race([
|
|
164
|
+
pool.connect(),
|
|
165
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error(`Connection to ${label} database timed out after ${timeoutMs}ms. ` +
|
|
166
|
+
`The server may require SSL, use an invalid certificate, or be unreachable.`)), timeoutMs)),
|
|
167
|
+
]);
|
|
168
|
+
client.release();
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
await pool.end().catch(() => { });
|
|
172
|
+
throw err;
|
|
173
|
+
}
|
|
174
|
+
return { pool, close: () => endPool(pool) };
|
|
175
|
+
}
|
|
176
|
+
export function endPool(pool) {
|
|
177
|
+
const clientCount = pool.totalCount;
|
|
178
|
+
if (clientCount === 0) {
|
|
179
|
+
return pool.end();
|
|
180
|
+
}
|
|
181
|
+
return new Promise((resolve, reject) => {
|
|
182
|
+
let removed = 0;
|
|
183
|
+
pool.on("remove", function onRemove() {
|
|
184
|
+
if (++removed >= clientCount) {
|
|
185
|
+
pool.removeListener("remove", onRemove);
|
|
186
|
+
resolve();
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
pool.end().catch(reject);
|
|
190
|
+
});
|
|
191
|
+
}
|
|
@@ -56,7 +56,17 @@ export function convertExplicitRequirementsToConstraints(phaseChanges, graphData
|
|
|
56
56
|
const requiredIds = graphData.explicitRequirementSets[consumerIndex];
|
|
57
57
|
if (requiredIds.size === 0)
|
|
58
58
|
continue;
|
|
59
|
+
// Collect dropped IDs for this change so we can skip requirements
|
|
60
|
+
// for stableIds that this change also drops. A change that drops a
|
|
61
|
+
// stableId should not depend on another change that creates the same
|
|
62
|
+
// stableId, because the entity already exists in the source database.
|
|
63
|
+
// This prevents false ordering constraints such as Grant → Revoke
|
|
64
|
+
// when both operate on the same ACL stableId.
|
|
65
|
+
const droppedIds = new Set(phaseChanges[consumerIndex].drops);
|
|
59
66
|
for (const requiredId of requiredIds) {
|
|
67
|
+
if (droppedIds.has(requiredId)) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
60
70
|
const producerIndexes = graphData.changeIndexesByCreatedId.get(requiredId);
|
|
61
71
|
if (!producerIndexes || producerIndexes.size === 0)
|
|
62
72
|
continue;
|
|
@@ -145,6 +145,25 @@ function getMainStableId(change) {
|
|
|
145
145
|
}
|
|
146
146
|
return null;
|
|
147
147
|
}
|
|
148
|
+
// For default_privilege operations: group by role + schema combination (before CREATE so we group and use tiebreaker)
|
|
149
|
+
if (change.scope === "default_privilege") {
|
|
150
|
+
if (change.requires.length > 0) {
|
|
151
|
+
let grantingRole = null;
|
|
152
|
+
let schemaId = null;
|
|
153
|
+
for (const id of change.requires) {
|
|
154
|
+
if (id.startsWith("role:")) {
|
|
155
|
+
grantingRole = id;
|
|
156
|
+
}
|
|
157
|
+
else if (id.startsWith("schema:")) {
|
|
158
|
+
schemaId = id;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (schemaId && grantingRole) {
|
|
162
|
+
return `${grantingRole}:${schemaId}`;
|
|
163
|
+
}
|
|
164
|
+
return grantingRole ?? null;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
148
167
|
// For CREATE operations: check if creating a constraint (sub-entity of table)
|
|
149
168
|
if (change.operation === "create" && change.creates.length > 0) {
|
|
150
169
|
// Iterate through creates to find the first non-metadata stable ID
|
|
@@ -182,29 +201,6 @@ function getMainStableId(change) {
|
|
|
182
201
|
// Fallback: if all drops are metadata, use first
|
|
183
202
|
return change.drops[0] ?? null;
|
|
184
203
|
}
|
|
185
|
-
// For default_privilege operations: group by role + schema combination
|
|
186
|
-
// This groups all "FOR ROLE X IN SCHEMA Y" statements together
|
|
187
|
-
if (change.scope === "default_privilege") {
|
|
188
|
-
if (change.requires.length > 0) {
|
|
189
|
-
// Iterate through requires to find role and schema
|
|
190
|
-
let grantingRole = null;
|
|
191
|
-
let schemaId = null;
|
|
192
|
-
for (const id of change.requires) {
|
|
193
|
-
if (id.startsWith("role:")) {
|
|
194
|
-
grantingRole = id;
|
|
195
|
-
}
|
|
196
|
-
else if (id.startsWith("schema:")) {
|
|
197
|
-
schemaId = id;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
if (schemaId && grantingRole) {
|
|
201
|
-
// Create composite key: "role:postgres:schema:public"
|
|
202
|
-
return `${grantingRole}:${schemaId}`;
|
|
203
|
-
}
|
|
204
|
-
// If no schema, just group by role
|
|
205
|
-
return grantingRole ?? null;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
204
|
// For ALTER operations: check if creating/dropping a constraint
|
|
209
205
|
// Skip this for privilege/comment/default_privilege scopes (handled above)
|
|
210
206
|
if (change.operation === "alter") {
|
|
@@ -525,6 +521,18 @@ function sortPhase(changes, phase) {
|
|
|
525
521
|
if (operationOrderA !== operationOrderB) {
|
|
526
522
|
return operationOrderA - operationOrderB;
|
|
527
523
|
}
|
|
524
|
+
// 6b. For default_privilege: deterministic tiebreaker by objtype then grantee (canonical order for objtype)
|
|
525
|
+
if (scopeA === "default_privilege" && scopeB === "default_privilege") {
|
|
526
|
+
const defPrivA = changeA;
|
|
527
|
+
const defPrivB = changeB;
|
|
528
|
+
const objtypeOrder = (code) => ({ n: 0, r: 1, S: 2, f: 3, T: 4 })[code] ?? 99;
|
|
529
|
+
const objtypeCompare = objtypeOrder(defPrivA.objtype) - objtypeOrder(defPrivB.objtype);
|
|
530
|
+
if (objtypeCompare !== 0)
|
|
531
|
+
return objtypeCompare;
|
|
532
|
+
const granteeCompare = defPrivA.grantee.localeCompare(defPrivB.grantee);
|
|
533
|
+
if (granteeCompare !== 0)
|
|
534
|
+
return granteeCompare;
|
|
535
|
+
}
|
|
528
536
|
// 7. Preserve original order (stability)
|
|
529
537
|
return a.originalIndex - b.originalIndex;
|
|
530
538
|
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Assert that the given SQL string is syntactically valid PostgreSQL.
|
|
3
|
+
*
|
|
4
|
+
* Uses the PostgreSQL parser from `@supabase/pg-topo` to ensure that
|
|
5
|
+
* serialized DDL statements are syntactically correct. This catches
|
|
6
|
+
* issues like malformed function signatures, missing keywords, etc.
|
|
7
|
+
*
|
|
8
|
+
* @param sql - The SQL string to validate (typically from `change.serialize()`).
|
|
9
|
+
*/
|
|
10
|
+
export declare function assertValidSql(sql: string): Promise<void>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { validateSqlSyntax } from "@supabase/pg-topo";
|
|
2
|
+
/**
|
|
3
|
+
* Assert that the given SQL string is syntactically valid PostgreSQL.
|
|
4
|
+
*
|
|
5
|
+
* Uses the PostgreSQL parser from `@supabase/pg-topo` to ensure that
|
|
6
|
+
* serialized DDL statements are syntactically correct. This catches
|
|
7
|
+
* issues like malformed function signatures, missing keywords, etc.
|
|
8
|
+
*
|
|
9
|
+
* @param sql - The SQL string to validate (typically from `change.serialize()`).
|
|
10
|
+
*/
|
|
11
|
+
export async function assertValidSql(sql) {
|
|
12
|
+
try {
|
|
13
|
+
await validateSqlSyntax(sql);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
const message = error instanceof Error ? error.message : "Unknown parser error";
|
|
17
|
+
throw new Error(`Invalid SQL syntax: ${message}\nSQL: ${sql}`);
|
|
18
|
+
}
|
|
19
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,15 @@
|
|
|
3
3
|
*
|
|
4
4
|
* This module exports the public API for the pg-delta library.
|
|
5
5
|
*/
|
|
6
|
+
export { Catalog, createEmptyCatalog, extractCatalog, } from "./core/catalog.model.ts";
|
|
7
|
+
export type { CatalogSnapshot } from "./core/catalog.snapshot.ts";
|
|
8
|
+
export { deserializeCatalog, serializeCatalog, stringifyCatalogSnapshot, } from "./core/catalog.snapshot.ts";
|
|
9
|
+
export { exportDeclarativeSchema } from "./core/export/index.ts";
|
|
10
|
+
export type { DeclarativeSchemaOutput, FileCategory, FileEntry, FileMetadata, } from "./core/export/types.ts";
|
|
6
11
|
export type { IntegrationDSL } from "./core/integrations/integration-dsl.ts";
|
|
7
12
|
export { applyPlan } from "./core/plan/apply.ts";
|
|
13
|
+
export type { CatalogInput } from "./core/plan/create.ts";
|
|
8
14
|
export { createPlan } from "./core/plan/create.ts";
|
|
15
|
+
export type { SqlFormatOptions } from "./core/plan/sql-format.ts";
|
|
16
|
+
export { formatSqlStatements } from "./core/plan/sql-format.ts";
|
|
9
17
|
export type { CreatePlanOptions, Plan } from "./core/plan/types.ts";
|