@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,104 @@
|
|
|
1
|
+
|
|
2
|
+
import { cmp, Content, isAuthActive, envName, canonKey, entityIdField, opRequestShape } from '@voxgig/sdkgen'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
KIT,
|
|
6
|
+
getModelPath,
|
|
7
|
+
nom,
|
|
8
|
+
} from '@voxgig/apidef'
|
|
9
|
+
|
|
10
|
+
import { hsVarName } from './utility_haskell'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
// A type-correct Haskell `Value` literal for a param.
|
|
14
|
+
function hsLit(type: any, placeholder: string = 'example'): string {
|
|
15
|
+
const k = canonKey(type)
|
|
16
|
+
if ('INTEGER' === k || 'NUMBER' === k) return 'VNum 1'
|
|
17
|
+
if ('BOOLEAN' === k) return 'VBool True'
|
|
18
|
+
if ('ARRAY' === k || 'OBJECT' === k) return 'VNoval'
|
|
19
|
+
return `VStr "${placeholder}"`
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
const ReadmeTopQuick = cmp(function ReadmeTopQuick(props: any) {
|
|
24
|
+
const { target, ctx$: { model } } = props
|
|
25
|
+
|
|
26
|
+
const entity = getModelPath(model, `main.${KIT}.entity`)
|
|
27
|
+
|
|
28
|
+
const exampleEntity = Object.values(entity).find((e: any) => e.active !== false) as any
|
|
29
|
+
|
|
30
|
+
const authActive = isAuthActive(model)
|
|
31
|
+
|
|
32
|
+
Content(`\`\`\`haskell
|
|
33
|
+
`)
|
|
34
|
+
if (authActive) {
|
|
35
|
+
Content(`import System.Environment (lookupEnv)
|
|
36
|
+
import qualified SdkClient as Sdk
|
|
37
|
+
import VoxgigStruct (Value (..), emptyMap)
|
|
38
|
+
import SdkHelpers (jo)
|
|
39
|
+
|
|
40
|
+
main :: IO ()
|
|
41
|
+
main = do
|
|
42
|
+
mkey <- lookupEnv "${envName(model)}_APIKEY"
|
|
43
|
+
opts <- jo [("apikey", maybe VNoval VStr mkey)]
|
|
44
|
+
sdk <- Sdk.newSdk opts
|
|
45
|
+
`)
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
Content(`import qualified SdkClient as Sdk
|
|
49
|
+
import VoxgigStruct (Value (..), emptyMap)
|
|
50
|
+
import SdkHelpers (jo)
|
|
51
|
+
|
|
52
|
+
main :: IO ()
|
|
53
|
+
main = do
|
|
54
|
+
sdk <- Sdk.newSdk0
|
|
55
|
+
`)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (exampleEntity) {
|
|
59
|
+
const eName = nom(exampleEntity, 'Name')
|
|
60
|
+
const eFn = hsVarName(exampleEntity.name)
|
|
61
|
+
const opnames = Object.keys(exampleEntity.op || {})
|
|
62
|
+
const idF = entityIdField(exampleEntity)
|
|
63
|
+
|
|
64
|
+
if (opnames.includes('list')) {
|
|
65
|
+
Content(`
|
|
66
|
+
-- List all ${eName.toLowerCase()}s (one ENTITY per record, raises on error)
|
|
67
|
+
ent <- Sdk.${eFn} sdk VNoval
|
|
68
|
+
match <- emptyMap
|
|
69
|
+
ctrl <- emptyMap
|
|
70
|
+
${eFn}s <- Sdk.eList ent match ctrl
|
|
71
|
+
mapM_ (\\en -> print =<< Sdk.eDataGet en) ${eFn}s
|
|
72
|
+
`)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (opnames.includes('load')) {
|
|
76
|
+
const loadItems = opRequestShape(exampleEntity, 'load').items
|
|
77
|
+
.filter((it: any) => !it.optional || it.name === idF)
|
|
78
|
+
.sort((a: any, b: any) =>
|
|
79
|
+
(a.name === idF ? 0 : 1) - (b.name === idF ? 0 : 1))
|
|
80
|
+
const loadArg = 0 < loadItems.length
|
|
81
|
+
? `[${loadItems.map((it: any) =>
|
|
82
|
+
`("${it.name}", ${hsLit(it.type,
|
|
83
|
+
it.name === idF ? 'example_id' : 'example_' + it.name)})`).join(', ')}]`
|
|
84
|
+
: '[]'
|
|
85
|
+
Content(`
|
|
86
|
+
-- Load a specific ${eName.toLowerCase()} (returns the ENTITY, raises on error)
|
|
87
|
+
ent2 <- Sdk.${eFn} sdk VNoval
|
|
88
|
+
m <- jo ${loadArg}
|
|
89
|
+
ctrl2 <- emptyMap
|
|
90
|
+
${eFn} <- Sdk.eLoad ent2 m ctrl2
|
|
91
|
+
print =<< Sdk.eDataGet ${eFn}
|
|
92
|
+
`)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
Content(`\`\`\`
|
|
97
|
+
`)
|
|
98
|
+
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
export {
|
|
103
|
+
ReadmeTopQuick
|
|
104
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
|
|
2
|
+
import { cmp, Content, canonKey, entityIdField, pickExampleEntity, opRequestShape } from '@voxgig/sdkgen'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
KIT,
|
|
6
|
+
getModelPath,
|
|
7
|
+
nom,
|
|
8
|
+
} from '@voxgig/apidef'
|
|
9
|
+
|
|
10
|
+
import { hsVarName } from './utility_haskell'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
// A type-correct Haskell `Value` literal for a field's canonical type.
|
|
14
|
+
function hsLit(type: any): string {
|
|
15
|
+
const k = canonKey(type)
|
|
16
|
+
if ('INTEGER' === k || 'NUMBER' === k) return 'VNum 1'
|
|
17
|
+
if ('BOOLEAN' === k) return 'VBool True'
|
|
18
|
+
if ('ARRAY' === k || 'OBJECT' === k) return 'VNoval'
|
|
19
|
+
return 'VStr "example"'
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
const ReadmeTopTest = cmp(function ReadmeTopTest(props: any) {
|
|
24
|
+
const { target, ctx$: { model } } = props
|
|
25
|
+
|
|
26
|
+
const entity = getModelPath(model, `main.${KIT}.entity`)
|
|
27
|
+
|
|
28
|
+
const { entity: exampleEntity, primaryOp } = pickExampleEntity(entity)
|
|
29
|
+
|
|
30
|
+
Content(`\`\`\`haskell
|
|
31
|
+
import qualified SdkClient as Sdk
|
|
32
|
+
import VoxgigStruct (Value (..), emptyMap)
|
|
33
|
+
import SdkHelpers (jo)
|
|
34
|
+
|
|
35
|
+
main :: IO ()
|
|
36
|
+
main = do
|
|
37
|
+
sdk <- Sdk.testSdk0
|
|
38
|
+
`)
|
|
39
|
+
|
|
40
|
+
if (exampleEntity && primaryOp) {
|
|
41
|
+
const eName = nom(exampleEntity, 'Name')
|
|
42
|
+
const eFn = hsVarName(exampleEntity.name)
|
|
43
|
+
const idF = entityIdField(exampleEntity)
|
|
44
|
+
const isMatchOp = 'load' === primaryOp || 'remove' === primaryOp
|
|
45
|
+
let argExpr = 'emptyMap'
|
|
46
|
+
if (isMatchOp) {
|
|
47
|
+
const items = opRequestShape(exampleEntity, primaryOp).items
|
|
48
|
+
.filter((it: any) => !it.optional || it.name === idF)
|
|
49
|
+
.sort((a: any, b: any) =>
|
|
50
|
+
(a.name === idF ? 0 : 1) - (b.name === idF ? 0 : 1))
|
|
51
|
+
argExpr = 0 < items.length
|
|
52
|
+
? `jo [${items.map((it: any) =>
|
|
53
|
+
`("${it.name}", ${it.name === idF ? 'VStr "test01"' : hsLit(it.type)})`).join(', ')}]`
|
|
54
|
+
: 'emptyMap'
|
|
55
|
+
} else if ('create' === primaryOp || 'update' === primaryOp) {
|
|
56
|
+
const items = opRequestShape(exampleEntity, primaryOp).items
|
|
57
|
+
.filter((it: any) => it.name !== idF && it.name !== 'id')
|
|
58
|
+
const required = items.filter((it: any) => !it.optional)
|
|
59
|
+
const chosen = required.length ? required : items.slice(0, 3)
|
|
60
|
+
argExpr = `jo [${chosen.map((it: any) => `("${it.name}", ${hsLit(it.type)})`).join(', ')}]`
|
|
61
|
+
}
|
|
62
|
+
const opCap = 'e' + primaryOp.charAt(0).toUpperCase() + primaryOp.slice(1)
|
|
63
|
+
const resVar = hsVarName(exampleEntity.name) + ('list' === primaryOp ? 's' : '')
|
|
64
|
+
Content(` ent <- Sdk.${eFn} sdk VNoval
|
|
65
|
+
arg <- ${argExpr}
|
|
66
|
+
ctrl <- emptyMap
|
|
67
|
+
${resVar} <- Sdk.${opCap} ent arg ctrl
|
|
68
|
+
print ${resVar}
|
|
69
|
+
`)
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
Content(`\`\`\`
|
|
73
|
+
`)
|
|
74
|
+
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
export {
|
|
79
|
+
ReadmeTopTest
|
|
80
|
+
}
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
|
|
2
|
+
import type {
|
|
3
|
+
ModelEntity
|
|
4
|
+
} from '@voxgig/apidef'
|
|
5
|
+
|
|
6
|
+
import { cmp, each, Folder, File, Content, entityCollection } from '@voxgig/sdkgen'
|
|
7
|
+
|
|
8
|
+
import { hsVarName } from './utility_haskell'
|
|
9
|
+
import { ReadmeExamplesTest } from './ReadmeExamplesTest_haskell'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
// test/SdkGenTests.hs — model-driven per-entity tests: an instance test, a
|
|
13
|
+
// CRUD basic-flow test driven through the in-memory mock (test mode), and a
|
|
14
|
+
// direct() call test against an injected system.fetch mock. Only ops the
|
|
15
|
+
// entity actually defines are exercised.
|
|
16
|
+
const Test = cmp(function Test(props: any) {
|
|
17
|
+
const { model } = props.ctx$
|
|
18
|
+
const { target } = props
|
|
19
|
+
|
|
20
|
+
const entity = each(entityCollection(model))
|
|
21
|
+
.filter((e: any) => false !== e.active)
|
|
22
|
+
|
|
23
|
+
Folder({ name: 'test' }, () => {
|
|
24
|
+
|
|
25
|
+
// Structural gate over the documented Haskell examples (emits
|
|
26
|
+
// test/TReadmeExamples.hs); wired into genTests below so it runs in the
|
|
27
|
+
// standard Runner.
|
|
28
|
+
ReadmeExamplesTest({ target })
|
|
29
|
+
|
|
30
|
+
File({ name: 'SdkGenTests.' + target.ext }, () => {
|
|
31
|
+
|
|
32
|
+
let calls = ''
|
|
33
|
+
let defs = ''
|
|
34
|
+
|
|
35
|
+
each(entity, (e: any) => {
|
|
36
|
+
const fn = hsVarName(e.name)
|
|
37
|
+
const ops = Object.keys(e.op || {})
|
|
38
|
+
const hasCreate = ops.includes('create')
|
|
39
|
+
const hasList = ops.includes('list')
|
|
40
|
+
const hasLoad = ops.includes('load')
|
|
41
|
+
const hasUpdate = ops.includes('update')
|
|
42
|
+
const hasRemove = ops.includes('remove')
|
|
43
|
+
|
|
44
|
+
// Pick a text field to mutate in update (first non-id field with a
|
|
45
|
+
// string value in the new-ref data, else "name").
|
|
46
|
+
let updField = 'name'
|
|
47
|
+
try {
|
|
48
|
+
const nf = e.fields || {}
|
|
49
|
+
const cand = Object.keys(nf).find((k) => k !== 'id' && !k.endsWith('$'))
|
|
50
|
+
if (cand) updField = cand
|
|
51
|
+
} catch (_e) { }
|
|
52
|
+
|
|
53
|
+
const instFn = `${fn}InstanceTest`
|
|
54
|
+
const basicFn = `${fn}BasicTest`
|
|
55
|
+
const directFn = `${fn}DirectTest`
|
|
56
|
+
|
|
57
|
+
calls += ` ${instFn} c\n`
|
|
58
|
+
calls += ` ${basicFn} c\n`
|
|
59
|
+
calls += ` ${directFn} c\n`
|
|
60
|
+
|
|
61
|
+
defs += `
|
|
62
|
+
${instFn} :: Counters -> IO ()
|
|
63
|
+
${instFn} c = runTest c "${e.name}.instance" $ do
|
|
64
|
+
sdk <- C.testSdk0
|
|
65
|
+
ent <- C.${fn} sdk VNoval
|
|
66
|
+
pure (eName ent == "${e.name}")
|
|
67
|
+
|
|
68
|
+
${basicFn} :: Counters -> IO ()
|
|
69
|
+
${basicFn} c = do
|
|
70
|
+
fixture <- loadFixture "${e.Name}"
|
|
71
|
+
existing <- getp fixture "existing"
|
|
72
|
+
opts <- jo [("entity", existing)]
|
|
73
|
+
`
|
|
74
|
+
// Basic flow. Each op is an independent runTest.
|
|
75
|
+
if (hasList) {
|
|
76
|
+
defs += ` runTest c "${e.name}.list" $ do
|
|
77
|
+
sdk <- C.testSdk opts VNoval
|
|
78
|
+
ent <- C.${fn} sdk VNoval
|
|
79
|
+
em1 <- emptyMap; em2 <- emptyMap
|
|
80
|
+
lst <- eList ent em1 em2
|
|
81
|
+
-- \`list\` resolves to one ENTITY per record; the record is reached
|
|
82
|
+
-- through eDataGet. See AGENTS.md "Entity operations return ENTITIES".
|
|
83
|
+
ok <- mapM (\\en -> ismap <$> eDataGet en) lst
|
|
84
|
+
pure (all id ok)
|
|
85
|
+
`
|
|
86
|
+
}
|
|
87
|
+
if (hasLoad) {
|
|
88
|
+
defs += ` runTest c "${e.name}.load" $ do
|
|
89
|
+
sdk <- C.testSdk opts VNoval
|
|
90
|
+
ent <- C.${fn} sdk VNoval
|
|
91
|
+
entmap <- getp existing "${e.name}"
|
|
92
|
+
ids <- keysof entmap
|
|
93
|
+
case ids of
|
|
94
|
+
[] -> pure True
|
|
95
|
+
(id0 : _) -> do
|
|
96
|
+
m <- jo [("id", VStr id0)]; ctrl <- emptyMap
|
|
97
|
+
loaded <- eLoad ent m ctrl
|
|
98
|
+
ld <- eDataGet loaded
|
|
99
|
+
lid <- getp ld "id"
|
|
100
|
+
pure (ismap ld && vstring lid == id0)
|
|
101
|
+
`
|
|
102
|
+
}
|
|
103
|
+
if (hasCreate) {
|
|
104
|
+
defs += ` runTest c "${e.name}.create" $ do
|
|
105
|
+
sdk <- C.testSdk opts VNoval
|
|
106
|
+
ent <- C.${fn} sdk VNoval
|
|
107
|
+
d <- newRefData fixture "${e.name}"
|
|
108
|
+
ctrl <- emptyMap
|
|
109
|
+
created <- eCreate ent d ctrl
|
|
110
|
+
cd <- eDataGet created
|
|
111
|
+
cid <- getp cd "id"
|
|
112
|
+
pure (ismap cd && not (isNoval cid))
|
|
113
|
+
`
|
|
114
|
+
}
|
|
115
|
+
if (hasCreate && hasUpdate) {
|
|
116
|
+
defs += ` runTest c "${e.name}.update" $ do
|
|
117
|
+
sdk <- C.testSdk opts VNoval
|
|
118
|
+
ent <- C.${fn} sdk VNoval
|
|
119
|
+
d <- newRefData fixture "${e.name}"
|
|
120
|
+
ctrl <- emptyMap
|
|
121
|
+
created <- eCreate ent d ctrl
|
|
122
|
+
cd <- eDataGet created
|
|
123
|
+
cid <- getp cd "id"
|
|
124
|
+
upd <- jo [("id", cid), ("${updField}", VStr "UpdatedMark")]
|
|
125
|
+
ctrl2 <- emptyMap
|
|
126
|
+
updated <- eUpdate ent upd ctrl2
|
|
127
|
+
ud <- eDataGet updated
|
|
128
|
+
uv <- getp ud "${updField}"
|
|
129
|
+
pure (ismap ud && vstring uv == "UpdatedMark")
|
|
130
|
+
`
|
|
131
|
+
}
|
|
132
|
+
if (hasCreate && hasRemove) {
|
|
133
|
+
defs += ` runTest c "${e.name}.remove" $ do
|
|
134
|
+
sdk <- C.testSdk opts VNoval
|
|
135
|
+
ent <- C.${fn} sdk VNoval
|
|
136
|
+
d <- newRefData fixture "${e.name}"
|
|
137
|
+
ctrl <- emptyMap
|
|
138
|
+
created <- eCreate ent d ctrl
|
|
139
|
+
cd <- eDataGet created
|
|
140
|
+
cid <- getp cd "id"
|
|
141
|
+
rm <- jo [("id", cid)]; ctrl2 <- emptyMap
|
|
142
|
+
-- \`remove\` resolves to the entity, marked. It KEEPS the data it held.
|
|
143
|
+
removed <- eRemove ent rm ctrl2
|
|
144
|
+
gone <- readIORef (eDeleted removed)
|
|
145
|
+
rd <- eDataGet removed
|
|
146
|
+
rid <- getp rd "id"
|
|
147
|
+
pure (gone && vstring rid == vstring cid)
|
|
148
|
+
`
|
|
149
|
+
}
|
|
150
|
+
// An op-less entity (no list/load/create — e.g. a bare path entity)
|
|
151
|
+
// appends no runTest, leaving the do-block ending on `opts <- jo [...]`
|
|
152
|
+
// (a bind), which is illegal as the final statement. Terminate it.
|
|
153
|
+
if (!hasList && !hasLoad && !hasCreate) {
|
|
154
|
+
defs += ` pure ()\n`
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Direct call test (via injected system.fetch mock).
|
|
158
|
+
defs += `
|
|
159
|
+
${directFn} :: Counters -> IO ()
|
|
160
|
+
${directFn} c = runTest c "${e.name}.direct" $ do
|
|
161
|
+
calls <- newIORef (0 :: Int)
|
|
162
|
+
let mock = VFunc (\\_ _ _ _ -> do
|
|
163
|
+
modifyIORef calls (+ 1)
|
|
164
|
+
d <- jo [("id", VStr "direct01")]
|
|
165
|
+
jo [("status", VNum 200), ("statusText", VStr "OK"), ("json", jsonThunk d)])
|
|
166
|
+
sys <- jo [("fetch", mock)]
|
|
167
|
+
opts <- jo [("base", VStr "http://localhost:8080"), ("system", sys)]
|
|
168
|
+
sdk <- C.newSdk opts
|
|
169
|
+
args <- jo [("path", VStr "/${e.name}/x"), ("method", VStr "GET")]
|
|
170
|
+
res <- F.direct sdk args
|
|
171
|
+
ok <- getp res "ok"
|
|
172
|
+
st <- getp res "status"
|
|
173
|
+
dat <- getp res "data"
|
|
174
|
+
did <- getp dat "id"
|
|
175
|
+
n <- readIORef calls
|
|
176
|
+
pure (isTrueV ok && toInt st == 200 && vstring did == "direct01" && n == 1)
|
|
177
|
+
`
|
|
178
|
+
|
|
179
|
+
// PR review #4: entity eStream(action, args, callopts) runs the op
|
|
180
|
+
// through the full pipeline and returns a lazy list. Fallback (no
|
|
181
|
+
// streaming feature) yields the materialised items; with the streaming
|
|
182
|
+
// feature active it yields from the streaming iterator (chunkSize
|
|
183
|
+
// groups into batches). Needs a list op; seeds three records.
|
|
184
|
+
if (hasList) {
|
|
185
|
+
const streamFn = `${fn}StreamTest`
|
|
186
|
+
calls += ` ${streamFn} c\n`
|
|
187
|
+
defs += `
|
|
188
|
+
${streamFn} :: Counters -> IO ()
|
|
189
|
+
${streamFn} c = do
|
|
190
|
+
let mkSeed = do
|
|
191
|
+
r1 <- jo [("id", VStr "S1"), ("name", VStr "a")]
|
|
192
|
+
r2 <- jo [("id", VStr "S2"), ("name", VStr "b")]
|
|
193
|
+
r3 <- jo [("id", VStr "S3"), ("name", VStr "c")]
|
|
194
|
+
recs <- jo [("S1", r1), ("S2", r2), ("S3", r3)]
|
|
195
|
+
jo [("${e.name}", recs)]
|
|
196
|
+
hasStreaming = do
|
|
197
|
+
sdk0 <- C.testSdk0
|
|
198
|
+
fs <- getp (clConfig sdk0) "feature"
|
|
199
|
+
st <- getp fs "streaming"
|
|
200
|
+
pure (not (isNoval st))
|
|
201
|
+
runTest c "${e.name}.stream" $ do
|
|
202
|
+
seed <- mkSeed; opts <- jo [("entity", seed)]
|
|
203
|
+
sdk <- C.testSdk opts VNoval
|
|
204
|
+
ent <- C.${fn} sdk VNoval
|
|
205
|
+
em1 <- emptyMap
|
|
206
|
+
items <- eStream ent "list" em1 VNoval
|
|
207
|
+
pure (length items == 3 && (case items of (x : _) -> ismap x; [] -> False))
|
|
208
|
+
runTest c "${e.name}.stream_signal" $ do
|
|
209
|
+
seed <- mkSeed; opts <- jo [("entity", seed)]
|
|
210
|
+
sdk <- C.testSdk opts VNoval
|
|
211
|
+
ent <- C.${fn} sdk VNoval
|
|
212
|
+
em1 <- emptyMap
|
|
213
|
+
n <- newIORef (0 :: Int)
|
|
214
|
+
let sig = vfunc0 (do modifyIORef n (+ 1); v <- readIORef n; pure (VBool (v >= 2)))
|
|
215
|
+
co <- jo [("signal", sig)]
|
|
216
|
+
items <- eStream ent "list" em1 co
|
|
217
|
+
pure (length items == 1)
|
|
218
|
+
runTest c "${e.name}.stream_active" $ do
|
|
219
|
+
hs <- hasStreaming
|
|
220
|
+
if not hs then pure True else do
|
|
221
|
+
seed <- mkSeed; opts <- jo [("entity", seed)]
|
|
222
|
+
stg <- jo [("active", VBool True)]; strm <- jo [("streaming", stg)]; sopts <- jo [("feature", strm)]
|
|
223
|
+
sdk <- C.testSdk opts sopts
|
|
224
|
+
ent <- C.${fn} sdk VNoval
|
|
225
|
+
em1 <- emptyMap
|
|
226
|
+
items <- eStream ent "list" em1 VNoval
|
|
227
|
+
pure (length items == 3)
|
|
228
|
+
runTest c "${e.name}.stream_chunk" $ do
|
|
229
|
+
hs <- hasStreaming
|
|
230
|
+
if not hs then pure True else do
|
|
231
|
+
seed <- mkSeed; opts <- jo [("entity", seed)]
|
|
232
|
+
stg <- jo [("active", VBool True), ("chunkSize", VNum 2)]; strm <- jo [("streaming", stg)]; sopts <- jo [("feature", strm)]
|
|
233
|
+
sdk <- C.testSdk opts sopts
|
|
234
|
+
ent <- C.${fn} sdk VNoval
|
|
235
|
+
em1 <- emptyMap
|
|
236
|
+
batches <- eStream ent "list" em1 VNoval
|
|
237
|
+
pure (length batches == 2)
|
|
238
|
+
`
|
|
239
|
+
}
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
Content(`-- Generated model-driven entity + direct tests.
|
|
243
|
+
{-# LANGUAGE ScopedTypeVariables #-}
|
|
244
|
+
|
|
245
|
+
module SdkGenTests (genTests) where
|
|
246
|
+
|
|
247
|
+
import Control.Exception (SomeException, try)
|
|
248
|
+
import Data.IORef
|
|
249
|
+
|
|
250
|
+
import VoxgigStruct (Value (..), emptyMap, keysof, ismap, islist, isNoval, clone)
|
|
251
|
+
import SdkTypes
|
|
252
|
+
import SdkHelpers
|
|
253
|
+
import qualified SdkFeatures as F
|
|
254
|
+
import qualified SdkClient as C
|
|
255
|
+
import qualified TReadmeExamples
|
|
256
|
+
import Testutil
|
|
257
|
+
import SdkJson (jsonRead)
|
|
258
|
+
|
|
259
|
+
-- Load an entity fixture (../.sdk/test/entity/<name>/<Name>TestData.json).
|
|
260
|
+
loadFixture :: String -> IO Value
|
|
261
|
+
loadFixture entName = do
|
|
262
|
+
-- The fixture DIRECTORY is the snake_case entity name (create_result), so a
|
|
263
|
+
-- plain lowercase of the CamelCase entName (createresult) misses the
|
|
264
|
+
-- underscores for multi-word entities. Convert CamelCase -> snake_case.
|
|
265
|
+
let lname = camelToSnake entName
|
|
266
|
+
raw <- readFile ("../.sdk/test/entity/" ++ lname ++ "/" ++ entName ++ "TestData.json")
|
|
267
|
+
jsonRead raw
|
|
268
|
+
where
|
|
269
|
+
toLowerCh ch = if ch >= 'A' && ch <= 'Z' then toEnum (fromEnum ch + 32) else ch
|
|
270
|
+
camelToSnake [] = []
|
|
271
|
+
camelToSnake (c0 : rest) = toLowerCh c0 : go rest
|
|
272
|
+
go [] = []
|
|
273
|
+
go (c : cs)
|
|
274
|
+
| c >= 'A' && c <= 'Z' = '_' : toLowerCh c : go cs
|
|
275
|
+
| otherwise = c : go cs
|
|
276
|
+
|
|
277
|
+
-- The first new-ref data map for an entity (fixture.new.<entity>.<ref0>).
|
|
278
|
+
newRefData :: Value -> String -> IO Value
|
|
279
|
+
newRefData fixture entName = do
|
|
280
|
+
newEnts <- getpathS fixture ("new." ++ entName)
|
|
281
|
+
refs <- keysof newEnts
|
|
282
|
+
case refs of
|
|
283
|
+
[] -> emptyMap
|
|
284
|
+
(r0 : _) -> do d <- getp newEnts r0; clone d
|
|
285
|
+
|
|
286
|
+
genTests :: Counters -> IO ()
|
|
287
|
+
genTests c = do
|
|
288
|
+
TReadmeExamples.tests c
|
|
289
|
+
${calls}${defs}`)
|
|
290
|
+
})
|
|
291
|
+
})
|
|
292
|
+
})
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
export {
|
|
296
|
+
Test
|
|
297
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"esModuleInterop": true,
|
|
4
|
+
"module": "nodenext",
|
|
5
|
+
"noEmitOnError": true,
|
|
6
|
+
"outDir":"../dist",
|
|
7
|
+
"rootDir":".",
|
|
8
|
+
"resolveJsonModule": true,
|
|
9
|
+
"sourceMap": true,
|
|
10
|
+
"strict": true,
|
|
11
|
+
"target": "es2022",
|
|
12
|
+
"declaration": true,
|
|
13
|
+
"declarationDir": "../dist"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import * as Path from 'node:path'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
clone,
|
|
5
|
+
walk,
|
|
6
|
+
} from '@voxgig/struct'
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
function projectPath(suffix?: string): string {
|
|
10
|
+
return Path.normalize(Path.join(__dirname, '../../..', suffix ?? ''))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
// Haskell reserved words that cannot be used as identifiers.
|
|
15
|
+
const HS_RESERVED = new Set<string>([
|
|
16
|
+
'case', 'class', 'data', 'default', 'deriving', 'do', 'else', 'foreign',
|
|
17
|
+
'if', 'import', 'in', 'infix', 'infixl', 'infixr', 'instance', 'let',
|
|
18
|
+
'module', 'newtype', 'of', 'then', 'type', 'where', 'as', 'hiding',
|
|
19
|
+
'qualified',
|
|
20
|
+
])
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
// A collision-free lower-camel Haskell identifier for a model name.
|
|
24
|
+
function hsVarName(name: string): string {
|
|
25
|
+
let s = String(name).replace(/[^a-zA-Z0-9_]/g, '_')
|
|
26
|
+
if (s.length === 0) {
|
|
27
|
+
s = 'x'
|
|
28
|
+
}
|
|
29
|
+
// Identifiers must start with a lowercase letter.
|
|
30
|
+
s = s.charAt(0).toLowerCase() + s.slice(1)
|
|
31
|
+
if (!/^[a-z_]/.test(s)) {
|
|
32
|
+
s = 'e_' + s
|
|
33
|
+
}
|
|
34
|
+
return HS_RESERVED.has(s) ? s + '_' : s
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
// A Haskell string literal (7-bit safe: non-printable / non-ASCII use the
|
|
39
|
+
// decimal numeric escape with a `\&` separator so digits never merge).
|
|
40
|
+
function hsString(s: string): string {
|
|
41
|
+
let out = '"'
|
|
42
|
+
for (const ch of String(s)) {
|
|
43
|
+
const code = ch.codePointAt(0) as number
|
|
44
|
+
if (ch === '"') out += '\\"'
|
|
45
|
+
else if (ch === '\\') out += '\\\\'
|
|
46
|
+
else if (ch === '\n') out += '\\n'
|
|
47
|
+
else if (ch === '\t') out += '\\t'
|
|
48
|
+
else if (ch === '\r') out += '\\r'
|
|
49
|
+
else if (code >= 32 && code < 127) out += ch
|
|
50
|
+
else out += '\\' + code + '\\&'
|
|
51
|
+
}
|
|
52
|
+
return out + '"'
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
// Render a JSON-shaped value as a Haskell `CV` literal (the generated
|
|
57
|
+
// SdkConfig realises it with buildCV). Empty map/list render as
|
|
58
|
+
// (CVMap []) / (CVList []) — valid for 0, 1 or N entries (N-feature-safe).
|
|
59
|
+
//
|
|
60
|
+
// KEY ORDER IS INSERTION ORDER, not sorted. struct's Haskell `Value` holds a
|
|
61
|
+
// map as an ORDERED assoc list, so key order is observable — it survives into
|
|
62
|
+
// keysof, iteration and stringify. This used to sort, which was fine while
|
|
63
|
+
// this was the only representation, but above the size threshold the same
|
|
64
|
+
// config arrives via jsonRead in the JSON text's order. Sorting here would
|
|
65
|
+
// have made the two representations describe the same config in a different
|
|
66
|
+
// order, which is exactly what rung L1 promises cannot happen.
|
|
67
|
+
//
|
|
68
|
+
// Insertion order is still byte-stable: every nested level of the config comes
|
|
69
|
+
// from `each`, which iterates sorted, and the two levels built by hand
|
|
70
|
+
// (the root, and `options`) have a fixed order every target's literal follows.
|
|
71
|
+
function formatHsValue(val: any): string {
|
|
72
|
+
if (val === null || val === undefined) {
|
|
73
|
+
return 'CVNull'
|
|
74
|
+
}
|
|
75
|
+
if (typeof val === 'string') {
|
|
76
|
+
return '(CVStr ' + hsString(val) + ')'
|
|
77
|
+
}
|
|
78
|
+
if (typeof val === 'number') {
|
|
79
|
+
return '(CVNum (' + (Number.isFinite(val) ? String(val) : '0') + '))'
|
|
80
|
+
}
|
|
81
|
+
if (typeof val === 'boolean') {
|
|
82
|
+
return '(CVBool ' + (val ? 'True' : 'False') + ')'
|
|
83
|
+
}
|
|
84
|
+
if (Array.isArray(val)) {
|
|
85
|
+
const items = val.map((v) => formatHsValue(v)).join(', ')
|
|
86
|
+
return '(CVList [' + items + '])'
|
|
87
|
+
}
|
|
88
|
+
if (typeof val === 'object') {
|
|
89
|
+
const items = Object.keys(val)
|
|
90
|
+
.map((k) => '(' + hsString(k) + ', ' + formatHsValue(val[k]) + ')')
|
|
91
|
+
.join(', ')
|
|
92
|
+
return '(CVMap [' + items + '])'
|
|
93
|
+
}
|
|
94
|
+
return 'CVNull'
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
// Remove `$`-suffixed model annotation keys.
|
|
99
|
+
// Emission-time normalisation of a model subtree (L0).
|
|
100
|
+
//
|
|
101
|
+
// Always drops jostraca's iteration metadata (`$`-suffixed keys: index$,
|
|
102
|
+
// key$, val$). With `dropDefaults`, also drops keys whose value IS the
|
|
103
|
+
// default the runtime already assumes when the key is absent, which is pure
|
|
104
|
+
// payload — see CONFIG_DEFAULT.
|
|
105
|
+
//
|
|
106
|
+
// Rebuilds the tree rather than mutating during a walk. The previous
|
|
107
|
+
// implementation walked a clone calling `delete p[k]`, but walk() assigns its
|
|
108
|
+
// callback's result back over the child (`setprop(out, ckey, walk(...))`), so
|
|
109
|
+
// the delete was undone on the way out and the helper silently did nothing.
|
|
110
|
+
// Returning `undefined` from the callback does not fix it either: setprop
|
|
111
|
+
// stores undefined rather than removing the key, which then emits as a null.
|
|
112
|
+
//
|
|
113
|
+
// `dropDefaults` is opt-in and must be passed ONLY for the entity subtree.
|
|
114
|
+
// `active` means something different in feature config, where absent reads as
|
|
115
|
+
// INACTIVE (see feature_init) — dropping `active: true` there would silently
|
|
116
|
+
// disable the feature.
|
|
117
|
+
// jostraca's iteration metadata, injected by each()/names() while it walks the
|
|
118
|
+
// model. Listed explicitly rather than matched by trailing-dollar suffix: a
|
|
119
|
+
// trailing dollar is not exclusive to jostraca -- Seneca uses entity$ as real
|
|
120
|
+
// data -- so a blanket suffix match can silently drop a legitimate API field.
|
|
121
|
+
const MODEL_META = ['index$', 'key$', 'val$']
|
|
122
|
+
|
|
123
|
+
// Keys whose value IS the default the runtime already assumes when the key is
|
|
124
|
+
// absent, so emitting them is pure payload.
|
|
125
|
+
const CONFIG_DEFAULT: Record<string, any> = {
|
|
126
|
+
active: true,
|
|
127
|
+
req: false,
|
|
128
|
+
reqd: false,
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Subtrees carrying user payload rather than schema. An active:true inside an
|
|
132
|
+
// OpenAPI example is DATA, not a default, so default-pruning stops at these
|
|
133
|
+
// keys and everything below them is passed through untouched.
|
|
134
|
+
const PAYLOAD_KEYS = ['default', 'example', 'examples']
|
|
135
|
+
|
|
136
|
+
function clean(o: any, dropDefaults?: boolean): any {
|
|
137
|
+
const prune = (node: any, defaults: boolean): any => {
|
|
138
|
+
if (Array.isArray(node)) {
|
|
139
|
+
return node.map((n: any) => prune(n, defaults))
|
|
140
|
+
}
|
|
141
|
+
if (null != node && 'object' === typeof node) {
|
|
142
|
+
const out: any = {}
|
|
143
|
+
for (const k of Object.keys(node)) {
|
|
144
|
+
if (MODEL_META.includes(k)) {
|
|
145
|
+
continue
|
|
146
|
+
}
|
|
147
|
+
if (defaults && k in CONFIG_DEFAULT && CONFIG_DEFAULT[k] === node[k]) {
|
|
148
|
+
continue
|
|
149
|
+
}
|
|
150
|
+
out[k] = prune(node[k], defaults && !PAYLOAD_KEYS.includes(k))
|
|
151
|
+
}
|
|
152
|
+
return out
|
|
153
|
+
}
|
|
154
|
+
return node
|
|
155
|
+
}
|
|
156
|
+
return prune(o, true === dropDefaults)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
export {
|
|
161
|
+
clean,
|
|
162
|
+
formatHsValue,
|
|
163
|
+
hsString,
|
|
164
|
+
hsVarName,
|
|
165
|
+
projectPath,
|
|
166
|
+
}
|