@voxgig/sdkgen 4.32.0 → 4.33.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 (415) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/dist/helpers/naming.js +1 -1
  3. package/dist/helpers/naming.js.map +1 -1
  4. package/dist/tsconfig.tsbuildinfo +1 -1
  5. package/model/sdkgen.aontu +7 -1
  6. package/package.json +1 -1
  7. package/project/.sdk/model/feature/debug.aontu +3 -1
  8. package/project/.sdk/src/cmp/c/PrepareAuth_c.ts +8 -28
  9. package/project/.sdk/src/cmp/c/TestClean_c.ts +774 -0
  10. package/project/.sdk/src/cmp/c/Test_c.ts +3 -0
  11. package/project/.sdk/src/cmp/c/fragment/Entity.fragment.c +16 -5
  12. package/project/.sdk/src/cmp/c/fragment/Main.fragment.c +1 -1
  13. package/project/.sdk/src/cmp/clojure/PrepareAuth_clojure.ts +3 -0
  14. package/project/.sdk/src/cmp/clojure/TestClean_clojure.ts +473 -0
  15. package/project/.sdk/src/cmp/clojure/Test_clojure.ts +6 -0
  16. package/project/.sdk/src/cmp/clojure/fragment/Entity.fragment.clj +18 -8
  17. package/project/.sdk/src/cmp/cpp/PrepareAuth_cpp.ts +3 -0
  18. package/project/.sdk/src/cmp/cpp/TestClean_cpp.ts +782 -0
  19. package/project/.sdk/src/cmp/cpp/TestEntity_cpp.ts +1 -1
  20. package/project/.sdk/src/cmp/cpp/Test_cpp.ts +2 -0
  21. package/project/.sdk/src/cmp/csharp/PrepareAuth_csharp.ts +3 -0
  22. package/project/.sdk/src/cmp/csharp/TestClean_csharp.ts +887 -0
  23. package/project/.sdk/src/cmp/csharp/Test_csharp.ts +2 -0
  24. package/project/.sdk/src/cmp/csharp/fragment/EntityBase.fragment.cs +68 -4
  25. package/project/.sdk/src/cmp/csharp/fragment/Main.fragment.cs +8 -2
  26. package/project/.sdk/src/cmp/csharp/fragment/SdkError.fragment.cs +49 -0
  27. package/project/.sdk/src/cmp/elixir/PrepareAuth_elixir.ts +3 -0
  28. package/project/.sdk/src/cmp/elixir/Schema_elixir.ts +20 -10
  29. package/project/.sdk/src/cmp/elixir/TestClean_elixir.ts +666 -0
  30. package/project/.sdk/src/cmp/elixir/Test_elixir.ts +4 -0
  31. package/project/.sdk/src/cmp/elixir/fragment/Main.fragment.ex +1 -1
  32. package/project/.sdk/src/cmp/elixir/fragment/Pipeline.fragment.ex +14 -2
  33. package/project/.sdk/src/cmp/go/PrepareAuth_go.ts +3 -0
  34. package/project/.sdk/src/cmp/go/TestClean_go.ts +804 -0
  35. package/project/.sdk/src/cmp/go/Test_go.ts +3 -0
  36. package/project/.sdk/src/cmp/go/fragment/Entity.fragment.go +54 -4
  37. package/project/.sdk/src/cmp/go/fragment/Main.fragment.go +27 -2
  38. package/project/.sdk/src/cmp/java/PrepareAuth_java.ts +3 -0
  39. package/project/.sdk/src/cmp/java/TestClean_java.ts +884 -0
  40. package/project/.sdk/src/cmp/java/Test_java.ts +2 -0
  41. package/project/.sdk/src/cmp/java/fragment/EntityBase.fragment.java +56 -11
  42. package/project/.sdk/src/cmp/java/fragment/SdkError.fragment.java +36 -3
  43. package/project/.sdk/src/cmp/js/PrepareAuth_js.ts +3 -0
  44. package/project/.sdk/src/cmp/js/TestClean_js.ts +458 -0
  45. package/project/.sdk/src/cmp/js/Test_js.ts +2 -0
  46. package/project/.sdk/src/cmp/js/fragment/EntityBase.fragment.js +5 -4
  47. package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +7 -1
  48. package/project/.sdk/src/cmp/js/fragment/EntityListOp.fragment.js +7 -1
  49. package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +7 -1
  50. package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +7 -1
  51. package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +7 -1
  52. package/project/.sdk/src/cmp/js/fragment/Main.fragment.js +11 -2
  53. package/project/.sdk/src/cmp/js/fragment/SdkError.fragment.js +17 -1
  54. package/project/.sdk/src/cmp/kotlin/Package_kotlin.ts +5 -0
  55. package/project/.sdk/src/cmp/kotlin/PrepareAuth_kotlin.ts +3 -0
  56. package/project/.sdk/src/cmp/kotlin/TestClean_kotlin.ts +654 -0
  57. package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +3 -0
  58. package/project/.sdk/src/cmp/kotlin/fragment/EntityBase.fragment.kt +44 -11
  59. package/project/.sdk/src/cmp/kotlin/fragment/SdkError.fragment.kt +31 -0
  60. package/project/.sdk/src/cmp/lua/PrepareAuth_lua.ts +3 -0
  61. package/project/.sdk/src/cmp/lua/TestClean_lua.ts +769 -0
  62. package/project/.sdk/src/cmp/lua/Test_lua.ts +3 -0
  63. package/project/.sdk/src/cmp/lua/fragment/Entity.fragment.lua +77 -1
  64. package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +49 -2
  65. package/project/.sdk/src/cmp/ocaml/Entity_ocaml.ts +3 -2
  66. package/project/.sdk/src/cmp/ocaml/PrepareAuth_ocaml.ts +4 -25
  67. package/project/.sdk/src/cmp/ocaml/TestClean_ocaml.ts +538 -0
  68. package/project/.sdk/src/cmp/ocaml/Test_ocaml.ts +5 -0
  69. package/project/.sdk/src/cmp/ocaml/fragment/RunOp.fragment.ml +16 -4
  70. package/project/.sdk/src/cmp/perl/PrepareAuth_perl.ts +3 -0
  71. package/project/.sdk/src/cmp/perl/TestClean_perl.ts +619 -0
  72. package/project/.sdk/src/cmp/perl/Test_perl.ts +3 -0
  73. package/project/.sdk/src/cmp/perl/fragment/Entity.fragment.pm +67 -5
  74. package/project/.sdk/src/cmp/perl/fragment/Main.fragment.pm +13 -1
  75. package/project/.sdk/src/cmp/php/PrepareAuth_php.ts +3 -0
  76. package/project/.sdk/src/cmp/php/TestClean_php.ts +809 -0
  77. package/project/.sdk/src/cmp/php/Test_php.ts +2 -0
  78. package/project/.sdk/src/cmp/php/fragment/Entity.fragment.php +96 -55
  79. package/project/.sdk/src/cmp/php/fragment/Main.fragment.php +15 -2
  80. package/project/.sdk/src/cmp/py/PrepareAuth_py.ts +3 -0
  81. package/project/.sdk/src/cmp/py/TestClean_py.ts +549 -0
  82. package/project/.sdk/src/cmp/py/Test_py.ts +3 -0
  83. package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +83 -55
  84. package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +19 -3
  85. package/project/.sdk/src/cmp/rb/PrepareAuth_rb.ts +3 -0
  86. package/project/.sdk/src/cmp/rb/TestClean_rb.ts +535 -0
  87. package/project/.sdk/src/cmp/rb/Test_rb.ts +3 -0
  88. package/project/.sdk/src/cmp/rb/fragment/Entity.fragment.rb +108 -46
  89. package/project/.sdk/src/cmp/rb/fragment/Main.fragment.rb +12 -1
  90. package/project/.sdk/src/cmp/rust/PrepareAuth_rust.ts +9 -45
  91. package/project/.sdk/src/cmp/rust/TestClean_rust.ts +881 -0
  92. package/project/.sdk/src/cmp/rust/Test_rust.ts +3 -0
  93. package/project/.sdk/src/cmp/rust/fragment/Entity.fragment.rs +14 -6
  94. package/project/.sdk/src/cmp/rust/fragment/Main.fragment.rs +17 -1
  95. package/project/.sdk/src/cmp/rust/fragment/SdkError.fragment.rs +34 -2
  96. package/project/.sdk/src/cmp/scala/PrepareAuth_scala.ts +3 -0
  97. package/project/.sdk/src/cmp/scala/TestClean_scala.ts +608 -0
  98. package/project/.sdk/src/cmp/scala/Test_scala.ts +3 -0
  99. package/project/.sdk/src/cmp/scala/fragment/EntityBase.fragment.scala +58 -6
  100. package/project/.sdk/src/cmp/swift/PrepareAuth_swift.ts +3 -0
  101. package/project/.sdk/src/cmp/swift/TestClean_swift.ts +671 -0
  102. package/project/.sdk/src/cmp/swift/Test_swift.ts +3 -0
  103. package/project/.sdk/src/cmp/swift/fragment/EntityBase.fragment.swift +10 -0
  104. package/project/.sdk/src/cmp/swift/fragment/Main.fragment.swift +16 -2
  105. package/project/.sdk/src/cmp/swift/fragment/SdkError.fragment.swift +47 -3
  106. package/project/.sdk/src/cmp/ts/PrepareAuth_ts.ts +3 -0
  107. package/project/.sdk/src/cmp/ts/TestClean_ts.ts +465 -0
  108. package/project/.sdk/src/cmp/ts/Test_ts.ts +2 -0
  109. package/project/.sdk/src/cmp/ts/fragment/EntityBase.fragment.ts +5 -4
  110. package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.ts +7 -1
  111. package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.ts +7 -1
  112. package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.ts +7 -1
  113. package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.ts +7 -1
  114. package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.ts +7 -1
  115. package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +8 -2
  116. package/project/.sdk/src/cmp/ts/fragment/SdkError.fragment.ts +20 -2
  117. package/project/.sdk/src/cmp/zig/PrepareAuth_zig.ts +3 -0
  118. package/project/.sdk/src/cmp/zig/TestClean_zig.ts +791 -0
  119. package/project/.sdk/src/cmp/zig/Test_zig.ts +5 -0
  120. package/project/.sdk/src/cmp/zig/fragment/Build.fragment.zig +19 -0
  121. package/project/.sdk/src/cmp/zig/fragment/Entity.fragment.zig +14 -5
  122. package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +1 -1
  123. package/project/.sdk/tm/c/core/context.c +25 -0
  124. package/project/.sdk/tm/c/core/error.c +16 -0
  125. package/project/.sdk/tm/c/core/sdk.h +22 -0
  126. package/project/.sdk/tm/c/feature/audit.c +2 -0
  127. package/project/.sdk/tm/c/feature/cost.c +1 -0
  128. package/project/.sdk/tm/c/feature/debug.c +19 -29
  129. package/project/.sdk/tm/c/feature/log.c +21 -2
  130. package/project/.sdk/tm/c/feature/proxy.c +55 -3
  131. package/project/.sdk/tm/c/feature/secrets.c +7 -0
  132. package/project/.sdk/tm/c/feature/telemetry.c +2 -0
  133. package/project/.sdk/tm/c/tests/feature_test.c +2 -2
  134. package/project/.sdk/tm/c/utility/clean.c +530 -8
  135. package/project/.sdk/tm/c/utility/done.c +28 -12
  136. package/project/.sdk/tm/c/utility/make_error.c +4 -3
  137. package/project/.sdk/tm/c/utility/make_options.c +71 -45
  138. package/project/.sdk/tm/clojure/feature/secrets/sdk/feature/secrets.clj +15 -0
  139. package/project/.sdk/tm/clojure/src/sdk/client.clj +20 -4
  140. package/project/.sdk/tm/clojure/src/sdk/core.clj +319 -35
  141. package/project/.sdk/tm/clojure/src/sdk/features.clj +68 -30
  142. package/project/.sdk/tm/clojure/test/sdk/test/feature.clj +4 -2
  143. package/project/.sdk/tm/clojure/test/sdk/test/pipeline.clj +47 -20
  144. package/project/.sdk/tm/clojure/test/sdk/test_runner.clj +4 -0
  145. package/project/.sdk/tm/cpp/core/types.hpp +93 -3
  146. package/project/.sdk/tm/cpp/feature/audit.hpp +1 -0
  147. package/project/.sdk/tm/cpp/feature/cost.hpp +1 -0
  148. package/project/.sdk/tm/cpp/feature/debug.hpp +20 -12
  149. package/project/.sdk/tm/cpp/feature/log.hpp +31 -9
  150. package/project/.sdk/tm/cpp/feature/proxy.hpp +52 -6
  151. package/project/.sdk/tm/cpp/feature/secrets.hpp +13 -0
  152. package/project/.sdk/tm/cpp/feature/telemetry.hpp +4 -2
  153. package/project/.sdk/tm/cpp/test/feature_test.cpp +2 -2
  154. package/project/.sdk/tm/cpp/utility/pipeline.hpp +426 -51
  155. package/project/.sdk/tm/csharp/core/Context.cs +32 -0
  156. package/project/.sdk/tm/csharp/core/Utility.cs +2 -0
  157. package/project/.sdk/tm/csharp/feature/AuditFeature.cs +1 -0
  158. package/project/.sdk/tm/csharp/feature/CostFeature.cs +7 -5
  159. package/project/.sdk/tm/csharp/feature/DebugFeature.cs +19 -16
  160. package/project/.sdk/tm/csharp/feature/FeatureOptions.cs +16 -0
  161. package/project/.sdk/tm/csharp/feature/LogFeature.cs +4 -1
  162. package/project/.sdk/tm/csharp/feature/ProxyFeature.cs +26 -5
  163. package/project/.sdk/tm/csharp/feature/SecretsFeature.cs +16 -0
  164. package/project/.sdk/tm/csharp/feature/TelemetryFeature.cs +4 -2
  165. package/project/.sdk/tm/csharp/test/FeatureTest.cs +2 -2
  166. package/project/.sdk/tm/csharp/utility/Clean.cs +440 -2
  167. package/project/.sdk/tm/csharp/utility/Done.cs +27 -11
  168. package/project/.sdk/tm/csharp/utility/MakeError.cs +19 -8
  169. package/project/.sdk/tm/csharp/utility/MakeOptions.cs +119 -29
  170. package/project/.sdk/tm/csharp/utility/MakeResponse.cs +21 -11
  171. package/project/.sdk/tm/csharp/utility/Register.cs +1 -0
  172. package/project/.sdk/tm/elixir/lib/projectname/context.ex +19 -0
  173. package/project/.sdk/tm/elixir/lib/projectname/entity_base.ex +22 -1
  174. package/project/.sdk/tm/elixir/lib/projectname/error.ex +24 -0
  175. package/project/.sdk/tm/elixir/lib/projectname/feature/audit.ex +2 -2
  176. package/project/.sdk/tm/elixir/lib/projectname/feature/cost.ex +2 -2
  177. package/project/.sdk/tm/elixir/lib/projectname/feature/debug.ex +13 -13
  178. package/project/.sdk/tm/elixir/lib/projectname/feature/log.ex +18 -5
  179. package/project/.sdk/tm/elixir/lib/projectname/feature/proxy.ex +19 -1
  180. package/project/.sdk/tm/elixir/lib/projectname/feature/secrets.ex +15 -0
  181. package/project/.sdk/tm/elixir/lib/projectname/feature/telemetry.ex +4 -2
  182. package/project/.sdk/tm/elixir/lib/projectname/feature.ex +22 -0
  183. package/project/.sdk/tm/elixir/lib/projectname/utility.ex +464 -41
  184. package/project/.sdk/tm/elixir/test/feature_test.exs +3 -2
  185. package/project/.sdk/tm/go/core/context.go +42 -0
  186. package/project/.sdk/tm/go/core/error.go +30 -10
  187. package/project/.sdk/tm/go/core/utility_type.go +2 -0
  188. package/project/.sdk/tm/go/feature/audit_feature.go +1 -0
  189. package/project/.sdk/tm/go/feature/base_feature.go +12 -0
  190. package/project/.sdk/tm/go/feature/cost_feature.go +2 -2
  191. package/project/.sdk/tm/go/feature/debug_feature.go +14 -12
  192. package/project/.sdk/tm/go/feature/log_feature.go +13 -8
  193. package/project/.sdk/tm/go/feature/proxy_feature.go +26 -6
  194. package/project/.sdk/tm/go/feature/secrets_feature.go +19 -0
  195. package/project/.sdk/tm/go/feature/telemetry_feature.go +4 -2
  196. package/project/.sdk/tm/go/test/feature_test.go +2 -2
  197. package/project/.sdk/tm/go/utility/clean.go +585 -2
  198. package/project/.sdk/tm/go/utility/done.go +29 -9
  199. package/project/.sdk/tm/go/utility/make_error.go +51 -16
  200. package/project/.sdk/tm/go/utility/make_options.go +77 -36
  201. package/project/.sdk/tm/go/utility/register.go +12 -0
  202. package/project/.sdk/tm/java/core/Context.java +29 -0
  203. package/project/.sdk/tm/java/core/SdkClient.java +4 -2
  204. package/project/.sdk/tm/java/core/Utility.java +7 -0
  205. package/project/.sdk/tm/java/feature/AuditFeature.java +6 -0
  206. package/project/.sdk/tm/java/feature/CostFeature.java +5 -0
  207. package/project/.sdk/tm/java/feature/DebugFeature.java +25 -14
  208. package/project/.sdk/tm/java/feature/LogFeature.java +11 -4
  209. package/project/.sdk/tm/java/feature/ProxyFeature.java +41 -6
  210. package/project/.sdk/tm/java/feature/SecretsFeature.java +18 -0
  211. package/project/.sdk/tm/java/feature/TelemetryFeature.java +8 -2
  212. package/project/.sdk/tm/java/test/FeatureTest.java +2 -2
  213. package/project/.sdk/tm/java/utility/Clean.java +519 -1
  214. package/project/.sdk/tm/java/utility/Done.java +1 -1
  215. package/project/.sdk/tm/java/utility/MakeError.java +5 -1
  216. package/project/.sdk/tm/java/utility/MakeOptions.java +55 -31
  217. package/project/.sdk/tm/java/utility/Register.java +4 -0
  218. package/project/.sdk/tm/js/src/Context.js +5 -1
  219. package/project/.sdk/tm/js/src/Response.js +14 -1
  220. package/project/.sdk/tm/js/src/feature/audit/AuditFeature.js +2 -2
  221. package/project/.sdk/tm/js/src/feature/cost/CostFeature.js +2 -2
  222. package/project/.sdk/tm/js/src/feature/debug/DebugFeature.js +13 -7
  223. package/project/.sdk/tm/js/src/feature/log/LogFeature.js +9 -5
  224. package/project/.sdk/tm/js/src/feature/proxy/ProxyFeature.js +19 -1
  225. package/project/.sdk/tm/js/src/feature/secrets/SecretsFeature.js +14 -0
  226. package/project/.sdk/tm/js/src/feature/telemetry/TelemetryFeature.js +4 -2
  227. package/project/.sdk/tm/js/src/utility/CleanUtility.js +294 -21
  228. package/project/.sdk/tm/js/src/utility/DoneUtility.js +17 -5
  229. package/project/.sdk/tm/js/src/utility/MakeErrorUtility.js +18 -2
  230. package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +39 -15
  231. package/project/.sdk/tm/js/src/utility/Utility.js +4 -2
  232. package/project/.sdk/tm/js/test/feature/harness.js +11 -1
  233. package/project/.sdk/tm/js/test/feature.test.js +9 -2
  234. package/project/.sdk/tm/js/test/utility/PrimaryUtility.test.js +25 -0
  235. package/project/.sdk/tm/kotlin/core/Context.kt +19 -0
  236. package/project/.sdk/tm/kotlin/core/SdkClient.kt +9 -2
  237. package/project/.sdk/tm/kotlin/core/Utility.kt +2 -0
  238. package/project/.sdk/tm/kotlin/feature/AuditFeature.kt +11 -9
  239. package/project/.sdk/tm/kotlin/feature/CostFeature.kt +8 -5
  240. package/project/.sdk/tm/kotlin/feature/DebugFeature.kt +15 -22
  241. package/project/.sdk/tm/kotlin/feature/LogFeature.kt +8 -4
  242. package/project/.sdk/tm/kotlin/feature/ProxyFeature.kt +26 -2
  243. package/project/.sdk/tm/kotlin/feature/SecretsFeature.kt +11 -0
  244. package/project/.sdk/tm/kotlin/feature/TelemetryFeature.kt +4 -2
  245. package/project/.sdk/tm/kotlin/test/FeatureTest.kt +2 -2
  246. package/project/.sdk/tm/kotlin/utility/CoreUtil.kt +447 -11
  247. package/project/.sdk/tm/kotlin/utility/MakeOptions.kt +38 -31
  248. package/project/.sdk/tm/kotlin/utility/Register.kt +1 -0
  249. package/project/.sdk/tm/lua/core/context.lua +43 -0
  250. package/project/.sdk/tm/lua/core/error.lua +36 -1
  251. package/project/.sdk/tm/lua/core/utility_type.lua +4 -0
  252. package/project/.sdk/tm/lua/feature/audit_feature.lua +2 -2
  253. package/project/.sdk/tm/lua/feature/cost_feature.lua +2 -2
  254. package/project/.sdk/tm/lua/feature/debug_feature.lua +21 -17
  255. package/project/.sdk/tm/lua/feature/log_feature.lua +2 -1
  256. package/project/.sdk/tm/lua/feature/proxy_feature.lua +23 -1
  257. package/project/.sdk/tm/lua/feature/secrets_feature.lua +18 -0
  258. package/project/.sdk/tm/lua/feature/telemetry_feature.lua +4 -2
  259. package/project/.sdk/tm/lua/test/feature/secrets/secrets_feature_test.lua +3 -2
  260. package/project/.sdk/tm/lua/test/feature_test.lua +10 -3
  261. package/project/.sdk/tm/lua/utility/clean.lua +426 -2
  262. package/project/.sdk/tm/lua/utility/clean_explain.lua +34 -0
  263. package/project/.sdk/tm/lua/utility/done.lua +1 -7
  264. package/project/.sdk/tm/lua/utility/make_error.lua +3 -1
  265. package/project/.sdk/tm/lua/utility/make_options.lua +76 -30
  266. package/project/.sdk/tm/lua/utility/register.lua +4 -1
  267. package/project/.sdk/tm/ocaml/Makefile +5 -1
  268. package/project/.sdk/tm/ocaml/feature/secrets_feature.ml +12 -1
  269. package/project/.sdk/tm/ocaml/sdk_features.ml +78 -18
  270. package/project/.sdk/tm/ocaml/sdk_helpers.ml +27 -0
  271. package/project/.sdk/tm/ocaml/sdk_runtime.ml +304 -26
  272. package/project/.sdk/tm/ocaml/sdk_types.ml +1 -0
  273. package/project/.sdk/tm/ocaml/test/feature/secrets/t_secrets.ml +3 -1
  274. package/project/.sdk/tm/ocaml/test/t_feature.ml +2 -2
  275. package/project/.sdk/tm/perl/core/context.pm +27 -0
  276. package/project/.sdk/tm/perl/core/error.pm +52 -5
  277. package/project/.sdk/tm/perl/feature/audit_feature.pm +2 -2
  278. package/project/.sdk/tm/perl/feature/cost_feature.pm +2 -2
  279. package/project/.sdk/tm/perl/feature/debug_feature.pm +17 -13
  280. package/project/.sdk/tm/perl/feature/log_feature.pm +3 -1
  281. package/project/.sdk/tm/perl/feature/proxy_feature.pm +21 -1
  282. package/project/.sdk/tm/perl/feature/secrets_feature.pm +20 -1
  283. package/project/.sdk/tm/perl/feature/telemetry_feature.pm +4 -2
  284. package/project/.sdk/tm/perl/t/feature.t +4 -2
  285. package/project/.sdk/tm/perl/utility/clean.pm +345 -1
  286. package/project/.sdk/tm/perl/utility/done.pm +24 -6
  287. package/project/.sdk/tm/perl/utility/make_error.pm +17 -4
  288. package/project/.sdk/tm/perl/utility/make_options.pm +33 -14
  289. package/project/.sdk/tm/php/core/Context.php +24 -1
  290. package/project/.sdk/tm/php/core/Error.php +34 -3
  291. package/project/.sdk/tm/php/core/UtilityType.php +4 -0
  292. package/project/.sdk/tm/php/feature/AuditFeature.php +2 -2
  293. package/project/.sdk/tm/php/feature/CostFeature.php +2 -2
  294. package/project/.sdk/tm/php/feature/DebugFeature.php +18 -9
  295. package/project/.sdk/tm/php/feature/LogFeature.php +5 -2
  296. package/project/.sdk/tm/php/feature/ProxyFeature.php +20 -1
  297. package/project/.sdk/tm/php/feature/SecretsFeature.php +18 -0
  298. package/project/.sdk/tm/php/feature/TelemetryFeature.php +4 -2
  299. package/project/.sdk/tm/php/test/FeatureTest.php +2 -2
  300. package/project/.sdk/tm/php/utility/Clean.php +438 -2
  301. package/project/.sdk/tm/php/utility/Done.php +14 -7
  302. package/project/.sdk/tm/php/utility/MakeError.php +9 -7
  303. package/project/.sdk/tm/php/utility/MakeOptions.php +62 -38
  304. package/project/.sdk/tm/php/utility/Register.php +2 -0
  305. package/project/.sdk/tm/py/pkg/core/context.py +17 -0
  306. package/project/.sdk/tm/py/pkg/core/error.py +42 -1
  307. package/project/.sdk/tm/py/pkg/core/utility_type.py +4 -0
  308. package/project/.sdk/tm/py/pkg/feature/audit_feature.py +2 -2
  309. package/project/.sdk/tm/py/pkg/feature/cost_feature.py +2 -2
  310. package/project/.sdk/tm/py/pkg/feature/debug_feature.py +17 -12
  311. package/project/.sdk/tm/py/pkg/feature/log_feature.py +2 -1
  312. package/project/.sdk/tm/py/pkg/feature/proxy_feature.py +18 -1
  313. package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +12 -0
  314. package/project/.sdk/tm/py/pkg/feature/telemetry_feature.py +4 -2
  315. package/project/.sdk/tm/py/pkg/utility/clean.py +311 -1
  316. package/project/.sdk/tm/py/pkg/utility/done.py +18 -5
  317. package/project/.sdk/tm/py/pkg/utility/make_error.py +9 -6
  318. package/project/.sdk/tm/py/pkg/utility/make_options.py +64 -25
  319. package/project/.sdk/tm/py/pkg/utility/make_response.py +19 -13
  320. package/project/.sdk/tm/py/pkg/utility/register.py +4 -2
  321. package/project/.sdk/tm/py/test/feature_harness.py +4 -0
  322. package/project/.sdk/tm/py/test/test_feature.py +2 -2
  323. package/project/.sdk/tm/py/test/test_primary_utility.py +1 -0
  324. package/project/.sdk/tm/rb/core/context.rb +28 -0
  325. package/project/.sdk/tm/rb/core/error.rb +30 -0
  326. package/project/.sdk/tm/rb/core/utility_type.rb +1 -1
  327. package/project/.sdk/tm/rb/feature/audit_feature.rb +2 -2
  328. package/project/.sdk/tm/rb/feature/cost_feature.rb +2 -2
  329. package/project/.sdk/tm/rb/feature/debug_feature.rb +15 -12
  330. package/project/.sdk/tm/rb/feature/log_feature.rb +3 -1
  331. package/project/.sdk/tm/rb/feature/proxy_feature.rb +25 -1
  332. package/project/.sdk/tm/rb/feature/secrets_feature.rb +17 -0
  333. package/project/.sdk/tm/rb/feature/telemetry_feature.rb +4 -2
  334. package/project/.sdk/tm/rb/test/feature_test.rb +4 -2
  335. package/project/.sdk/tm/rb/utility/clean.rb +312 -1
  336. package/project/.sdk/tm/rb/utility/done.rb +15 -5
  337. package/project/.sdk/tm/rb/utility/make_error.rb +13 -4
  338. package/project/.sdk/tm/rb/utility/make_options.rb +31 -12
  339. package/project/.sdk/tm/rb/utility/register.rb +2 -0
  340. package/project/.sdk/tm/rust/core/context.rs +55 -0
  341. package/project/.sdk/tm/rust/core/utility_type.rs +17 -0
  342. package/project/.sdk/tm/rust/feature/audit.rs +2 -0
  343. package/project/.sdk/tm/rust/feature/cost.rs +3 -2
  344. package/project/.sdk/tm/rust/feature/debug.rs +16 -16
  345. package/project/.sdk/tm/rust/feature/log.rs +42 -7
  346. package/project/.sdk/tm/rust/feature/proxy.rs +48 -2
  347. package/project/.sdk/tm/rust/feature/secrets.rs +12 -0
  348. package/project/.sdk/tm/rust/feature/telemetry.rs +2 -0
  349. package/project/.sdk/tm/rust/tests/feature_test.rs +2 -2
  350. package/project/.sdk/tm/rust/utility/clean.rs +446 -5
  351. package/project/.sdk/tm/rust/utility/done.rs +22 -12
  352. package/project/.sdk/tm/rust/utility/make_error.rs +4 -1
  353. package/project/.sdk/tm/rust/utility/make_options.rs +73 -19
  354. package/project/.sdk/tm/scala/Makefile +3 -1
  355. package/project/.sdk/tm/scala/core/Context.scala +16 -0
  356. package/project/.sdk/tm/scala/core/SdkClient.scala +14 -4
  357. package/project/.sdk/tm/scala/core/SdkError.scala +28 -0
  358. package/project/.sdk/tm/scala/core/Types.scala +3 -0
  359. package/project/.sdk/tm/scala/core/Utility.scala +2 -0
  360. package/project/.sdk/tm/scala/feature/AuditFeature.scala +16 -10
  361. package/project/.sdk/tm/scala/feature/CostFeature.scala +10 -5
  362. package/project/.sdk/tm/scala/feature/DebugFeature.scala +24 -21
  363. package/project/.sdk/tm/scala/feature/LogFeature.scala +9 -4
  364. package/project/.sdk/tm/scala/feature/ProxyFeature.scala +23 -2
  365. package/project/.sdk/tm/scala/feature/SecretsFeature.scala +14 -0
  366. package/project/.sdk/tm/scala/feature/TelemetryFeature.scala +9 -2
  367. package/project/.sdk/tm/scala/sdktest/SdkTestMain.scala +2 -2
  368. package/project/.sdk/tm/scala/utility/Make.scala +63 -20
  369. package/project/.sdk/tm/scala/utility/Misc.scala +358 -5
  370. package/project/.sdk/tm/scala/utility/Register.scala +1 -0
  371. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Context.swift +29 -0
  372. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Utility.swift +2 -0
  373. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/AuditFeature.swift +10 -9
  374. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/CostFeature.swift +7 -5
  375. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/DebugFeature.swift +19 -15
  376. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/FeatureOptions.swift +16 -0
  377. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/LogFeature.swift +4 -1
  378. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/ProxyFeature.swift +20 -5
  379. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/SecretsFeature.swift +13 -0
  380. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/TelemetryFeature.swift +4 -2
  381. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeError.swift +15 -5
  382. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +58 -19
  383. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Register.swift +1 -0
  384. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/ResultUtil.swift +391 -4
  385. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/FeatureTest.swift +2 -2
  386. package/project/.sdk/tm/ts/src/Context.ts +5 -1
  387. package/project/.sdk/tm/ts/src/Response.ts +14 -1
  388. package/project/.sdk/tm/ts/src/feature/audit/AuditFeature.ts +2 -2
  389. package/project/.sdk/tm/ts/src/feature/cost/CostFeature.ts +2 -2
  390. package/project/.sdk/tm/ts/src/feature/debug/DebugFeature.ts +13 -7
  391. package/project/.sdk/tm/ts/src/feature/log/LogFeature.ts +9 -5
  392. package/project/.sdk/tm/ts/src/feature/proxy/ProxyFeature.ts +19 -1
  393. package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +12 -0
  394. package/project/.sdk/tm/ts/src/feature/telemetry/TelemetryFeature.ts +4 -2
  395. package/project/.sdk/tm/ts/src/utility/CleanUtility.ts +287 -9
  396. package/project/.sdk/tm/ts/src/utility/DoneUtility.ts +18 -5
  397. package/project/.sdk/tm/ts/src/utility/MakeErrorUtility.ts +18 -8
  398. package/project/.sdk/tm/ts/src/utility/MakeOptionsUtility.ts +38 -16
  399. package/project/.sdk/tm/ts/src/utility/Utility.ts +4 -2
  400. package/project/.sdk/tm/ts/test/feature/harness.ts +11 -1
  401. package/project/.sdk/tm/ts/test/feature.test.ts +9 -2
  402. package/project/.sdk/tm/ts/test/utility/PrimaryUtility.test.ts +25 -0
  403. package/project/.sdk/tm/zig/core/context.zig +34 -0
  404. package/project/.sdk/tm/zig/core/error.zig +22 -1
  405. package/project/.sdk/tm/zig/core/utility.zig +403 -39
  406. package/project/.sdk/tm/zig/feature/audit.zig +4 -2
  407. package/project/.sdk/tm/zig/feature/cost.zig +3 -2
  408. package/project/.sdk/tm/zig/feature/debug.zig +20 -25
  409. package/project/.sdk/tm/zig/feature/log.zig +3 -1
  410. package/project/.sdk/tm/zig/feature/proxy.zig +47 -6
  411. package/project/.sdk/tm/zig/feature/secrets.zig +7 -0
  412. package/project/.sdk/tm/zig/feature/telemetry.zig +4 -2
  413. package/project/.sdk/tm/zig/test/feature_test.zig +2 -2
  414. package/project/sdkgen-package.json +1 -1
  415. package/src/helpers/naming.ts +1 -1
@@ -471,7 +471,7 @@ object SdkTestMain {
471
471
  val h = fhMake(null, fhF(f, om("max" -> I(1), "onEntry" -> oe)))
472
472
  h.op(fhOp("load").withHeaders(om("authorization" -> "Bearer secret"))); h.op(fhOp("list"))
473
473
  eqI("debug.ring", 1, f.entries.size()); eqI("debug.onEntry", 2, seen.size())
474
- eq("debug.redacted", "<redacted>", Helpers.toMapAny(seen.get(0).get("headers")).get("authorization")) }
474
+ eq("debug.redacted", "[redacted]", Helpers.toMapAny(seen.get(0).get("headers")).get("authorization")) }
475
475
  { val f = new DebugFeature()
476
476
  val h = fhMake(null, fhF(new NetsimFeature(), om("failTimes" -> I(1), "failStatus" -> I(500))), fhF(f, null))
477
477
  h.op(fhOp("load")); eqI("debug.fail.n", 1, f.entries.size()); eq("debug.fail.ok", B(false), f.entries.get(0).get("ok")) }
@@ -479,7 +479,7 @@ object SdkTestMain {
479
479
  val h = fhMake(null, fhF(f, om("now" -> f0(clk.nowFn), "redact" -> jl("x-secret"))))
480
480
  h.op(fhOp("load").withHeaders(om("x-secret" -> "hide", "x-ok" -> "show")))
481
481
  val dh = Helpers.toMapAny(f.entries.get(0).get("headers"))
482
- eq("debug.redact.secret", "<redacted>", dh.get("x-secret")); eq("debug.redact.ok", "show", dh.get("x-ok")) }
482
+ eq("debug.redact.secret", "[redacted]", dh.get("x-secret")); eq("debug.redact.ok", "show", dh.get("x-ok")) }
483
483
  { val f = new DebugFeature()
484
484
  val h = fhMake(null, fhF(f, om("active" -> B(false))))
485
485
  h.op(fhOp("load")); eqI("debug.inactive", 0, f.entries.size()) }
@@ -33,6 +33,7 @@ object MakeError {
33
33
  val spec = ctx.spec
34
34
 
35
35
  if (ctx.ctrl.explain != null) {
36
+ Clean.cleanExplain(ctx)
36
37
  val errRecord = new LinkedHashMap[String, Object]()
37
38
  errRecord.put("message", msg)
38
39
  ctx.ctrl.explain.put("err", errRecord)
@@ -44,6 +45,7 @@ object MakeError {
44
45
  val sdkErr = new SdkError(code, msg, ctx)
45
46
  sdkErr.result = Clean.clean(ctx, result)
46
47
  sdkErr.spec = Clean.clean(ctx, spec)
48
+ sdkErr.status = result.status
47
49
 
48
50
  ctx.ctrl.err = sdkErr
49
51
 
@@ -266,6 +268,29 @@ object MakeOptions {
266
268
  // null check, which cannot distinguish them.
267
269
  val authSuppressed = options.containsKey("auth") && null == options.get("auth")
268
270
 
271
+ var config = ctx.config
272
+ if (config == null) config = new LinkedHashMap[String, Object]()
273
+ var cfgopts = Helpers.toMapAny(config.get("options"))
274
+ if (cfgopts == null) cfgopts = new LinkedHashMap[String, Object]()
275
+
276
+ // The secret registry exists BEFORE validation, fed from the raw input, so
277
+ // the constructor's own rejection of a mistyped credential is clean too.
278
+ // An absent layer is left out: merge lets a null replace everything before it.
279
+ val cleanlist = new ArrayList[Object]()
280
+ cleanlist.add(new LinkedHashMap[String, Object]())
281
+ for (layer <- List(Schema.optspec.get("clean"), cfgopts.get("clean"), options.get("clean"))
282
+ if layer != null) {
283
+ cleanlist.add(Struct.clone(layer))
284
+ }
285
+ val cleancfg = Clean.makeCleanConfig(Struct.merge(cleanlist))
286
+ addSensitiveOptions(cleancfg, options, "clean")
287
+ for (block <- List(cfgopts.get("clean"), options.get("clean"))) {
288
+ val bm = Helpers.toMapAny(block)
289
+ for (raw <- Clean.splitvalues(if (bm == null) null else bm.get("values"))) {
290
+ Clean.registerValue(cleancfg, raw)
291
+ }
292
+ }
293
+
269
294
  var opts = Struct.clone(options).asInstanceOf[JMap[String, Object]]
270
295
 
271
296
  if (authSuppressed) opts.remove("auth")
@@ -298,11 +323,6 @@ object MakeOptions {
298
323
  case _ =>
299
324
  }
300
325
 
301
- var config = ctx.config
302
- if (config == null) config = new LinkedHashMap[String, Object]()
303
- var cfgopts = Helpers.toMapAny(config.get("options"))
304
- if (cfgopts == null) cfgopts = new LinkedHashMap[String, Object]()
305
-
306
326
  // THE OPTION SPEC IS GENERATED, NOT WRITTEN HERE.
307
327
  //
308
328
  // Built from the model: `main.kit.optspec` for the standard options, plus
@@ -330,9 +350,17 @@ object MakeOptions {
330
350
  mergeList.add(opts)
331
351
  val merged = Struct.merge(mergeList)
332
352
 
353
+ // Errors are collected, not thrown, so a mistyped option is not rejected.
333
354
  val vopts = new LinkedHashMap[String, Object]()
334
355
  vopts.put("errs", new ArrayList[Object]())
335
- val validated = Struct.validate(merged, optspec, vopts)
356
+ val validated =
357
+ try Struct.validate(merged, optspec, vopts)
358
+ catch {
359
+ // A rejection quotes the value it rejected.
360
+ case err: RuntimeException =>
361
+ val text = if (err.getMessage == null) String.valueOf(err) else err.getMessage
362
+ throw new SdkError("options_invalid", Clean.cleanWith(cleancfg, text).asInstanceOf[String], ctx)
363
+ }
336
364
  opts = validated.asInstanceOf[JMap[String, Object]]
337
365
 
338
366
  // Restore the suppression the optspec default would otherwise erase.
@@ -345,17 +373,6 @@ object MakeOptions {
345
373
  else { val sm = new LinkedHashMap[String, Object](); sm.put("fetch", sysFetch); opts.put("system", sm) }
346
374
  }
347
375
 
348
- // Derived clean config.
349
- var cleanKeys = "key,token,id"
350
- Struct.getpath(opts, java.util.List.of("clean", "keys")) match { case s: String => cleanKeys = s; case _ => }
351
-
352
- val filtered = new ArrayList[String]()
353
- for (p0 <- cleanKeys.split(",")) {
354
- val p = p0.trim
355
- if ("" != p) filtered.add(Struct.escre(p))
356
- }
357
- val keyre = String.join("|", filtered)
358
-
359
376
  // Resolve the feature add-order: an explicit list order (above) wins;
360
377
  // otherwise order the map test-first, then the remaining names sorted, so
361
378
  // the outcome is deterministic and `test` is always the base transport.
@@ -374,14 +391,40 @@ object MakeOptions {
374
391
  }
375
392
 
376
393
  val derived = new LinkedHashMap[String, Object]()
377
- val derivedClean = new LinkedHashMap[String, Object]()
378
- if ("" != keyre) derivedClean.put("keyre", keyre)
379
- derived.put("clean", derivedClean)
394
+ derived.put("clean", cleancfg)
380
395
  derived.put("featureorder", featureorder)
381
396
  opts.put("__derived__", derived)
382
397
 
398
+ // Again over the merged result: the config's own defaults can carry one.
399
+ addSensitiveOptions(cleancfg, opts, "clean", "__derived__")
400
+
383
401
  opts
384
402
  }
403
+
404
+ // A feature's name is not a field name: a feature called `secrets` does not
405
+ // make every one of its options a secret. Entity blocks (entity settings,
406
+ // seeded records) hold no credential.
407
+ private def addSensitiveOptions(cfg: CleanConfig, m: JMap[String, Object], keys: String*): Unit = {
408
+ val top = omit(m, (keys :+ "feature" :+ "entity")*)
409
+ if (top.containsKey("test")) top.put("test", noEntity(top.get("test")))
410
+ Clean.addSensitiveWith(cfg, top)
411
+ m.get("feature") match {
412
+ case fm: JMap[_, _] => fm.values().forEach(v => Clean.addSensitiveWith(cfg, noEntity(v.asInstanceOf[Object])))
413
+ case fl: JList[_] => fl.forEach(v => Clean.addSensitiveWith(cfg, noEntity(v.asInstanceOf[Object])))
414
+ case other => Clean.addSensitiveWith(cfg, other)
415
+ }
416
+ }
417
+
418
+ private def noEntity(block: Object): Object = block match {
419
+ case bm: JMap[_, _] => omit(bm.asInstanceOf[JMap[String, Object]], "entity")
420
+ case other => other
421
+ }
422
+
423
+ private def omit(m: JMap[String, Object], keys: String*): JMap[String, Object] = {
424
+ val out = new LinkedHashMap[String, Object](m)
425
+ keys.foreach(k => out.remove(k))
426
+ out
427
+ }
385
428
  }
386
429
 
387
430
  object MakeFetchDef {
@@ -1,6 +1,8 @@
1
1
  package SCALAPACKAGE.utility
2
2
 
3
- import java.util.{Map => JMap}
3
+ import java.io.{PrintWriter, StringWriter}
4
+ import java.nio.charset.StandardCharsets
5
+ import java.util.{ArrayList, Base64, IdentityHashMap, LinkedHashMap, List => JList, Map => JMap}
4
6
  import SCALAPACKAGE.core._
5
7
  import SCALAPACKAGE.utility.struct.Struct
6
8
 
@@ -9,16 +11,367 @@ object MakeContext {
9
11
  new Context(ctxmap, basectx)
10
12
  }
11
13
 
14
+ // The derived clean block: built by makeOptions from the raw input, grown by
15
+ // cleanAdd for as long as the client lives (features register later).
16
+ final class CleanConfig(
17
+ val active: Boolean,
18
+ val keys: List[String],
19
+ val values: ArrayList[String],
20
+ val mask: String,
21
+ val hint: Int,
22
+ val min: Int,
23
+ ) {
24
+ // The options map this sits in can itself be printed; the registry never is.
25
+ override def toString: String = "CleanConfig(active=" + active + ")"
26
+ }
27
+
28
+ // Everything that leaves the pipeline passes through clean; inside it data
29
+ // stays raw, so a hook can still read the header it must add to. See
30
+ // docs/explanation/secret-redaction.md.
12
31
  object Clean {
13
- def clean(ctx: Context, v: Object): Object = v
32
+ private val MAXDEPTH = 32
33
+ private val CIRCULAR = "[circular]"
34
+ private val DROP = new Object()
35
+ private val SPLIT_RE = "\\s*,\\s*"
36
+
37
+ private def normkey(key: Object): String =
38
+ String.valueOf(key).toLowerCase.replace("-", "").replace("_", "")
39
+
40
+ private def splitkeys(keys: Object): List[String] =
41
+ (if (keys == null) "" else String.valueOf(keys)).split(SPLIT_RE).toList
42
+ .map(k => normkey(k)).filter(k => "" != k)
43
+
44
+ def splitvalues(values: Object): List[String] = values match {
45
+ case null => Nil
46
+ case l: JList[_] => l.asInstanceOf[JList[Object]].toArray.toList.collect { case s: String => s }
47
+ case v => String.valueOf(v).split(SPLIT_RE).toList.filter(s => "" != s)
48
+ }
49
+
50
+ private def count(v: Object, dflt: Int): Int = {
51
+ val n: Double = v match {
52
+ case n: java.lang.Number => n.doubleValue()
53
+ case s: String =>
54
+ try s.trim.toDouble
55
+ catch { case _: NumberFormatException => return dflt }
56
+ case _ => return dflt
57
+ }
58
+ if (n.isNaN || n.isInfinite || n < 0) dflt else Math.floor(n).toInt
59
+ }
60
+
61
+ def makeCleanConfig(cleanopts: Object): CleanConfig = {
62
+ val opts = Helpers.toMapAny(cleanopts)
63
+ def get(k: String): Object = if (opts == null) null else opts.get(k)
64
+ new CleanConfig(
65
+ java.lang.Boolean.FALSE != get("active"),
66
+ splitkeys(get("keys")),
67
+ new ArrayList[String](),
68
+ get("mask") match { case s: String => s; case _ => "[redacted]" },
69
+ count(get("hint"), 0),
70
+ Math.max(1, count(get("min"), 4)),
71
+ )
72
+ }
73
+
74
+ // A context without options (makeError accepts a bare one) still masks by
75
+ // the schema defaults.
76
+ private def cleanConfig(ctx: Context): CleanConfig = {
77
+ if (ctx != null && ctx.options != null) {
78
+ val derived = Helpers.toMapAny(ctx.options.get("__derived__"))
79
+ if (derived != null) derived.get("clean") match {
80
+ case c: CleanConfig => return c
81
+ case _ =>
82
+ }
83
+ }
84
+ makeCleanConfig(Schema.optspec.get("clean"))
85
+ }
86
+
87
+ // encodeURIComponent, byte for byte: URLEncoder differs on space and `~!'()*`.
88
+ private def percentEncode(value: String): String = {
89
+ val out = new StringBuilder()
90
+ for (b <- value.getBytes(StandardCharsets.UTF_8)) {
91
+ val c = b & 0xff
92
+ val ch = c.toChar
93
+ if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') ||
94
+ "-_.!~*'()".indexOf(ch) >= 0) out.append(ch)
95
+ else out.append('%').append(String.format("%02X", java.lang.Integer.valueOf(c)))
96
+ }
97
+ out.toString
98
+ }
99
+
100
+ // The encoded forms a value travels in.
101
+ private def forms(value: String): List[String] = {
102
+ val out = new ArrayList[String]()
103
+ out.add(value)
104
+ def add(s: String): Unit = if ("" != s && !out.contains(s)) out.add(s)
105
+ try add(Base64.getEncoder.encodeToString(value.getBytes(StandardCharsets.UTF_8)))
106
+ catch { case _: RuntimeException => }
107
+ try add(percentEncode(value))
108
+ catch { case _: RuntimeException => }
109
+ try {
110
+ val j = Struct.jsonify(value)
111
+ if (j.length >= 2) add(j.substring(1, j.length - 1))
112
+ }
113
+ catch { case _: RuntimeException => }
114
+ out.toArray(new Array[String](0)).toList
115
+ }
116
+
117
+ private[utility] def registerValue(cfg: CleanConfig, value: Object): Unit = value match {
118
+ case s: String if s.length >= cfg.min =>
119
+ cfg.synchronized {
120
+ var changed = false
121
+ for (form <- forms(s)) {
122
+ if (form.length >= cfg.min && !cfg.values.contains(form)) {
123
+ cfg.values.add(form)
124
+ changed = true
125
+ }
126
+ }
127
+ if (changed) cfg.values.sort(new java.util.Comparator[String] {
128
+ def compare(a: String, b: String): Int = Integer.compare(b.length, a.length)
129
+ })
130
+ }
131
+ case _ =>
132
+ }
133
+
134
+ def cleanAdd(ctx: Context, value: Object): Unit = registerValue(cleanConfig(ctx), value)
135
+
136
+ private def maskValue(cfg: CleanConfig, value: String): String =
137
+ if (0 < cfg.hint && value.length > 2 * cfg.hint) cfg.mask + value.substring(value.length - cfg.hint)
138
+ else cfg.mask
139
+
140
+ private def cleanString(cfg: CleanConfig, text: String): String = {
141
+ val values = cfg.synchronized { new ArrayList[String](cfg.values) }
142
+ var out = text
143
+ val it = values.iterator()
144
+ while (it.hasNext) {
145
+ val v = it.next()
146
+ if (out.contains(v)) out = out.replace(v, maskValue(cfg, v))
147
+ }
148
+ out
149
+ }
150
+
151
+ private def sensitiveKey(cfg: CleanConfig, key: Object): Boolean = {
152
+ if (key == null || key.isInstanceOf[java.lang.Number]) return false
153
+ val nk = normkey(key)
154
+ cfg.keys.exists(k => nk.contains(k))
155
+ }
156
+
157
+ private def isfunc(v: Object): Boolean = {
158
+ val cls = v.getClass
159
+ cls.isSynthetic || cls.getInterfaces.exists { i =>
160
+ i.getName.startsWith("java.util.function.") || i.getName.startsWith("scala.Function")
161
+ }
162
+ }
163
+
164
+ private def stackOf(err: Throwable): String = {
165
+ val sw = new StringWriter()
166
+ err.printStackTrace(new PrintWriter(sw))
167
+ sw.toString
168
+ }
169
+
170
+ // The SDK's own objects have no serialisation hook, so this is the record
171
+ // each one leaves as. The context stays raw on the error and is not here.
172
+ private def record(v: Object): JMap[String, Object] = {
173
+ val out = new LinkedHashMap[String, Object]()
174
+ v match {
175
+ case e: Throwable =>
176
+ out.put("message", if (e.getMessage == null) "" else e.getMessage)
177
+ out.put("stack", stackOf(e))
178
+ e match {
179
+ case se: SdkError =>
180
+ out.put("sdk", se.sdk)
181
+ out.put("code", se.code)
182
+ out.put("status", java.lang.Integer.valueOf(se.status))
183
+ out.put("result", se.result)
184
+ out.put("spec", se.spec)
185
+ case _ =>
186
+ }
187
+ case s: Spec =>
188
+ out.put("method", s.method)
189
+ out.put("base", s.base)
190
+ out.put("prefix", s.prefix)
191
+ out.put("suffix", s.suffix)
192
+ out.put("path", s.path)
193
+ out.put("url", s.url)
194
+ out.put("params", s.params)
195
+ out.put("query", s.query)
196
+ out.put("headers", s.headers)
197
+ out.put("body", s.body)
198
+ out.put("step", s.step)
199
+ case r: Result =>
200
+ out.put("ok", java.lang.Boolean.valueOf(r.ok))
201
+ out.put("status", java.lang.Integer.valueOf(r.status))
202
+ out.put("statusText", r.statusText)
203
+ out.put("headers", r.headers)
204
+ out.put("body", r.body)
205
+ out.put("resdata", r.resdata)
206
+ out.put("resmatch", r.resmatch)
207
+ out.put("err", r.err)
208
+ out.put("paging", r.paging)
209
+ case r: Response =>
210
+ out.put("status", java.lang.Integer.valueOf(r.status))
211
+ out.put("statusText", r.statusText)
212
+ out.put("headers", r.headers)
213
+ out.put("body", r.body)
214
+ out.put("err", r.err)
215
+ case o: Operation =>
216
+ out.put("entity", o.entity)
217
+ out.put("name", o.name)
218
+ out.put("input", o.input)
219
+ case c: Context =>
220
+ out.put("id", c.id)
221
+ out.put("op", c.op)
222
+ out.put("spec", c.spec)
223
+ out.put("entity", c.entity)
224
+ out.put("result", c.result)
225
+ out.put("response", c.response)
226
+ out.put("meta", c.meta)
227
+ case e: Entity =>
228
+ out.put("name", e.getName())
229
+ out.put("data", try e.data() catch { case _: RuntimeException => null })
230
+ case _ =>
231
+ }
232
+ out
233
+ }
234
+
235
+ // A masked plain-data copy: functions dropped, cycles cut, and nothing
236
+ // shared with the live value, whose spec must stay raw.
237
+ private def snapshot(cfg: CleanConfig, v: Object, key: Object, depth: Int,
238
+ seen: IdentityHashMap[Object, Object]): Object = {
239
+ if (v == null || (v eq Struct.UNDEF)) return v
240
+
241
+ v match {
242
+ case s: String => return if (sensitiveKey(cfg, key)) maskValue(cfg, s) else cleanString(cfg, s)
243
+ case _ =>
244
+ }
245
+
246
+ if (isfunc(v)) return DROP
247
+
248
+ v match {
249
+ case _: java.lang.Number | _: java.lang.Boolean | _: java.lang.Character =>
250
+ return if (sensitiveKey(cfg, key)) cfg.mask else v
251
+ case _ =>
252
+ }
253
+
254
+ if (MAXDEPTH <= depth || seen.containsKey(v)) return CIRCULAR
255
+
256
+ if (sensitiveKey(cfg, key)) return cfg.mask
257
+
258
+ seen.put(v, v)
259
+ try {
260
+ v match {
261
+ case l: JList[_] =>
262
+ val out = new ArrayList[Object]()
263
+ var i = 0
264
+ val it = l.asInstanceOf[JList[Object]].iterator()
265
+ while (it.hasNext) {
266
+ val s = snapshot(cfg, it.next(), java.lang.Integer.valueOf(i), depth + 1, seen)
267
+ if (s ne DROP) out.add(s)
268
+ i += 1
269
+ }
270
+ out
271
+ case m: JMap[_, _] => plain(cfg, m, depth, seen)
272
+ case _: Throwable | _: Spec | _: Result | _: Response | _: Operation | _: Context | _: Entity =>
273
+ plain(cfg, record(v), depth, seen)
274
+ case _ => cleanString(cfg, v.toString)
275
+ }
276
+ }
277
+ finally seen.remove(v)
278
+ }
279
+
280
+ private def plain(cfg: CleanConfig, m: JMap[_, _], depth: Int,
281
+ seen: IdentityHashMap[Object, Object]): JMap[String, Object] = {
282
+ val out = new LinkedHashMap[String, Object]()
283
+ val it = m.asInstanceOf[JMap[Object, Object]].entrySet().iterator()
284
+ while (it.hasNext) {
285
+ val e = it.next()
286
+ val s = snapshot(cfg, e.getValue, e.getKey, depth + 1, seen)
287
+ if (s ne DROP) out.put(cleanName(cfg, out, String.valueOf(e.getKey)), s)
288
+ }
289
+ out
290
+ }
291
+
292
+ // A registered value used as a map key is masked like any other string;
293
+ // keys that mask alike take a counter, so none is lost.
294
+ private def cleanName(cfg: CleanConfig, out: JMap[String, Object], key: String): String = {
295
+ val name = cleanString(cfg, key)
296
+ if (name == key || !out.containsKey(name)) return name
297
+ var i = 1
298
+ while (out.containsKey(name + "#" + i)) i += 1
299
+ name + "#" + i
300
+ }
301
+
302
+ private[utility] def cleanWith(cfg: CleanConfig, value: Object): Object = {
303
+ if (!cfg.active) return value
304
+
305
+ value match {
306
+ case s: String => return cleanString(cfg, s)
307
+ case err: SdkError =>
308
+ // Cleaned in place, since it is about to be thrown.
309
+ err.msg = cleanString(cfg, err.msg)
310
+ err.code = cleanString(cfg, err.code)
311
+ err.result = snapshot(cfg, err.result, "result", 1, new IdentityHashMap[Object, Object]())
312
+ err.spec = snapshot(cfg, err.spec, "spec", 1, new IdentityHashMap[Object, Object]())
313
+ return err
314
+ // A throwable's message is fixed, so a foreign one leaves as a cleaned
315
+ // copy of the SDK's own error, without the raw one as its cause.
316
+ case t: Throwable =>
317
+ return new SdkError("", cleanString(cfg, if (t.getMessage == null) String.valueOf(t) else t.getMessage), null)
318
+ case _ =>
319
+ }
320
+
321
+ val out = snapshot(cfg, value, null, 0, new IdentityHashMap[Object, Object]())
322
+ if (out eq DROP) null else out
323
+ }
324
+
325
+ def clean(ctx: Context, v: Object): Object = cleanWith(cleanConfig(ctx), v)
326
+
327
+ def cleanKey(ctx: Context, key: Object): Boolean = sensitiveKey(cleanConfig(ctx), key)
328
+
329
+ // Every scalar under a sensitive name, at any depth and of any shape: a
330
+ // credential mistyped as a map or a number is still a credential, and a
331
+ // message about it can quote it.
332
+ private[utility] def addSensitiveWith(cfg: CleanConfig, v: Object): Unit =
333
+ addSensitive(cfg, v, false, 0, new IdentityHashMap[Object, Object]())
334
+
335
+ private def addSensitive(cfg: CleanConfig, v: Object, under: Boolean, depth: Int,
336
+ seen: IdentityHashMap[Object, Object]): Unit = {
337
+ if (v == null || MAXDEPTH <= depth) return
338
+ v match {
339
+ case s: String => if (under) registerValue(cfg, s)
340
+ case n: java.lang.Number => if (under) registerValue(cfg, Struct.stringify(n))
341
+ case _ if seen.containsKey(v) =>
342
+ case m: JMap[_, _] =>
343
+ seen.put(v, v)
344
+ val it = m.asInstanceOf[JMap[Object, Object]].entrySet().iterator()
345
+ while (it.hasNext) {
346
+ val e = it.next()
347
+ addSensitive(cfg, e.getValue, under || sensitiveKey(cfg, e.getKey), depth + 1, seen)
348
+ }
349
+ case l: JList[_] =>
350
+ seen.put(v, v)
351
+ val it = l.asInstanceOf[JList[Object]].iterator()
352
+ while (it.hasNext) addSensitive(cfg, it.next(), under, depth + 1, seen)
353
+ case _ =>
354
+ }
355
+ }
356
+
357
+ // The caller holds the explain map, so the cleaned copy is written back
358
+ // into it rather than swapped for it.
359
+ private[utility] def cleanExplain(ctx: Context): Unit = {
360
+ val explain = ctx.ctrl.explain
361
+ if (explain == null) return
362
+ val cleaned = Helpers.toMapAny(clean(ctx, explain))
363
+ if (cleaned != null && (cleaned ne explain)) {
364
+ explain.clear()
365
+ explain.putAll(cleaned)
366
+ }
367
+ }
14
368
  }
15
369
 
16
370
  object Done {
17
371
  def done(ctx: Context): Object = {
18
372
  if (ctx.ctrl.explain != null) {
19
- ctx.ctrl.explain = Clean.clean(ctx, ctx.ctrl.explain).asInstanceOf[JMap[String, Object]]
20
- val explainResult = ctx.ctrl.explain.get("result")
21
- val rm = Helpers.toMapAny(explainResult)
373
+ Clean.cleanExplain(ctx)
374
+ val rm = Helpers.toMapAny(ctx.ctrl.explain.get("result"))
22
375
  if (rm != null) rm.remove("err")
23
376
  }
24
377
 
@@ -6,6 +6,7 @@ import SCALAPACKAGE.core.Utility
6
6
  object Register {
7
7
  def registerAll(u: Utility): Unit = {
8
8
  u.clean = (ctx, v) => Clean.clean(ctx, v)
9
+ u.cleanAdd = (ctx, v) => Clean.cleanAdd(ctx, v)
9
10
  u.done = (ctx) => Done.done(ctx)
10
11
  u.makeError = (ctx, err) => MakeError.makeError(ctx, err)
11
12
  u.featureAdd = (ctx, f) => FeatureAdd.featureAdd(ctx, f)
@@ -158,4 +158,33 @@ public final class Context {
158
158
  public func makeError(_ code: String, _ msg: String) -> ProjectNameError {
159
159
  return ProjectNameError(code, msg, self)
160
160
  }
161
+
162
+ // The record form: what the context says about the operation, never its
163
+ // client, options or config.
164
+ func rawRecord() -> VMap {
165
+ let record = VMap()
166
+ record.entries["id"] = .string(id)
167
+ record.entries["op"] = op == nil ? .noval : .nat(op!)
168
+ record.entries["spec"] = spec == nil ? .noval : .nat(spec!)
169
+ record.entries["entity"] = entity == nil ? .noval : .string(entity!.getName())
170
+ record.entries["result"] = result == nil ? .noval : .nat(result!)
171
+ record.entries["response"] = response == nil ? .noval : .nat(response!)
172
+ record.entries["meta"] = .map(meta)
173
+ return record
174
+ }
175
+
176
+ // The serialised context leaves the pipeline (a logger, an error dump), so
177
+ // it is cleaned; the live fields stay raw for the pipeline's own use.
178
+ public func record() -> VMap {
179
+ let record = rawRecord()
180
+ guard let clean = utility?.clean else { return record }
181
+ return clean(self, .map(record)).asMap ?? record
182
+ }
183
+ }
184
+
185
+ // Every default print of a context is the cleaned record, `dump` included.
186
+ extension Context: CustomStringConvertible, CustomDebugStringConvertible, CustomReflectable {
187
+ public var description: String { "Context " + jsonify(.map(record()), indent: 0) }
188
+ public var debugDescription: String { description }
189
+ public var customMirror: Mirror { Mirror(self, children: ["record": jsonify(.map(record()), indent: 0)]) }
161
190
  }
@@ -6,6 +6,7 @@ import Foundation
6
6
 
7
7
  public final class Utility {
8
8
  public var clean: ((Context, Value) -> Value)!
9
+ public var cleanAdd: ((Context, Value) -> Void)!
9
10
  public var done: ((Context) throws -> Value)!
10
11
  public var makeError: ((Context, Error?) throws -> Value)!
11
12
  public var featureAdd: ((Context, BaseFeature) -> Void)!
@@ -49,6 +50,7 @@ public final class Utility {
49
50
  public static func copy(_ src: Utility) -> Utility {
50
51
  let u = Utility(noregister: true)
51
52
  u.clean = src.clean
53
+ u.cleanAdd = src.cleanAdd
52
54
  u.done = src.done
53
55
  u.makeError = src.makeError
54
56
  u.featureAdd = src.featureAdd
@@ -74,17 +74,18 @@ public final class AuditFeature: BaseFeature {
74
74
  let entity = ctx.op?.entity ?? "_"
75
75
  let opname = ctx.op?.name ?? "_"
76
76
 
77
- let record = VMap()
78
- record.entries["seq"] = .int(Int64(seq))
79
- record.entries["ts"] = .int(foptNow(options)())
80
- record.entries["actor"] = .string(actor)
81
- record.entries["entity"] = .string(entity)
82
- record.entries["op"] = .string(opname)
83
- record.entries["outcome"] = .string(outcome)
84
- record.entries["correlationId"] = .string(ctx.id)
77
+ let raw = VMap()
78
+ raw.entries["seq"] = .int(Int64(seq))
79
+ raw.entries["ts"] = .int(foptNow(options)())
80
+ raw.entries["actor"] = .string(actor)
81
+ raw.entries["entity"] = .string(entity)
82
+ raw.entries["op"] = .string(opname)
83
+ raw.entries["outcome"] = .string(outcome)
84
+ raw.entries["correlationId"] = .string(ctx.id)
85
85
  if let result = ctx.result {
86
- record.entries["status"] = .int(Int64(result.status))
86
+ raw.entries["status"] = .int(Int64(result.status))
87
87
  }
88
+ let record = fclean(ctx, raw)
88
89
 
89
90
  records.append(record)
90
91
  let max = foptInt(options, "max", 1000)
@@ -303,14 +303,16 @@ public final class CostFeature: BaseFeature {
303
303
  bump(&actors, actor, amount)
304
304
 
305
305
  seq += 1
306
+ // A typed record, so its strings are cleaned one by one rather than the
307
+ // record as a whole.
306
308
  let record = CostRecord()
307
309
  record.seq = seq
308
- record.entity = entity
309
- record.op = opname
310
- record.actor = actor
310
+ record.entity = fcleanStr(ctx, entity)
311
+ record.op = fcleanStr(ctx, opname)
312
+ record.actor = fcleanStr(ctx, actor)
311
313
  record.amount = amount
312
- record.currency = currency
313
- record.source = source
314
+ record.currency = fcleanStr(ctx, currency)
315
+ record.source = fcleanStr(ctx, source)
314
316
  record.attempts = pending.attempts
315
317
  last = record
316
318