@cosmicdrift/kumiko-framework 0.388.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 +12 -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/golden-path.md +13 -1
- 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 +55 -2
- package/agents/examples/list-table-options.md +466 -0
- package/agents/examples/managed-config.md +4 -4
- package/agents/examples/managed-pages.md +1 -1
- package/agents/examples/pdf-audit-export.md +4 -2
- 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 +5 -4
- package/agents/examples/tenant-isolation.md +73 -1
- 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 +5 -4
- package/agents/features.md +1 -1
- package/agents/widgets.md +1 -0
- package/dist/api/api-constants.d.ts +1 -0
- package/dist/api/api-constants.js +2 -0
- package/dist/api/auth-middleware.js +1 -1
- package/dist/api/auth-routes-invite.js +2 -1
- package/dist/api/auth-routes-shared.d.ts +2 -0
- package/dist/api/auth-routes-shared.js +5 -0
- package/dist/api/client-error-route.js +2 -3
- package/dist/api/entity-read-access.d.ts +4 -1
- package/dist/api/entity-read-access.js +14 -0
- package/dist/api/export/export-cells-reference.d.ts +9 -0
- package/dist/api/export/export-cells-reference.js +21 -0
- package/dist/api/export/export-cells.d.ts +11 -0
- package/dist/api/export/export-cells.js +136 -0
- package/dist/api/export/export-ciphertext-guard.d.ts +2 -0
- package/dist/api/export/export-ciphertext-guard.js +27 -0
- package/dist/api/export/export-columns.d.ts +31 -0
- package/dist/api/export/export-columns.js +85 -0
- package/dist/api/export/export-errors.d.ts +4 -0
- package/dist/api/export/export-errors.js +14 -0
- package/dist/api/export/export-route.d.ts +4 -0
- package/dist/api/export/export-route.js +75 -0
- package/dist/api/export/export-rows.d.ts +13 -0
- package/dist/api/export/export-rows.js +62 -0
- package/dist/api/export/export-screen.d.ts +13 -0
- package/dist/api/export/export-screen.js +47 -0
- package/dist/api/export/export-xlsx-writer.d.ts +4 -0
- package/dist/api/export/export-xlsx-writer.js +21 -0
- package/dist/api/extra-route.d.ts +7 -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/pii-leak-guard.d.ts +3 -0
- package/dist/api/pii-leak-guard.js +3 -2
- 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.d.ts +16 -0
- package/dist/api/routes.js +9 -5
- 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 +5 -1
- package/dist/api/server-middleware.js +3 -1
- package/dist/api/server-routes.d.ts +3 -2
- package/dist/api/server-routes.js +8 -2
- package/dist/api/server-wiring.js +8 -4
- package/dist/api/server.d.ts +2 -1
- package/dist/api/sse-route.d.ts +3 -1
- package/dist/api/sse-route.js +11 -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 +11 -9
- 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.d.ts +1 -0
- package/dist/crypto/pg-kms-adapter.js +17 -18
- package/dist/db/aggregate-sql.d.ts +2 -0
- package/dist/db/aggregate-sql.js +10 -0
- 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/closed-connection.js +12 -19
- 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 +7 -6
- package/dist/db/connection.js +43 -24
- 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-row-coercion.js +4 -4
- package/dist/db/driver-value-preparation.js +6 -4
- 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-aggregate-currencies.d.ts +17 -0
- package/dist/db/event-store-executor-read-aggregate-currencies.js +40 -0
- package/dist/db/event-store-executor-read-aggregate.js +36 -5
- package/dist/db/event-store-executor-read-filter.d.ts +1 -1
- package/dist/db/event-store-executor-read-filter.js +6 -3
- 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.d.ts +4 -0
- package/dist/db/event-store-executor-write-atomic.js +42 -0
- package/dist/db/event-store-executor-write-steps.d.ts +3 -5
- package/dist/db/event-store-executor-write-steps.js +0 -5
- package/dist/db/event-store-executor-write.js +22 -19
- package/dist/db/event-store-executor.d.ts +1 -1
- package/dist/db/event-store-executor.js +2 -1
- package/dist/db/executor-managed-tables.d.ts +7 -1
- package/dist/db/executor-managed-tables.js +12 -3
- 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 +7 -3
- 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 +37 -21
- package/dist/db/queries/backfill-pii.js +3 -6
- package/dist/db/queries/database-now.js +2 -1
- 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 +11 -28
- package/dist/db/queries/test-stack.d.ts +4 -1
- package/dist/db/queries/test-stack.js +83 -2
- package/dist/db/query.d.ts +14 -0
- package/dist/db/query.js +77 -48
- package/dist/db/reference-data.d.ts +1 -1
- package/dist/db/reference-data.js +20 -3
- 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/statement-timeout.js +2 -1
- 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-upsert.d.ts +5 -0
- package/dist/db/tenant-db-upsert.js +91 -0
- package/dist/db/tenant-db.d.ts +17 -12
- package/dist/db/tenant-db.js +60 -121
- 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/bundled-lists-table.d.ts +2 -0
- package/dist/engine/boot-validator/bundled-lists-table.js +36 -0
- 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 +3 -0
- package/dist/engine/boot-validator/entity-list-aggregate-options.js +23 -0
- package/dist/engine/boot-validator/list-bulk-actions.d.ts +3 -0
- package/dist/engine/boot-validator/list-bulk-actions.js +49 -0
- package/dist/engine/boot-validator/list-column-layout.d.ts +8 -0
- package/dist/engine/boot-validator/list-column-layout.js +41 -0
- package/dist/engine/boot-validator/list-table-aggregate-options.d.ts +24 -0
- package/dist/engine/boot-validator/list-table-aggregate-options.js +145 -0
- package/dist/engine/boot-validator/list-table-aggregate-query.d.ts +11 -0
- package/dist/engine/boot-validator/list-table-aggregate-query.js +31 -0
- package/dist/engine/boot-validator/list-table-export-options.d.ts +1 -0
- package/dist/engine/boot-validator/list-table-export-options.js +27 -0
- package/dist/engine/boot-validator/list-table-options.d.ts +3 -0
- package/dist/engine/boot-validator/list-table-options.js +77 -0
- package/dist/engine/boot-validator/list-table-reject-unknown-keys.d.ts +1 -0
- package/dist/engine/boot-validator/list-table-reject-unknown-keys.js +7 -0
- 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/projection-list-screens.js +3 -13
- package/dist/engine/boot-validator/query-refs.d.ts +2 -1
- package/dist/engine/boot-validator/related-list-table-rules.d.ts +4 -0
- package/dist/engine/boot-validator/related-list-table-rules.js +42 -0
- package/dist/engine/boot-validator/screens-forms.d.ts +2 -1
- package/dist/engine/boot-validator/screens-kind-entity-list.js +7 -0
- package/dist/engine/boot-validator/screens-kind-projection-list.js +4 -0
- package/dist/engine/boot-validator/screens-kind-shared.d.ts +3 -1
- package/dist/engine/boot-validator/screens-lists.js +12 -2
- 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/build-app-schema.d.ts +2 -1
- package/dist/engine/build-app-schema.js +9 -1
- package/dist/engine/build-config-feature-schema.js +6 -1
- 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 +5 -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 +9 -1
- package/dist/engine/feature-builder-state.js +1 -0
- 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.d.ts +1 -0
- package/dist/engine/feature-manifest.js +2 -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 +3 -1
- package/dist/engine/field-access.js +12 -0
- package/dist/engine/handler-field-references.d.ts +0 -4
- package/dist/engine/index.d.ts +58 -55
- package/dist/engine/index.js +23 -28
- 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 +2 -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/strip-disabled-features-from-app-schema.js +7 -3
- package/dist/engine/template-variables.d.ts +2 -1
- package/dist/engine/transfer-adjacency.d.ts +1 -1
- package/dist/engine/types/feature.d.ts +1 -0
- package/dist/engine/types/index.d.ts +8 -30
- package/dist/engine/types/index.js +2 -10
- package/dist/engine/types/screen.d.ts +1 -1
- package/dist/engine/types/screen.js +1 -1
- package/dist/engine/validation.d.ts +2 -1
- package/dist/entrypoint/index.d.ts +9 -35
- package/dist/entrypoint/index.js +10 -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.d.ts +1 -0
- package/dist/event-store/event-store.js +42 -32
- 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/provenance-append.js +1 -1
- 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 +6 -3
- package/dist/files/create-file-ref.d.ts +6 -2
- package/dist/files/create-file-ref.js +13 -4
- 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 +3 -1
- package/dist/files/file-routes.js +41 -4
- 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 +6 -4
- package/dist/files/provider-resolver.js +5 -5
- package/dist/files/record-write-check.d.ts +6 -0
- package/dist/files/record-write-check.js +13 -0
- 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/files/upload-ledger.d.ts +2 -2
- package/dist/files/upload-ledger.js +4 -4
- 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/i18n/required-surface-keys.js +7 -2
- 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 +10 -6
- 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-scope.js +6 -6
- package/dist/jobs/job-runner-types.d.ts +2 -1
- package/dist/jobs/job-runner.js +22 -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/escape-hatch-report.js +9 -2
- 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/after-rollback-sink.d.ts +6 -0
- package/dist/pipeline/after-rollback-sink.js +32 -0
- 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 +39 -19
- 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 -194
- 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 +7 -3
- package/dist/pipeline/event-dispatcher.d.ts +3 -2
- package/dist/pipeline/event-dispatcher.js +13 -12
- 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 +14 -6
- package/dist/pipeline/handler-context-dispatch.js +18 -5
- package/dist/pipeline/handler-context-events.d.ts +22 -38
- package/dist/pipeline/handler-context-events.js +42 -35
- 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 +6 -2
- package/dist/pipeline/system-hooks.js +61 -10
- 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/pipeline/write-result-masking.js +13 -10
- 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 +107 -91
- 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 -0
- package/dist/upgrade-changelog.js +18 -0
- package/dist/upgrade-cli-internals.d.ts +8 -0
- package/dist/upgrade-cli-internals.js +63 -0
- package/dist/upgrade-cli.d.ts +1 -18
- package/dist/upgrade-cli.js +29 -137
- package/dist/upgrade-marker-parse.d.ts +32 -0
- package/dist/upgrade-marker-parse.js +73 -0
- 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 +27 -20
- package/src/changes.json +451 -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 -10
- package/dist/engine/feature-ast/extractors/round1.js +0 -81
- 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 -483
- package/dist/engine/feature-ast/patch.d.ts +0 -210
- package/dist/engine/feature-ast/patch.js +0 -610
- 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 -1476
- package/dist/engine/feature-ast/pattern-change-schema.js +0 -1226
- package/dist/engine/feature-ast/pattern-id-matchers.d.ts +0 -7
- package/dist/engine/feature-ast/pattern-id-matchers.js +0 -210
- package/dist/engine/feature-ast/patterns.d.ts +0 -318
- package/dist/engine/feature-ast/patterns.js +0 -106
- package/dist/engine/feature-ast/render.d.ts +0 -47
- package/dist/engine/feature-ast/render.js +0 -662
- 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 -93
- 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 -20
- package/dist/engine/pattern-library/static-schemas.js +0 -478
- package/dist/engine/pattern-library/types.d.ts +0 -158
- package/dist/engine/pattern-library/types.js +0 -36
- package/dist/engine/provider-plugin-context.d.ts +0 -3
- package/dist/engine/provider-plugin-context.js +0 -28
- 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
|
@@ -38,7 +38,12 @@ bun test
|
|
|
38
38
|
|
|
39
39
|
import { afterAll, beforeAll, beforeEach, describe, expect, test } from "bun:test";
|
|
40
40
|
import { createTenantDb } from "@cosmicdrift/kumiko-framework/db";
|
|
41
|
-
import
|
|
41
|
+
import {
|
|
42
|
+
attachOutsideTransaction,
|
|
43
|
+
bridgeStub,
|
|
44
|
+
type HandlerContext,
|
|
45
|
+
type SaveContext,
|
|
46
|
+
} from "@cosmicdrift/kumiko-framework/engine";
|
|
42
47
|
import { createEventsTable } from "@cosmicdrift/kumiko-framework/event-store";
|
|
43
48
|
import { createCascadeDeleteHook } from "@cosmicdrift/kumiko-framework/pipeline";
|
|
44
49
|
import { TestUsers } from "@cosmicdrift/kumiko-framework/seeding";
|
|
@@ -77,6 +82,16 @@ beforeEach(() => {
|
|
|
77
82
|
stack.events.reset();
|
|
78
83
|
});
|
|
79
84
|
|
|
85
|
+
// The cascade hook runs against the same tenant-scoped db a dispatcher would hand it.
|
|
86
|
+
function hookContext(): HandlerContext {
|
|
87
|
+
const db = createTenantDb({ db: stack.db, tenantId: admin.tenantId });
|
|
88
|
+
return {
|
|
89
|
+
...bridgeStub({ user: admin }),
|
|
90
|
+
registry: stack.registry,
|
|
91
|
+
db: attachOutsideTransaction(db, undefined),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
80
95
|
describe("restrict: team cannot be deleted with members", () => {
|
|
81
96
|
test("delete team with members fails", async () => {
|
|
82
97
|
const team = await stack.http.writeOk<SaveContext>(
|
|
@@ -105,7 +120,7 @@ describe("restrict: team cannot be deleted with members", () => {
|
|
|
105
120
|
entityName: "team",
|
|
106
121
|
event: createTestStoredEvent(),
|
|
107
122
|
},
|
|
108
|
-
|
|
123
|
+
hookContext(),
|
|
109
124
|
),
|
|
110
125
|
).rejects.toMatchObject({ code: "conflict", details: { reason: "delete_restricted" } });
|
|
111
126
|
});
|
|
@@ -128,7 +143,7 @@ describe("restrict: team cannot be deleted with members", () => {
|
|
|
128
143
|
entityName: "team",
|
|
129
144
|
event: createTestStoredEvent(),
|
|
130
145
|
},
|
|
131
|
-
|
|
146
|
+
hookContext(),
|
|
132
147
|
),
|
|
133
148
|
).resolves.toBeUndefined();
|
|
134
149
|
});
|
|
@@ -178,7 +193,7 @@ describe("cascade: deleting member removes tasks", () => {
|
|
|
178
193
|
entityName: "member",
|
|
179
194
|
event: createTestStoredEvent(),
|
|
180
195
|
},
|
|
181
|
-
|
|
196
|
+
hookContext(),
|
|
182
197
|
);
|
|
183
198
|
|
|
184
199
|
// Tasks should be gone
|
|
@@ -13,7 +13,7 @@ Tenant-scoped full-text search (Meilisearch / in-memory adapter).
|
|
|
13
13
|
## What it shows
|
|
14
14
|
|
|
15
15
|
- `searchable` / `searchWeight` on fields
|
|
16
|
-
- Handler reads via `ctx.searchAdapter`
|
|
16
|
+
- Handler reads via `ctx.services.searchAdapter`
|
|
17
17
|
|
|
18
18
|
## Source
|
|
19
19
|
|
|
@@ -160,7 +160,7 @@ describe("search indexing", () => {
|
|
|
160
160
|
```ts
|
|
161
161
|
// Search Sample
|
|
162
162
|
// Shows: searchable fields, searchWeight, search via InMemory SearchAdapter.
|
|
163
|
-
// Each handler builds its executor inline so `ctx.searchAdapter` is read fresh
|
|
163
|
+
// Each handler builds its executor inline so `ctx.services.searchAdapter` is read fresh
|
|
164
164
|
// per call — tests swap the adapter between runs.
|
|
165
165
|
|
|
166
166
|
import { buildEntityTable, createEventStoreExecutor } from "@cosmicdrift/kumiko-framework/db";
|
|
@@ -198,7 +198,7 @@ export const productFeature = defineFeature("shop", (r) => {
|
|
|
198
198
|
}),
|
|
199
199
|
handler: async (event, ctx) => {
|
|
200
200
|
const crud = createEventStoreExecutor(productTable, productEntity, {
|
|
201
|
-
searchAdapter: ctx.searchAdapter,
|
|
201
|
+
searchAdapter: ctx.services.searchAdapter,
|
|
202
202
|
entityName: "product",
|
|
203
203
|
});
|
|
204
204
|
return crud.create(event.payload, event.user, ctx.db);
|
|
@@ -214,7 +214,7 @@ export const productFeature = defineFeature("shop", (r) => {
|
|
|
214
214
|
}),
|
|
215
215
|
handler: async (query, ctx) => {
|
|
216
216
|
const crud = createEventStoreExecutor(productTable, productEntity, {
|
|
217
|
-
searchAdapter: ctx.searchAdapter,
|
|
217
|
+
searchAdapter: ctx.services.searchAdapter,
|
|
218
218
|
entityName: "product",
|
|
219
219
|
});
|
|
220
220
|
return crud.list(query.payload, query.user, ctx.db);
|
|
@@ -12,7 +12,7 @@ Tenant-owned secrets with envelope encryption, DEK cache, and KEK rotation.
|
|
|
12
12
|
|
|
13
13
|
## What it shows
|
|
14
14
|
|
|
15
|
-
- `r.secret` + `ctx.secrets.get` (audited reads)
|
|
15
|
+
- `r.secret` + `ctx.services.secrets.get` (audited reads)
|
|
16
16
|
- Charge-style handler that never returns the plaintext key
|
|
17
17
|
|
|
18
18
|
## Source
|
|
@@ -39,7 +39,7 @@ bun test
|
|
|
39
39
|
// function calls into framework internals):
|
|
40
40
|
// 1. A TenantAdmin sets a secret over HTTP → DB holds only an envelope.
|
|
41
41
|
// 2. list handler returns a redacted preview, never plaintext.
|
|
42
|
-
// 3. Feature code (ctx.secrets.get) decrypts through the audited wrapper.
|
|
42
|
+
// 3. Feature code (ctx.services.secrets.get) decrypts through the audited wrapper.
|
|
43
43
|
// Every read writes a tenantSecretRead event to the events-table.
|
|
44
44
|
// 4. The response-guard catches accidental Secret<> leaks: a handler
|
|
45
45
|
// that tries to return the branded value triggers a 500 at the
|
|
@@ -129,7 +129,7 @@ beforeAll(async () => {
|
|
|
129
129
|
features: [createJobsFeature(), createSecretsFeature(), createBillingFeature(), leakyFeature],
|
|
130
130
|
// Typed masterKeyProvider option: lands in AppContext as a typed field,
|
|
131
131
|
// no Record<string, unknown>-via-extraContext. The rotation job reads
|
|
132
|
-
// it from ctx.masterKeyProvider directly.
|
|
132
|
+
// it from ctx.services.masterKeyProvider directly.
|
|
133
133
|
masterKeyProvider: providerRef,
|
|
134
134
|
extraContext: ({ db, registry }) => ({
|
|
135
135
|
// SecretsContext sees the mutable ref — any replace() flips what
|
|
@@ -299,7 +299,7 @@ describe("5. KEK rotation via the core job + real BullMQ dispatch", () => {
|
|
|
299
299
|
|
|
300
300
|
test("subsequent ctx.secrets.get after rotation still returns the original plaintext", async () => {
|
|
301
301
|
// Goes through the whole real stack: HTTP → dispatcher → billing
|
|
302
|
-
// handler → ctx.secrets.get → cached DEK-unwrap with V2 → decrypt.
|
|
302
|
+
// handler → ctx.services.secrets.get → cached DEK-unwrap with V2 → decrypt.
|
|
303
303
|
// If rotation broke anything, fingerprint would differ or the call
|
|
304
304
|
// would throw.
|
|
305
305
|
const result = await stack.http.writeOk<{ keyFingerprint: string }>(
|
|
@@ -328,7 +328,7 @@ describe("5. KEK rotation via the core job + real BullMQ dispatch", () => {
|
|
|
328
328
|
### src/feature.ts
|
|
329
329
|
|
|
330
330
|
```ts
|
|
331
|
-
// A miniature "billing" feature that reads a Stripe API key from ctx.secrets
|
|
331
|
+
// A miniature "billing" feature that reads a Stripe API key from ctx.services.secrets
|
|
332
332
|
// and simulates a charge. The point is to show how feature code uses the
|
|
333
333
|
// plaintext secret without ever exposing it to clients — the charge endpoint
|
|
334
334
|
// returns { chargeId } but never the apiKey.
|
|
@@ -357,7 +357,10 @@ const chargeWrite = defineWriteHandler({
|
|
|
357
357
|
}),
|
|
358
358
|
access: { roles: ["TenantAdmin", "User"] },
|
|
359
359
|
handler: async (event, ctx) => {
|
|
360
|
-
const secrets = requireSecretsContext(
|
|
360
|
+
const secrets = requireSecretsContext(
|
|
361
|
+
{ secrets: ctx.services.secrets, user: ctx.user },
|
|
362
|
+
"billing:write:charge",
|
|
363
|
+
);
|
|
361
364
|
// requireSecretsContext returned a wrapper that auto-fills the audit
|
|
362
365
|
// context (userId + "billing:write:charge") on every .get — the read
|
|
363
366
|
// lands in tenant_secret_reads without the handler having to remember.
|
|
@@ -492,6 +492,7 @@ export const invoiceTable = buildEntityTable("invoice", invoiceEntity);
|
|
|
492
492
|
|
|
493
493
|
import type { EventDef } from "@cosmicdrift/kumiko-framework/engine";
|
|
494
494
|
import { z } from "zod";
|
|
495
|
+
import { INVOICE_STATES } from "./entities/invoice.ts";
|
|
495
496
|
|
|
496
497
|
export const FEATURE_NAME = "billing";
|
|
497
498
|
export const ENTITY_NAME = "invoice";
|
|
@@ -509,7 +510,7 @@ export const INVOICE_EVENTS = {
|
|
|
509
510
|
// Qualifier used by the reducer to match events from the stream.
|
|
510
511
|
// `<const TShort>` preserves the literal-string at the call-site, so
|
|
511
512
|
// `eventName(INVOICE_EVENTS.sent)` carries `"billing:event:invoice-sent"`
|
|
512
|
-
// as a literal type. That literal is what `ctx.
|
|
513
|
+
// as a literal type. That literal is what `ctx.events.append({ type, ... })`
|
|
513
514
|
// strict-checks against the augmented `KumikoEventTypeMap`.
|
|
514
515
|
export function eventName<const TShort extends string>(
|
|
515
516
|
short: TShort,
|
|
@@ -523,8 +524,8 @@ export const INVOICE_CREATED_EVENT = `${ENTITY_NAME}.created` as const;
|
|
|
523
524
|
|
|
524
525
|
export const emptyEventPayload = z.object({});
|
|
525
526
|
export const statusForcedPayload = z.object({
|
|
526
|
-
newStatus: z.enum(
|
|
527
|
-
fromStatus: z.enum(
|
|
527
|
+
newStatus: z.enum(INVOICE_STATES),
|
|
528
|
+
fromStatus: z.enum(INVOICE_STATES),
|
|
528
529
|
});
|
|
529
530
|
|
|
530
531
|
// The EventDefs r.defineEvent returns inside the feature setup. Handlers receive them so that
|
|
@@ -926,7 +927,7 @@ export async function loadInvoiceState(
|
|
|
926
927
|
ctx: HandlerContext,
|
|
927
928
|
id: string,
|
|
928
929
|
): Promise<InvoiceState | null> {
|
|
929
|
-
const events = await ctx.
|
|
930
|
+
const events = await ctx.events.load(id);
|
|
930
931
|
if (events.length === 0) return null;
|
|
931
932
|
const state: InvoiceState = { ...initialInvoiceState };
|
|
932
933
|
for (const evt of events) reduceInvoice(state, evt);
|
|
@@ -13,6 +13,7 @@ Multi-tenant data isolation by default.
|
|
|
13
13
|
## What it shows
|
|
14
14
|
|
|
15
15
|
- Tenant filter on ordinary handlers
|
|
16
|
+
- `ctx.db.upsert`: insert-or-update on a tenant-scoped, non-event-sourced table. `conflictTarget` must contain `tenantId` and match a declared unique index (here `tenant_id, key`); event-fed tables are rejected
|
|
16
17
|
- What breaks if you forget tenancy (and how the framework prevents it)
|
|
17
18
|
|
|
18
19
|
## Source
|
|
@@ -37,6 +38,7 @@ bun test
|
|
|
37
38
|
// Proves: tenant_id scopes all data, cross-tenant access returns nothing
|
|
38
39
|
|
|
39
40
|
import { afterAll, beforeAll, beforeEach, describe, expect, test } from "bun:test";
|
|
41
|
+
import { selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
40
42
|
import type { SaveContext } from "@cosmicdrift/kumiko-framework/engine";
|
|
41
43
|
import { createEventsTable } from "@cosmicdrift/kumiko-framework/event-store";
|
|
42
44
|
import { createTestUser, TestUsers } from "@cosmicdrift/kumiko-framework/seeding";
|
|
@@ -45,7 +47,7 @@ import {
|
|
|
45
47
|
type TestStack,
|
|
46
48
|
unsafeCreateEntityTable,
|
|
47
49
|
} from "@cosmicdrift/kumiko-testing/stack";
|
|
48
|
-
import { noteEntity, noteFeature } from "../feature";
|
|
50
|
+
import { noteEntity, noteFeature, preferenceTable } from "../feature";
|
|
49
51
|
|
|
50
52
|
let stack: TestStack;
|
|
51
53
|
|
|
@@ -136,12 +138,48 @@ describe("tenant isolation", () => {
|
|
|
136
138
|
expect(listB.rows.some((r) => r["title"] === "A-Note")).toBe(false);
|
|
137
139
|
});
|
|
138
140
|
});
|
|
141
|
+
|
|
142
|
+
describe("ctx.db.upsert", () => {
|
|
143
|
+
const setPreference = (user: typeof tenantBAdmin, key: string, value: string) =>
|
|
144
|
+
stack.http.writeOk<{ value: string }>("notes:write:preference:set", { key, value }, user);
|
|
145
|
+
|
|
146
|
+
test("a second upsert with the same key updates the tenant's row instead of inserting", async () => {
|
|
147
|
+
await setPreference(tenantAAdmin, "theme", "light");
|
|
148
|
+
const second = await setPreference(tenantAAdmin, "theme", "dark");
|
|
149
|
+
|
|
150
|
+
expect(second.value).toBe("dark");
|
|
151
|
+
const rows = await selectMany(stack.db, preferenceTable, {
|
|
152
|
+
tenantId: tenantAAdmin.tenantId,
|
|
153
|
+
key: "theme",
|
|
154
|
+
});
|
|
155
|
+
expect(rows).toHaveLength(1);
|
|
156
|
+
expect(rows[0]?.["value"]).toBe("dark");
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test("the same key in another tenant creates a separate row and leaves A's value alone", async () => {
|
|
160
|
+
await setPreference(tenantAAdmin, "language", "de");
|
|
161
|
+
await setPreference(tenantBAdmin, "language", "en");
|
|
162
|
+
|
|
163
|
+
const rowsA = await selectMany(stack.db, preferenceTable, {
|
|
164
|
+
tenantId: tenantAAdmin.tenantId,
|
|
165
|
+
key: "language",
|
|
166
|
+
});
|
|
167
|
+
const rowsB = await selectMany(stack.db, preferenceTable, {
|
|
168
|
+
tenantId: tenantBAdmin.tenantId,
|
|
169
|
+
key: "language",
|
|
170
|
+
});
|
|
171
|
+
expect(rowsA.map((row) => row["value"])).toEqual(["de"]);
|
|
172
|
+
expect(rowsB.map((row) => row["value"])).toEqual(["en"]);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
139
175
|
```
|
|
140
176
|
|
|
141
177
|
### src/feature.ts
|
|
142
178
|
|
|
143
179
|
```ts
|
|
180
|
+
import { defineUnmanagedTable } from "@cosmicdrift/kumiko-framework/db";
|
|
144
181
|
import { createEntity, createTextField, defineFeature } from "@cosmicdrift/kumiko-framework/engine";
|
|
182
|
+
import * as z from "zod";
|
|
145
183
|
|
|
146
184
|
export const noteEntity = createEntity({
|
|
147
185
|
table: "read_sample_notes",
|
|
@@ -151,6 +189,26 @@ export const noteEntity = createEntity({
|
|
|
151
189
|
},
|
|
152
190
|
});
|
|
153
191
|
|
|
192
|
+
// Not event-sourced: ctx.db.upsert rejects executor-managed tables.
|
|
193
|
+
export const preferenceTable = defineUnmanagedTable({
|
|
194
|
+
tableName: "sample_tenant_preferences",
|
|
195
|
+
columns: [
|
|
196
|
+
{
|
|
197
|
+
name: "id",
|
|
198
|
+
pgType: "uuid",
|
|
199
|
+
notNull: true,
|
|
200
|
+
primaryKey: true,
|
|
201
|
+
defaultSql: "gen_random_uuid()",
|
|
202
|
+
},
|
|
203
|
+
{ name: "tenant_id", pgType: "uuid", notNull: true },
|
|
204
|
+
{ name: "key", pgType: "text", notNull: true },
|
|
205
|
+
{ name: "value", pgType: "text", notNull: true },
|
|
206
|
+
],
|
|
207
|
+
indexes: [
|
|
208
|
+
{ name: "sample_tenant_preferences_tenant_key", columns: ["tenant_id", "key"], unique: true },
|
|
209
|
+
],
|
|
210
|
+
});
|
|
211
|
+
|
|
154
212
|
const adminWrite = { access: { roles: ["Admin"] } } as const;
|
|
155
213
|
const openRead = {
|
|
156
214
|
access: {
|
|
@@ -168,5 +226,19 @@ export const noteFeature = defineFeature("notes", (r) => {
|
|
|
168
226
|
read: openRead,
|
|
169
227
|
verbs: { update: false, delete: false, restore: false },
|
|
170
228
|
});
|
|
229
|
+
|
|
230
|
+
r.storeTable(preferenceTable, { reason: "settings.tenant_preferences" });
|
|
231
|
+
|
|
232
|
+
r.writeHandler({
|
|
233
|
+
name: "preference:set",
|
|
234
|
+
schema: z.object({ key: z.string().min(1), value: z.string() }),
|
|
235
|
+
handler: async (event, ctx) => {
|
|
236
|
+
const row = await ctx.db.upsert<{ value: string }>(preferenceTable, event.payload, {
|
|
237
|
+
conflictTarget: ["tenantId", "key"],
|
|
238
|
+
});
|
|
239
|
+
return { isSuccess: true, data: { value: row?.value } };
|
|
240
|
+
},
|
|
241
|
+
...adminWrite,
|
|
242
|
+
});
|
|
171
243
|
});
|
|
172
244
|
```
|
|
@@ -158,7 +158,7 @@ beforeAll(async () => {
|
|
|
158
158
|
features: [createConfigFeature(), createTenantSettingsFeature(), invoiceFeature],
|
|
159
159
|
extraContext: ({ registry }) => ({
|
|
160
160
|
configResolver: resolver,
|
|
161
|
-
|
|
161
|
+
configAccessorFactory: createConfigAccessorFactory(registry, resolver),
|
|
162
162
|
}),
|
|
163
163
|
});
|
|
164
164
|
await unsafePushTables(stack.db, { configValuesTable });
|
|
@@ -173,7 +173,7 @@ import {
|
|
|
173
173
|
import { insertOne, selectMany } from "@cosmicdrift/kumiko-framework/db";
|
|
174
174
|
import { EXT_USER_DATA } from "@cosmicdrift/kumiko-framework/engine";
|
|
175
175
|
import { getTemporal } from "@cosmicdrift/kumiko-framework/time";
|
|
176
|
-
import {
|
|
176
|
+
import { seedRowViaEventStore } from "@cosmicdrift/kumiko-testing/helpers";
|
|
177
177
|
import {
|
|
178
178
|
setupTestStack,
|
|
179
179
|
type TestStack,
|
|
@@ -183,8 +183,6 @@ import { noteEntity, notesFeature, notesTable } from "../feature";
|
|
|
183
183
|
|
|
184
184
|
let stack: TestStack;
|
|
185
185
|
|
|
186
|
-
const TENANT_SYSTEM = "00000000-0000-4000-8000-000000000001";
|
|
187
|
-
|
|
188
186
|
// Each test gets its own tenant and user, so rows from other tests never show up.
|
|
189
187
|
let testNumber = 0;
|
|
190
188
|
let TENANT_A = "";
|
|
@@ -231,9 +229,8 @@ function noteId(index: number): string {
|
|
|
231
229
|
}
|
|
232
230
|
|
|
233
231
|
async function seedAlice(opts: { gracePeriodEnd?: Instant; status?: string } = {}): Promise<void> {
|
|
234
|
-
await
|
|
232
|
+
await seedRowViaEventStore(stack.db, userTable, {
|
|
235
233
|
id: ALICE_ID,
|
|
236
|
-
tenantId: TENANT_SYSTEM,
|
|
237
234
|
email: ALICE_EMAIL,
|
|
238
235
|
passwordHash: "h",
|
|
239
236
|
displayName: "Alice",
|
|
@@ -243,7 +240,7 @@ async function seedAlice(opts: { gracePeriodEnd?: Instant; status?: string } = {
|
|
|
243
240
|
status: opts.status ?? USER_STATUS.Active,
|
|
244
241
|
gracePeriodEnd: opts.gracePeriodEnd ?? null,
|
|
245
242
|
});
|
|
246
|
-
await
|
|
243
|
+
await seedRowViaEventStore(stack.db, tenantMembershipsTable, {
|
|
247
244
|
tenantId: TENANT_A,
|
|
248
245
|
userId: ALICE_ID,
|
|
249
246
|
roles: '["Member"]',
|