@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
@@ -12,8 +12,14 @@ import {
12
12
 
13
13
  import { showChanges } from '@voxgig/util'
14
14
 
15
+ import { showDryrun } from '../helpers/dryrun'
16
+
17
+ import { templateReplacements } from '../helpers/stdrep'
18
+
15
19
  import { getelem } from '@voxgig/struct'
16
20
 
21
+ import { Aontu } from 'aontu'
22
+
17
23
  import {
18
24
  KIT
19
25
  } from '../types'
@@ -25,6 +31,13 @@ import type {
25
31
 
26
32
  import { SdkGenError } from '../utility'
27
33
 
34
+ import {
35
+ availableFeatures,
36
+ findFeatureSources,
37
+ featureExcludes,
38
+ fullsetExcludes,
39
+ } from '../helpers/featureSource'
40
+
28
41
  import {
29
42
  feature_add
30
43
  } from './feature'
@@ -76,6 +89,16 @@ async function target_add(targets: string[], actx: ActionContext): Promise<Actio
76
89
  content: loadContent(actx, 'target')
77
90
  },
78
91
  model: actx.model,
92
+ // Dry run must be passed per-call, not left to the Jostraca instance.
93
+ // jostraca's `generate` runs its own options through OptionsShape FIRST,
94
+ // which fills in `control.dryrun: false`, and only then merges
95
+ // `deep({}, gOpts.control, opts.control)` — so the shape default silently
96
+ // OVERRIDES the instance-level flag. `-y target add ts` printed
97
+ // ** DRY RUN ** and wrote every file. (Same trap as the `existing` FIX
98
+ // note in jostraca.js.)
99
+ control: {
100
+ dryrun: !!actx.opts.dryrun
101
+ },
79
102
  }
80
103
 
81
104
  opts.log.info({
@@ -87,9 +110,16 @@ async function target_add(targets: string[], actx: ActionContext): Promise<Actio
87
110
  // The `test` feature is required by every generated target (SDK.test()
88
111
  // depends on it), so ensure it is added even if the model does not yet
89
112
  // declare it.
113
+ //
114
+ // Everything else has to be BOTH declared and active: `active` defaults to
115
+ // false in the schema, and a feature the model has switched off should not
116
+ // have its source land in the project. This used to be a plain
117
+ // Object.keys(), so `retry: { active: false }` still shipped every retry
118
+ // source file.
119
+ const featuremodel: any = actx.model.main[KIT]?.feature ?? {}
90
120
  const features = Array.from(new Set([
91
121
  'test',
92
- ...Object.keys(actx.model.main[KIT]?.feature ?? {}),
122
+ ...Object.keys(featuremodel).filter((n: string) => false !== featuremodel[n]?.active),
93
123
  ]))
94
124
 
95
125
  const jres = await jostraca.generate(opts, () =>
@@ -97,6 +127,10 @@ async function target_add(targets: string[], actx: ActionContext): Promise<Actio
97
127
 
98
128
  showChanges(opts.log, 'target-result', jres)
99
129
 
130
+ if (actx.opts.dryrun) {
131
+ showDryrun(opts.log, 'target-result', jres, actx.folder)
132
+ }
133
+
100
134
  // feature_add copies feature templates for targets already registered in
101
135
  // the model. The targets added above are not in the in-memory model yet,
102
136
  // so TargetRoot copies their feature templates itself.
@@ -167,26 +201,18 @@ const TargetRoot = cmp(function TargetRoot(props: any) {
167
201
  })
168
202
  })
169
203
 
204
+ // Copy the whole template tree MINUS the source of every feature the
205
+ // model did not ask for. Which files those are is discovered from the
206
+ // tree rather than assumed (see helpers/featureSource), because each
207
+ // language puts feature source somewhere different.
208
+ const trim = trimFeatures(ctx$, tfolder, torigname, tname, features)
209
+
170
210
  Folder({ name: 'tm/' + tname }, () => {
171
211
  Copy({
172
212
  from: tfolder + '/tm/' + torigname,
173
- exclude: [/src\/feature/],
174
- replace: {
175
-
176
- // TODO: standard replacements
177
- ProjectName: model.const.Name,
178
- }
179
- })
180
-
181
- Folder({ name: 'src/feature' }, () => {
182
- Copy({ from: tfolder + '/tm/' + torigname + '/src/feature/README.md' })
183
-
184
- each(Array.from(new Set(['base', ...(features ?? [])])), (f: any) => {
185
- const fname = f.val$
186
- Folder({ name: fname }, () => {
187
- Copy({ from: tfolder + '/tm/' + torigname + '/src/feature/' + fname })
188
- })
189
- })
213
+ exclude: trim,
214
+ // Shared with doctor, which re-applies them before comparing.
215
+ replace: templateReplacements(model, tname),
190
216
  })
191
217
  })
192
218
 
@@ -199,6 +225,116 @@ const TargetRoot = cmp(function TargetRoot(props: any) {
199
225
  })
200
226
 
201
227
 
228
+ // Path patterns that keep a target's unwanted feature source out of the
229
+ // project: the source of every AVAILABLE feature the model did not select,
230
+ // plus the templates that only compile with the complete feature set.
231
+ //
232
+ // Returns an empty list — copy the whole tree, as before — when the target
233
+ // opts out with `feature: { trim: false }`, or when its model cannot be
234
+ // read. Trimming a target whose templates are not ready for it produces a
235
+ // project that does not build, so an unreadable declaration must fail safe
236
+ // rather than fail tidy.
237
+ function trimFeatures(
238
+ ctx$: any,
239
+ tfolder: string,
240
+ torigname: string,
241
+ tname: string,
242
+ features: string[],
243
+ ): RegExp[] {
244
+ const { log } = ctx$
245
+ const fs = ctx$.fs()
246
+
247
+ const cfg = readTargetFeature(ctx$, tfolder, torigname, tname)
248
+
249
+ if (false === cfg.trim) {
250
+ log.info({
251
+ point: 'target-feature-trim', target: tname, trim: false,
252
+ note: tname + ': feature trim disabled, copying all feature source'
253
+ })
254
+ return []
255
+ }
256
+
257
+ // `base` is not a declared feature — it is the always-present foundation
258
+ // every other feature builds on — so it is never a trim candidate.
259
+ const selected = new Set(['base', ...(features ?? [])])
260
+
261
+ const available = availableFeatures(fs, tfolder)
262
+ const drop = findFeatureSources(fs, tfolder + '/tm/' + torigname, available)
263
+ .filter((s) => !selected.has(s.name))
264
+
265
+ const trimmed = 0 < drop.length
266
+
267
+ log.info({
268
+ point: 'target-feature-trim', target: tname, trim: true,
269
+ drop: drop.map((s) => s.name),
270
+ note: tname + ': ' + (trimmed ?
271
+ ('dropping ' + drop.length + ' unselected feature source entries') :
272
+ 'all available features selected')
273
+ })
274
+
275
+ return [
276
+ ...featureExcludes(drop),
277
+ // The cross-feature test suite is only excluded when something WAS
278
+ // trimmed; a project carrying the full set keeps its feature tests.
279
+ ...(trimmed ? fullsetExcludes(cfg.fullset) : []),
280
+ ]
281
+ }
282
+
283
+
284
+ // Load a target's `feature` declaration from its own model file.
285
+ //
286
+ // The target being added is not in the in-memory model yet (that is what
287
+ // `target add` is for), so this reads the very file that is about to be
288
+ // copied into `model/target/`. Each shipped target model is self-contained,
289
+ // so Aontu can resolve it on its own.
290
+ function readTargetFeature(
291
+ ctx$: any,
292
+ tfolder: string,
293
+ torigname: string,
294
+ tname: string,
295
+ ): { trim: boolean, fullset: string[] } {
296
+ const { log } = ctx$
297
+ const fs = ctx$.fs()
298
+
299
+ const path = tfolder + '/model/target/' + torigname + '.aontu'
300
+
301
+ try {
302
+ const errs: any[] = []
303
+ const model = new Aontu().generate(fs.readFileSync(path, 'utf8'), { path, errs })
304
+
305
+ if (0 < errs.length) {
306
+ throw new Error(errs.map((e: any) => e.msg || String(e)).join('\n'))
307
+ }
308
+
309
+ const feature = model?.main?.[KIT]?.target?.[torigname]?.feature ?? {}
310
+
311
+ return {
312
+ trim: false !== feature.trim,
313
+ fullset: Array.isArray(feature.fullset) ? feature.fullset : [],
314
+ }
315
+ }
316
+ catch (err: any) {
317
+ log.warn({
318
+ point: 'target-feature-model', target: tname, path,
319
+ err: err.message,
320
+ note: tname + ': cannot read target model (' + err.message +
321
+ '); copying all feature source'
322
+ })
323
+ return { trim: false, fullset: [] }
324
+ }
325
+ }
326
+
327
+
328
+ // Last path segment of a ref. A ref may be a bare target name ('go'), a
329
+ // package-relative path ('@acme/kit/go'), or an ABSOLUTE path — and on Windows
330
+ // an absolute path is separated by `\`, so splitting on '/' alone hands back
331
+ // the whole path as the target name and every tree lookup below then misses.
332
+ // On POSIX Path.sep IS '/', so this is the same split it always was.
333
+ function lastSegment(ref: string): string {
334
+ return getelem(ref.split('/').flatMap((p: string) => p.split(Path.sep)), -1)
335
+ }
336
+
337
+
202
338
  function resolveTarget(tref: string, ctx$: any) {
203
339
  let tname = tref
204
340
  let torigname = tref
@@ -208,24 +344,28 @@ function resolveTarget(tref: string, ctx$: any) {
208
344
  const fs = ctx$.fs()
209
345
 
210
346
  let fulltfolder = Path.normalize(Path.join(root, tfolder))
211
- tname = getelem(tref.split('/'), -1)
347
+ tname = lastSegment(tref)
212
348
 
213
349
  let aliasref = tref
214
- torigname = getelem(aliasref.split('/'), -1)
350
+ torigname = lastSegment(aliasref)
215
351
  const aliasing = tref.split('~')
216
352
  if (1 < aliasing.length) {
217
353
  aliasref = aliasing[0]
218
354
  tname = aliasing.slice(1).join('~')
219
- torigname = getelem(aliasref.split('/'), -1)
355
+ torigname = lastSegment(aliasref)
220
356
  }
221
357
 
222
358
  const search: string[] = []
223
359
  let found = false
224
- if (aliasref.includes('/')) {
360
+ // Windows: an absolute ref is `D:\a\...` or `D:/a/...`, and a Path.join'd
361
+ // one carries backslashes, so neither `includes('/')` nor `startsWith('/')`
362
+ // recognises it. Path.isAbsolute and Path.sep are platform-correct and
363
+ // reduce to the same answers on POSIX.
364
+ if (aliasref.includes('/') || aliasref.includes(Path.sep)) {
225
365
  // NOTE: the last path element of the ref is the target name, not a folder.
226
366
  const aliasbase = Path.dirname(aliasref)
227
367
 
228
- if (!aliasref.startsWith('/')) {
368
+ if (!Path.isAbsolute(aliasref)) {
229
369
  fulltfolder = Path.normalize(Path.join(root, 'node_modules', aliasbase, '.sdk'))
230
370
  search.push(fulltfolder)
231
371
  found = fs.existsSync(fulltfolder)
@@ -251,12 +391,19 @@ function resolveTarget(tref: string, ctx$: any) {
251
391
  throw new Error('Target folder not found in:\n' + search.join('\n '))
252
392
  }
253
393
 
254
- const rootslash = root.endsWith('/') ? root : root + '/'
394
+ // `base` is the target folder relative to the project root. Compare with the
395
+ // PLATFORM separator: on Windows `root + '/'` never prefixes a normalised
396
+ // absolute path, so the root would not be stripped and `base` would stay
397
+ // absolute. Normalise both sides first for the same reason.
398
+ const nroot = Path.normalize(root)
399
+ const rootslash = nroot.endsWith(Path.sep) ? nroot : nroot + Path.sep
255
400
  const out = {
256
401
  tname,
257
402
  tfolder: fulltfolder,
258
403
  torigname,
259
- base: fulltfolder.replace(rootslash, '')
404
+ base: fulltfolder.startsWith(rootslash)
405
+ ? fulltfolder.slice(rootslash.length)
406
+ : fulltfolder
260
407
  }
261
408
 
262
409
  return out
@@ -267,4 +414,6 @@ export {
267
414
  action_target,
268
415
  target_add,
269
416
  resolveTarget,
417
+ trimFeatures,
418
+ readTargetFeature,
270
419
  }
package/src/cmp/Entity.ts CHANGED
@@ -5,6 +5,8 @@ import {
5
5
 
6
6
  import { requirePath } from '../utility'
7
7
 
8
+ import { ensureStdrep } from '../helpers/stdrep'
9
+
8
10
 
9
11
  import {
10
12
  KIT,
@@ -16,6 +18,11 @@ const Entity = cmp(function Entity(props: any) {
16
18
  const { target, entity, ctx$ } = props
17
19
  const { log } = ctx$
18
20
 
21
+ // Entity_<lang> components pull stdrep off ctx$ for their fragments, and
22
+ // Entity is the FIRST phase Root runs — so the generator-owned keys have to
23
+ // exist by here, not just by Main.
24
+ ensureStdrep(ctx$)
25
+
19
26
  const entitySDK = getModelPath(ctx$.model, `main.${KIT}.entity.${entity.name}`)
20
27
 
21
28
  const Entity_sdk = requirePath(ctx$, `./cmp/${target.name}/Entity_${target.name}`)
@@ -0,0 +1,125 @@
1
+ // The Root for a target that generates OUTSIDE the SDK repo
2
+ // (`main: kit: target: <t>: output: path`).
3
+ //
4
+ // WHY THIS EXISTS, rather than a folder name
5
+ //
6
+ // A target's files normally land in `<sdk-repo>/<target>/`, which the
7
+ // consumer's own `Root.ts` arranges with `Folder({ name: target.name })`.
8
+ // Two things stop that reaching a sibling repo:
9
+ //
10
+ // - jostraca REFUSES a `..` segment in a Folder name (FileHandler.validName
11
+ // throws). Escaping the output root through a folder name is not an
12
+ // oversight to work around; it is the guard that keeps generation inside
13
+ // the tree it was pointed at.
14
+ // - the output root is `jopts.folder`, per generate() CALL. So writing
15
+ // somewhere else means another call, not another folder.
16
+ //
17
+ // So an out-of-tree target gets its own generate() pass, rooted at its
18
+ // output path, with this as the Root. It renders ONE target and nothing
19
+ // else: the consumer Root also emits the SDK repo's own furniture (its
20
+ // README, AGENTS.md, the build scaffold), and none of that belongs in a
21
+ // separate package's repo.
22
+ //
23
+ // No Folder wraps the target here — the destination IS the package, so its
24
+ // files go at the root of the output path.
25
+ //
26
+ // The phase gate mirrors the consumer Root exactly, so `output.path` is not
27
+ // a consumer-target feature: point a language target at another repo and it
28
+ // generates there the same way it would in-tree.
29
+
30
+ import { cmp, each, names } from 'jostraca'
31
+
32
+ import { Project } from 'jostraca'
33
+
34
+ import { KIT } from '@voxgig/apidef'
35
+
36
+ import { Main } from './Main'
37
+ import { Entity } from './Entity'
38
+ import { Feature } from './Feature'
39
+ import { Readme } from './Readme'
40
+ import { Test } from './Test'
41
+ import { AgentGuide } from './AgentGuide'
42
+
43
+
44
+ const ExternalTarget = cmp(function ExternalTarget(props: any) {
45
+ const { model, target, cmpfolder, sdkrelpath } = props
46
+ const ctx$ = props.ctx$
47
+
48
+ ctx$.model = model
49
+
50
+ // Components live in the PROJECT, not in the repo being written to. This
51
+ // pass has retargeted jostraca's output folder, which is what requirePath
52
+ // otherwise resolves against — see utility.resolvePath.
53
+ ctx$.cmpfolder = cmpfolder
54
+
55
+ // The path from the destination back to the SDK project, for a target whose
56
+ // output sits beside the SDK in a known layout.
57
+ ctx$.sdkrelpath = sdkrelpath
58
+
59
+ // The same model preamble the consumer's Root.ts performs before it renders
60
+ // anything: the case-variant name constants (`Name`, `NAME`, ...) and the
61
+ // ProjectName replacement map that every template substitution reads.
62
+ //
63
+ // Done HERE rather than relied upon, because this pass gets the model the
64
+ // in-tree pass never touched — Root mutates the filtered copy it is handed,
65
+ // not this one — and because an SDK project with only out-of-tree targets
66
+ // must generate the same way as one with both.
67
+ model.const = model.const || { name: model.name }
68
+ names(model.const, model.name)
69
+ if (null == model.const.year) {
70
+ model.const.year = new Date().getFullYear()
71
+ }
72
+ names(model, model.name)
73
+
74
+ ctx$.stdrep = ctx$.stdrep || {}
75
+ names(ctx$.stdrep, model.Name, 'Project' + 'Name')
76
+
77
+ const entity = model.main[KIT].entity || {}
78
+ const feature = model.main[KIT].feature || {}
79
+
80
+ // Defaults are inclusive: a phase runs unless the target's model turns it
81
+ // off. Consumer targets (go-cli, go-mcp, py-data, seneca-provider) switch
82
+ // every phase off and emit everything from Main.
83
+ const phase = target.phase || {}
84
+ const phaseActive = (name: string): boolean =>
85
+ false !== (phase[name] && phase[name].active)
86
+
87
+ Project({}, () => {
88
+ names(target, target.name)
89
+
90
+ if (phaseActive('entity')) {
91
+ each(entity, (entity: any) => {
92
+ names(entity, entity.name)
93
+ Entity({ target, entity })
94
+ })
95
+ }
96
+
97
+ if (phaseActive('feature')) {
98
+ each(feature)
99
+ .filter((feature: any) => feature.active)
100
+ .map((feature: any) => {
101
+ names(feature, feature.name)
102
+ Feature({ target, feature })
103
+ })
104
+ }
105
+
106
+ Main({ target })
107
+
108
+ if (phaseActive('readme')) {
109
+ Readme({ target })
110
+ }
111
+
112
+ if (phaseActive('agentguide')) {
113
+ AgentGuide({ target })
114
+ }
115
+
116
+ if (phaseActive('test')) {
117
+ Test({ target })
118
+ }
119
+ })
120
+ })
121
+
122
+
123
+ export {
124
+ ExternalTarget,
125
+ }
@@ -1,6 +1,8 @@
1
1
 
2
2
  import { cmp, Copy, Folder } from 'jostraca'
3
3
 
4
+ import { ensureStdrep } from '../helpers/stdrep'
5
+
4
6
  const Feature = cmp(function Feature(props: any) {
5
7
  const { target, feature, ctx$ } = props
6
8
  const { log } = ctx$
@@ -23,7 +25,7 @@ const Feature = cmp(function Feature(props: any) {
23
25
  // local Main_<lang> lost that Copy — got the raw placeholder.
24
26
  // voxgig-solardemo-sdk hit exactly that and could not build its
25
27
  // TypeScript at all.
26
- ...ctx$.stdrep,
28
+ ...ensureStdrep(ctx$),
27
29
  FEATURE_VERSION: feature.version,
28
30
  FEATURE_Name: feature.Name,
29
31
  }
package/src/cmp/Main.ts CHANGED
@@ -3,6 +3,8 @@ import { cmp, names } from 'jostraca'
3
3
 
4
4
  import { requirePath } from '../utility'
5
5
 
6
+ import { ensureStdrep } from '../helpers/stdrep'
7
+
6
8
  import {
7
9
  KIT
8
10
  } from '../types'
@@ -10,7 +12,11 @@ import {
10
12
 
11
13
  const Main = cmp(function Main(props: any) {
12
14
  const { target, ctx$ } = props
13
- const { model, stdrep, log } = ctx$
15
+ const { model, log } = ctx$
16
+
17
+ // Generator-owned placeholders (PROJECTENV) that the project's frozen
18
+ // Root.ts cannot know about.
19
+ const stdrep = ensureStdrep(ctx$)
14
20
 
15
21
  const Main_sdk = requirePath(ctx$, `cmp/${target.name}/Main_${target.name}`)
16
22
 
@@ -11,7 +11,7 @@ import { requirePath } from '../utility'
11
11
  import { entityIdField, pickExampleEntity } from '../helpers/opShape'
12
12
  import { idLiteral, matchArg, dataArg } from '../helpers/opExample'
13
13
  import type { ExampleLang } from '../helpers/opExample'
14
- import { safeVarName, exampleVarName } from '../helpers/naming'
14
+ import { safeVarName, exampleVarName, phpEntityAccessor } from '../helpers/naming'
15
15
 
16
16
 
17
17
  function cap(s: string): string {
@@ -110,7 +110,7 @@ with hook methods named after pipeline stages (e.g. \`PrePoint\`,
110
110
  stores the returned data and match criteria internally.
111
111
 
112
112
  \`\`\`php
113
- $${eLower} = $client->${eName}();
113
+ $${eLower} = $client->${phpEntityAccessor(eName)}();
114
114
  $${eLower}->${op}(${arg});
115
115
 
116
116
  // $${eLower}->data_get() now returns the ${eLower} data from the last ${op}
@@ -8,7 +8,10 @@ import {
8
8
 
9
9
  import { requirePath } from '../utility'
10
10
 
11
- import { entityPrimaryOp, entityIdField, opRequestShape } from '../helpers/opShape'
11
+ import {
12
+ entityPrimaryOp, entityIdField, opRequestShape, entityPath, entityActions,
13
+ } from '../helpers/opShape'
14
+ import { matchArg, idLiteral } from '../helpers/opExample'
12
15
  import { canonKey } from '../helpers/canonType'
13
16
  import { safeVarName, exampleVarName } from '../helpers/naming'
14
17
 
@@ -241,10 +244,21 @@ ${aboutMd.trim()}
241
244
  // only remove (or nothing), the op line is omitted entirely.
242
245
  const primaryOp = entityPrimaryOp(exEnt)
243
246
  let exCall = ''
247
+ // A `list()` on a NESTED entity needs its parent path params — the
248
+ // quickstart used to emit `client.Moon().list()` for an entity at
249
+ // `/planet/{planet_id}/moon`, which 404s against a live server from a
250
+ // half-built URL. The model knows which params are required; matchArg
251
+ // renders exactly those.
252
+ const exIdField = entityIdField(exEnt)
253
+ const exListArg = matchArg('ts', exEnt, 'list', exIdField,
254
+ idLiteral(exEnt, 'list', exIdField))
255
+ const exLoadArg = matchArg('ts', exEnt, 'load', exIdField,
256
+ idLiteral(exEnt, 'load', exIdField))
257
+
244
258
  if ('list' === primaryOp) {
245
- exCall = `const items = await client.${ex}().list()`
259
+ exCall = `const items = await client.${ex}().list(${exListArg})`
246
260
  } else if ('load' === primaryOp) {
247
- exCall = `const ${exLower} = await client.${ex}().load()`
261
+ exCall = `const ${exLower} = await client.${ex}().load(${exLoadArg})`
248
262
  } else if ('create' === primaryOp || 'update' === primaryOp) {
249
263
  const exIdF = entityIdField(exEnt)
250
264
  const shapeItems = opRequestShape(exEnt, primaryOp).items
@@ -424,12 +438,11 @@ The API exposes ${activeEntities.length === 1 ? 'one entity' : activeEntities.le
424
438
  // Never emit a blank description cell: fall back to an ops-derived line.
425
439
  const entdesc = entityDesc[ent.name] || ent.short || ent.desc ||
426
440
  `The ${ent.Name} entity${opNames.length ? ' (' + opNames.join(', ') + ')' : ''}.`
427
- const points = each(ops).map((op: any) =>
428
- op.points ? each(op.points) : []
429
- ).flat()
430
- const path = points.length > 0
431
- ? (points[0] as any).orig || ''
432
- : ''
441
+ // The entity's canonical route — never a folded-in custom action.
442
+ // Ops iterate in sorted-key order, so this used to take `create`'s
443
+ // first point, and an entity with a `/{id}/forbid` action route
444
+ // advertised THAT as its API path.
445
+ const path = entityPath(ent)
433
446
  Content(`| **${ent.Name}** | ${entdesc} | \`${path}\` |
434
447
  `)
435
448
  })
@@ -0,0 +1,100 @@
1
+ // `registerComponent` — add a per-target component of your own.
2
+ //
3
+ // WHY THIS EXISTS
4
+ //
5
+ // Every built-in resolves its per-language half by convention:
6
+ // `Main` loads `cmp/<target>/Main_<target>`, `Test` loads
7
+ // `cmp/<target>/Test_<target>`, and `ReadmeTop` loads
8
+ // `cmp/<target>/ReadmeTopQuick_<target>` with `{ ignore: true }` so a target
9
+ // that has not implemented it is simply skipped.
10
+ //
11
+ // A PROJECT had no way into that mechanism. voxgig-solardemo-sdk wanted a
12
+ // per-target `AGENTS.md` and had to hand-wire the dispatch in its own
13
+ // `Root.ts`:
14
+ //
15
+ // if ('ts' === target.name) { AgentsTs({ target }) }
16
+ // else if ('go' === target.name) { AgentsGo({ target }) }
17
+ //
18
+ // which duplicates the internal dispatch, does not scale past a couple of
19
+ // targets, and — because the branches live inline in Root.ts — is exactly
20
+ // what stops a project's root wiring from being resynced with the scaffold.
21
+ //
22
+ // With this, the same thing is one line and target-agnostic:
23
+ //
24
+ // const Agents = registerComponent('Agents')
25
+ // ...
26
+ // Agents({ target })
27
+ //
28
+ // resolving `cmp/<target>/Agents_<target>` and doing nothing for a target
29
+ // that has no such file. `doctor` reports those files as ADDITIVE — the
30
+ // project's own work — rather than as drift.
31
+
32
+ import { cmp } from 'jostraca'
33
+
34
+ import { requirePath } from '../utility'
35
+
36
+ import { ensureStdrep } from '../helpers/stdrep'
37
+
38
+
39
+ type RegisterOptions = {
40
+ // Exported member to call. Defaults to the component name, matching every
41
+ // built-in (`Main_go.ts` exports `Main`).
42
+ export?: string
43
+
44
+ // Whether a target without the component is skipped (the default, matching
45
+ // ReadmeTop's optional per-target parts) or is an error.
46
+ optional?: boolean
47
+ }
48
+
49
+
50
+ function registerComponent(name: string, options: RegisterOptions = {}) {
51
+ const member = options.export || name
52
+ const optional = false !== options.optional
53
+
54
+ return cmp(function Registered(props: any) {
55
+ const { target, ctx$ } = props
56
+ const { model, log } = ctx$
57
+
58
+ const stdrep = ensureStdrep(ctx$)
59
+
60
+ const mod: any = requirePath(
61
+ ctx$, `./cmp/${target.name}/${name}_${target.name}`, { ignore: optional })
62
+
63
+ if (null == mod) {
64
+ log.debug({
65
+ point: 'generate-registered-absent', component: name, target: target.name,
66
+ note: name + ': not implemented for ' + target.name
67
+ })
68
+ return
69
+ }
70
+
71
+ const fn = mod[member]
72
+
73
+ if ('function' !== typeof fn) {
74
+ log.warn({
75
+ point: 'generate-registered-noexport', component: name,
76
+ target: target.name, member,
77
+ note: name + '_' + target.name + ' does not export ' + member
78
+ })
79
+ return
80
+ }
81
+
82
+ // Same call shape as the built-ins, plus whatever the caller passed —
83
+ // so a registered component is written exactly like Main_<lang>.
84
+ fn({ ...props, model, target, stdrep })
85
+
86
+ log.info({
87
+ point: 'generate-registered', component: name, target: target.name,
88
+ note: name + ': target:' + target.name
89
+ })
90
+ })
91
+ }
92
+
93
+
94
+ export type {
95
+ RegisterOptions,
96
+ }
97
+
98
+ export {
99
+ registerComponent,
100
+ }
package/src/cmp/Test.ts CHANGED
@@ -5,6 +5,8 @@ import {
5
5
 
6
6
  import { requirePath } from '../utility'
7
7
 
8
+ import { ensureStdrep } from '../helpers/stdrep'
9
+
8
10
 
9
11
  import {
10
12
  KIT,
@@ -14,7 +16,8 @@ import {
14
16
 
15
17
  const Test = cmp(function Test(props: any) {
16
18
  const { target, ctx$ } = props
17
- const { model, stdrep, log } = ctx$
19
+ const { model, log } = ctx$
20
+ const stdrep = ensureStdrep(ctx$)
18
21
 
19
22
  const Test_sdk = requirePath(ctx$, `./cmp/${target.name}/Test_${target.name}`)
20
23
  Test_sdk['Test']({ model, target, stdrep })