@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,549 @@
1
+ import {
2
+ cmp,
3
+ File,
4
+ Content,
5
+ isAuthSuppressed,
6
+ isHttpBasicAuth,
7
+ resolveAuthIn,
8
+ resolveAuthName,
9
+ } from '@voxgig/sdkgen'
10
+
11
+
12
+ // The canary sweep: every credential slot holds a distinctive value, every
13
+ // diagnostic feature this SDK ships is switched on with a capturing sink, a
14
+ // real operation runs through every outcome, and every string that leaves
15
+ // the SDK is searched for the canaries and their encoded forms. It also
16
+ // proves its own sensitivity: with clean switched off the canary MUST show.
17
+ const TestClean = cmp(function TestClean(props: any) {
18
+ const { model } = props.ctx$
19
+ const { target } = props
20
+
21
+ const auth = {
22
+ suppressed: isAuthSuppressed(model),
23
+ where: resolveAuthIn(model),
24
+ name: 'header' === resolveAuthIn(model)
25
+ ? resolveAuthName(model).toLowerCase() : resolveAuthName(model),
26
+ basic: isHttpBasicAuth(model),
27
+ }
28
+
29
+ File({ name: 'test_clean.' + target.ext }, () => Content(render(model.const.Name, auth)))
30
+ })
31
+
32
+
33
+ function render(Name: string, auth: {
34
+ suppressed: boolean, where: string, name: string, basic: boolean
35
+ }): string {
36
+ const pkg = Name.toLowerCase() + '_sdk'
37
+
38
+ return `# ${Name} SDK clean test
39
+ #
40
+ # The canary sweep: no credential leaves the SDK in any form.
41
+
42
+ import base64
43
+ import json
44
+ import traceback
45
+ from urllib.parse import quote
46
+
47
+ import pytest
48
+
49
+ from ${pkg} import ${Name}SDK
50
+ from ${pkg}.core.error import ${Name}Error
51
+ from ${pkg}.feature.base_feature import ${Name}BaseFeature
52
+ from test.feature_harness import has_feature
53
+
54
+
55
+ # Generated: the credential's wire placement is fixed when the SDK is built.
56
+ AUTH = ${JSON.stringify(auth)
57
+ .replace(/true/g, 'True').replace(/false/g, 'False')}
58
+
59
+ CANARY = {
60
+ "apikey": "CANARY-APIKEY-k9x2m7q4p1",
61
+ "secret": "CANARY-SECRET-w3e8r5t2y6",
62
+ "header": "CANARY-HEADER-z1x4c7v0b3",
63
+ "value": "CANARY-VALUE-n5m8b2v9c4",
64
+ "config": "CANARY-CONFIG-h6j3k8l2m5",
65
+ }
66
+
67
+ MASK = "[redacted]"
68
+
69
+ NO_OP = "no operation of this SDK completes against a plain 200; nothing to sweep"
70
+
71
+
72
+ def _b64(s):
73
+ return base64.b64encode(s.encode("utf-8")).decode("ascii")
74
+
75
+
76
+ # Every form a canary can travel in.
77
+ FORMS = []
78
+ for _v in CANARY.values():
79
+ FORMS.extend([_v, _b64(_v), quote(_v, safe="")])
80
+ FORMS.append(_b64(CANARY["apikey"] + ":" + CANARY["secret"]))
81
+
82
+
83
+ # Header maps keep the caller's spelling; the assertion should not care.
84
+ def _header(m, name):
85
+ for k in (m or {}):
86
+ if str(k).lower() == name.lower():
87
+ return m[k]
88
+ return None
89
+
90
+
91
+ def _leaks(text):
92
+ return [f for f in FORMS if f in text]
93
+
94
+
95
+ def _plain(v):
96
+ return v if isinstance(v, dict) or v is None else vars(v)
97
+
98
+
99
+ # Every default print of a value: json, str and repr, plus what an
100
+ # exception shows a traceback and an attribute dump.
101
+ def _forms(name, val):
102
+ out = []
103
+
104
+ def push(kind, fn):
105
+ try:
106
+ out.append((name + ":" + kind, fn()))
107
+ except Exception:
108
+ pass
109
+
110
+ push("json", lambda: json.dumps(val, default=str))
111
+ push("str", lambda: str(val))
112
+ push("repr", lambda: repr(val))
113
+ if isinstance(val, BaseException):
114
+ push("message", lambda: str(val.args))
115
+ push("traceback", lambda: "".join(traceback.format_exception(val)))
116
+ push("vars", lambda: json.dumps(vars(val), default=str))
117
+ push("spec", lambda: json.dumps(_plain(getattr(val, "spec", None)), default=str))
118
+ push("result", lambda: json.dumps(_plain(getattr(val, "result", None)), default=str))
119
+ if callable(getattr(val, "to_json", None)):
120
+ push("to_json", lambda: json.dumps(val.to_json(), default=str))
121
+ if callable(getattr(val, "data_get", None)):
122
+ push("data", lambda: json.dumps(val.data_get(), default=str))
123
+ return out
124
+
125
+
126
+ # Captures the serialised context from inside the pipeline: what a hook
127
+ # author would hand to a logger.
128
+ class _CaptureFeature(${Name}BaseFeature):
129
+ def __init__(self, sinks):
130
+ super().__init__()
131
+ self.name = "capture"
132
+ self.version = "0.0.1"
133
+ self.active = True
134
+ self._sinks = sinks
135
+
136
+ def init(self, ctx, options):
137
+ pass
138
+
139
+ def PreRequest(self, ctx):
140
+ self._sinks.extend(_forms("ctx@PreRequest", ctx))
141
+
142
+ def PreResponse(self, ctx):
143
+ self._sinks.extend(_forms("ctx@PreResponse", ctx))
144
+
145
+ # The SDK's own error as a hook reads it, which an observability
146
+ # feature logs.
147
+ def PreUnexpected(self, ctx):
148
+ self._sinks.extend(_forms("ctx@PreUnexpected", ctx))
149
+ if isinstance(ctx.ctrl.err, ${Name}Error):
150
+ self._sinks.extend(_forms("ctrl.err@PreUnexpected", ctx.ctrl.err))
151
+
152
+
153
+ def _response(status, data, headers=None):
154
+ h = {"content-type": "application/json"}
155
+ h.update(headers or {})
156
+ return {
157
+ "status": status,
158
+ "statusText": "OK" if status < 400 else "ERR",
159
+ "headers": h,
160
+ "json": lambda: data,
161
+ "body": json.dumps(data),
162
+ }
163
+
164
+
165
+ def _notjson():
166
+ def raise_json():
167
+ raise ValueError("Unexpected token < in JSON")
168
+ return {
169
+ "status": 200,
170
+ "statusText": "OK",
171
+ "headers": {},
172
+ "json": raise_json,
173
+ "body": "<html>",
174
+ }
175
+
176
+
177
+ # The transport answers a (response, error) pair; a transport error is the
178
+ # pair with the error set, and its message quotes the URL.
179
+ SCENARIOS = [
180
+ ("ok", lambda url, fetchdef: (_response(200, {"id": "i1", "name": "n1"},
181
+ {"x-session-token": "RESP-TOKEN-a1b2c3d4e5"}), None)),
182
+ ("notfound", lambda url, fetchdef: (_response(404, {"error": "no such record"}), None)),
183
+ ("server", lambda url, fetchdef: (_response(500, {"error": "boom"}), None)),
184
+ ("transport", lambda url, fetchdef: (None, RuntimeError('socket hang up (URL was: "' + url + '")'))),
185
+ # The SDK's own error, its code quoting a registered value.
186
+ ("coded", lambda url, fetchdef: (None, ${Name}Error("denied_" + CANARY["apikey"], "coded failure"))),
187
+ ("notjson", lambda url, fetchdef: (_notjson(), None)),
188
+ ]
189
+
190
+
191
+ def _make_sdk(respond, sinks, cleanopts=None, extra=None):
192
+ def capture(name):
193
+ return lambda rec, *a: sinks.extend(_forms(name, rec))
194
+
195
+ feature = {}
196
+ if has_feature("log"):
197
+ logger = {}
198
+ for level in ["trace", "debug", "info", "warn", "error", "fatal"]:
199
+ logger[level] = capture("log." + level)
200
+ feature["log"] = {"active": True, "logger": logger}
201
+ if has_feature("debug"):
202
+ feature["debug"] = {"active": True, "onEntry": capture("debug")}
203
+ if has_feature("audit"):
204
+ feature["audit"] = {"active": True, "sink": capture("audit")}
205
+ if has_feature("telemetry"):
206
+ feature["telemetry"] = {"active": True, "exporter": capture("telemetry")}
207
+ if has_feature("cost"):
208
+ feature["cost"] = {"active": True, "sink": capture("cost")}
209
+ if has_feature("metrics"):
210
+ feature["metrics"] = {"active": True}
211
+ if has_feature("clienttrack"):
212
+ feature["clienttrack"] = {"active": True}
213
+
214
+ clean = {"values": CANARY["value"]}
215
+ clean.update(cleanopts or {})
216
+
217
+ return ${Name}SDK({
218
+ "apikey": CANARY["apikey"],
219
+ "secret": CANARY["secret"],
220
+ "headers": {"X-Custom-Token": CANARY["header"]},
221
+ "clean": clean,
222
+ "feature": feature,
223
+ "extend": [_CaptureFeature(sinks)] + list(extra or []),
224
+ "utility": {"fetcher": lambda ctx, url, fetchdef: respond(url, fetchdef)},
225
+ })
226
+
227
+
228
+ # The first operation that completes against a plain 200: with no
229
+ # arguments, else with every path parameter its points declare filled in.
230
+ def _usable_op():
231
+ def plain():
232
+ return ${Name}SDK({
233
+ "apikey": CANARY["apikey"],
234
+ "utility": {"fetcher": lambda ctx, url, fetchdef: (_response(200, {"id": "i1"}), None)},
235
+ })
236
+
237
+ client = plain()
238
+ entities = (client.get_root_ctx().config or {}).get("entity") or {}
239
+ found = {}
240
+ for attr in dir(client):
241
+ if not attr[:1].isupper():
242
+ continue
243
+ acc = getattr(client, attr, None)
244
+ if not callable(acc):
245
+ continue
246
+ try:
247
+ ent = acc()
248
+ except Exception:
249
+ continue
250
+ getname = getattr(ent, "get_name", None)
251
+ if not callable(getname):
252
+ continue
253
+ name = getname()
254
+ if isinstance(name, str) and name != "":
255
+ found[name] = (attr, ent)
256
+
257
+ safe = {"list": 0, "load": 1}
258
+ for name in sorted(found):
259
+ accessor, ent = found[name]
260
+ ops = [op for op in ["list", "load", "create", "update", "remove"]
261
+ if callable(getattr(ent, op, None))]
262
+ ops.sort(key=lambda o: safe.get(o, 2))
263
+ opdefs = (entities.get(name) or {}).get("op") or {}
264
+ for op in ops:
265
+ filled = {}
266
+ for point in (opdefs.get(op) or {}).get("points") or []:
267
+ for p in ((point or {}).get("args") or {}).get("params") or []:
268
+ if isinstance((p or {}).get("name"), str):
269
+ filled[p["name"]] = "p1"
270
+ for match in [{}, filled]:
271
+ try:
272
+ getattr(getattr(plain(), accessor)(), op)(dict(match), {})
273
+ return (accessor, op, match)
274
+ except Exception:
275
+ continue
276
+ return None
277
+
278
+
279
+ # A feature that raises from inside the pipeline, quoting the request it
280
+ # saw: an error make_error never handled. Its PreUnexpected variant raises
281
+ # where that hook fires: make_error, and the catch path before its cleaning.
282
+ class _ThrowFeature(${Name}BaseFeature):
283
+ def __init__(self, response=True, unexpected=False):
284
+ super().__init__()
285
+ self.name = "throwhook"
286
+ self.version = "0.0.1"
287
+ self.active = True
288
+ self._response = response
289
+ self._unexpected = unexpected
290
+
291
+ def init(self, ctx, options):
292
+ pass
293
+
294
+ def PreResponse(self, ctx):
295
+ if self._response:
296
+ raise RuntimeError("hook saw " + json.dumps(vars(ctx.spec), default=str))
297
+
298
+ def PreUnexpected(self, ctx):
299
+ if self._unexpected:
300
+ raise RuntimeError("hook saw " + json.dumps(vars(ctx.spec), default=str))
301
+
302
+
303
+ # A stream that fails while the caller iterates it, quoting a credential.
304
+ class _StreamThrowFeature(${Name}BaseFeature):
305
+ def __init__(self):
306
+ super().__init__()
307
+ self.name = "streamthrow"
308
+ self.version = "0.0.1"
309
+ self.active = True
310
+
311
+ def init(self, ctx, options):
312
+ pass
313
+
314
+ def PreDone(self, ctx):
315
+ def fail():
316
+ raise RuntimeError("stream saw " + CANARY["apikey"])
317
+ yield
318
+ ctx.result.stream = fail
319
+
320
+
321
+ # A stream that succeeds, so the pipeline's terminal step never runs.
322
+ class _StreamOkFeature(${Name}BaseFeature):
323
+ def __init__(self):
324
+ super().__init__()
325
+ self.name = "streamok"
326
+ self.version = "0.0.1"
327
+ self.active = True
328
+
329
+ def init(self, ctx, options):
330
+ pass
331
+
332
+ def PreDone(self, ctx):
333
+ data = ctx.result.resdata
334
+ items = data if isinstance(data, list) else ([] if data is None else [data])
335
+ ctx.result.stream = lambda: iter(items)
336
+
337
+
338
+ def _drive(sdk, target, ctrl, sinks):
339
+ # A caller may keep the record it passed rather than read ctrl["explain"].
340
+ held = ctrl.get("explain")
341
+ out = None
342
+ err = None
343
+ try:
344
+ out = getattr(getattr(sdk, target[0])(), target[1])(dict(target[2]), ctrl)
345
+ except Exception as e:
346
+ err = e
347
+ if err is not None:
348
+ sinks.extend(_forms("error", err))
349
+ if out is not None:
350
+ sinks.extend(_forms("result", out))
351
+ if ctrl.get("explain") is not None:
352
+ sinks.extend(_forms("explain", ctrl["explain"]))
353
+ if held is not None and held is not ctrl.get("explain"):
354
+ sinks.extend(_forms("explain:held", held))
355
+ return err
356
+
357
+
358
+ class TestClean:
359
+
360
+ def test_no_credential_leaves_the_sdk_in_any_form(self):
361
+ target = _usable_op()
362
+ if target is None:
363
+ pytest.skip(NO_OP)
364
+
365
+ sinks = []
366
+ errors = {}
367
+ explains = {}
368
+
369
+ for sname, respond in SCENARIOS:
370
+ for vname, make_ctrl in [
371
+ ("throw", lambda: {}),
372
+ ("explain", lambda: {"explain": {}}),
373
+ ("nothrow", lambda: {"throw": False, "explain": {}}),
374
+ ]:
375
+ sdk = _make_sdk(respond, sinks)
376
+ ctrl = make_ctrl()
377
+ err = _drive(sdk, target, ctrl, sinks)
378
+ key = sname + "/" + vname
379
+ if err is not None:
380
+ errors[key] = err
381
+ if ctrl.get("explain") is not None:
382
+ explains[key] = ctrl["explain"]
383
+ sinks.extend(_forms("sdk", sdk))
384
+ sinks.append(("sdk:vars", json.dumps(vars(sdk), default=repr)))
385
+
386
+ # A credential mistyped as a map is rejected by validation, whose
387
+ # message quotes the value it rejected.
388
+ rejected = None
389
+ try:
390
+ ${Name}SDK({"apikey": {"value": CANARY["apikey"]}, "clean": {"values": CANARY["value"]}})
391
+ except Exception as e:
392
+ rejected = e
393
+ assert rejected is not None, "a credential mistyped as a map should be rejected"
394
+ sinks.extend(_forms("rejected", rejected))
395
+
396
+ # An error a feature hook raises, quoting the request, skips make_error,
397
+ # as does the explain record it interrupts. The variant raising only in
398
+ # PreUnexpected reaches make_error's own firing through a 404.
399
+ for respond, hook in [
400
+ (SCENARIOS[0][1], _ThrowFeature()),
401
+ (SCENARIOS[0][1], _ThrowFeature(unexpected=True)),
402
+ (SCENARIOS[1][1], _ThrowFeature(response=False, unexpected=True))]:
403
+ hooked = _make_sdk(respond, sinks, None, [hook])
404
+ hookerr = _drive(hooked, target, {"explain": {}}, sinks)
405
+ assert hookerr is not None, "the throwing hook should fail the operation"
406
+
407
+ # Iterating a stream runs inside the same catch path as the operation,
408
+ # and the explain record the caller passed is cleaned however it ends.
409
+ for name, extra in [("stream", [_StreamThrowFeature()]),
410
+ ("stream-ok", [_StreamOkFeature()]), ("stream-plain", [])]:
411
+ streamed = _make_sdk(SCENARIOS[0][1], sinks, None, extra)
412
+ explain = {}
413
+ streamerr = None
414
+ try:
415
+ for _item in getattr(streamed, target[0])().stream(
416
+ target[1], {"reqmatch": dict(target[2])}, {"ctrl": {"explain": explain}}):
417
+ pass
418
+ except Exception as e:
419
+ streamerr = e
420
+ assert ("stream" == name) == (streamerr is not None), name + ": only the failing stream raises"
421
+ if streamerr is not None:
422
+ sinks.extend(_forms(name, streamerr))
423
+ assert 0 < len(explain), name + ": the explain record was not filled"
424
+ sinks.extend(_forms(name + ":explain", explain))
425
+
426
+ # A registered value used as a property name is masked; names that
427
+ # mask alike are kept apart.
428
+ util = hooked.get_utility()
429
+ rootctx = hooked.get_root_ctx()
430
+ named = util.clean(rootctx, {CANARY["value"]: 1, CANARY["header"]: 2, "plain": 3})
431
+ sinks.extend(_forms("named", named))
432
+ assert named == {MASK: 1, MASK + "#1": 2, "plain": 3}, named
433
+ err = RuntimeError("boom")
434
+ setattr(err, CANARY["value"], "x")
435
+ util.clean(rootctx, err)
436
+ sinks.extend(_forms("named-error", err))
437
+ assert CANARY["value"] not in vars(err) and vars(err).get(MASK) == "x", vars(err)
438
+
439
+ # The generated config's own clean block is read beside the caller's,
440
+ # and is not changed by it.
441
+ cfgclean = {"keys": "zzsens", "values": CANARY["config"]}
442
+ built = util.make_options(util.make_context({
443
+ "utility": util,
444
+ "config": {"options": {"clean": cfgclean}},
445
+ "options": {"clean": {"values": CANARY["value"]}},
446
+ }, None))
447
+ cfgctx = util.make_context({"options": built}, None)
448
+ seeded = util.clean(cfgctx, "config " + CANARY["config"] + " caller " + CANARY["value"])
449
+ sinks.append(("config-clean", seeded))
450
+ assert seeded == "config " + MASK + " caller " + MASK, seeded
451
+ bykey = util.clean(cfgctx, {"my_zzsens": "x", "other": "y"})
452
+ assert bykey == {"my_zzsens": MASK, "other": "y"}, bykey
453
+ assert cfgclean == {"keys": "zzsens", "values": CANARY["config"]}, cfgclean
454
+
455
+ # With no clean option at all, the schema defaults still apply.
456
+ bare = ${Name}SDK({
457
+ "apikey": CANARY["apikey"],
458
+ "secret": CANARY["secret"],
459
+ "headers": {"X-Custom-Token": CANARY["header"]},
460
+ "utility": {"fetcher": lambda ctx, url, fetchdef: SCENARIOS[1][1](url, fetchdef)},
461
+ })
462
+ assert _drive(bare, target, {"explain": {}}, sinks) is not None, "the 404 should fail"
463
+
464
+ # A feature's name is not a field name: only the sensitive names
465
+ # inside its settings register. An entity block, of per-entity
466
+ # settings or seeded records keyed by entity name and id, is not read.
467
+ featured = ${Name}SDK({
468
+ "apikey": CANARY["apikey"],
469
+ "feature": {
470
+ "zzsecrets": {"active": False, "kind": "PLAINSETTING-q8w2e4r6"},
471
+ "zzfeat": {"active": False, "apitoken": "FEATTOKEN-z9y8x7w6"},
472
+ "test": {"active": False, "entity": {
473
+ "zztoken": {"ZZTOKEN01": {"note": "PLAINRECORD-t5r3e1w9"}}}},
474
+ },
475
+ "entity": {"zztoken": {"alias": {"zzkey": "PLAINALIAS-m2n4b6v8"}}},
476
+ })
477
+ fclean = featured.get_utility().clean
478
+ froot = featured.get_root_ctx()
479
+ fplain = fclean(froot, "kind PLAINSETTING-q8w2e4r6")
480
+ ftoken = fclean(froot, "token FEATTOKEN-z9y8x7w6")
481
+ frecord = fclean(froot, "record PLAINRECORD-t5r3e1w9")
482
+ falias = fclean(froot, "alias PLAINALIAS-m2n4b6v8")
483
+
484
+ leaked = [(name, _leaks(text)) for name, text in sinks]
485
+ leaked = [(name, found) for name, found in leaked if 0 < len(found)]
486
+
487
+ print("clean: swept " + str(len(sinks)) + " surface(s), " + str(len(leaked)) + " leak(s)")
488
+
489
+ assert len(leaked) == 0, "credential leaked through: " + "; ".join(
490
+ name + " [" + ", ".join(found) + "]" for name, found in leaked)
491
+
492
+ # The positive half: the slot the credential travelled in is masked,
493
+ # and an unregistered token in a response header is masked by name.
494
+ notfound = errors.get("notfound/throw")
495
+ assert notfound is not None, "the 404 scenario must raise"
496
+ assert notfound.status == 404
497
+ spec = notfound.spec or {}
498
+ if not AUTH["suppressed"]:
499
+ if "query" == AUTH["where"]:
500
+ assert _header(spec.get("query"), AUTH["name"]) == MASK
501
+ elif "cookie" == AUTH["where"]:
502
+ cookie = str(_header(spec.get("headers"), "cookie"))
503
+ assert MASK in cookie, "cookie: " + cookie
504
+ else:
505
+ cred = str(_header(spec.get("headers"), AUTH["name"]))
506
+ assert cred.endswith(MASK), AUTH["name"] + ": " + cred
507
+ assert _header(spec.get("headers"), "x-custom-token") == MASK
508
+
509
+ coded = errors.get("coded/throw")
510
+ assert coded is not None and coded.code == "denied_" + MASK, repr(coded)
511
+
512
+ assert fplain == "kind PLAINSETTING-q8w2e4r6", fplain
513
+ assert ftoken == "token " + MASK, ftoken
514
+ assert frecord == "record PLAINRECORD-t5r3e1w9", frecord
515
+ assert falias == "alias PLAINALIAS-m2n4b6v8", falias
516
+
517
+ explained = explains.get("ok/explain") or {}
518
+ assert explained.get("result") is not None, "the explain record should carry the result"
519
+ assert _header(explained["result"].get("headers"), "x-session-token") == MASK
520
+
521
+ def test_the_sweep_can_see_a_leak_with_clean_switched_off(self):
522
+ target = _usable_op()
523
+ if target is None:
524
+ pytest.skip(NO_OP)
525
+
526
+ sinks = []
527
+ sdk = _make_sdk(SCENARIOS[1][1], sinks, {"active": False})
528
+ err = _drive(sdk, target, {}, sinks)
529
+ assert err is not None
530
+
531
+ # Explaining a failure must not cost it its error.
532
+ explained = _drive(_make_sdk(SCENARIOS[1][1], [], {"active": False}), target, {"explain": {}}, [])
533
+ assert str(explained) == str(err), "with clean off, explain lost the error: " + str(explained)
534
+
535
+ leaked = [name for name, text in sinks if 0 < len(_leaks(text))]
536
+ assert 0 < len(leaked), "with clean off, nothing showed the canary: the sweep is blind"
537
+
538
+ if not AUTH["suppressed"]:
539
+ text = json.dumps(_plain(err.spec), default=str)
540
+ assert CANARY["apikey"] in text or \\
541
+ _b64(CANARY["apikey"] + ":" + CANARY["secret"]) in text, \\
542
+ "the raw spec should carry the credential when clean is off"
543
+ `
544
+ }
545
+
546
+
547
+ export {
548
+ TestClean
549
+ }
@@ -9,6 +9,7 @@ import { cmp, each, Folder, File, Content, entityCollection,
9
9
 
10
10
  import { TestEntity } from './TestEntity_py'
11
11
  import { TestDirect } from './TestDirect_py'
12
+ import { TestClean } from './TestClean_py'
12
13
  import { ReadmeExamplesTest } from './ReadmeExamplesTest_py'
13
14
 
14
15
 
@@ -53,6 +54,8 @@ class TestExists:
53
54
  TestDirect({ target, entity })
54
55
  })
55
56
 
57
+ TestClean({ target })
58
+
56
59
  // Validate the documented python examples in the root README.
57
60
  ReadmeExamplesTest({ target })
58
61
  })