@specverse/engine-realize 3.5.3

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.
Files changed (420) hide show
  1. package/assets/examples/09-api/ai-spec.yaml +194 -0
  2. package/assets/examples/09-api/converted.yaml +95 -0
  3. package/assets/examples/09-api/diagram-architecture.mmd +10 -0
  4. package/assets/examples/09-api/diagram-er.mmd +10 -0
  5. package/assets/examples/09-api/documentation.html +104 -0
  6. package/assets/examples/09-api/documentation.md +95 -0
  7. package/assets/examples/09-api/inferred-spec.yaml +420 -0
  8. package/assets/examples/09-api/openapi.json +61 -0
  9. package/assets/examples/10-api/README.md +216 -0
  10. package/assets/examples/10-api/ai-spec.yaml +194 -0
  11. package/assets/examples/10-api/converted.yaml +96 -0
  12. package/assets/examples/10-api/diagram-architecture.mmd +10 -0
  13. package/assets/examples/10-api/diagram-er.mmd +10 -0
  14. package/assets/examples/10-api/documentation.html +104 -0
  15. package/assets/examples/10-api/documentation.md +95 -0
  16. package/assets/examples/10-api/inferred-spec.yaml +7 -0
  17. package/assets/examples/10-api/metadata.yaml +89 -0
  18. package/assets/examples/10-api/openapi.json +61 -0
  19. package/assets/examples/10-api/package-integration-test.js +177 -0
  20. package/assets/examples/10-api/usage-example.js +323 -0
  21. package/assets/examples/10-api/usage-example.ts +363 -0
  22. package/assets/examples/10-api/workflow-test.js +113 -0
  23. package/assets/examples/manifests/01-simple-default-mappings.yaml +36 -0
  24. package/assets/examples/manifests/02-capability-mappings.yaml +55 -0
  25. package/assets/examples/manifests/03-hybrid-mappings.yaml +109 -0
  26. package/assets/examples/manifests/README.md +245 -0
  27. package/assets/examples/manifests/backend-only.yaml +43 -0
  28. package/assets/examples/manifests/blog-api.md +78 -0
  29. package/assets/examples/manifests/blog-api.specly +79 -0
  30. package/assets/examples/manifests/frontend-only.yaml +27 -0
  31. package/assets/examples/manifests/fullstack-app.yaml +44 -0
  32. package/assets/examples/manifests/fullstack-monorepo.yaml +62 -0
  33. package/assets/examples/validate-examples-with-expected-failures.cjs +328 -0
  34. package/assets/examples/validate-examples.cjs +225 -0
  35. package/assets/examples-decomposed/cloud-native-manifest.example.yaml +8 -0
  36. package/assets/examples-decomposed/cloud-native-manifest.md +379 -0
  37. package/assets/examples-decomposed/cloud-native-manifest.specly +60 -0
  38. package/assets/examples-decomposed/docker-compose-manifest.example.yaml +8 -0
  39. package/assets/examples-decomposed/docker-compose-manifest.md +326 -0
  40. package/assets/examples-decomposed/docker-compose-manifest.specly +40 -0
  41. package/assets/examples-decomposed/kubernetes-deployment-manifest.example.yaml +8 -0
  42. package/assets/examples-decomposed/kubernetes-deployment-manifest.md +237 -0
  43. package/assets/examples-decomposed/kubernetes-deployment-manifest.specly +41 -0
  44. package/assets/templates/README.md +559 -0
  45. package/assets/templates/TEMPLATE-ENHANCEMENTS-V33.md +462 -0
  46. package/assets/templates/backend-only/CLAUDE.md +73 -0
  47. package/assets/templates/backend-only/README.md +197 -0
  48. package/assets/templates/backend-only/deployments/README.md +149 -0
  49. package/assets/templates/backend-only/deployments/development.specly +53 -0
  50. package/assets/templates/backend-only/deployments/production.specly +87 -0
  51. package/assets/templates/backend-only/docs/README.md +50 -0
  52. package/assets/templates/backend-only/docs/api/README.md +7 -0
  53. package/assets/templates/backend-only/docs/diagrams/README.md +85 -0
  54. package/assets/templates/backend-only/docs/example-documentation-template.md +269 -0
  55. package/assets/templates/backend-only/docs/guides/README.md +15 -0
  56. package/assets/templates/backend-only/dot.env.example +18 -0
  57. package/assets/templates/backend-only/generated/README.md +56 -0
  58. package/assets/templates/backend-only/generated/code/integration-test.template.js +320 -0
  59. package/assets/templates/backend-only/generated/code/package.json.template +34 -0
  60. package/assets/templates/backend-only/generated/docs/README.md +49 -0
  61. package/assets/templates/backend-only/gitignore +54 -0
  62. package/assets/templates/backend-only/manifests/README.md +72 -0
  63. package/assets/templates/backend-only/manifests/docker-compose.specly +91 -0
  64. package/assets/templates/backend-only/manifests/implementation.yaml +100 -0
  65. package/assets/templates/backend-only/manifests/kubernetes.specly +140 -0
  66. package/assets/templates/backend-only/package.json +59 -0
  67. package/assets/templates/backend-only/scripts/test-all.sh +160 -0
  68. package/assets/templates/backend-only/scripts/test-generated-code.sh +165 -0
  69. package/assets/templates/backend-only/specs/main.specly +67 -0
  70. package/assets/templates/default/CLAUDE.md +141 -0
  71. package/assets/templates/default/README.md +404 -0
  72. package/assets/templates/default/deployments/README.md +149 -0
  73. package/assets/templates/default/deployments/development.specly +53 -0
  74. package/assets/templates/default/deployments/production.specly +87 -0
  75. package/assets/templates/default/docs/README.md +50 -0
  76. package/assets/templates/default/docs/api/README.md +7 -0
  77. package/assets/templates/default/docs/diagrams/README.md +85 -0
  78. package/assets/templates/default/docs/example-documentation-template.md +269 -0
  79. package/assets/templates/default/docs/guides/README.md +15 -0
  80. package/assets/templates/default/dot.env.example +18 -0
  81. package/assets/templates/default/generated/README.md +56 -0
  82. package/assets/templates/default/generated/code/integration-test.template.js +320 -0
  83. package/assets/templates/default/generated/code/package.json.template +34 -0
  84. package/assets/templates/default/generated/docs/README.md +49 -0
  85. package/assets/templates/default/gitignore +54 -0
  86. package/assets/templates/default/manifests/README.md +72 -0
  87. package/assets/templates/default/manifests/docker-compose.specly +91 -0
  88. package/assets/templates/default/manifests/implementation.yaml +176 -0
  89. package/assets/templates/default/manifests/kubernetes.specly +140 -0
  90. package/assets/templates/default/package.json +61 -0
  91. package/assets/templates/default/scripts/test-all.sh +160 -0
  92. package/assets/templates/default/scripts/test-generated-code.sh +165 -0
  93. package/assets/templates/default/specs/main.specly +67 -0
  94. package/assets/templates/frontend-only/CLAUDE.md +75 -0
  95. package/assets/templates/frontend-only/README.md +231 -0
  96. package/assets/templates/frontend-only/deployments/README.md +149 -0
  97. package/assets/templates/frontend-only/deployments/development.specly +53 -0
  98. package/assets/templates/frontend-only/deployments/production.specly +87 -0
  99. package/assets/templates/frontend-only/docs/README.md +50 -0
  100. package/assets/templates/frontend-only/docs/api/README.md +7 -0
  101. package/assets/templates/frontend-only/docs/diagrams/README.md +85 -0
  102. package/assets/templates/frontend-only/docs/example-documentation-template.md +269 -0
  103. package/assets/templates/frontend-only/docs/guides/README.md +15 -0
  104. package/assets/templates/frontend-only/dot.env.example +18 -0
  105. package/assets/templates/frontend-only/generated/README.md +56 -0
  106. package/assets/templates/frontend-only/generated/code/integration-test.template.js +320 -0
  107. package/assets/templates/frontend-only/generated/code/package.json.template +34 -0
  108. package/assets/templates/frontend-only/generated/docs/README.md +49 -0
  109. package/assets/templates/frontend-only/gitignore +54 -0
  110. package/assets/templates/frontend-only/manifests/README.md +72 -0
  111. package/assets/templates/frontend-only/manifests/docker-compose.specly +91 -0
  112. package/assets/templates/frontend-only/manifests/implementation.yaml +58 -0
  113. package/assets/templates/frontend-only/manifests/kubernetes.specly +140 -0
  114. package/assets/templates/frontend-only/package.json +59 -0
  115. package/assets/templates/frontend-only/scripts/test-all.sh +160 -0
  116. package/assets/templates/frontend-only/scripts/test-generated-code.sh +165 -0
  117. package/assets/templates/frontend-only/specs/main.specly +57 -0
  118. package/assets/templates/full-stack/AI-GUIDE.md +60 -0
  119. package/assets/templates/full-stack/CLAUDE.md +141 -0
  120. package/assets/templates/full-stack/README.md +382 -0
  121. package/assets/templates/full-stack/archive/AI-GUIDE-legacy.md +392 -0
  122. package/assets/templates/full-stack/deployments/README.md +149 -0
  123. package/assets/templates/full-stack/deployments/development.specly +53 -0
  124. package/assets/templates/full-stack/deployments/production.specly +87 -0
  125. package/assets/templates/full-stack/docs/README.md +51 -0
  126. package/assets/templates/full-stack/docs/api/README.md +7 -0
  127. package/assets/templates/full-stack/docs/diagrams/README.md +85 -0
  128. package/assets/templates/full-stack/docs/example-documentation-template.md +269 -0
  129. package/assets/templates/full-stack/docs/guides/README.md +15 -0
  130. package/assets/templates/full-stack/generated/README.md +56 -0
  131. package/assets/templates/full-stack/generated/code/integration-test.template.js +320 -0
  132. package/assets/templates/full-stack/generated/code/package.json.template +34 -0
  133. package/assets/templates/full-stack/generated/docs/README.md +49 -0
  134. package/assets/templates/full-stack/gitignore +54 -0
  135. package/assets/templates/full-stack/manifests/README.md +72 -0
  136. package/assets/templates/full-stack/manifests/docker-compose.specly +91 -0
  137. package/assets/templates/full-stack/manifests/implementation.yaml +155 -0
  138. package/assets/templates/full-stack/manifests/kubernetes.specly +140 -0
  139. package/assets/templates/full-stack/package.json +45 -0
  140. package/assets/templates/full-stack/scripts/test-all.sh +160 -0
  141. package/assets/templates/full-stack/scripts/test-generated-code.sh +165 -0
  142. package/assets/templates/full-stack/specs/example-v33.specly +297 -0
  143. package/assets/templates/full-stack/specs/main-simple.specly +73 -0
  144. package/assets/templates/full-stack/specs/main.specly +408 -0
  145. package/dist/engines/code-generator.d.ts +86 -0
  146. package/dist/engines/code-generator.d.ts.map +1 -0
  147. package/dist/engines/code-generator.js +159 -0
  148. package/dist/engines/code-generator.js.map +1 -0
  149. package/dist/engines/engine-registry.d.ts +94 -0
  150. package/dist/engines/engine-registry.d.ts.map +1 -0
  151. package/dist/engines/engine-registry.js +163 -0
  152. package/dist/engines/engine-registry.js.map +1 -0
  153. package/dist/engines/index.d.ts +10 -0
  154. package/dist/engines/index.d.ts.map +1 -0
  155. package/dist/engines/index.js +12 -0
  156. package/dist/engines/index.js.map +1 -0
  157. package/dist/engines/typescript-engine.d.ts +74 -0
  158. package/dist/engines/typescript-engine.d.ts.map +1 -0
  159. package/dist/engines/typescript-engine.js +288 -0
  160. package/dist/engines/typescript-engine.js.map +1 -0
  161. package/dist/generators/index.d.ts +11 -0
  162. package/dist/generators/index.d.ts.map +1 -0
  163. package/dist/generators/index.js +11 -0
  164. package/dist/generators/index.js.map +1 -0
  165. package/dist/index.d.ts +48 -0
  166. package/dist/index.d.ts.map +1 -0
  167. package/dist/index.js +434 -0
  168. package/dist/index.js.map +1 -0
  169. package/dist/library/index.d.ts +12 -0
  170. package/dist/library/index.d.ts.map +1 -0
  171. package/dist/library/index.js +15 -0
  172. package/dist/library/index.js.map +1 -0
  173. package/dist/library/library.d.ts +132 -0
  174. package/dist/library/library.d.ts.map +1 -0
  175. package/dist/library/library.js +343 -0
  176. package/dist/library/library.js.map +1 -0
  177. package/dist/library/loader.d.ts +73 -0
  178. package/dist/library/loader.d.ts.map +1 -0
  179. package/dist/library/loader.js +150 -0
  180. package/dist/library/loader.js.map +1 -0
  181. package/dist/library/resolver.d.ts +104 -0
  182. package/dist/library/resolver.d.ts.map +1 -0
  183. package/dist/library/resolver.js +299 -0
  184. package/dist/library/resolver.js.map +1 -0
  185. package/dist/library/validator.d.ts +65 -0
  186. package/dist/library/validator.d.ts.map +1 -0
  187. package/dist/library/validator.js +203 -0
  188. package/dist/library/validator.js.map +1 -0
  189. package/dist/types/index.d.ts +7 -0
  190. package/dist/types/index.d.ts.map +1 -0
  191. package/dist/types/index.js +7 -0
  192. package/dist/types/index.js.map +1 -0
  193. package/dist/types/instance-factory.d.ts +289 -0
  194. package/dist/types/instance-factory.d.ts.map +1 -0
  195. package/dist/types/instance-factory.js +8 -0
  196. package/dist/types/instance-factory.js.map +1 -0
  197. package/dist/types/unified-mappings.d.ts +163 -0
  198. package/dist/types/unified-mappings.d.ts.map +1 -0
  199. package/dist/types/unified-mappings.js +110 -0
  200. package/dist/types/unified-mappings.js.map +1 -0
  201. package/dist/utils/ai-spec-loader.d.ts +77 -0
  202. package/dist/utils/ai-spec-loader.d.ts.map +1 -0
  203. package/dist/utils/ai-spec-loader.js +138 -0
  204. package/dist/utils/ai-spec-loader.js.map +1 -0
  205. package/dist/utils/index.d.ts +9 -0
  206. package/dist/utils/index.d.ts.map +1 -0
  207. package/dist/utils/index.js +9 -0
  208. package/dist/utils/index.js.map +1 -0
  209. package/dist/utils/manifest-loader.d.ts +107 -0
  210. package/dist/utils/manifest-loader.d.ts.map +1 -0
  211. package/dist/utils/manifest-loader.js +168 -0
  212. package/dist/utils/manifest-loader.js.map +1 -0
  213. package/dist/utils/mapping-migration.d.ts +53 -0
  214. package/dist/utils/mapping-migration.d.ts.map +1 -0
  215. package/dist/utils/mapping-migration.js +194 -0
  216. package/dist/utils/mapping-migration.js.map +1 -0
  217. package/libs/instance-factories/CURVED-INTERFACE.md +278 -0
  218. package/libs/instance-factories/README.md +433 -0
  219. package/libs/instance-factories/applications/generic-app.yaml +52 -0
  220. package/libs/instance-factories/applications/react-app.yaml +186 -0
  221. package/libs/instance-factories/applications/templates/generic/backend-env-generator.ts +31 -0
  222. package/libs/instance-factories/applications/templates/generic/backend-package-json-generator.ts +80 -0
  223. package/libs/instance-factories/applications/templates/generic/backend-tsconfig-generator.ts +69 -0
  224. package/libs/instance-factories/applications/templates/generic/main-generator.ts +308 -0
  225. package/libs/instance-factories/applications/templates/react/_view-components-source.ts +555 -0
  226. package/libs/instance-factories/applications/templates/react/api-client-generator.ts +436 -0
  227. package/libs/instance-factories/applications/templates/react/api-types-generator.ts +153 -0
  228. package/libs/instance-factories/applications/templates/react/app-tsx-generator.ts +94 -0
  229. package/libs/instance-factories/applications/templates/react/env-example-generator.ts +24 -0
  230. package/libs/instance-factories/applications/templates/react/field-helpers-generator.ts +106 -0
  231. package/libs/instance-factories/applications/templates/react/gitignore-generator.ts +38 -0
  232. package/libs/instance-factories/applications/templates/react/index-css-generator.ts +85 -0
  233. package/libs/instance-factories/applications/templates/react/index-html-generator.ts +30 -0
  234. package/libs/instance-factories/applications/templates/react/main-tsx-generator.ts +34 -0
  235. package/libs/instance-factories/applications/templates/react/package-json-generator.ts +54 -0
  236. package/libs/instance-factories/applications/templates/react/pattern-adapter-generator.ts +179 -0
  237. package/libs/instance-factories/applications/templates/react/react-pattern-adapter.tsx +1347 -0
  238. package/libs/instance-factories/applications/templates/react/relationship-field-generator.ts +150 -0
  239. package/libs/instance-factories/applications/templates/react/tailwind-adapter-generator.ts +704 -0
  240. package/libs/instance-factories/applications/templates/react/tailwind-adapter-wrapper-generator.ts +84 -0
  241. package/libs/instance-factories/applications/templates/react/tsconfig-generator.ts +35 -0
  242. package/libs/instance-factories/applications/templates/react/use-api-hooks-generator.ts +121 -0
  243. package/libs/instance-factories/applications/templates/react/view-dashboard-generator.ts +150 -0
  244. package/libs/instance-factories/applications/templates/react/view-detail-generator.ts +150 -0
  245. package/libs/instance-factories/applications/templates/react/view-form-generator.ts +362 -0
  246. package/libs/instance-factories/applications/templates/react/view-list-generator.ts +98 -0
  247. package/libs/instance-factories/applications/templates/react/view-router-generator.ts +89 -0
  248. package/libs/instance-factories/applications/templates/react/vite-config-generator.ts +49 -0
  249. package/libs/instance-factories/archived/fastify-prisma.yaml +104 -0
  250. package/libs/instance-factories/cli/commander-js.yaml +55 -0
  251. package/libs/instance-factories/cli/templates/commander/cli-entry-generator.d.ts +12 -0
  252. package/libs/instance-factories/cli/templates/commander/cli-entry-generator.d.ts.map +1 -0
  253. package/libs/instance-factories/cli/templates/commander/cli-entry-generator.js +115 -0
  254. package/libs/instance-factories/cli/templates/commander/cli-entry-generator.js.map +1 -0
  255. package/libs/instance-factories/cli/templates/commander/cli-entry-generator.ts +145 -0
  256. package/libs/instance-factories/cli/templates/commander/command-generator.d.ts +14 -0
  257. package/libs/instance-factories/cli/templates/commander/command-generator.d.ts.map +1 -0
  258. package/libs/instance-factories/cli/templates/commander/command-generator.js +182 -0
  259. package/libs/instance-factories/cli/templates/commander/command-generator.js.map +1 -0
  260. package/libs/instance-factories/cli/templates/commander/command-generator.ts +992 -0
  261. package/libs/instance-factories/communication/event-emitter.yaml +56 -0
  262. package/libs/instance-factories/communication/rabbitmq-events.yaml +87 -0
  263. package/libs/instance-factories/communication/templates/eventemitter/bus-generator.ts +93 -0
  264. package/libs/instance-factories/communication/templates/eventemitter/publisher-generator.ts +117 -0
  265. package/libs/instance-factories/communication/templates/eventemitter/subscriber-generator.ts +101 -0
  266. package/libs/instance-factories/controllers/fastify.yaml +127 -0
  267. package/libs/instance-factories/controllers/templates/fastify/meta-routes-generator.ts +103 -0
  268. package/libs/instance-factories/controllers/templates/fastify/routes-generator.ts +389 -0
  269. package/libs/instance-factories/controllers/templates/fastify/server-generator.ts +76 -0
  270. package/libs/instance-factories/infrastructure/docker-k8s.yaml +61 -0
  271. package/libs/instance-factories/infrastructure/templates/docker-k8s/infrastructure-generator.ts +46 -0
  272. package/libs/instance-factories/orms/prisma.yaml +89 -0
  273. package/libs/instance-factories/orms/templates/prisma/schema-generator.ts +563 -0
  274. package/libs/instance-factories/orms/templates/prisma/services-generator.ts +408 -0
  275. package/libs/instance-factories/scaffolding/generic-scaffold.yaml +65 -0
  276. package/libs/instance-factories/scaffolding/templates/generic/env-example-generator.ts +73 -0
  277. package/libs/instance-factories/scaffolding/templates/generic/env-generator.ts +85 -0
  278. package/libs/instance-factories/scaffolding/templates/generic/gitignore-generator.ts +69 -0
  279. package/libs/instance-factories/scaffolding/templates/generic/package-json-generator.ts +176 -0
  280. package/libs/instance-factories/scaffolding/templates/generic/readme-generator.ts +207 -0
  281. package/libs/instance-factories/scaffolding/templates/generic/tsconfig-generator.ts +78 -0
  282. package/libs/instance-factories/scaffolding/templates/generic/tsconfig-react-generator.ts +41 -0
  283. package/libs/instance-factories/sdks/python-sdk.yaml +66 -0
  284. package/libs/instance-factories/sdks/templates/python/sdk-generator.ts +50 -0
  285. package/libs/instance-factories/sdks/templates/typescript/sdk-generator.ts +49 -0
  286. package/libs/instance-factories/sdks/typescript-sdk.yaml +59 -0
  287. package/libs/instance-factories/services/prisma-services.yaml +71 -0
  288. package/libs/instance-factories/services/templates/prisma/behavior-generator.ts +303 -0
  289. package/libs/instance-factories/services/templates/prisma/controller-generator.ts +532 -0
  290. package/libs/instance-factories/services/templates/prisma/service-generator.ts +315 -0
  291. package/libs/instance-factories/shared/path-resolver.ts +111 -0
  292. package/libs/instance-factories/storage/mongodb.yaml +79 -0
  293. package/libs/instance-factories/storage/postgresql.yaml +75 -0
  294. package/libs/instance-factories/storage/redis.yaml +79 -0
  295. package/libs/instance-factories/storage/templates/mongodb/config-generator.ts +15 -0
  296. package/libs/instance-factories/storage/templates/mongodb/docker-generator.ts +18 -0
  297. package/libs/instance-factories/storage/templates/postgresql/config-generator.ts +54 -0
  298. package/libs/instance-factories/storage/templates/postgresql/docker-generator.ts +55 -0
  299. package/libs/instance-factories/storage/templates/redis/config-generator.ts +16 -0
  300. package/libs/instance-factories/storage/templates/redis/docker-generator.ts +18 -0
  301. package/libs/instance-factories/test-generation.ts +192 -0
  302. package/libs/instance-factories/testing/templates/vitest/tests-generator.ts +51 -0
  303. package/libs/instance-factories/testing/vitest-tests.yaml +63 -0
  304. package/libs/instance-factories/tools/templates/mcp/mcp-server-generator.ts +136 -0
  305. package/libs/instance-factories/tools/templates/mcp/static/docs/DEPLOYMENT_GUIDE.md +630 -0
  306. package/libs/instance-factories/tools/templates/mcp/static/docs/HYBRID_RESOURCE_SYSTEM.md +330 -0
  307. package/libs/instance-factories/tools/templates/mcp/static/docs/deployments/EXTENSION_DEPLOYMENT.md +552 -0
  308. package/libs/instance-factories/tools/templates/mcp/static/docs/deployments/LOCAL_DEPLOYMENT.md +164 -0
  309. package/libs/instance-factories/tools/templates/mcp/static/docs/deployments/WEB_DEPLOYMENT.md +247 -0
  310. package/libs/instance-factories/tools/templates/mcp/static/package.json +92 -0
  311. package/libs/instance-factories/tools/templates/mcp/static/scripts/build-enterprise.js +284 -0
  312. package/libs/instance-factories/tools/templates/mcp/static/scripts/build-extension.js +139 -0
  313. package/libs/instance-factories/tools/templates/mcp/static/scripts/build-local.js +74 -0
  314. package/libs/instance-factories/tools/templates/mcp/static/scripts/build-web.js +156 -0
  315. package/libs/instance-factories/tools/templates/mcp/static/scripts/copy-canonical-files.js +41 -0
  316. package/libs/instance-factories/tools/templates/mcp/static/scripts/test-deployments.js +259 -0
  317. package/libs/instance-factories/tools/templates/mcp/static/scripts/test-hybrid-resources.js +231 -0
  318. package/libs/instance-factories/tools/templates/mcp/static/scripts/test-hybrid-simple.js +196 -0
  319. package/libs/instance-factories/tools/templates/mcp/static/src/controllers/MCPServerController.ts +293 -0
  320. package/libs/instance-factories/tools/templates/mcp/static/src/events/EventEmitter.ts +90 -0
  321. package/libs/instance-factories/tools/templates/mcp/static/src/index.ts +24 -0
  322. package/libs/instance-factories/tools/templates/mcp/static/src/interfaces/ResourceProvider.ts +15 -0
  323. package/libs/instance-factories/tools/templates/mcp/static/src/models/LibrarySuggestion.ts +106 -0
  324. package/libs/instance-factories/tools/templates/mcp/static/src/models/SpecVerseResource.ts +75 -0
  325. package/libs/instance-factories/tools/templates/mcp/static/src/server/mcp-server.ts +239 -0
  326. package/libs/instance-factories/tools/templates/mcp/static/src/services/CLIProxyService.ts +1501 -0
  327. package/libs/instance-factories/tools/templates/mcp/static/src/services/EmbeddedResourcesAdapter.ts +211 -0
  328. package/libs/instance-factories/tools/templates/mcp/static/src/services/EntityModuleService.ts +308 -0
  329. package/libs/instance-factories/tools/templates/mcp/static/src/services/HybridResourcesProvider.ts +210 -0
  330. package/libs/instance-factories/tools/templates/mcp/static/src/services/LibraryToolsService.ts +356 -0
  331. package/libs/instance-factories/tools/templates/mcp/static/src/services/OrchestratorBridge.ts +524 -0
  332. package/libs/instance-factories/tools/templates/mcp/static/src/services/OrchestratorToolsService.ts +530 -0
  333. package/libs/instance-factories/tools/templates/mcp/static/src/services/PromptToolsService.ts +594 -0
  334. package/libs/instance-factories/tools/templates/mcp/static/src/services/ResourcesProviderService.ts +170 -0
  335. package/libs/instance-factories/tools/templates/mcp/static/src/tests/unit/CLIProxyService.init.test.ts +544 -0
  336. package/libs/instance-factories/tools/templates/mcp/static/src/tests/unit/CLIProxyService.test.ts +189 -0
  337. package/libs/instance-factories/tools/templates/mcp/static/src/tests/unit/ResourcesProviderService.test.ts +89 -0
  338. package/libs/instance-factories/tools/templates/mcp/static/src/types/index.ts +110 -0
  339. package/libs/instance-factories/tools/templates/mcp/static/tsconfig.json +28 -0
  340. package/libs/instance-factories/tools/templates/vscode/static/extension.ts +1195 -0
  341. package/libs/instance-factories/tools/templates/vscode/static/language-configuration.json +34 -0
  342. package/libs/instance-factories/tools/templates/vscode/static/schemas/specverse-v3-schema.json +4279 -0
  343. package/libs/instance-factories/tools/templates/vscode/static/syntaxes/specverse.tmLanguage.json +138 -0
  344. package/libs/instance-factories/tools/templates/vscode/static/themes/README.md +74 -0
  345. package/libs/instance-factories/tools/templates/vscode/static/themes/complete-specverse-colors.json +122 -0
  346. package/libs/instance-factories/tools/templates/vscode/static/themes/specverse-basic-theme.json +65 -0
  347. package/libs/instance-factories/tools/templates/vscode/static/themes/specverse-complete-theme.json +123 -0
  348. package/libs/instance-factories/tools/templates/vscode/static/themes/specverse-theme-colors.json +64 -0
  349. package/libs/instance-factories/tools/templates/vscode/vscode-extension-generator.ts +214 -0
  350. package/libs/instance-factories/validation/templates/zod/validation-generator.ts +46 -0
  351. package/libs/instance-factories/validation/zod.yaml +56 -0
  352. package/libs/instance-factories/views/index.d.ts +13 -0
  353. package/libs/instance-factories/views/index.d.ts.map +1 -0
  354. package/libs/instance-factories/views/index.js +18 -0
  355. package/libs/instance-factories/views/index.js.map +1 -0
  356. package/libs/instance-factories/views/index.ts +45 -0
  357. package/libs/instance-factories/views/react-components.yaml +129 -0
  358. package/libs/instance-factories/views/templates/ARCHITECTURE.md +198 -0
  359. package/libs/instance-factories/views/templates/react/adapters/antd-adapter.ts +869 -0
  360. package/libs/instance-factories/views/templates/react/adapters/mui-adapter.ts +953 -0
  361. package/libs/instance-factories/views/templates/react/adapters/shadcn-adapter.ts +806 -0
  362. package/libs/instance-factories/views/templates/react/app-generator.ts +55 -0
  363. package/libs/instance-factories/views/templates/react/components-generator.ts +391 -0
  364. package/libs/instance-factories/views/templates/react/forms-generator.ts +343 -0
  365. package/libs/instance-factories/views/templates/react/frontend-package-json-generator.ts +54 -0
  366. package/libs/instance-factories/views/templates/react/hooks-generator.ts +122 -0
  367. package/libs/instance-factories/views/templates/react/index-css-generator.ts +209 -0
  368. package/libs/instance-factories/views/templates/react/index-html-generator.ts +34 -0
  369. package/libs/instance-factories/views/templates/react/main-tsx-generator.ts +29 -0
  370. package/libs/instance-factories/views/templates/react/react-component-generator.d.ts +152 -0
  371. package/libs/instance-factories/views/templates/react/react-component-generator.d.ts.map +1 -0
  372. package/libs/instance-factories/views/templates/react/react-component-generator.js +398 -0
  373. package/libs/instance-factories/views/templates/react/react-component-generator.js.map +1 -0
  374. package/libs/instance-factories/views/templates/react/react-component-generator.ts +533 -0
  375. package/libs/instance-factories/views/templates/react/router-generator.ts +197 -0
  376. package/libs/instance-factories/views/templates/react/router-generic-generator.ts +103 -0
  377. package/libs/instance-factories/views/templates/react/spec-json-generator.ts +17 -0
  378. package/libs/instance-factories/views/templates/react/types-generator.ts +76 -0
  379. package/libs/instance-factories/views/templates/react/views-metadata-generator.ts +42 -0
  380. package/libs/instance-factories/views/templates/react/vite-config-generator.ts +38 -0
  381. package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.d.ts.map +1 -0
  382. package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.js.map +1 -0
  383. package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.ts +474 -0
  384. package/libs/instance-factories/views/templates/shared/__tests__/composite-patterns.test.ts +242 -0
  385. package/libs/instance-factories/views/templates/shared/adapter-types.d.ts +77 -0
  386. package/libs/instance-factories/views/templates/shared/adapter-types.d.ts.map +1 -0
  387. package/libs/instance-factories/views/templates/shared/adapter-types.js +47 -0
  388. package/libs/instance-factories/views/templates/shared/adapter-types.js.map +1 -0
  389. package/libs/instance-factories/views/templates/shared/adapter-types.ts +142 -0
  390. package/libs/instance-factories/views/templates/shared/atomic-components-registry.d.ts +63 -0
  391. package/libs/instance-factories/views/templates/shared/atomic-components-registry.d.ts.map +1 -0
  392. package/libs/instance-factories/views/templates/shared/atomic-components-registry.js +822 -0
  393. package/libs/instance-factories/views/templates/shared/atomic-components-registry.js.map +1 -0
  394. package/libs/instance-factories/views/templates/shared/atomic-components-registry.ts +908 -0
  395. package/libs/instance-factories/views/templates/shared/base-generator.d.ts +247 -0
  396. package/libs/instance-factories/views/templates/shared/base-generator.d.ts.map +1 -0
  397. package/libs/instance-factories/views/templates/shared/base-generator.js +363 -0
  398. package/libs/instance-factories/views/templates/shared/base-generator.js.map +1 -0
  399. package/libs/instance-factories/views/templates/shared/base-generator.ts +608 -0
  400. package/libs/instance-factories/views/templates/shared/component-metadata.d.ts +254 -0
  401. package/libs/instance-factories/views/templates/shared/component-metadata.d.ts.map +1 -0
  402. package/libs/instance-factories/views/templates/shared/component-metadata.js +602 -0
  403. package/libs/instance-factories/views/templates/shared/component-metadata.js.map +1 -0
  404. package/libs/instance-factories/views/templates/shared/component-metadata.ts +803 -0
  405. package/libs/instance-factories/views/templates/shared/composite-pattern-types.ts +250 -0
  406. package/libs/instance-factories/views/templates/shared/composite-patterns.ts +535 -0
  407. package/libs/instance-factories/views/templates/shared/index.ts +68 -0
  408. package/libs/instance-factories/views/templates/shared/pattern-validator.ts +279 -0
  409. package/libs/instance-factories/views/templates/shared/property-mapper.d.ts +149 -0
  410. package/libs/instance-factories/views/templates/shared/property-mapper.d.ts.map +1 -0
  411. package/libs/instance-factories/views/templates/shared/property-mapper.js +580 -0
  412. package/libs/instance-factories/views/templates/shared/property-mapper.js.map +1 -0
  413. package/libs/instance-factories/views/templates/shared/property-mapper.ts +700 -0
  414. package/libs/instance-factories/views/templates/shared/syntax-mapper.d.ts +143 -0
  415. package/libs/instance-factories/views/templates/shared/syntax-mapper.d.ts.map +1 -0
  416. package/libs/instance-factories/views/templates/shared/syntax-mapper.js +420 -0
  417. package/libs/instance-factories/views/templates/shared/syntax-mapper.js.map +1 -0
  418. package/libs/instance-factories/views/templates/shared/syntax-mapper.ts +539 -0
  419. package/package.json +42 -0
  420. package/schema/SPECVERSE-SCHEMA.json +4274 -0
@@ -0,0 +1,563 @@
1
+ /**
2
+ * Prisma Schema Generator
3
+ *
4
+ * Generates Prisma schema from SpecVerse models
5
+ */
6
+
7
+ import type { TemplateContext } from '@specverse/engine-realize';
8
+ import { pluralize } from '@specverse/types';
9
+
10
+ /**
11
+ * Generate Prisma schema
12
+ */
13
+ export default function generatePrismaSchema(context: TemplateContext): string {
14
+ const { spec, models, implType } = context;
15
+
16
+ const allModels = models || spec?.models || [];
17
+
18
+ if (allModels.length === 0) {
19
+ throw new Error('No models found in context for schema generation');
20
+ }
21
+
22
+ // Build relation map: track all references to each target model
23
+ // so we can add @relation("name") when a target is referenced multiple times
24
+ const relationMap = buildRelationMap(allModels);
25
+
26
+ // Build missing back-references: when Model A has hasMany B but B has no belongsTo A,
27
+ // Prisma requires the back-reference field on B. We auto-generate these.
28
+ const backRefs = buildMissingBackRefs(allModels, relationMap);
29
+
30
+ // Build set of "ParentModel->ChildModel" for hasOne relations
31
+ // Used to add @unique to FK fields on the child side of a hasOne
32
+ const hasOneTargets = new Set<string>();
33
+ for (const m of allModels) {
34
+ const rels = Array.isArray(m.relationships) ? m.relationships : Object.values(m.relationships || {});
35
+ for (const r of rels as any[]) {
36
+ if (r.type === 'hasOne') {
37
+ hasOneTargets.add(`${m.name}->${r.target}`);
38
+ }
39
+ }
40
+ }
41
+
42
+ // Generate header
43
+ const header = generateHeader(implType);
44
+
45
+ // Generate models
46
+ const modelSchemas = allModels.map((model: any) =>
47
+ generateModelSchema(model, relationMap, backRefs, hasOneTargets, allModels)
48
+ ).join('\n\n');
49
+
50
+ return `${header}\n\n${modelSchemas}`;
51
+ }
52
+
53
+ /**
54
+ * Build a relation name map that assigns consistent names to both sides of each relation.
55
+ *
56
+ * Prisma requires that when @relation("name") is used, BOTH sides use the same name.
57
+ * We need disambiguation when a model is referenced by multiple fields across all models.
58
+ *
59
+ * Returns: Map<"SourceModel.fieldName", relationName | null>
60
+ * - null means no @relation annotation needed
61
+ * - string means use @relation("name") on this field
62
+ */
63
+ function buildRelationMap(allModels: any[]): Map<string, string | null> {
64
+ // Step 1: Collect all relations grouped by target model
65
+ type RelRef = { sourceModel: string; fieldName: string; relType: string };
66
+ const targetRefs = new Map<string, RelRef[]>();
67
+
68
+ for (const model of allModels) {
69
+ const relationships = Array.isArray(model.relationships)
70
+ ? model.relationships
71
+ : Object.values(model.relationships || {});
72
+
73
+ for (const rel of relationships as any[]) {
74
+ const target = rel.target;
75
+ if (!target) continue;
76
+
77
+ const fieldName = rel.name || (rel.type === 'hasMany' || rel.type === 'manyToMany'
78
+ ? pluralize(target.toLowerCase())
79
+ : target.toLowerCase());
80
+
81
+ if (!targetRefs.has(target)) {
82
+ targetRefs.set(target, []);
83
+ }
84
+ targetRefs.get(target)!.push({
85
+ sourceModel: model.name,
86
+ fieldName,
87
+ relType: rel.type
88
+ });
89
+ }
90
+ }
91
+
92
+ // Step 2: For ALL belongsTo relations, find the matching parent-side name.
93
+ // Since we always name relations, every belongsTo must use the parent's canonical name.
94
+ const nameMap = new Map<string, string | null>();
95
+
96
+ for (const [target, refs] of targetRefs) {
97
+ for (const ref of refs) {
98
+ const key = `${ref.sourceModel}.${ref.fieldName}`;
99
+ if (ref.relType === 'belongsTo') {
100
+ // Child side: find the matching parent-side relation
101
+ const parentRefs = targetRefs.get(ref.sourceModel) || [];
102
+ const matchingParent = parentRefs.find(p =>
103
+ p.sourceModel === target &&
104
+ (p.relType === 'hasMany' || p.relType === 'hasOne')
105
+ );
106
+ if (matchingParent) {
107
+ // Use the parent's canonical name so both sides match
108
+ nameMap.set(key, `${matchingParent.sourceModel}_${matchingParent.fieldName}`);
109
+ }
110
+ // If no matching parent, leave unmapped — getRelationName will use default
111
+ }
112
+ // hasMany/hasOne/manyToMany use default naming in getRelationName
113
+ }
114
+ }
115
+
116
+ return nameMap;
117
+ }
118
+
119
+ /**
120
+ * Build missing back-reference fields.
121
+ * When Model A has `hasMany B` or `hasOne B`, Prisma requires B to have a
122
+ * corresponding FK + relation field pointing back to A.
123
+ * If B already has a `belongsTo A`, it's covered. Otherwise we need to inject one.
124
+ *
125
+ * Returns: Map<targetModelName, Array<{ fkField, relationField }>>
126
+ */
127
+ function buildMissingBackRefs(
128
+ allModels: any[],
129
+ relationMap: Map<string, string | null>
130
+ ): Map<string, string[]> {
131
+ // Build set of existing belongsTo relations: "ChildModel->ParentModel"
132
+ const existingBelongsTo = new Set<string>();
133
+ for (const model of allModels) {
134
+ const relationships = Array.isArray(model.relationships)
135
+ ? model.relationships
136
+ : Object.values(model.relationships || {});
137
+ for (const rel of relationships as any[]) {
138
+ if (rel.type === 'belongsTo') {
139
+ existingBelongsTo.add(`${model.name}->${rel.target}`);
140
+ }
141
+ }
142
+ }
143
+
144
+ // For each hasMany/hasOne, check if the target has a belongsTo back
145
+ const backRefs = new Map<string, string[]>();
146
+
147
+ for (const model of allModels) {
148
+ const relationships = Array.isArray(model.relationships)
149
+ ? model.relationships
150
+ : Object.values(model.relationships || {});
151
+ for (const rel of relationships as any[]) {
152
+ if (rel.type !== 'hasMany' && rel.type !== 'hasOne') continue;
153
+
154
+ const target = rel.target;
155
+ const backKey = `${target}->${model.name}`;
156
+
157
+ if (!existingBelongsTo.has(backKey)) {
158
+ // Target model is missing a belongsTo for this relation — inject one
159
+ const fieldName = rel.name || (rel.type === 'hasMany'
160
+ ? pluralize(target.toLowerCase())
161
+ : target.toLowerCase());
162
+ // Always use the parent's canonical relation name
163
+ const relName = `${model.name}_${fieldName}`;
164
+
165
+ // Check if the parent model has multiple hasMany/hasOne relations to the same target
166
+ // If so, include the field name in the FK to avoid collisions
167
+ const parentRelsToSameTarget = relationships.filter((r: any) =>
168
+ r.target === target && (r.type === 'hasMany' || r.type === 'hasOne')
169
+ );
170
+ const needsFieldInFk = parentRelsToSameTarget.length > 1;
171
+ const fkSuffix = needsFieldInFk
172
+ ? camelToSnake(fieldName) + '_id'
173
+ : camelToSnake(model.name.charAt(0).toLowerCase() + model.name.slice(1)) + '_id';
174
+ const fkName = fkSuffix;
175
+ const fkPadding = ' '.repeat(Math.max(1, 15 - fkName.length));
176
+ const refFieldName = needsFieldInFk
177
+ ? fieldName + model.name
178
+ : model.name.charAt(0).toLowerCase() + model.name.slice(1);
179
+ const refPadding = ' '.repeat(Math.max(1, 15 - refFieldName.length));
180
+
181
+ let relDef = `${refFieldName}${refPadding}${model.name}`;
182
+ relDef += ` @relation("${relName}", fields: [${fkName}], references: [id])`;
183
+
184
+ if (!backRefs.has(target)) {
185
+ backRefs.set(target, []);
186
+ }
187
+ const uniqueModifier = rel.type === 'hasOne' ? ' @unique' : '';
188
+ backRefs.get(target)!.push(`${fkName}${fkPadding}String${uniqueModifier}`);
189
+ backRefs.get(target)!.push(relDef);
190
+ }
191
+ }
192
+ }
193
+
194
+ // Also handle the reverse: belongsTo without matching hasMany/hasOne on parent
195
+ // Build set of existing hasMany/hasOne: "ParentModel->ChildModel"
196
+ const existingHasRelation = new Set<string>();
197
+ for (const model of allModels) {
198
+ const rels = Array.isArray(model.relationships)
199
+ ? model.relationships
200
+ : Object.values(model.relationships || {});
201
+ for (const rel of rels as any[]) {
202
+ if (rel.type === 'hasMany' || rel.type === 'hasOne') {
203
+ existingHasRelation.add(`${model.name}->${rel.target}`);
204
+ }
205
+ }
206
+ }
207
+
208
+ for (const model of allModels) {
209
+ const relationships = Array.isArray(model.relationships)
210
+ ? model.relationships
211
+ : Object.values(model.relationships || {});
212
+ for (const rel of relationships as any[]) {
213
+ if (rel.type !== 'belongsTo') continue;
214
+
215
+ const parent = rel.target;
216
+ const forwardKey = `${parent}->${model.name}`;
217
+
218
+ if (!existingHasRelation.has(forwardKey)) {
219
+ // Parent model is missing a hasMany/hasOne for this belongsTo — inject array
220
+ const fieldName = rel.name || parent.toLowerCase();
221
+ const relName = getRelationName(model.name, fieldName, parent, relationMap);
222
+ const arrayFieldName = pluralize(model.name.charAt(0).toLowerCase() + model.name.slice(1));
223
+ const padding = ' '.repeat(Math.max(1, 15 - arrayFieldName.length));
224
+
225
+ if (!backRefs.has(parent)) {
226
+ backRefs.set(parent, []);
227
+ }
228
+ backRefs.get(parent)!.push(`${arrayFieldName}${padding}${model.name}[] @relation("${relName}")`);
229
+ }
230
+ }
231
+ }
232
+
233
+ return backRefs;
234
+ }
235
+
236
+ /**
237
+ * Get the relation name for a given source model + field.
238
+ * ALWAYS returns a name — Prisma accepts explicit names even when not strictly required,
239
+ * and it avoids all ambiguity issues with complex schemas.
240
+ *
241
+ * For hasMany/hasOne: name = "SourceModel_fieldName" (canonical, parent-side)
242
+ * For belongsTo: looks up the matching parent-side name from the relation map
243
+ */
244
+ function getRelationName(
245
+ sourceModel: string,
246
+ fieldName: string,
247
+ target: string,
248
+ relationMap: Map<string, string | null>
249
+ ): string {
250
+ // Check if there's a mapped name (for belongsTo matching a parent's hasMany)
251
+ const mapped = relationMap.get(`${sourceModel}.${fieldName}`);
252
+ if (mapped) return mapped;
253
+
254
+ // Default: use canonical naming
255
+ return `${sourceModel}_${fieldName}`;
256
+ }
257
+
258
+ /**
259
+ * Generate Prisma schema header
260
+ */
261
+ function generateHeader(implType: any): string {
262
+ const provider = implType?.configuration?.orm?.provider || 'sqlite';
263
+
264
+ return `// Generated Prisma schema from SpecVerse specification
265
+ // This is your Prisma schema file
266
+ // learn more about it in the docs: https://pris.ly/d/prisma-schema
267
+
268
+ generator client {
269
+ provider = "prisma-client-js"
270
+ }
271
+
272
+ datasource db {
273
+ provider = "${provider}"
274
+ url = ${provider === 'sqlite' ? '"file:./dev.db"' : 'env("DATABASE_URL")'}
275
+ }`;
276
+ }
277
+
278
+ /**
279
+ * Generate a single model schema
280
+ */
281
+ function generateModelSchema(
282
+ model: any,
283
+ relationMap: Map<string, string | null>,
284
+ backRefs: Map<string, string[]>,
285
+ hasOneTargets: Set<string>,
286
+ allModels?: any[]
287
+ ): string {
288
+ const modelName = model.name;
289
+ let schema = `model ${modelName} {\n`;
290
+
291
+ // Convert attributes from object to array if needed
292
+ const attributes = Array.isArray(model.attributes)
293
+ ? model.attributes
294
+ : Object.values(model.attributes || {});
295
+
296
+ // Convert relationships from object to array if needed
297
+ const relationships = Array.isArray(model.relationships)
298
+ ? model.relationships
299
+ : Object.values(model.relationships || {});
300
+
301
+ // Add attributes
302
+ attributes.forEach((attr: any) => {
303
+ schema += ` ${generateField(attr, model)}\n`;
304
+ });
305
+
306
+ // Add lifecycle status fields (if model has lifecycles)
307
+ const rawLifecycles = model.lifecycles || [];
308
+ const lifecycleList = Array.isArray(rawLifecycles)
309
+ ? rawLifecycles
310
+ : Object.entries(rawLifecycles).map(([name, lc]: [string, any]) => ({ name, ...(typeof lc === 'object' ? lc : {}) }));
311
+ for (const lifecycle of lifecycleList) {
312
+ const fieldName = lifecycle.name || 'status';
313
+ const exists = attributes.some((a: any) => a.name === fieldName);
314
+ if (!exists && lifecycle.states?.length > 0) {
315
+ const defaultState = lifecycle.states[0];
316
+ const padding = ' '.repeat(Math.max(1, 15 - fieldName.length));
317
+ schema += ` ${fieldName}${padding}String @default("${defaultState}")\n`;
318
+ }
319
+ }
320
+
321
+ // Add relationships
322
+ relationships.forEach((rel: any) => {
323
+ const fields = generateRelationship(rel, model, relationMap, hasOneTargets, allModels);
324
+ fields.forEach(field => {
325
+ schema += ` ${field}\n`;
326
+ });
327
+ });
328
+
329
+ // Add auto-generated back-references (for hasMany/hasOne without corresponding belongsTo)
330
+ const modelBackRefs = backRefs.get(modelName);
331
+ if (modelBackRefs) {
332
+ for (const line of modelBackRefs) {
333
+ schema += ` ${line}\n`;
334
+ }
335
+ }
336
+
337
+ schema += `}`;
338
+
339
+ return schema;
340
+ }
341
+
342
+ /**
343
+ * Generate a field definition
344
+ */
345
+ function generateField(attr: any, model: any): string {
346
+ const name = attr.name;
347
+ const prismaType = mapTypeToPrisma(attr.type, attr.dbMapping?.columnType);
348
+ const isOptional = !(attr.required || attr.constraints?.required);
349
+ const isUnique = attr.unique || attr.constraints?.unique;
350
+ const metadata = model?.metadata || {};
351
+
352
+ let modifiers = '';
353
+
354
+ // Primary key detection
355
+ if (name.toLowerCase() === 'id') {
356
+ modifiers += ' @id';
357
+ if (metadata.id === 'uuid' || metadata.id === 'auto' || prismaType === 'String') {
358
+ modifiers += ' @default(uuid())';
359
+ } else if (metadata.id === 'integer' || prismaType === 'Int') {
360
+ modifiers += ' @default(autoincrement())';
361
+ }
362
+ } else if (isUnique) {
363
+ modifiers += ' @unique';
364
+ }
365
+
366
+ // Auto-generated fields (auto=now, auto=uuid, etc.)
367
+ if (attr.auto) {
368
+ const autoValue = typeof attr.auto === 'string' ? attr.auto.toLowerCase() : attr.auto;
369
+ if (autoValue === 'now' || autoValue === true) {
370
+ if (prismaType === 'DateTime') {
371
+ modifiers += ' @default(now())';
372
+ }
373
+ } else if (autoValue === 'uuid' || autoValue === 'uuid4') {
374
+ if (prismaType === 'String') {
375
+ modifiers += ' @default(uuid())';
376
+ }
377
+ }
378
+ } else {
379
+ // Workaround: Handle common auto-timestamp fields (parser not preserving auto directive)
380
+ const autoTimestampFields = ['joinedAt', 'registeredAt', 'enrolledAt', 'startedAt', 'completedAt', 'verifiedAt'];
381
+ if (autoTimestampFields.includes(name) && prismaType === 'DateTime') {
382
+ modifiers += ' @default(now())';
383
+ }
384
+ }
385
+
386
+ // Audit fields
387
+ if (metadata.audit && isAuditField(name)) {
388
+ if (name === 'createdAt' || name === 'created_at') {
389
+ if (!attr.auto) { // Don't override if already handled by auto
390
+ modifiers += ' @default(now())';
391
+ }
392
+ }
393
+ if (name === 'updatedAt' || name === 'updated_at') {
394
+ modifiers += ' @updatedAt';
395
+ }
396
+ }
397
+
398
+ // Soft delete fields
399
+ if (metadata.softDelete && isSoftDeleteField(name)) {
400
+ if (name === 'isDeleted' || name === 'is_deleted') {
401
+ modifiers += ' @default(false)';
402
+ }
403
+ }
404
+
405
+ // Version field
406
+ if (metadata.version && isVersionField(name)) {
407
+ modifiers += ' @default(0)';
408
+ }
409
+
410
+ // Database-specific type annotations
411
+ if (attr.dbMapping?.columnType === 'TEXT') {
412
+ modifiers += ' @db.Text';
413
+ } else if (attr.dbMapping?.columnType?.startsWith('VARCHAR')) {
414
+ const match = attr.dbMapping.columnType.match(/VARCHAR\((\d+)\)/);
415
+ if (match) {
416
+ modifiers += ` @db.VarChar(${match[1]})`;
417
+ }
418
+ }
419
+
420
+ const padding = ' '.repeat(Math.max(1, 15 - name.length));
421
+ const typeStr = isOptional ? `${prismaType}?` : prismaType;
422
+
423
+ return `${name}${padding}${typeStr}${modifiers}`;
424
+ }
425
+
426
+ /**
427
+ * Generate relationship fields
428
+ */
429
+ function generateRelationship(rel: any, model: any, relationMap: Map<string, string | null>, hasOneTargets: Set<string>, allModels?: any[]): string[] {
430
+ const fields: string[] = [];
431
+ const name = rel.name || rel.target.toLowerCase();
432
+ const padding = ' '.repeat(Math.max(1, 15 - name.length));
433
+ const isOptional = rel.optional || false;
434
+
435
+ // Always add explicit relation names for Prisma — avoids all ambiguity
436
+ const relName = getRelationName(model.name, name, rel.target, relationMap);
437
+ const relAnnotation = ` @relation("${relName}")`;
438
+
439
+ switch (rel.type) {
440
+ case 'belongsTo':
441
+ // Foreign key field — use snake_case for the FK column name
442
+ const fkBase = rel.foreignKey || camelToSnake(name) + '_id';
443
+ const fkPadding = ' '.repeat(Math.max(1, 15 - fkBase.length));
444
+ // Add @unique if the parent has a hasOne relation pointing to this model
445
+ const isUniqueFK = hasOneTargets.has(`${rel.target}->${model.name}`);
446
+ // FK type must match the target model's ID type
447
+ let fkType = 'String';
448
+ if (allModels) {
449
+ const targetModel = allModels.find((m: any) => m.name === rel.target);
450
+ if (targetModel) {
451
+ const idAttr = (Array.isArray(targetModel.attributes) ? targetModel.attributes : Object.values(targetModel.attributes || {}))
452
+ .find((a: any) => a.name === 'id');
453
+ if (idAttr) {
454
+ const idType = idAttr.type || 'String';
455
+ fkType = mapTypeToPrisma(idType);
456
+ }
457
+ }
458
+ }
459
+ fields.push(`${fkBase}${fkPadding}${fkType}${isOptional ? '?' : ''}${isUniqueFK ? ' @unique' : ''}`);
460
+
461
+ // Relation field with @relation including fields/references + optional name
462
+ let relationDef = `${name}${padding}${rel.target}${isOptional ? '?' : ''}`;
463
+ relationDef += ` @relation(`;
464
+ if (relName) {
465
+ relationDef += `"${relName}", `;
466
+ }
467
+ relationDef += `fields: [${fkBase}], references: [id]`;
468
+
469
+ if (rel.onDelete) {
470
+ relationDef += `, onDelete: ${rel.onDelete}`;
471
+ }
472
+ if (rel.onUpdate) {
473
+ relationDef += `, onUpdate: ${rel.onUpdate}`;
474
+ }
475
+
476
+ relationDef += ')';
477
+ fields.push(relationDef);
478
+ break;
479
+
480
+ case 'hasOne':
481
+ // Prisma requires hasOne relation fields to be optional
482
+ fields.push(`${name}${padding}${rel.target}?${relAnnotation}`);
483
+ break;
484
+
485
+ case 'hasMany':
486
+ const pluralName = rel.name || pluralize(rel.target.toLowerCase());
487
+ const manyPadding = ' '.repeat(Math.max(1, 15 - pluralName.length));
488
+ fields.push(`${pluralName}${manyPadding}${rel.target}[]${relAnnotation}`);
489
+ break;
490
+
491
+ case 'manyToMany':
492
+ const manyName = rel.name || pluralize(rel.target.toLowerCase());
493
+ const m2mPadding = ' '.repeat(Math.max(1, 15 - manyName.length));
494
+ fields.push(`${manyName}${m2mPadding}${rel.target}[]${relAnnotation}`);
495
+ break;
496
+ }
497
+
498
+ return fields;
499
+ }
500
+
501
+ /**
502
+ * Convert camelCase to snake_case
503
+ */
504
+ function camelToSnake(str: string): string {
505
+ return str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`);
506
+ }
507
+
508
+ /**
509
+ * Map SpecVerse type to Prisma type
510
+ */
511
+ function mapTypeToPrisma(type: string, dbType?: string): string {
512
+ // Use database type if provided
513
+ if (dbType) {
514
+ if (dbType.startsWith('VARCHAR') || dbType === 'TEXT') return 'String';
515
+
516
+ const typeMap: Record<string, string> = {
517
+ 'INTEGER': 'Int',
518
+ 'BIGINT': 'BigInt',
519
+ 'DECIMAL': 'Decimal',
520
+ 'BOOLEAN': 'Boolean',
521
+ 'DATE': 'DateTime',
522
+ 'TIMESTAMP': 'DateTime',
523
+ 'UUID': 'String',
524
+ 'JSONB': 'Json',
525
+ 'JSON': 'Json',
526
+ 'FLOAT': 'Float'
527
+ };
528
+
529
+ if (typeMap[dbType]) return typeMap[dbType];
530
+ }
531
+
532
+ // Infer from SpecVerse type
533
+ const typeLower = type.toLowerCase();
534
+
535
+ if (typeLower.includes('string') || typeLower.includes('text')) return 'String';
536
+ if (typeLower.includes('int')) return 'Int';
537
+ if (typeLower.includes('bool')) return 'Boolean';
538
+ if (typeLower.includes('date') || typeLower.includes('time')) return 'DateTime';
539
+ if (typeLower.includes('float') || typeLower.includes('decimal')) return 'Float';
540
+ if (typeLower.includes('json')) return 'Json';
541
+
542
+ return 'String'; // default
543
+ }
544
+
545
+ /**
546
+ * Helper functions
547
+ */
548
+ function isAuditField(name: string): boolean {
549
+ const auditFields = ['createdAt', 'updatedAt', 'createdBy', 'updatedBy',
550
+ 'created_at', 'updated_at', 'created_by', 'updated_by'];
551
+ return auditFields.includes(name);
552
+ }
553
+
554
+ function isSoftDeleteField(name: string): boolean {
555
+ const softDeleteFields = ['deletedAt', 'isDeleted', 'deleted_at', 'is_deleted'];
556
+ return softDeleteFields.includes(name);
557
+ }
558
+
559
+ function isVersionField(name: string): boolean {
560
+ const versionFields = ['version', 'versionNumber', 'version_number'];
561
+ return versionFields.includes(name);
562
+ }
563
+