@voxgig/sdkgen 4.32.1 → 4.34.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 (442) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/dist/action/copies.d.ts +21 -0
  3. package/dist/action/copies.js +146 -0
  4. package/dist/action/copies.js.map +1 -0
  5. package/dist/action/doctor.d.ts +15 -2
  6. package/dist/action/doctor.js +169 -23
  7. package/dist/action/doctor.js.map +1 -1
  8. package/dist/action/edition.js +6 -2
  9. package/dist/action/edition.js.map +1 -1
  10. package/dist/action/feature.js +6 -2
  11. package/dist/action/feature.js.map +1 -1
  12. package/dist/action/package.js +28 -10
  13. package/dist/action/package.js.map +1 -1
  14. package/dist/action/remove.js +2 -0
  15. package/dist/action/remove.js.map +1 -1
  16. package/dist/action/resolve.d.ts +1 -0
  17. package/dist/action/resolve.js +10 -2
  18. package/dist/action/resolve.js.map +1 -1
  19. package/dist/action/target.js +6 -2
  20. package/dist/action/target.js.map +1 -1
  21. package/dist/helpers/naming.js +1 -1
  22. package/dist/helpers/naming.js.map +1 -1
  23. package/dist/sdkgen.d.ts +2 -1
  24. package/dist/sdkgen.js +36 -3
  25. package/dist/sdkgen.js.map +1 -1
  26. package/dist/tsconfig.tsbuildinfo +1 -1
  27. package/model/sdkgen.aontu +7 -1
  28. package/package.json +1 -1
  29. package/project/.sdk/model/feature/debug.aontu +3 -1
  30. package/project/.sdk/src/cmp/c/PrepareAuth_c.ts +8 -28
  31. package/project/.sdk/src/cmp/c/TestClean_c.ts +774 -0
  32. package/project/.sdk/src/cmp/c/Test_c.ts +3 -0
  33. package/project/.sdk/src/cmp/c/fragment/Entity.fragment.c +16 -5
  34. package/project/.sdk/src/cmp/c/fragment/Main.fragment.c +1 -1
  35. package/project/.sdk/src/cmp/clojure/PrepareAuth_clojure.ts +3 -0
  36. package/project/.sdk/src/cmp/clojure/TestClean_clojure.ts +473 -0
  37. package/project/.sdk/src/cmp/clojure/Test_clojure.ts +6 -0
  38. package/project/.sdk/src/cmp/clojure/fragment/Entity.fragment.clj +18 -8
  39. package/project/.sdk/src/cmp/cpp/PrepareAuth_cpp.ts +3 -0
  40. package/project/.sdk/src/cmp/cpp/TestClean_cpp.ts +782 -0
  41. package/project/.sdk/src/cmp/cpp/TestEntity_cpp.ts +1 -1
  42. package/project/.sdk/src/cmp/cpp/Test_cpp.ts +2 -0
  43. package/project/.sdk/src/cmp/csharp/PrepareAuth_csharp.ts +3 -0
  44. package/project/.sdk/src/cmp/csharp/TestClean_csharp.ts +887 -0
  45. package/project/.sdk/src/cmp/csharp/Test_csharp.ts +2 -0
  46. package/project/.sdk/src/cmp/csharp/fragment/EntityBase.fragment.cs +68 -4
  47. package/project/.sdk/src/cmp/csharp/fragment/Main.fragment.cs +8 -2
  48. package/project/.sdk/src/cmp/csharp/fragment/SdkError.fragment.cs +49 -0
  49. package/project/.sdk/src/cmp/elixir/PrepareAuth_elixir.ts +3 -0
  50. package/project/.sdk/src/cmp/elixir/Schema_elixir.ts +20 -10
  51. package/project/.sdk/src/cmp/elixir/TestClean_elixir.ts +666 -0
  52. package/project/.sdk/src/cmp/elixir/Test_elixir.ts +4 -0
  53. package/project/.sdk/src/cmp/elixir/fragment/Main.fragment.ex +1 -1
  54. package/project/.sdk/src/cmp/elixir/fragment/Pipeline.fragment.ex +14 -2
  55. package/project/.sdk/src/cmp/go/PrepareAuth_go.ts +3 -0
  56. package/project/.sdk/src/cmp/go/TestClean_go.ts +804 -0
  57. package/project/.sdk/src/cmp/go/Test_go.ts +3 -0
  58. package/project/.sdk/src/cmp/go/fragment/Entity.fragment.go +54 -4
  59. package/project/.sdk/src/cmp/go/fragment/Main.fragment.go +27 -2
  60. package/project/.sdk/src/cmp/java/PrepareAuth_java.ts +3 -0
  61. package/project/.sdk/src/cmp/java/TestClean_java.ts +884 -0
  62. package/project/.sdk/src/cmp/java/Test_java.ts +2 -0
  63. package/project/.sdk/src/cmp/java/fragment/EntityBase.fragment.java +56 -11
  64. package/project/.sdk/src/cmp/java/fragment/SdkError.fragment.java +36 -3
  65. package/project/.sdk/src/cmp/js/PrepareAuth_js.ts +3 -0
  66. package/project/.sdk/src/cmp/js/TestClean_js.ts +458 -0
  67. package/project/.sdk/src/cmp/js/Test_js.ts +2 -0
  68. package/project/.sdk/src/cmp/js/fragment/EntityBase.fragment.js +5 -4
  69. package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +7 -1
  70. package/project/.sdk/src/cmp/js/fragment/EntityListOp.fragment.js +7 -1
  71. package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +7 -1
  72. package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +7 -1
  73. package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +7 -1
  74. package/project/.sdk/src/cmp/js/fragment/Main.fragment.js +11 -2
  75. package/project/.sdk/src/cmp/js/fragment/SdkError.fragment.js +17 -1
  76. package/project/.sdk/src/cmp/kotlin/Package_kotlin.ts +5 -0
  77. package/project/.sdk/src/cmp/kotlin/PrepareAuth_kotlin.ts +3 -0
  78. package/project/.sdk/src/cmp/kotlin/TestClean_kotlin.ts +654 -0
  79. package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +3 -0
  80. package/project/.sdk/src/cmp/kotlin/fragment/EntityBase.fragment.kt +44 -11
  81. package/project/.sdk/src/cmp/kotlin/fragment/SdkError.fragment.kt +31 -0
  82. package/project/.sdk/src/cmp/lua/PrepareAuth_lua.ts +3 -0
  83. package/project/.sdk/src/cmp/lua/TestClean_lua.ts +769 -0
  84. package/project/.sdk/src/cmp/lua/Test_lua.ts +3 -0
  85. package/project/.sdk/src/cmp/lua/fragment/Entity.fragment.lua +77 -1
  86. package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +49 -2
  87. package/project/.sdk/src/cmp/ocaml/Entity_ocaml.ts +3 -2
  88. package/project/.sdk/src/cmp/ocaml/PrepareAuth_ocaml.ts +4 -25
  89. package/project/.sdk/src/cmp/ocaml/TestClean_ocaml.ts +538 -0
  90. package/project/.sdk/src/cmp/ocaml/Test_ocaml.ts +5 -0
  91. package/project/.sdk/src/cmp/ocaml/fragment/RunOp.fragment.ml +16 -4
  92. package/project/.sdk/src/cmp/perl/PrepareAuth_perl.ts +3 -0
  93. package/project/.sdk/src/cmp/perl/TestClean_perl.ts +619 -0
  94. package/project/.sdk/src/cmp/perl/Test_perl.ts +3 -0
  95. package/project/.sdk/src/cmp/perl/fragment/Entity.fragment.pm +67 -5
  96. package/project/.sdk/src/cmp/perl/fragment/Main.fragment.pm +13 -1
  97. package/project/.sdk/src/cmp/php/PrepareAuth_php.ts +3 -0
  98. package/project/.sdk/src/cmp/php/TestClean_php.ts +809 -0
  99. package/project/.sdk/src/cmp/php/Test_php.ts +2 -0
  100. package/project/.sdk/src/cmp/php/fragment/Entity.fragment.php +96 -55
  101. package/project/.sdk/src/cmp/php/fragment/Main.fragment.php +15 -2
  102. package/project/.sdk/src/cmp/py/PrepareAuth_py.ts +3 -0
  103. package/project/.sdk/src/cmp/py/TestClean_py.ts +549 -0
  104. package/project/.sdk/src/cmp/py/Test_py.ts +3 -0
  105. package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +83 -55
  106. package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +19 -3
  107. package/project/.sdk/src/cmp/rb/PrepareAuth_rb.ts +3 -0
  108. package/project/.sdk/src/cmp/rb/TestClean_rb.ts +535 -0
  109. package/project/.sdk/src/cmp/rb/Test_rb.ts +3 -0
  110. package/project/.sdk/src/cmp/rb/fragment/Entity.fragment.rb +108 -46
  111. package/project/.sdk/src/cmp/rb/fragment/Main.fragment.rb +12 -1
  112. package/project/.sdk/src/cmp/rust/PrepareAuth_rust.ts +9 -45
  113. package/project/.sdk/src/cmp/rust/TestClean_rust.ts +881 -0
  114. package/project/.sdk/src/cmp/rust/Test_rust.ts +3 -0
  115. package/project/.sdk/src/cmp/rust/fragment/Entity.fragment.rs +14 -6
  116. package/project/.sdk/src/cmp/rust/fragment/Main.fragment.rs +17 -1
  117. package/project/.sdk/src/cmp/rust/fragment/SdkError.fragment.rs +34 -2
  118. package/project/.sdk/src/cmp/scala/PrepareAuth_scala.ts +3 -0
  119. package/project/.sdk/src/cmp/scala/TestClean_scala.ts +608 -0
  120. package/project/.sdk/src/cmp/scala/Test_scala.ts +3 -0
  121. package/project/.sdk/src/cmp/scala/fragment/EntityBase.fragment.scala +58 -6
  122. package/project/.sdk/src/cmp/swift/PrepareAuth_swift.ts +3 -0
  123. package/project/.sdk/src/cmp/swift/TestClean_swift.ts +671 -0
  124. package/project/.sdk/src/cmp/swift/Test_swift.ts +3 -0
  125. package/project/.sdk/src/cmp/swift/fragment/EntityBase.fragment.swift +10 -0
  126. package/project/.sdk/src/cmp/swift/fragment/Main.fragment.swift +16 -2
  127. package/project/.sdk/src/cmp/swift/fragment/SdkError.fragment.swift +47 -3
  128. package/project/.sdk/src/cmp/ts/PrepareAuth_ts.ts +3 -0
  129. package/project/.sdk/src/cmp/ts/TestClean_ts.ts +465 -0
  130. package/project/.sdk/src/cmp/ts/Test_ts.ts +2 -0
  131. package/project/.sdk/src/cmp/ts/fragment/EntityBase.fragment.ts +5 -4
  132. package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.ts +7 -1
  133. package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.ts +7 -1
  134. package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.ts +7 -1
  135. package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.ts +7 -1
  136. package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.ts +7 -1
  137. package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +8 -2
  138. package/project/.sdk/src/cmp/ts/fragment/SdkError.fragment.ts +20 -2
  139. package/project/.sdk/src/cmp/zig/PrepareAuth_zig.ts +3 -0
  140. package/project/.sdk/src/cmp/zig/TestClean_zig.ts +791 -0
  141. package/project/.sdk/src/cmp/zig/Test_zig.ts +5 -0
  142. package/project/.sdk/src/cmp/zig/fragment/Build.fragment.zig +19 -0
  143. package/project/.sdk/src/cmp/zig/fragment/Entity.fragment.zig +14 -5
  144. package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +1 -1
  145. package/project/.sdk/tm/c/core/context.c +25 -0
  146. package/project/.sdk/tm/c/core/error.c +16 -0
  147. package/project/.sdk/tm/c/core/sdk.h +22 -0
  148. package/project/.sdk/tm/c/feature/audit.c +2 -0
  149. package/project/.sdk/tm/c/feature/cost.c +1 -0
  150. package/project/.sdk/tm/c/feature/debug.c +19 -29
  151. package/project/.sdk/tm/c/feature/log.c +21 -2
  152. package/project/.sdk/tm/c/feature/proxy.c +55 -3
  153. package/project/.sdk/tm/c/feature/secrets.c +7 -0
  154. package/project/.sdk/tm/c/feature/telemetry.c +2 -0
  155. package/project/.sdk/tm/c/tests/feature_test.c +2 -2
  156. package/project/.sdk/tm/c/utility/clean.c +530 -8
  157. package/project/.sdk/tm/c/utility/done.c +28 -12
  158. package/project/.sdk/tm/c/utility/make_error.c +4 -3
  159. package/project/.sdk/tm/c/utility/make_options.c +71 -45
  160. package/project/.sdk/tm/clojure/feature/secrets/sdk/feature/secrets.clj +15 -0
  161. package/project/.sdk/tm/clojure/src/sdk/client.clj +20 -4
  162. package/project/.sdk/tm/clojure/src/sdk/core.clj +319 -35
  163. package/project/.sdk/tm/clojure/src/sdk/features.clj +68 -30
  164. package/project/.sdk/tm/clojure/test/sdk/test/feature.clj +4 -2
  165. package/project/.sdk/tm/clojure/test/sdk/test/pipeline.clj +47 -20
  166. package/project/.sdk/tm/clojure/test/sdk/test_runner.clj +4 -0
  167. package/project/.sdk/tm/cpp/core/types.hpp +93 -3
  168. package/project/.sdk/tm/cpp/feature/audit.hpp +1 -0
  169. package/project/.sdk/tm/cpp/feature/cost.hpp +1 -0
  170. package/project/.sdk/tm/cpp/feature/debug.hpp +20 -12
  171. package/project/.sdk/tm/cpp/feature/log.hpp +31 -9
  172. package/project/.sdk/tm/cpp/feature/proxy.hpp +52 -6
  173. package/project/.sdk/tm/cpp/feature/secrets.hpp +13 -0
  174. package/project/.sdk/tm/cpp/feature/telemetry.hpp +4 -2
  175. package/project/.sdk/tm/cpp/test/feature_test.cpp +2 -2
  176. package/project/.sdk/tm/cpp/utility/pipeline.hpp +426 -51
  177. package/project/.sdk/tm/csharp/core/Context.cs +32 -0
  178. package/project/.sdk/tm/csharp/core/Utility.cs +2 -0
  179. package/project/.sdk/tm/csharp/feature/AuditFeature.cs +1 -0
  180. package/project/.sdk/tm/csharp/feature/CostFeature.cs +7 -5
  181. package/project/.sdk/tm/csharp/feature/DebugFeature.cs +19 -16
  182. package/project/.sdk/tm/csharp/feature/FeatureOptions.cs +16 -0
  183. package/project/.sdk/tm/csharp/feature/LogFeature.cs +4 -1
  184. package/project/.sdk/tm/csharp/feature/ProxyFeature.cs +26 -5
  185. package/project/.sdk/tm/csharp/feature/SecretsFeature.cs +16 -0
  186. package/project/.sdk/tm/csharp/feature/TelemetryFeature.cs +4 -2
  187. package/project/.sdk/tm/csharp/test/FeatureTest.cs +2 -2
  188. package/project/.sdk/tm/csharp/utility/Clean.cs +440 -2
  189. package/project/.sdk/tm/csharp/utility/Done.cs +27 -11
  190. package/project/.sdk/tm/csharp/utility/MakeError.cs +19 -8
  191. package/project/.sdk/tm/csharp/utility/MakeOptions.cs +119 -29
  192. package/project/.sdk/tm/csharp/utility/MakeResponse.cs +21 -11
  193. package/project/.sdk/tm/csharp/utility/Register.cs +1 -0
  194. package/project/.sdk/tm/elixir/lib/projectname/context.ex +19 -0
  195. package/project/.sdk/tm/elixir/lib/projectname/entity_base.ex +22 -1
  196. package/project/.sdk/tm/elixir/lib/projectname/error.ex +24 -0
  197. package/project/.sdk/tm/elixir/lib/projectname/feature/audit.ex +2 -2
  198. package/project/.sdk/tm/elixir/lib/projectname/feature/cost.ex +2 -2
  199. package/project/.sdk/tm/elixir/lib/projectname/feature/debug.ex +13 -13
  200. package/project/.sdk/tm/elixir/lib/projectname/feature/log.ex +18 -5
  201. package/project/.sdk/tm/elixir/lib/projectname/feature/proxy.ex +19 -1
  202. package/project/.sdk/tm/elixir/lib/projectname/feature/secrets.ex +15 -0
  203. package/project/.sdk/tm/elixir/lib/projectname/feature/telemetry.ex +4 -2
  204. package/project/.sdk/tm/elixir/lib/projectname/feature.ex +22 -0
  205. package/project/.sdk/tm/elixir/lib/projectname/utility.ex +464 -41
  206. package/project/.sdk/tm/elixir/test/feature_test.exs +3 -2
  207. package/project/.sdk/tm/go/core/context.go +42 -0
  208. package/project/.sdk/tm/go/core/error.go +30 -10
  209. package/project/.sdk/tm/go/core/utility_type.go +2 -0
  210. package/project/.sdk/tm/go/feature/audit_feature.go +1 -0
  211. package/project/.sdk/tm/go/feature/base_feature.go +12 -0
  212. package/project/.sdk/tm/go/feature/cost_feature.go +2 -2
  213. package/project/.sdk/tm/go/feature/debug_feature.go +14 -12
  214. package/project/.sdk/tm/go/feature/log_feature.go +13 -8
  215. package/project/.sdk/tm/go/feature/proxy_feature.go +26 -6
  216. package/project/.sdk/tm/go/feature/secrets_feature.go +19 -0
  217. package/project/.sdk/tm/go/feature/telemetry_feature.go +4 -2
  218. package/project/.sdk/tm/go/test/feature_test.go +2 -2
  219. package/project/.sdk/tm/go/utility/clean.go +585 -2
  220. package/project/.sdk/tm/go/utility/done.go +29 -9
  221. package/project/.sdk/tm/go/utility/make_error.go +51 -16
  222. package/project/.sdk/tm/go/utility/make_options.go +77 -36
  223. package/project/.sdk/tm/go/utility/register.go +12 -0
  224. package/project/.sdk/tm/java/core/Context.java +29 -0
  225. package/project/.sdk/tm/java/core/SdkClient.java +4 -2
  226. package/project/.sdk/tm/java/core/Utility.java +7 -0
  227. package/project/.sdk/tm/java/feature/AuditFeature.java +6 -0
  228. package/project/.sdk/tm/java/feature/CostFeature.java +5 -0
  229. package/project/.sdk/tm/java/feature/DebugFeature.java +25 -14
  230. package/project/.sdk/tm/java/feature/LogFeature.java +11 -4
  231. package/project/.sdk/tm/java/feature/ProxyFeature.java +41 -6
  232. package/project/.sdk/tm/java/feature/SecretsFeature.java +18 -0
  233. package/project/.sdk/tm/java/feature/TelemetryFeature.java +8 -2
  234. package/project/.sdk/tm/java/test/FeatureTest.java +2 -2
  235. package/project/.sdk/tm/java/utility/Clean.java +519 -1
  236. package/project/.sdk/tm/java/utility/Done.java +1 -1
  237. package/project/.sdk/tm/java/utility/MakeError.java +5 -1
  238. package/project/.sdk/tm/java/utility/MakeOptions.java +55 -31
  239. package/project/.sdk/tm/java/utility/Register.java +4 -0
  240. package/project/.sdk/tm/js/src/Context.js +5 -1
  241. package/project/.sdk/tm/js/src/feature/audit/AuditFeature.js +2 -2
  242. package/project/.sdk/tm/js/src/feature/cost/CostFeature.js +2 -2
  243. package/project/.sdk/tm/js/src/feature/debug/DebugFeature.js +13 -7
  244. package/project/.sdk/tm/js/src/feature/log/LogFeature.js +9 -5
  245. package/project/.sdk/tm/js/src/feature/proxy/ProxyFeature.js +19 -1
  246. package/project/.sdk/tm/js/src/feature/secrets/SecretsFeature.js +14 -0
  247. package/project/.sdk/tm/js/src/feature/telemetry/TelemetryFeature.js +4 -2
  248. package/project/.sdk/tm/js/src/utility/CleanUtility.js +294 -21
  249. package/project/.sdk/tm/js/src/utility/DoneUtility.js +17 -5
  250. package/project/.sdk/tm/js/src/utility/MakeErrorUtility.js +18 -2
  251. package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +39 -15
  252. package/project/.sdk/tm/js/src/utility/Utility.js +4 -2
  253. package/project/.sdk/tm/js/test/feature/harness.js +11 -1
  254. package/project/.sdk/tm/js/test/feature.test.js +9 -2
  255. package/project/.sdk/tm/kotlin/core/Context.kt +19 -0
  256. package/project/.sdk/tm/kotlin/core/SdkClient.kt +9 -2
  257. package/project/.sdk/tm/kotlin/core/Utility.kt +2 -0
  258. package/project/.sdk/tm/kotlin/feature/AuditFeature.kt +11 -9
  259. package/project/.sdk/tm/kotlin/feature/CostFeature.kt +8 -5
  260. package/project/.sdk/tm/kotlin/feature/DebugFeature.kt +15 -22
  261. package/project/.sdk/tm/kotlin/feature/LogFeature.kt +8 -4
  262. package/project/.sdk/tm/kotlin/feature/ProxyFeature.kt +26 -2
  263. package/project/.sdk/tm/kotlin/feature/SecretsFeature.kt +11 -0
  264. package/project/.sdk/tm/kotlin/feature/TelemetryFeature.kt +4 -2
  265. package/project/.sdk/tm/kotlin/test/FeatureTest.kt +2 -2
  266. package/project/.sdk/tm/kotlin/utility/CoreUtil.kt +447 -11
  267. package/project/.sdk/tm/kotlin/utility/MakeOptions.kt +38 -31
  268. package/project/.sdk/tm/kotlin/utility/Register.kt +1 -0
  269. package/project/.sdk/tm/lua/core/context.lua +43 -0
  270. package/project/.sdk/tm/lua/core/error.lua +36 -1
  271. package/project/.sdk/tm/lua/core/utility_type.lua +4 -0
  272. package/project/.sdk/tm/lua/feature/audit_feature.lua +2 -2
  273. package/project/.sdk/tm/lua/feature/cost_feature.lua +2 -2
  274. package/project/.sdk/tm/lua/feature/debug_feature.lua +21 -17
  275. package/project/.sdk/tm/lua/feature/log_feature.lua +2 -1
  276. package/project/.sdk/tm/lua/feature/proxy_feature.lua +23 -1
  277. package/project/.sdk/tm/lua/feature/secrets_feature.lua +18 -0
  278. package/project/.sdk/tm/lua/feature/telemetry_feature.lua +4 -2
  279. package/project/.sdk/tm/lua/test/feature/secrets/secrets_feature_test.lua +3 -2
  280. package/project/.sdk/tm/lua/test/feature_test.lua +10 -3
  281. package/project/.sdk/tm/lua/utility/clean.lua +426 -2
  282. package/project/.sdk/tm/lua/utility/clean_explain.lua +34 -0
  283. package/project/.sdk/tm/lua/utility/done.lua +1 -7
  284. package/project/.sdk/tm/lua/utility/make_error.lua +3 -1
  285. package/project/.sdk/tm/lua/utility/make_options.lua +76 -30
  286. package/project/.sdk/tm/lua/utility/register.lua +4 -1
  287. package/project/.sdk/tm/ocaml/Makefile +5 -1
  288. package/project/.sdk/tm/ocaml/feature/secrets_feature.ml +12 -1
  289. package/project/.sdk/tm/ocaml/sdk_features.ml +78 -18
  290. package/project/.sdk/tm/ocaml/sdk_helpers.ml +27 -0
  291. package/project/.sdk/tm/ocaml/sdk_runtime.ml +304 -26
  292. package/project/.sdk/tm/ocaml/sdk_types.ml +1 -0
  293. package/project/.sdk/tm/ocaml/test/feature/secrets/t_secrets.ml +3 -1
  294. package/project/.sdk/tm/ocaml/test/t_feature.ml +2 -2
  295. package/project/.sdk/tm/perl/core/context.pm +27 -0
  296. package/project/.sdk/tm/perl/core/error.pm +52 -5
  297. package/project/.sdk/tm/perl/feature/audit_feature.pm +2 -2
  298. package/project/.sdk/tm/perl/feature/cost_feature.pm +2 -2
  299. package/project/.sdk/tm/perl/feature/debug_feature.pm +17 -13
  300. package/project/.sdk/tm/perl/feature/log_feature.pm +3 -1
  301. package/project/.sdk/tm/perl/feature/proxy_feature.pm +21 -1
  302. package/project/.sdk/tm/perl/feature/secrets_feature.pm +20 -1
  303. package/project/.sdk/tm/perl/feature/telemetry_feature.pm +4 -2
  304. package/project/.sdk/tm/perl/t/feature.t +4 -2
  305. package/project/.sdk/tm/perl/utility/clean.pm +345 -1
  306. package/project/.sdk/tm/perl/utility/done.pm +24 -6
  307. package/project/.sdk/tm/perl/utility/make_error.pm +17 -4
  308. package/project/.sdk/tm/perl/utility/make_options.pm +33 -14
  309. package/project/.sdk/tm/php/core/Context.php +24 -1
  310. package/project/.sdk/tm/php/core/Error.php +34 -3
  311. package/project/.sdk/tm/php/core/UtilityType.php +4 -0
  312. package/project/.sdk/tm/php/feature/AuditFeature.php +2 -2
  313. package/project/.sdk/tm/php/feature/CostFeature.php +2 -2
  314. package/project/.sdk/tm/php/feature/DebugFeature.php +18 -9
  315. package/project/.sdk/tm/php/feature/LogFeature.php +5 -2
  316. package/project/.sdk/tm/php/feature/ProxyFeature.php +20 -1
  317. package/project/.sdk/tm/php/feature/SecretsFeature.php +18 -0
  318. package/project/.sdk/tm/php/feature/TelemetryFeature.php +4 -2
  319. package/project/.sdk/tm/php/test/FeatureTest.php +2 -2
  320. package/project/.sdk/tm/php/utility/Clean.php +438 -2
  321. package/project/.sdk/tm/php/utility/Done.php +14 -7
  322. package/project/.sdk/tm/php/utility/MakeError.php +9 -7
  323. package/project/.sdk/tm/php/utility/MakeOptions.php +62 -38
  324. package/project/.sdk/tm/php/utility/Register.php +2 -0
  325. package/project/.sdk/tm/py/pkg/core/context.py +17 -0
  326. package/project/.sdk/tm/py/pkg/core/error.py +42 -1
  327. package/project/.sdk/tm/py/pkg/core/utility_type.py +4 -0
  328. package/project/.sdk/tm/py/pkg/feature/audit_feature.py +2 -2
  329. package/project/.sdk/tm/py/pkg/feature/cost_feature.py +2 -2
  330. package/project/.sdk/tm/py/pkg/feature/debug_feature.py +17 -12
  331. package/project/.sdk/tm/py/pkg/feature/log_feature.py +2 -1
  332. package/project/.sdk/tm/py/pkg/feature/proxy_feature.py +18 -1
  333. package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +12 -0
  334. package/project/.sdk/tm/py/pkg/feature/telemetry_feature.py +4 -2
  335. package/project/.sdk/tm/py/pkg/utility/clean.py +311 -1
  336. package/project/.sdk/tm/py/pkg/utility/done.py +18 -5
  337. package/project/.sdk/tm/py/pkg/utility/make_error.py +9 -6
  338. package/project/.sdk/tm/py/pkg/utility/make_options.py +64 -25
  339. package/project/.sdk/tm/py/pkg/utility/make_response.py +19 -13
  340. package/project/.sdk/tm/py/pkg/utility/register.py +4 -2
  341. package/project/.sdk/tm/py/test/feature_harness.py +4 -0
  342. package/project/.sdk/tm/py/test/test_feature.py +2 -2
  343. package/project/.sdk/tm/py/test/test_primary_utility.py +1 -0
  344. package/project/.sdk/tm/rb/core/context.rb +28 -0
  345. package/project/.sdk/tm/rb/core/error.rb +30 -0
  346. package/project/.sdk/tm/rb/core/utility_type.rb +1 -1
  347. package/project/.sdk/tm/rb/feature/audit_feature.rb +2 -2
  348. package/project/.sdk/tm/rb/feature/cost_feature.rb +2 -2
  349. package/project/.sdk/tm/rb/feature/debug_feature.rb +15 -12
  350. package/project/.sdk/tm/rb/feature/log_feature.rb +3 -1
  351. package/project/.sdk/tm/rb/feature/proxy_feature.rb +25 -1
  352. package/project/.sdk/tm/rb/feature/secrets_feature.rb +17 -0
  353. package/project/.sdk/tm/rb/feature/telemetry_feature.rb +4 -2
  354. package/project/.sdk/tm/rb/test/feature_test.rb +4 -2
  355. package/project/.sdk/tm/rb/utility/clean.rb +312 -1
  356. package/project/.sdk/tm/rb/utility/done.rb +15 -5
  357. package/project/.sdk/tm/rb/utility/make_error.rb +13 -4
  358. package/project/.sdk/tm/rb/utility/make_options.rb +31 -12
  359. package/project/.sdk/tm/rb/utility/register.rb +2 -0
  360. package/project/.sdk/tm/rust/core/context.rs +55 -0
  361. package/project/.sdk/tm/rust/core/utility_type.rs +17 -0
  362. package/project/.sdk/tm/rust/feature/audit.rs +2 -0
  363. package/project/.sdk/tm/rust/feature/cost.rs +3 -2
  364. package/project/.sdk/tm/rust/feature/debug.rs +16 -16
  365. package/project/.sdk/tm/rust/feature/log.rs +42 -7
  366. package/project/.sdk/tm/rust/feature/proxy.rs +48 -2
  367. package/project/.sdk/tm/rust/feature/secrets.rs +12 -0
  368. package/project/.sdk/tm/rust/feature/telemetry.rs +2 -0
  369. package/project/.sdk/tm/rust/tests/feature_test.rs +2 -2
  370. package/project/.sdk/tm/rust/utility/clean.rs +446 -5
  371. package/project/.sdk/tm/rust/utility/done.rs +22 -12
  372. package/project/.sdk/tm/rust/utility/make_error.rs +4 -1
  373. package/project/.sdk/tm/rust/utility/make_options.rs +73 -19
  374. package/project/.sdk/tm/scala/Makefile +3 -1
  375. package/project/.sdk/tm/scala/core/Context.scala +16 -0
  376. package/project/.sdk/tm/scala/core/SdkClient.scala +14 -4
  377. package/project/.sdk/tm/scala/core/SdkError.scala +28 -0
  378. package/project/.sdk/tm/scala/core/Types.scala +3 -0
  379. package/project/.sdk/tm/scala/core/Utility.scala +2 -0
  380. package/project/.sdk/tm/scala/feature/AuditFeature.scala +16 -10
  381. package/project/.sdk/tm/scala/feature/CostFeature.scala +10 -5
  382. package/project/.sdk/tm/scala/feature/DebugFeature.scala +24 -21
  383. package/project/.sdk/tm/scala/feature/LogFeature.scala +9 -4
  384. package/project/.sdk/tm/scala/feature/ProxyFeature.scala +23 -2
  385. package/project/.sdk/tm/scala/feature/SecretsFeature.scala +14 -0
  386. package/project/.sdk/tm/scala/feature/TelemetryFeature.scala +9 -2
  387. package/project/.sdk/tm/scala/sdktest/SdkTestMain.scala +2 -2
  388. package/project/.sdk/tm/scala/utility/Make.scala +63 -20
  389. package/project/.sdk/tm/scala/utility/Misc.scala +358 -5
  390. package/project/.sdk/tm/scala/utility/Register.scala +1 -0
  391. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Context.swift +29 -0
  392. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Utility.swift +2 -0
  393. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/AuditFeature.swift +10 -9
  394. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/CostFeature.swift +7 -5
  395. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/DebugFeature.swift +19 -15
  396. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/FeatureOptions.swift +16 -0
  397. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/LogFeature.swift +4 -1
  398. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/ProxyFeature.swift +20 -5
  399. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/SecretsFeature.swift +13 -0
  400. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/TelemetryFeature.swift +4 -2
  401. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeError.swift +15 -5
  402. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +58 -19
  403. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Register.swift +1 -0
  404. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/ResultUtil.swift +391 -4
  405. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/FeatureTest.swift +2 -2
  406. package/project/.sdk/tm/ts/src/Context.ts +5 -1
  407. package/project/.sdk/tm/ts/src/feature/audit/AuditFeature.ts +2 -2
  408. package/project/.sdk/tm/ts/src/feature/cost/CostFeature.ts +2 -2
  409. package/project/.sdk/tm/ts/src/feature/debug/DebugFeature.ts +13 -7
  410. package/project/.sdk/tm/ts/src/feature/log/LogFeature.ts +9 -5
  411. package/project/.sdk/tm/ts/src/feature/proxy/ProxyFeature.ts +19 -1
  412. package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +12 -0
  413. package/project/.sdk/tm/ts/src/feature/telemetry/TelemetryFeature.ts +4 -2
  414. package/project/.sdk/tm/ts/src/utility/CleanUtility.ts +287 -9
  415. package/project/.sdk/tm/ts/src/utility/DoneUtility.ts +18 -5
  416. package/project/.sdk/tm/ts/src/utility/MakeErrorUtility.ts +18 -8
  417. package/project/.sdk/tm/ts/src/utility/MakeOptionsUtility.ts +38 -16
  418. package/project/.sdk/tm/ts/src/utility/Utility.ts +4 -2
  419. package/project/.sdk/tm/ts/test/feature/harness.ts +11 -1
  420. package/project/.sdk/tm/ts/test/feature.test.ts +9 -2
  421. package/project/.sdk/tm/zig/core/context.zig +34 -0
  422. package/project/.sdk/tm/zig/core/error.zig +22 -1
  423. package/project/.sdk/tm/zig/core/utility.zig +403 -39
  424. package/project/.sdk/tm/zig/feature/audit.zig +4 -2
  425. package/project/.sdk/tm/zig/feature/cost.zig +3 -2
  426. package/project/.sdk/tm/zig/feature/debug.zig +20 -25
  427. package/project/.sdk/tm/zig/feature/log.zig +3 -1
  428. package/project/.sdk/tm/zig/feature/proxy.zig +47 -6
  429. package/project/.sdk/tm/zig/feature/secrets.zig +7 -0
  430. package/project/.sdk/tm/zig/feature/telemetry.zig +4 -2
  431. package/project/.sdk/tm/zig/test/feature_test.zig +2 -2
  432. package/project/sdkgen-package.json +1 -1
  433. package/src/action/copies.ts +219 -0
  434. package/src/action/doctor.ts +247 -21
  435. package/src/action/edition.ts +10 -2
  436. package/src/action/feature.ts +11 -2
  437. package/src/action/package.ts +31 -10
  438. package/src/action/remove.ts +4 -0
  439. package/src/action/resolve.ts +16 -3
  440. package/src/action/target.ts +10 -2
  441. package/src/helpers/naming.ts +1 -1
  442. package/src/sdkgen.ts +45 -5
@@ -1,4 +1,315 @@
1
1
  # ProjectName SDK utility: clean
2
+ require 'json'
3
+ require 'set'
4
+ require_relative '../schema'
5
+ require_relative '../core/error'
6
+ require_relative 'struct/voxgig_struct'
7
+
2
8
  module ProjectNameUtilities
3
- Clean = ->(ctx, val) { val }
9
+ # Everything that leaves the pipeline passes through clean: the error, the
10
+ # explain record, the serialised context, and whatever a feature emits.
11
+ # Two layers: every registered secret VALUE (and its encoded forms) is
12
+ # replaced wherever it appears in a string, and every value under a
13
+ # sensitive KEY name is masked whatever it holds. Inside the pipeline data
14
+ # stays raw, so a hook can still read the header it must add to.
15
+ module CleanSupport
16
+ MAXDEPTH = 32
17
+ CIRCULAR = "[circular]"
18
+
19
+ # Marks a value the copy must omit (a Proc), as ts omits `undefined`.
20
+ DROP = Object.new.freeze
21
+
22
+ def self.normkey(key)
23
+ key.to_s.downcase.gsub(/[-_]/, "")
24
+ end
25
+
26
+ def self.splitkeys(keys)
27
+ (keys.nil? ? "" : keys.to_s).split(/\s*,\s*/).map { |k| normkey(k) }.reject(&:empty?)
28
+ end
29
+
30
+ # The comma-separated literal values a caller registers; a list is taken
31
+ # as-is for a caller that has one.
32
+ def self.splitvalues(values)
33
+ return values.select { |v| v.is_a?(String) } if values.is_a?(Array)
34
+ (values.nil? ? "" : values.to_s).split(/\s*,\s*/).reject(&:empty?)
35
+ end
36
+
37
+ # The spec carries numbers as strings, so every target reads it alike.
38
+ def self.count(val, dflt)
39
+ n = Float(val.to_s, exception: false)
40
+ n.nil? || n.nan? || n.infinite? || n < 0 ? dflt : n.floor
41
+ end
42
+
43
+ # The derived block make_options builds; a context without options
44
+ # (make_error is reached with a bare one) falls back to the schema
45
+ # defaults, so nothing leaves raw for want of a constructor. A Hash
46
+ # stands in for a context before one exists (make_options).
47
+ def self.config(ctx)
48
+ opts = ctx.respond_to?(:options) ? ctx.options : (ctx.is_a?(Hash) ? ctx["options"] : nil)
49
+ derived = opts.is_a?(Hash) ? VoxgigStruct.getpath(opts, "__derived__.clean") : nil
50
+ return derived if derived.is_a?(Hash)
51
+ make_config(ProjectNameSchema::OPTSPEC["clean"])
52
+ end
53
+
54
+ def self.make_config(cleanopts)
55
+ opts = cleanopts.is_a?(Hash) ? cleanopts : {}
56
+ {
57
+ "active" => opts["active"] != false,
58
+ "keys" => splitkeys(opts["keys"]),
59
+ "values" => [],
60
+ "mask" => opts["mask"].is_a?(String) ? opts["mask"] : "[redacted]",
61
+ "hint" => count(opts["hint"], 0),
62
+ "min" => [1, count(opts["min"], 4)].max,
63
+ }
64
+ end
65
+
66
+ # encodeURIComponent, byte for byte: the form a query credential travels in.
67
+ def self.pct(value)
68
+ value.gsub(/[^A-Za-z0-9\-_.!~*'()]/) { |c| c.bytes.map { |b| format("%%%02X", b) }.join }
69
+ end
70
+
71
+ # The encoded forms a value travels in: Basic and Bearer both carry
72
+ # base64, a query credential is percent-encoded, and a JSON dump escapes it.
73
+ def self.forms(value)
74
+ out = [value]
75
+ add = ->(s) { out << s unless s.empty? || out.include?(s) }
76
+ add.call([value].pack("m0"))
77
+ add.call(pct(value))
78
+ begin
79
+ add.call(JSON.generate(value)[1..-2])
80
+ rescue StandardError
81
+ nil
82
+ end
83
+ out
84
+ end
85
+
86
+ # Register a secret value. Idempotent; shorter than `min` is not a secret
87
+ # the SDK can mask without blanking ordinary text.
88
+ def self.add(ctx, value)
89
+ cfg = config(ctx)
90
+ return unless value.is_a?(String) && value.length >= cfg["min"]
91
+ values = cfg["values"]
92
+ changed = false
93
+ forms(value).each do |form|
94
+ next if form.length < cfg["min"] || values.include?(form)
95
+ values << form
96
+ changed = true
97
+ end
98
+ values.sort_by! { |v| -v.length } if changed
99
+ nil
100
+ end
101
+
102
+ def self.mask_value(cfg, value)
103
+ hint = cfg["hint"]
104
+ return cfg["mask"] + value[-hint..] if hint > 0 && value.length > 2 * hint
105
+ cfg["mask"]
106
+ end
107
+
108
+ def self.clean_string(cfg, text)
109
+ out = text
110
+ cfg["values"].each do |value|
111
+ next unless out.include?(value)
112
+ masked = mask_value(cfg, value)
113
+ out = out.gsub(value) { masked }
114
+ end
115
+ out
116
+ end
117
+
118
+ def self.sensitive_key?(cfg, key)
119
+ return false if key.nil? || key.is_a?(Integer)
120
+ nk = normkey(key)
121
+ cfg["keys"].any? { |k| nk.include?(k) }
122
+ end
123
+
124
+ # A plain-data copy of what is about to leave: `to_h` is honoured (an
125
+ # entity gives its data, a context its record), procs are dropped,
126
+ # cycles are cut, and no live object is shared with the copy - masking
127
+ # the copy must never mask the pipeline's own spec. An object without a
128
+ # `to_h` copies as its instance variables, an exception as its message
129
+ # and fields; its `ctx` is the one field never copied, as the context
130
+ # holds the error that holds the context.
131
+ def self.snapshot(cfg, val, key, depth, seen)
132
+ return val if val.nil?
133
+
134
+ if val.is_a?(String)
135
+ return sensitive_key?(cfg, key) ? mask_value(cfg, val) : clean_string(cfg, val)
136
+ end
137
+
138
+ return DROP if val.is_a?(Proc) || val.is_a?(Method)
139
+
140
+ if val.is_a?(Numeric) || val == true || val == false || val.is_a?(Symbol)
141
+ return sensitive_key?(cfg, key) ? cfg["mask"] : val
142
+ end
143
+
144
+ return CIRCULAR if depth >= MAXDEPTH || seen.any? { |s| s.equal?(val) }
145
+
146
+ return cfg["mask"] if sensitive_key?(cfg, key)
147
+
148
+ seen.push(val)
149
+ begin
150
+ if val.is_a?(Array)
151
+ out = []
152
+ val.each_with_index do |item, i|
153
+ v = snapshot(cfg, item, i, depth + 1, seen)
154
+ out << v unless v.equal?(DROP)
155
+ end
156
+ return out
157
+ end
158
+
159
+ return plain(cfg, val, depth, seen) if val.is_a?(Hash)
160
+
161
+ if val.is_a?(Exception)
162
+ out = { "message" => clean_string(cfg, val.message.to_s) }
163
+ val.instance_variables.each do |ivar|
164
+ name = ivar.to_s.delete_prefix("@")
165
+ next if name == "ctx"
166
+ v = snapshot(cfg, val.instance_variable_get(ivar), name, depth + 1, seen)
167
+ out[clean_name(cfg, out, name)] = v unless v.equal?(DROP)
168
+ end
169
+ return out
170
+ end
171
+
172
+ if val.is_a?(Struct) || (val.respond_to?(:to_h) && !val.is_a?(Enumerable))
173
+ begin
174
+ return snapshot(cfg, val.to_h, key, depth + 1, seen)
175
+ rescue StandardError
176
+ nil
177
+ end
178
+ end
179
+
180
+ return snapshot(cfg, val.to_a, key, depth + 1, seen) if val.is_a?(Set)
181
+
182
+ ivars(cfg, val, depth, seen)
183
+ ensure
184
+ seen.pop
185
+ end
186
+ end
187
+
188
+ def self.plain(cfg, val, depth, seen)
189
+ out = {}
190
+ val.each do |k, v|
191
+ c = snapshot(cfg, v, k, depth + 1, seen)
192
+ out[clean_name(cfg, out, k)] = c unless c.equal?(DROP)
193
+ end
194
+ out
195
+ end
196
+
197
+ def self.ivars(cfg, val, depth, seen)
198
+ out = {}
199
+ val.instance_variables.each do |ivar|
200
+ name = ivar.to_s.delete_prefix("@")
201
+ c = snapshot(cfg, val.instance_variable_get(ivar), name, depth + 1, seen)
202
+ out[clean_name(cfg, out, name)] = c unless c.equal?(DROP)
203
+ end
204
+ out
205
+ end
206
+
207
+ # A registered value used as a property name is masked like any other
208
+ # string; names that mask alike take a counter, so none is lost.
209
+ def self.clean_name(cfg, out, key)
210
+ return key unless key.is_a?(String)
211
+ name = clean_string(cfg, key)
212
+ return name if name == key || !out.key?(name)
213
+ i = 1
214
+ i += 1 while out.key?("#{name}##{i}")
215
+ "#{name}##{i}"
216
+ end
217
+
218
+ # Does any message along the cause chain hold a registered value?
219
+ def self.dirty_chain?(cfg, err)
220
+ seen = []
221
+ until err.nil? || seen.any? { |s| s.equal?(err) }
222
+ return true if clean_string(cfg, err.message.to_s) != err.message.to_s
223
+ seen << err
224
+ err = err.cause
225
+ end
226
+ false
227
+ end
228
+
229
+ # Clean a value on its way out. A string is redacted; an SDK error is
230
+ # redacted IN PLACE (it is about to be raised, and its identity matters
231
+ # to the caller); another exception's message cannot be rewritten, so a
232
+ # changed one comes back as the same class carrying the cleaned text;
233
+ # anything else comes back as a masked plain-data copy.
234
+ def self.clean(ctx, val)
235
+ cfg = config(ctx)
236
+
237
+ return val if cfg["active"] == false
238
+
239
+ return clean_string(cfg, val) if val.is_a?(String)
240
+
241
+ if val.is_a?(Exception)
242
+ if val.is_a?(ProjectNameError)
243
+ val.msg = clean_string(cfg, val.msg.to_s)
244
+ val.instance_variables.each do |ivar|
245
+ name = ivar.to_s.delete_prefix("@")
246
+ next if name == "ctx" || name == "msg"
247
+ v = val.instance_variable_get(ivar)
248
+ if v.is_a?(String)
249
+ val.instance_variable_set(ivar,
250
+ sensitive_key?(cfg, name) ? mask_value(cfg, v) : clean_string(cfg, v))
251
+ elsif !v.nil? && !v.is_a?(Numeric) && v != true && v != false
252
+ val.instance_variable_set(ivar, snapshot(cfg, v, name, 1, []))
253
+ end
254
+ end
255
+ return val
256
+ end
257
+
258
+ # full_message prints the cause chain, so a dirty cause is dropped:
259
+ # a fresh exception carries none until it is raised.
260
+ return val unless dirty_chain?(cfg, val)
261
+ msg = clean_string(cfg, val.message.to_s)
262
+ out = val.class.exception(msg)
263
+ out.set_backtrace(val.backtrace) if val.backtrace
264
+ return out
265
+ end
266
+
267
+ out = snapshot(cfg, val, nil, 0, [])
268
+ out.equal?(DROP) ? nil : out
269
+ end
270
+
271
+ # Every scalar under a sensitive name, at any depth and of any shape: a
272
+ # credential mistyped as a map or a number is still a credential, and
273
+ # the validation error that rejects it quotes it.
274
+ def self.add_sensitive(ctx, val, under = false, depth = 0, seen = [])
275
+ return if val.nil? || depth >= MAXDEPTH
276
+ if val.is_a?(String) || val.is_a?(Integer) || val.is_a?(Float)
277
+ add(ctx, val.to_s) if under
278
+ return
279
+ end
280
+ return unless val.is_a?(Hash) || val.is_a?(Array)
281
+ return if seen.any? { |s| s.equal?(val) }
282
+ seen << val
283
+ if val.is_a?(Hash)
284
+ val.each { |k, v| add_sensitive(ctx, v, under || key?(ctx, k), depth + 1, seen) }
285
+ else
286
+ val.each { |v| add_sensitive(ctx, v, under, depth + 1, seen) }
287
+ end
288
+ end
289
+
290
+ # A feature's name is not a field name: only the sensitive names inside
291
+ # its settings count, so `secrets` does not make every setting a secret.
292
+ # Entity blocks (per-entity settings, seeded records) hold no credential.
293
+ def self.add_options(ctx, opts)
294
+ top = opts.reject { |k, _| k == "feature" || k == "entity" }
295
+ top["test"] = no_entity(top["test"]) if top.key?("test")
296
+ add_sensitive(ctx, top)
297
+ feature = opts["feature"]
298
+ blocks = feature.is_a?(Hash) ? feature.values : (feature.is_a?(Array) ? feature : [feature])
299
+ blocks.each { |fopts| add_sensitive(ctx, no_entity(fopts)) }
300
+ end
301
+
302
+ def self.no_entity(block)
303
+ block.is_a?(Hash) ? block.reject { |k, _| k == "entity" } : block
304
+ end
305
+
306
+ # Is this key name sensitive under the context's clean configuration?
307
+ def self.key?(ctx, key)
308
+ sensitive_key?(config(ctx), key)
309
+ end
310
+ end
311
+
312
+ Clean = ->(ctx, val) { CleanSupport.clean(ctx, val) }
313
+
314
+ CleanAdd = ->(ctx, value) { CleanSupport.add(ctx, value) }
4
315
  end
@@ -1,11 +1,7 @@
1
1
  # ProjectName SDK utility: done
2
2
  module ProjectNameUtilities
3
3
  Done = ->(ctx) {
4
- if ctx.ctrl.explain
5
- ctx.ctrl.explain = ctx.utility.clean.call(ctx, ctx.ctrl.explain)
6
- er = ctx.ctrl.explain["result"]
7
- er.delete("err") if er.is_a?(Hash)
8
- end
4
+ CleanExplain.call(ctx)
9
5
  if ctx.result && ctx.result.ok
10
6
  return ctx.result.resdata
11
7
  end
@@ -13,4 +9,18 @@ module ProjectNameUtilities
13
9
  # disabled, returns the bare result data). Propagate its value.
14
10
  ctx.utility.make_error.call(ctx, nil)
15
11
  }
12
+
13
+ # The caller's own hash is the explain record (the control is built from
14
+ # it, and a stream copies only its ctrl), so the cleaned copy is written
15
+ # back INTO it: assigning a fresh hash would leave the caller holding the
16
+ # raw one.
17
+ CleanExplain = ->(ctx) {
18
+ explain = ctx.ctrl.explain
19
+ return unless explain.is_a?(Hash)
20
+ cleaned = ctx.utility.clean.call(ctx, explain)
21
+ explain.replace(cleaned) if cleaned.is_a?(Hash) && !cleaned.equal?(explain)
22
+ # With clean off, explain.result is the live result object, not a Hash.
23
+ er = explain["result"]
24
+ explain["result"] = er.reject { |k, _| k == "err" } if er.is_a?(Hash)
25
+ }
16
26
  end
@@ -2,6 +2,7 @@
2
2
  require_relative '../core/operation'
3
3
  require_relative '../core/result'
4
4
  require_relative '../core/error'
5
+ require_relative 'clean'
5
6
  module ProjectNameUtilities
6
7
  MakeError = ->(ctx, err) {
7
8
  if ctx.nil?
@@ -18,9 +19,12 @@ module ProjectNameUtilities
18
19
  err = result.err if err.nil?
19
20
  err = ctx.make_error("unknown", "unknown error") if err.nil?
20
21
 
22
+ # A bare context (no client, no utility) still cleans, through the
23
+ # schema defaults.
24
+ clean = ctx.utility&.clean || ProjectNameUtilities::Clean
25
+
21
26
  errmsg = err.is_a?(ProjectNameError) ? err.msg : err.to_s
22
- msg = "ProjectNameSDK: #{opname}: #{errmsg}"
23
- msg = ctx.utility.clean.call(ctx, msg)
27
+ msg = clean.call(ctx, "ProjectNameSDK: #{opname}: #{errmsg}")
24
28
 
25
29
  result.err = nil
26
30
  spec = ctx.spec
@@ -29,15 +33,20 @@ module ProjectNameUtilities
29
33
  ctx.ctrl.explain["err"] = { "message" => msg }
30
34
  end
31
35
 
36
+ # The context stays reachable for a debugger (`err.ctx`) and is left out
37
+ # of every serialiser the error defines; result and spec are cleaned
38
+ # COPIES, so masking them never masks the pipeline's own objects.
32
39
  sdk_err = ProjectNameError.new("", msg, ctx)
33
- sdk_err.result = ctx.utility.clean.call(ctx, result)
34
- sdk_err.spec = ctx.utility.clean.call(ctx, spec)
40
+ sdk_err.result = clean.call(ctx, result)
41
+ sdk_err.spec = clean.call(ctx, spec)
35
42
 
36
43
  # Promote the HTTP status to the top level, so a consumer can branch on
37
44
  # `err.status` / `err.not_found?` instead of reaching into `err.result`.
38
45
  sdk_err.status = result.status.nil? ? -1 : result.status
39
46
  sdk_err.code = err.code if err.is_a?(ProjectNameError)
40
47
 
48
+ clean.call(ctx, sdk_err)
49
+
41
50
  ctx.ctrl.err = sdk_err
42
51
 
43
52
  # Fire PreUnexpected so observability features (metrics, telemetry, audit,
@@ -1,9 +1,11 @@
1
1
  # ProjectName SDK utility: make_options
2
2
  require_relative 'struct/voxgig_struct'
3
3
  require_relative '../schema'
4
+ require_relative 'clean'
4
5
  module ProjectNameUtilities
5
6
  MakeOptions = ->(ctx) {
6
7
  options = ctx.options || {}
8
+ options = {} unless options.is_a?(Hash)
7
9
 
8
10
  # Merge custom utility overrides.
9
11
  #
@@ -58,6 +60,22 @@ module ProjectNameUtilities
58
60
 
59
61
  opts.delete('auth') if authsuppressed
60
62
 
63
+ config = ctx.config || {}
64
+ cfgopts = config["options"].is_a?(Hash) ? config["options"] : {}
65
+
66
+ # The secret registry exists BEFORE validation, fed from the raw input, so
67
+ # the constructor's own rejection of a mistyped credential is clean too.
68
+ cfgclean = cfgopts["clean"].is_a?(Hash) ? VoxgigStruct.clone(cfgopts["clean"]) : nil
69
+ cleancfg = CleanSupport.make_config(VoxgigStruct.merge(
70
+ [{}, ProjectNameSchema::OPTSPEC["clean"], cfgclean, opts["clean"]].select { |c| c.is_a?(Hash) }))
71
+ cleanctx = { "options" => { "__derived__" => { "clean" => cleancfg } } }
72
+ CleanSupport.add_options(cleanctx, opts.reject { |k, _| k == "clean" })
73
+ [cfgopts, opts].each do |block|
74
+ CleanSupport.splitvalues(VoxgigStruct.getpath(block, "clean.values")).each do |raw|
75
+ CleanSupport.add(cleanctx, raw)
76
+ end
77
+ end
78
+
61
79
  # Feature add-order. options["feature"] may be given as an ordered ARRAY of
62
80
  # { "name" => ..., "active" => ..., ... } entries (the array position IS the
63
81
  # order in which features are added), or as a { "name" => {opts} } map.
@@ -78,9 +96,6 @@ module ProjectNameUtilities
78
96
  opts["feature"] = fmap
79
97
  end
80
98
 
81
- config = ctx.config || {}
82
- cfgopts = config["options"].is_a?(Hash) ? config["options"] : {}
83
-
84
99
  # THE OPTION SPEC IS GENERATED, NOT WRITTEN HERE.
85
100
  #
86
101
  # `ProjectNameSchema::OPTSPEC` is built from the model:
@@ -103,7 +118,12 @@ module ProjectNameUtilities
103
118
  # nested hashes as merge TARGETS — one instance's options (server,
104
119
  # headers, ...) would contaminate every instance constructed after it.
105
120
  merged = VoxgigStruct.merge([{}, VoxgigStruct.clone(cfgopts), opts])
106
- validated = VoxgigStruct.validate(merged, optspec)
121
+ begin
122
+ validated = VoxgigStruct.validate(merged, optspec)
123
+ rescue StandardError => e
124
+ # Not a cause: the raw error would print beneath the cleaned one.
125
+ raise CleanSupport.clean(cleanctx, e), cause: nil
126
+ end
107
127
  opts = validated.is_a?(Hash) ? validated : {}
108
128
 
109
129
  # Restore the suppression the optspec default would otherwise erase.
@@ -146,11 +166,6 @@ module ProjectNameUtilities
146
166
  opts["system"]["fetch"] = sys_fetch
147
167
  end
148
168
 
149
- clean_keys = VoxgigStruct.getpath(opts, "clean.keys")
150
- clean_keys = "key,token,id" unless clean_keys.is_a?(String)
151
- parts = clean_keys.split(",").map(&:strip).reject(&:empty?).map { |p| VoxgigStruct.escre(p) }
152
- keyre = parts.join("|")
153
-
154
169
  # Resolve the feature add-order: an explicit array order (above) wins;
155
170
  # otherwise order the map test-first, then the remaining names sorted, so
156
171
  # the outcome is deterministic and `test` is always the base transport.
@@ -176,9 +191,13 @@ module ProjectNameUtilities
176
191
  end
177
192
  end
178
193
 
179
- derived = { "clean" => keyre.empty? ? {} : { "keyre" => keyre } }
180
- derived["featureorder"] = featureorder
181
- opts["__derived__"] = derived
194
+ # Again over the merged result: the config's own defaults can carry one.
195
+ CleanSupport.add_options(cleanctx, opts.reject { |k, _| k == "clean" })
196
+
197
+ opts["__derived__"] = {
198
+ "clean" => cleancfg,
199
+ "featureorder" => featureorder,
200
+ }
182
201
 
183
202
  opts
184
203
  }
@@ -33,6 +33,8 @@ require_relative 'transform_response'
33
33
 
34
34
  ProjectNameUtility.registrar = ->(u) {
35
35
  u.clean = ProjectNameUtilities::Clean
36
+ u.clean_add = ProjectNameUtilities::CleanAdd
37
+ u.clean_explain = ProjectNameUtilities::CleanExplain
36
38
  u.done = ProjectNameUtilities::Done
37
39
  u.make_error = ProjectNameUtilities::MakeError
38
40
  u.feature_add = ProjectNameUtilities::FeatureAdd
@@ -12,6 +12,7 @@ use crate::core::sdk::ProjectNameSDK;
12
12
  use crate::core::spec::Spec;
13
13
  use crate::core::types::{Entity, OutVal};
14
14
  use crate::core::utility_type::Utility;
15
+ use crate::utility::voxgigstruct as vs;
15
16
  use crate::utility::voxgigstruct::Value;
16
17
 
17
18
  pub type OpMap = Rc<RefCell<HashMap<String, Rc<Operation>>>>;
@@ -279,6 +280,46 @@ impl Context {
279
280
  ProjectNameError::new(code, msg)
280
281
  }
281
282
 
283
+ /// The context as a record, CLEANED: it leaves the pipeline (a logger, an
284
+ /// error dump), while the live fields stay raw for the pipeline's own use.
285
+ pub fn to_value(&self) -> Value {
286
+ let op = self.op.borrow();
287
+ let spec = match self.spec.borrow().clone() {
288
+ Some(s) => s.borrow().to_value(),
289
+ None => Value::Noval,
290
+ };
291
+ let result = match self.result.borrow().clone() {
292
+ Some(r) => r.borrow().to_value(),
293
+ None => Value::Noval,
294
+ };
295
+ let response = match self.response.borrow().clone() {
296
+ Some(r) => {
297
+ let r = r.borrow();
298
+ jo(vec![
299
+ ("status", Value::Num(r.status as f64)),
300
+ ("statusText", Value::str(r.status_text.clone())),
301
+ ("headers", r.headers.clone()),
302
+ ])
303
+ }
304
+ None => Value::Noval,
305
+ };
306
+ let record = jo(vec![
307
+ ("id", Value::str(self.id.clone())),
308
+ (
309
+ "op",
310
+ jo(vec![
311
+ ("entity", Value::str(op.entity.clone())),
312
+ ("name", Value::str(op.name.clone())),
313
+ ]),
314
+ ),
315
+ ("spec", spec),
316
+ ("result", result),
317
+ ("response", response),
318
+ ("meta", self.meta.borrow().clone()),
319
+ ]);
320
+ crate::utility::clean::clean_value(self, &record)
321
+ }
322
+
282
323
  /// The context utility (set on every pipeline context).
283
324
  pub fn util(&self) -> Rc<Utility> {
284
325
  self.utility
@@ -309,3 +350,17 @@ impl Context {
309
350
  }
310
351
  }
311
352
  }
353
+
354
+ // Both prints are the cleaned record: a context is what a hook author hands
355
+ // to a logger.
356
+ impl std::fmt::Debug for Context {
357
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
358
+ write!(f, "Context({})", vs::jsonify(&self.to_value(), Some(&vs::JsonFlags { indent: 0, offset: 0 })))
359
+ }
360
+ }
361
+
362
+ impl std::fmt::Display for Context {
363
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
364
+ f.write_str(&vs::jsonify(&self.to_value(), Some(&vs::JsonFlags { indent: 0, offset: 0 })))
365
+ }
366
+ }
@@ -56,10 +56,27 @@ impl Utility {
56
56
  u::clean::clean_util(ctx, val)
57
57
  }
58
58
 
59
+ pub fn clean_str(&self, ctx: &Rc<Context>, val: &str) -> String {
60
+ u::clean::clean_str(ctx, val)
61
+ }
62
+
63
+ /// Register a secret value the SDK will mask from now on.
64
+ pub fn clean_add(&self, ctx: &Rc<Context>, value: &str) {
65
+ u::clean::clean_add(ctx, value)
66
+ }
67
+
68
+ pub fn clean_key(&self, ctx: &Rc<Context>, key: &str) -> bool {
69
+ u::clean::clean_key(ctx, key)
70
+ }
71
+
59
72
  pub fn done(&self, ctx: &Rc<Context>) -> Result<Value, ProjectNameError> {
60
73
  u::done::done_util(ctx)
61
74
  }
62
75
 
76
+ pub fn clean_explain(&self, ctx: &Rc<Context>) {
77
+ u::done::clean_explain_util(ctx)
78
+ }
79
+
63
80
  pub fn make_error(
64
81
  &self,
65
82
  ctx: &Rc<Context>,
@@ -80,6 +80,8 @@ impl AuditFeature {
80
80
  setp(&record, "status", Value::Num(r.borrow().status as f64));
81
81
  }
82
82
 
83
+ let record = ctx.util().clean(ctx, &record);
84
+
83
85
  self.records.push(record.clone());
84
86
  let max = fopt_int(&self.options, "max", 1000) as usize;
85
87
  while self.records.len() > max {
@@ -302,10 +302,11 @@ fn commit(
302
302
  setp(&record, "currency", Value::str(t.currency.clone()));
303
303
  setp(&record, "source", Value::str(source));
304
304
  setp(&record, "attempts", Value::Num(attempts));
305
-
306
- t.last = record.clone();
307
305
  }
308
306
 
307
+ let record = ctx.util().clean(ctx, &record);
308
+ track.borrow_mut().last = record.clone();
309
+
309
310
  let sink = getp(options, "sink");
310
311
  if let Value::Func(_) = sink {
311
312
  call_vfn(&sink, &record);
@@ -9,16 +9,6 @@ use crate::utility::voxgigstruct::Value;
9
9
 
10
10
  const DEBUG_ENTRY_KEY: &str = "debug_entry";
11
11
 
12
- const DEBUG_DEFAULT_REDACT: [&str; 7] = [
13
- "authorization",
14
- "cookie",
15
- "set-cookie",
16
- "api-key",
17
- "apikey",
18
- "x-api-key",
19
- "idempotency-key",
20
- ];
21
-
22
12
  pub struct DebugFeature {
23
13
  pub name: String,
24
14
  pub active: bool,
@@ -40,21 +30,26 @@ impl DebugFeature {
40
30
  }
41
31
  }
42
32
 
43
- fn redact(&self, headers: &Value) -> Value {
33
+ // The core clean rules apply (clean.keys, every registered value); the
34
+ // feature's own `redact` list ADDS header names on top of them.
35
+ fn redact(&self, ctx: &Rc<Context>, headers: &Value) -> Value {
44
36
  let out = Value::empty_map();
45
- let patterns = fopt_str_list(&self.options, "redact")
46
- .unwrap_or_else(|| DEBUG_DEFAULT_REDACT.iter().map(|s| s.to_string()).collect());
37
+ let patterns: Vec<String> = fopt_str_list(&self.options, "redact")
38
+ .unwrap_or_default()
39
+ .iter()
40
+ .map(|p| p.to_lowercase())
41
+ .collect();
47
42
  if let Value::Map(m) = headers {
48
43
  for (k, v) in m.borrow().iter() {
49
44
  let masked = patterns.iter().any(|p| k.to_lowercase() == *p);
50
45
  if masked {
51
- setp(&out, k, Value::str("<redacted>"));
46
+ setp(&out, k, Value::str("[redacted]"));
52
47
  } else {
53
48
  setp(&out, k, v.clone());
54
49
  }
55
50
  }
56
51
  }
57
- out
52
+ ctx.util().clean(ctx, &out)
58
53
  }
59
54
 
60
55
  fn finish(&mut self, ctx: &Rc<Context>, ok: bool) {
@@ -78,6 +73,11 @@ impl DebugFeature {
78
73
  }
79
74
  }
80
75
 
76
+ // The whole entry leaves through the buffer and the callback: the url
77
+ // and the error message can carry a query credential the header mask
78
+ // above never saw.
79
+ let entry = ctx.util().clean(ctx, &entry);
80
+
81
81
  self.entries.push(entry.clone());
82
82
  let max = fopt_int(&self.options, "max", 100) as usize;
83
83
  while self.entries.len() > max {
@@ -132,7 +132,7 @@ impl Feature for DebugFeature {
132
132
  } else {
133
133
  setp(&entry, "url", Value::str(s.path.clone()));
134
134
  }
135
- setp(&entry, "headers", self.redact(&s.headers));
135
+ setp(&entry, "headers", self.redact(ctx, &s.headers));
136
136
  }
137
137
  ctx.out_set(DEBUG_ENTRY_KEY, OutVal::Val(entry));
138
138
  }