@voxgig/sdkgen 1.2.1 → 1.3.2

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 (345) hide show
  1. package/bin/voxgig-sdkgen +2 -2
  2. package/dist/action/action.d.ts +3 -1
  3. package/dist/action/action.js +26 -10
  4. package/dist/action/action.js.map +1 -1
  5. package/dist/action/feature.js +9 -8
  6. package/dist/action/feature.js.map +1 -1
  7. package/dist/action/target.d.ts +7 -1
  8. package/dist/action/target.js +22 -13
  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 +225 -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 +12 -2
  53. package/dist/sdkgen.js +60 -20
  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.d.ts +2 -1
  59. package/dist/utility.js +39 -11
  60. package/dist/utility.js.map +1 -1
  61. package/model/sdkgen.aontu +137 -0
  62. package/package.json +11 -5
  63. package/project/.sdk/model/feature/feature-index.aontu +5 -0
  64. package/project/.sdk/model/target/go-cli.aontu +47 -0
  65. package/project/.sdk/model/target/go-mcp.aontu +41 -0
  66. package/project/.sdk/model/target/go.aontu +28 -0
  67. package/project/.sdk/model/target/{js.jsonic → js.aontu} +13 -0
  68. package/project/.sdk/model/target/{lua.jsonic → lua.aontu} +13 -0
  69. package/project/.sdk/model/target/{php.jsonic → php.aontu} +13 -0
  70. package/project/.sdk/model/target/{py.jsonic → py.aontu} +13 -0
  71. package/project/.sdk/model/target/{rb.jsonic → rb.aontu} +13 -0
  72. package/project/.sdk/model/target/{ts.jsonic → ts.aontu} +13 -0
  73. package/project/.sdk/src/cmp/go/Config_go.ts +3 -2
  74. package/project/.sdk/src/cmp/go/EntityOperation_go.ts +1 -0
  75. package/project/.sdk/src/cmp/go/EntityTypes_go.ts +197 -0
  76. package/project/.sdk/src/cmp/go/Entity_go.ts +2 -1
  77. package/project/.sdk/src/cmp/go/MainEntity_go.ts +6 -0
  78. package/project/.sdk/src/cmp/go/Main_go.ts +23 -3
  79. package/project/.sdk/src/cmp/go/Package_go.ts +1 -1
  80. package/project/.sdk/src/cmp/go/ReadmeEntity_go.ts +48 -10
  81. package/project/.sdk/src/cmp/go/ReadmeExamplesTest_go.ts +688 -0
  82. package/project/.sdk/src/cmp/go/ReadmeExplanation_go.ts +1 -1
  83. package/project/.sdk/src/cmp/go/ReadmeHowto_go.ts +52 -8
  84. package/project/.sdk/src/cmp/go/ReadmeInstall_go.ts +11 -6
  85. package/project/.sdk/src/cmp/go/ReadmeIntro_go.ts +40 -1
  86. package/project/.sdk/src/cmp/go/ReadmeModel_go.ts +67 -17
  87. package/project/.sdk/src/cmp/go/ReadmeOptions_go.ts +4 -3
  88. package/project/.sdk/src/cmp/go/ReadmeQuick_go.ts +146 -116
  89. package/project/.sdk/src/cmp/go/ReadmeRef_go.ts +87 -21
  90. package/project/.sdk/src/cmp/go/ReadmeTopHowto_go.ts +4 -0
  91. package/project/.sdk/src/cmp/go/ReadmeTopQuick_go.ts +75 -16
  92. package/project/.sdk/src/cmp/go/ReadmeTopTest_go.ts +35 -5
  93. package/project/.sdk/src/cmp/go/TestEntity_go.ts +1 -1
  94. package/project/.sdk/src/cmp/go/Test_go.ts +5 -1
  95. package/project/.sdk/src/cmp/go/fragment/Entity.fragment.go +21 -0
  96. package/project/.sdk/src/cmp/go/fragment/EntityCreateOp.fragment.go +11 -0
  97. package/project/.sdk/src/cmp/go/fragment/EntityListOp.fragment.go +11 -0
  98. package/project/.sdk/src/cmp/go/fragment/EntityLoadOp.fragment.go +11 -0
  99. package/project/.sdk/src/cmp/go/fragment/EntityRemoveOp.fragment.go +11 -0
  100. package/project/.sdk/src/cmp/go/fragment/EntityUpdateOp.fragment.go +11 -0
  101. package/project/.sdk/src/cmp/go/utility_go.ts +70 -0
  102. package/project/.sdk/src/cmp/go-cli/Main_go-cli.ts +195 -0
  103. package/project/.sdk/src/cmp/go-cli/fragment/main.fragment.go +106 -0
  104. package/project/.sdk/src/cmp/go-cli/fragment/words.fragment.go +132 -0
  105. package/project/.sdk/src/cmp/go-mcp/Main_go-mcp.ts +184 -0
  106. package/project/.sdk/src/cmp/go-mcp/fragment/main.fragment.go +68 -0
  107. package/project/.sdk/src/cmp/go-mcp/fragment/tools.fragment.go +114 -0
  108. package/project/.sdk/src/cmp/js/Config_js.ts +3 -6
  109. package/project/.sdk/src/cmp/js/EntityTypes_js.ts +111 -0
  110. package/project/.sdk/src/cmp/js/MainEntity_js.ts +1 -0
  111. package/project/.sdk/src/cmp/js/Main_js.ts +3 -0
  112. package/project/.sdk/src/cmp/js/Package_js.ts +16 -7
  113. package/project/.sdk/src/cmp/js/ReadmeEntity_js.ts +33 -10
  114. package/project/.sdk/src/cmp/js/ReadmeExplanation_js.ts +2 -2
  115. package/project/.sdk/src/cmp/js/ReadmeHowto_js.ts +52 -11
  116. package/project/.sdk/src/cmp/js/ReadmeIntro_js.ts +39 -1
  117. package/project/.sdk/src/cmp/js/ReadmeModel_js.ts +50 -18
  118. package/project/.sdk/src/cmp/js/ReadmeOptions_js.ts +4 -3
  119. package/project/.sdk/src/cmp/js/ReadmeQuick_js.ts +70 -20
  120. package/project/.sdk/src/cmp/js/ReadmeRef_js.ts +50 -16
  121. package/project/.sdk/src/cmp/js/ReadmeTopHowto_js.ts +3 -0
  122. package/project/.sdk/src/cmp/js/ReadmeTopQuick_js.ts +45 -19
  123. package/project/.sdk/src/cmp/js/ReadmeTopTest_js.ts +35 -3
  124. package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +5 -0
  125. package/project/.sdk/src/cmp/js/fragment/EntityListOp.fragment.js +5 -0
  126. package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +5 -0
  127. package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +5 -0
  128. package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +5 -0
  129. package/project/.sdk/src/cmp/js/utility_js.ts +57 -0
  130. package/project/.sdk/src/cmp/lua/Config_lua.ts +3 -2
  131. package/project/.sdk/src/cmp/lua/EntityTypes_lua.ts +113 -0
  132. package/project/.sdk/src/cmp/lua/MainEntity_lua.ts +8 -0
  133. package/project/.sdk/src/cmp/lua/Main_lua.ts +4 -0
  134. package/project/.sdk/src/cmp/lua/Package_lua.ts +23 -4
  135. package/project/.sdk/src/cmp/lua/ReadmeEntity_lua.ts +50 -13
  136. package/project/.sdk/src/cmp/lua/ReadmeExamplesTest_lua.ts +293 -0
  137. package/project/.sdk/src/cmp/lua/ReadmeHowto_lua.ts +46 -8
  138. package/project/.sdk/src/cmp/lua/ReadmeInstall_lua.ts +19 -3
  139. package/project/.sdk/src/cmp/lua/ReadmeIntro_lua.ts +38 -1
  140. package/project/.sdk/src/cmp/lua/ReadmeModel_lua.ts +51 -16
  141. package/project/.sdk/src/cmp/lua/ReadmeOptions_lua.ts +4 -3
  142. package/project/.sdk/src/cmp/lua/ReadmeQuick_lua.ts +156 -21
  143. package/project/.sdk/src/cmp/lua/ReadmeRef_lua.ts +71 -23
  144. package/project/.sdk/src/cmp/lua/ReadmeTopQuick_lua.ts +46 -9
  145. package/project/.sdk/src/cmp/lua/ReadmeTopTest_lua.ts +43 -5
  146. package/project/.sdk/src/cmp/lua/Test_lua.ts +4 -0
  147. package/project/.sdk/src/cmp/lua/fragment/EntityCreateOp.fragment.lua +4 -0
  148. package/project/.sdk/src/cmp/lua/fragment/EntityListOp.fragment.lua +4 -0
  149. package/project/.sdk/src/cmp/lua/fragment/EntityLoadOp.fragment.lua +4 -0
  150. package/project/.sdk/src/cmp/lua/fragment/EntityRemoveOp.fragment.lua +4 -0
  151. package/project/.sdk/src/cmp/lua/fragment/EntityUpdateOp.fragment.lua +4 -0
  152. package/project/.sdk/src/cmp/php/Config_php.ts +3 -2
  153. package/project/.sdk/src/cmp/php/EntityTypes_php.ts +142 -0
  154. package/project/.sdk/src/cmp/php/MainEntity_php.ts +18 -1
  155. package/project/.sdk/src/cmp/php/Main_php.ts +4 -0
  156. package/project/.sdk/src/cmp/php/Package_php.ts +18 -7
  157. package/project/.sdk/src/cmp/php/ReadmeEntity_php.ts +46 -14
  158. package/project/.sdk/src/cmp/php/ReadmeExamplesTest_php.ts +401 -0
  159. package/project/.sdk/src/cmp/php/ReadmeHowto_php.ts +56 -13
  160. package/project/.sdk/src/cmp/php/ReadmeInstall_php.ts +15 -3
  161. package/project/.sdk/src/cmp/php/ReadmeIntro_php.ts +40 -1
  162. package/project/.sdk/src/cmp/php/ReadmeModel_php.ts +26 -8
  163. package/project/.sdk/src/cmp/php/ReadmeOptions_php.ts +4 -3
  164. package/project/.sdk/src/cmp/php/ReadmeQuick_php.ts +159 -25
  165. package/project/.sdk/src/cmp/php/ReadmeRef_php.ts +90 -45
  166. package/project/.sdk/src/cmp/php/ReadmeTopHowto_php.ts +1 -1
  167. package/project/.sdk/src/cmp/php/ReadmeTopQuick_php.ts +43 -11
  168. package/project/.sdk/src/cmp/php/ReadmeTopTest_php.ts +52 -11
  169. package/project/.sdk/src/cmp/php/TestDirect_php.ts +9 -9
  170. package/project/.sdk/src/cmp/php/TestEntity_php.ts +6 -12
  171. package/project/.sdk/src/cmp/php/Test_php.ts +4 -0
  172. package/project/.sdk/src/cmp/php/fragment/Entity.fragment.php +13 -1
  173. package/project/.sdk/src/cmp/php/fragment/EntityCreateOp.fragment.php +10 -1
  174. package/project/.sdk/src/cmp/php/fragment/EntityListOp.fragment.php +10 -1
  175. package/project/.sdk/src/cmp/php/fragment/EntityLoadOp.fragment.php +10 -1
  176. package/project/.sdk/src/cmp/php/fragment/EntityRemoveOp.fragment.php +10 -1
  177. package/project/.sdk/src/cmp/php/fragment/EntityUpdateOp.fragment.php +10 -1
  178. package/project/.sdk/src/cmp/php/fragment/Main.fragment.php +22 -14
  179. package/project/.sdk/src/cmp/py/Config_py.ts +3 -2
  180. package/project/.sdk/src/cmp/py/EntityTypes_py.ts +184 -0
  181. package/project/.sdk/src/cmp/py/Entity_py.ts +27 -0
  182. package/project/.sdk/src/cmp/py/MainEntity_py.ts +2 -1
  183. package/project/.sdk/src/cmp/py/Main_py.ts +35 -0
  184. package/project/.sdk/src/cmp/py/Package_py.ts +24 -3
  185. package/project/.sdk/src/cmp/py/ReadmeEntity_py.ts +48 -14
  186. package/project/.sdk/src/cmp/py/ReadmeExamplesTest_py.ts +626 -0
  187. package/project/.sdk/src/cmp/py/ReadmeHowto_py.ts +53 -14
  188. package/project/.sdk/src/cmp/py/ReadmeInstall_py.ts +19 -3
  189. package/project/.sdk/src/cmp/py/ReadmeIntro_py.ts +48 -1
  190. package/project/.sdk/src/cmp/py/ReadmeModel_py.ts +28 -10
  191. package/project/.sdk/src/cmp/py/ReadmeOptions_py.ts +4 -3
  192. package/project/.sdk/src/cmp/py/ReadmeQuick_py.ts +150 -27
  193. package/project/.sdk/src/cmp/py/ReadmeRef_py.ts +86 -40
  194. package/project/.sdk/src/cmp/py/ReadmeTopHowto_py.ts +1 -1
  195. package/project/.sdk/src/cmp/py/ReadmeTopQuick_py.ts +45 -11
  196. package/project/.sdk/src/cmp/py/ReadmeTopTest_py.ts +43 -5
  197. package/project/.sdk/src/cmp/py/TestDirect_py.ts +7 -9
  198. package/project/.sdk/src/cmp/py/TestEntity_py.ts +6 -14
  199. package/project/.sdk/src/cmp/py/Test_py.ts +4 -0
  200. package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +5 -2
  201. package/project/.sdk/src/cmp/py/fragment/EntityCreateOp.fragment.py +1 -1
  202. package/project/.sdk/src/cmp/py/fragment/EntityListOp.fragment.py +5 -1
  203. package/project/.sdk/src/cmp/py/fragment/EntityLoadOp.fragment.py +6 -1
  204. package/project/.sdk/src/cmp/py/fragment/EntityRemoveOp.fragment.py +6 -1
  205. package/project/.sdk/src/cmp/py/fragment/EntityUpdateOp.fragment.py +1 -1
  206. package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +17 -10
  207. package/project/.sdk/src/cmp/rb/Config_rb.ts +3 -2
  208. package/project/.sdk/src/cmp/rb/EntityTypes_rb.ts +136 -0
  209. package/project/.sdk/src/cmp/rb/MainEntity_rb.ts +1 -0
  210. package/project/.sdk/src/cmp/rb/Main_rb.ts +4 -0
  211. package/project/.sdk/src/cmp/rb/Package_rb.ts +34 -7
  212. package/project/.sdk/src/cmp/rb/ReadmeEntity_rb.ts +47 -13
  213. package/project/.sdk/src/cmp/rb/ReadmeExamplesTest_rb.ts +289 -0
  214. package/project/.sdk/src/cmp/rb/ReadmeHowto_rb.ts +72 -21
  215. package/project/.sdk/src/cmp/rb/ReadmeInstall_rb.ts +16 -4
  216. package/project/.sdk/src/cmp/rb/ReadmeIntro_rb.ts +40 -1
  217. package/project/.sdk/src/cmp/rb/ReadmeModel_rb.ts +29 -12
  218. package/project/.sdk/src/cmp/rb/ReadmeOptions_rb.ts +4 -3
  219. package/project/.sdk/src/cmp/rb/ReadmeQuick_rb.ts +163 -25
  220. package/project/.sdk/src/cmp/rb/ReadmeRef_rb.ts +85 -40
  221. package/project/.sdk/src/cmp/rb/ReadmeTopHowto_rb.ts +1 -1
  222. package/project/.sdk/src/cmp/rb/ReadmeTopQuick_rb.ts +45 -11
  223. package/project/.sdk/src/cmp/rb/ReadmeTopTest_rb.ts +54 -11
  224. package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +9 -9
  225. package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +6 -12
  226. package/project/.sdk/src/cmp/rb/Test_rb.ts +4 -0
  227. package/project/.sdk/src/cmp/rb/fragment/Entity.fragment.rb +2 -0
  228. package/project/.sdk/src/cmp/rb/fragment/EntityCreateOp.fragment.rb +5 -0
  229. package/project/.sdk/src/cmp/rb/fragment/EntityListOp.fragment.rb +20 -2
  230. package/project/.sdk/src/cmp/rb/fragment/EntityLoadOp.fragment.rb +8 -1
  231. package/project/.sdk/src/cmp/rb/fragment/EntityRemoveOp.fragment.rb +6 -1
  232. package/project/.sdk/src/cmp/rb/fragment/EntityUpdateOp.fragment.rb +5 -0
  233. package/project/.sdk/src/cmp/rb/fragment/Main.fragment.rb +24 -8
  234. package/project/.sdk/src/cmp/ts/Config_ts.ts +3 -6
  235. package/project/.sdk/src/cmp/ts/EntityTypes_ts.ts +105 -0
  236. package/project/.sdk/src/cmp/ts/Entity_ts.ts +17 -1
  237. package/project/.sdk/src/cmp/ts/MainEntity_ts.ts +1 -0
  238. package/project/.sdk/src/cmp/ts/Main_ts.ts +6 -0
  239. package/project/.sdk/src/cmp/ts/Package_ts.ts +14 -7
  240. package/project/.sdk/src/cmp/ts/ReadmeEntity_ts.ts +32 -10
  241. package/project/.sdk/src/cmp/ts/ReadmeExampleTest_ts.ts +81 -0
  242. package/project/.sdk/src/cmp/ts/ReadmeExamplesTest_ts.ts +446 -0
  243. package/project/.sdk/src/cmp/ts/ReadmeExplanation_ts.ts +2 -2
  244. package/project/.sdk/src/cmp/ts/ReadmeHowto_ts.ts +57 -11
  245. package/project/.sdk/src/cmp/ts/ReadmeInstall_ts.ts +19 -6
  246. package/project/.sdk/src/cmp/ts/ReadmeIntro_ts.ts +39 -1
  247. package/project/.sdk/src/cmp/ts/ReadmeModel_ts.ts +50 -18
  248. package/project/.sdk/src/cmp/ts/ReadmeOptions_ts.ts +4 -3
  249. package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +141 -48
  250. package/project/.sdk/src/cmp/ts/ReadmeRef_ts.ts +50 -16
  251. package/project/.sdk/src/cmp/ts/ReadmeTopHowto_ts.ts +3 -0
  252. package/project/.sdk/src/cmp/ts/ReadmeTopQuick_ts.ts +58 -19
  253. package/project/.sdk/src/cmp/ts/ReadmeTopTest_ts.ts +35 -3
  254. package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +2 -2
  255. package/project/.sdk/src/cmp/ts/Test_ts.ts +5 -0
  256. package/project/.sdk/src/cmp/ts/fragment/Entity.fragment.ts +3 -1
  257. package/project/.sdk/src/cmp/ts/fragment/EntityBase.fragment.ts +10 -5
  258. package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.ts +4 -2
  259. package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.ts +4 -2
  260. package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.ts +4 -2
  261. package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.ts +4 -2
  262. package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.ts +4 -2
  263. package/project/.sdk/src/cmp/ts/utility_ts.ts +59 -0
  264. package/project/.sdk/tm/go/LICENSE +1 -1
  265. package/project/.sdk/tm/go/Makefile +36 -1
  266. package/project/.sdk/tm/go/VERSION +1 -0
  267. package/project/.sdk/tm/go/core/context.go +12 -7
  268. package/project/.sdk/tm/go-cli/src/feature/README.md +6 -0
  269. package/project/.sdk/tm/go-cli/src/feature/base/.gitkeep +0 -0
  270. package/project/.sdk/tm/go-cli/src/feature/log/.gitkeep +0 -0
  271. package/project/.sdk/tm/go-cli/src/feature/test/.gitkeep +0 -0
  272. package/project/.sdk/tm/go-mcp/src/feature/README.md +6 -0
  273. package/project/.sdk/tm/go-mcp/src/feature/base/.gitkeep +0 -0
  274. package/project/.sdk/tm/go-mcp/src/feature/log/.gitkeep +0 -0
  275. package/project/.sdk/tm/go-mcp/src/feature/test/.gitkeep +0 -0
  276. package/project/.sdk/tm/js/LICENSE +1 -1
  277. package/project/.sdk/tm/js/Makefile +41 -0
  278. package/project/.sdk/tm/lua/LICENSE +1 -1
  279. package/project/.sdk/tm/lua/Makefile +40 -1
  280. package/project/.sdk/tm/lua/core/context.lua +13 -8
  281. package/project/.sdk/tm/php/LICENSE +1 -1
  282. package/project/.sdk/tm/php/Makefile +31 -1
  283. package/project/.sdk/tm/php/VERSION +1 -0
  284. package/project/.sdk/tm/php/core/Context.php +12 -6
  285. package/project/.sdk/tm/php/test/PrimaryUtilityTest.php +13 -4
  286. package/project/.sdk/tm/php/utility/Done.php +2 -2
  287. package/project/.sdk/tm/php/utility/MakeError.php +3 -3
  288. package/project/.sdk/tm/py/LICENSE +1 -1
  289. package/project/.sdk/tm/py/Makefile +34 -1
  290. package/project/.sdk/tm/py/core/context.py +12 -7
  291. package/project/.sdk/tm/py/test/test_primary_utility.py +15 -4
  292. package/project/.sdk/tm/py/test/test_struct_utility.py +1 -1
  293. package/project/.sdk/tm/py/utility/done.py +3 -1
  294. package/project/.sdk/tm/py/utility/make_error.py +2 -2
  295. package/project/.sdk/tm/rb/LICENSE +1 -1
  296. package/project/.sdk/tm/rb/Makefile +36 -2
  297. package/project/.sdk/tm/rb/core/context.rb +8 -3
  298. package/project/.sdk/tm/rb/test/primary_utility_test.rb +2 -2
  299. package/project/.sdk/tm/rb/utility/done.rb +3 -1
  300. package/project/.sdk/tm/rb/utility/make_error.rb +5 -2
  301. package/project/.sdk/tm/ts/LICENSE +1 -1
  302. package/project/.sdk/tm/ts/Makefile +42 -0
  303. package/project/.sdk/tm/ts/src/Context.ts +8 -3
  304. package/src/action/action.ts +30 -11
  305. package/src/action/feature.ts +12 -14
  306. package/src/action/target.ts +28 -17
  307. package/src/cmp/Changelog.ts +34 -0
  308. package/src/cmp/Deploy.ts +258 -0
  309. package/src/cmp/FeatureHook.ts +6 -8
  310. package/src/cmp/License.ts +49 -0
  311. package/src/cmp/Readme.ts +2 -0
  312. package/src/cmp/ReadmeErrors.ts +257 -0
  313. package/src/cmp/ReadmeExplanation.ts +250 -230
  314. package/src/cmp/ReadmeModel.ts +7 -2
  315. package/src/cmp/ReadmeTop.ts +411 -95
  316. package/src/cmp/Security.ts +41 -0
  317. package/src/helpers/canonType.ts +89 -0
  318. package/src/helpers/collectDeps.ts +5 -3
  319. package/src/helpers/naming.ts +59 -0
  320. package/src/helpers/opExample.ts +170 -0
  321. package/src/helpers/opShape.ts +274 -0
  322. package/src/helpers/packageMeta.ts +236 -0
  323. package/src/sdkgen.ts +91 -23
  324. package/src/tsconfig.json +1 -0
  325. package/src/types.ts +85 -2
  326. package/src/utility.ts +45 -11
  327. package/README.md +0 -2
  328. package/dist/action/lang.d.ts +0 -2
  329. package/dist/action/lang.js +0 -68
  330. package/dist/action/lang.js.map +0 -1
  331. package/dist/cmp/Hook.d.ts +0 -2
  332. package/dist/cmp/Hook.js +0 -10
  333. package/dist/cmp/Hook.js.map +0 -1
  334. package/dist/cmp/Top.d.ts +0 -2
  335. package/dist/cmp/Top.js +0 -23
  336. package/dist/cmp/Top.js.map +0 -1
  337. package/dist/prepare-openapi.d.ts +0 -2
  338. package/dist/prepare-openapi.js +0 -37
  339. package/dist/prepare-openapi.js.map +0 -1
  340. package/model/sdkgen.jsonic +0 -74
  341. package/project/.sdk/model/feature/feature-index.jsonic +0 -5
  342. package/project/.sdk/model/target/go.jsonic +0 -22
  343. package/project/.sdk/tm/go/utility/struct/go.mod +0 -3
  344. /package/project/.sdk/model/feature/{log.jsonic → log.aontu} +0 -0
  345. /package/project/.sdk/model/feature/{test.jsonic → test.aontu} +0 -0
@@ -1,5 +1,5 @@
1
1
 
2
- import { cmp, each, Content, isAuthActive } from '@voxgig/sdkgen'
2
+ import { cmp, each, Content, isAuthActive, envName, canonKey, opRequestShape, entityIdField, entityDataIdField, entityOps } from '@voxgig/sdkgen'
3
3
 
4
4
  import {
5
5
  KIT,
@@ -14,78 +14,216 @@ const ReadmeQuick = cmp(function ReadmeQuick(props: any) {
14
14
  const entity = getModelPath(model, `main.${KIT}.entity`)
15
15
 
16
16
  const exampleEntity = Object.values(entity).find((e: any) => e.active !== false) as any
17
+
18
+ // Find a nested entity if available: one with a parent chain
19
+ // (relations.ancestors), an active load op, and a required non-id load
20
+ // param to demonstrate (the parent key, e.g. page_id).
17
21
  const nestedEntity = Object.values(entity).find((e: any) =>
18
- e.active !== false && e.ancestors && e.ancestors.length > 0
22
+ e.active !== false &&
23
+ e.relations && e.relations.ancestors && 0 < e.relations.ancestors.length &&
24
+ entityOps(e).includes('load') &&
25
+ opRequestShape(e, 'load').items.some((it: any) =>
26
+ !it.optional && it.name !== entityIdField(e))
19
27
  ) as any
20
28
 
21
- const apikeyArg = isAuthActive(model)
22
- ? `\n "apikey" => ENV["${model.NAME}_APIKEY"],\n`
23
- : ''
29
+ const ctor = isAuthActive(model)
30
+ ? `${model.const.Name}SDK.new({\n "apikey" => ENV["${envName(model)}_APIKEY"],\n})`
31
+ : `${model.const.Name}SDK.new`
24
32
 
25
33
  Content(`### 1. Create a client
26
34
 
27
35
  \`\`\`ruby
28
36
  require_relative "${model.const.Name}_sdk"
29
37
 
30
- client = ${model.const.Name}SDK.new({${apikeyArg}})
38
+ client = ${ctor}
31
39
  \`\`\`
32
40
 
33
41
  `)
34
42
 
35
43
  if (exampleEntity) {
36
44
  const eName = nom(exampleEntity, 'Name')
37
- const opnames = Object.keys(exampleEntity.op || {})
45
+ const article = /^[aeiou]/i.test(eName) ? "an" : "a"
46
+ const opnames = entityOps(exampleEntity)
47
+ // Model-driven id keys: `idF` is the load-MATCH key (null when the entity
48
+ // has no id-like field — a response-wrapped spec); when null, load/remove
49
+ // take no argument. `dataIdF` is the id on the RETURNED record's data type —
50
+ // an entity can key its match on an id it does not carry as data, so both a
51
+ // listed record's id column and a `created["id"]` read must be guarded on
52
+ // this, not the match key.
53
+ const idF = entityIdField(exampleEntity)
54
+ const dataIdF = entityDataIdField(exampleEntity)
55
+
56
+ // A type-correct, executable Ruby literal for a param: numeric/boolean/
57
+ // array/hash params render a typed literal; strings render the quoted
58
+ // placeholder (the doc test EXECUTES these blocks, so a comment
59
+ // placeholder would not parse).
60
+ const rbLit = (type: any, placeholder: string = 'example'): string => {
61
+ const k = canonKey(type)
62
+ if ('INTEGER' === k || 'NUMBER' === k) return '1'
63
+ if ('BOOLEAN' === k) return 'true'
64
+ if ('ARRAY' === k) return '[]'
65
+ if ('OBJECT' === k) return '{}'
66
+ return `"${placeholder}"`
67
+ }
68
+
69
+ // Model-driven display field: the entity's first non-id string field
70
+ // (falling back to any non-id field), so the list example prints a real
71
+ // column instead of a hardcoded "name" the entity may not have.
72
+ const fields = exampleEntity.fields || []
73
+ const displayField =
74
+ fields.find((f: any) => f && f.name !== 'id' && f.type === '$STRING') ||
75
+ fields.find((f: any) => f && f.name !== 'id') ||
76
+ null
77
+ const idCol = dataIdF ? `#{item[${JSON.stringify(dataIdF)}]}` : null
78
+ const dispCol = displayField ? `#{item[${JSON.stringify(displayField.name)}]}` : null
79
+ const itemPrint = [idCol, dispCol].filter(Boolean).join(' ') || '#{item}'
38
80
 
39
81
  if (opnames.includes('list')) {
40
- Content(`### 2. List ${eName.toLowerCase()}s
82
+ Content(`### 2. List ${eName.toLowerCase()} records
41
83
 
42
84
  \`\`\`ruby
43
- result, err = client.${eName}(nil).list(nil, nil)
44
- raise err if err
45
-
46
- if result.is_a?(Array)
47
- result.each do |item|
48
- d = item.data_get
49
- puts "#{d["id"]} #{d["name"]}"
85
+ begin
86
+ # list returns an Array of ${eName} records — iterate directly.
87
+ ${eName.toLowerCase()}s = client.${eName}.list
88
+ ${eName.toLowerCase()}s.each do |item|
89
+ puts "${itemPrint}"
50
90
  end
91
+ rescue => err
92
+ warn "list failed: #{err}"
51
93
  end
52
94
  \`\`\`
53
95
 
54
96
  `)
55
97
  }
56
98
 
57
- if (opnames.includes('load')) {
58
- Content(`### 3. Load a ${eName.toLowerCase()}
99
+ if (nestedEntity) {
100
+ const neName = nom(nestedEntity, 'Name')
101
+ const neArticle = /^[aeiou]/i.test(neName) ? "an" : "a"
102
+ const neVar = neName.toLowerCase()
103
+
104
+ // Model-driven match: every REQUIRED load-match key — the same shape
105
+ // the runtime resolves path params from, so the example always works.
106
+ // Parent keys (e.g. page_id) first, the entity's own id last.
107
+ const neIdF = entityIdField(nestedEntity)
108
+ const neRequired = opRequestShape(nestedEntity, 'load').items
109
+ .filter((it: any) => !it.optional)
110
+ .sort((a: any, b: any) =>
111
+ (a.name === neIdF ? 1 : 0) - (b.name === neIdF ? 1 : 0))
112
+ const parentItem = neRequired.find((it: any) => it.name !== neIdF) as any
113
+ const parentParam = parentItem && parentItem.name
114
+ const parentName = parentParam ? parentParam.replace(/_id$/, '') : 'its parent'
115
+ const neMatch = neRequired.map((it: any) =>
116
+ `"${it.name}" => ${rbLit(it.type,
117
+ it.name === neIdF ? 'example_id' : 'example_' + it.name)}`)
118
+
119
+ Content(`### 3. Load ${neArticle} ${neName.toLowerCase()}
120
+
121
+ ${neName} is nested under ${parentName}, so provide the \`${parentParam}\`.
122
+
123
+ \`\`\`ruby
124
+ begin
125
+ # load returns the bare ${neName} record (raises on error).
126
+ ${neVar} = client.${neName}.load({ ${neMatch.join(', ')} })
127
+ puts ${neVar}
128
+ rescue => err
129
+ warn "load failed: #{err}"
130
+ end
131
+ \`\`\`
132
+
133
+ `)
134
+ }
135
+ else if (opnames.includes('load')) {
136
+ // Every REQUIRED load-match key (id first, then parent path params like
137
+ // page_id) — the same shape the runtime resolves path params from, so
138
+ // the example always works.
139
+ const loadRequired = opRequestShape(exampleEntity, 'load').items
140
+ .filter((it: any) => !it.optional || it.name === idF)
141
+ .sort((a: any, b: any) =>
142
+ (a.name === idF ? 0 : 1) - (b.name === idF ? 0 : 1))
143
+ const loadArg = 0 < loadRequired.length
144
+ ? `{ ${loadRequired.map((it: any) =>
145
+ `"${it.name}" => ${rbLit(it.type,
146
+ it.name === idF ? 'example_id' : 'example_' + it.name)}`).join(', ')} }`
147
+ : ''
148
+
149
+ Content(`### 3. Load ${article} ${eName.toLowerCase()}
59
150
 
60
151
  \`\`\`ruby
61
- result, err = client.${eName}(nil).load({ "id" => "example_id" }, nil)
62
- raise err if err
63
- puts result
152
+ begin
153
+ # load returns the bare ${eName} record (raises on error).
154
+ ${eName.toLowerCase()} = client.${eName}.load(${loadArg})
155
+ puts ${eName.toLowerCase()}
156
+ rescue => err
157
+ warn "load failed: #{err}"
158
+ end
64
159
  \`\`\`
65
160
 
66
161
  `)
67
162
  }
68
163
 
164
+ // Model-driven example fields: derive the create/update body from the op
165
+ // shape (opRequestShape) so the docs reference REAL writable fields, not a
166
+ // hardcoded "name" the entity may not have. Literals are Ruby-typed by the
167
+ // field's canonical type. ids are rendered separately as the match key for
168
+ // update/remove; a REQUIRED create id stays (the call is invalid without
169
+ // it).
170
+ const examplePairs = (opname: string): string[] => {
171
+ const items = opRequestShape(exampleEntity, opname).items
172
+ .filter((it: any) => (it.name !== idF && it.name !== 'id') ||
173
+ ('create' === opname && !it.optional))
174
+ const required = items.filter((it: any) => !it.optional)
175
+ const optional = items.filter((it: any) => it.optional)
176
+ // create needs ALL required fields; update is a patch, so the required
177
+ // members plus a sample optional field or two suffice.
178
+ const chosen = 'create' === opname
179
+ ? (required.length ? required : items.slice(0, 2))
180
+ : required.concat(optional).slice(0, Math.max(2, required.length))
181
+ return chosen.map((it: any) => `"${it.name}" => ${rbLit(it.type, 'example_' + it.name)}`)
182
+ }
183
+
184
+ // The id VALUE for an update/remove match: off the returned `created`
185
+ // record only when its data type carries the id AND a create ran, else a
186
+ // type-correct literal (so an update-without-create never references an
187
+ // undefined `created`).
188
+ const idParamType = (opname: string): any => {
189
+ const it = opRequestShape(exampleEntity, opname).items.find((x: any) => x.name === idF)
190
+ return it && it.type
191
+ }
192
+ const idValueFor = (opname: string): string => (null != dataIdF && opnames.includes('create'))
193
+ ? `created["${dataIdF}"]`
194
+ : rbLit(idParamType(opname), 'example_id')
195
+
69
196
  if (opnames.includes('create') || opnames.includes('update') || opnames.includes('remove')) {
70
197
  Content(`### 4. Create, update, and remove
71
198
 
72
199
  \`\`\`ruby
73
200
  `)
74
201
  if (opnames.includes('create')) {
75
- Content(`# Create
76
- created, _ = client.${eName}(nil).create({ "name" => "Example" }, nil)
202
+ Content(`# create returns the bare created ${eName} record.
203
+ created = client.${eName}.create({ ${examplePairs('create').join(', ')} })
77
204
 
78
205
  `)
79
206
  }
80
207
  if (opnames.includes('update')) {
81
- Content(`# Update
82
- client.${eName}(nil).update({ "id" => created["id"], "name" => "Example-Renamed" }, nil)
208
+ const updatePairs = (idF ? [`"${idF}" => ${idValueFor('update')}`] : []).concat(examplePairs('update'))
209
+ const fromCreated = null != dataIdF && opnames.includes('create')
210
+ Content(`# Update${fromCreated ? ` — index the bare record directly (created["${dataIdF}"]).` : ''}
211
+ client.${eName}.update({ ${updatePairs.join(', ')} })
83
212
 
84
213
  `)
85
214
  }
86
215
  if (opnames.includes('remove')) {
216
+ // Every REQUIRED remove-match key: the id (off the created record
217
+ // when possible) plus parent keys like page_id.
218
+ const removePairs = opRequestShape(exampleEntity, 'remove').items
219
+ .filter((it: any) => !it.optional || it.name === idF)
220
+ .sort((a: any, b: any) =>
221
+ (a.name === idF ? 0 : 1) - (b.name === idF ? 0 : 1))
222
+ .map((it: any) => it.name === idF
223
+ ? `"${it.name}" => ${idValueFor('remove')}`
224
+ : `"${it.name}" => ${rbLit(it.type, 'example_' + it.name)}`)
87
225
  Content(`# Remove
88
- client.${eName}(nil).remove({ "id" => created["id"] }, nil)
226
+ client.${eName}.remove(${removePairs.length ? `{ ${removePairs.join(', ')} }` : ''})
89
227
  `)
90
228
  }
91
229
  Content(`\`\`\`
@@ -1,5 +1,5 @@
1
1
 
2
- import { cmp, each, Content, File, isAuthActive } from '@voxgig/sdkgen'
2
+ import { cmp, each, Content, canonToType, canonKey, File, isAuthActive, entityIdField, opRequestShape } from '@voxgig/sdkgen'
3
3
 
4
4
  import {
5
5
  KIT,
@@ -7,31 +7,44 @@ import {
7
7
  } from '@voxgig/apidef'
8
8
 
9
9
 
10
+ // A type-correct Ruby literal for a field's canonical type — the create body
11
+ // is EXECUTED by the doc test, so it must carry a real value per field.
12
+ // Strings render the quoted placeholder.
13
+ function rbLit(type: any, placeholder: string = 'example'): string {
14
+ const k = canonKey(type)
15
+ if ('INTEGER' === k || 'NUMBER' === k) return '1'
16
+ if ('BOOLEAN' === k) return 'true'
17
+ if ('ARRAY' === k) return '[]'
18
+ if ('OBJECT' === k) return '{}'
19
+ return `"${placeholder}"`
20
+ }
21
+
22
+
10
23
  const OP_SIGNATURES: Record<string, { sig: string, returns: string, desc: string }> = {
11
24
  load: {
12
- sig: 'load(reqmatch, ctrl = nil) -> result, err',
13
- returns: 'result, err',
14
- desc: 'Load a single entity matching the given criteria.',
25
+ sig: 'load(reqmatch, ctrl = nil) -> result',
26
+ returns: 'result',
27
+ desc: 'Load a single entity matching the given criteria. Raises on error.',
15
28
  },
16
29
  list: {
17
- sig: 'list(reqmatch, ctrl = nil) -> result, err',
18
- returns: 'result, err',
19
- desc: 'List entities matching the given criteria. Returns an array.',
30
+ sig: 'list(reqmatch = nil, ctrl = nil) -> Array',
31
+ returns: 'Array',
32
+ desc: 'List entities matching the given criteria (call with no argument to list all). Returns an array. Raises on error.',
20
33
  },
21
34
  create: {
22
- sig: 'create(reqdata, ctrl = nil) -> result, err',
23
- returns: 'result, err',
24
- desc: 'Create a new entity with the given data.',
35
+ sig: 'create(reqdata, ctrl = nil) -> result',
36
+ returns: 'result',
37
+ desc: 'Create a new entity with the given data. Raises on error.',
25
38
  },
26
39
  update: {
27
- sig: 'update(reqdata, ctrl = nil) -> result, err',
28
- returns: 'result, err',
29
- desc: 'Update an existing entity. The data must include the entity `id`.',
40
+ sig: 'update(reqdata, ctrl = nil) -> result',
41
+ returns: 'result',
42
+ desc: 'Update an existing entity. The data must include the entity `id`. Raises on error.',
30
43
  },
31
44
  remove: {
32
- sig: 'remove(reqmatch, ctrl = nil) -> result, err',
33
- returns: 'result, err',
34
- desc: 'Remove the entity matching the given criteria.',
45
+ sig: 'remove(reqmatch, ctrl = nil) -> result',
46
+ returns: 'result',
47
+ desc: 'Remove the entity matching the given criteria. Raises on error.',
35
48
  },
36
49
  }
37
50
 
@@ -60,7 +73,7 @@ Complete API reference for the ${model.Name} ${target.title} SDK.
60
73
  `)
61
74
 
62
75
  Content(`\`\`\`ruby
63
- require_relative '${model.name}_sdk'
76
+ require_relative '${model.const.Name}_sdk'
64
77
 
65
78
  client = ${model.const.Name}SDK.new(options)
66
79
  \`\`\`
@@ -72,8 +85,7 @@ Create a new SDK client instance.
72
85
  | Name | Type | Description |
73
86
  | --- | --- | --- |
74
87
  | \`options\` | \`Hash\` | SDK configuration options. |
75
- | \`options["apikey"]\` | \`String\` | API key for authentication. |
76
- | \`options["base"]\` | \`String\` | Base URL for API requests. |
88
+ ${isAuthActive(model) ? '| \`options["apikey"]\` | \`String\` | API key for authentication. |\n' : ''}| \`options["base"]\` | \`String\` | Base URL for API requests. |
77
89
  | \`options["prefix"]\` | \`String\` | URL prefix appended after base. |
78
90
  | \`options["suffix"]\` | \`String\` | URL suffix appended after path. |
79
91
  | \`options["headers"]\` | \`Hash\` | Custom headers for all requests. |
@@ -123,9 +135,11 @@ Return a deep copy of the current SDK options.
123
135
 
124
136
  Return a copy of the SDK utility object.
125
137
 
126
- #### \`direct(fetchargs = {}) -> Hash, err\`
138
+ #### \`direct(fetchargs = {}) -> Hash\`
127
139
 
128
- Make a direct HTTP request to any API endpoint.
140
+ Make a direct HTTP request to any API endpoint. Returns a result hash
141
+ (\`{ "ok" => ..., "status" => ..., "data" => ..., "err" => ... }\`); it
142
+ does not raise — inspect \`result["ok"]\`.
129
143
 
130
144
  **Parameters:**
131
145
 
@@ -139,14 +153,14 @@ Make a direct HTTP request to any API endpoint.
139
153
  | \`fetchargs["body"]\` | \`any\` | Request body (hashes are JSON-serialized). |
140
154
  | \`fetchargs["ctrl"]\` | \`Hash\` | Control options (e.g. \`{ "explain" => true }\`). |
141
155
 
142
- **Returns:** \`Hash, err\`
156
+ **Returns:** \`Hash\`
143
157
 
144
- #### \`prepare(fetchargs = {}) -> Hash, err\`
158
+ #### \`prepare(fetchargs = {}) -> Hash\`
145
159
 
146
160
  Prepare a fetch definition without sending the request. Accepts the
147
- same parameters as \`direct()\`.
161
+ same parameters as \`direct()\`. Raises on error.
148
162
 
149
- **Returns:** \`Hash, err\`
163
+ **Returns:** \`Hash\` (the fetch definition; raises on error)
150
164
 
151
165
  `)
152
166
 
@@ -155,6 +169,9 @@ same parameters as \`direct()\`.
155
169
  publishedEntities.map((ent: any) => {
156
170
  const opnames = Object.keys(ent.op || {})
157
171
  const fields = ent.fields || []
172
+ // Model-driven id key: null when this entity has no id-like field, in
173
+ // which case load/remove match on no argument and update omits the id.
174
+ const idF = entityIdField(ent)
158
175
 
159
176
  Content(`
160
177
  ---
@@ -186,7 +203,7 @@ ${ent.name} = client.${ent.Name}
186
203
  each(fields, (field: any) => {
187
204
  const req = field.req ? 'Yes' : 'No'
188
205
  const desc = field.short || ''
189
- Content(`| \`${field.name}\` | \`${field.type || 'any'}\` | ${req} | ${desc} |
206
+ Content(`| \`${field.name}\` | \`${canonToType(field.type, target.name)}\` | ${req} | ${desc} |
190
207
  `)
191
208
  })
192
209
 
@@ -196,15 +213,18 @@ ${ent.name} = client.${ent.Name}
196
213
  // Field operations breakdown
197
214
  const hasFieldOps = fields.some((f: any) => f.op && Object.keys(f.op).length > 0)
198
215
  if (hasFieldOps) {
216
+ // Only emit columns for operations this entity actually exposes —
217
+ // never advertise a create/update/remove column the entity lacks.
218
+ const opcols = ['load', 'list', 'create', 'update', 'remove']
219
+ .filter((op: string) => opnames.includes(op) && ent.op[op]?.active !== false)
199
220
  Content(`### Field Usage by Operation
200
221
 
201
- | Field | load | list | create | update | remove |
202
- | --- | --- | --- | --- | --- | --- |
222
+ | Field | ${opcols.join(' | ')} |
223
+ | --- | ${opcols.map(() => '---').join(' | ')} |
203
224
  `)
204
225
  each(fields, (field: any) => {
205
226
  const fops = field.op || {}
206
- const cols = ['load', 'list', 'create', 'update', 'remove'].map((op: string) => {
207
- if (!opnames.includes(op)) return '-'
227
+ const cols = opcols.map((op: string) => {
208
228
  const fop = fops[op]
209
229
  if (null == fop) return '-'
210
230
  if (fop.active === false) return '-'
@@ -238,28 +258,45 @@ ${info.desc}
238
258
 
239
259
  // Show example
240
260
  if ('load' === opname || 'remove' === opname) {
261
+ // The id key plus every REQUIRED match key (parent path params
262
+ // like page_id) — the same shape the runtime resolves path
263
+ // params from, so the example always works.
264
+ const matchItems = opRequestShape(ent, opname).items
265
+ .filter((it: any) => !it.optional || it.name === idF)
266
+ .sort((a: any, b: any) =>
267
+ (a.name === idF ? 0 : 1) - (b.name === idF ? 0 : 1))
268
+ const arg = 0 < matchItems.length
269
+ ? `{ ${matchItems.map((it: any) =>
270
+ `"${it.name}" => ${rbLit(it.type,
271
+ it.name === idF ? ent.name + '_id' : it.name)}`).join(', ')} }`
272
+ : ''
241
273
  Content(`\`\`\`ruby
242
- result, err = client.${ent.Name}.${opname}({ "id" => "${ent.name}_id" })
274
+ result = client.${ent.Name}.${opname}(${arg})
243
275
  \`\`\`
244
276
 
245
277
  `)
246
278
  }
247
279
  else if ('list' === opname) {
248
280
  Content(`\`\`\`ruby
249
- results, err = client.${ent.Name}.list(nil)
281
+ results = client.${ent.Name}.list
250
282
  \`\`\`
251
283
 
252
284
  `)
253
285
  }
254
286
  else if ('create' === opname) {
287
+ // Members come from the SAME shape the runtime validates
288
+ // (opRequestShape): every required member must appear — including
289
+ // a required id and parent keys like page_id — with a real,
290
+ // executable literal (the doc test RUNS this block, so a comment
291
+ // placeholder would break it).
292
+ const createItems = opRequestShape(ent, 'create').items
293
+ .filter((it: any) => !it.optional)
255
294
  Content(`\`\`\`ruby
256
- result, err = client.${ent.Name}.create({
295
+ result = client.${ent.Name}.create({
257
296
  `)
258
- each(fields, (field: any) => {
259
- if ('id' !== field.name && field.req) {
260
- Content(` "${field.name}" => # ${field.type || 'value'},
297
+ createItems.map((it: any) => {
298
+ Content(` "${it.name}" => ${rbLit(it.type, 'example_' + it.name)}, # ${canonToType(it.type, target.name)}
261
299
  `)
262
- }
263
300
  })
264
301
  Content(`})
265
302
  \`\`\`
@@ -267,10 +304,18 @@ result, err = client.${ent.Name}.create({
267
304
  `)
268
305
  }
269
306
  else if ('update' === opname) {
307
+ // The id key plus every REQUIRED data member — the same shape the
308
+ // runtime validates — then the patch-fields note.
309
+ const updateItems = opRequestShape(ent, 'update').items
310
+ .filter((it: any) => !it.optional || it.name === idF)
311
+ .sort((a: any, b: any) =>
312
+ (a.name === idF ? 0 : 1) - (b.name === idF ? 0 : 1))
313
+ const updateLines = updateItems.map((it: any) =>
314
+ ` "${it.name}" => ${rbLit(it.type,
315
+ it.name === idF ? ent.name + '_id' : it.name)},\n`).join('')
270
316
  Content(`\`\`\`ruby
271
- result, err = client.${ent.Name}.update({
272
- "id" => "${ent.name}_id",
273
- # Fields to update
317
+ result = client.${ent.Name}.update({
318
+ ${updateLines} # Fields to update
274
319
  })
275
320
  \`\`\`
276
321
 
@@ -7,7 +7,7 @@ const ReadmeTopHowto = cmp(function ReadmeTopHowto(props: any) {
7
7
 
8
8
  Content(`**Ruby:**
9
9
  \`\`\`ruby
10
- result, err = client.direct({
10
+ result = client.direct({
11
11
  "path" => "/api/resource/{id}",
12
12
  "method" => "GET",
13
13
  "params" => { "id" => "example" },
@@ -1,5 +1,5 @@
1
1
 
2
- import { cmp, Content, isAuthActive } from '@voxgig/sdkgen'
2
+ import { cmp, Content, isAuthActive, envName, canonKey, entityIdField, opRequestShape } from '@voxgig/sdkgen'
3
3
 
4
4
  import {
5
5
  KIT,
@@ -8,6 +8,20 @@ import {
8
8
  } from '@voxgig/apidef'
9
9
 
10
10
 
11
+ // A type-correct, executable Ruby literal for a param: numeric/boolean/
12
+ // array/hash params render a typed literal; strings render the quoted
13
+ // placeholder (the doc test EXECUTES this block, so a comment placeholder
14
+ // would break it).
15
+ function rbLit(type: any, placeholder: string = 'example'): string {
16
+ const k = canonKey(type)
17
+ if ('INTEGER' === k || 'NUMBER' === k) return '1'
18
+ if ('BOOLEAN' === k) return 'true'
19
+ if ('ARRAY' === k) return '[]'
20
+ if ('OBJECT' === k) return '{}'
21
+ return `"${placeholder}"`
22
+ }
23
+
24
+
11
25
  const ReadmeTopQuick = cmp(function ReadmeTopQuick(props: any) {
12
26
  const { target, ctx$: { model } } = props
13
27
 
@@ -15,34 +29,54 @@ const ReadmeTopQuick = cmp(function ReadmeTopQuick(props: any) {
15
29
 
16
30
  const exampleEntity = Object.values(entity).find((e: any) => e.active !== false) as any
17
31
 
18
- const apikeyArg = isAuthActive(model)
19
- ? `\n "apikey" => ENV["${model.NAME}_APIKEY"],\n`
20
- : ''
32
+ const authActive = isAuthActive(model)
33
+ const ctor = authActive
34
+ ? `${model.const.Name}SDK.new({\n "apikey" => ENV["${envName(model)}_APIKEY"],\n})`
35
+ : `${model.const.Name}SDK.new`
21
36
 
22
37
  Content(`\`\`\`ruby
23
38
  require_relative "${model.const.Name}_sdk"
24
39
 
25
- client = ${model.const.Name}SDK.new({${apikeyArg}})
40
+ client = ${ctor}
26
41
 
27
42
  `)
28
43
 
29
44
  if (exampleEntity) {
30
45
  const eName = nom(exampleEntity, 'Name')
31
46
  const opnames = Object.keys(exampleEntity.op || {})
47
+ // Model-driven id key: null when the entity has no id-like field, in which
48
+ // case the load example takes no match argument.
49
+ const idF = entityIdField(exampleEntity)
50
+
51
+ let hasCall = false
32
52
 
33
53
  if (opnames.includes('list')) {
34
- Content(`# List all ${eName.toLowerCase()}s
35
- ${eName.toLowerCase()}s, err = client.${eName}(nil).list(nil, nil)
54
+ Content(`# List all ${eName.toLowerCase()}s (returns an Array; raises on error)
55
+ ${eName.toLowerCase()}s = client.${eName}.list
56
+ puts ${eName.toLowerCase()}s
36
57
  `)
58
+ hasCall = true
37
59
  }
38
60
 
39
61
  if (opnames.includes('load')) {
62
+ // Every REQUIRED load-match key (id first, then parent path params like
63
+ // page_id) — the same shape the runtime resolves path params from, so
64
+ // the example always works.
65
+ const loadItems = opRequestShape(exampleEntity, 'load').items
66
+ .filter((it: any) => !it.optional || it.name === idF)
67
+ .sort((a: any, b: any) =>
68
+ (a.name === idF ? 0 : 1) - (b.name === idF ? 0 : 1))
69
+ const loadArg = 0 < loadItems.length
70
+ ? `{ ${loadItems.map((it: any) =>
71
+ `"${it.name}" => ${rbLit(it.type,
72
+ it.name === idF ? 'example_id' : 'example_' + it.name)}`).join(', ')} }`
73
+ : ''
40
74
  Content(`
41
- # Load a specific ${eName.toLowerCase()}
42
- ${eName.toLowerCase()}, err = client.${eName}(nil).load(
43
- { "id" => "example_id" }, nil
44
- )
75
+ # Load a specific ${eName.toLowerCase()} (returns the bare record; raises on error)
76
+ ${eName.toLowerCase()} = client.${eName}.load(${loadArg})
77
+ puts ${eName.toLowerCase()}
45
78
  `)
79
+ hasCall = true
46
80
  }
47
81
  }
48
82
 
@@ -1,5 +1,5 @@
1
1
 
2
- import { cmp, Content } from '@voxgig/sdkgen'
2
+ import { cmp, Content, canonKey, entityIdField, entityPrimaryOp, opRequestShape } from '@voxgig/sdkgen'
3
3
 
4
4
  import {
5
5
  KIT,
@@ -8,6 +8,17 @@ import {
8
8
  } from '@voxgig/apidef'
9
9
 
10
10
 
11
+ // A type-correct Ruby literal for a field's canonical type.
12
+ function rbLit(type: any): string {
13
+ const k = canonKey(type)
14
+ if ('INTEGER' === k || 'NUMBER' === k) return '1'
15
+ if ('BOOLEAN' === k) return 'true'
16
+ if ('ARRAY' === k) return '[]'
17
+ if ('OBJECT' === k) return '{}'
18
+ return '"example"'
19
+ }
20
+
21
+
11
22
  const ReadmeTopTest = cmp(function ReadmeTopTest(props: any) {
12
23
  const { target, ctx$: { model } } = props
13
24
 
@@ -15,20 +26,52 @@ const ReadmeTopTest = cmp(function ReadmeTopTest(props: any) {
15
26
 
16
27
  const exampleEntity = Object.values(entity).find((e: any) => e.active !== false) as any
17
28
 
18
- Content(`\`\`\`ruby
19
- client = ${model.const.Name}SDK.test(nil, nil)
20
- `)
21
-
22
29
  if (exampleEntity) {
23
30
  const eName = nom(exampleEntity, 'Name')
24
- Content(`result, err = client.${eName}(nil).load(
25
- { "id" => "test01" }, nil
26
- )
31
+ const ename = eName.toLowerCase()
32
+ // Model-driven id key: null when the entity has no id-like field, so the
33
+ // seeded record carries no id and a match op takes no argument.
34
+ const idF = entityIdField(exampleEntity)
35
+ // Drive the test-mode example off the entity's PRIMARY op — never a
36
+ // hardcoded `load` a create-only entity lacks.
37
+ const primaryOp = entityPrimaryOp(exampleEntity) || 'load'
38
+ const isMatchOp = 'load' === primaryOp || 'remove' === primaryOp
39
+ const recBody = idF ? `{ "${idF}" => "test01" }` : '{}'
40
+ let callArg = ''
41
+ if (isMatchOp) {
42
+ // Every REQUIRED match key (id first, then parent path params like
43
+ // page_id) — the same shape the runtime resolves path params from.
44
+ const items = opRequestShape(exampleEntity, primaryOp).items
45
+ .filter((it: any) => !it.optional || it.name === idF)
46
+ .sort((a: any, b: any) =>
47
+ (a.name === idF ? 0 : 1) - (b.name === idF ? 0 : 1))
48
+ callArg = 0 < items.length
49
+ ? `{ ${items.map((it: any) =>
50
+ `"${it.name}" => ${it.name === idF ? '"test01"' : rbLit(it.type)}`).join(', ')} }`
51
+ : ''
52
+ } else if ('create' === primaryOp || 'update' === primaryOp) {
53
+ const items = opRequestShape(exampleEntity, primaryOp).items
54
+ .filter((it: any) => it.name !== idF && it.name !== 'id')
55
+ const required = items.filter((it: any) => !it.optional)
56
+ const chosen = required.length ? required : items.slice(0, 3)
57
+ callArg = `{ ${chosen.map((it: any) => `"${it.name}" => ${rbLit(it.type)}`).join(', ')} }`
58
+ }
59
+ // A list result is an Array — name the variable accordingly.
60
+ const eVar = ename + ('list' === primaryOp ? 's' : '')
61
+ Content(`\`\`\`ruby
62
+ # Seed fixture data so offline calls resolve without a live server.
63
+ client = ${model.const.Name}SDK.test({
64
+ "entity" => { "${ename}" => { "test01" => ${recBody} } },
65
+ })
66
+ ${eVar} = client.${eName}.${primaryOp}(${callArg})
67
+ \`\`\`
27
68
  `)
28
- }
29
-
30
- Content(`\`\`\`
69
+ } else {
70
+ Content(`\`\`\`ruby
71
+ client = ${model.const.Name}SDK.test
72
+ \`\`\`
31
73
  `)
74
+ }
32
75
 
33
76
  })
34
77