@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,57 +14,181 @@ 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 = os.getenv("${model.NAME}_APIKEY"),\n`
23
- : ''
29
+ const ctor = isAuthActive(model)
30
+ ? `sdk.new({\n apikey = os.getenv("${envName(model)}_APIKEY"),\n})`
31
+ : `sdk.new()`
24
32
 
25
33
  Content(`### 1. Create a client
26
34
 
27
35
  \`\`\`lua
28
36
  local sdk = require("${model.name}_sdk")
29
37
 
30
- local client = sdk.new({${apikeyArg}})
38
+ local 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 key: `idF` is the MATCH key (null when none). `dataIdF`
48
+ // is the id on the RETURNED record's data type — an entity can key its match
49
+ // on an id it does not carry as data, so a record id read (`item["id"]`,
50
+ // `created["id"]`) must be guarded on this, not the match key.
51
+ const idF = entityIdField(exampleEntity)
52
+ const dataIdF = entityDataIdField(exampleEntity)
53
+
54
+ // A type-correct, executable Lua literal for a param: numeric/boolean/
55
+ // table params render a typed literal; strings render the quoted
56
+ // placeholder (the doc test EXECUTES these blocks, so a comment
57
+ // placeholder would not parse). Non-identifier keys use bracket syntax.
58
+ const luaLit = (type: any, placeholder: string = 'example'): string => {
59
+ const k = canonKey(type)
60
+ if ('INTEGER' === k || 'NUMBER' === k) return '1'
61
+ if ('BOOLEAN' === k) return 'true'
62
+ if ('ARRAY' === k || 'OBJECT' === k) return '{}'
63
+ return `"${placeholder}"`
64
+ }
65
+ const luaKey = (name: string): string =>
66
+ /^[A-Za-z_]\w*$/.test(name) ? name : `["${name}"]`
67
+
68
+ // MODEL-DRIVEN display field: the list example must reference a field
69
+ // the entity actually has, not a hardcoded "name". Pick the entity's
70
+ // first non-id string field (falling back to the first non-id field of
71
+ // any type). The id key stays `id` — the SDK renames every id param to
72
+ // `id`, matching the load example and the seeded test fixture.
73
+ const idNames = new Set<string>(['id',
74
+ (exampleEntity.id && exampleEntity.id.field) || 'id'])
75
+ const fields: any[] = Array.isArray(exampleEntity.fields) ? exampleEntity.fields : []
76
+ const isStringField = (f: any) =>
77
+ f && typeof f.type === 'string' && /STRING/i.test(f.type)
78
+ const displayFieldObj =
79
+ fields.find((f: any) => f && !idNames.has(f.name) && isStringField(f)) ||
80
+ fields.find((f: any) => f && !idNames.has(f.name))
81
+ const displayField = displayFieldObj ? displayFieldObj.name : null
82
+ const idCol = dataIdF ? `item["${dataIdF}"]` : null
83
+ const dispCol = displayField ? `item["${displayField}"]` : null
84
+ const printCols = [idCol, dispCol].filter(Boolean).join(', ')
85
+ const printLine = printCols ? ` print(${printCols})` : ` print(item)`
38
86
 
39
87
  if (opnames.includes('list')) {
40
- Content(`### 2. List ${eName.toLowerCase()}s
88
+ Content(`### 2. List ${eName.toLowerCase()} records
89
+
90
+ Entity operations return \`(value, err)\`. For \`list\`, \`value\` is the
91
+ array of records itself — iterate it directly (there is no wrapper).
41
92
 
42
93
  \`\`\`lua
43
- local result, err = client:${eName}(nil):list(nil, nil)
94
+ local ${eName.toLowerCase()}s, err = client:${eName}():list()
44
95
  if err then error(err) end
45
96
 
46
- if type(result) == "table" then
47
- for _, item in ipairs(result) do
48
- local d = item:data_get()
49
- print(d["id"], d["name"])
50
- end
97
+ for _, item in ipairs(${eName.toLowerCase()}s) do
98
+ ${printLine}
51
99
  end
52
100
  \`\`\`
53
101
 
54
102
  `)
55
103
  }
56
104
 
57
- if (opnames.includes('load')) {
58
- Content(`### 3. Load a ${eName.toLowerCase()}
105
+ if (nestedEntity) {
106
+ const neName = nom(nestedEntity, 'Name')
107
+ const neArticle = /^[aeiou]/i.test(neName) ? "an" : "a"
108
+ const neVar = neName.toLowerCase()
109
+
110
+ // Model-driven match: every REQUIRED load-match key — the same shape
111
+ // the runtime resolves path params from, so the example always works.
112
+ // Parent keys (e.g. page_id) first, the entity's own id last.
113
+ const neIdF = entityIdField(nestedEntity)
114
+ const neRequired = opRequestShape(nestedEntity, 'load').items
115
+ .filter((it: any) => !it.optional)
116
+ .sort((a: any, b: any) =>
117
+ (a.name === neIdF ? 1 : 0) - (b.name === neIdF ? 1 : 0))
118
+ const parentItem = neRequired.find((it: any) => it.name !== neIdF) as any
119
+ const parentParam = parentItem && parentItem.name
120
+ const parentName = parentParam ? parentParam.replace(/_id$/, '') : 'its parent'
121
+ const neMatch = neRequired.map((it: any) =>
122
+ `${luaKey(it.name)} = ${luaLit(it.type,
123
+ it.name === neIdF ? 'example_id' : 'example_' + it.name)}`)
124
+
125
+ Content(`### 3. Load ${neArticle} ${neName.toLowerCase()}
126
+
127
+ ${neName} is nested under ${parentName}, so provide the \`${parentParam}\`.
59
128
 
60
129
  \`\`\`lua
61
- local result, err = client:${eName}(nil):load({ id = "example_id" }, nil)
130
+ local ${neVar}, err = client:${neName}():load({ ${neMatch.join(', ')} })
62
131
  if err then error(err) end
63
- print(result)
132
+ print(${neVar})
64
133
  \`\`\`
65
134
 
66
135
  `)
67
136
  }
137
+ else if (opnames.includes('load')) {
138
+ // Every REQUIRED load-match key (id first, then parent path params like
139
+ // page_id) — the same shape the runtime resolves path params from, so
140
+ // the example always works.
141
+ const loadRequired = opRequestShape(exampleEntity, 'load').items
142
+ .filter((it: any) => !it.optional || it.name === idF)
143
+ .sort((a: any, b: any) =>
144
+ (a.name === idF ? 0 : 1) - (b.name === idF ? 0 : 1))
145
+ const loadArg = 0 < loadRequired.length
146
+ ? `{ ${loadRequired.map((it: any) =>
147
+ `${luaKey(it.name)} = ${luaLit(it.type,
148
+ it.name === idF ? 'example_id' : 'example_' + it.name)}`).join(', ')} }`
149
+ : ''
150
+
151
+ Content(`### 3. Load ${article} ${eName.toLowerCase()}
152
+
153
+ \`\`\`lua
154
+ local ${eName.toLowerCase()}, err = client:${eName}():load(${loadArg})
155
+ if err then error(err) end
156
+ print(${eName.toLowerCase()})
157
+ \`\`\`
158
+
159
+ `)
160
+ }
161
+
162
+ // Model-driven example fields: derive the create/update body from the op
163
+ // shape (opRequestShape) so the docs reference REAL writable fields, not a
164
+ // hardcoded "name" the entity may not have. Literals are Lua-typed by the
165
+ // field's canonical type; non-identifier keys use bracket syntax. ids are
166
+ // rendered separately as the match key for update/remove; a REQUIRED
167
+ // create id stays (the call is invalid without it).
168
+ const examplePairs = (opname: string): string[] => {
169
+ const items = opRequestShape(exampleEntity, opname).items
170
+ .filter((it: any) => !idNames.has(it.name) ||
171
+ ('create' === opname && !it.optional))
172
+ const required = items.filter((it: any) => !it.optional)
173
+ const optional = items.filter((it: any) => it.optional)
174
+ // create needs ALL required fields; update is a patch, so the required
175
+ // members plus a sample optional field or two suffice.
176
+ const chosen = 'create' === opname
177
+ ? (required.length ? required : items.slice(0, 2))
178
+ : required.concat(optional).slice(0, Math.max(2, required.length))
179
+ return chosen.map((it: any) =>
180
+ `${luaKey(it.name)} = ${luaLit(it.type, 'example_' + it.name)}`)
181
+ }
182
+
183
+ // The id VALUE for an update/remove match: off the returned `created` record
184
+ // only when its data type carries the id AND a create ran, else a literal.
185
+ const idParamType = (opname: string): any => {
186
+ const it = opRequestShape(exampleEntity, opname).items.find((x: any) => x.name === idF)
187
+ return it && it.type
188
+ }
189
+ const idValueFor = (opname: string): string => (null != dataIdF && opnames.includes('create'))
190
+ ? `created["${dataIdF}"]`
191
+ : luaLit(idParamType(opname), 'example_id')
68
192
 
69
193
  if (opnames.includes('create') || opnames.includes('update') || opnames.includes('remove')) {
70
194
  Content(`### 4. Create, update, and remove
@@ -73,19 +197,30 @@ print(result)
73
197
  `)
74
198
  if (opnames.includes('create')) {
75
199
  Content(`-- Create
76
- local created, _ = client:${eName}(nil):create({ name = "Example" }, nil)
200
+ local created, err = client:${eName}():create({ ${examplePairs('create').join(', ')} })
201
+ if err then error(err) end
77
202
 
78
203
  `)
79
204
  }
80
205
  if (opnames.includes('update')) {
206
+ const updatePairs = (idF ? [`${idF} = ${idValueFor('update')}`] : []).concat(examplePairs('update'))
81
207
  Content(`-- Update
82
- client:${eName}(nil):update({ id = created["id"], name = "Example-Renamed" }, nil)
208
+ client:${eName}():update({ ${updatePairs.join(', ')} })
83
209
 
84
210
  `)
85
211
  }
86
212
  if (opnames.includes('remove')) {
213
+ // Every REQUIRED remove-match key: the id (off the created record
214
+ // when possible) plus parent keys like page_id.
215
+ const removePairs = opRequestShape(exampleEntity, 'remove').items
216
+ .filter((it: any) => !it.optional || it.name === idF)
217
+ .sort((a: any, b: any) =>
218
+ (a.name === idF ? 0 : 1) - (b.name === idF ? 0 : 1))
219
+ .map((it: any) => it.name === idF
220
+ ? `${luaKey(it.name)} = ${idValueFor('remove')}`
221
+ : `${luaKey(it.name)} = ${luaLit(it.type, 'example_' + it.name)}`)
87
222
  Content(`-- Remove
88
- client:${eName}(nil):remove({ id = created["id"] }, nil)
223
+ client:${eName}():remove(${removePairs.length ? `{ ${removePairs.join(', ')} }` : ''})
89
224
  `)
90
225
  }
91
226
  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,6 +7,24 @@ import {
7
7
  } from '@voxgig/apidef'
8
8
 
9
9
 
10
+ // A type-correct, executable Lua literal for a param: numeric/boolean/table
11
+ // params render a typed literal; strings render the quoted placeholder (the
12
+ // doc test EXECUTES runnable blocks, so a comment placeholder would not
13
+ // parse).
14
+ function luaLit(type: any, placeholder: string = 'example'): string {
15
+ const k = canonKey(type)
16
+ if ('INTEGER' === k || 'NUMBER' === k) return '1'
17
+ if ('BOOLEAN' === k) return 'true'
18
+ if ('ARRAY' === k || 'OBJECT' === k) return '{}'
19
+ return `"${placeholder}"`
20
+ }
21
+
22
+ // Non-identifier table keys use bracket syntax.
23
+ function luaKey(name: string): string {
24
+ return /^[A-Za-z_]\w*$/.test(name) ? name : `["${name}"]`
25
+ }
26
+
27
+
10
28
  const OP_SIGNATURES: Record<string, { sig: string, returns: string, desc: string }> = {
11
29
  load: {
12
30
  sig: 'load(reqmatch, ctrl) -> any, err',
@@ -71,8 +89,7 @@ Create a new SDK client instance.
71
89
  | Name | Type | Description |
72
90
  | --- | --- | --- |
73
91
  | \`options\` | \`table\` | SDK configuration options. |
74
- | \`options.apikey\` | \`string\` | API key for authentication. |
75
- | \`options.base\` | \`string\` | Base URL for API requests. |
92
+ ${isAuthActive(model) ? '| \`options.apikey\` | \`string\` | API key for authentication. |\n' : ''}| \`options.base\` | \`string\` | Base URL for API requests. |
76
93
  | \`options.prefix\` | \`string\` | URL prefix appended after base. |
77
94
  | \`options.suffix\` | \`string\` | URL suffix appended after path. |
78
95
  | \`options.headers\` | \`table\` | Custom headers for all requests. |
@@ -87,12 +104,12 @@ Create a new SDK client instance.
87
104
 
88
105
  `)
89
106
 
90
- Content(`#### \`sdk.test(testopts, sdkopts)\`
107
+ Content(`#### \`sdk.test(testopts?, sdkopts?)\`
91
108
 
92
- Create a test client with mock features active. Both arguments may be \`nil\`.
109
+ Create a test client with mock features active. Both arguments are optional.
93
110
 
94
111
  \`\`\`lua
95
- local client = sdk.test(nil, nil)
112
+ local client = sdk.test()
96
113
  \`\`\`
97
114
 
98
115
  `)
@@ -154,6 +171,9 @@ same parameters as \`direct()\`.
154
171
  publishedEntities.map((ent: any) => {
155
172
  const opnames = Object.keys(ent.op || {})
156
173
  const fields = ent.fields || []
174
+ // Model-driven id key: null when this entity has no id-like field, in
175
+ // which case load/remove match on no argument and update omits the id.
176
+ const idF = entityIdField(ent)
157
177
 
158
178
  Content(`
159
179
  ---
@@ -185,7 +205,7 @@ local ${ent.name} = client:${ent.Name}(nil)
185
205
  each(fields, (field: any) => {
186
206
  const req = field.req ? 'Yes' : 'No'
187
207
  const desc = field.short || ''
188
- Content(`| \`${field.name}\` | \`${field.type || 'any'}\` | ${req} | ${desc} |
208
+ Content(`| \`${field.name}\` | \`${canonToType(field.type, target.name)}\` | ${req} | ${desc} |
189
209
  `)
190
210
  })
191
211
 
@@ -195,15 +215,18 @@ local ${ent.name} = client:${ent.Name}(nil)
195
215
  // Field operations breakdown
196
216
  const hasFieldOps = fields.some((f: any) => f.op && Object.keys(f.op).length > 0)
197
217
  if (hasFieldOps) {
218
+ // Only emit columns for operations this entity actually exposes —
219
+ // never advertise a create/update/remove column the entity lacks.
220
+ const opcols = ['load', 'list', 'create', 'update', 'remove']
221
+ .filter((op: string) => opnames.includes(op) && ent.op[op]?.active !== false)
198
222
  Content(`### Field Usage by Operation
199
223
 
200
- | Field | load | list | create | update | remove |
201
- | --- | --- | --- | --- | --- | --- |
224
+ | Field | ${opcols.join(' | ')} |
225
+ | --- | ${opcols.map(() => '---').join(' | ')} |
202
226
  `)
203
227
  each(fields, (field: any) => {
204
228
  const fops = field.op || {}
205
- const cols = ['load', 'list', 'create', 'update', 'remove'].map((op: string) => {
206
- if (!opnames.includes(op)) return '-'
229
+ const cols = opcols.map((op: string) => {
207
230
  const fop = fops[op]
208
231
  if (null == fop) return '-'
209
232
  if (fop.active === false) return '-'
@@ -237,40 +260,65 @@ ${info.desc}
237
260
 
238
261
  // Show example
239
262
  if ('load' === opname || 'remove' === opname) {
263
+ // The id key plus every REQUIRED match key (parent path params
264
+ // like page_id) — the same shape the runtime resolves path
265
+ // params from, so the example always works.
266
+ const matchItems = opRequestShape(ent, opname).items
267
+ .filter((it: any) => !it.optional || it.name === idF)
268
+ .sort((a: any, b: any) =>
269
+ (a.name === idF ? 0 : 1) - (b.name === idF ? 0 : 1))
270
+ const arg = 0 < matchItems.length
271
+ ? `{ ${matchItems.map((it: any) =>
272
+ `${luaKey(it.name)} = ${luaLit(it.type,
273
+ it.name === idF ? ent.name + '_id' : it.name)}`).join(', ')} }`
274
+ : ''
240
275
  Content(`\`\`\`lua
241
- local result, err = client:${ent.Name}(nil):${opname}({ id = "${ent.name}_id" }, nil)
276
+ local result, err = client:${ent.Name}():${opname}(${arg})
242
277
  \`\`\`
243
278
 
244
279
  `)
245
280
  }
246
281
  else if ('list' === opname) {
247
282
  Content(`\`\`\`lua
248
- local results, err = client:${ent.Name}(nil):list(nil, nil)
283
+ local results, err = client:${ent.Name}():list()
249
284
  \`\`\`
250
285
 
251
286
  `)
252
287
  }
253
288
  else if ('create' === opname) {
289
+ // Members come from the SAME shape the runtime validates
290
+ // (opRequestShape): every required member must appear — including
291
+ // a required id and parent keys like page_id (the --[[ type ]]
292
+ // placeholders mark the block as an illustration for the doc
293
+ // gate).
294
+ const createItems = opRequestShape(ent, 'create').items
295
+ .filter((it: any) => !it.optional)
254
296
  Content(`\`\`\`lua
255
- local result, err = client:${ent.Name}(nil):create({
297
+ local result, err = client:${ent.Name}():create({
256
298
  `)
257
- each(fields, (field: any) => {
258
- if ('id' !== field.name && field.req) {
259
- Content(` ${field.name} = --[[ ${field.type || 'value'} ]],
299
+ createItems.map((it: any) => {
300
+ Content(` ${luaKey(it.name)} = --[[ ${canonToType(it.type, target.name)} ]],
260
301
  `)
261
- }
262
302
  })
263
- Content(`}, nil)
303
+ Content(`})
264
304
  \`\`\`
265
305
 
266
306
  `)
267
307
  }
268
308
  else if ('update' === opname) {
309
+ // The id key plus every REQUIRED data member — the same shape the
310
+ // runtime validates — then the patch-fields note.
311
+ const updateItems = opRequestShape(ent, 'update').items
312
+ .filter((it: any) => !it.optional || it.name === idF)
313
+ .sort((a: any, b: any) =>
314
+ (a.name === idF ? 0 : 1) - (b.name === idF ? 0 : 1))
315
+ const updateLines = updateItems.map((it: any) =>
316
+ ` ${luaKey(it.name)} = ${luaLit(it.type,
317
+ it.name === idF ? ent.name + '_id' : it.name)},\n`).join('')
269
318
  Content(`\`\`\`lua
270
- local result, err = client:${ent.Name}(nil):update({
271
- id = "${ent.name}_id",
272
- -- Fields to update
273
- }, nil)
319
+ local result, err = client:${ent.Name}():update({
320
+ ${updateLines} -- Fields to update
321
+ })
274
322
  \`\`\`
275
323
 
276
324
  `)
@@ -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,23 @@ import {
8
8
  } from '@voxgig/apidef'
9
9
 
10
10
 
11
+ // A type-correct, executable Lua literal for a param: numeric/boolean/table
12
+ // params render a typed literal; strings render the quoted placeholder (the
13
+ // doc test EXECUTES this block, so a comment placeholder would break it).
14
+ function luaLit(type: any, placeholder: string = 'example'): string {
15
+ const k = canonKey(type)
16
+ if ('INTEGER' === k || 'NUMBER' === k) return '1'
17
+ if ('BOOLEAN' === k) return 'true'
18
+ if ('ARRAY' === k || 'OBJECT' === k) return '{}'
19
+ return `"${placeholder}"`
20
+ }
21
+
22
+ // Non-identifier table keys use bracket syntax.
23
+ function luaKey(name: string): string {
24
+ return /^[A-Za-z_]\w*$/.test(name) ? name : `["${name}"]`
25
+ }
26
+
27
+
11
28
  const ReadmeTopQuick = cmp(function ReadmeTopQuick(props: any) {
12
29
  const { target, ctx$: { model } } = props
13
30
 
@@ -15,34 +32,54 @@ const ReadmeTopQuick = cmp(function ReadmeTopQuick(props: any) {
15
32
 
16
33
  const exampleEntity = Object.values(entity).find((e: any) => e.active !== false) as any
17
34
 
18
- const apikeyArg = isAuthActive(model)
19
- ? `\n apikey = os.getenv("${model.NAME}_APIKEY"),\n`
20
- : ''
35
+ const authActive = isAuthActive(model)
36
+ const ctor = authActive
37
+ ? `sdk.new({\n apikey = os.getenv("${envName(model)}_APIKEY"),\n})`
38
+ : `sdk.new()`
21
39
 
22
40
  Content(`\`\`\`lua
23
41
  local sdk = require("${model.name}_sdk")
24
42
 
25
- local client = sdk.new({${apikeyArg}})
43
+ local client = ${ctor}
26
44
 
27
45
  `)
28
46
 
29
47
  if (exampleEntity) {
30
48
  const eName = nom(exampleEntity, 'Name')
31
49
  const opnames = Object.keys(exampleEntity.op || {})
50
+ // Model-driven id key: null when the entity has no id-like field, in which
51
+ // case the load example takes no match argument.
52
+ const idF = entityIdField(exampleEntity)
53
+
54
+ let hasCall = false
32
55
 
33
56
  if (opnames.includes('list')) {
34
57
  Content(`-- List all ${eName.toLowerCase()}s
35
- local ${eName.toLowerCase()}s, err = client:${eName}(nil):list(nil, nil)
58
+ local ${eName.toLowerCase()}s, err = client:${eName}():list()
59
+ print(${eName.toLowerCase()}s)
36
60
  `)
61
+ hasCall = true
37
62
  }
38
63
 
39
64
  if (opnames.includes('load')) {
65
+ // Every REQUIRED load-match key (id first, then parent path params like
66
+ // page_id) — the same shape the runtime resolves path params from, so
67
+ // the example always works.
68
+ const loadItems = opRequestShape(exampleEntity, 'load').items
69
+ .filter((it: any) => !it.optional || it.name === idF)
70
+ .sort((a: any, b: any) =>
71
+ (a.name === idF ? 0 : 1) - (b.name === idF ? 0 : 1))
72
+ const loadArg = 0 < loadItems.length
73
+ ? `{ ${loadItems.map((it: any) =>
74
+ `${luaKey(it.name)} = ${luaLit(it.type,
75
+ it.name === idF ? 'example_id' : 'example_' + it.name)}`).join(', ')} }`
76
+ : ''
40
77
  Content(`
41
78
  -- Load a specific ${eName.toLowerCase()}
42
- local ${eName.toLowerCase()}, err = client:${eName}(nil):load(
43
- { id = "example_id" }, nil
44
- )
79
+ local ${eName.toLowerCase()}, err = client:${eName}():load(${loadArg})
80
+ print(${eName.toLowerCase()})
45
81
  `)
82
+ hasCall = true
46
83
  }
47
84
  }
48
85
 
@@ -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,20 @@ import {
8
8
  } from '@voxgig/apidef'
9
9
 
10
10
 
11
+ // A type-correct Lua literal for a field's canonical type.
12
+ function luaLit(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 || 'OBJECT' === k) return '{}'
17
+ return '"example"'
18
+ }
19
+
20
+ function luaKey(name: string): string {
21
+ return /^[A-Za-z_]\w*$/.test(name) ? name : `["${name}"]`
22
+ }
23
+
24
+
11
25
  const ReadmeTopTest = cmp(function ReadmeTopTest(props: any) {
12
26
  const { target, ctx$: { model } } = props
13
27
 
@@ -16,14 +30,38 @@ const ReadmeTopTest = cmp(function ReadmeTopTest(props: any) {
16
30
  const exampleEntity = Object.values(entity).find((e: any) => e.active !== false) as any
17
31
 
18
32
  Content(`\`\`\`lua
19
- local client = sdk.test(nil, nil)
33
+ local client = sdk.test()
20
34
  `)
21
35
 
22
36
  if (exampleEntity) {
23
37
  const eName = nom(exampleEntity, 'Name')
24
- Content(`local result, err = client:${eName}(nil):load(
25
- { id = "test01" }, nil
26
- )
38
+ // Drive the test-mode example off the entity's PRIMARY op (never a hardcoded
39
+ // `load` a create-only entity lacks).
40
+ const idF = entityIdField(exampleEntity)
41
+ const primaryOp = entityPrimaryOp(exampleEntity) || 'load'
42
+ const isMatchOp = 'load' === primaryOp || 'remove' === primaryOp
43
+ let arg = ''
44
+ if (isMatchOp) {
45
+ // Every REQUIRED match key (id first, then parent path params like
46
+ // page_id) — the same shape the runtime resolves path params from.
47
+ const items = opRequestShape(exampleEntity, primaryOp).items
48
+ .filter((it: any) => !it.optional || it.name === idF)
49
+ .sort((a: any, b: any) =>
50
+ (a.name === idF ? 0 : 1) - (b.name === idF ? 0 : 1))
51
+ arg = 0 < items.length
52
+ ? `{ ${items.map((it: any) =>
53
+ `${luaKey(it.name)} = ${it.name === idF ? '"test01"' : luaLit(it.type)}`).join(', ')} }`
54
+ : ''
55
+ } else if ('create' === primaryOp || 'update' === primaryOp) {
56
+ const items = opRequestShape(exampleEntity, primaryOp).items
57
+ .filter((it: any) => it.name !== idF && it.name !== 'id')
58
+ const required = items.filter((it: any) => !it.optional)
59
+ const chosen = required.length ? required : items.slice(0, 3)
60
+ arg = `{ ${chosen.map((it: any) => `${luaKey(it.name)} = ${luaLit(it.type)}`).join(', ')} }`
61
+ }
62
+ // A list result is an array — name the variable accordingly.
63
+ const rVar = 'list' === primaryOp ? 'results' : 'result'
64
+ Content(`local ${rVar}, err = client:${eName}():${primaryOp}(${arg})
27
65
  `)
28
66
  }
29
67
 
@@ -13,6 +13,7 @@ import { cmp, each, Folder, File, Content } from '@voxgig/sdkgen'
13
13
 
14
14
  import { TestEntity } from './TestEntity_lua'
15
15
  import { TestDirect } from './TestDirect_lua'
16
+ import { ReadmeExamplesTest } from './ReadmeExamplesTest_lua'
16
17
 
17
18
 
18
19
  const Test = cmp(function Test(props: any) {
@@ -40,6 +41,9 @@ end)
40
41
  TestEntity({ target, entity })
41
42
  TestDirect({ target, entity })
42
43
  })
44
+
45
+ // README ```lua example snippets: syntax-check + offline run.
46
+ ReadmeExamplesTest({ target })
43
47
  })
44
48
  })
45
49
 
@@ -5,6 +5,10 @@ local entityCreateOp = {}
5
5
 
6
6
  -- EJECT-START
7
7
 
8
+ ---@param reqdata EntityNameCreateData
9
+ ---@param ctrl? table
10
+ ---@return EntityName
11
+ ---@return string? err
8
12
  function EntityNameEntity:create(reqdata, ctrl)
9
13
  local utility = self._utility
10
14
  local ctx = utility.make_context({
@@ -2,6 +2,10 @@ local entityListOp = {}
2
2
 
3
3
  -- EJECT-START
4
4
 
5
+ ---@param reqmatch EntityNameListMatch
6
+ ---@param ctrl? table
7
+ ---@return EntityName[]
8
+ ---@return string? err
5
9
  function EntityNameEntity:list(reqmatch, ctrl)
6
10
  local utility = self._utility
7
11
  local ctx = utility.make_context({
@@ -5,6 +5,10 @@ local entityLoadOp = {}
5
5
 
6
6
  -- EJECT-START
7
7
 
8
+ ---@param reqmatch EntityNameLoadMatch
9
+ ---@param ctrl? table
10
+ ---@return EntityName
11
+ ---@return string? err
8
12
  function EntityNameEntity:load(reqmatch, ctrl)
9
13
  local utility = self._utility
10
14
  local ctx = utility.make_context({
@@ -5,6 +5,10 @@ local entityRemoveOp = {}
5
5
 
6
6
  -- EJECT-START
7
7
 
8
+ ---@param reqmatch EntityNameRemoveMatch
9
+ ---@param ctrl? table
10
+ ---@return EntityName
11
+ ---@return string? err
8
12
  function EntityNameEntity:remove(reqmatch, ctrl)
9
13
  local utility = self._utility
10
14
  local ctx = utility.make_context({
@@ -5,6 +5,10 @@ local entityUpdateOp = {}
5
5
 
6
6
  -- EJECT-START
7
7
 
8
+ ---@param reqdata EntityNameUpdateData
9
+ ---@param ctrl? table
10
+ ---@return EntityName
11
+ ---@return string? err
8
12
  function EntityNameEntity:update(reqdata, ctrl)
9
13
  local utility = self._utility
10
14
  local ctx = utility.make_context({