@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.
- package/bin/voxgig-sdkgen +1 -1
- package/dist/action/copies.d.ts +21 -0
- package/dist/action/copies.js +146 -0
- package/dist/action/copies.js.map +1 -0
- package/dist/action/doctor.d.ts +15 -2
- package/dist/action/doctor.js +169 -23
- package/dist/action/doctor.js.map +1 -1
- package/dist/action/edition.js +6 -2
- package/dist/action/edition.js.map +1 -1
- package/dist/action/feature.js +6 -2
- package/dist/action/feature.js.map +1 -1
- package/dist/action/package.js +28 -10
- package/dist/action/package.js.map +1 -1
- package/dist/action/remove.js +2 -0
- package/dist/action/remove.js.map +1 -1
- package/dist/action/resolve.d.ts +1 -0
- package/dist/action/resolve.js +10 -2
- package/dist/action/resolve.js.map +1 -1
- package/dist/action/target.js +6 -2
- package/dist/action/target.js.map +1 -1
- package/dist/helpers/naming.js +1 -1
- package/dist/helpers/naming.js.map +1 -1
- package/dist/sdkgen.d.ts +2 -1
- package/dist/sdkgen.js +36 -3
- package/dist/sdkgen.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/model/sdkgen.aontu +7 -1
- package/package.json +1 -1
- package/project/.sdk/model/feature/debug.aontu +3 -1
- package/project/.sdk/src/cmp/c/PrepareAuth_c.ts +8 -28
- package/project/.sdk/src/cmp/c/TestClean_c.ts +774 -0
- package/project/.sdk/src/cmp/c/Test_c.ts +3 -0
- package/project/.sdk/src/cmp/c/fragment/Entity.fragment.c +16 -5
- package/project/.sdk/src/cmp/c/fragment/Main.fragment.c +1 -1
- package/project/.sdk/src/cmp/clojure/PrepareAuth_clojure.ts +3 -0
- package/project/.sdk/src/cmp/clojure/TestClean_clojure.ts +473 -0
- package/project/.sdk/src/cmp/clojure/Test_clojure.ts +6 -0
- package/project/.sdk/src/cmp/clojure/fragment/Entity.fragment.clj +18 -8
- package/project/.sdk/src/cmp/cpp/PrepareAuth_cpp.ts +3 -0
- package/project/.sdk/src/cmp/cpp/TestClean_cpp.ts +782 -0
- package/project/.sdk/src/cmp/cpp/TestEntity_cpp.ts +1 -1
- package/project/.sdk/src/cmp/cpp/Test_cpp.ts +2 -0
- package/project/.sdk/src/cmp/csharp/PrepareAuth_csharp.ts +3 -0
- package/project/.sdk/src/cmp/csharp/TestClean_csharp.ts +887 -0
- package/project/.sdk/src/cmp/csharp/Test_csharp.ts +2 -0
- package/project/.sdk/src/cmp/csharp/fragment/EntityBase.fragment.cs +68 -4
- package/project/.sdk/src/cmp/csharp/fragment/Main.fragment.cs +8 -2
- package/project/.sdk/src/cmp/csharp/fragment/SdkError.fragment.cs +49 -0
- package/project/.sdk/src/cmp/elixir/PrepareAuth_elixir.ts +3 -0
- package/project/.sdk/src/cmp/elixir/Schema_elixir.ts +20 -10
- package/project/.sdk/src/cmp/elixir/TestClean_elixir.ts +666 -0
- package/project/.sdk/src/cmp/elixir/Test_elixir.ts +4 -0
- package/project/.sdk/src/cmp/elixir/fragment/Main.fragment.ex +1 -1
- package/project/.sdk/src/cmp/elixir/fragment/Pipeline.fragment.ex +14 -2
- package/project/.sdk/src/cmp/go/PrepareAuth_go.ts +3 -0
- package/project/.sdk/src/cmp/go/TestClean_go.ts +804 -0
- package/project/.sdk/src/cmp/go/Test_go.ts +3 -0
- package/project/.sdk/src/cmp/go/fragment/Entity.fragment.go +54 -4
- package/project/.sdk/src/cmp/go/fragment/Main.fragment.go +27 -2
- package/project/.sdk/src/cmp/java/PrepareAuth_java.ts +3 -0
- package/project/.sdk/src/cmp/java/TestClean_java.ts +884 -0
- package/project/.sdk/src/cmp/java/Test_java.ts +2 -0
- package/project/.sdk/src/cmp/java/fragment/EntityBase.fragment.java +56 -11
- package/project/.sdk/src/cmp/java/fragment/SdkError.fragment.java +36 -3
- package/project/.sdk/src/cmp/js/PrepareAuth_js.ts +3 -0
- package/project/.sdk/src/cmp/js/TestClean_js.ts +458 -0
- package/project/.sdk/src/cmp/js/Test_js.ts +2 -0
- package/project/.sdk/src/cmp/js/fragment/EntityBase.fragment.js +5 -4
- package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/EntityListOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/Main.fragment.js +11 -2
- package/project/.sdk/src/cmp/js/fragment/SdkError.fragment.js +17 -1
- package/project/.sdk/src/cmp/kotlin/Package_kotlin.ts +5 -0
- package/project/.sdk/src/cmp/kotlin/PrepareAuth_kotlin.ts +3 -0
- package/project/.sdk/src/cmp/kotlin/TestClean_kotlin.ts +654 -0
- package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +3 -0
- package/project/.sdk/src/cmp/kotlin/fragment/EntityBase.fragment.kt +44 -11
- package/project/.sdk/src/cmp/kotlin/fragment/SdkError.fragment.kt +31 -0
- package/project/.sdk/src/cmp/lua/PrepareAuth_lua.ts +3 -0
- package/project/.sdk/src/cmp/lua/TestClean_lua.ts +769 -0
- package/project/.sdk/src/cmp/lua/Test_lua.ts +3 -0
- package/project/.sdk/src/cmp/lua/fragment/Entity.fragment.lua +77 -1
- package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +49 -2
- package/project/.sdk/src/cmp/ocaml/Entity_ocaml.ts +3 -2
- package/project/.sdk/src/cmp/ocaml/PrepareAuth_ocaml.ts +4 -25
- package/project/.sdk/src/cmp/ocaml/TestClean_ocaml.ts +538 -0
- package/project/.sdk/src/cmp/ocaml/Test_ocaml.ts +5 -0
- package/project/.sdk/src/cmp/ocaml/fragment/RunOp.fragment.ml +16 -4
- package/project/.sdk/src/cmp/perl/PrepareAuth_perl.ts +3 -0
- package/project/.sdk/src/cmp/perl/TestClean_perl.ts +619 -0
- package/project/.sdk/src/cmp/perl/Test_perl.ts +3 -0
- package/project/.sdk/src/cmp/perl/fragment/Entity.fragment.pm +67 -5
- package/project/.sdk/src/cmp/perl/fragment/Main.fragment.pm +13 -1
- package/project/.sdk/src/cmp/php/PrepareAuth_php.ts +3 -0
- package/project/.sdk/src/cmp/php/TestClean_php.ts +809 -0
- package/project/.sdk/src/cmp/php/Test_php.ts +2 -0
- package/project/.sdk/src/cmp/php/fragment/Entity.fragment.php +96 -55
- package/project/.sdk/src/cmp/php/fragment/Main.fragment.php +15 -2
- package/project/.sdk/src/cmp/py/PrepareAuth_py.ts +3 -0
- package/project/.sdk/src/cmp/py/TestClean_py.ts +549 -0
- package/project/.sdk/src/cmp/py/Test_py.ts +3 -0
- package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +83 -55
- package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +19 -3
- package/project/.sdk/src/cmp/rb/PrepareAuth_rb.ts +3 -0
- package/project/.sdk/src/cmp/rb/TestClean_rb.ts +535 -0
- package/project/.sdk/src/cmp/rb/Test_rb.ts +3 -0
- package/project/.sdk/src/cmp/rb/fragment/Entity.fragment.rb +108 -46
- package/project/.sdk/src/cmp/rb/fragment/Main.fragment.rb +12 -1
- package/project/.sdk/src/cmp/rust/PrepareAuth_rust.ts +9 -45
- package/project/.sdk/src/cmp/rust/TestClean_rust.ts +881 -0
- package/project/.sdk/src/cmp/rust/Test_rust.ts +3 -0
- package/project/.sdk/src/cmp/rust/fragment/Entity.fragment.rs +14 -6
- package/project/.sdk/src/cmp/rust/fragment/Main.fragment.rs +17 -1
- package/project/.sdk/src/cmp/rust/fragment/SdkError.fragment.rs +34 -2
- package/project/.sdk/src/cmp/scala/PrepareAuth_scala.ts +3 -0
- package/project/.sdk/src/cmp/scala/TestClean_scala.ts +608 -0
- package/project/.sdk/src/cmp/scala/Test_scala.ts +3 -0
- package/project/.sdk/src/cmp/scala/fragment/EntityBase.fragment.scala +58 -6
- package/project/.sdk/src/cmp/swift/PrepareAuth_swift.ts +3 -0
- package/project/.sdk/src/cmp/swift/TestClean_swift.ts +671 -0
- package/project/.sdk/src/cmp/swift/Test_swift.ts +3 -0
- package/project/.sdk/src/cmp/swift/fragment/EntityBase.fragment.swift +10 -0
- package/project/.sdk/src/cmp/swift/fragment/Main.fragment.swift +16 -2
- package/project/.sdk/src/cmp/swift/fragment/SdkError.fragment.swift +47 -3
- package/project/.sdk/src/cmp/ts/PrepareAuth_ts.ts +3 -0
- package/project/.sdk/src/cmp/ts/TestClean_ts.ts +465 -0
- package/project/.sdk/src/cmp/ts/Test_ts.ts +2 -0
- package/project/.sdk/src/cmp/ts/fragment/EntityBase.fragment.ts +5 -4
- package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +8 -2
- package/project/.sdk/src/cmp/ts/fragment/SdkError.fragment.ts +20 -2
- package/project/.sdk/src/cmp/zig/PrepareAuth_zig.ts +3 -0
- package/project/.sdk/src/cmp/zig/TestClean_zig.ts +791 -0
- package/project/.sdk/src/cmp/zig/Test_zig.ts +5 -0
- package/project/.sdk/src/cmp/zig/fragment/Build.fragment.zig +19 -0
- package/project/.sdk/src/cmp/zig/fragment/Entity.fragment.zig +14 -5
- package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +1 -1
- package/project/.sdk/tm/c/core/context.c +25 -0
- package/project/.sdk/tm/c/core/error.c +16 -0
- package/project/.sdk/tm/c/core/sdk.h +22 -0
- package/project/.sdk/tm/c/feature/audit.c +2 -0
- package/project/.sdk/tm/c/feature/cost.c +1 -0
- package/project/.sdk/tm/c/feature/debug.c +19 -29
- package/project/.sdk/tm/c/feature/log.c +21 -2
- package/project/.sdk/tm/c/feature/proxy.c +55 -3
- package/project/.sdk/tm/c/feature/secrets.c +7 -0
- package/project/.sdk/tm/c/feature/telemetry.c +2 -0
- package/project/.sdk/tm/c/tests/feature_test.c +2 -2
- package/project/.sdk/tm/c/utility/clean.c +530 -8
- package/project/.sdk/tm/c/utility/done.c +28 -12
- package/project/.sdk/tm/c/utility/make_error.c +4 -3
- package/project/.sdk/tm/c/utility/make_options.c +71 -45
- package/project/.sdk/tm/clojure/feature/secrets/sdk/feature/secrets.clj +15 -0
- package/project/.sdk/tm/clojure/src/sdk/client.clj +20 -4
- package/project/.sdk/tm/clojure/src/sdk/core.clj +319 -35
- package/project/.sdk/tm/clojure/src/sdk/features.clj +68 -30
- package/project/.sdk/tm/clojure/test/sdk/test/feature.clj +4 -2
- package/project/.sdk/tm/clojure/test/sdk/test/pipeline.clj +47 -20
- package/project/.sdk/tm/clojure/test/sdk/test_runner.clj +4 -0
- package/project/.sdk/tm/cpp/core/types.hpp +93 -3
- package/project/.sdk/tm/cpp/feature/audit.hpp +1 -0
- package/project/.sdk/tm/cpp/feature/cost.hpp +1 -0
- package/project/.sdk/tm/cpp/feature/debug.hpp +20 -12
- package/project/.sdk/tm/cpp/feature/log.hpp +31 -9
- package/project/.sdk/tm/cpp/feature/proxy.hpp +52 -6
- package/project/.sdk/tm/cpp/feature/secrets.hpp +13 -0
- package/project/.sdk/tm/cpp/feature/telemetry.hpp +4 -2
- package/project/.sdk/tm/cpp/test/feature_test.cpp +2 -2
- package/project/.sdk/tm/cpp/utility/pipeline.hpp +426 -51
- package/project/.sdk/tm/csharp/core/Context.cs +32 -0
- package/project/.sdk/tm/csharp/core/Utility.cs +2 -0
- package/project/.sdk/tm/csharp/feature/AuditFeature.cs +1 -0
- package/project/.sdk/tm/csharp/feature/CostFeature.cs +7 -5
- package/project/.sdk/tm/csharp/feature/DebugFeature.cs +19 -16
- package/project/.sdk/tm/csharp/feature/FeatureOptions.cs +16 -0
- package/project/.sdk/tm/csharp/feature/LogFeature.cs +4 -1
- package/project/.sdk/tm/csharp/feature/ProxyFeature.cs +26 -5
- package/project/.sdk/tm/csharp/feature/SecretsFeature.cs +16 -0
- package/project/.sdk/tm/csharp/feature/TelemetryFeature.cs +4 -2
- package/project/.sdk/tm/csharp/test/FeatureTest.cs +2 -2
- package/project/.sdk/tm/csharp/utility/Clean.cs +440 -2
- package/project/.sdk/tm/csharp/utility/Done.cs +27 -11
- package/project/.sdk/tm/csharp/utility/MakeError.cs +19 -8
- package/project/.sdk/tm/csharp/utility/MakeOptions.cs +119 -29
- package/project/.sdk/tm/csharp/utility/MakeResponse.cs +21 -11
- package/project/.sdk/tm/csharp/utility/Register.cs +1 -0
- package/project/.sdk/tm/elixir/lib/projectname/context.ex +19 -0
- package/project/.sdk/tm/elixir/lib/projectname/entity_base.ex +22 -1
- package/project/.sdk/tm/elixir/lib/projectname/error.ex +24 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/audit.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/cost.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/debug.ex +13 -13
- package/project/.sdk/tm/elixir/lib/projectname/feature/log.ex +18 -5
- package/project/.sdk/tm/elixir/lib/projectname/feature/proxy.ex +19 -1
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets.ex +15 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/telemetry.ex +4 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature.ex +22 -0
- package/project/.sdk/tm/elixir/lib/projectname/utility.ex +464 -41
- package/project/.sdk/tm/elixir/test/feature_test.exs +3 -2
- package/project/.sdk/tm/go/core/context.go +42 -0
- package/project/.sdk/tm/go/core/error.go +30 -10
- package/project/.sdk/tm/go/core/utility_type.go +2 -0
- package/project/.sdk/tm/go/feature/audit_feature.go +1 -0
- package/project/.sdk/tm/go/feature/base_feature.go +12 -0
- package/project/.sdk/tm/go/feature/cost_feature.go +2 -2
- package/project/.sdk/tm/go/feature/debug_feature.go +14 -12
- package/project/.sdk/tm/go/feature/log_feature.go +13 -8
- package/project/.sdk/tm/go/feature/proxy_feature.go +26 -6
- package/project/.sdk/tm/go/feature/secrets_feature.go +19 -0
- package/project/.sdk/tm/go/feature/telemetry_feature.go +4 -2
- package/project/.sdk/tm/go/test/feature_test.go +2 -2
- package/project/.sdk/tm/go/utility/clean.go +585 -2
- package/project/.sdk/tm/go/utility/done.go +29 -9
- package/project/.sdk/tm/go/utility/make_error.go +51 -16
- package/project/.sdk/tm/go/utility/make_options.go +77 -36
- package/project/.sdk/tm/go/utility/register.go +12 -0
- package/project/.sdk/tm/java/core/Context.java +29 -0
- package/project/.sdk/tm/java/core/SdkClient.java +4 -2
- package/project/.sdk/tm/java/core/Utility.java +7 -0
- package/project/.sdk/tm/java/feature/AuditFeature.java +6 -0
- package/project/.sdk/tm/java/feature/CostFeature.java +5 -0
- package/project/.sdk/tm/java/feature/DebugFeature.java +25 -14
- package/project/.sdk/tm/java/feature/LogFeature.java +11 -4
- package/project/.sdk/tm/java/feature/ProxyFeature.java +41 -6
- package/project/.sdk/tm/java/feature/SecretsFeature.java +18 -0
- package/project/.sdk/tm/java/feature/TelemetryFeature.java +8 -2
- package/project/.sdk/tm/java/test/FeatureTest.java +2 -2
- package/project/.sdk/tm/java/utility/Clean.java +519 -1
- package/project/.sdk/tm/java/utility/Done.java +1 -1
- package/project/.sdk/tm/java/utility/MakeError.java +5 -1
- package/project/.sdk/tm/java/utility/MakeOptions.java +55 -31
- package/project/.sdk/tm/java/utility/Register.java +4 -0
- package/project/.sdk/tm/js/src/Context.js +5 -1
- package/project/.sdk/tm/js/src/feature/audit/AuditFeature.js +2 -2
- package/project/.sdk/tm/js/src/feature/cost/CostFeature.js +2 -2
- package/project/.sdk/tm/js/src/feature/debug/DebugFeature.js +13 -7
- package/project/.sdk/tm/js/src/feature/log/LogFeature.js +9 -5
- package/project/.sdk/tm/js/src/feature/proxy/ProxyFeature.js +19 -1
- package/project/.sdk/tm/js/src/feature/secrets/SecretsFeature.js +14 -0
- package/project/.sdk/tm/js/src/feature/telemetry/TelemetryFeature.js +4 -2
- package/project/.sdk/tm/js/src/utility/CleanUtility.js +294 -21
- package/project/.sdk/tm/js/src/utility/DoneUtility.js +17 -5
- package/project/.sdk/tm/js/src/utility/MakeErrorUtility.js +18 -2
- package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +39 -15
- package/project/.sdk/tm/js/src/utility/Utility.js +4 -2
- package/project/.sdk/tm/js/test/feature/harness.js +11 -1
- package/project/.sdk/tm/js/test/feature.test.js +9 -2
- package/project/.sdk/tm/kotlin/core/Context.kt +19 -0
- package/project/.sdk/tm/kotlin/core/SdkClient.kt +9 -2
- package/project/.sdk/tm/kotlin/core/Utility.kt +2 -0
- package/project/.sdk/tm/kotlin/feature/AuditFeature.kt +11 -9
- package/project/.sdk/tm/kotlin/feature/CostFeature.kt +8 -5
- package/project/.sdk/tm/kotlin/feature/DebugFeature.kt +15 -22
- package/project/.sdk/tm/kotlin/feature/LogFeature.kt +8 -4
- package/project/.sdk/tm/kotlin/feature/ProxyFeature.kt +26 -2
- package/project/.sdk/tm/kotlin/feature/SecretsFeature.kt +11 -0
- package/project/.sdk/tm/kotlin/feature/TelemetryFeature.kt +4 -2
- package/project/.sdk/tm/kotlin/test/FeatureTest.kt +2 -2
- package/project/.sdk/tm/kotlin/utility/CoreUtil.kt +447 -11
- package/project/.sdk/tm/kotlin/utility/MakeOptions.kt +38 -31
- package/project/.sdk/tm/kotlin/utility/Register.kt +1 -0
- package/project/.sdk/tm/lua/core/context.lua +43 -0
- package/project/.sdk/tm/lua/core/error.lua +36 -1
- package/project/.sdk/tm/lua/core/utility_type.lua +4 -0
- package/project/.sdk/tm/lua/feature/audit_feature.lua +2 -2
- package/project/.sdk/tm/lua/feature/cost_feature.lua +2 -2
- package/project/.sdk/tm/lua/feature/debug_feature.lua +21 -17
- package/project/.sdk/tm/lua/feature/log_feature.lua +2 -1
- package/project/.sdk/tm/lua/feature/proxy_feature.lua +23 -1
- package/project/.sdk/tm/lua/feature/secrets_feature.lua +18 -0
- package/project/.sdk/tm/lua/feature/telemetry_feature.lua +4 -2
- package/project/.sdk/tm/lua/test/feature/secrets/secrets_feature_test.lua +3 -2
- package/project/.sdk/tm/lua/test/feature_test.lua +10 -3
- package/project/.sdk/tm/lua/utility/clean.lua +426 -2
- package/project/.sdk/tm/lua/utility/clean_explain.lua +34 -0
- package/project/.sdk/tm/lua/utility/done.lua +1 -7
- package/project/.sdk/tm/lua/utility/make_error.lua +3 -1
- package/project/.sdk/tm/lua/utility/make_options.lua +76 -30
- package/project/.sdk/tm/lua/utility/register.lua +4 -1
- package/project/.sdk/tm/ocaml/Makefile +5 -1
- package/project/.sdk/tm/ocaml/feature/secrets_feature.ml +12 -1
- package/project/.sdk/tm/ocaml/sdk_features.ml +78 -18
- package/project/.sdk/tm/ocaml/sdk_helpers.ml +27 -0
- package/project/.sdk/tm/ocaml/sdk_runtime.ml +304 -26
- package/project/.sdk/tm/ocaml/sdk_types.ml +1 -0
- package/project/.sdk/tm/ocaml/test/feature/secrets/t_secrets.ml +3 -1
- package/project/.sdk/tm/ocaml/test/t_feature.ml +2 -2
- package/project/.sdk/tm/perl/core/context.pm +27 -0
- package/project/.sdk/tm/perl/core/error.pm +52 -5
- package/project/.sdk/tm/perl/feature/audit_feature.pm +2 -2
- package/project/.sdk/tm/perl/feature/cost_feature.pm +2 -2
- package/project/.sdk/tm/perl/feature/debug_feature.pm +17 -13
- package/project/.sdk/tm/perl/feature/log_feature.pm +3 -1
- package/project/.sdk/tm/perl/feature/proxy_feature.pm +21 -1
- package/project/.sdk/tm/perl/feature/secrets_feature.pm +20 -1
- package/project/.sdk/tm/perl/feature/telemetry_feature.pm +4 -2
- package/project/.sdk/tm/perl/t/feature.t +4 -2
- package/project/.sdk/tm/perl/utility/clean.pm +345 -1
- package/project/.sdk/tm/perl/utility/done.pm +24 -6
- package/project/.sdk/tm/perl/utility/make_error.pm +17 -4
- package/project/.sdk/tm/perl/utility/make_options.pm +33 -14
- package/project/.sdk/tm/php/core/Context.php +24 -1
- package/project/.sdk/tm/php/core/Error.php +34 -3
- package/project/.sdk/tm/php/core/UtilityType.php +4 -0
- package/project/.sdk/tm/php/feature/AuditFeature.php +2 -2
- package/project/.sdk/tm/php/feature/CostFeature.php +2 -2
- package/project/.sdk/tm/php/feature/DebugFeature.php +18 -9
- package/project/.sdk/tm/php/feature/LogFeature.php +5 -2
- package/project/.sdk/tm/php/feature/ProxyFeature.php +20 -1
- package/project/.sdk/tm/php/feature/SecretsFeature.php +18 -0
- package/project/.sdk/tm/php/feature/TelemetryFeature.php +4 -2
- package/project/.sdk/tm/php/test/FeatureTest.php +2 -2
- package/project/.sdk/tm/php/utility/Clean.php +438 -2
- package/project/.sdk/tm/php/utility/Done.php +14 -7
- package/project/.sdk/tm/php/utility/MakeError.php +9 -7
- package/project/.sdk/tm/php/utility/MakeOptions.php +62 -38
- package/project/.sdk/tm/php/utility/Register.php +2 -0
- package/project/.sdk/tm/py/pkg/core/context.py +17 -0
- package/project/.sdk/tm/py/pkg/core/error.py +42 -1
- package/project/.sdk/tm/py/pkg/core/utility_type.py +4 -0
- package/project/.sdk/tm/py/pkg/feature/audit_feature.py +2 -2
- package/project/.sdk/tm/py/pkg/feature/cost_feature.py +2 -2
- package/project/.sdk/tm/py/pkg/feature/debug_feature.py +17 -12
- package/project/.sdk/tm/py/pkg/feature/log_feature.py +2 -1
- package/project/.sdk/tm/py/pkg/feature/proxy_feature.py +18 -1
- package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +12 -0
- package/project/.sdk/tm/py/pkg/feature/telemetry_feature.py +4 -2
- package/project/.sdk/tm/py/pkg/utility/clean.py +311 -1
- package/project/.sdk/tm/py/pkg/utility/done.py +18 -5
- package/project/.sdk/tm/py/pkg/utility/make_error.py +9 -6
- package/project/.sdk/tm/py/pkg/utility/make_options.py +64 -25
- package/project/.sdk/tm/py/pkg/utility/make_response.py +19 -13
- package/project/.sdk/tm/py/pkg/utility/register.py +4 -2
- package/project/.sdk/tm/py/test/feature_harness.py +4 -0
- package/project/.sdk/tm/py/test/test_feature.py +2 -2
- package/project/.sdk/tm/py/test/test_primary_utility.py +1 -0
- package/project/.sdk/tm/rb/core/context.rb +28 -0
- package/project/.sdk/tm/rb/core/error.rb +30 -0
- package/project/.sdk/tm/rb/core/utility_type.rb +1 -1
- package/project/.sdk/tm/rb/feature/audit_feature.rb +2 -2
- package/project/.sdk/tm/rb/feature/cost_feature.rb +2 -2
- package/project/.sdk/tm/rb/feature/debug_feature.rb +15 -12
- package/project/.sdk/tm/rb/feature/log_feature.rb +3 -1
- package/project/.sdk/tm/rb/feature/proxy_feature.rb +25 -1
- package/project/.sdk/tm/rb/feature/secrets_feature.rb +17 -0
- package/project/.sdk/tm/rb/feature/telemetry_feature.rb +4 -2
- package/project/.sdk/tm/rb/test/feature_test.rb +4 -2
- package/project/.sdk/tm/rb/utility/clean.rb +312 -1
- package/project/.sdk/tm/rb/utility/done.rb +15 -5
- package/project/.sdk/tm/rb/utility/make_error.rb +13 -4
- package/project/.sdk/tm/rb/utility/make_options.rb +31 -12
- package/project/.sdk/tm/rb/utility/register.rb +2 -0
- package/project/.sdk/tm/rust/core/context.rs +55 -0
- package/project/.sdk/tm/rust/core/utility_type.rs +17 -0
- package/project/.sdk/tm/rust/feature/audit.rs +2 -0
- package/project/.sdk/tm/rust/feature/cost.rs +3 -2
- package/project/.sdk/tm/rust/feature/debug.rs +16 -16
- package/project/.sdk/tm/rust/feature/log.rs +42 -7
- package/project/.sdk/tm/rust/feature/proxy.rs +48 -2
- package/project/.sdk/tm/rust/feature/secrets.rs +12 -0
- package/project/.sdk/tm/rust/feature/telemetry.rs +2 -0
- package/project/.sdk/tm/rust/tests/feature_test.rs +2 -2
- package/project/.sdk/tm/rust/utility/clean.rs +446 -5
- package/project/.sdk/tm/rust/utility/done.rs +22 -12
- package/project/.sdk/tm/rust/utility/make_error.rs +4 -1
- package/project/.sdk/tm/rust/utility/make_options.rs +73 -19
- package/project/.sdk/tm/scala/Makefile +3 -1
- package/project/.sdk/tm/scala/core/Context.scala +16 -0
- package/project/.sdk/tm/scala/core/SdkClient.scala +14 -4
- package/project/.sdk/tm/scala/core/SdkError.scala +28 -0
- package/project/.sdk/tm/scala/core/Types.scala +3 -0
- package/project/.sdk/tm/scala/core/Utility.scala +2 -0
- package/project/.sdk/tm/scala/feature/AuditFeature.scala +16 -10
- package/project/.sdk/tm/scala/feature/CostFeature.scala +10 -5
- package/project/.sdk/tm/scala/feature/DebugFeature.scala +24 -21
- package/project/.sdk/tm/scala/feature/LogFeature.scala +9 -4
- package/project/.sdk/tm/scala/feature/ProxyFeature.scala +23 -2
- package/project/.sdk/tm/scala/feature/SecretsFeature.scala +14 -0
- package/project/.sdk/tm/scala/feature/TelemetryFeature.scala +9 -2
- package/project/.sdk/tm/scala/sdktest/SdkTestMain.scala +2 -2
- package/project/.sdk/tm/scala/utility/Make.scala +63 -20
- package/project/.sdk/tm/scala/utility/Misc.scala +358 -5
- package/project/.sdk/tm/scala/utility/Register.scala +1 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Context.swift +29 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Utility.swift +2 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/AuditFeature.swift +10 -9
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/CostFeature.swift +7 -5
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/DebugFeature.swift +19 -15
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/FeatureOptions.swift +16 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/LogFeature.swift +4 -1
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/ProxyFeature.swift +20 -5
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/SecretsFeature.swift +13 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/TelemetryFeature.swift +4 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeError.swift +15 -5
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +58 -19
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Register.swift +1 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/ResultUtil.swift +391 -4
- package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/FeatureTest.swift +2 -2
- package/project/.sdk/tm/ts/src/Context.ts +5 -1
- package/project/.sdk/tm/ts/src/feature/audit/AuditFeature.ts +2 -2
- package/project/.sdk/tm/ts/src/feature/cost/CostFeature.ts +2 -2
- package/project/.sdk/tm/ts/src/feature/debug/DebugFeature.ts +13 -7
- package/project/.sdk/tm/ts/src/feature/log/LogFeature.ts +9 -5
- package/project/.sdk/tm/ts/src/feature/proxy/ProxyFeature.ts +19 -1
- package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +12 -0
- package/project/.sdk/tm/ts/src/feature/telemetry/TelemetryFeature.ts +4 -2
- package/project/.sdk/tm/ts/src/utility/CleanUtility.ts +287 -9
- package/project/.sdk/tm/ts/src/utility/DoneUtility.ts +18 -5
- package/project/.sdk/tm/ts/src/utility/MakeErrorUtility.ts +18 -8
- package/project/.sdk/tm/ts/src/utility/MakeOptionsUtility.ts +38 -16
- package/project/.sdk/tm/ts/src/utility/Utility.ts +4 -2
- package/project/.sdk/tm/ts/test/feature/harness.ts +11 -1
- package/project/.sdk/tm/ts/test/feature.test.ts +9 -2
- package/project/.sdk/tm/zig/core/context.zig +34 -0
- package/project/.sdk/tm/zig/core/error.zig +22 -1
- package/project/.sdk/tm/zig/core/utility.zig +403 -39
- package/project/.sdk/tm/zig/feature/audit.zig +4 -2
- package/project/.sdk/tm/zig/feature/cost.zig +3 -2
- package/project/.sdk/tm/zig/feature/debug.zig +20 -25
- package/project/.sdk/tm/zig/feature/log.zig +3 -1
- package/project/.sdk/tm/zig/feature/proxy.zig +47 -6
- package/project/.sdk/tm/zig/feature/secrets.zig +7 -0
- package/project/.sdk/tm/zig/feature/telemetry.zig +4 -2
- package/project/.sdk/tm/zig/test/feature_test.zig +2 -2
- package/project/sdkgen-package.json +1 -1
- package/src/action/copies.ts +219 -0
- package/src/action/doctor.ts +247 -21
- package/src/action/edition.ts +10 -2
- package/src/action/feature.ts +11 -2
- package/src/action/package.ts +31 -10
- package/src/action/remove.ts +4 -0
- package/src/action/resolve.ts +16 -3
- package/src/action/target.ts +10 -2
- package/src/helpers/naming.ts +1 -1
- package/src/sdkgen.ts +45 -5
|
@@ -8,6 +8,7 @@ import { cmp, each, Folder, File, Content, entityCollection } from '@voxgig/sdkg
|
|
|
8
8
|
|
|
9
9
|
import { TestEntity } from './TestEntity_c'
|
|
10
10
|
import { TestDirect } from './TestDirect_c'
|
|
11
|
+
import { TestClean } from './TestClean_c'
|
|
11
12
|
import { ReadmeExamplesTest } from './ReadmeExamplesTest_c'
|
|
12
13
|
|
|
13
14
|
|
|
@@ -42,6 +43,8 @@ int main(void) {
|
|
|
42
43
|
TestDirect({ target, entity })
|
|
43
44
|
})
|
|
44
45
|
|
|
46
|
+
TestClean({ target })
|
|
47
|
+
|
|
45
48
|
// Validate the documented C examples in the READMEs are well-formed.
|
|
46
49
|
ReadmeExamplesTest({ target })
|
|
47
50
|
})
|
|
@@ -116,6 +116,15 @@ static voxgig_value* entyvar_run_op(entyvar_entity* self, Context* ctx,
|
|
|
116
116
|
return done_util(ctx, err);
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
// A step's error does not pass through make_error in stream, so it and the
|
|
120
|
+
// explain record are cleaned on the way out.
|
|
121
|
+
static voxgig_value* entyvar_stream_fail(Context* ctx, PNError* pe, PNError** err) {
|
|
122
|
+
clean_explain_util(ctx);
|
|
123
|
+
clean_error_util(ctx, pe);
|
|
124
|
+
*err = pe;
|
|
125
|
+
return NULL;
|
|
126
|
+
}
|
|
127
|
+
|
|
119
128
|
// Streaming operation. Runs `action` through the full pipeline and returns a
|
|
120
129
|
// List of the result items, so the `streaming` feature's incremental output
|
|
121
130
|
// is reachable from a generated entity (a normal op call materialises the
|
|
@@ -162,27 +171,27 @@ voxgig_value* entyvar_stream(Entity* e, const char* action, voxgig_value* args,
|
|
|
162
171
|
|
|
163
172
|
feature_hook_util(ctx, "PrePoint");
|
|
164
173
|
voxgig_value* point = make_point_util(ctx, &pe);
|
|
165
|
-
if (pe)
|
|
174
|
+
if (pe) return entyvar_stream_fail(ctx, pe, err);
|
|
166
175
|
ctx_out_set_point_val(ctx, point);
|
|
167
176
|
|
|
168
177
|
feature_hook_util(ctx, "PreSpec");
|
|
169
178
|
Spec* spec = make_spec_util(ctx, &pe);
|
|
170
|
-
if (pe)
|
|
179
|
+
if (pe) return entyvar_stream_fail(ctx, pe, err);
|
|
171
180
|
ctx->out_spec = spec;
|
|
172
181
|
|
|
173
182
|
feature_hook_util(ctx, "PreRequest");
|
|
174
183
|
Response* resp = make_request_util(ctx, &pe);
|
|
175
|
-
if (pe)
|
|
184
|
+
if (pe) return entyvar_stream_fail(ctx, pe, err);
|
|
176
185
|
ctx->out_request = resp;
|
|
177
186
|
|
|
178
187
|
feature_hook_util(ctx, "PreResponse");
|
|
179
188
|
Response* resp2 = make_response_util(ctx, &pe);
|
|
180
|
-
if (pe)
|
|
189
|
+
if (pe) return entyvar_stream_fail(ctx, pe, err);
|
|
181
190
|
ctx->out_response = resp2;
|
|
182
191
|
|
|
183
192
|
feature_hook_util(ctx, "PreResult");
|
|
184
193
|
SdkResult* result = make_result_util(ctx, &pe);
|
|
185
|
-
if (pe)
|
|
194
|
+
if (pe) return entyvar_stream_fail(ctx, pe, err);
|
|
186
195
|
ctx->out_result = result;
|
|
187
196
|
|
|
188
197
|
feature_hook_util(ctx, "PreDone");
|
|
@@ -191,6 +200,8 @@ voxgig_value* entyvar_stream(Entity* e, const char* action, voxgig_value* args,
|
|
|
191
200
|
// back to the materialised items so `stream` always yields.
|
|
192
201
|
SdkResult* res = ctx->result;
|
|
193
202
|
if (res && res->stream) {
|
|
203
|
+
// done() does not run on this path, so its record is cleaned here.
|
|
204
|
+
clean_explain_util(ctx);
|
|
194
205
|
return res->stream(res->stream_ud);
|
|
195
206
|
}
|
|
196
207
|
|
|
@@ -188,7 +188,7 @@ static voxgig_value* sdk_raw_request(
|
|
|
188
188
|
PNError* ferr = NULL;
|
|
189
189
|
voxgig_value* fetched = utility_fetch(utility, ctx, url, fetchdef, &ferr);
|
|
190
190
|
if (ferr) {
|
|
191
|
-
return err_map(ferr->msg);
|
|
191
|
+
return err_map(clean_str(ctx, ferr->msg));
|
|
192
192
|
}
|
|
193
193
|
|
|
194
194
|
if (v_is_noval(fetched) || v_is_null(fetched)) {
|
|
@@ -121,6 +121,9 @@ function basicBlock(): string {
|
|
|
121
121
|
(let [auth-prefix (or (vs/getpath options "auth.prefix") "")
|
|
122
122
|
b64 (.encodeToString (java.util.Base64/getEncoder)
|
|
123
123
|
(.getBytes ^String (str apikey ":" (if (missing? secret) "" secret)) "UTF-8"))]
|
|
124
|
+
;; The joined, encoded pair is a wire form neither
|
|
125
|
+
;; credential's own registration covers.
|
|
126
|
+
(ucall ctx :clean-add b64)
|
|
124
127
|
(.put ^java.util.Map headers HEADER-AUTH
|
|
125
128
|
(if (= auth-prefix "") b64 (str auth-prefix " " b64))))))
|
|
126
129
|
${headerPlace(16)})`
|
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cmp,
|
|
3
|
+
each,
|
|
4
|
+
File,
|
|
5
|
+
Content,
|
|
6
|
+
isAuthSuppressed,
|
|
7
|
+
isHttpBasicAuth,
|
|
8
|
+
resolveAuthIn,
|
|
9
|
+
resolveAuthName,
|
|
10
|
+
} from '@voxgig/sdkgen'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
// The canary sweep, the clojure port of TestClean_ts.ts: see that component.
|
|
14
|
+
const TestClean = cmp(function TestClean(props: any) {
|
|
15
|
+
const { model } = props.ctx$
|
|
16
|
+
const { target, entity } = props
|
|
17
|
+
|
|
18
|
+
const auth = {
|
|
19
|
+
suppressed: isAuthSuppressed(model),
|
|
20
|
+
where: resolveAuthIn(model),
|
|
21
|
+
name: 'header' === resolveAuthIn(model)
|
|
22
|
+
? resolveAuthName(model).toLowerCase() : resolveAuthName(model),
|
|
23
|
+
basic: isHttpBasicAuth(model),
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
File({ name: 'clean.' + target.ext }, () => Content(render(model, entity, auth)))
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
const OP_ORDER: Record<string, number> = { list: 0, load: 1 }
|
|
31
|
+
const OPS = ['list', 'load', 'create', 'update', 'remove']
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
// The path parameters an operation's points declare, as the runtime config
|
|
35
|
+
// carries them under points[].args.params.
|
|
36
|
+
function pointParams(opdef: any): string[] {
|
|
37
|
+
const names: string[] = []
|
|
38
|
+
for (const point of each(opdef?.points || [])) {
|
|
39
|
+
if (false === point?.a) continue
|
|
40
|
+
for (const arg of each(point?.g?.params || [])) {
|
|
41
|
+
if (false !== arg?.a && 'string' === typeof arg?.n && !names.includes(arg.n)) {
|
|
42
|
+
names.push(arg.n)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return names
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
// The operations to try, list and load first: a required path parameter is
|
|
51
|
+
// what usually stops a candidate, and the read ops need none.
|
|
52
|
+
function candidates(entity: any[]): string {
|
|
53
|
+
const rows: { rank: number, text: string }[] = []
|
|
54
|
+
each(entity, (e: any) => {
|
|
55
|
+
for (const op of Object.keys(e.op || {})) {
|
|
56
|
+
if (!OPS.includes(op)) continue
|
|
57
|
+
rows.push({
|
|
58
|
+
rank: OP_ORDER[op] ?? 2,
|
|
59
|
+
text: ` {:name "${e.name}.${op}"
|
|
60
|
+
:accessor (fn [sdk] (api/${e.name} sdk nil))
|
|
61
|
+
:params [${pointParams(e.op[op]).map(cljstr).join(' ')}]
|
|
62
|
+
:op (fn [ent match ctrl] (e-${e.name}/${op} ent (args match) ctrl))
|
|
63
|
+
:stream (fn [ent match callopts] (e-${e.name}/stream ent ${cljstr(op)} (vs/jm "reqmatch" (args match)) callopts))}`,
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
rows.sort((a, b) => a.rank - b.rank)
|
|
68
|
+
return rows.map((r) => r.text).join('\n')
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
function render(model: any, entity: any[], auth: {
|
|
73
|
+
suppressed: boolean, where: string, name: string, basic: boolean
|
|
74
|
+
}): string {
|
|
75
|
+
let requires = ''
|
|
76
|
+
each(entity, (e: any) => {
|
|
77
|
+
requires += `\n [sdk.entity.${e.name} :as e-${e.name}]`
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
return `;; ${model.const.Name} SDK canary sweep (generated by @voxgig/sdkgen).
|
|
81
|
+
;;
|
|
82
|
+
;; Every credential slot holds a distinctive value, every diagnostic feature
|
|
83
|
+
;; this SDK ships is switched on with a capturing sink, a real operation runs
|
|
84
|
+
;; through every outcome, and every string that leaves the SDK is searched
|
|
85
|
+
;; for the canaries and their encoded forms. It also proves its own
|
|
86
|
+
;; sensitivity: with clean switched off the canary MUST show.
|
|
87
|
+
(ns sdk.test.clean
|
|
88
|
+
(:require [sdk.api :as api]
|
|
89
|
+
[sdk.core :as core]
|
|
90
|
+
[sdk.test.feature :as feature]
|
|
91
|
+
[sdk.testutil :as t]
|
|
92
|
+
[voxgig.struct :as vs]
|
|
93
|
+
[clojure.string :as str]${requires}))
|
|
94
|
+
|
|
95
|
+
;; Generated: the credential's wire placement is fixed when the SDK is built.
|
|
96
|
+
(def AUTH {:suppressed ${auth.suppressed} :where ${cljstr(auth.where)}
|
|
97
|
+
:name ${cljstr(auth.name)} :basic ${auth.basic}})
|
|
98
|
+
|
|
99
|
+
(def CANARY {:apikey "CANARY-APIKEY-k9x2m7q4p1"
|
|
100
|
+
:secret "CANARY-SECRET-w3e8r5t2y6"
|
|
101
|
+
:header "CANARY-HEADER-z1x4c7v0b3"
|
|
102
|
+
:value "CANARY-VALUE-n5m8b2v9c4"
|
|
103
|
+
:config "CANARY-CONFIG-h6j3k8l2m5"})
|
|
104
|
+
|
|
105
|
+
(def MASK "[redacted]")
|
|
106
|
+
|
|
107
|
+
(defn- b64 [^String s]
|
|
108
|
+
(.encodeToString (java.util.Base64/getEncoder) (.getBytes s "UTF-8")))
|
|
109
|
+
|
|
110
|
+
;; Every form a canary can travel in.
|
|
111
|
+
(def FORMS
|
|
112
|
+
(vec (concat (mapcat (fn [v] [v (b64 v) (vs/escurl v)]) (vals CANARY))
|
|
113
|
+
[(b64 (str (:apikey CANARY) ":" (:secret CANARY)))])))
|
|
114
|
+
|
|
115
|
+
(defn- leaks [^String text] (filterv (fn [^String f] (.contains text f)) FORMS))
|
|
116
|
+
|
|
117
|
+
;; Header maps keep the caller's spelling; the assertion should not care.
|
|
118
|
+
(defn- header [m name]
|
|
119
|
+
(when (instance? java.util.Map m)
|
|
120
|
+
(some (fn [k] (when (= (str/lower-case (str k)) (str/lower-case (str name)))
|
|
121
|
+
(.get ^java.util.Map m k)))
|
|
122
|
+
(vec (.keySet ^java.util.Map m)))))
|
|
123
|
+
|
|
124
|
+
;; Every default print and serialisation of a value, as a sink each.
|
|
125
|
+
(defn- forms [name val]
|
|
126
|
+
(let [out (atom [])
|
|
127
|
+
push (fn [kind f]
|
|
128
|
+
(try (swap! out conj {:name (str name ":" kind) :text (str (f))})
|
|
129
|
+
(catch Throwable _ nil)))]
|
|
130
|
+
(push "pr" #(pr-str val))
|
|
131
|
+
(push "str" #(str val))
|
|
132
|
+
(push "json" #(vs/jsonify val))
|
|
133
|
+
(when (instance? Throwable val)
|
|
134
|
+
(push "message" #(ex-message val))
|
|
135
|
+
(push "data" #(pr-str (ex-data val)))
|
|
136
|
+
(push "map" #(pr-str (Throwable->map val)))
|
|
137
|
+
(push "sdk-pr" #(pr-str (core/ex->sdk val)))
|
|
138
|
+
(push "sdk-json" #(vs/jsonify (core/err->data (core/ex->sdk val))))
|
|
139
|
+
(push "stack" #(let [sw (java.io.StringWriter.)]
|
|
140
|
+
(.printStackTrace ^Throwable val (java.io.PrintWriter. sw))
|
|
141
|
+
(str sw))))
|
|
142
|
+
@out))
|
|
143
|
+
|
|
144
|
+
;; Captures the serialised context from inside the pipeline: what a hook
|
|
145
|
+
;; author would hand to a logger.
|
|
146
|
+
(defn- capture-feature [sinks]
|
|
147
|
+
(let [cap (fn [hook] (fn [ctx] (swap! sinks into (forms (str "ctx@" hook) ctx))))]
|
|
148
|
+
(atom {:name "capture" :active true :version "0.0.1" :_options nil
|
|
149
|
+
"init" (fn [_ctx _opts] nil)
|
|
150
|
+
"PreRequest" (cap "PreRequest")
|
|
151
|
+
"PreResponse" (cap "PreResponse")
|
|
152
|
+
;; The SDK's own error as a hook reads it, which an observability
|
|
153
|
+
;; feature logs.
|
|
154
|
+
"PreUnexpected" (fn [ctx]
|
|
155
|
+
((cap "PreUnexpected") ctx)
|
|
156
|
+
(let [err (core/oget (core/oget ctx :ctrl) :err)]
|
|
157
|
+
(when (core/sdk-error? err)
|
|
158
|
+
(swap! sinks into (forms "ctrl.err@PreUnexpected" err)))))})))
|
|
159
|
+
|
|
160
|
+
(defn- response [status data headers]
|
|
161
|
+
(let [h (vs/jm "content-type" "application/json")]
|
|
162
|
+
(doseq [[k v] headers] (.put ^java.util.Map h k v))
|
|
163
|
+
(vs/jm "status" status "statusText" (if (< status 400) "OK" "ERR")
|
|
164
|
+
"headers" h "body" (vs/jsonify data) "json" (fn [] data))))
|
|
165
|
+
|
|
166
|
+
(def SCENARIOS
|
|
167
|
+
[{:name "ok"
|
|
168
|
+
:respond (fn [_url _fd] [(response 200 (vs/jm "id" "i1" "name" "n1")
|
|
169
|
+
{"x-session-token" "RESP-TOKEN-a1b2c3d4e5"}) nil])}
|
|
170
|
+
{:name "notfound"
|
|
171
|
+
:respond (fn [_url _fd] [(response 404 (vs/jm "error" "no such record") {}) nil])}
|
|
172
|
+
{:name "server"
|
|
173
|
+
:respond (fn [_url _fd] [(response 500 (vs/jm "error" "boom") {}) nil])}
|
|
174
|
+
{:name "transport"
|
|
175
|
+
:respond (fn [url _fd] [nil (core/make-error-obj "transport"
|
|
176
|
+
(str "socket hang up (URL was: \\"" url "\\")"))])}
|
|
177
|
+
;; The SDK's own error, its code quoting a registered value.
|
|
178
|
+
{:name "coded"
|
|
179
|
+
:respond (fn [_url _fd] [nil (core/make-error-obj (str "denied_" (:apikey CANARY)) "coded failure")])}
|
|
180
|
+
{:name "notjson"
|
|
181
|
+
:respond (fn [_url _fd] [(vs/jm "status" 200 "statusText" "OK" "headers" (vs/jm)
|
|
182
|
+
"body" "<html>"
|
|
183
|
+
"json" (fn [] (throw (RuntimeException. "Unexpected token < in JSON")))) nil])}])
|
|
184
|
+
|
|
185
|
+
(defn- make-sdk [scenario sinks cleanopts & extra]
|
|
186
|
+
(let [capture (fn [name] (fn [rec] (swap! sinks into (forms name rec))))
|
|
187
|
+
feature (vs/jm)
|
|
188
|
+
on (fn [name & kvs] (when (feature/feature-present? name)
|
|
189
|
+
(.put ^java.util.Map feature name (apply vs/jm "active" true kvs))))]
|
|
190
|
+
(on "log" "logger" (capture "log"))
|
|
191
|
+
(on "debug" "onEntry" (capture "debug"))
|
|
192
|
+
(on "audit" "sink" (capture "audit"))
|
|
193
|
+
(on "telemetry" "exporter" (capture "telemetry"))
|
|
194
|
+
(on "cost" "sink" (capture "cost"))
|
|
195
|
+
(on "metrics")
|
|
196
|
+
(on "clienttrack")
|
|
197
|
+
(let [clean (vs/jm "values" (:value CANARY))]
|
|
198
|
+
(doseq [[k v] (or cleanopts {})] (.put ^java.util.Map clean k v))
|
|
199
|
+
(api/make-sdk (vs/jm "apikey" (:apikey CANARY) "secret" (:secret CANARY)
|
|
200
|
+
"headers" (vs/jm "X-Custom-Token" (:header CANARY))
|
|
201
|
+
"clean" clean
|
|
202
|
+
"feature" feature
|
|
203
|
+
"extend" (apply vs/jt (capture-feature sinks) extra)
|
|
204
|
+
"utility" (vs/jm "fetcher" (fn [_fctx url fd] ((:respond scenario) url fd))))))))
|
|
205
|
+
|
|
206
|
+
;; A fresh struct map of the match, since an operation may keep what it is
|
|
207
|
+
;; given.
|
|
208
|
+
(defn- args [match]
|
|
209
|
+
(let [m (vs/jm)]
|
|
210
|
+
(doseq [[k v] match] (.put ^java.util.Map m k v))
|
|
211
|
+
m))
|
|
212
|
+
|
|
213
|
+
;; The operations this SDK generated, read ops first.
|
|
214
|
+
(def CANDIDATES
|
|
215
|
+
[
|
|
216
|
+
${candidates(entity)}
|
|
217
|
+
])
|
|
218
|
+
|
|
219
|
+
;; The first operation that completes against a plain 200: with no
|
|
220
|
+
;; arguments, else with every path parameter its points declare filled in.
|
|
221
|
+
(defn- usable-op []
|
|
222
|
+
(let [plain (api/make-sdk (vs/jm "apikey" (:apikey CANARY)
|
|
223
|
+
"utility" (vs/jm "fetcher" (fn [_ _ _] [(response 200 (vs/jm "id" "i1") {}) nil]))))]
|
|
224
|
+
(some (fn [c]
|
|
225
|
+
(some (fn [match]
|
|
226
|
+
(try ((:op c) ((:accessor c) plain) match (vs/jm))
|
|
227
|
+
(assoc c :match match)
|
|
228
|
+
(catch Throwable _ nil)))
|
|
229
|
+
[{} (into {} (map (fn [p] [p "p1"]) (:params c)))]))
|
|
230
|
+
CANDIDATES)))
|
|
231
|
+
|
|
232
|
+
;; A feature that throws from inside the pipeline, quoting the request it
|
|
233
|
+
;; saw: an error make-error never handled.
|
|
234
|
+
(defn- hook-saw [ctx]
|
|
235
|
+
(let [sp (core/oget ctx :spec)]
|
|
236
|
+
(RuntimeException. (str "hook saw " (pr-str (if (instance? clojure.lang.IDeref sp) @sp sp))))))
|
|
237
|
+
|
|
238
|
+
(defn- throw-feature [unexpected]
|
|
239
|
+
(atom {:name "throwhook" :active true :version "0.0.1" :_options nil
|
|
240
|
+
"init" (fn [_ctx _opts] nil)
|
|
241
|
+
"PreResponse" (fn [ctx] (throw (hook-saw ctx)))
|
|
242
|
+
;; Fired from the operation's catch, before its cleaning.
|
|
243
|
+
"PreUnexpected" (fn [ctx] (when unexpected (throw (hook-saw ctx))))}))
|
|
244
|
+
|
|
245
|
+
;; A stream that fails while it is realised, quoting a credential.
|
|
246
|
+
(defn- stream-throw-feature []
|
|
247
|
+
(atom {:name "streamthrow" :active true :version "0.0.1" :_options nil
|
|
248
|
+
"init" (fn [_ctx _opts] nil)
|
|
249
|
+
"PreDone" (fn [ctx]
|
|
250
|
+
(core/oset! (core/oget ctx :result) :stream
|
|
251
|
+
(fn [] (map (fn [_] (throw (RuntimeException. (str "stream saw " (:apikey CANARY)))))
|
|
252
|
+
[1]))))}))
|
|
253
|
+
|
|
254
|
+
;; A stream that succeeds, yielding the result's items.
|
|
255
|
+
(defn- stream-ok-feature []
|
|
256
|
+
(atom {:name "streamok" :active true :version "0.0.1" :_options nil
|
|
257
|
+
"init" (fn [_ctx _opts] nil)
|
|
258
|
+
"PreDone" (fn [ctx]
|
|
259
|
+
(let [result (core/oget ctx :result)
|
|
260
|
+
rd (core/oget result :resdata)
|
|
261
|
+
items (cond (vs/islist rd) (vec rd) (nil? rd) [] :else [rd])]
|
|
262
|
+
(core/oset! result :stream (fn [] items))))}))
|
|
263
|
+
|
|
264
|
+
;; A feature that throws the SDK's own error, its code quoting a registered
|
|
265
|
+
;; value: an SDK error make-error never handled.
|
|
266
|
+
(defn- coded-throw-feature []
|
|
267
|
+
(atom {:name "codedhook" :active true :version "0.0.1" :_options nil
|
|
268
|
+
"init" (fn [_ctx _opts] nil)
|
|
269
|
+
"PreResponse" (fn [_ctx]
|
|
270
|
+
(core/sdk-throw (core/make-error-obj (str "denied_" (:apikey CANARY))
|
|
271
|
+
"coded hook failure")))}))
|
|
272
|
+
|
|
273
|
+
(defn- drive [sdk target ctrl sinks]
|
|
274
|
+
(let [ent ((:accessor target) sdk)
|
|
275
|
+
;; A caller may keep the record it passed rather than read ctrl.explain.
|
|
276
|
+
held (vs/getprop ctrl "explain")
|
|
277
|
+
[out err] (try [((:op target) ent (:match target) ctrl) nil] (catch Throwable e [nil e]))
|
|
278
|
+
explain (vs/getprop ctrl "explain")]
|
|
279
|
+
(when err (swap! sinks into (forms "error" err)))
|
|
280
|
+
(when (some? out) (swap! sinks into (forms "result" out)))
|
|
281
|
+
(when (some? explain) (swap! sinks into (forms "explain" explain)))
|
|
282
|
+
(when (and (some? held) (not (identical? held explain))) (swap! sinks into (forms "explain:held" held)))
|
|
283
|
+
err))
|
|
284
|
+
|
|
285
|
+
(def ^:private NO-TARGET "no operation of this SDK completes against a plain 200; nothing to sweep")
|
|
286
|
+
|
|
287
|
+
(defn run [rec]
|
|
288
|
+
(t/run-check rec "clean-no-credential-leaves-the-sdk"
|
|
289
|
+
(fn []
|
|
290
|
+
(if-let [target (usable-op)]
|
|
291
|
+
(let [sinks (atom []) errors (atom {}) explains (atom {}) featured (atom {})]
|
|
292
|
+
(doseq [scenario SCENARIOS
|
|
293
|
+
variant [{:name "throw" :ctrl (fn [] (vs/jm))}
|
|
294
|
+
{:name "explain" :ctrl (fn [] (vs/jm "explain" (vs/jm)))}
|
|
295
|
+
{:name "nothrow" :ctrl (fn [] (vs/jm "throw" false "explain" (vs/jm)))}]]
|
|
296
|
+
(let [sdk (make-sdk scenario sinks nil)
|
|
297
|
+
ctrl ((:ctrl variant))
|
|
298
|
+
err (drive sdk target ctrl sinks)
|
|
299
|
+
key (str (:name scenario) "/" (:name variant))]
|
|
300
|
+
(when err (swap! errors assoc key err))
|
|
301
|
+
(when-let [ex (vs/getprop ctrl "explain")] (swap! explains assoc key ex))
|
|
302
|
+
(swap! sinks into (forms "sdk" sdk))
|
|
303
|
+
(swap! sinks conj {:name "sdk:slots" :text (pr-str (into {} sdk))})))
|
|
304
|
+
;; A credential mistyped as a map is rejected by validation, whose
|
|
305
|
+
;; message quotes the value it rejected.
|
|
306
|
+
(let [rejected (try (api/make-sdk (vs/jm "apikey" (vs/jm "value" (:apikey CANARY))
|
|
307
|
+
"clean" (vs/jm "values" (:value CANARY))))
|
|
308
|
+
nil
|
|
309
|
+
(catch Throwable e e))]
|
|
310
|
+
(t/is-some rejected "a credential mistyped as a map should be rejected")
|
|
311
|
+
(swap! sinks into (forms "rejected" rejected)))
|
|
312
|
+
;; An error a feature hook throws, quoting the request, skips make-error.
|
|
313
|
+
(doseq [unexpected [false true]]
|
|
314
|
+
(let [hooked (make-sdk (first SCENARIOS) sinks nil (throw-feature unexpected))]
|
|
315
|
+
(t/is-some (drive hooked target (vs/jm "explain" (vs/jm)) sinks)
|
|
316
|
+
"the throwing hook should fail the operation")))
|
|
317
|
+
;; Streaming runs through the same cleaning path as the operation,
|
|
318
|
+
;; and the explain record the caller passed is cleaned however it ends.
|
|
319
|
+
(doseq [[name extra] [["stream" [(stream-throw-feature)]] ["stream-ok" [(stream-ok-feature)]]
|
|
320
|
+
["stream-plain" []]]]
|
|
321
|
+
(let [streamed (apply make-sdk (first SCENARIOS) sinks nil extra)
|
|
322
|
+
explain (vs/jm)
|
|
323
|
+
err (try (vec ((:stream target) ((:accessor target) streamed) (:match target)
|
|
324
|
+
(vs/jm "ctrl" (vs/jm "explain" explain))))
|
|
325
|
+
nil
|
|
326
|
+
(catch Throwable e e))]
|
|
327
|
+
(t/is-eq (some? err) (= "stream" name) (str name ": only the failing stream throws"))
|
|
328
|
+
(when err (swap! sinks into (forms name err)))
|
|
329
|
+
(t/is-true (pos? (.size ^java.util.Map explain)) (str name ": the explain record was not filled"))
|
|
330
|
+
(swap! sinks into (forms (str name ":explain") explain))))
|
|
331
|
+
(let [codedhook (make-sdk (first SCENARIOS) sinks nil (coded-throw-feature))
|
|
332
|
+
err (drive codedhook target (vs/jm) sinks)]
|
|
333
|
+
(t/is-some err "the coded hook should fail the operation")
|
|
334
|
+
(swap! errors assoc "codedhook" err))
|
|
335
|
+
;; direct() returns its error rather than throwing it.
|
|
336
|
+
(doseq [scenario [(nth SCENARIOS 3) (nth SCENARIOS 4)]]
|
|
337
|
+
(let [raw (api/direct (make-sdk scenario sinks nil) (vs/jm "path" "raw"))]
|
|
338
|
+
(t/is-eq (vs/getprop raw "ok") false (str (:name scenario) ": direct() fails"))
|
|
339
|
+
(swap! errors assoc (str "direct/" (:name scenario)) (vs/getprop raw "err"))
|
|
340
|
+
(swap! sinks into (forms "direct" (vs/getprop raw "err")))))
|
|
341
|
+
;; The generated config's own clean block is read beside the
|
|
342
|
+
;; caller's, and is not changed by it.
|
|
343
|
+
(let [config (vs/jm "options" (vs/jm "clean" (vs/jm "keys" "zzsens" "values" (:config CANARY))))
|
|
344
|
+
built (core/u-make-options
|
|
345
|
+
(atom {:config config :options (vs/jm "clean" (vs/jm "values" (:value CANARY)))}))
|
|
346
|
+
cfgctx (atom {:options built})
|
|
347
|
+
seeded (core/u-clean cfgctx (str "config " (:config CANARY) " caller " (:value CANARY)))]
|
|
348
|
+
(swap! sinks conj {:name "config-clean" :text (str seeded)})
|
|
349
|
+
(t/is-eq seeded (str "config " MASK " caller " MASK) "the config's clean values are registered")
|
|
350
|
+
(t/is-deep (core/u-clean cfgctx (vs/jm "my_zzsens" "x" "other" "y"))
|
|
351
|
+
(vs/jm "my_zzsens" MASK "other" "y") "the config's clean keys apply")
|
|
352
|
+
(t/is-deep (vs/getpath config "options.clean") (vs/jm "keys" "zzsens" "values" (:config CANARY))
|
|
353
|
+
"the config's clean block is unchanged"))
|
|
354
|
+
;; With no clean option at all, the schema defaults still apply.
|
|
355
|
+
(let [bare (api/make-sdk (vs/jm "apikey" (:apikey CANARY) "secret" (:secret CANARY)
|
|
356
|
+
"headers" (vs/jm "X-Custom-Token" (:header CANARY))
|
|
357
|
+
"utility" (vs/jm "fetcher" (fn [_fctx url fd]
|
|
358
|
+
((:respond (nth SCENARIOS 1)) url fd)))))]
|
|
359
|
+
(t/is-some (drive bare target (vs/jm "explain" (vs/jm)) sinks) "the 404 should fail without a clean option"))
|
|
360
|
+
;; A feature's name is not a field name: only the sensitive names
|
|
361
|
+
;; inside its settings register. An entity block, of entity settings
|
|
362
|
+
;; or seeded records keyed by entity name and id, is not read at all.
|
|
363
|
+
(let [record (vs/jm "zztoken" (vs/jm "ZZTOKEN01" (vs/jm "note" "PLAINRECORD-t5r3e1w9")))
|
|
364
|
+
sdk (api/make-sdk (vs/jm "apikey" (:apikey CANARY)
|
|
365
|
+
"feature" (vs/jm "zzsecrets" (vs/jm "active" false "kind" "PLAINSETTING-q8w2e4r6")
|
|
366
|
+
"zzfeat" (vs/jm "active" false "apitoken" "FEATTOKEN-z9y8x7w6")
|
|
367
|
+
"test" (vs/jm "active" false "entity" record))
|
|
368
|
+
"entity" (vs/jm "zztoken" (vs/jm "alias" (vs/jm "zzkey" "PLAINALIAS-m2n4b6v8")))))
|
|
369
|
+
root (core/client-root-ctx sdk)]
|
|
370
|
+
(reset! featured {:plain (core/u-clean root "kind PLAINSETTING-q8w2e4r6")
|
|
371
|
+
:token (core/u-clean root "token FEATTOKEN-z9y8x7w6")
|
|
372
|
+
:record (core/u-clean root "record PLAINRECORD-t5r3e1w9")
|
|
373
|
+
:alias (core/u-clean root "alias PLAINALIAS-m2n4b6v8")}))
|
|
374
|
+
(let [leaked (filterv (fn [s] (seq (leaks (:text s)))) @sinks)]
|
|
375
|
+
(println (str "clean: swept " (count @sinks) " surface(s), " (count leaked) " leak(s)"))
|
|
376
|
+
(t/is-eq (count leaked) 0
|
|
377
|
+
(str "credential leaked through: "
|
|
378
|
+
(str/join "; " (map (fn [s] (str (:name s) " [" (str/join ", " (leaks (:text s))) "]"))
|
|
379
|
+
leaked)))))
|
|
380
|
+
;; The positive half: the slot the credential travelled in is
|
|
381
|
+
;; masked, and an unregistered token in a response header is masked
|
|
382
|
+
;; by name.
|
|
383
|
+
(let [notfound (get @errors "notfound/throw")
|
|
384
|
+
sdkerr (core/ex->sdk notfound)]
|
|
385
|
+
(t/is-some notfound "the 404 scenario must throw")
|
|
386
|
+
(t/is-some sdkerr "the 404 error is an SDK error")
|
|
387
|
+
(t/is-eq (vs/getprop (:result sdkerr) "status") 404 "status 404")
|
|
388
|
+
(let [spec (:spec sdkerr)]
|
|
389
|
+
(when-not (:suppressed AUTH)
|
|
390
|
+
(cond
|
|
391
|
+
(= "query" (:where AUTH))
|
|
392
|
+
(t/is-eq (header (vs/getprop spec "query") (:name AUTH)) MASK "query credential masked")
|
|
393
|
+
(= "cookie" (:where AUTH))
|
|
394
|
+
(t/is-true (str/includes? (str (header (vs/getprop spec "headers") "cookie")) MASK)
|
|
395
|
+
(str "cookie: " (header (vs/getprop spec "headers") "cookie")))
|
|
396
|
+
:else
|
|
397
|
+
(t/is-true (str/ends-with? (str (header (vs/getprop spec "headers") (:name AUTH))) MASK)
|
|
398
|
+
(str (:name AUTH) ": " (header (vs/getprop spec "headers") (:name AUTH))))))
|
|
399
|
+
(t/is-eq (header (vs/getprop spec "headers") "x-custom-token") MASK "custom token header masked")))
|
|
400
|
+
(doseq [key ["coded/throw" "codedhook"]]
|
|
401
|
+
(t/is-eq (:code (core/ex->sdk (get @errors key))) (str "denied_" MASK)
|
|
402
|
+
(str key ": the error keeps its code, masked")))
|
|
403
|
+
(t/is-eq (:code (get @errors "direct/transport")) "transport" "direct() returns the fetcher's error")
|
|
404
|
+
(t/is-eq (:code (get @errors "direct/coded")) (str "denied_" MASK)
|
|
405
|
+
"direct() returns the fetcher's error, its code masked")
|
|
406
|
+
(t/is-eq (:plain @featured) "kind PLAINSETTING-q8w2e4r6" "a feature's name does not register its settings")
|
|
407
|
+
(t/is-eq (:token @featured) (str "token " MASK) "a sensitive setting inside a feature registers")
|
|
408
|
+
(t/is-eq (:record @featured) "record PLAINRECORD-t5r3e1w9" "a seeded record does not register")
|
|
409
|
+
(t/is-eq (:alias @featured) "alias PLAINALIAS-m2n4b6v8" "an entity setting does not register")
|
|
410
|
+
(let [explained (get @explains "ok/explain")
|
|
411
|
+
result (vs/getprop explained "result")]
|
|
412
|
+
(t/is-some result "the explain record should carry the result")
|
|
413
|
+
(t/is-eq (header (vs/getprop result "headers") "x-session-token") MASK "response token masked")))
|
|
414
|
+
(println (str "SKIP clean-no-credential-leaves-the-sdk: " NO-TARGET)))))
|
|
415
|
+
|
|
416
|
+
(t/run-check rec "clean-the-sweep-can-see-a-leak"
|
|
417
|
+
(fn []
|
|
418
|
+
(if-let [target (usable-op)]
|
|
419
|
+
(let [sinks (atom [])
|
|
420
|
+
sdk (make-sdk (nth SCENARIOS 1) sinks {"active" false})
|
|
421
|
+
err (drive sdk target (vs/jm) sinks)
|
|
422
|
+
;; Explaining a failure must not cost it its error.
|
|
423
|
+
explained (drive (make-sdk (nth SCENARIOS 1) (atom []) {"active" false})
|
|
424
|
+
target (vs/jm "explain" (vs/jm)) (atom []))]
|
|
425
|
+
(t/is-some err "the 404 scenario must throw")
|
|
426
|
+
(t/is-eq (ex-message explained) (ex-message err) "with clean off, explain lost the error")
|
|
427
|
+
(t/is-true (some (fn [s] (seq (leaks (:text s)))) @sinks)
|
|
428
|
+
"with clean off, nothing showed the canary: the sweep is blind")
|
|
429
|
+
(when-not (:suppressed AUTH)
|
|
430
|
+
(let [text (pr-str (:spec (core/ex->sdk err)))]
|
|
431
|
+
(t/is-true (or (str/includes? text (:apikey CANARY))
|
|
432
|
+
(str/includes? text (b64 (str (:apikey CANARY) ":" (:secret CANARY)))))
|
|
433
|
+
"the raw spec should carry the credential when clean is off"))))
|
|
434
|
+
(println (str "SKIP clean-the-sweep-can-see-a-leak: " NO-TARGET)))))
|
|
435
|
+
|
|
436
|
+
(t/run-check rec "clean-a-registered-value-used-as-a-property-name"
|
|
437
|
+
(fn []
|
|
438
|
+
(let [cfg (core/make-clean-config (vs/jm "keys" "key,secret,token"))
|
|
439
|
+
ctx (atom {:options (vs/jm "__derived__" (vs/jm "clean" cfg))})]
|
|
440
|
+
(core/u-clean-add ctx "ZZVAL-abc123")
|
|
441
|
+
(core/u-clean-add ctx "ZZVAL-xyz789")
|
|
442
|
+
(let [out (core/u-clean ctx (vs/jm "ZZVAL-abc123" 1 "ZZVAL-xyz789" 2 "plain" 3))]
|
|
443
|
+
(t/is-eq (vs/getprop out MASK) 1 "a registered name is masked")
|
|
444
|
+
(t/is-eq (vs/getprop out (str MASK "#1")) 2 "a colliding masked name is numbered")
|
|
445
|
+
(t/is-eq (vs/getprop out "plain") 3 "a plain name is kept")
|
|
446
|
+
(t/is-nil (vs/getprop out "ZZVAL-abc123") "the registered name is gone")))))
|
|
447
|
+
|
|
448
|
+
(t/run-check rec "clean-add-sensitive-registers-every-scalar-under-a-sensitive-name"
|
|
449
|
+
(fn []
|
|
450
|
+
(let [cfg (core/make-clean-config (vs/jm "keys" "key,secret,token"))
|
|
451
|
+
ctx (atom {:options (vs/jm "__derived__" (vs/jm "clean" cfg))})
|
|
452
|
+
values (vs/getprop cfg "values")]
|
|
453
|
+
(core/u-clean-add-sensitive ctx (vs/jm "apikey" (vs/jm "value" "NESTED-SECRET-1")
|
|
454
|
+
"headers" (vs/jm "X-Api-Token" (vs/jt "LISTED-SECRET-2"))
|
|
455
|
+
"secret" 123456789
|
|
456
|
+
"name" "not-a-secret"))
|
|
457
|
+
(t/is-true (.contains ^java.util.List values "NESTED-SECRET-1") "nested under apikey")
|
|
458
|
+
(t/is-true (.contains ^java.util.List values "LISTED-SECRET-2") "listed under a token header")
|
|
459
|
+
(t/is-true (.contains ^java.util.List values "123456789") "a number, as its text")
|
|
460
|
+
(t/is-false (.contains ^java.util.List values "not-a-secret") "an ordinary name"))))
|
|
461
|
+
nil)
|
|
462
|
+
`
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
function cljstr(s: string): string {
|
|
467
|
+
return '"' + String(s).replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"'
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
export {
|
|
472
|
+
TestClean
|
|
473
|
+
}
|
|
@@ -7,6 +7,7 @@ import { cmp, each, File, Content, Folder, entityCollection } from '@voxgig/sdkg
|
|
|
7
7
|
|
|
8
8
|
import { TestEntity } from './TestEntity_clojure'
|
|
9
9
|
import { TestDirect } from './TestDirect_clojure'
|
|
10
|
+
import { TestClean } from './TestClean_clojure'
|
|
10
11
|
import { ReadmeExamplesTest } from './ReadmeExamplesTest_clojure'
|
|
11
12
|
|
|
12
13
|
|
|
@@ -54,6 +55,11 @@ const Test = cmp(function Test(props: any) {
|
|
|
54
55
|
Content(` nil)
|
|
55
56
|
`)
|
|
56
57
|
})
|
|
58
|
+
|
|
59
|
+
// The canary sweep, required by test_runner.clj as sdk.test.clean.
|
|
60
|
+
Folder({ name: 'test' }, () => {
|
|
61
|
+
TestClean({ target, entity })
|
|
62
|
+
})
|
|
57
63
|
})
|
|
58
64
|
})
|
|
59
65
|
})
|
|
@@ -109,8 +109,15 @@
|
|
|
109
109
|
(post-done)
|
|
110
110
|
((core/uget ctx :done) ctx))))))))))))))))
|
|
111
111
|
(catch Throwable operr
|
|
112
|
-
|
|
113
|
-
(
|
|
112
|
+
;; What a hook throws here must not escape the cleaning below.
|
|
113
|
+
(let [err (try
|
|
114
|
+
; #PreUnexpected-Hook
|
|
115
|
+
operr
|
|
116
|
+
(catch Throwable hookerr hookerr))]
|
|
117
|
+
;; An error a hook threw, SDK-shaped or not, never passed through
|
|
118
|
+
;; make-error.
|
|
119
|
+
(core/clean-explain! ctx)
|
|
120
|
+
(throw (core/clean-throwable ctx err))))))
|
|
114
121
|
|
|
115
122
|
;; Streaming operation. Runs `action` (an op name, e.g. "list") through the
|
|
116
123
|
;; full pipeline and returns a LAZY SEQUENCE of result items, so the
|
|
@@ -152,12 +159,15 @@
|
|
|
152
159
|
(vs/islist item) (mapv unwrap (vec item))
|
|
153
160
|
:else item))
|
|
154
161
|
;; Inbound: prefer the streaming feature's iterator; else fall back
|
|
155
|
-
;; to the materialised items so stream always yields.
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
162
|
+
;; to the materialised items so stream always yields. Realised after
|
|
163
|
+
;; run-op has returned, so what the stream throws is cleaned here.
|
|
164
|
+
items (try
|
|
165
|
+
(mapv unwrap
|
|
166
|
+
(if (and result (fn? (core/oget result :stream)))
|
|
167
|
+
(vec ((core/oget result :stream)))
|
|
168
|
+
(let [rd (when result (core/oget result :resdata))]
|
|
169
|
+
(cond (vs/islist rd) (vec rd) (nil? rd) [] :else [rd]))))
|
|
170
|
+
(catch Throwable e (throw (core/clean-throwable ctx e))))]
|
|
161
171
|
;; A lazy sequence that checks `signal` between yields.
|
|
162
172
|
(letfn [(lz [xs] (lazy-seq
|
|
163
173
|
(when (and (seq xs) (not (signalled?)))
|
|
@@ -187,6 +187,9 @@ ${clear(spec.where, 6)}
|
|
|
187
187
|
std::string b64 = authBase64(
|
|
188
188
|
(apikey.is_string() ? apikey.as_string() : "") + ":" +
|
|
189
189
|
(!noSecret && secret.is_string() ? secret.as_string() : ""));
|
|
190
|
+
// The joined, encoded pair is a wire form neither credential's own
|
|
191
|
+
// registration covers.
|
|
192
|
+
ctx->utility->cleanAdd(ctx, Value(b64));
|
|
190
193
|
if (authPrefix.empty()) {
|
|
191
194
|
map_put(headers, CRED_NAME, Value(b64));
|
|
192
195
|
} else {
|