@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,829 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RLS Generator Security Tests
|
|
3
|
+
*
|
|
4
|
+
* RED phase: These tests verify security-critical aspects of the RLS generator.
|
|
5
|
+
* SECURITY CRITICAL: These tests protect against unauthorized data access.
|
|
6
|
+
*
|
|
7
|
+
* Tests verify:
|
|
8
|
+
* 1. Generated policies are syntactically correct
|
|
9
|
+
* 2. Policies cannot be bypassed
|
|
10
|
+
* 3. USING and WITH CHECK clauses are correct
|
|
11
|
+
* 4. Multi-tenant isolation is enforced
|
|
12
|
+
* 5. Generated SQL is injection-safe
|
|
13
|
+
*/
|
|
14
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest'
|
|
15
|
+
import {
|
|
16
|
+
generatePolicySQL,
|
|
17
|
+
generateDropPolicySQL,
|
|
18
|
+
generateEnableRLSSQL,
|
|
19
|
+
generateDisableRLSSQL,
|
|
20
|
+
applyPolicy,
|
|
21
|
+
enableRLS,
|
|
22
|
+
disableRLS,
|
|
23
|
+
dropPolicy,
|
|
24
|
+
} from './generator'
|
|
25
|
+
import { createPolicy, createTenantPolicy, type RLSPolicy } from './policy'
|
|
26
|
+
|
|
27
|
+
// Mock PGlite interface for testing
|
|
28
|
+
interface MockPGlite {
|
|
29
|
+
exec: ReturnType<typeof vi.fn>
|
|
30
|
+
query: ReturnType<typeof vi.fn>
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const createMockPGlite = (): MockPGlite => ({
|
|
34
|
+
exec: vi.fn(),
|
|
35
|
+
query: vi.fn(),
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
describe('RLS Generator Security Tests', () => {
|
|
39
|
+
/**
|
|
40
|
+
* SECTION 1: Syntactically Correct Policy Generation
|
|
41
|
+
* Verifies that generated SQL is valid PostgreSQL syntax
|
|
42
|
+
*/
|
|
43
|
+
describe('Syntactic Correctness', () => {
|
|
44
|
+
it('should generate valid CREATE POLICY syntax for SELECT', () => {
|
|
45
|
+
const policy = createPolicy({
|
|
46
|
+
name: 'users_read_own',
|
|
47
|
+
table: 'users',
|
|
48
|
+
operation: 'SELECT',
|
|
49
|
+
using: "user_id = current_setting('app.user_id')::uuid",
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
const sql = generatePolicySQL(policy)
|
|
53
|
+
|
|
54
|
+
// Must match PostgreSQL CREATE POLICY syntax exactly
|
|
55
|
+
expect(sql).toMatch(/^CREATE POLICY\s+/)
|
|
56
|
+
expect(sql).toMatch(/\bON\s+users\b/)
|
|
57
|
+
expect(sql).toMatch(/\bAS\s+(PERMISSIVE|RESTRICTIVE)\b/)
|
|
58
|
+
expect(sql).toMatch(/\bFOR\s+SELECT\b/)
|
|
59
|
+
expect(sql).toMatch(/\bTO\s+/)
|
|
60
|
+
expect(sql).toMatch(/\bUSING\s*\(/)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('should generate valid CREATE POLICY syntax for INSERT', () => {
|
|
64
|
+
const policy = createPolicy({
|
|
65
|
+
name: 'users_create',
|
|
66
|
+
table: 'users',
|
|
67
|
+
operation: 'INSERT',
|
|
68
|
+
check: "user_id = current_setting('app.user_id')::uuid",
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
const sql = generatePolicySQL(policy)
|
|
72
|
+
|
|
73
|
+
expect(sql).toMatch(/\bFOR\s+INSERT\b/)
|
|
74
|
+
expect(sql).toMatch(/\bWITH\s+CHECK\s*\(/)
|
|
75
|
+
// INSERT policies should NOT have USING clause
|
|
76
|
+
expect(sql).not.toMatch(/\bUSING\s*\(/)
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it('should generate valid CREATE POLICY syntax for UPDATE with both clauses', () => {
|
|
80
|
+
const policy = createPolicy({
|
|
81
|
+
name: 'users_modify',
|
|
82
|
+
table: 'users',
|
|
83
|
+
operation: 'UPDATE',
|
|
84
|
+
using: "user_id = current_setting('app.user_id')::uuid",
|
|
85
|
+
check: "user_id = current_setting('app.user_id')::uuid",
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
const sql = generatePolicySQL(policy)
|
|
89
|
+
|
|
90
|
+
expect(sql).toMatch(/\bFOR\s+UPDATE\b/)
|
|
91
|
+
expect(sql).toMatch(/\bUSING\s*\(/)
|
|
92
|
+
expect(sql).toMatch(/\bWITH\s+CHECK\s*\(/)
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it('should generate valid CREATE POLICY syntax for DELETE', () => {
|
|
96
|
+
const policy = createPolicy({
|
|
97
|
+
name: 'users_remove',
|
|
98
|
+
table: 'users',
|
|
99
|
+
operation: 'DELETE',
|
|
100
|
+
using: "user_id = current_setting('app.user_id')::uuid",
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
const sql = generatePolicySQL(policy)
|
|
104
|
+
|
|
105
|
+
expect(sql).toMatch(/\bFOR\s+DELETE\b/)
|
|
106
|
+
expect(sql).toMatch(/\bUSING\s*\(/)
|
|
107
|
+
// DELETE policies should NOT have WITH CHECK clause
|
|
108
|
+
expect(sql).not.toMatch(/\bWITH\s+CHECK\s*\(/)
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
it('should generate valid CREATE POLICY syntax for ALL operations', () => {
|
|
112
|
+
const policy = createPolicy({
|
|
113
|
+
name: 'tenant_all_access',
|
|
114
|
+
table: 'resources',
|
|
115
|
+
operation: 'ALL',
|
|
116
|
+
using: "tenant_id = current_setting('app.tenant_id')::uuid",
|
|
117
|
+
check: "tenant_id = current_setting('app.tenant_id')::uuid",
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
const sql = generatePolicySQL(policy)
|
|
121
|
+
|
|
122
|
+
expect(sql).toMatch(/\bFOR\s+ALL\b/)
|
|
123
|
+
expect(sql).toMatch(/\bUSING\s*\(/)
|
|
124
|
+
expect(sql).toMatch(/\bWITH\s+CHECK\s*\(/)
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
it('should generate valid DROP POLICY syntax', () => {
|
|
128
|
+
const sql = generateDropPolicySQL('users_read_own', 'users')
|
|
129
|
+
|
|
130
|
+
expect(sql).toMatch(/^DROP POLICY\s+/)
|
|
131
|
+
expect(sql).toMatch(/\bON\s+users$/)
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
it('should generate valid DROP POLICY IF EXISTS syntax', () => {
|
|
135
|
+
const sql = generateDropPolicySQL('users_read_own', 'users', true)
|
|
136
|
+
|
|
137
|
+
expect(sql).toMatch(/^DROP POLICY IF EXISTS\s+/)
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
it('should generate valid ENABLE ROW LEVEL SECURITY syntax', () => {
|
|
141
|
+
const sql = generateEnableRLSSQL('users')
|
|
142
|
+
|
|
143
|
+
expect(sql).toBe('ALTER TABLE users ENABLE ROW LEVEL SECURITY')
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
it('should generate valid FORCE ROW LEVEL SECURITY syntax', () => {
|
|
147
|
+
const sql = generateEnableRLSSQL('users', { force: true })
|
|
148
|
+
|
|
149
|
+
expect(sql).toBe('ALTER TABLE users FORCE ROW LEVEL SECURITY')
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
it('should generate valid DISABLE ROW LEVEL SECURITY syntax', () => {
|
|
153
|
+
const sql = generateDisableRLSSQL('users')
|
|
154
|
+
|
|
155
|
+
expect(sql).toBe('ALTER TABLE users DISABLE ROW LEVEL SECURITY')
|
|
156
|
+
})
|
|
157
|
+
|
|
158
|
+
it('should generate valid NO FORCE ROW LEVEL SECURITY syntax', () => {
|
|
159
|
+
const sql = generateDisableRLSSQL('users', { removeForce: true })
|
|
160
|
+
|
|
161
|
+
expect(sql).toBe('ALTER TABLE users NO FORCE ROW LEVEL SECURITY')
|
|
162
|
+
})
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* SECTION 2: Policy Bypass Prevention
|
|
167
|
+
* SECURITY CRITICAL: Verifies that policies cannot be circumvented
|
|
168
|
+
*/
|
|
169
|
+
describe('Policy Bypass Prevention', () => {
|
|
170
|
+
it('should not allow empty USING clause for SELECT operations', () => {
|
|
171
|
+
const policy: RLSPolicy = {
|
|
172
|
+
name: 'unsafe_select',
|
|
173
|
+
table: 'users',
|
|
174
|
+
operation: 'SELECT',
|
|
175
|
+
using: '',
|
|
176
|
+
roles: ['public'],
|
|
177
|
+
type: 'permissive',
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const sql = generatePolicySQL(policy)
|
|
181
|
+
|
|
182
|
+
// Empty USING clause means no restriction - should either:
|
|
183
|
+
// 1. Throw an error, OR
|
|
184
|
+
// 2. Generate valid SQL that PostgreSQL will reject
|
|
185
|
+
// The generator should NOT produce: USING ()
|
|
186
|
+
expect(sql).not.toMatch(/USING\s*\(\s*\)/)
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
it('should not allow empty WITH CHECK clause for INSERT operations', () => {
|
|
190
|
+
const policy: RLSPolicy = {
|
|
191
|
+
name: 'unsafe_insert',
|
|
192
|
+
table: 'users',
|
|
193
|
+
operation: 'INSERT',
|
|
194
|
+
check: '',
|
|
195
|
+
roles: ['public'],
|
|
196
|
+
type: 'permissive',
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const sql = generatePolicySQL(policy)
|
|
200
|
+
|
|
201
|
+
// Empty WITH CHECK clause is dangerous - should not produce: WITH CHECK ()
|
|
202
|
+
expect(sql).not.toMatch(/WITH\s+CHECK\s*\(\s*\)/)
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
it('should require USING clause for SELECT operations', () => {
|
|
206
|
+
const policy: RLSPolicy = {
|
|
207
|
+
name: 'missing_using',
|
|
208
|
+
table: 'users',
|
|
209
|
+
operation: 'SELECT',
|
|
210
|
+
using: undefined,
|
|
211
|
+
roles: ['public'],
|
|
212
|
+
type: 'permissive',
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// The generator should ensure SELECT policies have USING clause
|
|
216
|
+
// or the resulting SQL should be invalid
|
|
217
|
+
const sql = generatePolicySQL(policy)
|
|
218
|
+
|
|
219
|
+
// SELECT without USING would allow all rows - verify it's handled
|
|
220
|
+
// Either no USING clause at all (PostgreSQL defaults to true) is intentional
|
|
221
|
+
// OR we should explicitly have a clause
|
|
222
|
+
expect(sql).toContain('FOR SELECT')
|
|
223
|
+
})
|
|
224
|
+
|
|
225
|
+
it('should require WITH CHECK clause for INSERT operations', () => {
|
|
226
|
+
const policy: RLSPolicy = {
|
|
227
|
+
name: 'missing_check',
|
|
228
|
+
table: 'users',
|
|
229
|
+
operation: 'INSERT',
|
|
230
|
+
check: undefined,
|
|
231
|
+
roles: ['public'],
|
|
232
|
+
type: 'permissive',
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// INSERT without WITH CHECK allows inserting any row - dangerous
|
|
236
|
+
const sql = generatePolicySQL(policy)
|
|
237
|
+
|
|
238
|
+
// Verify the generator handles missing check clause appropriately
|
|
239
|
+
expect(sql).toContain('FOR INSERT')
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
it('should not allow USING true without explicit intent', () => {
|
|
243
|
+
// USING (true) allows all rows - while valid, it should be flagged
|
|
244
|
+
const policy = createPolicy({
|
|
245
|
+
name: 'allow_all',
|
|
246
|
+
table: 'users',
|
|
247
|
+
operation: 'SELECT',
|
|
248
|
+
using: 'true',
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
const sql = generatePolicySQL(policy)
|
|
252
|
+
|
|
253
|
+
// The SQL will be valid, but this test documents that USING (true)
|
|
254
|
+
// is generated as-is (this should be caught by validatePolicy, not generator)
|
|
255
|
+
expect(sql).toContain('USING (true)')
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
it('should preserve parentheses in complex USING expressions', () => {
|
|
259
|
+
const policy = createPolicy({
|
|
260
|
+
name: 'complex_condition',
|
|
261
|
+
table: 'documents',
|
|
262
|
+
operation: 'SELECT',
|
|
263
|
+
using: "(owner_id = current_user_id()) OR (is_public = true AND deleted_at IS NULL)",
|
|
264
|
+
})
|
|
265
|
+
|
|
266
|
+
const sql = generatePolicySQL(policy)
|
|
267
|
+
|
|
268
|
+
// Must preserve the parentheses to maintain correct boolean logic
|
|
269
|
+
expect(sql).toContain('USING ((owner_id = current_user_id()) OR (is_public = true AND deleted_at IS NULL))')
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
it('should handle restrictive policies correctly', () => {
|
|
273
|
+
// Restrictive policies are AND-ed together, not OR-ed
|
|
274
|
+
const policy = createPolicy({
|
|
275
|
+
name: 'restrict_active',
|
|
276
|
+
table: 'users',
|
|
277
|
+
operation: 'SELECT',
|
|
278
|
+
using: 'is_active = true',
|
|
279
|
+
type: 'restrictive',
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
const sql = generatePolicySQL(policy)
|
|
283
|
+
|
|
284
|
+
expect(sql).toContain('AS RESTRICTIVE')
|
|
285
|
+
})
|
|
286
|
+
})
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* SECTION 3: USING and WITH CHECK Clause Correctness
|
|
290
|
+
* Verifies clauses are applied to correct operations
|
|
291
|
+
*/
|
|
292
|
+
describe('USING and WITH CHECK Clause Correctness', () => {
|
|
293
|
+
it('should only include USING clause for SELECT (not WITH CHECK)', () => {
|
|
294
|
+
const policy = createPolicy({
|
|
295
|
+
name: 'select_policy',
|
|
296
|
+
table: 'users',
|
|
297
|
+
operation: 'SELECT',
|
|
298
|
+
using: 'user_id = 1',
|
|
299
|
+
check: 'user_id = 1', // This should be ignored for SELECT
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
const sql = generatePolicySQL(policy)
|
|
303
|
+
|
|
304
|
+
expect(sql).toContain('USING (user_id = 1)')
|
|
305
|
+
// SELECT should NOT have WITH CHECK
|
|
306
|
+
expect(sql).not.toContain('WITH CHECK')
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
it('should only include WITH CHECK clause for INSERT (not USING)', () => {
|
|
310
|
+
const policy = createPolicy({
|
|
311
|
+
name: 'insert_policy',
|
|
312
|
+
table: 'users',
|
|
313
|
+
operation: 'INSERT',
|
|
314
|
+
using: 'user_id = 1', // This should be ignored for INSERT
|
|
315
|
+
check: 'user_id = 1',
|
|
316
|
+
})
|
|
317
|
+
|
|
318
|
+
const sql = generatePolicySQL(policy)
|
|
319
|
+
|
|
320
|
+
expect(sql).toContain('WITH CHECK (user_id = 1)')
|
|
321
|
+
// INSERT should NOT have USING clause
|
|
322
|
+
expect(sql).not.toContain('USING')
|
|
323
|
+
})
|
|
324
|
+
|
|
325
|
+
it('should include both USING and WITH CHECK for UPDATE', () => {
|
|
326
|
+
const policy = createPolicy({
|
|
327
|
+
name: 'update_policy',
|
|
328
|
+
table: 'users',
|
|
329
|
+
operation: 'UPDATE',
|
|
330
|
+
using: 'user_id = current_user_id()',
|
|
331
|
+
check: 'user_id = current_user_id()',
|
|
332
|
+
})
|
|
333
|
+
|
|
334
|
+
const sql = generatePolicySQL(policy)
|
|
335
|
+
|
|
336
|
+
expect(sql).toContain('USING (user_id = current_user_id())')
|
|
337
|
+
expect(sql).toContain('WITH CHECK (user_id = current_user_id())')
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
it('should only include USING clause for DELETE (not WITH CHECK)', () => {
|
|
341
|
+
const policy = createPolicy({
|
|
342
|
+
name: 'delete_policy',
|
|
343
|
+
table: 'users',
|
|
344
|
+
operation: 'DELETE',
|
|
345
|
+
using: 'user_id = current_user_id()',
|
|
346
|
+
check: 'user_id = current_user_id()', // This should be ignored for DELETE
|
|
347
|
+
})
|
|
348
|
+
|
|
349
|
+
const sql = generatePolicySQL(policy)
|
|
350
|
+
|
|
351
|
+
expect(sql).toContain('USING (user_id = current_user_id())')
|
|
352
|
+
// DELETE should NOT have WITH CHECK
|
|
353
|
+
expect(sql).not.toContain('WITH CHECK')
|
|
354
|
+
})
|
|
355
|
+
|
|
356
|
+
it('should include both clauses for ALL operations', () => {
|
|
357
|
+
const policy = createPolicy({
|
|
358
|
+
name: 'all_policy',
|
|
359
|
+
table: 'users',
|
|
360
|
+
operation: 'ALL',
|
|
361
|
+
using: 'owner_id = current_user_id()',
|
|
362
|
+
check: 'owner_id = current_user_id()',
|
|
363
|
+
})
|
|
364
|
+
|
|
365
|
+
const sql = generatePolicySQL(policy)
|
|
366
|
+
|
|
367
|
+
expect(sql).toContain('USING (owner_id = current_user_id())')
|
|
368
|
+
expect(sql).toContain('WITH CHECK (owner_id = current_user_id())')
|
|
369
|
+
})
|
|
370
|
+
|
|
371
|
+
it('should handle different USING and CHECK conditions for UPDATE', () => {
|
|
372
|
+
// UPDATE can have different conditions for reading vs writing
|
|
373
|
+
const policy = createPolicy({
|
|
374
|
+
name: 'update_different_conditions',
|
|
375
|
+
table: 'documents',
|
|
376
|
+
operation: 'UPDATE',
|
|
377
|
+
using: 'owner_id = current_user_id() OR is_editable = true',
|
|
378
|
+
check: 'owner_id = current_user_id()',
|
|
379
|
+
})
|
|
380
|
+
|
|
381
|
+
const sql = generatePolicySQL(policy)
|
|
382
|
+
|
|
383
|
+
// USING controls which rows can be seen for update
|
|
384
|
+
expect(sql).toContain('USING (owner_id = current_user_id() OR is_editable = true)')
|
|
385
|
+
// WITH CHECK controls what the new row values can be
|
|
386
|
+
expect(sql).toContain('WITH CHECK (owner_id = current_user_id())')
|
|
387
|
+
})
|
|
388
|
+
})
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* SECTION 4: Multi-Tenant Isolation
|
|
392
|
+
* SECURITY CRITICAL: Verifies tenant data cannot leak across tenants
|
|
393
|
+
*/
|
|
394
|
+
describe('Multi-Tenant Isolation', () => {
|
|
395
|
+
it('should generate tenant isolation policy with correct USING clause', () => {
|
|
396
|
+
const policy = createTenantPolicy('orders', 'tenant_id')
|
|
397
|
+
|
|
398
|
+
// Handle both single policy and array result
|
|
399
|
+
const singlePolicy = Array.isArray(policy) ? policy[0] : policy
|
|
400
|
+
const sql = generatePolicySQL(singlePolicy)
|
|
401
|
+
|
|
402
|
+
// Must include tenant_id column in USING
|
|
403
|
+
expect(sql).toContain('USING')
|
|
404
|
+
expect(singlePolicy.using).toContain('tenant_id')
|
|
405
|
+
expect(singlePolicy.using).toContain('current_setting')
|
|
406
|
+
expect(singlePolicy.using).toContain('app.tenant_id')
|
|
407
|
+
})
|
|
408
|
+
|
|
409
|
+
it('should generate tenant isolation policy with correct WITH CHECK clause', () => {
|
|
410
|
+
const policy = createTenantPolicy('orders', 'tenant_id')
|
|
411
|
+
|
|
412
|
+
// Handle both single policy and array result
|
|
413
|
+
const singlePolicy = Array.isArray(policy) ? policy[0] : policy
|
|
414
|
+
|
|
415
|
+
// Must include tenant_id column in WITH CHECK for INSERT/UPDATE
|
|
416
|
+
expect(singlePolicy.check).toContain('tenant_id')
|
|
417
|
+
expect(singlePolicy.check).toContain('current_setting')
|
|
418
|
+
})
|
|
419
|
+
|
|
420
|
+
it('should enforce tenant isolation for all CRUD operations', () => {
|
|
421
|
+
const policies = createTenantPolicy('orders', 'tenant_id', {
|
|
422
|
+
operations: ['SELECT', 'INSERT', 'UPDATE', 'DELETE'],
|
|
423
|
+
})
|
|
424
|
+
|
|
425
|
+
expect(Array.isArray(policies)).toBe(true)
|
|
426
|
+
expect(policies).toHaveLength(4)
|
|
427
|
+
|
|
428
|
+
// Verify each operation has proper tenant isolation
|
|
429
|
+
const policiesArray = policies as RLSPolicy[]
|
|
430
|
+
|
|
431
|
+
// SELECT should have USING with tenant check
|
|
432
|
+
const selectPolicy = policiesArray.find((p) => p.operation === 'SELECT')
|
|
433
|
+
expect(selectPolicy?.using).toContain('tenant_id')
|
|
434
|
+
expect(selectPolicy?.check).toBeUndefined()
|
|
435
|
+
|
|
436
|
+
// INSERT should have WITH CHECK with tenant check (no USING)
|
|
437
|
+
const insertPolicy = policiesArray.find((p) => p.operation === 'INSERT')
|
|
438
|
+
expect(insertPolicy?.check).toContain('tenant_id')
|
|
439
|
+
expect(insertPolicy?.using).toBeUndefined()
|
|
440
|
+
|
|
441
|
+
// UPDATE should have both USING and WITH CHECK
|
|
442
|
+
const updatePolicy = policiesArray.find((p) => p.operation === 'UPDATE')
|
|
443
|
+
expect(updatePolicy?.using).toContain('tenant_id')
|
|
444
|
+
expect(updatePolicy?.check).toContain('tenant_id')
|
|
445
|
+
|
|
446
|
+
// DELETE should have USING with tenant check
|
|
447
|
+
const deletePolicy = policiesArray.find((p) => p.operation === 'DELETE')
|
|
448
|
+
expect(deletePolicy?.using).toContain('tenant_id')
|
|
449
|
+
expect(deletePolicy?.check).toBeUndefined()
|
|
450
|
+
})
|
|
451
|
+
|
|
452
|
+
it('should properly cast tenant ID to correct type', () => {
|
|
453
|
+
const uuidPolicy = createTenantPolicy('orders', 'tenant_id', {
|
|
454
|
+
columnType: 'uuid',
|
|
455
|
+
}) as RLSPolicy
|
|
456
|
+
|
|
457
|
+
const intPolicy = createTenantPolicy('orders', 'tenant_id', {
|
|
458
|
+
columnType: 'integer',
|
|
459
|
+
}) as RLSPolicy
|
|
460
|
+
|
|
461
|
+
const textPolicy = createTenantPolicy('orders', 'tenant_id', {
|
|
462
|
+
columnType: 'text',
|
|
463
|
+
}) as RLSPolicy
|
|
464
|
+
|
|
465
|
+
// UUID type should cast
|
|
466
|
+
expect(uuidPolicy.using).toContain('::uuid')
|
|
467
|
+
|
|
468
|
+
// Integer type should cast
|
|
469
|
+
expect(intPolicy.using).toContain('::integer')
|
|
470
|
+
|
|
471
|
+
// Text type should NOT cast (avoid double conversion)
|
|
472
|
+
expect(textPolicy.using).not.toContain('::uuid')
|
|
473
|
+
expect(textPolicy.using).not.toContain('::integer')
|
|
474
|
+
})
|
|
475
|
+
|
|
476
|
+
it('should handle super-tenant bypass safely', () => {
|
|
477
|
+
const policy = createTenantPolicy('orders', 'tenant_id', {
|
|
478
|
+
superTenantBypass: 'SYSTEM_ADMIN',
|
|
479
|
+
}) as RLSPolicy
|
|
480
|
+
|
|
481
|
+
const sql = generatePolicySQL(policy)
|
|
482
|
+
|
|
483
|
+
// Super-tenant check should be OR-ed with normal tenant check
|
|
484
|
+
expect(policy.using).toContain('SYSTEM_ADMIN')
|
|
485
|
+
expect(policy.using).toContain('OR')
|
|
486
|
+
// The bypass should check the session variable, not a hardcoded role
|
|
487
|
+
expect(policy.using).toContain("current_setting('app.tenant_id') = 'SYSTEM_ADMIN'")
|
|
488
|
+
})
|
|
489
|
+
|
|
490
|
+
it('should handle nullable tenant columns safely', () => {
|
|
491
|
+
const policy = createTenantPolicy('shared_resources', 'tenant_id', {
|
|
492
|
+
allowNull: true,
|
|
493
|
+
}) as RLSPolicy
|
|
494
|
+
|
|
495
|
+
// NULL tenant_id rows should be accessible
|
|
496
|
+
expect(policy.using).toContain('IS NULL')
|
|
497
|
+
expect(policy.using).toContain('OR')
|
|
498
|
+
// But normal tenant check should still apply
|
|
499
|
+
expect(policy.using).toContain('current_setting')
|
|
500
|
+
})
|
|
501
|
+
|
|
502
|
+
it('should not allow tenant ID manipulation through SQL injection in policy', () => {
|
|
503
|
+
// This tests that the policy expression itself is safe
|
|
504
|
+
const policy = createTenantPolicy('orders', 'tenant_id') as RLSPolicy
|
|
505
|
+
|
|
506
|
+
// The policy should use parameterized session variables, not string interpolation
|
|
507
|
+
expect(policy.using).toContain('current_setting(')
|
|
508
|
+
// Should NOT contain direct string interpolation patterns
|
|
509
|
+
expect(policy.using).not.toContain("'${")
|
|
510
|
+
expect(policy.using).not.toContain("' + ")
|
|
511
|
+
expect(policy.using).not.toContain("' || ")
|
|
512
|
+
})
|
|
513
|
+
})
|
|
514
|
+
|
|
515
|
+
/**
|
|
516
|
+
* SECTION 5: SQL Injection Safety
|
|
517
|
+
* SECURITY CRITICAL: Verifies generated SQL cannot be manipulated
|
|
518
|
+
*/
|
|
519
|
+
describe('SQL Injection Safety', () => {
|
|
520
|
+
it('should properly quote identifiers with special characters', () => {
|
|
521
|
+
const policy = createPolicy({
|
|
522
|
+
name: 'my-policy-name',
|
|
523
|
+
table: 'my-table-name',
|
|
524
|
+
operation: 'SELECT',
|
|
525
|
+
using: 'true',
|
|
526
|
+
})
|
|
527
|
+
|
|
528
|
+
const sql = generatePolicySQL(policy)
|
|
529
|
+
|
|
530
|
+
// Identifiers with hyphens must be quoted
|
|
531
|
+
expect(sql).toContain('"my-policy-name"')
|
|
532
|
+
expect(sql).toContain('"my-table-name"')
|
|
533
|
+
})
|
|
534
|
+
|
|
535
|
+
it('should properly quote schema-qualified table names', () => {
|
|
536
|
+
const policy = createPolicy({
|
|
537
|
+
name: 'schema_policy',
|
|
538
|
+
table: 'myschema.mytable',
|
|
539
|
+
operation: 'SELECT',
|
|
540
|
+
using: 'true',
|
|
541
|
+
})
|
|
542
|
+
|
|
543
|
+
const sql = generatePolicySQL(policy)
|
|
544
|
+
|
|
545
|
+
// Schema-qualified names should be properly formatted
|
|
546
|
+
expect(sql).toContain('ON myschema.mytable')
|
|
547
|
+
})
|
|
548
|
+
|
|
549
|
+
it('should escape quotes in policy names', () => {
|
|
550
|
+
const policy = createPolicy({
|
|
551
|
+
name: 'policy"with"quotes',
|
|
552
|
+
table: 'users',
|
|
553
|
+
operation: 'SELECT',
|
|
554
|
+
using: 'true',
|
|
555
|
+
})
|
|
556
|
+
|
|
557
|
+
const sql = generatePolicySQL(policy)
|
|
558
|
+
|
|
559
|
+
// Quotes in identifiers should be escaped
|
|
560
|
+
expect(sql).toContain('"policy')
|
|
561
|
+
// Should not allow quote injection
|
|
562
|
+
expect(sql).not.toContain('policy"with"quotes ON')
|
|
563
|
+
})
|
|
564
|
+
|
|
565
|
+
it('should reject table names with SQL injection attempts', async () => {
|
|
566
|
+
const mockPGlite = createMockPGlite()
|
|
567
|
+
|
|
568
|
+
// Attempt SQL injection through table name
|
|
569
|
+
await expect(
|
|
570
|
+
enableRLS(mockPGlite, "users; DROP TABLE users; --")
|
|
571
|
+
).rejects.toThrow('Invalid table name')
|
|
572
|
+
})
|
|
573
|
+
|
|
574
|
+
it('should reject table names with comment injection', async () => {
|
|
575
|
+
const mockPGlite = createMockPGlite()
|
|
576
|
+
|
|
577
|
+
await expect(
|
|
578
|
+
enableRLS(mockPGlite, "users -- comment")
|
|
579
|
+
).rejects.toThrow('Invalid table name')
|
|
580
|
+
})
|
|
581
|
+
|
|
582
|
+
it('should reject table names with multi-line injection', async () => {
|
|
583
|
+
const mockPGlite = createMockPGlite()
|
|
584
|
+
|
|
585
|
+
await expect(
|
|
586
|
+
enableRLS(mockPGlite, "users\nDROP TABLE secrets")
|
|
587
|
+
).rejects.toThrow('Invalid table name')
|
|
588
|
+
})
|
|
589
|
+
|
|
590
|
+
it('should properly escape single quotes in expressions', () => {
|
|
591
|
+
const policy = createPolicy({
|
|
592
|
+
name: 'quote_test',
|
|
593
|
+
table: 'users',
|
|
594
|
+
operation: 'SELECT',
|
|
595
|
+
using: "name = 'O''Brien'", // Properly escaped single quote
|
|
596
|
+
})
|
|
597
|
+
|
|
598
|
+
const sql = generatePolicySQL(policy)
|
|
599
|
+
|
|
600
|
+
// The expression should be preserved as-is in USING clause
|
|
601
|
+
expect(sql).toContain("USING (name = 'O''Brien')")
|
|
602
|
+
})
|
|
603
|
+
|
|
604
|
+
it('should handle unicode characters in identifiers', () => {
|
|
605
|
+
const policy = createPolicy({
|
|
606
|
+
name: 'policy_with_unicode',
|
|
607
|
+
table: 'usuarios', // Spanish
|
|
608
|
+
operation: 'SELECT',
|
|
609
|
+
using: 'true',
|
|
610
|
+
})
|
|
611
|
+
|
|
612
|
+
const sql = generatePolicySQL(policy)
|
|
613
|
+
|
|
614
|
+
// Unicode table name should be preserved
|
|
615
|
+
expect(sql).toContain('usuarios')
|
|
616
|
+
})
|
|
617
|
+
|
|
618
|
+
it('should prevent policy name length overflow attacks', () => {
|
|
619
|
+
// PostgreSQL has a 63 character limit for identifiers
|
|
620
|
+
const longName = 'a'.repeat(100)
|
|
621
|
+
|
|
622
|
+
const policy = createPolicy({
|
|
623
|
+
name: longName,
|
|
624
|
+
table: 'users',
|
|
625
|
+
operation: 'SELECT',
|
|
626
|
+
using: 'true',
|
|
627
|
+
})
|
|
628
|
+
|
|
629
|
+
const sql = generatePolicySQL(policy)
|
|
630
|
+
|
|
631
|
+
// The name should be preserved (validation is separate concern)
|
|
632
|
+
// but verify no truncation causes unexpected SQL
|
|
633
|
+
expect(sql).toContain(longName)
|
|
634
|
+
})
|
|
635
|
+
|
|
636
|
+
it('should handle empty role array safely', () => {
|
|
637
|
+
const policy: RLSPolicy = {
|
|
638
|
+
name: 'empty_roles',
|
|
639
|
+
table: 'users',
|
|
640
|
+
operation: 'SELECT',
|
|
641
|
+
using: 'true',
|
|
642
|
+
roles: [],
|
|
643
|
+
type: 'permissive',
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
const sql = generatePolicySQL(policy)
|
|
647
|
+
|
|
648
|
+
// Empty roles should not produce invalid SQL like "TO "
|
|
649
|
+
// Should either default to public or handle appropriately
|
|
650
|
+
expect(sql).toContain('TO')
|
|
651
|
+
// Should not have "TO " followed by space then another keyword
|
|
652
|
+
expect(sql).not.toMatch(/TO\s+(?:USING|WITH|AS|FOR|ON)/)
|
|
653
|
+
})
|
|
654
|
+
|
|
655
|
+
it('should handle roles with special characters', () => {
|
|
656
|
+
const policy = createPolicy({
|
|
657
|
+
name: 'special_role_policy',
|
|
658
|
+
table: 'users',
|
|
659
|
+
operation: 'SELECT',
|
|
660
|
+
using: 'true',
|
|
661
|
+
roles: ['user-role', 'admin_role', 'role.with.dots'],
|
|
662
|
+
})
|
|
663
|
+
|
|
664
|
+
const sql = generatePolicySQL(policy)
|
|
665
|
+
|
|
666
|
+
// Roles with special characters should be handled
|
|
667
|
+
expect(sql).toContain('TO')
|
|
668
|
+
})
|
|
669
|
+
})
|
|
670
|
+
|
|
671
|
+
/**
|
|
672
|
+
* SECTION 6: Edge Cases and Boundary Conditions
|
|
673
|
+
*/
|
|
674
|
+
describe('Edge Cases', () => {
|
|
675
|
+
it('should handle policy with all optional fields undefined', () => {
|
|
676
|
+
const policy: RLSPolicy = {
|
|
677
|
+
name: 'minimal_policy',
|
|
678
|
+
table: 'users',
|
|
679
|
+
operation: 'SELECT',
|
|
680
|
+
using: undefined,
|
|
681
|
+
check: undefined,
|
|
682
|
+
roles: ['public'],
|
|
683
|
+
type: 'permissive',
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
// Should not throw, but generate potentially problematic SQL
|
|
687
|
+
// (which would be caught at apply time by PostgreSQL)
|
|
688
|
+
expect(() => generatePolicySQL(policy)).not.toThrow()
|
|
689
|
+
})
|
|
690
|
+
|
|
691
|
+
it('should handle policy with whitespace-only expressions', () => {
|
|
692
|
+
const policy: RLSPolicy = {
|
|
693
|
+
name: 'whitespace_policy',
|
|
694
|
+
table: 'users',
|
|
695
|
+
operation: 'SELECT',
|
|
696
|
+
using: ' ',
|
|
697
|
+
roles: ['public'],
|
|
698
|
+
type: 'permissive',
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
const sql = generatePolicySQL(policy)
|
|
702
|
+
|
|
703
|
+
// Whitespace-only USING is effectively empty - should be handled
|
|
704
|
+
// Either by trimming or by generating SQL that PostgreSQL rejects
|
|
705
|
+
expect(sql).toBeDefined()
|
|
706
|
+
})
|
|
707
|
+
|
|
708
|
+
it('should handle deeply nested boolean expressions', () => {
|
|
709
|
+
const policy = createPolicy({
|
|
710
|
+
name: 'nested_policy',
|
|
711
|
+
table: 'complex_table',
|
|
712
|
+
operation: 'SELECT',
|
|
713
|
+
using: '((((a = 1) AND (b = 2)) OR ((c = 3) AND (d = 4))) AND (e = 5))',
|
|
714
|
+
})
|
|
715
|
+
|
|
716
|
+
const sql = generatePolicySQL(policy)
|
|
717
|
+
|
|
718
|
+
// All parentheses should be preserved
|
|
719
|
+
expect(sql).toContain('USING (((((a = 1) AND (b = 2)) OR ((c = 3) AND (d = 4))) AND (e = 5)))')
|
|
720
|
+
})
|
|
721
|
+
|
|
722
|
+
it('should handle USING clause with subquery', () => {
|
|
723
|
+
const policy = createPolicy({
|
|
724
|
+
name: 'subquery_policy',
|
|
725
|
+
table: 'documents',
|
|
726
|
+
operation: 'SELECT',
|
|
727
|
+
using: 'owner_id IN (SELECT user_id FROM team_members WHERE team_id = current_setting(\'app.team_id\')::uuid)',
|
|
728
|
+
})
|
|
729
|
+
|
|
730
|
+
const sql = generatePolicySQL(policy)
|
|
731
|
+
|
|
732
|
+
// Subquery should be preserved exactly
|
|
733
|
+
expect(sql).toContain('SELECT user_id FROM team_members')
|
|
734
|
+
})
|
|
735
|
+
|
|
736
|
+
it('should handle USING clause with CTE reference', () => {
|
|
737
|
+
// Note: CTEs in RLS policies are limited but the generator should handle the syntax
|
|
738
|
+
const policy = createPolicy({
|
|
739
|
+
name: 'cte_policy',
|
|
740
|
+
table: 'documents',
|
|
741
|
+
operation: 'SELECT',
|
|
742
|
+
using: 'EXISTS (SELECT 1 FROM permissions WHERE document_id = documents.id)',
|
|
743
|
+
})
|
|
744
|
+
|
|
745
|
+
const sql = generatePolicySQL(policy)
|
|
746
|
+
|
|
747
|
+
expect(sql).toContain('EXISTS (SELECT 1 FROM permissions')
|
|
748
|
+
})
|
|
749
|
+
|
|
750
|
+
it('should handle USING clause with function calls', () => {
|
|
751
|
+
const policy = createPolicy({
|
|
752
|
+
name: 'function_policy',
|
|
753
|
+
table: 'users',
|
|
754
|
+
operation: 'SELECT',
|
|
755
|
+
using: "auth.uid() = user_id AND auth.role() = 'authenticated'",
|
|
756
|
+
})
|
|
757
|
+
|
|
758
|
+
const sql = generatePolicySQL(policy)
|
|
759
|
+
|
|
760
|
+
expect(sql).toContain('auth.uid()')
|
|
761
|
+
expect(sql).toContain('auth.role()')
|
|
762
|
+
})
|
|
763
|
+
|
|
764
|
+
it('should handle multiple consecutive special characters', () => {
|
|
765
|
+
const sql = generateDropPolicySQL('policy--name', 'table--name', true)
|
|
766
|
+
|
|
767
|
+
// Double hyphens could be interpreted as SQL comments
|
|
768
|
+
// Names with consecutive special chars should be quoted
|
|
769
|
+
expect(sql).toContain('"policy--name"')
|
|
770
|
+
expect(sql).toContain('"table--name"')
|
|
771
|
+
})
|
|
772
|
+
})
|
|
773
|
+
|
|
774
|
+
/**
|
|
775
|
+
* SECTION 7: Integration with applyPolicy
|
|
776
|
+
*/
|
|
777
|
+
describe('Apply Policy Integration', () => {
|
|
778
|
+
let mockPGlite: MockPGlite
|
|
779
|
+
|
|
780
|
+
beforeEach(() => {
|
|
781
|
+
mockPGlite = createMockPGlite()
|
|
782
|
+
})
|
|
783
|
+
|
|
784
|
+
it('should execute generated SQL through applyPolicy', async () => {
|
|
785
|
+
const policy = createPolicy({
|
|
786
|
+
name: 'test_policy',
|
|
787
|
+
table: 'users',
|
|
788
|
+
operation: 'SELECT',
|
|
789
|
+
using: 'user_id = 1',
|
|
790
|
+
})
|
|
791
|
+
|
|
792
|
+
await applyPolicy(mockPGlite, policy)
|
|
793
|
+
|
|
794
|
+
expect(mockPGlite.exec).toHaveBeenCalledTimes(1)
|
|
795
|
+
const executedSQL = mockPGlite.exec.mock.calls[0][0]
|
|
796
|
+
expect(executedSQL).toContain('CREATE POLICY')
|
|
797
|
+
expect(executedSQL).toContain('test_policy')
|
|
798
|
+
})
|
|
799
|
+
|
|
800
|
+
it('should drop and recreate when replace is true', async () => {
|
|
801
|
+
const policy = createPolicy({
|
|
802
|
+
name: 'test_policy',
|
|
803
|
+
table: 'users',
|
|
804
|
+
operation: 'SELECT',
|
|
805
|
+
using: 'user_id = 1',
|
|
806
|
+
})
|
|
807
|
+
|
|
808
|
+
await applyPolicy(mockPGlite, policy, { replace: true })
|
|
809
|
+
|
|
810
|
+
expect(mockPGlite.exec).toHaveBeenCalledTimes(2)
|
|
811
|
+
expect(mockPGlite.exec.mock.calls[0][0]).toContain('DROP POLICY')
|
|
812
|
+
expect(mockPGlite.exec.mock.calls[1][0]).toContain('CREATE POLICY')
|
|
813
|
+
})
|
|
814
|
+
|
|
815
|
+
it('should add IF NOT EXISTS when specified', async () => {
|
|
816
|
+
const policy = createPolicy({
|
|
817
|
+
name: 'test_policy',
|
|
818
|
+
table: 'users',
|
|
819
|
+
operation: 'SELECT',
|
|
820
|
+
using: 'user_id = 1',
|
|
821
|
+
})
|
|
822
|
+
|
|
823
|
+
await applyPolicy(mockPGlite, policy, { ifNotExists: true })
|
|
824
|
+
|
|
825
|
+
const executedSQL = mockPGlite.exec.mock.calls[0][0]
|
|
826
|
+
expect(executedSQL).toContain('IF NOT EXISTS')
|
|
827
|
+
})
|
|
828
|
+
})
|
|
829
|
+
})
|