@cosmicdrift/kumiko-framework 0.14.0 → 0.16.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/package.json +6 -6
- package/src/__tests__/{anonymous-access.integration.ts → anonymous-access.integration.test.ts} +12 -9
- package/src/__tests__/{error-contract.integration.ts → error-contract.integration.test.ts} +5 -4
- package/src/__tests__/{field-access.integration.ts → field-access.integration.test.ts} +3 -3
- package/src/__tests__/{full-stack.integration.ts → full-stack.integration.test.ts} +7 -16
- package/src/__tests__/{ownership.integration.ts → ownership.integration.test.ts} +3 -2
- package/src/__tests__/{raw-table.integration.ts → raw-table.integration.test.ts} +18 -30
- package/src/__tests__/{reference-data.integration.ts → reference-data.integration.test.ts} +24 -11
- package/src/__tests__/{transition-guard.integration.ts → transition-guard.integration.test.ts} +12 -10
- package/src/api/__tests__/api.test.ts +1 -1
- package/src/api/__tests__/auth-middleware-transport.test.ts +1 -1
- package/src/api/__tests__/auth-routes-cookie.test.ts +1 -1
- package/src/api/__tests__/{batch.integration.ts → batch.integration.test.ts} +30 -30
- package/src/api/__tests__/body-limit.test.ts +1 -1
- package/src/api/__tests__/csrf-middleware.test.ts +1 -1
- package/src/api/__tests__/{dispatcher-live.integration.ts → dispatcher-live.integration.test.ts} +10 -9
- package/src/api/__tests__/metrics-endpoint.test.ts +1 -1
- package/src/api/__tests__/{nested-write.integration.ts → nested-write.integration.test.ts} +13 -16
- package/src/api/__tests__/readiness.test.ts +1 -1
- package/src/api/__tests__/request-id-middleware.test.ts +1 -1
- package/src/api/__tests__/sse-broker.test.ts +12 -12
- package/src/api/__tests__/sse-route.test.ts +1 -1
- package/src/api/auth-routes.ts +2 -5
- package/src/api/readiness.ts +2 -2
- package/src/auth/__tests__/roles.test.ts +2 -2
- package/src/bun-db/__tests__/PATTERN.md +73 -0
- package/src/bun-db/__tests__/_helpers.ts +103 -0
- package/src/bun-db/__tests__/batch-methods.integration.test.ts +143 -0
- package/src/bun-db/__tests__/batch-methods.test.ts +20 -0
- package/src/bun-db/__tests__/bun-test-db.ts +19 -0
- package/src/bun-db/__tests__/bun-test-stack.ts +6 -0
- package/src/bun-db/__tests__/column-types.integration.test.ts +132 -0
- package/src/bun-db/__tests__/compound-types.integration.test.ts +134 -0
- package/src/bun-db/__tests__/jsonb-edge-cases.integration.test.ts +235 -0
- package/src/bun-db/__tests__/smoke.integration.test.ts +43 -0
- package/src/bun-db/__tests__/sql-methods.integration.test.ts +231 -0
- package/src/bun-db/__tests__/where-patterns.integration.test.ts +185 -0
- package/src/bun-db/connection.ts +84 -0
- package/src/bun-db/index.ts +31 -0
- package/src/bun-db/query.ts +842 -0
- package/src/compliance/__tests__/duration-spec.test.ts +1 -1
- package/src/compliance/__tests__/profiles.test.ts +1 -1
- package/src/compliance/__tests__/sub-processors.test.ts +1 -1
- package/src/compliance/profiles.ts +1 -4
- package/src/db/__tests__/{apply-entity-event-tenant.integration.ts → apply-entity-event-tenant.integration.test.ts} +13 -11
- package/src/db/__tests__/big-int-field.test.ts +15 -14
- package/src/db/__tests__/column-ddl.integration.test.ts +113 -0
- package/src/db/__tests__/compound-types.test.ts +1 -1
- package/src/db/__tests__/{config-seed.integration.ts → config-seed.integration.test.ts} +32 -27
- package/src/db/__tests__/connection-options.test.ts +1 -1
- package/src/db/__tests__/cursor.test.ts +8 -32
- package/src/db/__tests__/dialect-instant.test.ts +1 -1
- package/src/db/__tests__/encryption.test.ts +1 -1
- package/src/db/__tests__/{drizzle-table-types.test.ts → entity-table-types.test.ts} +16 -16
- package/src/db/__tests__/{event-store-executor-list.integration.ts → event-store-executor-list.integration.test.ts} +12 -7
- package/src/db/__tests__/{event-store-executor.integration.ts → event-store-executor.integration.test.ts} +19 -12
- package/src/db/__tests__/{implicit-projection-equivalence.integration.ts → implicit-projection-equivalence.integration.test.ts} +35 -29
- package/src/db/__tests__/located-timestamp.test.ts +1 -1
- package/src/db/__tests__/migrate-generator.test.ts +71 -0
- package/src/db/__tests__/migrate-runner.test.ts +19 -0
- package/src/db/__tests__/money.test.ts +1 -1
- package/src/db/__tests__/{multi-row-insert.integration.ts → multi-row-insert.integration.test.ts} +18 -11
- package/src/db/__tests__/parse-auto-verb.test.ts +1 -1
- package/src/db/__tests__/pg-error.test.ts +43 -0
- package/src/db/__tests__/{required-not-null-migration-safety.integration.ts → required-not-null-migration-safety.integration.test.ts} +28 -24
- package/src/db/__tests__/{schema-migration.integration.ts → schema-migration.integration.test.ts} +32 -28
- package/src/db/__tests__/sql-inventory.test.ts +56 -0
- package/src/db/__tests__/table-builder-indexes.test.ts +30 -11
- package/src/db/__tests__/table-builder-required.test.ts +20 -22
- package/src/db/__tests__/{tenant-db.integration.ts → tenant-db.integration.test.ts} +106 -144
- package/src/db/__tests__/{unique-violation-mapping.integration.ts → unique-violation-mapping.integration.test.ts} +13 -8
- package/src/db/api.ts +46 -0
- package/src/db/apply-entity-event.ts +45 -36
- package/src/db/assert-exists-in.ts +5 -16
- package/src/db/bun-provider.ts +37 -0
- package/src/db/config-seed.ts +4 -4
- package/src/db/connection.ts +14 -57
- package/src/db/cursor.ts +5 -56
- package/src/db/dialect.ts +472 -99
- package/src/db/eagerload.ts +5 -12
- package/src/db/entity-table-meta.ts +390 -0
- package/src/db/event-store-executor.ts +158 -100
- package/src/db/index.ts +33 -5
- package/src/db/migrate-generator.ts +350 -0
- package/src/db/migrate-runner.ts +206 -0
- package/src/db/postgres-provider.ts +25 -0
- package/src/db/queries/entity-read.ts +15 -0
- package/src/db/queries/es-ops.ts +17 -0
- package/src/db/queries/event-consumer.ts +170 -0
- package/src/db/queries/event-store-admin.ts +127 -0
- package/src/db/queries/event-store.ts +155 -0
- package/src/db/queries/projection-rebuild.ts +59 -0
- package/src/db/queries/raw-sql.ts +15 -0
- package/src/db/queries/schema-drift.ts +35 -0
- package/src/db/queries/seed-context.ts +58 -0
- package/src/db/queries/table-ops.ts +11 -0
- package/src/db/queries/test-stack.ts +56 -0
- package/src/db/query-api.ts +22 -0
- package/src/db/query.ts +30 -0
- package/src/db/reference-data.ts +19 -22
- package/src/db/render-ddl.ts +57 -0
- package/src/db/row-helpers.ts +3 -52
- package/src/db/schema-inspection.ts +17 -4
- package/src/db/sql-inventory.ts +208 -0
- package/src/db/table-builder.ts +54 -46
- package/src/db/tenant-db.ts +105 -326
- package/src/engine/__tests__/auth-claims-registrar.test.ts +1 -1
- package/src/engine/__tests__/boot-validator-api-exposure.test.ts +3 -3
- package/src/engine/__tests__/boot-validator-located-timestamps.test.ts +1 -1
- package/src/engine/__tests__/boot-validator-pii-retention.test.ts +5 -5
- package/src/engine/__tests__/boot-validator-s0-integration.test.ts +3 -3
- package/src/engine/__tests__/boot-validator.test.ts +4 -3
- package/src/engine/__tests__/build-app-schema.test.ts +1 -1
- package/src/engine/__tests__/build-target.test.ts +1 -1
- package/src/engine/__tests__/claim-keys.test.ts +1 -1
- package/src/engine/__tests__/codemod-pipeline.test.ts +3 -3
- package/src/engine/__tests__/config-helpers.test.ts +1 -1
- package/src/engine/__tests__/duration-utils.test.ts +16 -0
- package/src/engine/__tests__/effective-features.test.ts +1 -1
- package/src/engine/__tests__/engine.test.ts +1 -1
- package/src/engine/__tests__/entity-handlers.test.ts +3 -3
- package/src/engine/__tests__/event-helpers.test.ts +3 -3
- package/src/engine/__tests__/extends-registrar.test.ts +4 -4
- package/src/engine/__tests__/factories-long-text.test.ts +1 -1
- package/src/engine/__tests__/factories-time.test.ts +1 -1
- package/src/engine/__tests__/field-access.test.ts +38 -0
- package/src/engine/__tests__/field-predicates.test.ts +1 -1
- package/src/engine/__tests__/hook-phases.test.ts +1 -1
- package/src/engine/__tests__/identifiers.test.ts +1 -1
- package/src/engine/__tests__/lifecycle-hooks.test.ts +1 -1
- package/src/engine/__tests__/nav.test.ts +1 -1
- package/src/engine/__tests__/no-return-guard.test.ts +17 -0
- package/src/engine/__tests__/ownership.test.ts +10 -11
- package/src/engine/__tests__/parse-ref-target.test.ts +1 -1
- package/src/engine/__tests__/pipeline-engine.test.ts +1 -1
- package/src/engine/__tests__/{pipeline-handler.integration.ts → pipeline-handler.integration.test.ts} +38 -52
- package/src/engine/__tests__/{pipeline-observability.integration.ts → pipeline-observability.integration.test.ts} +1 -1
- package/src/engine/__tests__/{pipeline-performance.integration.ts → pipeline-performance.integration.test.ts} +1 -1
- package/src/engine/__tests__/pipeline-sub-pipelines.test.ts +1 -1
- package/src/engine/__tests__/post-query-hook.test.ts +1 -1
- package/src/engine/__tests__/projection-helpers.test.ts +25 -17
- package/src/engine/__tests__/projection.test.ts +4 -4
- package/src/engine/__tests__/qualified-name.test.ts +1 -1
- package/src/engine/__tests__/raw-table.test.ts +9 -8
- package/src/engine/__tests__/resolve-config-or-param.test.ts +5 -5
- package/src/engine/__tests__/run-in.test.ts +1 -1
- package/src/engine/__tests__/schema-builder.test.ts +1 -1
- package/src/engine/__tests__/screen.test.ts +1 -1
- package/src/engine/__tests__/search-payload-extension.test.ts +3 -3
- package/src/engine/__tests__/state-machine.test.ts +1 -1
- package/src/engine/__tests__/steps-aggregate-append-event.test.ts +7 -7
- package/src/engine/__tests__/steps-aggregate-create.test.ts +4 -4
- package/src/engine/__tests__/steps-aggregate-update.test.ts +3 -3
- package/src/engine/__tests__/steps-call-feature.test.ts +5 -5
- package/src/engine/__tests__/steps-mail-send.test.ts +7 -7
- package/src/engine/__tests__/steps-read.test.ts +34 -40
- package/src/engine/__tests__/steps-resolver-utils.test.ts +6 -6
- package/src/engine/__tests__/steps-unsafe-projection-delete.test.ts +24 -19
- package/src/engine/__tests__/steps-unsafe-projection-upsert.test.ts +28 -17
- package/src/engine/__tests__/steps-webhook-send.test.ts +6 -6
- package/src/engine/__tests__/steps-workflow.test.ts +7 -7
- package/src/engine/__tests__/system-user.test.ts +1 -1
- package/src/engine/__tests__/unmanaged-table.test.ts +98 -0
- package/src/engine/__tests__/validate-projection-allowlist.test.ts +4 -5
- package/src/engine/__tests__/validation-hooks.test.ts +1 -1
- package/src/engine/__tests__/visual-tree-patterns.test.ts +1 -1
- package/src/engine/boot-validator/entity-handler.ts +3 -3
- package/src/engine/boot-validator/ownership.ts +1 -1
- package/src/engine/define-feature.ts +37 -2
- package/src/engine/entity-handlers.ts +5 -5
- package/src/engine/factories.ts +1 -1
- package/src/engine/feature-ast/__tests__/canonical-form.test.ts +1 -1
- package/src/engine/feature-ast/__tests__/parse-happy-path.test.ts +1 -1
- package/src/engine/feature-ast/__tests__/parse-real-features.test.ts +2 -2
- package/src/engine/feature-ast/__tests__/parse.test.ts +1 -1
- package/src/engine/feature-ast/__tests__/patch.test.ts +1 -1
- package/src/engine/feature-ast/__tests__/patcher.test.ts +1 -1
- package/src/engine/feature-ast/__tests__/render-roundtrip.test.ts +1 -1
- package/src/engine/feature-ast/__tests__/visual-tree-parse.test.ts +1 -1
- package/src/engine/feature-ast/extractors/shared.ts +2 -3
- package/src/engine/ownership.ts +113 -41
- package/src/engine/pattern-library/__tests__/library.test.ts +2 -2
- package/src/engine/projection-helpers.ts +2 -11
- package/src/engine/registry.ts +21 -2
- package/src/engine/steps/read-find-many.ts +13 -13
- package/src/engine/steps/read-find-one.ts +7 -9
- package/src/engine/steps/unsafe-projection-delete.ts +4 -5
- package/src/engine/steps/unsafe-projection-upsert.ts +63 -31
- package/src/engine/types/feature.ts +47 -2
- package/src/engine/types/fields.ts +4 -5
- package/src/engine/types/index.ts +2 -0
- package/src/engine/types/step.ts +10 -10
- package/src/engine/validate-projection-allowlist.ts +23 -3
- package/src/entrypoint/__tests__/{entrypoint-job-wiring.integration.ts → entrypoint-job-wiring.integration.test.ts} +4 -3
- package/src/entrypoint/__tests__/{split-deploy.integration.ts → split-deploy.integration.test.ts} +4 -3
- package/src/env/__tests__/compose-env-schema.test.ts +1 -1
- package/src/env/__tests__/dry-run.test.ts +1 -1
- package/src/errors/__tests__/classes.test.ts +1 -1
- package/src/errors/__tests__/error-helpers.test.ts +44 -0
- package/src/errors/__tests__/field-issue-compat.test.ts +16 -0
- package/src/errors/__tests__/write-failures.test.ts +1 -1
- package/src/errors/classes.ts +5 -19
- package/src/errors/field-issue.ts +11 -0
- package/src/errors/index.ts +1 -0
- package/src/errors/zod-bridge.ts +3 -2
- package/src/es-ops/__tests__/{context.integration.ts → context.integration.test.ts} +43 -29
- package/src/es-ops/__tests__/{runner.integration.ts → runner.integration.test.ts} +25 -23
- package/src/es-ops/__tests__/runner.test.ts +29 -19
- package/src/es-ops/context.ts +11 -56
- package/src/es-ops/operations-schema.ts +2 -2
- package/src/es-ops/runner.ts +12 -26
- package/src/event-store/__tests__/{admin-api.integration.ts → admin-api.integration.test.ts} +71 -45
- package/src/event-store/__tests__/{event-store.integration.ts → event-store.integration.test.ts} +7 -5
- package/src/event-store/__tests__/{get-stream-version-perf.integration.ts → get-stream-version-perf.integration.test.ts} +5 -3
- package/src/event-store/__tests__/{perf.integration.ts → perf.integration.test.ts} +24 -16
- package/src/event-store/__tests__/{snapshot.integration.ts → snapshot.integration.test.ts} +34 -28
- package/src/event-store/__tests__/{upcaster-dead-letter.integration.ts → upcaster-dead-letter.integration.test.ts} +11 -12
- package/src/event-store/__tests__/{upcaster.integration.ts → upcaster.integration.test.ts} +19 -32
- package/src/event-store/admin-api.ts +55 -83
- package/src/event-store/archive.ts +15 -39
- package/src/event-store/event-store.ts +92 -86
- package/src/event-store/events-schema.ts +2 -1
- package/src/event-store/index.ts +1 -0
- package/src/event-store/snapshot.ts +26 -24
- package/src/event-store/upcaster-dead-letter.ts +19 -18
- package/src/files/__tests__/content-disposition.test.ts +1 -1
- package/src/files/__tests__/{file-field-pipeline.integration.ts → file-field-pipeline.integration.test.ts} +8 -5
- package/src/files/__tests__/file-handle.test.ts +1 -1
- package/src/files/__tests__/{files.integration.ts → files.integration.test.ts} +32 -17
- package/src/files/__tests__/read-stream.test.ts +1 -1
- package/src/files/__tests__/{storage-tracking.integration.ts → storage-tracking.integration.test.ts} +26 -30
- package/src/files/__tests__/write-stream.test.ts +1 -1
- package/src/files/__tests__/zip-stream.test.ts +1 -1
- package/src/files/file-ref-table.ts +2 -2
- package/src/files/file-routes.ts +7 -9
- package/src/files/storage-tracking.ts +9 -17
- package/src/i18n/__tests__/i18n.test.ts +1 -1
- package/src/jobs/__tests__/{job-event-trigger.integration.ts → job-event-trigger.integration.test.ts} +6 -3
- package/src/jobs/__tests__/{job-multi-trigger.integration.ts → job-multi-trigger.integration.test.ts} +6 -3
- package/src/jobs/__tests__/{jobs.integration.ts → jobs.integration.test.ts} +5 -7
- package/src/lifecycle/__tests__/{lifecycle-server.integration.ts → lifecycle-server.integration.test.ts} +1 -1
- package/src/lifecycle/__tests__/lifecycle.test.ts +6 -6
- package/src/lifecycle/__tests__/signal-handlers.test.ts +6 -6
- package/src/logging/__tests__/pino-trace-bridge.test.ts +1 -1
- package/src/migrations/__tests__/compare-snapshots.test.ts +1 -1
- package/src/migrations/__tests__/{detect-drift.integration.ts → detect-drift.integration.test.ts} +34 -26
- package/src/migrations/__tests__/{detect-projections-to-rebuild.integration.ts → detect-projections-to-rebuild.integration.test.ts} +1 -1
- package/src/migrations/__tests__/rebuild-marker.test.ts +1 -1
- package/src/migrations/projection-detection.ts +12 -1
- package/src/migrations/schema-drift.ts +7 -23
- package/src/observability/__tests__/console-provider.test.ts +1 -1
- package/src/observability/__tests__/metric-validator.test.ts +1 -1
- package/src/observability/__tests__/noop-provider.test.ts +1 -1
- package/src/observability/__tests__/{observability.integration.ts → observability.integration.test.ts} +5 -8
- package/src/observability/__tests__/prometheus-meter.test.ts +1 -1
- package/src/observability/__tests__/recording-meter.test.ts +1 -1
- package/src/observability/__tests__/recording-tracer.test.ts +1 -1
- package/src/observability/__tests__/sensitive-filter.test.ts +1 -1
- package/src/pipeline/__tests__/{archive-stream.integration.ts → archive-stream.integration.test.ts} +3 -3
- package/src/pipeline/__tests__/auth-claims-resolver.test.ts +9 -9
- package/src/pipeline/__tests__/{cascade-handler.integration.ts → cascade-handler.integration.test.ts} +18 -15
- package/src/pipeline/__tests__/cascade-handler.test.ts +1 -1
- package/src/pipeline/__tests__/{causation-chain.integration.ts → causation-chain.integration.test.ts} +12 -13
- package/src/pipeline/__tests__/{ctx-bridge.integration.ts → ctx-bridge.integration.test.ts} +12 -11
- package/src/pipeline/__tests__/dispatcher-utils.test.ts +107 -0
- package/src/pipeline/__tests__/dispatcher.test.ts +2 -2
- package/src/pipeline/__tests__/{distributed-lock.integration.ts → distributed-lock.integration.test.ts} +1 -1
- package/src/pipeline/__tests__/{domain-events-projections.integration.ts → domain-events-projections.integration.test.ts} +13 -15
- package/src/pipeline/__tests__/{event-dedup.integration.ts → event-dedup.integration.test.ts} +1 -1
- package/src/pipeline/__tests__/{event-define-event-strict.integration.ts → event-define-event-strict.integration.test.ts} +6 -16
- package/src/pipeline/__tests__/{event-dispatcher-lifecycle.integration.ts → event-dispatcher-lifecycle.integration.test.ts} +1 -1
- package/src/pipeline/__tests__/{event-dispatcher-multi-instance.integration.ts → event-dispatcher-multi-instance.integration.test.ts} +3 -2
- package/src/pipeline/__tests__/{event-dispatcher-pg-listen.integration.ts → event-dispatcher-pg-listen.integration.test.ts} +1 -1
- package/src/pipeline/__tests__/{event-dispatcher-recovery.integration.ts → event-dispatcher-recovery.integration.test.ts} +2 -2
- package/src/pipeline/__tests__/{event-dispatcher-second-audit.integration.ts → event-dispatcher-second-audit.integration.test.ts} +17 -16
- package/src/pipeline/__tests__/event-dispatcher-strict.test.ts +14 -12
- package/src/pipeline/__tests__/{event-dispatcher.integration.ts → event-dispatcher.integration.test.ts} +8 -15
- package/src/pipeline/__tests__/{event-retention.integration.ts → event-retention.integration.test.ts} +28 -25
- package/src/pipeline/__tests__/{fetch-for-writing.integration.ts → fetch-for-writing.integration.test.ts} +6 -6
- package/src/pipeline/__tests__/lifecycle-pipeline.test.ts +4 -4
- package/src/pipeline/__tests__/{load-aggregate-query.integration.ts → load-aggregate-query.integration.test.ts} +9 -5
- package/src/pipeline/__tests__/{msp-error-mode.integration.ts → msp-error-mode.integration.test.ts} +1 -1
- package/src/pipeline/__tests__/{msp-multi-hop.integration.ts → msp-multi-hop.integration.test.ts} +9 -8
- package/src/pipeline/__tests__/{msp-rebuild.integration.ts → msp-rebuild.integration.test.ts} +47 -55
- package/src/pipeline/__tests__/{multi-stream-projection.integration.ts → multi-stream-projection.integration.test.ts} +19 -53
- package/src/pipeline/__tests__/{perf-rebuild.integration.ts → perf-rebuild.integration.test.ts} +36 -34
- package/src/pipeline/__tests__/{post-query-hook.integration.ts → post-query-hook.integration.test.ts} +1 -1
- package/src/pipeline/__tests__/{projection-rebuild.integration.ts → projection-rebuild.integration.test.ts} +21 -30
- package/src/pipeline/__tests__/{query-projection.integration.ts → query-projection.integration.test.ts} +6 -5
- package/src/pipeline/__tests__/redis-keys.test.ts +12 -0
- package/src/pipeline/__tests__/{redis-pipeline.integration.ts → redis-pipeline.integration.test.ts} +3 -1
- package/src/pipeline/cascade-handler.ts +13 -21
- package/src/pipeline/dispatcher-utils.ts +8 -7
- package/src/pipeline/dispatcher.ts +43 -48
- package/src/pipeline/event-consumer-state.ts +11 -2
- package/src/pipeline/event-dispatcher.ts +86 -146
- package/src/pipeline/event-retention.ts +14 -24
- package/src/pipeline/msp-rebuild.ts +54 -78
- package/src/pipeline/projection-rebuild.ts +65 -67
- package/src/pipeline/projection-state.ts +2 -2
- package/src/random/__tests__/generate.test.ts +13 -13
- package/src/rate-limit/__tests__/{dispatcher-l3.integration.ts → dispatcher-l3.integration.test.ts} +1 -1
- package/src/rate-limit/__tests__/{middleware.integration.ts → middleware.integration.test.ts} +1 -1
- package/src/rate-limit/__tests__/{resolver.integration.ts → resolver.integration.test.ts} +1 -1
- package/src/redis/__tests__/redis-options.test.ts +1 -1
- package/src/search/__tests__/{meilisearch-adapter.integration.ts → meilisearch-adapter.integration.test.ts} +1 -1
- package/src/search/__tests__/search-adapter.test.ts +1 -1
- package/src/secrets/__tests__/dek-cache.test.ts +1 -3
- package/src/secrets/__tests__/env-master-key-provider.test.ts +1 -1
- package/src/secrets/__tests__/envelope.test.ts +1 -1
- package/src/secrets/__tests__/leak-guard.test.ts +1 -1
- package/src/secrets/__tests__/rotation.test.ts +1 -1
- package/src/stack/db.ts +25 -48
- package/src/stack/push-entity-projection-tables.ts +2 -4
- package/src/stack/table-helpers.ts +98 -61
- package/src/stack/test-stack.ts +10 -9
- package/src/testing/__tests__/db-cleanup.test.ts +40 -0
- package/src/testing/__tests__/e2e-generator.test.ts +1 -1
- package/src/testing/__tests__/{ensure-entity-table.integration.ts → ensure-entity-table.integration.test.ts} +7 -14
- package/src/testing/db-cleanup.ts +44 -0
- package/src/testing/expect-error.ts +1 -1
- package/src/testing/index.ts +2 -0
- package/src/testing/multipart-helper.ts +94 -0
- package/src/testing/shared-entities.ts +5 -5
- package/src/time/__tests__/polyfill.test.ts +1 -1
- package/src/time/__tests__/tz-context.test.ts +1 -1
- package/src/utils/__tests__/assert.test.ts +1 -1
- package/src/utils/__tests__/case.test.ts +16 -0
- package/src/utils/__tests__/env-parse.test.ts +1 -1
- package/src/utils/__tests__/is-plain-object.test.ts +16 -0
- package/src/utils/__tests__/parse-string-array-json.test.ts +16 -0
- package/src/utils/__tests__/safe-json.test.ts +22 -0
- package/src/utils/case.ts +6 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/is-plain-object.ts +4 -0
- package/src/utils/parse-string-array-json.ts +14 -0
- package/CHANGELOG.md +0 -474
- package/src/db/__tests__/db-helpers.test.ts +0 -369
- package/src/db/__tests__/drizzle-helpers.integration.ts +0 -186
- package/src/db/__tests__/row-helpers.test.ts +0 -59
- package/src/engine/steps/_drizzle-boundary.ts +0 -19
- package/src/files/__tests__/file-field-column.integration.ts +0 -103
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { and, asc, desc, eq, gt, inArray, lt, ne, type SQL, sql } from "drizzle-orm";
|
|
2
|
-
import type { AnyPgColumn } from "drizzle-orm/pg-core";
|
|
3
1
|
import { requestContext } from "../api/request-context";
|
|
2
|
+
import { executeRawQuery } from "../db/queries/raw-sql";
|
|
3
|
+
import type { WhereObject } from "../db/query";
|
|
4
|
+
import { coerceRow, extractTableInfo, selectMany } from "../db/query";
|
|
4
5
|
import { checkWriteFieldOwnership } from "../engine/field-access";
|
|
5
6
|
import {
|
|
6
7
|
buildOwnershipClause,
|
|
8
|
+
shiftParams,
|
|
7
9
|
userCanCreateFieldRow,
|
|
8
10
|
userCanWriteFieldRow,
|
|
9
11
|
} from "../engine/ownership";
|
|
@@ -16,6 +18,7 @@ import type {
|
|
|
16
18
|
SessionUser,
|
|
17
19
|
WriteResult,
|
|
18
20
|
} from "../engine/types";
|
|
21
|
+
import { SYSTEM_TENANT_ID } from "../engine/types/identifiers";
|
|
19
22
|
import {
|
|
20
23
|
VersionConflictError as FrameworkVersionConflict,
|
|
21
24
|
InternalError,
|
|
@@ -41,39 +44,35 @@ import { decodeCursor, encodeCursor } from "./cursor";
|
|
|
41
44
|
import type { TableColumns } from "./dialect";
|
|
42
45
|
import type { CursorResult } from "./index";
|
|
43
46
|
import { constraintOf, isUniqueViolation } from "./pg-error";
|
|
47
|
+
import { toSnakeCase } from "./table-builder";
|
|
44
48
|
import type { TenantDb } from "./tenant-db";
|
|
45
49
|
|
|
46
50
|
// biome-ignore lint/suspicious/noExplicitAny: Drizzle dynamic tables
|
|
47
51
|
type Table = TableColumns<any>;
|
|
48
52
|
|
|
49
|
-
// Screen-Filter (Tier 2.7c) — Op-Mapping
|
|
50
|
-
//
|
|
51
|
-
//
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
// vs-Type-Compat ohnehin Kontrolle was reinkommt.
|
|
56
|
-
//
|
|
57
|
-
// Empty-array IN ist explizit "no match" (SQL false), nicht "match all".
|
|
58
|
-
function buildFilterCondition(
|
|
59
|
-
col: AnyPgColumn,
|
|
53
|
+
// Screen-Filter (Tier 2.7c) — Op-Mapping als Where-Operator. Boot-
|
|
54
|
+
// Validator pinst field-Existenz + filterable + op-vs-Type-Compat.
|
|
55
|
+
// `op` ist auf {eq,ne,lt,gt,in} normalisiert; "in" mit empty-array ist
|
|
56
|
+
// explizit no-match.
|
|
57
|
+
function buildFilterWhere(
|
|
58
|
+
field: string,
|
|
60
59
|
op: "eq" | "ne" | "lt" | "gt" | "in",
|
|
61
60
|
value: unknown,
|
|
62
|
-
):
|
|
61
|
+
): WhereObject | null {
|
|
63
62
|
switch (op) {
|
|
64
63
|
case "eq":
|
|
65
|
-
return
|
|
64
|
+
return { [field]: value };
|
|
66
65
|
case "ne":
|
|
67
|
-
return ne
|
|
66
|
+
return { [field]: { ne: value } };
|
|
68
67
|
case "lt":
|
|
69
|
-
return lt
|
|
68
|
+
return { [field]: { lt: value } };
|
|
70
69
|
case "gt":
|
|
71
|
-
return gt
|
|
70
|
+
return { [field]: { gt: value } };
|
|
72
71
|
case "in":
|
|
73
72
|
if (Array.isArray(value) && value.length > 0) {
|
|
74
|
-
return
|
|
73
|
+
return { [field]: value };
|
|
75
74
|
}
|
|
76
|
-
return
|
|
75
|
+
return null; // no-match short-circuit
|
|
77
76
|
default:
|
|
78
77
|
assertUnreachable(op, "filter op");
|
|
79
78
|
}
|
|
@@ -280,22 +279,61 @@ export function createEventStoreExecutor(
|
|
|
280
279
|
return result;
|
|
281
280
|
}
|
|
282
281
|
|
|
283
|
-
function idFilter(id: EntityId) {
|
|
284
|
-
const
|
|
285
|
-
if (softDelete && table["isDeleted"])
|
|
286
|
-
|
|
287
|
-
}
|
|
288
|
-
// Drizzle's variadic `and()` is typed `SQL | undefined`; conditions is
|
|
289
|
-
// guaranteed non-empty above (we pushed at least one).
|
|
290
|
-
return and(...conditions) as SQL; // @cast-boundary db-operator
|
|
282
|
+
function idFilter(id: EntityId): WhereObject {
|
|
283
|
+
const filter: WhereObject = { id };
|
|
284
|
+
if (softDelete && table["isDeleted"]) filter["isDeleted"] = false;
|
|
285
|
+
return filter;
|
|
291
286
|
}
|
|
292
287
|
|
|
293
288
|
async function loadById(id: EntityId, db: TenantDb): Promise<Record<string, unknown> | null> {
|
|
294
|
-
const
|
|
289
|
+
const row = await db.fetchOne(table, idFilter(id));
|
|
295
290
|
if (!row) return null;
|
|
296
291
|
return rehydrateCompoundTypes(row as DbRow, entity);
|
|
297
292
|
}
|
|
298
293
|
|
|
294
|
+
// SELECT a row by id with the ownership clause applied at the DB layer.
|
|
295
|
+
// Detail() uses this both on cold path and as a cache-revalidation probe.
|
|
296
|
+
async function loadWithOwnership(
|
|
297
|
+
db: TenantDb,
|
|
298
|
+
idWhere: WhereObject,
|
|
299
|
+
ownership:
|
|
300
|
+
| { kind: "pass" }
|
|
301
|
+
| { kind: "empty" }
|
|
302
|
+
| { kind: "sql"; sqlText: string; params: readonly unknown[] },
|
|
303
|
+
): Promise<Record<string, unknown>[]> {
|
|
304
|
+
if (ownership.kind === "empty") return [];
|
|
305
|
+
if (ownership.kind === "pass") {
|
|
306
|
+
const row = await db.fetchOne(table, idWhere);
|
|
307
|
+
return row ? [row as Record<string, unknown>] : [];
|
|
308
|
+
}
|
|
309
|
+
// ownership has raw SQL — splice it into a raw query alongside the
|
|
310
|
+
// idFilter + tenant-filter that TenantDb would have added.
|
|
311
|
+
const tableName = String(
|
|
312
|
+
(table as unknown as Record<symbol, unknown>)[Symbol.for("kumiko:schema:Name")],
|
|
313
|
+
);
|
|
314
|
+
const colSql = (field: string): string =>
|
|
315
|
+
`"${(table[field] as { name?: string } | undefined)?.name ?? toSnakeCase(field)}"`;
|
|
316
|
+
const whereParts: string[] = [];
|
|
317
|
+
const params: unknown[] = [];
|
|
318
|
+
if (table["tenantId"] !== undefined && db.mode === "tenant") {
|
|
319
|
+
params.push(db.tenantId, SYSTEM_TENANT_ID);
|
|
320
|
+
whereParts.push(`${colSql("tenantId")} IN ($${params.length - 1}, $${params.length})`);
|
|
321
|
+
}
|
|
322
|
+
for (const [field, value] of Object.entries(idWhere)) {
|
|
323
|
+
if (typeof value === "boolean") {
|
|
324
|
+
whereParts.push(`${colSql(field)} = ${value ? "TRUE" : "FALSE"}`);
|
|
325
|
+
} else {
|
|
326
|
+
params.push(value);
|
|
327
|
+
whereParts.push(`${colSql(field)} = $${params.length}`);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
const shifted = shiftParams(ownership, params.length);
|
|
331
|
+
whereParts.push(shifted.sqlText);
|
|
332
|
+
for (const p of shifted.params) params.push(p);
|
|
333
|
+
const sqlText = `SELECT * FROM "${tableName}" WHERE ${whereParts.join(" AND ")} LIMIT 1`;
|
|
334
|
+
return [...(await executeRawQuery<Record<string, unknown>>(db.raw, sqlText, params))];
|
|
335
|
+
}
|
|
336
|
+
|
|
299
337
|
return {
|
|
300
338
|
async create(payload, user, db) {
|
|
301
339
|
// Respect an explicit id in the payload (seed pattern, SCIM import). Without
|
|
@@ -665,7 +703,7 @@ export function createEventStoreExecutor(
|
|
|
665
703
|
);
|
|
666
704
|
}
|
|
667
705
|
|
|
668
|
-
const [row] = await db.
|
|
706
|
+
const [row] = await selectMany(db.raw, table, { id: payload.id });
|
|
669
707
|
if (!row) return writeFailure(new NotFoundError(entityName, payload.id));
|
|
670
708
|
const data = row as DbRow;
|
|
671
709
|
if (!data["isDeleted"]) {
|
|
@@ -770,59 +808,98 @@ export function createEventStoreExecutor(
|
|
|
770
808
|
}
|
|
771
809
|
}
|
|
772
810
|
|
|
773
|
-
|
|
811
|
+
// Build the WHERE clause as raw SQL — ownership produces a
|
|
812
|
+
// parameterised fragment that we splice in alongside simple WhereObject
|
|
813
|
+
// conditions (cursor, search-filter-IDs, screen-filter, tenant-scope).
|
|
814
|
+
const tableName = String(
|
|
815
|
+
(table as unknown as Record<symbol, unknown>)[Symbol.for("kumiko:schema:Name")],
|
|
816
|
+
);
|
|
817
|
+
const whereSql: string[] = [];
|
|
818
|
+
const params: unknown[] = [];
|
|
819
|
+
const colSql = (field: string): string =>
|
|
820
|
+
`"${(table[field] as { name?: string } | undefined)?.name ?? toSnakeCase(field)}"`;
|
|
821
|
+
|
|
822
|
+
// Tenant-Filter (replicates TenantDb's readWhere semantics).
|
|
823
|
+
if (table["tenantId"] !== undefined && db.mode === "tenant") {
|
|
824
|
+
params.push(db.tenantId, SYSTEM_TENANT_ID);
|
|
825
|
+
whereSql.push(`${colSql("tenantId")} IN ($${params.length - 1}, $${params.length})`);
|
|
826
|
+
}
|
|
774
827
|
if (softDelete && table["isDeleted"]) {
|
|
775
|
-
|
|
828
|
+
whereSql.push(`${colSql("isDeleted")} = FALSE`);
|
|
776
829
|
}
|
|
777
|
-
// Cursor und Offset schließen sich aus: Cursor ist DB-stable (gt id),
|
|
778
|
-
// Offset ist für klassische Page-Navigation. Wenn beide gesetzt sind,
|
|
779
|
-
// gewinnt Cursor — Caller hätte eh nicht gleichzeitig beide nutzen
|
|
780
|
-
// sollen, das pinnt die Verteidigung.
|
|
781
830
|
if (payload.cursor) {
|
|
782
|
-
|
|
831
|
+
params.push(decodeCursor(payload.cursor));
|
|
832
|
+
whereSql.push(`${colSql("id")} > $${params.length}`);
|
|
783
833
|
}
|
|
784
834
|
if (filterIds) {
|
|
785
|
-
|
|
835
|
+
const placeholders = filterIds.map((id) => {
|
|
836
|
+
params.push(id);
|
|
837
|
+
return `$${params.length}`;
|
|
838
|
+
});
|
|
839
|
+
whereSql.push(`${colSql("id")} IN (${placeholders.join(", ")})`);
|
|
786
840
|
}
|
|
787
841
|
if (ownership.kind === "sql") {
|
|
788
|
-
|
|
842
|
+
const shifted = shiftParams(
|
|
843
|
+
{ sqlText: ownership.sqlText, params: ownership.params },
|
|
844
|
+
params.length,
|
|
845
|
+
);
|
|
846
|
+
whereSql.push(shifted.sqlText);
|
|
847
|
+
for (const p of shifted.params) params.push(p);
|
|
789
848
|
}
|
|
790
|
-
// Screen-Filter (Tier 2.7c) — Boot-Validator hat field-Existenz
|
|
791
|
-
// + filterable + op-vs-Type-Compat schon gepinnt. Runtime-Defense:
|
|
792
|
-
// undefined-column → silent skip (kein Crash). Op-Mapping läuft
|
|
793
|
-
// durch buildFilterCondition() — da lebt auch der einzige
|
|
794
|
-
// `as never`-Cast (Wire-Boundary).
|
|
795
849
|
if (payload.filter !== undefined) {
|
|
796
850
|
const col = table[payload.filter.field];
|
|
797
851
|
if (col !== undefined) {
|
|
798
|
-
|
|
852
|
+
const screen = buildFilterWhere(
|
|
853
|
+
payload.filter.field,
|
|
854
|
+
payload.filter.op,
|
|
855
|
+
payload.filter.value,
|
|
856
|
+
);
|
|
857
|
+
if (screen === null) {
|
|
858
|
+
whereSql.push("FALSE");
|
|
859
|
+
} else {
|
|
860
|
+
for (const [field, value] of Object.entries(screen)) {
|
|
861
|
+
if (Array.isArray(value)) {
|
|
862
|
+
const placeholders = value.map((v) => {
|
|
863
|
+
params.push(v);
|
|
864
|
+
return `$${params.length}`;
|
|
865
|
+
});
|
|
866
|
+
whereSql.push(`${colSql(field)} IN (${placeholders.join(", ")})`);
|
|
867
|
+
} else if (typeof value === "object" && value !== null) {
|
|
868
|
+
const opMap: Record<string, string> = {
|
|
869
|
+
gt: ">",
|
|
870
|
+
gte: ">=",
|
|
871
|
+
lt: "<",
|
|
872
|
+
lte: "<=",
|
|
873
|
+
ne: "<>",
|
|
874
|
+
};
|
|
875
|
+
for (const [opKey, opSym] of Object.entries(opMap)) {
|
|
876
|
+
if (!(opKey in value)) continue;
|
|
877
|
+
params.push((value as Record<string, unknown>)[opKey]);
|
|
878
|
+
whereSql.push(`${colSql(field)} ${opSym} $${params.length}`);
|
|
879
|
+
}
|
|
880
|
+
} else {
|
|
881
|
+
params.push(value);
|
|
882
|
+
whereSql.push(`${colSql(field)} = $${params.length}`);
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
}
|
|
799
886
|
}
|
|
800
887
|
}
|
|
801
888
|
|
|
802
|
-
const
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
889
|
+
const orderByClause =
|
|
890
|
+
payload.sort && table[payload.sort]
|
|
891
|
+
? ` ORDER BY ${colSql(payload.sort)} ${payload.sortDirection === "desc" ? "DESC" : "ASC"}`
|
|
892
|
+
: "";
|
|
893
|
+
const useOffset = !payload.cursor && offset > 0;
|
|
894
|
+
const offsetClause = useOffset ? ` OFFSET ${offset}` : "";
|
|
806
895
|
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
// Pagination-Schemes und der Caller bekommt unverhoffte Skips.
|
|
810
|
-
if (!payload.cursor && offset > 0) {
|
|
811
|
-
query = query.offset(offset);
|
|
812
|
-
}
|
|
896
|
+
const whereClauseSqlText = whereSql.length > 0 ? ` WHERE ${whereSql.join(" AND ")}` : "";
|
|
897
|
+
const listSql = `SELECT * FROM "${tableName}"${whereClauseSqlText}${orderByClause} LIMIT ${limit}${offsetClause}`;
|
|
813
898
|
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
? query.orderBy(desc(column))
|
|
819
|
-
: query.orderBy(asc(column));
|
|
820
|
-
}
|
|
821
|
-
|
|
822
|
-
const rawRows = (await query) as Record<string, unknown>[]; // @cast-boundary engine-payload
|
|
823
|
-
// Read-Side rehydrate pro Row. Cache speichert die hydrated Form,
|
|
824
|
-
// damit Cache-Hits dieselbe API-Form liefern.
|
|
825
|
-
const rows = rawRows.map((r) => rehydrateCompoundTypes(r, entity));
|
|
899
|
+
const rawRows = await executeRawQuery<Record<string, unknown>>(db.raw, listSql, params);
|
|
900
|
+
// Read-Side rehydrate pro Row + snake→camel coercion für driver-agnostic Feldnamen
|
|
901
|
+
const tableInfo = extractTableInfo(table);
|
|
902
|
+
const rows = rawRows.map((r) => coerceRow(rehydrateCompoundTypes(r, entity), tableInfo));
|
|
826
903
|
|
|
827
904
|
if (entityCache && entityName && rows.length > 0) {
|
|
828
905
|
await entityCache.mset(
|
|
@@ -845,11 +922,9 @@ export function createEventStoreExecutor(
|
|
|
845
922
|
if (filterIds) {
|
|
846
923
|
total = filterIds.length;
|
|
847
924
|
} else {
|
|
848
|
-
const
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
const countRow = (await countQuery) as Array<{ count: number }>; // @cast-boundary db-row
|
|
852
|
-
total = countRow[0]?.count ?? 0;
|
|
925
|
+
const countSql = `SELECT COUNT(*)::int AS count FROM "${tableName}"${whereClauseSqlText}`;
|
|
926
|
+
const countRows = await executeRawQuery<{ count: number }>(db.raw, countSql, params);
|
|
927
|
+
total = countRows[0]?.count ?? 0;
|
|
853
928
|
}
|
|
854
929
|
}
|
|
855
930
|
|
|
@@ -863,50 +938,33 @@ export function createEventStoreExecutor(
|
|
|
863
938
|
const ownership = buildOwnershipClause(user, entity.access?.read, table);
|
|
864
939
|
if (ownership.kind === "empty") return null;
|
|
865
940
|
|
|
941
|
+
const idWhere = idFilter(payload.id);
|
|
942
|
+
|
|
866
943
|
if (entityCache && entityName) {
|
|
867
944
|
const cached = await entityCache.get(user.tenantId, entityName, payload.id);
|
|
868
945
|
if (cached) {
|
|
869
|
-
// Even with a cache hit the ownership predicate must hold. The
|
|
870
|
-
// cache is keyed only by tenant + id, not by role, so a cached
|
|
871
|
-
// row may be visible to caller A but not caller B — re-check
|
|
872
|
-
// per request.
|
|
873
946
|
if (ownership.kind === "sql") {
|
|
874
|
-
//
|
|
875
|
-
//
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
const checked = await db
|
|
879
|
-
.select()
|
|
880
|
-
.from(table)
|
|
881
|
-
.where(and(idFilter(payload.id), ownership.sql) as SQL) // @cast-boundary db-operator
|
|
882
|
-
.limit(1);
|
|
883
|
-
if (checked.length === 0) return null;
|
|
947
|
+
// Re-check ownership predicate against the live row — the cache
|
|
948
|
+
// is keyed only by tenant + id, not by role.
|
|
949
|
+
const checkRows = await loadWithOwnership(db, idWhere, ownership);
|
|
950
|
+
if (checkRows.length === 0) return null;
|
|
884
951
|
}
|
|
885
952
|
return cached;
|
|
886
953
|
}
|
|
887
954
|
}
|
|
888
955
|
|
|
889
|
-
|
|
890
|
-
// DB does the filtering (cheaper than load-then-filter-in-JS). Reuse
|
|
891
|
-
// idFilter() — it handles the soft-delete guard consistently with
|
|
892
|
-
// loadById(), which we can't just call directly because it doesn't
|
|
893
|
-
// thread the ownership clause.
|
|
894
|
-
const baseFilter = idFilter(payload.id);
|
|
895
|
-
const whereClause =
|
|
896
|
-
ownership.kind === "sql" ? (and(baseFilter, ownership.sql) as SQL) : baseFilter; // @cast-boundary db-operator
|
|
897
|
-
const rows = (await db.select().from(table).where(whereClause).limit(1)) as Record<
|
|
898
|
-
string,
|
|
899
|
-
unknown
|
|
900
|
-
>[]; // @cast-boundary db-row
|
|
956
|
+
const rows = await loadWithOwnership(db, idWhere, ownership);
|
|
901
957
|
const raw = rows[0];
|
|
902
958
|
if (!raw) return null;
|
|
903
959
|
const row = rehydrateCompoundTypes(raw, entity);
|
|
960
|
+
const rowInfo = extractTableInfo(table);
|
|
961
|
+
const coerced = coerceRow(row, rowInfo);
|
|
904
962
|
|
|
905
963
|
if (entityCache && entityName) {
|
|
906
|
-
await entityCache.set(user.tenantId, entityName, payload.id,
|
|
964
|
+
await entityCache.set(user.tenantId, entityName, payload.id, coerced);
|
|
907
965
|
}
|
|
908
966
|
|
|
909
|
-
return
|
|
967
|
+
return coerced;
|
|
910
968
|
},
|
|
911
969
|
};
|
|
912
970
|
}
|
package/src/db/index.ts
CHANGED
|
@@ -4,15 +4,22 @@ export { seedConfigValues } from "./config-seed";
|
|
|
4
4
|
export type { DbConnection, DbConnectionOptions, DbRow, DbRunner, DbTx } from "./connection";
|
|
5
5
|
export { createDbConnection, dbConnectionOptionsFromEnv } from "./connection";
|
|
6
6
|
export type { CursorQueryOptions, CursorResult } from "./cursor";
|
|
7
|
-
export {
|
|
8
|
-
export type { SelectQuery, TableColumns } from "./dialect";
|
|
7
|
+
export { decodeCursor, encodeCursor } from "./cursor";
|
|
8
|
+
export type { SchemaTable, SelectQuery, TableColumns } from "./dialect";
|
|
9
9
|
export {
|
|
10
|
+
bigint,
|
|
11
|
+
bigserial,
|
|
10
12
|
boolean,
|
|
13
|
+
index,
|
|
11
14
|
instant,
|
|
15
|
+
instantToDriver,
|
|
12
16
|
integer,
|
|
13
17
|
jsonb,
|
|
18
|
+
moneyAmount,
|
|
19
|
+
numeric,
|
|
14
20
|
primaryKey,
|
|
15
21
|
serial,
|
|
22
|
+
sql,
|
|
16
23
|
table,
|
|
17
24
|
text,
|
|
18
25
|
timestamp,
|
|
@@ -27,6 +34,16 @@ export {
|
|
|
27
34
|
} from "./eagerload";
|
|
28
35
|
export type { EncryptionProvider } from "./encryption";
|
|
29
36
|
export { createEncryptionProvider } from "./encryption";
|
|
37
|
+
export type {
|
|
38
|
+
BuildEntityTableMetaOptions,
|
|
39
|
+
ColumnMeta,
|
|
40
|
+
CompositePrimaryKeyMeta,
|
|
41
|
+
EntityTableMeta,
|
|
42
|
+
IndexMeta,
|
|
43
|
+
PgType,
|
|
44
|
+
UnmanagedTableInput,
|
|
45
|
+
} from "./entity-table-meta";
|
|
46
|
+
export { buildEntityTableMeta, defineUnmanagedTable } from "./entity-table-meta";
|
|
30
47
|
export type {
|
|
31
48
|
EntityLifecycleVerb,
|
|
32
49
|
EventStoreExecutor,
|
|
@@ -42,13 +59,24 @@ export {
|
|
|
42
59
|
isUniqueViolation,
|
|
43
60
|
type PgErrorInfo,
|
|
44
61
|
} from "./pg-error";
|
|
62
|
+
export type { SelectOptions, WhereObject, WhereValue } from "./query-api";
|
|
63
|
+
export {
|
|
64
|
+
asRawClient,
|
|
65
|
+
deleteMany,
|
|
66
|
+
fetchOne,
|
|
67
|
+
insertMany,
|
|
68
|
+
insertOne,
|
|
69
|
+
selectMany,
|
|
70
|
+
transaction,
|
|
71
|
+
updateMany,
|
|
72
|
+
} from "./query-api";
|
|
45
73
|
export { seedReferenceData } from "./reference-data";
|
|
46
|
-
export {
|
|
74
|
+
export { renderTableDdl, renderTablesDdl } from "./render-ddl";
|
|
47
75
|
export { tableExists } from "./schema-inspection";
|
|
48
76
|
export {
|
|
49
77
|
buildBaseColumns,
|
|
50
|
-
|
|
51
|
-
type
|
|
78
|
+
buildEntityTable,
|
|
79
|
+
type EntityTable,
|
|
52
80
|
toSnakeCase,
|
|
53
81
|
toTableName,
|
|
54
82
|
} from "./table-builder";
|