@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
|
@@ -0,0 +1,535 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cmp,
|
|
3
|
+
File,
|
|
4
|
+
Content,
|
|
5
|
+
isAuthSuppressed,
|
|
6
|
+
isHttpBasicAuth,
|
|
7
|
+
resolveAuthIn,
|
|
8
|
+
resolveAuthName,
|
|
9
|
+
} from '@voxgig/sdkgen'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
// The canary sweep: every credential slot holds a distinctive value, every
|
|
13
|
+
// diagnostic feature this SDK ships is switched on with a capturing sink, a
|
|
14
|
+
// real operation runs through every outcome, and every string that leaves
|
|
15
|
+
// the SDK is searched for the canaries and their encoded forms. It also
|
|
16
|
+
// proves its own sensitivity: with clean switched off the canary MUST show.
|
|
17
|
+
const TestClean = cmp(function TestClean(props: any) {
|
|
18
|
+
const { model } = props.ctx$
|
|
19
|
+
const { target } = props
|
|
20
|
+
|
|
21
|
+
const auth = {
|
|
22
|
+
suppressed: isAuthSuppressed(model),
|
|
23
|
+
where: resolveAuthIn(model),
|
|
24
|
+
name: 'header' === resolveAuthIn(model)
|
|
25
|
+
? resolveAuthName(model).toLowerCase() : resolveAuthName(model),
|
|
26
|
+
basic: isHttpBasicAuth(model),
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
File({ name: 'clean_test.' + target.ext }, () => Content(render(model.const.Name, auth)))
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
function rbstr(s: string): string {
|
|
34
|
+
return JSON.stringify(String(s)).replace(/#\{/g, '\\#{')
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
// The class name carries the project prefix, and every helper sits inside
|
|
39
|
+
// it: the target's constant guard reads top-level declarations.
|
|
40
|
+
function render(Name: string, auth: {
|
|
41
|
+
suppressed: boolean, where: string, name: string, basic: boolean
|
|
42
|
+
}): string {
|
|
43
|
+
return `# ${Name} SDK clean test
|
|
44
|
+
#
|
|
45
|
+
# The canary sweep: every credential slot holds a distinctive value, every
|
|
46
|
+
# diagnostic feature this SDK ships is switched on with a capturing sink, a
|
|
47
|
+
# real operation runs through every outcome, and every string that leaves
|
|
48
|
+
# the SDK is searched for the canaries and their encoded forms. It also
|
|
49
|
+
# proves its own sensitivity: with clean switched off the canary MUST show.
|
|
50
|
+
|
|
51
|
+
require "minitest/autorun"
|
|
52
|
+
require "json"
|
|
53
|
+
require "pp"
|
|
54
|
+
require_relative "../${Name}_sdk"
|
|
55
|
+
|
|
56
|
+
class ${Name}CleanTest < Minitest::Test
|
|
57
|
+
# Generated: the credential's wire placement is fixed when the SDK is built.
|
|
58
|
+
AUTH = {
|
|
59
|
+
"suppressed" => ${auth.suppressed},
|
|
60
|
+
"where" => ${rbstr(auth.where)},
|
|
61
|
+
"name" => ${rbstr(auth.name)},
|
|
62
|
+
"basic" => ${auth.basic},
|
|
63
|
+
}.freeze
|
|
64
|
+
|
|
65
|
+
CANARY = {
|
|
66
|
+
"apikey" => "CANARY-APIKEY-k9x2m7q4p1",
|
|
67
|
+
"secret" => "CANARY-SECRET-w3e8r5t2y6",
|
|
68
|
+
"header" => "CANARY-HEADER-z1x4c7v0b3",
|
|
69
|
+
"value" => "CANARY-VALUE-n5m8b2v9c4",
|
|
70
|
+
"config" => "CANARY-CONFIG-h6j3k8l2m5",
|
|
71
|
+
}.freeze
|
|
72
|
+
|
|
73
|
+
MASK = "[redacted]"
|
|
74
|
+
|
|
75
|
+
# encodeURIComponent, the form a query credential travels in.
|
|
76
|
+
def self.pct(value)
|
|
77
|
+
value.gsub(/[^A-Za-z0-9\\-_.!~*'()]/) { |c| c.bytes.map { |b| format("%%%02X", b) }.join }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Every form a canary can travel in.
|
|
81
|
+
FORMS = (CANARY.values.flat_map { |v| [v, [v].pack("m0"), pct(v)] } +
|
|
82
|
+
[["#{CANARY['apikey']}:#{CANARY['secret']}"].pack("m0")]).freeze
|
|
83
|
+
|
|
84
|
+
module Sweep
|
|
85
|
+
module_function
|
|
86
|
+
|
|
87
|
+
# Header maps keep the caller's spelling; the assertion should not care.
|
|
88
|
+
def header(map, name)
|
|
89
|
+
return nil unless map.is_a?(Hash)
|
|
90
|
+
map.each { |k, v| return v if k.to_s.downcase == name.downcase }
|
|
91
|
+
nil
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def leaks(text)
|
|
95
|
+
FORMS.select { |f| text.include?(f) }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Every printed form of a value that left the SDK.
|
|
99
|
+
def forms(name, val)
|
|
100
|
+
out = []
|
|
101
|
+
surface(out, name, "json") { JSON.generate(val) }
|
|
102
|
+
surface(out, name, "string") { val.to_s }
|
|
103
|
+
surface(out, name, "inspect") { val.inspect }
|
|
104
|
+
surface(out, name, "pp") { PP.pp(val, +"") }
|
|
105
|
+
if val.is_a?(Exception)
|
|
106
|
+
surface(out, name, "message") { val.message.to_s }
|
|
107
|
+
surface(out, name, "full") { val.full_message(highlight: false) }
|
|
108
|
+
surface(out, name, "ivars") do
|
|
109
|
+
val.instance_variables.map { |v| [v, val.instance_variable_get(v)] }.inspect
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
out
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def surface(out, name, kind)
|
|
116
|
+
out << { "name" => "#{name}:#{kind}", "text" => yield.to_s }
|
|
117
|
+
rescue StandardError
|
|
118
|
+
nil
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def response(status, data, headers = nil)
|
|
122
|
+
h = { "content-type" => "application/json" }.merge(headers || {})
|
|
123
|
+
{
|
|
124
|
+
"status" => status,
|
|
125
|
+
"statusText" => status < 400 ? "OK" : "ERR",
|
|
126
|
+
"headers" => h,
|
|
127
|
+
"json" => -> { data },
|
|
128
|
+
"body" => JSON.generate(data),
|
|
129
|
+
}
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Captures the serialised context from inside the pipeline: what a hook
|
|
134
|
+
# author would hand to a logger.
|
|
135
|
+
class CaptureFeature < ${Name}BaseFeature
|
|
136
|
+
def initialize(sinks)
|
|
137
|
+
super()
|
|
138
|
+
@name = "capture"
|
|
139
|
+
@version = "0.0.1"
|
|
140
|
+
@active = true
|
|
141
|
+
@sinks = sinks
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def PreRequest(ctx); @sinks.concat(Sweep.forms("ctx@PreRequest", ctx)); end
|
|
145
|
+
def PreResponse(ctx); @sinks.concat(Sweep.forms("ctx@PreResponse", ctx)); end
|
|
146
|
+
|
|
147
|
+
# The SDK's own error as a hook reads it, which an observability feature
|
|
148
|
+
# logs.
|
|
149
|
+
def PreUnexpected(ctx)
|
|
150
|
+
@sinks.concat(Sweep.forms("ctx@PreUnexpected", ctx))
|
|
151
|
+
err = ctx.ctrl.err
|
|
152
|
+
@sinks.concat(Sweep.forms("ctrl.err@PreUnexpected", err)) if err.is_a?(${Name}Error)
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# A feature that raises from inside the pipeline, quoting the request it
|
|
157
|
+
# saw: an error make_error never handled.
|
|
158
|
+
class ThrowFeature < ${Name}BaseFeature
|
|
159
|
+
def initialize(response = true, unexpected = false)
|
|
160
|
+
super()
|
|
161
|
+
@name = "throwhook"
|
|
162
|
+
@version = "0.0.1"
|
|
163
|
+
@active = true
|
|
164
|
+
@response = response
|
|
165
|
+
@unexpected = unexpected
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def PreResponse(ctx)
|
|
169
|
+
raise "hook saw #{ctx.spec.inspect}" if @response
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Fires in make_error, and in the catch path before its cleaning.
|
|
173
|
+
def PreUnexpected(ctx)
|
|
174
|
+
raise "hook saw #{ctx.spec.inspect}" if @unexpected
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# A stream that succeeds, so the pipeline's terminal step never runs.
|
|
179
|
+
class StreamOkFeature < ${Name}BaseFeature
|
|
180
|
+
def initialize
|
|
181
|
+
super()
|
|
182
|
+
@name = "streamok"
|
|
183
|
+
@version = "0.0.1"
|
|
184
|
+
@active = true
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def PreDone(ctx)
|
|
188
|
+
data = ctx.result.resdata
|
|
189
|
+
ctx.result.stream = (data.is_a?(Array) ? data : (data.nil? ? [] : [data])).each
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# A feature that hands the caller the stream it was given.
|
|
194
|
+
class StreamFeature < ${Name}BaseFeature
|
|
195
|
+
def initialize(stream)
|
|
196
|
+
super()
|
|
197
|
+
@name = "streamed"
|
|
198
|
+
@version = "0.0.1"
|
|
199
|
+
@active = true
|
|
200
|
+
@stream = stream
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def PreDone(ctx)
|
|
204
|
+
ctx.result.stream = @stream
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
class CaptureLogger
|
|
209
|
+
def initialize(sinks)
|
|
210
|
+
@sinks = sinks
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def puts(line)
|
|
214
|
+
@sinks << { "name" => "log", "text" => line.to_s }
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Each scenario answers the transport's [response, err] pair.
|
|
219
|
+
SCENARIOS = [
|
|
220
|
+
["ok", ->(_url, _fd) {
|
|
221
|
+
[Sweep.response(200, { "id" => "i1", "name" => "n1" },
|
|
222
|
+
{ "x-session-token" => "RESP-TOKEN-a1b2c3d4e5" }), nil]
|
|
223
|
+
}],
|
|
224
|
+
["notfound", ->(_url, _fd) { [Sweep.response(404, { "error" => "no such record" }), nil] }],
|
|
225
|
+
["server", ->(_url, _fd) { [Sweep.response(500, { "error" => "boom" }), nil] }],
|
|
226
|
+
["transport", ->(url, _fd) {
|
|
227
|
+
[nil, RuntimeError.new("socket hang up (URL was: \\"#{url}\\")")]
|
|
228
|
+
}],
|
|
229
|
+
# The SDK's own error, its code quoting a registered value.
|
|
230
|
+
["coded", ->(_url, _fd) { [nil, ${Name}Error.new("denied_#{CANARY['apikey']}", "coded failure")] }],
|
|
231
|
+
["notjson", ->(_url, _fd) {
|
|
232
|
+
[{
|
|
233
|
+
"status" => 200, "statusText" => "OK", "headers" => {},
|
|
234
|
+
"json" => -> { raise "Unexpected token < in JSON" },
|
|
235
|
+
"body" => "<html>",
|
|
236
|
+
}, nil]
|
|
237
|
+
}],
|
|
238
|
+
].freeze
|
|
239
|
+
|
|
240
|
+
VARIANTS = [
|
|
241
|
+
["throw", -> { {} }],
|
|
242
|
+
["explain", -> { { "explain" => {} } }],
|
|
243
|
+
["nothrow", -> { { "throw" => false, "explain" => {} } }],
|
|
244
|
+
].freeze
|
|
245
|
+
|
|
246
|
+
# True when this SDK was generated with the named feature.
|
|
247
|
+
def has_feature?(name)
|
|
248
|
+
f = ${Name}Config.shared_config["feature"]
|
|
249
|
+
f.is_a?(Hash) && !f[name].nil?
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def make_sdk(scenario, sinks, cleanopts = nil, extra = [])
|
|
253
|
+
capture = ->(name) { ->(rec) { sinks.concat(Sweep.forms(name, rec)) } }
|
|
254
|
+
feature = {}
|
|
255
|
+
feature["log"] = { "active" => true, "logger" => CaptureLogger.new(sinks) } if has_feature?("log")
|
|
256
|
+
feature["debug"] = { "active" => true, "on_entry" => capture.call("debug") } if has_feature?("debug")
|
|
257
|
+
feature["audit"] = { "active" => true, "sink" => capture.call("audit") } if has_feature?("audit")
|
|
258
|
+
feature["telemetry"] = { "active" => true, "exporter" => capture.call("telemetry") } if has_feature?("telemetry")
|
|
259
|
+
feature["cost"] = { "active" => true, "sink" => capture.call("cost") } if has_feature?("cost")
|
|
260
|
+
feature["metrics"] = { "active" => true } if has_feature?("metrics")
|
|
261
|
+
feature["clienttrack"] = { "active" => true } if has_feature?("clienttrack")
|
|
262
|
+
|
|
263
|
+
respond = scenario[1]
|
|
264
|
+
${Name}SDK.new({
|
|
265
|
+
"apikey" => CANARY["apikey"],
|
|
266
|
+
"secret" => CANARY["secret"],
|
|
267
|
+
"headers" => { "X-Custom-Token" => CANARY["header"] },
|
|
268
|
+
"clean" => { "values" => CANARY["value"] }.merge(cleanopts || {}),
|
|
269
|
+
"feature" => feature,
|
|
270
|
+
"extend" => [CaptureFeature.new(sinks)] + extra,
|
|
271
|
+
"utility" => { "fetcher" => ->(_ctx, url, fetchdef) { respond.call(url, fetchdef) } },
|
|
272
|
+
})
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
# The first operation that completes against a plain 200: with no
|
|
276
|
+
# arguments, else with every path parameter its points declare filled in.
|
|
277
|
+
# An entity accessor is a capitalised client method whose result answers
|
|
278
|
+
# get_name, as the feature corpus runner finds them.
|
|
279
|
+
def usable_op
|
|
280
|
+
plain = ${Name}SDK.new({
|
|
281
|
+
"apikey" => CANARY["apikey"],
|
|
282
|
+
"utility" => { "fetcher" => ->(_ctx, _url, _fd) { [Sweep.response(200, { "id" => "i1" }), nil] } },
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
found = {}
|
|
286
|
+
plain.public_methods(false).each do |m|
|
|
287
|
+
name = m.to_s
|
|
288
|
+
next unless name[0] =~ /[A-Z]/
|
|
289
|
+
ent = begin
|
|
290
|
+
plain.public_send(m)
|
|
291
|
+
rescue StandardError
|
|
292
|
+
next
|
|
293
|
+
end
|
|
294
|
+
next unless ent.respond_to?(:get_name)
|
|
295
|
+
found[ent.get_name.to_s] = name
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
entities = ${Name}Config.shared_config["entity"] || {}
|
|
299
|
+
found.keys.sort.each do |entname|
|
|
300
|
+
accessor = found[entname]
|
|
301
|
+
%w[list load create update remove].each do |op|
|
|
302
|
+
next unless plain.public_send(accessor).respond_to?(op)
|
|
303
|
+
filled = {}
|
|
304
|
+
points = entities.dig(entname, "op", op, "points")
|
|
305
|
+
(points.is_a?(Array) ? points : []).each do |point|
|
|
306
|
+
params = point.is_a?(Hash) ? point.dig("args", "params") : nil
|
|
307
|
+
(params.is_a?(Array) ? params : []).each do |p|
|
|
308
|
+
filled[p["name"]] = "p1" if p.is_a?(Hash) && p["name"].is_a?(String)
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
[{}, filled].each do |match|
|
|
312
|
+
plain.public_send(accessor).public_send(op, match.dup, {})
|
|
313
|
+
return { "accessor" => accessor, "op" => op, "match" => match }
|
|
314
|
+
rescue StandardError
|
|
315
|
+
next
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
nil
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
def drive(sdk, target, ctrl, sinks)
|
|
323
|
+
# A caller may keep the record it passed rather than read ctrl["explain"].
|
|
324
|
+
held = ctrl["explain"]
|
|
325
|
+
out = nil
|
|
326
|
+
err = nil
|
|
327
|
+
begin
|
|
328
|
+
out = sdk.public_send(target["accessor"]).public_send(target["op"], target["match"].dup, ctrl)
|
|
329
|
+
rescue StandardError => e
|
|
330
|
+
err = e
|
|
331
|
+
end
|
|
332
|
+
sinks.concat(Sweep.forms("error", err)) unless err.nil?
|
|
333
|
+
sinks.concat(Sweep.forms("result", out)) unless out.nil?
|
|
334
|
+
sinks.concat(Sweep.forms("explain", ctrl["explain"])) unless ctrl["explain"].nil?
|
|
335
|
+
sinks.concat(Sweep.forms("explain:held", held)) unless held.nil? || held.equal?(ctrl["explain"])
|
|
336
|
+
err
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
def test_no_credential_leaves_the_sdk_in_any_form
|
|
340
|
+
target = usable_op
|
|
341
|
+
skip "no operation of this SDK completes against a plain 200; nothing to sweep" if target.nil?
|
|
342
|
+
|
|
343
|
+
sinks = []
|
|
344
|
+
errors = {}
|
|
345
|
+
explains = {}
|
|
346
|
+
|
|
347
|
+
SCENARIOS.each do |scenario|
|
|
348
|
+
VARIANTS.each do |vname, make_ctrl|
|
|
349
|
+
sdk = make_sdk(scenario, sinks)
|
|
350
|
+
ctrl = make_ctrl.call
|
|
351
|
+
err = drive(sdk, target, ctrl, sinks)
|
|
352
|
+
key = "#{scenario[0]}/#{vname}"
|
|
353
|
+
errors[key] = err unless err.nil?
|
|
354
|
+
explains[key] = ctrl["explain"] unless ctrl["explain"].nil?
|
|
355
|
+
sinks.concat(Sweep.forms("sdk", sdk))
|
|
356
|
+
end
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
# A credential mistyped as a map is rejected by validation, whose
|
|
360
|
+
# message quotes the value it rejected.
|
|
361
|
+
rejected = nil
|
|
362
|
+
begin
|
|
363
|
+
${Name}SDK.new({ "apikey" => { "value" => CANARY["apikey"] }, "clean" => { "values" => CANARY["value"] } })
|
|
364
|
+
rescue StandardError => e
|
|
365
|
+
rejected = e
|
|
366
|
+
end
|
|
367
|
+
refute_nil rejected, "a credential mistyped as a map should be rejected"
|
|
368
|
+
sinks.concat(Sweep.forms("rejected", rejected))
|
|
369
|
+
|
|
370
|
+
# An error a feature hook raises, quoting the request, skips make_error.
|
|
371
|
+
# The variant raising only in PreUnexpected reaches make_error's own
|
|
372
|
+
# firing through a 404.
|
|
373
|
+
hooked = nil
|
|
374
|
+
[[SCENARIOS[0], ThrowFeature.new], [SCENARIOS[0], ThrowFeature.new(true, true)],
|
|
375
|
+
[SCENARIOS[1], ThrowFeature.new(false, true)]].each do |scenario, hook|
|
|
376
|
+
hooked = make_sdk(scenario, sinks, nil, [hook])
|
|
377
|
+
refute_nil drive(hooked, target, { "explain" => {} }, sinks), "the throwing hook should fail the operation"
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
# Iterating a stream runs inside the same catch path as the operation,
|
|
381
|
+
# and the explain record the caller passed is cleaned however it ends;
|
|
382
|
+
# what the caller's own block raises passes through as it was raised.
|
|
383
|
+
stream = ->(extra, explain = {}) {
|
|
384
|
+
make_sdk(SCENARIOS[0], sinks, nil, extra).public_send(target["accessor"])
|
|
385
|
+
.stream(target["op"], { "reqmatch" => target["match"].dup }, { "ctrl" => { "explain" => explain } })
|
|
386
|
+
}
|
|
387
|
+
failing = Enumerator.new { |_y| raise "stream saw #{CANARY['apikey']}" }
|
|
388
|
+
[["stream", [StreamFeature.new(failing)]], ["stream-ok", [StreamOkFeature.new]],
|
|
389
|
+
["stream-plain", []]].each do |name, extra|
|
|
390
|
+
explain = {}
|
|
391
|
+
streamerr = nil
|
|
392
|
+
begin
|
|
393
|
+
stream.call(extra, explain).each { |_item| }
|
|
394
|
+
rescue StandardError => e
|
|
395
|
+
streamerr = e
|
|
396
|
+
end
|
|
397
|
+
assert_equal name == "stream", !streamerr.nil?, "#{name}: only the failing stream raises"
|
|
398
|
+
sinks.concat(Sweep.forms(name, streamerr)) unless streamerr.nil?
|
|
399
|
+
refute_empty explain, "#{name}: the explain record was not filled"
|
|
400
|
+
sinks.concat(Sweep.forms("#{name}:explain", explain))
|
|
401
|
+
end
|
|
402
|
+
mine = RuntimeError.new("caller saw #{CANARY['apikey']}")
|
|
403
|
+
got = begin
|
|
404
|
+
stream.call([StreamFeature.new([1].each)]).each { |_item| raise mine }
|
|
405
|
+
rescue StandardError => e
|
|
406
|
+
e
|
|
407
|
+
end
|
|
408
|
+
assert_same mine, got, "the caller's own error should leave the stream as raised"
|
|
409
|
+
|
|
410
|
+
# A registered value used as a property name is masked; names that
|
|
411
|
+
# mask alike are all kept.
|
|
412
|
+
named = hooked.get_utility.clean.call(hooked.get_root_ctx,
|
|
413
|
+
{ CANARY["header"] => 1, CANARY["value"] => 2, "plain" => 3 })
|
|
414
|
+
assert_equal({ MASK => 1, "#{MASK}#1" => 2, "plain" => 3 }, named)
|
|
415
|
+
sinks.concat(Sweep.forms("named", named))
|
|
416
|
+
|
|
417
|
+
# The generated config's own clean block is read beside the caller's,
|
|
418
|
+
# and is not changed by it.
|
|
419
|
+
util = hooked.get_utility
|
|
420
|
+
cfgclean = { "keys" => "zzsens", "values" => CANARY["config"] }
|
|
421
|
+
built = util.make_options.call(util.make_context.call({
|
|
422
|
+
"utility" => util,
|
|
423
|
+
"config" => { "options" => { "clean" => cfgclean } },
|
|
424
|
+
"options" => { "clean" => { "values" => CANARY["value"] } },
|
|
425
|
+
}, nil))
|
|
426
|
+
cfgctx = util.make_context.call({ "options" => built }, nil)
|
|
427
|
+
seeded = util.clean.call(cfgctx, "config #{CANARY['config']} caller #{CANARY['value']}")
|
|
428
|
+
sinks << { "name" => "config-clean", "text" => seeded.to_s }
|
|
429
|
+
assert_equal "config #{MASK} caller #{MASK}", seeded
|
|
430
|
+
assert_equal({ "my_zzsens" => MASK, "other" => "y" },
|
|
431
|
+
util.clean.call(cfgctx, { "my_zzsens" => "x", "other" => "y" }))
|
|
432
|
+
assert_equal({ "keys" => "zzsens", "values" => CANARY["config"] }, cfgclean)
|
|
433
|
+
|
|
434
|
+
# With no clean option at all, the schema defaults still apply.
|
|
435
|
+
bare = ${Name}SDK.new({
|
|
436
|
+
"apikey" => CANARY["apikey"],
|
|
437
|
+
"secret" => CANARY["secret"],
|
|
438
|
+
"headers" => { "X-Custom-Token" => CANARY["header"] },
|
|
439
|
+
"utility" => { "fetcher" => ->(_ctx, url, fetchdef) { SCENARIOS[1][1].call(url, fetchdef) } },
|
|
440
|
+
})
|
|
441
|
+
refute_nil drive(bare, target, { "explain" => {} }, sinks), "the 404 should fail"
|
|
442
|
+
|
|
443
|
+
# A feature's name is not a field name: only the sensitive names inside
|
|
444
|
+
# its settings register. An entity block, of per-entity settings or
|
|
445
|
+
# seeded records keyed by entity name and id, is not read at all.
|
|
446
|
+
featured = ${Name}SDK.new({
|
|
447
|
+
"apikey" => CANARY["apikey"],
|
|
448
|
+
"feature" => {
|
|
449
|
+
"zzsecrets" => { "active" => false, "kind" => "PLAINSETTING-q8w2e4r6" },
|
|
450
|
+
"zzfeat" => { "active" => false, "apitoken" => "FEATTOKEN-z9y8x7w6" },
|
|
451
|
+
"test" => { "active" => false, "entity" => {
|
|
452
|
+
"zztoken" => { "ZZTOKEN01" => { "note" => "PLAINRECORD-t5r3e1w9" } } } },
|
|
453
|
+
},
|
|
454
|
+
"entity" => { "zztoken" => { "alias" => { "zzkey" => "PLAINALIAS-m2n4b6v8" } } },
|
|
455
|
+
})
|
|
456
|
+
fclean = featured.get_utility.clean
|
|
457
|
+
fplain = fclean.call(featured.get_root_ctx, "kind PLAINSETTING-q8w2e4r6")
|
|
458
|
+
ftoken = fclean.call(featured.get_root_ctx, "token FEATTOKEN-z9y8x7w6")
|
|
459
|
+
frecord = fclean.call(featured.get_root_ctx, "record PLAINRECORD-t5r3e1w9")
|
|
460
|
+
falias = fclean.call(featured.get_root_ctx, "alias PLAINALIAS-m2n4b6v8")
|
|
461
|
+
|
|
462
|
+
leaked = sinks
|
|
463
|
+
.map { |s| [s["name"], Sweep.leaks(s["text"])] }
|
|
464
|
+
.reject { |_, found| found.empty? }
|
|
465
|
+
|
|
466
|
+
puts "clean: swept #{sinks.length} surface(s), #{leaked.length} leak(s)"
|
|
467
|
+
|
|
468
|
+
assert_equal 0, leaked.length, "credential leaked through: " +
|
|
469
|
+
leaked.map { |name, found| "#{name} [#{found.join(', ')}]" }.join("; ")
|
|
470
|
+
|
|
471
|
+
# The positive half: the slot the credential travelled in is masked,
|
|
472
|
+
# and an unregistered token in a response header is masked by name.
|
|
473
|
+
notfound = errors["notfound/throw"]
|
|
474
|
+
refute_nil notfound, "the 404 scenario must raise"
|
|
475
|
+
assert_equal 404, notfound.status
|
|
476
|
+
unless AUTH["suppressed"]
|
|
477
|
+
spec = notfound.spec.is_a?(Hash) ? notfound.spec : {}
|
|
478
|
+
if AUTH["where"] == "query"
|
|
479
|
+
assert_equal MASK, Sweep.header(spec["query"], AUTH["name"])
|
|
480
|
+
elsif AUTH["where"] == "cookie"
|
|
481
|
+
cookie = Sweep.header(spec["headers"], "cookie").to_s
|
|
482
|
+
assert cookie.include?(MASK), "cookie: #{cookie}"
|
|
483
|
+
else
|
|
484
|
+
got = Sweep.header(spec["headers"], AUTH["name"]).to_s
|
|
485
|
+
assert got.end_with?(MASK), "#{AUTH['name']}: #{got}"
|
|
486
|
+
end
|
|
487
|
+
end
|
|
488
|
+
assert_equal MASK, Sweep.header(notfound.spec["headers"], "x-custom-token")
|
|
489
|
+
|
|
490
|
+
coded = errors["coded/throw"]
|
|
491
|
+
assert coded.is_a?(${Name}Error) && coded.code == "denied_#{MASK}", coded.inspect
|
|
492
|
+
|
|
493
|
+
assert_equal "kind PLAINSETTING-q8w2e4r6", fplain
|
|
494
|
+
assert_equal "token #{MASK}", ftoken
|
|
495
|
+
assert_equal "record PLAINRECORD-t5r3e1w9", frecord
|
|
496
|
+
assert_equal "alias PLAINALIAS-m2n4b6v8", falias
|
|
497
|
+
|
|
498
|
+
explained = explains["ok/explain"] || {}
|
|
499
|
+
refute_nil explained["result"], "the explain record should carry the result"
|
|
500
|
+
assert_equal MASK, Sweep.header(explained["result"]["headers"], "x-session-token")
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
def test_the_sweep_can_see_a_leak_clean_switched_off_shows_the_credential
|
|
504
|
+
target = usable_op
|
|
505
|
+
skip "no operation of this SDK completes against a plain 200; nothing to sweep" if target.nil?
|
|
506
|
+
|
|
507
|
+
sinks = []
|
|
508
|
+
sdk = make_sdk(SCENARIOS[1], sinks, { "active" => false })
|
|
509
|
+
err = drive(sdk, target, {}, sinks)
|
|
510
|
+
refute_nil err
|
|
511
|
+
|
|
512
|
+
# Explaining a failure must not cost it its error.
|
|
513
|
+
explained = drive(make_sdk(SCENARIOS[1], [], { "active" => false }), target, { "explain" => {} }, [])
|
|
514
|
+
assert_equal err.message, explained&.message, "with clean off, explain lost the error"
|
|
515
|
+
|
|
516
|
+
leaked = sinks.select { |s| !Sweep.leaks(s["text"]).empty? }
|
|
517
|
+
assert !leaked.empty?, "with clean off, nothing showed the canary: the sweep is blind"
|
|
518
|
+
|
|
519
|
+
unless AUTH["suppressed"]
|
|
520
|
+
# With clean off the spec is the live object; its default print shows
|
|
521
|
+
# every field.
|
|
522
|
+
text = err.spec.inspect
|
|
523
|
+
pair = ["#{CANARY['apikey']}:#{CANARY['secret']}"].pack("m0")
|
|
524
|
+
assert text.include?(CANARY["apikey"]) || text.include?(pair),
|
|
525
|
+
"the raw spec should carry the credential when clean is off"
|
|
526
|
+
end
|
|
527
|
+
end
|
|
528
|
+
end
|
|
529
|
+
`
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
export {
|
|
534
|
+
TestClean
|
|
535
|
+
}
|
|
@@ -9,6 +9,7 @@ import { cmp, each, Folder, File, Content, entityCollection,
|
|
|
9
9
|
|
|
10
10
|
import { TestEntity } from './TestEntity_rb'
|
|
11
11
|
import { TestDirect } from './TestDirect_rb'
|
|
12
|
+
import { TestClean } from './TestClean_rb'
|
|
12
13
|
import { ReadmeExamplesTest } from './ReadmeExamplesTest_rb'
|
|
13
14
|
|
|
14
15
|
|
|
@@ -45,6 +46,8 @@ end
|
|
|
45
46
|
TestDirect({ target, entity })
|
|
46
47
|
})
|
|
47
48
|
|
|
49
|
+
TestClean({ target })
|
|
50
|
+
|
|
48
51
|
// README example snippet test (syntax + offline test-mode run).
|
|
49
52
|
ReadmeExamplesTest({ target })
|
|
50
53
|
})
|