@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.
Files changed (267) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/dist/cmp/Deploy.js +16 -16
  3. package/dist/cmp/Deploy.js.map +1 -1
  4. package/dist/cmp/Entity.js +5 -1
  5. package/dist/cmp/Entity.js.map +1 -1
  6. package/dist/cmp/Feature.js +2 -1
  7. package/dist/cmp/Feature.js.map +1 -1
  8. package/dist/cmp/ReadmeTop.js +13 -11
  9. package/dist/cmp/ReadmeTop.js.map +1 -1
  10. package/dist/helpers/canonType.js +8 -3
  11. package/dist/helpers/canonType.js.map +1 -1
  12. package/dist/helpers/collectDeps.d.ts +1 -1
  13. package/dist/helpers/collectDeps.js +36 -13
  14. package/dist/helpers/collectDeps.js.map +1 -1
  15. package/dist/helpers/naming.d.ts +5 -1
  16. package/dist/helpers/naming.js +118 -0
  17. package/dist/helpers/naming.js.map +1 -1
  18. package/dist/helpers/opShape.d.ts +3 -1
  19. package/dist/helpers/opShape.js +87 -8
  20. package/dist/helpers/opShape.js.map +1 -1
  21. package/dist/helpers/serverVars.d.ts +10 -0
  22. package/dist/helpers/serverVars.js +87 -0
  23. package/dist/helpers/serverVars.js.map +1 -0
  24. package/dist/sdkgen.d.ts +4 -3
  25. package/dist/sdkgen.js +11 -2
  26. package/dist/sdkgen.js.map +1 -1
  27. package/dist/tsconfig.tsbuildinfo +1 -1
  28. package/package.json +15 -10
  29. package/project/.sdk/model/target/cpp.aontu +4 -4
  30. package/project/.sdk/model/target/go-cli.aontu +17 -17
  31. package/project/.sdk/model/target/go-mcp.aontu +11 -11
  32. package/project/.sdk/model/target/go.aontu +1 -1
  33. package/project/.sdk/model/target/java.aontu +4 -4
  34. package/project/.sdk/model/target/kotlin.aontu +4 -4
  35. package/project/.sdk/model/target/lean.aontu +51 -0
  36. package/project/.sdk/model/target/scala.aontu +4 -4
  37. package/project/.sdk/src/cmp/c/EntityTypes_c.ts +3 -4
  38. package/project/.sdk/src/cmp/c/Entity_c.ts +3 -3
  39. package/project/.sdk/src/cmp/c/ReadmeExamplesTest_c.ts +24 -7
  40. package/project/.sdk/src/cmp/c/TestDirect_c.ts +3 -3
  41. package/project/.sdk/src/cmp/c/TestEntity_c.ts +1 -1
  42. package/project/.sdk/src/cmp/clojure/Entity_clojure.ts +1 -1
  43. package/project/.sdk/src/cmp/clojure/ReadmeExamplesTest_clojure.ts +19 -8
  44. package/project/.sdk/src/cmp/cpp/EntityTypes_cpp.ts +2 -2
  45. package/project/.sdk/src/cmp/cpp/Entity_cpp.ts +3 -3
  46. package/project/.sdk/src/cmp/cpp/MainEntity_cpp.ts +2 -2
  47. package/project/.sdk/src/cmp/cpp/ReadmeExamplesTest_cpp.ts +136 -0
  48. package/project/.sdk/src/cmp/cpp/TestDirect_cpp.ts +3 -3
  49. package/project/.sdk/src/cmp/cpp/Test_cpp.ts +4 -0
  50. package/project/.sdk/src/cmp/csharp/EntityTypes_csharp.ts +2 -3
  51. package/project/.sdk/src/cmp/csharp/Entity_csharp.ts +3 -3
  52. package/project/.sdk/src/cmp/csharp/MainEntity_csharp.ts +2 -2
  53. package/project/.sdk/src/cmp/csharp/Package_csharp.ts +1 -1
  54. package/project/.sdk/src/cmp/csharp/ReadmeExamplesTest_csharp.ts +13 -1
  55. package/project/.sdk/src/cmp/csharp/TestDirect_csharp.ts +3 -3
  56. package/project/.sdk/src/cmp/csharp/TestEntity_csharp.ts +22 -15
  57. package/project/.sdk/src/cmp/dart/EntityTypes_dart.ts +2 -3
  58. package/project/.sdk/src/cmp/dart/Entity_dart.ts +3 -3
  59. package/project/.sdk/src/cmp/dart/MainEntity_dart.ts +2 -2
  60. package/project/.sdk/src/cmp/dart/Main_dart.ts +3 -3
  61. package/project/.sdk/src/cmp/dart/Package_dart.ts +1 -1
  62. package/project/.sdk/src/cmp/dart/TestDirect_dart.ts +4 -4
  63. package/project/.sdk/src/cmp/elixir/EntityTypes_elixir.ts +2 -3
  64. package/project/.sdk/src/cmp/elixir/Entity_elixir.ts +1 -1
  65. package/project/.sdk/src/cmp/elixir/ReadmeExamplesTest_elixir.ts +21 -3
  66. package/project/.sdk/src/cmp/go/Config_go.ts +14 -2
  67. package/project/.sdk/src/cmp/go/EntityTypes_go.ts +110 -18
  68. package/project/.sdk/src/cmp/go/Entity_go.ts +3 -3
  69. package/project/.sdk/src/cmp/go/Main_go.ts +7 -6
  70. package/project/.sdk/src/cmp/go/Package_go.ts +1 -1
  71. package/project/.sdk/src/cmp/go/TestDirect_go.ts +3 -3
  72. package/project/.sdk/src/cmp/go/TestEntity_go.ts +1 -1
  73. package/project/.sdk/src/cmp/go/utility_go.ts +25 -0
  74. package/project/.sdk/src/cmp/go-cli/Main_go-cli.ts +62 -35
  75. package/project/.sdk/src/cmp/go-cli/fragment/main.fragment.go +7 -7
  76. package/project/.sdk/src/cmp/go-cli/fragment/words.fragment.go +21 -18
  77. package/project/.sdk/src/cmp/go-mcp/Main_go-mcp.ts +9 -1
  78. package/project/.sdk/src/cmp/haskell/ReadmeExamplesTest_haskell.ts +28 -18
  79. package/project/.sdk/src/cmp/java/EntityTypes_java.ts +2 -3
  80. package/project/.sdk/src/cmp/java/Entity_java.ts +3 -3
  81. package/project/.sdk/src/cmp/java/MainEntity_java.ts +2 -2
  82. package/project/.sdk/src/cmp/java/Package_java.ts +1 -1
  83. package/project/.sdk/src/cmp/java/ReadmeExamplesTest_java.ts +23 -1
  84. package/project/.sdk/src/cmp/java/TestDirect_java.ts +3 -3
  85. package/project/.sdk/src/cmp/js/Config_js.ts +11 -0
  86. package/project/.sdk/src/cmp/js/EntityTypes_js.ts +2 -3
  87. package/project/.sdk/src/cmp/js/Entity_js.ts +3 -3
  88. package/project/.sdk/src/cmp/js/MainEntity_js.ts +2 -2
  89. package/project/.sdk/src/cmp/js/Main_js.ts +2 -2
  90. package/project/.sdk/src/cmp/js/TestDirect_js.ts +4 -4
  91. package/project/.sdk/src/cmp/js/fragment/Config.fragment.js +2 -2
  92. package/project/.sdk/src/cmp/js/fragment/Direct.test.fragment.js +4 -0
  93. package/project/.sdk/src/cmp/kotlin/EntityTypes_kotlin.ts +2 -3
  94. package/project/.sdk/src/cmp/kotlin/Entity_kotlin.ts +3 -3
  95. package/project/.sdk/src/cmp/kotlin/MainEntity_kotlin.ts +2 -2
  96. package/project/.sdk/src/cmp/kotlin/Package_kotlin.ts +1 -1
  97. package/project/.sdk/src/cmp/kotlin/ReadmeExamplesTest_kotlin.ts +27 -2
  98. package/project/.sdk/src/cmp/kotlin/TestDirect_kotlin.ts +3 -3
  99. package/project/.sdk/src/cmp/lean/Config_lean.ts +88 -0
  100. package/project/.sdk/src/cmp/lean/Entity_lean.ts +9 -0
  101. package/project/.sdk/src/cmp/lean/Gitignore_lean.ts +18 -0
  102. package/project/.sdk/src/cmp/lean/Main_lean.ts +120 -0
  103. package/project/.sdk/src/cmp/lean/Package_lean.ts +68 -0
  104. package/project/.sdk/src/cmp/lean/ReadmeEntity_lean.ts +29 -0
  105. package/project/.sdk/src/cmp/lean/ReadmeExplanation_lean.ts +19 -0
  106. package/project/.sdk/src/cmp/lean/ReadmeHowto_lean.ts +25 -0
  107. package/project/.sdk/src/cmp/lean/ReadmeInstall_lean.ts +38 -0
  108. package/project/.sdk/src/cmp/lean/ReadmeIntro_lean.ts +25 -0
  109. package/project/.sdk/src/cmp/lean/ReadmeModel_lean.ts +24 -0
  110. package/project/.sdk/src/cmp/lean/ReadmeOptions_lean.ts +22 -0
  111. package/project/.sdk/src/cmp/lean/ReadmeQuick_lean.ts +50 -0
  112. package/project/.sdk/src/cmp/lean/ReadmeRef_lean.ts +16 -0
  113. package/project/.sdk/src/cmp/lean/ReadmeTopHowto_lean.ts +16 -0
  114. package/project/.sdk/src/cmp/lean/ReadmeTopQuick_lean.ts +23 -0
  115. package/project/.sdk/src/cmp/lean/ReadmeTopTest_lean.ts +18 -0
  116. package/project/.sdk/src/cmp/lean/Test_lean.ts +207 -0
  117. package/project/.sdk/src/cmp/lean/utility_lean.ts +78 -0
  118. package/project/.sdk/src/cmp/lua/Config_lua.ts +10 -1
  119. package/project/.sdk/src/cmp/lua/EntityTypes_lua.ts +2 -3
  120. package/project/.sdk/src/cmp/lua/Entity_lua.ts +3 -3
  121. package/project/.sdk/src/cmp/lua/Package_lua.ts +1 -1
  122. package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +3 -3
  123. package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +1 -1
  124. package/project/.sdk/src/cmp/ocaml/ReadmeExamplesTest_ocaml.ts +29 -14
  125. package/project/.sdk/src/cmp/perl/Entity_perl.ts +3 -3
  126. package/project/.sdk/src/cmp/perl/MainEntity_perl.ts +2 -2
  127. package/project/.sdk/src/cmp/perl/Package_perl.ts +1 -1
  128. package/project/.sdk/src/cmp/perl/TestDirect_perl.ts +3 -3
  129. package/project/.sdk/src/cmp/php/Config_php.ts +13 -2
  130. package/project/.sdk/src/cmp/php/EntityTypes_php.ts +2 -3
  131. package/project/.sdk/src/cmp/php/Entity_php.ts +3 -3
  132. package/project/.sdk/src/cmp/php/MainEntity_php.ts +2 -2
  133. package/project/.sdk/src/cmp/php/Package_php.ts +1 -1
  134. package/project/.sdk/src/cmp/php/TestDirect_php.ts +3 -3
  135. package/project/.sdk/src/cmp/php/TestEntity_php.ts +1 -1
  136. package/project/.sdk/src/cmp/py/Config_py.ts +10 -1
  137. package/project/.sdk/src/cmp/py/EntityTypes_py.ts +2 -3
  138. package/project/.sdk/src/cmp/py/Entity_py.ts +3 -3
  139. package/project/.sdk/src/cmp/py/MainEntity_py.ts +2 -2
  140. package/project/.sdk/src/cmp/py/Main_py.ts +2 -2
  141. package/project/.sdk/src/cmp/py/Package_py.ts +1 -1
  142. package/project/.sdk/src/cmp/py/TestDirect_py.ts +3 -3
  143. package/project/.sdk/src/cmp/py/TestEntity_py.ts +1 -1
  144. package/project/.sdk/src/cmp/rb/Config_rb.ts +12 -1
  145. package/project/.sdk/src/cmp/rb/EntityTypes_rb.ts +15 -5
  146. package/project/.sdk/src/cmp/rb/Entity_rb.ts +3 -3
  147. package/project/.sdk/src/cmp/rb/MainEntity_rb.ts +2 -2
  148. package/project/.sdk/src/cmp/rb/Package_rb.ts +2 -2
  149. package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +3 -3
  150. package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +1 -1
  151. package/project/.sdk/src/cmp/rust/EntityBase_rust.ts +2 -2
  152. package/project/.sdk/src/cmp/rust/EntityTypes_rust.ts +3 -4
  153. package/project/.sdk/src/cmp/rust/Entity_rust.ts +3 -3
  154. package/project/.sdk/src/cmp/rust/MainEntity_rust.ts +2 -2
  155. package/project/.sdk/src/cmp/rust/Package_rust.ts +1 -1
  156. package/project/.sdk/src/cmp/rust/ReadmeExamplesTest_rust.ts +22 -10
  157. package/project/.sdk/src/cmp/rust/TestDirect_rust.ts +3 -3
  158. package/project/.sdk/src/cmp/rust/TestEntity_rust.ts +25 -18
  159. package/project/.sdk/src/cmp/scala/EntityTypes_scala.ts +2 -3
  160. package/project/.sdk/src/cmp/scala/Entity_scala.ts +3 -3
  161. package/project/.sdk/src/cmp/scala/MainEntity_scala.ts +2 -2
  162. package/project/.sdk/src/cmp/scala/ReadmeExamplesTest_scala.ts +22 -3
  163. package/project/.sdk/src/cmp/scala/TestDirect_scala.ts +3 -3
  164. package/project/.sdk/src/cmp/scala/Test_scala.ts +1 -1
  165. package/project/.sdk/src/cmp/swift/EntityTypes_swift.ts +12 -6
  166. package/project/.sdk/src/cmp/swift/Entity_swift.ts +3 -3
  167. package/project/.sdk/src/cmp/swift/MainEntity_swift.ts +2 -2
  168. package/project/.sdk/src/cmp/swift/Package_swift.ts +1 -1
  169. package/project/.sdk/src/cmp/swift/ReadmeExamplesTest_swift.ts +18 -1
  170. package/project/.sdk/src/cmp/swift/TestDirect_swift.ts +1 -1
  171. package/project/.sdk/src/cmp/ts/Config_ts.ts +11 -0
  172. package/project/.sdk/src/cmp/ts/EntityTypes_ts.ts +2 -3
  173. package/project/.sdk/src/cmp/ts/Entity_ts.ts +3 -3
  174. package/project/.sdk/src/cmp/ts/MainEntity_ts.ts +2 -2
  175. package/project/.sdk/src/cmp/ts/Main_ts.ts +2 -2
  176. package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +4 -4
  177. package/project/.sdk/src/cmp/ts/fragment/Config.fragment.ts +2 -2
  178. package/project/.sdk/src/cmp/ts/fragment/Direct.test.fragment.ts +4 -0
  179. package/project/.sdk/src/cmp/zig/Entity_zig.ts +3 -3
  180. package/project/.sdk/src/cmp/zig/MainEntity_zig.ts +2 -2
  181. package/project/.sdk/src/cmp/zig/Package_zig.ts +10 -2
  182. package/project/.sdk/tm/cpp/test/primary_utility_test.cpp +8 -16
  183. package/project/.sdk/tm/csharp/Makefile +6 -6
  184. package/project/.sdk/tm/csharp/test/PrimaryUtilityTest.cs +10 -28
  185. package/project/.sdk/tm/dart/Makefile +3 -3
  186. package/project/.sdk/tm/dart/test/primary_test.dart +7 -0
  187. package/project/.sdk/tm/go/Makefile +6 -6
  188. package/project/.sdk/tm/go/feature/test_feature.go +33 -1
  189. package/project/.sdk/tm/go/test/primary_utility_test.go +46 -42
  190. package/project/.sdk/tm/go/test/runner_test.go +30 -1
  191. package/project/.sdk/tm/go/utility/make_options.go +48 -0
  192. package/project/.sdk/tm/java/Makefile +6 -6
  193. package/project/.sdk/tm/java/test/PrimaryUtilityTest.java +7 -24
  194. package/project/.sdk/tm/js/Makefile +6 -6
  195. package/project/.sdk/tm/js/src/feature/test/TestFeature.js +18 -1
  196. package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +39 -1
  197. package/project/.sdk/tm/js/test/utility/PrimaryUtility.test.js +13 -0
  198. package/project/.sdk/tm/kotlin/Makefile +6 -6
  199. package/project/.sdk/tm/kotlin/test/PrimaryUtilityTest.kt +7 -20
  200. package/project/.sdk/tm/lean/LICENSE +21 -0
  201. package/project/.sdk/tm/lean/VERSION +1 -0
  202. package/project/.sdk/tm/lean/src/SdkFeature.lean +171 -0
  203. package/project/.sdk/tm/lean/src/SdkFeatures.lean +602 -0
  204. package/project/.sdk/tm/lean/src/SdkJson.lean +134 -0
  205. package/project/.sdk/tm/lean/src/SdkRuntime.lean +356 -0
  206. package/project/.sdk/tm/lean/src/SdkUtility.lean +617 -0
  207. package/project/.sdk/tm/lean/src/VoxgigStruct.lean +2880 -0
  208. package/project/.sdk/tm/lean/src/Vregex.lean +412 -0
  209. package/project/.sdk/tm/lean/src/feature/README.md +5 -0
  210. package/project/.sdk/tm/lean/src/feature/audit/.gitkeep +0 -0
  211. package/project/.sdk/tm/lean/src/feature/base/.gitkeep +0 -0
  212. package/project/.sdk/tm/lean/src/feature/cache/.gitkeep +0 -0
  213. package/project/.sdk/tm/lean/src/feature/clienttrack/.gitkeep +0 -0
  214. package/project/.sdk/tm/lean/src/feature/debug/.gitkeep +0 -0
  215. package/project/.sdk/tm/lean/src/feature/idempotency/.gitkeep +0 -0
  216. package/project/.sdk/tm/lean/src/feature/log/.gitkeep +0 -0
  217. package/project/.sdk/tm/lean/src/feature/metrics/.gitkeep +0 -0
  218. package/project/.sdk/tm/lean/src/feature/netsim/.gitkeep +0 -0
  219. package/project/.sdk/tm/lean/src/feature/paging/.gitkeep +0 -0
  220. package/project/.sdk/tm/lean/src/feature/proxy/.gitkeep +0 -0
  221. package/project/.sdk/tm/lean/src/feature/ratelimit/.gitkeep +0 -0
  222. package/project/.sdk/tm/lean/src/feature/rbac/.gitkeep +0 -0
  223. package/project/.sdk/tm/lean/src/feature/retry/.gitkeep +0 -0
  224. package/project/.sdk/tm/lean/src/feature/streaming/.gitkeep +0 -0
  225. package/project/.sdk/tm/lean/src/feature/telemetry/.gitkeep +0 -0
  226. package/project/.sdk/tm/lean/src/feature/test/.gitkeep +0 -0
  227. package/project/.sdk/tm/lean/src/feature/timeout/.gitkeep +0 -0
  228. package/project/.sdk/tm/lean/test/StructCorpus.lean +697 -0
  229. package/project/.sdk/tm/lean/test/TFeature.lean +268 -0
  230. package/project/.sdk/tm/lean/test/TPrimaryUtility.lean +349 -0
  231. package/project/.sdk/tm/lua/Makefile +7 -7
  232. package/project/.sdk/tm/lua/feature/test_feature.lua +29 -1
  233. package/project/.sdk/tm/lua/test/primary_utility_test.lua +14 -8
  234. package/project/.sdk/tm/lua/utility/make_options.lua +39 -0
  235. package/project/.sdk/tm/perl/Makefile +6 -6
  236. package/project/.sdk/tm/perl/t/primary_utility.t +8 -17
  237. package/project/.sdk/tm/php/Makefile +6 -6
  238. package/project/.sdk/tm/php/feature/TestFeature.php +30 -2
  239. package/project/.sdk/tm/php/test/PrimaryUtilityTest.php +14 -7
  240. package/project/.sdk/tm/php/utility/MakeOptions.php +44 -0
  241. package/project/.sdk/tm/py/Makefile +6 -6
  242. package/project/.sdk/tm/py/feature/test_feature.py +28 -1
  243. package/project/.sdk/tm/py/test/test_primary_utility.py +18 -18
  244. package/project/.sdk/tm/py/utility/make_options.py +42 -0
  245. package/project/.sdk/tm/rb/Makefile +6 -6
  246. package/project/.sdk/tm/rb/feature/test_feature.rb +24 -1
  247. package/project/.sdk/tm/rb/test/primary_utility_test.rb +11 -8
  248. package/project/.sdk/tm/rb/utility/make_options.rb +37 -0
  249. package/project/.sdk/tm/rust/Makefile +6 -6
  250. package/project/.sdk/tm/rust/tests/common/mod.rs +37 -1
  251. package/project/.sdk/tm/rust/tests/primary_utility_test.rs +12 -26
  252. package/project/.sdk/tm/swift/Makefile +6 -6
  253. package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/PrimaryUtilityTest.swift +7 -8
  254. package/project/.sdk/tm/ts/Makefile +6 -6
  255. package/project/.sdk/tm/ts/src/feature/test/TestFeature.ts +18 -1
  256. package/project/.sdk/tm/ts/src/utility/MakeOptionsUtility.ts +39 -1
  257. package/project/.sdk/tm/ts/test/utility/PrimaryUtility.test.ts +69 -21
  258. package/src/cmp/Deploy.ts +16 -16
  259. package/src/cmp/Entity.ts +5 -1
  260. package/src/cmp/Feature.ts +2 -1
  261. package/src/cmp/ReadmeTop.ts +13 -11
  262. package/src/helpers/canonType.ts +8 -3
  263. package/src/helpers/collectDeps.ts +39 -12
  264. package/src/helpers/naming.ts +130 -0
  265. package/src/helpers/opShape.ts +99 -12
  266. package/src/helpers/serverVars.ts +105 -0
  267. package/src/sdkgen.ts +12 -3
@@ -0,0 +1,19 @@
1
+ import { cmp, Content } from '@voxgig/sdkgen'
2
+
3
+ const ReadmeExplanation = cmp(function ReadmeExplanation(_props: any) {
4
+ Content(`The SDK is **config-driven**: the API model is embedded as JSON in
5
+ \`SdkConfig.lean\` and parsed into a \`Value\` when a client is constructed. An
6
+ operation looks up its entity and op in that model, selects the matching
7
+ endpoint (a point whose \`select.exist\` keys are satisfied), builds the URL from
8
+ the point's path parts, applies the request transform, performs the call, then
9
+ applies the response transform. Because the pipeline is data-driven rather than
10
+ generated per entity, every entity and every API follow exactly the same path.
11
+
12
+ The HTTP transport shells out to \`curl\` via \`IO.Process\` — Lean 4 has no HTTP
13
+ library in its standard distribution, and this keeps the package free of Lake
14
+ dependencies.
15
+
16
+ `)
17
+ })
18
+
19
+ export { ReadmeExplanation }
@@ -0,0 +1,25 @@
1
+ import { cmp, Content } from '@voxgig/sdkgen'
2
+
3
+ const ReadmeHowto = cmp(function ReadmeHowto(_props: any) {
4
+ Content(`**Handle a missing record.** A \`load\` that finds nothing yields a
5
+ non-map value, so match on it:
6
+
7
+ \`\`\`lean
8
+ match (← Entity.load sdk m (← emptyMap)) with
9
+ | .map _ => IO.println "found"
10
+ | _ => IO.println "not found"
11
+ \`\`\`
12
+
13
+ **Test without a server.** \`Sdk.testSdk0\` takes seed data (the shape of the
14
+ generated \`<Entity>TestData.json\`) and answers operations from an in-memory
15
+ store, so entity behaviour can be exercised offline:
16
+
17
+ \`\`\`lean
18
+ let seed ← SdkJson.jsonRead (← IO.FS.readFile "../.sdk/test/entity/<e>/<E>TestData.json")
19
+ let sdk ← Sdk.testSdk0 seed
20
+ \`\`\`
21
+
22
+ `)
23
+ })
24
+
25
+ export { ReadmeHowto }
@@ -0,0 +1,38 @@
1
+ import { cmp, Content, isPublished, repoInfo } from '@voxgig/sdkgen'
2
+
3
+ const ReadmeInstall = cmp(function ReadmeInstall(props: any) {
4
+ const { target, ctx$ } = props
5
+ const { model } = ctx$
6
+
7
+ if (isPublished(model, target.name)) {
8
+ Content(`\`\`\`bash
9
+ cd ${target.name} && lake build
10
+ \`\`\`
11
+
12
+ `)
13
+ return
14
+ }
15
+
16
+ const { releasesUrl } = repoInfo(model)
17
+ Content(`This package is not yet published to [Reservoir](https://reservoir.lean-lang.org).
18
+ Install it from the GitHub release tag (\`${target.name}/vX.Y.Z\`, see
19
+ [Releases](${releasesUrl})) or from a source checkout. The runtime is
20
+ dependency-free (only the Lean 4 prelude + Std; the HTTP transport shells out
21
+ to \`curl\`), so a plain Lake build is all that is needed:
22
+
23
+ \`\`\`bash
24
+ cd ${target.name} && lake build
25
+ \`\`\`
26
+
27
+ Run the offline struct-corpus test (no server needed) and the live entity
28
+ tests (point them at a server with \`SDK_TEST_BASE\`):
29
+
30
+ \`\`\`bash
31
+ lake exe structcorpus
32
+ SDK_TEST_BASE=http://localhost:8901 lake exe runner
33
+ \`\`\`
34
+
35
+ `)
36
+ })
37
+
38
+ export { ReadmeInstall }
@@ -0,0 +1,25 @@
1
+ import { cmp, Content } from '@voxgig/sdkgen'
2
+ import { KIT, getModelPath } from '@voxgig/apidef'
3
+
4
+ const ReadmeIntro = cmp(function ReadmeIntro(props: any) {
5
+ const { target, ctx$: { model } } = props
6
+ const info = (model.main && model.main.kit && model.main.kit.info) || {}
7
+ const tagline = info.tagline || ''
8
+
9
+ Content(`# ${model.Name} ${target.title} SDK
10
+
11
+ ${tagline}
12
+
13
+ The ${target.title} SDK for the ${model.Name} API — an entity-oriented client
14
+ for Lean 4. The API is surfaced as capitalised Entities with a small, uniform
15
+ verb set (\`list\`, \`load\`, \`create\`, \`update\`, \`remove\`); every operation is
16
+ driven by the embedded config through the dependency-free vendored voxgig
17
+ \`Value\` struct model, and runs in struct's \`SIO\` monad.
18
+
19
+ `)
20
+
21
+ // touch the model so a mis-shaped model surfaces here, not at render time.
22
+ getModelPath(model, `main.${KIT}.entity`)
23
+ })
24
+
25
+ export { ReadmeIntro }
@@ -0,0 +1,24 @@
1
+ import { cmp, Content } from '@voxgig/sdkgen'
2
+
3
+ const ReadmeModel = cmp(function ReadmeModel(_props: any) {
4
+ Content(`Every value crossing the SDK boundary — options, request payloads,
5
+ responses and results — is a vendored voxgig \`Value\` (see \`VoxgigStruct.lean\`):
6
+ a JSON-shaped, heap-backed node, the Lean equivalent of the \`map[string]any\`
7
+ the Go and Python SDKs pass around. Operations run in struct's \`SIO\` monad
8
+ (\`ReaderT Ctx IO\`), so a single \`mkCtx\` is threaded through a run:
9
+
10
+ \`\`\`lean
11
+ let ctx ← mkCtx
12
+ (do
13
+ let sdk ← Sdk.newSdk (← emptyMap)
14
+ ...
15
+ ).run ctx
16
+ \`\`\`
17
+
18
+ Build values with \`newMap\` / \`newList\`, read them with \`getprop\` / \`getpath\`,
19
+ and render them with \`stringify\` (debug) or \`jsonify\` (strict JSON).
20
+
21
+ `)
22
+ })
23
+
24
+ export { ReadmeModel }
@@ -0,0 +1,22 @@
1
+ import { cmp, Content } from '@voxgig/sdkgen'
2
+
3
+ const ReadmeOptions = cmp(function ReadmeOptions(_props: any) {
4
+ Content(`Options are a struct \`Value\` map passed to \`Sdk.newSdk\`:
5
+
6
+ | Option | Meaning |
7
+ | --- | --- |
8
+ | \`base\` | API base URL (overrides the built-in default) |
9
+ | \`prefix\` / \`suffix\` | Path fragments wrapped around every request path |
10
+ | \`headers\` | Default request headers (merged with per-request headers) |
11
+ | \`apikey\` | Bearer/api key, sent via the \`authorization\` header |
12
+ | \`entity\` | Per-entity option overrides, keyed by entity name |
13
+
14
+ \`\`\`lean
15
+ let opts ← newMap #[("base", .str "https://api.example.com"), ("apikey", .str key)]
16
+ let sdk ← Sdk.newSdk opts
17
+ \`\`\`
18
+
19
+ `)
20
+ })
21
+
22
+ export { ReadmeOptions }
@@ -0,0 +1,50 @@
1
+ import { cmp, Content, isAuthActive, envName } from '@voxgig/sdkgen'
2
+ import { KIT, getModelPath } from '@voxgig/apidef'
3
+
4
+ // A capitalised entity op namespace + a representative read op for the example.
5
+ function pickEntity(model: any): { ns: string, op: string } | null {
6
+ const entity = getModelPath(model, `main.${KIT}.entity`)
7
+ const ents = Object.values(entity || {}).filter((e: any) => e.active !== false)
8
+ for (const e of ents as any[]) {
9
+ const ops = Object.keys(e.op || {})
10
+ const op = ops.includes('list') ? 'list' : ops[0]
11
+ if (op) {
12
+ return { ns: e.name.charAt(0).toUpperCase() + e.name.slice(1), op }
13
+ }
14
+ }
15
+ return null
16
+ }
17
+
18
+ const ReadmeQuick = cmp(function ReadmeQuick(props: any) {
19
+ const { ctx$: { model } } = props
20
+ const pick = pickEntity(model)
21
+ const ns = pick ? pick.ns : 'Entity'
22
+ const op = pick ? pick.op : 'list'
23
+ const auth = isAuthActive(model)
24
+ const optLines = [`("base", .str "https://api.example.com")`]
25
+ if (auth) {
26
+ optLines.push(`("apikey", .str (← IO.getEnv "${envName(model)}").getD "")`)
27
+ }
28
+
29
+ Content(`Construct a client with \`Sdk.newSdk\` and call an entity op. Everything runs
30
+ in struct's \`SIO\` monad, so wrap your calls and \`.run\` them on a fresh \`mkCtx\`:
31
+
32
+ \`\`\`lean
33
+ import SdkClient
34
+
35
+ open VoxgigStruct
36
+
37
+ def main : IO Unit := do
38
+ let ctx ← mkCtx
39
+ (do
40
+ let opts ← newMap #[${optLines.join(', ')}]
41
+ let sdk ← Sdk.newSdk opts
42
+ let result ← ${ns}.${op} sdk (← emptyMap) (← emptyMap)
43
+ IO.println s!"result: {← stringify result}"
44
+ ).run ctx
45
+ \`\`\`
46
+
47
+ `)
48
+ })
49
+
50
+ export { ReadmeQuick }
@@ -0,0 +1,16 @@
1
+ import { cmp, Content } from '@voxgig/sdkgen'
2
+
3
+ const ReadmeRef = cmp(function ReadmeRef(_props: any) {
4
+ Content(`| Module | Purpose |
5
+ | --- | --- |
6
+ | \`SdkClient\` | \`Sdk.newSdk\` / \`Sdk.testSdk\` and the per-entity op namespaces |
7
+ | \`SdkConfig\` | the embedded API model (JSON) |
8
+ | \`SdkRuntime\` | the config-driven operation pipeline and curl transport |
9
+ | \`SdkUtility\` | request-shaping utilities (spec, url, params, transforms, result) |
10
+ | \`SdkJson\` | JSON text to struct \`Value\` |
11
+ | \`VoxgigStruct\` | the vendored voxgig struct value model |
12
+
13
+ `)
14
+ })
15
+
16
+ export { ReadmeRef }
@@ -0,0 +1,16 @@
1
+ import { cmp, Content } from '@voxgig/sdkgen'
2
+
3
+ // The Lean stanza of the top-level README how-to section.
4
+ const ReadmeTopHowto = cmp(function ReadmeTopHowto(props: any) {
5
+ const { target } = props
6
+ Content(`For Lean, point the client at another server with the \`base\` option,
7
+ and run the entity suite against it with \`SDK_TEST_BASE\`:
8
+
9
+ \`\`\`bash
10
+ cd ${target.name} && SDK_TEST_BASE=http://localhost:8901 lake exe runner
11
+ \`\`\`
12
+
13
+ `)
14
+ })
15
+
16
+ export { ReadmeTopHowto }
@@ -0,0 +1,23 @@
1
+ import { cmp, Content } from '@voxgig/sdkgen'
2
+
3
+ // The Lean stanza of the top-level (multi-language) README quick start.
4
+ const ReadmeTopQuick = cmp(function ReadmeTopQuick(props: any) {
5
+ const { target } = props
6
+ Content(`\`\`\`lean
7
+ import SdkClient
8
+ open VoxgigStruct
9
+
10
+ def main : IO Unit := do
11
+ let ctx ← mkCtx
12
+ (do
13
+ let sdk ← Sdk.newSdk (← emptyMap)
14
+ IO.println s!"client ready"
15
+ ).run ctx
16
+ \`\`\`
17
+
18
+ Build it with \`cd ${target.name} && lake build\`.
19
+
20
+ `)
21
+ })
22
+
23
+ export { ReadmeTopQuick }
@@ -0,0 +1,18 @@
1
+ import { cmp, Content } from '@voxgig/sdkgen'
2
+
3
+ // The Lean stanza of the top-level README test section.
4
+ const ReadmeTopTest = cmp(function ReadmeTopTest(props: any) {
5
+ const { target } = props
6
+ Content(`\`\`\`bash
7
+ cd ${target.name}
8
+ lake build
9
+ lake exe primary # shared corpus: request-shaping utilities
10
+ lake exe feature # the feature catalog (retry, cache, rbac, netsim, …)
11
+ lake exe structcorpus # shared corpus: the vendored struct model
12
+ lake exe runner # entity behaviour (offline; add SDK_TEST_BASE for live)
13
+ \`\`\`
14
+
15
+ `)
16
+ })
17
+
18
+ export { ReadmeTopTest }
@@ -0,0 +1,207 @@
1
+ import {
2
+ Content,
3
+ File,
4
+ Folder,
5
+ cmp,
6
+ each,
7
+ } from '@voxgig/sdkgen'
8
+
9
+ import {
10
+ KIT,
11
+ Model,
12
+ getModelPath,
13
+ } from '@voxgig/apidef'
14
+
15
+
16
+ // True when an op has at least one endpoint point that needs no path params
17
+ // (a top-level operation the live smoke test can call without an id).
18
+ function hasParamFreePoint(op: any): boolean {
19
+ if (null == op) return false
20
+ const points = op.points || []
21
+ for (const pt of points) {
22
+ const params = ((pt.args || {}).params) || []
23
+ if (params.length === 0) return true
24
+ }
25
+ return false
26
+ }
27
+
28
+
29
+ // Synthesize a create payload from the entity's required non-id fields.
30
+ function synthData(fields: any): any {
31
+ const o: any = {}
32
+ each(fields, (f: any) => {
33
+ if (f.req && f.name !== 'id') {
34
+ const t = String(f.type || '').toLowerCase()
35
+ o[f.name] =
36
+ (t.includes('number') || t.includes('integer') || t.includes('decimal')) ? 42
37
+ : t.includes('bool') ? true
38
+ : 'leantest'
39
+ }
40
+ })
41
+ return o
42
+ }
43
+
44
+
45
+ // The generated `test/Runner.lean` exe runs TWO lanes:
46
+ //
47
+ // - OFFLINE (always): a test-mode client seeded from the entity's generated
48
+ // `<Entity>TestData.json` answers operations from an in-memory store, so
49
+ // entity behaviour (list/load/create/load-back/remove) is verified with no
50
+ // server — the same guarantee the `test` feature gives the other targets.
51
+ // - LIVE (only when SDK_TEST_BASE is set): the same flow against a real
52
+ // server, exercising the curl transport end to end.
53
+ const Test = cmp(async function Test(props: any) {
54
+ const ctx$ = props.ctx$
55
+ const target = props.target
56
+ const model: Model = ctx$.model
57
+
58
+ const entity = getModelPath(model, `main.${KIT}.entity`)
59
+
60
+ // Per-entity OFFLINE (test-mode) blocks: seeded store, no server.
61
+ let offline = ''
62
+ each(entity, (e: any) => {
63
+ const ns = e.name.charAt(0).toUpperCase() + e.name.slice(1)
64
+ const Name = e.Name || (e.name.charAt(0).toUpperCase() + e.name.slice(1))
65
+ const ops = e.op || {}
66
+ if (!ops.list && !ops.load) return
67
+ offline += ` -- ${e.name}: offline (test-mode) entity behaviour
68
+ (do
69
+ let seedPath := "../.sdk/test/entity/${e.name}/${Name}TestData.json"
70
+ if !(← System.FilePath.pathExists seedPath) then
71
+ IO.println s!"skip - ${e.name}: no seed at {seedPath}"
72
+ else do
73
+ let seed ← SdkJson.jsonRead (← IO.FS.readFile seedPath)
74
+ let tclient ← Sdk.testSdk0 seed
75
+ let existing ← SdkRuntime.gp (← SdkRuntime.gp seed "existing") "${e.name}"
76
+ let ids ← keysof existing
77
+ -- list returns every seeded entity
78
+ let items ← ${ns}.list tclient (← emptyMap) (← emptyMap)
79
+ let n ← (match items with | .list lid => do pure (← listItems lid).size | _ => pure 0)
80
+ if n == ids.size then pass s!"${e.name}.list offline -> {n} seeded"
81
+ else fail s!"${e.name}.list offline: got {n}, want {ids.size}"
82
+ -- load the first seeded entity by id
83
+ if ids.size > 0 then do
84
+ let wid := ids[0]!
85
+ let m ← newMap #[("id", .str wid)]
86
+ let got ← ${ns}.load tclient m (← emptyMap)
87
+ let gid ← SdkRuntime.gpS got "id"
88
+ if gid == wid then pass s!"${e.name}.load offline (id={wid})"
89
+ else fail s!"${e.name}.load offline: got {gid}, want {wid}"
90
+ -- create -> load back -> remove, all in the store
91
+ let newmap ← SdkRuntime.gp (← SdkRuntime.gp seed "new") "${e.name}"
92
+ let nks ← keysof newmap
93
+ if nks.size > 0 then do
94
+ let payload ← SdkRuntime.gp newmap nks[0]!
95
+ let created ← ${ns}.create tclient payload (← emptyMap)
96
+ let cid ← SdkRuntime.gpS created "id"
97
+ if cid == "" then fail "${e.name}.create offline returned no id" else do
98
+ let m2 ← newMap #[("id", .str cid)]
99
+ let back ← ${ns}.load tclient m2 (← emptyMap)
100
+ if (← SdkRuntime.gpS back "id") == cid then
101
+ pass s!"${e.name}.create/load offline (id={cid})"
102
+ else fail s!"${e.name}.create/load offline mismatch"
103
+ let _ ← ${ns}.remove tclient m2 (← emptyMap)
104
+ let gone ← ${ns}.load tclient m2 (← emptyMap)
105
+ match gone with
106
+ | .map _ => fail s!"${e.name}.remove offline: still present"
107
+ | _ => pass s!"${e.name}.remove offline (id={cid})")
108
+ `
109
+ })
110
+
111
+ // Per-entity LIVE test blocks.
112
+ let blocks = ''
113
+ each(entity, (e: any) => {
114
+ const ns = e.name.charAt(0).toUpperCase() + e.name.slice(1)
115
+ const listOp = (e.op || {}).list
116
+ const createOp = (e.op || {}).create
117
+ const removeOp = (e.op || {}).remove
118
+
119
+ if (hasParamFreePoint(listOp)) {
120
+ blocks += ` -- ${e.name}: list smoke
121
+ (do
122
+ let items ← ${ns}.list client (← emptyMap) (← emptyMap)
123
+ match items with
124
+ | .list lid => pass s!"${e.name}.list -> {(← listItems lid).size} items"
125
+ | _ => fail "${e.name}.list did not return a list")
126
+ `
127
+ }
128
+
129
+ // Round-trip when create is param-free (creatable without an id); load and
130
+ // remove then use the id returned by create.
131
+ const loadOp = (e.op || {}).load
132
+ if (hasParamFreePoint(createOp) && loadOp && removeOp) {
133
+ const data = JSON.stringify(synthData(e.fields))
134
+ blocks += ` -- ${e.name}: create / load / remove round-trip
135
+ (do
136
+ let d ← SdkJson.jsonRead ${JSON.stringify(data)}
137
+ let created ← ${ns}.create client d (← emptyMap)
138
+ let nid ← SdkRuntime.gpS created "id"
139
+ if nid == "" then fail "${e.name}.create returned no id" else do
140
+ let m ← newMap #[("id", .str nid)]
141
+ let back ← ${ns}.load client m (← emptyMap)
142
+ let bid ← SdkRuntime.gpS back "id"
143
+ if bid == nid then pass s!"${e.name}.create/load round-trip (id={nid})"
144
+ else fail s!"${e.name}.load mismatch: {bid} != {nid}"
145
+ let _ ← ${ns}.remove client m (← emptyMap)
146
+ pass s!"${e.name}.remove (id={nid})")
147
+ `
148
+ }
149
+ })
150
+
151
+ // The live lane nests two levels deeper than the offline lane.
152
+ const liveBlocks = blocks.split('\n').map((l) => l ? ' ' + l : l).join('\n')
153
+
154
+ Folder({ name: 'test' }, () => {
155
+ File({ name: 'Runner.' + target.ext }, () => {
156
+ Content(`-- ${model.const.Name} SDK test runner (generated by @voxgig/sdkgen).
157
+ --
158
+ -- OFFLINE lane (always): a test-mode client seeded from the generated entity
159
+ -- test data answers operations from an in-memory store — no server needed.
160
+ -- LIVE lane (only when SDK_TEST_BASE is set): the same flow over real HTTP.
161
+
162
+ import VoxgigStruct
163
+ import SdkJson
164
+ import SdkRuntime
165
+ import SdkClient
166
+
167
+ open VoxgigStruct
168
+
169
+ initialize npass : IO.Ref Nat ← IO.mkRef 0
170
+ initialize nfail : IO.Ref Nat ← IO.mkRef 0
171
+
172
+ def pass (msg : String) : SIO Unit := do
173
+ npass.modify (· + 1)
174
+ IO.println s!"ok - {msg}"
175
+
176
+ def fail (msg : String) : SIO Unit := do
177
+ nfail.modify (· + 1)
178
+ IO.println s!"FAIL - {msg}"
179
+
180
+ def defaultBase : String := "http://localhost:8901"
181
+
182
+ def main : IO UInt32 := do
183
+ let liveBase ← IO.getEnv "SDK_TEST_BASE"
184
+ let ctx ← mkCtx
185
+ let offline : SIO Unit := do
186
+ ${offline} offline.run ctx
187
+ match liveBase with
188
+ | none => IO.println "skip - live lane (set SDK_TEST_BASE to enable)"
189
+ | some base => do
190
+ let live : SIO Unit := do
191
+ let opts ← newMap #[("base", .str base)]
192
+ let client ← Sdk.newSdk opts
193
+ ${liveBlocks} live.run ctx
194
+ let p ← npass.get
195
+ let f ← nfail.get
196
+ IO.println ""
197
+ IO.println s!"PASS {p} FAIL {f}"
198
+ if f > 0 then return 1 else return 0
199
+ `)
200
+ })
201
+ })
202
+ })
203
+
204
+
205
+ export {
206
+ Test
207
+ }
@@ -0,0 +1,78 @@
1
+ import * as Path from 'node:path'
2
+
3
+ import {
4
+ clone,
5
+ walk,
6
+ } from '@voxgig/struct'
7
+
8
+
9
+ function projectPath(suffix?: string): string {
10
+ return Path.normalize(Path.join(__dirname, '../../..', suffix ?? ''))
11
+ }
12
+
13
+
14
+ // A Lean 4 string literal. Lean strings are UTF-8, so non-ASCII passes through;
15
+ // only the structural characters need escaping. (Backticks are ordinary in Lean
16
+ // strings, so the config's `body`-style transform exprs embed verbatim.)
17
+ function leanString(s: string): string {
18
+ let out = '"'
19
+ for (const ch of String(s)) {
20
+ if (ch === '"') out += '\\"'
21
+ else if (ch === '\\') out += '\\\\'
22
+ else if (ch === '\n') out += '\\n'
23
+ else if (ch === '\t') out += '\\t'
24
+ else if (ch === '\r') out += '\\r'
25
+ else out += ch
26
+ }
27
+ return out + '"'
28
+ }
29
+
30
+
31
+ // Lean reserved words that cannot be bare identifiers.
32
+ const LEAN_RESERVED = new Set<string>([
33
+ 'do', 'let', 'fun', 'match', 'with', 'if', 'then', 'else', 'by', 'end',
34
+ 'namespace', 'section', 'open', 'import', 'def', 'partial', 'mutual',
35
+ 'structure', 'inductive', 'class', 'instance', 'where', 'deriving', 'return',
36
+ 'try', 'catch', 'for', 'in', 'while', 'have', 'show', 'from', 'set_option',
37
+ ])
38
+
39
+
40
+ // A collision-free lower-camel Lean identifier for a model name.
41
+ function leanVarName(name: string): string {
42
+ let s = String(name).replace(/[^a-zA-Z0-9_]/g, '_')
43
+ if (s.length === 0) {
44
+ s = 'x'
45
+ }
46
+ s = s.charAt(0).toLowerCase() + s.slice(1)
47
+ if (!/^[a-z_]/.test(s)) {
48
+ s = 'e_' + s
49
+ }
50
+ return LEAN_RESERVED.has(s) ? s + '_' : s
51
+ }
52
+
53
+
54
+ // The lowercase-hyphenated package name (used for the lake package + repo).
55
+ function pkgName(model: any): string {
56
+ const org = (model.origin || 'voxgig-sdk').replace(/-sdk$/, '')
57
+ return `${org}-${model.name}-sdk`.toLowerCase().replace(/[^a-z0-9-]/g, '-')
58
+ }
59
+
60
+
61
+ // Remove `$`-suffixed model annotation keys (so the embedded config is clean).
62
+ function clean(o: any) {
63
+ return walk(clone(o), (k: any, v: any, p: any) => {
64
+ if (null != k && k.endsWith('$')) {
65
+ delete p[k]
66
+ }
67
+ return v
68
+ })
69
+ }
70
+
71
+
72
+ export {
73
+ clean,
74
+ leanString,
75
+ leanVarName,
76
+ pkgName,
77
+ projectPath,
78
+ }
@@ -11,6 +11,7 @@ import {
11
11
  each,
12
12
  isAuthActive,
13
13
  resolveAuthPrefix,
14
+ serverVariables,
14
15
  } from '@voxgig/sdkgen'
15
16
 
16
17
 
@@ -46,6 +47,14 @@ const Config = cmp(async function Config(props: any) {
46
47
  let baseUrl = ''
47
48
  try { baseUrl = getModelPath(model, `main.${KIT}.info.servers.0.url`) } catch (_e) { }
48
49
 
50
+ // Templated server URL: emit the spec's server-variable defaults so the
51
+ // runtime can substitute {name} placeholders in base (see make_options).
52
+ const svars = serverVariables(model)
53
+ const serverBlock = 0 === svars.length ? '' :
54
+ ' server = {\n' +
55
+ svars.map((v: any) => ` [${JSON.stringify(v.name)}] = ${JSON.stringify(v.dflt)},\n`).join('') +
56
+ ' },\n'
57
+
49
58
  const authBlock = authActive
50
59
  ? ` auth = {
51
60
  prefix = "${authPrefix}",
@@ -73,7 +82,7 @@ local function make_config()
73
82
  Content(` },
74
83
  options = {
75
84
  base = "${baseUrl}",
76
- ${authBlock} headers = ${formatLuaTable(headers, 3)},
85
+ ${serverBlock}${authBlock} headers = ${formatLuaTable(headers, 3)},
77
86
  entity = {
78
87
  `)
79
88
 
@@ -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,
@@ -53,11 +53,10 @@ const EntityTypes = cmp(function EntityTypes(props: any) {
53
53
  // filter, so inactive entities still get class files referencing these
54
54
  // typed names. Filter on `name` (always present), NOT `active` — parity
55
55
  // with the go emitter's fix.
56
- const entityList = each(entity).filter((e: any) => e && null != e.name)
56
+ const entityList = deriveEntityNames(entity)
57
57
  // Derive the PascalCase Name up-front — it is set LAZILY by names(), so an
58
58
  // entity not yet named (e.g. a fieldless placeholder) would otherwise read
59
59
  // `Name = undefined` below. Parity with the go emitter's fix.
60
- entityList.forEach((e: any) => { if (null == e.Name) names(e, e.name) })
61
60
 
62
61
  // Surface duplicate generated type names (two entities with the same
63
62
  // 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 {
@@ -24,7 +24,7 @@ const Entity = cmp(function Entity(props: any) {
24
24
  // data-type name. The class is a module-local table (snake-cased file name),
25
25
  // so this is used only for the local identifier — kept uniform with the other
26
26
  // languages.
27
- const entityColl = getModelPath(model, `main.${KIT}.entity`)
27
+ const entityColl = entityCollection(model)
28
28
  const cls = entityClassName(entity, entityColl)
29
29
 
30
30
  const entrep = {
@@ -40,7 +40,7 @@ const Entity = cmp(function Entity(props: any) {
40
40
 
41
41
  File({ name: entity.name + '_entity.' + target.ext }, () => {
42
42
 
43
- const opnames = Object.keys(entity.op)
43
+ const opnames = Object.keys(entity.op || {})
44
44
 
45
45
  const opfrags =
46
46
  (['load', 'list', 'create', 'update', 'remove']
@@ -57,7 +57,7 @@ dependencies = {
57
57
  `)
58
58
 
59
59
  const seen = new Set<string>(['lua', 'dkjson'])
60
- for (const d of collectDeps(model, target.name, target.deps)) {
60
+ for (const d of collectDeps(model, target.name, target.deps, ctx$.log)) {
61
61
  if (seen.has(d.name)) continue
62
62
  seen.add(d.name)
63
63
  const v = d.source === 'target' ? (d.version || '0.0') : d.version