@voxgig/sdkgen 4.10.0 → 4.11.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 (304) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/package.json +1 -1
  3. package/project/.sdk/model/feature/secrets.aon +330 -0
  4. package/project/.sdk/model/target/c.aon +15 -2
  5. package/project/.sdk/model/target/cpp.aon +18 -0
  6. package/project/.sdk/model/target/lua.aon +17 -0
  7. package/project/.sdk/model/target/ocaml.aon +48 -5
  8. package/project/.sdk/model/target/zig.aon +30 -4
  9. package/project/.sdk/src/cmp/c/Config_c.ts +338 -1
  10. package/project/.sdk/src/cmp/c/Main_c.ts +57 -2
  11. package/project/.sdk/src/cmp/c/Package_c.ts +12 -2
  12. package/project/.sdk/src/cmp/cpp/Config_cpp.ts +324 -2
  13. package/project/.sdk/src/cmp/cpp/Gitignore_cpp.ts +2 -0
  14. package/project/.sdk/src/cmp/cpp/Main_cpp.ts +62 -4
  15. package/project/.sdk/src/cmp/cpp/Package_cpp.ts +10 -0
  16. package/project/.sdk/src/cmp/lua/Config_lua.ts +88 -0
  17. package/project/.sdk/src/cmp/lua/Gitignore_lua.ts +4 -0
  18. package/project/.sdk/src/cmp/lua/Main_lua.ts +93 -3
  19. package/project/.sdk/src/cmp/lua/Package_lua.ts +60 -0
  20. package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +10 -0
  21. package/project/.sdk/src/cmp/ocaml/Config_ocaml.ts +183 -5
  22. package/project/.sdk/src/cmp/ocaml/Main_ocaml.ts +160 -3
  23. package/project/.sdk/src/cmp/ocaml/Package_ocaml.ts +25 -1
  24. package/project/.sdk/src/cmp/zig/Config_zig.ts +130 -9
  25. package/project/.sdk/src/cmp/zig/Main_zig.ts +208 -4
  26. package/project/.sdk/{tm/zig/build.zig → src/cmp/zig/fragment/Build.fragment.zig} +7 -0
  27. package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +25 -0
  28. package/project/.sdk/{tm/zig/root.zig → src/cmp/zig/fragment/Root.fragment.zig} +9 -0
  29. package/project/.sdk/tm/c/Makefile +58 -9
  30. package/project/.sdk/tm/c/core/sdk.h +10 -0
  31. package/project/.sdk/tm/c/feature/secrets/plugin/capability.c +133 -0
  32. package/project/.sdk/tm/c/feature/secrets/plugin/capability.h +39 -0
  33. package/project/.sdk/tm/c/feature/secrets/plugin/catalog.c +83 -0
  34. package/project/.sdk/tm/c/feature/secrets/plugin/catalog.h +48 -0
  35. package/project/.sdk/tm/c/feature/secrets/plugin/config.c +413 -0
  36. package/project/.sdk/tm/c/feature/secrets/plugin/config.h +24 -0
  37. package/project/.sdk/tm/c/feature/secrets/plugin/depend.c +264 -0
  38. package/project/.sdk/tm/c/feature/secrets/plugin/depend.h +29 -0
  39. package/project/.sdk/tm/c/feature/secrets/plugin/env.c +220 -0
  40. package/project/.sdk/tm/c/feature/secrets/plugin/env.h +19 -0
  41. package/project/.sdk/tm/c/feature/secrets/plugin/export.c +97 -0
  42. package/project/.sdk/tm/c/feature/secrets/plugin/export.h +19 -0
  43. package/project/.sdk/tm/c/feature/secrets/plugin/graph.c +237 -0
  44. package/project/.sdk/tm/c/feature/secrets/plugin/graph.h +17 -0
  45. package/project/.sdk/tm/c/feature/secrets/plugin/host.c +1494 -0
  46. package/project/.sdk/tm/c/feature/secrets/plugin/host.h +135 -0
  47. package/project/.sdk/tm/c/feature/secrets/plugin/order.c +288 -0
  48. package/project/.sdk/tm/c/feature/secrets/plugin/order.h +18 -0
  49. package/project/.sdk/tm/c/feature/secrets/plugin/point.c +141 -0
  50. package/project/.sdk/tm/c/feature/secrets/plugin/point.h +80 -0
  51. package/project/.sdk/tm/c/feature/secrets/plugin/ref.c +170 -0
  52. package/project/.sdk/tm/c/feature/secrets/plugin/ref.h +52 -0
  53. package/project/.sdk/tm/c/feature/secrets/plugin/resolve.c +98 -0
  54. package/project/.sdk/tm/c/feature/secrets/plugin/resolve.h +18 -0
  55. package/project/.sdk/tm/c/feature/secrets/plugin/types.c +150 -0
  56. package/project/.sdk/tm/c/feature/secrets/plugin/types.h +104 -0
  57. package/project/.sdk/tm/c/feature/secrets/plugin/value.c +649 -0
  58. package/project/.sdk/tm/c/feature/secrets/plugin/value.h +135 -0
  59. package/project/.sdk/tm/c/feature/secrets/plugin/version.c +151 -0
  60. package/project/.sdk/tm/c/feature/secrets/plugin/version.h +34 -0
  61. package/project/.sdk/tm/c/feature/secrets/plugins/aws.c +281 -0
  62. package/project/.sdk/tm/c/feature/secrets/plugins/azuresecrets.c +207 -0
  63. package/project/.sdk/tm/c/feature/secrets/plugins/boru.c +164 -0
  64. package/project/.sdk/tm/c/feature/secrets/plugins/clock.c +75 -0
  65. package/project/.sdk/tm/c/feature/secrets/plugins/doppler.c +141 -0
  66. package/project/.sdk/tm/c/feature/secrets/plugins/encode.c +144 -0
  67. package/project/.sdk/tm/c/feature/secrets/plugins/gcpsecrets.c +177 -0
  68. package/project/.sdk/tm/c/feature/secrets/plugins/hashicorp.c +239 -0
  69. package/project/.sdk/tm/c/feature/secrets/plugins/httpjson.c +599 -0
  70. package/project/.sdk/tm/c/feature/secrets/plugins/infisical.c +165 -0
  71. package/project/.sdk/tm/c/feature/secrets/plugins/onepassword.c +194 -0
  72. package/project/.sdk/tm/c/feature/secrets/plugins/proc.c +233 -0
  73. package/project/.sdk/tm/c/feature/secrets/plugins/secretspec.c +125 -0
  74. package/project/.sdk/tm/c/feature/secrets/plugins/sekretoplugins.h +125 -0
  75. package/project/.sdk/tm/c/feature/secrets/plugins/sha256.c +270 -0
  76. package/project/.sdk/tm/c/feature/secrets/plugins/sigv4.c +382 -0
  77. package/project/.sdk/tm/c/feature/secrets/plugins/support.h +153 -0
  78. package/project/.sdk/tm/c/feature/secrets/plugins/tls.c +420 -0
  79. package/project/.sdk/tm/c/feature/secrets/sekreto/internal.h +86 -0
  80. package/project/.sdk/tm/c/feature/secrets/sekreto/json.c +721 -0
  81. package/project/.sdk/tm/c/feature/secrets/sekreto/providers.c +813 -0
  82. package/project/.sdk/tm/c/feature/secrets/sekreto/sekreto.c +944 -0
  83. package/project/.sdk/tm/c/feature/secrets/sekreto/sekreto.h +490 -0
  84. package/project/.sdk/tm/c/feature/secrets/sekreto/util.c +442 -0
  85. package/project/.sdk/tm/c/feature/secrets.c +797 -0
  86. package/project/.sdk/tm/c/feature/secrets.h +46 -0
  87. package/project/.sdk/tm/c/src/feature/secrets/.gitkeep +0 -0
  88. package/project/.sdk/tm/c/tests/feature/secrets/secrets_test.c +802 -0
  89. package/project/.sdk/tm/clojure/feature/secrets/sdk/feature/secrets.clj +38 -11
  90. package/project/.sdk/tm/clojure/test/sdk/test/feature/secrets.clj +40 -6
  91. package/project/.sdk/tm/cpp/Makefile +48 -4
  92. package/project/.sdk/tm/cpp/feature/secrets/plugin/capability.cpp +121 -0
  93. package/project/.sdk/tm/cpp/feature/secrets/plugin/capability.hpp +41 -0
  94. package/project/.sdk/tm/cpp/feature/secrets/plugin/catalog.cpp +60 -0
  95. package/project/.sdk/tm/cpp/feature/secrets/plugin/catalog.hpp +66 -0
  96. package/project/.sdk/tm/cpp/feature/secrets/plugin/config.cpp +376 -0
  97. package/project/.sdk/tm/cpp/feature/secrets/plugin/config.hpp +29 -0
  98. package/project/.sdk/tm/cpp/feature/secrets/plugin/depend.cpp +230 -0
  99. package/project/.sdk/tm/cpp/feature/secrets/plugin/depend.hpp +31 -0
  100. package/project/.sdk/tm/cpp/feature/secrets/plugin/env.cpp +205 -0
  101. package/project/.sdk/tm/cpp/feature/secrets/plugin/env.hpp +25 -0
  102. package/project/.sdk/tm/cpp/feature/secrets/plugin/export.cpp +84 -0
  103. package/project/.sdk/tm/cpp/feature/secrets/plugin/export.hpp +24 -0
  104. package/project/.sdk/tm/cpp/feature/secrets/plugin/graph.cpp +222 -0
  105. package/project/.sdk/tm/cpp/feature/secrets/plugin/graph.hpp +21 -0
  106. package/project/.sdk/tm/cpp/feature/secrets/plugin/host.cpp +1200 -0
  107. package/project/.sdk/tm/cpp/feature/secrets/plugin/host.hpp +250 -0
  108. package/project/.sdk/tm/cpp/feature/secrets/plugin/order.cpp +250 -0
  109. package/project/.sdk/tm/cpp/feature/secrets/plugin/order.hpp +22 -0
  110. package/project/.sdk/tm/cpp/feature/secrets/plugin/point.cpp +110 -0
  111. package/project/.sdk/tm/cpp/feature/secrets/plugin/point.hpp +79 -0
  112. package/project/.sdk/tm/cpp/feature/secrets/plugin/ref.cpp +136 -0
  113. package/project/.sdk/tm/cpp/feature/secrets/plugin/ref.hpp +60 -0
  114. package/project/.sdk/tm/cpp/feature/secrets/plugin/resolve.cpp +82 -0
  115. package/project/.sdk/tm/cpp/feature/secrets/plugin/resolve.hpp +25 -0
  116. package/project/.sdk/tm/cpp/feature/secrets/plugin/types.cpp +90 -0
  117. package/project/.sdk/tm/cpp/feature/secrets/plugin/types.hpp +65 -0
  118. package/project/.sdk/tm/cpp/feature/secrets/plugin/value.cpp +491 -0
  119. package/project/.sdk/tm/cpp/feature/secrets/plugin/value.hpp +120 -0
  120. package/project/.sdk/tm/cpp/feature/secrets/plugin/version.cpp +143 -0
  121. package/project/.sdk/tm/cpp/feature/secrets/plugin/version.hpp +36 -0
  122. package/project/.sdk/tm/cpp/feature/secrets/plugins/Aws.cpp +248 -0
  123. package/project/.sdk/tm/cpp/feature/secrets/plugins/Aws.hpp +30 -0
  124. package/project/.sdk/tm/cpp/feature/secrets/plugins/Azuresecrets.cpp +149 -0
  125. package/project/.sdk/tm/cpp/feature/secrets/plugins/Azuresecrets.hpp +23 -0
  126. package/project/.sdk/tm/cpp/feature/secrets/plugins/Boru.cpp +117 -0
  127. package/project/.sdk/tm/cpp/feature/secrets/plugins/Boru.hpp +27 -0
  128. package/project/.sdk/tm/cpp/feature/secrets/plugins/Crypto.cpp +180 -0
  129. package/project/.sdk/tm/cpp/feature/secrets/plugins/Crypto.hpp +52 -0
  130. package/project/.sdk/tm/cpp/feature/secrets/plugins/Doppler.cpp +87 -0
  131. package/project/.sdk/tm/cpp/feature/secrets/plugins/Doppler.hpp +23 -0
  132. package/project/.sdk/tm/cpp/feature/secrets/plugins/Gcpsecrets.cpp +121 -0
  133. package/project/.sdk/tm/cpp/feature/secrets/plugins/Gcpsecrets.hpp +23 -0
  134. package/project/.sdk/tm/cpp/feature/secrets/plugins/Hashicorp.cpp +153 -0
  135. package/project/.sdk/tm/cpp/feature/secrets/plugins/Hashicorp.hpp +23 -0
  136. package/project/.sdk/tm/cpp/feature/secrets/plugins/Httpjson.cpp +666 -0
  137. package/project/.sdk/tm/cpp/feature/secrets/plugins/Httpjson.hpp +160 -0
  138. package/project/.sdk/tm/cpp/feature/secrets/plugins/Infisical.cpp +123 -0
  139. package/project/.sdk/tm/cpp/feature/secrets/plugins/Infisical.hpp +23 -0
  140. package/project/.sdk/tm/cpp/feature/secrets/plugins/Onepassword.cpp +125 -0
  141. package/project/.sdk/tm/cpp/feature/secrets/plugins/Onepassword.hpp +23 -0
  142. package/project/.sdk/tm/cpp/feature/secrets/plugins/Proc.cpp +223 -0
  143. package/project/.sdk/tm/cpp/feature/secrets/plugins/Proc.hpp +47 -0
  144. package/project/.sdk/tm/cpp/feature/secrets/plugins/Secretspec.cpp +104 -0
  145. package/project/.sdk/tm/cpp/feature/secrets/plugins/Secretspec.hpp +27 -0
  146. package/project/.sdk/tm/cpp/feature/secrets/plugins/Sigv4.cpp +242 -0
  147. package/project/.sdk/tm/cpp/feature/secrets/plugins/Sigv4.hpp +58 -0
  148. package/project/.sdk/tm/cpp/feature/secrets/plugins/Tls.cpp +260 -0
  149. package/project/.sdk/tm/cpp/feature/secrets/plugins/Tls.hpp +47 -0
  150. package/project/.sdk/tm/cpp/feature/secrets/sekreto/Json.cpp +476 -0
  151. package/project/.sdk/tm/cpp/feature/secrets/sekreto/Json.hpp +89 -0
  152. package/project/.sdk/tm/cpp/feature/secrets/sekreto/Provider.cpp +312 -0
  153. package/project/.sdk/tm/cpp/feature/secrets/sekreto/Provider.hpp +263 -0
  154. package/project/.sdk/tm/cpp/feature/secrets/sekreto/Providers.cpp +354 -0
  155. package/project/.sdk/tm/cpp/feature/secrets/sekreto/Providers.hpp +111 -0
  156. package/project/.sdk/tm/cpp/feature/secrets/sekreto/Sekreto.cpp +613 -0
  157. package/project/.sdk/tm/cpp/feature/secrets/sekreto/Sekreto.hpp +227 -0
  158. package/project/.sdk/tm/cpp/feature/secrets.hpp +745 -0
  159. package/project/.sdk/tm/cpp/src/feature/secrets/.gitkeep +0 -0
  160. package/project/.sdk/tm/cpp/test/feature/secrets/secrets_test.cpp +808 -0
  161. package/project/.sdk/tm/csharp/feature/SecretsFeature.cs +34 -8
  162. package/project/.sdk/tm/csharp/test/feature/secrets/SecretsFeatureTest.cs +85 -0
  163. package/project/.sdk/tm/elixir/lib/projectname/feature/secrets.ex +17 -2
  164. package/project/.sdk/tm/elixir/test/feature/secrets/secrets_test.exs +41 -0
  165. package/project/.sdk/tm/go/feature/secrets_feature.go +32 -10
  166. package/project/.sdk/tm/go/test/feature/secrets/secrets_feature_test.go +116 -0
  167. package/project/.sdk/tm/java/feature/SecretsFeature.java +33 -8
  168. package/project/.sdk/tm/java/test/feature/secrets/SecretsFeatureTest.java +64 -0
  169. package/project/.sdk/tm/js/src/feature/secrets/SecretsFeature.js +34 -11
  170. package/project/.sdk/tm/js/test/feature/secrets/Secrets.test.js +73 -0
  171. package/project/.sdk/tm/kotlin/feature/SecretsFeature.kt +32 -7
  172. package/project/.sdk/tm/kotlin/test/feature/secrets/SecretsTest.kt +69 -0
  173. package/project/.sdk/tm/lua/Makefile +15 -4
  174. package/project/.sdk/tm/lua/feature/secrets/native/sekretonet.c +806 -0
  175. package/project/.sdk/tm/lua/feature/secrets/plugin/capability.lua +135 -0
  176. package/project/.sdk/tm/lua/feature/secrets/plugin/catalog.lua +63 -0
  177. package/project/.sdk/tm/lua/feature/secrets/plugin/config.lua +361 -0
  178. package/project/.sdk/tm/lua/feature/secrets/plugin/depend.lua +232 -0
  179. package/project/.sdk/tm/lua/feature/secrets/plugin/env.lua +168 -0
  180. package/project/.sdk/tm/lua/feature/secrets/plugin/export.lua +66 -0
  181. package/project/.sdk/tm/lua/feature/secrets/plugin/graph.lua +194 -0
  182. package/project/.sdk/tm/lua/feature/secrets/plugin/host.lua +1190 -0
  183. package/project/.sdk/tm/lua/feature/secrets/plugin/json.lua +169 -0
  184. package/project/.sdk/tm/lua/feature/secrets/plugin/order.lua +207 -0
  185. package/project/.sdk/tm/lua/feature/secrets/plugin/point.lua +106 -0
  186. package/project/.sdk/tm/lua/feature/secrets/plugin/ref.lua +115 -0
  187. package/project/.sdk/tm/lua/feature/secrets/plugin/resolve.lua +78 -0
  188. package/project/.sdk/tm/lua/feature/secrets/plugin/types.lua +275 -0
  189. package/project/.sdk/tm/lua/feature/secrets/plugin/version.lua +131 -0
  190. package/project/.sdk/tm/lua/feature/secrets/plugin.lua +76 -0
  191. package/project/.sdk/tm/lua/feature/secrets/sekreto/addr.lua +124 -0
  192. package/project/.sdk/tm/lua/feature/secrets/sekreto/err.lua +47 -0
  193. package/project/.sdk/tm/lua/feature/secrets/sekreto/name.lua +315 -0
  194. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/aws.lua +228 -0
  195. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/azuresecrets.lua +137 -0
  196. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/boru.lua +124 -0
  197. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/crypto.lua +212 -0
  198. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/doppler.lua +89 -0
  199. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/gcpsecrets.lua +129 -0
  200. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/hashicorp.lua +154 -0
  201. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/httpjson.lua +248 -0
  202. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/infisical.lua +113 -0
  203. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/json.lua +449 -0
  204. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/net.lua +198 -0
  205. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/onepassword.lua +126 -0
  206. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/secretspec.lua +93 -0
  207. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/sigv4.lua +269 -0
  208. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/support.lua +146 -0
  209. package/project/.sdk/tm/lua/feature/secrets/sekreto/providers.lua +346 -0
  210. package/project/.sdk/tm/lua/feature/secrets/sekreto.lua +479 -0
  211. package/project/.sdk/tm/lua/feature/secrets_feature.lua +690 -0
  212. package/project/.sdk/tm/lua/src/feature/secrets/.gitkeep +0 -0
  213. package/project/.sdk/tm/lua/test/extend_test.lua +105 -0
  214. package/project/.sdk/tm/lua/test/feature/secrets/secrets_feature_test.lua +862 -0
  215. package/project/.sdk/tm/ocaml/Makefile +52 -8
  216. package/project/.sdk/tm/ocaml/feature/secrets/plugin/capability.ml +106 -0
  217. package/project/.sdk/tm/ocaml/feature/secrets/plugin/catalog.ml +43 -0
  218. package/project/.sdk/tm/ocaml/feature/secrets/plugin/config.ml +349 -0
  219. package/project/.sdk/tm/ocaml/feature/secrets/plugin/defs.ml +143 -0
  220. package/project/.sdk/tm/ocaml/feature/secrets/plugin/depend.ml +217 -0
  221. package/project/.sdk/tm/ocaml/feature/secrets/plugin/env.ml +197 -0
  222. package/project/.sdk/tm/ocaml/feature/secrets/plugin/export.ml +89 -0
  223. package/project/.sdk/tm/ocaml/feature/secrets/plugin/graph.ml +227 -0
  224. package/project/.sdk/tm/ocaml/feature/secrets/plugin/host.ml +1112 -0
  225. package/project/.sdk/tm/ocaml/feature/secrets/plugin/order.ml +202 -0
  226. package/project/.sdk/tm/ocaml/feature/secrets/plugin/point.ml +138 -0
  227. package/project/.sdk/tm/ocaml/feature/secrets/plugin/ref.ml +126 -0
  228. package/project/.sdk/tm/ocaml/feature/secrets/plugin/resolve.ml +62 -0
  229. package/project/.sdk/tm/ocaml/feature/secrets/plugin/types.ml +97 -0
  230. package/project/.sdk/tm/ocaml/feature/secrets/plugin/value.ml +387 -0
  231. package/project/.sdk/tm/ocaml/feature/secrets/plugin/version.ml +139 -0
  232. package/project/.sdk/tm/ocaml/feature/secrets/plugins/aws.ml +171 -0
  233. package/project/.sdk/tm/ocaml/feature/secrets/plugins/azuresecrets.ml +116 -0
  234. package/project/.sdk/tm/ocaml/feature/secrets/plugins/boru.ml +95 -0
  235. package/project/.sdk/tm/ocaml/feature/secrets/plugins/crypto.ml +149 -0
  236. package/project/.sdk/tm/ocaml/feature/secrets/plugins/doppler.ml +61 -0
  237. package/project/.sdk/tm/ocaml/feature/secrets/plugins/gcpsecrets.ml +93 -0
  238. package/project/.sdk/tm/ocaml/feature/secrets/plugins/hashicorp.ml +120 -0
  239. package/project/.sdk/tm/ocaml/feature/secrets/plugins/http.ml +421 -0
  240. package/project/.sdk/tm/ocaml/feature/secrets/plugins/httpjson.ml +66 -0
  241. package/project/.sdk/tm/ocaml/feature/secrets/plugins/infisical.ml +85 -0
  242. package/project/.sdk/tm/ocaml/feature/secrets/plugins/onepassword.ml +112 -0
  243. package/project/.sdk/tm/ocaml/feature/secrets/plugins/runcmd.ml +97 -0
  244. package/project/.sdk/tm/ocaml/feature/secrets/plugins/secretspec.ml +68 -0
  245. package/project/.sdk/tm/ocaml/feature/secrets/plugins/sigv4.ml +259 -0
  246. package/project/.sdk/tm/ocaml/feature/secrets/plugins/tls.ml +44 -0
  247. package/project/.sdk/tm/ocaml/feature/secrets/plugins/tls_stubs.c +358 -0
  248. package/project/.sdk/tm/ocaml/feature/secrets/sekreto/json.ml +376 -0
  249. package/project/.sdk/tm/ocaml/feature/secrets/sekreto/provider.ml +647 -0
  250. package/project/.sdk/tm/ocaml/feature/secrets/sekreto/secret.ml +299 -0
  251. package/project/.sdk/tm/ocaml/feature/secrets/sekreto/sekreto.ml +347 -0
  252. package/project/.sdk/tm/ocaml/feature/secrets_feature.ml +453 -0
  253. package/project/.sdk/tm/ocaml/src/feature/secrets/.gitkeep +0 -0
  254. package/project/.sdk/tm/ocaml/test/feature/secrets/t_secrets.ml +670 -0
  255. package/project/.sdk/tm/perl/feature/secrets_feature.pm +33 -12
  256. package/project/.sdk/tm/perl/t/feature/secrets/secrets.t +47 -0
  257. package/project/.sdk/tm/php/feature/SecretsFeature.php +30 -6
  258. package/project/.sdk/tm/php/test/feature/secrets/SecretsTest.php +98 -0
  259. package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +28 -6
  260. package/project/.sdk/tm/py/test/feature/secrets/test_secrets.py +114 -0
  261. package/project/.sdk/tm/rb/feature/secrets_feature.rb +28 -6
  262. package/project/.sdk/tm/rb/test/feature/secrets/secrets_feature_test.rb +93 -0
  263. package/project/.sdk/tm/rust/feature/secrets.rs +33 -10
  264. package/project/.sdk/tm/rust/tests/feature/secrets/main.rs +96 -0
  265. package/project/.sdk/tm/scala/feature/SecretsFeature.scala +29 -7
  266. package/project/.sdk/tm/scala/sdktest/feature/secrets/SecretsTestMain.scala +71 -0
  267. package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +35 -12
  268. package/project/.sdk/tm/ts/test/feature/secrets/Secrets.test.ts +73 -0
  269. package/project/.sdk/tm/zig/feature/secrets/plugin/capability.zig +137 -0
  270. package/project/.sdk/tm/zig/feature/secrets/plugin/catalog.zig +90 -0
  271. package/project/.sdk/tm/zig/feature/secrets/plugin/config.zig +346 -0
  272. package/project/.sdk/tm/zig/feature/secrets/plugin/depend.zig +244 -0
  273. package/project/.sdk/tm/zig/feature/secrets/plugin/env.zig +201 -0
  274. package/project/.sdk/tm/zig/feature/secrets/plugin/export.zig +83 -0
  275. package/project/.sdk/tm/zig/feature/secrets/plugin/graph.zig +212 -0
  276. package/project/.sdk/tm/zig/feature/secrets/plugin/host.zig +1224 -0
  277. package/project/.sdk/tm/zig/feature/secrets/plugin/inst.zig +126 -0
  278. package/project/.sdk/tm/zig/feature/secrets/plugin/order.zig +228 -0
  279. package/project/.sdk/tm/zig/feature/secrets/plugin/plugin.zig +34 -0
  280. package/project/.sdk/tm/zig/feature/secrets/plugin/point.zig +166 -0
  281. package/project/.sdk/tm/zig/feature/secrets/plugin/ref.zig +147 -0
  282. package/project/.sdk/tm/zig/feature/secrets/plugin/resolve.zig +74 -0
  283. package/project/.sdk/tm/zig/feature/secrets/plugin/types.zig +140 -0
  284. package/project/.sdk/tm/zig/feature/secrets/plugin/value.zig +662 -0
  285. package/project/.sdk/tm/zig/feature/secrets/plugin/version.zig +139 -0
  286. package/project/.sdk/tm/zig/feature/secrets/plugins/aws.zig +294 -0
  287. package/project/.sdk/tm/zig/feature/secrets/plugins/azuresecrets.zig +222 -0
  288. package/project/.sdk/tm/zig/feature/secrets/plugins/boru.zig +188 -0
  289. package/project/.sdk/tm/zig/feature/secrets/plugins/doppler.zig +135 -0
  290. package/project/.sdk/tm/zig/feature/secrets/plugins/gcpsecrets.zig +170 -0
  291. package/project/.sdk/tm/zig/feature/secrets/plugins/hashicorp.zig +242 -0
  292. package/project/.sdk/tm/zig/feature/secrets/plugins/httpjson.zig +535 -0
  293. package/project/.sdk/tm/zig/feature/secrets/plugins/infisical.zig +167 -0
  294. package/project/.sdk/tm/zig/feature/secrets/plugins/onepassword.zig +202 -0
  295. package/project/.sdk/tm/zig/feature/secrets/plugins/secretspec.zig +160 -0
  296. package/project/.sdk/tm/zig/feature/secrets/plugins/sigv4.zig +336 -0
  297. package/project/.sdk/tm/zig/feature/secrets/sekreto/addr.zig +148 -0
  298. package/project/.sdk/tm/zig/feature/secrets/sekreto/builtins.zig +259 -0
  299. package/project/.sdk/tm/zig/feature/secrets/sekreto/provider.zig +440 -0
  300. package/project/.sdk/tm/zig/feature/secrets/sekreto/sekreto.zig +944 -0
  301. package/project/.sdk/tm/zig/feature/secrets.zig +854 -0
  302. package/project/.sdk/tm/zig/src/feature/secrets/.gitkeep +0 -0
  303. package/project/.sdk/tm/zig/test/feature/secrets/secrets_test.zig +891 -0
  304. package/project/sdkgen-package.json +1 -1
@@ -0,0 +1,944 @@
1
+ // VENDORED: @voxgig/sekreto sdk-20260908-1556-0 (zig/src/sekreto.zig)
2
+ // Source: https://github.com/voxgig/sekreto @ 1267ee2e5f49566bc92695bc9eb3a60ef4924998 [tag: sdk-20260908-1556-0]
3
+ // License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
4
+ //! sekreto: one interface for secrets, wherever they live.
5
+ //!
6
+ //! A Sekreto is an ordered chain of providers. `get` asks each in turn and
7
+ //! returns the first hit, so an app can be configured from environment
8
+ //! variables in development and a vault in production without changing a
9
+ //! line of its own code.
10
+ //!
11
+ //! This is the Zig port. The CANONICAL implementation is
12
+ //! ../../typescript/src/Sekreto.ts, and ../../spec/sekreto.json is the
13
+ //! behavioural contract every port runs.
14
+ //!
15
+ //! THE CORE REACHES NO PROVIDER THAT OPENS A SOCKET, SPAWNS A PROCESS OR
16
+ //! SIGNS A REQUEST. The four built-in kinds - env, memory, dotenv, file -
17
+ //! read at most a local file; every other kind is a voxgig/plugin
18
+ //! definition under ../plugins/, and a chain may name one only if the
19
+ //! calling project handed it in through `Options.plugins`. In zig that is
20
+ //! the compiler's rule as much as this library's: a module's imports are
21
+ //! confined to its root's directory, this file is the root of `sekreto`,
22
+ //! and `../plugins/` is outside it. See docs/design/plugin-providers.md.
23
+ //!
24
+ //! Zig has no exceptions, and its error values carry no payload, so a
25
+ //! failure is RETURNED as a message - the shape voxgig/omni's own Zig port
26
+ //! uses. That also keeps the distinction this library cares about most
27
+ //! structural rather than conventional:
28
+ //!
29
+ //! Answer(?[]const u8){ .ok = "value" } a hit
30
+ //! Answer(?[]const u8){ .ok = null } a MISS - the chain carries on
31
+ //! Answer(?[]const u8){ .err = message } a FAILURE - the chain stops
32
+ //!
33
+ //! Memory: every function that can allocate takes the allocator first, and
34
+ //! what it returns (value or message) comes from that allocator. `Sekreto`
35
+ //! owns one allocator for what outlives a lookup (the cache, the redaction
36
+ //! list, the last failure message) and runs each lookup inside an arena it
37
+ //! resets afterwards, so repeated lookups do not grow the heap. What the
38
+ //! plugin host holds - definitions, instances, option maps - lives in
39
+ //! voxgig/plugin's own arena, which is never freed: construction is paid
40
+ //! for once per chain, and a process that builds chains in a loop should
41
+ //! know it.
42
+
43
+ const std = @import("std");
44
+
45
+ /// voxgig/plugin, the one dependency: the host every chain is made of.
46
+ /// Re-exported so a caller can introspect `Sekreto.host` - `list`,
47
+ /// `instance`, `exports` - without wiring the module in a second time.
48
+ pub const plugin = @import("plugin");
49
+
50
+ pub const provider = @import("provider.zig");
51
+ pub const builtins = @import("builtins.zig");
52
+ pub const addr = @import("addr.zig");
53
+
54
+ pub const Provider = provider.Provider;
55
+ pub const ProviderSpec = provider.ProviderSpec;
56
+ pub const KeyValue = provider.KeyValue;
57
+ pub const Auth = provider.Auth;
58
+ pub const Config = provider.Config;
59
+ pub const Definition = provider.Definition;
60
+ pub const providerplugin = provider.providerplugin;
61
+ pub const provide = provider.provide;
62
+ pub const adapt = provider.adapt;
63
+ pub const PROVIDER_EXPORT = provider.PROVIDER_EXPORT;
64
+ pub const ERROR_CODE = provider.ERROR_CODE;
65
+ pub const BUILTINS = builtins.BUILTINS;
66
+ pub const KINDS = builtins.KINDS;
67
+ pub const checkaddr = addr.checkaddr;
68
+ pub const safeaddr = addr.safeaddr;
69
+
70
+ const Allocator = std.mem.Allocator;
71
+ const pv = plugin.value;
72
+ const pt = plugin.types;
73
+
74
+ /// What a fallible call returns: the value, or the message of a failure.
75
+ ///
76
+ /// A provider lookup is `Answer(?[]const u8)`, where `.ok = null` is a miss.
77
+ /// A miss and a failure are therefore different cases of different depth,
78
+ /// and no caller can confuse one for the other by accident.
79
+ pub fn Answer(comptime T: type) type {
80
+ return union(enum) {
81
+ ok: T,
82
+ err: []const u8,
83
+ };
84
+ }
85
+
86
+ /// A secret, or a miss.
87
+ pub const Found = Answer(?[]const u8);
88
+
89
+ /// A secret name: dot-separated lowercase segments, e.g. `api.token`.
90
+ pub const Name = []const u8;
91
+
92
+ /// The message of anything sekreto refuses to do: a bad name, a missing
93
+ /// secret, a provider that could not be reached.
94
+ pub fn fail(alloc: Allocator, comptime format: []const u8, args: anytype) Allocator.Error![]const u8 {
95
+ return std.fmt.allocPrint(alloc, format, args);
96
+ }
97
+
98
+ /// Is this a well-formed secret name? Dot-separated segments of `[a-z0-9_]`.
99
+ pub fn validname(name: Name) bool {
100
+ if (0 == name.len) {
101
+ return false;
102
+ }
103
+
104
+ var parts = std.mem.splitScalar(u8, name, '.');
105
+
106
+ while (parts.next()) |part| {
107
+ if (0 == part.len) {
108
+ return false;
109
+ }
110
+ for (part) |ch| {
111
+ const ok = ('a' <= ch and 'z' >= ch) or ('0' <= ch and '9' >= ch) or '_' == ch;
112
+ if (!ok) {
113
+ return false;
114
+ }
115
+ }
116
+ }
117
+
118
+ return true;
119
+ }
120
+
121
+ /// The name itself, or the message that says why it is not one.
122
+ pub fn checkname(alloc: Allocator, name: Name) Allocator.Error!Answer(Name) {
123
+ if (!validname(name)) {
124
+ return .{ .err = try fail(alloc, "sekreto: invalid name: {s}", .{name}) };
125
+ }
126
+ return .{ .ok = name };
127
+ }
128
+
129
+ /// The environment-variable key for a name: `api.token` -> `API_TOKEN`.
130
+ pub fn envkey(alloc: Allocator, name: Name, prefix: []const u8) Allocator.Error!Answer([]const u8) {
131
+ switch (try checkname(alloc, name)) {
132
+ .err => |message| return .{ .err = message },
133
+ .ok => {},
134
+ }
135
+
136
+ var out: std.ArrayList(u8) = .empty;
137
+ try out.appendSlice(alloc, prefix);
138
+
139
+ for (name) |ch| {
140
+ try out.append(alloc, if ('.' == ch) '_' else std.ascii.toUpper(ch));
141
+ }
142
+
143
+ return .{ .ok = out.items };
144
+ }
145
+
146
+ /// Where a name lives in a KV vault: `api.token` -> `api` / `token`.
147
+ ///
148
+ /// A single-segment name has no path of its own, so it becomes a secret of
149
+ /// that name with the conventional field `value`.
150
+ pub const VaultRef = struct {
151
+ path: []const u8,
152
+ field: []const u8,
153
+ };
154
+
155
+ pub fn vaultref(alloc: Allocator, name: Name) Allocator.Error!Answer(VaultRef) {
156
+ switch (try checkname(alloc, name)) {
157
+ .err => |message| return .{ .err = message },
158
+ .ok => {},
159
+ }
160
+
161
+ const cut = std.mem.lastIndexOfScalar(u8, name, '.') orelse {
162
+ return .{ .ok = .{ .path = name, .field = "value" } };
163
+ };
164
+
165
+ var path: std.ArrayList(u8) = .empty;
166
+ for (name[0..cut]) |ch| {
167
+ try path.append(alloc, if ('.' == ch) '/' else ch);
168
+ }
169
+
170
+ return .{ .ok = .{ .path = path.items, .field = name[cut + 1 ..] } };
171
+ }
172
+
173
+ /// A name flattened to one segment: `api.token` -> `api_token` (GCP Secret
174
+ /// Manager, `_`) or `api-token` (Azure Key Vault, `-`).
175
+ ///
176
+ /// Those stores have no path hierarchy and reject dots in ids, so the dots
177
+ /// become the store's conventional separator. With `-` as the separator,
178
+ /// underscores flatten too: Azure Key Vault's alphabet is letters, digits
179
+ /// and hyphens only, and a valid sekreto name like `with_underscore` must
180
+ /// still be representable there.
181
+ pub fn flatname(alloc: Allocator, name: Name, sep: []const u8) Allocator.Error!Answer([]const u8) {
182
+ switch (try checkname(alloc, name)) {
183
+ .err => |message| return .{ .err = message },
184
+ .ok => {},
185
+ }
186
+
187
+ const hyphen = std.mem.eql(u8, "-", sep);
188
+
189
+ var out: std.ArrayList(u8) = .empty;
190
+ for (name) |ch| {
191
+ if ('.' == ch) {
192
+ try out.appendSlice(alloc, sep);
193
+ } else if (hyphen and '_' == ch) {
194
+ try out.append(alloc, '-');
195
+ } else {
196
+ try out.append(alloc, ch);
197
+ }
198
+ }
199
+
200
+ return .{ .ok = out.items };
201
+ }
202
+
203
+ /// The AWS SSM Parameter Store name for a name: dots become the path
204
+ /// hierarchy, rooted at `/` (or at a prefix): `db.pass.main` ->
205
+ /// `/db/pass/main`, or `/app/db/pass/main` under prefix `/app`.
206
+ pub fn awsparam(alloc: Allocator, name: Name, prefix: []const u8) Allocator.Error!Answer([]const u8) {
207
+ switch (try checkname(alloc, name)) {
208
+ .err => |message| return .{ .err = message },
209
+ .ok => {},
210
+ }
211
+
212
+ var base = prefix;
213
+ var out: std.ArrayList(u8) = .empty;
214
+
215
+ if (0 != base.len and '/' != base[0]) {
216
+ try out.append(alloc, '/');
217
+ }
218
+ if (0 != base.len and '/' == base[base.len - 1]) {
219
+ base = base[0 .. base.len - 1];
220
+ }
221
+
222
+ try out.appendSlice(alloc, base);
223
+ try out.append(alloc, '/');
224
+
225
+ for (name) |ch| {
226
+ try out.append(alloc, if ('.' == ch) '/' else ch);
227
+ }
228
+
229
+ return .{ .ok = out.items };
230
+ }
231
+
232
+ /// A parsed `.env`: raw keys to values, in the order the file gave them.
233
+ ///
234
+ /// An ordered list rather than a hash map, because the spec compares the
235
+ /// whole map and a randomised iteration order would make that comparison
236
+ /// depend on the run.
237
+ pub const Dotenv = struct {
238
+ keys: [][]const u8,
239
+ values: [][]const u8,
240
+
241
+ pub fn get(self: Dotenv, key: []const u8) ?[]const u8 {
242
+ for (self.keys, 0..) |candidate, at| {
243
+ if (std.mem.eql(u8, candidate, key)) {
244
+ return self.values[at];
245
+ }
246
+ }
247
+ return null;
248
+ }
249
+ };
250
+
251
+ /// Parse `.env` text into raw keys and values.
252
+ ///
253
+ /// Deliberately small: `KEY=value`, optional `export`, `#` comments on their
254
+ /// own line, and single- or double-quoted values (double quotes also
255
+ /// unescape `\n`, `\r`, `\t` and `\\`). A line with no `=` is skipped.
256
+ pub fn parsedotenv(alloc: Allocator, text: []const u8) Allocator.Error!Dotenv {
257
+ var keys: std.ArrayList([]const u8) = .empty;
258
+ var values: std.ArrayList([]const u8) = .empty;
259
+
260
+ var lines = std.mem.splitScalar(u8, text, '\n');
261
+
262
+ while (lines.next()) |rawline| {
263
+ var line = rawline;
264
+ if (0 != line.len and '\r' == line[line.len - 1]) {
265
+ line = line[0 .. line.len - 1];
266
+ }
267
+ line = std.mem.trim(u8, line, " \t");
268
+
269
+ if (0 == line.len or '#' == line[0]) {
270
+ continue;
271
+ }
272
+
273
+ const body = if (std.mem.startsWith(u8, line, "export "))
274
+ std.mem.trim(u8, line[7..], " \t")
275
+ else
276
+ line;
277
+
278
+ const eq = std.mem.indexOfScalar(u8, body, '=') orelse continue;
279
+ if (0 == eq) {
280
+ continue;
281
+ }
282
+
283
+ const key = std.mem.trim(u8, body[0..eq], " \t");
284
+ var value = std.mem.trim(u8, body[eq + 1 ..], " \t");
285
+
286
+ if (2 <= value.len and '"' == value[0] and '"' == value[value.len - 1]) {
287
+ value = try unescape(alloc, value[1 .. value.len - 1]);
288
+ } else if (2 <= value.len and '\'' == value[0] and '\'' == value[value.len - 1]) {
289
+ value = value[1 .. value.len - 1];
290
+ }
291
+
292
+ // A repeated key takes the later value, as an assignment does.
293
+ var replaced = false;
294
+ for (keys.items, 0..) |candidate, at| {
295
+ if (std.mem.eql(u8, candidate, key)) {
296
+ values.items[at] = value;
297
+ replaced = true;
298
+ break;
299
+ }
300
+ }
301
+ if (!replaced) {
302
+ try keys.append(alloc, key);
303
+ try values.append(alloc, value);
304
+ }
305
+ }
306
+
307
+ return .{ .keys = keys.items, .values = values.items };
308
+ }
309
+
310
+ fn unescape(alloc: Allocator, text: []const u8) Allocator.Error![]const u8 {
311
+ var out: std.ArrayList(u8) = .empty;
312
+
313
+ var index: usize = 0;
314
+ while (index < text.len) : (index += 1) {
315
+ if ('\\' == text[index] and index + 1 < text.len) {
316
+ const next = text[index + 1];
317
+ index += 1;
318
+ switch (next) {
319
+ 'n' => try out.append(alloc, '\n'),
320
+ 'r' => try out.append(alloc, '\r'),
321
+ 't' => try out.append(alloc, '\t'),
322
+ '\\' => try out.append(alloc, '\\'),
323
+ '"' => try out.append(alloc, '"'),
324
+ else => {
325
+ try out.append(alloc, '\\');
326
+ try out.append(alloc, next);
327
+ },
328
+ }
329
+ } else {
330
+ try out.append(alloc, text[index]);
331
+ }
332
+ }
333
+
334
+ return out.items;
335
+ }
336
+
337
+ /// Replace known secret values in text with `[redacted]`.
338
+ ///
339
+ /// Only values of four characters or more are replaced: shorter ones are
340
+ /// too likely to appear in ordinary text, and redacting them would make
341
+ /// logs unreadable without making them safer.
342
+ pub fn redact(alloc: Allocator, text: []const u8, values: []const []const u8) Allocator.Error![]const u8 {
343
+ var out: []const u8 = text;
344
+
345
+ // Longest first: a shorter secret that prefixes a longer one used to eat
346
+ // the prefix and leave the rest in the log. Copied first, so the
347
+ // caller's slice is not reordered.
348
+ const usable = try alloc.alloc([]const u8, values.len);
349
+ defer alloc.free(usable);
350
+
351
+ var count: usize = 0;
352
+ for (values) |value| {
353
+ if (4 <= value.len) {
354
+ usable[count] = value;
355
+ count += 1;
356
+ }
357
+ }
358
+
359
+ const longest = struct {
360
+ fn before(_: void, left: []const u8, right: []const u8) bool {
361
+ return left.len > right.len;
362
+ }
363
+ }.before;
364
+ std.mem.sort([]const u8, usable[0..count], {}, longest);
365
+
366
+ for (usable[0..count]) |value| {
367
+ out = try replaceall(alloc, out, value, "[redacted]");
368
+ }
369
+
370
+ return out;
371
+ }
372
+
373
+ fn replaceall(
374
+ alloc: Allocator,
375
+ text: []const u8,
376
+ from: []const u8,
377
+ to: []const u8,
378
+ ) Allocator.Error![]const u8 {
379
+ if (null == std.mem.indexOf(u8, text, from)) {
380
+ return text;
381
+ }
382
+
383
+ var out: std.ArrayList(u8) = .empty;
384
+ var rest = text;
385
+
386
+ while (std.mem.indexOf(u8, rest, from)) |at| {
387
+ try out.appendSlice(alloc, rest[0..at]);
388
+ try out.appendSlice(alloc, to);
389
+ rest = rest[at + from.len ..];
390
+ }
391
+
392
+ try out.appendSlice(alloc, rest);
393
+ return out.items;
394
+ }
395
+
396
+ /// Decode standard base64 - GCP payloads and AWS binary secrets.
397
+ pub fn unbase64(alloc: Allocator, text: []const u8) Allocator.Error!?[]const u8 {
398
+ const decoder = std.base64.standard.Decoder;
399
+
400
+ const size = decoder.calcSizeForSlice(text) catch return null;
401
+ const out = try alloc.alloc(u8, size);
402
+ decoder.decode(out, text) catch return null;
403
+
404
+ return out;
405
+ }
406
+
407
+ /// One provider in the chain, under the store name it answers to, and the
408
+ /// ref of the plugin instance that built it.
409
+ const Entry = struct {
410
+ store: []const u8,
411
+ ref: []const u8,
412
+ provider: Provider,
413
+ };
414
+
415
+ /// One resolved value, under the store the CALLER named ("" for a
416
+ /// transparent `get`). Kept as a list rather than a map so that the store
417
+ /// stays attached, and so redaction order is stable.
418
+ ///
419
+ /// `store` and `name` are copies: they arrive from the caller and must not
420
+ /// outlive it. `value` is not - it points at the copy `seen` already owns,
421
+ /// so a cached secret is stored once and freed once.
422
+ const Cached = struct {
423
+ store: []const u8,
424
+ name: []const u8,
425
+ value: []const u8,
426
+ };
427
+
428
+ /// What `Sekreto.init` takes.
429
+ pub const Options = struct {
430
+ /// The chain, in resolution order: each entry names a kind to build -
431
+ /// a built-in, or a plugin passed in `plugins`.
432
+ providers: []const ProviderSpec = &.{},
433
+ /// The provider kinds beyond the built-ins that `providers` may name,
434
+ /// as voxgig/plugin definitions. Static and explicit: the calling
435
+ /// project imports the plugins it needs and passes them here, and a
436
+ /// kind it did not pass is unknown to this Sekreto.
437
+ plugins: []const Definition = &.{},
438
+ /// Cache resolved values (default: true).
439
+ cache: bool = true,
440
+ };
441
+
442
+ /// A slice with nothing in it, for a closed chain: `[]Entry` cannot be
443
+ /// made from an empty literal without discarding const.
444
+ var noentries: [0]Entry = .{};
445
+
446
+ /// The message for a kind the catalog does not hold.
447
+ ///
448
+ /// A kind sekreto has never heard of is a typo; a kind that exists as a
449
+ /// plugin but was not passed in is the split working as designed and
450
+ /// telling you what to pass. Collapsing the two was the first thing that
451
+ /// made the split confusing to use.
452
+ fn unknownkind(alloc: Allocator, kind: []const u8, catalog: *plugin.catalog.Catalog) Allocator.Error![]const u8 {
453
+ var out: std.ArrayList(u8) = .empty;
454
+ errdefer out.deinit(alloc);
455
+
456
+ try out.appendSlice(alloc, "sekreto: unknown provider kind: ");
457
+ try out.appendSlice(alloc, kind);
458
+ try out.appendSlice(alloc, " (available: ");
459
+ for (pv.items(catalog.names()), 0..) |name, at| {
460
+ if (0 < at) {
461
+ try out.appendSlice(alloc, ", ");
462
+ }
463
+ try out.appendSlice(alloc, pv.asStr(name));
464
+ }
465
+ try out.appendSlice(alloc, ")");
466
+
467
+ for (KINDS.plugin) |known| {
468
+ if (std.mem.eql(u8, known, kind)) {
469
+ try out.appendSlice(alloc, " - ");
470
+ try out.appendSlice(alloc, kind);
471
+ try out.appendSlice(alloc, " is a sekreto plugin, not built in: pass it in the plugins option");
472
+ break;
473
+ }
474
+ }
475
+
476
+ return out.toOwnedSlice(alloc);
477
+ }
478
+
479
+ /// The parked plugin error, as a message the caller owns. A sekreto
480
+ /// failure that crossed the plugin boundary comes back out as itself,
481
+ /// byte for byte; anything else is the host's report, as the host words
482
+ /// it, and not sekreto's to rewrite.
483
+ fn unwrap(alloc: Allocator) Allocator.Error![]const u8 {
484
+ const err = pt.take();
485
+ const cause = pv.get(err.details, "cause");
486
+
487
+ if (std.mem.eql(u8, ERROR_CODE, err.code) and pv.isStr(cause)) {
488
+ return alloc.dupe(u8, pv.asStr(cause));
489
+ }
490
+
491
+ return alloc.dupe(u8, err.message);
492
+ }
493
+
494
+ /// One definition into the catalog: a copy the host can keep, since the
495
+ /// catalog holds pointers and the caller's slice is its own.
496
+ fn register(alloc: Allocator, catalog: *plugin.catalog.Catalog, definition: Definition) Allocator.Error!?[]const u8 {
497
+ const copy = pv.arena().create(Definition) catch return error.OutOfMemory;
498
+ copy.* = definition;
499
+ catalog.add(copy) catch return try unwrap(alloc);
500
+ return null;
501
+ }
502
+
503
+ /// One chain entry, as a plugin instance.
504
+ ///
505
+ /// The instance is `kind` for a store named after its kind and
506
+ /// `kind$store` otherwise - `hashicorp$prod` - so `host.list()` reads like
507
+ /// the chain. A store name that is already taken gets a numbered tag from
508
+ /// the host instead, because two providers MAY share a store name (a
509
+ /// directed read walks both) and an instance ref may not.
510
+ fn declare(
511
+ alloc: Allocator,
512
+ host: *plugin.host.Host,
513
+ catalog: *plugin.catalog.Catalog,
514
+ b: *provider.Building,
515
+ spec: ProviderSpec,
516
+ ) Allocator.Error!Answer(Entry) {
517
+ const kind = spec.kind;
518
+
519
+ if (!catalog.has(kind)) {
520
+ return .{ .err = try unknownkind(alloc, kind, catalog) };
521
+ }
522
+
523
+ const store = if (0 != spec.name.len) spec.name else kind;
524
+
525
+ if (!plugin.ref.checktag(pv.vstr(store))) {
526
+ return .{ .err = try fail(alloc, "sekreto: invalid store name: {s}", .{store}) };
527
+ }
528
+
529
+ var ref: []const u8 = kind;
530
+ if (!std.mem.eql(u8, store, kind)) {
531
+ ref = plugin.ref.formatref(pv.vstr(kind), pv.vstr(store)) catch return .{ .err = try unwrap(alloc) };
532
+ }
533
+ const taken = plugin.host.instance(host, ref) catch return .{ .err = try unwrap(alloc) };
534
+ if (null != taken) {
535
+ ref = plugin.host.autotag(host, kind) catch return .{ .err = try unwrap(alloc) };
536
+ }
537
+
538
+ // `load` runs the definition's `define`, which builds the provider
539
+ // from the spec; `activate` takes the instance live. Nothing is
540
+ // contacted by either: a provider opens nothing until its first
541
+ // lookup.
542
+ _ = plugin.host.load(host, ref, .{ .options = provider.optionsof(spec) }) catch {
543
+ if (b.oom) {
544
+ _ = pt.take();
545
+ return error.OutOfMemory;
546
+ }
547
+ return .{ .err = try unwrap(alloc) };
548
+ };
549
+ _ = plugin.host.activate(host, ref) catch return .{ .err = try unwrap(alloc) };
550
+
551
+ const key = try std.fmt.allocPrint(alloc, "{s}/{s}", .{ ref, PROVIDER_EXPORT });
552
+ defer alloc.free(key);
553
+
554
+ const exported = plugin.host.exports(host, key) catch return .{ .err = try unwrap(alloc) };
555
+ if (!pv.isNum(exported)) {
556
+ return .{ .err = try fail(alloc, "sekreto: plugin {s} exported no provider", .{kind}) };
557
+ }
558
+ const index: usize = @intFromFloat(pv.asNum(exported));
559
+
560
+ return .{ .ok = .{
561
+ .store = try alloc.dupe(u8, store),
562
+ .ref = try alloc.dupe(u8, ref),
563
+ .provider = b.made.items[index],
564
+ } };
565
+ }
566
+
567
+ /// Undo a chain that could not be finished: the host closed, every
568
+ /// provider built so far released, every store name freed.
569
+ fn teardown(alloc: Allocator, host: *plugin.host.Host, b: *provider.Building, entries: *std.ArrayList(Entry)) void {
570
+ plugin.host.close(host) catch {
571
+ _ = pt.take();
572
+ };
573
+ for (b.made.items) |made| {
574
+ made.deinit(alloc);
575
+ }
576
+ for (entries.items) |entry| {
577
+ alloc.free(entry.store);
578
+ alloc.free(entry.ref);
579
+ }
580
+ entries.deinit(alloc);
581
+ }
582
+
583
+ /// The secrets facade: a chain of providers plus a cache.
584
+ ///
585
+ /// Two ways to read. `get` is transparent - it walks the chain and takes the
586
+ /// first hit, and the caller never learns which store answered. `getfrom` is
587
+ /// directed - it names the store, and only that store is asked. Use the
588
+ /// first for ordinary configuration, the second when *which* store holds a
589
+ /// secret is part of what you mean.
590
+ pub const Sekreto = struct {
591
+ alloc: Allocator,
592
+ /// The voxgig/plugin host every chain entry is an instance of. Read it
593
+ /// for introspection - `plugin.host.list(secrets.host)` names each
594
+ /// store's ref and status - and nothing on it advances the chain.
595
+ host: *plugin.host.Host,
596
+ /// The definitions this Sekreto can build: the built-ins plus what
597
+ /// `Options.plugins` handed in.
598
+ catalog: *plugin.catalog.Catalog,
599
+ entries: []Entry,
600
+ docache: bool,
601
+ cache: std.ArrayList(Cached),
602
+ // Every value ever resolved, for redact(). Kept independently of the
603
+ // read cache so that redaction still works when caching is off -
604
+ // otherwise `cache: false` would silently disable redact() and leak
605
+ // secrets to logs. It also owns every value string the cache points at.
606
+ seen: std.ArrayList([]const u8),
607
+ // Scratch for one lookup: URLs, request bodies, parsed responses. Reset
608
+ // after every lookup, so a long-running process that reads the same
609
+ // secrets over and over does not grow.
610
+ scratch: std.heap.ArenaAllocator,
611
+ // The most recent failure message, owned here so that a caller need not
612
+ // free it and a retry loop cannot accumulate them.
613
+ lasterr: ?[]const u8,
614
+
615
+ /// Build a chain: a catalog of the built-in kinds plus the plugins, a
616
+ /// voxgig/plugin host, and one instance of the right kind per chain
617
+ /// entry. It fails on a kind the catalog does not hold, a store name
618
+ /// that is not a valid tag, or a provider that refuses its own
619
+ /// configuration.
620
+ ///
621
+ /// Heap-allocated, not returned by value: the scratch arena hands out an
622
+ /// allocator that points at its own address, so a Sekreto that moved
623
+ /// after construction would hand every lookup a dangling one.
624
+ ///
625
+ /// A failure here hands back a message the CALLER owns - there is no
626
+ /// Sekreto yet to own it. Once there is one, every message a lookup
627
+ /// returns belongs to the Sekreto and is freed by `deinit`.
628
+ pub fn init(alloc: Allocator, config: Config, options: Options) Allocator.Error!Answer(*Sekreto) {
629
+ // Built-ins first, then the plugins, into one catalog: a plugin
630
+ // that names a built-in kind replaces it, which is how a host
631
+ // substitutes an implementation and never an accident, because the
632
+ // four names are documented.
633
+ const catalog = plugin.catalog.makecatalog();
634
+ for (BUILTINS) |definition| {
635
+ if (try register(alloc, catalog, definition)) |message| {
636
+ return .{ .err = message };
637
+ }
638
+ }
639
+ for (options.plugins) |definition| {
640
+ if (try register(alloc, catalog, definition)) |message| {
641
+ return .{ .err = message };
642
+ }
643
+ }
644
+
645
+ const host = plugin.host.makehost(.{ .catalog = catalog });
646
+
647
+ var b = provider.Building{ .alloc = alloc, .config = config };
648
+ provider.building = &b;
649
+ defer provider.building = null;
650
+ defer b.made.deinit(alloc);
651
+
652
+ var entries: std.ArrayList(Entry) = .empty;
653
+ // A chain that cannot be built is not left half-built. `errdefer`
654
+ // covers running out of memory; the `.err` arm covers a spec this
655
+ // library refuses, which is a returned value rather than a Zig
656
+ // error and so is not an errdefer's business.
657
+ errdefer teardown(alloc, host, &b, &entries);
658
+
659
+ for (options.providers) |spec| {
660
+ switch (try declare(alloc, host, catalog, &b, spec)) {
661
+ .err => |message| {
662
+ teardown(alloc, host, &b, &entries);
663
+ return .{ .err = message };
664
+ },
665
+ .ok => |entry| try entries.append(alloc, entry),
666
+ }
667
+ }
668
+
669
+ const self = try alloc.create(Sekreto);
670
+ errdefer alloc.destroy(self);
671
+
672
+ self.* = .{
673
+ .alloc = alloc,
674
+ .host = host,
675
+ .catalog = catalog,
676
+ .entries = try entries.toOwnedSlice(alloc),
677
+ .docache = options.cache,
678
+ .cache = .empty,
679
+ .seen = .empty,
680
+ .scratch = std.heap.ArenaAllocator.init(alloc),
681
+ .lasterr = null,
682
+ };
683
+
684
+ return .{ .ok = self };
685
+ }
686
+
687
+ /// Tear the chain down: every plugin instance is deactivated and
688
+ /// unloaded, in reverse, releasing whatever a provider acquired at
689
+ /// activation, and every provider is freed. Afterwards there is
690
+ /// nothing to read from - `get` reports every secret unknown - and the
691
+ /// cache is dropped, though `redactText` still knows every value that
692
+ /// was ever resolved. Idempotent.
693
+ pub fn close(self: *Sekreto) void {
694
+ plugin.host.close(self.host) catch {
695
+ _ = pt.take();
696
+ };
697
+
698
+ for (self.entries) |entry| {
699
+ entry.provider.deinit(self.alloc);
700
+ self.alloc.free(entry.store);
701
+ self.alloc.free(entry.ref);
702
+ }
703
+ self.alloc.free(self.entries);
704
+ self.entries = &noentries;
705
+
706
+ self.refresh();
707
+ }
708
+
709
+ pub fn deinit(self: *Sekreto) void {
710
+ self.close();
711
+
712
+ for (self.seen.items) |value| {
713
+ self.alloc.free(value);
714
+ }
715
+ self.seen.deinit(self.alloc);
716
+ self.cache.deinit(self.alloc);
717
+
718
+ if (self.lasterr) |message| {
719
+ self.alloc.free(message);
720
+ }
721
+
722
+ self.scratch.deinit();
723
+ self.alloc.destroy(self);
724
+ }
725
+
726
+ /// The secret, or a failure if no provider has it.
727
+ pub fn get(self: *Sekreto, name: Name) Allocator.Error!Answer([]const u8) {
728
+ switch (try self.trysecret(name)) {
729
+ .err => |message| return .{ .err = message },
730
+ .ok => |found| {
731
+ const value = found orelse
732
+ return .{ .err = try self.keep("sekreto: unknown secret: {s}", .{name}) };
733
+ return .{ .ok = value };
734
+ },
735
+ }
736
+ }
737
+
738
+ /// The secret, or null if no provider has it.
739
+ ///
740
+ /// Named `trysecret` because `try` is a Zig keyword; every port names
741
+ /// this the closest thing its language allows.
742
+ pub fn trysecret(self: *Sekreto, name: Name) Allocator.Error!Found {
743
+ return self.resolve("", name, self.entries);
744
+ }
745
+
746
+ /// The secret from one named store, or a failure if that store does not
747
+ /// have it.
748
+ pub fn getfrom(self: *Sekreto, store: []const u8, name: Name) Allocator.Error!Answer([]const u8) {
749
+ switch (try self.tryfrom(store, name)) {
750
+ .err => |message| return .{ .err = message },
751
+ .ok => |found| {
752
+ const value = found orelse return .{
753
+ .err = try self.keep("sekreto: unknown secret: {s}:{s}", .{ store, name }),
754
+ };
755
+ return .{ .ok = value };
756
+ },
757
+ }
758
+ }
759
+
760
+ /// The secret from one named store, or null if that store does not have
761
+ /// it.
762
+ ///
763
+ /// Naming a store that is not in the chain is an error, not a miss:
764
+ /// `try` already means "this store may not have it", so it cannot also
765
+ /// mean "this store may not exist" without hiding a typo.
766
+ pub fn tryfrom(self: *Sekreto, store: []const u8, name: Name) Allocator.Error!Found {
767
+ var matching: std.ArrayList(Entry) = .empty;
768
+ defer matching.deinit(self.alloc);
769
+
770
+ for (self.entries) |entry| {
771
+ if (std.mem.eql(u8, entry.store, store)) {
772
+ try matching.append(self.alloc, entry);
773
+ }
774
+ }
775
+
776
+ if (0 == matching.items.len) {
777
+ return .{ .err = try self.keep("sekreto: unknown store: {s}", .{store}) };
778
+ }
779
+
780
+ return self.resolve(store, name, matching.items);
781
+ }
782
+
783
+ fn resolve(self: *Sekreto, store: []const u8, name: Name, entries: []const Entry) Allocator.Error!Found {
784
+ const work = self.scratch.allocator();
785
+ // The scratch arena holds only what this lookup needs; anything that
786
+ // outlives it is copied into self.alloc before the reset.
787
+ defer _ = self.scratch.reset(.retain_capacity);
788
+
789
+ switch (try checkname(work, name)) {
790
+ .err => |message| return .{ .err = try self.keepraw(message) },
791
+ .ok => {},
792
+ }
793
+
794
+ if (self.docache) {
795
+ for (self.cache.items) |entry| {
796
+ if (std.mem.eql(u8, entry.store, store) and std.mem.eql(u8, entry.name, name)) {
797
+ return .{ .ok = entry.value };
798
+ }
799
+ }
800
+ }
801
+
802
+ for (entries) |entry| {
803
+ switch (try entry.provider.lookup(work, name)) {
804
+ .err => |message| return .{ .err = try self.keepraw(message) },
805
+ .ok => |found| {
806
+ const value = found orelse continue;
807
+
808
+ // `seen` owns every resolved value; the cache points at
809
+ // the same bytes, so nothing is stored twice or freed
810
+ // twice.
811
+ const kept = try self.alloc.dupe(u8, value);
812
+ try self.seen.append(self.alloc, kept);
813
+
814
+ if (self.docache) {
815
+ // Keyed by the store the CALLER named - the empty
816
+ // string for a transparent `get` - not by whichever
817
+ // provider answered. A transparent read and a
818
+ // directed one are different questions, and a cache
819
+ // keyed by the answering provider would never
820
+ // satisfy the first of them.
821
+ try self.cache.append(self.alloc, .{
822
+ .store = try self.alloc.dupe(u8, store),
823
+ .name = try self.alloc.dupe(u8, name),
824
+ .value = kept,
825
+ });
826
+ }
827
+
828
+ return .{ .ok = kept };
829
+ },
830
+ }
831
+ }
832
+
833
+ return .{ .ok = null };
834
+ }
835
+
836
+ /// Does any provider have this secret?
837
+ pub fn has(self: *Sekreto, name: Name) Allocator.Error!Answer(bool) {
838
+ switch (try self.trysecret(name)) {
839
+ .err => |message| return .{ .err = message },
840
+ .ok => |found| return .{ .ok = null != found },
841
+ }
842
+ }
843
+
844
+ /// Does this named store have this secret?
845
+ pub fn hasin(self: *Sekreto, store: []const u8, name: Name) Allocator.Error!Answer(bool) {
846
+ switch (try self.tryfrom(store, name)) {
847
+ .err => |message| return .{ .err = message },
848
+ .ok => |found| return .{ .ok = null != found },
849
+ }
850
+ }
851
+
852
+ /// Every named secret at once. Missing ones are a failure.
853
+ ///
854
+ /// The values are the Sekreto's own; the returned list comes from
855
+ /// `alloc`.
856
+ pub fn all(
857
+ self: *Sekreto,
858
+ alloc: Allocator,
859
+ names: []const Name,
860
+ ) Allocator.Error!Answer([]const []const u8) {
861
+ var out: std.ArrayList([]const u8) = .empty;
862
+
863
+ for (names) |name| {
864
+ switch (try self.get(name)) {
865
+ .err => |message| return .{ .err = message },
866
+ .ok => |value| try out.append(alloc, value),
867
+ }
868
+ }
869
+
870
+ return .{ .ok = out.items };
871
+ }
872
+
873
+ /// A description of each provider, in resolution order.
874
+ pub fn sources(self: *const Sekreto, alloc: Allocator) Allocator.Error![]const []const u8 {
875
+ var out: std.ArrayList([]const u8) = .empty;
876
+
877
+ for (self.entries) |entry| {
878
+ try out.append(alloc, try entry.provider.describe(alloc));
879
+ }
880
+
881
+ return out.items;
882
+ }
883
+
884
+ /// The name of each store that can be named by `getfrom`, in resolution
885
+ /// order and without repeats.
886
+ pub fn stores(self: *const Sekreto, alloc: Allocator) Allocator.Error![]const []const u8 {
887
+ var out: std.ArrayList([]const u8) = .empty;
888
+
889
+ for (self.entries) |entry| {
890
+ var seen = false;
891
+ for (out.items) |candidate| {
892
+ if (std.mem.eql(u8, candidate, entry.store)) {
893
+ seen = true;
894
+ break;
895
+ }
896
+ }
897
+ if (!seen) {
898
+ try out.append(alloc, entry.store);
899
+ }
900
+ }
901
+
902
+ return out.items;
903
+ }
904
+
905
+ /// Replace every value this Sekreto has resolved with `[redacted]`.
906
+ ///
907
+ /// Works whether or not caching is enabled: the redaction list is kept
908
+ /// independently of the read cache.
909
+ pub fn redactText(
910
+ self: *const Sekreto,
911
+ alloc: Allocator,
912
+ text: []const u8,
913
+ ) Allocator.Error![]const u8 {
914
+ return redact(alloc, text, self.seen.items);
915
+ }
916
+
917
+ /// Drop cached values, so the next `get` asks the providers again.
918
+ pub fn refresh(self: *Sekreto) void {
919
+ for (self.cache.items) |entry| {
920
+ self.alloc.free(entry.store);
921
+ self.alloc.free(entry.name);
922
+ }
923
+ self.cache.clearRetainingCapacity();
924
+ }
925
+
926
+ // One failure message, owned by the Sekreto so that a caller never has
927
+ // to free it and a retry loop cannot pile them up.
928
+ fn keep(self: *Sekreto, comptime format: []const u8, args: anytype) Allocator.Error![]const u8 {
929
+ if (self.lasterr) |old| {
930
+ self.alloc.free(old);
931
+ self.lasterr = null;
932
+ }
933
+
934
+ const message = try std.fmt.allocPrint(self.alloc, format, args);
935
+ self.lasterr = message;
936
+ return message;
937
+ }
938
+
939
+ // The same, for a message built in the scratch arena: it must be copied
940
+ // out before the arena is reset.
941
+ fn keepraw(self: *Sekreto, message: []const u8) Allocator.Error![]const u8 {
942
+ return self.keep("{s}", .{message});
943
+ }
944
+ };