@voxgig/sdkgen 4.8.2 → 4.9.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 (407) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/dist/action/doctor.d.ts +1 -0
  3. package/dist/action/doctor.js +50 -2
  4. package/dist/action/doctor.js.map +1 -1
  5. package/dist/helpers/naming.js +4 -2
  6. package/dist/helpers/naming.js.map +1 -1
  7. package/dist/tsconfig.tsbuildinfo +1 -1
  8. package/model/sdkgen.aon +21 -0
  9. package/package.json +1 -1
  10. package/project/.sdk/model/feature/secrets.aon +120 -18
  11. package/project/.sdk/model/target/c.aon +10 -0
  12. package/project/.sdk/model/target/clojure.aon +13 -0
  13. package/project/.sdk/model/target/cpp.aon +10 -0
  14. package/project/.sdk/model/target/csharp.aon +9 -0
  15. package/project/.sdk/model/target/dart.aon +10 -0
  16. package/project/.sdk/model/target/elixir.aon +9 -0
  17. package/project/.sdk/model/target/go.aon +13 -0
  18. package/project/.sdk/model/target/java.aon +9 -0
  19. package/project/.sdk/model/target/js.aon +7 -0
  20. package/project/.sdk/model/target/kotlin.aon +9 -0
  21. package/project/.sdk/model/target/lean.aon +17 -0
  22. package/project/.sdk/model/target/lua.aon +8 -0
  23. package/project/.sdk/model/target/ocaml.aon +9 -0
  24. package/project/.sdk/model/target/perl.aon +8 -0
  25. package/project/.sdk/model/target/php.aon +8 -0
  26. package/project/.sdk/model/target/py.aon +13 -0
  27. package/project/.sdk/model/target/rb.aon +8 -0
  28. package/project/.sdk/model/target/rust.aon +10 -0
  29. package/project/.sdk/model/target/scala.aon +21 -2
  30. package/project/.sdk/model/target/swift.aon +18 -0
  31. package/project/.sdk/model/target/ts.aon +13 -0
  32. package/project/.sdk/model/target/zig.aon +9 -0
  33. package/project/.sdk/src/cmp/clojure/Package_clojure.ts +9 -2
  34. package/project/.sdk/src/cmp/cpp/Gitignore_cpp.ts +3 -0
  35. package/project/.sdk/src/cmp/dart/Test_dart.ts +2 -0
  36. package/project/.sdk/src/cmp/elixir/Package_elixir.ts +4 -1
  37. package/project/.sdk/src/cmp/go/Config_go.ts +59 -2
  38. package/project/.sdk/src/cmp/go/Main_go.ts +8 -2
  39. package/project/.sdk/src/cmp/java/Test_java.ts +6 -5
  40. package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +6 -5
  41. package/project/.sdk/src/cmp/lean/Package_lean.ts +23 -0
  42. package/project/.sdk/src/cmp/lean/ReadmeInstall_lean.ts +1 -0
  43. package/project/.sdk/src/cmp/lean/ReadmeTopTest_lean.ts +1 -0
  44. package/project/.sdk/src/cmp/ocaml/Gitignore_ocaml.ts +1 -0
  45. package/project/.sdk/src/cmp/ocaml/Main_ocaml.ts +7 -3
  46. package/project/.sdk/src/cmp/py/Config_py.ts +82 -1
  47. package/project/.sdk/src/cmp/py/Main_py.ts +44 -0
  48. package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +2 -0
  49. package/project/.sdk/src/cmp/swift/Main_swift.ts +10 -0
  50. package/project/.sdk/src/cmp/swift/Package_swift.ts +13 -1
  51. package/project/.sdk/src/cmp/ts/Config_ts.ts +42 -17
  52. package/project/.sdk/src/cmp/ts/fragment/Config.data.fragment.ts +13 -1
  53. package/project/.sdk/src/cmp/ts/fragment/Config.fragment.ts +13 -1
  54. package/project/.sdk/src/cmp/zig/Package_zig.ts +15 -11
  55. package/project/.sdk/src/cmp/zig/fragment/Entity.fragment.zig +3 -3
  56. package/project/.sdk/src/cmp/zig/fragment/EntityListOp.fragment.zig +3 -3
  57. package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +3 -3
  58. package/project/.sdk/src/cmp/zig/utility_zig.ts +50 -1
  59. package/project/.sdk/tm/c/Makefile +38 -3
  60. package/project/.sdk/tm/c/tests/omni_resolver.h +361 -0
  61. package/project/.sdk/tm/c/tests/omni_smoke_test.c +237 -0
  62. package/project/.sdk/tm/c/tests/primary_corpus_test.c +205 -284
  63. package/project/.sdk/tm/c/tests/struct_corpus_test.c +292 -212
  64. package/project/.sdk/tm/c/tests/vendor/omni/json.c +811 -0
  65. package/project/.sdk/tm/c/tests/vendor/omni/omni.h +240 -0
  66. package/project/.sdk/tm/c/tests/vendor/omni/runner.c +940 -0
  67. package/project/.sdk/tm/c/tests/vendor/omni/util.c +351 -0
  68. package/project/.sdk/tm/c/utility/struct/utility.c +7 -2
  69. package/project/.sdk/tm/clojure/test/sdk/test/omni.clj +401 -0
  70. package/project/.sdk/tm/clojure/test/sdk/test/omni_smoke.clj +81 -0
  71. package/project/.sdk/tm/clojure/test/sdk/test/primary.clj +92 -58
  72. package/project/.sdk/tm/clojure/test/sdk/test/struct_corpus.clj +122 -149
  73. package/project/.sdk/tm/clojure/test/sdk/test_runner.clj +8 -3
  74. package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/json.clj +145 -0
  75. package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/runner.clj +445 -0
  76. package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/util.clj +145 -0
  77. package/project/.sdk/tm/cpp/Makefile +5 -1
  78. package/project/.sdk/tm/cpp/test/omni_resolver.hpp +473 -0
  79. package/project/.sdk/tm/cpp/test/omni_smoke_test.cpp +209 -0
  80. package/project/.sdk/tm/cpp/test/primary_utility_test.cpp +243 -184
  81. package/project/.sdk/tm/cpp/test/runner_support.hpp +68 -181
  82. package/project/.sdk/tm/cpp/test/struct_corpus_test.cpp +183 -56
  83. package/project/.sdk/tm/cpp/test/vendor/omni/json.hpp +406 -0
  84. package/project/.sdk/tm/cpp/test/vendor/omni/omni.hpp +751 -0
  85. package/project/.sdk/tm/cpp/test/vendor/omni/util.hpp +256 -0
  86. package/project/.sdk/tm/cpp/utility/pipeline.hpp +7 -1
  87. package/project/.sdk/tm/csharp/test/OmniResolver.cs +491 -0
  88. package/project/.sdk/tm/csharp/test/OmniSmokeTest.cs +106 -0
  89. package/project/.sdk/tm/csharp/test/PrimaryUtilityTest.cs +299 -316
  90. package/project/.sdk/tm/csharp/test/Runner.cs +104 -269
  91. package/project/.sdk/tm/csharp/test/StructUtilityTest.cs +535 -724
  92. package/project/.sdk/tm/csharp/test/vendor/omni/Runner.cs +864 -0
  93. package/project/.sdk/tm/csharp/test/vendor/omni/Util.cs +347 -0
  94. package/project/.sdk/tm/csharp/utility/MakeSpec.cs +3 -1
  95. package/project/.sdk/tm/csharp/utility/PrepareMethod.cs +6 -1
  96. package/project/.sdk/tm/csharp/utility/struct/Struct.cs +21 -5
  97. package/project/.sdk/tm/dart/test/omni.dart +520 -0
  98. package/project/.sdk/tm/dart/test/omni_smoke_test.dart +143 -0
  99. package/project/.sdk/tm/dart/test/primary_test.dart +86 -28
  100. package/project/.sdk/tm/dart/test/struct_test.dart +438 -11
  101. package/project/.sdk/tm/dart/test/vendor/omni/omni.dart +7 -0
  102. package/project/.sdk/tm/dart/test/vendor/omni/runner.dart +653 -0
  103. package/project/.sdk/tm/dart/test/vendor/omni/util.dart +232 -0
  104. package/project/.sdk/tm/elixir/Makefile +11 -3
  105. package/project/.sdk/tm/elixir/test/omni_smoke_test.exs +117 -0
  106. package/project/.sdk/tm/elixir/test/primary_utility_test.exs +341 -16
  107. package/project/.sdk/tm/elixir/test/struct_corpus_test.exs +554 -9
  108. package/project/.sdk/tm/elixir/test/support/omni.ex +377 -0
  109. package/project/.sdk/tm/elixir/test/vendor/omni/json.ex +122 -0
  110. package/project/.sdk/tm/elixir/test/vendor/omni/runner.ex +623 -0
  111. package/project/.sdk/tm/elixir/test/vendor/omni/util.ex +187 -0
  112. package/project/.sdk/tm/go/core/context.go +32 -16
  113. package/project/.sdk/tm/go/feature/secrets/plugin/capability.go +261 -0
  114. package/project/.sdk/tm/go/feature/secrets/plugin/catalog.go +78 -0
  115. package/project/.sdk/tm/go/feature/secrets/plugin/config.go +652 -0
  116. package/project/.sdk/tm/go/feature/secrets/plugin/depend.go +250 -0
  117. package/project/.sdk/tm/go/feature/secrets/plugin/env.go +194 -0
  118. package/project/.sdk/tm/go/feature/secrets/plugin/export.go +80 -0
  119. package/project/.sdk/tm/go/feature/secrets/plugin/graph.go +238 -0
  120. package/project/.sdk/tm/go/feature/secrets/plugin/host.go +1575 -0
  121. package/project/.sdk/tm/go/feature/secrets/plugin/order.go +248 -0
  122. package/project/.sdk/tm/go/feature/secrets/plugin/point.go +184 -0
  123. package/project/.sdk/tm/go/feature/secrets/plugin/ref.go +123 -0
  124. package/project/.sdk/tm/go/feature/secrets/plugin/resolve.go +79 -0
  125. package/project/.sdk/tm/go/feature/secrets/plugin/types.go +296 -0
  126. package/project/.sdk/tm/go/feature/secrets/plugin/util.go +87 -0
  127. package/project/.sdk/tm/go/feature/secrets/plugin/version.go +161 -0
  128. package/project/.sdk/tm/go/feature/secrets/plugins/aws/aws.go +292 -0
  129. package/project/.sdk/tm/go/feature/secrets/plugins/aws/sigv4.go +201 -0
  130. package/project/.sdk/tm/go/feature/secrets/plugins/azuresecrets/azuresecrets.go +187 -0
  131. package/project/.sdk/tm/go/feature/secrets/plugins/boru/boru.go +184 -0
  132. package/project/.sdk/tm/go/feature/secrets/plugins/doppler/doppler.go +114 -0
  133. package/project/.sdk/tm/go/feature/secrets/plugins/gcpsecrets/gcpsecrets.go +156 -0
  134. package/project/.sdk/tm/go/feature/secrets/plugins/hashicorp/hashicorp.go +208 -0
  135. package/project/.sdk/tm/go/feature/secrets/plugins/httpjson/httpjson.go +241 -0
  136. package/project/.sdk/tm/go/feature/secrets/plugins/infisical/infisical.go +150 -0
  137. package/project/.sdk/tm/go/feature/secrets/plugins/onepassword/onepassword.go +152 -0
  138. package/project/.sdk/tm/go/feature/secrets/plugins/secretspec/secretspec.go +143 -0
  139. package/project/.sdk/tm/go/feature/secrets/sekreto/addr.go +120 -0
  140. package/project/.sdk/tm/go/feature/secrets/sekreto/providers.go +442 -0
  141. package/project/.sdk/tm/go/feature/secrets/sekreto/sekreto.go +714 -0
  142. package/project/.sdk/tm/go/feature/secrets_feature.go +675 -0
  143. package/project/.sdk/tm/go/src/feature/secrets/.gitkeep +0 -0
  144. package/project/.sdk/tm/go/test/feature/secrets/secrets_feature_test.go +799 -0
  145. package/project/.sdk/tm/go/test/omni/omni.go +902 -0
  146. package/project/.sdk/tm/go/test/omni/util.go +381 -0
  147. package/project/.sdk/tm/go/test/omniresolver_test.go +748 -0
  148. package/project/.sdk/tm/go/test/omnismoke_test.go +112 -0
  149. package/project/.sdk/tm/go/test/primary_utility_test.go +123 -191
  150. package/project/.sdk/tm/go/test/struct_utility_test.go +323 -16
  151. package/project/.sdk/tm/go/test/testsupport_test.go +294 -0
  152. package/project/.sdk/tm/go/utility/make_options.go +8 -1
  153. package/project/.sdk/tm/go/utility/prepare_method.go +5 -1
  154. package/project/.sdk/tm/go/utility/struct/voxgigstruct.go +2 -2
  155. package/project/.sdk/tm/java/test/OmniResolver.java +355 -0
  156. package/project/.sdk/tm/java/test/OmniSmokeTest.java +99 -0
  157. package/project/.sdk/tm/java/test/PrimaryUtilityTest.java +254 -280
  158. package/project/.sdk/tm/java/test/RunnerSupport.java +9 -194
  159. package/project/.sdk/tm/java/test/StructCorpusTest.java +119 -42
  160. package/project/.sdk/tm/java/test/vendor/omni/Json.java +287 -0
  161. package/project/.sdk/tm/java/test/vendor/omni/Runner.java +851 -0
  162. package/project/.sdk/tm/java/test/vendor/omni/Util.java +322 -0
  163. package/project/.sdk/tm/java/utility/MakeSpec.java +3 -1
  164. package/project/.sdk/tm/java/utility/PrepareMethod.java +5 -5
  165. package/project/.sdk/tm/java/utility/struct/Struct.java +17 -4
  166. package/project/.sdk/tm/js/src/utility/StructUtility.js +3 -3
  167. package/project/.sdk/tm/js/test/omni.js +251 -0
  168. package/project/.sdk/tm/js/test/omni.test.js +105 -0
  169. package/project/.sdk/tm/js/test/utility/PrimaryUtility.test.js +6 -2
  170. package/project/.sdk/tm/js/test/utility/StructUtility.test.js +27 -2
  171. package/project/.sdk/tm/js/test/vendor/omni/index.js +77 -0
  172. package/project/.sdk/tm/js/test/vendor/omni/runner.js +628 -0
  173. package/project/.sdk/tm/js/test/vendor/omni/util.js +229 -0
  174. package/project/.sdk/tm/kotlin/core/Utility.kt +1 -1
  175. package/project/.sdk/tm/kotlin/test/OmniResolver.kt +343 -0
  176. package/project/.sdk/tm/kotlin/test/OmniSmokeTest.kt +100 -0
  177. package/project/.sdk/tm/kotlin/test/PrimaryUtilityTest.kt +244 -262
  178. package/project/.sdk/tm/kotlin/test/RunnerSupport.kt +9 -178
  179. package/project/.sdk/tm/kotlin/test/StructCorpusTest.kt +121 -32
  180. package/project/.sdk/tm/kotlin/test/vendor/omni/Json.kt +264 -0
  181. package/project/.sdk/tm/kotlin/test/vendor/omni/Runner.kt +615 -0
  182. package/project/.sdk/tm/kotlin/test/vendor/omni/Util.kt +139 -0
  183. package/project/.sdk/tm/kotlin/utility/MakeSpecUrl.kt +6 -3
  184. package/project/.sdk/tm/kotlin/utility/Prepare.kt +6 -6
  185. package/project/.sdk/tm/kotlin/utility/struct/Struct.kt +18 -2
  186. package/project/.sdk/tm/lean/Makefile +12 -5
  187. package/project/.sdk/tm/lean/src/SdkUtility.lean +14 -1
  188. package/project/.sdk/tm/lean/test/OmniResolver.lean +358 -0
  189. package/project/.sdk/tm/lean/test/OmniSmoke.lean +174 -0
  190. package/project/.sdk/tm/lean/test/StructCorpus.lean +245 -574
  191. package/project/.sdk/tm/lean/test/TPrimaryUtility.lean +155 -291
  192. package/project/.sdk/tm/lean/test/vendor/omni/Omni.lean +997 -0
  193. package/project/.sdk/tm/lua/test/omni.lua +456 -0
  194. package/project/.sdk/tm/lua/test/omni_smoke_test.lua +103 -0
  195. package/project/.sdk/tm/lua/test/primary_utility_test.lua +250 -509
  196. package/project/.sdk/tm/lua/test/struct_utility_test.lua +161 -70
  197. package/project/.sdk/tm/lua/test/vendor/omni/json.lua +268 -0
  198. package/project/.sdk/tm/lua/test/vendor/omni/regex.lua +385 -0
  199. package/project/.sdk/tm/lua/test/vendor/omni/runner.lua +641 -0
  200. package/project/.sdk/tm/lua/test/vendor/omni/util.lua +282 -0
  201. package/project/.sdk/tm/lua/utility/prepare_method.lua +5 -1
  202. package/project/.sdk/tm/lua/utility/struct/regex.lua +663 -0
  203. package/project/.sdk/tm/lua/utility/struct/struct.lua +660 -420
  204. package/project/.sdk/tm/ocaml/Makefile +37 -12
  205. package/project/.sdk/tm/ocaml/test/omni_resolver.ml +284 -0
  206. package/project/.sdk/tm/ocaml/test/omni_smoke_test.ml +169 -0
  207. package/project/.sdk/tm/ocaml/test/primary_utility_test.ml +84 -100
  208. package/project/.sdk/tm/ocaml/test/struct_corpus.ml +225 -201
  209. package/project/.sdk/tm/ocaml/test/vendor/omni/omni.ml +1157 -0
  210. package/project/.sdk/tm/perl/lib/Voxgig/Struct.pm +88 -12
  211. package/project/.sdk/tm/perl/t/omni.pm +647 -0
  212. package/project/.sdk/tm/perl/t/omni_smoke.t +87 -0
  213. package/project/.sdk/tm/perl/t/primary_utility.t +189 -487
  214. package/project/.sdk/tm/perl/t/struct_utility.t +455 -389
  215. package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Runner.pm +649 -0
  216. package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Util.pm +253 -0
  217. package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni.pm +24 -0
  218. package/project/.sdk/tm/perl/utility/prepare_method.pm +7 -2
  219. package/project/.sdk/tm/php/test/Omni.php +691 -0
  220. package/project/.sdk/tm/php/test/OmniSmokeTest.php +93 -0
  221. package/project/.sdk/tm/php/test/PrimaryUtilityTest.php +210 -571
  222. package/project/.sdk/tm/php/test/StructUtilityTest.php +320 -342
  223. package/project/.sdk/tm/php/test/vendor/omni/Runner.php +644 -0
  224. package/project/.sdk/tm/php/test/vendor/omni/Util.php +283 -0
  225. package/project/.sdk/tm/php/utility/MakeSpec.php +10 -3
  226. package/project/.sdk/tm/php/utility/PrepareBody.php +7 -1
  227. package/project/.sdk/tm/php/utility/PrepareMethod.php +6 -2
  228. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/__init__.py +36 -0
  229. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/capability.py +141 -0
  230. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/catalog.py +50 -0
  231. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/config.py +333 -0
  232. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/depend.py +198 -0
  233. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/env.py +147 -0
  234. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/export.py +52 -0
  235. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/graph.py +139 -0
  236. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/host.py +1053 -0
  237. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/order.py +171 -0
  238. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/point.py +95 -0
  239. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/ref.py +116 -0
  240. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/resolve.py +59 -0
  241. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/types.py +87 -0
  242. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/version.py +112 -0
  243. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/__init__.py +76 -0
  244. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/addr.py +116 -0
  245. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/aws.py +192 -0
  246. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/azuresecrets.py +120 -0
  247. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/boru.py +140 -0
  248. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/doppler.py +62 -0
  249. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/gcpsecrets.py +101 -0
  250. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/hashicorp.py +151 -0
  251. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/httpjson.py +115 -0
  252. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/infisical.py +90 -0
  253. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/onepassword.py +101 -0
  254. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/secretspec.py +119 -0
  255. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/sigv4.py +125 -0
  256. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/providers.py +211 -0
  257. package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/sekreto.py +475 -0
  258. package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +467 -0
  259. package/project/.sdk/tm/py/pkg/utility/prepare_method.py +5 -1
  260. package/project/.sdk/tm/py/pkg/utility/voxgig_struct/__init__.py +0 -2
  261. package/project/.sdk/tm/py/pkg/utility/voxgig_struct/voxgig_struct.py +780 -529
  262. package/project/.sdk/tm/py/src/feature/secrets/.gitkeep +0 -0
  263. package/project/.sdk/tm/py/test/feature/__init__.py +0 -0
  264. package/project/.sdk/tm/py/test/feature/secrets/__init__.py +0 -0
  265. package/project/.sdk/tm/py/test/feature/secrets/test_secrets.py +337 -0
  266. package/project/.sdk/tm/py/test/omni.py +415 -0
  267. package/project/.sdk/tm/py/test/test_omni_smoke.py +74 -0
  268. package/project/.sdk/tm/py/test/test_primary_utility.py +144 -668
  269. package/project/.sdk/tm/py/test/test_struct_utility.py +74 -27
  270. package/project/.sdk/tm/py/test/voxgig_omni/__init__.py +62 -0
  271. package/project/.sdk/tm/py/test/voxgig_omni/runner.py +580 -0
  272. package/project/.sdk/tm/py/test/voxgig_omni/util.py +252 -0
  273. package/project/.sdk/tm/rb/test/omni.rb +505 -0
  274. package/project/.sdk/tm/rb/test/omni_smoke_test.rb +72 -0
  275. package/project/.sdk/tm/rb/test/primary_utility_test.rb +174 -560
  276. package/project/.sdk/tm/rb/test/struct_utility_test.rb +13 -7
  277. package/project/.sdk/tm/rb/test/vendor/omni/runner.rb +493 -0
  278. package/project/.sdk/tm/rb/test/vendor/omni/util.rb +199 -0
  279. package/project/.sdk/tm/rb/test/vendor/omni/voxgig_omni.rb +15 -0
  280. package/project/.sdk/tm/rb/utility/prepare_method.rb +5 -1
  281. package/project/.sdk/tm/rust/tests/common/mod.rs +19 -242
  282. package/project/.sdk/tm/rust/tests/omni_resolver/mod.rs +888 -0
  283. package/project/.sdk/tm/rust/tests/omni_smoke_test.rs +286 -0
  284. package/project/.sdk/tm/rust/tests/primary_utility_test.rs +318 -312
  285. package/project/.sdk/tm/rust/tests/struct_utility_test.rs +66 -28
  286. package/project/.sdk/tm/rust/tests/vendor/omni/json.rs +412 -0
  287. package/project/.sdk/tm/rust/tests/vendor/omni/mod.rs +38 -0
  288. package/project/.sdk/tm/rust/tests/vendor/omni/regex.rs +392 -0
  289. package/project/.sdk/tm/rust/tests/vendor/omni/runner.rs +1001 -0
  290. package/project/.sdk/tm/rust/tests/vendor/omni/util.rs +161 -0
  291. package/project/.sdk/tm/rust/utility/prepare_method.rs +5 -1
  292. package/project/.sdk/tm/scala/Makefile +16 -6
  293. package/project/.sdk/tm/scala/sdktest/OmniResolver.scala +497 -0
  294. package/project/.sdk/tm/scala/sdktest/OmniSmoke.scala +192 -0
  295. package/project/.sdk/tm/scala/sdktest/PrimaryCorpus.scala +47 -19
  296. package/project/.sdk/tm/scala/sdktest/StructCorpus.scala +0 -0
  297. package/project/.sdk/tm/scala/sdktest/vendor/omni/Json.scala +229 -0
  298. package/project/.sdk/tm/scala/sdktest/vendor/omni/Runner.scala +552 -0
  299. package/project/.sdk/tm/scala/sdktest/vendor/omni/Util.scala +104 -0
  300. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Constants.swift +10 -0
  301. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Inject.swift +28 -5
  302. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Injection.swift +5 -1
  303. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Minor.swift +4 -1
  304. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/Struct/Validate.swift +15 -5
  305. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Prepare.swift +6 -1
  306. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/OmniResolver.swift +474 -0
  307. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/OmniSmokeTest.swift +107 -0
  308. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/PrimaryUtilityTest.swift +141 -178
  309. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/Runner.swift +17 -113
  310. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/StructUtilityTest.swift +295 -446
  311. package/project/.sdk/tm/swift/Tests/vendor/omni/Json.swift +364 -0
  312. package/project/.sdk/tm/swift/Tests/vendor/omni/Runner.swift +730 -0
  313. package/project/.sdk/tm/swift/Tests/vendor/omni/Util.swift +162 -0
  314. package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +7 -0
  315. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Capability.ts +148 -0
  316. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Catalog.ts +55 -0
  317. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Config.ts +344 -0
  318. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Depend.ts +205 -0
  319. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Env.ts +138 -0
  320. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Export.ts +46 -0
  321. package/project/.sdk/tm/ts/src/feature/secrets/plugin/FeatureHost.ts +349 -0
  322. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Graph.ts +181 -0
  323. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Host.ts +1132 -0
  324. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Order.ts +177 -0
  325. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Point.ts +119 -0
  326. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Ref.ts +102 -0
  327. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Resolve.ts +61 -0
  328. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Types.ts +112 -0
  329. package/project/.sdk/tm/ts/src/feature/secrets/plugin/Version.ts +100 -0
  330. package/project/.sdk/tm/ts/src/feature/secrets/plugin/index.ts +37 -0
  331. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Sekreto.ts +163 -30
  332. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/index.ts +27 -22
  333. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/aws.ts +26 -36
  334. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/azuresecrets.ts +19 -21
  335. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/boru.ts +36 -17
  336. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/doppler.ts +14 -21
  337. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/gcpsecrets.ts +27 -27
  338. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/hashicorp.ts +25 -39
  339. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/httpjson.ts +99 -0
  340. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/infisical.ts +14 -16
  341. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{provider → plugins}/onepassword.ts +15 -22
  342. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/secretspec.ts +98 -0
  343. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/{Sigv4.ts → plugins/sigv4.ts} +7 -6
  344. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/addr.ts +97 -23
  345. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/builtin.ts +37 -0
  346. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/dotenv.ts +4 -17
  347. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/env.ts +4 -16
  348. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/file.ts +11 -25
  349. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/memory.ts +6 -23
  350. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/support.ts +106 -39
  351. package/project/.sdk/tm/ts/src/utility/StructUtility.ts +3 -3
  352. package/project/.sdk/tm/ts/test/omni.ts +104 -32
  353. package/project/.sdk/tm/ts/test/utility/StructUtility.test.ts +27 -0
  354. package/project/.sdk/tm/ts/test/vendor/omni/Runner.ts +32 -5
  355. package/project/.sdk/tm/ts/test/vendor/omni/Util.ts +2 -2
  356. package/project/.sdk/tm/ts/test/vendor/omni/index.ts +2 -2
  357. package/project/.sdk/tm/zig/Makefile +15 -1
  358. package/project/.sdk/tm/zig/build.zig +23 -5
  359. package/project/.sdk/tm/zig/core/helpers.zig +52 -11
  360. package/project/.sdk/tm/zig/core/mem.zig +17 -1
  361. package/project/.sdk/tm/zig/core/utility.zig +23 -19
  362. package/project/.sdk/tm/zig/feature/audit.zig +2 -2
  363. package/project/.sdk/tm/zig/feature/cache.zig +2 -2
  364. package/project/.sdk/tm/zig/feature/debug.zig +5 -5
  365. package/project/.sdk/tm/zig/feature/netsim.zig +2 -2
  366. package/project/.sdk/tm/zig/feature/paging.zig +2 -2
  367. package/project/.sdk/tm/zig/feature/proxy.zig +15 -8
  368. package/project/.sdk/tm/zig/feature/streaming.zig +5 -5
  369. package/project/.sdk/tm/zig/feature/support.zig +3 -3
  370. package/project/.sdk/tm/zig/feature/telemetry.zig +5 -5
  371. package/project/.sdk/tm/zig/feature/test.zig +10 -5
  372. package/project/.sdk/tm/zig/test/fh.zig +10 -10
  373. package/project/.sdk/tm/zig/test/gotcha_test.zig +5 -5
  374. package/project/.sdk/tm/zig/test/omniresolver.zig +515 -0
  375. package/project/.sdk/tm/zig/test/omnismoke_test.zig +284 -0
  376. package/project/.sdk/tm/zig/test/pipeline_test.zig +8 -8
  377. package/project/.sdk/tm/zig/test/primary_utility_test.zig +145 -155
  378. package/project/.sdk/tm/zig/test/struct_corpus.zig +264 -187
  379. package/project/.sdk/tm/zig/test/vendor/omni/omni.zig +1314 -0
  380. package/project/.sdk/tm/zig/test/vendor/omni/regex.zig +446 -0
  381. package/project/.sdk/tm/zig/utility/voxgigstruct/regex.zig +7 -4
  382. package/project/.sdk/tm/zig/utility/voxgigstruct/struct.zig +356 -157
  383. package/project/sdkgen-package.json +1 -1
  384. package/src/action/doctor.ts +66 -2
  385. package/src/helpers/naming.ts +4 -2
  386. package/project/.sdk/tm/c/tests/runner.h +0 -274
  387. package/project/.sdk/tm/cpp/test/struct_runner.hpp +0 -314
  388. package/project/.sdk/tm/csharp/test/StructRunner.cs +0 -276
  389. package/project/.sdk/tm/dart/test/runner.dart +0 -406
  390. package/project/.sdk/tm/dart/test/struct_corpus.dart +0 -531
  391. package/project/.sdk/tm/elixir/test/support/struct_corpus.ex +0 -1088
  392. package/project/.sdk/tm/go/test/runner_test.go +0 -629
  393. package/project/.sdk/tm/go/test/struct_runner_test.go +0 -1094
  394. package/project/.sdk/tm/java/test/StructRunner.java +0 -281
  395. package/project/.sdk/tm/js/test/runner.js +0 -387
  396. package/project/.sdk/tm/kotlin/test/StructRunner.kt +0 -177
  397. package/project/.sdk/tm/lua/test/struct_runner.lua +0 -602
  398. package/project/.sdk/tm/ocaml/test/corpus_runner.ml +0 -185
  399. package/project/.sdk/tm/perl/t/struct_runner.pm +0 -275
  400. package/project/.sdk/tm/php/test/StructRunner.php +0 -275
  401. package/project/.sdk/tm/py/test/struct_runner.py +0 -411
  402. package/project/.sdk/tm/rb/test/struct_runner.rb +0 -309
  403. package/project/.sdk/tm/rust/tests/struct_runner/mod.rs +0 -424
  404. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/Registry.ts +0 -90
  405. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/http.ts +0 -66
  406. package/project/.sdk/tm/ts/test/vendor/omni/compat.ts +0 -188
  407. package/project/.sdk/tm/zig/test/struct_runner.zig +0 -464
@@ -0,0 +1,799 @@
1
+ // Behavioural tests for the secrets feature (vendored @voxgig/sekreto) -
2
+ // the go port of tm/ts/test/feature/secrets/Secrets.test.ts.
3
+ //
4
+ // The contract under test: the `apikey` OPTION keeps its exact old meaning
5
+ // and always wins, because SecretsFeature places it FIRST in the provider
6
+ // chain (a `memory` store named `options`) - explicit-beats-lookup falls
7
+ // out of sekreto's first-hit rule rather than from special-case logic.
8
+ // With the feature inactive nothing changes at all. With it active and the
9
+ // option unset, the chain (env, a custom provider, a vault) supplies the
10
+ // credential instead.
11
+ //
12
+ // This file lives in the test `feature/` container on purpose: `target
13
+ // add` trims it, along with the feature source and the vendored library,
14
+ // for a project whose model does not select `secrets`.
15
+ //
16
+ // The feature is CONSTRUCTED DIRECTLY and handed in through the
17
+ // `extend` option, so these tests hold in any generated tree - whether or
18
+ // not the project's model activated the feature (activation only changes
19
+ // whether config.go registers a constructor for it). The credential is
20
+ // asserted ON THE WIRE: a live-mode client with a recording system.fetch,
21
+ // driven through a real entity operation, which is what exercises the
22
+ // PreSpec resolution seam. (See the migration guide: an options-level
23
+ // assertion passes for a port that never consults the value.)
24
+
25
+ package secretstest
26
+
27
+ import (
28
+ "encoding/json"
29
+ "fmt"
30
+ "net/http"
31
+ "net/http/httptest"
32
+ "os"
33
+ "reflect"
34
+ "strings"
35
+ "sync"
36
+ "testing"
37
+ "time"
38
+ "unicode"
39
+
40
+ sdk "GOMODULE"
41
+ feat "GOMODULE/feature"
42
+ )
43
+
44
+ const envprefix = "PROJECTENV_TEST_SECRETS_"
45
+
46
+ // ---------------------------------------------------------------------
47
+ // The recording transport: system.fetch for a LIVE client, scripting one
48
+ // status per API call (the last repeating) and a token endpoint for the
49
+ // exchange tests.
50
+
51
+ type wirecall struct {
52
+ url string
53
+ auth string
54
+ has bool
55
+ body string
56
+ }
57
+
58
+ type wire struct {
59
+ mu sync.Mutex
60
+ calls []wirecall
61
+ apistatus []int
62
+ tokens []string
63
+ tokenpath string
64
+ respfield string
65
+ issued int
66
+ apicalls int
67
+ }
68
+
69
+ func makewire() *wire {
70
+ return &wire{
71
+ apistatus: []int{200},
72
+ tokens: []string{"ACCESS01", "ACCESS02", "ACCESS03"},
73
+ tokenpath: "auth/token",
74
+ respfield: "access_token",
75
+ }
76
+ }
77
+
78
+ func (w *wire) fetch(url string, fetchdef map[string]any) (map[string]any, error) {
79
+ w.mu.Lock()
80
+ defer w.mu.Unlock()
81
+
82
+ auth := ""
83
+ has := false
84
+ if headers, is := fetchdef["headers"].(map[string]any); is {
85
+ if v, found := headers["authorization"]; found {
86
+ auth, _ = v.(string)
87
+ has = true
88
+ }
89
+ }
90
+ body, _ := fetchdef["body"].(string)
91
+ w.calls = append(w.calls, wirecall{url: url, auth: auth, has: has, body: body})
92
+
93
+ if strings.HasSuffix(url, "/"+w.tokenpath) {
94
+ token := w.tokens[min(w.issued, len(w.tokens)-1)]
95
+ w.issued++
96
+ payload := map[string]any{w.respfield: token}
97
+ return map[string]any{
98
+ "status": 200, "statusText": "OK",
99
+ "headers": map[string]any{},
100
+ "json": (func() any)(func() any { return payload }),
101
+ }, nil
102
+ }
103
+
104
+ status := w.apistatus[min(w.apicalls, len(w.apistatus)-1)]
105
+ w.apicalls++
106
+ payload := map[string]any{"ok": status < 400}
107
+ return map[string]any{
108
+ "status": status, "statusText": "X",
109
+ "headers": map[string]any{},
110
+ "json": (func() any)(func() any { return payload }),
111
+ }, nil
112
+ }
113
+
114
+ func min(a, b int) int {
115
+ if a < b {
116
+ return a
117
+ }
118
+ return b
119
+ }
120
+
121
+ // api returns the recorded calls that did NOT go to the token endpoint.
122
+ func (w *wire) api() []wirecall {
123
+ w.mu.Lock()
124
+ defer w.mu.Unlock()
125
+ out := []wirecall{}
126
+ for _, c := range w.calls {
127
+ if !strings.HasSuffix(c.url, "/"+w.tokenpath) {
128
+ out = append(out, c)
129
+ }
130
+ }
131
+ return out
132
+ }
133
+
134
+ func (w *wire) token() []wirecall {
135
+ w.mu.Lock()
136
+ defer w.mu.Unlock()
137
+ out := []wirecall{}
138
+ for _, c := range w.calls {
139
+ if strings.HasSuffix(c.url, "/"+w.tokenpath) {
140
+ out = append(out, c)
141
+ }
142
+ }
143
+ return out
144
+ }
145
+
146
+ // ---------------------------------------------------------------------
147
+ // Support.
148
+
149
+ // The Authorization header carries the SPEC's credential prefix, which a
150
+ // TEMPLATE cannot know - so assert on the CREDENTIAL and let the prefix be
151
+ // whatever this SDK's API declares.
152
+ func credentialIs(t *testing.T, header string, token string) {
153
+ t.Helper()
154
+ if header != token && !strings.HasSuffix(header, " "+token) {
155
+ t.Fatalf("expected the authorization header to carry %s, got: %q", token, header)
156
+ }
157
+ }
158
+
159
+ // secretsClient builds a LIVE client carrying the secrets feature via the
160
+ // `extend` seam, wired to the recording transport.
161
+ func secretsClient(w *wire, sdkopts map[string]any) *sdk.ProjectNameSDK {
162
+ opts := map[string]any{
163
+ "base": "http://secrets.test/api",
164
+ "system": map[string]any{"fetch": w.fetch},
165
+ }
166
+ for k, v := range sdkopts {
167
+ opts[k] = v
168
+ }
169
+ return withSecrets(func(extend bool) *sdk.ProjectNameSDK {
170
+ if extend {
171
+ opts["extend"] = []any{feat.NewSecretsFeature()}
172
+ }
173
+ return sdk.NewProjectNameSDK(opts)
174
+ })
175
+ }
176
+
177
+ // withSecrets constructs the client and ADOPTS the feature via `extend`
178
+ // ONLY when the generated config did not already install it - when this
179
+ // SDK was generated with `secrets` model-active, the ordinary factory
180
+ // path builds the instance, and adding a second via extend would DOUBLE
181
+ // the feature: two transport wraps, two resolutions, and a token
182
+ // purchase the assertions cannot account for. (The py harness guards the
183
+ // same way via _has_feature.)
184
+ func withSecrets(build func(extend bool) *sdk.ProjectNameSDK) *sdk.ProjectNameSDK {
185
+ client := build(false)
186
+ if nil == secretsFeatureOf(client) {
187
+ client = build(true)
188
+ }
189
+ return client
190
+ }
191
+
192
+ func secretsOpts(extra map[string]any) map[string]any {
193
+ fopts := map[string]any{
194
+ "active": true,
195
+ "providers": []any{
196
+ map[string]any{"kind": "env", "prefix": envprefix},
197
+ },
198
+ }
199
+ for k, v := range extra {
200
+ fopts[k] = v
201
+ }
202
+ return map[string]any{"secrets": fopts}
203
+ }
204
+
205
+ // secretsFeatureOf digs the live feature back out of the client, for
206
+ // assertions against its Sekreto instance.
207
+ func secretsFeatureOf(client *sdk.ProjectNameSDK) *feat.SecretsFeature {
208
+ for _, f := range client.Features {
209
+ if sf, is := f.(*feat.SecretsFeature); is {
210
+ return sf
211
+ }
212
+ }
213
+ return nil
214
+ }
215
+
216
+ // driveEntityOpUntil performs real entity operations - which is what runs
217
+ // the PreSpec hook - until `stop` reports the observable state a test is
218
+ // waiting for. Each op's own outcome is irrelevant (no seeded data, a
219
+ // scripted response); an op the API does not define fails BEFORE the
220
+ // PreSpec hook, which is why several may need driving. Entity names come
221
+ // from the SDK's own config, because this file is a TEMPLATE and no
222
+ // project's entity names are known here.
223
+ func driveEntityOpUntil(t *testing.T, client *sdk.ProjectNameSDK, what string, stop func() bool) {
224
+ t.Helper()
225
+
226
+ entities, _ := client.OptionsMap()["entity"].(map[string]any)
227
+ clientval := reflect.ValueOf(client)
228
+
229
+ for name := range entities {
230
+ runes := []rune(name)
231
+ runes[0] = unicode.ToUpper(runes[0])
232
+ accessor := clientval.MethodByName(string(runes))
233
+ if !accessor.IsValid() || 1 != accessor.Type().NumIn() {
234
+ continue
235
+ }
236
+
237
+ ent := accessor.Call([]reflect.Value{
238
+ reflect.Zero(accessor.Type().In(0)),
239
+ })[0]
240
+
241
+ for _, opname := range []string{"List", "Load"} {
242
+ op := ent.MethodByName(opname)
243
+ if !op.IsValid() {
244
+ continue
245
+ }
246
+ in := make([]reflect.Value, op.Type().NumIn())
247
+ for i := range in {
248
+ in[i] = reflect.Zero(op.Type().In(i))
249
+ }
250
+ op.Call(in)
251
+
252
+ if stop() {
253
+ return
254
+ }
255
+ }
256
+ }
257
+
258
+ t.Fatalf("no entity operation %s - nothing to assert on", what)
259
+ }
260
+
261
+ // driveEntityOp drives ops until one request reached the recorder.
262
+ func driveEntityOp(t *testing.T, client *sdk.ProjectNameSDK, w *wire) {
263
+ t.Helper()
264
+ before := len(w.api())
265
+ driveEntityOpUntil(t, client, "reached the transport", func() bool {
266
+ return before < len(w.api())
267
+ })
268
+ }
269
+
270
+ // ---------------------------------------------------------------------
271
+ // The feature-inactive baseline: bit-identical behaviour.
272
+
273
+ func TestSecretsInactive(t *testing.T) {
274
+
275
+ t.Run("apikey option behaves exactly as before", func(t *testing.T) {
276
+ client := sdk.TestSDK(nil, map[string]any{"apikey": "OPTKEY01"})
277
+ fetchdef, err := client.Prepare(map[string]any{"path": "/"})
278
+ if err != nil {
279
+ t.Fatalf("prepare failed: %v", err)
280
+ }
281
+ headers, _ := fetchdef["headers"].(map[string]any)
282
+ auth, _ := headers["authorization"].(string)
283
+ credentialIs(t, auth, "OPTKEY01")
284
+
285
+ if nil != secretsFeatureOf(client) {
286
+ t.Fatal("no model activation, no extend: the feature must not be installed")
287
+ }
288
+ })
289
+
290
+ t.Run("no apikey means no authorization header", func(t *testing.T) {
291
+ client := sdk.TestSDK(nil, nil)
292
+ fetchdef, err := client.Prepare(map[string]any{"path": "/"})
293
+ if err != nil {
294
+ t.Fatalf("prepare failed: %v", err)
295
+ }
296
+ headers, _ := fetchdef["headers"].(map[string]any)
297
+ if _, has := headers["authorization"]; has {
298
+ t.Fatalf("unexpected authorization header: %v", headers["authorization"])
299
+ }
300
+ })
301
+ }
302
+
303
+ // ---------------------------------------------------------------------
304
+ // Active: the provider chain, driven through real entity operations.
305
+
306
+ func TestSecretsChain(t *testing.T) {
307
+
308
+ t.Run("apikey option still wins over the chain", func(t *testing.T) {
309
+ os.Setenv(envprefix+"APIKEY", "ENVKEY01")
310
+ defer os.Unsetenv(envprefix + "APIKEY")
311
+
312
+ w := makewire()
313
+ client := secretsClient(w, map[string]any{
314
+ "apikey": "OPTKEY01",
315
+ "feature": secretsOpts(nil),
316
+ })
317
+
318
+ driveEntityOp(t, client, w)
319
+ call := w.api()[0]
320
+ credentialIs(t, call.auth, "OPTKEY01")
321
+
322
+ // The explicit option is a real store, not a special case: a
323
+ // directed read names it like any other.
324
+ sf := secretsFeatureOf(client)
325
+ if nil == sf {
326
+ t.Fatal("the extend seam did not install the feature")
327
+ }
328
+ found, err := sf.Sekreto().GetFrom("options", "apikey")
329
+ if err != nil || "OPTKEY01" != found {
330
+ t.Fatalf("directed read of the options store: %q, %v", found, err)
331
+ }
332
+ })
333
+
334
+ t.Run("an omitted apikey defers to the chain at the transport seam", func(t *testing.T) {
335
+ os.Setenv(envprefix+"APIKEY", "ENVKEY02")
336
+ defer os.Unsetenv(envprefix + "APIKEY")
337
+
338
+ w := makewire()
339
+ client := secretsClient(w, map[string]any{"feature": secretsOpts(nil)})
340
+
341
+ // Before any op, nothing has been resolved.
342
+ if v, _ := client.OptionsMap()["apikey"].(string); "" != v {
343
+ t.Fatalf("apikey resolved before any operation: %q", v)
344
+ }
345
+
346
+ driveEntityOp(t, client, w)
347
+
348
+ // Resolution happens AT THE TRANSPORT - the one seam every wire
349
+ // path crosses - so the credential is on the wire, not merely
350
+ // resolved. go holds it in FEATURE STATE and injects there; the
351
+ // options map is never mutated (it stays raced-read-safe for
352
+ // every concurrent operation), so the state assertion reads the
353
+ // feature.
354
+ credentialIs(t, w.api()[0].auth, "ENVKEY02")
355
+ if v := secretsFeatureOf(client).Credential(); "ENVKEY02" != v {
356
+ t.Fatalf("the entity op did not resolve the secret through PreSpec: %q", v)
357
+ }
358
+ if v, _ := client.OptionsMap()["apikey"].(string); "" != v {
359
+ t.Fatalf("the options map must stay unwritten (frozen after construction), got apikey=%q", v)
360
+ }
361
+ })
362
+
363
+ t.Run("custom provider objects are accepted verbatim", func(t *testing.T) {
364
+ asked := []string{}
365
+ w := makewire()
366
+ client := secretsClient(w, map[string]any{
367
+ "feature": map[string]any{"secrets": map[string]any{
368
+ "active": true,
369
+ "providers": []any{
370
+ &customProvider{
371
+ lookup: func(name string) (string, bool, error) {
372
+ asked = append(asked, name)
373
+ return "CUSTOM01", true, nil
374
+ },
375
+ },
376
+ },
377
+ }},
378
+ })
379
+
380
+ driveEntityOp(t, client, w)
381
+ credentialIs(t, w.api()[0].auth, "CUSTOM01")
382
+ if 1 > len(asked) || "apikey" != asked[0] {
383
+ t.Fatalf("the custom provider was asked %v, want [apikey ...]", asked)
384
+ }
385
+ })
386
+
387
+ t.Run("a miss everywhere leaves the header off", func(t *testing.T) {
388
+ os.Unsetenv(envprefix + "APIKEY")
389
+
390
+ w := makewire()
391
+ client := secretsClient(w, map[string]any{"feature": secretsOpts(nil)})
392
+
393
+ driveEntityOp(t, client, w)
394
+ call := w.api()[0]
395
+ if call.has {
396
+ t.Fatalf("a chain MISS must fall through to an unauthenticated request, got header %q", call.auth)
397
+ }
398
+ })
399
+
400
+ t.Run("a provider ERROR fails the op and nothing reaches the wire", func(t *testing.T) {
401
+ asked := false
402
+ w := makewire()
403
+ client := secretsClient(w, map[string]any{
404
+ "feature": map[string]any{"secrets": map[string]any{
405
+ "active": true,
406
+ "providers": []any{
407
+ &customProvider{
408
+ lookup: func(name string) (string, bool, error) {
409
+ asked = true
410
+ return "", false, fmt.Errorf("vault unreachable")
411
+ },
412
+ },
413
+ },
414
+ }},
415
+ })
416
+
417
+ driveEntityOpUntil(t, client, "consulted the chain", func() bool {
418
+ return asked
419
+ })
420
+
421
+ if 0 != len(w.api()) {
422
+ t.Fatalf("a broken vault must never yield a request: %d calls went out", len(w.api()))
423
+ }
424
+ })
425
+
426
+ t.Run("a provider recovers after a transient failure", func(t *testing.T) {
427
+ calls := 0
428
+ w := makewire()
429
+ client := secretsClient(w, map[string]any{
430
+ "feature": map[string]any{"secrets": map[string]any{
431
+ "active": true,
432
+ "providers": []any{
433
+ &customProvider{
434
+ lookup: func(name string) (string, bool, error) {
435
+ calls++
436
+ if 1 == calls {
437
+ return "", false, fmt.Errorf("vault unreachable")
438
+ }
439
+ return "RECOVERED01", true, nil
440
+ },
441
+ },
442
+ },
443
+ }},
444
+ })
445
+
446
+ // First op fails closed; a failed resolution is never cached, so
447
+ // the second op asks the chain again and succeeds.
448
+ driveEntityOpUntil(t, client, "consulted the chain", func() bool {
449
+ return 0 < calls
450
+ })
451
+ if 0 != len(w.api()) {
452
+ t.Fatal("the first op must not reach the wire")
453
+ }
454
+
455
+ driveEntityOp(t, client, w)
456
+ credentialIs(t, w.api()[0].auth, "RECOVERED01")
457
+ })
458
+
459
+ t.Run("auth nil suppresses the credential, chain or no chain", func(t *testing.T) {
460
+ os.Setenv(envprefix+"APIKEY", "ENVKEY03")
461
+ defer os.Unsetenv(envprefix + "APIKEY")
462
+
463
+ w := makewire()
464
+ client := secretsClient(w, map[string]any{
465
+ "auth": nil,
466
+ "apikey": "OPTKEY01",
467
+ "feature": secretsOpts(nil),
468
+ })
469
+
470
+ driveEntityOp(t, client, w)
471
+
472
+ // Nothing on the wire, even though the chain would have resolved:
473
+ // go's vendored struct treats a stored null as "no value"
474
+ // (fail-OPEN class), and makeOptions captures suppliedness before
475
+ // validate and restores the null after - the guard this pins.
476
+ call := w.api()[0]
477
+ if call.has {
478
+ t.Fatalf("auth nil must suppress the credential, got header %q", call.auth)
479
+ }
480
+
481
+ // The suppression survives option validation rather than being
482
+ // replaced by the optspec's default auth map.
483
+ opts := client.OptionsMap()
484
+ authval, authgiven := opts["auth"]
485
+ if !authgiven || nil != authval {
486
+ t.Fatalf("options.auth must stay a present null, got (%v, present=%v)", authval, authgiven)
487
+ }
488
+ })
489
+ }
490
+
491
+ // customProvider is a sekreto.Provider built in code (the interface is
492
+ // structural: Lookup + Describe).
493
+ type customProvider struct {
494
+ lookup func(name string) (string, bool, error)
495
+ }
496
+
497
+ func (p *customProvider) Lookup(name string) (string, bool, error) {
498
+ return p.lookup(name)
499
+ }
500
+
501
+ func (p *customProvider) Describe() string { return "custom:test" }
502
+
503
+ // ---------------------------------------------------------------------
504
+ // The access-token exchange.
505
+
506
+ func TestSecretsExchange(t *testing.T) {
507
+
508
+ t.Run("the refresh token buys an access token, and a spent one is rebought once", func(t *testing.T) {
509
+ os.Setenv(envprefix+"REFRESH_TOKEN", "REFRESH01")
510
+ defer os.Unsetenv(envprefix + "REFRESH_TOKEN")
511
+
512
+ // First API call is refused, the retry succeeds.
513
+ w := makewire()
514
+ w.apistatus = []int{401, 200}
515
+
516
+ client := secretsClient(w, map[string]any{
517
+ "feature": secretsOpts(map[string]any{
518
+ "name": "refresh_token",
519
+ "exchange": map[string]any{"active": true},
520
+ }),
521
+ })
522
+
523
+ driveEntityOp(t, client, w)
524
+
525
+ if 2 != len(w.token()) {
526
+ t.Fatalf("expected the initial purchase plus one rebuy, got %d", len(w.token()))
527
+ }
528
+ if !strings.Contains(w.token()[0].body, "REFRESH01") {
529
+ t.Fatalf("the refresh token is sent in the request body, got %q", w.token()[0].body)
530
+ }
531
+
532
+ api := w.api()
533
+ if 2 != len(api) {
534
+ t.Fatalf("expected the request to be retried exactly once, got %d calls", len(api))
535
+ }
536
+ credentialIs(t, api[0].auth, "ACCESS01")
537
+ // The retry must carry the NEW token, not the spent one.
538
+ credentialIs(t, api[1].auth, "ACCESS02")
539
+ })
540
+
541
+ t.Run("test mode buys nothing and needs no token endpoint", func(t *testing.T) {
542
+ os.Setenv(envprefix+"REFRESH_TOKEN", "REFRESH01")
543
+ defer os.Unsetenv(envprefix + "REFRESH_TOKEN")
544
+
545
+ w := makewire()
546
+ client := withSecrets(func(extend bool) *sdk.ProjectNameSDK {
547
+ opts := map[string]any{
548
+ "system": map[string]any{"fetch": w.fetch},
549
+ "feature": secretsOpts(map[string]any{
550
+ "name": "refresh_token",
551
+ "exchange": map[string]any{"active": true},
552
+ }),
553
+ }
554
+ if extend {
555
+ opts["extend"] = []any{feat.NewSecretsFeature()}
556
+ }
557
+ return sdk.TestSDK(nil, opts)
558
+ })
559
+
560
+ driveEntityOpUntil(t, client, "resolved the fake token", func() bool {
561
+ return "" != secretsFeatureOf(client).Credential()
562
+ })
563
+
564
+ if 0 != len(w.calls) {
565
+ t.Fatalf("test mode must not do IO, saw %d calls", len(w.calls))
566
+ }
567
+ // A deterministic placeholder, so offline suites need no
568
+ // configuration.
569
+ if v := secretsFeatureOf(client).Credential(); "test-access_token" != v {
570
+ t.Fatalf("expected the fake test token, got %q", v)
571
+ }
572
+ })
573
+ }
574
+
575
+ // ---------------------------------------------------------------------
576
+ // Review-hardening pins (vendor-tag rollout, PR review): the exchange
577
+ // works with ORDINARY options (no custom transport), the token body is
578
+ // real JSON, an uncached miss retracts the credential, and a failed
579
+ // resolution recovers safely under concurrency.
580
+
581
+ // The exchange with NO system.fetch: the raw fallback transport carries
582
+ // the purchase, and the body is MARSHALLED - a refresh token full of
583
+ // JSON-hostile characters must arrive as that literal value. End to end
584
+ // over real HTTP (httptest), token purchase and API call alike.
585
+ func TestSecretsExchangeRawFetch(t *testing.T) {
586
+ tricky := "re\"fresh\\to\nken"
587
+
588
+ var mu sync.Mutex
589
+ gotrefresh := ""
590
+ gotauth := ""
591
+
592
+ srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
593
+ if strings.HasSuffix(req.URL.Path, "/auth/token") {
594
+ var body map[string]any
595
+ json.NewDecoder(req.Body).Decode(&body)
596
+ mu.Lock()
597
+ gotrefresh, _ = body["refresh_token"].(string)
598
+ mu.Unlock()
599
+ res.Header().Set("content-type", "application/json")
600
+ res.Write([]byte(`{"access_token": "RAWTOK01"}`))
601
+ return
602
+ }
603
+ mu.Lock()
604
+ gotauth = req.Header.Get("authorization")
605
+ mu.Unlock()
606
+ res.Header().Set("content-type", "application/json")
607
+ res.Write([]byte(`{}`))
608
+ }))
609
+ defer srv.Close()
610
+
611
+ // No system.fetch anywhere: the API call takes the SDK's default
612
+ // transport and the token purchase takes the feature's raw fallback.
613
+ client := withSecrets(func(extend bool) *sdk.ProjectNameSDK {
614
+ opts := map[string]any{
615
+ "base": srv.URL + "/api",
616
+ "feature": map[string]any{"secrets": map[string]any{
617
+ "active": true,
618
+ "name": "refresh_token",
619
+ "exchange": map[string]any{"active": true, "refresh": tricky},
620
+ }},
621
+ }
622
+ if extend {
623
+ opts["extend"] = []any{feat.NewSecretsFeature()}
624
+ }
625
+ return sdk.NewProjectNameSDK(opts)
626
+ })
627
+
628
+ driveEntityOpUntil(t, client, "reached the httptest server", func() bool {
629
+ mu.Lock()
630
+ defer mu.Unlock()
631
+ return "" != gotauth
632
+ })
633
+
634
+ mu.Lock()
635
+ defer mu.Unlock()
636
+ if tricky != gotrefresh {
637
+ t.Fatalf("the refresh token must arrive as its literal value "+
638
+ "(marshalled, not concatenated): want %q got %q", tricky, gotrefresh)
639
+ }
640
+ credentialIs(t, gotauth, "RAWTOK01")
641
+ }
642
+
643
+ // With `cache: false`, a provider that answered once and then reports a
644
+ // MISS (a revoked secret) must RETRACT the credential the feature wrote -
645
+ // prepareAuth must stop transmitting it.
646
+ func TestSecretsUncachedMissRetracts(t *testing.T) {
647
+ var mu sync.Mutex
648
+ have := true
649
+
650
+ w := makewire()
651
+ client := secretsClient(w, map[string]any{
652
+ "feature": map[string]any{"secrets": map[string]any{
653
+ "active": true,
654
+ "cache": false,
655
+ "providers": []any{
656
+ &customProvider{
657
+ lookup: func(name string) (string, bool, error) {
658
+ mu.Lock()
659
+ defer mu.Unlock()
660
+ if have {
661
+ return "REVOCABLE01", true, nil
662
+ }
663
+ return "", false, nil
664
+ },
665
+ },
666
+ },
667
+ }},
668
+ })
669
+
670
+ driveEntityOp(t, client, w)
671
+ credentialIs(t, w.api()[0].auth, "REVOCABLE01")
672
+
673
+ mu.Lock()
674
+ have = false
675
+ mu.Unlock()
676
+
677
+ driveEntityOp(t, client, w)
678
+ last := w.api()[len(w.api())-1]
679
+ if last.has && "" != last.auth {
680
+ t.Fatalf("after the chain reports a miss, the retracted credential "+
681
+ "must not go out; the wire saw %q", last.auth)
682
+ }
683
+ }
684
+
685
+ // The RAW paths - Direct and Graphql - run no feature hooks at all, so
686
+ // for them the transport seam is the ONLY place resolution can happen.
687
+ // This is the pin that Direct gets the chain credential (and the same
688
+ // fail-closed refusal) without any entity pipeline involved.
689
+ func TestSecretsDirectPath(t *testing.T) {
690
+ os.Setenv(envprefix+"APIKEY", "DIRECTKEY01")
691
+ defer os.Unsetenv(envprefix + "APIKEY")
692
+
693
+ w := makewire()
694
+ client := secretsClient(w, map[string]any{
695
+ "allow": map[string]any{"op": "direct"},
696
+ "feature": secretsOpts(nil),
697
+ })
698
+
699
+ res, err := client.Direct(map[string]any{"path": "/direct-probe"})
700
+ if nil != err {
701
+ t.Fatalf("direct failed: %v", err)
702
+ }
703
+ if ok, _ := res["ok"].(bool); !ok {
704
+ t.Fatalf("direct refused: %v", res["err"])
705
+ }
706
+ if 1 != len(w.api()) {
707
+ t.Fatalf("expected one direct call on the wire, got %d", len(w.api()))
708
+ }
709
+ credentialIs(t, w.api()[0].auth, "DIRECTKEY01")
710
+
711
+ // And fail-closed holds for raw access too: a broken chain refuses
712
+ // the Direct call before anything reaches the wire.
713
+ broken := secretsClient(makewire(), map[string]any{
714
+ "allow": map[string]any{"op": "direct"},
715
+ "feature": map[string]any{"secrets": map[string]any{
716
+ "active": true,
717
+ "providers": []any{
718
+ &customProvider{
719
+ lookup: func(name string) (string, bool, error) {
720
+ return "", false, fmt.Errorf("vault unreachable")
721
+ },
722
+ },
723
+ },
724
+ }},
725
+ })
726
+ res, err = broken.Direct(map[string]any{"path": "/direct-probe"})
727
+ if nil != err {
728
+ t.Fatalf("direct must report the refusal in-band: %v", err)
729
+ }
730
+ if ok, _ := res["ok"].(bool); ok {
731
+ t.Fatal("a broken chain must refuse the raw path fail-closed")
732
+ }
733
+ }
734
+
735
+ // A provider failure closes the transport gate; a later retry that
736
+ // SUCCEEDS reopens it and every waiting operation goes out with the FRESH
737
+ // credential - never the stale pre-failure header, and never nothing.
738
+ func TestSecretsGateRecovery(t *testing.T) {
739
+ var mu sync.Mutex
740
+ mode := "fail"
741
+ release := make(chan struct{})
742
+
743
+ w := makewire()
744
+ client := secretsClient(w, map[string]any{
745
+ "feature": map[string]any{"secrets": map[string]any{
746
+ "active": true,
747
+ "cache": false,
748
+ "providers": []any{
749
+ &customProvider{
750
+ lookup: func(name string) (string, bool, error) {
751
+ mu.Lock()
752
+ m := mode
753
+ mu.Unlock()
754
+ if "fail" == m {
755
+ return "", false, fmt.Errorf("vault unreachable")
756
+ }
757
+ if "slow" == m {
758
+ <-release
759
+ }
760
+ return "FRESH01", true, nil
761
+ },
762
+ },
763
+ },
764
+ }},
765
+ })
766
+
767
+ // 1. The failure closes the gate: nothing reaches the wire.
768
+ driveEntityOpUntil(t, client, "was refused by the gate", func() bool { return true })
769
+ if 0 != len(w.api()) {
770
+ t.Fatalf("a failed resolution must keep the wire silent, saw %d calls", len(w.api()))
771
+ }
772
+
773
+ // 2. Recovery under concurrency: two operations race the slow retry;
774
+ // both must come out carrying the fresh credential.
775
+ mu.Lock()
776
+ mode = "slow"
777
+ mu.Unlock()
778
+
779
+ var wg sync.WaitGroup
780
+ for i := 0; i < 2; i++ {
781
+ wg.Add(1)
782
+ go func() {
783
+ defer wg.Done()
784
+ driveEntityOpUntil(t, client, "recovered", func() bool { return true })
785
+ }()
786
+ }
787
+ go func() {
788
+ time.Sleep(20 * time.Millisecond)
789
+ close(release)
790
+ }()
791
+ wg.Wait()
792
+
793
+ for _, call := range w.api() {
794
+ credentialIs(t, call.auth, "FRESH01")
795
+ }
796
+ if 0 == len(w.api()) {
797
+ t.Fatal("recovery must let the operations out")
798
+ }
799
+ }