@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
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { buildOwnershipClause, normalizeAccessEntry, shiftParams, } from "../engine/ownership.js";
|
|
2
|
+
import { SYSTEM_TENANT_ID } from "../engine/types/identifiers.js";
|
|
3
|
+
import { isListSortAllowed, isSensitiveLabelField } from "./entity-field-encryption.js";
|
|
4
|
+
import { isSoftDeletedTargetHidden } from "./event-store-executor-read-search.js";
|
|
5
|
+
import { buildEntityTable, physicalColumnName } from "./table-builder.js";
|
|
6
|
+
import { schemaTableName } from "./table-introspection.js";
|
|
7
|
+
// Projected alongside the row when a reference sort is active, so the keyset
|
|
8
|
+
// cursor carries the label that was ordered by instead of the FK's UUID.
|
|
9
|
+
const SORT_LABEL_ALIAS = "__kumiko_sort_label";
|
|
10
|
+
// Resolve a `sortable: true` reference field's label inline for
|
|
11
|
+
// ORDER BY. A correlated scalar subquery, not a join: the result set keeps one
|
|
12
|
+
// row per entity row, the read model stays untouched, and the lookup rides the
|
|
13
|
+
// target's primary key. Tenant-scoped exactly like the search path — a foreign
|
|
14
|
+
// tenant's label must never influence this tenant's ordering.
|
|
15
|
+
// undefined means "cannot order by this label", which drops the sort to plain
|
|
16
|
+
// id order; falling back to the UUID column would look deliberate to the user
|
|
17
|
+
// while being arbitrary, which is worse than no sorting.
|
|
18
|
+
function buildReferenceSortExpr(outerTableName, ownColumnSql, descriptor, resolveEntity, db, user) {
|
|
19
|
+
const targetEntity = resolveEntity(descriptor.targetEntityName);
|
|
20
|
+
if (targetEntity === undefined) {
|
|
21
|
+
// skip: unknown target entity — registry inconsistency the boot-validator
|
|
22
|
+
// should have caught; drop the sort rather than 500 the request
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
if (targetEntity.fields[descriptor.labelField] === undefined) {
|
|
26
|
+
// skip: labelField isn't a real (declared) column on the target entity
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
if (isSensitiveLabelField(targetEntity, descriptor.labelField)) {
|
|
30
|
+
// skip: encrypted/PII labelField — ciphertext orders by its bytes, which is
|
|
31
|
+
// arbitrary to the reader and would also rank rows by their stored secret
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
const targetTable = buildEntityTable(descriptor.targetEntityName, targetEntity);
|
|
35
|
+
// The order of labels the viewer may not read would leak them bit by bit, same as the search path.
|
|
36
|
+
const labelAccess = buildOwnershipClause(user, normalizeAccessEntry(targetEntity.fields[descriptor.labelField]?.access?.read), targetTable);
|
|
37
|
+
if (labelAccess.kind !== "pass")
|
|
38
|
+
return undefined;
|
|
39
|
+
const ownership = buildOwnershipClause(user, targetEntity.access?.read, targetTable);
|
|
40
|
+
if (ownership.kind === "empty")
|
|
41
|
+
return undefined;
|
|
42
|
+
const targetTableName = String(schemaTableName(targetTable));
|
|
43
|
+
const labelCol = physicalColumnName(targetTable, descriptor.labelField);
|
|
44
|
+
const tenantScoped = targetTable["tenantId"] !== undefined && db.mode === "tenant";
|
|
45
|
+
const tenantCol = tenantScoped ? physicalColumnName(targetTable, "tenantId") : "";
|
|
46
|
+
const tenantId = db.mode === "tenant" ? db.tenantId : undefined;
|
|
47
|
+
const deletedClause = isSoftDeletedTargetHidden(targetEntity, targetTable)
|
|
48
|
+
? ` AND t."${physicalColumnName(targetTable, "isDeleted")}" = FALSE`
|
|
49
|
+
: "";
|
|
50
|
+
// No ::text cast (unlike the ILIKE search path): a non-text label must keep
|
|
51
|
+
// its native collation/numeric order, and the keyset param infers its type
|
|
52
|
+
// from the comparison anyway.
|
|
53
|
+
return (params) => {
|
|
54
|
+
let tenantClause = "";
|
|
55
|
+
if (tenantScoped) {
|
|
56
|
+
params.push(tenantId, SYSTEM_TENANT_ID);
|
|
57
|
+
tenantClause = ` AND t."${tenantCol}" IN ($${params.length - 1}, $${params.length})`;
|
|
58
|
+
}
|
|
59
|
+
let ownershipClause = "";
|
|
60
|
+
if (ownership.kind === "sql") {
|
|
61
|
+
const shifted = shiftParams({ sqlText: ownership.sqlText, params: ownership.params }, params.length);
|
|
62
|
+
for (const p of shifted.params)
|
|
63
|
+
params.push(p);
|
|
64
|
+
ownershipClause = ` AND ${shifted.sqlText}`;
|
|
65
|
+
}
|
|
66
|
+
return (`(SELECT t."${labelCol}" FROM "${targetTableName}" t ` +
|
|
67
|
+
`WHERE t."id" = "${outerTableName}".${ownColumnSql}${tenantClause}${ownershipClause}${deletedClause})`);
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export function resolveListSort(request) {
|
|
71
|
+
const { payload, table, entity, referenceSort } = request;
|
|
72
|
+
// A column sort must not 400 (the renderer sends one per header click), and the order of
|
|
73
|
+
// ciphertext carries no meaning for the user while leaking the order of the plaintext.
|
|
74
|
+
const field = payload.sort &&
|
|
75
|
+
Object.hasOwn(table, payload.sort) &&
|
|
76
|
+
request.fieldReadClause(payload.sort).kind === "pass" &&
|
|
77
|
+
isListSortAllowed(entity, payload.sort)
|
|
78
|
+
? payload.sort
|
|
79
|
+
: undefined;
|
|
80
|
+
if (field === undefined)
|
|
81
|
+
return { kind: "unsorted" };
|
|
82
|
+
const descending = payload.sortDirection === "desc";
|
|
83
|
+
if (entity.fields[field]?.type !== "reference")
|
|
84
|
+
return { kind: "column", field, descending };
|
|
85
|
+
// A reference column stores a UUID, so it is never sorted by
|
|
86
|
+
// directly: either the field opted into `sortable` and we order by the
|
|
87
|
+
// target row's label, or the sort is dropped to plain id order.
|
|
88
|
+
const descriptor = referenceSort?.fields.find((f) => f.fieldName === field);
|
|
89
|
+
const labelSql = referenceSort && descriptor
|
|
90
|
+
? buildReferenceSortExpr(request.tableName, request.colSql(field), descriptor, referenceSort.resolveEntity, request.db, request.user)
|
|
91
|
+
: undefined;
|
|
92
|
+
return labelSql === undefined
|
|
93
|
+
? { kind: "unsorted" }
|
|
94
|
+
: { kind: "referenceLabel", field, descending, labelSql };
|
|
95
|
+
}
|
|
96
|
+
export function renderSortSql(sort, where) {
|
|
97
|
+
return sort.kind === "referenceLabel" ? sort.labelSql(where.params) : where.colSql(sort.field);
|
|
98
|
+
}
|
|
99
|
+
export function renderListOrderBy(sort, where) {
|
|
100
|
+
const idAscending = `${where.colSql("id")} ASC`;
|
|
101
|
+
if (sort.kind === "unsorted") {
|
|
102
|
+
return { orderByClause: ` ORDER BY ${idAscending}`, sortLabelProjection: "" };
|
|
103
|
+
}
|
|
104
|
+
const sortSql = renderSortSql(sort, where);
|
|
105
|
+
const direction = sort.descending ? "DESC" : "ASC";
|
|
106
|
+
if (sort.kind === "column") {
|
|
107
|
+
return {
|
|
108
|
+
orderByClause: ` ORDER BY ${sortSql} ${direction}, ${idAscending}`,
|
|
109
|
+
sortLabelProjection: "",
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// The projected label alias is ordered by directly, so Postgres evaluates
|
|
113
|
+
// the correlated subquery once per row instead of once for ORDER BY and
|
|
114
|
+
// once for the SELECT list. Projecting it also lets the keyset cursor carry
|
|
115
|
+
// the value that was ordered by rather than the FK column's UUID.
|
|
116
|
+
return {
|
|
117
|
+
orderByClause: ` ORDER BY "${SORT_LABEL_ALIAS}" ${direction}, ${idAscending}`,
|
|
118
|
+
sortLabelProjection: `, ${sortSql} AS "${SORT_LABEL_ALIAS}"`,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
// The label alias is a query artifact, not a column of this entity, so it is
|
|
122
|
+
// stripped before coercion; the last row's label feeds the keyset cursor.
|
|
123
|
+
export function takeLastSortLabel(rawRows, sort) {
|
|
124
|
+
const lastSortLabel = rawRows[rawRows.length - 1]?.[SORT_LABEL_ALIAS];
|
|
125
|
+
if (sort.kind === "referenceLabel") {
|
|
126
|
+
for (const row of rawRows)
|
|
127
|
+
delete row[SORT_LABEL_ALIAS];
|
|
128
|
+
}
|
|
129
|
+
return lastSortLabel;
|
|
130
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type OwnershipClause } from "../engine/ownership.ts";
|
|
2
|
+
import type { SessionUser } from "../engine/types/index.ts";
|
|
3
|
+
import type { EventStoreExecutor } from "./event-store-executor.ts";
|
|
4
|
+
import type { ExecutorContext } from "./event-store-executor-context.ts";
|
|
5
|
+
import { type ListWhere } from "./event-store-executor-read-filter.ts";
|
|
6
|
+
import { type ParentVisibilityOption } from "./parent-ref-clause.ts";
|
|
7
|
+
import type { TenantDb } from "./tenant-db.ts";
|
|
8
|
+
export type ListRuntimeOptions = NonNullable<Parameters<EventStoreExecutor["list"]>[3]>;
|
|
9
|
+
export type ListWherePayload = Pick<Parameters<EventStoreExecutor["list"]>[0], "search" | "filter" | "filters">;
|
|
10
|
+
export type FieldReadClause = (field: string) => OwnershipClause;
|
|
11
|
+
export declare function resolveReadOwnership(ctx: Pick<ExecutorContext, "entity" | "table">, tableName: string, user: SessionUser, db: TenantDb, parentVisibility: ParentVisibilityOption | undefined, gate: {
|
|
12
|
+
readonly includeDeleted: boolean;
|
|
13
|
+
readonly narrowTypes: ReadonlySet<string> | undefined;
|
|
14
|
+
}): OwnershipClause;
|
|
15
|
+
export declare function createFieldReadClause(ctx: Pick<ExecutorContext, "entity" | "table">, user: SessionUser): FieldReadClause;
|
|
16
|
+
export type ListWhereBuild = {
|
|
17
|
+
readonly kind: "empty";
|
|
18
|
+
} | {
|
|
19
|
+
readonly kind: "ready";
|
|
20
|
+
readonly where: ListWhere;
|
|
21
|
+
readonly fieldReadClause: FieldReadClause;
|
|
22
|
+
readonly searchTruncated: boolean;
|
|
23
|
+
};
|
|
24
|
+
export declare function buildListWhere(ctx: ExecutorContext, payload: ListWherePayload, user: SessionUser, db: TenantDb, runtimeOptions: ListRuntimeOptions | undefined): Promise<ListWhereBuild>;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { buildOwnershipClause, combineClauses, normalizeAccessEntry, } from "../engine/ownership.js";
|
|
2
|
+
import { SYSTEM_TENANT_ID } from "../engine/types/identifiers.js";
|
|
3
|
+
import { appendShiftedClause, applyListFilter, collectListFilters, deriveParentNarrowTypes, } from "./event-store-executor-read-filter.js";
|
|
4
|
+
import { applyListSearch } from "./event-store-executor-read-search.js";
|
|
5
|
+
import { buildParentRefClause } from "./parent-ref-clause.js";
|
|
6
|
+
import { physicalColumnName } from "./table-builder.js";
|
|
7
|
+
import { schemaTableName } from "./table-introspection.js";
|
|
8
|
+
// H.2 — entity-level read ownership, AND-ed with the parent-ref read-gate
|
|
9
|
+
// (join-row entities derive their visibility from a host row's own read path —
|
|
10
|
+
// see db/parent-ref-clause.ts). `empty` means there's no row the user could ever see.
|
|
11
|
+
export function resolveReadOwnership(ctx, tableName, user, db, parentVisibility, gate) {
|
|
12
|
+
const parentClause = buildParentRefClause(ctx.entity, ctx.table, tableName, user, db, parentVisibility, gate);
|
|
13
|
+
return combineClauses(buildOwnershipClause(user, ctx.entity.access?.read, ctx.table), parentClause);
|
|
14
|
+
}
|
|
15
|
+
// Replicates TenantDb's readWhere semantics for the raw list SQL.
|
|
16
|
+
function appendTenantAndSoftDeleteScope(where, ctx, db, includeDeleted) {
|
|
17
|
+
if (ctx.table["tenantId"] !== undefined && db.mode === "tenant") {
|
|
18
|
+
where.params.push(db.tenantId, SYSTEM_TENANT_ID);
|
|
19
|
+
where.whereSql.push(`${where.colSql("tenantId")} IN ($${where.params.length - 1}, $${where.params.length})`);
|
|
20
|
+
}
|
|
21
|
+
if (ctx.softDelete && ctx.table["isDeleted"] && !includeDeleted) {
|
|
22
|
+
where.whereSql.push(`${where.colSql("isDeleted")} = FALSE`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// Field-level read access gates filtering, sorting and aggregating the same way it
|
|
26
|
+
// gates the projected row: a caller who cannot read a field must not be
|
|
27
|
+
// able to probe its values through result counts, ordering or sums.
|
|
28
|
+
// Built before the search step — a searchable-reference clause is the
|
|
29
|
+
// same probe surface as a filter/sort and must be gated the same way,
|
|
30
|
+
// before the reference-match query even runs.
|
|
31
|
+
export function createFieldReadClause(ctx, user) {
|
|
32
|
+
return (field) => buildOwnershipClause(user, normalizeAccessEntry(ctx.entity.fields[field]?.access?.read), ctx.table);
|
|
33
|
+
}
|
|
34
|
+
// One WHERE for the row page, its COUNT and the aggregate: ownership, search,
|
|
35
|
+
// tenant/soft-delete scope and filters, so all of them see the same rows.
|
|
36
|
+
// `empty` means no row can match — callers skip the query.
|
|
37
|
+
export async function buildListWhere(ctx, payload, user, db, runtimeOptions) {
|
|
38
|
+
const { table, entity, entityName, searchAdapter, streamTenantFor } = ctx;
|
|
39
|
+
const tableName = String(schemaTableName(table));
|
|
40
|
+
const includeDeleted = runtimeOptions?.includeDeleted === true;
|
|
41
|
+
// Decide before touching search or the DB: an `empty` ownership skips both paths.
|
|
42
|
+
const ownership = resolveReadOwnership(ctx, tableName, user, db, runtimeOptions?.parentVisibility, {
|
|
43
|
+
includeDeleted,
|
|
44
|
+
narrowTypes: deriveParentNarrowTypes(entity, payload),
|
|
45
|
+
});
|
|
46
|
+
if (ownership.kind === "empty")
|
|
47
|
+
return { kind: "empty" };
|
|
48
|
+
const where = {
|
|
49
|
+
whereSql: [],
|
|
50
|
+
params: [],
|
|
51
|
+
colSql: (field) => `"${physicalColumnName(table, field)}"`,
|
|
52
|
+
};
|
|
53
|
+
const fieldReadClause = createFieldReadClause(ctx, user);
|
|
54
|
+
let searchTruncated = false;
|
|
55
|
+
if (payload.search) {
|
|
56
|
+
// The build-time options.searchAdapter takes precedence; use the runtime override
|
|
57
|
+
// as a fallback because defaultEntityQueryHandler receives the search adapter only
|
|
58
|
+
// at runtime, when createEventStoreExecutor has no server context yet.
|
|
59
|
+
const search = await applyListSearch({
|
|
60
|
+
searchTerm: payload.search,
|
|
61
|
+
searchAdapter: searchAdapter ?? runtimeOptions?.searchAdapter,
|
|
62
|
+
entityName,
|
|
63
|
+
table,
|
|
64
|
+
referenceSearch: runtimeOptions?.referenceSearch,
|
|
65
|
+
fieldReadClause,
|
|
66
|
+
streamTenantFor,
|
|
67
|
+
user,
|
|
68
|
+
db,
|
|
69
|
+
}, where);
|
|
70
|
+
if (search.kind === "noMatches")
|
|
71
|
+
return { kind: "empty" };
|
|
72
|
+
searchTruncated = search.searchTruncated;
|
|
73
|
+
}
|
|
74
|
+
appendTenantAndSoftDeleteScope(where, ctx, db, includeDeleted);
|
|
75
|
+
if (ownership.kind === "sql")
|
|
76
|
+
appendShiftedClause(where, ownership);
|
|
77
|
+
for (const f of collectListFilters(payload)) {
|
|
78
|
+
applyListFilter(where, f, table, entity, fieldReadClause);
|
|
79
|
+
}
|
|
80
|
+
return { kind: "ready", where, fieldReadClause, searchTruncated };
|
|
81
|
+
}
|
|
@@ -1,10 +1,3 @@
|
|
|
1
1
|
import type { EventStoreExecutor } from "./event-store-executor.ts";
|
|
2
|
-
import {
|
|
3
|
-
export declare function
|
|
4
|
-
readonly limit?: unknown;
|
|
5
|
-
readonly offset?: unknown;
|
|
6
|
-
}): {
|
|
7
|
-
readonly limit: number;
|
|
8
|
-
readonly offset: number;
|
|
9
|
-
};
|
|
10
|
-
export declare function createReadVerbs(ctx: ExecutorContext): Pick<EventStoreExecutor, "list" | "detail">;
|
|
2
|
+
import type { ExecutorContext } from "./event-store-executor-context.ts";
|
|
3
|
+
export declare function createReadVerbs(ctx: ExecutorContext): Pick<EventStoreExecutor, "list" | "detail" | "aggregate">;
|