@angriff36/manifest 2.18.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/LICENSE +21 -0
- package/README.md +476 -0
- package/dist/manifest/agent-sdk/agent-runtime.d.ts +30 -0
- package/dist/manifest/agent-sdk/agent-runtime.d.ts.map +1 -0
- package/dist/manifest/agent-sdk/agent-runtime.js +232 -0
- package/dist/manifest/agent-sdk/agent-runtime.js.map +1 -0
- package/dist/manifest/agent-sdk/index.d.ts +17 -0
- package/dist/manifest/agent-sdk/index.d.ts.map +1 -0
- package/dist/manifest/agent-sdk/index.js +21 -0
- package/dist/manifest/agent-sdk/index.js.map +1 -0
- package/dist/manifest/agent-sdk/intent-mapper.d.ts +17 -0
- package/dist/manifest/agent-sdk/intent-mapper.d.ts.map +1 -0
- package/dist/manifest/agent-sdk/intent-mapper.js +115 -0
- package/dist/manifest/agent-sdk/intent-mapper.js.map +1 -0
- package/dist/manifest/agent-sdk/introspect.d.ts +42 -0
- package/dist/manifest/agent-sdk/introspect.d.ts.map +1 -0
- package/dist/manifest/agent-sdk/introspect.js +284 -0
- package/dist/manifest/agent-sdk/introspect.js.map +1 -0
- package/dist/manifest/agent-sdk/json-schema.d.ts +29 -0
- package/dist/manifest/agent-sdk/json-schema.d.ts.map +1 -0
- package/dist/manifest/agent-sdk/json-schema.js +132 -0
- package/dist/manifest/agent-sdk/json-schema.js.map +1 -0
- package/dist/manifest/agent-sdk/tool-definitions.d.ts +41 -0
- package/dist/manifest/agent-sdk/tool-definitions.d.ts.map +1 -0
- package/dist/manifest/agent-sdk/tool-definitions.js +288 -0
- package/dist/manifest/agent-sdk/tool-definitions.js.map +1 -0
- package/dist/manifest/agent-sdk/types.d.ts +293 -0
- package/dist/manifest/agent-sdk/types.d.ts.map +1 -0
- package/dist/manifest/agent-sdk/types.js +6 -0
- package/dist/manifest/agent-sdk/types.js.map +1 -0
- package/dist/manifest/api-diagnostics.d.ts +41 -0
- package/dist/manifest/api-diagnostics.d.ts.map +1 -0
- package/dist/manifest/api-diagnostics.js +105 -0
- package/dist/manifest/api-diagnostics.js.map +1 -0
- package/dist/manifest/approval/approval-store.d.ts +52 -0
- package/dist/manifest/approval/approval-store.d.ts.map +1 -0
- package/dist/manifest/approval/approval-store.js +25 -0
- package/dist/manifest/approval/approval-store.js.map +1 -0
- package/dist/manifest/approval/stores/memory.d.ts +33 -0
- package/dist/manifest/approval/stores/memory.d.ts.map +1 -0
- package/dist/manifest/approval/stores/memory.js +56 -0
- package/dist/manifest/approval/stores/memory.js.map +1 -0
- package/dist/manifest/approval/stores/postgres.d.ts +41 -0
- package/dist/manifest/approval/stores/postgres.d.ts.map +1 -0
- package/dist/manifest/approval/stores/postgres.js +124 -0
- package/dist/manifest/approval/stores/postgres.js.map +1 -0
- package/dist/manifest/audit/audit-sink.d.ts +53 -0
- package/dist/manifest/audit/audit-sink.d.ts.map +1 -0
- package/dist/manifest/audit/audit-sink.js +15 -0
- package/dist/manifest/audit/audit-sink.js.map +1 -0
- package/dist/manifest/audit/sinks/memory.d.ts +50 -0
- package/dist/manifest/audit/sinks/memory.d.ts.map +1 -0
- package/dist/manifest/audit/sinks/memory.js +66 -0
- package/dist/manifest/audit/sinks/memory.js.map +1 -0
- package/dist/manifest/audit/sinks/postgres.d.ts +31 -0
- package/dist/manifest/audit/sinks/postgres.d.ts.map +1 -0
- package/dist/manifest/audit/sinks/postgres.js +67 -0
- package/dist/manifest/audit/sinks/postgres.js.map +1 -0
- package/dist/manifest/binary-ir.d.ts +76 -0
- package/dist/manifest/binary-ir.d.ts.map +1 -0
- package/dist/manifest/binary-ir.js +124 -0
- package/dist/manifest/binary-ir.js.map +1 -0
- package/dist/manifest/breaking-change.d.ts +75 -0
- package/dist/manifest/breaking-change.d.ts.map +1 -0
- package/dist/manifest/breaking-change.js +704 -0
- package/dist/manifest/breaking-change.js.map +1 -0
- package/dist/manifest/compiler.d.ts +12 -0
- package/dist/manifest/compiler.d.ts.map +1 -0
- package/dist/manifest/compiler.js +23 -0
- package/dist/manifest/compiler.js.map +1 -0
- package/dist/manifest/config.d.ts +171 -0
- package/dist/manifest/config.d.ts.map +1 -0
- package/dist/manifest/config.js +65 -0
- package/dist/manifest/config.js.map +1 -0
- package/dist/manifest/constraint-analysis.d.ts +122 -0
- package/dist/manifest/constraint-analysis.d.ts.map +1 -0
- package/dist/manifest/constraint-analysis.js +340 -0
- package/dist/manifest/constraint-analysis.js.map +1 -0
- package/dist/manifest/date-time.d.ts +13 -0
- package/dist/manifest/date-time.d.ts.map +1 -0
- package/dist/manifest/date-time.js +60 -0
- package/dist/manifest/date-time.js.map +1 -0
- package/dist/manifest/debug/command-trace.d.ts +37 -0
- package/dist/manifest/debug/command-trace.d.ts.map +1 -0
- package/dist/manifest/debug/command-trace.js +51 -0
- package/dist/manifest/debug/command-trace.js.map +1 -0
- package/dist/manifest/debug/index.d.ts +3 -0
- package/dist/manifest/debug/index.d.ts.map +1 -0
- package/dist/manifest/debug/index.js +2 -0
- package/dist/manifest/debug/index.js.map +1 -0
- package/dist/manifest/domain-completeness.d.ts +13 -0
- package/dist/manifest/domain-completeness.d.ts.map +1 -0
- package/dist/manifest/domain-completeness.js +245 -0
- package/dist/manifest/domain-completeness.js.map +1 -0
- package/dist/manifest/entity-composition.d.ts +24 -0
- package/dist/manifest/entity-composition.d.ts.map +1 -0
- package/dist/manifest/entity-composition.js +157 -0
- package/dist/manifest/entity-composition.js.map +1 -0
- package/dist/manifest/examples.d.ts +6 -0
- package/dist/manifest/examples.d.ts.map +1 -0
- package/dist/manifest/examples.js +443 -0
- package/dist/manifest/examples.js.map +1 -0
- package/dist/manifest/federation/client.d.ts +52 -0
- package/dist/manifest/federation/client.d.ts.map +1 -0
- package/dist/manifest/federation/client.js +152 -0
- package/dist/manifest/federation/client.js.map +1 -0
- package/dist/manifest/federation/descriptor.d.ts +25 -0
- package/dist/manifest/federation/descriptor.d.ts.map +1 -0
- package/dist/manifest/federation/descriptor.js +97 -0
- package/dist/manifest/federation/descriptor.js.map +1 -0
- package/dist/manifest/federation/http-adapter.d.ts +26 -0
- package/dist/manifest/federation/http-adapter.d.ts.map +1 -0
- package/dist/manifest/federation/http-adapter.js +209 -0
- package/dist/manifest/federation/http-adapter.js.map +1 -0
- package/dist/manifest/federation/index.d.ts +51 -0
- package/dist/manifest/federation/index.d.ts.map +1 -0
- package/dist/manifest/federation/index.js +49 -0
- package/dist/manifest/federation/index.js.map +1 -0
- package/dist/manifest/federation/policy-bridge.d.ts +51 -0
- package/dist/manifest/federation/policy-bridge.d.ts.map +1 -0
- package/dist/manifest/federation/policy-bridge.js +122 -0
- package/dist/manifest/federation/policy-bridge.js.map +1 -0
- package/dist/manifest/federation/registry.d.ts +88 -0
- package/dist/manifest/federation/registry.d.ts.map +1 -0
- package/dist/manifest/federation/registry.js +165 -0
- package/dist/manifest/federation/registry.js.map +1 -0
- package/dist/manifest/federation/types.d.ts +209 -0
- package/dist/manifest/federation/types.d.ts.map +1 -0
- package/dist/manifest/federation/types.js +13 -0
- package/dist/manifest/federation/types.js.map +1 -0
- package/dist/manifest/generator.d.ts +44 -0
- package/dist/manifest/generator.d.ts.map +1 -0
- package/dist/manifest/generator.js +899 -0
- package/dist/manifest/generator.js.map +1 -0
- package/dist/manifest/ir-cache.d.ts +48 -0
- package/dist/manifest/ir-cache.d.ts.map +1 -0
- package/dist/manifest/ir-cache.js +91 -0
- package/dist/manifest/ir-cache.js.map +1 -0
- package/dist/manifest/ir-compiler.d.ts +135 -0
- package/dist/manifest/ir-compiler.d.ts.map +1 -0
- package/dist/manifest/ir-compiler.js +1477 -0
- package/dist/manifest/ir-compiler.js.map +1 -0
- package/dist/manifest/ir-diff.d.ts +266 -0
- package/dist/manifest/ir-diff.d.ts.map +1 -0
- package/dist/manifest/ir-diff.js +731 -0
- package/dist/manifest/ir-diff.js.map +1 -0
- package/dist/manifest/ir-version-store.d.ts +109 -0
- package/dist/manifest/ir-version-store.d.ts.map +1 -0
- package/dist/manifest/ir-version-store.js +162 -0
- package/dist/manifest/ir-version-store.js.map +1 -0
- package/dist/manifest/ir.d.ts +616 -0
- package/dist/manifest/ir.d.ts.map +1 -0
- package/dist/manifest/ir.js +2 -0
- package/dist/manifest/ir.js.map +1 -0
- package/dist/manifest/lexer.d.ts +37 -0
- package/dist/manifest/lexer.d.ts.map +1 -0
- package/dist/manifest/lexer.js +224 -0
- package/dist/manifest/lexer.js.map +1 -0
- package/dist/manifest/masking.d.ts +11 -0
- package/dist/manifest/masking.d.ts.map +1 -0
- package/dist/manifest/masking.js +34 -0
- package/dist/manifest/masking.js.map +1 -0
- package/dist/manifest/module-resolver.d.ts +42 -0
- package/dist/manifest/module-resolver.d.ts.map +1 -0
- package/dist/manifest/module-resolver.js +162 -0
- package/dist/manifest/module-resolver.js.map +1 -0
- package/dist/manifest/multi-compiler.d.ts +40 -0
- package/dist/manifest/multi-compiler.d.ts.map +1 -0
- package/dist/manifest/multi-compiler.js +324 -0
- package/dist/manifest/multi-compiler.js.map +1 -0
- package/dist/manifest/outbox/outbox-store.d.ts +56 -0
- package/dist/manifest/outbox/outbox-store.d.ts.map +1 -0
- package/dist/manifest/outbox/outbox-store.js +13 -0
- package/dist/manifest/outbox/outbox-store.js.map +1 -0
- package/dist/manifest/outbox/stores/dynamodb.d.ts +100 -0
- package/dist/manifest/outbox/stores/dynamodb.d.ts.map +1 -0
- package/dist/manifest/outbox/stores/dynamodb.js +239 -0
- package/dist/manifest/outbox/stores/dynamodb.js.map +1 -0
- package/dist/manifest/outbox/stores/memory.d.ts +54 -0
- package/dist/manifest/outbox/stores/memory.d.ts.map +1 -0
- package/dist/manifest/outbox/stores/memory.js +131 -0
- package/dist/manifest/outbox/stores/memory.js.map +1 -0
- package/dist/manifest/outbox/stores/mongodb.d.ts +58 -0
- package/dist/manifest/outbox/stores/mongodb.d.ts.map +1 -0
- package/dist/manifest/outbox/stores/mongodb.js +151 -0
- package/dist/manifest/outbox/stores/mongodb.js.map +1 -0
- package/dist/manifest/outbox/stores/postgres.d.ts +81 -0
- package/dist/manifest/outbox/stores/postgres.d.ts.map +1 -0
- package/dist/manifest/outbox/stores/postgres.js +182 -0
- package/dist/manifest/outbox/stores/postgres.js.map +1 -0
- package/dist/manifest/outbox/stores/redis.d.ts +95 -0
- package/dist/manifest/outbox/stores/redis.d.ts.map +1 -0
- package/dist/manifest/outbox/stores/redis.js +248 -0
- package/dist/manifest/outbox/stores/redis.js.map +1 -0
- package/dist/manifest/parser.d.ts +148 -0
- package/dist/manifest/parser.d.ts.map +1 -0
- package/dist/manifest/parser.js +2243 -0
- package/dist/manifest/parser.js.map +1 -0
- package/dist/manifest/plugin-api.d.ts +202 -0
- package/dist/manifest/plugin-api.d.ts.map +1 -0
- package/dist/manifest/plugin-api.js +101 -0
- package/dist/manifest/plugin-api.js.map +1 -0
- package/dist/manifest/plugin-loader.d.ts +101 -0
- package/dist/manifest/plugin-loader.d.ts.map +1 -0
- package/dist/manifest/plugin-loader.js +332 -0
- package/dist/manifest/plugin-loader.js.map +1 -0
- package/dist/manifest/profiling.d.ts +183 -0
- package/dist/manifest/profiling.d.ts.map +1 -0
- package/dist/manifest/profiling.js +186 -0
- package/dist/manifest/profiling.js.map +1 -0
- package/dist/manifest/projections/analytics/generator.d.ts +27 -0
- package/dist/manifest/projections/analytics/generator.d.ts.map +1 -0
- package/dist/manifest/projections/analytics/generator.js +686 -0
- package/dist/manifest/projections/analytics/generator.js.map +1 -0
- package/dist/manifest/projections/analytics/types.d.ts +46 -0
- package/dist/manifest/projections/analytics/types.d.ts.map +1 -0
- package/dist/manifest/projections/analytics/types.js +8 -0
- package/dist/manifest/projections/analytics/types.js.map +1 -0
- package/dist/manifest/projections/builtins.d.ts +29 -0
- package/dist/manifest/projections/builtins.d.ts.map +1 -0
- package/dist/manifest/projections/builtins.js +143 -0
- package/dist/manifest/projections/builtins.js.map +1 -0
- package/dist/manifest/projections/convex/expression.d.ts +52 -0
- package/dist/manifest/projections/convex/expression.d.ts.map +1 -0
- package/dist/manifest/projections/convex/expression.js +166 -0
- package/dist/manifest/projections/convex/expression.js.map +1 -0
- package/dist/manifest/projections/convex/functions.d.ts +22 -0
- package/dist/manifest/projections/convex/functions.d.ts.map +1 -0
- package/dist/manifest/projections/convex/functions.js +786 -0
- package/dist/manifest/projections/convex/functions.js.map +1 -0
- package/dist/manifest/projections/convex/generator.d.ts +79 -0
- package/dist/manifest/projections/convex/generator.d.ts.map +1 -0
- package/dist/manifest/projections/convex/generator.js +406 -0
- package/dist/manifest/projections/convex/generator.js.map +1 -0
- package/dist/manifest/projections/convex/index.d.ts +10 -0
- package/dist/manifest/projections/convex/index.d.ts.map +1 -0
- package/dist/manifest/projections/convex/index.js +10 -0
- package/dist/manifest/projections/convex/index.js.map +1 -0
- package/dist/manifest/projections/convex/options.d.ts +153 -0
- package/dist/manifest/projections/convex/options.d.ts.map +1 -0
- package/dist/manifest/projections/convex/options.js +60 -0
- package/dist/manifest/projections/convex/options.js.map +1 -0
- package/dist/manifest/projections/convex/orchestration.d.ts +23 -0
- package/dist/manifest/projections/convex/orchestration.d.ts.map +1 -0
- package/dist/manifest/projections/convex/orchestration.js +150 -0
- package/dist/manifest/projections/convex/orchestration.js.map +1 -0
- package/dist/manifest/projections/convex/type-mapping.d.ts +40 -0
- package/dist/manifest/projections/convex/type-mapping.d.ts.map +1 -0
- package/dist/manifest/projections/convex/type-mapping.js +71 -0
- package/dist/manifest/projections/convex/type-mapping.js.map +1 -0
- package/dist/manifest/projections/dart/generator.d.ts +33 -0
- package/dist/manifest/projections/dart/generator.d.ts.map +1 -0
- package/dist/manifest/projections/dart/generator.js +981 -0
- package/dist/manifest/projections/dart/generator.js.map +1 -0
- package/dist/manifest/projections/dart/types.d.ts +29 -0
- package/dist/manifest/projections/dart/types.d.ts.map +1 -0
- package/dist/manifest/projections/dart/types.js +5 -0
- package/dist/manifest/projections/dart/types.js.map +1 -0
- package/dist/manifest/projections/drizzle/generator.d.ts +27 -0
- package/dist/manifest/projections/drizzle/generator.d.ts.map +1 -0
- package/dist/manifest/projections/drizzle/generator.js +654 -0
- package/dist/manifest/projections/drizzle/generator.js.map +1 -0
- package/dist/manifest/projections/drizzle/index.d.ts +12 -0
- package/dist/manifest/projections/drizzle/index.d.ts.map +1 -0
- package/dist/manifest/projections/drizzle/index.js +12 -0
- package/dist/manifest/projections/drizzle/index.js.map +1 -0
- package/dist/manifest/projections/drizzle/options.d.ts +94 -0
- package/dist/manifest/projections/drizzle/options.d.ts.map +1 -0
- package/dist/manifest/projections/drizzle/options.js +31 -0
- package/dist/manifest/projections/drizzle/options.js.map +1 -0
- package/dist/manifest/projections/drizzle/type-mapping.d.ts +74 -0
- package/dist/manifest/projections/drizzle/type-mapping.d.ts.map +1 -0
- package/dist/manifest/projections/drizzle/type-mapping.js +101 -0
- package/dist/manifest/projections/drizzle/type-mapping.js.map +1 -0
- package/dist/manifest/projections/dynamodb/generator.d.ts +48 -0
- package/dist/manifest/projections/dynamodb/generator.d.ts.map +1 -0
- package/dist/manifest/projections/dynamodb/generator.js +341 -0
- package/dist/manifest/projections/dynamodb/generator.js.map +1 -0
- package/dist/manifest/projections/elasticsearch/generator.d.ts +44 -0
- package/dist/manifest/projections/elasticsearch/generator.d.ts.map +1 -0
- package/dist/manifest/projections/elasticsearch/generator.js +613 -0
- package/dist/manifest/projections/elasticsearch/generator.js.map +1 -0
- package/dist/manifest/projections/elasticsearch/options.d.ts +56 -0
- package/dist/manifest/projections/elasticsearch/options.d.ts.map +1 -0
- package/dist/manifest/projections/elasticsearch/options.js +37 -0
- package/dist/manifest/projections/elasticsearch/options.js.map +1 -0
- package/dist/manifest/projections/elasticsearch/type-mapping.d.ts +30 -0
- package/dist/manifest/projections/elasticsearch/type-mapping.d.ts.map +1 -0
- package/dist/manifest/projections/elasticsearch/type-mapping.js +34 -0
- package/dist/manifest/projections/elasticsearch/type-mapping.js.map +1 -0
- package/dist/manifest/projections/elasticsearch/types.d.ts +81 -0
- package/dist/manifest/projections/elasticsearch/types.d.ts.map +1 -0
- package/dist/manifest/projections/elasticsearch/types.js +10 -0
- package/dist/manifest/projections/elasticsearch/types.js.map +1 -0
- package/dist/manifest/projections/express/generator.d.ts +38 -0
- package/dist/manifest/projections/express/generator.d.ts.map +1 -0
- package/dist/manifest/projections/express/generator.js +620 -0
- package/dist/manifest/projections/express/generator.js.map +1 -0
- package/dist/manifest/projections/express/index.d.ts +8 -0
- package/dist/manifest/projections/express/index.d.ts.map +1 -0
- package/dist/manifest/projections/express/index.js +7 -0
- package/dist/manifest/projections/express/index.js.map +1 -0
- package/dist/manifest/projections/express/types.d.ts +92 -0
- package/dist/manifest/projections/express/types.d.ts.map +1 -0
- package/dist/manifest/projections/express/types.js +9 -0
- package/dist/manifest/projections/express/types.js.map +1 -0
- package/dist/manifest/projections/graphql/generator.d.ts +43 -0
- package/dist/manifest/projections/graphql/generator.d.ts.map +1 -0
- package/dist/manifest/projections/graphql/generator.js +662 -0
- package/dist/manifest/projections/graphql/generator.js.map +1 -0
- package/dist/manifest/projections/graphql/index.d.ts +11 -0
- package/dist/manifest/projections/graphql/index.d.ts.map +1 -0
- package/dist/manifest/projections/graphql/index.js +10 -0
- package/dist/manifest/projections/graphql/index.js.map +1 -0
- package/dist/manifest/projections/graphql/types.d.ts +69 -0
- package/dist/manifest/projections/graphql/types.d.ts.map +1 -0
- package/dist/manifest/projections/graphql/types.js +9 -0
- package/dist/manifest/projections/graphql/types.js.map +1 -0
- package/dist/manifest/projections/health/generator.d.ts +36 -0
- package/dist/manifest/projections/health/generator.d.ts.map +1 -0
- package/dist/manifest/projections/health/generator.js +355 -0
- package/dist/manifest/projections/health/generator.js.map +1 -0
- package/dist/manifest/projections/health/types.d.ts +67 -0
- package/dist/manifest/projections/health/types.d.ts.map +1 -0
- package/dist/manifest/projections/health/types.js +28 -0
- package/dist/manifest/projections/health/types.js.map +1 -0
- package/dist/manifest/projections/hono/generator.d.ts +36 -0
- package/dist/manifest/projections/hono/generator.d.ts.map +1 -0
- package/dist/manifest/projections/hono/generator.js +578 -0
- package/dist/manifest/projections/hono/generator.js.map +1 -0
- package/dist/manifest/projections/hono/types.d.ts +86 -0
- package/dist/manifest/projections/hono/types.d.ts.map +1 -0
- package/dist/manifest/projections/hono/types.js +10 -0
- package/dist/manifest/projections/hono/types.js.map +1 -0
- package/dist/manifest/projections/index.d.ts +58 -0
- package/dist/manifest/projections/index.d.ts.map +1 -0
- package/dist/manifest/projections/index.js +41 -0
- package/dist/manifest/projections/index.js.map +1 -0
- package/dist/manifest/projections/interface.d.ts +285 -0
- package/dist/manifest/projections/interface.d.ts.map +1 -0
- package/dist/manifest/projections/interface.js +8 -0
- package/dist/manifest/projections/interface.js.map +1 -0
- package/dist/manifest/projections/jsonschema/generator.d.ts +35 -0
- package/dist/manifest/projections/jsonschema/generator.d.ts.map +1 -0
- package/dist/manifest/projections/jsonschema/generator.js +347 -0
- package/dist/manifest/projections/jsonschema/generator.js.map +1 -0
- package/dist/manifest/projections/jsonschema/index.d.ts +3 -0
- package/dist/manifest/projections/jsonschema/index.d.ts.map +1 -0
- package/dist/manifest/projections/jsonschema/index.js +2 -0
- package/dist/manifest/projections/jsonschema/index.js.map +1 -0
- package/dist/manifest/projections/jsonschema/types.d.ts +31 -0
- package/dist/manifest/projections/jsonschema/types.d.ts.map +1 -0
- package/dist/manifest/projections/jsonschema/types.js +2 -0
- package/dist/manifest/projections/jsonschema/types.js.map +1 -0
- package/dist/manifest/projections/kysely/generator.d.ts +36 -0
- package/dist/manifest/projections/kysely/generator.d.ts.map +1 -0
- package/dist/manifest/projections/kysely/generator.js +325 -0
- package/dist/manifest/projections/kysely/generator.js.map +1 -0
- package/dist/manifest/projections/kysely/index.d.ts +4 -0
- package/dist/manifest/projections/kysely/index.d.ts.map +1 -0
- package/dist/manifest/projections/kysely/index.js +2 -0
- package/dist/manifest/projections/kysely/index.js.map +1 -0
- package/dist/manifest/projections/kysely/options.d.ts +61 -0
- package/dist/manifest/projections/kysely/options.d.ts.map +1 -0
- package/dist/manifest/projections/kysely/options.js +31 -0
- package/dist/manifest/projections/kysely/options.js.map +1 -0
- package/dist/manifest/projections/kysely/type-mapping.d.ts +61 -0
- package/dist/manifest/projections/kysely/type-mapping.d.ts.map +1 -0
- package/dist/manifest/projections/kysely/type-mapping.js +84 -0
- package/dist/manifest/projections/kysely/type-mapping.js.map +1 -0
- package/dist/manifest/projections/llm-context/generator.d.ts +24 -0
- package/dist/manifest/projections/llm-context/generator.d.ts.map +1 -0
- package/dist/manifest/projections/llm-context/generator.js +371 -0
- package/dist/manifest/projections/llm-context/generator.js.map +1 -0
- package/dist/manifest/projections/llm-context/types.d.ts +205 -0
- package/dist/manifest/projections/llm-context/types.d.ts.map +1 -0
- package/dist/manifest/projections/llm-context/types.js +9 -0
- package/dist/manifest/projections/llm-context/types.js.map +1 -0
- package/dist/manifest/projections/materialized-views/expression-to-sql.d.ts +29 -0
- package/dist/manifest/projections/materialized-views/expression-to-sql.d.ts.map +1 -0
- package/dist/manifest/projections/materialized-views/expression-to-sql.js +211 -0
- package/dist/manifest/projections/materialized-views/expression-to-sql.js.map +1 -0
- package/dist/manifest/projections/materialized-views/generator.d.ts +29 -0
- package/dist/manifest/projections/materialized-views/generator.d.ts.map +1 -0
- package/dist/manifest/projections/materialized-views/generator.js +263 -0
- package/dist/manifest/projections/materialized-views/generator.js.map +1 -0
- package/dist/manifest/projections/materialized-views/options.d.ts +59 -0
- package/dist/manifest/projections/materialized-views/options.d.ts.map +1 -0
- package/dist/manifest/projections/materialized-views/options.js +34 -0
- package/dist/manifest/projections/materialized-views/options.js.map +1 -0
- package/dist/manifest/projections/materialized-views/types.d.ts +100 -0
- package/dist/manifest/projections/materialized-views/types.d.ts.map +1 -0
- package/dist/manifest/projections/materialized-views/types.js +11 -0
- package/dist/manifest/projections/materialized-views/types.js.map +1 -0
- package/dist/manifest/projections/mermaid/generator.d.ts +46 -0
- package/dist/manifest/projections/mermaid/generator.d.ts.map +1 -0
- package/dist/manifest/projections/mermaid/generator.js +436 -0
- package/dist/manifest/projections/mermaid/generator.js.map +1 -0
- package/dist/manifest/projections/mongoose/options.d.ts +30 -0
- package/dist/manifest/projections/mongoose/options.d.ts.map +1 -0
- package/dist/manifest/projections/mongoose/options.js +18 -0
- package/dist/manifest/projections/mongoose/options.js.map +1 -0
- package/dist/manifest/projections/mongoose/type-mapping.d.ts +42 -0
- package/dist/manifest/projections/mongoose/type-mapping.d.ts.map +1 -0
- package/dist/manifest/projections/mongoose/type-mapping.js +64 -0
- package/dist/manifest/projections/mongoose/type-mapping.js.map +1 -0
- package/dist/manifest/projections/nextjs/defaults.d.ts +161 -0
- package/dist/manifest/projections/nextjs/defaults.d.ts.map +1 -0
- package/dist/manifest/projections/nextjs/defaults.js +157 -0
- package/dist/manifest/projections/nextjs/defaults.js.map +1 -0
- package/dist/manifest/projections/nextjs/generator.d.ts +78 -0
- package/dist/manifest/projections/nextjs/generator.d.ts.map +1 -0
- package/dist/manifest/projections/nextjs/generator.js +1339 -0
- package/dist/manifest/projections/nextjs/generator.js.map +1 -0
- package/dist/manifest/projections/nextjs/schedule-generator.d.ts +10 -0
- package/dist/manifest/projections/nextjs/schedule-generator.d.ts.map +1 -0
- package/dist/manifest/projections/nextjs/schedule-generator.js +54 -0
- package/dist/manifest/projections/nextjs/schedule-generator.js.map +1 -0
- package/dist/manifest/projections/openapi/generator.d.ts +37 -0
- package/dist/manifest/projections/openapi/generator.d.ts.map +1 -0
- package/dist/manifest/projections/openapi/generator.js +690 -0
- package/dist/manifest/projections/openapi/generator.js.map +1 -0
- package/dist/manifest/projections/openapi/index.d.ts +11 -0
- package/dist/manifest/projections/openapi/index.d.ts.map +1 -0
- package/dist/manifest/projections/openapi/index.js +10 -0
- package/dist/manifest/projections/openapi/index.js.map +1 -0
- package/dist/manifest/projections/openapi/types.d.ts +75 -0
- package/dist/manifest/projections/openapi/types.d.ts.map +1 -0
- package/dist/manifest/projections/openapi/types.js +9 -0
- package/dist/manifest/projections/openapi/types.js.map +1 -0
- package/dist/manifest/projections/prisma/generator.d.ts +32 -0
- package/dist/manifest/projections/prisma/generator.d.ts.map +1 -0
- package/dist/manifest/projections/prisma/generator.js +861 -0
- package/dist/manifest/projections/prisma/generator.js.map +1 -0
- package/dist/manifest/projections/prisma/index.d.ts +12 -0
- package/dist/manifest/projections/prisma/index.d.ts.map +1 -0
- package/dist/manifest/projections/prisma/index.js +12 -0
- package/dist/manifest/projections/prisma/index.js.map +1 -0
- package/dist/manifest/projections/prisma/options.d.ts +243 -0
- package/dist/manifest/projections/prisma/options.d.ts.map +1 -0
- package/dist/manifest/projections/prisma/options.js +59 -0
- package/dist/manifest/projections/prisma/options.js.map +1 -0
- package/dist/manifest/projections/prisma/type-mapping.d.ts +60 -0
- package/dist/manifest/projections/prisma/type-mapping.d.ts.map +1 -0
- package/dist/manifest/projections/prisma/type-mapping.js +95 -0
- package/dist/manifest/projections/prisma/type-mapping.js.map +1 -0
- package/dist/manifest/projections/prisma-store/generator.d.ts +12 -0
- package/dist/manifest/projections/prisma-store/generator.d.ts.map +1 -0
- package/dist/manifest/projections/prisma-store/generator.js +52 -0
- package/dist/manifest/projections/prisma-store/generator.js.map +1 -0
- package/dist/manifest/projections/prisma-store/metadata-builder.d.ts +11 -0
- package/dist/manifest/projections/prisma-store/metadata-builder.d.ts.map +1 -0
- package/dist/manifest/projections/prisma-store/metadata-builder.js +183 -0
- package/dist/manifest/projections/prisma-store/metadata-builder.js.map +1 -0
- package/dist/manifest/projections/prisma-store/options.d.ts +31 -0
- package/dist/manifest/projections/prisma-store/options.d.ts.map +1 -0
- package/dist/manifest/projections/prisma-store/options.js +21 -0
- package/dist/manifest/projections/prisma-store/options.js.map +1 -0
- package/dist/manifest/projections/prisma-store/persistence.d.ts +4 -0
- package/dist/manifest/projections/prisma-store/persistence.d.ts.map +1 -0
- package/dist/manifest/projections/prisma-store/persistence.js +24 -0
- package/dist/manifest/projections/prisma-store/persistence.js.map +1 -0
- package/dist/manifest/projections/pydantic/generator.d.ts +27 -0
- package/dist/manifest/projections/pydantic/generator.d.ts.map +1 -0
- package/dist/manifest/projections/pydantic/generator.js +798 -0
- package/dist/manifest/projections/pydantic/generator.js.map +1 -0
- package/dist/manifest/projections/pydantic/types.d.ts +32 -0
- package/dist/manifest/projections/pydantic/types.d.ts.map +1 -0
- package/dist/manifest/projections/pydantic/types.js +5 -0
- package/dist/manifest/projections/pydantic/types.js.map +1 -0
- package/dist/manifest/projections/react-query/generator.d.ts +87 -0
- package/dist/manifest/projections/react-query/generator.d.ts.map +1 -0
- package/dist/manifest/projections/react-query/generator.js +413 -0
- package/dist/manifest/projections/react-query/generator.js.map +1 -0
- package/dist/manifest/projections/registry.d.ts +59 -0
- package/dist/manifest/projections/registry.d.ts.map +1 -0
- package/dist/manifest/projections/registry.js +110 -0
- package/dist/manifest/projections/registry.js.map +1 -0
- package/dist/manifest/projections/remix/generator.d.ts +58 -0
- package/dist/manifest/projections/remix/generator.d.ts.map +1 -0
- package/dist/manifest/projections/remix/generator.js +788 -0
- package/dist/manifest/projections/remix/generator.js.map +1 -0
- package/dist/manifest/projections/routes/generator.d.ts +32 -0
- package/dist/manifest/projections/routes/generator.d.ts.map +1 -0
- package/dist/manifest/projections/routes/generator.js +401 -0
- package/dist/manifest/projections/routes/generator.js.map +1 -0
- package/dist/manifest/projections/routes/types.d.ts +104 -0
- package/dist/manifest/projections/routes/types.d.ts.map +1 -0
- package/dist/manifest/projections/routes/types.js +11 -0
- package/dist/manifest/projections/routes/types.js.map +1 -0
- package/dist/manifest/projections/shared/naming.d.ts +64 -0
- package/dist/manifest/projections/shared/naming.d.ts.map +1 -0
- package/dist/manifest/projections/shared/naming.js +138 -0
- package/dist/manifest/projections/shared/naming.js.map +1 -0
- package/dist/manifest/projections/storybook/generator.d.ts +38 -0
- package/dist/manifest/projections/storybook/generator.d.ts.map +1 -0
- package/dist/manifest/projections/storybook/generator.js +462 -0
- package/dist/manifest/projections/storybook/generator.js.map +1 -0
- package/dist/manifest/projections/sveltekit/generator.d.ts +64 -0
- package/dist/manifest/projections/sveltekit/generator.d.ts.map +1 -0
- package/dist/manifest/projections/sveltekit/generator.js +1043 -0
- package/dist/manifest/projections/sveltekit/generator.js.map +1 -0
- package/dist/manifest/projections/sveltekit/index.d.ts +11 -0
- package/dist/manifest/projections/sveltekit/index.d.ts.map +1 -0
- package/dist/manifest/projections/sveltekit/index.js +10 -0
- package/dist/manifest/projections/sveltekit/index.js.map +1 -0
- package/dist/manifest/projections/sveltekit/types.d.ts +122 -0
- package/dist/manifest/projections/sveltekit/types.d.ts.map +1 -0
- package/dist/manifest/projections/sveltekit/types.js +10 -0
- package/dist/manifest/projections/sveltekit/types.js.map +1 -0
- package/dist/manifest/projections/terraform/generator.d.ts +29 -0
- package/dist/manifest/projections/terraform/generator.d.ts.map +1 -0
- package/dist/manifest/projections/terraform/generator.js +722 -0
- package/dist/manifest/projections/terraform/generator.js.map +1 -0
- package/dist/manifest/projections/terraform/index.d.ts +7 -0
- package/dist/manifest/projections/terraform/index.d.ts.map +1 -0
- package/dist/manifest/projections/terraform/index.js +7 -0
- package/dist/manifest/projections/terraform/index.js.map +1 -0
- package/dist/manifest/projections/terraform/options.d.ts +92 -0
- package/dist/manifest/projections/terraform/options.d.ts.map +1 -0
- package/dist/manifest/projections/terraform/options.js +37 -0
- package/dist/manifest/projections/terraform/options.js.map +1 -0
- package/dist/manifest/projections/terraform/types.d.ts +55 -0
- package/dist/manifest/projections/terraform/types.d.ts.map +1 -0
- package/dist/manifest/projections/terraform/types.js +38 -0
- package/dist/manifest/projections/terraform/types.js.map +1 -0
- package/dist/manifest/projections/zod/generator.d.ts +27 -0
- package/dist/manifest/projections/zod/generator.d.ts.map +1 -0
- package/dist/manifest/projections/zod/generator.js +367 -0
- package/dist/manifest/projections/zod/generator.js.map +1 -0
- package/dist/manifest/projections/zod/index.d.ts +8 -0
- package/dist/manifest/projections/zod/index.d.ts.map +1 -0
- package/dist/manifest/projections/zod/index.js +7 -0
- package/dist/manifest/projections/zod/index.js.map +1 -0
- package/dist/manifest/projections/zod/types.d.ts +14 -0
- package/dist/manifest/projections/zod/types.d.ts.map +1 -0
- package/dist/manifest/projections/zod/types.js +5 -0
- package/dist/manifest/projections/zod/types.js.map +1 -0
- package/dist/manifest/reaction-completeness-checks.d.ts +11 -0
- package/dist/manifest/reaction-completeness-checks.d.ts.map +1 -0
- package/dist/manifest/reaction-completeness-checks.js +106 -0
- package/dist/manifest/reaction-completeness-checks.js.map +1 -0
- package/dist/manifest/reaction-completeness.d.ts +9 -0
- package/dist/manifest/reaction-completeness.d.ts.map +1 -0
- package/dist/manifest/reaction-completeness.js +35 -0
- package/dist/manifest/reaction-completeness.js.map +1 -0
- package/dist/manifest/registry/emit.d.ts +53 -0
- package/dist/manifest/registry/emit.d.ts.map +1 -0
- package/dist/manifest/registry/emit.js +96 -0
- package/dist/manifest/registry/emit.js.map +1 -0
- package/dist/manifest/runtime-command-extensions.d.ts +21 -0
- package/dist/manifest/runtime-command-extensions.d.ts.map +1 -0
- package/dist/manifest/runtime-command-extensions.js +136 -0
- package/dist/manifest/runtime-command-extensions.js.map +1 -0
- package/dist/manifest/runtime-engine.d.ts +1019 -0
- package/dist/manifest/runtime-engine.d.ts.map +1 -0
- package/dist/manifest/runtime-engine.js +3872 -0
- package/dist/manifest/runtime-engine.js.map +1 -0
- package/dist/manifest/runtime-profiling-bridge.d.ts +22 -0
- package/dist/manifest/runtime-profiling-bridge.d.ts.map +1 -0
- package/dist/manifest/runtime-profiling-bridge.js +69 -0
- package/dist/manifest/runtime-profiling-bridge.js.map +1 -0
- package/dist/manifest/runtime-rate-limit.d.ts +52 -0
- package/dist/manifest/runtime-rate-limit.d.ts.map +1 -0
- package/dist/manifest/runtime-rate-limit.js +70 -0
- package/dist/manifest/runtime-rate-limit.js.map +1 -0
- package/dist/manifest/runtime-retry.d.ts +68 -0
- package/dist/manifest/runtime-retry.d.ts.map +1 -0
- package/dist/manifest/runtime-retry.js +93 -0
- package/dist/manifest/runtime-retry.js.map +1 -0
- package/dist/manifest/runtime-schedule.d.ts +47 -0
- package/dist/manifest/runtime-schedule.d.ts.map +1 -0
- package/dist/manifest/runtime-schedule.js +95 -0
- package/dist/manifest/runtime-schedule.js.map +1 -0
- package/dist/manifest/schedule-utils.d.ts +15 -0
- package/dist/manifest/schedule-utils.d.ts.map +1 -0
- package/dist/manifest/schedule-utils.js +82 -0
- package/dist/manifest/schedule-utils.js.map +1 -0
- package/dist/manifest/standalone-generator.d.ts +32 -0
- package/dist/manifest/standalone-generator.d.ts.map +1 -0
- package/dist/manifest/standalone-generator.js +596 -0
- package/dist/manifest/standalone-generator.js.map +1 -0
- package/dist/manifest/stores/prisma-generic/coercion.d.ts +17 -0
- package/dist/manifest/stores/prisma-generic/coercion.d.ts.map +1 -0
- package/dist/manifest/stores/prisma-generic/coercion.js +83 -0
- package/dist/manifest/stores/prisma-generic/coercion.js.map +1 -0
- package/dist/manifest/stores/prisma-generic/index.d.ts +3 -0
- package/dist/manifest/stores/prisma-generic/index.d.ts.map +1 -0
- package/dist/manifest/stores/prisma-generic/index.js +2 -0
- package/dist/manifest/stores/prisma-generic/index.js.map +1 -0
- package/dist/manifest/stores/prisma-generic/store.d.ts +35 -0
- package/dist/manifest/stores/prisma-generic/store.d.ts.map +1 -0
- package/dist/manifest/stores/prisma-generic/store.js +216 -0
- package/dist/manifest/stores/prisma-generic/store.js.map +1 -0
- package/dist/manifest/stores/prisma-generic/types.d.ts +46 -0
- package/dist/manifest/stores/prisma-generic/types.d.ts.map +1 -0
- package/dist/manifest/stores/prisma-generic/types.js +6 -0
- package/dist/manifest/stores/prisma-generic/types.js.map +1 -0
- package/dist/manifest/stores.node.d.ts +248 -0
- package/dist/manifest/stores.node.d.ts.map +1 -0
- package/dist/manifest/stores.node.js +718 -0
- package/dist/manifest/stores.node.js.map +1 -0
- package/dist/manifest/test/postgres-live-env.d.ts +9 -0
- package/dist/manifest/test/postgres-live-env.d.ts.map +1 -0
- package/dist/manifest/test/postgres-live-env.js +14 -0
- package/dist/manifest/test/postgres-live-env.js.map +1 -0
- package/dist/manifest/types.d.ts +570 -0
- package/dist/manifest/types.d.ts.map +1 -0
- package/dist/manifest/types.js +2 -0
- package/dist/manifest/types.js.map +1 -0
- package/dist/manifest/version.d.ts +15 -0
- package/dist/manifest/version.d.ts.map +1 -0
- package/dist/manifest/version.js +15 -0
- package/dist/manifest/version.js.map +1 -0
- package/dist/manifest/wasm/index.d.ts +15 -0
- package/dist/manifest/wasm/index.d.ts.map +1 -0
- package/dist/manifest/wasm/index.js +15 -0
- package/dist/manifest/wasm/index.js.map +1 -0
- package/dist/manifest/wasm/wasm-evaluator.d.ts +93 -0
- package/dist/manifest/wasm/wasm-evaluator.d.ts.map +1 -0
- package/dist/manifest/wasm/wasm-evaluator.js +242 -0
- package/dist/manifest/wasm/wasm-evaluator.js.map +1 -0
- package/dist/manifest/wasm/wasm-loader.d.ts +56 -0
- package/dist/manifest/wasm/wasm-loader.d.ts.map +1 -0
- package/dist/manifest/wasm/wasm-loader.js +132 -0
- package/dist/manifest/wasm/wasm-loader.js.map +1 -0
- package/docs/spec/config/manifest.config.schema.json +737 -0
- package/docs/spec/config/prisma-projection.schema.json +173 -0
- package/docs/spec/ir/ir-v1.schema.json +2033 -0
- package/docs/spec/plugins/plugin.schema.json +104 -0
- package/docs/spec/registry/bypasses.schema.json +87 -0
- package/docs/spec/registry/commands.schema.json +61 -0
- package/docs/spec/registry/entities.schema.json +52 -0
- package/docs/spec/semantics.md +630 -0
- package/package.json +356 -0
- package/packages/cli/dist/audit/bypass-violations.d.ts +16 -0
- package/packages/cli/dist/audit/bypass-violations.d.ts.map +1 -0
- package/packages/cli/dist/audit/bypass-violations.js +98 -0
- package/packages/cli/dist/audit/bypass-violations.js.map +1 -0
- package/packages/cli/dist/audit/direct-writes.d.ts +15 -0
- package/packages/cli/dist/audit/direct-writes.d.ts.map +1 -0
- package/packages/cli/dist/audit/direct-writes.js +86 -0
- package/packages/cli/dist/audit/direct-writes.js.map +1 -0
- package/packages/cli/dist/audit/event-fabrication.d.ts +17 -0
- package/packages/cli/dist/audit/event-fabrication.d.ts.map +1 -0
- package/packages/cli/dist/audit/event-fabrication.js +101 -0
- package/packages/cli/dist/audit/event-fabrication.js.map +1 -0
- package/packages/cli/dist/audit/existing-command-available.d.ts +20 -0
- package/packages/cli/dist/audit/existing-command-available.d.ts.map +1 -0
- package/packages/cli/dist/audit/existing-command-available.js +158 -0
- package/packages/cli/dist/audit/existing-command-available.js.map +1 -0
- package/packages/cli/dist/audit/missing-tests.d.ts +17 -0
- package/packages/cli/dist/audit/missing-tests.d.ts.map +1 -0
- package/packages/cli/dist/audit/missing-tests.js +108 -0
- package/packages/cli/dist/audit/missing-tests.js.map +1 -0
- package/packages/cli/dist/audit/route-drift.d.ts +16 -0
- package/packages/cli/dist/audit/route-drift.d.ts.map +1 -0
- package/packages/cli/dist/audit/route-drift.js +86 -0
- package/packages/cli/dist/audit/route-drift.js.map +1 -0
- package/packages/cli/dist/audit/types.d.ts +63 -0
- package/packages/cli/dist/audit/types.d.ts.map +1 -0
- package/packages/cli/dist/audit/types.js +10 -0
- package/packages/cli/dist/audit/types.js.map +1 -0
- package/packages/cli/dist/audit/unregistered-command-call.d.ts +25 -0
- package/packages/cli/dist/audit/unregistered-command-call.d.ts.map +1 -0
- package/packages/cli/dist/audit/unregistered-command-call.js +196 -0
- package/packages/cli/dist/audit/unregistered-command-call.js.map +1 -0
- package/packages/cli/dist/audit/unregistered-entity-write.d.ts +16 -0
- package/packages/cli/dist/audit/unregistered-entity-write.d.ts.map +1 -0
- package/packages/cli/dist/audit/unregistered-entity-write.js +96 -0
- package/packages/cli/dist/audit/unregistered-entity-write.js.map +1 -0
- package/packages/cli/dist/audit/write-receiver.d.ts +23 -0
- package/packages/cli/dist/audit/write-receiver.d.ts.map +1 -0
- package/packages/cli/dist/audit/write-receiver.js +32 -0
- package/packages/cli/dist/audit/write-receiver.js.map +1 -0
- package/packages/cli/dist/checks/dispatcher-presence.d.ts +37 -0
- package/packages/cli/dist/checks/dispatcher-presence.d.ts.map +1 -0
- package/packages/cli/dist/checks/dispatcher-presence.js +57 -0
- package/packages/cli/dist/checks/dispatcher-presence.js.map +1 -0
- package/packages/cli/dist/checks/package-shape.d.ts +81 -0
- package/packages/cli/dist/checks/package-shape.d.ts.map +1 -0
- package/packages/cli/dist/checks/package-shape.js +359 -0
- package/packages/cli/dist/checks/package-shape.js.map +1 -0
- package/packages/cli/dist/checks/runtime-smoke.d.ts +42 -0
- package/packages/cli/dist/checks/runtime-smoke.d.ts.map +1 -0
- package/packages/cli/dist/checks/runtime-smoke.js +167 -0
- package/packages/cli/dist/checks/runtime-smoke.js.map +1 -0
- package/packages/cli/dist/commands/analyze.d.ts +97 -0
- package/packages/cli/dist/commands/analyze.d.ts.map +1 -0
- package/packages/cli/dist/commands/analyze.js +411 -0
- package/packages/cli/dist/commands/analyze.js.map +1 -0
- package/packages/cli/dist/commands/audit-bypasses.d.ts +31 -0
- package/packages/cli/dist/commands/audit-bypasses.d.ts.map +1 -0
- package/packages/cli/dist/commands/audit-bypasses.js +152 -0
- package/packages/cli/dist/commands/audit-bypasses.js.map +1 -0
- package/packages/cli/dist/commands/audit-constitution.d.ts +20 -0
- package/packages/cli/dist/commands/audit-constitution.d.ts.map +1 -0
- package/packages/cli/dist/commands/audit-constitution.js +18 -0
- package/packages/cli/dist/commands/audit-constitution.js.map +1 -0
- package/packages/cli/dist/commands/audit-governance.d.ts +37 -0
- package/packages/cli/dist/commands/audit-governance.d.ts.map +1 -0
- package/packages/cli/dist/commands/audit-governance.js +78 -0
- package/packages/cli/dist/commands/audit-governance.js.map +1 -0
- package/packages/cli/dist/commands/audit-routes.d.ts +135 -0
- package/packages/cli/dist/commands/audit-routes.d.ts.map +1 -0
- package/packages/cli/dist/commands/audit-routes.js +514 -0
- package/packages/cli/dist/commands/audit-routes.js.map +1 -0
- package/packages/cli/dist/commands/breaking-change.d.ts +15 -0
- package/packages/cli/dist/commands/breaking-change.d.ts.map +1 -0
- package/packages/cli/dist/commands/breaking-change.js +150 -0
- package/packages/cli/dist/commands/breaking-change.js.map +1 -0
- package/packages/cli/dist/commands/build.d.ts +26 -0
- package/packages/cli/dist/commands/build.d.ts.map +1 -0
- package/packages/cli/dist/commands/build.js +58 -0
- package/packages/cli/dist/commands/build.js.map +1 -0
- package/packages/cli/dist/commands/changelog.d.ts +26 -0
- package/packages/cli/dist/commands/changelog.d.ts.map +1 -0
- package/packages/cli/dist/commands/changelog.js +365 -0
- package/packages/cli/dist/commands/changelog.js.map +1 -0
- package/packages/cli/dist/commands/check.d.ts +21 -0
- package/packages/cli/dist/commands/check.d.ts.map +1 -0
- package/packages/cli/dist/commands/check.js +31 -0
- package/packages/cli/dist/commands/check.js.map +1 -0
- package/packages/cli/dist/commands/compile.d.ts +19 -0
- package/packages/cli/dist/commands/compile.d.ts.map +1 -0
- package/packages/cli/dist/commands/compile.js +325 -0
- package/packages/cli/dist/commands/compile.js.map +1 -0
- package/packages/cli/dist/commands/config.d.ts +23 -0
- package/packages/cli/dist/commands/config.d.ts.map +1 -0
- package/packages/cli/dist/commands/config.js +172 -0
- package/packages/cli/dist/commands/config.js.map +1 -0
- package/packages/cli/dist/commands/coverage.d.ts +55 -0
- package/packages/cli/dist/commands/coverage.d.ts.map +1 -0
- package/packages/cli/dist/commands/coverage.js +343 -0
- package/packages/cli/dist/commands/coverage.js.map +1 -0
- package/packages/cli/dist/commands/diagram.d.ts +22 -0
- package/packages/cli/dist/commands/diagram.d.ts.map +1 -0
- package/packages/cli/dist/commands/diagram.js +176 -0
- package/packages/cli/dist/commands/diagram.js.map +1 -0
- package/packages/cli/dist/commands/docs.d.ts +18 -0
- package/packages/cli/dist/commands/docs.d.ts.map +1 -0
- package/packages/cli/dist/commands/docs.js +722 -0
- package/packages/cli/dist/commands/docs.js.map +1 -0
- package/packages/cli/dist/commands/doctor-lib.d.ts +147 -0
- package/packages/cli/dist/commands/doctor-lib.d.ts.map +1 -0
- package/packages/cli/dist/commands/doctor-lib.js +491 -0
- package/packages/cli/dist/commands/doctor-lib.js.map +1 -0
- package/packages/cli/dist/commands/doctor.d.ts +31 -0
- package/packages/cli/dist/commands/doctor.d.ts.map +1 -0
- package/packages/cli/dist/commands/doctor.js +628 -0
- package/packages/cli/dist/commands/doctor.js.map +1 -0
- package/packages/cli/dist/commands/emit-registries.d.ts +33 -0
- package/packages/cli/dist/commands/emit-registries.d.ts.map +1 -0
- package/packages/cli/dist/commands/emit-registries.js +109 -0
- package/packages/cli/dist/commands/emit-registries.js.map +1 -0
- package/packages/cli/dist/commands/enforce-surface.d.ts +62 -0
- package/packages/cli/dist/commands/enforce-surface.d.ts.map +1 -0
- package/packages/cli/dist/commands/enforce-surface.js +172 -0
- package/packages/cli/dist/commands/enforce-surface.js.map +1 -0
- package/packages/cli/dist/commands/fmt.d.ts +17 -0
- package/packages/cli/dist/commands/fmt.d.ts.map +1 -0
- package/packages/cli/dist/commands/fmt.js +129 -0
- package/packages/cli/dist/commands/fmt.js.map +1 -0
- package/packages/cli/dist/commands/gen-tests.d.ts +41 -0
- package/packages/cli/dist/commands/gen-tests.d.ts.map +1 -0
- package/packages/cli/dist/commands/gen-tests.js +370 -0
- package/packages/cli/dist/commands/gen-tests.js.map +1 -0
- package/packages/cli/dist/commands/generate-from-prompt.d.ts +34 -0
- package/packages/cli/dist/commands/generate-from-prompt.d.ts.map +1 -0
- package/packages/cli/dist/commands/generate-from-prompt.js +990 -0
- package/packages/cli/dist/commands/generate-from-prompt.js.map +1 -0
- package/packages/cli/dist/commands/generate.d.ts +36 -0
- package/packages/cli/dist/commands/generate.d.ts.map +1 -0
- package/packages/cli/dist/commands/generate.js +371 -0
- package/packages/cli/dist/commands/generate.js.map +1 -0
- package/packages/cli/dist/commands/harness.d.ts +13 -0
- package/packages/cli/dist/commands/harness.d.ts.map +1 -0
- package/packages/cli/dist/commands/harness.js +276 -0
- package/packages/cli/dist/commands/harness.js.map +1 -0
- package/packages/cli/dist/commands/init-ci.d.ts +19 -0
- package/packages/cli/dist/commands/init-ci.d.ts.map +1 -0
- package/packages/cli/dist/commands/init-ci.js +148 -0
- package/packages/cli/dist/commands/init-ci.js.map +1 -0
- package/packages/cli/dist/commands/init.d.ts +33 -0
- package/packages/cli/dist/commands/init.d.ts.map +1 -0
- package/packages/cli/dist/commands/init.js +157 -0
- package/packages/cli/dist/commands/init.js.map +1 -0
- package/packages/cli/dist/commands/install-hooks.d.ts +29 -0
- package/packages/cli/dist/commands/install-hooks.d.ts.map +1 -0
- package/packages/cli/dist/commands/install-hooks.js +139 -0
- package/packages/cli/dist/commands/install-hooks.js.map +1 -0
- package/packages/cli/dist/commands/integration-check.d.ts +62 -0
- package/packages/cli/dist/commands/integration-check.d.ts.map +1 -0
- package/packages/cli/dist/commands/integration-check.js +298 -0
- package/packages/cli/dist/commands/integration-check.js.map +1 -0
- package/packages/cli/dist/commands/ir-diff.d.ts +8 -0
- package/packages/cli/dist/commands/ir-diff.d.ts.map +1 -0
- package/packages/cli/dist/commands/ir-diff.js +199 -0
- package/packages/cli/dist/commands/ir-diff.js.map +1 -0
- package/packages/cli/dist/commands/lint-routes.d.ts +56 -0
- package/packages/cli/dist/commands/lint-routes.d.ts.map +1 -0
- package/packages/cli/dist/commands/lint-routes.js +228 -0
- package/packages/cli/dist/commands/lint-routes.js.map +1 -0
- package/packages/cli/dist/commands/load-test.d.ts +61 -0
- package/packages/cli/dist/commands/load-test.d.ts.map +1 -0
- package/packages/cli/dist/commands/load-test.js +675 -0
- package/packages/cli/dist/commands/load-test.js.map +1 -0
- package/packages/cli/dist/commands/migrate.d.ts +21 -0
- package/packages/cli/dist/commands/migrate.d.ts.map +1 -0
- package/packages/cli/dist/commands/migrate.js +264 -0
- package/packages/cli/dist/commands/migrate.js.map +1 -0
- package/packages/cli/dist/commands/mock.d.ts +79 -0
- package/packages/cli/dist/commands/mock.d.ts.map +1 -0
- package/packages/cli/dist/commands/mock.js +324 -0
- package/packages/cli/dist/commands/mock.js.map +1 -0
- package/packages/cli/dist/commands/pack-unpack.d.ts +30 -0
- package/packages/cli/dist/commands/pack-unpack.d.ts.map +1 -0
- package/packages/cli/dist/commands/pack-unpack.js +108 -0
- package/packages/cli/dist/commands/pack-unpack.js.map +1 -0
- package/packages/cli/dist/commands/preflight.d.ts +31 -0
- package/packages/cli/dist/commands/preflight.d.ts.map +1 -0
- package/packages/cli/dist/commands/preflight.js +246 -0
- package/packages/cli/dist/commands/preflight.js.map +1 -0
- package/packages/cli/dist/commands/profile.d.ts +30 -0
- package/packages/cli/dist/commands/profile.d.ts.map +1 -0
- package/packages/cli/dist/commands/profile.js +201 -0
- package/packages/cli/dist/commands/profile.js.map +1 -0
- package/packages/cli/dist/commands/repl.d.ts +16 -0
- package/packages/cli/dist/commands/repl.d.ts.map +1 -0
- package/packages/cli/dist/commands/repl.js +772 -0
- package/packages/cli/dist/commands/repl.js.map +1 -0
- package/packages/cli/dist/commands/routes.d.ts +24 -0
- package/packages/cli/dist/commands/routes.d.ts.map +1 -0
- package/packages/cli/dist/commands/routes.js +144 -0
- package/packages/cli/dist/commands/routes.js.map +1 -0
- package/packages/cli/dist/commands/scan.d.ts +23 -0
- package/packages/cli/dist/commands/scan.d.ts.map +1 -0
- package/packages/cli/dist/commands/scan.js +722 -0
- package/packages/cli/dist/commands/scan.js.map +1 -0
- package/packages/cli/dist/commands/seed.d.ts +35 -0
- package/packages/cli/dist/commands/seed.d.ts.map +1 -0
- package/packages/cli/dist/commands/seed.js +503 -0
- package/packages/cli/dist/commands/seed.js.map +1 -0
- package/packages/cli/dist/commands/validate-ai-ajv.d.ts +4 -0
- package/packages/cli/dist/commands/validate-ai-ajv.d.ts.map +1 -0
- package/packages/cli/dist/commands/validate-ai-ajv.js +78 -0
- package/packages/cli/dist/commands/validate-ai-ajv.js.map +1 -0
- package/packages/cli/dist/commands/validate-ai-compiler.d.ts +5 -0
- package/packages/cli/dist/commands/validate-ai-compiler.d.ts.map +1 -0
- package/packages/cli/dist/commands/validate-ai-compiler.js +8 -0
- package/packages/cli/dist/commands/validate-ai-compiler.js.map +1 -0
- package/packages/cli/dist/commands/validate-ai-report.d.ts +5 -0
- package/packages/cli/dist/commands/validate-ai-report.d.ts.map +1 -0
- package/packages/cli/dist/commands/validate-ai-report.js +80 -0
- package/packages/cli/dist/commands/validate-ai-report.js.map +1 -0
- package/packages/cli/dist/commands/validate-ai-resolve-inputs.d.ts +6 -0
- package/packages/cli/dist/commands/validate-ai-resolve-inputs.d.ts.map +1 -0
- package/packages/cli/dist/commands/validate-ai-resolve-inputs.js +54 -0
- package/packages/cli/dist/commands/validate-ai-resolve-inputs.js.map +1 -0
- package/packages/cli/dist/commands/validate-ai-semantic-checks.d.ts +4 -0
- package/packages/cli/dist/commands/validate-ai-semantic-checks.d.ts.map +1 -0
- package/packages/cli/dist/commands/validate-ai-semantic-checks.js +218 -0
- package/packages/cli/dist/commands/validate-ai-semantic-checks.js.map +1 -0
- package/packages/cli/dist/commands/validate-ai-types.d.ts +41 -0
- package/packages/cli/dist/commands/validate-ai-types.d.ts.map +1 -0
- package/packages/cli/dist/commands/validate-ai-types.js +2 -0
- package/packages/cli/dist/commands/validate-ai-types.js.map +1 -0
- package/packages/cli/dist/commands/validate-ai-validate-file.d.ts +5 -0
- package/packages/cli/dist/commands/validate-ai-validate-file.d.ts.map +1 -0
- package/packages/cli/dist/commands/validate-ai-validate-file.js +126 -0
- package/packages/cli/dist/commands/validate-ai-validate-file.js.map +1 -0
- package/packages/cli/dist/commands/validate-ai.d.ts +15 -0
- package/packages/cli/dist/commands/validate-ai.d.ts.map +1 -0
- package/packages/cli/dist/commands/validate-ai.js +124 -0
- package/packages/cli/dist/commands/validate-ai.js.map +1 -0
- package/packages/cli/dist/commands/validate.d.ts +15 -0
- package/packages/cli/dist/commands/validate.d.ts.map +1 -0
- package/packages/cli/dist/commands/validate.js +205 -0
- package/packages/cli/dist/commands/validate.js.map +1 -0
- package/packages/cli/dist/commands/versions.d.ts +56 -0
- package/packages/cli/dist/commands/versions.d.ts.map +1 -0
- package/packages/cli/dist/commands/versions.js +427 -0
- package/packages/cli/dist/commands/versions.js.map +1 -0
- package/packages/cli/dist/commands/watch.d.ts +34 -0
- package/packages/cli/dist/commands/watch.d.ts.map +1 -0
- package/packages/cli/dist/commands/watch.js +253 -0
- package/packages/cli/dist/commands/watch.js.map +1 -0
- package/packages/cli/dist/index.d.ts +14 -0
- package/packages/cli/dist/index.d.ts.map +1 -0
- package/packages/cli/dist/index.js +1159 -0
- package/packages/cli/dist/index.js.map +1 -0
- package/packages/cli/dist/utils/config-validate.d.ts +48 -0
- package/packages/cli/dist/utils/config-validate.d.ts.map +1 -0
- package/packages/cli/dist/utils/config-validate.js +116 -0
- package/packages/cli/dist/utils/config-validate.js.map +1 -0
- package/packages/cli/dist/utils/config.d.ts +360 -0
- package/packages/cli/dist/utils/config.d.ts.map +1 -0
- package/packages/cli/dist/utils/config.js +567 -0
- package/packages/cli/dist/utils/config.js.map +1 -0
- package/packages/cli/dist/utils/schema.d.ts +8 -0
- package/packages/cli/dist/utils/schema.d.ts.map +1 -0
- package/packages/cli/dist/utils/schema.js +13 -0
- package/packages/cli/dist/utils/schema.js.map +1 -0
- package/packages/lsp-server/bin/manifest-lsp.js +3 -0
- package/packages/lsp-server/dist/compiler-bridge.d.ts +24 -0
- package/packages/lsp-server/dist/compiler-bridge.d.ts.map +1 -0
- package/packages/lsp-server/dist/compiler-bridge.js +32 -0
- package/packages/lsp-server/dist/compiler-bridge.js.map +1 -0
- package/packages/lsp-server/dist/document-store.d.ts +23 -0
- package/packages/lsp-server/dist/document-store.d.ts.map +1 -0
- package/packages/lsp-server/dist/document-store.js +40 -0
- package/packages/lsp-server/dist/document-store.js.map +1 -0
- package/packages/lsp-server/dist/features/completion.d.ts +23 -0
- package/packages/lsp-server/dist/features/completion.d.ts.map +1 -0
- package/packages/lsp-server/dist/features/completion.js +293 -0
- package/packages/lsp-server/dist/features/completion.js.map +1 -0
- package/packages/lsp-server/dist/features/definition.d.ts +9 -0
- package/packages/lsp-server/dist/features/definition.d.ts.map +1 -0
- package/packages/lsp-server/dist/features/definition.js +24 -0
- package/packages/lsp-server/dist/features/definition.js.map +1 -0
- package/packages/lsp-server/dist/features/diagnostics.d.ts +8 -0
- package/packages/lsp-server/dist/features/diagnostics.d.ts.map +1 -0
- package/packages/lsp-server/dist/features/diagnostics.js +40 -0
- package/packages/lsp-server/dist/features/diagnostics.js.map +1 -0
- package/packages/lsp-server/dist/features/document-symbols.d.ts +8 -0
- package/packages/lsp-server/dist/features/document-symbols.d.ts.map +1 -0
- package/packages/lsp-server/dist/features/document-symbols.js +164 -0
- package/packages/lsp-server/dist/features/document-symbols.js.map +1 -0
- package/packages/lsp-server/dist/features/hover.d.ts +9 -0
- package/packages/lsp-server/dist/features/hover.d.ts.map +1 -0
- package/packages/lsp-server/dist/features/hover.js +100 -0
- package/packages/lsp-server/dist/features/hover.js.map +1 -0
- package/packages/lsp-server/dist/index.d.ts +6 -0
- package/packages/lsp-server/dist/index.d.ts.map +1 -0
- package/packages/lsp-server/dist/index.js +11 -0
- package/packages/lsp-server/dist/index.js.map +1 -0
- package/packages/lsp-server/dist/position-utils.d.ts +25 -0
- package/packages/lsp-server/dist/position-utils.d.ts.map +1 -0
- package/packages/lsp-server/dist/position-utils.js +39 -0
- package/packages/lsp-server/dist/position-utils.js.map +1 -0
- package/packages/lsp-server/dist/server.d.ts +14 -0
- package/packages/lsp-server/dist/server.d.ts.map +1 -0
- package/packages/lsp-server/dist/server.js +96 -0
- package/packages/lsp-server/dist/server.js.map +1 -0
- package/packages/lsp-server/dist/symbols/builtin-docs.d.ts +34 -0
- package/packages/lsp-server/dist/symbols/builtin-docs.d.ts.map +1 -0
- package/packages/lsp-server/dist/symbols/builtin-docs.js +193 -0
- package/packages/lsp-server/dist/symbols/builtin-docs.js.map +1 -0
- package/packages/lsp-server/dist/symbols/symbol-index.d.ts +18 -0
- package/packages/lsp-server/dist/symbols/symbol-index.d.ts.map +1 -0
- package/packages/lsp-server/dist/symbols/symbol-index.js +107 -0
- package/packages/lsp-server/dist/symbols/symbol-index.js.map +1 -0
- package/packages/mcp-server/bin/manifest-mcp.js +27 -0
- package/packages/mcp-server/dist/index.d.ts +24 -0
- package/packages/mcp-server/dist/index.d.ts.map +1 -0
- package/packages/mcp-server/dist/index.js +36 -0
- package/packages/mcp-server/dist/index.js.map +1 -0
- package/packages/mcp-server/dist/resources/ir-cache.d.ts +9 -0
- package/packages/mcp-server/dist/resources/ir-cache.d.ts.map +1 -0
- package/packages/mcp-server/dist/resources/ir-cache.js +47 -0
- package/packages/mcp-server/dist/resources/ir-cache.js.map +1 -0
- package/packages/mcp-server/dist/resources/ir-schema.d.ts +8 -0
- package/packages/mcp-server/dist/resources/ir-schema.d.ts.map +1 -0
- package/packages/mcp-server/dist/resources/ir-schema.js +39 -0
- package/packages/mcp-server/dist/resources/ir-schema.js.map +1 -0
- package/packages/mcp-server/dist/resources/semantics.d.ts +8 -0
- package/packages/mcp-server/dist/resources/semantics.d.ts.map +1 -0
- package/packages/mcp-server/dist/resources/semantics.js +38 -0
- package/packages/mcp-server/dist/resources/semantics.js.map +1 -0
- package/packages/mcp-server/dist/server.d.ts +7 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -0
- package/packages/mcp-server/dist/server.js +22 -0
- package/packages/mcp-server/dist/server.js.map +1 -0
- package/packages/mcp-server/dist/state/session-store.d.ts +39 -0
- package/packages/mcp-server/dist/state/session-store.d.ts.map +1 -0
- package/packages/mcp-server/dist/state/session-store.js +58 -0
- package/packages/mcp-server/dist/state/session-store.js.map +1 -0
- package/packages/mcp-server/dist/tools/compile.d.ts +30 -0
- package/packages/mcp-server/dist/tools/compile.d.ts.map +1 -0
- package/packages/mcp-server/dist/tools/compile.js +54 -0
- package/packages/mcp-server/dist/tools/compile.js.map +1 -0
- package/packages/mcp-server/dist/tools/execute.d.ts +112 -0
- package/packages/mcp-server/dist/tools/execute.d.ts.map +1 -0
- package/packages/mcp-server/dist/tools/execute.js +103 -0
- package/packages/mcp-server/dist/tools/execute.js.map +1 -0
- package/packages/mcp-server/dist/tools/explain.d.ts +25 -0
- package/packages/mcp-server/dist/tools/explain.d.ts.map +1 -0
- package/packages/mcp-server/dist/tools/explain.js +254 -0
- package/packages/mcp-server/dist/tools/explain.js.map +1 -0
- package/packages/mcp-server/dist/tools/validate.d.ts +23 -0
- package/packages/mcp-server/dist/tools/validate.d.ts.map +1 -0
- package/packages/mcp-server/dist/tools/validate.js +38 -0
- package/packages/mcp-server/dist/tools/validate.js.map +1 -0
- package/src/manifest/audit/sinks/postgres.sql +51 -0
- package/src/manifest/outbox/stores/postgres.sql +61 -0
|
@@ -0,0 +1,1477 @@
|
|
|
1
|
+
import { Parser } from './parser.js';
|
|
2
|
+
import { expandEntityComposition } from './entity-composition.js';
|
|
3
|
+
import { checkDomainCompleteness } from './domain-completeness.js';
|
|
4
|
+
import { checkReactionCompleteness } from './reaction-completeness.js';
|
|
5
|
+
import { parseDurationToMs, isValidCronExpression } from './schedule-utils.js';
|
|
6
|
+
import { globalIRCache } from './ir-cache.js';
|
|
7
|
+
import { COMPILER_VERSION, SCHEMA_VERSION } from './version.js';
|
|
8
|
+
/**
|
|
9
|
+
* Compute SHA-256 hash of the source manifest
|
|
10
|
+
*/
|
|
11
|
+
async function computeContentHash(source) {
|
|
12
|
+
const encoder = new TextEncoder();
|
|
13
|
+
const data = encoder.encode(source);
|
|
14
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
|
15
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
16
|
+
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Create provenance metadata for the IR
|
|
20
|
+
*/
|
|
21
|
+
async function createProvenance(source, irHash) {
|
|
22
|
+
return {
|
|
23
|
+
contentHash: await computeContentHash(source),
|
|
24
|
+
irHash,
|
|
25
|
+
compilerVersion: COMPILER_VERSION,
|
|
26
|
+
schemaVersion: SCHEMA_VERSION,
|
|
27
|
+
compiledAt: new Date().toISOString(),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Compute SHA-256 hash of the IR for runtime integrity verification
|
|
32
|
+
* This creates a canonical representation by sorting keys and excluding the irHash itself
|
|
33
|
+
*/
|
|
34
|
+
export async function computeIRHash(ir) {
|
|
35
|
+
// Create a copy of the IR without the irHash for hashing
|
|
36
|
+
const { provenance, ...irWithoutProvenance } = ir;
|
|
37
|
+
const { irHash: _irHash, ...provenanceWithoutIrHash } = provenance;
|
|
38
|
+
const canonical = {
|
|
39
|
+
...irWithoutProvenance,
|
|
40
|
+
provenance: provenanceWithoutIrHash,
|
|
41
|
+
};
|
|
42
|
+
// Use deterministic JSON serialization with recursive key sorting.
|
|
43
|
+
// A replacer function sorts object keys at every nesting level to ensure
|
|
44
|
+
// identical IR always produces the same hash regardless of property insertion order.
|
|
45
|
+
// NOTE: An array replacer (Object.keys().sort()) would only whitelist those key
|
|
46
|
+
// names at ALL levels, silently dropping nested properties — a subtle JSON.stringify
|
|
47
|
+
// pitfall that would make the hash blind to content changes within entities/commands.
|
|
48
|
+
const json = JSON.stringify(canonical, (_key, value) => {
|
|
49
|
+
if (value && typeof value === 'object' && !Array.isArray(value)) {
|
|
50
|
+
const sorted = {};
|
|
51
|
+
for (const k of Object.keys(value).sort()) {
|
|
52
|
+
sorted[k] = value[k];
|
|
53
|
+
}
|
|
54
|
+
return sorted;
|
|
55
|
+
}
|
|
56
|
+
return value;
|
|
57
|
+
});
|
|
58
|
+
const encoder = new TextEncoder();
|
|
59
|
+
const data = encoder.encode(json);
|
|
60
|
+
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
|
|
61
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
62
|
+
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
|
|
63
|
+
}
|
|
64
|
+
const COMMAND_INTENT_VERBS = {
|
|
65
|
+
create: 'create',
|
|
66
|
+
add: 'create',
|
|
67
|
+
new: 'create',
|
|
68
|
+
update: 'update',
|
|
69
|
+
edit: 'update',
|
|
70
|
+
modify: 'update',
|
|
71
|
+
delete: 'delete',
|
|
72
|
+
remove: 'delete',
|
|
73
|
+
deactivate: 'delete',
|
|
74
|
+
archive: 'delete',
|
|
75
|
+
};
|
|
76
|
+
function normalizeIntentToken(value) {
|
|
77
|
+
return value.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
78
|
+
}
|
|
79
|
+
function stripEntityAffixes(command, entity) {
|
|
80
|
+
const entityToken = entity ? normalizeIntentToken(entity) : '';
|
|
81
|
+
let normalized = normalizeIntentToken(command);
|
|
82
|
+
if (!entityToken)
|
|
83
|
+
return normalized;
|
|
84
|
+
let changed = true;
|
|
85
|
+
while (changed && normalized.length > entityToken.length) {
|
|
86
|
+
changed = false;
|
|
87
|
+
if (normalized.startsWith(entityToken)) {
|
|
88
|
+
normalized = normalized.slice(entityToken.length);
|
|
89
|
+
changed = true;
|
|
90
|
+
}
|
|
91
|
+
if (normalized.endsWith(entityToken) && normalized.length > entityToken.length) {
|
|
92
|
+
normalized = normalized.slice(0, -entityToken.length);
|
|
93
|
+
changed = true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return normalized;
|
|
97
|
+
}
|
|
98
|
+
function normalizeCommandIntent(command, entity) {
|
|
99
|
+
const stripped = stripEntityAffixes(command, entity);
|
|
100
|
+
for (const verb of Object.keys(COMMAND_INTENT_VERBS).sort((a, b) => b.length - a.length)) {
|
|
101
|
+
if (stripped === verb || stripped.startsWith(verb)) {
|
|
102
|
+
const rest = stripped.slice(verb.length);
|
|
103
|
+
return `${COMMAND_INTENT_VERBS[verb]}:${rest}`;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return `custom:${stripped}`;
|
|
107
|
+
}
|
|
108
|
+
function commandDisplay(entry) {
|
|
109
|
+
return entry.entity ? `${entry.entity}.${entry.command}` : entry.command;
|
|
110
|
+
}
|
|
111
|
+
function sourceDisplay(entry) {
|
|
112
|
+
if (!entry.sourcePath)
|
|
113
|
+
return undefined;
|
|
114
|
+
const position = entry.line !== undefined
|
|
115
|
+
? `:${entry.line}${entry.column !== undefined ? `:${entry.column}` : ''}`
|
|
116
|
+
: '';
|
|
117
|
+
return `${entry.sourcePath}${position}`;
|
|
118
|
+
}
|
|
119
|
+
function duplicateCommandIntentDiagnostic(duplicate, existing) {
|
|
120
|
+
const duplicateSource = sourceDisplay(duplicate);
|
|
121
|
+
const existingSource = sourceDisplay(existing);
|
|
122
|
+
const locations = [
|
|
123
|
+
duplicateSource ? `duplicate source: ${duplicateSource}` : undefined,
|
|
124
|
+
existingSource ? `existing source: ${existingSource}` : undefined,
|
|
125
|
+
].filter(Boolean).join('; ');
|
|
126
|
+
return {
|
|
127
|
+
severity: 'error',
|
|
128
|
+
message: `Duplicate command intent for ${commandDisplay(duplicate)} conflicts with existing command ${commandDisplay(existing)}${locations ? ` (${locations})` : ''}; use or extend the existing command.`,
|
|
129
|
+
line: duplicate.line,
|
|
130
|
+
column: duplicate.column,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
export function validateCommandIntentRegistry(entries) {
|
|
134
|
+
const diagnostics = [];
|
|
135
|
+
const exact = new Map();
|
|
136
|
+
const canonical = new Map();
|
|
137
|
+
for (const entry of entries) {
|
|
138
|
+
const entityKey = entry.entity ?? '__global__';
|
|
139
|
+
const exactKey = `${entityKey}\u0000${entry.command}`;
|
|
140
|
+
const exactExisting = exact.get(exactKey);
|
|
141
|
+
if (exactExisting) {
|
|
142
|
+
diagnostics.push(duplicateCommandIntentDiagnostic(entry, exactExisting));
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
exact.set(exactKey, entry);
|
|
146
|
+
const canonicalKey = `${entityKey}\u0000${normalizeCommandIntent(entry.command, entry.entity)}`;
|
|
147
|
+
const canonicalExisting = canonical.get(canonicalKey);
|
|
148
|
+
if (canonicalExisting) {
|
|
149
|
+
diagnostics.push(duplicateCommandIntentDiagnostic(entry, canonicalExisting));
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
canonical.set(canonicalKey, entry);
|
|
153
|
+
}
|
|
154
|
+
return diagnostics;
|
|
155
|
+
}
|
|
156
|
+
function collectCommandIntentEntries(program, sourcePath) {
|
|
157
|
+
return [
|
|
158
|
+
...program.commands.map(command => ({
|
|
159
|
+
command: command.name,
|
|
160
|
+
sourcePath,
|
|
161
|
+
line: command.position?.line,
|
|
162
|
+
column: command.position?.column,
|
|
163
|
+
})),
|
|
164
|
+
...program.modules.flatMap(module => module.commands.map(command => ({
|
|
165
|
+
command: command.name,
|
|
166
|
+
sourcePath,
|
|
167
|
+
line: command.position?.line,
|
|
168
|
+
column: command.position?.column,
|
|
169
|
+
}))),
|
|
170
|
+
...program.entities.flatMap(entity => entity.commands.map(command => ({
|
|
171
|
+
entity: entity.name,
|
|
172
|
+
command: command.name,
|
|
173
|
+
sourcePath,
|
|
174
|
+
line: command.position?.line,
|
|
175
|
+
column: command.position?.column,
|
|
176
|
+
}))),
|
|
177
|
+
...program.modules.flatMap(module => module.entities.flatMap(entity => entity.commands.map(command => ({
|
|
178
|
+
entity: entity.name,
|
|
179
|
+
command: command.name,
|
|
180
|
+
sourcePath,
|
|
181
|
+
line: command.position?.line,
|
|
182
|
+
column: command.position?.column,
|
|
183
|
+
})))),
|
|
184
|
+
];
|
|
185
|
+
}
|
|
186
|
+
export class IRCompiler {
|
|
187
|
+
diagnostics = [];
|
|
188
|
+
cache;
|
|
189
|
+
constructor(cache) {
|
|
190
|
+
this.cache = cache ?? globalIRCache;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Emit a semantic diagnostic during IR compilation.
|
|
194
|
+
* This is the compiler's mechanism for reporting semantic errors
|
|
195
|
+
* beyond what the parser catches (e.g., duplicate constraint codes).
|
|
196
|
+
*/
|
|
197
|
+
emitDiagnostic(severity, message, line, column) {
|
|
198
|
+
this.diagnostics.push({ severity, message, line, column });
|
|
199
|
+
}
|
|
200
|
+
async compileToIR(source, options) {
|
|
201
|
+
this.diagnostics = [];
|
|
202
|
+
// vNext: Check cache before compilation.
|
|
203
|
+
// The content-hash cache keys on THIS file's source only. When a
|
|
204
|
+
// compositionContext is supplied (multi-file build), the compiled IR also
|
|
205
|
+
// depends on entities declared in OTHER files, so caching by this file's hash
|
|
206
|
+
// alone would be incorrect — bypass the cache entirely in that mode.
|
|
207
|
+
const useCache = (options?.useCache ?? true) && !options?.compositionContext;
|
|
208
|
+
if (useCache) {
|
|
209
|
+
const contentHash = await computeContentHash(source);
|
|
210
|
+
const cached = this.cache.get(contentHash);
|
|
211
|
+
if (cached) {
|
|
212
|
+
return { ir: cached, diagnostics: [] };
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const parser = new Parser();
|
|
216
|
+
const { program, errors } = parser.parse(source);
|
|
217
|
+
for (const err of errors) {
|
|
218
|
+
this.diagnostics.push({
|
|
219
|
+
severity: err.severity,
|
|
220
|
+
message: err.message,
|
|
221
|
+
line: err.position?.line,
|
|
222
|
+
column: err.position?.column,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
if (errors.some(e => e.severity === 'error')) {
|
|
226
|
+
return { ir: null, diagnostics: this.diagnostics };
|
|
227
|
+
}
|
|
228
|
+
const ir = await this.transformProgram(program, source, options?.sourcePath, options?.compositionContext);
|
|
229
|
+
// Check for semantic errors emitted during transformation (e.g., duplicate constraint codes)
|
|
230
|
+
if (this.diagnostics.some(d => d.severity === 'error')) {
|
|
231
|
+
return { ir: null, diagnostics: this.diagnostics };
|
|
232
|
+
}
|
|
233
|
+
// vNext: Cache the compiled IR
|
|
234
|
+
if (useCache && ir) {
|
|
235
|
+
const contentHash = await computeContentHash(source);
|
|
236
|
+
this.cache.set(contentHash, ir);
|
|
237
|
+
}
|
|
238
|
+
return { ir, diagnostics: this.diagnostics };
|
|
239
|
+
}
|
|
240
|
+
async transformProgram(program, source, sourcePath, compositionContext) {
|
|
241
|
+
// Expand entity composition (extends, mixin, policies). The optional
|
|
242
|
+
// compositionContext lets cross-file `extends`/`mixin` bases resolve in
|
|
243
|
+
// multi-file builds.
|
|
244
|
+
expandEntityComposition(program, (severity, message) => {
|
|
245
|
+
this.emitDiagnostic(severity, message);
|
|
246
|
+
}, compositionContext);
|
|
247
|
+
// House style: syntax that parses must either lower into IR or be diagnosed,
|
|
248
|
+
// never silently dropped. The following top-level constructs have full parser
|
|
249
|
+
// support but no IR lowering yet (planned/unimplemented). Surface them as
|
|
250
|
+
// warnings so the no-op is explicit instead of silent. These do not null the
|
|
251
|
+
// IR (warnings only); they are NOT hard errors because they appear in the
|
|
252
|
+
// canonical examples and represent a planned-but-unlowered surface. Emitted in
|
|
253
|
+
// a fixed order (flows, effects, exposures, compositions) for deterministic
|
|
254
|
+
// diagnostics. `use` is intentionally excluded — it has partial (path)
|
|
255
|
+
// handling and belongs to multi-file resolution.
|
|
256
|
+
for (const flow of program.flows) {
|
|
257
|
+
this.emitDiagnostic('warning', `Flow '${flow.name}' is parsed but not yet lowered to IR; it has no effect at runtime.`);
|
|
258
|
+
}
|
|
259
|
+
for (const effect of program.effects) {
|
|
260
|
+
this.emitDiagnostic('warning', `Effect '${effect.name}' is parsed but not yet lowered to IR; it has no effect at runtime.`);
|
|
261
|
+
}
|
|
262
|
+
for (const exposure of program.exposures) {
|
|
263
|
+
this.emitDiagnostic('warning', `Expose of entity '${exposure.entity}' is parsed but not yet lowered to IR; it has no effect at runtime.`);
|
|
264
|
+
}
|
|
265
|
+
for (const composition of program.compositions) {
|
|
266
|
+
this.emitDiagnostic('warning', `Composition '${composition.name}' is parsed but not yet lowered to IR; it has no effect at runtime.`);
|
|
267
|
+
}
|
|
268
|
+
// House style: computed properties are NOT materialized into the guard/
|
|
269
|
+
// constraint evaluation context, so a guard or constraint that references one
|
|
270
|
+
// silently resolves to `undefined` (wrong authorization/validation). Reject it
|
|
271
|
+
// with a clear diagnostic instead of letting it succeed silently. (G8)
|
|
272
|
+
for (const entity of program.entities) {
|
|
273
|
+
this.checkComputedRefsInGuardsAndConstraints(entity);
|
|
274
|
+
}
|
|
275
|
+
for (const mod of program.modules) {
|
|
276
|
+
for (const entity of mod.entities) {
|
|
277
|
+
this.checkComputedRefsInGuardsAndConstraints(entity, mod.name);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
const modules = program.modules.map(m => this.transformModule(m));
|
|
281
|
+
const values = program.values.map(v => this.transformValueObject(v));
|
|
282
|
+
const entities = [
|
|
283
|
+
...program.entities.map(e => this.transformEntity(e)),
|
|
284
|
+
...program.modules.flatMap(m => m.entities.map(e => this.transformEntity(e, m.name))),
|
|
285
|
+
];
|
|
286
|
+
const enums = [
|
|
287
|
+
...program.enums.map(e => this.transformEnum(e)),
|
|
288
|
+
...program.modules.flatMap(m => m.enums.map(e => this.transformEnum(e, m.name))),
|
|
289
|
+
];
|
|
290
|
+
// Collect entity-scoped stores (defined as "store in <target>" inside entity)
|
|
291
|
+
// Target can be a built-in name or a custom adapter scheme registered via plugin API.
|
|
292
|
+
const entityScopedStores = [
|
|
293
|
+
...program.entities.filter(e => e.store).map(e => ({
|
|
294
|
+
entity: e.name,
|
|
295
|
+
target: e.store === 'filesystem' ? 'localStorage' : e.store,
|
|
296
|
+
config: {},
|
|
297
|
+
})),
|
|
298
|
+
...program.modules.flatMap(m => m.entities.filter(e => e.store).map(e => ({
|
|
299
|
+
entity: e.name,
|
|
300
|
+
target: e.store === 'filesystem' ? 'localStorage' : e.store,
|
|
301
|
+
config: {},
|
|
302
|
+
}))),
|
|
303
|
+
];
|
|
304
|
+
const stores = [
|
|
305
|
+
...program.stores.map(s => this.transformStore(s)),
|
|
306
|
+
...program.modules.flatMap(m => m.stores.map(s => this.transformStore(s))),
|
|
307
|
+
...entityScopedStores,
|
|
308
|
+
];
|
|
309
|
+
const events = [
|
|
310
|
+
...program.events.map(e => this.transformEvent(e)),
|
|
311
|
+
...program.modules.flatMap(m => m.events.map(e => this.transformEvent(e))),
|
|
312
|
+
];
|
|
313
|
+
const commands = [
|
|
314
|
+
...program.commands.map(c => this.transformCommand(c)),
|
|
315
|
+
...program.modules.flatMap(m => m.commands.map(c => this.transformCommand(c, m.name))),
|
|
316
|
+
...program.entities.flatMap(e => {
|
|
317
|
+
// Get default policies from entity for expansion
|
|
318
|
+
const defaultPolicies = e.policies.filter(p => p.isDefault).map(p => p.name);
|
|
319
|
+
return e.commands.map(c => this.transformCommand(c, undefined, e.name, defaultPolicies));
|
|
320
|
+
}),
|
|
321
|
+
...program.modules.flatMap(m => m.entities.flatMap(e => {
|
|
322
|
+
// Get default policies from entity for expansion
|
|
323
|
+
const defaultPolicies = e.policies.filter(p => p.isDefault).map(p => p.name);
|
|
324
|
+
return e.commands.map(c => this.transformCommand(c, m.name, e.name, defaultPolicies));
|
|
325
|
+
})),
|
|
326
|
+
];
|
|
327
|
+
// Synthesize completion/failure events for async commands.
|
|
328
|
+
// Synthesized events are appended after user-declared events, sorted
|
|
329
|
+
// among themselves by name for deterministic output.
|
|
330
|
+
const userEventNames = new Set(events.map(e => e.name));
|
|
331
|
+
const synthesizedEvents = [];
|
|
332
|
+
for (const cmd of commands) {
|
|
333
|
+
if (cmd.async && cmd.completionEvent && cmd.failureEvent) {
|
|
334
|
+
// Check for user-declared event name collisions
|
|
335
|
+
if (userEventNames.has(cmd.completionEvent)) {
|
|
336
|
+
this.emitDiagnostic('error', `Async command '${cmd.name}' auto-generates event '${cmd.completionEvent}' which collides with a user-declared event of the same name.`);
|
|
337
|
+
}
|
|
338
|
+
if (userEventNames.has(cmd.failureEvent)) {
|
|
339
|
+
this.emitDiagnostic('error', `Async command '${cmd.name}' auto-generates event '${cmd.failureEvent}' which collides with a user-declared event of the same name.`);
|
|
340
|
+
}
|
|
341
|
+
// Synthesize completion event
|
|
342
|
+
synthesizedEvents.push({
|
|
343
|
+
name: cmd.completionEvent,
|
|
344
|
+
channel: `jobs.${cmd.name}`,
|
|
345
|
+
payload: [
|
|
346
|
+
{ name: 'jobId', type: { name: 'string', nullable: false }, required: true },
|
|
347
|
+
{ name: 'result', type: { name: 'any', nullable: true }, required: false },
|
|
348
|
+
{ name: 'completedAt', type: { name: 'number', nullable: false }, required: true },
|
|
349
|
+
],
|
|
350
|
+
});
|
|
351
|
+
// Synthesize failure event
|
|
352
|
+
synthesizedEvents.push({
|
|
353
|
+
name: cmd.failureEvent,
|
|
354
|
+
channel: `jobs.${cmd.name}`,
|
|
355
|
+
payload: [
|
|
356
|
+
{ name: 'jobId', type: { name: 'string', nullable: false }, required: true },
|
|
357
|
+
{ name: 'error', type: { name: 'string', nullable: false }, required: true },
|
|
358
|
+
{ name: 'failedAt', type: { name: 'number', nullable: false }, required: true },
|
|
359
|
+
],
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
// Sort synthesized events by name for deterministic output, then append
|
|
364
|
+
synthesizedEvents.sort((a, b) => a.name.localeCompare(b.name));
|
|
365
|
+
events.push(...synthesizedEvents);
|
|
366
|
+
this.diagnostics.push(...validateCommandIntentRegistry(collectCommandIntentEntries(program, sourcePath)));
|
|
367
|
+
const policies = [
|
|
368
|
+
...program.policies.map(p => this.transformPolicy(p)),
|
|
369
|
+
...program.modules.flatMap(m => m.policies.map(p => this.transformPolicy(p, m.name))),
|
|
370
|
+
// Extract entity-scoped policies with entity name
|
|
371
|
+
...program.entities.flatMap(e => e.policies.map(p => this.transformPolicy(p, undefined, e.name))),
|
|
372
|
+
...program.modules.flatMap(m => m.entities.flatMap(e => e.policies.map(p => this.transformPolicy(p, m.name, e.name)))),
|
|
373
|
+
];
|
|
374
|
+
const reactions = [
|
|
375
|
+
...(program.reactions || []).map(r => this.transformReaction(r)),
|
|
376
|
+
...program.modules.flatMap(m => (m.reactions || []).map(r => this.transformReaction(r, m.name))),
|
|
377
|
+
...program.entities.flatMap(e => (e.reactions || []).map(r => this.transformReaction(r, undefined, e.name))),
|
|
378
|
+
...program.modules.flatMap(m => m.entities.flatMap(e => (e.reactions || []).map(r => this.transformReaction(r, m.name, e.name)))),
|
|
379
|
+
];
|
|
380
|
+
const sagas = [
|
|
381
|
+
...(program.sagas || []).map(s => this.transformSaga(s)),
|
|
382
|
+
...program.modules.flatMap(m => (m.sagas || []).map(s => this.transformSaga(s, m.name))),
|
|
383
|
+
];
|
|
384
|
+
// Collect and resolve role hierarchy
|
|
385
|
+
const rawRoles = [
|
|
386
|
+
...program.roles.map(r => this.transformRole(r)),
|
|
387
|
+
...program.modules.flatMap(m => m.roles.map(r => this.transformRole(r, m.name))),
|
|
388
|
+
];
|
|
389
|
+
const roles = this.resolveRoleGraph(rawRoles);
|
|
390
|
+
const webhooks = [
|
|
391
|
+
...(program.webhooks || []).map(w => this.transformWebhook(w)),
|
|
392
|
+
...program.modules.flatMap(m => (m.webhooks || []).map(w => this.transformWebhook(w, m.name))),
|
|
393
|
+
];
|
|
394
|
+
const schedules = [
|
|
395
|
+
...(program.schedules || []).map(s => this.transformSchedule(s)),
|
|
396
|
+
...program.modules.flatMap(m => (m.schedules || []).map(s => this.transformSchedule(s))),
|
|
397
|
+
];
|
|
398
|
+
// Create provenance once (single timestamp) then compute hash and stamp irHash.
|
|
399
|
+
// Provenance is created WITHOUT irHash first so the hash covers the entire IR
|
|
400
|
+
// except the irHash field itself. We reuse the same provenance object (same
|
|
401
|
+
// compiledAt) to ensure the runtime can reproduce the hash exactly.
|
|
402
|
+
const tenant = program.tenant
|
|
403
|
+
? this.transformTenant(program.tenant)
|
|
404
|
+
: undefined;
|
|
405
|
+
// Static guard: a `create` command that leaves a non-null, default-less field
|
|
406
|
+
// unset is guaranteed to fail at persist time (the `createdAt must not be null`
|
|
407
|
+
// class). Flag it at compile time so it surfaces in the IDE/LSP and CLI validate.
|
|
408
|
+
this.checkRequiredFieldsSetOnCreate(entities, commands, tenant);
|
|
409
|
+
// Static guard: duplicate event names collide in the event registry.
|
|
410
|
+
this.checkEventDeclarations(events);
|
|
411
|
+
// Product completeness: unwired FK params, one-sided relationships, orphan entities.
|
|
412
|
+
checkDomainCompleteness(entities, commands, stores, (severity, message) => {
|
|
413
|
+
if (severity === 'info')
|
|
414
|
+
return;
|
|
415
|
+
this.emitDiagnostic(severity, message);
|
|
416
|
+
}, reactions, tenant);
|
|
417
|
+
checkReactionCompleteness(entities, commands, reactions, (severity, message) => {
|
|
418
|
+
if (severity === 'info')
|
|
419
|
+
return;
|
|
420
|
+
this.emitDiagnostic(severity, message);
|
|
421
|
+
}, events);
|
|
422
|
+
const provenance = await createProvenance(source);
|
|
423
|
+
const irWithoutHash = {
|
|
424
|
+
version: '1.0',
|
|
425
|
+
provenance,
|
|
426
|
+
...(tenant ? { tenant } : {}),
|
|
427
|
+
modules,
|
|
428
|
+
values,
|
|
429
|
+
entities,
|
|
430
|
+
enums,
|
|
431
|
+
stores,
|
|
432
|
+
events,
|
|
433
|
+
commands,
|
|
434
|
+
policies,
|
|
435
|
+
reactions,
|
|
436
|
+
...(sagas.length > 0 ? { sagas } : {}),
|
|
437
|
+
...(roles.length > 0 ? { roles } : {}),
|
|
438
|
+
...(schedules.length > 0 ? { schedules } : {}),
|
|
439
|
+
...(webhooks.length > 0 ? { webhooks } : {}),
|
|
440
|
+
};
|
|
441
|
+
// Compute the IR hash and add it to the existing provenance
|
|
442
|
+
const irHash = await computeIRHash(irWithoutHash);
|
|
443
|
+
return {
|
|
444
|
+
...irWithoutHash,
|
|
445
|
+
provenance: { ...provenance, irHash },
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
transformModule(m) {
|
|
449
|
+
return {
|
|
450
|
+
name: m.name,
|
|
451
|
+
entities: m.entities.map(e => e.name),
|
|
452
|
+
enums: m.enums.map(e => e.name),
|
|
453
|
+
commands: [
|
|
454
|
+
...m.commands.map(c => c.name),
|
|
455
|
+
...m.entities.flatMap(e => e.commands.map(c => c.name)),
|
|
456
|
+
],
|
|
457
|
+
stores: m.stores.map(s => s.entity),
|
|
458
|
+
events: m.events.map(e => e.name), // Entity-scoped events emit parser warning
|
|
459
|
+
policies: [
|
|
460
|
+
...m.policies.map(p => p.name),
|
|
461
|
+
...m.entities.flatMap(e => e.policies.map(p => p.name)),
|
|
462
|
+
],
|
|
463
|
+
...((m.reactions && m.reactions.length > 0) ? { reactions: m.reactions.map(r => `${r.event}→${r.targetEntity}.${r.targetCommand}`) } : {}),
|
|
464
|
+
...((m.sagas && m.sagas.length > 0) ? { sagas: m.sagas.map(s => s.name) } : {}),
|
|
465
|
+
...((m.roles && m.roles.length > 0) ? { roles: m.roles.map(r => r.name) } : {}),
|
|
466
|
+
...((m.schedules && m.schedules.length > 0) ? { schedules: m.schedules.map(s => s.name) } : {}),
|
|
467
|
+
...((m.webhooks && m.webhooks.length > 0) ? { webhooks: m.webhooks.map(w => w.name) } : {}),
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
transformValueObject(v) {
|
|
471
|
+
return {
|
|
472
|
+
name: v.name,
|
|
473
|
+
properties: v.properties.map(p => this.transformProperty(p)),
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
transformTenant(t) {
|
|
477
|
+
return {
|
|
478
|
+
property: t.property,
|
|
479
|
+
type: this.transformType(t.dataType),
|
|
480
|
+
contextPath: t.contextPath,
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
transformEntity(e, moduleName) {
|
|
484
|
+
const constraints = e.constraints.map(c => this.transformConstraint(c));
|
|
485
|
+
this.validateConstraintCodeUniqueness(constraints, e.constraints, `entity '${e.name}'`);
|
|
486
|
+
// Separate default policies from regular policies
|
|
487
|
+
const defaultPolicies = e.policies.filter(p => p.isDefault).map(p => p.name);
|
|
488
|
+
const regularPolicies = e.policies.filter(p => !p.isDefault).map(p => p.name);
|
|
489
|
+
const properties = e.properties.map(p => this.transformProperty(p));
|
|
490
|
+
// Validate searchable modifier: only valid on string properties
|
|
491
|
+
for (const p of e.properties) {
|
|
492
|
+
if (p.modifiers.includes('searchable') && p.dataType.name !== 'string') {
|
|
493
|
+
this.emitDiagnostic('error', `Property '${p.name}' on entity '${e.name}': 'searchable' modifier is only valid on string properties (got '${p.dataType.name}').`);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
if (e.timestamps) {
|
|
497
|
+
const hasCreatedAt = properties.some(p => p.name === 'createdAt');
|
|
498
|
+
const hasUpdatedAt = properties.some(p => p.name === 'updatedAt');
|
|
499
|
+
if (!hasCreatedAt) {
|
|
500
|
+
properties.push({ name: 'createdAt', type: { name: 'datetime', nullable: false }, modifiers: ['readonly'] });
|
|
501
|
+
}
|
|
502
|
+
if (!hasUpdatedAt) {
|
|
503
|
+
properties.push({ name: 'updatedAt', type: { name: 'datetime', nullable: false }, modifiers: ['readonly'] });
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return {
|
|
507
|
+
name: e.name,
|
|
508
|
+
module: moduleName,
|
|
509
|
+
properties,
|
|
510
|
+
computedProperties: e.computedProperties.map(cp => this.transformComputedProperty(cp)),
|
|
511
|
+
relationships: e.relationships.map(r => this.transformRelationship(r)),
|
|
512
|
+
commands: [...(e.inheritedCommandNames || []), ...e.commands.map(c => c.name)],
|
|
513
|
+
constraints,
|
|
514
|
+
policies: regularPolicies,
|
|
515
|
+
...(e.parent ? { parent: e.parent } : {}),
|
|
516
|
+
...(e.mixins ? { mixins: e.mixins } : {}),
|
|
517
|
+
...(defaultPolicies.length > 0 ? { defaultPolicies } : {}),
|
|
518
|
+
...(e.key ? { key: e.key } : {}),
|
|
519
|
+
...(e.alternateKeys && e.alternateKeys.length > 0 ? { alternateKeys: e.alternateKeys } : {}),
|
|
520
|
+
versionProperty: e.versionProperty,
|
|
521
|
+
versionAtProperty: e.versionAtProperty,
|
|
522
|
+
...(e.timestamps ? { timestamps: true } : {}),
|
|
523
|
+
...(e.realtime ? { realtime: true } : {}),
|
|
524
|
+
...(e.external ? { external: true } : {}),
|
|
525
|
+
...(e.transitions.length > 0 ? { transitions: e.transitions.map(t => this.transformTransition(t)) } : {}),
|
|
526
|
+
...(e.approvals.length > 0 ? { approvals: e.approvals.map(a => this.transformApproval(a, e)) } : {}),
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
transformTransition(t) {
|
|
530
|
+
return {
|
|
531
|
+
property: t.property,
|
|
532
|
+
from: t.from,
|
|
533
|
+
to: t.to,
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
transformApproval(a, entity) {
|
|
537
|
+
// Validate: command must reference an existing command on this entity
|
|
538
|
+
const commandNames = entity.commands.map(c => c.name);
|
|
539
|
+
if (!commandNames.includes(a.command)) {
|
|
540
|
+
this.emitDiagnostic('error', `Approval '${a.name}' references command '${a.command}' which does not exist on entity '${entity.name}'. Available commands: ${commandNames.join(', ') || '(none)'}`, a.position?.line, a.position?.column);
|
|
541
|
+
}
|
|
542
|
+
// Validate: at least one stage required
|
|
543
|
+
if (a.stages.length === 0) {
|
|
544
|
+
this.emitDiagnostic('error', `Approval '${a.name}' must declare at least one stage`, a.position?.line, a.position?.column);
|
|
545
|
+
}
|
|
546
|
+
// Validate: stage names unique within this approval
|
|
547
|
+
const stageNames = new Set();
|
|
548
|
+
for (const s of a.stages) {
|
|
549
|
+
if (stageNames.has(s.name)) {
|
|
550
|
+
this.emitDiagnostic('error', `Duplicate stage name '${s.name}' in approval '${a.name}'`, s.position?.line, s.position?.column);
|
|
551
|
+
}
|
|
552
|
+
stageNames.add(s.name);
|
|
553
|
+
}
|
|
554
|
+
const node = {
|
|
555
|
+
name: a.name,
|
|
556
|
+
command: a.command,
|
|
557
|
+
stages: a.stages.map(s => this.transformApprovalStage(s)),
|
|
558
|
+
emits: a.emits,
|
|
559
|
+
};
|
|
560
|
+
if (a.timeout !== undefined)
|
|
561
|
+
node.timeout = a.timeout;
|
|
562
|
+
if (a.onTimeout !== undefined)
|
|
563
|
+
node.onTimeout = a.onTimeout;
|
|
564
|
+
return node;
|
|
565
|
+
}
|
|
566
|
+
transformApprovalStage(s) {
|
|
567
|
+
const node = {
|
|
568
|
+
name: s.name,
|
|
569
|
+
policy: this.transformExpression(s.policy),
|
|
570
|
+
required: s.required,
|
|
571
|
+
};
|
|
572
|
+
if (s.when)
|
|
573
|
+
node.when = this.transformExpression(s.when);
|
|
574
|
+
return node;
|
|
575
|
+
}
|
|
576
|
+
transformEnum(e, moduleName) {
|
|
577
|
+
return {
|
|
578
|
+
name: e.name,
|
|
579
|
+
module: moduleName,
|
|
580
|
+
values: e.values.map(v => ({
|
|
581
|
+
name: v.name,
|
|
582
|
+
...(v.label ? { label: v.label } : {}),
|
|
583
|
+
...(v.ordinal !== undefined ? { ordinal: v.ordinal } : {}),
|
|
584
|
+
})),
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
/** Nullary builtins recognized as a "current time on create" default. */
|
|
588
|
+
static AUTO_NOW_FNS = new Set(['now', 'today']);
|
|
589
|
+
transformProperty(p) {
|
|
590
|
+
const prop = {
|
|
591
|
+
name: p.name,
|
|
592
|
+
type: this.transformType(p.dataType),
|
|
593
|
+
defaultValue: p.defaultValue ? this.transformExprToValue(p.defaultValue) : undefined,
|
|
594
|
+
modifiers: p.modifiers,
|
|
595
|
+
};
|
|
596
|
+
// A default like `= now()` is a call expression — transformExprToValue can't
|
|
597
|
+
// represent it as a static IRValue, so it would otherwise be silently dropped
|
|
598
|
+
// (the original `createdAt must not be null` bug). Lower recognized current-time
|
|
599
|
+
// calls to `autoNow`; surface anything else instead of dropping it on the floor.
|
|
600
|
+
if (p.defaultValue && prop.defaultValue === undefined) {
|
|
601
|
+
const call = p.defaultValue;
|
|
602
|
+
const fn = call.type === 'Call' && call.callee?.type === 'Identifier' ? call.callee.name : undefined;
|
|
603
|
+
if (fn && IRCompiler.AUTO_NOW_FNS.has(fn) && (call.arguments?.length ?? 0) === 0) {
|
|
604
|
+
prop.autoNow = true;
|
|
605
|
+
}
|
|
606
|
+
else {
|
|
607
|
+
this.emitDiagnostic('warning', `Property '${p.name}': default expression is not a supported default and has no effect at runtime. Supported call defaults: ${[...IRCompiler.AUTO_NOW_FNS].map(f => `${f}()`).join(', ')}. Use a literal default or set the value in the command.`);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
// Invariant: 'masked' ∈ modifiers ⇔ maskStrategy present (bare masked ⇒ redact)
|
|
611
|
+
if (p.modifiers.includes('masked')) {
|
|
612
|
+
prop.maskStrategy = this.transformMaskStrategy(p);
|
|
613
|
+
}
|
|
614
|
+
return prop;
|
|
615
|
+
}
|
|
616
|
+
static MASK_STRATEGY_ARITY = {
|
|
617
|
+
redact: 0,
|
|
618
|
+
partial: 2,
|
|
619
|
+
email: 0,
|
|
620
|
+
phone: 0,
|
|
621
|
+
last4: 0,
|
|
622
|
+
};
|
|
623
|
+
transformMaskStrategy(p) {
|
|
624
|
+
const declared = p.maskStrategy ?? { type: 'redact' };
|
|
625
|
+
const known = Object.keys(IRCompiler.MASK_STRATEGY_ARITY);
|
|
626
|
+
if (!known.includes(declared.type)) {
|
|
627
|
+
this.emitDiagnostic('error', `Property '${p.name}': Unknown masking strategy '${declared.type}'. Known strategies: ${known.join(', ')}.`);
|
|
628
|
+
return { type: 'redact', ...(p.unmaskWhen ? { unmaskWhen: this.transformExpression(p.unmaskWhen) } : {}) };
|
|
629
|
+
}
|
|
630
|
+
const type = declared.type;
|
|
631
|
+
const params = declared.params ?? [];
|
|
632
|
+
const arity = IRCompiler.MASK_STRATEGY_ARITY[type];
|
|
633
|
+
if (params.length !== arity) {
|
|
634
|
+
if (arity === 0) {
|
|
635
|
+
this.emitDiagnostic('error', `Property '${p.name}': masking strategy '${type}' takes no parameters (got ${params.length}).`);
|
|
636
|
+
}
|
|
637
|
+
else {
|
|
638
|
+
this.emitDiagnostic('error', `Property '${p.name}': masking strategy '${type}' requires exactly ${arity} parameters (got ${params.length}).`);
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
else if (params.some(n => !Number.isInteger(n) || n < 0)) {
|
|
642
|
+
this.emitDiagnostic('error', `Property '${p.name}': masking strategy '${type}' parameters must be non-negative integers (got ${params.join(', ')}).`);
|
|
643
|
+
}
|
|
644
|
+
return {
|
|
645
|
+
type,
|
|
646
|
+
...(params.length > 0 ? { params } : {}),
|
|
647
|
+
...(p.unmaskWhen ? { unmaskWhen: this.transformExpression(p.unmaskWhen) } : {}),
|
|
648
|
+
};
|
|
649
|
+
}
|
|
650
|
+
transformComputedProperty(cp) {
|
|
651
|
+
const result = {
|
|
652
|
+
name: cp.name,
|
|
653
|
+
type: this.transformType(cp.dataType),
|
|
654
|
+
expression: this.transformExpression(cp.expression),
|
|
655
|
+
dependencies: cp.dependencies,
|
|
656
|
+
};
|
|
657
|
+
if (cp.cache) {
|
|
658
|
+
result.cache = { strategy: cp.cache.strategy };
|
|
659
|
+
if (cp.cache.ttlSeconds !== undefined) {
|
|
660
|
+
result.cache.ttlSeconds = cp.cache.ttlSeconds;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
return result;
|
|
664
|
+
}
|
|
665
|
+
transformRelationship(r) {
|
|
666
|
+
let foreignKey;
|
|
667
|
+
if (r.fields) {
|
|
668
|
+
foreignKey = { fields: r.fields };
|
|
669
|
+
if (r.references)
|
|
670
|
+
foreignKey.references = r.references;
|
|
671
|
+
}
|
|
672
|
+
return {
|
|
673
|
+
name: r.name,
|
|
674
|
+
kind: r.kind,
|
|
675
|
+
target: r.target,
|
|
676
|
+
...(foreignKey ? { foreignKey } : {}),
|
|
677
|
+
...(r.through ? { through: r.through } : {}),
|
|
678
|
+
...(r.onDelete ? { onDelete: r.onDelete } : {}),
|
|
679
|
+
...(r.onUpdate ? { onUpdate: r.onUpdate } : {}),
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
transformConstraint(c) {
|
|
683
|
+
return {
|
|
684
|
+
name: c.name,
|
|
685
|
+
code: c.code || c.name, // Default to name if code not specified
|
|
686
|
+
expression: this.transformExpression(c.expression),
|
|
687
|
+
severity: c.severity || 'block', // Default to block
|
|
688
|
+
message: c.message,
|
|
689
|
+
messageTemplate: c.messageTemplate,
|
|
690
|
+
detailsMapping: c.detailsMapping
|
|
691
|
+
? Object.fromEntries(Object.entries(c.detailsMapping).map(([k, v]) => [k, this.transformExpression(v)]))
|
|
692
|
+
: undefined,
|
|
693
|
+
overrideable: c.overrideable,
|
|
694
|
+
overridePolicyRef: c.overridePolicyRef,
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
/**
|
|
698
|
+
* Validate that constraint codes are unique within a scope (entity or command).
|
|
699
|
+
* Per spec (manifest-vnext.md, Constraint Blocks): "Within a single entity,
|
|
700
|
+
* code values MUST be unique. Within a single command's constraints array,
|
|
701
|
+
* code values MUST be unique. Compiler MUST emit diagnostic error on duplicates."
|
|
702
|
+
*
|
|
703
|
+
* Uses the AST nodes for source location (line/column) and IR constraints
|
|
704
|
+
* for the resolved code values (which default to name if not explicit).
|
|
705
|
+
*/
|
|
706
|
+
validateConstraintCodeUniqueness(irConstraints, astConstraints, scope) {
|
|
707
|
+
const seen = new Map(); // code → first occurrence index
|
|
708
|
+
for (let i = 0; i < irConstraints.length; i++) {
|
|
709
|
+
const code = irConstraints[i].code;
|
|
710
|
+
const firstIdx = seen.get(code);
|
|
711
|
+
if (firstIdx !== undefined) {
|
|
712
|
+
// Duplicate found — emit error at the duplicate's location
|
|
713
|
+
const astNode = astConstraints[i];
|
|
714
|
+
this.emitDiagnostic('error', `Duplicate constraint code '${code}' in ${scope}. First defined at constraint '${irConstraints[firstIdx].name}'.`, astNode.position?.line, astNode.position?.column);
|
|
715
|
+
}
|
|
716
|
+
else {
|
|
717
|
+
seen.set(code, i);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
transformStore(s) {
|
|
722
|
+
const config = {};
|
|
723
|
+
if (s.config) {
|
|
724
|
+
for (const [k, v] of Object.entries(s.config)) {
|
|
725
|
+
const val = this.transformExprToValue(v);
|
|
726
|
+
if (val)
|
|
727
|
+
config[k] = val;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
return {
|
|
731
|
+
entity: s.entity,
|
|
732
|
+
target: s.target,
|
|
733
|
+
config,
|
|
734
|
+
};
|
|
735
|
+
}
|
|
736
|
+
transformEvent(e) {
|
|
737
|
+
if ('fields' in e.payload) {
|
|
738
|
+
return {
|
|
739
|
+
name: e.name,
|
|
740
|
+
channel: e.channel,
|
|
741
|
+
payload: e.payload.fields.map(f => ({
|
|
742
|
+
name: f.name,
|
|
743
|
+
type: this.transformType(f.dataType),
|
|
744
|
+
required: f.required,
|
|
745
|
+
})),
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
return {
|
|
749
|
+
name: e.name,
|
|
750
|
+
channel: e.channel,
|
|
751
|
+
payload: this.transformType(e.payload),
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
transformReaction(r, moduleName, entityName) {
|
|
755
|
+
const params = r.params?.map(p => ({
|
|
756
|
+
name: p.name,
|
|
757
|
+
expression: this.transformExpression(p.expression),
|
|
758
|
+
}));
|
|
759
|
+
return {
|
|
760
|
+
event: r.event,
|
|
761
|
+
targetEntity: r.targetEntity,
|
|
762
|
+
targetCommand: r.targetCommand,
|
|
763
|
+
...(r.resolve ? { resolve: this.transformExpression(r.resolve) } : {}),
|
|
764
|
+
...(r.fanOut ? {
|
|
765
|
+
fanOut: {
|
|
766
|
+
matchField: r.fanOut.matchField,
|
|
767
|
+
matchSource: this.transformExpression(r.fanOut.matchSource),
|
|
768
|
+
},
|
|
769
|
+
} : {}),
|
|
770
|
+
...(params && params.length > 0 ? { params } : {}),
|
|
771
|
+
...(moduleName ? { module: moduleName } : {}),
|
|
772
|
+
...(entityName ? { entity: entityName } : {}),
|
|
773
|
+
};
|
|
774
|
+
}
|
|
775
|
+
transformSaga(s, moduleName) {
|
|
776
|
+
const steps = s.steps.map(step => ({
|
|
777
|
+
name: step.name,
|
|
778
|
+
commandEntity: step.commandEntity,
|
|
779
|
+
command: step.command,
|
|
780
|
+
...(step.compensate
|
|
781
|
+
? { compensateEntity: step.compensateEntity ?? step.commandEntity, compensate: step.compensate }
|
|
782
|
+
: {}),
|
|
783
|
+
}));
|
|
784
|
+
return {
|
|
785
|
+
name: s.name,
|
|
786
|
+
...(moduleName ? { module: moduleName } : {}),
|
|
787
|
+
steps,
|
|
788
|
+
onFailure: s.onFailure,
|
|
789
|
+
emits: s.emits,
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
transformWebhook(w, moduleName) {
|
|
793
|
+
const transform = w.transform?.map(p => ({
|
|
794
|
+
name: p.name,
|
|
795
|
+
expression: this.transformExpression(p.expression),
|
|
796
|
+
}));
|
|
797
|
+
let signature;
|
|
798
|
+
if (w.signature) {
|
|
799
|
+
signature = {
|
|
800
|
+
algorithm: w.signature.algorithm,
|
|
801
|
+
header: w.signature.header,
|
|
802
|
+
secret: w.signature.secret,
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
return {
|
|
806
|
+
name: w.name,
|
|
807
|
+
...(moduleName ? { module: moduleName } : {}),
|
|
808
|
+
path: w.path,
|
|
809
|
+
...(w.method ? { method: w.method } : {}),
|
|
810
|
+
command: w.command,
|
|
811
|
+
...(w.entity ? { entity: w.entity } : {}),
|
|
812
|
+
...(signature ? { signature } : {}),
|
|
813
|
+
...(w.idempotencyHeader ? { idempotencyHeader: w.idempotencyHeader } : {}),
|
|
814
|
+
...(transform && transform.length > 0 ? { transform } : {}),
|
|
815
|
+
};
|
|
816
|
+
}
|
|
817
|
+
transformCommand(c, moduleName, entityName, entityDefaultPolicies) {
|
|
818
|
+
const constraints = (c.constraints || []).map(con => this.transformConstraint(con));
|
|
819
|
+
if (c.constraints && c.constraints.length > 0) {
|
|
820
|
+
const scope = entityName ? `command '${entityName}.${c.name}'` : `command '${c.name}'`;
|
|
821
|
+
this.validateConstraintCodeUniqueness(constraints, c.constraints, scope);
|
|
822
|
+
}
|
|
823
|
+
// Expand entity default policies into command policies
|
|
824
|
+
// Per spec: commands without explicit policies inherit entity defaults
|
|
825
|
+
const commandPolicies = entityDefaultPolicies && entityDefaultPolicies.length > 0
|
|
826
|
+
? [...entityDefaultPolicies]
|
|
827
|
+
: undefined;
|
|
828
|
+
const cmd = {
|
|
829
|
+
name: c.name,
|
|
830
|
+
module: moduleName,
|
|
831
|
+
entity: entityName,
|
|
832
|
+
parameters: c.parameters.map(p => this.transformParameter(p)),
|
|
833
|
+
guards: (c.guards || []).map(g => this.transformExpression(g)),
|
|
834
|
+
constraints,
|
|
835
|
+
...(commandPolicies ? { policies: commandPolicies } : {}),
|
|
836
|
+
...(c.retry ? { retry: this.transformRetry(c.retry) } : {}),
|
|
837
|
+
...(c.rateLimit ? { rateLimit: this.transformRateLimit(c.rateLimit) } : {}),
|
|
838
|
+
actions: c.actions.map(a => this.transformAction(a)),
|
|
839
|
+
emits: c.emits || [],
|
|
840
|
+
...(c.emitPayloads && c.emitPayloads.length > 0
|
|
841
|
+
? {
|
|
842
|
+
emitPayloads: c.emitPayloads.map(ep => ({
|
|
843
|
+
eventName: ep.eventName,
|
|
844
|
+
fields: ep.payload.properties.map(p => ({
|
|
845
|
+
name: p.key,
|
|
846
|
+
expression: this.transformExpression(p.value),
|
|
847
|
+
})),
|
|
848
|
+
})),
|
|
849
|
+
}
|
|
850
|
+
: {}),
|
|
851
|
+
returns: c.returns ? this.transformType(c.returns) : undefined,
|
|
852
|
+
};
|
|
853
|
+
if (c.async) {
|
|
854
|
+
cmd.async = true;
|
|
855
|
+
cmd.completionEvent = `${c.name}Completed`;
|
|
856
|
+
cmd.failureEvent = `${c.name}Failed`;
|
|
857
|
+
}
|
|
858
|
+
return cmd;
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Reject guards/constraints that reference a computed property of the owning
|
|
862
|
+
* entity. Computed values are not materialized into the guard/constraint eval
|
|
863
|
+
* context, so such references silently resolve to `undefined` and produce wrong
|
|
864
|
+
* results. Detects both bare (`isRich`) and explicit (`self.isRich` /
|
|
865
|
+
* `this.isRich`) references. (G8)
|
|
866
|
+
*/
|
|
867
|
+
checkComputedRefsInGuardsAndConstraints(entity, moduleName) {
|
|
868
|
+
const computedNames = new Set(entity.computedProperties.map(c => c.name));
|
|
869
|
+
if (computedNames.size === 0)
|
|
870
|
+
return;
|
|
871
|
+
const qualified = moduleName ? `${moduleName}.${entity.name}` : entity.name;
|
|
872
|
+
const findComputedRef = (expr) => {
|
|
873
|
+
let found = null;
|
|
874
|
+
const walk = (e) => {
|
|
875
|
+
if (found)
|
|
876
|
+
return;
|
|
877
|
+
switch (e.type) {
|
|
878
|
+
case 'Identifier':
|
|
879
|
+
if (computedNames.has(e.name))
|
|
880
|
+
found = e.name;
|
|
881
|
+
break;
|
|
882
|
+
case 'MemberAccess':
|
|
883
|
+
if (e.object.type === 'Identifier' &&
|
|
884
|
+
(e.object.name === 'self' || e.object.name === 'this') &&
|
|
885
|
+
computedNames.has(e.property)) {
|
|
886
|
+
found = e.property;
|
|
887
|
+
}
|
|
888
|
+
else {
|
|
889
|
+
walk(e.object);
|
|
890
|
+
}
|
|
891
|
+
break;
|
|
892
|
+
case 'BinaryOp':
|
|
893
|
+
walk(e.left);
|
|
894
|
+
walk(e.right);
|
|
895
|
+
break;
|
|
896
|
+
case 'UnaryOp':
|
|
897
|
+
walk(e.operand);
|
|
898
|
+
break;
|
|
899
|
+
case 'Call':
|
|
900
|
+
walk(e.callee);
|
|
901
|
+
e.arguments.forEach(walk);
|
|
902
|
+
break;
|
|
903
|
+
case 'Conditional':
|
|
904
|
+
walk(e.condition);
|
|
905
|
+
walk(e.consequent);
|
|
906
|
+
walk(e.alternate);
|
|
907
|
+
break;
|
|
908
|
+
case 'Array':
|
|
909
|
+
e.elements.forEach(walk);
|
|
910
|
+
break;
|
|
911
|
+
case 'Object':
|
|
912
|
+
e.properties.forEach(p => walk(p.value));
|
|
913
|
+
break;
|
|
914
|
+
case 'Lambda':
|
|
915
|
+
walk(e.body);
|
|
916
|
+
break;
|
|
917
|
+
}
|
|
918
|
+
};
|
|
919
|
+
walk(expr);
|
|
920
|
+
return found;
|
|
921
|
+
};
|
|
922
|
+
for (const cmd of entity.commands) {
|
|
923
|
+
for (const guard of cmd.guards ?? []) {
|
|
924
|
+
const ref = findComputedRef(guard);
|
|
925
|
+
if (ref) {
|
|
926
|
+
this.emitDiagnostic('error', `Guard on command '${qualified}.${cmd.name}' references computed property '${ref}', which is not available during guard evaluation. Inline the formula or use a stored property.`);
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
for (const con of cmd.constraints ?? []) {
|
|
930
|
+
const ref = findComputedRef(con.expression);
|
|
931
|
+
if (ref) {
|
|
932
|
+
this.emitDiagnostic('error', `Constraint '${con.name}' on command '${qualified}.${cmd.name}' references computed property '${ref}', which is not available during constraint evaluation. Inline the formula or use a stored property.`);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
for (const con of entity.constraints) {
|
|
937
|
+
const ref = findComputedRef(con.expression);
|
|
938
|
+
if (ref) {
|
|
939
|
+
this.emitDiagnostic('error', `Constraint '${con.name}' on entity '${qualified}' references computed property '${ref}', which is not available during constraint evaluation. Inline the formula or use a stored property.`);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
/**
|
|
944
|
+
* Flag `create` commands that leave a storage-required field unset. The runtime
|
|
945
|
+
* treats a command literally named `create` as instance creation
|
|
946
|
+
* (`commandName === 'create'`), and persists every non-null property — so a
|
|
947
|
+
* non-null, default-less property the command never sets becomes an explicit
|
|
948
|
+
* `null` write that the store rejects. That failure only ever surfaced at
|
|
949
|
+
* runtime against a real DB; this surfaces it as a compile-time warning
|
|
950
|
+
* (warning, not error, because the runtime also merges arbitrary caller input
|
|
951
|
+
* on create, so the field is not *provably* unset).
|
|
952
|
+
*
|
|
953
|
+
* Excluded (supplied by the runtime/store, not the command body): `id`,
|
|
954
|
+
* composite-key columns, relationship foreign keys, the tenant property,
|
|
955
|
+
* optimistic-concurrency version fields, and auto timestamps. Properties with a
|
|
956
|
+
* literal default or `autoNow` are already covered.
|
|
957
|
+
*/
|
|
958
|
+
/**
|
|
959
|
+
* Types the runtime fills with a non-null zero value when a create command
|
|
960
|
+
* leaves them unset (mirrors `getDefaultForType` in the runtime engine). Every
|
|
961
|
+
* other non-null type fills with `null`, which a non-null store column rejects —
|
|
962
|
+
* those are the only guaranteed-failure cases this check flags.
|
|
963
|
+
*/
|
|
964
|
+
static ZERO_FILLABLE_TYPES = new Set(['string', 'number', 'boolean', 'list', 'array', 'map']);
|
|
965
|
+
checkRequiredFieldsSetOnCreate(entities, commands, tenant) {
|
|
966
|
+
for (const entity of entities) {
|
|
967
|
+
const createCmd = commands.find(c => c.name === 'create' && c.entity === entity.name && c.module === entity.module);
|
|
968
|
+
if (!createCmd)
|
|
969
|
+
continue;
|
|
970
|
+
// Fields the command itself produces.
|
|
971
|
+
const produced = new Set();
|
|
972
|
+
for (const a of createCmd.actions) {
|
|
973
|
+
if (a.target && (a.kind === 'mutate' || a.kind === 'compute' || a.kind === 'persist')) {
|
|
974
|
+
produced.add(a.target);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
// Fields supplied/managed outside the command body.
|
|
978
|
+
const auto = new Set(['id']);
|
|
979
|
+
if (tenant?.property)
|
|
980
|
+
auto.add(tenant.property);
|
|
981
|
+
if (entity.versionProperty)
|
|
982
|
+
auto.add(entity.versionProperty);
|
|
983
|
+
if (entity.versionAtProperty)
|
|
984
|
+
auto.add(entity.versionAtProperty);
|
|
985
|
+
if (entity.timestamps) {
|
|
986
|
+
auto.add('createdAt');
|
|
987
|
+
auto.add('updatedAt');
|
|
988
|
+
}
|
|
989
|
+
for (const k of entity.key ?? [])
|
|
990
|
+
auto.add(k);
|
|
991
|
+
for (const r of entity.relationships) {
|
|
992
|
+
for (const fk of r.foreignKey?.fields ?? [])
|
|
993
|
+
auto.add(fk);
|
|
994
|
+
}
|
|
995
|
+
const qualified = entity.module ? `${entity.module}.${entity.name}` : entity.name;
|
|
996
|
+
for (const prop of entity.properties) {
|
|
997
|
+
if (prop.type.nullable)
|
|
998
|
+
continue; // nullable column: a null write is legal
|
|
999
|
+
// Types the runtime zero-fills (string→"", number→0, …) persist fine even
|
|
1000
|
+
// when unset; only types that fill with null are guaranteed to fail.
|
|
1001
|
+
if (IRCompiler.ZERO_FILLABLE_TYPES.has(prop.type.name))
|
|
1002
|
+
continue;
|
|
1003
|
+
if (prop.defaultValue !== undefined)
|
|
1004
|
+
continue;
|
|
1005
|
+
if (prop.autoNow)
|
|
1006
|
+
continue;
|
|
1007
|
+
if (auto.has(prop.name))
|
|
1008
|
+
continue;
|
|
1009
|
+
if (produced.has(prop.name))
|
|
1010
|
+
continue;
|
|
1011
|
+
// Warning, not error: the runtime merges caller-supplied input on create,
|
|
1012
|
+
// so the compiler cannot *prove* the field is unset — but a non-null field
|
|
1013
|
+
// with no default that the command body never sets is the exact shape that
|
|
1014
|
+
// persists `null` and is rejected by a non-null store column (the
|
|
1015
|
+
// `createdAt must not be null` class). Surfaces in the IDE/LSP and validate.
|
|
1016
|
+
this.emitDiagnostic('warning', `Command '${qualified}.create' creates '${entity.name}' but never sets non-null field '${prop.name}' (type '${prop.type.name}', no default). If no caller supplies it, persisting writes null and a non-null store column rejects it. Add 'mutate ${prop.name} = ...', give '${prop.name}' a default (e.g. '= now()'), or make it optional ('${prop.name}: ${prop.type.name}?').`);
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
/**
|
|
1021
|
+
* Flag duplicate event names — two declarations of the same event name collide in
|
|
1022
|
+
* the event registry (one shadows the other). Warning, not error: surfaces in the
|
|
1023
|
+
* IDE/lint without breaking a build.
|
|
1024
|
+
*
|
|
1025
|
+
* Deliberately NOT checked: event-never-emitted (events are routinely emitted by
|
|
1026
|
+
* reactions and hand-written runtime middleware the compiler cannot see) and
|
|
1027
|
+
* mutate-to-undeclared-field (the runtime supports dynamic instance fields, so such
|
|
1028
|
+
* a write is valid, not a no-op — it is a lint smell, not a guaranteed error).
|
|
1029
|
+
*/
|
|
1030
|
+
checkEventDeclarations(events) {
|
|
1031
|
+
const seen = new Set();
|
|
1032
|
+
for (const e of events) {
|
|
1033
|
+
if (seen.has(e.name)) {
|
|
1034
|
+
this.emitDiagnostic('warning', `Duplicate event name '${e.name}': declared more than once, so one declaration shadows the other in the event registry. Rename one.`);
|
|
1035
|
+
}
|
|
1036
|
+
seen.add(e.name);
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
transformParameter(p) {
|
|
1040
|
+
return {
|
|
1041
|
+
name: p.name,
|
|
1042
|
+
type: this.transformType(p.dataType),
|
|
1043
|
+
required: p.required,
|
|
1044
|
+
defaultValue: p.defaultValue ? this.transformExprToValue(p.defaultValue) : undefined,
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
transformAction(a) {
|
|
1048
|
+
return {
|
|
1049
|
+
kind: a.kind,
|
|
1050
|
+
target: a.target,
|
|
1051
|
+
expression: this.transformExpression(a.expression),
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
1054
|
+
transformPolicy(p, moduleName, entityName) {
|
|
1055
|
+
return {
|
|
1056
|
+
name: p.name,
|
|
1057
|
+
module: moduleName,
|
|
1058
|
+
entity: entityName,
|
|
1059
|
+
action: p.action,
|
|
1060
|
+
expression: this.transformExpression(p.expression),
|
|
1061
|
+
...(p.rateLimit ? { rateLimit: this.transformRateLimit(p.rateLimit) } : {}),
|
|
1062
|
+
message: p.message,
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
transformRole(r, moduleName) {
|
|
1066
|
+
const sortPerm = (a, b) => {
|
|
1067
|
+
const ac = a.action.localeCompare(b.action);
|
|
1068
|
+
if (ac !== 0)
|
|
1069
|
+
return ac;
|
|
1070
|
+
return (a.target ?? '').localeCompare(b.target ?? '');
|
|
1071
|
+
};
|
|
1072
|
+
const allow = r.permissions
|
|
1073
|
+
.filter(p => p.kind === 'allow')
|
|
1074
|
+
.map(p => ({ action: p.action, ...(p.target ? { target: p.target } : {}) }))
|
|
1075
|
+
.sort(sortPerm);
|
|
1076
|
+
const deny = r.permissions
|
|
1077
|
+
.filter(p => p.kind === 'deny')
|
|
1078
|
+
.map(p => ({ action: p.action, ...(p.target ? { target: p.target } : {}) }))
|
|
1079
|
+
.sort(sortPerm);
|
|
1080
|
+
return {
|
|
1081
|
+
name: r.name,
|
|
1082
|
+
...(moduleName ? { module: moduleName } : {}),
|
|
1083
|
+
...(r.parent ? { parent: r.parent } : {}),
|
|
1084
|
+
allow,
|
|
1085
|
+
deny,
|
|
1086
|
+
effectivePermissions: [], // filled in by resolveRoleGraph
|
|
1087
|
+
};
|
|
1088
|
+
}
|
|
1089
|
+
/**
|
|
1090
|
+
* Resolve the role inheritance graph:
|
|
1091
|
+
* 1. Validate: no duplicate names, no unknown parents, no cycles
|
|
1092
|
+
* 2. Flatten inheritance: root-first union of allows
|
|
1093
|
+
* 3. Apply deny: any (action, target) that appears in ANY level's deny is removed
|
|
1094
|
+
* 4. Sort roles by name for deterministic output
|
|
1095
|
+
*/
|
|
1096
|
+
resolveRoleGraph(roles) {
|
|
1097
|
+
if (roles.length === 0)
|
|
1098
|
+
return [];
|
|
1099
|
+
const byName = new Map();
|
|
1100
|
+
for (const role of roles) {
|
|
1101
|
+
if (byName.has(role.name)) {
|
|
1102
|
+
this.emitDiagnostic('error', `Duplicate role declaration '${role.name}'`);
|
|
1103
|
+
continue;
|
|
1104
|
+
}
|
|
1105
|
+
byName.set(role.name, role);
|
|
1106
|
+
}
|
|
1107
|
+
// Validate parents exist
|
|
1108
|
+
for (const role of roles) {
|
|
1109
|
+
if (role.parent && !byName.has(role.parent)) {
|
|
1110
|
+
this.emitDiagnostic('error', `Role '${role.name}' extends unknown role '${role.parent}'`);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
// Cycle detection via DFS coloring
|
|
1114
|
+
const WHITE = 0, GRAY = 1, BLACK = 2;
|
|
1115
|
+
const color = new Map();
|
|
1116
|
+
for (const name of byName.keys())
|
|
1117
|
+
color.set(name, WHITE);
|
|
1118
|
+
const hasCycle = (name, path) => {
|
|
1119
|
+
color.set(name, GRAY);
|
|
1120
|
+
path.push(name);
|
|
1121
|
+
const role = byName.get(name);
|
|
1122
|
+
if (role?.parent) {
|
|
1123
|
+
const parentColor = color.get(role.parent);
|
|
1124
|
+
if (parentColor === GRAY) {
|
|
1125
|
+
this.emitDiagnostic('error', `Role cycle detected: ${[...path, role.parent].join(' -> ')}`);
|
|
1126
|
+
return true;
|
|
1127
|
+
}
|
|
1128
|
+
if (parentColor === WHITE && hasCycle(role.parent, path)) {
|
|
1129
|
+
return true;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
color.set(name, BLACK);
|
|
1133
|
+
path.pop();
|
|
1134
|
+
return false;
|
|
1135
|
+
};
|
|
1136
|
+
for (const name of byName.keys()) {
|
|
1137
|
+
if (color.get(name) === WHITE) {
|
|
1138
|
+
if (hasCycle(name, []))
|
|
1139
|
+
break;
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
// Compute effective permissions for each role
|
|
1143
|
+
const computeEffective = (roleName, visited) => {
|
|
1144
|
+
if (visited.has(roleName))
|
|
1145
|
+
return []; // cycle guard
|
|
1146
|
+
visited.add(roleName);
|
|
1147
|
+
const role = byName.get(roleName);
|
|
1148
|
+
if (!role)
|
|
1149
|
+
return [];
|
|
1150
|
+
// Start with parent's effective permissions (root-first)
|
|
1151
|
+
let effective = [];
|
|
1152
|
+
if (role.parent) {
|
|
1153
|
+
effective = [...computeEffective(role.parent, visited)];
|
|
1154
|
+
}
|
|
1155
|
+
// Union with this role's allows
|
|
1156
|
+
for (const a of role.allow) {
|
|
1157
|
+
const exists = effective.some(e => e.action === a.action && (e.target ?? '') === (a.target ?? ''));
|
|
1158
|
+
if (!exists)
|
|
1159
|
+
effective.push({ ...a });
|
|
1160
|
+
}
|
|
1161
|
+
// Collect all deny entries from the full chain
|
|
1162
|
+
const allDenies = [...role.deny];
|
|
1163
|
+
if (role.parent) {
|
|
1164
|
+
const collectDenies = (name, seen) => {
|
|
1165
|
+
if (seen.has(name))
|
|
1166
|
+
return [];
|
|
1167
|
+
seen.add(name);
|
|
1168
|
+
const r = byName.get(name);
|
|
1169
|
+
if (!r)
|
|
1170
|
+
return [];
|
|
1171
|
+
const parentDenies = r.parent ? collectDenies(r.parent, seen) : [];
|
|
1172
|
+
return [...parentDenies, ...r.deny];
|
|
1173
|
+
};
|
|
1174
|
+
allDenies.push(...collectDenies(role.parent, new Set()));
|
|
1175
|
+
}
|
|
1176
|
+
// Apply deny: remove any permission matching a deny entry
|
|
1177
|
+
// 'all' action in deny removes all permissions for that target scope
|
|
1178
|
+
effective = effective.filter(perm => {
|
|
1179
|
+
return !allDenies.some(d => {
|
|
1180
|
+
const actionMatch = d.action === 'all' || d.action === perm.action;
|
|
1181
|
+
const targetMatch = d.target === undefined || d.target === perm.target;
|
|
1182
|
+
return actionMatch && targetMatch;
|
|
1183
|
+
});
|
|
1184
|
+
});
|
|
1185
|
+
// Expand 'all' action in allows: if effective has an 'all' permission,
|
|
1186
|
+
// it means any action check should match (handled at runtime)
|
|
1187
|
+
// Keep 'all' as-is in effectivePermissions — runtime handles matching
|
|
1188
|
+
const sortPerm = (a, b) => {
|
|
1189
|
+
const ac = a.action.localeCompare(b.action);
|
|
1190
|
+
if (ac !== 0)
|
|
1191
|
+
return ac;
|
|
1192
|
+
return (a.target ?? '').localeCompare(b.target ?? '');
|
|
1193
|
+
};
|
|
1194
|
+
return effective.sort(sortPerm);
|
|
1195
|
+
};
|
|
1196
|
+
for (const role of byName.values()) {
|
|
1197
|
+
role.effectivePermissions = computeEffective(role.name, new Set());
|
|
1198
|
+
}
|
|
1199
|
+
// Sort roles by name for deterministic output
|
|
1200
|
+
return Array.from(byName.values()).sort((a, b) => a.name.localeCompare(b.name));
|
|
1201
|
+
}
|
|
1202
|
+
transformType(t) {
|
|
1203
|
+
return {
|
|
1204
|
+
name: t.name,
|
|
1205
|
+
generic: t.generic ? this.transformType(t.generic) : undefined,
|
|
1206
|
+
nullable: t.nullable,
|
|
1207
|
+
...(t.params ? { params: t.params } : {}),
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
transformExpression(expr) {
|
|
1211
|
+
switch (expr.type) {
|
|
1212
|
+
case 'Literal': {
|
|
1213
|
+
const lit = expr;
|
|
1214
|
+
return {
|
|
1215
|
+
kind: 'literal',
|
|
1216
|
+
value: this.literalToValue(lit.value, lit.dataType),
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
1219
|
+
case 'Identifier': {
|
|
1220
|
+
return { kind: 'identifier', name: expr.name };
|
|
1221
|
+
}
|
|
1222
|
+
case 'MemberAccess': {
|
|
1223
|
+
const ma = expr;
|
|
1224
|
+
return {
|
|
1225
|
+
kind: 'member',
|
|
1226
|
+
object: this.transformExpression(ma.object),
|
|
1227
|
+
property: ma.property,
|
|
1228
|
+
};
|
|
1229
|
+
}
|
|
1230
|
+
case 'BinaryOp': {
|
|
1231
|
+
const bo = expr;
|
|
1232
|
+
return {
|
|
1233
|
+
kind: 'binary',
|
|
1234
|
+
operator: bo.operator,
|
|
1235
|
+
left: this.transformExpression(bo.left),
|
|
1236
|
+
right: this.transformExpression(bo.right),
|
|
1237
|
+
};
|
|
1238
|
+
}
|
|
1239
|
+
case 'UnaryOp': {
|
|
1240
|
+
const uo = expr;
|
|
1241
|
+
return {
|
|
1242
|
+
kind: 'unary',
|
|
1243
|
+
operator: uo.operator,
|
|
1244
|
+
operand: this.transformExpression(uo.operand),
|
|
1245
|
+
};
|
|
1246
|
+
}
|
|
1247
|
+
case 'Call': {
|
|
1248
|
+
const call = expr;
|
|
1249
|
+
const irCall = {
|
|
1250
|
+
kind: 'call',
|
|
1251
|
+
callee: this.transformExpression(call.callee),
|
|
1252
|
+
args: call.arguments.map(a => this.transformExpression(a)),
|
|
1253
|
+
};
|
|
1254
|
+
// Compile-time regex validation for matches(value, pattern)
|
|
1255
|
+
if (irCall.kind === 'call' &&
|
|
1256
|
+
irCall.callee.kind === 'identifier' &&
|
|
1257
|
+
irCall.callee.name === 'matches' &&
|
|
1258
|
+
irCall.args.length >= 2) {
|
|
1259
|
+
const patternArg = irCall.args[1];
|
|
1260
|
+
if (patternArg.kind === 'literal' && patternArg.value?.kind === 'string') {
|
|
1261
|
+
try {
|
|
1262
|
+
new RegExp(patternArg.value.value);
|
|
1263
|
+
}
|
|
1264
|
+
catch {
|
|
1265
|
+
this.emitDiagnostic('error', `Invalid regex pattern in matches(): "${patternArg.value.value}"`, call.position?.line, call.position?.column);
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
return irCall;
|
|
1270
|
+
}
|
|
1271
|
+
case 'Conditional': {
|
|
1272
|
+
const cond = expr;
|
|
1273
|
+
return {
|
|
1274
|
+
kind: 'conditional',
|
|
1275
|
+
condition: this.transformExpression(cond.condition),
|
|
1276
|
+
consequent: this.transformExpression(cond.consequent),
|
|
1277
|
+
alternate: this.transformExpression(cond.alternate),
|
|
1278
|
+
};
|
|
1279
|
+
}
|
|
1280
|
+
case 'Array': {
|
|
1281
|
+
const arr = expr;
|
|
1282
|
+
return {
|
|
1283
|
+
kind: 'array',
|
|
1284
|
+
elements: arr.elements.map(e => this.transformExpression(e)),
|
|
1285
|
+
};
|
|
1286
|
+
}
|
|
1287
|
+
case 'Object': {
|
|
1288
|
+
const obj = expr;
|
|
1289
|
+
return {
|
|
1290
|
+
kind: 'object',
|
|
1291
|
+
properties: obj.properties.map(p => ({
|
|
1292
|
+
key: p.key,
|
|
1293
|
+
value: this.transformExpression(p.value),
|
|
1294
|
+
})),
|
|
1295
|
+
};
|
|
1296
|
+
}
|
|
1297
|
+
case 'Lambda': {
|
|
1298
|
+
const lam = expr;
|
|
1299
|
+
return {
|
|
1300
|
+
kind: 'lambda',
|
|
1301
|
+
params: lam.parameters,
|
|
1302
|
+
body: this.transformExpression(lam.body),
|
|
1303
|
+
};
|
|
1304
|
+
}
|
|
1305
|
+
case 'AggregateCount': {
|
|
1306
|
+
const ac = expr;
|
|
1307
|
+
return {
|
|
1308
|
+
kind: 'aggregate',
|
|
1309
|
+
op: 'count',
|
|
1310
|
+
entity: ac.entity,
|
|
1311
|
+
predicates: ac.predicates.map(p => ({
|
|
1312
|
+
field: p.field,
|
|
1313
|
+
value: this.transformExpression(p.value),
|
|
1314
|
+
})),
|
|
1315
|
+
};
|
|
1316
|
+
}
|
|
1317
|
+
default:
|
|
1318
|
+
return { kind: 'literal', value: { kind: 'null' } };
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
transformExprToValue(expr) {
|
|
1322
|
+
if (expr.type === 'Identifier') {
|
|
1323
|
+
// Enum member defaults (e.g. `property status: Status = draft`) lower to string IRValues.
|
|
1324
|
+
return { kind: 'string', value: expr.name };
|
|
1325
|
+
}
|
|
1326
|
+
if (expr.type === 'Literal') {
|
|
1327
|
+
const lit = expr;
|
|
1328
|
+
return this.literalToValue(lit.value, lit.dataType);
|
|
1329
|
+
}
|
|
1330
|
+
// Negative/positive numeric literal defaults (e.g. `= -1`) parse as a unary op
|
|
1331
|
+
// over a number literal; fold them so the default is a real static value.
|
|
1332
|
+
if (expr.type === 'UnaryOp') {
|
|
1333
|
+
const u = expr;
|
|
1334
|
+
const inner = this.transformExprToValue(u.operand);
|
|
1335
|
+
if (inner?.kind === 'number' && (u.operator === '-' || u.operator === '+')) {
|
|
1336
|
+
return { kind: 'number', value: u.operator === '-' ? -inner.value : inner.value };
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
if (expr.type === 'Array') {
|
|
1340
|
+
const arr = expr;
|
|
1341
|
+
const elements = arr.elements.map(e => this.transformExprToValue(e)).filter((v) => v !== undefined);
|
|
1342
|
+
return { kind: 'array', elements };
|
|
1343
|
+
}
|
|
1344
|
+
if (expr.type === 'Object') {
|
|
1345
|
+
const obj = expr;
|
|
1346
|
+
const properties = {};
|
|
1347
|
+
for (const p of obj.properties) {
|
|
1348
|
+
const v = this.transformExprToValue(p.value);
|
|
1349
|
+
if (v)
|
|
1350
|
+
properties[p.key] = v;
|
|
1351
|
+
}
|
|
1352
|
+
return { kind: 'object', properties };
|
|
1353
|
+
}
|
|
1354
|
+
return undefined;
|
|
1355
|
+
}
|
|
1356
|
+
literalToValue(value, dataType) {
|
|
1357
|
+
if (dataType === 'string')
|
|
1358
|
+
return { kind: 'string', value: value };
|
|
1359
|
+
if (dataType === 'number')
|
|
1360
|
+
return { kind: 'number', value: value };
|
|
1361
|
+
if (dataType === 'boolean')
|
|
1362
|
+
return { kind: 'boolean', value: value };
|
|
1363
|
+
return { kind: 'null' };
|
|
1364
|
+
}
|
|
1365
|
+
transformRetry(r) {
|
|
1366
|
+
const maxAttempts = r.maxAttempts ?? 1;
|
|
1367
|
+
const backoff = r.backoff ?? 'fixed';
|
|
1368
|
+
const delayMs = r.delayMs ?? r.delay ?? 0;
|
|
1369
|
+
const jitter = typeof r.jitter === 'boolean' ? r.jitter : r.jitter !== undefined ? true : undefined;
|
|
1370
|
+
const retryOn = r.retryOn ? [...new Set(r.retryOn)] : undefined;
|
|
1371
|
+
if (maxAttempts < 1) {
|
|
1372
|
+
this.emitDiagnostic('error', `Retry maxAttempts must be >= 1, got ${maxAttempts}`);
|
|
1373
|
+
}
|
|
1374
|
+
if (delayMs < 0) {
|
|
1375
|
+
this.emitDiagnostic('error', `Retry delay must be >= 0, got ${delayMs}`);
|
|
1376
|
+
}
|
|
1377
|
+
if (retryOn && retryOn.length < 1) {
|
|
1378
|
+
this.emitDiagnostic('error', 'Retry retryOn must list at least one error code');
|
|
1379
|
+
}
|
|
1380
|
+
return {
|
|
1381
|
+
maxAttempts,
|
|
1382
|
+
backoff,
|
|
1383
|
+
delayMs,
|
|
1384
|
+
...(jitter !== undefined ? { jitter } : {}),
|
|
1385
|
+
...(retryOn && retryOn.length > 0 ? { retryOn } : {}),
|
|
1386
|
+
};
|
|
1387
|
+
}
|
|
1388
|
+
transformRateLimit(rl) {
|
|
1389
|
+
const maxRequests = rl.maxRequests ?? 100;
|
|
1390
|
+
const windowMs = this.parseWindowDuration(rl.windowMs);
|
|
1391
|
+
const scope = rl.scope ?? 'global';
|
|
1392
|
+
const burst = rl.burstAllowance;
|
|
1393
|
+
if (maxRequests < 1) {
|
|
1394
|
+
this.emitDiagnostic('error', `RateLimit maxRequests must be >= 1, got ${maxRequests}`);
|
|
1395
|
+
}
|
|
1396
|
+
if (windowMs < 1) {
|
|
1397
|
+
this.emitDiagnostic('error', `RateLimit window must be >= 1ms`);
|
|
1398
|
+
}
|
|
1399
|
+
if (!['user', 'tenant', 'global'].includes(scope)) {
|
|
1400
|
+
this.emitDiagnostic('error', `RateLimit scope must be 'user', 'tenant', or 'global', got '${scope}'`);
|
|
1401
|
+
}
|
|
1402
|
+
return {
|
|
1403
|
+
maxRequests,
|
|
1404
|
+
windowMs,
|
|
1405
|
+
scope,
|
|
1406
|
+
...(burst !== undefined && burst >= 0 ? { burstAllowance: burst } : {}),
|
|
1407
|
+
};
|
|
1408
|
+
}
|
|
1409
|
+
parseWindowDuration(windowMs) {
|
|
1410
|
+
if (windowMs === undefined)
|
|
1411
|
+
return 60000; // Default 60 seconds
|
|
1412
|
+
if (typeof windowMs === 'number')
|
|
1413
|
+
return windowMs;
|
|
1414
|
+
try {
|
|
1415
|
+
return parseDurationToMs(windowMs);
|
|
1416
|
+
}
|
|
1417
|
+
catch (e) {
|
|
1418
|
+
this.emitDiagnostic('error', `Invalid rateLimit window duration: ${e instanceof Error ? e.message : String(e)}`);
|
|
1419
|
+
return 60000;
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
transformSchedule(s) {
|
|
1423
|
+
// Validate schedule type
|
|
1424
|
+
if (!['cron', 'interval', 'every'].includes(s.scheduleType)) {
|
|
1425
|
+
this.emitDiagnostic('error', `Invalid schedule type '${s.scheduleType}', must be 'cron', 'interval', or 'every'`);
|
|
1426
|
+
}
|
|
1427
|
+
const trigger = this.transformTrigger(s);
|
|
1428
|
+
const params = [];
|
|
1429
|
+
if (s.parameters) {
|
|
1430
|
+
for (const [name, expr] of Object.entries(s.parameters)) {
|
|
1431
|
+
params.push({ name, expression: this.transformExpression(expr) });
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
return {
|
|
1435
|
+
name: s.name,
|
|
1436
|
+
...(s.targetEntity ? { entityName: s.targetEntity } : {}),
|
|
1437
|
+
commandName: s.targetCommand,
|
|
1438
|
+
trigger,
|
|
1439
|
+
...(params.length > 0 ? { params } : {}),
|
|
1440
|
+
};
|
|
1441
|
+
}
|
|
1442
|
+
transformTrigger(s) {
|
|
1443
|
+
if (s.scheduleType === 'cron') {
|
|
1444
|
+
const cronExpr = s.cronExpression;
|
|
1445
|
+
if (!cronExpr) {
|
|
1446
|
+
this.emitDiagnostic('error', `Cron schedule '${s.name}' missing cronExpression`);
|
|
1447
|
+
return { kind: 'cron', cron: '0 0 * * *' };
|
|
1448
|
+
}
|
|
1449
|
+
if (!isValidCronExpression(cronExpr)) {
|
|
1450
|
+
this.emitDiagnostic('error', `Invalid cron expression '${cronExpr}' in schedule '${s.name}' (expected 5 fields: minute hour day month dayOfWeek)`);
|
|
1451
|
+
}
|
|
1452
|
+
return { kind: 'cron', cron: cronExpr };
|
|
1453
|
+
}
|
|
1454
|
+
if (s.scheduleType === 'interval' || s.scheduleType === 'every') {
|
|
1455
|
+
try {
|
|
1456
|
+
const durationMs = s.intervalDuration
|
|
1457
|
+
? parseDurationToMs(s.intervalDuration)
|
|
1458
|
+
: s.value !== undefined
|
|
1459
|
+
? parseDurationToMs(s.value, s.unit)
|
|
1460
|
+
: (() => { throw new Error('missing duration'); })();
|
|
1461
|
+
return { kind: s.scheduleType, durationMs };
|
|
1462
|
+
}
|
|
1463
|
+
catch (e) {
|
|
1464
|
+
this.emitDiagnostic('error', `Invalid ${s.scheduleType} duration in schedule '${s.name}': ${e instanceof Error ? e.message : String(e)}`);
|
|
1465
|
+
return { kind: s.scheduleType, durationMs: 60000 };
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
return { kind: 'cron', cron: '0 0 * * *' };
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
export async function compileToIR(source, options) {
|
|
1472
|
+
const compiler = new IRCompiler();
|
|
1473
|
+
return compiler.compileToIR(source, options);
|
|
1474
|
+
}
|
|
1475
|
+
export { checkDomainCompleteness, resolveEntityForFkField } from './domain-completeness.js';
|
|
1476
|
+
export { checkReactionCompleteness } from './reaction-completeness.js';
|
|
1477
|
+
//# sourceMappingURL=ir-compiler.js.map
|