@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,1339 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Next.js App Router projection for Manifest IR.
|
|
3
|
+
*
|
|
4
|
+
* Generates Next.js API route handlers using App Router conventions.
|
|
5
|
+
* Configurable for different auth providers and database setups.
|
|
6
|
+
*/
|
|
7
|
+
import { NEXTJS_DEFAULTS, DEFAULT_TENANT_PROVIDER, DISPATCHER_DEFAULTS, CONCRETE_COMMAND_ROUTES_DEFAULTS, READ_ROUTES_DEFAULTS, } from './defaults.js';
|
|
8
|
+
import { resolveTableName } from '../shared/naming.js';
|
|
9
|
+
import { generateScheduleCronRoutes } from './schedule-generator.js';
|
|
10
|
+
/**
|
|
11
|
+
* Re-export the canonical defaults so consumers of
|
|
12
|
+
* `@angriff36/manifest/projections/nextjs` get the defaults from the same
|
|
13
|
+
* entry point as the projection class. Anything that needs to render or
|
|
14
|
+
* snapshot the defaults (CLI inspect, tests, downstream tooling) must use
|
|
15
|
+
* these names, not redeclare them.
|
|
16
|
+
*/
|
|
17
|
+
export { NEXTJS_DEFAULTS, DEFAULT_TENANT_PROVIDER, DISPATCHER_DEFAULTS, CONCRETE_COMMAND_ROUTES_DEFAULTS, READ_ROUTES_DEFAULTS, ROUTES_DEFAULTS, getManifestDefaultsSnapshot, } from './defaults.js';
|
|
18
|
+
/**
|
|
19
|
+
* Normalize user options with defaults from `./defaults`.
|
|
20
|
+
*
|
|
21
|
+
* Defaults are imported (not redeclared) so the projection, the CLI's
|
|
22
|
+
* `manifest config print-defaults`, and the JSON schema all agree.
|
|
23
|
+
*/
|
|
24
|
+
function normalizeOptions(options) {
|
|
25
|
+
const dispatcher = {
|
|
26
|
+
enabled: options?.dispatcher?.enabled ?? DISPATCHER_DEFAULTS.enabled,
|
|
27
|
+
executionMode: options?.dispatcher?.executionMode ?? DISPATCHER_DEFAULTS.executionMode,
|
|
28
|
+
executorImportPath: options?.dispatcher?.executorImportPath ?? DISPATCHER_DEFAULTS.executorImportPath,
|
|
29
|
+
executorImportName: options?.dispatcher?.executorImportName ?? DISPATCHER_DEFAULTS.executorImportName,
|
|
30
|
+
deriveInstanceId: options?.dispatcher?.deriveInstanceId ?? DISPATCHER_DEFAULTS.deriveInstanceId,
|
|
31
|
+
path: options?.dispatcher?.path ?? DISPATCHER_DEFAULTS.path,
|
|
32
|
+
};
|
|
33
|
+
const concreteCommandRoutes = {
|
|
34
|
+
enabled: options?.concreteCommandRoutes?.enabled ?? CONCRETE_COMMAND_ROUTES_DEFAULTS.enabled,
|
|
35
|
+
legacyAliasesOnly: options?.concreteCommandRoutes?.legacyAliasesOnly ?? CONCRETE_COMMAND_ROUTES_DEFAULTS.legacyAliasesOnly,
|
|
36
|
+
};
|
|
37
|
+
const readRoutes = {
|
|
38
|
+
enabled: options?.readRoutes?.enabled ?? READ_ROUTES_DEFAULTS.enabled,
|
|
39
|
+
directDbReads: options?.readRoutes?.directDbReads ?? READ_ROUTES_DEFAULTS.directDbReads,
|
|
40
|
+
};
|
|
41
|
+
// Resolve artifact paths from generatedDir (default: 'src').
|
|
42
|
+
// Individual path overrides take precedence.
|
|
43
|
+
const generatedDir = options?.generatedDir ?? 'src';
|
|
44
|
+
const paths = {
|
|
45
|
+
typesFile: options?.paths?.typesFile ?? `${generatedDir}/types/manifest-generated.ts`,
|
|
46
|
+
clientFile: options?.paths?.clientFile ?? `${generatedDir}/lib/manifest-client.ts`,
|
|
47
|
+
hooksDir: options?.paths?.hooksDir ?? `${generatedDir}/hooks`,
|
|
48
|
+
sharedRuntimeFile: options?.paths?.sharedRuntimeFile ?? `${generatedDir}/lib/manifest-shared-runtime.ts`,
|
|
49
|
+
};
|
|
50
|
+
// Derive the import path for the shared-runtime module from its pathHint.
|
|
51
|
+
// e.g. 'src/lib/manifest-shared-runtime.ts' → '@/lib/manifest-shared-runtime'
|
|
52
|
+
const sharedRuntimeImportPath = pathHintToImport(paths.sharedRuntimeFile);
|
|
53
|
+
return {
|
|
54
|
+
authProvider: options?.authProvider ?? NEXTJS_DEFAULTS.authProvider,
|
|
55
|
+
authImportPath: options?.authImportPath ?? NEXTJS_DEFAULTS.authImportPath,
|
|
56
|
+
databaseImportPath: options?.databaseImportPath ?? NEXTJS_DEFAULTS.databaseImportPath,
|
|
57
|
+
responseImportPath: options?.responseImportPath ?? NEXTJS_DEFAULTS.responseImportPath,
|
|
58
|
+
runtimeImportPath: options?.runtimeImportPath ?? NEXTJS_DEFAULTS.runtimeImportPath,
|
|
59
|
+
includeTenantFilter: options?.includeTenantFilter ?? NEXTJS_DEFAULTS.includeTenantFilter,
|
|
60
|
+
includeSoftDeleteFilter: options?.includeSoftDeleteFilter ?? NEXTJS_DEFAULTS.includeSoftDeleteFilter,
|
|
61
|
+
tenantIdProperty: options?.tenantIdProperty ?? NEXTJS_DEFAULTS.tenantIdProperty,
|
|
62
|
+
deletedAtProperty: options?.deletedAtProperty ?? NEXTJS_DEFAULTS.deletedAtProperty,
|
|
63
|
+
appDir: options?.appDir ?? NEXTJS_DEFAULTS.appDir,
|
|
64
|
+
strictMode: options?.strictMode ?? NEXTJS_DEFAULTS.strictMode,
|
|
65
|
+
includeComments: options?.includeComments ?? NEXTJS_DEFAULTS.includeComments,
|
|
66
|
+
indentSize: options?.indentSize ?? NEXTJS_DEFAULTS.indentSize,
|
|
67
|
+
unauthorizedStatus: options?.unauthorizedStatus ?? NEXTJS_DEFAULTS.unauthorizedStatus,
|
|
68
|
+
tenantProvider: options?.tenantProvider ?? DEFAULT_TENANT_PROVIDER,
|
|
69
|
+
dispatcher,
|
|
70
|
+
concreteCommandRoutes,
|
|
71
|
+
readRoutes,
|
|
72
|
+
paths,
|
|
73
|
+
sharedRuntimeImportPath,
|
|
74
|
+
naming: options?.naming,
|
|
75
|
+
accessorNames: options?.accessorNames ?? {},
|
|
76
|
+
routeSegments: options?.routeSegments ?? {},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Convert a pathHint (e.g. 'src/lib/manifest-shared-runtime.ts') to a
|
|
81
|
+
* TypeScript import alias (e.g. '@/lib/manifest-shared-runtime').
|
|
82
|
+
*/
|
|
83
|
+
function pathHintToImport(pathHint) {
|
|
84
|
+
return '@/' + pathHint.replace(/^src\//, '').replace(/\.ts$/, '');
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* True when any entity in the IR is flagged `realtime`. Realtime is a
|
|
88
|
+
* projection hint only (docs/spec/semantics.md, "Realtime Entities"): when
|
|
89
|
+
* present, SSE surfaces are emitted and inline command surfaces switch to
|
|
90
|
+
* the shared singleton engine so subscriptions can observe command events.
|
|
91
|
+
*/
|
|
92
|
+
function hasRealtimeEntities(ir) {
|
|
93
|
+
return ir.entities.some(e => e.realtime === true);
|
|
94
|
+
}
|
|
95
|
+
function toLowerCamelCase(value) {
|
|
96
|
+
if (!value)
|
|
97
|
+
return value;
|
|
98
|
+
return value[0].toLowerCase() + value.slice(1);
|
|
99
|
+
}
|
|
100
|
+
function toKebabCase(value) {
|
|
101
|
+
return value
|
|
102
|
+
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
103
|
+
.replace(/\s+/g, '-')
|
|
104
|
+
.toLowerCase();
|
|
105
|
+
}
|
|
106
|
+
function toEntitySegment(value) {
|
|
107
|
+
return value.toLowerCase();
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Database accessor name for an entity (`database.<accessor>` in generated
|
|
111
|
+
* read routes). Resolution: explicit `accessorNames` override → `naming`
|
|
112
|
+
* convention (table-name resolution, e.g. snake_case plural for Kysely/raw
|
|
113
|
+
* SQL clients) → camelCased entity name (Prisma delegate convention).
|
|
114
|
+
*
|
|
115
|
+
* Response field names and local variables deliberately do NOT use this —
|
|
116
|
+
* the HTTP API contract stays camelCase regardless of physical DB naming.
|
|
117
|
+
*/
|
|
118
|
+
function resolveDbAccessor(entityName, options) {
|
|
119
|
+
const explicit = options.accessorNames[entityName];
|
|
120
|
+
if (explicit)
|
|
121
|
+
return explicit;
|
|
122
|
+
if (options.naming)
|
|
123
|
+
return resolveTableName(entityName, options.naming);
|
|
124
|
+
return toLowerCamelCase(entityName);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* URL path segment for an entity in generated route pathHints and client
|
|
128
|
+
* fetch paths. Resolution: explicit `routeSegments` override → lowercased
|
|
129
|
+
* entity name (legacy behavior).
|
|
130
|
+
*/
|
|
131
|
+
function resolveRouteSegment(entityName, options) {
|
|
132
|
+
return options.routeSegments[entityName] ?? toEntitySegment(entityName);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Generate an import statement with proper path handling.
|
|
136
|
+
*/
|
|
137
|
+
function generateImport(module, from) {
|
|
138
|
+
return `import ${module} from "${from}";`;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Generate the import line for the auth provider (empty string if none needed).
|
|
142
|
+
*/
|
|
143
|
+
function generateAuthImport(options) {
|
|
144
|
+
const { authProvider, authImportPath } = options;
|
|
145
|
+
switch (authProvider) {
|
|
146
|
+
case 'clerk': {
|
|
147
|
+
const clerkImport = authImportPath === '@/lib/auth' ? '@clerk/nextjs' : authImportPath;
|
|
148
|
+
return generateImport('{ auth }', clerkImport);
|
|
149
|
+
}
|
|
150
|
+
case 'nextauth': {
|
|
151
|
+
const nextAuthImport = authImportPath === '@/lib/auth' ? 'next-auth' : authImportPath;
|
|
152
|
+
return generateImport('{ getServerSession }', nextAuthImport);
|
|
153
|
+
}
|
|
154
|
+
case 'custom':
|
|
155
|
+
return generateImport('{ getUser }', authImportPath);
|
|
156
|
+
case 'none':
|
|
157
|
+
default:
|
|
158
|
+
return '';
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Generate the auth check body (no import statements).
|
|
163
|
+
*
|
|
164
|
+
* The unauthorized status is wired from `options.unauthorizedStatus` so apps
|
|
165
|
+
* can standardise on 403 (avoiding existence leak) without forking the
|
|
166
|
+
* generator. Thrown errors from the auth helper are NOT handled here — the
|
|
167
|
+
* caller is expected to wrap this body in a try/catch that maps any
|
|
168
|
+
* exception to the same unauthorized status, per goal step 4.
|
|
169
|
+
*/
|
|
170
|
+
function generateAuthBody(options) {
|
|
171
|
+
const { authProvider, unauthorizedStatus } = options;
|
|
172
|
+
const status = unauthorizedStatus;
|
|
173
|
+
switch (authProvider) {
|
|
174
|
+
case 'clerk': {
|
|
175
|
+
const needsOrgId = options.tenantProvider?.lookupKey === 'orgId';
|
|
176
|
+
const destructure = needsOrgId ? '{ orgId, userId }' : '{ userId }';
|
|
177
|
+
const authGuard = needsOrgId
|
|
178
|
+
? 'if (!(userId && orgId)) {'
|
|
179
|
+
: 'if (!userId) {';
|
|
180
|
+
return ` const ${destructure} = await auth();
|
|
181
|
+
${authGuard}
|
|
182
|
+
return manifestErrorResponse({ error: "Unauthorized", diagnostics: [] }, ${status});
|
|
183
|
+
}`;
|
|
184
|
+
}
|
|
185
|
+
case 'nextauth':
|
|
186
|
+
return ` const session = await getServerSession();
|
|
187
|
+
if (!session?.user?.id) {
|
|
188
|
+
return manifestErrorResponse({ error: "Unauthorized", diagnostics: [] }, ${status});
|
|
189
|
+
}
|
|
190
|
+
const userId = session.user.id;`;
|
|
191
|
+
case 'custom':
|
|
192
|
+
return ` const user = await getUser(request);
|
|
193
|
+
if (!user?.id) {
|
|
194
|
+
return manifestErrorResponse({ error: "Unauthorized", diagnostics: [] }, ${status});
|
|
195
|
+
}
|
|
196
|
+
const userId = user.id;`;
|
|
197
|
+
case 'none':
|
|
198
|
+
return ` // Auth disabled - all requests allowed\n const userId = "anonymous";`;
|
|
199
|
+
default:
|
|
200
|
+
return ` // Unknown auth provider - please implement\n const userId = "unknown";`;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Tag every emitted runtime error block with a stable Manifest response
|
|
205
|
+
* shape (`{ error, diagnostics }`) at status 500. Auth failures map to
|
|
206
|
+
* `unauthorizedStatus` via a separate branch; transport/runtime failures
|
|
207
|
+
* always carry this shape so downstream clients can rely on it.
|
|
208
|
+
*/
|
|
209
|
+
function emitRuntimeErrorReturn(unauthorizedStatus, opName) {
|
|
210
|
+
return [
|
|
211
|
+
' } catch (error) {',
|
|
212
|
+
' // Auth helpers (clerk, next-auth, custom) may throw on invalid/expired',
|
|
213
|
+
' // tokens. Goal step 4: auth failures MUST NEVER surface as 500.',
|
|
214
|
+
' const isAuthError = error instanceof Error && (',
|
|
215
|
+
' /unauth/i.test(error.message) ||',
|
|
216
|
+
' /token/i.test(error.message) ||',
|
|
217
|
+
' /session/i.test(error.message)',
|
|
218
|
+
' );',
|
|
219
|
+
' if (isAuthError) {',
|
|
220
|
+
` return manifestErrorResponse({ error: "Unauthorized", diagnostics: [] }, ${unauthorizedStatus});`,
|
|
221
|
+
' }',
|
|
222
|
+
` console.error(${JSON.stringify(opName)}, error);`,
|
|
223
|
+
' return manifestErrorResponse(',
|
|
224
|
+
' { error: "Internal server error", diagnostics: [{ kind: "runtime_error", message: error instanceof Error ? error.message : String(error) }] },',
|
|
225
|
+
' 500,',
|
|
226
|
+
' );',
|
|
227
|
+
' }',
|
|
228
|
+
];
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Generate tenant lookup code.
|
|
232
|
+
*/
|
|
233
|
+
function generateTenantLookup(options) {
|
|
234
|
+
if (!options.includeTenantFilter) {
|
|
235
|
+
return '';
|
|
236
|
+
}
|
|
237
|
+
if (options.tenantProvider) {
|
|
238
|
+
const { functionName, lookupKey } = options.tenantProvider;
|
|
239
|
+
return `
|
|
240
|
+
const ${options.tenantIdProperty} = await ${functionName}(${lookupKey});
|
|
241
|
+
|
|
242
|
+
if (!${options.tenantIdProperty}) {
|
|
243
|
+
return manifestErrorResponse({ error: "Tenant not found", diagnostics: [] }, 400);
|
|
244
|
+
}`;
|
|
245
|
+
}
|
|
246
|
+
return `
|
|
247
|
+
const userMapping = await database.userTenantMapping.findUnique({
|
|
248
|
+
where: { userId },
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
if (!userMapping) {
|
|
252
|
+
return manifestErrorResponse({ error: "User not mapped to tenant", diagnostics: [] }, 400);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
const { ${options.tenantIdProperty} } = userMapping;`;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* True when the entity declares a property with the given name.
|
|
259
|
+
*
|
|
260
|
+
* Read-query generation is field-aware: a filter or orderBy clause may only
|
|
261
|
+
* reference a column the entity actually has. Emitting `deletedAt: null` or
|
|
262
|
+
* `orderBy: { createdAt }` for an entity without those columns produces a
|
|
263
|
+
* query Prisma rejects at runtime ("Unknown argument deletedAt").
|
|
264
|
+
*/
|
|
265
|
+
function entityHasProperty(entity, propertyName) {
|
|
266
|
+
return entity.properties.some((p) => p.name === propertyName);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Generate Prisma query with filters.
|
|
270
|
+
*
|
|
271
|
+
* Field-aware: the soft-delete filter and the orderBy column are only emitted
|
|
272
|
+
* when the entity declares them. Without this, every generated read route
|
|
273
|
+
* assumes soft-delete + creation timestamps exist on every entity.
|
|
274
|
+
*/
|
|
275
|
+
function generatePrismaQuery(entity, options) {
|
|
276
|
+
const accessorName = resolveDbAccessor(entity.name, options);
|
|
277
|
+
const variableName = `${toLowerCamelCase(entity.name)}s`;
|
|
278
|
+
const { includeTenantFilter, includeSoftDeleteFilter, tenantIdProperty, deletedAtProperty } = options;
|
|
279
|
+
const whereConditions = [];
|
|
280
|
+
if (includeTenantFilter) {
|
|
281
|
+
whereConditions.push(`${tenantIdProperty}`);
|
|
282
|
+
}
|
|
283
|
+
// Soft-delete filter only when the entity actually declares the column.
|
|
284
|
+
if (includeSoftDeleteFilter && entityHasProperty(entity, deletedAtProperty)) {
|
|
285
|
+
whereConditions.push(`${deletedAtProperty}: null`);
|
|
286
|
+
}
|
|
287
|
+
const whereClause = whereConditions.length > 0
|
|
288
|
+
? `where: {
|
|
289
|
+
${whereConditions.join(',\n ')}
|
|
290
|
+
},`
|
|
291
|
+
: '';
|
|
292
|
+
// orderBy must reference a real column. Prefer createdAt when present;
|
|
293
|
+
// otherwise fall back to the always-present id so the query stays valid.
|
|
294
|
+
const orderByField = entityHasProperty(entity, 'createdAt') ? 'createdAt' : 'id';
|
|
295
|
+
return `const ${variableName} = await database.${accessorName}.findMany({
|
|
296
|
+
${whereClause}
|
|
297
|
+
orderBy: {
|
|
298
|
+
${orderByField}: "desc",
|
|
299
|
+
},
|
|
300
|
+
});`;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Convert IR type to TypeScript type.
|
|
304
|
+
*/
|
|
305
|
+
function irTypeToTsType(irType) {
|
|
306
|
+
const tsTypeMap = {
|
|
307
|
+
string: 'string',
|
|
308
|
+
number: 'number',
|
|
309
|
+
boolean: 'boolean',
|
|
310
|
+
date: 'Date',
|
|
311
|
+
datetime: 'Date',
|
|
312
|
+
any: 'unknown',
|
|
313
|
+
void: 'void',
|
|
314
|
+
};
|
|
315
|
+
const baseType = tsTypeMap[irType.name] || irType.name;
|
|
316
|
+
return irType.nullable ? `${baseType} | null` : baseType;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Generate TypeScript types from IR entity.
|
|
320
|
+
*/
|
|
321
|
+
function generateEntityTypes(entity) {
|
|
322
|
+
const lines = [];
|
|
323
|
+
lines.push(`export interface ${entity.name} {`);
|
|
324
|
+
for (const prop of entity.properties) {
|
|
325
|
+
const tsType = irTypeToTsType(prop.type);
|
|
326
|
+
const isOptional = prop.modifiers.includes('optional') ||
|
|
327
|
+
prop.defaultValue !== undefined ||
|
|
328
|
+
prop.type.nullable;
|
|
329
|
+
const optional = isOptional ? '?' : '';
|
|
330
|
+
lines.push(` ${prop.name}${optional}: ${tsType};`);
|
|
331
|
+
}
|
|
332
|
+
lines.push('}');
|
|
333
|
+
lines.push('');
|
|
334
|
+
return lines.join('\n');
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Next.js projection implementation.
|
|
338
|
+
*/
|
|
339
|
+
export class NextJsProjection {
|
|
340
|
+
name = 'nextjs';
|
|
341
|
+
description = 'Next.js App Router API routes with configurable auth and database support';
|
|
342
|
+
surfaces = ['nextjs.route', 'nextjs.detail', 'nextjs.command', 'nextjs.dispatcher', 'nextjs.subscribe', 'nextjs.subscriptionHook', 'nextjs.sharedRuntime', 'nextjs.schedule', 'ts.types', 'ts.client'];
|
|
343
|
+
generate(ir, request) {
|
|
344
|
+
const options = request.options;
|
|
345
|
+
switch (request.surface) {
|
|
346
|
+
case 'nextjs.route': {
|
|
347
|
+
if (!request.entity) {
|
|
348
|
+
return {
|
|
349
|
+
artifacts: [],
|
|
350
|
+
diagnostics: [{ severity: 'error', code: 'MISSING_ENTITY', message: 'surface "nextjs.route" requires entity' }],
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
const opts = normalizeOptions(options);
|
|
354
|
+
if (!opts.readRoutes.enabled) {
|
|
355
|
+
return {
|
|
356
|
+
artifacts: [],
|
|
357
|
+
diagnostics: [{
|
|
358
|
+
severity: 'info',
|
|
359
|
+
code: 'READ_ROUTES_DISABLED',
|
|
360
|
+
message: 'readRoutes.enabled is false — skipping nextjs.route emission.',
|
|
361
|
+
entity: request.entity,
|
|
362
|
+
}],
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
const result = this._route(ir, request.entity, options);
|
|
366
|
+
if (result.diagnostics.some(d => d.severity === 'error')) {
|
|
367
|
+
return { artifacts: [], diagnostics: result.diagnostics };
|
|
368
|
+
}
|
|
369
|
+
return {
|
|
370
|
+
artifacts: [{
|
|
371
|
+
id: `nextjs.route:${request.entity}`,
|
|
372
|
+
pathHint: `${opts.appDir}/${resolveRouteSegment(request.entity, opts)}/list/route.ts`,
|
|
373
|
+
contentType: 'typescript',
|
|
374
|
+
code: result.code,
|
|
375
|
+
}],
|
|
376
|
+
diagnostics: result.diagnostics,
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
case 'nextjs.detail': {
|
|
380
|
+
if (!request.entity) {
|
|
381
|
+
return {
|
|
382
|
+
artifacts: [],
|
|
383
|
+
diagnostics: [{ severity: 'error', code: 'MISSING_ENTITY', message: 'surface "nextjs.detail" requires entity' }],
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
const detailOpts = normalizeOptions(options);
|
|
387
|
+
if (!detailOpts.readRoutes.enabled) {
|
|
388
|
+
return {
|
|
389
|
+
artifacts: [],
|
|
390
|
+
diagnostics: [{
|
|
391
|
+
severity: 'info',
|
|
392
|
+
code: 'READ_ROUTES_DISABLED',
|
|
393
|
+
message: 'readRoutes.enabled is false — skipping nextjs.detail emission.',
|
|
394
|
+
entity: request.entity,
|
|
395
|
+
}],
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
const detailResult = this._detail(ir, request.entity, options);
|
|
399
|
+
if (detailResult.diagnostics.some(d => d.severity === 'error')) {
|
|
400
|
+
return { artifacts: [], diagnostics: detailResult.diagnostics };
|
|
401
|
+
}
|
|
402
|
+
return {
|
|
403
|
+
artifacts: [{
|
|
404
|
+
id: `nextjs.detail:${request.entity}`,
|
|
405
|
+
pathHint: `${detailOpts.appDir}/${resolveRouteSegment(request.entity, detailOpts)}/[id]/route.ts`,
|
|
406
|
+
contentType: 'typescript',
|
|
407
|
+
code: detailResult.code,
|
|
408
|
+
}],
|
|
409
|
+
diagnostics: detailResult.diagnostics,
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
case 'nextjs.command': {
|
|
413
|
+
if (!request.entity) {
|
|
414
|
+
return {
|
|
415
|
+
artifacts: [],
|
|
416
|
+
diagnostics: [{ severity: 'error', code: 'MISSING_ENTITY', message: 'surface "nextjs.command" requires entity' }],
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
if (!request.command) {
|
|
420
|
+
return {
|
|
421
|
+
artifacts: [],
|
|
422
|
+
diagnostics: [{ severity: 'error', code: 'MISSING_COMMAND', message: 'surface "nextjs.command" requires command' }],
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
const commandOpts = normalizeOptions(options);
|
|
426
|
+
if (!commandOpts.concreteCommandRoutes.enabled) {
|
|
427
|
+
return {
|
|
428
|
+
artifacts: [],
|
|
429
|
+
diagnostics: [{
|
|
430
|
+
severity: 'info',
|
|
431
|
+
code: 'CONCRETE_COMMAND_ROUTES_DISABLED',
|
|
432
|
+
message: 'concreteCommandRoutes.enabled is false — skipping per-command route emission. Use nextjs.dispatcher instead.',
|
|
433
|
+
entity: request.entity,
|
|
434
|
+
}],
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
const commandResult = this._command(ir, request.entity, request.command, options);
|
|
438
|
+
if (commandResult.diagnostics.some(d => d.severity === 'error')) {
|
|
439
|
+
return { artifacts: [], diagnostics: commandResult.diagnostics };
|
|
440
|
+
}
|
|
441
|
+
return {
|
|
442
|
+
artifacts: [{
|
|
443
|
+
id: `nextjs.command:${request.entity}.${request.command}`,
|
|
444
|
+
pathHint: `${commandOpts.appDir}/${resolveRouteSegment(request.entity, commandOpts)}/${toKebabCase(request.command)}/route.ts`,
|
|
445
|
+
contentType: 'typescript',
|
|
446
|
+
code: commandResult.code,
|
|
447
|
+
}],
|
|
448
|
+
diagnostics: commandResult.diagnostics,
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
case 'nextjs.dispatcher': {
|
|
452
|
+
const dispatcherOpts = normalizeOptions(options);
|
|
453
|
+
if (!dispatcherOpts.dispatcher.enabled) {
|
|
454
|
+
return {
|
|
455
|
+
artifacts: [],
|
|
456
|
+
diagnostics: [{
|
|
457
|
+
severity: 'info',
|
|
458
|
+
code: 'DISPATCHER_DISABLED',
|
|
459
|
+
message: 'dispatcher.enabled is false — skipping nextjs.dispatcher emission.',
|
|
460
|
+
}],
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
const dispatcherResult = this._dispatcher(ir, options);
|
|
464
|
+
if (dispatcherResult.diagnostics.some(d => d.severity === 'error')) {
|
|
465
|
+
return { artifacts: [], diagnostics: dispatcherResult.diagnostics };
|
|
466
|
+
}
|
|
467
|
+
// dispatcher.path is relative to appDir (joined directly; the
|
|
468
|
+
// default starts with '/' so we don't double-slash on appDir).
|
|
469
|
+
const dispatcherPathHint = `${dispatcherOpts.appDir}${dispatcherOpts.dispatcher.path}`;
|
|
470
|
+
return {
|
|
471
|
+
artifacts: [{
|
|
472
|
+
id: 'nextjs.dispatcher',
|
|
473
|
+
pathHint: dispatcherPathHint,
|
|
474
|
+
contentType: 'typescript',
|
|
475
|
+
code: dispatcherResult.code,
|
|
476
|
+
}],
|
|
477
|
+
diagnostics: dispatcherResult.diagnostics,
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
case 'nextjs.subscribe': {
|
|
481
|
+
if (!request.entity) {
|
|
482
|
+
return {
|
|
483
|
+
artifacts: [],
|
|
484
|
+
diagnostics: [{ severity: 'error', code: 'MISSING_ENTITY', message: 'surface "nextjs.subscribe" requires entity' }],
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
const subscribeOpts = normalizeOptions(options);
|
|
488
|
+
const subscribeResult = this._subscribe(ir, request.entity, options);
|
|
489
|
+
if (subscribeResult.diagnostics.some(d => d.severity === 'error') || !subscribeResult.code) {
|
|
490
|
+
return { artifacts: [], diagnostics: subscribeResult.diagnostics };
|
|
491
|
+
}
|
|
492
|
+
return {
|
|
493
|
+
artifacts: [{
|
|
494
|
+
id: `nextjs.subscribe:${request.entity}`,
|
|
495
|
+
pathHint: `${subscribeOpts.appDir}/${resolveRouteSegment(request.entity, subscribeOpts)}/subscribe/route.ts`,
|
|
496
|
+
contentType: 'typescript',
|
|
497
|
+
code: subscribeResult.code,
|
|
498
|
+
}],
|
|
499
|
+
diagnostics: subscribeResult.diagnostics,
|
|
500
|
+
};
|
|
501
|
+
}
|
|
502
|
+
case 'nextjs.subscriptionHook': {
|
|
503
|
+
if (!request.entity) {
|
|
504
|
+
return {
|
|
505
|
+
artifacts: [],
|
|
506
|
+
diagnostics: [{ severity: 'error', code: 'MISSING_ENTITY', message: 'surface "nextjs.subscriptionHook" requires entity' }],
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
const opts = normalizeOptions(options);
|
|
510
|
+
const hookResult = this._subscriptionHook(ir, request.entity, opts);
|
|
511
|
+
if (hookResult.diagnostics.some(d => d.severity === 'error') || !hookResult.code) {
|
|
512
|
+
return { artifacts: [], diagnostics: hookResult.diagnostics };
|
|
513
|
+
}
|
|
514
|
+
return {
|
|
515
|
+
artifacts: [{
|
|
516
|
+
id: `nextjs.subscriptionHook:${request.entity}`,
|
|
517
|
+
pathHint: `${opts.paths.hooksDir}/use${request.entity}Subscription.ts`,
|
|
518
|
+
contentType: 'typescript',
|
|
519
|
+
code: hookResult.code,
|
|
520
|
+
}],
|
|
521
|
+
diagnostics: hookResult.diagnostics,
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
case 'nextjs.sharedRuntime': {
|
|
525
|
+
const opts = normalizeOptions(options);
|
|
526
|
+
const sharedResult = this._sharedRuntime(ir, options);
|
|
527
|
+
if (!sharedResult.code) {
|
|
528
|
+
return { artifacts: [], diagnostics: sharedResult.diagnostics };
|
|
529
|
+
}
|
|
530
|
+
return {
|
|
531
|
+
artifacts: [{
|
|
532
|
+
id: 'nextjs.sharedRuntime',
|
|
533
|
+
pathHint: opts.paths.sharedRuntimeFile,
|
|
534
|
+
contentType: 'typescript',
|
|
535
|
+
code: sharedResult.code,
|
|
536
|
+
}],
|
|
537
|
+
diagnostics: sharedResult.diagnostics,
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
case 'nextjs.schedule': {
|
|
541
|
+
const scheduleOpts = normalizeOptions(options);
|
|
542
|
+
return generateScheduleCronRoutes(ir, {
|
|
543
|
+
runtimeImportPath: scheduleOpts.runtimeImportPath,
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
case 'ts.types': {
|
|
547
|
+
const opts = normalizeOptions(options);
|
|
548
|
+
const result = this._types(ir);
|
|
549
|
+
return {
|
|
550
|
+
artifacts: [{
|
|
551
|
+
id: 'ts.types',
|
|
552
|
+
pathHint: opts.paths.typesFile,
|
|
553
|
+
contentType: 'typescript',
|
|
554
|
+
code: result.code,
|
|
555
|
+
}],
|
|
556
|
+
diagnostics: result.diagnostics,
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
case 'ts.client': {
|
|
560
|
+
const opts = normalizeOptions(options);
|
|
561
|
+
const result = this._client(ir, opts);
|
|
562
|
+
return {
|
|
563
|
+
artifacts: [{
|
|
564
|
+
id: 'ts.client',
|
|
565
|
+
pathHint: opts.paths.clientFile,
|
|
566
|
+
contentType: 'typescript',
|
|
567
|
+
code: result.code,
|
|
568
|
+
}],
|
|
569
|
+
diagnostics: result.diagnostics,
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
default:
|
|
573
|
+
return {
|
|
574
|
+
artifacts: [],
|
|
575
|
+
diagnostics: [{ severity: 'error', code: 'UNKNOWN_SURFACE', message: `Unknown surface: "${request.surface}"` }],
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
_route(ir, entityName, options) {
|
|
580
|
+
const diagnostics = [];
|
|
581
|
+
const opts = normalizeOptions(options);
|
|
582
|
+
// Find the entity in IR
|
|
583
|
+
const entity = ir.entities.find(e => e.name === entityName);
|
|
584
|
+
if (!entity) {
|
|
585
|
+
diagnostics.push({
|
|
586
|
+
severity: 'error',
|
|
587
|
+
code: 'ENTITY_NOT_FOUND',
|
|
588
|
+
message: `Entity "${entityName}" not found in IR. Available entities: ${ir.entities.map(e => e.name).join(', ')}`,
|
|
589
|
+
entity: entityName,
|
|
590
|
+
});
|
|
591
|
+
return { code: '', diagnostics };
|
|
592
|
+
}
|
|
593
|
+
const code = this._generateGetRoute(entity, opts);
|
|
594
|
+
return { code, diagnostics };
|
|
595
|
+
}
|
|
596
|
+
_types(ir) {
|
|
597
|
+
const lines = [];
|
|
598
|
+
lines.push('// Auto-generated TypeScript types from Manifest IR');
|
|
599
|
+
lines.push('// DO NOT EDIT - This file is generated from .manifest source');
|
|
600
|
+
lines.push('');
|
|
601
|
+
for (const entity of ir.entities) {
|
|
602
|
+
lines.push(generateEntityTypes(entity));
|
|
603
|
+
}
|
|
604
|
+
return { code: lines.join('\n'), diagnostics: [] };
|
|
605
|
+
}
|
|
606
|
+
_client(ir, options) {
|
|
607
|
+
const lines = [];
|
|
608
|
+
lines.push('// Auto-generated client SDK from Manifest IR');
|
|
609
|
+
lines.push('// DO NOT EDIT - This file is generated from .manifest source');
|
|
610
|
+
lines.push('');
|
|
611
|
+
for (const entity of ir.entities) {
|
|
612
|
+
const lowerEntity = resolveRouteSegment(entity.name, options);
|
|
613
|
+
const delegateName = toLowerCamelCase(entity.name);
|
|
614
|
+
// List (findMany) function
|
|
615
|
+
lines.push(`export async function get${entity.name}s(): Promise<${entity.name}[]> {`);
|
|
616
|
+
lines.push(` const response = await fetch(\`/api/${lowerEntity}/list\`);`);
|
|
617
|
+
lines.push(` if (!response.ok) {`);
|
|
618
|
+
lines.push(` throw new Error("Failed to fetch ${entity.name}s");`);
|
|
619
|
+
lines.push(` }`);
|
|
620
|
+
lines.push(` const data = await response.json();`);
|
|
621
|
+
lines.push(` return data.${delegateName}s;`);
|
|
622
|
+
lines.push(`}`);
|
|
623
|
+
lines.push('');
|
|
624
|
+
// Detail (findUnique) function
|
|
625
|
+
lines.push(`export async function get${entity.name}(id: string): Promise<${entity.name}> {`);
|
|
626
|
+
lines.push(` const response = await fetch(\`/api/${lowerEntity}/\${encodeURIComponent(id)}\`);`);
|
|
627
|
+
lines.push(` if (!response.ok) {`);
|
|
628
|
+
lines.push(` throw new Error("Failed to fetch ${entity.name}");`);
|
|
629
|
+
lines.push(` }`);
|
|
630
|
+
lines.push(` const data = await response.json();`);
|
|
631
|
+
lines.push(` return data.${delegateName};`);
|
|
632
|
+
lines.push(`}`);
|
|
633
|
+
lines.push('');
|
|
634
|
+
}
|
|
635
|
+
return { code: lines.join('\n'), diagnostics: [] };
|
|
636
|
+
}
|
|
637
|
+
_command(ir, entityName, commandName, options) {
|
|
638
|
+
const diagnostics = [];
|
|
639
|
+
const opts = normalizeOptions(options);
|
|
640
|
+
const entity = ir.entities.find(e => e.name === entityName);
|
|
641
|
+
if (!entity) {
|
|
642
|
+
diagnostics.push({
|
|
643
|
+
severity: 'error',
|
|
644
|
+
code: 'ENTITY_NOT_FOUND',
|
|
645
|
+
message: `Entity "${entityName}" not found in IR. Available entities: ${ir.entities.map(e => e.name).join(', ')}`,
|
|
646
|
+
entity: entityName,
|
|
647
|
+
});
|
|
648
|
+
return { code: '', diagnostics };
|
|
649
|
+
}
|
|
650
|
+
const entityCommands = ir.commands.filter(c => c.entity === entityName);
|
|
651
|
+
const command = entityCommands.find(c => c.name === commandName);
|
|
652
|
+
if (!command) {
|
|
653
|
+
diagnostics.push({
|
|
654
|
+
severity: 'error',
|
|
655
|
+
code: 'COMMAND_NOT_FOUND',
|
|
656
|
+
message: `Command "${commandName}" not found on entity "${entityName}". Available commands: ${entityCommands.map(c => c.name).join(', ')}`,
|
|
657
|
+
entity: entityName,
|
|
658
|
+
});
|
|
659
|
+
return { code: '', diagnostics };
|
|
660
|
+
}
|
|
661
|
+
const code = this._generatePostCommandHandler(entity, command, opts, hasRealtimeEntities(ir));
|
|
662
|
+
return { code, diagnostics };
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Generate POST command handler for an entity command.
|
|
666
|
+
* Writes MUST flow through runtime.runCommand() to enforce guards, policies, and constraints.
|
|
667
|
+
*/
|
|
668
|
+
_generatePostCommandHandler(entity, command, options, useSharedRuntime) {
|
|
669
|
+
const { responseImportPath, runtimeImportPath, dispatcher } = options;
|
|
670
|
+
const useExternalExecutor = dispatcher.executionMode === 'externalExecutor';
|
|
671
|
+
// Realtime SSE requires command execution and subscriptions to share ONE
|
|
672
|
+
// engine; inline mode switches to the generated shared-runtime accessor.
|
|
673
|
+
// externalExecutor mode is unaffected — the executor owns runtime
|
|
674
|
+
// construction (and should use getSharedRuntime() itself).
|
|
675
|
+
const useShared = useSharedRuntime && !useExternalExecutor;
|
|
676
|
+
const lines = [];
|
|
677
|
+
lines.push(`// Auto-generated Next.js command handler for ${entity.name}.${command.name}`);
|
|
678
|
+
lines.push('// Generated from Manifest IR - DO NOT EDIT');
|
|
679
|
+
lines.push('//');
|
|
680
|
+
if (options.concreteCommandRoutes.legacyAliasesOnly) {
|
|
681
|
+
lines.push('// DEPRECATED ALIAS: this concrete per-command route is retained for');
|
|
682
|
+
lines.push('// backwards compatibility only. The canonical write path is the');
|
|
683
|
+
lines.push('// nextjs.dispatcher projection at:');
|
|
684
|
+
lines.push('// POST /api/manifest/[entity]/commands/[command]');
|
|
685
|
+
lines.push('// See docs/spec/adapters.md § "Canonical Dispatcher (Transport Boundary)".');
|
|
686
|
+
lines.push('//');
|
|
687
|
+
}
|
|
688
|
+
lines.push('// Writes MUST flow through runtime to enforce guards, policies, and constraints.');
|
|
689
|
+
lines.push('');
|
|
690
|
+
lines.push('import type { NextRequest } from "next/server";');
|
|
691
|
+
lines.push(generateImport('{ manifestErrorResponse, manifestSuccessResponse, normalizeCommandResult }', responseImportPath));
|
|
692
|
+
if (useExternalExecutor) {
|
|
693
|
+
lines.push(generateImport(`{ ${dispatcher.executorImportName} }`, dispatcher.executorImportPath));
|
|
694
|
+
}
|
|
695
|
+
else if (useShared) {
|
|
696
|
+
lines.push(generateImport('{ getSharedRuntime }', options.sharedRuntimeImportPath));
|
|
697
|
+
}
|
|
698
|
+
else {
|
|
699
|
+
lines.push(generateImport('{ createManifestRuntime }', runtimeImportPath));
|
|
700
|
+
}
|
|
701
|
+
if (options.includeTenantFilter) {
|
|
702
|
+
if (options.tenantProvider) {
|
|
703
|
+
lines.push(generateImport(`{ ${options.tenantProvider.functionName} }`, options.tenantProvider.importPath));
|
|
704
|
+
}
|
|
705
|
+
else {
|
|
706
|
+
lines.push(generateImport('{ database }', options.databaseImportPath));
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
const authImport = generateAuthImport(options);
|
|
710
|
+
if (authImport)
|
|
711
|
+
lines.push(authImport);
|
|
712
|
+
lines.push('');
|
|
713
|
+
lines.push('export async function POST(request: NextRequest) {');
|
|
714
|
+
lines.push(' try {');
|
|
715
|
+
lines.push(generateAuthBody(options));
|
|
716
|
+
const tenantLookup = generateTenantLookup(options);
|
|
717
|
+
if (tenantLookup)
|
|
718
|
+
lines.push(tenantLookup);
|
|
719
|
+
lines.push('');
|
|
720
|
+
lines.push(' const body = await request.json();');
|
|
721
|
+
lines.push('');
|
|
722
|
+
if (dispatcher.deriveInstanceId) {
|
|
723
|
+
// Goal step 4: non-create commands must extract instanceId from the
|
|
724
|
+
// request. Extract universally — create commands ignore it harmlessly.
|
|
725
|
+
lines.push(' const instanceId = typeof body?.instanceId === "string"');
|
|
726
|
+
lines.push(' ? body.instanceId');
|
|
727
|
+
lines.push(' : typeof body?.id === "string"');
|
|
728
|
+
lines.push(' ? body.id');
|
|
729
|
+
lines.push(' : undefined;');
|
|
730
|
+
lines.push('');
|
|
731
|
+
}
|
|
732
|
+
if (useExternalExecutor) {
|
|
733
|
+
const tenantField = options.tenantIdProperty;
|
|
734
|
+
const tenantValueExpr = options.includeTenantFilter ? tenantField : '"__no_tenant__"';
|
|
735
|
+
lines.push(` const result = await ${dispatcher.executorImportName}({`);
|
|
736
|
+
lines.push(` entityName: "${entity.name}",`);
|
|
737
|
+
lines.push(` commandName: "${command.name}",`);
|
|
738
|
+
lines.push(' input: body,');
|
|
739
|
+
if (dispatcher.deriveInstanceId) {
|
|
740
|
+
lines.push(' instanceId,');
|
|
741
|
+
}
|
|
742
|
+
lines.push(' context: {');
|
|
743
|
+
if (options.includeTenantFilter) {
|
|
744
|
+
lines.push(` tenantId: ${tenantValueExpr},`);
|
|
745
|
+
lines.push(` orgId: ${tenantValueExpr},`);
|
|
746
|
+
}
|
|
747
|
+
lines.push(' actorId: userId,');
|
|
748
|
+
lines.push(' requestId: request.headers.get("x-request-id") ?? undefined,');
|
|
749
|
+
lines.push(' source: "route",');
|
|
750
|
+
lines.push(` user: { id: userId, ${tenantField}: ${tenantValueExpr} },`);
|
|
751
|
+
lines.push(' },');
|
|
752
|
+
lines.push(' });');
|
|
753
|
+
}
|
|
754
|
+
else {
|
|
755
|
+
const tenantCtx = options.includeTenantFilter
|
|
756
|
+
? `{ user: { id: userId, ${options.tenantIdProperty}: ${options.tenantIdProperty} } }`
|
|
757
|
+
: `{ user: { id: userId, ${options.tenantIdProperty}: "__no_tenant__" } }`;
|
|
758
|
+
if (useShared) {
|
|
759
|
+
lines.push(' const runtime = await getSharedRuntime();');
|
|
760
|
+
lines.push(` runtime.replaceContext(${tenantCtx});`);
|
|
761
|
+
}
|
|
762
|
+
else {
|
|
763
|
+
lines.push(` const runtime = await createManifestRuntime(${tenantCtx});`);
|
|
764
|
+
}
|
|
765
|
+
lines.push(` const result = await runtime.runCommand("${command.name}", body, {`);
|
|
766
|
+
lines.push(` entityName: "${entity.name}",`);
|
|
767
|
+
if (dispatcher.deriveInstanceId) {
|
|
768
|
+
// runtime-engine.ts runCommand accepts { entityName?, instanceId? }
|
|
769
|
+
// as its third arg — pass instanceId through for non-create commands.
|
|
770
|
+
lines.push(' instanceId,');
|
|
771
|
+
}
|
|
772
|
+
lines.push(' });');
|
|
773
|
+
}
|
|
774
|
+
lines.push('');
|
|
775
|
+
lines.push(` const normalized = normalizeCommandResult("${entity.name}", "${command.name}", result);`);
|
|
776
|
+
lines.push('');
|
|
777
|
+
lines.push(' if (!normalized.success) {');
|
|
778
|
+
lines.push(' // Determine HTTP status based on diagnostic kind');
|
|
779
|
+
lines.push(' const firstDiagnostic = normalized.diagnostics?.[0];');
|
|
780
|
+
lines.push(' const status = firstDiagnostic?.kind === "policy_denial" ? 403');
|
|
781
|
+
lines.push(' : firstDiagnostic?.kind === "guard_failure" ? 422');
|
|
782
|
+
lines.push(' : firstDiagnostic?.kind === "constraint_block" ? 422');
|
|
783
|
+
lines.push(' : 400;');
|
|
784
|
+
lines.push(' return manifestErrorResponse({ error: normalized.error, diagnostics: normalized.diagnostics }, status);');
|
|
785
|
+
lines.push(' }');
|
|
786
|
+
lines.push('');
|
|
787
|
+
lines.push(' return manifestSuccessResponse({ data: normalized.data, events: normalized.events, diagnostics: normalized.diagnostics });');
|
|
788
|
+
for (const errLine of emitRuntimeErrorReturn(options.unauthorizedStatus, `Error executing ${entity.name}.${command.name}:`)) {
|
|
789
|
+
lines.push(errLine);
|
|
790
|
+
}
|
|
791
|
+
lines.push('}');
|
|
792
|
+
lines.push('');
|
|
793
|
+
return lines.join('\n');
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Generate the canonical dispatcher route. Single dynamic file at
|
|
797
|
+
* <appDir>/manifest/[entity]/commands/[command]/route.ts
|
|
798
|
+
* Resolves entity+command at request time and delegates to
|
|
799
|
+
* RuntimeEngine.runCommand. Single canonical write path for governed
|
|
800
|
+
* mutations; downstream integrations may add aliases or CI gates.
|
|
801
|
+
*/
|
|
802
|
+
_dispatcher(ir, options) {
|
|
803
|
+
const opts = normalizeOptions(options);
|
|
804
|
+
const code = this._generateDispatcherHandler(opts, hasRealtimeEntities(ir));
|
|
805
|
+
return { code, diagnostics: [] };
|
|
806
|
+
}
|
|
807
|
+
_generateDispatcherHandler(options, useSharedRuntime) {
|
|
808
|
+
const { responseImportPath, runtimeImportPath, dispatcher } = options;
|
|
809
|
+
const useExternalExecutor = dispatcher.executionMode === 'externalExecutor';
|
|
810
|
+
// Realtime SSE requires command execution and subscriptions to share ONE
|
|
811
|
+
// engine; inline mode switches to the generated shared-runtime accessor.
|
|
812
|
+
const useShared = useSharedRuntime && !useExternalExecutor;
|
|
813
|
+
const lines = [];
|
|
814
|
+
lines.push('// Auto-generated canonical Manifest dispatcher.');
|
|
815
|
+
lines.push('// Generated from Manifest IR - DO NOT EDIT');
|
|
816
|
+
lines.push('// Canonical write path for governed commands. Per-command');
|
|
817
|
+
lines.push('// concrete routes (nextjs.command) are deprecated aliases');
|
|
818
|
+
lines.push('// that delegate here.');
|
|
819
|
+
if (useExternalExecutor) {
|
|
820
|
+
lines.push('//');
|
|
821
|
+
lines.push(`// executionMode = "externalExecutor": delegates to ${dispatcher.executorImportName}`);
|
|
822
|
+
lines.push(`// imported from "${dispatcher.executorImportPath}". The dispatcher does NOT`);
|
|
823
|
+
lines.push('// construct a Manifest runtime — the executor owns that.');
|
|
824
|
+
}
|
|
825
|
+
lines.push('');
|
|
826
|
+
lines.push('import type { NextRequest } from "next/server";');
|
|
827
|
+
lines.push(generateImport('{ manifestErrorResponse, manifestSuccessResponse, normalizeCommandResult }', responseImportPath));
|
|
828
|
+
if (useExternalExecutor) {
|
|
829
|
+
lines.push(generateImport(`{ ${dispatcher.executorImportName} }`, dispatcher.executorImportPath));
|
|
830
|
+
}
|
|
831
|
+
else if (useShared) {
|
|
832
|
+
lines.push(generateImport('{ getSharedRuntime }', options.sharedRuntimeImportPath));
|
|
833
|
+
}
|
|
834
|
+
else {
|
|
835
|
+
lines.push(generateImport('{ createManifestRuntime }', runtimeImportPath));
|
|
836
|
+
}
|
|
837
|
+
if (options.includeTenantFilter) {
|
|
838
|
+
if (options.tenantProvider) {
|
|
839
|
+
lines.push(generateImport(`{ ${options.tenantProvider.functionName} }`, options.tenantProvider.importPath));
|
|
840
|
+
}
|
|
841
|
+
else {
|
|
842
|
+
lines.push(generateImport('{ database }', options.databaseImportPath));
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
const authImport = generateAuthImport(options);
|
|
846
|
+
if (authImport)
|
|
847
|
+
lines.push(authImport);
|
|
848
|
+
lines.push('');
|
|
849
|
+
lines.push('// Next.js 15 App Router: dynamic route params are async.');
|
|
850
|
+
lines.push('// See https://nextjs.org/docs/app/api-reference/file-conventions/route');
|
|
851
|
+
lines.push('interface DispatcherContext {');
|
|
852
|
+
lines.push(' params: Promise<{ entity: string; command: string }>;');
|
|
853
|
+
lines.push('}');
|
|
854
|
+
lines.push('');
|
|
855
|
+
lines.push('export async function POST(request: NextRequest, ctx: DispatcherContext) {');
|
|
856
|
+
lines.push(' try {');
|
|
857
|
+
lines.push(generateAuthBody(options));
|
|
858
|
+
const tenantLookup = generateTenantLookup(options);
|
|
859
|
+
if (tenantLookup)
|
|
860
|
+
lines.push(tenantLookup);
|
|
861
|
+
lines.push('');
|
|
862
|
+
lines.push(' const body = await request.json();');
|
|
863
|
+
lines.push(' const { entity, command } = await ctx.params;');
|
|
864
|
+
lines.push('');
|
|
865
|
+
lines.push(' if (!entity || !command) {');
|
|
866
|
+
lines.push(' return manifestErrorResponse("Missing entity or command in route", 400);');
|
|
867
|
+
lines.push(' }');
|
|
868
|
+
lines.push('');
|
|
869
|
+
const tenantField = options.tenantIdProperty;
|
|
870
|
+
const tenantValueExpr = options.includeTenantFilter ? tenantField : '"__no_tenant__"';
|
|
871
|
+
// Goal step 4: extract instanceId universally when deriveInstanceId is on
|
|
872
|
+
// (default). Non-create commands (release, archive, update, ...) need
|
|
873
|
+
// this; create commands ignore it harmlessly. Body shape preference:
|
|
874
|
+
// body.instanceId, then body.id, then undefined.
|
|
875
|
+
if (dispatcher.deriveInstanceId) {
|
|
876
|
+
lines.push(' const instanceId = typeof body?.instanceId === "string"');
|
|
877
|
+
lines.push(' ? body.instanceId');
|
|
878
|
+
lines.push(' : typeof body?.id === "string"');
|
|
879
|
+
lines.push(' ? body.id');
|
|
880
|
+
lines.push(' : undefined;');
|
|
881
|
+
lines.push('');
|
|
882
|
+
}
|
|
883
|
+
if (useExternalExecutor) {
|
|
884
|
+
// externalExecutor mode: delegate to app-owned executor; do NOT construct
|
|
885
|
+
// a runtime inline. The executor receives full RuntimeContext + the
|
|
886
|
+
// raw entity/command keys parsed from the URL, plus the input body.
|
|
887
|
+
lines.push(` const result = await ${dispatcher.executorImportName}({`);
|
|
888
|
+
lines.push(' entityName: entity,');
|
|
889
|
+
lines.push(' commandName: command,');
|
|
890
|
+
lines.push(' input: body,');
|
|
891
|
+
if (dispatcher.deriveInstanceId) {
|
|
892
|
+
lines.push(' instanceId,');
|
|
893
|
+
}
|
|
894
|
+
lines.push(' context: {');
|
|
895
|
+
if (options.includeTenantFilter) {
|
|
896
|
+
lines.push(` tenantId: ${tenantValueExpr},`);
|
|
897
|
+
lines.push(` orgId: ${tenantValueExpr},`);
|
|
898
|
+
}
|
|
899
|
+
lines.push(' actorId: userId,');
|
|
900
|
+
lines.push(' requestId: request.headers.get("x-request-id") ?? undefined,');
|
|
901
|
+
lines.push(' source: "route",');
|
|
902
|
+
lines.push(` user: { id: userId, ${tenantField}: ${tenantValueExpr} },`);
|
|
903
|
+
lines.push(' },');
|
|
904
|
+
lines.push(' });');
|
|
905
|
+
}
|
|
906
|
+
else {
|
|
907
|
+
// inline mode: construct (or reuse the shared singleton) runtime and
|
|
908
|
+
// call runCommand. Typed RuntimeContext: tenantId/orgId/actorId/
|
|
909
|
+
// requestId/source. Legacy `user` shorthand preserved for downstream
|
|
910
|
+
// callers still reading it; new code MUST prefer actorId.
|
|
911
|
+
if (useShared) {
|
|
912
|
+
lines.push(' const runtime = await getSharedRuntime();');
|
|
913
|
+
lines.push(' runtime.replaceContext({');
|
|
914
|
+
}
|
|
915
|
+
else {
|
|
916
|
+
lines.push(' const runtime = await createManifestRuntime({');
|
|
917
|
+
}
|
|
918
|
+
if (options.includeTenantFilter) {
|
|
919
|
+
lines.push(` tenantId: ${tenantValueExpr},`);
|
|
920
|
+
lines.push(` orgId: ${tenantValueExpr},`);
|
|
921
|
+
}
|
|
922
|
+
lines.push(' actorId: userId,');
|
|
923
|
+
lines.push(' requestId: request.headers.get("x-request-id") ?? undefined,');
|
|
924
|
+
lines.push(' source: "route",');
|
|
925
|
+
lines.push(` user: { id: userId, ${tenantField}: ${tenantValueExpr} },`);
|
|
926
|
+
lines.push(' });');
|
|
927
|
+
lines.push('');
|
|
928
|
+
lines.push(' const result = await runtime.runCommand(command, body, {');
|
|
929
|
+
lines.push(' entityName: entity,');
|
|
930
|
+
if (dispatcher.deriveInstanceId) {
|
|
931
|
+
// runtime-engine.ts runCommand options accept instanceId — pass it
|
|
932
|
+
// through so non-create commands route to the correct instance.
|
|
933
|
+
lines.push(' instanceId,');
|
|
934
|
+
}
|
|
935
|
+
lines.push(' });');
|
|
936
|
+
}
|
|
937
|
+
lines.push('');
|
|
938
|
+
lines.push(' const normalized = normalizeCommandResult(entity, command, result);');
|
|
939
|
+
lines.push('');
|
|
940
|
+
lines.push(' if (!normalized.success) {');
|
|
941
|
+
lines.push(' const firstDiagnostic = normalized.diagnostics?.[0];');
|
|
942
|
+
lines.push(' const status = firstDiagnostic?.kind === "policy_denial" ? 403');
|
|
943
|
+
lines.push(' : firstDiagnostic?.kind === "guard_failure" ? 422');
|
|
944
|
+
lines.push(' : firstDiagnostic?.kind === "constraint_block" ? 422');
|
|
945
|
+
lines.push(' : 400;');
|
|
946
|
+
lines.push(' return manifestErrorResponse({ error: normalized.error, diagnostics: normalized.diagnostics }, status);');
|
|
947
|
+
lines.push(' }');
|
|
948
|
+
lines.push('');
|
|
949
|
+
lines.push(' return manifestSuccessResponse({ data: normalized.data, events: normalized.events, diagnostics: normalized.diagnostics });');
|
|
950
|
+
for (const errLine of emitRuntimeErrorReturn(options.unauthorizedStatus, 'Manifest dispatcher error:')) {
|
|
951
|
+
lines.push(errLine);
|
|
952
|
+
}
|
|
953
|
+
lines.push('}');
|
|
954
|
+
lines.push('');
|
|
955
|
+
return lines.join('\n');
|
|
956
|
+
}
|
|
957
|
+
/**
|
|
958
|
+
* Generate the SSE subscription route for a realtime entity.
|
|
959
|
+
* GET <appDir>/<entity>/subscribe/route.ts — streams runtime events whose
|
|
960
|
+
* subject.entity matches, over the shared singleton engine.
|
|
961
|
+
*/
|
|
962
|
+
_subscribe(ir, entityName, options) {
|
|
963
|
+
const diagnostics = [];
|
|
964
|
+
const opts = normalizeOptions(options);
|
|
965
|
+
const entity = ir.entities.find(e => e.name === entityName);
|
|
966
|
+
if (!entity) {
|
|
967
|
+
diagnostics.push({
|
|
968
|
+
severity: 'error',
|
|
969
|
+
code: 'ENTITY_NOT_FOUND',
|
|
970
|
+
message: `Entity "${entityName}" not found in IR. Available entities: ${ir.entities.map(e => e.name).join(', ')}`,
|
|
971
|
+
entity: entityName,
|
|
972
|
+
});
|
|
973
|
+
return { code: '', diagnostics };
|
|
974
|
+
}
|
|
975
|
+
if (entity.realtime !== true) {
|
|
976
|
+
diagnostics.push({
|
|
977
|
+
severity: 'info',
|
|
978
|
+
code: 'REALTIME_NOT_ENABLED',
|
|
979
|
+
message: `Entity "${entityName}" is not flagged \`realtime\` — skipping SSE subscription route.`,
|
|
980
|
+
entity: entityName,
|
|
981
|
+
});
|
|
982
|
+
return { code: '', diagnostics };
|
|
983
|
+
}
|
|
984
|
+
const lines = [];
|
|
985
|
+
lines.push(`// Auto-generated SSE subscription route for ${entity.name}.`);
|
|
986
|
+
lines.push('// Generated from Manifest IR - DO NOT EDIT');
|
|
987
|
+
lines.push('//');
|
|
988
|
+
lines.push(`// Streams runtime events for realtime entity "${entity.name}" over`);
|
|
989
|
+
lines.push('// Server-Sent Events. Uses the shared singleton engine so command');
|
|
990
|
+
lines.push('// routes and subscriptions observe the same event stream.');
|
|
991
|
+
lines.push('// Requires a long-lived, single-instance deployment');
|
|
992
|
+
lines.push('// (docs/spec/semantics.md § "Realtime Entities").');
|
|
993
|
+
lines.push('');
|
|
994
|
+
lines.push('import type { NextRequest } from "next/server";');
|
|
995
|
+
lines.push(generateImport('{ manifestErrorResponse }', opts.responseImportPath));
|
|
996
|
+
lines.push(generateImport('{ getSharedRuntime }', opts.sharedRuntimeImportPath));
|
|
997
|
+
const authImport = generateAuthImport(opts);
|
|
998
|
+
if (authImport)
|
|
999
|
+
lines.push(authImport);
|
|
1000
|
+
lines.push('');
|
|
1001
|
+
lines.push('export async function GET(request: NextRequest) {');
|
|
1002
|
+
lines.push(' try {');
|
|
1003
|
+
lines.push(generateAuthBody(opts));
|
|
1004
|
+
lines.push('');
|
|
1005
|
+
lines.push(' const runtime = await getSharedRuntime();');
|
|
1006
|
+
lines.push(' const encoder = new TextEncoder();');
|
|
1007
|
+
lines.push('');
|
|
1008
|
+
lines.push(' const stream = new ReadableStream({');
|
|
1009
|
+
lines.push(' start(controller) {');
|
|
1010
|
+
lines.push(` const unsubscribe = runtime.subscribe("${entity.name}", (event) => {`);
|
|
1011
|
+
lines.push(' controller.enqueue(encoder.encode(`data: ${JSON.stringify(event)}\\n\\n`));');
|
|
1012
|
+
lines.push(' });');
|
|
1013
|
+
lines.push(' const close = () => {');
|
|
1014
|
+
lines.push(' unsubscribe();');
|
|
1015
|
+
lines.push(' try {');
|
|
1016
|
+
lines.push(' controller.close();');
|
|
1017
|
+
lines.push(' } catch {');
|
|
1018
|
+
lines.push(' // stream already closed');
|
|
1019
|
+
lines.push(' }');
|
|
1020
|
+
lines.push(' };');
|
|
1021
|
+
lines.push(' request.signal.addEventListener("abort", close);');
|
|
1022
|
+
lines.push(' },');
|
|
1023
|
+
lines.push(' });');
|
|
1024
|
+
lines.push('');
|
|
1025
|
+
lines.push(' return new Response(stream, {');
|
|
1026
|
+
lines.push(' headers: {');
|
|
1027
|
+
lines.push(' "Content-Type": "text/event-stream",');
|
|
1028
|
+
lines.push(' "Cache-Control": "no-cache, no-transform",');
|
|
1029
|
+
lines.push(' Connection: "keep-alive",');
|
|
1030
|
+
lines.push(' },');
|
|
1031
|
+
lines.push(' });');
|
|
1032
|
+
for (const errLine of emitRuntimeErrorReturn(opts.unauthorizedStatus, `Error subscribing to ${entity.name}:`)) {
|
|
1033
|
+
lines.push(errLine);
|
|
1034
|
+
}
|
|
1035
|
+
lines.push('}');
|
|
1036
|
+
lines.push('');
|
|
1037
|
+
return { code: lines.join('\n'), diagnostics };
|
|
1038
|
+
}
|
|
1039
|
+
/**
|
|
1040
|
+
* Generate a typed client-side EventSource hook for a realtime entity,
|
|
1041
|
+
* with exponential-backoff reconnect.
|
|
1042
|
+
*/
|
|
1043
|
+
_subscriptionHook(ir, entityName, options) {
|
|
1044
|
+
const diagnostics = [];
|
|
1045
|
+
const entity = ir.entities.find(e => e.name === entityName);
|
|
1046
|
+
if (!entity) {
|
|
1047
|
+
diagnostics.push({
|
|
1048
|
+
severity: 'error',
|
|
1049
|
+
code: 'ENTITY_NOT_FOUND',
|
|
1050
|
+
message: `Entity "${entityName}" not found in IR. Available entities: ${ir.entities.map(e => e.name).join(', ')}`,
|
|
1051
|
+
entity: entityName,
|
|
1052
|
+
});
|
|
1053
|
+
return { code: '', diagnostics };
|
|
1054
|
+
}
|
|
1055
|
+
if (entity.realtime !== true) {
|
|
1056
|
+
diagnostics.push({
|
|
1057
|
+
severity: 'info',
|
|
1058
|
+
code: 'REALTIME_NOT_ENABLED',
|
|
1059
|
+
message: `Entity "${entityName}" is not flagged \`realtime\` — skipping subscription hook.`,
|
|
1060
|
+
entity: entityName,
|
|
1061
|
+
});
|
|
1062
|
+
return { code: '', diagnostics };
|
|
1063
|
+
}
|
|
1064
|
+
const name = entity.name;
|
|
1065
|
+
const subscribePath = `/api/${resolveRouteSegment(name, options)}/subscribe`;
|
|
1066
|
+
const code = `"use client";
|
|
1067
|
+
|
|
1068
|
+
// Auto-generated subscription hook for ${name}.
|
|
1069
|
+
// Generated from Manifest IR - DO NOT EDIT
|
|
1070
|
+
//
|
|
1071
|
+
// Subscribes to ${subscribePath} (SSE) with typed payloads and
|
|
1072
|
+
// exponential-backoff reconnect.
|
|
1073
|
+
|
|
1074
|
+
import { useEffect, useRef, useState } from "react";
|
|
1075
|
+
|
|
1076
|
+
/** Event payload delivered for ${name} subscriptions. */
|
|
1077
|
+
export interface ${name}SubscriptionEvent {
|
|
1078
|
+
name: string;
|
|
1079
|
+
channel: string;
|
|
1080
|
+
payload: unknown;
|
|
1081
|
+
timestamp: number;
|
|
1082
|
+
subject?: { entity?: string; command?: string; instanceId?: string };
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
export interface Use${name}SubscriptionOptions {
|
|
1086
|
+
/** Called for every event observed for ${name}. */
|
|
1087
|
+
onEvent?: (event: ${name}SubscriptionEvent) => void;
|
|
1088
|
+
/** Initial reconnect delay in ms (doubles per attempt). Default 1000. */
|
|
1089
|
+
initialRetryDelayMs?: number;
|
|
1090
|
+
/** Reconnect delay ceiling in ms. Default 30000. */
|
|
1091
|
+
maxRetryDelayMs?: number;
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
export function use${name}Subscription(options: Use${name}SubscriptionOptions = {}) {
|
|
1095
|
+
const { onEvent, initialRetryDelayMs = 1000, maxRetryDelayMs = 30000 } = options;
|
|
1096
|
+
const [connected, setConnected] = useState(false);
|
|
1097
|
+
const [lastEvent, setLastEvent] = useState<${name}SubscriptionEvent | null>(null);
|
|
1098
|
+
const onEventRef = useRef(onEvent);
|
|
1099
|
+
onEventRef.current = onEvent;
|
|
1100
|
+
|
|
1101
|
+
useEffect(() => {
|
|
1102
|
+
let source: EventSource | null = null;
|
|
1103
|
+
let retryTimer: ReturnType<typeof setTimeout> | null = null;
|
|
1104
|
+
let retryDelay = initialRetryDelayMs;
|
|
1105
|
+
let disposed = false;
|
|
1106
|
+
|
|
1107
|
+
const connect = () => {
|
|
1108
|
+
if (disposed) return;
|
|
1109
|
+
source = new EventSource("${subscribePath}");
|
|
1110
|
+
source.onopen = () => {
|
|
1111
|
+
setConnected(true);
|
|
1112
|
+
retryDelay = initialRetryDelayMs;
|
|
1113
|
+
};
|
|
1114
|
+
source.onmessage = (message) => {
|
|
1115
|
+
const event = JSON.parse(message.data) as ${name}SubscriptionEvent;
|
|
1116
|
+
setLastEvent(event);
|
|
1117
|
+
onEventRef.current?.(event);
|
|
1118
|
+
};
|
|
1119
|
+
source.onerror = () => {
|
|
1120
|
+
setConnected(false);
|
|
1121
|
+
source?.close();
|
|
1122
|
+
source = null;
|
|
1123
|
+
if (disposed) return;
|
|
1124
|
+
retryTimer = setTimeout(connect, retryDelay);
|
|
1125
|
+
retryDelay = Math.min(retryDelay * 2, maxRetryDelayMs);
|
|
1126
|
+
};
|
|
1127
|
+
};
|
|
1128
|
+
|
|
1129
|
+
connect();
|
|
1130
|
+
return () => {
|
|
1131
|
+
disposed = true;
|
|
1132
|
+
if (retryTimer) clearTimeout(retryTimer);
|
|
1133
|
+
source?.close();
|
|
1134
|
+
};
|
|
1135
|
+
}, [initialRetryDelayMs, maxRetryDelayMs]);
|
|
1136
|
+
|
|
1137
|
+
return { connected, lastEvent };
|
|
1138
|
+
}
|
|
1139
|
+
`;
|
|
1140
|
+
return { code, diagnostics };
|
|
1141
|
+
}
|
|
1142
|
+
/**
|
|
1143
|
+
* Generate the module-scoped singleton runtime accessor. Emitted only when
|
|
1144
|
+
* the IR contains at least one realtime entity — SSE routes and command
|
|
1145
|
+
* routes must share ONE engine instance for subscriptions to observe
|
|
1146
|
+
* command events (the event stream is per-engine and in-memory).
|
|
1147
|
+
*/
|
|
1148
|
+
_sharedRuntime(ir, options) {
|
|
1149
|
+
const diagnostics = [];
|
|
1150
|
+
if (!hasRealtimeEntities(ir)) {
|
|
1151
|
+
diagnostics.push({
|
|
1152
|
+
severity: 'info',
|
|
1153
|
+
code: 'REALTIME_NOT_ENABLED',
|
|
1154
|
+
message: 'No entity is flagged `realtime` — skipping shared runtime accessor.',
|
|
1155
|
+
});
|
|
1156
|
+
return { code: '', diagnostics };
|
|
1157
|
+
}
|
|
1158
|
+
const opts = normalizeOptions(options);
|
|
1159
|
+
const code = `// Auto-generated shared Manifest runtime accessor.
|
|
1160
|
+
// Generated from Manifest IR - DO NOT EDIT
|
|
1161
|
+
//
|
|
1162
|
+
// Realtime SSE requires command execution and subscriptions to observe the
|
|
1163
|
+
// SAME engine instance: the event stream is per-engine and in-memory. This
|
|
1164
|
+
// module memoizes ONE runtime per server process.
|
|
1165
|
+
//
|
|
1166
|
+
// Deployment constraint: requires a long-lived, single-instance Node server.
|
|
1167
|
+
// Serverless / multi-instance fan-out needs an external event bus (out of
|
|
1168
|
+
// scope). See docs/spec/semantics.md § "Realtime Entities".
|
|
1169
|
+
|
|
1170
|
+
import { createManifestRuntime } from "${opts.runtimeImportPath}";
|
|
1171
|
+
|
|
1172
|
+
type SharedRuntime = Awaited<ReturnType<typeof createManifestRuntime>>;
|
|
1173
|
+
|
|
1174
|
+
let sharedRuntimePromise: Promise<SharedRuntime> | null = null;
|
|
1175
|
+
|
|
1176
|
+
/**
|
|
1177
|
+
* Returns the module-scoped singleton runtime. Request handlers MUST set
|
|
1178
|
+
* per-request context via runtime.replaceContext() before runCommand.
|
|
1179
|
+
*/
|
|
1180
|
+
export function getSharedRuntime(): Promise<SharedRuntime> {
|
|
1181
|
+
if (!sharedRuntimePromise) {
|
|
1182
|
+
sharedRuntimePromise = createManifestRuntime({});
|
|
1183
|
+
}
|
|
1184
|
+
return sharedRuntimePromise;
|
|
1185
|
+
}
|
|
1186
|
+
`;
|
|
1187
|
+
return { code, diagnostics };
|
|
1188
|
+
}
|
|
1189
|
+
/**
|
|
1190
|
+
* Generate detail (getById) route handler for an entity.
|
|
1191
|
+
* Uses direct Prisma findUnique (bypassing runtime) for efficiency.
|
|
1192
|
+
*/
|
|
1193
|
+
_detail(ir, entityName, options) {
|
|
1194
|
+
const diagnostics = [];
|
|
1195
|
+
const opts = normalizeOptions(options);
|
|
1196
|
+
const entity = ir.entities.find(e => e.name === entityName);
|
|
1197
|
+
if (!entity) {
|
|
1198
|
+
diagnostics.push({
|
|
1199
|
+
severity: 'error',
|
|
1200
|
+
code: 'ENTITY_NOT_FOUND',
|
|
1201
|
+
message: `Entity "${entityName}" not found in IR. Available entities: ${ir.entities.map(e => e.name).join(', ')}`,
|
|
1202
|
+
entity: entityName,
|
|
1203
|
+
});
|
|
1204
|
+
return { code: '', diagnostics };
|
|
1205
|
+
}
|
|
1206
|
+
const code = this._generateDetailRoute(entity, opts);
|
|
1207
|
+
return { code, diagnostics };
|
|
1208
|
+
}
|
|
1209
|
+
/**
|
|
1210
|
+
* Generate GET route for an entity.
|
|
1211
|
+
* Uses direct Prisma query (bypassing runtime) for efficiency.
|
|
1212
|
+
*/
|
|
1213
|
+
_generateGetRoute(entity, options) {
|
|
1214
|
+
const { databaseImportPath, responseImportPath } = options;
|
|
1215
|
+
const delegateName = toLowerCamelCase(entity.name);
|
|
1216
|
+
const variableName = `${delegateName}s`;
|
|
1217
|
+
const lines = [];
|
|
1218
|
+
// Add comment explaining the design decision
|
|
1219
|
+
lines.push(`// Auto-generated Next.js API route for ${entity.name}`);
|
|
1220
|
+
lines.push('// Generated from Manifest IR - DO NOT EDIT');
|
|
1221
|
+
lines.push('');
|
|
1222
|
+
lines.push('import type { NextRequest } from "next/server";');
|
|
1223
|
+
if (options.tenantProvider) {
|
|
1224
|
+
lines.push(generateImport(`{ ${options.tenantProvider.functionName} }`, options.tenantProvider.importPath));
|
|
1225
|
+
lines.push(generateImport(`{ database }`, databaseImportPath));
|
|
1226
|
+
}
|
|
1227
|
+
else {
|
|
1228
|
+
lines.push(generateImport(`{ database }`, databaseImportPath));
|
|
1229
|
+
}
|
|
1230
|
+
lines.push(generateImport(`{ manifestErrorResponse, manifestSuccessResponse }`, responseImportPath));
|
|
1231
|
+
const authImport = generateAuthImport(options);
|
|
1232
|
+
if (authImport)
|
|
1233
|
+
lines.push(authImport);
|
|
1234
|
+
lines.push('');
|
|
1235
|
+
lines.push('export async function GET(request: NextRequest) {');
|
|
1236
|
+
lines.push(' try {');
|
|
1237
|
+
lines.push(generateAuthBody(options));
|
|
1238
|
+
lines.push(generateTenantLookup(options));
|
|
1239
|
+
lines.push('');
|
|
1240
|
+
if (options.readRoutes.directDbReads) {
|
|
1241
|
+
lines.push(generatePrismaQuery(entity, options));
|
|
1242
|
+
}
|
|
1243
|
+
else {
|
|
1244
|
+
// directDbReads disabled: emit a stub that returns an empty list and
|
|
1245
|
+
// a diagnostic telling the app to wire its own read source.
|
|
1246
|
+
lines.push(` // readRoutes.directDbReads = false: emit no inline Prisma call.`);
|
|
1247
|
+
lines.push(` // Wire your read source here and assign to \`${variableName}\`.`);
|
|
1248
|
+
lines.push(` const ${variableName}: unknown[] = [];`);
|
|
1249
|
+
}
|
|
1250
|
+
lines.push('');
|
|
1251
|
+
lines.push(` return manifestSuccessResponse({ ${variableName} });`);
|
|
1252
|
+
for (const errLine of emitRuntimeErrorReturn(options.unauthorizedStatus, `Error fetching ${variableName}:`)) {
|
|
1253
|
+
lines.push(errLine);
|
|
1254
|
+
}
|
|
1255
|
+
lines.push('}');
|
|
1256
|
+
lines.push('');
|
|
1257
|
+
return lines.join('\n');
|
|
1258
|
+
}
|
|
1259
|
+
/**
|
|
1260
|
+
* Generate GET detail route for a single entity instance.
|
|
1261
|
+
* Uses direct Prisma findUnique (bypassing runtime) for efficiency.
|
|
1262
|
+
*/
|
|
1263
|
+
_generateDetailRoute(entity, options) {
|
|
1264
|
+
const { databaseImportPath, responseImportPath } = options;
|
|
1265
|
+
const delegateName = toLowerCamelCase(entity.name);
|
|
1266
|
+
const accessorName = resolveDbAccessor(entity.name, options);
|
|
1267
|
+
const lines = [];
|
|
1268
|
+
lines.push(`// Auto-generated Next.js API detail route for ${entity.name}`);
|
|
1269
|
+
lines.push('// Generated from Manifest IR - DO NOT EDIT');
|
|
1270
|
+
lines.push('');
|
|
1271
|
+
lines.push('import type { NextRequest } from "next/server";');
|
|
1272
|
+
if (options.tenantProvider) {
|
|
1273
|
+
lines.push(generateImport(`{ ${options.tenantProvider.functionName} }`, options.tenantProvider.importPath));
|
|
1274
|
+
lines.push(generateImport(`{ database }`, databaseImportPath));
|
|
1275
|
+
}
|
|
1276
|
+
else {
|
|
1277
|
+
lines.push(generateImport(`{ database }`, databaseImportPath));
|
|
1278
|
+
}
|
|
1279
|
+
lines.push(generateImport(`{ manifestErrorResponse, manifestSuccessResponse }`, responseImportPath));
|
|
1280
|
+
const authImport = generateAuthImport(options);
|
|
1281
|
+
if (authImport)
|
|
1282
|
+
lines.push(authImport);
|
|
1283
|
+
lines.push('');
|
|
1284
|
+
lines.push('export async function GET(');
|
|
1285
|
+
lines.push(' request: NextRequest,');
|
|
1286
|
+
lines.push(' { params }: { params: Promise<{ id: string }> }');
|
|
1287
|
+
lines.push(') {');
|
|
1288
|
+
lines.push(' try {');
|
|
1289
|
+
lines.push(generateAuthBody(options));
|
|
1290
|
+
lines.push(generateTenantLookup(options));
|
|
1291
|
+
lines.push('');
|
|
1292
|
+
lines.push(' const { id } = await params;');
|
|
1293
|
+
lines.push('');
|
|
1294
|
+
// Build the where clause and pick the correct Prisma method.
|
|
1295
|
+
// Prisma 7: findUnique REQUIRES the where to be a unique constraint
|
|
1296
|
+
// (just `id` for typical schemas). Multi-field filters need findFirst.
|
|
1297
|
+
// The previous template emitted findUnique({ where: { id, tenantId,
|
|
1298
|
+
// deletedAt } }) which fails type-check on Prisma 7. Goal step 5.
|
|
1299
|
+
const whereConditions = ['id'];
|
|
1300
|
+
if (options.includeTenantFilter) {
|
|
1301
|
+
whereConditions.push(options.tenantIdProperty);
|
|
1302
|
+
}
|
|
1303
|
+
// Soft-delete filter only when the entity actually declares the column.
|
|
1304
|
+
if (options.includeSoftDeleteFilter && entityHasProperty(entity, options.deletedAtProperty)) {
|
|
1305
|
+
whereConditions.push(`${options.deletedAtProperty}: null`);
|
|
1306
|
+
}
|
|
1307
|
+
const isMultiField = whereConditions.length > 1;
|
|
1308
|
+
const prismaMethod = isMultiField ? 'findFirst' : 'findUnique';
|
|
1309
|
+
const whereClause = isMultiField
|
|
1310
|
+
? `where: {
|
|
1311
|
+
${whereConditions.join(',\n ')}
|
|
1312
|
+
},`
|
|
1313
|
+
: `where: { id },`;
|
|
1314
|
+
if (options.readRoutes.directDbReads) {
|
|
1315
|
+
lines.push(` // Using ${prismaMethod} — ${isMultiField ? 'multi-field filter (tenant/soft-delete) requires findFirst on Prisma 7+' : 'single id is a unique constraint'}.`);
|
|
1316
|
+
lines.push(` const ${delegateName} = await database.${accessorName}.${prismaMethod}({`);
|
|
1317
|
+
lines.push(` ${whereClause}`);
|
|
1318
|
+
lines.push(' });');
|
|
1319
|
+
}
|
|
1320
|
+
else {
|
|
1321
|
+
lines.push(` // readRoutes.directDbReads = false: emit no inline Prisma call.`);
|
|
1322
|
+
lines.push(` // Wire your read source here and assign to \`${delegateName}\`.`);
|
|
1323
|
+
lines.push(` const ${delegateName}: unknown = null;`);
|
|
1324
|
+
}
|
|
1325
|
+
lines.push('');
|
|
1326
|
+
lines.push(` if (!${delegateName}) {`);
|
|
1327
|
+
lines.push(` return manifestErrorResponse({ error: "${entity.name} not found", diagnostics: [] }, 404);`);
|
|
1328
|
+
lines.push(' }');
|
|
1329
|
+
lines.push('');
|
|
1330
|
+
lines.push(` return manifestSuccessResponse({ ${delegateName} });`);
|
|
1331
|
+
for (const errLine of emitRuntimeErrorReturn(options.unauthorizedStatus, `Error fetching ${delegateName}:`)) {
|
|
1332
|
+
lines.push(errLine);
|
|
1333
|
+
}
|
|
1334
|
+
lines.push('}');
|
|
1335
|
+
lines.push('');
|
|
1336
|
+
return lines.join('\n');
|
|
1337
|
+
}
|
|
1338
|
+
}
|
|
1339
|
+
//# sourceMappingURL=generator.js.map
|