@voxgig/sdkgen 2.0.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (394) hide show
  1. package/bin/voxgig-sdkgen +22 -2
  2. package/dist/action/doctor.d.ts +14 -0
  3. package/dist/action/doctor.js +296 -0
  4. package/dist/action/doctor.js.map +1 -0
  5. package/dist/action/feature.js +48 -9
  6. package/dist/action/feature.js.map +1 -1
  7. package/dist/action/target.d.ts +6 -1
  8. package/dist/action/target.js +134 -22
  9. package/dist/action/target.js.map +1 -1
  10. package/dist/cmp/Entity.js +5 -0
  11. package/dist/cmp/Entity.js.map +1 -1
  12. package/dist/cmp/Feature.js +2 -1
  13. package/dist/cmp/Feature.js.map +1 -1
  14. package/dist/cmp/Main.js +5 -1
  15. package/dist/cmp/Main.js.map +1 -1
  16. package/dist/cmp/ReadmeExplanation.js +1 -1
  17. package/dist/cmp/ReadmeExplanation.js.map +1 -1
  18. package/dist/cmp/ReadmeTop.js +16 -6
  19. package/dist/cmp/ReadmeTop.js.map +1 -1
  20. package/dist/cmp/Registered.d.ts +7 -0
  21. package/dist/cmp/Registered.js +70 -0
  22. package/dist/cmp/Registered.js.map +1 -0
  23. package/dist/cmp/Test.js +3 -1
  24. package/dist/cmp/Test.js.map +1 -1
  25. package/dist/helpers/dryrun.d.ts +10 -0
  26. package/dist/helpers/dryrun.js +35 -0
  27. package/dist/helpers/dryrun.js.map +1 -0
  28. package/dist/helpers/featureSource.d.ts +13 -0
  29. package/dist/helpers/featureSource.js +156 -0
  30. package/dist/helpers/featureSource.js.map +1 -0
  31. package/dist/helpers/naming.d.ts +9 -1
  32. package/dist/helpers/naming.js +66 -2
  33. package/dist/helpers/naming.js.map +1 -1
  34. package/dist/helpers/opExample.js +23 -3
  35. package/dist/helpers/opExample.js.map +1 -1
  36. package/dist/helpers/opShape.d.ts +11 -1
  37. package/dist/helpers/opShape.js +51 -0
  38. package/dist/helpers/opShape.js.map +1 -1
  39. package/dist/helpers/packageMeta.d.ts +8 -1
  40. package/dist/helpers/packageMeta.js +141 -10
  41. package/dist/helpers/packageMeta.js.map +1 -1
  42. package/dist/helpers/stdrep.d.ts +3 -0
  43. package/dist/helpers/stdrep.js +47 -0
  44. package/dist/helpers/stdrep.js.map +1 -0
  45. package/dist/helpers/testPolicy.d.ts +2 -0
  46. package/dist/helpers/testPolicy.js +46 -0
  47. package/dist/helpers/testPolicy.js.map +1 -0
  48. package/dist/sdkgen.d.ts +15 -6
  49. package/dist/sdkgen.js +45 -4
  50. package/dist/sdkgen.js.map +1 -1
  51. package/dist/tsconfig.tsbuildinfo +1 -1
  52. package/model/sdkgen.aontu +125 -0
  53. package/package.json +8 -5
  54. package/project/.sdk/model/target/c.aontu +28 -3
  55. package/project/.sdk/model/target/clojure.aontu +24 -3
  56. package/project/.sdk/model/target/cpp.aontu +25 -3
  57. package/project/.sdk/model/target/csharp.aontu +25 -3
  58. package/project/.sdk/model/target/dart.aontu +15 -3
  59. package/project/.sdk/model/target/elixir.aontu +15 -3
  60. package/project/.sdk/model/target/go-cli.aontu +17 -1
  61. package/project/.sdk/model/target/go-mcp.aontu +17 -1
  62. package/project/.sdk/model/target/go.aontu +14 -4
  63. package/project/.sdk/model/target/haskell.aontu +24 -3
  64. package/project/.sdk/model/target/java.aontu +26 -3
  65. package/project/.sdk/model/target/js.aontu +15 -3
  66. package/project/.sdk/model/target/kotlin.aontu +26 -3
  67. package/project/.sdk/model/target/lean.aontu +25 -3
  68. package/project/.sdk/model/target/lua.aontu +15 -3
  69. package/project/.sdk/model/target/ocaml.aontu +24 -3
  70. package/project/.sdk/model/target/perl.aontu +15 -3
  71. package/project/.sdk/model/target/php.aontu +15 -3
  72. package/project/.sdk/model/target/py-data.aontu +16 -3
  73. package/project/.sdk/model/target/py.aontu +15 -3
  74. package/project/.sdk/model/target/rb.aontu +15 -3
  75. package/project/.sdk/model/target/rust.aontu +25 -3
  76. package/project/.sdk/model/target/scala.aontu +25 -3
  77. package/project/.sdk/model/target/swift.aontu +25 -3
  78. package/project/.sdk/model/target/ts.aontu +15 -3
  79. package/project/.sdk/model/target/zig.aontu +26 -3
  80. package/project/.sdk/src/cmp/c/Config_c.ts +10 -11
  81. package/project/.sdk/src/cmp/c/Entity_c.ts +5 -1
  82. package/project/.sdk/src/cmp/c/fragment/Entity.fragment.c +23 -5
  83. package/project/.sdk/src/cmp/c/fragment/EntityCreateOp.fragment.c +9 -2
  84. package/project/.sdk/src/cmp/c/fragment/EntityListOp.fragment.c +19 -2
  85. package/project/.sdk/src/cmp/c/fragment/EntityLoadOp.fragment.c +9 -2
  86. package/project/.sdk/src/cmp/c/fragment/EntityRemoveOp.fragment.c +12 -2
  87. package/project/.sdk/src/cmp/c/fragment/EntityUpdateOp.fragment.c +9 -2
  88. package/project/.sdk/src/cmp/c/fragment/Main.fragment.c +1 -0
  89. package/project/.sdk/src/cmp/clojure/TestEntity_clojure.ts +6 -3
  90. package/project/.sdk/src/cmp/clojure/fragment/Entity.fragment.clj +18 -1
  91. package/project/.sdk/src/cmp/clojure/fragment/EntityCreateOp.fragment.clj +2 -2
  92. package/project/.sdk/src/cmp/clojure/fragment/EntityLoadOp.fragment.clj +2 -2
  93. package/project/.sdk/src/cmp/clojure/fragment/EntityRemoveOp.fragment.clj +12 -8
  94. package/project/.sdk/src/cmp/clojure/fragment/EntityUpdateOp.fragment.clj +2 -2
  95. package/project/.sdk/src/cmp/cpp/Entity_cpp.ts +5 -1
  96. package/project/.sdk/src/cmp/cpp/TestEntity_cpp.ts +24 -11
  97. package/project/.sdk/src/cmp/cpp/fragment/EntityCreateOp.fragment.cpp +8 -2
  98. package/project/.sdk/src/cmp/cpp/fragment/EntityListOp.fragment.cpp +18 -2
  99. package/project/.sdk/src/cmp/cpp/fragment/EntityLoadOp.fragment.cpp +8 -2
  100. package/project/.sdk/src/cmp/cpp/fragment/EntityRemoveOp.fragment.cpp +11 -2
  101. package/project/.sdk/src/cmp/cpp/fragment/EntityUpdateOp.fragment.cpp +8 -2
  102. package/project/.sdk/src/cmp/csharp/Package_csharp.ts +2 -1
  103. package/project/.sdk/src/cmp/csharp/TestDirect_csharp.ts +3 -3
  104. package/project/.sdk/src/cmp/csharp/TestEntity_csharp.ts +6 -6
  105. package/project/.sdk/src/cmp/csharp/fragment/EntityBase.fragment.cs +38 -1
  106. package/project/.sdk/src/cmp/csharp/fragment/Main.fragment.cs +42 -33
  107. package/project/.sdk/src/cmp/dart/Config_dart.ts +6 -0
  108. package/project/.sdk/src/cmp/dart/Package_dart.ts +2 -1
  109. package/project/.sdk/src/cmp/dart/ReadmeEntity_dart.ts +13 -2
  110. package/project/.sdk/src/cmp/dart/ReadmeHowto_dart.ts +2 -1
  111. package/project/.sdk/src/cmp/dart/ReadmeInstall_dart.ts +3 -3
  112. package/project/.sdk/src/cmp/dart/ReadmeModel_dart.ts +1 -1
  113. package/project/.sdk/src/cmp/dart/ReadmeQuick_dart.ts +17 -6
  114. package/project/.sdk/src/cmp/dart/ReadmeRef_dart.ts +13 -2
  115. package/project/.sdk/src/cmp/dart/ReadmeTopQuick_dart.ts +13 -2
  116. package/project/.sdk/src/cmp/dart/TestDirect_dart.ts +3 -3
  117. package/project/.sdk/src/cmp/dart/TestEntity_dart.ts +8 -8
  118. package/project/.sdk/src/cmp/dart/fragment/EntityBase.fragment.dart +18 -1
  119. package/project/.sdk/src/cmp/dart/fragment/EntityCreateOp.fragment.dart +9 -1
  120. package/project/.sdk/src/cmp/dart/fragment/EntityLoadOp.fragment.dart +9 -1
  121. package/project/.sdk/src/cmp/dart/fragment/EntityRemoveOp.fragment.dart +15 -1
  122. package/project/.sdk/src/cmp/dart/fragment/EntityUpdateOp.fragment.dart +9 -1
  123. package/project/.sdk/src/cmp/dart/fragment/SdkError.fragment.dart +8 -0
  124. package/project/.sdk/src/cmp/elixir/Package_elixir.ts +3 -1
  125. package/project/.sdk/src/cmp/elixir/ReadmeInstall_elixir.ts +2 -2
  126. package/project/.sdk/src/cmp/elixir/ReadmeTopQuick_elixir.ts +7 -4
  127. package/project/.sdk/src/cmp/elixir/TestEntity_elixir.ts +11 -2
  128. package/project/.sdk/src/cmp/elixir/fragment/EntityCreateOp.fragment.ex +2 -1
  129. package/project/.sdk/src/cmp/elixir/fragment/EntityListOp.fragment.ex +1 -0
  130. package/project/.sdk/src/cmp/elixir/fragment/EntityLoadOp.fragment.ex +2 -1
  131. package/project/.sdk/src/cmp/elixir/fragment/EntityRemoveOp.fragment.ex +4 -1
  132. package/project/.sdk/src/cmp/elixir/fragment/EntityUpdateOp.fragment.ex +2 -1
  133. package/project/.sdk/src/cmp/go/EntityTypes_go.ts +38 -8
  134. package/project/.sdk/src/cmp/go/Entity_go.ts +2 -2
  135. package/project/.sdk/src/cmp/go/Main_go.ts +4 -5
  136. package/project/.sdk/src/cmp/go/Package_go.ts +8 -5
  137. package/project/.sdk/src/cmp/go/ReadmeExplanation_go.ts +2 -2
  138. package/project/.sdk/src/cmp/go/ReadmeHowto_go.ts +2 -2
  139. package/project/.sdk/src/cmp/go/ReadmeInstall_go.ts +4 -2
  140. package/project/.sdk/src/cmp/go/ReadmeModel_go.ts +2 -2
  141. package/project/.sdk/src/cmp/go/ReadmeQuick_go.ts +2 -2
  142. package/project/.sdk/src/cmp/go/ReadmeTopQuick_go.ts +2 -2
  143. package/project/.sdk/src/cmp/go/ReadmeTopTest_go.ts +2 -2
  144. package/project/.sdk/src/cmp/go/TestDirect_go.ts +21 -15
  145. package/project/.sdk/src/cmp/go/TestEntity_go.ts +9 -9
  146. package/project/.sdk/src/cmp/go/Test_go.ts +2 -2
  147. package/project/.sdk/src/cmp/go/fragment/Entity.fragment.go +42 -1
  148. package/project/.sdk/src/cmp/go-cli/Main_go-cli.ts +4 -4
  149. package/project/.sdk/src/cmp/go-mcp/Main_go-mcp.ts +4 -4
  150. package/project/.sdk/src/cmp/haskell/Package_haskell.ts +2 -1
  151. package/project/.sdk/src/cmp/haskell/ReadmeEntity_haskell.ts +10 -5
  152. package/project/.sdk/src/cmp/haskell/ReadmeModel_haskell.ts +10 -8
  153. package/project/.sdk/src/cmp/haskell/ReadmeQuick_haskell.ts +14 -10
  154. package/project/.sdk/src/cmp/haskell/ReadmeRef_haskell.ts +21 -18
  155. package/project/.sdk/src/cmp/haskell/ReadmeTopQuick_haskell.ts +4 -4
  156. package/project/.sdk/src/cmp/haskell/Test_haskell.ts +23 -11
  157. package/project/.sdk/src/cmp/java/Package_java.ts +2 -1
  158. package/project/.sdk/src/cmp/java/ReadmeHowto_java.ts +2 -1
  159. package/project/.sdk/src/cmp/java/ReadmeInstall_java.ts +2 -2
  160. package/project/.sdk/src/cmp/java/ReadmeModel_java.ts +1 -1
  161. package/project/.sdk/src/cmp/java/ReadmeQuick_java.ts +3 -3
  162. package/project/.sdk/src/cmp/java/TestDirect_java.ts +3 -3
  163. package/project/.sdk/src/cmp/java/TestEntity_java.ts +6 -6
  164. package/project/.sdk/src/cmp/java/fragment/EntityBase.fragment.java +34 -1
  165. package/project/.sdk/src/cmp/java/fragment/SdkError.fragment.java +12 -0
  166. package/project/.sdk/src/cmp/js/Main_js.ts +4 -1
  167. package/project/.sdk/src/cmp/js/Package_js.ts +7 -1
  168. package/project/.sdk/src/cmp/js/ReadmeEntity_js.ts +13 -2
  169. package/project/.sdk/src/cmp/js/ReadmeHowto_js.ts +2 -1
  170. package/project/.sdk/src/cmp/js/ReadmeQuick_js.ts +13 -2
  171. package/project/.sdk/src/cmp/js/ReadmeTopQuick_js.ts +13 -2
  172. package/project/.sdk/src/cmp/js/ReadmeTopTest_js.ts +2 -1
  173. package/project/.sdk/src/cmp/js/TestDirect_js.ts +3 -3
  174. package/project/.sdk/src/cmp/js/TestEntity_js.ts +8 -8
  175. package/project/.sdk/src/cmp/js/fragment/EntityBase.fragment.js +22 -1
  176. package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +9 -1
  177. package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +9 -1
  178. package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +15 -1
  179. package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +9 -1
  180. package/project/.sdk/src/cmp/js/fragment/SdkError.fragment.js +13 -0
  181. package/project/.sdk/src/cmp/kotlin/Package_kotlin.ts +2 -1
  182. package/project/.sdk/src/cmp/kotlin/ReadmeHowto_kotlin.ts +2 -1
  183. package/project/.sdk/src/cmp/kotlin/ReadmeInstall_kotlin.ts +2 -2
  184. package/project/.sdk/src/cmp/kotlin/ReadmeModel_kotlin.ts +1 -1
  185. package/project/.sdk/src/cmp/kotlin/ReadmeQuick_kotlin.ts +3 -3
  186. package/project/.sdk/src/cmp/kotlin/TestDirect_kotlin.ts +3 -3
  187. package/project/.sdk/src/cmp/kotlin/TestEntity_kotlin.ts +6 -6
  188. package/project/.sdk/src/cmp/kotlin/fragment/EntityBase.fragment.kt +32 -1
  189. package/project/.sdk/src/cmp/lean/Package_lean.ts +3 -1
  190. package/project/.sdk/src/cmp/lean/Test_lean.ts +75 -21
  191. package/project/.sdk/src/cmp/lua/MainEntity_lua.ts +9 -4
  192. package/project/.sdk/src/cmp/lua/Package_lua.ts +4 -3
  193. package/project/.sdk/src/cmp/lua/ReadmeModel_lua.ts +11 -3
  194. package/project/.sdk/src/cmp/lua/ReadmeQuick_lua.ts +1 -1
  195. package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +3 -3
  196. package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +9 -9
  197. package/project/.sdk/src/cmp/lua/fragment/Entity.fragment.lua +37 -1
  198. package/project/.sdk/src/cmp/lua/fragment/SdkError.fragment.lua +12 -0
  199. package/project/.sdk/src/cmp/ocaml/EntityOperation_ocaml.ts +30 -3
  200. package/project/.sdk/src/cmp/ocaml/Entity_ocaml.ts +11 -5
  201. package/project/.sdk/src/cmp/ocaml/Package_ocaml.ts +3 -1
  202. package/project/.sdk/src/cmp/ocaml/ReadmeEntity_ocaml.ts +10 -5
  203. package/project/.sdk/src/cmp/ocaml/ReadmeHowto_ocaml.ts +6 -2
  204. package/project/.sdk/src/cmp/ocaml/ReadmeModel_ocaml.ts +10 -8
  205. package/project/.sdk/src/cmp/ocaml/ReadmeQuick_ocaml.ts +14 -13
  206. package/project/.sdk/src/cmp/ocaml/ReadmeRef_ocaml.ts +20 -18
  207. package/project/.sdk/src/cmp/ocaml/ReadmeTopQuick_ocaml.ts +4 -4
  208. package/project/.sdk/src/cmp/ocaml/ReadmeTopTest_ocaml.ts +8 -2
  209. package/project/.sdk/src/cmp/ocaml/TestEntity_ocaml.ts +8 -5
  210. package/project/.sdk/src/cmp/perl/ReadmeHowto_perl.ts +2 -1
  211. package/project/.sdk/src/cmp/perl/ReadmeModel_perl.ts +1 -1
  212. package/project/.sdk/src/cmp/perl/ReadmeQuick_perl.ts +3 -3
  213. package/project/.sdk/src/cmp/perl/ReadmeTopQuick_perl.ts +1 -1
  214. package/project/.sdk/src/cmp/perl/TestDirect_perl.ts +3 -3
  215. package/project/.sdk/src/cmp/perl/TestEntity_perl.ts +6 -6
  216. package/project/.sdk/src/cmp/perl/fragment/Entity.fragment.pm +36 -1
  217. package/project/.sdk/src/cmp/php/MainEntity_php.ts +21 -16
  218. package/project/.sdk/src/cmp/php/Package_php.ts +2 -2
  219. package/project/.sdk/src/cmp/php/ReadmeEntity_php.ts +6 -6
  220. package/project/.sdk/src/cmp/php/ReadmeHowto_php.ts +4 -3
  221. package/project/.sdk/src/cmp/php/ReadmeIntro_php.ts +2 -2
  222. package/project/.sdk/src/cmp/php/ReadmeModel_php.ts +1 -1
  223. package/project/.sdk/src/cmp/php/ReadmeQuick_php.ts +12 -12
  224. package/project/.sdk/src/cmp/php/ReadmeRef_php.ts +6 -6
  225. package/project/.sdk/src/cmp/php/ReadmeTopQuick_php.ts +4 -4
  226. package/project/.sdk/src/cmp/php/ReadmeTopTest_php.ts +2 -2
  227. package/project/.sdk/src/cmp/php/TestDirect_php.ts +3 -3
  228. package/project/.sdk/src/cmp/php/TestEntity_php.ts +17 -15
  229. package/project/.sdk/src/cmp/php/fragment/Entity.fragment.php +20 -1
  230. package/project/.sdk/src/cmp/php/fragment/SdkError.fragment.php +11 -0
  231. package/project/.sdk/src/cmp/py/Package_py.ts +4 -3
  232. package/project/.sdk/src/cmp/py/ReadmeEntity_py.ts +13 -2
  233. package/project/.sdk/src/cmp/py/ReadmeHowto_py.ts +2 -1
  234. package/project/.sdk/src/cmp/py/ReadmeModel_py.ts +1 -1
  235. package/project/.sdk/src/cmp/py/ReadmeQuick_py.ts +17 -6
  236. package/project/.sdk/src/cmp/py/ReadmeRef_py.ts +14 -3
  237. package/project/.sdk/src/cmp/py/ReadmeTopQuick_py.ts +13 -2
  238. package/project/.sdk/src/cmp/py/TestDirect_py.ts +3 -3
  239. package/project/.sdk/src/cmp/py/TestEntity_py.ts +9 -9
  240. package/project/.sdk/src/cmp/py/Test_py.ts +4 -1
  241. package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +29 -1
  242. package/project/.sdk/src/cmp/py/fragment/SdkError.fragment.py +11 -0
  243. package/project/.sdk/src/cmp/py-data/Main_py-data.ts +2 -1
  244. package/project/.sdk/src/cmp/rb/Package_rb.ts +4 -3
  245. package/project/.sdk/src/cmp/rb/ReadmeEntity_rb.ts +1 -1
  246. package/project/.sdk/src/cmp/rb/ReadmeHowto_rb.ts +2 -1
  247. package/project/.sdk/src/cmp/rb/ReadmeQuick_rb.ts +5 -5
  248. package/project/.sdk/src/cmp/rb/ReadmeTopQuick_rb.ts +1 -1
  249. package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +3 -3
  250. package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +9 -9
  251. package/project/.sdk/src/cmp/rb/fragment/Entity.fragment.rb +31 -1
  252. package/project/.sdk/src/cmp/rb/fragment/SdkError.fragment.rb +10 -1
  253. package/project/.sdk/src/cmp/rust/Entity_rust.ts +5 -1
  254. package/project/.sdk/src/cmp/rust/Main_rust.ts +21 -0
  255. package/project/.sdk/src/cmp/rust/Package_rust.ts +2 -1
  256. package/project/.sdk/src/cmp/rust/TestDirect_rust.ts +3 -3
  257. package/project/.sdk/src/cmp/rust/TestEntity_rust.ts +12 -12
  258. package/project/.sdk/src/cmp/rust/fragment/Entity.fragment.rs +18 -0
  259. package/project/.sdk/src/cmp/rust/fragment/EntityCreateOp.fragment.rs +8 -2
  260. package/project/.sdk/src/cmp/rust/fragment/EntityListOp.fragment.rs +20 -3
  261. package/project/.sdk/src/cmp/rust/fragment/EntityLoadOp.fragment.rs +8 -2
  262. package/project/.sdk/src/cmp/rust/fragment/EntityRemoveOp.fragment.rs +10 -2
  263. package/project/.sdk/src/cmp/rust/fragment/EntityUpdateOp.fragment.rs +8 -2
  264. package/project/.sdk/src/cmp/rust/fragment/SdkError.fragment.rs +10 -0
  265. package/project/.sdk/src/cmp/scala/ReadmeHowto_scala.ts +2 -1
  266. package/project/.sdk/src/cmp/scala/ReadmeInstall_scala.ts +3 -3
  267. package/project/.sdk/src/cmp/scala/ReadmeModel_scala.ts +1 -1
  268. package/project/.sdk/src/cmp/scala/ReadmeQuick_scala.ts +3 -3
  269. package/project/.sdk/src/cmp/scala/TestEntity_scala.ts +3 -3
  270. package/project/.sdk/src/cmp/scala/fragment/EntityBase.fragment.scala +27 -1
  271. package/project/.sdk/src/cmp/swift/ReadmeHowto_swift.ts +2 -1
  272. package/project/.sdk/src/cmp/swift/ReadmeInstall_swift.ts +3 -3
  273. package/project/.sdk/src/cmp/swift/ReadmeModel_swift.ts +1 -1
  274. package/project/.sdk/src/cmp/swift/ReadmeQuick_swift.ts +3 -3
  275. package/project/.sdk/src/cmp/swift/fragment/EntityBase.fragment.swift +34 -1
  276. package/project/.sdk/src/cmp/ts/EntityOperation_ts.ts +9 -1
  277. package/project/.sdk/src/cmp/ts/EntityTypes_ts.ts +18 -1
  278. package/project/.sdk/src/cmp/ts/Gitignore_ts.ts +5 -2
  279. package/project/.sdk/src/cmp/ts/Main_ts.ts +4 -1
  280. package/project/.sdk/src/cmp/ts/Package_ts.ts +10 -1
  281. package/project/.sdk/src/cmp/ts/ReadmeEntity_ts.ts +13 -2
  282. package/project/.sdk/src/cmp/ts/ReadmeHowto_ts.ts +2 -1
  283. package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +21 -6
  284. package/project/.sdk/src/cmp/ts/ReadmeRef_ts.ts +52 -2
  285. package/project/.sdk/src/cmp/ts/ReadmeTopQuick_ts.ts +14 -3
  286. package/project/.sdk/src/cmp/ts/ReadmeTopTest_ts.ts +34 -2
  287. package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +64 -43
  288. package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +8 -8
  289. package/project/.sdk/src/cmp/ts/fragment/Direct.test.fragment.ts +2 -2
  290. package/project/.sdk/src/cmp/ts/fragment/Entity.test.fragment.ts +2 -2
  291. package/project/.sdk/src/cmp/ts/fragment/EntityBase.fragment.ts +25 -1
  292. package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.ts +10 -2
  293. package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.ts +1 -1
  294. package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.ts +10 -2
  295. package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.ts +27 -3
  296. package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.ts +10 -2
  297. package/project/.sdk/src/cmp/ts/fragment/SdkError.fragment.ts +15 -0
  298. package/project/.sdk/src/cmp/zig/Entity_zig.ts +5 -1
  299. package/project/.sdk/src/cmp/zig/Package_zig.ts +3 -1
  300. package/project/.sdk/src/cmp/zig/fragment/Entity.fragment.zig +39 -0
  301. package/project/.sdk/src/cmp/zig/fragment/EntityCreateOp.fragment.zig +2 -2
  302. package/project/.sdk/src/cmp/zig/fragment/EntityListOp.fragment.zig +21 -2
  303. package/project/.sdk/src/cmp/zig/fragment/EntityLoadOp.fragment.zig +2 -2
  304. package/project/.sdk/src/cmp/zig/fragment/EntityRemoveOp.fragment.zig +5 -2
  305. package/project/.sdk/src/cmp/zig/fragment/EntityUpdateOp.fragment.zig +2 -2
  306. package/project/.sdk/tm/c/VERSION +1 -1
  307. package/project/.sdk/tm/c/core/helpers.c +1 -0
  308. package/project/.sdk/tm/c/core/sdk.h +22 -6
  309. package/project/.sdk/tm/c/tests/feature_harness.h +1 -0
  310. package/project/.sdk/tm/c/tests/primary_utility_test.c +4 -1
  311. package/project/.sdk/tm/c/utility/graphql.c +1 -1
  312. package/project/.sdk/tm/c/utility/make_url.c +1 -0
  313. package/project/.sdk/tm/c/utility/param.c +1 -0
  314. package/project/.sdk/tm/clojure/VERSION +1 -1
  315. package/project/.sdk/tm/cpp/VERSION +1 -1
  316. package/project/.sdk/tm/cpp/core/types.hpp +33 -8
  317. package/project/.sdk/tm/cpp/test/pipeline_test.cpp +5 -0
  318. package/project/.sdk/tm/cpp/test/runner_support.hpp +4 -4
  319. package/project/.sdk/tm/csharp/VERSION +1 -1
  320. package/project/.sdk/tm/csharp/core/Types.cs +6 -0
  321. package/project/.sdk/tm/csharp/test/FeatureHarness.cs +396 -0
  322. package/project/.sdk/tm/csharp/test/FeatureTest.cs +7 -385
  323. package/project/.sdk/tm/csharp/test/Runner.cs +4 -4
  324. package/project/.sdk/tm/dart/lib/utility/MakeErrorUtility.dart +4 -0
  325. package/project/.sdk/tm/dart/test/utility.dart +4 -4
  326. package/project/.sdk/tm/elixir/VERSION +1 -1
  327. package/project/.sdk/tm/elixir/lib/projectname/entity_base.ex +26 -0
  328. package/project/.sdk/tm/go/VERSION +1 -1
  329. package/project/.sdk/tm/go/core/types.go +6 -0
  330. package/project/.sdk/tm/go/test/feature_harness_test.go +361 -0
  331. package/project/.sdk/tm/go/test/feature_test.go +7 -350
  332. package/project/.sdk/tm/go/test/pipeline_test.go +6 -0
  333. package/project/.sdk/tm/go/test/runner_test.go +16 -4
  334. package/project/.sdk/tm/haskell/VERSION +1 -1
  335. package/project/.sdk/tm/haskell/src/SdkFeatures.hs +28 -5
  336. package/project/.sdk/tm/haskell/src/SdkTypes.hs +14 -5
  337. package/project/.sdk/tm/java/VERSION +1 -1
  338. package/project/.sdk/tm/java/test/RunnerSupport.java +4 -4
  339. package/project/.sdk/tm/java/utility/MakeError.java +4 -0
  340. package/project/.sdk/tm/js/src/utility/MakeErrorUtility.js +4 -0
  341. package/project/.sdk/tm/js/test/utility.js +3 -3
  342. package/project/.sdk/tm/kotlin/VERSION +1 -1
  343. package/project/.sdk/tm/kotlin/core/Utility.kt +2 -0
  344. package/project/.sdk/tm/kotlin/test/RunnerSupport.kt +3 -3
  345. package/project/.sdk/tm/lean/Makefile +25 -0
  346. package/project/.sdk/tm/lean/VERSION +1 -1
  347. package/project/.sdk/tm/lean/src/SdkUtility.lean +11 -9
  348. package/project/.sdk/tm/lean/test/TFeature.lean +27 -14
  349. package/project/.sdk/tm/lean/test/TPrimaryUtility.lean +5 -2
  350. package/project/.sdk/tm/lua/test/runner.lua +4 -4
  351. package/project/.sdk/tm/lua/utility/make_error.lua +4 -0
  352. package/project/.sdk/tm/ocaml/VERSION +1 -1
  353. package/project/.sdk/tm/ocaml/sdk_types.ml +14 -5
  354. package/project/.sdk/tm/ocaml/test/t_pipeline.ml +5 -2
  355. package/project/.sdk/tm/perl/t/runner.pm +4 -4
  356. package/project/.sdk/tm/php/VERSION +1 -1
  357. package/project/.sdk/tm/php/test/Runner.php +4 -4
  358. package/project/.sdk/tm/php/utility/MakeError.php +5 -0
  359. package/project/.sdk/tm/py/pkg/utility/make_error.py +4 -0
  360. package/project/.sdk/tm/py/test/runner.py +19 -4
  361. package/project/.sdk/tm/rb/test/runner.rb +4 -4
  362. package/project/.sdk/tm/rb/utility/make_error.rb +4 -0
  363. package/project/.sdk/tm/rust/VERSION +1 -1
  364. package/project/.sdk/tm/rust/core/types.rs +22 -6
  365. package/project/.sdk/tm/rust/tests/common/mod.rs +6 -6
  366. package/project/.sdk/tm/rust/tests/pipeline_test.rs +6 -0
  367. package/project/.sdk/tm/rust/utility/make_error.rs +4 -0
  368. package/project/.sdk/tm/scala/VERSION +1 -1
  369. package/project/.sdk/tm/swift/VERSION +1 -1
  370. package/project/.sdk/tm/ts/src/tsconfig.json +1 -0
  371. package/project/.sdk/tm/ts/src/utility/MakeErrorUtility.ts +4 -0
  372. package/project/.sdk/tm/ts/test/tsconfig.json +1 -0
  373. package/project/.sdk/tm/ts/test/utility.ts +3 -3
  374. package/project/.sdk/tm/zig/VERSION +1 -1
  375. package/src/action/doctor.ts +410 -0
  376. package/src/action/feature.ts +54 -16
  377. package/src/action/target.ts +174 -25
  378. package/src/cmp/Entity.ts +7 -0
  379. package/src/cmp/Feature.ts +3 -1
  380. package/src/cmp/Main.ts +7 -1
  381. package/src/cmp/ReadmeExplanation.ts +2 -2
  382. package/src/cmp/ReadmeTop.ts +22 -9
  383. package/src/cmp/Registered.ts +100 -0
  384. package/src/cmp/Test.ts +4 -1
  385. package/src/helpers/dryrun.ts +57 -0
  386. package/src/helpers/featureSource.ts +208 -0
  387. package/src/helpers/naming.ts +73 -2
  388. package/src/helpers/opExample.ts +19 -2
  389. package/src/helpers/opShape.ts +65 -0
  390. package/src/helpers/packageMeta.ts +163 -10
  391. package/src/helpers/stdrep.ts +56 -0
  392. package/src/helpers/testPolicy.ts +52 -0
  393. package/src/sdkgen.ts +70 -4
  394. package/project/.sdk/tm/rust/feature/mod.rs +0 -24
@@ -1,5 +1,5 @@
1
1
 
2
- import { cmp, Content, isAuthActive, packageName, envName, entityIdField, entityOps, opRequestShape, safeVarName, exampleVarName, jsKey } from '@voxgig/sdkgen'
2
+ import { cmp, Content, isAuthActive, packageName, envName, entityIdField, entityOps, opRequestShape, safeVarName, exampleVarName, jsKey, matchArg, idLiteral } from '@voxgig/sdkgen'
3
3
 
4
4
  import {
5
5
  KIT,
@@ -10,6 +10,17 @@ import {
10
10
  import { exampleValue } from './utility_js'
11
11
 
12
12
 
13
+ // A `list()` on a NESTED entity needs its parent path params. The
14
+ // quickstart used to emit `client.Moon().list()` for an entity at
15
+ // `/planet/{planet_id}/moon`, which 404s against a live server from a
16
+ // half-built URL — indistinguishable from "no such record". The model
17
+ // already marks those params `reqd: true`; matchArg renders exactly them.
18
+ function listMatchArg(ent: any): string {
19
+ const idF = entityIdField(ent)
20
+ return matchArg('ts', ent, 'list', idF, idLiteral(ent, 'list', idF))
21
+ }
22
+
23
+
13
24
  const ReadmeTopQuick = cmp(function ReadmeTopQuick(props: any) {
14
25
  const { target, ctx$: { model } } = props
15
26
 
@@ -36,7 +47,7 @@ const client = ${ctor}
36
47
 
37
48
  if (opnames.includes('list')) {
38
49
  Content(`// List all ${eName.toLowerCase()}s (returns an array)
39
- const ${eVar}s = await client.${eName}().list()
50
+ const ${eVar}s = await client.${eName}().list(${listMatchArg(exampleEntity)})
40
51
  for (const ${eVar} of ${eVar}s) {
41
52
  console.log(${eVar})
42
53
  }
@@ -51,7 +51,8 @@ const client = ${model.const.Name}SDK.test()
51
51
  `${jsKey(it.name)}: ${exampleValue(exampleEntity, primaryOpDef, it.name, 'example_' + it.name)}`).join(', ')} }`
52
52
  }
53
53
  Content(`const ${eVar} = await client.${eName}().${primaryOp}(${arg})
54
- // ${eVar} is ${'list' === primaryOp ? 'an array of bare entities' : 'a bare entity'} populated with mock data
54
+ // ${eVar} is ${'list' === primaryOp ? 'an array of entities' : 'the entity'}, populated with mock data
55
+ // — call ${eVar}${'list' === primaryOp ? '[0]' : ''}.data() for the record itself
55
56
  console.log(${eVar})
56
57
  `)
57
58
  }
@@ -17,7 +17,7 @@ import {
17
17
  cmp,
18
18
  snakify,
19
19
  isAuthActive,
20
- jsProp,
20
+ jsProp, envName, envToken
21
21
  } from '@voxgig/sdkgen'
22
22
 
23
23
 
@@ -36,8 +36,8 @@ const TestDirect = cmp(function TestDirect(props: any) {
36
36
 
37
37
  const ff = projectPath('src/cmp/js/fragment/')
38
38
 
39
- const PROJECTNAME = nom(model, 'Name').toUpperCase().replace(/[^A-Z_]/g, '_')
40
- const entidEnvVar = `${PROJECTNAME}_TEST_${nom(entity, 'NAME').replace(/[^A-Z_]/g, '_')}_ENTID`
39
+ const PROJECTNAME = envName(model)
40
+ const entidEnvVar = `${PROJECTNAME}_TEST_${envToken(entity.name)}_ENTID`
41
41
 
42
42
  const authActive = isAuthActive(model)
43
43
  const apikeyEnvEntry = authActive
@@ -30,7 +30,7 @@ import {
30
30
  cmp,
31
31
  each,
32
32
  isAuthActive,
33
- entityDataIdField,
33
+ entityDataIdField, envName, envToken
34
34
  } from '@voxgig/sdkgen'
35
35
 
36
36
 
@@ -59,8 +59,8 @@ const TestEntity = cmp(function TestEntity(props: any) {
59
59
  const target = props.target
60
60
  const entity: ModelEntity = props.entity
61
61
 
62
- const PROJENVNAME = nom(model.const, 'NAME').replace(/[^A-Z_]/g, '_')
63
- const ENTENVNAME = nom(entity, 'NAME').replace(/[^A-Z_]/g, '_')
62
+ const PROJENVNAME = envName(model)
63
+ const ENTENVNAME = envToken(entity.name)
64
64
  const authActive = isAuthActive(model)
65
65
  const apikeyEnvEntry = authActive
66
66
  ? `\n '${PROJENVNAME}_APIKEY': 'NONE',`
@@ -256,7 +256,7 @@ const generateCreate: OpGen = (ctx, step, index) => {
256
256
  const hasEntIdC = null != entity.id
257
257
 
258
258
  Content(`
259
- ${datavar} = await ${entvar}.create(${datavar})
259
+ ${datavar} = (await ${entvar}.create(${datavar})).data()
260
260
  `)
261
261
  if (hasEntIdC) {
262
262
  Content(` assert(null != ${datavar}.id)
@@ -297,7 +297,7 @@ const generateList: OpGen = (ctx, step, index) => {
297
297
  })
298
298
 
299
299
  Content(`
300
- const ${listvar} = await ${entvar}.list(${matchvar})
300
+ const ${listvar} = (await ${entvar}.list(${matchvar})).map((e) => e.data())
301
301
  `)
302
302
  const allSteps = flow.step
303
303
  for (let vI = 0; vI < step.valid.length; vI++) {
@@ -370,7 +370,7 @@ const generateUpdate: OpGen = (ctx, step, index) => {
370
370
  }
371
371
 
372
372
  Content(`
373
- const ${resdatavar} = await ${entvar}.update(${datavar})
373
+ const ${resdatavar} = (await ${entvar}.update(${datavar})).data()
374
374
  `)
375
375
  if (hasEntIdU) {
376
376
  Content(` assert(${resdatavar}.id === ${datavar}.id)
@@ -435,13 +435,13 @@ const generateLoad: OpGen = (ctx, step, index) => {
435
435
  if (hasEntId) {
436
436
  Content(` const ${matchvar} = {}
437
437
  ${matchvar}.id = ${srcdatavar}.id
438
- const ${datavar} = await ${entvar}.load(${matchvar})
438
+ const ${datavar} = (await ${entvar}.load(${matchvar})).data()
439
439
  assert(${datavar}.id === ${srcdatavar}.id)
440
440
  `)
441
441
  }
442
442
  else {
443
443
  Content(` const ${matchvar} = {}
444
- const ${datavar} = await ${entvar}.load(${matchvar})
444
+ const ${datavar} = (await ${entvar}.load(${matchvar})).data()
445
445
  assert(null != ${datavar})
446
446
  `)
447
447
  }
@@ -24,6 +24,7 @@ class ProjectNameEntityBase {
24
24
  this._entopts = entopts
25
25
  this._utility = client.utility()
26
26
  this._data = {}
27
+ this._deleted = false
27
28
  this._match = {}
28
29
 
29
30
  const makeContext = this._utility.makeContext
@@ -37,6 +38,21 @@ class ProjectNameEntityBase {
37
38
  featureHook(this._entctx, 'PostConstructEntity')
38
39
  }
39
40
 
41
+
42
+ // True once a successful `remove` resolves on this instance. `remove`
43
+ // resolves to the entity like every other operation, and the instance KEEPS
44
+ // the data it held — a caller can still read what was deleted — but it is
45
+ // no longer a live record. See AGENTS.md.
46
+ markDeleted() {
47
+ this._deleted = true
48
+ }
49
+
50
+
51
+ deleted() {
52
+ return true === this._deleted
53
+ }
54
+
55
+
40
56
  entopts() {
41
57
  return this._utility.struct.merge([{}, this._entopts])
42
58
  }
@@ -161,7 +177,12 @@ class ProjectNameEntityBase {
161
177
 
162
178
  toJSON() {
163
179
  const struct = this._utility.struct
164
- return struct.merge([{}, struct.getdef(this._data, {}), { entity$: this.Name }])
180
+ // The marker is NAMESPACED. It used to be `entity$` a short, generic
181
+ // name, and the `$`-suffix convention is not unique to sdkgen. Seneca uses
182
+ // `entity$` on its own entities to hold the canon, so an SDK record fed
183
+ // into `entize` silently overwrote it and produced entities claiming a
184
+ // canon that does not exist: no error, just wrong entities.
185
+ return struct.merge([{}, struct.getdef(this._data, {}), { 'voxgig$entity': this.Name }])
165
186
  }
166
187
 
167
188
 
@@ -83,7 +83,15 @@ class EntityOperation {
83
83
  }
84
84
  }
85
85
 
86
- return done(ctx)
86
+ const out = done(ctx)
87
+
88
+ // An operation resolves to the ENTITY, not the raw data — the record
89
+ // has just been absorbed into this instance and is reached through
90
+ // data(). `done` still runs: it completes the pipeline and raises on
91
+ // failure, and when throwing is disabled it hands back the error
92
+ // payload, which passes through unchanged. See AGENTS.md "Entity
93
+ // operations return ENTITIES".
94
+ return (ctx.result && ctx.result.ok) ? this : out
87
95
  }
88
96
  catch (err) {
89
97
  // #PreUnexpected-Hook
@@ -88,7 +88,15 @@ class EntityOperation {
88
88
  }
89
89
  }
90
90
 
91
- return done(ctx)
91
+ const out = done(ctx)
92
+
93
+ // An operation resolves to the ENTITY, not the raw data — the record
94
+ // has just been absorbed into this instance and is reached through
95
+ // data(). `done` still runs: it completes the pipeline and raises on
96
+ // failure, and when throwing is disabled it hands back the error
97
+ // payload, which passes through unchanged. See AGENTS.md "Entity
98
+ // operations return ENTITIES".
99
+ return (ctx.result && ctx.result.ok) ? this : out
92
100
  }
93
101
  catch (err) {
94
102
  // #PreUnexpected-Hook
@@ -89,7 +89,21 @@ class EntityOperation {
89
89
  }
90
90
  }
91
91
 
92
- return done(ctx)
92
+ const out = done(ctx)
93
+
94
+ // An operation resolves to the ENTITY, not the raw data — the record
95
+ // has just been absorbed into this instance and is reached through
96
+ // data(). `done` still runs: it completes the pipeline and raises on
97
+ // failure, and when throwing is disabled it hands back the error
98
+ // payload, which passes through unchanged. See AGENTS.md "Entity
99
+ // operations return ENTITIES".
100
+ if (ctx.result && ctx.result.ok) {
101
+ // A removed entity keeps its data but is no longer a live record.
102
+ this.markDeleted()
103
+ return this
104
+ }
105
+
106
+ return out
93
107
  }
94
108
  catch (err) {
95
109
  // #PreUnexpected-Hook
@@ -89,7 +89,15 @@ class EntityOperation {
89
89
  }
90
90
  }
91
91
 
92
- return done(ctx)
92
+ const out = done(ctx)
93
+
94
+ // An operation resolves to the ENTITY, not the raw data — the record
95
+ // has just been absorbed into this instance and is reached through
96
+ // data(). `done` still runs: it completes the pipeline and raises on
97
+ // failure, and when throwing is disabled it hands back the error
98
+ // payload, which passes through unchanged. See AGENTS.md "Entity
99
+ // operations return ENTITIES".
100
+ return (ctx.result && ctx.result.ok) ? this : out
93
101
  }
94
102
  catch (err) {
95
103
  // #PreUnexpected-Hook
@@ -10,8 +10,21 @@ class ProjectNameError extends Error {
10
10
  super(msg)
11
11
  this.code = code
12
12
  this.ctx = ctx
13
+
14
+ // HTTP status of the response that caused this error, or -1 when the
15
+ // request never got one (transport failure, client-side abort).
16
+ //
17
+ // PROMOTED to the top level on purpose. It used to be reachable only at
18
+ // `err.result.status`, so every consumer wrote the same
19
+ // `404 === e?.result?.status` branch and coupled itself to the internal
20
+ // shape of `result`.
21
+ this.status = -1
13
22
  }
14
23
 
24
+
25
+ // `err.notFound` rather than a magic number at every call site.
26
+ get notFound() { return 404 === this.status }
27
+
15
28
  }
16
29
 
17
30
  module.exports = {
@@ -4,6 +4,7 @@ import {
4
4
  File,
5
5
  cmp,
6
6
  collectDeps,
7
+ packageVersion,
7
8
  } from '@voxgig/sdkgen'
8
9
 
9
10
 
@@ -53,7 +54,7 @@ const Package = cmp(async function Package(props: any) {
53
54
  }
54
55
 
55
56
  group = "${group}"
56
- version = "0.0.1"
57
+ version = "${packageVersion(model, target.name)}"
57
58
 
58
59
  repositories {
59
60
  mavenCentral()
@@ -51,7 +51,8 @@ const ReadmeHowto = cmp(function ReadmeHowto(props: any) {
51
51
  // The op-driven test-mode line, shown only when the SDK has an entity op.
52
52
  // A direct()-only SDK (no ops anywhere) shows a direct() call instead.
53
53
  const testModeExample = primaryOp
54
- ? `// Entity ops return the bare record and raise on error.
54
+ ? `// Entity ops return the ENTITY and raises on error;
55
+ // call data() for the record.
55
56
  val ${eVar} = client.${accessor}(null).${primaryOp}(${testArg}, null)
56
57
  // ${eVar} holds the mock response record
57
58
  println(${eVar})`
@@ -1,5 +1,5 @@
1
1
 
2
- import { cmp, Content, isPublished, repoInfo } from '@voxgig/sdkgen'
2
+ import { cmp, Content, isPublished, repoInfo, packageVersion } from '@voxgig/sdkgen'
3
3
 
4
4
  import { gradleGroup } from './utility_kotlin'
5
5
 
@@ -16,7 +16,7 @@ const ReadmeInstall = cmp(function ReadmeInstall(props: any) {
16
16
 
17
17
  \`\`\`kotlin
18
18
  dependencies {
19
- implementation("${group}:${artifactId}:0.0.1")
19
+ implementation("${group}:${artifactId}:${packageVersion(model, target.name)}")
20
20
  }
21
21
  \`\`\`
22
22
 
@@ -93,7 +93,7 @@ ${opRows}
93
93
 
94
94
  ### Result shape
95
95
 
96
- Entity operations return the bare result data (a \`Map\` for single-entity
96
+ Entity operations return the ENTITY (call data() for the record) (a \`Map\` for single-entity
97
97
  ops, an aggregate \`List\` for \`list\`) as \`Any?\` and raise on error. Wrap
98
98
  calls in \`try\`/\`catch\` to handle failures.
99
99
 
@@ -123,7 +123,7 @@ catch (err: RuntimeException) {
123
123
  Content(`### 3. Load ${neArticle} ${neName.toLowerCase()}
124
124
 
125
125
  ${neName} is nested under ${parentName}, so provide the \`${parentParam}\`.
126
- \`load()\` returns the bare record (as \`Any?\`) and raises on error.
126
+ \`load()\` returns the ENTITY call data() for the record — and raises on error.
127
127
 
128
128
  \`\`\`kotlin
129
129
  try {
@@ -151,7 +151,7 @@ catch (err: RuntimeException) {
151
151
 
152
152
  Content(`### 3. Load ${article} ${eName.toLowerCase()}
153
153
 
154
- \`load()\` returns the bare record (as \`Any?\`) and raises on error.
154
+ \`load()\` returns the ENTITY call data() for the record — and raises on error.
155
155
 
156
156
  \`\`\`kotlin
157
157
  try {
@@ -191,7 +191,7 @@ catch (err: RuntimeException) {
191
191
  \`\`\`kotlin
192
192
  `)
193
193
  if (opnames.includes('create')) {
194
- Content(`// Create — returns the bare created record (as Any?)
194
+ Content(`// Create — returns the ENTITY (call data() for the record)
195
195
  val created = client.${accessor}(null).create(mutableMapOf<String, Any?>(${examplePairs('create').join(', ')}), null)
196
196
 
197
197
  `)
@@ -11,7 +11,7 @@ import {
11
11
  File,
12
12
  cmp,
13
13
  snakify,
14
- isAuthActive,
14
+ isAuthActive, envName, envToken
15
15
  } from '@voxgig/sdkgen'
16
16
 
17
17
 
@@ -67,7 +67,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
67
67
  const entity: ModelEntity = props.entity
68
68
  const kotlinpackage: string = props.kotlinpackage
69
69
 
70
- const PROJECTNAME = nom(model, 'Name').toUpperCase().replace(/[^A-Z_]/g, '_')
70
+ const PROJECTNAME = envName(model)
71
71
  const SDK = model.const.Name + 'SDK'
72
72
 
73
73
  const authActive = isAuthActive(model)
@@ -121,7 +121,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
121
121
  ? loadParams.map((p: any) => ` params["${p.name}"] = ${kotlinLiteral(p.example)}`).join('\n')
122
122
  : ''
123
123
 
124
- const entidEnvVar = `${PROJECTNAME}_TEST_${nom(entity, 'NAME').replace(/[^A-Z_]/g, '_')}_ENTID`
124
+ const entidEnvVar = `${PROJECTNAME}_TEST_${envToken(entity.name)}_ENTID`
125
125
 
126
126
  File({ name: entity.Name + 'DirectTest.' + target.ext }, () => {
127
127
 
@@ -17,7 +17,7 @@ import {
17
17
  each,
18
18
  buildIdNames,
19
19
  getMatchEntries,
20
- isAuthActive,
20
+ isAuthActive, envName, envToken
21
21
  } from '@voxgig/sdkgen'
22
22
 
23
23
 
@@ -56,8 +56,8 @@ const TestEntity = cmp(function TestEntity(props: any) {
56
56
  return
57
57
  }
58
58
 
59
- const PROJUPPER = nom(model.const, 'Name').toUpperCase().replace(/[^A-Z_]/g, '_')
60
- const ENTUPPER = entity.name.toUpperCase().replace(/[^A-Z_]/g, '_')
59
+ const PROJUPPER = envName(model)
60
+ const ENTUPPER = envToken(entity.name)
61
61
  const entidEnvVar = `${PROJUPPER}_TEST_${ENTUPPER}_ENTID`
62
62
 
63
63
  const SDK = model.const.Name + 'SDK'
@@ -317,7 +317,7 @@ const generateCreate: OpGen = (ctx, step, index) => {
317
317
 
318
318
  Content(`
319
319
  val ${datavar}Result = ${entvar}.create(${datavar}, null)
320
- ${datavar} = Helpers.toMapAny(${datavar}Result) ?: linkedMapOf()
320
+ ${datavar} = Helpers.toMapAny(if (${datavar}Result is SdkEntity) ${datavar}Result.data() else ${datavar}Result) ?: linkedMapOf()
321
321
  assertNotNull(${datavar}, "expected create result to be a map")
322
322
  `)
323
323
  if (null != ctx.entity.id) {
@@ -451,7 +451,7 @@ const generateUpdate: OpGen = (ctx, step, index) => {
451
451
 
452
452
  Content(`
453
453
  val ${resdatavar}Result = ${entvar}.update(${datavar}Up, null)
454
- val ${resdatavar} = Helpers.toMapAny(${resdatavar}Result) ?: linkedMapOf()
454
+ val ${resdatavar} = Helpers.toMapAny(if (${resdatavar}Result is SdkEntity) ${resdatavar}Result.data() else ${resdatavar}Result) ?: linkedMapOf()
455
455
  assertNotNull(${resdatavar}, "expected update result to be a map")
456
456
  `)
457
457
  if (hasEntIdU) {
@@ -516,7 +516,7 @@ const generateLoad: OpGen = (ctx, step, index) => {
516
516
  if (hasEntId) {
517
517
  Content(` ${matchvar}["id"] = ${srcdatavar}["id"]
518
518
  val ${datavar}Loaded = ${entvar}.load(${matchvar}, null)
519
- val ${datavar}LoadResult = Helpers.toMapAny(${datavar}Loaded) ?: linkedMapOf()
519
+ val ${datavar}LoadResult = Helpers.toMapAny(if (${datavar}Loaded is SdkEntity) ${datavar}Loaded.data() else ${datavar}Loaded) ?: linkedMapOf()
520
520
  assertNotNull(${datavar}LoadResult, "expected load result to be a map")
521
521
  assertEquals(${srcdatavar}["id"], ${datavar}LoadResult["id"],
522
522
  "expected load result id to match")
@@ -71,6 +71,18 @@ abstract class EntityBase(nm: String, clientIn: SdkClient, entoptsIn: MutableMap
71
71
  // runOp drives one operation through the pipeline: for each stage the
72
72
  // feature hook fires, then the stage runs; a failing stage routes through
73
73
  // makeError (which throws, or returns fallback data when ctrl.throw false).
74
+ // Every operation resolves to the entity; `remove` additionally marks
75
+ // it. The instance KEEPS the data it held — a caller can still read
76
+ // what was deleted — but it is no longer a live record. See AGENTS.md.
77
+ private var deletedFlag: Boolean = false
78
+
79
+ fun markDeleted() {
80
+ this.deletedFlag = true
81
+ }
82
+
83
+ fun deleted(): Boolean = this.deletedFlag
84
+
85
+
74
86
  protected fun runOp(ctx: Context, postDone: () -> Unit): Any? {
75
87
  val utility = this.utility
76
88
 
@@ -104,7 +116,26 @@ abstract class EntityBase(nm: String, clientIn: SdkClient, entoptsIn: MutableMap
104
116
 
105
117
  postDone()
106
118
 
107
- return utility.done(ctx)
119
+ val out = utility.done(ctx)
120
+
121
+ // An operation resolves to the ENTITY, not the raw data. Entities are
122
+ // stateful: postDone has just absorbed resdata/resmatch into this
123
+ // instance, and the caller reaches the record through data(). Two
124
+ // structural exceptions: `list` resolves to the ARRAY of entity
125
+ // instances makeResult built, and a failed op with throwing disabled
126
+ // hands back the error payload unchanged. `remove` additionally marks
127
+ // the entity deleted; it KEEPS its data, so a caller can still read
128
+ // what was removed. See AGENTS.md "Entity operations return ENTITIES".
129
+ val opname = ctx.op?.name
130
+
131
+ if (ctx.result != null && ctx.result!!.ok && "list" != opname) {
132
+ if ("remove" == opname) {
133
+ this.markDeleted()
134
+ }
135
+ return this
136
+ }
137
+
138
+ return out
108
139
  } catch (err: RuntimeException) {
109
140
  // An error already finalised by makeError (e.g. via done) must not be
110
141
  // wrapped a second time.
@@ -2,6 +2,7 @@ import {
2
2
  Content,
3
3
  File,
4
4
  cmp,
5
+ packageVersion,
5
6
  } from '@voxgig/sdkgen'
6
7
 
7
8
  import type {
@@ -22,6 +23,7 @@ const LIBS = [
22
23
 
23
24
  const Package = cmp(async function Package(props: any) {
24
25
  const ctx$ = props.ctx$
26
+ const target = props.target
25
27
  const model: Model = ctx$.model
26
28
 
27
29
  const libBlocks = LIBS.map((n) =>
@@ -30,7 +32,7 @@ const Package = cmp(async function Package(props: any) {
30
32
  File({ name: 'lakefile.toml' }, () => {
31
33
  Content(`# ${model.const.Name} SDK for Lean 4 (generated by @voxgig/sdkgen).
32
34
  name = "${pkgName(model)}"
33
- version = "0.0.1"
35
+ version = "${packageVersion(model, target.name)}"
34
36
  defaultTargets = ["SdkClient"]
35
37
 
36
38
  ${libBlocks}
@@ -26,6 +26,21 @@ function hasParamFreePoint(op: any): boolean {
26
26
  }
27
27
 
28
28
 
29
+ // True when an op selects a single record by path params — i.e. loading it by
30
+ // id is meaningful. A load whose every point is param-free is a singleton
31
+ // endpoint (`/current`): passing it an id matches no point at all, and the
32
+ // runtime raises `has no matching endpoint`.
33
+ function selectsByParams(op: any): boolean {
34
+ if (null == op) return false
35
+ const points = op.points || []
36
+ for (const pt of points) {
37
+ const params = ((pt.args || {}).params) || []
38
+ if (0 < params.length) return true
39
+ }
40
+ return false
41
+ }
42
+
43
+
29
44
  // Synthesize a create payload from the entity's required non-id fields.
30
45
  function synthData(fields: any): any {
31
46
  const o: any = {}
@@ -64,30 +79,44 @@ const Test = cmp(async function Test(props: any) {
64
79
  const Name = e.Name || (e.name.charAt(0).toUpperCase() + e.name.slice(1))
65
80
  const ops = e.op || {}
66
81
  if (!ops.list && !ops.load) return
67
- offline += ` -- ${e.name}: offline (test-mode) entity behaviour
68
- (do
69
- let seedPath := "../.sdk/test/entity/${e.name}/${Name}TestData.json"
70
- if !(← System.FilePath.pathExists seedPath) then
71
- IO.println s!"skip - ${e.name}: no seed at {seedPath}"
72
- else do
73
- let seed SdkJson.jsonRead (← IO.FS.readFile seedPath)
74
- let tclient Sdk.testSdk0 seed
75
- let existing ← SdkRuntime.gp (← SdkRuntime.gp seed "existing") "${e.name}"
76
- let ids ← keysof existing
77
- -- list returns every seeded entity
82
+
83
+ // Only call the ops the entity actually declares. `Entity.create` is not
84
+ // generated for a load-only entity, so emitting the create/remove block
85
+ // unconditionally fails the build with "Unknown identifier X.create".
86
+ // Value's constructors are spelled out (`Value.list`, not `.list`) the
87
+ // expected type is not known at the match scrutinee, and Lean reports the
88
+ // dotted form as ambiguous against Std's own `.list`.
89
+ let body = ''
90
+
91
+ if (ops.list) {
92
+ body += ` -- list returns every seeded entity
78
93
  let items ← ${ns}.list tclient (← emptyMap) (← emptyMap)
79
- let n ← (match items with | .list lid => do pure (← listItems lid).size | _ => pure 0)
94
+ let n ← (match items with | Value.list lid => do pure (← listItems lid).size | _ => pure 0)
80
95
  if n == ids.size then pass s!"${e.name}.list offline -> {n} seeded"
81
96
  else fail s!"${e.name}.list offline: got {n}, want {ids.size}"
82
- -- load the first seeded entity by id
97
+ `
98
+ }
99
+
100
+ if (ops.load && selectsByParams(ops.load)) {
101
+ body += ` -- load the first seeded entity by id
83
102
  if ids.size > 0 then do
84
103
  let wid := ids[0]!
85
- let m ← newMap #[("id", .str wid)]
104
+ let m ← newMap #[("id", Value.str wid)]
86
105
  let got ← ${ns}.load tclient m (← emptyMap)
87
106
  let gid ← SdkRuntime.gpS got "id"
88
107
  if gid == wid then pass s!"${e.name}.load offline (id={wid})"
89
108
  else fail s!"${e.name}.load offline: got {gid}, want {wid}"
90
- -- create -> load back -> remove, all in the store
109
+ `
110
+ }
111
+ // A singleton load (`/current`, `/slack`) is deliberately NOT asserted
112
+ // here. The offline lane answers from a store keyed by entity id, so a
113
+ // load carrying no id has nothing to look up — the only honest assertion
114
+ // would need the model-driven match data the other targets build in their
115
+ // TestEntity components. Until this lane is model-driven too, such an
116
+ // entity contributes no offline block rather than a misleading one.
117
+
118
+ if (ops.create && ops.load && ops.remove) {
119
+ body += ` -- create -> load back -> remove, all in the store
91
120
  let newmap ← SdkRuntime.gp (← SdkRuntime.gp seed "new") "${e.name}"
92
121
  let nks ← keysof newmap
93
122
  if nks.size > 0 then do
@@ -95,7 +124,7 @@ const Test = cmp(async function Test(props: any) {
95
124
  let created ← ${ns}.create tclient payload (← emptyMap)
96
125
  let cid ← SdkRuntime.gpS created "id"
97
126
  if cid == "" then fail "${e.name}.create offline returned no id" else do
98
- let m2 ← newMap #[("id", .str cid)]
127
+ let m2 ← newMap #[("id", Value.str cid)]
99
128
  let back ← ${ns}.load tclient m2 (← emptyMap)
100
129
  if (← SdkRuntime.gpS back "id") == cid then
101
130
  pass s!"${e.name}.create/load offline (id={cid})"
@@ -103,8 +132,26 @@ const Test = cmp(async function Test(props: any) {
103
132
  let _ ← ${ns}.remove tclient m2 (← emptyMap)
104
133
  let gone ← ${ns}.load tclient m2 (← emptyMap)
105
134
  match gone with
106
- | .map _ => fail s!"${e.name}.remove offline: still present"
107
- | _ => pass s!"${e.name}.remove offline (id={cid})")
135
+ | Value.map _ => fail s!"${e.name}.remove offline: still present"
136
+ | _ => pass s!"${e.name}.remove offline (id={cid})"
137
+ `
138
+ }
139
+
140
+ // Nothing to assert (an entity whose only op needs path params we cannot
141
+ // synthesise) — skip the block rather than emit an empty `do`.
142
+ if ('' === body) return
143
+
144
+ offline += ` -- ${e.name}: offline (test-mode) entity behaviour
145
+ (do
146
+ let seedPath := "../.sdk/test/entity/${e.name}/${Name}TestData.json"
147
+ if !(← System.FilePath.pathExists seedPath) then
148
+ IO.println s!"skip - ${e.name}: no seed at {seedPath}"
149
+ else do
150
+ let seed ← SdkJson.jsonRead (← IO.FS.readFile seedPath)
151
+ let tclient ← Sdk.testSdk0 seed
152
+ let existing ← SdkRuntime.gp (← SdkRuntime.gp seed "existing") "${e.name}"
153
+ let ids ← keysof existing
154
+ ${body})
108
155
  `
109
156
  })
110
157
 
@@ -121,7 +168,7 @@ const Test = cmp(async function Test(props: any) {
121
168
  (do
122
169
  let items ← ${ns}.list client (← emptyMap) (← emptyMap)
123
170
  match items with
124
- | .list lid => pass s!"${e.name}.list -> {(← listItems lid).size} items"
171
+ | Value.list lid => pass s!"${e.name}.list -> {(← listItems lid).size} items"
125
172
  | _ => fail "${e.name}.list did not return a list")
126
173
  `
127
174
  }
@@ -151,6 +198,13 @@ const Test = cmp(async function Test(props: any) {
151
198
  // The live lane nests two levels deeper than the offline lane.
152
199
  const liveBlocks = blocks.split('\n').map((l) => l ? ' ' + l : l).join('\n')
153
200
 
201
+ // A `do` block whose last statement is a `let` is a type error in Lean
202
+ // ("the rest of the do block has monadic result type"), and an entirely
203
+ // empty one does not parse at all. An API whose entities offer no op these
204
+ // lanes can drive leaves both empty, so terminate them explicitly.
205
+ const offlineBody = '' === offline ? ' pure ()\n' : offline
206
+ const liveBody = '' === blocks ? ' pure ()\n' : liveBlocks
207
+
154
208
  Folder({ name: 'test' }, () => {
155
209
  File({ name: 'Runner.' + target.ext }, () => {
156
210
  Content(`-- ${model.const.Name} SDK test runner (generated by @voxgig/sdkgen).
@@ -183,14 +237,14 @@ def main : IO UInt32 := do
183
237
  let liveBase ← IO.getEnv "SDK_TEST_BASE"
184
238
  let ctx ← mkCtx
185
239
  let offline : SIO Unit := do
186
- ${offline} offline.run ctx
240
+ ${offlineBody} offline.run ctx
187
241
  match liveBase with
188
242
  | none => IO.println "skip - live lane (set SDK_TEST_BASE to enable)"
189
243
  | some base => do
190
244
  let live : SIO Unit := do
191
245
  let opts ← newMap #[("base", .str base)]
192
246
  let client ← Sdk.newSdk opts
193
- ${liveBlocks} live.run ctx
247
+ ${liveBody} live.run ctx
194
248
  let p ← npass.get
195
249
  let f ← nfail.get
196
250
  IO.println ""