@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
|
@@ -471,7 +471,7 @@ object SdkTestMain {
|
|
|
471
471
|
val h = fhMake(null, fhF(f, om("max" -> I(1), "onEntry" -> oe)))
|
|
472
472
|
h.op(fhOp("load").withHeaders(om("authorization" -> "Bearer secret"))); h.op(fhOp("list"))
|
|
473
473
|
eqI("debug.ring", 1, f.entries.size()); eqI("debug.onEntry", 2, seen.size())
|
|
474
|
-
eq("debug.redacted", "
|
|
474
|
+
eq("debug.redacted", "[redacted]", Helpers.toMapAny(seen.get(0).get("headers")).get("authorization")) }
|
|
475
475
|
{ val f = new DebugFeature()
|
|
476
476
|
val h = fhMake(null, fhF(new NetsimFeature(), om("failTimes" -> I(1), "failStatus" -> I(500))), fhF(f, null))
|
|
477
477
|
h.op(fhOp("load")); eqI("debug.fail.n", 1, f.entries.size()); eq("debug.fail.ok", B(false), f.entries.get(0).get("ok")) }
|
|
@@ -479,7 +479,7 @@ object SdkTestMain {
|
|
|
479
479
|
val h = fhMake(null, fhF(f, om("now" -> f0(clk.nowFn), "redact" -> jl("x-secret"))))
|
|
480
480
|
h.op(fhOp("load").withHeaders(om("x-secret" -> "hide", "x-ok" -> "show")))
|
|
481
481
|
val dh = Helpers.toMapAny(f.entries.get(0).get("headers"))
|
|
482
|
-
eq("debug.redact.secret", "
|
|
482
|
+
eq("debug.redact.secret", "[redacted]", dh.get("x-secret")); eq("debug.redact.ok", "show", dh.get("x-ok")) }
|
|
483
483
|
{ val f = new DebugFeature()
|
|
484
484
|
val h = fhMake(null, fhF(f, om("active" -> B(false))))
|
|
485
485
|
h.op(fhOp("load")); eqI("debug.inactive", 0, f.entries.size()) }
|
|
@@ -33,6 +33,7 @@ object MakeError {
|
|
|
33
33
|
val spec = ctx.spec
|
|
34
34
|
|
|
35
35
|
if (ctx.ctrl.explain != null) {
|
|
36
|
+
Clean.cleanExplain(ctx)
|
|
36
37
|
val errRecord = new LinkedHashMap[String, Object]()
|
|
37
38
|
errRecord.put("message", msg)
|
|
38
39
|
ctx.ctrl.explain.put("err", errRecord)
|
|
@@ -44,6 +45,7 @@ object MakeError {
|
|
|
44
45
|
val sdkErr = new SdkError(code, msg, ctx)
|
|
45
46
|
sdkErr.result = Clean.clean(ctx, result)
|
|
46
47
|
sdkErr.spec = Clean.clean(ctx, spec)
|
|
48
|
+
sdkErr.status = result.status
|
|
47
49
|
|
|
48
50
|
ctx.ctrl.err = sdkErr
|
|
49
51
|
|
|
@@ -266,6 +268,29 @@ object MakeOptions {
|
|
|
266
268
|
// null check, which cannot distinguish them.
|
|
267
269
|
val authSuppressed = options.containsKey("auth") && null == options.get("auth")
|
|
268
270
|
|
|
271
|
+
var config = ctx.config
|
|
272
|
+
if (config == null) config = new LinkedHashMap[String, Object]()
|
|
273
|
+
var cfgopts = Helpers.toMapAny(config.get("options"))
|
|
274
|
+
if (cfgopts == null) cfgopts = new LinkedHashMap[String, Object]()
|
|
275
|
+
|
|
276
|
+
// The secret registry exists BEFORE validation, fed from the raw input, so
|
|
277
|
+
// the constructor's own rejection of a mistyped credential is clean too.
|
|
278
|
+
// An absent layer is left out: merge lets a null replace everything before it.
|
|
279
|
+
val cleanlist = new ArrayList[Object]()
|
|
280
|
+
cleanlist.add(new LinkedHashMap[String, Object]())
|
|
281
|
+
for (layer <- List(Schema.optspec.get("clean"), cfgopts.get("clean"), options.get("clean"))
|
|
282
|
+
if layer != null) {
|
|
283
|
+
cleanlist.add(Struct.clone(layer))
|
|
284
|
+
}
|
|
285
|
+
val cleancfg = Clean.makeCleanConfig(Struct.merge(cleanlist))
|
|
286
|
+
addSensitiveOptions(cleancfg, options, "clean")
|
|
287
|
+
for (block <- List(cfgopts.get("clean"), options.get("clean"))) {
|
|
288
|
+
val bm = Helpers.toMapAny(block)
|
|
289
|
+
for (raw <- Clean.splitvalues(if (bm == null) null else bm.get("values"))) {
|
|
290
|
+
Clean.registerValue(cleancfg, raw)
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
269
294
|
var opts = Struct.clone(options).asInstanceOf[JMap[String, Object]]
|
|
270
295
|
|
|
271
296
|
if (authSuppressed) opts.remove("auth")
|
|
@@ -298,11 +323,6 @@ object MakeOptions {
|
|
|
298
323
|
case _ =>
|
|
299
324
|
}
|
|
300
325
|
|
|
301
|
-
var config = ctx.config
|
|
302
|
-
if (config == null) config = new LinkedHashMap[String, Object]()
|
|
303
|
-
var cfgopts = Helpers.toMapAny(config.get("options"))
|
|
304
|
-
if (cfgopts == null) cfgopts = new LinkedHashMap[String, Object]()
|
|
305
|
-
|
|
306
326
|
// THE OPTION SPEC IS GENERATED, NOT WRITTEN HERE.
|
|
307
327
|
//
|
|
308
328
|
// Built from the model: `main.kit.optspec` for the standard options, plus
|
|
@@ -330,9 +350,17 @@ object MakeOptions {
|
|
|
330
350
|
mergeList.add(opts)
|
|
331
351
|
val merged = Struct.merge(mergeList)
|
|
332
352
|
|
|
353
|
+
// Errors are collected, not thrown, so a mistyped option is not rejected.
|
|
333
354
|
val vopts = new LinkedHashMap[String, Object]()
|
|
334
355
|
vopts.put("errs", new ArrayList[Object]())
|
|
335
|
-
val validated =
|
|
356
|
+
val validated =
|
|
357
|
+
try Struct.validate(merged, optspec, vopts)
|
|
358
|
+
catch {
|
|
359
|
+
// A rejection quotes the value it rejected.
|
|
360
|
+
case err: RuntimeException =>
|
|
361
|
+
val text = if (err.getMessage == null) String.valueOf(err) else err.getMessage
|
|
362
|
+
throw new SdkError("options_invalid", Clean.cleanWith(cleancfg, text).asInstanceOf[String], ctx)
|
|
363
|
+
}
|
|
336
364
|
opts = validated.asInstanceOf[JMap[String, Object]]
|
|
337
365
|
|
|
338
366
|
// Restore the suppression the optspec default would otherwise erase.
|
|
@@ -345,17 +373,6 @@ object MakeOptions {
|
|
|
345
373
|
else { val sm = new LinkedHashMap[String, Object](); sm.put("fetch", sysFetch); opts.put("system", sm) }
|
|
346
374
|
}
|
|
347
375
|
|
|
348
|
-
// Derived clean config.
|
|
349
|
-
var cleanKeys = "key,token,id"
|
|
350
|
-
Struct.getpath(opts, java.util.List.of("clean", "keys")) match { case s: String => cleanKeys = s; case _ => }
|
|
351
|
-
|
|
352
|
-
val filtered = new ArrayList[String]()
|
|
353
|
-
for (p0 <- cleanKeys.split(",")) {
|
|
354
|
-
val p = p0.trim
|
|
355
|
-
if ("" != p) filtered.add(Struct.escre(p))
|
|
356
|
-
}
|
|
357
|
-
val keyre = String.join("|", filtered)
|
|
358
|
-
|
|
359
376
|
// Resolve the feature add-order: an explicit list order (above) wins;
|
|
360
377
|
// otherwise order the map test-first, then the remaining names sorted, so
|
|
361
378
|
// the outcome is deterministic and `test` is always the base transport.
|
|
@@ -374,14 +391,40 @@ object MakeOptions {
|
|
|
374
391
|
}
|
|
375
392
|
|
|
376
393
|
val derived = new LinkedHashMap[String, Object]()
|
|
377
|
-
|
|
378
|
-
if ("" != keyre) derivedClean.put("keyre", keyre)
|
|
379
|
-
derived.put("clean", derivedClean)
|
|
394
|
+
derived.put("clean", cleancfg)
|
|
380
395
|
derived.put("featureorder", featureorder)
|
|
381
396
|
opts.put("__derived__", derived)
|
|
382
397
|
|
|
398
|
+
// Again over the merged result: the config's own defaults can carry one.
|
|
399
|
+
addSensitiveOptions(cleancfg, opts, "clean", "__derived__")
|
|
400
|
+
|
|
383
401
|
opts
|
|
384
402
|
}
|
|
403
|
+
|
|
404
|
+
// A feature's name is not a field name: a feature called `secrets` does not
|
|
405
|
+
// make every one of its options a secret. Entity blocks (entity settings,
|
|
406
|
+
// seeded records) hold no credential.
|
|
407
|
+
private def addSensitiveOptions(cfg: CleanConfig, m: JMap[String, Object], keys: String*): Unit = {
|
|
408
|
+
val top = omit(m, (keys :+ "feature" :+ "entity")*)
|
|
409
|
+
if (top.containsKey("test")) top.put("test", noEntity(top.get("test")))
|
|
410
|
+
Clean.addSensitiveWith(cfg, top)
|
|
411
|
+
m.get("feature") match {
|
|
412
|
+
case fm: JMap[_, _] => fm.values().forEach(v => Clean.addSensitiveWith(cfg, noEntity(v.asInstanceOf[Object])))
|
|
413
|
+
case fl: JList[_] => fl.forEach(v => Clean.addSensitiveWith(cfg, noEntity(v.asInstanceOf[Object])))
|
|
414
|
+
case other => Clean.addSensitiveWith(cfg, other)
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
private def noEntity(block: Object): Object = block match {
|
|
419
|
+
case bm: JMap[_, _] => omit(bm.asInstanceOf[JMap[String, Object]], "entity")
|
|
420
|
+
case other => other
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
private def omit(m: JMap[String, Object], keys: String*): JMap[String, Object] = {
|
|
424
|
+
val out = new LinkedHashMap[String, Object](m)
|
|
425
|
+
keys.foreach(k => out.remove(k))
|
|
426
|
+
out
|
|
427
|
+
}
|
|
385
428
|
}
|
|
386
429
|
|
|
387
430
|
object MakeFetchDef {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
package SCALAPACKAGE.utility
|
|
2
2
|
|
|
3
|
-
import java.
|
|
3
|
+
import java.io.{PrintWriter, StringWriter}
|
|
4
|
+
import java.nio.charset.StandardCharsets
|
|
5
|
+
import java.util.{ArrayList, Base64, IdentityHashMap, LinkedHashMap, List => JList, Map => JMap}
|
|
4
6
|
import SCALAPACKAGE.core._
|
|
5
7
|
import SCALAPACKAGE.utility.struct.Struct
|
|
6
8
|
|
|
@@ -9,16 +11,367 @@ object MakeContext {
|
|
|
9
11
|
new Context(ctxmap, basectx)
|
|
10
12
|
}
|
|
11
13
|
|
|
14
|
+
// The derived clean block: built by makeOptions from the raw input, grown by
|
|
15
|
+
// cleanAdd for as long as the client lives (features register later).
|
|
16
|
+
final class CleanConfig(
|
|
17
|
+
val active: Boolean,
|
|
18
|
+
val keys: List[String],
|
|
19
|
+
val values: ArrayList[String],
|
|
20
|
+
val mask: String,
|
|
21
|
+
val hint: Int,
|
|
22
|
+
val min: Int,
|
|
23
|
+
) {
|
|
24
|
+
// The options map this sits in can itself be printed; the registry never is.
|
|
25
|
+
override def toString: String = "CleanConfig(active=" + active + ")"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Everything that leaves the pipeline passes through clean; inside it data
|
|
29
|
+
// stays raw, so a hook can still read the header it must add to. See
|
|
30
|
+
// docs/explanation/secret-redaction.md.
|
|
12
31
|
object Clean {
|
|
13
|
-
|
|
32
|
+
private val MAXDEPTH = 32
|
|
33
|
+
private val CIRCULAR = "[circular]"
|
|
34
|
+
private val DROP = new Object()
|
|
35
|
+
private val SPLIT_RE = "\\s*,\\s*"
|
|
36
|
+
|
|
37
|
+
private def normkey(key: Object): String =
|
|
38
|
+
String.valueOf(key).toLowerCase.replace("-", "").replace("_", "")
|
|
39
|
+
|
|
40
|
+
private def splitkeys(keys: Object): List[String] =
|
|
41
|
+
(if (keys == null) "" else String.valueOf(keys)).split(SPLIT_RE).toList
|
|
42
|
+
.map(k => normkey(k)).filter(k => "" != k)
|
|
43
|
+
|
|
44
|
+
def splitvalues(values: Object): List[String] = values match {
|
|
45
|
+
case null => Nil
|
|
46
|
+
case l: JList[_] => l.asInstanceOf[JList[Object]].toArray.toList.collect { case s: String => s }
|
|
47
|
+
case v => String.valueOf(v).split(SPLIT_RE).toList.filter(s => "" != s)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private def count(v: Object, dflt: Int): Int = {
|
|
51
|
+
val n: Double = v match {
|
|
52
|
+
case n: java.lang.Number => n.doubleValue()
|
|
53
|
+
case s: String =>
|
|
54
|
+
try s.trim.toDouble
|
|
55
|
+
catch { case _: NumberFormatException => return dflt }
|
|
56
|
+
case _ => return dflt
|
|
57
|
+
}
|
|
58
|
+
if (n.isNaN || n.isInfinite || n < 0) dflt else Math.floor(n).toInt
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
def makeCleanConfig(cleanopts: Object): CleanConfig = {
|
|
62
|
+
val opts = Helpers.toMapAny(cleanopts)
|
|
63
|
+
def get(k: String): Object = if (opts == null) null else opts.get(k)
|
|
64
|
+
new CleanConfig(
|
|
65
|
+
java.lang.Boolean.FALSE != get("active"),
|
|
66
|
+
splitkeys(get("keys")),
|
|
67
|
+
new ArrayList[String](),
|
|
68
|
+
get("mask") match { case s: String => s; case _ => "[redacted]" },
|
|
69
|
+
count(get("hint"), 0),
|
|
70
|
+
Math.max(1, count(get("min"), 4)),
|
|
71
|
+
)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// A context without options (makeError accepts a bare one) still masks by
|
|
75
|
+
// the schema defaults.
|
|
76
|
+
private def cleanConfig(ctx: Context): CleanConfig = {
|
|
77
|
+
if (ctx != null && ctx.options != null) {
|
|
78
|
+
val derived = Helpers.toMapAny(ctx.options.get("__derived__"))
|
|
79
|
+
if (derived != null) derived.get("clean") match {
|
|
80
|
+
case c: CleanConfig => return c
|
|
81
|
+
case _ =>
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
makeCleanConfig(Schema.optspec.get("clean"))
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// encodeURIComponent, byte for byte: URLEncoder differs on space and `~!'()*`.
|
|
88
|
+
private def percentEncode(value: String): String = {
|
|
89
|
+
val out = new StringBuilder()
|
|
90
|
+
for (b <- value.getBytes(StandardCharsets.UTF_8)) {
|
|
91
|
+
val c = b & 0xff
|
|
92
|
+
val ch = c.toChar
|
|
93
|
+
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') ||
|
|
94
|
+
"-_.!~*'()".indexOf(ch) >= 0) out.append(ch)
|
|
95
|
+
else out.append('%').append(String.format("%02X", java.lang.Integer.valueOf(c)))
|
|
96
|
+
}
|
|
97
|
+
out.toString
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// The encoded forms a value travels in.
|
|
101
|
+
private def forms(value: String): List[String] = {
|
|
102
|
+
val out = new ArrayList[String]()
|
|
103
|
+
out.add(value)
|
|
104
|
+
def add(s: String): Unit = if ("" != s && !out.contains(s)) out.add(s)
|
|
105
|
+
try add(Base64.getEncoder.encodeToString(value.getBytes(StandardCharsets.UTF_8)))
|
|
106
|
+
catch { case _: RuntimeException => }
|
|
107
|
+
try add(percentEncode(value))
|
|
108
|
+
catch { case _: RuntimeException => }
|
|
109
|
+
try {
|
|
110
|
+
val j = Struct.jsonify(value)
|
|
111
|
+
if (j.length >= 2) add(j.substring(1, j.length - 1))
|
|
112
|
+
}
|
|
113
|
+
catch { case _: RuntimeException => }
|
|
114
|
+
out.toArray(new Array[String](0)).toList
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private[utility] def registerValue(cfg: CleanConfig, value: Object): Unit = value match {
|
|
118
|
+
case s: String if s.length >= cfg.min =>
|
|
119
|
+
cfg.synchronized {
|
|
120
|
+
var changed = false
|
|
121
|
+
for (form <- forms(s)) {
|
|
122
|
+
if (form.length >= cfg.min && !cfg.values.contains(form)) {
|
|
123
|
+
cfg.values.add(form)
|
|
124
|
+
changed = true
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (changed) cfg.values.sort(new java.util.Comparator[String] {
|
|
128
|
+
def compare(a: String, b: String): Int = Integer.compare(b.length, a.length)
|
|
129
|
+
})
|
|
130
|
+
}
|
|
131
|
+
case _ =>
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
def cleanAdd(ctx: Context, value: Object): Unit = registerValue(cleanConfig(ctx), value)
|
|
135
|
+
|
|
136
|
+
private def maskValue(cfg: CleanConfig, value: String): String =
|
|
137
|
+
if (0 < cfg.hint && value.length > 2 * cfg.hint) cfg.mask + value.substring(value.length - cfg.hint)
|
|
138
|
+
else cfg.mask
|
|
139
|
+
|
|
140
|
+
private def cleanString(cfg: CleanConfig, text: String): String = {
|
|
141
|
+
val values = cfg.synchronized { new ArrayList[String](cfg.values) }
|
|
142
|
+
var out = text
|
|
143
|
+
val it = values.iterator()
|
|
144
|
+
while (it.hasNext) {
|
|
145
|
+
val v = it.next()
|
|
146
|
+
if (out.contains(v)) out = out.replace(v, maskValue(cfg, v))
|
|
147
|
+
}
|
|
148
|
+
out
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
private def sensitiveKey(cfg: CleanConfig, key: Object): Boolean = {
|
|
152
|
+
if (key == null || key.isInstanceOf[java.lang.Number]) return false
|
|
153
|
+
val nk = normkey(key)
|
|
154
|
+
cfg.keys.exists(k => nk.contains(k))
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
private def isfunc(v: Object): Boolean = {
|
|
158
|
+
val cls = v.getClass
|
|
159
|
+
cls.isSynthetic || cls.getInterfaces.exists { i =>
|
|
160
|
+
i.getName.startsWith("java.util.function.") || i.getName.startsWith("scala.Function")
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
private def stackOf(err: Throwable): String = {
|
|
165
|
+
val sw = new StringWriter()
|
|
166
|
+
err.printStackTrace(new PrintWriter(sw))
|
|
167
|
+
sw.toString
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// The SDK's own objects have no serialisation hook, so this is the record
|
|
171
|
+
// each one leaves as. The context stays raw on the error and is not here.
|
|
172
|
+
private def record(v: Object): JMap[String, Object] = {
|
|
173
|
+
val out = new LinkedHashMap[String, Object]()
|
|
174
|
+
v match {
|
|
175
|
+
case e: Throwable =>
|
|
176
|
+
out.put("message", if (e.getMessage == null) "" else e.getMessage)
|
|
177
|
+
out.put("stack", stackOf(e))
|
|
178
|
+
e match {
|
|
179
|
+
case se: SdkError =>
|
|
180
|
+
out.put("sdk", se.sdk)
|
|
181
|
+
out.put("code", se.code)
|
|
182
|
+
out.put("status", java.lang.Integer.valueOf(se.status))
|
|
183
|
+
out.put("result", se.result)
|
|
184
|
+
out.put("spec", se.spec)
|
|
185
|
+
case _ =>
|
|
186
|
+
}
|
|
187
|
+
case s: Spec =>
|
|
188
|
+
out.put("method", s.method)
|
|
189
|
+
out.put("base", s.base)
|
|
190
|
+
out.put("prefix", s.prefix)
|
|
191
|
+
out.put("suffix", s.suffix)
|
|
192
|
+
out.put("path", s.path)
|
|
193
|
+
out.put("url", s.url)
|
|
194
|
+
out.put("params", s.params)
|
|
195
|
+
out.put("query", s.query)
|
|
196
|
+
out.put("headers", s.headers)
|
|
197
|
+
out.put("body", s.body)
|
|
198
|
+
out.put("step", s.step)
|
|
199
|
+
case r: Result =>
|
|
200
|
+
out.put("ok", java.lang.Boolean.valueOf(r.ok))
|
|
201
|
+
out.put("status", java.lang.Integer.valueOf(r.status))
|
|
202
|
+
out.put("statusText", r.statusText)
|
|
203
|
+
out.put("headers", r.headers)
|
|
204
|
+
out.put("body", r.body)
|
|
205
|
+
out.put("resdata", r.resdata)
|
|
206
|
+
out.put("resmatch", r.resmatch)
|
|
207
|
+
out.put("err", r.err)
|
|
208
|
+
out.put("paging", r.paging)
|
|
209
|
+
case r: Response =>
|
|
210
|
+
out.put("status", java.lang.Integer.valueOf(r.status))
|
|
211
|
+
out.put("statusText", r.statusText)
|
|
212
|
+
out.put("headers", r.headers)
|
|
213
|
+
out.put("body", r.body)
|
|
214
|
+
out.put("err", r.err)
|
|
215
|
+
case o: Operation =>
|
|
216
|
+
out.put("entity", o.entity)
|
|
217
|
+
out.put("name", o.name)
|
|
218
|
+
out.put("input", o.input)
|
|
219
|
+
case c: Context =>
|
|
220
|
+
out.put("id", c.id)
|
|
221
|
+
out.put("op", c.op)
|
|
222
|
+
out.put("spec", c.spec)
|
|
223
|
+
out.put("entity", c.entity)
|
|
224
|
+
out.put("result", c.result)
|
|
225
|
+
out.put("response", c.response)
|
|
226
|
+
out.put("meta", c.meta)
|
|
227
|
+
case e: Entity =>
|
|
228
|
+
out.put("name", e.getName())
|
|
229
|
+
out.put("data", try e.data() catch { case _: RuntimeException => null })
|
|
230
|
+
case _ =>
|
|
231
|
+
}
|
|
232
|
+
out
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// A masked plain-data copy: functions dropped, cycles cut, and nothing
|
|
236
|
+
// shared with the live value, whose spec must stay raw.
|
|
237
|
+
private def snapshot(cfg: CleanConfig, v: Object, key: Object, depth: Int,
|
|
238
|
+
seen: IdentityHashMap[Object, Object]): Object = {
|
|
239
|
+
if (v == null || (v eq Struct.UNDEF)) return v
|
|
240
|
+
|
|
241
|
+
v match {
|
|
242
|
+
case s: String => return if (sensitiveKey(cfg, key)) maskValue(cfg, s) else cleanString(cfg, s)
|
|
243
|
+
case _ =>
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (isfunc(v)) return DROP
|
|
247
|
+
|
|
248
|
+
v match {
|
|
249
|
+
case _: java.lang.Number | _: java.lang.Boolean | _: java.lang.Character =>
|
|
250
|
+
return if (sensitiveKey(cfg, key)) cfg.mask else v
|
|
251
|
+
case _ =>
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (MAXDEPTH <= depth || seen.containsKey(v)) return CIRCULAR
|
|
255
|
+
|
|
256
|
+
if (sensitiveKey(cfg, key)) return cfg.mask
|
|
257
|
+
|
|
258
|
+
seen.put(v, v)
|
|
259
|
+
try {
|
|
260
|
+
v match {
|
|
261
|
+
case l: JList[_] =>
|
|
262
|
+
val out = new ArrayList[Object]()
|
|
263
|
+
var i = 0
|
|
264
|
+
val it = l.asInstanceOf[JList[Object]].iterator()
|
|
265
|
+
while (it.hasNext) {
|
|
266
|
+
val s = snapshot(cfg, it.next(), java.lang.Integer.valueOf(i), depth + 1, seen)
|
|
267
|
+
if (s ne DROP) out.add(s)
|
|
268
|
+
i += 1
|
|
269
|
+
}
|
|
270
|
+
out
|
|
271
|
+
case m: JMap[_, _] => plain(cfg, m, depth, seen)
|
|
272
|
+
case _: Throwable | _: Spec | _: Result | _: Response | _: Operation | _: Context | _: Entity =>
|
|
273
|
+
plain(cfg, record(v), depth, seen)
|
|
274
|
+
case _ => cleanString(cfg, v.toString)
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
finally seen.remove(v)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
private def plain(cfg: CleanConfig, m: JMap[_, _], depth: Int,
|
|
281
|
+
seen: IdentityHashMap[Object, Object]): JMap[String, Object] = {
|
|
282
|
+
val out = new LinkedHashMap[String, Object]()
|
|
283
|
+
val it = m.asInstanceOf[JMap[Object, Object]].entrySet().iterator()
|
|
284
|
+
while (it.hasNext) {
|
|
285
|
+
val e = it.next()
|
|
286
|
+
val s = snapshot(cfg, e.getValue, e.getKey, depth + 1, seen)
|
|
287
|
+
if (s ne DROP) out.put(cleanName(cfg, out, String.valueOf(e.getKey)), s)
|
|
288
|
+
}
|
|
289
|
+
out
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// A registered value used as a map key is masked like any other string;
|
|
293
|
+
// keys that mask alike take a counter, so none is lost.
|
|
294
|
+
private def cleanName(cfg: CleanConfig, out: JMap[String, Object], key: String): String = {
|
|
295
|
+
val name = cleanString(cfg, key)
|
|
296
|
+
if (name == key || !out.containsKey(name)) return name
|
|
297
|
+
var i = 1
|
|
298
|
+
while (out.containsKey(name + "#" + i)) i += 1
|
|
299
|
+
name + "#" + i
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
private[utility] def cleanWith(cfg: CleanConfig, value: Object): Object = {
|
|
303
|
+
if (!cfg.active) return value
|
|
304
|
+
|
|
305
|
+
value match {
|
|
306
|
+
case s: String => return cleanString(cfg, s)
|
|
307
|
+
case err: SdkError =>
|
|
308
|
+
// Cleaned in place, since it is about to be thrown.
|
|
309
|
+
err.msg = cleanString(cfg, err.msg)
|
|
310
|
+
err.code = cleanString(cfg, err.code)
|
|
311
|
+
err.result = snapshot(cfg, err.result, "result", 1, new IdentityHashMap[Object, Object]())
|
|
312
|
+
err.spec = snapshot(cfg, err.spec, "spec", 1, new IdentityHashMap[Object, Object]())
|
|
313
|
+
return err
|
|
314
|
+
// A throwable's message is fixed, so a foreign one leaves as a cleaned
|
|
315
|
+
// copy of the SDK's own error, without the raw one as its cause.
|
|
316
|
+
case t: Throwable =>
|
|
317
|
+
return new SdkError("", cleanString(cfg, if (t.getMessage == null) String.valueOf(t) else t.getMessage), null)
|
|
318
|
+
case _ =>
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
val out = snapshot(cfg, value, null, 0, new IdentityHashMap[Object, Object]())
|
|
322
|
+
if (out eq DROP) null else out
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
def clean(ctx: Context, v: Object): Object = cleanWith(cleanConfig(ctx), v)
|
|
326
|
+
|
|
327
|
+
def cleanKey(ctx: Context, key: Object): Boolean = sensitiveKey(cleanConfig(ctx), key)
|
|
328
|
+
|
|
329
|
+
// Every scalar under a sensitive name, at any depth and of any shape: a
|
|
330
|
+
// credential mistyped as a map or a number is still a credential, and a
|
|
331
|
+
// message about it can quote it.
|
|
332
|
+
private[utility] def addSensitiveWith(cfg: CleanConfig, v: Object): Unit =
|
|
333
|
+
addSensitive(cfg, v, false, 0, new IdentityHashMap[Object, Object]())
|
|
334
|
+
|
|
335
|
+
private def addSensitive(cfg: CleanConfig, v: Object, under: Boolean, depth: Int,
|
|
336
|
+
seen: IdentityHashMap[Object, Object]): Unit = {
|
|
337
|
+
if (v == null || MAXDEPTH <= depth) return
|
|
338
|
+
v match {
|
|
339
|
+
case s: String => if (under) registerValue(cfg, s)
|
|
340
|
+
case n: java.lang.Number => if (under) registerValue(cfg, Struct.stringify(n))
|
|
341
|
+
case _ if seen.containsKey(v) =>
|
|
342
|
+
case m: JMap[_, _] =>
|
|
343
|
+
seen.put(v, v)
|
|
344
|
+
val it = m.asInstanceOf[JMap[Object, Object]].entrySet().iterator()
|
|
345
|
+
while (it.hasNext) {
|
|
346
|
+
val e = it.next()
|
|
347
|
+
addSensitive(cfg, e.getValue, under || sensitiveKey(cfg, e.getKey), depth + 1, seen)
|
|
348
|
+
}
|
|
349
|
+
case l: JList[_] =>
|
|
350
|
+
seen.put(v, v)
|
|
351
|
+
val it = l.asInstanceOf[JList[Object]].iterator()
|
|
352
|
+
while (it.hasNext) addSensitive(cfg, it.next(), under, depth + 1, seen)
|
|
353
|
+
case _ =>
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// The caller holds the explain map, so the cleaned copy is written back
|
|
358
|
+
// into it rather than swapped for it.
|
|
359
|
+
private[utility] def cleanExplain(ctx: Context): Unit = {
|
|
360
|
+
val explain = ctx.ctrl.explain
|
|
361
|
+
if (explain == null) return
|
|
362
|
+
val cleaned = Helpers.toMapAny(clean(ctx, explain))
|
|
363
|
+
if (cleaned != null && (cleaned ne explain)) {
|
|
364
|
+
explain.clear()
|
|
365
|
+
explain.putAll(cleaned)
|
|
366
|
+
}
|
|
367
|
+
}
|
|
14
368
|
}
|
|
15
369
|
|
|
16
370
|
object Done {
|
|
17
371
|
def done(ctx: Context): Object = {
|
|
18
372
|
if (ctx.ctrl.explain != null) {
|
|
19
|
-
|
|
20
|
-
val
|
|
21
|
-
val rm = Helpers.toMapAny(explainResult)
|
|
373
|
+
Clean.cleanExplain(ctx)
|
|
374
|
+
val rm = Helpers.toMapAny(ctx.ctrl.explain.get("result"))
|
|
22
375
|
if (rm != null) rm.remove("err")
|
|
23
376
|
}
|
|
24
377
|
|
|
@@ -6,6 +6,7 @@ import SCALAPACKAGE.core.Utility
|
|
|
6
6
|
object Register {
|
|
7
7
|
def registerAll(u: Utility): Unit = {
|
|
8
8
|
u.clean = (ctx, v) => Clean.clean(ctx, v)
|
|
9
|
+
u.cleanAdd = (ctx, v) => Clean.cleanAdd(ctx, v)
|
|
9
10
|
u.done = (ctx) => Done.done(ctx)
|
|
10
11
|
u.makeError = (ctx, err) => MakeError.makeError(ctx, err)
|
|
11
12
|
u.featureAdd = (ctx, f) => FeatureAdd.featureAdd(ctx, f)
|
|
@@ -158,4 +158,33 @@ public final class Context {
|
|
|
158
158
|
public func makeError(_ code: String, _ msg: String) -> ProjectNameError {
|
|
159
159
|
return ProjectNameError(code, msg, self)
|
|
160
160
|
}
|
|
161
|
+
|
|
162
|
+
// The record form: what the context says about the operation, never its
|
|
163
|
+
// client, options or config.
|
|
164
|
+
func rawRecord() -> VMap {
|
|
165
|
+
let record = VMap()
|
|
166
|
+
record.entries["id"] = .string(id)
|
|
167
|
+
record.entries["op"] = op == nil ? .noval : .nat(op!)
|
|
168
|
+
record.entries["spec"] = spec == nil ? .noval : .nat(spec!)
|
|
169
|
+
record.entries["entity"] = entity == nil ? .noval : .string(entity!.getName())
|
|
170
|
+
record.entries["result"] = result == nil ? .noval : .nat(result!)
|
|
171
|
+
record.entries["response"] = response == nil ? .noval : .nat(response!)
|
|
172
|
+
record.entries["meta"] = .map(meta)
|
|
173
|
+
return record
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// The serialised context leaves the pipeline (a logger, an error dump), so
|
|
177
|
+
// it is cleaned; the live fields stay raw for the pipeline's own use.
|
|
178
|
+
public func record() -> VMap {
|
|
179
|
+
let record = rawRecord()
|
|
180
|
+
guard let clean = utility?.clean else { return record }
|
|
181
|
+
return clean(self, .map(record)).asMap ?? record
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Every default print of a context is the cleaned record, `dump` included.
|
|
186
|
+
extension Context: CustomStringConvertible, CustomDebugStringConvertible, CustomReflectable {
|
|
187
|
+
public var description: String { "Context " + jsonify(.map(record()), indent: 0) }
|
|
188
|
+
public var debugDescription: String { description }
|
|
189
|
+
public var customMirror: Mirror { Mirror(self, children: ["record": jsonify(.map(record()), indent: 0)]) }
|
|
161
190
|
}
|
|
@@ -6,6 +6,7 @@ import Foundation
|
|
|
6
6
|
|
|
7
7
|
public final class Utility {
|
|
8
8
|
public var clean: ((Context, Value) -> Value)!
|
|
9
|
+
public var cleanAdd: ((Context, Value) -> Void)!
|
|
9
10
|
public var done: ((Context) throws -> Value)!
|
|
10
11
|
public var makeError: ((Context, Error?) throws -> Value)!
|
|
11
12
|
public var featureAdd: ((Context, BaseFeature) -> Void)!
|
|
@@ -49,6 +50,7 @@ public final class Utility {
|
|
|
49
50
|
public static func copy(_ src: Utility) -> Utility {
|
|
50
51
|
let u = Utility(noregister: true)
|
|
51
52
|
u.clean = src.clean
|
|
53
|
+
u.cleanAdd = src.cleanAdd
|
|
52
54
|
u.done = src.done
|
|
53
55
|
u.makeError = src.makeError
|
|
54
56
|
u.featureAdd = src.featureAdd
|
|
@@ -74,17 +74,18 @@ public final class AuditFeature: BaseFeature {
|
|
|
74
74
|
let entity = ctx.op?.entity ?? "_"
|
|
75
75
|
let opname = ctx.op?.name ?? "_"
|
|
76
76
|
|
|
77
|
-
let
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
77
|
+
let raw = VMap()
|
|
78
|
+
raw.entries["seq"] = .int(Int64(seq))
|
|
79
|
+
raw.entries["ts"] = .int(foptNow(options)())
|
|
80
|
+
raw.entries["actor"] = .string(actor)
|
|
81
|
+
raw.entries["entity"] = .string(entity)
|
|
82
|
+
raw.entries["op"] = .string(opname)
|
|
83
|
+
raw.entries["outcome"] = .string(outcome)
|
|
84
|
+
raw.entries["correlationId"] = .string(ctx.id)
|
|
85
85
|
if let result = ctx.result {
|
|
86
|
-
|
|
86
|
+
raw.entries["status"] = .int(Int64(result.status))
|
|
87
87
|
}
|
|
88
|
+
let record = fclean(ctx, raw)
|
|
88
89
|
|
|
89
90
|
records.append(record)
|
|
90
91
|
let max = foptInt(options, "max", 1000)
|
|
@@ -303,14 +303,16 @@ public final class CostFeature: BaseFeature {
|
|
|
303
303
|
bump(&actors, actor, amount)
|
|
304
304
|
|
|
305
305
|
seq += 1
|
|
306
|
+
// A typed record, so its strings are cleaned one by one rather than the
|
|
307
|
+
// record as a whole.
|
|
306
308
|
let record = CostRecord()
|
|
307
309
|
record.seq = seq
|
|
308
|
-
record.entity = entity
|
|
309
|
-
record.op = opname
|
|
310
|
-
record.actor = actor
|
|
310
|
+
record.entity = fcleanStr(ctx, entity)
|
|
311
|
+
record.op = fcleanStr(ctx, opname)
|
|
312
|
+
record.actor = fcleanStr(ctx, actor)
|
|
311
313
|
record.amount = amount
|
|
312
|
-
record.currency = currency
|
|
313
|
-
record.source = source
|
|
314
|
+
record.currency = fcleanStr(ctx, currency)
|
|
315
|
+
record.source = fcleanStr(ctx, source)
|
|
314
316
|
record.attempts = pending.attempts
|
|
315
317
|
last = record
|
|
316
318
|
|