@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,787 @@
|
|
|
1
|
+
/- ProjectName SDK feature catalog: the concrete features.
|
|
2
|
+
|
|
3
|
+
Each constructor returns a `Feature` closing over its own state refs. A
|
|
4
|
+
feature either wraps the transport (retry, timeout, ratelimit, cache, proxy,
|
|
5
|
+
netsim, test) or handles pipeline hooks (idempotency, rbac, metrics,
|
|
6
|
+
telemetry, debug, audit, clienttrack, paging, streaming) — or both.
|
|
7
|
+
|
|
8
|
+
Observable state is recorded in the client's `track` buckets under the
|
|
9
|
+
feature's own name, so behaviour is assertable from tests. -/
|
|
10
|
+
|
|
11
|
+
import VoxgigStruct
|
|
12
|
+
import SdkJson
|
|
13
|
+
import SdkUtility
|
|
14
|
+
import SdkFeature
|
|
15
|
+
|
|
16
|
+
open VoxgigStruct
|
|
17
|
+
open SdkFeature
|
|
18
|
+
|
|
19
|
+
namespace SdkFeatures
|
|
20
|
+
|
|
21
|
+
def gp := SdkUtility.gp
|
|
22
|
+
def sp := SdkUtility.sp
|
|
23
|
+
def gpS := SdkUtility.gpS
|
|
24
|
+
def vs := SdkUtility.vs
|
|
25
|
+
def isNov := SdkUtility.isNov
|
|
26
|
+
def truthy := SdkUtility.truthy
|
|
27
|
+
|
|
28
|
+
def statusOf (v : Value) : Float :=
|
|
29
|
+
match v with
|
|
30
|
+
| .map _ => 0.0
|
|
31
|
+
| _ => 0.0
|
|
32
|
+
|
|
33
|
+
def numOf (v : Value) (d : Float) : Float :=
|
|
34
|
+
match v with
|
|
35
|
+
| .num n => n
|
|
36
|
+
| _ => d
|
|
37
|
+
|
|
38
|
+
/-- Append a value to a struct list held at `key` on `parent`. -/
|
|
39
|
+
def appendTo (parent : Value) (key : String) (v : Value) : SIO Unit := do
|
|
40
|
+
match (← gp parent key) with
|
|
41
|
+
| .list i => do
|
|
42
|
+
let items ← listItems i
|
|
43
|
+
sp parent key (← newList (items.push v))
|
|
44
|
+
| _ => sp parent key (← newList #[v])
|
|
45
|
+
|
|
46
|
+
-- ---------------------------------------------------------------------------
|
|
47
|
+
-- base / log
|
|
48
|
+
-- ---------------------------------------------------------------------------
|
|
49
|
+
|
|
50
|
+
def baseFeature : SIO Feature := do
|
|
51
|
+
pure { name := "base" }
|
|
52
|
+
|
|
53
|
+
def logFeature : SIO Feature := do
|
|
54
|
+
pure { name := "log"
|
|
55
|
+
, hook := fun stage ctx => do
|
|
56
|
+
if stage == "PreRequest" then do
|
|
57
|
+
let b ← trackCtx ctx "log" (newMap #[("calls", .num 0.0)])
|
|
58
|
+
bumpNum b "calls" 1.0 }
|
|
59
|
+
|
|
60
|
+
-- ---------------------------------------------------------------------------
|
|
61
|
+
-- retry
|
|
62
|
+
-- ---------------------------------------------------------------------------
|
|
63
|
+
|
|
64
|
+
def retryFeature : SIO Feature := do
|
|
65
|
+
let optsR ← IO.mkRef (← emptyMap)
|
|
66
|
+
let retryable (res : Value) (err : Option Value) (statuses : Array Float) : Bool :=
|
|
67
|
+
match err with
|
|
68
|
+
| some _ => true
|
|
69
|
+
| none =>
|
|
70
|
+
match res with
|
|
71
|
+
| .noval => true
|
|
72
|
+
| _ => false
|
|
73
|
+
pure { name := "retry"
|
|
74
|
+
, init := fun ctx opts => do
|
|
75
|
+
let om ← toOptsMap opts
|
|
76
|
+
optsR.set om
|
|
77
|
+
if (← optActive opts) then do
|
|
78
|
+
let client ← clientOf ctx
|
|
79
|
+
let inner ← getFetcher client
|
|
80
|
+
setFetcher client fun c u f => do
|
|
81
|
+
let o ← optsR.get
|
|
82
|
+
let retries := (← optInt o "retries" 2).toNat
|
|
83
|
+
let minDelay ← optNum o "minDelay" 50.0
|
|
84
|
+
let maxDelay ← optNum o "maxDelay" 2000.0
|
|
85
|
+
let factor ← optNum o "factor" 2.0
|
|
86
|
+
let mut attempt := 0
|
|
87
|
+
let mut out ← inner c u f
|
|
88
|
+
while attempt < retries do
|
|
89
|
+
let statusV ← gp out.1 "status"
|
|
90
|
+
let st := numOf statusV 0.0
|
|
91
|
+
let bad := (out.2.isSome) || st >= 500.0 || st == 429.0 || st == 408.0
|
|
92
|
+
if !bad then break
|
|
93
|
+
let mut delay := minDelay
|
|
94
|
+
for _ in [0:attempt] do delay := delay * factor
|
|
95
|
+
sleepMs (if delay > maxDelay then maxDelay else delay)
|
|
96
|
+
let b ← trackCtx c "retry" (newMap #[("attempts", .num 0.0)])
|
|
97
|
+
bumpNum b "attempts" 1.0
|
|
98
|
+
out ← inner c u f
|
|
99
|
+
attempt := attempt + 1
|
|
100
|
+
pure out }
|
|
101
|
+
|
|
102
|
+
-- ---------------------------------------------------------------------------
|
|
103
|
+
-- timeout
|
|
104
|
+
-- ---------------------------------------------------------------------------
|
|
105
|
+
|
|
106
|
+
def timeoutFeature : SIO Feature := do
|
|
107
|
+
let optsR ← IO.mkRef (← emptyMap)
|
|
108
|
+
pure { name := "timeout"
|
|
109
|
+
, init := fun ctx opts => do
|
|
110
|
+
let om ← toOptsMap opts
|
|
111
|
+
optsR.set om
|
|
112
|
+
if (← optActive opts) then do
|
|
113
|
+
let client ← clientOf ctx
|
|
114
|
+
let inner ← getFetcher client
|
|
115
|
+
setFetcher client fun c u f => do
|
|
116
|
+
let o ← optsR.get
|
|
117
|
+
let ms ← optNum o "ms" 30000.0
|
|
118
|
+
if ms <= 0.0 then inner c u f
|
|
119
|
+
else do
|
|
120
|
+
sp f "timeout" (.num (ms / 1000.0))
|
|
121
|
+
let start ← nowMs
|
|
122
|
+
let out ← inner c u f
|
|
123
|
+
let elapsed := (← nowMs) - start
|
|
124
|
+
if elapsed > ms then do
|
|
125
|
+
let b ← trackCtx c "timeout" (newMap #[("count", .num 0.0), ("ms", .num ms)])
|
|
126
|
+
bumpNum b "count" 1.0
|
|
127
|
+
let e ← SdkUtility.mkErr "timeout"
|
|
128
|
+
("Request exceeded timeout of " ++ numToString ms ++ "ms")
|
|
129
|
+
pure (.noval, some e)
|
|
130
|
+
else pure out }
|
|
131
|
+
|
|
132
|
+
-- ---------------------------------------------------------------------------
|
|
133
|
+
-- ratelimit (token bucket)
|
|
134
|
+
-- ---------------------------------------------------------------------------
|
|
135
|
+
|
|
136
|
+
def ratelimitFeature : SIO Feature := do
|
|
137
|
+
let optsR ← IO.mkRef (← emptyMap)
|
|
138
|
+
let tokensR ← IO.mkRef (0.0 : Float)
|
|
139
|
+
let lastR ← IO.mkRef (0.0 : Float)
|
|
140
|
+
pure { name := "ratelimit"
|
|
141
|
+
, init := fun ctx opts => do
|
|
142
|
+
let om ← toOptsMap opts
|
|
143
|
+
optsR.set om
|
|
144
|
+
if (← optActive opts) then do
|
|
145
|
+
let rate ← optNum om "rate" 5.0
|
|
146
|
+
let burst ← optNum om "burst" rate
|
|
147
|
+
tokensR.set burst
|
|
148
|
+
lastR.set (← nowMs)
|
|
149
|
+
let client ← clientOf ctx
|
|
150
|
+
let inner ← getFetcher client
|
|
151
|
+
setFetcher client fun c u f => do
|
|
152
|
+
let o ← optsR.get
|
|
153
|
+
let r ← optNum o "rate" 5.0
|
|
154
|
+
let b ← optNum o "burst" r
|
|
155
|
+
let now ← nowMs
|
|
156
|
+
let elapsed := now - (← lastR.get)
|
|
157
|
+
lastR.set now
|
|
158
|
+
let tk0 := (← tokensR.get) + (elapsed / 1000.0) * r
|
|
159
|
+
let tk := if tk0 > b then b else tk0
|
|
160
|
+
if tk >= 1.0 then tokensR.set (tk - 1.0)
|
|
161
|
+
else do
|
|
162
|
+
let waitMs := ((1.0 - tk) / r) * 1000.0
|
|
163
|
+
let bucket ← trackCtx c "ratelimit"
|
|
164
|
+
(newMap #[("throttled", .num 0.0), ("waitMs", .num 0.0)])
|
|
165
|
+
bumpNum bucket "throttled" 1.0
|
|
166
|
+
bumpNum bucket "waitMs" waitMs
|
|
167
|
+
sleepMs waitMs
|
|
168
|
+
lastR.set (← nowMs)
|
|
169
|
+
tokensR.set 0.0
|
|
170
|
+
inner c u f }
|
|
171
|
+
|
|
172
|
+
-- ---------------------------------------------------------------------------
|
|
173
|
+
-- cache
|
|
174
|
+
-- ---------------------------------------------------------------------------
|
|
175
|
+
|
|
176
|
+
def cacheFeature : SIO Feature := do
|
|
177
|
+
let optsR ← IO.mkRef (← emptyMap)
|
|
178
|
+
let storeR ← IO.mkRef (← emptyMap)
|
|
179
|
+
pure { name := "cache"
|
|
180
|
+
, init := fun ctx opts => do
|
|
181
|
+
let om ← toOptsMap opts
|
|
182
|
+
optsR.set om
|
|
183
|
+
if (← optActive opts) then do
|
|
184
|
+
storeR.set (← emptyMap)
|
|
185
|
+
let client ← clientOf ctx
|
|
186
|
+
let inner ← getFetcher client
|
|
187
|
+
setFetcher client fun c u f => do
|
|
188
|
+
let o ← optsR.get
|
|
189
|
+
let meth := upper (← gpS f "method")
|
|
190
|
+
let methods ← optStrList o "methods" #["GET"]
|
|
191
|
+
if !(methods.map upper).contains (if meth == "" then "GET" else meth) then
|
|
192
|
+
inner c u f
|
|
193
|
+
else do
|
|
194
|
+
let key := meth ++ " " ++ u
|
|
195
|
+
let store ← storeR.get
|
|
196
|
+
let now ← nowMs
|
|
197
|
+
let hit ← gp store key
|
|
198
|
+
let fresh := match hit with
|
|
199
|
+
| .map _ => true
|
|
200
|
+
| _ => false
|
|
201
|
+
let expiry := numOf (← gp hit "expiry") 0.0
|
|
202
|
+
if fresh && expiry > now then do
|
|
203
|
+
let b ← trackCtx c "cache"
|
|
204
|
+
(newMap #[("hit", .num 0.0), ("miss", .num 0.0), ("bypass", .num 0.0)])
|
|
205
|
+
bumpNum b "hit" 1.0
|
|
206
|
+
pure ((← gp hit "snapshot"), none)
|
|
207
|
+
else do
|
|
208
|
+
let out ← inner c u f
|
|
209
|
+
let st := numOf (← gp out.1 "status") 0.0
|
|
210
|
+
let ok := out.2.isNone && st >= 200.0 && st < 300.0
|
|
211
|
+
let b ← trackCtx c "cache"
|
|
212
|
+
(newMap #[("hit", .num 0.0), ("miss", .num 0.0), ("bypass", .num 0.0)])
|
|
213
|
+
if ok then do
|
|
214
|
+
let ttl ← optNum o "ttl" 5000.0
|
|
215
|
+
let snap ← clone out.1
|
|
216
|
+
let entry ← newMap #[("expiry", .num (now + ttl)), ("snapshot", snap)]
|
|
217
|
+
sp store key entry
|
|
218
|
+
bumpNum b "miss" 1.0
|
|
219
|
+
else bumpNum b "bypass" 1.0
|
|
220
|
+
pure out }
|
|
221
|
+
|
|
222
|
+
-- ---------------------------------------------------------------------------
|
|
223
|
+
-- idempotency
|
|
224
|
+
-- ---------------------------------------------------------------------------
|
|
225
|
+
|
|
226
|
+
def idempotencyFeature : SIO Feature := do
|
|
227
|
+
let optsR ← IO.mkRef (← emptyMap)
|
|
228
|
+
pure { name := "idempotency"
|
|
229
|
+
, init := fun _ opts => do optsR.set (← toOptsMap opts)
|
|
230
|
+
, hook := fun stage ctx => do
|
|
231
|
+
if stage == "PreRequest" then do
|
|
232
|
+
let o ← optsR.get
|
|
233
|
+
let specV ← gp ctx "spec"
|
|
234
|
+
match specV with
|
|
235
|
+
| .map _ => do
|
|
236
|
+
let methods ← optStrList o "methods" #["POST", "PUT", "PATCH", "DELETE"]
|
|
237
|
+
let meth := upper (← gpS specV "method")
|
|
238
|
+
let ops ← optStrList o "ops" #["create", "update", "remove"]
|
|
239
|
+
let opname ← SdkUtility.opnameOf ctx
|
|
240
|
+
if (methods.map upper).contains meth || ops.contains opname then do
|
|
241
|
+
let header ← optStr o "header" "Idempotency-Key"
|
|
242
|
+
let hdrs ← SdkUtility.gpMap specV "headers"
|
|
243
|
+
if isNov (← headerCI hdrs header) then do
|
|
244
|
+
let key ← genId
|
|
245
|
+
sp hdrs header (.str key)
|
|
246
|
+
let b ← trackCtx ctx "idempotency"
|
|
247
|
+
(newMap #[("issued", .num 0.0), ("last", .noval)])
|
|
248
|
+
bumpNum b "issued" 1.0
|
|
249
|
+
sp b "last" (.str key)
|
|
250
|
+
| _ => pure () }
|
|
251
|
+
|
|
252
|
+
-- ---------------------------------------------------------------------------
|
|
253
|
+
-- rbac (PrePoint short-circuit)
|
|
254
|
+
-- ---------------------------------------------------------------------------
|
|
255
|
+
|
|
256
|
+
def rbacFeature : SIO Feature := do
|
|
257
|
+
let optsR ← IO.mkRef (← emptyMap)
|
|
258
|
+
pure { name := "rbac"
|
|
259
|
+
, init := fun _ opts => do optsR.set (← toOptsMap opts)
|
|
260
|
+
, hook := fun stage ctx => do
|
|
261
|
+
if stage == "PrePoint" then do
|
|
262
|
+
let o ← optsR.get
|
|
263
|
+
let opname ← SdkUtility.opnameOf ctx
|
|
264
|
+
let perms ← optStrList o "perms" #[]
|
|
265
|
+
let rules ← gp o "rules"
|
|
266
|
+
let required ← gpS rules opname
|
|
267
|
+
let deny := truthy (← gp o "deny")
|
|
268
|
+
let needed := if required != "" then required else (if deny then "<default-deny>" else "")
|
|
269
|
+
let allowed := needed == "" || perms.contains needed
|
|
270
|
+
let b ← trackCtx ctx "rbac"
|
|
271
|
+
(newMap #[("allowed", .num 0.0), ("denied", .num 0.0), ("last", .noval)])
|
|
272
|
+
bumpNum b (if allowed then "allowed" else "denied") 1.0
|
|
273
|
+
sp b "last" (.str needed)
|
|
274
|
+
if !allowed then do
|
|
275
|
+
let e ← SdkUtility.mkErr "rbac_denied"
|
|
276
|
+
("Permission \"" ++ needed ++ "\" required for operation \"" ++ opname ++ "\"")
|
|
277
|
+
let out ← SdkUtility.gpMap ctx "out"
|
|
278
|
+
sp out "point" e }
|
|
279
|
+
|
|
280
|
+
-- ---------------------------------------------------------------------------
|
|
281
|
+
-- metrics
|
|
282
|
+
-- ---------------------------------------------------------------------------
|
|
283
|
+
|
|
284
|
+
def metricsFeature : SIO Feature := do
|
|
285
|
+
let startR ← IO.mkRef (0.0 : Float)
|
|
286
|
+
pure { name := "metrics"
|
|
287
|
+
, hook := fun stage ctx => do
|
|
288
|
+
let mk : SIO Value := do
|
|
289
|
+
let tot ← newMap #[("count", .num 0.0), ("ok", .num 0.0), ("err", .num 0.0),
|
|
290
|
+
("totalMs", .num 0.0), ("maxMs", .num 0.0)]
|
|
291
|
+
let ops ← emptyMap
|
|
292
|
+
newMap #[("total", tot), ("ops", ops)]
|
|
293
|
+
if stage == "PreRequest" then startR.set (← nowMs)
|
|
294
|
+
else if stage == "PreDone" then do
|
|
295
|
+
let m ← trackCtx ctx "metrics" mk
|
|
296
|
+
let dur := (← nowMs) - (← startR.get)
|
|
297
|
+
let total ← gp m "total"
|
|
298
|
+
let res ← gp ctx "result"
|
|
299
|
+
let ok := truthy (← gp res "ok")
|
|
300
|
+
bumpNum total "count" 1.0
|
|
301
|
+
bumpNum total (if ok then "ok" else "err") 1.0
|
|
302
|
+
bumpNum total "totalMs" dur
|
|
303
|
+
if dur > numOf (← gp total "maxMs") 0.0 then sp total "maxMs" (.num dur)
|
|
304
|
+
let opname ← SdkUtility.opnameOf ctx
|
|
305
|
+
let ops ← gp m "ops"
|
|
306
|
+
let key := (← gpS (← gp ctx "op") "entity") ++ "." ++ opname
|
|
307
|
+
let opb ← (match (← gp ops key) with
|
|
308
|
+
| .map i => pure (Value.map i)
|
|
309
|
+
| _ => do
|
|
310
|
+
let b ← newMap #[("count", .num 0.0), ("ok", .num 0.0), ("err", .num 0.0),
|
|
311
|
+
("totalMs", .num 0.0), ("maxMs", .num 0.0)]
|
|
312
|
+
sp ops key b
|
|
313
|
+
pure b)
|
|
314
|
+
bumpNum opb "count" 1.0
|
|
315
|
+
bumpNum opb (if ok then "ok" else "err") 1.0
|
|
316
|
+
bumpNum opb "totalMs" dur }
|
|
317
|
+
|
|
318
|
+
-- ---------------------------------------------------------------------------
|
|
319
|
+
-- telemetry (spans)
|
|
320
|
+
-- ---------------------------------------------------------------------------
|
|
321
|
+
|
|
322
|
+
def telemetryFeature : SIO Feature := do
|
|
323
|
+
let spanR ← IO.mkRef (Value.noval)
|
|
324
|
+
pure { name := "telemetry"
|
|
325
|
+
, hook := fun stage ctx => do
|
|
326
|
+
let mk : SIO Value := do
|
|
327
|
+
let sp0 ← emptyList
|
|
328
|
+
newMap #[("spans", sp0), ("active", .num 0.0)]
|
|
329
|
+
if stage == "PrePoint" then do
|
|
330
|
+
let t ← trackCtx ctx "telemetry" mk
|
|
331
|
+
let opname ← SdkUtility.opnameOf ctx
|
|
332
|
+
let sid ← genId
|
|
333
|
+
let s ← newMap #[("id", .str ("s" ++ sid)), ("name", .str opname),
|
|
334
|
+
("start", .num (← nowMs)), ("ok", .bool false)]
|
|
335
|
+
spanR.set s
|
|
336
|
+
appendTo t "spans" s
|
|
337
|
+
bumpNum t "active" 1.0
|
|
338
|
+
else if stage == "PreDone" then do
|
|
339
|
+
let s ← spanR.get
|
|
340
|
+
match s with
|
|
341
|
+
| .map _ => do
|
|
342
|
+
let t ← trackCtx ctx "telemetry" mk
|
|
343
|
+
let endMs ← nowMs
|
|
344
|
+
sp s "end" (.num endMs)
|
|
345
|
+
sp s "durationMs" (.num (endMs - numOf (← gp s "start") 0.0))
|
|
346
|
+
sp s "ok" (.bool (truthy (← gp (← gp ctx "result") "ok")))
|
|
347
|
+
bumpNum t "active" (-1.0)
|
|
348
|
+
| _ => pure () }
|
|
349
|
+
|
|
350
|
+
-- ---------------------------------------------------------------------------
|
|
351
|
+
-- debug (redacted request/response log)
|
|
352
|
+
-- ---------------------------------------------------------------------------
|
|
353
|
+
|
|
354
|
+
def debugFeature : SIO Feature := do
|
|
355
|
+
let optsR ← IO.mkRef (← emptyMap)
|
|
356
|
+
let entryR ← IO.mkRef (Value.noval)
|
|
357
|
+
pure { name := "debug"
|
|
358
|
+
, init := fun _ opts => do optsR.set (← toOptsMap opts)
|
|
359
|
+
, hook := fun stage ctx => do
|
|
360
|
+
let mk : SIO Value := do
|
|
361
|
+
let es ← emptyList
|
|
362
|
+
newMap #[("entries", es)]
|
|
363
|
+
if stage == "PreRequest" then do
|
|
364
|
+
let o ← optsR.get
|
|
365
|
+
let d ← trackCtx ctx "debug" mk
|
|
366
|
+
let patterns ← optStrList o "redact"
|
|
367
|
+
#["authorization", "cookie", "set-cookie", "api-key", "apikey",
|
|
368
|
+
"x-api-key", "idempotency-key"]
|
|
369
|
+
let specV ← gp ctx "spec"
|
|
370
|
+
let hdrs ← gp specV "headers"
|
|
371
|
+
let safe ← emptyMap
|
|
372
|
+
match hdrs with
|
|
373
|
+
| .map i =>
|
|
374
|
+
for k in (← keysof (.map i)) do
|
|
375
|
+
if patterns.contains (lower k) then sp safe k (.str "<redacted>")
|
|
376
|
+
else sp safe k (← gp (.map i) k)
|
|
377
|
+
| _ => pure ()
|
|
378
|
+
let opname ← SdkUtility.opnameOf ctx
|
|
379
|
+
let e ← newMap #[("op", .str opname), ("start", .num (← nowMs)),
|
|
380
|
+
("headers", safe), ("ok", .bool false)]
|
|
381
|
+
entryR.set e
|
|
382
|
+
appendTo d "entries" e
|
|
383
|
+
else if stage == "PreDone" then do
|
|
384
|
+
let e ← entryR.get
|
|
385
|
+
match e with
|
|
386
|
+
| .map _ => do
|
|
387
|
+
let endMs ← nowMs
|
|
388
|
+
sp e "durationMs" (.num (endMs - numOf (← gp e "start") 0.0))
|
|
389
|
+
let res ← gp ctx "result"
|
|
390
|
+
sp e "ok" (.bool (truthy (← gp res "ok")))
|
|
391
|
+
sp e "status" (← gp res "status")
|
|
392
|
+
| _ => pure () }
|
|
393
|
+
|
|
394
|
+
-- ---------------------------------------------------------------------------
|
|
395
|
+
-- audit
|
|
396
|
+
-- ---------------------------------------------------------------------------
|
|
397
|
+
|
|
398
|
+
def auditFeature : SIO Feature := do
|
|
399
|
+
pure { name := "audit"
|
|
400
|
+
, hook := fun stage ctx => do
|
|
401
|
+
if stage == "PreDone" then do
|
|
402
|
+
let a ← trackCtx ctx "audit" (do let rs ← emptyList; newMap #[("records", rs)])
|
|
403
|
+
let opname ← SdkUtility.opnameOf ctx
|
|
404
|
+
let res ← gp ctx "result"
|
|
405
|
+
let rec0 ← newMap #[("op", .str opname),
|
|
406
|
+
("entity", ← gp (← gp ctx "op") "entity"),
|
|
407
|
+
("ok", .bool (truthy (← gp res "ok"))),
|
|
408
|
+
("at", .num (← nowMs))]
|
|
409
|
+
appendTo a "records" rec0 }
|
|
410
|
+
|
|
411
|
+
-- ---------------------------------------------------------------------------
|
|
412
|
+
-- clienttrack (request/session identity headers)
|
|
413
|
+
-- ---------------------------------------------------------------------------
|
|
414
|
+
|
|
415
|
+
def clienttrackFeature : SIO Feature := do
|
|
416
|
+
let optsR ← IO.mkRef (← emptyMap)
|
|
417
|
+
let sessionR ← IO.mkRef ""
|
|
418
|
+
pure { name := "clienttrack"
|
|
419
|
+
, init := fun _ opts => do
|
|
420
|
+
optsR.set (← toOptsMap opts)
|
|
421
|
+
if (← sessionR.get) == "" then sessionR.set ("s-" ++ (← genId))
|
|
422
|
+
, hook := fun stage ctx => do
|
|
423
|
+
if stage == "PreRequest" then do
|
|
424
|
+
let o ← optsR.get
|
|
425
|
+
let nm ← optStr o "clientName" "ProjectName-SDK"
|
|
426
|
+
let ver ← optStr o "clientVersion" "0.0.1"
|
|
427
|
+
let rid := "r-" ++ (← genId)
|
|
428
|
+
let session ← sessionR.get
|
|
429
|
+
let specV ← gp ctx "spec"
|
|
430
|
+
let hdrs ← SdkUtility.gpMap specV "headers"
|
|
431
|
+
let hopt ← gp o "headers"
|
|
432
|
+
let reqH ← optStr hopt "request" "X-Request-Id"
|
|
433
|
+
let sesH ← optStr hopt "session" "X-Session-Id"
|
|
434
|
+
let cliH ← optStr hopt "client" "X-Client"
|
|
435
|
+
if isNov (← headerCI hdrs reqH) then sp hdrs reqH (.str rid)
|
|
436
|
+
if isNov (← headerCI hdrs sesH) then sp hdrs sesH (.str session)
|
|
437
|
+
if isNov (← headerCI hdrs cliH) then sp hdrs cliH (.str (nm ++ "/" ++ ver))
|
|
438
|
+
let b ← trackCtx ctx "clienttrack"
|
|
439
|
+
(newMap #[("session", .str session), ("requests", .num 0.0),
|
|
440
|
+
("clientName", .str nm)])
|
|
441
|
+
bumpNum b "requests" 1.0
|
|
442
|
+
sp b "lastRequestId" (.str rid) }
|
|
443
|
+
|
|
444
|
+
-- ---------------------------------------------------------------------------
|
|
445
|
+
-- paging / streaming
|
|
446
|
+
-- ---------------------------------------------------------------------------
|
|
447
|
+
|
|
448
|
+
def pagingFeature : SIO Feature := do
|
|
449
|
+
let optsR ← IO.mkRef (← emptyMap)
|
|
450
|
+
pure { name := "paging"
|
|
451
|
+
, init := fun _ opts => do optsR.set (← toOptsMap opts)
|
|
452
|
+
, hook := fun stage ctx => do
|
|
453
|
+
if stage == "PreSpec" then do
|
|
454
|
+
let o ← optsR.get
|
|
455
|
+
let opname ← SdkUtility.opnameOf ctx
|
|
456
|
+
if opname == "list" then do
|
|
457
|
+
let sizeKey ← optStr o "sizeParam" "limit"
|
|
458
|
+
let pageKey ← optStr o "pageParam" "page"
|
|
459
|
+
let sizeV ← gp o "size"
|
|
460
|
+
let specV ← gp ctx "spec"
|
|
461
|
+
match specV with
|
|
462
|
+
| .map _ => do
|
|
463
|
+
let q ← SdkUtility.gpMap specV "query"
|
|
464
|
+
if !(isNov sizeV) then sp q sizeKey sizeV
|
|
465
|
+
let pageV ← gp o "page"
|
|
466
|
+
if !(isNov pageV) then sp q pageKey pageV
|
|
467
|
+
let b ← trackCtx ctx "paging"
|
|
468
|
+
(newMap #[("pages", .num 0.0), ("items", .num 0.0)])
|
|
469
|
+
bumpNum b "pages" 1.0
|
|
470
|
+
| _ => pure ()
|
|
471
|
+
else if stage == "PreDone" then do
|
|
472
|
+
let opname ← SdkUtility.opnameOf ctx
|
|
473
|
+
if opname == "list" then do
|
|
474
|
+
let res ← gp ctx "result"
|
|
475
|
+
let n ← (match (← gp res "resdata") with
|
|
476
|
+
| .list i => do pure (← listItems i).size
|
|
477
|
+
| _ => pure 0)
|
|
478
|
+
let b ← trackCtx ctx "paging"
|
|
479
|
+
(newMap #[("pages", .num 0.0), ("items", .num 0.0)])
|
|
480
|
+
bumpNum b "items" n.toFloat }
|
|
481
|
+
|
|
482
|
+
-- ---------------------------------------------------------------------------
|
|
483
|
+
-- cost
|
|
484
|
+
-- ---------------------------------------------------------------------------
|
|
485
|
+
-- Prices every transport ATTEMPT and commits the spend once per OPERATION.
|
|
486
|
+
-- Mirrors tm/ts/src/feature/cost/CostFeature.ts.
|
|
487
|
+
--
|
|
488
|
+
-- ORDER MATTERS. Cost must sit INSIDE the cache, or a response served from
|
|
489
|
+
-- cache is charged for money that was never spent.
|
|
490
|
+
|
|
491
|
+
def costFeature : SIO Feature := do
|
|
492
|
+
let optsR ← IO.mkRef (← emptyMap)
|
|
493
|
+
-- Accumulated per call and committed once: adding each attempt to the
|
|
494
|
+
-- running total and subtracting it again loses precision.
|
|
495
|
+
let pendR ← IO.mkRef (← newMap #[("attempts", Value.num 0.0), ("amount", Value.num 0.0),
|
|
496
|
+
("reported", Value.num 0.0), ("estimated", Value.num 0.0),
|
|
497
|
+
("source", Value.str "none")])
|
|
498
|
+
let seqR ← IO.mkRef 0
|
|
499
|
+
|
|
500
|
+
let record : Value → SIO Value := fun ctx => do
|
|
501
|
+
let o ← optsR.get
|
|
502
|
+
let cur ← optStr o "currency" "USD"
|
|
503
|
+
let lim ← optNum o "budget" 0.0
|
|
504
|
+
let total ← newMap #[("calls", Value.num 0.0), ("attempts", Value.num 0.0),
|
|
505
|
+
("amount", Value.num 0.0), ("reported", Value.num 0.0),
|
|
506
|
+
("estimated", Value.num 0.0)]
|
|
507
|
+
let ops ← emptyMap
|
|
508
|
+
let actors ← emptyMap
|
|
509
|
+
let budget ← newMap #[("limit", Value.num lim), ("spent", Value.num 0.0),
|
|
510
|
+
("remaining", Value.num lim), ("exceeded", Value.bool false)]
|
|
511
|
+
trackCtx ctx "cost" (newMap #[("currency", Value.str cur), ("total", total),
|
|
512
|
+
("ops", ops), ("actors", actors), ("budget", budget),
|
|
513
|
+
("last", Value.noval)])
|
|
514
|
+
|
|
515
|
+
let resetPending : SIO Unit := do
|
|
516
|
+
let p ← newMap #[("attempts", Value.num 0.0), ("amount", Value.num 0.0),
|
|
517
|
+
("reported", Value.num 0.0), ("estimated", Value.num 0.0),
|
|
518
|
+
("source", Value.str "none")]
|
|
519
|
+
pendR.set p
|
|
520
|
+
|
|
521
|
+
-- Pricing precedence: a server-stated header beats the rate table, which
|
|
522
|
+
-- beats the flat unit.
|
|
523
|
+
let priceOf : Value → Value → SIO (Float × String) := fun ctx res => do
|
|
524
|
+
let o ← optsR.get
|
|
525
|
+
let perUnit ← optNum o "perUnit" 0.0
|
|
526
|
+
let hname ← optStr o "header" ""
|
|
527
|
+
let hv ← if hname == "" then pure Value.noval else headerCI (← gp res "headers") hname
|
|
528
|
+
let hn := numOf hv (-1.0)
|
|
529
|
+
if hname != "" && hn >= 0.0 then
|
|
530
|
+
pure (hn * perUnit, "header")
|
|
531
|
+
else do
|
|
532
|
+
let rates ← gp o "rates"
|
|
533
|
+
let opname ← SdkUtility.opnameOf ctx
|
|
534
|
+
-- The documented grammar is '<entity>.<op>', then '<op>', then '*'.
|
|
535
|
+
-- Checking only the bare name charged `{'widget.load': 0.25, '*': 0.01}`
|
|
536
|
+
-- a widget load at 0.01, unlike every other port.
|
|
537
|
+
let ent ← gpS (← gp ctx "op") "entity"
|
|
538
|
+
let byEntOp := numOf (← gp rates (ent ++ "." ++ opname)) (-1.0)
|
|
539
|
+
let byOp := numOf (← gp rates opname) (-1.0)
|
|
540
|
+
let byAny := numOf (← gp rates "*") (-1.0)
|
|
541
|
+
if byEntOp >= 0.0 then pure (byEntOp, "table")
|
|
542
|
+
else if byOp >= 0.0 then pure (byOp, "table")
|
|
543
|
+
else if byAny >= 0.0 then pure (byAny, "table")
|
|
544
|
+
else do
|
|
545
|
+
let unit ← optNum o "unit" 0.0
|
|
546
|
+
if unit != 0.0 then pure (unit, "unit") else pure (0.0, "none")
|
|
547
|
+
|
|
548
|
+
let bucketOf : Value → String → SIO Value := fun bucket key => do
|
|
549
|
+
let b ← gp bucket key
|
|
550
|
+
match b with
|
|
551
|
+
| Value.map _ => pure b
|
|
552
|
+
| _ => do
|
|
553
|
+
let m ← newMap #[("calls", Value.num 0.0), ("amount", Value.num 0.0)]
|
|
554
|
+
sp bucket key m
|
|
555
|
+
pure m
|
|
556
|
+
|
|
557
|
+
let commit : Value → SIO Unit := fun ctx => do
|
|
558
|
+
let o ← optsR.get
|
|
559
|
+
let p ← pendR.get
|
|
560
|
+
let rec_ ← record ctx
|
|
561
|
+
|
|
562
|
+
-- A body usage figure prices the WHOLE call, so it replaces the
|
|
563
|
+
-- per-attempt estimate rather than adding to it - and, being
|
|
564
|
+
-- server-stated, the whole amount counts as reported. Read here, not at
|
|
565
|
+
-- the transport seam, because the body is one-shot.
|
|
566
|
+
let path ← optStr o "path" ""
|
|
567
|
+
let perUnit ← optNum o "perUnit" 0.0
|
|
568
|
+
let bodyAmt ← if path == "" then pure (-1.0) else do
|
|
569
|
+
let body ← gp (← gp ctx "result") "body"
|
|
570
|
+
pure (numOf (← getpath body (Value.str path)) (-1.0))
|
|
571
|
+
|
|
572
|
+
-- Bind the pending figures first: `←` cannot be nested inside an
|
|
573
|
+
-- if-then-else that is not itself a `do` block.
|
|
574
|
+
let pendAmount := numOf (← gp p "amount") 0.0
|
|
575
|
+
let pendReported := numOf (← gp p "reported") 0.0
|
|
576
|
+
let pendEstimated := numOf (← gp p "estimated") 0.0
|
|
577
|
+
let amount := if bodyAmt >= 0.0 then bodyAmt * perUnit else pendAmount
|
|
578
|
+
let reported := if bodyAmt >= 0.0 then amount else pendReported
|
|
579
|
+
let estimated := if bodyAmt >= 0.0 then 0.0 else pendEstimated
|
|
580
|
+
if bodyAmt >= 0.0 then sp p "source" (Value.str "body")
|
|
581
|
+
|
|
582
|
+
let total ← gp rec_ "total"
|
|
583
|
+
bumpNum total "amount" amount
|
|
584
|
+
bumpNum total "reported" reported
|
|
585
|
+
bumpNum total "estimated" estimated
|
|
586
|
+
bumpNum total "calls" 1.0
|
|
587
|
+
|
|
588
|
+
let budget ← gp rec_ "budget"
|
|
589
|
+
let lim := numOf (← gp budget "limit") 0.0
|
|
590
|
+
let spent := numOf (← gp total "amount") 0.0
|
|
591
|
+
sp budget "spent" (Value.num spent)
|
|
592
|
+
sp budget "remaining"
|
|
593
|
+
(Value.num (if lim > 0.0 then (if lim - spent > 0.0 then lim - spent else 0.0) else 0.0))
|
|
594
|
+
if lim > 0.0 && spent >= lim then sp budget "exceeded" (Value.bool true)
|
|
595
|
+
|
|
596
|
+
let opname ← SdkUtility.opnameOf ctx
|
|
597
|
+
let actorV ← gp (← gp ctx "ctrl") "actor"
|
|
598
|
+
let actorS := match actorV with | Value.str a => a | _ => ""
|
|
599
|
+
let actor ← if actorS != "" then pure actorS else optStr o "actor" "anonymous"
|
|
600
|
+
|
|
601
|
+
let opB ← bucketOf (← gp rec_ "ops") ("_." ++ opname)
|
|
602
|
+
bumpNum opB "calls" 1.0
|
|
603
|
+
bumpNum opB "amount" amount
|
|
604
|
+
let acB ← bucketOf (← gp rec_ "actors") actor
|
|
605
|
+
bumpNum acB "calls" 1.0
|
|
606
|
+
bumpNum acB "amount" amount
|
|
607
|
+
|
|
608
|
+
let n ← seqR.modifyGet fun n => (n + 1, n + 1)
|
|
609
|
+
let last ← newMap #[("seq", Value.num n.toFloat), ("op", Value.str opname),
|
|
610
|
+
("actor", Value.str actor), ("amount", Value.num amount),
|
|
611
|
+
("currency", ← gp rec_ "currency"), ("source", ← gp p "source"),
|
|
612
|
+
("attempts", ← gp p "attempts")]
|
|
613
|
+
sp rec_ "last" last
|
|
614
|
+
resetPending
|
|
615
|
+
|
|
616
|
+
pure { name := "cost"
|
|
617
|
+
, init := fun ctx opts => do
|
|
618
|
+
let om ← toOptsMap opts
|
|
619
|
+
optsR.set om
|
|
620
|
+
resetPending
|
|
621
|
+
if (← optActive opts) then do
|
|
622
|
+
let _ ← record ctx
|
|
623
|
+
let client ← clientOf ctx
|
|
624
|
+
let inner ← getFetcher client
|
|
625
|
+
setFetcher client fun c u f => do
|
|
626
|
+
-- The transport answers (response, error): a rejecting attempt
|
|
627
|
+
-- still costs, or a run of failures under retry would be free.
|
|
628
|
+
let (res, rerr) ← inner c u f
|
|
629
|
+
let (amount, source) ← priceOf c res
|
|
630
|
+
let p ← pendR.get
|
|
631
|
+
bumpNum p "attempts" 1.0
|
|
632
|
+
bumpNum p "amount" amount
|
|
633
|
+
bumpNum p (if source == "header" then "reported" else "estimated") amount
|
|
634
|
+
sp p "source" (Value.str source)
|
|
635
|
+
let rec_ ← record c
|
|
636
|
+
bumpNum (← gp rec_ "total") "attempts" 1.0
|
|
637
|
+
pure (res, rerr)
|
|
638
|
+
, hook := fun stage ctx => do
|
|
639
|
+
let o ← optsR.get
|
|
640
|
+
if stage == "PrePoint" then do
|
|
641
|
+
let lim ← optNum o "budget" 0.0
|
|
642
|
+
if lim > 0.0 then do
|
|
643
|
+
let rec_ ← record ctx
|
|
644
|
+
let spent := numOf (← gp (← gp rec_ "total") "amount") 0.0
|
|
645
|
+
if spent >= lim then do
|
|
646
|
+
sp (← gp rec_ "budget") "exceeded" (Value.bool true)
|
|
647
|
+
if (← optStr o "onBudget" "warn") == "deny" then do
|
|
648
|
+
let e ← SdkUtility.mkErr "cost_budget"
|
|
649
|
+
("Cost budget of " ++ toString lim ++ " is spent")
|
|
650
|
+
let out ← SdkUtility.gpMap ctx "out"
|
|
651
|
+
sp out "point" e
|
|
652
|
+
else if stage == "PreDone" then do
|
|
653
|
+
-- A cache hit is a real call that cost nothing, so it commits
|
|
654
|
+
-- too: that is the point of ordering cost inside the cache.
|
|
655
|
+
commit ctx
|
|
656
|
+
else if stage == "PreUnexpected" then do
|
|
657
|
+
-- A failed operation never reaches PreDone, so without this its
|
|
658
|
+
-- attempts are priced and then discarded: repeated connection
|
|
659
|
+
-- failures would slip past an onBudget "deny" ceiling, and the
|
|
660
|
+
-- shared pending value would survive to be attributed to the
|
|
661
|
+
-- next successful call. A call that made NO attempt was refused
|
|
662
|
+
-- before the network and must not be counted.
|
|
663
|
+
let p ← pendR.get
|
|
664
|
+
if numOf (← gp p "attempts") 0.0 > 0.0 then commit ctx else resetPending }
|
|
665
|
+
|
|
666
|
+
def streamingFeature : SIO Feature := do
|
|
667
|
+
let optsR ← IO.mkRef (← emptyMap)
|
|
668
|
+
pure { name := "streaming"
|
|
669
|
+
, init := fun _ opts => do optsR.set (← toOptsMap opts)
|
|
670
|
+
, hook := fun stage ctx => do
|
|
671
|
+
if stage == "PreDone" then do
|
|
672
|
+
let res ← gp ctx "result"
|
|
673
|
+
let items ← gp res "resdata"
|
|
674
|
+
match items with
|
|
675
|
+
| .list i => do
|
|
676
|
+
let its ← listItems i
|
|
677
|
+
let b ← trackCtx ctx "streaming"
|
|
678
|
+
(newMap #[("emitted", .num 0.0), ("chunks", .num 0.0)])
|
|
679
|
+
bumpNum b "emitted" its.size.toFloat
|
|
680
|
+
bumpNum b "chunks" 1.0
|
|
681
|
+
| _ => pure () }
|
|
682
|
+
|
|
683
|
+
-- ---------------------------------------------------------------------------
|
|
684
|
+
-- proxy
|
|
685
|
+
-- ---------------------------------------------------------------------------
|
|
686
|
+
|
|
687
|
+
def proxyFeature : SIO Feature := do
|
|
688
|
+
let optsR ← IO.mkRef (← emptyMap)
|
|
689
|
+
pure { name := "proxy"
|
|
690
|
+
, init := fun ctx opts => do
|
|
691
|
+
let om ← toOptsMap opts
|
|
692
|
+
optsR.set om
|
|
693
|
+
if (← optActive opts) then do
|
|
694
|
+
let client ← clientOf ctx
|
|
695
|
+
let inner ← getFetcher client
|
|
696
|
+
setFetcher client fun c u f => do
|
|
697
|
+
let o ← optsR.get
|
|
698
|
+
let purl ← gpS o "url"
|
|
699
|
+
if purl == "" then inner c u f
|
|
700
|
+
else do
|
|
701
|
+
sp f "proxy" (.str purl)
|
|
702
|
+
let proxies ← newMap #[("http", .str purl), ("https", .str purl)]
|
|
703
|
+
sp f "proxies" proxies
|
|
704
|
+
let b ← trackCtx c "proxy"
|
|
705
|
+
(newMap #[("routed", .num 0.0), ("url", .str purl)])
|
|
706
|
+
bumpNum b "routed" 1.0
|
|
707
|
+
inner c u f }
|
|
708
|
+
|
|
709
|
+
-- ---------------------------------------------------------------------------
|
|
710
|
+
-- netsim (offline / latency / failStatus simulation)
|
|
711
|
+
-- ---------------------------------------------------------------------------
|
|
712
|
+
|
|
713
|
+
def netsimFeature : SIO Feature := do
|
|
714
|
+
let optsR ← IO.mkRef (← emptyMap)
|
|
715
|
+
let seedR ← IO.mkRef (12345 : Nat)
|
|
716
|
+
let callR ← IO.mkRef (0 : Nat)
|
|
717
|
+
pure { name := "netsim"
|
|
718
|
+
, init := fun ctx opts => do
|
|
719
|
+
let om ← toOptsMap opts
|
|
720
|
+
optsR.set om
|
|
721
|
+
if (← optActive opts) then do
|
|
722
|
+
let client ← clientOf ctx
|
|
723
|
+
let inner ← getFetcher client
|
|
724
|
+
setFetcher client fun c u f => do
|
|
725
|
+
let o ← optsR.get
|
|
726
|
+
let call := (← callR.get) + 1
|
|
727
|
+
callR.set call
|
|
728
|
+
let applied ← emptyMap
|
|
729
|
+
let b ← trackCtx c "netsim"
|
|
730
|
+
(do let ap ← emptyList; newMap #[("calls", .num 0.0), ("applied", ap)])
|
|
731
|
+
bumpNum b "calls" 1.0
|
|
732
|
+
-- deterministic LCG for latency jitter
|
|
733
|
+
let s := ((← seedR.get) * 1103515245 + 12345) % 2147483648
|
|
734
|
+
seedR.set s
|
|
735
|
+
let lat ← optNum o "latency" 0.0
|
|
736
|
+
if lat > 0.0 then sleepMs lat
|
|
737
|
+
if truthy (← gp o "offline") then do
|
|
738
|
+
sp applied "offline" (.bool true)
|
|
739
|
+
appendTo b "applied" applied
|
|
740
|
+
let e ← SdkUtility.mkErr "netsim_offline"
|
|
741
|
+
("Simulated network offline (URL was: \"" ++ u ++ "\")")
|
|
742
|
+
pure (.noval, some e)
|
|
743
|
+
else do
|
|
744
|
+
let fs ← optNum o "failStatus" 0.0
|
|
745
|
+
if fs > 0.0 then do
|
|
746
|
+
sp applied "failStatus" (.num fs)
|
|
747
|
+
appendTo b "applied" applied
|
|
748
|
+
let resp ← newMap #[("status", .num fs), ("statusText", .str "Simulated"),
|
|
749
|
+
("body", ← emptyMap)]
|
|
750
|
+
pure (resp, none)
|
|
751
|
+
else do
|
|
752
|
+
appendTo b "applied" applied
|
|
753
|
+
inner c u f }
|
|
754
|
+
|
|
755
|
+
-- ---------------------------------------------------------------------------
|
|
756
|
+
-- the catalog
|
|
757
|
+
-- ---------------------------------------------------------------------------
|
|
758
|
+
|
|
759
|
+
/-- Every feature by name (the factory the client uses). -/
|
|
760
|
+
def makeFeature (name : String) : SIO Feature :=
|
|
761
|
+
match name with
|
|
762
|
+
| "log" => logFeature
|
|
763
|
+
| "retry" => retryFeature
|
|
764
|
+
| "timeout" => timeoutFeature
|
|
765
|
+
| "ratelimit" => ratelimitFeature
|
|
766
|
+
| "cache" => cacheFeature
|
|
767
|
+
| "idempotency" => idempotencyFeature
|
|
768
|
+
| "rbac" => rbacFeature
|
|
769
|
+
| "metrics" => metricsFeature
|
|
770
|
+
| "telemetry" => telemetryFeature
|
|
771
|
+
| "debug" => debugFeature
|
|
772
|
+
| "audit" => auditFeature
|
|
773
|
+
| "clienttrack" => clienttrackFeature
|
|
774
|
+
| "paging" => pagingFeature
|
|
775
|
+
| "streaming" => streamingFeature
|
|
776
|
+
| "proxy" => proxyFeature
|
|
777
|
+
| "netsim" => netsimFeature
|
|
778
|
+
| "cost" => costFeature
|
|
779
|
+
| _ => baseFeature
|
|
780
|
+
|
|
781
|
+
/-- The catalog order: transport wrappers compose in this order. -/
|
|
782
|
+
def featureNames : Array String :=
|
|
783
|
+
#["log", "rbac", "idempotency", "clienttrack", "paging", "streaming",
|
|
784
|
+
"metrics", "telemetry", "debug", "audit",
|
|
785
|
+
"cost", "cache", "ratelimit", "timeout", "retry", "proxy", "netsim"]
|
|
786
|
+
|
|
787
|
+
end SdkFeatures
|