@voxgig/sdkgen 4.32.0 → 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/Response.js +14 -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/js/test/utility/PrimaryUtility.test.js +25 -0
- 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/Response.ts +14 -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/ts/test/utility/PrimaryUtility.test.ts +25 -0
- 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,538 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cmp,
|
|
3
|
+
each,
|
|
4
|
+
File,
|
|
5
|
+
Content,
|
|
6
|
+
isAuthSuppressed,
|
|
7
|
+
isHttpBasicAuth,
|
|
8
|
+
resolveAuthIn,
|
|
9
|
+
resolveAuthName,
|
|
10
|
+
} from '@voxgig/sdkgen'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
import { ocamlString, ocamlVarName } from './utility_ocaml'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
// The canary sweep, the ocaml port of TestClean_ts.ts: see that component.
|
|
17
|
+
const TestClean = cmp(function TestClean(props: any) {
|
|
18
|
+
const { model } = props.ctx$
|
|
19
|
+
const { target, entity } = 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, entity, auth)))
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
const OP_ORDER: Record<string, number> = { list: 0, load: 1 }
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
// The path parameters an operation's points declare, as the runtime config
|
|
37
|
+
// carries them under points[].args.params.
|
|
38
|
+
function pointParams(opdef: any): string[] {
|
|
39
|
+
const names: string[] = []
|
|
40
|
+
for (const point of each(opdef?.points || [])) {
|
|
41
|
+
if (false === point?.a) continue
|
|
42
|
+
for (const arg of each(point?.g?.params || [])) {
|
|
43
|
+
if (false !== arg?.a && 'string' === typeof arg?.n && !names.includes(arg.n)) {
|
|
44
|
+
names.push(arg.n)
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return names
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
// The operations to try, list and load first: a required path parameter is
|
|
53
|
+
// what usually stops a candidate, and the read ops need none. Each runs to
|
|
54
|
+
// the record so the candidates share one type.
|
|
55
|
+
function candidates(entity: any[]): string {
|
|
56
|
+
const rows: { rank: number, text: string }[] = []
|
|
57
|
+
each(entity, (e: any) => {
|
|
58
|
+
const fn = ocamlVarName(e.name)
|
|
59
|
+
for (const op of Object.keys(e.op || {})) {
|
|
60
|
+
const run = 'list' === op
|
|
61
|
+
? `lst (List.map (fun en -> en.e_data_get ()) (ent.e_list m ctrl))`
|
|
62
|
+
: 'load' === op ? `(ent.e_load m ctrl).e_data_get ()`
|
|
63
|
+
: 'create' === op ? `(ent.e_create m ctrl).e_data_get ()`
|
|
64
|
+
: 'update' === op ? `(ent.e_update m ctrl).e_data_get ()`
|
|
65
|
+
: 'remove' === op ? `(ent.e_remove m ctrl).e_data_get ()`
|
|
66
|
+
: null
|
|
67
|
+
if (null == run) continue
|
|
68
|
+
rows.push({
|
|
69
|
+
rank: OP_ORDER[op] ?? 2,
|
|
70
|
+
text: ` { c_name = "${ocamlString(e.name + '.' + op)}";
|
|
71
|
+
c_params = [${pointParams(e.op[op]).map((p) => '"' + ocamlString(p) + '"').join('; ')}];
|
|
72
|
+
c_run = (fun sdk m ctrl -> let ent = Sdk_client.${fn} sdk Noval in ${run});
|
|
73
|
+
c_stream = (fun sdk m callopts ->
|
|
74
|
+
let ent = Sdk_client.${fn} sdk Noval in List.of_seq (ent.e_stream "${op}" m callopts)) };`,
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
rows.sort((a, b) => a.rank - b.rank)
|
|
79
|
+
return rows.map((r) => r.text).join('\n')
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
function render(model: any, entity: any[], auth: {
|
|
84
|
+
suppressed: boolean, where: string, name: string, basic: boolean
|
|
85
|
+
}): string {
|
|
86
|
+
return `(* ${model.const.Name} SDK canary sweep (generated by @voxgig/sdkgen).
|
|
87
|
+
*
|
|
88
|
+
* Every credential slot holds a distinctive value, every diagnostic feature
|
|
89
|
+
* this SDK ships is switched on with a capturing sink, a real operation runs
|
|
90
|
+
* through every outcome, and every string that leaves the SDK is searched
|
|
91
|
+
* for the canaries and their encoded forms. It also proves its own
|
|
92
|
+
* sensitivity: with clean switched off the canary MUST show. *)
|
|
93
|
+
|
|
94
|
+
open Voxgig_struct
|
|
95
|
+
open Sdk_types
|
|
96
|
+
open Sdk_helpers
|
|
97
|
+
open Sdk_runtime
|
|
98
|
+
open Testutil
|
|
99
|
+
|
|
100
|
+
(* Generated: the credential's wire placement is fixed when the SDK is built. *)
|
|
101
|
+
let auth_suppressed = ${auth.suppressed}
|
|
102
|
+
let auth_where = "${ocamlString(auth.where)}"
|
|
103
|
+
let auth_name = "${ocamlString(auth.name)}"
|
|
104
|
+
let auth_basic = ${auth.basic}
|
|
105
|
+
let _ = auth_basic
|
|
106
|
+
|
|
107
|
+
let canary = [
|
|
108
|
+
("apikey", "CANARY-APIKEY-k9x2m7q4p1");
|
|
109
|
+
("secret", "CANARY-SECRET-w3e8r5t2y6");
|
|
110
|
+
("header", "CANARY-HEADER-z1x4c7v0b3");
|
|
111
|
+
("value", "CANARY-VALUE-n5m8b2v9c4") ]
|
|
112
|
+
|
|
113
|
+
let canary_of (k : string) : string = List.assoc k canary
|
|
114
|
+
let mask = "[redacted]"
|
|
115
|
+
|
|
116
|
+
(* Every form a canary can travel in. *)
|
|
117
|
+
let forms_all : string list =
|
|
118
|
+
List.concat (List.map (fun (_, v) -> [v; base64_encode v; escurl_s v]) canary)
|
|
119
|
+
@ [base64_encode (canary_of "apikey" ^ ":" ^ canary_of "secret")]
|
|
120
|
+
|
|
121
|
+
let leaks (text : string) : string list = List.filter (fun f -> substr_contains text f) forms_all
|
|
122
|
+
|
|
123
|
+
let ends_with_s (s : string) (suf : string) : bool =
|
|
124
|
+
let ls = String.length s and lf = String.length suf in
|
|
125
|
+
ls >= lf && String.sub s (ls - lf) lf = suf
|
|
126
|
+
|
|
127
|
+
(* Header maps keep the caller's spelling; the assertion should not care. *)
|
|
128
|
+
let header (m : value) (name : string) : value = header_ci m name
|
|
129
|
+
|
|
130
|
+
type sinks = (string * string) list ref
|
|
131
|
+
|
|
132
|
+
let push (sinks : sinks) (name : string) (kind : string) (f : unit -> string) : unit =
|
|
133
|
+
try sinks := !sinks @ [(name ^ ":" ^ kind, f ())] with _ -> ()
|
|
134
|
+
|
|
135
|
+
(* Every print and serialisation of a value, as a sink each. *)
|
|
136
|
+
let value_forms (sinks : sinks) (name : string) (v : value) : unit =
|
|
137
|
+
push sinks name "json" (fun () -> jsonify v);
|
|
138
|
+
push sinks name "stringify" (fun () -> stringify v);
|
|
139
|
+
push sinks name "js" (fun () -> js_string v)
|
|
140
|
+
|
|
141
|
+
let error_forms (sinks : sinks) (name : string) (e : exn) : unit =
|
|
142
|
+
push sinks name "printexc" (fun () -> Printexc.to_string e);
|
|
143
|
+
match e with
|
|
144
|
+
| Sdk_error_exc er ->
|
|
145
|
+
push sinks name "message" (fun () -> er.err_msg);
|
|
146
|
+
push sinks name "code" (fun () -> er.err_code);
|
|
147
|
+
value_forms sinks (name ^ ".result") er.err_result;
|
|
148
|
+
value_forms sinks (name ^ ".spec") er.err_spec;
|
|
149
|
+
value_forms sinks (name ^ ".value") (err_to_value er)
|
|
150
|
+
| _ -> ()
|
|
151
|
+
|
|
152
|
+
(* Captures the serialised context from inside the pipeline: what a hook
|
|
153
|
+
* author would hand to a logger. *)
|
|
154
|
+
let capture_feature (sinks : sinks) : feature =
|
|
155
|
+
let f = { f_name = "capture"; f_version = "0.0.1"; f_active = true; f_options = Noval;
|
|
156
|
+
f_init = (fun _ _ -> ()); f_hook = (fun _ _ -> ()) } in
|
|
157
|
+
f.f_hook <- (fun name ctx ->
|
|
158
|
+
match name with
|
|
159
|
+
| "PreRequest" | "PreResponse" | "PreUnexpected" -> value_forms sinks ("ctx@" ^ name) (ctx_to_value ctx)
|
|
160
|
+
| _ -> ());
|
|
161
|
+
f
|
|
162
|
+
|
|
163
|
+
let response ?(headers = []) (status : int) (data : value) : value =
|
|
164
|
+
let h = jo [("content-type", Str "application/json")] in
|
|
165
|
+
List.iter (fun (k, v) -> setp h k (Str v)) headers;
|
|
166
|
+
jo [("status", vint_of status); ("statusText", Str (if status < 400 then "OK" else "ERR"));
|
|
167
|
+
("headers", h); ("body", Str (jsonify data)); ("json", json_thunk data)]
|
|
168
|
+
|
|
169
|
+
type scenario = { s_name : string; s_respond : string -> value -> value }
|
|
170
|
+
|
|
171
|
+
(* system.fetch answers a value; "__err__" is the transport-failure form. *)
|
|
172
|
+
let scenarios : scenario list = [
|
|
173
|
+
{ s_name = "ok"; s_respond = (fun _ _ ->
|
|
174
|
+
response ~headers:[("x-session-token", "RESP-TOKEN-a1b2c3d4e5")] 200
|
|
175
|
+
(jo [("id", Str "i1"); ("name", Str "n1")])) };
|
|
176
|
+
{ s_name = "notfound"; s_respond = (fun _ _ -> response 404 (jo [("error", Str "no such record")])) };
|
|
177
|
+
{ s_name = "server"; s_respond = (fun _ _ -> response 500 (jo [("error", Str "boom")])) };
|
|
178
|
+
{ s_name = "transport"; s_respond = (fun url _ ->
|
|
179
|
+
jo [("__err__", Str ("socket hang up (URL was: \\"" ^ url ^ "\\")"))]) };
|
|
180
|
+
{ s_name = "notjson"; s_respond = (fun _ _ ->
|
|
181
|
+
jo [("status", Num 200.); ("statusText", Str "OK"); ("headers", empty_map ());
|
|
182
|
+
("body", Str "<html>");
|
|
183
|
+
("json", Func (fun _ _ _ _ -> failwith "Unexpected token < in JSON"))]) } ]
|
|
184
|
+
|
|
185
|
+
let make_sdk ?(extra = []) (sc : scenario) (sinks : sinks) (cleanopts : (string * value) list) : sdk_client =
|
|
186
|
+
let capture name = vfunc1 (fun record -> value_forms sinks name record; Noval) in
|
|
187
|
+
let feature = empty_map () in
|
|
188
|
+
let on name kvs = if Harness.has_feature name then setp feature name (jo (("active", Bool true) :: kvs)) in
|
|
189
|
+
on "log" [("logger", capture "log")];
|
|
190
|
+
on "debug" [("onEntry", capture "debug")];
|
|
191
|
+
on "audit" [("sink", capture "audit")];
|
|
192
|
+
on "telemetry" [("exporter", capture "telemetry")];
|
|
193
|
+
on "cost" [("sink", capture "cost")];
|
|
194
|
+
on "metrics" [];
|
|
195
|
+
on "clienttrack" [];
|
|
196
|
+
let clean = jo [("values", Str (canary_of "value"))] in
|
|
197
|
+
List.iter (fun (k, v) -> setp clean k v) cleanopts;
|
|
198
|
+
let fetch = Func (fun _ args _ _ ->
|
|
199
|
+
let url = match getelem args (Num 0.) with Str s -> s | _ -> "" in
|
|
200
|
+
sc.s_respond url (getelem args (Num 1.))) in
|
|
201
|
+
let client = Sdk_client.make (jo [
|
|
202
|
+
("apikey", Str (canary_of "apikey")); ("secret", Str (canary_of "secret"));
|
|
203
|
+
("headers", jo [("X-Custom-Token", Str (canary_of "header"))]);
|
|
204
|
+
("clean", clean); ("feature", feature);
|
|
205
|
+
("system", jo [("fetch", fetch)])]) in
|
|
206
|
+
client.cl_features <- client.cl_features @ [capture_feature sinks] @ extra;
|
|
207
|
+
client
|
|
208
|
+
|
|
209
|
+
(* A feature that raises from inside the pipeline, quoting the request it
|
|
210
|
+
* saw: an error make_error never handled. The unexpected variant raises the
|
|
211
|
+
* SDK's own error there, so the catch path fires PreUnexpected, and raises
|
|
212
|
+
* again from that hook. *)
|
|
213
|
+
let throw_feature ?(unexpected = false) () : feature =
|
|
214
|
+
let saw ctx = "hook saw " ^ (match ctx.c_spec with
|
|
215
|
+
| Some sp -> jsonify (spec_to_value sp)
|
|
216
|
+
| None -> "null") in
|
|
217
|
+
{ f_name = "throwhook"; f_version = "0.0.1"; f_active = true; f_options = Noval;
|
|
218
|
+
f_init = (fun _ _ -> ());
|
|
219
|
+
f_hook = (fun name ctx ->
|
|
220
|
+
match name, unexpected with
|
|
221
|
+
| "PreResponse", true ->
|
|
222
|
+
raise (Sdk_error_exc { err_code = "throwhook"; err_msg = saw ctx;
|
|
223
|
+
err_result = Noval; err_spec = Noval })
|
|
224
|
+
| "PreResponse", false | "PreUnexpected", true -> failwith (saw ctx)
|
|
225
|
+
| _ -> ()) }
|
|
226
|
+
|
|
227
|
+
(* Features that fail the operation with the SDK's own error, whose code
|
|
228
|
+
* quotes a registered value: one refuses it as rbac does, and records the
|
|
229
|
+
* error PreUnexpected hands a hook; the other raises. *)
|
|
230
|
+
let deny_feature (sinks : sinks) : feature =
|
|
231
|
+
{ f_name = "denyhook"; f_version = "0.0.1"; f_active = true; f_options = Noval;
|
|
232
|
+
f_init = (fun _ _ -> ());
|
|
233
|
+
f_hook = (fun name ctx ->
|
|
234
|
+
match name with
|
|
235
|
+
| "PrePoint" ->
|
|
236
|
+
Hashtbl.replace ctx.c_out "point"
|
|
237
|
+
(OErr (ctx_make_error ctx ("denied:" ^ canary_of "value") "denied"))
|
|
238
|
+
| "PreUnexpected" ->
|
|
239
|
+
(match ctx.c_ctrl.ctrl_err with
|
|
240
|
+
| Some er -> error_forms sinks "error" (Sdk_error_exc er)
|
|
241
|
+
| None -> ())
|
|
242
|
+
| _ -> ()) }
|
|
243
|
+
|
|
244
|
+
let raise_feature () : feature =
|
|
245
|
+
{ f_name = "raisehook"; f_version = "0.0.1"; f_active = true; f_options = Noval;
|
|
246
|
+
f_init = (fun _ _ -> ());
|
|
247
|
+
f_hook = (fun name _ ->
|
|
248
|
+
if name = "PreResponse" then
|
|
249
|
+
raise (Sdk_error_exc { err_code = "raised:" ^ canary_of "value"; err_msg = "raised";
|
|
250
|
+
err_result = Noval; err_spec = Noval })) }
|
|
251
|
+
|
|
252
|
+
(* A stream whose producer fails while the caller consumes it, quoting a
|
|
253
|
+
* credential. *)
|
|
254
|
+
let stream_throw_feature () : feature =
|
|
255
|
+
{ f_name = "streamthrow"; f_version = "0.0.1"; f_active = true; f_options = Noval;
|
|
256
|
+
f_init = (fun _ _ -> ());
|
|
257
|
+
f_hook = (fun name ctx ->
|
|
258
|
+
match name, ctx.c_result with
|
|
259
|
+
| "PreDone", Some result ->
|
|
260
|
+
result.rt_stream <- Some (fun () -> failwith ("stream saw " ^ canary_of "apikey"))
|
|
261
|
+
| _ -> ()) }
|
|
262
|
+
|
|
263
|
+
(* A stream a feature supplies, which succeeds. *)
|
|
264
|
+
let stream_ok_feature () : feature =
|
|
265
|
+
{ f_name = "streamok"; f_version = "0.0.1"; f_active = true; f_options = Noval;
|
|
266
|
+
f_init = (fun _ _ -> ());
|
|
267
|
+
f_hook = (fun name ctx ->
|
|
268
|
+
match name, ctx.c_result with
|
|
269
|
+
| "PreDone", Some result ->
|
|
270
|
+
let items = match result.rt_resdata with List r -> !r | v when is_nullish v -> [] | v -> [v] in
|
|
271
|
+
result.rt_stream <- Some (fun () -> items)
|
|
272
|
+
| _ -> ()) }
|
|
273
|
+
|
|
274
|
+
let code_of (e : exn option) : string =
|
|
275
|
+
match e with Some (Sdk_error_exc er) -> er.err_code | _ -> "<no SDK error>"
|
|
276
|
+
|
|
277
|
+
let msg_of (e : exn option) : string =
|
|
278
|
+
match e with Some (Sdk_error_exc er) -> er.err_msg | _ -> "<no SDK error>"
|
|
279
|
+
|
|
280
|
+
type candidate = {
|
|
281
|
+
c_name : string;
|
|
282
|
+
c_params : string list;
|
|
283
|
+
c_run : sdk_client -> value -> value -> value;
|
|
284
|
+
c_stream : sdk_client -> value -> value -> value list;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
type target = { t_cand : candidate; t_params : string list }
|
|
288
|
+
|
|
289
|
+
(* A fresh match for each call, since an operation may keep what it is given. *)
|
|
290
|
+
let args (params : string list) : value = jo (List.map (fun p -> (p, Str "p1")) params)
|
|
291
|
+
|
|
292
|
+
let rec first_some (f : 'a -> 'b option) (l : 'a list) : 'b option =
|
|
293
|
+
match l with
|
|
294
|
+
| [] -> None
|
|
295
|
+
| x :: rest -> (match f x with Some _ as r -> r | None -> first_some f rest)
|
|
296
|
+
|
|
297
|
+
(* The operations this SDK generated, read ops first. *)
|
|
298
|
+
let candidates : candidate list = [
|
|
299
|
+
${candidates(entity)}
|
|
300
|
+
]
|
|
301
|
+
|
|
302
|
+
(* The first operation that completes against a plain 200: with no
|
|
303
|
+
* arguments, else with every path parameter its points declare filled in. *)
|
|
304
|
+
let usable_op () : target option =
|
|
305
|
+
let plain = Sdk_client.make (jo [
|
|
306
|
+
("apikey", Str (canary_of "apikey"));
|
|
307
|
+
("system", jo [("fetch", Func (fun _ _ _ _ -> response 200 (jo [("id", Str "i1")])))])]) in
|
|
308
|
+
first_some (fun c ->
|
|
309
|
+
first_some (fun ps ->
|
|
310
|
+
try ignore (c.c_run plain (args ps) (empty_map ())); Some { t_cand = c; t_params = ps }
|
|
311
|
+
with _ -> None) [[]; c.c_params]) candidates
|
|
312
|
+
|
|
313
|
+
let drive (sdk : sdk_client) (t : target) (ctrl : value) (sinks : sinks) : exn option =
|
|
314
|
+
(* A caller may keep the record it passed rather than read ctrl.explain. *)
|
|
315
|
+
let held = getp ctrl "explain" in
|
|
316
|
+
let err =
|
|
317
|
+
try value_forms sinks "result" (t.t_cand.c_run sdk (args t.t_params) ctrl); None
|
|
318
|
+
with e -> error_forms sinks "error" e; Some e in
|
|
319
|
+
(match getp ctrl "explain" with Map _ as ex -> value_forms sinks "explain" ex | _ -> ());
|
|
320
|
+
(match held, getp ctrl "explain" with
|
|
321
|
+
| Map h, Map now when h == now -> ()
|
|
322
|
+
| Map _, _ -> value_forms sinks "explain:held" held
|
|
323
|
+
| _ -> ());
|
|
324
|
+
err
|
|
325
|
+
|
|
326
|
+
let variants : (string * (unit -> value)) list = [
|
|
327
|
+
("throw", (fun () -> empty_map ()));
|
|
328
|
+
("explain", (fun () -> jo [("explain", empty_map ())]));
|
|
329
|
+
("nothrow", (fun () -> jo [("throw", Bool false); ("explain", empty_map ())])) ]
|
|
330
|
+
|
|
331
|
+
let no_target = "no operation of this SDK completes against a plain 200; nothing to sweep"
|
|
332
|
+
|
|
333
|
+
(* The harness has no skip, so a sweep with nothing to drive says so. *)
|
|
334
|
+
let () =
|
|
335
|
+
test "clean.no_credential_leaves_the_sdk" (fun () ->
|
|
336
|
+
match usable_op () with
|
|
337
|
+
| None -> Printf.printf "SKIP clean.no_credential_leaves_the_sdk: %s\\n%!" no_target
|
|
338
|
+
| Some target ->
|
|
339
|
+
let sinks : sinks = ref [] in
|
|
340
|
+
let errors = ref [] and explains = ref [] in
|
|
341
|
+
List.iter (fun sc ->
|
|
342
|
+
List.iter (fun (vname, mkctrl) ->
|
|
343
|
+
let sdk = make_sdk sc sinks [] in
|
|
344
|
+
let ctrl = mkctrl () in
|
|
345
|
+
let err = drive sdk target ctrl sinks in
|
|
346
|
+
let key = sc.s_name ^ "/" ^ vname in
|
|
347
|
+
(match err with Some e -> errors := (key, e) :: !errors | None -> ());
|
|
348
|
+
(match getp ctrl "explain" with Map _ as ex -> explains := (key, ex) :: !explains | _ -> ());
|
|
349
|
+
value_forms sinks "sdk" (client_to_value sdk)) variants) scenarios;
|
|
350
|
+
(* A credential mistyped as a map is rejected by validation, whose
|
|
351
|
+
* message quotes the value it rejected. *)
|
|
352
|
+
let rejected =
|
|
353
|
+
try
|
|
354
|
+
ignore (Sdk_client.make (jo [
|
|
355
|
+
("apikey", jo [("value", Str (canary_of "apikey"))]);
|
|
356
|
+
("clean", jo [("values", Str (canary_of "value"))])]));
|
|
357
|
+
None
|
|
358
|
+
with e -> Some e in
|
|
359
|
+
(match rejected with
|
|
360
|
+
| Some e -> error_forms sinks "rejected" e
|
|
361
|
+
| None -> failwith "a credential mistyped as a map should be rejected");
|
|
362
|
+
(* An error a feature hook raises, quoting the request, skips make_error,
|
|
363
|
+
* and the explain record it interrupted leaves cleaned too. *)
|
|
364
|
+
List.iter (fun unexpected ->
|
|
365
|
+
let hooked = make_sdk ~extra:[throw_feature ~unexpected ()] (List.hd scenarios) sinks [] in
|
|
366
|
+
check "the throwing hook should fail the operation"
|
|
367
|
+
(match drive hooked target (jo [("explain", empty_map ())]) sinks with
|
|
368
|
+
| Some (Failure m) -> substr_contains m "hook saw"
|
|
369
|
+
| _ -> false)) [false; true];
|
|
370
|
+
(* A feature's own error keeps its code, which is cleaned like the
|
|
371
|
+
* message: returned, handed to a hook, and raised by a hook. *)
|
|
372
|
+
let denied = drive (make_sdk ~extra:[deny_feature sinks] (List.hd scenarios) sinks [])
|
|
373
|
+
target (empty_map ()) sinks in
|
|
374
|
+
let raised = drive (make_sdk ~extra:[raise_feature ()] (List.hd scenarios) sinks [])
|
|
375
|
+
target (empty_map ()) sinks in
|
|
376
|
+
(* Consuming a stream runs inside the same catch path as the operation,
|
|
377
|
+
* and the explain record the caller passed is cleaned however it ends. *)
|
|
378
|
+
List.iter (fun (name, extra) ->
|
|
379
|
+
let streamed = make_sdk ~extra (List.hd scenarios) sinks [] in
|
|
380
|
+
let explain = empty_map () in
|
|
381
|
+
let streamerr =
|
|
382
|
+
try ignore (target.t_cand.c_stream streamed (args target.t_params)
|
|
383
|
+
(jo [("ctrl", jo [("explain", explain)])])); None
|
|
384
|
+
with e -> error_forms sinks name e; Some e in
|
|
385
|
+
check (name ^ ": only the failing stream throws") ((name = "stream") = (streamerr <> None));
|
|
386
|
+
check (name ^ ": the explain record was not filled") (keysof explain <> []);
|
|
387
|
+
value_forms sinks (name ^ ":explain") explain)
|
|
388
|
+
[("stream", [stream_throw_feature ()]); ("stream-ok", [stream_ok_feature ()]);
|
|
389
|
+
("stream-plain", [])];
|
|
390
|
+
(* A client given no clean block at all masks by the schema defaults. *)
|
|
391
|
+
let bare = Sdk_client.make (jo [
|
|
392
|
+
("apikey", Str (canary_of "apikey")); ("secret", Str (canary_of "secret"));
|
|
393
|
+
("headers", jo [("X-Custom-Token", Str (canary_of "header"))]);
|
|
394
|
+
("system", jo [("fetch", Func (fun _ args _ _ ->
|
|
395
|
+
let url = match getelem args (Num 0.) with Str s -> s | _ -> "" in
|
|
396
|
+
(List.nth scenarios 1).s_respond url (getelem args (Num 1.))))])]) in
|
|
397
|
+
let barerr = drive bare target (empty_map ()) sinks in
|
|
398
|
+
(* The raw path returns its failure rather than raising it. *)
|
|
399
|
+
let direct = Sdk_client.direct (make_sdk (List.nth scenarios 3) sinks []) (jo [("path", Str "raw")]) in
|
|
400
|
+
check "a transport failure should fail direct()" (getp direct "ok" = Bool false);
|
|
401
|
+
value_forms sinks "direct" direct;
|
|
402
|
+
let leaked = List.filter (fun (_, text) -> leaks text <> []) !sinks in
|
|
403
|
+
Printf.printf "clean: swept %d surface(s), %d leak(s)\\n%!" (List.length !sinks) (List.length leaked);
|
|
404
|
+
if leaked <> [] then
|
|
405
|
+
failwith ("credential leaked through: "
|
|
406
|
+
^ String.concat "; " (List.map (fun (n, t) -> n ^ " [" ^ String.concat ", " (leaks t) ^ "]") leaked));
|
|
407
|
+
(* The positive half: the slot the credential travelled in is masked,
|
|
408
|
+
* and an unregistered token in a response header is masked by name. *)
|
|
409
|
+
let notfound = match List.assoc_opt "notfound/throw" !errors with
|
|
410
|
+
| Some (Sdk_error_exc e) -> e
|
|
411
|
+
| _ -> failwith "the 404 scenario must throw an SDK error" in
|
|
412
|
+
check_vnum "status 404" (getp notfound.err_result "status") 404.;
|
|
413
|
+
let spec = notfound.err_spec in
|
|
414
|
+
if not auth_suppressed then begin
|
|
415
|
+
if auth_where = "query" then
|
|
416
|
+
check_vstr "query credential masked" (header (getp spec "query") auth_name) mask
|
|
417
|
+
else if auth_where = "cookie" then
|
|
418
|
+
check "cookie masked" (substr_contains (vstring (header (getp spec "headers") "cookie")) mask)
|
|
419
|
+
else
|
|
420
|
+
check "credential header masked" (ends_with_s (vstring (header (getp spec "headers") auth_name)) mask)
|
|
421
|
+
end;
|
|
422
|
+
check_vstr "custom token masked" (header (getp spec "headers") "x-custom-token") mask;
|
|
423
|
+
check ("the refusal's code is masked: " ^ code_of denied) (code_of denied = "denied:" ^ mask);
|
|
424
|
+
check ("the raised code is masked: " ^ code_of raised) (code_of raised = "raised:" ^ mask);
|
|
425
|
+
(match barerr with
|
|
426
|
+
| Some (Sdk_error_exc e) ->
|
|
427
|
+
check_vstr "no clean block: custom token masked" (header (getp e.err_spec "headers") "x-custom-token") mask
|
|
428
|
+
| _ -> failwith "the 404 scenario must throw without a clean block");
|
|
429
|
+
let explained = match List.assoc_opt "ok/explain" !explains with
|
|
430
|
+
| Some ex -> ex
|
|
431
|
+
| None -> failwith "the ok scenario recorded no explain" in
|
|
432
|
+
let result = getp explained "result" in
|
|
433
|
+
check "the explain record should carry the result" (ismap result);
|
|
434
|
+
check_vstr "response token masked" (header (getp result "headers") "x-session-token") mask)
|
|
435
|
+
|
|
436
|
+
let () =
|
|
437
|
+
test "clean.the_sweep_can_see_a_leak" (fun () ->
|
|
438
|
+
match usable_op () with
|
|
439
|
+
| None -> Printf.printf "SKIP clean.the_sweep_can_see_a_leak: %s\\n%!" no_target
|
|
440
|
+
| Some target ->
|
|
441
|
+
let sinks : sinks = ref [] in
|
|
442
|
+
let sdk = make_sdk (List.nth scenarios 1) sinks [("active", Bool false)] in
|
|
443
|
+
let err = drive sdk target (empty_map ()) sinks in
|
|
444
|
+
check "with clean off, nothing showed the canary: the sweep is blind"
|
|
445
|
+
(List.exists (fun (_, t) -> leaks t <> []) !sinks);
|
|
446
|
+
(* Explaining a failure must not cost it its error. *)
|
|
447
|
+
let quiet : sinks = ref [] in
|
|
448
|
+
let explained = drive (make_sdk (List.nth scenarios 1) quiet [("active", Bool false)])
|
|
449
|
+
target (jo [("explain", empty_map ())]) quiet in
|
|
450
|
+
check ("with clean off, explain lost the error: " ^ msg_of explained)
|
|
451
|
+
(msg_of explained = msg_of err);
|
|
452
|
+
match err with
|
|
453
|
+
| Some (Sdk_error_exc e) ->
|
|
454
|
+
if not auth_suppressed then begin
|
|
455
|
+
let text = jsonify e.err_spec in
|
|
456
|
+
check "the raw spec should carry the credential when clean is off"
|
|
457
|
+
(substr_contains text (canary_of "apikey")
|
|
458
|
+
|| substr_contains text (base64_encode (canary_of "apikey" ^ ":" ^ canary_of "secret")))
|
|
459
|
+
end
|
|
460
|
+
| _ -> failwith "the 404 scenario must throw an SDK error")
|
|
461
|
+
|
|
462
|
+
let clean_ctx () : value * ctx =
|
|
463
|
+
let cfg = make_clean_config (jo [("keys", Str "key,secret,token")]) in
|
|
464
|
+
let base = make_context_impl (default_ctxspec ()) None in
|
|
465
|
+
(cfg, { base with c_options = jo [("__derived__", jo [("clean", cfg)])] })
|
|
466
|
+
|
|
467
|
+
let () =
|
|
468
|
+
test "clean.a_registered_value_used_as_a_property_name" (fun () ->
|
|
469
|
+
let (_, ctx) = clean_ctx () in
|
|
470
|
+
clean_add_util ctx "ZZVAL-abc123";
|
|
471
|
+
clean_add_util ctx "ZZVAL-xyz789";
|
|
472
|
+
let out = clean_util ctx
|
|
473
|
+
(jo [("ZZVAL-abc123", Num 1.); ("ZZVAL-xyz789", Num 2.); ("plain", Num 3.)]) in
|
|
474
|
+
check_vnum "a registered name is masked" (getp out mask) 1.;
|
|
475
|
+
check_vnum "a colliding masked name is numbered" (getp out (mask ^ "#1")) 2.;
|
|
476
|
+
check_vnum "a plain name is kept" (getp out "plain") 3.;
|
|
477
|
+
check "the registered name is gone" (not (List.mem "ZZVAL-abc123" (keysof out))))
|
|
478
|
+
|
|
479
|
+
(* A feature's name is not a field name: a feature called secrets does not
|
|
480
|
+
* make its settings secret, though a sensitive field inside it still is. An
|
|
481
|
+
* entity block, of per-entity settings or seeded records keyed by entity name
|
|
482
|
+
* and id, is not read at all. *)
|
|
483
|
+
let () =
|
|
484
|
+
test "clean.a_feature_name_is_read_as_a_name" (fun () ->
|
|
485
|
+
let seeded = jo [("zztoken", jo [("ZZTOKEN01", jo [("note", Str "PLAINRECORD-t5r3e1w9")])])] in
|
|
486
|
+
let client = Sdk_client.make (jo [
|
|
487
|
+
("apikey", Str (canary_of "apikey"));
|
|
488
|
+
("feature", jo [
|
|
489
|
+
("secrets", jo [("active", Bool false); ("name", Str "ZZNAME-feat123");
|
|
490
|
+
("token", Str "ZZTOKEN-feat456")]);
|
|
491
|
+
("test", jo [("active", Bool false); ("entity", seeded)])]);
|
|
492
|
+
("entity", jo [("zztoken", jo [("alias", jo [("zzkey", Str "PLAINALIAS-m2n4b6v8")])])])]) in
|
|
493
|
+
match client.cl_rootctx with
|
|
494
|
+
| Some ctx ->
|
|
495
|
+
check_vstr "only the sensitive field is masked"
|
|
496
|
+
(clean_util ctx (Str "ZZNAME-feat123 ZZTOKEN-feat456")) ("ZZNAME-feat123 " ^ mask);
|
|
497
|
+
check_vstr "a record seeded under an entity block is not registered"
|
|
498
|
+
(clean_util ctx (Str "record PLAINRECORD-t5r3e1w9")) "record PLAINRECORD-t5r3e1w9";
|
|
499
|
+
check_vstr "an entity's own settings are not registered"
|
|
500
|
+
(clean_util ctx (Str "alias PLAINALIAS-m2n4b6v8")) "alias PLAINALIAS-m2n4b6v8"
|
|
501
|
+
| None -> failwith "the client has no root context")
|
|
502
|
+
|
|
503
|
+
let () =
|
|
504
|
+
test "clean.the_generated_configs_own_clean_block_is_honoured" (fun () ->
|
|
505
|
+
let base = make_context_impl (default_ctxspec ()) None in
|
|
506
|
+
let config = jo [("options", jo [("clean", jo [
|
|
507
|
+
("keys", Str "zzsens"); ("values", Str "CONFIG-SEEDED-1")])])] in
|
|
508
|
+
let opts = make_options_util { base with c_config = config;
|
|
509
|
+
c_options = jo [("clean", jo [("values", Str "CALLER-SEEDED-2")])] } in
|
|
510
|
+
let ctx = { base with c_options = opts } in
|
|
511
|
+
check_vstr "both seeded values are masked"
|
|
512
|
+
(clean_util ctx (Str "a CONFIG-SEEDED-1 b CALLER-SEEDED-2")) ("a " ^ mask ^ " b " ^ mask);
|
|
513
|
+
let out = clean_util ctx (jo [("my_zzsens", Str "x"); ("other", Str "y")]) in
|
|
514
|
+
check_vstr "the config's key name is sensitive" (getp out "my_zzsens") mask;
|
|
515
|
+
check_vstr "an ordinary name is kept" (getp out "other") "y";
|
|
516
|
+
check_vstr "the config's keys are left alone" (getpath_s config "options.clean.keys") "zzsens";
|
|
517
|
+
check_vstr "the config's values are left alone" (getpath_s config "options.clean.values") "CONFIG-SEEDED-1")
|
|
518
|
+
|
|
519
|
+
let () =
|
|
520
|
+
test "clean.add_sensitive_registers_every_scalar_under_a_sensitive_name" (fun () ->
|
|
521
|
+
let (cfg, ctx) = clean_ctx () in
|
|
522
|
+
clean_add_sensitive ctx (jo [
|
|
523
|
+
("apikey", jo [("value", Str "NESTED-SECRET-1")]);
|
|
524
|
+
("headers", jo [("X-Api-Token", ja [Str "LISTED-SECRET-2"])]);
|
|
525
|
+
("secret", Num 123456789.);
|
|
526
|
+
("name", Str "not-a-secret")]);
|
|
527
|
+
let values = str_values (getp cfg "values") in
|
|
528
|
+
check "nested under apikey" (List.mem "NESTED-SECRET-1" values);
|
|
529
|
+
check "listed under a token header" (List.mem "LISTED-SECRET-2" values);
|
|
530
|
+
check "a number, as its text" (List.mem "123456789" values);
|
|
531
|
+
check "an ordinary name" (not (List.mem "not-a-secret" values)))
|
|
532
|
+
`
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
export {
|
|
537
|
+
TestClean
|
|
538
|
+
}
|
|
@@ -8,6 +8,7 @@ import { cmp, each, Folder, entityCollection } from '@voxgig/sdkgen'
|
|
|
8
8
|
|
|
9
9
|
import { TestEntity } from './TestEntity_ocaml'
|
|
10
10
|
import { TestDirect } from './TestDirect_ocaml'
|
|
11
|
+
import { TestClean } from './TestClean_ocaml'
|
|
11
12
|
import { ReadmeExamplesTest } from './ReadmeExamplesTest_ocaml'
|
|
12
13
|
|
|
13
14
|
|
|
@@ -24,6 +25,10 @@ const Test = cmp(function Test(props: any) {
|
|
|
24
25
|
TestDirect({ target, entity })
|
|
25
26
|
})
|
|
26
27
|
|
|
28
|
+
// The canary sweep (test/clean_test.ml), linked by the Makefile's
|
|
29
|
+
// CLEAN_TESTS.
|
|
30
|
+
TestClean({ target, entity })
|
|
31
|
+
|
|
27
32
|
// Structural gate over the ```ocaml blocks in the generated docs.
|
|
28
33
|
ReadmeExamplesTest({ target })
|
|
29
34
|
})
|
|
@@ -1,3 +1,18 @@
|
|
|
1
|
+
(* The catch path every entity call leaves through: an error that never
|
|
2
|
+
* passed through make_error leaves cleaned, and so does the explain record
|
|
3
|
+
* it interrupted. An SDK error fires PreUnexpected here, and whatever that
|
|
4
|
+
* hook raises is cleaned in its place. *)
|
|
5
|
+
let unexpected (ctx : ctx) (e : exn) : 'a =
|
|
6
|
+
let e = match e with
|
|
7
|
+
| Sdk_error_exc _ ->
|
|
8
|
+
(try
|
|
9
|
+
(* #PreUnexpected-Hook *)
|
|
10
|
+
e
|
|
11
|
+
with hookerr -> hookerr)
|
|
12
|
+
| _ -> e in
|
|
13
|
+
clean_explain ctx;
|
|
14
|
+
raise (clean_exn ctx e)
|
|
15
|
+
|
|
1
16
|
(* Run the operation pipeline, firing feature hooks between stages via the
|
|
2
17
|
* generated hook-marker lines. post_done runs after the PreDone stage, just
|
|
3
18
|
* before done. Errors from any stage go through make_error (which either
|
|
@@ -26,7 +41,4 @@ let run_op (ctx : ctx) (post_done : unit -> unit) : value =
|
|
|
26
41
|
post_done ();
|
|
27
42
|
utility.u_done ctx
|
|
28
43
|
with Op_return v -> v)
|
|
29
|
-
with
|
|
30
|
-
| Sdk_error_exc _ as e ->
|
|
31
|
-
(* #PreUnexpected-Hook *)
|
|
32
|
-
raise e
|
|
44
|
+
with e -> unexpected ctx e
|
|
@@ -291,6 +291,9 @@ function basicBlock(spec: AuthSpec, wantBasic: boolean): string {
|
|
|
291
291
|
# newline inside a header value is not a header value.
|
|
292
292
|
my $pass = $no_secret ? '' : $secret;
|
|
293
293
|
my $b64 = MIME::Base64::encode_base64("$apikey:$pass", '');
|
|
294
|
+
# The joined, encoded pair is a wire form neither credential's own
|
|
295
|
+
# registration covers.
|
|
296
|
+
$ctx->{utility}{clean_add}->($ctx, $b64);
|
|
294
297
|
$headers->{$CRED_NAME} =
|
|
295
298
|
('' eq $auth_prefix) ? $b64 : "$auth_prefix $b64";
|
|
296
299
|
}
|