@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,930 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RLS Validator Security Tests
|
|
3
|
+
* RED phase: These tests verify security-critical validation functionality
|
|
4
|
+
*
|
|
5
|
+
* SECURITY CRITICAL: These tests protect against privilege escalation and SQL injection
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
8
|
+
import {
|
|
9
|
+
validatePolicy,
|
|
10
|
+
validatePolicySyntax,
|
|
11
|
+
validateTableName,
|
|
12
|
+
validateTenantId,
|
|
13
|
+
isValidIdentifier,
|
|
14
|
+
needsQuoting,
|
|
15
|
+
quoteIdentifier,
|
|
16
|
+
} from './validator'
|
|
17
|
+
import type { RLSPolicy, PolicyValidationResult, PGliteLike } from './policy'
|
|
18
|
+
|
|
19
|
+
// Mock PGlite interface for testing
|
|
20
|
+
interface MockPGlite {
|
|
21
|
+
exec: ReturnType<typeof vi.fn>
|
|
22
|
+
query: ReturnType<typeof vi.fn>
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const createMockPGlite = (): MockPGlite => ({
|
|
26
|
+
exec: vi.fn(),
|
|
27
|
+
query: vi.fn(),
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
// Helper to create a valid base policy for mutation
|
|
31
|
+
const createBasePolicy = (overrides: Partial<RLSPolicy> = {}): RLSPolicy => ({
|
|
32
|
+
name: 'test_policy',
|
|
33
|
+
table: 'users',
|
|
34
|
+
operation: 'SELECT',
|
|
35
|
+
using: 'user_id = current_user_id()',
|
|
36
|
+
check: undefined,
|
|
37
|
+
roles: ['public'],
|
|
38
|
+
type: 'permissive',
|
|
39
|
+
...overrides,
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
describe('RLS Validator Security Tests', () => {
|
|
43
|
+
describe('SQL Injection Detection', () => {
|
|
44
|
+
describe('Policy Name Injection', () => {
|
|
45
|
+
it('should reject semicolon-based command injection in policy name', () => {
|
|
46
|
+
const policy = createBasePolicy({
|
|
47
|
+
name: 'policy; DROP TABLE users;',
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
const result = validatePolicy(policy)
|
|
51
|
+
|
|
52
|
+
expect(result.valid).toBe(false)
|
|
53
|
+
expect(result.errors.some(e => e.toLowerCase().includes('unsafe'))).toBe(true)
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
it('should reject SQL comment injection (--) in policy name', () => {
|
|
57
|
+
const policy = createBasePolicy({
|
|
58
|
+
name: 'policy-- DROP TABLE users',
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
const result = validatePolicy(policy)
|
|
62
|
+
|
|
63
|
+
expect(result.valid).toBe(false)
|
|
64
|
+
expect(result.errors.some(e => e.toLowerCase().includes('unsafe'))).toBe(true)
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('should reject block comment injection (/*) in policy name', () => {
|
|
68
|
+
const policy = createBasePolicy({
|
|
69
|
+
name: 'policy/* evil */name',
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
const result = validatePolicy(policy)
|
|
73
|
+
|
|
74
|
+
expect(result.valid).toBe(false)
|
|
75
|
+
expect(result.errors.some(e => e.toLowerCase().includes('unsafe'))).toBe(true)
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
it('should reject DROP keyword injection in policy name', () => {
|
|
79
|
+
const policy = createBasePolicy({
|
|
80
|
+
name: 'DROP TABLE users',
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
const result = validatePolicy(policy)
|
|
84
|
+
|
|
85
|
+
expect(result.valid).toBe(false)
|
|
86
|
+
expect(result.errors.some(e => e.toLowerCase().includes('unsafe'))).toBe(true)
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
it('should reject TRUNCATE keyword injection in policy name', () => {
|
|
90
|
+
const policy = createBasePolicy({
|
|
91
|
+
name: 'TRUNCATE users',
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
const result = validatePolicy(policy)
|
|
95
|
+
|
|
96
|
+
expect(result.valid).toBe(false)
|
|
97
|
+
expect(result.errors.some(e => e.toLowerCase().includes('unsafe'))).toBe(true)
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
it('should reject ALTER keyword injection in policy name', () => {
|
|
101
|
+
const policy = createBasePolicy({
|
|
102
|
+
name: 'ALTER TABLE users',
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
const result = validatePolicy(policy)
|
|
106
|
+
|
|
107
|
+
expect(result.valid).toBe(false)
|
|
108
|
+
expect(result.errors.some(e => e.toLowerCase().includes('unsafe'))).toBe(true)
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it('should reject stacked query injection with newlines', () => {
|
|
112
|
+
const policy = createBasePolicy({
|
|
113
|
+
name: 'policy\n; DROP TABLE users;',
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
const result = validatePolicy(policy)
|
|
117
|
+
|
|
118
|
+
expect(result.valid).toBe(false)
|
|
119
|
+
expect(result.errors.some(e => e.toLowerCase().includes('unsafe'))).toBe(true)
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
it('should reject unicode escape injection attempts', () => {
|
|
123
|
+
// Unicode semicolon (U+037E Greek Question Mark)
|
|
124
|
+
const policy = createBasePolicy({
|
|
125
|
+
name: 'policy\u037E DROP TABLE users',
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
const result = validatePolicy(policy)
|
|
129
|
+
|
|
130
|
+
// Should be invalid - either detected as unsafe or as invalid identifier
|
|
131
|
+
expect(result.valid).toBe(false)
|
|
132
|
+
})
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
describe('Table Name Injection', () => {
|
|
136
|
+
it('should reject semicolon injection in table name', () => {
|
|
137
|
+
const policy = createBasePolicy({
|
|
138
|
+
table: 'users; DROP TABLE users;',
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
const result = validatePolicy(policy)
|
|
142
|
+
|
|
143
|
+
expect(result.valid).toBe(false)
|
|
144
|
+
expect(result.errors.some(e => e.toLowerCase().includes('unsafe'))).toBe(true)
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
it('should reject comment injection in table name', () => {
|
|
148
|
+
const policy = createBasePolicy({
|
|
149
|
+
table: 'users--comment',
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
const result = validatePolicy(policy)
|
|
153
|
+
|
|
154
|
+
expect(result.valid).toBe(false)
|
|
155
|
+
expect(result.errors.some(e => e.toLowerCase().includes('unsafe'))).toBe(true)
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
it('should validate table name with validateTableName function', () => {
|
|
159
|
+
expect(validateTableName('users; DROP TABLE x;')).toBe(false)
|
|
160
|
+
expect(validateTableName('users--')).toBe(false)
|
|
161
|
+
expect(validateTableName('users/*evil*/')).toBe(false)
|
|
162
|
+
expect(validateTableName('DROP TABLE users')).toBe(false)
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
it('should allow valid table names', () => {
|
|
166
|
+
expect(validateTableName('users')).toBe(true)
|
|
167
|
+
expect(validateTableName('public.users')).toBe(true)
|
|
168
|
+
expect(validateTableName('my_schema.my_table')).toBe(true)
|
|
169
|
+
expect(validateTableName('table_123')).toBe(true)
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
it('should allow hyphenated table names', () => {
|
|
173
|
+
expect(validateTableName('my-table')).toBe(true)
|
|
174
|
+
expect(validateTableName('public.my-table')).toBe(true)
|
|
175
|
+
})
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
describe('USING Clause Injection', () => {
|
|
179
|
+
it('should reject pg_sleep in USING clause (timing attack)', () => {
|
|
180
|
+
const policy = createBasePolicy({
|
|
181
|
+
using: 'pg_sleep(10) IS NOT NULL',
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
const result = validatePolicy(policy)
|
|
185
|
+
|
|
186
|
+
expect(result.valid).toBe(false)
|
|
187
|
+
expect(result.errors.some(e => e.includes('dangerous function'))).toBe(true)
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
it('should reject pg_cancel_backend in USING clause (DoS)', () => {
|
|
191
|
+
const policy = createBasePolicy({
|
|
192
|
+
using: 'pg_cancel_backend(pg_backend_pid())',
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
const result = validatePolicy(policy)
|
|
196
|
+
|
|
197
|
+
expect(result.valid).toBe(false)
|
|
198
|
+
expect(result.errors.some(e => e.includes('dangerous function'))).toBe(true)
|
|
199
|
+
})
|
|
200
|
+
|
|
201
|
+
it('should reject pg_terminate_backend in USING clause (DoS)', () => {
|
|
202
|
+
const policy = createBasePolicy({
|
|
203
|
+
using: 'pg_terminate_backend(pg_backend_pid())',
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
const result = validatePolicy(policy)
|
|
207
|
+
|
|
208
|
+
expect(result.valid).toBe(false)
|
|
209
|
+
expect(result.errors.some(e => e.includes('dangerous function'))).toBe(true)
|
|
210
|
+
})
|
|
211
|
+
|
|
212
|
+
it('should reject pg_read_file in USING clause (file access)', () => {
|
|
213
|
+
const policy = createBasePolicy({
|
|
214
|
+
using: "pg_read_file('/etc/passwd') IS NOT NULL",
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
const result = validatePolicy(policy)
|
|
218
|
+
|
|
219
|
+
expect(result.valid).toBe(false)
|
|
220
|
+
expect(result.errors.some(e => e.includes('dangerous function'))).toBe(true)
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
it('should reject pg_write_file in USING clause (file write)', () => {
|
|
224
|
+
const policy = createBasePolicy({
|
|
225
|
+
using: "pg_write_file('/tmp/evil', 'data') IS NOT NULL",
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
const result = validatePolicy(policy)
|
|
229
|
+
|
|
230
|
+
expect(result.valid).toBe(false)
|
|
231
|
+
expect(result.errors.some(e => e.includes('dangerous function'))).toBe(true)
|
|
232
|
+
})
|
|
233
|
+
|
|
234
|
+
it('should reject lo_import in USING clause (large object import)', () => {
|
|
235
|
+
const policy = createBasePolicy({
|
|
236
|
+
using: "lo_import('/etc/passwd') IS NOT NULL",
|
|
237
|
+
})
|
|
238
|
+
|
|
239
|
+
const result = validatePolicy(policy)
|
|
240
|
+
|
|
241
|
+
expect(result.valid).toBe(false)
|
|
242
|
+
expect(result.errors.some(e => e.includes('dangerous function'))).toBe(true)
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
it('should reject lo_export in USING clause (large object export)', () => {
|
|
246
|
+
const policy = createBasePolicy({
|
|
247
|
+
using: "lo_export(12345, '/tmp/file') IS NOT NULL",
|
|
248
|
+
})
|
|
249
|
+
|
|
250
|
+
const result = validatePolicy(policy)
|
|
251
|
+
|
|
252
|
+
expect(result.valid).toBe(false)
|
|
253
|
+
expect(result.errors.some(e => e.includes('dangerous function'))).toBe(true)
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
it('should reject dblink in USING clause (remote execution)', () => {
|
|
257
|
+
const policy = createBasePolicy({
|
|
258
|
+
using: "dblink('host=evil.com', 'SELECT 1') IS NOT NULL",
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
const result = validatePolicy(policy)
|
|
262
|
+
|
|
263
|
+
expect(result.valid).toBe(false)
|
|
264
|
+
expect(result.errors.some(e => e.includes('dangerous function'))).toBe(true)
|
|
265
|
+
})
|
|
266
|
+
|
|
267
|
+
it('should reject COPY in USING clause (file I/O)', () => {
|
|
268
|
+
const policy = createBasePolicy({
|
|
269
|
+
using: "copy (SELECT * FROM users) TO '/tmp/users.csv'",
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
const result = validatePolicy(policy)
|
|
273
|
+
|
|
274
|
+
expect(result.valid).toBe(false)
|
|
275
|
+
expect(result.errors.some(e => e.includes('dangerous function'))).toBe(true)
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
it('should detect dangerous functions case-insensitively', () => {
|
|
279
|
+
const variations = [
|
|
280
|
+
'PG_SLEEP(5)',
|
|
281
|
+
'Pg_Sleep(5)',
|
|
282
|
+
'pG_sLeEp(5)',
|
|
283
|
+
]
|
|
284
|
+
|
|
285
|
+
for (const func of variations) {
|
|
286
|
+
const policy = createBasePolicy({
|
|
287
|
+
using: `${func} IS NOT NULL`,
|
|
288
|
+
})
|
|
289
|
+
|
|
290
|
+
const result = validatePolicy(policy)
|
|
291
|
+
|
|
292
|
+
expect(result.valid).toBe(false)
|
|
293
|
+
expect(result.errors.some(e => e.includes('dangerous function'))).toBe(true)
|
|
294
|
+
}
|
|
295
|
+
})
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
describe('CHECK Clause Injection', () => {
|
|
299
|
+
it('should reject pg_sleep in CHECK clause', () => {
|
|
300
|
+
const policy = createBasePolicy({
|
|
301
|
+
operation: 'INSERT',
|
|
302
|
+
using: undefined,
|
|
303
|
+
check: 'pg_sleep(10) IS NOT NULL',
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
const result = validatePolicy(policy)
|
|
307
|
+
|
|
308
|
+
expect(result.valid).toBe(false)
|
|
309
|
+
expect(result.errors.some(e => e.includes('dangerous function'))).toBe(true)
|
|
310
|
+
})
|
|
311
|
+
|
|
312
|
+
it('should reject all dangerous functions in CHECK clause', () => {
|
|
313
|
+
const dangerousFunctions = [
|
|
314
|
+
'pg_cancel_backend(1)',
|
|
315
|
+
'pg_terminate_backend(1)',
|
|
316
|
+
"pg_read_file('/etc/passwd')",
|
|
317
|
+
"pg_write_file('/tmp/x', 'data')",
|
|
318
|
+
"lo_import('/etc/passwd')",
|
|
319
|
+
"lo_export(1, '/tmp/x')",
|
|
320
|
+
"dblink('host=x', 'SELECT 1')",
|
|
321
|
+
"copy (SELECT 1) TO '/tmp/x'",
|
|
322
|
+
]
|
|
323
|
+
|
|
324
|
+
for (const func of dangerousFunctions) {
|
|
325
|
+
const policy = createBasePolicy({
|
|
326
|
+
operation: 'INSERT',
|
|
327
|
+
using: undefined,
|
|
328
|
+
check: `${func} IS NOT NULL`,
|
|
329
|
+
})
|
|
330
|
+
|
|
331
|
+
const result = validatePolicy(policy)
|
|
332
|
+
|
|
333
|
+
expect(result.valid).toBe(false)
|
|
334
|
+
expect(result.errors.some(e => e.includes('dangerous function'))).toBe(true)
|
|
335
|
+
}
|
|
336
|
+
})
|
|
337
|
+
})
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
describe('Policy Expression Validation', () => {
|
|
341
|
+
describe('USING Clause Requirements', () => {
|
|
342
|
+
it('should require USING clause for SELECT policy', () => {
|
|
343
|
+
const policy = createBasePolicy({
|
|
344
|
+
operation: 'SELECT',
|
|
345
|
+
using: undefined,
|
|
346
|
+
})
|
|
347
|
+
|
|
348
|
+
const result = validatePolicy(policy)
|
|
349
|
+
|
|
350
|
+
expect(result.valid).toBe(false)
|
|
351
|
+
expect(result.errors).toContain('SELECT policy requires USING clause')
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
it('should require USING clause for DELETE policy', () => {
|
|
355
|
+
const policy = createBasePolicy({
|
|
356
|
+
operation: 'DELETE',
|
|
357
|
+
using: undefined,
|
|
358
|
+
})
|
|
359
|
+
|
|
360
|
+
const result = validatePolicy(policy)
|
|
361
|
+
|
|
362
|
+
expect(result.valid).toBe(false)
|
|
363
|
+
expect(result.errors).toContain('DELETE policy requires USING clause')
|
|
364
|
+
})
|
|
365
|
+
})
|
|
366
|
+
|
|
367
|
+
describe('CHECK Clause Requirements', () => {
|
|
368
|
+
it('should require CHECK clause for INSERT policy', () => {
|
|
369
|
+
const policy = createBasePolicy({
|
|
370
|
+
operation: 'INSERT',
|
|
371
|
+
using: undefined,
|
|
372
|
+
check: undefined,
|
|
373
|
+
})
|
|
374
|
+
|
|
375
|
+
const result = validatePolicy(policy)
|
|
376
|
+
|
|
377
|
+
expect(result.valid).toBe(false)
|
|
378
|
+
expect(result.errors).toContain('INSERT policy requires WITH CHECK clause')
|
|
379
|
+
})
|
|
380
|
+
})
|
|
381
|
+
|
|
382
|
+
describe('Expression Syntax Validation', () => {
|
|
383
|
+
let mockPGlite: MockPGlite
|
|
384
|
+
|
|
385
|
+
beforeEach(() => {
|
|
386
|
+
mockPGlite = createMockPGlite()
|
|
387
|
+
})
|
|
388
|
+
|
|
389
|
+
it('should validate correct SQL expression syntax', async () => {
|
|
390
|
+
mockPGlite.exec.mockResolvedValue(undefined)
|
|
391
|
+
mockPGlite.query.mockResolvedValue({ rows: [{ result: 'boolean' }] })
|
|
392
|
+
|
|
393
|
+
const result = await validatePolicySyntax(
|
|
394
|
+
mockPGlite,
|
|
395
|
+
"user_id = current_setting('app.user_id')::uuid"
|
|
396
|
+
)
|
|
397
|
+
|
|
398
|
+
expect(result.valid).toBe(true)
|
|
399
|
+
expect(result.errors).toHaveLength(0)
|
|
400
|
+
})
|
|
401
|
+
|
|
402
|
+
it('should reject invalid SQL syntax', async () => {
|
|
403
|
+
mockPGlite.exec.mockRejectedValue(new Error('syntax error'))
|
|
404
|
+
|
|
405
|
+
const result = await validatePolicySyntax(
|
|
406
|
+
mockPGlite,
|
|
407
|
+
'INVALID!!! SYNTAX @@@'
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
expect(result.valid).toBe(false)
|
|
411
|
+
expect(result.errors).toContain('Invalid SQL syntax')
|
|
412
|
+
})
|
|
413
|
+
|
|
414
|
+
it('should reject expressions that do not return boolean', async () => {
|
|
415
|
+
mockPGlite.exec.mockResolvedValue(undefined)
|
|
416
|
+
mockPGlite.query.mockResolvedValue({ rows: [{ result: 'integer' }] })
|
|
417
|
+
|
|
418
|
+
const result = await validatePolicySyntax(
|
|
419
|
+
mockPGlite,
|
|
420
|
+
'1 + 1'
|
|
421
|
+
)
|
|
422
|
+
|
|
423
|
+
expect(result.valid).toBe(false)
|
|
424
|
+
expect(result.errors.some(e => e.includes('must return boolean'))).toBe(true)
|
|
425
|
+
})
|
|
426
|
+
|
|
427
|
+
it('should detect arithmetic expressions as non-boolean', async () => {
|
|
428
|
+
mockPGlite.exec.mockResolvedValue(undefined)
|
|
429
|
+
// Even if pg_typeof somehow returns 'boolean', arithmetic should be caught
|
|
430
|
+
mockPGlite.query.mockResolvedValue({ rows: [{ result: 'boolean' }] })
|
|
431
|
+
|
|
432
|
+
const result = await validatePolicySyntax(
|
|
433
|
+
mockPGlite,
|
|
434
|
+
'2 * 3'
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
expect(result.valid).toBe(false)
|
|
438
|
+
expect(result.errors.some(e => e.includes('must return boolean'))).toBe(true)
|
|
439
|
+
})
|
|
440
|
+
})
|
|
441
|
+
})
|
|
442
|
+
|
|
443
|
+
describe('User Role Reference Validation', () => {
|
|
444
|
+
describe('Role Name Validation in Policy', () => {
|
|
445
|
+
it('should accept valid role names', () => {
|
|
446
|
+
const policy = createBasePolicy({
|
|
447
|
+
roles: ['admin', 'readonly_user', 'app_user_123'],
|
|
448
|
+
})
|
|
449
|
+
|
|
450
|
+
const result = validatePolicy(policy)
|
|
451
|
+
|
|
452
|
+
expect(result.valid).toBe(true)
|
|
453
|
+
})
|
|
454
|
+
|
|
455
|
+
it('should detect SQL injection attempts in role names', () => {
|
|
456
|
+
// This test verifies that malicious role names are caught
|
|
457
|
+
const policy = createBasePolicy({
|
|
458
|
+
roles: ["admin'; DROP TABLE users;--"],
|
|
459
|
+
})
|
|
460
|
+
|
|
461
|
+
const result = validatePolicy(policy)
|
|
462
|
+
|
|
463
|
+
// Role injection should be detected
|
|
464
|
+
// If not currently implemented, this test should FAIL (RED phase)
|
|
465
|
+
expect(result.valid).toBe(false)
|
|
466
|
+
expect(result.errors.some(e => e.toLowerCase().includes('role') || e.toLowerCase().includes('unsafe'))).toBe(true)
|
|
467
|
+
})
|
|
468
|
+
|
|
469
|
+
it('should detect semicolon injection in role names', () => {
|
|
470
|
+
const policy = createBasePolicy({
|
|
471
|
+
roles: ['admin; DROP DATABASE postgres'],
|
|
472
|
+
})
|
|
473
|
+
|
|
474
|
+
const result = validatePolicy(policy)
|
|
475
|
+
|
|
476
|
+
expect(result.valid).toBe(false)
|
|
477
|
+
})
|
|
478
|
+
|
|
479
|
+
it('should detect comment injection in role names', () => {
|
|
480
|
+
const policy = createBasePolicy({
|
|
481
|
+
roles: ['admin--evil'],
|
|
482
|
+
})
|
|
483
|
+
|
|
484
|
+
const result = validatePolicy(policy)
|
|
485
|
+
|
|
486
|
+
expect(result.valid).toBe(false)
|
|
487
|
+
})
|
|
488
|
+
|
|
489
|
+
it('should validate role names contain only safe characters', () => {
|
|
490
|
+
const policy = createBasePolicy({
|
|
491
|
+
roles: ['admin<script>alert(1)</script>'],
|
|
492
|
+
})
|
|
493
|
+
|
|
494
|
+
const result = validatePolicy(policy)
|
|
495
|
+
|
|
496
|
+
expect(result.valid).toBe(false)
|
|
497
|
+
})
|
|
498
|
+
})
|
|
499
|
+
})
|
|
500
|
+
|
|
501
|
+
describe('Malicious Policy Expression Rejection', () => {
|
|
502
|
+
describe('Privilege Escalation Attempts', () => {
|
|
503
|
+
it('should reject policy that always returns true (bypass attempt)', () => {
|
|
504
|
+
const policy = createBasePolicy({
|
|
505
|
+
using: 'true',
|
|
506
|
+
})
|
|
507
|
+
|
|
508
|
+
const result = validatePolicy(policy)
|
|
509
|
+
|
|
510
|
+
// Should at least warn about this
|
|
511
|
+
expect(result.warnings.some(w => w.includes('true') && w.includes('all rows'))).toBe(true)
|
|
512
|
+
})
|
|
513
|
+
|
|
514
|
+
it('should reject policy with 1=1 bypass pattern', () => {
|
|
515
|
+
const policy = createBasePolicy({
|
|
516
|
+
using: '1=1',
|
|
517
|
+
})
|
|
518
|
+
|
|
519
|
+
const result = validatePolicy(policy)
|
|
520
|
+
|
|
521
|
+
// This is a common SQL injection pattern that bypasses security
|
|
522
|
+
// Should be detected as potentially dangerous
|
|
523
|
+
expect(result.warnings.length > 0 || !result.valid).toBe(true)
|
|
524
|
+
})
|
|
525
|
+
|
|
526
|
+
it('should reject policy with OR-based bypass', () => {
|
|
527
|
+
const policy = createBasePolicy({
|
|
528
|
+
using: "user_id = 1 OR 'x'='x'",
|
|
529
|
+
})
|
|
530
|
+
|
|
531
|
+
const result = validatePolicy(policy)
|
|
532
|
+
|
|
533
|
+
// OR with always-true condition is a bypass attempt
|
|
534
|
+
expect(result.warnings.length > 0 || !result.valid).toBe(true)
|
|
535
|
+
})
|
|
536
|
+
|
|
537
|
+
it('should detect GRANT statements embedded in expressions', () => {
|
|
538
|
+
const policy = createBasePolicy({
|
|
539
|
+
using: "GRANT ALL ON users TO PUBLIC",
|
|
540
|
+
})
|
|
541
|
+
|
|
542
|
+
const result = validatePolicy(policy)
|
|
543
|
+
|
|
544
|
+
// GRANT should be detected as dangerous
|
|
545
|
+
expect(result.valid).toBe(false)
|
|
546
|
+
})
|
|
547
|
+
|
|
548
|
+
it('should detect CREATE USER in expressions', () => {
|
|
549
|
+
const policy = createBasePolicy({
|
|
550
|
+
using: "CREATE USER hacker WITH SUPERUSER",
|
|
551
|
+
})
|
|
552
|
+
|
|
553
|
+
const result = validatePolicy(policy)
|
|
554
|
+
|
|
555
|
+
expect(result.valid).toBe(false)
|
|
556
|
+
})
|
|
557
|
+
|
|
558
|
+
it('should detect ALTER ROLE in expressions', () => {
|
|
559
|
+
const policy = createBasePolicy({
|
|
560
|
+
using: "ALTER ROLE postgres WITH SUPERUSER",
|
|
561
|
+
})
|
|
562
|
+
|
|
563
|
+
const result = validatePolicy(policy)
|
|
564
|
+
|
|
565
|
+
expect(result.valid).toBe(false)
|
|
566
|
+
expect(result.errors.some(e => e.toLowerCase().includes('unsafe') || e.toLowerCase().includes('alter'))).toBe(true)
|
|
567
|
+
})
|
|
568
|
+
})
|
|
569
|
+
|
|
570
|
+
describe('Information Disclosure Attempts', () => {
|
|
571
|
+
it('should detect pg_catalog access attempts', () => {
|
|
572
|
+
const policy = createBasePolicy({
|
|
573
|
+
using: "EXISTS (SELECT 1 FROM pg_catalog.pg_shadow)",
|
|
574
|
+
})
|
|
575
|
+
|
|
576
|
+
const result = validatePolicy(policy)
|
|
577
|
+
|
|
578
|
+
// Access to pg_catalog.pg_shadow exposes password hashes
|
|
579
|
+
expect(result.warnings.length > 0).toBe(true) // At least warn about subquery
|
|
580
|
+
})
|
|
581
|
+
|
|
582
|
+
it('should warn about information_schema access', () => {
|
|
583
|
+
const policy = createBasePolicy({
|
|
584
|
+
using: "EXISTS (SELECT 1 FROM information_schema.columns)",
|
|
585
|
+
})
|
|
586
|
+
|
|
587
|
+
const result = validatePolicy(policy)
|
|
588
|
+
|
|
589
|
+
// Should at least warn about subquery
|
|
590
|
+
expect(result.warnings.some(w => w.includes('subquery'))).toBe(true)
|
|
591
|
+
})
|
|
592
|
+
})
|
|
593
|
+
|
|
594
|
+
describe('Denial of Service Attempts', () => {
|
|
595
|
+
it('should reject infinite recursion patterns', () => {
|
|
596
|
+
const policy = createBasePolicy({
|
|
597
|
+
using: "EXISTS (WITH RECURSIVE inf AS (SELECT 1 UNION ALL SELECT n+1 FROM inf) SELECT * FROM inf)",
|
|
598
|
+
})
|
|
599
|
+
|
|
600
|
+
const result = validatePolicy(policy)
|
|
601
|
+
|
|
602
|
+
// Recursive CTEs can cause infinite loops
|
|
603
|
+
expect(result.warnings.some(w => w.includes('subquery')) || !result.valid).toBe(true)
|
|
604
|
+
})
|
|
605
|
+
|
|
606
|
+
it('should reject generate_series abuse', () => {
|
|
607
|
+
const policy = createBasePolicy({
|
|
608
|
+
using: "EXISTS (SELECT * FROM generate_series(1, 1000000000))",
|
|
609
|
+
})
|
|
610
|
+
|
|
611
|
+
const result = validatePolicy(policy)
|
|
612
|
+
|
|
613
|
+
// Should at least warn about subquery
|
|
614
|
+
expect(result.warnings.length > 0).toBe(true)
|
|
615
|
+
})
|
|
616
|
+
})
|
|
617
|
+
})
|
|
618
|
+
|
|
619
|
+
describe('Policy Syntax Edge Cases', () => {
|
|
620
|
+
describe('Identifier Edge Cases', () => {
|
|
621
|
+
it('should validate identifiers starting with underscore', () => {
|
|
622
|
+
expect(isValidIdentifier('_private_table')).toBe(true)
|
|
623
|
+
})
|
|
624
|
+
|
|
625
|
+
it('should reject identifiers starting with numbers', () => {
|
|
626
|
+
expect(isValidIdentifier('123table')).toBe(false)
|
|
627
|
+
})
|
|
628
|
+
|
|
629
|
+
it('should reject identifiers with special characters', () => {
|
|
630
|
+
expect(isValidIdentifier('table@name')).toBe(false)
|
|
631
|
+
expect(isValidIdentifier('table$name')).toBe(false)
|
|
632
|
+
expect(isValidIdentifier('table#name')).toBe(false)
|
|
633
|
+
})
|
|
634
|
+
|
|
635
|
+
it('should allow schema-qualified identifiers', () => {
|
|
636
|
+
expect(isValidIdentifier('public.users')).toBe(true)
|
|
637
|
+
expect(isValidIdentifier('my_schema.my_table')).toBe(true)
|
|
638
|
+
})
|
|
639
|
+
|
|
640
|
+
it('should reject multiple dots in identifier', () => {
|
|
641
|
+
// public.schema.table should be handled differently
|
|
642
|
+
expect(isValidIdentifier('a.b.c')).toBe(false)
|
|
643
|
+
})
|
|
644
|
+
|
|
645
|
+
it('should reject empty identifiers', () => {
|
|
646
|
+
expect(isValidIdentifier('')).toBe(false)
|
|
647
|
+
})
|
|
648
|
+
|
|
649
|
+
it('should reject whitespace-only identifiers', () => {
|
|
650
|
+
expect(isValidIdentifier(' ')).toBe(false)
|
|
651
|
+
})
|
|
652
|
+
})
|
|
653
|
+
|
|
654
|
+
describe('Quoting Edge Cases', () => {
|
|
655
|
+
it('should identify identifiers needing quoting', () => {
|
|
656
|
+
expect(needsQuoting('my-table')).toBe(true)
|
|
657
|
+
expect(needsQuoting('table name')).toBe(true)
|
|
658
|
+
expect(needsQuoting('123start')).toBe(true)
|
|
659
|
+
})
|
|
660
|
+
|
|
661
|
+
it('should not require quoting for valid identifiers', () => {
|
|
662
|
+
expect(needsQuoting('users')).toBe(false)
|
|
663
|
+
expect(needsQuoting('my_table')).toBe(false)
|
|
664
|
+
expect(needsQuoting('_private')).toBe(false)
|
|
665
|
+
})
|
|
666
|
+
|
|
667
|
+
it('should quote identifiers with hyphens', () => {
|
|
668
|
+
expect(quoteIdentifier('my-table')).toBe('"my-table"')
|
|
669
|
+
})
|
|
670
|
+
|
|
671
|
+
it('should quote identifiers with spaces', () => {
|
|
672
|
+
expect(quoteIdentifier('my table')).toBe('"my table"')
|
|
673
|
+
})
|
|
674
|
+
|
|
675
|
+
it('should not double-quote already valid identifiers', () => {
|
|
676
|
+
expect(quoteIdentifier('users')).toBe('users')
|
|
677
|
+
})
|
|
678
|
+
})
|
|
679
|
+
|
|
680
|
+
describe('Policy Name Edge Cases', () => {
|
|
681
|
+
it('should reject empty policy name', () => {
|
|
682
|
+
const policy = createBasePolicy({ name: '' })
|
|
683
|
+
|
|
684
|
+
const result = validatePolicy(policy)
|
|
685
|
+
|
|
686
|
+
expect(result.valid).toBe(false)
|
|
687
|
+
expect(result.errors).toContain('Policy name cannot be empty')
|
|
688
|
+
})
|
|
689
|
+
|
|
690
|
+
it('should reject whitespace-only policy name', () => {
|
|
691
|
+
const policy = createBasePolicy({ name: ' ' })
|
|
692
|
+
|
|
693
|
+
const result = validatePolicy(policy)
|
|
694
|
+
|
|
695
|
+
expect(result.valid).toBe(false)
|
|
696
|
+
expect(result.errors).toContain('Policy name cannot be empty')
|
|
697
|
+
})
|
|
698
|
+
|
|
699
|
+
it('should reject policy name exceeding 63 characters', () => {
|
|
700
|
+
const policy = createBasePolicy({ name: 'a'.repeat(64) })
|
|
701
|
+
|
|
702
|
+
const result = validatePolicy(policy)
|
|
703
|
+
|
|
704
|
+
expect(result.valid).toBe(false)
|
|
705
|
+
expect(result.errors.some(e => e.includes('too long'))).toBe(true)
|
|
706
|
+
})
|
|
707
|
+
|
|
708
|
+
it('should allow policy name of exactly 63 characters', () => {
|
|
709
|
+
const policy = createBasePolicy({ name: 'a'.repeat(63) })
|
|
710
|
+
|
|
711
|
+
const result = validatePolicy(policy)
|
|
712
|
+
|
|
713
|
+
expect(result.errors.some(e => e.includes('too long'))).toBe(false)
|
|
714
|
+
})
|
|
715
|
+
|
|
716
|
+
it('should warn about reserved SQL keywords as policy names', () => {
|
|
717
|
+
const keywords = ['select', 'insert', 'update', 'delete', 'table', 'policy']
|
|
718
|
+
|
|
719
|
+
for (const keyword of keywords) {
|
|
720
|
+
const policy = createBasePolicy({ name: keyword })
|
|
721
|
+
|
|
722
|
+
const result = validatePolicy(policy)
|
|
723
|
+
|
|
724
|
+
expect(result.warnings.some(w => w.includes('reserved'))).toBe(true)
|
|
725
|
+
}
|
|
726
|
+
})
|
|
727
|
+
|
|
728
|
+
it('should allow quoted policy names starting with numbers', () => {
|
|
729
|
+
const policy = createBasePolicy({ name: '"123policy"' })
|
|
730
|
+
|
|
731
|
+
const result = validatePolicy(policy)
|
|
732
|
+
|
|
733
|
+
// Quoted names starting with numbers should be allowed
|
|
734
|
+
expect(result.errors.some(e => e.includes('must start with'))).toBe(false)
|
|
735
|
+
})
|
|
736
|
+
})
|
|
737
|
+
|
|
738
|
+
describe('Table Name Edge Cases', () => {
|
|
739
|
+
it('should reject empty table name', () => {
|
|
740
|
+
const policy = createBasePolicy({ table: '' })
|
|
741
|
+
|
|
742
|
+
const result = validatePolicy(policy)
|
|
743
|
+
|
|
744
|
+
expect(result.valid).toBe(false)
|
|
745
|
+
expect(result.errors).toContain('Table name cannot be empty')
|
|
746
|
+
})
|
|
747
|
+
|
|
748
|
+
it('should reject whitespace-only table name', () => {
|
|
749
|
+
const policy = createBasePolicy({ table: ' ' })
|
|
750
|
+
|
|
751
|
+
const result = validatePolicy(policy)
|
|
752
|
+
|
|
753
|
+
expect(result.valid).toBe(false)
|
|
754
|
+
expect(result.errors).toContain('Table name cannot be empty')
|
|
755
|
+
})
|
|
756
|
+
|
|
757
|
+
it('should warn about reserved keywords as table names', () => {
|
|
758
|
+
const policy = createBasePolicy({ table: 'order' })
|
|
759
|
+
|
|
760
|
+
const result = validatePolicy(policy)
|
|
761
|
+
|
|
762
|
+
expect(result.warnings.some(w => w.includes('reserved'))).toBe(true)
|
|
763
|
+
})
|
|
764
|
+
|
|
765
|
+
it('should warn about schema-qualified reserved keywords', () => {
|
|
766
|
+
const policy = createBasePolicy({ table: 'public.order' })
|
|
767
|
+
|
|
768
|
+
const result = validatePolicy(policy)
|
|
769
|
+
|
|
770
|
+
expect(result.warnings.some(w => w.includes('reserved'))).toBe(true)
|
|
771
|
+
})
|
|
772
|
+
})
|
|
773
|
+
})
|
|
774
|
+
|
|
775
|
+
describe('Tenant ID Validation', () => {
|
|
776
|
+
describe('validateTenantId()', () => {
|
|
777
|
+
it('should accept valid alphanumeric tenant IDs', () => {
|
|
778
|
+
expect(validateTenantId('tenant123')).toBe(true)
|
|
779
|
+
expect(validateTenantId('TENANT_ABC')).toBe(true)
|
|
780
|
+
expect(validateTenantId('tenant-id-123')).toBe(true)
|
|
781
|
+
})
|
|
782
|
+
|
|
783
|
+
it('should accept UUID-like tenant IDs', () => {
|
|
784
|
+
expect(validateTenantId('550e8400-e29b-41d4-a716-446655440000')).toBe(true)
|
|
785
|
+
})
|
|
786
|
+
|
|
787
|
+
it('should reject tenant IDs with SQL injection patterns', () => {
|
|
788
|
+
expect(validateTenantId("tenant'; DROP TABLE users;--")).toBe(false)
|
|
789
|
+
expect(validateTenantId("tenant; DELETE FROM users")).toBe(false)
|
|
790
|
+
expect(validateTenantId("tenant/* evil */")).toBe(false)
|
|
791
|
+
})
|
|
792
|
+
|
|
793
|
+
it('should reject tenant IDs with special characters', () => {
|
|
794
|
+
expect(validateTenantId("tenant'id")).toBe(false)
|
|
795
|
+
expect(validateTenantId('tenant"id')).toBe(false)
|
|
796
|
+
expect(validateTenantId('tenant;id')).toBe(false)
|
|
797
|
+
expect(validateTenantId('tenant=id')).toBe(false)
|
|
798
|
+
expect(validateTenantId('tenant(id)')).toBe(false)
|
|
799
|
+
})
|
|
800
|
+
|
|
801
|
+
it('should reject empty tenant ID', () => {
|
|
802
|
+
expect(validateTenantId('')).toBe(false)
|
|
803
|
+
})
|
|
804
|
+
|
|
805
|
+
it('should reject tenant ID with only whitespace', () => {
|
|
806
|
+
expect(validateTenantId(' ')).toBe(false)
|
|
807
|
+
})
|
|
808
|
+
|
|
809
|
+
it('should reject tenant ID with newlines', () => {
|
|
810
|
+
expect(validateTenantId("tenant\nid")).toBe(false)
|
|
811
|
+
expect(validateTenantId("tenant\r\nid")).toBe(false)
|
|
812
|
+
})
|
|
813
|
+
|
|
814
|
+
it('should reject tenant ID with null bytes', () => {
|
|
815
|
+
expect(validateTenantId("tenant\x00id")).toBe(false)
|
|
816
|
+
})
|
|
817
|
+
})
|
|
818
|
+
})
|
|
819
|
+
|
|
820
|
+
describe('Cross-cutting Security Concerns', () => {
|
|
821
|
+
describe('Unicode and Encoding Attacks', () => {
|
|
822
|
+
it('should handle homoglyph attacks in policy names', () => {
|
|
823
|
+
// Using Cyrillic 'а' (U+0430) instead of Latin 'a'
|
|
824
|
+
const policy = createBasePolicy({ name: 'polic\u0430' })
|
|
825
|
+
|
|
826
|
+
const result = validatePolicy(policy)
|
|
827
|
+
|
|
828
|
+
// Should either reject or handle properly
|
|
829
|
+
expect(result.valid).toBe(false)
|
|
830
|
+
})
|
|
831
|
+
|
|
832
|
+
it('should handle zero-width characters in policy names', () => {
|
|
833
|
+
// Zero-width space (U+200B)
|
|
834
|
+
const policy = createBasePolicy({ name: 'policy\u200Bname' })
|
|
835
|
+
|
|
836
|
+
const result = validatePolicy(policy)
|
|
837
|
+
|
|
838
|
+
// Should reject invisible characters
|
|
839
|
+
expect(result.valid).toBe(false)
|
|
840
|
+
})
|
|
841
|
+
|
|
842
|
+
it('should handle right-to-left override in policy names', () => {
|
|
843
|
+
// Right-to-left override (U+202E)
|
|
844
|
+
const policy = createBasePolicy({ name: 'policy\u202Ename' })
|
|
845
|
+
|
|
846
|
+
const result = validatePolicy(policy)
|
|
847
|
+
|
|
848
|
+
// Should reject RTL override
|
|
849
|
+
expect(result.valid).toBe(false)
|
|
850
|
+
})
|
|
851
|
+
})
|
|
852
|
+
|
|
853
|
+
describe('Null Byte Injection', () => {
|
|
854
|
+
it('should reject null bytes in policy name', () => {
|
|
855
|
+
const policy = createBasePolicy({ name: 'policy\x00evil' })
|
|
856
|
+
|
|
857
|
+
const result = validatePolicy(policy)
|
|
858
|
+
|
|
859
|
+
expect(result.valid).toBe(false)
|
|
860
|
+
})
|
|
861
|
+
|
|
862
|
+
it('should reject null bytes in table name', () => {
|
|
863
|
+
const policy = createBasePolicy({ table: 'users\x00evil' })
|
|
864
|
+
|
|
865
|
+
const result = validatePolicy(policy)
|
|
866
|
+
|
|
867
|
+
expect(result.valid).toBe(false)
|
|
868
|
+
})
|
|
869
|
+
|
|
870
|
+
it('should reject null bytes in USING clause', () => {
|
|
871
|
+
const policy = createBasePolicy({ using: "user_id = '\x00evil'" })
|
|
872
|
+
|
|
873
|
+
const result = validatePolicy(policy)
|
|
874
|
+
|
|
875
|
+
// Null bytes in expressions should be caught
|
|
876
|
+
expect(result.valid).toBe(false)
|
|
877
|
+
})
|
|
878
|
+
})
|
|
879
|
+
|
|
880
|
+
describe('Case Sensitivity Handling', () => {
|
|
881
|
+
it('should detect dangerous functions regardless of case', () => {
|
|
882
|
+
const cases = ['PG_SLEEP', 'pg_Sleep', 'Pg_SLEEP', 'pG_sLeEp']
|
|
883
|
+
|
|
884
|
+
for (const fn of cases) {
|
|
885
|
+
const policy = createBasePolicy({ using: `${fn}(1) IS NOT NULL` })
|
|
886
|
+
|
|
887
|
+
const result = validatePolicy(policy)
|
|
888
|
+
|
|
889
|
+
expect(result.valid).toBe(false)
|
|
890
|
+
expect(result.errors.some(e => e.includes('dangerous function'))).toBe(true)
|
|
891
|
+
}
|
|
892
|
+
})
|
|
893
|
+
|
|
894
|
+
it('should detect SQL keywords regardless of case', () => {
|
|
895
|
+
const keywords = ['DROP', 'drop', 'Drop', 'dRoP']
|
|
896
|
+
|
|
897
|
+
for (const kw of keywords) {
|
|
898
|
+
const policy = createBasePolicy({ name: `${kw} TABLE users` })
|
|
899
|
+
|
|
900
|
+
const result = validatePolicy(policy)
|
|
901
|
+
|
|
902
|
+
expect(result.valid).toBe(false)
|
|
903
|
+
}
|
|
904
|
+
})
|
|
905
|
+
})
|
|
906
|
+
|
|
907
|
+
describe('Multi-line and Whitespace Attacks', () => {
|
|
908
|
+
it('should detect injection attempts split across lines', () => {
|
|
909
|
+
const policy = createBasePolicy({
|
|
910
|
+
name: `policy
|
|
911
|
+
; DROP TABLE users`,
|
|
912
|
+
})
|
|
913
|
+
|
|
914
|
+
const result = validatePolicy(policy)
|
|
915
|
+
|
|
916
|
+
expect(result.valid).toBe(false)
|
|
917
|
+
})
|
|
918
|
+
|
|
919
|
+
it('should detect tab-separated injection', () => {
|
|
920
|
+
const policy = createBasePolicy({
|
|
921
|
+
name: 'policy\t; DROP TABLE users',
|
|
922
|
+
})
|
|
923
|
+
|
|
924
|
+
const result = validatePolicy(policy)
|
|
925
|
+
|
|
926
|
+
expect(result.valid).toBe(false)
|
|
927
|
+
})
|
|
928
|
+
})
|
|
929
|
+
})
|
|
930
|
+
})
|