@voxgig/sdkgen 3.5.1 → 3.7.0

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 (255) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/dist/cmp/AgentGuideTop.js +17 -0
  3. package/dist/cmp/AgentGuideTop.js.map +1 -1
  4. package/dist/cmp/ExternalTarget.js +1 -1
  5. package/dist/cmp/ExternalTarget.js.map +1 -1
  6. package/dist/cmp/Readme.js +2 -0
  7. package/dist/cmp/Readme.js.map +1 -1
  8. package/dist/cmp/ReadmeStation.d.ts +2 -0
  9. package/dist/cmp/ReadmeStation.js +57 -0
  10. package/dist/cmp/ReadmeStation.js.map +1 -0
  11. package/dist/helpers/naming.d.ts +6 -1
  12. package/dist/helpers/naming.js +156 -5
  13. package/dist/helpers/naming.js.map +1 -1
  14. package/dist/helpers/opShape.js +72 -0
  15. package/dist/helpers/opShape.js.map +1 -1
  16. package/dist/helpers/packageMeta.d.ts +2 -1
  17. package/dist/helpers/packageMeta.js +57 -20
  18. package/dist/helpers/packageMeta.js.map +1 -1
  19. package/dist/sdkgen.d.ts +3 -3
  20. package/dist/sdkgen.js +63 -18
  21. package/dist/sdkgen.js.map +1 -1
  22. package/dist/testkit.d.ts +39 -0
  23. package/dist/testkit.js +663 -0
  24. package/dist/testkit.js.map +1 -0
  25. package/dist/tsconfig.tsbuildinfo +1 -1
  26. package/dist/utility.d.ts +1 -1
  27. package/dist/utility.js +16 -2
  28. package/dist/utility.js.map +1 -1
  29. package/package.json +32 -8
  30. package/project/.sdk/src/cmp/c/Config_c.ts +34 -13
  31. package/project/.sdk/src/cmp/c/Test_c.ts +5 -7
  32. package/project/.sdk/src/cmp/clojure/Test_clojure.ts +3 -7
  33. package/project/.sdk/src/cmp/cpp/Config_cpp.ts +9 -46
  34. package/project/.sdk/src/cmp/cpp/Test_cpp.ts +4 -7
  35. package/project/.sdk/src/cmp/csharp/Config_csharp.ts +7 -1
  36. package/project/.sdk/src/cmp/csharp/Package_csharp.ts +1 -1
  37. package/project/.sdk/src/cmp/csharp/Test_csharp.ts +5 -7
  38. package/project/.sdk/src/cmp/dart/Config_dart.ts +14 -2
  39. package/project/.sdk/src/cmp/dart/Test_dart.ts +3 -4
  40. package/project/.sdk/src/cmp/dart/fragment/Config.data.fragment.dart +5 -0
  41. package/project/.sdk/src/cmp/dart/fragment/Config.fragment.dart +6 -0
  42. package/project/.sdk/src/cmp/dart/fragment/Main.fragment.dart +13 -4
  43. package/project/.sdk/src/cmp/elixir/Config_elixir.ts +12 -2
  44. package/project/.sdk/src/cmp/elixir/Package_elixir.ts +42 -3
  45. package/project/.sdk/src/cmp/elixir/Test_elixir.ts +5 -6
  46. package/project/.sdk/src/cmp/go/Config_go.ts +8 -1
  47. package/project/.sdk/src/cmp/go/EntityTypes_go.ts +1 -1
  48. package/project/.sdk/src/cmp/go/Entity_go.ts +1 -1
  49. package/project/.sdk/src/cmp/go/Gitignore_go.ts +6 -0
  50. package/project/.sdk/src/cmp/go/Main_go.ts +2 -2
  51. package/project/.sdk/src/cmp/go/Package_go.ts +1 -1
  52. package/project/.sdk/src/cmp/go/ReadmeExamplesTest_go.ts +59 -6
  53. package/project/.sdk/src/cmp/go/ReadmeExplanation_go.ts +1 -1
  54. package/project/.sdk/src/cmp/go/ReadmeHowto_go.ts +1 -1
  55. package/project/.sdk/src/cmp/go/ReadmeInstall_go.ts +1 -1
  56. package/project/.sdk/src/cmp/go/ReadmeModel_go.ts +1 -1
  57. package/project/.sdk/src/cmp/go/ReadmeQuick_go.ts +1 -1
  58. package/project/.sdk/src/cmp/go/ReadmeTopQuick_go.ts +1 -1
  59. package/project/.sdk/src/cmp/go/ReadmeTopTest_go.ts +1 -1
  60. package/project/.sdk/src/cmp/go/Test_go.ts +6 -8
  61. package/project/.sdk/src/cmp/go-cli/Main_go-cli.ts +6 -2
  62. package/project/.sdk/src/cmp/go-mcp/Main_go-mcp.ts +6 -2
  63. package/project/.sdk/src/cmp/java/Config_java.ts +8 -1
  64. package/project/.sdk/src/cmp/java/Test_java.ts +4 -7
  65. package/project/.sdk/src/cmp/js/Config_js.ts +9 -1
  66. package/project/.sdk/src/cmp/js/Package_js.ts +1 -1
  67. package/project/.sdk/src/cmp/js/Test_js.ts +4 -7
  68. package/project/.sdk/src/cmp/js/fragment/Config.data.fragment.js +7 -0
  69. package/project/.sdk/src/cmp/js/fragment/Config.fragment.js +8 -0
  70. package/project/.sdk/src/cmp/js/fragment/Main.fragment.js +33 -5
  71. package/project/.sdk/src/cmp/kotlin/Config_kotlin.ts +8 -1
  72. package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +4 -7
  73. package/project/.sdk/src/cmp/lean/Test_lean.ts +3 -3
  74. package/project/.sdk/src/cmp/lua/Config_lua.ts +11 -2
  75. package/project/.sdk/src/cmp/lua/Package_lua.ts +26 -3
  76. package/project/.sdk/src/cmp/lua/Test_lua.ts +5 -7
  77. package/project/.sdk/src/cmp/ocaml/Test_ocaml.ts +3 -7
  78. package/project/.sdk/src/cmp/perl/Config_perl.ts +8 -60
  79. package/project/.sdk/src/cmp/perl/Package_perl.ts +1 -1
  80. package/project/.sdk/src/cmp/perl/Test_perl.ts +5 -7
  81. package/project/.sdk/src/cmp/php/Config_php.ts +11 -2
  82. package/project/.sdk/src/cmp/php/EntityTypes_php.ts +13 -2
  83. package/project/.sdk/src/cmp/php/Main_php.ts +25 -0
  84. package/project/.sdk/src/cmp/php/Package_php.ts +2 -2
  85. package/project/.sdk/src/cmp/php/Test_php.ts +5 -7
  86. package/project/.sdk/src/cmp/php/fragment/Main.fragment.php +23 -6
  87. package/project/.sdk/src/cmp/py/Config_py.ts +11 -2
  88. package/project/.sdk/src/cmp/py/Main_py.ts +17 -7
  89. package/project/.sdk/src/cmp/py/Package_py.ts +2 -2
  90. package/project/.sdk/src/cmp/py/Test_py.ts +5 -7
  91. package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +23 -6
  92. package/project/.sdk/src/cmp/py-data/Main_py-data.ts +14 -19
  93. package/project/.sdk/src/cmp/rb/Config_rb.ts +7 -1
  94. package/project/.sdk/src/cmp/rb/Package_rb.ts +3 -3
  95. package/project/.sdk/src/cmp/rb/ReadmeInstall_rb.ts +1 -1
  96. package/project/.sdk/src/cmp/rb/Test_rb.ts +5 -7
  97. package/project/.sdk/src/cmp/rust/Config_rust.ts +5 -2
  98. package/project/.sdk/src/cmp/rust/Test_rust.ts +5 -7
  99. package/project/.sdk/src/cmp/scala/Test_scala.ts +5 -2
  100. package/project/.sdk/src/cmp/seneca-provider/Gitignore_seneca-provider.ts +161 -0
  101. package/project/.sdk/src/cmp/seneca-provider/Main_seneca-provider.ts +20 -11
  102. package/project/.sdk/src/cmp/swift/Config_swift.ts +8 -54
  103. package/project/.sdk/src/cmp/swift/Package_swift.ts +52 -10
  104. package/project/.sdk/src/cmp/swift/Test_swift.ts +5 -7
  105. package/project/.sdk/src/cmp/ts/Config_ts.ts +9 -1
  106. package/project/.sdk/src/cmp/ts/EntityTypes_ts.ts +5 -2
  107. package/project/.sdk/src/cmp/ts/Entity_ts.ts +8 -2
  108. package/project/.sdk/src/cmp/ts/Package_ts.ts +1 -1
  109. package/project/.sdk/src/cmp/ts/Test_ts.ts +8 -7
  110. package/project/.sdk/src/cmp/ts/fragment/Config.data.fragment.ts +7 -0
  111. package/project/.sdk/src/cmp/ts/fragment/Config.fragment.ts +8 -0
  112. package/project/.sdk/src/cmp/ts/fragment/Entity.fragment.ts +1 -1
  113. package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +12 -4
  114. package/project/.sdk/src/cmp/zig/Test_zig.ts +3 -7
  115. package/project/.sdk/tm/c/Makefile +6 -1
  116. package/project/.sdk/tm/c/utility/make_options.c +12 -1
  117. package/project/.sdk/tm/c/utility/make_point.c +64 -3
  118. package/project/.sdk/tm/clojure/src/sdk/core.clj +49 -14
  119. package/project/.sdk/tm/cpp/utility/pipeline.hpp +64 -4
  120. package/project/.sdk/tm/csharp/feature/TestFeature.cs +36 -2
  121. package/project/.sdk/tm/csharp/utility/Fetcher.cs +23 -5
  122. package/project/.sdk/tm/csharp/utility/MakeOptions.cs +13 -0
  123. package/project/.sdk/tm/csharp/utility/MakePoint.cs +65 -2
  124. package/project/.sdk/tm/dart/lib/feature/test/TestFeature.dart +34 -4
  125. package/project/.sdk/tm/dart/lib/utility/FetcherUtility.dart +9 -0
  126. package/project/.sdk/tm/dart/lib/utility/MakeOptionsUtility.dart +17 -0
  127. package/project/.sdk/tm/dart/lib/utility/MakePointUtility.dart +48 -2
  128. package/project/.sdk/tm/elixir/lib/projectname/utility.ex +109 -13
  129. package/project/.sdk/tm/elixir/test/feature_test.exs +19 -0
  130. package/project/.sdk/tm/elixir/test/primary_utility_test.exs +72 -0
  131. package/project/.sdk/tm/go/feature/test_feature.go +34 -2
  132. package/project/.sdk/tm/go/test/primary_utility_test.go +42 -20
  133. package/project/.sdk/tm/go/test/runner_test.go +1 -1
  134. package/project/.sdk/tm/go/utility/fetcher.go +14 -0
  135. package/project/.sdk/tm/go/utility/make_options.go +31 -4
  136. package/project/.sdk/tm/go/utility/make_point.go +66 -2
  137. package/project/.sdk/tm/java/feature/TestFeature.java +42 -2
  138. package/project/.sdk/tm/java/utility/Fetcher.java +11 -1
  139. package/project/.sdk/tm/java/utility/MakeOptions.java +11 -0
  140. package/project/.sdk/tm/java/utility/MakePoint.java +61 -2
  141. package/project/.sdk/tm/js/src/feature/test/TestFeature.js +22 -3
  142. package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +20 -2
  143. package/project/.sdk/tm/js/src/utility/MakePointUtility.js +72 -2
  144. package/project/.sdk/tm/kotlin/feature/TestFeature.kt +31 -2
  145. package/project/.sdk/tm/kotlin/utility/Fetcher.kt +10 -1
  146. package/project/.sdk/tm/kotlin/utility/MakeOptions.kt +11 -0
  147. package/project/.sdk/tm/kotlin/utility/MakePoint.kt +58 -2
  148. package/project/.sdk/tm/lean/src/SdkUtility.lean +28 -0
  149. package/project/.sdk/tm/lean/test/TPrimaryUtility.lean +13 -2
  150. package/project/.sdk/tm/lua/utility/make_options.lua +44 -0
  151. package/project/.sdk/tm/lua/utility/make_point.lua +65 -2
  152. package/project/.sdk/tm/ocaml/sdk_runtime.ml +40 -2
  153. package/project/.sdk/tm/perl/utility/fetcher.pm +10 -1
  154. package/project/.sdk/tm/perl/utility/make_options.pm +36 -0
  155. package/project/.sdk/tm/perl/utility/make_point.pm +55 -2
  156. package/project/.sdk/tm/php/feature/TestFeature.php +30 -1
  157. package/project/.sdk/tm/php/test/PipelineTest.php +20 -0
  158. package/project/.sdk/tm/php/utility/Fetcher.php +12 -1
  159. package/project/.sdk/tm/php/utility/MakeOptions.php +58 -0
  160. package/project/.sdk/tm/php/utility/MakePoint.php +49 -1
  161. package/project/.sdk/tm/py/pkg/utility/fetcher.py +13 -1
  162. package/project/.sdk/tm/py/pkg/utility/make_options.py +23 -0
  163. package/project/.sdk/tm/py/pkg/utility/make_point.py +56 -2
  164. package/project/.sdk/tm/rb/utility/make_options.rb +18 -0
  165. package/project/.sdk/tm/rb/utility/make_point.rb +42 -2
  166. package/project/.sdk/tm/rust/tests/common/mod.rs +1 -1
  167. package/project/.sdk/tm/rust/tests/feature_test.rs +27 -0
  168. package/project/.sdk/tm/rust/utility/fetcher.rs +8 -0
  169. package/project/.sdk/tm/rust/utility/make_options.rs +15 -0
  170. package/project/.sdk/tm/rust/utility/make_point.rs +69 -2
  171. package/project/.sdk/tm/scala/feature/TestFeature.scala +36 -1
  172. package/project/.sdk/tm/scala/utility/Make.scala +57 -3
  173. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/TestFeature.swift +29 -1
  174. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Fetcher.swift +24 -1
  175. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Make.swift +51 -2
  176. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +12 -0
  177. package/project/.sdk/tm/ts/src/feature/test/TestFeature.ts +22 -3
  178. package/project/.sdk/tm/ts/src/utility/MakeOptionsUtility.ts +20 -2
  179. package/project/.sdk/tm/ts/src/utility/MakePointUtility.ts +72 -2
  180. package/project/.sdk/tm/ts/test/utility/Corpus.test.ts +85 -0
  181. package/project/.sdk/tm/ts/test/utility/PrimaryUtility.test.ts +10 -17
  182. package/project/.sdk/tm/zig/core/utility.zig +66 -3
  183. package/project/sdkgen-package.json +1 -2
  184. package/src/cmp/AgentGuideTop.ts +18 -0
  185. package/src/cmp/ExternalTarget.ts +1 -1
  186. package/src/cmp/Readme.ts +2 -0
  187. package/src/cmp/ReadmeStation.ts +69 -0
  188. package/src/helpers/naming.ts +172 -5
  189. package/src/helpers/opShape.ts +85 -0
  190. package/src/helpers/packageMeta.ts +59 -20
  191. package/src/sdkgen.ts +70 -20
  192. package/src/testkit.ts +863 -0
  193. package/src/utility.ts +17 -2
  194. package/testkit.d.ts +3 -0
  195. package/testkit.js +12 -0
  196. package/project/.sdk/model/target/haskell.aontu +0 -72
  197. package/project/.sdk/src/cmp/haskell/Config_haskell.ts +0 -98
  198. package/project/.sdk/src/cmp/haskell/Entity_haskell.ts +0 -13
  199. package/project/.sdk/src/cmp/haskell/Gitignore_haskell.ts +0 -27
  200. package/project/.sdk/src/cmp/haskell/Main_haskell.ts +0 -123
  201. package/project/.sdk/src/cmp/haskell/Package_haskell.ts +0 -60
  202. package/project/.sdk/src/cmp/haskell/ReadmeEntity_haskell.ts +0 -186
  203. package/project/.sdk/src/cmp/haskell/ReadmeExamplesTest_haskell.ts +0 -135
  204. package/project/.sdk/src/cmp/haskell/ReadmeExplanation_haskell.ts +0 -48
  205. package/project/.sdk/src/cmp/haskell/ReadmeHowto_haskell.ts +0 -168
  206. package/project/.sdk/src/cmp/haskell/ReadmeInstall_haskell.ts +0 -51
  207. package/project/.sdk/src/cmp/haskell/ReadmeIntro_haskell.ts +0 -67
  208. package/project/.sdk/src/cmp/haskell/ReadmeModel_haskell.ts +0 -162
  209. package/project/.sdk/src/cmp/haskell/ReadmeOptions_haskell.ts +0 -74
  210. package/project/.sdk/src/cmp/haskell/ReadmeQuick_haskell.ts +0 -241
  211. package/project/.sdk/src/cmp/haskell/ReadmeRef_haskell.ts +0 -408
  212. package/project/.sdk/src/cmp/haskell/ReadmeTopHowto_haskell.ts +0 -31
  213. package/project/.sdk/src/cmp/haskell/ReadmeTopQuick_haskell.ts +0 -104
  214. package/project/.sdk/src/cmp/haskell/ReadmeTopTest_haskell.ts +0 -80
  215. package/project/.sdk/src/cmp/haskell/Test_haskell.ts +0 -300
  216. package/project/.sdk/src/cmp/haskell/tsconfig.json +0 -15
  217. package/project/.sdk/src/cmp/haskell/utility_haskell.ts +0 -166
  218. package/project/.sdk/tm/haskell/LICENSE +0 -21
  219. package/project/.sdk/tm/haskell/Makefile +0 -22
  220. package/project/.sdk/tm/haskell/VERSION +0 -1
  221. package/project/.sdk/tm/haskell/src/SdkFeatures.hs +0 -1440
  222. package/project/.sdk/tm/haskell/src/SdkHelpers.hs +0 -337
  223. package/project/.sdk/tm/haskell/src/SdkJson.hs +0 -111
  224. package/project/.sdk/tm/haskell/src/SdkRuntime.hs +0 -1219
  225. package/project/.sdk/tm/haskell/src/SdkTypes.hs +0 -195
  226. package/project/.sdk/tm/haskell/src/VoxgigStruct.hs +0 -2299
  227. package/project/.sdk/tm/haskell/src/Vregex.hs +0 -237
  228. package/project/.sdk/tm/haskell/src/feature/README.md +0 -5
  229. package/project/.sdk/tm/haskell/src/feature/audit/.gitkeep +0 -0
  230. package/project/.sdk/tm/haskell/src/feature/base/.gitkeep +0 -0
  231. package/project/.sdk/tm/haskell/src/feature/cache/.gitkeep +0 -0
  232. package/project/.sdk/tm/haskell/src/feature/clienttrack/.gitkeep +0 -0
  233. package/project/.sdk/tm/haskell/src/feature/debug/.gitkeep +0 -0
  234. package/project/.sdk/tm/haskell/src/feature/idempotency/.gitkeep +0 -0
  235. package/project/.sdk/tm/haskell/src/feature/log/.gitkeep +0 -0
  236. package/project/.sdk/tm/haskell/src/feature/metrics/.gitkeep +0 -0
  237. package/project/.sdk/tm/haskell/src/feature/netsim/.gitkeep +0 -0
  238. package/project/.sdk/tm/haskell/src/feature/paging/.gitkeep +0 -0
  239. package/project/.sdk/tm/haskell/src/feature/proxy/.gitkeep +0 -0
  240. package/project/.sdk/tm/haskell/src/feature/ratelimit/.gitkeep +0 -0
  241. package/project/.sdk/tm/haskell/src/feature/rbac/.gitkeep +0 -0
  242. package/project/.sdk/tm/haskell/src/feature/retry/.gitkeep +0 -0
  243. package/project/.sdk/tm/haskell/src/feature/streaming/.gitkeep +0 -0
  244. package/project/.sdk/tm/haskell/src/feature/telemetry/.gitkeep +0 -0
  245. package/project/.sdk/tm/haskell/src/feature/test/.gitkeep +0 -0
  246. package/project/.sdk/tm/haskell/src/feature/timeout/.gitkeep +0 -0
  247. package/project/.sdk/tm/haskell/test/Harness.hs +0 -281
  248. package/project/.sdk/tm/haskell/test/Runner.hs +0 -47
  249. package/project/.sdk/tm/haskell/test/StructCorpus.hs +0 -449
  250. package/project/.sdk/tm/haskell/test/TCustomUtility.hs +0 -38
  251. package/project/.sdk/tm/haskell/test/TFeature.hs +0 -794
  252. package/project/.sdk/tm/haskell/test/TNetsim.hs +0 -50
  253. package/project/.sdk/tm/haskell/test/TPipeline.hs +0 -334
  254. package/project/.sdk/tm/haskell/test/TPrimaryUtility.hs +0 -386
  255. package/project/.sdk/tm/haskell/test/Testutil.hs +0 -59
@@ -3,6 +3,7 @@ import {
3
3
  Content,
4
4
  File,
5
5
  cmp,
6
+ collectDeps,
6
7
  pkgDescription,
7
8
  repoInfo,
8
9
  packageVersion,
@@ -15,7 +16,11 @@ import type {
15
16
 
16
17
 
17
18
  // Generate mix.exs for the Elixir SDK. The vendored struct library has zero
18
- // third-party runtime deps, so the SDK ships with none either.
19
+ // third-party runtime deps, so a bare SDK ships with none - but dependencies
20
+ // declared by the model DO flow: the target's own `deps` block plus any
21
+ // feature-declared elixir deps (e.g. the station feature's voxgig_station),
22
+ // via the shared collectDeps helper, exactly like rust/dart/go. A model with
23
+ // no deps emits the byte-identical `defp deps, do: []` it always has.
19
24
  const Package = cmp(async function Package(props: any) {
20
25
  const ctx$ = props.ctx$
21
26
  const target = props.target
@@ -27,6 +32,31 @@ const Package = cmp(async function Package(props: any) {
27
32
  const app = String(model.const.name).replace(/-/g, '_')
28
33
  const { repoUrl } = repoInfo(model)
29
34
 
35
+ // Render one mix deps entry per collected dependency. Hex package names
36
+ // share the atom alphabet, but a hyphen in a model dep name is mapped to
37
+ // '_' rather than emitted broken. Version -> Mix requirement: an explicit
38
+ // operator is kept (spaced, the mix convention: '>=0.0.1' -> '>= 0.0.1');
39
+ // a bare version gets hex's customary '~>'; a target dep with no version
40
+ // accepts anything. kind: 'dev' scopes to [:dev, :test]; 'peer'/'prod'
41
+ // (and anything else) are runtime deps - mix has no peer notion.
42
+ const entries: string[] = []
43
+ for (const d of collectDeps(model, target.name, target.deps, ctx$.log)) {
44
+ const atom = String(d.name).replace(/-/g, '_')
45
+ const version = null == d.version || '' === String(d.version).trim()
46
+ ? '>= 0.0.0'
47
+ : mixRequirement(String(d.version).trim())
48
+ const scope = 'dev' === (d.raw as any)?.kind ? ', only: [:dev, :test]' : ''
49
+ entries.push(`{:${atom}, ${JSON.stringify(version)}${scope}}`)
50
+ }
51
+
52
+ const depsBlock = 0 === entries.length
53
+ ? ` defp deps, do: []`
54
+ : ` defp deps do
55
+ [
56
+ ${entries.join(',\n ')}
57
+ ]
58
+ end`
59
+
30
60
  File({ name: 'mix.exs' }, () => {
31
61
  Content(`defmodule ${Name}.MixProject do
32
62
  use Mix.Project
@@ -36,7 +66,7 @@ const Package = cmp(async function Package(props: any) {
36
66
  app: :${app},
37
67
  version: "${packageVersion(model, target.name)}",
38
68
  elixir: "~> 1.14",
39
- description: ${JSON.stringify(pkgDescription(model, 'elixir'))},
69
+ description: ${JSON.stringify(pkgDescription(model, target.name))},
40
70
  elixirc_paths: elixirc_paths(Mix.env()),
41
71
  start_permanent: Mix.env() == :prod,
42
72
  deps: deps(),
@@ -46,7 +76,7 @@ const Package = cmp(async function Package(props: any) {
46
76
 
47
77
  def application, do: [extra_applications: [:inets, :ssl]]
48
78
 
49
- defp deps, do: []
79
+ ${depsBlock}
50
80
 
51
81
  defp elixirc_paths(:test), do: ["lib", "test/support"]
52
82
  defp elixirc_paths(_), do: ["lib"]
@@ -63,6 +93,15 @@ end
63
93
  })
64
94
 
65
95
 
96
+ function mixRequirement(version: string): string {
97
+ const m = version.match(/^(>=|<=|~>|==|!=|>|<)\s*(.+)$/)
98
+ if (null != m) {
99
+ return m[1] + ' ' + m[2]
100
+ }
101
+ return '~> ' + version
102
+ }
103
+
104
+
66
105
  export {
67
106
  Package
68
107
  }
@@ -1,13 +1,9 @@
1
1
 
2
- import {
3
- KIT,
4
- } from '@voxgig/apidef'
5
-
6
2
  import type {
7
3
  ModelEntity
8
4
  } from '@voxgig/apidef'
9
5
 
10
- import { cmp, each, Folder, File, Content } from '@voxgig/sdkgen'
6
+ import { cmp, each, Folder, File, Content, entityCollection } from '@voxgig/sdkgen'
11
7
 
12
8
 
13
9
  import { TestEntity } from './TestEntity_elixir'
@@ -35,7 +31,10 @@ end
35
31
  `)
36
32
  })
37
33
 
38
- each(model.main[KIT].entity, (entity: ModelEntity) => {
34
+ const entity = each(entityCollection(model))
35
+ .filter((e: any) => false !== e.active)
36
+
37
+ each(entity, (entity: ModelEntity) => {
39
38
  TestEntity({ target, entity })
40
39
  TestDirect({ target, entity })
41
40
  })
@@ -69,7 +69,7 @@ const Config = cmp(async function Config(props: any) {
69
69
  // literal and the data that replaces it above the threshold are the same
70
70
  // config by construction. The JSON is what the threshold is measured on -
71
71
  // emitted source size varies by language, the model does not.
72
- const { json: configJson } = configDefinition(model)
72
+ const { def: configDef, json: configJson } = configDefinition(model, target.name)
73
73
  const asData = isConfigData(configJson, configReprSetting(model))
74
74
 
75
75
  File({ name: 'config.' + target.ext }, () => {
@@ -154,6 +154,10 @@ import (
154
154
 
155
155
  `)
156
156
 
157
+ // main slug/version/target come from configDefinition's def, not
158
+ // re-derived here, so the literal rep and the data rep cannot disagree
159
+ // on identity (mirrors Config_ts's #MainMeta block; station's
160
+ // descriptor reads all three).
157
161
  Content(`// MakeConfig builds a fresh, fully materialised config map. Every call
158
162
  // rebuilds the whole structure, so prefer SharedConfig unless you need a
159
163
  // private copy you intend to mutate.
@@ -161,6 +165,9 @@ func MakeConfig() map[string]any {
161
165
  return map[string]any{
162
166
  "main": map[string]any{
163
167
  "name": "${model.const.Name}",
168
+ "slug": ${JSON.stringify(configDef.main.slug)},
169
+ "version": ${JSON.stringify(configDef.main.version)},
170
+ "target": ${JSON.stringify(configDef.main.target)},
164
171
  },
165
172
  "feature": map[string]any{
166
173
  `)
@@ -167,7 +167,7 @@ const EntityTypes = cmp(function EntityTypes(props: any) {
167
167
 
168
168
  // This file is GENERATED, not templated, so the GOMODULE placeholder is
169
169
  // never substituted for it — the module path has to be interpolated.
170
- const gomodule = goModule(model, 'go')
170
+ const gomodule = goModule(model, target.name)
171
171
 
172
172
  // only_active:false — getModelPath DROPS active:false entries by default,
173
173
  // but the consumer scaffold (create-sdkgen Root.ts) iterates the RAW entity
@@ -21,7 +21,7 @@ const Entity = cmp(function Entity(props: any) {
21
21
 
22
22
  // Module name: concatenated lowercase
23
23
  // Go module path == repo path on GitHub (org from model.origin).
24
- const gomodule = goModule(model, 'go')
24
+ const gomodule = goModule(model, target.name)
25
25
 
26
26
  // Collision-free entity CLASS name (see entityClassName): normally
27
27
  // `<Name>Entity`, but disambiguated (e.g. `<Name>EntityClient`) when it would
@@ -21,6 +21,12 @@ const Gitignore = cmp(async function Gitignore(_props: any) {
21
21
  *.test
22
22
  *.out
23
23
 
24
+ # Readme-snippet check work dirs (TestReadmeGoSnippets). Normally removed on
25
+ # exit; a killed run leaves one behind, and committing it is how a 1132-file
26
+ # snippet package once shipped in a release.
27
+ _readmecheck-*/
28
+ readmecheck-*/
29
+
24
30
  # Coverage
25
31
  coverage.txt
26
32
  coverage.html
@@ -37,10 +37,10 @@ const Main = cmp(async function Main(props: any) {
37
37
 
38
38
  // Go module path == the repo path on GitHub (org from model.origin),
39
39
  // e.g. github.com/voxgig-sdk/<slug>-sdk. Used in go.mod and every import.
40
- const gomodule = goModule(model, 'go')
40
+ const gomodule = goModule(model, target.name)
41
41
  // The root package name must be a plain Go identifier (can't be a path),
42
42
  // so it stays a concatenated-lowercase form (e.g. voxgigdogsdk).
43
- const gopackage = goPackageIdent(model, 'go')
43
+ const gopackage = goPackageIdent(model, target.name)
44
44
 
45
45
  Package({ target })
46
46
 
@@ -23,7 +23,7 @@ const Package = cmp(async function Package(props: any) {
23
23
  // may not be named `<slug>-sdk`, and the hardcoded `go 1.20` this used to
24
24
  // emit could not compile sdkgen's own `log` feature (it imports log/slog,
25
25
  // which needs 1.21).
26
- const gomodule = goModule(model, 'go')
26
+ const gomodule = goModule(model, target.name)
27
27
 
28
28
  File({ name: 'go.mod' }, () => {
29
29
  Content(`module ${gomodule}
@@ -67,11 +67,26 @@ import (
67
67
  "testing"
68
68
  )
69
69
 
70
- // testSeed is a test-mode fixture seeded for every entity. It is spliced as
71
- // literal Go source into fragment wrappers and into the test-mode variant of
72
- // complete programs, so the offline mock transport has data to return.
70
+ // testSeed is a test-mode fixture seeded for every entity, as Go source, so
71
+ // the offline mock transport has data to return. It is NOT spliced into each
72
+ // snippet: it is written ONCE per generated package as seed.go, and snippets
73
+ // reference it by name (seedRef).
74
+ //
75
+ // Splicing it inline was O(snippets x entities). Every fragment lands in ONE
76
+ // package, so a large API multiplied one ~26 KB composite literal by every
77
+ // \`\`\`go block in the docs: gitlab reached 1132 fragments / ~625k literal
78
+ // entries in a single compilation unit, and \`compile\` grew ~15 MB per fragment
79
+ // to ~16 GB — the same superlinear-composite-literal blowup the L1 config data
80
+ // path fixed for core/config.go. One shared var is O(1) in the snippet count.
73
81
  const testSeed = \`${goSeed}\`
74
82
 
83
+ // seedRef is how a snippet names the shared fixture; seedFile declares it.
84
+ const seedRef = "readmeTestSeed"
85
+
86
+ func seedFile(pkg string) []byte {
87
+ return []byte("package " + pkg + "\\n\\nvar " + seedRef + " = " + testSeed + "\\n")
88
+ }
89
+
75
90
  // doc names one of the three docs that carry go examples, with its path
76
91
  // relative to this test file's directory (which is <repo>/go/test): the root
77
92
  // README is two levels up, the go docs are one.
@@ -109,7 +124,18 @@ func TestReadmeGoSnippets(t *testing.T) {
109
124
  {"go/REFERENCE", filepath.Join(testDir, "..", "REFERENCE.md")},
110
125
  }
111
126
 
112
- work, err := os.MkdirTemp(moduleRoot, "readmecheck-")
127
+ // The work dir has to live inside the module (the snippets import the SDK
128
+ // by module path), but it MUST stay invisible to \`go build ./...\`. The go
129
+ // tool skips directories whose name starts with "_" for wildcard matching
130
+ // while still building them by explicit path — exactly what is needed
131
+ // here, because \`defer os.RemoveAll\` does NOT run when the process is
132
+ // killed. A leftover frag package inside the module made the NEXT plain
133
+ // \`go build ./...\` compile every snippet and OOM, which is how a killed
134
+ // run poisoned later runs (and, once committed, every fresh clone).
135
+ // Sweeping first lets a repo that already carries one self-heal.
136
+ sweepStaleWorkDirs(moduleRoot)
137
+
138
+ work, err := os.MkdirTemp(moduleRoot, "_readmecheck-")
113
139
  if err != nil {
114
140
  t.Fatalf("mkdir temp: %v", err)
115
141
  }
@@ -179,6 +205,10 @@ func TestReadmeGoSnippets(t *testing.T) {
179
205
  if err := os.WriteFile(filepath.Join(runDir, "main.go"), []byte(variant), 0o644); err != nil {
180
206
  t.Fatal(err)
181
207
  }
208
+ // The rewritten ctors reference the shared fixture.
209
+ if err := os.WriteFile(filepath.Join(runDir, "seed.go"), seedFile("main"), 0o644); err != nil {
210
+ t.Fatal(err)
211
+ }
182
212
  runDirs = append(runDirs, "./"+rel+"/run"+strconv.Itoa(progCount))
183
213
  }
184
214
 
@@ -197,6 +227,10 @@ func TestReadmeGoSnippets(t *testing.T) {
197
227
  if err := os.MkdirAll(fragDir, 0o755); err != nil {
198
228
  t.Fatal(err)
199
229
  }
230
+ // One shared fixture for the whole fragment package (see testSeed).
231
+ if err := os.WriteFile(filepath.Join(fragDir, "seed.go"), seedFile("readmefrag"), 0o644); err != nil {
232
+ t.Fatal(err)
233
+ }
200
234
  fragPkg = "./" + rel + "/frag"
201
235
  }
202
236
 
@@ -305,7 +339,7 @@ func runProgs(moduleRoot string, dirs []string) string {
305
339
  // left-to-right pass with balanced-paren matching; returns the rewritten
306
340
  // source and whether any replacement was made.
307
341
  func rewriteCtorsToTest(src string) (string, bool) {
308
- repl := "sdk.TestSDK(" + testSeed + ", nil)"
342
+ repl := "sdk.TestSDK(" + seedRef + ", nil)"
309
343
  var b strings.Builder
310
344
  changed := false
311
345
  i := 0
@@ -555,7 +589,7 @@ func wrapFragment(name, block, modulePath string) string {
555
589
  b.WriteString("func " + name + "() {\\n")
556
590
  if injectClient {
557
591
  // Seeded test client so the fragment's documented calls have data.
558
- b.WriteString("\\tclient := sdk.TestSDK(" + testSeed + ", nil)\\n")
592
+ b.WriteString("\\tclient := sdk.TestSDK(" + seedRef + ", nil)\\n")
559
593
  }
560
594
  b.WriteString(block)
561
595
  b.WriteString("\\n}\\n")
@@ -664,6 +698,25 @@ func addBlankAssign(content, name string) string {
664
698
  return content[:last] + "\\t_ = " + name + "\\n" + content[last:]
665
699
  }
666
700
 
701
+ // sweepStaleWorkDirs removes work dirs abandoned by a killed run, under both
702
+ // the current "_readmecheck-" name and the legacy "readmecheck-" one that
703
+ // \`go build ./...\` still picks up.
704
+ func sweepStaleWorkDirs(moduleRoot string) {
705
+ entries, err := os.ReadDir(moduleRoot)
706
+ if err != nil {
707
+ return
708
+ }
709
+ for _, e := range entries {
710
+ if !e.IsDir() {
711
+ continue
712
+ }
713
+ if n := e.Name(); strings.HasPrefix(n, "readmecheck-") ||
714
+ strings.HasPrefix(n, "_readmecheck-") {
715
+ os.RemoveAll(filepath.Join(moduleRoot, n))
716
+ }
717
+ }
718
+ }
719
+
667
720
  func readModulePath(moduleRoot string) string {
668
721
  data, err := os.ReadFile(filepath.Join(moduleRoot, "go.mod"))
669
722
  if err != nil {
@@ -6,7 +6,7 @@ const ReadmeExplanation = cmp(function ReadmeExplanation(props: any) {
6
6
  const { target, ctx$: { model } } = props
7
7
 
8
8
  // Go module path == repo path on GitHub (org from model.origin).
9
- const gomodule = goModule(model, 'go')
9
+ const gomodule = goModule(model, target.name)
10
10
 
11
11
  Content(`### Data as maps
12
12
 
@@ -29,7 +29,7 @@ const ReadmeHowto = cmp(function ReadmeHowto(props: any) {
29
29
  const { target, ctx$: { model } } = props
30
30
 
31
31
  // Go module path == repo path on GitHub (org from model.origin).
32
- const gomodule = goModule(model, 'go')
32
+ const gomodule = goModule(model, target.name)
33
33
 
34
34
  const entity = getModelPath(model, `main.${KIT}.entity`)
35
35
  // Pick an entity with a real op (prefer a read op) — never fabricate a
@@ -7,7 +7,7 @@ const ReadmeInstall = cmp(function ReadmeInstall(props: any) {
7
7
  const { model } = ctx$
8
8
 
9
9
  // Go module path == repo path on GitHub (org from model.origin).
10
- const gomodule = packageName(model, 'go')
10
+ const gomodule = packageName(model, target.name)
11
11
  // `repo` is the directory a `git clone` of this project creates — not
12
12
  // `<slug>-sdk`, which is only the DEFAULT repo name.
13
13
  const { releasesUrl, repo } = repoInfo(model)
@@ -44,7 +44,7 @@ const ReadmeModel = cmp(function ReadmeModel(props: any) {
44
44
  const resultShapeRows = resultRows.join('\n')
45
45
 
46
46
  // Go module path == repo path on GitHub (org from model.origin).
47
- const gomodule = goModule(model, 'go')
47
+ const gomodule = goModule(model, target.name)
48
48
 
49
49
  const apikeyOptionRow = isAuthActive(model)
50
50
  ? '| `"apikey"` | `string` | API key for authentication. |\n'
@@ -20,7 +20,7 @@ const ReadmeQuick = cmp(function ReadmeQuick(props: any) {
20
20
 
21
21
  const entity = getModelPath(model, `main.${KIT}.entity`)
22
22
  // Go module path == repo path on GitHub (org from model.origin).
23
- const gomodule = goModule(model, 'go')
23
+ const gomodule = goModule(model, target.name)
24
24
 
25
25
  const exampleEntity = Object.values(entity).find((e: any) => e.active !== false) as any
26
26
 
@@ -15,7 +15,7 @@ const ReadmeTopQuick = cmp(function ReadmeTopQuick(props: any) {
15
15
 
16
16
  const entity = getModelPath(model, `main.${KIT}.entity`)
17
17
  // Go module path == repo path on GitHub (org from model.origin).
18
- const gomodule = goModule(model, 'go')
18
+ const gomodule = goModule(model, target.name)
19
19
 
20
20
  const exampleEntity = Object.values(entity).find((e: any) => e.active !== false) as any
21
21
 
@@ -28,7 +28,7 @@ const ReadmeTopTest = cmp(function ReadmeTopTest(props: any) {
28
28
 
29
29
  const entity = getModelPath(model, `main.${KIT}.entity`)
30
30
  // Go module path == repo path on GitHub (org from model.origin).
31
- const gomodule = goModule(model, 'go')
31
+ const gomodule = goModule(model, target.name)
32
32
 
33
33
  // Pick an entity with a real op (prefer a read op) — never fabricate a
34
34
  // `load` on an op-less entity like Cloudsmith's `Abort`.
@@ -1,14 +1,9 @@
1
1
 
2
- import {
3
- KIT,
4
- getModelPath
5
- } from '@voxgig/apidef'
6
-
7
2
  import type {
8
3
  ModelEntity
9
4
  } from '@voxgig/apidef'
10
5
 
11
- import { cmp, each, Folder, File, Content, goModule } from '@voxgig/sdkgen'
6
+ import { cmp, each, Folder, File, Content, goModule, entityCollection } from '@voxgig/sdkgen'
12
7
 
13
8
 
14
9
  import { TestEntity } from './TestEntity_go'
@@ -22,7 +17,7 @@ const Test = cmp(function Test(props: any) {
22
17
 
23
18
  // Module name: concatenated lowercase
24
19
  // Go module path == repo path on GitHub (org from model.origin).
25
- const gomodule = goModule(model, 'go')
20
+ const gomodule = goModule(model, target.name)
26
21
 
27
22
  Folder({ name: 'test' }, () => {
28
23
 
@@ -48,7 +43,10 @@ func TestExists(t *testing.T) {
48
43
  `)
49
44
  })
50
45
 
51
- each(model.main[KIT].entity, (entity: ModelEntity) => {
46
+ const entity = each(entityCollection(model))
47
+ .filter((e: any) => false !== e.active)
48
+
49
+ each(entity, (entity: ModelEntity) => {
52
50
  TestEntity({ target, entity, gomodule })
53
51
  TestDirect({ target, entity, gomodule })
54
52
  })
@@ -50,8 +50,12 @@ const Main = cmp(function Main(props: any) {
50
50
  const { model } = props.ctx$
51
51
 
52
52
  const org = model.origin || 'voxgig-sdk'
53
+ // The two names on the next lines are DIFFERENT KINDS of name, and the
54
+ // adjacency is the trap. `sdkModule` is the Go SDK this CLI imports — a
55
+ // different target, so it keeps its own name and must NOT follow this
56
+ // target's alias. `cliModule` is this target itself, so it must.
53
57
  const sdkModule = goModule(model, 'go')
54
- const cliModule = goModule(model, 'go-cli')
58
+ const cliModule = goModule(model, target.name)
55
59
 
56
60
  const entityMap: any = getModelPath(model, `main.${KIT}.entity`)
57
61
  // Derive each entity's PascalCase `Name` here rather than relying on another
@@ -369,7 +373,7 @@ this repo, or upstream at
369
373
  // (go 1.24.7) — keep in step with BORU_ENG_VERSION.
370
374
  File({ name: 'go.mod' }, () => Content(`module ${cliModule}
371
375
 
372
- go ${goVersion(model, 'go-cli', '1.24.7')}
376
+ go ${goVersion(model, target.name, '1.24.7')}
373
377
 
374
378
  require ${sdkModule} v0.0.0
375
379
  require github.com/boru-lang/boru/eng/go ${BORU_ENG_VERSION}
@@ -50,8 +50,12 @@ const Main = cmp(function Main(props: any) {
50
50
  const { model } = props.ctx$
51
51
 
52
52
  const org = model.origin || 'voxgig-sdk'
53
+ // The two names on the next lines are DIFFERENT KINDS of name, and the
54
+ // adjacency is the trap. `sdkModule` is the Go SDK this CLI imports — a
55
+ // different target, so it keeps its own name and must NOT follow this
56
+ // target's alias. `mcpModule` is this target itself, so it must.
53
57
  const sdkModule = goModule(model, 'go')
54
- const mcpModule = goModule(model, 'go-mcp')
58
+ const mcpModule = goModule(model, target.name)
55
59
 
56
60
  const entityMap: any = getModelPath(model, `main.${KIT}.entity`)
57
61
  // Derive each entity's PascalCase `Name` here rather than relying on another
@@ -319,7 +323,7 @@ this repo, or upstream at
319
323
  // the public proxy. The MCP Go SDK requires go >= 1.25.
320
324
  File({ name: 'go.mod' }, () => Content(`module ${mcpModule}
321
325
 
322
- go ${goVersion(model, 'go-mcp', '1.25.0')}
326
+ go ${goVersion(model, target.name, '1.25.0')}
323
327
 
324
328
  require ${sdkModule} v0.0.0
325
329
  require github.com/modelcontextprotocol/go-sdk ${MCP_GO_SDK_VERSION}
@@ -3,6 +3,7 @@ import {
3
3
  Content,
4
4
  File,
5
5
  cmp,
6
+ configDefinition,
6
7
  each,
7
8
  isAuthActive,
8
9
  resolveAuthPrefix,
@@ -75,8 +76,14 @@ const Config = cmp(async function Config(props: any) {
75
76
  relations: n.relations,
76
77
  }, true), a), {})
77
78
 
79
+ // Identity comes from configDefinition's def, not re-derived here, so
80
+ // this target cannot disagree with the shared emitter on main.slug /
81
+ // main.version / main.target (the three station descriptor fields,
82
+ // station design §4) — passing target.name is what opts this target in.
83
+ const { def: configDef } = configDefinition(model, target.name)
84
+
78
85
  const config = {
79
- main: { name: model.const.Name },
86
+ main: configDef.main,
80
87
  feature: featureConfig,
81
88
  options,
82
89
  entity: entityConfig,
@@ -1,14 +1,9 @@
1
1
 
2
- import {
3
- KIT,
4
- getModelPath
5
- } from '@voxgig/apidef'
6
-
7
2
  import type {
8
3
  ModelEntity
9
4
  } from '@voxgig/apidef'
10
5
 
11
- import { cmp, each, Folder } from '@voxgig/sdkgen'
6
+ import { cmp, each, Folder, entityCollection } from '@voxgig/sdkgen'
12
7
 
13
8
 
14
9
  import { TestEntity } from './TestEntity_java'
@@ -30,7 +25,9 @@ const Test = cmp(function Test(props: any) {
30
25
  // CustomUtilityTest, StructRunner/StructCorpusTest, ExistsTest and
31
26
  // sdk-test-control.json) ships as templates in tm/java/test/ and is
32
27
  // copied by Main_java. Here we generate only the API-specific tests.
33
- each(model.main[KIT].entity, (entity: ModelEntity) => {
28
+ const entity = each(entityCollection(model))
29
+ .filter((e: any) => false !== e.active)
30
+ each(entity, (entity: ModelEntity) => {
34
31
  TestEntity({ target, entity, javapackage })
35
32
  TestDirect({ target, entity, javapackage })
36
33
  })
@@ -81,7 +81,7 @@ const Config = cmp(async function Config(props: any) {
81
81
  // literal and the data that replaces it above the threshold are the same
82
82
  // config by construction. The JSON is what the threshold is measured on -
83
83
  // emitted source size varies by language, the model does not.
84
- const { json: configJson } = configDefinition(model)
84
+ const { def: configDef, json: configJson } = configDefinition(model, target.name)
85
85
  const asData = isConfigData(configJson, configReprSetting(model))
86
86
 
87
87
  File({ name: 'Config.' + target.ext }, () => {
@@ -128,6 +128,14 @@ const Config = cmp(async function Config(props: any) {
128
128
  `require('./feature/${f.name}/${nom(f, 'Name')}Feature')`)
129
129
  }),
130
130
 
131
+ // Values from configDefinition's def, not re-derived here, so the
132
+ // literal rep and the data rep cannot disagree on identity.
133
+ '// #MainMeta': () => {
134
+ Line(` slug: ${JSON.stringify(configDef.main.slug)},`)
135
+ Line(` version: ${JSON.stringify(configDef.main.version)},`)
136
+ Line(` target: ${JSON.stringify(configDef.main.target)},`)
137
+ },
138
+
131
139
  '// #FeatureClasses': () => each(feature, (f: any) => {
132
140
  // Trailing comma: the map has one entry per feature, so entries
133
141
  // must be comma-separated (a single feature hid this until now).
@@ -63,7 +63,7 @@ const Package = cmp(async function Package(props: any) {
63
63
  const pkg = {
64
64
  // The ts target publishes the canonical scoped npm name; the js target
65
65
  // appends `-js` so the two never collide on npm.
66
- name: packageName(model, 'js'),
66
+ name: packageName(model, target.name),
67
67
  version: packageVersion(model, target.name),
68
68
  description: pkgDescription(model, target.name),
69
69
  keywords: keywords(model),
@@ -1,14 +1,9 @@
1
1
 
2
- import {
3
- KIT,
4
- getModelPath
5
- } from '@voxgig/apidef'
6
-
7
2
  import type {
8
3
  ModelEntity
9
4
  } from '@voxgig/apidef'
10
5
 
11
- import { cmp, each, Folder } from '@voxgig/sdkgen'
6
+ import { cmp, each, Folder, entityCollection } from '@voxgig/sdkgen'
12
7
 
13
8
 
14
9
  import { TestDirect } from './TestDirect_js'
@@ -22,7 +17,9 @@ const Test = cmp(function Test(props: any) {
22
17
  Folder({ name: 'test' }, () => {
23
18
 
24
19
  Folder({ name: 'entity' }, () => {
25
- each(model.main[KIT].entity, (entity: ModelEntity) => {
20
+ const entity = each(entityCollection(model))
21
+ .filter((e: any) => false !== e.active)
22
+ each(entity, (entity: ModelEntity) => {
26
23
  TestEntity({ target, entity })
27
24
  TestDirect({ target, entity })
28
25
  })
@@ -34,6 +34,13 @@ class Config {
34
34
  return fi
35
35
  }
36
36
 
37
+ // False for a feature added at runtime via options.extend (station's
38
+ // adopt path) - the constructor uses this to skip makeFeature for names
39
+ // no generated class backs.
40
+ hasFeature(fn) {
41
+ return null != FEATURE_CLASS[fn]
42
+ }
43
+
37
44
  }
38
45
 
39
46
 
@@ -17,9 +17,17 @@ class Config {
17
17
  return fi
18
18
  }
19
19
 
20
+ // False for a feature added at runtime via options.extend (station's
21
+ // adopt path) - the constructor uses this to skip makeFeature for names
22
+ // no generated class backs.
23
+ hasFeature(fn) {
24
+ return null != FEATURE_CLASS[fn]
25
+ }
26
+
20
27
 
21
28
  main = {
22
29
  name: '$$const.Name$$',
30
+ // #MainMeta
23
31
  }
24
32
 
25
33