@voxgig/sdkgen 4.32.1 → 4.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/voxgig-sdkgen +1 -1
- package/dist/action/copies.d.ts +21 -0
- package/dist/action/copies.js +146 -0
- package/dist/action/copies.js.map +1 -0
- package/dist/action/doctor.d.ts +15 -2
- package/dist/action/doctor.js +169 -23
- package/dist/action/doctor.js.map +1 -1
- package/dist/action/edition.js +6 -2
- package/dist/action/edition.js.map +1 -1
- package/dist/action/feature.js +6 -2
- package/dist/action/feature.js.map +1 -1
- package/dist/action/package.js +28 -10
- package/dist/action/package.js.map +1 -1
- package/dist/action/remove.js +2 -0
- package/dist/action/remove.js.map +1 -1
- package/dist/action/resolve.d.ts +1 -0
- package/dist/action/resolve.js +10 -2
- package/dist/action/resolve.js.map +1 -1
- package/dist/action/target.js +6 -2
- package/dist/action/target.js.map +1 -1
- package/dist/helpers/naming.js +1 -1
- package/dist/helpers/naming.js.map +1 -1
- package/dist/sdkgen.d.ts +2 -1
- package/dist/sdkgen.js +36 -3
- package/dist/sdkgen.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/model/sdkgen.aontu +7 -1
- package/package.json +1 -1
- package/project/.sdk/model/feature/debug.aontu +3 -1
- package/project/.sdk/src/cmp/c/PrepareAuth_c.ts +8 -28
- package/project/.sdk/src/cmp/c/TestClean_c.ts +774 -0
- package/project/.sdk/src/cmp/c/Test_c.ts +3 -0
- package/project/.sdk/src/cmp/c/fragment/Entity.fragment.c +16 -5
- package/project/.sdk/src/cmp/c/fragment/Main.fragment.c +1 -1
- package/project/.sdk/src/cmp/clojure/PrepareAuth_clojure.ts +3 -0
- package/project/.sdk/src/cmp/clojure/TestClean_clojure.ts +473 -0
- package/project/.sdk/src/cmp/clojure/Test_clojure.ts +6 -0
- package/project/.sdk/src/cmp/clojure/fragment/Entity.fragment.clj +18 -8
- package/project/.sdk/src/cmp/cpp/PrepareAuth_cpp.ts +3 -0
- package/project/.sdk/src/cmp/cpp/TestClean_cpp.ts +782 -0
- package/project/.sdk/src/cmp/cpp/TestEntity_cpp.ts +1 -1
- package/project/.sdk/src/cmp/cpp/Test_cpp.ts +2 -0
- package/project/.sdk/src/cmp/csharp/PrepareAuth_csharp.ts +3 -0
- package/project/.sdk/src/cmp/csharp/TestClean_csharp.ts +887 -0
- package/project/.sdk/src/cmp/csharp/Test_csharp.ts +2 -0
- package/project/.sdk/src/cmp/csharp/fragment/EntityBase.fragment.cs +68 -4
- package/project/.sdk/src/cmp/csharp/fragment/Main.fragment.cs +8 -2
- package/project/.sdk/src/cmp/csharp/fragment/SdkError.fragment.cs +49 -0
- package/project/.sdk/src/cmp/elixir/PrepareAuth_elixir.ts +3 -0
- package/project/.sdk/src/cmp/elixir/Schema_elixir.ts +20 -10
- package/project/.sdk/src/cmp/elixir/TestClean_elixir.ts +666 -0
- package/project/.sdk/src/cmp/elixir/Test_elixir.ts +4 -0
- package/project/.sdk/src/cmp/elixir/fragment/Main.fragment.ex +1 -1
- package/project/.sdk/src/cmp/elixir/fragment/Pipeline.fragment.ex +14 -2
- package/project/.sdk/src/cmp/go/PrepareAuth_go.ts +3 -0
- package/project/.sdk/src/cmp/go/TestClean_go.ts +804 -0
- package/project/.sdk/src/cmp/go/Test_go.ts +3 -0
- package/project/.sdk/src/cmp/go/fragment/Entity.fragment.go +54 -4
- package/project/.sdk/src/cmp/go/fragment/Main.fragment.go +27 -2
- package/project/.sdk/src/cmp/java/PrepareAuth_java.ts +3 -0
- package/project/.sdk/src/cmp/java/TestClean_java.ts +884 -0
- package/project/.sdk/src/cmp/java/Test_java.ts +2 -0
- package/project/.sdk/src/cmp/java/fragment/EntityBase.fragment.java +56 -11
- package/project/.sdk/src/cmp/java/fragment/SdkError.fragment.java +36 -3
- package/project/.sdk/src/cmp/js/PrepareAuth_js.ts +3 -0
- package/project/.sdk/src/cmp/js/TestClean_js.ts +458 -0
- package/project/.sdk/src/cmp/js/Test_js.ts +2 -0
- package/project/.sdk/src/cmp/js/fragment/EntityBase.fragment.js +5 -4
- package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/EntityListOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/Main.fragment.js +11 -2
- package/project/.sdk/src/cmp/js/fragment/SdkError.fragment.js +17 -1
- package/project/.sdk/src/cmp/kotlin/Package_kotlin.ts +5 -0
- package/project/.sdk/src/cmp/kotlin/PrepareAuth_kotlin.ts +3 -0
- package/project/.sdk/src/cmp/kotlin/TestClean_kotlin.ts +654 -0
- package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +3 -0
- package/project/.sdk/src/cmp/kotlin/fragment/EntityBase.fragment.kt +44 -11
- package/project/.sdk/src/cmp/kotlin/fragment/SdkError.fragment.kt +31 -0
- package/project/.sdk/src/cmp/lua/PrepareAuth_lua.ts +3 -0
- package/project/.sdk/src/cmp/lua/TestClean_lua.ts +769 -0
- package/project/.sdk/src/cmp/lua/Test_lua.ts +3 -0
- package/project/.sdk/src/cmp/lua/fragment/Entity.fragment.lua +77 -1
- package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +49 -2
- package/project/.sdk/src/cmp/ocaml/Entity_ocaml.ts +3 -2
- package/project/.sdk/src/cmp/ocaml/PrepareAuth_ocaml.ts +4 -25
- package/project/.sdk/src/cmp/ocaml/TestClean_ocaml.ts +538 -0
- package/project/.sdk/src/cmp/ocaml/Test_ocaml.ts +5 -0
- package/project/.sdk/src/cmp/ocaml/fragment/RunOp.fragment.ml +16 -4
- package/project/.sdk/src/cmp/perl/PrepareAuth_perl.ts +3 -0
- package/project/.sdk/src/cmp/perl/TestClean_perl.ts +619 -0
- package/project/.sdk/src/cmp/perl/Test_perl.ts +3 -0
- package/project/.sdk/src/cmp/perl/fragment/Entity.fragment.pm +67 -5
- package/project/.sdk/src/cmp/perl/fragment/Main.fragment.pm +13 -1
- package/project/.sdk/src/cmp/php/PrepareAuth_php.ts +3 -0
- package/project/.sdk/src/cmp/php/TestClean_php.ts +809 -0
- package/project/.sdk/src/cmp/php/Test_php.ts +2 -0
- package/project/.sdk/src/cmp/php/fragment/Entity.fragment.php +96 -55
- package/project/.sdk/src/cmp/php/fragment/Main.fragment.php +15 -2
- package/project/.sdk/src/cmp/py/PrepareAuth_py.ts +3 -0
- package/project/.sdk/src/cmp/py/TestClean_py.ts +549 -0
- package/project/.sdk/src/cmp/py/Test_py.ts +3 -0
- package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +83 -55
- package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +19 -3
- package/project/.sdk/src/cmp/rb/PrepareAuth_rb.ts +3 -0
- package/project/.sdk/src/cmp/rb/TestClean_rb.ts +535 -0
- package/project/.sdk/src/cmp/rb/Test_rb.ts +3 -0
- package/project/.sdk/src/cmp/rb/fragment/Entity.fragment.rb +108 -46
- package/project/.sdk/src/cmp/rb/fragment/Main.fragment.rb +12 -1
- package/project/.sdk/src/cmp/rust/PrepareAuth_rust.ts +9 -45
- package/project/.sdk/src/cmp/rust/TestClean_rust.ts +881 -0
- package/project/.sdk/src/cmp/rust/Test_rust.ts +3 -0
- package/project/.sdk/src/cmp/rust/fragment/Entity.fragment.rs +14 -6
- package/project/.sdk/src/cmp/rust/fragment/Main.fragment.rs +17 -1
- package/project/.sdk/src/cmp/rust/fragment/SdkError.fragment.rs +34 -2
- package/project/.sdk/src/cmp/scala/PrepareAuth_scala.ts +3 -0
- package/project/.sdk/src/cmp/scala/TestClean_scala.ts +608 -0
- package/project/.sdk/src/cmp/scala/Test_scala.ts +3 -0
- package/project/.sdk/src/cmp/scala/fragment/EntityBase.fragment.scala +58 -6
- package/project/.sdk/src/cmp/swift/PrepareAuth_swift.ts +3 -0
- package/project/.sdk/src/cmp/swift/TestClean_swift.ts +671 -0
- package/project/.sdk/src/cmp/swift/Test_swift.ts +3 -0
- package/project/.sdk/src/cmp/swift/fragment/EntityBase.fragment.swift +10 -0
- package/project/.sdk/src/cmp/swift/fragment/Main.fragment.swift +16 -2
- package/project/.sdk/src/cmp/swift/fragment/SdkError.fragment.swift +47 -3
- package/project/.sdk/src/cmp/ts/PrepareAuth_ts.ts +3 -0
- package/project/.sdk/src/cmp/ts/TestClean_ts.ts +465 -0
- package/project/.sdk/src/cmp/ts/Test_ts.ts +2 -0
- package/project/.sdk/src/cmp/ts/fragment/EntityBase.fragment.ts +5 -4
- package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +8 -2
- package/project/.sdk/src/cmp/ts/fragment/SdkError.fragment.ts +20 -2
- package/project/.sdk/src/cmp/zig/PrepareAuth_zig.ts +3 -0
- package/project/.sdk/src/cmp/zig/TestClean_zig.ts +791 -0
- package/project/.sdk/src/cmp/zig/Test_zig.ts +5 -0
- package/project/.sdk/src/cmp/zig/fragment/Build.fragment.zig +19 -0
- package/project/.sdk/src/cmp/zig/fragment/Entity.fragment.zig +14 -5
- package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +1 -1
- package/project/.sdk/tm/c/core/context.c +25 -0
- package/project/.sdk/tm/c/core/error.c +16 -0
- package/project/.sdk/tm/c/core/sdk.h +22 -0
- package/project/.sdk/tm/c/feature/audit.c +2 -0
- package/project/.sdk/tm/c/feature/cost.c +1 -0
- package/project/.sdk/tm/c/feature/debug.c +19 -29
- package/project/.sdk/tm/c/feature/log.c +21 -2
- package/project/.sdk/tm/c/feature/proxy.c +55 -3
- package/project/.sdk/tm/c/feature/secrets.c +7 -0
- package/project/.sdk/tm/c/feature/telemetry.c +2 -0
- package/project/.sdk/tm/c/tests/feature_test.c +2 -2
- package/project/.sdk/tm/c/utility/clean.c +530 -8
- package/project/.sdk/tm/c/utility/done.c +28 -12
- package/project/.sdk/tm/c/utility/make_error.c +4 -3
- package/project/.sdk/tm/c/utility/make_options.c +71 -45
- package/project/.sdk/tm/clojure/feature/secrets/sdk/feature/secrets.clj +15 -0
- package/project/.sdk/tm/clojure/src/sdk/client.clj +20 -4
- package/project/.sdk/tm/clojure/src/sdk/core.clj +319 -35
- package/project/.sdk/tm/clojure/src/sdk/features.clj +68 -30
- package/project/.sdk/tm/clojure/test/sdk/test/feature.clj +4 -2
- package/project/.sdk/tm/clojure/test/sdk/test/pipeline.clj +47 -20
- package/project/.sdk/tm/clojure/test/sdk/test_runner.clj +4 -0
- package/project/.sdk/tm/cpp/core/types.hpp +93 -3
- package/project/.sdk/tm/cpp/feature/audit.hpp +1 -0
- package/project/.sdk/tm/cpp/feature/cost.hpp +1 -0
- package/project/.sdk/tm/cpp/feature/debug.hpp +20 -12
- package/project/.sdk/tm/cpp/feature/log.hpp +31 -9
- package/project/.sdk/tm/cpp/feature/proxy.hpp +52 -6
- package/project/.sdk/tm/cpp/feature/secrets.hpp +13 -0
- package/project/.sdk/tm/cpp/feature/telemetry.hpp +4 -2
- package/project/.sdk/tm/cpp/test/feature_test.cpp +2 -2
- package/project/.sdk/tm/cpp/utility/pipeline.hpp +426 -51
- package/project/.sdk/tm/csharp/core/Context.cs +32 -0
- package/project/.sdk/tm/csharp/core/Utility.cs +2 -0
- package/project/.sdk/tm/csharp/feature/AuditFeature.cs +1 -0
- package/project/.sdk/tm/csharp/feature/CostFeature.cs +7 -5
- package/project/.sdk/tm/csharp/feature/DebugFeature.cs +19 -16
- package/project/.sdk/tm/csharp/feature/FeatureOptions.cs +16 -0
- package/project/.sdk/tm/csharp/feature/LogFeature.cs +4 -1
- package/project/.sdk/tm/csharp/feature/ProxyFeature.cs +26 -5
- package/project/.sdk/tm/csharp/feature/SecretsFeature.cs +16 -0
- package/project/.sdk/tm/csharp/feature/TelemetryFeature.cs +4 -2
- package/project/.sdk/tm/csharp/test/FeatureTest.cs +2 -2
- package/project/.sdk/tm/csharp/utility/Clean.cs +440 -2
- package/project/.sdk/tm/csharp/utility/Done.cs +27 -11
- package/project/.sdk/tm/csharp/utility/MakeError.cs +19 -8
- package/project/.sdk/tm/csharp/utility/MakeOptions.cs +119 -29
- package/project/.sdk/tm/csharp/utility/MakeResponse.cs +21 -11
- package/project/.sdk/tm/csharp/utility/Register.cs +1 -0
- package/project/.sdk/tm/elixir/lib/projectname/context.ex +19 -0
- package/project/.sdk/tm/elixir/lib/projectname/entity_base.ex +22 -1
- package/project/.sdk/tm/elixir/lib/projectname/error.ex +24 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/audit.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/cost.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/debug.ex +13 -13
- package/project/.sdk/tm/elixir/lib/projectname/feature/log.ex +18 -5
- package/project/.sdk/tm/elixir/lib/projectname/feature/proxy.ex +19 -1
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets.ex +15 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/telemetry.ex +4 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature.ex +22 -0
- package/project/.sdk/tm/elixir/lib/projectname/utility.ex +464 -41
- package/project/.sdk/tm/elixir/test/feature_test.exs +3 -2
- package/project/.sdk/tm/go/core/context.go +42 -0
- package/project/.sdk/tm/go/core/error.go +30 -10
- package/project/.sdk/tm/go/core/utility_type.go +2 -0
- package/project/.sdk/tm/go/feature/audit_feature.go +1 -0
- package/project/.sdk/tm/go/feature/base_feature.go +12 -0
- package/project/.sdk/tm/go/feature/cost_feature.go +2 -2
- package/project/.sdk/tm/go/feature/debug_feature.go +14 -12
- package/project/.sdk/tm/go/feature/log_feature.go +13 -8
- package/project/.sdk/tm/go/feature/proxy_feature.go +26 -6
- package/project/.sdk/tm/go/feature/secrets_feature.go +19 -0
- package/project/.sdk/tm/go/feature/telemetry_feature.go +4 -2
- package/project/.sdk/tm/go/test/feature_test.go +2 -2
- package/project/.sdk/tm/go/utility/clean.go +585 -2
- package/project/.sdk/tm/go/utility/done.go +29 -9
- package/project/.sdk/tm/go/utility/make_error.go +51 -16
- package/project/.sdk/tm/go/utility/make_options.go +77 -36
- package/project/.sdk/tm/go/utility/register.go +12 -0
- package/project/.sdk/tm/java/core/Context.java +29 -0
- package/project/.sdk/tm/java/core/SdkClient.java +4 -2
- package/project/.sdk/tm/java/core/Utility.java +7 -0
- package/project/.sdk/tm/java/feature/AuditFeature.java +6 -0
- package/project/.sdk/tm/java/feature/CostFeature.java +5 -0
- package/project/.sdk/tm/java/feature/DebugFeature.java +25 -14
- package/project/.sdk/tm/java/feature/LogFeature.java +11 -4
- package/project/.sdk/tm/java/feature/ProxyFeature.java +41 -6
- package/project/.sdk/tm/java/feature/SecretsFeature.java +18 -0
- package/project/.sdk/tm/java/feature/TelemetryFeature.java +8 -2
- package/project/.sdk/tm/java/test/FeatureTest.java +2 -2
- package/project/.sdk/tm/java/utility/Clean.java +519 -1
- package/project/.sdk/tm/java/utility/Done.java +1 -1
- package/project/.sdk/tm/java/utility/MakeError.java +5 -1
- package/project/.sdk/tm/java/utility/MakeOptions.java +55 -31
- package/project/.sdk/tm/java/utility/Register.java +4 -0
- package/project/.sdk/tm/js/src/Context.js +5 -1
- package/project/.sdk/tm/js/src/feature/audit/AuditFeature.js +2 -2
- package/project/.sdk/tm/js/src/feature/cost/CostFeature.js +2 -2
- package/project/.sdk/tm/js/src/feature/debug/DebugFeature.js +13 -7
- package/project/.sdk/tm/js/src/feature/log/LogFeature.js +9 -5
- package/project/.sdk/tm/js/src/feature/proxy/ProxyFeature.js +19 -1
- package/project/.sdk/tm/js/src/feature/secrets/SecretsFeature.js +14 -0
- package/project/.sdk/tm/js/src/feature/telemetry/TelemetryFeature.js +4 -2
- package/project/.sdk/tm/js/src/utility/CleanUtility.js +294 -21
- package/project/.sdk/tm/js/src/utility/DoneUtility.js +17 -5
- package/project/.sdk/tm/js/src/utility/MakeErrorUtility.js +18 -2
- package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +39 -15
- package/project/.sdk/tm/js/src/utility/Utility.js +4 -2
- package/project/.sdk/tm/js/test/feature/harness.js +11 -1
- package/project/.sdk/tm/js/test/feature.test.js +9 -2
- package/project/.sdk/tm/kotlin/core/Context.kt +19 -0
- package/project/.sdk/tm/kotlin/core/SdkClient.kt +9 -2
- package/project/.sdk/tm/kotlin/core/Utility.kt +2 -0
- package/project/.sdk/tm/kotlin/feature/AuditFeature.kt +11 -9
- package/project/.sdk/tm/kotlin/feature/CostFeature.kt +8 -5
- package/project/.sdk/tm/kotlin/feature/DebugFeature.kt +15 -22
- package/project/.sdk/tm/kotlin/feature/LogFeature.kt +8 -4
- package/project/.sdk/tm/kotlin/feature/ProxyFeature.kt +26 -2
- package/project/.sdk/tm/kotlin/feature/SecretsFeature.kt +11 -0
- package/project/.sdk/tm/kotlin/feature/TelemetryFeature.kt +4 -2
- package/project/.sdk/tm/kotlin/test/FeatureTest.kt +2 -2
- package/project/.sdk/tm/kotlin/utility/CoreUtil.kt +447 -11
- package/project/.sdk/tm/kotlin/utility/MakeOptions.kt +38 -31
- package/project/.sdk/tm/kotlin/utility/Register.kt +1 -0
- package/project/.sdk/tm/lua/core/context.lua +43 -0
- package/project/.sdk/tm/lua/core/error.lua +36 -1
- package/project/.sdk/tm/lua/core/utility_type.lua +4 -0
- package/project/.sdk/tm/lua/feature/audit_feature.lua +2 -2
- package/project/.sdk/tm/lua/feature/cost_feature.lua +2 -2
- package/project/.sdk/tm/lua/feature/debug_feature.lua +21 -17
- package/project/.sdk/tm/lua/feature/log_feature.lua +2 -1
- package/project/.sdk/tm/lua/feature/proxy_feature.lua +23 -1
- package/project/.sdk/tm/lua/feature/secrets_feature.lua +18 -0
- package/project/.sdk/tm/lua/feature/telemetry_feature.lua +4 -2
- package/project/.sdk/tm/lua/test/feature/secrets/secrets_feature_test.lua +3 -2
- package/project/.sdk/tm/lua/test/feature_test.lua +10 -3
- package/project/.sdk/tm/lua/utility/clean.lua +426 -2
- package/project/.sdk/tm/lua/utility/clean_explain.lua +34 -0
- package/project/.sdk/tm/lua/utility/done.lua +1 -7
- package/project/.sdk/tm/lua/utility/make_error.lua +3 -1
- package/project/.sdk/tm/lua/utility/make_options.lua +76 -30
- package/project/.sdk/tm/lua/utility/register.lua +4 -1
- package/project/.sdk/tm/ocaml/Makefile +5 -1
- package/project/.sdk/tm/ocaml/feature/secrets_feature.ml +12 -1
- package/project/.sdk/tm/ocaml/sdk_features.ml +78 -18
- package/project/.sdk/tm/ocaml/sdk_helpers.ml +27 -0
- package/project/.sdk/tm/ocaml/sdk_runtime.ml +304 -26
- package/project/.sdk/tm/ocaml/sdk_types.ml +1 -0
- package/project/.sdk/tm/ocaml/test/feature/secrets/t_secrets.ml +3 -1
- package/project/.sdk/tm/ocaml/test/t_feature.ml +2 -2
- package/project/.sdk/tm/perl/core/context.pm +27 -0
- package/project/.sdk/tm/perl/core/error.pm +52 -5
- package/project/.sdk/tm/perl/feature/audit_feature.pm +2 -2
- package/project/.sdk/tm/perl/feature/cost_feature.pm +2 -2
- package/project/.sdk/tm/perl/feature/debug_feature.pm +17 -13
- package/project/.sdk/tm/perl/feature/log_feature.pm +3 -1
- package/project/.sdk/tm/perl/feature/proxy_feature.pm +21 -1
- package/project/.sdk/tm/perl/feature/secrets_feature.pm +20 -1
- package/project/.sdk/tm/perl/feature/telemetry_feature.pm +4 -2
- package/project/.sdk/tm/perl/t/feature.t +4 -2
- package/project/.sdk/tm/perl/utility/clean.pm +345 -1
- package/project/.sdk/tm/perl/utility/done.pm +24 -6
- package/project/.sdk/tm/perl/utility/make_error.pm +17 -4
- package/project/.sdk/tm/perl/utility/make_options.pm +33 -14
- package/project/.sdk/tm/php/core/Context.php +24 -1
- package/project/.sdk/tm/php/core/Error.php +34 -3
- package/project/.sdk/tm/php/core/UtilityType.php +4 -0
- package/project/.sdk/tm/php/feature/AuditFeature.php +2 -2
- package/project/.sdk/tm/php/feature/CostFeature.php +2 -2
- package/project/.sdk/tm/php/feature/DebugFeature.php +18 -9
- package/project/.sdk/tm/php/feature/LogFeature.php +5 -2
- package/project/.sdk/tm/php/feature/ProxyFeature.php +20 -1
- package/project/.sdk/tm/php/feature/SecretsFeature.php +18 -0
- package/project/.sdk/tm/php/feature/TelemetryFeature.php +4 -2
- package/project/.sdk/tm/php/test/FeatureTest.php +2 -2
- package/project/.sdk/tm/php/utility/Clean.php +438 -2
- package/project/.sdk/tm/php/utility/Done.php +14 -7
- package/project/.sdk/tm/php/utility/MakeError.php +9 -7
- package/project/.sdk/tm/php/utility/MakeOptions.php +62 -38
- package/project/.sdk/tm/php/utility/Register.php +2 -0
- package/project/.sdk/tm/py/pkg/core/context.py +17 -0
- package/project/.sdk/tm/py/pkg/core/error.py +42 -1
- package/project/.sdk/tm/py/pkg/core/utility_type.py +4 -0
- package/project/.sdk/tm/py/pkg/feature/audit_feature.py +2 -2
- package/project/.sdk/tm/py/pkg/feature/cost_feature.py +2 -2
- package/project/.sdk/tm/py/pkg/feature/debug_feature.py +17 -12
- package/project/.sdk/tm/py/pkg/feature/log_feature.py +2 -1
- package/project/.sdk/tm/py/pkg/feature/proxy_feature.py +18 -1
- package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +12 -0
- package/project/.sdk/tm/py/pkg/feature/telemetry_feature.py +4 -2
- package/project/.sdk/tm/py/pkg/utility/clean.py +311 -1
- package/project/.sdk/tm/py/pkg/utility/done.py +18 -5
- package/project/.sdk/tm/py/pkg/utility/make_error.py +9 -6
- package/project/.sdk/tm/py/pkg/utility/make_options.py +64 -25
- package/project/.sdk/tm/py/pkg/utility/make_response.py +19 -13
- package/project/.sdk/tm/py/pkg/utility/register.py +4 -2
- package/project/.sdk/tm/py/test/feature_harness.py +4 -0
- package/project/.sdk/tm/py/test/test_feature.py +2 -2
- package/project/.sdk/tm/py/test/test_primary_utility.py +1 -0
- package/project/.sdk/tm/rb/core/context.rb +28 -0
- package/project/.sdk/tm/rb/core/error.rb +30 -0
- package/project/.sdk/tm/rb/core/utility_type.rb +1 -1
- package/project/.sdk/tm/rb/feature/audit_feature.rb +2 -2
- package/project/.sdk/tm/rb/feature/cost_feature.rb +2 -2
- package/project/.sdk/tm/rb/feature/debug_feature.rb +15 -12
- package/project/.sdk/tm/rb/feature/log_feature.rb +3 -1
- package/project/.sdk/tm/rb/feature/proxy_feature.rb +25 -1
- package/project/.sdk/tm/rb/feature/secrets_feature.rb +17 -0
- package/project/.sdk/tm/rb/feature/telemetry_feature.rb +4 -2
- package/project/.sdk/tm/rb/test/feature_test.rb +4 -2
- package/project/.sdk/tm/rb/utility/clean.rb +312 -1
- package/project/.sdk/tm/rb/utility/done.rb +15 -5
- package/project/.sdk/tm/rb/utility/make_error.rb +13 -4
- package/project/.sdk/tm/rb/utility/make_options.rb +31 -12
- package/project/.sdk/tm/rb/utility/register.rb +2 -0
- package/project/.sdk/tm/rust/core/context.rs +55 -0
- package/project/.sdk/tm/rust/core/utility_type.rs +17 -0
- package/project/.sdk/tm/rust/feature/audit.rs +2 -0
- package/project/.sdk/tm/rust/feature/cost.rs +3 -2
- package/project/.sdk/tm/rust/feature/debug.rs +16 -16
- package/project/.sdk/tm/rust/feature/log.rs +42 -7
- package/project/.sdk/tm/rust/feature/proxy.rs +48 -2
- package/project/.sdk/tm/rust/feature/secrets.rs +12 -0
- package/project/.sdk/tm/rust/feature/telemetry.rs +2 -0
- package/project/.sdk/tm/rust/tests/feature_test.rs +2 -2
- package/project/.sdk/tm/rust/utility/clean.rs +446 -5
- package/project/.sdk/tm/rust/utility/done.rs +22 -12
- package/project/.sdk/tm/rust/utility/make_error.rs +4 -1
- package/project/.sdk/tm/rust/utility/make_options.rs +73 -19
- package/project/.sdk/tm/scala/Makefile +3 -1
- package/project/.sdk/tm/scala/core/Context.scala +16 -0
- package/project/.sdk/tm/scala/core/SdkClient.scala +14 -4
- package/project/.sdk/tm/scala/core/SdkError.scala +28 -0
- package/project/.sdk/tm/scala/core/Types.scala +3 -0
- package/project/.sdk/tm/scala/core/Utility.scala +2 -0
- package/project/.sdk/tm/scala/feature/AuditFeature.scala +16 -10
- package/project/.sdk/tm/scala/feature/CostFeature.scala +10 -5
- package/project/.sdk/tm/scala/feature/DebugFeature.scala +24 -21
- package/project/.sdk/tm/scala/feature/LogFeature.scala +9 -4
- package/project/.sdk/tm/scala/feature/ProxyFeature.scala +23 -2
- package/project/.sdk/tm/scala/feature/SecretsFeature.scala +14 -0
- package/project/.sdk/tm/scala/feature/TelemetryFeature.scala +9 -2
- package/project/.sdk/tm/scala/sdktest/SdkTestMain.scala +2 -2
- package/project/.sdk/tm/scala/utility/Make.scala +63 -20
- package/project/.sdk/tm/scala/utility/Misc.scala +358 -5
- package/project/.sdk/tm/scala/utility/Register.scala +1 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Context.swift +29 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Utility.swift +2 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/AuditFeature.swift +10 -9
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/CostFeature.swift +7 -5
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/DebugFeature.swift +19 -15
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/FeatureOptions.swift +16 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/LogFeature.swift +4 -1
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/ProxyFeature.swift +20 -5
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/SecretsFeature.swift +13 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/TelemetryFeature.swift +4 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeError.swift +15 -5
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +58 -19
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Register.swift +1 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/ResultUtil.swift +391 -4
- package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/FeatureTest.swift +2 -2
- package/project/.sdk/tm/ts/src/Context.ts +5 -1
- package/project/.sdk/tm/ts/src/feature/audit/AuditFeature.ts +2 -2
- package/project/.sdk/tm/ts/src/feature/cost/CostFeature.ts +2 -2
- package/project/.sdk/tm/ts/src/feature/debug/DebugFeature.ts +13 -7
- package/project/.sdk/tm/ts/src/feature/log/LogFeature.ts +9 -5
- package/project/.sdk/tm/ts/src/feature/proxy/ProxyFeature.ts +19 -1
- package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +12 -0
- package/project/.sdk/tm/ts/src/feature/telemetry/TelemetryFeature.ts +4 -2
- package/project/.sdk/tm/ts/src/utility/CleanUtility.ts +287 -9
- package/project/.sdk/tm/ts/src/utility/DoneUtility.ts +18 -5
- package/project/.sdk/tm/ts/src/utility/MakeErrorUtility.ts +18 -8
- package/project/.sdk/tm/ts/src/utility/MakeOptionsUtility.ts +38 -16
- package/project/.sdk/tm/ts/src/utility/Utility.ts +4 -2
- package/project/.sdk/tm/ts/test/feature/harness.ts +11 -1
- package/project/.sdk/tm/ts/test/feature.test.ts +9 -2
- package/project/.sdk/tm/zig/core/context.zig +34 -0
- package/project/.sdk/tm/zig/core/error.zig +22 -1
- package/project/.sdk/tm/zig/core/utility.zig +403 -39
- package/project/.sdk/tm/zig/feature/audit.zig +4 -2
- package/project/.sdk/tm/zig/feature/cost.zig +3 -2
- package/project/.sdk/tm/zig/feature/debug.zig +20 -25
- package/project/.sdk/tm/zig/feature/log.zig +3 -1
- package/project/.sdk/tm/zig/feature/proxy.zig +47 -6
- package/project/.sdk/tm/zig/feature/secrets.zig +7 -0
- package/project/.sdk/tm/zig/feature/telemetry.zig +4 -2
- package/project/.sdk/tm/zig/test/feature_test.zig +2 -2
- package/project/sdkgen-package.json +1 -1
- package/src/action/copies.ts +219 -0
- package/src/action/doctor.ts +247 -21
- package/src/action/edition.ts +10 -2
- package/src/action/feature.ts +11 -2
- package/src/action/package.ts +31 -10
- package/src/action/remove.ts +4 -0
- package/src/action/resolve.ts +16 -3
- package/src/action/target.ts +10 -2
- package/src/helpers/naming.ts +1 -1
- package/src/sdkgen.ts +45 -5
|
@@ -207,3 +207,20 @@ class ProjectNameContext:
|
|
|
207
207
|
|
|
208
208
|
def make_error(self, code, msg):
|
|
209
209
|
return ProjectNameError(code, msg, self)
|
|
210
|
+
|
|
211
|
+
# The serialised context leaves the pipeline (a logger, an error dump),
|
|
212
|
+
# so it is cleaned; the live fields stay raw for the pipeline's own use.
|
|
213
|
+
def to_json(self):
|
|
214
|
+
record = {
|
|
215
|
+
"id": self.id,
|
|
216
|
+
"op": self.op,
|
|
217
|
+
"spec": self.spec,
|
|
218
|
+
"result": self.result,
|
|
219
|
+
"response": self.response,
|
|
220
|
+
"meta": self.meta,
|
|
221
|
+
}
|
|
222
|
+
clean = getattr(self.utility, "clean", None) if self.utility is not None else None
|
|
223
|
+
return clean(self, record) if callable(clean) else record
|
|
224
|
+
|
|
225
|
+
def __repr__(self):
|
|
226
|
+
return self.__class__.__name__ + "(" + repr(self.to_json()) + ")"
|
|
@@ -4,15 +4,56 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
class ProjectNameError(Exception):
|
|
7
|
+
# The context holds the live spec and options, and an error is what gets
|
|
8
|
+
# logged: a slot keeps it reachable for a debugger and out of `vars()`,
|
|
9
|
+
# pickling and every attribute dump.
|
|
10
|
+
__slots__ = ("_ctx",)
|
|
11
|
+
|
|
7
12
|
def __init__(self, code="", msg="", ctx=None):
|
|
8
13
|
super().__init__(msg)
|
|
9
14
|
self.is_sdk_error = True
|
|
10
15
|
self.sdk = "ProjectName"
|
|
11
16
|
self.code = code
|
|
12
17
|
self.msg = msg
|
|
13
|
-
self.
|
|
18
|
+
self._ctx = ctx
|
|
19
|
+
self.status = -1
|
|
14
20
|
self.result = None
|
|
15
21
|
self.spec = None
|
|
16
22
|
|
|
23
|
+
@property
|
|
24
|
+
def ctx(self):
|
|
25
|
+
return getattr(self, "_ctx", None)
|
|
26
|
+
|
|
27
|
+
@ctx.setter
|
|
28
|
+
def ctx(self, value):
|
|
29
|
+
self._ctx = value
|
|
30
|
+
|
|
31
|
+
# `err.not_found` rather than a magic number at every call site.
|
|
32
|
+
@property
|
|
33
|
+
def not_found(self):
|
|
34
|
+
return 404 == self.status
|
|
35
|
+
|
|
36
|
+
# What make_error attached is already cleaned; the context is not part
|
|
37
|
+
# of the record.
|
|
38
|
+
def to_json(self):
|
|
39
|
+
return {
|
|
40
|
+
"sdk": self.sdk,
|
|
41
|
+
"code": self.code,
|
|
42
|
+
"message": self.msg,
|
|
43
|
+
"status": self.status,
|
|
44
|
+
"result": self.result,
|
|
45
|
+
"spec": self.spec,
|
|
46
|
+
}
|
|
47
|
+
|
|
17
48
|
def __str__(self):
|
|
18
49
|
return self.msg
|
|
50
|
+
|
|
51
|
+
def __repr__(self):
|
|
52
|
+
return (self.__class__.__name__ + "(code=" + repr(self.code) +
|
|
53
|
+
", msg=" + repr(self.msg) + ", status=" + repr(self.status) + ")")
|
|
54
|
+
|
|
55
|
+
def __getstate__(self):
|
|
56
|
+
return dict(self.__dict__)
|
|
57
|
+
|
|
58
|
+
def __reduce__(self):
|
|
59
|
+
return (self.__class__, (self.code, self.msg), self.__getstate__())
|
|
@@ -11,6 +11,8 @@ class ProjectNameUtility:
|
|
|
11
11
|
|
|
12
12
|
# All utility functions are set by the register module
|
|
13
13
|
self.clean = None
|
|
14
|
+
self.clean_add = None
|
|
15
|
+
self.clean_explain = None
|
|
14
16
|
self.done = None
|
|
15
17
|
self.make_error = None
|
|
16
18
|
self.feature_add = None
|
|
@@ -50,6 +52,8 @@ class ProjectNameUtility:
|
|
|
50
52
|
def copy(cls, src):
|
|
51
53
|
u = cls()
|
|
52
54
|
u.clean = src.clean
|
|
55
|
+
u.clean_add = src.clean_add
|
|
56
|
+
u.clean_explain = src.clean_explain
|
|
53
57
|
u.done = src.done
|
|
54
58
|
u.make_error = src.make_error
|
|
55
59
|
u.feature_add = src.feature_add
|
|
@@ -67,7 +67,7 @@ class ProjectNameAuditFeature(ProjectNameBaseFeature):
|
|
|
67
67
|
if actor is None:
|
|
68
68
|
actor = "anonymous"
|
|
69
69
|
|
|
70
|
-
record = {
|
|
70
|
+
record = ctx.utility.clean(ctx, {
|
|
71
71
|
"seq": self.seq,
|
|
72
72
|
"ts": self._now(),
|
|
73
73
|
"actor": actor,
|
|
@@ -76,7 +76,7 @@ class ProjectNameAuditFeature(ProjectNameBaseFeature):
|
|
|
76
76
|
"outcome": outcome,
|
|
77
77
|
"status": ctx.result.status if ctx.result is not None else None,
|
|
78
78
|
"correlationId": ctx.id,
|
|
79
|
-
}
|
|
79
|
+
})
|
|
80
80
|
|
|
81
81
|
records = self.client._audit["records"]
|
|
82
82
|
records.append(record)
|
|
@@ -249,7 +249,7 @@ class ProjectNameCostFeature(ProjectNameBaseFeature):
|
|
|
249
249
|
self._bump(cost["actors"], actor, amount)
|
|
250
250
|
|
|
251
251
|
self.seq += 1
|
|
252
|
-
record = {
|
|
252
|
+
record = ctx.utility.clean(ctx, {
|
|
253
253
|
"seq": self.seq,
|
|
254
254
|
"entity": entity,
|
|
255
255
|
"op": opname,
|
|
@@ -258,7 +258,7 @@ class ProjectNameCostFeature(ProjectNameBaseFeature):
|
|
|
258
258
|
"currency": cost["currency"],
|
|
259
259
|
"source": source,
|
|
260
260
|
"attempts": pending["attempts"],
|
|
261
|
-
}
|
|
261
|
+
})
|
|
262
262
|
cost["last"] = record
|
|
263
263
|
|
|
264
264
|
sink = self.options.get("sink")
|
|
@@ -8,10 +8,11 @@ from projectname_sdk.feature.base_feature import ProjectNameBaseFeature
|
|
|
8
8
|
|
|
9
9
|
# Request/response capture for debugging. Records a bounded ring buffer of
|
|
10
10
|
# per-operation traces — method, URL, redacted headers, response status and
|
|
11
|
-
# timing — on `client._debug["entries"]`.
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
11
|
+
# timing — on `client._debug["entries"]`. Every entry passes through the
|
|
12
|
+
# SDK's clean rules (clean.keys and every registered secret value); the
|
|
13
|
+
# `redact` option ADDS header names on top of them. An optional `onEntry`
|
|
14
|
+
# callback receives each finished entry (e.g. to stream to a console).
|
|
15
|
+
# `max` caps the buffer (default 100).
|
|
15
16
|
class ProjectNameDebugFeature(ProjectNameBaseFeature):
|
|
16
17
|
def __init__(self):
|
|
17
18
|
super().__init__()
|
|
@@ -47,7 +48,7 @@ class ProjectNameDebugFeature(ProjectNameBaseFeature):
|
|
|
47
48
|
"op": opname,
|
|
48
49
|
"method": spec.method if spec is not None else None,
|
|
49
50
|
"url": (spec.url or spec.path) if spec is not None else None,
|
|
50
|
-
"headers": self._redact(spec.headers if spec is not None else None),
|
|
51
|
+
"headers": self._redact(ctx, spec.headers if spec is not None else None),
|
|
51
52
|
"start": self._now(),
|
|
52
53
|
"status": None,
|
|
53
54
|
"ok": None,
|
|
@@ -99,6 +100,11 @@ class ProjectNameDebugFeature(ProjectNameBaseFeature):
|
|
|
99
100
|
if entry["status"] is None and result is not None:
|
|
100
101
|
entry["status"] = result.status
|
|
101
102
|
|
|
103
|
+
# The whole entry leaves through the buffer and the callback: the url
|
|
104
|
+
# and the error message can carry a query credential the header mask
|
|
105
|
+
# above never saw.
|
|
106
|
+
entry = ctx.utility.clean(ctx, entry)
|
|
107
|
+
|
|
102
108
|
buf = self.client._debug["entries"]
|
|
103
109
|
buf.append(entry)
|
|
104
110
|
mx = 100 if self.options.get("max") is None else self.options.get("max")
|
|
@@ -112,20 +118,19 @@ class ProjectNameDebugFeature(ProjectNameBaseFeature):
|
|
|
112
118
|
except Exception:
|
|
113
119
|
pass
|
|
114
120
|
|
|
115
|
-
|
|
121
|
+
# The core clean rules apply (clean.keys, every registered value); the
|
|
122
|
+
# feature's own `redact` list ADDS header names on top of them.
|
|
123
|
+
def _redact(self, ctx, headers):
|
|
116
124
|
if headers is None:
|
|
117
125
|
return {}
|
|
118
|
-
patterns = self.options.get("redact") or [
|
|
119
|
-
"authorization", "cookie", "set-cookie", "api-key",
|
|
120
|
-
"apikey", "x-api-key", "idempotency-key",
|
|
121
|
-
]
|
|
126
|
+
patterns = [str(n).lower() for n in (self.options.get("redact") or [])]
|
|
122
127
|
out = {}
|
|
123
128
|
for key in headers:
|
|
124
129
|
if str(key).lower() in patterns:
|
|
125
|
-
out[key] = "
|
|
130
|
+
out[key] = "[redacted]"
|
|
126
131
|
else:
|
|
127
132
|
out[key] = headers[key]
|
|
128
|
-
return out
|
|
133
|
+
return ctx.utility.clean(ctx, out)
|
|
129
134
|
|
|
130
135
|
def _now(self):
|
|
131
136
|
now = self.options.get("now")
|
|
@@ -44,7 +44,8 @@ class ProjectNameLogFeature(ProjectNameBaseFeature):
|
|
|
44
44
|
if ctx.op is not None:
|
|
45
45
|
opname = ctx.op.name
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
# A log line leaves the pipeline, so it is cleaned like any record.
|
|
48
|
+
msg = ctx.utility.clean(ctx, "hook=" + hook + " op=" + opname)
|
|
48
49
|
|
|
49
50
|
log_fn = self.logger.get(level)
|
|
50
51
|
if callable(log_fn):
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
import os
|
|
5
5
|
import re
|
|
6
|
+
from urllib.parse import unquote, urlsplit
|
|
6
7
|
|
|
7
8
|
from projectname_sdk.feature.base_feature import ProjectNameBaseFeature
|
|
8
9
|
|
|
@@ -27,6 +28,7 @@ class ProjectNameProxyFeature(ProjectNameBaseFeature):
|
|
|
27
28
|
self.options = {}
|
|
28
29
|
self.url = None
|
|
29
30
|
self.no_proxy = []
|
|
31
|
+
self._ctx = None
|
|
30
32
|
|
|
31
33
|
def init(self, ctx, options):
|
|
32
34
|
self.client = ctx.client
|
|
@@ -54,6 +56,19 @@ class ProjectNameProxyFeature(ProjectNameBaseFeature):
|
|
|
54
56
|
no_proxy = re.split(r"\s*,\s*", no_proxy)
|
|
55
57
|
self.no_proxy = [s for s in (no_proxy or []) if s is not None and s != ""]
|
|
56
58
|
|
|
59
|
+
# A proxy URL may carry credentials as userinfo, from the option or
|
|
60
|
+
# the environment, and neither is under a sensitive key name.
|
|
61
|
+
self._ctx = ctx
|
|
62
|
+
if isinstance(self.url, str):
|
|
63
|
+
try:
|
|
64
|
+
parsed = urlsplit(self.url)
|
|
65
|
+
for part in (parsed.username, parsed.password):
|
|
66
|
+
if part:
|
|
67
|
+
ctx.utility.clean_add(ctx, part)
|
|
68
|
+
ctx.utility.clean_add(ctx, unquote(part))
|
|
69
|
+
except Exception:
|
|
70
|
+
pass
|
|
71
|
+
|
|
57
72
|
utility = ctx.utility
|
|
58
73
|
inner = utility.fetcher
|
|
59
74
|
|
|
@@ -99,6 +114,8 @@ class ProjectNameProxyFeature(ProjectNameBaseFeature):
|
|
|
99
114
|
client = self.client
|
|
100
115
|
track = getattr(client, "_proxy", None)
|
|
101
116
|
if track is None:
|
|
102
|
-
|
|
117
|
+
ctx = self._ctx
|
|
118
|
+
url = self.url if ctx is None else ctx.utility.clean(ctx, self.url)
|
|
119
|
+
track = {"routed": 0, "url": url}
|
|
103
120
|
client._proxy = track
|
|
104
121
|
track["routed"] += 1
|
|
@@ -153,6 +153,7 @@ class ProjectNameSecretsFeature(ProjectNameBaseFeature):
|
|
|
153
153
|
explicit = xopts.get("refresh") if isinstance(xopts, dict) else None
|
|
154
154
|
|
|
155
155
|
if isinstance(explicit, str) and "" != explicit:
|
|
156
|
+
self._register(explicit)
|
|
156
157
|
providers.append({
|
|
157
158
|
"kind": "memory",
|
|
158
159
|
"name": "options",
|
|
@@ -198,6 +199,14 @@ class ProjectNameSecretsFeature(ProjectNameBaseFeature):
|
|
|
198
199
|
def sekreto(self):
|
|
199
200
|
return self._sekreto
|
|
200
201
|
|
|
202
|
+
# Every value this feature resolves or buys is a secret the SDK handles,
|
|
203
|
+
# and none arrives under an option key the intake registration saw.
|
|
204
|
+
def _register(self, value):
|
|
205
|
+
ctx = getattr(self._client, "_rootctx", None)
|
|
206
|
+
utility = getattr(ctx, "utility", None)
|
|
207
|
+
if callable(getattr(utility, "clean_add", None)):
|
|
208
|
+
utility.clean_add(ctx, value)
|
|
209
|
+
|
|
201
210
|
def PreSpec(self, _ctx):
|
|
202
211
|
return self.resolve()
|
|
203
212
|
|
|
@@ -231,6 +240,7 @@ class ProjectNameSecretsFeature(ProjectNameBaseFeature):
|
|
|
231
240
|
# RAISES for "a store could not answer" - only the miss falls
|
|
232
241
|
# through.
|
|
233
242
|
found = self._sekreto.try_(self._secretname)
|
|
243
|
+
self._register(found)
|
|
234
244
|
|
|
235
245
|
if self._exchange is None:
|
|
236
246
|
if found is not None:
|
|
@@ -367,6 +377,8 @@ class ProjectNameSecretsFeature(ProjectNameBaseFeature):
|
|
|
367
377
|
"secrets: token exchange returned no '" + x["response"]
|
|
368
378
|
+ "' field from " + url)
|
|
369
379
|
|
|
380
|
+
self._register(token)
|
|
381
|
+
|
|
370
382
|
return token
|
|
371
383
|
|
|
372
384
|
# Buy a token and try the request again when the API says the current
|
|
@@ -101,14 +101,16 @@ class ProjectNameTelemetryFeature(ProjectNameBaseFeature):
|
|
|
101
101
|
span["durationMs"] = max(0, span["end"] - span["start"])
|
|
102
102
|
span["ok"] = ok
|
|
103
103
|
|
|
104
|
+
out = ctx.utility.clean(ctx, span)
|
|
105
|
+
|
|
104
106
|
telemetry = self.client._telemetry
|
|
105
107
|
telemetry["active"] -= 1
|
|
106
|
-
telemetry["spans"].append(
|
|
108
|
+
telemetry["spans"].append(out)
|
|
107
109
|
|
|
108
110
|
exporter = self.options.get("exporter")
|
|
109
111
|
if callable(exporter):
|
|
110
112
|
try:
|
|
111
|
-
exporter(
|
|
113
|
+
exporter(out)
|
|
112
114
|
except Exception:
|
|
113
115
|
pass
|
|
114
116
|
|
|
@@ -1,5 +1,315 @@
|
|
|
1
1
|
# ProjectName SDK utility: clean
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
import base64
|
|
5
|
+
import json
|
|
6
|
+
from urllib.parse import quote
|
|
3
7
|
|
|
8
|
+
from projectname_sdk.schema import OPTSPEC
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Everything that leaves the pipeline passes through clean: the error, the
|
|
12
|
+
# explain record, the serialised context, and whatever a feature emits.
|
|
13
|
+
# Two layers: every registered secret VALUE (and its encoded forms) is
|
|
14
|
+
# replaced wherever it appears in a string, and every value under a
|
|
15
|
+
# sensitive KEY name is masked whatever it holds. Inside the pipeline data
|
|
16
|
+
# stays raw, so a hook can still read the header it must add to.
|
|
17
|
+
|
|
18
|
+
_MAXDEPTH = 32
|
|
19
|
+
_CIRCULAR = "[circular]"
|
|
20
|
+
|
|
21
|
+
# A dropped value (a function) - distinct from None, which is data.
|
|
22
|
+
_DROP = object()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _normkey(key):
|
|
26
|
+
return str(key).lower().replace("-", "").replace("_", "")
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _splitkeys(keys):
|
|
30
|
+
out = []
|
|
31
|
+
for part in str("" if keys is None else keys).split(","):
|
|
32
|
+
k = _normkey(part.strip())
|
|
33
|
+
if k != "":
|
|
34
|
+
out.append(k)
|
|
35
|
+
return out
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# The comma-separated literal values a caller registers; a list is taken
|
|
39
|
+
# as-is for a caller that has one.
|
|
40
|
+
def split_values(values):
|
|
41
|
+
if isinstance(values, list):
|
|
42
|
+
return [v for v in values if isinstance(v, str)]
|
|
43
|
+
out = []
|
|
44
|
+
for part in str("" if values is None else values).split(","):
|
|
45
|
+
v = part.strip()
|
|
46
|
+
if v != "":
|
|
47
|
+
out.append(v)
|
|
48
|
+
return out
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# The spec carries numbers as strings, so every target reads it alike.
|
|
52
|
+
def _count(val, dflt):
|
|
53
|
+
try:
|
|
54
|
+
n = int(float(val))
|
|
55
|
+
except (TypeError, ValueError):
|
|
56
|
+
return dflt
|
|
57
|
+
return n if n >= 0 else dflt
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _options_of(ctx):
|
|
61
|
+
if isinstance(ctx, dict):
|
|
62
|
+
return ctx.get("options")
|
|
63
|
+
return getattr(ctx, "options", None)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# The derived block make_options builds; a context without options
|
|
67
|
+
# (make_error is reached with a bare one) falls back to the schema defaults,
|
|
68
|
+
# so nothing leaves raw for want of a constructor.
|
|
69
|
+
def _clean_config(ctx):
|
|
70
|
+
options = _options_of(ctx)
|
|
71
|
+
derived = options.get("__derived__") if isinstance(options, dict) else None
|
|
72
|
+
cfg = derived.get("clean") if isinstance(derived, dict) else None
|
|
73
|
+
if isinstance(cfg, dict) and isinstance(cfg.get("values"), list):
|
|
74
|
+
return cfg
|
|
75
|
+
return make_clean_config(OPTSPEC.get("clean"))
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def make_clean_config(cleanopts):
|
|
79
|
+
opts = cleanopts if isinstance(cleanopts, dict) else {}
|
|
80
|
+
mask = opts.get("mask")
|
|
81
|
+
return {
|
|
82
|
+
"active": opts.get("active") is not False,
|
|
83
|
+
"keys": _splitkeys(opts.get("keys")),
|
|
84
|
+
"values": [],
|
|
85
|
+
"mask": mask if isinstance(mask, str) else "[redacted]",
|
|
86
|
+
"hint": _count(opts.get("hint"), 0),
|
|
87
|
+
"min": max(1, _count(opts.get("min"), 4)),
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
# The encoded forms a value travels in: Basic and Bearer both carry base64,
|
|
92
|
+
# a query credential is percent-encoded, and a JSON dump escapes it.
|
|
93
|
+
def _forms(value):
|
|
94
|
+
out = [value]
|
|
95
|
+
|
|
96
|
+
def add(s):
|
|
97
|
+
if s != "" and s not in out:
|
|
98
|
+
out.append(s)
|
|
99
|
+
|
|
100
|
+
try:
|
|
101
|
+
add(base64.b64encode(value.encode("utf-8")).decode("ascii"))
|
|
102
|
+
except Exception:
|
|
103
|
+
pass
|
|
104
|
+
try:
|
|
105
|
+
add(quote(value, safe="!~*'()"))
|
|
106
|
+
except Exception:
|
|
107
|
+
pass
|
|
108
|
+
try:
|
|
109
|
+
add(json.dumps(value, ensure_ascii=False)[1:-1])
|
|
110
|
+
add(json.dumps(value)[1:-1])
|
|
111
|
+
except Exception:
|
|
112
|
+
pass
|
|
113
|
+
return out
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
# Register a secret value. Idempotent; shorter than `min` is not a secret
|
|
117
|
+
# the SDK can mask without blanking ordinary text.
|
|
118
|
+
def clean_add_util(ctx, value):
|
|
119
|
+
cfg = _clean_config(ctx)
|
|
120
|
+
if not isinstance(value, str) or len(value) < cfg["min"]:
|
|
121
|
+
return
|
|
122
|
+
values = cfg["values"]
|
|
123
|
+
changed = False
|
|
124
|
+
for form in _forms(value):
|
|
125
|
+
if len(form) >= cfg["min"] and form not in values:
|
|
126
|
+
values.append(form)
|
|
127
|
+
changed = True
|
|
128
|
+
if changed:
|
|
129
|
+
values.sort(key=len, reverse=True)
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
# Every scalar under a sensitive name, at any depth and of any shape: a
|
|
133
|
+
# credential mistyped as a map or a number is still a credential, and the
|
|
134
|
+
# validation error that rejects it quotes it.
|
|
135
|
+
def clean_add_sensitive(ctx, val, under=False, depth=0, seen=None):
|
|
136
|
+
if val is None or _MAXDEPTH <= depth or isinstance(val, bool):
|
|
137
|
+
return
|
|
138
|
+
if isinstance(val, (str, int, float)):
|
|
139
|
+
if under:
|
|
140
|
+
text = str(int(val)) if isinstance(val, float) and val.is_integer() else str(val)
|
|
141
|
+
clean_add_util(ctx, text)
|
|
142
|
+
return
|
|
143
|
+
if not isinstance(val, (dict, list, tuple)):
|
|
144
|
+
return
|
|
145
|
+
seen = [] if seen is None else seen
|
|
146
|
+
if id(val) in seen:
|
|
147
|
+
return
|
|
148
|
+
seen.append(id(val))
|
|
149
|
+
if isinstance(val, dict):
|
|
150
|
+
for k, v in val.items():
|
|
151
|
+
clean_add_sensitive(ctx, v, under or clean_key(ctx, k), depth + 1, seen)
|
|
152
|
+
else:
|
|
153
|
+
for v in val:
|
|
154
|
+
clean_add_sensitive(ctx, v, under, depth + 1, seen)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def _mask_value(cfg, value):
|
|
158
|
+
hint = cfg["hint"]
|
|
159
|
+
if 0 < hint and len(value) > 2 * hint:
|
|
160
|
+
return cfg["mask"] + value[-hint:]
|
|
161
|
+
return cfg["mask"]
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def _clean_string(cfg, text):
|
|
165
|
+
out = text
|
|
166
|
+
for value in cfg["values"]:
|
|
167
|
+
if value in out:
|
|
168
|
+
out = out.replace(value, _mask_value(cfg, value))
|
|
169
|
+
return out
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def _sensitive_key(cfg, key):
|
|
173
|
+
if key is None or isinstance(key, bool) or isinstance(key, (int, float)):
|
|
174
|
+
return False
|
|
175
|
+
nk = _normkey(key)
|
|
176
|
+
for k in cfg["keys"]:
|
|
177
|
+
if k in nk:
|
|
178
|
+
return True
|
|
179
|
+
return False
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def _is_function(val):
|
|
183
|
+
return callable(val) and not isinstance(val, type)
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
# A plain-data copy of what is about to leave: a `to_json` hook is honoured
|
|
187
|
+
# (a context serialises as its record), functions are dropped, cycles are
|
|
188
|
+
# cut, and no live object is shared with the copy - masking the copy must
|
|
189
|
+
# never mask the pipeline's own spec.
|
|
190
|
+
def _snapshot(cfg, val, key, depth, seen):
|
|
191
|
+
if val is None:
|
|
192
|
+
return None
|
|
193
|
+
|
|
194
|
+
if isinstance(val, str):
|
|
195
|
+
return _mask_value(cfg, val) if _sensitive_key(cfg, key) else _clean_string(cfg, val)
|
|
196
|
+
|
|
197
|
+
if isinstance(val, (bool, int, float)):
|
|
198
|
+
return cfg["mask"] if _sensitive_key(cfg, key) else val
|
|
199
|
+
|
|
200
|
+
if _is_function(val):
|
|
201
|
+
return _DROP
|
|
202
|
+
|
|
203
|
+
if _MAXDEPTH <= depth or id(val) in seen:
|
|
204
|
+
return _CIRCULAR
|
|
205
|
+
|
|
206
|
+
if _sensitive_key(cfg, key):
|
|
207
|
+
return cfg["mask"]
|
|
208
|
+
|
|
209
|
+
seen.append(id(val))
|
|
210
|
+
try:
|
|
211
|
+
if isinstance(val, dict):
|
|
212
|
+
return _plain(cfg, val.items(), depth, seen)
|
|
213
|
+
|
|
214
|
+
if isinstance(val, (list, tuple, set, frozenset)):
|
|
215
|
+
out = []
|
|
216
|
+
for i, item in enumerate(val):
|
|
217
|
+
c = _snapshot(cfg, item, i, depth + 1, seen)
|
|
218
|
+
out.append(None if c is _DROP else c)
|
|
219
|
+
return out
|
|
220
|
+
|
|
221
|
+
if isinstance(val, BaseException):
|
|
222
|
+
out = {"message": _clean_string(cfg, str(val))}
|
|
223
|
+
for k, v in _public(val):
|
|
224
|
+
c = _snapshot(cfg, v, k, depth + 1, seen)
|
|
225
|
+
if c is not _DROP:
|
|
226
|
+
out[k] = c
|
|
227
|
+
return out
|
|
228
|
+
|
|
229
|
+
to_json = getattr(val, "to_json", None)
|
|
230
|
+
if callable(to_json):
|
|
231
|
+
rec = to_json()
|
|
232
|
+
if rec is not val:
|
|
233
|
+
return _snapshot(cfg, rec, key, depth + 1, seen)
|
|
234
|
+
|
|
235
|
+
if hasattr(val, "__dict__"):
|
|
236
|
+
return _plain(cfg, _public(val), depth, seen)
|
|
237
|
+
|
|
238
|
+
return _clean_string(cfg, str(val))
|
|
239
|
+
finally:
|
|
240
|
+
seen.pop()
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
# An object's own public attributes: the private ones hold the pipeline's
|
|
244
|
+
# live references (an entity's client, an error's context).
|
|
245
|
+
def _public(obj):
|
|
246
|
+
return [(k, v) for k, v in vars(obj).items()
|
|
247
|
+
if not str(k).startswith("_")]
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
def _plain(cfg, items, depth, seen):
|
|
251
|
+
out = {}
|
|
252
|
+
for k, v in items:
|
|
253
|
+
c = _snapshot(cfg, v, k, depth + 1, seen)
|
|
254
|
+
if c is not _DROP:
|
|
255
|
+
out[_clean_name(cfg, out, str(k))] = c
|
|
256
|
+
return out
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
# A registered value used as a property name is masked like any other
|
|
260
|
+
# string; names that mask alike take a counter, so none is lost.
|
|
261
|
+
def _clean_name(cfg, out, key):
|
|
262
|
+
name = _clean_string(cfg, key)
|
|
263
|
+
if name == key or name not in out:
|
|
264
|
+
return name
|
|
265
|
+
i = 1
|
|
266
|
+
while name + "#" + str(i) in out:
|
|
267
|
+
i += 1
|
|
268
|
+
return name + "#" + str(i)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
# An exception is cleaned IN PLACE: it is about to be raised, and its
|
|
272
|
+
# identity matters to the caller. The message lives in `args`.
|
|
273
|
+
def _clean_exception(cfg, err):
|
|
274
|
+
args = tuple(_clean_string(cfg, a) if isinstance(a, str) else a for a in err.args)
|
|
275
|
+
if args != err.args:
|
|
276
|
+
err.args = args
|
|
277
|
+
|
|
278
|
+
for k, v in _public(err):
|
|
279
|
+
if isinstance(v, str):
|
|
280
|
+
v = _mask_value(cfg, v) if _sensitive_key(cfg, k) else _clean_string(cfg, v)
|
|
281
|
+
elif v is not None and not isinstance(v, (bool, int, float)) and not _is_function(v):
|
|
282
|
+
v = _snapshot(cfg, v, k, 1, [])
|
|
283
|
+
name = _clean_string(cfg, k)
|
|
284
|
+
if name != k:
|
|
285
|
+
delattr(err, k)
|
|
286
|
+
name = _clean_name(cfg, vars(err), k)
|
|
287
|
+
setattr(err, name, v)
|
|
288
|
+
|
|
289
|
+
notes = getattr(err, "__notes__", None)
|
|
290
|
+
if isinstance(notes, list):
|
|
291
|
+
err.__notes__ = [_clean_string(cfg, n) if isinstance(n, str) else n for n in notes]
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
# Clean a value on its way out. A string is redacted; an exception is
|
|
295
|
+
# redacted in place; anything else comes back as a masked plain-data copy.
|
|
4
296
|
def clean_util(ctx, val):
|
|
5
|
-
|
|
297
|
+
cfg = _clean_config(ctx)
|
|
298
|
+
|
|
299
|
+
if cfg["active"] is False:
|
|
300
|
+
return val
|
|
301
|
+
|
|
302
|
+
if isinstance(val, str):
|
|
303
|
+
return _clean_string(cfg, val)
|
|
304
|
+
|
|
305
|
+
if isinstance(val, BaseException):
|
|
306
|
+
_clean_exception(cfg, val)
|
|
307
|
+
return val
|
|
308
|
+
|
|
309
|
+
out = _snapshot(cfg, val, None, 0, [])
|
|
310
|
+
return None if out is _DROP else out
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
# Is this key name sensitive under the context's clean configuration?
|
|
314
|
+
def clean_key(ctx, key):
|
|
315
|
+
return _sensitive_key(_clean_config(ctx), key)
|
|
@@ -2,11 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
def done_util(ctx):
|
|
5
|
-
|
|
6
|
-
ctx.ctrl.explain = ctx.utility.clean(ctx, ctx.ctrl.explain)
|
|
7
|
-
explain_result = ctx.ctrl.explain.get("result") if isinstance(ctx.ctrl.explain, dict) else None
|
|
8
|
-
if isinstance(explain_result, dict):
|
|
9
|
-
explain_result.pop("err", None)
|
|
5
|
+
clean_explain_util(ctx)
|
|
10
6
|
|
|
11
7
|
if ctx.result is not None and ctx.result.ok:
|
|
12
8
|
return ctx.result.resdata
|
|
@@ -14,3 +10,20 @@ def done_util(ctx):
|
|
|
14
10
|
# make_error raises on the default (throw) path; only returns bare
|
|
15
11
|
# resdata when throw_err is explicitly disabled.
|
|
16
12
|
return ctx.utility.make_error(ctx, None)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
# In place: the caller holds this very dict (ctrl is built from it), and a
|
|
16
|
+
# stream copies only its ctrl, so a reassignment would leave the raw record
|
|
17
|
+
# in their hands.
|
|
18
|
+
def clean_explain_util(ctx):
|
|
19
|
+
explain = ctx.ctrl.explain
|
|
20
|
+
if not isinstance(explain, dict):
|
|
21
|
+
return
|
|
22
|
+
cleaned = ctx.utility.clean(ctx, explain)
|
|
23
|
+
if isinstance(cleaned, dict) and cleaned is not explain:
|
|
24
|
+
explain.clear()
|
|
25
|
+
explain.update(cleaned)
|
|
26
|
+
# With clean off, explain.result is the live result object, not a dict.
|
|
27
|
+
result = explain.get("result")
|
|
28
|
+
if isinstance(result, dict):
|
|
29
|
+
explain["result"] = {k: v for k, v in result.items() if k != "err"}
|