@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,774 @@
1
+ import type {
2
+ ModelEntity
3
+ } from '@voxgig/apidef'
4
+
5
+ import {
6
+ cmp,
7
+ configDefinition,
8
+ each,
9
+ File,
10
+ Content,
11
+ entityCollection,
12
+ targetFeatures,
13
+ isAuthSuppressed,
14
+ isHttpBasicAuth,
15
+ resolveAuthIn,
16
+ resolveAuthName,
17
+ } from '@voxgig/sdkgen'
18
+
19
+
20
+ import { cIdent, cVarName } from './utility_c'
21
+
22
+
23
+ // A custom action is not a vtable slot the sweep can call by name.
24
+ const CRUD = ['list', 'load', 'create', 'update', 'remove']
25
+
26
+ const DIAGNOSTIC = ['log', 'debug', 'audit', 'telemetry', 'cost', 'metrics', 'clienttrack']
27
+
28
+
29
+ // The canary sweep (twin of TestClean_ts). C is statically typed, so the
30
+ // operation candidates the ts sweep finds by reflection are enumerated here
31
+ // at generation time, each with the path parameters its config points
32
+ // declare; the sweep still DRIVES them to find the first that completes.
33
+ const TestClean = cmp(function TestClean(props: any) {
34
+ const { model } = props.ctx$
35
+ const { target } = props
36
+
37
+ const Name = model.const.Name
38
+ const ident = cIdent(model)
39
+
40
+ const auth = {
41
+ suppressed: isAuthSuppressed(model),
42
+ where: resolveAuthIn(model),
43
+ name: 'header' === resolveAuthIn(model)
44
+ ? resolveAuthName(model).toLowerCase() : resolveAuthName(model),
45
+ basic: isHttpBasicAuth(model),
46
+ }
47
+
48
+ const features = Object.keys(targetFeatures(model, target))
49
+ .filter((name) => DIAGNOSTIC.includes(name))
50
+ .sort()
51
+
52
+ const configEntity = configDefinition(model, target.name).def.entity || {}
53
+
54
+ const candidates: Candidate[] = []
55
+ const entities = each(entityCollection(model)).filter((e: any) => false !== e.active)
56
+ each(entities, (entity: ModelEntity) => {
57
+ const evar = cVarName(entity.name)
58
+ const ops = Object.keys((entity as any).op || {})
59
+ .filter((op) => CRUD.includes(op))
60
+ .sort((a, b) => CRUD.indexOf(a) - CRUD.indexOf(b))
61
+ for (const op of ops) {
62
+ candidates.push({
63
+ name: entity.name + '.' + op, fn: 'drive_' + evar + '_' + op, evar, op,
64
+ params: pointParams(configEntity[entity.name]?.op?.[op]),
65
+ })
66
+ }
67
+ })
68
+
69
+ File({ name: 'clean_test.c' }, () => {
70
+ Content(render({ Name, ident, auth, features, candidates }))
71
+ })
72
+ })
73
+
74
+
75
+ type Candidate = { name: string, fn: string, evar: string, op: string, params: string[] }
76
+
77
+
78
+ // Every path parameter an operation's points declare, as the generated
79
+ // config carries them (points[].args.params[].name).
80
+ function pointParams(opdef: any): string[] {
81
+ const names: string[] = []
82
+ for (const point of opdef?.points || []) {
83
+ for (const p of point?.args?.params || []) {
84
+ if ('string' === typeof p?.name && !names.includes(p.name)) names.push(p.name)
85
+ }
86
+ }
87
+ return names
88
+ }
89
+
90
+
91
+ function render(spec: {
92
+ Name: string,
93
+ ident: string,
94
+ auth: { suppressed: boolean, where: string, name: string, basic: boolean },
95
+ features: string[],
96
+ candidates: Candidate[],
97
+ }): string {
98
+ const { Name, ident, auth, features, candidates } = spec
99
+
100
+ const drivers = candidates.map((c) => 'list' === c.op
101
+ ? `static PNError* ${c.fn}(${Name}SDK* sdk, voxgig_value* mtch, voxgig_value* ctrl, voxgig_value** out) {
102
+ PNError* err = NULL;
103
+ Entity* e = ${ident}_${c.evar}(sdk, NULL);
104
+ Entity** items = e->vt->list(e, mtch, ctrl, &err);
105
+ if (err) return err;
106
+ voxgig_value* list = v_list();
107
+ for (size_t i = 0; items && items[i]; i++) {
108
+ voxgig_list_push(voxgig_as_list(list), items[i]->vt->data(items[i], NULL));
109
+ }
110
+ *out = list;
111
+ return NULL;
112
+ }
113
+ `
114
+ : `static PNError* ${c.fn}(${Name}SDK* sdk, voxgig_value* mtch, voxgig_value* ctrl, voxgig_value** out) {
115
+ PNError* err = NULL;
116
+ Entity* e = ${ident}_${c.evar}(sdk, NULL);
117
+ Entity* r = e->vt->${c.op}(e, mtch, ctrl, &err);
118
+ if (err) return err;
119
+ *out = r ? r->vt->data(r, NULL) : v_undef();
120
+ return NULL;
121
+ }
122
+ `).join('\n') + '\n' + candidates.map((c) =>
123
+ `static voxgig_value* ${c.fn}_stream(${Name}SDK* sdk, voxgig_value* mtch, voxgig_value* callopts, PNError** err) {
124
+ return ${c.evar}_stream(${ident}_${c.evar}(sdk, NULL), "${c.op}", mtch, callopts, err);
125
+ }
126
+ `).join('\n')
127
+
128
+ const table = candidates.map((c) => ` { "${c.name}", ${c.fn}, ${c.fn}_stream, { ${
129
+ c.params.map((p) => '"' + cstr(p) + '", ').join('')}NULL } },`).join('\n')
130
+
131
+ return `// Generated canary sweep (see TestClean_c): no credential leaves the SDK
132
+ // in any form, and the sweep can see one when clean is switched off.
133
+
134
+ #include "ctest.h"
135
+
136
+ #include <ctype.h>
137
+ #include <stdint.h>
138
+ #include <stdio.h>
139
+ #include <stdlib.h>
140
+ #include <string.h>
141
+ #include <strings.h>
142
+
143
+ // Generated: the credential's wire placement is fixed when the SDK is built.
144
+ static const bool AUTH_SUPPRESSED = ${auth.suppressed};
145
+ static const char* AUTH_WHERE = "${cstr(auth.where)}";
146
+ static const char* AUTH_NAME = "${cstr(auth.name)}";
147
+
148
+ // The diagnostic features this SDK ships.
149
+ static const char* FEATURES[] = { ${features.map((f) => '"' + f + '"').join(', ')}${0 < features.length ? ', ' : ''}NULL };
150
+
151
+ static const char* CANARY_APIKEY = "CANARY-APIKEY-k9x2m7q4p1";
152
+ static const char* CANARY_SECRET = "CANARY-SECRET-w3e8r5t2y6";
153
+ static const char* CANARY_HEADER = "CANARY-HEADER-z1x4c7v0b3";
154
+ static const char* CANARY_VALUE = "CANARY-VALUE-n5m8b2v9c4";
155
+
156
+ static const char* MASK = "[redacted]";
157
+
158
+ // The sweep's own encoders: a leak of an encoded form must not hide behind
159
+ // the SDK's encoder.
160
+ static char* b64(const char* in) {
161
+ static const char ALPHABET[] =
162
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
163
+ size_t n = strlen(in);
164
+ char* out = (char*)malloc((n + 2) / 3 * 4 + 1);
165
+ size_t o = 0;
166
+ for (size_t i = 0; i < n; i += 3) {
167
+ unsigned int v = (unsigned char)in[i] << 16;
168
+ if (i + 1 < n) v |= (unsigned int)(unsigned char)in[i + 1] << 8;
169
+ if (i + 2 < n) v |= (unsigned int)(unsigned char)in[i + 2];
170
+ out[o++] = ALPHABET[(v >> 18) & 0x3f];
171
+ out[o++] = ALPHABET[(v >> 12) & 0x3f];
172
+ out[o++] = (i + 1 < n) ? ALPHABET[(v >> 6) & 0x3f] : '=';
173
+ out[o++] = (i + 2 < n) ? ALPHABET[v & 0x3f] : '=';
174
+ }
175
+ out[o] = '\\0';
176
+ return out;
177
+ }
178
+
179
+ static char* pct(const char* in) {
180
+ size_t n = strlen(in);
181
+ char* out = (char*)malloc(n * 3 + 1);
182
+ size_t o = 0;
183
+ for (size_t i = 0; i < n; i++) {
184
+ unsigned char c = (unsigned char)in[i];
185
+ if (isalnum(c) || strchr("-_.!~*'()", c)) {
186
+ out[o++] = (char)c;
187
+ } else {
188
+ o += (size_t)sprintf(out + o, "%%%02X", c);
189
+ }
190
+ }
191
+ out[o] = '\\0';
192
+ return out;
193
+ }
194
+
195
+ // Every form a canary can travel in.
196
+ static const char* FORMS[16];
197
+ static size_t NFORMS = 0;
198
+
199
+ static void build_forms(void) {
200
+ const char* canaries[4] = { CANARY_APIKEY, CANARY_SECRET, CANARY_HEADER, CANARY_VALUE };
201
+ for (int i = 0; i < 4; i++) {
202
+ FORMS[NFORMS++] = canaries[i];
203
+ FORMS[NFORMS++] = b64(canaries[i]);
204
+ FORMS[NFORMS++] = pct(canaries[i]);
205
+ }
206
+ char pair[256];
207
+ snprintf(pair, sizeof(pair), "%s:%s", CANARY_APIKEY, CANARY_SECRET);
208
+ FORMS[NFORMS++] = b64(pair);
209
+ }
210
+
211
+ typedef struct {
212
+ const char* name;
213
+ char* text;
214
+ } Sink;
215
+
216
+ static Sink* SINKS = NULL;
217
+ static size_t NSINKS = 0;
218
+ static size_t CAPSINKS = 0;
219
+
220
+ static void push(const char* name, char* text) {
221
+ if (NSINKS == CAPSINKS) {
222
+ CAPSINKS = CAPSINKS ? CAPSINKS * 2 : 64;
223
+ SINKS = (Sink*)realloc(SINKS, CAPSINKS * sizeof(Sink));
224
+ }
225
+ SINKS[NSINKS].name = name;
226
+ SINKS[NSINKS].text = text ? text : strdup("");
227
+ NSINKS++;
228
+ }
229
+
230
+ static void push_value(const char* name, voxgig_value* val) {
231
+ push(name, voxgig_jsonify(val, NULL));
232
+ push(name, voxgig_stringify(val, -1));
233
+ }
234
+
235
+ static void push_error(const char* name, PNError* err) {
236
+ push(name, strdup(err->msg ? err->msg : ""));
237
+ push(name, pn_error_str(err));
238
+ push(name, voxgig_jsonify(err->spec, NULL));
239
+ push(name, voxgig_jsonify(err->result, NULL));
240
+ }
241
+
242
+ static voxgig_value* capture_fn(void* ud, voxgig_value* arg) {
243
+ push_value((const char*)ud, arg);
244
+ return v_undef();
245
+ }
246
+
247
+ // Captures the serialised context from inside the pipeline: what a hook
248
+ // author would hand to a logger.
249
+ typedef struct {
250
+ Feature base;
251
+ } CaptureFeature;
252
+
253
+ static const char* capture_name(Feature* f) { (void)f; return "capture"; }
254
+ static bool capture_active(Feature* f) { (void)f; return true; }
255
+ static voxgig_value* capture_add_options(Feature* f) { (void)f; return NULL; }
256
+ static void capture_init(Feature* f, Context* ctx, voxgig_value* options) {
257
+ (void)f; (void)ctx; (void)options;
258
+ }
259
+ static void capture_hook(Feature* f, const char* name, Context* ctx) {
260
+ (void)f;
261
+ if (0 == strcmp(name, "PreRequest") || 0 == strcmp(name, "PreResponse") ||
262
+ 0 == strcmp(name, "PreUnexpected")) {
263
+ push("ctx", context_str(ctx));
264
+ push_value("ctx", context_to_value(ctx));
265
+ }
266
+ }
267
+
268
+ static const FeatureVT CAPTURE_VT = {
269
+ capture_name, capture_active, capture_add_options, capture_init, capture_hook, NULL,
270
+ };
271
+
272
+ // A feature that fails the operation from inside the pipeline, quoting the
273
+ // request it saw. A C hook has no error return, so it fails the result: an
274
+ // error make_error receives from a hook, not from the pipeline. For the same
275
+ // reason there is no variant failing in PreUnexpected: make_error has built
276
+ // and cleaned the error it returns before that hook runs.
277
+ static const char* throw_name(Feature* f) { (void)f; return "throwhook"; }
278
+ static void throw_hook(Feature* f, const char* name, Context* ctx) {
279
+ (void)f;
280
+ if (0 != strcmp(name, "PreResponse") || !ctx->result) return;
281
+ char* spec = voxgig_jsonify(ctx->spec ? spec_to_value(ctx->spec) : v_undef(), NULL);
282
+ char msg[4096];
283
+ snprintf(msg, sizeof(msg), "hook saw %s", spec ? spec : "");
284
+ ctx->result->err = context_make_error(ctx, "hook", msg);
285
+ }
286
+
287
+ static const FeatureVT THROW_VT = {
288
+ throw_name, capture_active, capture_add_options, capture_init, throw_hook, NULL,
289
+ };
290
+
291
+ // A feature that refuses the operation with the SDK's own error, as rbac
292
+ // does, whose code quotes a registered value; it records the error
293
+ // PreUnexpected hands a hook.
294
+ static const char* deny_name(Feature* f) { (void)f; return "denyhook"; }
295
+ static void deny_hook(Feature* f, const char* name, Context* ctx) {
296
+ (void)f;
297
+ if (0 == strcmp(name, "PrePoint")) {
298
+ char code[128];
299
+ snprintf(code, sizeof(code), "denied:%s", CANARY_VALUE);
300
+ ctx_out_set_point_err(ctx, context_make_error(ctx, code, "denied"));
301
+ } else if (0 == strcmp(name, "PreUnexpected") && ctx->ctrl && ctx->ctrl->err) {
302
+ push_error("error", ctx->ctrl->err);
303
+ }
304
+ }
305
+
306
+ static const FeatureVT DENY_VT = {
307
+ deny_name, capture_active, capture_add_options, capture_init, deny_hook, NULL,
308
+ };
309
+
310
+ // A stream that succeeds, so the pipeline's terminal step never runs. A C
311
+ // stream producer has no error channel, so no stream fails.
312
+ static voxgig_value* streamok_items(void* ud) {
313
+ voxgig_value* data = (voxgig_value*)ud;
314
+ voxgig_value* out = v_list();
315
+ if (voxgig_is_list(data)) {
316
+ voxgig_list* l = voxgig_as_list(data);
317
+ for (size_t i = 0; i < l->len; i++) {
318
+ voxgig_list_push(voxgig_as_list(out), voxgig_retain(l->items[i]));
319
+ }
320
+ } else if (!v_is_noval(data) && !v_is_null(data)) {
321
+ voxgig_list_push(voxgig_as_list(out), voxgig_retain(data));
322
+ }
323
+ return out;
324
+ }
325
+
326
+ static const char* streamok_name(Feature* f) { (void)f; return "streamok"; }
327
+ static void streamok_hook(Feature* f, const char* name, Context* ctx) {
328
+ (void)f;
329
+ if (0 != strcmp(name, "PreDone") || !ctx->result) return;
330
+ ctx->result->stream = streamok_items;
331
+ ctx->result->stream_ud = v_share(ctx->result->resdata);
332
+ }
333
+
334
+ static const FeatureVT STREAMOK_VT = {
335
+ streamok_name, capture_active, capture_add_options, capture_init, streamok_hook, NULL,
336
+ };
337
+
338
+ enum { SC_OK = 0, SC_NOTFOUND, SC_SERVER, SC_TRANSPORT, SC_NOTJSON, SC_COUNT };
339
+ static const char* SC_NAMES[] = { "ok", "notfound", "server", "transport", "notjson" };
340
+
341
+ static voxgig_value* response(int status, voxgig_value* data, const char* hk, const char* hv) {
342
+ voxgig_value* headers = cmap(1, "content-type", v_str("application/json"));
343
+ if (hk) setp(headers, hk, v_str(hv));
344
+ return cmap(5,
345
+ "status", v_num((double)status),
346
+ "statusText", v_str(status < 400 ? "OK" : "ERR"),
347
+ "headers", headers,
348
+ "body", v_str(voxgig_jsonify(data, NULL)),
349
+ "json", json_thunk(data));
350
+ }
351
+
352
+ static voxgig_value* respond(int sc, const char* url) {
353
+ switch (sc) {
354
+ case SC_OK:
355
+ return response(200, cmap(2, "id", v_str("i1"), "name", v_str("n1")),
356
+ "x-session-token", "RESP-TOKEN-a1b2c3d4e5");
357
+ case SC_NOTFOUND:
358
+ return response(404, cmap(1, "error", v_str("no such record")), NULL, NULL);
359
+ case SC_SERVER:
360
+ return response(500, cmap(1, "error", v_str("boom")), NULL, NULL);
361
+ case SC_TRANSPORT: {
362
+ char msg[2048];
363
+ snprintf(msg, sizeof(msg), "socket hang up (URL was: \\"%s\\")", url);
364
+ return cmap(1, "__err__", v_str(msg));
365
+ }
366
+ default:
367
+ return cmap(5,
368
+ "status", v_num(200),
369
+ "statusText", v_str("OK"),
370
+ "headers", v_map(),
371
+ "body", v_str("<html>"),
372
+ "json", json_thunk(v_undef()));
373
+ }
374
+ }
375
+
376
+ // The transport seam: system.fetch is called with [url, fetchdef].
377
+ static voxgig_value* transport_fn(void* ud, voxgig_value* args) {
378
+ int sc = (int)(intptr_t)ud;
379
+ const char* url = "";
380
+ if (voxgig_is_list(args) && 0 < voxgig_as_list(args)->len) {
381
+ voxgig_value* u = voxgig_as_list(args)->items[0];
382
+ if (voxgig_is_string(u)) url = voxgig_as_string(u);
383
+ }
384
+ return respond(sc, url);
385
+ }
386
+
387
+ static ${Name}SDK* make_sdk(int sc, voxgig_value* cleanopts, Feature* extra) {
388
+ voxgig_value* feature = v_map();
389
+ for (size_t i = 0; FEATURES[i]; i++) {
390
+ const char* name = FEATURES[i];
391
+ voxgig_value* fopts = cmap(1, "active", v_bool(true));
392
+ if (0 == strcmp(name, "log")) setp(fopts, "logger", vfn(capture_fn, (void*)"log"));
393
+ else if (0 == strcmp(name, "debug")) setp(fopts, "onEntry", vfn(capture_fn, (void*)"debug"));
394
+ else if (0 == strcmp(name, "audit")) setp(fopts, "sink", vfn(capture_fn, (void*)"audit"));
395
+ else if (0 == strcmp(name, "telemetry")) setp(fopts, "exporter", vfn(capture_fn, (void*)"telemetry"));
396
+ else if (0 == strcmp(name, "cost")) setp(fopts, "sink", vfn(capture_fn, (void*)"cost"));
397
+ setp(feature, name, fopts);
398
+ }
399
+
400
+ voxgig_value* clean = cmap(1, "values", v_str(CANARY_VALUE));
401
+ if (voxgig_is_map(cleanopts)) {
402
+ voxgig_map* m = voxgig_as_map(cleanopts);
403
+ for (size_t i = 0; i < m->len; i++) {
404
+ setp(clean, m->entries[i].key, voxgig_retain(m->entries[i].value));
405
+ }
406
+ }
407
+
408
+ ${Name}SDK* sdk = ${ident}_sdk_new(cmap(6,
409
+ "apikey", v_str(CANARY_APIKEY),
410
+ "secret", v_str(CANARY_SECRET),
411
+ "headers", cmap(1, "X-Custom-Token", v_str(CANARY_HEADER)),
412
+ "clean", clean,
413
+ "feature", feature,
414
+ "system", cmap(1, "fetch", vfn(transport_fn, (void*)(intptr_t)sc))));
415
+
416
+ // C options are pure data, so the extension feature is added after
417
+ // construction (the \`extend\` option of the ts client).
418
+ CaptureFeature* cf = (CaptureFeature*)calloc(1, sizeof(CaptureFeature));
419
+ cf->base.vt = &CAPTURE_VT;
420
+ sdk_features_push(sdk, (Feature*)cf);
421
+ if (extra) sdk_features_push(sdk, extra);
422
+
423
+ return sdk;
424
+ }
425
+
426
+ typedef PNError* (*Drive)(${Name}SDK* sdk, voxgig_value* mtch, voxgig_value* ctrl, voxgig_value** out);
427
+ typedef voxgig_value* (*Streamer)(${Name}SDK* sdk, voxgig_value* mtch, voxgig_value* callopts, PNError** err);
428
+
429
+ ${drivers}
430
+ // Generated: every CRUD operation of every active entity, list and load
431
+ // first (they need no body), with the path parameters its points declare.
432
+ static const struct { const char* name; Drive fn; Streamer stream; const char* params[16]; } CANDIDATES[] = {
433
+ ${table}
434
+ { NULL, NULL, NULL, { NULL } },
435
+ };
436
+
437
+ typedef struct {
438
+ Drive fn;
439
+ Streamer stream;
440
+ voxgig_value* mtch;
441
+ } Target;
442
+
443
+ // The first operation that completes against a plain 200: with no
444
+ // arguments, else with every path parameter its points declare filled in.
445
+ static bool usable_op(Target* target) {
446
+ ${Name}SDK* plain = ${ident}_sdk_new(cmap(2,
447
+ "apikey", v_str(CANARY_APIKEY),
448
+ "system", cmap(1, "fetch", vfn(transport_fn, (void*)(intptr_t)SC_OK))));
449
+ for (size_t i = 0; CANDIDATES[i].name; i++) {
450
+ voxgig_value* filled = v_map();
451
+ for (size_t p = 0; CANDIDATES[i].params[p]; p++) {
452
+ setp(filled, CANDIDATES[i].params[p], v_str("p1"));
453
+ }
454
+ voxgig_value* tries[2] = { v_map(), filled };
455
+ for (int t = 0; t < 2; t++) {
456
+ voxgig_value* out = NULL;
457
+ PNError* err = CANDIDATES[i].fn(plain, voxgig_clone(tries[t]), NULL, &out);
458
+ if (!err) {
459
+ target->fn = CANDIDATES[i].fn;
460
+ target->stream = CANDIDATES[i].stream;
461
+ target->mtch = tries[t];
462
+ return true;
463
+ }
464
+ }
465
+ }
466
+ return false;
467
+ }
468
+
469
+ static PNError* drive(${Name}SDK* sdk, Target* target, voxgig_value* ctrl) {
470
+ // A caller may keep the record it passed rather than read ctrl.explain.
471
+ voxgig_value* held = ctrl ? getp(ctrl, "explain") : NULL;
472
+ voxgig_value* out = NULL;
473
+ PNError* err = target->fn(sdk, voxgig_clone(target->mtch), ctrl, &out);
474
+ if (err) {
475
+ push_error("error", err);
476
+ } else {
477
+ push_value("result", out ? out : v_undef());
478
+ }
479
+ voxgig_value* explain = ctrl ? getp(ctrl, "explain") : NULL;
480
+ if (v_is_map(explain)) push_value("explain", explain);
481
+ if (v_is_map(held) && held != explain) push_value("explain:held", held);
482
+ return err;
483
+ }
484
+
485
+ // Header maps keep the caller's spelling; the assertion should not care.
486
+ static const char* header(voxgig_value* map, const char* name) {
487
+ if (!voxgig_is_map(map)) return NULL;
488
+ voxgig_map* m = voxgig_as_map(map);
489
+ for (size_t i = 0; i < m->len; i++) {
490
+ if (0 == strcasecmp(m->entries[i].key, name)) {
491
+ voxgig_value* v = m->entries[i].value;
492
+ return voxgig_is_string(v) ? voxgig_as_string(v) : voxgig_stringify(v, -1);
493
+ }
494
+ }
495
+ return NULL;
496
+ }
497
+
498
+ static size_t leaks(const char* text, char* found, size_t cap) {
499
+ size_t n = 0;
500
+ found[0] = '\\0';
501
+ for (size_t i = 0; i < NFORMS; i++) {
502
+ if (strstr(text, FORMS[i])) {
503
+ if (n) strncat(found, ", ", cap - strlen(found) - 1);
504
+ strncat(found, FORMS[i], cap - strlen(found) - 1);
505
+ n++;
506
+ }
507
+ }
508
+ return n;
509
+ }
510
+
511
+ static bool ends_with(const char* s, const char* suffix) {
512
+ size_t sl = strlen(s);
513
+ size_t xl = strlen(suffix);
514
+ return sl >= xl && 0 == strcmp(s + sl - xl, suffix);
515
+ }
516
+
517
+ int main(void) {
518
+ build_forms();
519
+
520
+ Target target;
521
+ if (!usable_op(&target)) {
522
+ printf("SKIP: no operation of this SDK completes against a plain 200; nothing to sweep\\n");
523
+ return 0;
524
+ }
525
+ Target* op = &target;
526
+
527
+ PNError* notfound = NULL;
528
+ voxgig_value* explained = NULL;
529
+
530
+ for (int sc = 0; sc < SC_COUNT; sc++) {
531
+ for (int variant = 0; variant < 3; variant++) {
532
+ ${Name}SDK* sdk = make_sdk(sc, NULL, NULL);
533
+ voxgig_value* explain = v_map();
534
+ voxgig_value* ctrl = NULL;
535
+ if (1 == variant) ctrl = cmap(1, "explain", explain);
536
+ if (2 == variant) ctrl = cmap(2, "throw", v_bool(false), "explain", explain);
537
+ PNError* err = drive(sdk, op, ctrl);
538
+ if (SC_NOTFOUND == sc && 0 == variant) notfound = err;
539
+ if (SC_OK == sc && 1 == variant) explained = explain;
540
+ (void)SC_NAMES;
541
+ }
542
+ }
543
+
544
+ // A credential mistyped as a map. The C validator defaults rather than
545
+ // rejects, so what the constructor produced is swept instead: a string
546
+ // quoting the value, cleaned the way a validation message is.
547
+ ${Name}SDK* mistyped = ${ident}_sdk_new(cmap(2,
548
+ "apikey", cmap(1, "value", v_str(CANARY_APIKEY)),
549
+ "clean", cmap(1, "values", v_str(CANARY_VALUE))));
550
+ {
551
+ char quoted[256];
552
+ snprintf(quoted, sizeof(quoted), "apikey: expected string, got {\\"value\\":\\"%s\\"}",
553
+ CANARY_APIKEY);
554
+ push("mistyped:quoted", clean_str(sdk_get_root_ctx(mistyped), quoted));
555
+ }
556
+
557
+ // An error a feature hook raises, quoting the request, with explain on.
558
+ Feature* thrower = (Feature*)calloc(1, sizeof(CaptureFeature));
559
+ thrower->vt = &THROW_VT;
560
+ PNError* hookerr = drive(make_sdk(SC_OK, NULL, thrower), op, cmap(1, "explain", v_map()));
561
+ CHECK(hookerr != NULL, "the throwing hook should fail the operation");
562
+
563
+ // The explain record a stream call is passed is cleaned however the stream
564
+ // ends: from a feature's producer, or materialised by done.
565
+ for (int s = 0; s < 2; s++) {
566
+ const char* name = 0 == s ? "stream-ok" : "stream-plain";
567
+ Feature* extra = NULL;
568
+ if (0 == s) {
569
+ extra = (Feature*)calloc(1, sizeof(CaptureFeature));
570
+ extra->vt = &STREAMOK_VT;
571
+ }
572
+ voxgig_value* explain = v_map();
573
+ PNError* serr = NULL;
574
+ op->stream(make_sdk(SC_OK, NULL, extra), voxgig_clone(op->mtch),
575
+ cmap(1, "ctrl", cmap(1, "explain", explain)), &serr);
576
+ char label[64];
577
+ snprintf(label, sizeof(label), "%s: only a failing stream raises", name);
578
+ CHECK(NULL == serr, label);
579
+ snprintf(label, sizeof(label), "%s: the explain record was not filled", name);
580
+ CHECK(0 < voxgig_as_map(explain)->len, label);
581
+ push_value(0 == s ? "stream-ok:explain" : "stream-plain:explain", explain);
582
+ }
583
+
584
+ // A feature's own error keeps its code, which is cleaned like the message:
585
+ // returned, handed to a hook, and cleaned where a step's error skips
586
+ // make_error.
587
+ Feature* denier = (Feature*)calloc(1, sizeof(CaptureFeature));
588
+ denier->vt = &DENY_VT;
589
+ PNError* denied = drive(make_sdk(SC_OK, NULL, denier), op, NULL);
590
+ CHECK(denied != NULL, "the refusing hook should fail the operation");
591
+ char steppedcode[128];
592
+ snprintf(steppedcode, sizeof(steppedcode), "stepped:%s", CANARY_VALUE);
593
+ PNError* stepped = pn_error_new(steppedcode, "stepped");
594
+ clean_error_util(sdk_get_root_ctx(mistyped), stepped);
595
+ push("stepped", pn_error_str(stepped));
596
+
597
+ // A client given no clean block at all masks by the schema defaults.
598
+ ${Name}SDK* bare = ${ident}_sdk_new(cmap(4,
599
+ "apikey", v_str(CANARY_APIKEY),
600
+ "secret", v_str(CANARY_SECRET),
601
+ "headers", cmap(1, "X-Custom-Token", v_str(CANARY_HEADER)),
602
+ "system", cmap(1, "fetch", vfn(transport_fn, (void*)(intptr_t)SC_NOTFOUND))));
603
+ PNError* barerr = drive(bare, op, NULL);
604
+ CHECK(barerr != NULL, "the 404 scenario must throw without a clean block");
605
+
606
+ // The raw path returns its failure rather than an error.
607
+ PNError* directerr = NULL;
608
+ voxgig_value* direct = sdk_direct(make_sdk(SC_TRANSPORT, NULL, NULL),
609
+ cmap(1, "path", v_str("raw")), &directerr);
610
+ bool directok = true;
611
+ CHECK(NULL == directerr && get_bool(direct, "ok", &directok) && !directok,
612
+ "a transport failure should fail direct()");
613
+ push_value("direct", direct);
614
+
615
+ size_t nleaks = 0;
616
+ char found[4096];
617
+ for (size_t i = 0; i < NSINKS; i++) {
618
+ if (leaks(SINKS[i].text, found, sizeof(found))) {
619
+ fprintf(stderr, "credential leaked through: %s [%s]\\n", SINKS[i].name, found);
620
+ nleaks++;
621
+ }
622
+ }
623
+
624
+ printf("clean: swept %zu surface(s), %zu leak(s)\\n", NSINKS, nleaks);
625
+ CHECK(0 == nleaks, "a credential leaked (see above)");
626
+
627
+ // The positive half: the slot the credential travelled in is masked, and
628
+ // an unregistered token in a response header is masked by name.
629
+ CHECK(notfound != NULL, "the 404 scenario must throw");
630
+ if (notfound) {
631
+ CHECK_INT_EQ(to_int(getp(notfound->result, "status")), 404, "the 404 error carries its status");
632
+ voxgig_value* headers = getp(notfound->spec, "headers");
633
+ if (!AUTH_SUPPRESSED) {
634
+ if (0 == strcmp(AUTH_WHERE, "query")) {
635
+ CHECK_STR_EQ(header(getp(notfound->spec, "query"), AUTH_NAME), MASK, "the query credential is masked");
636
+ } else if (0 == strcmp(AUTH_WHERE, "cookie")) {
637
+ const char* cookie = header(headers, "cookie");
638
+ CHECK(cookie && strstr(cookie, MASK), "the cookie credential is masked");
639
+ } else {
640
+ const char* cred = header(headers, AUTH_NAME);
641
+ CHECK(cred && ends_with(cred, MASK), "the header credential is masked");
642
+ }
643
+ }
644
+ CHECK_STR_EQ(header(headers, "x-custom-token"), MASK, "a custom token header is masked by name");
645
+ }
646
+
647
+ {
648
+ char want[64];
649
+ snprintf(want, sizeof(want), "denied:%s", MASK);
650
+ CHECK_STR_EQ(denied ? denied->code : NULL, want, "a feature's own error code is masked");
651
+ snprintf(want, sizeof(want), "stepped:%s", MASK);
652
+ CHECK_STR_EQ(stepped->code, want, "clean_error masks the code");
653
+ }
654
+ CHECK_STR_EQ(barerr ? header(getp(barerr->spec, "headers"), "x-custom-token") : NULL, MASK,
655
+ "a client with no clean block masks by the schema defaults");
656
+
657
+ CHECK(explained != NULL && voxgig_is_map(getp(explained, "result")),
658
+ "the explain record should carry the result");
659
+ if (explained) {
660
+ CHECK_STR_EQ(header(getp(getp(explained, "result"), "headers"), "x-session-token"), MASK,
661
+ "a response token header is masked by name");
662
+ }
663
+
664
+ // The negative control: with clean switched off the canary MUST show, or
665
+ // the sweep is blind.
666
+ size_t before = NSINKS;
667
+ ${Name}SDK* raw = make_sdk(SC_NOTFOUND, cmap(1, "active", v_bool(false)), NULL);
668
+ PNError* rawerr = drive(raw, op, NULL);
669
+ CHECK(rawerr != NULL, "the 404 scenario must throw with clean off");
670
+ size_t shown = 0;
671
+ for (size_t i = before; i < NSINKS; i++) {
672
+ if (leaks(SINKS[i].text, found, sizeof(found))) shown++;
673
+ }
674
+ CHECK(0 < shown, "with clean off, nothing showed the canary: the sweep is blind");
675
+ if (rawerr && !AUTH_SUPPRESSED) {
676
+ char* text = voxgig_jsonify(rawerr->spec, NULL);
677
+ char pair[256];
678
+ snprintf(pair, sizeof(pair), "%s:%s", CANARY_APIKEY, CANARY_SECRET);
679
+ char* pairb64 = b64(pair);
680
+ CHECK(strstr(text, CANARY_APIKEY) || strstr(text, pairb64),
681
+ "the raw spec should carry the credential when clean is off");
682
+ }
683
+
684
+ // Explaining a failure must not cost it its error.
685
+ {
686
+ voxgig_value* out = NULL;
687
+ PNError* explained = op->fn(make_sdk(SC_NOTFOUND, cmap(1, "active", v_bool(false)), NULL),
688
+ voxgig_clone(op->mtch), cmap(1, "explain", v_map()), &out);
689
+ CHECK_STR_EQ(explained ? explained->msg : NULL, rawerr ? rawerr->msg : NULL,
690
+ "with clean off, explain lost the error");
691
+ }
692
+
693
+ // A registered value used as a property name is masked; names that mask
694
+ // alike are all kept.
695
+ ${Name}SDK* named = ${ident}_sdk_new(cmap(1,
696
+ "clean", cmap(1, "values", v_str("ZZVAL-abc123,ZZVAL-xyz789"))));
697
+ voxgig_value* renamed = clean_util(sdk_get_root_ctx(named), cmap(3,
698
+ "ZZVAL-abc123", v_num(1), "ZZVAL-xyz789", v_num(2), "plain", v_num(3)));
699
+ voxgig_map* rm = voxgig_as_map(renamed);
700
+ CHECK(3 == rm->len, "every masked name is kept");
701
+ if (3 == rm->len) {
702
+ char alt[64];
703
+ snprintf(alt, sizeof(alt), "%s#1", MASK);
704
+ CHECK_STR_EQ(rm->entries[0].key, MASK, "a registered value used as a name is masked");
705
+ CHECK_STR_EQ(rm->entries[1].key, alt, "a colliding masked name takes a counter");
706
+ CHECK_STR_EQ(rm->entries[2].key, "plain", "an ordinary name is kept");
707
+ }
708
+
709
+ // The generated config's own clean block is honoured, and left unchanged.
710
+ {
711
+ voxgig_value* config = cmap(1, "options", cmap(1, "clean", cmap(2,
712
+ "keys", v_str("zzsens"), "values", v_str("CONFIG-SEEDED-1"))));
713
+ CtxSpec cs;
714
+ memset(&cs, 0, sizeof(cs));
715
+ cs.options = cmap(1, "clean", cmap(1, "values", v_str("CALLER-SEEDED-2")));
716
+ cs.config = config;
717
+ Context* cctx = make_context_util(cs, NULL);
718
+ cctx->options = make_options_util(cctx);
719
+ char want[128];
720
+ snprintf(want, sizeof(want), "a %s b %s", MASK, MASK);
721
+ CHECK_STR_EQ(clean_str(cctx, "a CONFIG-SEEDED-1 b CALLER-SEEDED-2"), want,
722
+ "the config's and the caller's values are both masked");
723
+ voxgig_value* out = clean_util(cctx, cmap(2, "my_zzsens", v_str("x"), "other", v_str("y")));
724
+ CHECK_STR_EQ(get_str(out, "my_zzsens"), MASK, "the config's key name is sensitive");
725
+ CHECK_STR_EQ(get_str(out, "other"), "y", "an ordinary name is kept");
726
+ voxgig_value* cfgclean = getpath2(config, "options", "clean");
727
+ CHECK_STR_EQ(get_str(cfgclean, "keys"), "zzsens", "the config's keys are left alone");
728
+ CHECK_STR_EQ(get_str(cfgclean, "values"), "CONFIG-SEEDED-1",
729
+ "the config's values are left alone");
730
+ }
731
+
732
+ // A feature's name is not a field name: a feature called secrets does not
733
+ // make its settings secret, though a sensitive field inside it still is. An
734
+ // entity block, of per-entity settings or seeded records keyed by entity
735
+ // name and id, is not read at all.
736
+ {
737
+ ${Name}SDK* featured = ${ident}_sdk_new(cmap(3,
738
+ "apikey", v_str(CANARY_APIKEY),
739
+ "feature", cmap(2,
740
+ "secrets", cmap(3,
741
+ "active", v_bool(false),
742
+ "name", v_str("ZZNAME-feat123"),
743
+ "token", v_str("ZZTOKEN-feat456")),
744
+ "test", cmap(2,
745
+ "active", v_bool(false),
746
+ "entity", cmap(1, "zztoken", cmap(1, "ZZTOKEN01",
747
+ cmap(1, "note", v_str("PLAINRECORD-t5r3e1w9")))))),
748
+ "entity", cmap(1, "zztoken", cmap(1, "alias",
749
+ cmap(1, "zzkey", v_str("PLAINALIAS-m2n4b6v8"))))));
750
+ Context* fctx = sdk_get_root_ctx(featured);
751
+ char want[128];
752
+ snprintf(want, sizeof(want), "ZZNAME-feat123 %s", MASK);
753
+ CHECK_STR_EQ(clean_str(fctx, "ZZNAME-feat123 ZZTOKEN-feat456"), want,
754
+ "only the sensitive field of a feature is registered");
755
+ CHECK_STR_EQ(clean_str(fctx, "record PLAINRECORD-t5r3e1w9"), "record PLAINRECORD-t5r3e1w9",
756
+ "a record seeded under an entity block is not registered");
757
+ CHECK_STR_EQ(clean_str(fctx, "alias PLAINALIAS-m2n4b6v8"), "alias PLAINALIAS-m2n4b6v8",
758
+ "an entity's own settings are not registered");
759
+ }
760
+
761
+ TEST_SUMMARY("clean");
762
+ }
763
+ `
764
+ }
765
+
766
+
767
+ function cstr(s: string): string {
768
+ return String(s).replace(/\\/g, '\\\\').replace(/"/g, '\\"')
769
+ }
770
+
771
+
772
+ export {
773
+ TestClean
774
+ }