@voxgig/sdkgen 4.32.1 → 4.33.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/helpers/naming.js +1 -1
- package/dist/helpers/naming.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/helpers/naming.ts +1 -1
|
@@ -0,0 +1,608 @@
|
|
|
1
|
+
|
|
2
|
+
import {
|
|
3
|
+
Content,
|
|
4
|
+
File,
|
|
5
|
+
cmp,
|
|
6
|
+
isAuthSuppressed,
|
|
7
|
+
isHttpBasicAuth,
|
|
8
|
+
resolveAuthIn,
|
|
9
|
+
resolveAuthName,
|
|
10
|
+
} from '@voxgig/sdkgen'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
import type { Model } from '@voxgig/apidef'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
// The canary sweep (test/clean.test.ts in the ts reference): canaries in
|
|
17
|
+
// every credential slot, every diagnostic feature on with a capturing sink,
|
|
18
|
+
// a real operation through every outcome, every string that leaves searched
|
|
19
|
+
// for the canaries and their encoded forms, and the negative control. A
|
|
20
|
+
// scala-cli main of its own, named in the Makefile's test target.
|
|
21
|
+
const TestClean = cmp(function TestClean(props: any) {
|
|
22
|
+
const model: Model = props.ctx$.model
|
|
23
|
+
const target = props.target
|
|
24
|
+
const scalapackage: string = props.scalapackage
|
|
25
|
+
|
|
26
|
+
const SDK = model.const.Name + 'SDK'
|
|
27
|
+
|
|
28
|
+
const auth = {
|
|
29
|
+
suppressed: isAuthSuppressed(model),
|
|
30
|
+
where: resolveAuthIn(model),
|
|
31
|
+
name: 'header' === resolveAuthIn(model)
|
|
32
|
+
? resolveAuthName(model).toLowerCase() : resolveAuthName(model),
|
|
33
|
+
basic: isHttpBasicAuth(model),
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
File({ name: 'SdkCleanTestMain.' + target.ext }, () => Content(render(scalapackage, SDK, auth)))
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
type AuthSpec = { suppressed: boolean, where: string, name: string, basic: boolean }
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
function render(scalapackage: string, SDK: string, auth: AuthSpec): string {
|
|
44
|
+
return `// The canary sweep: every credential slot holds a distinctive value, every
|
|
45
|
+
// diagnostic feature this SDK ships is switched on with a capturing sink, a
|
|
46
|
+
// real operation runs through every outcome, and every string that leaves
|
|
47
|
+
// the SDK is searched for the canaries and their encoded forms. It also
|
|
48
|
+
// proves its own sensitivity: with clean switched off the canary MUST show.
|
|
49
|
+
// Run: scala-cli run . --main-class SdkCleanTestMain
|
|
50
|
+
|
|
51
|
+
import java.io.{PrintWriter, StringWriter}
|
|
52
|
+
import java.lang.reflect.{Method, Modifier}
|
|
53
|
+
import java.net.URLEncoder
|
|
54
|
+
import java.nio.charset.StandardCharsets
|
|
55
|
+
import java.util.{ArrayList, Base64, LinkedHashMap, List => JList, Map => JMap}
|
|
56
|
+
import java.util.function.{Consumer, Supplier}
|
|
57
|
+
import java.util.logging.{Handler, Level, LogRecord, Logger}
|
|
58
|
+
|
|
59
|
+
import ${scalapackage}.core.{Config, Context, Helpers, Result, SdkEntity, SdkError, Spec, ${SDK}}
|
|
60
|
+
import ${scalapackage}.feature.BaseFeature
|
|
61
|
+
import ${scalapackage}.utility.struct.Struct
|
|
62
|
+
|
|
63
|
+
object SdkCleanTestMain {
|
|
64
|
+
|
|
65
|
+
// Generated: the credential's wire placement is fixed when the SDK is built.
|
|
66
|
+
private val AUTH_SUPPRESSED = ${auth.suppressed}
|
|
67
|
+
private val AUTH_WHERE = "${scalastr(auth.where)}"
|
|
68
|
+
private val AUTH_NAME = "${scalastr(auth.name)}"
|
|
69
|
+
|
|
70
|
+
private val CANARY_APIKEY = "CANARY-APIKEY-k9x2m7q4p1"
|
|
71
|
+
private val CANARY_SECRET = "CANARY-SECRET-w3e8r5t2y6"
|
|
72
|
+
private val CANARY_HEADER = "CANARY-HEADER-z1x4c7v0b3"
|
|
73
|
+
private val CANARY_VALUE = "CANARY-VALUE-n5m8b2v9c4"
|
|
74
|
+
|
|
75
|
+
private val MASK = "[redacted]"
|
|
76
|
+
|
|
77
|
+
private def b64(s: String): String =
|
|
78
|
+
Base64.getEncoder.encodeToString(s.getBytes(StandardCharsets.UTF_8))
|
|
79
|
+
|
|
80
|
+
// Every form a canary can travel in.
|
|
81
|
+
private val FORMS: List[String] =
|
|
82
|
+
List(CANARY_APIKEY, CANARY_SECRET, CANARY_HEADER, CANARY_VALUE)
|
|
83
|
+
.flatMap(v => List(v, b64(v), URLEncoder.encode(v, StandardCharsets.UTF_8))) :+
|
|
84
|
+
b64(CANARY_APIKEY + ":" + CANARY_SECRET)
|
|
85
|
+
|
|
86
|
+
final class Sink(val name: String, val text: String)
|
|
87
|
+
|
|
88
|
+
private def om(kv: (String, Object)*): JMap[String, Object] = SdkTestSupport.om(kv*)
|
|
89
|
+
private def I(n: Int): java.lang.Integer = java.lang.Integer.valueOf(n)
|
|
90
|
+
private def B(b: Boolean): java.lang.Boolean = java.lang.Boolean.valueOf(b)
|
|
91
|
+
|
|
92
|
+
private def hasFeature(name: String): Boolean = {
|
|
93
|
+
val fm = Helpers.toMapAny(Config.sharedConfig().get("feature"))
|
|
94
|
+
fm != null && fm.get(name) != null
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Header maps keep the caller's spelling; the assertion should not care.
|
|
98
|
+
private def header(map: Object, name: String): Object = {
|
|
99
|
+
val m = Helpers.toMapAny(map)
|
|
100
|
+
if (m == null) return null
|
|
101
|
+
val it = m.entrySet().iterator()
|
|
102
|
+
while (it.hasNext) {
|
|
103
|
+
val e = it.next()
|
|
104
|
+
if (e.getKey.toLowerCase == name.toLowerCase) return e.getValue
|
|
105
|
+
}
|
|
106
|
+
null
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
private def leaks(text: String): List[String] = FORMS.filter(f => text.contains(f))
|
|
110
|
+
|
|
111
|
+
// The SDK's own objects print their data, not a class name, so a raw spec
|
|
112
|
+
// handed back with clean off shows what it holds.
|
|
113
|
+
private def plain(v: Object): Object = v match {
|
|
114
|
+
case s: Spec => om("method" -> s.method, "url" -> s.url, "path" -> s.path,
|
|
115
|
+
"headers" -> s.headers, "query" -> s.query, "body" -> s.body)
|
|
116
|
+
case r: Result => om("status" -> I(r.status), "headers" -> r.headers,
|
|
117
|
+
"body" -> r.body, "resdata" -> r.resdata)
|
|
118
|
+
case e: SdkEntity => e.data()
|
|
119
|
+
case _ => v
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private def stack(err: Throwable): String = {
|
|
123
|
+
val sw = new StringWriter()
|
|
124
|
+
err.printStackTrace(new PrintWriter(sw))
|
|
125
|
+
sw.toString
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private def surfaces(name: String, v: Object): List[Sink] = {
|
|
129
|
+
val out = new ArrayList[Sink]()
|
|
130
|
+
def push(kind: String)(fn: => String): Unit =
|
|
131
|
+
try out.add(new Sink(name + ":" + kind, fn))
|
|
132
|
+
catch { case _: Throwable => }
|
|
133
|
+
push("json") { Struct.jsonify(plain(v)) }
|
|
134
|
+
push("string") { String.valueOf(v) }
|
|
135
|
+
v match {
|
|
136
|
+
case t: Throwable =>
|
|
137
|
+
push("message") { if (t.getMessage == null) "" else t.getMessage }
|
|
138
|
+
push("stack") { stack(t) }
|
|
139
|
+
case _ =>
|
|
140
|
+
}
|
|
141
|
+
v match {
|
|
142
|
+
case e: SdkError =>
|
|
143
|
+
push("map") { Struct.jsonify(e.toMap()) }
|
|
144
|
+
push("spec") { Struct.jsonify(plain(e.spec)) }
|
|
145
|
+
push("result") { Struct.jsonify(plain(e.result)) }
|
|
146
|
+
case _ =>
|
|
147
|
+
}
|
|
148
|
+
v match {
|
|
149
|
+
case c: Context => push("record") { Struct.jsonify(c.toMap()) }
|
|
150
|
+
case _ =>
|
|
151
|
+
}
|
|
152
|
+
out.toArray(new Array[Sink](0)).toList
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
private def collect(sinks: ArrayList[Sink], name: String, v: Object): Unit =
|
|
156
|
+
surfaces(name, v).foreach(s => sinks.add(s))
|
|
157
|
+
|
|
158
|
+
// Captures the serialised context from inside the pipeline: what a hook
|
|
159
|
+
// author would hand to a logger.
|
|
160
|
+
final class CaptureFeature(sinks: ArrayList[Sink]) extends BaseFeature("capture", "0.0.1", true) {
|
|
161
|
+
override def preRequest(ctx: Context): Unit = collect(sinks, "ctx@PreRequest", ctx)
|
|
162
|
+
override def preResponse(ctx: Context): Unit = collect(sinks, "ctx@PreResponse", ctx)
|
|
163
|
+
override def preUnexpected(ctx: Context): Unit = collect(sinks, "ctx@PreUnexpected", ctx)
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// A feature that throws from inside the pipeline, quoting the request it
|
|
167
|
+
// saw: a plain Exception, which is not a RuntimeException. makeError fires
|
|
168
|
+
// PreUnexpected, so what the unexpected variant throws there escapes it.
|
|
169
|
+
final class ThrowFeature(unexpected: Boolean) extends BaseFeature("throwhook", "0.0.1", true) {
|
|
170
|
+
private def saw(ctx: Context): Exception = new Exception("hook saw " + Struct.jsonify(plain(ctx.spec)))
|
|
171
|
+
override def preResponse(ctx: Context): Unit = throw saw(ctx)
|
|
172
|
+
override def preUnexpected(ctx: Context): Unit = if (unexpected) throw saw(ctx)
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// A stream that fails while the caller iterates it, quoting a credential.
|
|
176
|
+
final class StreamThrowFeature extends BaseFeature("streamthrow", "0.0.1", true) {
|
|
177
|
+
override def preDone(ctx: Context): Unit = {
|
|
178
|
+
val failing: Supplier[java.util.Iterator[Object]] = () => new java.util.Iterator[Object] {
|
|
179
|
+
override def hasNext: Boolean = throw new RuntimeException("stream saw " + CANARY_APIKEY)
|
|
180
|
+
override def next(): Object = throw new NoSuchElementException()
|
|
181
|
+
}
|
|
182
|
+
ctx.result.stream = failing
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// A stream that succeeds, yielding the result's items.
|
|
187
|
+
final class StreamOkFeature extends BaseFeature("streamok", "0.0.1", true) {
|
|
188
|
+
override def preDone(ctx: Context): Unit = {
|
|
189
|
+
val items = new ArrayList[Object]()
|
|
190
|
+
ctx.result.resdata match {
|
|
191
|
+
case l: JList[_] => l.forEach(item => items.add(item.asInstanceOf[Object]))
|
|
192
|
+
case null =>
|
|
193
|
+
case other => items.add(other)
|
|
194
|
+
}
|
|
195
|
+
val ok: Supplier[java.util.Iterator[Object]] = () => items.iterator()
|
|
196
|
+
ctx.result.stream = ok
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
final class Scenario(val name: String, val respond: (String, JMap[String, Object]) => Object)
|
|
201
|
+
|
|
202
|
+
private def response(status: Int, data: Object, headers: JMap[String, Object]): JMap[String, Object] = {
|
|
203
|
+
val h = new LinkedHashMap[String, Object]()
|
|
204
|
+
h.put("content-type", "application/json")
|
|
205
|
+
if (headers != null) h.putAll(headers)
|
|
206
|
+
val js: Supplier[Object] = () => data
|
|
207
|
+
val out = new LinkedHashMap[String, Object]()
|
|
208
|
+
out.put("status", I(status))
|
|
209
|
+
out.put("statusText", if (status < 400) "OK" else "ERR")
|
|
210
|
+
out.put("headers", h)
|
|
211
|
+
out.put("json", js)
|
|
212
|
+
out.put("body", Struct.jsonify(data))
|
|
213
|
+
out
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
private val SCENARIOS: List[Scenario] = List(
|
|
217
|
+
new Scenario("ok", (_, _) => response(200, om("id" -> "i1", "name" -> "n1"),
|
|
218
|
+
om("x-session-token" -> "RESP-TOKEN-a1b2c3d4e5"))),
|
|
219
|
+
new Scenario("notfound", (_, _) => response(404, om("error" -> "no such record"), null)),
|
|
220
|
+
new Scenario("server", (_, _) => response(500, om("error" -> "boom"), null)),
|
|
221
|
+
new Scenario("transport", (url, _) =>
|
|
222
|
+
throw new RuntimeException("socket hang up (URL was: \\"" + url + "\\")")),
|
|
223
|
+
new Scenario("notjson", (_, _) => {
|
|
224
|
+
val js: Supplier[Object] = () => null
|
|
225
|
+
om("status" -> I(200), "statusText" -> "OK",
|
|
226
|
+
"headers" -> new LinkedHashMap[String, Object](), "json" -> js, "body" -> "<html>")
|
|
227
|
+
}),
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
private def makeSdk(scenario: Scenario, sinks: ArrayList[Sink], cleanopts: JMap[String, Object],
|
|
231
|
+
extra: BaseFeature = null): ${SDK} = {
|
|
232
|
+
def capture(name: String): Consumer[Object] = (rec: Object) => collect(sinks, name, rec)
|
|
233
|
+
|
|
234
|
+
val feature = new LinkedHashMap[String, Object]()
|
|
235
|
+
if (hasFeature("log")) {
|
|
236
|
+
val logger = Logger.getLogger("clean-sweep-" + System.nanoTime())
|
|
237
|
+
logger.setUseParentHandlers(false)
|
|
238
|
+
logger.setLevel(Level.ALL)
|
|
239
|
+
logger.addHandler(new Handler() {
|
|
240
|
+
override def publish(record: LogRecord): Unit = collect(sinks, "log", record.getMessage)
|
|
241
|
+
override def flush(): Unit = {}
|
|
242
|
+
override def close(): Unit = {}
|
|
243
|
+
})
|
|
244
|
+
feature.put("log", om("active" -> B(true), "logger" -> logger))
|
|
245
|
+
}
|
|
246
|
+
if (hasFeature("debug")) feature.put("debug", om("active" -> B(true), "onEntry" -> capture("debug")))
|
|
247
|
+
if (hasFeature("audit")) feature.put("audit", om("active" -> B(true), "sink" -> capture("audit")))
|
|
248
|
+
if (hasFeature("telemetry")) feature.put("telemetry", om("active" -> B(true), "exporter" -> capture("telemetry")))
|
|
249
|
+
if (hasFeature("cost")) feature.put("cost", om("active" -> B(true), "sink" -> capture("cost")))
|
|
250
|
+
if (hasFeature("metrics")) feature.put("metrics", om("active" -> B(true)))
|
|
251
|
+
if (hasFeature("clienttrack")) feature.put("clienttrack", om("active" -> B(true)))
|
|
252
|
+
|
|
253
|
+
val clean = new LinkedHashMap[String, Object]()
|
|
254
|
+
clean.put("values", CANARY_VALUE)
|
|
255
|
+
if (cleanopts != null) clean.putAll(cleanopts)
|
|
256
|
+
|
|
257
|
+
val fetcher: (Context, String, JMap[String, Object]) => Object =
|
|
258
|
+
(_, url, fetchdef) => scenario.respond(url, fetchdef)
|
|
259
|
+
|
|
260
|
+
val opts = new LinkedHashMap[String, Object]()
|
|
261
|
+
opts.put("apikey", CANARY_APIKEY)
|
|
262
|
+
opts.put("secret", CANARY_SECRET)
|
|
263
|
+
opts.put("headers", om("X-Custom-Token" -> CANARY_HEADER))
|
|
264
|
+
opts.put("clean", clean)
|
|
265
|
+
opts.put("feature", feature)
|
|
266
|
+
val extend = SdkTestSupport.jl(new CaptureFeature(sinks))
|
|
267
|
+
if (extra != null) extend.add(extra)
|
|
268
|
+
opts.put("extend", extend)
|
|
269
|
+
opts.put("utility", om("fetcher" -> fetcher))
|
|
270
|
+
new ${SDK}(opts)
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
final class Target(val accessor: Method, val op: String, val matchArgs: JMap[String, Object])
|
|
274
|
+
|
|
275
|
+
private def accessors(): List[Method] =
|
|
276
|
+
classOf[${SDK}].getMethods.toList
|
|
277
|
+
.filter(m => classOf[SdkEntity].isAssignableFrom(m.getReturnType) &&
|
|
278
|
+
m.getParameterCount == 1 && Modifier.isPublic(m.getModifiers))
|
|
279
|
+
.sortBy(m => m.getName)
|
|
280
|
+
|
|
281
|
+
private def entityOf(sdk: ${SDK}, m: Method): SdkEntity =
|
|
282
|
+
try m.invoke(sdk, Array[Object](null)*) match {
|
|
283
|
+
case e: SdkEntity => e
|
|
284
|
+
case _ => null
|
|
285
|
+
}
|
|
286
|
+
catch { case _: Throwable => null }
|
|
287
|
+
|
|
288
|
+
private def call(ent: SdkEntity, op: String, matchArgs: JMap[String, Object],
|
|
289
|
+
ctrl: JMap[String, Object]): Object = {
|
|
290
|
+
val args = new LinkedHashMap[String, Object](matchArgs)
|
|
291
|
+
op match {
|
|
292
|
+
case "list" => ent.list(args, ctrl)
|
|
293
|
+
case "load" => ent.load(args, ctrl)
|
|
294
|
+
case "create" => ent.create(args, ctrl)
|
|
295
|
+
case "update" => ent.update(args, ctrl)
|
|
296
|
+
case "remove" => ent.remove(args, ctrl)
|
|
297
|
+
case _ => throw new IllegalArgumentException("no such op: " + op)
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Every path parameter an op's points declare, filled in.
|
|
302
|
+
private def filled(opdef: JMap[String, Object]): JMap[String, Object] = {
|
|
303
|
+
val out = new LinkedHashMap[String, Object]()
|
|
304
|
+
Struct.getprop(opdef, "points") match {
|
|
305
|
+
case points: JList[_] =>
|
|
306
|
+
points.forEach { point =>
|
|
307
|
+
Struct.getpath(point, java.util.List.of("args", "params")) match {
|
|
308
|
+
case ps: JList[_] =>
|
|
309
|
+
ps.forEach { p =>
|
|
310
|
+
Struct.getprop(p, "name") match { case n: String => out.put(n, "p1"); case _ => }
|
|
311
|
+
}
|
|
312
|
+
case _ =>
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
case _ =>
|
|
316
|
+
}
|
|
317
|
+
out
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// The first operation that completes against a plain 200: with no
|
|
321
|
+
// arguments, else with every path parameter its points declare filled in.
|
|
322
|
+
private def usableOp(): Target = {
|
|
323
|
+
val plainFetch: (Context, String, JMap[String, Object]) => Object =
|
|
324
|
+
(_, _, _) => response(200, om("id" -> "i1"), null)
|
|
325
|
+
val plain = new ${SDK}(om("apikey" -> CANARY_APIKEY, "utility" -> om("fetcher" -> plainFetch)))
|
|
326
|
+
val entities = Helpers.toMapAny(Config.sharedConfig().get("entity"))
|
|
327
|
+
if (entities == null) return null
|
|
328
|
+
val rank = Map("list" -> 0, "load" -> 1)
|
|
329
|
+
var found: Target = null
|
|
330
|
+
val mit = accessors().iterator
|
|
331
|
+
while (found == null && mit.hasNext) {
|
|
332
|
+
val m = mit.next()
|
|
333
|
+
val inst = entityOf(plain, m)
|
|
334
|
+
val ecfg = if (inst == null) null else Helpers.toMapAny(entities.get(inst.getName()))
|
|
335
|
+
val opmap = if (ecfg == null) null else Helpers.toMapAny(ecfg.get("op"))
|
|
336
|
+
val ops =
|
|
337
|
+
if (opmap == null) Nil
|
|
338
|
+
else opmap.keySet().toArray.toList.map(k => String.valueOf(k)).sortBy(op => rank.getOrElse(op, 2))
|
|
339
|
+
val oit = ops.iterator
|
|
340
|
+
while (found == null && oit.hasNext) {
|
|
341
|
+
val op = oit.next()
|
|
342
|
+
val matches = List(new LinkedHashMap[String, Object](), filled(Helpers.toMapAny(opmap.get(op))))
|
|
343
|
+
val kit = matches.iterator
|
|
344
|
+
while (found == null && kit.hasNext) {
|
|
345
|
+
val matchArgs = kit.next()
|
|
346
|
+
try {
|
|
347
|
+
call(entityOf(plain, m), op, matchArgs, null)
|
|
348
|
+
found = new Target(m, op, matchArgs)
|
|
349
|
+
}
|
|
350
|
+
catch { case _: Throwable => }
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
found
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
private val NO_OP = "no operation of this SDK completes against a plain 200; nothing to sweep"
|
|
358
|
+
|
|
359
|
+
private def drive(sdk: ${SDK}, target: Target, ctrl: JMap[String, Object], sinks: ArrayList[Sink]): Throwable = {
|
|
360
|
+
// A caller may keep the record it passed rather than read ctrl's entry.
|
|
361
|
+
val held = if (ctrl == null) null else ctrl.get("explain")
|
|
362
|
+
var out: Object = null
|
|
363
|
+
var err: Throwable = null
|
|
364
|
+
try out = call(entityOf(sdk, target.accessor), target.op, target.matchArgs, ctrl)
|
|
365
|
+
catch { case e: Throwable => err = e }
|
|
366
|
+
if (err != null) collect(sinks, "error", err)
|
|
367
|
+
if (out != null) collect(sinks, "result", out)
|
|
368
|
+
val explain = if (ctrl == null) null else ctrl.get("explain")
|
|
369
|
+
if (explain != null) collect(sinks, "explain", explain)
|
|
370
|
+
if (held != null && !(held eq explain)) collect(sinks, "explain:held", held)
|
|
371
|
+
err
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
private def sweep(rep: SdkTestReport): Unit = {
|
|
375
|
+
val target = usableOp()
|
|
376
|
+
if (target == null) {
|
|
377
|
+
println("clean: skipped: " + NO_OP)
|
|
378
|
+
return
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
val sinks = new ArrayList[Sink]()
|
|
382
|
+
val errors = new LinkedHashMap[String, Throwable]()
|
|
383
|
+
val explains = new LinkedHashMap[String, JMap[String, Object]]()
|
|
384
|
+
|
|
385
|
+
for (scenario <- SCENARIOS) {
|
|
386
|
+
for (variant <- List("throw", "explain", "nothrow")) {
|
|
387
|
+
val sdk = makeSdk(scenario, sinks, null)
|
|
388
|
+
val ctrl: JMap[String, Object] = variant match {
|
|
389
|
+
case "throw" => null
|
|
390
|
+
case "explain" => om("explain" -> new LinkedHashMap[String, Object]())
|
|
391
|
+
case _ => om("throw" -> B(false), "explain" -> new LinkedHashMap[String, Object]())
|
|
392
|
+
}
|
|
393
|
+
val err = drive(sdk, target, ctrl, sinks)
|
|
394
|
+
val key = scenario.name + "/" + variant
|
|
395
|
+
if (err != null) errors.put(key, err)
|
|
396
|
+
val explain = if (ctrl == null) null else Helpers.toMapAny(ctrl.get("explain"))
|
|
397
|
+
if (explain != null) explains.put(key, explain)
|
|
398
|
+
collect(sinks, "sdk", sdk)
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
// A credential mistyped as a map. Validation here collects its errors
|
|
403
|
+
// rather than throwing, so there is no rejection to sweep: sweep the
|
|
404
|
+
// client it built, an operation it runs, and a message quoting the value.
|
|
405
|
+
val fetch404: (Context, String, JMap[String, Object]) => Object =
|
|
406
|
+
(_, url, fetchdef) => SCENARIOS(1).respond(url, fetchdef)
|
|
407
|
+
val mistyped = new ${SDK}(om("apikey" -> om("value" -> CANARY_APIKEY),
|
|
408
|
+
"clean" -> om("values" -> CANARY_VALUE), "utility" -> om("fetcher" -> fetch404)))
|
|
409
|
+
collect(sinks, "mistyped", mistyped)
|
|
410
|
+
drive(mistyped, target, null, sinks)
|
|
411
|
+
collect(sinks, "mistyped:quoted",
|
|
412
|
+
mistyped.getUtility().clean(mistyped.getRootCtx(), "found map: " + CANARY_APIKEY))
|
|
413
|
+
|
|
414
|
+
// An exception a feature hook throws, quoting the request, skips makeError.
|
|
415
|
+
for (unexpected <- List(false, true)) {
|
|
416
|
+
val hooked = makeSdk(SCENARIOS.head, sinks, null, new ThrowFeature(unexpected))
|
|
417
|
+
val hookerr = drive(hooked, target, om("explain" -> new LinkedHashMap[String, Object]()), sinks)
|
|
418
|
+
rep.check("clean.hook-throws", hookerr != null, "the throwing hook should fail the operation")
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Iterating a stream runs inside the same catch path as the operation,
|
|
422
|
+
// and the explain record the caller passed is cleaned however it ends.
|
|
423
|
+
for ((name, extra) <- List[(String, BaseFeature)](
|
|
424
|
+
("stream", new StreamThrowFeature()), ("stream-ok", new StreamOkFeature()), ("stream-plain", null))) {
|
|
425
|
+
val streaming = entityOf(makeSdk(SCENARIOS.head, sinks, null, extra), target.accessor)
|
|
426
|
+
val explain = new LinkedHashMap[String, Object]()
|
|
427
|
+
var streamerr: Throwable = null
|
|
428
|
+
try streaming.stream(target.op, om("reqmatch" -> new LinkedHashMap[String, Object](target.matchArgs)),
|
|
429
|
+
om("ctrl" -> om("explain" -> explain))).foreach(_ => ())
|
|
430
|
+
catch { case e: Throwable => streamerr = e }
|
|
431
|
+
rep.check("clean." + name + ".throws", ("stream" == name) == (streamerr != null),
|
|
432
|
+
name + ": only the failing stream throws")
|
|
433
|
+
if (streamerr != null) collect(sinks, name, streamerr)
|
|
434
|
+
rep.check("clean." + name + ".explain", !explain.isEmpty, name + ": the explain record was not filled")
|
|
435
|
+
collect(sinks, name + ":explain", explain)
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// The raw path returns its failure rather than throwing it.
|
|
439
|
+
val raw = makeSdk(SCENARIOS(3), sinks, null).direct(om("path" -> "raw"))
|
|
440
|
+
rep.check("clean.direct-fails", java.lang.Boolean.FALSE == raw.get("ok") && raw.get("err") != null,
|
|
441
|
+
"a transport failure should fail direct()")
|
|
442
|
+
collect(sinks, "direct", raw.get("err"))
|
|
443
|
+
|
|
444
|
+
// A registered value used as a map key is masked; keys that mask alike
|
|
445
|
+
// are kept apart.
|
|
446
|
+
val probe = makeSdk(SCENARIOS.head, sinks, null)
|
|
447
|
+
val named = Helpers.toMapAny(probe.getUtility().clean(probe.getRootCtx(),
|
|
448
|
+
om(CANARY_VALUE -> I(1), CANARY_HEADER -> I(2), "plain" -> I(3))))
|
|
449
|
+
collect(sinks, "named", named)
|
|
450
|
+
|
|
451
|
+
// An error's code is cleaned like its message.
|
|
452
|
+
val coded = probe.getUtility().clean(probe.getRootCtx(), new SdkError("code_" + CANARY_VALUE, "coded", null))
|
|
453
|
+
collect(sinks, "coded", coded)
|
|
454
|
+
|
|
455
|
+
val all = sinks.toArray(new Array[Sink](0)).toList
|
|
456
|
+
val leaked = all.map(s => (s.name, leaks(s.text))).filter(l => l._2.nonEmpty)
|
|
457
|
+
|
|
458
|
+
println("clean: swept " + all.size + " surface(s), " + leaked.size + " leak(s)")
|
|
459
|
+
|
|
460
|
+
rep.check("clean.no-leak", leaked.isEmpty, "credential leaked through: " +
|
|
461
|
+
leaked.map(l => l._1 + " [" + l._2.mkString(", ") + "]").mkString("; "))
|
|
462
|
+
|
|
463
|
+
// The positive half: the slot the credential travelled in is masked,
|
|
464
|
+
// and an unregistered token in a response header is masked by name.
|
|
465
|
+
val notfound = errors.get("notfound/throw")
|
|
466
|
+
rep.check("clean.404-throws", notfound != null, "the 404 scenario must throw")
|
|
467
|
+
notfound match {
|
|
468
|
+
case nf: SdkError =>
|
|
469
|
+
rep.eqI("clean.404-status", 404, nf.status)
|
|
470
|
+
val specm = Helpers.toMapAny(nf.spec)
|
|
471
|
+
val spec = if (specm == null) new LinkedHashMap[String, Object]() else specm
|
|
472
|
+
if (!AUTH_SUPPRESSED) {
|
|
473
|
+
if ("query" == AUTH_WHERE) {
|
|
474
|
+
rep.eq("clean.query-masked", MASK, header(spec.get("query"), AUTH_NAME))
|
|
475
|
+
} else if ("cookie" == AUTH_WHERE) {
|
|
476
|
+
val cookie = String.valueOf(header(spec.get("headers"), "cookie"))
|
|
477
|
+
rep.check("clean.cookie-masked", cookie.contains(MASK), "cookie: " + cookie)
|
|
478
|
+
} else {
|
|
479
|
+
val cred = String.valueOf(header(spec.get("headers"), AUTH_NAME))
|
|
480
|
+
rep.check("clean.header-masked", cred.endsWith(MASK), AUTH_NAME + ": " + cred)
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
rep.eq("clean.custom-header-masked", MASK, header(spec.get("headers"), "x-custom-token"))
|
|
484
|
+
case other =>
|
|
485
|
+
rep.fail("clean.404-sdkerror", "the 404 scenario should throw an SdkError, got " + other)
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
val explained = explains.get("ok/explain")
|
|
489
|
+
val result = if (explained == null) null else Helpers.toMapAny(explained.get("result"))
|
|
490
|
+
rep.check("clean.explain-result", result != null, "the explain record should carry the result")
|
|
491
|
+
if (result != null) {
|
|
492
|
+
rep.eq("clean.response-header-masked", MASK, header(result.get("headers"), "x-session-token"))
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
rep.eq("clean.map-keys", om(MASK -> I(1), (MASK + "#1") -> I(2), "plain" -> I(3)), named)
|
|
496
|
+
coded match {
|
|
497
|
+
case e: SdkError => rep.eq("clean.code-masked", "code_" + MASK, e.code)
|
|
498
|
+
case other => rep.fail("clean.code-sdkerror", "clean should return the SdkError, got " + other)
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
private def sensitivity(rep: SdkTestReport): Unit = {
|
|
503
|
+
val target = usableOp()
|
|
504
|
+
if (target == null) {
|
|
505
|
+
println("clean: skipped: " + NO_OP)
|
|
506
|
+
return
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
val sinks = new ArrayList[Sink]()
|
|
510
|
+
val sdk = makeSdk(SCENARIOS(1), sinks, om("active" -> B(false)))
|
|
511
|
+
val err = drive(sdk, target, null, sinks)
|
|
512
|
+
rep.check("clean.off.throws", err != null, "the 404 scenario must throw")
|
|
513
|
+
|
|
514
|
+
// Explaining a failure must not cost it its error.
|
|
515
|
+
val explained = drive(makeSdk(SCENARIOS(1), new ArrayList[Sink](), om("active" -> B(false))), target,
|
|
516
|
+
om("explain" -> new LinkedHashMap[String, Object]()), new ArrayList[Sink]())
|
|
517
|
+
val errmsg = if (err == null) null else err.getMessage
|
|
518
|
+
val explainedmsg = if (explained == null) null else explained.getMessage
|
|
519
|
+
rep.check("clean.off.explain-keeps-error", errmsg == explainedmsg,
|
|
520
|
+
"with clean off, explain lost the error: expected " + errmsg + ", got " + explainedmsg)
|
|
521
|
+
|
|
522
|
+
val leaked = sinks.toArray(new Array[Sink](0)).toList.filter(s => leaks(s.text).nonEmpty)
|
|
523
|
+
rep.check("clean.off.shows-canary", leaked.nonEmpty,
|
|
524
|
+
"with clean off, nothing showed the canary: the sweep is blind")
|
|
525
|
+
|
|
526
|
+
if (!AUTH_SUPPRESSED) err match {
|
|
527
|
+
case e: SdkError =>
|
|
528
|
+
val text = Struct.jsonify(plain(e.spec))
|
|
529
|
+
rep.check("clean.off.raw-spec",
|
|
530
|
+
text.contains(CANARY_APIKEY) || text.contains(b64(CANARY_APIKEY + ":" + CANARY_SECRET)),
|
|
531
|
+
"the raw spec should carry the credential when clean is off")
|
|
532
|
+
case _ =>
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
// A feature's name is not a field name: only the sensitive names inside its
|
|
537
|
+
// settings register. An entity block, of per-entity settings or seeded
|
|
538
|
+
// records keyed by entity name and id, is not read at all.
|
|
539
|
+
private def featureNames(rep: SdkTestReport): Unit = {
|
|
540
|
+
val sdk = new ${SDK}(om(
|
|
541
|
+
"apikey" -> CANARY_APIKEY,
|
|
542
|
+
"feature" -> om(
|
|
543
|
+
"zzsecrets" -> om("active" -> B(false), "kind" -> "PLAINSETTING-q8w2e4r6"),
|
|
544
|
+
"zzfeat" -> om("active" -> B(false), "apitoken" -> "FEATTOKEN-z9y8x7w6"),
|
|
545
|
+
"test" -> om("active" -> B(false), "entity" -> om(
|
|
546
|
+
"zztoken" -> om("ZZTOKEN01" -> om("note" -> "PLAINRECORD-t5r3e1w9"))))),
|
|
547
|
+
"entity" -> om("zztoken" -> om("alias" -> om("zzkey" -> "PLAINALIAS-m2n4b6v8")))))
|
|
548
|
+
def clean(s: String): Object = sdk.getUtility().clean(sdk.getRootCtx(), s)
|
|
549
|
+
|
|
550
|
+
rep.eq("clean.feature.setting", "kind PLAINSETTING-q8w2e4r6", clean("kind PLAINSETTING-q8w2e4r6"))
|
|
551
|
+
rep.eq("clean.feature.token", "token " + MASK, clean("token FEATTOKEN-z9y8x7w6"))
|
|
552
|
+
rep.eq("clean.entity.record", "record PLAINRECORD-t5r3e1w9", clean("record PLAINRECORD-t5r3e1w9"))
|
|
553
|
+
rep.eq("clean.entity.alias", "alias PLAINALIAS-m2n4b6v8", clean("alias PLAINALIAS-m2n4b6v8"))
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
private def configBlock(rep: SdkTestReport): Unit = {
|
|
557
|
+
val utility = new ${SDK}(om()).getUtility()
|
|
558
|
+
val config = om("options" -> om("clean" -> om("keys" -> "zzsens", "values" -> "CONFIG-SEEDED-1")))
|
|
559
|
+
val ctx = utility.makeContext(om("utility" -> utility, "config" -> config,
|
|
560
|
+
"options" -> om("clean" -> om("values" -> "CALLER-SEEDED-2"))), null)
|
|
561
|
+
ctx.options = utility.makeOptions(ctx)
|
|
562
|
+
|
|
563
|
+
rep.eq("clean.config.values", "a " + MASK + " b " + MASK,
|
|
564
|
+
utility.clean(ctx, "a CONFIG-SEEDED-1 b CALLER-SEEDED-2"))
|
|
565
|
+
val masked = Helpers.toMapAny(utility.clean(ctx, om("my_zzsens" -> "x", "other" -> "y")))
|
|
566
|
+
rep.eq("clean.config.keys", om("my_zzsens" -> MASK, "other" -> "y"), masked)
|
|
567
|
+
rep.eq("clean.config.unchanged", "CONFIG-SEEDED-1",
|
|
568
|
+
Struct.getpath(config, java.util.List.of("options", "clean", "values")))
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
private def noBlock(rep: SdkTestReport): Unit = {
|
|
572
|
+
val utility = new ${SDK}(om()).getUtility()
|
|
573
|
+
val ctx = utility.makeContext(om("utility" -> utility,
|
|
574
|
+
"options" -> om("apikey" -> "NOBLOCK-APIKEY-k3j5h7")), null)
|
|
575
|
+
ctx.options = utility.makeOptions(ctx)
|
|
576
|
+
|
|
577
|
+
rep.eq("clean.no-block.values", "failed with " + MASK,
|
|
578
|
+
utility.clean(ctx, "failed with NOBLOCK-APIKEY-k3j5h7"))
|
|
579
|
+
val masked = Helpers.toMapAny(utility.clean(ctx, om("x-session-token" -> "RESP-TOKEN-a1b2c3d4e5")))
|
|
580
|
+
rep.eq("clean.no-block.keys", om("x-session-token" -> MASK), masked)
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
def main(args: Array[String]): Unit = {
|
|
584
|
+
val rep = new SdkTestReport()
|
|
585
|
+
|
|
586
|
+
rep.scope("clean-no-credential-leaves-the-sdk") { sweep(rep) }
|
|
587
|
+
rep.scope("clean-the-sweep-can-see-a-leak") { sensitivity(rep) }
|
|
588
|
+
rep.scope("clean-a-feature-name-does-not-make-its-settings-secret") { featureNames(rep) }
|
|
589
|
+
rep.scope("clean-the-config-clean-block-is-honoured") { configBlock(rep) }
|
|
590
|
+
rep.scope("clean-with-no-clean-block-the-schema-defaults-apply") { noBlock(rep) }
|
|
591
|
+
|
|
592
|
+
rep.finish("CLEAN")
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
`
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
// A Scala double-quoted string literal body: the auth name comes from the
|
|
600
|
+
// API's own securityScheme.
|
|
601
|
+
function scalastr(s: string): string {
|
|
602
|
+
return String(s).replace(/\\/g, '\\\\').replace(/"/g, '\\"')
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
export {
|
|
607
|
+
TestClean
|
|
608
|
+
}
|
|
@@ -15,6 +15,7 @@ import { cmp, each, Folder, File, Content, entityCollection,
|
|
|
15
15
|
|
|
16
16
|
import { TestEntity } from './TestEntity_scala'
|
|
17
17
|
import { TestDirect } from './TestDirect_scala'
|
|
18
|
+
import { TestClean } from './TestClean_scala'
|
|
18
19
|
import { ReadmeExamplesTest } from './ReadmeExamplesTest_scala'
|
|
19
20
|
import { scalaPackage } from './utility_scala'
|
|
20
21
|
|
|
@@ -35,6 +36,8 @@ const Test = cmp(function Test(props: any) {
|
|
|
35
36
|
// Write-once: a project's edited control file survives regeneration.
|
|
36
37
|
TestControl({ target, dir: 'sdktest' })
|
|
37
38
|
|
|
39
|
+
TestClean({ target, scalapackage })
|
|
40
|
+
|
|
38
41
|
const entities: { Name: string; entity: boolean; direct: boolean }[] = []
|
|
39
42
|
|
|
40
43
|
const entity = each(entityCollection(model))
|