@cosmicdrift/kumiko-framework 1.0.0 → 2.0.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/README.md +9 -38
- package/package.json +21 -2
- package/src/__tests__/anonymous-access.integration.test.ts +185 -0
- package/src/__tests__/consumer-cli.integration.test.ts +172 -0
- package/src/__tests__/entity-permalink-open.integration.test.ts +94 -0
- package/src/__tests__/full-stack.integration.test.ts +1 -1
- package/src/__tests__/schema-cli-temporal-polyfill.test.ts +48 -0
- package/src/__tests__/schema-cli.integration.test.ts +50 -0
- package/src/__tests__/store-table.integration.test.ts +93 -0
- package/src/api/__tests__/api.test.ts +373 -0
- package/src/api/__tests__/auth-middleware-anonymous-access-boot.test.ts +40 -0
- package/src/api/__tests__/auth-routes-cookie.test.ts +17 -1
- package/src/api/__tests__/auth-routes-invalid-body-invite.test.ts +253 -0
- package/src/api/__tests__/auth-routes-mfa-preauth-confirm.test.ts +222 -0
- package/src/api/__tests__/auth-routes-mfa-preauth-enable-start.test.ts +249 -0
- package/src/api/__tests__/auth-routes-mfa-verify.test.ts +202 -0
- package/src/api/__tests__/auth-routes-trusted-proxy.test.ts +135 -0
- package/src/api/__tests__/batch.integration.test.ts +101 -11
- package/src/api/__tests__/csrf-constants-sync.test.ts +20 -0
- package/src/api/__tests__/dispatcher-live.integration.test.ts +74 -0
- package/src/api/__tests__/jwt.test.ts +200 -1
- package/src/api/__tests__/login-rate-limiter-sweep.test.ts +50 -0
- package/src/api/__tests__/pat-scope.test.ts +36 -0
- package/src/api/__tests__/pii-leak-guard.integration.test.ts +103 -0
- package/src/api/__tests__/redis-login-rate-limiter.integration.test.ts +138 -0
- package/src/api/__tests__/request-id-middleware.test.ts +51 -0
- package/src/api/__tests__/server-boot-guards.test.ts +71 -0
- package/src/api/__tests__/server-jwt-ttl.test.ts +58 -0
- package/src/api/__tests__/sse-broker.test.ts +57 -0
- package/src/api/__tests__/sse-route.test.ts +4 -0
- package/src/api/api-constants.ts +11 -0
- package/src/api/auth-middleware.ts +248 -40
- package/src/api/auth-routes.ts +576 -95
- package/src/api/index.ts +13 -4
- package/src/api/jwt.ts +170 -11
- package/src/api/pat-scope.ts +14 -0
- package/src/api/pii-leak-guard.ts +47 -0
- package/src/api/request-context.ts +3 -0
- package/src/api/request-id-middleware.ts +2 -0
- package/src/api/routes.ts +169 -2
- package/src/api/server.ts +112 -16
- package/src/api/sse-broker.ts +39 -0
- package/src/bun-db/__tests__/PATTERN.md +0 -1
- package/src/bun-db/__tests__/coerce-row-temporal.test.ts +41 -0
- package/src/bun-db/__tests__/select-many-retry.test.ts +79 -0
- package/src/bun-db/__tests__/write-brand.test.ts +21 -0
- package/src/bun-db/connection.ts +3 -3
- package/src/bun-db/index.ts +2 -0
- package/src/bun-db/query.ts +105 -32
- package/src/consumer-cli.ts +134 -0
- package/src/crypto/__tests__/blind-index.test.ts +130 -0
- package/src/crypto/__tests__/event-pii.test.ts +161 -0
- package/src/crypto/__tests__/kek-rotation.integration.test.ts +180 -0
- package/src/crypto/__tests__/kms-adapter-contract.ts +134 -0
- package/src/crypto/__tests__/kms-adapter.contract.test.ts +4 -0
- package/src/crypto/__tests__/pg-kms-adapter.integration.test.ts +117 -0
- package/src/crypto/__tests__/pii-field-encryption.test.ts +376 -0
- package/src/crypto/__tests__/request-kms-cache.test.ts +74 -0
- package/src/crypto/__tests__/subject-resolver.test.ts +108 -0
- package/src/crypto/blind-index.ts +118 -0
- package/src/crypto/event-pii.ts +70 -0
- package/src/crypto/in-memory-kms-adapter.ts +50 -0
- package/src/crypto/index.ts +67 -0
- package/src/crypto/kms-adapter.ts +2 -0
- package/src/crypto/pg-kms-adapter.ts +295 -0
- package/src/crypto/pii-field-encryption.ts +248 -0
- package/src/crypto/request-kms-cache.ts +38 -0
- package/src/crypto/subject-resolver.ts +91 -0
- package/src/db/__tests__/assert-no-unreachable-live-rows.integration.test.ts +191 -0
- package/src/db/__tests__/blind-index.integration.test.ts +248 -0
- package/src/db/__tests__/build-filter-where.test.ts +34 -0
- package/src/db/__tests__/collect-table-metas.test.ts +10 -10
- package/src/db/__tests__/config-seed.integration.test.ts +13 -5
- package/src/db/__tests__/dialect-instant.test.ts +1 -4
- package/src/db/__tests__/entity-field-encryption.test.ts +7 -7
- package/src/db/__tests__/entity-table-meta-source.test.ts +50 -0
- package/src/db/__tests__/event-store-executor-context.pii-roundtrip.test.ts +67 -0
- package/src/db/__tests__/event-store-executor-write-verbs.integration.test.ts +402 -0
- package/src/db/__tests__/event-store-executor.integration.test.ts +299 -29
- package/src/db/__tests__/feature-table-sources.test.ts +34 -0
- package/src/db/__tests__/implicit-projection-equivalence.integration.test.ts +118 -39
- package/src/db/__tests__/instant-to-driver-temporal.test.ts +21 -0
- package/src/db/__tests__/located-timestamp.test.ts +19 -0
- package/src/db/__tests__/migrate-generator.test.ts +21 -0
- package/src/db/__tests__/migrate-runner.test.ts +61 -0
- package/src/db/__tests__/number-field-fractional.integration.test.ts +58 -0
- package/src/db/__tests__/rebuild-marker.test.ts +13 -3
- package/src/db/__tests__/replay-migration-sql.test.ts +384 -0
- package/src/db/__tests__/schema-inspection.test.ts +7 -0
- package/src/db/__tests__/schema-migration.integration.test.ts +1 -1
- package/src/db/__tests__/table-builder-meta-lockstep.test.ts +39 -0
- package/src/db/__tests__/tenant-db-where-merge.test.ts +49 -3
- package/src/db/__tests__/tenant-db.integration.test.ts +6 -2
- package/src/db/api.ts +2 -2
- package/src/db/apply-entity-event.ts +18 -14
- package/src/db/blind-index-cleanup.ts +55 -0
- package/src/db/bun-provider.ts +2 -2
- package/src/db/collect-table-metas.ts +6 -7
- package/src/db/config-seed.ts +9 -9
- package/src/db/connection.ts +7 -12
- package/src/db/cursor.ts +1 -18
- package/src/db/dialect.ts +20 -26
- package/src/db/entity-field-encryption.ts +81 -24
- package/src/db/entity-table-meta-types.ts +2 -0
- package/src/db/entity-table-meta.ts +63 -90
- package/src/db/event-store-executor-context.ts +404 -0
- package/src/db/event-store-executor-read.ts +275 -0
- package/src/db/event-store-executor-write.ts +644 -0
- package/src/db/event-store-executor.ts +28 -1155
- package/src/db/feature-table-sources.ts +6 -5
- package/src/db/index.ts +20 -3
- package/src/db/located-timestamp.ts +4 -0
- package/src/db/migrate-generator.ts +39 -6
- package/src/db/migrate-runner.ts +107 -11
- package/src/db/pg-error.ts +9 -1
- package/src/db/postgres-provider.ts +2 -2
- package/src/db/queries/__tests__/event-store-idempotency-index.integration.test.ts +80 -0
- package/src/db/queries/backfill-pii.ts +277 -0
- package/src/db/queries/ddl.ts +45 -0
- package/src/db/queries/event-consumer.ts +35 -2
- package/src/db/queries/event-store.ts +126 -19
- package/src/db/queries/projection-rebuild.ts +22 -8
- package/src/db/queries/shadow-swap.ts +183 -0
- package/src/db/queries/test-stack.ts +4 -30
- package/src/db/query-api.ts +1 -0
- package/src/db/query.ts +1 -0
- package/src/db/rebuild-marker.ts +18 -2
- package/src/db/reference-data.ts +2 -3
- package/src/db/replay-migration-sql.ts +257 -0
- package/src/db/schema-inspection.ts +1 -1
- package/src/db/table-builder.ts +102 -71
- package/src/db/tenant-db.ts +15 -53
- package/src/engine/__tests__/boot-validator-action-wiring.test.ts +242 -0
- package/src/engine/__tests__/boot-validator-boot-check.test.ts +99 -0
- package/src/engine/__tests__/boot-validator-dashboard.test.ts +237 -0
- package/src/engine/__tests__/boot-validator-entity-list.test.ts +104 -0
- package/src/engine/__tests__/boot-validator-gdpr-storage.test.ts +7 -69
- package/src/engine/__tests__/boot-validator-i18n-keys.test.ts +26 -5
- package/src/engine/__tests__/boot-validator-located-timestamps.test.ts +3 -19
- package/src/engine/__tests__/boot-validator-pii-retention.test.ts +246 -4
- package/src/engine/__tests__/boot-validator.test.ts +219 -15
- package/src/engine/__tests__/build-app-schema.test.ts +82 -0
- package/src/engine/__tests__/build-config-feature-schema.test.ts +125 -0
- package/src/engine/__tests__/build-target.test.ts +3 -11
- package/src/engine/__tests__/codemod-pipeline.test.ts +152 -21
- package/src/engine/__tests__/config-helpers.test.ts +16 -0
- package/src/engine/__tests__/define-feature-entity-mapping.test.ts +6 -0
- package/src/engine/__tests__/define-roles.test.ts +21 -0
- package/src/engine/__tests__/engine.test.ts +163 -1
- package/src/engine/__tests__/entity-handlers.test.ts +80 -0
- package/src/engine/__tests__/event-migration-declarative.test.ts +65 -0
- package/src/engine/__tests__/event-type-map-augmentation.test.ts +24 -0
- package/src/engine/__tests__/extend-entity-projection.test.ts +123 -0
- package/src/engine/__tests__/factories-time.test.ts +2 -66
- package/src/engine/__tests__/feature-crud-shorthand.test.ts +28 -0
- package/src/engine/__tests__/feature-manifest.test.ts +31 -1
- package/src/engine/__tests__/field-access.test.ts +23 -1
- package/src/engine/__tests__/hook-phases.test.ts +5 -5
- package/src/engine/__tests__/membership-roles.test.ts +4 -10
- package/src/engine/__tests__/nav.test.ts +86 -1
- package/src/engine/__tests__/pipeline-engine.test.ts +9 -9
- package/src/engine/__tests__/pipeline-handler.integration.test.ts +18 -18
- package/src/engine/__tests__/pipeline-observability.integration.test.ts +2 -2
- package/src/engine/__tests__/pipeline-performance.integration.test.ts +3 -3
- package/src/engine/__tests__/pipeline-sub-pipelines.test.ts +9 -9
- package/src/engine/__tests__/post-query-hook.test.ts +7 -7
- package/src/engine/__tests__/registrar-object-form.test.ts +141 -0
- package/src/engine/__tests__/registry.test.ts +144 -0
- package/src/engine/__tests__/schema-builder.test.ts +18 -0
- package/src/engine/__tests__/screen.test.ts +147 -1
- package/src/engine/__tests__/soft-delete-cleanup.test.ts +3 -0
- package/src/engine/__tests__/store-table.test.ts +229 -0
- package/src/engine/__tests__/tier-resolver-extension.test.ts +19 -1
- package/src/engine/__tests__/{visual-tree-patterns.test.ts → tree-actions-patterns.test.ts} +7 -95
- package/src/engine/__tests__/validate-projection-allowlist.test.ts +15 -15
- package/src/engine/boot-validator/__tests__/config-deps.test.ts +92 -0
- package/src/engine/boot-validator/action-wiring.ts +149 -0
- package/src/engine/boot-validator/boot-check.ts +21 -0
- package/src/engine/boot-validator/config-deps.ts +40 -4
- package/src/engine/boot-validator/entity-handler.ts +20 -21
- package/src/engine/boot-validator/entity-list-screens.ts +88 -0
- package/src/engine/boot-validator/gdpr-storage.ts +0 -20
- package/src/engine/boot-validator/i18n-keys.ts +58 -4
- package/src/engine/boot-validator/index.ts +33 -12
- package/src/engine/boot-validator/nav.ts +125 -0
- package/src/engine/boot-validator/pii-retention.ts +95 -10
- package/src/engine/boot-validator/{screens-nav.ts → screens.ts} +214 -191
- package/src/engine/boot-validator/workspaces.ts +68 -0
- package/src/engine/build-app-schema.ts +16 -0
- package/src/engine/build-config-feature-schema.ts +44 -7
- package/src/engine/codemod/pipeline-codemod.ts +5 -5
- package/src/engine/config-helpers.ts +15 -0
- package/src/engine/constants.ts +32 -6
- package/src/engine/create-app.ts +11 -0
- package/src/engine/define-feature.ts +95 -947
- package/src/engine/define-handler.ts +28 -94
- package/src/engine/define-workflow.ts +1 -1
- package/src/engine/effective-features.ts +12 -2
- package/src/engine/entity-handlers.ts +76 -11
- package/src/engine/extensions/tenant-data.ts +19 -0
- package/src/engine/extensions/user-data.ts +29 -2
- package/src/engine/factories.ts +8 -49
- package/src/engine/feature-ast/__tests__/canonical-form.test.ts +26 -29
- package/src/engine/feature-ast/__tests__/fixtures/cross-file-registrar/feature.ts +9 -0
- package/src/engine/feature-ast/__tests__/fixtures/cross-file-registrar/screens.ts +4 -0
- package/src/engine/feature-ast/__tests__/parse-happy-path.test.ts +1 -2
- package/src/engine/feature-ast/__tests__/parse-real-features.test.ts +18 -8
- package/src/engine/feature-ast/__tests__/parse.test.ts +1640 -160
- package/src/engine/feature-ast/__tests__/patch.test.ts +206 -12
- package/src/engine/feature-ast/__tests__/patcher.test.ts +20 -23
- package/src/engine/feature-ast/__tests__/render-roundtrip.test.ts +380 -5
- package/src/engine/feature-ast/extractors/events.ts +322 -0
- package/src/engine/feature-ast/extractors/handlers.ts +234 -0
- package/src/engine/feature-ast/extractors/hooks.ts +243 -0
- package/src/engine/feature-ast/extractors/index.ts +34 -31
- package/src/engine/feature-ast/extractors/jobs-routes.ts +221 -0
- package/src/engine/feature-ast/extractors/projections-screens.ts +269 -0
- package/src/engine/feature-ast/extractors/round1.ts +3 -3
- package/src/engine/feature-ast/extractors/round5.ts +3 -3
- package/src/engine/feature-ast/extractors/round6.ts +2 -36
- package/src/engine/feature-ast/extractors/shared.ts +64 -6
- package/src/engine/feature-ast/index.ts +2 -4
- package/src/engine/feature-ast/parse.ts +130 -23
- package/src/engine/feature-ast/patch.ts +39 -50
- package/src/engine/feature-ast/patcher.ts +37 -38
- package/src/engine/feature-ast/patterns.ts +50 -62
- package/src/engine/feature-ast/render.ts +67 -44
- package/src/engine/feature-builder-state.ts +168 -0
- package/src/engine/feature-config-events-jobs.ts +403 -0
- package/src/engine/feature-entity-handlers.ts +208 -0
- package/src/engine/feature-manifest.ts +2 -1
- package/src/engine/feature-ui-extensions.ts +500 -0
- package/src/engine/field-access.ts +13 -2
- package/src/engine/field-helpers.ts +31 -0
- package/src/engine/handler-helpers.ts +26 -0
- package/src/engine/hook-helpers.ts +16 -0
- package/src/engine/index.ts +23 -7
- package/src/engine/membership-roles.ts +13 -0
- package/src/engine/object-form.ts +27 -0
- package/src/engine/ownership.ts +26 -79
- package/src/engine/pattern-library/__tests__/library.test.ts +7 -20
- package/src/engine/pattern-library/library.ts +44 -1152
- package/src/engine/pattern-library/mixed-schemas.ts +450 -0
- package/src/engine/pattern-library/opaque-schemas.ts +124 -0
- package/src/engine/pattern-library/shared-fields.ts +75 -0
- package/src/engine/pattern-library/static-schemas.ts +456 -0
- package/src/engine/pipeline.ts +6 -11
- package/src/engine/registry-facade.ts +362 -0
- package/src/engine/registry-ingest.ts +478 -0
- package/src/engine/registry-state.ts +388 -0
- package/src/engine/registry-validate.ts +642 -0
- package/src/engine/registry.ts +78 -1658
- package/src/engine/run-pipeline.ts +1 -1
- package/src/engine/schema-builder.ts +1 -0
- package/src/engine/screen-helpers.ts +54 -0
- package/src/engine/soft-delete-cleanup.ts +6 -2
- package/src/engine/steps/__tests__/duration-utils.test.ts +20 -0
- package/src/engine/steps/_duration-utils.ts +2 -0
- package/src/engine/steps/unsafe-projection-upsert.ts +1 -4
- package/src/engine/tier-resolver-extension.ts +3 -2
- package/src/engine/types/config.ts +2 -482
- package/src/engine/types/define-handler.ts +2 -0
- package/src/engine/types/entity-handlers.ts +2 -0
- package/src/engine/types/event-type-map.ts +1 -37
- package/src/engine/types/feature.ts +2 -972
- package/src/engine/types/fields.ts +2 -675
- package/src/engine/types/handlers.ts +2 -774
- package/src/engine/types/hooks.ts +2 -184
- package/src/engine/types/http-route.ts +1 -54
- package/src/engine/types/identifiers.ts +1 -47
- package/src/engine/types/index.ts +86 -40
- package/src/engine/types/nav.ts +2 -63
- package/src/engine/types/ownership.ts +2 -0
- package/src/engine/types/projection.ts +2 -138
- package/src/engine/types/relations.ts +1 -51
- package/src/engine/types/screen.ts +2 -574
- package/src/engine/types/step.ts +2 -334
- package/src/engine/types/target-ref.ts +1 -21
- package/src/engine/types/tree-node.ts +1 -132
- package/src/engine/types/workspace.ts +2 -49
- package/src/engine/validate-projection-allowlist.ts +6 -6
- package/src/entrypoint/__tests__/entrypoint-job-wiring.integration.test.ts +120 -1
- package/src/entrypoint/index.ts +49 -6
- package/src/errors/classes.ts +22 -1
- package/src/errors/field-issue.ts +0 -3
- package/src/errors/index.ts +1 -1
- package/src/errors/write-error-info.ts +10 -22
- package/src/es-ops/README.md +1 -1
- package/src/es-ops/__tests__/runner.integration.test.ts +74 -0
- package/src/es-ops/context.ts +4 -2
- package/src/es-ops/types.ts +8 -1
- package/src/event-store/__tests__/admin-api.integration.test.ts +27 -1
- package/src/event-store/__tests__/backfill-pii.integration.test.ts +279 -0
- package/src/event-store/__tests__/event-store.integration.test.ts +201 -0
- package/src/event-store/__tests__/row-to-stored-event.test.ts +2 -2
- package/src/event-store/__tests__/snapshot.integration.test.ts +86 -0
- package/src/event-store/__tests__/unscoped-stream-primitives.guard.test.ts +58 -0
- package/src/event-store/__tests__/upcaster.integration.test.ts +77 -45
- package/src/event-store/admin-api.ts +11 -4
- package/src/event-store/errors.ts +2 -35
- package/src/event-store/event-store.ts +64 -78
- package/src/event-store/events-schema.ts +11 -13
- package/src/event-store/index.ts +18 -3
- package/src/event-store/rebuild-dead-letter.ts +111 -0
- package/src/event-store/snapshot.ts +63 -40
- package/src/event-store/types.ts +2 -0
- package/src/files/__tests__/build-storage-key.test.ts +28 -0
- package/src/files/__tests__/file-ref-entity.test.ts +8 -0
- package/src/files/__tests__/files.integration.test.ts +24 -0
- package/src/files/__tests__/in-memory-provider.contract.test.ts +4 -0
- package/src/files/__tests__/local-provider.test.ts +31 -0
- package/src/files/__tests__/provider-resolver.test.ts +70 -0
- package/src/files/__tests__/write-stream.test.ts +13 -0
- package/src/files/file-handle.ts +2 -19
- package/src/files/file-ref-entity.ts +2 -2
- package/src/files/file-routes.ts +13 -0
- package/src/files/index.ts +1 -1
- package/src/files/local-provider.ts +27 -8
- package/src/files/provider-resolver.ts +31 -20
- package/src/files/types.ts +13 -55
- package/src/i18n/__tests__/required-surface-keys.test.ts +17 -0
- package/src/i18n/required-surface-keys.ts +120 -1
- package/src/jobs/__tests__/job-queue-depth.integration.test.ts +82 -0
- package/src/jobs/__tests__/jobs.integration.test.ts +329 -3
- package/src/jobs/job-runner.ts +82 -12
- package/src/logging/types.ts +1 -7
- package/src/migrations/pending-rebuilds.ts +1 -1
- package/src/observability/__tests__/observability.integration.test.ts +4 -1
- package/src/observability/__tests__/recording-tracer.test.ts +6 -4
- package/src/observability/index.ts +2 -0
- package/src/observability/noop-provider.ts +0 -9
- package/src/observability/recording-tracer.ts +0 -12
- package/src/observability/standard-metrics.ts +64 -2
- package/src/observability/types/index.ts +1 -29
- package/src/observability/types/metric.ts +1 -56
- package/src/observability/types/provider.ts +1 -32
- package/src/observability/types/span.ts +1 -64
- package/src/pipeline/__tests__/ctx-bridge.integration.test.ts +2 -2
- package/src/pipeline/__tests__/dispatcher.test.ts +366 -1
- package/src/pipeline/__tests__/event-consumer-state.integration.test.ts +31 -0
- package/src/pipeline/__tests__/event-dispatcher-delivery-max-attempts.test.ts +126 -0
- package/src/pipeline/__tests__/event-dispatcher-rearm.integration.test.ts +263 -0
- package/src/pipeline/__tests__/event-dispatcher.integration.test.ts +10 -0
- package/src/pipeline/__tests__/job-trigger-consumer.integration.test.ts +106 -0
- package/src/pipeline/__tests__/lifecycle-pipeline.test.ts +308 -77
- package/src/pipeline/__tests__/load-aggregate-query.integration.test.ts +16 -8
- package/src/pipeline/__tests__/post-query-hook.integration.test.ts +3 -3
- package/src/pipeline/__tests__/projection-rebuild.integration.test.ts +80 -2
- package/src/pipeline/__tests__/rebuild-poison-quarantine.integration.test.ts +274 -0
- package/src/pipeline/__tests__/try-append-event.integration.test.ts +166 -0
- package/src/pipeline/dispatch-batch.ts +187 -0
- package/src/pipeline/dispatch-query.ts +165 -0
- package/src/pipeline/dispatch-shared.ts +826 -0
- package/src/pipeline/dispatch-stream.ts +90 -0
- package/src/pipeline/dispatch-write.ts +451 -0
- package/src/pipeline/dispatcher-utils.ts +1 -1
- package/src/pipeline/dispatcher.ts +44 -1372
- package/src/pipeline/entity-cache.ts +2 -33
- package/src/pipeline/event-consumer-state.ts +30 -2
- package/src/pipeline/event-dispatcher-admin.ts +293 -0
- package/src/pipeline/event-dispatcher-delivery.ts +305 -0
- package/src/pipeline/event-dispatcher.ts +85 -542
- package/src/pipeline/index.ts +2 -0
- package/src/pipeline/msp-rebuild.ts +42 -3
- package/src/pipeline/multi-stream-apply-context.ts +4 -42
- package/src/pipeline/projection-rebuild.ts +105 -3
- package/src/pipeline/system-hooks.ts +144 -1
- package/src/rate-limit/__tests__/resolver.integration.test.ts +18 -0
- package/src/rate-limit/resolver.ts +16 -32
- package/src/schema-cli.ts +76 -16
- package/src/search/__tests__/meilisearch-adapter.integration.test.ts +207 -185
- package/src/search/__tests__/meilisearch-ids.test.ts +30 -0
- package/src/search/__tests__/reindex-entity.integration.test.ts +144 -0
- package/src/search/index.ts +6 -0
- package/src/search/meilisearch-adapter.ts +13 -12
- package/src/search/reindex-entity.ts +177 -0
- package/src/search/types.ts +1 -39
- package/src/secrets/__tests__/contains-secret.test.ts +34 -0
- package/src/secrets/__tests__/envelope-cipher.test.ts +59 -0
- package/src/secrets/__tests__/envelope.test.ts +1 -1
- package/src/secrets/dek-cache.ts +26 -5
- package/src/secrets/envelope-cipher.ts +53 -0
- package/src/secrets/envelope.ts +5 -3
- package/src/secrets/index.ts +13 -1
- package/src/secrets/stored-envelope.ts +46 -0
- package/src/secrets/types.ts +2 -162
- package/src/stack/__tests__/event-collector.test.ts +42 -0
- package/src/stack/__tests__/setup-test-stack-jobs.integration.test.ts +125 -0
- package/src/stack/db.ts +2 -1
- package/src/stack/push-entity-projection-tables.ts +4 -3
- package/src/stack/redis.ts +8 -0
- package/src/stack/request-helper.ts +38 -2
- package/src/stack/table-helpers.ts +6 -4
- package/src/stack/test-stack.ts +249 -131
- package/src/testing/__tests__/late-bound.test.ts +32 -0
- package/src/testing/__tests__/wait-for.test.ts +59 -0
- package/src/testing/boot-validator-fixture.ts +121 -0
- package/src/testing/e2e-generator.ts +8 -0
- package/src/testing/file-provider-contract.ts +104 -0
- package/src/testing/handler-context.ts +3 -1
- package/src/testing/index.ts +5 -0
- package/src/testing/late-bound.ts +5 -3
- package/src/testing/mutable-master-key-provider.ts +29 -3
- package/src/testing/wait-for.ts +3 -0
- package/src/testing/without-ambient-temporal.ts +14 -0
- package/src/time/__tests__/tz-dateline.test.ts +8 -10
- package/src/time/geo-tz.ts +1 -32
- package/src/time/index.ts +1 -0
- package/src/time/legacy-date.ts +18 -0
- package/src/time/polyfill.ts +21 -38
- package/src/time/tz-context.ts +44 -85
- package/src/ui-types/app-schema.ts +12 -0
- package/src/ui-types/index.ts +20 -7
- package/src/utils/__tests__/safe-json-temporal.test.ts +18 -0
- package/src/utils/safe-json.ts +13 -1
- package/src/__tests__/raw-table.integration.test.ts +0 -116
- package/src/bun-db/__tests__/bun-test-stack.ts +0 -6
- package/src/db/__tests__/encryption.test.ts +0 -39
- package/src/db/encryption.ts +0 -39
- package/src/db/row-helpers.ts +0 -4
- package/src/engine/__tests__/raw-table.test.ts +0 -150
- package/src/engine/__tests__/unmanaged-table.test.ts +0 -127
- package/src/engine/feature-ast/__tests__/visual-tree-parse.test.ts +0 -184
- package/src/engine/feature-ast/extractors/round4.ts +0 -1366
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import type { CallExpression, Node, SourceFile } from "ts-morph";
|
|
2
|
+
import { SyntaxKind } from "ts-morph";
|
|
3
|
+
import type { RunIn } from "../../types/config";
|
|
4
|
+
import type { MspErrorMode } from "../../types/projection";
|
|
5
|
+
import type { ScreenDefinition } from "../../types/screen";
|
|
6
|
+
import type {
|
|
7
|
+
MultiStreamProjectionPattern,
|
|
8
|
+
OpaquePropMap,
|
|
9
|
+
ProjectionPattern,
|
|
10
|
+
ScreenPattern,
|
|
11
|
+
} from "../patterns";
|
|
12
|
+
import { SCREEN_OPAQUE_MARKER } from "../patterns";
|
|
13
|
+
import type { SourceLocation } from "../source-location";
|
|
14
|
+
import { sourceLocationFromNode } from "../source-location";
|
|
15
|
+
import {
|
|
16
|
+
type ExtractOutput,
|
|
17
|
+
fail,
|
|
18
|
+
findFunctionLiteral,
|
|
19
|
+
isPlainObject,
|
|
20
|
+
isRawRefSentinel,
|
|
21
|
+
ok,
|
|
22
|
+
readDataLiteralNode,
|
|
23
|
+
readNameOrRefOrList,
|
|
24
|
+
readPropertyKey,
|
|
25
|
+
} from "./shared";
|
|
26
|
+
|
|
27
|
+
export function readApplyBodies(
|
|
28
|
+
defObj: ReturnType<Node["asKind"]>,
|
|
29
|
+
sourceFile: SourceFile,
|
|
30
|
+
): Record<string, SourceLocation> | undefined {
|
|
31
|
+
if (!defObj) return undefined;
|
|
32
|
+
const obj = defObj.asKind?.(SyntaxKind.ObjectLiteralExpression);
|
|
33
|
+
if (!obj) return undefined;
|
|
34
|
+
const applyObj = obj
|
|
35
|
+
.getProperty("apply")
|
|
36
|
+
?.asKind(SyntaxKind.PropertyAssignment)
|
|
37
|
+
?.getInitializer()
|
|
38
|
+
?.asKind(SyntaxKind.ObjectLiteralExpression);
|
|
39
|
+
if (!applyObj) return undefined;
|
|
40
|
+
const out: Record<string, SourceLocation> = {};
|
|
41
|
+
for (const prop of applyObj.getProperties()) {
|
|
42
|
+
const propAssign = prop.asKind(SyntaxKind.PropertyAssignment);
|
|
43
|
+
if (!propAssign) return undefined;
|
|
44
|
+
const init = propAssign.getInitializer();
|
|
45
|
+
if (!init) return undefined;
|
|
46
|
+
const fn = findFunctionLiteral(init);
|
|
47
|
+
if (!fn) return undefined;
|
|
48
|
+
out[readPropertyKey(propAssign)] = sourceLocationFromNode(fn, sourceFile);
|
|
49
|
+
}
|
|
50
|
+
return out;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function extractProjection(
|
|
54
|
+
call: CallExpression,
|
|
55
|
+
sourceFile: SourceFile,
|
|
56
|
+
): ExtractOutput<ProjectionPattern> {
|
|
57
|
+
const arg = call.getArguments()[0]?.asKind(SyntaxKind.ObjectLiteralExpression);
|
|
58
|
+
if (!arg) {
|
|
59
|
+
return fail(
|
|
60
|
+
"projection",
|
|
61
|
+
sourceLocationFromNode(call, sourceFile),
|
|
62
|
+
"argument must be an inline ProjectionDefinition object",
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
const nameLit = arg
|
|
66
|
+
.getProperty("name")
|
|
67
|
+
?.asKind(SyntaxKind.PropertyAssignment)
|
|
68
|
+
?.getInitializer()
|
|
69
|
+
?.asKind(SyntaxKind.StringLiteral);
|
|
70
|
+
if (!nameLit) {
|
|
71
|
+
return fail(
|
|
72
|
+
"projection",
|
|
73
|
+
sourceLocationFromNode(call, sourceFile),
|
|
74
|
+
"name must be a string literal",
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
const sourceInit = arg
|
|
78
|
+
.getProperty("source")
|
|
79
|
+
?.asKind(SyntaxKind.PropertyAssignment)
|
|
80
|
+
?.getInitializer();
|
|
81
|
+
if (!sourceInit) {
|
|
82
|
+
return fail(
|
|
83
|
+
"projection",
|
|
84
|
+
sourceLocationFromNode(call, sourceFile),
|
|
85
|
+
"missing `source` property",
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
const sourceEntity = readNameOrRefOrList(sourceInit);
|
|
89
|
+
if (!sourceEntity) {
|
|
90
|
+
return fail(
|
|
91
|
+
"projection",
|
|
92
|
+
sourceLocationFromNode(call, sourceFile),
|
|
93
|
+
"source must be a string literal or array of string literals",
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
const applyBodies = readApplyBodies(arg, sourceFile);
|
|
97
|
+
if (!applyBodies) {
|
|
98
|
+
return fail(
|
|
99
|
+
"projection",
|
|
100
|
+
sourceLocationFromNode(call, sourceFile),
|
|
101
|
+
"apply must be an inline object map of event-type → function",
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
return ok({
|
|
105
|
+
kind: "projection",
|
|
106
|
+
source: sourceLocationFromNode(call, sourceFile),
|
|
107
|
+
name: nameLit.getLiteralValue(),
|
|
108
|
+
sourceEntity,
|
|
109
|
+
applyBodies,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export function extractMultiStreamProjection(
|
|
114
|
+
call: CallExpression,
|
|
115
|
+
sourceFile: SourceFile,
|
|
116
|
+
): ExtractOutput<MultiStreamProjectionPattern> {
|
|
117
|
+
const arg = call.getArguments()[0]?.asKind(SyntaxKind.ObjectLiteralExpression);
|
|
118
|
+
if (!arg) {
|
|
119
|
+
return fail(
|
|
120
|
+
"multiStreamProjection",
|
|
121
|
+
sourceLocationFromNode(call, sourceFile),
|
|
122
|
+
"argument must be an inline MultiStreamProjectionDefinition object",
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
const nameLit = arg
|
|
126
|
+
.getProperty("name")
|
|
127
|
+
?.asKind(SyntaxKind.PropertyAssignment)
|
|
128
|
+
?.getInitializer()
|
|
129
|
+
?.asKind(SyntaxKind.StringLiteral);
|
|
130
|
+
if (!nameLit) {
|
|
131
|
+
return fail(
|
|
132
|
+
"multiStreamProjection",
|
|
133
|
+
sourceLocationFromNode(call, sourceFile),
|
|
134
|
+
"name must be a string literal",
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
const applyBodies = readApplyBodies(arg, sourceFile);
|
|
138
|
+
if (!applyBodies) {
|
|
139
|
+
return fail(
|
|
140
|
+
"multiStreamProjection",
|
|
141
|
+
sourceLocationFromNode(call, sourceFile),
|
|
142
|
+
"apply must be an inline object map of event-type → function",
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
const errorModeInit = arg
|
|
146
|
+
.getProperty("errorMode")
|
|
147
|
+
?.asKind(SyntaxKind.PropertyAssignment)
|
|
148
|
+
?.getInitializer();
|
|
149
|
+
const errorMode = errorModeInit ? readDataLiteralNode(errorModeInit) : undefined;
|
|
150
|
+
const runInLit = arg
|
|
151
|
+
.getProperty("runIn")
|
|
152
|
+
?.asKind(SyntaxKind.PropertyAssignment)
|
|
153
|
+
?.getInitializer()
|
|
154
|
+
?.asKind(SyntaxKind.StringLiteral);
|
|
155
|
+
const runIn = runInLit ? (runInLit.getLiteralValue() as RunIn) : undefined;
|
|
156
|
+
const deliveryLit = arg
|
|
157
|
+
.getProperty("delivery")
|
|
158
|
+
?.asKind(SyntaxKind.PropertyAssignment)
|
|
159
|
+
?.getInitializer()
|
|
160
|
+
?.asKind(SyntaxKind.StringLiteral);
|
|
161
|
+
const delivery = deliveryLit
|
|
162
|
+
? (deliveryLit.getLiteralValue() as "shared" | "per-instance")
|
|
163
|
+
: undefined;
|
|
164
|
+
return ok({
|
|
165
|
+
kind: "multiStreamProjection",
|
|
166
|
+
source: sourceLocationFromNode(call, sourceFile),
|
|
167
|
+
name: nameLit.getLiteralValue(),
|
|
168
|
+
applyBodies,
|
|
169
|
+
...(isPlainObject(errorMode) && { errorMode: errorMode as MspErrorMode }),
|
|
170
|
+
...(runIn !== undefined && { runIn }),
|
|
171
|
+
...(delivery !== undefined && { delivery }),
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export function collectScreenOpaqueProps(
|
|
176
|
+
node: Node,
|
|
177
|
+
path: string,
|
|
178
|
+
sourceFile: SourceFile,
|
|
179
|
+
out: Record<string, SourceLocation>,
|
|
180
|
+
): void {
|
|
181
|
+
const fn = findFunctionLiteral(node);
|
|
182
|
+
if (fn) {
|
|
183
|
+
out[path] = sourceLocationFromNode(fn, sourceFile);
|
|
184
|
+
} else if (node.isKind(SyntaxKind.ObjectLiteralExpression)) {
|
|
185
|
+
for (const prop of node.getProperties()) {
|
|
186
|
+
const propAssign = prop.asKind(SyntaxKind.PropertyAssignment);
|
|
187
|
+
if (!propAssign) continue;
|
|
188
|
+
const init = propAssign.getInitializer();
|
|
189
|
+
if (!init) continue;
|
|
190
|
+
const key = readPropertyKey(propAssign);
|
|
191
|
+
const childPath = path ? `${path}.${key}` : key;
|
|
192
|
+
collectScreenOpaqueProps(init, childPath, sourceFile, out);
|
|
193
|
+
}
|
|
194
|
+
} else if (node.isKind(SyntaxKind.ArrayLiteralExpression)) {
|
|
195
|
+
node.getElements().forEach((el, idx) => {
|
|
196
|
+
collectScreenOpaqueProps(el, `${path}.${idx}`, sourceFile, out);
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export function readScreenStatic(node: Node): unknown {
|
|
202
|
+
if (findFunctionLiteral(node)) return SCREEN_OPAQUE_MARKER;
|
|
203
|
+
const obj = node.asKind(SyntaxKind.ObjectLiteralExpression);
|
|
204
|
+
if (obj) {
|
|
205
|
+
const out: Record<string, unknown> = {};
|
|
206
|
+
for (const prop of obj.getProperties()) {
|
|
207
|
+
const propAssign = prop.asKind(SyntaxKind.PropertyAssignment);
|
|
208
|
+
if (!propAssign) continue;
|
|
209
|
+
const init = propAssign.getInitializer();
|
|
210
|
+
if (!init) continue;
|
|
211
|
+
out[readPropertyKey(propAssign)] = readScreenStatic(init);
|
|
212
|
+
}
|
|
213
|
+
return out;
|
|
214
|
+
}
|
|
215
|
+
const arr = node.asKind(SyntaxKind.ArrayLiteralExpression);
|
|
216
|
+
if (arr) {
|
|
217
|
+
return arr.getElements().map(readScreenStatic);
|
|
218
|
+
}
|
|
219
|
+
const value = readDataLiteralNode(node);
|
|
220
|
+
if (value === undefined) return SCREEN_OPAQUE_MARKER;
|
|
221
|
+
return value;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export function extractScreen(
|
|
225
|
+
call: CallExpression,
|
|
226
|
+
sourceFile: SourceFile,
|
|
227
|
+
): ExtractOutput<ScreenPattern> {
|
|
228
|
+
const arg = call.getArguments()[0];
|
|
229
|
+
if (!arg) {
|
|
230
|
+
return fail(
|
|
231
|
+
"screen",
|
|
232
|
+
sourceLocationFromNode(call, sourceFile),
|
|
233
|
+
"expected a ScreenDefinition object as first argument",
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
const obj = arg.asKind(SyntaxKind.ObjectLiteralExpression);
|
|
237
|
+
if (!obj) {
|
|
238
|
+
const raw = readDataLiteralNode(arg);
|
|
239
|
+
if (!isRawRefSentinel(raw)) {
|
|
240
|
+
return fail(
|
|
241
|
+
"screen",
|
|
242
|
+
sourceLocationFromNode(call, sourceFile),
|
|
243
|
+
"argument must be an inline object literal",
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
return ok({
|
|
247
|
+
kind: "screen",
|
|
248
|
+
source: sourceLocationFromNode(call, sourceFile),
|
|
249
|
+
definition: raw as unknown as ScreenDefinition,
|
|
250
|
+
opaqueProps: {} as OpaquePropMap,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
const opaqueProps: Record<string, SourceLocation> = {};
|
|
254
|
+
collectScreenOpaqueProps(obj, "", sourceFile, opaqueProps);
|
|
255
|
+
const definition = readScreenStatic(obj);
|
|
256
|
+
if (!isPlainObject(definition)) {
|
|
257
|
+
return fail(
|
|
258
|
+
"screen",
|
|
259
|
+
sourceLocationFromNode(call, sourceFile),
|
|
260
|
+
"definition could not be read structurally",
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
return ok({
|
|
264
|
+
kind: "screen",
|
|
265
|
+
source: sourceLocationFromNode(call, sourceFile),
|
|
266
|
+
definition: definition as ScreenDefinition,
|
|
267
|
+
opaqueProps: opaqueProps as OpaquePropMap,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
@@ -33,7 +33,7 @@ export function extractRequires(
|
|
|
33
33
|
return ok({
|
|
34
34
|
kind: "requires",
|
|
35
35
|
source: sourceLocationFromNode(call, sourceFile),
|
|
36
|
-
featureNames: names,
|
|
36
|
+
featureNames: names as readonly string[],
|
|
37
37
|
});
|
|
38
38
|
}
|
|
39
39
|
|
|
@@ -52,7 +52,7 @@ export function extractOptionalRequires(
|
|
|
52
52
|
return ok({
|
|
53
53
|
kind: "optionalRequires",
|
|
54
54
|
source: sourceLocationFromNode(call, sourceFile),
|
|
55
|
-
featureNames: names,
|
|
55
|
+
featureNames: names as readonly string[],
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
|
|
@@ -71,7 +71,7 @@ export function extractReadsConfig(
|
|
|
71
71
|
return ok({
|
|
72
72
|
kind: "readsConfig",
|
|
73
73
|
source: sourceLocationFromNode(call, sourceFile),
|
|
74
|
-
qualifiedKeys: keys,
|
|
74
|
+
qualifiedKeys: keys as readonly string[],
|
|
75
75
|
});
|
|
76
76
|
}
|
|
77
77
|
|
|
@@ -95,7 +95,7 @@ export function extractExposesApi(
|
|
|
95
95
|
});
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
export function
|
|
98
|
+
export function extractStoreTable(
|
|
99
99
|
call: CallExpression,
|
|
100
100
|
sourceFile: SourceFile,
|
|
101
101
|
): ExtractOutput<never> {
|
|
@@ -104,8 +104,8 @@ export function extractUnmanagedTable(
|
|
|
104
104
|
// so there is nothing to extract statically. A clean ParseError (not
|
|
105
105
|
// UnknownPattern) marks it design-time-unreadable, like entity-by-identifier.
|
|
106
106
|
return fail(
|
|
107
|
-
"
|
|
107
|
+
"storeTable",
|
|
108
108
|
sourceLocationFromNode(call, sourceFile),
|
|
109
|
-
"
|
|
109
|
+
"storeTable meta is a factory/identifier argument, not a static literal",
|
|
110
110
|
);
|
|
111
111
|
}
|
|
@@ -1,15 +1,8 @@
|
|
|
1
1
|
import type { CallExpression, SourceFile } from "ts-morph";
|
|
2
2
|
import type { TreeActionDef } from "../../types/tree-node";
|
|
3
|
-
import type { TreeActionsPattern
|
|
3
|
+
import type { TreeActionsPattern } from "../patterns";
|
|
4
4
|
import { sourceLocationFromNode } from "../source-location";
|
|
5
|
-
import {
|
|
6
|
-
type ExtractOutput,
|
|
7
|
-
fail,
|
|
8
|
-
findFunctionLiteral,
|
|
9
|
-
isPlainObject,
|
|
10
|
-
ok,
|
|
11
|
-
readDataLiteralNode,
|
|
12
|
-
} from "./shared";
|
|
5
|
+
import { type ExtractOutput, fail, isPlainObject, ok, readDataLiteralNode } from "./shared";
|
|
13
6
|
|
|
14
7
|
export function extractTreeActions(
|
|
15
8
|
call: CallExpression,
|
|
@@ -37,30 +30,3 @@ export function extractTreeActions(
|
|
|
37
30
|
definitions: definitions as Readonly<Record<string, TreeActionDef>>,
|
|
38
31
|
});
|
|
39
32
|
}
|
|
40
|
-
|
|
41
|
-
export function extractTree(
|
|
42
|
-
call: CallExpression,
|
|
43
|
-
sourceFile: SourceFile,
|
|
44
|
-
): ExtractOutput<TreePattern> {
|
|
45
|
-
const arg = call.getArguments()[0];
|
|
46
|
-
if (!arg) {
|
|
47
|
-
return fail(
|
|
48
|
-
"tree",
|
|
49
|
-
sourceLocationFromNode(call, sourceFile),
|
|
50
|
-
"expected a tree-provider function as first argument",
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
const fn = findFunctionLiteral(arg);
|
|
54
|
-
if (!fn) {
|
|
55
|
-
return fail(
|
|
56
|
-
"tree",
|
|
57
|
-
sourceLocationFromNode(call, sourceFile),
|
|
58
|
-
"first argument must be an inline arrow function or function expression",
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
return ok({
|
|
62
|
-
kind: "tree",
|
|
63
|
-
source: sourceLocationFromNode(call, sourceFile),
|
|
64
|
-
providerBody: sourceLocationFromNode(fn, sourceFile),
|
|
65
|
-
});
|
|
66
|
-
}
|
|
@@ -47,6 +47,25 @@ export function readBooleanProperty(
|
|
|
47
47
|
return undefined;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Marks a value the parser could not resolve into a literal (an Identifier
|
|
52
|
+
* reference, a call expression, ...) while preserving its exact source text.
|
|
53
|
+
* `renderValue` re-emits `__raw` verbatim instead of re-serializing the
|
|
54
|
+
* value, so round-tripping a reference like `eventEntity` never expands it
|
|
55
|
+
* into an inlined object literal.
|
|
56
|
+
*/
|
|
57
|
+
export type RawRefSentinel = { readonly __raw: string };
|
|
58
|
+
|
|
59
|
+
export function isRawRefSentinel(value: unknown): value is RawRefSentinel {
|
|
60
|
+
return (
|
|
61
|
+
value !== null &&
|
|
62
|
+
typeof value === "object" &&
|
|
63
|
+
!Array.isArray(value) &&
|
|
64
|
+
"__raw" in value &&
|
|
65
|
+
typeof (value as { __raw: unknown }).__raw === "string"
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
50
69
|
export function readDataLiteralNode(node: Node): unknown {
|
|
51
70
|
const kind = node.getKind();
|
|
52
71
|
switch (kind) {
|
|
@@ -103,11 +122,50 @@ export function readDataLiteralNode(node: Node): unknown {
|
|
|
103
122
|
return readDataLiteralNode(
|
|
104
123
|
node.asKindOrThrow(SyntaxKind.ParenthesizedExpression).getExpression(),
|
|
105
124
|
);
|
|
125
|
+
case SyntaxKind.Identifier:
|
|
126
|
+
case SyntaxKind.CallExpression:
|
|
127
|
+
case SyntaxKind.PropertyAccessExpression:
|
|
128
|
+
// Unresolvable reference (const identifier, factory call, member access).
|
|
129
|
+
// Keep the exact source text so renderValue can re-emit it verbatim —
|
|
130
|
+
// resolving/inlining it would silently rewrite the source on the next
|
|
131
|
+
// parse->render roundtrip (see readDataLiteralNode doc above).
|
|
132
|
+
return { __raw: node.getText() } satisfies RawRefSentinel;
|
|
106
133
|
default:
|
|
107
134
|
return undefined;
|
|
108
135
|
}
|
|
109
136
|
}
|
|
110
137
|
|
|
138
|
+
/**
|
|
139
|
+
* A node's literal string value, or the raw-ref sentinel when it resolves to
|
|
140
|
+
* an unresolvable identifier/factory-call/member-access (see
|
|
141
|
+
* readDataLiteralNode). undefined for anything else (number, boolean, ...).
|
|
142
|
+
*/
|
|
143
|
+
export function readStringOrRaw(node: Node): string | RawRefSentinel | undefined {
|
|
144
|
+
const value = readDataLiteralNode(node);
|
|
145
|
+
if (typeof value === "string") return value;
|
|
146
|
+
if (isRawRefSentinel(value)) return value;
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Like readStringLiteralArgs, but an argument that resolves to a raw-ref
|
|
152
|
+
* sentinel is kept as that sentinel instead of failing the whole call. Used
|
|
153
|
+
* where a value stands in for a single name/key and inlining its resolved
|
|
154
|
+
* string would corrupt the render roundtrip (e.g. `r.requires(someFeature.name)`
|
|
155
|
+
* — see #1009).
|
|
156
|
+
*/
|
|
157
|
+
export function readStringOrRawArgs(
|
|
158
|
+
call: CallExpression,
|
|
159
|
+
): readonly (string | RawRefSentinel)[] | undefined {
|
|
160
|
+
const out: (string | RawRefSentinel)[] = [];
|
|
161
|
+
for (const arg of call.getArguments()) {
|
|
162
|
+
const value = readStringOrRaw(arg);
|
|
163
|
+
if (value === undefined) return undefined;
|
|
164
|
+
out.push(value);
|
|
165
|
+
}
|
|
166
|
+
return out;
|
|
167
|
+
}
|
|
168
|
+
|
|
111
169
|
export { isPlainObject } from "../../../utils/is-plain-object";
|
|
112
170
|
|
|
113
171
|
export function readPropertyKey(propAssign: import("ts-morph").PropertyAssignment): string {
|
|
@@ -150,7 +208,7 @@ export function readNameOrRefOrList(node: Node): string | readonly string[] | un
|
|
|
150
208
|
export function readVarargsOrArrayProp(
|
|
151
209
|
call: CallExpression,
|
|
152
210
|
arrayPropName: "features" | "keys",
|
|
153
|
-
): readonly string[] | undefined {
|
|
211
|
+
): readonly (string | RawRefSentinel)[] | undefined {
|
|
154
212
|
const args = call.getArguments();
|
|
155
213
|
if (args.length === 1) {
|
|
156
214
|
const obj = args[0]?.asKind(SyntaxKind.ObjectLiteralExpression);
|
|
@@ -162,15 +220,15 @@ export function readVarargsOrArrayProp(
|
|
|
162
220
|
if (propInit) {
|
|
163
221
|
const arr = propInit.asKind(SyntaxKind.ArrayLiteralExpression);
|
|
164
222
|
if (!arr) return undefined;
|
|
165
|
-
const out: string[] = [];
|
|
223
|
+
const out: (string | RawRefSentinel)[] = [];
|
|
166
224
|
for (const el of arr.getElements()) {
|
|
167
|
-
const
|
|
168
|
-
if (
|
|
169
|
-
out.push(
|
|
225
|
+
const value = readStringOrRaw(el);
|
|
226
|
+
if (value === undefined) return undefined;
|
|
227
|
+
out.push(value);
|
|
170
228
|
}
|
|
171
229
|
return out;
|
|
172
230
|
}
|
|
173
231
|
}
|
|
174
232
|
}
|
|
175
|
-
return
|
|
233
|
+
return readStringOrRawArgs(call);
|
|
176
234
|
}
|
|
@@ -27,8 +27,6 @@ export type {
|
|
|
27
27
|
AddConfigArgs,
|
|
28
28
|
AddDefineEventArgs,
|
|
29
29
|
AddEntityArgs,
|
|
30
|
-
AddEntityHookArgs,
|
|
31
|
-
AddEventMigrationArgs,
|
|
32
30
|
AddHookArgs,
|
|
33
31
|
AddHttpRouteArgs,
|
|
34
32
|
AddJobArgs,
|
|
@@ -45,6 +43,7 @@ export type {
|
|
|
45
43
|
AddRequiresArgs,
|
|
46
44
|
AddScreenArgs,
|
|
47
45
|
AddSecretArgs,
|
|
46
|
+
AddStreamHandlerArgs,
|
|
48
47
|
AddToggleableArgs,
|
|
49
48
|
AddTranslationsArgs,
|
|
50
49
|
AddUseExtensionArgs,
|
|
@@ -59,10 +58,8 @@ export type {
|
|
|
59
58
|
ConfigPattern,
|
|
60
59
|
DefineEventPattern,
|
|
61
60
|
Editability,
|
|
62
|
-
EntityHookPattern,
|
|
63
61
|
// Static patterns
|
|
64
62
|
EntityPattern,
|
|
65
|
-
EventMigrationPattern,
|
|
66
63
|
ExtendsRegistrarPattern,
|
|
67
64
|
FeaturePattern,
|
|
68
65
|
FeaturePatternKind,
|
|
@@ -83,6 +80,7 @@ export type {
|
|
|
83
80
|
// Mixed patterns
|
|
84
81
|
ScreenPattern,
|
|
85
82
|
SecretPattern,
|
|
83
|
+
StreamHandlerPattern,
|
|
86
84
|
SystemScopePattern,
|
|
87
85
|
ToggleablePattern,
|
|
88
86
|
TranslationsPattern,
|