@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
|
@@ -59,7 +59,7 @@ const TestEntity = cmp(function TestEntity(props: any) {
|
|
|
59
59
|
// it only applies to entities that declare a list op. Others (e.g. Batch =
|
|
60
60
|
// create/load) have no list endpoint — make_point errors and the stream
|
|
61
61
|
// yields nothing — so skip the stream test for them.
|
|
62
|
-
const hasList = !!(entity.op && (entity.op as any)
|
|
62
|
+
const hasList = !!(entity.op && (entity.op as any)?.list)
|
|
63
63
|
|
|
64
64
|
const basicflow: ModelEntityFlow | undefined =
|
|
65
65
|
getModelPath(model, `main.${KIT}.flow.Basic${nom(entity, 'Name')}Flow`)
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
canonKey,
|
|
8
8
|
each,
|
|
9
9
|
exampleVarName,
|
|
10
|
+
names,
|
|
10
11
|
} from '@voxgig/sdkgen'
|
|
11
12
|
|
|
12
13
|
import {
|
|
@@ -149,7 +150,31 @@ function clean(o: any) {
|
|
|
149
150
|
}
|
|
150
151
|
|
|
151
152
|
|
|
153
|
+
|
|
154
|
+
// The Go identifier fragment for a feature's generated constructor
|
|
155
|
+
// (New<Fname>Feature / New<Fname>FeatureFunc).
|
|
156
|
+
//
|
|
157
|
+
// SHARED because the identifier is DECLARED in Main_go.ts (registry.go and the
|
|
158
|
+
// root init()) and REFERENCED in Config_go.ts (makeFeature). Two copies of the
|
|
159
|
+
// derivation is a latent undefined-identifier bug in the generated SDK: they
|
|
160
|
+
// were both `name.charAt(0).toUpperCase() + name.slice(1)`, consistently wrong
|
|
161
|
+
// for a name needing real normalisation but at least agreeing, until one side
|
|
162
|
+
// was fixed alone and `rate_limit` became NewRateLimitFeatureFunc in the
|
|
163
|
+
// registry and NewRate_limitFeatureFunc in config.
|
|
164
|
+
//
|
|
165
|
+
// Uses the jostraca-derived PascalCase `Name` (deriving it if absent), which is
|
|
166
|
+
// what Main_ts.ts uses, so a hyphenated or underscored feature name yields a
|
|
167
|
+
// legal Go identifier instead of `NewRate-limitFeatureFunc`.
|
|
168
|
+
function goFeatureName(feat: any): string {
|
|
169
|
+
if (null == feat.Name) {
|
|
170
|
+
names(feat, feat.name)
|
|
171
|
+
}
|
|
172
|
+
return feat.Name
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
|
|
152
176
|
export {
|
|
177
|
+
goFeatureName,
|
|
153
178
|
clean,
|
|
154
179
|
exampleValue,
|
|
155
180
|
formatGoMap,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import * as Path from 'node:path'
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
|
-
cmp, each,
|
|
5
|
+
cmp, each, deriveEntityNames,
|
|
6
6
|
File, Content, Fragment, Slot,
|
|
7
7
|
} from '@voxgig/sdkgen'
|
|
8
8
|
|
|
@@ -16,18 +16,32 @@ import {
|
|
|
16
16
|
} from '@voxgig/apidef'
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
// Published
|
|
20
|
-
// eng/go
|
|
21
|
-
|
|
19
|
+
// Published boru/eng/go version. The engine module
|
|
20
|
+
// github.com/boru-lang/boru/eng/go is not yet tagged under the boru path (the
|
|
21
|
+
// eng/go/v0.0.1 tag predates the aql->boru rename and still declares the old
|
|
22
|
+
// aql-lang/aql module path), so we pin a commit pseudo-version. Bump here —
|
|
23
|
+
// to a real eng/go/v<X.Y.Z> once one is published, or a newer pseudo-version —
|
|
24
|
+
// when adopting a newer engine.
|
|
25
|
+
const BORU_ENG_VERSION = 'v0.0.2-0.20260804163932-0d66b55c5110'
|
|
22
26
|
|
|
23
|
-
// go.sum entries for
|
|
27
|
+
// go.sum entries for BORU_ENG_VERSION and its transitive deps. The sibling
|
|
24
28
|
// SDK dep needs no entry (path replace). Deterministic because the version
|
|
25
29
|
// is pinned above — regenerate with `go mod tidy` and update BOTH constants
|
|
26
|
-
// together when bumping
|
|
27
|
-
const
|
|
28
|
-
github.com/
|
|
29
|
-
github.com/
|
|
30
|
-
github.com/
|
|
30
|
+
// together when bumping BORU_ENG_VERSION.
|
|
31
|
+
const BORU_ENG_GOSUM = `github.com/boru-lang/boru/eng/go v0.0.2-0.20260804163932-0d66b55c5110 h1:iwMbEPhByhVhJgt6xhyhT+jXMiARvbG4wHIrc4OPcvU=
|
|
32
|
+
github.com/boru-lang/boru/eng/go v0.0.2-0.20260804163932-0d66b55c5110/go.mod h1:KQLjjCq4QVAfdSuhmQ58ZFA9JK7LV2+A/aLRb3m4s5k=
|
|
33
|
+
github.com/cockroachdb/apd/v3 v3.2.3 h1:4Zx+I3R35bFXMnltzmjP79i2cravE4jTRL6ps9Aux80=
|
|
34
|
+
github.com/cockroachdb/apd/v3 v3.2.3/go.mod h1:klXJcjp+FffLTHlhIG69tezTDvdP065naDsHzKhYSqc=
|
|
35
|
+
github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw=
|
|
36
|
+
github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
|
37
|
+
github.com/tabnas/debug/go v0.2.3 h1:cptiwHcHKw+lqtZuKp6gX7yY1NunJLS5PHD7ykVcIvM=
|
|
38
|
+
github.com/tabnas/debug/go v0.2.3/go.mod h1:EXSNFdN6Ct9pcAUk8ZGozNbIltb3Hw0wcne+5vWQyns=
|
|
39
|
+
github.com/tabnas/json/go v0.4.0 h1:1BxLHyCullkKXkvui/SuZ4s6OMrFVDuEB13IX/5S1eM=
|
|
40
|
+
github.com/tabnas/json/go v0.4.0/go.mod h1:MJzyziKcvZk3OZCaSDxhMdf/Wkq2UJ0uLGWFtp9zsJs=
|
|
41
|
+
github.com/tabnas/jsonic/go v0.4.0 h1:y5k/P21C3q3jWaA+VxEhXxzZ8xJgpgAehMBEseDN31g=
|
|
42
|
+
github.com/tabnas/jsonic/go v0.4.0/go.mod h1:eDpkddhkuTFuIXMkSqTZl7cU7M23swbMpkXR1W5bApQ=
|
|
43
|
+
github.com/tabnas/parser/go v0.4.0 h1:M8+qRT4KaCtr4OCpg9NDNUXJIdbbweqeqbpEpVGNEqU=
|
|
44
|
+
github.com/tabnas/parser/go v0.4.0/go.mod h1:WrlfEVyZ1QjEIowWiyEu3K1iHj7wxuPut5zoH9Trehk=
|
|
31
45
|
`
|
|
32
46
|
|
|
33
47
|
|
|
@@ -40,6 +54,14 @@ const Main = cmp(function Main(props: any) {
|
|
|
40
54
|
const cliModule = `github.com/${org}/${model.name}-sdk/go-cli`
|
|
41
55
|
|
|
42
56
|
const entityMap: any = getModelPath(model, `main.${KIT}.entity`)
|
|
57
|
+
// Derive each entity's PascalCase `Name` here rather than relying on another
|
|
58
|
+
// TARGET having run first. This target sets `phase.entity: { active: false }`
|
|
59
|
+
// (see model/target/go-{cli,mcp}.aontu), so create-sdkgen's Root.ts never
|
|
60
|
+
// calls names() for it — the accessor emitted below used to read `Name` off
|
|
61
|
+
// objects the `go` target happened to have named as a side effect, which
|
|
62
|
+
// yields `client.undefined(nil)` whenever this target is generated without
|
|
63
|
+
// `go`, or before it in target order.
|
|
64
|
+
deriveEntityNames(entityMap)
|
|
43
65
|
const entityNames = Object.keys(entityMap).map(n => n.toLowerCase())
|
|
44
66
|
|
|
45
67
|
const FRAGMENT = Path.normalize(__dirname + '/../../../src/cmp/go-cli/fragment')
|
|
@@ -56,7 +78,7 @@ const Main = cmp(function Main(props: any) {
|
|
|
56
78
|
// EVERYTHING here is MODEL-DRIVEN: verbs, examples and how-to sections are
|
|
57
79
|
// gated on whether an active entity actually exposes that op
|
|
58
80
|
// (op.<name>.active !== false) — never document an operation no entity
|
|
59
|
-
// supports. The CLI implements three
|
|
81
|
+
// supports. The CLI implements three boru words (list / load / update; see
|
|
60
82
|
// words.fragment.go + runOp).
|
|
61
83
|
// ==========================================================================
|
|
62
84
|
const bin = `${model.name}-cli`
|
|
@@ -121,7 +143,7 @@ const Main = cmp(function Main(props: any) {
|
|
|
121
143
|
ex.push('# 3. Provide credentials once, via the environment')
|
|
122
144
|
ex.push(`export ${apiKeyEnv}=sk_live_xxx`)
|
|
123
145
|
ex.push('')
|
|
124
|
-
ex.push('# 4. Each command line is ONE
|
|
146
|
+
ex.push('# 4. Each command line is ONE boru expression, run against the API:')
|
|
125
147
|
if (firstHas('list')) ex.push(`./${bin} list ${firstEntity}`)
|
|
126
148
|
if (firstHas('load')) {
|
|
127
149
|
ex.push(`./${bin} load 1 ${firstEntity} # {id:1} shorthand`)
|
|
@@ -150,7 +172,7 @@ const Main = cmp(function Main(props: any) {
|
|
|
150
172
|
\`\`\`
|
|
151
173
|
|
|
152
174
|
\`list <entity>\` returns the first page of records. \`<entity>\` is a bareword —
|
|
153
|
-
it is auto-quoted as an
|
|
175
|
+
it is auto-quoted as an boru atom, so no quotes are needed.`)
|
|
154
176
|
|
|
155
177
|
if (firstHas('load')) howtos.push(`### Load a single record
|
|
156
178
|
|
|
@@ -186,7 +208,7 @@ Both are injectable by a secrets vault, so the key never has to be typed inline.
|
|
|
186
208
|
howtos.push(`### Explore interactively with the REPL
|
|
187
209
|
|
|
188
210
|
Run with no arguments to open a REPL (prompt \`${model.name}>\`). Each line is
|
|
189
|
-
evaluated as its own
|
|
211
|
+
evaluated as its own boru expression:
|
|
190
212
|
|
|
191
213
|
\`\`\`text
|
|
192
214
|
$ ./${bin}
|
|
@@ -210,10 +232,10 @@ below — this SDK exposes ${entityCount} ${entityNoun}.`)
|
|
|
210
232
|
|
|
211
233
|
File({ name: 'README.md' }, () => Content(`# ${model.name}-cli
|
|
212
234
|
|
|
213
|
-
|
|
214
|
-
SDK. Each command line is parsed as a single [
|
|
235
|
+
boru-driven command-line client **and** interactive REPL for the ${model.Name}
|
|
236
|
+
SDK. Each command line is parsed as a single [boru](https://github.com/boru-lang/boru)
|
|
215
237
|
expression and evaluated against the live API; run it with no arguments to drop
|
|
216
|
-
into a REPL. Built on \`github.com/
|
|
238
|
+
into a REPL. Built on \`github.com/boru-lang/boru/eng/go\` and the sibling Go SDK
|
|
217
239
|
at \`../go\`.
|
|
218
240
|
|
|
219
241
|
## Examples
|
|
@@ -240,7 +262,7 @@ ${exampleBlock}
|
|
|
240
262
|
export ${apiKeyEnv}=sk_live_xxx
|
|
241
263
|
\`\`\`
|
|
242
264
|
|
|
243
|
-
3. **Run a query.** Evaluate an
|
|
265
|
+
3. **Run a query.** Evaluate an boru expression against the API (or run with no
|
|
244
266
|
arguments to open the REPL):
|
|
245
267
|
|
|
246
268
|
\`\`\`sh
|
|
@@ -250,7 +272,7 @@ ${exampleBlock}
|
|
|
250
272
|
4. **Go interactive.** Run the binary with no arguments to open the REPL, then
|
|
251
273
|
type \`/help\` for the word and entity lists and \`/quit\` to leave.
|
|
252
274
|
|
|
253
|
-
That is the whole loop: *build → set key → evaluate
|
|
275
|
+
That is the whole loop: *build → set key → evaluate boru expressions*.
|
|
254
276
|
|
|
255
277
|
## How-to guides
|
|
256
278
|
|
|
@@ -260,13 +282,13 @@ ${howtoBlock}
|
|
|
260
282
|
|
|
261
283
|
### Words
|
|
262
284
|
|
|
263
|
-
The CLI registers these
|
|
285
|
+
The CLI registers these boru words, each bound to the SDK:
|
|
264
286
|
|
|
265
287
|
| Word | Signatures | Returns |
|
|
266
288
|
|----------|-----------------------------------------------|--------------------------------|
|
|
267
289
|
${verbRows}
|
|
268
290
|
|
|
269
|
-
- \`<entity>\` is a bareword, auto-quoted as an
|
|
291
|
+
- \`<entity>\` is a bareword, auto-quoted as an boru atom (e.g. \`${firstEntity}\`).
|
|
270
292
|
- \`<query>\` is either a **Map** (\`{id:1}\`) or a **Scalar** (\`1\`, treated as
|
|
271
293
|
\`{id:1}\`). A scalar is always wrapped as \`{id:<value>}\`.
|
|
272
294
|
|
|
@@ -285,7 +307,7 @@ Unset variables fall back to the SDK's built-in defaults.
|
|
|
285
307
|
|
|
286
308
|
### REPL commands
|
|
287
309
|
|
|
288
|
-
Meta-commands use the \`/\` prefix (everything else on a line is evaluated as
|
|
310
|
+
Meta-commands use the \`/\` prefix (everything else on a line is evaluated as boru):
|
|
289
311
|
|
|
290
312
|
- \`/quit\` / \`/q\` / \`/exit\` — exit the REPL
|
|
291
313
|
- \`/help\` / \`/h\` / \`/?\` — show the word list, entity list and meta commands
|
|
@@ -313,25 +335,25 @@ ${entityList}
|
|
|
313
335
|
|
|
314
336
|
## Explanation
|
|
315
337
|
|
|
316
|
-
### Why
|
|
338
|
+
### Why boru?
|
|
317
339
|
|
|
318
|
-
The whole command line is one [
|
|
340
|
+
The whole command line is one [boru](https://github.com/boru-lang/boru) expression,
|
|
319
341
|
not a fixed \`verb --flag\` grammar. That means the same binary works one-shot
|
|
320
342
|
(\`./${bin} <expr>\`) and interactively (the REPL), and expressions compose the
|
|
321
|
-
same way in both. \`list\` / \`load\` / \`update\` are ordinary
|
|
343
|
+
same way in both. \`list\` / \`load\` / \`update\` are ordinary boru *words* bound to
|
|
322
344
|
the SDK — adding SDK operations is adding words, not re-parsing flags.
|
|
323
345
|
|
|
324
346
|
### How it is wired
|
|
325
347
|
|
|
326
348
|
\`main.go\` builds the SDK client (configured from the environment), creates an
|
|
327
|
-
|
|
349
|
+
boru registry, and \`words.go\` registers \`list\` / \`load\` / \`update\` as native
|
|
328
350
|
words that dispatch on the entity atom and call the sibling Go SDK at \`../go\`.
|
|
329
351
|
Results are unwrapped from their \`Entity\` wrappers to plain data before being
|
|
330
352
|
printed.
|
|
331
353
|
|
|
332
354
|
### Output format
|
|
333
355
|
|
|
334
|
-
Each result value is printed as its
|
|
356
|
+
Each result value is printed as its boru string form (a JSON-like rendering of
|
|
335
357
|
the record or list of records). One-shot mode prints to stdout; errors go to
|
|
336
358
|
stderr with a non-zero exit code.
|
|
337
359
|
|
|
@@ -342,25 +364,30 @@ this repo, or upstream at
|
|
|
342
364
|
\`github.com/voxgig/sdkgen/project/.sdk/src/cmp/go-cli/\`.
|
|
343
365
|
`))
|
|
344
366
|
|
|
345
|
-
// go.mod — sibling SDK via relative replace;
|
|
346
|
-
// public Go module proxy. The go directive must be >=
|
|
347
|
-
// (go 1.24.7
|
|
367
|
+
// go.mod — sibling SDK via relative replace; boru/eng/go from the
|
|
368
|
+
// public Go module proxy. The go directive must be >= boru/eng/go's own
|
|
369
|
+
// (go 1.24.7) — keep in step with BORU_ENG_VERSION.
|
|
348
370
|
File({ name: 'go.mod' }, () => Content(`module ${cliModule}
|
|
349
371
|
|
|
350
372
|
go 1.24.7
|
|
351
373
|
|
|
352
374
|
require ${sdkModule} v0.0.0
|
|
353
|
-
require github.com/
|
|
375
|
+
require github.com/boru-lang/boru/eng/go ${BORU_ENG_VERSION}
|
|
354
376
|
|
|
355
|
-
require
|
|
377
|
+
require (
|
|
378
|
+
github.com/cockroachdb/apd/v3 v3.2.3 // indirect
|
|
379
|
+
github.com/tabnas/json/go v0.4.0 // indirect
|
|
380
|
+
github.com/tabnas/jsonic/go v0.4.0 // indirect
|
|
381
|
+
github.com/tabnas/parser/go v0.4.0 // indirect
|
|
382
|
+
)
|
|
356
383
|
|
|
357
384
|
replace ${sdkModule} => ../go
|
|
358
385
|
`))
|
|
359
386
|
|
|
360
|
-
// go.sum — required for `go build` to accept the
|
|
387
|
+
// go.sum — required for `go build` to accept the boru/eng/go dependency
|
|
361
388
|
// (the path-replaced sibling SDK needs no entry). Pinned alongside
|
|
362
|
-
//
|
|
363
|
-
File({ name: 'go.sum' }, () => Content(
|
|
389
|
+
// BORU_ENG_VERSION above.
|
|
390
|
+
File({ name: 'go.sum' }, () => Content(BORU_ENG_GOSUM))
|
|
364
391
|
|
|
365
392
|
// Makefile — `make build` for the current machine, `make build-all` to
|
|
366
393
|
// cross-compile for the three desktop OSes (linux, darwin, windows) on
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Command ProjectName-cli is a CLI + REPL for the ProjectName SDK,
|
|
2
|
-
// built on the
|
|
3
|
-
// single
|
|
2
|
+
// built on the boru engine. Positional arguments are joined into a
|
|
3
|
+
// single boru expression and evaluated; with no arguments, falls into
|
|
4
4
|
// a REPL. Generated by sdkgen go-cli target.
|
|
5
5
|
package main
|
|
6
6
|
|
|
@@ -11,8 +11,8 @@ import (
|
|
|
11
11
|
"os"
|
|
12
12
|
"strings"
|
|
13
13
|
|
|
14
|
-
eng "github.com/
|
|
15
|
-
"github.com/
|
|
14
|
+
eng "github.com/boru-lang/boru/eng/go"
|
|
15
|
+
"github.com/boru-lang/boru/eng/go/parser"
|
|
16
16
|
sdk "GOMODULE"
|
|
17
17
|
)
|
|
18
18
|
|
|
@@ -28,10 +28,10 @@ func main() {
|
|
|
28
28
|
|
|
29
29
|
// usage prints the CLI help (for --help / -h). No client or network setup.
|
|
30
30
|
func usage(out io.Writer) {
|
|
31
|
-
fmt.Fprintf(out, "%s-cli —
|
|
31
|
+
fmt.Fprintf(out, "%s-cli — boru-driven CLI + REPL for the %s SDK\n\n", prompt, prompt)
|
|
32
32
|
fmt.Fprintln(out, "Usage:")
|
|
33
|
-
fmt.Fprintf(out, " %s-cli [--help] [<
|
|
34
|
-
fmt.Fprintln(out, "With arguments, they are joined into a single
|
|
33
|
+
fmt.Fprintf(out, " %s-cli [--help] [<boru expression>]\n\n", prompt)
|
|
34
|
+
fmt.Fprintln(out, "With arguments, they are joined into a single boru expression and")
|
|
35
35
|
fmt.Fprintln(out, "evaluated against the API. With no arguments, starts an interactive REPL.")
|
|
36
36
|
fmt.Fprintln(out)
|
|
37
37
|
fmt.Fprintln(out, "Words: list / load / update <query?> <entity>")
|
|
@@ -5,11 +5,11 @@ import (
|
|
|
5
5
|
"fmt"
|
|
6
6
|
"strings"
|
|
7
7
|
|
|
8
|
-
eng "github.com/
|
|
8
|
+
eng "github.com/boru-lang/boru/eng/go"
|
|
9
9
|
sdk "GOMODULE"
|
|
10
10
|
)
|
|
11
11
|
|
|
12
|
-
// registerSDKWords installs three native
|
|
12
|
+
// registerSDKWords installs three native boru words bound to the SDK:
|
|
13
13
|
// list / load / update. Each is declared with two overloads matching
|
|
14
14
|
// the signature [query?:(Node or Scalar) entity:atom]:
|
|
15
15
|
//
|
|
@@ -18,31 +18,34 @@ import (
|
|
|
18
18
|
// `load {id:1} book`, `load 1 book`)
|
|
19
19
|
//
|
|
20
20
|
// The entity slot is /q-quoted so a bareword `book` parses as the
|
|
21
|
-
// Atom "book" rather than dispatching as an undefined word.
|
|
21
|
+
// Atom "book" rather than dispatching as an undefined word. Both
|
|
22
|
+
// overloads are all-forward (BarrierAllForward), so args are collected
|
|
23
|
+
// from the tokens following the word.
|
|
22
24
|
func registerSDKWords(r *eng.Registry, client *sdk.ProjectNameSDK) {
|
|
23
25
|
for _, op := range []string{"list", "load", "update"} {
|
|
24
26
|
op := op
|
|
25
|
-
single := eng.
|
|
27
|
+
single := eng.Signature{
|
|
26
28
|
Args: []*eng.Type{eng.TAtom},
|
|
27
29
|
QuoteArgs: map[int]bool{0: true},
|
|
28
|
-
|
|
30
|
+
Impl: eng.Go(func(args []eng.Value, _ map[string]eng.Value, _ []eng.Value, _ *eng.Registry) ([]eng.Value, error) {
|
|
29
31
|
return runOp(client, op, nil, args[0])
|
|
30
|
-
},
|
|
31
|
-
Returns:
|
|
32
|
+
}),
|
|
33
|
+
Returns: []*eng.Type{eng.TAny},
|
|
34
|
+
BarrierPos: eng.BarrierAllForward,
|
|
32
35
|
}
|
|
33
|
-
dual := eng.
|
|
36
|
+
dual := eng.Signature{
|
|
34
37
|
Args: []*eng.Type{eng.TAny, eng.TAtom},
|
|
35
38
|
QuoteArgs: map[int]bool{1: true},
|
|
36
|
-
|
|
39
|
+
Impl: eng.Go(func(args []eng.Value, _ map[string]eng.Value, _ []eng.Value, _ *eng.Registry) ([]eng.Value, error) {
|
|
37
40
|
q := args[0]
|
|
38
41
|
return runOp(client, op, &q, args[1])
|
|
39
|
-
},
|
|
40
|
-
Returns:
|
|
42
|
+
}),
|
|
43
|
+
Returns: []*eng.Type{eng.TAny},
|
|
44
|
+
BarrierPos: eng.BarrierAllForward,
|
|
41
45
|
}
|
|
42
46
|
r.RegisterNativeFunc(eng.NativeFunc{
|
|
43
|
-
Name:
|
|
44
|
-
|
|
45
|
-
Signatures: []eng.NativeSig{single, dual},
|
|
47
|
+
Name: op,
|
|
48
|
+
Signatures: []eng.Signature{single, dual},
|
|
46
49
|
})
|
|
47
50
|
}
|
|
48
51
|
}
|
|
@@ -91,22 +94,22 @@ func entityFor(client *sdk.ProjectNameSDK, name string) (sdk.ProjectNameEntity,
|
|
|
91
94
|
return nil, fmt.Errorf("unknown entity %q", name)
|
|
92
95
|
}
|
|
93
96
|
|
|
94
|
-
// queryToMap converts
|
|
97
|
+
// queryToMap converts a boru Value (Map or Scalar) into the
|
|
95
98
|
// `map[string]any` shape the SDK expects. Maps are unwrapped via
|
|
96
99
|
// eng.ToNative. Scalars are wrapped as {"id": <value>} so the
|
|
97
100
|
// shorthand `load 1 book` becomes `load {id:1} book`.
|
|
98
101
|
func queryToMap(v eng.Value) (map[string]any, error) {
|
|
99
|
-
if v.
|
|
102
|
+
if v.Parent.ConformsTo(eng.TMap) {
|
|
100
103
|
m, ok := eng.ToNative(v).(map[string]any)
|
|
101
104
|
if !ok {
|
|
102
105
|
return nil, fmt.Errorf("query map could not be unwrapped")
|
|
103
106
|
}
|
|
104
107
|
return m, nil
|
|
105
108
|
}
|
|
106
|
-
if v.
|
|
109
|
+
if v.Parent.ConformsTo(eng.TScalar) {
|
|
107
110
|
return map[string]any{"id": eng.ToNative(v)}, nil
|
|
108
111
|
}
|
|
109
|
-
return nil, fmt.Errorf("query must be a Map or Scalar, got %s", v.
|
|
112
|
+
return nil, fmt.Errorf("query must be a Map or Scalar, got %s", v.Parent)
|
|
110
113
|
}
|
|
111
114
|
|
|
112
115
|
// extractData walks an SDK result and replaces any sdk.Entity wrapper
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import * as Path from 'node:path'
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
|
-
cmp, each,
|
|
5
|
+
cmp, each, deriveEntityNames,
|
|
6
6
|
File, Content, Fragment, Slot,
|
|
7
7
|
} from '@voxgig/sdkgen'
|
|
8
8
|
|
|
@@ -54,6 +54,14 @@ const Main = cmp(function Main(props: any) {
|
|
|
54
54
|
const mcpModule = `github.com/${org}/${model.name}-sdk/go-mcp`
|
|
55
55
|
|
|
56
56
|
const entityMap: any = getModelPath(model, `main.${KIT}.entity`)
|
|
57
|
+
// Derive each entity's PascalCase `Name` here rather than relying on another
|
|
58
|
+
// TARGET having run first. This target sets `phase.entity: { active: false }`
|
|
59
|
+
// (see model/target/go-{cli,mcp}.aontu), so create-sdkgen's Root.ts never
|
|
60
|
+
// calls names() for it — the accessor emitted below used to read `Name` off
|
|
61
|
+
// objects the `go` target happened to have named as a side effect, which
|
|
62
|
+
// yields `client.undefined(nil)` whenever this target is generated without
|
|
63
|
+
// `go`, or before it in target order.
|
|
64
|
+
deriveEntityNames(entityMap)
|
|
57
65
|
const entityNames = Object.keys(entityMap).map(n => n.toLowerCase())
|
|
58
66
|
const entityHelp = entityNames.length > 0 ? entityNames.join(' | ') : '(none)'
|
|
59
67
|
|
|
@@ -67,35 +67,44 @@ readDoc path = do
|
|
|
67
67
|
pure (either (const "") id r)
|
|
68
68
|
|
|
69
69
|
|
|
70
|
-
-- Extract the body of every fenced Haskell block from markdown.
|
|
71
|
-
--
|
|
72
|
-
--
|
|
73
|
-
|
|
70
|
+
-- Extract the body of every fenced Haskell block from markdown. Returns
|
|
71
|
+
-- (blocks, allClosed) where allClosed is False when a fence was opened but
|
|
72
|
+
-- never closed before EOF — a malformed doc that must fail rather than pass
|
|
73
|
+
-- silently on the unterminated block. The fence marker (three backticks) is
|
|
74
|
+
-- built from its char code so this source stays backtick-free.
|
|
75
|
+
haskellBlocks :: String -> ([String], Bool)
|
|
74
76
|
haskellBlocks src = go (lines src)
|
|
75
77
|
where
|
|
76
78
|
fence3 = replicate 3 (toEnum 96 :: Char)
|
|
77
79
|
fenceHs = fence3 ++ "haskell"
|
|
78
|
-
go [] = []
|
|
80
|
+
go [] = ([], True)
|
|
79
81
|
go (l : ls)
|
|
80
82
|
| trimWs l == fenceHs =
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
case break (\\x -> trimWs x == fence3) ls of
|
|
84
|
+
(blk, []) -> ([unlines blk], False)
|
|
85
|
+
(blk, _ : rest) -> let (bs, ok) = go rest in (unlines blk : bs, ok)
|
|
83
86
|
| otherwise = go ls
|
|
84
87
|
|
|
85
88
|
|
|
86
|
-
-- Balanced (), [], {}
|
|
87
|
-
--
|
|
89
|
+
-- Balanced (), [], {} outside of double-quoted string literals, with each
|
|
90
|
+
-- closer matching the most-recent opener via a stack (so "([)]" is rejected,
|
|
91
|
+
-- not merely counted). The generated snippets never embed an escaped quote
|
|
92
|
+
-- inside a string.
|
|
88
93
|
balanced :: String -> Bool
|
|
89
|
-
balanced = go False
|
|
94
|
+
balanced = go False []
|
|
90
95
|
where
|
|
91
|
-
go inStr
|
|
92
|
-
go inStr
|
|
93
|
-
| c == '"' = go (not inStr)
|
|
94
|
-
| inStr = go inStr
|
|
95
|
-
| c == '('
|
|
96
|
+
go inStr stack [] = not inStr && null stack
|
|
97
|
+
go inStr stack (c : cs)
|
|
98
|
+
| c == '"' = go (not inStr) stack cs
|
|
99
|
+
| inStr = go inStr stack cs
|
|
100
|
+
| c == '(' = go inStr (')' : stack) cs
|
|
101
|
+
| c == '[' = go inStr (']' : stack) cs
|
|
102
|
+
| c == '{' = go inStr ('}' : stack) cs
|
|
96
103
|
| c == ')' || c == ']' || c == '}' =
|
|
97
|
-
|
|
98
|
-
|
|
104
|
+
case stack of
|
|
105
|
+
(top : rest) | top == c -> go inStr rest cs
|
|
106
|
+
_ -> False
|
|
107
|
+
| otherwise = go inStr stack cs
|
|
99
108
|
|
|
100
109
|
|
|
101
110
|
-- The three documents held to the gate, tagged by human label.
|
|
@@ -111,7 +120,8 @@ tests :: Counters -> IO ()
|
|
|
111
120
|
tests c =
|
|
112
121
|
forM_ docs (\\(label, path) -> do
|
|
113
122
|
src <- readDoc path
|
|
114
|
-
let blocks = haskellBlocks src
|
|
123
|
+
let (blocks, closed) = haskellBlocks src
|
|
124
|
+
runTest c (label ++ " haskell fences closed") (pure closed)
|
|
115
125
|
forM_ (zip [1 :: Int ..] blocks) (\\(i, blk) ->
|
|
116
126
|
runTest c (label ++ " haskell block " ++ show i ++ " well-formed")
|
|
117
127
|
(pure (not (null (trimWs blk)) && balanced blk))))
|
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
File, Content,
|
|
38
38
|
} from '@voxgig/sdkgen'
|
|
39
39
|
|
|
40
|
-
import { canonToType, opTypeName, opRequestShape, warnEntityTypeCollisions } from '@voxgig/sdkgen'
|
|
40
|
+
import { canonToType, opTypeName, opRequestShape, warnEntityTypeCollisions , deriveEntityNames } from '@voxgig/sdkgen'
|
|
41
41
|
|
|
42
42
|
import {
|
|
43
43
|
KIT,
|
|
@@ -134,11 +134,10 @@ const EntityTypes = cmp(function EntityTypes(props: any) {
|
|
|
134
134
|
// filter, so inactive entities still get class files referencing these
|
|
135
135
|
// typed names. Filter on `name` (always present), NOT `active` — parity
|
|
136
136
|
// with the go emitter's fix.
|
|
137
|
-
const entityList =
|
|
137
|
+
const entityList = deriveEntityNames(entity)
|
|
138
138
|
// Derive the PascalCase Name up-front — it is set LAZILY by names(), so an
|
|
139
139
|
// entity not yet named (e.g. a fieldless placeholder) would otherwise read
|
|
140
140
|
// `Name = undefined` below. Parity with the go/py/csharp emitter's fix.
|
|
141
|
-
entityList.forEach((e: any) => { if (null == e.Name) names(e, e.name) })
|
|
142
141
|
|
|
143
142
|
// Surface duplicate generated type names (two entities with the same
|
|
144
143
|
// 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 = {
|
|
@@ -42,7 +42,7 @@ const Entity = cmp(function Entity(props: any) {
|
|
|
42
42
|
|
|
43
43
|
File({ name: cls + '.' + target.ext }, () => {
|
|
44
44
|
|
|
45
|
-
const opnames = Object.keys(entity.op)
|
|
45
|
+
const opnames = Object.keys(entity.op || {})
|
|
46
46
|
|
|
47
47
|
// For each CRUD op: if the spec defines it, splice in the real
|
|
48
48
|
// implementation. Otherwise emit a stub that satisfies the SdkEntity
|
|
@@ -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,
|
|
@@ -18,7 +18,7 @@ const MainEntity = cmp(async function MainEntity(props: any) {
|
|
|
18
18
|
const { model } = props.ctx$
|
|
19
19
|
|
|
20
20
|
const javapackage = javaPackage(model)
|
|
21
|
-
const entityColl =
|
|
21
|
+
const entityColl = entityCollection(model)
|
|
22
22
|
const cls = entityClassName(entity, entityColl)
|
|
23
23
|
const accessor = javaVarName(entity.name)
|
|
24
24
|
|
|
@@ -31,7 +31,7 @@ const Package = cmp(async function Package(props: any) {
|
|
|
31
31
|
|
|
32
32
|
// Dep name convention: "groupId:artifactId" with an explicit version.
|
|
33
33
|
const deps: { groupId: string, artifactId: string, version: string, kind: string }[] = []
|
|
34
|
-
for (const d of collectDeps(model, target.name, target.deps)) {
|
|
34
|
+
for (const d of collectDeps(model, target.name, target.deps, ctx$.log)) {
|
|
35
35
|
const [dgroup, dartifact] = String(d.name).split(':')
|
|
36
36
|
if (dgroup && dartifact && d.version) {
|
|
37
37
|
deps.push({
|
|
@@ -95,6 +95,23 @@ public class ReadmeExamplesTest {
|
|
|
95
95
|
return blocks;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
// A well-formed doc has an even number of triple-backtick fence markers:
|
|
99
|
+
// every opening fence has a matching close. An odd count means a fence was
|
|
100
|
+
// opened but never closed — a truncated or malformed generated doc. The
|
|
101
|
+
// split-based javaBlocks() would silently treat the unterminated tail as a
|
|
102
|
+
// complete block, so this must be checked explicitly.
|
|
103
|
+
private static boolean fencesClosed(String text) {
|
|
104
|
+
String fence = String.valueOf((char) 96).repeat(3);
|
|
105
|
+
int count = 0;
|
|
106
|
+
int from = 0;
|
|
107
|
+
int idx;
|
|
108
|
+
while ((idx = text.indexOf(fence, from)) >= 0) {
|
|
109
|
+
count++;
|
|
110
|
+
from = idx + fence.length();
|
|
111
|
+
}
|
|
112
|
+
return count % 2 == 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
98
115
|
private static String readDoc(Path path, String label) {
|
|
99
116
|
assertTrue(Files.exists(path), label + " not found: " + path);
|
|
100
117
|
try {
|
|
@@ -158,7 +175,12 @@ public class ReadmeExamplesTest {
|
|
|
158
175
|
if (!Files.exists(path)) {
|
|
159
176
|
continue;
|
|
160
177
|
}
|
|
161
|
-
|
|
178
|
+
String src = readDoc(path, doc[0]);
|
|
179
|
+
if (!fencesClosed(src)) {
|
|
180
|
+
failures.add(doc[0] +
|
|
181
|
+
" has an unclosed code fence (opened but never closed)");
|
|
182
|
+
}
|
|
183
|
+
List<String> blocks = javaBlocks(src);
|
|
162
184
|
int balancedCount = 0;
|
|
163
185
|
for (int i = 0; i < blocks.size(); i++) {
|
|
164
186
|
if (balanced(blocks.get(i))) {
|
|
@@ -75,7 +75,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
75
75
|
|
|
76
76
|
const authActive = isAuthActive(model)
|
|
77
77
|
|
|
78
|
-
const opnames = Object.keys(entity.op)
|
|
78
|
+
const opnames = Object.keys(entity.op || {})
|
|
79
79
|
const hasLoad = opnames.includes('load')
|
|
80
80
|
const hasList = opnames.includes('list')
|
|
81
81
|
|
|
@@ -83,8 +83,8 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
83
83
|
return
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
const loadOp = entity.op
|
|
87
|
-
const listOp = entity.op
|
|
86
|
+
const loadOp = entity.op?.load
|
|
87
|
+
const listOp = entity.op?.list
|
|
88
88
|
|
|
89
89
|
// Get load point info
|
|
90
90
|
const loadPoint = loadOp?.points?.[0]
|