@dotdo/postgres 0.1.0
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 +868 -0
- package/dist/cdc/change-stream.d.ts +44 -0
- package/dist/cdc/change-stream.d.ts.map +1 -0
- package/dist/cdc/change-stream.js +95 -0
- package/dist/cdc/change-stream.js.map +1 -0
- package/dist/cdc/filter.d.ts +58 -0
- package/dist/cdc/filter.d.ts.map +1 -0
- package/dist/cdc/filter.js +520 -0
- package/dist/cdc/filter.js.map +1 -0
- package/dist/cdc/index.d.ts +47 -0
- package/dist/cdc/index.d.ts.map +1 -0
- package/dist/cdc/index.js +50 -0
- package/dist/cdc/index.js.map +1 -0
- package/dist/cdc/resume-token.d.ts +60 -0
- package/dist/cdc/resume-token.d.ts.map +1 -0
- package/dist/cdc/resume-token.js +228 -0
- package/dist/cdc/resume-token.js.map +1 -0
- package/dist/cdc/transport/index.d.ts +7 -0
- package/dist/cdc/transport/index.d.ts.map +1 -0
- package/dist/cdc/transport/index.js +7 -0
- package/dist/cdc/transport/index.js.map +1 -0
- package/dist/cdc/transport/sse.d.ts +120 -0
- package/dist/cdc/transport/sse.d.ts.map +1 -0
- package/dist/cdc/transport/sse.js +590 -0
- package/dist/cdc/transport/sse.js.map +1 -0
- package/dist/cdc/transport/websocket.d.ts +130 -0
- package/dist/cdc/transport/websocket.d.ts.map +1 -0
- package/dist/cdc/transport/websocket.js +688 -0
- package/dist/cdc/transport/websocket.js.map +1 -0
- package/dist/cdc/types.d.ts +306 -0
- package/dist/cdc/types.d.ts.map +1 -0
- package/dist/cdc/types.js +8 -0
- package/dist/cdc/types.js.map +1 -0
- package/dist/config/index.d.ts +25 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +25 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/memory.d.ts +139 -0
- package/dist/config/memory.d.ts.map +1 -0
- package/dist/config/memory.js +157 -0
- package/dist/config/memory.js.map +1 -0
- package/dist/config/storage.d.ts +157 -0
- package/dist/config/storage.d.ts.map +1 -0
- package/dist/config/storage.js +178 -0
- package/dist/config/storage.js.map +1 -0
- package/dist/config/streaming.d.ts +117 -0
- package/dist/config/streaming.d.ts.map +1 -0
- package/dist/config/streaming.js +132 -0
- package/dist/config/streaming.js.map +1 -0
- package/dist/config/timeouts.d.ts +168 -0
- package/dist/config/timeouts.d.ts.map +1 -0
- package/dist/config/timeouts.js +192 -0
- package/dist/config/timeouts.js.map +1 -0
- package/dist/extensions/config.d.ts +89 -0
- package/dist/extensions/config.d.ts.map +1 -0
- package/dist/extensions/config.js +216 -0
- package/dist/extensions/config.js.map +1 -0
- package/dist/extensions/geo.d.ts +452 -0
- package/dist/extensions/geo.d.ts.map +1 -0
- package/dist/extensions/geo.js +583 -0
- package/dist/extensions/geo.js.map +1 -0
- package/dist/extensions/index.d.ts +167 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +99 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/extensions/loader.d.ts +226 -0
- package/dist/extensions/loader.d.ts.map +1 -0
- package/dist/extensions/loader.js +456 -0
- package/dist/extensions/loader.js.map +1 -0
- package/dist/extensions/pgmq-lite.d.ts +330 -0
- package/dist/extensions/pgmq-lite.d.ts.map +1 -0
- package/dist/extensions/pgmq-lite.js +648 -0
- package/dist/extensions/pgmq-lite.js.map +1 -0
- package/dist/extensions/plugins.d.ts +260 -0
- package/dist/extensions/plugins.d.ts.map +1 -0
- package/dist/extensions/plugins.js +535 -0
- package/dist/extensions/plugins.js.map +1 -0
- package/dist/extensions/registry.d.ts +93 -0
- package/dist/extensions/registry.d.ts.map +1 -0
- package/dist/extensions/registry.js +182 -0
- package/dist/extensions/registry.js.map +1 -0
- package/dist/extensions/vector.d.ts +106 -0
- package/dist/extensions/vector.d.ts.map +1 -0
- package/dist/extensions/vector.js +129 -0
- package/dist/extensions/vector.js.map +1 -0
- package/dist/iceberg/analytics.d.ts +279 -0
- package/dist/iceberg/analytics.d.ts.map +1 -0
- package/dist/iceberg/analytics.js +448 -0
- package/dist/iceberg/analytics.js.map +1 -0
- package/dist/iceberg/catalog-api.d.ts +39 -0
- package/dist/iceberg/catalog-api.d.ts.map +1 -0
- package/dist/iceberg/catalog-api.js +388 -0
- package/dist/iceberg/catalog-api.js.map +1 -0
- package/dist/iceberg/catalog.d.ts +401 -0
- package/dist/iceberg/catalog.d.ts.map +1 -0
- package/dist/iceberg/catalog.js +677 -0
- package/dist/iceberg/catalog.js.map +1 -0
- package/dist/iceberg/duckdb-wasm.d.ts +447 -0
- package/dist/iceberg/duckdb-wasm.d.ts.map +1 -0
- package/dist/iceberg/duckdb-wasm.js +600 -0
- package/dist/iceberg/duckdb-wasm.js.map +1 -0
- package/dist/iceberg/index.d.ts +92 -0
- package/dist/iceberg/index.d.ts.map +1 -0
- package/dist/iceberg/index.js +119 -0
- package/dist/iceberg/index.js.map +1 -0
- package/dist/iceberg/metadata.d.ts +214 -0
- package/dist/iceberg/metadata.d.ts.map +1 -0
- package/dist/iceberg/metadata.js +535 -0
- package/dist/iceberg/metadata.js.map +1 -0
- package/dist/iceberg/optimizer.d.ts +296 -0
- package/dist/iceberg/optimizer.d.ts.map +1 -0
- package/dist/iceberg/optimizer.js +889 -0
- package/dist/iceberg/optimizer.js.map +1 -0
- package/dist/iceberg/parquet.d.ts +447 -0
- package/dist/iceberg/parquet.d.ts.map +1 -0
- package/dist/iceberg/parquet.js +1225 -0
- package/dist/iceberg/parquet.js.map +1 -0
- package/dist/iceberg/r2-organization.d.ts +422 -0
- package/dist/iceberg/r2-organization.d.ts.map +1 -0
- package/dist/iceberg/r2-organization.js +672 -0
- package/dist/iceberg/r2-organization.js.map +1 -0
- package/dist/iceberg/scheduler-do-example.d.ts +158 -0
- package/dist/iceberg/scheduler-do-example.d.ts.map +1 -0
- package/dist/iceberg/scheduler-do-example.js +261 -0
- package/dist/iceberg/scheduler-do-example.js.map +1 -0
- package/dist/iceberg/scheduler.d.ts +434 -0
- package/dist/iceberg/scheduler.d.ts.map +1 -0
- package/dist/iceberg/scheduler.js +818 -0
- package/dist/iceberg/scheduler.js.map +1 -0
- package/dist/iceberg/schema.d.ts +149 -0
- package/dist/iceberg/schema.d.ts.map +1 -0
- package/dist/iceberg/schema.js +525 -0
- package/dist/iceberg/schema.js.map +1 -0
- package/dist/iceberg/snapshot-manager.d.ts +406 -0
- package/dist/iceberg/snapshot-manager.d.ts.map +1 -0
- package/dist/iceberg/snapshot-manager.js +934 -0
- package/dist/iceberg/snapshot-manager.js.map +1 -0
- package/dist/iceberg/sql-router.d.ts +194 -0
- package/dist/iceberg/sql-router.d.ts.map +1 -0
- package/dist/iceberg/sql-router.js +180 -0
- package/dist/iceberg/sql-router.js.map +1 -0
- package/dist/iceberg/test-fixtures.d.ts +151 -0
- package/dist/iceberg/test-fixtures.d.ts.map +1 -0
- package/dist/iceberg/test-fixtures.js +446 -0
- package/dist/iceberg/test-fixtures.js.map +1 -0
- package/dist/iceberg/time-travel-api.d.ts +102 -0
- package/dist/iceberg/time-travel-api.d.ts.map +1 -0
- package/dist/iceberg/time-travel-api.js +437 -0
- package/dist/iceberg/time-travel-api.js.map +1 -0
- package/dist/iceberg/time-travel.d.ts +293 -0
- package/dist/iceberg/time-travel.d.ts.map +1 -0
- package/dist/iceberg/time-travel.js +689 -0
- package/dist/iceberg/time-travel.js.map +1 -0
- package/dist/iceberg/transformer.d.ts +356 -0
- package/dist/iceberg/transformer.d.ts.map +1 -0
- package/dist/iceberg/transformer.js +770 -0
- package/dist/iceberg/transformer.js.map +1 -0
- package/dist/iceberg/types.d.ts +318 -0
- package/dist/iceberg/types.d.ts.map +1 -0
- package/dist/iceberg/types.js +9 -0
- package/dist/iceberg/types.js.map +1 -0
- package/dist/iceberg/writer.d.ts +144 -0
- package/dist/iceberg/writer.d.ts.map +1 -0
- package/dist/iceberg/writer.js +452 -0
- package/dist/iceberg/writer.js.map +1 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -0
- package/dist/lineage/index.d.ts +11 -0
- package/dist/lineage/index.d.ts.map +1 -0
- package/dist/lineage/index.js +11 -0
- package/dist/lineage/index.js.map +1 -0
- package/dist/lineage/integration.d.ts +134 -0
- package/dist/lineage/integration.d.ts.map +1 -0
- package/dist/lineage/integration.js +258 -0
- package/dist/lineage/integration.js.map +1 -0
- package/dist/lineage/tracker.d.ts +189 -0
- package/dist/lineage/tracker.d.ts.map +1 -0
- package/dist/lineage/tracker.js +1352 -0
- package/dist/lineage/tracker.js.map +1 -0
- package/dist/lineage/types.d.ts +318 -0
- package/dist/lineage/types.d.ts.map +1 -0
- package/dist/lineage/types.js +9 -0
- package/dist/lineage/types.js.map +1 -0
- package/dist/middleware/index.d.ts +11 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +16 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/middleware/rate-limit.d.ts +397 -0
- package/dist/middleware/rate-limit.d.ts.map +1 -0
- package/dist/middleware/rate-limit.js +507 -0
- package/dist/middleware/rate-limit.js.map +1 -0
- package/dist/migration-tooling/external-migration.d.ts +601 -0
- package/dist/migration-tooling/external-migration.d.ts.map +1 -0
- package/dist/migration-tooling/external-migration.js +1612 -0
- package/dist/migration-tooling/external-migration.js.map +1 -0
- package/dist/migration-tooling/index.d.ts +19 -0
- package/dist/migration-tooling/index.d.ts.map +1 -0
- package/dist/migration-tooling/index.js +19 -0
- package/dist/migration-tooling/index.js.map +1 -0
- package/dist/migrations/auto-migrator.d.ts +289 -0
- package/dist/migrations/auto-migrator.d.ts.map +1 -0
- package/dist/migrations/auto-migrator.js +396 -0
- package/dist/migrations/auto-migrator.js.map +1 -0
- package/dist/migrations/bulk-orchestrator.d.ts +403 -0
- package/dist/migrations/bulk-orchestrator.d.ts.map +1 -0
- package/dist/migrations/bulk-orchestrator.js +646 -0
- package/dist/migrations/bulk-orchestrator.js.map +1 -0
- package/dist/migrations/compatibility.d.ts +216 -0
- package/dist/migrations/compatibility.d.ts.map +1 -0
- package/dist/migrations/compatibility.js +651 -0
- package/dist/migrations/compatibility.js.map +1 -0
- package/dist/migrations/do-migrations.d.ts +101 -0
- package/dist/migrations/do-migrations.d.ts.map +1 -0
- package/dist/migrations/do-migrations.js +1060 -0
- package/dist/migrations/do-migrations.js.map +1 -0
- package/dist/migrations/do-migrations.types.d.ts +550 -0
- package/dist/migrations/do-migrations.types.d.ts.map +1 -0
- package/dist/migrations/do-migrations.types.js +15 -0
- package/dist/migrations/do-migrations.types.js.map +1 -0
- package/dist/migrations/drizzle-compat.d.ts +163 -0
- package/dist/migrations/drizzle-compat.d.ts.map +1 -0
- package/dist/migrations/drizzle-compat.js +273 -0
- package/dist/migrations/drizzle-compat.js.map +1 -0
- package/dist/migrations/index.d.ts +109 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +127 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/migrations/migration-api.d.ts +161 -0
- package/dist/migrations/migration-api.d.ts.map +1 -0
- package/dist/migrations/migration-api.js +499 -0
- package/dist/migrations/migration-api.js.map +1 -0
- package/dist/migrations/progress-tracker-do.d.ts +195 -0
- package/dist/migrations/progress-tracker-do.d.ts.map +1 -0
- package/dist/migrations/progress-tracker-do.js +339 -0
- package/dist/migrations/progress-tracker-do.js.map +1 -0
- package/dist/migrations/progress-tracker-kv.d.ts +103 -0
- package/dist/migrations/progress-tracker-kv.d.ts.map +1 -0
- package/dist/migrations/progress-tracker-kv.js +231 -0
- package/dist/migrations/progress-tracker-kv.js.map +1 -0
- package/dist/migrations/progress-tracker.d.ts +320 -0
- package/dist/migrations/progress-tracker.d.ts.map +1 -0
- package/dist/migrations/progress-tracker.js +443 -0
- package/dist/migrations/progress-tracker.js.map +1 -0
- package/dist/migrations/registry.d.ts +231 -0
- package/dist/migrations/registry.d.ts.map +1 -0
- package/dist/migrations/registry.js +376 -0
- package/dist/migrations/registry.js.map +1 -0
- package/dist/migrations/runner.d.ts +197 -0
- package/dist/migrations/runner.d.ts.map +1 -0
- package/dist/migrations/runner.js +1167 -0
- package/dist/migrations/runner.js.map +1 -0
- package/dist/migrations/schema-generator.d.ts +111 -0
- package/dist/migrations/schema-generator.d.ts.map +1 -0
- package/dist/migrations/schema-generator.js +335 -0
- package/dist/migrations/schema-generator.js.map +1 -0
- package/dist/migrations/testing.d.ts +321 -0
- package/dist/migrations/testing.d.ts.map +1 -0
- package/dist/migrations/testing.js +645 -0
- package/dist/migrations/testing.js.map +1 -0
- package/dist/migrations/types.d.ts +503 -0
- package/dist/migrations/types.d.ts.map +1 -0
- package/dist/migrations/types.js +11 -0
- package/dist/migrations/types.js.map +1 -0
- package/dist/migrations/validator.d.ts +215 -0
- package/dist/migrations/validator.d.ts.map +1 -0
- package/dist/migrations/validator.js +494 -0
- package/dist/migrations/validator.js.map +1 -0
- package/dist/observability/alerting.d.ts +116 -0
- package/dist/observability/alerting.d.ts.map +1 -0
- package/dist/observability/alerting.js +353 -0
- package/dist/observability/alerting.js.map +1 -0
- package/dist/observability/analytics-engine.d.ts +357 -0
- package/dist/observability/analytics-engine.d.ts.map +1 -0
- package/dist/observability/analytics-engine.js +430 -0
- package/dist/observability/analytics-engine.js.map +1 -0
- package/dist/observability/cost-metrics.d.ts +269 -0
- package/dist/observability/cost-metrics.d.ts.map +1 -0
- package/dist/observability/cost-metrics.js +560 -0
- package/dist/observability/cost-metrics.js.map +1 -0
- package/dist/observability/cross-do-tracing.d.ts +305 -0
- package/dist/observability/cross-do-tracing.d.ts.map +1 -0
- package/dist/observability/cross-do-tracing.js +431 -0
- package/dist/observability/cross-do-tracing.js.map +1 -0
- package/dist/observability/error-rate-collector.d.ts +163 -0
- package/dist/observability/error-rate-collector.d.ts.map +1 -0
- package/dist/observability/error-rate-collector.js +306 -0
- package/dist/observability/error-rate-collector.js.map +1 -0
- package/dist/observability/exporters.d.ts +231 -0
- package/dist/observability/exporters.d.ts.map +1 -0
- package/dist/observability/exporters.js +479 -0
- package/dist/observability/exporters.js.map +1 -0
- package/dist/observability/health-check.d.ts +106 -0
- package/dist/observability/health-check.d.ts.map +1 -0
- package/dist/observability/health-check.js +243 -0
- package/dist/observability/health-check.js.map +1 -0
- package/dist/observability/index.d.ts +297 -0
- package/dist/observability/index.d.ts.map +1 -0
- package/dist/observability/index.js +455 -0
- package/dist/observability/index.js.map +1 -0
- package/dist/observability/instrumentation.d.ts +222 -0
- package/dist/observability/instrumentation.d.ts.map +1 -0
- package/dist/observability/instrumentation.js +532 -0
- package/dist/observability/instrumentation.js.map +1 -0
- package/dist/observability/memory-metrics.d.ts +227 -0
- package/dist/observability/memory-metrics.d.ts.map +1 -0
- package/dist/observability/memory-metrics.js +688 -0
- package/dist/observability/memory-metrics.js.map +1 -0
- package/dist/observability/metrics-endpoint.d.ts +91 -0
- package/dist/observability/metrics-endpoint.d.ts.map +1 -0
- package/dist/observability/metrics-endpoint.js +246 -0
- package/dist/observability/metrics-endpoint.js.map +1 -0
- package/dist/observability/metrics.d.ts +88 -0
- package/dist/observability/metrics.d.ts.map +1 -0
- package/dist/observability/metrics.js +253 -0
- package/dist/observability/metrics.js.map +1 -0
- package/dist/observability/observability-features.d.ts +488 -0
- package/dist/observability/observability-features.d.ts.map +1 -0
- package/dist/observability/observability-features.js +773 -0
- package/dist/observability/observability-features.js.map +1 -0
- package/dist/observability/prometheus.d.ts +39 -0
- package/dist/observability/prometheus.d.ts.map +1 -0
- package/dist/observability/prometheus.js +120 -0
- package/dist/observability/prometheus.js.map +1 -0
- package/dist/observability/propagation.d.ts +126 -0
- package/dist/observability/propagation.d.ts.map +1 -0
- package/dist/observability/propagation.js +234 -0
- package/dist/observability/propagation.js.map +1 -0
- package/dist/observability/query-latency.d.ts +243 -0
- package/dist/observability/query-latency.d.ts.map +1 -0
- package/dist/observability/query-latency.js +292 -0
- package/dist/observability/query-latency.js.map +1 -0
- package/dist/observability/query-performance.d.ts +169 -0
- package/dist/observability/query-performance.d.ts.map +1 -0
- package/dist/observability/query-performance.js +290 -0
- package/dist/observability/query-performance.js.map +1 -0
- package/dist/observability/storage-tier-metrics.d.ts +174 -0
- package/dist/observability/storage-tier-metrics.d.ts.map +1 -0
- package/dist/observability/storage-tier-metrics.js +306 -0
- package/dist/observability/storage-tier-metrics.js.map +1 -0
- package/dist/observability/tier-cost-optimizer.d.ts +155 -0
- package/dist/observability/tier-cost-optimizer.d.ts.map +1 -0
- package/dist/observability/tier-cost-optimizer.js +536 -0
- package/dist/observability/tier-cost-optimizer.js.map +1 -0
- package/dist/observability/tracer.d.ts +149 -0
- package/dist/observability/tracer.d.ts.map +1 -0
- package/dist/observability/tracer.js +435 -0
- package/dist/observability/tracer.js.map +1 -0
- package/dist/observability/types.d.ts +402 -0
- package/dist/observability/types.d.ts.map +1 -0
- package/dist/observability/types.js +103 -0
- package/dist/observability/types.js.map +1 -0
- package/dist/pglite/workers-pglite.d.ts +138 -0
- package/dist/pglite/workers-pglite.d.ts.map +1 -0
- package/dist/pglite/workers-pglite.js +143 -0
- package/dist/pglite/workers-pglite.js.map +1 -0
- package/dist/pglite-assets/pglite.data +0 -0
- package/dist/pglite-assets/pglite.wasm +0 -0
- package/dist/playground/index.d.ts +52 -0
- package/dist/playground/index.d.ts.map +1 -0
- package/dist/playground/index.js +55 -0
- package/dist/playground/index.js.map +1 -0
- package/dist/playground/keyboard-shortcuts.d.ts +116 -0
- package/dist/playground/keyboard-shortcuts.d.ts.map +1 -0
- package/dist/playground/keyboard-shortcuts.js +588 -0
- package/dist/playground/keyboard-shortcuts.js.map +1 -0
- package/dist/playground/playground.d.ts +82 -0
- package/dist/playground/playground.d.ts.map +1 -0
- package/dist/playground/playground.js +271 -0
- package/dist/playground/playground.js.map +1 -0
- package/dist/playground/query-executor.d.ts +115 -0
- package/dist/playground/query-executor.d.ts.map +1 -0
- package/dist/playground/query-executor.js +558 -0
- package/dist/playground/query-executor.js.map +1 -0
- package/dist/playground/query-history.d.ts +92 -0
- package/dist/playground/query-history.d.ts.map +1 -0
- package/dist/playground/query-history.js +259 -0
- package/dist/playground/query-history.js.map +1 -0
- package/dist/playground/result-formatter.d.ts +59 -0
- package/dist/playground/result-formatter.d.ts.map +1 -0
- package/dist/playground/result-formatter.js +341 -0
- package/dist/playground/result-formatter.js.map +1 -0
- package/dist/playground/sample-datasets.d.ts +77 -0
- package/dist/playground/sample-datasets.d.ts.map +1 -0
- package/dist/playground/sample-datasets.js +641 -0
- package/dist/playground/sample-datasets.js.map +1 -0
- package/dist/playground/sample-queries.d.ts +73 -0
- package/dist/playground/sample-queries.d.ts.map +1 -0
- package/dist/playground/sample-queries.js +1095 -0
- package/dist/playground/sample-queries.js.map +1 -0
- package/dist/playground/schema-explorer.d.ts +55 -0
- package/dist/playground/schema-explorer.d.ts.map +1 -0
- package/dist/playground/schema-explorer.js +473 -0
- package/dist/playground/schema-explorer.js.map +1 -0
- package/dist/playground/types.d.ts +430 -0
- package/dist/playground/types.d.ts.map +1 -0
- package/dist/playground/types.js +10 -0
- package/dist/playground/types.js.map +1 -0
- package/dist/readonly/cache-reader.d.ts +145 -0
- package/dist/readonly/cache-reader.d.ts.map +1 -0
- package/dist/readonly/cache-reader.js +198 -0
- package/dist/readonly/cache-reader.js.map +1 -0
- package/dist/readonly/config.d.ts +74 -0
- package/dist/readonly/config.d.ts.map +1 -0
- package/dist/readonly/config.js +67 -0
- package/dist/readonly/config.js.map +1 -0
- package/dist/readonly/index.d.ts +22 -0
- package/dist/readonly/index.d.ts.map +1 -0
- package/dist/readonly/index.js +17 -0
- package/dist/readonly/index.js.map +1 -0
- package/dist/readonly/pglite-wrapper.d.ts +82 -0
- package/dist/readonly/pglite-wrapper.d.ts.map +1 -0
- package/dist/readonly/pglite-wrapper.js +123 -0
- package/dist/readonly/pglite-wrapper.js.map +1 -0
- package/dist/readonly/worker.d.ts +142 -0
- package/dist/readonly/worker.d.ts.map +1 -0
- package/dist/readonly/worker.js +187 -0
- package/dist/readonly/worker.js.map +1 -0
- package/dist/readonly/write-blocker.d.ts +47 -0
- package/dist/readonly/write-blocker.d.ts.map +1 -0
- package/dist/readonly/write-blocker.js +136 -0
- package/dist/readonly/write-blocker.js.map +1 -0
- package/dist/recovery/disaster-recovery.d.ts +326 -0
- package/dist/recovery/disaster-recovery.d.ts.map +1 -0
- package/dist/recovery/disaster-recovery.js +799 -0
- package/dist/recovery/disaster-recovery.js.map +1 -0
- package/dist/recovery/index.d.ts +12 -0
- package/dist/recovery/index.d.ts.map +1 -0
- package/dist/recovery/index.js +12 -0
- package/dist/recovery/index.js.map +1 -0
- package/dist/recovery/parquet-parser.d.ts +321 -0
- package/dist/recovery/parquet-parser.d.ts.map +1 -0
- package/dist/recovery/parquet-parser.js +797 -0
- package/dist/recovery/parquet-parser.js.map +1 -0
- package/dist/retention/index.d.ts +50 -0
- package/dist/retention/index.d.ts.map +1 -0
- package/dist/retention/index.js +50 -0
- package/dist/retention/index.js.map +1 -0
- package/dist/retention/policy.d.ts +344 -0
- package/dist/retention/policy.d.ts.map +1 -0
- package/dist/retention/policy.js +472 -0
- package/dist/retention/policy.js.map +1 -0
- package/dist/retention/purger.d.ts +187 -0
- package/dist/retention/purger.d.ts.map +1 -0
- package/dist/retention/purger.js +411 -0
- package/dist/retention/purger.js.map +1 -0
- package/dist/rls/auth-integration.d.ts +280 -0
- package/dist/rls/auth-integration.d.ts.map +1 -0
- package/dist/rls/auth-integration.js +399 -0
- package/dist/rls/auth-integration.js.map +1 -0
- package/dist/rls/generator.d.ts +249 -0
- package/dist/rls/generator.d.ts.map +1 -0
- package/dist/rls/generator.js +495 -0
- package/dist/rls/generator.js.map +1 -0
- package/dist/rls/index.d.ts +26 -0
- package/dist/rls/index.d.ts.map +1 -0
- package/dist/rls/index.js +58 -0
- package/dist/rls/index.js.map +1 -0
- package/dist/rls/policy.d.ts +116 -0
- package/dist/rls/policy.d.ts.map +1 -0
- package/dist/rls/policy.js +77 -0
- package/dist/rls/policy.js.map +1 -0
- package/dist/rls/validator.d.ts +155 -0
- package/dist/rls/validator.d.ts.map +1 -0
- package/dist/rls/validator.js +792 -0
- package/dist/rls/validator.js.map +1 -0
- package/dist/routing/adaptive-router.d.ts +317 -0
- package/dist/routing/adaptive-router.d.ts.map +1 -0
- package/dist/routing/adaptive-router.js +554 -0
- package/dist/routing/adaptive-router.js.map +1 -0
- package/dist/routing/circuit-breaker.d.ts +339 -0
- package/dist/routing/circuit-breaker.d.ts.map +1 -0
- package/dist/routing/circuit-breaker.js +620 -0
- package/dist/routing/circuit-breaker.js.map +1 -0
- package/dist/routing/cost-metrics.d.ts +133 -0
- package/dist/routing/cost-metrics.d.ts.map +1 -0
- package/dist/routing/cost-metrics.js +259 -0
- package/dist/routing/cost-metrics.js.map +1 -0
- package/dist/routing/do-connection-pool.d.ts +243 -0
- package/dist/routing/do-connection-pool.d.ts.map +1 -0
- package/dist/routing/do-connection-pool.js +572 -0
- package/dist/routing/do-connection-pool.js.map +1 -0
- package/dist/routing/index.d.ts +59 -0
- package/dist/routing/index.d.ts.map +1 -0
- package/dist/routing/index.js +59 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/routing/query-complexity-estimator.d.ts +73 -0
- package/dist/routing/query-complexity-estimator.d.ts.map +1 -0
- package/dist/routing/query-complexity-estimator.js +327 -0
- package/dist/routing/query-complexity-estimator.js.map +1 -0
- package/dist/routing/request-coalescing.d.ts +178 -0
- package/dist/routing/request-coalescing.d.ts.map +1 -0
- package/dist/routing/request-coalescing.js +325 -0
- package/dist/routing/request-coalescing.js.map +1 -0
- package/dist/routing/runtime-router.d.ts +107 -0
- package/dist/routing/runtime-router.d.ts.map +1 -0
- package/dist/routing/runtime-router.js +246 -0
- package/dist/routing/runtime-router.js.map +1 -0
- package/dist/routing/tenant-router.d.ts +848 -0
- package/dist/routing/tenant-router.d.ts.map +1 -0
- package/dist/routing/tenant-router.js +1056 -0
- package/dist/routing/tenant-router.js.map +1 -0
- package/dist/routing/websocket-pool.d.ts +119 -0
- package/dist/routing/websocket-pool.d.ts.map +1 -0
- package/dist/routing/websocket-pool.js +436 -0
- package/dist/routing/websocket-pool.js.map +1 -0
- package/dist/storage/cache-layer.d.ts +159 -0
- package/dist/storage/cache-layer.d.ts.map +1 -0
- package/dist/storage/cache-layer.js +245 -0
- package/dist/storage/cache-layer.js.map +1 -0
- package/dist/storage/cost-aware-tiering.d.ts +258 -0
- package/dist/storage/cost-aware-tiering.d.ts.map +1 -0
- package/dist/storage/cost-aware-tiering.js +526 -0
- package/dist/storage/cost-aware-tiering.js.map +1 -0
- package/dist/storage/index.d.ts +87 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +78 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/interfaces.d.ts +856 -0
- package/dist/storage/interfaces.d.ts.map +1 -0
- package/dist/storage/interfaces.js +69 -0
- package/dist/storage/interfaces.js.map +1 -0
- package/dist/storage/r2-layer.d.ts +226 -0
- package/dist/storage/r2-layer.d.ts.map +1 -0
- package/dist/storage/r2-layer.js +307 -0
- package/dist/storage/r2-layer.js.map +1 -0
- package/dist/storage/r2-overflow.d.ts +344 -0
- package/dist/storage/r2-overflow.d.ts.map +1 -0
- package/dist/storage/r2-overflow.js +730 -0
- package/dist/storage/r2-overflow.js.map +1 -0
- package/dist/storage/r2-page-vfs.d.ts +374 -0
- package/dist/storage/r2-page-vfs.d.ts.map +1 -0
- package/dist/storage/r2-page-vfs.js +754 -0
- package/dist/storage/r2-page-vfs.js.map +1 -0
- package/dist/storage/swr-cache.d.ts +181 -0
- package/dist/storage/swr-cache.d.ts.map +1 -0
- package/dist/storage/swr-cache.js +295 -0
- package/dist/storage/swr-cache.js.map +1 -0
- package/dist/storage/tiered-orchestrator.d.ts +951 -0
- package/dist/storage/tiered-orchestrator.d.ts.map +1 -0
- package/dist/storage/tiered-orchestrator.js +1731 -0
- package/dist/storage/tiered-orchestrator.js.map +1 -0
- package/dist/storage/tiered-vfs-swr.d.ts +279 -0
- package/dist/storage/tiered-vfs-swr.d.ts.map +1 -0
- package/dist/storage/tiered-vfs-swr.js +584 -0
- package/dist/storage/tiered-vfs-swr.js.map +1 -0
- package/dist/storage/tiered-vfs.d.ts +405 -0
- package/dist/storage/tiered-vfs.d.ts.map +1 -0
- package/dist/storage/tiered-vfs.js +833 -0
- package/dist/storage/tiered-vfs.js.map +1 -0
- package/dist/streaming/backpressure-controller.d.ts +173 -0
- package/dist/streaming/backpressure-controller.d.ts.map +1 -0
- package/dist/streaming/backpressure-controller.js +344 -0
- package/dist/streaming/backpressure-controller.js.map +1 -0
- package/dist/streaming/buffer-pool.d.ts +241 -0
- package/dist/streaming/buffer-pool.d.ts.map +1 -0
- package/dist/streaming/buffer-pool.js +381 -0
- package/dist/streaming/buffer-pool.js.map +1 -0
- package/dist/streaming/cdc-iceberg-connector.d.ts +272 -0
- package/dist/streaming/cdc-iceberg-connector.d.ts.map +1 -0
- package/dist/streaming/cdc-iceberg-connector.js +408 -0
- package/dist/streaming/cdc-iceberg-connector.js.map +1 -0
- package/dist/streaming/index.d.ts +111 -0
- package/dist/streaming/index.d.ts.map +1 -0
- package/dist/streaming/index.js +128 -0
- package/dist/streaming/index.js.map +1 -0
- package/dist/streaming/live-cdc-stream.d.ts +400 -0
- package/dist/streaming/live-cdc-stream.d.ts.map +1 -0
- package/dist/streaming/live-cdc-stream.js +703 -0
- package/dist/streaming/live-cdc-stream.js.map +1 -0
- package/dist/streaming/memory-bounded-stream.d.ts +207 -0
- package/dist/streaming/memory-bounded-stream.d.ts.map +1 -0
- package/dist/streaming/memory-bounded-stream.js +340 -0
- package/dist/streaming/memory-bounded-stream.js.map +1 -0
- package/dist/streaming/query-streamer.d.ts +379 -0
- package/dist/streaming/query-streamer.d.ts.map +1 -0
- package/dist/streaming/query-streamer.js +495 -0
- package/dist/streaming/query-streamer.js.map +1 -0
- package/dist/streaming/response-streaming.d.ts +203 -0
- package/dist/streaming/response-streaming.d.ts.map +1 -0
- package/dist/streaming/response-streaming.js +449 -0
- package/dist/streaming/response-streaming.js.map +1 -0
- package/dist/types/branded.d.ts +859 -0
- package/dist/types/branded.d.ts.map +1 -0
- package/dist/types/branded.js +891 -0
- package/dist/types/branded.js.map +1 -0
- package/dist/types/utilities.d.ts +757 -0
- package/dist/types/utilities.d.ts.map +1 -0
- package/dist/types/utilities.js +447 -0
- package/dist/types/utilities.js.map +1 -0
- package/dist/wal/replay-engine.d.ts +344 -0
- package/dist/wal/replay-engine.d.ts.map +1 -0
- package/dist/wal/replay-engine.js +975 -0
- package/dist/wal/replay-engine.js.map +1 -0
- package/dist/worker/__mocks__/capnweb.d.ts +13 -0
- package/dist/worker/__mocks__/capnweb.d.ts.map +1 -0
- package/dist/worker/__mocks__/capnweb.js +15 -0
- package/dist/worker/__mocks__/capnweb.js.map +1 -0
- package/dist/worker/__mocks__/cloudflare-workers.d.ts +31 -0
- package/dist/worker/__mocks__/cloudflare-workers.d.ts.map +1 -0
- package/dist/worker/__mocks__/cloudflare-workers.js +33 -0
- package/dist/worker/__mocks__/cloudflare-workers.js.map +1 -0
- package/dist/worker/__mocks__/pglite.data.d.ts +3 -0
- package/dist/worker/__mocks__/pglite.data.d.ts.map +1 -0
- package/dist/worker/__mocks__/pglite.data.js +20 -0
- package/dist/worker/__mocks__/pglite.data.js.map +1 -0
- package/dist/worker/__mocks__/pglite.wasm.d.ts +3 -0
- package/dist/worker/__mocks__/pglite.wasm.d.ts.map +1 -0
- package/dist/worker/__mocks__/pglite.wasm.js +30 -0
- package/dist/worker/__mocks__/pglite.wasm.js.map +1 -0
- package/dist/worker/auth-rate-limiter.d.ts +270 -0
- package/dist/worker/auth-rate-limiter.d.ts.map +1 -0
- package/dist/worker/auth-rate-limiter.js +332 -0
- package/dist/worker/auth-rate-limiter.js.map +1 -0
- package/dist/worker/auth.d.ts +345 -0
- package/dist/worker/auth.d.ts.map +1 -0
- package/dist/worker/auth.js +837 -0
- package/dist/worker/auth.js.map +1 -0
- package/dist/worker/cdc-backpressure.d.ts +338 -0
- package/dist/worker/cdc-backpressure.d.ts.map +1 -0
- package/dist/worker/cdc-backpressure.js +619 -0
- package/dist/worker/cdc-backpressure.js.map +1 -0
- package/dist/worker/cdc-sse.d.ts +277 -0
- package/dist/worker/cdc-sse.d.ts.map +1 -0
- package/dist/worker/cdc-sse.js +528 -0
- package/dist/worker/cdc-sse.js.map +1 -0
- package/dist/worker/cdc-websocket.d.ts +252 -0
- package/dist/worker/cdc-websocket.d.ts.map +1 -0
- package/dist/worker/cdc-websocket.js +940 -0
- package/dist/worker/cdc-websocket.js.map +1 -0
- package/dist/worker/cdc.d.ts +95 -0
- package/dist/worker/cdc.d.ts.map +1 -0
- package/dist/worker/cdc.js +211 -0
- package/dist/worker/cdc.js.map +1 -0
- package/dist/worker/concerns/auth-concern.d.ts +50 -0
- package/dist/worker/concerns/auth-concern.d.ts.map +1 -0
- package/dist/worker/concerns/auth-concern.js +131 -0
- package/dist/worker/concerns/auth-concern.js.map +1 -0
- package/dist/worker/concerns/cdc-concern.d.ts +99 -0
- package/dist/worker/concerns/cdc-concern.d.ts.map +1 -0
- package/dist/worker/concerns/cdc-concern.js +137 -0
- package/dist/worker/concerns/cdc-concern.js.map +1 -0
- package/dist/worker/concerns/index.d.ts +22 -0
- package/dist/worker/concerns/index.d.ts.map +1 -0
- package/dist/worker/concerns/index.js +13 -0
- package/dist/worker/concerns/index.js.map +1 -0
- package/dist/worker/concerns/query-execution-concern.d.ts +104 -0
- package/dist/worker/concerns/query-execution-concern.d.ts.map +1 -0
- package/dist/worker/concerns/query-execution-concern.js +95 -0
- package/dist/worker/concerns/query-execution-concern.js.map +1 -0
- package/dist/worker/concerns/storage-orchestration-concern.d.ts +78 -0
- package/dist/worker/concerns/storage-orchestration-concern.d.ts.map +1 -0
- package/dist/worker/concerns/storage-orchestration-concern.js +240 -0
- package/dist/worker/concerns/storage-orchestration-concern.js.map +1 -0
- package/dist/worker/do-auth-manager.d.ts +108 -0
- package/dist/worker/do-auth-manager.d.ts.map +1 -0
- package/dist/worker/do-auth-manager.js +212 -0
- package/dist/worker/do-auth-manager.js.map +1 -0
- package/dist/worker/do-pglite-manager.d.ts +137 -0
- package/dist/worker/do-pglite-manager.d.ts.map +1 -0
- package/dist/worker/do-pglite-manager.js +228 -0
- package/dist/worker/do-pglite-manager.js.map +1 -0
- package/dist/worker/do.d.ts +556 -0
- package/dist/worker/do.d.ts.map +1 -0
- package/dist/worker/do.js +1441 -0
- package/dist/worker/do.js.map +1 -0
- package/dist/worker/entry.d.ts +23 -0
- package/dist/worker/entry.d.ts.map +1 -0
- package/dist/worker/entry.js +362 -0
- package/dist/worker/entry.js.map +1 -0
- package/dist/worker/errors.d.ts +106 -0
- package/dist/worker/errors.d.ts.map +1 -0
- package/dist/worker/errors.js +178 -0
- package/dist/worker/errors.js.map +1 -0
- package/dist/worker/health-check-manager.d.ts +141 -0
- package/dist/worker/health-check-manager.d.ts.map +1 -0
- package/dist/worker/health-check-manager.js +145 -0
- package/dist/worker/health-check-manager.js.map +1 -0
- package/dist/worker/index.d.ts +60 -0
- package/dist/worker/index.d.ts.map +1 -0
- package/dist/worker/index.js +67 -0
- package/dist/worker/index.js.map +1 -0
- package/dist/worker/memory-pressure.d.ts +892 -0
- package/dist/worker/memory-pressure.d.ts.map +1 -0
- package/dist/worker/memory-pressure.js +1990 -0
- package/dist/worker/memory-pressure.js.map +1 -0
- package/dist/worker/migration-manager.d.ts +153 -0
- package/dist/worker/migration-manager.d.ts.map +1 -0
- package/dist/worker/migration-manager.js +461 -0
- package/dist/worker/migration-manager.js.map +1 -0
- package/dist/worker/plugin-manager.d.ts +147 -0
- package/dist/worker/plugin-manager.d.ts.map +1 -0
- package/dist/worker/plugin-manager.js +408 -0
- package/dist/worker/plugin-manager.js.map +1 -0
- package/dist/worker/proxy.d.ts +330 -0
- package/dist/worker/proxy.d.ts.map +1 -0
- package/dist/worker/proxy.js +504 -0
- package/dist/worker/proxy.js.map +1 -0
- package/dist/worker/query-execution-manager.d.ts +107 -0
- package/dist/worker/query-execution-manager.d.ts.map +1 -0
- package/dist/worker/query-execution-manager.js +155 -0
- package/dist/worker/query-execution-manager.js.map +1 -0
- package/dist/worker/query-executor.d.ts +163 -0
- package/dist/worker/query-executor.d.ts.map +1 -0
- package/dist/worker/query-executor.js +413 -0
- package/dist/worker/query-executor.js.map +1 -0
- package/dist/worker/query-stats-manager.d.ts +117 -0
- package/dist/worker/query-stats-manager.d.ts.map +1 -0
- package/dist/worker/query-stats-manager.js +162 -0
- package/dist/worker/query-stats-manager.js.map +1 -0
- package/dist/worker/result-handler.d.ts +192 -0
- package/dist/worker/result-handler.d.ts.map +1 -0
- package/dist/worker/result-handler.js +346 -0
- package/dist/worker/result-handler.js.map +1 -0
- package/dist/worker/routes.d.ts +135 -0
- package/dist/worker/routes.d.ts.map +1 -0
- package/dist/worker/routes.js +460 -0
- package/dist/worker/routes.js.map +1 -0
- package/dist/worker/rpc-methods-manager.d.ts +142 -0
- package/dist/worker/rpc-methods-manager.d.ts.map +1 -0
- package/dist/worker/rpc-methods-manager.js +195 -0
- package/dist/worker/rpc-methods-manager.js.map +1 -0
- package/dist/worker/rpc.d.ts +259 -0
- package/dist/worker/rpc.d.ts.map +1 -0
- package/dist/worker/rpc.js +398 -0
- package/dist/worker/rpc.js.map +1 -0
- package/dist/worker/schema-version.d.ts +209 -0
- package/dist/worker/schema-version.d.ts.map +1 -0
- package/dist/worker/schema-version.js +450 -0
- package/dist/worker/schema-version.js.map +1 -0
- package/dist/worker/session-manager.d.ts +282 -0
- package/dist/worker/session-manager.d.ts.map +1 -0
- package/dist/worker/session-manager.js +523 -0
- package/dist/worker/session-manager.js.map +1 -0
- package/dist/worker/shutdown-manager.d.ts +188 -0
- package/dist/worker/shutdown-manager.d.ts.map +1 -0
- package/dist/worker/shutdown-manager.js +347 -0
- package/dist/worker/shutdown-manager.js.map +1 -0
- package/dist/worker/sql-transform.d.ts +61 -0
- package/dist/worker/sql-transform.d.ts.map +1 -0
- package/dist/worker/sql-transform.js +312 -0
- package/dist/worker/sql-transform.js.map +1 -0
- package/dist/worker/types.d.ts +738 -0
- package/dist/worker/types.d.ts.map +1 -0
- package/dist/worker/types.js +6 -0
- package/dist/worker/types.js.map +1 -0
- package/dist/worker/user-routes.d.ts +76 -0
- package/dist/worker/user-routes.d.ts.map +1 -0
- package/dist/worker/user-routes.js +188 -0
- package/dist/worker/user-routes.js.map +1 -0
- package/dist/worker/wal-facade.d.ts +138 -0
- package/dist/worker/wal-facade.d.ts.map +1 -0
- package/dist/worker/wal-facade.js +184 -0
- package/dist/worker/wal-facade.js.map +1 -0
- package/dist/worker/wal-r2.d.ts +271 -0
- package/dist/worker/wal-r2.d.ts.map +1 -0
- package/dist/worker/wal-r2.js +689 -0
- package/dist/worker/wal-r2.js.map +1 -0
- package/dist/worker/wal-replay.d.ts +361 -0
- package/dist/worker/wal-replay.d.ts.map +1 -0
- package/dist/worker/wal-replay.js +628 -0
- package/dist/worker/wal-replay.js.map +1 -0
- package/dist/worker/wal-retention.d.ts +389 -0
- package/dist/worker/wal-retention.d.ts.map +1 -0
- package/dist/worker/wal-retention.js +763 -0
- package/dist/worker/wal-retention.js.map +1 -0
- package/dist/worker/wal.d.ts +278 -0
- package/dist/worker/wal.d.ts.map +1 -0
- package/dist/worker/wal.js +467 -0
- package/dist/worker/wal.js.map +1 -0
- package/dist/worker/websocket.d.ts +85 -0
- package/dist/worker/websocket.d.ts.map +1 -0
- package/dist/worker/websocket.js +227 -0
- package/dist/worker/websocket.js.map +1 -0
- package/package.json +108 -0
- package/src/cdc/change-stream.ts +137 -0
- package/src/cdc/filter.ts +646 -0
- package/src/cdc/index.ts +112 -0
- package/src/cdc/resume-token.ts +280 -0
- package/src/cdc/transport/index.ts +7 -0
- package/src/cdc/transport/sse.ts +723 -0
- package/src/cdc/transport/websocket.ts +873 -0
- package/src/cdc/types.ts +346 -0
- package/src/config/index.ts +25 -0
- package/src/config/memory.ts +177 -0
- package/src/config/storage.ts +204 -0
- package/src/config/streaming.ts +147 -0
- package/src/config/timeouts.ts +221 -0
- package/src/extensions/config.test.ts +187 -0
- package/src/extensions/config.ts +278 -0
- package/src/extensions/geo.test.ts +455 -0
- package/src/extensions/geo.ts +858 -0
- package/src/extensions/index.test.ts +259 -0
- package/src/extensions/index.ts +227 -0
- package/src/extensions/loader.test.ts +555 -0
- package/src/extensions/loader.ts +588 -0
- package/src/extensions/pgmq-lite.test.ts +727 -0
- package/src/extensions/pgmq-lite.ts +770 -0
- package/src/extensions/plugins.test.ts +528 -0
- package/src/extensions/plugins.ts +718 -0
- package/src/extensions/registry.test.ts +202 -0
- package/src/extensions/registry.ts +267 -0
- package/src/extensions/vector.test.ts +195 -0
- package/src/extensions/vector.ts +217 -0
- package/src/iceberg/SCHEDULER.md +580 -0
- package/src/iceberg/analytics.test.ts +703 -0
- package/src/iceberg/analytics.ts +727 -0
- package/src/iceberg/catalog-api.test.ts +838 -0
- package/src/iceberg/catalog-api.ts +520 -0
- package/src/iceberg/catalog.test.ts +680 -0
- package/src/iceberg/catalog.ts +1007 -0
- package/src/iceberg/iceberg.test.ts +705 -0
- package/src/iceberg/index.ts +406 -0
- package/src/iceberg/metadata.test.ts +632 -0
- package/src/iceberg/metadata.ts +649 -0
- package/src/iceberg/optimizer.test.ts +868 -0
- package/src/iceberg/optimizer.ts +1287 -0
- package/src/iceberg/parquet.test.ts +899 -0
- package/src/iceberg/parquet.ts +1640 -0
- package/src/iceberg/r2-organization.test.ts +615 -0
- package/src/iceberg/r2-organization.ts +951 -0
- package/src/iceberg/scheduler-do-example.ts +364 -0
- package/src/iceberg/scheduler.test.ts +861 -0
- package/src/iceberg/scheduler.ts +1201 -0
- package/src/iceberg/schema.test.ts +547 -0
- package/src/iceberg/schema.ts +616 -0
- package/src/iceberg/snapshot-manager.test.ts +919 -0
- package/src/iceberg/snapshot-manager.ts +1369 -0
- package/src/iceberg/sql-router.test.ts +334 -0
- package/src/iceberg/sql-router.ts +337 -0
- package/src/iceberg/test-fixtures.ts +605 -0
- package/src/iceberg/time-travel-api.test.ts +1029 -0
- package/src/iceberg/time-travel-api.ts +731 -0
- package/src/iceberg/time-travel.test.ts +1218 -0
- package/src/iceberg/time-travel.ts +1052 -0
- package/src/iceberg/transformer.test.ts +689 -0
- package/src/iceberg/transformer.ts +1029 -0
- package/src/iceberg/types.ts +373 -0
- package/src/iceberg/writer.test.ts +716 -0
- package/src/iceberg/writer.ts +590 -0
- package/src/index.ts +212 -0
- package/src/lineage/index.ts +42 -0
- package/src/lineage/integration.ts +334 -0
- package/src/lineage/tracker.ts +1618 -0
- package/src/lineage/types.ts +354 -0
- package/src/middleware/index.ts +36 -0
- package/src/middleware/rate-limit-concurrent.test.ts +794 -0
- package/src/middleware/rate-limit.test.ts +1568 -0
- package/src/middleware/rate-limit.ts +840 -0
- package/src/migration-tooling/external-migration.test.ts +1864 -0
- package/src/migration-tooling/external-migration.ts +2355 -0
- package/src/migration-tooling/index.ts +19 -0
- package/src/migrations/ARCHITECTURE.md +474 -0
- package/src/migrations/PROGRESS_TRACKING.md +485 -0
- package/src/migrations/auto-migrator.test.ts +732 -0
- package/src/migrations/auto-migrator.ts +531 -0
- package/src/migrations/bulk-orchestrator.test.ts +801 -0
- package/src/migrations/bulk-orchestrator.ts +1039 -0
- package/src/migrations/compatibility.test.ts +958 -0
- package/src/migrations/compatibility.ts +902 -0
- package/src/migrations/do-migrations.test.ts +2620 -0
- package/src/migrations/do-migrations.ts +1289 -0
- package/src/migrations/do-migrations.types.ts +715 -0
- package/src/migrations/drizzle-compat.test.ts +210 -0
- package/src/migrations/drizzle-compat.ts +337 -0
- package/src/migrations/index.ts +334 -0
- package/src/migrations/migration-api.test.ts +438 -0
- package/src/migrations/migration-api.ts +704 -0
- package/src/migrations/progress-tracker-do.ts +518 -0
- package/src/migrations/progress-tracker-kv.ts +305 -0
- package/src/migrations/progress-tracker.test.ts +937 -0
- package/src/migrations/progress-tracker.ts +665 -0
- package/src/migrations/registry.test.ts +331 -0
- package/src/migrations/registry.ts +468 -0
- package/src/migrations/rollback.test.ts +644 -0
- package/src/migrations/runner.test.ts +807 -0
- package/src/migrations/runner.test.ts.backup +759 -0
- package/src/migrations/runner.ts +1459 -0
- package/src/migrations/schema-generator.test.ts +649 -0
- package/src/migrations/schema-generator.ts +513 -0
- package/src/migrations/testing.ts +1037 -0
- package/src/migrations/types.ts +573 -0
- package/src/migrations/validator.test.ts +660 -0
- package/src/migrations/validator.ts +741 -0
- package/src/observability/alerting.test.ts +1133 -0
- package/src/observability/alerting.ts +455 -0
- package/src/observability/analytics-engine.ts +733 -0
- package/src/observability/cost-metrics.ts +804 -0
- package/src/observability/cross-do-tracing.test.ts +516 -0
- package/src/observability/cross-do-tracing.ts +588 -0
- package/src/observability/dashboards/postgres-do-overview.json +1656 -0
- package/src/observability/error-rate-collector.test.ts +977 -0
- package/src/observability/error-rate-collector.ts +518 -0
- package/src/observability/exporters.test.ts +365 -0
- package/src/observability/exporters.ts +650 -0
- package/src/observability/health-check.test.ts +353 -0
- package/src/observability/health-check.ts +341 -0
- package/src/observability/index.test.ts +298 -0
- package/src/observability/index.ts +885 -0
- package/src/observability/instrumentation.test.ts +428 -0
- package/src/observability/instrumentation.ts +788 -0
- package/src/observability/memory-metrics.test.ts +355 -0
- package/src/observability/memory-metrics.ts +990 -0
- package/src/observability/metrics-endpoint.test.ts +402 -0
- package/src/observability/metrics-endpoint.ts +374 -0
- package/src/observability/metrics.test.ts +291 -0
- package/src/observability/metrics.ts +315 -0
- package/src/observability/observability-features.ts +1296 -0
- package/src/observability/prometheus.test.ts +292 -0
- package/src/observability/prometheus.ts +170 -0
- package/src/observability/propagation.test.ts +417 -0
- package/src/observability/propagation.ts +294 -0
- package/src/observability/query-latency.ts +586 -0
- package/src/observability/query-performance.test.ts +406 -0
- package/src/observability/query-performance.ts +491 -0
- package/src/observability/storage-tier-metrics.test.ts +633 -0
- package/src/observability/storage-tier-metrics.ts +570 -0
- package/src/observability/tier-cost-optimizer.ts +740 -0
- package/src/observability/tracer.test.ts +346 -0
- package/src/observability/tracer.ts +585 -0
- package/src/observability/types.test.ts +726 -0
- package/src/observability/types.ts +434 -0
- package/src/pglite/auto-demotion.test.ts +477 -0
- package/src/pglite/auto-demotion.ts +385 -0
- package/src/pglite/auto-promotion.test.ts +824 -0
- package/src/pglite/auto-promotion.ts +547 -0
- package/src/pglite/cache-layer.test.ts +469 -0
- package/src/pglite/cache-layer.ts +271 -0
- package/src/pglite/cold-start-manager.ts +1260 -0
- package/src/pglite/cold-start-optimizer.test.ts +937 -0
- package/src/pglite/cold-start-optimizer.ts +1895 -0
- package/src/pglite/dovfs-adapter.ts +1122 -0
- package/src/pglite/dovfs.ts +1258 -0
- package/src/pglite/etag-cache.test.ts +844 -0
- package/src/pglite/etag-cache.ts +526 -0
- package/src/pglite/index.ts +442 -0
- package/src/pglite/init.test.ts +455 -0
- package/src/pglite/init.ts +574 -0
- package/src/pglite/lifecycle.test.ts +599 -0
- package/src/pglite/lifecycle.ts +704 -0
- package/src/pglite/parallel-loader.test.ts +586 -0
- package/src/pglite/parallel-loader.ts +481 -0
- package/src/pglite/production-pglite.test.ts +666 -0
- package/src/pglite/production-pglite.ts +537 -0
- package/src/pglite/query-executor.ts +614 -0
- package/src/pglite/r2-layer.test.ts +501 -0
- package/src/pglite/r2-layer.ts +322 -0
- package/src/pglite/tiered-init.test.ts +725 -0
- package/src/pglite/tiered-init.ts +556 -0
- package/src/pglite/tiered-vfs.test.ts +726 -0
- package/src/pglite/tiered-vfs.ts +33 -0
- package/src/pglite/tiering-stats.test.ts +531 -0
- package/src/pglite/tiering-stats.ts +407 -0
- package/src/pglite/transaction-hooks.ts +343 -0
- package/src/pglite/warm-loader.test.ts +1701 -0
- package/src/pglite/warm-loader.ts +528 -0
- package/src/pglite/workers-pglite.ts +224 -0
- package/src/pglite-assets/pglite.data +0 -0
- package/src/pglite-assets/pglite.wasm +0 -0
- package/src/pglite.d.ts +47 -0
- package/src/playground/index.ts +137 -0
- package/src/playground/keyboard-shortcuts.ts +677 -0
- package/src/playground/playground.ts +323 -0
- package/src/playground/query-executor.ts +669 -0
- package/src/playground/query-history.ts +328 -0
- package/src/playground/result-formatter.ts +420 -0
- package/src/playground/sample-datasets.ts +674 -0
- package/src/playground/sample-queries.ts +1168 -0
- package/src/playground/schema-explorer.ts +558 -0
- package/src/playground/types.ts +518 -0
- package/src/readonly/cache-reader.test.ts +460 -0
- package/src/readonly/cache-reader.ts +313 -0
- package/src/readonly/config.test.ts +187 -0
- package/src/readonly/config.ts +128 -0
- package/src/readonly/index.ts +50 -0
- package/src/readonly/pglite-wrapper.test.ts +278 -0
- package/src/readonly/pglite-wrapper.ts +184 -0
- package/src/readonly/worker.test.ts +533 -0
- package/src/readonly/worker.ts +341 -0
- package/src/readonly/write-blocker.test.ts +459 -0
- package/src/readonly/write-blocker.ts +175 -0
- package/src/recovery/disaster-recovery.test.ts +618 -0
- package/src/recovery/disaster-recovery.ts +1181 -0
- package/src/recovery/index.ts +43 -0
- package/src/recovery/parquet-parser.ts +974 -0
- package/src/retention/index.ts +74 -0
- package/src/retention/policy.test.ts +571 -0
- package/src/retention/policy.ts +774 -0
- package/src/retention/purger.test.ts +465 -0
- package/src/retention/purger.ts +558 -0
- package/src/rls/auth-integration.test.ts +752 -0
- package/src/rls/auth-integration.ts +533 -0
- package/src/rls/generator.test.ts +829 -0
- package/src/rls/generator.ts +573 -0
- package/src/rls/index.ts +128 -0
- package/src/rls/policy.ts +208 -0
- package/src/rls/rls.test.ts +1071 -0
- package/src/rls/validator.test.ts +930 -0
- package/src/rls/validator.ts +895 -0
- package/src/routing/adaptive-router.test.ts +884 -0
- package/src/routing/adaptive-router.ts +845 -0
- package/src/routing/circuit-breaker.test.ts +1505 -0
- package/src/routing/circuit-breaker.ts +852 -0
- package/src/routing/cost-metrics.test.ts +565 -0
- package/src/routing/cost-metrics.ts +408 -0
- package/src/routing/do-connection-pool.test.ts +1109 -0
- package/src/routing/do-connection-pool.ts +828 -0
- package/src/routing/index.ts +158 -0
- package/src/routing/query-complexity-estimator.test.ts +356 -0
- package/src/routing/query-complexity-estimator.ts +444 -0
- package/src/routing/request-coalescing.test.ts +738 -0
- package/src/routing/request-coalescing.ts +475 -0
- package/src/routing/runtime-router.test.ts +436 -0
- package/src/routing/runtime-router.ts +357 -0
- package/src/routing/tenant-router.test.ts +2493 -0
- package/src/routing/tenant-router.ts +1908 -0
- package/src/routing/websocket-pool.test.ts +551 -0
- package/src/routing/websocket-pool.ts +577 -0
- package/src/storage/access-pattern-tracker.test.ts +874 -0
- package/src/storage/cache-layer.test.ts +560 -0
- package/src/storage/cache-layer.ts +328 -0
- package/src/storage/cost-aware-tiering.test.ts +652 -0
- package/src/storage/cost-aware-tiering.ts +794 -0
- package/src/storage/do-sqlite-blobs.test.ts +937 -0
- package/src/storage/index.ts +272 -0
- package/src/storage/interfaces.ts +974 -0
- package/src/storage/r2-layer.test.ts +653 -0
- package/src/storage/r2-layer.ts +434 -0
- package/src/storage/r2-overflow.ts +920 -0
- package/src/storage/r2-page-vfs.test.ts +2348 -0
- package/src/storage/r2-page-vfs.ts +1054 -0
- package/src/storage/swr-cache.test.ts +832 -0
- package/src/storage/swr-cache.ts +398 -0
- package/src/storage/swr-tiered-integration.test.ts +617 -0
- package/src/storage/tiered-orchestrator.test.ts +2441 -0
- package/src/storage/tiered-orchestrator.ts +2081 -0
- package/src/storage/tiered-vfs-swr.test.ts +736 -0
- package/src/storage/tiered-vfs-swr.ts +735 -0
- package/src/storage/tiered-vfs.test.ts +793 -0
- package/src/storage/tiered-vfs.ts +1082 -0
- package/src/streaming/backpressure-controller.ts +452 -0
- package/src/streaming/buffer-pool.ts +484 -0
- package/src/streaming/cdc-iceberg-connector.ts +605 -0
- package/src/streaming/index.ts +225 -0
- package/src/streaming/live-cdc-stream.ts +985 -0
- package/src/streaming/memory-bounded-stream.ts +443 -0
- package/src/streaming/query-streamer.ts +662 -0
- package/src/streaming/response-streaming.ts +557 -0
- package/src/types/branded.ts +1075 -0
- package/src/types/branded.ts.backup +273 -0
- package/src/types/utilities.ts +1023 -0
- package/src/types/wasm.d.ts +30 -0
- package/src/validation/typed-errors.test.ts +420 -0
- package/src/wal/replay-engine.ts +1264 -0
- package/src/worker/__mocks__/capnweb.ts +15 -0
- package/src/worker/__mocks__/pglite.data.ts +22 -0
- package/src/worker/__mocks__/pglite.wasm.ts +33 -0
- package/src/worker/auth-rate-limiter.test.ts +272 -0
- package/src/worker/auth-rate-limiter.ts +448 -0
- package/src/worker/auth.security-red.test.ts +1236 -0
- package/src/worker/auth.security.test.ts +822 -0
- package/src/worker/auth.test.ts +469 -0
- package/src/worker/auth.ts +1104 -0
- package/src/worker/cdc-backpressure.test.ts +726 -0
- package/src/worker/cdc-backpressure.ts +866 -0
- package/src/worker/cdc-sse.test.ts +780 -0
- package/src/worker/cdc-sse.ts +728 -0
- package/src/worker/cdc-websocket.ts +1229 -0
- package/src/worker/cdc-ws.test.ts +1009 -0
- package/src/worker/cdc.test.ts +327 -0
- package/src/worker/cdc.ts +289 -0
- package/src/worker/concerns/auth-concern.ts +179 -0
- package/src/worker/concerns/cdc-concern.ts +247 -0
- package/src/worker/concerns/index.ts +58 -0
- package/src/worker/concerns/query-execution-concern.ts +194 -0
- package/src/worker/concerns/storage-orchestration-concern.ts +373 -0
- package/src/worker/discriminated-types.test.ts +280 -0
- package/src/worker/do-auth-manager.ts +257 -0
- package/src/worker/do-decomposition.test.ts +1236 -0
- package/src/worker/do-pglite-manager.ts +302 -0
- package/src/worker/do.test.ts +2254 -0
- package/src/worker/do.ts +1878 -0
- package/src/worker/entry.ts +417 -0
- package/src/worker/errors.ts +285 -0
- package/src/worker/health-check-manager.test.ts +261 -0
- package/src/worker/health-check-manager.ts +231 -0
- package/src/worker/index.ts +389 -0
- package/src/worker/memory-pressure.test.ts +1460 -0
- package/src/worker/memory-pressure.ts +2650 -0
- package/src/worker/migration-manager.ts +582 -0
- package/src/worker/neon-compat.test.ts +332 -0
- package/src/worker/plugin-manager.ts +485 -0
- package/src/worker/postgres.do-rpc.d.ts +76 -0
- package/src/worker/proxy.ts +694 -0
- package/src/worker/query-execution-manager.test.ts +303 -0
- package/src/worker/query-execution-manager.ts +219 -0
- package/src/worker/query-executor.test.ts +282 -0
- package/src/worker/query-executor.ts +560 -0
- package/src/worker/query-stats-manager.ts +229 -0
- package/src/worker/result-handler.test.ts +364 -0
- package/src/worker/result-handler.ts +510 -0
- package/src/worker/routes.test.ts +795 -0
- package/src/worker/routes.ts +650 -0
- package/src/worker/rpc-methods-manager.test.ts +326 -0
- package/src/worker/rpc-methods-manager.ts +276 -0
- package/src/worker/rpc.ts +524 -0
- package/src/worker/schema-version.ts +605 -0
- package/src/worker/session-manager.test.ts +506 -0
- package/src/worker/session-manager.ts +732 -0
- package/src/worker/shutdown-manager.ts +469 -0
- package/src/worker/sql-transform.test.ts +286 -0
- package/src/worker/sql-transform.ts +368 -0
- package/src/worker/supabase-compat.test.ts +621 -0
- package/src/worker/types.test.ts +292 -0
- package/src/worker/types.ts +873 -0
- package/src/worker/user-routes.test.ts +703 -0
- package/src/worker/user-routes.ts +303 -0
- package/src/worker/wal-facade.ts +235 -0
- package/src/worker/wal-r2.test.ts +570 -0
- package/src/worker/wal-r2.ts +930 -0
- package/src/worker/wal-replay.test.ts +845 -0
- package/src/worker/wal-replay.ts +897 -0
- package/src/worker/wal-retention.test.ts +758 -0
- package/src/worker/wal-retention.ts +1075 -0
- package/src/worker/wal.test.ts +618 -0
- package/src/worker/wal.ts +697 -0
- package/src/worker/websocket.test.ts +296 -0
- package/src/worker/websocket.ts +284 -0
|
@@ -0,0 +1,1289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DO Migration System
|
|
3
|
+
*
|
|
4
|
+
* Durable Object-specific migration system designed for:
|
|
5
|
+
* - Fast, idempotent migrations (called on every request)
|
|
6
|
+
* - Memory-efficient for Workers environment
|
|
7
|
+
* - Support for schema snapshots for fast bootstrapping
|
|
8
|
+
* - Concurrent access protection with advisory locking
|
|
9
|
+
*
|
|
10
|
+
* @module migrations/do-migrations
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import type { PGlite } from '@dotdo/pglite'
|
|
14
|
+
import { createLogger, LogLevel, type ILogger } from '@dotdo/postgres-shared'
|
|
15
|
+
import { ValidationError, InvalidIdentifierError, StateError } from '@dotdo/postgres-shared/errors'
|
|
16
|
+
import type {
|
|
17
|
+
DOMigration,
|
|
18
|
+
DOMigrationRunner,
|
|
19
|
+
DOMigrationResult,
|
|
20
|
+
DOMigrationBatchResult,
|
|
21
|
+
DOMigrationConfig,
|
|
22
|
+
DOMigrationState,
|
|
23
|
+
DOSchemaVersion,
|
|
24
|
+
DOSchemaSnapshot,
|
|
25
|
+
DOMigrationRecord,
|
|
26
|
+
DOMigrationEvent,
|
|
27
|
+
DOMigrationEventType,
|
|
28
|
+
DOMigrationEventHandler,
|
|
29
|
+
DORollbackOptions,
|
|
30
|
+
DOMigrationValidationResult,
|
|
31
|
+
DOMigrationValidationIssue,
|
|
32
|
+
MigrationExecutor,
|
|
33
|
+
CreateDOMigrationRunner,
|
|
34
|
+
GenerateDOSchemaSnapshot,
|
|
35
|
+
ConvertToDOMigration,
|
|
36
|
+
} from './do-migrations.types'
|
|
37
|
+
|
|
38
|
+
// =============================================================================
|
|
39
|
+
// Constants
|
|
40
|
+
// =============================================================================
|
|
41
|
+
|
|
42
|
+
const DEFAULT_META_TABLE = '_do_migrations'
|
|
43
|
+
const DEFAULT_LOCK_TIMEOUT_MS = 5000
|
|
44
|
+
const DEFAULT_MIGRATION_TIMEOUT_MS = 30000
|
|
45
|
+
const LOCK_KEY = 1 // Advisory lock key for migrations
|
|
46
|
+
|
|
47
|
+
// Module-level logger for DO migrations
|
|
48
|
+
// Level is DEBUG because the debug config flag gates whether log() is called at all.
|
|
49
|
+
// The logger just provides structured output - the filtering happens at call site.
|
|
50
|
+
const doMigrationLogger: ILogger = createLogger({
|
|
51
|
+
level: LogLevel.DEBUG,
|
|
52
|
+
prefix: '[DOMigration]',
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
// Regex pattern for valid SQL identifiers (alphanumeric + underscore, starting with letter or underscore)
|
|
56
|
+
const VALID_SQL_IDENTIFIER_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Validate that a string is a safe SQL identifier to prevent SQL injection.
|
|
60
|
+
* Must start with a letter or underscore, followed by letters, numbers, or underscores.
|
|
61
|
+
*/
|
|
62
|
+
function isValidSqlIdentifier(name: string): boolean {
|
|
63
|
+
return VALID_SQL_IDENTIFIER_PATTERN.test(name)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// =============================================================================
|
|
67
|
+
// Type Guards for MigrationExecutor
|
|
68
|
+
// =============================================================================
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Type guard to check if executor is a plain SQL string
|
|
72
|
+
*/
|
|
73
|
+
function isStringExecutor(executor: MigrationExecutor): executor is string {
|
|
74
|
+
return typeof executor === 'string'
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Type guard to check if executor is a function that returns SQL
|
|
79
|
+
* These are zero-arity functions that return string or Promise<string>
|
|
80
|
+
*/
|
|
81
|
+
function isSqlFunctionExecutor(
|
|
82
|
+
executor: MigrationExecutor
|
|
83
|
+
): executor is (() => string) | (() => Promise<string>) {
|
|
84
|
+
if (typeof executor !== 'function') return false
|
|
85
|
+
// Check function signature - no parameters means SQL function
|
|
86
|
+
return executor.length === 0
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Type guard to check if executor is a function that operates on the database directly
|
|
91
|
+
* These are functions that take a PGlite instance and execute operations
|
|
92
|
+
*/
|
|
93
|
+
function isDbFunctionExecutor(
|
|
94
|
+
executor: MigrationExecutor
|
|
95
|
+
): executor is (db: PGlite) => Promise<void> {
|
|
96
|
+
if (typeof executor !== 'function') return false
|
|
97
|
+
// Check function signature - one parameter means DB function
|
|
98
|
+
return executor.length === 1
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// =============================================================================
|
|
102
|
+
// Utility Functions
|
|
103
|
+
// =============================================================================
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Calculate a cryptographic checksum for migration content using SHA-256
|
|
107
|
+
*/
|
|
108
|
+
async function calculateChecksum(content: string): Promise<string> {
|
|
109
|
+
const encoder = new TextEncoder()
|
|
110
|
+
const data = encoder.encode(content)
|
|
111
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', data)
|
|
112
|
+
const hashArray = new Uint8Array(hashBuffer)
|
|
113
|
+
// Use first 16 bytes (32 hex chars) for reasonable uniqueness
|
|
114
|
+
return Array.from(hashArray.slice(0, 16))
|
|
115
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
116
|
+
.join('')
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Execute a migration executor
|
|
121
|
+
*/
|
|
122
|
+
async function executeExecutor(executor: MigrationExecutor, db: PGlite): Promise<void> {
|
|
123
|
+
if (isStringExecutor(executor)) {
|
|
124
|
+
await db.exec(executor)
|
|
125
|
+
return
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (isDbFunctionExecutor(executor)) {
|
|
129
|
+
// Function expects db parameter - executes directly
|
|
130
|
+
await executor(db)
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (isSqlFunctionExecutor(executor)) {
|
|
135
|
+
// Function returns SQL string
|
|
136
|
+
const sql = await executor()
|
|
137
|
+
await db.exec(sql)
|
|
138
|
+
return
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
throw new ValidationError('Invalid executor type', {
|
|
142
|
+
code: 'INVALID_TYPE',
|
|
143
|
+
context: { executorType: typeof executor },
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Get checksum content for a migration
|
|
149
|
+
*/
|
|
150
|
+
function getMigrationChecksumContent(migration: DOMigration): string {
|
|
151
|
+
const upContent = typeof migration.up === 'string' ? migration.up : migration.up.toString()
|
|
152
|
+
const downContent = migration.down
|
|
153
|
+
? (typeof migration.down === 'string' ? migration.down : migration.down.toString())
|
|
154
|
+
: ''
|
|
155
|
+
return `v${migration.version}:${migration.name}:${upContent}:${downContent}`
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// =============================================================================
|
|
159
|
+
// DOMigrationRunner Implementation
|
|
160
|
+
// =============================================================================
|
|
161
|
+
|
|
162
|
+
class DOMigrationRunnerImpl implements DOMigrationRunner {
|
|
163
|
+
private _state: DOMigrationState = 'uninitialized'
|
|
164
|
+
private readonly db: PGlite
|
|
165
|
+
private readonly migrations: DOMigration[]
|
|
166
|
+
private readonly config: Required<Omit<DOMigrationConfig, 'snapshot' | 'onEvent'>> & {
|
|
167
|
+
snapshot?: DOSchemaSnapshot
|
|
168
|
+
onEvent?: DOMigrationEventHandler
|
|
169
|
+
}
|
|
170
|
+
private readonly eventHandlers: Set<DOMigrationEventHandler> = new Set()
|
|
171
|
+
private cachedVersion: number | null = null
|
|
172
|
+
private isInitialized = false
|
|
173
|
+
|
|
174
|
+
constructor(db: PGlite, migrations: DOMigration[], config?: DOMigrationConfig) {
|
|
175
|
+
// Validate metaTableName to prevent SQL injection
|
|
176
|
+
const metaTableName = config?.metaTableName ?? DEFAULT_META_TABLE
|
|
177
|
+
if (!isValidSqlIdentifier(metaTableName)) {
|
|
178
|
+
throw new InvalidIdentifierError(
|
|
179
|
+
metaTableName,
|
|
180
|
+
'table',
|
|
181
|
+
'Must be a valid SQL identifier (start with letter or underscore, contain only letters, numbers, and underscores)'
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
this.db = db
|
|
186
|
+
this.migrations = [...migrations].sort((a, b) => a.version - b.version)
|
|
187
|
+
this.config = {
|
|
188
|
+
metaTableName,
|
|
189
|
+
useLocking: config?.useLocking ?? true,
|
|
190
|
+
lockTimeoutMs: config?.lockTimeoutMs ?? DEFAULT_LOCK_TIMEOUT_MS,
|
|
191
|
+
migrationTimeoutMs: config?.migrationTimeoutMs ?? DEFAULT_MIGRATION_TIMEOUT_MS,
|
|
192
|
+
useSnapshot: config?.useSnapshot ?? false,
|
|
193
|
+
allowVersionGaps: config?.allowVersionGaps ?? false,
|
|
194
|
+
debug: config?.debug ?? false,
|
|
195
|
+
dryRun: config?.dryRun ?? false,
|
|
196
|
+
...(config?.snapshot !== undefined && { snapshot: config.snapshot }),
|
|
197
|
+
...(config?.onEvent !== undefined && { onEvent: config.onEvent }),
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (config?.onEvent) {
|
|
201
|
+
this.eventHandlers.add(config.onEvent)
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
get state(): DOMigrationState {
|
|
206
|
+
return this._state
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private emit(type: DOMigrationEventType, data?: Partial<Omit<DOMigrationEvent, 'type' | 'timestamp'>>): void {
|
|
210
|
+
const event: DOMigrationEvent = {
|
|
211
|
+
type,
|
|
212
|
+
timestamp: new Date(),
|
|
213
|
+
...data,
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
this.eventHandlers.forEach(handler => {
|
|
217
|
+
try {
|
|
218
|
+
handler(event)
|
|
219
|
+
} catch (error) {
|
|
220
|
+
// Don't let event handler errors break migration
|
|
221
|
+
if (this.config.debug) {
|
|
222
|
+
doMigrationLogger.error('Event handler error', {
|
|
223
|
+
error: error instanceof Error ? error.message : String(error),
|
|
224
|
+
})
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
})
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private async acquireLock(): Promise<boolean> {
|
|
231
|
+
if (!this.config.useLocking) {
|
|
232
|
+
return true
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
try {
|
|
236
|
+
// Use pg_try_advisory_lock with timeout
|
|
237
|
+
const startTime = Date.now()
|
|
238
|
+
|
|
239
|
+
while (Date.now() - startTime < this.config.lockTimeoutMs) {
|
|
240
|
+
const result = await this.db.query<{ pg_try_advisory_lock: boolean }>(
|
|
241
|
+
`SELECT pg_try_advisory_lock(${LOCK_KEY})`
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
if (result.rows[0]?.pg_try_advisory_lock) {
|
|
245
|
+
this.emit('lock:acquired')
|
|
246
|
+
return true
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
// Wait a bit before retrying
|
|
250
|
+
await new Promise(resolve => setTimeout(resolve, 50))
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
this.emit('lock:timeout')
|
|
254
|
+
return false
|
|
255
|
+
} catch (error) {
|
|
256
|
+
// If advisory locks aren't supported, proceed without locking
|
|
257
|
+
if (this.config.debug) {
|
|
258
|
+
doMigrationLogger.warn('Advisory lock not available, proceeding without lock')
|
|
259
|
+
}
|
|
260
|
+
return true
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
private async releaseLock(): Promise<void> {
|
|
265
|
+
if (!this.config.useLocking) {
|
|
266
|
+
return
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
try {
|
|
270
|
+
await this.db.query(`SELECT pg_advisory_unlock(${LOCK_KEY})`)
|
|
271
|
+
this.emit('lock:released')
|
|
272
|
+
} catch (error) {
|
|
273
|
+
// Ignore unlock errors
|
|
274
|
+
if (this.config.debug) {
|
|
275
|
+
doMigrationLogger.warn('Failed to release advisory lock', {
|
|
276
|
+
error: error instanceof Error ? error.message : String(error),
|
|
277
|
+
})
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
async initialize(): Promise<void> {
|
|
283
|
+
if (this.isInitialized) {
|
|
284
|
+
return
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
this._state = 'initializing'
|
|
288
|
+
|
|
289
|
+
try {
|
|
290
|
+
// Create migrations meta table if not exists
|
|
291
|
+
await this.db.exec(`
|
|
292
|
+
CREATE TABLE IF NOT EXISTS ${this.config.metaTableName} (
|
|
293
|
+
version INTEGER PRIMARY KEY,
|
|
294
|
+
name TEXT NOT NULL,
|
|
295
|
+
checksum TEXT NOT NULL,
|
|
296
|
+
applied_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
|
297
|
+
execution_time_ms INTEGER
|
|
298
|
+
)
|
|
299
|
+
`)
|
|
300
|
+
|
|
301
|
+
this.isInitialized = true
|
|
302
|
+
this._state = 'ready'
|
|
303
|
+
this.emit('initialized')
|
|
304
|
+
} catch (error) {
|
|
305
|
+
this._state = 'error'
|
|
306
|
+
throw error
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
async migrate(): Promise<DOMigrationBatchResult> {
|
|
311
|
+
const startTime = Date.now()
|
|
312
|
+
const results: DOMigrationResult[] = []
|
|
313
|
+
let fromVersion = await this.getCurrentVersion()
|
|
314
|
+
let migrationsRun = 0
|
|
315
|
+
let migrationsSkipped = 0
|
|
316
|
+
|
|
317
|
+
if (!this.isInitialized) {
|
|
318
|
+
await this.initialize()
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const pendingMigrations = await this.getPendingMigrations()
|
|
322
|
+
|
|
323
|
+
if (pendingMigrations.length === 0) {
|
|
324
|
+
return {
|
|
325
|
+
success: true,
|
|
326
|
+
fromVersion,
|
|
327
|
+
toVersion: fromVersion,
|
|
328
|
+
totalTimeMs: Date.now() - startTime,
|
|
329
|
+
results: [],
|
|
330
|
+
migrationsRun: 0,
|
|
331
|
+
migrationsSkipped: 0,
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Acquire lock
|
|
336
|
+
const lockAcquired = await this.acquireLock()
|
|
337
|
+
if (!lockAcquired) {
|
|
338
|
+
return {
|
|
339
|
+
success: false,
|
|
340
|
+
fromVersion,
|
|
341
|
+
toVersion: fromVersion,
|
|
342
|
+
totalTimeMs: Date.now() - startTime,
|
|
343
|
+
results: [],
|
|
344
|
+
migrationsRun: 0,
|
|
345
|
+
migrationsSkipped: 0,
|
|
346
|
+
error: 'Failed to acquire migration lock',
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
this._state = 'migrating'
|
|
351
|
+
this.emit('batch:start', { metadata: { fromVersion, pendingCount: pendingMigrations.length } })
|
|
352
|
+
|
|
353
|
+
try {
|
|
354
|
+
// Re-check pending migrations after acquiring lock (another process may have run them)
|
|
355
|
+
const actualPendingMigrations = await this.getPendingMigrations()
|
|
356
|
+
|
|
357
|
+
for (const migration of actualPendingMigrations) {
|
|
358
|
+
const migrationStartTime = Date.now()
|
|
359
|
+
this.emit('migration:start', { version: migration.version, name: migration.name })
|
|
360
|
+
|
|
361
|
+
try {
|
|
362
|
+
if (this.config.dryRun) {
|
|
363
|
+
// In dry-run mode, just record what would be done
|
|
364
|
+
results.push({
|
|
365
|
+
success: true,
|
|
366
|
+
version: migration.version,
|
|
367
|
+
name: migration.name,
|
|
368
|
+
executionTimeMs: 0,
|
|
369
|
+
skipped: true,
|
|
370
|
+
})
|
|
371
|
+
migrationsSkipped++
|
|
372
|
+
this.emit('migration:skip', { version: migration.version, name: migration.name })
|
|
373
|
+
continue
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const transactional = migration.transactional !== false
|
|
377
|
+
|
|
378
|
+
if (transactional) {
|
|
379
|
+
await this.db.exec('BEGIN')
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
try {
|
|
383
|
+
await executeExecutor(migration.up, this.db)
|
|
384
|
+
|
|
385
|
+
// Record the migration
|
|
386
|
+
const checksum = await calculateChecksum(getMigrationChecksumContent(migration))
|
|
387
|
+
const executionTimeMs = Date.now() - migrationStartTime
|
|
388
|
+
|
|
389
|
+
await this.db.query(
|
|
390
|
+
`INSERT INTO ${this.config.metaTableName} (version, name, checksum, execution_time_ms) VALUES ($1, $2, $3, $4)`,
|
|
391
|
+
[migration.version, migration.name, checksum, executionTimeMs]
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
if (transactional) {
|
|
395
|
+
await this.db.exec('COMMIT')
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
results.push({
|
|
399
|
+
success: true,
|
|
400
|
+
version: migration.version,
|
|
401
|
+
name: migration.name,
|
|
402
|
+
executionTimeMs,
|
|
403
|
+
checksum,
|
|
404
|
+
})
|
|
405
|
+
migrationsRun++
|
|
406
|
+
this.cachedVersion = migration.version
|
|
407
|
+
|
|
408
|
+
this.emit('migration:complete', {
|
|
409
|
+
version: migration.version,
|
|
410
|
+
name: migration.name,
|
|
411
|
+
durationMs: executionTimeMs,
|
|
412
|
+
})
|
|
413
|
+
} catch (error) {
|
|
414
|
+
if (transactional) {
|
|
415
|
+
await this.db.exec('ROLLBACK')
|
|
416
|
+
}
|
|
417
|
+
throw error
|
|
418
|
+
}
|
|
419
|
+
} catch (error) {
|
|
420
|
+
const errorMessage = error instanceof Error ? error.message : String(error)
|
|
421
|
+
const executionTimeMs = Date.now() - migrationStartTime
|
|
422
|
+
|
|
423
|
+
results.push({
|
|
424
|
+
success: false,
|
|
425
|
+
version: migration.version,
|
|
426
|
+
name: migration.name,
|
|
427
|
+
executionTimeMs,
|
|
428
|
+
error: errorMessage,
|
|
429
|
+
})
|
|
430
|
+
|
|
431
|
+
this.emit('migration:error', {
|
|
432
|
+
version: migration.version,
|
|
433
|
+
name: migration.name,
|
|
434
|
+
error: error instanceof Error ? error : new Error(errorMessage),
|
|
435
|
+
durationMs: executionTimeMs,
|
|
436
|
+
})
|
|
437
|
+
|
|
438
|
+
// Stop on first failure
|
|
439
|
+
break
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
const toVersion = await this.getCurrentVersion()
|
|
444
|
+
const success = results.every(r => r.success)
|
|
445
|
+
|
|
446
|
+
this._state = success ? 'ready' : 'error'
|
|
447
|
+
|
|
448
|
+
const failedResult = results.find(r => !r.success)
|
|
449
|
+
const batchResult: DOMigrationBatchResult = {
|
|
450
|
+
success,
|
|
451
|
+
fromVersion,
|
|
452
|
+
toVersion,
|
|
453
|
+
totalTimeMs: Date.now() - startTime,
|
|
454
|
+
results,
|
|
455
|
+
migrationsRun,
|
|
456
|
+
migrationsSkipped,
|
|
457
|
+
...(failedResult?.error !== undefined && { error: failedResult.error }),
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
this.emit(success ? 'batch:complete' : 'batch:error', {
|
|
461
|
+
durationMs: batchResult.totalTimeMs,
|
|
462
|
+
metadata: { fromVersion, toVersion, migrationsRun, migrationsSkipped },
|
|
463
|
+
...(batchResult.error !== undefined && { error: new Error(batchResult.error) }),
|
|
464
|
+
})
|
|
465
|
+
|
|
466
|
+
return batchResult
|
|
467
|
+
} finally {
|
|
468
|
+
await this.releaseLock()
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
async ensureMigrated(): Promise<DOMigrationBatchResult> {
|
|
473
|
+
if (!this.isInitialized) {
|
|
474
|
+
await this.initialize()
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// Check if snapshot should be used for new DOs
|
|
478
|
+
if (this.config.useSnapshot && this.config.snapshot) {
|
|
479
|
+
const currentVersion = await this.getCurrentVersion()
|
|
480
|
+
|
|
481
|
+
if (currentVersion === 0) {
|
|
482
|
+
// New DO - use snapshot
|
|
483
|
+
return this.applySnapshot(this.config.snapshot)
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
return this.migrate()
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
private async applySnapshot(snapshot: DOSchemaSnapshot): Promise<DOMigrationBatchResult> {
|
|
491
|
+
const startTime = Date.now()
|
|
492
|
+
|
|
493
|
+
// Validate snapshot checksum
|
|
494
|
+
const currentChecksum = await this.calculateMigrationsChecksum()
|
|
495
|
+
if (snapshot.migrationsChecksum !== currentChecksum) {
|
|
496
|
+
// Snapshot is stale, fall back to incremental migrations
|
|
497
|
+
if (this.config.debug) {
|
|
498
|
+
doMigrationLogger.warn('Snapshot checksum mismatch, falling back to incremental migrations')
|
|
499
|
+
}
|
|
500
|
+
return this.migrate()
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
const lockAcquired = await this.acquireLock()
|
|
504
|
+
if (!lockAcquired) {
|
|
505
|
+
return {
|
|
506
|
+
success: false,
|
|
507
|
+
fromVersion: 0,
|
|
508
|
+
toVersion: 0,
|
|
509
|
+
totalTimeMs: Date.now() - startTime,
|
|
510
|
+
results: [],
|
|
511
|
+
migrationsRun: 0,
|
|
512
|
+
migrationsSkipped: 0,
|
|
513
|
+
error: 'Failed to acquire migration lock',
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
this._state = 'migrating'
|
|
518
|
+
|
|
519
|
+
try {
|
|
520
|
+
await this.db.exec('BEGIN')
|
|
521
|
+
|
|
522
|
+
try {
|
|
523
|
+
// Apply schema DDL
|
|
524
|
+
await this.db.exec(snapshot.schemaDDL)
|
|
525
|
+
|
|
526
|
+
// Apply seed data if present
|
|
527
|
+
if (snapshot.seedDataDDL) {
|
|
528
|
+
await this.db.exec(snapshot.seedDataDDL)
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
// Record all migration versions
|
|
532
|
+
for (const version of snapshot.includedVersions) {
|
|
533
|
+
const migration = this.migrations.find(m => m.version === version)
|
|
534
|
+
if (migration) {
|
|
535
|
+
const checksum = await calculateChecksum(getMigrationChecksumContent(migration))
|
|
536
|
+
await this.db.query(
|
|
537
|
+
`INSERT INTO ${this.config.metaTableName} (version, name, checksum, execution_time_ms) VALUES ($1, $2, $3, $4)`,
|
|
538
|
+
[migration.version, migration.name, checksum, 0]
|
|
539
|
+
)
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
await this.db.exec('COMMIT')
|
|
544
|
+
|
|
545
|
+
this.cachedVersion = snapshot.targetVersion
|
|
546
|
+
this._state = 'ready'
|
|
547
|
+
|
|
548
|
+
this.emit('snapshot:applied', {
|
|
549
|
+
metadata: { targetVersion: snapshot.targetVersion, includedVersions: snapshot.includedVersions },
|
|
550
|
+
})
|
|
551
|
+
|
|
552
|
+
return {
|
|
553
|
+
success: true,
|
|
554
|
+
fromVersion: 0,
|
|
555
|
+
toVersion: snapshot.targetVersion,
|
|
556
|
+
totalTimeMs: Date.now() - startTime,
|
|
557
|
+
results: snapshot.includedVersions.map(v => {
|
|
558
|
+
const m = this.migrations.find(m => m.version === v)
|
|
559
|
+
return {
|
|
560
|
+
success: true,
|
|
561
|
+
version: v,
|
|
562
|
+
name: m?.name ?? `migration_${v}`,
|
|
563
|
+
executionTimeMs: 0,
|
|
564
|
+
skipped: false,
|
|
565
|
+
}
|
|
566
|
+
}),
|
|
567
|
+
migrationsRun: snapshot.includedVersions.length,
|
|
568
|
+
migrationsSkipped: 0,
|
|
569
|
+
}
|
|
570
|
+
} catch (error) {
|
|
571
|
+
await this.db.exec('ROLLBACK')
|
|
572
|
+
throw error
|
|
573
|
+
}
|
|
574
|
+
} catch (error) {
|
|
575
|
+
this._state = 'error'
|
|
576
|
+
const errorMessage = error instanceof Error ? error.message : String(error)
|
|
577
|
+
|
|
578
|
+
// Fall back to incremental migrations
|
|
579
|
+
if (this.config.debug) {
|
|
580
|
+
doMigrationLogger.warn('Snapshot application failed, falling back to incremental migrations', {
|
|
581
|
+
error: errorMessage,
|
|
582
|
+
})
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
return this.migrate()
|
|
586
|
+
} finally {
|
|
587
|
+
await this.releaseLock()
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
private async calculateMigrationsChecksum(): Promise<string> {
|
|
592
|
+
const content = this.migrations
|
|
593
|
+
.map(m => getMigrationChecksumContent(m))
|
|
594
|
+
.join('|')
|
|
595
|
+
return await calculateChecksum(content)
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
async getCurrentVersion(): Promise<number> {
|
|
599
|
+
if (this.cachedVersion !== null) {
|
|
600
|
+
return this.cachedVersion
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
if (!this.isInitialized) {
|
|
604
|
+
await this.initialize()
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
try {
|
|
608
|
+
const result = await this.db.query<{ max: number | null }>(
|
|
609
|
+
`SELECT MAX(version) as max FROM ${this.config.metaTableName}`
|
|
610
|
+
)
|
|
611
|
+
const version = result.rows[0]?.max ?? 0
|
|
612
|
+
this.cachedVersion = version
|
|
613
|
+
return version
|
|
614
|
+
} catch (error) {
|
|
615
|
+
// Table might not exist yet
|
|
616
|
+
return 0
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
async getSchemaVersion(): Promise<DOSchemaVersion> {
|
|
621
|
+
if (!this.isInitialized) {
|
|
622
|
+
await this.initialize()
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
try {
|
|
626
|
+
const result = await this.db.query<{
|
|
627
|
+
current_version: number | null
|
|
628
|
+
applied_count: number
|
|
629
|
+
last_migration_at: string | null
|
|
630
|
+
}>(`
|
|
631
|
+
SELECT
|
|
632
|
+
MAX(version) as current_version,
|
|
633
|
+
COUNT(*) as applied_count,
|
|
634
|
+
MAX(applied_at) as last_migration_at
|
|
635
|
+
FROM ${this.config.metaTableName}
|
|
636
|
+
`)
|
|
637
|
+
|
|
638
|
+
const row = result.rows[0]
|
|
639
|
+
const currentVersion = row?.current_version ?? 0
|
|
640
|
+
const appliedCount = Number(row?.applied_count ?? 0)
|
|
641
|
+
const lastMigrationAt = row?.last_migration_at ? new Date(row.last_migration_at) : null
|
|
642
|
+
|
|
643
|
+
// Calculate schema checksum from applied migrations
|
|
644
|
+
const appliedMigrations = await this.getAppliedMigrations()
|
|
645
|
+
const schemaChecksum = appliedMigrations.length > 0
|
|
646
|
+
? await calculateChecksum(appliedMigrations.map(m => m.checksum).join('|'))
|
|
647
|
+
: null
|
|
648
|
+
|
|
649
|
+
return {
|
|
650
|
+
currentVersion,
|
|
651
|
+
appliedCount,
|
|
652
|
+
lastMigrationAt,
|
|
653
|
+
schemaChecksum,
|
|
654
|
+
}
|
|
655
|
+
} catch (error) {
|
|
656
|
+
return {
|
|
657
|
+
currentVersion: 0,
|
|
658
|
+
appliedCount: 0,
|
|
659
|
+
lastMigrationAt: null,
|
|
660
|
+
schemaChecksum: null,
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
async getPendingMigrations(): Promise<DOMigration[]> {
|
|
666
|
+
const currentVersion = await this.getCurrentVersion()
|
|
667
|
+
const appliedVersions = new Set(
|
|
668
|
+
(await this.getAppliedMigrations()).map(m => m.version)
|
|
669
|
+
)
|
|
670
|
+
|
|
671
|
+
return this.migrations.filter(
|
|
672
|
+
m => m.version > currentVersion || !appliedVersions.has(m.version)
|
|
673
|
+
)
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
async hasPendingMigrations(): Promise<boolean> {
|
|
677
|
+
const pending = await this.getPendingMigrations()
|
|
678
|
+
return pending.length > 0
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
async rollbackTo(targetVersion: number, options?: DORollbackOptions): Promise<DOMigrationBatchResult> {
|
|
682
|
+
const startTime = Date.now()
|
|
683
|
+
const currentVersion = await this.getCurrentVersion()
|
|
684
|
+
const results: DOMigrationResult[] = []
|
|
685
|
+
|
|
686
|
+
if (targetVersion >= currentVersion) {
|
|
687
|
+
return {
|
|
688
|
+
success: true,
|
|
689
|
+
fromVersion: currentVersion,
|
|
690
|
+
toVersion: currentVersion,
|
|
691
|
+
totalTimeMs: Date.now() - startTime,
|
|
692
|
+
results: [],
|
|
693
|
+
migrationsRun: 0,
|
|
694
|
+
migrationsSkipped: 0,
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
// Get migrations to rollback (in reverse order)
|
|
699
|
+
const migrationsToRollback = this.migrations
|
|
700
|
+
.filter(m => m.version > targetVersion && m.version <= currentVersion)
|
|
701
|
+
.sort((a, b) => b.version - a.version)
|
|
702
|
+
|
|
703
|
+
// Check for non-reversible migrations
|
|
704
|
+
if (!options?.force) {
|
|
705
|
+
const nonReversible = migrationsToRollback.find(
|
|
706
|
+
m => m.isReversible === false || (!m.down && m.isReversible !== true)
|
|
707
|
+
)
|
|
708
|
+
if (nonReversible) {
|
|
709
|
+
return {
|
|
710
|
+
success: false,
|
|
711
|
+
fromVersion: currentVersion,
|
|
712
|
+
toVersion: currentVersion,
|
|
713
|
+
totalTimeMs: Date.now() - startTime,
|
|
714
|
+
results: [],
|
|
715
|
+
migrationsRun: 0,
|
|
716
|
+
migrationsSkipped: 0,
|
|
717
|
+
error: `Migration ${nonReversible.version} (${nonReversible.name}) is not reversible. Use force option to skip.`,
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
if (options?.dryRun) {
|
|
723
|
+
return {
|
|
724
|
+
success: true,
|
|
725
|
+
fromVersion: currentVersion,
|
|
726
|
+
toVersion: targetVersion,
|
|
727
|
+
totalTimeMs: Date.now() - startTime,
|
|
728
|
+
results: migrationsToRollback.map(m => ({
|
|
729
|
+
success: true,
|
|
730
|
+
version: m.version,
|
|
731
|
+
name: m.name,
|
|
732
|
+
executionTimeMs: 0,
|
|
733
|
+
skipped: true,
|
|
734
|
+
})),
|
|
735
|
+
migrationsRun: 0,
|
|
736
|
+
migrationsSkipped: migrationsToRollback.length,
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
const lockAcquired = await this.acquireLock()
|
|
741
|
+
if (!lockAcquired) {
|
|
742
|
+
return {
|
|
743
|
+
success: false,
|
|
744
|
+
fromVersion: currentVersion,
|
|
745
|
+
toVersion: currentVersion,
|
|
746
|
+
totalTimeMs: Date.now() - startTime,
|
|
747
|
+
results: [],
|
|
748
|
+
migrationsRun: 0,
|
|
749
|
+
migrationsSkipped: 0,
|
|
750
|
+
error: 'Failed to acquire migration lock',
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
this._state = 'migrating'
|
|
755
|
+
|
|
756
|
+
try {
|
|
757
|
+
let migrationsRun = 0
|
|
758
|
+
let migrationsSkipped = 0
|
|
759
|
+
|
|
760
|
+
for (const migration of migrationsToRollback) {
|
|
761
|
+
const migrationStartTime = Date.now()
|
|
762
|
+
|
|
763
|
+
if (!migration.down) {
|
|
764
|
+
// Skip migrations without down
|
|
765
|
+
results.push({
|
|
766
|
+
success: true,
|
|
767
|
+
version: migration.version,
|
|
768
|
+
name: migration.name,
|
|
769
|
+
executionTimeMs: 0,
|
|
770
|
+
skipped: true,
|
|
771
|
+
})
|
|
772
|
+
migrationsSkipped++
|
|
773
|
+
|
|
774
|
+
if (options?.onProgress) {
|
|
775
|
+
options.onProgress({
|
|
776
|
+
type: 'migration:skip',
|
|
777
|
+
timestamp: new Date(),
|
|
778
|
+
version: migration.version,
|
|
779
|
+
name: migration.name,
|
|
780
|
+
})
|
|
781
|
+
}
|
|
782
|
+
continue
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
try {
|
|
786
|
+
const transactional = migration.transactional !== false
|
|
787
|
+
|
|
788
|
+
if (transactional) {
|
|
789
|
+
await this.db.exec('BEGIN')
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
try {
|
|
793
|
+
await executeExecutor(migration.down, this.db)
|
|
794
|
+
|
|
795
|
+
// Remove the migration record
|
|
796
|
+
await this.db.query(
|
|
797
|
+
`DELETE FROM ${this.config.metaTableName} WHERE version = $1`,
|
|
798
|
+
[migration.version]
|
|
799
|
+
)
|
|
800
|
+
|
|
801
|
+
if (transactional) {
|
|
802
|
+
await this.db.exec('COMMIT')
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
const executionTimeMs = Date.now() - migrationStartTime
|
|
806
|
+
results.push({
|
|
807
|
+
success: true,
|
|
808
|
+
version: migration.version,
|
|
809
|
+
name: migration.name,
|
|
810
|
+
executionTimeMs,
|
|
811
|
+
})
|
|
812
|
+
migrationsRun++
|
|
813
|
+
|
|
814
|
+
if (options?.onProgress) {
|
|
815
|
+
options.onProgress({
|
|
816
|
+
type: 'migration:complete',
|
|
817
|
+
timestamp: new Date(),
|
|
818
|
+
version: migration.version,
|
|
819
|
+
name: migration.name,
|
|
820
|
+
durationMs: executionTimeMs,
|
|
821
|
+
})
|
|
822
|
+
}
|
|
823
|
+
} catch (error) {
|
|
824
|
+
if (transactional) {
|
|
825
|
+
await this.db.exec('ROLLBACK')
|
|
826
|
+
}
|
|
827
|
+
throw error
|
|
828
|
+
}
|
|
829
|
+
} catch (error) {
|
|
830
|
+
const errorMessage = error instanceof Error ? error.message : String(error)
|
|
831
|
+
results.push({
|
|
832
|
+
success: false,
|
|
833
|
+
version: migration.version,
|
|
834
|
+
name: migration.name,
|
|
835
|
+
executionTimeMs: Date.now() - migrationStartTime,
|
|
836
|
+
error: errorMessage,
|
|
837
|
+
})
|
|
838
|
+
|
|
839
|
+
if (options?.onProgress) {
|
|
840
|
+
options.onProgress({
|
|
841
|
+
type: 'migration:error',
|
|
842
|
+
timestamp: new Date(),
|
|
843
|
+
version: migration.version,
|
|
844
|
+
name: migration.name,
|
|
845
|
+
error: error instanceof Error ? error : new Error(errorMessage),
|
|
846
|
+
})
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
// Stop on first failure
|
|
850
|
+
break
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
// Invalidate cache
|
|
855
|
+
this.cachedVersion = null
|
|
856
|
+
const toVersion = await this.getCurrentVersion()
|
|
857
|
+
const success = results.every(r => r.success)
|
|
858
|
+
|
|
859
|
+
this._state = success ? 'ready' : 'error'
|
|
860
|
+
|
|
861
|
+
const failedError = results.find(r => !r.success)?.error
|
|
862
|
+
const result: DOMigrationBatchResult = {
|
|
863
|
+
success,
|
|
864
|
+
fromVersion: currentVersion,
|
|
865
|
+
toVersion,
|
|
866
|
+
totalTimeMs: Date.now() - startTime,
|
|
867
|
+
results,
|
|
868
|
+
migrationsRun,
|
|
869
|
+
migrationsSkipped,
|
|
870
|
+
}
|
|
871
|
+
if (failedError !== undefined) {
|
|
872
|
+
result.error = failedError
|
|
873
|
+
}
|
|
874
|
+
return result
|
|
875
|
+
} finally {
|
|
876
|
+
await this.releaseLock()
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
async rollbackLast(count = 1, options?: DORollbackOptions): Promise<DOMigrationBatchResult> {
|
|
881
|
+
const currentVersion = await this.getCurrentVersion()
|
|
882
|
+
const appliedMigrations = await this.getAppliedMigrations()
|
|
883
|
+
|
|
884
|
+
// Sort by version descending and take the last 'count' migrations
|
|
885
|
+
const toRollback = appliedMigrations
|
|
886
|
+
.sort((a, b) => b.version - a.version)
|
|
887
|
+
.slice(0, count)
|
|
888
|
+
|
|
889
|
+
if (toRollback.length === 0) {
|
|
890
|
+
return {
|
|
891
|
+
success: true,
|
|
892
|
+
fromVersion: currentVersion,
|
|
893
|
+
toVersion: currentVersion,
|
|
894
|
+
totalTimeMs: 0,
|
|
895
|
+
results: [],
|
|
896
|
+
migrationsRun: 0,
|
|
897
|
+
migrationsSkipped: 0,
|
|
898
|
+
}
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
// Find the target version (one less than the lowest version to rollback)
|
|
902
|
+
const lowestVersion = Math.min(...toRollback.map(m => m.version))
|
|
903
|
+
const targetVersion = this.migrations
|
|
904
|
+
.filter(m => m.version < lowestVersion)
|
|
905
|
+
.reduce((max, m) => Math.max(max, m.version), 0)
|
|
906
|
+
|
|
907
|
+
return this.rollbackTo(targetVersion, options)
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
async reset(): Promise<void> {
|
|
911
|
+
const lockAcquired = await this.acquireLock()
|
|
912
|
+
if (!lockAcquired) {
|
|
913
|
+
throw new StateError('Failed to acquire migration lock for reset', {
|
|
914
|
+
currentState: 'locked',
|
|
915
|
+
expectedStates: ['unlocked'],
|
|
916
|
+
})
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
try {
|
|
920
|
+
await this.db.exec(`DROP TABLE IF EXISTS ${this.config.metaTableName}`)
|
|
921
|
+
this.cachedVersion = null
|
|
922
|
+
this.isInitialized = false
|
|
923
|
+
this._state = 'uninitialized'
|
|
924
|
+
} finally {
|
|
925
|
+
await this.releaseLock()
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
async validate(): Promise<DOMigrationValidationResult> {
|
|
930
|
+
const issues: DOMigrationValidationIssue[] = []
|
|
931
|
+
|
|
932
|
+
// Check for required fields
|
|
933
|
+
for (const migration of this.migrations) {
|
|
934
|
+
if (typeof migration.version !== 'number' || migration.version < 1) {
|
|
935
|
+
issues.push({
|
|
936
|
+
severity: 'error',
|
|
937
|
+
version: migration.version,
|
|
938
|
+
message: `Migration version must be a positive integer, got: ${migration.version}`,
|
|
939
|
+
suggestion: 'Use a positive integer for the version field',
|
|
940
|
+
})
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
if (!migration.name || typeof migration.name !== 'string') {
|
|
944
|
+
issues.push({
|
|
945
|
+
severity: 'error',
|
|
946
|
+
version: migration.version,
|
|
947
|
+
message: 'Migration name is required and must be a non-empty string',
|
|
948
|
+
suggestion: 'Add a descriptive name for the migration',
|
|
949
|
+
})
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
if (
|
|
953
|
+
migration.up === undefined ||
|
|
954
|
+
(typeof migration.up !== 'string' && typeof migration.up !== 'function')
|
|
955
|
+
) {
|
|
956
|
+
issues.push({
|
|
957
|
+
severity: 'error',
|
|
958
|
+
version: migration.version,
|
|
959
|
+
message: 'Migration up must be a string or function',
|
|
960
|
+
suggestion: 'Provide SQL string or function for the up migration',
|
|
961
|
+
})
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
if (
|
|
965
|
+
migration.down !== undefined &&
|
|
966
|
+
typeof migration.down !== 'string' &&
|
|
967
|
+
typeof migration.down !== 'function'
|
|
968
|
+
) {
|
|
969
|
+
issues.push({
|
|
970
|
+
severity: 'error',
|
|
971
|
+
version: migration.version,
|
|
972
|
+
message: 'Migration down must be a string or function if provided',
|
|
973
|
+
suggestion: 'Provide SQL string or function for the down migration',
|
|
974
|
+
})
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
// Warning for missing down migration
|
|
978
|
+
if (!migration.down && migration.isReversible !== false) {
|
|
979
|
+
issues.push({
|
|
980
|
+
severity: 'warning',
|
|
981
|
+
version: migration.version,
|
|
982
|
+
message: 'Migration has no down migration defined',
|
|
983
|
+
suggestion: 'Add a down migration or set isReversible: false',
|
|
984
|
+
})
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
// Check for duplicate versions
|
|
989
|
+
const versions = new Set<number>()
|
|
990
|
+
for (const migration of this.migrations) {
|
|
991
|
+
if (versions.has(migration.version)) {
|
|
992
|
+
issues.push({
|
|
993
|
+
severity: 'error',
|
|
994
|
+
version: migration.version,
|
|
995
|
+
message: `Duplicate migration version: ${migration.version}`,
|
|
996
|
+
suggestion: 'Use unique version numbers for each migration',
|
|
997
|
+
})
|
|
998
|
+
}
|
|
999
|
+
versions.add(migration.version)
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
// Check for sequential versions (if not allowing gaps)
|
|
1003
|
+
if (!this.config.allowVersionGaps) {
|
|
1004
|
+
const sortedVersions = Array.from(versions).sort((a, b) => a - b)
|
|
1005
|
+
for (let i = 1; i < sortedVersions.length; i++) {
|
|
1006
|
+
const currentVersion = sortedVersions[i]!
|
|
1007
|
+
const previousVersion = sortedVersions[i - 1]!
|
|
1008
|
+
if (currentVersion !== previousVersion + 1) {
|
|
1009
|
+
issues.push({
|
|
1010
|
+
severity: 'warning',
|
|
1011
|
+
version: currentVersion,
|
|
1012
|
+
message: `Gap in version numbers between ${previousVersion} and ${currentVersion}`,
|
|
1013
|
+
suggestion: 'Use sequential version numbers or enable allowVersionGaps config',
|
|
1014
|
+
})
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
// Check for checksum mismatches with applied migrations
|
|
1020
|
+
try {
|
|
1021
|
+
const appliedMigrations = await this.getAppliedMigrations()
|
|
1022
|
+
const appliedByVersion = new Map(appliedMigrations.map(m => [m.version, m]))
|
|
1023
|
+
|
|
1024
|
+
for (const migration of this.migrations) {
|
|
1025
|
+
const applied = appliedByVersion.get(migration.version)
|
|
1026
|
+
if (applied) {
|
|
1027
|
+
const currentChecksum = await calculateChecksum(getMigrationChecksumContent(migration))
|
|
1028
|
+
if (applied.checksum !== currentChecksum) {
|
|
1029
|
+
issues.push({
|
|
1030
|
+
severity: 'error',
|
|
1031
|
+
version: migration.version,
|
|
1032
|
+
message: `Migration ${migration.version} has been modified after being applied`,
|
|
1033
|
+
suggestion: 'Migrations should not be modified after being applied. Create a new migration instead.',
|
|
1034
|
+
})
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
} catch (error) {
|
|
1039
|
+
// Meta table might not exist yet, skip checksum validation
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
const errorCount = issues.filter(i => i.severity === 'error').length
|
|
1043
|
+
const warningCount = issues.filter(i => i.severity === 'warning').length
|
|
1044
|
+
|
|
1045
|
+
return {
|
|
1046
|
+
valid: errorCount === 0,
|
|
1047
|
+
issues,
|
|
1048
|
+
errorCount,
|
|
1049
|
+
warningCount,
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
getMigrations(): DOMigration[] {
|
|
1054
|
+
return [...this.migrations]
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
getLatestVersion(): number {
|
|
1058
|
+
if (this.migrations.length === 0) {
|
|
1059
|
+
return 0
|
|
1060
|
+
}
|
|
1061
|
+
return Math.max(...this.migrations.map(m => m.version))
|
|
1062
|
+
}
|
|
1063
|
+
|
|
1064
|
+
async getAppliedMigrations(): Promise<DOMigrationRecord[]> {
|
|
1065
|
+
if (!this.isInitialized) {
|
|
1066
|
+
await this.initialize()
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
try {
|
|
1070
|
+
const result = await this.db.query<{
|
|
1071
|
+
version: number
|
|
1072
|
+
name: string
|
|
1073
|
+
checksum: string
|
|
1074
|
+
applied_at: string
|
|
1075
|
+
execution_time_ms: number
|
|
1076
|
+
}>(`
|
|
1077
|
+
SELECT version, name, checksum, applied_at, execution_time_ms
|
|
1078
|
+
FROM ${this.config.metaTableName}
|
|
1079
|
+
ORDER BY version ASC
|
|
1080
|
+
`)
|
|
1081
|
+
|
|
1082
|
+
return result.rows.map(row => ({
|
|
1083
|
+
version: row.version,
|
|
1084
|
+
name: row.name,
|
|
1085
|
+
checksum: row.checksum,
|
|
1086
|
+
appliedAt: new Date(row.applied_at),
|
|
1087
|
+
executionTimeMs: row.execution_time_ms,
|
|
1088
|
+
}))
|
|
1089
|
+
} catch (error) {
|
|
1090
|
+
return []
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
onEvent(handler: DOMigrationEventHandler): () => void {
|
|
1095
|
+
this.eventHandlers.add(handler)
|
|
1096
|
+
return () => {
|
|
1097
|
+
this.eventHandlers.delete(handler)
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
// =============================================================================
|
|
1103
|
+
// Factory Functions
|
|
1104
|
+
// =============================================================================
|
|
1105
|
+
|
|
1106
|
+
/**
|
|
1107
|
+
* Create a DO migration runner
|
|
1108
|
+
*
|
|
1109
|
+
* @param db - PGlite database instance
|
|
1110
|
+
* @param migrations - Array of migrations to manage
|
|
1111
|
+
* @param config - Optional configuration for the runner
|
|
1112
|
+
* @returns A configured DOMigrationRunner instance
|
|
1113
|
+
*
|
|
1114
|
+
* @example
|
|
1115
|
+
* ```typescript
|
|
1116
|
+
* import { createDOMigrationRunner } from './do-migrations'
|
|
1117
|
+
*
|
|
1118
|
+
* const migrations = [
|
|
1119
|
+
* {
|
|
1120
|
+
* version: 1,
|
|
1121
|
+
* name: 'create_users_table',
|
|
1122
|
+
* up: `CREATE TABLE users (
|
|
1123
|
+
* id SERIAL PRIMARY KEY,
|
|
1124
|
+
* email TEXT UNIQUE NOT NULL,
|
|
1125
|
+
* created_at TIMESTAMPTZ DEFAULT NOW()
|
|
1126
|
+
* )`,
|
|
1127
|
+
* down: 'DROP TABLE users',
|
|
1128
|
+
* },
|
|
1129
|
+
* {
|
|
1130
|
+
* version: 2,
|
|
1131
|
+
* name: 'add_users_name',
|
|
1132
|
+
* up: 'ALTER TABLE users ADD COLUMN name TEXT',
|
|
1133
|
+
* down: 'ALTER TABLE users DROP COLUMN name',
|
|
1134
|
+
* },
|
|
1135
|
+
* ]
|
|
1136
|
+
*
|
|
1137
|
+
* const runner = createDOMigrationRunner(pglite, migrations, {
|
|
1138
|
+
* metaTableName: '_migrations',
|
|
1139
|
+
* useLocking: true,
|
|
1140
|
+
* })
|
|
1141
|
+
*
|
|
1142
|
+
* // Run all pending migrations
|
|
1143
|
+
* const result = await runner.migrate()
|
|
1144
|
+
* console.log(`Migrated from v${result.fromVersion} to v${result.toVersion}`)
|
|
1145
|
+
* ```
|
|
1146
|
+
*
|
|
1147
|
+
* @example
|
|
1148
|
+
* ```typescript
|
|
1149
|
+
* // With event handlers for logging
|
|
1150
|
+
* const runner = createDOMigrationRunner(pglite, migrations, {
|
|
1151
|
+
* onEvent: (event) => {
|
|
1152
|
+
* if (event.type === 'migration:complete') {
|
|
1153
|
+
* console.log(`Applied migration ${event.version}: ${event.name}`)
|
|
1154
|
+
* }
|
|
1155
|
+
* },
|
|
1156
|
+
* })
|
|
1157
|
+
* ```
|
|
1158
|
+
*/
|
|
1159
|
+
export const createDOMigrationRunner: CreateDOMigrationRunner = (
|
|
1160
|
+
db: PGlite,
|
|
1161
|
+
migrations: DOMigration[],
|
|
1162
|
+
config?: DOMigrationConfig
|
|
1163
|
+
): DOMigrationRunner => {
|
|
1164
|
+
if (!db) {
|
|
1165
|
+
throw new ValidationError('Database instance is required', {
|
|
1166
|
+
code: 'VALIDATION_ERROR',
|
|
1167
|
+
fields: { db: 'Required parameter is missing' },
|
|
1168
|
+
})
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
if (!migrations || !Array.isArray(migrations)) {
|
|
1172
|
+
throw new ValidationError('Migrations array is required', {
|
|
1173
|
+
code: 'VALIDATION_ERROR',
|
|
1174
|
+
fields: { migrations: 'Must be an array' },
|
|
1175
|
+
})
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
return new DOMigrationRunnerImpl(db, migrations, config)
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
/**
|
|
1182
|
+
* Generate a schema snapshot from migrations
|
|
1183
|
+
*
|
|
1184
|
+
* Creates a consolidated schema DDL from a set of migrations for fast
|
|
1185
|
+
* bootstrapping of new Durable Objects.
|
|
1186
|
+
*
|
|
1187
|
+
* @param migrations - Array of migrations to consolidate
|
|
1188
|
+
* @param options - Optional configuration
|
|
1189
|
+
* @returns Schema snapshot with DDL and metadata
|
|
1190
|
+
*
|
|
1191
|
+
* @example
|
|
1192
|
+
* ```typescript
|
|
1193
|
+
* import { generateDOSchemaSnapshot } from './do-migrations'
|
|
1194
|
+
*
|
|
1195
|
+
* const snapshot = await generateDOSchemaSnapshot(migrations, {
|
|
1196
|
+
* includeSeedData: true,
|
|
1197
|
+
* })
|
|
1198
|
+
*
|
|
1199
|
+
* console.log(`Target version: ${snapshot.targetVersion}`)
|
|
1200
|
+
* console.log(`Schema DDL:\n${snapshot.schemaDDL}`)
|
|
1201
|
+
*
|
|
1202
|
+
* // Use with runner for fast bootstrap
|
|
1203
|
+
* const runner = createDOMigrationRunner(pglite, migrations, {
|
|
1204
|
+
* useSnapshot: true,
|
|
1205
|
+
* snapshot,
|
|
1206
|
+
* })
|
|
1207
|
+
* ```
|
|
1208
|
+
*/
|
|
1209
|
+
export const generateDOSchemaSnapshot: GenerateDOSchemaSnapshot = async (
|
|
1210
|
+
migrations: DOMigration[],
|
|
1211
|
+
options?: { includeSeedData?: boolean }
|
|
1212
|
+
): Promise<DOSchemaSnapshot> => {
|
|
1213
|
+
const sortedMigrations = [...migrations].sort((a, b) => a.version - b.version)
|
|
1214
|
+
|
|
1215
|
+
const schemaSQLParts: string[] = []
|
|
1216
|
+
const seedDataSQLParts: string[] = []
|
|
1217
|
+
|
|
1218
|
+
for (const migration of sortedMigrations) {
|
|
1219
|
+
const sql = typeof migration.up === 'string'
|
|
1220
|
+
? migration.up
|
|
1221
|
+
: migration.up.toString()
|
|
1222
|
+
|
|
1223
|
+
// Simple heuristic: seed data migrations often have INSERT statements
|
|
1224
|
+
// and are tagged as 'seed' or 'data'
|
|
1225
|
+
const isSeedData = migration.tags?.includes('seed') || migration.tags?.includes('data')
|
|
1226
|
+
|
|
1227
|
+
if (isSeedData && options?.includeSeedData) {
|
|
1228
|
+
seedDataSQLParts.push(sql)
|
|
1229
|
+
} else {
|
|
1230
|
+
schemaSQLParts.push(sql)
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
const targetVersion = sortedMigrations.length > 0
|
|
1235
|
+
? Math.max(...sortedMigrations.map(m => m.version))
|
|
1236
|
+
: 0
|
|
1237
|
+
|
|
1238
|
+
const migrationsChecksum = await calculateChecksum(
|
|
1239
|
+
sortedMigrations.map(m => getMigrationChecksumContent(m)).join('|')
|
|
1240
|
+
)
|
|
1241
|
+
|
|
1242
|
+
return {
|
|
1243
|
+
targetVersion,
|
|
1244
|
+
schemaDDL: schemaSQLParts.join('\n\n'),
|
|
1245
|
+
migrationsChecksum,
|
|
1246
|
+
includedVersions: sortedMigrations.map(m => m.version),
|
|
1247
|
+
generatedAt: new Date(),
|
|
1248
|
+
...(seedDataSQLParts.length > 0 && { seedDataDDL: seedDataSQLParts.join('\n\n') }),
|
|
1249
|
+
}
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
/**
|
|
1253
|
+
* Convert standard Migration to DOMigration
|
|
1254
|
+
*/
|
|
1255
|
+
export const convertToDOMigration: ConvertToDOMigration = (migration): DOMigration => {
|
|
1256
|
+
return {
|
|
1257
|
+
version: migration.version,
|
|
1258
|
+
name: migration.name,
|
|
1259
|
+
up: migration.up,
|
|
1260
|
+
...(migration.down !== undefined && { down: migration.down }),
|
|
1261
|
+
...(migration.isReversible !== undefined && { isReversible: migration.isReversible }),
|
|
1262
|
+
...(migration.transactional !== undefined && { transactional: migration.transactional }),
|
|
1263
|
+
...(migration.timeoutMs !== undefined && { timeoutMs: migration.timeoutMs }),
|
|
1264
|
+
...(migration.tags !== undefined && { tags: migration.tags }),
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
// =============================================================================
|
|
1269
|
+
// Re-exports
|
|
1270
|
+
// =============================================================================
|
|
1271
|
+
|
|
1272
|
+
export type {
|
|
1273
|
+
DOMigration,
|
|
1274
|
+
DOMigrationRunner,
|
|
1275
|
+
DOMigrationResult,
|
|
1276
|
+
DOMigrationBatchResult,
|
|
1277
|
+
DOMigrationConfig,
|
|
1278
|
+
DOMigrationState,
|
|
1279
|
+
DOSchemaVersion,
|
|
1280
|
+
DOSchemaSnapshot,
|
|
1281
|
+
DOMigrationRecord,
|
|
1282
|
+
DOMigrationEvent,
|
|
1283
|
+
DOMigrationEventType,
|
|
1284
|
+
DOMigrationEventHandler,
|
|
1285
|
+
DORollbackOptions,
|
|
1286
|
+
DOMigrationValidationResult,
|
|
1287
|
+
DOMigrationValidationIssue,
|
|
1288
|
+
MigrationExecutor,
|
|
1289
|
+
}
|