@voxgig/sdkgen 4.32.1 → 4.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (442) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/dist/action/copies.d.ts +21 -0
  3. package/dist/action/copies.js +146 -0
  4. package/dist/action/copies.js.map +1 -0
  5. package/dist/action/doctor.d.ts +15 -2
  6. package/dist/action/doctor.js +169 -23
  7. package/dist/action/doctor.js.map +1 -1
  8. package/dist/action/edition.js +6 -2
  9. package/dist/action/edition.js.map +1 -1
  10. package/dist/action/feature.js +6 -2
  11. package/dist/action/feature.js.map +1 -1
  12. package/dist/action/package.js +28 -10
  13. package/dist/action/package.js.map +1 -1
  14. package/dist/action/remove.js +2 -0
  15. package/dist/action/remove.js.map +1 -1
  16. package/dist/action/resolve.d.ts +1 -0
  17. package/dist/action/resolve.js +10 -2
  18. package/dist/action/resolve.js.map +1 -1
  19. package/dist/action/target.js +6 -2
  20. package/dist/action/target.js.map +1 -1
  21. package/dist/helpers/naming.js +1 -1
  22. package/dist/helpers/naming.js.map +1 -1
  23. package/dist/sdkgen.d.ts +2 -1
  24. package/dist/sdkgen.js +36 -3
  25. package/dist/sdkgen.js.map +1 -1
  26. package/dist/tsconfig.tsbuildinfo +1 -1
  27. package/model/sdkgen.aontu +7 -1
  28. package/package.json +1 -1
  29. package/project/.sdk/model/feature/debug.aontu +3 -1
  30. package/project/.sdk/src/cmp/c/PrepareAuth_c.ts +8 -28
  31. package/project/.sdk/src/cmp/c/TestClean_c.ts +774 -0
  32. package/project/.sdk/src/cmp/c/Test_c.ts +3 -0
  33. package/project/.sdk/src/cmp/c/fragment/Entity.fragment.c +16 -5
  34. package/project/.sdk/src/cmp/c/fragment/Main.fragment.c +1 -1
  35. package/project/.sdk/src/cmp/clojure/PrepareAuth_clojure.ts +3 -0
  36. package/project/.sdk/src/cmp/clojure/TestClean_clojure.ts +473 -0
  37. package/project/.sdk/src/cmp/clojure/Test_clojure.ts +6 -0
  38. package/project/.sdk/src/cmp/clojure/fragment/Entity.fragment.clj +18 -8
  39. package/project/.sdk/src/cmp/cpp/PrepareAuth_cpp.ts +3 -0
  40. package/project/.sdk/src/cmp/cpp/TestClean_cpp.ts +782 -0
  41. package/project/.sdk/src/cmp/cpp/TestEntity_cpp.ts +1 -1
  42. package/project/.sdk/src/cmp/cpp/Test_cpp.ts +2 -0
  43. package/project/.sdk/src/cmp/csharp/PrepareAuth_csharp.ts +3 -0
  44. package/project/.sdk/src/cmp/csharp/TestClean_csharp.ts +887 -0
  45. package/project/.sdk/src/cmp/csharp/Test_csharp.ts +2 -0
  46. package/project/.sdk/src/cmp/csharp/fragment/EntityBase.fragment.cs +68 -4
  47. package/project/.sdk/src/cmp/csharp/fragment/Main.fragment.cs +8 -2
  48. package/project/.sdk/src/cmp/csharp/fragment/SdkError.fragment.cs +49 -0
  49. package/project/.sdk/src/cmp/elixir/PrepareAuth_elixir.ts +3 -0
  50. package/project/.sdk/src/cmp/elixir/Schema_elixir.ts +20 -10
  51. package/project/.sdk/src/cmp/elixir/TestClean_elixir.ts +666 -0
  52. package/project/.sdk/src/cmp/elixir/Test_elixir.ts +4 -0
  53. package/project/.sdk/src/cmp/elixir/fragment/Main.fragment.ex +1 -1
  54. package/project/.sdk/src/cmp/elixir/fragment/Pipeline.fragment.ex +14 -2
  55. package/project/.sdk/src/cmp/go/PrepareAuth_go.ts +3 -0
  56. package/project/.sdk/src/cmp/go/TestClean_go.ts +804 -0
  57. package/project/.sdk/src/cmp/go/Test_go.ts +3 -0
  58. package/project/.sdk/src/cmp/go/fragment/Entity.fragment.go +54 -4
  59. package/project/.sdk/src/cmp/go/fragment/Main.fragment.go +27 -2
  60. package/project/.sdk/src/cmp/java/PrepareAuth_java.ts +3 -0
  61. package/project/.sdk/src/cmp/java/TestClean_java.ts +884 -0
  62. package/project/.sdk/src/cmp/java/Test_java.ts +2 -0
  63. package/project/.sdk/src/cmp/java/fragment/EntityBase.fragment.java +56 -11
  64. package/project/.sdk/src/cmp/java/fragment/SdkError.fragment.java +36 -3
  65. package/project/.sdk/src/cmp/js/PrepareAuth_js.ts +3 -0
  66. package/project/.sdk/src/cmp/js/TestClean_js.ts +458 -0
  67. package/project/.sdk/src/cmp/js/Test_js.ts +2 -0
  68. package/project/.sdk/src/cmp/js/fragment/EntityBase.fragment.js +5 -4
  69. package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +7 -1
  70. package/project/.sdk/src/cmp/js/fragment/EntityListOp.fragment.js +7 -1
  71. package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +7 -1
  72. package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +7 -1
  73. package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +7 -1
  74. package/project/.sdk/src/cmp/js/fragment/Main.fragment.js +11 -2
  75. package/project/.sdk/src/cmp/js/fragment/SdkError.fragment.js +17 -1
  76. package/project/.sdk/src/cmp/kotlin/Package_kotlin.ts +5 -0
  77. package/project/.sdk/src/cmp/kotlin/PrepareAuth_kotlin.ts +3 -0
  78. package/project/.sdk/src/cmp/kotlin/TestClean_kotlin.ts +654 -0
  79. package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +3 -0
  80. package/project/.sdk/src/cmp/kotlin/fragment/EntityBase.fragment.kt +44 -11
  81. package/project/.sdk/src/cmp/kotlin/fragment/SdkError.fragment.kt +31 -0
  82. package/project/.sdk/src/cmp/lua/PrepareAuth_lua.ts +3 -0
  83. package/project/.sdk/src/cmp/lua/TestClean_lua.ts +769 -0
  84. package/project/.sdk/src/cmp/lua/Test_lua.ts +3 -0
  85. package/project/.sdk/src/cmp/lua/fragment/Entity.fragment.lua +77 -1
  86. package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +49 -2
  87. package/project/.sdk/src/cmp/ocaml/Entity_ocaml.ts +3 -2
  88. package/project/.sdk/src/cmp/ocaml/PrepareAuth_ocaml.ts +4 -25
  89. package/project/.sdk/src/cmp/ocaml/TestClean_ocaml.ts +538 -0
  90. package/project/.sdk/src/cmp/ocaml/Test_ocaml.ts +5 -0
  91. package/project/.sdk/src/cmp/ocaml/fragment/RunOp.fragment.ml +16 -4
  92. package/project/.sdk/src/cmp/perl/PrepareAuth_perl.ts +3 -0
  93. package/project/.sdk/src/cmp/perl/TestClean_perl.ts +619 -0
  94. package/project/.sdk/src/cmp/perl/Test_perl.ts +3 -0
  95. package/project/.sdk/src/cmp/perl/fragment/Entity.fragment.pm +67 -5
  96. package/project/.sdk/src/cmp/perl/fragment/Main.fragment.pm +13 -1
  97. package/project/.sdk/src/cmp/php/PrepareAuth_php.ts +3 -0
  98. package/project/.sdk/src/cmp/php/TestClean_php.ts +809 -0
  99. package/project/.sdk/src/cmp/php/Test_php.ts +2 -0
  100. package/project/.sdk/src/cmp/php/fragment/Entity.fragment.php +96 -55
  101. package/project/.sdk/src/cmp/php/fragment/Main.fragment.php +15 -2
  102. package/project/.sdk/src/cmp/py/PrepareAuth_py.ts +3 -0
  103. package/project/.sdk/src/cmp/py/TestClean_py.ts +549 -0
  104. package/project/.sdk/src/cmp/py/Test_py.ts +3 -0
  105. package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +83 -55
  106. package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +19 -3
  107. package/project/.sdk/src/cmp/rb/PrepareAuth_rb.ts +3 -0
  108. package/project/.sdk/src/cmp/rb/TestClean_rb.ts +535 -0
  109. package/project/.sdk/src/cmp/rb/Test_rb.ts +3 -0
  110. package/project/.sdk/src/cmp/rb/fragment/Entity.fragment.rb +108 -46
  111. package/project/.sdk/src/cmp/rb/fragment/Main.fragment.rb +12 -1
  112. package/project/.sdk/src/cmp/rust/PrepareAuth_rust.ts +9 -45
  113. package/project/.sdk/src/cmp/rust/TestClean_rust.ts +881 -0
  114. package/project/.sdk/src/cmp/rust/Test_rust.ts +3 -0
  115. package/project/.sdk/src/cmp/rust/fragment/Entity.fragment.rs +14 -6
  116. package/project/.sdk/src/cmp/rust/fragment/Main.fragment.rs +17 -1
  117. package/project/.sdk/src/cmp/rust/fragment/SdkError.fragment.rs +34 -2
  118. package/project/.sdk/src/cmp/scala/PrepareAuth_scala.ts +3 -0
  119. package/project/.sdk/src/cmp/scala/TestClean_scala.ts +608 -0
  120. package/project/.sdk/src/cmp/scala/Test_scala.ts +3 -0
  121. package/project/.sdk/src/cmp/scala/fragment/EntityBase.fragment.scala +58 -6
  122. package/project/.sdk/src/cmp/swift/PrepareAuth_swift.ts +3 -0
  123. package/project/.sdk/src/cmp/swift/TestClean_swift.ts +671 -0
  124. package/project/.sdk/src/cmp/swift/Test_swift.ts +3 -0
  125. package/project/.sdk/src/cmp/swift/fragment/EntityBase.fragment.swift +10 -0
  126. package/project/.sdk/src/cmp/swift/fragment/Main.fragment.swift +16 -2
  127. package/project/.sdk/src/cmp/swift/fragment/SdkError.fragment.swift +47 -3
  128. package/project/.sdk/src/cmp/ts/PrepareAuth_ts.ts +3 -0
  129. package/project/.sdk/src/cmp/ts/TestClean_ts.ts +465 -0
  130. package/project/.sdk/src/cmp/ts/Test_ts.ts +2 -0
  131. package/project/.sdk/src/cmp/ts/fragment/EntityBase.fragment.ts +5 -4
  132. package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.ts +7 -1
  133. package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.ts +7 -1
  134. package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.ts +7 -1
  135. package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.ts +7 -1
  136. package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.ts +7 -1
  137. package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +8 -2
  138. package/project/.sdk/src/cmp/ts/fragment/SdkError.fragment.ts +20 -2
  139. package/project/.sdk/src/cmp/zig/PrepareAuth_zig.ts +3 -0
  140. package/project/.sdk/src/cmp/zig/TestClean_zig.ts +791 -0
  141. package/project/.sdk/src/cmp/zig/Test_zig.ts +5 -0
  142. package/project/.sdk/src/cmp/zig/fragment/Build.fragment.zig +19 -0
  143. package/project/.sdk/src/cmp/zig/fragment/Entity.fragment.zig +14 -5
  144. package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +1 -1
  145. package/project/.sdk/tm/c/core/context.c +25 -0
  146. package/project/.sdk/tm/c/core/error.c +16 -0
  147. package/project/.sdk/tm/c/core/sdk.h +22 -0
  148. package/project/.sdk/tm/c/feature/audit.c +2 -0
  149. package/project/.sdk/tm/c/feature/cost.c +1 -0
  150. package/project/.sdk/tm/c/feature/debug.c +19 -29
  151. package/project/.sdk/tm/c/feature/log.c +21 -2
  152. package/project/.sdk/tm/c/feature/proxy.c +55 -3
  153. package/project/.sdk/tm/c/feature/secrets.c +7 -0
  154. package/project/.sdk/tm/c/feature/telemetry.c +2 -0
  155. package/project/.sdk/tm/c/tests/feature_test.c +2 -2
  156. package/project/.sdk/tm/c/utility/clean.c +530 -8
  157. package/project/.sdk/tm/c/utility/done.c +28 -12
  158. package/project/.sdk/tm/c/utility/make_error.c +4 -3
  159. package/project/.sdk/tm/c/utility/make_options.c +71 -45
  160. package/project/.sdk/tm/clojure/feature/secrets/sdk/feature/secrets.clj +15 -0
  161. package/project/.sdk/tm/clojure/src/sdk/client.clj +20 -4
  162. package/project/.sdk/tm/clojure/src/sdk/core.clj +319 -35
  163. package/project/.sdk/tm/clojure/src/sdk/features.clj +68 -30
  164. package/project/.sdk/tm/clojure/test/sdk/test/feature.clj +4 -2
  165. package/project/.sdk/tm/clojure/test/sdk/test/pipeline.clj +47 -20
  166. package/project/.sdk/tm/clojure/test/sdk/test_runner.clj +4 -0
  167. package/project/.sdk/tm/cpp/core/types.hpp +93 -3
  168. package/project/.sdk/tm/cpp/feature/audit.hpp +1 -0
  169. package/project/.sdk/tm/cpp/feature/cost.hpp +1 -0
  170. package/project/.sdk/tm/cpp/feature/debug.hpp +20 -12
  171. package/project/.sdk/tm/cpp/feature/log.hpp +31 -9
  172. package/project/.sdk/tm/cpp/feature/proxy.hpp +52 -6
  173. package/project/.sdk/tm/cpp/feature/secrets.hpp +13 -0
  174. package/project/.sdk/tm/cpp/feature/telemetry.hpp +4 -2
  175. package/project/.sdk/tm/cpp/test/feature_test.cpp +2 -2
  176. package/project/.sdk/tm/cpp/utility/pipeline.hpp +426 -51
  177. package/project/.sdk/tm/csharp/core/Context.cs +32 -0
  178. package/project/.sdk/tm/csharp/core/Utility.cs +2 -0
  179. package/project/.sdk/tm/csharp/feature/AuditFeature.cs +1 -0
  180. package/project/.sdk/tm/csharp/feature/CostFeature.cs +7 -5
  181. package/project/.sdk/tm/csharp/feature/DebugFeature.cs +19 -16
  182. package/project/.sdk/tm/csharp/feature/FeatureOptions.cs +16 -0
  183. package/project/.sdk/tm/csharp/feature/LogFeature.cs +4 -1
  184. package/project/.sdk/tm/csharp/feature/ProxyFeature.cs +26 -5
  185. package/project/.sdk/tm/csharp/feature/SecretsFeature.cs +16 -0
  186. package/project/.sdk/tm/csharp/feature/TelemetryFeature.cs +4 -2
  187. package/project/.sdk/tm/csharp/test/FeatureTest.cs +2 -2
  188. package/project/.sdk/tm/csharp/utility/Clean.cs +440 -2
  189. package/project/.sdk/tm/csharp/utility/Done.cs +27 -11
  190. package/project/.sdk/tm/csharp/utility/MakeError.cs +19 -8
  191. package/project/.sdk/tm/csharp/utility/MakeOptions.cs +119 -29
  192. package/project/.sdk/tm/csharp/utility/MakeResponse.cs +21 -11
  193. package/project/.sdk/tm/csharp/utility/Register.cs +1 -0
  194. package/project/.sdk/tm/elixir/lib/projectname/context.ex +19 -0
  195. package/project/.sdk/tm/elixir/lib/projectname/entity_base.ex +22 -1
  196. package/project/.sdk/tm/elixir/lib/projectname/error.ex +24 -0
  197. package/project/.sdk/tm/elixir/lib/projectname/feature/audit.ex +2 -2
  198. package/project/.sdk/tm/elixir/lib/projectname/feature/cost.ex +2 -2
  199. package/project/.sdk/tm/elixir/lib/projectname/feature/debug.ex +13 -13
  200. package/project/.sdk/tm/elixir/lib/projectname/feature/log.ex +18 -5
  201. package/project/.sdk/tm/elixir/lib/projectname/feature/proxy.ex +19 -1
  202. package/project/.sdk/tm/elixir/lib/projectname/feature/secrets.ex +15 -0
  203. package/project/.sdk/tm/elixir/lib/projectname/feature/telemetry.ex +4 -2
  204. package/project/.sdk/tm/elixir/lib/projectname/feature.ex +22 -0
  205. package/project/.sdk/tm/elixir/lib/projectname/utility.ex +464 -41
  206. package/project/.sdk/tm/elixir/test/feature_test.exs +3 -2
  207. package/project/.sdk/tm/go/core/context.go +42 -0
  208. package/project/.sdk/tm/go/core/error.go +30 -10
  209. package/project/.sdk/tm/go/core/utility_type.go +2 -0
  210. package/project/.sdk/tm/go/feature/audit_feature.go +1 -0
  211. package/project/.sdk/tm/go/feature/base_feature.go +12 -0
  212. package/project/.sdk/tm/go/feature/cost_feature.go +2 -2
  213. package/project/.sdk/tm/go/feature/debug_feature.go +14 -12
  214. package/project/.sdk/tm/go/feature/log_feature.go +13 -8
  215. package/project/.sdk/tm/go/feature/proxy_feature.go +26 -6
  216. package/project/.sdk/tm/go/feature/secrets_feature.go +19 -0
  217. package/project/.sdk/tm/go/feature/telemetry_feature.go +4 -2
  218. package/project/.sdk/tm/go/test/feature_test.go +2 -2
  219. package/project/.sdk/tm/go/utility/clean.go +585 -2
  220. package/project/.sdk/tm/go/utility/done.go +29 -9
  221. package/project/.sdk/tm/go/utility/make_error.go +51 -16
  222. package/project/.sdk/tm/go/utility/make_options.go +77 -36
  223. package/project/.sdk/tm/go/utility/register.go +12 -0
  224. package/project/.sdk/tm/java/core/Context.java +29 -0
  225. package/project/.sdk/tm/java/core/SdkClient.java +4 -2
  226. package/project/.sdk/tm/java/core/Utility.java +7 -0
  227. package/project/.sdk/tm/java/feature/AuditFeature.java +6 -0
  228. package/project/.sdk/tm/java/feature/CostFeature.java +5 -0
  229. package/project/.sdk/tm/java/feature/DebugFeature.java +25 -14
  230. package/project/.sdk/tm/java/feature/LogFeature.java +11 -4
  231. package/project/.sdk/tm/java/feature/ProxyFeature.java +41 -6
  232. package/project/.sdk/tm/java/feature/SecretsFeature.java +18 -0
  233. package/project/.sdk/tm/java/feature/TelemetryFeature.java +8 -2
  234. package/project/.sdk/tm/java/test/FeatureTest.java +2 -2
  235. package/project/.sdk/tm/java/utility/Clean.java +519 -1
  236. package/project/.sdk/tm/java/utility/Done.java +1 -1
  237. package/project/.sdk/tm/java/utility/MakeError.java +5 -1
  238. package/project/.sdk/tm/java/utility/MakeOptions.java +55 -31
  239. package/project/.sdk/tm/java/utility/Register.java +4 -0
  240. package/project/.sdk/tm/js/src/Context.js +5 -1
  241. package/project/.sdk/tm/js/src/feature/audit/AuditFeature.js +2 -2
  242. package/project/.sdk/tm/js/src/feature/cost/CostFeature.js +2 -2
  243. package/project/.sdk/tm/js/src/feature/debug/DebugFeature.js +13 -7
  244. package/project/.sdk/tm/js/src/feature/log/LogFeature.js +9 -5
  245. package/project/.sdk/tm/js/src/feature/proxy/ProxyFeature.js +19 -1
  246. package/project/.sdk/tm/js/src/feature/secrets/SecretsFeature.js +14 -0
  247. package/project/.sdk/tm/js/src/feature/telemetry/TelemetryFeature.js +4 -2
  248. package/project/.sdk/tm/js/src/utility/CleanUtility.js +294 -21
  249. package/project/.sdk/tm/js/src/utility/DoneUtility.js +17 -5
  250. package/project/.sdk/tm/js/src/utility/MakeErrorUtility.js +18 -2
  251. package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +39 -15
  252. package/project/.sdk/tm/js/src/utility/Utility.js +4 -2
  253. package/project/.sdk/tm/js/test/feature/harness.js +11 -1
  254. package/project/.sdk/tm/js/test/feature.test.js +9 -2
  255. package/project/.sdk/tm/kotlin/core/Context.kt +19 -0
  256. package/project/.sdk/tm/kotlin/core/SdkClient.kt +9 -2
  257. package/project/.sdk/tm/kotlin/core/Utility.kt +2 -0
  258. package/project/.sdk/tm/kotlin/feature/AuditFeature.kt +11 -9
  259. package/project/.sdk/tm/kotlin/feature/CostFeature.kt +8 -5
  260. package/project/.sdk/tm/kotlin/feature/DebugFeature.kt +15 -22
  261. package/project/.sdk/tm/kotlin/feature/LogFeature.kt +8 -4
  262. package/project/.sdk/tm/kotlin/feature/ProxyFeature.kt +26 -2
  263. package/project/.sdk/tm/kotlin/feature/SecretsFeature.kt +11 -0
  264. package/project/.sdk/tm/kotlin/feature/TelemetryFeature.kt +4 -2
  265. package/project/.sdk/tm/kotlin/test/FeatureTest.kt +2 -2
  266. package/project/.sdk/tm/kotlin/utility/CoreUtil.kt +447 -11
  267. package/project/.sdk/tm/kotlin/utility/MakeOptions.kt +38 -31
  268. package/project/.sdk/tm/kotlin/utility/Register.kt +1 -0
  269. package/project/.sdk/tm/lua/core/context.lua +43 -0
  270. package/project/.sdk/tm/lua/core/error.lua +36 -1
  271. package/project/.sdk/tm/lua/core/utility_type.lua +4 -0
  272. package/project/.sdk/tm/lua/feature/audit_feature.lua +2 -2
  273. package/project/.sdk/tm/lua/feature/cost_feature.lua +2 -2
  274. package/project/.sdk/tm/lua/feature/debug_feature.lua +21 -17
  275. package/project/.sdk/tm/lua/feature/log_feature.lua +2 -1
  276. package/project/.sdk/tm/lua/feature/proxy_feature.lua +23 -1
  277. package/project/.sdk/tm/lua/feature/secrets_feature.lua +18 -0
  278. package/project/.sdk/tm/lua/feature/telemetry_feature.lua +4 -2
  279. package/project/.sdk/tm/lua/test/feature/secrets/secrets_feature_test.lua +3 -2
  280. package/project/.sdk/tm/lua/test/feature_test.lua +10 -3
  281. package/project/.sdk/tm/lua/utility/clean.lua +426 -2
  282. package/project/.sdk/tm/lua/utility/clean_explain.lua +34 -0
  283. package/project/.sdk/tm/lua/utility/done.lua +1 -7
  284. package/project/.sdk/tm/lua/utility/make_error.lua +3 -1
  285. package/project/.sdk/tm/lua/utility/make_options.lua +76 -30
  286. package/project/.sdk/tm/lua/utility/register.lua +4 -1
  287. package/project/.sdk/tm/ocaml/Makefile +5 -1
  288. package/project/.sdk/tm/ocaml/feature/secrets_feature.ml +12 -1
  289. package/project/.sdk/tm/ocaml/sdk_features.ml +78 -18
  290. package/project/.sdk/tm/ocaml/sdk_helpers.ml +27 -0
  291. package/project/.sdk/tm/ocaml/sdk_runtime.ml +304 -26
  292. package/project/.sdk/tm/ocaml/sdk_types.ml +1 -0
  293. package/project/.sdk/tm/ocaml/test/feature/secrets/t_secrets.ml +3 -1
  294. package/project/.sdk/tm/ocaml/test/t_feature.ml +2 -2
  295. package/project/.sdk/tm/perl/core/context.pm +27 -0
  296. package/project/.sdk/tm/perl/core/error.pm +52 -5
  297. package/project/.sdk/tm/perl/feature/audit_feature.pm +2 -2
  298. package/project/.sdk/tm/perl/feature/cost_feature.pm +2 -2
  299. package/project/.sdk/tm/perl/feature/debug_feature.pm +17 -13
  300. package/project/.sdk/tm/perl/feature/log_feature.pm +3 -1
  301. package/project/.sdk/tm/perl/feature/proxy_feature.pm +21 -1
  302. package/project/.sdk/tm/perl/feature/secrets_feature.pm +20 -1
  303. package/project/.sdk/tm/perl/feature/telemetry_feature.pm +4 -2
  304. package/project/.sdk/tm/perl/t/feature.t +4 -2
  305. package/project/.sdk/tm/perl/utility/clean.pm +345 -1
  306. package/project/.sdk/tm/perl/utility/done.pm +24 -6
  307. package/project/.sdk/tm/perl/utility/make_error.pm +17 -4
  308. package/project/.sdk/tm/perl/utility/make_options.pm +33 -14
  309. package/project/.sdk/tm/php/core/Context.php +24 -1
  310. package/project/.sdk/tm/php/core/Error.php +34 -3
  311. package/project/.sdk/tm/php/core/UtilityType.php +4 -0
  312. package/project/.sdk/tm/php/feature/AuditFeature.php +2 -2
  313. package/project/.sdk/tm/php/feature/CostFeature.php +2 -2
  314. package/project/.sdk/tm/php/feature/DebugFeature.php +18 -9
  315. package/project/.sdk/tm/php/feature/LogFeature.php +5 -2
  316. package/project/.sdk/tm/php/feature/ProxyFeature.php +20 -1
  317. package/project/.sdk/tm/php/feature/SecretsFeature.php +18 -0
  318. package/project/.sdk/tm/php/feature/TelemetryFeature.php +4 -2
  319. package/project/.sdk/tm/php/test/FeatureTest.php +2 -2
  320. package/project/.sdk/tm/php/utility/Clean.php +438 -2
  321. package/project/.sdk/tm/php/utility/Done.php +14 -7
  322. package/project/.sdk/tm/php/utility/MakeError.php +9 -7
  323. package/project/.sdk/tm/php/utility/MakeOptions.php +62 -38
  324. package/project/.sdk/tm/php/utility/Register.php +2 -0
  325. package/project/.sdk/tm/py/pkg/core/context.py +17 -0
  326. package/project/.sdk/tm/py/pkg/core/error.py +42 -1
  327. package/project/.sdk/tm/py/pkg/core/utility_type.py +4 -0
  328. package/project/.sdk/tm/py/pkg/feature/audit_feature.py +2 -2
  329. package/project/.sdk/tm/py/pkg/feature/cost_feature.py +2 -2
  330. package/project/.sdk/tm/py/pkg/feature/debug_feature.py +17 -12
  331. package/project/.sdk/tm/py/pkg/feature/log_feature.py +2 -1
  332. package/project/.sdk/tm/py/pkg/feature/proxy_feature.py +18 -1
  333. package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +12 -0
  334. package/project/.sdk/tm/py/pkg/feature/telemetry_feature.py +4 -2
  335. package/project/.sdk/tm/py/pkg/utility/clean.py +311 -1
  336. package/project/.sdk/tm/py/pkg/utility/done.py +18 -5
  337. package/project/.sdk/tm/py/pkg/utility/make_error.py +9 -6
  338. package/project/.sdk/tm/py/pkg/utility/make_options.py +64 -25
  339. package/project/.sdk/tm/py/pkg/utility/make_response.py +19 -13
  340. package/project/.sdk/tm/py/pkg/utility/register.py +4 -2
  341. package/project/.sdk/tm/py/test/feature_harness.py +4 -0
  342. package/project/.sdk/tm/py/test/test_feature.py +2 -2
  343. package/project/.sdk/tm/py/test/test_primary_utility.py +1 -0
  344. package/project/.sdk/tm/rb/core/context.rb +28 -0
  345. package/project/.sdk/tm/rb/core/error.rb +30 -0
  346. package/project/.sdk/tm/rb/core/utility_type.rb +1 -1
  347. package/project/.sdk/tm/rb/feature/audit_feature.rb +2 -2
  348. package/project/.sdk/tm/rb/feature/cost_feature.rb +2 -2
  349. package/project/.sdk/tm/rb/feature/debug_feature.rb +15 -12
  350. package/project/.sdk/tm/rb/feature/log_feature.rb +3 -1
  351. package/project/.sdk/tm/rb/feature/proxy_feature.rb +25 -1
  352. package/project/.sdk/tm/rb/feature/secrets_feature.rb +17 -0
  353. package/project/.sdk/tm/rb/feature/telemetry_feature.rb +4 -2
  354. package/project/.sdk/tm/rb/test/feature_test.rb +4 -2
  355. package/project/.sdk/tm/rb/utility/clean.rb +312 -1
  356. package/project/.sdk/tm/rb/utility/done.rb +15 -5
  357. package/project/.sdk/tm/rb/utility/make_error.rb +13 -4
  358. package/project/.sdk/tm/rb/utility/make_options.rb +31 -12
  359. package/project/.sdk/tm/rb/utility/register.rb +2 -0
  360. package/project/.sdk/tm/rust/core/context.rs +55 -0
  361. package/project/.sdk/tm/rust/core/utility_type.rs +17 -0
  362. package/project/.sdk/tm/rust/feature/audit.rs +2 -0
  363. package/project/.sdk/tm/rust/feature/cost.rs +3 -2
  364. package/project/.sdk/tm/rust/feature/debug.rs +16 -16
  365. package/project/.sdk/tm/rust/feature/log.rs +42 -7
  366. package/project/.sdk/tm/rust/feature/proxy.rs +48 -2
  367. package/project/.sdk/tm/rust/feature/secrets.rs +12 -0
  368. package/project/.sdk/tm/rust/feature/telemetry.rs +2 -0
  369. package/project/.sdk/tm/rust/tests/feature_test.rs +2 -2
  370. package/project/.sdk/tm/rust/utility/clean.rs +446 -5
  371. package/project/.sdk/tm/rust/utility/done.rs +22 -12
  372. package/project/.sdk/tm/rust/utility/make_error.rs +4 -1
  373. package/project/.sdk/tm/rust/utility/make_options.rs +73 -19
  374. package/project/.sdk/tm/scala/Makefile +3 -1
  375. package/project/.sdk/tm/scala/core/Context.scala +16 -0
  376. package/project/.sdk/tm/scala/core/SdkClient.scala +14 -4
  377. package/project/.sdk/tm/scala/core/SdkError.scala +28 -0
  378. package/project/.sdk/tm/scala/core/Types.scala +3 -0
  379. package/project/.sdk/tm/scala/core/Utility.scala +2 -0
  380. package/project/.sdk/tm/scala/feature/AuditFeature.scala +16 -10
  381. package/project/.sdk/tm/scala/feature/CostFeature.scala +10 -5
  382. package/project/.sdk/tm/scala/feature/DebugFeature.scala +24 -21
  383. package/project/.sdk/tm/scala/feature/LogFeature.scala +9 -4
  384. package/project/.sdk/tm/scala/feature/ProxyFeature.scala +23 -2
  385. package/project/.sdk/tm/scala/feature/SecretsFeature.scala +14 -0
  386. package/project/.sdk/tm/scala/feature/TelemetryFeature.scala +9 -2
  387. package/project/.sdk/tm/scala/sdktest/SdkTestMain.scala +2 -2
  388. package/project/.sdk/tm/scala/utility/Make.scala +63 -20
  389. package/project/.sdk/tm/scala/utility/Misc.scala +358 -5
  390. package/project/.sdk/tm/scala/utility/Register.scala +1 -0
  391. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Context.swift +29 -0
  392. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Utility.swift +2 -0
  393. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/AuditFeature.swift +10 -9
  394. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/CostFeature.swift +7 -5
  395. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/DebugFeature.swift +19 -15
  396. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/FeatureOptions.swift +16 -0
  397. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/LogFeature.swift +4 -1
  398. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/ProxyFeature.swift +20 -5
  399. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/SecretsFeature.swift +13 -0
  400. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/TelemetryFeature.swift +4 -2
  401. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeError.swift +15 -5
  402. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +58 -19
  403. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Register.swift +1 -0
  404. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/ResultUtil.swift +391 -4
  405. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/FeatureTest.swift +2 -2
  406. package/project/.sdk/tm/ts/src/Context.ts +5 -1
  407. package/project/.sdk/tm/ts/src/feature/audit/AuditFeature.ts +2 -2
  408. package/project/.sdk/tm/ts/src/feature/cost/CostFeature.ts +2 -2
  409. package/project/.sdk/tm/ts/src/feature/debug/DebugFeature.ts +13 -7
  410. package/project/.sdk/tm/ts/src/feature/log/LogFeature.ts +9 -5
  411. package/project/.sdk/tm/ts/src/feature/proxy/ProxyFeature.ts +19 -1
  412. package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +12 -0
  413. package/project/.sdk/tm/ts/src/feature/telemetry/TelemetryFeature.ts +4 -2
  414. package/project/.sdk/tm/ts/src/utility/CleanUtility.ts +287 -9
  415. package/project/.sdk/tm/ts/src/utility/DoneUtility.ts +18 -5
  416. package/project/.sdk/tm/ts/src/utility/MakeErrorUtility.ts +18 -8
  417. package/project/.sdk/tm/ts/src/utility/MakeOptionsUtility.ts +38 -16
  418. package/project/.sdk/tm/ts/src/utility/Utility.ts +4 -2
  419. package/project/.sdk/tm/ts/test/feature/harness.ts +11 -1
  420. package/project/.sdk/tm/ts/test/feature.test.ts +9 -2
  421. package/project/.sdk/tm/zig/core/context.zig +34 -0
  422. package/project/.sdk/tm/zig/core/error.zig +22 -1
  423. package/project/.sdk/tm/zig/core/utility.zig +403 -39
  424. package/project/.sdk/tm/zig/feature/audit.zig +4 -2
  425. package/project/.sdk/tm/zig/feature/cost.zig +3 -2
  426. package/project/.sdk/tm/zig/feature/debug.zig +20 -25
  427. package/project/.sdk/tm/zig/feature/log.zig +3 -1
  428. package/project/.sdk/tm/zig/feature/proxy.zig +47 -6
  429. package/project/.sdk/tm/zig/feature/secrets.zig +7 -0
  430. package/project/.sdk/tm/zig/feature/telemetry.zig +4 -2
  431. package/project/.sdk/tm/zig/test/feature_test.zig +2 -2
  432. package/project/sdkgen-package.json +1 -1
  433. package/src/action/copies.ts +219 -0
  434. package/src/action/doctor.ts +247 -21
  435. package/src/action/edition.ts +10 -2
  436. package/src/action/feature.ts +11 -2
  437. package/src/action/package.ts +31 -10
  438. package/src/action/remove.ts +4 -0
  439. package/src/action/resolve.ts +16 -3
  440. package/src/action/target.ts +10 -2
  441. package/src/helpers/naming.ts +1 -1
  442. package/src/sdkgen.ts +45 -5
@@ -233,3 +233,13 @@ open class ProjectNameEntityBase: Entity {
233
233
  }
234
234
  }
235
235
  }
236
+
237
+ // An entity prints as its data, as ts and go do: `match` can hold a query
238
+ // credential from the response match, and `dump` walks every stored property.
239
+ extension ProjectNameEntityBase: CustomStringConvertible, CustomDebugStringConvertible, CustomReflectable {
240
+ public var description: Swift.String { name + " " + jsonify(.map(data), indent: 0) }
241
+ public var debugDescription: Swift.String { description }
242
+ public var customMirror: Swift.Mirror {
243
+ Swift.Mirror(self, children: ["name": name, "data": jsonify(.map(data), indent: 0)])
244
+ }
245
+ }
@@ -177,13 +177,15 @@ public final class ProjectNameSDK {
177
177
  private func rawRequest(_ fetchargsIn: ProjectNameSdk.VMap?) -> ProjectNameSdk.VMap {
178
178
  let utility = self.utility
179
179
 
180
+ // The error is returned rather than passed through makeError, so it is
181
+ // cleaned here.
180
182
  let fetchdef: ProjectNameSdk.VMap
181
183
  do {
182
184
  fetchdef = try prepare(fetchargsIn)
183
185
  } catch {
184
186
  let r = ProjectNameSdk.VMap()
185
187
  r.entries["ok"] = .bool(false)
186
- r.entries["err"] = .nat(error)
188
+ r.entries["err"] = utility.clean(rootctx, .nat(error))
187
189
  return r
188
190
  }
189
191
 
@@ -200,7 +202,7 @@ public final class ProjectNameSDK {
200
202
  } catch {
201
203
  let r = ProjectNameSdk.VMap()
202
204
  r.entries["ok"] = .bool(false)
203
- r.entries["err"] = .nat(error)
205
+ r.entries["err"] = utility.clean(ctx, .nat(error))
204
206
  return r
205
207
  }
206
208
 
@@ -311,3 +313,15 @@ public final class ProjectNameSDK {
311
313
  return sdk
312
314
  }
313
315
  }
316
+
317
+ // The client holds the credential in its options. Its default prints name
318
+ // it and nothing more, and its mirror - which `dump` and a structured
319
+ // logger walk, private stored properties included - shows only the mode
320
+ // and the feature names.
321
+ extension ProjectNameSDK: CustomStringConvertible, CustomDebugStringConvertible, CustomReflectable {
322
+ public var description: Swift.String { "ProjectNameSDK" }
323
+ public var debugDescription: Swift.String { "ProjectNameSDK(mode: " + mode + ")" }
324
+ public var customMirror: Swift.Mirror {
325
+ Swift.Mirror(self, children: ["mode": mode, "features": features.map { $0.getName() }])
326
+ }
327
+ }
@@ -3,12 +3,22 @@
3
3
 
4
4
  import Foundation
5
5
 
6
- public final class ProjectNameError: Error, CustomStringConvertible {
6
+ public final class ProjectNameError: Error {
7
7
  public let isProjectNameError = true
8
8
  public let sdk = "ProjectName"
9
- public let code: String
10
- public let message: String
9
+
10
+ // Clean rewrites the code and the message in place, since the error is
11
+ // about to be thrown.
12
+ public internal(set) var code: String
13
+ public internal(set) var message: String
14
+
15
+ // Reachable for a debugger, out of every printer and mirror: the context
16
+ // holds the live spec and options, and an error is what gets logged.
11
17
  public var ctx: Context?
18
+
19
+ // The HTTP status, -1 when there was no response.
20
+ public var status: Int = -1
21
+
12
22
  public var resultVal: Value = .noval
13
23
  public var specVal: Value = .noval
14
24
 
@@ -18,5 +28,39 @@ public final class ProjectNameError: Error, CustomStringConvertible {
18
28
  self.ctx = ctx
19
29
  }
20
30
 
31
+ public var notFound: Bool { 404 == status }
32
+
33
+ // What makeError attached is already cleaned; the context is not part of
34
+ // the record.
35
+ public func record() -> VMap {
36
+ let out = VMap()
37
+ out.entries["sdk"] = .string(sdk)
38
+ out.entries["code"] = .string(code)
39
+ out.entries["message"] = .string(message)
40
+ out.entries["status"] = .int(Int64(status))
41
+ out.entries["result"] = resultVal
42
+ out.entries["spec"] = specVal
43
+ return out
44
+ }
45
+ }
46
+
47
+ // `description` is the message; every other default print - String(reflecting:),
48
+ // debugPrint, dump - is the record, so none of them walks into the context.
49
+ extension ProjectNameError: CustomStringConvertible, CustomDebugStringConvertible, CustomReflectable {
21
50
  public var description: String { message }
51
+
52
+ public var debugDescription: String {
53
+ "ProjectNameError [" + code + "] " + message + " (status " + String(status) + ") spec="
54
+ + jsonify(specVal, indent: 0)
55
+ }
56
+
57
+ public var customMirror: Mirror {
58
+ Mirror(self, children: [
59
+ "code": code,
60
+ "message": message,
61
+ "status": status,
62
+ "result": jsonify(resultVal, indent: 0),
63
+ "spec": jsonify(specVal, indent: 0),
64
+ ])
65
+ }
22
66
  }
@@ -123,6 +123,9 @@ ${cookieHelper(spec.where)}
123
123
  }
124
124
  else {
125
125
  const b64 = Buffer.from(apikey + ':' + pass).toString('base64')
126
+ // The joined, encoded pair is a wire form neither credential's own
127
+ // registration covers.
128
+ utility.cleanAdd(ctx, b64)
126
129
  setprop(headers, CRED_name, prefix ? prefix + ' ' + b64 : b64)
127
130
  }
128
131
 
@@ -0,0 +1,465 @@
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
+
20
+ const auth = {
21
+ suppressed: isAuthSuppressed(model),
22
+ where: resolveAuthIn(model),
23
+ name: 'header' === resolveAuthIn(model)
24
+ ? resolveAuthName(model).toLowerCase() : resolveAuthName(model),
25
+ basic: isHttpBasicAuth(model),
26
+ }
27
+
28
+ File({ name: 'clean.test.ts' }, () => Content(render(auth)))
29
+ })
30
+
31
+
32
+ function render(auth: {
33
+ suppressed: boolean, where: string, name: string, basic: boolean
34
+ }): string {
35
+ return `import { test, describe } from 'node:test'
36
+ import { ok, equal, deepStrictEqual } from 'node:assert'
37
+ import { inspect } from 'node:util'
38
+
39
+ import { SDK, BaseFeature } from '..'
40
+ import { hasFeature } from './feature/harness'
41
+
42
+
43
+ // Generated: the credential's wire placement is fixed when the SDK is built.
44
+ const AUTH = ${JSON.stringify(auth)}
45
+
46
+ const CANARY = {
47
+ apikey: 'CANARY-APIKEY-k9x2m7q4p1',
48
+ secret: 'CANARY-SECRET-w3e8r5t2y6',
49
+ header: 'CANARY-HEADER-z1x4c7v0b3',
50
+ value: 'CANARY-VALUE-n5m8b2v9c4',
51
+ config: 'CANARY-CONFIG-h6j3k8l2m5',
52
+ }
53
+
54
+ const MASK = '[redacted]'
55
+
56
+ // Every form a canary can travel in.
57
+ const FORMS: string[] = []
58
+ for (const v of Object.values(CANARY)) {
59
+ FORMS.push(v, Buffer.from(v).toString('base64'), encodeURIComponent(v))
60
+ }
61
+ FORMS.push(Buffer.from(CANARY.apikey + ':' + CANARY.secret).toString('base64'))
62
+
63
+
64
+ type Sink = { name: string, text: string }
65
+
66
+
67
+ // Header maps keep the caller's spelling; the assertion should not care.
68
+ function header(map: any, name: string): any {
69
+ for (const k of Object.keys(map || {})) {
70
+ if (k.toLowerCase() === name.toLowerCase()) return map[k]
71
+ }
72
+ return undefined
73
+ }
74
+
75
+
76
+ function leaks(text: string): string[] {
77
+ return FORMS.filter((f) => text.includes(f))
78
+ }
79
+
80
+
81
+ function forms(name: string, val: any): Sink[] {
82
+ const out: Sink[] = []
83
+ const push = (kind: string, fn: () => string) => {
84
+ try { out.push({ name: name + ':' + kind, text: fn() }) } catch (_e) { }
85
+ }
86
+ push('json', () => JSON.stringify(val))
87
+ push('string', () => String(val))
88
+ push('inspect', () => inspect(val, { depth: 8 }))
89
+ if (val instanceof Error) {
90
+ push('message', () => String(val.message))
91
+ push('stack', () => String(val.stack))
92
+ push('props', () => inspect({ ...val }, { depth: 8 }))
93
+ }
94
+ return out
95
+ }
96
+
97
+
98
+ // Captures the serialised context from inside the pipeline: what a hook
99
+ // author would hand to a logger.
100
+ class CaptureFeature extends BaseFeature {
101
+ name = 'capture'
102
+ version = '0.0.1'
103
+ active = true
104
+ _sinks: Sink[]
105
+ constructor(sinks: Sink[]) { super(); this._sinks = sinks }
106
+ init() { }
107
+ PreRequest(this: any, ctx: any) { this._sinks.push(...forms('ctx@PreRequest', ctx)) }
108
+ PreResponse(this: any, ctx: any) { this._sinks.push(...forms('ctx@PreResponse', ctx)) }
109
+ // The SDK's own error as a hook reads it, which an observability feature logs.
110
+ PreUnexpected(this: any, ctx: any) {
111
+ this._sinks.push(...forms('ctx@PreUnexpected', ctx))
112
+ if (ctx.ctrl?.err instanceof Error) this._sinks.push(...forms('ctrl.err@PreUnexpected', ctx.ctrl.err))
113
+ }
114
+ }
115
+
116
+
117
+ type Scenario = { name: string, respond: (url: string, fetchdef: any, ctx?: any) => any }
118
+
119
+ function response(status: number, data: any, headers?: Record<string, string>): any {
120
+ const h: Record<string, string> = { 'content-type': 'application/json', ...(headers || {}) }
121
+ return {
122
+ status,
123
+ statusText: status < 400 ? 'OK' : 'ERR',
124
+ json: async () => data,
125
+ text: async () => JSON.stringify(data),
126
+ headers: {
127
+ get(key: string) { return h[String(key).toLowerCase()] },
128
+ forEach(cb: any) { Object.keys(h).forEach((k) => cb(h[k], k, this)) },
129
+ },
130
+ }
131
+ }
132
+
133
+ const SCENARIOS: Scenario[] = [
134
+ { name: 'ok', respond: () => response(200, { id: 'i1', name: 'n1' },
135
+ { 'x-session-token': 'RESP-TOKEN-a1b2c3d4e5' }) },
136
+ { name: 'notfound', respond: () => response(404, { error: 'no such record' }) },
137
+ { name: 'server', respond: () => response(500, { error: 'boom' }) },
138
+ { name: 'transport', respond: (url: string) => {
139
+ throw new Error('socket hang up (URL was: "' + url + '")')
140
+ } },
141
+ { name: 'notjson', respond: () => ({
142
+ status: 200, statusText: 'OK',
143
+ json: async () => { throw new Error('Unexpected token < in JSON') },
144
+ text: async () => '<html>',
145
+ headers: { get() { return undefined }, forEach() { } },
146
+ }) },
147
+ // The SDK's own error, its code quoting a registered value.
148
+ { name: 'coded', respond: (_url: string, _fetchdef: any, ctx: any) => {
149
+ throw ctx.error('denied_' + CANARY.apikey, 'coded failure')
150
+ } },
151
+ ]
152
+
153
+
154
+ function makeSdk(scenario: Scenario, sinks: Sink[], cleanopts?: any, extra?: any[]): any {
155
+ const capture = (name: string) => (rec: any) => { sinks.push(...forms(name, rec)) }
156
+ const feature: any = {}
157
+ if (hasFeature('log')) {
158
+ const logger: any = {}
159
+ for (const level of ['trace', 'debug', 'info', 'warn', 'error', 'fatal']) {
160
+ logger[level] = capture('log.' + level)
161
+ }
162
+ feature.log = { active: true, logger }
163
+ }
164
+ if (hasFeature('debug')) feature.debug = { active: true, onEntry: capture('debug') }
165
+ if (hasFeature('audit')) feature.audit = { active: true, sink: capture('audit') }
166
+ if (hasFeature('telemetry')) feature.telemetry = { active: true, exporter: capture('telemetry') }
167
+ if (hasFeature('cost')) feature.cost = { active: true, sink: capture('cost') }
168
+ if (hasFeature('metrics')) feature.metrics = { active: true }
169
+ if (hasFeature('clienttrack')) feature.clienttrack = { active: true }
170
+
171
+ const opts: any = {
172
+ apikey: CANARY.apikey,
173
+ secret: CANARY.secret,
174
+ headers: { 'X-Custom-Token': CANARY.header },
175
+ feature,
176
+ extend: [new CaptureFeature(sinks), ...(extra || [])],
177
+ utility: {
178
+ fetcher: async (ctx: any, url: string, fetchdef: any) => scenario.respond(url, fetchdef, ctx),
179
+ },
180
+ }
181
+ // null builds the client with no clean block at all, as most callers do.
182
+ if (null !== cleanopts) opts.clean = { values: CANARY.value, ...(cleanopts || {}) }
183
+ return new (SDK as any)(opts)
184
+ }
185
+
186
+
187
+ // The first operation that completes against a plain 200: with no
188
+ // arguments, else with every path parameter its points declare filled in.
189
+ type Target = { accessor: string, op: string, match: any }
190
+
191
+ async function usableOp(): Promise<Target | null> {
192
+ const plain = new (SDK as any)({
193
+ apikey: CANARY.apikey,
194
+ utility: { fetcher: async () => response(200, { id: 'i1' }) },
195
+ })
196
+ const entities: Record<string, any> = plain._rootctx.config.entity || {}
197
+ const rank = (op: string) => (({ list: 0, load: 1 } as any)[op] ?? 2)
198
+ for (const m of Object.getOwnPropertyNames(Object.getPrototypeOf(plain)).sort()) {
199
+ if (!/^[A-Z]/.test(m) || 'function' !== typeof plain[m]) { continue }
200
+ let inst: any
201
+ try { inst = plain[m]() } catch (_e) { continue }
202
+ if (null == inst || 'string' !== typeof inst.name || null == entities[inst.name]) { continue }
203
+ const opdefs = entities[inst.name].op || {}
204
+ for (const op of Object.keys(opdefs).sort((a, b) => rank(a) - rank(b))) {
205
+ const filled: any = {}
206
+ for (const point of opdefs[op].points || []) {
207
+ for (const p of point?.args?.params || []) {
208
+ if ('string' === typeof p?.name) filled[p.name] = 'p1'
209
+ }
210
+ }
211
+ for (const match of [{}, filled]) {
212
+ try {
213
+ await plain[m]()[op]({ ...match }, {})
214
+ return { accessor: m, op, match }
215
+ }
216
+ catch (_e) { continue }
217
+ }
218
+ }
219
+ }
220
+ return null
221
+ }
222
+
223
+
224
+ // A feature that throws from inside the pipeline, quoting the request it
225
+ // saw: an error makeError never handled.
226
+ class ThrowFeature extends BaseFeature {
227
+ name = 'throwhook'
228
+ version = '0.0.1'
229
+ active = true
230
+ _unexpected: boolean
231
+ constructor(unexpected = false) { super(); this._unexpected = unexpected }
232
+ init() { }
233
+ PreResponse(this: any, ctx: any) {
234
+ throw new Error('hook saw ' + JSON.stringify(ctx.spec))
235
+ }
236
+ // Fired from the operation's catch block, before its cleaning.
237
+ PreUnexpected(this: any, ctx: any) {
238
+ if (this._unexpected) throw new Error('hook saw ' + JSON.stringify(ctx.spec))
239
+ }
240
+ }
241
+
242
+
243
+ // A stream that fails while the caller iterates it, quoting a credential.
244
+ class StreamThrowFeature extends BaseFeature {
245
+ name = 'streamthrow'
246
+ version = '0.0.1'
247
+ active = true
248
+ init() { }
249
+ PreDone(this: any, ctx: any) {
250
+ ctx.result.stream = async function* () { throw new Error('stream saw ' + CANARY.apikey) }
251
+ }
252
+ }
253
+
254
+
255
+ // A stream that succeeds, so the pipeline's terminal step never runs.
256
+ class StreamOkFeature extends BaseFeature {
257
+ name = 'streamok'
258
+ version = '0.0.1'
259
+ active = true
260
+ init() { }
261
+ PreDone(this: any, ctx: any) {
262
+ const items = [].concat(ctx.result.resdata ?? [])
263
+ ctx.result.stream = async function* () { yield* items }
264
+ }
265
+ }
266
+
267
+
268
+ async function drive(sdk: any, target: Target, ctrl: any, sinks: Sink[]) {
269
+ // A caller may keep the record it passed rather than read ctrl.explain.
270
+ const held = ctrl.explain
271
+ let out: any = undefined
272
+ let err: any = undefined
273
+ try {
274
+ out = await sdk[target.accessor]()[target.op]({ ...target.match }, ctrl)
275
+ }
276
+ catch (e: any) {
277
+ err = e
278
+ }
279
+ if (undefined !== err) sinks.push(...forms('error', err))
280
+ if (undefined !== out) sinks.push(...forms('result', out))
281
+ if (null != ctrl.explain) sinks.push(...forms('explain', ctrl.explain))
282
+ if (null != held && held !== ctrl.explain) sinks.push(...forms('explain:held', held))
283
+ return err
284
+ }
285
+
286
+
287
+ describe('clean', () => {
288
+ test('no credential leaves the SDK in any form', async (t) => {
289
+ const target = await usableOp()
290
+ if (null == target) {
291
+ return t.skip('no operation of this SDK completes against a plain 200; nothing to sweep')
292
+ }
293
+
294
+ const sinks: Sink[] = []
295
+ const errors: Record<string, any> = {}
296
+ const explains: Record<string, any> = {}
297
+
298
+ for (const scenario of SCENARIOS) {
299
+ for (const variant of [
300
+ { name: 'throw', ctrl: () => ({}) },
301
+ { name: 'explain', ctrl: () => ({ explain: {} }) },
302
+ { name: 'nothrow', ctrl: () => ({ throw: false, explain: {} }) },
303
+ ]) {
304
+ const sdk = makeSdk(scenario, sinks)
305
+ const ctrl: any = variant.ctrl()
306
+ const err = await drive(sdk, target, ctrl, sinks)
307
+ const key = scenario.name + '/' + variant.name
308
+ if (null != err) errors[key] = err
309
+ if (null != ctrl.explain) explains[key] = ctrl.explain
310
+ sinks.push(...forms('sdk', sdk))
311
+ sinks.push({ name: 'sdk:spread', text: inspect({ ...sdk }, { depth: 6 }) })
312
+ }
313
+ }
314
+
315
+ // A credential mistyped as an object is rejected by validation, whose
316
+ // message quotes the value it rejected; with and without a clean block.
317
+ for (const cleanblock of [{ clean: { values: CANARY.value } }, {}]) {
318
+ let rejected: any = undefined
319
+ try {
320
+ new (SDK as any)({ apikey: { value: CANARY.apikey }, ...cleanblock })
321
+ }
322
+ catch (e: any) {
323
+ rejected = e
324
+ }
325
+ ok(null != rejected, 'a credential mistyped as an object should be rejected')
326
+ sinks.push(...forms('rejected', rejected))
327
+ }
328
+
329
+ // An error a feature hook throws, quoting the request, skips makeError.
330
+ for (const unexpected of [false, true]) {
331
+ const hooked = makeSdk(SCENARIOS[0], sinks, undefined, [new ThrowFeature(unexpected)])
332
+ const hookerr = await drive(hooked, target, { explain: {} }, sinks)
333
+ ok(null != hookerr, 'the throwing hook should fail the operation')
334
+ }
335
+
336
+ // Iterating a stream runs inside the same catch path as the operation,
337
+ // and the explain record the caller passed is cleaned however it ends.
338
+ for (const [name, extra] of [['stream', [new StreamThrowFeature()]],
339
+ ['stream-ok', [new StreamOkFeature()]], ['stream-plain', []]] as [string, any[]][]) {
340
+ const streamed = makeSdk(SCENARIOS[0], sinks, undefined, extra)
341
+ const explain = {}
342
+ let streamerr: any = undefined
343
+ try {
344
+ for await (const _item of streamed[target.accessor]().stream(
345
+ target.op, { reqmatch: { ...target.match } }, { ctrl: { explain } })) { }
346
+ }
347
+ catch (e: any) { streamerr = e }
348
+ ok(('stream' === name) === (null != streamerr), name + ': only the failing stream throws')
349
+ if (null != streamerr) sinks.push(...forms(name, streamerr))
350
+ ok(0 < Object.keys(explain).length, name + ': the explain record was not filled')
351
+ sinks.push(...forms(name + ':explain', explain))
352
+ }
353
+
354
+ // Most callers pass no clean block; the defaults alone must mask.
355
+ for (const scenario of [SCENARIOS[1], SCENARIOS[3]]) {
356
+ const bare = makeSdk(scenario, sinks, null)
357
+ await drive(bare, target, { explain: {} }, sinks)
358
+ sinks.push(...forms('bare', bare))
359
+ }
360
+
361
+ // The generated config's own clean block is read beside the caller's,
362
+ // and is not changed by it.
363
+ const util: any = makeSdk(SCENARIOS[0], sinks).utility()
364
+ const cfgclean = { keys: 'zzsens', values: CANARY.config }
365
+ const built = util.makeOptions({ utility: util, config: { options: { clean: cfgclean } },
366
+ options: { clean: { values: CANARY.value } } })
367
+ const seeded = util.clean({ options: built }, 'config ' + CANARY.config + ' caller ' + CANARY.value)
368
+ sinks.push({ name: 'config-clean', text: seeded })
369
+
370
+ // A feature's name is not a field name: only the sensitive names inside
371
+ // its settings register. An entity block, of per-entity settings or seeded
372
+ // records keyed by entity name and id, is not read at all.
373
+ const featured: any = new (SDK as any)({ apikey: CANARY.apikey, feature: {
374
+ zzsecrets: { active: false, kind: 'PLAINSETTING-q8w2e4r6' },
375
+ zzfeat: { active: false, apitoken: 'FEATTOKEN-z9y8x7w6' },
376
+ test: { active: false, entity: { zztoken: { ZZTOKEN01: { note: 'PLAINRECORD-t5r3e1w9' } } } },
377
+ }, entity: { zztoken: { alias: { zzkey: 'PLAINALIAS-m2n4b6v8' } } } })
378
+ const fctx = { options: featured._options }
379
+
380
+ // The raw path returns its failure rather than throwing it.
381
+ const raw = await makeSdk(SCENARIOS[3], sinks).direct({ path: 'raw' })
382
+ ok(false === raw.ok && null != raw.err, 'a transport failure should fail direct()')
383
+ sinks.push(...forms('direct', raw.err))
384
+
385
+ const leaked = sinks
386
+ .map((s) => ({ name: s.name, found: leaks(s.text) }))
387
+ .filter((s) => 0 < s.found.length)
388
+
389
+ console.log('clean: swept ' + sinks.length + ' surface(s), ' + leaked.length + ' leak(s)')
390
+
391
+ equal(leaked.length, 0, 'credential leaked through: ' +
392
+ leaked.map((l) => l.name + ' [' + l.found.join(', ') + ']').join('; '))
393
+
394
+ // The positive half: the slot the credential travelled in is masked,
395
+ // and an unregistered token in a response header is masked by name.
396
+ const notfound = errors['notfound/throw']
397
+ ok(null != notfound, 'the 404 scenario must throw')
398
+ equal(notfound.status, 404)
399
+ if (!AUTH.suppressed) {
400
+ const spec = notfound.spec || {}
401
+ if ('query' === AUTH.where) {
402
+ equal(header(spec.query, AUTH.name), MASK)
403
+ }
404
+ else if ('cookie' === AUTH.where) {
405
+ ok(String(header(spec.headers, 'cookie')).includes(MASK), 'cookie: ' + header(spec.headers, 'cookie'))
406
+ }
407
+ else {
408
+ ok(String(header(spec.headers, AUTH.name)).endsWith(MASK),
409
+ AUTH.name + ': ' + header(spec.headers, AUTH.name))
410
+ }
411
+ }
412
+ equal(header(notfound.spec.headers, 'x-custom-token'), MASK)
413
+
414
+ equal(seeded, 'config ' + MASK + ' caller ' + MASK)
415
+ deepStrictEqual(util.clean({ options: built }, { my_zzsens: 'x', other: 'y' }), { my_zzsens: MASK, other: 'y' })
416
+ deepStrictEqual(cfgclean, { keys: 'zzsens', values: CANARY.config })
417
+
418
+ equal(featured.utility().clean(fctx, 'kind PLAINSETTING-q8w2e4r6'), 'kind PLAINSETTING-q8w2e4r6')
419
+ equal(featured.utility().clean(fctx, 'token FEATTOKEN-z9y8x7w6'), 'token ' + MASK)
420
+ equal(featured.utility().clean(fctx, 'record PLAINRECORD-t5r3e1w9'), 'record PLAINRECORD-t5r3e1w9')
421
+ equal(featured.utility().clean(fctx, 'alias PLAINALIAS-m2n4b6v8'), 'alias PLAINALIAS-m2n4b6v8')
422
+
423
+ const coded = errors['coded/throw']
424
+ ok(null != coded, 'the coded scenario must throw')
425
+ equal(coded.code, 'denied_' + MASK)
426
+
427
+ const explained = explains['ok/explain'] || {}
428
+ ok(null != explained.result, 'the explain record should carry the result')
429
+ equal(header(explained.result.headers, 'x-session-token'), MASK)
430
+ })
431
+
432
+
433
+ test('the sweep can see a leak: clean switched off shows the credential', async (t) => {
434
+ const target = await usableOp()
435
+ if (null == target) {
436
+ return t.skip('no operation of this SDK completes against a plain 200; nothing to sweep')
437
+ }
438
+
439
+ const sinks: Sink[] = []
440
+ const sdk = makeSdk(SCENARIOS[1], sinks, { active: false })
441
+ const err = await drive(sdk, target, {}, sinks)
442
+ ok(null != err)
443
+
444
+ // Explaining a failure must not cost it its error.
445
+ const explained = await drive(makeSdk(SCENARIOS[1], [], { active: false }), target, { explain: {} }, [])
446
+ equal(explained?.message, err.message, 'with clean off, explain lost the error')
447
+
448
+ const leaked = sinks.filter((s) => 0 < leaks(s.text).length)
449
+ ok(0 < leaked.length, 'with clean off, nothing showed the canary: the sweep is blind')
450
+
451
+ if (!AUTH.suppressed) {
452
+ const text = JSON.stringify(err.spec)
453
+ ok(text.includes(CANARY.apikey) ||
454
+ text.includes(Buffer.from(CANARY.apikey + ':' + CANARY.secret).toString('base64')),
455
+ 'the raw spec should carry the credential when clean is off')
456
+ }
457
+ })
458
+ })
459
+ `
460
+ }
461
+
462
+
463
+ export {
464
+ TestClean
465
+ }
@@ -9,6 +9,7 @@ import { cmp, each, Folder, entityCollection,
9
9
 
10
10
  import { TestLive } from './TestLive_ts'
11
11
  import { TestDefinition } from './TestDefinition_ts'
12
+ import { TestClean } from './TestClean_ts'
12
13
  import { TestDirect } from './TestDirect_ts'
13
14
  import { TestEntity } from './TestEntity_ts'
14
15
  import { ReadmeExampleTest } from './ReadmeExampleTest_ts'
@@ -25,6 +26,7 @@ const Test = cmp(function Test(props: any) {
25
26
  TestControl({ target, dir: 'test' })
26
27
  TestLive({ target })
27
28
  TestDefinition({ target })
29
+ TestClean({ target })
28
30
 
29
31
  ReadmeExampleTest({ target })
30
32
  ReadmeExamplesTest({ target })
@@ -159,6 +159,8 @@ class ProjectNameEntityBase<D = any> {
159
159
  // Inbound: prefer the streaming feature's incremental iterator; else
160
160
  // fall back to the materialised items so `stream` always yields.
161
161
  if (result && 'function' === typeof result.stream) {
162
+ // done() does not run on this path, so its record is cleaned here.
163
+ utility.cleanExplain(ctx)
162
164
  for await (const item of result.stream()) {
163
165
  if (signal && signal.aborted) { return }
164
166
  yield item
@@ -200,7 +202,6 @@ class ProjectNameEntityBase<D = any> {
200
202
  const clean = this._utility.clean
201
203
  const struct = this._utility.struct
202
204
 
203
- const delprop = struct.delprop
204
205
  const clone = struct.clone
205
206
  const merge = struct.merge
206
207
 
@@ -209,8 +210,7 @@ class ProjectNameEntityBase<D = any> {
209
210
  ctrl.err = err
210
211
 
211
212
  if (ctrl.explain) {
212
- ctx.ctrl.explain = clean(ctx, ctx.ctrl.explain)
213
- delprop(ctx.ctrl.explain.result, 'err')
213
+ this._utility.cleanExplain(ctx)
214
214
 
215
215
  if (null != ctx.result && null != ctx.result.err) {
216
216
  ctrl.explain.err = clean(ctx, merge([
@@ -240,7 +240,8 @@ class ProjectNameEntityBase<D = any> {
240
240
  return undefined
241
241
  }
242
242
 
243
- return err
243
+ // An error a hook threw never passed through makeError.
244
+ return clean(ctx, err)
244
245
  }
245
246
 
246
247
  }
@@ -90,7 +90,13 @@ class EntityOperation {
90
90
  return (ctx.result && ctx.result.ok) ? this : out
91
91
  }
92
92
  catch (err: any) {
93
- // #PreUnexpected-Hook
93
+ // What a hook throws here must not escape the cleaning below.
94
+ try {
95
+ // #PreUnexpected-Hook
96
+ }
97
+ catch (hookerr: any) {
98
+ err = hookerr
99
+ }
94
100
 
95
101
  err = this._unexpected(ctx, err)
96
102
 
@@ -89,7 +89,13 @@ class EntityOperation {
89
89
  return done(ctx)
90
90
  }
91
91
  catch (err: any) {
92
- // #PreUnexpected-Hook
92
+ // What a hook throws here must not escape the cleaning below.
93
+ try {
94
+ // #PreUnexpected-Hook
95
+ }
96
+ catch (hookerr: any) {
97
+ err = hookerr
98
+ }
93
99
 
94
100
  err = this._unexpected(ctx, err)
95
101