@voxgig/sdkgen 1.3.17 → 1.3.19

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 (267) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/dist/cmp/Deploy.js +16 -16
  3. package/dist/cmp/Deploy.js.map +1 -1
  4. package/dist/cmp/Entity.js +5 -1
  5. package/dist/cmp/Entity.js.map +1 -1
  6. package/dist/cmp/Feature.js +2 -1
  7. package/dist/cmp/Feature.js.map +1 -1
  8. package/dist/cmp/ReadmeTop.js +13 -11
  9. package/dist/cmp/ReadmeTop.js.map +1 -1
  10. package/dist/helpers/canonType.js +8 -3
  11. package/dist/helpers/canonType.js.map +1 -1
  12. package/dist/helpers/collectDeps.d.ts +1 -1
  13. package/dist/helpers/collectDeps.js +36 -13
  14. package/dist/helpers/collectDeps.js.map +1 -1
  15. package/dist/helpers/naming.d.ts +5 -1
  16. package/dist/helpers/naming.js +118 -0
  17. package/dist/helpers/naming.js.map +1 -1
  18. package/dist/helpers/opShape.d.ts +3 -1
  19. package/dist/helpers/opShape.js +87 -8
  20. package/dist/helpers/opShape.js.map +1 -1
  21. package/dist/helpers/serverVars.d.ts +10 -0
  22. package/dist/helpers/serverVars.js +87 -0
  23. package/dist/helpers/serverVars.js.map +1 -0
  24. package/dist/sdkgen.d.ts +4 -3
  25. package/dist/sdkgen.js +11 -2
  26. package/dist/sdkgen.js.map +1 -1
  27. package/dist/tsconfig.tsbuildinfo +1 -1
  28. package/package.json +15 -10
  29. package/project/.sdk/model/target/cpp.aontu +4 -4
  30. package/project/.sdk/model/target/go-cli.aontu +17 -17
  31. package/project/.sdk/model/target/go-mcp.aontu +11 -11
  32. package/project/.sdk/model/target/go.aontu +1 -1
  33. package/project/.sdk/model/target/java.aontu +4 -4
  34. package/project/.sdk/model/target/kotlin.aontu +4 -4
  35. package/project/.sdk/model/target/lean.aontu +51 -0
  36. package/project/.sdk/model/target/scala.aontu +4 -4
  37. package/project/.sdk/src/cmp/c/EntityTypes_c.ts +3 -4
  38. package/project/.sdk/src/cmp/c/Entity_c.ts +3 -3
  39. package/project/.sdk/src/cmp/c/ReadmeExamplesTest_c.ts +24 -7
  40. package/project/.sdk/src/cmp/c/TestDirect_c.ts +3 -3
  41. package/project/.sdk/src/cmp/c/TestEntity_c.ts +1 -1
  42. package/project/.sdk/src/cmp/clojure/Entity_clojure.ts +1 -1
  43. package/project/.sdk/src/cmp/clojure/ReadmeExamplesTest_clojure.ts +19 -8
  44. package/project/.sdk/src/cmp/cpp/EntityTypes_cpp.ts +2 -2
  45. package/project/.sdk/src/cmp/cpp/Entity_cpp.ts +3 -3
  46. package/project/.sdk/src/cmp/cpp/MainEntity_cpp.ts +2 -2
  47. package/project/.sdk/src/cmp/cpp/ReadmeExamplesTest_cpp.ts +136 -0
  48. package/project/.sdk/src/cmp/cpp/TestDirect_cpp.ts +3 -3
  49. package/project/.sdk/src/cmp/cpp/Test_cpp.ts +4 -0
  50. package/project/.sdk/src/cmp/csharp/EntityTypes_csharp.ts +2 -3
  51. package/project/.sdk/src/cmp/csharp/Entity_csharp.ts +3 -3
  52. package/project/.sdk/src/cmp/csharp/MainEntity_csharp.ts +2 -2
  53. package/project/.sdk/src/cmp/csharp/Package_csharp.ts +1 -1
  54. package/project/.sdk/src/cmp/csharp/ReadmeExamplesTest_csharp.ts +13 -1
  55. package/project/.sdk/src/cmp/csharp/TestDirect_csharp.ts +3 -3
  56. package/project/.sdk/src/cmp/csharp/TestEntity_csharp.ts +22 -15
  57. package/project/.sdk/src/cmp/dart/EntityTypes_dart.ts +2 -3
  58. package/project/.sdk/src/cmp/dart/Entity_dart.ts +3 -3
  59. package/project/.sdk/src/cmp/dart/MainEntity_dart.ts +2 -2
  60. package/project/.sdk/src/cmp/dart/Main_dart.ts +3 -3
  61. package/project/.sdk/src/cmp/dart/Package_dart.ts +1 -1
  62. package/project/.sdk/src/cmp/dart/TestDirect_dart.ts +4 -4
  63. package/project/.sdk/src/cmp/elixir/EntityTypes_elixir.ts +2 -3
  64. package/project/.sdk/src/cmp/elixir/Entity_elixir.ts +1 -1
  65. package/project/.sdk/src/cmp/elixir/ReadmeExamplesTest_elixir.ts +21 -3
  66. package/project/.sdk/src/cmp/go/Config_go.ts +14 -2
  67. package/project/.sdk/src/cmp/go/EntityTypes_go.ts +110 -18
  68. package/project/.sdk/src/cmp/go/Entity_go.ts +3 -3
  69. package/project/.sdk/src/cmp/go/Main_go.ts +7 -6
  70. package/project/.sdk/src/cmp/go/Package_go.ts +1 -1
  71. package/project/.sdk/src/cmp/go/TestDirect_go.ts +3 -3
  72. package/project/.sdk/src/cmp/go/TestEntity_go.ts +1 -1
  73. package/project/.sdk/src/cmp/go/utility_go.ts +25 -0
  74. package/project/.sdk/src/cmp/go-cli/Main_go-cli.ts +62 -35
  75. package/project/.sdk/src/cmp/go-cli/fragment/main.fragment.go +7 -7
  76. package/project/.sdk/src/cmp/go-cli/fragment/words.fragment.go +21 -18
  77. package/project/.sdk/src/cmp/go-mcp/Main_go-mcp.ts +9 -1
  78. package/project/.sdk/src/cmp/haskell/ReadmeExamplesTest_haskell.ts +28 -18
  79. package/project/.sdk/src/cmp/java/EntityTypes_java.ts +2 -3
  80. package/project/.sdk/src/cmp/java/Entity_java.ts +3 -3
  81. package/project/.sdk/src/cmp/java/MainEntity_java.ts +2 -2
  82. package/project/.sdk/src/cmp/java/Package_java.ts +1 -1
  83. package/project/.sdk/src/cmp/java/ReadmeExamplesTest_java.ts +23 -1
  84. package/project/.sdk/src/cmp/java/TestDirect_java.ts +3 -3
  85. package/project/.sdk/src/cmp/js/Config_js.ts +11 -0
  86. package/project/.sdk/src/cmp/js/EntityTypes_js.ts +2 -3
  87. package/project/.sdk/src/cmp/js/Entity_js.ts +3 -3
  88. package/project/.sdk/src/cmp/js/MainEntity_js.ts +2 -2
  89. package/project/.sdk/src/cmp/js/Main_js.ts +2 -2
  90. package/project/.sdk/src/cmp/js/TestDirect_js.ts +4 -4
  91. package/project/.sdk/src/cmp/js/fragment/Config.fragment.js +2 -2
  92. package/project/.sdk/src/cmp/js/fragment/Direct.test.fragment.js +4 -0
  93. package/project/.sdk/src/cmp/kotlin/EntityTypes_kotlin.ts +2 -3
  94. package/project/.sdk/src/cmp/kotlin/Entity_kotlin.ts +3 -3
  95. package/project/.sdk/src/cmp/kotlin/MainEntity_kotlin.ts +2 -2
  96. package/project/.sdk/src/cmp/kotlin/Package_kotlin.ts +1 -1
  97. package/project/.sdk/src/cmp/kotlin/ReadmeExamplesTest_kotlin.ts +27 -2
  98. package/project/.sdk/src/cmp/kotlin/TestDirect_kotlin.ts +3 -3
  99. package/project/.sdk/src/cmp/lean/Config_lean.ts +88 -0
  100. package/project/.sdk/src/cmp/lean/Entity_lean.ts +9 -0
  101. package/project/.sdk/src/cmp/lean/Gitignore_lean.ts +18 -0
  102. package/project/.sdk/src/cmp/lean/Main_lean.ts +120 -0
  103. package/project/.sdk/src/cmp/lean/Package_lean.ts +68 -0
  104. package/project/.sdk/src/cmp/lean/ReadmeEntity_lean.ts +29 -0
  105. package/project/.sdk/src/cmp/lean/ReadmeExplanation_lean.ts +19 -0
  106. package/project/.sdk/src/cmp/lean/ReadmeHowto_lean.ts +25 -0
  107. package/project/.sdk/src/cmp/lean/ReadmeInstall_lean.ts +38 -0
  108. package/project/.sdk/src/cmp/lean/ReadmeIntro_lean.ts +25 -0
  109. package/project/.sdk/src/cmp/lean/ReadmeModel_lean.ts +24 -0
  110. package/project/.sdk/src/cmp/lean/ReadmeOptions_lean.ts +22 -0
  111. package/project/.sdk/src/cmp/lean/ReadmeQuick_lean.ts +50 -0
  112. package/project/.sdk/src/cmp/lean/ReadmeRef_lean.ts +16 -0
  113. package/project/.sdk/src/cmp/lean/ReadmeTopHowto_lean.ts +16 -0
  114. package/project/.sdk/src/cmp/lean/ReadmeTopQuick_lean.ts +23 -0
  115. package/project/.sdk/src/cmp/lean/ReadmeTopTest_lean.ts +18 -0
  116. package/project/.sdk/src/cmp/lean/Test_lean.ts +207 -0
  117. package/project/.sdk/src/cmp/lean/utility_lean.ts +78 -0
  118. package/project/.sdk/src/cmp/lua/Config_lua.ts +10 -1
  119. package/project/.sdk/src/cmp/lua/EntityTypes_lua.ts +2 -3
  120. package/project/.sdk/src/cmp/lua/Entity_lua.ts +3 -3
  121. package/project/.sdk/src/cmp/lua/Package_lua.ts +1 -1
  122. package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +3 -3
  123. package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +1 -1
  124. package/project/.sdk/src/cmp/ocaml/ReadmeExamplesTest_ocaml.ts +29 -14
  125. package/project/.sdk/src/cmp/perl/Entity_perl.ts +3 -3
  126. package/project/.sdk/src/cmp/perl/MainEntity_perl.ts +2 -2
  127. package/project/.sdk/src/cmp/perl/Package_perl.ts +1 -1
  128. package/project/.sdk/src/cmp/perl/TestDirect_perl.ts +3 -3
  129. package/project/.sdk/src/cmp/php/Config_php.ts +13 -2
  130. package/project/.sdk/src/cmp/php/EntityTypes_php.ts +2 -3
  131. package/project/.sdk/src/cmp/php/Entity_php.ts +3 -3
  132. package/project/.sdk/src/cmp/php/MainEntity_php.ts +2 -2
  133. package/project/.sdk/src/cmp/php/Package_php.ts +1 -1
  134. package/project/.sdk/src/cmp/php/TestDirect_php.ts +3 -3
  135. package/project/.sdk/src/cmp/php/TestEntity_php.ts +1 -1
  136. package/project/.sdk/src/cmp/py/Config_py.ts +10 -1
  137. package/project/.sdk/src/cmp/py/EntityTypes_py.ts +2 -3
  138. package/project/.sdk/src/cmp/py/Entity_py.ts +3 -3
  139. package/project/.sdk/src/cmp/py/MainEntity_py.ts +2 -2
  140. package/project/.sdk/src/cmp/py/Main_py.ts +2 -2
  141. package/project/.sdk/src/cmp/py/Package_py.ts +1 -1
  142. package/project/.sdk/src/cmp/py/TestDirect_py.ts +3 -3
  143. package/project/.sdk/src/cmp/py/TestEntity_py.ts +1 -1
  144. package/project/.sdk/src/cmp/rb/Config_rb.ts +12 -1
  145. package/project/.sdk/src/cmp/rb/EntityTypes_rb.ts +15 -5
  146. package/project/.sdk/src/cmp/rb/Entity_rb.ts +3 -3
  147. package/project/.sdk/src/cmp/rb/MainEntity_rb.ts +2 -2
  148. package/project/.sdk/src/cmp/rb/Package_rb.ts +2 -2
  149. package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +3 -3
  150. package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +1 -1
  151. package/project/.sdk/src/cmp/rust/EntityBase_rust.ts +2 -2
  152. package/project/.sdk/src/cmp/rust/EntityTypes_rust.ts +3 -4
  153. package/project/.sdk/src/cmp/rust/Entity_rust.ts +3 -3
  154. package/project/.sdk/src/cmp/rust/MainEntity_rust.ts +2 -2
  155. package/project/.sdk/src/cmp/rust/Package_rust.ts +1 -1
  156. package/project/.sdk/src/cmp/rust/ReadmeExamplesTest_rust.ts +22 -10
  157. package/project/.sdk/src/cmp/rust/TestDirect_rust.ts +3 -3
  158. package/project/.sdk/src/cmp/rust/TestEntity_rust.ts +25 -18
  159. package/project/.sdk/src/cmp/scala/EntityTypes_scala.ts +2 -3
  160. package/project/.sdk/src/cmp/scala/Entity_scala.ts +3 -3
  161. package/project/.sdk/src/cmp/scala/MainEntity_scala.ts +2 -2
  162. package/project/.sdk/src/cmp/scala/ReadmeExamplesTest_scala.ts +22 -3
  163. package/project/.sdk/src/cmp/scala/TestDirect_scala.ts +3 -3
  164. package/project/.sdk/src/cmp/scala/Test_scala.ts +1 -1
  165. package/project/.sdk/src/cmp/swift/EntityTypes_swift.ts +12 -6
  166. package/project/.sdk/src/cmp/swift/Entity_swift.ts +3 -3
  167. package/project/.sdk/src/cmp/swift/MainEntity_swift.ts +2 -2
  168. package/project/.sdk/src/cmp/swift/Package_swift.ts +1 -1
  169. package/project/.sdk/src/cmp/swift/ReadmeExamplesTest_swift.ts +18 -1
  170. package/project/.sdk/src/cmp/swift/TestDirect_swift.ts +1 -1
  171. package/project/.sdk/src/cmp/ts/Config_ts.ts +11 -0
  172. package/project/.sdk/src/cmp/ts/EntityTypes_ts.ts +2 -3
  173. package/project/.sdk/src/cmp/ts/Entity_ts.ts +3 -3
  174. package/project/.sdk/src/cmp/ts/MainEntity_ts.ts +2 -2
  175. package/project/.sdk/src/cmp/ts/Main_ts.ts +2 -2
  176. package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +4 -4
  177. package/project/.sdk/src/cmp/ts/fragment/Config.fragment.ts +2 -2
  178. package/project/.sdk/src/cmp/ts/fragment/Direct.test.fragment.ts +4 -0
  179. package/project/.sdk/src/cmp/zig/Entity_zig.ts +3 -3
  180. package/project/.sdk/src/cmp/zig/MainEntity_zig.ts +2 -2
  181. package/project/.sdk/src/cmp/zig/Package_zig.ts +10 -2
  182. package/project/.sdk/tm/cpp/test/primary_utility_test.cpp +8 -16
  183. package/project/.sdk/tm/csharp/Makefile +6 -6
  184. package/project/.sdk/tm/csharp/test/PrimaryUtilityTest.cs +10 -28
  185. package/project/.sdk/tm/dart/Makefile +3 -3
  186. package/project/.sdk/tm/dart/test/primary_test.dart +7 -0
  187. package/project/.sdk/tm/go/Makefile +6 -6
  188. package/project/.sdk/tm/go/feature/test_feature.go +33 -1
  189. package/project/.sdk/tm/go/test/primary_utility_test.go +46 -42
  190. package/project/.sdk/tm/go/test/runner_test.go +30 -1
  191. package/project/.sdk/tm/go/utility/make_options.go +48 -0
  192. package/project/.sdk/tm/java/Makefile +6 -6
  193. package/project/.sdk/tm/java/test/PrimaryUtilityTest.java +7 -24
  194. package/project/.sdk/tm/js/Makefile +6 -6
  195. package/project/.sdk/tm/js/src/feature/test/TestFeature.js +18 -1
  196. package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +39 -1
  197. package/project/.sdk/tm/js/test/utility/PrimaryUtility.test.js +13 -0
  198. package/project/.sdk/tm/kotlin/Makefile +6 -6
  199. package/project/.sdk/tm/kotlin/test/PrimaryUtilityTest.kt +7 -20
  200. package/project/.sdk/tm/lean/LICENSE +21 -0
  201. package/project/.sdk/tm/lean/VERSION +1 -0
  202. package/project/.sdk/tm/lean/src/SdkFeature.lean +171 -0
  203. package/project/.sdk/tm/lean/src/SdkFeatures.lean +602 -0
  204. package/project/.sdk/tm/lean/src/SdkJson.lean +134 -0
  205. package/project/.sdk/tm/lean/src/SdkRuntime.lean +356 -0
  206. package/project/.sdk/tm/lean/src/SdkUtility.lean +617 -0
  207. package/project/.sdk/tm/lean/src/VoxgigStruct.lean +2880 -0
  208. package/project/.sdk/tm/lean/src/Vregex.lean +412 -0
  209. package/project/.sdk/tm/lean/src/feature/README.md +5 -0
  210. package/project/.sdk/tm/lean/src/feature/audit/.gitkeep +0 -0
  211. package/project/.sdk/tm/lean/src/feature/base/.gitkeep +0 -0
  212. package/project/.sdk/tm/lean/src/feature/cache/.gitkeep +0 -0
  213. package/project/.sdk/tm/lean/src/feature/clienttrack/.gitkeep +0 -0
  214. package/project/.sdk/tm/lean/src/feature/debug/.gitkeep +0 -0
  215. package/project/.sdk/tm/lean/src/feature/idempotency/.gitkeep +0 -0
  216. package/project/.sdk/tm/lean/src/feature/log/.gitkeep +0 -0
  217. package/project/.sdk/tm/lean/src/feature/metrics/.gitkeep +0 -0
  218. package/project/.sdk/tm/lean/src/feature/netsim/.gitkeep +0 -0
  219. package/project/.sdk/tm/lean/src/feature/paging/.gitkeep +0 -0
  220. package/project/.sdk/tm/lean/src/feature/proxy/.gitkeep +0 -0
  221. package/project/.sdk/tm/lean/src/feature/ratelimit/.gitkeep +0 -0
  222. package/project/.sdk/tm/lean/src/feature/rbac/.gitkeep +0 -0
  223. package/project/.sdk/tm/lean/src/feature/retry/.gitkeep +0 -0
  224. package/project/.sdk/tm/lean/src/feature/streaming/.gitkeep +0 -0
  225. package/project/.sdk/tm/lean/src/feature/telemetry/.gitkeep +0 -0
  226. package/project/.sdk/tm/lean/src/feature/test/.gitkeep +0 -0
  227. package/project/.sdk/tm/lean/src/feature/timeout/.gitkeep +0 -0
  228. package/project/.sdk/tm/lean/test/StructCorpus.lean +697 -0
  229. package/project/.sdk/tm/lean/test/TFeature.lean +268 -0
  230. package/project/.sdk/tm/lean/test/TPrimaryUtility.lean +349 -0
  231. package/project/.sdk/tm/lua/Makefile +7 -7
  232. package/project/.sdk/tm/lua/feature/test_feature.lua +29 -1
  233. package/project/.sdk/tm/lua/test/primary_utility_test.lua +14 -8
  234. package/project/.sdk/tm/lua/utility/make_options.lua +39 -0
  235. package/project/.sdk/tm/perl/Makefile +6 -6
  236. package/project/.sdk/tm/perl/t/primary_utility.t +8 -17
  237. package/project/.sdk/tm/php/Makefile +6 -6
  238. package/project/.sdk/tm/php/feature/TestFeature.php +30 -2
  239. package/project/.sdk/tm/php/test/PrimaryUtilityTest.php +14 -7
  240. package/project/.sdk/tm/php/utility/MakeOptions.php +44 -0
  241. package/project/.sdk/tm/py/Makefile +6 -6
  242. package/project/.sdk/tm/py/feature/test_feature.py +28 -1
  243. package/project/.sdk/tm/py/test/test_primary_utility.py +18 -18
  244. package/project/.sdk/tm/py/utility/make_options.py +42 -0
  245. package/project/.sdk/tm/rb/Makefile +6 -6
  246. package/project/.sdk/tm/rb/feature/test_feature.rb +24 -1
  247. package/project/.sdk/tm/rb/test/primary_utility_test.rb +11 -8
  248. package/project/.sdk/tm/rb/utility/make_options.rb +37 -0
  249. package/project/.sdk/tm/rust/Makefile +6 -6
  250. package/project/.sdk/tm/rust/tests/common/mod.rs +37 -1
  251. package/project/.sdk/tm/rust/tests/primary_utility_test.rs +12 -26
  252. package/project/.sdk/tm/swift/Makefile +6 -6
  253. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/PrimaryUtilityTest.swift +7 -8
  254. package/project/.sdk/tm/ts/Makefile +6 -6
  255. package/project/.sdk/tm/ts/src/feature/test/TestFeature.ts +18 -1
  256. package/project/.sdk/tm/ts/src/utility/MakeOptionsUtility.ts +39 -1
  257. package/project/.sdk/tm/ts/test/utility/PrimaryUtility.test.ts +69 -21
  258. package/src/cmp/Deploy.ts +16 -16
  259. package/src/cmp/Entity.ts +5 -1
  260. package/src/cmp/Feature.ts +2 -1
  261. package/src/cmp/ReadmeTop.ts +13 -11
  262. package/src/helpers/canonType.ts +8 -3
  263. package/src/helpers/collectDeps.ts +39 -12
  264. package/src/helpers/naming.ts +130 -0
  265. package/src/helpers/opShape.ts +99 -12
  266. package/src/helpers/serverVars.ts +105 -0
  267. package/src/sdkgen.ts +12 -3
@@ -176,6 +176,9 @@ class PrimaryUtilityTest < Minitest::Test
176
176
  def test_fetcher_live
177
177
  calls = []
178
178
  live_client = ProjectNameSDK.new({
179
+ # Concrete base: a live construction must satisfy any server variables
180
+ # a templated base URL declares; a literal base sidesteps the requirement.
181
+ "base" => "http://localhost:8080",
179
182
  "system" => {
180
183
  "fetch" => ->(url, fetchdef) {
181
184
  calls << { "url" => url, "init" => fetchdef }
@@ -199,6 +202,7 @@ class PrimaryUtilityTest < Minitest::Test
199
202
 
200
203
  def test_fetcher_blocked_test_mode
201
204
  blocked_client = ProjectNameSDK.new({
205
+ "base" => "http://localhost:8080",
202
206
  "system" => {
203
207
  "fetch" => ->(url, fetchdef) {
204
208
  return {}, nil
@@ -610,14 +614,13 @@ class PrimaryUtilityTest < Minitest::Test
610
614
  # === preparePath ===
611
615
 
612
616
  def test_prepare_path_basic
613
- ctx = make_test_full_ctx(@client, @utility)
614
- ctx.point = {
615
- "parts" => ["api", "planet", "{id}"],
616
- "args" => { "params" => [] },
617
- }
618
-
619
- path = @utility.prepare_path.call(ctx)
620
- assert_equal "api/planet/{id}", path
617
+ # Was hand-written cases that had drifted out of the shared corpus
618
+ # (the preparePath fixture shipped as an empty `set: []`).
619
+ runset(get_spec(@primary, "preparePath", "basic")) do |entry|
620
+ ctxmap = entry["ctx"] || {}
621
+ ctx = make_ctx_from_map(ctxmap, @client, @utility)
622
+ @utility.prepare_path.call(ctx)
623
+ end
621
624
  end
622
625
 
623
626
  def test_prepare_path_single
@@ -52,6 +52,11 @@ module ProjectNameUtilities
52
52
  "system" => {},
53
53
  "test" => { "active" => false, "entity" => { "`$OPEN`" => true } },
54
54
  "clean" => { "keys" => "key,token,id" },
55
+ # Server-variable values for a templated base URL (OpenAPI server
56
+ # variables): {name} placeholders in "base" are substituted from this
57
+ # map at construction. Spec defaults arrive via the generated config;
58
+ # user values override them.
59
+ "server" => { "`$CHILD`" => "" },
55
60
  }
56
61
 
57
62
  sys_fetch = VoxgigStruct.getpath(opts, "system.fetch")
@@ -60,6 +65,38 @@ module ProjectNameUtilities
60
65
  validated = VoxgigStruct.validate(merged, optspec)
61
66
  opts = validated.is_a?(Hash) ? validated : {}
62
67
 
68
+ # Resolve a templated base URL (e.g. https://{tenant_id}.hanko.io).
69
+ # Every placeholder must resolve to a non-empty value: from
70
+ # options["server"] (user), else the config default. A placeholder that
71
+ # resolves to "" is a construction ERROR in live mode — the URL cannot
72
+ # work — but in test mode substitutes the deterministic value
73
+ # "test-<name>" so offline tests need no configuration.
74
+ base = opts["base"]
75
+ if base.is_a?(String) && base.include?("{")
76
+ testmode = VoxgigStruct.getpath(opts, "test.active") == true ||
77
+ VoxgigStruct.getpath(opts, "feature.test.active") == true
78
+ server = opts["server"].is_a?(Hash) ? opts["server"] : {}
79
+ sdkname = VoxgigStruct.getpath(config, "main.name")
80
+ sdkname = "SDK" unless sdkname.is_a?(String) && !sdkname.empty?
81
+ opts["base"] = base.gsub(/\{([A-Za-z0-9_]+)\}/) do
82
+ name = Regexp.last_match(1)
83
+ val = server[name]
84
+ val = "" unless val.is_a?(String)
85
+ if val.empty?
86
+ if testmode
87
+ "test-#{name}"
88
+ else
89
+ raise ArgumentError,
90
+ "#{sdkname}: the server variable '#{name}' is required: " \
91
+ "the API base URL is '#{base}' — pass " \
92
+ "{ \"server\" => { \"#{name}\" => \"...\" } } in the SDK options"
93
+ end
94
+ else
95
+ val
96
+ end
97
+ end
98
+ end
99
+
63
100
  if sys_fetch
64
101
  opts["system"] = {} unless opts["system"].is_a?(Hash)
65
102
  opts["system"]["fetch"] = sys_fetch
@@ -13,21 +13,21 @@ clean:
13
13
  # The crates.io registry entry is declared in the model with
14
14
  # state: 'pending' — a real deploy publishes the git tag rust/vX.Y.Z only;
15
15
  # `cargo publish` starts when the registry state flips to 'active'. Run
16
- # headless under the aql key vault, which injects the GitHub token so
16
+ # headless under the boru key vault, which injects the GitHub token so
17
17
  # nothing lands on disk or argv:
18
- # aql vault exec --for=github=<alias> -- make publish
19
- # aql `--dry-run` injects a filler token we detect to rehearse (no tag/push).
18
+ # boru vault exec --for=github=<alias> -- make publish
19
+ # boru `--dry-run` injects a filler token we detect to rehearse (no tag/push).
20
20
  # set -e + tag-last: a failed push never leaves a tag behind.
21
21
  VERSION := $(shell cat VERSION)
22
22
  TAG := rust/v$(VERSION)
23
- AQL_DRY_RUN_FILLER := AQL-DRY-RUN-FILLER-NOT-A-REAL-SECRET
23
+ BORU_DRY_RUN_FILLER := BORU-DRY-RUN-FILLER-NOT-A-REAL-SECRET
24
24
  publish:
25
25
  @if git rev-parse -q --verify "refs/tags/$(TAG)" >/dev/null; then \
26
26
  echo "tag $(TAG) already exists — bump VERSION first"; exit 1; fi
27
27
  @set -e; \
28
28
  token="$${GITHUB_TOKEN:-$$GH_TOKEN}"; \
29
- if [ "$$token" = "$(AQL_DRY_RUN_FILLER)" ]; then \
30
- echo "[dry-run] aql filler token detected: would tag $(TAG); nothing pushed."; \
29
+ if [ "$$token" = "$(BORU_DRY_RUN_FILLER)" ]; then \
30
+ echo "[dry-run] boru filler token detected: would tag $(TAG); nothing pushed."; \
31
31
  exit 0; \
32
32
  fi; \
33
33
  git tag -a "$(TAG)" -m "rust v$(VERSION)"; \
@@ -291,15 +291,51 @@ pub fn match_deep(check: &Value, base: &Value) -> Option<String> {
291
291
 
292
292
  // ---- runset (mirrors go runner_test.go runset) -----------------------------------
293
293
 
294
+ // Sections deliberately left empty in the shared corpus
295
+ // (.sdk/test/primary/<name>.aontu carries a PENDING header). Everything else
296
+ // MUST contribute cases.
297
+ pub const PENDING_SECTIONS: &[&str] = &[
298
+ "fetcher", "makeFetchDef", "makePoint", "makeResult", "featureAdd",
299
+ "featureHook", "featureInit",
300
+ ];
301
+
294
302
  pub fn runset(
295
303
  testspec: &Value,
296
304
  subject: &mut dyn FnMut(&Value) -> Result<Value, ProjectNameError>,
305
+ ) {
306
+ runset_named("", testspec, subject)
307
+ }
308
+
309
+ /// Drive one section of the shared test corpus.
310
+ ///
311
+ /// This used to `return` silently when "set" was missing or not a list, so a
312
+ /// renamed section, a fixture that failed to compile, or an empty set reported
313
+ /// PASS while running zero assertions — the whole point of a shared oracle lost
314
+ /// without a single red test. Both conditions now panic, except for the
315
+ /// sections explicitly marked PENDING in the corpus.
316
+ pub fn runset_named(
317
+ name: &str,
318
+ testspec: &Value,
319
+ subject: &mut dyn FnMut(&Value) -> Result<Value, ProjectNameError>,
297
320
  ) {
298
321
  let set = match getp(testspec, "set") {
299
322
  Value::List(l) => Value::List(l),
300
- _ => return,
323
+ _ => panic!(
324
+ "test corpus section {:?} has no `set` list — zero cases would run",
325
+ name
326
+ ),
301
327
  };
302
328
 
329
+ if let Value::List(l) = &set {
330
+ if l.borrow().is_empty() && !PENDING_SECTIONS.contains(&name) {
331
+ panic!(
332
+ "test corpus section {:?} is EMPTY — zero cases would run; add \
333
+ cases, or mark the fixture PENDING in .sdk/test/primary/",
334
+ name
335
+ );
336
+ }
337
+ }
338
+
303
339
  let entries: Vec<Value> = match &set {
304
340
  Value::List(l) => l.borrow().clone(),
305
341
  _ => Vec::new(),
@@ -810,35 +810,21 @@ fn primary_prepare_params_basic() {
810
810
  );
811
811
  }
812
812
 
813
+ // Was two hand-written cases that had drifted out of the shared corpus (the
814
+ // preparePath fixture shipped as an empty `set: []`). Now driven by the
815
+ // corpus like every other section, so all ports assert the same separator /
816
+ // blank-segment behaviour.
813
817
  #[test]
814
818
  fn primary_prepare_path_basic() {
815
819
  let (client, utility) = base_client();
816
- let ctx = make_test_full_ctx(&client, &utility);
817
- *ctx.point.borrow_mut() = jo(vec![
818
- (
819
- "parts",
820
- ja(vec![
821
- Value::str("api"),
822
- Value::str("planet"),
823
- Value::str("{id}"),
824
- ]),
825
- ),
826
- ("args", jo(vec![("params", Value::empty_list())])),
827
- ]);
828
-
829
- assert_eq!(utility.prepare_path(&ctx), "api/planet/{id}");
830
- }
831
-
832
- #[test]
833
- fn primary_prepare_path_single() {
834
- let (client, utility) = base_client();
835
- let ctx = make_test_full_ctx(&client, &utility);
836
- *ctx.point.borrow_mut() = jo(vec![
837
- ("parts", ja(vec![Value::str("items")])),
838
- ("args", jo(vec![("params", Value::empty_list())])),
839
- ]);
840
-
841
- assert_eq!(utility.prepare_path(&ctx), "items");
820
+ let primary = primary();
821
+ runset(
822
+ &get_spec(&primary, &["preparePath", "basic"]),
823
+ &mut |entry| {
824
+ let ctx = make_ctx_from_map(&getp(entry, "ctx"), &client, &utility);
825
+ Ok(Value::str(utility.prepare_path(&ctx)))
826
+ },
827
+ );
842
828
  }
843
829
 
844
830
  #[test]
@@ -13,21 +13,21 @@ clean:
13
13
  # --- Release: tag for the SwiftPM registry ---------------------------------
14
14
  # SwiftPM has no upload step - publishing IS the git tag. Publication is
15
15
  # pending (see model/target/swift.aontu publish block); publishing a version
16
- # currently means pushing the tag swift/vX.Y.Z. Run headless under the aql key
16
+ # currently means pushing the tag swift/vX.Y.Z. Run headless under the boru key
17
17
  # vault, which injects the GitHub token so nothing lands on disk or argv:
18
- # aql vault exec --for=github=<alias> -- make publish
19
- # aql `--dry-run` injects a filler token we detect to rehearse (no tag/push).
18
+ # boru vault exec --for=github=<alias> -- make publish
19
+ # boru `--dry-run` injects a filler token we detect to rehearse (no tag/push).
20
20
  # set -e + tag-last: a failed push never leaves a tag behind.
21
21
  VERSION := $(shell cat VERSION)
22
22
  TAG := swift/v$(VERSION)
23
- AQL_DRY_RUN_FILLER := AQL-DRY-RUN-FILLER-NOT-A-REAL-SECRET
23
+ BORU_DRY_RUN_FILLER := BORU-DRY-RUN-FILLER-NOT-A-REAL-SECRET
24
24
  publish: test
25
25
  @if git rev-parse -q --verify "refs/tags/$(TAG)" >/dev/null; then \
26
26
  echo "tag $(TAG) already exists - bump VERSION first"; exit 1; fi
27
27
  @set -e; \
28
28
  token="$${GITHUB_TOKEN:-$$GH_TOKEN}"; \
29
- if [ "$$token" = "$(AQL_DRY_RUN_FILLER)" ]; then \
30
- echo "[dry-run] aql filler token detected: would tag $(TAG); nothing pushed."; \
29
+ if [ "$$token" = "$(BORU_DRY_RUN_FILLER)" ]; then \
30
+ echo "[dry-run] boru filler token detected: would tag $(TAG); nothing pushed."; \
31
31
  exit 0; \
32
32
  fi; \
33
33
  git tag -a "$(TAG)" -m "swift v$(VERSION)"; \
@@ -629,14 +629,13 @@ final class PrimaryUtilityTest: XCTestCase {
629
629
  }
630
630
 
631
631
  func testPreparePathBasic() {
632
- let ctx = makeTestFullCtx(client, utility)
633
- ctx.point = vm(
634
- ("parts", .list([.string("api"), .string("planet"), .string("{id}")])),
635
- ("args", .map(vm(("params", .list([])))))
636
- )
637
-
638
- let path = utility.preparePath(ctx)
639
- XCTAssertEqual(path, "api/planet/{id}")
632
+ // Was hand-written cases that had drifted out of the shared corpus
633
+ // (the preparePath fixture shipped as an empty `set: []`).
634
+ SdkRunner.runSet(SdkRunner.spec(primary, "preparePath", "basic")) { entry in
635
+ let ctxmap = entry.entries["ctx"]?.asMap
636
+ let ctx = SdkRunner.makeCtxFromMap(ctxmap, self.client, self.utility)
637
+ return .string(self.utility.preparePath(ctx))
638
+ }
640
639
  }
641
640
 
642
641
  func testPreparePathSingle() {
@@ -17,22 +17,22 @@ clean:
17
17
 
18
18
  # --- Release: publish to npm ----------------------------------------------
19
19
  # Compile, then publish this package to npm and tag ts/vX.Y.Z. Run headless
20
- # under the aql key vault, which injects the npm auth token + the GitHub token
20
+ # under the boru key vault, which injects the npm auth token + the GitHub token
21
21
  # (never on disk or argv):
22
- # aql vault exec --for=npm=<alias> --for=github=<alias> -- make publish
23
- # aql `--dry-run` injects a filler token we detect to rehearse (build only, no
22
+ # boru vault exec --for=npm=<alias> --for=github=<alias> -- make publish
23
+ # boru `--dry-run` injects a filler token we detect to rehearse (build only, no
24
24
  # publish/tag). set -e + tag-last: a failed publish never leaves a tag behind.
25
25
  SHELL := /bin/bash
26
26
  VERSION := $(shell node -p "require('./package.json').version")
27
27
  TAG := ts/v$(VERSION)
28
- AQL_DRY_RUN_FILLER := AQL-DRY-RUN-FILLER-NOT-A-REAL-SECRET
28
+ BORU_DRY_RUN_FILLER := BORU-DRY-RUN-FILLER-NOT-A-REAL-SECRET
29
29
  publish: test
30
30
  @if git rev-parse -q --verify "refs/tags/$(TAG)" >/dev/null; then \
31
31
  echo "tag $(TAG) already exists — bump package.json version first"; exit 1; fi
32
32
  @set -e; \
33
33
  token="$${GITHUB_TOKEN:-$$GH_TOKEN}"; \
34
- if [ "$$token" = "$(AQL_DRY_RUN_FILLER)" ]; then \
35
- echo "[dry-run] aql filler token detected: would publish to npm and tag $(TAG); nothing pushed."; \
34
+ if [ "$$token" = "$(BORU_DRY_RUN_FILLER)" ]; then \
35
+ echo "[dry-run] boru filler token detected: would publish to npm and tag $(TAG); nothing pushed."; \
36
36
  exit 0; \
37
37
  fi; \
38
38
  npm stage publish --access public --registry https://registry.npmjs.org; \
@@ -52,12 +52,29 @@ class TestFeature extends BaseFeature {
52
52
  const delprop = struct.delprop
53
53
  const getdef = struct.getdef
54
54
 
55
+ // Shape the mock payload the way the real API would, so the op's
56
+ // response transform recovers the entity from it. A point carrying
57
+ // `transform.res: \`body.item\`` describes an API that answers
58
+ // `{item: {...}}`; handing back the bare entity means the transform
59
+ // unwraps a property that is not there and the caller gets undefined.
60
+ // The mock has to agree with the model, or it only ever simulates APIs
61
+ // whose responses happen to be unwrapped.
62
+ function envelope(data: any) {
63
+ const restf = getprop(getprop(ctx.point, 'transform', {}), 'res')
64
+ if (null == data || 'string' !== typeof restf) {
65
+ return data
66
+ }
67
+ const m = restf.match(/^`body\.([^`.]+)`$/)
68
+ return null == m ? data : { [m[1]]: data }
69
+ }
70
+
55
71
  function respond(status: number, data?: any, res?: any) {
72
+ const payload = envelope(data)
56
73
  const out = merge([
57
74
  {
58
75
  status,
59
76
  statusText: 'OK',
60
- json: async () => data,
77
+ json: async () => payload,
61
78
  body: 'not-used',
62
79
  },
63
80
  getdef(res, {})
@@ -82,16 +82,54 @@ function makeOptions(ctx: Context) {
82
82
  },
83
83
  clean: {
84
84
  keys: 'key,token,id'
85
+ },
86
+ // Server-variable values for a templated base URL (OpenAPI server
87
+ // variables): `{name}` placeholders in `base` are substituted from
88
+ // this map at construction. Spec defaults arrive via the generated
89
+ // Config; user values override them.
90
+ server: {
91
+ '`$CHILD`': ''
85
92
  }
86
93
  }
87
94
 
88
95
  // JavaScript specific option values.
89
96
  optspec.system.fetch = opts.system?.fetch || global.fetch
90
97
 
91
- opts = merge([{}, cfgopts, opts])
98
+ // Clone the config side before merging: `config` is a module-level
99
+ // singleton in ts/js, and merge would otherwise use its nested maps as
100
+ // merge TARGETS — one instance's options (server, headers, ...) would
101
+ // contaminate every instance constructed after it.
102
+ opts = merge([{}, struct.clone(cfgopts), opts])
92
103
 
93
104
  opts = validate(opts, optspec)
94
105
 
106
+ // Resolve a templated base URL (e.g. https://{tenant_id}.hanko.io).
107
+ // Every placeholder must resolve to a non-empty value: from
108
+ // options.server (user), else the Config default. A placeholder that
109
+ // resolves to '' is a construction ERROR in live mode — the URL cannot
110
+ // work — but in test mode substitutes the deterministic value
111
+ // `test-<name>` so offline tests need no configuration.
112
+ if ('string' === typeof opts.base && opts.base.includes('{')) {
113
+ const testmode = true === opts.test.active ||
114
+ true === (opts.feature && opts.feature.test && opts.feature.test.active)
115
+ const server = opts.server || {}
116
+ opts.base = opts.base.replace(/\{([A-Za-z0-9_]+)\}/g,
117
+ (_m: string, name: string) => {
118
+ let val = server[name]
119
+ val = 'string' === typeof val ? val : ''
120
+ if ('' === val) {
121
+ if (testmode) {
122
+ return 'test-' + name
123
+ }
124
+ throw new Error(
125
+ `${config?.main?.name || 'SDK'}: the server variable '${name}' is required: ` +
126
+ `the API base URL is '${opts.base}' — pass { server: { ${name}: '...' } } ` +
127
+ `in the SDK options`)
128
+ }
129
+ return val
130
+ })
131
+ }
132
+
95
133
  // Resolve the feature add-order: an explicit array order (above) wins;
96
134
  // otherwise order the map test-first, then the remaining names sorted, so
97
135
  // the outcome is deterministic and `test` is always the base transport.
@@ -31,6 +31,38 @@ describe('PrimaryUtility', async () => {
31
31
  }
32
32
 
33
33
 
34
+ // Sections deliberately left empty in the shared corpus
35
+ // (.sdk/test/primary/<name>.aontu carries a PENDING header). Everything
36
+ // else MUST contribute cases.
37
+ const PENDING = new Set([
38
+ 'fetcher', 'makeFetchDef', 'makePoint', 'makeResult',
39
+ 'featureAdd', 'featureHook', 'featureInit',
40
+ ])
41
+
42
+ // Run one corpus section, failing loudly when it would run ZERO cases.
43
+ // A renamed section or a fixture that compiled to an empty `set` used to
44
+ // pass silently, which defeats the point of a shared oracle. (The guard
45
+ // lives here rather than in runner.ts, which is vendored verbatim from
46
+ // @voxgig/struct and must stay byte-identical to upstream.)
47
+ //
48
+ // EVERY corpus-backed test goes through here — a guard that only some
49
+ // sections opt into leaves the rest able to run zero assertions, which is
50
+ // the exact hole it was added to close.
51
+ async function runsection(name: string, subject: Function) {
52
+ const section = spec[name]
53
+ ok(null != section,
54
+ `test corpus section '${name}' missing — check the name against .sdk/test/primary/`)
55
+ ok(null != section.basic && Array.isArray(section.basic.set),
56
+ `test corpus section '${name}' has no basic.set list`)
57
+ if (0 === section.basic.set.length && !PENDING.has(name)) {
58
+ throw new Error(
59
+ `test corpus section '${name}' is EMPTY — zero cases would run; ` +
60
+ `add cases, or mark the fixture PENDING in .sdk/test/primary/`)
61
+ }
62
+ return runset(section.basic, subject)
63
+ }
64
+
65
+
34
66
  before(async () => {
35
67
  const runner = await makeRunner(TEST_JSON_FILE, await SDK.test())
36
68
  const run = await runner('primary')
@@ -61,24 +93,24 @@ describe('PrimaryUtility', async () => {
61
93
 
62
94
 
63
95
  test('context-basic', async () => {
64
- await runset(spec.makeContext.basic, utility.makeContext)
96
+ await runsection('makeContext', utility.makeContext)
65
97
  })
66
98
 
67
99
 
68
100
  test('method-basic', async () => {
69
- await runset(spec.prepareMethod.basic, utility.prepareMethod)
101
+ await runsection('prepareMethod', utility.prepareMethod)
70
102
  })
71
103
 
72
104
 
73
105
  test('headers-basic', async () => {
74
- await runset(spec.prepareHeaders.basic, utility.prepareHeaders)
106
+ await runsection('prepareHeaders', utility.prepareHeaders)
75
107
  })
76
108
 
77
109
 
78
110
  test('auth-basic', async () => {
79
111
  const sdkopts = spec.prepareAuth?.DEF?.setup?.a || {}
80
112
  const authClient = SDK.test({}, sdkopts)
81
- await runset(spec.prepareAuth.basic, (ctx: any) => {
113
+ await runsection('prepareAuth', (ctx: any) => {
82
114
  ctx.client = authClient
83
115
  fixctx(ctx)
84
116
  return utility.prepareAuth(ctx)
@@ -87,17 +119,17 @@ describe('PrimaryUtility', async () => {
87
119
 
88
120
 
89
121
  test('params-basic', async () => {
90
- await runset(spec.prepareParams.basic, utility.prepareParams)
122
+ await runsection('prepareParams', utility.prepareParams)
91
123
  })
92
124
 
93
125
 
94
126
  test('query-basic', async () => {
95
- await runset(spec.prepareQuery.basic, utility.prepareQuery)
127
+ await runsection('prepareQuery', utility.prepareQuery)
96
128
  })
97
129
 
98
130
 
99
131
  test('body-basic', async () => {
100
- await runset(spec.prepareBody.basic, (ctx: any) => {
132
+ await runsection('prepareBody', (ctx: any) => {
101
133
  fixctx(ctx)
102
134
  return utility.prepareBody(ctx)
103
135
  })
@@ -105,17 +137,17 @@ describe('PrimaryUtility', async () => {
105
137
 
106
138
 
107
139
  test('findparam-basic', async () => {
108
- await runset(spec.param.basic, utility.param)
140
+ await runsection('param', utility.param)
109
141
  })
110
142
 
111
143
 
112
144
  test('fullurl-basic', async () => {
113
- await runset(spec.makeUrl.basic, utility.makeUrl)
145
+ await runsection('makeUrl', utility.makeUrl)
114
146
  })
115
147
 
116
148
 
117
149
  test('operator-basic', async () => {
118
- await runset(spec.operator.basic, (opmap: any) => ({
150
+ await runsection('operator', (opmap: any) => ({
119
151
  entity: opmap.entity || '_',
120
152
  name: opmap.name || '_',
121
153
  input: opmap.input || '_',
@@ -125,7 +157,7 @@ describe('PrimaryUtility', async () => {
125
157
 
126
158
 
127
159
  test('options-basic', async () => {
128
- await runset(spec.makeOptions.basic, (vin: any) => {
160
+ await runsection('makeOptions', (vin: any) => {
129
161
  const ctx = utility.makeContext({ options: vin.options, config: vin.config })
130
162
  ctx.client = client
131
163
  ctx.utility = utility
@@ -137,7 +169,7 @@ describe('PrimaryUtility', async () => {
137
169
  test('spec-basic', async () => {
138
170
  const sdkopts = spec.makeSpec?.DEF?.setup?.a || {}
139
171
  const specClient = SDK.test({}, sdkopts)
140
- await runset(spec.makeSpec.basic, (ctx: any) => {
172
+ await runsection('makeSpec', (ctx: any) => {
141
173
  ctx.client = specClient
142
174
  ctx.options = specClient.options()
143
175
  return utility.makeSpec(ctx)
@@ -146,17 +178,17 @@ describe('PrimaryUtility', async () => {
146
178
 
147
179
 
148
180
  test('reqform-basic', async () => {
149
- await runset(spec.transformRequest.basic, utility.transformRequest)
181
+ await runsection('transformRequest', utility.transformRequest)
150
182
  })
151
183
 
152
184
 
153
185
  test('resform-basic', async () => {
154
- await runset(spec.transformResponse.basic, utility.transformResponse)
186
+ await runsection('transformResponse', utility.transformResponse)
155
187
  })
156
188
 
157
189
 
158
190
  test('resbasic-basic', async () => {
159
- await runset(spec.resultBasic.basic, (ctx: any) => {
191
+ await runsection('resultBasic', (ctx: any) => {
160
192
  fixctx(ctx)
161
193
  return utility.resultBasic(ctx)
162
194
  })
@@ -164,7 +196,7 @@ describe('PrimaryUtility', async () => {
164
196
 
165
197
 
166
198
  test('resheaders-basic', async () => {
167
- await runset(spec.resultHeaders.basic, (ctx: any) => {
199
+ await runsection('resultHeaders', (ctx: any) => {
168
200
  // Convert plain headers map to forEach-based (browser Response API)
169
201
  if (ctx.response?.headers && !ctx.response.headers.forEach) {
170
202
  const h = ctx.response.headers
@@ -178,7 +210,7 @@ describe('PrimaryUtility', async () => {
178
210
 
179
211
 
180
212
  test('resbody-basic', async () => {
181
- await runset(spec.resultBody.basic, async (ctx: any) => {
213
+ await runsection('resultBody', async (ctx: any) => {
182
214
  if (ctx.response && !ctx.response.json) {
183
215
  const body = ctx.response.body
184
216
  ctx.response.json = async () => body
@@ -197,10 +229,12 @@ describe('PrimaryUtility', async () => {
197
229
  body: 'present',
198
230
  })
199
231
  const reqClient = new (SDK as any)({
232
+ // Concrete base: a live construction must satisfy any server variables a templated base URL declares; a literal base sidesteps the requirement.
233
+ base: 'http://localhost:8080',
200
234
  system: { fetch: mockFetch }
201
235
  })
202
236
  const reqUtility = reqClient.utility()
203
- await runset(spec.makeRequest.basic, async (ctx: any) => {
237
+ await runsection('makeRequest', async (ctx: any) => {
204
238
  ctx.client = reqClient
205
239
  ctx.utility = reqUtility
206
240
  ctx.options = reqClient.options()
@@ -210,7 +244,7 @@ describe('PrimaryUtility', async () => {
210
244
 
211
245
 
212
246
  test('response-basic', async () => {
213
- await runset(spec.makeResponse.basic, async (ctx: any) => {
247
+ await runsection('makeResponse', async (ctx: any) => {
214
248
  fixctx(ctx)
215
249
  // Add json() and forEach to response for proper TS handling
216
250
  if (ctx.response && !ctx.response.json) {
@@ -229,7 +263,7 @@ describe('PrimaryUtility', async () => {
229
263
 
230
264
 
231
265
  test('done-basic', async () => {
232
- await runset(spec.done.basic, (ctx: any) => {
266
+ await runsection('done', (ctx: any) => {
233
267
  fixctx(ctx)
234
268
  return utility.done(ctx)
235
269
  })
@@ -237,7 +271,7 @@ describe('PrimaryUtility', async () => {
237
271
 
238
272
 
239
273
  test('error-basic', async () => {
240
- await runset(spec.makeError.basic, (...args: any[]) => {
274
+ await runsection('makeError', (...args: any[]) => {
241
275
  const ctx = args[0]
242
276
  fixctx(ctx)
243
277
  return utility.makeError(...args)
@@ -378,6 +412,7 @@ describe('PrimaryUtility', async () => {
378
412
  test('fetcher-live', async () => {
379
413
  const calls: any[] = []
380
414
  const liveClient = new (SDK as any)({
415
+ base: 'http://localhost:8080',
381
416
  system: {
382
417
  fetch: async (url: string, init: any) => {
383
418
  calls.push({ url, init })
@@ -399,6 +434,7 @@ describe('PrimaryUtility', async () => {
399
434
 
400
435
  test('fetcher-blocked-test-mode', async () => {
401
436
  const blockedClient = new (SDK as any)({
437
+ base: 'http://localhost:8080',
402
438
  system: { fetch: async () => ({}) }
403
439
  })
404
440
  blockedClient._mode = 'test'
@@ -424,6 +460,18 @@ describe('PrimaryUtility', async () => {
424
460
  })
425
461
 
426
462
 
463
+ test('path-basic', async () => {
464
+ // preparePath shipped as an empty `set: []` — every port "passed" it while
465
+ // running zero cases. Now corpus-driven like every other section.
466
+ await runsection('preparePath', (ctx: any) => utility.preparePath(ctx))
467
+ })
468
+
469
+
470
+ test('clean-corpus', async () => {
471
+ await runsection('clean', (...args: any[]) => utility.clean(args[0], args[1]))
472
+ })
473
+
474
+
427
475
  test('clean', () => {
428
476
  const ctx = makeFullCtx()
429
477
  const val = { key: 'secret123', name: 'test' }