@metaobjectsdev/codegen-ts 0.9.0-rc.1 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (323) hide show
  1. package/README.md +1 -1
  2. package/dist/column-mapper.d.ts.map +1 -1
  3. package/dist/column-mapper.js +24 -8
  4. package/dist/column-mapper.js.map +1 -1
  5. package/dist/constants.d.ts +8 -0
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/constants.js +16 -0
  8. package/dist/constants.js.map +1 -1
  9. package/dist/docs-paths.d.ts +58 -0
  10. package/dist/docs-paths.d.ts.map +1 -0
  11. package/dist/docs-paths.js +89 -0
  12. package/dist/docs-paths.js.map +1 -0
  13. package/dist/enum-import.d.ts +14 -0
  14. package/dist/enum-import.d.ts.map +1 -0
  15. package/dist/enum-import.js +35 -0
  16. package/dist/enum-import.js.map +1 -0
  17. package/dist/enum-shared.d.ts +32 -0
  18. package/dist/enum-shared.d.ts.map +1 -0
  19. package/dist/enum-shared.js +83 -0
  20. package/dist/enum-shared.js.map +1 -0
  21. package/dist/generator-registry.d.ts +22 -0
  22. package/dist/generator-registry.d.ts.map +1 -0
  23. package/dist/generator-registry.js +161 -0
  24. package/dist/generator-registry.js.map +1 -0
  25. package/dist/generator.d.ts +6 -0
  26. package/dist/generator.d.ts.map +1 -1
  27. package/dist/generator.js.map +1 -1
  28. package/dist/generators/api-doc-render.d.ts +17 -0
  29. package/dist/generators/api-doc-render.d.ts.map +1 -0
  30. package/dist/generators/api-doc-render.js +431 -0
  31. package/dist/generators/api-doc-render.js.map +1 -0
  32. package/dist/generators/api-docs-file.d.ts +21 -0
  33. package/dist/generators/api-docs-file.d.ts.map +1 -0
  34. package/dist/generators/api-docs-file.js +112 -0
  35. package/dist/generators/api-docs-file.js.map +1 -0
  36. package/dist/generators/api-field-shape.d.ts +39 -0
  37. package/dist/generators/api-field-shape.d.ts.map +1 -0
  38. package/dist/generators/api-field-shape.js +92 -0
  39. package/dist/generators/api-field-shape.js.map +1 -0
  40. package/dist/generators/api-label.d.ts +3 -0
  41. package/dist/generators/api-label.d.ts.map +1 -0
  42. package/dist/generators/api-label.js +8 -0
  43. package/dist/generators/api-label.js.map +1 -0
  44. package/dist/generators/api-model.d.ts +122 -0
  45. package/dist/generators/api-model.d.ts.map +1 -0
  46. package/dist/generators/api-model.js +809 -0
  47. package/dist/generators/api-model.js.map +1 -0
  48. package/dist/generators/docs-data-builder.d.ts +26 -4
  49. package/dist/generators/docs-data-builder.d.ts.map +1 -1
  50. package/dist/generators/docs-data-builder.js +436 -164
  51. package/dist/generators/docs-data-builder.js.map +1 -1
  52. package/dist/generators/docs-data.d.ts +136 -27
  53. package/dist/generators/docs-data.d.ts.map +1 -1
  54. package/dist/generators/docs-data.js +1 -1
  55. package/dist/generators/docs-data.js.map +1 -1
  56. package/dist/generators/docs-file.d.ts +19 -0
  57. package/dist/generators/docs-file.d.ts.map +1 -1
  58. package/dist/generators/docs-file.js +154 -27
  59. package/dist/generators/docs-file.js.map +1 -1
  60. package/dist/generators/entity-file.d.ts.map +1 -1
  61. package/dist/generators/entity-file.js +29 -14
  62. package/dist/generators/entity-file.js.map +1 -1
  63. package/dist/generators/extractor-file.d.ts.map +1 -1
  64. package/dist/generators/extractor-file.js +2 -1
  65. package/dist/generators/extractor-file.js.map +1 -1
  66. package/dist/generators/field-anchor.d.ts +7 -0
  67. package/dist/generators/field-anchor.d.ts.map +1 -0
  68. package/dist/generators/field-anchor.js +23 -0
  69. package/dist/generators/field-anchor.js.map +1 -0
  70. package/dist/generators/index.d.ts +8 -1
  71. package/dist/generators/index.d.ts.map +1 -1
  72. package/dist/generators/index.js +6 -0
  73. package/dist/generators/index.js.map +1 -1
  74. package/dist/generators/mermaid-er.d.ts +14 -0
  75. package/dist/generators/mermaid-er.d.ts.map +1 -1
  76. package/dist/generators/mermaid-er.js +14 -0
  77. package/dist/generators/mermaid-er.js.map +1 -1
  78. package/dist/generators/output-parser-file.d.ts.map +1 -1
  79. package/dist/generators/output-parser-file.js +3 -4
  80. package/dist/generators/output-parser-file.js.map +1 -1
  81. package/dist/generators/output-prompt-file.d.ts.map +1 -1
  82. package/dist/generators/output-prompt-file.js +2 -2
  83. package/dist/generators/output-prompt-file.js.map +1 -1
  84. package/dist/generators/prompt-render-file.d.ts.map +1 -1
  85. package/dist/generators/prompt-render-file.js +3 -4
  86. package/dist/generators/prompt-render-file.js.map +1 -1
  87. package/dist/generators/queries-file.d.ts.map +1 -1
  88. package/dist/generators/queries-file.js +8 -3
  89. package/dist/generators/queries-file.js.map +1 -1
  90. package/dist/generators/render-helper-file.d.ts.map +1 -1
  91. package/dist/generators/render-helper-file.js +2 -2
  92. package/dist/generators/render-helper-file.js.map +1 -1
  93. package/dist/generators/routes-file-hono.d.ts.map +1 -1
  94. package/dist/generators/routes-file-hono.js +5 -1
  95. package/dist/generators/routes-file-hono.js.map +1 -1
  96. package/dist/generators/routes-file.d.ts +3 -0
  97. package/dist/generators/routes-file.d.ts.map +1 -1
  98. package/dist/generators/routes-file.js +6 -1
  99. package/dist/generators/routes-file.js.map +1 -1
  100. package/dist/generators/template-doc-builder.d.ts +19 -0
  101. package/dist/generators/template-doc-builder.d.ts.map +1 -0
  102. package/dist/generators/template-doc-builder.js +220 -0
  103. package/dist/generators/template-doc-builder.js.map +1 -0
  104. package/dist/generators/template-doc-data.d.ts +62 -0
  105. package/dist/generators/template-doc-data.d.ts.map +1 -0
  106. package/dist/generators/template-doc-data.js +16 -0
  107. package/dist/generators/template-doc-data.js.map +1 -0
  108. package/dist/generators/template-payload-tree.d.ts +15 -0
  109. package/dist/generators/template-payload-tree.d.ts.map +1 -0
  110. package/dist/generators/template-payload-tree.js +61 -0
  111. package/dist/generators/template-payload-tree.js.map +1 -0
  112. package/dist/generators/template-source-annotate.d.ts +74 -0
  113. package/dist/generators/template-source-annotate.d.ts.map +1 -0
  114. package/dist/generators/template-source-annotate.js +184 -0
  115. package/dist/generators/template-source-annotate.js.map +1 -0
  116. package/dist/generators/template-source-render.d.ts +24 -0
  117. package/dist/generators/template-source-render.d.ts.map +1 -0
  118. package/dist/generators/template-source-render.js +175 -0
  119. package/dist/generators/template-source-render.js.map +1 -0
  120. package/dist/generators/trace-helper-file.d.ts +9 -0
  121. package/dist/generators/trace-helper-file.d.ts.map +1 -0
  122. package/dist/generators/trace-helper-file.js +196 -0
  123. package/dist/generators/trace-helper-file.js.map +1 -0
  124. package/dist/index.d.ts +29 -4
  125. package/dist/index.d.ts.map +1 -1
  126. package/dist/index.js +28 -2
  127. package/dist/index.js.map +1 -1
  128. package/dist/metaobjects-config.d.ts +75 -2
  129. package/dist/metaobjects-config.d.ts.map +1 -1
  130. package/dist/metaobjects-config.js +43 -0
  131. package/dist/metaobjects-config.js.map +1 -1
  132. package/dist/naming.d.ts +19 -0
  133. package/dist/naming.d.ts.map +1 -1
  134. package/dist/naming.js +41 -0
  135. package/dist/naming.js.map +1 -1
  136. package/dist/payload-codegen.d.ts.map +1 -1
  137. package/dist/payload-codegen.js +12 -4
  138. package/dist/payload-codegen.js.map +1 -1
  139. package/dist/projection/extract-view-spec.d.ts.map +1 -1
  140. package/dist/projection/extract-view-spec.js +51 -25
  141. package/dist/projection/extract-view-spec.js.map +1 -1
  142. package/dist/relation-resolver.d.ts +16 -0
  143. package/dist/relation-resolver.d.ts.map +1 -1
  144. package/dist/relation-resolver.js +82 -1
  145. package/dist/relation-resolver.js.map +1 -1
  146. package/dist/render-context.d.ts +4 -0
  147. package/dist/render-context.d.ts.map +1 -1
  148. package/dist/render-context.js.map +1 -1
  149. package/dist/render-engine/embedded-templates.generated.d.ts +2 -0
  150. package/dist/render-engine/embedded-templates.generated.d.ts.map +1 -0
  151. package/dist/render-engine/embedded-templates.generated.js +15 -0
  152. package/dist/render-engine/embedded-templates.generated.js.map +1 -0
  153. package/dist/render-engine/framework-provider.d.ts.map +1 -1
  154. package/dist/render-engine/framework-provider.js +26 -13
  155. package/dist/render-engine/framework-provider.js.map +1 -1
  156. package/dist/runner.d.ts.map +1 -1
  157. package/dist/runner.js +17 -0
  158. package/dist/runner.js.map +1 -1
  159. package/dist/templates/docs-file.d.ts +2 -6
  160. package/dist/templates/docs-file.d.ts.map +1 -1
  161. package/dist/templates/docs-file.js +2 -5
  162. package/dist/templates/docs-file.js.map +1 -1
  163. package/dist/templates/drizzle-schema.d.ts.map +1 -1
  164. package/dist/templates/drizzle-schema.js +30 -2
  165. package/dist/templates/drizzle-schema.js.map +1 -1
  166. package/dist/templates/entity-constants.d.ts +7 -0
  167. package/dist/templates/entity-constants.d.ts.map +1 -1
  168. package/dist/templates/entity-constants.js +1 -1
  169. package/dist/templates/entity-constants.js.map +1 -1
  170. package/dist/templates/entity-file.d.ts.map +1 -1
  171. package/dist/templates/entity-file.js +16 -5
  172. package/dist/templates/entity-file.js.map +1 -1
  173. package/dist/templates/enums-file.d.ts +11 -0
  174. package/dist/templates/enums-file.d.ts.map +1 -0
  175. package/dist/templates/enums-file.js +44 -0
  176. package/dist/templates/enums-file.js.map +1 -0
  177. package/dist/templates/extract-delegate-emitter.d.ts.map +1 -1
  178. package/dist/templates/extract-delegate-emitter.js +5 -7
  179. package/dist/templates/extract-delegate-emitter.js.map +1 -1
  180. package/dist/templates/extract-schema-emitter.d.ts.map +1 -1
  181. package/dist/templates/extract-schema-emitter.js +5 -1
  182. package/dist/templates/extract-schema-emitter.js.map +1 -1
  183. package/dist/templates/extractor.d.ts.map +1 -1
  184. package/dist/templates/extractor.js +56 -39
  185. package/dist/templates/extractor.js.map +1 -1
  186. package/dist/templates/field-meta.d.ts.map +1 -1
  187. package/dist/templates/field-meta.js +1 -5
  188. package/dist/templates/field-meta.js.map +1 -1
  189. package/dist/templates/filter-allowlist.d.ts +7 -2
  190. package/dist/templates/filter-allowlist.d.ts.map +1 -1
  191. package/dist/templates/filter-allowlist.js +17 -9
  192. package/dist/templates/filter-allowlist.js.map +1 -1
  193. package/dist/templates/filter-type.d.ts +7 -1
  194. package/dist/templates/filter-type.d.ts.map +1 -1
  195. package/dist/templates/filter-type.js +9 -5
  196. package/dist/templates/filter-type.js.map +1 -1
  197. package/dist/templates/find-templates.d.ts +4 -0
  198. package/dist/templates/find-templates.d.ts.map +1 -0
  199. package/dist/templates/find-templates.js +15 -0
  200. package/dist/templates/find-templates.js.map +1 -0
  201. package/dist/templates/fr010-field-mapping.d.ts +2 -0
  202. package/dist/templates/fr010-field-mapping.d.ts.map +1 -1
  203. package/dist/templates/fr010-field-mapping.js +10 -6
  204. package/dist/templates/fr010-field-mapping.js.map +1 -1
  205. package/dist/templates/inferred-types.d.ts +44 -7
  206. package/dist/templates/inferred-types.d.ts.map +1 -1
  207. package/dist/templates/inferred-types.js +107 -16
  208. package/dist/templates/inferred-types.js.map +1 -1
  209. package/dist/templates/mermaid-er.d.ts +35 -2
  210. package/dist/templates/mermaid-er.d.ts.map +1 -1
  211. package/dist/templates/mermaid-er.js +174 -7
  212. package/dist/templates/mermaid-er.js.map +1 -1
  213. package/dist/templates/output-parser.d.ts.map +1 -1
  214. package/dist/templates/output-parser.js +30 -79
  215. package/dist/templates/output-parser.js.map +1 -1
  216. package/dist/templates/output-prompt.d.ts.map +1 -1
  217. package/dist/templates/output-prompt.js +2 -2
  218. package/dist/templates/output-prompt.js.map +1 -1
  219. package/dist/templates/queries-file.d.ts.map +1 -1
  220. package/dist/templates/queries-file.js +112 -4
  221. package/dist/templates/queries-file.js.map +1 -1
  222. package/dist/templates/queries.d.ts +5 -0
  223. package/dist/templates/queries.d.ts.map +1 -1
  224. package/dist/templates/queries.js +7 -7
  225. package/dist/templates/queries.js.map +1 -1
  226. package/dist/templates/recover-schema-emitter.d.ts +8 -0
  227. package/dist/templates/recover-schema-emitter.d.ts.map +1 -0
  228. package/dist/templates/recover-schema-emitter.js +64 -0
  229. package/dist/templates/recover-schema-emitter.js.map +1 -0
  230. package/dist/templates/relations-block.js +10 -0
  231. package/dist/templates/relations-block.js.map +1 -1
  232. package/dist/templates/render-helper.d.ts.map +1 -1
  233. package/dist/templates/render-helper.js +4 -4
  234. package/dist/templates/render-helper.js.map +1 -1
  235. package/dist/templates/routes-file.d.ts.map +1 -1
  236. package/dist/templates/routes-file.js +183 -6
  237. package/dist/templates/routes-file.js.map +1 -1
  238. package/dist/templates/tph-discriminator.d.ts +56 -0
  239. package/dist/templates/tph-discriminator.d.ts.map +1 -0
  240. package/dist/templates/tph-discriminator.js +180 -0
  241. package/dist/templates/tph-discriminator.js.map +1 -0
  242. package/dist/templates/value-object-file.d.ts +2 -1
  243. package/dist/templates/value-object-file.d.ts.map +1 -1
  244. package/dist/templates/value-object-file.js +32 -4
  245. package/dist/templates/value-object-file.js.map +1 -1
  246. package/dist/templates/zod-validators.d.ts +64 -1
  247. package/dist/templates/zod-validators.d.ts.map +1 -1
  248. package/dist/templates/zod-validators.js +181 -8
  249. package/dist/templates/zod-validators.js.map +1 -1
  250. package/package.json +103 -34
  251. package/src/column-mapper.ts +25 -8
  252. package/src/constants.ts +18 -0
  253. package/src/docs-paths.ts +128 -0
  254. package/src/enum-import.ts +43 -0
  255. package/src/enum-shared.ts +95 -0
  256. package/src/generator-registry.ts +204 -0
  257. package/src/generator.ts +6 -0
  258. package/src/generators/api-doc-render.ts +572 -0
  259. package/src/generators/api-docs-file.ts +146 -0
  260. package/src/generators/api-field-shape.ts +114 -0
  261. package/src/generators/api-label.ts +7 -0
  262. package/src/generators/api-model.ts +1067 -0
  263. package/src/generators/docs-data-builder.ts +479 -185
  264. package/src/generators/docs-data.ts +139 -28
  265. package/src/generators/docs-file.ts +205 -39
  266. package/src/generators/entity-file.ts +31 -15
  267. package/src/generators/extractor-file.ts +2 -1
  268. package/src/generators/field-anchor.ts +24 -0
  269. package/src/generators/index.ts +8 -1
  270. package/src/generators/mermaid-er.ts +14 -0
  271. package/src/generators/output-parser-file.ts +3 -4
  272. package/src/generators/output-prompt-file.ts +2 -1
  273. package/src/generators/prompt-render-file.ts +3 -4
  274. package/src/generators/queries-file.ts +9 -3
  275. package/src/generators/render-helper-file.ts +2 -1
  276. package/src/generators/routes-file-hono.ts +5 -1
  277. package/src/generators/routes-file.ts +7 -1
  278. package/src/generators/template-doc-builder.ts +306 -0
  279. package/src/generators/template-doc-data.ts +85 -0
  280. package/src/generators/template-payload-tree.ts +71 -0
  281. package/src/generators/template-source-annotate.ts +290 -0
  282. package/src/generators/template-source-render.ts +203 -0
  283. package/src/generators/trace-helper-file.ts +301 -0
  284. package/src/index.ts +55 -4
  285. package/src/metaobjects-config.ts +117 -2
  286. package/src/naming.ts +48 -0
  287. package/src/payload-codegen.ts +14 -3
  288. package/src/projection/extract-view-spec.ts +49 -30
  289. package/src/relation-resolver.ts +103 -1
  290. package/src/render-context.ts +4 -0
  291. package/src/render-engine/embedded-templates.generated.ts +14 -0
  292. package/src/render-engine/framework-provider.ts +25 -11
  293. package/src/runner.ts +21 -0
  294. package/src/templates/docs-file.ts +2 -9
  295. package/src/templates/drizzle-schema.ts +31 -1
  296. package/src/templates/entity-constants.ts +1 -1
  297. package/src/templates/entity-file.ts +16 -5
  298. package/src/templates/enums-file.ts +50 -0
  299. package/src/templates/extract-delegate-emitter.ts +5 -6
  300. package/src/templates/extractor.ts +68 -38
  301. package/src/templates/field-meta.ts +0 -6
  302. package/src/templates/filter-allowlist.ts +17 -10
  303. package/src/templates/filter-type.ts +8 -6
  304. package/src/templates/find-templates.ts +15 -0
  305. package/src/templates/fr010-field-mapping.ts +10 -8
  306. package/src/templates/inferred-types.ts +108 -18
  307. package/src/templates/mermaid-er.ts +176 -8
  308. package/src/templates/output-parser.ts +30 -79
  309. package/src/templates/output-prompt.ts +2 -1
  310. package/src/templates/queries-file.ts +132 -3
  311. package/src/templates/queries.ts +15 -7
  312. package/src/templates/relations-block.ts +17 -0
  313. package/src/templates/render-helper.ts +4 -3
  314. package/src/templates/routes-file.ts +233 -6
  315. package/src/templates/tph-discriminator.ts +232 -0
  316. package/src/templates/value-object-file.ts +38 -4
  317. package/src/templates/zod-validators.ts +204 -7
  318. package/templates/api/agent-api.md.mustache +30 -0
  319. package/templates/api/entity-api.md.mustache +69 -0
  320. package/templates/api/index.md.mustache +21 -0
  321. package/templates/docs/entity-page.md.mustache +33 -21
  322. package/templates/docs/template-page.md.mustache +56 -0
  323. package/src/templates/extract-schema-emitter.ts +0 -111
@@ -0,0 +1,161 @@
1
+ // ADR-0021 D3 — stable-name generator registry.
2
+ //
3
+ // Generators are identified by a STABLE string id (e.g. `entity`, `routes`,
4
+ // `render-helper`) rather than by a language-specific factory import. The id is
5
+ // the cross-port contract: the same logical generator carries the same stable
6
+ // name in every port. This module is the discoverability + identity surface
7
+ // behind `meta gen --list`.
8
+ //
9
+ // It is ADDITIVE. The existing `defineConfig({ generators: [entityFile(), ...] })`
10
+ // factory-array config keeps working unchanged — the registry powers `--list`
11
+ // and a stable identity, it does not replace the config path.
12
+ //
13
+ // Tiering (ADR-0020 / ADR-0021 D1):
14
+ // - "native" — the recommended Tier-1 `meta gen` suite (idiomatic emission).
15
+ // - "neutral" — Tier-2 artifacts owned by the neutral docs engine. `docs` and
16
+ // `mermaid-er` are present here for identity/discoverability but
17
+ // are NOT part of the recommended native surface — the canonical
18
+ // door for documentation is `meta docs` (D1).
19
+ import { entityFile, queriesFile, callableFile, routesFile, routesFileHono, barrel, mermaidErDiagram, promptRender, outputParser, extractor, outputPrompt, renderHelper, apiDocsFile, docsFile, templateGenerator, traceHelperFile, } from "./generators/index.js";
20
+ // The `template` generator is a PRIMITIVE: callers supply { name, walk,
21
+ // template }. For registry identity + `--list` we expose a no-op default so the
22
+ // factory constructs a valid Generator without throwing; real use passes opts
23
+ // via the config factory-array path. (docsFile() is the first instance of this
24
+ // primitive — see template-generator.ts.)
25
+ function templatePrimitive() {
26
+ return templateGenerator({
27
+ name: "template",
28
+ template: "",
29
+ walk: () => [],
30
+ });
31
+ }
32
+ export const generatorRegistry = {
33
+ // ----- Tier-1 native suite (idiomatic per-port emission) -----------------
34
+ entity: {
35
+ name: "entity",
36
+ description: "Per-entity Drizzle table + typed model module (the entity module).",
37
+ tier: "native",
38
+ factory: () => entityFile(),
39
+ options: "filter?, target?",
40
+ },
41
+ queries: {
42
+ name: "queries",
43
+ description: "Per-entity typed query helpers (findById/create/...).",
44
+ tier: "native",
45
+ factory: () => queriesFile(),
46
+ options: "filter?, target?",
47
+ },
48
+ callable: {
49
+ name: "callable",
50
+ description: "Per-entity callable/service surface wrapping the query helpers.",
51
+ tier: "native",
52
+ factory: () => callableFile(),
53
+ options: "filter?, target?",
54
+ },
55
+ routes: {
56
+ name: "routes",
57
+ description: "Per-entity Fastify CRUD routes (drizzle-fastify mountCrudRoutes).",
58
+ tier: "native",
59
+ factory: () => routesFile(),
60
+ options: "filter?, target?",
61
+ },
62
+ "routes-hono": {
63
+ name: "routes-hono",
64
+ description: "Per-entity Hono CRUD routes (runtime-ts/hono mountCrudRoutes).",
65
+ tier: "native",
66
+ factory: () => routesFileHono(),
67
+ options: "filter?, target?",
68
+ },
69
+ barrel: {
70
+ name: "barrel",
71
+ description: "Single index.ts re-exporting every generated entity module.",
72
+ tier: "native",
73
+ factory: () => barrel(),
74
+ options: "target?",
75
+ },
76
+ "prompt-render": {
77
+ name: "prompt-render",
78
+ description: "Per-template prompt-render helper over the render engine.",
79
+ tier: "native",
80
+ factory: () => promptRender(),
81
+ options: "filter?, target?",
82
+ },
83
+ "output-parser": {
84
+ name: "output-parser",
85
+ description: "Per-template tolerant output parser (recover-on-receipt).",
86
+ tier: "native",
87
+ factory: () => outputParser(),
88
+ options: "filter?, target?",
89
+ },
90
+ extractor: {
91
+ name: "extractor",
92
+ description: "Per-template typed extract<Name> helper (strict payload extraction).",
93
+ tier: "native",
94
+ factory: () => extractor(),
95
+ options: "filter?, target?",
96
+ },
97
+ "output-prompt": {
98
+ name: "output-prompt",
99
+ description: "Per-template output-format prompt fragment generator.",
100
+ tier: "native",
101
+ factory: () => outputPrompt(),
102
+ options: "filter?, target?",
103
+ },
104
+ "render-helper": {
105
+ name: "render-helper",
106
+ description: "Per-template.output render helper (document/email typed wrappers).",
107
+ tier: "native",
108
+ factory: () => renderHelper(),
109
+ options: "filter?, target?",
110
+ },
111
+ template: {
112
+ name: "template",
113
+ description: "Generic Mustache template primitive (walk + template → files).",
114
+ tier: "native",
115
+ factory: () => templatePrimitive(),
116
+ options: "name, walk, template, format?, filter?, provider?, target?",
117
+ },
118
+ "api-docs": {
119
+ name: "api-docs",
120
+ description: "Per-entity/template SDK API reference (the generated code's API, human + agent forms).",
121
+ tier: "native",
122
+ factory: () => apiDocsFile(),
123
+ options: "filter?, target?",
124
+ },
125
+ "trace-helper": {
126
+ name: "trace-helper",
127
+ description: "Per-entity typed record<Entity>/call<Entity> trace helpers (extract + buildLlmCallRow + persist; LlmCallBase-derived entities only).",
128
+ tier: "native",
129
+ factory: () => traceHelperFile(),
130
+ options: "outDir?, target?",
131
+ },
132
+ // ----- Tier-2 neutral (owned by the `meta docs` engine — D1 / ADR-0020) ---
133
+ docs: {
134
+ name: "docs",
135
+ description: "Neutral per-entity / per-template Markdown documentation pages.",
136
+ tier: "neutral",
137
+ factory: () => docsFile(),
138
+ note: "neutral artifact — use `meta docs` (the single docs door, ADR-0021 D1); not part of the recommended `meta gen` native suite.",
139
+ },
140
+ "mermaid-er": {
141
+ name: "mermaid-er",
142
+ description: "Mermaid ER diagram of the entity/relationship model.",
143
+ tier: "neutral",
144
+ factory: () => mermaidErDiagram(),
145
+ note: "neutral artifact owned by the docs engine (ADR-0020); surfaced via `meta docs`, not the recommended `meta gen` native suite.",
146
+ },
147
+ };
148
+ /** All registry entries, native first then neutral, alphabetical within tier. */
149
+ export function listGenerators() {
150
+ const entries = Object.values(generatorRegistry);
151
+ const byName = (a, b) => a.name.localeCompare(b.name);
152
+ return [
153
+ ...entries.filter((e) => e.tier === "native").sort(byName),
154
+ ...entries.filter((e) => e.tier === "neutral").sort(byName),
155
+ ];
156
+ }
157
+ /** Resolve a generator entry by its stable id, or undefined if unknown. */
158
+ export function getGenerator(id) {
159
+ return generatorRegistry[id];
160
+ }
161
+ //# sourceMappingURL=generator-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator-registry.js","sourceRoot":"","sources":["../src/generator-registry.ts"],"names":[],"mappings":"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"}
@@ -44,6 +44,12 @@ export interface Generator {
44
44
  /** Marks the generator that produces entity modules — the runner uses its
45
45
  * target as the entity-module target for cross-target import resolution. */
46
46
  emitsEntityModule?: boolean;
47
+ /** Marks the OPT-IN Hono routes generator (routesFileHono). The runner
48
+ * aggregates this across the active suite into `ctx.config.includeHonoRoutes`,
49
+ * so a generator that documents the API surface (api-docs) can AUTO-DETECT
50
+ * that Hono routes are actually being emitted and document them — rather than
51
+ * silently omitting the Hono CRUD registrars whenever the variant is wired. */
52
+ emitsHonoRoutes?: boolean;
47
53
  }
48
54
  export type GeneratorFactory<TOpts = void> = TOpts extends void ? () => Generator : (opts?: TOpts) => Generator;
49
55
  /** One-file-per-entity convenience. Async-safe. */
@@ -1 +1 @@
1
- {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,MAAM,WAAW,WAAW;IAC1B,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,UAAU,EAAE,QAAQ,CAAC;IACrB;;oBAEgB;IAChB,OAAO,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC;IACzC,MAAM,EAAE,iBAAiB,CAAC;IAC1B;;;gEAG4D;IAC5D,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;;;;;4DAOwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC;IACzC,QAAQ,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,WAAW,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACtE,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;iFAC6E;IAC7E,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,MAAM,gBAAgB,CAAC,KAAK,GAAG,IAAI,IAAI,KAAK,SAAS,IAAI,GAC3D,MAAM,SAAS,GACf,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,SAAS,CAAC;AAEhC,mDAAmD;AACnD,wBAAgB,SAAS,CACvB,EAAE,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,KACpC,WAAW,GACX,WAAW,EAAE,GACb,OAAO,CAAC,WAAW,GAAG,WAAW,EAAE,CAAC,GACvC,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAM7C;AAED,sFAAsF;AACtF,wBAAgB,UAAU,CACxB,EAAE,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,UAAU,KACxC,WAAW,GACX,WAAW,EAAE,GACb,OAAO,CAAC,WAAW,GAAG,WAAW,EAAE,CAAC,GACvC,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAM7C"}
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE,MAAM,WAAW,WAAW;IAC1B,iDAAiD;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,UAAU,EAAE,CAAC;IACvB,UAAU,EAAE,QAAQ,CAAC;IACrB;;oBAEgB;IAChB,OAAO,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC;IACzC,MAAM,EAAE,iBAAiB,CAAC;IAC1B;;;gEAG4D;IAC5D,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;;;;;4DAOwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC;IACzC,QAAQ,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,WAAW,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACtE,iEAAiE;IACjE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;iFAC6E;IAC7E,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;oFAIgF;IAChF,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,MAAM,gBAAgB,CAAC,KAAK,GAAG,IAAI,IAAI,KAAK,SAAS,IAAI,GAC3D,MAAM,SAAS,GACf,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,SAAS,CAAC;AAEhC,mDAAmD;AACnD,wBAAgB,SAAS,CACvB,EAAE,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,KACpC,WAAW,GACX,WAAW,EAAE,GACb,OAAO,CAAC,WAAW,GAAG,WAAW,EAAE,CAAC,GACvC,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAM7C;AAED,sFAAsF;AACtF,wBAAgB,UAAU,CACxB,EAAE,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,GAAG,EAAE,UAAU,KACxC,WAAW,GACX,WAAW,EAAE,GACb,OAAO,CAAC,WAAW,GAAG,WAAW,EAAE,CAAC,GACvC,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,CAAC,WAAW,EAAE,CAAC,CAM7C"}
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAuDA,mDAAmD;AACnD,MAAM,UAAU,SAAS,CACvB,EAGwC;IAExC,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;QACnB,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAClE,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC;AACJ,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,UAAU,CACxB,EAGwC;IAExC,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;QACnB,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACtC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AA6DA,mDAAmD;AACnD,MAAM,UAAU,SAAS,CACvB,EAGwC;IAExC,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;QACnB,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAClE,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC;AACJ,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,UAAU,CACxB,EAGwC;IAExC,OAAO,KAAK,EAAE,GAAG,EAAE,EAAE;QACnB,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACtC,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { Provider } from "@metaobjectsdev/render";
2
+ import type { ApiModel, ApiUnitDoc } from "./api-model.js";
3
+ import type { OutputLayout } from "../import-path.js";
4
+ /** Render ONE per-unit human reference page from an ApiUnitDoc, via the shared
5
+ * render() engine + the canonical `api/entity-api.md` template. `modelPageHref`
6
+ * (when given) cross-links the page back to the entity's model/metadata page. */
7
+ export declare function renderEntityApiPage(unit: ApiUnitDoc, provider: Provider, modelPageHref?: string): string;
8
+ /** Render the consolidated human API index (links to each unit page, grouped
9
+ * entity vs template) via the shared render() engine + `api/index.md`. */
10
+ export declare function renderApiIndex(model: ApiModel, layout: OutputLayout, provider: Provider): string;
11
+ /** Render the condensed agent/LLM form: per unit, symbols grouped under a single
12
+ * `import { … } from "<module>"` header then one compact `signature — usage`
13
+ * line each (with a `[throws: …]` marker when it throws), NO prose/examples
14
+ * (token budget). Units keep their ApiModel order; symbols keep their per-unit
15
+ * order (the canonical generator emission order). */
16
+ export declare function renderAgentApi(model: ApiModel, provider: Provider): string;
17
+ //# sourceMappingURL=api-doc-render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-doc-render.d.ts","sourceRoot":"","sources":["../../src/generators/api-doc-render.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAyC,MAAM,gBAAgB,CAAC;AAGlG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AA8StD;;kFAEkF;AAClF,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,QAAQ,EAClB,aAAa,CAAC,EAAE,MAAM,GACrB,MAAM,CASR;AAyDD;2EAC2E;AAC3E,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAehG;AA+GD;;;;sDAIsD;AACtD,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,CA8B1E"}
@@ -0,0 +1,431 @@
1
+ // api-doc-render.ts — the two documentation FORMS that an ApiModel feeds:
2
+ // • a per-unit HUMAN reference page (renderEntityApiPage)
3
+ // • a consolidated HUMAN index (renderApiIndex)
4
+ // • a condensed AGENT/LLM form (renderAgentApi)
5
+ //
6
+ // ADR-0022 Part 3: one ApiModel, two forms — the human prose page and the
7
+ // token-frugal agent form derive from the SAME IR, never re-derived. Rendering
8
+ // goes through the SHARED `render()` Mustache engine against canonical templates
9
+ // under `templates/api/` (resolved via the framework/project provider chain —
10
+ // the same mechanism docs-file.ts uses), so adopters can override a template by
11
+ // dropping their own `templates/api/<ref>.mustache` into their project root.
12
+ //
13
+ // The view-models are pre-rendered here (mirroring docs-data-builder) so the
14
+ // Mustache templates stay logic-light: section grouping, symbol counts, and the
15
+ // collision-safe index hrefs (docPageHref) are computed in TS.
16
+ import { render } from "@metaobjectsdev/render";
17
+ import { inlineShape } from "./api-field-shape.js";
18
+ import { docPageHref } from "../docs-paths.js";
19
+ import { GENERATED_HEADER } from "../constants.js";
20
+ // Template refs (resolved as `templates/api/<ref-tail>.mustache`).
21
+ const ENTITY_PAGE_REF = "api/entity-api.md";
22
+ const INDEX_REF = "api/index.md";
23
+ const AGENT_REF = "api/agent-api.md";
24
+ const GENERATED_MARKER = `<!-- ${GENERATED_HEADER} — DO NOT EDIT. -->`;
25
+ // ---------------------------------------------------------------------------
26
+ // Relative-import RENDER prefix.
27
+ //
28
+ // An `ApiSymbol.importPath` is the generated module's path RELATIVE TO the
29
+ // codegen output dir (flat → `Product.queries`; package → the package-folded
30
+ // `acme/shop/Product.queries`). It is the DATA the accuracy gate verifies
31
+ // against the emitted file, so it stays a bare module path.
32
+ //
33
+ // The generated files import each OTHER with `./`-prefixed RELATIVE specifiers
34
+ // (`from "./Product"`), so a copy-paste consumer co-located in the generated
35
+ // output dir must do the same — a BARE specifier (`from "Product.queries"`)
36
+ // only resolves with a non-default `baseUrl` and otherwise fails TS2307. The
37
+ // renderers therefore `./`-prefix the importPath in every rendered `from "…"`
38
+ // (the human page, the agent group headers, AND the example import blocks),
39
+ // without touching the underlying importPath data. A consumer importing from
40
+ // elsewhere adjusts the prefix (stated once in the page's import note).
41
+ // ---------------------------------------------------------------------------
42
+ /** The `./`-prefixed RELATIVE specifier for a documented module path (the form a
43
+ * co-located consumer copy-pastes). Already-relative paths pass through. */
44
+ function relSpecifier(importPath) {
45
+ return importPath.startsWith("./") || importPath.startsWith("../")
46
+ ? importPath
47
+ : `./${importPath}`;
48
+ }
49
+ /** Rewrite the `from "<module>"` tail of an example `import { … } from "<module>";`
50
+ * line to the `./`-prefixed relative specifier — the example imports are
51
+ * pre-composed in the ApiModel (reusing each symbol's bare importPath), so the
52
+ * `./` prefix is applied at render time alongside the section/header imports. */
53
+ function relImportLine(line) {
54
+ return line.replace(/(\bfrom\s+")([^"]+)(")/, (_m, pre, mod, post) => `${pre}${relSpecifier(mod)}${post}`);
55
+ }
56
+ // The human-facing section ORDER + HEADING per ApiSymbolKind. A unit's page
57
+ // renders only the kinds it actually carries, always in this canonical order
58
+ // (so two runs over the same model are byte-stable regardless of symbol order).
59
+ const KIND_ORDER = [
60
+ "model",
61
+ "relation",
62
+ "data-access",
63
+ "callable",
64
+ "rest",
65
+ "rest-hono",
66
+ "validation",
67
+ "extractor",
68
+ "render",
69
+ "prompt",
70
+ ];
71
+ const KIND_HEADING = {
72
+ model: "Model",
73
+ relation: "Relations",
74
+ "data-access": "Data access",
75
+ callable: "Callable",
76
+ rest: "REST",
77
+ "rest-hono": "REST (Hono)",
78
+ validation: "Validation",
79
+ extractor: "Extractor",
80
+ render: "Render",
81
+ prompt: "Prompt",
82
+ };
83
+ /** A docs-page name for the index href helper. The API index lives at the docs
84
+ * ROOT, so its links to per-unit pages are computed via the same docPageHref
85
+ * used elsewhere (resolves in flat AND package layout). */
86
+ const INDEX_NODE = { name: "index" };
87
+ /** The full set of handles a unit's example may reference. The per-unit page
88
+ * shows only the handles that unit's example actually uses; the agent + index
89
+ * forms show the full set once. */
90
+ /** Build a setup row, deriving the single-line agent snippet from the block one
91
+ * (newlines → `; `, collapsing any blank lines / double semicolons). */
92
+ function setupHandle(handle, note, snippet) {
93
+ const snippetInline = snippet
94
+ .split("\n")
95
+ .map((l) => l.trim())
96
+ .filter((l) => l.length > 0)
97
+ .map((l) => (l.endsWith(";") ? l.slice(0, -1) : l))
98
+ .join("; ");
99
+ return { handle, note, snippet, snippetInline };
100
+ }
101
+ const SETUP_HANDLES = {
102
+ db: setupHandle("db", "your Drizzle connection — the generated queries take `db: Db` (a `NodePgDatabase` / `BaseSQLiteDatabase` alias). Construct one over your own driver and pass any compatible Drizzle instance:", `import { drizzle } from "drizzle-orm/node-postgres";
103
+ import { Pool } from "pg";
104
+ const db = drizzle(new Pool({ connectionString: process.env.DATABASE_URL }));`),
105
+ provider: setupHandle("provider", "the render `Provider` (resolves a template ref to text) — import it from `@metaobjectsdev/render`; `InMemoryProvider` is built in (or supply your own filesystem-backed `Provider`):", `import { InMemoryProvider } from "@metaobjectsdev/render";
106
+ const provider = new InMemoryProvider({ "group/source": "Hello {{name}}" });`),
107
+ root: setupHandle("root", "the loaded `MetaRoot` `extract<Name>` parses against — load your metadata via `@metaobjectsdev/metadata` (the result carries `.root`):", `import { loadDirectory } from "@metaobjectsdev/metadata";
108
+ const { root } = await loadDirectory("./metadata");`),
109
+ };
110
+ /** Which handles a unit's example references (so the page shows only those). */
111
+ function setupHandlesFor(unit) {
112
+ const text = unit.example ? unit.example.body.join("\n") : "";
113
+ const out = [];
114
+ if (/\bdb\b/.test(text))
115
+ out.push(SETUP_HANDLES.db);
116
+ if (/\bprovider\b/.test(text))
117
+ out.push(SETUP_HANDLES.provider);
118
+ if (/\broot\b/.test(text))
119
+ out.push(SETUP_HANDLES.root);
120
+ return out;
121
+ }
122
+ /** A human-page caption for a symbol's field table, by kind + signature shape. */
123
+ function fieldsCaptionFor(s) {
124
+ if (s.kind === "model")
125
+ return "Fields";
126
+ if (s.kind === "validation")
127
+ return "Accepted fields";
128
+ if (s.kind === "prompt")
129
+ return "Payload";
130
+ if (s.kind === "extractor")
131
+ return "Returns";
132
+ if (s.kind === "relation")
133
+ return "Navigations";
134
+ if (s.kind === "callable")
135
+ return "Returns";
136
+ if (s.kind === "rest" || s.kind === "rest-hono") {
137
+ return s.name.startsWith("GET ") ? "Response body" : "Request body";
138
+ }
139
+ // data-access: a create/update takes a body; reads return the model.
140
+ return s.name.startsWith("create") || s.name.startsWith("update") ? "Request body (data)" : "Returns";
141
+ }
142
+ /** Markdown-escape a cell whose text may contain a `|` (TS union types do). */
143
+ function mdCell(text) {
144
+ return text.replace(/\|/g, "\\|");
145
+ }
146
+ /** Build the Field / Type / Required / Notes rows from a field shape. */
147
+ function fieldRows(fields) {
148
+ return fields.map((f) => ({
149
+ field: f.name,
150
+ type: mdCell(f.type),
151
+ required: f.optional ? "" : "yes",
152
+ notes: f.note ?? "",
153
+ }));
154
+ }
155
+ /** The exact `import { … } from "<importPath>"` an adopter writes for a symbol.
156
+ * REST endpoints aren't importable functions — the import is the entity's route
157
+ * registrar (`<entity>Routes`) from the routes module; the symbol's `name` is a
158
+ * "METHOD /path", not an identifier, so we import the registrar instead. Import
159
+ * paths are RELATIVE to the adopter's generated-output dir (a note at the top of
160
+ * the page states this once). */
161
+ function importLineFor(s) {
162
+ // REST + Hono endpoints aren't importable functions — import the route
163
+ // registrar named on the symbol instead of the "METHOD /path" name.
164
+ const isRouteKind = s.kind === "rest" || s.kind === "rest-hono";
165
+ const imported = isRouteKind ? s.registrar ?? s.name : s.name;
166
+ return `import { ${imported} } from "${relSpecifier(s.importPath)}"`;
167
+ }
168
+ /** Group a unit's symbols into ordered sections (one per present kind), each a
169
+ * list of {signature, usage, import, throws, example}. Empty kinds are omitted. */
170
+ function entityPageVM(unit) {
171
+ const sections = [];
172
+ for (const kind of KIND_ORDER) {
173
+ const ofKind = unit.symbols.filter((s) => s.kind === kind);
174
+ if (ofKind.length === 0)
175
+ continue;
176
+ sections.push({
177
+ heading: KIND_HEADING[kind],
178
+ symbols: ofKind.map(symbolVM),
179
+ });
180
+ }
181
+ const setup = setupHandlesFor(unit);
182
+ const vm = {
183
+ generatedMarker: GENERATED_MARKER,
184
+ node: unit.node,
185
+ hasSetup: setup.length > 0,
186
+ setup,
187
+ sections,
188
+ };
189
+ const ex = unitExampleBlock(unit.example);
190
+ if (ex !== undefined)
191
+ vm.unitExample = ex;
192
+ return vm;
193
+ }
194
+ /** The full worked-example block for a unit (imports + body), as one ```ts body
195
+ * string. Undefined when the unit has no runnable example. */
196
+ function unitExampleBlock(example) {
197
+ if (example === undefined)
198
+ return undefined;
199
+ // The example imports are pre-composed in the ApiModel from the symbols' bare
200
+ // importPaths; `./`-prefix each at render time so the copy-paste block resolves.
201
+ const lines = example.imports.map(relImportLine);
202
+ if (example.imports.length > 0 && example.body.length > 0)
203
+ lines.push("");
204
+ lines.push(...example.body);
205
+ return lines.join("\n");
206
+ }
207
+ function symbolVM(s) {
208
+ const vm = { signature: s.signature, usage: s.usage, importLine: importLineFor(s) };
209
+ // REST: tell the agent how to actually wire the endpoints once imported.
210
+ if (s.kind === "rest" && s.registrar !== undefined) {
211
+ vm.mountNote = `\`await ${s.registrar}(fastify)\``;
212
+ }
213
+ // Hono: the registrar mounts onto the Hono app with a per-request deps object.
214
+ if (s.kind === "rest-hono" && s.registrar !== undefined) {
215
+ vm.mountNote = `\`${s.registrar}(app, { db })\``;
216
+ }
217
+ if (s.throws !== undefined)
218
+ vm.throws = s.throws;
219
+ if (s.example !== undefined)
220
+ vm.example = s.example;
221
+ // Field shape → a Field / Type / Required / Notes table (only when there is at
222
+ // least one field; a shape with no fields is omitted to keep the page clean).
223
+ if (s.fields !== undefined && s.fields.length > 0) {
224
+ vm.hasFields = true;
225
+ vm.fieldsCaption = fieldsCaptionFor(s);
226
+ vm.fieldRows = fieldRows(s.fields);
227
+ }
228
+ return vm;
229
+ }
230
+ /** Render ONE per-unit human reference page from an ApiUnitDoc, via the shared
231
+ * render() engine + the canonical `api/entity-api.md` template. `modelPageHref`
232
+ * (when given) cross-links the page back to the entity's model/metadata page. */
233
+ export function renderEntityApiPage(unit, provider, modelPageHref) {
234
+ const payload = entityPageVM(unit);
235
+ if (modelPageHref !== undefined)
236
+ payload.modelPageHref = modelPageHref;
237
+ return render({
238
+ ref: ENTITY_PAGE_REF,
239
+ payload,
240
+ provider,
241
+ format: "markdown",
242
+ });
243
+ }
244
+ /** Lowercase summary label per kind (keeps the proper-noun acronym "REST"
245
+ * intact rather than ".toLowerCase()"-ing it to "rest"). */
246
+ const KIND_SUMMARY_LABEL = {
247
+ model: "model",
248
+ relation: "relations",
249
+ "data-access": "data access",
250
+ callable: "callable",
251
+ rest: "REST",
252
+ "rest-hono": "REST (Hono)",
253
+ validation: "validation",
254
+ extractor: "extractor",
255
+ render: "render",
256
+ prompt: "prompt",
257
+ };
258
+ /** A one-line summary for a unit's index row: the count of each present kind,
259
+ * in canonical order (e.g. "model, 5 data access, 5 REST, 2 validation"). */
260
+ function unitSummary(unit) {
261
+ const parts = [];
262
+ for (const kind of KIND_ORDER) {
263
+ const n = unit.symbols.filter((s) => s.kind === kind).length;
264
+ if (n === 0)
265
+ continue;
266
+ const label = KIND_SUMMARY_LABEL[kind];
267
+ parts.push(n === 1 ? label : `${n} ${label}`);
268
+ }
269
+ return parts.length > 0 ? parts.join(", ") : "no public symbols";
270
+ }
271
+ function indexRow(layout, unit) {
272
+ // The per-unit page is placed by {name, effective package} (see Task-3
273
+ // emission); link to it via the same docPageHref used for doc pages so it
274
+ // resolves in BOTH layouts — flat (`./Product.md`) and package
275
+ // (`./acme/shop/Product.md`), folding under the package path.
276
+ const href = docPageHref(layout, INDEX_NODE, { name: unit.node, package: unit.package });
277
+ return {
278
+ node: unit.node,
279
+ href,
280
+ summary: unitSummary(unit),
281
+ symbolCount: unit.symbols.length,
282
+ one: unit.symbols.length === 1,
283
+ };
284
+ }
285
+ /** Render the consolidated human API index (links to each unit page, grouped
286
+ * entity vs template) via the shared render() engine + `api/index.md`. */
287
+ export function renderApiIndex(model, layout, provider) {
288
+ const byName = (a, b) => a.node.localeCompare(b.node);
289
+ const entities = model.units.filter((u) => u.nodeKind === "entity").sort(byName);
290
+ const templates = model.units.filter((u) => u.nodeKind === "template").sort(byName);
291
+ const payload = {
292
+ generatedMarker: GENERATED_MARKER,
293
+ title: "API Reference",
294
+ intro: "Generated public API surface, one page per entity and output template.",
295
+ hasEntities: entities.length > 0,
296
+ entities: entities.map((u) => indexRow(layout, u)),
297
+ hasTemplates: templates.length > 0,
298
+ templates: templates.map((u) => indexRow(layout, u)),
299
+ };
300
+ return render({ ref: INDEX_REF, payload, provider, format: "markdown" });
301
+ }
302
+ /**
303
+ * The agent-form signature WITH the field shape inlined — so an LLM sees exactly
304
+ * what to pass / what it gets, not an opaque `unknown` / `ZodType` / type NAME.
305
+ * Token-frugal but complete. Shaping is per kind:
306
+ * • model → `interface <Name> <inlineShape>`;
307
+ * • data-access → swap the `data: unknown` param for `data: <inlineShape>`
308
+ * (create/update only; reads have no body shape);
309
+ * • validation → `<Name>InsertSchema: ZodType<<inlineShape>>`;
310
+ * • REST → append ` body: <inlineShape>` (write) / ` -> <inlineShape>`
311
+ * (GET response);
312
+ * • extractor → append ` // <Payload>: <inlineShape>`.
313
+ * Falls back to the bare signature when the symbol carries no field shape.
314
+ */
315
+ function agentSignature(s) {
316
+ if (s.fields === undefined || s.fields.length === 0)
317
+ return s.signature;
318
+ const shape = inlineShape(s.fields);
319
+ switch (s.kind) {
320
+ case "model":
321
+ return `interface ${s.name} ${shape}`;
322
+ case "data-access":
323
+ // create/update carry a `data: unknown` body param to specialize.
324
+ return s.signature.includes("data: unknown")
325
+ ? s.signature.replace("data: unknown", `data: ${shape}`)
326
+ : s.signature;
327
+ case "validation":
328
+ return s.signature.replace("ZodType", `ZodType<${shape}>`);
329
+ case "rest":
330
+ case "rest-hono":
331
+ return s.name.startsWith("GET ") ? `${s.signature} -> ${shape}` : `${s.signature} body: ${shape}`;
332
+ case "extractor":
333
+ case "prompt":
334
+ return `${s.signature} // ${s.returns ?? "payload"}: ${shape}`;
335
+ case "relation":
336
+ // The navigations ride in the shape; show them inline after the const decl.
337
+ return `const ${s.name} ${shape}`;
338
+ case "callable":
339
+ // Callable returns a typed row array; the model shape isn't its param, so
340
+ // keep the bare signature (its `args` shape is the @parameterRef VO, shown
341
+ // on that VO's own unit).
342
+ return s.signature;
343
+ default:
344
+ return s.signature;
345
+ }
346
+ }
347
+ /** Group a unit's symbols by their import MODULE (first-appearance order),
348
+ * emitting ONE `import { … } from "<module>"` header per module then the
349
+ * symbols under it. This is the token-frugal form that still tells the agent the
350
+ * exact import for EVERY symbol (one header amortized over N symbols, vs. an
351
+ * import line per symbol). REST endpoints aren't importable identifiers — they
352
+ * collapse under their entity's single route-registrar import (the registrar is
353
+ * the imported name; the endpoints list the verbs/paths it mounts). */
354
+ function agentGroups(unit) {
355
+ const order = [];
356
+ const byModule = new Map();
357
+ for (const s of unit.symbols) {
358
+ let g = byModule.get(s.importPath);
359
+ if (!g) {
360
+ g = { names: [], symbols: [] };
361
+ byModule.set(s.importPath, g);
362
+ order.push(s.importPath);
363
+ }
364
+ // The identifier an adopter imports: the symbol name, or — for REST / Hono —
365
+ // the shared route registrar (deduped across the entity's endpoints).
366
+ const isRouteKind = s.kind === "rest" || s.kind === "rest-hono";
367
+ const imported = isRouteKind ? s.registrar ?? s.name : s.name;
368
+ if (!g.names.includes(imported))
369
+ g.names.push(imported);
370
+ const sym = { signature: agentSignature(s), usage: s.usage };
371
+ if (s.throws !== undefined)
372
+ sym.throwsMarker = `[throws: ${s.throws}]`;
373
+ g.symbols.push(sym);
374
+ }
375
+ return order.map((mod) => {
376
+ const g = byModule.get(mod);
377
+ return {
378
+ importHeader: `import { ${g.names.join(", ")} } from "${relSpecifier(mod)}"`,
379
+ symbols: g.symbols,
380
+ };
381
+ });
382
+ }
383
+ /** Render the condensed agent/LLM form: per unit, symbols grouped under a single
384
+ * `import { … } from "<module>"` header then one compact `signature — usage`
385
+ * line each (with a `[throws: …]` marker when it throws), NO prose/examples
386
+ * (token budget). Units keep their ApiModel order; symbols keep their per-unit
387
+ * order (the canonical generator emission order). */
388
+ export function renderAgentApi(model, provider) {
389
+ const units = model.units
390
+ .filter((u) => u.symbols.length > 0)
391
+ .map((u) => {
392
+ const vm = { node: u.node, groups: agentGroups(u) };
393
+ // The compact agent example: body statements only (the imports are already
394
+ // amortized into the group headers above the example).
395
+ if (u.example !== undefined && u.example.body.length > 0) {
396
+ vm.example = u.example.body.join("\n");
397
+ }
398
+ return vm;
399
+ });
400
+ // The handles ANY unit's example references — shown once at the top so an agent
401
+ // knows where db / provider / root come from before the call sites below.
402
+ const setup = setupHandlesForModel(model);
403
+ const payload = {
404
+ generatedMarker: GENERATED_MARKER,
405
+ title: "Agent API Reference",
406
+ // The ApiModel carries no package itself, so the model-only entry point uses
407
+ // a generic, self-contained project label. (A richer label off the loaded
408
+ // root's package can be layered in by the Task-3 emission entrypoint, which
409
+ // has the root.)
410
+ project: "this project",
411
+ // Import paths are RELATIVE to the adopter's generated-output dir.
412
+ importNote: "Imports are relative to your generated-output directory.",
413
+ hasSetup: setup.length > 0,
414
+ setup,
415
+ units,
416
+ };
417
+ return render({ ref: AGENT_REF, payload, provider, format: "markdown" });
418
+ }
419
+ /** The union of setup handles referenced by ANY unit's example, in canonical
420
+ * db→provider→root order (shown once at the top of the agent form). */
421
+ function setupHandlesForModel(model) {
422
+ const used = new Set();
423
+ for (const u of model.units) {
424
+ for (const h of setupHandlesFor(u))
425
+ used.add(h.handle);
426
+ }
427
+ return ["db", "provider", "root"]
428
+ .filter((h) => used.has(h))
429
+ .map((h) => SETUP_HANDLES[h]);
430
+ }
431
+ //# sourceMappingURL=api-doc-render.js.map