@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
|
@@ -325,7 +325,7 @@ describe("workflow-engine", () => {
|
|
|
325
325
|
});
|
|
326
326
|
|
|
327
327
|
it("webhook-delivery completes with exactly one dispatch request", async () => {
|
|
328
|
-
const ctx = {
|
|
328
|
+
const ctx = { events: { unsafeAppend: mock().mockResolvedValue(undefined) } };
|
|
329
329
|
|
|
330
330
|
const result = await startAndRunWorkflow({
|
|
331
331
|
runId: "wf-webhook-delivery-1",
|
|
@@ -339,7 +339,7 @@ describe("workflow-engine", () => {
|
|
|
339
339
|
});
|
|
340
340
|
|
|
341
341
|
expect(result.outcome).toBe("completed");
|
|
342
|
-
const dispatchRequests = ctx.
|
|
342
|
+
const dispatchRequests = ctx.events.unsafeAppend.mock.calls
|
|
343
343
|
.map(([event]) => event as { type: string; payload: Record<string, unknown> })
|
|
344
344
|
.filter((event) => event.type === STEP_DISPATCH_REQUESTED_TYPE);
|
|
345
345
|
expect(dispatchRequests).toHaveLength(1);
|
|
@@ -367,7 +367,7 @@ describe("workflow-engine", () => {
|
|
|
367
367
|
|
|
368
368
|
describe("workflow-runner", () => {
|
|
369
369
|
function makeAppendOnlyCtx() {
|
|
370
|
-
return {
|
|
370
|
+
return { events: { unsafeAppend: mock().mockResolvedValue(undefined) } };
|
|
371
371
|
}
|
|
372
372
|
|
|
373
373
|
it("startAndRunWorkflow writes run.started with Q7 snapshot fingerprint, then runs the pipeline to completion when no suspension", async () => {
|
|
@@ -386,15 +386,15 @@ describe("workflow-runner", () => {
|
|
|
386
386
|
});
|
|
387
387
|
|
|
388
388
|
expect(result.outcome).toBe("completed");
|
|
389
|
-
expect(ctx.
|
|
390
|
-
const started = ctx.
|
|
389
|
+
expect(ctx.events.unsafeAppend).toHaveBeenCalledTimes(2);
|
|
390
|
+
const started = ctx.events.unsafeAppend.mock.calls[0]![0] as {
|
|
391
391
|
type: string;
|
|
392
392
|
payload: Record<string, unknown>;
|
|
393
393
|
};
|
|
394
394
|
expect(started.type).toBe("kumiko:system:workflow.run-started");
|
|
395
395
|
expect(started.payload["definitionFingerprint"]).toBe(computeDefinitionFingerprint(workflow));
|
|
396
396
|
expect(started.payload["triggerEventType"]).toBe("demo.fired");
|
|
397
|
-
const completed = ctx.
|
|
397
|
+
const completed = ctx.events.unsafeAppend.mock.calls[1]![0] as { type: string };
|
|
398
398
|
expect(completed.type).toBe("kumiko:system:workflow.run-completed");
|
|
399
399
|
});
|
|
400
400
|
|
|
@@ -418,8 +418,8 @@ describe("workflow-runner", () => {
|
|
|
418
418
|
|
|
419
419
|
expect(result.outcome).toBe("suspended");
|
|
420
420
|
// run.started + workflow.step.waiting — no run-completed yet
|
|
421
|
-
expect(ctx.
|
|
422
|
-
const waiting = ctx.
|
|
421
|
+
expect(ctx.events.unsafeAppend).toHaveBeenCalledTimes(2);
|
|
422
|
+
const waiting = ctx.events.unsafeAppend.mock.calls[1]![0] as {
|
|
423
423
|
type: string;
|
|
424
424
|
payload: Record<string, unknown>;
|
|
425
425
|
};
|
|
@@ -444,14 +444,16 @@ describe("workflow-runner", () => {
|
|
|
444
444
|
handlerCtx: ctx as never,
|
|
445
445
|
});
|
|
446
446
|
|
|
447
|
-
const started = ctx.
|
|
447
|
+
const started = ctx.events.unsafeAppend.mock.calls[0]![0] as {
|
|
448
|
+
payload: Record<string, unknown>;
|
|
449
|
+
};
|
|
448
450
|
expect(started.payload["idempotencyKey"]).toBe("id:abc");
|
|
449
451
|
});
|
|
450
452
|
});
|
|
451
453
|
|
|
452
454
|
describe("userOnboardingWorkflow (end-to-end, in-memory)", () => {
|
|
453
455
|
it("suspends on the first wait, then resume-loop runs it through to completion", async () => {
|
|
454
|
-
const ctx = {
|
|
456
|
+
const ctx = { events: { unsafeAppend: mock().mockResolvedValue(undefined) } };
|
|
455
457
|
const trigger = {
|
|
456
458
|
aggregateId: "agg_user_42",
|
|
457
459
|
type: "user.signed-up",
|
|
@@ -469,16 +471,16 @@ describe("userOnboardingWorkflow (end-to-end, in-memory)", () => {
|
|
|
469
471
|
|
|
470
472
|
expect(result.outcome).toBe("suspended");
|
|
471
473
|
// Calls: run.started, mail.send dispatch-requested, workflow.step.waiting
|
|
472
|
-
expect(ctx.
|
|
473
|
-
const startedCall = ctx.
|
|
474
|
+
expect(ctx.events.unsafeAppend).toHaveBeenCalledTimes(3);
|
|
475
|
+
const startedCall = ctx.events.unsafeAppend.mock.calls[0]![0] as {
|
|
474
476
|
type: string;
|
|
475
477
|
payload: Record<string, unknown>;
|
|
476
478
|
};
|
|
477
|
-
const mailCall = ctx.
|
|
479
|
+
const mailCall = ctx.events.unsafeAppend.mock.calls[1]![0] as {
|
|
478
480
|
type: string;
|
|
479
481
|
payload: Record<string, unknown>;
|
|
480
482
|
};
|
|
481
|
-
const waitingCall = ctx.
|
|
483
|
+
const waitingCall = ctx.events.unsafeAppend.mock.calls[2]![0] as {
|
|
482
484
|
type: string;
|
|
483
485
|
payload: Record<string, unknown>;
|
|
484
486
|
};
|
|
@@ -514,7 +516,7 @@ describe("userOnboardingWorkflow (end-to-end, in-memory)", () => {
|
|
|
514
516
|
definitionFingerprint: waitingCall.payload["definitionFingerprint"] as string,
|
|
515
517
|
};
|
|
516
518
|
|
|
517
|
-
const resumeCtx = {
|
|
519
|
+
const resumeCtx = { events: { unsafeAppend: mock().mockResolvedValue(undefined) } };
|
|
518
520
|
const count = await runResumeLoop(
|
|
519
521
|
createInMemorySuspendedRunFetcher([suspendedRun]),
|
|
520
522
|
resumeCtx as never,
|
|
@@ -525,7 +527,7 @@ describe("userOnboardingWorkflow (end-to-end, in-memory)", () => {
|
|
|
525
527
|
// because userId starts with "active-"), second WAITING for P7D.
|
|
526
528
|
// The run is suspended again before the webhook, so no RUN_COMPLETED
|
|
527
529
|
// yet — this is one resume-cycle, not the whole workflow.
|
|
528
|
-
const resumeTypes = resumeCtx.
|
|
530
|
+
const resumeTypes = resumeCtx.events.unsafeAppend.mock.calls.map(
|
|
529
531
|
(c) => (c[0] as { type: string }).type,
|
|
530
532
|
);
|
|
531
533
|
expect(resumeTypes).toEqual([
|
|
@@ -533,14 +535,14 @@ describe("userOnboardingWorkflow (end-to-end, in-memory)", () => {
|
|
|
533
535
|
"kumiko:system:step.dispatch-requested",
|
|
534
536
|
"kumiko:system:workflow.step.waiting",
|
|
535
537
|
]);
|
|
536
|
-
const tipsMail = resumeCtx.
|
|
538
|
+
const tipsMail = resumeCtx.events.unsafeAppend.mock.calls[1]![0] as {
|
|
537
539
|
payload: { subject: string };
|
|
538
540
|
};
|
|
539
541
|
expect(tipsMail.payload.subject).toBe("Engagement tips");
|
|
540
542
|
});
|
|
541
543
|
|
|
542
544
|
it("not-engaged path picks the reminder branch", async () => {
|
|
543
|
-
const ctx = {
|
|
545
|
+
const ctx = { events: { unsafeAppend: mock().mockResolvedValue(undefined) } };
|
|
544
546
|
const trigger = {
|
|
545
547
|
aggregateId: "agg_user_cold",
|
|
546
548
|
type: "user.signed-up",
|
|
@@ -553,7 +555,9 @@ describe("userOnboardingWorkflow (end-to-end, in-memory)", () => {
|
|
|
553
555
|
triggerEventRef: { eventId: "2", aggregateId: trigger.aggregateId, version: 1 },
|
|
554
556
|
handlerCtx: ctx as never,
|
|
555
557
|
});
|
|
556
|
-
const waiting = ctx.
|
|
558
|
+
const waiting = ctx.events.unsafeAppend.mock.calls[2]![0] as {
|
|
559
|
+
payload: Record<string, unknown>;
|
|
560
|
+
};
|
|
557
561
|
const suspendedRun: SuspendableRun = {
|
|
558
562
|
runId: "wf-onboarding-cold-1",
|
|
559
563
|
workflowName: "user-onboarding",
|
|
@@ -564,10 +568,10 @@ describe("userOnboardingWorkflow (end-to-end, in-memory)", () => {
|
|
|
564
568
|
triggerEvent: trigger as never,
|
|
565
569
|
definitionFingerprint: waiting.payload["definitionFingerprint"] as string,
|
|
566
570
|
};
|
|
567
|
-
const resumeCtx = {
|
|
571
|
+
const resumeCtx = { events: { unsafeAppend: mock().mockResolvedValue(undefined) } };
|
|
568
572
|
await runResumeLoop(createInMemorySuspendedRunFetcher([suspendedRun]), resumeCtx as never);
|
|
569
573
|
|
|
570
|
-
const reminderMail = resumeCtx.
|
|
574
|
+
const reminderMail = resumeCtx.events.unsafeAppend.mock.calls[1]![0] as {
|
|
571
575
|
payload: { subject: string };
|
|
572
576
|
};
|
|
573
577
|
expect(reminderMail.payload.subject).toBe("Getting started");
|
|
@@ -696,7 +700,7 @@ describe("cron-scheduler", () => {
|
|
|
696
700
|
steps: stepsPipeline(({ r }) => [r.step.return({ isSuccess: true, data: undefined })]),
|
|
697
701
|
});
|
|
698
702
|
|
|
699
|
-
const handlerCtx = {
|
|
703
|
+
const handlerCtx = { events: { unsafeAppend: mock() } };
|
|
700
704
|
const lastRuns = new Map<string, Temporal.Instant>();
|
|
701
705
|
const now = Temporal.Instant.from("2025-06-01T08:00:00Z");
|
|
702
706
|
|
|
@@ -708,7 +712,7 @@ describe("cron-scheduler", () => {
|
|
|
708
712
|
);
|
|
709
713
|
|
|
710
714
|
expect(count).toBe(0);
|
|
711
|
-
expect(handlerCtx.
|
|
715
|
+
expect(handlerCtx.events.unsafeAppend).not.toHaveBeenCalled();
|
|
712
716
|
});
|
|
713
717
|
|
|
714
718
|
it("runDueCronWorkflows runs due workflows through the full start path", async () => {
|
|
@@ -718,7 +722,7 @@ describe("cron-scheduler", () => {
|
|
|
718
722
|
steps: stepsPipeline(({ r }) => [r.step.return({ isSuccess: true, data: undefined })]),
|
|
719
723
|
});
|
|
720
724
|
|
|
721
|
-
const handlerCtx = {
|
|
725
|
+
const handlerCtx = { events: { unsafeAppend: mock().mockResolvedValue(undefined) } };
|
|
722
726
|
const lastRuns = new Map<string, Temporal.Instant>();
|
|
723
727
|
const lastRun = Temporal.Instant.from("2025-05-31T08:00:00Z");
|
|
724
728
|
lastRuns.set("test-daily", lastRun);
|
|
@@ -733,10 +737,10 @@ describe("cron-scheduler", () => {
|
|
|
733
737
|
|
|
734
738
|
expect(count).toBe(1);
|
|
735
739
|
// run.started + run-completed (no suspension, pipeline returns immediately).
|
|
736
|
-
expect(handlerCtx.
|
|
737
|
-
const started = handlerCtx.
|
|
740
|
+
expect(handlerCtx.events.unsafeAppend).toHaveBeenCalledTimes(2);
|
|
741
|
+
const started = handlerCtx.events.unsafeAppend.mock.calls[0]![0] as Record<string, unknown>;
|
|
738
742
|
expect(started["type"]).toBe("kumiko:system:workflow.run-started");
|
|
739
|
-
const completed = handlerCtx.
|
|
743
|
+
const completed = handlerCtx.events.unsafeAppend.mock.calls[1]![0] as Record<string, unknown>;
|
|
740
744
|
expect(completed["type"]).toBe("kumiko:system:workflow.run-completed");
|
|
741
745
|
});
|
|
742
746
|
});
|
|
@@ -744,12 +748,12 @@ describe("cron-scheduler", () => {
|
|
|
744
748
|
describe("resume-loop", () => {
|
|
745
749
|
it("returns 0 when no suspended runs exist", async () => {
|
|
746
750
|
const fetchRuns = createInMemorySuspendedRunFetcher([]);
|
|
747
|
-
const handlerCtx = {
|
|
751
|
+
const handlerCtx = { events: { unsafeAppend: mock() } };
|
|
748
752
|
|
|
749
753
|
const count = await runResumeLoop(fetchRuns, handlerCtx as never);
|
|
750
754
|
|
|
751
755
|
expect(count).toBe(0);
|
|
752
|
-
expect(handlerCtx.
|
|
756
|
+
expect(handlerCtx.events.unsafeAppend).not.toHaveBeenCalled();
|
|
753
757
|
});
|
|
754
758
|
|
|
755
759
|
it("resumes a suspended run", async () => {
|
|
@@ -766,19 +770,19 @@ describe("resume-loop", () => {
|
|
|
766
770
|
};
|
|
767
771
|
|
|
768
772
|
const fetchRuns = createInMemorySuspendedRunFetcher([suspendedRun]);
|
|
769
|
-
const handlerCtx = {
|
|
773
|
+
const handlerCtx = { events: { unsafeAppend: mock().mockResolvedValue(undefined) } };
|
|
770
774
|
|
|
771
775
|
const count = await runResumeLoop(fetchRuns, handlerCtx as never);
|
|
772
776
|
|
|
773
777
|
expect(count).toBe(1);
|
|
774
|
-
expect(handlerCtx.
|
|
775
|
-
expect(handlerCtx.
|
|
778
|
+
expect(handlerCtx.events.unsafeAppend).toHaveBeenCalledTimes(2);
|
|
779
|
+
expect(handlerCtx.events.unsafeAppend).toHaveBeenNthCalledWith(1, {
|
|
776
780
|
aggregateId: "wf-test-run_123",
|
|
777
781
|
aggregateType: "workflow-run",
|
|
778
782
|
type: "kumiko:system:workflow.step.resumed",
|
|
779
783
|
payload: { stepIndex: 0, retryAttempt: undefined },
|
|
780
784
|
});
|
|
781
|
-
expect(handlerCtx.
|
|
785
|
+
expect(handlerCtx.events.unsafeAppend).toHaveBeenNthCalledWith(2, {
|
|
782
786
|
aggregateId: "wf-test-run_123",
|
|
783
787
|
aggregateType: "workflow-run",
|
|
784
788
|
type: "kumiko:system:workflow.run-completed",
|
|
@@ -800,13 +804,13 @@ describe("resume-loop", () => {
|
|
|
800
804
|
};
|
|
801
805
|
|
|
802
806
|
const fetchRuns = createInMemorySuspendedRunFetcher([suspendedRun]);
|
|
803
|
-
const handlerCtx = {
|
|
807
|
+
const handlerCtx = { events: { unsafeAppend: mock().mockResolvedValue(undefined) } };
|
|
804
808
|
|
|
805
809
|
const count = await runResumeLoop(fetchRuns, handlerCtx as never);
|
|
806
810
|
|
|
807
811
|
expect(count).toBe(0);
|
|
808
|
-
expect(handlerCtx.
|
|
809
|
-
const failed = handlerCtx.
|
|
812
|
+
expect(handlerCtx.events.unsafeAppend).toHaveBeenCalledTimes(1);
|
|
813
|
+
const failed = handlerCtx.events.unsafeAppend.mock.calls[0]![0] as {
|
|
810
814
|
type: string;
|
|
811
815
|
payload: Record<string, unknown>;
|
|
812
816
|
};
|
|
@@ -830,16 +834,18 @@ describe("resume-loop", () => {
|
|
|
830
834
|
|
|
831
835
|
const fetchRuns = createInMemorySuspendedRunFetcher([suspendedRun]);
|
|
832
836
|
const handlerCtx = {
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
837
|
+
events: {
|
|
838
|
+
unsafeAppend: mock()
|
|
839
|
+
.mockRejectedValueOnce(new VersionConflictError("wf-conflict-run", 1))
|
|
840
|
+
.mockResolvedValue(undefined),
|
|
841
|
+
},
|
|
836
842
|
};
|
|
837
843
|
|
|
838
844
|
const count = await runResumeLoop(fetchRuns, handlerCtx as never);
|
|
839
845
|
|
|
840
846
|
expect(count).toBe(0);
|
|
841
|
-
expect(handlerCtx.
|
|
842
|
-
expect((handlerCtx.
|
|
847
|
+
expect(handlerCtx.events.unsafeAppend).toHaveBeenCalledTimes(1);
|
|
848
|
+
expect((handlerCtx.events.unsafeAppend.mock.calls[0]![0] as { type: string }).type).toBe(
|
|
843
849
|
"kumiko:system:workflow.step.resumed",
|
|
844
850
|
);
|
|
845
851
|
});
|
|
@@ -1509,7 +1515,7 @@ export async function runResumeLoop(
|
|
|
1509
1515
|
if (run.definitionFingerprint !== undefined) {
|
|
1510
1516
|
const currentFingerprint = computeDefinitionFingerprint(run.workflow);
|
|
1511
1517
|
if (currentFingerprint !== run.definitionFingerprint) {
|
|
1512
|
-
await handlerCtx.
|
|
1518
|
+
await handlerCtx.events.unsafeAppend({
|
|
1513
1519
|
aggregateId: run.runId,
|
|
1514
1520
|
aggregateType: WORKFLOW_AGGREGATE_TYPE,
|
|
1515
1521
|
type: WORKFLOW_RUN_FAILED_TYPE,
|
|
@@ -1537,7 +1543,7 @@ export async function runResumeLoop(
|
|
|
1537
1543
|
// no FAILED-event. Stale WAITING-rows in the fetcher result also
|
|
1538
1544
|
// hit this branch on the second poll-tick.
|
|
1539
1545
|
try {
|
|
1540
|
-
await handlerCtx.
|
|
1546
|
+
await handlerCtx.events.unsafeAppend({
|
|
1541
1547
|
aggregateId: run.runId,
|
|
1542
1548
|
aggregateType: WORKFLOW_AGGREGATE_TYPE,
|
|
1543
1549
|
type: WORKFLOW_RESUMED_TYPE,
|
|
@@ -1589,7 +1595,7 @@ export async function runResumeLoop(
|
|
|
1589
1595
|
// returned. A second suspension (e.g. `wait` further down the
|
|
1590
1596
|
// pipeline) leaves the run pending for the next resume-loop tick.
|
|
1591
1597
|
if (outcome.kind !== "suspended") {
|
|
1592
|
-
await handlerCtx.
|
|
1598
|
+
await handlerCtx.events.unsafeAppend({
|
|
1593
1599
|
aggregateId: run.runId,
|
|
1594
1600
|
aggregateType: WORKFLOW_AGGREGATE_TYPE,
|
|
1595
1601
|
type: WORKFLOW_RUN_COMPLETED_TYPE,
|
|
@@ -1606,7 +1612,7 @@ export async function runResumeLoop(
|
|
|
1606
1612
|
stepIndex: run.stepIndex,
|
|
1607
1613
|
error: String(error),
|
|
1608
1614
|
});
|
|
1609
|
-
await handlerCtx.
|
|
1615
|
+
await handlerCtx.events.unsafeAppend({
|
|
1610
1616
|
aggregateId: run.runId,
|
|
1611
1617
|
aggregateType: WORKFLOW_AGGREGATE_TYPE,
|
|
1612
1618
|
type: WORKFLOW_RUN_FAILED_TYPE,
|
|
@@ -1697,7 +1703,7 @@ export async function startAndRunWorkflow(args: {
|
|
|
1697
1703
|
...(args.idempotencyKey && { idempotencyKey: args.idempotencyKey }),
|
|
1698
1704
|
};
|
|
1699
1705
|
|
|
1700
|
-
await args.handlerCtx.
|
|
1706
|
+
await args.handlerCtx.events.unsafeAppend({
|
|
1701
1707
|
aggregateId: args.runId,
|
|
1702
1708
|
aggregateType: WORKFLOW_AGGREGATE_TYPE,
|
|
1703
1709
|
type: WORKFLOW_RUN_STARTED_TYPE,
|
|
@@ -1724,7 +1730,7 @@ export async function startAndRunWorkflow(args: {
|
|
|
1724
1730
|
return { outcome: "suspended" };
|
|
1725
1731
|
}
|
|
1726
1732
|
|
|
1727
|
-
await args.handlerCtx.
|
|
1733
|
+
await args.handlerCtx.events.unsafeAppend({
|
|
1728
1734
|
aggregateId: args.runId,
|
|
1729
1735
|
aggregateType: WORKFLOW_AGGREGATE_TYPE,
|
|
1730
1736
|
type: WORKFLOW_RUN_COMPLETED_TYPE,
|
package/agents/examples.md
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
| `chat-channels` | Chat channels. Delivery notifications to Slack, minus the browser tab. | `examples/chat-channels.md` |
|
|
20
20
|
| `compliance-profiles-demo` | Two-tenant demo: EU + Swiss compliance profiles deliver different authority contacts, languages, and grace periods through the same App-code. | `examples/compliance-profiles-demo.md` |
|
|
21
21
|
| `compose-stacks` | compose*Stack helpers for auth, security, GDPR and SaaS billing, and the runProdApp check that names a stack whose boot option is missing. | `examples/compose-stacks.md` |
|
|
22
|
-
| `cross-feature-events` | Feature appends a typed domain event via ctx.
|
|
22
|
+
| `cross-feature-events` | Feature appends a typed domain event via ctx.events.append; a r.multiStreamProjection reacts asynchronously. | `examples/cross-feature-events.md` |
|
|
23
23
|
| `crypto-shredding-hr` | Crypto-shredding: PII fields encrypted per subject key; forgetting the subject erases the key and every field it protected. | `examples/crypto-shredding-hr.md` |
|
|
24
24
|
| `currencies-global` | Shared money fields across tenants. Commas still matter. | `examples/currencies-global.md` |
|
|
25
25
|
| `currencies-per-tenant` | Tenant-scoped money fields. Commas matter. | `examples/currencies-per-tenant.md` |
|
|
@@ -34,20 +34,21 @@
|
|
|
34
34
|
| `encrypted-tenant-config` | Per-tenant secrets via config-key encryption — Stripe-API-key pattern. | `examples/encrypted-tenant-config.md` |
|
|
35
35
|
| `env-composition` | Typed app env from the env blocks bundled features register, plus app-level blocks in extend. | `examples/env-composition.md` |
|
|
36
36
|
| `error-contract` | Typed errors on the wire. With snake_case reasons, because we care. | `examples/error-contract.md` |
|
|
37
|
-
| `event-sourcing` | Production-pattern ES sample: r.defineEvent (versioned + migrations) + ctx.
|
|
37
|
+
| `event-sourcing` | Production-pattern ES sample: r.defineEvent (versioned + migrations) + ctx.events.append + r.projection + r.multiStreamProjection + ctx.events.load (asOf) + ctx.events.archive + ctx.dispatch.queryProjection. | `examples/event-sourcing.md` |
|
|
38
38
|
| `feature-toggles` | Runtime feature-toggle flip — two toggleable features, one registers a cross-feature hook on the other; disabling either has the documented effect without reboot. | `examples/feature-toggles.md` |
|
|
39
39
|
| `field-access` | Field-level access control. When entity-level roles aren't granular enough. | `examples/field-access.md` |
|
|
40
|
-
| `files-post-processing` | The three ways to generate an image variant: declarative field variants, imperative ctx.derivatives.variant() with region-blur, and the public route behind a default-deny predicate. | `examples/files-post-processing.md` |
|
|
40
|
+
| `files-post-processing` | The three ways to generate an image variant: declarative field variants, imperative ctx.services.derivatives.variant() with region-blur, and the public route behind a default-deny predicate. | `examples/files-post-processing.md` |
|
|
41
41
|
| `golden-path` | The smallest complete feature: entity, write handler, event, projection, screen and an integration test. | `examples/golden-path.md` |
|
|
42
42
|
| `host-routing` | createHostRoutingFeature + createHostDispatch — tenant per subdomain, per-host HTML and CSP, locale redirect, shared by runProdApp and the dev server. | `examples/host-routing.md` |
|
|
43
43
|
| `i18n` | Feature-scoped translations. 'Hallo' and 'Hello' in the same app. | `examples/i18n.md` |
|
|
44
44
|
| `idempotency` | Same request, same result. Dedupes on request ID. | `examples/idempotency.md` |
|
|
45
45
|
| `inbound-mail-triage` | Inbound-mail consumer pattern: inbound-mail-foundation + in-memory provider, a worker-lane triage job attached to the ingest handler, verified end-to-end through createAllInOneEntrypoint. | `examples/inbound-mail-triage.md` |
|
|
46
|
-
| `lane-routing` | runIn lane-routing: r.job pinned to api/worker deploy-lanes, event-chain via ctx.
|
|
46
|
+
| `lane-routing` | runIn lane-routing: r.job pinned to api/worker deploy-lanes, event-chain via ctx.events.append, verified end-to-end through createAllInOneEntrypoint. | `examples/lane-routing.md` |
|
|
47
47
|
| `ledger-banking` | Bank accounts + transfers on the ledger primitive — balances are pure queries, never stored. | `examples/ledger-banking.md` |
|
|
48
48
|
| `ledger-invoicing` | Accrual invoicing on the ledger primitive — revenue at invoice time, VAT as a liability, receivable cleared on payment. | `examples/ledger-invoicing.md` |
|
|
49
49
|
| `legal-pages` | Auto-rendered Impressum + Datenschutzerklärung pages — template-resolver + legal-pages bundled features wired up with anonymousAccess for DACH-compliance. | `examples/legal-pages.md` |
|
|
50
50
|
| `lifecycle-hooks` | preSave, postSave, and the rest. Your logic, our plumbing. | `examples/lifecycle-hooks.md` |
|
|
51
|
+
| `list-table-options` | Opt-in table behaviour of a list: remembered search/sort/filters, one reset button, column picker with hidden columns, row density, server-side groups with sums, a totals row and a number range facet. | `examples/list-table-options.md` |
|
|
51
52
|
| `managed-config` | Managed config: one declaration provisions storage + masking + settings-hub, across backings (secrets vs config) and scopes (system vs tenant). | `examples/managed-config.md` |
|
|
52
53
|
| `managed-pages` | Tenant-editable, server-rendered public pages with per-tenant branding + tier-gated sanitized custom CSS — managed-pages wired up with config + anonymousAccess. | `examples/managed-pages.md` |
|
|
53
54
|
| `notes-history-basic` | Append-only note history — who wrote what, when — attached to any entity without changing it. | `examples/notes-history-basic.md` |
|
package/agents/features.md
CHANGED
|
@@ -257,7 +257,7 @@ Category: operations
|
|
|
257
257
|
|
|
258
258
|
## file-derivatives
|
|
259
259
|
|
|
260
|
-
Declares the `derivativeRenderer` extension point. `ctx.derivatives.variant(fileRefId, spec, name)` derives a variant of a tracked FileRef the first time it's requested and reuses the stored result afterwards (derive-on-first-use, keyed by a hash of the spec). Mount at least one `derivatives-*` renderer feature alongside this one — without a registered renderer for the FileRef's MIME type, every `variant(...)` call throws. Also declares the `derivativePublicPredicate` extension point (`r.useExtension(EXT_DERIVATIVE_PUBLIC_PREDICATE, '<entityType>', { isPublic })`) and, when `createFileDerivativesFeature({resolveApexTenant})` is passed a host-resolver, mounts an anonymous `GET {basePath}/:fileRefId/:variant` route that serves any variant name the FileRef's field declared in its `variants` for a FileRef whose entityType has a registered predicate returning true — default-deny (404) otherwise, same as an unknown FileRef or an undeclared variant name. The route's only rate-limit (`per: "ip"`) depends on the server's `trustedProxyHops` matching the deployment's actual reverse-proxy count — at the default 0 it ignores `x-forwarded-for` entirely, so every caller shares one bucket until that's configured. `publicTenantResolution: "fileRef"` keeps resolveApexTenant as the host gate but reads the variant from the FileRef row's own tenant instead of the host's, so one shared platform host serves every tenant's public variants — each FileRef-tenant's own `isPublic` predicate still default-denies. Also declares the `derivativeOverlayResolver` extension point (`r.useExtension(EXT_DERIVATIVE_OVERLAY_RESOLVER, '<entityType>', { resolve })`), used to turn a variant's `overlays[].dataToken` into the actual QR payload for that FileRef's entityType before the variant is rendered — a variant declaring a `qr` overlay throws at request-time if no resolver is registered for the FileRef's entityType.
|
|
260
|
+
Declares the `derivativeRenderer` extension point. `ctx.services.derivatives.variant(fileRefId, spec, name)` derives a variant of a tracked FileRef the first time it's requested and reuses the stored result afterwards (derive-on-first-use, keyed by a hash of the spec). Mount at least one `derivatives-*` renderer feature alongside this one — without a registered renderer for the FileRef's MIME type, every `variant(...)` call throws. Also declares the `derivativePublicPredicate` extension point (`r.useExtension(EXT_DERIVATIVE_PUBLIC_PREDICATE, '<entityType>', { isPublic })`) and, when `createFileDerivativesFeature({resolveApexTenant})` is passed a host-resolver, mounts an anonymous `GET {basePath}/:fileRefId/:variant` route that serves any variant name the FileRef's field declared in its `variants` for a FileRef whose entityType has a registered predicate returning true — default-deny (404) otherwise, same as an unknown FileRef or an undeclared variant name. The route's only rate-limit (`per: "ip"`) depends on the server's `trustedProxyHops` matching the deployment's actual reverse-proxy count — at the default 0 it ignores `x-forwarded-for` entirely, so every caller shares one bucket until that's configured. `publicTenantResolution: "fileRef"` keeps resolveApexTenant as the host gate but reads the variant from the FileRef row's own tenant instead of the host's, so one shared platform host serves every tenant's public variants — each FileRef-tenant's own `isPublic` predicate still default-denies. Also declares the `derivativeOverlayResolver` extension point (`r.useExtension(EXT_DERIVATIVE_OVERLAY_RESOLVER, '<entityType>', { resolve })`), used to turn a variant's `overlays[].dataToken` into the actual QR payload for that FileRef's entityType before the variant is rendered — a variant declaring a `qr` overlay throws at request-time if no resolver is registered for the FileRef's entityType.
|
|
261
261
|
|
|
262
262
|
Category: storage
|
|
263
263
|
|
package/agents/widgets.md
CHANGED
|
@@ -143,6 +143,7 @@ Value exports of `@cosmicdrift/kumiko-renderer/web`.
|
|
|
143
143
|
| `buildFileUploadFormData` | |
|
|
144
144
|
| `buildNavRegistrySlice` | |
|
|
145
145
|
| `buildNavRegistrySliceForApp` | |
|
|
146
|
+
| `clearRememberedListState` | Forgets all remembered list state and the identity marker. |
|
|
146
147
|
| `cn` | Standard shadcn helper: `clsx` combines conditional classes, while `tailwind-merge` resolves conflicts (for example, `px-2 px-4` → `px-4`). |
|
|
147
148
|
| `createBrowserDraftStorage` | Default DraftStorage when createKumikoApp boots without one. |
|
|
148
149
|
| `createBrowserLocaleResolver` | Default resolver when createKumikoApp is booted without a `locale` option. |
|
|
@@ -8,6 +8,7 @@ export declare const Routes: {
|
|
|
8
8
|
readonly command: "/command";
|
|
9
9
|
readonly sse: "/sse";
|
|
10
10
|
readonly stream: "/stream";
|
|
11
|
+
readonly exportXlsx: "/export/xlsx";
|
|
11
12
|
readonly auth: "/auth";
|
|
12
13
|
readonly authLogin: "/auth/login";
|
|
13
14
|
readonly authMfaVerify: "/auth/mfa/verify";
|
|
@@ -10,6 +10,7 @@ export const Routes = {
|
|
|
10
10
|
command: "/command",
|
|
11
11
|
sse: "/sse",
|
|
12
12
|
stream: "/stream",
|
|
13
|
+
exportXlsx: "/export/xlsx",
|
|
13
14
|
auth: "/auth",
|
|
14
15
|
authLogin: "/auth/login",
|
|
15
16
|
authMfaVerify: "/auth/mfa/verify",
|
|
@@ -76,6 +77,7 @@ export const NON_PUBLIC_API_PATHS = new Set([
|
|
|
76
77
|
`/api${Routes.command}`,
|
|
77
78
|
`/api${Routes.sse}`,
|
|
78
79
|
`/api${Routes.stream}`,
|
|
80
|
+
`/api${Routes.exportXlsx}`,
|
|
79
81
|
// Namespace prefix used only for body-limit registration
|
|
80
82
|
// (`/api/auth/*` in route-registrars.ts) — never dispatched as its own
|
|
81
83
|
// route, so it carries no auth bypass either way. Classified non-public
|
|
@@ -5,7 +5,7 @@ import { createAnonymousUser } from "../engine/system-user.js";
|
|
|
5
5
|
import { parseTenantId, SYSTEM_TENANT_ID } from "../engine/types/identifiers.js";
|
|
6
6
|
import { isSessionRequiredApiPath, TENANT_HEADER_NAME } from "./api-constants.js";
|
|
7
7
|
import { isForeignCookieOrigin } from "./origin-middleware.js";
|
|
8
|
-
import { setRequestIdentity } from "./request-context.js";
|
|
8
|
+
import { setRequestIdentity } from "./request-context-internals.js";
|
|
9
9
|
import { clearSessionCookies, getSessionCookies, hasDuplicateSessionCookie, } from "./session-cookies.js";
|
|
10
10
|
const USER_KEY = "pipelineUser";
|
|
11
11
|
const AUTH_TRANSPORT_KEY = "authTransport";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
2
|
import { createAnonymousUser } from "../engine/system-user.js";
|
|
3
3
|
import { SYSTEM_TENANT_ID } from "../engine/types/index.js";
|
|
4
|
-
import { toKumikoError
|
|
4
|
+
import { toKumikoError } from "../errors/to-kumiko-error.js";
|
|
5
|
+
import { toWriteErrorInfo } from "../errors/write-error-info.js";
|
|
5
6
|
import { Routes } from "./api-constants.js";
|
|
6
7
|
import { getUser } from "./auth-middleware.js";
|
|
7
8
|
import { pendingMfaStepResponse } from "./auth-routes-shared.js";
|
|
@@ -8,6 +8,7 @@ export declare const SignupRequestBody: z.ZodObject<{
|
|
|
8
8
|
entityType: z.ZodString;
|
|
9
9
|
token: z.ZodString;
|
|
10
10
|
}, z.core.$strip>>;
|
|
11
|
+
returnTo: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
11
12
|
}, z.core.$strip>;
|
|
12
13
|
export declare function isUnknownHandlerError(e: unknown): boolean;
|
|
13
14
|
export type PendingMfaStep = {
|
|
@@ -29,5 +30,6 @@ export declare function registerTokenRequestRoute(opts: {
|
|
|
29
30
|
}): void;
|
|
30
31
|
declare const RequestTokenBody: z.ZodObject<{
|
|
31
32
|
email: z.ZodEmail;
|
|
33
|
+
returnTo: z.ZodCatch<z.ZodOptional<z.ZodString>>;
|
|
32
34
|
}, z.core.$strip>;
|
|
33
35
|
export {};
|
|
@@ -4,6 +4,9 @@ import { SYSTEM_TENANT_ID } from "../engine/types/index.js";
|
|
|
4
4
|
import { NotFoundError } from "../errors/index.js";
|
|
5
5
|
import { createFallbackLogger } from "../logging/utils.js";
|
|
6
6
|
const log = createFallbackLogger("kumiko");
|
|
7
|
+
// Content is checked where the mail link is built (bundled-features knows the path rules); a bad
|
|
8
|
+
// value must never void the whole body, or the request would silently send no mail.
|
|
9
|
+
const returnToField = z.string().max(2048).optional().catch(undefined);
|
|
7
10
|
// Cross-device try-first handover: an optional tenant-handover grant the signup-request
|
|
8
11
|
// route forwards to the handler for server-side verification and binding —
|
|
9
12
|
// the grant itself never appears anywhere else (URL, mail, log, response).
|
|
@@ -15,6 +18,7 @@ export const SignupRequestBody = z.object({
|
|
|
15
18
|
token: z.string().min(1).max(4096),
|
|
16
19
|
})
|
|
17
20
|
.optional(),
|
|
21
|
+
returnTo: returnToField,
|
|
18
22
|
});
|
|
19
23
|
// Shape guard for "handler not registered" — the only legitimate reason to
|
|
20
24
|
// fall back to a single-tenant reply on /auth/tenants or /auth/switch-tenant.
|
|
@@ -82,4 +86,5 @@ export function registerTokenRequestRoute(opts) {
|
|
|
82
86
|
// gains optional fields (locale, deviceId, …).
|
|
83
87
|
const RequestTokenBody = z.object({
|
|
84
88
|
email: z.email(),
|
|
89
|
+
returnTo: returnToField,
|
|
85
90
|
});
|
|
@@ -73,6 +73,8 @@ export function createClientErrorRoute(options) {
|
|
|
73
73
|
const app = new Hono();
|
|
74
74
|
const logger = createFallbackLogger("client-errors");
|
|
75
75
|
const routePath = `/api${Routes.clientErrors}`;
|
|
76
|
+
// Always on: the shared limiter fails open when Redis is down, this per-process window is the floor.
|
|
77
|
+
app.post(Routes.clientErrors, inMemoryIpRateLimit(options.clientIpResolver, options.now ?? Date.now));
|
|
76
78
|
if (options.resolver) {
|
|
77
79
|
app.post(Routes.clientErrors, httpRouteRateLimit({
|
|
78
80
|
resolver: options.resolver,
|
|
@@ -82,9 +84,6 @@ export function createClientErrorRoute(options) {
|
|
|
82
84
|
...(options.meter && { meter: options.meter }),
|
|
83
85
|
}));
|
|
84
86
|
}
|
|
85
|
-
else {
|
|
86
|
-
app.post(Routes.clientErrors, inMemoryIpRateLimit(options.clientIpResolver, options.now ?? Date.now));
|
|
87
|
-
}
|
|
88
87
|
app.post(Routes.clientErrors, bodyLimit({
|
|
89
88
|
maxSize: MAX_BODY_BYTES,
|
|
90
89
|
onError: (c) => c.json({ error: { code: "payload_too_large" } }, 413),
|
|
@@ -1,2 +1,5 @@
|
|
|
1
|
-
import type { AccessRule
|
|
1
|
+
import type { AccessRule } from "@cosmicdrift/kumiko-types/handlers";
|
|
2
|
+
import type { OwnershipMap } from "@cosmicdrift/kumiko-types/ownership";
|
|
3
|
+
import type { Registry } from "../engine/types/index.ts";
|
|
2
4
|
export declare function collectEntityReadAccess(registry: Registry): ReadonlyMap<string, readonly AccessRule[]>;
|
|
5
|
+
export declare function collectEntityRowReadMaps(registry: Registry): ReadonlyMap<string, OwnershipMap>;
|
|
@@ -25,3 +25,17 @@ export function collectEntityReadAccess(registry) {
|
|
|
25
25
|
}
|
|
26
26
|
return rulesByEntity;
|
|
27
27
|
}
|
|
28
|
+
// Entities whose own access.read narrows rows per role (e.g. Driver sees only assigned rows).
|
|
29
|
+
// A signal for such an entity must not name ids to a role that does not read every row.
|
|
30
|
+
export function collectEntityRowReadMaps(registry) {
|
|
31
|
+
const mapsByEntity = new Map();
|
|
32
|
+
for (const [entityName, entity] of registry.getAllEntities()) {
|
|
33
|
+
const readMap = entity.access?.read;
|
|
34
|
+
if (readMap === undefined || Object.keys(readMap).length === 0)
|
|
35
|
+
continue;
|
|
36
|
+
for (const aggregateType of new Set([entityName, toKebabCase(entityName)])) {
|
|
37
|
+
mapsByEntity.set(aggregateType, readMap);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return mapsByEntity;
|
|
41
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Cell } from "write-excel-file/node";
|
|
2
|
+
import type { ExportRow } from "./export-rows.ts";
|
|
3
|
+
export type ReferenceCellKind = {
|
|
4
|
+
readonly kind: "reference";
|
|
5
|
+
readonly labelField: string;
|
|
6
|
+
readonly multiple: boolean;
|
|
7
|
+
};
|
|
8
|
+
/** Labels come from the list row's eager-loaded `_refs`; a missing target shows its raw id. */
|
|
9
|
+
export declare function referenceCell(cell: ReferenceCellKind, field: string, row: ExportRow): Cell;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { isPlainObject } from "../../utils/is-plain-object.js";
|
|
2
|
+
function labelOf(ref, labelField) {
|
|
3
|
+
if (!isPlainObject(ref))
|
|
4
|
+
return undefined;
|
|
5
|
+
const label = ref[labelField];
|
|
6
|
+
return typeof label === "string" ? label : undefined;
|
|
7
|
+
}
|
|
8
|
+
function refsOf(row, field) {
|
|
9
|
+
const refs = row["_refs"];
|
|
10
|
+
return isPlainObject(refs) ? refs[field] : undefined;
|
|
11
|
+
}
|
|
12
|
+
/** Labels come from the list row's eager-loaded `_refs`; a missing target shows its raw id. */
|
|
13
|
+
export function referenceCell(cell, field, row) {
|
|
14
|
+
const ids = cell.multiple && Array.isArray(row[field]) ? row[field] : [row[field]];
|
|
15
|
+
const ref = refsOf(row, field);
|
|
16
|
+
const labels = ids.map((id) => {
|
|
17
|
+
const target = Array.isArray(ref) ? ref.find((r) => isPlainObject(r) && r["id"] === id) : ref;
|
|
18
|
+
return labelOf(target, cell.labelField) ?? String(id);
|
|
19
|
+
});
|
|
20
|
+
return { value: labels.join(", "), type: String };
|
|
21
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Cell } from "write-excel-file/node";
|
|
2
|
+
import type { ExportColumn } from "./export-columns.ts";
|
|
3
|
+
import type { ExportRow } from "./export-rows.ts";
|
|
4
|
+
export type Translate = (key: string) => string;
|
|
5
|
+
export type ExportCellContext = {
|
|
6
|
+
readonly row: ExportRow;
|
|
7
|
+
readonly translate: Translate;
|
|
8
|
+
readonly timeZone: string;
|
|
9
|
+
};
|
|
10
|
+
/** Never emits a formula cell and never reinterprets strings: text always stays text. */
|
|
11
|
+
export declare function toExportCell(column: ExportColumn, context: ExportCellContext): Cell;
|