@voxgig/sdkgen 4.32.1 → 4.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/voxgig-sdkgen +1 -1
- package/dist/action/copies.d.ts +21 -0
- package/dist/action/copies.js +146 -0
- package/dist/action/copies.js.map +1 -0
- package/dist/action/doctor.d.ts +15 -2
- package/dist/action/doctor.js +169 -23
- package/dist/action/doctor.js.map +1 -1
- package/dist/action/edition.js +6 -2
- package/dist/action/edition.js.map +1 -1
- package/dist/action/feature.js +6 -2
- package/dist/action/feature.js.map +1 -1
- package/dist/action/package.js +28 -10
- package/dist/action/package.js.map +1 -1
- package/dist/action/remove.js +2 -0
- package/dist/action/remove.js.map +1 -1
- package/dist/action/resolve.d.ts +1 -0
- package/dist/action/resolve.js +10 -2
- package/dist/action/resolve.js.map +1 -1
- package/dist/action/target.js +6 -2
- package/dist/action/target.js.map +1 -1
- package/dist/helpers/naming.js +1 -1
- package/dist/helpers/naming.js.map +1 -1
- package/dist/sdkgen.d.ts +2 -1
- package/dist/sdkgen.js +36 -3
- package/dist/sdkgen.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/model/sdkgen.aontu +7 -1
- package/package.json +1 -1
- package/project/.sdk/model/feature/debug.aontu +3 -1
- package/project/.sdk/src/cmp/c/PrepareAuth_c.ts +8 -28
- package/project/.sdk/src/cmp/c/TestClean_c.ts +774 -0
- package/project/.sdk/src/cmp/c/Test_c.ts +3 -0
- package/project/.sdk/src/cmp/c/fragment/Entity.fragment.c +16 -5
- package/project/.sdk/src/cmp/c/fragment/Main.fragment.c +1 -1
- package/project/.sdk/src/cmp/clojure/PrepareAuth_clojure.ts +3 -0
- package/project/.sdk/src/cmp/clojure/TestClean_clojure.ts +473 -0
- package/project/.sdk/src/cmp/clojure/Test_clojure.ts +6 -0
- package/project/.sdk/src/cmp/clojure/fragment/Entity.fragment.clj +18 -8
- package/project/.sdk/src/cmp/cpp/PrepareAuth_cpp.ts +3 -0
- package/project/.sdk/src/cmp/cpp/TestClean_cpp.ts +782 -0
- package/project/.sdk/src/cmp/cpp/TestEntity_cpp.ts +1 -1
- package/project/.sdk/src/cmp/cpp/Test_cpp.ts +2 -0
- package/project/.sdk/src/cmp/csharp/PrepareAuth_csharp.ts +3 -0
- package/project/.sdk/src/cmp/csharp/TestClean_csharp.ts +887 -0
- package/project/.sdk/src/cmp/csharp/Test_csharp.ts +2 -0
- package/project/.sdk/src/cmp/csharp/fragment/EntityBase.fragment.cs +68 -4
- package/project/.sdk/src/cmp/csharp/fragment/Main.fragment.cs +8 -2
- package/project/.sdk/src/cmp/csharp/fragment/SdkError.fragment.cs +49 -0
- package/project/.sdk/src/cmp/elixir/PrepareAuth_elixir.ts +3 -0
- package/project/.sdk/src/cmp/elixir/Schema_elixir.ts +20 -10
- package/project/.sdk/src/cmp/elixir/TestClean_elixir.ts +666 -0
- package/project/.sdk/src/cmp/elixir/Test_elixir.ts +4 -0
- package/project/.sdk/src/cmp/elixir/fragment/Main.fragment.ex +1 -1
- package/project/.sdk/src/cmp/elixir/fragment/Pipeline.fragment.ex +14 -2
- package/project/.sdk/src/cmp/go/PrepareAuth_go.ts +3 -0
- package/project/.sdk/src/cmp/go/TestClean_go.ts +804 -0
- package/project/.sdk/src/cmp/go/Test_go.ts +3 -0
- package/project/.sdk/src/cmp/go/fragment/Entity.fragment.go +54 -4
- package/project/.sdk/src/cmp/go/fragment/Main.fragment.go +27 -2
- package/project/.sdk/src/cmp/java/PrepareAuth_java.ts +3 -0
- package/project/.sdk/src/cmp/java/TestClean_java.ts +884 -0
- package/project/.sdk/src/cmp/java/Test_java.ts +2 -0
- package/project/.sdk/src/cmp/java/fragment/EntityBase.fragment.java +56 -11
- package/project/.sdk/src/cmp/java/fragment/SdkError.fragment.java +36 -3
- package/project/.sdk/src/cmp/js/PrepareAuth_js.ts +3 -0
- package/project/.sdk/src/cmp/js/TestClean_js.ts +458 -0
- package/project/.sdk/src/cmp/js/Test_js.ts +2 -0
- package/project/.sdk/src/cmp/js/fragment/EntityBase.fragment.js +5 -4
- package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/EntityListOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/Main.fragment.js +11 -2
- package/project/.sdk/src/cmp/js/fragment/SdkError.fragment.js +17 -1
- package/project/.sdk/src/cmp/kotlin/Package_kotlin.ts +5 -0
- package/project/.sdk/src/cmp/kotlin/PrepareAuth_kotlin.ts +3 -0
- package/project/.sdk/src/cmp/kotlin/TestClean_kotlin.ts +654 -0
- package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +3 -0
- package/project/.sdk/src/cmp/kotlin/fragment/EntityBase.fragment.kt +44 -11
- package/project/.sdk/src/cmp/kotlin/fragment/SdkError.fragment.kt +31 -0
- package/project/.sdk/src/cmp/lua/PrepareAuth_lua.ts +3 -0
- package/project/.sdk/src/cmp/lua/TestClean_lua.ts +769 -0
- package/project/.sdk/src/cmp/lua/Test_lua.ts +3 -0
- package/project/.sdk/src/cmp/lua/fragment/Entity.fragment.lua +77 -1
- package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +49 -2
- package/project/.sdk/src/cmp/ocaml/Entity_ocaml.ts +3 -2
- package/project/.sdk/src/cmp/ocaml/PrepareAuth_ocaml.ts +4 -25
- package/project/.sdk/src/cmp/ocaml/TestClean_ocaml.ts +538 -0
- package/project/.sdk/src/cmp/ocaml/Test_ocaml.ts +5 -0
- package/project/.sdk/src/cmp/ocaml/fragment/RunOp.fragment.ml +16 -4
- package/project/.sdk/src/cmp/perl/PrepareAuth_perl.ts +3 -0
- package/project/.sdk/src/cmp/perl/TestClean_perl.ts +619 -0
- package/project/.sdk/src/cmp/perl/Test_perl.ts +3 -0
- package/project/.sdk/src/cmp/perl/fragment/Entity.fragment.pm +67 -5
- package/project/.sdk/src/cmp/perl/fragment/Main.fragment.pm +13 -1
- package/project/.sdk/src/cmp/php/PrepareAuth_php.ts +3 -0
- package/project/.sdk/src/cmp/php/TestClean_php.ts +809 -0
- package/project/.sdk/src/cmp/php/Test_php.ts +2 -0
- package/project/.sdk/src/cmp/php/fragment/Entity.fragment.php +96 -55
- package/project/.sdk/src/cmp/php/fragment/Main.fragment.php +15 -2
- package/project/.sdk/src/cmp/py/PrepareAuth_py.ts +3 -0
- package/project/.sdk/src/cmp/py/TestClean_py.ts +549 -0
- package/project/.sdk/src/cmp/py/Test_py.ts +3 -0
- package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +83 -55
- package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +19 -3
- package/project/.sdk/src/cmp/rb/PrepareAuth_rb.ts +3 -0
- package/project/.sdk/src/cmp/rb/TestClean_rb.ts +535 -0
- package/project/.sdk/src/cmp/rb/Test_rb.ts +3 -0
- package/project/.sdk/src/cmp/rb/fragment/Entity.fragment.rb +108 -46
- package/project/.sdk/src/cmp/rb/fragment/Main.fragment.rb +12 -1
- package/project/.sdk/src/cmp/rust/PrepareAuth_rust.ts +9 -45
- package/project/.sdk/src/cmp/rust/TestClean_rust.ts +881 -0
- package/project/.sdk/src/cmp/rust/Test_rust.ts +3 -0
- package/project/.sdk/src/cmp/rust/fragment/Entity.fragment.rs +14 -6
- package/project/.sdk/src/cmp/rust/fragment/Main.fragment.rs +17 -1
- package/project/.sdk/src/cmp/rust/fragment/SdkError.fragment.rs +34 -2
- package/project/.sdk/src/cmp/scala/PrepareAuth_scala.ts +3 -0
- package/project/.sdk/src/cmp/scala/TestClean_scala.ts +608 -0
- package/project/.sdk/src/cmp/scala/Test_scala.ts +3 -0
- package/project/.sdk/src/cmp/scala/fragment/EntityBase.fragment.scala +58 -6
- package/project/.sdk/src/cmp/swift/PrepareAuth_swift.ts +3 -0
- package/project/.sdk/src/cmp/swift/TestClean_swift.ts +671 -0
- package/project/.sdk/src/cmp/swift/Test_swift.ts +3 -0
- package/project/.sdk/src/cmp/swift/fragment/EntityBase.fragment.swift +10 -0
- package/project/.sdk/src/cmp/swift/fragment/Main.fragment.swift +16 -2
- package/project/.sdk/src/cmp/swift/fragment/SdkError.fragment.swift +47 -3
- package/project/.sdk/src/cmp/ts/PrepareAuth_ts.ts +3 -0
- package/project/.sdk/src/cmp/ts/TestClean_ts.ts +465 -0
- package/project/.sdk/src/cmp/ts/Test_ts.ts +2 -0
- package/project/.sdk/src/cmp/ts/fragment/EntityBase.fragment.ts +5 -4
- package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.ts +7 -1
- package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +8 -2
- package/project/.sdk/src/cmp/ts/fragment/SdkError.fragment.ts +20 -2
- package/project/.sdk/src/cmp/zig/PrepareAuth_zig.ts +3 -0
- package/project/.sdk/src/cmp/zig/TestClean_zig.ts +791 -0
- package/project/.sdk/src/cmp/zig/Test_zig.ts +5 -0
- package/project/.sdk/src/cmp/zig/fragment/Build.fragment.zig +19 -0
- package/project/.sdk/src/cmp/zig/fragment/Entity.fragment.zig +14 -5
- package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +1 -1
- package/project/.sdk/tm/c/core/context.c +25 -0
- package/project/.sdk/tm/c/core/error.c +16 -0
- package/project/.sdk/tm/c/core/sdk.h +22 -0
- package/project/.sdk/tm/c/feature/audit.c +2 -0
- package/project/.sdk/tm/c/feature/cost.c +1 -0
- package/project/.sdk/tm/c/feature/debug.c +19 -29
- package/project/.sdk/tm/c/feature/log.c +21 -2
- package/project/.sdk/tm/c/feature/proxy.c +55 -3
- package/project/.sdk/tm/c/feature/secrets.c +7 -0
- package/project/.sdk/tm/c/feature/telemetry.c +2 -0
- package/project/.sdk/tm/c/tests/feature_test.c +2 -2
- package/project/.sdk/tm/c/utility/clean.c +530 -8
- package/project/.sdk/tm/c/utility/done.c +28 -12
- package/project/.sdk/tm/c/utility/make_error.c +4 -3
- package/project/.sdk/tm/c/utility/make_options.c +71 -45
- package/project/.sdk/tm/clojure/feature/secrets/sdk/feature/secrets.clj +15 -0
- package/project/.sdk/tm/clojure/src/sdk/client.clj +20 -4
- package/project/.sdk/tm/clojure/src/sdk/core.clj +319 -35
- package/project/.sdk/tm/clojure/src/sdk/features.clj +68 -30
- package/project/.sdk/tm/clojure/test/sdk/test/feature.clj +4 -2
- package/project/.sdk/tm/clojure/test/sdk/test/pipeline.clj +47 -20
- package/project/.sdk/tm/clojure/test/sdk/test_runner.clj +4 -0
- package/project/.sdk/tm/cpp/core/types.hpp +93 -3
- package/project/.sdk/tm/cpp/feature/audit.hpp +1 -0
- package/project/.sdk/tm/cpp/feature/cost.hpp +1 -0
- package/project/.sdk/tm/cpp/feature/debug.hpp +20 -12
- package/project/.sdk/tm/cpp/feature/log.hpp +31 -9
- package/project/.sdk/tm/cpp/feature/proxy.hpp +52 -6
- package/project/.sdk/tm/cpp/feature/secrets.hpp +13 -0
- package/project/.sdk/tm/cpp/feature/telemetry.hpp +4 -2
- package/project/.sdk/tm/cpp/test/feature_test.cpp +2 -2
- package/project/.sdk/tm/cpp/utility/pipeline.hpp +426 -51
- package/project/.sdk/tm/csharp/core/Context.cs +32 -0
- package/project/.sdk/tm/csharp/core/Utility.cs +2 -0
- package/project/.sdk/tm/csharp/feature/AuditFeature.cs +1 -0
- package/project/.sdk/tm/csharp/feature/CostFeature.cs +7 -5
- package/project/.sdk/tm/csharp/feature/DebugFeature.cs +19 -16
- package/project/.sdk/tm/csharp/feature/FeatureOptions.cs +16 -0
- package/project/.sdk/tm/csharp/feature/LogFeature.cs +4 -1
- package/project/.sdk/tm/csharp/feature/ProxyFeature.cs +26 -5
- package/project/.sdk/tm/csharp/feature/SecretsFeature.cs +16 -0
- package/project/.sdk/tm/csharp/feature/TelemetryFeature.cs +4 -2
- package/project/.sdk/tm/csharp/test/FeatureTest.cs +2 -2
- package/project/.sdk/tm/csharp/utility/Clean.cs +440 -2
- package/project/.sdk/tm/csharp/utility/Done.cs +27 -11
- package/project/.sdk/tm/csharp/utility/MakeError.cs +19 -8
- package/project/.sdk/tm/csharp/utility/MakeOptions.cs +119 -29
- package/project/.sdk/tm/csharp/utility/MakeResponse.cs +21 -11
- package/project/.sdk/tm/csharp/utility/Register.cs +1 -0
- package/project/.sdk/tm/elixir/lib/projectname/context.ex +19 -0
- package/project/.sdk/tm/elixir/lib/projectname/entity_base.ex +22 -1
- package/project/.sdk/tm/elixir/lib/projectname/error.ex +24 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/audit.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/cost.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/debug.ex +13 -13
- package/project/.sdk/tm/elixir/lib/projectname/feature/log.ex +18 -5
- package/project/.sdk/tm/elixir/lib/projectname/feature/proxy.ex +19 -1
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets.ex +15 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/telemetry.ex +4 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature.ex +22 -0
- package/project/.sdk/tm/elixir/lib/projectname/utility.ex +464 -41
- package/project/.sdk/tm/elixir/test/feature_test.exs +3 -2
- package/project/.sdk/tm/go/core/context.go +42 -0
- package/project/.sdk/tm/go/core/error.go +30 -10
- package/project/.sdk/tm/go/core/utility_type.go +2 -0
- package/project/.sdk/tm/go/feature/audit_feature.go +1 -0
- package/project/.sdk/tm/go/feature/base_feature.go +12 -0
- package/project/.sdk/tm/go/feature/cost_feature.go +2 -2
- package/project/.sdk/tm/go/feature/debug_feature.go +14 -12
- package/project/.sdk/tm/go/feature/log_feature.go +13 -8
- package/project/.sdk/tm/go/feature/proxy_feature.go +26 -6
- package/project/.sdk/tm/go/feature/secrets_feature.go +19 -0
- package/project/.sdk/tm/go/feature/telemetry_feature.go +4 -2
- package/project/.sdk/tm/go/test/feature_test.go +2 -2
- package/project/.sdk/tm/go/utility/clean.go +585 -2
- package/project/.sdk/tm/go/utility/done.go +29 -9
- package/project/.sdk/tm/go/utility/make_error.go +51 -16
- package/project/.sdk/tm/go/utility/make_options.go +77 -36
- package/project/.sdk/tm/go/utility/register.go +12 -0
- package/project/.sdk/tm/java/core/Context.java +29 -0
- package/project/.sdk/tm/java/core/SdkClient.java +4 -2
- package/project/.sdk/tm/java/core/Utility.java +7 -0
- package/project/.sdk/tm/java/feature/AuditFeature.java +6 -0
- package/project/.sdk/tm/java/feature/CostFeature.java +5 -0
- package/project/.sdk/tm/java/feature/DebugFeature.java +25 -14
- package/project/.sdk/tm/java/feature/LogFeature.java +11 -4
- package/project/.sdk/tm/java/feature/ProxyFeature.java +41 -6
- package/project/.sdk/tm/java/feature/SecretsFeature.java +18 -0
- package/project/.sdk/tm/java/feature/TelemetryFeature.java +8 -2
- package/project/.sdk/tm/java/test/FeatureTest.java +2 -2
- package/project/.sdk/tm/java/utility/Clean.java +519 -1
- package/project/.sdk/tm/java/utility/Done.java +1 -1
- package/project/.sdk/tm/java/utility/MakeError.java +5 -1
- package/project/.sdk/tm/java/utility/MakeOptions.java +55 -31
- package/project/.sdk/tm/java/utility/Register.java +4 -0
- package/project/.sdk/tm/js/src/Context.js +5 -1
- package/project/.sdk/tm/js/src/feature/audit/AuditFeature.js +2 -2
- package/project/.sdk/tm/js/src/feature/cost/CostFeature.js +2 -2
- package/project/.sdk/tm/js/src/feature/debug/DebugFeature.js +13 -7
- package/project/.sdk/tm/js/src/feature/log/LogFeature.js +9 -5
- package/project/.sdk/tm/js/src/feature/proxy/ProxyFeature.js +19 -1
- package/project/.sdk/tm/js/src/feature/secrets/SecretsFeature.js +14 -0
- package/project/.sdk/tm/js/src/feature/telemetry/TelemetryFeature.js +4 -2
- package/project/.sdk/tm/js/src/utility/CleanUtility.js +294 -21
- package/project/.sdk/tm/js/src/utility/DoneUtility.js +17 -5
- package/project/.sdk/tm/js/src/utility/MakeErrorUtility.js +18 -2
- package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +39 -15
- package/project/.sdk/tm/js/src/utility/Utility.js +4 -2
- package/project/.sdk/tm/js/test/feature/harness.js +11 -1
- package/project/.sdk/tm/js/test/feature.test.js +9 -2
- package/project/.sdk/tm/kotlin/core/Context.kt +19 -0
- package/project/.sdk/tm/kotlin/core/SdkClient.kt +9 -2
- package/project/.sdk/tm/kotlin/core/Utility.kt +2 -0
- package/project/.sdk/tm/kotlin/feature/AuditFeature.kt +11 -9
- package/project/.sdk/tm/kotlin/feature/CostFeature.kt +8 -5
- package/project/.sdk/tm/kotlin/feature/DebugFeature.kt +15 -22
- package/project/.sdk/tm/kotlin/feature/LogFeature.kt +8 -4
- package/project/.sdk/tm/kotlin/feature/ProxyFeature.kt +26 -2
- package/project/.sdk/tm/kotlin/feature/SecretsFeature.kt +11 -0
- package/project/.sdk/tm/kotlin/feature/TelemetryFeature.kt +4 -2
- package/project/.sdk/tm/kotlin/test/FeatureTest.kt +2 -2
- package/project/.sdk/tm/kotlin/utility/CoreUtil.kt +447 -11
- package/project/.sdk/tm/kotlin/utility/MakeOptions.kt +38 -31
- package/project/.sdk/tm/kotlin/utility/Register.kt +1 -0
- package/project/.sdk/tm/lua/core/context.lua +43 -0
- package/project/.sdk/tm/lua/core/error.lua +36 -1
- package/project/.sdk/tm/lua/core/utility_type.lua +4 -0
- package/project/.sdk/tm/lua/feature/audit_feature.lua +2 -2
- package/project/.sdk/tm/lua/feature/cost_feature.lua +2 -2
- package/project/.sdk/tm/lua/feature/debug_feature.lua +21 -17
- package/project/.sdk/tm/lua/feature/log_feature.lua +2 -1
- package/project/.sdk/tm/lua/feature/proxy_feature.lua +23 -1
- package/project/.sdk/tm/lua/feature/secrets_feature.lua +18 -0
- package/project/.sdk/tm/lua/feature/telemetry_feature.lua +4 -2
- package/project/.sdk/tm/lua/test/feature/secrets/secrets_feature_test.lua +3 -2
- package/project/.sdk/tm/lua/test/feature_test.lua +10 -3
- package/project/.sdk/tm/lua/utility/clean.lua +426 -2
- package/project/.sdk/tm/lua/utility/clean_explain.lua +34 -0
- package/project/.sdk/tm/lua/utility/done.lua +1 -7
- package/project/.sdk/tm/lua/utility/make_error.lua +3 -1
- package/project/.sdk/tm/lua/utility/make_options.lua +76 -30
- package/project/.sdk/tm/lua/utility/register.lua +4 -1
- package/project/.sdk/tm/ocaml/Makefile +5 -1
- package/project/.sdk/tm/ocaml/feature/secrets_feature.ml +12 -1
- package/project/.sdk/tm/ocaml/sdk_features.ml +78 -18
- package/project/.sdk/tm/ocaml/sdk_helpers.ml +27 -0
- package/project/.sdk/tm/ocaml/sdk_runtime.ml +304 -26
- package/project/.sdk/tm/ocaml/sdk_types.ml +1 -0
- package/project/.sdk/tm/ocaml/test/feature/secrets/t_secrets.ml +3 -1
- package/project/.sdk/tm/ocaml/test/t_feature.ml +2 -2
- package/project/.sdk/tm/perl/core/context.pm +27 -0
- package/project/.sdk/tm/perl/core/error.pm +52 -5
- package/project/.sdk/tm/perl/feature/audit_feature.pm +2 -2
- package/project/.sdk/tm/perl/feature/cost_feature.pm +2 -2
- package/project/.sdk/tm/perl/feature/debug_feature.pm +17 -13
- package/project/.sdk/tm/perl/feature/log_feature.pm +3 -1
- package/project/.sdk/tm/perl/feature/proxy_feature.pm +21 -1
- package/project/.sdk/tm/perl/feature/secrets_feature.pm +20 -1
- package/project/.sdk/tm/perl/feature/telemetry_feature.pm +4 -2
- package/project/.sdk/tm/perl/t/feature.t +4 -2
- package/project/.sdk/tm/perl/utility/clean.pm +345 -1
- package/project/.sdk/tm/perl/utility/done.pm +24 -6
- package/project/.sdk/tm/perl/utility/make_error.pm +17 -4
- package/project/.sdk/tm/perl/utility/make_options.pm +33 -14
- package/project/.sdk/tm/php/core/Context.php +24 -1
- package/project/.sdk/tm/php/core/Error.php +34 -3
- package/project/.sdk/tm/php/core/UtilityType.php +4 -0
- package/project/.sdk/tm/php/feature/AuditFeature.php +2 -2
- package/project/.sdk/tm/php/feature/CostFeature.php +2 -2
- package/project/.sdk/tm/php/feature/DebugFeature.php +18 -9
- package/project/.sdk/tm/php/feature/LogFeature.php +5 -2
- package/project/.sdk/tm/php/feature/ProxyFeature.php +20 -1
- package/project/.sdk/tm/php/feature/SecretsFeature.php +18 -0
- package/project/.sdk/tm/php/feature/TelemetryFeature.php +4 -2
- package/project/.sdk/tm/php/test/FeatureTest.php +2 -2
- package/project/.sdk/tm/php/utility/Clean.php +438 -2
- package/project/.sdk/tm/php/utility/Done.php +14 -7
- package/project/.sdk/tm/php/utility/MakeError.php +9 -7
- package/project/.sdk/tm/php/utility/MakeOptions.php +62 -38
- package/project/.sdk/tm/php/utility/Register.php +2 -0
- package/project/.sdk/tm/py/pkg/core/context.py +17 -0
- package/project/.sdk/tm/py/pkg/core/error.py +42 -1
- package/project/.sdk/tm/py/pkg/core/utility_type.py +4 -0
- package/project/.sdk/tm/py/pkg/feature/audit_feature.py +2 -2
- package/project/.sdk/tm/py/pkg/feature/cost_feature.py +2 -2
- package/project/.sdk/tm/py/pkg/feature/debug_feature.py +17 -12
- package/project/.sdk/tm/py/pkg/feature/log_feature.py +2 -1
- package/project/.sdk/tm/py/pkg/feature/proxy_feature.py +18 -1
- package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +12 -0
- package/project/.sdk/tm/py/pkg/feature/telemetry_feature.py +4 -2
- package/project/.sdk/tm/py/pkg/utility/clean.py +311 -1
- package/project/.sdk/tm/py/pkg/utility/done.py +18 -5
- package/project/.sdk/tm/py/pkg/utility/make_error.py +9 -6
- package/project/.sdk/tm/py/pkg/utility/make_options.py +64 -25
- package/project/.sdk/tm/py/pkg/utility/make_response.py +19 -13
- package/project/.sdk/tm/py/pkg/utility/register.py +4 -2
- package/project/.sdk/tm/py/test/feature_harness.py +4 -0
- package/project/.sdk/tm/py/test/test_feature.py +2 -2
- package/project/.sdk/tm/py/test/test_primary_utility.py +1 -0
- package/project/.sdk/tm/rb/core/context.rb +28 -0
- package/project/.sdk/tm/rb/core/error.rb +30 -0
- package/project/.sdk/tm/rb/core/utility_type.rb +1 -1
- package/project/.sdk/tm/rb/feature/audit_feature.rb +2 -2
- package/project/.sdk/tm/rb/feature/cost_feature.rb +2 -2
- package/project/.sdk/tm/rb/feature/debug_feature.rb +15 -12
- package/project/.sdk/tm/rb/feature/log_feature.rb +3 -1
- package/project/.sdk/tm/rb/feature/proxy_feature.rb +25 -1
- package/project/.sdk/tm/rb/feature/secrets_feature.rb +17 -0
- package/project/.sdk/tm/rb/feature/telemetry_feature.rb +4 -2
- package/project/.sdk/tm/rb/test/feature_test.rb +4 -2
- package/project/.sdk/tm/rb/utility/clean.rb +312 -1
- package/project/.sdk/tm/rb/utility/done.rb +15 -5
- package/project/.sdk/tm/rb/utility/make_error.rb +13 -4
- package/project/.sdk/tm/rb/utility/make_options.rb +31 -12
- package/project/.sdk/tm/rb/utility/register.rb +2 -0
- package/project/.sdk/tm/rust/core/context.rs +55 -0
- package/project/.sdk/tm/rust/core/utility_type.rs +17 -0
- package/project/.sdk/tm/rust/feature/audit.rs +2 -0
- package/project/.sdk/tm/rust/feature/cost.rs +3 -2
- package/project/.sdk/tm/rust/feature/debug.rs +16 -16
- package/project/.sdk/tm/rust/feature/log.rs +42 -7
- package/project/.sdk/tm/rust/feature/proxy.rs +48 -2
- package/project/.sdk/tm/rust/feature/secrets.rs +12 -0
- package/project/.sdk/tm/rust/feature/telemetry.rs +2 -0
- package/project/.sdk/tm/rust/tests/feature_test.rs +2 -2
- package/project/.sdk/tm/rust/utility/clean.rs +446 -5
- package/project/.sdk/tm/rust/utility/done.rs +22 -12
- package/project/.sdk/tm/rust/utility/make_error.rs +4 -1
- package/project/.sdk/tm/rust/utility/make_options.rs +73 -19
- package/project/.sdk/tm/scala/Makefile +3 -1
- package/project/.sdk/tm/scala/core/Context.scala +16 -0
- package/project/.sdk/tm/scala/core/SdkClient.scala +14 -4
- package/project/.sdk/tm/scala/core/SdkError.scala +28 -0
- package/project/.sdk/tm/scala/core/Types.scala +3 -0
- package/project/.sdk/tm/scala/core/Utility.scala +2 -0
- package/project/.sdk/tm/scala/feature/AuditFeature.scala +16 -10
- package/project/.sdk/tm/scala/feature/CostFeature.scala +10 -5
- package/project/.sdk/tm/scala/feature/DebugFeature.scala +24 -21
- package/project/.sdk/tm/scala/feature/LogFeature.scala +9 -4
- package/project/.sdk/tm/scala/feature/ProxyFeature.scala +23 -2
- package/project/.sdk/tm/scala/feature/SecretsFeature.scala +14 -0
- package/project/.sdk/tm/scala/feature/TelemetryFeature.scala +9 -2
- package/project/.sdk/tm/scala/sdktest/SdkTestMain.scala +2 -2
- package/project/.sdk/tm/scala/utility/Make.scala +63 -20
- package/project/.sdk/tm/scala/utility/Misc.scala +358 -5
- package/project/.sdk/tm/scala/utility/Register.scala +1 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Context.swift +29 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Utility.swift +2 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/AuditFeature.swift +10 -9
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/CostFeature.swift +7 -5
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/DebugFeature.swift +19 -15
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/FeatureOptions.swift +16 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/LogFeature.swift +4 -1
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/ProxyFeature.swift +20 -5
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/SecretsFeature.swift +13 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/TelemetryFeature.swift +4 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeError.swift +15 -5
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +58 -19
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Register.swift +1 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/ResultUtil.swift +391 -4
- package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/FeatureTest.swift +2 -2
- package/project/.sdk/tm/ts/src/Context.ts +5 -1
- package/project/.sdk/tm/ts/src/feature/audit/AuditFeature.ts +2 -2
- package/project/.sdk/tm/ts/src/feature/cost/CostFeature.ts +2 -2
- package/project/.sdk/tm/ts/src/feature/debug/DebugFeature.ts +13 -7
- package/project/.sdk/tm/ts/src/feature/log/LogFeature.ts +9 -5
- package/project/.sdk/tm/ts/src/feature/proxy/ProxyFeature.ts +19 -1
- package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +12 -0
- package/project/.sdk/tm/ts/src/feature/telemetry/TelemetryFeature.ts +4 -2
- package/project/.sdk/tm/ts/src/utility/CleanUtility.ts +287 -9
- package/project/.sdk/tm/ts/src/utility/DoneUtility.ts +18 -5
- package/project/.sdk/tm/ts/src/utility/MakeErrorUtility.ts +18 -8
- package/project/.sdk/tm/ts/src/utility/MakeOptionsUtility.ts +38 -16
- package/project/.sdk/tm/ts/src/utility/Utility.ts +4 -2
- package/project/.sdk/tm/ts/test/feature/harness.ts +11 -1
- package/project/.sdk/tm/ts/test/feature.test.ts +9 -2
- package/project/.sdk/tm/zig/core/context.zig +34 -0
- package/project/.sdk/tm/zig/core/error.zig +22 -1
- package/project/.sdk/tm/zig/core/utility.zig +403 -39
- package/project/.sdk/tm/zig/feature/audit.zig +4 -2
- package/project/.sdk/tm/zig/feature/cost.zig +3 -2
- package/project/.sdk/tm/zig/feature/debug.zig +20 -25
- package/project/.sdk/tm/zig/feature/log.zig +3 -1
- package/project/.sdk/tm/zig/feature/proxy.zig +47 -6
- package/project/.sdk/tm/zig/feature/secrets.zig +7 -0
- package/project/.sdk/tm/zig/feature/telemetry.zig +4 -2
- package/project/.sdk/tm/zig/test/feature_test.zig +2 -2
- package/project/sdkgen-package.json +1 -1
- package/src/action/copies.ts +219 -0
- package/src/action/doctor.ts +247 -21
- package/src/action/edition.ts +10 -2
- package/src/action/feature.ts +11 -2
- package/src/action/package.ts +31 -10
- package/src/action/remove.ts +4 -0
- package/src/action/resolve.ts +16 -3
- package/src/action/target.ts +10 -2
- package/src/helpers/naming.ts +1 -1
- package/src/sdkgen.ts +45 -5
|
@@ -233,3 +233,13 @@ open class ProjectNameEntityBase: Entity {
|
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
|
+
|
|
237
|
+
// An entity prints as its data, as ts and go do: `match` can hold a query
|
|
238
|
+
// credential from the response match, and `dump` walks every stored property.
|
|
239
|
+
extension ProjectNameEntityBase: CustomStringConvertible, CustomDebugStringConvertible, CustomReflectable {
|
|
240
|
+
public var description: Swift.String { name + " " + jsonify(.map(data), indent: 0) }
|
|
241
|
+
public var debugDescription: Swift.String { description }
|
|
242
|
+
public var customMirror: Swift.Mirror {
|
|
243
|
+
Swift.Mirror(self, children: ["name": name, "data": jsonify(.map(data), indent: 0)])
|
|
244
|
+
}
|
|
245
|
+
}
|
|
@@ -177,13 +177,15 @@ public final class ProjectNameSDK {
|
|
|
177
177
|
private func rawRequest(_ fetchargsIn: ProjectNameSdk.VMap?) -> ProjectNameSdk.VMap {
|
|
178
178
|
let utility = self.utility
|
|
179
179
|
|
|
180
|
+
// The error is returned rather than passed through makeError, so it is
|
|
181
|
+
// cleaned here.
|
|
180
182
|
let fetchdef: ProjectNameSdk.VMap
|
|
181
183
|
do {
|
|
182
184
|
fetchdef = try prepare(fetchargsIn)
|
|
183
185
|
} catch {
|
|
184
186
|
let r = ProjectNameSdk.VMap()
|
|
185
187
|
r.entries["ok"] = .bool(false)
|
|
186
|
-
r.entries["err"] = .nat(error)
|
|
188
|
+
r.entries["err"] = utility.clean(rootctx, .nat(error))
|
|
187
189
|
return r
|
|
188
190
|
}
|
|
189
191
|
|
|
@@ -200,7 +202,7 @@ public final class ProjectNameSDK {
|
|
|
200
202
|
} catch {
|
|
201
203
|
let r = ProjectNameSdk.VMap()
|
|
202
204
|
r.entries["ok"] = .bool(false)
|
|
203
|
-
r.entries["err"] = .nat(error)
|
|
205
|
+
r.entries["err"] = utility.clean(ctx, .nat(error))
|
|
204
206
|
return r
|
|
205
207
|
}
|
|
206
208
|
|
|
@@ -311,3 +313,15 @@ public final class ProjectNameSDK {
|
|
|
311
313
|
return sdk
|
|
312
314
|
}
|
|
313
315
|
}
|
|
316
|
+
|
|
317
|
+
// The client holds the credential in its options. Its default prints name
|
|
318
|
+
// it and nothing more, and its mirror - which `dump` and a structured
|
|
319
|
+
// logger walk, private stored properties included - shows only the mode
|
|
320
|
+
// and the feature names.
|
|
321
|
+
extension ProjectNameSDK: CustomStringConvertible, CustomDebugStringConvertible, CustomReflectable {
|
|
322
|
+
public var description: Swift.String { "ProjectNameSDK" }
|
|
323
|
+
public var debugDescription: Swift.String { "ProjectNameSDK(mode: " + mode + ")" }
|
|
324
|
+
public var customMirror: Swift.Mirror {
|
|
325
|
+
Swift.Mirror(self, children: ["mode": mode, "features": features.map { $0.getName() }])
|
|
326
|
+
}
|
|
327
|
+
}
|
|
@@ -3,12 +3,22 @@
|
|
|
3
3
|
|
|
4
4
|
import Foundation
|
|
5
5
|
|
|
6
|
-
public final class ProjectNameError: Error
|
|
6
|
+
public final class ProjectNameError: Error {
|
|
7
7
|
public let isProjectNameError = true
|
|
8
8
|
public let sdk = "ProjectName"
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
|
|
10
|
+
// Clean rewrites the code and the message in place, since the error is
|
|
11
|
+
// about to be thrown.
|
|
12
|
+
public internal(set) var code: String
|
|
13
|
+
public internal(set) var message: String
|
|
14
|
+
|
|
15
|
+
// Reachable for a debugger, out of every printer and mirror: the context
|
|
16
|
+
// holds the live spec and options, and an error is what gets logged.
|
|
11
17
|
public var ctx: Context?
|
|
18
|
+
|
|
19
|
+
// The HTTP status, -1 when there was no response.
|
|
20
|
+
public var status: Int = -1
|
|
21
|
+
|
|
12
22
|
public var resultVal: Value = .noval
|
|
13
23
|
public var specVal: Value = .noval
|
|
14
24
|
|
|
@@ -18,5 +28,39 @@ public final class ProjectNameError: Error, CustomStringConvertible {
|
|
|
18
28
|
self.ctx = ctx
|
|
19
29
|
}
|
|
20
30
|
|
|
31
|
+
public var notFound: Bool { 404 == status }
|
|
32
|
+
|
|
33
|
+
// What makeError attached is already cleaned; the context is not part of
|
|
34
|
+
// the record.
|
|
35
|
+
public func record() -> VMap {
|
|
36
|
+
let out = VMap()
|
|
37
|
+
out.entries["sdk"] = .string(sdk)
|
|
38
|
+
out.entries["code"] = .string(code)
|
|
39
|
+
out.entries["message"] = .string(message)
|
|
40
|
+
out.entries["status"] = .int(Int64(status))
|
|
41
|
+
out.entries["result"] = resultVal
|
|
42
|
+
out.entries["spec"] = specVal
|
|
43
|
+
return out
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// `description` is the message; every other default print - String(reflecting:),
|
|
48
|
+
// debugPrint, dump - is the record, so none of them walks into the context.
|
|
49
|
+
extension ProjectNameError: CustomStringConvertible, CustomDebugStringConvertible, CustomReflectable {
|
|
21
50
|
public var description: String { message }
|
|
51
|
+
|
|
52
|
+
public var debugDescription: String {
|
|
53
|
+
"ProjectNameError [" + code + "] " + message + " (status " + String(status) + ") spec="
|
|
54
|
+
+ jsonify(specVal, indent: 0)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
public var customMirror: Mirror {
|
|
58
|
+
Mirror(self, children: [
|
|
59
|
+
"code": code,
|
|
60
|
+
"message": message,
|
|
61
|
+
"status": status,
|
|
62
|
+
"result": jsonify(resultVal, indent: 0),
|
|
63
|
+
"spec": jsonify(specVal, indent: 0),
|
|
64
|
+
])
|
|
65
|
+
}
|
|
22
66
|
}
|
|
@@ -123,6 +123,9 @@ ${cookieHelper(spec.where)}
|
|
|
123
123
|
}
|
|
124
124
|
else {
|
|
125
125
|
const b64 = Buffer.from(apikey + ':' + pass).toString('base64')
|
|
126
|
+
// The joined, encoded pair is a wire form neither credential's own
|
|
127
|
+
// registration covers.
|
|
128
|
+
utility.cleanAdd(ctx, b64)
|
|
126
129
|
setprop(headers, CRED_name, prefix ? prefix + ' ' + b64 : b64)
|
|
127
130
|
}
|
|
128
131
|
|
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cmp,
|
|
3
|
+
File,
|
|
4
|
+
Content,
|
|
5
|
+
isAuthSuppressed,
|
|
6
|
+
isHttpBasicAuth,
|
|
7
|
+
resolveAuthIn,
|
|
8
|
+
resolveAuthName,
|
|
9
|
+
} from '@voxgig/sdkgen'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
// The canary sweep: every credential slot holds a distinctive value, every
|
|
13
|
+
// diagnostic feature this SDK ships is switched on with a capturing sink, a
|
|
14
|
+
// real operation runs through every outcome, and every string that leaves
|
|
15
|
+
// the SDK is searched for the canaries and their encoded forms. It also
|
|
16
|
+
// proves its own sensitivity: with clean switched off the canary MUST show.
|
|
17
|
+
const TestClean = cmp(function TestClean(props: any) {
|
|
18
|
+
const { model } = props.ctx$
|
|
19
|
+
|
|
20
|
+
const auth = {
|
|
21
|
+
suppressed: isAuthSuppressed(model),
|
|
22
|
+
where: resolveAuthIn(model),
|
|
23
|
+
name: 'header' === resolveAuthIn(model)
|
|
24
|
+
? resolveAuthName(model).toLowerCase() : resolveAuthName(model),
|
|
25
|
+
basic: isHttpBasicAuth(model),
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
File({ name: 'clean.test.ts' }, () => Content(render(auth)))
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
function render(auth: {
|
|
33
|
+
suppressed: boolean, where: string, name: string, basic: boolean
|
|
34
|
+
}): string {
|
|
35
|
+
return `import { test, describe } from 'node:test'
|
|
36
|
+
import { ok, equal, deepStrictEqual } from 'node:assert'
|
|
37
|
+
import { inspect } from 'node:util'
|
|
38
|
+
|
|
39
|
+
import { SDK, BaseFeature } from '..'
|
|
40
|
+
import { hasFeature } from './feature/harness'
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
// Generated: the credential's wire placement is fixed when the SDK is built.
|
|
44
|
+
const AUTH = ${JSON.stringify(auth)}
|
|
45
|
+
|
|
46
|
+
const CANARY = {
|
|
47
|
+
apikey: 'CANARY-APIKEY-k9x2m7q4p1',
|
|
48
|
+
secret: 'CANARY-SECRET-w3e8r5t2y6',
|
|
49
|
+
header: 'CANARY-HEADER-z1x4c7v0b3',
|
|
50
|
+
value: 'CANARY-VALUE-n5m8b2v9c4',
|
|
51
|
+
config: 'CANARY-CONFIG-h6j3k8l2m5',
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const MASK = '[redacted]'
|
|
55
|
+
|
|
56
|
+
// Every form a canary can travel in.
|
|
57
|
+
const FORMS: string[] = []
|
|
58
|
+
for (const v of Object.values(CANARY)) {
|
|
59
|
+
FORMS.push(v, Buffer.from(v).toString('base64'), encodeURIComponent(v))
|
|
60
|
+
}
|
|
61
|
+
FORMS.push(Buffer.from(CANARY.apikey + ':' + CANARY.secret).toString('base64'))
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
type Sink = { name: string, text: string }
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
// Header maps keep the caller's spelling; the assertion should not care.
|
|
68
|
+
function header(map: any, name: string): any {
|
|
69
|
+
for (const k of Object.keys(map || {})) {
|
|
70
|
+
if (k.toLowerCase() === name.toLowerCase()) return map[k]
|
|
71
|
+
}
|
|
72
|
+
return undefined
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
function leaks(text: string): string[] {
|
|
77
|
+
return FORMS.filter((f) => text.includes(f))
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
function forms(name: string, val: any): Sink[] {
|
|
82
|
+
const out: Sink[] = []
|
|
83
|
+
const push = (kind: string, fn: () => string) => {
|
|
84
|
+
try { out.push({ name: name + ':' + kind, text: fn() }) } catch (_e) { }
|
|
85
|
+
}
|
|
86
|
+
push('json', () => JSON.stringify(val))
|
|
87
|
+
push('string', () => String(val))
|
|
88
|
+
push('inspect', () => inspect(val, { depth: 8 }))
|
|
89
|
+
if (val instanceof Error) {
|
|
90
|
+
push('message', () => String(val.message))
|
|
91
|
+
push('stack', () => String(val.stack))
|
|
92
|
+
push('props', () => inspect({ ...val }, { depth: 8 }))
|
|
93
|
+
}
|
|
94
|
+
return out
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
// Captures the serialised context from inside the pipeline: what a hook
|
|
99
|
+
// author would hand to a logger.
|
|
100
|
+
class CaptureFeature extends BaseFeature {
|
|
101
|
+
name = 'capture'
|
|
102
|
+
version = '0.0.1'
|
|
103
|
+
active = true
|
|
104
|
+
_sinks: Sink[]
|
|
105
|
+
constructor(sinks: Sink[]) { super(); this._sinks = sinks }
|
|
106
|
+
init() { }
|
|
107
|
+
PreRequest(this: any, ctx: any) { this._sinks.push(...forms('ctx@PreRequest', ctx)) }
|
|
108
|
+
PreResponse(this: any, ctx: any) { this._sinks.push(...forms('ctx@PreResponse', ctx)) }
|
|
109
|
+
// The SDK's own error as a hook reads it, which an observability feature logs.
|
|
110
|
+
PreUnexpected(this: any, ctx: any) {
|
|
111
|
+
this._sinks.push(...forms('ctx@PreUnexpected', ctx))
|
|
112
|
+
if (ctx.ctrl?.err instanceof Error) this._sinks.push(...forms('ctrl.err@PreUnexpected', ctx.ctrl.err))
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
type Scenario = { name: string, respond: (url: string, fetchdef: any, ctx?: any) => any }
|
|
118
|
+
|
|
119
|
+
function response(status: number, data: any, headers?: Record<string, string>): any {
|
|
120
|
+
const h: Record<string, string> = { 'content-type': 'application/json', ...(headers || {}) }
|
|
121
|
+
return {
|
|
122
|
+
status,
|
|
123
|
+
statusText: status < 400 ? 'OK' : 'ERR',
|
|
124
|
+
json: async () => data,
|
|
125
|
+
text: async () => JSON.stringify(data),
|
|
126
|
+
headers: {
|
|
127
|
+
get(key: string) { return h[String(key).toLowerCase()] },
|
|
128
|
+
forEach(cb: any) { Object.keys(h).forEach((k) => cb(h[k], k, this)) },
|
|
129
|
+
},
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const SCENARIOS: Scenario[] = [
|
|
134
|
+
{ name: 'ok', respond: () => response(200, { id: 'i1', name: 'n1' },
|
|
135
|
+
{ 'x-session-token': 'RESP-TOKEN-a1b2c3d4e5' }) },
|
|
136
|
+
{ name: 'notfound', respond: () => response(404, { error: 'no such record' }) },
|
|
137
|
+
{ name: 'server', respond: () => response(500, { error: 'boom' }) },
|
|
138
|
+
{ name: 'transport', respond: (url: string) => {
|
|
139
|
+
throw new Error('socket hang up (URL was: "' + url + '")')
|
|
140
|
+
} },
|
|
141
|
+
{ name: 'notjson', respond: () => ({
|
|
142
|
+
status: 200, statusText: 'OK',
|
|
143
|
+
json: async () => { throw new Error('Unexpected token < in JSON') },
|
|
144
|
+
text: async () => '<html>',
|
|
145
|
+
headers: { get() { return undefined }, forEach() { } },
|
|
146
|
+
}) },
|
|
147
|
+
// The SDK's own error, its code quoting a registered value.
|
|
148
|
+
{ name: 'coded', respond: (_url: string, _fetchdef: any, ctx: any) => {
|
|
149
|
+
throw ctx.error('denied_' + CANARY.apikey, 'coded failure')
|
|
150
|
+
} },
|
|
151
|
+
]
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
function makeSdk(scenario: Scenario, sinks: Sink[], cleanopts?: any, extra?: any[]): any {
|
|
155
|
+
const capture = (name: string) => (rec: any) => { sinks.push(...forms(name, rec)) }
|
|
156
|
+
const feature: any = {}
|
|
157
|
+
if (hasFeature('log')) {
|
|
158
|
+
const logger: any = {}
|
|
159
|
+
for (const level of ['trace', 'debug', 'info', 'warn', 'error', 'fatal']) {
|
|
160
|
+
logger[level] = capture('log.' + level)
|
|
161
|
+
}
|
|
162
|
+
feature.log = { active: true, logger }
|
|
163
|
+
}
|
|
164
|
+
if (hasFeature('debug')) feature.debug = { active: true, onEntry: capture('debug') }
|
|
165
|
+
if (hasFeature('audit')) feature.audit = { active: true, sink: capture('audit') }
|
|
166
|
+
if (hasFeature('telemetry')) feature.telemetry = { active: true, exporter: capture('telemetry') }
|
|
167
|
+
if (hasFeature('cost')) feature.cost = { active: true, sink: capture('cost') }
|
|
168
|
+
if (hasFeature('metrics')) feature.metrics = { active: true }
|
|
169
|
+
if (hasFeature('clienttrack')) feature.clienttrack = { active: true }
|
|
170
|
+
|
|
171
|
+
const opts: any = {
|
|
172
|
+
apikey: CANARY.apikey,
|
|
173
|
+
secret: CANARY.secret,
|
|
174
|
+
headers: { 'X-Custom-Token': CANARY.header },
|
|
175
|
+
feature,
|
|
176
|
+
extend: [new CaptureFeature(sinks), ...(extra || [])],
|
|
177
|
+
utility: {
|
|
178
|
+
fetcher: async (ctx: any, url: string, fetchdef: any) => scenario.respond(url, fetchdef, ctx),
|
|
179
|
+
},
|
|
180
|
+
}
|
|
181
|
+
// null builds the client with no clean block at all, as most callers do.
|
|
182
|
+
if (null !== cleanopts) opts.clean = { values: CANARY.value, ...(cleanopts || {}) }
|
|
183
|
+
return new (SDK as any)(opts)
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
// The first operation that completes against a plain 200: with no
|
|
188
|
+
// arguments, else with every path parameter its points declare filled in.
|
|
189
|
+
type Target = { accessor: string, op: string, match: any }
|
|
190
|
+
|
|
191
|
+
async function usableOp(): Promise<Target | null> {
|
|
192
|
+
const plain = new (SDK as any)({
|
|
193
|
+
apikey: CANARY.apikey,
|
|
194
|
+
utility: { fetcher: async () => response(200, { id: 'i1' }) },
|
|
195
|
+
})
|
|
196
|
+
const entities: Record<string, any> = plain._rootctx.config.entity || {}
|
|
197
|
+
const rank = (op: string) => (({ list: 0, load: 1 } as any)[op] ?? 2)
|
|
198
|
+
for (const m of Object.getOwnPropertyNames(Object.getPrototypeOf(plain)).sort()) {
|
|
199
|
+
if (!/^[A-Z]/.test(m) || 'function' !== typeof plain[m]) { continue }
|
|
200
|
+
let inst: any
|
|
201
|
+
try { inst = plain[m]() } catch (_e) { continue }
|
|
202
|
+
if (null == inst || 'string' !== typeof inst.name || null == entities[inst.name]) { continue }
|
|
203
|
+
const opdefs = entities[inst.name].op || {}
|
|
204
|
+
for (const op of Object.keys(opdefs).sort((a, b) => rank(a) - rank(b))) {
|
|
205
|
+
const filled: any = {}
|
|
206
|
+
for (const point of opdefs[op].points || []) {
|
|
207
|
+
for (const p of point?.args?.params || []) {
|
|
208
|
+
if ('string' === typeof p?.name) filled[p.name] = 'p1'
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
for (const match of [{}, filled]) {
|
|
212
|
+
try {
|
|
213
|
+
await plain[m]()[op]({ ...match }, {})
|
|
214
|
+
return { accessor: m, op, match }
|
|
215
|
+
}
|
|
216
|
+
catch (_e) { continue }
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return null
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
// A feature that throws from inside the pipeline, quoting the request it
|
|
225
|
+
// saw: an error makeError never handled.
|
|
226
|
+
class ThrowFeature extends BaseFeature {
|
|
227
|
+
name = 'throwhook'
|
|
228
|
+
version = '0.0.1'
|
|
229
|
+
active = true
|
|
230
|
+
_unexpected: boolean
|
|
231
|
+
constructor(unexpected = false) { super(); this._unexpected = unexpected }
|
|
232
|
+
init() { }
|
|
233
|
+
PreResponse(this: any, ctx: any) {
|
|
234
|
+
throw new Error('hook saw ' + JSON.stringify(ctx.spec))
|
|
235
|
+
}
|
|
236
|
+
// Fired from the operation's catch block, before its cleaning.
|
|
237
|
+
PreUnexpected(this: any, ctx: any) {
|
|
238
|
+
if (this._unexpected) throw new Error('hook saw ' + JSON.stringify(ctx.spec))
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
// A stream that fails while the caller iterates it, quoting a credential.
|
|
244
|
+
class StreamThrowFeature extends BaseFeature {
|
|
245
|
+
name = 'streamthrow'
|
|
246
|
+
version = '0.0.1'
|
|
247
|
+
active = true
|
|
248
|
+
init() { }
|
|
249
|
+
PreDone(this: any, ctx: any) {
|
|
250
|
+
ctx.result.stream = async function* () { throw new Error('stream saw ' + CANARY.apikey) }
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
// A stream that succeeds, so the pipeline's terminal step never runs.
|
|
256
|
+
class StreamOkFeature extends BaseFeature {
|
|
257
|
+
name = 'streamok'
|
|
258
|
+
version = '0.0.1'
|
|
259
|
+
active = true
|
|
260
|
+
init() { }
|
|
261
|
+
PreDone(this: any, ctx: any) {
|
|
262
|
+
const items = [].concat(ctx.result.resdata ?? [])
|
|
263
|
+
ctx.result.stream = async function* () { yield* items }
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
async function drive(sdk: any, target: Target, ctrl: any, sinks: Sink[]) {
|
|
269
|
+
// A caller may keep the record it passed rather than read ctrl.explain.
|
|
270
|
+
const held = ctrl.explain
|
|
271
|
+
let out: any = undefined
|
|
272
|
+
let err: any = undefined
|
|
273
|
+
try {
|
|
274
|
+
out = await sdk[target.accessor]()[target.op]({ ...target.match }, ctrl)
|
|
275
|
+
}
|
|
276
|
+
catch (e: any) {
|
|
277
|
+
err = e
|
|
278
|
+
}
|
|
279
|
+
if (undefined !== err) sinks.push(...forms('error', err))
|
|
280
|
+
if (undefined !== out) sinks.push(...forms('result', out))
|
|
281
|
+
if (null != ctrl.explain) sinks.push(...forms('explain', ctrl.explain))
|
|
282
|
+
if (null != held && held !== ctrl.explain) sinks.push(...forms('explain:held', held))
|
|
283
|
+
return err
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
describe('clean', () => {
|
|
288
|
+
test('no credential leaves the SDK in any form', async (t) => {
|
|
289
|
+
const target = await usableOp()
|
|
290
|
+
if (null == target) {
|
|
291
|
+
return t.skip('no operation of this SDK completes against a plain 200; nothing to sweep')
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const sinks: Sink[] = []
|
|
295
|
+
const errors: Record<string, any> = {}
|
|
296
|
+
const explains: Record<string, any> = {}
|
|
297
|
+
|
|
298
|
+
for (const scenario of SCENARIOS) {
|
|
299
|
+
for (const variant of [
|
|
300
|
+
{ name: 'throw', ctrl: () => ({}) },
|
|
301
|
+
{ name: 'explain', ctrl: () => ({ explain: {} }) },
|
|
302
|
+
{ name: 'nothrow', ctrl: () => ({ throw: false, explain: {} }) },
|
|
303
|
+
]) {
|
|
304
|
+
const sdk = makeSdk(scenario, sinks)
|
|
305
|
+
const ctrl: any = variant.ctrl()
|
|
306
|
+
const err = await drive(sdk, target, ctrl, sinks)
|
|
307
|
+
const key = scenario.name + '/' + variant.name
|
|
308
|
+
if (null != err) errors[key] = err
|
|
309
|
+
if (null != ctrl.explain) explains[key] = ctrl.explain
|
|
310
|
+
sinks.push(...forms('sdk', sdk))
|
|
311
|
+
sinks.push({ name: 'sdk:spread', text: inspect({ ...sdk }, { depth: 6 }) })
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// A credential mistyped as an object is rejected by validation, whose
|
|
316
|
+
// message quotes the value it rejected; with and without a clean block.
|
|
317
|
+
for (const cleanblock of [{ clean: { values: CANARY.value } }, {}]) {
|
|
318
|
+
let rejected: any = undefined
|
|
319
|
+
try {
|
|
320
|
+
new (SDK as any)({ apikey: { value: CANARY.apikey }, ...cleanblock })
|
|
321
|
+
}
|
|
322
|
+
catch (e: any) {
|
|
323
|
+
rejected = e
|
|
324
|
+
}
|
|
325
|
+
ok(null != rejected, 'a credential mistyped as an object should be rejected')
|
|
326
|
+
sinks.push(...forms('rejected', rejected))
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// An error a feature hook throws, quoting the request, skips makeError.
|
|
330
|
+
for (const unexpected of [false, true]) {
|
|
331
|
+
const hooked = makeSdk(SCENARIOS[0], sinks, undefined, [new ThrowFeature(unexpected)])
|
|
332
|
+
const hookerr = await drive(hooked, target, { explain: {} }, sinks)
|
|
333
|
+
ok(null != hookerr, 'the throwing hook should fail the operation')
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
// Iterating a stream runs inside the same catch path as the operation,
|
|
337
|
+
// and the explain record the caller passed is cleaned however it ends.
|
|
338
|
+
for (const [name, extra] of [['stream', [new StreamThrowFeature()]],
|
|
339
|
+
['stream-ok', [new StreamOkFeature()]], ['stream-plain', []]] as [string, any[]][]) {
|
|
340
|
+
const streamed = makeSdk(SCENARIOS[0], sinks, undefined, extra)
|
|
341
|
+
const explain = {}
|
|
342
|
+
let streamerr: any = undefined
|
|
343
|
+
try {
|
|
344
|
+
for await (const _item of streamed[target.accessor]().stream(
|
|
345
|
+
target.op, { reqmatch: { ...target.match } }, { ctrl: { explain } })) { }
|
|
346
|
+
}
|
|
347
|
+
catch (e: any) { streamerr = e }
|
|
348
|
+
ok(('stream' === name) === (null != streamerr), name + ': only the failing stream throws')
|
|
349
|
+
if (null != streamerr) sinks.push(...forms(name, streamerr))
|
|
350
|
+
ok(0 < Object.keys(explain).length, name + ': the explain record was not filled')
|
|
351
|
+
sinks.push(...forms(name + ':explain', explain))
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Most callers pass no clean block; the defaults alone must mask.
|
|
355
|
+
for (const scenario of [SCENARIOS[1], SCENARIOS[3]]) {
|
|
356
|
+
const bare = makeSdk(scenario, sinks, null)
|
|
357
|
+
await drive(bare, target, { explain: {} }, sinks)
|
|
358
|
+
sinks.push(...forms('bare', bare))
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// The generated config's own clean block is read beside the caller's,
|
|
362
|
+
// and is not changed by it.
|
|
363
|
+
const util: any = makeSdk(SCENARIOS[0], sinks).utility()
|
|
364
|
+
const cfgclean = { keys: 'zzsens', values: CANARY.config }
|
|
365
|
+
const built = util.makeOptions({ utility: util, config: { options: { clean: cfgclean } },
|
|
366
|
+
options: { clean: { values: CANARY.value } } })
|
|
367
|
+
const seeded = util.clean({ options: built }, 'config ' + CANARY.config + ' caller ' + CANARY.value)
|
|
368
|
+
sinks.push({ name: 'config-clean', text: seeded })
|
|
369
|
+
|
|
370
|
+
// A feature's name is not a field name: only the sensitive names inside
|
|
371
|
+
// its settings register. An entity block, of per-entity settings or seeded
|
|
372
|
+
// records keyed by entity name and id, is not read at all.
|
|
373
|
+
const featured: any = new (SDK as any)({ apikey: CANARY.apikey, feature: {
|
|
374
|
+
zzsecrets: { active: false, kind: 'PLAINSETTING-q8w2e4r6' },
|
|
375
|
+
zzfeat: { active: false, apitoken: 'FEATTOKEN-z9y8x7w6' },
|
|
376
|
+
test: { active: false, entity: { zztoken: { ZZTOKEN01: { note: 'PLAINRECORD-t5r3e1w9' } } } },
|
|
377
|
+
}, entity: { zztoken: { alias: { zzkey: 'PLAINALIAS-m2n4b6v8' } } } })
|
|
378
|
+
const fctx = { options: featured._options }
|
|
379
|
+
|
|
380
|
+
// The raw path returns its failure rather than throwing it.
|
|
381
|
+
const raw = await makeSdk(SCENARIOS[3], sinks).direct({ path: 'raw' })
|
|
382
|
+
ok(false === raw.ok && null != raw.err, 'a transport failure should fail direct()')
|
|
383
|
+
sinks.push(...forms('direct', raw.err))
|
|
384
|
+
|
|
385
|
+
const leaked = sinks
|
|
386
|
+
.map((s) => ({ name: s.name, found: leaks(s.text) }))
|
|
387
|
+
.filter((s) => 0 < s.found.length)
|
|
388
|
+
|
|
389
|
+
console.log('clean: swept ' + sinks.length + ' surface(s), ' + leaked.length + ' leak(s)')
|
|
390
|
+
|
|
391
|
+
equal(leaked.length, 0, 'credential leaked through: ' +
|
|
392
|
+
leaked.map((l) => l.name + ' [' + l.found.join(', ') + ']').join('; '))
|
|
393
|
+
|
|
394
|
+
// The positive half: the slot the credential travelled in is masked,
|
|
395
|
+
// and an unregistered token in a response header is masked by name.
|
|
396
|
+
const notfound = errors['notfound/throw']
|
|
397
|
+
ok(null != notfound, 'the 404 scenario must throw')
|
|
398
|
+
equal(notfound.status, 404)
|
|
399
|
+
if (!AUTH.suppressed) {
|
|
400
|
+
const spec = notfound.spec || {}
|
|
401
|
+
if ('query' === AUTH.where) {
|
|
402
|
+
equal(header(spec.query, AUTH.name), MASK)
|
|
403
|
+
}
|
|
404
|
+
else if ('cookie' === AUTH.where) {
|
|
405
|
+
ok(String(header(spec.headers, 'cookie')).includes(MASK), 'cookie: ' + header(spec.headers, 'cookie'))
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
ok(String(header(spec.headers, AUTH.name)).endsWith(MASK),
|
|
409
|
+
AUTH.name + ': ' + header(spec.headers, AUTH.name))
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
equal(header(notfound.spec.headers, 'x-custom-token'), MASK)
|
|
413
|
+
|
|
414
|
+
equal(seeded, 'config ' + MASK + ' caller ' + MASK)
|
|
415
|
+
deepStrictEqual(util.clean({ options: built }, { my_zzsens: 'x', other: 'y' }), { my_zzsens: MASK, other: 'y' })
|
|
416
|
+
deepStrictEqual(cfgclean, { keys: 'zzsens', values: CANARY.config })
|
|
417
|
+
|
|
418
|
+
equal(featured.utility().clean(fctx, 'kind PLAINSETTING-q8w2e4r6'), 'kind PLAINSETTING-q8w2e4r6')
|
|
419
|
+
equal(featured.utility().clean(fctx, 'token FEATTOKEN-z9y8x7w6'), 'token ' + MASK)
|
|
420
|
+
equal(featured.utility().clean(fctx, 'record PLAINRECORD-t5r3e1w9'), 'record PLAINRECORD-t5r3e1w9')
|
|
421
|
+
equal(featured.utility().clean(fctx, 'alias PLAINALIAS-m2n4b6v8'), 'alias PLAINALIAS-m2n4b6v8')
|
|
422
|
+
|
|
423
|
+
const coded = errors['coded/throw']
|
|
424
|
+
ok(null != coded, 'the coded scenario must throw')
|
|
425
|
+
equal(coded.code, 'denied_' + MASK)
|
|
426
|
+
|
|
427
|
+
const explained = explains['ok/explain'] || {}
|
|
428
|
+
ok(null != explained.result, 'the explain record should carry the result')
|
|
429
|
+
equal(header(explained.result.headers, 'x-session-token'), MASK)
|
|
430
|
+
})
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
test('the sweep can see a leak: clean switched off shows the credential', async (t) => {
|
|
434
|
+
const target = await usableOp()
|
|
435
|
+
if (null == target) {
|
|
436
|
+
return t.skip('no operation of this SDK completes against a plain 200; nothing to sweep')
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
const sinks: Sink[] = []
|
|
440
|
+
const sdk = makeSdk(SCENARIOS[1], sinks, { active: false })
|
|
441
|
+
const err = await drive(sdk, target, {}, sinks)
|
|
442
|
+
ok(null != err)
|
|
443
|
+
|
|
444
|
+
// Explaining a failure must not cost it its error.
|
|
445
|
+
const explained = await drive(makeSdk(SCENARIOS[1], [], { active: false }), target, { explain: {} }, [])
|
|
446
|
+
equal(explained?.message, err.message, 'with clean off, explain lost the error')
|
|
447
|
+
|
|
448
|
+
const leaked = sinks.filter((s) => 0 < leaks(s.text).length)
|
|
449
|
+
ok(0 < leaked.length, 'with clean off, nothing showed the canary: the sweep is blind')
|
|
450
|
+
|
|
451
|
+
if (!AUTH.suppressed) {
|
|
452
|
+
const text = JSON.stringify(err.spec)
|
|
453
|
+
ok(text.includes(CANARY.apikey) ||
|
|
454
|
+
text.includes(Buffer.from(CANARY.apikey + ':' + CANARY.secret).toString('base64')),
|
|
455
|
+
'the raw spec should carry the credential when clean is off')
|
|
456
|
+
}
|
|
457
|
+
})
|
|
458
|
+
})
|
|
459
|
+
`
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
export {
|
|
464
|
+
TestClean
|
|
465
|
+
}
|
|
@@ -9,6 +9,7 @@ import { cmp, each, Folder, entityCollection,
|
|
|
9
9
|
|
|
10
10
|
import { TestLive } from './TestLive_ts'
|
|
11
11
|
import { TestDefinition } from './TestDefinition_ts'
|
|
12
|
+
import { TestClean } from './TestClean_ts'
|
|
12
13
|
import { TestDirect } from './TestDirect_ts'
|
|
13
14
|
import { TestEntity } from './TestEntity_ts'
|
|
14
15
|
import { ReadmeExampleTest } from './ReadmeExampleTest_ts'
|
|
@@ -25,6 +26,7 @@ const Test = cmp(function Test(props: any) {
|
|
|
25
26
|
TestControl({ target, dir: 'test' })
|
|
26
27
|
TestLive({ target })
|
|
27
28
|
TestDefinition({ target })
|
|
29
|
+
TestClean({ target })
|
|
28
30
|
|
|
29
31
|
ReadmeExampleTest({ target })
|
|
30
32
|
ReadmeExamplesTest({ target })
|
|
@@ -159,6 +159,8 @@ class ProjectNameEntityBase<D = any> {
|
|
|
159
159
|
// Inbound: prefer the streaming feature's incremental iterator; else
|
|
160
160
|
// fall back to the materialised items so `stream` always yields.
|
|
161
161
|
if (result && 'function' === typeof result.stream) {
|
|
162
|
+
// done() does not run on this path, so its record is cleaned here.
|
|
163
|
+
utility.cleanExplain(ctx)
|
|
162
164
|
for await (const item of result.stream()) {
|
|
163
165
|
if (signal && signal.aborted) { return }
|
|
164
166
|
yield item
|
|
@@ -200,7 +202,6 @@ class ProjectNameEntityBase<D = any> {
|
|
|
200
202
|
const clean = this._utility.clean
|
|
201
203
|
const struct = this._utility.struct
|
|
202
204
|
|
|
203
|
-
const delprop = struct.delprop
|
|
204
205
|
const clone = struct.clone
|
|
205
206
|
const merge = struct.merge
|
|
206
207
|
|
|
@@ -209,8 +210,7 @@ class ProjectNameEntityBase<D = any> {
|
|
|
209
210
|
ctrl.err = err
|
|
210
211
|
|
|
211
212
|
if (ctrl.explain) {
|
|
212
|
-
|
|
213
|
-
delprop(ctx.ctrl.explain.result, 'err')
|
|
213
|
+
this._utility.cleanExplain(ctx)
|
|
214
214
|
|
|
215
215
|
if (null != ctx.result && null != ctx.result.err) {
|
|
216
216
|
ctrl.explain.err = clean(ctx, merge([
|
|
@@ -240,7 +240,8 @@ class ProjectNameEntityBase<D = any> {
|
|
|
240
240
|
return undefined
|
|
241
241
|
}
|
|
242
242
|
|
|
243
|
-
|
|
243
|
+
// An error a hook threw never passed through makeError.
|
|
244
|
+
return clean(ctx, err)
|
|
244
245
|
}
|
|
245
246
|
|
|
246
247
|
}
|
|
@@ -90,7 +90,13 @@ class EntityOperation {
|
|
|
90
90
|
return (ctx.result && ctx.result.ok) ? this : out
|
|
91
91
|
}
|
|
92
92
|
catch (err: any) {
|
|
93
|
-
//
|
|
93
|
+
// What a hook throws here must not escape the cleaning below.
|
|
94
|
+
try {
|
|
95
|
+
// #PreUnexpected-Hook
|
|
96
|
+
}
|
|
97
|
+
catch (hookerr: any) {
|
|
98
|
+
err = hookerr
|
|
99
|
+
}
|
|
94
100
|
|
|
95
101
|
err = this._unexpected(ctx, err)
|
|
96
102
|
|
|
@@ -89,7 +89,13 @@ class EntityOperation {
|
|
|
89
89
|
return done(ctx)
|
|
90
90
|
}
|
|
91
91
|
catch (err: any) {
|
|
92
|
-
//
|
|
92
|
+
// What a hook throws here must not escape the cleaning below.
|
|
93
|
+
try {
|
|
94
|
+
// #PreUnexpected-Hook
|
|
95
|
+
}
|
|
96
|
+
catch (hookerr: any) {
|
|
97
|
+
err = hookerr
|
|
98
|
+
}
|
|
93
99
|
|
|
94
100
|
err = this._unexpected(ctx, err)
|
|
95
101
|
|