@voxgig/sdkgen 2.0.2 → 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 (385) 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 +5 -3
  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 +12 -9
  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/Package_dart.ts +2 -1
  108. package/project/.sdk/src/cmp/dart/ReadmeEntity_dart.ts +13 -2
  109. package/project/.sdk/src/cmp/dart/ReadmeHowto_dart.ts +2 -1
  110. package/project/.sdk/src/cmp/dart/ReadmeInstall_dart.ts +3 -3
  111. package/project/.sdk/src/cmp/dart/ReadmeModel_dart.ts +1 -1
  112. package/project/.sdk/src/cmp/dart/ReadmeQuick_dart.ts +17 -6
  113. package/project/.sdk/src/cmp/dart/ReadmeRef_dart.ts +13 -2
  114. package/project/.sdk/src/cmp/dart/ReadmeTopQuick_dart.ts +13 -2
  115. package/project/.sdk/src/cmp/dart/TestDirect_dart.ts +3 -3
  116. package/project/.sdk/src/cmp/dart/TestEntity_dart.ts +8 -8
  117. package/project/.sdk/src/cmp/dart/fragment/EntityBase.fragment.dart +18 -1
  118. package/project/.sdk/src/cmp/dart/fragment/EntityCreateOp.fragment.dart +9 -1
  119. package/project/.sdk/src/cmp/dart/fragment/EntityLoadOp.fragment.dart +9 -1
  120. package/project/.sdk/src/cmp/dart/fragment/EntityRemoveOp.fragment.dart +15 -1
  121. package/project/.sdk/src/cmp/dart/fragment/EntityUpdateOp.fragment.dart +9 -1
  122. package/project/.sdk/src/cmp/dart/fragment/SdkError.fragment.dart +8 -0
  123. package/project/.sdk/src/cmp/elixir/Package_elixir.ts +3 -1
  124. package/project/.sdk/src/cmp/elixir/ReadmeInstall_elixir.ts +2 -2
  125. package/project/.sdk/src/cmp/elixir/TestEntity_elixir.ts +11 -2
  126. package/project/.sdk/src/cmp/elixir/fragment/EntityCreateOp.fragment.ex +2 -1
  127. package/project/.sdk/src/cmp/elixir/fragment/EntityListOp.fragment.ex +1 -0
  128. package/project/.sdk/src/cmp/elixir/fragment/EntityLoadOp.fragment.ex +2 -1
  129. package/project/.sdk/src/cmp/elixir/fragment/EntityRemoveOp.fragment.ex +4 -1
  130. package/project/.sdk/src/cmp/elixir/fragment/EntityUpdateOp.fragment.ex +2 -1
  131. package/project/.sdk/src/cmp/go/EntityTypes_go.ts +38 -8
  132. package/project/.sdk/src/cmp/go/Entity_go.ts +2 -2
  133. package/project/.sdk/src/cmp/go/Main_go.ts +4 -5
  134. package/project/.sdk/src/cmp/go/Package_go.ts +8 -5
  135. package/project/.sdk/src/cmp/go/ReadmeExplanation_go.ts +2 -2
  136. package/project/.sdk/src/cmp/go/ReadmeHowto_go.ts +2 -2
  137. package/project/.sdk/src/cmp/go/ReadmeInstall_go.ts +4 -2
  138. package/project/.sdk/src/cmp/go/ReadmeModel_go.ts +2 -2
  139. package/project/.sdk/src/cmp/go/ReadmeQuick_go.ts +2 -2
  140. package/project/.sdk/src/cmp/go/ReadmeTopQuick_go.ts +2 -2
  141. package/project/.sdk/src/cmp/go/ReadmeTopTest_go.ts +2 -2
  142. package/project/.sdk/src/cmp/go/TestDirect_go.ts +21 -15
  143. package/project/.sdk/src/cmp/go/TestEntity_go.ts +9 -9
  144. package/project/.sdk/src/cmp/go/Test_go.ts +2 -2
  145. package/project/.sdk/src/cmp/go/fragment/Entity.fragment.go +42 -1
  146. package/project/.sdk/src/cmp/go-cli/Main_go-cli.ts +4 -4
  147. package/project/.sdk/src/cmp/go-mcp/Main_go-mcp.ts +4 -4
  148. package/project/.sdk/src/cmp/haskell/Package_haskell.ts +2 -1
  149. package/project/.sdk/src/cmp/haskell/ReadmeEntity_haskell.ts +10 -5
  150. package/project/.sdk/src/cmp/haskell/ReadmeModel_haskell.ts +10 -8
  151. package/project/.sdk/src/cmp/haskell/ReadmeQuick_haskell.ts +14 -10
  152. package/project/.sdk/src/cmp/haskell/ReadmeRef_haskell.ts +21 -18
  153. package/project/.sdk/src/cmp/haskell/ReadmeTopQuick_haskell.ts +4 -4
  154. package/project/.sdk/src/cmp/haskell/Test_haskell.ts +23 -11
  155. package/project/.sdk/src/cmp/java/Package_java.ts +2 -1
  156. package/project/.sdk/src/cmp/java/ReadmeHowto_java.ts +2 -1
  157. package/project/.sdk/src/cmp/java/ReadmeInstall_java.ts +2 -2
  158. package/project/.sdk/src/cmp/java/ReadmeModel_java.ts +1 -1
  159. package/project/.sdk/src/cmp/java/ReadmeQuick_java.ts +3 -3
  160. package/project/.sdk/src/cmp/java/TestDirect_java.ts +3 -3
  161. package/project/.sdk/src/cmp/java/TestEntity_java.ts +6 -6
  162. package/project/.sdk/src/cmp/java/fragment/EntityBase.fragment.java +34 -1
  163. package/project/.sdk/src/cmp/java/fragment/SdkError.fragment.java +12 -0
  164. package/project/.sdk/src/cmp/js/Main_js.ts +4 -1
  165. package/project/.sdk/src/cmp/js/Package_js.ts +7 -1
  166. package/project/.sdk/src/cmp/js/ReadmeEntity_js.ts +13 -2
  167. package/project/.sdk/src/cmp/js/ReadmeHowto_js.ts +2 -1
  168. package/project/.sdk/src/cmp/js/ReadmeQuick_js.ts +13 -2
  169. package/project/.sdk/src/cmp/js/ReadmeTopQuick_js.ts +13 -2
  170. package/project/.sdk/src/cmp/js/ReadmeTopTest_js.ts +2 -1
  171. package/project/.sdk/src/cmp/js/TestDirect_js.ts +3 -3
  172. package/project/.sdk/src/cmp/js/TestEntity_js.ts +8 -8
  173. package/project/.sdk/src/cmp/js/fragment/EntityBase.fragment.js +22 -1
  174. package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +9 -1
  175. package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +9 -1
  176. package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +15 -1
  177. package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +9 -1
  178. package/project/.sdk/src/cmp/js/fragment/SdkError.fragment.js +13 -0
  179. package/project/.sdk/src/cmp/kotlin/Package_kotlin.ts +2 -1
  180. package/project/.sdk/src/cmp/kotlin/ReadmeHowto_kotlin.ts +2 -1
  181. package/project/.sdk/src/cmp/kotlin/ReadmeInstall_kotlin.ts +2 -2
  182. package/project/.sdk/src/cmp/kotlin/ReadmeModel_kotlin.ts +1 -1
  183. package/project/.sdk/src/cmp/kotlin/ReadmeQuick_kotlin.ts +3 -3
  184. package/project/.sdk/src/cmp/kotlin/TestDirect_kotlin.ts +3 -3
  185. package/project/.sdk/src/cmp/kotlin/TestEntity_kotlin.ts +6 -6
  186. package/project/.sdk/src/cmp/kotlin/fragment/EntityBase.fragment.kt +32 -1
  187. package/project/.sdk/src/cmp/lean/Package_lean.ts +3 -1
  188. package/project/.sdk/src/cmp/lua/MainEntity_lua.ts +9 -4
  189. package/project/.sdk/src/cmp/lua/Package_lua.ts +4 -3
  190. package/project/.sdk/src/cmp/lua/ReadmeModel_lua.ts +11 -3
  191. package/project/.sdk/src/cmp/lua/ReadmeQuick_lua.ts +1 -1
  192. package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +3 -3
  193. package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +9 -9
  194. package/project/.sdk/src/cmp/lua/fragment/Entity.fragment.lua +37 -1
  195. package/project/.sdk/src/cmp/lua/fragment/SdkError.fragment.lua +12 -0
  196. package/project/.sdk/src/cmp/ocaml/EntityOperation_ocaml.ts +30 -3
  197. package/project/.sdk/src/cmp/ocaml/Entity_ocaml.ts +11 -5
  198. package/project/.sdk/src/cmp/ocaml/Package_ocaml.ts +3 -1
  199. package/project/.sdk/src/cmp/ocaml/ReadmeEntity_ocaml.ts +10 -5
  200. package/project/.sdk/src/cmp/ocaml/ReadmeHowto_ocaml.ts +6 -2
  201. package/project/.sdk/src/cmp/ocaml/ReadmeModel_ocaml.ts +10 -8
  202. package/project/.sdk/src/cmp/ocaml/ReadmeQuick_ocaml.ts +14 -13
  203. package/project/.sdk/src/cmp/ocaml/ReadmeRef_ocaml.ts +20 -18
  204. package/project/.sdk/src/cmp/ocaml/ReadmeTopQuick_ocaml.ts +4 -4
  205. package/project/.sdk/src/cmp/ocaml/ReadmeTopTest_ocaml.ts +8 -2
  206. package/project/.sdk/src/cmp/ocaml/TestEntity_ocaml.ts +8 -5
  207. package/project/.sdk/src/cmp/perl/ReadmeHowto_perl.ts +2 -1
  208. package/project/.sdk/src/cmp/perl/ReadmeModel_perl.ts +1 -1
  209. package/project/.sdk/src/cmp/perl/ReadmeQuick_perl.ts +3 -3
  210. package/project/.sdk/src/cmp/perl/ReadmeTopQuick_perl.ts +1 -1
  211. package/project/.sdk/src/cmp/perl/TestDirect_perl.ts +3 -3
  212. package/project/.sdk/src/cmp/perl/TestEntity_perl.ts +6 -6
  213. package/project/.sdk/src/cmp/perl/fragment/Entity.fragment.pm +36 -1
  214. package/project/.sdk/src/cmp/php/MainEntity_php.ts +21 -16
  215. package/project/.sdk/src/cmp/php/Package_php.ts +2 -2
  216. package/project/.sdk/src/cmp/php/ReadmeEntity_php.ts +6 -6
  217. package/project/.sdk/src/cmp/php/ReadmeHowto_php.ts +4 -3
  218. package/project/.sdk/src/cmp/php/ReadmeIntro_php.ts +2 -2
  219. package/project/.sdk/src/cmp/php/ReadmeModel_php.ts +1 -1
  220. package/project/.sdk/src/cmp/php/ReadmeQuick_php.ts +12 -12
  221. package/project/.sdk/src/cmp/php/ReadmeRef_php.ts +6 -6
  222. package/project/.sdk/src/cmp/php/ReadmeTopQuick_php.ts +4 -4
  223. package/project/.sdk/src/cmp/php/ReadmeTopTest_php.ts +2 -2
  224. package/project/.sdk/src/cmp/php/TestDirect_php.ts +3 -3
  225. package/project/.sdk/src/cmp/php/TestEntity_php.ts +17 -15
  226. package/project/.sdk/src/cmp/php/fragment/Entity.fragment.php +20 -1
  227. package/project/.sdk/src/cmp/php/fragment/SdkError.fragment.php +11 -0
  228. package/project/.sdk/src/cmp/py/Package_py.ts +4 -3
  229. package/project/.sdk/src/cmp/py/ReadmeEntity_py.ts +13 -2
  230. package/project/.sdk/src/cmp/py/ReadmeHowto_py.ts +2 -1
  231. package/project/.sdk/src/cmp/py/ReadmeModel_py.ts +1 -1
  232. package/project/.sdk/src/cmp/py/ReadmeQuick_py.ts +17 -6
  233. package/project/.sdk/src/cmp/py/ReadmeRef_py.ts +14 -3
  234. package/project/.sdk/src/cmp/py/ReadmeTopQuick_py.ts +13 -2
  235. package/project/.sdk/src/cmp/py/TestDirect_py.ts +3 -3
  236. package/project/.sdk/src/cmp/py/TestEntity_py.ts +9 -9
  237. package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +29 -1
  238. package/project/.sdk/src/cmp/py/fragment/SdkError.fragment.py +11 -0
  239. package/project/.sdk/src/cmp/py-data/Main_py-data.ts +2 -1
  240. package/project/.sdk/src/cmp/rb/Package_rb.ts +4 -3
  241. package/project/.sdk/src/cmp/rb/ReadmeEntity_rb.ts +1 -1
  242. package/project/.sdk/src/cmp/rb/ReadmeHowto_rb.ts +2 -1
  243. package/project/.sdk/src/cmp/rb/ReadmeQuick_rb.ts +5 -5
  244. package/project/.sdk/src/cmp/rb/ReadmeTopQuick_rb.ts +1 -1
  245. package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +3 -3
  246. package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +9 -9
  247. package/project/.sdk/src/cmp/rb/fragment/Entity.fragment.rb +31 -1
  248. package/project/.sdk/src/cmp/rb/fragment/SdkError.fragment.rb +10 -1
  249. package/project/.sdk/src/cmp/rust/Entity_rust.ts +5 -1
  250. package/project/.sdk/src/cmp/rust/Main_rust.ts +21 -0
  251. package/project/.sdk/src/cmp/rust/Package_rust.ts +2 -1
  252. package/project/.sdk/src/cmp/rust/TestDirect_rust.ts +3 -3
  253. package/project/.sdk/src/cmp/rust/TestEntity_rust.ts +12 -12
  254. package/project/.sdk/src/cmp/rust/fragment/Entity.fragment.rs +18 -0
  255. package/project/.sdk/src/cmp/rust/fragment/EntityCreateOp.fragment.rs +8 -2
  256. package/project/.sdk/src/cmp/rust/fragment/EntityListOp.fragment.rs +20 -3
  257. package/project/.sdk/src/cmp/rust/fragment/EntityLoadOp.fragment.rs +8 -2
  258. package/project/.sdk/src/cmp/rust/fragment/EntityRemoveOp.fragment.rs +10 -2
  259. package/project/.sdk/src/cmp/rust/fragment/EntityUpdateOp.fragment.rs +8 -2
  260. package/project/.sdk/src/cmp/rust/fragment/SdkError.fragment.rs +10 -0
  261. package/project/.sdk/src/cmp/scala/ReadmeHowto_scala.ts +2 -1
  262. package/project/.sdk/src/cmp/scala/ReadmeInstall_scala.ts +3 -3
  263. package/project/.sdk/src/cmp/scala/ReadmeModel_scala.ts +1 -1
  264. package/project/.sdk/src/cmp/scala/ReadmeQuick_scala.ts +3 -3
  265. package/project/.sdk/src/cmp/scala/TestEntity_scala.ts +3 -3
  266. package/project/.sdk/src/cmp/scala/fragment/EntityBase.fragment.scala +27 -1
  267. package/project/.sdk/src/cmp/swift/ReadmeHowto_swift.ts +2 -1
  268. package/project/.sdk/src/cmp/swift/ReadmeInstall_swift.ts +3 -3
  269. package/project/.sdk/src/cmp/swift/ReadmeModel_swift.ts +1 -1
  270. package/project/.sdk/src/cmp/swift/ReadmeQuick_swift.ts +3 -3
  271. package/project/.sdk/src/cmp/swift/fragment/EntityBase.fragment.swift +34 -1
  272. package/project/.sdk/src/cmp/ts/EntityOperation_ts.ts +9 -1
  273. package/project/.sdk/src/cmp/ts/EntityTypes_ts.ts +18 -1
  274. package/project/.sdk/src/cmp/ts/Gitignore_ts.ts +5 -2
  275. package/project/.sdk/src/cmp/ts/Main_ts.ts +4 -1
  276. package/project/.sdk/src/cmp/ts/Package_ts.ts +10 -1
  277. package/project/.sdk/src/cmp/ts/ReadmeEntity_ts.ts +13 -2
  278. package/project/.sdk/src/cmp/ts/ReadmeHowto_ts.ts +2 -1
  279. package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +21 -6
  280. package/project/.sdk/src/cmp/ts/ReadmeRef_ts.ts +52 -2
  281. package/project/.sdk/src/cmp/ts/ReadmeTopQuick_ts.ts +14 -3
  282. package/project/.sdk/src/cmp/ts/ReadmeTopTest_ts.ts +34 -2
  283. package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +64 -43
  284. package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +8 -8
  285. package/project/.sdk/src/cmp/ts/fragment/Direct.test.fragment.ts +2 -2
  286. package/project/.sdk/src/cmp/ts/fragment/Entity.test.fragment.ts +2 -2
  287. package/project/.sdk/src/cmp/ts/fragment/EntityBase.fragment.ts +25 -1
  288. package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.ts +10 -2
  289. package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.ts +1 -1
  290. package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.ts +10 -2
  291. package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.ts +27 -3
  292. package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.ts +10 -2
  293. package/project/.sdk/src/cmp/ts/fragment/SdkError.fragment.ts +15 -0
  294. package/project/.sdk/src/cmp/zig/Entity_zig.ts +5 -1
  295. package/project/.sdk/src/cmp/zig/Package_zig.ts +3 -1
  296. package/project/.sdk/src/cmp/zig/fragment/Entity.fragment.zig +39 -0
  297. package/project/.sdk/src/cmp/zig/fragment/EntityCreateOp.fragment.zig +2 -2
  298. package/project/.sdk/src/cmp/zig/fragment/EntityListOp.fragment.zig +21 -2
  299. package/project/.sdk/src/cmp/zig/fragment/EntityLoadOp.fragment.zig +2 -2
  300. package/project/.sdk/src/cmp/zig/fragment/EntityRemoveOp.fragment.zig +5 -2
  301. package/project/.sdk/src/cmp/zig/fragment/EntityUpdateOp.fragment.zig +2 -2
  302. package/project/.sdk/tm/c/VERSION +1 -1
  303. package/project/.sdk/tm/c/core/helpers.c +1 -0
  304. package/project/.sdk/tm/c/core/sdk.h +22 -6
  305. package/project/.sdk/tm/c/tests/feature_harness.h +1 -0
  306. package/project/.sdk/tm/c/tests/primary_utility_test.c +4 -1
  307. package/project/.sdk/tm/c/utility/make_url.c +1 -0
  308. package/project/.sdk/tm/c/utility/param.c +1 -0
  309. package/project/.sdk/tm/clojure/VERSION +1 -1
  310. package/project/.sdk/tm/cpp/VERSION +1 -1
  311. package/project/.sdk/tm/cpp/core/types.hpp +33 -8
  312. package/project/.sdk/tm/cpp/test/pipeline_test.cpp +5 -0
  313. package/project/.sdk/tm/cpp/test/runner_support.hpp +4 -4
  314. package/project/.sdk/tm/csharp/VERSION +1 -1
  315. package/project/.sdk/tm/csharp/core/Types.cs +6 -0
  316. package/project/.sdk/tm/csharp/test/FeatureHarness.cs +396 -0
  317. package/project/.sdk/tm/csharp/test/FeatureTest.cs +7 -385
  318. package/project/.sdk/tm/csharp/test/Runner.cs +4 -4
  319. package/project/.sdk/tm/dart/lib/utility/MakeErrorUtility.dart +4 -0
  320. package/project/.sdk/tm/dart/test/utility.dart +4 -4
  321. package/project/.sdk/tm/elixir/VERSION +1 -1
  322. package/project/.sdk/tm/elixir/lib/projectname/entity_base.ex +26 -0
  323. package/project/.sdk/tm/go/VERSION +1 -1
  324. package/project/.sdk/tm/go/core/types.go +6 -0
  325. package/project/.sdk/tm/go/test/feature_harness_test.go +361 -0
  326. package/project/.sdk/tm/go/test/feature_test.go +7 -350
  327. package/project/.sdk/tm/go/test/pipeline_test.go +6 -0
  328. package/project/.sdk/tm/go/test/runner_test.go +16 -4
  329. package/project/.sdk/tm/haskell/VERSION +1 -1
  330. package/project/.sdk/tm/haskell/src/SdkFeatures.hs +28 -5
  331. package/project/.sdk/tm/haskell/src/SdkTypes.hs +14 -5
  332. package/project/.sdk/tm/java/VERSION +1 -1
  333. package/project/.sdk/tm/java/test/RunnerSupport.java +4 -4
  334. package/project/.sdk/tm/java/utility/MakeError.java +4 -0
  335. package/project/.sdk/tm/js/src/utility/MakeErrorUtility.js +4 -0
  336. package/project/.sdk/tm/js/test/utility.js +3 -3
  337. package/project/.sdk/tm/kotlin/VERSION +1 -1
  338. package/project/.sdk/tm/kotlin/test/RunnerSupport.kt +3 -3
  339. package/project/.sdk/tm/lean/VERSION +1 -1
  340. package/project/.sdk/tm/lean/test/TFeature.lean +27 -14
  341. package/project/.sdk/tm/lua/test/runner.lua +4 -4
  342. package/project/.sdk/tm/lua/utility/make_error.lua +4 -0
  343. package/project/.sdk/tm/ocaml/VERSION +1 -1
  344. package/project/.sdk/tm/ocaml/sdk_types.ml +14 -5
  345. package/project/.sdk/tm/ocaml/test/t_pipeline.ml +5 -2
  346. package/project/.sdk/tm/perl/t/runner.pm +4 -4
  347. package/project/.sdk/tm/php/VERSION +1 -1
  348. package/project/.sdk/tm/php/test/Runner.php +4 -4
  349. package/project/.sdk/tm/php/utility/MakeError.php +5 -0
  350. package/project/.sdk/tm/py/pkg/utility/make_error.py +4 -0
  351. package/project/.sdk/tm/py/test/runner.py +19 -4
  352. package/project/.sdk/tm/rb/test/runner.rb +4 -4
  353. package/project/.sdk/tm/rb/utility/make_error.rb +4 -0
  354. package/project/.sdk/tm/rust/VERSION +1 -1
  355. package/project/.sdk/tm/rust/core/types.rs +22 -6
  356. package/project/.sdk/tm/rust/tests/common/mod.rs +6 -6
  357. package/project/.sdk/tm/rust/tests/pipeline_test.rs +6 -0
  358. package/project/.sdk/tm/rust/utility/make_error.rs +4 -0
  359. package/project/.sdk/tm/scala/VERSION +1 -1
  360. package/project/.sdk/tm/swift/VERSION +1 -1
  361. package/project/.sdk/tm/ts/src/tsconfig.json +1 -0
  362. package/project/.sdk/tm/ts/src/utility/MakeErrorUtility.ts +4 -0
  363. package/project/.sdk/tm/ts/test/tsconfig.json +1 -0
  364. package/project/.sdk/tm/ts/test/utility.ts +3 -3
  365. package/project/.sdk/tm/zig/VERSION +1 -1
  366. package/src/action/doctor.ts +410 -0
  367. package/src/action/feature.ts +54 -16
  368. package/src/action/target.ts +174 -25
  369. package/src/cmp/Entity.ts +7 -0
  370. package/src/cmp/Feature.ts +3 -1
  371. package/src/cmp/Main.ts +7 -1
  372. package/src/cmp/ReadmeExplanation.ts +2 -2
  373. package/src/cmp/ReadmeTop.ts +22 -9
  374. package/src/cmp/Registered.ts +100 -0
  375. package/src/cmp/Test.ts +4 -1
  376. package/src/helpers/dryrun.ts +57 -0
  377. package/src/helpers/featureSource.ts +208 -0
  378. package/src/helpers/naming.ts +73 -2
  379. package/src/helpers/opExample.ts +19 -2
  380. package/src/helpers/opShape.ts +65 -0
  381. package/src/helpers/packageMeta.ts +163 -10
  382. package/src/helpers/stdrep.ts +56 -0
  383. package/src/helpers/testPolicy.ts +52 -0
  384. package/src/sdkgen.ts +70 -4
  385. package/project/.sdk/tm/rust/feature/mod.rs +0 -24
@@ -12,8 +12,11 @@ const Gitignore = cmp(async function Gitignore(_props: any) {
12
12
  node_modules/
13
13
 
14
14
  # Build output
15
- dist/
16
- dist-test/
15
+ #
16
+ # dist/ and dist-test/ are COMMITTED, not ignored: the compiled SDK and the
17
+ # compiled test suite are part of the published repo, so a consumer can read
18
+ # and run them straight from a clone without a build step. Only the
19
+ # incremental-build bookkeeping is ignored.
17
20
  *.tsbuildinfo
18
21
 
19
22
  # Coverage
@@ -4,7 +4,7 @@ import * as Path from 'node:path'
4
4
  import {
5
5
  cmp, each, names, cmap,
6
6
  List, File, Content, Copy, Folder, Fragment, Line, FeatureHook,
7
- entityClassName, entityCollection,
7
+ entityClassName, entityCollection, srcFeatureExcludes,
8
8
  } from '@voxgig/sdkgen'
9
9
 
10
10
 
@@ -43,6 +43,9 @@ const Main = cmp(async function Main(props: any) {
43
43
 
44
44
  Copy({
45
45
  from: 'tm/' + target.name,
46
+ // Root copies src/feature/<name>/ per ACTIVE feature; keep this blanket
47
+ // copy from restoring one that was switched off after `target add`.
48
+ exclude: srcFeatureExcludes(model),
46
49
  replace: {
47
50
  ...props.ctx$.stdrep,
48
51
  }
@@ -11,6 +11,7 @@ import {
11
11
  repoInfo,
12
12
  PUBLISHER,
13
13
  PUBLISHER_URL,
14
+ packageVersion,
14
15
  } from '@voxgig/sdkgen'
15
16
 
16
17
 
@@ -54,7 +55,7 @@ const Package = cmp(async function Package(props: any) {
54
55
 
55
56
  const pkg = {
56
57
  name: packageName(model, 'npm'),
57
- version: `0.0.1`,
58
+ version: packageVersion(model, target.name),
58
59
  description: pkgDescription(model, target.name),
59
60
  keywords: keywords(model),
60
61
  homepage: `${repoUrl}#readme`,
@@ -63,6 +64,14 @@ const Package = cmp(async function Package(props: any) {
63
64
  main: `dist/${SdkName}SDK.js`,
64
65
  type: 'commonjs',
65
66
  types: `dist/${SdkName}SDK.d.ts`,
67
+
68
+ // What actually ships. Without `files`, `npm publish` packs everything
69
+ // not gitignored — the test suite, dist-test/, the Makefile, the agent
70
+ // guides — into the published tarball. `src` IS included: the emitted
71
+ // .js.map files point back at it, so shipping it is what makes stack
72
+ // traces in a consumer resolve to SDK source. README/LICENSE/package.json
73
+ // are always included by npm and need no entry.
74
+ files: ['dist', 'src'],
66
75
  scripts: {
67
76
  // `test` and `test-coverage` run the COMPILED suite in dist-test/, which
68
77
  // a fresh clone does not have — the glob then matches nothing and the
@@ -1,5 +1,5 @@
1
1
 
2
- import { cmp, each, Content, canonToType, entityIdField, opRequestShape, safeVarName, exampleVarName, jsKey } from '@voxgig/sdkgen'
2
+ import { cmp, each, Content, canonToType, entityIdField, opRequestShape, safeVarName, exampleVarName, jsKey, matchArg, idLiteral } from '@voxgig/sdkgen'
3
3
 
4
4
  import {
5
5
  KIT,
@@ -12,6 +12,17 @@ import { exampleValue } from './utility_ts'
12
12
  // Operation method spelling differs between Go and other languages — Go
13
13
  // uses PascalCase methods with explicit ctrl arg, others use lowercase
14
14
  // methods with optional ctrl. The op descriptions are language-agnostic.
15
+ // A `list()` on a NESTED entity needs its parent path params. The
16
+ // quickstart used to emit `client.Moon().list()` for an entity at
17
+ // `/planet/{planet_id}/moon`, which 404s against a live server from a
18
+ // half-built URL — indistinguishable from "no such record". The model
19
+ // already marks those params `reqd: true`; matchArg renders exactly them.
20
+ function listMatchArg(ent: any): string {
21
+ const idF = entityIdField(ent)
22
+ return matchArg('ts', ent, 'list', idF, idLiteral(ent, 'list', idF))
23
+ }
24
+
25
+
15
26
  const OP_DESC: Record<string, { method: string, desc: string }> = {
16
27
  load: { method: 'load(match)', desc: 'Load a single entity by match criteria.' },
17
28
  list: { method: 'list(match)', desc: 'List entities matching the criteria.' },
@@ -124,7 +135,7 @@ const ${eVar} = await client.${entity.Name}().load(${loadArg})
124
135
  Content(`#### Example: List
125
136
 
126
137
  \`\`\`ts
127
- const ${eVar}s = await client.${entity.Name}().list()
138
+ const ${eVar}s = await client.${entity.Name}().list(${listMatchArg(entity)})
128
139
  \`\`\`
129
140
 
130
141
  `)
@@ -67,7 +67,8 @@ const ReadmeHowto = cmp(function ReadmeHowto(props: any) {
67
67
  // A direct()-only SDK (no ops anywhere) shows a direct() test call instead.
68
68
  const testModeExample = primaryOp
69
69
  ? `const ${eVar} = await client.${eName}().${primaryOp}(${testCallArg})
70
- // ${eVar} is a bare entity populated with mock response data
70
+ // ${eVar} is the entity, populated with mock response data
71
+ // — call ${eVar}.data() for the record itself
71
72
  console.log(${eVar})`
72
73
  : `const result = await client.direct({ path: '/api/resource', method: 'GET' })
73
74
  console.log(result)`
@@ -1,5 +1,5 @@
1
1
 
2
- import { cmp, each, Content, isAuthActive, packageName, envName, opRequestShape, entityIdField, entityDataIdField, entityOps, safeVarName, exampleVarName, jsKey } from '@voxgig/sdkgen'
2
+ import { cmp, each, Content, isAuthActive, packageName, envName, opRequestShape, entityIdField, entityDataIdField, entityOps, 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_ts'
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 ReadmeQuick = cmp(function ReadmeQuick(props: any) {
14
25
  const { target, ctx$: { model } } = props
15
26
 
@@ -63,10 +74,12 @@ const client = ${ctor}
63
74
  if (opnames.includes('list')) {
64
75
  Content(`### 2. List ${eName.toLowerCase()} records
65
76
 
66
- \`list()\` resolves to an array of ${eName} objectsiterate it directly:
77
+ \`list()\` resolves to an array of ${eName} ENTITIESevery operation
78
+ resolves to entities, not raw records. Iterate them directly, and call
79
+ \`.data()\` on one for the record it holds:
67
80
 
68
81
  \`\`\`ts
69
- const ${eVar}s = await client.${eName}().list()
82
+ const ${eVar}s = await client.${eName}().list(${listMatchArg(exampleEntity)})
70
83
 
71
84
  for (const ${eVar} of ${eVar}s) {
72
85
  console.log(${eVar})
@@ -195,8 +208,10 @@ try {
195
208
  const matchType = matchItem ? matchItem.type : null
196
209
  return null == matchType || null == dataIdType || matchType === dataIdType
197
210
  }
211
+ // `create` resolves to the ENTITY, so the id is reached through
212
+ // `.data()` — `created.id` is a TS2339 on the entity class.
198
213
  const idValueFor = (opname: string): string => usesCreatedId(opname)
199
- ? `created.${dataIdF}!`
214
+ ? `created.data().${dataIdF}!`
200
215
  : exampleValue(exampleEntity, exampleEntity.op[opname], idF as string, 'example_id')
201
216
 
202
217
  Content(`### 4. Create, update, and remove
@@ -206,7 +221,7 @@ try {
206
221
  if (opnames.includes('create')) {
207
222
  const createLines = exampleFields('create')
208
223
  const createBody = createLines.length ? '\n' + createLines.join('\n') + '\n' : ''
209
- Content(`// Create — returns the created ${eName}
224
+ Content(`// Create — returns the created ${eName} ENTITY (.data() for the record)
210
225
  const created = await client.${eName}().create({${createBody}})
211
226
 
212
227
  `)
@@ -216,7 +231,7 @@ const created = await client.${eName}().create({${createBody}})
216
231
  // type carries one, else a literal), plus a couple of patch fields.
217
232
  const updateLines = (idF ? [` ${idF}: ${idValueFor('update')},`] : []).concat(exampleFields('update'))
218
233
  const updateBody = updateLines.length ? '\n' + updateLines.join('\n') + '\n' : ''
219
- Content(`// Update${usesCreatedId('update') ? ' — the id comes straight off the returned entity' : ''}
234
+ Content(`// Update${usesCreatedId('update') ? ' — the id comes off the returned entity\'s data()' : ''}
220
235
  const updated = await client.${eName}().update({${updateBody}})
221
236
 
222
237
  `)
@@ -1,5 +1,5 @@
1
1
 
2
- import { cmp, each, Content, canonToType, File, isAuthActive, entityIdField, opRequestShape, safeVarName, exampleVarName, jsKey } from '@voxgig/sdkgen'
2
+ import { cmp, each, Content, canonToType, File, isAuthActive, entityIdField, entityActions, opRequestShape, safeVarName, exampleVarName, jsKey, matchArg, idLiteral } from '@voxgig/sdkgen'
3
3
 
4
4
  import {
5
5
  KIT,
@@ -9,6 +9,17 @@ import {
9
9
  import { exampleValue } from './utility_ts'
10
10
 
11
11
 
12
+ // A `list()` on a NESTED entity needs its parent path params. The
13
+ // quickstart used to emit `client.Moon().list()` for an entity at
14
+ // `/planet/{planet_id}/moon`, which 404s against a live server from a
15
+ // half-built URL — indistinguishable from "no such record". The model
16
+ // already marks those params `reqd: true`; matchArg renders exactly them.
17
+ function listMatchArg(ent: any): string {
18
+ const idF = entityIdField(ent)
19
+ return matchArg('ts', ent, 'list', idF, idLiteral(ent, 'list', idF))
20
+ }
21
+
22
+
12
23
  const OP_SIGNATURES: Record<string, { sig: string, returns: string, desc: string }> = {
13
24
  load: {
14
25
  sig: 'load(match: object, ctrl?: object)',
@@ -254,6 +265,45 @@ const ${eVar} = client.${ent.Name}()
254
265
  }
255
266
 
256
267
 
268
+ // Custom actions.
269
+ //
270
+ // A POST route like `/api/planet/{id}/terraform` is folded into the
271
+ // `create` op as an alternative point, selected at call time by
272
+ // `$action`. The mechanism was implemented and documented NOWHERE — so
273
+ // for an API with two such routes, two of its six endpoints were
274
+ // unreachable by anyone reading the docs. A user who wanted `terraform`
275
+ // had to fall back to `direct()` and rebuild the URL by hand, which is
276
+ // exactly what the entity model exists to spare them.
277
+ const actions = entityActions(ent)
278
+ if (0 < actions.length) {
279
+ Content(`### Actions
280
+
281
+ This entity exposes custom API actions in addition to the standard
282
+ operations. Select one with \`$action\` in the call's argument; the
283
+ remaining keys are sent as that action's payload.
284
+
285
+ | Action | Route | Call |
286
+ | --- | --- | --- |
287
+ `)
288
+ actions.forEach((a: any) => {
289
+ Content(`| \`${a.action}\` | \`${a.path}\` | \`client.${ent.Name}().${a.op}({ $action: '${a.action}', ... })\` |
290
+ `)
291
+ })
292
+
293
+ Content(`
294
+ An action returns that action's OWN response, which is not necessarily a
295
+ ${ent.Name} record — check the API definition for its shape.
296
+
297
+ \`\`\`ts
298
+ const result = await client.${ent.Name}().${actions[0].op}({
299
+ $action: '${actions[0].action}',
300
+ /* ...the action's own arguments */
301
+ })
302
+ \`\`\`
303
+
304
+ `)
305
+ }
306
+
257
307
  // Operation details
258
308
  if (opnames.length > 0) {
259
309
  Content(`### Operations
@@ -292,7 +342,7 @@ const result = await client.${ent.Name}().${opname}(${arg})
292
342
  }
293
343
  else if ('list' === opname) {
294
344
  Content(`\`\`\`ts
295
- const results = await client.${ent.Name}().${opname}()
345
+ const results = await client.${ent.Name}().${opname}(${listMatchArg(ent)})
296
346
  \`\`\`
297
347
 
298
348
  `)
@@ -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_ts'
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,8 +47,8 @@ const client = ${ctor}
36
47
  let hasCall = false
37
48
 
38
49
  if (opnames.includes('list')) {
39
- Content(`// List all ${eName.toLowerCase()}s (returns ${eName}[])
40
- const ${eVar}s = await client.${eName}().list()
50
+ Content(`// List all ${eName.toLowerCase()}s (returns ${eName}Entity[] — .data() for the record)
51
+ const ${eVar}s = await client.${eName}().list(${listMatchArg(exampleEntity)})
41
52
  for (const ${eVar} of ${eVar}s) {
42
53
  console.log(${eVar})
43
54
  }
@@ -18,8 +18,39 @@ const ReadmeTopTest = cmp(function ReadmeTopTest(props: any) {
18
18
  // `load` on an op-less entity like Cloudsmith's `Abort`.
19
19
  const { entity: exampleEntity, primaryOp } = pickExampleEntity(entity)
20
20
 
21
+ // The mock SEEDS NOTHING on its own.
22
+ //
23
+ // `SDK.test()` with no argument used to be shown alongside "populated with
24
+ // mock data" — and returned an empty array. The seed shape
25
+ // (`{ entity: { <name>: { <id>: {...} } } }`) was documented nowhere; the
26
+ // only way to find it was to read TestFeature.ts. Offline test mode is a
27
+ // headline feature of these SDKs, so its one worked example has to run.
28
+ const seedEntity = exampleEntity ? nom(exampleEntity, 'name') : ''
29
+ const seedFields = exampleEntity ?
30
+ opRequestShape(exampleEntity, 'create').items
31
+ .filter((it: any) => !it.optional)
32
+ .slice(0, 3) : []
33
+
34
+ const seedId = 'test01'
35
+ const seedBody = [
36
+ `${jsKey('id')}: '${seedId}'`,
37
+ ...seedFields
38
+ .filter((it: any) => 'id' !== it.name)
39
+ .map((it: any) => `${jsKey(it.name)}: ${exampleValue(
40
+ exampleEntity, exampleEntity.op && exampleEntity.op.create, it.name,
41
+ 'example_' + it.name)}`),
42
+ ].join(', ')
43
+
21
44
  Content(`\`\`\`ts
22
- const client = ${model.const.Name}SDK.test()
45
+ // The offline mock starts EMPTY — seed it with the records the test needs.
46
+ // Shape: { entity: { <entity-name>: { <id>: <record> } } }
47
+ const client = ${model.const.Name}SDK.test({
48
+ entity: {
49
+ ${seedEntity}: {
50
+ ${seedId}: { ${seedBody} },
51
+ },
52
+ },
53
+ })
23
54
  `)
24
55
 
25
56
  if (exampleEntity && primaryOp) {
@@ -51,7 +82,8 @@ const client = ${model.const.Name}SDK.test()
51
82
  `${jsKey(it.name)}: ${exampleValue(exampleEntity, primaryOpDef, it.name, 'example_' + it.name)}`).join(', ')} }`
52
83
  }
53
84
  Content(`const ${eVar} = await client.${eName}().${primaryOp}(${arg})
54
- // ${eVar} is ${'list' === primaryOp ? `an array of bare ${eName} records` : `a bare ${eName}`} populated with mock data
85
+ // ${eVar} is ${'list' === primaryOp ? `an array of ${eName} entities` : `the ${eName} entity`}, populated with mock data
86
+ // — call ${eVar}${'list' === primaryOp ? '[0]' : ''}.data() for the record itself
55
87
  console.log(${eVar})
56
88
  `)
57
89
  }
@@ -18,7 +18,7 @@ import {
18
18
  snakify,
19
19
  isAuthActive,
20
20
  jsProp,
21
- jsOptProp,
21
+ jsOptProp, envName, envToken, liveStrict
22
22
  } from '@voxgig/sdkgen'
23
23
 
24
24
 
@@ -37,8 +37,11 @@ const TestDirect = cmp(function TestDirect(props: any) {
37
37
 
38
38
  const ff = projectPath('src/cmp/ts/fragment/')
39
39
 
40
- const PROJECTNAME = nom(model, 'Name').toUpperCase().replace(/[^A-Z_]/g, '_')
41
- const entidEnvVar = `${PROJECTNAME}_TEST_${nom(entity, 'NAME').replace(/[^A-Z_]/g, '_')}_ENTID`
40
+ // Does a live run ASSERT, or merely observe? See helpers/testPolicy.
41
+ const strict = liveStrict(model, target.name)
42
+
43
+ const PROJECTNAME = envName(model)
44
+ const entidEnvVar = `${PROJECTNAME}_TEST_${envToken(entity.name)}_ENTID`
42
45
 
43
46
  const authActive = isAuthActive(model)
44
47
  const apikeyEnvEntry = authActive
@@ -136,11 +139,11 @@ function unwrapListData(data: any): any[] | null {
136
139
  Slot({ name: 'direct' }, () => {
137
140
 
138
141
  if (hasLoad) {
139
- generateDirectLoad(model, entity)
142
+ generateDirectLoad(model, entity, strict)
140
143
  }
141
144
 
142
145
  if (hasList) {
143
- generateDirectList(model, entity)
146
+ generateDirectList(model, entity, strict)
144
147
  }
145
148
  })
146
149
 
@@ -150,7 +153,7 @@ function unwrapListData(data: any): any[] | null {
150
153
  })
151
154
 
152
155
 
153
- function generateDirectLoad(model: Model, entity: ModelEntity) {
156
+ function generateDirectLoad(model: Model, entity: ModelEntity, strict: boolean) {
154
157
  const loadOp = entity.op?.load
155
158
  const loadPoint: ModelPoint | undefined = loadOp?.points?.[0]
156
159
 
@@ -318,6 +321,31 @@ ${loadParams.map((p: any, i: number) => ` ${jsProp('params', p.name)} = 'di
318
321
  ? ` if (skipIfMissingIds(t, setup, ${JSON.stringify(liveIdKeys)})) return\n`
319
322
  : ''
320
323
 
324
+ // Live-mode leniency is a MODEL decision (main.kit.test.live.strict).
325
+ // The default stays lenient: a fleet SDK generated against an arbitrary
326
+ // public API 4xxes on synthetic IDs, and asserting would mean permanent
327
+ // red. A project that owns its test server wants the opposite — without
328
+ // it, the suite passes with nothing listening on the port.
329
+ const offlineChecks = ` assert(result.ok === true)
330
+ assert(result.status === 200)
331
+ assert(null != result.data)
332
+ assert(result.data.id === 'direct01')
333
+ assert(calls.length === 1)
334
+ assert(calls[0].init.method === 'GET')
335
+ ${paramAsserts}`
336
+
337
+ const loadChecks = strict ?
338
+ offlineChecks.replace(/^ {6}/gm, ' ').replace(/^ {4}$/gm, '') :
339
+ ` if (setup.live) {
340
+ // Live mode is lenient: synthetic IDs frequently 4xx. Skip rather
341
+ // than fail when the load endpoint isn't reachable with the IDs we
342
+ // can construct from setup.idmap.
343
+ if (!result.ok || result.status < 200 || result.status >= 300) {
344
+ return
345
+ }
346
+ } else {
347
+ ${offlineChecks} }`
348
+
321
349
  Content(`
322
350
  test('direct-load-${entity.name}', async (t: any) => {
323
351
  const setup = directSetup({ id: 'direct01' })
@@ -335,27 +363,13 @@ ${liveParamsBlock}
335
363
  query,
336
364
  })
337
365
 
338
- if (setup.live) {
339
- // Live mode is lenient: synthetic IDs frequently 4xx. Skip rather
340
- // than fail when the load endpoint isn't reachable with the IDs we
341
- // can construct from setup.idmap.
342
- if (!result.ok || result.status < 200 || result.status >= 300) {
343
- return
344
- }
345
- } else {
346
- assert(result.ok === true)
347
- assert(result.status === 200)
348
- assert(null != result.data)
349
- assert(result.data.id === 'direct01')
350
- assert(calls.length === 1)
351
- assert(calls[0].init.method === 'GET')
352
- ${paramAsserts} }
366
+ ${loadChecks}
353
367
  })
354
368
  `)
355
369
  }
356
370
 
357
371
 
358
- function generateDirectList(model: Model, entity: ModelEntity) {
372
+ function generateDirectList(model: Model, entity: ModelEntity, strict: boolean) {
359
373
  const listOp = entity.op?.list
360
374
  const listPoint: ModelPoint | undefined = listOp?.points?.[0]
361
375
 
@@ -418,6 +432,33 @@ ${mockLines}
418
432
  ? ` if (skipIfMissingIds(t, setup, ${JSON.stringify(liveIdKeys)})) return\n`
419
433
  : ''
420
434
 
435
+ // See generateDirectLoad: leniency is main.kit.test.live.strict.
436
+ const offlineChecks = ` assert(result.ok === true)
437
+ assert(result.status === 200)
438
+ assert(null != result.data)
439
+ const listArr = unwrapListData(result.data)
440
+ assert(Array.isArray(listArr))
441
+ assert(listArr!.length === 2)
442
+ assert(calls.length === 1)
443
+ assert(calls[0].init.method === 'GET')
444
+ ${paramAsserts}`
445
+
446
+ const listChecks = strict ?
447
+ offlineChecks.replace(/^ {6}/gm, ' ').replace(/^ {4}$/gm, '') :
448
+ ` if (setup.live) {
449
+ // Live mode is lenient: synthetic IDs frequently 4xx and the list-
450
+ // response shape varies wildly across public APIs. Skip rather than
451
+ // fail when the call doesn't return a usable list.
452
+ if (!result.ok || result.status < 200 || result.status >= 300) {
453
+ return
454
+ }
455
+ const listArr = unwrapListData(result.data)
456
+ if (!Array.isArray(listArr)) {
457
+ return
458
+ }
459
+ } else {
460
+ ${offlineChecks} }`
461
+
421
462
  Content(`
422
463
  test('direct-list-${entity.name}', async (t: any) => {
423
464
  const setup = directSetup([{ id: 'direct01' }, { id: 'direct02' }])
@@ -432,27 +473,7 @@ ${paramsBlock}
432
473
  query,
433
474
  })
434
475
 
435
- if (setup.live) {
436
- // Live mode is lenient: synthetic IDs frequently 4xx and the list-
437
- // response shape varies wildly across public APIs. Skip rather than
438
- // fail when the call doesn't return a usable list.
439
- if (!result.ok || result.status < 200 || result.status >= 300) {
440
- return
441
- }
442
- const listArr = unwrapListData(result.data)
443
- if (!Array.isArray(listArr)) {
444
- return
445
- }
446
- } else {
447
- assert(result.ok === true)
448
- assert(result.status === 200)
449
- assert(null != result.data)
450
- const listArr = unwrapListData(result.data)
451
- assert(Array.isArray(listArr))
452
- assert(listArr!.length === 2)
453
- assert(calls.length === 1)
454
- assert(calls[0].init.method === 'GET')
455
- ${paramAsserts} }
476
+ ${listChecks}
456
477
  })
457
478
  `)
458
479
  }
@@ -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
 
@@ -61,8 +61,8 @@ const TestEntity = cmp(function TestEntity(props: any) {
61
61
  const target = props.target
62
62
  const entity: ModelEntity = props.entity
63
63
 
64
- const PROJENVNAME = nom(model.const, 'NAME').replace(/[^A-Z_]/g, '_')
65
- const ENTENVNAME = nom(entity, 'NAME').replace(/[^A-Z_]/g, '_')
64
+ const PROJENVNAME = envName(model)
65
+ const ENTENVNAME = envToken(entity.name)
66
66
  const authActive = isAuthActive(model)
67
67
  const apikeyEnvEntry = authActive
68
68
  ? `\n '${PROJENVNAME}_APIKEY': 'NONE',`
@@ -300,7 +300,7 @@ const generateCreate: OpGen = (ctx, step, index) => {
300
300
  const hasEntIdC = null != entity.id
301
301
 
302
302
  Content(`
303
- ${datavar} = await ${entvar}.create(${datavar})
303
+ ${datavar} = (await ${entvar}.create(${datavar})).data()
304
304
  `)
305
305
  if (hasEntIdC) {
306
306
  Content(` assert(null != ${datavar}.id)
@@ -341,7 +341,7 @@ const generateList: OpGen = (ctx, step, index) => {
341
341
  })
342
342
 
343
343
  Content(`
344
- const ${listvar} = await ${entvar}.list(${matchvar})
344
+ const ${listvar} = (await ${entvar}.list(${matchvar})).map((e: any) => e.data())
345
345
  `)
346
346
  const allSteps = flow.step
347
347
  for (let vI = 0; vI < step.valid.length; vI++) {
@@ -420,7 +420,7 @@ const generateUpdate: OpGen = (ctx, step, index) => {
420
420
  }
421
421
 
422
422
  Content(`
423
- const ${resdatavar} = await ${entvar}.update(${datavar})
423
+ const ${resdatavar} = (await ${entvar}.update(${datavar})).data()
424
424
  `)
425
425
  if (hasEntIdU) {
426
426
  Content(` assert(${resdatavar}.id === ${datavar}.id)
@@ -508,13 +508,13 @@ const generateLoad: OpGen = (ctx, step, index) => {
508
508
  if (hasEntId) {
509
509
  Content(` const ${matchvar}: any = {}
510
510
  ${matchvar}.id = ${srcdatavar}.id
511
- const ${datavar} = await ${entvar}.load(${matchvar})
511
+ const ${datavar} = (await ${entvar}.load(${matchvar})).data()
512
512
  assert(${datavar}.id === ${srcdatavar}.id)
513
513
  `)
514
514
  }
515
515
  else {
516
516
  Content(` const ${matchvar}: any = {}
517
- const ${datavar} = await ${entvar}.load(${matchvar})
517
+ const ${datavar} = (await ${entvar}.load(${matchvar})).data()
518
518
  assert(null != ${datavar})
519
519
  `)
520
520
  }
@@ -19,8 +19,8 @@ import {
19
19
  describe('EntityNameDirect', async () => {
20
20
 
21
21
  // Per-test live pacing. Delay is read from sdk-test-control.json's
22
- // `test.live.delayMs`; only sleeps when PROJECTNAME_TEST_LIVE=TRUE.
23
- afterEach(liveDelay('PROJECTNAME_TEST_LIVE'))
22
+ // `test.live.delayMs`; only sleeps when PROJECTENV_TEST_LIVE=TRUE.
23
+ afterEach(liveDelay('PROJECTENV_TEST_LIVE'))
24
24
 
25
25
  test('direct-exists', async () => {
26
26
  const sdk = new ProjectNameSDK({
@@ -26,8 +26,8 @@ import {
26
26
  describe('EntityNameEntity', async () => {
27
27
 
28
28
  // Per-test live pacing. Delay is read from sdk-test-control.json's
29
- // `test.live.delayMs`; only sleeps when PROJECTNAME_TEST_LIVE=TRUE.
30
- afterEach(liveDelay('PROJECTNAME_TEST_LIVE'))
29
+ // `test.live.delayMs`; only sleeps when PROJECTENV_TEST_LIVE=TRUE.
30
+ afterEach(liveDelay('PROJECTENV_TEST_LIVE'))
31
31
 
32
32
  test('instance', async () => {
33
33
  const testsdk = ProjectNameSDK.test()
@@ -32,6 +32,11 @@ class ProjectNameEntityBase<D = any> {
32
32
  _match: Partial<D>
33
33
  _entctx: Context
34
34
 
35
+ // Set once a successful `remove` resolves on this instance. The entity
36
+ // KEEPS the data it held — a caller can still read what was deleted — but
37
+ // it is no longer a live record.
38
+ _deleted: boolean
39
+
35
40
 
36
41
  constructor(client: ProjectNameSDK, entopts: any) {
37
42
  entopts = entopts || {}
@@ -42,6 +47,7 @@ class ProjectNameEntityBase<D = any> {
42
47
  this._utility = client.utility()
43
48
  this._data = {}
44
49
  this._match = {}
50
+ this._deleted = false
45
51
 
46
52
  const makeContext = this._utility.makeContext
47
53
 
@@ -54,6 +60,19 @@ class ProjectNameEntityBase<D = any> {
54
60
  featureHook(this._entctx, 'PostConstructEntity')
55
61
  }
56
62
 
63
+ // True once `remove` has succeeded on this instance. `remove` resolves to
64
+ // the entity like every other operation, so this is how a caller tells a
65
+ // removed record from a live one.
66
+ markDeleted(this: any): void {
67
+ this._deleted = true
68
+ }
69
+
70
+
71
+ deleted(this: any): boolean {
72
+ return true === this._deleted
73
+ }
74
+
75
+
57
76
  entopts() {
58
77
  return this._utility.struct.merge([{}, this._entopts])
59
78
  }
@@ -178,7 +197,12 @@ class ProjectNameEntityBase<D = any> {
178
197
 
179
198
  toJSON() {
180
199
  const struct = this._utility.struct
181
- return struct.merge([{}, struct.getdef(this._data, {}), { entity$: this.Name }])
200
+ // The marker is NAMESPACED. It used to be `entity$` a short, generic
201
+ // name, and the `$`-suffix convention is not unique to sdkgen. Seneca uses
202
+ // `entity$` on its own entities to hold the canon, so an SDK record fed
203
+ // into `entize` silently overwrote it and produced entities claiming a
204
+ // canon that does not exist: no error, just wrong entities.
205
+ return struct.merge([{}, struct.getdef(this._data, {}), { 'voxgig$entity': this.Name }])
182
206
  }
183
207
 
184
208