@voxgig/sdkgen 2.0.2 → 3.1.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 (403) hide show
  1. package/bin/voxgig-sdkgen +22 -2
  2. package/dist/action/doctor.d.ts +14 -0
  3. package/dist/action/doctor.js +351 -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/ExternalTarget.d.ts +2 -0
  13. package/dist/cmp/ExternalTarget.js +104 -0
  14. package/dist/cmp/ExternalTarget.js.map +1 -0
  15. package/dist/cmp/Feature.js +2 -1
  16. package/dist/cmp/Feature.js.map +1 -1
  17. package/dist/cmp/Main.js +5 -1
  18. package/dist/cmp/Main.js.map +1 -1
  19. package/dist/cmp/ReadmeExplanation.js +1 -1
  20. package/dist/cmp/ReadmeExplanation.js.map +1 -1
  21. package/dist/cmp/ReadmeTop.js +16 -6
  22. package/dist/cmp/ReadmeTop.js.map +1 -1
  23. package/dist/cmp/Registered.d.ts +7 -0
  24. package/dist/cmp/Registered.js +70 -0
  25. package/dist/cmp/Registered.js.map +1 -0
  26. package/dist/cmp/Test.js +3 -1
  27. package/dist/cmp/Test.js.map +1 -1
  28. package/dist/helpers/dryrun.d.ts +10 -0
  29. package/dist/helpers/dryrun.js +35 -0
  30. package/dist/helpers/dryrun.js.map +1 -0
  31. package/dist/helpers/featureSource.d.ts +13 -0
  32. package/dist/helpers/featureSource.js +156 -0
  33. package/dist/helpers/featureSource.js.map +1 -0
  34. package/dist/helpers/naming.d.ts +9 -1
  35. package/dist/helpers/naming.js +66 -2
  36. package/dist/helpers/naming.js.map +1 -1
  37. package/dist/helpers/opExample.js +23 -3
  38. package/dist/helpers/opExample.js.map +1 -1
  39. package/dist/helpers/opShape.d.ts +11 -1
  40. package/dist/helpers/opShape.js +51 -0
  41. package/dist/helpers/opShape.js.map +1 -1
  42. package/dist/helpers/packageMeta.d.ts +16 -1
  43. package/dist/helpers/packageMeta.js +181 -10
  44. package/dist/helpers/packageMeta.js.map +1 -1
  45. package/dist/helpers/stdrep.d.ts +3 -0
  46. package/dist/helpers/stdrep.js +47 -0
  47. package/dist/helpers/stdrep.js.map +1 -0
  48. package/dist/helpers/testPolicy.d.ts +2 -0
  49. package/dist/helpers/testPolicy.js +46 -0
  50. package/dist/helpers/testPolicy.js.map +1 -0
  51. package/dist/sdkgen.d.ts +15 -6
  52. package/dist/sdkgen.js +273 -5
  53. package/dist/sdkgen.js.map +1 -1
  54. package/dist/tsconfig.tsbuildinfo +1 -1
  55. package/dist/types.d.ts +12 -0
  56. package/dist/utility.js +10 -1
  57. package/dist/utility.js.map +1 -1
  58. package/model/sdkgen.aontu +245 -0
  59. package/package.json +5 -3
  60. package/project/.sdk/model/target/c.aontu +28 -3
  61. package/project/.sdk/model/target/clojure.aontu +24 -3
  62. package/project/.sdk/model/target/cpp.aontu +25 -3
  63. package/project/.sdk/model/target/csharp.aontu +25 -3
  64. package/project/.sdk/model/target/dart.aontu +15 -3
  65. package/project/.sdk/model/target/elixir.aontu +15 -3
  66. package/project/.sdk/model/target/go-cli.aontu +16 -1
  67. package/project/.sdk/model/target/go-mcp.aontu +16 -1
  68. package/project/.sdk/model/target/go.aontu +14 -4
  69. package/project/.sdk/model/target/haskell.aontu +24 -3
  70. package/project/.sdk/model/target/java.aontu +25 -3
  71. package/project/.sdk/model/target/js.aontu +15 -3
  72. package/project/.sdk/model/target/kotlin.aontu +25 -3
  73. package/project/.sdk/model/target/lean.aontu +24 -3
  74. package/project/.sdk/model/target/lua.aontu +15 -3
  75. package/project/.sdk/model/target/ocaml.aontu +24 -3
  76. package/project/.sdk/model/target/perl.aontu +15 -3
  77. package/project/.sdk/model/target/php.aontu +15 -3
  78. package/project/.sdk/model/target/py-data.aontu +15 -3
  79. package/project/.sdk/model/target/py.aontu +15 -3
  80. package/project/.sdk/model/target/rb.aontu +15 -3
  81. package/project/.sdk/model/target/rust.aontu +25 -3
  82. package/project/.sdk/model/target/scala.aontu +24 -3
  83. package/project/.sdk/model/target/seneca-provider.aontu +118 -0
  84. package/project/.sdk/model/target/swift.aontu +25 -3
  85. package/project/.sdk/model/target/ts.aontu +15 -3
  86. package/project/.sdk/model/target/zig.aontu +25 -3
  87. package/project/.sdk/src/cmp/c/Config_c.ts +10 -11
  88. package/project/.sdk/src/cmp/c/Entity_c.ts +5 -1
  89. package/project/.sdk/src/cmp/c/fragment/Entity.fragment.c +23 -5
  90. package/project/.sdk/src/cmp/c/fragment/EntityCreateOp.fragment.c +9 -2
  91. package/project/.sdk/src/cmp/c/fragment/EntityListOp.fragment.c +19 -2
  92. package/project/.sdk/src/cmp/c/fragment/EntityLoadOp.fragment.c +9 -2
  93. package/project/.sdk/src/cmp/c/fragment/EntityRemoveOp.fragment.c +12 -2
  94. package/project/.sdk/src/cmp/c/fragment/EntityUpdateOp.fragment.c +9 -2
  95. package/project/.sdk/src/cmp/c/fragment/Main.fragment.c +1 -0
  96. package/project/.sdk/src/cmp/clojure/TestEntity_clojure.ts +6 -3
  97. package/project/.sdk/src/cmp/clojure/fragment/Entity.fragment.clj +18 -1
  98. package/project/.sdk/src/cmp/clojure/fragment/EntityCreateOp.fragment.clj +2 -2
  99. package/project/.sdk/src/cmp/clojure/fragment/EntityLoadOp.fragment.clj +2 -2
  100. package/project/.sdk/src/cmp/clojure/fragment/EntityRemoveOp.fragment.clj +12 -8
  101. package/project/.sdk/src/cmp/clojure/fragment/EntityUpdateOp.fragment.clj +2 -2
  102. package/project/.sdk/src/cmp/cpp/Entity_cpp.ts +5 -1
  103. package/project/.sdk/src/cmp/cpp/TestEntity_cpp.ts +12 -9
  104. package/project/.sdk/src/cmp/cpp/fragment/EntityCreateOp.fragment.cpp +8 -2
  105. package/project/.sdk/src/cmp/cpp/fragment/EntityListOp.fragment.cpp +18 -2
  106. package/project/.sdk/src/cmp/cpp/fragment/EntityLoadOp.fragment.cpp +8 -2
  107. package/project/.sdk/src/cmp/cpp/fragment/EntityRemoveOp.fragment.cpp +11 -2
  108. package/project/.sdk/src/cmp/cpp/fragment/EntityUpdateOp.fragment.cpp +8 -2
  109. package/project/.sdk/src/cmp/csharp/Package_csharp.ts +2 -1
  110. package/project/.sdk/src/cmp/csharp/TestDirect_csharp.ts +3 -3
  111. package/project/.sdk/src/cmp/csharp/TestEntity_csharp.ts +6 -6
  112. package/project/.sdk/src/cmp/csharp/fragment/EntityBase.fragment.cs +38 -1
  113. package/project/.sdk/src/cmp/csharp/fragment/Main.fragment.cs +42 -33
  114. package/project/.sdk/src/cmp/dart/Package_dart.ts +2 -1
  115. package/project/.sdk/src/cmp/dart/ReadmeEntity_dart.ts +13 -2
  116. package/project/.sdk/src/cmp/dart/ReadmeHowto_dart.ts +2 -1
  117. package/project/.sdk/src/cmp/dart/ReadmeInstall_dart.ts +3 -3
  118. package/project/.sdk/src/cmp/dart/ReadmeModel_dart.ts +1 -1
  119. package/project/.sdk/src/cmp/dart/ReadmeQuick_dart.ts +17 -6
  120. package/project/.sdk/src/cmp/dart/ReadmeRef_dart.ts +13 -2
  121. package/project/.sdk/src/cmp/dart/ReadmeTopQuick_dart.ts +13 -2
  122. package/project/.sdk/src/cmp/dart/TestDirect_dart.ts +3 -3
  123. package/project/.sdk/src/cmp/dart/TestEntity_dart.ts +8 -8
  124. package/project/.sdk/src/cmp/dart/fragment/EntityBase.fragment.dart +18 -1
  125. package/project/.sdk/src/cmp/dart/fragment/EntityCreateOp.fragment.dart +9 -1
  126. package/project/.sdk/src/cmp/dart/fragment/EntityLoadOp.fragment.dart +9 -1
  127. package/project/.sdk/src/cmp/dart/fragment/EntityRemoveOp.fragment.dart +15 -1
  128. package/project/.sdk/src/cmp/dart/fragment/EntityUpdateOp.fragment.dart +9 -1
  129. package/project/.sdk/src/cmp/dart/fragment/SdkError.fragment.dart +8 -0
  130. package/project/.sdk/src/cmp/elixir/Package_elixir.ts +3 -1
  131. package/project/.sdk/src/cmp/elixir/ReadmeInstall_elixir.ts +2 -2
  132. package/project/.sdk/src/cmp/elixir/TestEntity_elixir.ts +11 -2
  133. package/project/.sdk/src/cmp/elixir/fragment/EntityCreateOp.fragment.ex +2 -1
  134. package/project/.sdk/src/cmp/elixir/fragment/EntityListOp.fragment.ex +1 -0
  135. package/project/.sdk/src/cmp/elixir/fragment/EntityLoadOp.fragment.ex +2 -1
  136. package/project/.sdk/src/cmp/elixir/fragment/EntityRemoveOp.fragment.ex +4 -1
  137. package/project/.sdk/src/cmp/elixir/fragment/EntityUpdateOp.fragment.ex +2 -1
  138. package/project/.sdk/src/cmp/go/EntityTypes_go.ts +38 -8
  139. package/project/.sdk/src/cmp/go/Entity_go.ts +2 -2
  140. package/project/.sdk/src/cmp/go/Main_go.ts +4 -5
  141. package/project/.sdk/src/cmp/go/Package_go.ts +8 -5
  142. package/project/.sdk/src/cmp/go/ReadmeExplanation_go.ts +2 -2
  143. package/project/.sdk/src/cmp/go/ReadmeHowto_go.ts +2 -2
  144. package/project/.sdk/src/cmp/go/ReadmeInstall_go.ts +4 -2
  145. package/project/.sdk/src/cmp/go/ReadmeModel_go.ts +2 -2
  146. package/project/.sdk/src/cmp/go/ReadmeQuick_go.ts +2 -2
  147. package/project/.sdk/src/cmp/go/ReadmeTopQuick_go.ts +2 -2
  148. package/project/.sdk/src/cmp/go/ReadmeTopTest_go.ts +2 -2
  149. package/project/.sdk/src/cmp/go/TestDirect_go.ts +21 -15
  150. package/project/.sdk/src/cmp/go/TestEntity_go.ts +9 -9
  151. package/project/.sdk/src/cmp/go/Test_go.ts +2 -2
  152. package/project/.sdk/src/cmp/go/fragment/Entity.fragment.go +42 -1
  153. package/project/.sdk/src/cmp/go-cli/Main_go-cli.ts +4 -4
  154. package/project/.sdk/src/cmp/go-mcp/Main_go-mcp.ts +4 -4
  155. package/project/.sdk/src/cmp/haskell/Package_haskell.ts +2 -1
  156. package/project/.sdk/src/cmp/haskell/ReadmeEntity_haskell.ts +10 -5
  157. package/project/.sdk/src/cmp/haskell/ReadmeModel_haskell.ts +10 -8
  158. package/project/.sdk/src/cmp/haskell/ReadmeQuick_haskell.ts +14 -10
  159. package/project/.sdk/src/cmp/haskell/ReadmeRef_haskell.ts +21 -18
  160. package/project/.sdk/src/cmp/haskell/ReadmeTopQuick_haskell.ts +4 -4
  161. package/project/.sdk/src/cmp/haskell/Test_haskell.ts +23 -11
  162. package/project/.sdk/src/cmp/java/Package_java.ts +2 -1
  163. package/project/.sdk/src/cmp/java/ReadmeHowto_java.ts +2 -1
  164. package/project/.sdk/src/cmp/java/ReadmeInstall_java.ts +2 -2
  165. package/project/.sdk/src/cmp/java/ReadmeModel_java.ts +1 -1
  166. package/project/.sdk/src/cmp/java/ReadmeQuick_java.ts +3 -3
  167. package/project/.sdk/src/cmp/java/TestDirect_java.ts +3 -3
  168. package/project/.sdk/src/cmp/java/TestEntity_java.ts +6 -6
  169. package/project/.sdk/src/cmp/java/fragment/EntityBase.fragment.java +34 -1
  170. package/project/.sdk/src/cmp/java/fragment/SdkError.fragment.java +12 -0
  171. package/project/.sdk/src/cmp/js/Main_js.ts +4 -1
  172. package/project/.sdk/src/cmp/js/Package_js.ts +7 -1
  173. package/project/.sdk/src/cmp/js/ReadmeEntity_js.ts +13 -2
  174. package/project/.sdk/src/cmp/js/ReadmeHowto_js.ts +2 -1
  175. package/project/.sdk/src/cmp/js/ReadmeQuick_js.ts +13 -2
  176. package/project/.sdk/src/cmp/js/ReadmeTopQuick_js.ts +13 -2
  177. package/project/.sdk/src/cmp/js/ReadmeTopTest_js.ts +2 -1
  178. package/project/.sdk/src/cmp/js/TestDirect_js.ts +3 -3
  179. package/project/.sdk/src/cmp/js/TestEntity_js.ts +8 -8
  180. package/project/.sdk/src/cmp/js/fragment/EntityBase.fragment.js +22 -1
  181. package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +9 -1
  182. package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +9 -1
  183. package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +15 -1
  184. package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +9 -1
  185. package/project/.sdk/src/cmp/js/fragment/SdkError.fragment.js +13 -0
  186. package/project/.sdk/src/cmp/kotlin/Package_kotlin.ts +2 -1
  187. package/project/.sdk/src/cmp/kotlin/ReadmeHowto_kotlin.ts +2 -1
  188. package/project/.sdk/src/cmp/kotlin/ReadmeInstall_kotlin.ts +2 -2
  189. package/project/.sdk/src/cmp/kotlin/ReadmeModel_kotlin.ts +1 -1
  190. package/project/.sdk/src/cmp/kotlin/ReadmeQuick_kotlin.ts +3 -3
  191. package/project/.sdk/src/cmp/kotlin/TestDirect_kotlin.ts +3 -3
  192. package/project/.sdk/src/cmp/kotlin/TestEntity_kotlin.ts +6 -6
  193. package/project/.sdk/src/cmp/kotlin/fragment/EntityBase.fragment.kt +32 -1
  194. package/project/.sdk/src/cmp/lean/Package_lean.ts +3 -1
  195. package/project/.sdk/src/cmp/lua/MainEntity_lua.ts +9 -4
  196. package/project/.sdk/src/cmp/lua/Package_lua.ts +4 -3
  197. package/project/.sdk/src/cmp/lua/ReadmeModel_lua.ts +11 -3
  198. package/project/.sdk/src/cmp/lua/ReadmeQuick_lua.ts +1 -1
  199. package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +3 -3
  200. package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +9 -9
  201. package/project/.sdk/src/cmp/lua/fragment/Entity.fragment.lua +37 -1
  202. package/project/.sdk/src/cmp/lua/fragment/SdkError.fragment.lua +12 -0
  203. package/project/.sdk/src/cmp/ocaml/EntityOperation_ocaml.ts +30 -3
  204. package/project/.sdk/src/cmp/ocaml/Entity_ocaml.ts +11 -5
  205. package/project/.sdk/src/cmp/ocaml/Package_ocaml.ts +3 -1
  206. package/project/.sdk/src/cmp/ocaml/ReadmeEntity_ocaml.ts +10 -5
  207. package/project/.sdk/src/cmp/ocaml/ReadmeHowto_ocaml.ts +6 -2
  208. package/project/.sdk/src/cmp/ocaml/ReadmeModel_ocaml.ts +10 -8
  209. package/project/.sdk/src/cmp/ocaml/ReadmeQuick_ocaml.ts +14 -13
  210. package/project/.sdk/src/cmp/ocaml/ReadmeRef_ocaml.ts +20 -18
  211. package/project/.sdk/src/cmp/ocaml/ReadmeTopQuick_ocaml.ts +4 -4
  212. package/project/.sdk/src/cmp/ocaml/ReadmeTopTest_ocaml.ts +8 -2
  213. package/project/.sdk/src/cmp/ocaml/TestEntity_ocaml.ts +8 -5
  214. package/project/.sdk/src/cmp/perl/ReadmeHowto_perl.ts +2 -1
  215. package/project/.sdk/src/cmp/perl/ReadmeModel_perl.ts +1 -1
  216. package/project/.sdk/src/cmp/perl/ReadmeQuick_perl.ts +3 -3
  217. package/project/.sdk/src/cmp/perl/ReadmeTopQuick_perl.ts +1 -1
  218. package/project/.sdk/src/cmp/perl/TestDirect_perl.ts +3 -3
  219. package/project/.sdk/src/cmp/perl/TestEntity_perl.ts +6 -6
  220. package/project/.sdk/src/cmp/perl/fragment/Entity.fragment.pm +36 -1
  221. package/project/.sdk/src/cmp/php/MainEntity_php.ts +21 -16
  222. package/project/.sdk/src/cmp/php/Package_php.ts +2 -2
  223. package/project/.sdk/src/cmp/php/ReadmeEntity_php.ts +6 -6
  224. package/project/.sdk/src/cmp/php/ReadmeHowto_php.ts +4 -3
  225. package/project/.sdk/src/cmp/php/ReadmeIntro_php.ts +2 -2
  226. package/project/.sdk/src/cmp/php/ReadmeModel_php.ts +1 -1
  227. package/project/.sdk/src/cmp/php/ReadmeQuick_php.ts +12 -12
  228. package/project/.sdk/src/cmp/php/ReadmeRef_php.ts +6 -6
  229. package/project/.sdk/src/cmp/php/ReadmeTopQuick_php.ts +4 -4
  230. package/project/.sdk/src/cmp/php/ReadmeTopTest_php.ts +2 -2
  231. package/project/.sdk/src/cmp/php/TestDirect_php.ts +3 -3
  232. package/project/.sdk/src/cmp/php/TestEntity_php.ts +17 -15
  233. package/project/.sdk/src/cmp/php/fragment/Entity.fragment.php +20 -1
  234. package/project/.sdk/src/cmp/php/fragment/SdkError.fragment.php +11 -0
  235. package/project/.sdk/src/cmp/py/Package_py.ts +4 -3
  236. package/project/.sdk/src/cmp/py/ReadmeEntity_py.ts +13 -2
  237. package/project/.sdk/src/cmp/py/ReadmeHowto_py.ts +2 -1
  238. package/project/.sdk/src/cmp/py/ReadmeModel_py.ts +1 -1
  239. package/project/.sdk/src/cmp/py/ReadmeQuick_py.ts +17 -6
  240. package/project/.sdk/src/cmp/py/ReadmeRef_py.ts +14 -3
  241. package/project/.sdk/src/cmp/py/ReadmeTopQuick_py.ts +13 -2
  242. package/project/.sdk/src/cmp/py/TestDirect_py.ts +3 -3
  243. package/project/.sdk/src/cmp/py/TestEntity_py.ts +9 -9
  244. package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +29 -1
  245. package/project/.sdk/src/cmp/py/fragment/SdkError.fragment.py +11 -0
  246. package/project/.sdk/src/cmp/py-data/Main_py-data.ts +2 -1
  247. package/project/.sdk/src/cmp/rb/Package_rb.ts +4 -3
  248. package/project/.sdk/src/cmp/rb/ReadmeEntity_rb.ts +1 -1
  249. package/project/.sdk/src/cmp/rb/ReadmeHowto_rb.ts +2 -1
  250. package/project/.sdk/src/cmp/rb/ReadmeQuick_rb.ts +5 -5
  251. package/project/.sdk/src/cmp/rb/ReadmeTopQuick_rb.ts +1 -1
  252. package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +3 -3
  253. package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +9 -9
  254. package/project/.sdk/src/cmp/rb/fragment/Entity.fragment.rb +31 -1
  255. package/project/.sdk/src/cmp/rb/fragment/SdkError.fragment.rb +10 -1
  256. package/project/.sdk/src/cmp/rust/Entity_rust.ts +5 -1
  257. package/project/.sdk/src/cmp/rust/Main_rust.ts +21 -0
  258. package/project/.sdk/src/cmp/rust/Package_rust.ts +2 -1
  259. package/project/.sdk/src/cmp/rust/TestDirect_rust.ts +3 -3
  260. package/project/.sdk/src/cmp/rust/TestEntity_rust.ts +12 -12
  261. package/project/.sdk/src/cmp/rust/fragment/Entity.fragment.rs +18 -0
  262. package/project/.sdk/src/cmp/rust/fragment/EntityCreateOp.fragment.rs +8 -2
  263. package/project/.sdk/src/cmp/rust/fragment/EntityListOp.fragment.rs +20 -3
  264. package/project/.sdk/src/cmp/rust/fragment/EntityLoadOp.fragment.rs +8 -2
  265. package/project/.sdk/src/cmp/rust/fragment/EntityRemoveOp.fragment.rs +10 -2
  266. package/project/.sdk/src/cmp/rust/fragment/EntityUpdateOp.fragment.rs +8 -2
  267. package/project/.sdk/src/cmp/rust/fragment/SdkError.fragment.rs +10 -0
  268. package/project/.sdk/src/cmp/scala/ReadmeHowto_scala.ts +2 -1
  269. package/project/.sdk/src/cmp/scala/ReadmeInstall_scala.ts +3 -3
  270. package/project/.sdk/src/cmp/scala/ReadmeModel_scala.ts +1 -1
  271. package/project/.sdk/src/cmp/scala/ReadmeQuick_scala.ts +3 -3
  272. package/project/.sdk/src/cmp/scala/TestEntity_scala.ts +3 -3
  273. package/project/.sdk/src/cmp/scala/fragment/EntityBase.fragment.scala +27 -1
  274. package/project/.sdk/src/cmp/seneca-provider/Extras_seneca-provider.ts +3915 -0
  275. package/project/.sdk/src/cmp/seneca-provider/Main_seneca-provider.ts +960 -0
  276. package/project/.sdk/src/cmp/swift/ReadmeHowto_swift.ts +2 -1
  277. package/project/.sdk/src/cmp/swift/ReadmeInstall_swift.ts +3 -3
  278. package/project/.sdk/src/cmp/swift/ReadmeModel_swift.ts +1 -1
  279. package/project/.sdk/src/cmp/swift/ReadmeQuick_swift.ts +3 -3
  280. package/project/.sdk/src/cmp/swift/fragment/EntityBase.fragment.swift +34 -1
  281. package/project/.sdk/src/cmp/ts/EntityOperation_ts.ts +9 -1
  282. package/project/.sdk/src/cmp/ts/EntityTypes_ts.ts +18 -1
  283. package/project/.sdk/src/cmp/ts/Gitignore_ts.ts +5 -2
  284. package/project/.sdk/src/cmp/ts/Main_ts.ts +4 -1
  285. package/project/.sdk/src/cmp/ts/Package_ts.ts +10 -1
  286. package/project/.sdk/src/cmp/ts/ReadmeEntity_ts.ts +13 -2
  287. package/project/.sdk/src/cmp/ts/ReadmeHowto_ts.ts +2 -1
  288. package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +21 -6
  289. package/project/.sdk/src/cmp/ts/ReadmeRef_ts.ts +52 -2
  290. package/project/.sdk/src/cmp/ts/ReadmeTopQuick_ts.ts +14 -3
  291. package/project/.sdk/src/cmp/ts/ReadmeTopTest_ts.ts +34 -2
  292. package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +64 -43
  293. package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +8 -8
  294. package/project/.sdk/src/cmp/ts/fragment/Direct.test.fragment.ts +2 -2
  295. package/project/.sdk/src/cmp/ts/fragment/Entity.test.fragment.ts +2 -2
  296. package/project/.sdk/src/cmp/ts/fragment/EntityBase.fragment.ts +25 -1
  297. package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.ts +10 -2
  298. package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.ts +1 -1
  299. package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.ts +10 -2
  300. package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.ts +27 -3
  301. package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.ts +10 -2
  302. package/project/.sdk/src/cmp/ts/fragment/SdkError.fragment.ts +15 -0
  303. package/project/.sdk/src/cmp/zig/Entity_zig.ts +5 -1
  304. package/project/.sdk/src/cmp/zig/Package_zig.ts +3 -1
  305. package/project/.sdk/src/cmp/zig/fragment/Entity.fragment.zig +39 -0
  306. package/project/.sdk/src/cmp/zig/fragment/EntityCreateOp.fragment.zig +2 -2
  307. package/project/.sdk/src/cmp/zig/fragment/EntityListOp.fragment.zig +21 -2
  308. package/project/.sdk/src/cmp/zig/fragment/EntityLoadOp.fragment.zig +2 -2
  309. package/project/.sdk/src/cmp/zig/fragment/EntityRemoveOp.fragment.zig +5 -2
  310. package/project/.sdk/src/cmp/zig/fragment/EntityUpdateOp.fragment.zig +2 -2
  311. package/project/.sdk/tm/c/VERSION +1 -1
  312. package/project/.sdk/tm/c/core/helpers.c +1 -0
  313. package/project/.sdk/tm/c/core/sdk.h +22 -6
  314. package/project/.sdk/tm/c/tests/feature_harness.h +1 -0
  315. package/project/.sdk/tm/c/tests/primary_utility_test.c +4 -1
  316. package/project/.sdk/tm/c/utility/make_url.c +1 -0
  317. package/project/.sdk/tm/c/utility/param.c +1 -0
  318. package/project/.sdk/tm/clojure/VERSION +1 -1
  319. package/project/.sdk/tm/cpp/VERSION +1 -1
  320. package/project/.sdk/tm/cpp/core/types.hpp +33 -8
  321. package/project/.sdk/tm/cpp/test/pipeline_test.cpp +5 -0
  322. package/project/.sdk/tm/cpp/test/runner_support.hpp +4 -4
  323. package/project/.sdk/tm/csharp/VERSION +1 -1
  324. package/project/.sdk/tm/csharp/core/Types.cs +6 -0
  325. package/project/.sdk/tm/csharp/test/FeatureHarness.cs +396 -0
  326. package/project/.sdk/tm/csharp/test/FeatureTest.cs +7 -385
  327. package/project/.sdk/tm/csharp/test/Runner.cs +4 -4
  328. package/project/.sdk/tm/dart/lib/utility/MakeErrorUtility.dart +4 -0
  329. package/project/.sdk/tm/dart/test/utility.dart +4 -4
  330. package/project/.sdk/tm/elixir/VERSION +1 -1
  331. package/project/.sdk/tm/elixir/lib/projectname/entity_base.ex +26 -0
  332. package/project/.sdk/tm/go/VERSION +1 -1
  333. package/project/.sdk/tm/go/core/types.go +6 -0
  334. package/project/.sdk/tm/go/test/feature_harness_test.go +361 -0
  335. package/project/.sdk/tm/go/test/feature_test.go +7 -350
  336. package/project/.sdk/tm/go/test/pipeline_test.go +6 -0
  337. package/project/.sdk/tm/go/test/runner_test.go +16 -4
  338. package/project/.sdk/tm/haskell/VERSION +1 -1
  339. package/project/.sdk/tm/haskell/src/SdkFeatures.hs +28 -5
  340. package/project/.sdk/tm/haskell/src/SdkTypes.hs +14 -5
  341. package/project/.sdk/tm/java/VERSION +1 -1
  342. package/project/.sdk/tm/java/test/RunnerSupport.java +4 -4
  343. package/project/.sdk/tm/java/utility/MakeError.java +4 -0
  344. package/project/.sdk/tm/js/src/utility/MakeErrorUtility.js +4 -0
  345. package/project/.sdk/tm/js/test/utility.js +3 -3
  346. package/project/.sdk/tm/kotlin/VERSION +1 -1
  347. package/project/.sdk/tm/kotlin/test/RunnerSupport.kt +3 -3
  348. package/project/.sdk/tm/lean/VERSION +1 -1
  349. package/project/.sdk/tm/lean/test/TFeature.lean +27 -14
  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/seneca-provider/CODE_OF_CONDUCT.md +132 -0
  370. package/project/.sdk/tm/seneca-provider/LICENSE +21 -0
  371. package/project/.sdk/tm/seneca-provider/Makefile +15 -0
  372. package/project/.sdk/tm/seneca-provider/src/tsconfig.json +18 -0
  373. package/project/.sdk/tm/seneca-provider/test/tsconfig.json +16 -0
  374. package/project/.sdk/tm/seneca-provider/tsfmt.json +3 -0
  375. package/project/.sdk/tm/swift/VERSION +1 -1
  376. package/project/.sdk/tm/ts/src/tsconfig.json +1 -0
  377. package/project/.sdk/tm/ts/src/utility/MakeErrorUtility.ts +4 -0
  378. package/project/.sdk/tm/ts/test/tsconfig.json +1 -0
  379. package/project/.sdk/tm/ts/test/utility.ts +3 -3
  380. package/project/.sdk/tm/zig/VERSION +1 -1
  381. package/src/action/doctor.ts +475 -0
  382. package/src/action/feature.ts +54 -16
  383. package/src/action/target.ts +174 -25
  384. package/src/cmp/Entity.ts +7 -0
  385. package/src/cmp/ExternalTarget.ts +125 -0
  386. package/src/cmp/Feature.ts +3 -1
  387. package/src/cmp/Main.ts +7 -1
  388. package/src/cmp/ReadmeExplanation.ts +2 -2
  389. package/src/cmp/ReadmeTop.ts +22 -9
  390. package/src/cmp/Registered.ts +100 -0
  391. package/src/cmp/Test.ts +4 -1
  392. package/src/helpers/dryrun.ts +57 -0
  393. package/src/helpers/featureSource.ts +208 -0
  394. package/src/helpers/naming.ts +73 -2
  395. package/src/helpers/opExample.ts +19 -2
  396. package/src/helpers/opShape.ts +65 -0
  397. package/src/helpers/packageMeta.ts +211 -10
  398. package/src/helpers/stdrep.ts +56 -0
  399. package/src/helpers/testPolicy.ts +52 -0
  400. package/src/sdkgen.ts +350 -5
  401. package/src/types.ts +24 -1
  402. package/src/utility.ts +10 -1
  403. package/project/.sdk/tm/rust/feature/mod.rs +0 -24
@@ -1,6 +1,6 @@
1
1
  // EJECT-START
2
2
 
3
- pub fn update(self: *EntyClass, reqdata: Value, ctrl: Value) OpResult {
3
+ pub fn update(self: *EntyClass, reqdata: Value, ctrl: Value) EntResult {
4
4
  const ctx = self.utility.make_context(CtxSpec{
5
5
  .opname = "update",
6
6
  .ctrl = ctrl,
@@ -8,7 +8,7 @@ pub fn update(self: *EntyClass, reqdata: Value, ctrl: Value) OpResult {
8
8
  .data = self.data,
9
9
  .reqdata = reqdata,
10
10
  }, self.ent_ctx());
11
- return self.run_op(ctx, update_post_done);
11
+ return self.run_op_ent(ctx, update_post_done);
12
12
  }
13
13
 
14
14
  fn update_post_done(self: *EntyClass, ctx: *Context) void {
@@ -1 +1 @@
1
- 0.0.1
1
+ PROJECTVERSION
@@ -5,6 +5,7 @@
5
5
  #include "sdk.h"
6
6
 
7
7
  #include <stdarg.h>
8
+ #include <stdio.h> // snprintf
8
9
  #include <stdlib.h>
9
10
  #include <string.h>
10
11
  #include <time.h>
@@ -303,17 +303,33 @@ voxgig_value* utility_fetch(Utility* u, Context* ctx, const char* url,
303
303
  // Entity (vtable; mirrors core/types.rs Entity + ProjectNameEntity)
304
304
  // ===========================================================================
305
305
 
306
+ // Every operation resolves to the ENTITY, not the raw data. `list` resolves
307
+ // to a NULL-terminated array of them, one per record; the record is reached
308
+ // through `data`. See AGENTS.md "Entity operations return ENTITIES".
309
+ //
310
+ // `voxgig_value` cannot carry an entity - it is a closed data union
311
+ // (UNDEF|NULL|BOOL|INT|DOUBLE|STRING|LIST|MAP|FUNC|SENTINEL), and adding a
312
+ // variant to a general-purpose struct library to hold SDK objects would be
313
+ // wrong - so the CONTRACT lives in these signatures instead.
306
314
  typedef struct EntityVT {
307
315
  const char* (*get_name)(Entity*);
308
316
  Entity* (*make)(Entity*);
309
317
  voxgig_value* (*data)(Entity*, voxgig_value* args); // args NULL => none
310
318
  voxgig_value* (*matchv)(Entity*, voxgig_value* args); // args NULL => none
311
- // CRUD ops (ProjectNameEntity). On error set *err.
312
- voxgig_value* (*load)(Entity*, voxgig_value* reqmatch, voxgig_value* ctrl, PNError** err);
313
- voxgig_value* (*list)(Entity*, voxgig_value* reqmatch, voxgig_value* ctrl, PNError** err);
314
- voxgig_value* (*create)(Entity*, voxgig_value* reqdata, voxgig_value* ctrl, PNError** err);
315
- voxgig_value* (*update)(Entity*, voxgig_value* reqdata, voxgig_value* ctrl, PNError** err);
316
- voxgig_value* (*remove)(Entity*, voxgig_value* reqmatch, voxgig_value* ctrl, PNError** err);
319
+
320
+ // `remove` resolves to the entity, marked. The instance KEEPS the data it
321
+ // held - a caller can still read what was deleted - but it is no longer a
322
+ // live record.
323
+ void (*mark_deleted)(Entity*);
324
+ bool (*deleted)(Entity*);
325
+
326
+ // CRUD ops (ProjectNameEntity). On error set *err and return NULL.
327
+ Entity* (*load)(Entity*, voxgig_value* reqmatch, voxgig_value* ctrl, PNError** err);
328
+ // Returns a NULL-terminated Entity* array (never NULL on success).
329
+ Entity** (*list)(Entity*, voxgig_value* reqmatch, voxgig_value* ctrl, PNError** err);
330
+ Entity* (*create)(Entity*, voxgig_value* reqdata, voxgig_value* ctrl, PNError** err);
331
+ Entity* (*update)(Entity*, voxgig_value* reqdata, voxgig_value* ctrl, PNError** err);
332
+ Entity* (*remove)(Entity*, voxgig_value* reqmatch, voxgig_value* ctrl, PNError** err);
317
333
  } EntityVT;
318
334
 
319
335
  struct Entity {
@@ -15,6 +15,7 @@
15
15
  #include "ctest.h" // -> api.h -> sdk.h, plus voxgig_struct.h
16
16
 
17
17
  #include <ctype.h>
18
+ #include <stdio.h> // snprintf
18
19
  #include <stdlib.h>
19
20
  #include <string.h>
20
21
 
@@ -241,7 +241,10 @@ static void test_primary_make_fetch_def_basic(void) {
241
241
  static void test_primary_make_fetch_def_with_body(void) {
242
242
  base_client();
243
243
  Context* ctx = full_ctx();
244
- ctx->spec = spec_new(cmap(9, "base", v_str("http://localhost:8080"), "prefix", v_str(""),
244
+ // 8 pairs, not 9 - cmap is variadic and reads exactly npairs, so an
245
+ // overcount walks off the argument list and the trailing entry (method) is
246
+ // whatever the read finds.
247
+ ctx->spec = spec_new(cmap(8, "base", v_str("http://localhost:8080"), "prefix", v_str(""),
245
248
  "path", v_str("items"), "suffix", v_str(""), "params", v_map(),
246
249
  "query", v_map(), "headers", v_map(), "method", v_str("POST")));
247
250
  ctx->spec->body = cmap(1, "name", v_str("test"));
@@ -2,6 +2,7 @@
2
2
 
3
3
  #include "sdk.h"
4
4
 
5
+ #include <stdio.h> // snprintf
5
6
  #include <stdlib.h>
6
7
  #include <string.h>
7
8
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  #include "sdk.h"
4
4
 
5
+ #include <stdio.h> // snprintf
5
6
  #include <string.h>
6
7
 
7
8
  voxgig_value* param_util(Context* ctx, voxgig_value* paramdef) {
@@ -1 +1 @@
1
- 0.0.1
1
+ PROJECTVERSION
@@ -1 +1 @@
1
- 0.0.1
1
+ PROJECTVERSION
@@ -347,6 +347,12 @@ public:
347
347
  virtual EntityPtr make() = 0;
348
348
  virtual Value data(const Value& arg = Value::undef()) = 0;
349
349
  virtual Value match(const Value& arg = Value::undef()) = 0;
350
+
351
+ // `remove` resolves to the entity, marked. The instance KEEPS the data it
352
+ // held - a caller can still read what was deleted - but it is no longer a
353
+ // live record.
354
+ virtual void markDeleted() = 0;
355
+ virtual bool deleted() = 0;
350
356
  };
351
357
 
352
358
  // ---- Feature contract -------------------------------------------------
@@ -575,22 +581,33 @@ public:
575
581
 
576
582
  // ---- SdkEntity contract -----------------------------------------------
577
583
 
584
+ class SdkEntity;
585
+ using SdkEntityPtr = std::shared_ptr<SdkEntity>;
586
+
587
+ // Every operation resolves to the ENTITY, not the raw data - `list` to a
588
+ // vector of them, one per record. The record is reached through `data()`.
589
+ // See AGENTS.md "Entity operations return ENTITIES".
590
+ //
591
+ // `Value` cannot carry an entity: it is a closed data union, and adding a
592
+ // variant to a general-purpose struct library to hold SDK objects would be
593
+ // wrong. So the CONTRACT lives in these signatures instead.
578
594
  class SdkEntity : public Entity {
579
595
  public:
580
- virtual Value load(const Value& reqmatch, const Value& ctrl) = 0;
581
- virtual Value list(const Value& reqmatch, const Value& ctrl) = 0;
582
- virtual Value create(const Value& reqdata, const Value& ctrl) = 0;
583
- virtual Value update(const Value& reqdata, const Value& ctrl) = 0;
584
- virtual Value remove(const Value& reqmatch, const Value& ctrl) = 0;
596
+ virtual SdkEntityPtr load(const Value& reqmatch, const Value& ctrl) = 0;
597
+ virtual std::vector<SdkEntityPtr> list(const Value& reqmatch, const Value& ctrl) = 0;
598
+ virtual SdkEntityPtr create(const Value& reqdata, const Value& ctrl) = 0;
599
+ virtual SdkEntityPtr update(const Value& reqdata, const Value& ctrl) = 0;
600
+ virtual SdkEntityPtr remove(const Value& reqmatch, const Value& ctrl) = 0;
585
601
  };
586
602
 
587
- using SdkEntityPtr = std::shared_ptr<SdkEntity>;
588
-
589
603
  // ---- EntityBase (shared entity runtime + runOp) -----------------------
590
604
 
591
- class EntityBase : public SdkEntity {
605
+ class EntityBase : public SdkEntity,
606
+ public std::enable_shared_from_this<EntityBase> {
592
607
  public:
593
608
  std::string name_ = "";
609
+ // Set once a successful `remove` resolves on this instance.
610
+ bool deleted_ = false;
594
611
  SdkClient* client = nullptr;
595
612
  UtilityPtr utility;
596
613
  Value entopts = Value::undef();
@@ -602,6 +619,14 @@ public:
602
619
 
603
620
  std::string getName() override { return name_; }
604
621
 
622
+ void markDeleted() override { deleted_ = true; }
623
+ bool deleted() override { return deleted_; }
624
+
625
+ // The handle for this instance, as the ops return it.
626
+ SdkEntityPtr self() {
627
+ return std::static_pointer_cast<SdkEntity>(shared_from_this());
628
+ }
629
+
605
630
  Value data(const Value& arg = Value::undef()) override;
606
631
  Value match(const Value& arg = Value::undef()) override;
607
632
 
@@ -43,6 +43,11 @@ struct PlEntity : public Entity {
43
43
  return Value::undef();
44
44
  }
45
45
  Value match(const Value& arg = Value::undef()) override { return Value::undef(); }
46
+
47
+ // Every operation resolves to the entity; `remove` marks it. The fake has
48
+ // to satisfy the same interface the real entities do.
49
+ void markDeleted() override {}
50
+ bool deleted() override { return false; }
46
51
  };
47
52
 
48
53
  static std::string errCodeOf(const std::function<void()>& fn) {
@@ -74,8 +74,8 @@ inline std::string getenv_local(const std::string& key) {
74
74
  }
75
75
 
76
76
  inline Value env_override(Value m) {
77
- std::string live = getenv_local("PROJECTNAME_TEST_LIVE");
78
- std::string over = getenv_local("PROJECTNAME_TEST_OVERRIDE");
77
+ std::string live = getenv_local("PROJECTENV_TEST_LIVE");
78
+ std::string over = getenv_local("PROJECTENV_TEST_OVERRIDE");
79
79
  if (live == "TRUE" || over == "TRUE") {
80
80
  if (m.is_map()) {
81
81
  for (const auto& k : Struct::keysof(m)) {
@@ -92,8 +92,8 @@ inline Value env_override(Value m) {
92
92
  }
93
93
  }
94
94
  }
95
- std::string explain = getenv_local("PROJECTNAME_TEST_EXPLAIN");
96
- if (!explain.empty()) map_put(m, "PROJECTNAME_TEST_EXPLAIN", Value(explain));
95
+ std::string explain = getenv_local("PROJECTENV_TEST_EXPLAIN");
96
+ if (!explain.empty()) map_put(m, "PROJECTENV_TEST_EXPLAIN", Value(explain));
97
97
  return m;
98
98
  }
99
99
 
@@ -1 +1 @@
1
- 0.0.1
1
+ PROJECTVERSION
@@ -11,6 +11,12 @@ public interface IEntity
11
11
  IEntity Make();
12
12
  object? Data(object? data = null);
13
13
  object? Match(object? match = null);
14
+
15
+ // Every operation resolves to the entity; Remove additionally marks it.
16
+ // The instance keeps the data it held - a caller can still read what was
17
+ // deleted - but it is no longer a live record.
18
+ void MarkDeleted();
19
+ bool Deleted();
14
20
  }
15
21
 
16
22
  // Transport function: performs the HTTP (or mock) request. Returns a
@@ -0,0 +1,396 @@
1
+ // Offline feature-test harness: a faithful miniature of the real operation
2
+ // pipeline (same hook order and short-circuit rules as the generated entity
3
+ // op code) driven against a configurable mock transport, with no live server
4
+ // and no API-specific fixtures. C# twin of tm/go/test/feature_harness_test.go.
5
+ //
6
+ // SEPARATE FROM FeatureTest.cs ON PURPOSE. `target add` drops the
7
+ // cross-feature suite when a project trims its feature set (it constructs
8
+ // every shipped feature by name), but PipelineTest.cs uses these Fh* helpers
9
+ // too - leaving them in FeatureTest.cs took the whole test assembly down
10
+ // with it.
11
+
12
+ using System.Text.RegularExpressions;
13
+
14
+ using Voxgig.Struct;
15
+ using Xunit;
16
+
17
+ using ProjectNameSdk;
18
+ using ProjectNameSdk.Feature;
19
+
20
+ namespace ProjectNameSdk.Test;
21
+
22
+ // --- harness ----------------------------------------------------------------
23
+
24
+ // FhClock is a deterministic virtual clock: Now() advances only when
25
+ // Sleep(ms) is called, so timing-based features can be asserted without
26
+ // real delays.
27
+ internal class FhClock
28
+ {
29
+ public long T;
30
+ public long Now() => T;
31
+ public void Sleep(int ms) => T += ms;
32
+ public void Advance(int ms) => T += ms;
33
+ }
34
+
35
+ // FhRecorder is a mock transport recording every call, replying via an
36
+ // optional Reply func (default: 200 with a call counter).
37
+ internal class FhRecorder
38
+ {
39
+ public List<Dictionary<string, object?>> Calls = new();
40
+ public Func<int, Dictionary<string, object?>, object?>? Reply;
41
+
42
+ public object? Fetch(Context ctx, string url, Dictionary<string, object?> fetchdef)
43
+ {
44
+ Calls.Add(new Dictionary<string, object?>
45
+ {
46
+ ["url"] = url,
47
+ ["fetchdef"] = fetchdef,
48
+ });
49
+ if (Reply != null)
50
+ {
51
+ return Reply(Calls.Count, fetchdef);
52
+ }
53
+ return Fh.Response(200, new Dictionary<string, object?>
54
+ {
55
+ ["ok"] = true,
56
+ ["n"] = Calls.Count,
57
+ }, null);
58
+ }
59
+
60
+ public Dictionary<string, object?> Headers(int i)
61
+ {
62
+ var fetchdef = Calls[i]["fetchdef"] as Dictionary<string, object?>;
63
+ return fetchdef?["headers"] as Dictionary<string, object?>
64
+ ?? new Dictionary<string, object?>();
65
+ }
66
+
67
+ public Dictionary<string, object?> Fetchdef(int i)
68
+ {
69
+ return Calls[i]["fetchdef"] as Dictionary<string, object?>
70
+ ?? new Dictionary<string, object?>();
71
+ }
72
+
73
+ public string Url(int i)
74
+ {
75
+ return Calls[i]["url"] as string ?? "";
76
+ }
77
+ }
78
+
79
+ internal class FhOpSpec
80
+ {
81
+ public string Entity = "";
82
+ public string Op = "";
83
+ public string Method = "";
84
+ public string Path = "";
85
+ public Dictionary<string, object?>? Query;
86
+ public Dictionary<string, object?>? Headers;
87
+ public object? Body;
88
+ public Dictionary<string, object?>? Ctrl;
89
+ }
90
+
91
+ internal class FhOpResult
92
+ {
93
+ public bool Ok;
94
+ public object? Data;
95
+ public Exception? Err;
96
+ public Result? Result;
97
+ public Context? Ctx;
98
+ }
99
+
100
+ // FhHarness wires features (in init order) to a mock transport and a mini
101
+ // operation pipeline.
102
+ internal class FhHarness
103
+ {
104
+ public ProjectNameSDK Client = null!;
105
+ public Utility Utility = null!;
106
+ public Context Rootctx = null!;
107
+ public string Base = "http://api.test";
108
+
109
+ private static string FhDefaultMethod(string op)
110
+ {
111
+ return op switch
112
+ {
113
+ "create" => "POST",
114
+ "update" => "PATCH",
115
+ "remove" => "DELETE",
116
+ _ => "GET",
117
+ };
118
+ }
119
+
120
+ private static string FhBuildUrl(Spec spec)
121
+ {
122
+ var keys = spec.Query.Where(kv => kv.Value != null)
123
+ .Select(kv => kv.Key).OrderBy(k => k, StringComparer.Ordinal).ToList();
124
+ var qs = string.Join("&", keys.Select(k =>
125
+ Uri.EscapeDataString(k) + "=" +
126
+ Uri.EscapeDataString(StructUtils.Stringify(spec.Query[k]))));
127
+ var url = spec.Base + spec.Path;
128
+ if (qs != "")
129
+ {
130
+ url += "?" + qs;
131
+ }
132
+ return url;
133
+ }
134
+
135
+ // Op runs one operation through the mini pipeline (mirrors the generated
136
+ // entity op code: hook, short-circuit, make*, hook, ...).
137
+ public FhOpResult Op(FhOpSpec o)
138
+ {
139
+ var entity = o.Entity == "" ? "widget" : o.Entity;
140
+ var opname = o.Op == "" ? "load" : o.Op;
141
+ var method = o.Method == "" ? FhDefaultMethod(opname) : o.Method;
142
+ var ctrl = o.Ctrl ?? new Dictionary<string, object?>();
143
+
144
+ var ctx = Utility.MakeContext(new Dictionary<string, object?>
145
+ {
146
+ ["opname"] = opname,
147
+ ["ctrl"] = ctrl,
148
+ }, Rootctx);
149
+ ctx.Op = new Operation(new Dictionary<string, object?>
150
+ {
151
+ ["entity"] = entity,
152
+ ["name"] = opname,
153
+ });
154
+
155
+ Utility.FeatureHook(ctx, "PostConstructEntity");
156
+
157
+ Utility.FeatureHook(ctx, "PrePoint");
158
+ if (ctx.Out.TryGetValue("point", out var pointOut) && pointOut is Exception perr)
159
+ {
160
+ return Fail(ctx, perr);
161
+ }
162
+
163
+ Utility.FeatureHook(ctx, "PreSpec");
164
+ var path = o.Path == "" ? "/" + entity : o.Path;
165
+ var headers = new Dictionary<string, object?>(o.Headers
166
+ ?? new Dictionary<string, object?>());
167
+ var query = new Dictionary<string, object?>(o.Query
168
+ ?? new Dictionary<string, object?>());
169
+ ctx.Spec = new Spec(new Dictionary<string, object?>
170
+ {
171
+ ["method"] = method,
172
+ ["base"] = Base,
173
+ ["path"] = path,
174
+ ["headers"] = headers,
175
+ ["query"] = query,
176
+ ["step"] = "start",
177
+ });
178
+ if (o.Body != null)
179
+ {
180
+ ctx.Spec.Body = o.Body;
181
+ }
182
+
183
+ Utility.FeatureHook(ctx, "PreRequest");
184
+ ctx.Spec.Url = FhBuildUrl(ctx.Spec);
185
+
186
+ var fetchdef = new Dictionary<string, object?>
187
+ {
188
+ ["url"] = ctx.Spec.Url,
189
+ ["method"] = ctx.Spec.Method,
190
+ ["headers"] = ctx.Spec.Headers,
191
+ };
192
+ if (ctx.Spec.Body != null)
193
+ {
194
+ fetchdef["body"] = ctx.Spec.Body;
195
+ }
196
+
197
+ object? response = null;
198
+ Exception? fetchErr = null;
199
+ if (ctx.Out.TryGetValue("request", out var reqOut) && reqOut != null)
200
+ {
201
+ response = reqOut;
202
+ }
203
+ else
204
+ {
205
+ try
206
+ {
207
+ response = Utility.Fetcher(ctx, ctx.Spec.Url, fetchdef);
208
+ }
209
+ catch (Exception ex)
210
+ {
211
+ fetchErr = ex;
212
+ }
213
+ }
214
+ if (response is Dictionary<string, object?> rm)
215
+ {
216
+ ctx.Response = new Response(rm);
217
+ }
218
+
219
+ Utility.FeatureHook(ctx, "PreResponse");
220
+ FhPopulateResult(ctx, response, fetchErr);
221
+ Utility.FeatureHook(ctx, "PreResult");
222
+ Utility.FeatureHook(ctx, "PreDone");
223
+
224
+ if (ctx.Result != null && ctx.Result.Ok)
225
+ {
226
+ return new FhOpResult
227
+ {
228
+ Ok = true,
229
+ Data = ctx.Result.Resdata,
230
+ Result = ctx.Result,
231
+ Ctx = ctx,
232
+ };
233
+ }
234
+
235
+ Exception err;
236
+ if (ctx.Result?.Err != null)
237
+ {
238
+ err = ctx.Result.Err;
239
+ }
240
+ else
241
+ {
242
+ err = ctx.MakeError("op_failed", "operation failed");
243
+ }
244
+ return Fail(ctx, err);
245
+ }
246
+
247
+ private FhOpResult Fail(Context ctx, Exception err)
248
+ {
249
+ ctx.Ctrl.Err = err;
250
+ Utility.FeatureHook(ctx, "PreUnexpected");
251
+ return new FhOpResult
252
+ {
253
+ Ok = false,
254
+ Err = err,
255
+ Result = ctx.Result,
256
+ Ctx = ctx,
257
+ };
258
+ }
259
+
260
+ private static void FhPopulateResult(Context ctx, object? response, Exception? fetchErr)
261
+ {
262
+ var result = new Result(new Dictionary<string, object?>());
263
+ ctx.Result = result;
264
+
265
+ if (fetchErr != null)
266
+ {
267
+ result.Err = fetchErr;
268
+ return;
269
+ }
270
+
271
+ if (response is not Dictionary<string, object?> rm)
272
+ {
273
+ result.Err = ctx.MakeError("request_no_response", "response: undefined");
274
+ return;
275
+ }
276
+
277
+ var resp = new Response(rm);
278
+ result.Status = resp.Status;
279
+ result.StatusText = resp.StatusText;
280
+ if (resp.Headers is Dictionary<string, object?> hm)
281
+ {
282
+ result.Headers = hm;
283
+ }
284
+ if (resp.JsonFunc != null)
285
+ {
286
+ result.Body = resp.JsonFunc();
287
+ }
288
+ result.Resdata = result.Body;
289
+
290
+ if (result.Status >= 400)
291
+ {
292
+ result.Err = ctx.MakeError("request_status",
293
+ $"request: {result.Status}: {result.StatusText}");
294
+ }
295
+ else if (resp.Err != null)
296
+ {
297
+ result.Err = resp.Err;
298
+ }
299
+ if (result.Err == null)
300
+ {
301
+ result.Ok = true;
302
+ }
303
+ }
304
+ }
305
+
306
+ internal static class Fh
307
+ {
308
+ // HasFeature is true when this SDK was generated with the named feature.
309
+ public static bool HasFeature(string name)
310
+ {
311
+ var config = SdkConfig.MakeConfig();
312
+ return config.TryGetValue("feature", out var fraw) &&
313
+ fraw is Dictionary<string, object?> fm &&
314
+ fm.TryGetValue(name, out var f) && f != null;
315
+ }
316
+
317
+ public static bool SkipWithout(params string[] names)
318
+ {
319
+ return names.Any(name => !HasFeature(name));
320
+ }
321
+
322
+ // Response builds a transport-shaped response the pipeline understands.
323
+ public static Dictionary<string, object?> Response(int status, object? data,
324
+ Dictionary<string, object?>? headers)
325
+ {
326
+ var h = new Dictionary<string, object?>();
327
+ if (headers != null)
328
+ {
329
+ foreach (var kv in headers)
330
+ {
331
+ h[kv.Key.ToLowerInvariant()] = kv.Value;
332
+ }
333
+ }
334
+ return new Dictionary<string, object?>
335
+ {
336
+ ["status"] = status,
337
+ ["statusText"] = status >= 400 ? "ERR" : "OK",
338
+ ["body"] = "not-used",
339
+ ["json"] = (Func<object?>)(() => data),
340
+ ["headers"] = h,
341
+ };
342
+ }
343
+
344
+ // Make constructs the harness: a real (test-mode) client, an isolated
345
+ // utility whose fetcher is the mock server, and the requested features
346
+ // initialised against it. Fires PostConstruct once wiring is complete.
347
+ public static FhHarness Make(FetcherFunc? server,
348
+ params (BaseFeature f, Dictionary<string, object?>? options)[] features)
349
+ {
350
+ var client = ProjectNameSDK.TestSDK(null, null);
351
+ client.Features = new List<BaseFeature>();
352
+
353
+ var utility = client.GetUtility();
354
+ if (server == null)
355
+ {
356
+ var rec = new FhRecorder();
357
+ server = rec.Fetch;
358
+ }
359
+ utility.Fetcher = server;
360
+
361
+ var rootctx = utility.MakeContext(new Dictionary<string, object?>
362
+ {
363
+ ["client"] = client,
364
+ ["utility"] = utility,
365
+ }, client.GetRootCtx());
366
+
367
+ foreach (var (f, options) in features)
368
+ {
369
+ var fopts = new Dictionary<string, object?> { ["active"] = true };
370
+ if (options != null)
371
+ {
372
+ foreach (var kv in options)
373
+ {
374
+ fopts[kv.Key] = kv.Value;
375
+ }
376
+ }
377
+ f.Init(rootctx, fopts);
378
+ client.Features.Add(f);
379
+ }
380
+
381
+ utility.FeatureHook(rootctx, "PostConstruct");
382
+
383
+ return new FhHarness
384
+ {
385
+ Client = client,
386
+ Utility = utility,
387
+ Rootctx = rootctx,
388
+ };
389
+ }
390
+
391
+ // ErrCode extracts the SDK error code, "" otherwise.
392
+ public static string ErrCode(Exception? err)
393
+ {
394
+ return err is ProjectNameError se ? se.Code : "";
395
+ }
396
+ }