@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
@@ -0,0 +1,671 @@
1
+ import {
2
+ cmp,
3
+ each,
4
+ entityCollection,
5
+ File,
6
+ Content,
7
+ isAuthSuppressed,
8
+ isHttpBasicAuth,
9
+ resolveAuthIn,
10
+ resolveAuthName,
11
+ } from '@voxgig/sdkgen'
12
+
13
+
14
+ import { swiftString } from './utility_swift'
15
+
16
+
17
+ // The canary sweep, the swift twin of TestClean_ts.ts. The entity accessors
18
+ // and their operations are typed methods, so the candidates the sweep drives
19
+ // are emitted from the model rather than found by walking the client at run
20
+ // time. The helper types nest in the test case: the swift type guard reads
21
+ // top-level declarations, and the Tests module is a namespace of its own.
22
+ const TestClean = cmp(function TestClean(props: any) {
23
+ const { model } = props.ctx$
24
+ const { target } = props
25
+
26
+ const auth = {
27
+ suppressed: isAuthSuppressed(model),
28
+ where: resolveAuthIn(model),
29
+ name: 'header' === resolveAuthIn(model)
30
+ ? resolveAuthName(model).toLowerCase() : resolveAuthName(model),
31
+ basic: isHttpBasicAuth(model),
32
+ }
33
+
34
+ // Same order the ts sweep tries: list, then load, then the rest.
35
+ const rank: Record<string, number> = { list: 0, load: 1 }
36
+ const candidates = each(entityCollection(model))
37
+ .filter((e: any) => false !== e.active)
38
+ .map((e: any) => ({
39
+ name: e.name,
40
+ Name: e.Name,
41
+ ops: Object.keys(e.op || {})
42
+ .sort((a, b) => (rank[a] ?? 2) - (rank[b] ?? 2)),
43
+ params: Object.fromEntries(Object.keys(e.op || {})
44
+ .map((op: string) => [op, pointParams(e.op[op])])),
45
+ }))
46
+ .filter((c: any) => 0 < c.ops.length)
47
+
48
+ // Inside Tests/<Name>SdkTests already: Test_swift.ts opens those folders.
49
+ File({ name: 'CleanTest.' + target.ext }, () =>
50
+ Content(render(model.const.Name, auth, candidates)))
51
+ })
52
+
53
+
54
+ // The path parameters an operation's points declare, as the runtime config
55
+ // carries them under points[].args.params.
56
+ function pointParams(opdef: any): string[] {
57
+ const names: string[] = []
58
+ for (const point of each(opdef?.points || [])) {
59
+ if (false === point?.a) continue
60
+ for (const arg of each(point?.g?.params || [])) {
61
+ if (false !== arg?.a && 'string' === typeof arg?.n && !names.includes(arg.n)) {
62
+ names.push(arg.n)
63
+ }
64
+ }
65
+ }
66
+ return names
67
+ }
68
+
69
+
70
+ function render(
71
+ Name: string,
72
+ auth: { suppressed: boolean, where: string, name: string, basic: boolean },
73
+ candidates: { name: string, Name: string, ops: string[], params: Record<string, string[]> }[],
74
+ ): string {
75
+ const swiftList = (items: string[]) => '[' + items.map((i) => swiftString(i)).join(', ') + ']'
76
+ const candidateLines = candidates.map((c) =>
77
+ ` Candidate(name: ${swiftString(c.name)}, accessor: { $0.${c.Name}(nil) }, ` +
78
+ `ops: ${swiftList(c.ops)}, params: [${c.ops.map((o) =>
79
+ swiftString(o) + ': ' + swiftList(c.params[o] || [])).join(', ')}]),`)
80
+ .join('\n')
81
+
82
+ return `// The canary sweep: every credential slot holds a distinctive value, every
83
+ // diagnostic feature this SDK ships is switched on with a capturing sink, a
84
+ // real operation runs through every outcome, and every string that leaves
85
+ // the SDK is searched for the canaries and their encoded forms. It also
86
+ // proves its own sensitivity: with clean switched off the canary MUST show.
87
+
88
+ import Foundation
89
+ import XCTest
90
+
91
+ @testable import ${Name}Sdk
92
+
93
+ // Generated: the credential's wire placement is fixed when the SDK is built.
94
+ private let authSuppressed = ${auth.suppressed ? 'true' : 'false'}
95
+ private let authWhere = ${swiftString(auth.where)}
96
+ private let authName = ${swiftString(auth.name)}
97
+
98
+ private let canaryApikey = "CANARY-APIKEY-k9x2m7q4p1"
99
+ private let canarySecret = "CANARY-SECRET-w3e8r5t2y6"
100
+ private let canaryHeader = "CANARY-HEADER-z1x4c7v0b3"
101
+ private let canaryValue = "CANARY-VALUE-n5m8b2v9c4"
102
+ private let canaryConfig = "CANARY-CONFIG-h6j3k8l2m5"
103
+
104
+ private let mask = "[redacted]"
105
+
106
+ // encodeURIComponent's unreserved set.
107
+ private let unreserved = CharacterSet(
108
+ charactersIn: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.!~*'()")
109
+
110
+ private func base64(_ s: String) -> String { Data(s.utf8).base64EncodedString() }
111
+
112
+ private func percent(_ s: String) -> String {
113
+ s.addingPercentEncoding(withAllowedCharacters: unreserved) ?? s
114
+ }
115
+
116
+ // Every form a canary can travel in.
117
+ private let forms: [String] = {
118
+ var out: [String] = []
119
+ for v in [canaryApikey, canarySecret, canaryHeader, canaryValue, canaryConfig] {
120
+ out.append(v)
121
+ out.append(base64(v))
122
+ out.append(percent(v))
123
+ }
124
+ out.append(base64(canaryApikey + ":" + canarySecret))
125
+ return out
126
+ }()
127
+
128
+ private func leaks(_ text: String) -> [String] {
129
+ forms.filter { text.contains($0) }
130
+ }
131
+
132
+ // Header maps keep the caller's spelling; the assertion should not care.
133
+ private func header(_ map: Value, _ name: String) -> Value {
134
+ guard let m = map.asMap else { return .noval }
135
+ for (k, v) in m.entries where k.caseInsensitiveCompare(name) == .orderedSame {
136
+ return v
137
+ }
138
+ return .noval
139
+ }
140
+
141
+ private func response(_ status: Int, _ data: Value, _ headers: [(String, String)] = []) -> Value {
142
+ let h = VMap()
143
+ h.entries["content-type"] = .string("application/json")
144
+ for (k, v) in headers { h.entries[k.lowercased()] = .string(v) }
145
+ let m = VMap()
146
+ m.entries["status"] = .int(Int64(status))
147
+ m.entries["statusText"] = .string(status < 400 ? "OK" : "ERR")
148
+ m.entries["json"] = .nat({ () -> Value in data } as NativeCall0)
149
+ m.entries["body"] = .string(jsonify(data, indent: 0))
150
+ m.entries["headers"] = .map(h)
151
+ return .map(m)
152
+ }
153
+
154
+ // The typed pipeline products read through their stored properties, so the
155
+ // raw spec is visible when clean is off - the sensitivity check depends on it.
156
+ private func render(_ any: Any?, _ depth: Int = 0) -> String {
157
+ guard let any = any, depth < 8 else { return "null" }
158
+ if let v = any as? Value {
159
+ if let n = v.asNative { return render(n, depth + 1) }
160
+ return jsonify(v, indent: 0)
161
+ }
162
+ if let m = any as? VMap { return jsonify(.map(m), indent: 0) }
163
+ if let s = any as? String { return s }
164
+ if let sp = any as? Spec {
165
+ let m = VMap()
166
+ m.entries["method"] = .string(sp.method)
167
+ m.entries["url"] = .string(sp.url)
168
+ m.entries["path"] = .string(sp.path)
169
+ m.entries["headers"] = .map(sp.headers)
170
+ m.entries["query"] = .map(sp.query)
171
+ m.entries["params"] = .map(sp.params)
172
+ m.entries["body"] = sp.body
173
+ return jsonify(.map(m), indent: 0)
174
+ }
175
+ if let ent = any as? Entity { return jsonify(ent.data(), indent: 0) }
176
+ if let ctx = any as? Context { return jsonify(.map(ctx.record()), indent: 0) }
177
+ if let e = any as? ${Name}Error { return jsonify(.map(e.record()), indent: 0) }
178
+ var out = ""
179
+ dump(any, to: &out, maxDepth: 8)
180
+ return out
181
+ }
182
+
183
+ final class ${Name}CleanTest: XCTestCase {
184
+
185
+ struct Sink {
186
+ let name: String
187
+ let text: String
188
+ }
189
+
190
+ // A reference the capturing closures share.
191
+ final class SinkBox {
192
+ var sinks: [Sink] = []
193
+ }
194
+
195
+ struct Candidate {
196
+ let name: String
197
+ let accessor: (${Name}SDK) -> ${Name}EntityBase
198
+ let ops: [String]
199
+ let params: [String: [String]]
200
+ }
201
+
202
+ struct Target {
203
+ let candidate: Candidate
204
+ let op: String
205
+ let params: [String]
206
+ }
207
+
208
+ struct TransportError: Error, CustomStringConvertible {
209
+ let message: String
210
+ var description: String { message }
211
+ }
212
+
213
+ struct Scenario {
214
+ let name: String
215
+ let respond: (String, VMap) throws -> Value
216
+ }
217
+
218
+ // Every default print a value has, plus the SDK's own record of it.
219
+ static func formsOf(_ name: String, _ val: Any?) -> [Sink] {
220
+ var out: [Sink] = []
221
+ func push(_ kind: String, _ fn: () -> String) {
222
+ out.append(Sink(name: name + ":" + kind, text: fn()))
223
+ }
224
+ guard let val = val else { return out }
225
+ push("describing") { String(describing: val) }
226
+ push("reflecting") { String(reflecting: val) }
227
+ push("dump") {
228
+ var s = ""
229
+ dump(val, to: &s, maxDepth: 8)
230
+ return s
231
+ }
232
+ push("render") { render(val) }
233
+ if let v = val as? Value { push("json") { jsonify(v, indent: 0) } }
234
+ if let m = val as? VMap { push("json") { jsonify(.map(m), indent: 0) } }
235
+ if let e = val as? ${Name}Error {
236
+ push("message") { e.message }
237
+ push("record") { jsonify(.map(e.record()), indent: 0) }
238
+ }
239
+ if let e = val as? Error { push("message") { errMessage(e) } }
240
+ if let c = val as? Context { push("record") { jsonify(.map(c.record()), indent: 0) } }
241
+ return out
242
+ }
243
+
244
+ // Captures the serialised context from inside the pipeline: what a hook
245
+ // author would hand to a logger.
246
+ final class CaptureFeature: BaseFeature {
247
+ let box: SinkBox
248
+ init(_ box: SinkBox) {
249
+ self.box = box
250
+ super.init()
251
+ name = "capture"
252
+ version = "0.0.1"
253
+ active = true
254
+ }
255
+ override func preRequest(_ ctx: Context) { box.sinks += ${Name}CleanTest.formsOf("ctx@PreRequest", ctx) }
256
+ override func preResponse(_ ctx: Context) { box.sinks += ${Name}CleanTest.formsOf("ctx@PreResponse", ctx) }
257
+
258
+ // The SDK's own error as a hook reads it, which an observability feature
259
+ // logs.
260
+ override func preUnexpected(_ ctx: Context) {
261
+ box.sinks += ${Name}CleanTest.formsOf("ctx@PreUnexpected", ctx)
262
+ if let err = ctx.ctrl.err as? ${Name}Error {
263
+ box.sinks += ${Name}CleanTest.formsOf("ctrl.err@PreUnexpected", err)
264
+ }
265
+ }
266
+ }
267
+
268
+ // A feature that fails the operation from inside the pipeline, quoting the
269
+ // request it saw. A swift hook cannot throw, so it fails the response the
270
+ // way a hook can, and the error never came from makeError.
271
+ final class FailFeature: BaseFeature {
272
+ override init() {
273
+ super.init()
274
+ name = "throwhook"
275
+ version = "0.0.1"
276
+ active = true
277
+ }
278
+ override func preResponse(_ ctx: Context) {
279
+ ctx.response?.err = TransportError(message: "hook saw " + render(ctx.spec))
280
+ }
281
+ }
282
+
283
+ // A stream that succeeds, yielding the result's items.
284
+ final class StreamOkFeature: BaseFeature {
285
+ override init() {
286
+ super.init()
287
+ name = "streamok"
288
+ version = "0.0.1"
289
+ active = true
290
+ }
291
+ override func preDone(_ ctx: Context) {
292
+ guard let result = ctx.result else { return }
293
+ let items: [Value] = result.resdata.asList?.items ?? (isNil(result.resdata) ? [] : [result.resdata])
294
+ result.stream = { items }
295
+ }
296
+ }
297
+
298
+ static let scenarios: [Scenario] = [
299
+ Scenario(name: "ok", respond: { _, _ in
300
+ response(200, .map(vm(("id", .string("i1")), ("name", .string("n1")))),
301
+ [("x-session-token", "RESP-TOKEN-a1b2c3d4e5")])
302
+ }),
303
+ Scenario(name: "notfound", respond: { _, _ in
304
+ response(404, .map(vm(("error", .string("no such record")))))
305
+ }),
306
+ Scenario(name: "server", respond: { _, _ in
307
+ response(500, .map(vm(("error", .string("boom")))))
308
+ }),
309
+ Scenario(name: "transport", respond: { url, _ in
310
+ throw TransportError(message: "socket hang up (URL was: \\"" + url + "\\")")
311
+ }),
312
+ // The SDK's own error, its code quoting a registered value.
313
+ Scenario(name: "coded", respond: { _, _ in
314
+ throw ${Name}Error("denied_" + canaryApikey, "coded failure", nil)
315
+ }),
316
+ Scenario(name: "notjson", respond: { _, _ in
317
+ let m = VMap()
318
+ m.entries["status"] = .int(200)
319
+ m.entries["statusText"] = .string("OK")
320
+ m.entries["json"] = .nat({ () -> Value in .noval } as NativeCall0)
321
+ m.entries["body"] = .string("<html>")
322
+ m.entries["headers"] = .map(VMap())
323
+ return .map(m)
324
+ }),
325
+ ]
326
+
327
+ // True when this SDK was generated with the named feature.
328
+ static func hasFeature(_ name: String) -> Bool {
329
+ gp(SdkConfig.makeConfig(), "feature").asMap?.entries[name] != nil
330
+ }
331
+
332
+ static func makeSdk(
333
+ _ scenario: Scenario, _ box: SinkBox, _ cleanopts: VMap? = nil, _ extra: [BaseFeature] = []
334
+ ) -> ${Name}SDK {
335
+ func capture(_ name: String) -> (VMap) -> Void {
336
+ return { rec in box.sinks += formsOf(name, rec) }
337
+ }
338
+
339
+ let feature = VMap()
340
+ if hasFeature("log") {
341
+ let logger: (String, String, VMap) -> Void = { level, _, attrs in
342
+ box.sinks += formsOf("log." + level, attrs)
343
+ }
344
+ feature.entries["log"] = .map(vm(("active", .bool(true)), ("logger", .nat(logger))))
345
+ }
346
+ if hasFeature("debug") {
347
+ feature.entries["debug"] = .map(vm(("active", .bool(true)), ("onEntry", .nat(capture("debug")))))
348
+ }
349
+ if hasFeature("audit") {
350
+ feature.entries["audit"] = .map(vm(("active", .bool(true)), ("sink", .nat(capture("audit")))))
351
+ }
352
+ if hasFeature("telemetry") {
353
+ feature.entries["telemetry"] = .map(vm(("active", .bool(true)), ("exporter", .nat(capture("telemetry")))))
354
+ }
355
+ if hasFeature("cost") {
356
+ let sink: (CostRecord) -> Void = { rec in box.sinks += formsOf("cost", rec) }
357
+ feature.entries["cost"] = .map(vm(("active", .bool(true)), ("sink", .nat(sink))))
358
+ }
359
+ if hasFeature("metrics") {
360
+ feature.entries["metrics"] = .map(vm(("active", .bool(true))))
361
+ }
362
+ if hasFeature("clienttrack") {
363
+ feature.entries["clienttrack"] = .map(vm(("active", .bool(true))))
364
+ }
365
+
366
+ let clean = VMap()
367
+ clean.entries["values"] = .string(canaryValue)
368
+ if let extra = cleanopts {
369
+ for (k, v) in extra.entries { clean.entries[k] = v }
370
+ }
371
+
372
+ let fetch: FetcherFunc = { _, url, fetchdef in try scenario.respond(url, fetchdef) }
373
+
374
+ let opts = VMap()
375
+ opts.entries["apikey"] = .string(canaryApikey)
376
+ opts.entries["secret"] = .string(canarySecret)
377
+ opts.entries["headers"] = .map(vm(("X-Custom-Token", .string(canaryHeader))))
378
+ opts.entries["clean"] = .map(clean)
379
+ opts.entries["feature"] = .map(feature)
380
+ var extend: [Value] = [.nat(CaptureFeature(box))]
381
+ for f in extra { extend.append(.nat(f)) }
382
+ opts.entries["extend"] = .list(VList(extend))
383
+ opts.entries["utility"] = .map(vm(("fetcher", .nat(fetch))))
384
+ return ${Name}SDK(opts)
385
+ }
386
+
387
+ // Emitted from the model: every active entity with the operations it
388
+ // declares, list and load first.
389
+ static let candidates: [Candidate] = [
390
+ ${candidateLines}
391
+ ]
392
+
393
+ static func invoke(
394
+ _ ent: ${Name}EntityBase, _ op: String, _ params: [String], _ ctrl: VMap?
395
+ ) throws -> Value {
396
+ let args = VMap()
397
+ for p in params { args.entries[p] = .string("p1") }
398
+ switch op {
399
+ case "list": return try ent.list(args, ctrl)
400
+ case "load": return try ent.load(args, ctrl)
401
+ case "create": return try ent.create(args, ctrl)
402
+ case "update": return try ent.update(args, ctrl)
403
+ case "remove": return try ent.remove(args, ctrl)
404
+ default: throw TransportError(message: "unknown operation: " + op)
405
+ }
406
+ }
407
+
408
+ // The first operation that completes against a plain 200: with no
409
+ // arguments, else with every path parameter its points declare filled in.
410
+ static func usableOp() -> Target? {
411
+ let fetch: FetcherFunc = { _, _, _ in response(200, .map(vm(("id", .string("i1"))))) }
412
+ let opts = VMap()
413
+ opts.entries["apikey"] = .string(canaryApikey)
414
+ opts.entries["utility"] = .map(vm(("fetcher", .nat(fetch))))
415
+ let plain = ${Name}SDK(opts)
416
+ for candidate in candidates {
417
+ for op in candidate.ops {
418
+ let filled: [String] = candidate.params[op] ?? []
419
+ for params in [[], filled] {
420
+ if (try? invoke(candidate.accessor(plain), op, params, nil)) != nil {
421
+ return Target(candidate: candidate, op: op, params: params)
422
+ }
423
+ }
424
+ }
425
+ }
426
+ return nil
427
+ }
428
+
429
+ static func drive(_ sdk: ${Name}SDK, _ target: Target, _ ctrl: VMap, _ box: SinkBox) -> Error? {
430
+ // A caller may keep the record it passed rather than read ctrl["explain"].
431
+ let held = ctrl.entries["explain"]?.asMap
432
+ var out: Value = .noval
433
+ var err: Error? = nil
434
+ do {
435
+ out = try invoke(target.candidate.accessor(sdk), target.op, target.params, ctrl)
436
+ } catch {
437
+ err = error
438
+ }
439
+ if let e = err { box.sinks += formsOf("error", e) }
440
+ if !isNil(out) { box.sinks += formsOf("result", out) }
441
+ if let explain = ctrl.entries["explain"]?.asMap { box.sinks += formsOf("explain", explain) }
442
+ if let h = held, h !== ctrl.entries["explain"]?.asMap { box.sinks += formsOf("explain:held", h) }
443
+ return err
444
+ }
445
+
446
+ func testNoCredentialLeavesTheSdkInAnyForm() throws {
447
+ guard let target = ${Name}CleanTest.usableOp() else {
448
+ throw XCTSkip("no operation of this SDK completes against a plain 200; nothing to sweep")
449
+ }
450
+
451
+ let box = SinkBox()
452
+ var errors: [String: Error] = [:]
453
+ var explains: [String: VMap] = [:]
454
+
455
+ let variants: [(String, () -> VMap)] = [
456
+ ("throw", { VMap() }),
457
+ ("explain", { vm(("explain", .map(VMap()))) }),
458
+ ("nothrow", { vm(("throw", .bool(false)), ("explain", .map(VMap()))) }),
459
+ ]
460
+
461
+ for scenario in ${Name}CleanTest.scenarios {
462
+ for (vname, makeCtrl) in variants {
463
+ let sdk = ${Name}CleanTest.makeSdk(scenario, box)
464
+ let ctrl = makeCtrl()
465
+ let err = ${Name}CleanTest.drive(sdk, target, ctrl, box)
466
+ let key = scenario.name + "/" + vname
467
+ if let e = err { errors[key] = e }
468
+ if let ex = ctrl.entries["explain"]?.asMap { explains[key] = ex }
469
+ box.sinks += ${Name}CleanTest.formsOf("sdk", sdk)
470
+ }
471
+ }
472
+
473
+ // A credential mistyped as a map. This struct port's validate collects
474
+ // its errors instead of throwing, so nothing rejects it: the client it
475
+ // produced is swept instead.
476
+ let mistyped = VMap()
477
+ mistyped.entries["apikey"] = .map(vm(("value", .string(canaryApikey))))
478
+ mistyped.entries["clean"] = .map(vm(("values", .string(canaryValue))))
479
+ box.sinks += ${Name}CleanTest.formsOf("mistyped", ${Name}SDK(mistyped))
480
+
481
+ // An error a feature hook raises, quoting the request, skips makeError.
482
+ // A swift hook cannot throw, so no variant fails from PreUnexpected.
483
+ let hooked = ${Name}CleanTest.makeSdk(${Name}CleanTest.scenarios[0], box, nil, [FailFeature()])
484
+ let hookerr = ${Name}CleanTest.drive(hooked, target, vm(("explain", .map(VMap()))), box)
485
+ XCTAssertNotNil(hookerr, "the failing hook should fail the operation")
486
+
487
+ // The explain record a stream call carries is cleaned however the stream
488
+ // is fed. A swift stream cannot raise, so there is no failing variant,
489
+ // and the record is complete once stream() returns.
490
+ let streams: [(String, [BaseFeature])] = [("stream-ok", [StreamOkFeature()]), ("stream-plain", [])]
491
+ for (label, extra) in streams {
492
+ let explain = VMap()
493
+ let streamed = ${Name}CleanTest.makeSdk(${Name}CleanTest.scenarios[0], box, nil, extra)
494
+ XCTAssertNoThrow(try target.candidate.accessor(streamed).stream(
495
+ target.op, nil, vm(("ctrl", .map(vm(("explain", .map(explain))))))), label + ": the stream should not fail")
496
+ XCTAssertFalse(explain.entries.isEmpty, label + ": the explain record was not filled")
497
+ box.sinks += ${Name}CleanTest.formsOf(label + ":explain", explain)
498
+ }
499
+
500
+ // The generated config's own clean block is read beside the caller's,
501
+ // and is not changed by it.
502
+ let config = vm(("options", .map(vm(("clean", .map(vm(
503
+ ("keys", .string("zzsens")), ("values", .string(canaryConfig)))))))))
504
+ let built = makeOptionsUtil(Context(
505
+ ["config": config, "options": vm(("clean", .map(vm(("values", .string(canaryValue))))))], nil))
506
+ let cfgctx = Context(["options": built], nil)
507
+ let seeded = cleanUtil(cfgctx, .string("config " + canaryConfig + " caller " + canaryValue)).asString ?? ""
508
+ box.sinks.append(Sink(name: "config-clean", text: seeded))
509
+ XCTAssertEqual(seeded, "config " + mask + " caller " + mask)
510
+ let bykey = cleanUtil(cfgctx, .map(vm(("my_zzsens", .string("x")), ("other", .string("y"))))).asMap
511
+ XCTAssertEqual(bykey?.entries["my_zzsens"], Value.string(mask))
512
+ XCTAssertEqual(bykey?.entries["other"], Value.string("y"))
513
+ XCTAssertEqual(gpath(config, "options", "clean", "values"), .string(canaryConfig))
514
+ XCTAssertEqual(gpath(config, "options", "clean", "keys"), .string("zzsens"))
515
+
516
+ // A coded SDK error inside a structure is cleaned like any other field.
517
+ let nested = cleanUtil(cfgctx, .map(vm(
518
+ ("err", .nat(${Name}Error("denied_" + canaryValue, "coded failure", nil))))))
519
+ box.sinks += ${Name}CleanTest.formsOf("coded-nested", nested)
520
+
521
+ // With no clean option at all, or one that is not a map, the schema
522
+ // defaults still apply.
523
+ for clean in [Value.noval, Value.bool(true)] {
524
+ let fetch404: FetcherFunc = { _, url, fetchdef in
525
+ try ${Name}CleanTest.scenarios[1].respond(url, fetchdef)
526
+ }
527
+ let bareopts = VMap()
528
+ bareopts.entries["apikey"] = .string(canaryApikey)
529
+ bareopts.entries["secret"] = .string(canarySecret)
530
+ bareopts.entries["headers"] = .map(vm(("X-Custom-Token", .string(canaryHeader))))
531
+ bareopts.entries["utility"] = .map(vm(("fetcher", .nat(fetch404))))
532
+ if !isNil(clean) {
533
+ bareopts.entries["clean"] = clean
534
+ }
535
+ let bareerr = ${Name}CleanTest.drive(${Name}SDK(bareopts), target, vm(("explain", .map(VMap()))), box)
536
+ XCTAssertNotNil(bareerr, "the 404 should fail with clean: " + stringify(clean))
537
+ }
538
+
539
+ // A feature's name is not a field name: only the sensitive names inside
540
+ // its settings register. An entity block, of entity settings or seeded
541
+ // records keyed by entity name and id, is not read at all.
542
+ let record = vm(("zztoken", .map(vm(("ZZTOKEN01", .map(vm(("note", .string("PLAINRECORD-t5r3e1w9")))))))))
543
+ let alias = vm(("zztoken", .map(vm(("alias", .map(vm(("zzkey", .string("PLAINALIAS-m2n4b6v8")))))))))
544
+ let featopts = VMap()
545
+ featopts.entries["apikey"] = .string(canaryApikey)
546
+ featopts.entries["feature"] = .map(vm(
547
+ ("zzsecrets", .map(vm(("active", .bool(false)), ("kind", .string("PLAINSETTING-q8w2e4r6"))))),
548
+ ("zzfeat", .map(vm(("active", .bool(false)), ("apitoken", .string("FEATTOKEN-z9y8x7w6"))))),
549
+ ("test", .map(vm(("active", .bool(false)), ("entity", .map(record)))))))
550
+ featopts.entries["entity"] = .map(alias)
551
+ let fctx = Context(["options": makeOptionsUtil(Context(["options": featopts], nil))], nil)
552
+ let fplain = cleanUtil(fctx, .string("kind PLAINSETTING-q8w2e4r6")).asString
553
+ let ftoken = cleanUtil(fctx, .string("token FEATTOKEN-z9y8x7w6")).asString
554
+ let frecord = cleanUtil(fctx, .string("record PLAINRECORD-t5r3e1w9")).asString
555
+ let falias = cleanUtil(fctx, .string("alias PLAINALIAS-m2n4b6v8")).asString
556
+
557
+ // direct() returns its error rather than throwing it. Only the SDK's own
558
+ // error can be cleaned in place, so the coded transport is the one used.
559
+ let raw = ${Name}CleanTest.makeSdk(${Name}CleanTest.scenarios[4], box).direct(vm(("path", .string("raw"))))
560
+ XCTAssertEqual(gp(raw, "ok"), .bool(false))
561
+ let rawerr = gp(raw, "err").asNative as? ${Name}Error
562
+ box.sinks += ${Name}CleanTest.formsOf("direct", rawerr)
563
+
564
+ let leaked = box.sinks
565
+ .map { (name: $0.name, found: leaks($0.text)) }
566
+ .filter { !$0.found.isEmpty }
567
+
568
+ print("clean: swept \\(box.sinks.count) surface(s), \\(leaked.count) leak(s)")
569
+
570
+ XCTAssertEqual(leaked.count, 0, "credential leaked through: " +
571
+ leaked.map { $0.name + " [" + $0.found.joined(separator: ", ") + "]" }.joined(separator: "; "))
572
+
573
+ // The positive half: the slot the credential travelled in is masked,
574
+ // and an unregistered token in a response header is masked by name.
575
+ guard let notfound = errors["notfound/throw"] as? ${Name}Error else {
576
+ XCTFail("the 404 scenario must throw")
577
+ return
578
+ }
579
+ XCTAssertEqual(notfound.status, 404)
580
+ let spec = notfound.specVal
581
+ if !authSuppressed {
582
+ if "query" == authWhere {
583
+ XCTAssertEqual(header(gp(spec, "query"), authName), .string(mask))
584
+ } else if "cookie" == authWhere {
585
+ let cookie = header(gp(spec, "headers"), "cookie").asString ?? ""
586
+ XCTAssertTrue(cookie.contains(mask), "cookie: " + cookie)
587
+ } else {
588
+ let cred = header(gp(spec, "headers"), authName).asString ?? ""
589
+ XCTAssertTrue(cred.hasSuffix(mask), authName + ": " + cred)
590
+ }
591
+ }
592
+ XCTAssertEqual(header(gp(spec, "headers"), "x-custom-token"), .string(mask))
593
+
594
+ XCTAssertEqual((errors["coded/throw"] as? ${Name}Error)?.code, "denied_" + mask)
595
+
596
+ XCTAssertEqual(fplain, "kind PLAINSETTING-q8w2e4r6")
597
+ XCTAssertEqual(ftoken, "token " + mask)
598
+ XCTAssertEqual(frecord, "record PLAINRECORD-t5r3e1w9")
599
+ XCTAssertEqual(falias, "alias PLAINALIAS-m2n4b6v8")
600
+ XCTAssertEqual(rawerr?.code, "denied_" + mask)
601
+
602
+ let explained = explains["ok/explain"] ?? VMap()
603
+ let result = gp(explained, "result")
604
+ XCTAssertFalse(isNil(result), "the explain record should carry the result")
605
+ XCTAssertEqual(header(gp(result, "headers"), "x-session-token"), .string(mask))
606
+ }
607
+
608
+ func testTheSweepCanSeeALeakCleanSwitchedOffShowsTheCredential() throws {
609
+ guard let target = ${Name}CleanTest.usableOp() else {
610
+ throw XCTSkip("no operation of this SDK completes against a plain 200; nothing to sweep")
611
+ }
612
+
613
+ let box = SinkBox()
614
+ let sdk = ${Name}CleanTest.makeSdk(${Name}CleanTest.scenarios[1], box, vm(("active", .bool(false))))
615
+ let err = ${Name}CleanTest.drive(sdk, target, VMap(), box)
616
+ XCTAssertNotNil(err, "the 404 scenario must throw")
617
+
618
+ // Explaining a failure must not cost it its error.
619
+ let explained = ${Name}CleanTest.drive(
620
+ ${Name}CleanTest.makeSdk(${Name}CleanTest.scenarios[1], SinkBox(), vm(("active", .bool(false)))),
621
+ target, vm(("explain", .map(VMap()))), SinkBox())
622
+ XCTAssertEqual(explained.map { errMessage($0) }, err.map { errMessage($0) },
623
+ "with clean off, explain lost the error")
624
+
625
+ let leaked = box.sinks.filter { !leaks($0.text).isEmpty }
626
+ XCTAssertTrue(!leaked.isEmpty, "with clean off, nothing showed the canary: the sweep is blind")
627
+
628
+ if !authSuppressed, let e = err as? ${Name}Error {
629
+ let text = render(e.specVal)
630
+ XCTAssertTrue(text.contains(canaryApikey) || text.contains(base64(canaryApikey + ":" + canarySecret)),
631
+ "the raw spec should carry the credential when clean is off")
632
+ }
633
+ }
634
+
635
+ func testARegisteredValueUsedAsAPropertyNameIsMaskedCollisionsKept() {
636
+ let cfg = makeCleanConfig(gp(SdkSchema.optspec, "clean"))
637
+ let ctx = Context(["options": vm(("__derived__", .map(vm(("clean", .nat(cfg))))))], nil)
638
+ cleanAddUtil(ctx, .string("ZZVAL-abc123"))
639
+ cleanAddUtil(ctx, .string("ZZVAL-xyz789"))
640
+ let src = vm(("ZZVAL-abc123", .int(1)), ("ZZVAL-xyz789", .int(2)), ("plain", .int(3)))
641
+ guard let out = cleanUtil(ctx, .map(src)).asMap else {
642
+ XCTFail("clean of a map should be a map")
643
+ return
644
+ }
645
+ XCTAssertEqual(out.entries[mask], Value.int(1))
646
+ XCTAssertEqual(out.entries[mask + "#1"], Value.int(2))
647
+ XCTAssertEqual(out.entries["plain"], Value.int(3))
648
+ XCTAssertNil(out.entries["ZZVAL-abc123"])
649
+ }
650
+
651
+ func testCleanAddSensitiveRegistersEveryScalarUnderASensitiveName() {
652
+ let cfg = makeCleanConfig(gp(SdkSchema.optspec, "clean"))
653
+ let ctx = Context(["options": vm(("__derived__", .map(vm(("clean", .nat(cfg))))))], nil)
654
+ cleanAddSensitiveUtil(ctx, .map(vm(
655
+ ("apikey", .map(vm(("value", .string("NESTED-SECRET-1"))))),
656
+ ("headers", .map(vm(("X-Api-Token", .list(VList([.string("LISTED-SECRET-2")])))))),
657
+ ("secret", .int(123456789)),
658
+ ("name", .string("not-a-secret")))))
659
+ XCTAssertTrue(cfg.values.contains("NESTED-SECRET-1"))
660
+ XCTAssertTrue(cfg.values.contains("LISTED-SECRET-2"))
661
+ XCTAssertTrue(cfg.values.contains("123456789"))
662
+ XCTAssertFalse(cfg.values.contains("not-a-secret"))
663
+ }
664
+ }
665
+ `
666
+ }
667
+
668
+
669
+ export {
670
+ TestClean
671
+ }
@@ -10,6 +10,7 @@ import { cmp, each, Folder, entityCollection } from '@voxgig/sdkgen'
10
10
 
11
11
  import { TestEntity } from './TestEntity_swift'
12
12
  import { TestDirect } from './TestDirect_swift'
13
+ import { TestClean } from './TestClean_swift'
13
14
  import { ReadmeExamplesTest } from './ReadmeExamplesTest_swift'
14
15
 
15
16
 
@@ -23,6 +24,8 @@ const Test = cmp(function Test(props: any) {
23
24
  // are generated here.
24
25
  Folder({ name: 'Tests' }, () => {
25
26
  Folder({ name: swiftTestDir(model) }, () => {
27
+ TestClean({ target })
28
+
26
29
  const entity = each(entityCollection(model))
27
30
  .filter((e: any) => false !== e.active)
28
31