@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,654 @@
1
+
2
+ import {
3
+ Content,
4
+ File,
5
+ cmp,
6
+ isAuthSuppressed,
7
+ isHttpBasicAuth,
8
+ resolveAuthIn,
9
+ resolveAuthName,
10
+ } from '@voxgig/sdkgen'
11
+
12
+
13
+ import type { Model } from '@voxgig/apidef'
14
+
15
+
16
+ // The canary sweep: every credential slot holds a distinctive value, every
17
+ // diagnostic feature this SDK ships is switched on with a capturing sink, a
18
+ // real operation runs through every outcome, and every string that leaves
19
+ // the SDK is searched for the canaries and their encoded forms. It also
20
+ // proves its own sensitivity: with clean switched off the canary MUST show.
21
+ const TestClean = cmp(function TestClean(props: any) {
22
+ const model: Model = props.ctx$.model
23
+ const target = props.target
24
+ const kotlinpackage: string = props.kotlinpackage
25
+
26
+ const SDK = model.const.Name + 'SDK'
27
+
28
+ const auth = {
29
+ suppressed: isAuthSuppressed(model),
30
+ where: resolveAuthIn(model),
31
+ name: 'header' === resolveAuthIn(model)
32
+ ? resolveAuthName(model).toLowerCase() : resolveAuthName(model),
33
+ basic: isHttpBasicAuth(model),
34
+ }
35
+
36
+ File({ name: 'CleanTest.' + target.ext }, () => Content(render(kotlinpackage, SDK, auth)))
37
+ })
38
+
39
+
40
+ type AuthSpec = { suppressed: boolean, where: string, name: string, basic: boolean }
41
+
42
+
43
+ function render(kotlinpackage: string, SDK: string, auth: AuthSpec): string {
44
+ return `package ${kotlinpackage}.sdktest
45
+
46
+ // The canary sweep: every credential slot holds a distinctive value, every
47
+ // diagnostic feature this SDK ships is switched on with a capturing sink, a
48
+ // real operation runs through every outcome, and every string that leaves
49
+ // the SDK is searched for the canaries and their encoded forms. It also
50
+ // proves its own sensitivity: with clean switched off the canary MUST show.
51
+
52
+ import java.io.PrintWriter
53
+ import java.io.StringWriter
54
+ import java.lang.reflect.Method
55
+ import java.lang.reflect.Modifier
56
+ import java.net.URLEncoder
57
+ import java.nio.charset.StandardCharsets
58
+ import java.util.Base64
59
+ import java.util.function.Consumer
60
+ import java.util.function.Supplier
61
+ import java.util.logging.Handler
62
+ import java.util.logging.Level
63
+ import java.util.logging.LogRecord
64
+ import java.util.logging.Logger
65
+
66
+ import org.junit.jupiter.api.Assertions.assertEquals
67
+ import org.junit.jupiter.api.Assertions.assertNotNull
68
+ import org.junit.jupiter.api.Assertions.assertTrue
69
+ import org.junit.jupiter.api.Assumptions.assumeTrue
70
+ import org.junit.jupiter.api.Test
71
+
72
+ import ${kotlinpackage}.core.Config
73
+ import ${kotlinpackage}.core.Context
74
+ import ${kotlinpackage}.core.Helpers
75
+ import ${kotlinpackage}.core.${SDK}
76
+ import ${kotlinpackage}.core.Result
77
+ import ${kotlinpackage}.core.SdkEntity
78
+ import ${kotlinpackage}.core.SdkError
79
+ import ${kotlinpackage}.core.Spec
80
+ import ${kotlinpackage}.core.Utility
81
+ import ${kotlinpackage}.feature.BaseFeature
82
+ import ${kotlinpackage}.sdktest.FeatureHarness.fhHasFeature
83
+ import ${kotlinpackage}.utility.struct.Struct
84
+
85
+ @Suppress("UNCHECKED_CAST")
86
+ class CleanTest {
87
+
88
+ // Generated: the credential's wire placement is fixed when the SDK is built.
89
+ private val authSuppressed = ${auth.suppressed}
90
+ private val authWhere = "${ktstr(auth.where)}"
91
+ private val authName = "${ktstr(auth.name)}"
92
+
93
+ private val canaryApikey = "CANARY-APIKEY-k9x2m7q4p1"
94
+ private val canarySecret = "CANARY-SECRET-w3e8r5t2y6"
95
+ private val canaryHeader = "CANARY-HEADER-z1x4c7v0b3"
96
+ private val canaryValue = "CANARY-VALUE-n5m8b2v9c4"
97
+
98
+ private val mask = "[redacted]"
99
+
100
+ private val noOp = "no operation of this SDK completes against a plain 200; nothing to sweep"
101
+
102
+ private fun b64(s: String): String =
103
+ Base64.getEncoder().encodeToString(s.toByteArray(StandardCharsets.UTF_8))
104
+
105
+ // Every form a canary can travel in.
106
+ private val forms: List<String> = run {
107
+ val out = mutableListOf<String>()
108
+ for (v in listOf(canaryApikey, canarySecret, canaryHeader, canaryValue)) {
109
+ out.add(v)
110
+ out.add(b64(v))
111
+ out.add(URLEncoder.encode(v, StandardCharsets.UTF_8))
112
+ }
113
+ out.add(b64(canaryApikey + ":" + canarySecret))
114
+ out
115
+ }
116
+
117
+ class Sink(val name: String, val text: String)
118
+
119
+ // Header maps keep the caller's spelling; the assertion should not care.
120
+ private fun header(map: Any?, name: String): Any? {
121
+ val m = Helpers.toMapAny(map) ?: return null
122
+ for ((k, v) in m) {
123
+ if (k.lowercase() == name.lowercase()) {
124
+ return v
125
+ }
126
+ }
127
+ return null
128
+ }
129
+
130
+ private fun leaks(text: String): List<String> = forms.filter { text.contains(it) }
131
+
132
+ // The SDK's own objects print their data, not a class name, so a raw spec
133
+ // handed back with clean off shows what it holds.
134
+ private fun plain(v: Any?): Any? = when (v) {
135
+ is Spec -> linkedMapOf<String, Any?>(
136
+ "method" to v.method, "url" to v.url, "path" to v.path,
137
+ "headers" to v.headers, "query" to v.query, "body" to v.body)
138
+ is Result -> linkedMapOf<String, Any?>(
139
+ "status" to v.status, "headers" to v.headers, "body" to v.body, "resdata" to v.resdata)
140
+ is SdkEntity -> v.data()
141
+ else -> v
142
+ }
143
+
144
+ private fun stack(err: Throwable): String {
145
+ val sw = StringWriter()
146
+ err.printStackTrace(PrintWriter(sw))
147
+ return sw.toString()
148
+ }
149
+
150
+ private fun surfaces(name: String, v: Any?): List<Sink> {
151
+ val out = mutableListOf<Sink>()
152
+ val push = { kind: String, fn: () -> String ->
153
+ try {
154
+ out.add(Sink(name + ":" + kind, fn()))
155
+ } catch (e: Throwable) {
156
+ }
157
+ }
158
+ push("json") { Struct.jsonify(plain(v)) }
159
+ push("string") { v.toString() }
160
+ if (v is Throwable) {
161
+ push("message") { v.message ?: "" }
162
+ push("stack") { stack(v) }
163
+ }
164
+ if (v is SdkError) {
165
+ push("map") { Struct.jsonify(v.toMap()) }
166
+ push("spec") { Struct.jsonify(plain(v.spec)) }
167
+ push("result") { Struct.jsonify(plain(v.result)) }
168
+ }
169
+ if (v is Context) {
170
+ push("record") { Struct.jsonify(v.toMap()) }
171
+ }
172
+ return out
173
+ }
174
+
175
+ // Captures the serialised context from inside the pipeline: what a hook
176
+ // author would hand to a logger.
177
+ inner class CaptureFeature(private val sinks: MutableList<Sink>) :
178
+ BaseFeature("capture", "0.0.1", true) {
179
+ override fun preRequest(ctx: Context) { sinks.addAll(surfaces("ctx@PreRequest", ctx)) }
180
+ override fun preResponse(ctx: Context) { sinks.addAll(surfaces("ctx@PreResponse", ctx)) }
181
+ override fun preUnexpected(ctx: Context) { sinks.addAll(surfaces("ctx@PreUnexpected", ctx)) }
182
+ }
183
+
184
+ // A feature that fails from inside the pipeline, quoting the request it
185
+ // saw in the code and the message. makeError cleans a failed stage, but
186
+ // PreUnexpected fires inside makeError: what a hook throws there does not
187
+ // pass through it.
188
+ inner class ThrowFeature(private val unexpected: Boolean) :
189
+ BaseFeature("throwhook", "0.0.1", true) {
190
+ private fun saw(ctx: Context): RuntimeException {
191
+ val saw = "hook saw " + Struct.jsonify(plain(ctx.spec))
192
+ return ctx.makeError(saw, saw)
193
+ }
194
+ override fun preResponse(ctx: Context) { throw saw(ctx) }
195
+ override fun preUnexpected(ctx: Context) {
196
+ if (unexpected) {
197
+ throw saw(ctx)
198
+ }
199
+ }
200
+ }
201
+
202
+ // A stream that fails while the caller iterates it, quoting a credential.
203
+ inner class StreamThrowFeature : BaseFeature("streamthrow", "0.0.1", true) {
204
+ override fun preDone(ctx: Context) {
205
+ ctx.result?.stream = Supplier<Iterator<Any?>> {
206
+ object : Iterator<Any?> {
207
+ override fun hasNext(): Boolean = throw RuntimeException("stream saw " + canaryApikey)
208
+ override fun next(): Any? = throw NoSuchElementException()
209
+ }
210
+ }
211
+ }
212
+ }
213
+
214
+ // A stream that succeeds, yielding the result's items.
215
+ inner class StreamOkFeature : BaseFeature("streamok", "0.0.1", true) {
216
+ override fun preDone(ctx: Context) {
217
+ val resdata = ctx.result?.resdata
218
+ val items: List<Any?> = when (resdata) {
219
+ is List<*> -> resdata.toList()
220
+ null -> emptyList()
221
+ else -> listOf(resdata)
222
+ }
223
+ ctx.result?.stream = Supplier<Iterator<Any?>> { items.iterator() }
224
+ }
225
+ }
226
+
227
+ class Scenario(val name: String, val respond: (String, MutableMap<String, Any?>) -> Any?)
228
+
229
+ private fun response(status: Int, data: Any?, headers: Map<String, String>?): MutableMap<String, Any?> {
230
+ val h = linkedMapOf<String, Any?>("content-type" to "application/json")
231
+ headers?.forEach { (k, v) -> h[k] = v }
232
+ val out = linkedMapOf<String, Any?>()
233
+ out["status"] = status
234
+ out["statusText"] = if (status < 400) "OK" else "ERR"
235
+ out["headers"] = h
236
+ out["json"] = Supplier<Any?> { data }
237
+ out["body"] = Struct.jsonify(data)
238
+ return out
239
+ }
240
+
241
+ private val scenarios: List<Scenario> = listOf(
242
+ Scenario("ok") { _, _ ->
243
+ response(200, linkedMapOf<String, Any?>("id" to "i1", "name" to "n1"),
244
+ mapOf("x-session-token" to "RESP-TOKEN-a1b2c3d4e5"))
245
+ },
246
+ Scenario("notfound") { _, _ ->
247
+ response(404, linkedMapOf<String, Any?>("error" to "no such record"), null)
248
+ },
249
+ Scenario("server") { _, _ ->
250
+ response(500, linkedMapOf<String, Any?>("error" to "boom"), null)
251
+ },
252
+ Scenario("transport") { url, _ ->
253
+ throw RuntimeException("socket hang up (URL was: \\"" + url + "\\")")
254
+ },
255
+ Scenario("notjson") { _, _ ->
256
+ val out = linkedMapOf<String, Any?>()
257
+ out["status"] = 200
258
+ out["statusText"] = "OK"
259
+ out["headers"] = linkedMapOf<String, Any?>()
260
+ out["json"] = Supplier<Any?> { null }
261
+ out["body"] = "<html>"
262
+ out
263
+ },
264
+ )
265
+
266
+ private fun makeSdk(scenario: Scenario, sinks: MutableList<Sink>, cleanopts: Map<String, Any?>?,
267
+ vararg extra: BaseFeature): ${SDK} {
268
+ val capture = { name: String -> Consumer<Any?> { rec -> sinks.addAll(surfaces(name, rec)) } }
269
+
270
+ val feature = linkedMapOf<String, Any?>()
271
+ if (fhHasFeature("log")) {
272
+ val logger = Logger.getLogger("clean-sweep-" + System.nanoTime())
273
+ logger.useParentHandlers = false
274
+ logger.level = Level.ALL
275
+ logger.addHandler(object : Handler() {
276
+ override fun publish(record: LogRecord) { sinks.addAll(surfaces("log", record.message)) }
277
+ override fun flush() {}
278
+ override fun close() {}
279
+ })
280
+ feature["log"] = linkedMapOf<String, Any?>("active" to true, "logger" to logger)
281
+ }
282
+ if (fhHasFeature("debug")) {
283
+ feature["debug"] = linkedMapOf<String, Any?>("active" to true, "onEntry" to capture("debug"))
284
+ }
285
+ if (fhHasFeature("audit")) {
286
+ feature["audit"] = linkedMapOf<String, Any?>("active" to true, "sink" to capture("audit"))
287
+ }
288
+ if (fhHasFeature("telemetry")) {
289
+ feature["telemetry"] = linkedMapOf<String, Any?>("active" to true, "exporter" to capture("telemetry"))
290
+ }
291
+ if (fhHasFeature("cost")) {
292
+ feature["cost"] = linkedMapOf<String, Any?>("active" to true, "sink" to capture("cost"))
293
+ }
294
+ if (fhHasFeature("metrics")) {
295
+ feature["metrics"] = linkedMapOf<String, Any?>("active" to true)
296
+ }
297
+ if (fhHasFeature("clienttrack")) {
298
+ feature["clienttrack"] = linkedMapOf<String, Any?>("active" to true)
299
+ }
300
+
301
+ val clean = linkedMapOf<String, Any?>("values" to canaryValue)
302
+ cleanopts?.forEach { (k, v) -> clean[k] = v }
303
+
304
+ val fetcher: (Context, String, MutableMap<String, Any?>) -> Any? =
305
+ { _, url, fetchdef -> scenario.respond(url, fetchdef) }
306
+
307
+ val opts = linkedMapOf<String, Any?>()
308
+ opts["apikey"] = canaryApikey
309
+ opts["secret"] = canarySecret
310
+ opts["headers"] = linkedMapOf<String, Any?>("X-Custom-Token" to canaryHeader)
311
+ opts["clean"] = clean
312
+ opts["feature"] = feature
313
+ opts["extend"] = mutableListOf<Any?>(CaptureFeature(sinks), *extra)
314
+ opts["utility"] = linkedMapOf<String, Any?>("fetcher" to fetcher)
315
+ return ${SDK}(opts)
316
+ }
317
+
318
+ class Target(val accessor: Method, val op: String, val match: Map<String, Any?>)
319
+
320
+ private fun accessors(): List<Method> =
321
+ ${SDK}::class.java.methods
322
+ .filter {
323
+ SdkEntity::class.java.isAssignableFrom(it.returnType) &&
324
+ it.parameterCount == 1 && Modifier.isPublic(it.modifiers)
325
+ }
326
+ .sortedBy { it.name }
327
+
328
+ private fun entityOf(sdk: ${SDK}, m: Method): SdkEntity? =
329
+ try {
330
+ m.invoke(sdk, *arrayOf<Any?>(null)) as? SdkEntity
331
+ } catch (e: Throwable) {
332
+ null
333
+ }
334
+
335
+ private fun call(ent: SdkEntity, op: String, match: Map<String, Any?>,
336
+ ctrl: MutableMap<String, Any?>?): Any? {
337
+ val arg = LinkedHashMap<String, Any?>(match)
338
+ return when (op) {
339
+ "list" -> ent.list(arg, ctrl)
340
+ "load" -> ent.load(arg, ctrl)
341
+ "create" -> ent.create(arg, ctrl)
342
+ "update" -> ent.update(arg, ctrl)
343
+ "remove" -> ent.remove(arg, ctrl)
344
+ else -> throw IllegalArgumentException("no such op: " + op)
345
+ }
346
+ }
347
+
348
+ // Every path parameter an operation's points declare, filled in.
349
+ private fun filled(entname: String, opname: String): Map<String, Any?> {
350
+ val out = linkedMapOf<String, Any?>()
351
+ val points = Struct.getpath(Config.sharedConfig(), listOf("entity", entname, "op", opname, "points"))
352
+ if (points !is List<*>) {
353
+ return out
354
+ }
355
+ for (point in points) {
356
+ val params = Struct.getpath(point, listOf("args", "params"))
357
+ if (params is List<*>) {
358
+ for (param in params) {
359
+ val name = Struct.getprop(param, "name")
360
+ if (name is String) {
361
+ out[name] = "p1"
362
+ }
363
+ }
364
+ }
365
+ }
366
+ return out
367
+ }
368
+
369
+ // The first operation that completes against a plain 200: with no
370
+ // arguments, else with every path parameter its points declare filled in.
371
+ private fun usableOp(): Target? {
372
+ val plainFetch: (Context, String, MutableMap<String, Any?>) -> Any? =
373
+ { _, _, _ -> response(200, linkedMapOf<String, Any?>("id" to "i1"), null) }
374
+ val plain = ${SDK}(linkedMapOf<String, Any?>(
375
+ "apikey" to canaryApikey,
376
+ "utility" to linkedMapOf<String, Any?>("fetcher" to plainFetch)))
377
+ val entities = Helpers.toMapAny(Config.sharedConfig()["entity"]) ?: linkedMapOf()
378
+ val rank = mapOf("list" to 0, "load" to 1)
379
+ for (m in accessors()) {
380
+ val inst = entityOf(plain, m) ?: continue
381
+ val ecfg = Helpers.toMapAny(entities[inst.name]) ?: continue
382
+ val ops = (Helpers.toMapAny(ecfg["op"]) ?: linkedMapOf()).keys.sortedBy { rank[it] ?: 2 }
383
+ for (op in ops) {
384
+ for (match in listOf(linkedMapOf<String, Any?>(), filled(inst.name, op))) {
385
+ try {
386
+ call(entityOf(plain, m)!!, op, match, null)
387
+ return Target(m, op, match)
388
+ } catch (e: Throwable) {
389
+ continue
390
+ }
391
+ }
392
+ }
393
+ }
394
+ return null
395
+ }
396
+
397
+ // Nothing usable is a visible skip; the lane then misses the swept line.
398
+ private fun usableOrSkip(): Target {
399
+ val target = usableOp()
400
+ if (target == null) {
401
+ println("clean: skipped: " + noOp)
402
+ }
403
+ assumeTrue(target != null, noOp)
404
+ return target!!
405
+ }
406
+
407
+ private fun drive(sdk: ${SDK}, target: Target, ctrl: MutableMap<String, Any?>?, sinks: MutableList<Sink>): Throwable? {
408
+ // A caller may keep the record it passed rather than read ctrl's entry.
409
+ val held = ctrl?.get("explain")
410
+ var out: Any? = null
411
+ var err: Throwable? = null
412
+ try {
413
+ out = call(entityOf(sdk, target.accessor)!!, target.op, target.match, ctrl)
414
+ } catch (e: Throwable) {
415
+ err = e
416
+ }
417
+ if (err != null) {
418
+ sinks.addAll(surfaces("error", err))
419
+ }
420
+ if (out != null) {
421
+ sinks.addAll(surfaces("result", out))
422
+ }
423
+ val explain = ctrl?.get("explain")
424
+ if (explain != null) {
425
+ sinks.addAll(surfaces("explain", explain))
426
+ }
427
+ if (held != null && held !== explain) {
428
+ sinks.addAll(surfaces("explain:held", held))
429
+ }
430
+ return err
431
+ }
432
+
433
+ @Test
434
+ fun noCredentialLeavesTheSdkInAnyForm() {
435
+ val target = usableOrSkip()
436
+
437
+ val sinks = mutableListOf<Sink>()
438
+ val errors = linkedMapOf<String, Throwable>()
439
+ val explains = linkedMapOf<String, MutableMap<String, Any?>>()
440
+
441
+ for (scenario in scenarios) {
442
+ for (variant in listOf("throw", "explain", "nothrow")) {
443
+ val sdk = makeSdk(scenario, sinks, null)
444
+ val ctrl: MutableMap<String, Any?>? = when (variant) {
445
+ "throw" -> null
446
+ "explain" -> linkedMapOf<String, Any?>("explain" to linkedMapOf<String, Any?>())
447
+ else -> linkedMapOf<String, Any?>("throw" to false, "explain" to linkedMapOf<String, Any?>())
448
+ }
449
+ val err = drive(sdk, target, ctrl, sinks)
450
+ val key = scenario.name + "/" + variant
451
+ if (err != null) {
452
+ errors[key] = err
453
+ }
454
+ val explain = Helpers.toMapAny(ctrl?.get("explain"))
455
+ if (explain != null) {
456
+ explains[key] = explain
457
+ }
458
+ sinks.addAll(surfaces("sdk", sdk))
459
+ }
460
+ }
461
+
462
+ // No clean option at all: the schema defaults still apply.
463
+ val bareFetch: (Context, String, MutableMap<String, Any?>) -> Any? =
464
+ { _, url, fetchdef -> scenarios[1].respond(url, fetchdef) }
465
+ val bare = ${SDK}(linkedMapOf<String, Any?>(
466
+ "apikey" to canaryApikey,
467
+ "secret" to canarySecret,
468
+ "headers" to linkedMapOf<String, Any?>("X-Custom-Token" to canaryHeader),
469
+ "utility" to linkedMapOf<String, Any?>("fetcher" to bareFetch)))
470
+ assertNotNull(drive(bare, target, null, sinks), "the 404 should fail")
471
+
472
+ // A credential mistyped as a map. The kotlin validator collects its
473
+ // errors and substitutes the default rather than rejecting, so there is
474
+ // no rejection to sweep: sweep the client, and what clean makes of the
475
+ // value should anything quote it.
476
+ try {
477
+ val mistyped = ${SDK}(linkedMapOf<String, Any?>(
478
+ "apikey" to linkedMapOf<String, Any?>("value" to canaryApikey),
479
+ "clean" to linkedMapOf<String, Any?>("values" to canaryValue)))
480
+ sinks.addAll(surfaces("mistyped", mistyped))
481
+ sinks.addAll(surfaces("mistyped:quoted",
482
+ mistyped.getUtility().clean(mistyped.getRootCtx(), "found map: " + canaryApikey)))
483
+ } catch (e: RuntimeException) {
484
+ sinks.addAll(surfaces("mistyped:rejected", e))
485
+ }
486
+
487
+ // A number is registered as the text a message quotes it in.
488
+ val numeric = ${SDK}(linkedMapOf<String, Any?>("apikey" to 918273645))
489
+ val numbered = numeric.getUtility().clean(numeric.getRootCtx(), "found 918273645")
490
+
491
+ for (unexpected in listOf(false, true)) {
492
+ val hooked = makeSdk(scenarios[0], sinks, null, ThrowFeature(unexpected))
493
+ assertNotNull(drive(hooked, target, linkedMapOf<String, Any?>("explain" to linkedMapOf<String, Any?>()), sinks),
494
+ "the throwing hook should fail the operation")
495
+ }
496
+
497
+ // Iterating a stream runs inside the same catch path as the operation,
498
+ // and the explain record the caller passed is cleaned however it ends.
499
+ for ((name, extra) in listOf<Pair<String, Array<BaseFeature>>>(
500
+ Pair("stream", arrayOf(StreamThrowFeature())),
501
+ Pair("stream-ok", arrayOf(StreamOkFeature())),
502
+ Pair("stream-plain", arrayOf()))) {
503
+ val streaming = entityOf(makeSdk(scenarios[0], sinks, null, *extra), target.accessor)!!
504
+ val explain = linkedMapOf<String, Any?>()
505
+ var streamerr: Throwable? = null
506
+ try {
507
+ streaming.stream(target.op, linkedMapOf<String, Any?>("reqmatch" to LinkedHashMap(target.match)),
508
+ linkedMapOf<String, Any?>("ctrl" to linkedMapOf<String, Any?>("explain" to explain)))
509
+ .forEach { }
510
+ } catch (e: Throwable) {
511
+ streamerr = e
512
+ }
513
+ assertEquals("stream" == name, streamerr != null, name + ": only the failing stream throws")
514
+ if (streamerr != null) {
515
+ sinks.addAll(surfaces(name, streamerr))
516
+ }
517
+ assertTrue(explain.isNotEmpty(), name + ": the explain record was not filled")
518
+ sinks.addAll(surfaces(name + ":explain", explain))
519
+ }
520
+
521
+ // The raw path returns its failure rather than throwing it.
522
+ val raw = makeSdk(scenarios[3], sinks, null).direct(linkedMapOf<String, Any?>("path" to "raw"))
523
+ assertTrue(false == raw["ok"] && raw["err"] is Throwable,
524
+ "a transport failure should fail direct() with an error")
525
+ sinks.addAll(surfaces("direct", raw["err"]))
526
+
527
+ // A registered value used as a property name is masked; names that mask
528
+ // alike are kept apart.
529
+ val probe = makeSdk(scenarios[0], sinks, null)
530
+ val named = probe.getUtility().clean(probe.getRootCtx(),
531
+ linkedMapOf<String, Any?>(canaryValue to 1, canaryHeader to 2, "plain" to 3))
532
+ sinks.addAll(surfaces("named", named))
533
+
534
+ val leaked = sinks
535
+ .map { Pair(it.name, leaks(it.text)) }
536
+ .filter { it.second.isNotEmpty() }
537
+
538
+ println("clean: swept " + sinks.size + " surface(s), " + leaked.size + " leak(s)")
539
+
540
+ assertEquals(0, leaked.size, "credential leaked through: " +
541
+ leaked.joinToString("; ") { it.first + " [" + it.second.joinToString(", ") + "]" })
542
+
543
+ assertEquals("found " + mask, numbered)
544
+ assertEquals(linkedMapOf<String, Any?>(mask to 1, mask + "#1" to 2, "plain" to 3), named)
545
+
546
+ // The positive half: the slot the credential travelled in is masked,
547
+ // and an unregistered token in a response header is masked by name.
548
+ val notfound = errors["notfound/throw"]
549
+ assertNotNull(notfound, "the 404 scenario must throw")
550
+ assertTrue(notfound is SdkError, "the 404 scenario should throw an SdkError, got " + notfound)
551
+ val nf = notfound as SdkError
552
+ assertEquals(404, nf.status)
553
+ val spec = Helpers.toMapAny(nf.spec) ?: linkedMapOf()
554
+ if (!authSuppressed) {
555
+ if ("query" == authWhere) {
556
+ assertEquals(mask, header(spec["query"], authName))
557
+ } else if ("cookie" == authWhere) {
558
+ assertTrue(header(spec["headers"], "cookie").toString().contains(mask),
559
+ "cookie: " + header(spec["headers"], "cookie"))
560
+ } else {
561
+ assertTrue(header(spec["headers"], authName).toString().endsWith(mask),
562
+ authName + ": " + header(spec["headers"], authName))
563
+ }
564
+ }
565
+ assertEquals(mask, header(spec["headers"], "x-custom-token"))
566
+
567
+ val explained = explains["ok/explain"] ?: linkedMapOf()
568
+ val result = Helpers.toMapAny(explained["result"])
569
+ assertNotNull(result, "the explain record should carry the result")
570
+ assertEquals(mask, header(result!!["headers"], "x-session-token"))
571
+ }
572
+
573
+ @Test
574
+ fun theSweepCanSeeALeakCleanSwitchedOffShowsTheCredential() {
575
+ val target = usableOrSkip()
576
+
577
+ val sinks = mutableListOf<Sink>()
578
+ val sdk = makeSdk(scenarios[1], sinks, mapOf("active" to false))
579
+ val err = drive(sdk, target, null, sinks)
580
+ assertNotNull(err)
581
+
582
+ // Explaining a failure must not cost it its error.
583
+ val explained = drive(makeSdk(scenarios[1], mutableListOf(), mapOf("active" to false)), target,
584
+ linkedMapOf<String, Any?>("explain" to linkedMapOf<String, Any?>()), mutableListOf())
585
+ assertEquals(err?.message, explained?.message, "with clean off, explain lost the error")
586
+
587
+ val leaked = sinks.filter { leaks(it.text).isNotEmpty() }
588
+ assertTrue(leaked.isNotEmpty(), "with clean off, nothing showed the canary: the sweep is blind")
589
+
590
+ if (!authSuppressed) {
591
+ val text = Struct.jsonify(plain((err as? SdkError)?.spec))
592
+ assertTrue(text.contains(canaryApikey) || text.contains(b64(canaryApikey + ":" + canarySecret)),
593
+ "the raw spec should carry the credential when clean is off")
594
+ }
595
+ }
596
+
597
+ // An entity block, of per-entity settings or seeded records keyed by
598
+ // entity name and id, is not read at all.
599
+ @Test
600
+ fun aFeatureNameDoesNotMakeItsSettingsSecret() {
601
+ val sdk = ${SDK}(linkedMapOf<String, Any?>(
602
+ "apikey" to canaryApikey,
603
+ "feature" to linkedMapOf<String, Any?>(
604
+ "secrets" to linkedMapOf<String, Any?>(
605
+ "active" to false, "kind" to "SETTING-KIND-4829", "token" to canarySecret),
606
+ "test" to linkedMapOf<String, Any?>("active" to false, "entity" to linkedMapOf<String, Any?>(
607
+ "zztoken" to linkedMapOf<String, Any?>(
608
+ "ZZTOKEN01" to linkedMapOf<String, Any?>("note" to "PLAINRECORD-t5r3e1w9"))))),
609
+ "entity" to linkedMapOf<String, Any?>("zztoken" to linkedMapOf<String, Any?>(
610
+ "alias" to linkedMapOf<String, Any?>("zzkey" to "PLAINALIAS-m2n4b6v8")))))
611
+ val root = sdk.getRootCtx()
612
+ assertEquals("SETTING-KIND-4829 " + mask,
613
+ sdk.getUtility().clean(root, "SETTING-KIND-4829 " + canarySecret))
614
+ assertEquals("record PLAINRECORD-t5r3e1w9",
615
+ sdk.getUtility().clean(root, "record PLAINRECORD-t5r3e1w9"))
616
+ assertEquals("alias PLAINALIAS-m2n4b6v8",
617
+ sdk.getUtility().clean(root, "alias PLAINALIAS-m2n4b6v8"))
618
+ }
619
+
620
+ @Test
621
+ fun theGeneratedConfigsOwnCleanBlockIsHonoured() {
622
+ val cfgclean = linkedMapOf<String, Any?>("keys" to "zzsens", "values" to "CONFIG-SEEDED-1")
623
+ val utility = Utility()
624
+ val ctx = utility.makeContext(linkedMapOf<String, Any?>(
625
+ "utility" to utility,
626
+ "config" to linkedMapOf<String, Any?>("options" to linkedMapOf<String, Any?>("clean" to cfgclean)),
627
+ "options" to linkedMapOf<String, Any?>(
628
+ "clean" to linkedMapOf<String, Any?>("values" to "CALLER-SEEDED-2"))), null)
629
+ ctx.options = utility.makeOptions(ctx)
630
+
631
+ assertEquals("a " + mask + " b " + mask,
632
+ utility.clean(ctx, "a CONFIG-SEEDED-1 b CALLER-SEEDED-2"))
633
+ assertEquals(linkedMapOf<String, Any?>("my_zzsens" to mask, "other" to "y"),
634
+ utility.clean(ctx, linkedMapOf<String, Any?>("my_zzsens" to "x", "other" to "y")))
635
+ assertEquals("CONFIG-SEEDED-1", cfgclean["values"])
636
+ }
637
+ }
638
+ `
639
+ }
640
+
641
+
642
+ // A Kotlin double-quoted string literal body: the auth name comes from the
643
+ // API's own securityScheme.
644
+ function ktstr(s: string): string {
645
+ return String(s)
646
+ .replace(/\\/g, '\\\\')
647
+ .replace(/"/g, '\\"')
648
+ .replace(/\$/g, '\\$')
649
+ }
650
+
651
+
652
+ export {
653
+ TestClean
654
+ }
@@ -9,6 +9,7 @@ import { cmp, each, Folder, entityCollection,
9
9
 
10
10
  import { TestEntity } from './TestEntity_kotlin'
11
11
  import { TestDirect } from './TestDirect_kotlin'
12
+ import { TestClean } from './TestClean_kotlin'
12
13
  import { ReadmeExamplesTest } from './ReadmeExamplesTest_kotlin'
13
14
  import { kotlinPackage } from './utility_kotlin'
14
15
 
@@ -24,6 +25,8 @@ const Test = cmp(function Test(props: any) {
24
25
  // Write-once: a project's edited control file survives regeneration.
25
26
  TestControl({ target, dir: 'test' })
26
27
 
28
+ TestClean({ target, kotlinpackage })
29
+
27
30
  const entity = each(entityCollection(model))
28
31
  .filter((e: any) => false !== e.active)
29
32
  each(entity, (entity: ModelEntity) => {