@voxgig/sdkgen 4.32.1 → 4.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/voxgig-sdkgen +1 -1
- package/dist/helpers/naming.js +1 -1
- package/dist/helpers/naming.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/model/sdkgen.aontu +7 -1
- package/package.json +1 -1
- package/project/.sdk/model/feature/debug.aontu +3 -1
- package/project/.sdk/src/cmp/c/PrepareAuth_c.ts +8 -28
- package/project/.sdk/src/cmp/c/TestClean_c.ts +774 -0
- package/project/.sdk/src/cmp/c/Test_c.ts +3 -0
- package/project/.sdk/src/cmp/c/fragment/Entity.fragment.c +16 -5
- package/project/.sdk/src/cmp/c/fragment/Main.fragment.c +1 -1
- package/project/.sdk/src/cmp/clojure/PrepareAuth_clojure.ts +3 -0
- package/project/.sdk/src/cmp/clojure/TestClean_clojure.ts +473 -0
- package/project/.sdk/src/cmp/clojure/Test_clojure.ts +6 -0
- package/project/.sdk/src/cmp/clojure/fragment/Entity.fragment.clj +18 -8
- package/project/.sdk/src/cmp/cpp/PrepareAuth_cpp.ts +3 -0
- package/project/.sdk/src/cmp/cpp/TestClean_cpp.ts +782 -0
- package/project/.sdk/src/cmp/cpp/TestEntity_cpp.ts +1 -1
- package/project/.sdk/src/cmp/cpp/Test_cpp.ts +2 -0
- package/project/.sdk/src/cmp/csharp/PrepareAuth_csharp.ts +3 -0
- package/project/.sdk/src/cmp/csharp/TestClean_csharp.ts +887 -0
- package/project/.sdk/src/cmp/csharp/Test_csharp.ts +2 -0
- package/project/.sdk/src/cmp/csharp/fragment/EntityBase.fragment.cs +68 -4
- package/project/.sdk/src/cmp/csharp/fragment/Main.fragment.cs +8 -2
- package/project/.sdk/src/cmp/csharp/fragment/SdkError.fragment.cs +49 -0
- package/project/.sdk/src/cmp/elixir/PrepareAuth_elixir.ts +3 -0
- package/project/.sdk/src/cmp/elixir/Schema_elixir.ts +20 -10
- package/project/.sdk/src/cmp/elixir/TestClean_elixir.ts +666 -0
- package/project/.sdk/src/cmp/elixir/Test_elixir.ts +4 -0
- package/project/.sdk/src/cmp/elixir/fragment/Main.fragment.ex +1 -1
- package/project/.sdk/src/cmp/elixir/fragment/Pipeline.fragment.ex +14 -2
- package/project/.sdk/src/cmp/go/PrepareAuth_go.ts +3 -0
- package/project/.sdk/src/cmp/go/TestClean_go.ts +804 -0
- package/project/.sdk/src/cmp/go/Test_go.ts +3 -0
- package/project/.sdk/src/cmp/go/fragment/Entity.fragment.go +54 -4
- package/project/.sdk/src/cmp/go/fragment/Main.fragment.go +27 -2
- package/project/.sdk/src/cmp/java/PrepareAuth_java.ts +3 -0
- package/project/.sdk/src/cmp/java/TestClean_java.ts +884 -0
- package/project/.sdk/src/cmp/java/Test_java.ts +2 -0
- package/project/.sdk/src/cmp/java/fragment/EntityBase.fragment.java +56 -11
- package/project/.sdk/src/cmp/java/fragment/SdkError.fragment.java +36 -3
- package/project/.sdk/src/cmp/js/PrepareAuth_js.ts +3 -0
- package/project/.sdk/src/cmp/js/TestClean_js.ts +458 -0
- package/project/.sdk/src/cmp/js/Test_js.ts +2 -0
- package/project/.sdk/src/cmp/js/fragment/EntityBase.fragment.js +5 -4
- package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/EntityListOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/Main.fragment.js +11 -2
- package/project/.sdk/src/cmp/js/fragment/SdkError.fragment.js +17 -1
- package/project/.sdk/src/cmp/kotlin/Package_kotlin.ts +5 -0
- package/project/.sdk/src/cmp/kotlin/PrepareAuth_kotlin.ts +3 -0
- package/project/.sdk/src/cmp/kotlin/TestClean_kotlin.ts +654 -0
- package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +3 -0
- package/project/.sdk/src/cmp/kotlin/fragment/EntityBase.fragment.kt +44 -11
- package/project/.sdk/src/cmp/kotlin/fragment/SdkError.fragment.kt +31 -0
- package/project/.sdk/src/cmp/lua/PrepareAuth_lua.ts +3 -0
- package/project/.sdk/src/cmp/lua/TestClean_lua.ts +769 -0
- package/project/.sdk/src/cmp/lua/Test_lua.ts +3 -0
- package/project/.sdk/src/cmp/lua/fragment/Entity.fragment.lua +77 -1
- package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +49 -2
- package/project/.sdk/src/cmp/ocaml/Entity_ocaml.ts +3 -2
- package/project/.sdk/src/cmp/ocaml/PrepareAuth_ocaml.ts +4 -25
- package/project/.sdk/src/cmp/ocaml/TestClean_ocaml.ts +538 -0
- package/project/.sdk/src/cmp/ocaml/Test_ocaml.ts +5 -0
- package/project/.sdk/src/cmp/ocaml/fragment/RunOp.fragment.ml +16 -4
- package/project/.sdk/src/cmp/perl/PrepareAuth_perl.ts +3 -0
- package/project/.sdk/src/cmp/perl/TestClean_perl.ts +619 -0
- package/project/.sdk/src/cmp/perl/Test_perl.ts +3 -0
- package/project/.sdk/src/cmp/perl/fragment/Entity.fragment.pm +67 -5
- package/project/.sdk/src/cmp/perl/fragment/Main.fragment.pm +13 -1
- package/project/.sdk/src/cmp/php/PrepareAuth_php.ts +3 -0
- package/project/.sdk/src/cmp/php/TestClean_php.ts +809 -0
- package/project/.sdk/src/cmp/php/Test_php.ts +2 -0
- package/project/.sdk/src/cmp/php/fragment/Entity.fragment.php +96 -55
- package/project/.sdk/src/cmp/php/fragment/Main.fragment.php +15 -2
- package/project/.sdk/src/cmp/py/PrepareAuth_py.ts +3 -0
- package/project/.sdk/src/cmp/py/TestClean_py.ts +549 -0
- package/project/.sdk/src/cmp/py/Test_py.ts +3 -0
- package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +83 -55
- package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +19 -3
- package/project/.sdk/src/cmp/rb/PrepareAuth_rb.ts +3 -0
- package/project/.sdk/src/cmp/rb/TestClean_rb.ts +535 -0
- package/project/.sdk/src/cmp/rb/Test_rb.ts +3 -0
- package/project/.sdk/src/cmp/rb/fragment/Entity.fragment.rb +108 -46
- package/project/.sdk/src/cmp/rb/fragment/Main.fragment.rb +12 -1
- package/project/.sdk/src/cmp/rust/PrepareAuth_rust.ts +9 -45
- package/project/.sdk/src/cmp/rust/TestClean_rust.ts +881 -0
- package/project/.sdk/src/cmp/rust/Test_rust.ts +3 -0
- package/project/.sdk/src/cmp/rust/fragment/Entity.fragment.rs +14 -6
- package/project/.sdk/src/cmp/rust/fragment/Main.fragment.rs +17 -1
- package/project/.sdk/src/cmp/rust/fragment/SdkError.fragment.rs +34 -2
- package/project/.sdk/src/cmp/scala/PrepareAuth_scala.ts +3 -0
- package/project/.sdk/src/cmp/scala/TestClean_scala.ts +608 -0
- package/project/.sdk/src/cmp/scala/Test_scala.ts +3 -0
- package/project/.sdk/src/cmp/scala/fragment/EntityBase.fragment.scala +58 -6
- package/project/.sdk/src/cmp/swift/PrepareAuth_swift.ts +3 -0
- package/project/.sdk/src/cmp/swift/TestClean_swift.ts +671 -0
- package/project/.sdk/src/cmp/swift/Test_swift.ts +3 -0
- package/project/.sdk/src/cmp/swift/fragment/EntityBase.fragment.swift +10 -0
- package/project/.sdk/src/cmp/swift/fragment/Main.fragment.swift +16 -2
- package/project/.sdk/src/cmp/swift/fragment/SdkError.fragment.swift +47 -3
- package/project/.sdk/src/cmp/ts/PrepareAuth_ts.ts +3 -0
- package/project/.sdk/src/cmp/ts/TestClean_ts.ts +465 -0
- package/project/.sdk/src/cmp/ts/Test_ts.ts +2 -0
- package/project/.sdk/src/cmp/ts/fragment/EntityBase.fragment.ts +5 -4
- package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +8 -2
- package/project/.sdk/src/cmp/ts/fragment/SdkError.fragment.ts +20 -2
- package/project/.sdk/src/cmp/zig/PrepareAuth_zig.ts +3 -0
- package/project/.sdk/src/cmp/zig/TestClean_zig.ts +791 -0
- package/project/.sdk/src/cmp/zig/Test_zig.ts +5 -0
- package/project/.sdk/src/cmp/zig/fragment/Build.fragment.zig +19 -0
- package/project/.sdk/src/cmp/zig/fragment/Entity.fragment.zig +14 -5
- package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +1 -1
- package/project/.sdk/tm/c/core/context.c +25 -0
- package/project/.sdk/tm/c/core/error.c +16 -0
- package/project/.sdk/tm/c/core/sdk.h +22 -0
- package/project/.sdk/tm/c/feature/audit.c +2 -0
- package/project/.sdk/tm/c/feature/cost.c +1 -0
- package/project/.sdk/tm/c/feature/debug.c +19 -29
- package/project/.sdk/tm/c/feature/log.c +21 -2
- package/project/.sdk/tm/c/feature/proxy.c +55 -3
- package/project/.sdk/tm/c/feature/secrets.c +7 -0
- package/project/.sdk/tm/c/feature/telemetry.c +2 -0
- package/project/.sdk/tm/c/tests/feature_test.c +2 -2
- package/project/.sdk/tm/c/utility/clean.c +530 -8
- package/project/.sdk/tm/c/utility/done.c +28 -12
- package/project/.sdk/tm/c/utility/make_error.c +4 -3
- package/project/.sdk/tm/c/utility/make_options.c +71 -45
- package/project/.sdk/tm/clojure/feature/secrets/sdk/feature/secrets.clj +15 -0
- package/project/.sdk/tm/clojure/src/sdk/client.clj +20 -4
- package/project/.sdk/tm/clojure/src/sdk/core.clj +319 -35
- package/project/.sdk/tm/clojure/src/sdk/features.clj +68 -30
- package/project/.sdk/tm/clojure/test/sdk/test/feature.clj +4 -2
- package/project/.sdk/tm/clojure/test/sdk/test/pipeline.clj +47 -20
- package/project/.sdk/tm/clojure/test/sdk/test_runner.clj +4 -0
- package/project/.sdk/tm/cpp/core/types.hpp +93 -3
- package/project/.sdk/tm/cpp/feature/audit.hpp +1 -0
- package/project/.sdk/tm/cpp/feature/cost.hpp +1 -0
- package/project/.sdk/tm/cpp/feature/debug.hpp +20 -12
- package/project/.sdk/tm/cpp/feature/log.hpp +31 -9
- package/project/.sdk/tm/cpp/feature/proxy.hpp +52 -6
- package/project/.sdk/tm/cpp/feature/secrets.hpp +13 -0
- package/project/.sdk/tm/cpp/feature/telemetry.hpp +4 -2
- package/project/.sdk/tm/cpp/test/feature_test.cpp +2 -2
- package/project/.sdk/tm/cpp/utility/pipeline.hpp +426 -51
- package/project/.sdk/tm/csharp/core/Context.cs +32 -0
- package/project/.sdk/tm/csharp/core/Utility.cs +2 -0
- package/project/.sdk/tm/csharp/feature/AuditFeature.cs +1 -0
- package/project/.sdk/tm/csharp/feature/CostFeature.cs +7 -5
- package/project/.sdk/tm/csharp/feature/DebugFeature.cs +19 -16
- package/project/.sdk/tm/csharp/feature/FeatureOptions.cs +16 -0
- package/project/.sdk/tm/csharp/feature/LogFeature.cs +4 -1
- package/project/.sdk/tm/csharp/feature/ProxyFeature.cs +26 -5
- package/project/.sdk/tm/csharp/feature/SecretsFeature.cs +16 -0
- package/project/.sdk/tm/csharp/feature/TelemetryFeature.cs +4 -2
- package/project/.sdk/tm/csharp/test/FeatureTest.cs +2 -2
- package/project/.sdk/tm/csharp/utility/Clean.cs +440 -2
- package/project/.sdk/tm/csharp/utility/Done.cs +27 -11
- package/project/.sdk/tm/csharp/utility/MakeError.cs +19 -8
- package/project/.sdk/tm/csharp/utility/MakeOptions.cs +119 -29
- package/project/.sdk/tm/csharp/utility/MakeResponse.cs +21 -11
- package/project/.sdk/tm/csharp/utility/Register.cs +1 -0
- package/project/.sdk/tm/elixir/lib/projectname/context.ex +19 -0
- package/project/.sdk/tm/elixir/lib/projectname/entity_base.ex +22 -1
- package/project/.sdk/tm/elixir/lib/projectname/error.ex +24 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/audit.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/cost.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/debug.ex +13 -13
- package/project/.sdk/tm/elixir/lib/projectname/feature/log.ex +18 -5
- package/project/.sdk/tm/elixir/lib/projectname/feature/proxy.ex +19 -1
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets.ex +15 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/telemetry.ex +4 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature.ex +22 -0
- package/project/.sdk/tm/elixir/lib/projectname/utility.ex +464 -41
- package/project/.sdk/tm/elixir/test/feature_test.exs +3 -2
- package/project/.sdk/tm/go/core/context.go +42 -0
- package/project/.sdk/tm/go/core/error.go +30 -10
- package/project/.sdk/tm/go/core/utility_type.go +2 -0
- package/project/.sdk/tm/go/feature/audit_feature.go +1 -0
- package/project/.sdk/tm/go/feature/base_feature.go +12 -0
- package/project/.sdk/tm/go/feature/cost_feature.go +2 -2
- package/project/.sdk/tm/go/feature/debug_feature.go +14 -12
- package/project/.sdk/tm/go/feature/log_feature.go +13 -8
- package/project/.sdk/tm/go/feature/proxy_feature.go +26 -6
- package/project/.sdk/tm/go/feature/secrets_feature.go +19 -0
- package/project/.sdk/tm/go/feature/telemetry_feature.go +4 -2
- package/project/.sdk/tm/go/test/feature_test.go +2 -2
- package/project/.sdk/tm/go/utility/clean.go +585 -2
- package/project/.sdk/tm/go/utility/done.go +29 -9
- package/project/.sdk/tm/go/utility/make_error.go +51 -16
- package/project/.sdk/tm/go/utility/make_options.go +77 -36
- package/project/.sdk/tm/go/utility/register.go +12 -0
- package/project/.sdk/tm/java/core/Context.java +29 -0
- package/project/.sdk/tm/java/core/SdkClient.java +4 -2
- package/project/.sdk/tm/java/core/Utility.java +7 -0
- package/project/.sdk/tm/java/feature/AuditFeature.java +6 -0
- package/project/.sdk/tm/java/feature/CostFeature.java +5 -0
- package/project/.sdk/tm/java/feature/DebugFeature.java +25 -14
- package/project/.sdk/tm/java/feature/LogFeature.java +11 -4
- package/project/.sdk/tm/java/feature/ProxyFeature.java +41 -6
- package/project/.sdk/tm/java/feature/SecretsFeature.java +18 -0
- package/project/.sdk/tm/java/feature/TelemetryFeature.java +8 -2
- package/project/.sdk/tm/java/test/FeatureTest.java +2 -2
- package/project/.sdk/tm/java/utility/Clean.java +519 -1
- package/project/.sdk/tm/java/utility/Done.java +1 -1
- package/project/.sdk/tm/java/utility/MakeError.java +5 -1
- package/project/.sdk/tm/java/utility/MakeOptions.java +55 -31
- package/project/.sdk/tm/java/utility/Register.java +4 -0
- package/project/.sdk/tm/js/src/Context.js +5 -1
- package/project/.sdk/tm/js/src/feature/audit/AuditFeature.js +2 -2
- package/project/.sdk/tm/js/src/feature/cost/CostFeature.js +2 -2
- package/project/.sdk/tm/js/src/feature/debug/DebugFeature.js +13 -7
- package/project/.sdk/tm/js/src/feature/log/LogFeature.js +9 -5
- package/project/.sdk/tm/js/src/feature/proxy/ProxyFeature.js +19 -1
- package/project/.sdk/tm/js/src/feature/secrets/SecretsFeature.js +14 -0
- package/project/.sdk/tm/js/src/feature/telemetry/TelemetryFeature.js +4 -2
- package/project/.sdk/tm/js/src/utility/CleanUtility.js +294 -21
- package/project/.sdk/tm/js/src/utility/DoneUtility.js +17 -5
- package/project/.sdk/tm/js/src/utility/MakeErrorUtility.js +18 -2
- package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +39 -15
- package/project/.sdk/tm/js/src/utility/Utility.js +4 -2
- package/project/.sdk/tm/js/test/feature/harness.js +11 -1
- package/project/.sdk/tm/js/test/feature.test.js +9 -2
- package/project/.sdk/tm/kotlin/core/Context.kt +19 -0
- package/project/.sdk/tm/kotlin/core/SdkClient.kt +9 -2
- package/project/.sdk/tm/kotlin/core/Utility.kt +2 -0
- package/project/.sdk/tm/kotlin/feature/AuditFeature.kt +11 -9
- package/project/.sdk/tm/kotlin/feature/CostFeature.kt +8 -5
- package/project/.sdk/tm/kotlin/feature/DebugFeature.kt +15 -22
- package/project/.sdk/tm/kotlin/feature/LogFeature.kt +8 -4
- package/project/.sdk/tm/kotlin/feature/ProxyFeature.kt +26 -2
- package/project/.sdk/tm/kotlin/feature/SecretsFeature.kt +11 -0
- package/project/.sdk/tm/kotlin/feature/TelemetryFeature.kt +4 -2
- package/project/.sdk/tm/kotlin/test/FeatureTest.kt +2 -2
- package/project/.sdk/tm/kotlin/utility/CoreUtil.kt +447 -11
- package/project/.sdk/tm/kotlin/utility/MakeOptions.kt +38 -31
- package/project/.sdk/tm/kotlin/utility/Register.kt +1 -0
- package/project/.sdk/tm/lua/core/context.lua +43 -0
- package/project/.sdk/tm/lua/core/error.lua +36 -1
- package/project/.sdk/tm/lua/core/utility_type.lua +4 -0
- package/project/.sdk/tm/lua/feature/audit_feature.lua +2 -2
- package/project/.sdk/tm/lua/feature/cost_feature.lua +2 -2
- package/project/.sdk/tm/lua/feature/debug_feature.lua +21 -17
- package/project/.sdk/tm/lua/feature/log_feature.lua +2 -1
- package/project/.sdk/tm/lua/feature/proxy_feature.lua +23 -1
- package/project/.sdk/tm/lua/feature/secrets_feature.lua +18 -0
- package/project/.sdk/tm/lua/feature/telemetry_feature.lua +4 -2
- package/project/.sdk/tm/lua/test/feature/secrets/secrets_feature_test.lua +3 -2
- package/project/.sdk/tm/lua/test/feature_test.lua +10 -3
- package/project/.sdk/tm/lua/utility/clean.lua +426 -2
- package/project/.sdk/tm/lua/utility/clean_explain.lua +34 -0
- package/project/.sdk/tm/lua/utility/done.lua +1 -7
- package/project/.sdk/tm/lua/utility/make_error.lua +3 -1
- package/project/.sdk/tm/lua/utility/make_options.lua +76 -30
- package/project/.sdk/tm/lua/utility/register.lua +4 -1
- package/project/.sdk/tm/ocaml/Makefile +5 -1
- package/project/.sdk/tm/ocaml/feature/secrets_feature.ml +12 -1
- package/project/.sdk/tm/ocaml/sdk_features.ml +78 -18
- package/project/.sdk/tm/ocaml/sdk_helpers.ml +27 -0
- package/project/.sdk/tm/ocaml/sdk_runtime.ml +304 -26
- package/project/.sdk/tm/ocaml/sdk_types.ml +1 -0
- package/project/.sdk/tm/ocaml/test/feature/secrets/t_secrets.ml +3 -1
- package/project/.sdk/tm/ocaml/test/t_feature.ml +2 -2
- package/project/.sdk/tm/perl/core/context.pm +27 -0
- package/project/.sdk/tm/perl/core/error.pm +52 -5
- package/project/.sdk/tm/perl/feature/audit_feature.pm +2 -2
- package/project/.sdk/tm/perl/feature/cost_feature.pm +2 -2
- package/project/.sdk/tm/perl/feature/debug_feature.pm +17 -13
- package/project/.sdk/tm/perl/feature/log_feature.pm +3 -1
- package/project/.sdk/tm/perl/feature/proxy_feature.pm +21 -1
- package/project/.sdk/tm/perl/feature/secrets_feature.pm +20 -1
- package/project/.sdk/tm/perl/feature/telemetry_feature.pm +4 -2
- package/project/.sdk/tm/perl/t/feature.t +4 -2
- package/project/.sdk/tm/perl/utility/clean.pm +345 -1
- package/project/.sdk/tm/perl/utility/done.pm +24 -6
- package/project/.sdk/tm/perl/utility/make_error.pm +17 -4
- package/project/.sdk/tm/perl/utility/make_options.pm +33 -14
- package/project/.sdk/tm/php/core/Context.php +24 -1
- package/project/.sdk/tm/php/core/Error.php +34 -3
- package/project/.sdk/tm/php/core/UtilityType.php +4 -0
- package/project/.sdk/tm/php/feature/AuditFeature.php +2 -2
- package/project/.sdk/tm/php/feature/CostFeature.php +2 -2
- package/project/.sdk/tm/php/feature/DebugFeature.php +18 -9
- package/project/.sdk/tm/php/feature/LogFeature.php +5 -2
- package/project/.sdk/tm/php/feature/ProxyFeature.php +20 -1
- package/project/.sdk/tm/php/feature/SecretsFeature.php +18 -0
- package/project/.sdk/tm/php/feature/TelemetryFeature.php +4 -2
- package/project/.sdk/tm/php/test/FeatureTest.php +2 -2
- package/project/.sdk/tm/php/utility/Clean.php +438 -2
- package/project/.sdk/tm/php/utility/Done.php +14 -7
- package/project/.sdk/tm/php/utility/MakeError.php +9 -7
- package/project/.sdk/tm/php/utility/MakeOptions.php +62 -38
- package/project/.sdk/tm/php/utility/Register.php +2 -0
- package/project/.sdk/tm/py/pkg/core/context.py +17 -0
- package/project/.sdk/tm/py/pkg/core/error.py +42 -1
- package/project/.sdk/tm/py/pkg/core/utility_type.py +4 -0
- package/project/.sdk/tm/py/pkg/feature/audit_feature.py +2 -2
- package/project/.sdk/tm/py/pkg/feature/cost_feature.py +2 -2
- package/project/.sdk/tm/py/pkg/feature/debug_feature.py +17 -12
- package/project/.sdk/tm/py/pkg/feature/log_feature.py +2 -1
- package/project/.sdk/tm/py/pkg/feature/proxy_feature.py +18 -1
- package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +12 -0
- package/project/.sdk/tm/py/pkg/feature/telemetry_feature.py +4 -2
- package/project/.sdk/tm/py/pkg/utility/clean.py +311 -1
- package/project/.sdk/tm/py/pkg/utility/done.py +18 -5
- package/project/.sdk/tm/py/pkg/utility/make_error.py +9 -6
- package/project/.sdk/tm/py/pkg/utility/make_options.py +64 -25
- package/project/.sdk/tm/py/pkg/utility/make_response.py +19 -13
- package/project/.sdk/tm/py/pkg/utility/register.py +4 -2
- package/project/.sdk/tm/py/test/feature_harness.py +4 -0
- package/project/.sdk/tm/py/test/test_feature.py +2 -2
- package/project/.sdk/tm/py/test/test_primary_utility.py +1 -0
- package/project/.sdk/tm/rb/core/context.rb +28 -0
- package/project/.sdk/tm/rb/core/error.rb +30 -0
- package/project/.sdk/tm/rb/core/utility_type.rb +1 -1
- package/project/.sdk/tm/rb/feature/audit_feature.rb +2 -2
- package/project/.sdk/tm/rb/feature/cost_feature.rb +2 -2
- package/project/.sdk/tm/rb/feature/debug_feature.rb +15 -12
- package/project/.sdk/tm/rb/feature/log_feature.rb +3 -1
- package/project/.sdk/tm/rb/feature/proxy_feature.rb +25 -1
- package/project/.sdk/tm/rb/feature/secrets_feature.rb +17 -0
- package/project/.sdk/tm/rb/feature/telemetry_feature.rb +4 -2
- package/project/.sdk/tm/rb/test/feature_test.rb +4 -2
- package/project/.sdk/tm/rb/utility/clean.rb +312 -1
- package/project/.sdk/tm/rb/utility/done.rb +15 -5
- package/project/.sdk/tm/rb/utility/make_error.rb +13 -4
- package/project/.sdk/tm/rb/utility/make_options.rb +31 -12
- package/project/.sdk/tm/rb/utility/register.rb +2 -0
- package/project/.sdk/tm/rust/core/context.rs +55 -0
- package/project/.sdk/tm/rust/core/utility_type.rs +17 -0
- package/project/.sdk/tm/rust/feature/audit.rs +2 -0
- package/project/.sdk/tm/rust/feature/cost.rs +3 -2
- package/project/.sdk/tm/rust/feature/debug.rs +16 -16
- package/project/.sdk/tm/rust/feature/log.rs +42 -7
- package/project/.sdk/tm/rust/feature/proxy.rs +48 -2
- package/project/.sdk/tm/rust/feature/secrets.rs +12 -0
- package/project/.sdk/tm/rust/feature/telemetry.rs +2 -0
- package/project/.sdk/tm/rust/tests/feature_test.rs +2 -2
- package/project/.sdk/tm/rust/utility/clean.rs +446 -5
- package/project/.sdk/tm/rust/utility/done.rs +22 -12
- package/project/.sdk/tm/rust/utility/make_error.rs +4 -1
- package/project/.sdk/tm/rust/utility/make_options.rs +73 -19
- package/project/.sdk/tm/scala/Makefile +3 -1
- package/project/.sdk/tm/scala/core/Context.scala +16 -0
- package/project/.sdk/tm/scala/core/SdkClient.scala +14 -4
- package/project/.sdk/tm/scala/core/SdkError.scala +28 -0
- package/project/.sdk/tm/scala/core/Types.scala +3 -0
- package/project/.sdk/tm/scala/core/Utility.scala +2 -0
- package/project/.sdk/tm/scala/feature/AuditFeature.scala +16 -10
- package/project/.sdk/tm/scala/feature/CostFeature.scala +10 -5
- package/project/.sdk/tm/scala/feature/DebugFeature.scala +24 -21
- package/project/.sdk/tm/scala/feature/LogFeature.scala +9 -4
- package/project/.sdk/tm/scala/feature/ProxyFeature.scala +23 -2
- package/project/.sdk/tm/scala/feature/SecretsFeature.scala +14 -0
- package/project/.sdk/tm/scala/feature/TelemetryFeature.scala +9 -2
- package/project/.sdk/tm/scala/sdktest/SdkTestMain.scala +2 -2
- package/project/.sdk/tm/scala/utility/Make.scala +63 -20
- package/project/.sdk/tm/scala/utility/Misc.scala +358 -5
- package/project/.sdk/tm/scala/utility/Register.scala +1 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Context.swift +29 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Utility.swift +2 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/AuditFeature.swift +10 -9
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/CostFeature.swift +7 -5
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/DebugFeature.swift +19 -15
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/FeatureOptions.swift +16 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/LogFeature.swift +4 -1
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/ProxyFeature.swift +20 -5
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/SecretsFeature.swift +13 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/TelemetryFeature.swift +4 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeError.swift +15 -5
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +58 -19
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Register.swift +1 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/ResultUtil.swift +391 -4
- package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/FeatureTest.swift +2 -2
- package/project/.sdk/tm/ts/src/Context.ts +5 -1
- package/project/.sdk/tm/ts/src/feature/audit/AuditFeature.ts +2 -2
- package/project/.sdk/tm/ts/src/feature/cost/CostFeature.ts +2 -2
- package/project/.sdk/tm/ts/src/feature/debug/DebugFeature.ts +13 -7
- package/project/.sdk/tm/ts/src/feature/log/LogFeature.ts +9 -5
- package/project/.sdk/tm/ts/src/feature/proxy/ProxyFeature.ts +19 -1
- package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +12 -0
- package/project/.sdk/tm/ts/src/feature/telemetry/TelemetryFeature.ts +4 -2
- package/project/.sdk/tm/ts/src/utility/CleanUtility.ts +287 -9
- package/project/.sdk/tm/ts/src/utility/DoneUtility.ts +18 -5
- package/project/.sdk/tm/ts/src/utility/MakeErrorUtility.ts +18 -8
- package/project/.sdk/tm/ts/src/utility/MakeOptionsUtility.ts +38 -16
- package/project/.sdk/tm/ts/src/utility/Utility.ts +4 -2
- package/project/.sdk/tm/ts/test/feature/harness.ts +11 -1
- package/project/.sdk/tm/ts/test/feature.test.ts +9 -2
- package/project/.sdk/tm/zig/core/context.zig +34 -0
- package/project/.sdk/tm/zig/core/error.zig +22 -1
- package/project/.sdk/tm/zig/core/utility.zig +403 -39
- package/project/.sdk/tm/zig/feature/audit.zig +4 -2
- package/project/.sdk/tm/zig/feature/cost.zig +3 -2
- package/project/.sdk/tm/zig/feature/debug.zig +20 -25
- package/project/.sdk/tm/zig/feature/log.zig +3 -1
- package/project/.sdk/tm/zig/feature/proxy.zig +47 -6
- package/project/.sdk/tm/zig/feature/secrets.zig +7 -0
- package/project/.sdk/tm/zig/feature/telemetry.zig +4 -2
- package/project/.sdk/tm/zig/test/feature_test.zig +2 -2
- package/project/sdkgen-package.json +1 -1
- package/src/helpers/naming.ts +1 -1
|
@@ -0,0 +1,769 @@
|
|
|
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, the lua port of TestClean_ts.ts: see that component.
|
|
13
|
+
const TestClean = cmp(function TestClean(props: any) {
|
|
14
|
+
const { model } = props.ctx$
|
|
15
|
+
const { target } = props
|
|
16
|
+
|
|
17
|
+
const auth = {
|
|
18
|
+
suppressed: isAuthSuppressed(model),
|
|
19
|
+
where: resolveAuthIn(model),
|
|
20
|
+
name: 'header' === resolveAuthIn(model)
|
|
21
|
+
? resolveAuthName(model).toLowerCase() : resolveAuthName(model),
|
|
22
|
+
basic: isHttpBasicAuth(model),
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
File({ name: 'clean_test.' + target.ext }, () => Content(render(model, auth)))
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
function luabool(b: boolean): string {
|
|
30
|
+
return b ? 'true' : 'false'
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
function luastr(s: string): string {
|
|
35
|
+
return '"' + String(s).replace(/\\/g, '\\\\').replace(/"/g, '\\"') + '"'
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
function render(model: any, auth: {
|
|
40
|
+
suppressed: boolean, where: string, name: string, basic: boolean
|
|
41
|
+
}): string {
|
|
42
|
+
return `-- ${model.const.Name} SDK clean test
|
|
43
|
+
--
|
|
44
|
+
-- The canary sweep: every credential slot holds a distinctive value, every
|
|
45
|
+
-- diagnostic feature this SDK ships is switched on with a capturing sink, a
|
|
46
|
+
-- real operation runs through every outcome, and every string that leaves
|
|
47
|
+
-- the SDK is searched for the canaries and their encoded forms. It also
|
|
48
|
+
-- proves its own sensitivity: with clean switched off the canary MUST show.
|
|
49
|
+
|
|
50
|
+
local json = require("dkjson")
|
|
51
|
+
local sdk = require("${model.name}_sdk")
|
|
52
|
+
local BaseFeature = require("feature.base_feature")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
-- Generated: the credential's wire placement is fixed when the SDK is built.
|
|
56
|
+
local AUTH = {
|
|
57
|
+
suppressed = ${luabool(auth.suppressed)},
|
|
58
|
+
where = ${luastr(auth.where)},
|
|
59
|
+
name = ${luastr(auth.name)},
|
|
60
|
+
basic = ${luabool(auth.basic)},
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
local CANARY = {
|
|
64
|
+
apikey = "CANARY-APIKEY-k9x2m7q4p1",
|
|
65
|
+
secret = "CANARY-SECRET-w3e8r5t2y6",
|
|
66
|
+
header = "CANARY-HEADER-z1x4c7v0b3",
|
|
67
|
+
value = "CANARY-VALUE-n5m8b2v9c4",
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
local MASK = "[redacted]"
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
local B64_ALPHABET =
|
|
74
|
+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
|
|
75
|
+
|
|
76
|
+
local function base64(text)
|
|
77
|
+
local out = {}
|
|
78
|
+
local size = #text
|
|
79
|
+
local index = 1
|
|
80
|
+
while index <= size do
|
|
81
|
+
local rest = size - index + 1
|
|
82
|
+
local a = string.byte(text, index)
|
|
83
|
+
local b = string.byte(text, index + 1) or 0
|
|
84
|
+
local c = string.byte(text, index + 2) or 0
|
|
85
|
+
local word = (a << 16) | (b << 8) | c
|
|
86
|
+
local chunk = {}
|
|
87
|
+
for shift = 18, 0, -6 do
|
|
88
|
+
local at = (word >> shift) & 0x3f
|
|
89
|
+
chunk[#chunk + 1] = string.sub(B64_ALPHABET, at + 1, at + 1)
|
|
90
|
+
end
|
|
91
|
+
if rest == 1 then
|
|
92
|
+
chunk[3] = "="
|
|
93
|
+
chunk[4] = "="
|
|
94
|
+
elseif rest == 2 then
|
|
95
|
+
chunk[4] = "="
|
|
96
|
+
end
|
|
97
|
+
out[#out + 1] = table.concat(chunk)
|
|
98
|
+
index = index + 3
|
|
99
|
+
end
|
|
100
|
+
return table.concat(out)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
local function percent(text)
|
|
105
|
+
return (string.gsub(text, "[^%w%-_%.~!%*'%(%)]", function(c)
|
|
106
|
+
return string.format("%%%02X", string.byte(c))
|
|
107
|
+
end))
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
-- Every form a canary can travel in.
|
|
112
|
+
local FORMS = {}
|
|
113
|
+
for _, v in ipairs({ CANARY.apikey, CANARY.secret, CANARY.header, CANARY.value }) do
|
|
114
|
+
FORMS[#FORMS + 1] = v
|
|
115
|
+
FORMS[#FORMS + 1] = base64(v)
|
|
116
|
+
FORMS[#FORMS + 1] = percent(v)
|
|
117
|
+
end
|
|
118
|
+
FORMS[#FORMS + 1] = base64(CANARY.apikey .. ":" .. CANARY.secret)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
-- Header tables keep the caller's spelling; the assertion should not care.
|
|
122
|
+
local function header(map, name)
|
|
123
|
+
for k, v in pairs(map or {}) do
|
|
124
|
+
if type(k) == "string" and string.lower(k) == string.lower(name) then
|
|
125
|
+
return v
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
return nil
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
local function leaks(text)
|
|
133
|
+
local found = {}
|
|
134
|
+
for _, f in ipairs(FORMS) do
|
|
135
|
+
if string.find(text, f, 1, true) ~= nil then
|
|
136
|
+
found[#found + 1] = f
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
return found
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
local function tojson(val)
|
|
144
|
+
local ok, text = pcall(json.encode, val, {
|
|
145
|
+
exception = function() return "null" end,
|
|
146
|
+
})
|
|
147
|
+
if ok and type(text) == "string" then
|
|
148
|
+
return text
|
|
149
|
+
end
|
|
150
|
+
return "<json failed: " .. tostring(text) .. ">"
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
-- A generic table dump, the way a REPL or a logger prints a value: it
|
|
155
|
+
-- honours __tostring, as print does, and otherwise walks every field.
|
|
156
|
+
local function dump(val, depth, seen)
|
|
157
|
+
depth = depth or 0
|
|
158
|
+
seen = seen or {}
|
|
159
|
+
if type(val) == "string" then
|
|
160
|
+
return string.format("%q", val)
|
|
161
|
+
end
|
|
162
|
+
if type(val) ~= "table" then
|
|
163
|
+
return tostring(val)
|
|
164
|
+
end
|
|
165
|
+
local mt = getmetatable(val)
|
|
166
|
+
if type(mt) == "table" and mt.__tostring ~= nil then
|
|
167
|
+
return tostring(val)
|
|
168
|
+
end
|
|
169
|
+
if seen[val] or depth > 8 then
|
|
170
|
+
return "{...}"
|
|
171
|
+
end
|
|
172
|
+
seen[val] = true
|
|
173
|
+
local parts = {}
|
|
174
|
+
for k, v in pairs(val) do
|
|
175
|
+
parts[#parts + 1] = tostring(k) .. "=" .. dump(v, depth + 1, seen)
|
|
176
|
+
end
|
|
177
|
+
seen[val] = nil
|
|
178
|
+
return "{" .. table.concat(parts, ", ") .. "}"
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
local function copy(tbl)
|
|
183
|
+
local out = {}
|
|
184
|
+
for k, v in pairs(tbl) do
|
|
185
|
+
out[k] = v
|
|
186
|
+
end
|
|
187
|
+
return out
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
local function append(sinks, more)
|
|
192
|
+
for _, s in ipairs(more) do
|
|
193
|
+
sinks[#sinks + 1] = s
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
-- Every default form a value leaves in: the SDK's JSON encoding, tostring,
|
|
199
|
+
-- a table dump, and an error's own fields.
|
|
200
|
+
local function surfaces(name, val)
|
|
201
|
+
local out = {}
|
|
202
|
+
local function push(kind, fn)
|
|
203
|
+
local ok, text = pcall(fn)
|
|
204
|
+
if ok and text ~= nil then
|
|
205
|
+
out[#out + 1] = { name = name .. ":" .. kind, text = tostring(text) }
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
push("json", function() return tojson(val) end)
|
|
209
|
+
push("string", function() return tostring(val) end)
|
|
210
|
+
push("dump", function() return dump(val) end)
|
|
211
|
+
if type(val) == "table" then
|
|
212
|
+
if type(val.to_json) == "function" then
|
|
213
|
+
push("tojson", function() return val:to_json() end)
|
|
214
|
+
end
|
|
215
|
+
if val.is_sdk_error == true then
|
|
216
|
+
push("msg", function() return val.msg end)
|
|
217
|
+
push("result", function() return dump(val.result) end)
|
|
218
|
+
push("spec", function() return dump(val.spec) end)
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
return out
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
-- Captures the serialised context from inside the pipeline: what a hook
|
|
226
|
+
-- author would hand to a logger.
|
|
227
|
+
local CaptureFeature = {}
|
|
228
|
+
CaptureFeature.__index = CaptureFeature
|
|
229
|
+
setmetatable(CaptureFeature, { __index = BaseFeature })
|
|
230
|
+
|
|
231
|
+
function CaptureFeature.new(sinks)
|
|
232
|
+
local self = setmetatable(BaseFeature.new(), CaptureFeature)
|
|
233
|
+
self.name = "capture"
|
|
234
|
+
self.version = "0.0.1"
|
|
235
|
+
self.active = true
|
|
236
|
+
self.sinks = sinks
|
|
237
|
+
return self
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
function CaptureFeature:init(_ctx, _options) end
|
|
241
|
+
function CaptureFeature:PreRequest(ctx) append(self.sinks, surfaces("ctx@PreRequest", ctx)) end
|
|
242
|
+
function CaptureFeature:PreResponse(ctx) append(self.sinks, surfaces("ctx@PreResponse", ctx)) end
|
|
243
|
+
function CaptureFeature:PreUnexpected(ctx) append(self.sinks, surfaces("ctx@PreUnexpected", ctx)) end
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
-- A feature that raises from inside the pipeline, quoting the request it
|
|
247
|
+
-- saw: an error make_error never handled. The unexpected variant raises
|
|
248
|
+
-- from PreUnexpected instead, which fires inside make_error.
|
|
249
|
+
local ThrowFeature = {}
|
|
250
|
+
ThrowFeature.__index = ThrowFeature
|
|
251
|
+
setmetatable(ThrowFeature, { __index = BaseFeature })
|
|
252
|
+
|
|
253
|
+
function ThrowFeature.new(unexpected)
|
|
254
|
+
local self = setmetatable(BaseFeature.new(), ThrowFeature)
|
|
255
|
+
self.name = "throwhook"
|
|
256
|
+
self.version = "0.0.1"
|
|
257
|
+
self.active = true
|
|
258
|
+
self.unexpected = unexpected == true
|
|
259
|
+
return self
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
function ThrowFeature:init(_ctx, _options) end
|
|
263
|
+
function ThrowFeature:PreResponse(ctx)
|
|
264
|
+
if not self.unexpected then error("hook saw " .. tojson(ctx.spec)) end
|
|
265
|
+
end
|
|
266
|
+
function ThrowFeature:PreUnexpected(ctx)
|
|
267
|
+
if self.unexpected then error("hook saw " .. tojson(ctx.spec)) end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
-- A feature that refuses the operation with the SDK's own error, as rbac
|
|
272
|
+
-- does, whose code quotes a registered value.
|
|
273
|
+
local DenyFeature = {}
|
|
274
|
+
DenyFeature.__index = DenyFeature
|
|
275
|
+
setmetatable(DenyFeature, { __index = BaseFeature })
|
|
276
|
+
|
|
277
|
+
function DenyFeature.new()
|
|
278
|
+
local self = setmetatable(BaseFeature.new(), DenyFeature)
|
|
279
|
+
self.name = "denyhook"
|
|
280
|
+
self.version = "0.0.1"
|
|
281
|
+
self.active = true
|
|
282
|
+
return self
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
function DenyFeature:init(_ctx, _options) end
|
|
286
|
+
function DenyFeature:PrePoint(ctx)
|
|
287
|
+
ctx.out["point"] = ctx:make_error("denied:" .. CANARY.value, "denied")
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
-- A stream that fails while the caller iterates it, quoting a credential.
|
|
292
|
+
local StreamThrowFeature = {}
|
|
293
|
+
StreamThrowFeature.__index = StreamThrowFeature
|
|
294
|
+
setmetatable(StreamThrowFeature, { __index = BaseFeature })
|
|
295
|
+
|
|
296
|
+
function StreamThrowFeature.new()
|
|
297
|
+
local self = setmetatable(BaseFeature.new(), StreamThrowFeature)
|
|
298
|
+
self.name = "streamthrow"
|
|
299
|
+
self.version = "0.0.1"
|
|
300
|
+
self.active = true
|
|
301
|
+
return self
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
function StreamThrowFeature:init(_ctx, _options) end
|
|
305
|
+
function StreamThrowFeature:PreDone(ctx)
|
|
306
|
+
ctx.result.stream = function()
|
|
307
|
+
return function() error("stream saw " .. CANARY.apikey) end
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
-- A stream that succeeds, so the pipeline's terminal step never runs.
|
|
313
|
+
local StreamOkFeature = {}
|
|
314
|
+
StreamOkFeature.__index = StreamOkFeature
|
|
315
|
+
setmetatable(StreamOkFeature, { __index = BaseFeature })
|
|
316
|
+
|
|
317
|
+
function StreamOkFeature.new()
|
|
318
|
+
local self = setmetatable(BaseFeature.new(), StreamOkFeature)
|
|
319
|
+
self.name = "streamok"
|
|
320
|
+
self.version = "0.0.1"
|
|
321
|
+
self.active = true
|
|
322
|
+
return self
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
function StreamOkFeature:init(_ctx, _options) end
|
|
326
|
+
function StreamOkFeature:PreDone(ctx)
|
|
327
|
+
local items = { ctx.result.resdata or {} }
|
|
328
|
+
ctx.result.stream = function()
|
|
329
|
+
local i = 0
|
|
330
|
+
return function()
|
|
331
|
+
i = i + 1
|
|
332
|
+
return items[i]
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
-- Drops the result once the record holds it, so a later step fails.
|
|
339
|
+
local StepFailFeature = {}
|
|
340
|
+
StepFailFeature.__index = StepFailFeature
|
|
341
|
+
setmetatable(StepFailFeature, { __index = BaseFeature })
|
|
342
|
+
|
|
343
|
+
function StepFailFeature.new()
|
|
344
|
+
local self = setmetatable(BaseFeature.new(), StepFailFeature)
|
|
345
|
+
self.name = "stepfail"
|
|
346
|
+
self.version = "0.0.1"
|
|
347
|
+
self.active = true
|
|
348
|
+
return self
|
|
349
|
+
end
|
|
350
|
+
|
|
351
|
+
function StepFailFeature:init(_ctx, _options) end
|
|
352
|
+
function StepFailFeature:PreResult(ctx) ctx.result = nil end
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
local function response(status, data, headers)
|
|
356
|
+
local h = { ["content-type"] = "application/json" }
|
|
357
|
+
for k, v in pairs(headers or {}) do
|
|
358
|
+
h[string.lower(k)] = v
|
|
359
|
+
end
|
|
360
|
+
return {
|
|
361
|
+
status = status,
|
|
362
|
+
statusText = status < 400 and "OK" or "ERR",
|
|
363
|
+
headers = h,
|
|
364
|
+
json = function() return data end,
|
|
365
|
+
body = tojson(data),
|
|
366
|
+
}, nil
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
local SCENARIOS = {
|
|
371
|
+
{ name = "ok", respond = function()
|
|
372
|
+
return response(200, { id = "i1", name = "n1" },
|
|
373
|
+
{ ["x-session-token"] = "RESP-TOKEN-a1b2c3d4e5" })
|
|
374
|
+
end },
|
|
375
|
+
{ name = "notfound", respond = function()
|
|
376
|
+
return response(404, { error = "no such record" })
|
|
377
|
+
end },
|
|
378
|
+
{ name = "server", respond = function()
|
|
379
|
+
return response(500, { error = "boom" })
|
|
380
|
+
end },
|
|
381
|
+
{ name = "transport", respond = function(url)
|
|
382
|
+
return nil, 'socket hang up (URL was: "' .. url .. '")'
|
|
383
|
+
end },
|
|
384
|
+
{ name = "notjson", respond = function()
|
|
385
|
+
return {
|
|
386
|
+
status = 200,
|
|
387
|
+
statusText = "OK",
|
|
388
|
+
headers = {},
|
|
389
|
+
json = function() error("Unexpected token < in JSON") end,
|
|
390
|
+
body = "<html>",
|
|
391
|
+
}, nil
|
|
392
|
+
end },
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
-- True when this SDK was generated with the named feature.
|
|
397
|
+
local function has_feature(name)
|
|
398
|
+
local ok, features = pcall(require, "features")
|
|
399
|
+
return ok and type(features) == "table" and features[name] ~= nil
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
local function make_sdk(scenario, sinks, cleanopts, extra)
|
|
404
|
+
local function capture(name)
|
|
405
|
+
return function(rec) append(sinks, surfaces(name, rec)) end
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
local feature = {}
|
|
409
|
+
if has_feature("log") then
|
|
410
|
+
local logger = {}
|
|
411
|
+
for _, level in ipairs({ "trace", "debug", "info", "warn", "error", "fatal" }) do
|
|
412
|
+
logger[level] = function(_, msg) append(sinks, surfaces("log." .. level, msg)) end
|
|
413
|
+
end
|
|
414
|
+
feature.log = { active = true, logger = logger }
|
|
415
|
+
end
|
|
416
|
+
if has_feature("debug") then
|
|
417
|
+
feature.debug = { active = true, onEntry = capture("debug") }
|
|
418
|
+
end
|
|
419
|
+
if has_feature("audit") then
|
|
420
|
+
feature.audit = { active = true, sink = capture("audit") }
|
|
421
|
+
end
|
|
422
|
+
if has_feature("telemetry") then
|
|
423
|
+
feature.telemetry = { active = true, exporter = capture("telemetry") }
|
|
424
|
+
end
|
|
425
|
+
if has_feature("cost") then
|
|
426
|
+
feature.cost = { active = true, sink = capture("cost") }
|
|
427
|
+
end
|
|
428
|
+
if has_feature("metrics") then
|
|
429
|
+
feature.metrics = { active = true }
|
|
430
|
+
end
|
|
431
|
+
if has_feature("clienttrack") then
|
|
432
|
+
feature.clienttrack = { active = true }
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
local clean = { values = CANARY.value }
|
|
436
|
+
for k, v in pairs(cleanopts or {}) do
|
|
437
|
+
clean[k] = v
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
local extend = { CaptureFeature.new(sinks) }
|
|
441
|
+
for _, f in ipairs(extra or {}) do
|
|
442
|
+
extend[#extend + 1] = f
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
return sdk.new({
|
|
446
|
+
apikey = CANARY.apikey,
|
|
447
|
+
secret = CANARY.secret,
|
|
448
|
+
headers = { ["X-Custom-Token"] = CANARY.header },
|
|
449
|
+
clean = clean,
|
|
450
|
+
feature = feature,
|
|
451
|
+
extend = extend,
|
|
452
|
+
utility = {
|
|
453
|
+
fetcher = function(_ctx, url, fetchdef) return scenario.respond(url, fetchdef) end,
|
|
454
|
+
},
|
|
455
|
+
})
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
|
|
459
|
+
-- The first operation that completes against a plain 200: with no
|
|
460
|
+
-- arguments, else with every path parameter its points declare filled in.
|
|
461
|
+
local function usable_op()
|
|
462
|
+
local plain = sdk.new({
|
|
463
|
+
apikey = CANARY.apikey,
|
|
464
|
+
utility = { fetcher = function() return response(200, { id = "i1" }) end },
|
|
465
|
+
})
|
|
466
|
+
local config = require("config_shared")()
|
|
467
|
+
local entities = type(config.entity) == "table" and config.entity or {}
|
|
468
|
+
|
|
469
|
+
local accessors = {}
|
|
470
|
+
for k, v in pairs(getmetatable(plain)) do
|
|
471
|
+
if type(k) == "string" and string.match(k, "^%u") and type(v) == "function" then
|
|
472
|
+
accessors[#accessors + 1] = k
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
table.sort(accessors)
|
|
476
|
+
|
|
477
|
+
local rank = { list = 0, load = 1 }
|
|
478
|
+
for _, accessor in ipairs(accessors) do
|
|
479
|
+
local ok, inst = pcall(plain[accessor], plain)
|
|
480
|
+
if ok and type(inst) == "table" and type(inst.get_name) == "function"
|
|
481
|
+
and type(entities[inst:get_name()]) == "table"
|
|
482
|
+
then
|
|
483
|
+
local ops = {}
|
|
484
|
+
for op in pairs(entities[inst:get_name()].op or {}) do
|
|
485
|
+
ops[#ops + 1] = op
|
|
486
|
+
end
|
|
487
|
+
table.sort(ops, function(a, b)
|
|
488
|
+
return (rank[a] or 2) < (rank[b] or 2) or ((rank[a] or 2) == (rank[b] or 2) and a < b)
|
|
489
|
+
end)
|
|
490
|
+
for _, op in ipairs(ops) do
|
|
491
|
+
if type(inst[op]) == "function" then
|
|
492
|
+
local filled = {}
|
|
493
|
+
local opdef = entities[inst:get_name()].op[op]
|
|
494
|
+
local points = type(opdef) == "table" and opdef.points or nil
|
|
495
|
+
for _, point in ipairs(type(points) == "table" and points or {}) do
|
|
496
|
+
local params = type(point) == "table" and type(point.args) == "table"
|
|
497
|
+
and point.args.params or nil
|
|
498
|
+
for _, p in ipairs(type(params) == "table" and params or {}) do
|
|
499
|
+
if type(p) == "table" and type(p.name) == "string" then
|
|
500
|
+
filled[p.name] = "p1"
|
|
501
|
+
end
|
|
502
|
+
end
|
|
503
|
+
end
|
|
504
|
+
for _, match in ipairs({ {}, filled }) do
|
|
505
|
+
local cok, out, err = pcall(inst[op], plain[accessor](plain), copy(match), {})
|
|
506
|
+
if cok and err == nil and out ~= nil then
|
|
507
|
+
return { accessor = accessor, op = op, match = match }
|
|
508
|
+
end
|
|
509
|
+
end
|
|
510
|
+
end
|
|
511
|
+
end
|
|
512
|
+
end
|
|
513
|
+
end
|
|
514
|
+
return nil
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
|
|
518
|
+
local function drive(client, target, ctrl, sinks)
|
|
519
|
+
-- A caller may keep the record it passed rather than read ctrl.explain.
|
|
520
|
+
local held = ctrl.explain
|
|
521
|
+
local ent = client[target.accessor](client)
|
|
522
|
+
local ok, out, err = pcall(ent[target.op], ent, copy(target.match), ctrl)
|
|
523
|
+
if not ok then
|
|
524
|
+
err = out
|
|
525
|
+
out = nil
|
|
526
|
+
end
|
|
527
|
+
if err ~= nil then
|
|
528
|
+
append(sinks, surfaces("error", err))
|
|
529
|
+
end
|
|
530
|
+
if out ~= nil then
|
|
531
|
+
append(sinks, surfaces("result", out))
|
|
532
|
+
end
|
|
533
|
+
if ctrl.explain ~= nil then
|
|
534
|
+
append(sinks, surfaces("explain", ctrl.explain))
|
|
535
|
+
end
|
|
536
|
+
if held ~= nil and held ~= ctrl.explain then
|
|
537
|
+
append(sinks, surfaces("explain:held", held))
|
|
538
|
+
end
|
|
539
|
+
return err
|
|
540
|
+
end
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
describe("clean", function()
|
|
544
|
+
|
|
545
|
+
it("no credential leaves the SDK in any form", function()
|
|
546
|
+
local target = usable_op()
|
|
547
|
+
if target == nil then
|
|
548
|
+
pending("no operation of this SDK completes against a plain 200; nothing to sweep")
|
|
549
|
+
return
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
local sinks = {}
|
|
553
|
+
local errors = {}
|
|
554
|
+
local explains = {}
|
|
555
|
+
|
|
556
|
+
for _, scenario in ipairs(SCENARIOS) do
|
|
557
|
+
for _, variant in ipairs({
|
|
558
|
+
{ name = "throw", ctrl = function() return {} end },
|
|
559
|
+
{ name = "explain", ctrl = function() return { explain = {} } end },
|
|
560
|
+
{ name = "nothrow", ctrl = function() return { throw = false, explain = {} } end },
|
|
561
|
+
}) do
|
|
562
|
+
local client = make_sdk(scenario, sinks)
|
|
563
|
+
local ctrl = variant.ctrl()
|
|
564
|
+
local err = drive(client, target, ctrl, sinks)
|
|
565
|
+
local key = scenario.name .. "/" .. variant.name
|
|
566
|
+
if err ~= nil then
|
|
567
|
+
errors[key] = err
|
|
568
|
+
end
|
|
569
|
+
if ctrl.explain ~= nil then
|
|
570
|
+
explains[key] = ctrl.explain
|
|
571
|
+
end
|
|
572
|
+
append(sinks, surfaces("sdk", client))
|
|
573
|
+
end
|
|
574
|
+
end
|
|
575
|
+
|
|
576
|
+
-- A credential mistyped as a table is rejected by validation, whose
|
|
577
|
+
-- message quotes the value it rejected.
|
|
578
|
+
local built, rejected = pcall(sdk.new, {
|
|
579
|
+
apikey = { value = CANARY.apikey },
|
|
580
|
+
clean = { values = CANARY.value },
|
|
581
|
+
})
|
|
582
|
+
assert.is_false(built, "a credential mistyped as a table should be rejected")
|
|
583
|
+
append(sinks, surfaces("rejected", rejected))
|
|
584
|
+
|
|
585
|
+
-- An error a feature hook raises, quoting the request, skips make_error.
|
|
586
|
+
-- PreUnexpected fires only inside make_error, so its variant needs a
|
|
587
|
+
-- failing response to reach it.
|
|
588
|
+
local hooked = make_sdk(SCENARIOS[1], sinks, nil, { ThrowFeature.new() })
|
|
589
|
+
local unexpected = make_sdk(SCENARIOS[2], sinks, nil, { ThrowFeature.new(true) })
|
|
590
|
+
for _, client in ipairs({ hooked, unexpected }) do
|
|
591
|
+
local hookerr = drive(client, target, { explain = {} }, sinks)
|
|
592
|
+
assert.is_truthy(string.find(tostring(hookerr), "hook saw", 1, true),
|
|
593
|
+
"the throwing hook should fail the operation")
|
|
594
|
+
end
|
|
595
|
+
|
|
596
|
+
-- A step's own error reaches make_error without passing through done().
|
|
597
|
+
local stepped = drive(make_sdk(SCENARIOS[1], sinks, nil, { StepFailFeature.new() }),
|
|
598
|
+
target, { explain = {} }, sinks)
|
|
599
|
+
assert.is_not_nil(stepped, "the failing step should fail the operation")
|
|
600
|
+
|
|
601
|
+
-- A feature's own error keeps its code, which is cleaned like the message.
|
|
602
|
+
local denied = drive(make_sdk(SCENARIOS[1], sinks, nil, { DenyFeature.new() }), target, {}, sinks)
|
|
603
|
+
assert.is_not_nil(denied, "the refusing hook should fail the operation")
|
|
604
|
+
|
|
605
|
+
-- Iterating a stream runs inside the same catch path as the operation,
|
|
606
|
+
-- and the explain record the caller passed is cleaned however it ends.
|
|
607
|
+
-- A step's error ends a stream without raising. The caller stops at the
|
|
608
|
+
-- first item, leaving the stream open.
|
|
609
|
+
for _, case in ipairs({
|
|
610
|
+
{ name = "stream", extra = { StreamThrowFeature.new() }, raises = true },
|
|
611
|
+
{ name = "stream-ok", extra = { StreamOkFeature.new() } },
|
|
612
|
+
{ name = "stream-plain", extra = {} },
|
|
613
|
+
{ name = "stream-step", extra = { StepFailFeature.new() } },
|
|
614
|
+
}) do
|
|
615
|
+
local streamed = make_sdk(SCENARIOS[1], sinks, nil, case.extra)
|
|
616
|
+
local sent = streamed[target.accessor](streamed)
|
|
617
|
+
local explain = {}
|
|
618
|
+
local sok, streamerr = pcall(function()
|
|
619
|
+
for _ in sent:stream(target.op, { reqmatch = copy(target.match) },
|
|
620
|
+
{ ctrl = { explain = explain } }) do break end
|
|
621
|
+
end)
|
|
622
|
+
assert.are.equal(case.raises == true, not sok, case.name .. ": only the failing stream throws")
|
|
623
|
+
if not sok then
|
|
624
|
+
append(sinks, surfaces(case.name, streamerr))
|
|
625
|
+
end
|
|
626
|
+
assert.is_not_nil(next(explain), case.name .. ": the explain record was not filled")
|
|
627
|
+
append(sinks, surfaces(case.name .. ":explain", explain))
|
|
628
|
+
end
|
|
629
|
+
|
|
630
|
+
-- A client given no clean block at all masks by the schema defaults.
|
|
631
|
+
local bare = sdk.new({
|
|
632
|
+
apikey = CANARY.apikey,
|
|
633
|
+
secret = CANARY.secret,
|
|
634
|
+
headers = { ["X-Custom-Token"] = CANARY.header },
|
|
635
|
+
utility = {
|
|
636
|
+
fetcher = function(_ctx, url, fetchdef) return SCENARIOS[2].respond(url, fetchdef) end,
|
|
637
|
+
},
|
|
638
|
+
})
|
|
639
|
+
local barerr = drive(bare, target, {}, sinks)
|
|
640
|
+
assert.is_not_nil(barerr, "the 404 scenario must fail without a clean block")
|
|
641
|
+
|
|
642
|
+
-- The raw path returns its failure rather than raising it.
|
|
643
|
+
local direct = make_sdk(SCENARIOS[4], sinks):direct({ path = "raw" })
|
|
644
|
+
assert.is_false(direct.ok, "a transport failure should fail direct()")
|
|
645
|
+
append(sinks, surfaces("direct", direct.err))
|
|
646
|
+
|
|
647
|
+
-- A registered value used as a property name is masked; names that
|
|
648
|
+
-- mask alike are all kept.
|
|
649
|
+
local named = hooked:get_utility().clean(hooked:get_root_ctx(),
|
|
650
|
+
{ [CANARY.header] = 1, [CANARY.value] = 2, plain = 3 })
|
|
651
|
+
assert.are.same({ [MASK] = 1, [MASK .. "#1"] = 2, plain = 3 }, named)
|
|
652
|
+
append(sinks, surfaces("named", named))
|
|
653
|
+
|
|
654
|
+
local leaked = {}
|
|
655
|
+
for _, s in ipairs(sinks) do
|
|
656
|
+
local found = leaks(s.text)
|
|
657
|
+
if 0 < #found then
|
|
658
|
+
leaked[#leaked + 1] = s.name .. " [" .. table.concat(found, ", ") .. "]"
|
|
659
|
+
end
|
|
660
|
+
end
|
|
661
|
+
|
|
662
|
+
print("clean: swept " .. #sinks .. " surface(s), " .. #leaked .. " leak(s)")
|
|
663
|
+
|
|
664
|
+
assert.are.equal(0, #leaked, "credential leaked through: " .. table.concat(leaked, "; "))
|
|
665
|
+
|
|
666
|
+
-- The positive half: the slot the credential travelled in is masked,
|
|
667
|
+
-- and an unregistered token in a response header is masked by name.
|
|
668
|
+
local notfound = errors["notfound/throw"]
|
|
669
|
+
assert.is_not_nil(notfound, "the 404 scenario must fail")
|
|
670
|
+
assert.are.equal(404, notfound.status)
|
|
671
|
+
local spec = notfound.spec or {}
|
|
672
|
+
if not AUTH.suppressed then
|
|
673
|
+
if AUTH.where == "query" then
|
|
674
|
+
assert.are.equal(MASK, header(spec.query, AUTH.name))
|
|
675
|
+
elseif AUTH.where == "cookie" then
|
|
676
|
+
local cookie = tostring(header(spec.headers, "cookie"))
|
|
677
|
+
assert.is_truthy(string.find(cookie, MASK, 1, true), "cookie: " .. cookie)
|
|
678
|
+
else
|
|
679
|
+
local cred = tostring(header(spec.headers, AUTH.name))
|
|
680
|
+
assert.is_truthy(string.sub(cred, -#MASK) == MASK, AUTH.name .. ": " .. cred)
|
|
681
|
+
end
|
|
682
|
+
end
|
|
683
|
+
assert.are.equal(MASK, header(spec.headers, "x-custom-token"))
|
|
684
|
+
assert.are.equal("denied:" .. MASK, denied.code)
|
|
685
|
+
assert.are.equal(MASK, header((barerr.spec or {}).headers, "x-custom-token"))
|
|
686
|
+
|
|
687
|
+
local explained = explains["ok/explain"] or {}
|
|
688
|
+
assert.is_not_nil(explained.result, "the explain record should carry the result")
|
|
689
|
+
assert.are.equal(MASK, header(explained.result.headers, "x-session-token"))
|
|
690
|
+
end)
|
|
691
|
+
|
|
692
|
+
|
|
693
|
+
it("the sweep can see a leak: clean switched off shows the credential", function()
|
|
694
|
+
local target = usable_op()
|
|
695
|
+
if target == nil then
|
|
696
|
+
pending("no operation of this SDK completes against a plain 200; nothing to sweep")
|
|
697
|
+
return
|
|
698
|
+
end
|
|
699
|
+
|
|
700
|
+
local sinks = {}
|
|
701
|
+
local client = make_sdk(SCENARIOS[2], sinks, { active = false })
|
|
702
|
+
local err = drive(client, target, {}, sinks)
|
|
703
|
+
assert.is_not_nil(err)
|
|
704
|
+
|
|
705
|
+
-- Explaining a failure must not cost it its error.
|
|
706
|
+
local explained = drive(make_sdk(SCENARIOS[2], {}, { active = false }), target, { explain = {} }, {})
|
|
707
|
+
assert.are.equal(err.msg, explained and explained.msg, "with clean off, explain lost the error")
|
|
708
|
+
|
|
709
|
+
local seen = 0
|
|
710
|
+
for _, s in ipairs(sinks) do
|
|
711
|
+
if 0 < #leaks(s.text) then
|
|
712
|
+
seen = seen + 1
|
|
713
|
+
end
|
|
714
|
+
end
|
|
715
|
+
assert.is_true(0 < seen, "with clean off, nothing showed the canary: the sweep is blind")
|
|
716
|
+
|
|
717
|
+
if not AUTH.suppressed then
|
|
718
|
+
local text = tojson(err.spec)
|
|
719
|
+
assert.is_true(
|
|
720
|
+
string.find(text, CANARY.apikey, 1, true) ~= nil
|
|
721
|
+
or string.find(text, base64(CANARY.apikey .. ":" .. CANARY.secret), 1, true) ~= nil,
|
|
722
|
+
"the raw spec should carry the credential when clean is off")
|
|
723
|
+
end
|
|
724
|
+
end)
|
|
725
|
+
|
|
726
|
+
|
|
727
|
+
-- A feature's name is not a field name: a feature called secrets does not
|
|
728
|
+
-- make its settings secret, though a sensitive field inside it still is. An
|
|
729
|
+
-- entity block, of per-entity settings or seeded records keyed by entity
|
|
730
|
+
-- name and id, is not read at all.
|
|
731
|
+
it("a feature's name is read as a name", function()
|
|
732
|
+
local client = sdk.new({
|
|
733
|
+
apikey = CANARY.apikey,
|
|
734
|
+
feature = {
|
|
735
|
+
secrets = { active = false, name = "ZZNAME-feat123", token = "ZZTOKEN-feat456" },
|
|
736
|
+
test = { active = false, entity = { zztoken = { ZZTOKEN01 = { note = "PLAINRECORD-t5r3e1w9" } } } },
|
|
737
|
+
},
|
|
738
|
+
entity = { zztoken = { alias = { zzkey = "PLAINALIAS-m2n4b6v8" } } },
|
|
739
|
+
})
|
|
740
|
+
local clean = client:get_utility().clean
|
|
741
|
+
local ctx = client:get_root_ctx()
|
|
742
|
+
assert.are.equal("ZZNAME-feat123 " .. MASK, clean(ctx, "ZZNAME-feat123 ZZTOKEN-feat456"))
|
|
743
|
+
assert.are.equal("record PLAINRECORD-t5r3e1w9", clean(ctx, "record PLAINRECORD-t5r3e1w9"))
|
|
744
|
+
assert.are.equal("alias PLAINALIAS-m2n4b6v8", clean(ctx, "alias PLAINALIAS-m2n4b6v8"))
|
|
745
|
+
end)
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
it("the generated config's own clean block is honoured", function()
|
|
749
|
+
local utility = sdk.new({}):get_utility()
|
|
750
|
+
local config = { options = { clean = { keys = "zzsens", values = "CONFIG-SEEDED-1" } } }
|
|
751
|
+
local opts = utility.make_options({
|
|
752
|
+
utility = utility,
|
|
753
|
+
config = config,
|
|
754
|
+
options = { clean = { values = "CALLER-SEEDED-2" } },
|
|
755
|
+
})
|
|
756
|
+
local ctx = { options = opts }
|
|
757
|
+
assert.are.equal("a " .. MASK .. " b " .. MASK,
|
|
758
|
+
utility.clean(ctx, "a CONFIG-SEEDED-1 b CALLER-SEEDED-2"))
|
|
759
|
+
assert.are.same({ my_zzsens = MASK, other = "y" }, utility.clean(ctx, { my_zzsens = "x", other = "y" }))
|
|
760
|
+
assert.are.same({ keys = "zzsens", values = "CONFIG-SEEDED-1" }, config.options.clean)
|
|
761
|
+
end)
|
|
762
|
+
end)
|
|
763
|
+
`
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
|
|
767
|
+
export {
|
|
768
|
+
TestClean
|
|
769
|
+
}
|