@voxgig/sdkgen-langpack 0.0.1
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/.sdk/model/target/dart.aon +63 -0
- package/.sdk/model/target/haskell.aon +72 -0
- package/.sdk/model/target/lean.aon +91 -0
- package/.sdk/src/cmp/dart/Config_dart.ts +248 -0
- package/.sdk/src/cmp/dart/EntityBase_dart.ts +34 -0
- package/.sdk/src/cmp/dart/EntityOperation_dart.ts +43 -0
- package/.sdk/src/cmp/dart/EntityTypes_dart.ts +207 -0
- package/.sdk/src/cmp/dart/Entity_dart.ts +87 -0
- package/.sdk/src/cmp/dart/Gitignore_dart.ts +34 -0
- package/.sdk/src/cmp/dart/MainEntity_dart.ts +33 -0
- package/.sdk/src/cmp/dart/Main_dart.ts +178 -0
- package/.sdk/src/cmp/dart/Package_dart.ts +82 -0
- package/.sdk/src/cmp/dart/ReadmeEntity_dart.ts +177 -0
- package/.sdk/src/cmp/dart/ReadmeExamplesTest_dart.ts +238 -0
- package/.sdk/src/cmp/dart/ReadmeExplanation_dart.ts +53 -0
- package/.sdk/src/cmp/dart/ReadmeHowto_dart.ts +152 -0
- package/.sdk/src/cmp/dart/ReadmeInstall_dart.ts +59 -0
- package/.sdk/src/cmp/dart/ReadmeIntro_dart.ts +65 -0
- package/.sdk/src/cmp/dart/ReadmeModel_dart.ts +151 -0
- package/.sdk/src/cmp/dart/ReadmeOptions_dart.ts +63 -0
- package/.sdk/src/cmp/dart/ReadmeQuick_dart.ts +225 -0
- package/.sdk/src/cmp/dart/ReadmeRef_dart.ts +397 -0
- package/.sdk/src/cmp/dart/ReadmeTopHowto_dart.ts +24 -0
- package/.sdk/src/cmp/dart/ReadmeTopQuick_dart.ts +106 -0
- package/.sdk/src/cmp/dart/ReadmeTopTest_dart.ts +78 -0
- package/.sdk/src/cmp/dart/SdkError_dart.ts +42 -0
- package/.sdk/src/cmp/dart/TestDirect_dart.ts +516 -0
- package/.sdk/src/cmp/dart/TestEntity_dart.ts +628 -0
- package/.sdk/src/cmp/dart/Test_dart.ts +138 -0
- package/.sdk/src/cmp/dart/fragment/Config.data.fragment.dart +98 -0
- package/.sdk/src/cmp/dart/fragment/Config.fragment.dart +70 -0
- package/.sdk/src/cmp/dart/fragment/Direct.test.fragment.dart +25 -0
- package/.sdk/src/cmp/dart/fragment/Entity.fragment.dart +29 -0
- package/.sdk/src/cmp/dart/fragment/Entity.test.fragment.dart +28 -0
- package/.sdk/src/cmp/dart/fragment/EntityBase.fragment.dart +302 -0
- package/.sdk/src/cmp/dart/fragment/EntityCreateOp.fragment.dart +98 -0
- package/.sdk/src/cmp/dart/fragment/EntityListOp.fragment.dart +90 -0
- package/.sdk/src/cmp/dart/fragment/EntityLoadOp.fragment.dart +102 -0
- package/.sdk/src/cmp/dart/fragment/EntityRemoveOp.fragment.dart +108 -0
- package/.sdk/src/cmp/dart/fragment/EntityUpdateOp.fragment.dart +102 -0
- package/.sdk/src/cmp/dart/fragment/Main.fragment.dart +339 -0
- package/.sdk/src/cmp/dart/fragment/SdkError.fragment.dart +26 -0
- package/.sdk/src/cmp/dart/tsconfig.json +15 -0
- package/.sdk/src/cmp/dart/utility_dart.ts +155 -0
- package/.sdk/src/cmp/haskell/Config_haskell.ts +98 -0
- package/.sdk/src/cmp/haskell/Entity_haskell.ts +13 -0
- package/.sdk/src/cmp/haskell/Gitignore_haskell.ts +27 -0
- package/.sdk/src/cmp/haskell/Main_haskell.ts +123 -0
- package/.sdk/src/cmp/haskell/Package_haskell.ts +60 -0
- package/.sdk/src/cmp/haskell/ReadmeEntity_haskell.ts +186 -0
- package/.sdk/src/cmp/haskell/ReadmeExamplesTest_haskell.ts +135 -0
- package/.sdk/src/cmp/haskell/ReadmeExplanation_haskell.ts +48 -0
- package/.sdk/src/cmp/haskell/ReadmeHowto_haskell.ts +168 -0
- package/.sdk/src/cmp/haskell/ReadmeInstall_haskell.ts +51 -0
- package/.sdk/src/cmp/haskell/ReadmeIntro_haskell.ts +67 -0
- package/.sdk/src/cmp/haskell/ReadmeModel_haskell.ts +162 -0
- package/.sdk/src/cmp/haskell/ReadmeOptions_haskell.ts +74 -0
- package/.sdk/src/cmp/haskell/ReadmeQuick_haskell.ts +241 -0
- package/.sdk/src/cmp/haskell/ReadmeRef_haskell.ts +408 -0
- package/.sdk/src/cmp/haskell/ReadmeTopHowto_haskell.ts +31 -0
- package/.sdk/src/cmp/haskell/ReadmeTopQuick_haskell.ts +104 -0
- package/.sdk/src/cmp/haskell/ReadmeTopTest_haskell.ts +80 -0
- package/.sdk/src/cmp/haskell/Test_haskell.ts +297 -0
- package/.sdk/src/cmp/haskell/tsconfig.json +15 -0
- package/.sdk/src/cmp/haskell/utility_haskell.ts +166 -0
- package/.sdk/src/cmp/lean/Config_lean.ts +93 -0
- package/.sdk/src/cmp/lean/Entity_lean.ts +9 -0
- package/.sdk/src/cmp/lean/Gitignore_lean.ts +18 -0
- package/.sdk/src/cmp/lean/Main_lean.ts +120 -0
- package/.sdk/src/cmp/lean/Package_lean.ts +93 -0
- package/.sdk/src/cmp/lean/ReadmeEntity_lean.ts +29 -0
- package/.sdk/src/cmp/lean/ReadmeExplanation_lean.ts +19 -0
- package/.sdk/src/cmp/lean/ReadmeHowto_lean.ts +25 -0
- package/.sdk/src/cmp/lean/ReadmeInstall_lean.ts +39 -0
- package/.sdk/src/cmp/lean/ReadmeIntro_lean.ts +25 -0
- package/.sdk/src/cmp/lean/ReadmeModel_lean.ts +24 -0
- package/.sdk/src/cmp/lean/ReadmeOptions_lean.ts +22 -0
- package/.sdk/src/cmp/lean/ReadmeQuick_lean.ts +50 -0
- package/.sdk/src/cmp/lean/ReadmeRef_lean.ts +40 -0
- package/.sdk/src/cmp/lean/ReadmeTopHowto_lean.ts +16 -0
- package/.sdk/src/cmp/lean/ReadmeTopQuick_lean.ts +23 -0
- package/.sdk/src/cmp/lean/ReadmeTopTest_lean.ts +19 -0
- package/.sdk/src/cmp/lean/Test_lean.ts +261 -0
- package/.sdk/src/cmp/lean/utility_lean.ts +129 -0
- package/.sdk/tm/dart/LICENSE +22 -0
- package/.sdk/tm/dart/Makefile +50 -0
- package/.sdk/tm/dart/lib/Context.dart +150 -0
- package/.sdk/tm/dart/lib/Control.dart +15 -0
- package/.sdk/tm/dart/lib/Operation.dart +31 -0
- package/.sdk/tm/dart/lib/Point.dart +51 -0
- package/.sdk/tm/dart/lib/Response.dart +32 -0
- package/.sdk/tm/dart/lib/Result.dart +39 -0
- package/.sdk/tm/dart/lib/Spec.dart +49 -0
- package/.sdk/tm/dart/lib/feature/audit/AuditFeature.dart +103 -0
- package/.sdk/tm/dart/lib/feature/base/BaseFeature.dart +76 -0
- package/.sdk/tm/dart/lib/feature/cache/CacheFeature.dart +152 -0
- package/.sdk/tm/dart/lib/feature/clienttrack/ClienttrackFeature.dart +104 -0
- package/.sdk/tm/dart/lib/feature/cost/CostFeature.dart +446 -0
- package/.sdk/tm/dart/lib/feature/debug/DebugFeature.dart +153 -0
- package/.sdk/tm/dart/lib/feature/idempotency/IdempotencyFeature.dart +92 -0
- package/.sdk/tm/dart/lib/feature/log/LogFeature.dart +85 -0
- package/.sdk/tm/dart/lib/feature/metrics/MetricsFeature.dart +103 -0
- package/.sdk/tm/dart/lib/feature/netsim/NetsimFeature.dart +186 -0
- package/.sdk/tm/dart/lib/feature/paging/PagingFeature.dart +240 -0
- package/.sdk/tm/dart/lib/feature/proxy/ProxyFeature.dart +118 -0
- package/.sdk/tm/dart/lib/feature/ratelimit/RatelimitFeature.dart +103 -0
- package/.sdk/tm/dart/lib/feature/rbac/RbacFeature.dart +121 -0
- package/.sdk/tm/dart/lib/feature/retry/RetryFeature.dart +155 -0
- package/.sdk/tm/dart/lib/feature/secrets/SecretsFeature.dart +649 -0
- package/.sdk/tm/dart/lib/feature/secrets/plugin/capability.dart +105 -0
- package/.sdk/tm/dart/lib/feature/secrets/plugin/catalog.dart +46 -0
- package/.sdk/tm/dart/lib/feature/secrets/plugin/config.dart +297 -0
- package/.sdk/tm/dart/lib/feature/secrets/plugin/depend.dart +198 -0
- package/.sdk/tm/dart/lib/feature/secrets/plugin/env.dart +144 -0
- package/.sdk/tm/dart/lib/feature/secrets/plugin/export.dart +58 -0
- package/.sdk/tm/dart/lib/feature/secrets/plugin/graph.dart +160 -0
- package/.sdk/tm/dart/lib/feature/secrets/plugin/host.dart +1067 -0
- package/.sdk/tm/dart/lib/feature/secrets/plugin/order.dart +172 -0
- package/.sdk/tm/dart/lib/feature/secrets/plugin/plugin.dart +23 -0
- package/.sdk/tm/dart/lib/feature/secrets/plugin/point.dart +117 -0
- package/.sdk/tm/dart/lib/feature/secrets/plugin/ref.dart +105 -0
- package/.sdk/tm/dart/lib/feature/secrets/plugin/resolve.dart +58 -0
- package/.sdk/tm/dart/lib/feature/secrets/plugin/types.dart +201 -0
- package/.sdk/tm/dart/lib/feature/secrets/plugin/version.dart +116 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/aws.dart +285 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/azuresecrets.dart +178 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/boru.dart +145 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/crypto.dart +194 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/doppler.dart +101 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/gcpsecrets.dart +143 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/hashicorp.dart +190 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/httpjson.dart +363 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/infisical.dart +149 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/onepassword.dart +146 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/secretspec.dart +116 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/plugins/sigv4.dart +237 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/addr.dart +138 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/json.dart +276 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/provider.dart +31 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/providers.dart +243 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/sekreto.dart +730 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/spec.dart +200 -0
- package/.sdk/tm/dart/lib/feature/secrets/sekreto/src/support.dart +217 -0
- package/.sdk/tm/dart/lib/feature/streaming/StreamingFeature.dart +97 -0
- package/.sdk/tm/dart/lib/feature/telemetry/TelemetryFeature.dart +136 -0
- package/.sdk/tm/dart/lib/feature/test/TestFeature.dart +328 -0
- package/.sdk/tm/dart/lib/feature/timeout/TimeoutFeature.dart +104 -0
- package/.sdk/tm/dart/lib/utility/CleanUtility.dart +12 -0
- package/.sdk/tm/dart/lib/utility/DoneUtility.dart +18 -0
- package/.sdk/tm/dart/lib/utility/ErrUtility.dart +46 -0
- package/.sdk/tm/dart/lib/utility/FeatureAddUtility.dart +35 -0
- package/.sdk/tm/dart/lib/utility/FeatureHookUtility.dart +20 -0
- package/.sdk/tm/dart/lib/utility/FeatureInitUtility.dart +9 -0
- package/.sdk/tm/dart/lib/utility/FetcherUtility.dart +104 -0
- package/.sdk/tm/dart/lib/utility/GraphqlUtility.dart +162 -0
- package/.sdk/tm/dart/lib/utility/MakeContextUtility.dart +6 -0
- package/.sdk/tm/dart/lib/utility/MakeErrorUtility.dart +71 -0
- package/.sdk/tm/dart/lib/utility/MakeFetchDefUtility.dart +42 -0
- package/.sdk/tm/dart/lib/utility/MakeOptionsUtility.dart +233 -0
- package/.sdk/tm/dart/lib/utility/MakePointUtility.dart +130 -0
- package/.sdk/tm/dart/lib/utility/MakeRequestUtility.dart +66 -0
- package/.sdk/tm/dart/lib/utility/MakeResponseUtility.dart +59 -0
- package/.sdk/tm/dart/lib/utility/MakeResultUtility.dart +49 -0
- package/.sdk/tm/dart/lib/utility/MakeSpecUtility.dart +77 -0
- package/.sdk/tm/dart/lib/utility/MakeUrlUtility.dart +51 -0
- package/.sdk/tm/dart/lib/utility/ParamUtility.dart +56 -0
- package/.sdk/tm/dart/lib/utility/PrepareAuthUtility.dart +46 -0
- package/.sdk/tm/dart/lib/utility/PrepareBodyUtility.dart +19 -0
- package/.sdk/tm/dart/lib/utility/PrepareHeadersUtility.dart +11 -0
- package/.sdk/tm/dart/lib/utility/PrepareMethodUtility.dart +30 -0
- package/.sdk/tm/dart/lib/utility/PrepareParamsUtility.dart +23 -0
- package/.sdk/tm/dart/lib/utility/PreparePathUtility.dart +9 -0
- package/.sdk/tm/dart/lib/utility/PrepareQueryUtility.dart +18 -0
- package/.sdk/tm/dart/lib/utility/ResultBasicUtility.dart +29 -0
- package/.sdk/tm/dart/lib/utility/ResultBodyUtility.dart +15 -0
- package/.sdk/tm/dart/lib/utility/ResultHeadersUtility.dart +18 -0
- package/.sdk/tm/dart/lib/utility/StructUtility.dart +127 -0
- package/.sdk/tm/dart/lib/utility/TransformRequestUtility.dart +28 -0
- package/.sdk/tm/dart/lib/utility/TransformResponseUtility.dart +44 -0
- package/.sdk/tm/dart/lib/utility/Utility.dart +239 -0
- package/.sdk/tm/dart/lib/utility/voxgig_struct.dart +2462 -0
- package/.sdk/tm/dart/src/feature/README.md +3 -0
- package/.sdk/tm/dart/src/feature/audit/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/base/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/cache/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/clienttrack/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/cost/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/debug/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/idempotency/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/log/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/metrics/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/netsim/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/paging/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/proxy/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/ratelimit/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/rbac/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/retry/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/secrets/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/streaming/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/telemetry/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/test/.gitkeep +0 -0
- package/.sdk/tm/dart/src/feature/timeout/.gitkeep +0 -0
- package/.sdk/tm/dart/test/custom_test.dart +65 -0
- package/.sdk/tm/dart/test/exists_test.dart +12 -0
- package/.sdk/tm/dart/test/feature/harness.dart +347 -0
- package/.sdk/tm/dart/test/feature/secrets/secrets_test.dart +1107 -0
- package/.sdk/tm/dart/test/feature_test.dart +1193 -0
- package/.sdk/tm/dart/test/harness.dart +153 -0
- package/.sdk/tm/dart/test/netsim_test.dart +48 -0
- package/.sdk/tm/dart/test/omni.dart +520 -0
- package/.sdk/tm/dart/test/omni_smoke_test.dart +143 -0
- package/.sdk/tm/dart/test/pipeline_test.dart +608 -0
- package/.sdk/tm/dart/test/primary_test.dart +476 -0
- package/.sdk/tm/dart/test/sdk-test-control.json +19 -0
- package/.sdk/tm/dart/test/struct_test.dart +468 -0
- package/.sdk/tm/dart/test/utility.dart +198 -0
- package/.sdk/tm/dart/test/vendor/omni/omni.dart +7 -0
- package/.sdk/tm/dart/test/vendor/omni/runner.dart +653 -0
- package/.sdk/tm/dart/test/vendor/omni/util.dart +232 -0
- package/.sdk/tm/haskell/LICENSE +21 -0
- package/.sdk/tm/haskell/Makefile +22 -0
- package/.sdk/tm/haskell/VERSION +1 -0
- package/.sdk/tm/haskell/src/SdkFeatures.hs +1440 -0
- package/.sdk/tm/haskell/src/SdkHelpers.hs +337 -0
- package/.sdk/tm/haskell/src/SdkJson.hs +111 -0
- package/.sdk/tm/haskell/src/SdkRuntime.hs +1279 -0
- package/.sdk/tm/haskell/src/SdkTypes.hs +195 -0
- package/.sdk/tm/haskell/src/VoxgigStruct.hs +2299 -0
- package/.sdk/tm/haskell/src/Vregex.hs +237 -0
- package/.sdk/tm/haskell/src/feature/README.md +5 -0
- package/.sdk/tm/haskell/src/feature/audit/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/base/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/cache/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/clienttrack/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/debug/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/idempotency/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/log/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/metrics/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/netsim/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/paging/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/proxy/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/ratelimit/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/rbac/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/retry/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/streaming/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/telemetry/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/test/.gitkeep +0 -0
- package/.sdk/tm/haskell/src/feature/timeout/.gitkeep +0 -0
- package/.sdk/tm/haskell/test/Harness.hs +281 -0
- package/.sdk/tm/haskell/test/OmniResolver.hs +252 -0
- package/.sdk/tm/haskell/test/Runner.hs +49 -0
- package/.sdk/tm/haskell/test/StructCorpus.hs +449 -0
- package/.sdk/tm/haskell/test/TCustomUtility.hs +38 -0
- package/.sdk/tm/haskell/test/TFeature.hs +794 -0
- package/.sdk/tm/haskell/test/TNetsim.hs +50 -0
- package/.sdk/tm/haskell/test/TPipeline.hs +334 -0
- package/.sdk/tm/haskell/test/TPrimaryCorpus.hs +263 -0
- package/.sdk/tm/haskell/test/TPrimaryUtility.hs +386 -0
- package/.sdk/tm/haskell/test/Testutil.hs +59 -0
- package/.sdk/tm/haskell/test/vendor/omni/Omni.hs +1147 -0
- package/.sdk/tm/lean/LICENSE +21 -0
- package/.sdk/tm/lean/Makefile +32 -0
- package/.sdk/tm/lean/VERSION +1 -0
- package/.sdk/tm/lean/src/SdkFeature.lean +171 -0
- package/.sdk/tm/lean/src/SdkFeatures.lean +787 -0
- package/.sdk/tm/lean/src/SdkJson.lean +134 -0
- package/.sdk/tm/lean/src/SdkRuntime.lean +374 -0
- package/.sdk/tm/lean/src/SdkUtility.lean +809 -0
- package/.sdk/tm/lean/src/VoxgigStruct.lean +2880 -0
- package/.sdk/tm/lean/src/Vregex.lean +412 -0
- package/.sdk/tm/lean/src/feature/README.md +5 -0
- package/.sdk/tm/lean/src/feature/audit/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/base/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/cache/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/clienttrack/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/cost/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/debug/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/idempotency/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/log/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/metrics/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/netsim/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/paging/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/proxy/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/ratelimit/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/rbac/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/retry/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/streaming/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/telemetry/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/test/.gitkeep +0 -0
- package/.sdk/tm/lean/src/feature/timeout/.gitkeep +0 -0
- package/.sdk/tm/lean/test/OmniResolver.lean +358 -0
- package/.sdk/tm/lean/test/OmniSmoke.lean +174 -0
- package/.sdk/tm/lean/test/StructCorpus.lean +368 -0
- package/.sdk/tm/lean/test/TFeature.lean +281 -0
- package/.sdk/tm/lean/test/TPrimaryUtility.lean +227 -0
- package/.sdk/tm/lean/test/vendor/omni/Omni.lean +997 -0
- package/LICENSE +21 -0
- package/README.md +104 -0
- package/package.json +78 -0
- package/sdkgen-package.json +22 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
// VENDORED: @voxgig/sekreto sdk-20260908-1556-0 (dart/plugins/hashicorp.dart)
|
|
2
|
+
// Source: https://github.com/voxgig/sekreto @ 1267ee2e5f49566bc92695bc9eb3a60ef4924998 [tag: sdk-20260908-1556-0]
|
|
3
|
+
// License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
|
|
4
|
+
// HashiCorp Vault, as a voxgig/plugin definition.
|
|
5
|
+
//
|
|
6
|
+
// A PLUGIN, not a built-in: it opens a socket. A `Sekreto` can build the
|
|
7
|
+
// `hashicorp` kind only if the calling project imported this file and passed
|
|
8
|
+
// `hashicorp` in the `plugins` option (docs/design/plugin-providers.md).
|
|
9
|
+
//
|
|
10
|
+
// A port of typescript/plugins/hashicorp.ts, which is canonical.
|
|
11
|
+
|
|
12
|
+
import 'dart:async';
|
|
13
|
+
import 'dart:io';
|
|
14
|
+
|
|
15
|
+
import '../src/addr.dart';
|
|
16
|
+
import '../src/json.dart';
|
|
17
|
+
import '../src/provider.dart';
|
|
18
|
+
import '../src/sekreto.dart';
|
|
19
|
+
import '../src/spec.dart';
|
|
20
|
+
import '../src/support.dart';
|
|
21
|
+
|
|
22
|
+
import 'httpjson.dart';
|
|
23
|
+
|
|
24
|
+
/// HashiCorp Vault.
|
|
25
|
+
///
|
|
26
|
+
/// KV v2 (the default): `api.token` reads `{addr}/v1/{mount}/data/api` and
|
|
27
|
+
/// takes the `token` field of `data.data`. KV v1 (`kv: 1`) reads
|
|
28
|
+
/// `{addr}/v1/{mount}/api` and takes the field of `data`. A 404 means "not
|
|
29
|
+
/// here" - a miss - so a vault can sit in a chain with fallbacks.
|
|
30
|
+
///
|
|
31
|
+
/// A Vault Enterprise namespace rides the X-Vault-Namespace header, on
|
|
32
|
+
/// logins as well as reads.
|
|
33
|
+
///
|
|
34
|
+
/// Instead of being handed a token, the provider can log in: Kubernetes auth
|
|
35
|
+
/// (the pod's service-account JWT, from its conventional path) or AppRole. A
|
|
36
|
+
/// failed login is an error, never a miss - it means this store could not
|
|
37
|
+
/// answer at all.
|
|
38
|
+
class Hashicorp extends Provider {
|
|
39
|
+
final String addr;
|
|
40
|
+
final String mount;
|
|
41
|
+
final int kv;
|
|
42
|
+
final String? vaultnamespace;
|
|
43
|
+
final AuthSpec? auth;
|
|
44
|
+
|
|
45
|
+
// The working token: a configured token is kept forever, a logged-in token
|
|
46
|
+
// is renewed shortly before its lease runs out - a long-running process
|
|
47
|
+
// must not keep presenting a token the vault already expired.
|
|
48
|
+
String? _livetoken;
|
|
49
|
+
int _renewat = NEVER;
|
|
50
|
+
|
|
51
|
+
Hashicorp(
|
|
52
|
+
this.addr, {
|
|
53
|
+
String? token,
|
|
54
|
+
String? mount,
|
|
55
|
+
int? kv,
|
|
56
|
+
this.vaultnamespace,
|
|
57
|
+
this.auth,
|
|
58
|
+
}) : mount = (null == mount || mount.isEmpty) ? 'secret' : mount,
|
|
59
|
+
kv = kv ?? 2,
|
|
60
|
+
_livetoken = (null == token || token.isEmpty) ? null : token {
|
|
61
|
+
// A version typo like kv: 3 must not quietly behave as v2 and turn its
|
|
62
|
+
// 404s into misses; there is nothing safe to assume it meant.
|
|
63
|
+
if (1 != this.kv && 2 != this.kv) {
|
|
64
|
+
throw SekretoError('sekreto: hashicorp: unsupported kv version: ${this.kv}');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
Map<String, String> _baseheaders() {
|
|
69
|
+
if (null != vaultnamespace && vaultnamespace!.isNotEmpty) {
|
|
70
|
+
return {'X-Vault-Namespace': vaultnamespace!};
|
|
71
|
+
}
|
|
72
|
+
return {};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
Future<String> _login() async {
|
|
76
|
+
final use = auth;
|
|
77
|
+
if (null == use) {
|
|
78
|
+
throw SekretoError('sekreto: hashicorp: no token and no auth method');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
final authmount = first([use.mount, use.method]);
|
|
82
|
+
final url = '${trimslash(addr)}/v1/auth/$authmount/login';
|
|
83
|
+
|
|
84
|
+
final Json body;
|
|
85
|
+
|
|
86
|
+
switch (use.method) {
|
|
87
|
+
case 'kubernetes':
|
|
88
|
+
String jwt;
|
|
89
|
+
final given = use.jwt;
|
|
90
|
+
|
|
91
|
+
if (null != given) {
|
|
92
|
+
jwt = given;
|
|
93
|
+
} else {
|
|
94
|
+
final file = use.jwtfile ??
|
|
95
|
+
'/var/run/secrets/kubernetes.io/serviceaccount/token';
|
|
96
|
+
try {
|
|
97
|
+
jwt = File(file).readAsStringSync().trim();
|
|
98
|
+
} on FileSystemException {
|
|
99
|
+
throw SekretoError(
|
|
100
|
+
'sekreto: hashicorp: cannot read jwt file $file',
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
body = JsonObj({
|
|
106
|
+
'role': JsonStr(use.role ?? ''),
|
|
107
|
+
'jwt': JsonStr(jwt),
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
case 'approle':
|
|
111
|
+
body = JsonObj({
|
|
112
|
+
'role_id': JsonStr(use.roleid ?? ''),
|
|
113
|
+
'secret_id': JsonStr(use.secretid ?? ''),
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
default:
|
|
117
|
+
throw SekretoError(
|
|
118
|
+
'sekreto: hashicorp: unknown auth method: ${use.method}',
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
final res = await fetchjson(
|
|
123
|
+
'POST',
|
|
124
|
+
url,
|
|
125
|
+
headers: _baseheaders(),
|
|
126
|
+
body: jsonstringify(body),
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
final got = res.body.dig('auth', 'client_token').text;
|
|
130
|
+
if (200 != res.status || null == got || got.isEmpty) {
|
|
131
|
+
throw SekretoError('sekreto: hashicorp login failed: ${res.status}: $url');
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
_renewat = renewtime(res.body.dig('auth', 'lease_duration'));
|
|
135
|
+
|
|
136
|
+
return got;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
@override
|
|
140
|
+
FutureOr<String?> lookup(String name) {
|
|
141
|
+
// Refused before anything is dialled, and synchronously, so a misspelled
|
|
142
|
+
// address is a configuration error rather than a network one.
|
|
143
|
+
checkaddr(addr);
|
|
144
|
+
return _read(name);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
Future<String?> _read(String name) async {
|
|
148
|
+
if (null == _livetoken || DateTime.now().millisecondsSinceEpoch >= _renewat) {
|
|
149
|
+
_livetoken = await _login();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
final ref = vaultref(name);
|
|
153
|
+
final base = '${trimslash(addr)}/v1/$mount';
|
|
154
|
+
final url = 1 == kv ? '$base/${ref.path}' : '$base/data/${ref.path}';
|
|
155
|
+
|
|
156
|
+
final headers = _baseheaders();
|
|
157
|
+
headers['X-Vault-Token'] = _livetoken ?? '';
|
|
158
|
+
|
|
159
|
+
final res = await fetchjson('GET', url, headers: headers);
|
|
160
|
+
|
|
161
|
+
if (404 == res.status) {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
if (200 != res.status) {
|
|
165
|
+
throw SekretoError('sekreto: hashicorp error: ${res.status}: $url');
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
final data =
|
|
169
|
+
1 == kv ? res.body.dig('data') : res.body.dig('data', 'data');
|
|
170
|
+
|
|
171
|
+
return data.dig(ref.field).text;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
@override
|
|
175
|
+
String describe() => 'hashicorp:$addr/$mount';
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/// The `hashicorp` provider kind. Pass it in `plugins` to name it in a
|
|
179
|
+
/// chain: `sekreto(chain, plugins: [hashicorp])`.
|
|
180
|
+
final Definition hashicorp = providerplugin(
|
|
181
|
+
'hashicorp',
|
|
182
|
+
(spec) => Hashicorp(
|
|
183
|
+
spec.addr ?? '',
|
|
184
|
+
token: spec.token,
|
|
185
|
+
mount: spec.mount,
|
|
186
|
+
kv: spec.kv,
|
|
187
|
+
vaultnamespace: spec.vaultnamespace,
|
|
188
|
+
auth: spec.auth,
|
|
189
|
+
),
|
|
190
|
+
);
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
// VENDORED: @voxgig/sekreto sdk-20260908-1556-0 (dart/plugins/httpjson.dart)
|
|
2
|
+
// Source: https://github.com/voxgig/sekreto @ 1267ee2e5f49566bc92695bc9eb3a60ef4924998 [tag: sdk-20260908-1556-0]
|
|
3
|
+
// License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
|
|
4
|
+
// The shared HTTP-JSON transport, and the child-process runner.
|
|
5
|
+
//
|
|
6
|
+
// PLUGIN-ONLY, and that is the point of the file. A socket, a TLS handshake
|
|
7
|
+
// and a forked process are exactly what the core does not have, so the
|
|
8
|
+
// bounded, redirect-refusing, proxy-ignoring JSON round-trip every vault
|
|
9
|
+
// client here is built on lives under `plugins/` with them. A chain of the
|
|
10
|
+
// four built-in kinds never imports it.
|
|
11
|
+
//
|
|
12
|
+
// A port of typescript/plugins/httpjson.ts, which is canonical.
|
|
13
|
+
|
|
14
|
+
import 'dart:convert';
|
|
15
|
+
import 'dart:io';
|
|
16
|
+
|
|
17
|
+
import '../src/json.dart';
|
|
18
|
+
import '../src/providers.dart';
|
|
19
|
+
import '../src/sekreto.dart';
|
|
20
|
+
|
|
21
|
+
/// How long any single vault round-trip may take before it is treated as
|
|
22
|
+
/// unreachable. Ports carry the same bound.
|
|
23
|
+
const Duration TIMEOUT = Duration(seconds: 10);
|
|
24
|
+
|
|
25
|
+
/// How much of a response body will be read before the store is treated as
|
|
26
|
+
/// having answered incoherently. Ports carry the same bound.
|
|
27
|
+
///
|
|
28
|
+
/// Far above anything real - the largest legitimate payload this library
|
|
29
|
+
/// fetches is Doppler's whole-config download, measured in kilobytes. A
|
|
30
|
+
/// bound is needed because the TIMEOUT is not one: ten seconds on a loopback
|
|
31
|
+
/// or datacentre link is gigabytes, and the body is accumulated in memory
|
|
32
|
+
/// before it is parsed. This runs on an application's startup path, so the
|
|
33
|
+
/// failure is the application never starting.
|
|
34
|
+
const int MAXBODY = 8 * 1024 * 1024;
|
|
35
|
+
|
|
36
|
+
/// A deadline that never arrives: a configured token is never renewed.
|
|
37
|
+
const int NEVER = 0x7fffffffffffffff;
|
|
38
|
+
|
|
39
|
+
/// The first candidate that is set and non-empty, or the empty string.
|
|
40
|
+
String first(List<String?> candidates) {
|
|
41
|
+
for (final candidate in candidates) {
|
|
42
|
+
if (null != candidate && candidate.isNotEmpty) {
|
|
43
|
+
return candidate;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return '';
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/// Drop one trailing slash.
|
|
50
|
+
String trimslash(String text) => dropsuffix(text, '/');
|
|
51
|
+
|
|
52
|
+
/// A URL without its query string, for a message that must not leak one.
|
|
53
|
+
String bare(String url) {
|
|
54
|
+
final mark = url.indexOf('?');
|
|
55
|
+
return -1 == mark ? url : url.substring(0, mark);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// --- percent encoding -----------------------------------------------
|
|
59
|
+
//
|
|
60
|
+
// WITH THE TRANSPORT, not with the signer, and the difference is a plugin
|
|
61
|
+
// or two of compiled SHA-256. Every URL this library builds is built by a
|
|
62
|
+
// plugin - a Key Vault query, a Doppler config, an Infisical secret path -
|
|
63
|
+
// and `sigv4.dart` uses the SAME pair, so a signed query and a fetched one
|
|
64
|
+
// escape identically. Keeping them here means the four kinds that only
|
|
65
|
+
// need to escape a query parameter import the transport and stop, rather
|
|
66
|
+
// than dragging in the AWS signer and its hash function behind it.
|
|
67
|
+
|
|
68
|
+
/// RFC 3986 escaping, which is stricter than the usual URL encoder: AWS
|
|
69
|
+
/// wants everything but unreserved characters escaped, with uppercase hex.
|
|
70
|
+
String uriescape(String text) {
|
|
71
|
+
final out = StringBuffer();
|
|
72
|
+
|
|
73
|
+
for (final byte in utf8.encode(text)) {
|
|
74
|
+
final ch = byte & 0xff;
|
|
75
|
+
final unreserved = (0x41 <= ch && 0x5a >= ch) ||
|
|
76
|
+
(0x61 <= ch && 0x7a >= ch) ||
|
|
77
|
+
(0x30 <= ch && 0x39 >= ch) ||
|
|
78
|
+
0x2d == ch ||
|
|
79
|
+
0x5f == ch ||
|
|
80
|
+
0x2e == ch ||
|
|
81
|
+
0x7e == ch;
|
|
82
|
+
|
|
83
|
+
if (unreserved) {
|
|
84
|
+
out.writeCharCode(ch);
|
|
85
|
+
} else {
|
|
86
|
+
out.write('%');
|
|
87
|
+
out.write(ch.toRadixString(16).toUpperCase().padLeft(2, '0'));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return out.toString();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/// Two hex digits as a byte, or nothing.
|
|
95
|
+
int? _hexbyte(String text) {
|
|
96
|
+
var value = 0;
|
|
97
|
+
|
|
98
|
+
for (final unit in text.codeUnits) {
|
|
99
|
+
final digit = _HEX.indexOf(String.fromCharCode(unit).toLowerCase());
|
|
100
|
+
if (-1 == digit) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
value = value * 16 + digit;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return value;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const String _HEX = '0123456789abcdef';
|
|
110
|
+
|
|
111
|
+
/// Percent-decode, and nothing else: `+` stays `+`, as on the wire.
|
|
112
|
+
String uridecode(String text) {
|
|
113
|
+
final out = <int>[];
|
|
114
|
+
var index = 0;
|
|
115
|
+
|
|
116
|
+
while (index < text.length) {
|
|
117
|
+
var taken = false;
|
|
118
|
+
|
|
119
|
+
if ('%' == text[index] && index + 2 < text.length) {
|
|
120
|
+
final code = _hexbyte(text.substring(index + 1, index + 3));
|
|
121
|
+
if (null != code) {
|
|
122
|
+
out.add(code);
|
|
123
|
+
index += 3;
|
|
124
|
+
taken = true;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (!taken) {
|
|
129
|
+
// A stray % is kept as-is, the way a browser would.
|
|
130
|
+
out.addAll(utf8.encode(text[index]));
|
|
131
|
+
index += 1;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return utf8.decode(out, allowMalformed: true);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/// What a finished child process left behind.
|
|
139
|
+
class Ran {
|
|
140
|
+
final String out;
|
|
141
|
+
final String why;
|
|
142
|
+
final int status;
|
|
143
|
+
const Ran(this.out, this.why, this.status);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/// Run a child to completion and collect both its streams.
|
|
147
|
+
///
|
|
148
|
+
/// `Process.runSync` closes the child's stdin and drains stdout and stderr
|
|
149
|
+
/// together. Both matter. A CLI that prompts for a passphrase when its
|
|
150
|
+
/// environment variable is absent sees EOF and gives up rather than waiting
|
|
151
|
+
/// forever; and draining one stream to EOF before starting on the other
|
|
152
|
+
/// would deadlock the moment the child writes more than one pipe buffer
|
|
153
|
+
/// (64 KiB on Linux) to stderr - secretspec's box-drawn diagnostics reach
|
|
154
|
+
/// that size easily, and nothing here sets a timeout, so that hang would be
|
|
155
|
+
/// permanent.
|
|
156
|
+
///
|
|
157
|
+
/// The argument list is passed as a list, never through a shell, and no
|
|
158
|
+
/// secret is ever put on it: the process table is public.
|
|
159
|
+
Ran runcmd(List<String> argv, String command, {Map<String, String>? extraenv}) {
|
|
160
|
+
try {
|
|
161
|
+
final result = Process.runSync(
|
|
162
|
+
argv.first,
|
|
163
|
+
argv.sublist(1),
|
|
164
|
+
environment: extraenv,
|
|
165
|
+
stdoutEncoding: utf8,
|
|
166
|
+
stderrEncoding: utf8,
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
return Ran(
|
|
170
|
+
result.stdout as String,
|
|
171
|
+
(result.stderr as String).trim(),
|
|
172
|
+
result.exitCode,
|
|
173
|
+
);
|
|
174
|
+
} on ProcessException catch (err) {
|
|
175
|
+
throw SekretoError('sekreto: cannot run $command: ${err.message}');
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/// One JSON round-trip's result: the status, and the parsed body.
|
|
180
|
+
class Answer {
|
|
181
|
+
final int status;
|
|
182
|
+
final Json? body;
|
|
183
|
+
const Answer(this.status, this.body);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// The one HTTP client, built once.
|
|
187
|
+
//
|
|
188
|
+
// Redirects are never followed: a vault API does not legitimately redirect,
|
|
189
|
+
// and a followed redirect would carry X-Vault-Token to the redirect's host
|
|
190
|
+
// (and could downgrade https to http), which checkaddr - it only validates
|
|
191
|
+
// the configured address - cannot see.
|
|
192
|
+
//
|
|
193
|
+
// Proxies are ignored. The GCP and Azure metadata endpoints are not
|
|
194
|
+
// loopback, and an `http_proxy` in the environment has sent a Vault token in
|
|
195
|
+
// the clear before now. Dart's HttpClient does not read the proxy
|
|
196
|
+
// environment unless asked; saying so explicitly makes it auditable rather
|
|
197
|
+
// than merely true.
|
|
198
|
+
HttpClient? _client;
|
|
199
|
+
|
|
200
|
+
HttpClient http() {
|
|
201
|
+
final existing = _client;
|
|
202
|
+
if (null != existing) {
|
|
203
|
+
return existing;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Additive, never a replacement: the platform roots are loaded first and
|
|
207
|
+
// unconditionally, and SEKRETO_CA_BUNDLE adds to them. It fails open and
|
|
208
|
+
// silently - an unreadable file or a certificate the store rejects adds no
|
|
209
|
+
// roots and raises nothing, so a wrong path cannot turn into a refusal
|
|
210
|
+
// that looks like a network fault.
|
|
211
|
+
final context = SecurityContext(withTrustedRoots: true);
|
|
212
|
+
final extra = getenv('SEKRETO_CA_BUNDLE');
|
|
213
|
+
|
|
214
|
+
if (null != extra && extra.isNotEmpty) {
|
|
215
|
+
try {
|
|
216
|
+
context.setTrustedCertificates(extra);
|
|
217
|
+
} catch (_) {
|
|
218
|
+
// Fails open by design.
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
final client = HttpClient(context: context);
|
|
223
|
+
client.connectionTimeout = TIMEOUT;
|
|
224
|
+
client.findProxy = (uri) => 'DIRECT';
|
|
225
|
+
|
|
226
|
+
_client = client;
|
|
227
|
+
return client;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
Future<(int, String)> _roundtrip(
|
|
231
|
+
String method,
|
|
232
|
+
String url,
|
|
233
|
+
Map<String, String> headers,
|
|
234
|
+
String? body,
|
|
235
|
+
) async {
|
|
236
|
+
final request = await http().openUrl(method, Uri.parse(url));
|
|
237
|
+
|
|
238
|
+
request.followRedirects = false;
|
|
239
|
+
|
|
240
|
+
headers.forEach((key, value) => request.headers.set(key, value));
|
|
241
|
+
|
|
242
|
+
if (null == body) {
|
|
243
|
+
request.contentLength = 0;
|
|
244
|
+
} else {
|
|
245
|
+
final bytes = utf8.encode(body);
|
|
246
|
+
request.contentLength = bytes.length;
|
|
247
|
+
request.add(bytes);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
final response = await request.close();
|
|
251
|
+
|
|
252
|
+
// One byte over the bound is enough to know it was exceeded. An endless
|
|
253
|
+
// body is a store that could not answer, so this raises rather than
|
|
254
|
+
// returning a miss - the latter would fall through to a weaker store on an
|
|
255
|
+
// attacker's cue.
|
|
256
|
+
final chunks = <int>[];
|
|
257
|
+
|
|
258
|
+
await for (final chunk in response) {
|
|
259
|
+
chunks.addAll(chunk);
|
|
260
|
+
if (MAXBODY < chunks.length) {
|
|
261
|
+
throw SekretoError('sekreto: oversized response from ${bare(url)}');
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return (response.statusCode, utf8.decode(chunks, allowMalformed: true));
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/// One JSON round-trip. Network failure is always an error - an unreachable
|
|
269
|
+
/// store is a store that could not answer, never a store that does not hold
|
|
270
|
+
/// the secret.
|
|
271
|
+
Future<Answer> fetchjson(
|
|
272
|
+
String method,
|
|
273
|
+
String url, {
|
|
274
|
+
Map<String, String> headers = const {},
|
|
275
|
+
String? body,
|
|
276
|
+
}) async {
|
|
277
|
+
final int status;
|
|
278
|
+
final String text;
|
|
279
|
+
|
|
280
|
+
try {
|
|
281
|
+
final answered = await _roundtrip(method, url, headers, body).timeout(TIMEOUT);
|
|
282
|
+
status = answered.$1;
|
|
283
|
+
text = answered.$2;
|
|
284
|
+
} on SekretoError {
|
|
285
|
+
// The body bound above; already the message it should be.
|
|
286
|
+
rethrow;
|
|
287
|
+
} catch (err) {
|
|
288
|
+
throw SekretoError('sekreto: cannot reach ${bare(url)}: ${why(err)}');
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// A success status promised JSON; a body that does not parse means the
|
|
292
|
+
// store could not answer coherently, and treating it as a miss would fall
|
|
293
|
+
// through to a weaker store. Error statuses may carry any body - they are
|
|
294
|
+
// decided on status alone.
|
|
295
|
+
final parsed = jsonparse(text);
|
|
296
|
+
if (200 == status && null == parsed) {
|
|
297
|
+
throw SekretoError('sekreto: malformed response from ${bare(url)}');
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return Answer(status, parsed);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/// When a logged-in token must be renewed, from its expiry in seconds (a
|
|
304
|
+
/// JSON number, or a string as Azure IMDS sends it): now + max(seconds - 60,
|
|
305
|
+
/// 1). A missing or zero expiry means never renew.
|
|
306
|
+
int renewtime(Json? expires) {
|
|
307
|
+
var seconds = 0.0;
|
|
308
|
+
|
|
309
|
+
final number = expires.asnum;
|
|
310
|
+
if (null != number) {
|
|
311
|
+
seconds = number;
|
|
312
|
+
} else {
|
|
313
|
+
final text = expires.asstr;
|
|
314
|
+
if (null != text) {
|
|
315
|
+
seconds = double.tryParse(text) ?? 0.0;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
if (seconds.isNaN || 0 >= seconds) {
|
|
320
|
+
return NEVER;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
final lead = seconds - 60 < 1 ? 1.0 : seconds - 60;
|
|
324
|
+
return DateTime.now().millisecondsSinceEpoch + (lead * 1000).toInt();
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/// Decode standard base64, strictly.
|
|
328
|
+
///
|
|
329
|
+
/// Nothing is skipped and nothing is guessed: a lenient decoder silently
|
|
330
|
+
/// drops bytes outside the alphabet and hands back plausible bytes for a
|
|
331
|
+
/// corrupted payload - which then get returned as the secret. Whitespace is
|
|
332
|
+
/// stripped first, because the canonical function accepts a payload wrapped
|
|
333
|
+
/// across lines; everything else outside the alphabet is a refusal, and a
|
|
334
|
+
/// refusal is an error, never a miss.
|
|
335
|
+
String? unbase64(String text) {
|
|
336
|
+
final cleaned = text.replaceAll(RegExp(r'\s'), '');
|
|
337
|
+
|
|
338
|
+
if (cleaned.isEmpty || 0 != cleaned.length % 4) {
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
var end = cleaned.length;
|
|
343
|
+
var pad = 0;
|
|
344
|
+
while (0 < end && '=' == cleaned[end - 1] && 2 > pad) {
|
|
345
|
+
end--;
|
|
346
|
+
pad++;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
for (var at = 0; at < end; at++) {
|
|
350
|
+
if (!_B64.contains(cleaned[at])) {
|
|
351
|
+
return null;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
try {
|
|
356
|
+
return utf8.decode(base64.decode(cleaned), allowMalformed: true);
|
|
357
|
+
} catch (_) {
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const String _B64 =
|
|
363
|
+
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// VENDORED: @voxgig/sekreto sdk-20260908-1556-0 (dart/plugins/infisical.dart)
|
|
2
|
+
// Source: https://github.com/voxgig/sekreto @ 1267ee2e5f49566bc92695bc9eb3a60ef4924998 [tag: sdk-20260908-1556-0]
|
|
3
|
+
// License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
|
|
4
|
+
// Infisical, as a voxgig/plugin definition.
|
|
5
|
+
//
|
|
6
|
+
// A PLUGIN, not a built-in: it opens a socket. A `Sekreto` can build the
|
|
7
|
+
// `infisical` kind only if the calling project imported this file and
|
|
8
|
+
// passed `infisical` in the `plugins` option
|
|
9
|
+
// (docs/design/plugin-providers.md).
|
|
10
|
+
//
|
|
11
|
+
// A port of typescript/plugins/infisical.ts, which is canonical.
|
|
12
|
+
|
|
13
|
+
import 'dart:async';
|
|
14
|
+
|
|
15
|
+
import '../src/addr.dart';
|
|
16
|
+
import '../src/json.dart';
|
|
17
|
+
import '../src/provider.dart';
|
|
18
|
+
import '../src/sekreto.dart';
|
|
19
|
+
import '../src/support.dart';
|
|
20
|
+
|
|
21
|
+
import 'httpjson.dart';
|
|
22
|
+
|
|
23
|
+
/// Infisical.
|
|
24
|
+
///
|
|
25
|
+
/// `api.token` reads the secret keyed `API_TOKEN` (Infisical's own
|
|
26
|
+
/// convention is environment-style keys) at a secret path in one environment
|
|
27
|
+
/// of a project. Auth is a token, or a universal-auth (machine identity)
|
|
28
|
+
/// login with clientid/clientsecret.
|
|
29
|
+
class Infisical extends Provider {
|
|
30
|
+
final String? addr;
|
|
31
|
+
final String? token;
|
|
32
|
+
final String? clientid;
|
|
33
|
+
final String? clientsecret;
|
|
34
|
+
final String? project;
|
|
35
|
+
final String? environment;
|
|
36
|
+
final String? path;
|
|
37
|
+
|
|
38
|
+
// A configured token is kept forever; a universal-auth token carries
|
|
39
|
+
// expiresIn and is renewed shortly before it runs out.
|
|
40
|
+
String? _livetoken;
|
|
41
|
+
int _renewat = NEVER;
|
|
42
|
+
|
|
43
|
+
Infisical({
|
|
44
|
+
this.addr,
|
|
45
|
+
this.token,
|
|
46
|
+
this.clientid,
|
|
47
|
+
this.clientsecret,
|
|
48
|
+
this.project,
|
|
49
|
+
this.environment,
|
|
50
|
+
this.path,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
Future<String> _login(String useaddr) async {
|
|
54
|
+
if (null != token && token!.isNotEmpty) {
|
|
55
|
+
return token!;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (null == clientid ||
|
|
59
|
+
clientid!.isEmpty ||
|
|
60
|
+
null == clientsecret ||
|
|
61
|
+
clientsecret!.isEmpty) {
|
|
62
|
+
throw SekretoError(
|
|
63
|
+
'sekreto: infisical: no token and no client credentials',
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
final body = JsonObj({
|
|
68
|
+
'clientId': JsonStr(clientid!),
|
|
69
|
+
'clientSecret': JsonStr(clientsecret!),
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
final res = await fetchjson(
|
|
73
|
+
'POST',
|
|
74
|
+
'$useaddr/api/v1/auth/universal-auth/login',
|
|
75
|
+
headers: {'content-type': 'application/json'},
|
|
76
|
+
body: jsonstringify(body),
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
final got = res.body.dig('accessToken').text;
|
|
80
|
+
if (200 != res.status || null == got || got.isEmpty) {
|
|
81
|
+
throw SekretoError('sekreto: infisical login failed: ${res.status}');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// camelCase, unlike everyone else's expires_in.
|
|
85
|
+
_renewat = renewtime(res.body.dig('expiresIn'));
|
|
86
|
+
|
|
87
|
+
return got;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@override
|
|
91
|
+
FutureOr<String?> lookup(String name) {
|
|
92
|
+
final useaddr = trimslash(first([addr, 'https://app.infisical.com']));
|
|
93
|
+
checkaddr(useaddr);
|
|
94
|
+
|
|
95
|
+
final useproject = project ?? '';
|
|
96
|
+
final useenvironment = environment ?? '';
|
|
97
|
+
if (useproject.isEmpty || useenvironment.isEmpty) {
|
|
98
|
+
throw SekretoError('sekreto: infisical: no project/environment');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return _read(useaddr, useproject, useenvironment, name);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
Future<String?> _read(
|
|
105
|
+
String useaddr,
|
|
106
|
+
String useproject,
|
|
107
|
+
String useenvironment,
|
|
108
|
+
String name,
|
|
109
|
+
) async {
|
|
110
|
+
if (null == _livetoken || DateTime.now().millisecondsSinceEpoch >= _renewat) {
|
|
111
|
+
_livetoken = await _login(useaddr);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
final url = '$useaddr/api/v3/secrets/raw/${envkey(name)}'
|
|
115
|
+
'?workspaceId=${uriescape(useproject)}'
|
|
116
|
+
'&environment=${uriescape(useenvironment)}'
|
|
117
|
+
'&secretPath=${uriescape(first([path, '/']))}';
|
|
118
|
+
|
|
119
|
+
final res = await fetchjson('GET', url,
|
|
120
|
+
headers: {'authorization': 'Bearer ${_livetoken ?? ''}'});
|
|
121
|
+
|
|
122
|
+
if (404 == res.status) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
if (200 != res.status) {
|
|
126
|
+
throw SekretoError('sekreto: infisical error: ${res.status}');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return res.body.dig('secret', 'secretValue').text;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
@override
|
|
133
|
+
String describe() => 'infisical:${project ?? ''}/${environment ?? ''}';
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/// The `infisical` provider kind. Pass it in `plugins` to name it in a
|
|
137
|
+
/// chain.
|
|
138
|
+
final Definition infisical = providerplugin(
|
|
139
|
+
'infisical',
|
|
140
|
+
(spec) => Infisical(
|
|
141
|
+
addr: spec.addr,
|
|
142
|
+
token: spec.token,
|
|
143
|
+
clientid: spec.clientid,
|
|
144
|
+
clientsecret: spec.clientsecret,
|
|
145
|
+
project: spec.project,
|
|
146
|
+
environment: spec.environment,
|
|
147
|
+
path: spec.path,
|
|
148
|
+
),
|
|
149
|
+
);
|