@cosmicdrift/kumiko-framework 0.1.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 +159 -0
- package/package.json +91 -0
- package/src/__tests__/anonymous-access.integration.ts +325 -0
- package/src/__tests__/error-contract.integration.ts +435 -0
- package/src/__tests__/field-access.integration.ts +269 -0
- package/src/__tests__/full-stack.integration.ts +914 -0
- package/src/__tests__/ownership.integration.ts +449 -0
- package/src/__tests__/reference-data.integration.ts +198 -0
- package/src/__tests__/transition-guard.integration.ts +340 -0
- package/src/api/__tests__/api.test.ts +337 -0
- package/src/api/__tests__/auth-middleware-transport.test.ts +80 -0
- package/src/api/__tests__/auth-routes-cookie.test.ts +179 -0
- package/src/api/__tests__/batch.integration.ts +404 -0
- package/src/api/__tests__/body-limit.test.ts +88 -0
- package/src/api/__tests__/csrf-middleware.test.ts +97 -0
- package/src/api/__tests__/dispatcher-live.integration.ts +216 -0
- package/src/api/__tests__/metrics-endpoint.test.ts +126 -0
- package/src/api/__tests__/nested-write.integration.ts +213 -0
- package/src/api/__tests__/readiness.test.ts +76 -0
- package/src/api/__tests__/request-id-middleware.test.ts +72 -0
- package/src/api/__tests__/sse-broker.test.ts +58 -0
- package/src/api/__tests__/sse-route.test.ts +112 -0
- package/src/api/anonymous-cookie.ts +60 -0
- package/src/api/api-constants.ts +64 -0
- package/src/api/auth-middleware.ts +418 -0
- package/src/api/auth-routes.ts +982 -0
- package/src/api/csrf-middleware.ts +77 -0
- package/src/api/index.ts +31 -0
- package/src/api/jwt.ts +66 -0
- package/src/api/observability-middleware.ts +89 -0
- package/src/api/readiness.ts +132 -0
- package/src/api/request-context.ts +49 -0
- package/src/api/request-id-middleware.ts +50 -0
- package/src/api/route-registrars.ts +195 -0
- package/src/api/routes.ts +135 -0
- package/src/api/server.ts +640 -0
- package/src/api/sse-broker.ts +71 -0
- package/src/api/sse-route.ts +62 -0
- package/src/api/tokens.ts +16 -0
- package/src/db/__tests__/apply-entity-event-tenant.integration.ts +159 -0
- package/src/db/__tests__/compound-types.test.ts +114 -0
- package/src/db/__tests__/connection-options.test.ts +68 -0
- package/src/db/__tests__/cursor.test.ts +41 -0
- package/src/db/__tests__/db-helpers.test.ts +369 -0
- package/src/db/__tests__/dialect-instant.test.ts +50 -0
- package/src/db/__tests__/drizzle-helpers.integration.ts +186 -0
- package/src/db/__tests__/drizzle-table-types.test.ts +162 -0
- package/src/db/__tests__/encryption.test.ts +39 -0
- package/src/db/__tests__/event-store-executor-list.integration.ts +313 -0
- package/src/db/__tests__/event-store-executor.integration.ts +235 -0
- package/src/db/__tests__/implicit-projection-equivalence.integration.ts +304 -0
- package/src/db/__tests__/located-timestamp.test.ts +184 -0
- package/src/db/__tests__/money.test.ts +199 -0
- package/src/db/__tests__/multi-row-insert.integration.ts +76 -0
- package/src/db/__tests__/parse-auto-verb.test.ts +70 -0
- package/src/db/__tests__/required-not-null-migration-safety.integration.ts +105 -0
- package/src/db/__tests__/row-helpers.test.ts +59 -0
- package/src/db/__tests__/schema-migration.integration.ts +273 -0
- package/src/db/__tests__/table-builder-indexes.test.ts +153 -0
- package/src/db/__tests__/table-builder-required.test.ts +216 -0
- package/src/db/__tests__/tenant-db.integration.ts +606 -0
- package/src/db/__tests__/unique-violation-mapping.integration.ts +166 -0
- package/src/db/apply-entity-event.ts +188 -0
- package/src/db/assert-exists-in.ts +59 -0
- package/src/db/compound-types.ts +47 -0
- package/src/db/connection.ts +104 -0
- package/src/db/cursor.ts +83 -0
- package/src/db/dialect.ts +109 -0
- package/src/db/eagerload.ts +174 -0
- package/src/db/encryption.ts +39 -0
- package/src/db/event-store-executor.ts +906 -0
- package/src/db/index.ts +55 -0
- package/src/db/located-timestamp.ts +114 -0
- package/src/db/money.ts +120 -0
- package/src/db/pg-error.ts +46 -0
- package/src/db/reference-data.ts +77 -0
- package/src/db/row-helpers.ts +53 -0
- package/src/db/schema-inspection.ts +25 -0
- package/src/db/table-builder.ts +475 -0
- package/src/db/tenant-db.ts +434 -0
- package/src/engine/__tests__/auth-claims-registrar.test.ts +74 -0
- package/src/engine/__tests__/boot-validator-located-timestamps.test.ts +108 -0
- package/src/engine/__tests__/boot-validator.test.ts +1865 -0
- package/src/engine/__tests__/build-app-schema.test.ts +154 -0
- package/src/engine/__tests__/claim-keys.test.ts +274 -0
- package/src/engine/__tests__/config-helpers.test.ts +236 -0
- package/src/engine/__tests__/effective-features.test.ts +86 -0
- package/src/engine/__tests__/engine.test.ts +1461 -0
- package/src/engine/__tests__/entity-handlers.test.ts +274 -0
- package/src/engine/__tests__/event-helpers.test.ts +68 -0
- package/src/engine/__tests__/extends-registrar.test.ts +159 -0
- package/src/engine/__tests__/factories-long-text.test.ts +84 -0
- package/src/engine/__tests__/factories-time.test.ts +158 -0
- package/src/engine/__tests__/field-predicates.test.ts +48 -0
- package/src/engine/__tests__/hook-phases.test.ts +132 -0
- package/src/engine/__tests__/identifiers.test.ts +35 -0
- package/src/engine/__tests__/lifecycle-hooks.test.ts +237 -0
- package/src/engine/__tests__/nav.test.ts +267 -0
- package/src/engine/__tests__/ownership.test.ts +421 -0
- package/src/engine/__tests__/parse-ref-target.test.ts +43 -0
- package/src/engine/__tests__/projection-helpers.test.ts +62 -0
- package/src/engine/__tests__/projection.test.ts +191 -0
- package/src/engine/__tests__/qualified-name.test.ts +264 -0
- package/src/engine/__tests__/resolve-config-or-param.test.ts +315 -0
- package/src/engine/__tests__/run-in.test.ts +38 -0
- package/src/engine/__tests__/schema-builder.test.ts +380 -0
- package/src/engine/__tests__/screen.test.ts +408 -0
- package/src/engine/__tests__/state-machine.test.ts +148 -0
- package/src/engine/__tests__/system-user.test.ts +57 -0
- package/src/engine/__tests__/validation-hooks.test.ts +71 -0
- package/src/engine/access.ts +23 -0
- package/src/engine/boot-validator.ts +1528 -0
- package/src/engine/build-app-schema.ts +125 -0
- package/src/engine/config-helpers.ts +115 -0
- package/src/engine/constants.ts +85 -0
- package/src/engine/create-app.ts +98 -0
- package/src/engine/define-feature.ts +702 -0
- package/src/engine/define-handler.ts +78 -0
- package/src/engine/define-roles.ts +19 -0
- package/src/engine/effective-features.ts +87 -0
- package/src/engine/entity-handlers.ts +364 -0
- package/src/engine/event-helpers.ts +73 -0
- package/src/engine/factories.ts +328 -0
- package/src/engine/feature-ast/__tests__/canonical-form.test.ts +416 -0
- package/src/engine/feature-ast/__tests__/parse-happy-path.test.ts +197 -0
- package/src/engine/feature-ast/__tests__/parse-real-features.test.ts +128 -0
- package/src/engine/feature-ast/__tests__/parse.test.ts +888 -0
- package/src/engine/feature-ast/__tests__/patch.test.ts +360 -0
- package/src/engine/feature-ast/__tests__/patcher.test.ts +469 -0
- package/src/engine/feature-ast/__tests__/render-roundtrip.test.ts +287 -0
- package/src/engine/feature-ast/extractors.ts +2562 -0
- package/src/engine/feature-ast/index.ts +105 -0
- package/src/engine/feature-ast/parse.ts +369 -0
- package/src/engine/feature-ast/patch.ts +525 -0
- package/src/engine/feature-ast/patcher.ts +518 -0
- package/src/engine/feature-ast/patterns.ts +434 -0
- package/src/engine/feature-ast/render.ts +602 -0
- package/src/engine/feature-ast/source-location.ts +45 -0
- package/src/engine/field-access.ts +120 -0
- package/src/engine/index.ts +254 -0
- package/src/engine/ownership.ts +337 -0
- package/src/engine/parse-ref-target.ts +22 -0
- package/src/engine/pattern-library/__tests__/library.test.ts +351 -0
- package/src/engine/pattern-library/index.ts +24 -0
- package/src/engine/pattern-library/library.ts +1117 -0
- package/src/engine/pattern-library/types.ts +255 -0
- package/src/engine/projection-helpers.ts +85 -0
- package/src/engine/qualified-name.ts +122 -0
- package/src/engine/read-claim.ts +31 -0
- package/src/engine/registry.ts +1325 -0
- package/src/engine/resolve-config-or-param.ts +153 -0
- package/src/engine/run-in.ts +29 -0
- package/src/engine/schema-builder.ts +175 -0
- package/src/engine/screen-filter-ops.ts +51 -0
- package/src/engine/state-machine.ts +70 -0
- package/src/engine/system-user.ts +32 -0
- package/src/engine/types/config.ts +306 -0
- package/src/engine/types/event-type-map.ts +37 -0
- package/src/engine/types/feature.ts +574 -0
- package/src/engine/types/fields.ts +422 -0
- package/src/engine/types/handlers.ts +742 -0
- package/src/engine/types/hooks.ts +142 -0
- package/src/engine/types/http-route.ts +54 -0
- package/src/engine/types/identifiers.ts +47 -0
- package/src/engine/types/index.ts +208 -0
- package/src/engine/types/nav.ts +46 -0
- package/src/engine/types/projection.ts +132 -0
- package/src/engine/types/relations.ts +51 -0
- package/src/engine/types/screen.ts +452 -0
- package/src/engine/types/workspace.ts +42 -0
- package/src/engine/validation.ts +33 -0
- package/src/entrypoint/__tests__/entrypoint-job-wiring.integration.ts +173 -0
- package/src/entrypoint/__tests__/split-deploy.integration.ts +297 -0
- package/src/entrypoint/index.ts +442 -0
- package/src/errors/__tests__/classes.test.ts +371 -0
- package/src/errors/__tests__/write-failures.test.ts +109 -0
- package/src/errors/classes.ts +249 -0
- package/src/errors/i18n/de.yaml +83 -0
- package/src/errors/i18n/en.yaml +80 -0
- package/src/errors/index.ts +41 -0
- package/src/errors/kumiko-error.ts +67 -0
- package/src/errors/reasons.ts +36 -0
- package/src/errors/serialize.ts +136 -0
- package/src/errors/transition-details.ts +30 -0
- package/src/errors/write-error-info.ts +123 -0
- package/src/errors/zod-bridge.ts +49 -0
- package/src/event-store/__tests__/admin-api.integration.ts +361 -0
- package/src/event-store/__tests__/event-store.integration.ts +584 -0
- package/src/event-store/__tests__/get-stream-version-perf.integration.ts +83 -0
- package/src/event-store/__tests__/perf.integration.ts +255 -0
- package/src/event-store/__tests__/snapshot.integration.ts +267 -0
- package/src/event-store/__tests__/upcaster-dead-letter.integration.ts +204 -0
- package/src/event-store/__tests__/upcaster.integration.ts +460 -0
- package/src/event-store/admin-api.ts +257 -0
- package/src/event-store/archive.ts +106 -0
- package/src/event-store/errors.ts +35 -0
- package/src/event-store/event-store.ts +405 -0
- package/src/event-store/events-schema.ts +90 -0
- package/src/event-store/index.ts +50 -0
- package/src/event-store/snapshot.ts +210 -0
- package/src/event-store/upcaster-dead-letter.ts +119 -0
- package/src/event-store/upcaster.ts +147 -0
- package/src/files/__tests__/content-disposition.test.ts +123 -0
- package/src/files/__tests__/file-field-column.integration.ts +103 -0
- package/src/files/__tests__/file-field-pipeline.integration.ts +211 -0
- package/src/files/__tests__/file-handle.test.ts +122 -0
- package/src/files/__tests__/files.integration.ts +830 -0
- package/src/files/__tests__/storage-tracking.integration.ts +153 -0
- package/src/files/content-disposition.ts +55 -0
- package/src/files/file-handle.ts +63 -0
- package/src/files/file-ref-table.ts +22 -0
- package/src/files/file-routes.ts +353 -0
- package/src/files/in-memory-provider.ts +62 -0
- package/src/files/index.ts +29 -0
- package/src/files/local-provider.ts +35 -0
- package/src/files/storage-tracking.ts +60 -0
- package/src/files/types.ts +118 -0
- package/src/i18n/__tests__/i18n.test.ts +72 -0
- package/src/i18n/index.ts +29 -0
- package/src/jobs/__tests__/job-event-trigger.integration.ts +172 -0
- package/src/jobs/__tests__/job-multi-trigger.integration.ts +144 -0
- package/src/jobs/__tests__/jobs.integration.ts +566 -0
- package/src/jobs/index.ts +2 -0
- package/src/jobs/job-runner.ts +574 -0
- package/src/lifecycle/__tests__/create-test-lifecycle.ts +19 -0
- package/src/lifecycle/__tests__/lifecycle-server.integration.ts +108 -0
- package/src/lifecycle/__tests__/lifecycle.test.ts +212 -0
- package/src/lifecycle/__tests__/signal-handlers.test.ts +106 -0
- package/src/lifecycle/index.ts +13 -0
- package/src/lifecycle/lifecycle.ts +160 -0
- package/src/lifecycle/signal-handlers.ts +62 -0
- package/src/logging/__tests__/pino-trace-bridge.test.ts +50 -0
- package/src/logging/index.ts +3 -0
- package/src/logging/pino-logger.ts +64 -0
- package/src/logging/types.ts +7 -0
- package/src/migrations/__tests__/compare-snapshots.test.ts +150 -0
- package/src/migrations/__tests__/detect-drift.integration.ts +320 -0
- package/src/migrations/__tests__/detect-projections-to-rebuild.integration.ts +134 -0
- package/src/migrations/__tests__/rebuild-marker.test.ts +79 -0
- package/src/migrations/index.ts +28 -0
- package/src/migrations/projection-detection.ts +149 -0
- package/src/migrations/rebuild-marker.ts +64 -0
- package/src/migrations/schema-drift.ts +395 -0
- package/src/observability/__tests__/console-provider.test.ts +67 -0
- package/src/observability/__tests__/metric-validator.test.ts +87 -0
- package/src/observability/__tests__/noop-provider.test.ts +82 -0
- package/src/observability/__tests__/observability.integration.ts +559 -0
- package/src/observability/__tests__/prometheus-meter.test.ts +144 -0
- package/src/observability/__tests__/recording-meter.test.ts +101 -0
- package/src/observability/__tests__/recording-tracer.test.ts +110 -0
- package/src/observability/__tests__/sensitive-filter.test.ts +98 -0
- package/src/observability/console-provider.ts +130 -0
- package/src/observability/context.ts +26 -0
- package/src/observability/fallback.ts +34 -0
- package/src/observability/ids.ts +25 -0
- package/src/observability/index.ts +79 -0
- package/src/observability/metric-validator.ts +86 -0
- package/src/observability/metrics-handle.ts +56 -0
- package/src/observability/noop-provider.ts +146 -0
- package/src/observability/prometheus-meter.ts +284 -0
- package/src/observability/recording-meter.ts +156 -0
- package/src/observability/recording-tracer.ts +198 -0
- package/src/observability/redis-wrapper.ts +132 -0
- package/src/observability/sensitive-filter.ts +108 -0
- package/src/observability/standard-metrics.ts +213 -0
- package/src/observability/types/index.ts +29 -0
- package/src/observability/types/metric.ts +56 -0
- package/src/observability/types/provider.ts +32 -0
- package/src/observability/types/span.ts +64 -0
- package/src/pipeline/__tests__/archive-stream.integration.ts +220 -0
- package/src/pipeline/__tests__/auth-claims-resolver.test.ts +279 -0
- package/src/pipeline/__tests__/cascade-handler.integration.ts +419 -0
- package/src/pipeline/__tests__/cascade-handler.test.ts +52 -0
- package/src/pipeline/__tests__/causation-chain.integration.ts +206 -0
- package/src/pipeline/__tests__/ctx-bridge.integration.ts +234 -0
- package/src/pipeline/__tests__/dispatcher.test.ts +379 -0
- package/src/pipeline/__tests__/distributed-lock.integration.ts +67 -0
- package/src/pipeline/__tests__/domain-events-projections.integration.ts +323 -0
- package/src/pipeline/__tests__/event-dedup.integration.ts +153 -0
- package/src/pipeline/__tests__/event-define-event-strict.integration.ts +202 -0
- package/src/pipeline/__tests__/event-dispatcher-lifecycle.integration.ts +220 -0
- package/src/pipeline/__tests__/event-dispatcher-multi-instance.integration.ts +423 -0
- package/src/pipeline/__tests__/event-dispatcher-pg-listen.integration.ts +123 -0
- package/src/pipeline/__tests__/event-dispatcher-recovery.integration.ts +202 -0
- package/src/pipeline/__tests__/event-dispatcher-second-audit.integration.ts +290 -0
- package/src/pipeline/__tests__/event-dispatcher-strict.test.ts +65 -0
- package/src/pipeline/__tests__/event-dispatcher.integration.ts +287 -0
- package/src/pipeline/__tests__/event-retention.integration.ts +239 -0
- package/src/pipeline/__tests__/fetch-for-writing.integration.ts +281 -0
- package/src/pipeline/__tests__/lifecycle-pipeline.test.ts +430 -0
- package/src/pipeline/__tests__/load-aggregate-query.integration.ts +266 -0
- package/src/pipeline/__tests__/msp-error-mode.integration.ts +149 -0
- package/src/pipeline/__tests__/msp-multi-hop.integration.ts +228 -0
- package/src/pipeline/__tests__/msp-rebuild.integration.ts +368 -0
- package/src/pipeline/__tests__/multi-stream-projection.integration.ts +341 -0
- package/src/pipeline/__tests__/perf-rebuild.integration.ts +147 -0
- package/src/pipeline/__tests__/projection-rebuild.integration.ts +551 -0
- package/src/pipeline/__tests__/query-projection.integration.ts +201 -0
- package/src/pipeline/__tests__/redis-pipeline.integration.ts +306 -0
- package/src/pipeline/append-event-core.ts +117 -0
- package/src/pipeline/auth-claims-resolver.ts +103 -0
- package/src/pipeline/cascade-handler.ts +113 -0
- package/src/pipeline/dispatcher.ts +1585 -0
- package/src/pipeline/distributed-lock.ts +37 -0
- package/src/pipeline/entity-cache.ts +113 -0
- package/src/pipeline/event-consumer-state.ts +108 -0
- package/src/pipeline/event-dedup.ts +23 -0
- package/src/pipeline/event-dispatcher.ts +1016 -0
- package/src/pipeline/event-retention.ts +154 -0
- package/src/pipeline/idempotency.ts +76 -0
- package/src/pipeline/index.ts +66 -0
- package/src/pipeline/lifecycle-pipeline.ts +409 -0
- package/src/pipeline/msp-rebuild.ts +242 -0
- package/src/pipeline/multi-stream-apply-context.ts +115 -0
- package/src/pipeline/projection-rebuild.ts +334 -0
- package/src/pipeline/projection-state.ts +72 -0
- package/src/pipeline/projections-runner.ts +56 -0
- package/src/pipeline/redis-keys.ts +11 -0
- package/src/pipeline/system-hooks.ts +190 -0
- package/src/random/__tests__/generate.test.ts +149 -0
- package/src/random/generate.ts +141 -0
- package/src/random/index.ts +8 -0
- package/src/random/words.ts +392 -0
- package/src/rate-limit/__tests__/dispatcher-l3.integration.ts +111 -0
- package/src/rate-limit/__tests__/middleware.integration.ts +189 -0
- package/src/rate-limit/__tests__/resolver.integration.ts +189 -0
- package/src/rate-limit/bucket.ts +36 -0
- package/src/rate-limit/index.ts +14 -0
- package/src/rate-limit/middleware.ts +152 -0
- package/src/rate-limit/resolver.ts +267 -0
- package/src/redis/__tests__/redis-options.test.ts +54 -0
- package/src/redis/index.ts +74 -0
- package/src/search/__tests__/meilisearch-adapter.integration.ts +236 -0
- package/src/search/__tests__/search-adapter.test.ts +256 -0
- package/src/search/in-memory-adapter.ts +123 -0
- package/src/search/index.ts +12 -0
- package/src/search/meilisearch-adapter.ts +106 -0
- package/src/search/types.ts +39 -0
- package/src/secrets/__tests__/dek-cache.test.ts +213 -0
- package/src/secrets/__tests__/env-master-key-provider.test.ts +119 -0
- package/src/secrets/__tests__/envelope.test.ts +74 -0
- package/src/secrets/__tests__/leak-guard.test.ts +92 -0
- package/src/secrets/__tests__/rotation.test.ts +149 -0
- package/src/secrets/dek-cache.ts +116 -0
- package/src/secrets/env-master-key-provider.ts +162 -0
- package/src/secrets/envelope.ts +55 -0
- package/src/secrets/index.ts +19 -0
- package/src/secrets/leak-guard.ts +87 -0
- package/src/secrets/rotation.ts +34 -0
- package/src/secrets/types.ts +107 -0
- package/src/stack/db.ts +104 -0
- package/src/stack/event-collector.ts +23 -0
- package/src/stack/index.ts +32 -0
- package/src/stack/redis.ts +44 -0
- package/src/stack/request-helper.ts +168 -0
- package/src/stack/table-helpers.ts +104 -0
- package/src/stack/test-stack.ts +357 -0
- package/src/stack/test-users.ts +37 -0
- package/src/testing/__tests__/e2e-generator.test.ts +230 -0
- package/src/testing/__tests__/ensure-entity-table.integration.ts +54 -0
- package/src/testing/access-assertions.ts +15 -0
- package/src/testing/assertions.ts +35 -0
- package/src/testing/e2e-generator.ts +465 -0
- package/src/testing/expect-error.ts +25 -0
- package/src/testing/handler-context.ts +125 -0
- package/src/testing/http-cookies.ts +52 -0
- package/src/testing/index.ts +41 -0
- package/src/testing/late-bound.ts +39 -0
- package/src/testing/mutable-master-key-provider.ts +31 -0
- package/src/testing/observability-recorder.ts +54 -0
- package/src/testing/shared-entities.ts +49 -0
- package/src/testing/utils.ts +1 -0
- package/src/testing/wait-for.ts +31 -0
- package/src/time/__tests__/polyfill.test.ts +73 -0
- package/src/time/__tests__/tz-context.test.ts +121 -0
- package/src/time/index.ts +21 -0
- package/src/time/polyfill.ts +70 -0
- package/src/time/tz-context.ts +107 -0
- package/src/ui-types/app-schema.ts +57 -0
- package/src/ui-types/index.ts +65 -0
- package/src/utils/__tests__/assert.test.ts +17 -0
- package/src/utils/__tests__/env-parse.test.ts +54 -0
- package/src/utils/assert.ts +18 -0
- package/src/utils/env-parse.ts +16 -0
- package/src/utils/ids.ts +16 -0
- package/src/utils/index.ts +5 -0
- package/src/utils/safe-json.ts +30 -0
- package/src/utils/serialization.ts +7 -0
|
@@ -0,0 +1,434 @@
|
|
|
1
|
+
// FeaturePattern — typed representation of an `r.*` call inside a
|
|
2
|
+
// feature file. The AST visitor (parse.ts) walks the
|
|
3
|
+
// `defineFeature(name, (r) => { ... })` setup callback and yields one
|
|
4
|
+
// FeaturePattern per recognised call.
|
|
5
|
+
//
|
|
6
|
+
// **Design principle:**
|
|
7
|
+
//
|
|
8
|
+
// - Whatever the Designer/AI can edit declaratively → typed static
|
|
9
|
+
// fields, reusing the existing engine/types definitions so the
|
|
10
|
+
// pattern shape never drifts from the runtime contract.
|
|
11
|
+
// - Whatever carries closures/code → SourceLocation pointing at the
|
|
12
|
+
// opaque region. The Designer renders that as a read-only code
|
|
13
|
+
// block; the AI patcher overwrites the span verbatim.
|
|
14
|
+
//
|
|
15
|
+
// **Coverage = 100%.** Calls we don't recognise become UnknownPattern
|
|
16
|
+
// (the Designer shows "custom call", AI leaves them alone). Custom
|
|
17
|
+
// TypeScript code BETWEEN `r.*` calls (helpers, local consts, imports)
|
|
18
|
+
// is not extracted — it stays in the file buffer and survives every
|
|
19
|
+
// patch unchanged.
|
|
20
|
+
//
|
|
21
|
+
// **Extension point.** Adding a new r.* API → new pattern type here +
|
|
22
|
+
// new extractor in parse.ts. The discriminated union forces every
|
|
23
|
+
// consumer (Designer, AI patcher, MCP server) to handle the new kind
|
|
24
|
+
// at compile time.
|
|
25
|
+
//
|
|
26
|
+
// **Naming convention.** Pattern `kind` matches the r.* method name
|
|
27
|
+
// 1:1 (e.g. `r.writeHandler` → `kind: "writeHandler"`). No kebab/camel
|
|
28
|
+
// translation layer.
|
|
29
|
+
|
|
30
|
+
import type { LifecycleHookType } from "../constants";
|
|
31
|
+
import type {
|
|
32
|
+
ConfigKeyDefinition,
|
|
33
|
+
ConfigKeyType,
|
|
34
|
+
JobDefinition,
|
|
35
|
+
ReferenceDataDef,
|
|
36
|
+
RunIn,
|
|
37
|
+
TranslationKeys,
|
|
38
|
+
} from "../types/config";
|
|
39
|
+
import type { MetricOptions, SecretOptions } from "../types/feature";
|
|
40
|
+
import type { EntityDefinition } from "../types/fields";
|
|
41
|
+
import type { AccessRule, ClaimKeyType, RateLimitOption } from "../types/handlers";
|
|
42
|
+
import type { HookPhase } from "../types/hooks";
|
|
43
|
+
import type { HttpRouteMethod } from "../types/http-route";
|
|
44
|
+
import type { NavDefinition } from "../types/nav";
|
|
45
|
+
import type { MspErrorMode } from "../types/projection";
|
|
46
|
+
import type { RelationDefinition } from "../types/relations";
|
|
47
|
+
import type { ScreenDefinition } from "../types/screen";
|
|
48
|
+
import type { WorkspaceDefinition } from "../types/workspace";
|
|
49
|
+
import type { SourceLocation } from "./source-location";
|
|
50
|
+
|
|
51
|
+
// =============================================================================
|
|
52
|
+
// Static patterns — fully declarative. Designer renders forms, AI
|
|
53
|
+
// generates them as pure data. Round-trip without code spans.
|
|
54
|
+
// =============================================================================
|
|
55
|
+
|
|
56
|
+
export type EntityPattern = {
|
|
57
|
+
readonly kind: "entity";
|
|
58
|
+
readonly source: SourceLocation;
|
|
59
|
+
readonly entityName: string;
|
|
60
|
+
readonly definition: EntityDefinition;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type RelationPattern = {
|
|
64
|
+
readonly kind: "relation";
|
|
65
|
+
readonly source: SourceLocation;
|
|
66
|
+
readonly entityName: string;
|
|
67
|
+
readonly relationName: string;
|
|
68
|
+
readonly definition: RelationDefinition;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export type NavPattern = {
|
|
72
|
+
readonly kind: "nav";
|
|
73
|
+
readonly source: SourceLocation;
|
|
74
|
+
readonly definition: NavDefinition;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export type WorkspacePattern = {
|
|
78
|
+
readonly kind: "workspace";
|
|
79
|
+
readonly source: SourceLocation;
|
|
80
|
+
readonly definition: WorkspaceDefinition;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export type ConfigPattern = {
|
|
84
|
+
readonly kind: "config";
|
|
85
|
+
readonly source: SourceLocation;
|
|
86
|
+
readonly keys: Readonly<Record<string, ConfigKeyDefinition<ConfigKeyType>>>;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export type TranslationsPattern = {
|
|
90
|
+
readonly kind: "translations";
|
|
91
|
+
readonly source: SourceLocation;
|
|
92
|
+
readonly keys: TranslationKeys;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export type RequiresPattern = {
|
|
96
|
+
readonly kind: "requires";
|
|
97
|
+
readonly source: SourceLocation;
|
|
98
|
+
readonly featureNames: readonly string[];
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export type OptionalRequiresPattern = {
|
|
102
|
+
readonly kind: "optionalRequires";
|
|
103
|
+
readonly source: SourceLocation;
|
|
104
|
+
readonly featureNames: readonly string[];
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export type SystemScopePattern = {
|
|
108
|
+
readonly kind: "systemScope";
|
|
109
|
+
readonly source: SourceLocation;
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
export type ToggleablePattern = {
|
|
113
|
+
readonly kind: "toggleable";
|
|
114
|
+
readonly source: SourceLocation;
|
|
115
|
+
readonly default: boolean;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export type MetricPattern = {
|
|
119
|
+
readonly kind: "metric";
|
|
120
|
+
readonly source: SourceLocation;
|
|
121
|
+
readonly shortName: string;
|
|
122
|
+
readonly options: MetricOptions;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export type SecretPattern = {
|
|
126
|
+
readonly kind: "secret";
|
|
127
|
+
readonly source: SourceLocation;
|
|
128
|
+
readonly shortName: string;
|
|
129
|
+
readonly options: SecretOptions;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export type ClaimKeyPattern = {
|
|
133
|
+
readonly kind: "claimKey";
|
|
134
|
+
readonly source: SourceLocation;
|
|
135
|
+
readonly shortName: string;
|
|
136
|
+
readonly claimType: ClaimKeyType;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export type ReferenceDataPattern = {
|
|
140
|
+
readonly kind: "referenceData";
|
|
141
|
+
readonly source: SourceLocation;
|
|
142
|
+
readonly entityName: string;
|
|
143
|
+
readonly data: ReferenceDataDef["data"];
|
|
144
|
+
readonly upsertKey?: string;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export type ReadsConfigPattern = {
|
|
148
|
+
readonly kind: "readsConfig";
|
|
149
|
+
readonly source: SourceLocation;
|
|
150
|
+
readonly qualifiedKeys: readonly string[];
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
export type UseExtensionPattern = {
|
|
154
|
+
readonly kind: "useExtension";
|
|
155
|
+
readonly source: SourceLocation;
|
|
156
|
+
readonly extensionName: string;
|
|
157
|
+
readonly entityName: string;
|
|
158
|
+
readonly options?: Readonly<Record<string, unknown>>;
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// =============================================================================
|
|
162
|
+
// Mixed patterns — header (name/access/etc.) is declarative, body
|
|
163
|
+
// (handler/hook/apply/transform fn) is opaque. Designer renders the
|
|
164
|
+
// header as a form + the body as a code block. AI patcher generates
|
|
165
|
+
// the header as data + the body as TypeScript source.
|
|
166
|
+
// =============================================================================
|
|
167
|
+
|
|
168
|
+
// Path-keyed map of source locations for opaque sub-properties of an
|
|
169
|
+
// otherwise declarative definition (e.g. screen.rowActions[0].visible
|
|
170
|
+
// is a closure that lives only in monolith bundles). Keys use JSON-path
|
|
171
|
+
// notation so the Designer can show "this prop is custom code" at the
|
|
172
|
+
// exact form-field that maps to the path.
|
|
173
|
+
export type OpaquePropMap = Readonly<Record<string, SourceLocation>>;
|
|
174
|
+
|
|
175
|
+
// Marker emitted in `ScreenPattern.definition` wherever a closure or
|
|
176
|
+
// unresolvable identifier sat in the source. Designer renderers compare
|
|
177
|
+
// against this constant to decide "form vs read-only span" — the actual
|
|
178
|
+
// SourceLocation lives at the matching path in `opaqueProps`.
|
|
179
|
+
export const SCREEN_OPAQUE_MARKER = "$opaque" as const;
|
|
180
|
+
export type ScreenOpaqueMarker = typeof SCREEN_OPAQUE_MARKER;
|
|
181
|
+
|
|
182
|
+
export type ScreenPattern = {
|
|
183
|
+
readonly kind: "screen";
|
|
184
|
+
readonly source: SourceLocation;
|
|
185
|
+
readonly definition: ScreenDefinition;
|
|
186
|
+
// Closure-typed sub-properties (FieldCondition, RowAction.payload,
|
|
187
|
+
// FieldRenderer function form). Keyed by JSON path inside the
|
|
188
|
+
// definition (e.g. "rowActions.0.visible", "fields.email.renderer").
|
|
189
|
+
readonly opaqueProps: OpaquePropMap;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
export type WriteHandlerPattern = {
|
|
193
|
+
readonly kind: "writeHandler";
|
|
194
|
+
readonly source: SourceLocation;
|
|
195
|
+
readonly handlerName: string;
|
|
196
|
+
// schemaSource: the Zod call as source text (e.g. "z.object({...})").
|
|
197
|
+
// We keep it as an opaque block instead of decoding it back to JSON
|
|
198
|
+
// schema — Zod's full surface is too rich for a faithful round-trip.
|
|
199
|
+
readonly schemaSource: SourceLocation;
|
|
200
|
+
// handlerBody: the closure body as source text. Always opaque — AI
|
|
201
|
+
// generates raw TypeScript, no DSL interpretation.
|
|
202
|
+
readonly handlerBody: SourceLocation;
|
|
203
|
+
readonly access?: AccessRule;
|
|
204
|
+
readonly rateLimit?: RateLimitOption;
|
|
205
|
+
readonly skipTransitionGuard?: boolean;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
export type QueryHandlerPattern = {
|
|
209
|
+
readonly kind: "queryHandler";
|
|
210
|
+
readonly source: SourceLocation;
|
|
211
|
+
readonly handlerName: string;
|
|
212
|
+
readonly schemaSource: SourceLocation;
|
|
213
|
+
readonly handlerBody: SourceLocation;
|
|
214
|
+
readonly access?: AccessRule;
|
|
215
|
+
readonly rateLimit?: RateLimitOption;
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
export type HookPattern = {
|
|
219
|
+
readonly kind: "hook";
|
|
220
|
+
readonly source: SourceLocation;
|
|
221
|
+
readonly hookType: LifecycleHookType | "validation";
|
|
222
|
+
// r.hook accepts a single target or a list; we keep both shapes so
|
|
223
|
+
// the Designer can render the original author intent.
|
|
224
|
+
readonly target: string | readonly string[];
|
|
225
|
+
readonly fnBody: SourceLocation;
|
|
226
|
+
readonly phase?: HookPhase;
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
export type EntityHookPattern = {
|
|
230
|
+
readonly kind: "entityHook";
|
|
231
|
+
readonly source: SourceLocation;
|
|
232
|
+
readonly hookType: "postSave" | "preDelete" | "postDelete";
|
|
233
|
+
readonly entityName: string;
|
|
234
|
+
readonly fnBody: SourceLocation;
|
|
235
|
+
readonly phase?: HookPhase;
|
|
236
|
+
};
|
|
237
|
+
|
|
238
|
+
export type JobPattern = {
|
|
239
|
+
readonly kind: "job";
|
|
240
|
+
readonly source: SourceLocation;
|
|
241
|
+
readonly jobName: string;
|
|
242
|
+
// JobDefinition without `name` (already on jobName) and without
|
|
243
|
+
// `handler` (kept separately as handlerBody for opacity).
|
|
244
|
+
readonly options: Omit<JobDefinition, "name" | "handler">;
|
|
245
|
+
readonly handlerBody: SourceLocation;
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
export type NotificationPattern = {
|
|
249
|
+
readonly kind: "notification";
|
|
250
|
+
readonly source: SourceLocation;
|
|
251
|
+
readonly notificationName: string;
|
|
252
|
+
readonly trigger: { readonly on: string };
|
|
253
|
+
readonly recipientBody: SourceLocation;
|
|
254
|
+
readonly dataBody: SourceLocation;
|
|
255
|
+
// Each template (e.g. "email", "push") carries its own closure source.
|
|
256
|
+
readonly templates?: Readonly<Record<string, SourceLocation>>;
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
export type AuthClaimsPattern = {
|
|
260
|
+
readonly kind: "authClaims";
|
|
261
|
+
readonly source: SourceLocation;
|
|
262
|
+
readonly fnBody: SourceLocation;
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
export type HttpRoutePattern = {
|
|
266
|
+
readonly kind: "httpRoute";
|
|
267
|
+
readonly source: SourceLocation;
|
|
268
|
+
readonly method: HttpRouteMethod;
|
|
269
|
+
readonly path: string;
|
|
270
|
+
readonly anonymous?: boolean;
|
|
271
|
+
readonly handlerBody: SourceLocation;
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
export type ProjectionPattern = {
|
|
275
|
+
readonly kind: "projection";
|
|
276
|
+
readonly source: SourceLocation;
|
|
277
|
+
readonly name: string;
|
|
278
|
+
// Entity name(s) whose events feed this projection. Disambiguated
|
|
279
|
+
// from `source: SourceLocation` by the explicit `Entity` suffix.
|
|
280
|
+
readonly sourceEntity: string | readonly string[];
|
|
281
|
+
// Map event-type → SourceLocation of the apply closure.
|
|
282
|
+
readonly applyBodies: Readonly<Record<string, SourceLocation>>;
|
|
283
|
+
};
|
|
284
|
+
|
|
285
|
+
export type MultiStreamProjectionPattern = {
|
|
286
|
+
readonly kind: "multiStreamProjection";
|
|
287
|
+
readonly source: SourceLocation;
|
|
288
|
+
readonly name: string;
|
|
289
|
+
readonly applyBodies: Readonly<Record<string, SourceLocation>>;
|
|
290
|
+
readonly errorMode?: MspErrorMode;
|
|
291
|
+
readonly runIn?: RunIn;
|
|
292
|
+
readonly delivery?: "shared" | "per-instance";
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
export type DefineEventPattern = {
|
|
296
|
+
readonly kind: "defineEvent";
|
|
297
|
+
readonly source: SourceLocation;
|
|
298
|
+
readonly eventName: string;
|
|
299
|
+
readonly schemaSource: SourceLocation;
|
|
300
|
+
readonly version?: number;
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
export type EventMigrationPattern = {
|
|
304
|
+
readonly kind: "eventMigration";
|
|
305
|
+
readonly source: SourceLocation;
|
|
306
|
+
readonly eventName: string;
|
|
307
|
+
readonly fromVersion: number;
|
|
308
|
+
readonly toVersion: number;
|
|
309
|
+
readonly transformBody: SourceLocation;
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
export type ExtendsRegistrarPattern = {
|
|
313
|
+
readonly kind: "extendsRegistrar";
|
|
314
|
+
readonly source: SourceLocation;
|
|
315
|
+
readonly extensionName: string;
|
|
316
|
+
// Meta-programming surface — kept fully opaque in the MVP. The
|
|
317
|
+
// Designer shows "Custom Registrar Extension"; AI leaves it alone.
|
|
318
|
+
readonly defBody: SourceLocation;
|
|
319
|
+
};
|
|
320
|
+
|
|
321
|
+
// =============================================================================
|
|
322
|
+
// Catch-all — r.* calls the visitor doesn't recognise. Designer renders
|
|
323
|
+
// "unknown call (cannot edit)", AI patcher leaves them unchanged. When
|
|
324
|
+
// an UnknownPattern shows up in the wild it's a signal that a new r.*
|
|
325
|
+
// API exists and needs its own pattern type here.
|
|
326
|
+
// =============================================================================
|
|
327
|
+
|
|
328
|
+
export type UnknownPattern = {
|
|
329
|
+
readonly kind: "unknown";
|
|
330
|
+
readonly source: SourceLocation;
|
|
331
|
+
readonly methodName: string;
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
// =============================================================================
|
|
335
|
+
// Discriminated union — visitors return FeaturePattern[]; consumers
|
|
336
|
+
// switch on `kind`.
|
|
337
|
+
// =============================================================================
|
|
338
|
+
|
|
339
|
+
export type FeaturePattern =
|
|
340
|
+
// Static
|
|
341
|
+
| EntityPattern
|
|
342
|
+
| RelationPattern
|
|
343
|
+
| NavPattern
|
|
344
|
+
| WorkspacePattern
|
|
345
|
+
| ConfigPattern
|
|
346
|
+
| TranslationsPattern
|
|
347
|
+
| RequiresPattern
|
|
348
|
+
| OptionalRequiresPattern
|
|
349
|
+
| SystemScopePattern
|
|
350
|
+
| ToggleablePattern
|
|
351
|
+
| MetricPattern
|
|
352
|
+
| SecretPattern
|
|
353
|
+
| ClaimKeyPattern
|
|
354
|
+
| ReferenceDataPattern
|
|
355
|
+
| ReadsConfigPattern
|
|
356
|
+
| UseExtensionPattern
|
|
357
|
+
// Mixed
|
|
358
|
+
| ScreenPattern
|
|
359
|
+
| WriteHandlerPattern
|
|
360
|
+
| QueryHandlerPattern
|
|
361
|
+
| HookPattern
|
|
362
|
+
| EntityHookPattern
|
|
363
|
+
| JobPattern
|
|
364
|
+
| NotificationPattern
|
|
365
|
+
| AuthClaimsPattern
|
|
366
|
+
| HttpRoutePattern
|
|
367
|
+
| ProjectionPattern
|
|
368
|
+
| MultiStreamProjectionPattern
|
|
369
|
+
| DefineEventPattern
|
|
370
|
+
| EventMigrationPattern
|
|
371
|
+
| ExtendsRegistrarPattern
|
|
372
|
+
// Catch-all
|
|
373
|
+
| UnknownPattern;
|
|
374
|
+
|
|
375
|
+
// Convenience: the literal union of all kinds, useful for Designer
|
|
376
|
+
// switches that exhaustively cover every pattern.
|
|
377
|
+
export type FeaturePatternKind = FeaturePattern["kind"];
|
|
378
|
+
|
|
379
|
+
// =============================================================================
|
|
380
|
+
// Editability classification — Designer UI uses this to decide whether
|
|
381
|
+
// to render a pattern as a form (editable) or a read-only code block
|
|
382
|
+
// (opaque). The AI patcher uses the same signal to decide JSON-patch
|
|
383
|
+
// vs TS-source-replace.
|
|
384
|
+
// =============================================================================
|
|
385
|
+
|
|
386
|
+
export type Editability =
|
|
387
|
+
| "static" // Fully declarative — forms only, no code slot.
|
|
388
|
+
| "mixed" // Header declarative + body as TS source block.
|
|
389
|
+
| "opaque"; // Whole pattern is TS code, no form surface.
|
|
390
|
+
|
|
391
|
+
export function getEditability(pattern: FeaturePattern): Editability {
|
|
392
|
+
switch (pattern.kind) {
|
|
393
|
+
case "entity":
|
|
394
|
+
case "relation":
|
|
395
|
+
case "nav":
|
|
396
|
+
case "workspace":
|
|
397
|
+
case "config":
|
|
398
|
+
case "translations":
|
|
399
|
+
case "requires":
|
|
400
|
+
case "optionalRequires":
|
|
401
|
+
case "systemScope":
|
|
402
|
+
case "toggleable":
|
|
403
|
+
case "metric":
|
|
404
|
+
case "secret":
|
|
405
|
+
case "claimKey":
|
|
406
|
+
case "referenceData":
|
|
407
|
+
case "readsConfig":
|
|
408
|
+
case "useExtension":
|
|
409
|
+
return "static";
|
|
410
|
+
case "screen":
|
|
411
|
+
case "writeHandler":
|
|
412
|
+
case "queryHandler":
|
|
413
|
+
case "hook":
|
|
414
|
+
case "entityHook":
|
|
415
|
+
case "job":
|
|
416
|
+
case "notification":
|
|
417
|
+
case "httpRoute":
|
|
418
|
+
case "projection":
|
|
419
|
+
case "multiStreamProjection":
|
|
420
|
+
case "defineEvent":
|
|
421
|
+
case "eventMigration":
|
|
422
|
+
return "mixed";
|
|
423
|
+
case "authClaims":
|
|
424
|
+
case "extendsRegistrar":
|
|
425
|
+
case "unknown":
|
|
426
|
+
return "opaque";
|
|
427
|
+
default: {
|
|
428
|
+
// Exhaustiveness guard — adding a new pattern kind without
|
|
429
|
+
// updating this switch produces a compile error here.
|
|
430
|
+
const _exhaustive: never = pattern;
|
|
431
|
+
return _exhaustive;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|