@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
@@ -3,10 +3,446 @@ declare(strict_types=1);
3
3
 
4
4
  // ProjectName SDK utility: clean
5
5
 
6
+ // Everything that leaves the pipeline passes through clean: the error, the
7
+ // explain record, the printed context, and whatever a feature emits. Two
8
+ // layers: every registered secret VALUE (and its encoded forms) is replaced
9
+ // wherever it appears in a string, and every value under a sensitive KEY
10
+ // name is masked whatever it holds. Inside the pipeline data stays raw, so a
11
+ // hook can still read the header it must add to. Mirrors
12
+ // tm/ts/src/utility/CleanUtility.ts.
6
13
  class ProjectNameClean
7
14
  {
8
- public static function call(ProjectNameContext $ctx, mixed $val): mixed
15
+ private const MAXDEPTH = 32;
16
+ private const CIRCULAR = '[circular]';
17
+
18
+ // Clean a value on its way out. A string is redacted; a Throwable is
19
+ // redacted IN PLACE (it is about to be thrown, and its identity matters
20
+ // to the caller); anything else comes back as a masked plain-data copy.
21
+ public static function call(?ProjectNameContext $ctx, mixed $val): mixed
22
+ {
23
+ $cfg = self::config_of($ctx);
24
+
25
+ if (false === $cfg->active) {
26
+ return $val;
27
+ }
28
+
29
+ if (is_string($val)) {
30
+ return self::clean_string($cfg, $val);
31
+ }
32
+
33
+ if ($val instanceof \Throwable) {
34
+ self::clean_throwable($cfg, $val);
35
+ return $val;
36
+ }
37
+
38
+ $seen = [];
39
+ return self::snapshot($cfg, $val, null, 0, $seen);
40
+ }
41
+
42
+ // Register a secret value (clean_add). Idempotent; shorter than `min` is
43
+ // not a secret the SDK can mask without blanking ordinary text.
44
+ public static function add(?ProjectNameContext $ctx, mixed $value): void
45
+ {
46
+ $cfg = self::config_of($ctx);
47
+ if (!is_string($value) || strlen($value) < $cfg->min) {
48
+ return;
49
+ }
50
+ $changed = false;
51
+ foreach (self::forms($value) as $form) {
52
+ if (strlen($form) >= $cfg->min && !in_array($form, $cfg->values, true)) {
53
+ $cfg->values[] = $form;
54
+ $changed = true;
55
+ }
56
+ }
57
+ if ($changed) {
58
+ usort($cfg->values, function (string $a, string $b): int {
59
+ return strlen($b) - strlen($a);
60
+ });
61
+ }
62
+ }
63
+
64
+ // Every scalar under a sensitive name, at any depth and of any shape: a
65
+ // credential mistyped as a map or a number is still a credential, and
66
+ // the validation error that rejects it quotes it.
67
+ public static function add_sensitive(?ProjectNameContext $ctx, mixed $val): void
68
+ {
69
+ $seen = [];
70
+ self::walk_sensitive($ctx, $val, false, 0, $seen);
71
+ }
72
+
73
+ private static function walk_sensitive(
74
+ ?ProjectNameContext $ctx, mixed $val, bool $under, int $depth, array &$seen
75
+ ): void {
76
+ if (null === $val || self::MAXDEPTH <= $depth || $val instanceof \Closure) {
77
+ return;
78
+ }
79
+ if (is_string($val) || is_int($val) || is_float($val)) {
80
+ if ($under) {
81
+ self::add($ctx, (string)$val);
82
+ }
83
+ return;
84
+ }
85
+ if (is_object($val)) {
86
+ $id = spl_object_id($val);
87
+ if (in_array($id, $seen, true)) {
88
+ return;
89
+ }
90
+ $seen[] = $id;
91
+ $val = get_object_vars($val);
92
+ }
93
+ if (is_array($val)) {
94
+ foreach ($val as $k => $v) {
95
+ self::walk_sensitive($ctx, $v, $under || self::key($ctx, $k), $depth + 1, $seen);
96
+ }
97
+ }
98
+ }
99
+
100
+ // A feature's name is not a field name: only the sensitive names inside
101
+ // its settings count, so `secrets` does not make every setting a secret.
102
+ // Entity blocks (per-entity settings, seeded records) hold no credential.
103
+ public static function add_options(?ProjectNameContext $ctx, array $opts): void
104
+ {
105
+ $feature = $opts['feature'] ?? null;
106
+ unset($opts['feature'], $opts['entity']);
107
+ if (array_key_exists('test', $opts)) {
108
+ $opts['test'] = self::no_entity($opts['test']);
109
+ }
110
+ self::add_sensitive($ctx, $opts);
111
+ $feature = is_object($feature) ? get_object_vars($feature) : $feature;
112
+ foreach (is_array($feature) ? $feature : [$feature] as $fopts) {
113
+ self::add_sensitive($ctx, self::no_entity($fopts));
114
+ }
115
+ }
116
+
117
+ private static function no_entity(mixed $block): mixed
118
+ {
119
+ $block = is_object($block) ? get_object_vars($block) : $block;
120
+ if (is_array($block)) {
121
+ unset($block['entity']);
122
+ }
123
+ return $block;
124
+ }
125
+
126
+ // Is this key name sensitive under the context's clean configuration?
127
+ public static function key(?ProjectNameContext $ctx, mixed $key): bool
128
+ {
129
+ return self::sensitive_key(self::config_of($ctx), $key);
130
+ }
131
+
132
+ // The derived clean block make_options builds from the option spec. An
133
+ // OBJECT, deliberately: every context copies the options array, and the
134
+ // registry must be one shared, mutable thing for a feature to add to
135
+ // after construction.
136
+ public static function config(mixed $cleanopts): \stdClass
137
+ {
138
+ $opts = is_object($cleanopts) ? get_object_vars($cleanopts)
139
+ : (is_array($cleanopts) ? $cleanopts : []);
140
+ return (object)[
141
+ 'active' => ($opts['active'] ?? null) !== false,
142
+ 'keys' => self::splitkeys($opts['keys'] ?? null),
143
+ 'values' => [],
144
+ 'mask' => is_string($opts['mask'] ?? null) ? $opts['mask'] : '[redacted]',
145
+ 'hint' => self::count($opts['hint'] ?? null, 0),
146
+ 'min' => max(1, self::count($opts['min'] ?? null, 4)),
147
+ ];
148
+ }
149
+
150
+ // The comma-separated literal values a caller registers; a list is taken
151
+ // as-is for a caller that has one.
152
+ public static function splitvalues(mixed $values): array
153
+ {
154
+ if (is_array($values)) {
155
+ return array_values(array_filter($values, 'is_string'));
156
+ }
157
+ $parts = preg_split('/\s*,\s*/', null === $values ? '' : (string)$values) ?: [];
158
+ return array_values(array_filter($parts, function (string $v): bool {
159
+ return '' !== $v;
160
+ }));
161
+ }
162
+
163
+ // A context without options (make_error is reached with a bare one)
164
+ // falls back to the schema defaults, so nothing leaves raw for want of a
165
+ // constructor.
166
+ private static function config_of(?ProjectNameContext $ctx): \stdClass
167
+ {
168
+ $derived = null;
169
+ if (null !== $ctx && is_array($ctx->options)) {
170
+ $derived = $ctx->options['__derived__']['clean'] ?? null;
171
+ }
172
+ if ($derived instanceof \stdClass) {
173
+ return $derived;
174
+ }
175
+ if (is_array($derived)) {
176
+ return (object)$derived;
177
+ }
178
+ require_once __DIR__ . '/../schema.php';
179
+ return self::config(\Voxgig\Struct\Struct::getprop(ProjectNameSchema::optspec(), 'clean'));
180
+ }
181
+
182
+ private static function normkey(mixed $key): string
183
+ {
184
+ return str_replace(['-', '_'], '', strtolower((string)$key));
185
+ }
186
+
187
+ private static function splitkeys(mixed $keys): array
188
+ {
189
+ $parts = preg_split('/\s*,\s*/', null === $keys ? '' : (string)$keys) ?: [];
190
+ $out = [];
191
+ foreach ($parts as $part) {
192
+ $nk = self::normkey($part);
193
+ if ('' !== $nk) {
194
+ $out[] = $nk;
195
+ }
196
+ }
197
+ return $out;
198
+ }
199
+
200
+ // The spec carries numbers as strings, so every target reads it alike.
201
+ private static function count(mixed $val, int $dflt): int
202
+ {
203
+ if (!is_numeric($val)) {
204
+ return $dflt;
205
+ }
206
+ $n = (int)floor((float)$val);
207
+ return 0 <= $n ? $n : $dflt;
208
+ }
209
+
210
+ // The encoded forms a value travels in: Basic and Bearer both carry
211
+ // base64, a query credential is percent-encoded, and a JSON dump escapes
212
+ // it.
213
+ private static function forms(string $value): array
214
+ {
215
+ $out = [$value];
216
+ $add = function (mixed $s) use (&$out): void {
217
+ if (is_string($s) && '' !== $s && !in_array($s, $out, true)) {
218
+ $out[] = $s;
219
+ }
220
+ };
221
+ $add(base64_encode($value));
222
+ $add(rawurlencode($value));
223
+ $json = json_encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
224
+ if (is_string($json)) {
225
+ $add(substr($json, 1, -1));
226
+ }
227
+ return $out;
228
+ }
229
+
230
+ private static function mask_value(\stdClass $cfg, string $value): string
231
+ {
232
+ if (0 < $cfg->hint && strlen($value) > 2 * $cfg->hint) {
233
+ return $cfg->mask . substr($value, -$cfg->hint);
234
+ }
235
+ return $cfg->mask;
236
+ }
237
+
238
+ private static function clean_string(\stdClass $cfg, string $text): string
239
+ {
240
+ $out = $text;
241
+ foreach ($cfg->values as $value) {
242
+ if (is_string($value) && '' !== $value && str_contains($out, $value)) {
243
+ $out = str_replace($value, self::mask_value($cfg, $value), $out);
244
+ }
245
+ }
246
+ return $out;
247
+ }
248
+
249
+ private static function sensitive_key(\stdClass $cfg, mixed $key): bool
250
+ {
251
+ if (null === $key || is_int($key)) {
252
+ return false;
253
+ }
254
+ $nk = self::normkey($key);
255
+ foreach ($cfg->keys as $k) {
256
+ if (str_contains($nk, $k)) {
257
+ return true;
258
+ }
259
+ }
260
+ return false;
261
+ }
262
+
263
+ // A plain-data copy of what is about to leave: jsonSerialize is honoured
264
+ // (a context serialises as its record), closures are dropped, cycles are
265
+ // cut, and no live object is shared with the copy - masking the copy
266
+ // must never mask the pipeline's own spec.
267
+ private static function snapshot(\stdClass $cfg, mixed $val, mixed $key, int $depth, array &$seen): mixed
268
+ {
269
+ if (null === $val) {
270
+ return null;
271
+ }
272
+
273
+ if (is_string($val)) {
274
+ return self::sensitive_key($cfg, $key)
275
+ ? self::mask_value($cfg, $val) : self::clean_string($cfg, $val);
276
+ }
277
+
278
+ if ($val instanceof \Closure) {
279
+ return null;
280
+ }
281
+
282
+ if (!is_array($val) && !is_object($val)) {
283
+ return self::sensitive_key($cfg, $key) ? $cfg->mask : $val;
284
+ }
285
+
286
+ if (self::MAXDEPTH <= $depth) {
287
+ return self::CIRCULAR;
288
+ }
289
+
290
+ if (self::sensitive_key($cfg, $key)) {
291
+ return $cfg->mask;
292
+ }
293
+
294
+ if (is_array($val)) {
295
+ return self::plain($cfg, $val, $depth, $seen);
296
+ }
297
+
298
+ $id = spl_object_id($val);
299
+ if (in_array($id, $seen, true)) {
300
+ return self::CIRCULAR;
301
+ }
302
+
303
+ $seen[] = $id;
304
+ try {
305
+ if ($val instanceof \Throwable) {
306
+ $out = [
307
+ 'message' => self::clean_string($cfg, $val->getMessage()),
308
+ 'stack' => self::clean_string($cfg, $val->getTraceAsString()),
309
+ ];
310
+ foreach (get_object_vars($val) as $k => $v) {
311
+ if (!($v instanceof \Closure)) {
312
+ $out[self::clean_name($cfg, $out, $k)] = self::snapshot($cfg, $v, $k, $depth + 1, $seen);
313
+ }
314
+ }
315
+ return $out;
316
+ }
317
+
318
+ if ($val instanceof \JsonSerializable) {
319
+ $json = $val->jsonSerialize();
320
+ return $json === $val
321
+ ? self::plain($cfg, get_object_vars($val), $depth, $seen)
322
+ : self::snapshot($cfg, $json, $key, $depth + 1, $seen);
323
+ }
324
+
325
+ return self::plain($cfg, get_object_vars($val), $depth, $seen);
326
+ } finally {
327
+ array_pop($seen);
328
+ }
329
+ }
330
+
331
+ private static function plain(\stdClass $cfg, array $val, int $depth, array &$seen): array
332
+ {
333
+ $out = [];
334
+ foreach ($val as $k => $v) {
335
+ if (!($v instanceof \Closure)) {
336
+ $out[self::clean_name($cfg, $out, $k)] = self::snapshot($cfg, $v, $k, $depth + 1, $seen);
337
+ }
338
+ }
339
+ return $out;
340
+ }
341
+
342
+ // A registered value used as a property name is masked like any other
343
+ // string; names that mask alike take a counter, so none is lost.
344
+ private static function clean_name(\stdClass $cfg, array|object $out, int|string $key): int|string
345
+ {
346
+ if (!is_string($key)) {
347
+ return $key;
348
+ }
349
+ $name = self::clean_string($cfg, $key);
350
+ $has = fn (string $n): bool => is_array($out) ? array_key_exists($n, $out) : property_exists($out, $n);
351
+ if ($name === $key || !$has($name)) {
352
+ return $name;
353
+ }
354
+ $i = 1;
355
+ while ($has($name . '#' . $i)) {
356
+ $i++;
357
+ }
358
+ return $name . '#' . $i;
359
+ }
360
+
361
+ // In place: the message, the public fields, and the trace arguments,
362
+ // which hold every context the failing frames were handed. The previous
363
+ // chain too, since var_export walks it.
364
+ private static function clean_throwable(\stdClass $cfg, \Throwable $top): void
365
+ {
366
+ $seen = [];
367
+ for ($err = $top; null !== $err && !in_array(spl_object_id($err), $seen, true);
368
+ $err = $err->getPrevious()) {
369
+ $seen[] = spl_object_id($err);
370
+ self::clean_one($cfg, $err);
371
+ }
372
+ }
373
+
374
+ private static function clean_one(\stdClass $cfg, \Throwable $err): void
375
+ {
376
+ $msg = self::clean_string($cfg, $err->getMessage());
377
+ if ($msg !== $err->getMessage()) {
378
+ self::rewrite($err, 'message', $msg);
379
+ }
380
+
381
+ // print_r and var_export show the protected code, a string for some
382
+ // drivers.
383
+ $code = $err->getCode();
384
+ $cleancode = is_string($code) ? self::clean_string($cfg, $code) : $code;
385
+ if ($cleancode !== $code) {
386
+ self::rewrite($err, 'code', $cleancode);
387
+ }
388
+
389
+ // The base __toString caches its text, raw message and all.
390
+ if ('' !== self::read($err, 'string')) {
391
+ self::rewrite($err, 'string', '');
392
+ }
393
+
394
+ $trace = $err->getTrace();
395
+ $stripped = false;
396
+ foreach ($trace as $i => $frame) {
397
+ if (is_array($frame) && array_key_exists('args', $frame)) {
398
+ unset($trace[$i]['args']);
399
+ $stripped = true;
400
+ }
401
+ }
402
+ if ($stripped) {
403
+ self::rewrite($err, 'trace', $trace);
404
+ }
405
+
406
+ foreach (get_object_vars($err) as $k => $raw) {
407
+ $v = $raw;
408
+ if (is_string($v)) {
409
+ $v = self::sensitive_key($cfg, $k)
410
+ ? self::mask_value($cfg, $v) : self::clean_string($cfg, $v);
411
+ } elseif ((is_array($v) || is_object($v)) && !($v instanceof \Closure)) {
412
+ $seen = [];
413
+ $v = self::snapshot($cfg, $v, $k, 1, $seen);
414
+ }
415
+ $name = is_string($k) ? self::clean_string($cfg, $k) : $k;
416
+ if ($name === $k) {
417
+ if ($v !== $raw) {
418
+ $err->$k = $v;
419
+ }
420
+ continue;
421
+ }
422
+ // Only a dynamic property can carry a secret name. Re-adding it
423
+ // may raise a deprecation a handler turns into an exception; the
424
+ // raw name is gone either way.
425
+ unset($err->$k);
426
+ try {
427
+ $err->{self::clean_name($cfg, $err, $k)} = $v;
428
+ } catch (\Throwable $_e) {
429
+ }
430
+ }
431
+ }
432
+
433
+ private static function read(\Throwable $err, string $prop): mixed
434
+ {
435
+ $owner = $err instanceof \Exception ? \Exception::class : \Error::class;
436
+ return (new \ReflectionProperty($owner, $prop))->getValue($err);
437
+ }
438
+
439
+ // Exception::$message and ::$trace cannot be assigned from outside, and
440
+ // a closure cannot be bound to an internal class, so reflection is the
441
+ // one door to cleaning a thrown error in place.
442
+ private static function rewrite(\Throwable $err, string $prop, mixed $value): void
9
443
  {
10
- return $val;
444
+ $owner = $err instanceof \Exception ? \Exception::class : \Error::class;
445
+ $rp = new \ReflectionProperty($owner, $prop);
446
+ $rp->setValue($err, $value);
11
447
  }
12
448
  }
@@ -7,13 +7,7 @@ class ProjectNameDone
7
7
  {
8
8
  public static function call(ProjectNameContext $ctx): mixed
9
9
  {
10
- if ($ctx->ctrl->explain) {
11
- $ctx->ctrl->explain = ($ctx->utility->clean)($ctx, $ctx->ctrl->explain);
12
- $er = $ctx->ctrl->explain['result'] ?? null;
13
- if (is_array($er)) {
14
- unset($ctx->ctrl->explain['result']['err']);
15
- }
16
- }
10
+ self::clean_explain($ctx);
17
11
  if ($ctx->result && $ctx->result->ok) {
18
12
  $resdata = $ctx->result->resdata;
19
13
  if (is_object($resdata)) {
@@ -23,4 +17,17 @@ class ProjectNameDone
23
17
  }
24
18
  return ($ctx->utility->make_error)($ctx, null);
25
19
  }
20
+
21
+ // The record is an array the context owns (the caller's copy is its
22
+ // own), so the cleaned copy is assigned back; err is pruned from it.
23
+ public static function clean_explain(ProjectNameContext $ctx): void
24
+ {
25
+ if (!$ctx->ctrl->explain) {
26
+ return;
27
+ }
28
+ $ctx->ctrl->explain = ($ctx->utility->clean)($ctx, $ctx->ctrl->explain);
29
+ if (is_array($ctx->ctrl->explain['result'] ?? null)) {
30
+ unset($ctx->ctrl->explain['result']['err']);
31
+ }
32
+ }
26
33
  }
@@ -31,18 +31,23 @@ class ProjectNameMakeError
31
31
  $err = $ctx->make_error('unknown', 'unknown error');
32
32
  }
33
33
 
34
- $errmsg = ($err instanceof ProjectNameError) ? $err->msg : (string)$err;
34
+ $errmsg = ($err instanceof ProjectNameError) ? $err->msg
35
+ : (($err instanceof \Throwable) ? $err->getMessage() : (string)$err);
35
36
  $msg = "ProjectNameSDK: {$opname}: {$errmsg}";
36
- $msg = ($ctx->utility->clean)($ctx, $msg);
37
37
 
38
38
  $result->err = null;
39
39
  $spec = $ctx->spec;
40
40
 
41
+ $sdk_err = new ProjectNameError(
42
+ ($err instanceof ProjectNameError) ? $err->sdk_code : '', $msg, $ctx);
43
+ ($ctx->utility->clean)($ctx, $sdk_err);
44
+
41
45
  if ($ctx->ctrl->explain) {
42
- $ctx->ctrl->explain['err'] = ['message' => $msg];
46
+ $ctx->ctrl->explain['err'] = ['message' => $sdk_err->msg];
47
+ // A failure before done() leaves the record holding the live spec.
48
+ ($ctx->utility->clean_explain)($ctx);
43
49
  }
44
50
 
45
- $sdk_err = new ProjectNameError('', $msg, $ctx);
46
51
  $sdk_err->result = ($ctx->utility->clean)($ctx, $result);
47
52
  $sdk_err->spec = ($ctx->utility->clean)($ctx, $spec);
48
53
 
@@ -50,9 +55,6 @@ class ProjectNameMakeError
50
55
  // on `err->status` / `err->notFound()` rather than reaching into
51
56
  // `err->result`.
52
57
  $sdk_err->status = null === $result->status ? -1 : (int)$result->status;
53
- if ($err instanceof ProjectNameError) {
54
- $sdk_err->sdk_code = $err->sdk_code;
55
- }
56
58
 
57
59
  $ctx->ctrl->err = $sdk_err;
58
60
 
@@ -27,6 +27,49 @@ class ProjectNameMakeOptions
27
27
  {
28
28
  $options = $ctx->options ?? [];
29
29
 
30
+ // THE OPTION SPEC IS GENERATED, NOT WRITTEN HERE.
31
+ //
32
+ // `ProjectNameSchema::optspec()` is built from the model:
33
+ // `main.kit.optspec` for the standard options, plus one entry per
34
+ // feature this target carries, taken from that feature's own
35
+ // `config.options` / `config.optspec`. Editing this file to add an
36
+ // option would put it back where it was — one of twenty
37
+ // hand-maintained copies of a schema nothing cross-checked — so add
38
+ // it to the model instead and every ported target validates it.
39
+ //
40
+ // Required explicitly rather than left to the classmap: the generated
41
+ // SDK is exercised (README examples, the compile checks) without a
42
+ // dumped composer autoload.
43
+ require_once __DIR__ . '/../schema.php';
44
+ require_once __DIR__ . '/../core/Context.php';
45
+ $optspec = ProjectNameSchema::optspec();
46
+
47
+ $config = $ctx->config ?? [];
48
+ $cfgopts = isset($config['options']) && is_array($config['options']) ? $config['options'] : [];
49
+
50
+ // The secret registry exists BEFORE validation, fed from the raw
51
+ // input, so the constructor's own rejection of a mistyped credential
52
+ // is clean too.
53
+ $block = function (mixed $clean): array {
54
+ return is_object($clean) ? get_object_vars($clean) : (is_array($clean) ? $clean : []);
55
+ };
56
+ $rawclean = $block($options['clean'] ?? null);
57
+ $cfgclean = $block($cfgopts['clean'] ?? null);
58
+ $specclean = $block(\Voxgig\Struct\Struct::getprop($optspec, 'clean'));
59
+ $cleancfg = ProjectNameClean::config(array_merge($specclean, $cfgclean, $rawclean));
60
+ $cleanctx = new ProjectNameContext([
61
+ 'options' => ['__derived__' => ['clean' => $cleancfg]],
62
+ ], null);
63
+ $rawopts = is_object($options) ? get_object_vars($options)
64
+ : (is_array($options) ? $options : []);
65
+ unset($rawopts['clean']);
66
+ ProjectNameClean::add_options($cleanctx, $rawopts);
67
+ foreach ([$cfgclean, $rawclean] as $source) {
68
+ foreach (ProjectNameClean::splitvalues($source['values'] ?? null) as $raw) {
69
+ ProjectNameClean::add($cleanctx, $raw);
70
+ }
71
+ }
72
+
30
73
  // Merge custom utility overrides.
31
74
  //
32
75
  // A key naming a real utility member REPLACES it; anything else is
@@ -144,31 +187,17 @@ class ProjectNameMakeOptions
144
187
  $opts['feature'] = $fmap;
145
188
  }
146
189
 
147
- $config = $ctx->config ?? [];
148
- $cfgopts = isset($config['options']) && is_array($config['options']) ? $config['options'] : [];
149
-
150
- // THE OPTION SPEC IS GENERATED, NOT WRITTEN HERE.
151
- //
152
- // `ProjectNameSchema::optspec()` is built from the model:
153
- // `main.kit.optspec` for the standard options, plus one entry per
154
- // feature this target carries, taken from that feature's own
155
- // `config.options` / `config.optspec`. Editing this file to add an
156
- // option would put it back where it was — one of twenty
157
- // hand-maintained copies of a schema nothing cross-checked — so add
158
- // it to the model instead and every ported target validates it.
159
- //
160
- // Required explicitly rather than left to the classmap: the generated
161
- // SDK is exercised (README examples, the compile checks) without a
162
- // dumped composer autoload.
163
- require_once __DIR__ . '/../schema.php';
164
- $optspec = ProjectNameSchema::optspec();
165
-
166
190
  // Empty [] would be treated as a list and clobber the map under merge;
167
191
  // substitute an empty stdClass to preserve map semantics.
168
192
  $cfgopts_merge = empty($cfgopts) ? new \stdClass() : $cfgopts;
169
193
  $opts_merge = empty($opts) ? new \stdClass() : $opts;
170
194
  $merged = \Voxgig\Struct\Struct::merge([(object)[], $cfgopts_merge, $opts_merge]);
171
- $validated = \Voxgig\Struct\Struct::validate($merged, $optspec);
195
+ try {
196
+ $validated = \Voxgig\Struct\Struct::validate($merged, $optspec);
197
+ } catch (\Throwable $err) {
198
+ ProjectNameClean::call($cleanctx, $err);
199
+ throw $err;
200
+ }
172
201
  $opts = self::to_array_deep($validated);
173
202
  if (!is_array($opts)) {
174
203
  $opts = [];
@@ -215,7 +244,7 @@ class ProjectNameMakeOptions
215
244
  }
216
245
  $opts['base'] = preg_replace_callback(
217
246
  '/\{([A-Za-z0-9_]+)\}/',
218
- function ($m) use ($server, $testmode, $sdkname, $base) {
247
+ function ($m) use ($server, $testmode, $sdkname, $base, $cleanctx) {
219
248
  $name = $m[1];
220
249
  $val = $server[$name] ?? '';
221
250
  if (!is_string($val)) {
@@ -225,10 +254,11 @@ class ProjectNameMakeOptions
225
254
  if ($testmode) {
226
255
  return 'test-' . $name;
227
256
  }
228
- throw new \InvalidArgumentException(
257
+ // Its trace holds the raw options.
258
+ throw ProjectNameClean::call($cleanctx, new \InvalidArgumentException(
229
259
  $sdkname . ": the server variable '" . $name . "' is required: " .
230
260
  "the API base URL is '" . $base . "' — pass " .
231
- "['server' => ['" . $name . "' => '...']] in the SDK options");
261
+ "['server' => ['" . $name . "' => '...']] in the SDK options"));
232
262
  }
233
263
  return $val;
234
264
  },
@@ -243,18 +273,6 @@ class ProjectNameMakeOptions
243
273
  $opts['system']['fetch'] = $sys_fetch;
244
274
  }
245
275
 
246
- $clean_keys = \Voxgig\Struct\Struct::getpath($opts, 'clean.keys');
247
- if (!is_string($clean_keys)) {
248
- $clean_keys = 'key,token,id';
249
- }
250
- $parts = array_filter(array_map('trim', explode(',', $clean_keys)), function ($p) {
251
- return $p !== '';
252
- });
253
- $parts = array_map(function ($p) {
254
- return \Voxgig\Struct\Struct::escre($p);
255
- }, $parts);
256
- $keyre = implode('|', $parts);
257
-
258
276
  // Resolve the feature add-order: an explicit list order (above) wins;
259
277
  // otherwise order the map test-first, then the remaining names sorted,
260
278
  // so the outcome is deterministic and `test` is always the base.
@@ -286,9 +304,15 @@ class ProjectNameMakeOptions
286
304
  }
287
305
  }
288
306
 
289
- $derived = ['clean' => $keyre === '' ? [] : ['keyre' => $keyre]];
290
- $derived['featureorder'] = $featureorder;
291
- $opts['__derived__'] = $derived;
307
+ // Again over the merged result: the config's own defaults can carry one.
308
+ $merged = $opts;
309
+ unset($merged['clean']);
310
+ ProjectNameClean::add_options($cleanctx, $merged);
311
+
312
+ $opts['__derived__'] = [
313
+ 'clean' => $cleancfg,
314
+ 'featureorder' => $featureorder,
315
+ ];
292
316
 
293
317
  return $opts;
294
318
  }
@@ -37,6 +37,8 @@ require_once __DIR__ . '/TransformResponse.php';
37
37
 
38
38
  ProjectNameUtility::setRegistrar(function (ProjectNameUtility $u): void {
39
39
  $u->clean = [ProjectNameClean::class, 'call'];
40
+ $u->clean_add = [ProjectNameClean::class, 'add'];
41
+ $u->clean_explain = [ProjectNameDone::class, 'clean_explain'];
40
42
  $u->done = [ProjectNameDone::class, 'call'];
41
43
  $u->make_error = [ProjectNameMakeError::class, 'call'];
42
44
  $u->feature_add = [ProjectNameFeatureAdd::class, 'call'];