@cosmicdrift/kumiko-framework 0.386.0 → 0.388.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 +6 -1
- package/LICENSE +21 -57
- package/README.md +2 -2
- package/agents/examples/anonymous-access.md +1 -1
- package/agents/examples/apex-landing.md +204 -0
- package/agents/examples/api-worker-split.md +64 -0
- package/agents/examples/app-config.md +14 -0
- package/agents/examples/auth-mfa.md +115 -0
- package/agents/examples/env-composition.md +28 -1
- package/agents/examples/legal-pages.md +1 -1
- package/agents/examples/prod-boot-options.md +16 -0
- package/agents/examples/rate-limiting.md +48 -0
- package/agents/examples/record-detail-layout.md +692 -0
- package/agents/examples/seed-migration.md +212 -0
- package/agents/examples/wizard-form.md +941 -0
- package/agents/examples/writeform-section.md +548 -0
- package/agents/features.md +19 -2
- package/agents/widgets.md +40 -39
- package/dist/api/api-constants.js +2 -2
- package/dist/api/auth-middleware.js +7 -7
- package/dist/api/auth-rate-limiters.js +7 -3
- package/dist/api/auth-routes-mfa.js +1 -1
- package/dist/api/auth-routes-session.js +1 -1
- package/dist/api/auth-routes-shared.js +7 -3
- package/dist/api/auth-routes-signup.js +1 -1
- package/dist/api/client-error-route.js +8 -2
- package/dist/api/client-ip.js +3 -1
- package/dist/api/extra-route.js +1 -1
- package/dist/api/index.d.ts +3 -1
- package/dist/api/index.js +3 -1
- package/dist/api/pii-leak-guard.js +4 -2
- package/dist/api/readiness.js +5 -5
- package/dist/api/redis-sse-broker.js +8 -6
- package/dist/api/request-context.d.ts +1 -1
- package/dist/api/request-context.js +1 -1
- package/dist/api/routes.js +2 -2
- package/dist/api/server-boot-checks.d.ts +10 -0
- package/dist/api/server-boot-checks.js +157 -0
- package/dist/api/server-event-dispatcher.d.ts +26 -0
- package/dist/api/server-event-dispatcher.js +208 -0
- package/dist/api/server-extra-routes.d.ts +11 -0
- package/dist/api/server-extra-routes.js +203 -0
- package/dist/api/server-middleware.d.ts +20 -0
- package/dist/api/server-middleware.js +211 -0
- package/dist/api/server-routes.d.ts +19 -0
- package/dist/api/server-routes.js +293 -0
- package/dist/api/server-websocket-routes.d.ts +4 -0
- package/dist/api/server-websocket-routes.js +108 -0
- package/dist/api/server-wiring.d.ts +32 -0
- package/dist/api/server-wiring.js +236 -0
- package/dist/api/server.d.ts +10 -15
- package/dist/api/server.js +48 -1250
- package/dist/api/session-cookies.js +4 -4
- package/dist/api/sse-broker.js +1 -1
- package/dist/api/sse-route.d.ts +13 -13
- package/dist/api/sse-route.js +31 -27
- package/dist/auth/index.js +4 -4
- package/dist/auth/roles.d.ts +4 -4
- package/dist/auth/roles.js +24 -24
- package/dist/compliance/duration-spec.js +18 -20
- package/dist/compliance/index.js +2 -3
- package/dist/compliance/override-schema.d.ts +4 -4
- package/dist/compliance/override-schema.js +19 -22
- package/dist/compliance/profiles.d.ts +26 -29
- package/dist/compliance/profiles.js +62 -69
- package/dist/compliance/sub-processors.d.ts +28 -30
- package/dist/compliance/sub-processors.js +17 -21
- package/dist/consumer-cli.js +4 -4
- package/dist/crypto/blind-index.js +18 -17
- package/dist/crypto/ciphertext-pattern.js +1 -1
- package/dist/crypto/event-pii.js +3 -3
- package/dist/crypto/kek-source.d.ts +1 -1
- package/dist/crypto/kek-source.js +3 -2
- package/dist/crypto/kms-adapter.d.ts +1 -1
- package/dist/crypto/kms-adapter.js +4 -6
- package/dist/crypto/kms-wiring.d.ts +1 -2
- package/dist/crypto/kms-wiring.js +2 -2
- package/dist/crypto/owner-transition-rekey.d.ts +5 -1
- package/dist/crypto/owner-transition-rekey.js +1 -1
- package/dist/crypto/pg-kms-adapter.js +2 -6
- package/dist/crypto/pii-field-encryption.d.ts +5 -1
- package/dist/crypto/pii-field-encryption.js +7 -5
- package/dist/crypto/subject-resolver.d.ts +1 -1
- package/dist/crypto/subject-resolver.js +2 -2
- package/dist/db/aggregate-sql.d.ts +21 -0
- package/dist/db/aggregate-sql.js +155 -0
- package/dist/db/apply-entity-event.d.ts +6 -6
- package/dist/db/apply-entity-event.js +55 -55
- package/dist/db/blind-index-cleanup.js +7 -7
- package/dist/db/closed-connection.d.ts +9 -0
- package/dist/db/closed-connection.js +95 -0
- package/dist/db/collect-table-metas.js +10 -11
- package/dist/db/compound-types.d.ts +1 -1
- package/dist/db/compound-types.js +12 -12
- package/dist/db/cursor.js +3 -4
- package/dist/db/dialect.d.ts +2 -2
- package/dist/db/dialect.js +3 -3
- package/dist/db/distinct-on.d.ts +1 -1
- package/dist/db/driver-row-coercion.d.ts +2 -0
- package/dist/db/driver-row-coercion.js +186 -0
- package/dist/db/driver-value-preparation.d.ts +16 -0
- package/dist/db/driver-value-preparation.js +99 -0
- package/dist/db/eagerload.d.ts +3 -3
- package/dist/db/eagerload.js +21 -12
- package/dist/db/entity-field-encryption.d.ts +1 -0
- package/dist/db/entity-field-encryption.js +1 -1
- package/dist/db/entity-table-meta.d.ts +2 -2
- package/dist/db/entity-table-meta.js +105 -112
- package/dist/db/event-store-executor-context.d.ts +3 -2
- package/dist/db/event-store-executor-context.js +13 -13
- package/dist/db/event-store-executor-read-aggregate.d.ts +8 -0
- package/dist/db/event-store-executor-read-aggregate.js +112 -0
- package/dist/db/event-store-executor-read-filter.d.ts +31 -0
- package/dist/db/event-store-executor-read-filter.js +203 -0
- package/dist/db/event-store-executor-read-paging.d.ts +14 -0
- package/dist/db/event-store-executor-read-paging.js +99 -0
- package/dist/db/event-store-executor-read-rows.d.ts +6 -0
- package/dist/db/event-store-executor-read-rows.js +32 -0
- package/dist/db/event-store-executor-read-search.d.ts +28 -0
- package/dist/db/event-store-executor-read-search.js +221 -0
- package/dist/db/event-store-executor-read-sort.d.ts +41 -0
- package/dist/db/event-store-executor-read-sort.js +130 -0
- package/dist/db/event-store-executor-read-where.d.ts +24 -0
- package/dist/db/event-store-executor-read-where.js +81 -0
- package/dist/db/event-store-executor-read.d.ts +2 -9
- package/dist/db/event-store-executor-read.js +50 -704
- package/dist/db/event-store-executor-write-steps.d.ts +20 -0
- package/dist/db/event-store-executor-write-steps.js +100 -0
- package/dist/db/event-store-executor-write.js +401 -510
- package/dist/db/index.d.ts +6 -2
- package/dist/db/index.js +5 -1
- package/dist/db/list-aggregate-labels.d.ts +14 -0
- package/dist/db/list-aggregate-labels.js +26 -0
- package/dist/db/located-timestamp.d.ts +11 -11
- package/dist/db/located-timestamp.js +29 -30
- package/dist/db/migrate-generator.d.ts +1 -1
- package/dist/db/migrate-generator.js +97 -105
- package/dist/db/migrate-runner.js +29 -26
- package/dist/db/money.d.ts +6 -6
- package/dist/db/money.js +29 -27
- package/dist/db/queries/backfill-pii.js +5 -5
- package/dist/db/queries/ddl.js +1 -1
- package/dist/db/queries/es-ops.d.ts +1 -1
- package/dist/db/queries/es-ops.js +1 -1
- package/dist/db/queries/event-consumer.js +3 -3
- package/dist/db/queries/event-store.js +4 -2
- package/dist/db/queries/projection-rebuild.js +3 -3
- package/dist/db/queries/raw-sql.d.ts +2 -2
- package/dist/db/queries/raw-sql.js +2 -2
- package/dist/db/queries/shadow-swap.js +19 -19
- package/dist/db/query.d.ts +3 -16
- package/dist/db/query.js +8 -761
- package/dist/db/rebuild-marker.js +20 -21
- package/dist/db/reference-data.js +6 -1
- package/dist/db/replay-migration-sql.js +2 -2
- package/dist/db/schema-inspection.js +4 -5
- package/dist/db/table-builder.d.ts +1 -2
- package/dist/db/table-builder.js +137 -190
- package/dist/db/table-info.d.ts +10 -0
- package/dist/db/table-info.js +45 -0
- package/dist/db/temporal-value-guards.d.ts +6 -0
- package/dist/db/temporal-value-guards.js +15 -0
- package/dist/db/tenant-db-runner.d.ts +1 -0
- package/dist/db/tenant-db-runner.js +3 -0
- package/dist/db/tenant-db.d.ts +2 -2
- package/dist/db/tenant-db.js +48 -11
- package/dist/db/where-clause.d.ts +6 -0
- package/dist/db/where-clause.js +236 -0
- package/dist/derivatives/delete-stored-file.js +6 -2
- package/dist/derivatives/derivatives-context.js +1 -1
- package/dist/engine/boot-validator/access-roles.js +4 -3
- package/dist/engine/boot-validator/api-ext.js +14 -14
- package/dist/engine/boot-validator/boot-check.js +1 -1
- package/dist/engine/boot-validator/config-deps.js +7 -6
- package/dist/engine/boot-validator/detail-screens.js +4 -4
- package/dist/engine/boot-validator/entity-handler.d.ts +1 -0
- package/dist/engine/boot-validator/entity-handler.js +77 -61
- package/dist/engine/boot-validator/form-derivations.js +35 -1
- package/dist/engine/boot-validator/gdpr-storage.js +4 -4
- package/dist/engine/boot-validator/i18n-keys.js +6 -4
- package/dist/engine/boot-validator/index.d.ts +2 -2
- package/dist/engine/boot-validator/index.js +22 -20
- package/dist/engine/boot-validator/nav.js +5 -5
- package/dist/engine/boot-validator/ownership.js +12 -9
- package/dist/engine/boot-validator/parent-ref.js +1 -1
- package/dist/engine/boot-validator/pii-retention.js +258 -187
- package/dist/engine/boot-validator/projection-list-screens.js +7 -7
- package/dist/engine/boot-validator/query-refs.js +1 -1
- package/dist/engine/boot-validator/screens-actions.d.ts +1 -0
- package/dist/engine/boot-validator/screens-actions.js +23 -17
- package/dist/engine/boot-validator/screens-dashboard.js +2 -5
- package/dist/engine/boot-validator/screens-forms.js +12 -17
- package/dist/engine/boot-validator/screens-kind-config-edit.d.ts +3 -0
- package/dist/engine/boot-validator/screens-kind-config-edit.js +88 -0
- package/dist/engine/boot-validator/screens-kind-entity-edit.d.ts +3 -0
- package/dist/engine/boot-validator/screens-kind-entity-edit.js +55 -0
- package/dist/engine/boot-validator/screens-kind-entity-list.d.ts +3 -0
- package/dist/engine/boot-validator/screens-kind-entity-list.js +228 -0
- package/dist/engine/boot-validator/screens-kind-projection-detail.d.ts +3 -0
- package/dist/engine/boot-validator/screens-kind-projection-detail.js +235 -0
- package/dist/engine/boot-validator/screens-kind-projection-list.d.ts +3 -0
- package/dist/engine/boot-validator/screens-kind-projection-list.js +52 -0
- package/dist/engine/boot-validator/screens-kind-secret-mint.d.ts +3 -0
- package/dist/engine/boot-validator/screens-kind-secret-mint.js +28 -0
- package/dist/engine/boot-validator/screens-kind-shared.d.ts +37 -0
- package/dist/engine/boot-validator/screens-kind-shared.js +142 -0
- package/dist/engine/boot-validator/screens-lists.d.ts +2 -1
- package/dist/engine/boot-validator/screens-lists.js +26 -24
- package/dist/engine/boot-validator/screens.d.ts +0 -2
- package/dist/engine/boot-validator/screens.js +102 -869
- package/dist/engine/boot-validator/security-baseline.js +3 -2
- package/dist/engine/boot-validator/transfer-graph.js +2 -2
- package/dist/engine/boot-validator/workspaces.js +3 -3
- package/dist/engine/bridge-stub.js +3 -4
- package/dist/engine/build-app-schema.js +130 -170
- package/dist/engine/build-config-feature-schema.js +50 -50
- package/dist/engine/build-target.js +20 -23
- package/dist/engine/codemod/pipeline-codemod.js +20 -13
- package/dist/engine/config-helpers.js +4 -4
- package/dist/engine/constants.js +2 -2
- package/dist/engine/create-app.js +2 -2
- package/dist/engine/define-feature.js +21 -13
- package/dist/engine/define-handler.js +13 -11
- package/dist/engine/define-step.js +1 -1
- package/dist/engine/define-workflow.d.ts +5 -5
- package/dist/engine/define-workflow.js +6 -6
- package/dist/engine/entity-handlers.d.ts +13 -0
- package/dist/engine/entity-handlers.js +22 -34
- package/dist/engine/entity-list-runtime-options.d.ts +8 -0
- package/dist/engine/entity-list-runtime-options.js +18 -0
- package/dist/engine/event-def.js +2 -2
- package/dist/engine/extension-names.d.ts +16 -17
- package/dist/engine/extension-names.js +37 -38
- package/dist/engine/extensions/escape-hatch-usage.js +1 -1
- package/dist/engine/extensions/tenant-data.js +2 -2
- package/dist/engine/extensions/user-data.d.ts +23 -24
- package/dist/engine/factories.d.ts +14 -13
- package/dist/engine/factories.js +38 -37
- package/dist/engine/feature-ast/entity-field-types.js +1 -1
- package/dist/engine/feature-ast/extractors/handlers.js +2 -1
- package/dist/engine/feature-ast/extractors/hooks.js +1 -1
- package/dist/engine/feature-ast/extractors/round2.js +25 -6
- package/dist/engine/feature-ast/extractors/shared.d.ts +2 -3
- package/dist/engine/feature-ast/extractors/shared.js +2 -3
- package/dist/engine/feature-ast/parse.js +13 -13
- package/dist/engine/feature-ast/patch.js +4 -182
- package/dist/engine/feature-ast/pattern-change-schema.d.ts +3 -0
- package/dist/engine/feature-ast/pattern-change-schema.js +2 -1
- package/dist/engine/feature-ast/pattern-id-matchers.d.ts +7 -0
- package/dist/engine/feature-ast/pattern-id-matchers.js +210 -0
- package/dist/engine/feature-ast/patterns.d.ts +11 -2
- package/dist/engine/feature-ast/patterns.js +43 -51
- package/dist/engine/feature-ast/render.js +50 -89
- package/dist/engine/feature-config-events-jobs.js +15 -12
- package/dist/engine/feature-entity-handlers.js +12 -5
- package/dist/engine/feature-manifest.d.ts +9 -9
- package/dist/engine/feature-manifest.js +6 -7
- package/dist/engine/feature-ui-extensions.d.ts +3 -3
- package/dist/engine/feature-ui-extensions.js +30 -22
- package/dist/engine/field-access.js +5 -6
- package/dist/engine/form-derivations.js +18 -7
- package/dist/engine/handler-field-references.js +1 -1
- package/dist/engine/index.d.ts +1 -0
- package/dist/engine/index.js +4 -4
- package/dist/engine/object-form.d.ts +1 -0
- package/dist/engine/object-form.js +14 -4
- package/dist/engine/ownership.js +3 -3
- package/dist/engine/parse-ref-target.js +5 -7
- package/dist/engine/pattern-library/index.js +2 -2
- package/dist/engine/pattern-library/library.js +2 -2
- package/dist/engine/pattern-library/types.js +3 -3
- package/dist/engine/pipeline.js +2 -2
- package/dist/engine/project-app-schema-for-roles.d.ts +2 -0
- package/dist/engine/project-app-schema-for-roles.js +7 -5
- package/dist/engine/projection-helpers.js +9 -9
- package/dist/engine/qualified-name.js +2 -2
- package/dist/engine/registry-facade.js +1 -1
- package/dist/engine/registry-ingest.js +13 -13
- package/dist/engine/registry-state.js +17 -19
- package/dist/engine/registry-validate.js +12 -12
- package/dist/engine/run-in.js +2 -2
- package/dist/engine/run-pipeline.js +7 -0
- package/dist/engine/schema-builder.js +251 -233
- package/dist/engine/screen-filter-ops.js +17 -20
- package/dist/engine/screen-helpers.js +4 -3
- package/dist/engine/screen-kind.d.ts +7 -0
- package/dist/engine/screen-kind.js +1 -0
- package/dist/engine/state-machine.d.ts +12 -12
- package/dist/engine/state-machine.js +7 -7
- package/dist/engine/steps/_resolver-utils.js +4 -3
- package/dist/engine/steps/for-each.js +4 -4
- package/dist/engine/steps/unsafe-projection-delete.js +1 -1
- package/dist/engine/steps/unsafe-projection-upsert.js +4 -4
- package/dist/engine/steps/wait-for-event.js +4 -4
- package/dist/engine/steps/workflow-system-events.js +3 -3
- package/dist/engine/strip-disabled-features-from-app-schema.js +51 -14
- package/dist/engine/tier-resolver-extension.d.ts +29 -27
- package/dist/engine/tier-resolver-extension.js +26 -26
- package/dist/engine/transfer-adjacency.js +2 -2
- package/dist/engine/validate-projection-allowlist.js +9 -28
- package/dist/engine/walk-step-instances.d.ts +2 -0
- package/dist/engine/walk-step-instances.js +38 -0
- package/dist/engine/where-rule-lint.js +1 -1
- package/dist/engine/write-handler-qn-extract.js +1 -1
- package/dist/entrypoint/index.d.ts +4 -1
- package/dist/entrypoint/index.js +10 -4
- package/dist/env/index.d.ts +7 -6
- package/dist/env/index.js +10 -9
- package/dist/errors/docs-url.d.ts +1 -1
- package/dist/errors/docs-url.js +22 -2
- package/dist/errors/transition-details.js +7 -7
- package/dist/errors/write-error-info.d.ts +6 -6
- package/dist/errors/write-error-info.js +6 -6
- package/dist/es-ops/context.d.ts +9 -9
- package/dist/es-ops/context.js +29 -29
- package/dist/es-ops/index.js +7 -9
- package/dist/es-ops/operations-schema.js +4 -10
- package/dist/es-ops/runner.d.ts +11 -11
- package/dist/es-ops/runner.js +49 -53
- package/dist/es-ops/types.d.ts +55 -55
- package/dist/es-ops/types.js +11 -11
- package/dist/event-store/admin-api.js +7 -8
- package/dist/event-store/errors.js +1 -1
- package/dist/event-store/event-store.js +12 -6
- package/dist/event-store/rebuild-dead-letter.js +1 -1
- package/dist/files/bind-pending-file-refs.js +3 -3
- package/dist/files/create-file-ref-from-bytes.js +4 -1
- package/dist/files/feature.js +9 -10
- package/dist/files/file-handle.js +7 -9
- package/dist/files/file-ref-entity.js +15 -15
- package/dist/files/file-ref-table.js +7 -8
- package/dist/files/file-routes.d.ts +7 -0
- package/dist/files/file-routes.js +22 -13
- package/dist/files/in-memory-provider.js +8 -9
- package/dist/files/local-provider.js +18 -25
- package/dist/files/provider-resolver.d.ts +7 -7
- package/dist/files/resolve-content-type.js +43 -0
- package/dist/files/storage-tracking.js +2 -2
- package/dist/files/upload-ledger.js +7 -0
- package/dist/files/zip-stream.d.ts +12 -19
- package/dist/files/zip-stream.js +44 -63
- package/dist/i18n/required-surface-keys.d.ts +1 -1
- package/dist/i18n/required-surface-keys.js +188 -212
- package/dist/internal/stack-support.d.ts +2 -1
- package/dist/internal/stack-support.js +1 -1
- package/dist/jobs/job-runner-context.d.ts +32 -0
- package/dist/jobs/job-runner-context.js +305 -0
- package/dist/jobs/job-runner-execution.d.ts +7 -0
- package/dist/jobs/job-runner-execution.js +160 -0
- package/dist/jobs/job-runner-gates.d.ts +19 -0
- package/dist/jobs/job-runner-gates.js +198 -0
- package/dist/jobs/job-runner-helpers.d.ts +17 -3
- package/dist/jobs/job-runner-helpers.js +69 -4
- package/dist/jobs/job-runner-schedulers.d.ts +1 -1
- package/dist/jobs/job-runner-schedulers.js +3 -4
- package/dist/jobs/job-runner-scope.d.ts +44 -0
- package/dist/jobs/job-runner-scope.js +102 -0
- package/dist/jobs/job-runner-types.d.ts +12 -0
- package/dist/jobs/job-runner.d.ts +0 -1
- package/dist/jobs/job-runner.js +57 -669
- package/dist/lifecycle/lifecycle.js +3 -5
- package/dist/lifecycle/signal-handlers.js +5 -4
- package/dist/logging/utils.d.ts +2 -1
- package/dist/logging/utils.js +38 -10
- package/dist/migrations/index.js +1 -1
- package/dist/migrations/kumiko-drift.js +14 -13
- package/dist/migrations/pending-rebuilds.d.ts +21 -20
- package/dist/migrations/pending-rebuilds.js +27 -27
- package/dist/migrations/projection-table-index.d.ts +3 -3
- package/dist/migrations/projection-table-index.js +8 -8
- package/dist/observability/escape-hatch-report.d.ts +3 -0
- package/dist/observability/escape-hatch-report.js +12 -1
- package/dist/observability/metric-validator.js +1 -1
- package/dist/observability/metrics-handle.js +3 -3
- package/dist/pipeline/append-event-core.js +11 -2
- package/dist/pipeline/cascade-handler.d.ts +1 -1
- package/dist/pipeline/cascade-handler.js +165 -138
- package/dist/pipeline/dispatch-batch.js +2 -2
- package/dist/pipeline/dispatch-query.js +20 -13
- package/dist/pipeline/dispatch-shared.d.ts +14 -3
- package/dist/pipeline/dispatch-shared.js +67 -721
- package/dist/pipeline/dispatch-stream.js +1 -1
- package/dist/pipeline/dispatch-write.js +297 -190
- package/dist/pipeline/dispatcher-utils.d.ts +1 -1
- package/dist/pipeline/dispatcher-utils.js +1 -1
- package/dist/pipeline/event-consumer-state.js +2 -2
- package/dist/pipeline/event-dispatcher-admin.js +2 -1
- package/dist/pipeline/event-dispatcher-delivery.js +4 -6
- package/dist/pipeline/event-dispatcher.js +17 -28
- package/dist/pipeline/handler-context-auth.d.ts +9 -0
- package/dist/pipeline/handler-context-auth.js +54 -0
- package/dist/pipeline/handler-context-config.d.ts +14 -0
- package/dist/pipeline/handler-context-config.js +113 -0
- package/dist/pipeline/handler-context-db.d.ts +24 -0
- package/dist/pipeline/handler-context-db.js +149 -0
- package/dist/pipeline/handler-context-dispatch.d.ts +21 -0
- package/dist/pipeline/handler-context-dispatch.js +89 -0
- package/dist/pipeline/handler-context-events.d.ts +43 -0
- package/dist/pipeline/handler-context-events.js +237 -0
- package/dist/pipeline/handler-context-notify.d.ts +12 -0
- package/dist/pipeline/handler-context-notify.js +55 -0
- package/dist/pipeline/handler-context-observability.d.ts +7 -0
- package/dist/pipeline/handler-context-observability.js +21 -0
- package/dist/pipeline/handler-context-scope.d.ts +48 -0
- package/dist/pipeline/handler-context-scope.js +88 -0
- package/dist/pipeline/irreversible-operation-gate.js +1 -1
- package/dist/pipeline/lifecycle-pipeline.js +9 -9
- package/dist/pipeline/member-read-only-transaction.js +1 -3
- package/dist/pipeline/msp-rebuild.js +1 -1
- package/dist/pipeline/notify-scope.js +12 -1
- package/dist/pipeline/pre-handler-gates.js +20 -4
- package/dist/pipeline/pre-transaction-reservations.d.ts +1 -0
- package/dist/pipeline/pre-transaction-reservations.js +9 -3
- package/dist/pipeline/projection-rebuild.js +15 -13
- package/dist/pipeline/system-hooks.js +39 -41
- package/dist/pipeline/system-identity-switch.js +1 -3
- package/dist/pipeline/tenant-timezone-cache.js +1 -1
- package/dist/random/generate.d.ts +29 -29
- package/dist/random/generate.js +30 -30
- package/dist/random/words.js +20 -20
- package/dist/rate-limit/middleware.js +9 -5
- package/dist/redis/client.js +2 -2
- package/dist/redis/pubsub-signal.js +14 -17
- package/dist/schema-cli/apply-command.d.ts +2 -0
- package/dist/schema-cli/apply-command.js +97 -0
- package/dist/schema-cli/baseline-command.d.ts +2 -0
- package/dist/schema-cli/baseline-command.js +33 -0
- package/dist/schema-cli/generate-command.d.ts +2 -0
- package/dist/schema-cli/generate-command.js +90 -0
- package/dist/schema-cli/shared.d.ts +39 -0
- package/dist/schema-cli/shared.js +95 -0
- package/dist/schema-cli/status-command.d.ts +2 -0
- package/dist/schema-cli/status-command.js +73 -0
- package/dist/schema-cli/validate-boot-input.d.ts +5 -0
- package/dist/schema-cli/validate-boot-input.js +130 -0
- package/dist/schema-cli/validate-command.d.ts +2 -0
- package/dist/schema-cli/validate-command.js +130 -0
- package/dist/schema-cli.d.ts +2 -18
- package/dist/schema-cli.js +47 -510
- package/dist/search/index.js +4 -4
- package/dist/search/meilisearch-adapter.js +2 -1
- package/dist/search/purge-subject.js +4 -5
- package/dist/search/reindex-entity.js +6 -9
- package/dist/time/boot-tz-warning.d.ts +2 -2
- package/dist/time/boot-tz-warning.js +8 -8
- package/dist/time/iana.js +10 -10
- package/dist/time/index.js +9 -9
- package/dist/time/legacy-date.d.ts +2 -2
- package/dist/time/legacy-date.js +6 -8
- package/dist/time/polyfill.js +1 -1
- package/dist/time/tz-context.d.ts +1 -1
- package/dist/time/tz-context.js +1 -1
- package/dist/ui-types/app-schema.js +7 -7
- package/dist/ui-types/list-row-meta.js +4 -4
- package/dist/upgrade-cli.js +159 -130
- package/dist/utils/compare.js +1 -1
- package/package.json +5 -5
- package/src/changes.json +358 -0
- package/src/scripts/codemod/crypto-shredding-testing-move.ts +2 -2
- package/src/scripts/codemod/feature-layout.ts +10 -2
- package/src/scripts/codemod/migrate-cross-tenant.ts +1 -1
- package/src/scripts/codemod/migrate-open-to-all.ts +1 -1
- package/src/scripts/codemod/object-form.ts +41 -4
- package/src/scripts/codemod/package-merge.ts +58 -8
- package/src/scripts/codemod/pii-personal-migration.ts +192 -153
- package/src/scripts/codemod/testing-injection.ts +122 -42
- package/src/scripts/codemod/testing-move.ts +29 -7
- package/src/scripts/codemod/unprocessable-error-details-reason.ts +2 -2
|
@@ -48,10 +48,10 @@ export type ManifestFeature = {
|
|
|
48
48
|
readonly extensionsUsed: readonly ManifestExtension[];
|
|
49
49
|
readonly configKeys: readonly ManifestConfigKey[];
|
|
50
50
|
readonly secrets: readonly ManifestSecret[];
|
|
51
|
-
/**
|
|
52
|
-
* (
|
|
53
|
-
*
|
|
54
|
-
*
|
|
51
|
+
/** All registered write-handler QNs for this feature
|
|
52
|
+
* (e.g. "user:write:user:create", "auth-email-password:write:login").
|
|
53
|
+
* Derived from `collectWriteHandlerQns` and used as the source of truth
|
|
54
|
+
* for client-side type checking of `dispatcher.write` calls. */
|
|
55
55
|
readonly writeHandlers: readonly string[];
|
|
56
56
|
/** Picker/scaffolder UI metadata declared via r.uiHints(). Optional —
|
|
57
57
|
* absent for features that haven't been annotated yet (the picker falls
|
|
@@ -68,13 +68,13 @@ export type FeatureManifest = {
|
|
|
68
68
|
readonly tier?: string;
|
|
69
69
|
};
|
|
70
70
|
export type BuildManifestOptions = {
|
|
71
|
-
/**
|
|
71
|
+
/** Description of the manifest's origin, included unchanged in the JSON. */
|
|
72
72
|
readonly source: string;
|
|
73
|
-
/**
|
|
74
|
-
* Registry
|
|
75
|
-
*
|
|
73
|
+
/** Emit only these features (e.g. the 16 enterprise features from a
|
|
74
|
+
* Registry that also mounted their bundled requirements). Default:
|
|
75
|
+
* all features in the Registry. */
|
|
76
76
|
readonly featureNames?: ReadonlySet<string>;
|
|
77
|
-
/**
|
|
77
|
+
/** Tags each feature and the top-level manifest (e.g. "enterprise"). */
|
|
78
78
|
readonly tier?: string;
|
|
79
79
|
};
|
|
80
80
|
export declare function buildManifestFromRegistry(registry: Registry, options: BuildManifestOptions): FeatureManifest;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
// Runtime-introspected feature
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// lesen.
|
|
1
|
+
// Runtime-introspected feature manifest — shared extraction logic for
|
|
2
|
+
// `gen-feature-manifest.ts` (use-all-bundled) and the enterprise generator.
|
|
3
|
+
// These were previously two nearly identical forks with diverging schemas:
|
|
4
|
+
// when framework introspection was extended, the copy silently drifted. The
|
|
5
|
+
// booted Registry is authoritative because the AST parser cannot read the
|
|
6
|
+
// imperative factory helpers of bundled features.
|
|
8
7
|
import { SYSTEM_EVENT_PREFIX } from "../crypto/system-event-pii.js";
|
|
9
8
|
import { compareByCodepoint } from "../utils/index.js";
|
|
10
9
|
import { isEncryptedAtRest } from "./config-helpers.js";
|
|
@@ -38,9 +38,9 @@ export declare function buildUiExtensionsMethods<TName extends string>(state: Fe
|
|
|
38
38
|
*/
|
|
39
39
|
exposesApi(apiName: string): void;
|
|
40
40
|
/**
|
|
41
|
-
* Declares that this feature calls a cross-feature API.
|
|
42
|
-
*
|
|
43
|
-
*
|
|
41
|
+
* Declares that this feature calls a cross-feature API. The boot validator
|
|
42
|
+
* checks that another feature calls `r.exposesApi(name)` and that this
|
|
43
|
+
* feature declares a corresponding `r.requires` dependency.
|
|
44
44
|
*/
|
|
45
45
|
usesApi(apiName: string): void;
|
|
46
46
|
bootCheck(fn: BootCheckFn): void;
|
|
@@ -6,7 +6,7 @@ import { bindHookEscapeHatchGrant } from "../pipeline/system-identity-switch.js"
|
|
|
6
6
|
import { LifecycleHookTypes } from "./constants.js";
|
|
7
7
|
import { reasonProblem } from "./escape-hatch-reason.js";
|
|
8
8
|
import { resolveName } from "./handler-helpers.js";
|
|
9
|
-
import { isObjectArgument, throwObjectArgumentRequired } from "./object-form.js";
|
|
9
|
+
import { isObjectArgument, requireArgument, throwObjectArgumentRequired } from "./object-form.js";
|
|
10
10
|
import { isKebabSegment, isValidQn, qualifyEntityName, toKebab } from "./qualified-name.js";
|
|
11
11
|
import { HookPhases } from "./types/index.js";
|
|
12
12
|
// Builds hooks/extensions/projections/screens/nav/workspace/tables/tree-actions
|
|
@@ -159,7 +159,7 @@ export function buildUiExtensionsMethods(state, name) {
|
|
|
159
159
|
}
|
|
160
160
|
const targets = Array.isArray(target) ? target : [target];
|
|
161
161
|
const names = targets.map(resolveName);
|
|
162
|
-
//
|
|
162
|
+
// All hook-function casts below: @cast-boundary engine-bridge
|
|
163
163
|
// — typed Dev-API (LifecycleHookFn|ValidationHookFn) → erased Map<name, fn>.
|
|
164
164
|
if (type === "validation") {
|
|
165
165
|
for (const n of names) {
|
|
@@ -211,7 +211,11 @@ export function buildUiExtensionsMethods(state, name) {
|
|
|
211
211
|
},
|
|
212
212
|
useExtension(extensionNameOrDefinition, entityRef, options) {
|
|
213
213
|
const [extensionName, resolvedEntityRef, resolvedOptions] = typeof extensionNameOrDefinition === "string"
|
|
214
|
-
? [
|
|
214
|
+
? [
|
|
215
|
+
extensionNameOrDefinition,
|
|
216
|
+
requireArgument(entityRef, name, "useExtension", "entity"),
|
|
217
|
+
options,
|
|
218
|
+
]
|
|
215
219
|
: (() => {
|
|
216
220
|
const { name, entity, ...rest } = extensionNameOrDefinition;
|
|
217
221
|
return [name, entity, rest];
|
|
@@ -219,13 +223,14 @@ export function buildUiExtensionsMethods(state, name) {
|
|
|
219
223
|
const resolvedEntityName = resolveName(resolvedEntityRef);
|
|
220
224
|
// @cast-boundary engine-bridge — typed per-extension options → erased registration bag
|
|
221
225
|
const optionsBag = resolvedOptions;
|
|
222
|
-
//
|
|
226
|
+
// Cross-cutting escapeHatch convention for hook-context db
|
|
223
227
|
// access (mirrors r.hook's validation above). Validated the same way
|
|
224
228
|
// for every extension regardless of its typed hook shape.
|
|
225
229
|
const escapeHatch = optionsBag?.["escapeHatch"];
|
|
226
230
|
if (escapeHatch !== undefined) {
|
|
227
|
-
const
|
|
228
|
-
|
|
231
|
+
const escapeHatchObject = isPlainObject(escapeHatch) ? escapeHatch : undefined;
|
|
232
|
+
const reason = escapeHatchObject?.["reason"];
|
|
233
|
+
if (escapeHatchObject === undefined || typeof reason !== "string") {
|
|
229
234
|
throw new Error(`[Feature ${name}] r.useExtension("${extensionName}", "${resolvedEntityName}", ...) declares an invalid { escapeHatch } — ` +
|
|
230
235
|
`must be { reason: "<explanation>" } explaining why this usage needs unfiltered db access.`);
|
|
231
236
|
}
|
|
@@ -233,7 +238,7 @@ export function buildUiExtensionsMethods(state, name) {
|
|
|
233
238
|
if (extReasonProblem !== undefined) {
|
|
234
239
|
throw new Error(`[Feature ${name}] r.useExtension("${extensionName}", "${resolvedEntityName}", ...) declares an invalid { escapeHatch } — ${extReasonProblem}`);
|
|
235
240
|
}
|
|
236
|
-
const extGrantsProblem = escapeHatchGrantsProblem(
|
|
241
|
+
const extGrantsProblem = escapeHatchGrantsProblem(escapeHatchObject);
|
|
237
242
|
if (extGrantsProblem) {
|
|
238
243
|
throw new Error(`[Feature ${name}] r.useExtension("${extensionName}", "${resolvedEntityName}", ...) declares an invalid { escapeHatch } — ${extGrantsProblem}`);
|
|
239
244
|
}
|
|
@@ -282,9 +287,9 @@ export function buildUiExtensionsMethods(state, name) {
|
|
|
282
287
|
state.exposedApis.add(apiName);
|
|
283
288
|
},
|
|
284
289
|
/**
|
|
285
|
-
* Declares that this feature calls a cross-feature API.
|
|
286
|
-
*
|
|
287
|
-
*
|
|
290
|
+
* Declares that this feature calls a cross-feature API. The boot validator
|
|
291
|
+
* checks that another feature calls `r.exposesApi(name)` and that this
|
|
292
|
+
* feature declares a corresponding `r.requires` dependency.
|
|
288
293
|
*/
|
|
289
294
|
usesApi(apiName) {
|
|
290
295
|
state.usedApis.add(apiName);
|
|
@@ -344,7 +349,11 @@ export function buildUiExtensionsMethods(state, name) {
|
|
|
344
349
|
entityRefOrDefinition.data,
|
|
345
350
|
entityRefOrDefinition.upsertKey,
|
|
346
351
|
]
|
|
347
|
-
: [
|
|
352
|
+
: [
|
|
353
|
+
entityRefOrDefinition,
|
|
354
|
+
requireArgument(data, name, "referenceData", "data"),
|
|
355
|
+
options?.upsertKey,
|
|
356
|
+
];
|
|
348
357
|
state.referenceData.push({
|
|
349
358
|
entityName: resolveName(entityRef),
|
|
350
359
|
data: resolvedData,
|
|
@@ -424,10 +433,9 @@ export function buildUiExtensionsMethods(state, name) {
|
|
|
424
433
|
state.workspaces[definition.id] = definition;
|
|
425
434
|
},
|
|
426
435
|
httpRoute(definition) {
|
|
427
|
-
// Path
|
|
428
|
-
//
|
|
429
|
-
//
|
|
430
|
-
// das ausgesprochen hat — bewusster Block).
|
|
436
|
+
// Path validation: must start with "/"; /api/ routes are reserved for the
|
|
437
|
+
// dispatcher. An HTTP route occupying /api/foo could bypass the auth
|
|
438
|
+
// middleware without the author explicitly intending it, so block it.
|
|
431
439
|
if (!definition.path.startsWith("/")) {
|
|
432
440
|
throw new Error(`[Feature ${name}] httpRoute path "${definition.path}" must start with "/". ` +
|
|
433
441
|
`Got "${definition.path}".`);
|
|
@@ -505,7 +513,7 @@ export function buildUiExtensionsMethods(state, name) {
|
|
|
505
513
|
}
|
|
506
514
|
// `read_` is reserved for r.entity()/r.projection() (managed,
|
|
507
515
|
// event-sourced, rebuildable). storeTable is the unmanaged
|
|
508
|
-
// direct-write escape hatch — the prefix must say so
|
|
516
|
+
// direct-write escape hatch — the prefix must say so.
|
|
509
517
|
if (tableName.startsWith("read_")) {
|
|
510
518
|
throw new Error(`[Feature ${name}] r.storeTable("${tableName}"): the "read_" prefix is reserved ` +
|
|
511
519
|
`for managed r.entity()/r.projection() tables. Pick an unprefixed name or a ` +
|
|
@@ -514,7 +522,7 @@ export function buildUiExtensionsMethods(state, name) {
|
|
|
514
522
|
// meta.source must agree with the r.storeTable() escape hatch, or the
|
|
515
523
|
// migrate-generator treats schema drift on this table as safe to
|
|
516
524
|
// DROP+rebuild-from-events — wiping direct-write data with no events
|
|
517
|
-
// to replay it from
|
|
525
|
+
// to replay it from.
|
|
518
526
|
if (meta.source !== "unmanaged") {
|
|
519
527
|
throw new Error(`[Feature ${name}] r.storeTable("${tableName}") was given an EntityTableMeta with ` +
|
|
520
528
|
`source: "${meta.source}". r.storeTable() requires source: "unmanaged" (via ` +
|
|
@@ -538,16 +546,16 @@ export function buildUiExtensionsMethods(state, name) {
|
|
|
538
546
|
};
|
|
539
547
|
},
|
|
540
548
|
treeActions(actions) {
|
|
541
|
-
// Only-once
|
|
542
|
-
//
|
|
549
|
+
// Only-once guard: a second call is an authoring error that should surface in
|
|
550
|
+
// the feature file (matching the behavior of r.toggleable).
|
|
543
551
|
if (state.treeActions !== undefined) {
|
|
544
552
|
throw new Error(`[Feature ${name}] r.treeActions() already called. ` +
|
|
545
553
|
`Each feature may declare a single tree-actions schema.`);
|
|
546
554
|
}
|
|
547
555
|
state.treeActions = actions;
|
|
548
|
-
// Return typed handle
|
|
549
|
-
//
|
|
550
|
-
//
|
|
556
|
+
// Return a typed handle for the setup export. Freeze it so callers cannot
|
|
557
|
+
// mutate the map afterward, which would make the pattern AST and runtime
|
|
558
|
+
// lookup diverge.
|
|
551
559
|
return Object.freeze({
|
|
552
560
|
id: name,
|
|
553
561
|
treeActions: actions,
|
|
@@ -119,18 +119,17 @@ export function checkWriteFieldRoles(entity, changes, user) {
|
|
|
119
119
|
// row. For creates, pass oldRow = undefined; the check degenerates to a
|
|
120
120
|
// newRow-only evaluation.
|
|
121
121
|
//
|
|
122
|
-
// `submittedChanges` and `rowContext` are deliberately separate
|
|
122
|
+
// `submittedChanges` and `rowContext` are deliberately separate:
|
|
123
123
|
// - `submittedChanges` drives WHICH fields get checked — only what the user
|
|
124
124
|
// actually wrote in the request. A preSave-hook-derived field the user
|
|
125
125
|
// never touched (e.g. a system hook setting `assignedTo`) must not be
|
|
126
126
|
// field-ownership-checked against the user at all.
|
|
127
127
|
// - `rowContext` drives what a checked field's rule is evaluated AGAINST —
|
|
128
128
|
// this needs the full post-hook row, because an ownership rule can
|
|
129
|
-
// reference a DIFFERENT column that only a hook populates (
|
|
130
|
-
//
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
// `secretNote`). Defaults to `submittedChanges` when omitted.
|
|
129
|
+
// reference a DIFFERENT column that only a hook populates (a hook derives
|
|
130
|
+
// `authorId`, a user-submitted `secretNote` field's rule is `from("user:id", "authorId")`
|
|
131
|
+
// — the check needs the hook-derived `authorId` in scope even though the
|
|
132
|
+
// user only wrote `secretNote`). Defaults to `submittedChanges` when omitted.
|
|
134
133
|
//
|
|
135
134
|
// Returns the denied field name for the caller to wrap into an
|
|
136
135
|
// `ownership_denied` error with scope: "field", or null if all fields pass.
|
|
@@ -101,17 +101,30 @@ function sumListCell(rows, listField, cell) {
|
|
|
101
101
|
return sum;
|
|
102
102
|
}
|
|
103
103
|
function targetCurrency(field, current, sourceCurrency) {
|
|
104
|
+
// The client value is last: it must never override what the field or its sources dictate.
|
|
105
|
+
if (field.type === "money" && field.currency.kind === "literal")
|
|
106
|
+
return field.currency.code;
|
|
107
|
+
if (sourceCurrency !== undefined)
|
|
108
|
+
return sourceCurrency;
|
|
104
109
|
if (isPlainObject(current) &&
|
|
105
110
|
typeof current["currency"] === "string" &&
|
|
106
111
|
current["currency"] !== "") {
|
|
107
112
|
return current["currency"];
|
|
108
113
|
}
|
|
109
|
-
if (sourceCurrency !== undefined)
|
|
110
|
-
return sourceCurrency;
|
|
111
|
-
if (field.type === "money" && field.currency.kind === "literal")
|
|
112
|
-
return field.currency.code;
|
|
113
114
|
return undefined;
|
|
114
115
|
}
|
|
116
|
+
function computeOrdinary(derivation, values, fields) {
|
|
117
|
+
const operands = derivation.from.map((name) => readOperand(values, fields, name));
|
|
118
|
+
const currencies = new Set(operands.flatMap((operand) => operand.currency ?? []));
|
|
119
|
+
const sourceCurrency = currencies.values().next().value;
|
|
120
|
+
// Operands in different currencies have no meaningful sum.
|
|
121
|
+
if (currencies.size > 1)
|
|
122
|
+
return { computed: undefined, sourceCurrency };
|
|
123
|
+
return {
|
|
124
|
+
computed: computeDerivedCellValue(derivation.op, operands.map((operand) => operand.value)),
|
|
125
|
+
sourceCurrency,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
115
128
|
/** Recomputes every derived head field of an action form from its inputs.
|
|
116
129
|
* Pure and client-safe: the renderer runs it live, the server runs it
|
|
117
130
|
* again (`withFormDerivations`) and overwrites whatever the client sent.
|
|
@@ -148,9 +161,7 @@ export function applyFormDerivations(values, screen) {
|
|
|
148
161
|
ordinary = derivation;
|
|
149
162
|
}
|
|
150
163
|
if (ordinary !== undefined) {
|
|
151
|
-
|
|
152
|
-
sourceCurrency = operands.find((operand) => operand.currency !== undefined)?.currency;
|
|
153
|
-
computed = computeDerivedCellValue(ordinary.op, operands.map((operand) => operand.value));
|
|
164
|
+
({ computed, sourceCurrency } = computeOrdinary(ordinary, result, screen.fields));
|
|
154
165
|
}
|
|
155
166
|
if (computed === undefined) {
|
|
156
167
|
delete result[target];
|
|
@@ -5,7 +5,7 @@ const MAX_WRAPPER_DEPTH = 8;
|
|
|
5
5
|
const MAX_NESTING_DEPTH = 8;
|
|
6
6
|
const referenceMetaSchema = z.union([
|
|
7
7
|
z.string().min(1),
|
|
8
|
-
z.
|
|
8
|
+
z.strictObject({ entity: z.string().min(1), by: z.string().min(1).optional() }),
|
|
9
9
|
]);
|
|
10
10
|
function rawReferenceMeta(field) {
|
|
11
11
|
const meta = zodMeta(field);
|
package/dist/engine/index.d.ts
CHANGED
|
@@ -91,4 +91,5 @@ export type { AccessRule, ActionFormScreenDefinition, ActiveMembership, ActiveMe
|
|
|
91
91
|
export { DEFAULT_CURRENCIES, DEFAULT_LOCALES, DELIVERY_FAILURE_CODES, DELIVERY_SKIP_REASONS, HookPhases, HTTP_ERROR_CODE_PATTERN, isAgentVisibleScreen, isDeliveryErrorCode, isOpenToAllGranted, resolveAgentExposure, } from "./types/index.ts";
|
|
92
92
|
export type { AwaitedEventType, PipelineBuildCtx, PipelineCtx, PipelineDef, StepBuilder, StepDef, StepFailureStrategy, StepInstance, StepKind, StepNamespace, StepResolver, } from "./types/step.ts";
|
|
93
93
|
export { runValidation } from "./validation.ts";
|
|
94
|
+
export { walkStepInstances } from "./walk-step-instances.ts";
|
|
94
95
|
export { formDerivationsOfSchema, withFormDerivations } from "./with-form-derivations.ts";
|
package/dist/engine/index.js
CHANGED
|
@@ -22,10 +22,9 @@ export { defineStep, getStep, listStepKinds } from "./define-step.js";
|
|
|
22
22
|
export { computeDefinitionFingerprint, defineWorkflow } from "./define-workflow.js";
|
|
23
23
|
export { computeEffectiveFeatures, isToggleableFeature } from "./effective-features.js";
|
|
24
24
|
export { createEntityExecutor, defineEntityCreateHandler, defineEntityDeleteHandler, defineEntityDetailHandler, defineEntityListHandler,
|
|
25
|
-
// Legacy single-fn-with-verb-string API. Backwards
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
// unverändert lauffähig.
|
|
25
|
+
// Legacy single-fn-with-verb-string API. Backwards compatibility — new
|
|
26
|
+
// apps use the verb-specific wrappers above. Existing callers (integration
|
|
27
|
+
// tests, old bundled-features) remain runnable without changes.
|
|
29
28
|
defineEntityQueryHandler, defineEntityRestoreHandler, defineEntityUpdateHandler, defineEntityWriteHandler, defineProjectionQueryHandler, entityListSchema, MAX_LIST_LIMIT, } from "./entity-handlers.js";
|
|
30
29
|
export { declareEscapeHatch } from "./escape-hatch-declaration.js";
|
|
31
30
|
export { createEventDef } from "./event-def.js";
|
|
@@ -81,4 +80,5 @@ export { findOverDeepTransferChain, resolveTransferAdjacency as resolveEntityTra
|
|
|
81
80
|
export { isSystemTenant, isUuid, parseTenantId, SYSTEM_TENANT_ID } from "./types/identifiers.js";
|
|
82
81
|
export { DEFAULT_CURRENCIES, DEFAULT_LOCALES, DELIVERY_FAILURE_CODES, DELIVERY_SKIP_REASONS, HookPhases, HTTP_ERROR_CODE_PATTERN, isAgentVisibleScreen, isDeliveryErrorCode, isOpenToAllGranted, resolveAgentExposure, } from "./types/index.js";
|
|
83
82
|
export { runValidation } from "./validation.js";
|
|
83
|
+
export { walkStepInstances } from "./walk-step-instances.js";
|
|
84
84
|
export { formDerivationsOfSchema, withFormDerivations } from "./with-form-derivations.js";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export declare function splitNamedDefinition<T extends {
|
|
2
2
|
readonly name: string;
|
|
3
3
|
}>(definition: T): [string, Omit<T, "name">];
|
|
4
|
+
export declare function requireArgument<T>(value: T | undefined, featureName: string, method: string, argument: string): T;
|
|
4
5
|
export declare function unwrapArrayForm<K extends string>(args: readonly [Record<K, readonly string[]>] | readonly string[], key: K): readonly string[];
|
|
5
6
|
export declare function isObjectArgument(value: unknown): boolean;
|
|
6
7
|
export declare function throwObjectArgumentRequired(featureName: string, method: string): never;
|
|
@@ -4,14 +4,24 @@ export function splitNamedDefinition(definition) {
|
|
|
4
4
|
const { name, ...rest } = definition;
|
|
5
5
|
return [name, rest];
|
|
6
6
|
}
|
|
7
|
+
// The `(name, options)` overloads make `options` required for typed callers;
|
|
8
|
+
// the implementation signature has to stay optional, so untyped callers are caught here.
|
|
9
|
+
export function requireArgument(value, featureName, method, argument) {
|
|
10
|
+
if (value === undefined) {
|
|
11
|
+
throw new Error(`[Feature ${featureName}] r.${method}() needs its ${argument} argument`);
|
|
12
|
+
}
|
|
13
|
+
return value;
|
|
14
|
+
}
|
|
15
|
+
function isStringList(args) {
|
|
16
|
+
return args.every((arg) => typeof arg === "string");
|
|
17
|
+
}
|
|
7
18
|
// `optionalRequires` and `readConfig` still accept variadic strings next to a
|
|
8
19
|
// single object wrapping the same string array under `key`.
|
|
9
20
|
export function unwrapArrayForm(args, key) {
|
|
21
|
+
if (isStringList(args))
|
|
22
|
+
return args;
|
|
10
23
|
const [first] = args;
|
|
11
|
-
|
|
12
|
-
return first[key];
|
|
13
|
-
}
|
|
14
|
-
return args;
|
|
24
|
+
return first[key];
|
|
15
25
|
}
|
|
16
26
|
export function isObjectArgument(value) {
|
|
17
27
|
return typeof value === "object" && value !== null;
|
package/dist/engine/ownership.js
CHANGED
|
@@ -72,7 +72,7 @@ export function matchesRule(rule, user, row) {
|
|
|
72
72
|
// `where` rules produce SQL for the DB-side filter and have no in-memory
|
|
73
73
|
// evaluator — the feature author owns the semantics. Only the read path
|
|
74
74
|
// reaches SQL (buildOwnershipClause); on write maps the boot-validator
|
|
75
|
-
// rejects them outright
|
|
75
|
+
// rejects them outright, and the in-memory write helpers below
|
|
76
76
|
// fail closed rather than calling in here.
|
|
77
77
|
throw new Error("where-rules can only be evaluated at the SQL layer (buildOwnershipClause); they are rejected on access.write at boot.");
|
|
78
78
|
}
|
|
@@ -219,7 +219,7 @@ export function shiftParams(fragment, shift) {
|
|
|
219
219
|
// is a boot-time misconfiguration; at request time we treat it as empty
|
|
220
220
|
// (safe default) rather than passing silently.
|
|
221
221
|
//
|
|
222
|
-
// Caller obligations
|
|
222
|
+
// Caller obligations — this function returns ONLY the ownership
|
|
223
223
|
// fragment, not the full row-access contract. A raw-SQL caller (not going
|
|
224
224
|
// through `ctx.db`, which already applies all three) must additionally:
|
|
225
225
|
// 1. Pass `paramStart` as `params.length + 1` for its own already-bound
|
|
@@ -309,7 +309,7 @@ function ruleToFragment(rule, user, table, paramStart) {
|
|
|
309
309
|
});
|
|
310
310
|
// Runtime backstop for the boot-time probe (boot-validator/ownership.ts):
|
|
311
311
|
// an unqualified column in a correlated subquery silently turns into a
|
|
312
|
-
// fail-open tautology
|
|
312
|
+
// fail-open tautology — throw instead of shipping it.
|
|
313
313
|
assertQualifiedWhereFragment(frag.sqlText, cachedTableColumnSqlNames(table), `ownership where-rule on "${tableNameOf(table)}"`);
|
|
314
314
|
return { kind: "sql", sqlText: frag.sqlText, params: frag.params };
|
|
315
315
|
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
// Akzeptiert beide Formen:
|
|
1
|
+
// Parser for the ReferenceFieldDef.entity string. Accepts both forms:
|
|
4
2
|
// - "user" → same-feature ref (featureName = currentFeature)
|
|
5
|
-
// - "users:user" → cross-feature ref (
|
|
3
|
+
// - "users:user" → cross-feature ref (qualified)
|
|
6
4
|
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
5
|
+
// Kept in the framework package so the server validator and renderer (via
|
|
6
|
+
// re-export from @cosmicdrift/kumiko-renderer/headless) use the same parser;
|
|
7
|
+
// the convention must not be implemented twice.
|
|
10
8
|
export function parseRefTarget(raw, currentFeature) {
|
|
11
9
|
const idx = raw.indexOf(":");
|
|
12
10
|
if (idx < 0) {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
// Public API of the pattern-library — Designer
|
|
2
|
-
// MCP-Server
|
|
1
|
+
// Public API of the pattern-library — Designer, AI-Builder,
|
|
2
|
+
// MCP-Server consume from here.
|
|
3
3
|
export { getPatternSchema, groupByCategory, PATTERN_LIBRARY } from "./library.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Pattern-Library — concrete FormSchema entries for every FeaturePattern
|
|
2
|
-
// kind. Centralised here so the Designer
|
|
3
|
-
// and the MCP-Server
|
|
2
|
+
// kind. Centralised here so the Designer, the AI-Builder,
|
|
3
|
+
// and the MCP-Server share one source-of-truth for "how does this
|
|
4
4
|
// pattern look as a form?".
|
|
5
5
|
//
|
|
6
6
|
// **Updating contract:** when a new pattern-kind gets a parser/renderer
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Forms-Schema metadata — describes how a FeaturePattern is rendered as
|
|
2
2
|
// a Designer form, fed to an LLM as a JSON-Schema, or surfaced in the
|
|
3
3
|
// MCP-Server tool list. One schema, three consumers — that's the whole
|
|
4
|
-
// point of factoring this out of the hand-rolled
|
|
4
|
+
// point of factoring this out of the hand-rolled skeleton.
|
|
5
5
|
//
|
|
6
6
|
// **NOT a DSL.** The Source-of-Truth for a feature stays
|
|
7
7
|
// `defineFeature.ts` — the AST-visitor (feature-ast/parse.ts) reads it
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// already-parsed FeaturePattern in a form. No alternative parser, no
|
|
11
11
|
// alternative syntax, no second canonical representation.
|
|
12
12
|
//
|
|
13
|
-
// **
|
|
13
|
+
// **Vocabulary** (12 input-types):
|
|
14
14
|
//
|
|
15
15
|
// text — single-line string (name / label / id)
|
|
16
16
|
// textarea — multi-line string (description / SQL / readme)
|
|
@@ -31,6 +31,6 @@
|
|
|
31
31
|
// FeaturePattern object using dot-separated keys (`definition.fields`,
|
|
32
32
|
// `access.roles`, `templates.email`). Numeric indices use the bracket
|
|
33
33
|
// form (`columns.0`). The Designer/LLM uses paths for read & write —
|
|
34
|
-
// the patcher
|
|
34
|
+
// the patcher consumes pattern-level updates only, so paths are
|
|
35
35
|
// purely a UI concern at this stage.
|
|
36
36
|
export {};
|
package/dist/engine/pipeline.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// the resolver-side PipelineCtx (run-pipeline.ts). Resolvers that need
|
|
9
9
|
// prior step results destructure them from the resolver's ctx.
|
|
10
10
|
//
|
|
11
|
-
// Renamed from `pipeline()`
|
|
11
|
+
// Renamed from `pipeline()` — it shared its name with the
|
|
12
12
|
// internal `packages/framework/src/pipeline/` directory (dispatcher,
|
|
13
13
|
// lifecycle, outbox-poller), which made repo-wide grep for `pipeline`
|
|
14
14
|
// return mixed results.
|
|
@@ -76,7 +76,7 @@ export function stepsPipeline(closure) {
|
|
|
76
76
|
// awaits map wired into the closure. The cast below is the one place a
|
|
77
77
|
// workflow's raw declared event-type strings become AwaitedEventType — safe
|
|
78
78
|
// because pipelineDef.awaits only ever holds what defineWorkflow's `awaits`
|
|
79
|
-
// carried in (
|
|
79
|
+
// carried in (workflow-resume-loop.md), never an unchecked external
|
|
80
80
|
// value.
|
|
81
81
|
export function buildPipelineSteps(pipelineDef, event) {
|
|
82
82
|
const steps = pipelineDef.build({
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
import type { AppSchema } from "../ui-types/app-schema.ts";
|
|
2
|
+
import type { NavDefinition } from "./types/nav.ts";
|
|
2
3
|
export declare function projectAppSchemaForRoles(schema: AppSchema, roles: readonly string[]): AppSchema;
|
|
4
|
+
export declare function isPureGroupingNav(nav: Pick<NavDefinition, "screen" | "target" | "provider">): boolean;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Per-role projection of a fully-built AppSchema
|
|
1
|
+
// Per-role projection of a fully-built AppSchema. GET /api/schema
|
|
2
2
|
// used to ship the same full schema — screens, navs, workspaces, content
|
|
3
3
|
// collections — to every authenticated user regardless of role, relying on
|
|
4
4
|
// client-side UI checks (isUiAccessGranted) alone to hide what a role
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
// @cosmicdrift/kumiko-types/handlers) — an unset `access` here means every
|
|
28
28
|
// signed-in user may see the entry, the opposite stance from `hasAccess`.
|
|
29
29
|
//
|
|
30
|
-
// Reference-site coverage (every place boot-validator/screens
|
|
30
|
+
// Reference-site coverage (every place boot-validator/screens*.ts resolves a
|
|
31
31
|
// screen target is a site this file also projects):
|
|
32
32
|
// - nav.screen / nav.parent (author-registered AND settings-hub-generated
|
|
33
33
|
// navs — the latter use short ids relative to the synthetic "config"
|
|
@@ -204,16 +204,18 @@ function isNavDeniedOrDead(ctx, screenAccessByQn, keptScreenQns, roles) {
|
|
|
204
204
|
const effectiveAccess = ctx.nav.access ?? screenAccessByQn.get(ctx.resolvedScreenQn);
|
|
205
205
|
return !isUiAccessGranted(effectiveAccess, roles);
|
|
206
206
|
}
|
|
207
|
+
export function isPureGroupingNav(nav) {
|
|
208
|
+
return nav.screen === undefined && nav.target === undefined && nav.provider !== true;
|
|
209
|
+
}
|
|
207
210
|
function isDroppedByPropagation(ctx, dropped, childrenByParent) {
|
|
208
211
|
if (ctx.resolvedParentQn !== undefined && dropped.has(ctx.resolvedParentQn))
|
|
209
212
|
return true;
|
|
210
|
-
|
|
211
|
-
if (!isPureGroupingNode)
|
|
213
|
+
if (!isPureGroupingNav(ctx.nav))
|
|
212
214
|
return false;
|
|
213
215
|
const children = childrenByParent.get(ctx.qn) ?? [];
|
|
214
216
|
return children.length > 0 && children.every((child) => dropped.has(child.qn));
|
|
215
217
|
}
|
|
216
|
-
// --- screen-target resolution helpers (mirror boot-validator/screens
|
|
218
|
+
// --- screen-target resolution helpers (mirror boot-validator/screens*.ts) ---
|
|
217
219
|
function isScreenTargetKept(featureName, target, keptScreenQns) {
|
|
218
220
|
return keptScreenQns.has(resolveScreenTargetQn(featureName, target));
|
|
219
221
|
}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
import { updateMany } from "../db/query.js";
|
|
2
|
-
// Typed
|
|
3
|
-
//
|
|
4
|
-
//
|
|
2
|
+
// Typed apply helper for r.projection.apply: enables typed event.payload
|
|
3
|
+
// access per event type without propagating a SingleStreamApplyFn generic
|
|
4
|
+
// through the entire ProjectionDefinition.
|
|
5
5
|
//
|
|
6
|
-
//
|
|
6
|
+
// The helper is purely a type vehicle — an identity function at runtime:
|
|
7
7
|
//
|
|
8
8
|
// apply: {
|
|
9
9
|
// "user.created": defineApply<UserCreatedPayload>(async (event, tx, table) => {
|
|
10
|
-
// // event.payload
|
|
10
|
+
// // event.payload is UserCreatedPayload, not Record<string, unknown>.
|
|
11
11
|
// // Write through the passed `table` (ES-blessed inside apply), not a
|
|
12
12
|
// // closed-over branded constant.
|
|
13
13
|
// await insertOne(tx, table, { id: event.aggregateId, ...event.payload });
|
|
14
14
|
// }),
|
|
15
15
|
// }
|
|
16
16
|
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
//
|
|
17
|
+
// The default generic, Record<string, unknown>, preserves backward-compatible
|
|
18
|
+
// behavior for apply handlers written without a type argument. The `table`
|
|
19
|
+
// parameter is optional to use, so 2-argument applies remain valid.
|
|
20
20
|
export function defineApply(fn) {
|
|
21
21
|
// @cast-boundary engine-bridge — typed user-fn → erased internal storage
|
|
22
22
|
return fn;
|
|
23
23
|
}
|
|
24
|
-
//
|
|
24
|
+
// Counterpart for r.multiStreamProjection.apply — also receives ctx.
|
|
25
25
|
export function defineMspApply(fn) {
|
|
26
26
|
// @cast-boundary engine-bridge — typed user-fn → erased internal storage
|
|
27
27
|
return fn;
|
|
@@ -32,7 +32,7 @@ function validateSegment(value, label, context) {
|
|
|
32
32
|
}
|
|
33
33
|
// registry-ingest.ts also qualifies handlers/projections with these two —
|
|
34
34
|
// not in the public QnTypes enum, but reachable as a type segment the same
|
|
35
|
-
// way
|
|
35
|
+
// way.
|
|
36
36
|
const NON_ENUM_QN_TYPES = ["stream", "projection", "workspace"];
|
|
37
37
|
// Every segment word that a fully-qualified QN can carry as its type.
|
|
38
38
|
const RESERVED_QN_SEGMENTS = new Set([
|
|
@@ -44,7 +44,7 @@ const RESERVED_QN_SEGMENTS = new Set([
|
|
|
44
44
|
// the trailing part. Both signals must hold together: the scope alone
|
|
45
45
|
// repeating (e.g. entity "user:create" on feature "user") or a reserved word
|
|
46
46
|
// alone appearing (e.g. "compliance:query:for-tenant") are both common,
|
|
47
|
-
// legitimate sub-structure on their own
|
|
47
|
+
// legitimate sub-structure on their own.
|
|
48
48
|
function isDoubleQualified(scope, segments) {
|
|
49
49
|
const [first, second] = segments;
|
|
50
50
|
return first === scope && second !== undefined && RESERVED_QN_SEGMENTS.has(second);
|
|
@@ -85,7 +85,7 @@ export function buildRegistryFacade(state) {
|
|
|
85
85
|
getEntityPostQueryHooks(entityName, effectiveFeatures) {
|
|
86
86
|
return filterOwned(state.entityPostQueryHooks.get(entityName), effectiveFeatures);
|
|
87
87
|
},
|
|
88
|
-
//
|
|
88
|
+
// Search-Payload-Extension contributors for an entity. Used by
|
|
89
89
|
// `buildSearchDocument` in system-hooks.ts to enrich the indexed payload.
|
|
90
90
|
// `effectiveFeatures` filters out contributors owned by feature-toggle-
|
|
91
91
|
// disabled features (parallel to getEntityPostQueryHooks etc.).
|