@voxgig/sdkgen 1.3.17 → 1.3.18
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/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/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 +3 -1
- package/dist/helpers/naming.js +53 -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/sdkgen.d.ts +3 -3
- package/dist/sdkgen.js +6 -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/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 +4 -1
- 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 +9 -1
- 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/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/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/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/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/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/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/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 +3 -4
- 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/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/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/test/PrimaryUtilityTest.cs +10 -28
- package/project/.sdk/tm/dart/test/primary_test.dart +7 -0
- package/project/.sdk/tm/go/feature/test_feature.go +33 -1
- package/project/.sdk/tm/go/test/primary_utility_test.go +41 -42
- package/project/.sdk/tm/go/test/runner_test.go +30 -1
- package/project/.sdk/tm/java/test/PrimaryUtilityTest.java +7 -24
- package/project/.sdk/tm/js/src/feature/test/TestFeature.js +18 -1
- package/project/.sdk/tm/js/test/utility/PrimaryUtility.test.js +8 -0
- 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/test/primary_utility_test.lua +10 -8
- package/project/.sdk/tm/perl/t/primary_utility.t +8 -17
- package/project/.sdk/tm/php/test/PrimaryUtilityTest.php +9 -7
- package/project/.sdk/tm/py/feature/test_feature.py +28 -1
- package/project/.sdk/tm/py/test/test_primary_utility.py +13 -18
- package/project/.sdk/tm/rb/feature/test_feature.rb +24 -1
- package/project/.sdk/tm/rb/test/primary_utility_test.rb +7 -8
- 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/Tests/ProjectNameSDKTests/PrimaryUtilityTest.swift +7 -8
- package/project/.sdk/tm/ts/src/feature/test/TestFeature.ts +18 -1
- package/project/.sdk/tm/ts/test/utility/PrimaryUtility.test.ts +65 -21
- package/src/cmp/Entity.ts +5 -1
- package/src/cmp/Feature.ts +2 -1
- package/src/helpers/canonType.ts +8 -3
- package/src/helpers/collectDeps.ts +39 -12
- package/src/helpers/naming.ts +59 -0
- package/src/helpers/opShape.ts +99 -12
- package/src/sdkgen.ts +7 -3
|
@@ -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,
|
|
@@ -12,7 +12,7 @@ const MainEntity = cmp(async function MainEntity(props: any) {
|
|
|
12
12
|
const { model } = props.ctx$
|
|
13
13
|
|
|
14
14
|
// Collision-free entity CLASS name (see entityClassName).
|
|
15
|
-
const entityColl =
|
|
15
|
+
const entityColl = entityCollection(model)
|
|
16
16
|
const cls = entityClassName(entity, entityColl)
|
|
17
17
|
|
|
18
18
|
const Name = model.const.Name
|
|
@@ -28,7 +28,7 @@ const Package = cmp(async function Package(props: any) {
|
|
|
28
28
|
const Name = model.const.Name
|
|
29
29
|
|
|
30
30
|
const deps: Record<string, string> = {}
|
|
31
|
-
for (const d of collectDeps(model, target.name, target.deps)) {
|
|
31
|
+
for (const d of collectDeps(model, target.name, target.deps, ctx$.log)) {
|
|
32
32
|
deps[d.name] = d.source === 'target' ? (d.version || '0.0.0') : d.version
|
|
33
33
|
}
|
|
34
34
|
// Vendored, dependency-free by design; declared deps (if any) are ignored
|
|
@@ -43,7 +43,9 @@ const ReadmeExamplesTest = cmp(function ReadmeExamplesTest(props: any) {
|
|
|
43
43
|
// Checks, PER DOCUMENT that exists:
|
|
44
44
|
// 1. PRESENCE: the doc holds at least one swift block.
|
|
45
45
|
// 2. STRUCTURE: every swift block's braces / parens / brackets balance, so a
|
|
46
|
-
// truncated or malformed generated snippet fails loudly.
|
|
46
|
+
// truncated or malformed generated snippet fails loudly. An unclosed fence
|
|
47
|
+
// (odd number of fence markers) also fails, rather than silently absorbing
|
|
48
|
+
// the trailing text as a block.
|
|
47
49
|
//
|
|
48
50
|
// GENERATED by @voxgig/sdkgen — do not edit by hand.
|
|
49
51
|
|
|
@@ -94,6 +96,16 @@ final class ReadmeExamplesTest: XCTestCase {
|
|
|
94
96
|
return blocks
|
|
95
97
|
}
|
|
96
98
|
|
|
99
|
+
// True when the doc has a fence that was opened but never closed. A
|
|
100
|
+
// well-formed doc holds fence markers in open/close pairs, so an ODD number
|
|
101
|
+
// of markers means the final fence dangles — the split-based scan above would
|
|
102
|
+
// otherwise silently treat the truncated tail as a block. This is the
|
|
103
|
+
// structural analogue of an at-EOF "still inside a block" check.
|
|
104
|
+
private func hasUnclosedFence(_ text: String) -> Bool {
|
|
105
|
+
let fenceCount = text.components(separatedBy: fence).count - 1
|
|
106
|
+
return fenceCount % 2 != 0
|
|
107
|
+
}
|
|
108
|
+
|
|
97
109
|
// True when every open/close delimiter balances, ignoring characters inside
|
|
98
110
|
// string literals and line comments (a generated snippet never nests an
|
|
99
111
|
// unbalanced delimiter outside those, and this catches truncation).
|
|
@@ -149,6 +161,11 @@ final class ReadmeExamplesTest: XCTestCase {
|
|
|
149
161
|
var failures: [String] = []
|
|
150
162
|
for doc in docs() {
|
|
151
163
|
guard let text = read(doc.path) else { continue }
|
|
164
|
+
// A fence opened but never closed is a malformed doc — fail loudly rather
|
|
165
|
+
// than silently absorbing the unterminated tail as a block.
|
|
166
|
+
if hasUnclosedFence(text) {
|
|
167
|
+
failures.append(doc.label + " has an unclosed swift code fence")
|
|
168
|
+
}
|
|
152
169
|
let blocks = swiftBlocks(text)
|
|
153
170
|
var balancedCount = 0
|
|
154
171
|
for (i, b) in blocks.enumerated() {
|
|
@@ -24,7 +24,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
24
24
|
|
|
25
25
|
const Name = model.const.Name
|
|
26
26
|
|
|
27
|
-
const opnames = Object.keys(entity.op)
|
|
27
|
+
const opnames = Object.keys(entity.op || {})
|
|
28
28
|
if (!opnames.includes('load') && !opnames.includes('list')) {
|
|
29
29
|
return
|
|
30
30
|
}
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
File, Content,
|
|
22
22
|
} from '@voxgig/sdkgen'
|
|
23
23
|
|
|
24
|
-
import { canonToType, opTypeName, opRequestShape, warnEntityTypeCollisions } from '@voxgig/sdkgen'
|
|
24
|
+
import { canonToType, opTypeName, opRequestShape, warnEntityTypeCollisions , deriveEntityNames } from '@voxgig/sdkgen'
|
|
25
25
|
|
|
26
26
|
import {
|
|
27
27
|
KIT,
|
|
@@ -51,11 +51,10 @@ const EntityTypes = cmp(function EntityTypes(props: any) {
|
|
|
51
51
|
// filter, so inactive entities still get class files referencing these
|
|
52
52
|
// typed names. Filter on `name` (always present), NOT `active` — parity
|
|
53
53
|
// with the go emitter's fix.
|
|
54
|
-
const entityList =
|
|
54
|
+
const entityList = deriveEntityNames(entity)
|
|
55
55
|
// Derive the PascalCase Name up-front — it is set LAZILY by names(), so an
|
|
56
56
|
// entity not yet named (e.g. a fieldless placeholder) would otherwise read
|
|
57
57
|
// `Name = undefined` below. Parity with the go emitter's fix.
|
|
58
|
-
entityList.forEach((e: any) => { if (null == e.Name) names(e, e.name) })
|
|
59
58
|
|
|
60
59
|
// Surface duplicate generated type names (two entities with the same
|
|
61
60
|
// 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
|
-
opTypeName, entityClassName,
|
|
7
|
+
opTypeName, entityClassName, entityCollection,
|
|
8
8
|
} from '@voxgig/sdkgen'
|
|
9
9
|
|
|
10
10
|
import {
|
|
@@ -24,7 +24,7 @@ const Entity = cmp(function Entity(props: any) {
|
|
|
24
24
|
// `<Name>Entity`, disambiguated when it would clash with another entity's
|
|
25
25
|
// data-type name. The DATA type stays `<Name>`. The class file name and the
|
|
26
26
|
// Main import path both use this, so they always agree.
|
|
27
|
-
const entityColl =
|
|
27
|
+
const entityColl = entityCollection(model)
|
|
28
28
|
const cls = entityClassName(entity, entityColl)
|
|
29
29
|
|
|
30
30
|
const entrep = {
|
|
@@ -52,7 +52,7 @@ const Entity = cmp(function Entity(props: any) {
|
|
|
52
52
|
|
|
53
53
|
File({ name: cls + '.' + target.name }, () => {
|
|
54
54
|
|
|
55
|
-
const opnames = Object.keys(entity.op)
|
|
55
|
+
const opnames = Object.keys(entity.op || {})
|
|
56
56
|
|
|
57
57
|
const opfrags =
|
|
58
58
|
(['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 TYPE (entityClassName); the accessor METHOD
|
|
16
16
|
// name (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(`import { ${cls} } from './entity/${cls}'`)
|
|
62
62
|
})
|
|
63
63
|
|
|
@@ -49,7 +49,7 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
49
49
|
apikey: env.${PROJECTNAME}_APIKEY,`
|
|
50
50
|
: ''
|
|
51
51
|
|
|
52
|
-
const opnames = Object.keys(entity.op)
|
|
52
|
+
const opnames = Object.keys(entity.op || {})
|
|
53
53
|
const hasLoad = opnames.includes('load')
|
|
54
54
|
const hasList = opnames.includes('list')
|
|
55
55
|
|
|
@@ -151,7 +151,7 @@ function unwrapListData(data: any): any[] | null {
|
|
|
151
151
|
|
|
152
152
|
|
|
153
153
|
function generateDirectLoad(model: Model, entity: ModelEntity) {
|
|
154
|
-
const loadOp = entity.op
|
|
154
|
+
const loadOp = entity.op?.load
|
|
155
155
|
const loadPoint: ModelPoint | undefined = loadOp?.points?.[0]
|
|
156
156
|
|
|
157
157
|
if (null == loadPoint) {
|
|
@@ -198,7 +198,7 @@ function generateDirectLoad(model: Model, entity: ModelEntity) {
|
|
|
198
198
|
.join('\n')
|
|
199
199
|
|
|
200
200
|
// Get list info for live mode bootstrapping
|
|
201
|
-
const listOp = entity.op
|
|
201
|
+
const listOp = entity.op?.list
|
|
202
202
|
const listPoint = listOp?.points?.[0]
|
|
203
203
|
const listParams = listPoint?.args?.params || []
|
|
204
204
|
const listPath = listPoint ? normalizePathParams(listPoint.parts || [], listParams, listPoint.rename?.param) : ''
|
|
@@ -356,7 +356,7 @@ ${paramAsserts} }
|
|
|
356
356
|
|
|
357
357
|
|
|
358
358
|
function generateDirectList(model: Model, entity: ModelEntity) {
|
|
359
|
-
const listOp = entity.op
|
|
359
|
+
const listOp = entity.op?.list
|
|
360
360
|
const listPoint: ModelPoint | undefined = listOp?.points?.[0]
|
|
361
361
|
|
|
362
362
|
if (null == listPoint) {
|
|
@@ -4,7 +4,7 @@ import * as Path from 'node:path'
|
|
|
4
4
|
import {
|
|
5
5
|
cmp, camelify,
|
|
6
6
|
File, Content, Folder, Fragment,
|
|
7
|
-
entityClassName,
|
|
7
|
+
entityClassName, entityCollection,
|
|
8
8
|
} from '@voxgig/sdkgen'
|
|
9
9
|
|
|
10
10
|
import {
|
|
@@ -20,7 +20,7 @@ const Entity = cmp(function Entity(props: any) {
|
|
|
20
20
|
const { model, stdrep } = props.ctx$
|
|
21
21
|
const { target, entity } = props
|
|
22
22
|
|
|
23
|
-
const entityColl =
|
|
23
|
+
const entityColl = entityCollection(model)
|
|
24
24
|
const cls = entityClassName(entity, entityColl)
|
|
25
25
|
|
|
26
26
|
const entrep = {
|
|
@@ -34,7 +34,7 @@ const Entity = cmp(function Entity(props: any) {
|
|
|
34
34
|
|
|
35
35
|
File({ name: zigVarName(entity.name) + '.' + target.ext }, () => {
|
|
36
36
|
|
|
37
|
-
const opnames = Object.keys(entity.op)
|
|
37
|
+
const opnames = Object.keys(entity.op || {})
|
|
38
38
|
|
|
39
39
|
// For each CRUD op: if the spec defines it, splice in the real
|
|
40
40
|
// implementation. Otherwise emit a stub returning the unsupported_op
|
|
@@ -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,
|
|
@@ -16,7 +16,7 @@ const MainEntity = cmp(async function MainEntity(props: any) {
|
|
|
16
16
|
const { entity } = props
|
|
17
17
|
const { model } = props.ctx$
|
|
18
18
|
|
|
19
|
-
const entityColl =
|
|
19
|
+
const entityColl = entityCollection(model)
|
|
20
20
|
const cls = entityClassName(entity, entityColl)
|
|
21
21
|
const method = zigVarName(entity.name)
|
|
22
22
|
const mod = zigVarName(entity.name)
|
|
@@ -23,8 +23,16 @@ import { zigModuleName } from './utility_zig'
|
|
|
23
23
|
//
|
|
24
24
|
// The `.paths` allow-list mirrors the (registry-less) template: it only
|
|
25
25
|
// matters when packaging for a registry, which zig does not do, so it is kept
|
|
26
|
-
// stable. `.name` is a plain string here
|
|
27
|
-
//
|
|
26
|
+
// stable. `.name` is a plain string here rather than the newer enum-literal +
|
|
27
|
+
// fingerprint form.
|
|
28
|
+
//
|
|
29
|
+
// TOOLCHAIN PIN: the string form REQUIRES zig <= 0.13. Zig 0.14 rejects it
|
|
30
|
+
// outright — `build.zig.zon:2:13: error: expected enum literal` — so the
|
|
31
|
+
// generated SDK will not build at all on a newer toolchain. The consumer CI
|
|
32
|
+
// job pins 0.13.0 to match (create-sdkgen
|
|
33
|
+
// project/standard/.github/workflows/ci.yml). Moving to a newer zig means
|
|
34
|
+
// changing BOTH: `.name = .${name}` plus a `.fingerprint` here, and the CI
|
|
35
|
+
// pin there.
|
|
28
36
|
const Package = cmp(async function Package(props: any) {
|
|
29
37
|
const ctx$ = props.ctx$
|
|
30
38
|
const model: Model = ctx$.model
|
|
@@ -669,23 +669,16 @@ static void prepareParamsBasic() {
|
|
|
669
669
|
// --- preparePath ------------------------------------------------------------
|
|
670
670
|
|
|
671
671
|
static void preparePathBasic() {
|
|
672
|
+
// Was hand-written cases that had drifted out of the shared corpus (the
|
|
673
|
+
// preparePath fixture shipped as an empty `set: []`).
|
|
672
674
|
auto c = client();
|
|
673
675
|
UtilityPtr utility = c->getUtility();
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
static void preparePathSingle() {
|
|
682
|
-
auto c = client();
|
|
683
|
-
UtilityPtr utility = c->getUtility();
|
|
684
|
-
CtxPtr ctx = makeTestFullCtx(c, utility);
|
|
685
|
-
ctx->point = fhMap({
|
|
686
|
-
{"parts", vlist({Value("items")})},
|
|
687
|
-
{"args", fhMap({{"params", vlist()}})}});
|
|
688
|
-
ASSERT_EQ(utility->preparePath(ctx), std::string("items"), "expected items");
|
|
676
|
+
rs::runset("preparePath-basic", rs::get_spec(primary(), {"preparePath", "basic"}),
|
|
677
|
+
[&](const Value& entry) -> Value {
|
|
678
|
+
Value ctxmap = Helpers::toMapAny(getp(entry, "ctx"));
|
|
679
|
+
CtxPtr ctx = rs::make_ctx_from_map(ctxmap, c, utility);
|
|
680
|
+
return Value(utility->preparePath(ctx));
|
|
681
|
+
});
|
|
689
682
|
}
|
|
690
683
|
|
|
691
684
|
// --- prepareQuery -----------------------------------------------------------
|
|
@@ -830,7 +823,6 @@ int main() {
|
|
|
830
823
|
T_RUN(prepareMethodBasic);
|
|
831
824
|
T_RUN(prepareParamsBasic);
|
|
832
825
|
T_RUN(preparePathBasic);
|
|
833
|
-
T_RUN(preparePathSingle);
|
|
834
826
|
T_RUN(prepareQueryBasic);
|
|
835
827
|
T_RUN(resultBasicBasic);
|
|
836
828
|
T_RUN(resultBodyBasic);
|
|
@@ -789,38 +789,20 @@ public class PrimaryUtilityTest
|
|
|
789
789
|
});
|
|
790
790
|
}
|
|
791
791
|
|
|
792
|
+
// Was two hand-written cases that had drifted out of the shared corpus
|
|
793
|
+
// (the preparePath fixture shipped as an empty `set: []`). Now driven by
|
|
794
|
+
// the corpus like every other section, so all ports assert the same
|
|
795
|
+
// separator / blank-segment behaviour.
|
|
792
796
|
[Fact]
|
|
793
797
|
public void PreparePathBasic()
|
|
794
798
|
{
|
|
795
|
-
|
|
796
|
-
ctx.Point = new Dictionary<string, object?>
|
|
799
|
+
TestRunner.RunSet(TestRunner.GetSpec(_primary, "preparePath", "basic"), entry =>
|
|
797
800
|
{
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
};
|
|
804
|
-
|
|
805
|
-
var path = _utility.PreparePath(ctx);
|
|
806
|
-
Assert.Equal("api/planet/{id}", path);
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
[Fact]
|
|
810
|
-
public void PreparePathSingle()
|
|
811
|
-
{
|
|
812
|
-
var ctx = MakeTestFullCtx(_client, _utility);
|
|
813
|
-
ctx.Point = new Dictionary<string, object?>
|
|
814
|
-
{
|
|
815
|
-
["parts"] = new List<object?> { "items" },
|
|
816
|
-
["args"] = new Dictionary<string, object?>
|
|
817
|
-
{
|
|
818
|
-
["params"] = new List<object?>(),
|
|
819
|
-
},
|
|
820
|
-
};
|
|
821
|
-
|
|
822
|
-
var path = _utility.PreparePath(ctx);
|
|
823
|
-
Assert.Equal("items", path);
|
|
801
|
+
var ctxmap = entry.TryGetValue("ctx", out var c)
|
|
802
|
+
? c as Dictionary<string, object?> : null;
|
|
803
|
+
var ctx = TestRunner.MakeCtxFromMap(ctxmap, _client, _utility);
|
|
804
|
+
return _utility.PreparePath(ctx);
|
|
805
|
+
});
|
|
824
806
|
}
|
|
825
807
|
|
|
826
808
|
[Fact]
|
|
@@ -94,6 +94,13 @@ void tests() {
|
|
|
94
94
|
await _runset(_g('prepareQuery.basic'), _utility.prepareQuery);
|
|
95
95
|
});
|
|
96
96
|
|
|
97
|
+
// preparePath shipped as an empty `set: []`, so no port drove it and
|
|
98
|
+
// several kept private hand-written cases instead.
|
|
99
|
+
test('path-basic', (t) async {
|
|
100
|
+
await _setup();
|
|
101
|
+
await _runset(_g('preparePath.basic'), _utility.preparePath);
|
|
102
|
+
});
|
|
103
|
+
|
|
97
104
|
test('body-basic', (t) async {
|
|
98
105
|
await _setup();
|
|
99
106
|
await _runset(_g('prepareBody.basic'), (dynamic ctx) {
|
|
@@ -3,12 +3,17 @@ package feature
|
|
|
3
3
|
import (
|
|
4
4
|
"fmt"
|
|
5
5
|
"math/rand"
|
|
6
|
+
"regexp"
|
|
6
7
|
|
|
7
8
|
vs "github.com/voxgig/struct"
|
|
8
9
|
|
|
9
10
|
"GOMODULE/core"
|
|
10
11
|
)
|
|
11
12
|
|
|
13
|
+
// The `body.<key>` form of an op's response transform: the mock wraps its
|
|
14
|
+
// payload in <key> so the transform can unwrap it again.
|
|
15
|
+
var envelopeResRe = regexp.MustCompile("^`body\\.([^`.]+)`$")
|
|
16
|
+
|
|
12
17
|
type TestFeature struct {
|
|
13
18
|
BaseFeature
|
|
14
19
|
client *core.ProjectNameSDK
|
|
@@ -49,11 +54,38 @@ func (f *TestFeature) Init(ctx *core.Context, options map[string]any) {
|
|
|
49
54
|
self := f
|
|
50
55
|
|
|
51
56
|
testFetcher := func(ctx *core.Context, _fullurl string, _fetchdef map[string]any) (any, error) {
|
|
57
|
+
// Shape the mock payload the way the real API would, so the op's
|
|
58
|
+
// response transform recovers the entity from it. A point carrying
|
|
59
|
+
// `transform.res: ` + "`body.item`" + ` describes an API that answers
|
|
60
|
+
// {"item": {...}}; handing back the bare entity means the transform
|
|
61
|
+
// unwraps a property that is not there and the caller gets nil. The
|
|
62
|
+
// mock has to agree with the model, or it only ever simulates APIs
|
|
63
|
+
// whose responses happen to be unwrapped. Mirrors the ts mock.
|
|
64
|
+
envelope := func(data any) any {
|
|
65
|
+
if data == nil || ctx.Point == nil {
|
|
66
|
+
return data
|
|
67
|
+
}
|
|
68
|
+
tm, ok := ctx.Point["transform"].(map[string]any)
|
|
69
|
+
if !ok {
|
|
70
|
+
return data
|
|
71
|
+
}
|
|
72
|
+
restf, ok := tm["res"].(string)
|
|
73
|
+
if !ok {
|
|
74
|
+
return data
|
|
75
|
+
}
|
|
76
|
+
m := envelopeResRe.FindStringSubmatch(restf)
|
|
77
|
+
if m == nil {
|
|
78
|
+
return data
|
|
79
|
+
}
|
|
80
|
+
return map[string]any{m[1]: data}
|
|
81
|
+
}
|
|
82
|
+
|
|
52
83
|
respond := func(status int, data any, extra map[string]any) map[string]any {
|
|
84
|
+
payload := envelope(data)
|
|
53
85
|
out := map[string]any{
|
|
54
86
|
"status": status,
|
|
55
87
|
"statusText": "OK",
|
|
56
|
-
"json": (func() any)(func() any { return
|
|
88
|
+
"json": (func() any)(func() any { return payload }),
|
|
57
89
|
"body": "not-used",
|
|
58
90
|
}
|
|
59
91
|
if extra != nil {
|