@voxgig/sdkgen 1.2.0 → 1.3.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 (329) hide show
  1. package/bin/voxgig-sdkgen +2 -2
  2. package/dist/action/action.d.ts +2 -1
  3. package/dist/action/action.js +15 -9
  4. package/dist/action/action.js.map +1 -1
  5. package/dist/action/feature.js +6 -3
  6. package/dist/action/feature.js.map +1 -1
  7. package/dist/action/target.d.ts +7 -1
  8. package/dist/action/target.js +13 -6
  9. package/dist/action/target.js.map +1 -1
  10. package/dist/cmp/Changelog.d.ts +2 -0
  11. package/dist/cmp/Changelog.js +30 -0
  12. package/dist/cmp/Changelog.js.map +1 -0
  13. package/dist/cmp/Deploy.d.ts +2 -0
  14. package/dist/cmp/Deploy.js +227 -0
  15. package/dist/cmp/Deploy.js.map +1 -0
  16. package/dist/cmp/FeatureHook.js +5 -6
  17. package/dist/cmp/FeatureHook.js.map +1 -1
  18. package/dist/cmp/License.d.ts +2 -0
  19. package/dist/cmp/License.js +44 -0
  20. package/dist/cmp/License.js.map +1 -0
  21. package/dist/cmp/Readme.js +2 -0
  22. package/dist/cmp/Readme.js.map +1 -1
  23. package/dist/cmp/ReadmeErrors.d.ts +2 -0
  24. package/dist/cmp/ReadmeErrors.js +210 -0
  25. package/dist/cmp/ReadmeErrors.js.map +1 -0
  26. package/dist/cmp/ReadmeExplanation.js +213 -223
  27. package/dist/cmp/ReadmeExplanation.js.map +1 -1
  28. package/dist/cmp/ReadmeModel.js +6 -1
  29. package/dist/cmp/ReadmeModel.js.map +1 -1
  30. package/dist/cmp/ReadmeTop.js +389 -82
  31. package/dist/cmp/ReadmeTop.js.map +1 -1
  32. package/dist/cmp/Security.d.ts +2 -0
  33. package/dist/cmp/Security.js +36 -0
  34. package/dist/cmp/Security.js.map +1 -0
  35. package/dist/helpers/canonType.d.ts +7 -0
  36. package/dist/helpers/canonType.js +74 -0
  37. package/dist/helpers/canonType.js.map +1 -0
  38. package/dist/helpers/collectDeps.d.ts +3 -2
  39. package/dist/helpers/collectDeps.js.map +1 -1
  40. package/dist/helpers/naming.d.ts +3 -0
  41. package/dist/helpers/naming.js +51 -0
  42. package/dist/helpers/naming.js.map +1 -0
  43. package/dist/helpers/opExample.d.ts +13 -0
  44. package/dist/helpers/opExample.js +149 -0
  45. package/dist/helpers/opExample.js.map +1 -0
  46. package/dist/helpers/opShape.d.ts +18 -0
  47. package/dist/helpers/opShape.js +193 -0
  48. package/dist/helpers/opShape.js.map +1 -0
  49. package/dist/helpers/packageMeta.d.ts +27 -0
  50. package/dist/helpers/packageMeta.js +224 -0
  51. package/dist/helpers/packageMeta.js.map +1 -0
  52. package/dist/sdkgen.d.ts +11 -1
  53. package/dist/sdkgen.js +57 -18
  54. package/dist/sdkgen.js.map +1 -1
  55. package/dist/tsconfig.tsbuildinfo +1 -1
  56. package/dist/types.d.ts +65 -2
  57. package/dist/types.js.map +1 -1
  58. package/dist/utility.js +20 -11
  59. package/dist/utility.js.map +1 -1
  60. package/model/sdkgen.aontu +137 -0
  61. package/package.json +13 -6
  62. package/project/.sdk/model/target/go-cli.jsonic +47 -0
  63. package/project/.sdk/model/target/go-mcp.jsonic +41 -0
  64. package/project/.sdk/model/target/go.jsonic +9 -3
  65. package/project/.sdk/model/target/js.jsonic +13 -0
  66. package/project/.sdk/model/target/lua.jsonic +13 -0
  67. package/project/.sdk/model/target/php.jsonic +13 -0
  68. package/project/.sdk/model/target/py.jsonic +13 -0
  69. package/project/.sdk/model/target/rb.jsonic +13 -0
  70. package/project/.sdk/model/target/ts.jsonic +13 -0
  71. package/project/.sdk/src/cmp/go/EntityOperation_go.ts +1 -0
  72. package/project/.sdk/src/cmp/go/EntityTypes_go.ts +197 -0
  73. package/project/.sdk/src/cmp/go/Entity_go.ts +2 -1
  74. package/project/.sdk/src/cmp/go/MainEntity_go.ts +6 -0
  75. package/project/.sdk/src/cmp/go/Main_go.ts +23 -3
  76. package/project/.sdk/src/cmp/go/Package_go.ts +1 -1
  77. package/project/.sdk/src/cmp/go/ReadmeEntity_go.ts +18 -6
  78. package/project/.sdk/src/cmp/go/ReadmeExamplesTest_go.ts +684 -0
  79. package/project/.sdk/src/cmp/go/ReadmeExplanation_go.ts +1 -1
  80. package/project/.sdk/src/cmp/go/ReadmeHowto_go.ts +48 -8
  81. package/project/.sdk/src/cmp/go/ReadmeInstall_go.ts +11 -6
  82. package/project/.sdk/src/cmp/go/ReadmeIntro_go.ts +40 -1
  83. package/project/.sdk/src/cmp/go/ReadmeModel_go.ts +63 -17
  84. package/project/.sdk/src/cmp/go/ReadmeOptions_go.ts +4 -3
  85. package/project/.sdk/src/cmp/go/ReadmeQuick_go.ts +124 -115
  86. package/project/.sdk/src/cmp/go/ReadmeRef_go.ts +28 -15
  87. package/project/.sdk/src/cmp/go/ReadmeTopQuick_go.ts +33 -9
  88. package/project/.sdk/src/cmp/go/ReadmeTopTest_go.ts +35 -5
  89. package/project/.sdk/src/cmp/go/TestEntity_go.ts +1 -1
  90. package/project/.sdk/src/cmp/go/Test_go.ts +5 -1
  91. package/project/.sdk/src/cmp/go/fragment/Entity.fragment.go +21 -0
  92. package/project/.sdk/src/cmp/go/fragment/EntityCreateOp.fragment.go +11 -0
  93. package/project/.sdk/src/cmp/go/fragment/EntityListOp.fragment.go +11 -0
  94. package/project/.sdk/src/cmp/go/fragment/EntityLoadOp.fragment.go +11 -0
  95. package/project/.sdk/src/cmp/go/fragment/EntityRemoveOp.fragment.go +11 -0
  96. package/project/.sdk/src/cmp/go/fragment/EntityUpdateOp.fragment.go +11 -0
  97. package/project/.sdk/src/cmp/go-cli/Main_go-cli.ts +195 -0
  98. package/project/.sdk/src/cmp/go-cli/fragment/main.fragment.go +106 -0
  99. package/project/.sdk/src/cmp/go-cli/fragment/words.fragment.go +132 -0
  100. package/project/.sdk/src/cmp/go-mcp/Main_go-mcp.ts +184 -0
  101. package/project/.sdk/src/cmp/go-mcp/fragment/main.fragment.go +68 -0
  102. package/project/.sdk/src/cmp/go-mcp/fragment/tools.fragment.go +114 -0
  103. package/project/.sdk/src/cmp/js/EntityTypes_js.ts +111 -0
  104. package/project/.sdk/src/cmp/js/MainEntity_js.ts +1 -0
  105. package/project/.sdk/src/cmp/js/Main_js.ts +3 -0
  106. package/project/.sdk/src/cmp/js/Package_js.ts +16 -7
  107. package/project/.sdk/src/cmp/js/ReadmeEntity_js.ts +13 -7
  108. package/project/.sdk/src/cmp/js/ReadmeExplanation_js.ts +2 -2
  109. package/project/.sdk/src/cmp/js/ReadmeHowto_js.ts +52 -11
  110. package/project/.sdk/src/cmp/js/ReadmeIntro_js.ts +39 -1
  111. package/project/.sdk/src/cmp/js/ReadmeModel_js.ts +50 -18
  112. package/project/.sdk/src/cmp/js/ReadmeOptions_js.ts +4 -3
  113. package/project/.sdk/src/cmp/js/ReadmeQuick_js.ts +45 -19
  114. package/project/.sdk/src/cmp/js/ReadmeRef_js.ts +24 -13
  115. package/project/.sdk/src/cmp/js/ReadmeTopHowto_js.ts +3 -0
  116. package/project/.sdk/src/cmp/js/ReadmeTopQuick_js.ts +28 -12
  117. package/project/.sdk/src/cmp/js/ReadmeTopTest_js.ts +23 -3
  118. package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +5 -0
  119. package/project/.sdk/src/cmp/js/fragment/EntityListOp.fragment.js +5 -0
  120. package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +5 -0
  121. package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +5 -0
  122. package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +5 -0
  123. package/project/.sdk/src/cmp/js/utility_js.ts +57 -0
  124. package/project/.sdk/src/cmp/lua/EntityTypes_lua.ts +113 -0
  125. package/project/.sdk/src/cmp/lua/MainEntity_lua.ts +8 -0
  126. package/project/.sdk/src/cmp/lua/Main_lua.ts +4 -0
  127. package/project/.sdk/src/cmp/lua/Package_lua.ts +23 -4
  128. package/project/.sdk/src/cmp/lua/ReadmeEntity_lua.ts +12 -10
  129. package/project/.sdk/src/cmp/lua/ReadmeExamplesTest_lua.ts +293 -0
  130. package/project/.sdk/src/cmp/lua/ReadmeHowto_lua.ts +46 -8
  131. package/project/.sdk/src/cmp/lua/ReadmeInstall_lua.ts +19 -3
  132. package/project/.sdk/src/cmp/lua/ReadmeIntro_lua.ts +38 -1
  133. package/project/.sdk/src/cmp/lua/ReadmeModel_lua.ts +51 -16
  134. package/project/.sdk/src/cmp/lua/ReadmeOptions_lua.ts +4 -3
  135. package/project/.sdk/src/cmp/lua/ReadmeQuick_lua.ts +79 -18
  136. package/project/.sdk/src/cmp/lua/ReadmeRef_lua.ts +25 -20
  137. package/project/.sdk/src/cmp/lua/ReadmeTopQuick_lua.ts +17 -9
  138. package/project/.sdk/src/cmp/lua/ReadmeTopTest_lua.ts +32 -5
  139. package/project/.sdk/src/cmp/lua/Test_lua.ts +4 -0
  140. package/project/.sdk/src/cmp/lua/fragment/EntityCreateOp.fragment.lua +4 -0
  141. package/project/.sdk/src/cmp/lua/fragment/EntityListOp.fragment.lua +4 -0
  142. package/project/.sdk/src/cmp/lua/fragment/EntityLoadOp.fragment.lua +4 -0
  143. package/project/.sdk/src/cmp/lua/fragment/EntityRemoveOp.fragment.lua +4 -0
  144. package/project/.sdk/src/cmp/lua/fragment/EntityUpdateOp.fragment.lua +4 -0
  145. package/project/.sdk/src/cmp/php/EntityTypes_php.ts +142 -0
  146. package/project/.sdk/src/cmp/php/MainEntity_php.ts +18 -1
  147. package/project/.sdk/src/cmp/php/Main_php.ts +4 -0
  148. package/project/.sdk/src/cmp/php/Package_php.ts +18 -7
  149. package/project/.sdk/src/cmp/php/ReadmeEntity_php.ts +15 -11
  150. package/project/.sdk/src/cmp/php/ReadmeExamplesTest_php.ts +401 -0
  151. package/project/.sdk/src/cmp/php/ReadmeHowto_php.ts +56 -13
  152. package/project/.sdk/src/cmp/php/ReadmeInstall_php.ts +15 -3
  153. package/project/.sdk/src/cmp/php/ReadmeIntro_php.ts +40 -1
  154. package/project/.sdk/src/cmp/php/ReadmeModel_php.ts +26 -8
  155. package/project/.sdk/src/cmp/php/ReadmeOptions_php.ts +4 -3
  156. package/project/.sdk/src/cmp/php/ReadmeQuick_php.ts +80 -22
  157. package/project/.sdk/src/cmp/php/ReadmeRef_php.ts +51 -42
  158. package/project/.sdk/src/cmp/php/ReadmeTopHowto_php.ts +1 -1
  159. package/project/.sdk/src/cmp/php/ReadmeTopQuick_php.ts +19 -11
  160. package/project/.sdk/src/cmp/php/ReadmeTopTest_php.ts +41 -11
  161. package/project/.sdk/src/cmp/php/TestDirect_php.ts +9 -9
  162. package/project/.sdk/src/cmp/php/TestEntity_php.ts +6 -12
  163. package/project/.sdk/src/cmp/php/Test_php.ts +4 -0
  164. package/project/.sdk/src/cmp/php/fragment/Entity.fragment.php +13 -1
  165. package/project/.sdk/src/cmp/php/fragment/EntityCreateOp.fragment.php +10 -1
  166. package/project/.sdk/src/cmp/php/fragment/EntityListOp.fragment.php +10 -1
  167. package/project/.sdk/src/cmp/php/fragment/EntityLoadOp.fragment.php +10 -1
  168. package/project/.sdk/src/cmp/php/fragment/EntityRemoveOp.fragment.php +10 -1
  169. package/project/.sdk/src/cmp/php/fragment/EntityUpdateOp.fragment.php +10 -1
  170. package/project/.sdk/src/cmp/php/fragment/Main.fragment.php +22 -14
  171. package/project/.sdk/src/cmp/py/EntityTypes_py.ts +184 -0
  172. package/project/.sdk/src/cmp/py/Entity_py.ts +27 -0
  173. package/project/.sdk/src/cmp/py/MainEntity_py.ts +2 -1
  174. package/project/.sdk/src/cmp/py/Main_py.ts +35 -0
  175. package/project/.sdk/src/cmp/py/Package_py.ts +24 -3
  176. package/project/.sdk/src/cmp/py/ReadmeEntity_py.ts +27 -11
  177. package/project/.sdk/src/cmp/py/ReadmeExamplesTest_py.ts +626 -0
  178. package/project/.sdk/src/cmp/py/ReadmeHowto_py.ts +53 -14
  179. package/project/.sdk/src/cmp/py/ReadmeInstall_py.ts +19 -3
  180. package/project/.sdk/src/cmp/py/ReadmeIntro_py.ts +48 -1
  181. package/project/.sdk/src/cmp/py/ReadmeModel_py.ts +28 -10
  182. package/project/.sdk/src/cmp/py/ReadmeOptions_py.ts +4 -3
  183. package/project/.sdk/src/cmp/py/ReadmeQuick_py.ts +73 -24
  184. package/project/.sdk/src/cmp/py/ReadmeRef_py.ts +57 -37
  185. package/project/.sdk/src/cmp/py/ReadmeTopHowto_py.ts +1 -1
  186. package/project/.sdk/src/cmp/py/ReadmeTopQuick_py.ts +19 -11
  187. package/project/.sdk/src/cmp/py/ReadmeTopTest_py.ts +30 -5
  188. package/project/.sdk/src/cmp/py/TestDirect_py.ts +7 -9
  189. package/project/.sdk/src/cmp/py/TestEntity_py.ts +6 -14
  190. package/project/.sdk/src/cmp/py/Test_py.ts +4 -0
  191. package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +5 -2
  192. package/project/.sdk/src/cmp/py/fragment/EntityCreateOp.fragment.py +1 -1
  193. package/project/.sdk/src/cmp/py/fragment/EntityListOp.fragment.py +5 -1
  194. package/project/.sdk/src/cmp/py/fragment/EntityLoadOp.fragment.py +6 -1
  195. package/project/.sdk/src/cmp/py/fragment/EntityRemoveOp.fragment.py +6 -1
  196. package/project/.sdk/src/cmp/py/fragment/EntityUpdateOp.fragment.py +1 -1
  197. package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +17 -10
  198. package/project/.sdk/src/cmp/rb/EntityTypes_rb.ts +136 -0
  199. package/project/.sdk/src/cmp/rb/MainEntity_rb.ts +1 -0
  200. package/project/.sdk/src/cmp/rb/Main_rb.ts +4 -0
  201. package/project/.sdk/src/cmp/rb/Package_rb.ts +34 -7
  202. package/project/.sdk/src/cmp/rb/ReadmeEntity_rb.ts +26 -10
  203. package/project/.sdk/src/cmp/rb/ReadmeExamplesTest_rb.ts +289 -0
  204. package/project/.sdk/src/cmp/rb/ReadmeHowto_rb.ts +72 -21
  205. package/project/.sdk/src/cmp/rb/ReadmeInstall_rb.ts +16 -4
  206. package/project/.sdk/src/cmp/rb/ReadmeIntro_rb.ts +40 -1
  207. package/project/.sdk/src/cmp/rb/ReadmeModel_rb.ts +29 -12
  208. package/project/.sdk/src/cmp/rb/ReadmeOptions_rb.ts +4 -3
  209. package/project/.sdk/src/cmp/rb/ReadmeQuick_rb.ts +85 -22
  210. package/project/.sdk/src/cmp/rb/ReadmeRef_rb.ts +56 -37
  211. package/project/.sdk/src/cmp/rb/ReadmeTopHowto_rb.ts +1 -1
  212. package/project/.sdk/src/cmp/rb/ReadmeTopQuick_rb.ts +19 -11
  213. package/project/.sdk/src/cmp/rb/ReadmeTopTest_rb.ts +43 -11
  214. package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +9 -9
  215. package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +6 -12
  216. package/project/.sdk/src/cmp/rb/Test_rb.ts +4 -0
  217. package/project/.sdk/src/cmp/rb/fragment/Entity.fragment.rb +2 -0
  218. package/project/.sdk/src/cmp/rb/fragment/EntityCreateOp.fragment.rb +5 -0
  219. package/project/.sdk/src/cmp/rb/fragment/EntityListOp.fragment.rb +20 -2
  220. package/project/.sdk/src/cmp/rb/fragment/EntityLoadOp.fragment.rb +8 -1
  221. package/project/.sdk/src/cmp/rb/fragment/EntityRemoveOp.fragment.rb +6 -1
  222. package/project/.sdk/src/cmp/rb/fragment/EntityUpdateOp.fragment.rb +5 -0
  223. package/project/.sdk/src/cmp/rb/fragment/Main.fragment.rb +24 -8
  224. package/project/.sdk/src/cmp/ts/EntityTypes_ts.ts +105 -0
  225. package/project/.sdk/src/cmp/ts/Entity_ts.ts +17 -1
  226. package/project/.sdk/src/cmp/ts/MainEntity_ts.ts +1 -0
  227. package/project/.sdk/src/cmp/ts/Main_ts.ts +6 -0
  228. package/project/.sdk/src/cmp/ts/Package_ts.ts +14 -7
  229. package/project/.sdk/src/cmp/ts/ReadmeEntity_ts.ts +13 -7
  230. package/project/.sdk/src/cmp/ts/ReadmeExampleTest_ts.ts +81 -0
  231. package/project/.sdk/src/cmp/ts/ReadmeExamplesTest_ts.ts +446 -0
  232. package/project/.sdk/src/cmp/ts/ReadmeExplanation_ts.ts +2 -2
  233. package/project/.sdk/src/cmp/ts/ReadmeHowto_ts.ts +57 -11
  234. package/project/.sdk/src/cmp/ts/ReadmeInstall_ts.ts +19 -6
  235. package/project/.sdk/src/cmp/ts/ReadmeIntro_ts.ts +39 -1
  236. package/project/.sdk/src/cmp/ts/ReadmeModel_ts.ts +50 -18
  237. package/project/.sdk/src/cmp/ts/ReadmeOptions_ts.ts +4 -3
  238. package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +95 -40
  239. package/project/.sdk/src/cmp/ts/ReadmeRef_ts.ts +24 -13
  240. package/project/.sdk/src/cmp/ts/ReadmeTopHowto_ts.ts +3 -0
  241. package/project/.sdk/src/cmp/ts/ReadmeTopQuick_ts.ts +44 -12
  242. package/project/.sdk/src/cmp/ts/ReadmeTopTest_ts.ts +23 -3
  243. package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +2 -2
  244. package/project/.sdk/src/cmp/ts/Test_ts.ts +5 -0
  245. package/project/.sdk/src/cmp/ts/fragment/Entity.fragment.ts +3 -1
  246. package/project/.sdk/src/cmp/ts/fragment/EntityBase.fragment.ts +10 -5
  247. package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.ts +4 -2
  248. package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.ts +4 -2
  249. package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.ts +4 -2
  250. package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.ts +4 -2
  251. package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.ts +4 -2
  252. package/project/.sdk/src/cmp/ts/utility_ts.ts +59 -0
  253. package/project/.sdk/tm/go/LICENSE +1 -1
  254. package/project/.sdk/tm/go/Makefile +36 -1
  255. package/project/.sdk/tm/go/VERSION +1 -0
  256. package/project/.sdk/tm/go/core/context.go +12 -7
  257. package/project/.sdk/tm/go-cli/src/feature/README.md +6 -0
  258. package/project/.sdk/tm/go-cli/src/feature/base/.gitkeep +0 -0
  259. package/project/.sdk/tm/go-cli/src/feature/log/.gitkeep +0 -0
  260. package/project/.sdk/tm/go-cli/src/feature/test/.gitkeep +0 -0
  261. package/project/.sdk/tm/go-mcp/src/feature/README.md +6 -0
  262. package/project/.sdk/tm/go-mcp/src/feature/base/.gitkeep +0 -0
  263. package/project/.sdk/tm/go-mcp/src/feature/log/.gitkeep +0 -0
  264. package/project/.sdk/tm/go-mcp/src/feature/test/.gitkeep +0 -0
  265. package/project/.sdk/tm/js/LICENSE +1 -1
  266. package/project/.sdk/tm/js/Makefile +41 -0
  267. package/project/.sdk/tm/lua/LICENSE +1 -1
  268. package/project/.sdk/tm/lua/Makefile +40 -1
  269. package/project/.sdk/tm/lua/core/context.lua +13 -8
  270. package/project/.sdk/tm/php/LICENSE +1 -1
  271. package/project/.sdk/tm/php/Makefile +31 -1
  272. package/project/.sdk/tm/php/VERSION +1 -0
  273. package/project/.sdk/tm/php/core/Context.php +12 -6
  274. package/project/.sdk/tm/php/test/PrimaryUtilityTest.php +13 -4
  275. package/project/.sdk/tm/php/utility/Done.php +2 -2
  276. package/project/.sdk/tm/php/utility/MakeError.php +3 -3
  277. package/project/.sdk/tm/py/LICENSE +1 -1
  278. package/project/.sdk/tm/py/Makefile +34 -1
  279. package/project/.sdk/tm/py/core/context.py +12 -7
  280. package/project/.sdk/tm/py/test/test_primary_utility.py +15 -4
  281. package/project/.sdk/tm/py/utility/done.py +3 -1
  282. package/project/.sdk/tm/py/utility/make_error.py +2 -2
  283. package/project/.sdk/tm/rb/LICENSE +1 -1
  284. package/project/.sdk/tm/rb/Makefile +33 -1
  285. package/project/.sdk/tm/rb/core/context.rb +8 -3
  286. package/project/.sdk/tm/rb/test/primary_utility_test.rb +2 -2
  287. package/project/.sdk/tm/rb/utility/done.rb +3 -1
  288. package/project/.sdk/tm/rb/utility/make_error.rb +5 -2
  289. package/project/.sdk/tm/ts/LICENSE +1 -1
  290. package/project/.sdk/tm/ts/Makefile +42 -0
  291. package/project/.sdk/tm/ts/src/Context.ts +8 -3
  292. package/src/action/action.ts +17 -10
  293. package/src/action/feature.ts +8 -6
  294. package/src/action/target.ts +17 -8
  295. package/src/cmp/Changelog.ts +34 -0
  296. package/src/cmp/Deploy.ts +258 -0
  297. package/src/cmp/FeatureHook.ts +6 -8
  298. package/src/cmp/License.ts +49 -0
  299. package/src/cmp/Readme.ts +2 -0
  300. package/src/cmp/ReadmeErrors.ts +257 -0
  301. package/src/cmp/ReadmeExplanation.ts +250 -230
  302. package/src/cmp/ReadmeModel.ts +7 -2
  303. package/src/cmp/ReadmeTop.ts +411 -95
  304. package/src/cmp/Security.ts +41 -0
  305. package/src/helpers/canonType.ts +89 -0
  306. package/src/helpers/collectDeps.ts +5 -3
  307. package/src/helpers/naming.ts +59 -0
  308. package/src/helpers/opExample.ts +170 -0
  309. package/src/helpers/opShape.ts +236 -0
  310. package/src/helpers/packageMeta.ts +236 -0
  311. package/src/sdkgen.ts +87 -20
  312. package/src/tsconfig.json +1 -0
  313. package/src/types.ts +85 -2
  314. package/src/utility.ts +22 -11
  315. package/README.md +0 -2
  316. package/dist/action/lang.d.ts +0 -2
  317. package/dist/action/lang.js +0 -68
  318. package/dist/action/lang.js.map +0 -1
  319. package/dist/cmp/Hook.d.ts +0 -2
  320. package/dist/cmp/Hook.js +0 -10
  321. package/dist/cmp/Hook.js.map +0 -1
  322. package/dist/cmp/Top.d.ts +0 -2
  323. package/dist/cmp/Top.js +0 -23
  324. package/dist/cmp/Top.js.map +0 -1
  325. package/dist/prepare-openapi.d.ts +0 -2
  326. package/dist/prepare-openapi.js +0 -37
  327. package/dist/prepare-openapi.js.map +0 -1
  328. package/model/sdkgen.jsonic +0 -74
  329. package/project/.sdk/tm/go/utility/struct/go.mod +0 -3
@@ -0,0 +1,89 @@
1
+ // Canonical type-sentinel -> language primitive type mapper.
2
+ //
3
+ // SOURCE OF TRUTH for the sentinel set: @voxgig/apidef
4
+ // ~/Projects/voxgig/apidef ts/src/utility.ts -> `const VALID_CANON`
5
+ // (around line 908). VALID_CANON maps an OpenAPI type NAME -> a `$SENTINEL`
6
+ // string (e.g. 'string' -> `$STRING`). The model stores those sentinels on
7
+ // every `fields[].type` and op `points[].args.params[].type`.
8
+ //
9
+ // This table maps the SENTINEL the other way -> a concrete primitive type in
10
+ // each target language, so the typed-model generators (EntityTypes_<lang>.ts)
11
+ // can turn the model's field/param sentinels into real language types.
12
+ //
13
+ // Kept as a small duplicate here (rather than importing VALID_CANON) because
14
+ // VALID_CANON is name->sentinel, is not exported from @voxgig/apidef, and would
15
+ // need inverting; a sentinel->type table is what every language generator
16
+ // actually needs. If VALID_CANON gains a new sentinel, add a row below (all
17
+ // languages) and keep the two in sync.
18
+ //
19
+ // KNOWN GAPS (papered over sanely, documented for the port):
20
+ // - Unknown / missing sentinel -> the language's "any" (never throws).
21
+ // - Array element typing is not in the model: $ARRAY maps to an untyped
22
+ // list/array. `list` ops return T[] via op-kind inference in the op
23
+ // fragment, NOT via a field sentinel.
24
+ // - Object/nested field schemas are not in the corpus: $OBJECT maps to the
25
+ // language's open record/map type.
26
+ // - No enum/format/nullability beyond the `req` flag.
27
+
28
+ // Target languages sdkgen supports (go-cli / go-mcp reuse 'go').
29
+ type CanonLang = 'ts' | 'js' | 'py' | 'php' | 'rb' | 'lua' | 'go'
30
+
31
+ // Bare sentinel key (backticks + leading `$` stripped, upper-cased)
32
+ // -> per-language primitive type name.
33
+ //
34
+ // ONLY the `ts` column is exercised + tested today (the reference target).
35
+ // The other columns are a starting scaffold for the per-language port; verify
36
+ // each against that language's idioms before wiring its EntityTypes_<lang>.ts.
37
+ const CANON_TYPE: Record<string, Record<CanonLang, string>> = {
38
+ STRING: { ts: 'string', js: 'string', py: 'str', php: 'string', rb: 'String', lua: 'string', go: 'string' },
39
+ INTEGER: { ts: 'number', js: 'number', py: 'int', php: 'int', rb: 'Integer', lua: 'number', go: 'int' },
40
+ NUMBER: { ts: 'number', js: 'number', py: 'float', php: 'float', rb: 'Float', lua: 'number', go: 'float64' },
41
+ BOOLEAN: { ts: 'boolean', js: 'boolean', py: 'bool', php: 'bool', rb: 'Boolean', lua: 'boolean', go: 'bool' },
42
+ NULL: { ts: 'null', js: 'null', py: 'None', php: 'null', rb: 'NilClass', lua: 'nil', go: 'any' },
43
+ ARRAY: { ts: 'any[]', js: 'Array', py: 'list', php: 'array', rb: 'Array', lua: 'table', go: '[]any' },
44
+ OBJECT: { ts: 'Record<string, any>', js: 'Object', py: 'dict', php: 'array', rb: 'Hash', lua: 'table', go: 'map[string]any' },
45
+ ANY: { ts: 'any', js: '*', py: 'Any', php: 'mixed', rb: 'Object', lua: 'any', go: 'any' },
46
+ }
47
+
48
+ // Per-language fallback for unknown / missing sentinels.
49
+ // js uses JSDoc's `*` (any type); lua uses `any` (LuaLS).
50
+ const CANON_ANY: Record<CanonLang, string> = {
51
+ ts: 'any', js: '*', py: 'Any', php: 'mixed', rb: 'Object', lua: 'any', go: 'any',
52
+ }
53
+
54
+
55
+ // Normalize a raw sentinel value to its bare upper-case key:
56
+ // '`$STRING`' / '$STRING' / 'string' -> 'STRING'.
57
+ function canonKey(sentinel: unknown): string {
58
+ if (null == sentinel) {
59
+ return ''
60
+ }
61
+ return String(sentinel).replace(/[`$]/g, '').trim().toUpperCase()
62
+ }
63
+
64
+
65
+ // Map a field/param type sentinel to a target-language primitive type.
66
+ // Unknown or missing sentinel -> that language's "any" (never throws).
67
+ function canonToType(sentinel: unknown, lang: string): string {
68
+ const l = lang as CanonLang
69
+ const fallback = CANON_ANY[l] ?? 'any'
70
+
71
+ const row = CANON_TYPE[canonKey(sentinel)]
72
+ if (null == row) {
73
+ return fallback
74
+ }
75
+
76
+ return row[l] ?? fallback
77
+ }
78
+
79
+
80
+ export {
81
+ canonToType,
82
+ canonKey,
83
+ CANON_TYPE,
84
+ CANON_ANY,
85
+ }
86
+
87
+ export type {
88
+ CanonLang,
89
+ }
@@ -14,17 +14,19 @@
14
14
  import { each } from 'jostraca'
15
15
  import { KIT, getModelPath } from '@voxgig/apidef'
16
16
 
17
+ import type { SdkModel, ModelDep } from '../types'
18
+
17
19
  type DepEntry = {
18
20
  name: string
19
21
  version: string
20
22
  source: 'feature' | 'target'
21
- raw: any
23
+ raw: ModelDep
22
24
  }
23
25
 
24
26
  function collectDeps(
25
- model: any,
27
+ model: SdkModel,
26
28
  targetName: string,
27
- targetDeps: any,
29
+ targetDeps: Record<string, ModelDep> | undefined,
28
30
  ): DepEntry[] {
29
31
  const out: DepEntry[] = []
30
32
  const feature = getModelPath(model, `main.${KIT}.feature`)
@@ -0,0 +1,59 @@
1
+ // Reserved-word sanitiser for generated doc-example variable names.
2
+ //
3
+ // A doc example binds a variable named after the lowercased entity name
4
+ // (e.g. `const delete = await client.Delete().load()`). When that name is a
5
+ // reserved word in the target language the snippet does not compile
6
+ // (TS1109/TS1389 for `delete`). `safeVarName` appends `_` to any reserved
7
+ // name so the example still reads clearly and compiles.
8
+ //
9
+ // Only languages whose build/vet actually rejects the name are listed. JS and
10
+ // TS share the ECMAScript reserved set (plus the strict-mode / contextual
11
+ // words a `const` binding trips on). Go lists its 25 keywords — a var named
12
+ // `type`/`func`/`range` fails `go build`; Go builtins like `delete`/`len` are
13
+ // NOT keywords and are legal identifiers, so they are intentionally omitted.
14
+ // py/php/rb/lua rarely collide on a lowercased entity name and are not treated
15
+ // here (add a set if a real collision surfaces).
16
+
17
+ const JS_RESERVED = new Set<string>([
18
+ 'break', 'case', 'catch', 'class', 'const', 'continue', 'debugger',
19
+ 'default', 'delete', 'do', 'else', 'enum', 'export', 'extends', 'false',
20
+ 'finally', 'for', 'function', 'if', 'import', 'in', 'instanceof', 'new',
21
+ 'null', 'return', 'super', 'switch', 'this', 'throw', 'true', 'try',
22
+ 'typeof', 'var', 'void', 'while', 'with', 'yield',
23
+ // strict-mode / contextual words that are invalid as a `const`/`let` binding
24
+ 'await', 'implements', 'interface', 'let', 'package', 'private',
25
+ 'protected', 'public', 'static',
26
+ ])
27
+
28
+ const GO_RESERVED = new Set<string>([
29
+ 'break', 'case', 'chan', 'const', 'continue', 'default', 'defer', 'else',
30
+ 'fallthrough', 'for', 'func', 'go', 'goto', 'if', 'import', 'interface',
31
+ 'map', 'package', 'range', 'return', 'select', 'struct', 'switch', 'type',
32
+ 'var',
33
+ ])
34
+
35
+ const RESERVED: Record<string, Set<string>> = {
36
+ ts: JS_RESERVED,
37
+ js: JS_RESERVED,
38
+ go: GO_RESERVED,
39
+ }
40
+
41
+
42
+ // Is `name` a reserved word (an illegal identifier) in the target language?
43
+ function isReservedName(name: string, lang: string): boolean {
44
+ const set = RESERVED[lang]
45
+ return !!set && set.has(name)
46
+ }
47
+
48
+
49
+ // A collision-free variable name for the target language: the name unchanged
50
+ // unless it is reserved, in which case a trailing `_` is appended.
51
+ function safeVarName(name: string, lang: string): string {
52
+ return isReservedName(name, lang) ? name + '_' : name
53
+ }
54
+
55
+
56
+ export {
57
+ isReservedName,
58
+ safeVarName,
59
+ }
@@ -0,0 +1,170 @@
1
+ // Renders a single, type-correct entity-op CALL for the neutral doc
2
+ // components (ReadmeErrors, ReadmeExplanation) that illustrate a convention
3
+ // (throw-on-error, stateful entities) with one representative operation.
4
+ //
5
+ // Two model traps this centralises:
6
+ // 1. OP-AWARENESS — the illustrated op must be one the entity actually
7
+ // exposes. A create-only entity has no `load` method, so these components
8
+ // pick the entity's PRIMARY op (entityPrimaryOp) rather than hardcoding
9
+ // `load`, and this module renders whatever op that is.
10
+ // 2. TYPE-CORRECT MATCH ID — an entity can carry its id ONLY in the
11
+ // load-match params (no `id` data field). The example id literal is
12
+ // therefore derived from the OP's param type (opRequestShape), not the
13
+ // entity fields, so a numeric match id renders `1` and not `"example_id"`
14
+ // (which would be a TS2322 against a `number` match).
15
+ //
16
+ // Output is the invocation EXPRESSION and its result binding; the surrounding
17
+ // prose / try-catch scaffolding stays in each component's per-language table.
18
+
19
+ import { each } from 'jostraca'
20
+ import { canonKey } from './canonType'
21
+ import { opRequestShape, entityIdField } from './opShape'
22
+
23
+
24
+ type ExampleLang = 'ts' | 'js' | 'py' | 'php' | 'rb' | 'lua' | 'go'
25
+
26
+
27
+ function cap(s: string): string {
28
+ return s.charAt(0).toUpperCase() + s.slice(1)
29
+ }
30
+
31
+
32
+ // A type-correct literal for a canonical type sentinel, in the target language.
33
+ function litFor(lang: ExampleLang, type: any): string {
34
+ const k = canonKey(type)
35
+ if ('INTEGER' === k || 'NUMBER' === k) return '1'
36
+ if ('BOOLEAN' === k) return 'py' === lang ? 'True' : ('rb' === lang ? 'true' : 'true')
37
+ if ('ARRAY' === k) return ('lua' === lang) ? '{}' : ('go' === lang ? '[]any{}' : '[]')
38
+ if ('OBJECT' === k) return ('go' === lang) ? 'map[string]any{}' : '{}'
39
+ return '"example"'
40
+ }
41
+
42
+
43
+ // The example id literal for an op's match key, typed from the op's declared
44
+ // param (falling back to the entity field) so a numeric id is never quoted.
45
+ function idLiteral(ent: any, op: string, idF: string | null): string {
46
+ if (null == idF) return '"example_id"'
47
+ const item = opRequestShape(ent, op).items.find((it: any) => it.name === idF)
48
+ const k = canonKey(item && item.type)
49
+ return ('INTEGER' === k || 'NUMBER' === k) ? '1' : '"example_id"'
50
+ }
51
+
52
+
53
+ // Render a match object `{ idF: idLit }` (or empty when the entity has no id
54
+ // key) in the target language's object syntax.
55
+ function matchArg(lang: ExampleLang, idF: string | null, idLit: string): string {
56
+ if (null == idF) return 'go' === lang ? 'nil' : ''
57
+ switch (lang) {
58
+ case 'py': return `{"${idF}": ${idLit}}`
59
+ case 'php': return `["${idF}" => ${idLit}]`
60
+ case 'rb': return `{ "${idF}" => ${idLit} }`
61
+ case 'lua': return `{ ${idF} = ${idLit} }`
62
+ case 'go': return `map[string]any{"${idF}": ${idLit}}`
63
+ default: return `{ ${idF}: ${idLit} }`
64
+ }
65
+ }
66
+
67
+
68
+ // The entity's required writable fields for a create/update body, rendered as
69
+ // `key: value` pairs (capped) in the target language's object syntax. Ensures
70
+ // the body satisfies a typed CreateData/UpdateData (required fields present).
71
+ function dataArg(lang: ExampleLang, ent: any, op: string, idF: string | null): string {
72
+ const items = opRequestShape(ent, op).items
73
+ .filter((it: any) => it.name !== idF && it.name !== 'id')
74
+ const required = items.filter((it: any) => !it.optional)
75
+ // ALL required fields must appear (a typed CreateData rejects a partial); cap
76
+ // only the optional fallback used when the op declares no required field.
77
+ const chosen = required.length ? required : items.slice(0, 3)
78
+ const pairs = chosen.map((it: any) => {
79
+ const v = litFor(lang, it.type)
80
+ switch (lang) {
81
+ case 'py': return `"${it.name}": ${v}`
82
+ case 'php': return `"${it.name}" => ${v}`
83
+ case 'rb': return `"${it.name}" => ${v}`
84
+ case 'lua': return `${it.name} = ${v}`
85
+ case 'go': return `"${it.name}": ${v}`
86
+ default: return `${it.name}: ${v}`
87
+ }
88
+ })
89
+ switch (lang) {
90
+ case 'php': return `[${pairs.join(', ')}]`
91
+ case 'lua': return `{ ${pairs.join(', ')} }`
92
+ case 'go': return `map[string]any{${pairs.join(', ')}}`
93
+ default: return `{ ${pairs.join(', ')} }`
94
+ }
95
+ }
96
+
97
+
98
+ type PrimaryCall = {
99
+ // The full invocation expression, e.g. `client.Advice().load({ id: 1 })`
100
+ // (ts) or `client.Generate(nil).Create(map[string]any{...}, nil)` (go).
101
+ expr: string
102
+ // The natural result-variable name (`advice`, `advices`, `generate`).
103
+ resultVar: string
104
+ // True when the op returns no value (remove) — callers that print the
105
+ // result should skip it.
106
+ isVoid: boolean
107
+ }
108
+
109
+
110
+ // Render the entity's PRIMARY-op invocation in `lang`. `eName` is the
111
+ // Capitalised entity name, `eLower` the variable-safe lowercase name, `op` the
112
+ // primary op name. Method spelling / factory syntax follow each language's
113
+ // idiom (Go PascalCase + ctrl arg, Lua `:` calls, Ruby paren-less factory).
114
+ function primaryOpCall(
115
+ lang: ExampleLang,
116
+ eName: string,
117
+ eLower: string,
118
+ op: string,
119
+ idF: string | null,
120
+ ent: any,
121
+ ): PrimaryCall {
122
+ const isMatch = 'load' === op || 'remove' === op
123
+ const isList = 'list' === op
124
+ const isData = 'create' === op || 'update' === op
125
+ const idLit = idLiteral(ent, op, idF)
126
+
127
+ // Factory + method spelling per language.
128
+ const method = 'go' === lang ? cap(op) : op
129
+ let factory: string
130
+ let sep: string
131
+ if ('go' === lang) { factory = `client.${eName}(nil)`; sep = '.' }
132
+ else if ('lua' === lang) { factory = `client:${eName}()`; sep = ':' }
133
+ else if ('rb' === lang) { factory = `client.${eName}`; sep = '.' }
134
+ else if ('php' === lang) { factory = `$client->${eName}()`; sep = '->' }
135
+ else { factory = `client.${eName}()`; sep = '.' }
136
+
137
+ // Argument string per op + language.
138
+ let arg: string
139
+ if (isList) {
140
+ arg = 'go' === lang ? 'nil' : ''
141
+ } else if (isMatch) {
142
+ arg = matchArg(lang, idF, idLit)
143
+ } else if (isData) {
144
+ arg = dataArg(lang, ent, op, idF)
145
+ } else {
146
+ arg = 'go' === lang ? 'nil' : ''
147
+ }
148
+ // Go passes a trailing ctrl arg on every entity method.
149
+ if ('go' === lang) {
150
+ arg = arg + ', nil'
151
+ }
152
+
153
+ const expr = `${factory}${sep}${method}(${arg})`
154
+ const resultVar = isList ? eLower + 's' : eLower
155
+ return { expr, resultVar, isVoid: 'remove' === op }
156
+ }
157
+
158
+
159
+ export {
160
+ primaryOpCall,
161
+ idLiteral,
162
+ matchArg,
163
+ dataArg,
164
+ litFor,
165
+ }
166
+
167
+ export type {
168
+ ExampleLang,
169
+ PrimaryCall,
170
+ }
@@ -0,0 +1,236 @@
1
+ // Per-op request-payload shape + partiality policy for the typed-model
2
+ // generators (EntityTypes_<lang>.ts).
3
+ //
4
+ // SINGLE SOURCE OF TRUTH for two things every language generator needs:
5
+ // 1. The type-name scheme: <Name>{Load,List,Remove}Match /
6
+ // <Name>{Create,Update}Data (OP_SUFFIX + opTypeName).
7
+ // 2. Which fields make up an op's request payload, and whether each is
8
+ // required or optional (opRequestShape) — i.e. the partiality policy.
9
+ //
10
+ // PARTIALITY POLICY
11
+ // Op-declared params win: if the op declares params
12
+ // (op.<name>.points[].args.params[]), the payload is built from them and a
13
+ // param is optional iff `reqd === false` (this is how path/query params such
14
+ // as {id} become required). `fromParams` is true in that case.
15
+ //
16
+ // Otherwise the payload mirrors the entity's fields, filtered to those active
17
+ // for the op (field.op[opname].active !== false; absent -> participates), and
18
+ // optionality is decided per-op:
19
+ // create -> required iff `field.req` (server-shaped required fields);
20
+ // update -> all optional (patch);
21
+ // load / remove -> a field named `id` is required, the rest optional
22
+ // (best-effort key convention; degrades to all-optional if no `id`);
23
+ // list -> all optional (filter).
24
+ //
25
+ // The generators consume `items` (each already carrying its final `optional`
26
+ // flag) and render them in the target language's struct/interface/TypedDict
27
+ // syntax; the policy itself is language-neutral and tested in isolation.
28
+
29
+ import { each } from 'jostraca'
30
+
31
+
32
+ // The five ops, and whether their request payload is a `Match` (query/id) or
33
+ // `Data` (body) — this fixes the generated type-name suffix per op.
34
+ const OP_SUFFIX: Record<string, 'Match' | 'Data'> = {
35
+ load: 'Match',
36
+ list: 'Match',
37
+ remove: 'Match',
38
+ create: 'Data',
39
+ update: 'Data',
40
+ }
41
+
42
+
43
+ function cap(s: string): string {
44
+ return s.charAt(0).toUpperCase() + s.slice(1)
45
+ }
46
+
47
+
48
+ // The generated type name for an op's request payload, e.g. AdviceLoadMatch.
49
+ function opTypeName(Name: string, opname: string): string {
50
+ return Name + cap(opname) + (OP_SUFFIX[opname] || 'Match')
51
+ }
52
+
53
+
54
+ // One request-payload member: a model field or op param, with the final
55
+ // required/optional decision already applied per the partiality policy.
56
+ type OpShapeItem = {
57
+ name: string
58
+ type: any // canonical type sentinel (e.g. `$STRING`); render via canonToType
59
+ optional: boolean
60
+ }
61
+
62
+
63
+ // Collect an op's params, deduped by name across all of its points.
64
+ function opParams(op: any): any[] {
65
+ const points = op && op.points ? each(op.points) : []
66
+ const seen: Record<string, boolean> = {}
67
+ const out: any[] = []
68
+ points.forEach((pt: any) => {
69
+ const params = pt && pt.args && pt.args.params ? each(pt.args.params) : []
70
+ params.forEach((p: any) => {
71
+ if (p && null != p.name && !seen[p.name]) {
72
+ seen[p.name] = true
73
+ out.push(p)
74
+ }
75
+ })
76
+ })
77
+ return out
78
+ }
79
+
80
+
81
+ // Does a field participate in an op? Absent op-entry -> participates; only an
82
+ // explicit `active: false` excludes it.
83
+ function fieldInOp(field: any, opname: string): boolean {
84
+ const fop = field && field.op && field.op[opname]
85
+ return null == fop || fop.active !== false
86
+ }
87
+
88
+
89
+ // Decide optionality for a field in a no-params request payload, per op.
90
+ function fieldOptional(field: any, opname: string): boolean {
91
+ switch (opname) {
92
+ case 'create':
93
+ // Respect the model's required flag: required unless req === false.
94
+ return false === field.req
95
+ case 'update':
96
+ // Patch semantics — every field optional.
97
+ return true
98
+ case 'load':
99
+ case 'remove':
100
+ // Best-effort key convention: the `id` field is required, rest optional.
101
+ return 'id' !== field.name
102
+ case 'list':
103
+ default:
104
+ // Filter — every field optional.
105
+ return true
106
+ }
107
+ }
108
+
109
+
110
+ // The ordered request-payload members for an entity op, with each member's
111
+ // required/optional decision baked in. `fromParams` records whether the op's
112
+ // declared params were used (true) or the entity-field fallback (false).
113
+ function opRequestShape(ent: any, opname: string):
114
+ { items: OpShapeItem[], fromParams: boolean } {
115
+
116
+ const op = ent && ent.op ? ent.op[opname] : null
117
+ if (null == op) {
118
+ return { items: [], fromParams: false }
119
+ }
120
+
121
+ const params = opParams(op)
122
+ if (0 < params.length) {
123
+ const items = params.map((p: any) => ({
124
+ name: p.name,
125
+ type: p.type,
126
+ optional: false === p.reqd,
127
+ }))
128
+ return { items, fromParams: true }
129
+ }
130
+
131
+ const fields = (ent.fields ? each(ent.fields) : [])
132
+ .filter((f: any) => f.active !== false)
133
+ .filter((f: any) => fieldInOp(f, opname))
134
+
135
+ const items = fields.map((f: any) => ({
136
+ name: f.name,
137
+ type: f.type,
138
+ optional: fieldOptional(f, opname),
139
+ }))
140
+
141
+ return { items, fromParams: false }
142
+ }
143
+
144
+
145
+ // The entity's id-like key field, or null when it has none. Used by the doc
146
+ // generators to decide whether an example may key a load/remove on `{ id: ... }`
147
+ // and access `.id` on a returned entity, OR must degrade to `load()` with no
148
+ // argument (some APIs model an entity whose load match carries no id — e.g. a
149
+ // response-wrapped spec, where AqiLoadMatch is { code, data, msg }). Prefers the
150
+ // model's declared id field name, then a literal `id`, checking the load-match
151
+ // shape first and the entity's own fields as a fallback.
152
+ function entityIdField(ent: any): string | null {
153
+ if (null == ent) {
154
+ return null
155
+ }
156
+ const idName = (ent.id && ent.id.field) || 'id'
157
+ const loadItems = opRequestShape(ent, 'load').items
158
+ if (loadItems.some((it: OpShapeItem) => it.name === idName)) {
159
+ return idName
160
+ }
161
+ if (loadItems.some((it: OpShapeItem) => it.name === 'id')) {
162
+ return 'id'
163
+ }
164
+ // NO fallback to entity.fields: this is the load-MATCH key. An entity whose
165
+ // DATA type has an `id` field but whose load match does NOT (a query-param
166
+ // load, e.g. playstation-store's StoreLoadMatch { age, country, ... }) must
167
+ // degrade to a no-arg load(); `.id` access is decided by entityDataIdField.
168
+ return null
169
+ }
170
+
171
+
172
+ // The entity's ACTIVE op names, in canonical CRUD order (list, load, create,
173
+ // update, remove), with any non-canonical ops appended in sorted order. Doc
174
+ // generators must gate an op example on this (an op present in the model but
175
+ // `active: false` generates no method, so an example calling it would not
176
+ // compile) — NOT on the raw `Object.keys(ent.op)`, which includes inactive ops.
177
+ const CANON_OP_ORDER = ['list', 'load', 'create', 'update', 'remove']
178
+
179
+ function entityOps(ent: any): string[] {
180
+ const ops = (ent && ent.op) || {}
181
+ const active = Object.keys(ops).filter((o: string) => ops[o] && ops[o].active !== false)
182
+ return CANON_OP_ORDER.filter((o) => active.includes(o))
183
+ .concat(active.filter((o) => !CANON_OP_ORDER.includes(o)).sort())
184
+ }
185
+
186
+
187
+ // The entity's primary/representative op for a single illustrative call —
188
+ // prefer a read op (list, then load) so the snippet needs no fabricated match,
189
+ // then fall back to create/update/remove. null when the entity exposes no op.
190
+ // Doc generators MUST pick their "primary" op through this rather than
191
+ // hardcoding `load`: a create-only entity has no `load` method.
192
+ function entityPrimaryOp(ent: any): string | null {
193
+ const ops = entityOps(ent)
194
+ for (const o of CANON_OP_ORDER) {
195
+ if (ops.includes(o)) {
196
+ return o
197
+ }
198
+ }
199
+ return ops[0] || null
200
+ }
201
+
202
+
203
+ // The id field on the entity's DATA type (its fields[]), or null. DISTINCT from
204
+ // entityIdField (the load-MATCH key): an API can model a load match that carries
205
+ // an `id` param while the response entity itself has no `id` field, so `.id`
206
+ // access on a RETURNED record must be guarded on this, not on the match key.
207
+ function entityDataIdField(ent: any): string | null {
208
+ if (null == ent) {
209
+ return null
210
+ }
211
+ const idName = (ent.id && ent.id.field) || 'id'
212
+ const fields = ent.fields ? each(ent.fields) : []
213
+ if (fields.some((f: any) => f && f.name === idName)) {
214
+ return idName
215
+ }
216
+ if (fields.some((f: any) => f && f.name === 'id')) {
217
+ return 'id'
218
+ }
219
+ return null
220
+ }
221
+
222
+
223
+ export {
224
+ OP_SUFFIX,
225
+ opTypeName,
226
+ opParams,
227
+ opRequestShape,
228
+ entityIdField,
229
+ entityDataIdField,
230
+ entityOps,
231
+ entityPrimaryOp,
232
+ }
233
+
234
+ export type {
235
+ OpShapeItem,
236
+ }