@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
@@ -0,0 +1,804 @@
1
+ import {
2
+ cmp,
3
+ File,
4
+ Content,
5
+ isAuthSuppressed,
6
+ isHttpBasicAuth,
7
+ resolveAuthIn,
8
+ resolveAuthName,
9
+ } from '@voxgig/sdkgen'
10
+
11
+
12
+ // The canary sweep: every credential slot holds a distinctive value, every
13
+ // diagnostic feature this SDK ships is switched on with a capturing sink, a
14
+ // real operation runs through every outcome, and every string that leaves
15
+ // the SDK is searched for the canaries and their encoded forms. It also
16
+ // proves its own sensitivity: with clean switched off the canary MUST show.
17
+ const TestClean = cmp(function TestClean(props: any) {
18
+ const { model } = props.ctx$
19
+ const { target, gomodule } = props
20
+
21
+ const auth = {
22
+ suppressed: isAuthSuppressed(model),
23
+ where: resolveAuthIn(model),
24
+ name: 'header' === resolveAuthIn(model)
25
+ ? resolveAuthName(model).toLowerCase() : resolveAuthName(model),
26
+ basic: isHttpBasicAuth(model),
27
+ }
28
+
29
+ File({ name: 'clean_test.' + target.ext }, () => Content(render(gomodule, model.const.Name, auth)))
30
+ })
31
+
32
+
33
+ function render(gomodule: string, Name: string, auth: {
34
+ suppressed: boolean, where: string, name: string, basic: boolean
35
+ }): string {
36
+ return `package sdktest
37
+
38
+ import (
39
+ "context"
40
+ "encoding/base64"
41
+ "encoding/json"
42
+ "fmt"
43
+ "log/slog"
44
+ "net/url"
45
+ "reflect"
46
+ "sort"
47
+ "strings"
48
+ "testing"
49
+
50
+ sdk "${gomodule}"
51
+ "${gomodule}/core"
52
+ )
53
+
54
+ // Generated: the credential's wire placement is fixed when the SDK is built.
55
+ var cleanAuth = struct {
56
+ suppressed bool
57
+ where string
58
+ name string
59
+ basic bool
60
+ }{${auth.suppressed}, ${JSON.stringify(auth.where)}, ${JSON.stringify(auth.name)}, ${auth.basic}}
61
+
62
+ var cleanCanary = map[string]string{
63
+ "apikey": "CANARY-APIKEY-k9x2m7q4p1",
64
+ "secret": "CANARY-SECRET-w3e8r5t2y6",
65
+ "header": "CANARY-HEADER-z1x4c7v0b3",
66
+ "value": "CANARY-VALUE-n5m8b2v9c4",
67
+ "config": "CANARY-CONFIG-h6j3k8l2m5",
68
+ }
69
+
70
+ const cleanMask = "[redacted]"
71
+
72
+ // Every form a canary can travel in.
73
+ var cleanForms = func() []string {
74
+ out := []string{}
75
+ for _, k := range []string{"apikey", "secret", "header", "value", "config"} {
76
+ v := cleanCanary[k]
77
+ out = append(out, v, base64.StdEncoding.EncodeToString([]byte(v)), url.QueryEscape(v))
78
+ }
79
+ return append(out, base64.StdEncoding.EncodeToString(
80
+ []byte(cleanCanary["apikey"]+":"+cleanCanary["secret"])))
81
+ }()
82
+
83
+ type cleanSink struct {
84
+ name string
85
+ text string
86
+ }
87
+
88
+ // Header maps keep the caller's spelling; the assertion should not care.
89
+ func cleanHeader(m any, name string) any {
90
+ hm, _ := m.(map[string]any)
91
+ for k, v := range hm {
92
+ if strings.EqualFold(k, name) {
93
+ return v
94
+ }
95
+ }
96
+ return nil
97
+ }
98
+
99
+ func cleanLeaks(text string) []string {
100
+ found := []string{}
101
+ for _, f := range cleanForms {
102
+ if strings.Contains(text, f) {
103
+ found = append(found, f)
104
+ }
105
+ }
106
+ return found
107
+ }
108
+
109
+ // The default prints and the JSON form of a value: what a log line, a panic
110
+ // message or a structured logger would carry.
111
+ func cleanSurfaces(name string, val any) []cleanSink {
112
+ out := []cleanSink{}
113
+ if raw, err := json.Marshal(val); err == nil {
114
+ out = append(out, cleanSink{name + ":json", string(raw)})
115
+ }
116
+ out = append(out,
117
+ cleanSink{name + ":v", fmt.Sprintf("%v", val)},
118
+ cleanSink{name + ":+v", fmt.Sprintf("%+v", val)},
119
+ cleanSink{name + ":#v", fmt.Sprintf("%#v", val)},
120
+ )
121
+ if err, ok := val.(error); ok {
122
+ out = append(out, cleanSink{name + ":message", err.Error()})
123
+ }
124
+ return out
125
+ }
126
+
127
+ // Captures the serialised context from inside the pipeline: what a hook
128
+ // author would hand to a logger.
129
+ type cleanCapture struct {
130
+ sdk.BaseFeature
131
+ sinks *[]cleanSink
132
+ }
133
+
134
+ func newCleanCapture(sinks *[]cleanSink) *cleanCapture {
135
+ return &cleanCapture{
136
+ BaseFeature: sdk.BaseFeature{Version: "0.0.1", Name: "capture", Active: true},
137
+ sinks: sinks,
138
+ }
139
+ }
140
+
141
+ func (f *cleanCapture) take(name string, ctx *sdk.Context) {
142
+ *f.sinks = append(*f.sinks, cleanSurfaces(name, ctx)...)
143
+ }
144
+
145
+ func (f *cleanCapture) PreRequest(ctx *sdk.Context) { f.take("ctx@PreRequest", ctx) }
146
+ func (f *cleanCapture) PreResponse(ctx *sdk.Context) { f.take("ctx@PreResponse", ctx) }
147
+
148
+ // The SDK's own error as a hook reads it, which an observability feature logs.
149
+ func (f *cleanCapture) PreUnexpected(ctx *sdk.Context) {
150
+ f.take("ctx@PreUnexpected", ctx)
151
+ if ctx.Ctrl == nil {
152
+ return
153
+ }
154
+ if sdkerr, ok := ctx.Ctrl.Err.(*sdk.${Name}Error); ok {
155
+ *f.sinks = append(*f.sinks, cleanSurfaces("ctrl.err@PreUnexpected", sdkerr)...)
156
+ }
157
+ }
158
+
159
+ // A slog handler that keeps every record, attributes included.
160
+ type cleanLogHandler struct {
161
+ name string
162
+ sinks *[]cleanSink
163
+ attrs []slog.Attr
164
+ }
165
+
166
+ func (h *cleanLogHandler) Enabled(context.Context, slog.Level) bool { return true }
167
+
168
+ func (h *cleanLogHandler) Handle(_ context.Context, r slog.Record) error {
169
+ rec := map[string]any{"msg": r.Message}
170
+ for _, a := range h.attrs {
171
+ rec[a.Key] = a.Value.Any()
172
+ }
173
+ r.Attrs(func(a slog.Attr) bool {
174
+ rec[a.Key] = a.Value.Any()
175
+ return true
176
+ })
177
+ *h.sinks = append(*h.sinks,
178
+ cleanSurfaces(h.name+"."+strings.ToLower(r.Level.String()), rec)...)
179
+ return nil
180
+ }
181
+
182
+ func (h *cleanLogHandler) WithAttrs(attrs []slog.Attr) slog.Handler {
183
+ return &cleanLogHandler{
184
+ name: h.name,
185
+ sinks: h.sinks,
186
+ attrs: append(append([]slog.Attr{}, h.attrs...), attrs...),
187
+ }
188
+ }
189
+
190
+ func (h *cleanLogHandler) WithGroup(string) slog.Handler { return h }
191
+
192
+ type cleanScenario struct {
193
+ name string
194
+ respond func(url string, fetchdef map[string]any) (any, error)
195
+ }
196
+
197
+ func cleanResponse(status int, data any, headers map[string]any) map[string]any {
198
+ h := map[string]any{"content-type": "application/json"}
199
+ for k, v := range headers {
200
+ h[k] = v
201
+ }
202
+ statusText := "OK"
203
+ if status >= 400 {
204
+ statusText = "ERR"
205
+ }
206
+ raw, _ := json.Marshal(data)
207
+ return map[string]any{
208
+ "status": status,
209
+ "statusText": statusText,
210
+ "headers": h,
211
+ "json": (func() any)(func() any { return data }),
212
+ "body": string(raw),
213
+ }
214
+ }
215
+
216
+ var cleanScenarios = []cleanScenario{
217
+ {"ok", func(string, map[string]any) (any, error) {
218
+ return cleanResponse(200, map[string]any{"id": "i1", "name": "n1"},
219
+ map[string]any{"x-session-token": "RESP-TOKEN-a1b2c3d4e5"}), nil
220
+ }},
221
+ {"notfound", func(string, map[string]any) (any, error) {
222
+ return cleanResponse(404, map[string]any{"error": "no such record"}, nil), nil
223
+ }},
224
+ {"server", func(string, map[string]any) (any, error) {
225
+ return cleanResponse(500, map[string]any{"error": "boom"}, nil), nil
226
+ }},
227
+ {"transport", func(url string, _ map[string]any) (any, error) {
228
+ return nil, fmt.Errorf("socket hang up (URL was: %q)", url)
229
+ }},
230
+ // The SDK's own error, its code quoting a registered value.
231
+ {"coded", func(string, map[string]any) (any, error) {
232
+ return nil, core.New${Name}Error("denied_"+cleanCanary["apikey"], "coded failure", nil)
233
+ }},
234
+ {"notjson", func(string, map[string]any) (any, error) {
235
+ return map[string]any{
236
+ "status": 200,
237
+ "statusText": "OK",
238
+ "headers": map[string]any{},
239
+ "json": (func() any)(func() any { return nil }),
240
+ "body": "<html>",
241
+ }, nil
242
+ }},
243
+ }
244
+
245
+ func cleanMakeSdk(scenario cleanScenario, sinks *[]cleanSink, cleanopts map[string]any,
246
+ extra ...any) *sdk.${Name}SDK {
247
+ capture := func(name string) func(map[string]any) {
248
+ return func(rec map[string]any) {
249
+ *sinks = append(*sinks, cleanSurfaces(name, rec)...)
250
+ }
251
+ }
252
+
253
+ feature := map[string]any{}
254
+ if fhHasFeature("log") {
255
+ feature["log"] = map[string]any{
256
+ "active": true,
257
+ "logger": slog.New(&cleanLogHandler{name: "log", sinks: sinks}),
258
+ }
259
+ }
260
+ if fhHasFeature("debug") {
261
+ feature["debug"] = map[string]any{"active": true, "onEntry": capture("debug")}
262
+ }
263
+ if fhHasFeature("audit") {
264
+ feature["audit"] = map[string]any{"active": true, "sink": capture("audit")}
265
+ }
266
+ if fhHasFeature("telemetry") {
267
+ feature["telemetry"] = map[string]any{"active": true, "exporter": capture("telemetry")}
268
+ }
269
+ if fhHasFeature("cost") {
270
+ feature["cost"] = map[string]any{"active": true, "sink": capture("cost")}
271
+ }
272
+ if fhHasFeature("metrics") {
273
+ feature["metrics"] = map[string]any{"active": true}
274
+ }
275
+ if fhHasFeature("clienttrack") {
276
+ feature["clienttrack"] = map[string]any{"active": true}
277
+ }
278
+
279
+ clean := map[string]any{"values": cleanCanary["value"]}
280
+ for k, v := range cleanopts {
281
+ clean[k] = v
282
+ }
283
+
284
+ return sdk.New${Name}SDK(map[string]any{
285
+ "apikey": cleanCanary["apikey"],
286
+ "secret": cleanCanary["secret"],
287
+ "headers": map[string]any{"X-Custom-Token": cleanCanary["header"]},
288
+ "clean": clean,
289
+ "feature": feature,
290
+ "extend": append([]any{newCleanCapture(sinks)}, extra...),
291
+ "utility": map[string]any{
292
+ "fetcher": sdk.FetcherFunc(func(_ *sdk.Context, url string, fetchdef map[string]any) (any, error) {
293
+ return scenario.respond(url, fetchdef)
294
+ }),
295
+ },
296
+ })
297
+ }
298
+
299
+ // One operation this SDK can perform: the client method returning the
300
+ // entity, the op method on it, and the match it completes with.
301
+ type cleanOp struct {
302
+ accessor string
303
+ method string
304
+ match map[string]any
305
+ }
306
+
307
+ func cleanEntity(client *sdk.${Name}SDK, accessor string) reflect.Value {
308
+ return reflect.ValueOf(client).MethodByName(accessor).
309
+ Call([]reflect.Value{reflect.ValueOf(map[string]any(nil))})[0]
310
+ }
311
+
312
+ func cleanInvoke(client *sdk.${Name}SDK, op cleanOp, ctrl map[string]any) (any, error) {
313
+ match := map[string]any{}
314
+ for k, v := range op.match {
315
+ match[k] = v
316
+ }
317
+ rets := cleanEntity(client, op.accessor).MethodByName(op.method).Call([]reflect.Value{
318
+ reflect.ValueOf(match),
319
+ reflect.ValueOf(ctrl),
320
+ })
321
+ var err error
322
+ if e, ok := rets[1].Interface().(error); ok {
323
+ err = e
324
+ }
325
+ return rets[0].Interface(), err
326
+ }
327
+
328
+ // Every path parameter an op's points declare, filled in.
329
+ func cleanFilled(client *sdk.${Name}SDK, entity string, method string) map[string]any {
330
+ filled := map[string]any{}
331
+ opdef := core.ToMapAny(core.ToMapAny(core.ToMapAny(core.ToMapAny(
332
+ client.GetRootCtx().Config["entity"])[entity])["op"])[strings.ToLower(method)])
333
+ points, _ := opdef["points"].([]any)
334
+ for _, point := range points {
335
+ params, _ := core.ToMapAny(core.ToMapAny(point)["args"])["params"].([]any)
336
+ for _, p := range params {
337
+ if name, ok := core.ToMapAny(p)["name"].(string); ok {
338
+ filled[name] = "p1"
339
+ }
340
+ }
341
+ }
342
+ return filled
343
+ }
344
+
345
+ // The first operation that completes against a plain 200: with no
346
+ // arguments, else with every path parameter its points declare filled in.
347
+ // An entity accessor is a client method taking one options map and
348
+ // returning something that answers GetName().
349
+ func cleanUsableOp() (cleanOp, bool) {
350
+ plain := func() *sdk.${Name}SDK {
351
+ return sdk.New${Name}SDK(map[string]any{
352
+ "apikey": cleanCanary["apikey"],
353
+ "utility": map[string]any{
354
+ "fetcher": sdk.FetcherFunc(func(*sdk.Context, string, map[string]any) (any, error) {
355
+ return cleanResponse(200, map[string]any{"id": "i1"}, nil), nil
356
+ }),
357
+ },
358
+ })
359
+ }
360
+
361
+ probe := plain()
362
+ cv := reflect.ValueOf(probe)
363
+ ct := cv.Type()
364
+ mapType := reflect.TypeOf(map[string]any{})
365
+
366
+ accessors := []string{}
367
+ for i := 0; i < ct.NumMethod(); i++ {
368
+ m := ct.Method(i)
369
+ if m.Type.NumIn() != 2 || m.Type.NumOut() != 1 || m.Type.In(1) != mapType {
370
+ continue
371
+ }
372
+ ent := cleanEntity(probe, m.Name)
373
+ if !ent.IsValid() || (ent.Kind() == reflect.Ptr && ent.IsNil()) {
374
+ continue
375
+ }
376
+ gn := ent.MethodByName("GetName")
377
+ if !gn.IsValid() || gn.Type().NumIn() != 0 || gn.Type().NumOut() != 1 ||
378
+ gn.Type().Out(0).Kind() != reflect.String {
379
+ continue
380
+ }
381
+ accessors = append(accessors, m.Name)
382
+ }
383
+ sort.Strings(accessors)
384
+
385
+ for _, accessor := range accessors {
386
+ for _, method := range []string{"List", "Load", "Create", "Update", "Remove"} {
387
+ om := cleanEntity(probe, accessor).MethodByName(method)
388
+ if !om.IsValid() || om.Type().NumIn() != 2 || om.Type().NumOut() != 2 {
389
+ continue
390
+ }
391
+ name := cleanEntity(probe, accessor).MethodByName("GetName").
392
+ Call(nil)[0].String()
393
+ for _, match := range []map[string]any{{}, cleanFilled(probe, name, method)} {
394
+ op := cleanOp{accessor: accessor, method: method, match: match}
395
+ if _, err := cleanInvoke(plain(), op, map[string]any{}); err == nil {
396
+ return op, true
397
+ }
398
+ }
399
+ }
400
+ }
401
+ return cleanOp{}, false
402
+ }
403
+
404
+ func cleanDrive(client *sdk.${Name}SDK, op cleanOp, ctrl map[string]any, sinks *[]cleanSink) error {
405
+ // A caller may keep the record it passed rather than read ctrl["explain"].
406
+ held, _ := ctrl["explain"].(map[string]any)
407
+ out, err := cleanInvoke(client, op, ctrl)
408
+ if err != nil {
409
+ *sinks = append(*sinks, cleanSurfaces("error", err)...)
410
+ }
411
+ if out != nil {
412
+ *sinks = append(*sinks, cleanSurfaces("result", out)...)
413
+ }
414
+ explain, ok := ctrl["explain"].(map[string]any)
415
+ if ok {
416
+ *sinks = append(*sinks, cleanSurfaces("explain", explain)...)
417
+ }
418
+ if held != nil && reflect.ValueOf(held).Pointer() != reflect.ValueOf(explain).Pointer() {
419
+ *sinks = append(*sinks, cleanSurfaces("explain:held", held)...)
420
+ }
421
+ return err
422
+ }
423
+
424
+ // A feature that fails from inside the pipeline, quoting the request it
425
+ // saw: a panic MakeError never handled. Its PreUnexpected variant panics
426
+ // inside MakeError, after the cleaning there.
427
+ type cleanThrow struct {
428
+ sdk.BaseFeature
429
+ response bool
430
+ unexpected bool
431
+ }
432
+
433
+ func newCleanThrow(response bool, unexpected bool) *cleanThrow {
434
+ return &cleanThrow{
435
+ BaseFeature: sdk.BaseFeature{Version: "0.0.1", Name: "throwhook", Active: true},
436
+ response: response,
437
+ unexpected: unexpected,
438
+ }
439
+ }
440
+
441
+ func (f *cleanThrow) PreResponse(ctx *sdk.Context) {
442
+ if f.response {
443
+ raw, _ := json.Marshal(ctx.Spec)
444
+ panic(fmt.Errorf("hook saw %s", raw))
445
+ }
446
+ }
447
+
448
+ func (f *cleanThrow) PreUnexpected(ctx *sdk.Context) {
449
+ if f.unexpected {
450
+ raw, _ := json.Marshal(ctx.Spec)
451
+ panic(fmt.Errorf("hook saw %s", raw))
452
+ }
453
+ }
454
+
455
+ // A stream that succeeds, so Stream never reaches Done.
456
+ type cleanStreamOk struct {
457
+ sdk.BaseFeature
458
+ }
459
+
460
+ func (f *cleanStreamOk) PreDone(ctx *sdk.Context) {
461
+ var items []any
462
+ switch d := ctx.Result.Resdata.(type) {
463
+ case []any:
464
+ items = d
465
+ case nil:
466
+ default:
467
+ items = []any{d}
468
+ }
469
+ ctx.Result.Stream = func() <-chan any {
470
+ ch := make(chan any, len(items))
471
+ for _, item := range items {
472
+ ch <- item
473
+ }
474
+ close(ch)
475
+ return ch
476
+ }
477
+ }
478
+
479
+ // A stream function that panics when Stream calls it, quoting a credential.
480
+ type cleanStreamPanic struct {
481
+ sdk.BaseFeature
482
+ }
483
+
484
+ func (f *cleanStreamPanic) PreDone(ctx *sdk.Context) {
485
+ ctx.Result.Stream = func() <-chan any {
486
+ panic("stream saw " + cleanCanary["apikey"])
487
+ }
488
+ }
489
+
490
+ // A panic that escapes is a surface too: what a crash would print.
491
+ func cleanCatch(name string, sinks *[]cleanSink, fn func() error) (err error) {
492
+ defer func() {
493
+ if r := recover(); r != nil {
494
+ *sinks = append(*sinks, cleanSurfaces(name+":panic", r)...)
495
+ err = fmt.Errorf("panic: %v", r)
496
+ }
497
+ }()
498
+ return fn()
499
+ }
500
+
501
+ const cleanNoOp = "no operation of this SDK completes against a plain 200; nothing to sweep"
502
+
503
+ func TestCleanSweep(t *testing.T) {
504
+ op, found := cleanUsableOp()
505
+ if !found {
506
+ t.Skip(cleanNoOp)
507
+ }
508
+
509
+ sinks := []cleanSink{}
510
+ errs := map[string]error{}
511
+ explains := map[string]map[string]any{}
512
+
513
+ variants := []struct {
514
+ name string
515
+ ctrl func() map[string]any
516
+ }{
517
+ {"throw", func() map[string]any { return map[string]any{} }},
518
+ {"explain", func() map[string]any { return map[string]any{"explain": map[string]any{}} }},
519
+ {"nothrow", func() map[string]any {
520
+ return map[string]any{"throw": false, "explain": map[string]any{}}
521
+ }},
522
+ }
523
+
524
+ for _, scenario := range cleanScenarios {
525
+ for _, variant := range variants {
526
+ client := cleanMakeSdk(scenario, &sinks, nil)
527
+ ctrl := variant.ctrl()
528
+ err := cleanDrive(client, op, ctrl, &sinks)
529
+ key := scenario.name + "/" + variant.name
530
+ if err != nil {
531
+ errs[key] = err
532
+ }
533
+ if explain, ok := ctrl["explain"].(map[string]any); ok {
534
+ explains[key] = explain
535
+ }
536
+ sinks = append(sinks, cleanSurfaces("sdk", client)...)
537
+ sinks = append(sinks, cleanSink{"sdk:value", fmt.Sprintf("%+v", *client)})
538
+ }
539
+ }
540
+
541
+ // A credential mistyped as a map. The go validator substitutes the
542
+ // default rather than rejecting it, so there is no rejection to sweep:
543
+ // sweep what the constructor produced, and what clean makes of the value
544
+ // should anything later quote it.
545
+ cleanCatch("mistyped", &sinks, func() error {
546
+ client := sdk.New${Name}SDK(map[string]any{
547
+ "apikey": map[string]any{"value": cleanCanary["apikey"]},
548
+ "clean": map[string]any{"values": cleanCanary["value"]},
549
+ })
550
+ sinks = append(sinks, cleanSurfaces("mistyped", client)...)
551
+ sinks = append(sinks, cleanSurfaces("mistyped:quoted",
552
+ client.GetUtility().Clean(client.GetRootCtx(), "found map: "+cleanCanary["apikey"]))...)
553
+ return nil
554
+ })
555
+
556
+ // MakeError is the one place PreUnexpected fires, so the variant that
557
+ // panics there alone is driven through a 404 as well.
558
+ for _, hooked := range []struct {
559
+ scenario cleanScenario
560
+ hook *cleanThrow
561
+ }{
562
+ {cleanScenarios[0], newCleanThrow(true, false)},
563
+ {cleanScenarios[0], newCleanThrow(true, true)},
564
+ {cleanScenarios[1], newCleanThrow(false, true)},
565
+ } {
566
+ hookerr := cleanCatch("hook", &sinks, func() error {
567
+ return cleanDrive(cleanMakeSdk(hooked.scenario, &sinks, nil, hooked.hook), op,
568
+ map[string]any{"explain": map[string]any{}}, &sinks)
569
+ })
570
+ if hookerr == nil {
571
+ t.Errorf("the throwing hook should fail the operation")
572
+ }
573
+ }
574
+
575
+ // Stream has no error channel: a panic inside it must end the stream
576
+ // through MakeError, cleaned, and not crash the process. However it
577
+ // ends, the explain record the caller passed is left clean.
578
+ for _, streamed := range []struct {
579
+ name string
580
+ saw string
581
+ extra []any
582
+ }{
583
+ {"stream-hook", "hook saw", []any{newCleanThrow(true, false)}},
584
+ {"stream", "stream saw", []any{&cleanStreamPanic{
585
+ BaseFeature: sdk.BaseFeature{Version: "0.0.1", Name: "streampanic", Active: true}}}},
586
+ {"stream-ok", "", []any{&cleanStreamOk{
587
+ BaseFeature: sdk.BaseFeature{Version: "0.0.1", Name: "streamok", Active: true}}}},
588
+ {"stream-plain", "", nil},
589
+ } {
590
+ client := cleanMakeSdk(cleanScenarios[0], &sinks, nil, streamed.extra...)
591
+ reqmatch := map[string]any{}
592
+ for k, v := range op.match {
593
+ reqmatch[k] = v
594
+ }
595
+ explain := map[string]any{}
596
+ items := cleanEntity(client, op.accessor).MethodByName("Stream").Call([]reflect.Value{
597
+ reflect.ValueOf(strings.ToLower(op.method)),
598
+ reflect.ValueOf(map[string]any{"reqmatch": reqmatch}),
599
+ reflect.ValueOf(map[string]any{"ctrl": map[string]any{"explain": explain}}),
600
+ })[0].Interface().(<-chan any)
601
+ for range items {
602
+ }
603
+ sinks = append(sinks, cleanSurfaces(streamed.name+":explain", explain)...)
604
+ if 0 == len(explain) {
605
+ t.Errorf("%s: the explain record was not filled", streamed.name)
606
+ }
607
+ msg, _ := core.ToMapAny(explain["err"])["message"].(string)
608
+ if ("" == streamed.saw) != (nil == explain["err"]) || !strings.Contains(msg, streamed.saw) {
609
+ t.Errorf("%s: only a failing stream ends as the SDK error, got %v", streamed.name, explain)
610
+ }
611
+ }
612
+
613
+ // A registered value used as a property name is masked; names that mask
614
+ // alike are kept apart.
615
+ probe := cleanMakeSdk(cleanScenarios[0], &sinks, nil)
616
+ named, _ := probe.GetUtility().Clean(probe.GetRootCtx(), map[string]any{
617
+ cleanCanary["value"]: 1, cleanCanary["header"]: 2, "plain": 3,
618
+ }).(map[string]any)
619
+ sinks = append(sinks, cleanSurfaces("named", named)...)
620
+ if want := map[string]any{cleanMask: 2, cleanMask + "#1": 1, "plain": 3}; !reflect.DeepEqual(named, want) {
621
+ t.Errorf("property names: expected %v, got %v", want, named)
622
+ }
623
+
624
+ // The generated config's own clean block is read beside the caller's,
625
+ // and is not changed by it.
626
+ cfgclean := map[string]any{"keys": "zzsens", "values": cleanCanary["config"]}
627
+ util := probe.GetUtility()
628
+ cfgctx := &core.Context{Options: util.MakeOptions(&core.Context{
629
+ Utility: util,
630
+ Config: map[string]any{"options": map[string]any{"clean": cfgclean}},
631
+ Options: map[string]any{"clean": map[string]any{"values": cleanCanary["value"]}},
632
+ })}
633
+ seeded, _ := util.Clean(cfgctx, "config "+cleanCanary["config"]+" caller "+cleanCanary["value"]).(string)
634
+ sinks = append(sinks, cleanSink{"config-clean", seeded})
635
+ if want := "config " + cleanMask + " caller " + cleanMask; seeded != want {
636
+ t.Errorf("config clean values: expected %q, got %q", want, seeded)
637
+ }
638
+ bykey, _ := util.Clean(cfgctx, map[string]any{"my_zzsens": "x", "other": "y"}).(map[string]any)
639
+ if want := map[string]any{"my_zzsens": cleanMask, "other": "y"}; !reflect.DeepEqual(bykey, want) {
640
+ t.Errorf("config clean keys: expected %v, got %v", want, bykey)
641
+ }
642
+ if cfgclean["keys"] != "zzsens" || cfgclean["values"] != cleanCanary["config"] {
643
+ t.Errorf("the config's own clean block was changed: %v", cfgclean)
644
+ }
645
+
646
+ // With no clean option at all, the schema defaults still apply.
647
+ bare := sdk.New${Name}SDK(map[string]any{
648
+ "apikey": cleanCanary["apikey"],
649
+ "secret": cleanCanary["secret"],
650
+ "headers": map[string]any{"X-Custom-Token": cleanCanary["header"]},
651
+ "utility": map[string]any{
652
+ "fetcher": sdk.FetcherFunc(func(_ *sdk.Context, url string, fetchdef map[string]any) (any, error) {
653
+ return cleanScenarios[1].respond(url, fetchdef)
654
+ }),
655
+ },
656
+ })
657
+ if nil == cleanDrive(bare, op, map[string]any{"explain": map[string]any{}}, &sinks) {
658
+ t.Errorf("the 404 scenario should fail without a clean option too")
659
+ }
660
+
661
+ // A feature's name is not a field name: only the sensitive names inside
662
+ // its settings register. An entity block, of per-entity settings or seeded
663
+ // records keyed by entity name and id, is not read at all.
664
+ featured := sdk.New${Name}SDK(map[string]any{
665
+ "apikey": cleanCanary["apikey"],
666
+ "feature": map[string]any{
667
+ "zzsecrets": map[string]any{"active": false, "kind": "PLAINSETTING-q8w2e4r6"},
668
+ "zzfeat": map[string]any{"active": false, "apitoken": "FEATTOKEN-z9y8x7w6"},
669
+ "test": map[string]any{"active": false, "entity": map[string]any{
670
+ "zztoken": map[string]any{"ZZTOKEN01": map[string]any{"note": "PLAINRECORD-t5r3e1w9"}},
671
+ }},
672
+ },
673
+ "entity": map[string]any{"zztoken": map[string]any{"alias": map[string]any{"zzkey": "PLAINALIAS-m2n4b6v8"}}},
674
+ })
675
+ fclean := featured.GetUtility().Clean
676
+ if got, _ := fclean(featured.GetRootCtx(), "kind PLAINSETTING-q8w2e4r6").(string); got != "kind PLAINSETTING-q8w2e4r6" {
677
+ t.Errorf("a setting of a feature named like a secret was registered: %q", got)
678
+ }
679
+ if got, _ := fclean(featured.GetRootCtx(), "token FEATTOKEN-z9y8x7w6").(string); got != "token "+cleanMask {
680
+ t.Errorf("a sensitive setting inside a feature was not registered: %q", got)
681
+ }
682
+ for _, plain := range []string{"record PLAINRECORD-t5r3e1w9", "alias PLAINALIAS-m2n4b6v8"} {
683
+ if got, _ := fclean(featured.GetRootCtx(), plain).(string); got != plain {
684
+ t.Errorf("an entity block was registered: %q", got)
685
+ }
686
+ }
687
+
688
+ leaked := []string{}
689
+ for _, s := range sinks {
690
+ if found := cleanLeaks(s.text); 0 < len(found) {
691
+ leaked = append(leaked, s.name+" ["+strings.Join(found, ", ")+"]")
692
+ }
693
+ }
694
+
695
+ fmt.Printf("clean: swept %d surface(s), %d leak(s)\\n", len(sinks), len(leaked))
696
+
697
+ if 0 < len(leaked) {
698
+ t.Fatalf("credential leaked through: %s", strings.Join(leaked, "; "))
699
+ }
700
+
701
+ // The positive half: the slot the credential travelled in is masked,
702
+ // and an unregistered token in a response header is masked by name.
703
+ notfound, _ := errs["notfound/throw"].(*sdk.${Name}Error)
704
+ if notfound == nil {
705
+ t.Fatalf("the 404 scenario must return the SDK error, got %v", errs["notfound/throw"])
706
+ }
707
+ result, _ := notfound.Result.(map[string]any)
708
+ if core.ToInt(result["status"]) != 404 {
709
+ t.Fatalf("expected status 404 on the error, got %v", result["status"])
710
+ }
711
+ spec, _ := notfound.Spec.(map[string]any)
712
+ if !cleanAuth.suppressed {
713
+ switch cleanAuth.where {
714
+ case "query":
715
+ if got := cleanHeader(spec["query"], cleanAuth.name); got != cleanMask {
716
+ t.Errorf("%s: expected the mask, got %v", cleanAuth.name, got)
717
+ }
718
+ case "cookie":
719
+ got := fmt.Sprintf("%v", cleanHeader(spec["headers"], "cookie"))
720
+ if !strings.Contains(got, cleanMask) {
721
+ t.Errorf("cookie: expected the mask, got %v", got)
722
+ }
723
+ default:
724
+ got := fmt.Sprintf("%v", cleanHeader(spec["headers"], cleanAuth.name))
725
+ if !strings.HasSuffix(got, cleanMask) {
726
+ t.Errorf("%s: expected the mask, got %v", cleanAuth.name, got)
727
+ }
728
+ }
729
+ }
730
+ if got := cleanHeader(spec["headers"], "x-custom-token"); got != cleanMask {
731
+ t.Errorf("x-custom-token: expected the mask, got %v", got)
732
+ }
733
+
734
+ coded, _ := errs["coded/throw"].(*sdk.${Name}Error)
735
+ if coded == nil || coded.Code != "denied_"+cleanMask {
736
+ t.Errorf("the coded error keeps its code, masked: got %#v", errs["coded/throw"])
737
+ }
738
+
739
+ explained := explains["ok/explain"]
740
+ explainedResult, _ := explained["result"].(map[string]any)
741
+ if explainedResult == nil {
742
+ t.Fatalf("the explain record should carry the result, got %v", explained)
743
+ }
744
+ if got := cleanHeader(explainedResult["headers"], "x-session-token"); got != cleanMask {
745
+ t.Errorf("x-session-token: expected the mask, got %v", got)
746
+ }
747
+ }
748
+
749
+ func TestCleanSensitivity(t *testing.T) {
750
+ op, found := cleanUsableOp()
751
+ if !found {
752
+ t.Skip(cleanNoOp)
753
+ }
754
+
755
+ sinks := []cleanSink{}
756
+ client := cleanMakeSdk(cleanScenarios[1], &sinks, map[string]any{"active": false})
757
+ err := cleanDrive(client, op, map[string]any{}, &sinks)
758
+ if err == nil {
759
+ t.Fatal("the 404 scenario must fail")
760
+ }
761
+
762
+ // Explaining a failure must not cost it its error, nor the record.
763
+ discard := []cleanSink{}
764
+ ectrl := map[string]any{"explain": map[string]any{}}
765
+ explained := cleanDrive(cleanMakeSdk(cleanScenarios[1], &discard, map[string]any{"active": false}),
766
+ op, ectrl, &discard)
767
+ if explained == nil || explained.Error() != err.Error() {
768
+ t.Errorf("with clean off, explain lost the error: %v", explained)
769
+ }
770
+ if nil == ectrl["explain"].(map[string]any)["err"] {
771
+ t.Errorf("with clean off, the explain record was emptied: %v", ectrl["explain"])
772
+ }
773
+
774
+ leaked := 0
775
+ for _, s := range sinks {
776
+ if 0 < len(cleanLeaks(s.text)) {
777
+ leaked++
778
+ }
779
+ }
780
+ if leaked == 0 {
781
+ t.Fatal("with clean off, nothing showed the canary: the sweep is blind")
782
+ }
783
+
784
+ if !cleanAuth.suppressed {
785
+ sdkerr, _ := err.(*sdk.${Name}Error)
786
+ if sdkerr == nil {
787
+ t.Fatalf("expected the SDK error, got %v", err)
788
+ }
789
+ raw, _ := json.Marshal(sdkerr.Spec)
790
+ text := string(raw)
791
+ composite := base64.StdEncoding.EncodeToString(
792
+ []byte(cleanCanary["apikey"] + ":" + cleanCanary["secret"]))
793
+ if !strings.Contains(text, cleanCanary["apikey"]) && !strings.Contains(text, composite) {
794
+ t.Errorf("the raw spec should carry the credential when clean is off, got %s", text)
795
+ }
796
+ }
797
+ }
798
+ `
799
+ }
800
+
801
+
802
+ export {
803
+ TestClean
804
+ }