@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
|
@@ -3,13 +3,357 @@
|
|
|
3
3
|
use strict;
|
|
4
4
|
use warnings;
|
|
5
5
|
|
|
6
|
+
use File::Basename ();
|
|
7
|
+
use Cwd ();
|
|
8
|
+
use Scalar::Util ();
|
|
9
|
+
use MIME::Base64 ();
|
|
10
|
+
|
|
11
|
+
my $__dir;
|
|
12
|
+
BEGIN { $__dir = File::Basename::dirname(Cwd::abs_path(__FILE__)) }
|
|
13
|
+
require(Cwd::abs_path("$__dir/../lib/Voxgig/Struct.pm"));
|
|
14
|
+
require(Cwd::abs_path("$__dir/../core/helpers.pm"));
|
|
15
|
+
require(Cwd::abs_path("$__dir/../schema.pm"));
|
|
16
|
+
|
|
17
|
+
# Everything that leaves the pipeline passes through clean: the error, the
|
|
18
|
+
# explain record, the serialised context, and whatever a feature emits.
|
|
19
|
+
# Two layers: every registered secret VALUE (and its encoded forms) is
|
|
20
|
+
# replaced wherever it appears in a string, and every value under a
|
|
21
|
+
# sensitive KEY name is masked whatever it holds. Inside the pipeline data
|
|
22
|
+
# stays raw, so a hook can still read the header it must add to.
|
|
23
|
+
package ProjectNameCleanSupport;
|
|
24
|
+
|
|
25
|
+
my $MAXDEPTH = 32;
|
|
26
|
+
my $CIRCULAR = '[circular]';
|
|
27
|
+
|
|
28
|
+
# Marks a value the copy omits (a coderef), as ts omits `undefined`.
|
|
29
|
+
my $DROP = \'drop';
|
|
30
|
+
|
|
31
|
+
sub _dropped {
|
|
32
|
+
my ($v) = @_;
|
|
33
|
+
return ref $v && Scalar::Util::refaddr($v) == Scalar::Util::refaddr($DROP) ? 1 : 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
sub normkey {
|
|
37
|
+
my ($key) = @_;
|
|
38
|
+
my $k = lc("$key");
|
|
39
|
+
$k =~ s/[-_]//g;
|
|
40
|
+
return $k;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
sub splitkeys {
|
|
44
|
+
my ($keys) = @_;
|
|
45
|
+
return [] unless defined $keys && !ref $keys;
|
|
46
|
+
return [ grep { '' ne $_ } map { normkey($_) } split /\s*,\s*/, "$keys" ];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# The comma-separated literal values a caller registers; a list is taken
|
|
50
|
+
# as-is for a caller that has one.
|
|
51
|
+
sub splitvalues {
|
|
52
|
+
my ($values) = @_;
|
|
53
|
+
if (Voxgig::Struct::islist($values)) {
|
|
54
|
+
return [ grep { defined $_ && !ref $_ } @$values ];
|
|
55
|
+
}
|
|
56
|
+
return [] unless defined $values && !ref $values;
|
|
57
|
+
return [ grep { '' ne $_ } split /\s*,\s*/, "$values" ];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# The spec carries numbers as strings, so every target reads it alike.
|
|
61
|
+
sub count {
|
|
62
|
+
my ($val, $dflt) = @_;
|
|
63
|
+
return $dflt unless defined $val && !ref $val && Scalar::Util::looks_like_number($val);
|
|
64
|
+
my $n = int($val);
|
|
65
|
+
return $n < 0 ? $dflt : $n;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
# The derived block make_options builds; a context without options
|
|
69
|
+
# (make_error is reached with a bare one) falls back to the schema
|
|
70
|
+
# defaults, so nothing leaves raw for want of a constructor. A plain hash
|
|
71
|
+
# stands in for a context before one exists (make_options).
|
|
72
|
+
sub config {
|
|
73
|
+
my ($ctx) = @_;
|
|
74
|
+
my $opts = (defined $ctx && ref $ctx && (Scalar::Util::reftype($ctx) // '') eq 'HASH')
|
|
75
|
+
? $ctx->{options} : undef;
|
|
76
|
+
my $derived = Voxgig::Struct::ismap($opts) ? $opts->{__derived__} : undef;
|
|
77
|
+
my $cfg = Voxgig::Struct::ismap($derived) ? $derived->{clean} : undef;
|
|
78
|
+
return $cfg if Voxgig::Struct::ismap($cfg) && Voxgig::Struct::islist($cfg->{values});
|
|
79
|
+
return make_config(ProjectNameSchema::optspec()->{clean});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
sub make_config {
|
|
83
|
+
my ($cleanopts) = @_;
|
|
84
|
+
my $o = Voxgig::Struct::ismap($cleanopts) ? $cleanopts : {};
|
|
85
|
+
my $min = count($o->{min}, 4);
|
|
86
|
+
return {
|
|
87
|
+
'active' => ProjectNameHelpers::is_false($o->{active}) ? 0 : 1,
|
|
88
|
+
'keys' => splitkeys($o->{keys}),
|
|
89
|
+
'values' => [],
|
|
90
|
+
'mask' => (defined $o->{mask} && !ref $o->{mask}) ? "$o->{mask}" : '[redacted]',
|
|
91
|
+
'hint' => count($o->{hint}, 0),
|
|
92
|
+
'min' => ($min < 1 ? 1 : $min),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
# encodeURIComponent, byte for byte: the form a query credential travels in.
|
|
97
|
+
sub pct {
|
|
98
|
+
my ($value) = @_;
|
|
99
|
+
my $b = "$value";
|
|
100
|
+
utf8::encode($b) if utf8::is_utf8($b);
|
|
101
|
+
$b =~ s/([^A-Za-z0-9\-_.!~*'()])/sprintf('%%%02X', ord($1))/ge;
|
|
102
|
+
return $b;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# The JSON string escape, as a JSON dump would write the value.
|
|
106
|
+
sub jsonesc {
|
|
107
|
+
my ($value) = @_;
|
|
108
|
+
my $s = "$value";
|
|
109
|
+
$s =~ s/\\/\\\\/g;
|
|
110
|
+
$s =~ s/"/\\"/g;
|
|
111
|
+
$s =~ s/\n/\\n/g;
|
|
112
|
+
$s =~ s/\r/\\r/g;
|
|
113
|
+
$s =~ s/\t/\\t/g;
|
|
114
|
+
$s =~ s/([\x00-\x1f])/sprintf('\\u%04x', ord($1))/ge;
|
|
115
|
+
return $s;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
# The encoded forms a value travels in: Basic and Bearer both carry base64,
|
|
119
|
+
# a query credential is percent-encoded, and a JSON dump escapes it.
|
|
120
|
+
sub forms {
|
|
121
|
+
my ($value) = @_;
|
|
122
|
+
my @out = ("$value");
|
|
123
|
+
my $add = sub {
|
|
124
|
+
my ($s) = @_;
|
|
125
|
+
push @out, $s if defined $s && '' ne $s && !grep { $_ eq $s } @out;
|
|
126
|
+
};
|
|
127
|
+
my $b = "$value";
|
|
128
|
+
utf8::encode($b) if utf8::is_utf8($b);
|
|
129
|
+
$add->(MIME::Base64::encode_base64($b, ''));
|
|
130
|
+
$add->(pct($value));
|
|
131
|
+
$add->(jsonesc($value));
|
|
132
|
+
return @out;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
# Register a secret value. Idempotent; shorter than `min` is not a secret
|
|
136
|
+
# the SDK can mask without blanking ordinary text.
|
|
137
|
+
sub add {
|
|
138
|
+
my ($ctx, $value) = @_;
|
|
139
|
+
my $cfg = config($ctx);
|
|
140
|
+
return unless defined $value && !ref $value && length("$value") >= $cfg->{min};
|
|
141
|
+
my $values = $cfg->{values};
|
|
142
|
+
my $changed = 0;
|
|
143
|
+
for my $form (forms($value)) {
|
|
144
|
+
next if length($form) < $cfg->{min} || grep { $_ eq $form } @$values;
|
|
145
|
+
push @$values, $form;
|
|
146
|
+
$changed = 1;
|
|
147
|
+
}
|
|
148
|
+
@$values = sort { length($b) <=> length($a) } @$values if $changed;
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
sub mask_value {
|
|
153
|
+
my ($cfg, $value) = @_;
|
|
154
|
+
my $hint = $cfg->{hint};
|
|
155
|
+
return $cfg->{mask} . substr($value, -$hint) if $hint > 0 && length($value) > 2 * $hint;
|
|
156
|
+
return $cfg->{mask};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# The scalar comes back untouched when no value matches, so a number stays
|
|
160
|
+
# a number.
|
|
161
|
+
sub clean_string {
|
|
162
|
+
my ($cfg, $text) = @_;
|
|
163
|
+
my $out = $text;
|
|
164
|
+
my $hit = 0;
|
|
165
|
+
for my $value (@{ $cfg->{values} }) {
|
|
166
|
+
next if index("$out", $value) < 0;
|
|
167
|
+
my $masked = mask_value($cfg, $value);
|
|
168
|
+
my $q = quotemeta $value;
|
|
169
|
+
$out = "$out";
|
|
170
|
+
$out =~ s/$q/$masked/g;
|
|
171
|
+
$hit = 1;
|
|
172
|
+
}
|
|
173
|
+
return $hit ? $out : $text;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
sub sensitive_key {
|
|
177
|
+
my ($cfg, $key) = @_;
|
|
178
|
+
return 0 unless defined $key && !ref $key;
|
|
179
|
+
my $nk = normkey($key);
|
|
180
|
+
for my $k (@{ $cfg->{keys} }) {
|
|
181
|
+
return 1 if index($nk, $k) >= 0;
|
|
182
|
+
}
|
|
183
|
+
return 0;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
# A plain-data copy of what is about to leave: TO_JSON is honoured (an
|
|
187
|
+
# entity gives its data, a context its record), coderefs are dropped,
|
|
188
|
+
# cycles are cut, and no live object is shared with the copy - masking the
|
|
189
|
+
# copy must never mask the pipeline's own spec. Any other blessed hash
|
|
190
|
+
# copies as its fields; the error keeps its context out of them.
|
|
191
|
+
sub snapshot {
|
|
192
|
+
my ($cfg, $val, $key, $depth, $seen) = @_;
|
|
193
|
+
return $val unless defined $val;
|
|
194
|
+
|
|
195
|
+
if (!ref $val) {
|
|
196
|
+
return sensitive_key($cfg, $key) ? mask_value($cfg, "$val") : clean_string($cfg, $val);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (Voxgig::Struct::is_jbool($val) || Voxgig::Struct::is_jnull($val) || Voxgig::Struct::is_none($val)) {
|
|
200
|
+
return sensitive_key($cfg, $key) ? $cfg->{mask} : $val;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
my $type = Scalar::Util::reftype($val) // '';
|
|
204
|
+
return $DROP unless 'HASH' eq $type || 'ARRAY' eq $type;
|
|
205
|
+
|
|
206
|
+
my $addr = Scalar::Util::refaddr($val);
|
|
207
|
+
return $CIRCULAR if $depth >= $MAXDEPTH || $seen->{$addr};
|
|
208
|
+
return $cfg->{mask} if sensitive_key($cfg, $key);
|
|
209
|
+
|
|
210
|
+
$seen->{$addr} = 1;
|
|
211
|
+
my $out;
|
|
212
|
+
if ('ARRAY' eq $type) {
|
|
213
|
+
$out = [];
|
|
214
|
+
for (my $i = 0; $i < @$val; $i++) {
|
|
215
|
+
my $v = snapshot($cfg, $val->[$i], "$i", $depth + 1, $seen);
|
|
216
|
+
push @$out, $v unless _dropped($v);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
elsif (Scalar::Util::blessed($val) && $val->isa('ProjectNameError')) {
|
|
220
|
+
$out = plain($cfg, $val, $depth, $seen);
|
|
221
|
+
$out->{message} = clean_string($cfg, defined $val->{msg} ? "$val->{msg}" : '');
|
|
222
|
+
}
|
|
223
|
+
elsif (Scalar::Util::blessed($val) && $val->can('TO_JSON')) {
|
|
224
|
+
my $json = eval { $val->TO_JSON };
|
|
225
|
+
$out = $@ ? plain($cfg, $val, $depth, $seen) : snapshot($cfg, $json, $key, $depth + 1, $seen);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
$out = plain($cfg, $val, $depth, $seen);
|
|
229
|
+
}
|
|
230
|
+
delete $seen->{$addr};
|
|
231
|
+
return $out;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
sub plain {
|
|
235
|
+
my ($cfg, $val, $depth, $seen) = @_;
|
|
236
|
+
my $out = {};
|
|
237
|
+
for my $k (sort keys %$val) {
|
|
238
|
+
my $v = snapshot($cfg, $val->{$k}, $k, $depth + 1, $seen);
|
|
239
|
+
$out->{ clean_name($cfg, $out, $k) } = $v unless _dropped($v);
|
|
240
|
+
}
|
|
241
|
+
return $out;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
# A registered value used as a property name is masked like any other
|
|
245
|
+
# string; names that mask alike take a counter, so none is lost. Callers
|
|
246
|
+
# visit keys sorted, so the counters are stable.
|
|
247
|
+
sub clean_name {
|
|
248
|
+
my ($cfg, $out, $key) = @_;
|
|
249
|
+
my $name = clean_string($cfg, $key);
|
|
250
|
+
return $name if $name eq $key || !exists $out->{$name};
|
|
251
|
+
my $i = 1;
|
|
252
|
+
$i++ while exists $out->{"$name#$i"};
|
|
253
|
+
return "$name#$i";
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
# Clean a value on its way out. A string is redacted; an SDK error is
|
|
257
|
+
# redacted IN PLACE (it is about to be thrown, and its identity matters to
|
|
258
|
+
# the caller); another blessed object is not this SDK's to rewrite and comes
|
|
259
|
+
# back as it is; anything else comes back as a masked plain-data copy.
|
|
260
|
+
sub clean {
|
|
261
|
+
my ($ctx, $val) = @_;
|
|
262
|
+
my $cfg = config($ctx);
|
|
263
|
+
|
|
264
|
+
return $val unless $cfg->{active};
|
|
265
|
+
return $val unless defined $val;
|
|
266
|
+
return clean_string($cfg, $val) unless ref $val;
|
|
267
|
+
|
|
268
|
+
if (Scalar::Util::blessed($val)) {
|
|
269
|
+
return $val unless $val->isa('ProjectNameError');
|
|
270
|
+
$val->{msg} = clean_string($cfg, "$val->{msg}") if defined $val->{msg};
|
|
271
|
+
for my $k (sort keys %$val) {
|
|
272
|
+
next if 'msg' eq $k;
|
|
273
|
+
my $v = $val->{$k};
|
|
274
|
+
if (defined $v && !ref $v) {
|
|
275
|
+
$v = sensitive_key($cfg, $k) ? mask_value($cfg, "$v") : clean_string($cfg, $v);
|
|
276
|
+
}
|
|
277
|
+
elsif (ref $v && (Scalar::Util::reftype($v) // '') =~ /\A(?:HASH|ARRAY)\z/) {
|
|
278
|
+
$v = snapshot($cfg, $v, $k, 1, {});
|
|
279
|
+
}
|
|
280
|
+
my $name = clean_string($cfg, $k);
|
|
281
|
+
delete $val->{$k} if $name ne $k;
|
|
282
|
+
$val->{ $name eq $k ? $k : clean_name($cfg, $val, $k) } = $v;
|
|
283
|
+
}
|
|
284
|
+
return $val;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
my $out = snapshot($cfg, $val, undef, 0, {});
|
|
288
|
+
return _dropped($out) ? undef : $out;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
# Every scalar under a sensitive name, at any depth and of any shape: a
|
|
292
|
+
# credential mistyped as a map or a number is still a credential, and the
|
|
293
|
+
# validation error that rejects it quotes it.
|
|
294
|
+
sub add_sensitive {
|
|
295
|
+
my ($ctx, $val, $under, $depth, $seen) = @_;
|
|
296
|
+
$depth //= 0;
|
|
297
|
+
$seen //= {};
|
|
298
|
+
return if !defined $val || $depth >= $MAXDEPTH;
|
|
299
|
+
if (!ref $val) {
|
|
300
|
+
add($ctx, "$val") if $under;
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
my $type = Scalar::Util::reftype($val) // '';
|
|
304
|
+
return unless 'HASH' eq $type || 'ARRAY' eq $type;
|
|
305
|
+
return if $seen->{ Scalar::Util::refaddr($val) }++;
|
|
306
|
+
if ('HASH' eq $type) {
|
|
307
|
+
add_sensitive($ctx, $val->{$_}, $under || key($ctx, $_), $depth + 1, $seen) for keys %$val;
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
add_sensitive($ctx, $_, $under, $depth + 1, $seen) for @$val;
|
|
311
|
+
}
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
# A feature's name is not a field name: only the sensitive names inside its
|
|
316
|
+
# settings count, so `secrets` does not make every setting a secret. Entity
|
|
317
|
+
# blocks (per-entity settings, seeded records) hold no credential.
|
|
318
|
+
sub add_options {
|
|
319
|
+
my ($ctx, $opts) = @_;
|
|
320
|
+
my %scan = %$opts;
|
|
321
|
+
my $feature = delete $scan{feature};
|
|
322
|
+
delete $scan{entity};
|
|
323
|
+
$scan{test} = no_entity($scan{test}) if exists $scan{test};
|
|
324
|
+
add_sensitive($ctx, \%scan);
|
|
325
|
+
my @blocks = Voxgig::Struct::ismap($feature) ? values %$feature
|
|
326
|
+
: Voxgig::Struct::islist($feature) ? @$feature : ($feature);
|
|
327
|
+
add_sensitive($ctx, no_entity($_)) for @blocks;
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
sub no_entity {
|
|
332
|
+
my ($block) = @_;
|
|
333
|
+
return $block unless Voxgig::Struct::ismap($block);
|
|
334
|
+
my %copy = %$block;
|
|
335
|
+
delete $copy{entity};
|
|
336
|
+
return \%copy;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
# Is this key name sensitive under the context's clean configuration?
|
|
340
|
+
sub key {
|
|
341
|
+
my ($ctx, $key) = @_;
|
|
342
|
+
return sensitive_key(config($ctx), $key);
|
|
343
|
+
}
|
|
344
|
+
|
|
6
345
|
package ProjectNameUtilities;
|
|
7
346
|
|
|
8
347
|
our %REGISTRY;
|
|
9
348
|
|
|
10
349
|
$REGISTRY{clean} = sub {
|
|
11
350
|
my ($ctx, $val) = @_;
|
|
12
|
-
return $val;
|
|
351
|
+
return ProjectNameCleanSupport::clean($ctx, $val);
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
$REGISTRY{clean_add} = sub {
|
|
355
|
+
my ($ctx, $value) = @_;
|
|
356
|
+
return ProjectNameCleanSupport::add($ctx, $value);
|
|
13
357
|
};
|
|
14
358
|
|
|
15
359
|
1;
|
|
@@ -5,6 +5,7 @@ use warnings;
|
|
|
5
5
|
|
|
6
6
|
use File::Basename ();
|
|
7
7
|
use Cwd ();
|
|
8
|
+
use Scalar::Util ();
|
|
8
9
|
|
|
9
10
|
my $__dir;
|
|
10
11
|
BEGIN { $__dir = File::Basename::dirname(Cwd::abs_path(__FILE__)) }
|
|
@@ -17,12 +18,7 @@ our %REGISTRY;
|
|
|
17
18
|
|
|
18
19
|
$REGISTRY{done} = sub {
|
|
19
20
|
my ($ctx) = @_;
|
|
20
|
-
|
|
21
|
-
if ($ctrl->{explain}) {
|
|
22
|
-
$ctrl->{explain} = $ctx->{utility}{clean}->($ctx, $ctrl->{explain});
|
|
23
|
-
my $er = $ctrl->{explain}{result};
|
|
24
|
-
delete $er->{err} if Voxgig::Struct::ismap($er);
|
|
25
|
-
}
|
|
21
|
+
$REGISTRY{clean_explain}->($ctx);
|
|
26
22
|
if ($ctx->{result} && $ctx->{result}{ok}) {
|
|
27
23
|
return $ctx->{result}{resdata};
|
|
28
24
|
}
|
|
@@ -31,4 +27,26 @@ $REGISTRY{done} = sub {
|
|
|
31
27
|
return $ctx->{utility}{make_error}->($ctx, undef);
|
|
32
28
|
};
|
|
33
29
|
|
|
30
|
+
# The caller's own hash is the explain record (the control is built from it,
|
|
31
|
+
# and a stream copies only its ctrl), so the cleaned copy is written back
|
|
32
|
+
# INTO it: assigning a fresh hash would leave the caller holding the raw one.
|
|
33
|
+
$REGISTRY{clean_explain} = sub {
|
|
34
|
+
my ($ctx) = @_;
|
|
35
|
+
my $explain = $ctx->{ctrl}{explain};
|
|
36
|
+
return unless Voxgig::Struct::ismap($explain);
|
|
37
|
+
my $cleaned = $ctx->{utility}{clean}->($ctx, $explain);
|
|
38
|
+
if (Voxgig::Struct::ismap($cleaned)
|
|
39
|
+
&& Scalar::Util::refaddr($cleaned) != Scalar::Util::refaddr($explain)) {
|
|
40
|
+
%$explain = %$cleaned;
|
|
41
|
+
}
|
|
42
|
+
# A copy: with clean off, explain.result is the live result make_error reads.
|
|
43
|
+
my $er = $explain->{result};
|
|
44
|
+
if (Voxgig::Struct::ismap($er)) {
|
|
45
|
+
my %pruned = %$er;
|
|
46
|
+
delete $pruned{err};
|
|
47
|
+
$explain->{result} = \%pruned;
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
};
|
|
51
|
+
|
|
34
52
|
1;
|
|
@@ -13,6 +13,7 @@ require(Cwd::abs_path("$__dir/../core/context.pm"));
|
|
|
13
13
|
require(Cwd::abs_path("$__dir/../core/operation.pm"));
|
|
14
14
|
require(Cwd::abs_path("$__dir/../core/result.pm"));
|
|
15
15
|
require(Cwd::abs_path("$__dir/../core/error.pm"));
|
|
16
|
+
require(Cwd::abs_path("$__dir/clean.pm"));
|
|
16
17
|
|
|
17
18
|
package ProjectNameUtilities;
|
|
18
19
|
|
|
@@ -33,11 +34,14 @@ $REGISTRY{make_error} = sub {
|
|
|
33
34
|
$err = $result->{err} if !defined $err;
|
|
34
35
|
$err = $ctx->make_error('unknown', 'unknown error') if !defined $err;
|
|
35
36
|
|
|
37
|
+
# A bare context (no client, no utility) still cleans, through the
|
|
38
|
+
# schema defaults.
|
|
39
|
+
my $clean = ($ctx->{utility} && $ctx->{utility}{clean}) || $REGISTRY{clean};
|
|
40
|
+
|
|
36
41
|
my $errmsg = (Scalar::Util::blessed($err) && $err->isa('ProjectNameError'))
|
|
37
42
|
? $err->{msg} : "$err";
|
|
38
43
|
$errmsg =~ s/\s+\z//;
|
|
39
|
-
my $msg = "ProjectNameSDK: $opname: $errmsg";
|
|
40
|
-
$msg = $ctx->{utility}{clean}->($ctx, $msg);
|
|
44
|
+
my $msg = $clean->($ctx, "ProjectNameSDK: $opname: $errmsg");
|
|
41
45
|
|
|
42
46
|
$result->{err} = undef;
|
|
43
47
|
my $spec = $ctx->{spec};
|
|
@@ -46,12 +50,21 @@ $REGISTRY{make_error} = sub {
|
|
|
46
50
|
$ctx->{ctrl}{explain}{err} = { 'message' => $msg };
|
|
47
51
|
}
|
|
48
52
|
|
|
53
|
+
# The context stays reachable for a debugger (`$err->ctx`) and is part of
|
|
54
|
+
# no dump of the error; result and spec are cleaned COPIES, so masking
|
|
55
|
+
# them never masks the pipeline's own objects.
|
|
49
56
|
my $sdk_err = ProjectNameError->new('', $msg, $ctx);
|
|
50
|
-
$sdk_err->{result} = $
|
|
51
|
-
$sdk_err->{spec} = $
|
|
57
|
+
$sdk_err->{result} = $clean->($ctx, $result);
|
|
58
|
+
$sdk_err->{spec} = $clean->($ctx, $spec);
|
|
52
59
|
$sdk_err->{code} = $err->{code}
|
|
53
60
|
if Scalar::Util::blessed($err) && $err->isa('ProjectNameError');
|
|
54
61
|
|
|
62
|
+
# Promote the HTTP status to the top level, so a consumer can branch on
|
|
63
|
+
# `$err->{status}` instead of reaching into `$err->{result}`.
|
|
64
|
+
$sdk_err->{status} = defined $result->{status} ? $result->{status} : -1;
|
|
65
|
+
|
|
66
|
+
$clean->($ctx, $sdk_err);
|
|
67
|
+
|
|
55
68
|
$ctx->{ctrl}{err} = $sdk_err;
|
|
56
69
|
|
|
57
70
|
# Fire PreUnexpected so observability features (metrics, telemetry, audit,
|
|
@@ -11,6 +11,7 @@ BEGIN { $__dir = File::Basename::dirname(Cwd::abs_path(__FILE__)) }
|
|
|
11
11
|
require(Cwd::abs_path("$__dir/../lib/Voxgig/Struct.pm"));
|
|
12
12
|
require(Cwd::abs_path("$__dir/../core/helpers.pm"));
|
|
13
13
|
require(Cwd::abs_path("$__dir/../schema.pm"));
|
|
14
|
+
require(Cwd::abs_path("$__dir/clean.pm"));
|
|
14
15
|
|
|
15
16
|
package ProjectNameUtilities;
|
|
16
17
|
|
|
@@ -89,6 +90,27 @@ $REGISTRY{make_options} = sub {
|
|
|
89
90
|
$opts = {} unless Voxgig::Struct::ismap($opts);
|
|
90
91
|
delete $opts->{extend};
|
|
91
92
|
|
|
93
|
+
my $config = $ctx->{config} || {};
|
|
94
|
+
my $cfgopts = Voxgig::Struct::ismap($config->{options}) ? $config->{options} : {};
|
|
95
|
+
|
|
96
|
+
# The secret registry exists BEFORE validation, fed from the raw input, so
|
|
97
|
+
# the constructor's own rejection of a mistyped credential is clean too.
|
|
98
|
+
my $cleancfg = ProjectNameCleanSupport::make_config(Voxgig::Struct::merge([
|
|
99
|
+
{},
|
|
100
|
+
grep { Voxgig::Struct::ismap($_) }
|
|
101
|
+
(Voxgig::Struct::clone(ProjectNameSchema::optspec()->{clean}),
|
|
102
|
+
Voxgig::Struct::clone($cfgopts->{clean}), $opts->{clean}),
|
|
103
|
+
]));
|
|
104
|
+
my $cleanctx = { 'options' => { '__derived__' => { 'clean' => $cleancfg } } };
|
|
105
|
+
my %rawscan = %$opts;
|
|
106
|
+
delete $rawscan{clean};
|
|
107
|
+
ProjectNameCleanSupport::add_options($cleanctx, \%rawscan);
|
|
108
|
+
for my $block ($cfgopts, $opts) {
|
|
109
|
+
for my $raw (@{ ProjectNameCleanSupport::splitvalues(ProjectNameHelpers::gpath($block, 'clean.values')) }) {
|
|
110
|
+
ProjectNameCleanSupport::add($cleanctx, $raw);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
92
114
|
# Feature add-order. options.feature may be given as an ordered ARRAY of
|
|
93
115
|
# { name, active, ...opts } entries (the array position IS the order in
|
|
94
116
|
# which features are added), or as a { name => {opts} } map. Normalize an
|
|
@@ -111,9 +133,6 @@ $REGISTRY{make_options} = sub {
|
|
|
111
133
|
$opts->{feature} = \%fmap;
|
|
112
134
|
}
|
|
113
135
|
|
|
114
|
-
my $config = $ctx->{config} || {};
|
|
115
|
-
my $cfgopts = Voxgig::Struct::ismap($config->{options}) ? $config->{options} : {};
|
|
116
|
-
|
|
117
136
|
# THE OPTION SPEC IS GENERATED, NOT WRITTEN HERE.
|
|
118
137
|
#
|
|
119
138
|
# Built from the model: `main.kit.optspec` for the standard options, plus one
|
|
@@ -146,7 +165,10 @@ $REGISTRY{make_options} = sub {
|
|
|
146
165
|
# TARGETS, so without this one client's options (headers, server, ...) are
|
|
147
166
|
# written into the shared config and inherited by every client after it.
|
|
148
167
|
my $merged = Voxgig::Struct::merge([{}, Voxgig::Struct::clone($cfgopts), $opts]);
|
|
149
|
-
my $validated = Voxgig::Struct::validate($merged, $optspec);
|
|
168
|
+
my $validated = eval { Voxgig::Struct::validate($merged, $optspec) };
|
|
169
|
+
if (my $verr = $@) {
|
|
170
|
+
die ProjectNameCleanSupport::clean($cleanctx, $verr);
|
|
171
|
+
}
|
|
150
172
|
$opts = Voxgig::Struct::ismap($validated) ? $validated : {};
|
|
151
173
|
|
|
152
174
|
# Restore the suppression the optspec default would otherwise erase.
|
|
@@ -162,15 +184,6 @@ $REGISTRY{make_options} = sub {
|
|
|
162
184
|
$opts->{extend} = $extend_raw;
|
|
163
185
|
}
|
|
164
186
|
|
|
165
|
-
my $clean_keys = ProjectNameHelpers::gpath($opts, 'clean.keys');
|
|
166
|
-
$clean_keys = 'key,token,id' unless defined $clean_keys && !ref $clean_keys;
|
|
167
|
-
my @parts;
|
|
168
|
-
for my $p (split /,/, $clean_keys) {
|
|
169
|
-
$p =~ s/^\s+|\s+$//g;
|
|
170
|
-
push @parts, Voxgig::Struct::escre($p) if '' ne $p;
|
|
171
|
-
}
|
|
172
|
-
my $keyre = join('|', @parts);
|
|
173
|
-
|
|
174
187
|
# Resolve the feature add-order: an explicit array order (above) wins;
|
|
175
188
|
# otherwise order the map test-first, then the remaining names sorted, so
|
|
176
189
|
# the outcome is deterministic and `test` is always the base transport.
|
|
@@ -197,10 +210,16 @@ $REGISTRY{make_options} = sub {
|
|
|
197
210
|
}
|
|
198
211
|
|
|
199
212
|
$opts->{__derived__} = {
|
|
200
|
-
'clean' =>
|
|
213
|
+
'clean' => $cleancfg,
|
|
201
214
|
'featureorder' => \@featureorder,
|
|
202
215
|
};
|
|
203
216
|
|
|
217
|
+
# Again over the merged result: the config's own defaults can carry one.
|
|
218
|
+
# The extend instances are live objects, not option data.
|
|
219
|
+
my %scan = %$opts;
|
|
220
|
+
delete @scan{qw(__derived__ extend clean)};
|
|
221
|
+
ProjectNameCleanSupport::add_options($cleanctx, \%scan);
|
|
222
|
+
|
|
204
223
|
return $opts;
|
|
205
224
|
};
|
|
206
225
|
|
|
@@ -11,7 +11,7 @@ require_once __DIR__ . '/Response.php';
|
|
|
11
11
|
require_once __DIR__ . '/Error.php';
|
|
12
12
|
require_once __DIR__ . '/Helpers.php';
|
|
13
13
|
|
|
14
|
-
class ProjectNameContext
|
|
14
|
+
class ProjectNameContext implements \JsonSerializable
|
|
15
15
|
{
|
|
16
16
|
public string $id;
|
|
17
17
|
public array $out;
|
|
@@ -149,4 +149,27 @@ class ProjectNameContext
|
|
|
149
149
|
{
|
|
150
150
|
return new ProjectNameError($code, $msg, $this);
|
|
151
151
|
}
|
|
152
|
+
|
|
153
|
+
// The serialised context leaves the pipeline (a logger, a dump), so it
|
|
154
|
+
// is cleaned; the live fields stay raw for the pipeline's own use.
|
|
155
|
+
public function jsonSerialize(): mixed
|
|
156
|
+
{
|
|
157
|
+
$record = [
|
|
158
|
+
'id' => $this->id,
|
|
159
|
+
'op' => $this->op,
|
|
160
|
+
'spec' => $this->spec,
|
|
161
|
+
'entity' => $this->entity,
|
|
162
|
+
'result' => $this->result,
|
|
163
|
+
'response' => $this->response,
|
|
164
|
+
'meta' => $this->meta,
|
|
165
|
+
];
|
|
166
|
+
$clean = null === $this->utility ? null : $this->utility->clean;
|
|
167
|
+
return is_callable($clean) ? $clean($this, $record) : $record;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
public function __debugInfo(): array
|
|
171
|
+
{
|
|
172
|
+
$record = $this->jsonSerialize();
|
|
173
|
+
return is_array($record) ? $record : ['record' => $record];
|
|
174
|
+
}
|
|
152
175
|
}
|
|
@@ -3,13 +3,12 @@ declare(strict_types=1);
|
|
|
3
3
|
|
|
4
4
|
// ProjectName SDK error
|
|
5
5
|
|
|
6
|
-
class ProjectNameError extends \Exception
|
|
6
|
+
class ProjectNameError extends \Exception implements \JsonSerializable
|
|
7
7
|
{
|
|
8
8
|
public bool $is_sdk_error;
|
|
9
9
|
public string $sdk;
|
|
10
10
|
public string $sdk_code;
|
|
11
11
|
public string $msg;
|
|
12
|
-
public mixed $ctx;
|
|
13
12
|
public mixed $result;
|
|
14
13
|
public mixed $spec;
|
|
15
14
|
|
|
@@ -24,6 +23,12 @@ class ProjectNameError extends \Exception
|
|
|
24
23
|
// same field; php needs it spelled out because the class is typed.
|
|
25
24
|
public int $status;
|
|
26
25
|
|
|
26
|
+
// The context stays reachable for a debugger (`ctx()`) and out of every
|
|
27
|
+
// serialiser: print_r and json_encode take the record below, and
|
|
28
|
+
// var_export renders a closure as empty where a property would dump the
|
|
29
|
+
// context's whole object graph, options and credential included.
|
|
30
|
+
private ?\Closure $ctxref;
|
|
31
|
+
|
|
27
32
|
public function __construct(string $code = '', string $msg = '', mixed $ctx = null)
|
|
28
33
|
{
|
|
29
34
|
parent::__construct($msg);
|
|
@@ -31,12 +36,19 @@ class ProjectNameError extends \Exception
|
|
|
31
36
|
$this->sdk = 'ProjectName';
|
|
32
37
|
$this->sdk_code = $code;
|
|
33
38
|
$this->msg = $msg;
|
|
34
|
-
$this->
|
|
39
|
+
$this->ctxref = null === $ctx ? null : static function () use ($ctx): mixed {
|
|
40
|
+
return $ctx;
|
|
41
|
+
};
|
|
35
42
|
$this->result = null;
|
|
36
43
|
$this->spec = null;
|
|
37
44
|
$this->status = -1;
|
|
38
45
|
}
|
|
39
46
|
|
|
47
|
+
public function ctx(): mixed
|
|
48
|
+
{
|
|
49
|
+
return null === $this->ctxref ? null : ($this->ctxref)();
|
|
50
|
+
}
|
|
51
|
+
|
|
40
52
|
public function error(): string
|
|
41
53
|
{
|
|
42
54
|
return $this->msg;
|
|
@@ -46,4 +58,23 @@ class ProjectNameError extends \Exception
|
|
|
46
58
|
{
|
|
47
59
|
return $this->msg;
|
|
48
60
|
}
|
|
61
|
+
|
|
62
|
+
// What make_error attached is already cleaned; the context is not part
|
|
63
|
+
// of the record.
|
|
64
|
+
public function jsonSerialize(): array
|
|
65
|
+
{
|
|
66
|
+
return [
|
|
67
|
+
'sdk' => $this->sdk,
|
|
68
|
+
'code' => $this->sdk_code,
|
|
69
|
+
'message' => $this->getMessage(),
|
|
70
|
+
'status' => $this->status,
|
|
71
|
+
'result' => $this->result,
|
|
72
|
+
'spec' => $this->spec,
|
|
73
|
+
];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
public function __debugInfo(): array
|
|
77
|
+
{
|
|
78
|
+
return $this->jsonSerialize();
|
|
79
|
+
}
|
|
49
80
|
}
|
|
@@ -6,6 +6,8 @@ declare(strict_types=1);
|
|
|
6
6
|
class ProjectNameUtility
|
|
7
7
|
{
|
|
8
8
|
public mixed $clean = null;
|
|
9
|
+
public mixed $clean_add = null;
|
|
10
|
+
public mixed $clean_explain = null;
|
|
9
11
|
public mixed $done = null;
|
|
10
12
|
public mixed $make_error = null;
|
|
11
13
|
public mixed $feature_add = null;
|
|
@@ -57,6 +59,8 @@ class ProjectNameUtility
|
|
|
57
59
|
{
|
|
58
60
|
$u = new ProjectNameUtility();
|
|
59
61
|
$u->clean = $src->clean;
|
|
62
|
+
$u->clean_add = $src->clean_add;
|
|
63
|
+
$u->clean_explain = $src->clean_explain;
|
|
60
64
|
$u->done = $src->done;
|
|
61
65
|
$u->make_error = $src->make_error;
|
|
62
66
|
$u->feature_add = $src->feature_add;
|
|
@@ -86,7 +86,7 @@ class ProjectNameAuditFeature extends ProjectNameBaseFeature
|
|
|
86
86
|
: ($this->options['actor'] ?? null);
|
|
87
87
|
$actor = (is_string($actor) && $actor !== '') ? $actor : 'anonymous';
|
|
88
88
|
|
|
89
|
-
$record = [
|
|
89
|
+
$record = ($ctx->utility->clean)($ctx, [
|
|
90
90
|
'seq' => $this->seq,
|
|
91
91
|
'ts' => $this->_now(),
|
|
92
92
|
'actor' => $actor,
|
|
@@ -95,7 +95,7 @@ class ProjectNameAuditFeature extends ProjectNameBaseFeature
|
|
|
95
95
|
'outcome' => $outcome,
|
|
96
96
|
'status' => $ctx->result !== null ? $ctx->result->status : null,
|
|
97
97
|
'correlationId' => $ctx->id,
|
|
98
|
-
];
|
|
98
|
+
]);
|
|
99
99
|
|
|
100
100
|
$client = $this->client;
|
|
101
101
|
$client->_audit['records'][] = $record;
|