@voxgig/sdkgen 4.9.0 → 4.10.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/dist/helpers/manifest.d.ts +2 -1
- package/dist/helpers/manifest.js +75 -1
- package/dist/helpers/manifest.js.map +1 -1
- package/dist/helpers/modelNames.d.ts +7 -0
- package/dist/helpers/modelNames.js +232 -0
- package/dist/helpers/modelNames.js.map +1 -0
- package/dist/helpers/naming.d.ts +2 -1
- package/dist/helpers/naming.js +45 -1
- package/dist/helpers/naming.js.map +1 -1
- package/dist/sdkgen.d.ts +3 -2
- package/dist/sdkgen.js +12 -3
- package/dist/sdkgen.js.map +1 -1
- package/dist/testkit.d.ts +2 -0
- package/dist/testkit.js +80 -24
- package/dist/testkit.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utility.js +17 -7
- package/dist/utility.js.map +1 -1
- package/package.json +1 -1
- package/project/.sdk/model/feature/secrets.aon +671 -0
- package/project/.sdk/model/target/clojure.aon +10 -0
- package/project/.sdk/model/target/csharp.aon +5 -0
- package/project/.sdk/model/target/elixir.aon +6 -0
- package/project/.sdk/model/target/java.aon +5 -0
- package/project/.sdk/model/target/js.aon +5 -0
- package/project/.sdk/model/target/kotlin.aon +7 -0
- package/project/.sdk/model/target/perl.aon +5 -0
- package/project/.sdk/model/target/php.aon +5 -0
- package/project/.sdk/model/target/rb.aon +5 -0
- package/project/.sdk/model/target/rust.aon +5 -0
- package/project/.sdk/model/target/scala.aon +38 -2
- package/project/.sdk/model/target/swift.aon +10 -0
- package/project/.sdk/src/cmp/clojure/Config_clojure.ts +51 -4
- package/project/.sdk/src/cmp/clojure/Main_clojure.ts +43 -1
- package/project/.sdk/src/cmp/clojure/Package_clojure.ts +17 -1
- package/project/.sdk/src/cmp/clojure/featureextra_clojure.ts +130 -0
- package/project/.sdk/src/cmp/csharp/Config_csharp.ts +70 -0
- package/project/.sdk/src/cmp/csharp/Main_csharp.ts +9 -1
- package/project/.sdk/src/cmp/csharp/Package_csharp.ts +25 -1
- package/project/.sdk/src/cmp/elixir/Config_elixir.ts +68 -2
- package/project/.sdk/src/cmp/elixir/Main_elixir.ts +16 -0
- package/project/.sdk/src/cmp/go-cli/Main_go-cli.ts +14 -1
- package/project/.sdk/src/cmp/java/Config_java.ts +84 -2
- package/project/.sdk/src/cmp/java/Main_java.ts +10 -1
- package/project/.sdk/src/cmp/js/Config_js.ts +75 -8
- package/project/.sdk/src/cmp/js/Main_js.ts +66 -2
- package/project/.sdk/src/cmp/js/fragment/Config.data.fragment.js +18 -1
- package/project/.sdk/src/cmp/js/fragment/Config.fragment.js +18 -1
- package/project/.sdk/src/cmp/js/fragment/Main.fragment.js +7 -0
- package/project/.sdk/src/cmp/kotlin/Config_kotlin.ts +63 -1
- package/project/.sdk/src/cmp/kotlin/Main_kotlin.ts +32 -2
- package/project/.sdk/src/cmp/perl/Config_perl.ts +129 -3
- package/project/.sdk/src/cmp/perl/Main_perl.ts +41 -1
- package/project/.sdk/src/cmp/perl/Package_perl.ts +13 -1
- package/project/.sdk/src/cmp/perl/fragment/Main.fragment.pm +1 -0
- package/project/.sdk/src/cmp/php/Config_php.ts +105 -1
- package/project/.sdk/src/cmp/php/Gitignore_php.ts +4 -2
- package/project/.sdk/src/cmp/php/Main_php.ts +16 -1
- package/project/.sdk/src/cmp/rb/Config_rb.ts +92 -2
- package/project/.sdk/src/cmp/rb/EntityTypes_rb.ts +11 -1
- package/project/.sdk/src/cmp/rb/Main_rb.ts +7 -1
- package/project/.sdk/src/cmp/rust/Main_rust.ts +99 -1
- package/project/.sdk/src/cmp/rust/Package_rust.ts +72 -6
- package/project/.sdk/src/cmp/scala/Config_scala.ts +44 -0
- package/project/.sdk/src/cmp/scala/Main_scala.ts +68 -1
- package/project/.sdk/src/cmp/swift/Config_swift.ts +62 -1
- package/project/.sdk/src/cmp/swift/Main_swift.ts +35 -1
- package/project/.sdk/src/cmp/swift/Package_swift.ts +81 -11
- package/project/.sdk/src/cmp/swift/fragment/Main.fragment.swift +58 -44
- package/project/.sdk/src/cmp/swift/utility_swift.ts +22 -0
- package/project/.sdk/tm/c/tests/vendor/omni/json.c +2 -2
- package/project/.sdk/tm/c/tests/vendor/omni/omni.h +2 -2
- package/project/.sdk/tm/c/tests/vendor/omni/runner.c +2 -2
- package/project/.sdk/tm/c/tests/vendor/omni/util.c +2 -2
- package/project/.sdk/tm/clojure/Makefile +3 -0
- package/project/.sdk/tm/clojure/feature/secrets/sdk/feature/secrets.clj +503 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/capability.clj +84 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/catalog.clj +44 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/config.clj +240 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/depend.clj +199 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/env.clj +111 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/export.clj +46 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/graph.clj +122 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/host.clj +1018 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/json.clj +106 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/order.clj +157 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/point.clj +77 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/ref.clj +92 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/resolve.clj +46 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/types.clj +177 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/version.clj +90 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin.clj +40 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/addr.clj +111 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/chain.clj +297 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/core.clj +192 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/json.clj +261 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/aws.clj +165 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/azuresecrets.clj +111 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/boru.clj +107 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/doppler.clj +61 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/gcpsecrets.clj +88 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/hashicorp.clj +115 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/httpjson.clj +214 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/infisical.clj +80 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/onepassword.clj +93 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/proc.clj +63 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/secretspec.clj +99 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/sigv4.clj +142 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/provider.clj +25 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/providers.clj +196 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto.clj +113 -0
- package/project/.sdk/tm/clojure/src/sdk/core.clj +9 -0
- package/project/.sdk/tm/clojure/src/sdk/features.clj +13 -1
- package/project/.sdk/tm/clojure/test/sdk/test/feature/secrets.clj +547 -0
- package/project/.sdk/tm/clojure/test/sdk/test_runner.clj +103 -14
- package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/json.clj +2 -2
- package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/runner.clj +2 -2
- package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/util.clj +2 -2
- package/project/.sdk/tm/cpp/test/vendor/omni/json.hpp +2 -2
- package/project/.sdk/tm/cpp/test/vendor/omni/omni.hpp +2 -2
- package/project/.sdk/tm/cpp/test/vendor/omni/util.hpp +2 -2
- package/project/.sdk/tm/csharp/feature/SecretsFeature.cs +889 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Capability.cs +196 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Catalog.cs +70 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Config.cs +505 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Definition.cs +52 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Depend.cs +285 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Entry.cs +55 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Env.cs +228 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Export.cs +102 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Graph.cs +256 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Host.cs +1379 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Inst.cs +177 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Json.cs +326 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Order.cs +295 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Plugin.cs +113 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Point.cs +177 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Refs.cs +198 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Resolve.cs +95 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Types.cs +351 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Version.cs +196 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Aws.cs +325 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/AzureSecrets.cs +195 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Boru.cs +192 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Child.cs +75 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Doppler.cs +112 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/GcpSecrets.cs +167 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Hashicorp.cs +221 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/HttpJson.cs +213 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Infisical.cs +155 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/OnePassword.cs +169 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/SecretSpec.cs +172 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Sigv4.cs +240 -0
- package/project/.sdk/tm/csharp/feature/secrets/sekreto/Json.cs +192 -0
- package/project/.sdk/tm/csharp/feature/secrets/sekreto/Providers.cs +503 -0
- package/project/.sdk/tm/csharp/feature/secrets/sekreto/Sekreto.cs +775 -0
- package/project/.sdk/tm/csharp/test/feature/secrets/SecretsFeatureTest.cs +1702 -0
- package/project/.sdk/tm/csharp/test/vendor/omni/Runner.cs +2 -2
- package/project/.sdk/tm/csharp/test/vendor/omni/Util.cs +2 -2
- package/project/.sdk/tm/csharp/utility/MakeOptions.cs +10 -0
- package/project/.sdk/tm/csharp/utility/struct/Struct.cs +1 -1
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/capability.ex +118 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/catalog.ex +56 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/config.ex +320 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/depend.ex +205 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/env.ex +166 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/error.ex +13 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/export.ex +73 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/graph.ex +185 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/host.ex +1182 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/inst.ex +139 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/json.ex +132 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/order.ex +179 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/point.ex +99 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/ref.ex +129 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/resolve.ex +59 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/types.ex +190 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/version.ex +136 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/voxgig_plugin.ex +42 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/json.ex +368 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/aws.ex +257 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/azuresecrets.ex +160 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/boru.ex +127 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/doppler.ex +96 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/gcpsecrets.ex +124 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/hashicorp.ex +162 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/http.ex +627 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/httpjson.ex +134 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/infisical.ex +125 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/onepassword.ex +152 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/proc.ex +80 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/secretspec.ex +101 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/sigv4.ex +176 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/provider.ex +67 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/providers.ex +536 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/sekreto.ex +662 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets.ex +824 -0
- package/project/.sdk/tm/elixir/test/feature/secrets/secrets_test.exs +1072 -0
- package/project/.sdk/tm/elixir/test/vendor/omni/json.ex +2 -2
- package/project/.sdk/tm/elixir/test/vendor/omni/runner.ex +2 -2
- package/project/.sdk/tm/elixir/test/vendor/omni/util.ex +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugin/capability.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/catalog.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/config.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/depend.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/env.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/export.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/graph.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/host.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/order.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/point.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/ref.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/resolve.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/types.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/util.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/version.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugins/aws/aws.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/aws/sigv4.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/azuresecrets/azuresecrets.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/boru/boru.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/doppler/doppler.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/gcpsecrets/gcpsecrets.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/hashicorp/hashicorp.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/httpjson/httpjson.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/infisical/infisical.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/onepassword/onepassword.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/secretspec/secretspec.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/sekreto/addr.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/sekreto/providers.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/sekreto/sekreto.go +2 -2
- package/project/.sdk/tm/go/feature/secrets_feature.go +16 -0
- package/project/.sdk/tm/go/test/feature/secrets/secrets_feature_test.go +123 -0
- package/project/.sdk/tm/go/test/omni/omni.go +2 -2
- package/project/.sdk/tm/go/test/omni/util.go +2 -2
- package/project/.sdk/tm/go/utility/struct/voxgigstruct.go +1 -1
- package/project/.sdk/tm/java/feature/SecretsFeature.java +766 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Capability.java +181 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Catalog.java +64 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Config.java +433 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Definition.java +54 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Depend.java +292 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Entry.java +49 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Env.java +204 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Export.java +93 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Graph.java +244 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Host.java +1196 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Inst.java +173 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Json.java +339 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Order.java +274 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Plugin.java +94 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/PluginException.java +37 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Point.java +172 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Refs.java +171 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Resolve.java +89 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Types.java +232 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Version.java +198 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/Addr.java +142 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/Builtins.java +229 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/Json.java +302 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/Provider.java +21 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/Sekreto.java +698 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/Support.java +100 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Aws.java +294 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Azuresecrets.java +164 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Boru.java +161 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Doppler.java +103 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Gcpsecrets.java +143 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Hashicorp.java +186 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Httpjson.java +192 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Infisical.java +139 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Onepassword.java +143 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Proc.java +80 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Secretspec.java +138 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Sigv4.java +243 -0
- package/project/.sdk/tm/java/test/feature/secrets/SecretsFeatureTest.java +986 -0
- package/project/.sdk/tm/java/test/vendor/omni/Json.java +2 -2
- package/project/.sdk/tm/java/test/vendor/omni/Runner.java +2 -2
- package/project/.sdk/tm/java/test/vendor/omni/Util.java +2 -2
- package/project/.sdk/tm/java/utility/MakeOptions.java +7 -0
- package/project/.sdk/tm/java/utility/struct/Struct.java +1 -1
- package/project/.sdk/tm/js/src/feature/secrets/SecretsFeature.js +431 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/capability.js +119 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/catalog.js +42 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/config.js +323 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/depend.js +196 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/env.js +120 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/export.js +48 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/graph.js +150 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/host.js +949 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/index.js +35 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/order.js +165 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/point.js +94 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/ref.js +106 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/resolve.js +59 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/types.js +79 -0
- package/project/.sdk/tm/js/src/feature/secrets/plugin/version.js +100 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/Sekreto.js +574 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/index.js +56 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/aws.js +188 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/azuresecrets.js +135 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/boru.js +128 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/doppler.js +67 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/gcpsecrets.js +115 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/hashicorp.js +139 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/httpjson.js +93 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/infisical.js +99 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/onepassword.js +111 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/secretspec.js +105 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/sigv4.js +157 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/addr.js +119 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/builtin.js +39 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/dotenv.js +40 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/env.js +21 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/file.js +42 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/memory.js +18 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/support.js +151 -0
- package/project/.sdk/tm/js/src/utility/StructUtility.js +1 -1
- package/project/.sdk/tm/js/test/feature/secrets/Secrets.test.js +946 -0
- package/project/.sdk/tm/js/test/vendor/omni/index.js +1 -1
- package/project/.sdk/tm/js/test/vendor/omni/runner.js +1 -1
- package/project/.sdk/tm/js/test/vendor/omni/util.js +1 -1
- package/project/.sdk/tm/kotlin/feature/SecretsFeature.kt +659 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Capability.kt +117 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Catalog.kt +40 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Config.kt +322 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Depend.kt +227 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Env.kt +163 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Export.kt +57 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Graph.kt +179 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Host.kt +1131 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Json.kt +241 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Order.kt +180 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Plugin.kt +64 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Point.kt +124 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Refs.kt +125 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Resolve.kt +66 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Types.kt +171 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Version.kt +132 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Json.kt +359 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Provider.kt +21 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Providers.kt +308 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Sekreto.kt +525 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Spec.kt +126 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Support.kt +205 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Aws.kt +251 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Azuresecrets.kt +145 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Boru.kt +130 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Doppler.kt +77 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Gcpsecrets.kt +119 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Hashicorp.kt +156 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Httpjson.kt +219 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Infisical.kt +114 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Onepassword.kt +114 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Secretspec.kt +118 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Sigv4.kt +220 -0
- package/project/.sdk/tm/kotlin/test/feature/secrets/SecretsTest.kt +1148 -0
- package/project/.sdk/tm/kotlin/test/vendor/omni/Json.kt +2 -2
- package/project/.sdk/tm/kotlin/test/vendor/omni/Runner.kt +2 -2
- package/project/.sdk/tm/kotlin/test/vendor/omni/Util.kt +2 -2
- package/project/.sdk/tm/kotlin/utility/struct/Struct.kt +1 -1
- package/project/.sdk/tm/lua/test/vendor/omni/json.lua +2 -2
- package/project/.sdk/tm/lua/test/vendor/omni/regex.lua +2 -2
- package/project/.sdk/tm/lua/test/vendor/omni/runner.lua +2 -2
- package/project/.sdk/tm/lua/test/vendor/omni/util.lua +2 -2
- package/project/.sdk/tm/lua/utility/struct/regex.lua +1 -1
- package/project/.sdk/tm/lua/utility/struct/struct.lua +1 -1
- package/project/.sdk/tm/ocaml/test/vendor/omni/omni.ml +2 -2
- package/project/.sdk/tm/perl/Makefile +6 -1
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Capability.pm +141 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Catalog.pm +65 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Config.pm +346 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Depend.pm +216 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Env.pm +176 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Export.pm +59 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Graph.pm +157 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Host.pm +1139 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Order.pm +187 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Point.pm +100 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Ref.pm +119 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Resolve.pm +71 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Types.pm +251 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Version.pm +122 -0
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin.pm +70 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Aws.pm +263 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Azuresecrets.pm +159 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Boru.pm +180 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Doppler.pm +92 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Gcpsecrets.pm +138 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Hashicorp.pm +213 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Httpjson.pm +173 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Infisical.pm +132 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Onepassword.pm +132 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Proc.pm +102 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Secretspec.pm +132 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Sigv4.pm +190 -0
- package/project/.sdk/tm/perl/feature/secrets/sekreto/Voxgig/Sekreto/Addr.pm +124 -0
- package/project/.sdk/tm/perl/feature/secrets/sekreto/Voxgig/Sekreto/Providers.pm +301 -0
- package/project/.sdk/tm/perl/feature/secrets/sekreto/Voxgig/Sekreto.pm +605 -0
- package/project/.sdk/tm/perl/feature/secrets_feature.pm +675 -0
- package/project/.sdk/tm/perl/lib/Voxgig/Struct.pm +1 -1
- package/project/.sdk/tm/perl/t/feature/secrets/secrets.t +957 -0
- package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Runner.pm +1 -1
- package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Util.pm +1 -1
- package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni.pm +1 -1
- package/project/.sdk/tm/php/feature/SecretsFeature.php +670 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Capability.php +226 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Catalog.php +75 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Config.php +444 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Depend.php +262 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Env.php +202 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Export.php +74 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Graph.php +195 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Host.php +1514 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Order.php +260 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Point.php +129 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Ref.php +169 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Resolve.php +79 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Types.php +348 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Version.php +163 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/plugin.php +40 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/aws.php +274 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/azuresecrets.php +170 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/boru.php +163 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/doppler.php +106 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/gcpsecrets.php +144 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/hashicorp.php +194 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/httpjson.php +113 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/infisical.php +131 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/onepassword.php +150 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/runcmd.php +101 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/secretspec.php +146 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/sigv4.php +161 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/src/Addr.php +129 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/src/Providers.php +322 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/src/Sekreto.php +724 -0
- package/project/.sdk/tm/php/test/feature/secrets/SecretsTest.php +1067 -0
- package/project/.sdk/tm/php/test/vendor/omni/Runner.php +2 -2
- package/project/.sdk/tm/php/test/vendor/omni/Util.php +2 -2
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/__init__.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/capability.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/catalog.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/config.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/depend.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/env.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/export.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/graph.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/host.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/order.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/point.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/ref.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/resolve.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/types.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/version.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/__init__.py +2 -2
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/addr.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/aws.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/azuresecrets.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/boru.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/doppler.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/gcpsecrets.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/hashicorp.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/httpjson.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/infisical.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/onepassword.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/secretspec.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/sigv4.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/providers.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/sekreto.py +1 -1
- package/project/.sdk/tm/py/pkg/utility/voxgig_struct/voxgig_struct.py +1 -1
- package/project/.sdk/tm/py/test/voxgig_omni/__init__.py +1 -1
- package/project/.sdk/tm/py/test/voxgig_omni/runner.py +1 -1
- package/project/.sdk/tm/py/test/voxgig_omni/util.py +1 -1
- package/project/.sdk/tm/rb/Makefile +7 -1
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/capability.rb +118 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/catalog.rb +55 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/config.rb +315 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/depend.rb +197 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/env.rb +143 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/export.rb +52 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/graph.rb +147 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/host.rb +1079 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/order.rb +169 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/point.rb +93 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/ref.rb +112 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/resolve.rb +56 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/types.rb +99 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/version.rb +106 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin.rb +24 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/addr.rb +111 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/aws.rb +200 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/azuresecrets.rb +130 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/boru.rb +121 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/doppler.rb +66 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/gcpsecrets.rb +107 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/hashicorp.rb +137 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/httpjson.rb +136 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/infisical.rb +97 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/onepassword.rb +104 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/secretspec.rb +113 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/sigv4.rb +127 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/providers.rb +210 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/sekreto.rb +465 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto.rb +30 -0
- package/project/.sdk/tm/rb/feature/secrets_feature.rb +561 -0
- package/project/.sdk/tm/rb/test/feature/secrets/secrets_feature_test.rb +842 -0
- package/project/.sdk/tm/rb/test/vendor/omni/runner.rb +2 -2
- package/project/.sdk/tm/rb/test/vendor/omni/util.rb +2 -2
- package/project/.sdk/tm/rb/test/vendor/omni/voxgig_omni.rb +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/capability.rs +130 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/catalog.rs +114 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/config.rs +416 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/depend.rs +245 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/env.rs +200 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/export.rs +90 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/graph.rs +231 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/host.rs +1565 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/mod.rs +18 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/order.rs +226 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/point.rs +137 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/refs.rs +148 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/resolve.rs +83 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/types.rs +132 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/value.rs +433 -0
- package/project/.sdk/tm/rust/feature/secrets/plugin/version.rs +174 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/aws/crypto.rs +146 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/aws/sigv4.rs +230 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/aws.rs +328 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/azuresecrets.rs +184 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/boru.rs +172 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/doppler.rs +102 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/gcpsecrets.rs +153 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/hashicorp.rs +228 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/httpjson/http.rs +537 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/httpjson/json.rs +300 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/httpjson.rs +137 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/infisical.rs +148 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/onepassword.rs +165 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/secretspec.rs +150 -0
- package/project/.sdk/tm/rust/feature/secrets/sekreto/addr.rs +144 -0
- package/project/.sdk/tm/rust/feature/secrets/sekreto/mod.rs +51 -0
- package/project/.sdk/tm/rust/feature/secrets/sekreto/providers.rs +637 -0
- package/project/.sdk/tm/rust/feature/secrets/sekreto/sekreto.rs +677 -0
- package/project/.sdk/tm/rust/feature/secrets.rs +961 -0
- package/project/.sdk/tm/rust/tests/feature/secrets/main.rs +1509 -0
- package/project/.sdk/tm/rust/tests/vendor/omni/json.rs +2 -2
- package/project/.sdk/tm/rust/tests/vendor/omni/mod.rs +2 -2
- package/project/.sdk/tm/rust/tests/vendor/omni/regex.rs +2 -2
- package/project/.sdk/tm/rust/tests/vendor/omni/runner.rs +2 -2
- package/project/.sdk/tm/rust/tests/vendor/omni/util.rs +2 -2
- package/project/.sdk/tm/scala/Makefile +8 -3
- package/project/.sdk/tm/scala/feature/SecretsFeature.scala +556 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Capability.scala +96 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Config.scala +270 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Depend.scala +216 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Env.scala +144 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Export.scala +59 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Graph.scala +149 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Host.scala +1089 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Json.scala +156 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Order.scala +169 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Plugin.scala +47 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Point.scala +107 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Refs.scala +131 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Resolve.scala +53 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Types.scala +110 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Value.scala +157 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Version.scala +136 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Json.scala +302 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Provider.scala +20 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Providers.scala +281 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Sekreto.scala +473 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Spec.scala +123 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Support.scala +216 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Aws.scala +225 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Azuresecrets.scala +124 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Boru.scala +104 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Doppler.scala +68 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Gcpsecrets.scala +97 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Hashicorp.scala +131 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Httpjson.scala +209 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Infisical.scala +98 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Onepassword.scala +90 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Secretspec.scala +95 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Sigv4.scala +214 -0
- package/project/.sdk/tm/scala/sdktest/feature/secrets/SecretsTestMain.scala +971 -0
- package/project/.sdk/tm/scala/sdktest/vendor/omni/Json.scala +2 -2
- package/project/.sdk/tm/scala/sdktest/vendor/omni/Runner.scala +2 -2
- package/project/.sdk/tm/scala/sdktest/vendor/omni/Util.scala +2 -2
- package/project/.sdk/tm/scala/utility/Make.scala +7 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/SecretsFeature.swift +669 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Capability.swift +98 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Catalog.swift +87 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Config.swift +298 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Depend.swift +209 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Env.swift +191 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Export.swift +63 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Graph.swift +158 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Host.swift +1141 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Json.swift +192 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Order.swift +183 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Point.swift +130 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Refs.swift +141 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Resolve.swift +59 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Types.swift +125 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Value.swift +198 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Version.swift +139 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Aws.swift +271 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Azuresecrets.swift +173 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Boru.swift +139 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Crypto.swift +198 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Doppler.swift +86 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Gcpsecrets.swift +129 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Hashicorp.swift +175 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Httpjson.swift +310 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Infisical.swift +140 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Onepassword.swift +118 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Proc.swift +105 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Secretspec.swift +111 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Sigv4.swift +297 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/sekreto/Addr.swift +120 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/sekreto/Json.swift +452 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/sekreto/Provider.swift +25 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/sekreto/Providers.swift +689 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/sekreto/Sekreto.swift +755 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +9 -0
- package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/PrimaryUtilityTest.swift +30 -0
- package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/feature/secrets/SecretsFeatureTest.swift +1030 -0
- package/project/.sdk/tm/swift/Tests/vendor/omni/Json.swift +2 -2
- package/project/.sdk/tm/swift/Tests/vendor/omni/Runner.swift +2 -2
- package/project/.sdk/tm/swift/Tests/vendor/omni/Util.swift +2 -2
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Capability.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Catalog.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Config.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Depend.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Env.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Export.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/FeatureHost.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Graph.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Host.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Order.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Point.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Ref.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Resolve.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Types.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Version.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/index.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Sekreto.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/index.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/aws.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/azuresecrets.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/boru.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/doppler.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/gcpsecrets.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/hashicorp.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/httpjson.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/infisical.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/onepassword.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/secretspec.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/sigv4.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/addr.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/builtin.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/dotenv.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/env.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/file.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/memory.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/support.ts +1 -1
- package/project/.sdk/tm/ts/src/utility/StructUtility.ts +1 -1
- package/project/.sdk/tm/ts/test/vendor/omni/Runner.ts +1 -1
- package/project/.sdk/tm/ts/test/vendor/omni/Util.ts +1 -1
- package/project/.sdk/tm/ts/test/vendor/omni/index.ts +1 -1
- package/project/.sdk/tm/zig/test/vendor/omni/omni.zig +2 -2
- package/project/.sdk/tm/zig/test/vendor/omni/regex.zig +2 -2
- package/project/.sdk/tm/zig/utility/voxgigstruct/regex.zig +2 -2
- package/project/.sdk/tm/zig/utility/voxgigstruct/struct.zig +2 -2
- package/project/sdkgen-package.json +1 -4
- package/src/helpers/manifest.ts +81 -1
- package/src/helpers/modelNames.ts +284 -0
- package/src/helpers/naming.ts +45 -1
- package/src/sdkgen.ts +11 -1
- package/src/testkit.ts +115 -26
- package/src/utility.ts +17 -7
- package/project/.sdk/model/target/dart.aon +0 -58
- package/project/.sdk/model/target/lean.aon +0 -91
- package/project/.sdk/model/target/seneca-provider.aon +0 -120
- package/project/.sdk/src/cmp/dart/Config_dart.ts +0 -176
- package/project/.sdk/src/cmp/dart/EntityBase_dart.ts +0 -34
- package/project/.sdk/src/cmp/dart/EntityOperation_dart.ts +0 -43
- package/project/.sdk/src/cmp/dart/EntityTypes_dart.ts +0 -207
- package/project/.sdk/src/cmp/dart/Entity_dart.ts +0 -87
- package/project/.sdk/src/cmp/dart/Gitignore_dart.ts +0 -34
- package/project/.sdk/src/cmp/dart/MainEntity_dart.ts +0 -33
- package/project/.sdk/src/cmp/dart/Main_dart.ts +0 -106
- package/project/.sdk/src/cmp/dart/Package_dart.ts +0 -82
- package/project/.sdk/src/cmp/dart/ReadmeEntity_dart.ts +0 -177
- package/project/.sdk/src/cmp/dart/ReadmeExamplesTest_dart.ts +0 -238
- package/project/.sdk/src/cmp/dart/ReadmeExplanation_dart.ts +0 -53
- package/project/.sdk/src/cmp/dart/ReadmeHowto_dart.ts +0 -152
- package/project/.sdk/src/cmp/dart/ReadmeInstall_dart.ts +0 -59
- package/project/.sdk/src/cmp/dart/ReadmeIntro_dart.ts +0 -65
- package/project/.sdk/src/cmp/dart/ReadmeModel_dart.ts +0 -151
- package/project/.sdk/src/cmp/dart/ReadmeOptions_dart.ts +0 -63
- package/project/.sdk/src/cmp/dart/ReadmeQuick_dart.ts +0 -225
- package/project/.sdk/src/cmp/dart/ReadmeRef_dart.ts +0 -397
- package/project/.sdk/src/cmp/dart/ReadmeTopHowto_dart.ts +0 -24
- package/project/.sdk/src/cmp/dart/ReadmeTopQuick_dart.ts +0 -106
- package/project/.sdk/src/cmp/dart/ReadmeTopTest_dart.ts +0 -78
- package/project/.sdk/src/cmp/dart/SdkError_dart.ts +0 -42
- package/project/.sdk/src/cmp/dart/TestDirect_dart.ts +0 -516
- package/project/.sdk/src/cmp/dart/TestEntity_dart.ts +0 -628
- package/project/.sdk/src/cmp/dart/Test_dart.ts +0 -116
- package/project/.sdk/src/cmp/dart/fragment/Config.data.fragment.dart +0 -79
- package/project/.sdk/src/cmp/dart/fragment/Config.fragment.dart +0 -51
- package/project/.sdk/src/cmp/dart/fragment/Direct.test.fragment.dart +0 -25
- package/project/.sdk/src/cmp/dart/fragment/Entity.fragment.dart +0 -29
- package/project/.sdk/src/cmp/dart/fragment/Entity.test.fragment.dart +0 -28
- package/project/.sdk/src/cmp/dart/fragment/EntityBase.fragment.dart +0 -302
- package/project/.sdk/src/cmp/dart/fragment/EntityCreateOp.fragment.dart +0 -98
- package/project/.sdk/src/cmp/dart/fragment/EntityListOp.fragment.dart +0 -90
- package/project/.sdk/src/cmp/dart/fragment/EntityLoadOp.fragment.dart +0 -102
- package/project/.sdk/src/cmp/dart/fragment/EntityRemoveOp.fragment.dart +0 -108
- package/project/.sdk/src/cmp/dart/fragment/EntityUpdateOp.fragment.dart +0 -102
- package/project/.sdk/src/cmp/dart/fragment/Main.fragment.dart +0 -338
- package/project/.sdk/src/cmp/dart/fragment/SdkError.fragment.dart +0 -26
- package/project/.sdk/src/cmp/dart/tsconfig.json +0 -15
- package/project/.sdk/src/cmp/dart/utility_dart.ts +0 -155
- package/project/.sdk/src/cmp/lean/Config_lean.ts +0 -93
- package/project/.sdk/src/cmp/lean/Entity_lean.ts +0 -9
- package/project/.sdk/src/cmp/lean/Gitignore_lean.ts +0 -18
- package/project/.sdk/src/cmp/lean/Main_lean.ts +0 -120
- package/project/.sdk/src/cmp/lean/Package_lean.ts +0 -93
- package/project/.sdk/src/cmp/lean/ReadmeEntity_lean.ts +0 -29
- package/project/.sdk/src/cmp/lean/ReadmeExplanation_lean.ts +0 -19
- package/project/.sdk/src/cmp/lean/ReadmeHowto_lean.ts +0 -25
- package/project/.sdk/src/cmp/lean/ReadmeInstall_lean.ts +0 -39
- package/project/.sdk/src/cmp/lean/ReadmeIntro_lean.ts +0 -25
- package/project/.sdk/src/cmp/lean/ReadmeModel_lean.ts +0 -24
- package/project/.sdk/src/cmp/lean/ReadmeOptions_lean.ts +0 -22
- package/project/.sdk/src/cmp/lean/ReadmeQuick_lean.ts +0 -50
- package/project/.sdk/src/cmp/lean/ReadmeRef_lean.ts +0 -40
- package/project/.sdk/src/cmp/lean/ReadmeTopHowto_lean.ts +0 -16
- package/project/.sdk/src/cmp/lean/ReadmeTopQuick_lean.ts +0 -23
- package/project/.sdk/src/cmp/lean/ReadmeTopTest_lean.ts +0 -19
- package/project/.sdk/src/cmp/lean/Test_lean.ts +0 -261
- package/project/.sdk/src/cmp/lean/utility_lean.ts +0 -129
- package/project/.sdk/src/cmp/seneca-provider/Extras_seneca-provider.ts +0 -4080
- package/project/.sdk/src/cmp/seneca-provider/Gitignore_seneca-provider.ts +0 -161
- package/project/.sdk/src/cmp/seneca-provider/Main_seneca-provider.ts +0 -1011
- package/project/.sdk/tm/dart/LICENSE +0 -22
- package/project/.sdk/tm/dart/Makefile +0 -50
- package/project/.sdk/tm/dart/lib/Context.dart +0 -150
- package/project/.sdk/tm/dart/lib/Control.dart +0 -15
- package/project/.sdk/tm/dart/lib/Operation.dart +0 -31
- package/project/.sdk/tm/dart/lib/Point.dart +0 -51
- package/project/.sdk/tm/dart/lib/Response.dart +0 -32
- package/project/.sdk/tm/dart/lib/Result.dart +0 -39
- package/project/.sdk/tm/dart/lib/Spec.dart +0 -49
- package/project/.sdk/tm/dart/lib/feature/audit/AuditFeature.dart +0 -103
- package/project/.sdk/tm/dart/lib/feature/base/BaseFeature.dart +0 -76
- package/project/.sdk/tm/dart/lib/feature/cache/CacheFeature.dart +0 -152
- package/project/.sdk/tm/dart/lib/feature/clienttrack/ClienttrackFeature.dart +0 -104
- package/project/.sdk/tm/dart/lib/feature/cost/CostFeature.dart +0 -446
- package/project/.sdk/tm/dart/lib/feature/debug/DebugFeature.dart +0 -153
- package/project/.sdk/tm/dart/lib/feature/idempotency/IdempotencyFeature.dart +0 -92
- package/project/.sdk/tm/dart/lib/feature/log/LogFeature.dart +0 -85
- package/project/.sdk/tm/dart/lib/feature/metrics/MetricsFeature.dart +0 -103
- package/project/.sdk/tm/dart/lib/feature/netsim/NetsimFeature.dart +0 -186
- package/project/.sdk/tm/dart/lib/feature/paging/PagingFeature.dart +0 -240
- package/project/.sdk/tm/dart/lib/feature/proxy/ProxyFeature.dart +0 -118
- package/project/.sdk/tm/dart/lib/feature/ratelimit/RatelimitFeature.dart +0 -103
- package/project/.sdk/tm/dart/lib/feature/rbac/RbacFeature.dart +0 -121
- package/project/.sdk/tm/dart/lib/feature/retry/RetryFeature.dart +0 -155
- package/project/.sdk/tm/dart/lib/feature/streaming/StreamingFeature.dart +0 -97
- package/project/.sdk/tm/dart/lib/feature/telemetry/TelemetryFeature.dart +0 -136
- package/project/.sdk/tm/dart/lib/feature/test/TestFeature.dart +0 -328
- package/project/.sdk/tm/dart/lib/feature/timeout/TimeoutFeature.dart +0 -104
- package/project/.sdk/tm/dart/lib/utility/CleanUtility.dart +0 -12
- package/project/.sdk/tm/dart/lib/utility/DoneUtility.dart +0 -18
- package/project/.sdk/tm/dart/lib/utility/ErrUtility.dart +0 -46
- package/project/.sdk/tm/dart/lib/utility/FeatureAddUtility.dart +0 -35
- package/project/.sdk/tm/dart/lib/utility/FeatureHookUtility.dart +0 -20
- package/project/.sdk/tm/dart/lib/utility/FeatureInitUtility.dart +0 -9
- package/project/.sdk/tm/dart/lib/utility/FetcherUtility.dart +0 -104
- package/project/.sdk/tm/dart/lib/utility/GraphqlUtility.dart +0 -162
- package/project/.sdk/tm/dart/lib/utility/MakeContextUtility.dart +0 -6
- package/project/.sdk/tm/dart/lib/utility/MakeErrorUtility.dart +0 -71
- package/project/.sdk/tm/dart/lib/utility/MakeFetchDefUtility.dart +0 -42
- package/project/.sdk/tm/dart/lib/utility/MakeOptionsUtility.dart +0 -233
- package/project/.sdk/tm/dart/lib/utility/MakePointUtility.dart +0 -130
- package/project/.sdk/tm/dart/lib/utility/MakeRequestUtility.dart +0 -66
- package/project/.sdk/tm/dart/lib/utility/MakeResponseUtility.dart +0 -59
- package/project/.sdk/tm/dart/lib/utility/MakeResultUtility.dart +0 -49
- package/project/.sdk/tm/dart/lib/utility/MakeSpecUtility.dart +0 -77
- package/project/.sdk/tm/dart/lib/utility/MakeUrlUtility.dart +0 -51
- package/project/.sdk/tm/dart/lib/utility/ParamUtility.dart +0 -56
- package/project/.sdk/tm/dart/lib/utility/PrepareAuthUtility.dart +0 -46
- package/project/.sdk/tm/dart/lib/utility/PrepareBodyUtility.dart +0 -19
- package/project/.sdk/tm/dart/lib/utility/PrepareHeadersUtility.dart +0 -11
- package/project/.sdk/tm/dart/lib/utility/PrepareMethodUtility.dart +0 -30
- package/project/.sdk/tm/dart/lib/utility/PrepareParamsUtility.dart +0 -23
- package/project/.sdk/tm/dart/lib/utility/PreparePathUtility.dart +0 -9
- package/project/.sdk/tm/dart/lib/utility/PrepareQueryUtility.dart +0 -18
- package/project/.sdk/tm/dart/lib/utility/ResultBasicUtility.dart +0 -29
- package/project/.sdk/tm/dart/lib/utility/ResultBodyUtility.dart +0 -15
- package/project/.sdk/tm/dart/lib/utility/ResultHeadersUtility.dart +0 -18
- package/project/.sdk/tm/dart/lib/utility/StructUtility.dart +0 -127
- package/project/.sdk/tm/dart/lib/utility/TransformRequestUtility.dart +0 -28
- package/project/.sdk/tm/dart/lib/utility/TransformResponseUtility.dart +0 -44
- package/project/.sdk/tm/dart/lib/utility/Utility.dart +0 -239
- package/project/.sdk/tm/dart/lib/utility/voxgig_struct.dart +0 -2462
- package/project/.sdk/tm/dart/src/feature/README.md +0 -3
- package/project/.sdk/tm/dart/src/feature/proxy/.gitkeep +0 -0
- package/project/.sdk/tm/dart/src/feature/ratelimit/.gitkeep +0 -0
- package/project/.sdk/tm/dart/src/feature/rbac/.gitkeep +0 -0
- package/project/.sdk/tm/dart/src/feature/retry/.gitkeep +0 -0
- package/project/.sdk/tm/dart/src/feature/streaming/.gitkeep +0 -0
- package/project/.sdk/tm/dart/src/feature/telemetry/.gitkeep +0 -0
- package/project/.sdk/tm/dart/src/feature/test/.gitkeep +0 -0
- package/project/.sdk/tm/dart/src/feature/timeout/.gitkeep +0 -0
- package/project/.sdk/tm/dart/test/custom_test.dart +0 -65
- package/project/.sdk/tm/dart/test/exists_test.dart +0 -12
- package/project/.sdk/tm/dart/test/feature/harness.dart +0 -329
- package/project/.sdk/tm/dart/test/feature_test.dart +0 -1193
- package/project/.sdk/tm/dart/test/harness.dart +0 -153
- package/project/.sdk/tm/dart/test/netsim_test.dart +0 -48
- package/project/.sdk/tm/dart/test/omni.dart +0 -520
- package/project/.sdk/tm/dart/test/omni_smoke_test.dart +0 -143
- package/project/.sdk/tm/dart/test/pipeline_test.dart +0 -608
- package/project/.sdk/tm/dart/test/primary_test.dart +0 -476
- package/project/.sdk/tm/dart/test/sdk-test-control.json +0 -19
- package/project/.sdk/tm/dart/test/struct_test.dart +0 -468
- package/project/.sdk/tm/dart/test/utility.dart +0 -198
- package/project/.sdk/tm/dart/test/vendor/omni/omni.dart +0 -7
- package/project/.sdk/tm/dart/test/vendor/omni/runner.dart +0 -653
- package/project/.sdk/tm/dart/test/vendor/omni/util.dart +0 -232
- package/project/.sdk/tm/lean/LICENSE +0 -21
- package/project/.sdk/tm/lean/Makefile +0 -32
- package/project/.sdk/tm/lean/VERSION +0 -1
- package/project/.sdk/tm/lean/src/SdkFeature.lean +0 -171
- package/project/.sdk/tm/lean/src/SdkFeatures.lean +0 -787
- package/project/.sdk/tm/lean/src/SdkJson.lean +0 -134
- package/project/.sdk/tm/lean/src/SdkRuntime.lean +0 -374
- package/project/.sdk/tm/lean/src/SdkUtility.lean +0 -809
- package/project/.sdk/tm/lean/src/VoxgigStruct.lean +0 -2880
- package/project/.sdk/tm/lean/src/Vregex.lean +0 -412
- package/project/.sdk/tm/lean/src/feature/README.md +0 -5
- package/project/.sdk/tm/lean/src/feature/audit/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/base/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/cache/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/clienttrack/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/cost/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/debug/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/idempotency/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/log/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/metrics/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/netsim/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/paging/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/proxy/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/ratelimit/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/rbac/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/retry/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/streaming/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/telemetry/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/test/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/timeout/.gitkeep +0 -0
- package/project/.sdk/tm/lean/test/OmniResolver.lean +0 -358
- package/project/.sdk/tm/lean/test/OmniSmoke.lean +0 -174
- package/project/.sdk/tm/lean/test/StructCorpus.lean +0 -368
- package/project/.sdk/tm/lean/test/TFeature.lean +0 -281
- package/project/.sdk/tm/lean/test/TPrimaryUtility.lean +0 -227
- package/project/.sdk/tm/lean/test/vendor/omni/Omni.lean +0 -997
- package/project/.sdk/tm/seneca-provider/CODE_OF_CONDUCT.md +0 -132
- package/project/.sdk/tm/seneca-provider/LICENSE +0 -21
- package/project/.sdk/tm/seneca-provider/Makefile +0 -15
- package/project/.sdk/tm/seneca-provider/src/tsconfig.json +0 -18
- package/project/.sdk/tm/seneca-provider/test/tsconfig.json +0 -16
- package/project/.sdk/tm/seneca-provider/tsfmt.json +0 -3
- /package/project/.sdk/tm/{dart/src/feature/audit → clojure/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/base → csharp/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/cache → elixir/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/clienttrack → java/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/cost → kotlin/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/debug → perl/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/idempotency → php/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/log → rb/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/metrics → rust/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/netsim → scala/src/feature/secrets}/.gitkeep +0 -0
- /package/project/.sdk/tm/{dart/src/feature/paging → swift/src/feature/secrets}/.gitkeep +0 -0
package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/feature/secrets/SecretsFeatureTest.swift
ADDED
|
@@ -0,0 +1,1030 @@
|
|
|
1
|
+
// Behavioural tests for the secrets feature (vendored @voxgig/sekreto) -
|
|
2
|
+
// the swift port of tm/ts/test/feature/secrets/Secrets.test.ts, in the
|
|
3
|
+
// shape of kotlin's SecretsTest.kt.
|
|
4
|
+
//
|
|
5
|
+
// The contract under test: the `apikey` OPTION keeps its exact old meaning
|
|
6
|
+
// and always wins, because SecretsFeature places it FIRST in the provider
|
|
7
|
+
// chain (a `memory` store named `options`) - explicit-beats-lookup falls
|
|
8
|
+
// out of sekreto's first-hit rule rather than from special-case logic.
|
|
9
|
+
// With the feature inactive nothing changes at all. With it active and the
|
|
10
|
+
// option unset, the chain (a memory store, a custom provider, a vault)
|
|
11
|
+
// supplies the credential instead.
|
|
12
|
+
//
|
|
13
|
+
// This file lives in the test `feature/` container on purpose: `target add`
|
|
14
|
+
// trims it, along with the feature source and the vendored library, for a
|
|
15
|
+
// project whose model does not select `secrets` - and Main_swift withholds
|
|
16
|
+
// it at generate time for the same model, because it imports Sekreto.
|
|
17
|
+
//
|
|
18
|
+
// THE CLIENT IS LIVE AND THE TRANSPORT IS THE THING COUNTED. Every wire
|
|
19
|
+
// assertion here runs against a real client whose `system.fetch` is the
|
|
20
|
+
// recorder - never `testSDK`, whose test feature REPLACES the fetcher with
|
|
21
|
+
// its own in-memory mock and would leave a `system.fetch` counter at zero
|
|
22
|
+
// for a healthy SDK carrying no secrets feature at all. An assertion that
|
|
23
|
+
// cannot fail pins no rule, so each fail-closed case additionally carries a
|
|
24
|
+
// CONTROL leg: the same construction with a WORKING provider must reach the
|
|
25
|
+
// same recorder exactly once, carrying the credential. Only then does a
|
|
26
|
+
// zero from the broken provider mean REFUSED rather than UNWIRED. And the
|
|
27
|
+
// refusal is matched on the PROVIDER'S OWN message, so an unrelated failure
|
|
28
|
+
// (a missing route, a blocked op) cannot stand in for fail-closed.
|
|
29
|
+
//
|
|
30
|
+
// The feature is CONSTRUCTED DIRECTLY and adopted through the `extend`
|
|
31
|
+
// option ONLY when the generated Config did not already install it, so
|
|
32
|
+
// these tests hold in any generated tree - and never double the feature
|
|
33
|
+
// (two transport wraps, two purchases) in one that did.
|
|
34
|
+
//
|
|
35
|
+
// NO ENVIRONMENT VARIABLES. Foundation has no supported way to set one for
|
|
36
|
+
// the current process, so the ts/go/js suites' `env` chains become `memory`
|
|
37
|
+
// chains and custom Provider objects here. The rule under test - the chain
|
|
38
|
+
// answers when the option does not - is identical either way.
|
|
39
|
+
|
|
40
|
+
import Foundation
|
|
41
|
+
import XCTest
|
|
42
|
+
|
|
43
|
+
@testable import ProjectNameSdk
|
|
44
|
+
import Sekreto
|
|
45
|
+
import struct VoxgigPlugin.Definition
|
|
46
|
+
|
|
47
|
+
// -------------------------------------------------------------------
|
|
48
|
+
// The recording transport: system.fetch for a LIVE client, scripting one
|
|
49
|
+
// status per API call (the last repeating) and a token endpoint for the
|
|
50
|
+
// exchange tests.
|
|
51
|
+
|
|
52
|
+
final class SecretsWire {
|
|
53
|
+
struct Call {
|
|
54
|
+
let url: String
|
|
55
|
+
let auth: String
|
|
56
|
+
let hasAuth: Bool
|
|
57
|
+
let body: String
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private let lock = NSLock()
|
|
61
|
+
private var recorded: [Call] = []
|
|
62
|
+
|
|
63
|
+
var apistatus: [Int] = [200]
|
|
64
|
+
var tokens: [String] = ["ACCESS01", "ACCESS02", "ACCESS03"]
|
|
65
|
+
var tokenpath = "auth/token"
|
|
66
|
+
var respfield = "access_token"
|
|
67
|
+
|
|
68
|
+
// A token endpoint that starts refusing after `tokenok` successful
|
|
69
|
+
// purchases (0 refuses the first).
|
|
70
|
+
var tokenok = Int.max
|
|
71
|
+
|
|
72
|
+
private var issued = 0
|
|
73
|
+
private var apicalls = 0
|
|
74
|
+
|
|
75
|
+
// A `SystemFetch`-typed closure: that is the shape utility/Fetcher.swift
|
|
76
|
+
// casts `system.fetch` to, and a closure stored under any other type
|
|
77
|
+
// would be silently refused as "not a valid function".
|
|
78
|
+
lazy var fetch: SystemFetch = { [unowned self] url, fetchdef in
|
|
79
|
+
self.serve(url, fetchdef)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
private func serve(_ url: String, _ fetchdef: VMap) -> Value {
|
|
83
|
+
lock.lock()
|
|
84
|
+
defer { lock.unlock() }
|
|
85
|
+
|
|
86
|
+
// The header value is SNAPSHOT here, not referenced: the retry path
|
|
87
|
+
// rewrites the same headers map in place, so a stored reference would
|
|
88
|
+
// make every earlier record show the newest token.
|
|
89
|
+
var auth = ""
|
|
90
|
+
var hasAuth = false
|
|
91
|
+
if let headers = gp(fetchdef, "headers").asMap {
|
|
92
|
+
for (k, v) in headers.entries where k.lowercased() == "authorization" {
|
|
93
|
+
hasAuth = true
|
|
94
|
+
auth = v.asString ?? stringify(v)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
let body = gp(fetchdef, "body").asString ?? ""
|
|
98
|
+
recorded.append(Call(url: url, auth: auth, hasAuth: hasAuth, body: body))
|
|
99
|
+
|
|
100
|
+
if url.hasSuffix("/" + tokenpath) {
|
|
101
|
+
if issued >= tokenok {
|
|
102
|
+
issued += 1
|
|
103
|
+
return SecretsWire.response(500, vm(("error", .string("nope"))))
|
|
104
|
+
}
|
|
105
|
+
let token = tokens[min(issued, tokens.count - 1)]
|
|
106
|
+
issued += 1
|
|
107
|
+
return SecretsWire.response(200, vm((respfield, .string(token))))
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
let status = apistatus[min(apicalls, apistatus.count - 1)]
|
|
111
|
+
apicalls += 1
|
|
112
|
+
return SecretsWire.response(status, vm(("ok", .bool(status < 400))))
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
static func response(_ status: Int, _ payload: VMap) -> Value {
|
|
116
|
+
let captured: Value = .map(payload)
|
|
117
|
+
return .map(vm(
|
|
118
|
+
("status", .int(Int64(status))),
|
|
119
|
+
("statusText", .string(status < 400 ? "OK" : "ERR")),
|
|
120
|
+
("headers", .map(VMap())),
|
|
121
|
+
("json", .nat({ () -> Value in captured } as NativeCall0))))
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
func calls() -> [Call] {
|
|
125
|
+
lock.lock()
|
|
126
|
+
defer { lock.unlock() }
|
|
127
|
+
return recorded
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// The recorded calls that did NOT go to the token endpoint.
|
|
131
|
+
func api() -> [Call] {
|
|
132
|
+
return calls().filter { !$0.url.hasSuffix("/" + tokenpath) }
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
func token() -> [Call] {
|
|
136
|
+
return calls().filter { $0.url.hasSuffix("/" + tokenpath) }
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// What went out, for a message that names the leak rather than counting it.
|
|
140
|
+
func wire() -> String {
|
|
141
|
+
return calls().map { $0.url + " auth=" + $0.auth }.joined(separator: ", ")
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// A sekreto Provider built in code.
|
|
146
|
+
final class SecretsProbeProvider: Provider {
|
|
147
|
+
private let onlookup: (String) throws -> String?
|
|
148
|
+
private let label: String
|
|
149
|
+
|
|
150
|
+
init(_ label: String = "custom:test", _ onlookup: @escaping (String) throws -> String?) {
|
|
151
|
+
self.label = label
|
|
152
|
+
self.onlookup = onlookup
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
func lookup(_ name: String) throws -> String? {
|
|
156
|
+
return try onlookup(name)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
func describe() -> String {
|
|
160
|
+
return label
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// A provider's own failure - carries only its message, so that message is
|
|
165
|
+
// the one thing a refusal can be matched on.
|
|
166
|
+
struct SecretsProbeError: Error, CustomStringConvertible {
|
|
167
|
+
let message: String
|
|
168
|
+
init(_ message: String) { self.message = message }
|
|
169
|
+
var description: String { message }
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
final class SecretsFeatureTest: XCTestCase {
|
|
173
|
+
|
|
174
|
+
static let BASE = "http://secrets.test/api"
|
|
175
|
+
|
|
176
|
+
// -------------------------------------------------------------------
|
|
177
|
+
// Support.
|
|
178
|
+
|
|
179
|
+
// The Authorization header carries the SPEC's credential prefix, which a
|
|
180
|
+
// TEMPLATE cannot know: an OpenAPI `http`/`bearer` scheme gives
|
|
181
|
+
// `Bearer <token>`, an apiKey scheme the raw token. So assert on the
|
|
182
|
+
// CREDENTIAL and let the prefix be whatever this SDK's API declares.
|
|
183
|
+
private func credentialIs(_ header: String, _ token: String,
|
|
184
|
+
file: StaticString = #filePath, line: UInt = #line) {
|
|
185
|
+
XCTAssertTrue(header == token || header.hasSuffix(" " + token),
|
|
186
|
+
"expected the authorization header to carry \(token), got: \"\(header)\"",
|
|
187
|
+
file: file, line: line)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
private func secretsOf(_ client: ProjectNameSDK) -> SecretsFeature? {
|
|
191
|
+
return client.features.first { $0 is SecretsFeature } as? SecretsFeature
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
private func messageOf(_ err: Error?) -> String {
|
|
195
|
+
guard let e = err else { return "" }
|
|
196
|
+
if let pe = e as? ProjectNameError { return pe.message }
|
|
197
|
+
return String(describing: e)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private func errOf(_ res: VMap) -> Error? {
|
|
201
|
+
return res.entries["err"]?.asNative as? Error
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Build the client, and ADOPT the feature via `extend` ONLY when the
|
|
205
|
+
// generated Config did not already install it: when this SDK was generated
|
|
206
|
+
// with `secrets` model-active, the ordinary factory path builds the
|
|
207
|
+
// instance, and adding a second via extend would DOUBLE the feature - two
|
|
208
|
+
// transport wraps, two resolutions, and a token purchase the assertions
|
|
209
|
+
// cannot account for.
|
|
210
|
+
private func withSecrets(_ build: (Bool) -> ProjectNameSDK) -> ProjectNameSDK {
|
|
211
|
+
let client = build(false)
|
|
212
|
+
if nil != secretsOf(client) {
|
|
213
|
+
return client
|
|
214
|
+
}
|
|
215
|
+
return build(true)
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// A LIVE client carrying the secrets feature, wired to the recorder.
|
|
219
|
+
//
|
|
220
|
+
// `allow.op` is named explicitly: a project that narrows the default set
|
|
221
|
+
// would otherwise turn the raw-path cases into a false RED (the control
|
|
222
|
+
// leg refused before it reached the transport).
|
|
223
|
+
private func secretsClient(_ w: SecretsWire, _ extra: [(String, Value)]) -> ProjectNameSDK {
|
|
224
|
+
return withSecrets { extend in
|
|
225
|
+
let opts = VMap()
|
|
226
|
+
opts.entries["base"] = .string(SecretsFeatureTest.BASE)
|
|
227
|
+
opts.entries["allow"] = .map(vm(
|
|
228
|
+
("op", .string("create,update,load,list,remove,command,direct,graphql"))))
|
|
229
|
+
opts.entries["system"] = .map(vm(("fetch", .nat(w.fetch))))
|
|
230
|
+
for (k, v) in extra {
|
|
231
|
+
opts.entries[k] = v
|
|
232
|
+
}
|
|
233
|
+
if extend {
|
|
234
|
+
opts.entries["extend"] = .list([.nat(SecretsFeature())])
|
|
235
|
+
}
|
|
236
|
+
return ProjectNameSDK(opts)
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// The feature options block: one provider (a live Provider object, or a
|
|
241
|
+
// declarative spec / plain map), plus any extra feature options.
|
|
242
|
+
private func chainOpts(_ provider: Value, _ extra: [(String, Value)] = []) -> Value {
|
|
243
|
+
let fopts = VMap()
|
|
244
|
+
fopts.entries["active"] = .bool(true)
|
|
245
|
+
fopts.entries["providers"] = .list([provider])
|
|
246
|
+
for (k, v) in extra {
|
|
247
|
+
fopts.entries[k] = v
|
|
248
|
+
}
|
|
249
|
+
return .map(vm(("secrets", .map(fopts))))
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
private func working(_ value: String) -> Value {
|
|
253
|
+
return .nat(SecretsProbeProvider("working:test") { name in
|
|
254
|
+
"apikey" == name ? value : nil
|
|
255
|
+
})
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
private var broken: Value {
|
|
259
|
+
return .nat(SecretsProbeProvider("broken:test") { _ in
|
|
260
|
+
throw SecretsProbeError("vault unreachable")
|
|
261
|
+
})
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
private func memorySpec(_ key: String, _ value: String) -> Value {
|
|
265
|
+
return .map(vm(("kind", .string("memory")), ("values", .map(vm((key, .string(value)))))))
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
// -------------------------------------------------------------------
|
|
269
|
+
// Driving real entity operations - which is what runs the whole pipeline
|
|
270
|
+
// and reaches the transport. Entities are discovered from the generated
|
|
271
|
+
// CONFIG rather than named, because this file is a TEMPLATE and no
|
|
272
|
+
// project's entity names are known here; each is driven through the
|
|
273
|
+
// shared ProjectNameEntityBase pipeline exactly as a generated entity's
|
|
274
|
+
// own `list`/`load` do (src/cmp/swift/fragment/Entity*Op.fragment.swift).
|
|
275
|
+
// An op the API does not define fails BEFORE the transport, which is why
|
|
276
|
+
// several may need driving.
|
|
277
|
+
|
|
278
|
+
private func entityNames() -> [String] {
|
|
279
|
+
return gp(SdkConfig.sharedConfig(), "entity").asMap?.entries.keys.sorted() ?? []
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
private func runEntityOp(_ client: ProjectNameSDK, _ entity: String,
|
|
283
|
+
_ opname: String) throws -> Value {
|
|
284
|
+
let ent = ProjectNameEntityBase(client, nil, entity)
|
|
285
|
+
let ctx = ent.utility.makeContext(
|
|
286
|
+
["opname": opname, "match": ent.match, "data": ent.data], ent.entctx)
|
|
287
|
+
return try ent.runOp(ctx) {}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Drives ops until `stop` reports the observable state a test waits for,
|
|
291
|
+
// and returns the last error an op raised (the operation's own outcome is
|
|
292
|
+
// otherwise irrelevant: no seeded data, a scripted response). `stop` is
|
|
293
|
+
// handed that last error too, so a fail-closed case can stop on EITHER
|
|
294
|
+
// outcome - the refusal it wants, or a request going out, which is the
|
|
295
|
+
// failure it exists to catch; stopping only on the refusal would report
|
|
296
|
+
// "nothing to assert on" for the leak.
|
|
297
|
+
private func driveEntityOpUntil(_ client: ProjectNameSDK, _ what: String,
|
|
298
|
+
_ stop: (Error?) -> Bool) -> Error? {
|
|
299
|
+
var last: Error? = nil
|
|
300
|
+
|
|
301
|
+
for name in entityNames() {
|
|
302
|
+
for op in ["list", "load"] {
|
|
303
|
+
do {
|
|
304
|
+
let out = try runEntityOp(client, name, op)
|
|
305
|
+
if let m = out.asMap, let e = m.entries["err"]?.asNative as? Error {
|
|
306
|
+
last = e
|
|
307
|
+
}
|
|
308
|
+
} catch {
|
|
309
|
+
last = error
|
|
310
|
+
}
|
|
311
|
+
if stop(last) {
|
|
312
|
+
return last
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
XCTFail("no entity operation \(what) - nothing to assert on")
|
|
318
|
+
return last
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
@discardableResult
|
|
322
|
+
private func driveEntityOp(_ client: ProjectNameSDK, _ w: SecretsWire) -> Error? {
|
|
323
|
+
let before = w.api().count
|
|
324
|
+
return driveEntityOpUntil(client, "reached the transport") { _ in before < w.api().count }
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// ===================================================================
|
|
328
|
+
// The feature-inactive baseline: bit-identical behaviour.
|
|
329
|
+
|
|
330
|
+
func testInactiveApikeyOptionBehavesExactlyAsBefore() throws {
|
|
331
|
+
let client = ProjectNameSDK.testSDK(nil, vm(("apikey", .string("OPTKEY01"))))
|
|
332
|
+
let fetchdef = try client.prepare(vm(("path", .string("/"))))
|
|
333
|
+
let headers = gp(fetchdef, "headers").asMap ?? VMap()
|
|
334
|
+
credentialIs(gp(headers, "authorization").asString ?? "", "OPTKEY01")
|
|
335
|
+
|
|
336
|
+
// No runtime activation, no extend: the feature must not be installed,
|
|
337
|
+
// whatever this project's model says.
|
|
338
|
+
XCTAssertNil(secretsOf(client),
|
|
339
|
+
"the feature must not install itself without feature.secrets.active")
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
func testInactiveNoApikeyMeansNoAuthorizationHeader() throws {
|
|
343
|
+
let client = ProjectNameSDK.testSDK(nil, nil)
|
|
344
|
+
let fetchdef = try client.prepare(vm(("path", .string("/"))))
|
|
345
|
+
let headers = gp(fetchdef, "headers").asMap ?? VMap()
|
|
346
|
+
XCTAssertNil(headers.entries["authorization"],
|
|
347
|
+
"unexpected authorization header: \(stringify(gp(headers, "authorization")))")
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// ===================================================================
|
|
351
|
+
// Active: the provider chain, driven through real entity operations.
|
|
352
|
+
|
|
353
|
+
func testApikeyOptionStillWinsOverTheChain() throws {
|
|
354
|
+
let w = SecretsWire()
|
|
355
|
+
let client = secretsClient(w, [
|
|
356
|
+
("apikey", .string("OPTKEY01")),
|
|
357
|
+
("feature", chainOpts(working("CHAINKEY01"))),
|
|
358
|
+
])
|
|
359
|
+
|
|
360
|
+
driveEntityOp(client, w)
|
|
361
|
+
credentialIs(w.api()[0].auth, "OPTKEY01")
|
|
362
|
+
|
|
363
|
+
// The explicit option is a real store, not a special case: a directed
|
|
364
|
+
// read names it like any other.
|
|
365
|
+
guard let sf = secretsOf(client) else {
|
|
366
|
+
return XCTFail("the extend seam did not install the feature")
|
|
367
|
+
}
|
|
368
|
+
XCTAssertEqual("OPTKEY01", try sf.sekreto()!.getfrom("options", "apikey"))
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
func testAnOmittedApikeyDefersToTheChainAtTheTransportSeam() {
|
|
372
|
+
let w = SecretsWire()
|
|
373
|
+
let client = secretsClient(w, [
|
|
374
|
+
("feature", chainOpts(working("CHAINKEY02"))),
|
|
375
|
+
])
|
|
376
|
+
|
|
377
|
+
// Before any op, nothing has been resolved.
|
|
378
|
+
XCTAssertEqual("", secretsOf(client)!.credential(),
|
|
379
|
+
"the chain was consulted before any operation")
|
|
380
|
+
|
|
381
|
+
driveEntityOp(client, w)
|
|
382
|
+
|
|
383
|
+
// Resolution happens AT THE TRANSPORT - the one seam every wire path
|
|
384
|
+
// crosses - so the credential is ON THE WIRE, not merely resolved.
|
|
385
|
+
credentialIs(w.api()[0].auth, "CHAINKEY02")
|
|
386
|
+
XCTAssertEqual("CHAINKEY02", secretsOf(client)!.credential())
|
|
387
|
+
|
|
388
|
+
// And the shared options map stays FROZEN: prepareAuth clones it on
|
|
389
|
+
// every request, so a feature writing to it would race every concurrent
|
|
390
|
+
// operation.
|
|
391
|
+
XCTAssertEqual("", gp(client.optionsMap(), "apikey").asString ?? "",
|
|
392
|
+
"the options map must stay unwritten after construction")
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
func testAnExplicitlyEmptyApikeyAlsoDefersToTheChain() {
|
|
396
|
+
let w = SecretsWire()
|
|
397
|
+
let client = secretsClient(w, [
|
|
398
|
+
("apikey", .string("")),
|
|
399
|
+
("feature", chainOpts(working("CHAINKEY03"))),
|
|
400
|
+
])
|
|
401
|
+
|
|
402
|
+
driveEntityOp(client, w)
|
|
403
|
+
credentialIs(w.api()[0].auth, "CHAINKEY03")
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
func testCustomProviderObjectsAreAcceptedVerbatim() {
|
|
407
|
+
let asklock = NSLock()
|
|
408
|
+
var asked: [String] = []
|
|
409
|
+
let w = SecretsWire()
|
|
410
|
+
let client = secretsClient(w, [
|
|
411
|
+
("feature", chainOpts(.nat(SecretsProbeProvider { name in
|
|
412
|
+
asklock.lock()
|
|
413
|
+
asked.append(name)
|
|
414
|
+
asklock.unlock()
|
|
415
|
+
return "CUSTOM01"
|
|
416
|
+
}))),
|
|
417
|
+
])
|
|
418
|
+
|
|
419
|
+
driveEntityOp(client, w)
|
|
420
|
+
credentialIs(w.api()[0].auth, "CUSTOM01")
|
|
421
|
+
XCTAssertTrue(asked.contains("apikey"),
|
|
422
|
+
"the custom provider was asked \(asked), want it to include apikey")
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
func testTypedProviderSpecsAreAcceptedVerbatim() {
|
|
426
|
+
// The typed arm of the providers list: a ProviderSpec built in code
|
|
427
|
+
// joins the chain without going through `specof`.
|
|
428
|
+
let w = SecretsWire()
|
|
429
|
+
let client = secretsClient(w, [
|
|
430
|
+
("feature", chainOpts(.nat(ProviderSpec(
|
|
431
|
+
kind: "memory",
|
|
432
|
+
values: Ordered<String>([("APIKEY", "SPECKEY01")]))))),
|
|
433
|
+
])
|
|
434
|
+
|
|
435
|
+
driveEntityOp(client, w)
|
|
436
|
+
credentialIs(w.api()[0].auth, "SPECKEY01")
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
func testDeclarativeMemorySpecsAreAcceptedAsMaps() {
|
|
440
|
+
// A chain given as plain maps (the shape a config file produces) is
|
|
441
|
+
// turned into ProviderSpecs by sekreto's own `specof`.
|
|
442
|
+
let w = SecretsWire()
|
|
443
|
+
let client = secretsClient(w, [
|
|
444
|
+
("feature", chainOpts(memorySpec("APIKEY", "MAPKEY01"))),
|
|
445
|
+
])
|
|
446
|
+
|
|
447
|
+
driveEntityOp(client, w)
|
|
448
|
+
credentialIs(w.api()[0].auth, "MAPKEY01")
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
func testAMissEverywhereLeavesTheHeaderOff() {
|
|
452
|
+
let w = SecretsWire()
|
|
453
|
+
let client = secretsClient(w, [
|
|
454
|
+
("feature", chainOpts(.nat(SecretsProbeProvider("empty:test") { _ in nil }))),
|
|
455
|
+
])
|
|
456
|
+
|
|
457
|
+
driveEntityOp(client, w)
|
|
458
|
+
|
|
459
|
+
// A MISS falls through to an unauthenticated request - and leaves the
|
|
460
|
+
// header ABSENT rather than empty, which is what prepareAuth does.
|
|
461
|
+
XCTAssertFalse(w.api()[0].hasAuth,
|
|
462
|
+
"a chain MISS must leave the header off, got \"\(w.api()[0].auth)\"")
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
func testAuthNullSuppressesTheCredentialChainOrNoChain() {
|
|
466
|
+
let w = SecretsWire()
|
|
467
|
+
let client = secretsClient(w, [
|
|
468
|
+
("auth", .null),
|
|
469
|
+
("apikey", .string("OPTKEY01")),
|
|
470
|
+
("feature", chainOpts(working("CHAINKEY04"))),
|
|
471
|
+
])
|
|
472
|
+
|
|
473
|
+
driveEntityOp(client, w)
|
|
474
|
+
|
|
475
|
+
// Nothing on the wire, even though the chain would have resolved AND an
|
|
476
|
+
// explicit apikey was given.
|
|
477
|
+
XCTAssertFalse(w.api()[0].hasAuth,
|
|
478
|
+
"auth null must suppress the credential, got \"\(w.api()[0].auth)\"")
|
|
479
|
+
|
|
480
|
+
// The suppression survives option validation rather than being replaced
|
|
481
|
+
// by the optspec's default auth map.
|
|
482
|
+
let opts = client.optionsMap()
|
|
483
|
+
XCTAssertNotNil(opts.entries["auth"], "options.auth must stay present")
|
|
484
|
+
XCTAssertTrue(opts.entries["auth"]?.isNull ?? false, "options.auth must stay a null")
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
func testSecretNameIsConfigurable() {
|
|
488
|
+
let w = SecretsWire()
|
|
489
|
+
let client = secretsClient(w, [
|
|
490
|
+
("feature", chainOpts(memorySpec("API_TOKEN", "TOKKEY01"),
|
|
491
|
+
[("name", .string("api.token"))])),
|
|
492
|
+
])
|
|
493
|
+
|
|
494
|
+
driveEntityOp(client, w)
|
|
495
|
+
credentialIs(w.api()[0].auth, "TOKKEY01")
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
func testSekretoIsLiveForArbitrarySecretsAndRedaction() throws {
|
|
499
|
+
let w = SecretsWire()
|
|
500
|
+
let client = secretsClient(w, [
|
|
501
|
+
("feature", chainOpts(memorySpec("DB_PASSWORD", "dbpass01"))),
|
|
502
|
+
])
|
|
503
|
+
|
|
504
|
+
let secrets = secretsOf(client)!.sekreto()!
|
|
505
|
+
XCTAssertEqual("dbpass01", try secrets.get("db.password"))
|
|
506
|
+
XCTAssertEqual("the password is [redacted], keep it safe",
|
|
507
|
+
secrets.redact("the password is dbpass01, keep it safe"))
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// THE PROVIDER VOCABULARY IS NON-EMPTY.
|
|
511
|
+
//
|
|
512
|
+
// The model's choice of plugin groups IS the SDK's provider vocabulary:
|
|
513
|
+
// Config emits the selected definitions and the feature hands them to
|
|
514
|
+
// Sekreto, which refuses at CONSTRUCTION any kind it was not given. A
|
|
515
|
+
// feature that dropped them on the floor would carry every selected plugin
|
|
516
|
+
// FILE and refuse every one of their kinds at runtime, while every test
|
|
517
|
+
// using only built-in kinds stayed green.
|
|
518
|
+
//
|
|
519
|
+
// Conditional on this project selecting a group at all.
|
|
520
|
+
func testASelectedPluginKindIsInTheSdkVocabulary() {
|
|
521
|
+
let plugins = SdkConfig.featurePlugins("secrets")
|
|
522
|
+
if plugins.isEmpty {
|
|
523
|
+
return
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
let w = SecretsWire()
|
|
527
|
+
let client = secretsClient(w, [
|
|
528
|
+
("feature", chainOpts(memorySpec("APIKEY", "VOCAB01"))),
|
|
529
|
+
])
|
|
530
|
+
|
|
531
|
+
let catalog = secretsOf(client)!.sekreto()!.catalog
|
|
532
|
+
for d in plugins {
|
|
533
|
+
guard let def = d as? Definition else {
|
|
534
|
+
return XCTFail("a selected plugin definition is not a Definition: \(d)")
|
|
535
|
+
}
|
|
536
|
+
XCTAssertTrue(catalog.has(def.name),
|
|
537
|
+
"the model selected plugin kind '\(def.name)' but the feature's Sekreto "
|
|
538
|
+
+ "does not know it - the definitions never reached the chain")
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
driveEntityOp(client, w)
|
|
542
|
+
credentialIs(w.api()[0].auth, "VOCAB01")
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
// ===================================================================
|
|
546
|
+
// FAIL CLOSED. sekreto's miss-vs-error invariant: a MISS falls through, an
|
|
547
|
+
// ERROR does not. A broken vault must never degrade into an
|
|
548
|
+
// unauthenticated request.
|
|
549
|
+
|
|
550
|
+
func testAProviderErrorFailsTheEntityOpAndNothingReachesTheWire() {
|
|
551
|
+
// THE RULE, asserted first so a regression reports the leak itself.
|
|
552
|
+
let w = SecretsWire()
|
|
553
|
+
let client = secretsClient(w, [("feature", chainOpts(broken))])
|
|
554
|
+
|
|
555
|
+
// Stop on EITHER outcome - the refusal, or a request going out. Stopping
|
|
556
|
+
// on the first op driven would report an op the API does not define
|
|
557
|
+
// (which fails BEFORE the transport) as the provider's refusal.
|
|
558
|
+
let err = driveEntityOpUntil(client, "refused the operation or sent one") { last in
|
|
559
|
+
0 < w.api().count || messageOf(last).contains("vault unreachable")
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
XCTAssertEqual(0, w.api().count,
|
|
563
|
+
"a request must not go out unauthenticated because a provider broke,"
|
|
564
|
+
+ " but one reached the transport: " + w.wire())
|
|
565
|
+
XCTAssertNotNil(err, "the operation must fail rather than proceed")
|
|
566
|
+
XCTAssertTrue(messageOf(err).contains("vault unreachable"),
|
|
567
|
+
"the failure must carry the PROVIDER'S own message, got: " + messageOf(err))
|
|
568
|
+
|
|
569
|
+
// CONTROL, which makes that zero mean REFUSED rather than UNWIRED: the
|
|
570
|
+
// same construction with a WORKING provider must reach the same
|
|
571
|
+
// transport, once, carrying the credential.
|
|
572
|
+
let control = SecretsWire()
|
|
573
|
+
let ok = secretsClient(control, [("feature", chainOpts(working("RAWKEY01")))])
|
|
574
|
+
driveEntityOp(ok, control)
|
|
575
|
+
|
|
576
|
+
XCTAssertEqual(1, control.api().count,
|
|
577
|
+
"the control operation did not reach system.fetch exactly once, so "
|
|
578
|
+
+ "this test cannot observe a request going out at all: " + control.wire())
|
|
579
|
+
credentialIs(control.api()[0].auth, "RAWKEY01")
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
// THE RAW PATHS, which run NO feature hooks at all. If resolution lived in
|
|
583
|
+
// the PreSpec hook these would send an unauthenticated request and never
|
|
584
|
+
// notice; they are covered because the TRANSPORT is where resolution
|
|
585
|
+
// happens.
|
|
586
|
+
|
|
587
|
+
func testDirectCarriesTheChainCredentialAndFailsClosed() {
|
|
588
|
+
let w = SecretsWire()
|
|
589
|
+
let client = secretsClient(w, [("feature", chainOpts(working("DIRECTKEY01")))])
|
|
590
|
+
|
|
591
|
+
let res = client.direct(vm(("path", .string("/direct-probe"))))
|
|
592
|
+
XCTAssertEqual(.bool(true), res.entries["ok"], "direct refused: " + messageOf(errOf(res)))
|
|
593
|
+
XCTAssertEqual(1, w.api().count, "expected one direct call on the wire: " + w.wire())
|
|
594
|
+
credentialIs(w.api()[0].auth, "DIRECTKEY01")
|
|
595
|
+
|
|
596
|
+
// And fail-closed holds for raw access too: a broken chain refuses the
|
|
597
|
+
// direct call before anything reaches the wire, IN BAND.
|
|
598
|
+
let brokenw = SecretsWire()
|
|
599
|
+
let bclient = secretsClient(brokenw, [("feature", chainOpts(broken))])
|
|
600
|
+
|
|
601
|
+
let bres = bclient.direct(vm(("path", .string("/direct-probe"))))
|
|
602
|
+
XCTAssertEqual(0, brokenw.api().count,
|
|
603
|
+
"a broken chain must not yield a raw request: " + brokenw.wire())
|
|
604
|
+
XCTAssertEqual(.bool(false), bres.entries["ok"], "a broken chain must refuse the raw path")
|
|
605
|
+
XCTAssertTrue(messageOf(errOf(bres)).contains("vault unreachable"),
|
|
606
|
+
"direct must report the PROVIDER'S own refusal, got: " + messageOf(errOf(bres)))
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
func testGraphqlCarriesTheChainCredentialAndFailsClosed() {
|
|
610
|
+
let w = SecretsWire()
|
|
611
|
+
let client = secretsClient(w, [("feature", chainOpts(working("GQLKEY01")))])
|
|
612
|
+
|
|
613
|
+
let res = client.graphql("{ thing }", nil, nil)
|
|
614
|
+
XCTAssertEqual(.bool(true), res.entries["ok"], "graphql refused: " + messageOf(errOf(res)))
|
|
615
|
+
XCTAssertEqual(1, w.api().count, "expected one graphql call on the wire: " + w.wire())
|
|
616
|
+
credentialIs(w.api()[0].auth, "GQLKEY01")
|
|
617
|
+
|
|
618
|
+
let brokenw = SecretsWire()
|
|
619
|
+
let bclient = secretsClient(brokenw, [("feature", chainOpts(broken))])
|
|
620
|
+
|
|
621
|
+
let bres = bclient.graphql("{ thing }", nil, nil)
|
|
622
|
+
XCTAssertEqual(0, brokenw.api().count,
|
|
623
|
+
"a broken chain must not yield a graphql request: " + brokenw.wire())
|
|
624
|
+
XCTAssertEqual(.bool(false), bres.entries["ok"], "a broken chain must refuse graphql")
|
|
625
|
+
XCTAssertTrue(messageOf(errOf(bres)).contains("vault unreachable"),
|
|
626
|
+
"graphql must report the PROVIDER'S own refusal, got: " + messageOf(errOf(bres)))
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
// ===================================================================
|
|
630
|
+
// FAIL CLOSED ON A CONSTRUCTION FAILURE. The chain a project configures
|
|
631
|
+
// can be wrong before a single lookup happens, and initFeature cannot
|
|
632
|
+
// fail the client construction the way ts's throwing init does - so it
|
|
633
|
+
// HOLDS the error (`initerr`) and the transport gate refuses to send.
|
|
634
|
+
//
|
|
635
|
+
// The entry pinned here is one the constructor refuses but init used to
|
|
636
|
+
// never SHOW it: a bare kind name where a spec belongs. A loop over the
|
|
637
|
+
// providers list with arms for a Provider, a ProviderSpec and a map, and
|
|
638
|
+
// no `else`, silently DROPPED the entry - the chain got SHORTER rather
|
|
639
|
+
// than broken, and every request went out unauthenticated while the gate
|
|
640
|
+
// had nothing to refuse. That is fail-open by omission, and it survives
|
|
641
|
+
// every other case in this file because each of them configures the
|
|
642
|
+
// chain correctly.
|
|
643
|
+
//
|
|
644
|
+
// Three cases for the three wire paths - the entity pipeline, direct()
|
|
645
|
+
// and graphql() - each with its own CONTROL leg through the SAME live
|
|
646
|
+
// transport, so a zero means REFUSED and not UNWIRED. The refusal is
|
|
647
|
+
// matched on sekreto's OWN message, so an unrelated failure cannot stand
|
|
648
|
+
// in for it.
|
|
649
|
+
|
|
650
|
+
// A kind NAME where a provider or spec belongs - the natural slip for a
|
|
651
|
+
// reader of the ts docs.
|
|
652
|
+
private let MALFORMED: Value = .string("hashicorp")
|
|
653
|
+
private let NOTAPROVIDER = "not a provider or a provider spec"
|
|
654
|
+
|
|
655
|
+
func testAMalformedProviderEntryFailsTheEntityOpAndNothingReachesTheWire() {
|
|
656
|
+
// CONTROL FIRST, so the zero below is known to be observable at all.
|
|
657
|
+
let control = SecretsWire()
|
|
658
|
+
let ok = secretsClient(control, [("feature", chainOpts(working("INITKEY01")))])
|
|
659
|
+
driveEntityOp(ok, control)
|
|
660
|
+
XCTAssertEqual(1, control.api().count,
|
|
661
|
+
"the control operation did not reach system.fetch exactly once, so "
|
|
662
|
+
+ "this test cannot observe a request going out at all: " + control.wire())
|
|
663
|
+
credentialIs(control.api()[0].auth, "INITKEY01")
|
|
664
|
+
|
|
665
|
+
// THE RULE.
|
|
666
|
+
let w = SecretsWire()
|
|
667
|
+
let client = secretsClient(w, [("feature", chainOpts(MALFORMED))])
|
|
668
|
+
|
|
669
|
+
// The feature must still be INSTALLED: a construction failure that
|
|
670
|
+
// silently uninstalled it would be the same fail-open by another route,
|
|
671
|
+
// with nothing downstream gating anything.
|
|
672
|
+
XCTAssertNotNil(secretsOf(client),
|
|
673
|
+
"the secrets feature must stay installed on a construction failure")
|
|
674
|
+
|
|
675
|
+
let err = driveEntityOpUntil(client, "refused the operation or sent one") { last in
|
|
676
|
+
0 < w.api().count || messageOf(last).contains(NOTAPROVIDER)
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
XCTAssertEqual(0, w.api().count,
|
|
680
|
+
"a malformed providers entry was DROPPED and the shortened chain sent "
|
|
681
|
+
+ "an UNAUTHENTICATED request: " + w.wire())
|
|
682
|
+
XCTAssertNotNil(err, "the entity op must fail when the chain cannot be built")
|
|
683
|
+
XCTAssertTrue(messageOf(err).contains(NOTAPROVIDER),
|
|
684
|
+
"the refusal must carry sekreto's own message (\(NOTAPROVIDER)), got: " + messageOf(err))
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
func testAMalformedProviderEntryFailsDirectRatherThanSending() {
|
|
688
|
+
// CONTROL FIRST.
|
|
689
|
+
let control = SecretsWire()
|
|
690
|
+
let res = secretsClient(control, [("feature", chainOpts(working("INITKEY01")))])
|
|
691
|
+
.direct(vm(("path", .string("/thing"))))
|
|
692
|
+
XCTAssertEqual(.bool(true), res.entries["ok"], "the control request failed: " + messageOf(errOf(res)))
|
|
693
|
+
XCTAssertEqual(1, control.api().count,
|
|
694
|
+
"the control request did not reach system.fetch exactly once, so "
|
|
695
|
+
+ "this test cannot observe a request going out at all: " + control.wire())
|
|
696
|
+
credentialIs(control.api()[0].auth, "INITKEY01")
|
|
697
|
+
|
|
698
|
+
// THE RULE. direct() runs no feature hook at all, so the ONLY thing
|
|
699
|
+
// that can refuse it is the transport gate.
|
|
700
|
+
let w = SecretsWire()
|
|
701
|
+
let out = secretsClient(w, [("feature", chainOpts(MALFORMED))])
|
|
702
|
+
.direct(vm(("path", .string("/thing"))))
|
|
703
|
+
|
|
704
|
+
XCTAssertEqual(0, w.api().count,
|
|
705
|
+
"a malformed providers entry was DROPPED and the shortened chain sent "
|
|
706
|
+
+ "an UNAUTHENTICATED direct request: " + w.wire())
|
|
707
|
+
XCTAssertEqual(.bool(false), out.entries["ok"],
|
|
708
|
+
"a chain that could not be built must refuse the raw path fail-closed")
|
|
709
|
+
XCTAssertTrue(messageOf(errOf(out)).contains(NOTAPROVIDER),
|
|
710
|
+
"the refusal must carry sekreto's own message (\(NOTAPROVIDER)), got: " + messageOf(errOf(out)))
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
func testAMalformedProviderEntryFailsGraphqlRatherThanSending() {
|
|
714
|
+
// CONTROL FIRST.
|
|
715
|
+
let control = SecretsWire()
|
|
716
|
+
let res = secretsClient(control, [("feature", chainOpts(working("INITKEY01")))])
|
|
717
|
+
.graphql("{ thing }", nil, nil)
|
|
718
|
+
XCTAssertEqual(.bool(true), res.entries["ok"], "the control request failed: " + messageOf(errOf(res)))
|
|
719
|
+
XCTAssertEqual(1, control.api().count,
|
|
720
|
+
"the control request did not reach system.fetch exactly once, so "
|
|
721
|
+
+ "this test cannot observe a request going out at all: " + control.wire())
|
|
722
|
+
credentialIs(control.api()[0].auth, "INITKEY01")
|
|
723
|
+
|
|
724
|
+
// THE RULE.
|
|
725
|
+
let w = SecretsWire()
|
|
726
|
+
let out = secretsClient(w, [("feature", chainOpts(MALFORMED))])
|
|
727
|
+
.graphql("{ thing }", nil, nil)
|
|
728
|
+
|
|
729
|
+
XCTAssertEqual(0, w.api().count,
|
|
730
|
+
"a malformed providers entry was DROPPED and the shortened chain sent "
|
|
731
|
+
+ "an UNAUTHENTICATED graphql request: " + w.wire())
|
|
732
|
+
XCTAssertEqual(.bool(false), out.entries["ok"],
|
|
733
|
+
"a chain that could not be built must refuse graphql fail-closed")
|
|
734
|
+
XCTAssertTrue(messageOf(errOf(out)).contains(NOTAPROVIDER),
|
|
735
|
+
"the refusal must carry sekreto's own message (\(NOTAPROVIDER)), got: " + messageOf(errOf(out)))
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
// A chain Sekreto's OWN constructor refuses (an unknown kind). This is
|
|
739
|
+
// the case that pins WRAP FIRST, BUILD SECOND: with the wrap installed
|
|
740
|
+
// after the constructor, a throw there would return before the wrap and
|
|
741
|
+
// the held error would be dead code - a misconfigured chain sending
|
|
742
|
+
// ordinary unauthenticated requests, exactly what java shipped.
|
|
743
|
+
func testAChainTheConstructorRefusesFailsClosed() {
|
|
744
|
+
// CONTROL FIRST.
|
|
745
|
+
let control = SecretsWire()
|
|
746
|
+
let res = secretsClient(control, [("feature", chainOpts(working("INITKEY02")))])
|
|
747
|
+
.direct(vm(("path", .string("/thing"))))
|
|
748
|
+
XCTAssertEqual(.bool(true), res.entries["ok"], "the control request failed: " + messageOf(errOf(res)))
|
|
749
|
+
XCTAssertEqual(1, control.api().count,
|
|
750
|
+
"the control request did not reach system.fetch exactly once: " + control.wire())
|
|
751
|
+
|
|
752
|
+
// THE RULE.
|
|
753
|
+
let w = SecretsWire()
|
|
754
|
+
let client = secretsClient(w, [
|
|
755
|
+
("feature", chainOpts(.map(vm(("kind", .string("nosuchkind")))))),
|
|
756
|
+
])
|
|
757
|
+
XCTAssertNotNil(secretsOf(client), "the feature must stay installed on a construction failure")
|
|
758
|
+
XCTAssertNil(secretsOf(client)!.sekreto(), "a refused chain must not yield a Sekreto")
|
|
759
|
+
|
|
760
|
+
let out = client.direct(vm(("path", .string("/thing"))))
|
|
761
|
+
XCTAssertEqual(0, w.api().count,
|
|
762
|
+
"a chain the constructor refused sent an UNAUTHENTICATED request: " + w.wire())
|
|
763
|
+
XCTAssertEqual(.bool(false), out.entries["ok"], "a refused chain must refuse the raw path")
|
|
764
|
+
XCTAssertTrue(messageOf(errOf(out)).contains("unknown provider kind: nosuchkind"),
|
|
765
|
+
"the refusal must carry sekreto's own message, got: " + messageOf(errOf(out)))
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
func testAProviderRecoversAfterATransientFailure() {
|
|
769
|
+
let countlock = NSLock()
|
|
770
|
+
var calls = 0
|
|
771
|
+
let w = SecretsWire()
|
|
772
|
+
let client = secretsClient(w, [
|
|
773
|
+
("feature", chainOpts(.nat(SecretsProbeProvider("flaky:test") { _ in
|
|
774
|
+
countlock.lock()
|
|
775
|
+
calls += 1
|
|
776
|
+
let n = calls
|
|
777
|
+
countlock.unlock()
|
|
778
|
+
if 1 == n {
|
|
779
|
+
throw SecretsProbeError("vault unreachable")
|
|
780
|
+
}
|
|
781
|
+
return "RECOVERED01"
|
|
782
|
+
}))),
|
|
783
|
+
])
|
|
784
|
+
|
|
785
|
+
// A failed resolution is never cached, so the second op asks the chain
|
|
786
|
+
// again and succeeds. Holding the failure would mean a transient vault
|
|
787
|
+
// outage poisoned the client permanently.
|
|
788
|
+
_ = driveEntityOpUntil(client, "consulted the chain") { _ in 0 < calls }
|
|
789
|
+
XCTAssertEqual(0, w.api().count, "the first op must not reach the wire")
|
|
790
|
+
|
|
791
|
+
driveEntityOp(client, w)
|
|
792
|
+
credentialIs(w.api()[0].auth, "RECOVERED01")
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
func testUncachedMissRetractsTheCredential() {
|
|
796
|
+
let havelock = NSLock()
|
|
797
|
+
var have = true
|
|
798
|
+
let w = SecretsWire()
|
|
799
|
+
let client = secretsClient(w, [
|
|
800
|
+
("feature", chainOpts(.nat(SecretsProbeProvider("revocable:test") { _ in
|
|
801
|
+
havelock.lock()
|
|
802
|
+
defer { havelock.unlock() }
|
|
803
|
+
return have ? "REVOCABLE01" : nil
|
|
804
|
+
}), [("cache", .bool(false))])),
|
|
805
|
+
])
|
|
806
|
+
|
|
807
|
+
driveEntityOp(client, w)
|
|
808
|
+
credentialIs(w.api()[0].auth, "REVOCABLE01")
|
|
809
|
+
|
|
810
|
+
havelock.lock()
|
|
811
|
+
have = false
|
|
812
|
+
havelock.unlock()
|
|
813
|
+
|
|
814
|
+
driveEntityOp(client, w)
|
|
815
|
+
let last = w.api().last!
|
|
816
|
+
XCTAssertFalse(last.hasAuth && "" != last.auth,
|
|
817
|
+
"after the chain reports a miss the retracted credential must not go "
|
|
818
|
+
+ "out; the wire saw \"" + last.auth + "\"")
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
// Concurrent operations share ONE resolution: the first caller asks the
|
|
822
|
+
// chain, the rest wait on it, and every request goes out carrying the
|
|
823
|
+
// credential. A per-request lookup would hit a vault N times for N
|
|
824
|
+
// simultaneous first requests.
|
|
825
|
+
func testConcurrentFirstRequestsShareOneResolution() {
|
|
826
|
+
let countlock = NSLock()
|
|
827
|
+
var lookups = 0
|
|
828
|
+
let w = SecretsWire()
|
|
829
|
+
let client = secretsClient(w, [
|
|
830
|
+
("feature", chainOpts(.nat(SecretsProbeProvider("slow:test") { _ in
|
|
831
|
+
countlock.lock()
|
|
832
|
+
lookups += 1
|
|
833
|
+
countlock.unlock()
|
|
834
|
+
Thread.sleep(forTimeInterval: 0.05)
|
|
835
|
+
return "SHARED01"
|
|
836
|
+
}))),
|
|
837
|
+
])
|
|
838
|
+
|
|
839
|
+
let n = 8
|
|
840
|
+
DispatchQueue.concurrentPerform(iterations: n) { _ in
|
|
841
|
+
_ = client.direct(vm(("path", .string("/shared"))))
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
XCTAssertEqual(n, w.api().count, "every concurrent request must reach the wire: " + w.wire())
|
|
845
|
+
for call in w.api() {
|
|
846
|
+
credentialIs(call.auth, "SHARED01")
|
|
847
|
+
}
|
|
848
|
+
XCTAssertEqual(1, lookups,
|
|
849
|
+
"\(n) concurrent first requests must share ONE resolution, the chain was asked \(lookups) times")
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
// ===================================================================
|
|
853
|
+
// THE EXCHANGE. What the chain resolves is a REFRESH token; the feature
|
|
854
|
+
// buys an ACCESS token from the token endpoint and that is what goes on
|
|
855
|
+
// the wire.
|
|
856
|
+
|
|
857
|
+
private func exchangeOn(_ extra: [(String, Value)] = []) -> (String, Value) {
|
|
858
|
+
let x = VMap()
|
|
859
|
+
x.entries["active"] = .bool(true)
|
|
860
|
+
x.entries["path"] = .string("auth/token")
|
|
861
|
+
for (k, v) in extra {
|
|
862
|
+
x.entries[k] = v
|
|
863
|
+
}
|
|
864
|
+
return ("exchange", .map(x))
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
func testExchangeBuysAnAccessTokenWithTheRefreshToken() {
|
|
868
|
+
let w = SecretsWire()
|
|
869
|
+
let client = secretsClient(w, [
|
|
870
|
+
("feature", chainOpts(working("REFRESH01"), [exchangeOn()])),
|
|
871
|
+
])
|
|
872
|
+
|
|
873
|
+
let res = client.direct(vm(("path", .string("/thing"))))
|
|
874
|
+
XCTAssertEqual(.bool(true), res.entries["ok"], "direct refused: " + messageOf(errOf(res)))
|
|
875
|
+
|
|
876
|
+
// One purchase, at the token endpoint under the base, carrying the
|
|
877
|
+
// refresh token in the configured request field.
|
|
878
|
+
XCTAssertEqual(1, w.token().count, "expected one token purchase: " + w.wire())
|
|
879
|
+
XCTAssertEqual(SecretsFeatureTest.BASE + "/auth/token", w.token()[0].url)
|
|
880
|
+
XCTAssertTrue(w.token()[0].body.contains("\"refresh_token\":\"REFRESH01\""),
|
|
881
|
+
"the purchase must carry the refresh token, got body: " + w.token()[0].body)
|
|
882
|
+
|
|
883
|
+
// And the API request carries the ACCESS token, never the refresh one.
|
|
884
|
+
XCTAssertEqual(1, w.api().count, "expected one API call: " + w.wire())
|
|
885
|
+
credentialIs(w.api()[0].auth, "ACCESS01")
|
|
886
|
+
XCTAssertEqual("ACCESS01", secretsOf(client)!.credential())
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
func testASpentTokenIsReboughtOnceAndTheRetryCarriesTheNewToken() {
|
|
890
|
+
let w = SecretsWire()
|
|
891
|
+
w.apistatus = [401, 200]
|
|
892
|
+
let client = secretsClient(w, [
|
|
893
|
+
("feature", chainOpts(working("REFRESH01"), [exchangeOn()])),
|
|
894
|
+
])
|
|
895
|
+
|
|
896
|
+
let res = client.direct(vm(("path", .string("/thing"))))
|
|
897
|
+
XCTAssertEqual(.bool(true), res.entries["ok"], "direct refused: " + messageOf(errOf(res)))
|
|
898
|
+
|
|
899
|
+
// Two purchases (the first, then the rebuy), two API calls: the refused
|
|
900
|
+
// one with the first token, the retry with the second.
|
|
901
|
+
XCTAssertEqual(2, w.token().count, "expected the spent token to be rebought once: " + w.wire())
|
|
902
|
+
XCTAssertEqual(2, w.api().count, "expected the refused request to be retried once: " + w.wire())
|
|
903
|
+
credentialIs(w.api()[0].auth, "ACCESS01")
|
|
904
|
+
credentialIs(w.api()[1].auth, "ACCESS02")
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
func testAnExplicitApikeyIsTheStartingAccessTokenWhenExchanging() {
|
|
908
|
+
// With the exchange on, `apikey` is an access token the caller already
|
|
909
|
+
// holds: it is SPENT first, and the API decides whether it is stale.
|
|
910
|
+
let w = SecretsWire()
|
|
911
|
+
w.apistatus = [401, 200]
|
|
912
|
+
let client = secretsClient(w, [
|
|
913
|
+
("apikey", .string("STARTACCESS01")),
|
|
914
|
+
("feature", chainOpts(working("REFRESH01"), [exchangeOn()])),
|
|
915
|
+
])
|
|
916
|
+
|
|
917
|
+
let res = client.direct(vm(("path", .string("/thing"))))
|
|
918
|
+
XCTAssertEqual(.bool(true), res.entries["ok"], "direct refused: " + messageOf(errOf(res)))
|
|
919
|
+
|
|
920
|
+
XCTAssertEqual(2, w.api().count, "expected the stale starting token to be retried: " + w.wire())
|
|
921
|
+
credentialIs(w.api()[0].auth, "STARTACCESS01")
|
|
922
|
+
XCTAssertEqual(1, w.token().count, "nothing should be bought until the starting token is refused")
|
|
923
|
+
credentialIs(w.api()[1].auth, "ACCESS01")
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
func testAFailedPurchaseAnswersWithTheApisOwnRefusal() {
|
|
927
|
+
let w = SecretsWire()
|
|
928
|
+
w.apistatus = [401]
|
|
929
|
+
w.tokenok = 1
|
|
930
|
+
let client = secretsClient(w, [
|
|
931
|
+
("feature", chainOpts(working("REFRESH01"), [exchangeOn()])),
|
|
932
|
+
])
|
|
933
|
+
|
|
934
|
+
let res = client.direct(vm(("path", .string("/thing"))))
|
|
935
|
+
// The rebuy failed (500 from the token endpoint), so the API's 401 is
|
|
936
|
+
// the answer - not the exchange error, which is a symptom.
|
|
937
|
+
XCTAssertEqual(.bool(false), res.entries["ok"])
|
|
938
|
+
XCTAssertEqual(.int(401), res.entries["status"], "expected the API's own refusal, got: \(stringify(.map(res)))")
|
|
939
|
+
XCTAssertEqual(2, w.token().count, "expected the first purchase and one failed rebuy: " + w.wire())
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
func testNoRefreshTokenAnywhereFailsClosedWhenExchanging() {
|
|
943
|
+
// CONTROL: the same construction with a refresh token reaches the wire.
|
|
944
|
+
let control = SecretsWire()
|
|
945
|
+
let ok = secretsClient(control, [
|
|
946
|
+
("feature", chainOpts(working("REFRESH01"), [exchangeOn()])),
|
|
947
|
+
]).direct(vm(("path", .string("/thing"))))
|
|
948
|
+
XCTAssertEqual(.bool(true), ok.entries["ok"], "the control request failed: " + messageOf(errOf(ok)))
|
|
949
|
+
XCTAssertEqual(1, control.api().count, "the control request did not reach the wire: " + control.wire())
|
|
950
|
+
|
|
951
|
+
// THE RULE: no refresh token from the chain, no `exchange.refresh`, no
|
|
952
|
+
// starting `apikey` - there is nothing to buy with, so the request is
|
|
953
|
+
// refused with the feature's own message rather than sent bare.
|
|
954
|
+
let w = SecretsWire()
|
|
955
|
+
let out = secretsClient(w, [
|
|
956
|
+
("feature", chainOpts(.nat(SecretsProbeProvider("empty:test") { _ in nil }), [exchangeOn()])),
|
|
957
|
+
]).direct(vm(("path", .string("/thing"))))
|
|
958
|
+
|
|
959
|
+
XCTAssertEqual(0, w.api().count, "a request went out with nothing to authenticate it: " + w.wire())
|
|
960
|
+
XCTAssertEqual(.bool(false), out.entries["ok"])
|
|
961
|
+
XCTAssertTrue(messageOf(errOf(out)).contains("no refresh token"),
|
|
962
|
+
"expected the feature's own refusal, got: " + messageOf(errOf(out)))
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
func testExchangeDoesNotRetryADeliberatelyUnauthenticatedRefusal() {
|
|
966
|
+
// `auth: null` sends NO credential; a 401 on such a request is not an
|
|
967
|
+
// expired token and buying one would transmit exactly what the caller
|
|
968
|
+
// suppressed.
|
|
969
|
+
let w = SecretsWire()
|
|
970
|
+
w.apistatus = [401]
|
|
971
|
+
let client = secretsClient(w, [
|
|
972
|
+
("auth", .null),
|
|
973
|
+
("feature", chainOpts(working("REFRESH01"), [exchangeOn()])),
|
|
974
|
+
])
|
|
975
|
+
|
|
976
|
+
let res = client.direct(vm(("path", .string("/thing"))))
|
|
977
|
+
XCTAssertEqual(.bool(false), res.entries["ok"])
|
|
978
|
+
XCTAssertEqual(1, w.api().count, "a suppressed-auth 401 must not be retried: " + w.wire())
|
|
979
|
+
XCTAssertFalse(w.api()[0].hasAuth, "auth null must keep the header off, got: " + w.api()[0].auth)
|
|
980
|
+
// Resolution still ran once (the chain was consulted and the access
|
|
981
|
+
// token bought, as go's resolveonce does whatever `auth` says); what
|
|
982
|
+
// the suppression forbids is the REBUY after the refusal.
|
|
983
|
+
XCTAssertEqual(1, w.token().count,
|
|
984
|
+
"a suppressed-auth 401 must not buy another token: " + w.wire())
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
func testExchangeInTestModeBuysNothing() {
|
|
988
|
+
// The test feature replaces the transport; a purchase would be the one
|
|
989
|
+
// HTTP call it could not stop. A deterministic fake token instead.
|
|
990
|
+
let fopts = VMap()
|
|
991
|
+
fopts.entries["active"] = .bool(true)
|
|
992
|
+
fopts.entries["providers"] = .list([working("REFRESH01")])
|
|
993
|
+
fopts.entries["exchange"] = exchangeOn().1
|
|
994
|
+
let opts = VMap()
|
|
995
|
+
opts.entries["base"] = .string(SecretsFeatureTest.BASE)
|
|
996
|
+
opts.entries["allow"] = .map(vm(("op", .string("direct,graphql"))))
|
|
997
|
+
opts.entries["feature"] = .map(vm(("secrets", .map(fopts))))
|
|
998
|
+
|
|
999
|
+
let client = withSecrets { extend in
|
|
1000
|
+
let use = clone(.map(opts)).asMap ?? VMap()
|
|
1001
|
+
if extend {
|
|
1002
|
+
use.entries["extend"] = .list([.nat(SecretsFeature())])
|
|
1003
|
+
}
|
|
1004
|
+
return ProjectNameSDK.testSDK(nil, use)
|
|
1005
|
+
}
|
|
1006
|
+
XCTAssertEqual("test", client.mode)
|
|
1007
|
+
|
|
1008
|
+
_ = client.direct(vm(("path", .string("/thing"))))
|
|
1009
|
+
XCTAssertEqual("test-access_token", secretsOf(client)!.credential(),
|
|
1010
|
+
"test mode must answer with the deterministic fake token")
|
|
1011
|
+
}
|
|
1012
|
+
|
|
1013
|
+
func testTheExchangeBodyIsJsonEncoded() throws {
|
|
1014
|
+
// A refresh token carrying a quote, a backslash and a newline must
|
|
1015
|
+
// arrive as that literal value: the body is ENCODED, never concatenated.
|
|
1016
|
+
let nasty = "re\"fresh\\to\nken"
|
|
1017
|
+
let w = SecretsWire()
|
|
1018
|
+
let client = secretsClient(w, [
|
|
1019
|
+
("feature", chainOpts(working(nasty), [exchangeOn()])),
|
|
1020
|
+
])
|
|
1021
|
+
|
|
1022
|
+
let res = client.direct(vm(("path", .string("/thing"))))
|
|
1023
|
+
XCTAssertEqual(.bool(true), res.entries["ok"], "direct refused: " + messageOf(errOf(res)))
|
|
1024
|
+
XCTAssertEqual(1, w.token().count, "expected one purchase: " + w.wire())
|
|
1025
|
+
|
|
1026
|
+
let body = try JSON.parse(w.token()[0].body)
|
|
1027
|
+
XCTAssertEqual(nasty, gp(body, "refresh_token").asString,
|
|
1028
|
+
"the refresh token did not survive the body encoding: " + w.token()[0].body)
|
|
1029
|
+
}
|
|
1030
|
+
}
|