@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,518 @@
|
|
|
1
|
+
// FeaturePatcher — imperative typed wrapper around the generic apply API.
|
|
2
|
+
// Each `add{Kind}` method takes the natural arguments for that pattern
|
|
3
|
+
// (no SourceLocation gymnastics, no FeaturePattern hand-crafting) and
|
|
4
|
+
// dispatches through the renderer + addPattern under the hood.
|
|
5
|
+
//
|
|
6
|
+
// **Why this layer exists:**
|
|
7
|
+
// - **AI tool-use**: an LLM-with-tools picks methods by name. `addEntity`
|
|
8
|
+
// with typed args is a 1-shot tool-call; building a FeaturePattern
|
|
9
|
+
// literal in JSON would require teaching the model our internal
|
|
10
|
+
// discriminated-union shape (kind + source + entityName + definition).
|
|
11
|
+
// - **Designer forms**: form-submit handlers map directly to a single
|
|
12
|
+
// `patcher.addX(formData)` call — no intermediary translation step.
|
|
13
|
+
// - **Type narrowing**: each method's TypeScript signature locks the
|
|
14
|
+
// fields the caller must provide; missing required props fail at
|
|
15
|
+
// compile time, not at the parse step downstream.
|
|
16
|
+
//
|
|
17
|
+
// **What stays in the generic API:**
|
|
18
|
+
// - `replace(id, pattern)` / `remove(id)` — symmetric across kinds; the
|
|
19
|
+
// PatternId discriminator already names what to match.
|
|
20
|
+
// - `apply(changes)` — bulk operations, friendlier when the AI emits a
|
|
21
|
+
// change-list as a single JSON array.
|
|
22
|
+
|
|
23
|
+
import type { SourceFile } from "ts-morph";
|
|
24
|
+
import type { LifecycleHookType } from "../constants";
|
|
25
|
+
import type {
|
|
26
|
+
ConfigKeyDefinition,
|
|
27
|
+
ConfigKeyType,
|
|
28
|
+
JobDefinition,
|
|
29
|
+
RunIn,
|
|
30
|
+
TranslationKeys,
|
|
31
|
+
} from "../types/config";
|
|
32
|
+
import type { MetricOptions, SecretOptions } from "../types/feature";
|
|
33
|
+
import type { EntityDefinition } from "../types/fields";
|
|
34
|
+
import type { AccessRule, ClaimKeyType, RateLimitOption } from "../types/handlers";
|
|
35
|
+
import type { HookPhase } from "../types/hooks";
|
|
36
|
+
import type { HttpRouteMethod } from "../types/http-route";
|
|
37
|
+
import type { NavDefinition } from "../types/nav";
|
|
38
|
+
import type { MspErrorMode } from "../types/projection";
|
|
39
|
+
import type { RelationDefinition } from "../types/relations";
|
|
40
|
+
import type { ScreenDefinition } from "../types/screen";
|
|
41
|
+
import type { WorkspaceDefinition } from "../types/workspace";
|
|
42
|
+
import {
|
|
43
|
+
addPattern,
|
|
44
|
+
applyChanges,
|
|
45
|
+
type PatternChange,
|
|
46
|
+
type PatternId,
|
|
47
|
+
removePattern,
|
|
48
|
+
replacePattern,
|
|
49
|
+
} from "./patch";
|
|
50
|
+
import type { FeaturePattern, OpaquePropMap } from "./patterns";
|
|
51
|
+
import type { SourceLocation } from "./source-location";
|
|
52
|
+
|
|
53
|
+
// =============================================================================
|
|
54
|
+
// Synthetic SourceLocation — for new patterns that don't have a real file
|
|
55
|
+
// span yet. The renderer only reads `.raw` from body locations (handler/
|
|
56
|
+
// schema/etc.), so for static patterns the synthetic value is a placeholder
|
|
57
|
+
// that never reaches the output.
|
|
58
|
+
// =============================================================================
|
|
59
|
+
|
|
60
|
+
const SYNTHETIC_LOC: SourceLocation = {
|
|
61
|
+
file: "<patcher>",
|
|
62
|
+
start: { line: 1, column: 1 },
|
|
63
|
+
end: { line: 1, column: 1 },
|
|
64
|
+
raw: "",
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
function rawLoc(raw: string): SourceLocation {
|
|
68
|
+
return { ...SYNTHETIC_LOC, raw };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// =============================================================================
|
|
72
|
+
// Argument shapes — typed inputs per pattern kind. These mirror the
|
|
73
|
+
// runtime-API argument signatures so the patcher feels like a slightly
|
|
74
|
+
// flatter version of the registrar itself.
|
|
75
|
+
// =============================================================================
|
|
76
|
+
|
|
77
|
+
export type AddEntityArgs = {
|
|
78
|
+
readonly name: string;
|
|
79
|
+
readonly definition: EntityDefinition;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export type AddRelationArgs = {
|
|
83
|
+
readonly entity: string;
|
|
84
|
+
readonly name: string;
|
|
85
|
+
readonly definition: RelationDefinition;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export type AddWriteHandlerArgs = {
|
|
89
|
+
readonly name: string;
|
|
90
|
+
/** Source text of the Zod schema, e.g. `"z.object({ title: z.string() })"`. */
|
|
91
|
+
readonly schemaSource: string;
|
|
92
|
+
/** Source text of the handler closure, e.g. `"async (event, ctx) => { ... }"`. */
|
|
93
|
+
readonly handlerSource: string;
|
|
94
|
+
readonly access?: AccessRule;
|
|
95
|
+
readonly rateLimit?: RateLimitOption;
|
|
96
|
+
readonly skipTransitionGuard?: boolean;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
export type AddQueryHandlerArgs = {
|
|
100
|
+
readonly name: string;
|
|
101
|
+
readonly schemaSource: string;
|
|
102
|
+
readonly handlerSource: string;
|
|
103
|
+
readonly access?: AccessRule;
|
|
104
|
+
readonly rateLimit?: RateLimitOption;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export type AddHookArgs = {
|
|
108
|
+
readonly type: LifecycleHookType | "validation";
|
|
109
|
+
readonly target: string | readonly string[];
|
|
110
|
+
/** Source text of the closure, e.g. `"async (event, ctx) => { ... }"`. */
|
|
111
|
+
readonly handlerSource: string;
|
|
112
|
+
readonly phase?: HookPhase;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export type AddEntityHookArgs = {
|
|
116
|
+
readonly type: "postSave" | "preDelete" | "postDelete";
|
|
117
|
+
readonly entity: string;
|
|
118
|
+
readonly handlerSource: string;
|
|
119
|
+
readonly phase?: HookPhase;
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export type AddJobArgs = {
|
|
123
|
+
readonly name: string;
|
|
124
|
+
readonly options: Omit<JobDefinition, "name" | "handler">;
|
|
125
|
+
readonly handlerSource: string;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
export type AddNotificationArgs = {
|
|
129
|
+
readonly name: string;
|
|
130
|
+
readonly trigger: { readonly on: string };
|
|
131
|
+
readonly recipientSource: string;
|
|
132
|
+
readonly dataSource: string;
|
|
133
|
+
readonly templates?: Readonly<Record<string, string>>;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export type AddHttpRouteArgs = {
|
|
137
|
+
readonly method: HttpRouteMethod;
|
|
138
|
+
readonly path: string;
|
|
139
|
+
readonly handlerSource: string;
|
|
140
|
+
readonly anonymous?: boolean;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
export type AddDefineEventArgs = {
|
|
144
|
+
readonly name: string;
|
|
145
|
+
readonly schemaSource: string;
|
|
146
|
+
readonly version?: number;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
export type AddEventMigrationArgs = {
|
|
150
|
+
readonly event: string;
|
|
151
|
+
readonly fromVersion: number;
|
|
152
|
+
readonly toVersion: number;
|
|
153
|
+
readonly transformSource: string;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
export type AddProjectionArgs = {
|
|
157
|
+
readonly name: string;
|
|
158
|
+
readonly sourceEntity: string | readonly string[];
|
|
159
|
+
/** Map of event-type → closure source for the apply handler. */
|
|
160
|
+
readonly applySources: Readonly<Record<string, string>>;
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
export type AddMultiStreamProjectionArgs = {
|
|
164
|
+
readonly name: string;
|
|
165
|
+
readonly applySources: Readonly<Record<string, string>>;
|
|
166
|
+
readonly errorMode?: MspErrorMode;
|
|
167
|
+
readonly runIn?: RunIn;
|
|
168
|
+
readonly delivery?: "shared" | "per-instance";
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
export type AddReferenceDataArgs = {
|
|
172
|
+
readonly entity: string;
|
|
173
|
+
readonly data: readonly Record<string, unknown>[];
|
|
174
|
+
readonly upsertKey?: string;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
export type AddMetricArgs = { readonly name: string; readonly options: MetricOptions };
|
|
178
|
+
export type AddSecretArgs = { readonly name: string; readonly options: SecretOptions };
|
|
179
|
+
export type AddClaimKeyArgs = { readonly name: string; readonly type: ClaimKeyType };
|
|
180
|
+
export type AddUseExtensionArgs = {
|
|
181
|
+
readonly extension: string;
|
|
182
|
+
readonly entity: string;
|
|
183
|
+
readonly options?: Readonly<Record<string, unknown>>;
|
|
184
|
+
};
|
|
185
|
+
export type AddScreenArgs = {
|
|
186
|
+
readonly definition: ScreenDefinition;
|
|
187
|
+
/** Source spans for each closure-typed sub-property; keyed by JSON-path
|
|
188
|
+
* inside the definition (e.g. `"rowActions.0.visible"`). Each entry's
|
|
189
|
+
* raw is the closure source the renderer will splice in. */
|
|
190
|
+
readonly opaqueSources?: Readonly<Record<string, string>>;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// Object-Form args for the previously-positional methods. Every typed
|
|
194
|
+
// `add{Kind}` now takes a single object argument so the AI sees one
|
|
195
|
+
// uniform method-call shape.
|
|
196
|
+
export type AddRequiresArgs = { readonly features: readonly string[] };
|
|
197
|
+
export type AddOptionalRequiresArgs = { readonly features: readonly string[] };
|
|
198
|
+
export type AddReadsConfigArgs = { readonly keys: readonly string[] };
|
|
199
|
+
export type AddToggleableArgs = { readonly default: boolean };
|
|
200
|
+
export type AddNavArgs = { readonly definition: NavDefinition };
|
|
201
|
+
export type AddWorkspaceArgs = { readonly definition: WorkspaceDefinition };
|
|
202
|
+
export type AddConfigArgs = {
|
|
203
|
+
readonly keys: Readonly<Record<string, ConfigKeyDefinition<ConfigKeyType>>>;
|
|
204
|
+
};
|
|
205
|
+
export type AddTranslationsArgs = { readonly keys: TranslationKeys };
|
|
206
|
+
export type AddAuthClaimsArgs = {
|
|
207
|
+
/** Source text of the claims handler closure. */
|
|
208
|
+
readonly handlerSource: string;
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
// =============================================================================
|
|
212
|
+
// FeaturePatcher — the public surface
|
|
213
|
+
// =============================================================================
|
|
214
|
+
|
|
215
|
+
// Every typed `add{Kind}` takes a single object argument — uniform shape
|
|
216
|
+
// across the API so AI tool-use learns ONE method-call form. The few
|
|
217
|
+
// methods that conceptually take "no args" (addSystemScope) still take
|
|
218
|
+
// none, but everything that carries data is object-form.
|
|
219
|
+
export type FeaturePatcher = {
|
|
220
|
+
// --- Static patterns (no closures) ---
|
|
221
|
+
readonly addRequires: (args: AddRequiresArgs) => void;
|
|
222
|
+
readonly addOptionalRequires: (args: AddOptionalRequiresArgs) => void;
|
|
223
|
+
readonly addReadsConfig: (args: AddReadsConfigArgs) => void;
|
|
224
|
+
readonly addSystemScope: () => void;
|
|
225
|
+
readonly addToggleable: (args: AddToggleableArgs) => void;
|
|
226
|
+
readonly addEntity: (args: AddEntityArgs) => void;
|
|
227
|
+
readonly addRelation: (args: AddRelationArgs) => void;
|
|
228
|
+
readonly addNav: (args: AddNavArgs) => void;
|
|
229
|
+
readonly addWorkspace: (args: AddWorkspaceArgs) => void;
|
|
230
|
+
readonly addConfig: (args: AddConfigArgs) => void;
|
|
231
|
+
readonly addTranslations: (args: AddTranslationsArgs) => void;
|
|
232
|
+
readonly addMetric: (args: AddMetricArgs) => void;
|
|
233
|
+
readonly addSecret: (args: AddSecretArgs) => void;
|
|
234
|
+
readonly addClaimKey: (args: AddClaimKeyArgs) => void;
|
|
235
|
+
readonly addReferenceData: (args: AddReferenceDataArgs) => void;
|
|
236
|
+
readonly addUseExtension: (args: AddUseExtensionArgs) => void;
|
|
237
|
+
// --- Mixed patterns (with opaque source bodies) ---
|
|
238
|
+
readonly addScreen: (args: AddScreenArgs) => void;
|
|
239
|
+
readonly addWriteHandler: (args: AddWriteHandlerArgs) => void;
|
|
240
|
+
readonly addQueryHandler: (args: AddQueryHandlerArgs) => void;
|
|
241
|
+
readonly addHook: (args: AddHookArgs) => void;
|
|
242
|
+
readonly addEntityHook: (args: AddEntityHookArgs) => void;
|
|
243
|
+
readonly addJob: (args: AddJobArgs) => void;
|
|
244
|
+
readonly addNotification: (args: AddNotificationArgs) => void;
|
|
245
|
+
readonly addAuthClaims: (args: AddAuthClaimsArgs) => void;
|
|
246
|
+
readonly addHttpRoute: (args: AddHttpRouteArgs) => void;
|
|
247
|
+
readonly addProjection: (args: AddProjectionArgs) => void;
|
|
248
|
+
readonly addMultiStreamProjection: (args: AddMultiStreamProjectionArgs) => void;
|
|
249
|
+
readonly addDefineEvent: (args: AddDefineEventArgs) => void;
|
|
250
|
+
readonly addEventMigration: (args: AddEventMigrationArgs) => void;
|
|
251
|
+
// --- Symmetric ops (id-driven) ---
|
|
252
|
+
readonly replace: (id: PatternId, pattern: FeaturePattern) => void;
|
|
253
|
+
readonly remove: (id: PatternId) => void;
|
|
254
|
+
readonly apply: (changes: readonly PatternChange[]) => void;
|
|
255
|
+
/**
|
|
256
|
+
* Escape hatch — directly add a hand-built pattern. The typed `add{Kind}`
|
|
257
|
+
* methods above cover every pattern in the catalogue and should be the
|
|
258
|
+
* default path; this method exists for migration tools, AST-replay
|
|
259
|
+
* scenarios, and the rare case where a future pattern-kind isn't yet
|
|
260
|
+
* exposed via a typed method.
|
|
261
|
+
*/
|
|
262
|
+
readonly addPattern: (pattern: FeaturePattern) => void;
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Build a patcher bound to the given source file. All methods mutate the
|
|
267
|
+
* file in place; saving is the caller's responsibility (e.g. via
|
|
268
|
+
* `sourceFile.saveSync()`).
|
|
269
|
+
*/
|
|
270
|
+
export function createFeaturePatcher(sourceFile: SourceFile): FeaturePatcher {
|
|
271
|
+
function add(pattern: FeaturePattern): void {
|
|
272
|
+
addPattern(sourceFile, pattern);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
addRequires({ features }) {
|
|
277
|
+
add({
|
|
278
|
+
kind: "requires",
|
|
279
|
+
source: SYNTHETIC_LOC,
|
|
280
|
+
featureNames: features,
|
|
281
|
+
});
|
|
282
|
+
},
|
|
283
|
+
addOptionalRequires({ features }) {
|
|
284
|
+
add({
|
|
285
|
+
kind: "optionalRequires",
|
|
286
|
+
source: SYNTHETIC_LOC,
|
|
287
|
+
featureNames: features,
|
|
288
|
+
});
|
|
289
|
+
},
|
|
290
|
+
addReadsConfig({ keys }) {
|
|
291
|
+
add({
|
|
292
|
+
kind: "readsConfig",
|
|
293
|
+
source: SYNTHETIC_LOC,
|
|
294
|
+
qualifiedKeys: keys,
|
|
295
|
+
});
|
|
296
|
+
},
|
|
297
|
+
addSystemScope() {
|
|
298
|
+
add({ kind: "systemScope", source: SYNTHETIC_LOC });
|
|
299
|
+
},
|
|
300
|
+
addToggleable({ default: defaultOn }) {
|
|
301
|
+
add({ kind: "toggleable", source: SYNTHETIC_LOC, default: defaultOn });
|
|
302
|
+
},
|
|
303
|
+
addEntity({ name, definition }) {
|
|
304
|
+
add({
|
|
305
|
+
kind: "entity",
|
|
306
|
+
source: SYNTHETIC_LOC,
|
|
307
|
+
entityName: name,
|
|
308
|
+
definition,
|
|
309
|
+
});
|
|
310
|
+
},
|
|
311
|
+
addRelation({ entity, name, definition }) {
|
|
312
|
+
add({
|
|
313
|
+
kind: "relation",
|
|
314
|
+
source: SYNTHETIC_LOC,
|
|
315
|
+
entityName: entity,
|
|
316
|
+
relationName: name,
|
|
317
|
+
definition,
|
|
318
|
+
});
|
|
319
|
+
},
|
|
320
|
+
addNav({ definition }) {
|
|
321
|
+
add({ kind: "nav", source: SYNTHETIC_LOC, definition });
|
|
322
|
+
},
|
|
323
|
+
addWorkspace({ definition }) {
|
|
324
|
+
add({ kind: "workspace", source: SYNTHETIC_LOC, definition });
|
|
325
|
+
},
|
|
326
|
+
addConfig({ keys }) {
|
|
327
|
+
add({ kind: "config", source: SYNTHETIC_LOC, keys });
|
|
328
|
+
},
|
|
329
|
+
addTranslations({ keys }) {
|
|
330
|
+
add({ kind: "translations", source: SYNTHETIC_LOC, keys });
|
|
331
|
+
},
|
|
332
|
+
addMetric({ name, options }) {
|
|
333
|
+
add({ kind: "metric", source: SYNTHETIC_LOC, shortName: name, options });
|
|
334
|
+
},
|
|
335
|
+
addSecret({ name, options }) {
|
|
336
|
+
add({ kind: "secret", source: SYNTHETIC_LOC, shortName: name, options });
|
|
337
|
+
},
|
|
338
|
+
addClaimKey({ name, type }) {
|
|
339
|
+
add({ kind: "claimKey", source: SYNTHETIC_LOC, shortName: name, claimType: type });
|
|
340
|
+
},
|
|
341
|
+
addReferenceData({ entity, data, upsertKey }) {
|
|
342
|
+
add({
|
|
343
|
+
kind: "referenceData",
|
|
344
|
+
source: SYNTHETIC_LOC,
|
|
345
|
+
entityName: entity,
|
|
346
|
+
data,
|
|
347
|
+
...(upsertKey !== undefined && { upsertKey }),
|
|
348
|
+
});
|
|
349
|
+
},
|
|
350
|
+
addUseExtension({ extension, entity, options }) {
|
|
351
|
+
add({
|
|
352
|
+
kind: "useExtension",
|
|
353
|
+
source: SYNTHETIC_LOC,
|
|
354
|
+
extensionName: extension,
|
|
355
|
+
entityName: entity,
|
|
356
|
+
...(options !== undefined && { options }),
|
|
357
|
+
});
|
|
358
|
+
},
|
|
359
|
+
|
|
360
|
+
addScreen({ definition, opaqueSources }) {
|
|
361
|
+
const opaqueProps: OpaquePropMap = opaqueSources
|
|
362
|
+
? Object.fromEntries(Object.entries(opaqueSources).map(([k, v]) => [k, rawLoc(v)]))
|
|
363
|
+
: {};
|
|
364
|
+
add({ kind: "screen", source: SYNTHETIC_LOC, definition, opaqueProps });
|
|
365
|
+
},
|
|
366
|
+
|
|
367
|
+
addWriteHandler({ name, schemaSource, handlerSource, access, rateLimit, skipTransitionGuard }) {
|
|
368
|
+
add({
|
|
369
|
+
kind: "writeHandler",
|
|
370
|
+
source: SYNTHETIC_LOC,
|
|
371
|
+
handlerName: name,
|
|
372
|
+
schemaSource: rawLoc(schemaSource),
|
|
373
|
+
handlerBody: rawLoc(handlerSource),
|
|
374
|
+
...(access !== undefined && { access }),
|
|
375
|
+
...(rateLimit !== undefined && { rateLimit }),
|
|
376
|
+
...(skipTransitionGuard === true && { skipTransitionGuard: true }),
|
|
377
|
+
});
|
|
378
|
+
},
|
|
379
|
+
|
|
380
|
+
addQueryHandler({ name, schemaSource, handlerSource, access, rateLimit }) {
|
|
381
|
+
add({
|
|
382
|
+
kind: "queryHandler",
|
|
383
|
+
source: SYNTHETIC_LOC,
|
|
384
|
+
handlerName: name,
|
|
385
|
+
schemaSource: rawLoc(schemaSource),
|
|
386
|
+
handlerBody: rawLoc(handlerSource),
|
|
387
|
+
...(access !== undefined && { access }),
|
|
388
|
+
...(rateLimit !== undefined && { rateLimit }),
|
|
389
|
+
});
|
|
390
|
+
},
|
|
391
|
+
|
|
392
|
+
addHook({ type, target, handlerSource, phase }) {
|
|
393
|
+
add({
|
|
394
|
+
kind: "hook",
|
|
395
|
+
source: SYNTHETIC_LOC,
|
|
396
|
+
hookType: type,
|
|
397
|
+
target,
|
|
398
|
+
fnBody: rawLoc(handlerSource),
|
|
399
|
+
...(phase !== undefined && { phase }),
|
|
400
|
+
});
|
|
401
|
+
},
|
|
402
|
+
|
|
403
|
+
addEntityHook({ type, entity, handlerSource, phase }) {
|
|
404
|
+
add({
|
|
405
|
+
kind: "entityHook",
|
|
406
|
+
source: SYNTHETIC_LOC,
|
|
407
|
+
hookType: type,
|
|
408
|
+
entityName: entity,
|
|
409
|
+
fnBody: rawLoc(handlerSource),
|
|
410
|
+
...(phase !== undefined && { phase }),
|
|
411
|
+
});
|
|
412
|
+
},
|
|
413
|
+
|
|
414
|
+
addJob({ name, options, handlerSource }) {
|
|
415
|
+
add({
|
|
416
|
+
kind: "job",
|
|
417
|
+
source: SYNTHETIC_LOC,
|
|
418
|
+
jobName: name,
|
|
419
|
+
options,
|
|
420
|
+
handlerBody: rawLoc(handlerSource),
|
|
421
|
+
});
|
|
422
|
+
},
|
|
423
|
+
|
|
424
|
+
addNotification({ name, trigger, recipientSource, dataSource, templates }) {
|
|
425
|
+
const templateLocs = templates
|
|
426
|
+
? Object.fromEntries(Object.entries(templates).map(([k, v]) => [k, rawLoc(v)]))
|
|
427
|
+
: undefined;
|
|
428
|
+
add({
|
|
429
|
+
kind: "notification",
|
|
430
|
+
source: SYNTHETIC_LOC,
|
|
431
|
+
notificationName: name,
|
|
432
|
+
trigger,
|
|
433
|
+
recipientBody: rawLoc(recipientSource),
|
|
434
|
+
dataBody: rawLoc(dataSource),
|
|
435
|
+
...(templateLocs !== undefined && { templates: templateLocs }),
|
|
436
|
+
});
|
|
437
|
+
},
|
|
438
|
+
|
|
439
|
+
addAuthClaims({ handlerSource }) {
|
|
440
|
+
add({
|
|
441
|
+
kind: "authClaims",
|
|
442
|
+
source: SYNTHETIC_LOC,
|
|
443
|
+
fnBody: rawLoc(handlerSource),
|
|
444
|
+
});
|
|
445
|
+
},
|
|
446
|
+
|
|
447
|
+
addHttpRoute({ method, path, handlerSource, anonymous }) {
|
|
448
|
+
add({
|
|
449
|
+
kind: "httpRoute",
|
|
450
|
+
source: SYNTHETIC_LOC,
|
|
451
|
+
method,
|
|
452
|
+
path,
|
|
453
|
+
handlerBody: rawLoc(handlerSource),
|
|
454
|
+
...(anonymous === true && { anonymous: true }),
|
|
455
|
+
});
|
|
456
|
+
},
|
|
457
|
+
|
|
458
|
+
addProjection({ name, sourceEntity, applySources }) {
|
|
459
|
+
const applyBodies = Object.fromEntries(
|
|
460
|
+
Object.entries(applySources).map(([k, v]) => [k, rawLoc(v)]),
|
|
461
|
+
);
|
|
462
|
+
add({
|
|
463
|
+
kind: "projection",
|
|
464
|
+
source: SYNTHETIC_LOC,
|
|
465
|
+
name,
|
|
466
|
+
sourceEntity,
|
|
467
|
+
applyBodies,
|
|
468
|
+
});
|
|
469
|
+
},
|
|
470
|
+
|
|
471
|
+
addMultiStreamProjection({ name, applySources, errorMode, runIn, delivery }) {
|
|
472
|
+
const applyBodies = Object.fromEntries(
|
|
473
|
+
Object.entries(applySources).map(([k, v]) => [k, rawLoc(v)]),
|
|
474
|
+
);
|
|
475
|
+
add({
|
|
476
|
+
kind: "multiStreamProjection",
|
|
477
|
+
source: SYNTHETIC_LOC,
|
|
478
|
+
name,
|
|
479
|
+
applyBodies,
|
|
480
|
+
...(errorMode !== undefined && { errorMode }),
|
|
481
|
+
...(runIn !== undefined && { runIn }),
|
|
482
|
+
...(delivery !== undefined && { delivery }),
|
|
483
|
+
});
|
|
484
|
+
},
|
|
485
|
+
|
|
486
|
+
addDefineEvent({ name, schemaSource, version }) {
|
|
487
|
+
add({
|
|
488
|
+
kind: "defineEvent",
|
|
489
|
+
source: SYNTHETIC_LOC,
|
|
490
|
+
eventName: name,
|
|
491
|
+
schemaSource: rawLoc(schemaSource),
|
|
492
|
+
...(version !== undefined && { version }),
|
|
493
|
+
});
|
|
494
|
+
},
|
|
495
|
+
|
|
496
|
+
addEventMigration({ event, fromVersion, toVersion, transformSource }) {
|
|
497
|
+
add({
|
|
498
|
+
kind: "eventMigration",
|
|
499
|
+
source: SYNTHETIC_LOC,
|
|
500
|
+
eventName: event,
|
|
501
|
+
fromVersion,
|
|
502
|
+
toVersion,
|
|
503
|
+
transformBody: rawLoc(transformSource),
|
|
504
|
+
});
|
|
505
|
+
},
|
|
506
|
+
|
|
507
|
+
replace(id, pattern) {
|
|
508
|
+
replacePattern(sourceFile, id, pattern);
|
|
509
|
+
},
|
|
510
|
+
remove(id) {
|
|
511
|
+
removePattern(sourceFile, id);
|
|
512
|
+
},
|
|
513
|
+
apply(changes) {
|
|
514
|
+
applyChanges(sourceFile, changes);
|
|
515
|
+
},
|
|
516
|
+
addPattern: add,
|
|
517
|
+
};
|
|
518
|
+
}
|