@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,809 @@
|
|
|
1
|
+
/- ProjectName SDK request-shaping utilities (the primary utility layer).
|
|
2
|
+
|
|
3
|
+
These are the language-neutral pipeline utilities the shared test corpus
|
|
4
|
+
(.sdk/test/test.json, section `primary`) exercises in every target. The
|
|
5
|
+
context is a struct `Value` map: heap-backed and reference-stable, so the
|
|
6
|
+
utilities mutate it in place exactly as the IORef/pointer-based donors do,
|
|
7
|
+
and nested `ctx.spec` / `ctx.result` handles stay live across calls. -/
|
|
8
|
+
|
|
9
|
+
import VoxgigStruct
|
|
10
|
+
import SdkJson
|
|
11
|
+
|
|
12
|
+
open VoxgigStruct
|
|
13
|
+
|
|
14
|
+
namespace SdkUtility
|
|
15
|
+
|
|
16
|
+
-- ---------------------------------------------------------------------------
|
|
17
|
+
-- Value helpers
|
|
18
|
+
-- ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
def gp (v : Value) (k : String) : SIO Value := getprop v (.str k) .noval
|
|
21
|
+
|
|
22
|
+
def sp (v : Value) (k : String) (x : Value) : SIO Unit := do
|
|
23
|
+
let _ ← setprop v (.str k) x
|
|
24
|
+
|
|
25
|
+
def dp (v : Value) (k : String) : SIO Unit := do
|
|
26
|
+
let _ ← delprop v (.str k)
|
|
27
|
+
|
|
28
|
+
def vs : Value → String
|
|
29
|
+
| .str s => s
|
|
30
|
+
| _ => ""
|
|
31
|
+
|
|
32
|
+
def isNov : Value → Bool
|
|
33
|
+
| .noval => true
|
|
34
|
+
| _ => false
|
|
35
|
+
|
|
36
|
+
def isMapV : Value → Bool
|
|
37
|
+
| .map _ => true
|
|
38
|
+
| _ => false
|
|
39
|
+
|
|
40
|
+
def truthy : Value → Bool
|
|
41
|
+
| .bool b => b
|
|
42
|
+
| _ => false
|
|
43
|
+
|
|
44
|
+
def gpS (v : Value) (k : String) : SIO String := do pure (vs (← gp v k))
|
|
45
|
+
|
|
46
|
+
/-- Field as a map, creating AND attaching an empty map when absent. -/
|
|
47
|
+
def gpMap (v : Value) (k : String) : SIO Value := do
|
|
48
|
+
match (← gp v k) with
|
|
49
|
+
| .map i => pure (.map i)
|
|
50
|
+
| _ => do
|
|
51
|
+
let m ← emptyMap
|
|
52
|
+
sp v k m
|
|
53
|
+
pure m
|
|
54
|
+
|
|
55
|
+
/-- A map view of a value (empty map when it is not a map); does not attach. -/
|
|
56
|
+
def asMap (v : Value) : SIO Value := do
|
|
57
|
+
match v with
|
|
58
|
+
| .map i => pure (.map i)
|
|
59
|
+
| _ => emptyMap
|
|
60
|
+
|
|
61
|
+
/-- An SDK error value: a struct map tagged `__sdkerr__`. -/
|
|
62
|
+
def mkErr (code msg : String) : SIO Value :=
|
|
63
|
+
newMap #[("__sdkerr__", .bool true), ("code", .str code), ("message", .str msg)]
|
|
64
|
+
|
|
65
|
+
def isErrV (v : Value) : SIO Bool := do
|
|
66
|
+
match v with
|
|
67
|
+
| .map _ => pure (truthy (← gp v "__sdkerr__"))
|
|
68
|
+
| _ => pure false
|
|
69
|
+
|
|
70
|
+
-- ---------------------------------------------------------------------------
|
|
71
|
+
-- Operation naming
|
|
72
|
+
-- ---------------------------------------------------------------------------
|
|
73
|
+
|
|
74
|
+
/-- The op-name convention, used only when the API definition names no
|
|
75
|
+
method for the point.
|
|
76
|
+
|
|
77
|
+
NO CATCH-ALL GET. The ts reference returns `methodMap[key]`, which is
|
|
78
|
+
undefined for an op the map does not name — the request is then rejected
|
|
79
|
+
rather than silently issued. A `| _ => "GET"` here turned every
|
|
80
|
+
unrecognised op into a GET, which is both a divergence from the corpus
|
|
81
|
+
(`primary/prepareMethod` case 6, opname "bad", expects no method) and the
|
|
82
|
+
more dangerous of the two behaviours: a mistyped or unsupported op quietly
|
|
83
|
+
fetched. "" is Lean's spelling of the same "no value"; the seven other
|
|
84
|
+
targets that carried this bug answer it identically. -/
|
|
85
|
+
def opMethodOf : String → String
|
|
86
|
+
| "create" => "POST"
|
|
87
|
+
| "update" => "PUT"
|
|
88
|
+
| "load" => "GET"
|
|
89
|
+
| "list" => "GET"
|
|
90
|
+
| "remove" => "DELETE"
|
|
91
|
+
| "patch" => "PATCH"
|
|
92
|
+
| _ => ""
|
|
93
|
+
|
|
94
|
+
def opInputOf : String → String
|
|
95
|
+
| "create" => "data"
|
|
96
|
+
| "update" => "data"
|
|
97
|
+
| _ => "match"
|
|
98
|
+
|
|
99
|
+
/-- The operation name: `ctx.opname`, falling back to `ctx.op.name`. -/
|
|
100
|
+
def opnameOf (ctx : Value) : SIO String := do
|
|
101
|
+
let n ← gpS ctx "opname"
|
|
102
|
+
if n != "" then pure n
|
|
103
|
+
else do gpS (← gp ctx "op") "name"
|
|
104
|
+
|
|
105
|
+
-- ---------------------------------------------------------------------------
|
|
106
|
+
-- makeOptions / makeContext / operator / makeError / done
|
|
107
|
+
-- ---------------------------------------------------------------------------
|
|
108
|
+
|
|
109
|
+
def defaultOptions : SIO Value := do
|
|
110
|
+
let hdr ← newMap #[("content-type", .str "application/json")]
|
|
111
|
+
let ent ← emptyMap
|
|
112
|
+
newMap #[("base", .str "http://localhost:8000"), ("prefix", .str ""),
|
|
113
|
+
("suffix", .str ""), ("headers", hdr), ("entity", ent)]
|
|
114
|
+
|
|
115
|
+
/-- Defaults <- config.options <- options, then every entity gets an alias map. -/
|
|
116
|
+
def makeOptions (config options : Value) : SIO Value := do
|
|
117
|
+
let base ← defaultOptions
|
|
118
|
+
let copts ← asMap (← gp config "options")
|
|
119
|
+
let uopts ← asMap options
|
|
120
|
+
let parts ← newList #[base, copts, uopts]
|
|
121
|
+
let out ← merge parts
|
|
122
|
+
let ent ← gpMap out "entity"
|
|
123
|
+
for k in (← keysof ent) do
|
|
124
|
+
let e ← gp ent k
|
|
125
|
+
match e with
|
|
126
|
+
| .map _ =>
|
|
127
|
+
match (← gp e "alias") with
|
|
128
|
+
| .map _ => pure ()
|
|
129
|
+
| _ => do
|
|
130
|
+
let a ← emptyMap
|
|
131
|
+
sp e "alias" a
|
|
132
|
+
| _ => pure ()
|
|
133
|
+
pure out
|
|
134
|
+
|
|
135
|
+
def makeContext (ctxmap : Value) : SIO Value := do
|
|
136
|
+
let ctx ← if isMapV ctxmap then pure ctxmap else emptyMap
|
|
137
|
+
let opname ← opnameOf ctx
|
|
138
|
+
let op ← gpMap ctx "op"
|
|
139
|
+
if (← gpS op "name") == "" then sp op "name" (.str opname)
|
|
140
|
+
if (← gpS op "input") == "" then sp op "input" (.str (opInputOf opname))
|
|
141
|
+
pure ctx
|
|
142
|
+
|
|
143
|
+
/-- The Operation record (entity/name/input/points) as a plain map. -/
|
|
144
|
+
def operator (inv : Value) : SIO Value := do
|
|
145
|
+
let ent ← gp inv "entity"
|
|
146
|
+
let nm ← gp inv "name"
|
|
147
|
+
let inp ← gp inv "input"
|
|
148
|
+
let pts ← match (← gp inv "points") with
|
|
149
|
+
| .list i => pure (Value.list i)
|
|
150
|
+
| _ => emptyList
|
|
151
|
+
newMap #[("entity", ent), ("name", nm), ("input", inp), ("points", pts)]
|
|
152
|
+
|
|
153
|
+
def sdkNameOf (ctx : Value) : SIO String := do
|
|
154
|
+
let cfg ← gp ctx "config"
|
|
155
|
+
gpS (← gp cfg "main") "name"
|
|
156
|
+
|
|
157
|
+
/-- "<Name>SDK: <opname>: <message>", with the neutral fallbacks. -/
|
|
158
|
+
def makeError (ctx : Value) (errv : Value) : SIO Value := do
|
|
159
|
+
let nm ← sdkNameOf ctx
|
|
160
|
+
let opn ← opnameOf ctx
|
|
161
|
+
let opname := if opn == "" then "unknown operation" else opn
|
|
162
|
+
let m1 ← match errv with
|
|
163
|
+
| .map _ => gpS errv "message"
|
|
164
|
+
| _ => pure ""
|
|
165
|
+
let rerr ← gp (← gp ctx "result") "err"
|
|
166
|
+
let m2 ← match rerr with
|
|
167
|
+
| .map _ => gpS rerr "message"
|
|
168
|
+
| _ => pure ""
|
|
169
|
+
let msg := if m1 != "" then m1 else if m2 != "" then m2 else "unknown error"
|
|
170
|
+
mkErr "sdk_error" (nm ++ "SDK: " ++ opname ++ ": " ++ msg)
|
|
171
|
+
|
|
172
|
+
/-- Terminal step: the result payload, or the pipeline error. -/
|
|
173
|
+
def done (ctx : Value) : SIO (Value × Option Value) := do
|
|
174
|
+
let res ← gp ctx "result"
|
|
175
|
+
if truthy (← gp res "ok") then pure ((← gp res "resdata"), none)
|
|
176
|
+
else do
|
|
177
|
+
let e ← makeError ctx .noval
|
|
178
|
+
pure (.noval, some e)
|
|
179
|
+
|
|
180
|
+
-- ---------------------------------------------------------------------------
|
|
181
|
+
-- param / prepare*
|
|
182
|
+
-- ---------------------------------------------------------------------------
|
|
183
|
+
|
|
184
|
+
/-- Resolve a parameter by name across reqmatch/match/reqdata/data, honouring
|
|
185
|
+
the point's alias map (and recording the reverse alias on the spec). -/
|
|
186
|
+
def param (ctx : Value) (paramdef : Value) : SIO Value := do
|
|
187
|
+
let point ← gp ctx "point"
|
|
188
|
+
let specV ← gp ctx "spec"
|
|
189
|
+
let mtch ← gp ctx "match"
|
|
190
|
+
let reqmatch ← gp ctx "reqmatch"
|
|
191
|
+
let dat ← gp ctx "data"
|
|
192
|
+
let reqdata ← gp ctx "reqdata"
|
|
193
|
+
let key ← match paramdef with
|
|
194
|
+
| .str s => pure s
|
|
195
|
+
| _ => gpS paramdef "name"
|
|
196
|
+
let aliasV ← gp point "alias"
|
|
197
|
+
let akey ← match aliasV with
|
|
198
|
+
| .map _ => gpS aliasV key
|
|
199
|
+
| _ => pure ""
|
|
200
|
+
let v1 ← gp reqmatch key
|
|
201
|
+
let v2 ← if isNov v1 then gp mtch key else pure v1
|
|
202
|
+
let v3 ← if isNov v2 && akey != "" then do
|
|
203
|
+
match specV with
|
|
204
|
+
| .map _ => do
|
|
205
|
+
let sa ← gpMap specV "alias"
|
|
206
|
+
sp sa akey (.str key)
|
|
207
|
+
| _ => pure ()
|
|
208
|
+
gp reqmatch akey
|
|
209
|
+
else pure v2
|
|
210
|
+
let v4 ← if isNov v3 then gp reqdata key else pure v3
|
|
211
|
+
let v5 ← if isNov v4 then gp dat key else pure v4
|
|
212
|
+
if isNov v5 && akey != "" then do
|
|
213
|
+
let a ← gp reqdata akey
|
|
214
|
+
if isNov a then gp dat akey else pure a
|
|
215
|
+
else pure v5
|
|
216
|
+
|
|
217
|
+
/-- Path params declared by the point's args, resolved through `param`. -/
|
|
218
|
+
def prepareParams (ctx : Value) : SIO Value := do
|
|
219
|
+
let point ← gp ctx "point"
|
|
220
|
+
let args ← gp point "args"
|
|
221
|
+
let out ← emptyMap
|
|
222
|
+
match (← gp args "params") with
|
|
223
|
+
| .list i =>
|
|
224
|
+
for pd in (← listItems i) do
|
|
225
|
+
let v ← param ctx pd
|
|
226
|
+
if !(isNov v) then do
|
|
227
|
+
let nm ← match pd with
|
|
228
|
+
| .str s => pure s
|
|
229
|
+
| _ => gpS pd "name"
|
|
230
|
+
if nm != "" then sp out nm v
|
|
231
|
+
| _ => pure ()
|
|
232
|
+
pure out
|
|
233
|
+
|
|
234
|
+
/-- Everything in reqmatch that is NOT a declared path param becomes query. -/
|
|
235
|
+
def prepareQuery (ctx : Value) : SIO Value := do
|
|
236
|
+
let point ← gp ctx "point"
|
|
237
|
+
let reqmatch ← asMap (← gp ctx "reqmatch")
|
|
238
|
+
let names ← match (← gp point "params") with
|
|
239
|
+
| .list i => do pure ((← listItems i).map vs)
|
|
240
|
+
| _ => pure #[]
|
|
241
|
+
let out ← emptyMap
|
|
242
|
+
for k in (← keysof reqmatch) do
|
|
243
|
+
let v ← gp reqmatch k
|
|
244
|
+
if !(isNov v) && !(names.contains k) then sp out k v
|
|
245
|
+
pure out
|
|
246
|
+
|
|
247
|
+
/-- Assemble the path template from `point.parts`. This is `struct.join` with
|
|
248
|
+
the url flag — NOT a plain intercalate: empty segments are dropped (a doubled
|
|
249
|
+
slash changes the URL and 404s on strict routers) and there is no leading
|
|
250
|
+
slash, because makeUrl joins base/prefix/path/suffix with `joinurl`. -/
|
|
251
|
+
def preparePath (ctx : Value) : SIO String := do
|
|
252
|
+
let point ← gp ctx "point"
|
|
253
|
+
join (← gp point "parts") (sep := .str "/") (url := true)
|
|
254
|
+
|
|
255
|
+
/-- The API definition is authoritative: a POST-only or PATCH-based API
|
|
256
|
+
exposes `update` as POST or PATCH, not the PUT the op name implies. Only
|
|
257
|
+
fall back to the op-name convention when the point has no method. -/
|
|
258
|
+
def prepareMethod (ctx : Value) : SIO String := do
|
|
259
|
+
let m ← gpS (← gp ctx "point") "method"
|
|
260
|
+
if m != "" then pure m.toUpper
|
|
261
|
+
else pure (opMethodOf (← opnameOf ctx))
|
|
262
|
+
|
|
263
|
+
def prepareHeaders (ctx : Value) : SIO Value := do
|
|
264
|
+
let options ← gp ctx "options"
|
|
265
|
+
match (← gp options "headers") with
|
|
266
|
+
| .map i => clone (.map i)
|
|
267
|
+
| _ => newMap #[("content-type", .str "application/json")]
|
|
268
|
+
|
|
269
|
+
/-- apikey (with the configured auth prefix) becomes the authorization header. -/
|
|
270
|
+
def prepareAuth (ctx : Value) : SIO (Value × Option Value) := do
|
|
271
|
+
let specV ← gp ctx "spec"
|
|
272
|
+
match specV with
|
|
273
|
+
| .map _ => do
|
|
274
|
+
let headers ← gpMap specV "headers"
|
|
275
|
+
let options ← gp ctx "options"
|
|
276
|
+
-- `auth: null` is the documented way to suppress auth outright: NO
|
|
277
|
+
-- authorization header, whatever the apikey says. Without this the
|
|
278
|
+
-- withheld credential goes on the wire.
|
|
279
|
+
--
|
|
280
|
+
-- The ports that run options through validate against an optspec carrying
|
|
281
|
+
-- an `auth` default can use absence as the signal (validate guarantees the
|
|
282
|
+
-- key is present otherwise). lean's makeOptions has no optspec, so `auth`
|
|
283
|
+
-- is ABSENT in the ordinary case and absence must stay the ordinary case.
|
|
284
|
+
-- getpropRaw is the only reader that tells a STORED null from an absent
|
|
285
|
+
-- key - gp collapses both to .noval - so the stored null alone suppresses.
|
|
286
|
+
let authRaw ← getpropRaw options "auth"
|
|
287
|
+
let apikey ← gpS options "apikey"
|
|
288
|
+
if authRaw == .null || apikey == "" then do
|
|
289
|
+
dp headers "authorization"
|
|
290
|
+
pure (specV, none)
|
|
291
|
+
else do
|
|
292
|
+
let pfx ← gpS (← gp options "auth") "prefix"
|
|
293
|
+
let authval := if pfx != "" then pfx ++ " " ++ apikey else apikey
|
|
294
|
+
sp headers "authorization" (.str authval)
|
|
295
|
+
pure (specV, none)
|
|
296
|
+
| _ => do
|
|
297
|
+
let e ← mkErr "auth_no_spec" "Expected context spec property to be defined."
|
|
298
|
+
pure (.noval, some e)
|
|
299
|
+
|
|
300
|
+
-- ---------------------------------------------------------------------------
|
|
301
|
+
-- transforms
|
|
302
|
+
-- ---------------------------------------------------------------------------
|
|
303
|
+
|
|
304
|
+
def transformRequest (ctx : Value) : SIO Value := do
|
|
305
|
+
let specV ← gp ctx "spec"
|
|
306
|
+
match specV with
|
|
307
|
+
| .map _ => sp specV "step" (.str "reqform")
|
|
308
|
+
| _ => pure ()
|
|
309
|
+
let point ← gp ctx "point"
|
|
310
|
+
let reqdata ← gp ctx "reqdata"
|
|
311
|
+
match (← gp point "transform") with
|
|
312
|
+
| .map i => do
|
|
313
|
+
let reqform ← gp (.map i) "req"
|
|
314
|
+
if isNov reqform then pure reqdata
|
|
315
|
+
else do
|
|
316
|
+
let input ← newMap #[("reqdata", reqdata)]
|
|
317
|
+
transform input reqform
|
|
318
|
+
| _ => pure reqdata
|
|
319
|
+
|
|
320
|
+
def transformResponse (ctx : Value) : SIO Value := do
|
|
321
|
+
let specV ← gp ctx "spec"
|
|
322
|
+
match specV with
|
|
323
|
+
| .map _ => sp specV "step" (.str "resform")
|
|
324
|
+
| _ => pure ()
|
|
325
|
+
let resultV ← gp ctx "result"
|
|
326
|
+
match resultV with
|
|
327
|
+
| .map _ => do
|
|
328
|
+
if !(truthy (← gp resultV "ok")) then pure .noval
|
|
329
|
+
else do
|
|
330
|
+
let point ← gp ctx "point"
|
|
331
|
+
match (← gp point "transform") with
|
|
332
|
+
| .map i => do
|
|
333
|
+
let resform ← gp (.map i) "res"
|
|
334
|
+
if isNov resform then pure .noval
|
|
335
|
+
else do
|
|
336
|
+
let ok ← gp resultV "ok"
|
|
337
|
+
let status ← gp resultV "status"
|
|
338
|
+
let stt ← gp resultV "statusText"
|
|
339
|
+
let hdr ← gp resultV "headers"
|
|
340
|
+
let body ← gp resultV "body"
|
|
341
|
+
let resdata ← gp resultV "resdata"
|
|
342
|
+
let resmatch ← gp resultV "resmatch"
|
|
343
|
+
let input ← newMap #[("ok", ok), ("status", status), ("statusText", stt),
|
|
344
|
+
("headers", hdr), ("body", body),
|
|
345
|
+
("resdata", resdata), ("resmatch", resmatch)]
|
|
346
|
+
transform input resform
|
|
347
|
+
| _ => pure .noval
|
|
348
|
+
| _ => pure .noval
|
|
349
|
+
|
|
350
|
+
/-- The request body: only data-input operations carry one. -/
|
|
351
|
+
def prepareBody (ctx : Value) : SIO Value := do
|
|
352
|
+
if opInputOf (← opnameOf ctx) == "data" then transformRequest ctx
|
|
353
|
+
else pure .noval
|
|
354
|
+
|
|
355
|
+
-- ---------------------------------------------------------------------------
|
|
356
|
+
-- graphql (transport)
|
|
357
|
+
--
|
|
358
|
+
-- GraphQL transport. API-INDEPENDENT: every GraphQL SDK this generator
|
|
359
|
+
-- produces uses this code unchanged. The API-specific part — which operations
|
|
360
|
+
-- exist and what each one's document is — is model data, computed once by
|
|
361
|
+
-- apidef and emitted into Config.
|
|
362
|
+
--
|
|
363
|
+
-- Two jobs:
|
|
364
|
+
--
|
|
365
|
+
-- graphqlBody — build { query, variables } for a point, binding the op's
|
|
366
|
+
-- arguments to the document's declared variables.
|
|
367
|
+
--
|
|
368
|
+
-- graphqlErrors — lift a GraphQL failure into an SDK error. GraphQL reports
|
|
369
|
+
-- failures as a top-level `errors` array under HTTP 200, so
|
|
370
|
+
-- the status-driven path in resultBasic never sees them.
|
|
371
|
+
-- ---------------------------------------------------------------------------
|
|
372
|
+
|
|
373
|
+
/-- Content type every GraphQL-over-HTTP request uses. -/
|
|
374
|
+
def graphqlContentType : String := "application/json"
|
|
375
|
+
|
|
376
|
+
private def hasSub (hay needle : String) : Bool :=
|
|
377
|
+
1 < (hay.splitOn needle).length
|
|
378
|
+
|
|
379
|
+
/-- Map a GraphQL error to the same error codes the HTTP path produces, so a
|
|
380
|
+
caller handles auth or rate limiting identically on both transports. Servers
|
|
381
|
+
put the machine-readable code in `extensions.code`; Linear-style APIs use
|
|
382
|
+
`extensions.type`. -/
|
|
383
|
+
def graphqlErrorCode (gqlerr : Value) : SIO String := do
|
|
384
|
+
let ext ← gp gqlerr "extensions"
|
|
385
|
+
let c ← gpS ext "code"
|
|
386
|
+
let code ← if c == "" then gpS ext "type" else pure c
|
|
387
|
+
let raw := code.toUpper
|
|
388
|
+
if hasSub raw "AUTH" || hasSub raw "FORBIDDEN" || hasSub raw "UNAUTHENTICATED" then
|
|
389
|
+
pure "request_auth"
|
|
390
|
+
else if hasSub raw "RATELIMIT" || hasSub raw "RATE_LIMIT" || hasSub raw "TOO_MANY" then
|
|
391
|
+
pure "request_ratelimit"
|
|
392
|
+
else if hasSub raw "BAD_USER_INPUT" || hasSub raw "VALIDATION" || hasSub raw "INVALID" then
|
|
393
|
+
pure "request_invalid"
|
|
394
|
+
else
|
|
395
|
+
pure "request_graphql"
|
|
396
|
+
|
|
397
|
+
/-- Build the request body for a GraphQL point.
|
|
398
|
+
|
|
399
|
+
Variables come from the op's own arguments: a named variable binds to the
|
|
400
|
+
like-named argument (`from`), and the input-object variable (empty `from`)
|
|
401
|
+
takes the request data as a whole — which is what makes a generated
|
|
402
|
+
create/update call look exactly like its REST equivalent. -/
|
|
403
|
+
def graphqlBody (ctx : Value) : SIO Value := do
|
|
404
|
+
let gql ← gp (← gp ctx "point") "graphql"
|
|
405
|
+
match gql with
|
|
406
|
+
| .map _ => do
|
|
407
|
+
-- reqmatch/reqdata hold the caller's arguments for THIS call; data/match
|
|
408
|
+
-- hold the entity's current state. Which pair depends on whether the op
|
|
409
|
+
-- takes match or data input. A named variable falls back to the current
|
|
410
|
+
-- state, so updating a loaded entity with just {title} still binds the
|
|
411
|
+
-- stored id the mutation requires.
|
|
412
|
+
let datainput := opInputOf (← opnameOf ctx) == "data"
|
|
413
|
+
let reqsrc ← asMap (← gp ctx (if datainput then "reqdata" else "reqmatch"))
|
|
414
|
+
let datasrc ← asMap (← gp ctx (if datainput then "data" else "match"))
|
|
415
|
+
let variables ← emptyMap
|
|
416
|
+
let varlist ← match (← gp gql "vars") with
|
|
417
|
+
| .list i => listItems i
|
|
418
|
+
| _ => pure #[]
|
|
419
|
+
for spec in varlist do
|
|
420
|
+
match spec with
|
|
421
|
+
| .map _ => do
|
|
422
|
+
let name ← gpS spec "name"
|
|
423
|
+
-- `from` is a Lean keyword, so the binding cannot take the field's
|
|
424
|
+
-- own name.
|
|
425
|
+
let varFrom ← gpS spec "from"
|
|
426
|
+
if name != "" then
|
|
427
|
+
if varFrom == "" then do
|
|
428
|
+
-- The input object IS the request body. Strip the action
|
|
429
|
+
-- selector, which is an SDK-side point discriminator, not an API
|
|
430
|
+
-- field.
|
|
431
|
+
let body ← emptyMap
|
|
432
|
+
for k in (← keysof reqsrc) do
|
|
433
|
+
if k != "$action" then sp body k (← gp reqsrc k)
|
|
434
|
+
sp variables name body
|
|
435
|
+
else do
|
|
436
|
+
-- Only send variables the caller actually supplied: sending an
|
|
437
|
+
-- explicit null would clear a field on many APIs.
|
|
438
|
+
let v0 ← gp reqsrc varFrom
|
|
439
|
+
let v ← if isNullish v0 then gp datasrc varFrom else pure v0
|
|
440
|
+
if !(isNullish v) then sp variables name v
|
|
441
|
+
| _ => pure ()
|
|
442
|
+
newMap #[("query", ← gp gql "doc"), ("variables", variables)]
|
|
443
|
+
| _ => pure .noval
|
|
444
|
+
|
|
445
|
+
/-- Inspect a decoded GraphQL response body and record a failure when the
|
|
446
|
+
server reported one. Returns true when an error was recorded.
|
|
447
|
+
|
|
448
|
+
Partial data (`data` alongside `errors`) is treated as failure: the REST
|
|
449
|
+
surface has no partial-success concept, and silently returning half an object
|
|
450
|
+
would be worse than failing. -/
|
|
451
|
+
def graphqlErrors (ctx : Value) : SIO Bool := do
|
|
452
|
+
let resultV ← gp ctx "result"
|
|
453
|
+
match resultV with
|
|
454
|
+
| .map _ => do
|
|
455
|
+
if (← gpS (← gp ctx "point") "kind") != "graphql" then pure false
|
|
456
|
+
else
|
|
457
|
+
let errors ← match (← gp (← gp resultV "body") "errors") with
|
|
458
|
+
| .list i => listItems i
|
|
459
|
+
| _ => pure #[]
|
|
460
|
+
if errors.size == 0 then pure false
|
|
461
|
+
else do
|
|
462
|
+
let first := errors[0]!
|
|
463
|
+
let m0 ← gpS first "message"
|
|
464
|
+
let m1 := if m0 == "" then "graphql error" else m0
|
|
465
|
+
let msg := if 1 < errors.size then
|
|
466
|
+
m1 ++ " (+" ++ toString (errors.size - 1) ++ " more)" else m1
|
|
467
|
+
let e ← mkErr (← graphqlErrorCode first) ("graphql: " ++ msg)
|
|
468
|
+
sp resultV "err" e
|
|
469
|
+
sp resultV "ok" (.bool false)
|
|
470
|
+
pure true
|
|
471
|
+
| _ => pure false
|
|
472
|
+
|
|
473
|
+
-- ---------------------------------------------------------------------------
|
|
474
|
+
-- result assembly
|
|
475
|
+
-- ---------------------------------------------------------------------------
|
|
476
|
+
|
|
477
|
+
def resultBasic (ctx : Value) : SIO Unit := do
|
|
478
|
+
let responseV ← gp ctx "response"
|
|
479
|
+
let resultV ← gp ctx "result"
|
|
480
|
+
match responseV, resultV with
|
|
481
|
+
| .map _, .map _ => do
|
|
482
|
+
let st ← gp responseV "status"
|
|
483
|
+
let stt ← gp responseV "statusText"
|
|
484
|
+
sp resultV "status" st
|
|
485
|
+
sp resultV "statusText" stt
|
|
486
|
+
let status := jsNumber st
|
|
487
|
+
if status >= 400.0 then do
|
|
488
|
+
let msg := "request: " ++ numToString status ++ ": " ++ vs stt
|
|
489
|
+
let prev ← gp resultV "err"
|
|
490
|
+
let pm ← match prev with
|
|
491
|
+
| .map _ => gpS prev "message"
|
|
492
|
+
| _ => pure ""
|
|
493
|
+
let full := if pm != "" then pm ++ ": " ++ msg else msg
|
|
494
|
+
let e ← mkErr "request_status" full
|
|
495
|
+
sp resultV "err" e
|
|
496
|
+
else pure ()
|
|
497
|
+
| _, _ => pure ()
|
|
498
|
+
|
|
499
|
+
/-- Response headers land on the result with lower-cased keys. -/
|
|
500
|
+
def resultHeaders (ctx : Value) : SIO Unit := do
|
|
501
|
+
let resultV ← gp ctx "result"
|
|
502
|
+
match resultV with
|
|
503
|
+
| .map _ => do
|
|
504
|
+
let out ← emptyMap
|
|
505
|
+
let responseV ← gp ctx "response"
|
|
506
|
+
match responseV with
|
|
507
|
+
| .map _ => do
|
|
508
|
+
match (← gp responseV "headers") with
|
|
509
|
+
| .map i =>
|
|
510
|
+
for k in (← keysof (.map i)) do
|
|
511
|
+
let v ← gp (.map i) k
|
|
512
|
+
sp out k.toLower v
|
|
513
|
+
| _ => pure ()
|
|
514
|
+
| _ => pure ()
|
|
515
|
+
sp resultV "headers" out
|
|
516
|
+
| _ => pure ()
|
|
517
|
+
|
|
518
|
+
def resultBody (ctx : Value) : SIO Unit := do
|
|
519
|
+
let responseV ← gp ctx "response"
|
|
520
|
+
let resultV ← gp ctx "result"
|
|
521
|
+
match responseV, resultV with
|
|
522
|
+
| .map _, .map _ => do
|
|
523
|
+
let body ← gp responseV "body"
|
|
524
|
+
if !(isNov body) then sp resultV "body" body
|
|
525
|
+
| _, _ => pure ()
|
|
526
|
+
|
|
527
|
+
-- ---------------------------------------------------------------------------
|
|
528
|
+
-- spec / url / request / response
|
|
529
|
+
-- ---------------------------------------------------------------------------
|
|
530
|
+
|
|
531
|
+
def makeSpec (ctx : Value) : SIO (Value × Option Value) := do
|
|
532
|
+
let options ← gp ctx "options"
|
|
533
|
+
let base ← gpS options "base"
|
|
534
|
+
let pfx ← gpS options "prefix"
|
|
535
|
+
let suffix ← gpS options "suffix"
|
|
536
|
+
let point ← gp ctx "point"
|
|
537
|
+
let parts ← match (← gp point "parts") with
|
|
538
|
+
| .list i => pure (Value.list i)
|
|
539
|
+
| _ => emptyList
|
|
540
|
+
let aliasm ← emptyMap
|
|
541
|
+
let spec ← newMap #[("base", .str base), ("prefix", .str pfx),
|
|
542
|
+
("suffix", .str suffix), ("parts", parts),
|
|
543
|
+
("alias", aliasm), ("step", .str "start")]
|
|
544
|
+
sp ctx "spec" spec
|
|
545
|
+
sp spec "method" (.str (← prepareMethod ctx))
|
|
546
|
+
sp spec "path" (.str (← preparePath ctx))
|
|
547
|
+
sp spec "params" (← prepareParams ctx)
|
|
548
|
+
sp spec "query" (← prepareQuery ctx)
|
|
549
|
+
let headers ← prepareHeaders ctx
|
|
550
|
+
sp spec "headers" headers
|
|
551
|
+
if (← gpS point "kind") == "graphql" then do
|
|
552
|
+
-- GraphQL addresses one endpoint: no path parts, no query string, and the
|
|
553
|
+
-- body carries the operation. prepareBody is skipped deliberately — it
|
|
554
|
+
-- only emits a body for data-input ops, whereas every GraphQL op posts
|
|
555
|
+
-- one, including load/list/remove.
|
|
556
|
+
sp spec "body" (← graphqlBody ctx)
|
|
557
|
+
sp spec "path" (.str "")
|
|
558
|
+
-- prepareQuery already copied the op's match arguments into the query
|
|
559
|
+
-- string. Those same values are bound as operation variables, so leaving
|
|
560
|
+
-- them would send /graphql?id=i1.
|
|
561
|
+
sp spec "query" (← emptyMap)
|
|
562
|
+
sp headers "content-type" (.str graphqlContentType)
|
|
563
|
+
pure (spec, none)
|
|
564
|
+
|
|
565
|
+
/-- base/prefix/path/suffix joined, `{param}` substituted, query appended. -/
|
|
566
|
+
def makeUrl (ctx : Value) : SIO (Value × Option Value) := do
|
|
567
|
+
let specV ← gp ctx "spec"
|
|
568
|
+
match specV with
|
|
569
|
+
| .map _ => do
|
|
570
|
+
let base ← gpS specV "base"
|
|
571
|
+
let pfx ← gpS specV "prefix"
|
|
572
|
+
let path ← gpS specV "path"
|
|
573
|
+
let suffix ← gpS specV "suffix"
|
|
574
|
+
let arr ← newList #[.str base, .str pfx, .str path, .str suffix]
|
|
575
|
+
let url0 ← joinurl arr
|
|
576
|
+
let resmatch ← emptyMap
|
|
577
|
+
let mut url := url0
|
|
578
|
+
let params ← gp specV "params"
|
|
579
|
+
for k in (← keysof params) do
|
|
580
|
+
let v ← gp params k
|
|
581
|
+
if !(isNov v) then do
|
|
582
|
+
let enc ← escurl (.str (vs v))
|
|
583
|
+
sp resmatch k v
|
|
584
|
+
url := url.replace ("{" ++ k ++ "}") (vs enc)
|
|
585
|
+
let query ← gp specV "query"
|
|
586
|
+
let mut qsep := "?"
|
|
587
|
+
for k in (← keysof query) do
|
|
588
|
+
let v ← gp query k
|
|
589
|
+
if !(isNov v) then do
|
|
590
|
+
let ek ← escurl (.str k)
|
|
591
|
+
let ev ← escurl (.str (vs v))
|
|
592
|
+
sp resmatch k v
|
|
593
|
+
url := url ++ qsep ++ vs ek ++ "=" ++ vs ev
|
|
594
|
+
qsep := "&"
|
|
595
|
+
let resultV ← gp ctx "result"
|
|
596
|
+
match resultV with
|
|
597
|
+
| .map _ => sp resultV "resmatch" resmatch
|
|
598
|
+
| _ => pure ()
|
|
599
|
+
pure (.str url, none)
|
|
600
|
+
| _ => do
|
|
601
|
+
let e ← mkErr "url_no_spec" "Expected context spec property to be defined."
|
|
602
|
+
pure (.str "", some e)
|
|
603
|
+
|
|
604
|
+
/-- Prepare the transport call: the response/result carriers must exist. -/
|
|
605
|
+
def makeRequest (ctx : Value) : SIO (Value × Option Value) := do
|
|
606
|
+
let specV ← gp ctx "spec"
|
|
607
|
+
match specV with
|
|
608
|
+
| .map _ => sp specV "step" (.str "request")
|
|
609
|
+
| _ => pure ()
|
|
610
|
+
let _ ← gpMap ctx "response"
|
|
611
|
+
let _ ← gpMap ctx "result"
|
|
612
|
+
pure ((← gp ctx "response"), none)
|
|
613
|
+
|
|
614
|
+
/-- The initial result carrier the pipeline fills in. -/
|
|
615
|
+
def makeResult (ctx : Value) : SIO Value := do
|
|
616
|
+
let resmatch ← emptyMap
|
|
617
|
+
let res ← newMap #[("ok", .bool false), ("status", .num (-1.0)),
|
|
618
|
+
("statusText", .str ""), ("resmatch", resmatch)]
|
|
619
|
+
sp ctx "result" res
|
|
620
|
+
pure res
|
|
621
|
+
|
|
622
|
+
/-- How many path segments a point has, and whether its path ends in a
|
|
623
|
+
parameter. A record route ends in the record's identifier (/boards/{id});
|
|
624
|
+
a cross-reference that also returns the entity ends in the relationship's
|
|
625
|
+
name (/posts/{id}/author). That, then fewest segments, is what tells the
|
|
626
|
+
entity's own route from a cross-reference. The same rule runs at
|
|
627
|
+
generation time, in helpers/opShape.ts — both sides must move together. -/
|
|
628
|
+
def pointShape (pt : Value) : SIO (Nat × Bool) := do
|
|
629
|
+
match (← gp pt "parts") with
|
|
630
|
+
| .list i =>
|
|
631
|
+
let items ← listItems i
|
|
632
|
+
if items.size == 0 then pure (0, false)
|
|
633
|
+
else pure (items.size, (vs items[items.size - 1]!).startsWith "{")
|
|
634
|
+
| _ => pure (0, false)
|
|
635
|
+
|
|
636
|
+
/-- Select the endpoint for this operation: the single point, else the first
|
|
637
|
+
whose `select.exist` keys are all present and whose `$action` agrees. -/
|
|
638
|
+
def makePoint (ctx : Value) : SIO Value := do
|
|
639
|
+
let op ← gp ctx "op"
|
|
640
|
+
let matchV ← gp ctx "reqmatch"
|
|
641
|
+
let dataV ← gp ctx "reqdata"
|
|
642
|
+
let pts ← match (← gp op "points") with
|
|
643
|
+
| .list i => listItems i
|
|
644
|
+
| _ => pure #[]
|
|
645
|
+
if pts.size == 0 then pure .noval
|
|
646
|
+
else if pts.size == 1 then do
|
|
647
|
+
sp ctx "point" (pts[0]!)
|
|
648
|
+
pure (pts[0]!)
|
|
649
|
+
else do
|
|
650
|
+
let mut chosen : Value := .noval
|
|
651
|
+
for pt in pts do
|
|
652
|
+
if isNov chosen then
|
|
653
|
+
let sel ← gp pt "select"
|
|
654
|
+
let mut ok := true
|
|
655
|
+
match (← gp sel "exist") with
|
|
656
|
+
| .list i =>
|
|
657
|
+
for ek in (← listItems i) do
|
|
658
|
+
let k := vs ek
|
|
659
|
+
if isNov (← gp matchV k) && isNov (← gp dataV k) then ok := false
|
|
660
|
+
| _ => pure ()
|
|
661
|
+
if ok && ((← gp sel "$action") == (← gp matchV "$action")) then
|
|
662
|
+
chosen := pt
|
|
663
|
+
-- select.exist can list more than the params needed to pick a point (for
|
|
664
|
+
-- /boards/{id} it is Trello's 17 optional query-includes), so a plain
|
|
665
|
+
-- {id} call matches NOTHING and this loop chose no point at all. Fall
|
|
666
|
+
-- back to the entity's own route rather than sending nowhere.
|
|
667
|
+
if isNov chosen then
|
|
668
|
+
let mut best := pts[0]!
|
|
669
|
+
for cand in pts do
|
|
670
|
+
let (candLen, candTerm) ← pointShape cand
|
|
671
|
+
let (bestLen, bestTerm) ← pointShape best
|
|
672
|
+
if candTerm && !bestTerm then
|
|
673
|
+
best := cand
|
|
674
|
+
else if candTerm == bestTerm && candLen < bestLen then
|
|
675
|
+
best := cand
|
|
676
|
+
chosen := best
|
|
677
|
+
if !(isNov chosen) then sp ctx "point" chosen
|
|
678
|
+
pure chosen
|
|
679
|
+
|
|
680
|
+
/-- The transport payload: method, headers and (for data ops) the body. -/
|
|
681
|
+
def makeFetchDef (ctx : Value) : SIO Value := do
|
|
682
|
+
let specV ← gp ctx "spec"
|
|
683
|
+
let method ← gpS specV "method"
|
|
684
|
+
let headers ← asMap (← gp specV "headers")
|
|
685
|
+
let out ← newMap #[("method", .str method), ("headers", headers)]
|
|
686
|
+
let body ← gp specV "body"
|
|
687
|
+
if !(isNov body) then sp out "body" body
|
|
688
|
+
pure out
|
|
689
|
+
|
|
690
|
+
/-- Remove configured sensitive keys (options.clean.keys) from a value. -/
|
|
691
|
+
def clean (ctx : Value) (v : Value) : SIO Value := do
|
|
692
|
+
let options ← gp ctx "options"
|
|
693
|
+
let keysStr ← gpS (← gp options "clean") "keys"
|
|
694
|
+
let drop := if keysStr == "" then #[] else (keysStr.splitOn ",").toArray
|
|
695
|
+
let out ← clone v
|
|
696
|
+
match out with
|
|
697
|
+
| .map _ =>
|
|
698
|
+
for k in drop do
|
|
699
|
+
if k != "" then dp out k
|
|
700
|
+
| _ => pure ()
|
|
701
|
+
pure out
|
|
702
|
+
|
|
703
|
+
/-- The transport step. In test mode the client answers from its own store, so
|
|
704
|
+
this is only reached for live calls; the concrete send is injected by the
|
|
705
|
+
runtime (SdkRuntime.curlFetch) to keep this layer transport-agnostic. -/
|
|
706
|
+
def fetcher (ctx : Value) (url : String) (fetchdef : Value) : SIO Value := do
|
|
707
|
+
let out ← emptyMap
|
|
708
|
+
sp out "url" (.str url)
|
|
709
|
+
sp out "fetchdef" fetchdef
|
|
710
|
+
sp ctx "fetch" out
|
|
711
|
+
pure out
|
|
712
|
+
|
|
713
|
+
-- ---------------------------------------------------------------------------
|
|
714
|
+
-- features
|
|
715
|
+
-- ---------------------------------------------------------------------------
|
|
716
|
+
|
|
717
|
+
/-- The client's ordered feature list. -/
|
|
718
|
+
def featureList (client : Value) : SIO Value := do
|
|
719
|
+
match (← gp client "features") with
|
|
720
|
+
| .list i => pure (Value.list i)
|
|
721
|
+
| _ => do
|
|
722
|
+
let l ← emptyList
|
|
723
|
+
sp client "features" l
|
|
724
|
+
pure l
|
|
725
|
+
|
|
726
|
+
/-- Add a feature, honouring `__before__` / `__after__` / `__replace__`
|
|
727
|
+
placement against the named feature (append by default). -/
|
|
728
|
+
def featureAdd (client : Value) (feat : Value) : SIO Unit := do
|
|
729
|
+
let feats ← featureList client
|
|
730
|
+
let items ← match feats with
|
|
731
|
+
| .list i => listItems i
|
|
732
|
+
| _ => pure #[]
|
|
733
|
+
let nm ← gpS feat "name"
|
|
734
|
+
let before ← gpS feat "__before__"
|
|
735
|
+
let after ← gpS feat "__after__"
|
|
736
|
+
let replace ← gpS feat "__replace__"
|
|
737
|
+
let mut out : Array Value := #[]
|
|
738
|
+
let mut placed := false
|
|
739
|
+
for f in items do
|
|
740
|
+
let fn ← gpS f "name"
|
|
741
|
+
if replace != "" && fn == replace then
|
|
742
|
+
out := out.push feat
|
|
743
|
+
placed := true
|
|
744
|
+
else if before != "" && fn == before then
|
|
745
|
+
out := out.push feat
|
|
746
|
+
out := out.push f
|
|
747
|
+
placed := true
|
|
748
|
+
else if after != "" && fn == after then
|
|
749
|
+
out := out.push f
|
|
750
|
+
out := out.push feat
|
|
751
|
+
placed := true
|
|
752
|
+
else if fn == nm then
|
|
753
|
+
out := out.push feat
|
|
754
|
+
placed := true
|
|
755
|
+
else
|
|
756
|
+
out := out.push f
|
|
757
|
+
if !placed then out := out.push feat
|
|
758
|
+
sp client "features" (← newList out)
|
|
759
|
+
|
|
760
|
+
/-- Initialise every active feature (idempotent: marks `inited`). -/
|
|
761
|
+
def featureInit (client : Value) (ctx : Value) : SIO Unit := do
|
|
762
|
+
let feats ← featureList client
|
|
763
|
+
match feats with
|
|
764
|
+
| .list i =>
|
|
765
|
+
for f in (← listItems i) do
|
|
766
|
+
if truthy (← gp f "active") && !(truthy (← gp f "inited")) then do
|
|
767
|
+
sp f "inited" (.bool true)
|
|
768
|
+
sp f "ctx" ctx
|
|
769
|
+
| _ => pure ()
|
|
770
|
+
|
|
771
|
+
/-- Dispatch a pipeline stage to every active feature that defines the hook. -/
|
|
772
|
+
def featureHook (client : Value) (stage : String) (ctx : Value) : SIO Unit := do
|
|
773
|
+
let feats ← featureList client
|
|
774
|
+
match feats with
|
|
775
|
+
| .list i =>
|
|
776
|
+
for f in (← listItems i) do
|
|
777
|
+
if truthy (← gp f "active") then do
|
|
778
|
+
let hooks ← gp f "hooks"
|
|
779
|
+
let h ← gp hooks stage
|
|
780
|
+
match h with
|
|
781
|
+
| .func fid => do
|
|
782
|
+
let inj ← getDummyInj
|
|
783
|
+
let _ ← callFunc fid inj ctx stage ctx
|
|
784
|
+
pure ()
|
|
785
|
+
| _ => pure ()
|
|
786
|
+
| _ => pure ()
|
|
787
|
+
|
|
788
|
+
/-- Fold the transport response into the result (basic/headers/body/resform). -/
|
|
789
|
+
def makeResponse (ctx : Value) : SIO (Value × Option Value) := do
|
|
790
|
+
let specV ← gp ctx "spec"
|
|
791
|
+
let responseV ← gp ctx "response"
|
|
792
|
+
let resultV ← gp ctx "result"
|
|
793
|
+
match specV, responseV, resultV with
|
|
794
|
+
| .map _, .map _, .map _ => do
|
|
795
|
+
sp specV "step" (.str "response")
|
|
796
|
+
resultBasic ctx
|
|
797
|
+
resultHeaders ctx
|
|
798
|
+
resultBody ctx
|
|
799
|
+
-- GraphQL reports failures as a top-level `errors` array under HTTP 200,
|
|
800
|
+
-- so resultBasic's status check never sees them. Lift them here, before
|
|
801
|
+
-- the response transform tries to unwrap data that is not there.
|
|
802
|
+
let _ ← graphqlErrors ctx
|
|
803
|
+
let _ ← transformResponse ctx
|
|
804
|
+
let errv ← gp resultV "err"
|
|
805
|
+
if !(← isErrV errv) then sp resultV "ok" (.bool true)
|
|
806
|
+
pure (responseV, none)
|
|
807
|
+
| _, _, _ => pure (.noval, none)
|
|
808
|
+
|
|
809
|
+
end SdkUtility
|