@specverse/engines 4.1.30 → 4.2.1

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 (285) hide show
  1. package/assets/examples/manifests/frontend-only.yaml +3 -6
  2. package/assets/examples/manifests/fullstack-app.yaml +5 -7
  3. package/assets/examples/manifests/fullstack-monorepo.yaml +3 -6
  4. package/assets/templates/default/specs/main.specly +65 -0
  5. package/dist/inference/comprehensive-engine.d.ts.map +1 -1
  6. package/dist/inference/comprehensive-engine.js +3 -19
  7. package/dist/inference/comprehensive-engine.js.map +1 -1
  8. package/dist/inference/core/rule-engine.d.ts +31 -0
  9. package/dist/inference/core/rule-engine.d.ts.map +1 -1
  10. package/dist/inference/core/rule-engine.js +117 -33
  11. package/dist/inference/core/rule-engine.js.map +1 -1
  12. package/dist/inference/core/rule-file-types.d.ts +0 -2
  13. package/dist/inference/core/rule-file-types.d.ts.map +1 -1
  14. package/dist/inference/core/rule-file-types.js +3 -6
  15. package/dist/inference/core/rule-file-types.js.map +1 -1
  16. package/dist/inference/core/rule-loader.d.ts +5 -15
  17. package/dist/inference/core/rule-loader.d.ts.map +1 -1
  18. package/dist/inference/core/rule-loader.js +43 -132
  19. package/dist/inference/core/rule-loader.js.map +1 -1
  20. package/dist/inference/core/types.d.ts +0 -6
  21. package/dist/inference/core/types.d.ts.map +1 -1
  22. package/dist/inference/core/types.js +0 -4
  23. package/dist/inference/core/types.js.map +1 -1
  24. package/dist/inference/logical/generators/component-type-resolver.d.ts +0 -26
  25. package/dist/inference/logical/generators/component-type-resolver.d.ts.map +1 -1
  26. package/dist/inference/logical/generators/component-type-resolver.js +0 -19
  27. package/dist/inference/logical/generators/component-type-resolver.js.map +1 -1
  28. package/dist/inference/logical/generators/specialist-view-expander.d.ts +1 -17
  29. package/dist/inference/logical/generators/specialist-view-expander.d.ts.map +1 -1
  30. package/dist/inference/logical/generators/specialist-view-expander.js +0 -15
  31. package/dist/inference/logical/generators/specialist-view-expander.js.map +1 -1
  32. package/dist/inference/logical/generators/view-generator.d.ts +4 -14
  33. package/dist/inference/logical/generators/view-generator.d.ts.map +1 -1
  34. package/dist/inference/logical/generators/view-generator.js +6 -26
  35. package/dist/inference/logical/generators/view-generator.js.map +1 -1
  36. package/dist/inference/logical/index.d.ts +2 -2
  37. package/dist/inference/logical/index.d.ts.map +1 -1
  38. package/dist/inference/logical/logical-engine.d.ts.map +1 -1
  39. package/dist/inference/logical/logical-engine.js +17 -80
  40. package/dist/inference/logical/logical-engine.js.map +1 -1
  41. package/dist/inference/quint-transpiler.d.ts +5 -3
  42. package/dist/inference/quint-transpiler.d.ts.map +1 -1
  43. package/dist/inference/quint-transpiler.js +11 -6
  44. package/dist/inference/quint-transpiler.js.map +1 -1
  45. package/dist/libs/instance-factories/CURVED-INTERFACE.md +278 -0
  46. package/dist/libs/instance-factories/README.md +73 -0
  47. package/dist/libs/instance-factories/applications/README.md +51 -0
  48. package/dist/libs/instance-factories/applications/generic-app.yaml +52 -0
  49. package/{libs/instance-factories/applications/react-app.yaml → dist/libs/instance-factories/applications/react-app-runtime.yaml} +30 -77
  50. package/dist/libs/instance-factories/applications/react-app-starter.yaml +143 -0
  51. package/dist/libs/instance-factories/applications/templates/react/env-example-generator.js +24 -2
  52. package/dist/libs/instance-factories/applications/templates/react/vite-config-generator.js +54 -33
  53. package/dist/libs/instance-factories/applications/templates/react-starter/README.md +211 -0
  54. package/dist/libs/instance-factories/applications/templates/react-starter/api-types-starter-generator.js +69 -0
  55. package/dist/libs/instance-factories/applications/templates/react-starter/app-tsx-generator.js +110 -0
  56. package/dist/libs/instance-factories/applications/templates/react-starter/belongs-to.js +40 -0
  57. package/dist/libs/instance-factories/applications/templates/react-starter/dashboard-body-composer.js +129 -0
  58. package/dist/libs/instance-factories/applications/templates/react-starter/detail-body-composer.js +80 -0
  59. package/dist/libs/instance-factories/applications/templates/react-starter/form-body-composer.js +217 -0
  60. package/dist/libs/instance-factories/applications/templates/react-starter/helpers-emitter.js +51 -0
  61. package/dist/libs/instance-factories/applications/templates/react-starter/html-to-jsx.js +192 -0
  62. package/dist/libs/instance-factories/applications/templates/react-starter/list-body-composer.js +56 -0
  63. package/dist/libs/instance-factories/applications/templates/react-starter/orchestrator.js +41 -0
  64. package/dist/libs/instance-factories/applications/templates/react-starter/package-json-generator.js +38 -0
  65. package/dist/libs/instance-factories/applications/templates/react-starter/regen-safety.js +89 -0
  66. package/dist/libs/instance-factories/applications/templates/react-starter/skeletons/dashboard.tsx.template +49 -0
  67. package/dist/libs/instance-factories/applications/templates/react-starter/skeletons/detail.tsx.template +96 -0
  68. package/dist/libs/instance-factories/applications/templates/react-starter/skeletons/form.tsx.template +116 -0
  69. package/dist/libs/instance-factories/applications/templates/react-starter/skeletons/list.tsx.template +74 -0
  70. package/dist/libs/instance-factories/applications/templates/react-starter/use-api-hooks-starter-generator.js +95 -0
  71. package/dist/libs/instance-factories/applications/templates/react-starter/view-emitter.js +81 -0
  72. package/dist/libs/instance-factories/applications/templates/react-starter/views-generator.js +66 -0
  73. package/dist/libs/instance-factories/archived/fastify-prisma.yaml +104 -0
  74. package/dist/libs/instance-factories/cli/README.md +43 -0
  75. package/dist/libs/instance-factories/cli/commander-js.yaml +55 -0
  76. package/dist/libs/instance-factories/cli/templates/commander/command-generator.js +63 -12
  77. package/dist/libs/instance-factories/communication/README.md +47 -0
  78. package/dist/libs/instance-factories/communication/event-emitter.yaml +60 -0
  79. package/dist/libs/instance-factories/communication/rabbitmq-events.yaml +87 -0
  80. package/dist/libs/instance-factories/controllers/README.md +42 -0
  81. package/dist/libs/instance-factories/controllers/fastify.yaml +139 -0
  82. package/dist/libs/instance-factories/controllers/templates/fastify/server-generator.js +29 -2
  83. package/dist/libs/instance-factories/infrastructure/README.md +29 -0
  84. package/dist/libs/instance-factories/infrastructure/docker-k8s.yaml +61 -0
  85. package/dist/libs/instance-factories/orms/README.md +54 -0
  86. package/dist/libs/instance-factories/orms/prisma.yaml +89 -0
  87. package/dist/libs/instance-factories/orms/templates/prisma/schema-generator.js +2 -2
  88. package/dist/libs/instance-factories/scaffolding/README.md +49 -0
  89. package/dist/libs/instance-factories/scaffolding/generic-scaffold.yaml +65 -0
  90. package/dist/libs/instance-factories/sdks/README.md +28 -0
  91. package/dist/libs/instance-factories/sdks/python-sdk.yaml +66 -0
  92. package/dist/libs/instance-factories/sdks/typescript-sdk.yaml +59 -0
  93. package/dist/libs/instance-factories/services/README.md +55 -0
  94. package/dist/libs/instance-factories/services/prisma-services.yaml +71 -0
  95. package/dist/libs/instance-factories/storage/README.md +34 -0
  96. package/dist/libs/instance-factories/storage/mongodb.yaml +79 -0
  97. package/dist/libs/instance-factories/storage/postgresql.yaml +75 -0
  98. package/dist/libs/instance-factories/storage/redis.yaml +79 -0
  99. package/dist/libs/instance-factories/testing/README.md +40 -0
  100. package/dist/libs/instance-factories/testing/vitest-tests.yaml +63 -0
  101. package/dist/libs/instance-factories/tools/README.md +70 -0
  102. package/dist/libs/instance-factories/tools/mcp.yaml +36 -0
  103. package/dist/libs/instance-factories/tools/vscode.yaml +35 -0
  104. package/dist/libs/instance-factories/validation/README.md +38 -0
  105. package/dist/libs/instance-factories/validation/zod.yaml +56 -0
  106. package/dist/realize/engines/code-generator.d.ts.map +1 -1
  107. package/dist/realize/engines/code-generator.js +3 -0
  108. package/dist/realize/engines/code-generator.js.map +1 -1
  109. package/dist/realize/index.d.ts.map +1 -1
  110. package/dist/realize/index.js +15 -22
  111. package/dist/realize/index.js.map +1 -1
  112. package/dist/registry/utils/manifest-adapter.d.ts +8 -1
  113. package/dist/registry/utils/manifest-adapter.d.ts.map +1 -1
  114. package/dist/registry/utils/manifest-adapter.js +8 -1
  115. package/dist/registry/utils/manifest-adapter.js.map +1 -1
  116. package/libs/instance-factories/applications/react-app-starter.yaml +143 -0
  117. package/libs/instance-factories/applications/templates/react/env-example-generator.ts +24 -2
  118. package/libs/instance-factories/applications/templates/react/vite-config-generator.ts +54 -33
  119. package/libs/instance-factories/applications/templates/react-starter/README.md +211 -0
  120. package/libs/instance-factories/applications/templates/react-starter/__tests__/dashboard-body-composer.test.ts +153 -0
  121. package/libs/instance-factories/applications/templates/react-starter/__tests__/detail-body-composer.test.ts +146 -0
  122. package/libs/instance-factories/applications/templates/react-starter/__tests__/form-body-composer.test.ts +188 -0
  123. package/libs/instance-factories/applications/templates/react-starter/__tests__/helpers-emitter.test.ts +55 -0
  124. package/libs/instance-factories/applications/templates/react-starter/__tests__/html-to-jsx.test.ts +140 -0
  125. package/libs/instance-factories/applications/templates/react-starter/__tests__/list-body-composer.test.ts +146 -0
  126. package/libs/instance-factories/applications/templates/react-starter/__tests__/orchestrator.test.ts +184 -0
  127. package/libs/instance-factories/applications/templates/react-starter/__tests__/parity-p2-factory-imports.test.ts +116 -0
  128. package/libs/instance-factories/applications/templates/react-starter/__tests__/parity-p3-rendered-output.test.ts +183 -0
  129. package/libs/instance-factories/applications/templates/react-starter/__tests__/regen-safety.test.ts +144 -0
  130. package/libs/instance-factories/applications/templates/react-starter/__tests__/starter-generators.test.ts +114 -0
  131. package/libs/instance-factories/applications/templates/react-starter/__tests__/view-emitter.test.ts +107 -0
  132. package/libs/instance-factories/applications/templates/react-starter/__tests__/views-generator.test.ts +139 -0
  133. package/libs/instance-factories/applications/templates/react-starter/api-types-starter-generator.ts +98 -0
  134. package/libs/instance-factories/applications/templates/react-starter/app-tsx-generator.ts +141 -0
  135. package/libs/instance-factories/applications/templates/react-starter/belongs-to.ts +82 -0
  136. package/libs/instance-factories/applications/templates/react-starter/dashboard-body-composer.ts +189 -0
  137. package/libs/instance-factories/applications/templates/react-starter/detail-body-composer.ts +135 -0
  138. package/libs/instance-factories/applications/templates/react-starter/form-body-composer.ts +383 -0
  139. package/libs/instance-factories/applications/templates/react-starter/helpers-emitter.ts +66 -0
  140. package/libs/instance-factories/applications/templates/react-starter/html-to-jsx.ts +334 -0
  141. package/libs/instance-factories/applications/templates/react-starter/list-body-composer.ts +146 -0
  142. package/libs/instance-factories/applications/templates/react-starter/orchestrator.ts +95 -0
  143. package/libs/instance-factories/applications/templates/react-starter/package-json-generator.ts +57 -0
  144. package/libs/instance-factories/applications/templates/react-starter/regen-safety.ts +157 -0
  145. package/libs/instance-factories/applications/templates/react-starter/skeletons/dashboard.tsx.template +49 -0
  146. package/libs/instance-factories/applications/templates/react-starter/skeletons/detail.tsx.template +96 -0
  147. package/libs/instance-factories/applications/templates/react-starter/skeletons/form.tsx.template +116 -0
  148. package/libs/instance-factories/applications/templates/react-starter/skeletons/list.tsx.template +74 -0
  149. package/libs/instance-factories/applications/templates/react-starter/use-api-hooks-starter-generator.ts +124 -0
  150. package/libs/instance-factories/applications/templates/react-starter/view-emitter.ts +209 -0
  151. package/libs/instance-factories/applications/templates/react-starter/views-generator.ts +137 -0
  152. package/libs/instance-factories/cli/templates/commander/command-generator.ts +63 -12
  153. package/libs/instance-factories/controllers/fastify.yaml +7 -0
  154. package/libs/instance-factories/controllers/templates/fastify/server-generator.ts +36 -2
  155. package/libs/instance-factories/orms/templates/prisma/schema-generator.ts +11 -4
  156. package/package.json +3 -3
  157. package/dist/libs/instance-factories/applications/templates/react/_view-components-source.js +0 -530
  158. package/dist/libs/instance-factories/applications/templates/react/app-tsx-generator.js +0 -73
  159. package/dist/libs/instance-factories/applications/templates/react/field-helpers-generator.js +0 -99
  160. package/dist/libs/instance-factories/applications/templates/react/package-json-generator.js +0 -49
  161. package/dist/libs/instance-factories/applications/templates/react/pattern-adapter-generator.js +0 -156
  162. package/dist/libs/instance-factories/applications/templates/react/react-pattern-adapter.js +0 -935
  163. package/dist/libs/instance-factories/applications/templates/react/relationship-field-generator.js +0 -143
  164. package/dist/libs/instance-factories/applications/templates/react/tailwind-adapter-generator.js +0 -646
  165. package/dist/libs/instance-factories/applications/templates/react/tailwind-adapter-wrapper-generator.js +0 -65
  166. package/dist/libs/instance-factories/applications/templates/react/view-dashboard-generator.js +0 -143
  167. package/dist/libs/instance-factories/applications/templates/react/view-detail-generator.js +0 -143
  168. package/dist/libs/instance-factories/applications/templates/react/view-form-generator.js +0 -355
  169. package/dist/libs/instance-factories/applications/templates/react/view-list-generator.js +0 -91
  170. package/dist/libs/instance-factories/applications/templates/react/view-router-generator.js +0 -79
  171. package/dist/libs/instance-factories/views/index.js +0 -48
  172. package/dist/libs/instance-factories/views/templates/react/adapters/antd-adapter.js +0 -742
  173. package/dist/libs/instance-factories/views/templates/react/adapters/mui-adapter.js +0 -824
  174. package/dist/libs/instance-factories/views/templates/react/adapters/shadcn-adapter.js +0 -719
  175. package/dist/libs/instance-factories/views/templates/react/app-generator.js +0 -45
  176. package/dist/libs/instance-factories/views/templates/react/components-generator.js +0 -820
  177. package/dist/libs/instance-factories/views/templates/react/forms-generator.js +0 -275
  178. package/dist/libs/instance-factories/views/templates/react/frontend-package-json-generator.js +0 -46
  179. package/dist/libs/instance-factories/views/templates/react/hooks-generator.js +0 -81
  180. package/dist/libs/instance-factories/views/templates/react/index-css-generator.js +0 -9
  181. package/dist/libs/instance-factories/views/templates/react/index-html-generator.js +0 -23
  182. package/dist/libs/instance-factories/views/templates/react/main-tsx-generator.js +0 -21
  183. package/dist/libs/instance-factories/views/templates/react/react-component-generator.js +0 -299
  184. package/dist/libs/instance-factories/views/templates/react/router-generator.js +0 -136
  185. package/dist/libs/instance-factories/views/templates/react/router-generic-generator.js +0 -107
  186. package/dist/libs/instance-factories/views/templates/react/shared-utils-generator.js +0 -187
  187. package/dist/libs/instance-factories/views/templates/react/spec-json-generator.js +0 -7
  188. package/dist/libs/instance-factories/views/templates/react/types-generator.js +0 -56
  189. package/dist/libs/instance-factories/views/templates/react/views-metadata-generator.js +0 -27
  190. package/dist/libs/instance-factories/views/templates/react/vite-config-generator.js +0 -29
  191. package/dist/libs/instance-factories/views/templates/runtime/runtime-view-renderer.js +0 -261
  192. package/dist/libs/instance-factories/views/templates/shared/adapter-types.js +0 -34
  193. package/dist/libs/instance-factories/views/templates/shared/atomic-components-registry.js +0 -800
  194. package/dist/libs/instance-factories/views/templates/shared/base-generator.js +0 -305
  195. package/dist/libs/instance-factories/views/templates/shared/component-metadata.js +0 -517
  196. package/dist/libs/instance-factories/views/templates/shared/composite-pattern-types.js +0 -0
  197. package/dist/libs/instance-factories/views/templates/shared/composite-patterns.js +0 -445
  198. package/dist/libs/instance-factories/views/templates/shared/index.js +0 -80
  199. package/dist/libs/instance-factories/views/templates/shared/pattern-validator.js +0 -210
  200. package/dist/libs/instance-factories/views/templates/shared/property-mapper.js +0 -492
  201. package/dist/libs/instance-factories/views/templates/shared/syntax-mapper.js +0 -321
  202. package/dist/realize/index.js.bak +0 -758
  203. package/libs/instance-factories/applications/templates/react/_view-components-source.ts +0 -555
  204. package/libs/instance-factories/applications/templates/react/app-tsx-generator.ts +0 -94
  205. package/libs/instance-factories/applications/templates/react/field-helpers-generator.ts +0 -106
  206. package/libs/instance-factories/applications/templates/react/package-json-generator.ts +0 -57
  207. package/libs/instance-factories/applications/templates/react/pattern-adapter-generator.ts +0 -179
  208. package/libs/instance-factories/applications/templates/react/react-pattern-adapter.tsx +0 -1347
  209. package/libs/instance-factories/applications/templates/react/relationship-field-generator.ts +0 -150
  210. package/libs/instance-factories/applications/templates/react/tailwind-adapter-generator.ts +0 -704
  211. package/libs/instance-factories/applications/templates/react/tailwind-adapter-wrapper-generator.ts +0 -84
  212. package/libs/instance-factories/applications/templates/react/view-dashboard-generator.ts +0 -150
  213. package/libs/instance-factories/applications/templates/react/view-detail-generator.ts +0 -150
  214. package/libs/instance-factories/applications/templates/react/view-form-generator.ts +0 -362
  215. package/libs/instance-factories/applications/templates/react/view-list-generator.ts +0 -98
  216. package/libs/instance-factories/applications/templates/react/view-router-generator.ts +0 -89
  217. package/libs/instance-factories/views/README.md +0 -62
  218. package/libs/instance-factories/views/index.d.ts +0 -13
  219. package/libs/instance-factories/views/index.d.ts.map +0 -1
  220. package/libs/instance-factories/views/index.js +0 -18
  221. package/libs/instance-factories/views/index.js.map +0 -1
  222. package/libs/instance-factories/views/index.ts +0 -45
  223. package/libs/instance-factories/views/react-components.yaml +0 -129
  224. package/libs/instance-factories/views/templates/ARCHITECTURE.md +0 -198
  225. package/libs/instance-factories/views/templates/react/adapters/antd-adapter.ts +0 -869
  226. package/libs/instance-factories/views/templates/react/adapters/mui-adapter.ts +0 -953
  227. package/libs/instance-factories/views/templates/react/adapters/shadcn-adapter.ts +0 -806
  228. package/libs/instance-factories/views/templates/react/app-generator.ts +0 -55
  229. package/libs/instance-factories/views/templates/react/components-generator.ts +0 -938
  230. package/libs/instance-factories/views/templates/react/forms-generator.ts +0 -325
  231. package/libs/instance-factories/views/templates/react/frontend-package-json-generator.ts +0 -57
  232. package/libs/instance-factories/views/templates/react/hooks-generator.ts +0 -106
  233. package/libs/instance-factories/views/templates/react/index-css-generator.ts +0 -14
  234. package/libs/instance-factories/views/templates/react/index-html-generator.ts +0 -34
  235. package/libs/instance-factories/views/templates/react/main-tsx-generator.ts +0 -29
  236. package/libs/instance-factories/views/templates/react/react-component-generator.d.ts +0 -152
  237. package/libs/instance-factories/views/templates/react/react-component-generator.d.ts.map +0 -1
  238. package/libs/instance-factories/views/templates/react/react-component-generator.js +0 -398
  239. package/libs/instance-factories/views/templates/react/react-component-generator.js.map +0 -1
  240. package/libs/instance-factories/views/templates/react/react-component-generator.ts +0 -533
  241. package/libs/instance-factories/views/templates/react/router-generator.ts +0 -197
  242. package/libs/instance-factories/views/templates/react/router-generic-generator.ts +0 -132
  243. package/libs/instance-factories/views/templates/react/shared-utils-generator.ts +0 -196
  244. package/libs/instance-factories/views/templates/react/spec-json-generator.ts +0 -17
  245. package/libs/instance-factories/views/templates/react/types-generator.ts +0 -76
  246. package/libs/instance-factories/views/templates/react/views-metadata-generator.ts +0 -42
  247. package/libs/instance-factories/views/templates/react/vite-config-generator.ts +0 -38
  248. package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.d.ts.map +0 -1
  249. package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.js.map +0 -1
  250. package/libs/instance-factories/views/templates/runtime/runtime-view-renderer.ts +0 -474
  251. package/libs/instance-factories/views/templates/shared/__tests__/composite-patterns.test.ts +0 -242
  252. package/libs/instance-factories/views/templates/shared/adapter-types.d.ts +0 -77
  253. package/libs/instance-factories/views/templates/shared/adapter-types.d.ts.map +0 -1
  254. package/libs/instance-factories/views/templates/shared/adapter-types.js +0 -47
  255. package/libs/instance-factories/views/templates/shared/adapter-types.js.map +0 -1
  256. package/libs/instance-factories/views/templates/shared/adapter-types.ts +0 -142
  257. package/libs/instance-factories/views/templates/shared/atomic-components-registry.d.ts +0 -63
  258. package/libs/instance-factories/views/templates/shared/atomic-components-registry.d.ts.map +0 -1
  259. package/libs/instance-factories/views/templates/shared/atomic-components-registry.js +0 -822
  260. package/libs/instance-factories/views/templates/shared/atomic-components-registry.js.map +0 -1
  261. package/libs/instance-factories/views/templates/shared/atomic-components-registry.ts +0 -908
  262. package/libs/instance-factories/views/templates/shared/base-generator.d.ts +0 -247
  263. package/libs/instance-factories/views/templates/shared/base-generator.d.ts.map +0 -1
  264. package/libs/instance-factories/views/templates/shared/base-generator.js +0 -363
  265. package/libs/instance-factories/views/templates/shared/base-generator.js.map +0 -1
  266. package/libs/instance-factories/views/templates/shared/base-generator.ts +0 -608
  267. package/libs/instance-factories/views/templates/shared/component-metadata.d.ts +0 -254
  268. package/libs/instance-factories/views/templates/shared/component-metadata.d.ts.map +0 -1
  269. package/libs/instance-factories/views/templates/shared/component-metadata.js +0 -602
  270. package/libs/instance-factories/views/templates/shared/component-metadata.js.map +0 -1
  271. package/libs/instance-factories/views/templates/shared/component-metadata.ts +0 -803
  272. package/libs/instance-factories/views/templates/shared/composite-pattern-types.ts +0 -250
  273. package/libs/instance-factories/views/templates/shared/composite-patterns.ts +0 -535
  274. package/libs/instance-factories/views/templates/shared/index.ts +0 -68
  275. package/libs/instance-factories/views/templates/shared/pattern-validator.ts +0 -279
  276. package/libs/instance-factories/views/templates/shared/property-mapper.d.ts +0 -149
  277. package/libs/instance-factories/views/templates/shared/property-mapper.d.ts.map +0 -1
  278. package/libs/instance-factories/views/templates/shared/property-mapper.js +0 -580
  279. package/libs/instance-factories/views/templates/shared/property-mapper.js.map +0 -1
  280. package/libs/instance-factories/views/templates/shared/property-mapper.ts +0 -700
  281. package/libs/instance-factories/views/templates/shared/syntax-mapper.d.ts +0 -143
  282. package/libs/instance-factories/views/templates/shared/syntax-mapper.d.ts.map +0 -1
  283. package/libs/instance-factories/views/templates/shared/syntax-mapper.js +0 -420
  284. package/libs/instance-factories/views/templates/shared/syntax-mapper.js.map +0 -1
  285. package/libs/instance-factories/views/templates/shared/syntax-mapper.ts +0 -539
@@ -0,0 +1,383 @@
1
+ /**
2
+ * Form-view body composer for ReactAppStarter
3
+ *
4
+ * Emits one <label>+<input> pair per editable attribute of the model.
5
+ * Input type is inferred from the attribute's type + constraints
6
+ * (mirrors the canonical mapping in
7
+ * `entities/src/core/views/inference/component-mappings.json`, minus
8
+ * the atomic-component indirection).
9
+ *
10
+ * Auto-generated fields (id, timestamps, `auto=...` markers) are
11
+ * omitted — the backend assigns them.
12
+ *
13
+ * Relationship fields (belongsTo) are emitted as <select> dropdowns
14
+ * backed by the related model's list query. The corresponding hook
15
+ * calls and imports are wired by view-emitter via the RELATED_HOOKS /
16
+ * RELATED_IMPORTS substitutions — this composer only emits the JSX
17
+ * that consumes the `${relName}Options` variable.
18
+ */
19
+
20
+ import { METADATA_FIELDS } from '@specverse/runtime/views/core';
21
+ import type { EmitContext, ModelSpec } from './view-emitter.js';
22
+ import { extractBelongsToTargets, type BelongsToRel } from './belongs-to.js';
23
+
24
+ /**
25
+ * Attribute names the backend always generates — never render as
26
+ * inputs. Sourced from the pattern library's metadata set; any
27
+ * attribute with `auto=...` or category=metadata is additionally
28
+ * skipped via per-field checks in `selectFormFields` below.
29
+ */
30
+ const AUTO_GENERATED_FIELD_NAMES = new Set(METADATA_FIELDS);
31
+
32
+ /**
33
+ * Compose the form body as JSX-safe source. Dropped at `{{BODY}}`.
34
+ */
35
+ export function composeFormBody(context: EmitContext): string {
36
+ const belongsTo = extractBelongsToTargets(context.model);
37
+ // FK columns shadowed by a belongsTo relationship are emitted in the
38
+ // belongsTo section as <select>s — skip them in the main loop so we
39
+ // don't render both a plain-text input and a dropdown for the same
40
+ // column.
41
+ const shadowedFKs = new Set(belongsTo.map(rel => `${rel.name}Id`));
42
+ const fields = selectFormFields(context.model, shadowedFKs);
43
+
44
+ const lines: string[] = [];
45
+ lines.push('<div className="space-y-4">');
46
+
47
+ if (fields.length === 0 && belongsTo.length === 0) {
48
+ lines.push(' <p className="text-sm text-gray-400">No editable fields for this model.</p>');
49
+ lines.push('</div>');
50
+ return lines.join('\n');
51
+ }
52
+
53
+ for (const field of fields) {
54
+ lines.push(...renderInput(field));
55
+ }
56
+
57
+ for (const rel of belongsTo) {
58
+ lines.push(...renderRelationshipSelect(rel));
59
+ }
60
+
61
+ lines.push('</div>');
62
+ return lines.join('\n');
63
+ }
64
+
65
+ /**
66
+ * Emit a <select> dropdown for a belongsTo relationship. The options
67
+ * array (`${relName}Options`) is populated by the hook call wired in
68
+ * via view-emitter's RELATED_HOOKS substitution. Labels use
69
+ * `getEntityDisplayName` so users see human names instead of UUIDs.
70
+ */
71
+ function renderRelationshipSelect(rel: BelongsToRel): string[] {
72
+ const fkName = `${rel.name}Id`;
73
+ const varName = `${rel.name}Options`;
74
+ const label = humanize(rel.name);
75
+
76
+ return [
77
+ ' <div>',
78
+ ` <label className="${LABEL_CLS}" htmlFor="${fkName}">${label} *</label>`,
79
+ ` <select`,
80
+ ` id="${fkName}"`,
81
+ ` className="${INPUT_CLS}"`,
82
+ ` value={String((formData as any).${fkName} ?? '')}`,
83
+ ` onChange={e => handleChange('${fkName}', e.target.value)} required`,
84
+ ` >`,
85
+ ` <option value="">— choose —</option>`,
86
+ ` {${varName}.map((opt: any) => (`,
87
+ ` <option key={opt.id} value={opt.id}>{getEntityDisplayName(opt)}</option>`,
88
+ ` ))}`,
89
+ ` </select>`,
90
+ ' </div>',
91
+ ];
92
+ }
93
+
94
+ // ──────────────────────────────────────────────────────────────────────
95
+ // Field selection
96
+ // ──────────────────────────────────────────────────────────────────────
97
+
98
+ interface FieldInfo {
99
+ name: string;
100
+ label: string;
101
+ type: string;
102
+ required: boolean;
103
+ values?: string[]; // enum options if present
104
+ isLongString?: boolean;
105
+ auto?: boolean;
106
+ }
107
+
108
+ function selectFormFields(
109
+ model: ModelSpec,
110
+ skip: Set<string> = new Set()
111
+ ): FieldInfo[] {
112
+ const out: FieldInfo[] = [];
113
+ const attrs = model.attributes ?? {};
114
+ const lifecycleStates = extractLifecycleStates(model);
115
+
116
+ for (const [name, rawDef] of Object.entries(attrs)) {
117
+ if (AUTO_GENERATED_FIELD_NAMES.has(name)) continue;
118
+ if (skip.has(name)) continue;
119
+
120
+ const def = rawDef as AttributeShape;
121
+ if (def?.auto) continue;
122
+
123
+ // Heuristic: parse a type like "String required unique" to detect
124
+ // convention-string shapes. We prefer the structured fields if
125
+ // they're present.
126
+ const type = (def?.type ?? parseTypeFromConvention(def)) ?? 'String';
127
+ const required = def?.required === true || hasConventionFlag(def, 'required');
128
+ const declaredValues = def?.values as string[] | undefined;
129
+ // Lifecycle-backed attributes: if the model declares a lifecycle
130
+ // with the same name as this attribute, the attribute's valid
131
+ // values are the lifecycle states. Matches the FK rule's spirit —
132
+ // any attribute whose legal values are declared elsewhere in the
133
+ // spec should render as a <select>, not free text.
134
+ const lifecycleValues = lifecycleStates.get(name);
135
+ const values = declaredValues ?? lifecycleValues;
136
+ const maxLength = def?.maxLength ?? def?.max as number | undefined;
137
+ const isLongString =
138
+ typeof maxLength === 'number' && maxLength > 100;
139
+
140
+ out.push({
141
+ name,
142
+ label: humanize(name),
143
+ type: normalizeType(type),
144
+ required,
145
+ values,
146
+ isLongString,
147
+ });
148
+ }
149
+ return out;
150
+ }
151
+
152
+ /**
153
+ * Map from attribute name → list of lifecycle states, extracted from
154
+ * the model's `lifecycles` section. Supports both the convention-string
155
+ * shape (`flow: "a -> b -> c"`) and structured (`states: ["a", ...]`).
156
+ *
157
+ * Example:
158
+ * lifecycles:
159
+ * status:
160
+ * flow: "planning -> active -> completed -> archived"
161
+ * returns { status → ['planning', 'active', 'completed', 'archived'] }
162
+ */
163
+ function extractLifecycleStates(model: ModelSpec): Map<string, string[]> {
164
+ const out = new Map<string, string[]>();
165
+ const lifecycles = (model as ModelSpec & { lifecycles?: Record<string, unknown> }).lifecycles ?? {};
166
+
167
+ for (const [name, rawDef] of Object.entries(lifecycles)) {
168
+ if (!rawDef || typeof rawDef !== 'object') continue;
169
+ // The parser normalizes lifecycles into a rich structured form:
170
+ // { flow: "a -> b -> c",
171
+ // states: [{ name: "a" }, { name: "b" }, { name: "c" }],
172
+ // transitions: [...],
173
+ // initialState: "a" }
174
+ // Also support the pre-normalization shape (states as plain strings,
175
+ // or just a flow string) so the composer works on raw specs too.
176
+ const def = rawDef as {
177
+ flow?: string;
178
+ states?: Array<string | { name?: string; id?: string }>;
179
+ };
180
+
181
+ if (Array.isArray(def.states) && def.states.length > 0) {
182
+ const names = def.states
183
+ .map(s => (typeof s === 'string' ? s : s?.name ?? s?.id ?? ''))
184
+ .filter(Boolean);
185
+ if (names.length > 0) {
186
+ out.set(name, names);
187
+ continue;
188
+ }
189
+ }
190
+
191
+ if (typeof def.flow === 'string') {
192
+ // Split on -> with optional whitespace. Also accept commas as a
193
+ // fallback separator so a state list like "a, b, c" still works.
194
+ const states = def.flow
195
+ .split(/\s*(?:->|,)\s*/)
196
+ .map(s => s.trim())
197
+ .filter(Boolean);
198
+ if (states.length > 0) out.set(name, states);
199
+ }
200
+ }
201
+ return out;
202
+ }
203
+
204
+ /** Structured attribute object from the parsed spec. */
205
+ interface AttributeShape {
206
+ type?: string;
207
+ required?: boolean;
208
+ unique?: boolean;
209
+ auto?: string;
210
+ values?: string[];
211
+ maxLength?: number;
212
+ max?: number;
213
+ [k: string]: unknown;
214
+ }
215
+
216
+ function parseTypeFromConvention(def: unknown): string | undefined {
217
+ // Convention form: "String required unique"
218
+ if (typeof def === 'string') {
219
+ const first = def.trim().split(/\s+/)[0];
220
+ return first;
221
+ }
222
+ return undefined;
223
+ }
224
+
225
+ function hasConventionFlag(def: unknown, flag: string): boolean {
226
+ if (typeof def === 'string') {
227
+ return def.split(/\s+/).includes(flag);
228
+ }
229
+ return false;
230
+ }
231
+
232
+ function normalizeType(type: string): string {
233
+ // Strip any trailing modifiers from a compact convention-string form.
234
+ return type.replace(/[^A-Za-z].*$/, '');
235
+ }
236
+
237
+ // (`extractBelongsTo` was removed — the shared helper in
238
+ // `./belongs-to.ts` returns both the relationship name AND the target
239
+ // model so view-emitter can wire the hook call for each dropdown.)
240
+
241
+ // ──────────────────────────────────────────────────────────────────────
242
+ // Input rendering
243
+ // ──────────────────────────────────────────────────────────────────────
244
+
245
+ const INPUT_CLS =
246
+ 'w-full rounded border border-gray-300 px-3 py-2 text-sm ' +
247
+ 'focus:outline-none focus:ring-2 focus:ring-blue-500 ' +
248
+ 'dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100';
249
+
250
+ const LABEL_CLS = 'block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1';
251
+
252
+ function renderInput(field: FieldInfo): string[] {
253
+ const requiredMark = field.required ? ' *' : '';
254
+ const reqAttr = field.required ? ' required' : '';
255
+
256
+ // Enum → <select>
257
+ if (field.values && field.values.length > 0) {
258
+ const options = field.values
259
+ .map(v => ` <option value="${escapeAttr(v)}">${escapeText(v)}</option>`)
260
+ .join('\n');
261
+ return [
262
+ ' <div>',
263
+ ` <label className="${LABEL_CLS}" htmlFor="${field.name}">${field.label}${requiredMark}</label>`,
264
+ ` <select`,
265
+ ` id="${field.name}"`,
266
+ ` className="${INPUT_CLS}"`,
267
+ ` value={String((formData as any).${field.name} ?? '')}`,
268
+ ` onChange={e => handleChange('${field.name}', e.target.value)}${reqAttr}`,
269
+ ` >`,
270
+ ` <option value="">— choose —</option>`,
271
+ options,
272
+ ` </select>`,
273
+ ' </div>',
274
+ ];
275
+ }
276
+
277
+ // Long-string / Text → <textarea>
278
+ if (field.type === 'Text' || field.isLongString) {
279
+ return [
280
+ ' <div>',
281
+ ` <label className="${LABEL_CLS}" htmlFor="${field.name}">${field.label}${requiredMark}</label>`,
282
+ ` <textarea`,
283
+ ` id="${field.name}"`,
284
+ ` className="${INPUT_CLS}"`,
285
+ ` rows={4}`,
286
+ ` value={String((formData as any).${field.name} ?? '')}`,
287
+ ` onChange={e => handleChange('${field.name}', e.target.value)}${reqAttr}`,
288
+ ` />`,
289
+ ' </div>',
290
+ ];
291
+ }
292
+
293
+ // Boolean → checkbox
294
+ if (field.type === 'Boolean') {
295
+ return [
296
+ ' <div>',
297
+ ` <label className="inline-flex items-center gap-2">`,
298
+ ` <input`,
299
+ ` id="${field.name}"`,
300
+ ` type="checkbox"`,
301
+ ` checked={Boolean((formData as any).${field.name})}`,
302
+ ` onChange={e => handleChange('${field.name}', e.target.checked)}`,
303
+ ` />`,
304
+ ` <span className="text-sm text-gray-700 dark:text-gray-300">${field.label}${requiredMark}</span>`,
305
+ ` </label>`,
306
+ ' </div>',
307
+ ];
308
+ }
309
+
310
+ const inputType = mapInputType(field.type);
311
+ return [
312
+ ' <div>',
313
+ ` <label className="${LABEL_CLS}" htmlFor="${field.name}">${field.label}${requiredMark}</label>`,
314
+ ` <input`,
315
+ ` id="${field.name}"`,
316
+ ` type="${inputType}"`,
317
+ ` className="${INPUT_CLS}"`,
318
+ ` value={String((formData as any).${field.name} ?? '')}`,
319
+ ` onChange={e => handleChange('${field.name}', ${coerceOnChange(field.type)})}${reqAttr}`,
320
+ ` />`,
321
+ ' </div>',
322
+ ];
323
+ }
324
+
325
+ /** Scalar SpecVerse type → HTML input type attribute. */
326
+ function mapInputType(type: string): string {
327
+ switch (type) {
328
+ case 'Integer':
329
+ case 'Float':
330
+ case 'Number':
331
+ case 'Money':
332
+ return 'number';
333
+ case 'DateTime':
334
+ return 'datetime-local';
335
+ case 'Date':
336
+ return 'date';
337
+ case 'Email':
338
+ return 'email';
339
+ case 'URL':
340
+ return 'url';
341
+ case 'String':
342
+ case 'UUID':
343
+ default:
344
+ return 'text';
345
+ }
346
+ }
347
+
348
+ /**
349
+ * JSX snippet for the onChange handler's second argument — coerces
350
+ * the string value to the right shape for the field. The user can
351
+ * edit this; defaults are a reasonable starter.
352
+ */
353
+ function coerceOnChange(type: string): string {
354
+ switch (type) {
355
+ case 'Integer':
356
+ case 'Number':
357
+ return "e.target.value === '' ? undefined : Number(e.target.value)";
358
+ case 'Float':
359
+ case 'Money':
360
+ return "e.target.value === '' ? undefined : parseFloat(e.target.value)";
361
+ default:
362
+ return 'e.target.value';
363
+ }
364
+ }
365
+
366
+ // ──────────────────────────────────────────────────────────────────────
367
+ // Small helpers
368
+ // ──────────────────────────────────────────────────────────────────────
369
+
370
+ function humanize(name: string): string {
371
+ return name
372
+ .replace(/([A-Z])/g, ' $1')
373
+ .replace(/^./, c => c.toUpperCase())
374
+ .trim();
375
+ }
376
+
377
+ function escapeAttr(s: string): string {
378
+ return s.replace(/"/g, '&quot;');
379
+ }
380
+
381
+ function escapeText(s: string): string {
382
+ return s.replace(/</g, '&lt;').replace(/>/g, '&gt;');
383
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Helpers emitter for ReactAppStarter
3
+ *
4
+ * Returns the source of small utility files that generated projects
5
+ * use. Inlined into `src/lib/` at realize time rather than imported
6
+ * from `@specverse/runtime` — Factory B's defining trait is that the
7
+ * generated code has no @specverse/* runtime dependency.
8
+ */
9
+
10
+ /**
11
+ * Source of `src/lib/entity-display.ts`.
12
+ *
13
+ * Mirrors `getEntityDisplayName` from
14
+ * `@specverse/runtime/views/core/entity-display`. Used by:
15
+ * - The FK-resolution TODO in detail-view output (users who upgrade
16
+ * the plain-FK display to a resolved display name import this).
17
+ * - Any user-written code that wants to label a record.
18
+ */
19
+ export function emitEntityDisplay(): string {
20
+ return `/**
21
+ * Pick the best human-readable label for an entity.
22
+ *
23
+ * Walks a prioritized list of candidate fields. Falls back to a
24
+ * truncated id if none match. Inlined into this project by
25
+ * @specverse/realize (ReactAppStarter); edit freely — nothing in
26
+ * the factory's regeneration will clobber your edits.
27
+ */
28
+ export function getEntityDisplayName(entity: Record<string, unknown> | null | undefined): string {
29
+ if (!entity) return '';
30
+
31
+ const candidates = ['name', 'title', 'displayName', 'label', 'username', 'email'];
32
+ for (const key of candidates) {
33
+ const value = entity[key];
34
+ if (typeof value === 'string' && value.trim().length > 0) {
35
+ return value;
36
+ }
37
+ }
38
+
39
+ const id = entity.id;
40
+ if (typeof id === 'string') {
41
+ return id.length > 8 ? id.slice(0, 8) + '…' : id;
42
+ }
43
+ return id != null ? String(id) : '';
44
+ }
45
+
46
+ /**
47
+ * Map an entity id to the display name of the record with that id in
48
+ * a provided list. Handy for resolving belongsTo FK columns in
49
+ * list / detail / dashboard views.
50
+ *
51
+ * Typed as \`readonly unknown[]\` so callers can pass arrays of
52
+ * specific model types (e.g. \`User[]\`) without needing to cast; the
53
+ * runtime check on \`.id\` narrows safely.
54
+ */
55
+ export function resolveEntityDisplayName(
56
+ id: unknown,
57
+ records: readonly unknown[]
58
+ ): string {
59
+ if (id == null) return '';
60
+ const match = records.find((r): r is Record<string, unknown> =>
61
+ typeof r === 'object' && r !== null && (r as { id?: unknown }).id === id
62
+ );
63
+ return match ? getEntityDisplayName(match) : String(id);
64
+ }
65
+ `;
66
+ }