@cosmicdrift/kumiko-framework 0.13.0 → 0.15.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 +7 -7
- 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/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 +845 -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/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__/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__/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__/{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 +48 -40
- 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__/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-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__/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__/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 +1 -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/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 +2 -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 +7 -2
- package/src/engine/types/fields.ts +4 -5
- 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__/write-failures.test.ts +1 -1
- 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 +9 -43
- 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.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-pipeline.integration.ts → redis-pipeline.integration.test.ts} +3 -1
- package/src/pipeline/cascade-handler.ts +13 -21
- 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 +8 -7
- 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__/env-parse.test.ts +1 -1
- package/CHANGELOG.md +0 -472
- package/src/db/__tests__/cursor.test.ts +0 -41
- 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
|
@@ -5,8 +5,8 @@
|
|
|
5
5
|
// Singular/Plural). Der Bug aus dem U5a-Review (`{hours: 6}` fiel auf
|
|
6
6
|
// 30d-Default) wird hier zentral verhindert.
|
|
7
7
|
|
|
8
|
+
import { beforeAll, describe, expect, test } from "bun:test";
|
|
8
9
|
import { ensureTemporalPolyfill, getTemporal } from "@cosmicdrift/kumiko-framework/time";
|
|
9
|
-
import { beforeAll, describe, expect, test } from "vitest";
|
|
10
10
|
import { addDurationSpec, describeDurationSpec, durationSpecToMs } from "../duration-spec";
|
|
11
11
|
|
|
12
12
|
beforeAll(async () => {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
// 3. Deep-merge-Semantik beim Override (rekursiv, Top-Level-Replace nicht)
|
|
7
7
|
// 4. Override darf einzelne Felder gezielt setzen ohne Required-Drops
|
|
8
8
|
|
|
9
|
-
import { describe, expect, test } from "
|
|
9
|
+
import { describe, expect, test } from "bun:test";
|
|
10
10
|
import { complianceProfileOverrideSchema } from "../override-schema";
|
|
11
11
|
import {
|
|
12
12
|
COMPLIANCE_PROFILES,
|
|
@@ -15,15 +15,16 @@
|
|
|
15
15
|
// zerbrechen — der bestehende seed-Test wäre der einzige Catcher, und
|
|
16
16
|
// der lief vor dem Refactor durch Zufall grün.
|
|
17
17
|
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
18
|
+
import { afterAll, beforeAll, beforeEach, describe, expect, test } from "bun:test";
|
|
19
|
+
import { type BunTestDb, createTestDb } from "../../bun-db/__tests__/bun-test-db";
|
|
20
|
+
import { asRawClient, selectMany } from "../../db/query";
|
|
20
21
|
import { createEntity, createTextField } from "../../engine/factories";
|
|
21
22
|
import type { TenantId } from "../../engine/types";
|
|
22
23
|
import type { StoredEvent } from "../../event-store";
|
|
23
24
|
import { createEventsTable } from "../../event-store";
|
|
24
|
-
import {
|
|
25
|
+
import { ensureTemporalPolyfill } from "../../time/polyfill";
|
|
25
26
|
import { applyEntityEvent } from "../apply-entity-event";
|
|
26
|
-
import {
|
|
27
|
+
import { buildEntityTable } from "../table-builder";
|
|
27
28
|
|
|
28
29
|
const entity = createEntity({
|
|
29
30
|
table: "read_apply_tenant_check",
|
|
@@ -31,14 +32,15 @@ const entity = createEntity({
|
|
|
31
32
|
name: createTextField({ required: true }),
|
|
32
33
|
},
|
|
33
34
|
});
|
|
34
|
-
const table =
|
|
35
|
+
const table = buildEntityTable("apply-tenant-check", entity);
|
|
35
36
|
|
|
36
|
-
let testDb:
|
|
37
|
+
let testDb: BunTestDb;
|
|
37
38
|
|
|
38
39
|
beforeAll(async () => {
|
|
40
|
+
await ensureTemporalPolyfill();
|
|
39
41
|
testDb = await createTestDb();
|
|
40
42
|
await createEventsTable(testDb.db);
|
|
41
|
-
await testDb.db.
|
|
43
|
+
await asRawClient(testDb.db).unsafe(`
|
|
42
44
|
CREATE TABLE read_apply_tenant_check (
|
|
43
45
|
id uuid PRIMARY KEY,
|
|
44
46
|
tenant_id uuid NOT NULL,
|
|
@@ -57,7 +59,7 @@ afterAll(async () => {
|
|
|
57
59
|
});
|
|
58
60
|
|
|
59
61
|
beforeEach(async () => {
|
|
60
|
-
await testDb.db.
|
|
62
|
+
await asRawClient(testDb.db).unsafe(`TRUNCATE read_apply_tenant_check`);
|
|
61
63
|
});
|
|
62
64
|
|
|
63
65
|
const TENANT_OPERATOR = "11111111-1111-1111-1111-111111111111" as TenantId;
|
|
@@ -85,7 +87,7 @@ describe("applyEntityEvent — tenantId-Defaulting", () => {
|
|
|
85
87
|
const result = await applyEntityEvent(event, table, entity, testDb.db);
|
|
86
88
|
expect(result.kind).toBe("applied");
|
|
87
89
|
|
|
88
|
-
const [row] = await testDb.db
|
|
90
|
+
const [row] = await selectMany(testDb.db, table, { id: event.aggregateId });
|
|
89
91
|
expect(row?.["tenantId"]).toBe(TENANT_OPERATOR);
|
|
90
92
|
expect(row?.["name"]).toBe("without-tenantId-in-payload");
|
|
91
93
|
});
|
|
@@ -101,7 +103,7 @@ describe("applyEntityEvent — tenantId-Defaulting", () => {
|
|
|
101
103
|
const result = await applyEntityEvent(event, table, entity, testDb.db);
|
|
102
104
|
expect(result.kind).toBe("applied");
|
|
103
105
|
|
|
104
|
-
const [row] = await testDb.db
|
|
106
|
+
const [row] = await selectMany(testDb.db, table, { id: event.aggregateId });
|
|
105
107
|
expect(row?.["tenantId"]).toBe(TENANT_TARGET);
|
|
106
108
|
expect(row?.["tenantId"]).not.toBe(TENANT_OPERATOR);
|
|
107
109
|
});
|
|
@@ -148,7 +150,7 @@ describe("applyEntityEvent — tenantId-Defaulting", () => {
|
|
|
148
150
|
const result = await applyEntityEvent(event, table, entity, testDb.db);
|
|
149
151
|
expect(result.kind).toBe("applied");
|
|
150
152
|
|
|
151
|
-
const [row] = await testDb.db
|
|
153
|
+
const [row] = await selectMany(testDb.db, table, { id: event.aggregateId });
|
|
152
154
|
// event.aggregateId wins, nicht payload.id
|
|
153
155
|
expect(row?.["id"]).toBe(event.aggregateId);
|
|
154
156
|
// event.version wins, nicht payload.version
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
//
|
|
4
4
|
// Pinst:
|
|
5
5
|
// - createBigIntField liefert FieldDefinition.type === "bigInt"
|
|
6
|
-
// -
|
|
6
|
+
// - buildEntityTable mappt auf bigint(name, mode:"number"), nicht
|
|
7
7
|
// integer (32-bit) → kein silent 2 GB-Cap
|
|
8
8
|
// - Zod-Schema akzeptiert int + safe-integer + lehnt non-int + Float
|
|
9
9
|
// + non-safe-integer ab
|
|
@@ -15,19 +15,20 @@
|
|
|
15
15
|
// einrichten — pinst dort auf realer Postgres + Drizzle-customType-
|
|
16
16
|
// Path statt parallel-mock hier.
|
|
17
17
|
|
|
18
|
-
import { describe, expect, test } from "
|
|
18
|
+
import { describe, expect, test } from "bun:test";
|
|
19
19
|
import { createBigIntField, createEntity, createNumberField } from "../../engine";
|
|
20
20
|
import { buildInsertSchema } from "../../engine/schema-builder";
|
|
21
|
-
import {
|
|
21
|
+
import { buildEntityTable } from "../table-builder";
|
|
22
22
|
|
|
23
|
-
function colByName(table:
|
|
24
|
-
|
|
25
|
-
name?: string
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
function colByName(table: unknown, dbName: string) {
|
|
24
|
+
const cols = (
|
|
25
|
+
table as { columns?: ReadonlyArray<{ name: string; notNull?: boolean; pgType?: string }> }
|
|
26
|
+
).columns;
|
|
27
|
+
if (!cols) throw new Error("Table has no columns metadata");
|
|
28
|
+
for (const c of cols) {
|
|
29
|
+
if (c.name === dbName) {
|
|
30
|
+
return { name: c.name, notNull: c.notNull, columnType: c.pgType, dataType: c.pgType };
|
|
31
|
+
}
|
|
31
32
|
}
|
|
32
33
|
throw new Error(`Column ${dbName} not found in table`);
|
|
33
34
|
}
|
|
@@ -53,7 +54,7 @@ describe("createBigIntField factory", () => {
|
|
|
53
54
|
});
|
|
54
55
|
});
|
|
55
56
|
|
|
56
|
-
describe("
|
|
57
|
+
describe("buildEntityTable — bigInt-Mapping", () => {
|
|
57
58
|
test("bigInt-Spalte ist DISTINCT von number-Spalte (number=integer/32-bit, bigInt=bigint/64-bit)", () => {
|
|
58
59
|
const entity = createEntity({
|
|
59
60
|
fields: {
|
|
@@ -61,7 +62,7 @@ describe("buildDrizzleTable — bigInt-Mapping", () => {
|
|
|
61
62
|
bigCount: createBigIntField({}),
|
|
62
63
|
},
|
|
63
64
|
});
|
|
64
|
-
const table =
|
|
65
|
+
const table = buildEntityTable("counters", entity);
|
|
65
66
|
|
|
66
67
|
const small = colByName(table, "small_count");
|
|
67
68
|
const big = colByName(table, "big_count");
|
|
@@ -79,7 +80,7 @@ describe("buildDrizzleTable — bigInt-Mapping", () => {
|
|
|
79
80
|
optionalBig: createBigIntField({}),
|
|
80
81
|
},
|
|
81
82
|
});
|
|
82
|
-
const table =
|
|
83
|
+
const table = buildEntityTable("t", entity);
|
|
83
84
|
expect(colByName(table, "required_big").notNull).toBe(true);
|
|
84
85
|
expect(colByName(table, "optional_big").notNull).toBe(false);
|
|
85
86
|
});
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// DDL-Render-Test: alle pgTable Column-Types + Builder-Optionen.
|
|
2
|
+
import { describe, expect, test } from "bun:test";
|
|
3
|
+
import {
|
|
4
|
+
bigint,
|
|
5
|
+
bigserial,
|
|
6
|
+
integer,
|
|
7
|
+
jsonb,
|
|
8
|
+
boolean as pgBoolean,
|
|
9
|
+
table as pgTable,
|
|
10
|
+
serial,
|
|
11
|
+
text,
|
|
12
|
+
timestamp,
|
|
13
|
+
uuid,
|
|
14
|
+
} from "../dialect";
|
|
15
|
+
import { renderTableDdl } from "../render-ddl";
|
|
16
|
+
|
|
17
|
+
function findIndex(ddl: readonly string[], pattern: RegExp): boolean {
|
|
18
|
+
return ddl.some((s) => pattern.test(s));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
describe("renderTableDdl — column types", () => {
|
|
22
|
+
test("uuid notNull primaryKey defaultRandom", () => {
|
|
23
|
+
const t = pgTable("t_uuid", { id: uuid("id").primaryKey().defaultRandom() });
|
|
24
|
+
// biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
|
|
25
|
+
const ddl = renderTableDdl(t as any);
|
|
26
|
+
expect(ddl[0]).toContain('"id" uuid PRIMARY KEY DEFAULT gen_random_uuid()');
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("text notNull unique", () => {
|
|
30
|
+
const t = pgTable("t_text", { slug: text("slug").notNull().unique() });
|
|
31
|
+
// biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
|
|
32
|
+
const ddl = renderTableDdl(t as any);
|
|
33
|
+
expect(ddl[0]).toContain('"slug" text NOT NULL');
|
|
34
|
+
expect(findIndex(ddl, /UNIQUE INDEX/)).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("integer default", () => {
|
|
38
|
+
const t = pgTable("t_int", { count: integer("count").default(0) });
|
|
39
|
+
// biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
|
|
40
|
+
const ddl = renderTableDdl(t as any);
|
|
41
|
+
expect(ddl[0]).toContain('"count" integer DEFAULT 0');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("serial primaryKey", () => {
|
|
45
|
+
const t = pgTable("t_serial", { id: serial("id").primaryKey() });
|
|
46
|
+
// biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
|
|
47
|
+
const ddl = renderTableDdl(t as any);
|
|
48
|
+
expect(ddl[0]).toContain('"id" serial PRIMARY KEY');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test("bigserial primaryKey", () => {
|
|
52
|
+
const t = pgTable("t_bigserial", { id: bigserial("id").primaryKey() });
|
|
53
|
+
// biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
|
|
54
|
+
const ddl = renderTableDdl(t as any);
|
|
55
|
+
expect(ddl[0]).toContain('"id" bigserial PRIMARY KEY');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test("bigint notNull", () => {
|
|
59
|
+
const t = pgTable("t_bigint", { amount: bigint("amount").notNull() });
|
|
60
|
+
// biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
|
|
61
|
+
const ddl = renderTableDdl(t as any);
|
|
62
|
+
expect(ddl[0]).toContain('"amount" bigint NOT NULL');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
test("boolean default", () => {
|
|
66
|
+
const t = pgTable("t_bool", { active: pgBoolean("active").default(true) });
|
|
67
|
+
// biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
|
|
68
|
+
const ddl = renderTableDdl(t as any);
|
|
69
|
+
expect(ddl[0]).toContain('"active" boolean DEFAULT true');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("jsonb notNull", () => {
|
|
73
|
+
const t = pgTable("t_jsonb", { data: jsonb("data").notNull() });
|
|
74
|
+
// biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
|
|
75
|
+
const ddl = renderTableDdl(t as any);
|
|
76
|
+
expect(ddl[0]).toContain('"data" jsonb NOT NULL');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("timestamptz defaultNow", () => {
|
|
80
|
+
const t = pgTable("t_ts", {
|
|
81
|
+
created: timestamp("created", { withTimezone: true }).notNull().defaultNow(),
|
|
82
|
+
});
|
|
83
|
+
// biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
|
|
84
|
+
const ddl = renderTableDdl(t as any);
|
|
85
|
+
expect(ddl[0]).toContain('"created" timestamp with time zone DEFAULT now() NOT NULL');
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test("bigint generatedAlwaysAsIdentity primaryKey", () => {
|
|
89
|
+
const t = pgTable("t_ident", { id: bigint("id").primaryKey().generatedAlwaysAsIdentity() });
|
|
90
|
+
// biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
|
|
91
|
+
const ddl = renderTableDdl(t as any);
|
|
92
|
+
expect(ddl[0]).toContain("GENERATED ALWAYS AS IDENTITY");
|
|
93
|
+
expect(ddl[0]).not.toContain("DEFAULT"); // identity replaces default
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test("composite: multiple columns with various options", () => {
|
|
97
|
+
const t = pgTable("t_composite", {
|
|
98
|
+
pk: bigint("pk").primaryKey().generatedAlwaysAsIdentity(),
|
|
99
|
+
name: text("name").notNull(),
|
|
100
|
+
slug: text("slug").notNull().unique(),
|
|
101
|
+
active: pgBoolean("active").default(true),
|
|
102
|
+
data: jsonb("data"),
|
|
103
|
+
created: timestamp("created", { withTimezone: true }).notNull().defaultNow(),
|
|
104
|
+
});
|
|
105
|
+
// biome-ignore lint/suspicious/noExplicitAny: DDL test uses cast for mock tables
|
|
106
|
+
const ddl = renderTableDdl(t as any);
|
|
107
|
+
expect(ddl[0]).toContain("GENERATED ALWAYS AS IDENTITY");
|
|
108
|
+
expect(ddl[0]).toContain('"name" text NOT NULL');
|
|
109
|
+
expect(ddl[0]).toContain('"active" boolean DEFAULT true');
|
|
110
|
+
expect(ddl[0]).toContain('"data" jsonb');
|
|
111
|
+
expect(findIndex(ddl, /UNIQUE INDEX.*slug/)).toBe(true);
|
|
112
|
+
});
|
|
113
|
+
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { afterAll, beforeAll, beforeEach, describe, expect, test } from "bun:test";
|
|
2
|
+
import { type BunTestDb, createTestDb } from "../../bun-db/__tests__/bun-test-db";
|
|
3
|
+
import { asRawClient } from "../../db/query";
|
|
3
4
|
import {
|
|
4
5
|
createEntity,
|
|
5
6
|
createSystemConfig,
|
|
@@ -9,10 +10,11 @@ import {
|
|
|
9
10
|
SYSTEM_TENANT_ID,
|
|
10
11
|
} from "../../engine";
|
|
11
12
|
import type { ConfigSeedDef, Registry } from "../../engine/types";
|
|
12
|
-
import {
|
|
13
|
+
import { unsafeCreateEntityTable } from "../../stack";
|
|
14
|
+
import { ensureTemporalPolyfill } from "../../time/polyfill";
|
|
13
15
|
import { seedConfigValues } from "../config-seed";
|
|
14
16
|
import { createEncryptionProvider } from "../encryption";
|
|
15
|
-
import {
|
|
17
|
+
import { buildEntityTable } from "../table-builder";
|
|
16
18
|
|
|
17
19
|
// --- Test Entity ---
|
|
18
20
|
// Mirrors the config-value entity from bundled-features with a unique
|
|
@@ -32,7 +34,7 @@ const configEntity = createEntity({
|
|
|
32
34
|
},
|
|
33
35
|
],
|
|
34
36
|
});
|
|
35
|
-
const configTable =
|
|
37
|
+
const configTable = buildEntityTable("cfgSeedTest", configEntity);
|
|
36
38
|
|
|
37
39
|
// --- Registry Stub ---
|
|
38
40
|
const KEY_DEFS = {
|
|
@@ -53,24 +55,25 @@ const encryption = createEncryptionProvider(
|
|
|
53
55
|
Buffer.from("0123456789abcdef0123456789abcdef").toString("base64"),
|
|
54
56
|
);
|
|
55
57
|
|
|
56
|
-
let testDb:
|
|
58
|
+
let testDb: BunTestDb;
|
|
57
59
|
|
|
58
60
|
async function countRows(): Promise<number> {
|
|
59
|
-
const [r] = await testDb.db.
|
|
60
|
-
|
|
61
|
+
const [r] = await asRawClient(testDb.db).unsafe<{ count: number }>(
|
|
62
|
+
`SELECT COUNT(*)::int AS count FROM read_cfg_seed_test`,
|
|
61
63
|
);
|
|
62
64
|
return r?.count ?? 0;
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
async function countEvents(): Promise<number> {
|
|
66
|
-
const [r] = await testDb.db.
|
|
67
|
-
|
|
68
|
+
const [r] = await asRawClient(testDb.db).unsafe<{ count: number }>(
|
|
69
|
+
`SELECT COUNT(*)::int AS count FROM kumiko_events`,
|
|
68
70
|
);
|
|
69
71
|
return r?.count ?? 0;
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
// --- Setup ---
|
|
73
75
|
beforeAll(async () => {
|
|
76
|
+
await ensureTemporalPolyfill();
|
|
74
77
|
testDb = await createTestDb();
|
|
75
78
|
await unsafeCreateEntityTable(testDb.db, configEntity, "cfgSeedTest");
|
|
76
79
|
});
|
|
@@ -80,7 +83,9 @@ afterAll(async () => {
|
|
|
80
83
|
});
|
|
81
84
|
|
|
82
85
|
beforeEach(async () => {
|
|
83
|
-
await testDb.db.
|
|
86
|
+
await asRawClient(testDb.db).unsafe(
|
|
87
|
+
`TRUNCATE kumiko_events, read_cfg_seed_test RESTART IDENTITY CASCADE`,
|
|
88
|
+
);
|
|
84
89
|
});
|
|
85
90
|
|
|
86
91
|
// --- Tests ---
|
|
@@ -150,8 +155,8 @@ describe("seedConfigValues", () => {
|
|
|
150
155
|
expect(result).toEqual({ created: 0, skipped: 1 });
|
|
151
156
|
|
|
152
157
|
// Old value persists
|
|
153
|
-
const [row] = await testDb.db.
|
|
154
|
-
|
|
158
|
+
const [row] = await asRawClient(testDb.db).unsafe<{ value: string }>(
|
|
159
|
+
`SELECT value FROM read_cfg_seed_test WHERE key = 'test:config:max-upload' LIMIT 1`,
|
|
155
160
|
);
|
|
156
161
|
expect(row).toBeDefined();
|
|
157
162
|
expect(JSON.parse(row!.value)).toBe(10);
|
|
@@ -168,28 +173,28 @@ describe("seedConfigValues", () => {
|
|
|
168
173
|
|
|
169
174
|
await seedConfigValues(seeds, configTable, configEntity, mockRegistry, testDb.db);
|
|
170
175
|
|
|
171
|
-
const rows = await testDb.db.
|
|
176
|
+
const rows = await asRawClient(testDb.db).unsafe<{
|
|
172
177
|
key: string;
|
|
173
|
-
tenantId: string;
|
|
178
|
+
tenantId: string | null;
|
|
174
179
|
userId: string | null;
|
|
175
180
|
}>(
|
|
176
|
-
|
|
181
|
+
`SELECT key, tenant_id AS "tenantId", user_id AS "userId" FROM read_cfg_seed_test ORDER BY key`,
|
|
177
182
|
);
|
|
178
183
|
|
|
179
|
-
const sys = rows.find((r) => r
|
|
180
|
-
const tnt = rows.find((r) => r
|
|
181
|
-
const usr = rows.find((r) => r
|
|
184
|
+
const sys = rows.find((r: Record<string, unknown>) => r["key"] === "test:config:service-url");
|
|
185
|
+
const tnt = rows.find((r: Record<string, unknown>) => r["key"] === "test:config:max-upload");
|
|
186
|
+
const usr = rows.find((r: Record<string, unknown>) => r["key"] === "test:config:theme");
|
|
182
187
|
|
|
183
|
-
expect(sys
|
|
184
|
-
expect(sys
|
|
188
|
+
expect(sys!["tenantId"]).toBe(SYSTEM_TENANT_ID);
|
|
189
|
+
expect(sys!["userId"]).toBeNull();
|
|
185
190
|
|
|
186
|
-
expect(tnt
|
|
187
|
-
expect(tnt
|
|
191
|
+
expect(tnt!["tenantId"]).toBe(SYSTEM_TENANT_ID);
|
|
192
|
+
expect(tnt!["userId"]).toBeNull();
|
|
188
193
|
|
|
189
194
|
// user-scope seed must live under the user's actual tenantId so the
|
|
190
195
|
// resolver cascade can match it — never under SYSTEM_TENANT_ID.
|
|
191
|
-
expect(usr
|
|
192
|
-
expect(usr
|
|
196
|
+
expect(usr!["tenantId"]).toBe(TENANT_A);
|
|
197
|
+
expect(usr!["userId"]).toBe("u-1");
|
|
193
198
|
});
|
|
194
199
|
|
|
195
200
|
test("user-scope seed without tenantId throws (would be unreachable)", async () => {
|
|
@@ -227,8 +232,8 @@ describe("seedConfigValues", () => {
|
|
|
227
232
|
);
|
|
228
233
|
expect(result).toEqual({ created: 1, skipped: 0 });
|
|
229
234
|
|
|
230
|
-
const [row] = await testDb.db.
|
|
231
|
-
|
|
235
|
+
const [row] = await asRawClient(testDb.db).unsafe<{ value: string }>(
|
|
236
|
+
`SELECT value FROM read_cfg_seed_test WHERE key = 'test:config:stripe-key' LIMIT 1`,
|
|
232
237
|
);
|
|
233
238
|
expect(row).toBeDefined();
|
|
234
239
|
// value column holds ciphertext, never the plain token. The
|
|
@@ -15,7 +15,7 @@ import { ensureTemporalPolyfill } from "../../time/polyfill";
|
|
|
15
15
|
|
|
16
16
|
await ensureTemporalPolyfill();
|
|
17
17
|
|
|
18
|
-
import { describe, expect, test } from "
|
|
18
|
+
import { describe, expect, test } from "bun:test";
|
|
19
19
|
import { instantToDriver as toDriver } from "../dialect";
|
|
20
20
|
|
|
21
21
|
describe("instant() customType — toDriver", () => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// Type-Tests für
|
|
2
|
-
// Generic-Inferenz-Pipeline createEntity →
|
|
1
|
+
// Type-Tests für EntityTable<E>: pinned das vertragliche Verhalten der
|
|
2
|
+
// Generic-Inferenz-Pipeline createEntity → buildEntityTable. Wenn ein
|
|
3
3
|
// Branch in `fieldToColumns` driftet aber `ColumnsForField` im Type-
|
|
4
4
|
// System nicht mitkommt (oder umgekehrt), schlagen diese Tests fehl
|
|
5
5
|
// BEVOR ein Consumer in den Wald läuft.
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// repräsentative Fälle: required-Literal, required-Default, money-Pair,
|
|
9
9
|
// locatedTimestamp-Pair, multiSelect-jsonb-default, idType-Variation.
|
|
10
10
|
|
|
11
|
-
import { describe, expect, expectTypeOf, test } from "
|
|
11
|
+
import { describe, expect, expectTypeOf, test } from "bun:test";
|
|
12
12
|
import {
|
|
13
13
|
createBooleanField,
|
|
14
14
|
createDateField,
|
|
@@ -22,9 +22,9 @@ import {
|
|
|
22
22
|
createTimestampField,
|
|
23
23
|
createTzField,
|
|
24
24
|
} from "../../engine";
|
|
25
|
-
import {
|
|
25
|
+
import { buildEntityTable } from "../table-builder";
|
|
26
26
|
|
|
27
|
-
describe("
|
|
27
|
+
describe("EntityTable<E> — Property-Names existieren", () => {
|
|
28
28
|
const sampleEntity = createEntity({
|
|
29
29
|
table: "x",
|
|
30
30
|
fields: {
|
|
@@ -33,7 +33,7 @@ describe("DrizzleTable<E> — Property-Names existieren", () => {
|
|
|
33
33
|
priority: createSelectField({ options: ["low", "high"] as const }),
|
|
34
34
|
},
|
|
35
35
|
});
|
|
36
|
-
const t =
|
|
36
|
+
const t = buildEntityTable("sample", sampleEntity);
|
|
37
37
|
|
|
38
38
|
test("base-columns sind getypt", () => {
|
|
39
39
|
expectTypeOf(t.id).not.toBeNever();
|
|
@@ -61,7 +61,7 @@ describe("DrizzleTable<E> — Property-Names existieren", () => {
|
|
|
61
61
|
});
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
-
describe("
|
|
64
|
+
describe("EntityTable<E> — Money produces two columns", () => {
|
|
65
65
|
const ent = createEntity({
|
|
66
66
|
table: "invoice",
|
|
67
67
|
fields: {
|
|
@@ -69,7 +69,7 @@ describe("DrizzleTable<E> — Money produces two columns", () => {
|
|
|
69
69
|
shipping: createMoneyField(),
|
|
70
70
|
},
|
|
71
71
|
});
|
|
72
|
-
const t =
|
|
72
|
+
const t = buildEntityTable("invoice", ent);
|
|
73
73
|
|
|
74
74
|
test("money-amount column existiert", () => {
|
|
75
75
|
expectTypeOf(t.amount).not.toBeNever();
|
|
@@ -82,14 +82,14 @@ describe("DrizzleTable<E> — Money produces two columns", () => {
|
|
|
82
82
|
});
|
|
83
83
|
});
|
|
84
84
|
|
|
85
|
-
describe("
|
|
85
|
+
describe("EntityTable<E> — locatedTimestamp produces Utc + Tz", () => {
|
|
86
86
|
const ent = createEntity({
|
|
87
87
|
table: "delivery",
|
|
88
88
|
fields: {
|
|
89
89
|
pickup: createLocatedTimestampField({ required: true }),
|
|
90
90
|
},
|
|
91
91
|
});
|
|
92
|
-
const t =
|
|
92
|
+
const t = buildEntityTable("delivery", ent);
|
|
93
93
|
|
|
94
94
|
test("Utc und Tz Spalten existieren", () => {
|
|
95
95
|
expectTypeOf(t.pickupUtc).not.toBeNever();
|
|
@@ -104,7 +104,7 @@ describe("DrizzleTable<E> — locatedTimestamp produces Utc + Tz", () => {
|
|
|
104
104
|
});
|
|
105
105
|
});
|
|
106
106
|
|
|
107
|
-
describe("
|
|
107
|
+
describe("EntityTable<E> — files/images produzieren keine columns", () => {
|
|
108
108
|
// files/images werden über fileRefsTable resolved, nicht in der entity-table.
|
|
109
109
|
// Ein Type-Test der das pinnt würde createFilesField verlangen — wir lassen
|
|
110
110
|
// das hier weg, weil das Authoring-Pattern "createXField" ohne file-helper
|
|
@@ -115,7 +115,7 @@ describe("DrizzleTable<E> — files/images produzieren keine columns", () => {
|
|
|
115
115
|
});
|
|
116
116
|
});
|
|
117
117
|
|
|
118
|
-
describe("
|
|
118
|
+
describe("EntityTable<E> — verschiedene Feld-Typen existieren", () => {
|
|
119
119
|
const ent = createEntity({
|
|
120
120
|
table: "many",
|
|
121
121
|
fields: {
|
|
@@ -127,7 +127,7 @@ describe("DrizzleTable<E> — verschiedene Feld-Typen existieren", () => {
|
|
|
127
127
|
tags: createMultiSelectField({ options: ["a", "b"] as const }),
|
|
128
128
|
},
|
|
129
129
|
});
|
|
130
|
-
const t =
|
|
130
|
+
const t = buildEntityTable("many", ent);
|
|
131
131
|
|
|
132
132
|
test("alle Felder als columns sichtbar", () => {
|
|
133
133
|
expectTypeOf(t.txt).not.toBeNever();
|
|
@@ -139,7 +139,7 @@ describe("DrizzleTable<E> — verschiedene Feld-Typen existieren", () => {
|
|
|
139
139
|
});
|
|
140
140
|
});
|
|
141
141
|
|
|
142
|
-
describe("
|
|
142
|
+
describe("EntityTable<E> — idType wirkt", () => {
|
|
143
143
|
const uuidEnt = createEntity({
|
|
144
144
|
table: "uuid_ent",
|
|
145
145
|
fields: { name: createTextField() },
|
|
@@ -150,8 +150,8 @@ describe("DrizzleTable<E> — idType wirkt", () => {
|
|
|
150
150
|
fields: { name: createTextField() },
|
|
151
151
|
idType: "serial",
|
|
152
152
|
});
|
|
153
|
-
const tu =
|
|
154
|
-
const ts =
|
|
153
|
+
const tu = buildEntityTable("uuid_ent", uuidEnt);
|
|
154
|
+
const ts = buildEntityTable("serial_ent", serialEnt);
|
|
155
155
|
|
|
156
156
|
test("uuid-Entity exposed id existiert", () => {
|
|
157
157
|
expectTypeOf(tu.id).not.toBeNever();
|
|
@@ -4,13 +4,15 @@
|
|
|
4
4
|
// items-create.integration im Showcase abgedeckt — nicht ausreichend
|
|
5
5
|
// für Framework-Code der von jeder App genutzt wird.
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { afterAll, beforeAll, beforeEach, describe, expect, test } from "bun:test";
|
|
8
|
+
import { type BunTestDb, createTestDb } from "../../bun-db/__tests__/bun-test-db";
|
|
9
|
+
import { asRawClient } from "../../db/query";
|
|
9
10
|
import { createEntity, createNumberField, createTextField } from "../../engine";
|
|
10
11
|
import { createEventsTable } from "../../event-store";
|
|
11
|
-
import {
|
|
12
|
+
import { TestUsers, unsafeCreateEntityTable } from "../../stack";
|
|
13
|
+
import { ensureTemporalPolyfill } from "../../time/polyfill";
|
|
12
14
|
import { createEventStoreExecutor } from "../event-store-executor";
|
|
13
|
-
import {
|
|
15
|
+
import { buildEntityTable } from "../table-builder";
|
|
14
16
|
import { createTenantDb, type TenantDb } from "../tenant-db";
|
|
15
17
|
|
|
16
18
|
const entity = createEntity({
|
|
@@ -20,13 +22,14 @@ const entity = createEntity({
|
|
|
20
22
|
rank: createNumberField({ sortable: true }),
|
|
21
23
|
},
|
|
22
24
|
});
|
|
23
|
-
const table =
|
|
25
|
+
const table = buildEntityTable("pagerItem", entity);
|
|
24
26
|
|
|
25
|
-
let testDb:
|
|
27
|
+
let testDb: BunTestDb;
|
|
26
28
|
let tdb: TenantDb;
|
|
27
29
|
const admin = TestUsers.admin;
|
|
28
30
|
|
|
29
31
|
beforeAll(async () => {
|
|
32
|
+
await ensureTemporalPolyfill();
|
|
30
33
|
testDb = await createTestDb();
|
|
31
34
|
await unsafeCreateEntityTable(testDb.db, entity, "pagerItem");
|
|
32
35
|
await createEventsTable(testDb.db);
|
|
@@ -38,7 +41,9 @@ afterAll(async () => {
|
|
|
38
41
|
});
|
|
39
42
|
|
|
40
43
|
beforeEach(async () => {
|
|
41
|
-
await testDb.db.
|
|
44
|
+
await asRawClient(testDb.db).unsafe(
|
|
45
|
+
`TRUNCATE kumiko_events, read_pager_items RESTART IDENTITY CASCADE`,
|
|
46
|
+
);
|
|
42
47
|
});
|
|
43
48
|
|
|
44
49
|
describe("event-store-executor.list — offset + totalCount (Tier 2.6d)", () => {
|