@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
@@ -207,3 +207,20 @@ class ProjectNameContext:
207
207
 
208
208
  def make_error(self, code, msg):
209
209
  return ProjectNameError(code, msg, self)
210
+
211
+ # The serialised context leaves the pipeline (a logger, an error dump),
212
+ # so it is cleaned; the live fields stay raw for the pipeline's own use.
213
+ def to_json(self):
214
+ record = {
215
+ "id": self.id,
216
+ "op": self.op,
217
+ "spec": self.spec,
218
+ "result": self.result,
219
+ "response": self.response,
220
+ "meta": self.meta,
221
+ }
222
+ clean = getattr(self.utility, "clean", None) if self.utility is not None else None
223
+ return clean(self, record) if callable(clean) else record
224
+
225
+ def __repr__(self):
226
+ return self.__class__.__name__ + "(" + repr(self.to_json()) + ")"
@@ -4,15 +4,56 @@ from __future__ import annotations
4
4
 
5
5
 
6
6
  class ProjectNameError(Exception):
7
+ # The context holds the live spec and options, and an error is what gets
8
+ # logged: a slot keeps it reachable for a debugger and out of `vars()`,
9
+ # pickling and every attribute dump.
10
+ __slots__ = ("_ctx",)
11
+
7
12
  def __init__(self, code="", msg="", ctx=None):
8
13
  super().__init__(msg)
9
14
  self.is_sdk_error = True
10
15
  self.sdk = "ProjectName"
11
16
  self.code = code
12
17
  self.msg = msg
13
- self.ctx = ctx
18
+ self._ctx = ctx
19
+ self.status = -1
14
20
  self.result = None
15
21
  self.spec = None
16
22
 
23
+ @property
24
+ def ctx(self):
25
+ return getattr(self, "_ctx", None)
26
+
27
+ @ctx.setter
28
+ def ctx(self, value):
29
+ self._ctx = value
30
+
31
+ # `err.not_found` rather than a magic number at every call site.
32
+ @property
33
+ def not_found(self):
34
+ return 404 == self.status
35
+
36
+ # What make_error attached is already cleaned; the context is not part
37
+ # of the record.
38
+ def to_json(self):
39
+ return {
40
+ "sdk": self.sdk,
41
+ "code": self.code,
42
+ "message": self.msg,
43
+ "status": self.status,
44
+ "result": self.result,
45
+ "spec": self.spec,
46
+ }
47
+
17
48
  def __str__(self):
18
49
  return self.msg
50
+
51
+ def __repr__(self):
52
+ return (self.__class__.__name__ + "(code=" + repr(self.code) +
53
+ ", msg=" + repr(self.msg) + ", status=" + repr(self.status) + ")")
54
+
55
+ def __getstate__(self):
56
+ return dict(self.__dict__)
57
+
58
+ def __reduce__(self):
59
+ return (self.__class__, (self.code, self.msg), self.__getstate__())
@@ -11,6 +11,8 @@ class ProjectNameUtility:
11
11
 
12
12
  # All utility functions are set by the register module
13
13
  self.clean = None
14
+ self.clean_add = None
15
+ self.clean_explain = None
14
16
  self.done = None
15
17
  self.make_error = None
16
18
  self.feature_add = None
@@ -50,6 +52,8 @@ class ProjectNameUtility:
50
52
  def copy(cls, src):
51
53
  u = cls()
52
54
  u.clean = src.clean
55
+ u.clean_add = src.clean_add
56
+ u.clean_explain = src.clean_explain
53
57
  u.done = src.done
54
58
  u.make_error = src.make_error
55
59
  u.feature_add = src.feature_add
@@ -67,7 +67,7 @@ class ProjectNameAuditFeature(ProjectNameBaseFeature):
67
67
  if actor is None:
68
68
  actor = "anonymous"
69
69
 
70
- record = {
70
+ record = ctx.utility.clean(ctx, {
71
71
  "seq": self.seq,
72
72
  "ts": self._now(),
73
73
  "actor": actor,
@@ -76,7 +76,7 @@ class ProjectNameAuditFeature(ProjectNameBaseFeature):
76
76
  "outcome": outcome,
77
77
  "status": ctx.result.status if ctx.result is not None else None,
78
78
  "correlationId": ctx.id,
79
- }
79
+ })
80
80
 
81
81
  records = self.client._audit["records"]
82
82
  records.append(record)
@@ -249,7 +249,7 @@ class ProjectNameCostFeature(ProjectNameBaseFeature):
249
249
  self._bump(cost["actors"], actor, amount)
250
250
 
251
251
  self.seq += 1
252
- record = {
252
+ record = ctx.utility.clean(ctx, {
253
253
  "seq": self.seq,
254
254
  "entity": entity,
255
255
  "op": opname,
@@ -258,7 +258,7 @@ class ProjectNameCostFeature(ProjectNameBaseFeature):
258
258
  "currency": cost["currency"],
259
259
  "source": source,
260
260
  "attempts": pending["attempts"],
261
- }
261
+ })
262
262
  cost["last"] = record
263
263
 
264
264
  sink = self.options.get("sink")
@@ -8,10 +8,11 @@ from projectname_sdk.feature.base_feature import ProjectNameBaseFeature
8
8
 
9
9
  # Request/response capture for debugging. Records a bounded ring buffer of
10
10
  # per-operation traces — method, URL, redacted headers, response status and
11
- # timing — on `client._debug["entries"]`. Sensitive header values (matching
12
- # `redact`, default authorization/cookie/api-key style names) are masked.
13
- # An optional `onEntry` callback receives each finished entry (e.g. to
14
- # stream to a console). `max` caps the buffer (default 100).
11
+ # timing — on `client._debug["entries"]`. Every entry passes through the
12
+ # SDK's clean rules (clean.keys and every registered secret value); the
13
+ # `redact` option ADDS header names on top of them. An optional `onEntry`
14
+ # callback receives each finished entry (e.g. to stream to a console).
15
+ # `max` caps the buffer (default 100).
15
16
  class ProjectNameDebugFeature(ProjectNameBaseFeature):
16
17
  def __init__(self):
17
18
  super().__init__()
@@ -47,7 +48,7 @@ class ProjectNameDebugFeature(ProjectNameBaseFeature):
47
48
  "op": opname,
48
49
  "method": spec.method if spec is not None else None,
49
50
  "url": (spec.url or spec.path) if spec is not None else None,
50
- "headers": self._redact(spec.headers if spec is not None else None),
51
+ "headers": self._redact(ctx, spec.headers if spec is not None else None),
51
52
  "start": self._now(),
52
53
  "status": None,
53
54
  "ok": None,
@@ -99,6 +100,11 @@ class ProjectNameDebugFeature(ProjectNameBaseFeature):
99
100
  if entry["status"] is None and result is not None:
100
101
  entry["status"] = result.status
101
102
 
103
+ # The whole entry leaves through the buffer and the callback: the url
104
+ # and the error message can carry a query credential the header mask
105
+ # above never saw.
106
+ entry = ctx.utility.clean(ctx, entry)
107
+
102
108
  buf = self.client._debug["entries"]
103
109
  buf.append(entry)
104
110
  mx = 100 if self.options.get("max") is None else self.options.get("max")
@@ -112,20 +118,19 @@ class ProjectNameDebugFeature(ProjectNameBaseFeature):
112
118
  except Exception:
113
119
  pass
114
120
 
115
- def _redact(self, headers):
121
+ # The core clean rules apply (clean.keys, every registered value); the
122
+ # feature's own `redact` list ADDS header names on top of them.
123
+ def _redact(self, ctx, headers):
116
124
  if headers is None:
117
125
  return {}
118
- patterns = self.options.get("redact") or [
119
- "authorization", "cookie", "set-cookie", "api-key",
120
- "apikey", "x-api-key", "idempotency-key",
121
- ]
126
+ patterns = [str(n).lower() for n in (self.options.get("redact") or [])]
122
127
  out = {}
123
128
  for key in headers:
124
129
  if str(key).lower() in patterns:
125
- out[key] = "<redacted>"
130
+ out[key] = "[redacted]"
126
131
  else:
127
132
  out[key] = headers[key]
128
- return out
133
+ return ctx.utility.clean(ctx, out)
129
134
 
130
135
  def _now(self):
131
136
  now = self.options.get("now")
@@ -44,7 +44,8 @@ class ProjectNameLogFeature(ProjectNameBaseFeature):
44
44
  if ctx.op is not None:
45
45
  opname = ctx.op.name
46
46
 
47
- msg = "hook=" + hook + " op=" + opname
47
+ # A log line leaves the pipeline, so it is cleaned like any record.
48
+ msg = ctx.utility.clean(ctx, "hook=" + hook + " op=" + opname)
48
49
 
49
50
  log_fn = self.logger.get(level)
50
51
  if callable(log_fn):
@@ -3,6 +3,7 @@
3
3
  from __future__ import annotations
4
4
  import os
5
5
  import re
6
+ from urllib.parse import unquote, urlsplit
6
7
 
7
8
  from projectname_sdk.feature.base_feature import ProjectNameBaseFeature
8
9
 
@@ -27,6 +28,7 @@ class ProjectNameProxyFeature(ProjectNameBaseFeature):
27
28
  self.options = {}
28
29
  self.url = None
29
30
  self.no_proxy = []
31
+ self._ctx = None
30
32
 
31
33
  def init(self, ctx, options):
32
34
  self.client = ctx.client
@@ -54,6 +56,19 @@ class ProjectNameProxyFeature(ProjectNameBaseFeature):
54
56
  no_proxy = re.split(r"\s*,\s*", no_proxy)
55
57
  self.no_proxy = [s for s in (no_proxy or []) if s is not None and s != ""]
56
58
 
59
+ # A proxy URL may carry credentials as userinfo, from the option or
60
+ # the environment, and neither is under a sensitive key name.
61
+ self._ctx = ctx
62
+ if isinstance(self.url, str):
63
+ try:
64
+ parsed = urlsplit(self.url)
65
+ for part in (parsed.username, parsed.password):
66
+ if part:
67
+ ctx.utility.clean_add(ctx, part)
68
+ ctx.utility.clean_add(ctx, unquote(part))
69
+ except Exception:
70
+ pass
71
+
57
72
  utility = ctx.utility
58
73
  inner = utility.fetcher
59
74
 
@@ -99,6 +114,8 @@ class ProjectNameProxyFeature(ProjectNameBaseFeature):
99
114
  client = self.client
100
115
  track = getattr(client, "_proxy", None)
101
116
  if track is None:
102
- track = {"routed": 0, "url": self.url}
117
+ ctx = self._ctx
118
+ url = self.url if ctx is None else ctx.utility.clean(ctx, self.url)
119
+ track = {"routed": 0, "url": url}
103
120
  client._proxy = track
104
121
  track["routed"] += 1
@@ -153,6 +153,7 @@ class ProjectNameSecretsFeature(ProjectNameBaseFeature):
153
153
  explicit = xopts.get("refresh") if isinstance(xopts, dict) else None
154
154
 
155
155
  if isinstance(explicit, str) and "" != explicit:
156
+ self._register(explicit)
156
157
  providers.append({
157
158
  "kind": "memory",
158
159
  "name": "options",
@@ -198,6 +199,14 @@ class ProjectNameSecretsFeature(ProjectNameBaseFeature):
198
199
  def sekreto(self):
199
200
  return self._sekreto
200
201
 
202
+ # Every value this feature resolves or buys is a secret the SDK handles,
203
+ # and none arrives under an option key the intake registration saw.
204
+ def _register(self, value):
205
+ ctx = getattr(self._client, "_rootctx", None)
206
+ utility = getattr(ctx, "utility", None)
207
+ if callable(getattr(utility, "clean_add", None)):
208
+ utility.clean_add(ctx, value)
209
+
201
210
  def PreSpec(self, _ctx):
202
211
  return self.resolve()
203
212
 
@@ -231,6 +240,7 @@ class ProjectNameSecretsFeature(ProjectNameBaseFeature):
231
240
  # RAISES for "a store could not answer" - only the miss falls
232
241
  # through.
233
242
  found = self._sekreto.try_(self._secretname)
243
+ self._register(found)
234
244
 
235
245
  if self._exchange is None:
236
246
  if found is not None:
@@ -367,6 +377,8 @@ class ProjectNameSecretsFeature(ProjectNameBaseFeature):
367
377
  "secrets: token exchange returned no '" + x["response"]
368
378
  + "' field from " + url)
369
379
 
380
+ self._register(token)
381
+
370
382
  return token
371
383
 
372
384
  # Buy a token and try the request again when the API says the current
@@ -101,14 +101,16 @@ class ProjectNameTelemetryFeature(ProjectNameBaseFeature):
101
101
  span["durationMs"] = max(0, span["end"] - span["start"])
102
102
  span["ok"] = ok
103
103
 
104
+ out = ctx.utility.clean(ctx, span)
105
+
104
106
  telemetry = self.client._telemetry
105
107
  telemetry["active"] -= 1
106
- telemetry["spans"].append(span)
108
+ telemetry["spans"].append(out)
107
109
 
108
110
  exporter = self.options.get("exporter")
109
111
  if callable(exporter):
110
112
  try:
111
- exporter(span)
113
+ exporter(out)
112
114
  except Exception:
113
115
  pass
114
116
 
@@ -1,5 +1,315 @@
1
1
  # ProjectName SDK utility: clean
2
2
 
3
+ from __future__ import annotations
4
+ import base64
5
+ import json
6
+ from urllib.parse import quote
3
7
 
8
+ from projectname_sdk.schema import OPTSPEC
9
+
10
+
11
+ # Everything that leaves the pipeline passes through clean: the error, the
12
+ # explain record, the serialised context, and whatever a feature emits.
13
+ # Two layers: every registered secret VALUE (and its encoded forms) is
14
+ # replaced wherever it appears in a string, and every value under a
15
+ # sensitive KEY name is masked whatever it holds. Inside the pipeline data
16
+ # stays raw, so a hook can still read the header it must add to.
17
+
18
+ _MAXDEPTH = 32
19
+ _CIRCULAR = "[circular]"
20
+
21
+ # A dropped value (a function) - distinct from None, which is data.
22
+ _DROP = object()
23
+
24
+
25
+ def _normkey(key):
26
+ return str(key).lower().replace("-", "").replace("_", "")
27
+
28
+
29
+ def _splitkeys(keys):
30
+ out = []
31
+ for part in str("" if keys is None else keys).split(","):
32
+ k = _normkey(part.strip())
33
+ if k != "":
34
+ out.append(k)
35
+ return out
36
+
37
+
38
+ # The comma-separated literal values a caller registers; a list is taken
39
+ # as-is for a caller that has one.
40
+ def split_values(values):
41
+ if isinstance(values, list):
42
+ return [v for v in values if isinstance(v, str)]
43
+ out = []
44
+ for part in str("" if values is None else values).split(","):
45
+ v = part.strip()
46
+ if v != "":
47
+ out.append(v)
48
+ return out
49
+
50
+
51
+ # The spec carries numbers as strings, so every target reads it alike.
52
+ def _count(val, dflt):
53
+ try:
54
+ n = int(float(val))
55
+ except (TypeError, ValueError):
56
+ return dflt
57
+ return n if n >= 0 else dflt
58
+
59
+
60
+ def _options_of(ctx):
61
+ if isinstance(ctx, dict):
62
+ return ctx.get("options")
63
+ return getattr(ctx, "options", None)
64
+
65
+
66
+ # The derived block make_options builds; a context without options
67
+ # (make_error is reached with a bare one) falls back to the schema defaults,
68
+ # so nothing leaves raw for want of a constructor.
69
+ def _clean_config(ctx):
70
+ options = _options_of(ctx)
71
+ derived = options.get("__derived__") if isinstance(options, dict) else None
72
+ cfg = derived.get("clean") if isinstance(derived, dict) else None
73
+ if isinstance(cfg, dict) and isinstance(cfg.get("values"), list):
74
+ return cfg
75
+ return make_clean_config(OPTSPEC.get("clean"))
76
+
77
+
78
+ def make_clean_config(cleanopts):
79
+ opts = cleanopts if isinstance(cleanopts, dict) else {}
80
+ mask = opts.get("mask")
81
+ return {
82
+ "active": opts.get("active") is not False,
83
+ "keys": _splitkeys(opts.get("keys")),
84
+ "values": [],
85
+ "mask": mask if isinstance(mask, str) else "[redacted]",
86
+ "hint": _count(opts.get("hint"), 0),
87
+ "min": max(1, _count(opts.get("min"), 4)),
88
+ }
89
+
90
+
91
+ # The encoded forms a value travels in: Basic and Bearer both carry base64,
92
+ # a query credential is percent-encoded, and a JSON dump escapes it.
93
+ def _forms(value):
94
+ out = [value]
95
+
96
+ def add(s):
97
+ if s != "" and s not in out:
98
+ out.append(s)
99
+
100
+ try:
101
+ add(base64.b64encode(value.encode("utf-8")).decode("ascii"))
102
+ except Exception:
103
+ pass
104
+ try:
105
+ add(quote(value, safe="!~*'()"))
106
+ except Exception:
107
+ pass
108
+ try:
109
+ add(json.dumps(value, ensure_ascii=False)[1:-1])
110
+ add(json.dumps(value)[1:-1])
111
+ except Exception:
112
+ pass
113
+ return out
114
+
115
+
116
+ # Register a secret value. Idempotent; shorter than `min` is not a secret
117
+ # the SDK can mask without blanking ordinary text.
118
+ def clean_add_util(ctx, value):
119
+ cfg = _clean_config(ctx)
120
+ if not isinstance(value, str) or len(value) < cfg["min"]:
121
+ return
122
+ values = cfg["values"]
123
+ changed = False
124
+ for form in _forms(value):
125
+ if len(form) >= cfg["min"] and form not in values:
126
+ values.append(form)
127
+ changed = True
128
+ if changed:
129
+ values.sort(key=len, reverse=True)
130
+
131
+
132
+ # Every scalar under a sensitive name, at any depth and of any shape: a
133
+ # credential mistyped as a map or a number is still a credential, and the
134
+ # validation error that rejects it quotes it.
135
+ def clean_add_sensitive(ctx, val, under=False, depth=0, seen=None):
136
+ if val is None or _MAXDEPTH <= depth or isinstance(val, bool):
137
+ return
138
+ if isinstance(val, (str, int, float)):
139
+ if under:
140
+ text = str(int(val)) if isinstance(val, float) and val.is_integer() else str(val)
141
+ clean_add_util(ctx, text)
142
+ return
143
+ if not isinstance(val, (dict, list, tuple)):
144
+ return
145
+ seen = [] if seen is None else seen
146
+ if id(val) in seen:
147
+ return
148
+ seen.append(id(val))
149
+ if isinstance(val, dict):
150
+ for k, v in val.items():
151
+ clean_add_sensitive(ctx, v, under or clean_key(ctx, k), depth + 1, seen)
152
+ else:
153
+ for v in val:
154
+ clean_add_sensitive(ctx, v, under, depth + 1, seen)
155
+
156
+
157
+ def _mask_value(cfg, value):
158
+ hint = cfg["hint"]
159
+ if 0 < hint and len(value) > 2 * hint:
160
+ return cfg["mask"] + value[-hint:]
161
+ return cfg["mask"]
162
+
163
+
164
+ def _clean_string(cfg, text):
165
+ out = text
166
+ for value in cfg["values"]:
167
+ if value in out:
168
+ out = out.replace(value, _mask_value(cfg, value))
169
+ return out
170
+
171
+
172
+ def _sensitive_key(cfg, key):
173
+ if key is None or isinstance(key, bool) or isinstance(key, (int, float)):
174
+ return False
175
+ nk = _normkey(key)
176
+ for k in cfg["keys"]:
177
+ if k in nk:
178
+ return True
179
+ return False
180
+
181
+
182
+ def _is_function(val):
183
+ return callable(val) and not isinstance(val, type)
184
+
185
+
186
+ # A plain-data copy of what is about to leave: a `to_json` hook is honoured
187
+ # (a context serialises as its record), functions are dropped, cycles are
188
+ # cut, and no live object is shared with the copy - masking the copy must
189
+ # never mask the pipeline's own spec.
190
+ def _snapshot(cfg, val, key, depth, seen):
191
+ if val is None:
192
+ return None
193
+
194
+ if isinstance(val, str):
195
+ return _mask_value(cfg, val) if _sensitive_key(cfg, key) else _clean_string(cfg, val)
196
+
197
+ if isinstance(val, (bool, int, float)):
198
+ return cfg["mask"] if _sensitive_key(cfg, key) else val
199
+
200
+ if _is_function(val):
201
+ return _DROP
202
+
203
+ if _MAXDEPTH <= depth or id(val) in seen:
204
+ return _CIRCULAR
205
+
206
+ if _sensitive_key(cfg, key):
207
+ return cfg["mask"]
208
+
209
+ seen.append(id(val))
210
+ try:
211
+ if isinstance(val, dict):
212
+ return _plain(cfg, val.items(), depth, seen)
213
+
214
+ if isinstance(val, (list, tuple, set, frozenset)):
215
+ out = []
216
+ for i, item in enumerate(val):
217
+ c = _snapshot(cfg, item, i, depth + 1, seen)
218
+ out.append(None if c is _DROP else c)
219
+ return out
220
+
221
+ if isinstance(val, BaseException):
222
+ out = {"message": _clean_string(cfg, str(val))}
223
+ for k, v in _public(val):
224
+ c = _snapshot(cfg, v, k, depth + 1, seen)
225
+ if c is not _DROP:
226
+ out[k] = c
227
+ return out
228
+
229
+ to_json = getattr(val, "to_json", None)
230
+ if callable(to_json):
231
+ rec = to_json()
232
+ if rec is not val:
233
+ return _snapshot(cfg, rec, key, depth + 1, seen)
234
+
235
+ if hasattr(val, "__dict__"):
236
+ return _plain(cfg, _public(val), depth, seen)
237
+
238
+ return _clean_string(cfg, str(val))
239
+ finally:
240
+ seen.pop()
241
+
242
+
243
+ # An object's own public attributes: the private ones hold the pipeline's
244
+ # live references (an entity's client, an error's context).
245
+ def _public(obj):
246
+ return [(k, v) for k, v in vars(obj).items()
247
+ if not str(k).startswith("_")]
248
+
249
+
250
+ def _plain(cfg, items, depth, seen):
251
+ out = {}
252
+ for k, v in items:
253
+ c = _snapshot(cfg, v, k, depth + 1, seen)
254
+ if c is not _DROP:
255
+ out[_clean_name(cfg, out, str(k))] = c
256
+ return out
257
+
258
+
259
+ # A registered value used as a property name is masked like any other
260
+ # string; names that mask alike take a counter, so none is lost.
261
+ def _clean_name(cfg, out, key):
262
+ name = _clean_string(cfg, key)
263
+ if name == key or name not in out:
264
+ return name
265
+ i = 1
266
+ while name + "#" + str(i) in out:
267
+ i += 1
268
+ return name + "#" + str(i)
269
+
270
+
271
+ # An exception is cleaned IN PLACE: it is about to be raised, and its
272
+ # identity matters to the caller. The message lives in `args`.
273
+ def _clean_exception(cfg, err):
274
+ args = tuple(_clean_string(cfg, a) if isinstance(a, str) else a for a in err.args)
275
+ if args != err.args:
276
+ err.args = args
277
+
278
+ for k, v in _public(err):
279
+ if isinstance(v, str):
280
+ v = _mask_value(cfg, v) if _sensitive_key(cfg, k) else _clean_string(cfg, v)
281
+ elif v is not None and not isinstance(v, (bool, int, float)) and not _is_function(v):
282
+ v = _snapshot(cfg, v, k, 1, [])
283
+ name = _clean_string(cfg, k)
284
+ if name != k:
285
+ delattr(err, k)
286
+ name = _clean_name(cfg, vars(err), k)
287
+ setattr(err, name, v)
288
+
289
+ notes = getattr(err, "__notes__", None)
290
+ if isinstance(notes, list):
291
+ err.__notes__ = [_clean_string(cfg, n) if isinstance(n, str) else n for n in notes]
292
+
293
+
294
+ # Clean a value on its way out. A string is redacted; an exception is
295
+ # redacted in place; anything else comes back as a masked plain-data copy.
4
296
  def clean_util(ctx, val):
5
- return val
297
+ cfg = _clean_config(ctx)
298
+
299
+ if cfg["active"] is False:
300
+ return val
301
+
302
+ if isinstance(val, str):
303
+ return _clean_string(cfg, val)
304
+
305
+ if isinstance(val, BaseException):
306
+ _clean_exception(cfg, val)
307
+ return val
308
+
309
+ out = _snapshot(cfg, val, None, 0, [])
310
+ return None if out is _DROP else out
311
+
312
+
313
+ # Is this key name sensitive under the context's clean configuration?
314
+ def clean_key(ctx, key):
315
+ return _sensitive_key(_clean_config(ctx), key)
@@ -2,11 +2,7 @@
2
2
 
3
3
 
4
4
  def done_util(ctx):
5
- if ctx.ctrl.explain is not None:
6
- ctx.ctrl.explain = ctx.utility.clean(ctx, ctx.ctrl.explain)
7
- explain_result = ctx.ctrl.explain.get("result") if isinstance(ctx.ctrl.explain, dict) else None
8
- if isinstance(explain_result, dict):
9
- explain_result.pop("err", None)
5
+ clean_explain_util(ctx)
10
6
 
11
7
  if ctx.result is not None and ctx.result.ok:
12
8
  return ctx.result.resdata
@@ -14,3 +10,20 @@ def done_util(ctx):
14
10
  # make_error raises on the default (throw) path; only returns bare
15
11
  # resdata when throw_err is explicitly disabled.
16
12
  return ctx.utility.make_error(ctx, None)
13
+
14
+
15
+ # In place: the caller holds this very dict (ctrl is built from it), and a
16
+ # stream copies only its ctrl, so a reassignment would leave the raw record
17
+ # in their hands.
18
+ def clean_explain_util(ctx):
19
+ explain = ctx.ctrl.explain
20
+ if not isinstance(explain, dict):
21
+ return
22
+ cleaned = ctx.utility.clean(ctx, explain)
23
+ if isinstance(cleaned, dict) and cleaned is not explain:
24
+ explain.clear()
25
+ explain.update(cleaned)
26
+ # With clean off, explain.result is the live result object, not a dict.
27
+ result = explain.get("result")
28
+ if isinstance(result, dict):
29
+ explain["result"] = {k: v for k, v in result.items() if k != "err"}