@cosmicdrift/kumiko-framework 0.389.0 → 0.390.1
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/AGENTS.md +9 -4
- package/README.md +1 -1
- package/agents/examples/apex-surface-auth.md +2 -3
- package/agents/examples/api-worker-split.md +9 -2
- package/agents/examples/auth-claims.md +1 -1
- package/agents/examples/cross-feature-events.md +12 -12
- package/agents/examples/crypto-shredding-hr.md +2 -2
- package/agents/examples/encrypted-tenant-config.md +1 -1
- package/agents/examples/error-contract.md +12 -7
- package/agents/examples/event-sourcing.md +29 -29
- package/agents/examples/files-post-processing.md +10 -8
- package/agents/examples/inbound-mail-triage.md +1 -0
- package/agents/examples/lane-routing.md +2 -1
- package/agents/examples/legal-pages.md +2 -2
- package/agents/examples/lifecycle-hooks.md +3 -3
- package/agents/examples/managed-config.md +4 -4
- package/agents/examples/managed-pages.md +1 -1
- package/agents/examples/relations.md +19 -4
- package/agents/examples/search.md +4 -4
- package/agents/examples/secrets-demo.md +9 -6
- package/agents/examples/state-machine.md +2 -2
- package/agents/examples/tenant-settings.md +1 -1
- package/agents/examples/user-data-rights.md +3 -6
- package/agents/examples/workflow-engine.md +53 -47
- package/agents/examples.md +4 -4
- package/agents/features.md +1 -1
- package/dist/api/auth-middleware.js +1 -1
- package/dist/api/auth-routes-invite.js +2 -1
- package/dist/api/entity-read-access.d.ts +3 -1
- package/dist/api/export/export-columns.d.ts +3 -1
- package/dist/api/export/export-route.js +3 -2
- package/dist/api/export/export-screen.d.ts +2 -1
- package/dist/api/extra-route.d.ts +3 -1
- package/dist/api/index.d.ts +23 -27
- package/dist/api/index.js +13 -15
- package/dist/api/jwt.js +1 -1
- package/dist/api/observability-middleware.d.ts +1 -1
- package/dist/api/observability-middleware.js +2 -1
- package/dist/api/request-context-internals.d.ts +31 -0
- package/dist/api/request-context-internals.js +11 -0
- package/dist/api/request-context-scopes.d.ts +14 -0
- package/dist/api/request-context-scopes.js +69 -0
- package/dist/api/request-context.d.ts +1 -40
- package/dist/api/request-context.js +22 -51
- package/dist/api/request-id-middleware.d.ts +1 -1
- package/dist/api/route-registrars.d.ts +2 -1
- package/dist/api/route-registrars.js +1 -1
- package/dist/api/routes.js +7 -3
- package/dist/api/server-boot-checks.d.ts +1 -1
- package/dist/api/server-boot-checks.js +2 -2
- package/dist/api/server-event-dispatcher.d.ts +6 -1
- package/dist/api/server-event-dispatcher.js +3 -4
- package/dist/api/server-extra-routes.d.ts +1 -1
- package/dist/api/server-extra-routes.js +2 -1
- package/dist/api/server-middleware.js +3 -1
- package/dist/api/server-routes.d.ts +2 -1
- package/dist/api/server-wiring.js +6 -4
- package/dist/api/server.d.ts +2 -1
- package/dist/api/sse-route.d.ts +2 -1
- package/dist/api/tenant-scoped-secrets.d.ts +2 -0
- package/dist/api/tenant-scoped-secrets.js +13 -0
- package/dist/api/websocket-route.d.ts +1 -1
- package/dist/auth/index.d.ts +0 -1
- package/dist/auth/roles.d.ts +0 -5
- package/dist/compliance/duration-spec.d.ts +0 -1
- package/dist/compliance/duration-spec.js +0 -5
- package/dist/compliance/index.d.ts +4 -4
- package/dist/compliance/index.js +2 -2
- package/dist/compliance/profiles.d.ts +0 -15
- package/dist/compliance/profiles.js +0 -23
- package/dist/config/index.d.ts +10 -10
- package/dist/config/index.js +13 -1
- package/dist/config/internals.d.ts +9 -0
- package/dist/config/internals.js +1 -0
- package/dist/consumer-cli-internals.d.ts +4 -0
- package/dist/consumer-cli-internals.js +1 -0
- package/dist/consumer-cli.d.ts +1 -4
- package/dist/consumer-cli.js +5 -1
- package/dist/crypto/event-pii.js +1 -1
- package/dist/crypto/index.d.ts +8 -9
- package/dist/crypto/index.js +7 -8
- package/dist/crypto/pg-kms-adapter.js +6 -1
- package/dist/db/apply-entity-event.d.ts +1 -1
- package/dist/db/apply-entity-event.js +15 -47
- package/dist/db/blind-index-cleanup.js +91 -77
- package/dist/db/collect-table-metas.js +1 -1
- package/dist/db/compound-types.d.ts +1 -1
- package/dist/db/compound-types.js +0 -7
- package/dist/db/config-seed.d.ts +2 -1
- package/dist/db/config-seed.js +6 -1
- package/dist/db/connection.d.ts +3 -1
- package/dist/db/connection.js +15 -5
- package/dist/db/cross-tenant-reads.d.ts +1 -1
- package/dist/db/cross-tenant-reads.js +1 -1
- package/dist/db/dialect.d.ts +0 -5
- package/dist/db/dialect.js +0 -3
- package/dist/db/driver-value-preparation.js +23 -2
- package/dist/db/eagerload.d.ts +2 -1
- package/dist/db/entity-field-encryption.d.ts +1 -1
- package/dist/db/entity-table-meta.d.ts +1 -1
- package/dist/db/event-store-executor-context.d.ts +3 -1
- package/dist/db/event-store-executor-context.js +4 -3
- package/dist/db/event-store-executor-read-filter.d.ts +1 -1
- package/dist/db/event-store-executor-read-rows.d.ts +2 -1
- package/dist/db/event-store-executor-read-search.d.ts +2 -1
- package/dist/db/event-store-executor-read-sort.d.ts +2 -1
- package/dist/db/event-store-executor-read.js +2 -2
- package/dist/db/event-store-executor-write-atomic.js +8 -7
- package/dist/db/event-store-executor-write-steps.d.ts +3 -2
- package/dist/db/event-store-executor-write.js +7 -4
- package/dist/db/event-store-executor.d.ts +1 -1
- package/dist/db/executor-managed-tables.d.ts +7 -1
- package/dist/db/executor-managed-tables.js +11 -2
- package/dist/db/index.d.ts +29 -28
- package/dist/db/index.js +22 -20
- package/dist/db/known-table-names.d.ts +6 -0
- package/dist/db/known-table-names.js +21 -0
- package/dist/db/list-aggregate-labels.d.ts +1 -1
- package/dist/db/located-timestamp.d.ts +1 -1
- package/dist/db/located-timestamp.js +0 -5
- package/dist/db/migrate-generator.d.ts +17 -1
- package/dist/db/migrate-generator.js +50 -20
- package/dist/db/migrate-primary-key.d.ts +12 -0
- package/dist/db/migrate-primary-key.js +45 -0
- package/dist/db/migrate-rls-diff.d.ts +20 -0
- package/dist/db/migrate-rls-diff.js +61 -0
- package/dist/db/migrate-runner.js +4 -0
- package/dist/db/money.d.ts +1 -1
- package/dist/db/money.js +1 -1
- package/dist/db/parent-ref-clause.d.ts +2 -1
- package/dist/db/pg-error.d.ts +2 -0
- package/dist/db/pg-error.js +11 -0
- package/dist/db/queries/ddl.d.ts +3 -0
- package/dist/db/queries/ddl.js +34 -1
- package/dist/db/queries/event-store.js +4 -2
- package/dist/db/queries/event-tenants.d.ts +2 -0
- package/dist/db/queries/event-tenants.js +17 -0
- package/dist/db/queries/rebuild-rls-guard.d.ts +2 -0
- package/dist/db/queries/rebuild-rls-guard.js +29 -0
- package/dist/db/queries/rls-boot-catalog.d.ts +16 -0
- package/dist/db/queries/rls-boot-catalog.js +39 -0
- package/dist/db/queries/rls-catalog.d.ts +6 -0
- package/dist/db/queries/rls-catalog.js +82 -0
- package/dist/db/queries/rls-scope.d.ts +3 -0
- package/dist/db/queries/rls-scope.js +17 -0
- package/dist/db/queries/rls-shape.d.ts +10 -0
- package/dist/db/queries/rls-shape.js +42 -0
- package/dist/db/queries/session-advisory-lock.d.ts +2 -0
- package/dist/db/queries/session-advisory-lock.js +23 -0
- package/dist/db/queries/shadow-swap.d.ts +1 -2
- package/dist/db/queries/shadow-swap.js +9 -25
- package/dist/db/queries/test-stack.d.ts +4 -1
- package/dist/db/queries/test-stack.js +84 -2
- package/dist/db/query.js +11 -7
- package/dist/db/reference-data.d.ts +1 -1
- package/dist/db/reference-data.js +6 -1
- package/dist/db/render-ddl.d.ts +6 -2
- package/dist/db/render-ddl.js +7 -7
- package/dist/db/render-rls-ddl.d.ts +35 -0
- package/dist/db/render-rls-ddl.js +127 -0
- package/dist/db/replay-migration-sql.d.ts +3 -1
- package/dist/db/replay-migration-sql.js +22 -5
- package/dist/db/replay-rls.d.ts +25 -0
- package/dist/db/replay-rls.js +156 -0
- package/dist/db/row-level-security-boot-check.d.ts +6 -0
- package/dist/db/row-level-security-boot-check.js +86 -0
- package/dist/db/row-level-security-connection.d.ts +3 -0
- package/dist/db/row-level-security-connection.js +213 -0
- package/dist/db/row-level-security-scope.d.ts +33 -0
- package/dist/db/row-level-security-scope.js +127 -0
- package/dist/db/scope-tenant-db-to-tenant.d.ts +3 -0
- package/dist/db/scope-tenant-db-to-tenant.js +14 -0
- package/dist/db/sql-identifier.d.ts +1 -0
- package/dist/db/sql-identifier.js +3 -0
- package/dist/db/table-builder.d.ts +2 -1
- package/dist/db/table-builder.js +1 -1
- package/dist/db/table-info.js +1 -1
- package/dist/db/table-push.d.ts +11 -2
- package/dist/db/table-push.js +15 -2
- package/dist/db/tenant-db-runner.d.ts +3 -1
- package/dist/db/tenant-db-runner.js +4 -3
- package/dist/db/tenant-db-scoped-rebind.d.ts +10 -0
- package/dist/db/tenant-db-scoped-rebind.js +33 -0
- package/dist/db/tenant-db-statement-runner.d.ts +13 -0
- package/dist/db/tenant-db-statement-runner.js +48 -0
- package/dist/db/tenant-db.d.ts +17 -12
- package/dist/db/tenant-db.js +49 -120
- package/dist/db/tenant-id-filter.d.ts +3 -0
- package/dist/db/tenant-id-filter.js +30 -0
- package/dist/db/transaction-serialization.d.ts +6 -0
- package/dist/db/transaction-serialization.js +60 -0
- package/dist/derivatives/delete-stored-file.js +1 -1
- package/dist/derivatives/index.d.ts +2 -5
- package/dist/derivatives/index.js +2 -3
- package/dist/engine/access.d.ts +2 -1
- package/dist/engine/access.js +1 -1
- package/dist/engine/boot-validator/entity-handler.d.ts +2 -1
- package/dist/engine/boot-validator/entity-handler.js +1 -1
- package/dist/engine/boot-validator/entity-list-aggregate-options.d.ts +1 -1
- package/dist/engine/boot-validator/list-table-aggregate-options.d.ts +1 -1
- package/dist/engine/boot-validator/list-table-aggregate-query.d.ts +2 -1
- package/dist/engine/boot-validator/nav.d.ts +3 -1
- package/dist/engine/boot-validator/nav.js +1 -1
- package/dist/engine/boot-validator/ownership.d.ts +2 -1
- package/dist/engine/boot-validator/parent-ref.d.ts +2 -1
- package/dist/engine/boot-validator/projection-list-screens.d.ts +2 -1
- package/dist/engine/boot-validator/query-refs.d.ts +2 -1
- package/dist/engine/boot-validator/screens-forms.d.ts +2 -1
- package/dist/engine/boot-validator/screens-kind-shared.d.ts +3 -1
- package/dist/engine/boot-validator/screens.d.ts +2 -1
- package/dist/engine/boot-validator/workspaces.d.ts +3 -1
- package/dist/engine/bridge-stub.d.ts +5 -2
- package/dist/engine/bridge-stub.js +39 -24
- package/dist/engine/config-helpers.d.ts +2 -2
- package/dist/engine/config-helpers.js +0 -9
- package/dist/engine/constants.d.ts +0 -10
- package/dist/engine/constants.js +0 -8
- package/dist/engine/create-app.js +1 -1
- package/dist/engine/define-feature.d.ts +2 -1
- package/dist/engine/define-feature.js +1 -2
- package/dist/engine/define-handler.d.ts +1 -1
- package/dist/engine/define-step.d.ts +0 -1
- package/dist/engine/define-step.js +0 -3
- package/dist/engine/embedded-derived.d.ts +1 -1
- package/dist/engine/entity-handlers.d.ts +2 -1
- package/dist/engine/entity-handlers.js +7 -7
- package/dist/engine/entity-list-runtime-options.js +3 -1
- package/dist/engine/entity-list-searchability.d.ts +2 -1
- package/dist/engine/event-def.d.ts +2 -1
- package/dist/engine/event-helpers.d.ts +3 -1
- package/dist/engine/event-helpers.js +3 -3
- package/dist/engine/extension-names.d.ts +2 -8
- package/dist/engine/extension-names.js +2 -2
- package/dist/engine/extension-selector-plugins.d.ts +1 -1
- package/dist/engine/extensions/storage-provider.d.ts +1 -2
- package/dist/engine/extensions/user-data.d.ts +0 -8
- package/dist/engine/factories.d.ts +2 -1
- package/dist/engine/feature-builder-state.d.ts +8 -1
- package/dist/engine/feature-changelog.d.ts +1 -1
- package/dist/engine/feature-config-events-jobs.d.ts +4 -1
- package/dist/engine/feature-entity-handlers.d.ts +5 -1
- package/dist/engine/feature-manifest.js +1 -1
- package/dist/engine/feature-ui-extensions.d.ts +7 -1
- package/dist/engine/feature-ui-extensions.js +6 -4
- package/dist/engine/field-access.d.ts +2 -1
- package/dist/engine/handler-field-references.d.ts +0 -4
- package/dist/engine/index.d.ts +57 -54
- package/dist/engine/index.js +22 -27
- package/dist/engine/instruction-fields.d.ts +1 -1
- package/dist/engine/personal-data-fields.d.ts +1 -1
- package/dist/engine/qualified-name.d.ts +0 -1
- package/dist/engine/read-claim.d.ts +2 -1
- package/dist/engine/registry-facade.js +0 -3
- package/dist/engine/registry-ingest.d.ts +2 -1
- package/dist/engine/registry-ingest.js +1 -2
- package/dist/engine/registry-state.d.ts +12 -2
- package/dist/engine/registry-state.js +2 -3
- package/dist/engine/registry-validate.d.ts +3 -1
- package/dist/engine/registry-validate.js +7 -7
- package/dist/engine/run-in.d.ts +1 -1
- package/dist/engine/run-in.js +0 -1
- package/dist/engine/schema-builder.d.ts +1 -1
- package/dist/engine/schema-builder.js +1 -1
- package/dist/engine/screen-filter-ops.d.ts +2 -1
- package/dist/engine/screen-filter-ops.js +0 -5
- package/dist/engine/soft-delete-cleanup.d.ts +1 -1
- package/dist/engine/soft-delete-cleanup.js +4 -4
- package/dist/engine/state-machine.js +2 -1
- package/dist/engine/steps/_read-source.js +1 -1
- package/dist/engine/steps/aggregate-append-event.js +2 -2
- package/dist/engine/steps/call-feature.js +2 -2
- package/dist/engine/steps/mail-send.js +1 -1
- package/dist/engine/steps/retry.js +1 -1
- package/dist/engine/steps/wait-for-event.js +1 -1
- package/dist/engine/steps/wait.js +1 -1
- package/dist/engine/steps/webhook-send.js +1 -1
- package/dist/engine/template-variables.d.ts +2 -1
- package/dist/engine/transfer-adjacency.d.ts +1 -1
- package/dist/engine/types/index.d.ts +8 -31
- package/dist/engine/types/index.js +2 -10
- package/dist/engine/validation.d.ts +2 -1
- package/dist/entrypoint/index.d.ts +7 -35
- package/dist/entrypoint/index.js +7 -1
- package/dist/entrypoint/internals.d.ts +40 -0
- package/dist/entrypoint/internals.js +1 -0
- package/dist/entrypoint/row-level-security-mode-check.d.ts +3 -0
- package/dist/entrypoint/row-level-security-mode-check.js +19 -0
- package/dist/env/dry-run-internals.d.ts +10 -0
- package/dist/env/dry-run-internals.js +1 -0
- package/dist/env/dry-run.d.ts +1 -10
- package/dist/env/dry-run.js +2 -1
- package/dist/env/index.d.ts +1 -85
- package/dist/env/index.js +6 -50
- package/dist/env/internals.d.ts +87 -0
- package/dist/env/internals.js +53 -0
- package/dist/errors/classes.js +2 -2
- package/dist/errors/index.d.ts +5 -14
- package/dist/errors/index.js +4 -9
- package/dist/errors/member-resolution.js +1 -1
- package/dist/errors/reasons.d.ts +0 -1
- package/dist/errors/reasons.js +7 -7
- package/dist/errors/serialize.d.ts +0 -18
- package/dist/errors/serialize.js +0 -27
- package/dist/es-ops/index.d.ts +4 -4
- package/dist/es-ops/index.js +2 -2
- package/dist/es-ops/operations-schema.d.ts +1 -1
- package/dist/es-ops/types.d.ts +4 -5
- package/dist/event-store/admin-api-internals.d.ts +14 -0
- package/dist/event-store/admin-api-internals.js +1 -0
- package/dist/event-store/admin-api.d.ts +1 -14
- package/dist/event-store/admin-api.js +11 -6
- package/dist/event-store/archive.js +4 -2
- package/dist/event-store/errors.js +2 -2
- package/dist/event-store/event-store.js +41 -34
- package/dist/event-store/events-schema.js +4 -1
- package/dist/event-store/index.d.ts +11 -13
- package/dist/event-store/index.js +7 -9
- package/dist/event-store/rebuild-dead-letter.js +4 -2
- package/dist/event-store/snapshot.js +4 -3
- package/dist/event-store/stream-scope.d.ts +2 -0
- package/dist/event-store/stream-scope.js +6 -0
- package/dist/event-store/upcaster-dead-letter.js +4 -2
- package/dist/event-store/upcaster.d.ts +2 -1
- package/dist/files/action-form-upload.d.ts +2 -1
- package/dist/files/action-form-upload.js +1 -1
- package/dist/files/assert-file-refs-belong-to-tenant.d.ts +2 -1
- package/dist/files/assert-file-refs-belong-to-tenant.js +1 -1
- package/dist/files/bind-pending-file-refs.d.ts +2 -1
- package/dist/files/bind-pending-file-refs.js +2 -1
- package/dist/files/bind-referenced-files.write.js +1 -1
- package/dist/files/create-file-ref-from-bytes.d.ts +6 -3
- package/dist/files/create-file-ref-from-bytes.js +3 -3
- package/dist/files/create-file-ref.d.ts +3 -2
- package/dist/files/create-file-ref.js +2 -2
- package/dist/files/dispose-removed-file-refs.d.ts +2 -1
- package/dist/files/dispose-removed-file-refs.js +1 -1
- package/dist/files/feature.js +2 -2
- package/dist/files/file-handle.js +1 -1
- package/dist/files/file-routes.d.ts +1 -1
- package/dist/files/file-routes.js +12 -2
- package/dist/files/index.d.ts +11 -13
- package/dist/files/index.js +5 -7
- package/dist/files/load-save-file-refs.d.ts +2 -1
- package/dist/files/load-save-file-refs.js +1 -1
- package/dist/files/provider-resolver.d.ts +5 -4
- package/dist/files/provider-resolver.js +4 -4
- package/dist/files/storage-tracking.js +4 -2
- package/dist/files/sweep-orphaned-uploads.d.ts +1 -1
- package/dist/files/sweep-orphaned-uploads.js +1 -1
- package/dist/i18n/index.d.ts +2 -8
- package/dist/i18n/index.js +1 -1
- package/dist/i18n/internals.d.ts +7 -0
- package/dist/i18n/internals.js +1 -0
- package/dist/i18n/required-surface-keys.d.ts +4 -1
- package/dist/internal/row-level-security.d.ts +3 -0
- package/dist/internal/row-level-security.js +3 -0
- package/dist/internal/stack-support.d.ts +1 -1
- package/dist/internal/stack-support.js +1 -1
- package/dist/internal/testing.d.ts +1 -0
- package/dist/internal/testing.js +9 -5
- package/dist/jobs/index.d.ts +1 -1
- package/dist/jobs/job-append-event.d.ts +12 -0
- package/dist/jobs/job-append-event.js +30 -0
- package/dist/jobs/job-runner-context.d.ts +2 -2
- package/dist/jobs/job-runner-context.js +46 -16
- package/dist/jobs/job-runner-execution.d.ts +1 -1
- package/dist/jobs/job-runner-execution.js +6 -4
- package/dist/jobs/job-runner-gates.d.ts +1 -1
- package/dist/jobs/job-runner-gates.js +0 -1
- package/dist/jobs/job-runner-helpers.d.ts +11 -4
- package/dist/jobs/job-runner-helpers.js +10 -1
- package/dist/jobs/job-runner-scope.d.ts +5 -2
- package/dist/jobs/job-runner-types.d.ts +2 -1
- package/dist/jobs/job-runner.js +19 -6
- package/dist/jobs/max-per-tenant.d.ts +1 -1
- package/dist/logging/index.d.ts +1 -2
- package/dist/logging/index.js +1 -1
- package/dist/logging/pino-logger.js +1 -1
- package/dist/logging/utils.d.ts +1 -0
- package/dist/logging/utils.js +6 -0
- package/dist/migrations/index.d.ts +3 -3
- package/dist/migrations/index.js +3 -3
- package/dist/migrations/pending-rebuilds.d.ts +1 -1
- package/dist/migrations/pending-rebuilds.js +1 -1
- package/dist/migrations/pii-event-backfill.js +4 -1
- package/dist/observability/escape-hatch-report.d.ts +2 -1
- package/dist/observability/index.d.ts +7 -15
- package/dist/observability/index.js +4 -12
- package/dist/observability/metric-validator.js +1 -1
- package/dist/observability/metrics-handle.d.ts +0 -1
- package/dist/observability/metrics-handle.js +2 -15
- package/dist/observability/recording-tracer.d.ts +1 -2
- package/dist/observability/recording-tracer.js +0 -6
- package/dist/observability/sensitive-filter.d.ts +0 -2
- package/dist/observability/sensitive-filter.js +0 -29
- package/dist/pipeline/active-membership.d.ts +2 -1
- package/dist/pipeline/active-membership.js +6 -2
- package/dist/pipeline/append-event-core.d.ts +2 -1
- package/dist/pipeline/append-event-core.js +2 -2
- package/dist/pipeline/attach-outside-transaction.d.ts +3 -0
- package/dist/pipeline/attach-outside-transaction.js +13 -0
- package/dist/pipeline/auth-claims-resolver.d.ts +2 -1
- package/dist/pipeline/cascade-handler.d.ts +2 -1
- package/dist/pipeline/cascade-handler.js +3 -2
- package/dist/pipeline/config-accessor-factory.d.ts +1 -1
- package/dist/pipeline/config-accessor-factory.js +1 -1
- package/dist/pipeline/context-services.d.ts +56 -0
- package/dist/pipeline/context-services.js +73 -0
- package/dist/pipeline/dispatch-batch.d.ts +2 -1
- package/dist/pipeline/dispatch-batch.js +31 -18
- package/dist/pipeline/dispatch-query.js +5 -4
- package/dist/pipeline/dispatch-scope.d.ts +6 -0
- package/dist/pipeline/dispatch-scope.js +27 -0
- package/dist/pipeline/dispatch-shared.d.ts +13 -9
- package/dist/pipeline/dispatch-shared.js +75 -198
- package/dist/pipeline/dispatch-stream.js +8 -4
- package/dist/pipeline/dispatch-write.d.ts +2 -1
- package/dist/pipeline/dispatch-write.js +10 -8
- package/dist/pipeline/dispatcher-utils.d.ts +3 -1
- package/dist/pipeline/dispatcher-utils.js +8 -2
- package/dist/pipeline/dispatcher.d.ts +3 -2
- package/dist/pipeline/dispatcher.js +4 -3
- package/dist/pipeline/event-consumer-state.d.ts +0 -1
- package/dist/pipeline/event-dispatcher-delivery.d.ts +1 -1
- package/dist/pipeline/event-dispatcher-delivery.js +4 -2
- package/dist/pipeline/event-dispatcher.d.ts +2 -2
- package/dist/pipeline/event-dispatcher.js +7 -3
- package/dist/pipeline/event-retention.js +59 -56
- package/dist/pipeline/handler-access-error.js +2 -1
- package/dist/pipeline/handler-context-auth.d.ts +5 -6
- package/dist/pipeline/handler-context-auth.js +7 -4
- package/dist/pipeline/handler-context-config.d.ts +2 -5
- package/dist/pipeline/handler-context-config.js +2 -2
- package/dist/pipeline/handler-context-db.d.ts +32 -7
- package/dist/pipeline/handler-context-db.js +26 -17
- package/dist/pipeline/handler-context-dispatch.d.ts +13 -7
- package/dist/pipeline/handler-context-dispatch.js +9 -8
- package/dist/pipeline/handler-context-events.d.ts +22 -36
- package/dist/pipeline/handler-context-events.js +36 -31
- package/dist/pipeline/handler-context-member-resolution.d.ts +2 -0
- package/dist/pipeline/handler-context-member-resolution.js +110 -0
- package/dist/pipeline/handler-context-notify.d.ts +3 -2
- package/dist/pipeline/handler-context-notify.js +1 -1
- package/dist/pipeline/handler-context-observability.d.ts +2 -4
- package/dist/pipeline/handler-context-observability.js +7 -5
- package/dist/pipeline/handler-context-phase-denials.d.ts +11 -0
- package/dist/pipeline/handler-context-phase-denials.js +98 -0
- package/dist/pipeline/handler-context-scope.d.ts +7 -10
- package/dist/pipeline/handler-context-scope.js +18 -20
- package/dist/pipeline/index.d.ts +9 -21
- package/dist/pipeline/index.js +5 -7
- package/dist/pipeline/irreversible-operation-gate.d.ts +1 -1
- package/dist/pipeline/irreversible-operation-gate.js +2 -2
- package/dist/pipeline/lifecycle-pipeline.d.ts +8 -7
- package/dist/pipeline/lifecycle-pipeline.js +9 -15
- package/dist/pipeline/member-read-only-transaction.js +11 -3
- package/dist/pipeline/member-reader.d.ts +1 -1
- package/dist/pipeline/member-reader.js +2 -2
- package/dist/pipeline/msp-rebuild.js +5 -3
- package/dist/pipeline/multi-stream-apply-context.js +3 -2
- package/dist/pipeline/notify-scope.d.ts +2 -1
- package/dist/pipeline/pre-handler-gates.d.ts +2 -1
- package/dist/pipeline/pre-transaction-reservations.d.ts +3 -3
- package/dist/pipeline/pre-transaction-reservations.js +9 -7
- package/dist/pipeline/projection-rebuild.js +12 -5
- package/dist/pipeline/projection-state.d.ts +0 -6
- package/dist/pipeline/projection-state.js +0 -5
- package/dist/pipeline/projections-runner.d.ts +2 -1
- package/dist/pipeline/projections-runner.js +10 -6
- package/dist/pipeline/system-hooks.d.ts +3 -1
- package/dist/pipeline/system-hooks.js +6 -4
- package/dist/pipeline/system-identity-switch.d.ts +4 -2
- package/dist/pipeline/system-identity-switch.js +51 -36
- package/dist/pipeline/typed-append-event.d.ts +2 -0
- package/dist/pipeline/typed-append-event.js +4 -0
- package/dist/pipeline/write-origin.js +2 -2
- package/dist/pipeline/write-result-masking.d.ts +1 -1
- package/dist/random/index.d.ts +1 -2
- package/dist/random/index.js +1 -2
- package/dist/rate-limit/bucket.d.ts +2 -1
- package/dist/rate-limit/middleware.js +2 -1
- package/dist/redis/index.d.ts +3 -4
- package/dist/redis/index.js +2 -2
- package/dist/schema-cli/apply-command.js +5 -2
- package/dist/schema-cli/baseline-command.js +7 -2
- package/dist/schema-cli/generate-command.js +7 -9
- package/dist/schema-cli/shared.d.ts +12 -2
- package/dist/schema-cli/shared.js +24 -2
- package/dist/schema-cli/status-command.js +8 -2
- package/dist/schema-cli/validate-command.js +48 -4
- package/dist/schema-cli.d.ts +0 -1
- package/dist/search/configure-tenant-index.d.ts +1 -3
- package/dist/search/configure-tenant-index.js +0 -4
- package/dist/search/index.d.ts +1 -4
- package/dist/search/index.js +0 -2
- package/dist/search/meilisearch-adapter-internals.d.ts +8 -0
- package/dist/search/meilisearch-adapter-internals.js +9 -0
- package/dist/search/meilisearch-adapter.d.ts +1 -8
- package/dist/search/meilisearch-adapter.js +6 -7
- package/dist/search/meilisearch-peer.d.ts +2 -0
- package/dist/search/meilisearch-peer.js +5 -0
- package/dist/search/reindex-entity.js +93 -87
- package/dist/secrets/index.d.ts +3 -4
- package/dist/secrets/index.js +2 -3
- package/dist/seeding/index.d.ts +2 -2
- package/dist/seeding/index.js +1 -2
- package/dist/time/index.d.ts +2 -2
- package/dist/time/index.js +1 -1
- package/dist/time/tz-context.d.ts +0 -5
- package/dist/time/tz-context.js +0 -9
- package/dist/ui-types/index.d.ts +8 -11
- package/dist/ui-types/index.js +3 -3
- package/dist/upgrade-changelog.d.ts +3 -2
- package/dist/upgrade-changelog.js +12 -8
- package/dist/upgrade-cli-internals.d.ts +8 -0
- package/dist/upgrade-cli-internals.js +63 -0
- package/dist/upgrade-cli.d.ts +2 -9
- package/dist/upgrade-cli.js +28 -70
- package/dist/utils/import-optional-peer.d.ts +6 -0
- package/dist/utils/import-optional-peer.js +19 -0
- package/dist/utils/index.d.ts +1 -4
- package/dist/utils/index.js +1 -4
- package/package.json +23 -19
- package/src/changes.json +236 -0
- package/dist/crypto/request-kms-cache.d.ts +0 -8
- package/dist/crypto/request-kms-cache.js +0 -21
- package/dist/engine/codemod/index.d.ts +0 -2
- package/dist/engine/codemod/index.js +0 -1
- package/dist/engine/codemod/pipeline-codemod.d.ts +0 -50
- package/dist/engine/codemod/pipeline-codemod.js +0 -536
- package/dist/engine/feature-ast/entity-field-types.d.ts +0 -13
- package/dist/engine/feature-ast/entity-field-types.js +0 -35
- package/dist/engine/feature-ast/extractors/ai-steps.d.ts +0 -6
- package/dist/engine/feature-ast/extractors/ai-steps.js +0 -254
- package/dist/engine/feature-ast/extractors/events.d.ts +0 -5
- package/dist/engine/feature-ast/extractors/events.js +0 -275
- package/dist/engine/feature-ast/extractors/handlers.d.ts +0 -24
- package/dist/engine/feature-ast/extractors/handlers.js +0 -358
- package/dist/engine/feature-ast/extractors/hooks.d.ts +0 -24
- package/dist/engine/feature-ast/extractors/hooks.js +0 -248
- package/dist/engine/feature-ast/extractors/index.d.ts +0 -14
- package/dist/engine/feature-ast/extractors/index.js +0 -13
- package/dist/engine/feature-ast/extractors/jobs-routes.d.ts +0 -7
- package/dist/engine/feature-ast/extractors/jobs-routes.js +0 -145
- package/dist/engine/feature-ast/extractors/projections-screens.d.ts +0 -10
- package/dist/engine/feature-ast/extractors/projections-screens.js +0 -195
- package/dist/engine/feature-ast/extractors/resolve-import.d.ts +0 -21
- package/dist/engine/feature-ast/extractors/resolve-import.js +0 -180
- package/dist/engine/feature-ast/extractors/round1.d.ts +0 -11
- package/dist/engine/feature-ast/extractors/round1.js +0 -87
- package/dist/engine/feature-ast/extractors/round2.d.ts +0 -7
- package/dist/engine/feature-ast/extractors/round2.js +0 -191
- package/dist/engine/feature-ast/extractors/round3.d.ts +0 -23
- package/dist/engine/feature-ast/extractors/round3.js +0 -292
- package/dist/engine/feature-ast/extractors/round5.d.ts +0 -9
- package/dist/engine/feature-ast/extractors/round5.js +0 -68
- package/dist/engine/feature-ast/extractors/round6.d.ts +0 -4
- package/dist/engine/feature-ast/extractors/round6.js +0 -17
- package/dist/engine/feature-ast/extractors/shared.d.ts +0 -94
- package/dist/engine/feature-ast/extractors/shared.js +0 -343
- package/dist/engine/feature-ast/index.d.ts +0 -16
- package/dist/engine/feature-ast/index.js +0 -10
- package/dist/engine/feature-ast/parse.d.ts +0 -31
- package/dist/engine/feature-ast/parse.js +0 -485
- package/dist/engine/feature-ast/patch.d.ts +0 -212
- package/dist/engine/feature-ast/patch.js +0 -611
- package/dist/engine/feature-ast/patcher.d.ts +0 -217
- package/dist/engine/feature-ast/patcher.js +0 -281
- package/dist/engine/feature-ast/pattern-change-schema.d.ts +0 -1238
- package/dist/engine/feature-ast/pattern-change-schema.js +0 -1072
- package/dist/engine/feature-ast/pattern-id-matchers.d.ts +0 -7
- package/dist/engine/feature-ast/pattern-id-matchers.js +0 -211
- package/dist/engine/feature-ast/pattern-id-schema.d.ts +0 -251
- package/dist/engine/feature-ast/pattern-id-schema.js +0 -166
- package/dist/engine/feature-ast/patterns.d.ts +0 -322
- package/dist/engine/feature-ast/patterns.js +0 -107
- package/dist/engine/feature-ast/render.d.ts +0 -47
- package/dist/engine/feature-ast/render.js +0 -666
- package/dist/engine/feature-ast/source-location.d.ts +0 -17
- package/dist/engine/feature-ast/source-location.js +0 -27
- package/dist/engine/pattern-library/index.d.ts +0 -2
- package/dist/engine/pattern-library/index.js +0 -3
- package/dist/engine/pattern-library/library.d.ts +0 -14
- package/dist/engine/pattern-library/library.js +0 -94
- package/dist/engine/pattern-library/mixed-schemas.d.ts +0 -16
- package/dist/engine/pattern-library/mixed-schemas.js +0 -559
- package/dist/engine/pattern-library/opaque-schemas.d.ts +0 -7
- package/dist/engine/pattern-library/opaque-schemas.js +0 -115
- package/dist/engine/pattern-library/shared-fields.d.ts +0 -122
- package/dist/engine/pattern-library/shared-fields.js +0 -88
- package/dist/engine/pattern-library/static-schemas.d.ts +0 -21
- package/dist/engine/pattern-library/static-schemas.js +0 -487
- package/dist/engine/pattern-library/types.d.ts +0 -158
- package/dist/engine/pattern-library/types.js +0 -36
- package/dist/engine/resolve-config-or-param.d.ts +0 -18
- package/dist/engine/resolve-config-or-param.js +0 -76
- package/src/scripts/codemod/README.md +0 -187
- package/src/scripts/codemod/codemod-support.ts +0 -334
- package/src/scripts/codemod/collect-source-files.ts +0 -48
- package/src/scripts/codemod/crypto-shredding-testing-move.ts +0 -119
- package/src/scripts/codemod/db-factory.ts +0 -810
- package/src/scripts/codemod/feature-factory.ts +0 -429
- package/src/scripts/codemod/feature-layout.ts +0 -424
- package/src/scripts/codemod/import-extensions.ts +0 -118
- package/src/scripts/codemod/migrate-cross-tenant.ts +0 -328
- package/src/scripts/codemod/migrate-db-raw.ts +0 -401
- package/src/scripts/codemod/migrate-open-to-all.ts +0 -235
- package/src/scripts/codemod/object-form.ts +0 -746
- package/src/scripts/codemod/package-merge.ts +0 -299
- package/src/scripts/codemod/pii-personal-migration.ts +0 -816
- package/src/scripts/codemod/remove-engine-payload-casts.ts +0 -318
- package/src/scripts/codemod/s3-imports.ts +0 -236
- package/src/scripts/codemod/tenant-db-options.ts +0 -454
- package/src/scripts/codemod/testing-injection.ts +0 -215
- package/src/scripts/codemod/testing-move-targets.ts +0 -161
- package/src/scripts/codemod/testing-move.ts +0 -542
- package/src/scripts/codemod/unprocessable-error-details-reason.ts +0 -411
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type DbConnection } from "../db/index.ts";
|
|
2
|
-
export type EsOperationType = "seed-migration";
|
|
2
|
+
export type EsOperationType = "seed-migration" | "stream-migration";
|
|
3
3
|
export type EsOperationAppliedBy = "boot" | "cli" | "ci-pipeline";
|
|
4
4
|
export declare const esOperationsTable: import("@cosmicdrift/kumiko-types/executor-brand").WritableSchemaTable;
|
|
5
5
|
export declare function createEsOperationsTable(db: DbConnection): Promise<void>;
|
package/dist/es-ops/types.d.ts
CHANGED
|
@@ -30,10 +30,9 @@ export type SeedUserRow = {
|
|
|
30
30
|
/** Read shape of a membership entry exposed to seed helpers.
|
|
31
31
|
* Distinguishes two tenantIds: the logical one from the read projection
|
|
32
32
|
* (`tenantId`) and the physical one from the aggregate stream
|
|
33
|
-
* (`streamTenantId`). They differ
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* publicstatus driver use case. */
|
|
33
|
+
* (`streamTenantId`). They only differ for memberships written by an admin
|
|
34
|
+
* of another tenant before `backfillTenantStreamTenants` ran; afterwards
|
|
35
|
+
* `streamTenantId = tenantId`. */
|
|
37
36
|
export type SeedMembershipRow = {
|
|
38
37
|
readonly userId: string;
|
|
39
38
|
/** Payload tenant from `read_tenant_memberships.tenant_id`; it is used
|
|
@@ -74,7 +73,7 @@ export type SeedMigrationContext = {
|
|
|
74
73
|
* user executes it while bypassing access checks. Events have
|
|
75
74
|
* inserted_by_id = SYSTEM_TENANT_ID-user, making them auditable.
|
|
76
75
|
*
|
|
77
|
-
* The type signature follows existing ctx.writeAs (with payload as unknown).
|
|
76
|
+
* The type signature follows existing ctx.dispatch.writeAs (with payload as unknown).
|
|
78
77
|
* Type safety comes from handler-specific wrappers in the caller; do not
|
|
79
78
|
* attempt generic magic.
|
|
80
79
|
*
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { TenantId } from "../engine/types/index.ts";
|
|
2
|
+
import type { EventMetadata } from "./event-store.ts";
|
|
3
|
+
export type RawEventToAppend = {
|
|
4
|
+
readonly aggregateId: string;
|
|
5
|
+
readonly aggregateType: string;
|
|
6
|
+
readonly tenantId: TenantId;
|
|
7
|
+
readonly expectedVersion: number;
|
|
8
|
+
readonly type: string;
|
|
9
|
+
readonly eventVersion?: number;
|
|
10
|
+
readonly payload: Record<string, unknown>;
|
|
11
|
+
readonly metadata: EventMetadata;
|
|
12
|
+
readonly createdAt: Temporal.Instant;
|
|
13
|
+
readonly createdBy: string;
|
|
14
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,18 +1,5 @@
|
|
|
1
1
|
/// <reference types="temporal-polyfill/global" preserve="true" />
|
|
2
2
|
import type { DbRunner } from "../db/index.ts";
|
|
3
|
-
import type {
|
|
4
|
-
import type { EventMetadata } from "./event-store.ts";
|
|
5
|
-
export type RawEventToAppend = {
|
|
6
|
-
readonly aggregateId: string;
|
|
7
|
-
readonly aggregateType: string;
|
|
8
|
-
readonly tenantId: TenantId;
|
|
9
|
-
readonly expectedVersion: number;
|
|
10
|
-
readonly type: string;
|
|
11
|
-
readonly eventVersion?: number;
|
|
12
|
-
readonly payload: Record<string, unknown>;
|
|
13
|
-
readonly metadata: EventMetadata;
|
|
14
|
-
readonly createdAt: Temporal.Instant;
|
|
15
|
-
readonly createdBy: string;
|
|
16
|
-
};
|
|
3
|
+
import type { RawEventToAppend } from "./admin-api-internals.ts";
|
|
17
4
|
export declare function appendRaw(runner: DbRunner, event: RawEventToAppend): Promise<void>;
|
|
18
5
|
export declare function appendRawBatch(runner: DbRunner, events: readonly RawEventToAppend[]): Promise<void>;
|
|
@@ -10,7 +10,9 @@ import { instantToTimestamptzParam } from "../db/driver-value-preparation.js";
|
|
|
10
10
|
import { constraintOf, isUniqueViolation } from "../db/pg-error.js";
|
|
11
11
|
import { claimXactId, runAtomicEventWrite } from "../db/queries/event-store.js";
|
|
12
12
|
import { eventPredecessorExists, findExistingEventVersion, insertRawEventBatch, insertRawFirstEvent, insertRawSubsequentEvent, } from "../db/queries/event-store-admin.js";
|
|
13
|
+
import { runInSystemRowLevelSecurityScope } from "../db/row-level-security-scope.js";
|
|
13
14
|
import { IdempotentAppendConflictError, VersionConflictError } from "./errors.js";
|
|
15
|
+
import { inEventStreamScope } from "./stream-scope.js";
|
|
14
16
|
function mapEventUniqueViolation(e, event) {
|
|
15
17
|
if (constraintOf(e) === "events_idempotency_uq" && event.metadata.idempotencyKey) {
|
|
16
18
|
return new IdempotentAppendConflictError(event.tenantId, event.metadata.idempotencyKey);
|
|
@@ -26,7 +28,7 @@ export async function appendRaw(runner, event) {
|
|
|
26
28
|
try {
|
|
27
29
|
// See db/queries/event-store.ts's claimXactId — gap-finality needs a
|
|
28
30
|
// real xact id assigned before this holder's insert.
|
|
29
|
-
await runAtomicEventWrite(runner, async (tx) => {
|
|
31
|
+
await inEventStreamScope(event.tenantId, () => runAtomicEventWrite(runner, async (tx) => {
|
|
30
32
|
await claimXactId(tx);
|
|
31
33
|
if (event.expectedVersion === 0) {
|
|
32
34
|
await insertRawFirst(tx, event, newVersion, eventVersion);
|
|
@@ -34,7 +36,7 @@ export async function appendRaw(runner, event) {
|
|
|
34
36
|
else {
|
|
35
37
|
await insertRawSubsequent(tx, event, newVersion, eventVersion);
|
|
36
38
|
}
|
|
37
|
-
});
|
|
39
|
+
}));
|
|
38
40
|
}
|
|
39
41
|
catch (e) {
|
|
40
42
|
if (isUniqueViolation(e)) {
|
|
@@ -81,8 +83,11 @@ export async function appendRawBatch(runner, events) {
|
|
|
81
83
|
if (!firstEvent)
|
|
82
84
|
return;
|
|
83
85
|
verifyContiguousWithinBatch(events);
|
|
84
|
-
|
|
85
|
-
await
|
|
86
|
+
// A batch may span tenants (replay, transfer), so its pre-flight reads and the insert are system scoped.
|
|
87
|
+
await runInSystemRowLevelSecurityScope("raw event batch append writes events for arbitrary tenants", async () => {
|
|
88
|
+
await verifyPredecessors(runner, events);
|
|
89
|
+
await verifyNoDuplicates(runner, events);
|
|
90
|
+
});
|
|
86
91
|
const params = [];
|
|
87
92
|
const valuesClauses = events.map((e) => {
|
|
88
93
|
const newVersion = e.expectedVersion + 1;
|
|
@@ -92,10 +97,10 @@ export async function appendRawBatch(runner, events) {
|
|
|
92
97
|
return `($${baseIdx + 1}::uuid, $${baseIdx + 2}, $${baseIdx + 3}::uuid, $${baseIdx + 4}, $${baseIdx + 5}, $${baseIdx + 6}, $${baseIdx + 7}::jsonb, $${baseIdx + 8}::jsonb, $${baseIdx + 9}::timestamptz, $${baseIdx + 10})`;
|
|
93
98
|
});
|
|
94
99
|
try {
|
|
95
|
-
await runAtomicEventWrite(runner, async (tx) => {
|
|
100
|
+
await runInSystemRowLevelSecurityScope("raw event batch append refreshes stream state across tenants", () => runAtomicEventWrite(runner, async (tx) => {
|
|
96
101
|
await claimXactId(tx);
|
|
97
102
|
await insertRawEventBatch(tx, valuesClauses.join(", "), params);
|
|
98
|
-
});
|
|
103
|
+
}));
|
|
99
104
|
}
|
|
100
105
|
catch (e) {
|
|
101
106
|
if (isUniqueViolation(e)) {
|
|
@@ -3,7 +3,7 @@ import { instant, table as pgTable, sql, text, uniqueIndex, uuid } from "../db/d
|
|
|
3
3
|
import { upsertArchivedStream } from "../db/queries/event-store.js";
|
|
4
4
|
import { deleteMany, fetchOne } from "../db/query.js";
|
|
5
5
|
import { tableExists } from "../db/schema-inspection.js";
|
|
6
|
-
import { unsafePushTables } from "../db/table-push.js";
|
|
6
|
+
import { ensureTableRowLevelSecurity, unsafePushTables } from "../db/table-push.js";
|
|
7
7
|
// Marten-aligned stream archival. Archived streams become read-only: fresh
|
|
8
8
|
// appendEvent on an archived aggregate throws, and loadAggregate returns
|
|
9
9
|
// an empty slice unless the caller passes { includeArchived: true }.
|
|
@@ -24,8 +24,10 @@ export const archivedStreamsTable = pgTable("kumiko_archived_streams", {
|
|
|
24
24
|
// guard:dup-ok — intentionale Parallele zu createSnapshotsTable; verschiedene Tabellen-Schemas by design
|
|
25
25
|
export async function createArchivedStreamsTable(db) {
|
|
26
26
|
// skip: table already exists — idempotent boot + test-setup call
|
|
27
|
-
if (await tableExists(db, "public.kumiko_archived_streams"))
|
|
27
|
+
if (await tableExists(db, "public.kumiko_archived_streams")) {
|
|
28
|
+
await ensureTableRowLevelSecurity(db, archivedStreamsTable);
|
|
28
29
|
return;
|
|
30
|
+
}
|
|
29
31
|
await unsafePushTables(db, { kumikoArchivedStreams: archivedStreamsTable });
|
|
30
32
|
}
|
|
31
33
|
// Mark a stream as archived. Idempotent — re-archiving (same tenant +
|
|
@@ -55,11 +55,11 @@ export class SeedTimeOrderError extends Error {
|
|
|
55
55
|
this.predecessorCreatedAt = predecessorCreatedAt;
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
|
-
// Thrown when ctx.
|
|
58
|
+
// Thrown when ctx.events.append targets an archived stream. Archived aggregates
|
|
59
59
|
// are read-only — restoreStream() makes them writable again. The archive
|
|
60
60
|
// state is not carried on the events themselves; it lives on the sparse
|
|
61
61
|
// kumiko_archived_streams table. Handlers that need to branch on archive
|
|
62
|
-
// state should call ctx.
|
|
62
|
+
// state should call ctx.events.isArchived(id) first.
|
|
63
63
|
export class ArchivedStreamError extends Error {
|
|
64
64
|
tenantId;
|
|
65
65
|
aggregateId;
|
|
@@ -12,6 +12,7 @@ import { IdempotentAppendConflictError, SeedTimeOrderError, VersionConflictError
|
|
|
12
12
|
import { eventsTable } from "./events-schema.js";
|
|
13
13
|
import { toStoredEvent } from "./row-to-stored-event.js";
|
|
14
14
|
import { currentSeedCreatedAt } from "./seed-clock.js";
|
|
15
|
+
import { inEventStreamScope } from "./stream-scope.js";
|
|
15
16
|
// Append one event atomically. Two guarantees combined:
|
|
16
17
|
//
|
|
17
18
|
// 1. UNIQUE (tenant_id, aggregate_id, version) serializes concurrent writers
|
|
@@ -51,7 +52,7 @@ export async function append(db, event) {
|
|
|
51
52
|
const newVersion = toStore.expectedVersion + 1;
|
|
52
53
|
const eventVersion = toStore.eventVersion ?? 1;
|
|
53
54
|
try {
|
|
54
|
-
const row = await runAtomicEventWrite(db, async (runner) => {
|
|
55
|
+
const row = await inEventStreamScope(toStore.tenantId, () => runAtomicEventWrite(db, async (runner) => {
|
|
55
56
|
await claimXactId(runner);
|
|
56
57
|
// Inside the write transaction so a concurrent live append cannot slip
|
|
57
58
|
// between the check and the insert.
|
|
@@ -65,7 +66,7 @@ export async function append(db, event) {
|
|
|
65
66
|
// commit, so the dispatcher cannot wake before the row is visible.
|
|
66
67
|
await notifyPgChannel(runner, EVENTS_PUBSUB_CHANNEL);
|
|
67
68
|
return inserted;
|
|
68
|
-
});
|
|
69
|
+
}));
|
|
69
70
|
return buildStoredEvent(toStore, newVersion, eventVersion, row);
|
|
70
71
|
}
|
|
71
72
|
catch (e) {
|
|
@@ -208,18 +209,20 @@ export async function loadAggregate(db, aggregateId, tenantId, options) {
|
|
|
208
209
|
if (options?.aggregateType === "") {
|
|
209
210
|
throw new Error("loadAggregate: aggregateType must be a non-empty string when provided");
|
|
210
211
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
212
|
+
return inEventStreamScope(tenantId, async () => {
|
|
213
|
+
if (!options?.includeArchived) {
|
|
214
|
+
const archived = await isStreamArchived(db, tenantId, aggregateId);
|
|
215
|
+
if (archived)
|
|
216
|
+
return [];
|
|
217
|
+
}
|
|
218
|
+
const rows = await selectMany(db, eventsTable, {
|
|
219
|
+
aggregateId,
|
|
220
|
+
tenantId,
|
|
221
|
+
...(options?.aggregateType !== undefined && { aggregateType: options.aggregateType }),
|
|
222
|
+
...(options?.atVersion !== undefined && { version: options.atVersion }),
|
|
223
|
+
}, { orderBy: { col: "version", direction: "asc" } });
|
|
224
|
+
return rows.map(toStoredEvent);
|
|
225
|
+
});
|
|
223
226
|
}
|
|
224
227
|
// Events and the stream's latest version from ONE read, so both come from the same
|
|
225
228
|
// snapshot: a commit landing between two separate statements would leave the caller
|
|
@@ -230,40 +233,44 @@ export async function loadAggregateForWriting(db, aggregateId, tenantId, options
|
|
|
230
233
|
if (options.aggregateType === "") {
|
|
231
234
|
throw new Error("loadAggregateForWriting: aggregateType must be a non-empty string");
|
|
232
235
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
236
|
+
return inEventStreamScope(tenantId, async () => {
|
|
237
|
+
if (await isStreamArchived(db, tenantId, aggregateId)) {
|
|
238
|
+
return { events: [], streamVersion: await getStreamVersion(db, aggregateId, tenantId) };
|
|
239
|
+
}
|
|
240
|
+
const rows = await selectMany(db, eventsTable, { aggregateId, tenantId }, { orderBy: { col: "version", direction: "asc" } });
|
|
241
|
+
const all = rows.map(toStoredEvent);
|
|
242
|
+
return {
|
|
243
|
+
events: all.filter((e) => e.aggregateType === options.aggregateType),
|
|
244
|
+
streamVersion: all.at(-1)?.version ?? 0,
|
|
245
|
+
};
|
|
246
|
+
});
|
|
242
247
|
}
|
|
243
248
|
// Load events up to a point in time. Used for asOf queries that reconstruct
|
|
244
249
|
// historical state. Includes events whose created_at is <= asOf. Same
|
|
245
250
|
// archive semantics as loadAggregate.
|
|
246
251
|
export async function loadAggregateAsOf(db, aggregateId, tenantId, asOf, options) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
252
|
+
return inEventStreamScope(tenantId, async () => {
|
|
253
|
+
if (!options?.includeArchived) {
|
|
254
|
+
const archived = await isStreamArchived(db, tenantId, aggregateId);
|
|
255
|
+
if (archived)
|
|
256
|
+
return [];
|
|
257
|
+
}
|
|
258
|
+
const rows = await selectMany(db, eventsTable, { aggregateId, tenantId, createdAt: { lte: asOf } }, { orderBy: { col: "version", direction: "asc" } });
|
|
259
|
+
return rows.map(toStoredEvent);
|
|
260
|
+
});
|
|
254
261
|
}
|
|
255
262
|
// Cheapest possible read of "what's the latest version on this stream?". The
|
|
256
263
|
// CRUD executor uses this as expectedVersion for its append, so a domain
|
|
257
|
-
// event appended via ctx.
|
|
264
|
+
// event appended via ctx.events.append between two CRUD writes doesn't cause
|
|
258
265
|
// the next CRUD write to fail with version_conflict. Indexed lookup on the
|
|
259
266
|
// existing (aggregate_id, version) unique index. Returns 0 for empty/unknown
|
|
260
267
|
// streams (matches create()'s expectedVersion=0 convention).
|
|
261
268
|
// @wrapper-known semantic-alias
|
|
262
269
|
export async function getStreamVersion(db, aggregateId, tenantId) {
|
|
263
|
-
return selectStreamMaxVersion(db, aggregateId, tenantId);
|
|
270
|
+
return inEventStreamScope(tenantId, () => selectStreamMaxVersion(db, aggregateId, tenantId));
|
|
264
271
|
}
|
|
265
272
|
export async function getStreamVersions(db, aggregateIds, tenantId) {
|
|
266
|
-
return selectStreamMaxVersions(db, aggregateIds, tenantId);
|
|
273
|
+
return inEventStreamScope(tenantId, () => selectStreamMaxVersions(db, aggregateIds, tenantId));
|
|
267
274
|
}
|
|
268
275
|
/** MAX(version) for one aggregate — no tenant filter. SECURITY: existence-oracle,
|
|
269
276
|
* a caller can probe whether an aggregateId has any events regardless of tenant
|
|
@@ -310,7 +317,7 @@ export async function loadEventsAfterVersion(db, aggregateId, tenantId, afterVer
|
|
|
310
317
|
// The caller may pause / do async work between yields; the next batch is
|
|
311
318
|
// only fetched when consumed.
|
|
312
319
|
//
|
|
313
|
-
// Cancellation: pass `signal` (typically `ctx.signal` from a handler) to
|
|
320
|
+
// Cancellation: pass `signal` (typically `ctx.lifecycle.signal` from a handler) to
|
|
314
321
|
// abort iteration. Checked both at batch boundaries (before the next
|
|
315
322
|
// fetch) AND between yields (so abort lands within one event regardless
|
|
316
323
|
// of batch size). Throws AbortError on the first check after abort;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { bigserial, index, instant, integer, jsonb, table as pgTable, sql, text, uniqueIndex, uuid, } from "../db/dialect.js";
|
|
3
3
|
import { tableExists } from "../db/index.js";
|
|
4
4
|
import { ensureIdempotencyKeyIndex, ensureMembershipPayloadTenantIndex, } from "../db/queries/event-store.js";
|
|
5
|
-
import { unsafePushTables } from "../db/table-push.js";
|
|
5
|
+
import { ensureTableRowLevelSecurity, unsafePushTables } from "../db/table-push.js";
|
|
6
6
|
import { createArchivedStreamsTable } from "./archive.js";
|
|
7
7
|
import { createSnapshotsTable } from "./snapshot.js";
|
|
8
8
|
// Event-store schema as a Drizzle table. The typed select/insert path handles
|
|
@@ -57,6 +57,9 @@ export async function createEventsTable(db) {
|
|
|
57
57
|
if (!(await tableExists(db, "public.kumiko_events"))) {
|
|
58
58
|
await unsafePushTables(db, { kumikoEvents: eventsTable });
|
|
59
59
|
}
|
|
60
|
+
else {
|
|
61
|
+
await ensureTableRowLevelSecurity(db, eventsTable);
|
|
62
|
+
}
|
|
60
63
|
// Runs unconditionally (both fresh + already-existing table) so installs
|
|
61
64
|
// that predate the idempotency-key index get healed the same way
|
|
62
65
|
// ensureSnapshotVersionColumn heals kumiko_snapshots.
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
export { APP_INSTANCE_STREAM_TYPE, APP_STARTED_EVENT_TYPE } from "../crypto/system-event-pii.ts";
|
|
2
|
-
export { backfillEventPiiEncryption, backfillEventPiiEncryptionBatch,
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
6
|
-
export { append,
|
|
2
|
+
export { backfillEventPiiEncryption, backfillEventPiiEncryptionBatch, } from "../db/queries/backfill-pii.ts";
|
|
3
|
+
export { deleteRowsWithoutReplayableStream } from "../db/queries/event-store-orphan-rows.ts";
|
|
4
|
+
export { archivedStreamsTable, archiveStream, createArchivedStreamsTable, isStreamArchived, } from "./archive.ts";
|
|
5
|
+
export { SeedTimeOrderError, VersionConflictError, } from "./errors.ts";
|
|
6
|
+
export { append, type EventMetadata, getEventsHighWaterMark, getStreamVersion, getStreamVersions, getUnscopedAggregateStreamMaxVersion, getUnscopedStreamMaxVersionForSeed, loadAggregate, type StoredEvent, streamAllEventsByType, } from "./event-store.ts";
|
|
7
7
|
export { createEventsTable, eventsTable } from "./events-schema.ts";
|
|
8
|
-
export { appendProvenanceEvent
|
|
9
|
-
export { createRebuildDeadLetterTable, listRebuildDeadLetters, type RebuildDeadLetterRow, rebuildDeadLetterTable, recordRebuildDeadLetters, type SkippedApply, } from "./rebuild-dead-letter.ts";
|
|
10
|
-
export { toStoredEvent } from "./row-to-stored-event.ts";
|
|
8
|
+
export { appendProvenanceEvent } from "./provenance-append.ts";
|
|
11
9
|
export { assertSeedModeNotInProduction, isSeedModeEnabled, runSeedWritesAt, SEED_MODE_ENV, SeedModeDisabledError, } from "./seed-clock.ts";
|
|
12
|
-
export {
|
|
13
|
-
export {
|
|
14
|
-
export { AGGREGATE_TRANSFER_STREAM_TYPE, AGGREGATE_TRANSFERRED_EVENT_TYPE,
|
|
15
|
-
export {
|
|
16
|
-
export {
|
|
10
|
+
export { snapshotsTable } from "./snapshot.ts";
|
|
11
|
+
export { appendEventInTenantDb, getStreamVersionInTenantDb, } from "./tenant-db-append.ts";
|
|
12
|
+
export { AGGREGATE_TRANSFER_STREAM_TYPE, AGGREGATE_TRANSFERRED_EVENT_TYPE, transferAggregateStreams, } from "./transfer.ts";
|
|
13
|
+
export { makeUpcastCtx, upcastStoredEvent, } from "./upcaster.ts";
|
|
14
|
+
export { upcasterDeadLetterTable } from "./upcaster-dead-letter.ts";
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
export { APP_INSTANCE_STREAM_TYPE, APP_STARTED_EVENT_TYPE } from "../crypto/system-event-pii.js";
|
|
2
2
|
export { backfillEventPiiEncryption, backfillEventPiiEncryptionBatch, } from "../db/queries/backfill-pii.js";
|
|
3
|
-
export { deleteRowsWithoutReplayableStream
|
|
4
|
-
export { archivedStreamsTable, archiveStream, createArchivedStreamsTable, isStreamArchived,
|
|
5
|
-
export {
|
|
6
|
-
export { append,
|
|
3
|
+
export { deleteRowsWithoutReplayableStream } from "../db/queries/event-store-orphan-rows.js";
|
|
4
|
+
export { archivedStreamsTable, archiveStream, createArchivedStreamsTable, isStreamArchived, } from "./archive.js";
|
|
5
|
+
export { SeedTimeOrderError, VersionConflictError, } from "./errors.js";
|
|
6
|
+
export { append, getEventsHighWaterMark, getStreamVersion, getStreamVersions, getUnscopedAggregateStreamMaxVersion, getUnscopedStreamMaxVersionForSeed, loadAggregate, streamAllEventsByType, } from "./event-store.js";
|
|
7
7
|
export { createEventsTable, eventsTable } from "./events-schema.js";
|
|
8
8
|
export { appendProvenanceEvent } from "./provenance-append.js";
|
|
9
|
-
export { createRebuildDeadLetterTable, listRebuildDeadLetters, rebuildDeadLetterTable, recordRebuildDeadLetters, } from "./rebuild-dead-letter.js";
|
|
10
|
-
export { toStoredEvent } from "./row-to-stored-event.js";
|
|
11
9
|
export { assertSeedModeNotInProduction, isSeedModeEnabled, runSeedWritesAt, SEED_MODE_ENV, SeedModeDisabledError, } from "./seed-clock.js";
|
|
12
|
-
export {
|
|
10
|
+
export { snapshotsTable } from "./snapshot.js";
|
|
13
11
|
export { appendEventInTenantDb, getStreamVersionInTenantDb, } from "./tenant-db-append.js";
|
|
14
12
|
export { AGGREGATE_TRANSFER_STREAM_TYPE, AGGREGATE_TRANSFERRED_EVENT_TYPE, transferAggregateStreams, } from "./transfer.js";
|
|
15
|
-
export { makeUpcastCtx, upcastStoredEvent,
|
|
16
|
-
export {
|
|
13
|
+
export { makeUpcastCtx, upcastStoredEvent, } from "./upcaster.js";
|
|
14
|
+
export { upcasterDeadLetterTable } from "./upcaster-dead-letter.js";
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// is a separate ops step — same stance as the upcaster dead-letter.
|
|
15
15
|
import { bigint, index, jsonb, table as pgTable, text, timestamp, uuid } from "../db/dialect.js";
|
|
16
16
|
import { tableExists } from "../db/schema-inspection.js";
|
|
17
|
-
import { unsafePushTables } from "../db/table-push.js";
|
|
17
|
+
import { ensureTableRowLevelSecurity, unsafePushTables } from "../db/table-push.js";
|
|
18
18
|
export const rebuildDeadLetterTable = pgTable("kumiko_rebuild_dead_letters", {
|
|
19
19
|
// Surrogate PK — the same event can land here across multiple rebuild
|
|
20
20
|
// attempts before the fix ships, without unique-violation noise.
|
|
@@ -39,8 +39,10 @@ export const rebuildDeadLetterTable = pgTable("kumiko_rebuild_dead_letters", {
|
|
|
39
39
|
// provisioned before this table existed.
|
|
40
40
|
export async function createRebuildDeadLetterTable(db) {
|
|
41
41
|
// skip: table already exists — bootstrap called from multiple paths
|
|
42
|
-
if (await tableExists(db, "public.kumiko_rebuild_dead_letters"))
|
|
42
|
+
if (await tableExists(db, "public.kumiko_rebuild_dead_letters")) {
|
|
43
|
+
await ensureTableRowLevelSecurity(db, rebuildDeadLetterTable);
|
|
43
44
|
return;
|
|
45
|
+
}
|
|
44
46
|
await unsafePushTables(db, { kumikoRebuildDeadLetters: rebuildDeadLetterTable });
|
|
45
47
|
}
|
|
46
48
|
// Bulk-write, called ONCE at the end of a quarantining rebuild (inside its
|
|
@@ -4,7 +4,7 @@ import { index, instant, integer, jsonb, table as pgTable, primaryKey, sql, text
|
|
|
4
4
|
import { ensureSnapshotVersionColumn, upsertSnapshot } from "../db/queries/event-store.js";
|
|
5
5
|
import { selectMany } from "../db/query.js";
|
|
6
6
|
import { tableExists } from "../db/schema-inspection.js";
|
|
7
|
-
import { unsafePushTables } from "../db/table-push.js";
|
|
7
|
+
import { ensureTableRowLevelSecurity, unsafePushTables } from "../db/table-push.js";
|
|
8
8
|
import { createFallbackLogger, scrubLogText } from "../logging/index.js";
|
|
9
9
|
import { isStreamArchived } from "./archive.js";
|
|
10
10
|
import { loadEventsAfterVersion } from "./event-store.js";
|
|
@@ -18,7 +18,7 @@ import { loadEventsAfterVersion } from "./event-store.js";
|
|
|
18
18
|
// 3. loadEventsAfterVersion(aggregate, N) → only the delta
|
|
19
19
|
// 4. reducer(snapshot, delta) → current state
|
|
20
20
|
//
|
|
21
|
-
// Write path: manual via ctx.
|
|
21
|
+
// Write path: manual via ctx.events.snapshot, or automatic via the
|
|
22
22
|
// { snapshotEvery: N } load option — the read path persists a fresh
|
|
23
23
|
// snapshot whenever it folded at least N delta events.
|
|
24
24
|
//
|
|
@@ -32,7 +32,7 @@ import { loadEventsAfterVersion } from "./event-store.js";
|
|
|
32
32
|
//
|
|
33
33
|
// Upcaster interaction: the raw API (loadAggregateWithSnapshot below) does
|
|
34
34
|
// NOT apply the upcaster chain on delta events — same layering as raw
|
|
35
|
-
// loadAggregate. The Dispatcher wraps this into ctx.
|
|
35
|
+
// loadAggregate. The Dispatcher wraps this into ctx.events.loadWithSnapshot
|
|
36
36
|
// and runs upcastStoredEvents on the delta before calling the reducer, so
|
|
37
37
|
// feature authors always see current-version payloads.
|
|
38
38
|
export const snapshotsTable = pgTable("kumiko_snapshots", {
|
|
@@ -64,6 +64,7 @@ export async function createSnapshotsTable(db) {
|
|
|
64
64
|
// Installs that predate snapshot_version get healed by the same
|
|
65
65
|
// idempotent ensure that `kumiko schema apply` / test-setup already runs.
|
|
66
66
|
await ensureSnapshotVersionColumn(db);
|
|
67
|
+
await ensureTableRowLevelSecurity(db, snapshotsTable);
|
|
67
68
|
// skip: table already ensured — only the column heal above was needed
|
|
68
69
|
return;
|
|
69
70
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { runInRowLevelSecurityScope, tenantRowLevelSecurityScope, } from "../db/row-level-security-scope.js";
|
|
2
|
+
// A stream belongs to exactly one tenant; its rows are only writable and reliably readable in
|
|
3
|
+
// that tenant's scope, which differs from the caller's for systemStream entities and ctx.tenants.writeTarget.
|
|
4
|
+
export function inEventStreamScope(streamTenantId, work) {
|
|
5
|
+
return runInRowLevelSecurityScope(tenantRowLevelSecurityScope(streamTenantId), work);
|
|
6
|
+
}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// separate CLI step — not implemented here, tracked as follow-up.
|
|
14
14
|
import { bigint, index, integer, jsonb, table as pgTable, text, timestamp, uuid, } from "../db/dialect.js";
|
|
15
15
|
import { tableExists } from "../db/schema-inspection.js";
|
|
16
|
-
import { unsafePushTables } from "../db/table-push.js";
|
|
16
|
+
import { ensureTableRowLevelSecurity, unsafePushTables } from "../db/table-push.js";
|
|
17
17
|
export const upcasterDeadLetterTable = pgTable("kumiko_upcaster_dead_letters", {
|
|
18
18
|
// Surrogate PK. We don't reuse eventId so a single event can land
|
|
19
19
|
// here multiple times (retry attempts across deploys before the fix
|
|
@@ -40,8 +40,10 @@ export const upcasterDeadLetterTable = pgTable("kumiko_upcaster_dead_letters", {
|
|
|
40
40
|
// exercise the quarantine path; production boot uses drizzle-kit push.
|
|
41
41
|
export async function createUpcasterDeadLetterTable(db) {
|
|
42
42
|
// skip: table already exists — bootstrap called from multiple paths
|
|
43
|
-
if (await tableExists(db, "public.kumiko_upcaster_dead_letters"))
|
|
43
|
+
if (await tableExists(db, "public.kumiko_upcaster_dead_letters")) {
|
|
44
|
+
await ensureTableRowLevelSecurity(db, upcasterDeadLetterTable);
|
|
44
45
|
return;
|
|
46
|
+
}
|
|
45
47
|
await unsafePushTables(db, { kumikoUpcasterDeadLetters: upcasterDeadLetterTable });
|
|
46
48
|
}
|
|
47
49
|
// Writes a dead-letter row. Called by upcastStoredEvent when errorPolicy
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { EventUpcastCtx, EventUpcastFn } from "@cosmicdrift/kumiko-types/handlers";
|
|
1
2
|
import type { DbRunner } from "../db/index.ts";
|
|
2
|
-
import type {
|
|
3
|
+
import type { TenantId } from "../engine/types/index.ts";
|
|
3
4
|
import type { StoredEvent } from "./event-store.ts";
|
|
4
5
|
export type UpcasterErrorPolicy = "throw" | "quarantine";
|
|
5
6
|
export type UpcastOptions = {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { AnyFileFieldDef } from "@cosmicdrift/kumiko-types/fields";
|
|
2
|
+
import type { Registry, SessionUser } from "../engine/types/index.ts";
|
|
2
3
|
export declare function isActionFormScreenQn(value: string): boolean;
|
|
3
4
|
/** The files/images field `fieldName` of the registered actionForm screen `screenQn`, if any. */
|
|
4
5
|
export declare function resolveActionFormFileField(registry: Pick<Registry, "getScreen"> | undefined, screenQn: string, fieldName: string): AnyFileFieldDef | undefined;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { hasAccess } from "../engine/access.js";
|
|
2
|
-
import { isFileField
|
|
2
|
+
import { isFileField } from "../engine/field-helpers.js";
|
|
3
3
|
// Same character set as the other upload identifiers: the screen QN is stored as the pending
|
|
4
4
|
// upload's entityType and compared by exact match, never interpolated into a storage key.
|
|
5
5
|
const ACTION_FORM_SCREEN_QN = /^[A-Za-z0-9_-]+:screen:[A-Za-z0-9_-]+$/;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { SaveContext } from "@cosmicdrift/kumiko-types/hooks";
|
|
2
|
+
import type { Registry } from "../engine/types/index.ts";
|
|
2
3
|
import type { FileRefRows } from "./load-save-file-refs.ts";
|
|
3
4
|
export declare function assertFileRefsBelongToTenant(args: {
|
|
4
5
|
readonly registry: Registry;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isFileField } from "../engine/
|
|
1
|
+
import { isFileField } from "../engine/field-helpers.js";
|
|
2
2
|
import { ValidationError } from "../errors/index.js";
|
|
3
3
|
import { fileRefIdsOf } from "./bind-pending-file-refs.js";
|
|
4
4
|
import { FILE_REF_ENTITY_NAME } from "./file-ref-entity.js";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { SaveContext } from "@cosmicdrift/kumiko-types/hooks";
|
|
1
2
|
import type { TenantDb } from "../db/tenant-db.ts";
|
|
2
|
-
import {
|
|
3
|
+
import type { Registry, SessionUser } from "../engine/types/index.ts";
|
|
3
4
|
import { type FileRefRows } from "./load-save-file-refs.ts";
|
|
4
5
|
export declare function fileRefIdsOf(value: unknown): readonly string[];
|
|
5
6
|
type FileRefRow = Readonly<Record<string, unknown>>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { isUuid } from "@cosmicdrift/kumiko-types/identifiers";
|
|
2
|
+
import { isFileField } from "../engine/field-helpers.js";
|
|
1
3
|
import { isAnonymousSessionUser } from "../engine/system-user.js";
|
|
2
|
-
import { isFileField, isUuid, } from "../engine/types/index.js";
|
|
3
4
|
import { FrameworkReasons, InternalError, reraiseAsKumikoError, UnprocessableError, } from "../errors/index.js";
|
|
4
5
|
import { getFileRefExecutor, resolveAttachedField } from "./create-file-ref.js";
|
|
5
6
|
import { FILE_REF_ENTITY_NAME } from "./file-ref-entity.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
|
+
import { isFileField } from "../engine/field-helpers.js";
|
|
2
3
|
import { defineWriteHandler, SYSTEM_ROLE, SYSTEM_USER_ID } from "../engine/index.js";
|
|
3
|
-
import { isFileField } from "../engine/types/index.js";
|
|
4
4
|
import { ValidationError } from "../errors/index.js";
|
|
5
5
|
import { fileRefIdsOf } from "./bind-pending-file-refs.js";
|
|
6
6
|
import { getFileRefExecutor } from "./create-file-ref.js";
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import type { BeforeTransactionResult, WriteResult } from "@cosmicdrift/kumiko-types/handlers";
|
|
1
2
|
import type { TenantDb } from "../db/tenant-db.ts";
|
|
2
|
-
import type {
|
|
3
|
+
import type { Registry, SessionUser } from "../engine/types/index.ts";
|
|
3
4
|
import { type CreatedFileRef, type UploadedFileBytes } from "./create-file-ref.ts";
|
|
4
5
|
import type { FileContext } from "./file-handle.ts";
|
|
5
6
|
export type { CreatedFileRef, UploadedFileBytes };
|
|
6
7
|
export type CreateFileRefContext = {
|
|
7
8
|
readonly db: TenantDb;
|
|
8
|
-
readonly
|
|
9
|
+
readonly services: {
|
|
10
|
+
readonly files?: FileContext | undefined;
|
|
11
|
+
};
|
|
9
12
|
readonly registry: Registry;
|
|
10
13
|
readonly user: SessionUser;
|
|
11
14
|
};
|
|
@@ -21,6 +24,6 @@ export type CreateFileRefInput = {
|
|
|
21
24
|
};
|
|
22
25
|
export declare function filesUnavailableMessage(caller: string): string;
|
|
23
26
|
export declare function createFileRefFromBytes(ctx: CreateFileRefContext, input: CreateFileRefInput): Promise<WriteResult<CreatedFileRef>>;
|
|
24
|
-
export type UploadFileBytesContext = Pick<CreateFileRefContext, "db" | "
|
|
27
|
+
export type UploadFileBytesContext = Pick<CreateFileRefContext, "db" | "services" | "registry" | "user">;
|
|
25
28
|
export declare function uploadFileBytesBeforeTransaction(ctx: UploadFileBytesContext, input: CreateFileRefInput): Promise<BeforeTransactionResult<UploadedFileBytes>>;
|
|
26
29
|
export declare function createFileRefFromUploadedBytes(ctx: Pick<CreateFileRefContext, "db" | "user">, uploaded: UploadedFileBytes): Promise<WriteResult<CreatedFileRef>>;
|
|
@@ -8,13 +8,13 @@ import { assertSafeStorageKey } from "./types.js";
|
|
|
8
8
|
// The handler context has no HTTP/job/seed marker to name, so the message states the actual
|
|
9
9
|
// cause: the dispatcher's AppContext carries no file-provider resolver.
|
|
10
10
|
export function filesUnavailableMessage(caller) {
|
|
11
|
-
return `${caller}: ctx.files is unavailable because no file-provider resolver is wired on this dispatcher context. Mount a file-provider-* feature and build the dispatcher context with withFileProviderResolver (HTTP, job and seed dispatchers each need it)`;
|
|
11
|
+
return `${caller}: ctx.services.files is unavailable because no file-provider resolver is wired on this dispatcher context. Mount a file-provider-* feature and build the dispatcher context with withFileProviderResolver (HTTP, job and seed dispatchers each need it)`;
|
|
12
12
|
}
|
|
13
13
|
// Server-side counterpart of POST /files for handlers/jobs that produce bytes
|
|
14
14
|
// themselves (generated PDFs, exports). Same validation, storage layout and
|
|
15
15
|
// fileRef.created event as an upload; the tenant is always ctx.user.tenantId.
|
|
16
16
|
export async function createFileRefFromBytes(ctx, input) {
|
|
17
|
-
const { files } = ctx;
|
|
17
|
+
const { files } = ctx.services;
|
|
18
18
|
if (!files) {
|
|
19
19
|
return writeFailure(new InternalError({
|
|
20
20
|
message: filesUnavailableMessage("createFileRefFromBytes"),
|
|
@@ -59,7 +59,7 @@ function fileRejectedFailure(error) {
|
|
|
59
59
|
// A crash between this phase and the commit leaves the bytes in storage; the upload ledger sweep
|
|
60
60
|
// removes them after its grace period.
|
|
61
61
|
export async function uploadFileBytesBeforeTransaction(ctx, input) {
|
|
62
|
-
const { files } = ctx;
|
|
62
|
+
const { files } = ctx.services;
|
|
63
63
|
if (!files) {
|
|
64
64
|
return writeFailure(new InternalError({
|
|
65
65
|
message: filesUnavailableMessage("uploadFileBytesBeforeTransaction"),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import type { AnyFileFieldDef } from "@cosmicdrift/kumiko-types/fields";
|
|
2
|
+
import type { TenantDb } from "../db/tenant-db.ts";
|
|
3
|
+
import type { Registry, SessionUser } from "../engine/types/index.ts";
|
|
3
4
|
import { type WriteFailure } from "../errors/index.ts";
|
|
4
5
|
export declare const DEFAULT_MAX_UPLOAD_SIZE = "10mb";
|
|
5
6
|
declare function buildFileRefExecutor(): import("@cosmicdrift/kumiko-types/event-store-executor-types").EventStoreExecutor<{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createEventStoreExecutor } from "../db/event-store-executor.js";
|
|
2
|
-
import { runInOwnTransaction } from "../db/tenant-db.js";
|
|
3
|
-
import { isFileField
|
|
2
|
+
import { runInOwnTransaction } from "../db/tenant-db-scoped-rebind.js";
|
|
3
|
+
import { isFileField } from "../engine/field-helpers.js";
|
|
4
4
|
import { InternalError } from "../errors/index.js";
|
|
5
5
|
import { generateId } from "../utils/index.js";
|
|
6
6
|
import { isActionFormScreenQn, resolveActionFormFileField } from "./action-form-upload.js";
|