@voxgig/sdkgen 1.3.17 → 1.3.19
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/bin/voxgig-sdkgen +1 -1
- package/dist/cmp/Deploy.js +16 -16
- package/dist/cmp/Deploy.js.map +1 -1
- package/dist/cmp/Entity.js +5 -1
- package/dist/cmp/Entity.js.map +1 -1
- package/dist/cmp/Feature.js +2 -1
- package/dist/cmp/Feature.js.map +1 -1
- package/dist/cmp/ReadmeTop.js +13 -11
- package/dist/cmp/ReadmeTop.js.map +1 -1
- package/dist/helpers/canonType.js +8 -3
- package/dist/helpers/canonType.js.map +1 -1
- package/dist/helpers/collectDeps.d.ts +1 -1
- package/dist/helpers/collectDeps.js +36 -13
- package/dist/helpers/collectDeps.js.map +1 -1
- package/dist/helpers/naming.d.ts +5 -1
- package/dist/helpers/naming.js +118 -0
- package/dist/helpers/naming.js.map +1 -1
- package/dist/helpers/opShape.d.ts +3 -1
- package/dist/helpers/opShape.js +87 -8
- package/dist/helpers/opShape.js.map +1 -1
- package/dist/helpers/serverVars.d.ts +10 -0
- package/dist/helpers/serverVars.js +87 -0
- package/dist/helpers/serverVars.js.map +1 -0
- package/dist/sdkgen.d.ts +4 -3
- package/dist/sdkgen.js +11 -2
- package/dist/sdkgen.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +15 -10
- package/project/.sdk/model/target/cpp.aontu +4 -4
- package/project/.sdk/model/target/go-cli.aontu +17 -17
- package/project/.sdk/model/target/go-mcp.aontu +11 -11
- package/project/.sdk/model/target/go.aontu +1 -1
- package/project/.sdk/model/target/java.aontu +4 -4
- package/project/.sdk/model/target/kotlin.aontu +4 -4
- package/project/.sdk/model/target/lean.aontu +51 -0
- package/project/.sdk/model/target/scala.aontu +4 -4
- package/project/.sdk/src/cmp/c/EntityTypes_c.ts +3 -4
- package/project/.sdk/src/cmp/c/Entity_c.ts +3 -3
- package/project/.sdk/src/cmp/c/ReadmeExamplesTest_c.ts +24 -7
- package/project/.sdk/src/cmp/c/TestDirect_c.ts +3 -3
- package/project/.sdk/src/cmp/c/TestEntity_c.ts +1 -1
- package/project/.sdk/src/cmp/clojure/Entity_clojure.ts +1 -1
- package/project/.sdk/src/cmp/clojure/ReadmeExamplesTest_clojure.ts +19 -8
- package/project/.sdk/src/cmp/cpp/EntityTypes_cpp.ts +2 -2
- package/project/.sdk/src/cmp/cpp/Entity_cpp.ts +3 -3
- package/project/.sdk/src/cmp/cpp/MainEntity_cpp.ts +2 -2
- package/project/.sdk/src/cmp/cpp/ReadmeExamplesTest_cpp.ts +136 -0
- package/project/.sdk/src/cmp/cpp/TestDirect_cpp.ts +3 -3
- package/project/.sdk/src/cmp/cpp/Test_cpp.ts +4 -0
- package/project/.sdk/src/cmp/csharp/EntityTypes_csharp.ts +2 -3
- package/project/.sdk/src/cmp/csharp/Entity_csharp.ts +3 -3
- package/project/.sdk/src/cmp/csharp/MainEntity_csharp.ts +2 -2
- package/project/.sdk/src/cmp/csharp/Package_csharp.ts +1 -1
- package/project/.sdk/src/cmp/csharp/ReadmeExamplesTest_csharp.ts +13 -1
- package/project/.sdk/src/cmp/csharp/TestDirect_csharp.ts +3 -3
- package/project/.sdk/src/cmp/csharp/TestEntity_csharp.ts +22 -15
- package/project/.sdk/src/cmp/dart/EntityTypes_dart.ts +2 -3
- package/project/.sdk/src/cmp/dart/Entity_dart.ts +3 -3
- package/project/.sdk/src/cmp/dart/MainEntity_dart.ts +2 -2
- package/project/.sdk/src/cmp/dart/Main_dart.ts +3 -3
- package/project/.sdk/src/cmp/dart/Package_dart.ts +1 -1
- package/project/.sdk/src/cmp/dart/TestDirect_dart.ts +4 -4
- package/project/.sdk/src/cmp/elixir/EntityTypes_elixir.ts +2 -3
- package/project/.sdk/src/cmp/elixir/Entity_elixir.ts +1 -1
- package/project/.sdk/src/cmp/elixir/ReadmeExamplesTest_elixir.ts +21 -3
- package/project/.sdk/src/cmp/go/Config_go.ts +14 -2
- package/project/.sdk/src/cmp/go/EntityTypes_go.ts +110 -18
- package/project/.sdk/src/cmp/go/Entity_go.ts +3 -3
- package/project/.sdk/src/cmp/go/Main_go.ts +7 -6
- package/project/.sdk/src/cmp/go/Package_go.ts +1 -1
- package/project/.sdk/src/cmp/go/TestDirect_go.ts +3 -3
- package/project/.sdk/src/cmp/go/TestEntity_go.ts +1 -1
- package/project/.sdk/src/cmp/go/utility_go.ts +25 -0
- package/project/.sdk/src/cmp/go-cli/Main_go-cli.ts +62 -35
- package/project/.sdk/src/cmp/go-cli/fragment/main.fragment.go +7 -7
- package/project/.sdk/src/cmp/go-cli/fragment/words.fragment.go +21 -18
- package/project/.sdk/src/cmp/go-mcp/Main_go-mcp.ts +9 -1
- package/project/.sdk/src/cmp/haskell/ReadmeExamplesTest_haskell.ts +28 -18
- package/project/.sdk/src/cmp/java/EntityTypes_java.ts +2 -3
- package/project/.sdk/src/cmp/java/Entity_java.ts +3 -3
- package/project/.sdk/src/cmp/java/MainEntity_java.ts +2 -2
- package/project/.sdk/src/cmp/java/Package_java.ts +1 -1
- package/project/.sdk/src/cmp/java/ReadmeExamplesTest_java.ts +23 -1
- package/project/.sdk/src/cmp/java/TestDirect_java.ts +3 -3
- package/project/.sdk/src/cmp/js/Config_js.ts +11 -0
- package/project/.sdk/src/cmp/js/EntityTypes_js.ts +2 -3
- package/project/.sdk/src/cmp/js/Entity_js.ts +3 -3
- package/project/.sdk/src/cmp/js/MainEntity_js.ts +2 -2
- package/project/.sdk/src/cmp/js/Main_js.ts +2 -2
- package/project/.sdk/src/cmp/js/TestDirect_js.ts +4 -4
- package/project/.sdk/src/cmp/js/fragment/Config.fragment.js +2 -2
- package/project/.sdk/src/cmp/js/fragment/Direct.test.fragment.js +4 -0
- package/project/.sdk/src/cmp/kotlin/EntityTypes_kotlin.ts +2 -3
- package/project/.sdk/src/cmp/kotlin/Entity_kotlin.ts +3 -3
- package/project/.sdk/src/cmp/kotlin/MainEntity_kotlin.ts +2 -2
- package/project/.sdk/src/cmp/kotlin/Package_kotlin.ts +1 -1
- package/project/.sdk/src/cmp/kotlin/ReadmeExamplesTest_kotlin.ts +27 -2
- package/project/.sdk/src/cmp/kotlin/TestDirect_kotlin.ts +3 -3
- package/project/.sdk/src/cmp/lean/Config_lean.ts +88 -0
- package/project/.sdk/src/cmp/lean/Entity_lean.ts +9 -0
- package/project/.sdk/src/cmp/lean/Gitignore_lean.ts +18 -0
- package/project/.sdk/src/cmp/lean/Main_lean.ts +120 -0
- package/project/.sdk/src/cmp/lean/Package_lean.ts +68 -0
- package/project/.sdk/src/cmp/lean/ReadmeEntity_lean.ts +29 -0
- package/project/.sdk/src/cmp/lean/ReadmeExplanation_lean.ts +19 -0
- package/project/.sdk/src/cmp/lean/ReadmeHowto_lean.ts +25 -0
- package/project/.sdk/src/cmp/lean/ReadmeInstall_lean.ts +38 -0
- package/project/.sdk/src/cmp/lean/ReadmeIntro_lean.ts +25 -0
- package/project/.sdk/src/cmp/lean/ReadmeModel_lean.ts +24 -0
- package/project/.sdk/src/cmp/lean/ReadmeOptions_lean.ts +22 -0
- package/project/.sdk/src/cmp/lean/ReadmeQuick_lean.ts +50 -0
- package/project/.sdk/src/cmp/lean/ReadmeRef_lean.ts +16 -0
- package/project/.sdk/src/cmp/lean/ReadmeTopHowto_lean.ts +16 -0
- package/project/.sdk/src/cmp/lean/ReadmeTopQuick_lean.ts +23 -0
- package/project/.sdk/src/cmp/lean/ReadmeTopTest_lean.ts +18 -0
- package/project/.sdk/src/cmp/lean/Test_lean.ts +207 -0
- package/project/.sdk/src/cmp/lean/utility_lean.ts +78 -0
- package/project/.sdk/src/cmp/lua/Config_lua.ts +10 -1
- package/project/.sdk/src/cmp/lua/EntityTypes_lua.ts +2 -3
- package/project/.sdk/src/cmp/lua/Entity_lua.ts +3 -3
- package/project/.sdk/src/cmp/lua/Package_lua.ts +1 -1
- package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +3 -3
- package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +1 -1
- package/project/.sdk/src/cmp/ocaml/ReadmeExamplesTest_ocaml.ts +29 -14
- package/project/.sdk/src/cmp/perl/Entity_perl.ts +3 -3
- package/project/.sdk/src/cmp/perl/MainEntity_perl.ts +2 -2
- package/project/.sdk/src/cmp/perl/Package_perl.ts +1 -1
- package/project/.sdk/src/cmp/perl/TestDirect_perl.ts +3 -3
- package/project/.sdk/src/cmp/php/Config_php.ts +13 -2
- package/project/.sdk/src/cmp/php/EntityTypes_php.ts +2 -3
- package/project/.sdk/src/cmp/php/Entity_php.ts +3 -3
- package/project/.sdk/src/cmp/php/MainEntity_php.ts +2 -2
- package/project/.sdk/src/cmp/php/Package_php.ts +1 -1
- package/project/.sdk/src/cmp/php/TestDirect_php.ts +3 -3
- package/project/.sdk/src/cmp/php/TestEntity_php.ts +1 -1
- package/project/.sdk/src/cmp/py/Config_py.ts +10 -1
- package/project/.sdk/src/cmp/py/EntityTypes_py.ts +2 -3
- package/project/.sdk/src/cmp/py/Entity_py.ts +3 -3
- package/project/.sdk/src/cmp/py/MainEntity_py.ts +2 -2
- package/project/.sdk/src/cmp/py/Main_py.ts +2 -2
- package/project/.sdk/src/cmp/py/Package_py.ts +1 -1
- package/project/.sdk/src/cmp/py/TestDirect_py.ts +3 -3
- package/project/.sdk/src/cmp/py/TestEntity_py.ts +1 -1
- package/project/.sdk/src/cmp/rb/Config_rb.ts +12 -1
- package/project/.sdk/src/cmp/rb/EntityTypes_rb.ts +15 -5
- package/project/.sdk/src/cmp/rb/Entity_rb.ts +3 -3
- package/project/.sdk/src/cmp/rb/MainEntity_rb.ts +2 -2
- package/project/.sdk/src/cmp/rb/Package_rb.ts +2 -2
- package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +3 -3
- package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +1 -1
- package/project/.sdk/src/cmp/rust/EntityBase_rust.ts +2 -2
- package/project/.sdk/src/cmp/rust/EntityTypes_rust.ts +3 -4
- package/project/.sdk/src/cmp/rust/Entity_rust.ts +3 -3
- package/project/.sdk/src/cmp/rust/MainEntity_rust.ts +2 -2
- package/project/.sdk/src/cmp/rust/Package_rust.ts +1 -1
- package/project/.sdk/src/cmp/rust/ReadmeExamplesTest_rust.ts +22 -10
- package/project/.sdk/src/cmp/rust/TestDirect_rust.ts +3 -3
- package/project/.sdk/src/cmp/rust/TestEntity_rust.ts +25 -18
- package/project/.sdk/src/cmp/scala/EntityTypes_scala.ts +2 -3
- package/project/.sdk/src/cmp/scala/Entity_scala.ts +3 -3
- package/project/.sdk/src/cmp/scala/MainEntity_scala.ts +2 -2
- package/project/.sdk/src/cmp/scala/ReadmeExamplesTest_scala.ts +22 -3
- package/project/.sdk/src/cmp/scala/TestDirect_scala.ts +3 -3
- package/project/.sdk/src/cmp/scala/Test_scala.ts +1 -1
- package/project/.sdk/src/cmp/swift/EntityTypes_swift.ts +12 -6
- package/project/.sdk/src/cmp/swift/Entity_swift.ts +3 -3
- package/project/.sdk/src/cmp/swift/MainEntity_swift.ts +2 -2
- package/project/.sdk/src/cmp/swift/Package_swift.ts +1 -1
- package/project/.sdk/src/cmp/swift/ReadmeExamplesTest_swift.ts +18 -1
- package/project/.sdk/src/cmp/swift/TestDirect_swift.ts +1 -1
- package/project/.sdk/src/cmp/ts/Config_ts.ts +11 -0
- package/project/.sdk/src/cmp/ts/EntityTypes_ts.ts +2 -3
- package/project/.sdk/src/cmp/ts/Entity_ts.ts +3 -3
- package/project/.sdk/src/cmp/ts/MainEntity_ts.ts +2 -2
- package/project/.sdk/src/cmp/ts/Main_ts.ts +2 -2
- package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +4 -4
- package/project/.sdk/src/cmp/ts/fragment/Config.fragment.ts +2 -2
- package/project/.sdk/src/cmp/ts/fragment/Direct.test.fragment.ts +4 -0
- package/project/.sdk/src/cmp/zig/Entity_zig.ts +3 -3
- package/project/.sdk/src/cmp/zig/MainEntity_zig.ts +2 -2
- package/project/.sdk/src/cmp/zig/Package_zig.ts +10 -2
- package/project/.sdk/tm/cpp/test/primary_utility_test.cpp +8 -16
- package/project/.sdk/tm/csharp/Makefile +6 -6
- package/project/.sdk/tm/csharp/test/PrimaryUtilityTest.cs +10 -28
- package/project/.sdk/tm/dart/Makefile +3 -3
- package/project/.sdk/tm/dart/test/primary_test.dart +7 -0
- package/project/.sdk/tm/go/Makefile +6 -6
- package/project/.sdk/tm/go/feature/test_feature.go +33 -1
- package/project/.sdk/tm/go/test/primary_utility_test.go +46 -42
- package/project/.sdk/tm/go/test/runner_test.go +30 -1
- package/project/.sdk/tm/go/utility/make_options.go +48 -0
- package/project/.sdk/tm/java/Makefile +6 -6
- package/project/.sdk/tm/java/test/PrimaryUtilityTest.java +7 -24
- package/project/.sdk/tm/js/Makefile +6 -6
- package/project/.sdk/tm/js/src/feature/test/TestFeature.js +18 -1
- package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +39 -1
- package/project/.sdk/tm/js/test/utility/PrimaryUtility.test.js +13 -0
- package/project/.sdk/tm/kotlin/Makefile +6 -6
- package/project/.sdk/tm/kotlin/test/PrimaryUtilityTest.kt +7 -20
- package/project/.sdk/tm/lean/LICENSE +21 -0
- package/project/.sdk/tm/lean/VERSION +1 -0
- package/project/.sdk/tm/lean/src/SdkFeature.lean +171 -0
- package/project/.sdk/tm/lean/src/SdkFeatures.lean +602 -0
- package/project/.sdk/tm/lean/src/SdkJson.lean +134 -0
- package/project/.sdk/tm/lean/src/SdkRuntime.lean +356 -0
- package/project/.sdk/tm/lean/src/SdkUtility.lean +617 -0
- package/project/.sdk/tm/lean/src/VoxgigStruct.lean +2880 -0
- package/project/.sdk/tm/lean/src/Vregex.lean +412 -0
- package/project/.sdk/tm/lean/src/feature/README.md +5 -0
- package/project/.sdk/tm/lean/src/feature/audit/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/base/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/cache/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/clienttrack/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/debug/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/idempotency/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/log/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/metrics/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/netsim/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/paging/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/proxy/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/ratelimit/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/rbac/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/retry/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/streaming/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/telemetry/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/test/.gitkeep +0 -0
- package/project/.sdk/tm/lean/src/feature/timeout/.gitkeep +0 -0
- package/project/.sdk/tm/lean/test/StructCorpus.lean +697 -0
- package/project/.sdk/tm/lean/test/TFeature.lean +268 -0
- package/project/.sdk/tm/lean/test/TPrimaryUtility.lean +349 -0
- package/project/.sdk/tm/lua/Makefile +7 -7
- package/project/.sdk/tm/lua/feature/test_feature.lua +29 -1
- package/project/.sdk/tm/lua/test/primary_utility_test.lua +14 -8
- package/project/.sdk/tm/lua/utility/make_options.lua +39 -0
- package/project/.sdk/tm/perl/Makefile +6 -6
- package/project/.sdk/tm/perl/t/primary_utility.t +8 -17
- package/project/.sdk/tm/php/Makefile +6 -6
- package/project/.sdk/tm/php/feature/TestFeature.php +30 -2
- package/project/.sdk/tm/php/test/PrimaryUtilityTest.php +14 -7
- package/project/.sdk/tm/php/utility/MakeOptions.php +44 -0
- package/project/.sdk/tm/py/Makefile +6 -6
- package/project/.sdk/tm/py/feature/test_feature.py +28 -1
- package/project/.sdk/tm/py/test/test_primary_utility.py +18 -18
- package/project/.sdk/tm/py/utility/make_options.py +42 -0
- package/project/.sdk/tm/rb/Makefile +6 -6
- package/project/.sdk/tm/rb/feature/test_feature.rb +24 -1
- package/project/.sdk/tm/rb/test/primary_utility_test.rb +11 -8
- package/project/.sdk/tm/rb/utility/make_options.rb +37 -0
- package/project/.sdk/tm/rust/Makefile +6 -6
- package/project/.sdk/tm/rust/tests/common/mod.rs +37 -1
- package/project/.sdk/tm/rust/tests/primary_utility_test.rs +12 -26
- package/project/.sdk/tm/swift/Makefile +6 -6
- package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/PrimaryUtilityTest.swift +7 -8
- package/project/.sdk/tm/ts/Makefile +6 -6
- package/project/.sdk/tm/ts/src/feature/test/TestFeature.ts +18 -1
- package/project/.sdk/tm/ts/src/utility/MakeOptionsUtility.ts +39 -1
- package/project/.sdk/tm/ts/test/utility/PrimaryUtility.test.ts +69 -21
- package/src/cmp/Deploy.ts +16 -16
- package/src/cmp/Entity.ts +5 -1
- package/src/cmp/Feature.ts +2 -1
- package/src/cmp/ReadmeTop.ts +13 -11
- package/src/helpers/canonType.ts +8 -3
- package/src/helpers/collectDeps.ts +39 -12
- package/src/helpers/naming.ts +130 -0
- package/src/helpers/opShape.ts +99 -12
- package/src/helpers/serverVars.ts +105 -0
- package/src/sdkgen.ts +12 -3
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
indent,
|
|
13
13
|
isAuthActive,
|
|
14
14
|
resolveAuthPrefix,
|
|
15
|
+
serverVariables,
|
|
15
16
|
} from '@voxgig/sdkgen'
|
|
16
17
|
|
|
17
18
|
|
|
@@ -53,6 +54,14 @@ const Config = cmp(async function Config(props: any) {
|
|
|
53
54
|
`
|
|
54
55
|
: ''
|
|
55
56
|
|
|
57
|
+
// Templated server URL: emit the spec's server-variable defaults so the
|
|
58
|
+
// runtime can substitute {name} placeholders in base (see makeOptions).
|
|
59
|
+
const svars = serverVariables(model)
|
|
60
|
+
const serverBlock = 0 === svars.length ? '' :
|
|
61
|
+
'server: {\n' +
|
|
62
|
+
svars.map((v: any) => ` ${JSON.stringify(v.name)}: ${JSON.stringify(v.dflt)},\n`).join('') +
|
|
63
|
+
' },\n\n '
|
|
64
|
+
|
|
56
65
|
File({ name: 'Config.' + target.ext }, () => {
|
|
57
66
|
|
|
58
67
|
Fragment({
|
|
@@ -60,6 +69,8 @@ const Config = cmp(async function Config(props: any) {
|
|
|
60
69
|
|
|
61
70
|
replace: {
|
|
62
71
|
|
|
72
|
+
"'SERVERBLOCK'": serverBlock,
|
|
73
|
+
|
|
63
74
|
"'AUTHBLOCK'": authBlock,
|
|
64
75
|
|
|
65
76
|
"'HEADERS'": indent(JSON.stringify(headers, null, 2), 4).trim(),
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
File, Content,
|
|
27
27
|
} from '@voxgig/sdkgen'
|
|
28
28
|
|
|
29
|
-
import { canonToType, opTypeName, opRequestShape, warnEntityTypeCollisions } from '@voxgig/sdkgen'
|
|
29
|
+
import { canonToType, opTypeName, opRequestShape, warnEntityTypeCollisions , deriveEntityNames } from '@voxgig/sdkgen'
|
|
30
30
|
|
|
31
31
|
import {
|
|
32
32
|
KIT,
|
|
@@ -57,11 +57,10 @@ const EntityTypes = cmp(function EntityTypes(props: any) {
|
|
|
57
57
|
// filter, so inactive entities still get class files referencing these
|
|
58
58
|
// typed names. Filter on `name` (always present), NOT `active` — parity
|
|
59
59
|
// with the go emitter's fix.
|
|
60
|
-
const entityList =
|
|
60
|
+
const entityList = deriveEntityNames(entity)
|
|
61
61
|
// Derive the PascalCase Name up-front — it is set LAZILY by names(), so an
|
|
62
62
|
// entity not yet named (e.g. a fieldless placeholder) would otherwise read
|
|
63
63
|
// `Name = undefined` below. Parity with the go emitter's fix.
|
|
64
|
-
entityList.forEach((e: any) => { if (null == e.Name) names(e, e.name) })
|
|
65
64
|
|
|
66
65
|
// Surface duplicate generated type names (two entities with the same
|
|
67
66
|
// PascalCase Name) — they would redeclare a type in statically-typed
|
|
@@ -4,7 +4,7 @@ import * as Path from 'node:path'
|
|
|
4
4
|
import {
|
|
5
5
|
cmp, each, camelify, names,
|
|
6
6
|
File, Content, Folder, Fragment, Line, FeatureHook, Slot,
|
|
7
|
-
entityClassName,
|
|
7
|
+
entityClassName, entityCollection,
|
|
8
8
|
} from '@voxgig/sdkgen'
|
|
9
9
|
|
|
10
10
|
import {
|
|
@@ -22,7 +22,7 @@ const Entity = cmp(function Entity(props: any) {
|
|
|
22
22
|
// Collision-free entity CLASS name (see entityClassName): normally
|
|
23
23
|
// `<Name>Entity`, disambiguated when it would clash with another entity's
|
|
24
24
|
// data-type name. The class file name and the Main require path both use this.
|
|
25
|
-
const entityColl =
|
|
25
|
+
const entityColl = entityCollection(model)
|
|
26
26
|
const cls = entityClassName(entity, entityColl)
|
|
27
27
|
|
|
28
28
|
const entrep = {
|
|
@@ -37,7 +37,7 @@ const Entity = cmp(function Entity(props: any) {
|
|
|
37
37
|
|
|
38
38
|
File({ name: cls + '.' + target.name }, () => {
|
|
39
39
|
|
|
40
|
-
const opnames = Object.keys(entity.op)
|
|
40
|
+
const opnames = Object.keys(entity.op || {})
|
|
41
41
|
|
|
42
42
|
const opfrags =
|
|
43
43
|
(['load', 'list', 'create', 'update', 'remove']
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
import { cmp, Content, entityClassName } from '@voxgig/sdkgen'
|
|
3
|
+
import { cmp, Content, entityClassName, entityCollection } from '@voxgig/sdkgen'
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
KIT,
|
|
@@ -14,7 +14,7 @@ const MainEntity = cmp(async function MainEntity(props: any) {
|
|
|
14
14
|
|
|
15
15
|
// Return the collision-free class (entityClassName); the accessor METHOD name
|
|
16
16
|
// (entity.Name) is unchanged so callers still write client.<Name>().
|
|
17
|
-
const cls = entityClassName(entity,
|
|
17
|
+
const cls = entityClassName(entity, entityCollection(model))
|
|
18
18
|
|
|
19
19
|
Content(`
|
|
20
20
|
// Entity access: \`client.${entity.Name}().list()\` / \`client.${entity.Name}().load({ id })\`.
|
|
@@ -4,7 +4,7 @@ import * as Path from 'node:path'
|
|
|
4
4
|
import {
|
|
5
5
|
cmp, each, names, cmap,
|
|
6
6
|
List, File, Content, Copy, Folder, Fragment, Line, FeatureHook,
|
|
7
|
-
entityClassName,
|
|
7
|
+
entityClassName, entityCollection,
|
|
8
8
|
} from '@voxgig/sdkgen'
|
|
9
9
|
|
|
10
10
|
|
|
@@ -57,7 +57,7 @@ const Main = cmp(async function Main(props: any) {
|
|
|
57
57
|
Line(`// ${model.const.Name} ${target.Name} SDK\n`)
|
|
58
58
|
|
|
59
59
|
List({ item: entity }, ({ item }: any) => {
|
|
60
|
-
const cls = entityClassName(item,
|
|
60
|
+
const cls = entityClassName(item, entityCollection(model))
|
|
61
61
|
return Line(`const { ${cls} } = require('./entity/${cls}')`)
|
|
62
62
|
})
|
|
63
63
|
|
|
@@ -48,7 +48,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
48
48
|
apikey: env.${PROJECTNAME}_APIKEY,`
|
|
49
49
|
: ''
|
|
50
50
|
|
|
51
|
-
const opnames = Object.keys(entity.op)
|
|
51
|
+
const opnames = Object.keys(entity.op || {})
|
|
52
52
|
const hasLoad = opnames.includes('load')
|
|
53
53
|
const hasList = opnames.includes('list')
|
|
54
54
|
|
|
@@ -134,7 +134,7 @@ function directSetup(mockres) {
|
|
|
134
134
|
|
|
135
135
|
|
|
136
136
|
function generateDirectLoad(model: Model, entity: ModelEntity) {
|
|
137
|
-
const loadOp = entity.op
|
|
137
|
+
const loadOp = entity.op?.load
|
|
138
138
|
const loadPoint: ModelPoint | undefined = loadOp?.points?.[0]
|
|
139
139
|
|
|
140
140
|
if (null == loadPoint) {
|
|
@@ -145,7 +145,7 @@ function generateDirectLoad(model: Model, entity: ModelEntity) {
|
|
|
145
145
|
const loadPath = normalizePathParams(loadPoint.parts || [], loadParams, loadPoint.rename?.param)
|
|
146
146
|
|
|
147
147
|
// Get list info for live mode bootstrapping
|
|
148
|
-
const listOp = entity.op
|
|
148
|
+
const listOp = entity.op?.list
|
|
149
149
|
const listPoint = listOp?.points?.[0]
|
|
150
150
|
const listParams = listPoint?.args?.params || []
|
|
151
151
|
const listPath = listPoint ? normalizePathParams(listPoint.parts || [], listParams, listPoint.rename?.param) : ''
|
|
@@ -231,7 +231,7 @@ ${paramAsserts} }
|
|
|
231
231
|
|
|
232
232
|
|
|
233
233
|
function generateDirectList(model: Model, entity: ModelEntity) {
|
|
234
|
-
const listOp = entity.op
|
|
234
|
+
const listOp = entity.op?.list
|
|
235
235
|
const listPoint: ModelPoint | undefined = listOp?.points?.[0]
|
|
236
236
|
|
|
237
237
|
if (null == listPoint) {
|
|
@@ -19,7 +19,7 @@ class Config {
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
main = {
|
|
22
|
-
name: '
|
|
22
|
+
name: '$$const.Name$$',
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
|
|
@@ -31,7 +31,7 @@ class Config {
|
|
|
31
31
|
options = {
|
|
32
32
|
base: '$$main.kit.info.servers.0.url$$',
|
|
33
33
|
|
|
34
|
-
'AUTHBLOCK'headers: 'HEADERS',
|
|
34
|
+
'SERVERBLOCK''AUTHBLOCK'headers: 'HEADERS',
|
|
35
35
|
|
|
36
36
|
entity: {
|
|
37
37
|
// #EntityConfigs
|
|
@@ -17,6 +17,10 @@ describe('EntityNameDirect', async () => {
|
|
|
17
17
|
|
|
18
18
|
test('direct-exists', async () => {
|
|
19
19
|
const sdk = new ProjectNameSDK({
|
|
20
|
+
// Concrete base: a live construction must satisfy any server
|
|
21
|
+
// variables a templated base URL declares; overriding base with a
|
|
22
|
+
// literal (as the direct flow tests do) sidesteps the requirement.
|
|
23
|
+
base: 'http://localhost:8080',
|
|
20
24
|
system: { fetch: async () => ({}) }
|
|
21
25
|
})
|
|
22
26
|
assert('function' === typeof sdk.direct)
|
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
File, Content,
|
|
40
40
|
} from '@voxgig/sdkgen'
|
|
41
41
|
|
|
42
|
-
import { canonToType, opTypeName, opRequestShape, warnEntityTypeCollisions } from '@voxgig/sdkgen'
|
|
42
|
+
import { canonToType, opTypeName, opRequestShape, warnEntityTypeCollisions , deriveEntityNames } from '@voxgig/sdkgen'
|
|
43
43
|
|
|
44
44
|
import {
|
|
45
45
|
KIT,
|
|
@@ -132,11 +132,10 @@ const EntityTypes = cmp(function EntityTypes(props: any) {
|
|
|
132
132
|
// filter, so inactive entities still get class files referencing these
|
|
133
133
|
// typed names. Filter on `name` (always present), NOT `active` — parity
|
|
134
134
|
// with the go emitter's fix.
|
|
135
|
-
const entityList =
|
|
135
|
+
const entityList = deriveEntityNames(entity)
|
|
136
136
|
// Derive the PascalCase Name up-front — it is set LAZILY by names(), so an
|
|
137
137
|
// entity not yet named (e.g. a fieldless placeholder) would otherwise read
|
|
138
138
|
// `Name = undefined` below. Parity with the go/py/csharp/java emitter's fix.
|
|
139
|
-
entityList.forEach((e: any) => { if (null == e.Name) names(e, e.name) })
|
|
140
139
|
|
|
141
140
|
// Surface duplicate generated type names (two entities with the same
|
|
142
141
|
// PascalCase Name) — they would redeclare a type in statically-typed
|
|
@@ -4,7 +4,7 @@ import * as Path from 'node:path'
|
|
|
4
4
|
import {
|
|
5
5
|
cmp, camelify, names,
|
|
6
6
|
File, Content, Folder, Fragment,
|
|
7
|
-
entityClassName,
|
|
7
|
+
entityClassName, entityCollection,
|
|
8
8
|
} from '@voxgig/sdkgen'
|
|
9
9
|
|
|
10
10
|
import {
|
|
@@ -25,7 +25,7 @@ const Entity = cmp(function Entity(props: any) {
|
|
|
25
25
|
// Collision-free entity CLASS name (see entityClassName): normally
|
|
26
26
|
// `<Name>Entity`, but disambiguated (e.g. `<Name>EntityClient`) when it
|
|
27
27
|
// would clash with another entity's data-type name.
|
|
28
|
-
const entityColl =
|
|
28
|
+
const entityColl = entityCollection(model)
|
|
29
29
|
const cls = entityClassName(entity, entityColl)
|
|
30
30
|
|
|
31
31
|
const entrep = {
|
|
@@ -41,7 +41,7 @@ const Entity = cmp(function Entity(props: any) {
|
|
|
41
41
|
|
|
42
42
|
File({ name: cls + '.' + target.ext }, () => {
|
|
43
43
|
|
|
44
|
-
const opnames = Object.keys(entity.op)
|
|
44
|
+
const opnames = Object.keys(entity.op || {})
|
|
45
45
|
|
|
46
46
|
// For each CRUD op: if the spec defines it, splice in the real
|
|
47
47
|
// implementation. Otherwise emit a stub that satisfies the SdkEntity
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { cmp, Content, entityClassName } from '@voxgig/sdkgen'
|
|
2
|
+
import { cmp, Content, entityClassName, entityCollection } from '@voxgig/sdkgen'
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
KIT,
|
|
@@ -17,7 +17,7 @@ const MainEntity = cmp(async function MainEntity(props: any) {
|
|
|
17
17
|
const { model } = props.ctx$
|
|
18
18
|
|
|
19
19
|
const kotlinpackage = kotlinPackage(model)
|
|
20
|
-
const entityColl =
|
|
20
|
+
const entityColl = entityCollection(model)
|
|
21
21
|
const cls = entityClassName(entity, entityColl)
|
|
22
22
|
const accessor = kotlinVarName(entity.name)
|
|
23
23
|
|
|
@@ -30,7 +30,7 @@ const Package = cmp(async function Package(props: any) {
|
|
|
30
30
|
|
|
31
31
|
// Dep name convention: "group:artifact" with an explicit version.
|
|
32
32
|
const deps: { group: string, artifact: string, version: string, kind: string }[] = []
|
|
33
|
-
for (const d of collectDeps(model, target.name, target.deps)) {
|
|
33
|
+
for (const d of collectDeps(model, target.name, target.deps, ctx$.log)) {
|
|
34
34
|
const [dgroup, dartifact] = String(d.name).split(':')
|
|
35
35
|
if (dgroup && dartifact && d.version) {
|
|
36
36
|
deps.push({
|
|
@@ -46,7 +46,9 @@ const ReadmeExamplesTest = cmp(function ReadmeExamplesTest(props: any) {
|
|
|
46
46
|
// Checks, PER DOCUMENT:
|
|
47
47
|
// 1. PRESENCE: the doc exists and holds at least one kotlin block.
|
|
48
48
|
// 2. STRUCTURE: every kotlin block's braces / parens / brackets balance, so a
|
|
49
|
-
// truncated or malformed generated snippet fails loudly.
|
|
49
|
+
// truncated or malformed generated snippet fails loudly. Every code fence
|
|
50
|
+
// is also terminated (even fence count), so an unclosed fence at EOF is
|
|
51
|
+
// caught rather than accepted as a complete block.
|
|
50
52
|
//
|
|
51
53
|
// GENERATED by @voxgig/sdkgen — do not edit by hand.
|
|
52
54
|
|
|
@@ -97,6 +99,22 @@ class ReadmeExamplesTest {
|
|
|
97
99
|
return Files.readString(path)
|
|
98
100
|
}
|
|
99
101
|
|
|
102
|
+
// Count triple-backtick fence markers. A well-formed document opens and
|
|
103
|
+
// closes every fenced block, so the total must be EVEN. An odd count means a
|
|
104
|
+
// fence was opened but never closed (a truncated / malformed doc) — the
|
|
105
|
+
// split-based extraction in kotlinBlocks() would otherwise accept the
|
|
106
|
+
// unterminated trailing segment as a complete block and pass silently.
|
|
107
|
+
private fun fenceCount(text: String): Int {
|
|
108
|
+
val fence = 96.toChar().toString().repeat(3)
|
|
109
|
+
var count = 0
|
|
110
|
+
var idx = text.indexOf(fence)
|
|
111
|
+
while (idx >= 0) {
|
|
112
|
+
count++
|
|
113
|
+
idx = text.indexOf(fence, idx + fence.length)
|
|
114
|
+
}
|
|
115
|
+
return count
|
|
116
|
+
}
|
|
117
|
+
|
|
100
118
|
// True when every open/close delimiter balances (ignores the subtlety of
|
|
101
119
|
// delimiters inside string literals — a generated snippet never nests an
|
|
102
120
|
// unbalanced delimiter in a string, and this catches truncation).
|
|
@@ -145,7 +163,14 @@ class ReadmeExamplesTest {
|
|
|
145
163
|
if (!Files.exists(path)) {
|
|
146
164
|
continue
|
|
147
165
|
}
|
|
148
|
-
val
|
|
166
|
+
val src = readDoc(path, doc[0])
|
|
167
|
+
// A fence opened but never closed is a malformed doc — fail loudly
|
|
168
|
+
// rather than silently accepting the unterminated trailing segment as a
|
|
169
|
+
// complete block.
|
|
170
|
+
if (fenceCount(src) % 2 != 0) {
|
|
171
|
+
failures.add(doc[0] + " has an unterminated code fence")
|
|
172
|
+
}
|
|
173
|
+
val blocks = kotlinBlocks(src)
|
|
149
174
|
var balancedCount = 0
|
|
150
175
|
for (i in blocks.indices) {
|
|
151
176
|
if (balanced(blocks[i])) {
|
|
@@ -72,7 +72,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
72
72
|
|
|
73
73
|
const authActive = isAuthActive(model)
|
|
74
74
|
|
|
75
|
-
const opnames = Object.keys(entity.op)
|
|
75
|
+
const opnames = Object.keys(entity.op || {})
|
|
76
76
|
const hasLoad = opnames.includes('load')
|
|
77
77
|
const hasList = opnames.includes('list')
|
|
78
78
|
|
|
@@ -80,8 +80,8 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
80
80
|
return
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
const loadOp = entity.op
|
|
84
|
-
const listOp = entity.op
|
|
83
|
+
const loadOp = entity.op?.load
|
|
84
|
+
const listOp = entity.op?.list
|
|
85
85
|
|
|
86
86
|
const loadPoint = loadOp?.points?.[0]
|
|
87
87
|
const loadPath = loadPoint ? normalizePathParams(loadPoint.parts || [], loadPoint?.args?.params || [], loadPoint?.rename?.param) : ''
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Content,
|
|
3
|
+
File,
|
|
4
|
+
cmp,
|
|
5
|
+
each,
|
|
6
|
+
isAuthActive,
|
|
7
|
+
resolveAuthPrefix,
|
|
8
|
+
} from '@voxgig/sdkgen'
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
KIT,
|
|
12
|
+
Model,
|
|
13
|
+
getModelPath,
|
|
14
|
+
} from '@voxgig/apidef'
|
|
15
|
+
|
|
16
|
+
import {
|
|
17
|
+
clean,
|
|
18
|
+
leanString,
|
|
19
|
+
} from './utility_lean'
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
// SdkConfig.lean: the embedded API model, serialised to a JSON string. The
|
|
23
|
+
// config-driven runtime (SdkRuntime) parses it into a struct `Value` at client
|
|
24
|
+
// construction — the whole SDK is data-driven, so there is no per-entity code.
|
|
25
|
+
const Config = cmp(async function Config(props: any) {
|
|
26
|
+
const ctx$ = props.ctx$
|
|
27
|
+
const target = props.target
|
|
28
|
+
|
|
29
|
+
const model: Model = ctx$.model
|
|
30
|
+
|
|
31
|
+
const entity = getModelPath(model, `main.${KIT}.entity`)
|
|
32
|
+
const feature = getModelPath(model, `main.${KIT}.feature`)
|
|
33
|
+
const headers = getModelPath(model, `main.${KIT}.config.headers`) || {}
|
|
34
|
+
|
|
35
|
+
const authActive = isAuthActive(model)
|
|
36
|
+
const authPrefix = resolveAuthPrefix(model)
|
|
37
|
+
|
|
38
|
+
let baseUrl = ''
|
|
39
|
+
try { baseUrl = getModelPath(model, `main.${KIT}.info.servers.0.url`) } catch (_e) { }
|
|
40
|
+
|
|
41
|
+
const featureConfig: any = {}
|
|
42
|
+
each(feature, (f: any) => { featureConfig[f.name] = f.config || {} })
|
|
43
|
+
|
|
44
|
+
const entityOptions: any = {}
|
|
45
|
+
each(entity, (ent: any) => { entityOptions[ent.name] = {} })
|
|
46
|
+
|
|
47
|
+
const options: any = {
|
|
48
|
+
base: baseUrl,
|
|
49
|
+
headers,
|
|
50
|
+
entity: entityOptions,
|
|
51
|
+
}
|
|
52
|
+
if (authActive) {
|
|
53
|
+
options.auth = { prefix: authPrefix }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const entityConfig = Object.values(entity || {}).reduce((a: any, n: any) => (
|
|
57
|
+
a[n.name] = clean({
|
|
58
|
+
fields: n.fields,
|
|
59
|
+
name: n.name,
|
|
60
|
+
op: n.op,
|
|
61
|
+
relations: n.relations,
|
|
62
|
+
}), a), {})
|
|
63
|
+
|
|
64
|
+
const config = {
|
|
65
|
+
main: { name: model.const.Name },
|
|
66
|
+
feature: featureConfig,
|
|
67
|
+
options,
|
|
68
|
+
entity: entityConfig,
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
File({ name: 'SdkConfig.' + target.ext }, () => {
|
|
72
|
+
Content(`-- Generated API configuration for the config-driven runtime.
|
|
73
|
+
-- The embedded model is parsed into a struct Value at client construction.
|
|
74
|
+
|
|
75
|
+
namespace SdkConfig
|
|
76
|
+
|
|
77
|
+
def configJson : String :=
|
|
78
|
+
${leanString(JSON.stringify(config))}
|
|
79
|
+
|
|
80
|
+
end SdkConfig
|
|
81
|
+
`)
|
|
82
|
+
})
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
export {
|
|
87
|
+
Config
|
|
88
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { cmp } from '@voxgig/sdkgen'
|
|
2
|
+
|
|
3
|
+
// Entities are generic in the Lean target: there is no per-entity generated
|
|
4
|
+
// module. Every entity's operations are dispatched by the config-driven
|
|
5
|
+
// SdkRuntime (see SdkClient), so this component emits nothing. It exists only
|
|
6
|
+
// so the neutral Entity component can resolve a language delegate.
|
|
7
|
+
const Entity = cmp(function Entity(_props: any) {})
|
|
8
|
+
|
|
9
|
+
export { Entity }
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Content, File, cmp } from '@voxgig/sdkgen'
|
|
2
|
+
|
|
3
|
+
const Gitignore = cmp(async function Gitignore(_props: any) {
|
|
4
|
+
File({ name: '.gitignore' }, () => {
|
|
5
|
+
Content(`# Lake build output
|
|
6
|
+
.lake/
|
|
7
|
+
build/
|
|
8
|
+
lake-packages/
|
|
9
|
+
|
|
10
|
+
# IDE / OS
|
|
11
|
+
.idea/
|
|
12
|
+
.vscode/
|
|
13
|
+
.DS_Store
|
|
14
|
+
`)
|
|
15
|
+
})
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
export { Gitignore }
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cmp, each,
|
|
3
|
+
File, Content, Copy, Folder,
|
|
4
|
+
} from '@voxgig/sdkgen'
|
|
5
|
+
|
|
6
|
+
import type {
|
|
7
|
+
ModelEntity
|
|
8
|
+
} from '@voxgig/apidef'
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
KIT,
|
|
12
|
+
getModelPath
|
|
13
|
+
} from '@voxgig/apidef'
|
|
14
|
+
|
|
15
|
+
import { Package } from './Package_lean'
|
|
16
|
+
import { Config } from './Config_lean'
|
|
17
|
+
import { Gitignore } from './Gitignore_lean'
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
// Op name -> generated wrapper. list/load/remove take a match; create takes
|
|
21
|
+
// data; update takes both. Any non-standard op falls back to the match+data
|
|
22
|
+
// form. Every wrapper delegates to the config-driven SdkRuntime.
|
|
23
|
+
function opWrapper(entName: string, opName: string): string {
|
|
24
|
+
const q = `"${entName}"`
|
|
25
|
+
switch (opName) {
|
|
26
|
+
case 'list':
|
|
27
|
+
return ` def list (c m co : Value) : SIO Value := SdkRuntime.opList c ${q} m co\n`
|
|
28
|
+
case 'load':
|
|
29
|
+
return ` def load (c m co : Value) : SIO Value := SdkRuntime.opLoad c ${q} m co\n`
|
|
30
|
+
case 'remove':
|
|
31
|
+
return ` def remove (c m co : Value) : SIO Value := SdkRuntime.opRemove c ${q} m co\n`
|
|
32
|
+
case 'create':
|
|
33
|
+
return ` def create (c d co : Value) : SIO Value := SdkRuntime.opCreate c ${q} d co\n`
|
|
34
|
+
case 'update':
|
|
35
|
+
return ` def update (c m d co : Value) : SIO Value := SdkRuntime.opUpdate c ${q} m d co\n`
|
|
36
|
+
default:
|
|
37
|
+
return ` def ${opName} (c m d co : Value) : SIO Value := SdkRuntime.runOp c ${q} "${opName}" m d co\n`
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
const Main = cmp(async function Main(props: any) {
|
|
43
|
+
|
|
44
|
+
const { target } = props
|
|
45
|
+
const { model } = props.ctx$
|
|
46
|
+
|
|
47
|
+
const entity: ModelEntity = getModelPath(model, `main.${KIT}.entity`)
|
|
48
|
+
|
|
49
|
+
Package({ target })
|
|
50
|
+
Gitignore({})
|
|
51
|
+
|
|
52
|
+
// Copy tm/lean verbatim (placeholder substitution applies): the runtime under
|
|
53
|
+
// src/ (VoxgigStruct, Vregex, SdkJson, SdkRuntime), plus LICENSE/VERSION. The
|
|
54
|
+
// per-feature custom-source scaffold under src/feature is excluded.
|
|
55
|
+
Copy({
|
|
56
|
+
from: 'tm/' + target.name,
|
|
57
|
+
exclude: [/src\/feature\//],
|
|
58
|
+
replace: {
|
|
59
|
+
...props.ctx$.stdrep,
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
// Generated modules under src/: the embedded API config and the public
|
|
64
|
+
// client (constructors + one op namespace per entity).
|
|
65
|
+
Folder({ name: 'src' }, () => {
|
|
66
|
+
|
|
67
|
+
Config({ target })
|
|
68
|
+
|
|
69
|
+
File({ name: 'SdkClient.' + target.ext }, () => {
|
|
70
|
+
|
|
71
|
+
let namespaces = ''
|
|
72
|
+
each(entity, (e: any) => {
|
|
73
|
+
// Capitalise the entity name for its op namespace.
|
|
74
|
+
const ns = e.name.charAt(0).toUpperCase() + e.name.slice(1)
|
|
75
|
+
let ops = ''
|
|
76
|
+
each(e.op, (op: any) => { ops += opWrapper(e.name, op.name) })
|
|
77
|
+
namespaces += `namespace ${ns}\n${ops}end ${ns}\n\n`
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
Content(`-- ${model.const.Name} SDK public client (generated by @voxgig/sdkgen).
|
|
81
|
+
--
|
|
82
|
+
-- Constructors (newSdk / testSdk) and one op namespace per entity. Entities are
|
|
83
|
+
-- generic: every op delegates to the config-driven SdkRuntime, so the pipeline
|
|
84
|
+
-- is identical for every entity and every API.
|
|
85
|
+
|
|
86
|
+
import VoxgigStruct
|
|
87
|
+
import SdkRuntime
|
|
88
|
+
import SdkConfig
|
|
89
|
+
|
|
90
|
+
open VoxgigStruct
|
|
91
|
+
|
|
92
|
+
namespace Sdk
|
|
93
|
+
|
|
94
|
+
/-- Construct a live client from an options map (empty map = defaults). -/
|
|
95
|
+
def newSdk (options : Value) : SIO Value :=
|
|
96
|
+
SdkRuntime.mkClientV options SdkConfig.configJson
|
|
97
|
+
|
|
98
|
+
/-- No-argument convenience constructor. -/
|
|
99
|
+
def newSdk0 : SIO Value := do newSdk (← emptyMap)
|
|
100
|
+
|
|
101
|
+
/-- Construct a test-mode client: operations are answered from an in-memory
|
|
102
|
+
store seeded with the entity test data, so no server is needed. -/
|
|
103
|
+
def testSdk (seed : Value) (options : Value) : SIO Value :=
|
|
104
|
+
SdkRuntime.mkTestClientV options SdkConfig.configJson seed
|
|
105
|
+
|
|
106
|
+
/-- Test client with default options. -/
|
|
107
|
+
def testSdk0 (seed : Value) : SIO Value := do testSdk seed (← emptyMap)
|
|
108
|
+
|
|
109
|
+
end Sdk
|
|
110
|
+
|
|
111
|
+
${namespaces}`)
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
export {
|
|
119
|
+
Main
|
|
120
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Content,
|
|
3
|
+
File,
|
|
4
|
+
cmp,
|
|
5
|
+
} from '@voxgig/sdkgen'
|
|
6
|
+
|
|
7
|
+
import type {
|
|
8
|
+
Model,
|
|
9
|
+
} from '@voxgig/apidef'
|
|
10
|
+
|
|
11
|
+
import { pkgName } from './utility_lean'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
// Each runtime module is its own `lean_lib` (Lake globs `<LibName>.lean` from
|
|
15
|
+
// srcDir), matching the vendored struct project's layout. The runtime is
|
|
16
|
+
// dependency-free (prelude + Std only); the HTTP transport shells to curl.
|
|
17
|
+
const LIBS = [
|
|
18
|
+
'Vregex', 'VoxgigStruct', 'SdkJson', 'SdkUtility', 'SdkFeature', 'SdkFeatures', 'SdkRuntime', 'SdkConfig',
|
|
19
|
+
'SdkClient',
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
const Package = cmp(async function Package(props: any) {
|
|
24
|
+
const ctx$ = props.ctx$
|
|
25
|
+
const model: Model = ctx$.model
|
|
26
|
+
|
|
27
|
+
const libBlocks = LIBS.map((n) =>
|
|
28
|
+
`[[lean_lib]]\nname = "${n}"\nsrcDir = "src"\n`).join('\n')
|
|
29
|
+
|
|
30
|
+
File({ name: 'lakefile.toml' }, () => {
|
|
31
|
+
Content(`# ${model.const.Name} SDK for Lean 4 (generated by @voxgig/sdkgen).
|
|
32
|
+
name = "${pkgName(model)}"
|
|
33
|
+
version = "0.0.1"
|
|
34
|
+
defaultTargets = ["SdkClient"]
|
|
35
|
+
|
|
36
|
+
${libBlocks}
|
|
37
|
+
[[lean_exe]]
|
|
38
|
+
name = "runner"
|
|
39
|
+
srcDir = "test"
|
|
40
|
+
root = "Runner"
|
|
41
|
+
|
|
42
|
+
[[lean_exe]]
|
|
43
|
+
name = "structcorpus"
|
|
44
|
+
srcDir = "test"
|
|
45
|
+
root = "StructCorpus"
|
|
46
|
+
|
|
47
|
+
[[lean_exe]]
|
|
48
|
+
name = "primary"
|
|
49
|
+
srcDir = "test"
|
|
50
|
+
root = "TPrimaryUtility"
|
|
51
|
+
|
|
52
|
+
[[lean_exe]]
|
|
53
|
+
name = "feature"
|
|
54
|
+
srcDir = "test"
|
|
55
|
+
root = "TFeature"
|
|
56
|
+
`)
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
// Pin the toolchain to the version the runtime is developed against.
|
|
60
|
+
File({ name: 'lean-toolchain' }, () => {
|
|
61
|
+
Content(`leanprover/lean4:v4.32.1\n`)
|
|
62
|
+
})
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
export {
|
|
67
|
+
Package
|
|
68
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { cmp, Content, each } from '@voxgig/sdkgen'
|
|
2
|
+
|
|
3
|
+
// One section per entity: its op namespace and the verbs it supports.
|
|
4
|
+
const ReadmeEntity = cmp(function ReadmeEntity(props: any) {
|
|
5
|
+
const { entity } = props
|
|
6
|
+
if (null == entity) return
|
|
7
|
+
const ns = entity.name.charAt(0).toUpperCase() + entity.name.slice(1)
|
|
8
|
+
const ops = Object.keys(entity.op || {}).sort()
|
|
9
|
+
if (0 === ops.length) return
|
|
10
|
+
|
|
11
|
+
let rows = ''
|
|
12
|
+
for (const op of ops) {
|
|
13
|
+
const call =
|
|
14
|
+
'create' === op ? `${ns}.create sdk data (← emptyMap)`
|
|
15
|
+
: 'update' === op ? `${ns}.update sdk match data (← emptyMap)`
|
|
16
|
+
: `${ns}.${op} sdk match (← emptyMap)`
|
|
17
|
+
rows += `| \`${op}\` | \`${call}\` |\n`
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
Content(`Operations are in the \`${ns}\` namespace; each takes the client first
|
|
21
|
+
and per-call options last.
|
|
22
|
+
|
|
23
|
+
| Op | Call |
|
|
24
|
+
| --- | --- |
|
|
25
|
+
${rows}
|
|
26
|
+
`)
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
export { ReadmeEntity }
|