@cosmicdrift/kumiko-framework 0.389.0 → 0.390.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/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/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 +83 -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 +5 -0
- package/dist/db/row-level-security-boot-check.js +85 -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 +4 -0
- package/dist/schema-cli/shared.js +21 -2
- package/dist/schema-cli/status-command.js +8 -2
- package/dist/schema-cli/validate-command.js +52 -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 +1 -9
- package/dist/upgrade-cli.js +10 -64
- 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 +22 -18
- package/src/changes.json +206 -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
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { InternalError } from "../errors/index.js";
|
|
2
|
+
import { runInNewTransaction, runInSavepointIfSupported } from "./query.js";
|
|
3
|
+
import { tenantDbRunner } from "./tenant-db-runner.js";
|
|
4
|
+
const scopedRebinders = new WeakMap();
|
|
5
|
+
export function registerScopedRebinder(tenantDb, scoped) {
|
|
6
|
+
scopedRebinders.set(tenantDb, scoped);
|
|
7
|
+
}
|
|
8
|
+
function requireScopedRebinder(tenantDb, caller) {
|
|
9
|
+
const scoped = scopedRebinders.get(tenantDb);
|
|
10
|
+
if (!scoped) {
|
|
11
|
+
throw new InternalError({
|
|
12
|
+
message: `${caller} received a TenantDb without a transaction rebinder: either it was not ` +
|
|
13
|
+
"built by createTenantDb, or it is the fail-closed ctx.db/ctx.db.outsideTransaction of an " +
|
|
14
|
+
"r.systemScope() handler (use ctx.systemDb.outsideTransaction there).",
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
return scoped;
|
|
18
|
+
}
|
|
19
|
+
export async function runInOwnTransaction(tenantDb, fn) {
|
|
20
|
+
const scoped = requireScopedRebinder(tenantDb, "runInOwnTransaction");
|
|
21
|
+
if (scoped.memberReadOnly) {
|
|
22
|
+
throw new InternalError({
|
|
23
|
+
message: "runInOwnTransaction: memberReadOnly TenantDb — a fresh transaction would escape " +
|
|
24
|
+
"the enforced read-only scope.",
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return runInNewTransaction(tenantDbRunner(tenantDb), (tx) => fn(scoped.rebind(tx)));
|
|
28
|
+
}
|
|
29
|
+
// A throw inside fn rolls back only fn's statements; the caller's transaction stays usable.
|
|
30
|
+
export async function runInOwnSavepoint(tenantDb, fn) {
|
|
31
|
+
const scoped = requireScopedRebinder(tenantDb, "runInOwnSavepoint");
|
|
32
|
+
return runInSavepointIfSupported(tenantDbRunner(tenantDb), (sp) => fn(scoped.rebind(sp)));
|
|
33
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { EntityTableMeta } from "@cosmicdrift/kumiko-types/entity-table-meta-types";
|
|
2
|
+
import type { Meter, Tracer } from "@cosmicdrift/kumiko-types/observability";
|
|
3
|
+
import type { SchemaTable } from "@cosmicdrift/kumiko-types/schema-table-types";
|
|
4
|
+
import type { TenantId } from "../engine/types/identifiers.ts";
|
|
5
|
+
import { type TenantDbModeOptions } from "./row-level-security-scope.ts";
|
|
6
|
+
export type TenantDbStatementRunnerOptions = {
|
|
7
|
+
readonly tracer?: Tracer | undefined;
|
|
8
|
+
readonly meter?: Meter | undefined;
|
|
9
|
+
readonly signal?: AbortSignal | undefined;
|
|
10
|
+
readonly tenantId: TenantId;
|
|
11
|
+
} & TenantDbModeOptions;
|
|
12
|
+
export type TenantDbOperation = "select" | "insert" | "update" | "delete";
|
|
13
|
+
export declare function createTenantDbStatementRunner({ tracer, meter, signal, mode, reason, tenantId, }: TenantDbStatementRunnerOptions): <T>(operation: TenantDbOperation, table: SchemaTable | EntityTableMeta, runner: () => Promise<T>) => Promise<T>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { emitDbQuery } from "../observability/standard-metrics.js";
|
|
2
|
+
import { runInRowLevelSecurityScope, tenantDbRowLevelSecurityScope, } from "./row-level-security-scope.js";
|
|
3
|
+
import { tableNameOf } from "./table-introspection.js";
|
|
4
|
+
export function createTenantDbStatementRunner({ tracer, meter, signal, mode, reason, tenantId, }) {
|
|
5
|
+
return function withDbSpan(operation, table, runner) {
|
|
6
|
+
signal?.throwIfAborted();
|
|
7
|
+
const scope = tenantDbRowLevelSecurityScope(mode === "system" ? { mode, reason } : { mode }, tenantId, table);
|
|
8
|
+
const scopedRunner = () => runInRowLevelSecurityScope(scope, runner);
|
|
9
|
+
if (!tracer && !meter)
|
|
10
|
+
return scopedRunner();
|
|
11
|
+
const tableName = tableNameOf(table);
|
|
12
|
+
const start = performance.now();
|
|
13
|
+
const emitMetric = () => {
|
|
14
|
+
if (meter) {
|
|
15
|
+
emitDbQuery(meter, { operation, table: tableName }, (performance.now() - start) / 1000);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
if (!tracer) {
|
|
19
|
+
return (async () => {
|
|
20
|
+
try {
|
|
21
|
+
return await scopedRunner();
|
|
22
|
+
}
|
|
23
|
+
finally {
|
|
24
|
+
emitMetric();
|
|
25
|
+
}
|
|
26
|
+
})();
|
|
27
|
+
}
|
|
28
|
+
return tracer.withSpan("db.query", {
|
|
29
|
+
kind: "client",
|
|
30
|
+
attributes: {
|
|
31
|
+
"db.system": "postgresql",
|
|
32
|
+
"db.operation": operation,
|
|
33
|
+
"db.table": tableName,
|
|
34
|
+
},
|
|
35
|
+
}, async (span) => {
|
|
36
|
+
try {
|
|
37
|
+
const result = await scopedRunner();
|
|
38
|
+
if (Array.isArray(result)) {
|
|
39
|
+
span.setAttribute("db.row_count", result.length);
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
emitMetric();
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
}
|
package/dist/db/tenant-db.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { EntityTableMeta } from "@cosmicdrift/kumiko-types/entity-table-meta-types";
|
|
2
2
|
import type { ExecutorManagedRunner } from "@cosmicdrift/kumiko-types/executor-brand";
|
|
3
|
-
import type { EscapeHatchDeclaration, EscapeHatchReporter, EscapeHatchTarget } from "@cosmicdrift/kumiko-types/handlers";
|
|
3
|
+
import type { EscapeHatchDeclaration, EscapeHatchReporter, EscapeHatchTarget, HandlerDb } from "@cosmicdrift/kumiko-types/handlers";
|
|
4
|
+
import type { Meter, Tracer } from "@cosmicdrift/kumiko-types/observability";
|
|
4
5
|
import type { SchemaTable } from "@cosmicdrift/kumiko-types/schema-table-types";
|
|
5
|
-
import { type ExecutorManagedTenantDb, type TenantDb, type
|
|
6
|
+
import { type ExecutorManagedTenantDb, type TenantDb, type UncheckedSystemDb } from "@cosmicdrift/kumiko-types/tenant-db-types";
|
|
6
7
|
import { asRawClient } from "../db/query.ts";
|
|
7
8
|
import type { EntityDefinition } from "../engine/types/fields.ts";
|
|
8
9
|
import { type TenantId } from "../engine/types/identifiers.ts";
|
|
9
10
|
import type { Registry } from "../engine/types/index.ts";
|
|
10
|
-
import { type Meter, type Tracer } from "../observability/index.ts";
|
|
11
11
|
import type { DbRunner } from "./connection.ts";
|
|
12
12
|
import { tableNameOf } from "./table-introspection.ts";
|
|
13
13
|
type Table = SchemaTable;
|
|
@@ -19,10 +19,9 @@ export declare function unsafeRawForDeclaredStep(holder: TenantDb | UncheckedSys
|
|
|
19
19
|
export declare function withSystemDbUnsafeRawGrant<T extends object>(systemDb: T, grant: EscapeHatchDeclaration | undefined, deniedCallerLabel: string): T | UncheckedSystemDb;
|
|
20
20
|
export declare function createUncheckedSystemDb(db: TenantDb, dbOutsideTransaction?: TenantDb, report?: EscapeHatchReporter): UncheckedSystemDb;
|
|
21
21
|
export declare function createSystemDbView(db: TenantDb, dbOutsideTransaction?: TenantDb, report?: EscapeHatchReporter): UncheckedSystemDb;
|
|
22
|
-
export declare function scopeTenantDbToTenant(db: TenantDb, tenantId: TenantId): TenantDb;
|
|
23
22
|
export declare function castTenantRows<T>(rows: readonly Record<string, unknown>[]): readonly T[];
|
|
23
|
+
export { requestedTenantIds } from "./tenant-id-filter.ts";
|
|
24
24
|
export { tableNameOf };
|
|
25
|
-
export declare function requestedTenantIds(requested: unknown): readonly unknown[] | undefined;
|
|
26
25
|
export declare function hasTenantColumn(table: Table | EntityTableMeta): boolean;
|
|
27
26
|
export type TenantDbGrants = {
|
|
28
27
|
readonly globalWrites?: EscapeHatchDeclaration;
|
|
@@ -40,26 +39,32 @@ export declare function acknowledgeConventionCrossTenant(tenantDb: TenantDb, rea
|
|
|
40
39
|
}): TenantDb;
|
|
41
40
|
export declare function reportConventionCrossTenantUse(acknowledged: TenantDb, target?: EscapeHatchTarget): void;
|
|
42
41
|
export type OutsideTransactionContext = {
|
|
43
|
-
readonly
|
|
42
|
+
readonly db: Pick<HandlerDb, "outsideTransaction">;
|
|
44
43
|
};
|
|
45
|
-
export declare function hasOutsideTransactionDb(ctx: OutsideTransactionContext): ctx is
|
|
46
|
-
readonly
|
|
44
|
+
export declare function hasOutsideTransactionDb(ctx: OutsideTransactionContext): ctx is {
|
|
45
|
+
readonly db: {
|
|
46
|
+
readonly outsideTransaction: TenantDb;
|
|
47
|
+
};
|
|
47
48
|
};
|
|
48
49
|
export declare function requireOutsideTransactionDb(ctx: OutsideTransactionContext): TenantDb;
|
|
49
|
-
export declare function runInOwnTransaction<T>(tenantDb: TenantDb, fn: (txDb: TenantDb) => Promise<T>): Promise<T>;
|
|
50
50
|
export type CreateTenantDbOptions = {
|
|
51
51
|
readonly db: DbRunner;
|
|
52
52
|
readonly tenantId: TenantId;
|
|
53
|
-
readonly mode?: TenantDbMode;
|
|
54
53
|
readonly tracer?: Tracer;
|
|
55
54
|
readonly meter?: Meter;
|
|
56
55
|
readonly signal?: AbortSignal;
|
|
57
56
|
readonly grants?: TenantDbGrants;
|
|
58
|
-
}
|
|
57
|
+
} & ({
|
|
58
|
+
readonly mode?: "tenant";
|
|
59
|
+
readonly reason?: undefined;
|
|
60
|
+
} | {
|
|
61
|
+
readonly mode: "system";
|
|
62
|
+
readonly reason: string;
|
|
63
|
+
});
|
|
59
64
|
export declare function createTenantDb(options: CreateTenantDbOptions & {
|
|
60
65
|
readonly db: ExecutorManagedRunner;
|
|
61
66
|
}): ExecutorManagedTenantDb;
|
|
62
67
|
export declare function createTenantDb(options: CreateTenantDbOptions): TenantDb;
|
|
63
|
-
export declare function createTenantDataDestroyDb(options: Omit<CreateTenantDbOptions, "mode">): ExecutorManagedTenantDb;
|
|
68
|
+
export declare function createTenantDataDestroyDb(options: Omit<CreateTenantDbOptions, "mode" | "reason">): ExecutorManagedTenantDb;
|
|
64
69
|
export declare function createProjectingTenantDb(db: DbRunner, tenantId: TenantId, projectionRegistry: Registry | undefined): TenantDb;
|
|
65
70
|
export { asRawClient };
|
package/dist/db/tenant-db.js
CHANGED
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
import { SYSTEM_SCOPE_CHECK_BRAND, } from "@cosmicdrift/kumiko-types/tenant-db-types";
|
|
2
|
-
import {
|
|
3
|
-
import { asEntityTableMeta, asRawClient, aggregateWhere as bunAggregateWhere, countWhere as bunCountWhere, deleteMany as bunDeleteMany, fetchOne as bunFetchOne, insertOne as bunInsertOne, selectMany as bunSelectMany, updateMany as bunUpdateMany, runInNewTransaction, } from "../db/query.js";
|
|
2
|
+
import { asEntityTableMeta, asRawClient, aggregateWhere as bunAggregateWhere, countWhere as bunCountWhere, deleteMany as bunDeleteMany, fetchOne as bunFetchOne, insertOne as bunInsertOne, selectMany as bunSelectMany, updateMany as bunUpdateMany, } from "../db/query.js";
|
|
4
3
|
import { assertReason } from "../engine/escape-hatch-reason.js";
|
|
5
4
|
import { SYSTEM_TENANT_ID } from "../engine/types/identifiers.js";
|
|
6
|
-
import { AccessDeniedError, InternalError
|
|
7
|
-
import {
|
|
5
|
+
import { AccessDeniedError, InternalError } from "../errors/index.js";
|
|
6
|
+
import { memberResolutionReadOnlyDenied } from "../errors/member-resolution.js";
|
|
7
|
+
import { fallbackEscapeHatchReporter } from "../observability/escape-hatch-report.js";
|
|
8
|
+
import { registerStandardMetrics } from "../observability/standard-metrics.js";
|
|
8
9
|
import { assertWritableTable, executorManagedWriteDenied, hasExecutorManagedWriteCapability, registerExecutorManagedWriteRunner, } from "./executor-managed-tables.js";
|
|
9
10
|
import { bindProjectionRegistry, projectionRegistryOf } from "./projection-registry-binding.js";
|
|
10
11
|
import { acquireNamespacedAdvisoryLock } from "./queries/advisory-lock.js";
|
|
11
12
|
import { queryDatabaseNow } from "./queries/database-now.js";
|
|
13
|
+
import { systemModeOptions, unsafeRawScopedRunner, unscopedRunnerOf, } from "./row-level-security-scope.js";
|
|
12
14
|
import { hasFieldProperty, tableNameOf } from "./table-introspection.js";
|
|
13
|
-
import { bindTenantDbRunner, denyTenantDbWrites, tenantDbRunner, tenantDbWritesDeniedError,
|
|
15
|
+
import { bindTenantDbRunner, denyTenantDbWrites, tenantDbRunner, tenantDbWritesDeniedError, } from "./tenant-db-runner.js";
|
|
16
|
+
import { registerScopedRebinder } from "./tenant-db-scoped-rebind.js";
|
|
17
|
+
import { createTenantDbStatementRunner } from "./tenant-db-statement-runner.js";
|
|
14
18
|
import { upsertTableDenied, upsertTenantRow } from "./tenant-db-upsert.js";
|
|
19
|
+
import { isForeignTenantId, requestedTenantIds, tenantIdsAfterExclusion, } from "./tenant-id-filter.js";
|
|
20
|
+
import { registerRunnerProxyTarget } from "./transaction-serialization.js";
|
|
15
21
|
export { SYSTEM_SCOPE_CHECK_BRAND, } from "@cosmicdrift/kumiko-types/tenant-db-types";
|
|
16
22
|
const declaredUnsafeRawRunners = new WeakMap();
|
|
17
23
|
// The CRUD executor writes through tenantDbRunner, not insertOne, so it asks the
|
|
@@ -67,6 +73,7 @@ function boundRunner(runner, gate, projectionRegistry, executorManagedWrites) {
|
|
|
67
73
|
return value.bind(target);
|
|
68
74
|
},
|
|
69
75
|
});
|
|
76
|
+
registerRunnerProxyTarget(proxy, runner);
|
|
70
77
|
if (gate)
|
|
71
78
|
runnerPersonalDataGates.set(proxy, gate);
|
|
72
79
|
if (projectionRegistry)
|
|
@@ -166,9 +173,10 @@ function buildUncheckedSystemDb(db, dbOutsideTransaction, report, gate) {
|
|
|
166
173
|
`${gate.deniedCallerLabel} to allow unsafeRaw.`,
|
|
167
174
|
});
|
|
168
175
|
}
|
|
176
|
+
// A granted unsafeRaw is a declared, audited bypass of the TenantDb filter, so row-level security does not narrow it either.
|
|
169
177
|
// Engine-forwarded steps carry their own declared reason; a caller-supplied one never reaches the audit trail.
|
|
170
178
|
report("unsafe-raw", forwardedDeclaredStep ? reason : (gate?.grant?.reason ?? reason));
|
|
171
|
-
const runner = withoutExecutorManagedWrites(tenantDbRunner(db));
|
|
179
|
+
const runner = unsafeRawScopedRunner(withoutExecutorManagedWrites(tenantDbRunner(db)));
|
|
172
180
|
return boundRunner(runner, personalDataGates.get(db), projectionRegistryOf(db), false);
|
|
173
181
|
}
|
|
174
182
|
const uncheckedSystemDb = {
|
|
@@ -234,10 +242,9 @@ function buildUncheckedSystemDb(db, dbOutsideTransaction, report, gate) {
|
|
|
234
242
|
// own tenantId, never a foreign one.
|
|
235
243
|
//
|
|
236
244
|
// dbOutsideTransaction is optional so every existing single-arg call site
|
|
237
|
-
// (jobs/job-runner.ts, tests) keeps compiling — those callers have no
|
|
238
|
-
//
|
|
239
|
-
//
|
|
240
|
-
// is reachable through `ctx.systemDb`.
|
|
245
|
+
// (jobs/job-runner.ts, tests) keeps compiling — those callers have no outside-tx
|
|
246
|
+
// source to hand in. Only buildHandlerContext passes it, which is also the only
|
|
247
|
+
// place `.outsideTransaction` is reachable through `ctx.systemDb`.
|
|
241
248
|
//
|
|
242
249
|
// Ungated here (the handler's own systemScope() is the grant); a hook's own
|
|
243
250
|
// escapeHatch is layered on afterwards via withSystemDbUnsafeRawGrant. Public
|
|
@@ -252,55 +259,16 @@ export function createUncheckedSystemDb(db, dbOutsideTransaction, report = fallb
|
|
|
252
259
|
export function createSystemDbView(db, dbOutsideTransaction, report = fallbackEscapeHatchReporter(db.tenantId)) {
|
|
253
260
|
return buildUncheckedSystemDb(db, dbOutsideTransaction, report, { kind: "source-tenant-db" });
|
|
254
261
|
}
|
|
255
|
-
// Narrows a (possibly "system"-mode) TenantDb to a "tenant"-mode handle for one tenant on the
|
|
256
|
-
// same connection/transaction. For code that must run caller-supplied callbacks (e.g. config
|
|
257
|
-
// validators) without handing them a cross-tenant view.
|
|
258
|
-
export function scopeTenantDbToTenant(db, tenantId) {
|
|
259
|
-
const writesDeniedReason = tenantDbWritesDeniedReason(db);
|
|
260
|
-
return createTenantDb({
|
|
261
|
-
db: tenantDbRunner(db),
|
|
262
|
-
tenantId,
|
|
263
|
-
mode: "tenant",
|
|
264
|
-
...(writesDeniedReason !== undefined && { grants: { writesDeniedReason } }),
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
262
|
// @cast-boundary tenant-db-row
|
|
268
263
|
export function castTenantRows(rows) {
|
|
269
264
|
return rows;
|
|
270
265
|
}
|
|
266
|
+
export { requestedTenantIds } from "./tenant-id-filter.js";
|
|
271
267
|
export { tableNameOf };
|
|
272
268
|
// A grant is only real when its reason is non-empty — `{ reason: "" }` must not silently unlock it.
|
|
273
269
|
function hasGrant(decl) {
|
|
274
270
|
return decl !== undefined && decl.reason.trim().length > 0;
|
|
275
271
|
}
|
|
276
|
-
// Tenant ids left over when the caller excludes some via ne/notIn; undefined for other operator forms.
|
|
277
|
-
function tenantIdsAfterExclusion(requested, allowed) {
|
|
278
|
-
if (!isPlainObject(requested))
|
|
279
|
-
return undefined;
|
|
280
|
-
if ("ne" in requested)
|
|
281
|
-
return allowed.filter((t) => t !== requested["ne"]);
|
|
282
|
-
if (Array.isArray(requested["notIn"])) {
|
|
283
|
-
const excluded = requested["notIn"];
|
|
284
|
-
return allowed.filter((t) => !excluded.includes(t));
|
|
285
|
-
}
|
|
286
|
-
return undefined;
|
|
287
|
-
}
|
|
288
|
-
// Tenant ids a where.tenantId filter asks for; undefined for operator forms
|
|
289
|
-
// that cannot narrow to a tenant list (ne, like, ...).
|
|
290
|
-
export function requestedTenantIds(requested) {
|
|
291
|
-
if (Array.isArray(requested))
|
|
292
|
-
return requested;
|
|
293
|
-
if (!isPlainObject(requested))
|
|
294
|
-
return [requested];
|
|
295
|
-
if (Array.isArray(requested["in"]))
|
|
296
|
-
return requested["in"];
|
|
297
|
-
if ("eq" in requested)
|
|
298
|
-
return [requested["eq"]];
|
|
299
|
-
return undefined;
|
|
300
|
-
}
|
|
301
|
-
function isForeignTenantId(tenantIdValue) {
|
|
302
|
-
return tenantIdValue !== undefined && tenantIdValue !== SYSTEM_TENANT_ID;
|
|
303
|
-
}
|
|
304
272
|
// Checks the canonical EntityTableMeta (branded EntityTable's KUMIKO_META_SYMBOL
|
|
305
273
|
// or a plain deriveEntityTableMeta/defineUnmanagedTable result), not a direct
|
|
306
274
|
// `table.tenantId` property read — the latter only exists on branded EntityTables
|
|
@@ -347,28 +315,16 @@ export function reportConventionCrossTenantUse(acknowledged, target) {
|
|
|
347
315
|
}
|
|
348
316
|
reporter(target);
|
|
349
317
|
}
|
|
350
|
-
const ownTransactionRebinders = new WeakMap();
|
|
351
318
|
export function hasOutsideTransactionDb(ctx) {
|
|
352
|
-
return ctx.
|
|
319
|
+
return ctx.db.outsideTransaction !== undefined;
|
|
353
320
|
}
|
|
354
321
|
export function requireOutsideTransactionDb(ctx) {
|
|
355
322
|
if (!hasOutsideTransactionDb(ctx)) {
|
|
356
323
|
throw new InternalError({
|
|
357
|
-
message: "ctx.
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
return ctx.dbOutsideTransaction;
|
|
361
|
-
}
|
|
362
|
-
export async function runInOwnTransaction(tenantDb, fn) {
|
|
363
|
-
const rebind = ownTransactionRebinders.get(tenantDb);
|
|
364
|
-
if (!rebind) {
|
|
365
|
-
throw new InternalError({
|
|
366
|
-
message: "runInOwnTransaction received a TenantDb without a transaction rebinder: either it was not " +
|
|
367
|
-
"built by createTenantDb, or it is the fail-closed ctx.db/ctx.dbOutsideTransaction of an " +
|
|
368
|
-
"r.systemScope() handler (use ctx.systemDb.outsideTransaction there).",
|
|
324
|
+
message: "ctx.db.outsideTransaction is not available in this dispatch phase (member-resolution, before-transaction denial) or metering tenant mode.",
|
|
369
325
|
});
|
|
370
326
|
}
|
|
371
|
-
return
|
|
327
|
+
return ctx.db.outsideTransaction;
|
|
372
328
|
}
|
|
373
329
|
export function createTenantDb(options) {
|
|
374
330
|
return buildTenantDb(options);
|
|
@@ -380,7 +336,9 @@ export function createTenantDataDestroyDb(options) {
|
|
|
380
336
|
// Untyped JS callers or an `as` cast can still hand in undefined; a scoped handle
|
|
381
337
|
// without a tenant would bind `tenant_id = NULL` instead of failing loudly.
|
|
382
338
|
function buildTenantDb(options) {
|
|
383
|
-
const { db, tenantId, mode = "tenant", tracer, meter, signal, grants } = options;
|
|
339
|
+
const { db: givenDb, tenantId, mode = "tenant", reason: systemReason, tracer, meter, signal, grants, } = options;
|
|
340
|
+
const modeOptions = mode === "system" ? systemModeOptions(systemReason) : { mode: "tenant" };
|
|
341
|
+
const db = mode === "system" ? givenDb : unscopedRunnerOf(givenDb);
|
|
384
342
|
if (tenantId === undefined) {
|
|
385
343
|
throw new InternalError({ message: "createTenantDb: tenantId is required" });
|
|
386
344
|
}
|
|
@@ -393,47 +351,13 @@ function buildTenantDb(options) {
|
|
|
393
351
|
const rebindGrants = projectionRegistry && grants?.projectionRegistry === undefined
|
|
394
352
|
? { ...grants, projectionRegistry }
|
|
395
353
|
: grants;
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
if (meter) {
|
|
404
|
-
emitDbQuery(meter, { operation, table: tableName }, (performance.now() - start) / 1000);
|
|
405
|
-
}
|
|
406
|
-
};
|
|
407
|
-
if (!tracer) {
|
|
408
|
-
return (async () => {
|
|
409
|
-
try {
|
|
410
|
-
return await runner();
|
|
411
|
-
}
|
|
412
|
-
finally {
|
|
413
|
-
emitMetric();
|
|
414
|
-
}
|
|
415
|
-
})();
|
|
416
|
-
}
|
|
417
|
-
return tracer.withSpan("db.query", {
|
|
418
|
-
kind: "client",
|
|
419
|
-
attributes: {
|
|
420
|
-
"db.system": "postgresql",
|
|
421
|
-
"db.operation": operation,
|
|
422
|
-
"db.table": tableName,
|
|
423
|
-
},
|
|
424
|
-
}, async (span) => {
|
|
425
|
-
try {
|
|
426
|
-
const result = await runner();
|
|
427
|
-
if (Array.isArray(result)) {
|
|
428
|
-
span.setAttribute("db.row_count", result.length);
|
|
429
|
-
}
|
|
430
|
-
return result;
|
|
431
|
-
}
|
|
432
|
-
finally {
|
|
433
|
-
emitMetric();
|
|
434
|
-
}
|
|
435
|
-
});
|
|
436
|
-
}
|
|
354
|
+
const withDbSpan = createTenantDbStatementRunner({
|
|
355
|
+
tracer,
|
|
356
|
+
meter,
|
|
357
|
+
signal,
|
|
358
|
+
...modeOptions,
|
|
359
|
+
tenantId,
|
|
360
|
+
});
|
|
437
361
|
// Reads see own-tenant rows + reference data (tenantId === SYSTEM_TENANT_ID).
|
|
438
362
|
// Writes never touch reference rows — those are system-mode only.
|
|
439
363
|
// A caller-supplied `where.tenantId` may only NARROW the enforced scope
|
|
@@ -613,7 +537,7 @@ function buildTenantDb(options) {
|
|
|
613
537
|
}
|
|
614
538
|
// Engine-forwarded steps carry their own declared reason; otherwise the grant's reason is audited.
|
|
615
539
|
report("unsafe-raw", declaredStepReason ?? grants?.unsafeRaw?.reason ?? "");
|
|
616
|
-
return boundRunner(withoutExecutorManagedWrites(db), personalDataGate, projectionRegistry, false);
|
|
540
|
+
return boundRunner(unsafeRawScopedRunner(withoutExecutorManagedWrites(db)), personalDataGate, projectionRegistry, false);
|
|
617
541
|
}
|
|
618
542
|
const tenantDb = {
|
|
619
543
|
tenantId,
|
|
@@ -712,7 +636,7 @@ function buildTenantDb(options) {
|
|
|
712
636
|
unsafeRawRebinders.set(tenantDb, (grant) => createTenantDb({
|
|
713
637
|
db,
|
|
714
638
|
tenantId,
|
|
715
|
-
|
|
639
|
+
...modeOptions,
|
|
716
640
|
tracer,
|
|
717
641
|
meter,
|
|
718
642
|
signal,
|
|
@@ -730,6 +654,7 @@ function buildTenantDb(options) {
|
|
|
730
654
|
db,
|
|
731
655
|
tenantId,
|
|
732
656
|
mode: "system",
|
|
657
|
+
reason,
|
|
733
658
|
tracer,
|
|
734
659
|
meter,
|
|
735
660
|
signal,
|
|
@@ -738,18 +663,22 @@ function buildTenantDb(options) {
|
|
|
738
663
|
crossTenantUseReporters.set(acknowledged, (target) => report("acknowledge-cross-tenant", reason, target));
|
|
739
664
|
return acknowledged;
|
|
740
665
|
});
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
666
|
+
// Carries a runner-bound gate (grants.personalDataGate unset, resolved via the fallback above) forward explicitly, since a fresh tx-handle isn't itself registered in runnerPersonalDataGates.
|
|
667
|
+
const scopedGrants = personalDataGate ? { ...rebindGrants, personalDataGate } : rebindGrants;
|
|
668
|
+
registerScopedRebinder(tenantDb, {
|
|
669
|
+
memberReadOnly: grants?.memberReadOnly === true,
|
|
670
|
+
rebind: (runner) => createTenantDb({
|
|
671
|
+
db: runner,
|
|
672
|
+
tenantId,
|
|
673
|
+
...modeOptions,
|
|
674
|
+
tracer,
|
|
675
|
+
meter,
|
|
676
|
+
signal,
|
|
677
|
+
grants: scopedGrants,
|
|
678
|
+
}),
|
|
751
679
|
});
|
|
752
|
-
|
|
680
|
+
// Framework code reading through the raw runner (executor list/detail) must follow the db's own mode, not the ambient scope.
|
|
681
|
+
bindTenantDbRunner(tenantDb, db, modeOptions, tenantId);
|
|
753
682
|
if (grants?.writesDeniedReason !== undefined) {
|
|
754
683
|
denyTenantDbWrites(tenantDb, grants.writesDeniedReason);
|
|
755
684
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function tenantIdsAfterExclusion(requested: unknown, allowed: readonly unknown[]): readonly unknown[] | undefined;
|
|
2
|
+
export declare function requestedTenantIds(requested: unknown): readonly unknown[] | undefined;
|
|
3
|
+
export declare function isForeignTenantId(tenantIdValue: unknown): boolean;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { isPlainObject } from "@cosmicdrift/kumiko-types/type-guards";
|
|
2
|
+
import { SYSTEM_TENANT_ID } from "../engine/types/identifiers.js";
|
|
3
|
+
// Tenant ids left over when the caller excludes some via ne/notIn; undefined for other operator forms.
|
|
4
|
+
export function tenantIdsAfterExclusion(requested, allowed) {
|
|
5
|
+
if (!isPlainObject(requested))
|
|
6
|
+
return undefined;
|
|
7
|
+
if ("ne" in requested)
|
|
8
|
+
return allowed.filter((t) => t !== requested["ne"]);
|
|
9
|
+
if (Array.isArray(requested["notIn"])) {
|
|
10
|
+
const excluded = requested["notIn"];
|
|
11
|
+
return allowed.filter((t) => !excluded.includes(t));
|
|
12
|
+
}
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
// Tenant ids a where.tenantId filter asks for; undefined for operator forms
|
|
16
|
+
// that cannot narrow to a tenant list (ne, like, ...).
|
|
17
|
+
export function requestedTenantIds(requested) {
|
|
18
|
+
if (Array.isArray(requested))
|
|
19
|
+
return requested;
|
|
20
|
+
if (!isPlainObject(requested))
|
|
21
|
+
return [requested];
|
|
22
|
+
if (Array.isArray(requested["in"]))
|
|
23
|
+
return requested["in"];
|
|
24
|
+
if ("eq" in requested)
|
|
25
|
+
return [requested["eq"]];
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
export function isForeignTenantId(tenantIdValue) {
|
|
29
|
+
return tenantIdValue !== undefined && tenantIdValue !== SYSTEM_TENANT_ID;
|
|
30
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type HandleKey = object;
|
|
2
|
+
export declare function registerRunnerProxyTarget(proxy: HandleKey, target: HandleKey): void;
|
|
3
|
+
export declare function openSerializedSavepoint<T>(transactionHandle: HandleKey & {
|
|
4
|
+
savepoint: <R>(fn: (sp: unknown) => Promise<R>) => Promise<R>;
|
|
5
|
+
}, fn: (sp: unknown) => Promise<T>): Promise<T>;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
const runnerProxyTargets = new WeakMap();
|
|
3
|
+
const savepointTransactionKeys = new WeakMap();
|
|
4
|
+
const rootChains = new WeakMap();
|
|
5
|
+
const nestedChainsInScope = new AsyncLocalStorage();
|
|
6
|
+
function isHandleKey(value) {
|
|
7
|
+
return typeof value === "function" || (typeof value === "object" && value !== null);
|
|
8
|
+
}
|
|
9
|
+
export function registerRunnerProxyTarget(proxy, target) {
|
|
10
|
+
runnerProxyTargets.set(proxy, target);
|
|
11
|
+
}
|
|
12
|
+
function driverHandleOf(handle) {
|
|
13
|
+
let current = handle;
|
|
14
|
+
let target = runnerProxyTargets.get(current);
|
|
15
|
+
while (target) {
|
|
16
|
+
current = target;
|
|
17
|
+
target = runnerProxyTargets.get(current);
|
|
18
|
+
}
|
|
19
|
+
return current;
|
|
20
|
+
}
|
|
21
|
+
function transactionKeyOf(handle) {
|
|
22
|
+
const driverHandle = driverHandleOf(handle);
|
|
23
|
+
return savepointTransactionKeys.get(driverHandle) ?? driverHandle;
|
|
24
|
+
}
|
|
25
|
+
function chainFor(transactionKey) {
|
|
26
|
+
const nested = nestedChainsInScope.getStore()?.get(transactionKey);
|
|
27
|
+
if (nested)
|
|
28
|
+
return nested;
|
|
29
|
+
const root = rootChains.get(transactionKey);
|
|
30
|
+
if (root)
|
|
31
|
+
return root;
|
|
32
|
+
const created = { tail: Promise.resolve() };
|
|
33
|
+
rootChains.set(transactionKey, created);
|
|
34
|
+
return created;
|
|
35
|
+
}
|
|
36
|
+
async function runOnChain(transactionKey, work) {
|
|
37
|
+
const chain = chainFor(transactionKey);
|
|
38
|
+
const previous = chain.tail;
|
|
39
|
+
let release = () => { };
|
|
40
|
+
chain.tail = new Promise((resolve) => {
|
|
41
|
+
release = resolve;
|
|
42
|
+
});
|
|
43
|
+
await previous;
|
|
44
|
+
try {
|
|
45
|
+
const scope = new Map(nestedChainsInScope.getStore());
|
|
46
|
+
scope.set(transactionKey, { tail: Promise.resolve() });
|
|
47
|
+
return await nestedChainsInScope.run(scope, work);
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
release();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export function openSerializedSavepoint(transactionHandle, fn) {
|
|
54
|
+
const transactionKey = transactionKeyOf(transactionHandle);
|
|
55
|
+
return runOnChain(transactionKey, () => transactionHandle.savepoint((sp) => {
|
|
56
|
+
if (isHandleKey(sp))
|
|
57
|
+
savepointTransactionKeys.set(driverHandleOf(sp), transactionKey);
|
|
58
|
+
return fn(sp);
|
|
59
|
+
}));
|
|
60
|
+
}
|
|
@@ -72,7 +72,7 @@ export async function deleteStoredFileAndDerivatives(originalKey, store, errorCo
|
|
|
72
72
|
}
|
|
73
73
|
return failedKeys;
|
|
74
74
|
}
|
|
75
|
-
// deleteStoredFileAndDerivatives through ctx.files for a key read from a tenant-filtered fileRef
|
|
75
|
+
// deleteStoredFileAndDerivatives through ctx.services.files for a key read from a tenant-filtered fileRef
|
|
76
76
|
// row. After a tenant handover the key keeps the previous tenant's prefix, which ref() and list()
|
|
77
77
|
// reject; every key the helper deletes is the original or one of its derivatives.
|
|
78
78
|
export function deleteFileRefBytes(files, row, errorContext) {
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
export { deleteFileRefBytes, deleteStoredFileAndDerivatives, listDerivativeKeys, } from "./delete-stored-file.ts";
|
|
3
|
-
export type { DerivativesContextDeps } from "./derivatives-context.ts";
|
|
4
|
-
export { createDerivativesContext, resolveRenderer } from "./derivatives-context.ts";
|
|
1
|
+
export { deleteFileRefBytes, deleteStoredFileAndDerivatives, } from "./delete-stored-file.ts";
|
|
5
2
|
export { resolveFieldVariant } from "./field-variants.ts";
|
|
6
|
-
export {
|
|
3
|
+
export { derivativeListPrefix, parseDerivativeKey, variantSuffix, } from "./variant-key.ts";
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export { deleteFileRefBytes, deleteStoredFileAndDerivatives,
|
|
2
|
-
export { createDerivativesContext, resolveRenderer } from "./derivatives-context.js";
|
|
1
|
+
export { deleteFileRefBytes, deleteStoredFileAndDerivatives, } from "./delete-stored-file.js";
|
|
3
2
|
export { resolveFieldVariant } from "./field-variants.js";
|
|
4
|
-
export {
|
|
3
|
+
export { derivativeListPrefix, parseDerivativeKey, variantSuffix, } from "./variant-key.js";
|
package/dist/engine/access.d.ts
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
import type { AccessRule
|
|
1
|
+
import type { AccessRule } from "@cosmicdrift/kumiko-types/handlers";
|
|
2
|
+
import type { SessionUser } from "./types/index.ts";
|
|
2
3
|
export declare function hasAccess(user: Pick<SessionUser, "roles">, access: AccessRule | undefined): boolean;
|
package/dist/engine/access.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { isOpenToAllGranted } from "@cosmicdrift/kumiko-types/handlers";
|
|
1
2
|
import { ANONYMOUS_ROLE } from "./system-user.js";
|
|
2
|
-
import { isOpenToAllGranted } from "./types/index.js";
|
|
3
3
|
// Default-deny: a handler without an explicit AccessRule is unreachable. To
|
|
4
4
|
// grant access a handler must either list allowed roles or opt into
|
|
5
5
|
// openToAll. Leaving access undefined now returns false (previously true) —
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { QueryHandlerDef } from "@cosmicdrift/kumiko-types/handlers";
|
|
2
|
+
import type { FeatureDefinition } from "../types/index.ts";
|
|
2
3
|
export declare const FILE_FIELD_TYPES: Set<string>;
|
|
3
4
|
export declare const PII_DIRECT_NAME_HINTS: ReadonlySet<string>;
|
|
4
5
|
export declare const PII_USER_OWNED_NAME_HINTS: ReadonlySet<string>;
|
|
@@ -209,7 +209,7 @@ export function validatePerCommandTransaction(featureName, handlerName, handler)
|
|
|
209
209
|
const conflicting = perCommandConflict(handler);
|
|
210
210
|
if (conflicting !== undefined) {
|
|
211
211
|
throw new Error(`write handler "${featureName}:write:${handlerName}" declares transaction: "perCommand" together with ${conflicting} — ` +
|
|
212
|
-
"a perCommand handler holds no transaction, so move the phase into the commands it issues via ctx.write.");
|
|
212
|
+
"a perCommand handler holds no transaction, so move the phase into the commands it issues via ctx.dispatch.write.");
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
215
|
const IP_SCOPED_RATE_LIMIT_PER = ["ip", "ip+handler"];
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { EntityDefinition } from "
|
|
1
|
+
import type { EntityDefinition } from "@cosmicdrift/kumiko-types/fields";
|
|
2
2
|
import type { EntityListScreenDefinition } from "../types/screen.ts";
|
|
3
3
|
export declare function validateEntityListAggregateOptions(where: string, screen: EntityListScreenDefinition, entity: EntityDefinition): void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { EntityDefinition, FieldDefinition } from "
|
|
1
|
+
import type { EntityDefinition, FieldDefinition } from "@cosmicdrift/kumiko-types/fields";
|
|
2
2
|
import { type ListColumnSpec, type ListTableGrouping, type ListTableTotal } from "../types/screen.ts";
|
|
3
3
|
type FieldType = FieldDefinition["type"];
|
|
4
4
|
export type AggregateFieldInfo = {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { QueryHandlerDef } from "@cosmicdrift/kumiko-types/handlers";
|
|
2
|
+
import type { FeatureDefinition } from "../types/index.ts";
|
|
2
3
|
import type { ListColumnSpec, ListTableOptions } from "../types/screen.ts";
|
|
3
4
|
export declare function validateListTableAggregateQuery(args: {
|
|
4
5
|
readonly prefix: string;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { NavDefinition } from "@cosmicdrift/kumiko-types/nav";
|
|
2
|
+
import type { WorkspaceDefinition } from "@cosmicdrift/kumiko-types/workspace";
|
|
3
|
+
import type { FeatureDefinition } from "../types/index.ts";
|
|
2
4
|
export declare function collectWriteHandlerQns(features: readonly FeatureDefinition[]): Set<string>;
|
|
3
5
|
export declare function collectNavQns(features: readonly FeatureDefinition[]): Map<string, NavDefinition & {
|
|
4
6
|
readonly featureName: string;
|