@voxgig/sdkgen 1.2.1 → 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 +11 -5
  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
@@ -1,5 +1,5 @@
1
1
 
2
- import { cmp, each, Content } from '@voxgig/sdkgen'
2
+ import { cmp, each, Content, canonToType, canonKey, entityIdField } from '@voxgig/sdkgen'
3
3
 
4
4
  import {
5
5
  KIT,
@@ -7,6 +7,18 @@ 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
+ 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
+
10
22
  // Operation method spelling differs between Go and other languages — Go
11
23
  // uses PascalCase methods with explicit ctrl arg, others use lowercase
12
24
  // methods with optional ctrl. The op descriptions are language-agnostic.
@@ -41,6 +53,8 @@ const ReadmeEntity = cmp(function ReadmeEntity(props: any) {
41
53
  publishedEntities.map((entity: any) => {
42
54
  const opnames = Object.keys(entity.op || {})
43
55
  const fields = entity.fields || []
56
+ // Model-driven id key: null when this entity has no id-like field.
57
+ const idF = entityIdField(entity)
44
58
 
45
59
  Content(`
46
60
  ### ${entity.Name}
@@ -53,7 +67,7 @@ const ReadmeEntity = cmp(function ReadmeEntity(props: any) {
53
67
  `)
54
68
  }
55
69
 
56
- Content(`Create an instance: \`const ${entity.name} = client.${entity.Name}()\`
70
+ Content(`Create an instance: \`${entity.name} = client.${entity.Name}\`
57
71
 
58
72
  `)
59
73
 
@@ -84,7 +98,7 @@ const ReadmeEntity = cmp(function ReadmeEntity(props: any) {
84
98
 
85
99
  each(fields, (field: any) => {
86
100
  const desc = field.short || ''
87
- Content(`| \`${field.name}\` | \`${field.type || 'any'}\` | ${desc} |
101
+ Content(`| \`${field.name}\` | \`${canonToType(field.type, target.name)}\` | ${desc} |
88
102
  `)
89
103
  })
90
104
 
@@ -95,8 +109,9 @@ const ReadmeEntity = cmp(function ReadmeEntity(props: any) {
95
109
  if (opnames.includes('load')) {
96
110
  Content(`#### Example: Load
97
111
 
98
- \`\`\`ts
99
- const ${entity.name} = await client.${entity.Name}().load({ id: '${entity.name}_id' })
112
+ \`\`\`ruby
113
+ # load returns the bare ${entity.Name} record (raises on error).
114
+ ${entity.name} = client.${entity.Name}.load(${idF ? `{ "${idF}" => "${entity.name}_id" }` : ''})
100
115
  \`\`\`
101
116
 
102
117
  `)
@@ -105,8 +120,9 @@ const ${entity.name} = await client.${entity.Name}().load({ id: '${entity.name}_
105
120
  if (opnames.includes('list')) {
106
121
  Content(`#### Example: List
107
122
 
108
- \`\`\`ts
109
- const ${entity.name}s = await client.${entity.Name}().list()
123
+ \`\`\`ruby
124
+ # list returns an Array of ${entity.Name} records (raises on error).
125
+ ${entity.name}s = client.${entity.Name}.list
110
126
  \`\`\`
111
127
 
112
128
  `)
@@ -115,12 +131,12 @@ const ${entity.name}s = await client.${entity.Name}().list()
115
131
  if (opnames.includes('create')) {
116
132
  Content(`#### Example: Create
117
133
 
118
- \`\`\`ts
119
- const ${entity.name} = await client.${entity.Name}().create({
134
+ \`\`\`ruby
135
+ ${entity.name} = client.${entity.Name}.create({
120
136
  `)
121
137
  each(fields, (field: any) => {
122
138
  if ('id' !== field.name && field.req) {
123
- Content(` ${field.name}: /* ${field.type || 'value'} */,
139
+ Content(` "${field.name}" => ${rbLit(field.type)}, # ${canonToType(field.type, target.name)}
124
140
  `)
125
141
  }
126
142
  })
@@ -0,0 +1,289 @@
1
+
2
+ import { cmp, File, Content } from '@voxgig/sdkgen'
3
+
4
+ import {
5
+ KIT,
6
+ getModelPath,
7
+ } from '@voxgig/apidef'
8
+
9
+
10
+ // Emits test/readme_examples_test.rb — a Minitest COMPLETENESS GATE that
11
+ // guarantees every fenced ruby code example in the package docs is unit-tested.
12
+ // It reads ALL THREE docs — the root (multi-language) ../../README.md, the
13
+ // Ruby-specific ../README.md, and ../REFERENCE.md — extracts every fenced ruby
14
+ // block (tagged by source doc + index) and enforces four properties:
15
+ //
16
+ // 1. SYNTAX — `ruby -c` on every block. Every documented example must parse.
17
+ // 2. RUN — every RUNNABLE block (one that constructs the SDK, drives
18
+ // client., or performs an entity op) is EXECUTED offline in seeded test
19
+ // mode against the real SDK. The captured stdout+stderr is scanned for
20
+ // FATAL programming-error markers REGARDLESS of exit code, so a bug that a
21
+ // documented begin/rescue swallows and prints is still caught. Only a
22
+ // not-found / domain error is tolerated.
23
+ // 3. COMPLETENESS — every block is partitioned into exactly one of
24
+ // {executed, syntaxchecked-nonrunnable, illustration} and the counts must
25
+ // sum to the total. "illustration" is a NARROW explicit class (a
26
+ // signature / method-table block that names the SDK class or a documented
27
+ // method but never uses a live client) — never a catch-all. A
28
+ // runnable-looking block that was NOT executed lands in neither bucket and
29
+ // FAILS the gate: no runnable example can be silently skipped.
30
+ // 4. A per-doc summary (total / executed / syntaxchecked / illustration) is
31
+ // printed.
32
+ //
33
+ // A runnable block is rewritten so its client is a test-mode client
34
+ // (<Sdk>SDK.test) seeded with an in-memory fixture for every entity it
35
+ // references; any real .new/.test constructor is rewritten and the doc's own
36
+ // require of the SDK file is stripped (we require it by absolute path). A block
37
+ // that only *uses* `client` (constructed in an earlier fenced block) gets a
38
+ // test client prepended.
39
+ //
40
+ // The emitted Ruby builds the ``` fence via 96.chr and shells out via Open3,
41
+ // so this generator string contains no backticks of its own.
42
+ const ReadmeExamplesTest = cmp(function ReadmeExamplesTest(props: any) {
43
+ const { target } = props
44
+ const { model } = props.ctx$
45
+
46
+ const sdkbase = model.const.Name + '_sdk'
47
+ const sdkfile = sdkbase + '.rb'
48
+
49
+ // Entity accessor (client.<Name>) => fixture storage key (lowercase name),
50
+ // derived from the model so fixtures seed under the key the mock expects.
51
+ const entity = getModelPath(model, `main.${KIT}.entity`) || {}
52
+ const entityLines = Object.values(entity)
53
+ .filter((e: any) => e && e.active !== false)
54
+ .map((e: any) => ` ${JSON.stringify(e.Name)} => ${JSON.stringify(e.name)},`)
55
+ .join('\n')
56
+
57
+ File({ name: 'readme_examples_test.' + target.ext }, () => {
58
+ Content(`# ${model.const.Name} SDK — documentation example COMPLETENESS GATE.
59
+ #
60
+ # Guarantees every fenced ruby code example across ALL THREE package docs is
61
+ # unit-tested. Reads the root ../../README.md, the Ruby ../README.md, and
62
+ # ../REFERENCE.md, extracts every fenced ruby block (tagged by source doc +
63
+ # index) and enforces:
64
+ #
65
+ # 1. SYNTAX — 'ruby -c' on every block. Every documented ruby example must
66
+ # parse.
67
+ # 2. RUN — every RUNNABLE block (one that constructs the SDK, drives client.,
68
+ # or performs an entity op load/list/create/update/remove) is EXECUTED
69
+ # offline in seeded test mode (${model.const.Name}SDK.test) against the real
70
+ # SDK. The captured output is scanned for a real Ruby-level error (undefined
71
+ # method, wrong number of arguments, NameError, ...) REGARDLESS of exit
72
+ # code, so a bug a documented begin/rescue swallows and prints cannot slip
73
+ # through. Expected not-found domain errors are tolerated.
74
+ # 3. COMPLETENESS — every block is partitioned into exactly one of
75
+ # {executed, syntaxchecked-nonrunnable, illustration}; the counts must sum
76
+ # to the total. A runnable-looking block that was not executed belongs to
77
+ # no bucket and FAILS the gate.
78
+ #
79
+ # Ruby is dynamically typed, so syntax + actually running every example is the
80
+ # strongest check available without a live server.
81
+
82
+ require "minitest/autorun"
83
+ require "tempfile"
84
+ require "open3"
85
+
86
+ class ReadmeExamplesTest < Minitest::Test
87
+ # The three documentation sources this gate covers.
88
+ DOCS = {
89
+ "root README" => File.join(__dir__, "..", "..", "README.md"),
90
+ "rb README" => File.join(__dir__, "..", "README.md"),
91
+ "rb REFERENCE" => File.join(__dir__, "..", "REFERENCE.md"),
92
+ }
93
+ SDK = File.join(__dir__, "..", "${sdkfile}")
94
+ SDK_CLASS = "${model.const.Name}SDK"
95
+
96
+ # SDK file basename (no extension) — used to strip the doc's own require of the
97
+ # SDK file from a runnable block (we require it by absolute path).
98
+ SDK_BASE = "${sdkbase}"
99
+
100
+ # Entity accessor (client.<Name>) => fixture storage key (lowercase name).
101
+ ENTITIES = {
102
+ ${entityLines}
103
+ }
104
+
105
+ # Documented SDK method names — used only to recognise the NARROW
106
+ # signature/method-table "illustration" class.
107
+ METHODS = %w[options_map get_utility prepare direct data_get data_set match_get match_set make get_name]
108
+
109
+ # Ruby-level errors that indicate a real bug in a documented example (as
110
+ # opposed to an expected not-found / domain error, which is tolerated).
111
+ FATAL = /NoMethodError|NameError|ArgumentError|undefined method|undefined local variable|uninitialized constant|wrong number of arguments/
112
+
113
+ # Extract every fenced ruby block from all three docs, each tagged with its
114
+ # source doc label and its index within that doc.
115
+ def ruby_blocks
116
+ fence = (96.chr) * 3
117
+ blocks = []
118
+ DOCS.each do |label, path|
119
+ assert File.exist?(path), "missing documentation source: #{label}"
120
+ File.read(path).scan(/#{fence}ruby\\r?\\n(.*?)#{fence}/m).each_with_index do |a, i|
121
+ blocks << { doc: label, n: i, code: a[0] }
122
+ end
123
+ end
124
+ blocks
125
+ end
126
+
127
+ # --- classification -------------------------------------------------------
128
+
129
+ # A block is RUNNABLE when it constructs the SDK, drives client., or performs
130
+ # an entity operation. Every runnable block MUST be executed.
131
+ def runnable?(b)
132
+ b =~ /#{Regexp.escape(SDK_CLASS)}\\.(?:new|test)\\b/ ||
133
+ b =~ /\\bclient\\./ ||
134
+ b =~ /\\.(?:load|list|create|update|remove)\\b/ ? true : false
135
+ end
136
+
137
+ # A block "mentions the SDK" when it references the client variable, the SDK
138
+ # class, an entity accessor, or an entity operation. A non-runnable block that
139
+ # mentions the SDK but is not a signature illustration is an uncovered
140
+ # runnable-looking block and must fail the completeness gate.
141
+ def looks_sdk?(b)
142
+ return true if b =~ /\\bclient\\b/
143
+ return true if b =~ /\\b#{Regexp.escape(SDK_CLASS)}\\b/
144
+ return true if b =~ /\\.(?:load|list|create|update|remove)\\b/
145
+ ENTITIES.each_key { |name| return true if b =~ /\\.#{Regexp.escape(name)}\\b/ }
146
+ false
147
+ end
148
+
149
+ # NARROW illustration class: a non-runnable block that references the SDK class
150
+ # or a documented method NAME as a signature / method-table, and never uses a
151
+ # live client variable. This is an explicit, restricted class — not a
152
+ # catch-all — so an unexecuted block that uses a client variable cannot hide here.
153
+ def illustration?(b)
154
+ return false if runnable?(b)
155
+ return false if b =~ /\\bclient\\b/
156
+ return true if b =~ /\\b#{Regexp.escape(SDK_CLASS)}\\b/
157
+ METHODS.each { |m| return true if b =~ /\\b#{Regexp.escape(m)}\\s*\\(/ }
158
+ false
159
+ end
160
+
161
+ # Partition label for a block: exactly one of the four.
162
+ def classify(b)
163
+ return "executed" if runnable?(b)
164
+ return "illustration" if illustration?(b)
165
+ return "syntaxchecked_nonrunnable" unless looks_sdk?(b)
166
+ "unclassified"
167
+ end
168
+
169
+ # --- tests ----------------------------------------------------------------
170
+
171
+ def test_docs_have_ruby_examples
172
+ refute_empty ruby_blocks, "docs should contain ruby examples"
173
+ end
174
+
175
+ # Every ruby block across all three docs must parse (ruby -c).
176
+ def test_ruby_snippets_have_valid_syntax
177
+ failures = []
178
+ ruby_blocks.each do |blk|
179
+ Tempfile.create(["readme_rb_", ".rb"]) do |f|
180
+ f.write(blk[:code])
181
+ f.flush
182
+ out, status = Open3.capture2e("ruby", "-c", f.path)
183
+ failures << "#{blk[:doc]} ##{blk[:n]}:\\n#{out}\\n#{blk[:code]}" unless status.success?
184
+ end
185
+ end
186
+ assert_equal [], failures, "docs ruby blocks with syntax errors:\\n#{failures.join("\\n\\n")}"
187
+ end
188
+
189
+ # Build the SDK 'entity' fixture option (as Ruby source) for the entities a
190
+ # block references, falling back to seeding all entities when none are named.
191
+ def fixtures_literal(block)
192
+ refs = ENTITIES.select { |name, _| block =~ /\\bclient\\.#{Regexp.escape(name)}\\b/ }
193
+ refs = ENTITIES if refs.empty?
194
+ entity = {}
195
+ refs.each_value { |storage| entity[storage] = { "test01" => { "id" => "test01" } } }
196
+ { "entity" => entity }.inspect
197
+ end
198
+
199
+ # Rewrite a runnable block into an executable offline test-mode program: the
200
+ # doc's own require of the SDK file is stripped (we require it by absolute
201
+ # path); any real client constructor (.new/.test) becomes <Sdk>SDK.test(<fixtures>);
202
+ # a block that only uses a client variable gets such a constructor prepended. (The
203
+ # constructor arg-list match is deliberately shallow — it does not span nested
204
+ # parens — because runnable op blocks never build a client inline with a
205
+ # lambda/closure argument.)
206
+ def to_runner(block)
207
+ fixtures = fixtures_literal(block)
208
+ # Drop the doc's own require of the SDK file; we require it by absolute path.
209
+ block = block.gsub(/^[ \\t]*require(?:_relative|_once)?[^\\n]*#{Regexp.escape(SDK_BASE)}[^\\n]*\\r?\\n?/i, "")
210
+ ctor_re = /#{Regexp.escape(SDK_CLASS)}\\.(?:new|test)(?:\\([^()]*\\))?/
211
+ body =
212
+ if block =~ /#{Regexp.escape(SDK_CLASS)}\\.(?:new|test)\\b/
213
+ block.gsub(ctor_re) { "#{SDK_CLASS}.test(#{fixtures})" }
214
+ else
215
+ "client = #{SDK_CLASS}.test(#{fixtures})\\n" + block
216
+ end
217
+ "require_relative #{SDK.inspect}\\n" + body
218
+ end
219
+
220
+ # Every RUNNABLE block is executed offline in test mode and must not raise a
221
+ # real Ruby-level error — even one an error-handling example swallows in a
222
+ # rescue and prints: the captured output is scanned for FATAL either way, so a
223
+ # programming error in a documented begin/rescue cannot slip through. Expected
224
+ # domain errors (e.g. "404: Not found") never match FATAL, so caught not-found
225
+ # cases stay tolerated.
226
+ def test_ruby_examples_run_offline
227
+ ran = 0
228
+ failures = []
229
+ ruby_blocks.each do |blk|
230
+ next unless runnable?(blk[:code])
231
+ ran += 1
232
+ Tempfile.create(["readme_run_", ".rb"]) do |f|
233
+ f.write(to_runner(blk[:code]))
234
+ f.flush
235
+ out, status = Open3.capture2e("ruby", f.path)
236
+ if out =~ FATAL
237
+ failures << "#{blk[:doc]} ##{blk[:n]} (exit #{status.exitstatus}):\\n#{out}\\n#{blk[:code]}"
238
+ end
239
+ end
240
+ end
241
+ assert_operator ran, :>, 0, "expected at least one runnable example to execute"
242
+ assert_equal [], failures, "docs ruby examples raised a real error when run offline:\\n#{failures.join("\\n\\n")}"
243
+ end
244
+
245
+ # COMPLETENESS GATE: every fenced ruby block is partitioned into exactly one of
246
+ # {executed, syntaxchecked-nonrunnable, illustration}. The three counts must
247
+ # sum to the total. A block that references the SDK but is neither runnable (so
248
+ # not executed) nor a narrow signature illustration is "unclassified" — a
249
+ # runnable-looking example that would be silently skipped — and fails the gate.
250
+ def test_ruby_examples_are_completely_classified
251
+ blocks = ruby_blocks
252
+ buckets = { "executed" => [], "syntaxchecked_nonrunnable" => [], "illustration" => [], "unclassified" => [] }
253
+ per_doc = {}
254
+ blocks.each do |blk|
255
+ cls = classify(blk[:code])
256
+ buckets[cls] << blk
257
+ d = (per_doc[blk[:doc]] ||= { "total" => 0, "executed" => 0, "syntaxchecked_nonrunnable" => 0, "illustration" => 0, "unclassified" => 0 })
258
+ d["total"] += 1
259
+ d[cls] += 1
260
+ end
261
+
262
+ summary = "ReadmeExamplesTest — ruby example coverage:\\n"
263
+ per_doc.each do |doc, c|
264
+ extra = c["unclassified"] > 0 ? " UNCLASSIFIED=#{c["unclassified"]}" : ""
265
+ summary += format(" %-14s total=%d executed=%d syntaxchecked=%d illustration=%d%s\\n",
266
+ doc, c["total"], c["executed"], c["syntaxchecked_nonrunnable"], c["illustration"], extra)
267
+ end
268
+ warn "\\n" + summary
269
+
270
+ unclassified = buckets["unclassified"].map { |b| "#{b[:doc]} ##{b[:n]}:\\n#{b[:code]}" }
271
+ assert_equal [], unclassified,
272
+ "runnable-looking ruby blocks that were neither executed nor a signature illustration:\\n#{unclassified.join("\\n\\n")}"
273
+
274
+ total = blocks.length
275
+ sum = buckets["executed"].length + buckets["syntaxchecked_nonrunnable"].length + buckets["illustration"].length
276
+ assert_equal total, sum,
277
+ "every ruby block must be executed, syntaxchecked-nonrunnable, or illustration.\\n#{summary}"
278
+
279
+ assert_operator buckets["executed"].length, :>, 0, "expected at least one executed ruby example"
280
+ end
281
+ end
282
+ `)
283
+ })
284
+ })
285
+
286
+
287
+ export {
288
+ ReadmeExamplesTest
289
+ }
@@ -1,12 +1,59 @@
1
1
 
2
- import { cmp, Content, isAuthActive } from '@voxgig/sdkgen'
2
+ import { cmp, Content, isAuthActive, envName, canonKey, entityIdField, entityPrimaryOp, opRequestShape } from '@voxgig/sdkgen'
3
+
4
+ import {
5
+ KIT,
6
+ getModelPath,
7
+ nom,
8
+ } from '@voxgig/apidef'
9
+
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
+ }
3
20
 
4
21
 
5
22
  const ReadmeHowto = cmp(function ReadmeHowto(props: any) {
6
23
  const { target, ctx$: { model } } = props
7
24
 
25
+ const entity = getModelPath(model, `main.${KIT}.entity`)
26
+ const exampleEntity = Object.values(entity || {}).find((e: any) => e && e.active !== false) as any
27
+ const eName = exampleEntity ? nom(exampleEntity, 'Name') : 'Entity'
28
+ // Model-driven id key: null when the entity has no id-like field (a
29
+ // response-wrapped spec). When null the fixture seeds no id and a match op
30
+ // takes no argument.
31
+ const idF = exampleEntity ? entityIdField(exampleEntity) : null
32
+ // Drive the test-mode example off the entity's PRIMARY op — an op it actually
33
+ // exposes — never a hardcoded `load` a create-only entity lacks.
34
+ const primaryOp = exampleEntity ? (entityPrimaryOp(exampleEntity) || 'load') : 'load'
35
+ const isMatchOp = 'load' === primaryOp || 'remove' === primaryOp
36
+ const seedSentence = idF
37
+ ? '. Seed fixture\ndata via the `entity` option so offline calls resolve without a live server'
38
+ : ''
39
+ const testCtor = idF
40
+ ? `${model.const.Name}SDK.test({\n "entity" => { "${eName.toLowerCase()}" => { "test01" => { "${idF}" => "test01" } } },\n})`
41
+ : `${model.const.Name}SDK.test`
42
+ // A type-correct argument for the primary-op call: a match hash for load/
43
+ // remove, a required-field body for create/update, nothing for list.
44
+ let testCallArg = ''
45
+ if (exampleEntity && isMatchOp) {
46
+ testCallArg = idF ? `{ "${idF}" => "test01" }` : ''
47
+ } else if (exampleEntity && ('create' === primaryOp || 'update' === primaryOp)) {
48
+ const items = opRequestShape(exampleEntity, primaryOp).items
49
+ .filter((it: any) => it.name !== idF && it.name !== 'id')
50
+ const required = items.filter((it: any) => !it.optional)
51
+ const chosen = required.length ? required : items.slice(0, 3)
52
+ testCallArg = `{ ${chosen.map((it: any) => `"${it.name}" => ${rbLit(it.type)}`).join(', ')} }`
53
+ }
54
+
8
55
  const apikeyEnvLine = isAuthActive(model)
9
- ? `\n${model.NAME}_APIKEY=<your-key>`
56
+ ? `\n${envName(model)}_APIKEY=<your-key>`
10
57
  : ''
11
58
 
12
59
  Content(`### Make a direct HTTP request
@@ -14,45 +61,49 @@ const ReadmeHowto = cmp(function ReadmeHowto(props: any) {
14
61
  For endpoints not covered by entity methods:
15
62
 
16
63
  \`\`\`ruby
17
- result, err = client.direct({
64
+ result = client.direct({
18
65
  "path" => "/api/resource/{id}",
19
66
  "method" => "GET",
20
67
  "params" => { "id" => "example" },
21
68
  })
22
- raise err if err
23
69
 
24
70
  if result["ok"]
25
71
  puts result["status"] # 200
26
72
  puts result["data"] # response body
73
+ else
74
+ # On an HTTP error status there is no err (only a transport failure sets
75
+ # it), so fall back to the status code.
76
+ warn(result["err"] || "HTTP #{result["status"]}")
27
77
  end
28
78
  \`\`\`
29
79
 
30
80
  ### Prepare a request without sending it
31
81
 
32
82
  \`\`\`ruby
33
- fetchdef, err = client.prepare({
34
- "path" => "/api/resource/{id}",
35
- "method" => "DELETE",
36
- "params" => { "id" => "example" },
37
- })
38
- raise err if err
39
-
40
- puts fetchdef["url"]
41
- puts fetchdef["method"]
42
- puts fetchdef["headers"]
83
+ begin
84
+ fetchdef = client.prepare({
85
+ "path" => "/api/resource/{id}",
86
+ "method" => "DELETE",
87
+ "params" => { "id" => "example" },
88
+ })
89
+ puts fetchdef["url"]
90
+ puts fetchdef["method"]
91
+ puts fetchdef["headers"]
92
+ rescue => err
93
+ warn "prepare failed: #{err}"
94
+ end
43
95
  \`\`\`
44
96
 
45
97
  ### Use test mode
46
98
 
47
- Create a mock client for unit testing — no server required:
99
+ Create a mock client for unit testing — no server required${seedSentence}:
48
100
 
49
101
  \`\`\`ruby
50
- client = ${model.const.Name}SDK.test(nil, nil)
102
+ client = ${testCtor}
51
103
 
52
- result, err = client.${model.const.Name}(nil).load(
53
- { "id" => "test01" }, nil
54
- )
55
- # result contains mock response data
104
+ # Entity ops return the bare mock record (raises on error).
105
+ ${eName.toLowerCase()} = client.${eName}.${primaryOp}(${testCallArg})
106
+ puts ${eName.toLowerCase()}
56
107
  \`\`\`
57
108
 
58
109
  ### Use a custom fetch function
@@ -82,7 +133,7 @@ client = ${model.const.Name}SDK.new({
82
133
  Create a \`.env.local\` file at the project root:
83
134
 
84
135
  \`\`\`
85
- ${model.NAME}_TEST_LIVE=TRUE${apikeyEnvLine}
136
+ ${envName(model)}_TEST_LIVE=TRUE${apikeyEnvLine}
86
137
  \`\`\`
87
138
 
88
139
  Then run:
@@ -1,19 +1,20 @@
1
1
 
2
- import { cmp, Content } from '@voxgig/sdkgen'
2
+ import { cmp, Content, installCommand, isPublished, packageName, repoInfo } from '@voxgig/sdkgen'
3
3
 
4
4
 
5
5
  const ReadmeInstall = cmp(function ReadmeInstall(props: any) {
6
6
  const { target, ctx$ } = props
7
7
  const { model } = ctx$
8
8
 
9
- Content(`\`\`\`bash
10
- gem install ${model.name}-sdk
9
+ if (isPublished(model, target.name)) {
10
+ Content(`\`\`\`bash
11
+ ${installCommand(model, target.name)}
11
12
  \`\`\`
12
13
 
13
14
  Or add to your \`Gemfile\`:
14
15
 
15
16
  \`\`\`ruby
16
- gem "${model.name}-sdk"
17
+ gem "${packageName(model, 'gem')}"
17
18
  \`\`\`
18
19
 
19
20
  Then run:
@@ -22,6 +23,17 @@ Then run:
22
23
  bundle install
23
24
  \`\`\`
24
25
 
26
+ `)
27
+ return
28
+ }
29
+
30
+ // Publish pending: not yet on RubyGems. Install from the git release tag.
31
+ const { releasesUrl } = repoInfo(model)
32
+ Content(`This package is not yet published to RubyGems. Install it from the
33
+ GitHub release tag (\`${target.name}/vX.Y.Z\`):
34
+
35
+ - Releases: [${releasesUrl}](${releasesUrl})
36
+
25
37
  `)
26
38
  })
27
39
 
@@ -1,13 +1,52 @@
1
1
 
2
2
  import { cmp, Content } from '@voxgig/sdkgen'
3
3
 
4
+ import {
5
+ KIT,
6
+ getModelPath,
7
+ nom,
8
+ } from '@voxgig/apidef'
9
+
4
10
 
5
11
  const ReadmeIntro = cmp(function ReadmeIntro(props: any) {
6
12
  const { target, ctx$: { model } } = props
13
+ const info = (model.main && model.main.kit && model.main.kit.info) || {}
14
+ const tagline = info.tagline || ''
15
+
16
+ // Derive a representative entity (and its operations) from the model so the
17
+ // semantic-entity pitch names something real rather than a placeholder.
18
+ const entity = getModelPath(model, `main.${KIT}.entity`) || {}
19
+ const exampleEntity = Object.values(entity).find((e: any) => e && e.active !== false) as any
20
+ const eName = exampleEntity ? nom(exampleEntity, 'Name') : null
21
+ // Model-driven op list — union of the operations the active entities
22
+ // actually expose (a read-only entity has just list+load), in canonical
23
+ // order; never claim create/update/remove exist when no entity has them.
24
+ const CANON_OPS = ['list', 'load', 'create', 'update', 'remove']
25
+ const opSet = new Set<string>()
26
+ Object.values(entity || {}).forEach((e: any) => {
27
+ if (!e || e.active === false) return
28
+ Object.keys(e.op || {}).forEach((o: string) => {
29
+ if (e.op[o] && e.op[o].active !== false) opSet.add(o)
30
+ })
31
+ })
32
+ const opnames = CANON_OPS.filter((o) => opSet.has(o))
33
+ .concat([...opSet].filter((o) => !CANON_OPS.includes(o)))
34
+ const opList = (opnames.length > 0 ? opnames : ['list', 'load']).join('`/`')
35
+
36
+ const semantic = eName
37
+ ? `The SDK exposes the API as capitalised, semantic **Entities** — for example \`client.${eName}\` — with named operations (\`${opList}\`) instead of raw URL paths and query strings. Working with resources and verbs keeps call sites self-describing and reduces cognitive load.
38
+
39
+ `
40
+ : ''
7
41
 
8
42
  Content(`# ${model.Name} ${target.title} SDK
9
43
 
10
- The ${target.title} SDK for the ${model.Name} API. Provides an entity-oriented interface using idiomatic Ruby conventions.
44
+ ${tagline}
45
+
46
+ The ${target.title} SDK for the ${model.Name} API — an entity-oriented client using idiomatic Ruby conventions.
47
+
48
+ ${semantic}> Other languages, the CLI, and MCP server live alongside this one — see
49
+ > the [top-level README](../README.md).
11
50
 
12
51
  `)
13
52
  })