@voxgig/sdkgen 4.22.0 → 4.24.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 (315) hide show
  1. package/bin/voxgig-sdkgen +18 -2
  2. package/dist/action/doctor.d.ts +1 -1
  3. package/dist/action/doctor.js +12 -10
  4. package/dist/action/doctor.js.map +1 -1
  5. package/dist/action/edition.js +4 -0
  6. package/dist/action/edition.js.map +1 -1
  7. package/dist/action/feature.js +5 -1
  8. package/dist/action/feature.js.map +1 -1
  9. package/dist/action/remove.d.ts +16 -0
  10. package/dist/action/remove.js +345 -0
  11. package/dist/action/remove.js.map +1 -0
  12. package/dist/action/target.js +6 -1
  13. package/dist/action/target.js.map +1 -1
  14. package/dist/cmp/ReadmeTop.js +1 -1
  15. package/dist/cmp/ReadmeTop.js.map +1 -1
  16. package/dist/cmp/ReadmeUnions.js +1 -1
  17. package/dist/cmp/ReadmeUnions.js.map +1 -1
  18. package/dist/cmp/Test.js +1 -1
  19. package/dist/cmp/Test.js.map +1 -1
  20. package/dist/helpers/buildIdNames.d.ts +3 -1
  21. package/dist/helpers/buildIdNames.js +15 -7
  22. package/dist/helpers/buildIdNames.js.map +1 -1
  23. package/dist/helpers/canonSpec.js +2 -2
  24. package/dist/helpers/canonSpec.js.map +1 -1
  25. package/dist/helpers/getMatchEntries.js +2 -2
  26. package/dist/helpers/getMatchEntries.js.map +1 -1
  27. package/dist/helpers/modelNames.js +5 -1
  28. package/dist/helpers/modelNames.js.map +1 -1
  29. package/dist/helpers/opShape.js +33 -33
  30. package/dist/helpers/opShape.js.map +1 -1
  31. package/dist/helpers/pointPath.js +5 -10
  32. package/dist/helpers/pointPath.js.map +1 -1
  33. package/dist/helpers/resolved.js +2 -29
  34. package/dist/helpers/resolved.js.map +1 -1
  35. package/dist/sdkgen.d.ts +2 -2
  36. package/dist/sdkgen.js +5 -3
  37. package/dist/sdkgen.js.map +1 -1
  38. package/dist/tsconfig.tsbuildinfo +1 -1
  39. package/dist/utility.js +15 -7
  40. package/dist/utility.js.map +1 -1
  41. package/package.json +3 -3
  42. package/project/.sdk/src/cmp/c/EntityTypes_c.ts +4 -4
  43. package/project/.sdk/src/cmp/c/ReadmeEntity_c.ts +3 -3
  44. package/project/.sdk/src/cmp/c/ReadmeModel_c.ts +3 -3
  45. package/project/.sdk/src/cmp/c/ReadmeRef_c.ts +5 -5
  46. package/project/.sdk/src/cmp/c/Schema_c.ts +1 -1
  47. package/project/.sdk/src/cmp/c/TestDirect_c.ts +12 -12
  48. package/project/.sdk/src/cmp/clojure/ReadmeEntity_clojure.ts +3 -3
  49. package/project/.sdk/src/cmp/clojure/ReadmeModel_clojure.ts +3 -3
  50. package/project/.sdk/src/cmp/clojure/ReadmeRef_clojure.ts +5 -5
  51. package/project/.sdk/src/cmp/clojure/Schema_clojure.ts +1 -1
  52. package/project/.sdk/src/cmp/cpp/EntityTypes_cpp.ts +3 -3
  53. package/project/.sdk/src/cmp/cpp/ReadmeEntity_cpp.ts +3 -3
  54. package/project/.sdk/src/cmp/cpp/ReadmeModel_cpp.ts +3 -3
  55. package/project/.sdk/src/cmp/cpp/ReadmeRef_cpp.ts +5 -5
  56. package/project/.sdk/src/cmp/cpp/Schema_cpp.ts +1 -1
  57. package/project/.sdk/src/cmp/cpp/TestDirect_cpp.ts +14 -14
  58. package/project/.sdk/src/cmp/cpp/TestEntity_cpp.ts +51 -50
  59. package/project/.sdk/src/cmp/csharp/EntityTypes_csharp.ts +4 -4
  60. package/project/.sdk/src/cmp/csharp/ReadmeEntity_csharp.ts +3 -3
  61. package/project/.sdk/src/cmp/csharp/ReadmeModel_csharp.ts +3 -3
  62. package/project/.sdk/src/cmp/csharp/ReadmeRef_csharp.ts +5 -5
  63. package/project/.sdk/src/cmp/csharp/Schema_csharp.ts +1 -1
  64. package/project/.sdk/src/cmp/csharp/TestDirect_csharp.ts +30 -30
  65. package/project/.sdk/src/cmp/csharp/TestEntity_csharp.ts +66 -65
  66. package/project/.sdk/src/cmp/elixir/EntityTypes_elixir.ts +4 -4
  67. package/project/.sdk/src/cmp/elixir/ReadmeEntity_elixir.ts +3 -3
  68. package/project/.sdk/src/cmp/elixir/ReadmeModel_elixir.ts +3 -3
  69. package/project/.sdk/src/cmp/elixir/ReadmeRef_elixir.ts +4 -4
  70. package/project/.sdk/src/cmp/elixir/Schema_elixir.ts +1 -1
  71. package/project/.sdk/src/cmp/go/EntityTypes_go.ts +4 -4
  72. package/project/.sdk/src/cmp/go/ReadmeEntity_go.ts +3 -3
  73. package/project/.sdk/src/cmp/go/ReadmeModel_go.ts +3 -3
  74. package/project/.sdk/src/cmp/go/ReadmeRef_go.ts +5 -5
  75. package/project/.sdk/src/cmp/go/Schema_go.ts +1 -1
  76. package/project/.sdk/src/cmp/go/TestDirect_go.ts +38 -38
  77. package/project/.sdk/src/cmp/go/TestEntity_go.ts +75 -74
  78. package/project/.sdk/src/cmp/go/utility_go.ts +5 -5
  79. package/project/.sdk/src/cmp/java/EntityTypes_java.ts +4 -4
  80. package/project/.sdk/src/cmp/java/ReadmeEntity_java.ts +3 -3
  81. package/project/.sdk/src/cmp/java/ReadmeModel_java.ts +3 -3
  82. package/project/.sdk/src/cmp/java/ReadmeRef_java.ts +5 -5
  83. package/project/.sdk/src/cmp/java/Schema_java.ts +1 -1
  84. package/project/.sdk/src/cmp/java/TestDirect_java.ts +30 -30
  85. package/project/.sdk/src/cmp/java/TestEntity_java.ts +69 -68
  86. package/project/.sdk/src/cmp/js/EntityTypes_js.ts +5 -5
  87. package/project/.sdk/src/cmp/js/ReadmeEntity_js.ts +3 -3
  88. package/project/.sdk/src/cmp/js/ReadmeModel_js.ts +3 -3
  89. package/project/.sdk/src/cmp/js/ReadmeRef_js.ts +5 -5
  90. package/project/.sdk/src/cmp/js/Schema_js.ts +1 -1
  91. package/project/.sdk/src/cmp/js/TestDirect_js.ts +27 -27
  92. package/project/.sdk/src/cmp/js/TestEntity_js.ts +66 -69
  93. package/project/.sdk/src/cmp/js/TestLive_js.ts +3 -3
  94. package/project/.sdk/src/cmp/js/utility_js.ts +5 -5
  95. package/project/.sdk/src/cmp/kotlin/EntityTypes_kotlin.ts +4 -4
  96. package/project/.sdk/src/cmp/kotlin/ReadmeEntity_kotlin.ts +3 -3
  97. package/project/.sdk/src/cmp/kotlin/ReadmeModel_kotlin.ts +3 -3
  98. package/project/.sdk/src/cmp/kotlin/ReadmeRef_kotlin.ts +5 -5
  99. package/project/.sdk/src/cmp/kotlin/Schema_kotlin.ts +1 -1
  100. package/project/.sdk/src/cmp/kotlin/TestDirect_kotlin.ts +30 -30
  101. package/project/.sdk/src/cmp/kotlin/TestEntity_kotlin.ts +67 -66
  102. package/project/.sdk/src/cmp/lua/EntityTypes_lua.ts +5 -5
  103. package/project/.sdk/src/cmp/lua/ReadmeEntity_lua.ts +3 -3
  104. package/project/.sdk/src/cmp/lua/ReadmeModel_lua.ts +3 -3
  105. package/project/.sdk/src/cmp/lua/ReadmeQuick_lua.ts +4 -4
  106. package/project/.sdk/src/cmp/lua/ReadmeRef_lua.ts +5 -5
  107. package/project/.sdk/src/cmp/lua/Schema_lua.ts +1 -1
  108. package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +25 -25
  109. package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +66 -65
  110. package/project/.sdk/src/cmp/ocaml/ReadmeEntity_ocaml.ts +3 -3
  111. package/project/.sdk/src/cmp/ocaml/ReadmeModel_ocaml.ts +3 -3
  112. package/project/.sdk/src/cmp/ocaml/ReadmeRef_ocaml.ts +5 -5
  113. package/project/.sdk/src/cmp/ocaml/Schema_ocaml.ts +1 -1
  114. package/project/.sdk/src/cmp/perl/ReadmeEntity_perl.ts +3 -3
  115. package/project/.sdk/src/cmp/perl/ReadmeModel_perl.ts +3 -3
  116. package/project/.sdk/src/cmp/perl/ReadmeRef_perl.ts +5 -5
  117. package/project/.sdk/src/cmp/perl/Schema_perl.ts +1 -1
  118. package/project/.sdk/src/cmp/perl/TestDirect_perl.ts +25 -25
  119. package/project/.sdk/src/cmp/perl/TestEntity_perl.ts +60 -59
  120. package/project/.sdk/src/cmp/php/EntityTypes_php.ts +4 -4
  121. package/project/.sdk/src/cmp/php/ReadmeEntity_php.ts +3 -3
  122. package/project/.sdk/src/cmp/php/ReadmeModel_php.ts +3 -3
  123. package/project/.sdk/src/cmp/php/ReadmeQuick_php.ts +4 -4
  124. package/project/.sdk/src/cmp/php/ReadmeRef_php.ts +5 -5
  125. package/project/.sdk/src/cmp/php/Schema_php.ts +1 -1
  126. package/project/.sdk/src/cmp/php/TestDirect_php.ts +25 -25
  127. package/project/.sdk/src/cmp/php/TestEntity_php.ts +66 -65
  128. package/project/.sdk/src/cmp/py/EntityTypes_py.ts +4 -4
  129. package/project/.sdk/src/cmp/py/ReadmeEntity_py.ts +3 -3
  130. package/project/.sdk/src/cmp/py/ReadmeModel_py.ts +3 -3
  131. package/project/.sdk/src/cmp/py/ReadmeRef_py.ts +5 -5
  132. package/project/.sdk/src/cmp/py/Schema_py.ts +1 -1
  133. package/project/.sdk/src/cmp/py/TestDirect_py.ts +25 -25
  134. package/project/.sdk/src/cmp/py/TestEntity_py.ts +66 -65
  135. package/project/.sdk/src/cmp/py-data/Main_py-data.ts +4 -4
  136. package/project/.sdk/src/cmp/rb/EntityTypes_rb.ts +4 -4
  137. package/project/.sdk/src/cmp/rb/ReadmeEntity_rb.ts +3 -3
  138. package/project/.sdk/src/cmp/rb/ReadmeModel_rb.ts +3 -3
  139. package/project/.sdk/src/cmp/rb/ReadmeQuick_rb.ts +4 -4
  140. package/project/.sdk/src/cmp/rb/ReadmeRef_rb.ts +5 -5
  141. package/project/.sdk/src/cmp/rb/Schema_rb.ts +1 -1
  142. package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +25 -25
  143. package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +66 -65
  144. package/project/.sdk/src/cmp/rust/EntityTypes_rust.ts +4 -4
  145. package/project/.sdk/src/cmp/rust/ReadmeEntity_rust.ts +3 -3
  146. package/project/.sdk/src/cmp/rust/ReadmeModel_rust.ts +3 -3
  147. package/project/.sdk/src/cmp/rust/ReadmeRef_rust.ts +5 -5
  148. package/project/.sdk/src/cmp/rust/Schema_rust.ts +1 -1
  149. package/project/.sdk/src/cmp/rust/TestDirect_rust.ts +18 -18
  150. package/project/.sdk/src/cmp/rust/TestEntity_rust.ts +63 -62
  151. package/project/.sdk/src/cmp/scala/EntityTypes_scala.ts +4 -4
  152. package/project/.sdk/src/cmp/scala/ReadmeEntity_scala.ts +3 -3
  153. package/project/.sdk/src/cmp/scala/ReadmeModel_scala.ts +3 -3
  154. package/project/.sdk/src/cmp/scala/ReadmeRef_scala.ts +5 -5
  155. package/project/.sdk/src/cmp/scala/Schema_scala.ts +1 -1
  156. package/project/.sdk/src/cmp/scala/TestDirect_scala.ts +14 -14
  157. package/project/.sdk/src/cmp/scala/TestEntity_scala.ts +60 -59
  158. package/project/.sdk/src/cmp/swift/EntityTypes_swift.ts +4 -4
  159. package/project/.sdk/src/cmp/swift/ReadmeEntity_swift.ts +3 -3
  160. package/project/.sdk/src/cmp/swift/ReadmeModel_swift.ts +3 -3
  161. package/project/.sdk/src/cmp/swift/ReadmeRef_swift.ts +5 -5
  162. package/project/.sdk/src/cmp/swift/Schema_swift.ts +1 -1
  163. package/project/.sdk/src/cmp/ts/EntityTypes_ts.ts +5 -5
  164. package/project/.sdk/src/cmp/ts/ReadmeEntity_ts.ts +3 -3
  165. package/project/.sdk/src/cmp/ts/ReadmeModel_ts.ts +3 -3
  166. package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +1 -1
  167. package/project/.sdk/src/cmp/ts/ReadmeRef_ts.ts +5 -5
  168. package/project/.sdk/src/cmp/ts/Schema_ts.ts +1 -1
  169. package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +40 -40
  170. package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +72 -75
  171. package/project/.sdk/src/cmp/ts/TestLive_ts.ts +3 -3
  172. package/project/.sdk/src/cmp/ts/utility_ts.ts +5 -5
  173. package/project/.sdk/src/cmp/zig/ReadmeEntity_zig.ts +3 -3
  174. package/project/.sdk/src/cmp/zig/ReadmeModel_zig.ts +3 -3
  175. package/project/.sdk/src/cmp/zig/ReadmeRef_zig.ts +5 -5
  176. package/project/.sdk/src/cmp/zig/Schema_zig.ts +1 -1
  177. package/project/.sdk/tm/c/core/context.c +3 -1
  178. package/project/.sdk/tm/c/feature/paging.c +37 -3
  179. package/project/.sdk/tm/c/feature/test.c +71 -31
  180. package/project/.sdk/tm/c/utility/prepare_query.c +2 -1
  181. package/project/.sdk/tm/c/utility/transform_request.c +25 -3
  182. package/project/.sdk/tm/clojure/src/sdk/core.clj +21 -7
  183. package/project/.sdk/tm/clojure/src/sdk/features.clj +74 -22
  184. package/project/.sdk/tm/cpp/core/types.hpp +1 -1
  185. package/project/.sdk/tm/cpp/feature/paging.hpp +36 -3
  186. package/project/.sdk/tm/cpp/feature/test.hpp +58 -19
  187. package/project/.sdk/tm/cpp/utility/pipeline.hpp +16 -4
  188. package/project/.sdk/tm/csharp/core/Context.cs +1 -1
  189. package/project/.sdk/tm/csharp/feature/PagingFeature.cs +58 -4
  190. package/project/.sdk/tm/csharp/feature/TestFeature.cs +23 -25
  191. package/project/.sdk/tm/csharp/utility/Fetcher.cs +19 -12
  192. package/project/.sdk/tm/csharp/utility/PrepareQuery.cs +1 -1
  193. package/project/.sdk/tm/csharp/utility/TransformRequest.cs +23 -3
  194. package/project/.sdk/tm/elixir/lib/projectname/context.ex +1 -1
  195. package/project/.sdk/tm/elixir/lib/projectname/feature/paging.ex +52 -10
  196. package/project/.sdk/tm/elixir/lib/projectname/feature/test.ex +58 -22
  197. package/project/.sdk/tm/elixir/lib/projectname/utility.ex +30 -9
  198. package/project/.sdk/tm/go/core/context.go +13 -13
  199. package/project/.sdk/tm/go/feature/paging_feature.go +40 -2
  200. package/project/.sdk/tm/go/feature/test_feature.go +3 -15
  201. package/project/.sdk/tm/go/test/feature_corpus_test.go +1 -0
  202. package/project/.sdk/tm/go/test/feature_test.go +54 -0
  203. package/project/.sdk/tm/go/utility/fetcher.go +41 -20
  204. package/project/.sdk/tm/go/utility/prepare_query.go +1 -1
  205. package/project/.sdk/tm/go/utility/transform_request.go +22 -3
  206. package/project/.sdk/tm/java/core/Context.java +2 -1
  207. package/project/.sdk/tm/java/feature/PagingFeature.java +46 -4
  208. package/project/.sdk/tm/java/feature/TestFeature.java +21 -19
  209. package/project/.sdk/tm/java/test/FeatureCorpusTest.java +3 -0
  210. package/project/.sdk/tm/java/test/FeatureTest.java +42 -0
  211. package/project/.sdk/tm/java/utility/Fetcher.java +36 -28
  212. package/project/.sdk/tm/java/utility/PrepareQuery.java +1 -1
  213. package/project/.sdk/tm/java/utility/TransformRequest.java +18 -3
  214. package/project/.sdk/tm/js/src/Context.js +7 -2
  215. package/project/.sdk/tm/js/src/feature/paging/PagingFeature.js +24 -6
  216. package/project/.sdk/tm/js/src/feature/test/TestFeature.js +7 -5
  217. package/project/.sdk/tm/js/src/utility/PrepareQueryUtility.js +1 -1
  218. package/project/.sdk/tm/js/test/feature/Corpus.test.js +4 -0
  219. package/project/.sdk/tm/js/test/live-entity.js +29 -29
  220. package/project/.sdk/tm/js/test/live-scenarios.js +4 -4
  221. package/project/.sdk/tm/kotlin/core/Context.kt +1 -1
  222. package/project/.sdk/tm/kotlin/feature/PagingFeature.kt +36 -4
  223. package/project/.sdk/tm/kotlin/feature/TestFeature.kt +19 -18
  224. package/project/.sdk/tm/kotlin/utility/Fetcher.kt +33 -24
  225. package/project/.sdk/tm/kotlin/utility/Prepare.kt +1 -1
  226. package/project/.sdk/tm/kotlin/utility/ResultTransform.kt +18 -3
  227. package/project/.sdk/tm/lua/core/context.lua +8 -1
  228. package/project/.sdk/tm/lua/core/control.lua +3 -0
  229. package/project/.sdk/tm/lua/feature/paging_feature.lua +44 -5
  230. package/project/.sdk/tm/lua/feature/test_feature.lua +32 -14
  231. package/project/.sdk/tm/lua/utility/prepare_query.lua +2 -1
  232. package/project/.sdk/tm/lua/utility/transform_request.lua +19 -3
  233. package/project/.sdk/tm/ocaml/sdk_features.ml +78 -25
  234. package/project/.sdk/tm/ocaml/sdk_runtime.ml +23 -8
  235. package/project/.sdk/tm/perl/core/context.pm +2 -1
  236. package/project/.sdk/tm/perl/feature/paging_feature.pm +31 -5
  237. package/project/.sdk/tm/perl/feature/test_feature.pm +52 -20
  238. package/project/.sdk/tm/perl/feature/timeout_feature.pm +17 -13
  239. package/project/.sdk/tm/perl/t/feature_corpus.t +14 -1
  240. package/project/.sdk/tm/perl/utility/fetcher.pm +15 -1
  241. package/project/.sdk/tm/perl/utility/prepare_query.pm +1 -0
  242. package/project/.sdk/tm/perl/utility/transform_request.pm +13 -3
  243. package/project/.sdk/tm/php/core/Context.php +5 -1
  244. package/project/.sdk/tm/php/core/Control.php +5 -0
  245. package/project/.sdk/tm/php/feature/PagingFeature.php +26 -5
  246. package/project/.sdk/tm/php/feature/TestFeature.php +27 -42
  247. package/project/.sdk/tm/php/test/FeatureCorpusTest.php +17 -1
  248. package/project/.sdk/tm/php/test/FeatureTest.php +44 -0
  249. package/project/.sdk/tm/php/utility/Fetcher.php +17 -3
  250. package/project/.sdk/tm/php/utility/PrepareQuery.php +1 -1
  251. package/project/.sdk/tm/php/utility/TransformRequest.php +15 -3
  252. package/project/.sdk/tm/py/pkg/core/context.py +2 -1
  253. package/project/.sdk/tm/py/pkg/feature/paging_feature.py +29 -4
  254. package/project/.sdk/tm/py/pkg/feature/test_feature.py +29 -12
  255. package/project/.sdk/tm/py/pkg/utility/fetcher.py +63 -65
  256. package/project/.sdk/tm/py/pkg/utility/prepare_query.py +2 -1
  257. package/project/.sdk/tm/py/pkg/utility/transform_request.py +11 -3
  258. package/project/.sdk/tm/py/test/test_feature.py +27 -0
  259. package/project/.sdk/tm/py/test/test_feature_corpus.py +11 -1
  260. package/project/.sdk/tm/rb/core/context.rb +1 -1
  261. package/project/.sdk/tm/rb/feature/paging_feature.rb +27 -5
  262. package/project/.sdk/tm/rb/feature/test_feature.rb +39 -11
  263. package/project/.sdk/tm/rb/test/feature_corpus_test.rb +12 -1
  264. package/project/.sdk/tm/rb/test/feature_test.rb +38 -0
  265. package/project/.sdk/tm/rb/utility/fetcher.rb +49 -3
  266. package/project/.sdk/tm/rb/utility/prepare_query.rb +1 -1
  267. package/project/.sdk/tm/rb/utility/transform_request.rb +10 -3
  268. package/project/.sdk/tm/rust/core/context.rs +2 -6
  269. package/project/.sdk/tm/rust/feature/paging.rs +44 -3
  270. package/project/.sdk/tm/rust/feature/secrets.rs +1 -1
  271. package/project/.sdk/tm/rust/feature/test.rs +74 -37
  272. package/project/.sdk/tm/rust/utility/fetcher.rs +41 -14
  273. package/project/.sdk/tm/rust/utility/prepare_query.rs +1 -1
  274. package/project/.sdk/tm/rust/utility/transform_request.rs +31 -5
  275. package/project/.sdk/tm/scala/core/Context.scala +2 -1
  276. package/project/.sdk/tm/scala/feature/PagingFeature.scala +41 -4
  277. package/project/.sdk/tm/scala/feature/TestFeature.scala +21 -18
  278. package/project/.sdk/tm/scala/utility/Fetcher.scala +34 -13
  279. package/project/.sdk/tm/scala/utility/Prepare.scala +1 -1
  280. package/project/.sdk/tm/scala/utility/Transform.scala +19 -3
  281. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Context.swift +1 -1
  282. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/PagingFeature.swift +31 -4
  283. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/TestFeature.swift +22 -15
  284. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Fetcher.swift +22 -3
  285. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Prepare.swift +1 -1
  286. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/ResultUtil.swift +14 -3
  287. package/project/.sdk/tm/ts/src/Context.ts +7 -2
  288. package/project/.sdk/tm/ts/src/feature/paging/PagingFeature.ts +19 -3
  289. package/project/.sdk/tm/ts/src/feature/test/TestFeature.ts +3 -0
  290. package/project/.sdk/tm/ts/src/utility/PrepareQueryUtility.ts +1 -1
  291. package/project/.sdk/tm/ts/test/feature/Corpus.test.ts +1 -0
  292. package/project/.sdk/tm/ts/test/live-entity.ts +26 -26
  293. package/project/.sdk/tm/ts/test/live-scenarios.ts +3 -3
  294. package/project/.sdk/tm/zig/core/context.zig +1 -1
  295. package/project/.sdk/tm/zig/core/utility.zig +19 -5
  296. package/project/.sdk/tm/zig/feature/paging.zig +34 -4
  297. package/project/.sdk/tm/zig/feature/test.zig +65 -30
  298. package/project/sdkgen-package.json +1 -1
  299. package/src/action/doctor.ts +12 -9
  300. package/src/action/edition.ts +8 -0
  301. package/src/action/feature.ts +7 -1
  302. package/src/action/remove.ts +492 -0
  303. package/src/action/target.ts +8 -1
  304. package/src/cmp/ReadmeTop.ts +1 -1
  305. package/src/cmp/ReadmeUnions.ts +1 -1
  306. package/src/cmp/Test.ts +1 -1
  307. package/src/helpers/buildIdNames.ts +17 -7
  308. package/src/helpers/canonSpec.ts +2 -2
  309. package/src/helpers/getMatchEntries.ts +2 -2
  310. package/src/helpers/modelNames.ts +6 -1
  311. package/src/helpers/opShape.ts +33 -33
  312. package/src/helpers/pointPath.ts +5 -10
  313. package/src/helpers/resolved.ts +3 -14
  314. package/src/sdkgen.ts +3 -1
  315. package/src/utility.ts +16 -7
@@ -3,7 +3,8 @@
3
3
  // query; on the way back (PreResult) it reads the server's pagination
4
4
  // signals — a `Link: rel="next"` header, `X-Page`/`X-Next-Page`/
5
5
  // `X-Total-Count` headers, or `next`/`cursor`/`nextCursor`/`hasMore` fields
6
- // in the body — and records them on `result.paging`. A per-call cursor/page
6
+ // in the body (snake_case forms too) — and records them on `result.paging`
7
+ // and the caller's ctrl paging. A per-call cursor/page
7
8
  // from ctrl takes priority (used by auto-iteration). Parameter names
8
9
  // (`pageParam`, `limitParam`, `cursorParam`), the page size (`limit`) and
9
10
  // the start page (`startPage`, default 1) are configurable.
@@ -225,7 +226,10 @@ static void paging_pre_request(PagingFeature* pf, Context* ctx) {
225
226
  if (!v_is_noval(cursor) && !v_is_null(cursor)) {
226
227
  setp(query, cursor_param, cursor);
227
228
  } else if (v_is_noval(getp(query, page_param))) {
228
- voxgig_value* page = getp(paging, "page");
229
+ // A record written back by pre_result holds the page just fetched as
230
+ // "page" and the one to fetch as "nextPage", so nextPage wins.
231
+ voxgig_value* page = getp(paging, "nextPage");
232
+ if (v_is_noval(page) || v_is_null(page)) page = getp(paging, "page");
229
233
  if (!v_is_noval(page) && !v_is_null(page)) {
230
234
  setp(query, page_param, page);
231
235
  } else {
@@ -297,12 +301,16 @@ static void paging_pre_result(PagingFeature* pf, Context* ctx) {
297
301
  }
298
302
  }
299
303
 
300
- // Body-level cursors.
304
+ // Body-level signals; snake_case forms are read first so camelCase wins.
301
305
  if (voxgig_is_map(body)) {
302
306
  voxgig_value* next = getp(body, "next");
303
307
  if (!v_is_noval(next) && !v_is_null(next) && v_is_noval(getp(paging, "next"))) {
304
308
  setp(paging, "next", next);
305
309
  }
310
+ voxgig_value* snake_cursor = getp(body, "next_cursor");
311
+ if (!v_is_noval(snake_cursor) && !v_is_null(snake_cursor)) {
312
+ setp(paging, "cursor", snake_cursor);
313
+ }
306
314
  voxgig_value* cursor = getp(body, "cursor");
307
315
  if (!v_is_noval(cursor) && !v_is_null(cursor)) {
308
316
  setp(paging, "cursor", cursor);
@@ -311,7 +319,18 @@ static void paging_pre_result(PagingFeature* pf, Context* ctx) {
311
319
  if (!v_is_noval(next_cursor) && !v_is_null(next_cursor)) {
312
320
  setp(paging, "cursor", next_cursor);
313
321
  }
322
+ if (v_is_noval(getp(paging, "nextPage"))) {
323
+ voxgig_value* np = getp(body, "nextPage");
324
+ if (v_is_noval(np) || v_is_null(np)) np = getp(body, "next_page");
325
+ if (voxgig_is_number(np) || voxgig_is_string(np)) {
326
+ setp(paging, "nextPage", np);
327
+ }
328
+ }
314
329
  bool has_more;
330
+ if (get_bool(body, "has_more", &has_more)) {
331
+ setp(paging, "hasMore", v_bool(has_more));
332
+ explicit_more = true;
333
+ }
315
334
  if (get_bool(body, "hasMore", &has_more)) {
316
335
  setp(paging, "hasMore", v_bool(has_more));
317
336
  explicit_more = true;
@@ -334,6 +353,21 @@ static void paging_pre_result(PagingFeature* pf, Context* ctx) {
334
353
 
335
354
  ctx->result->paging = paging;
336
355
  pf->last = paging;
356
+
357
+ if (ctx->ctrl) {
358
+ // The Context shares the caller's paging map by pointer, so refill it in
359
+ // place; a fresh map on ctrl never reaches the caller.
360
+ if (voxgig_is_map(ctx->ctrl->paging)) {
361
+ voxgig_map* dst = voxgig_as_map(ctx->ctrl->paging);
362
+ voxgig_map* src = voxgig_as_map(paging);
363
+ voxgig_map_clear(dst);
364
+ for (size_t i = 0; i < voxgig_map_len(src); i++) {
365
+ voxgig_map_set(dst, voxgig_map_key_at(src, i), v_share(voxgig_map_val_at(src, i)));
366
+ }
367
+ } else {
368
+ ctx->ctrl->paging = paging;
369
+ }
370
+ }
337
371
  }
338
372
 
339
373
  static void paging_hook(Feature* f, const char* name, Context* ctx) {
@@ -30,20 +30,36 @@ static voxgig_value* envelope(Context* ctx, voxgig_value* data) {
30
30
  if (NULL == spec) {
31
31
  return data;
32
32
  }
33
- // Exactly `body.<key>`; a deeper path is not an envelope this mock can
34
- // synthesise, so it is left alone rather than guessed at.
33
+ // Rebuild whatever nesting the transform unwraps. Multi-segment on purpose:
34
+ // GraphQL ops unwrap `body.data.<field>` (and `body.data.<field>.<entity>`
35
+ // for mutation payloads), not just a single envelope property.
35
36
  size_t n = strlen(spec);
36
37
  if (n < 8 || 0 != strncmp(spec, "`body.", 6) || '`' != spec[n - 1]) {
37
38
  return data;
38
39
  }
39
40
  size_t inner_len = n - 7;
40
- if (0 == inner_len || NULL != memchr(spec + 6, '.', inner_len)) {
41
+ if (0 == inner_len) {
41
42
  return data;
42
43
  }
43
44
  char* inner = (char*)malloc(inner_len + 1);
44
45
  memcpy(inner, spec + 6, inner_len);
45
46
  inner[inner_len] = '\0';
46
- voxgig_value* out = cmap(1, inner, data);
47
+ // Innermost segment first, so walk back from the end, terminating each
48
+ // segment in place as it is consumed. cmap copies the key.
49
+ voxgig_value* out = data;
50
+ size_t pos = inner_len;
51
+ while (1) {
52
+ size_t start = pos;
53
+ while (start > 0 && '.' != inner[start - 1]) {
54
+ start--;
55
+ }
56
+ inner[pos] = '\0';
57
+ out = cmap(1, inner + start, out);
58
+ if (0 == start) {
59
+ break;
60
+ }
61
+ pos = start - 1;
62
+ }
47
63
  free(inner);
48
64
  return out;
49
65
  }
@@ -76,23 +92,61 @@ static const char* test_entity_name(Context* ctx) {
76
92
  return ctx->op->entity;
77
93
  }
78
94
 
95
+ static bool point_terminal(voxgig_value* p) {
96
+ voxgig_value* parts = getp(p, "parts");
97
+ if (!voxgig_is_list(parts)) return false;
98
+ voxgig_list* l = voxgig_as_list(parts);
99
+ if (0 == l->len) return false;
100
+ voxgig_value* last = l->items[l->len - 1];
101
+ return voxgig_is_string(last) && '{' == voxgig_as_string(last)[0];
102
+ }
103
+
104
+ static size_t point_depth(voxgig_value* p) {
105
+ voxgig_value* parts = getp(p, "parts");
106
+ return voxgig_is_list(parts) ? voxgig_as_list(parts)->len : 0;
107
+ }
108
+
109
+ // The entity's own endpoint: a terminal `{param}` marks a record route, and
110
+ // among equals the shallower path wins (the same rule as make_point).
111
+ static voxgig_value* pick_point(voxgig_value* points) {
112
+ if (!voxgig_is_list(points)) return NULL;
113
+ voxgig_list* l = voxgig_as_list(points);
114
+ if (0 == l->len) return NULL;
115
+ voxgig_value* point = l->items[0];
116
+ for (size_t i = 1; i < l->len; i++) {
117
+ voxgig_value* cand = l->items[i];
118
+ if (point_terminal(cand) != point_terminal(point)) {
119
+ if (point_terminal(cand)) point = cand;
120
+ } else if (point_depth(cand) < point_depth(point)) {
121
+ point = cand;
122
+ }
123
+ }
124
+ return point;
125
+ }
126
+
127
+ static voxgig_value* reqd_names(voxgig_value* point, const char* kind) {
128
+ voxgig_value* args_path = getpath2(point, "args", kind);
129
+ voxgig_value* reqd_args = voxgig_select(args_path, cmap(1, "reqd", v_bool(true)));
130
+ voxgig_value* reqd_spec =
131
+ clist(3, v_str("`$EACH`"), v_str(""), v_str("`$KEY.name`"));
132
+ voxgig_value* reqd = voxgig_transform(reqd_args, reqd_spec, NULL);
133
+ if (!voxgig_is_list(reqd)) reqd = v_list();
134
+ return reqd;
135
+ }
136
+
79
137
  static voxgig_value* build_args(Context* ctx, voxgig_value* args) {
80
138
  Operation* op = ctx->op;
81
139
  const char* opname = op->name;
82
140
  const char* entname = test_entity_name(ctx);
83
141
 
84
- // Get last point from config.
85
142
  const char* ppath[6] = {"entity", entname, "op", opname, "points", NULL};
86
143
  voxgig_value* points = getpath_c(ctx->config, ppath);
87
- voxgig_value* point = voxgig_getelem(points, v_int(-1), NULL);
144
+ voxgig_value* point = pick_point(points);
88
145
 
89
- // Get required params.
90
- voxgig_value* params_path = getpath2(point, "args", "params");
91
- voxgig_value* reqd_params = voxgig_select(params_path, cmap(1, "reqd", v_bool(true)));
92
- voxgig_value* reqd_spec =
93
- clist(3, v_str("`$EACH`"), v_str(""), v_str("`$KEY.name`"));
94
- voxgig_value* reqd = voxgig_transform(reqd_params, reqd_spec, NULL);
95
- if (!voxgig_is_list(reqd)) reqd = v_list();
146
+ // Path AND query: a path-only read misses a query-addressed record
147
+ // (e.g. GET /result?trace_id=), which has no path param at all.
148
+ voxgig_value* reqd_params = reqd_names(point, "params");
149
+ voxgig_value* reqd_query = reqd_names(point, "query");
96
150
 
97
151
  voxgig_value* qand = v_list();
98
152
  voxgig_value* q = cmap(1, "`$AND`", qand);
@@ -102,8 +156,8 @@ static voxgig_value* build_args(Context* ctx, voxgig_value* args) {
102
156
  for (size_t ki = 0; ki < keys.len; ki++) {
103
157
  const char* key = keys.data[ki];
104
158
  bool is_id = strcmp(key, "id") == 0;
105
- voxgig_value* selected = voxgig_select(reqd, v_str(key));
106
- bool is_reqd = !voxgig_isempty(selected);
159
+ bool is_reqd = !voxgig_isempty(voxgig_select(reqd_params, v_str(key))) ||
160
+ !voxgig_isempty(voxgig_select(reqd_query, v_str(key)));
107
161
 
108
162
  if (is_id || is_reqd) {
109
163
  voxgig_value* v = param_util(ctx, v_str(key));
@@ -193,28 +247,14 @@ static voxgig_value* test_fetch(voxgig_value* entity, Context* ctx, const char*
193
247
  voxgig_value* args = build_args(ctx, update_match);
194
248
  voxgig_value* found = voxgig_select(entmap, args);
195
249
  voxgig_value* ent = voxgig_getelem(found, v_int(0), NULL);
196
- if ((v_is_noval(ent) || v_is_null(ent)) && voxgig_size(entmap) > 0) {
197
- // Fall back to any entity in the fixture.
198
- voxgig_value* items = voxgig_items_v(entmap);
199
- voxgig_list* il = voxgig_as_list(items);
200
- for (size_t i = 0; i < il->len; i++) {
201
- voxgig_value* e = voxgig_getelem(il->items[i], v_int(1), NULL);
202
- if (voxgig_is_map(e)) {
203
- ent = e;
204
- break;
205
- }
206
- }
207
- }
208
250
  if (v_is_noval(ent) || v_is_null(ent)) {
251
+ // update miss: 404, never another record
209
252
  voxgig_value* r = respond(ctx, 404, v_undef());
210
253
  setp(r, "statusText", v_str("Not found"));
211
254
  return r;
212
255
  }
213
256
  if (voxgig_is_map(ent) && voxgig_is_map(reqdata)) {
214
- voxgig_map* rm = voxgig_as_map(reqdata);
215
- for (size_t i = 0; i < rm->len; i++) {
216
- setp(ent, rm->entries[i].key, rm->entries[i].value);
217
- }
257
+ ent = voxgig_merge(clist(2, v_share(ent), v_share(reqdata)), VOXGIG_MAXDEPTH);
218
258
  }
219
259
  voxgig_delprop(ent, v_str("$KEY"));
220
260
  return respond(ctx, 200, voxgig_clone(ent));
@@ -28,7 +28,8 @@ voxgig_value* prepare_query_util(Context* ctx) {
28
28
  for (size_t i = 0; i < rm->len; i++) {
29
29
  const char* key = rm->entries[i].key;
30
30
  voxgig_value* val = rm->entries[i].value;
31
- if (!v_is_noval(val) && !v_is_null(val) && !params_contains(params, key)) {
31
+ if (!v_is_noval(val) && !v_is_null(val) && strcmp(key, "$action") != 0 &&
32
+ !params_contains(params, key)) {
32
33
  setp(out, key, v_share(val));
33
34
  }
34
35
  }
@@ -2,6 +2,28 @@
2
2
 
3
3
  #include "sdk.h"
4
4
 
5
+ #include <string.h>
6
+
7
+ /* `$action` selects the point (see make_point_util); it is never an API
8
+ field, so the body is a copy without it. The caller's map is left
9
+ untouched. */
10
+ static voxgig_value* strip_action(voxgig_value* reqdata) {
11
+ if (!voxgig_is_map(reqdata)) return reqdata;
12
+ voxgig_map* rm = voxgig_as_map(reqdata);
13
+ bool has = false;
14
+ for (size_t i = 0; i < rm->len; i++) {
15
+ if (strcmp(rm->entries[i].key, "$action") == 0) { has = true; break; }
16
+ }
17
+ if (!has) return reqdata;
18
+ voxgig_value* body = voxgig_new_map();
19
+ for (size_t i = 0; i < rm->len; i++) {
20
+ if (strcmp(rm->entries[i].key, "$action") != 0) {
21
+ setp(body, rm->entries[i].key, v_share(rm->entries[i].value));
22
+ }
23
+ }
24
+ return body;
25
+ }
26
+
5
27
  voxgig_value* transform_request_util(Context* ctx) {
6
28
  Spec* spec = ctx->spec;
7
29
  voxgig_value* point = ctx->point;
@@ -9,14 +31,14 @@ voxgig_value* transform_request_util(Context* ctx) {
9
31
  if (spec) spec_set_step(spec, "reqform");
10
32
 
11
33
  voxgig_value* transform = to_map(getp(point, "transform"));
12
- if (v_is_noval(transform)) return ctx->reqdata;
34
+ if (v_is_noval(transform)) return strip_action(ctx->reqdata);
13
35
 
14
36
  voxgig_value* reqform = getp(transform, "req");
15
- if (v_is_noval(reqform) || v_is_null(reqform)) return ctx->reqdata;
37
+ if (v_is_noval(reqform) || v_is_null(reqform)) return strip_action(ctx->reqdata);
16
38
 
17
39
  voxgig_value* store = cmap(1, "reqdata", v_share(ctx->reqdata));
18
40
  /* Return the transform result verbatim, as the ts reference does. Falling
19
41
  back to ctx->reqdata meant a reqform naming a path that does not resolve
20
42
  sent the WHOLE request data instead of nothing. */
21
- return voxgig_transform(store, reqform, NULL);
43
+ return strip_action(voxgig_transform(store, reqform, NULL));
22
44
  }
@@ -305,7 +305,9 @@
305
305
  cprop (fn [k] (mget ctxmap k))
306
306
  client (or (cprop "client") (bget :client))
307
307
  utility (or (cprop "utility") (bget :utility))
308
- ;; ctrl: explicit ctrl map -> fresh control; else share base ctrl.
308
+ ;; ctrl: explicit ctrl map -> fresh control; an OPERATION (one named by
309
+ ;; opname) also gets its own, so a paging cursor cannot leak into the
310
+ ;; next call; anything else shares the base ctrl.
309
311
  ctrl-raw (cprop "ctrl")
310
312
  ctrl (cond
311
313
  (vs/ismap ctrl-raw)
@@ -315,7 +317,7 @@
315
317
  (when (contains? (into #{} (vs/keysof ctrl-raw)) "actor") (oset! c :actor (mget ctrl-raw "actor")))
316
318
  (when (vs/ismap (mget ctrl-raw "paging")) (oset! c :paging (mget ctrl-raw "paging")))
317
319
  c)
318
- (bget :ctrl) (bget :ctrl)
320
+ (and (nil? (cprop "opname")) (bget :ctrl)) (bget :ctrl)
319
321
  :else (make-control))
320
322
  meta (let [m (cprop "meta")] (if (vs/ismap m) m (or (bget :meta) (vs/jm))))
321
323
  config (let [c (cprop "config")] (if (vs/ismap c) c (bget :config)))
@@ -502,18 +504,30 @@
502
504
  out (vs/jm)]
503
505
  (doseq [item (or (vs/items reqmatch) [])]
504
506
  (let [k (vs/getprop item 0) v (vs/getprop item 1)]
505
- (when (and (some? v) (string? k) (not (contains? pset k)))
507
+ (when (and (some? v) (string? k) (not= "$action" k) (not (contains? pset k)))
506
508
  (.put ^java.util.Map out k v))))
507
509
  out))
508
510
 
511
+ ;; `$action` selects the point (see u-make-point); it is never an API field,
512
+ ;; so the body is a copy without it. The caller's map is left untouched.
513
+ (defn- strip-action [reqdata]
514
+ (if (and (vs/ismap reqdata) (.containsKey ^java.util.Map reqdata "$action"))
515
+ (let [body (vs/jm)]
516
+ (doseq [item (or (vs/items reqdata) [])]
517
+ (let [k (vs/getprop item 0) v (vs/getprop item 1)]
518
+ (when (not= "$action" k) (.put ^java.util.Map body k v))))
519
+ body)
520
+ reqdata))
521
+
509
522
  (defn u-transform-request [ctx]
510
523
  (let [spec (oget ctx :spec) point (oget ctx :point)]
511
524
  (when spec (oset! spec :step "reqform"))
512
525
  (let [transform (to-map (vs/getprop point "transform"))]
513
- (if (nil? transform) (oget ctx :reqdata)
514
- (let [reqform (vs/getprop transform "req")]
515
- (if (nil? reqform) (oget ctx :reqdata)
516
- (vs/transform (vs/jm "reqdata" (oget ctx :reqdata)) reqform)))))))
526
+ (strip-action
527
+ (if (nil? transform) (oget ctx :reqdata)
528
+ (let [reqform (vs/getprop transform "req")]
529
+ (if (nil? reqform) (oget ctx :reqdata)
530
+ (vs/transform (vs/jm "reqdata" (oget ctx :reqdata)) reqform))))))))
517
531
 
518
532
  (defn u-prepare-body [ctx]
519
533
  (if (= "data" (op-input (oget ctx :op))) (ucall ctx :transform-request) nil))
@@ -124,11 +124,13 @@
124
124
  (let [envelope (fn [data]
125
125
  (let [tm (vs/getprop (core/oget fctx :point) "transform")
126
126
  spec (vs/getprop tm "res")]
127
- ;; Exactly `body.<key>`; a deeper path is not an
128
- ;; envelope this mock can synthesise.
127
+ ;; Rebuild whatever nesting the transform unwraps;
128
+ ;; GraphQL ops unwrap `body.data.<field>`.
129
129
  (if (and (some? data) (string? spec))
130
- (if-let [m (re-matches #"`body\.([^`.]+)`" spec)]
131
- (vs/jm (second m) data)
130
+ (if-let [m (re-matches #"`body\.(.+)`" spec)]
131
+ (reduce (fn [out seg] (vs/jm seg out))
132
+ data
133
+ (reverse (str/split (second m) #"\." -1)))
132
134
  data)
133
135
  data)))
134
136
  respond (fn [status data extra]
@@ -175,14 +177,11 @@
175
177
  (let [update-match (if (zero? (vs/size update-match)) (resolve-match (vs/jm)) update-match)
176
178
  args (test-build-args fctx op update-match)
177
179
  found (vs/select entmap args)
178
- ent0 (vs/getelem found 0)
179
- ent (if (and (nil? ent0) (vs/ismap entmap) (pos? (vs/size entmap)))
180
- (first (filter vs/ismap (map #(vs/getprop entmap %) (vs/keysof entmap))))
181
- ent0)]
180
+ ent (vs/getelem found 0)]
181
+ ;; update miss: 404, never another record
182
182
  (if (nil? ent) (respond 404 nil (vs/jm "statusText" "Not found"))
183
- (do (when (and (vs/ismap ent) reqdata)
184
- (doseq [item (or (vs/items reqdata) [])]
185
- (.put ^java.util.Map ent (vs/getprop item 0) (vs/getprop item 1))))
183
+ (do (when (and (vs/ismap ent) (vs/ismap reqdata))
184
+ (vs/merge (vs/jt ent reqdata)))
186
185
  (vs/delprop ent "$KEY")
187
186
  (respond 200 (vs/clone ent) nil)))))
188
187
  (= opn "remove")
@@ -208,20 +207,47 @@
208
207
  (if (nil? net) test-fetcher (make-netsim fa net test-fetcher)))))))
209
208
  fa))
210
209
 
210
+ (defn- point-terminal? [p]
211
+ (let [parts (vs/getprop p "parts")
212
+ n (if (vs/islist parts) (vs/size parts) 0)
213
+ last-part (when (pos? n) (vs/getelem parts (dec n)))]
214
+ (and (string? last-part) (str/starts-with? last-part "{"))))
215
+
216
+ (defn- point-depth [p]
217
+ (let [parts (vs/getprop p "parts")]
218
+ (if (vs/islist parts) (vs/size parts) 0)))
219
+
220
+ ;; The entity's own endpoint: a terminal `{param}` marks a record route, and
221
+ ;; among equals the shallower path wins (the same rule as make-point).
222
+ (defn- pick-point [points]
223
+ (when (and (vs/islist points) (pos? (vs/size points)))
224
+ (reduce (fn [point cand]
225
+ (cond
226
+ (not= (point-terminal? cand) (point-terminal? point)) (if (point-terminal? cand) cand point)
227
+ (< (point-depth cand) (point-depth point)) cand
228
+ :else point))
229
+ (vs/getelem points 0)
230
+ (map #(vs/getelem points %) (range 1 (vs/size points))))))
231
+
232
+ (defn- reqd-names [point kind]
233
+ (vs/transform (vs/select (vs/getpath point (str "args." kind)) (vs/jm "reqd" true))
234
+ (vs/jt "`$EACH`" "" "`$KEY.name`")))
235
+
211
236
  (defn- test-build-args [ctx op args]
212
237
  (let [opname (core/op-name op)
213
238
  points (vs/getpath (core/oget ctx :config)
214
239
  (str "entity." (core/entity-get-name (core/oget ctx :entity)) ".op." opname ".points"))
215
- point (vs/getelem points -1)
216
- params-path (vs/getpath point "args.params")
217
- reqd-params (vs/select params-path (vs/jm "reqd" true))
218
- reqd (vs/transform reqd-params (vs/jt "`$EACH`" "" "`$KEY.name`"))
240
+ point (pick-point points)
241
+ ;; Path AND query: a path-only read misses a query-addressed record
242
+ ;; (e.g. GET /result?trace_id=), which has no path param at all.
243
+ reqd-params (reqd-names point "params")
244
+ reqd-query (reqd-names point "query")
219
245
  qand (vs/jt)]
220
246
  (when args
221
247
  (doseq [key (or (vs/keysof args) [])]
222
248
  (let [is-id (= key "id")
223
- selected (vs/select reqd key)
224
- is-reqd (not (vs/isempty selected))]
249
+ is-reqd (or (not (vs/isempty (vs/select reqd-params key)))
250
+ (not (vs/isempty (vs/select reqd-query key))))]
225
251
  (when (or is-id is-reqd)
226
252
  (let [v ((core/uget ctx :param) ctx key)
227
253
  ka (when (core/op-alias op) (vs/getprop (core/op-alias op) key))
@@ -562,7 +588,14 @@
562
588
  (cond
563
589
  (some? (mget paging "cursor")) (.put ^java.util.Map q cursor-param (mget paging "cursor"))
564
590
  (nil? (mget q page-param))
565
- (.put ^java.util.Map q page-param (if (nil? (mget paging "page")) (opt fa "startPage" 1) (mget paging "page"))))
591
+ ;; A record written back by PreResult holds the page
592
+ ;; just fetched as `page` and the one to fetch as
593
+ ;; `nextPage`, so nextPage wins.
594
+ (.put ^java.util.Map q page-param
595
+ (cond
596
+ (some? (mget paging "nextPage")) (mget paging "nextPage")
597
+ (some? (mget paging "page")) (mget paging "page")
598
+ :else (opt fa "startPage" 1))))
566
599
  (when (and (some? (opt fa "limit")) (nil? (mget q limit-param)))
567
600
  (.put ^java.util.Map q limit-param (opt fa "limit"))))))))))
568
601
  "PreResult"
@@ -607,12 +640,21 @@
607
640
  (reset! explicit-more true))))))
608
641
  (when (vs/ismap body)
609
642
  (when (some? (mget body "next")) (when (nil? (mget paging "next")) (.put ^java.util.Map paging "next" (mget body "next"))))
643
+ ;; Both spellings, camelCase last so it wins when a
644
+ ;; body carries the two.
645
+ (when (some? (mget body "next_cursor")) (.put ^java.util.Map paging "cursor" (mget body "next_cursor")))
610
646
  (when (some? (mget body "cursor")) (.put ^java.util.Map paging "cursor" (mget body "cursor")))
611
647
  (when (some? (mget body "nextCursor")) (.put ^java.util.Map paging "cursor" (mget body "nextCursor")))
612
- (let [hm (mget body "hasMore")]
613
- (when (or (= hm true) (= hm false))
614
- (.put ^java.util.Map paging "hasMore" hm)
615
- (reset! explicit-more true))))
648
+ (when (nil? (mget paging "nextPage"))
649
+ (let [np (if (some? (mget body "nextPage"))
650
+ (mget body "nextPage") (mget body "next_page"))]
651
+ (when (or (number? np) (string? np))
652
+ (.put ^java.util.Map paging "nextPage" np))))
653
+ (doseq [k ["has_more" "hasMore"]]
654
+ (let [hm (mget body k)]
655
+ (when (or (= hm true) (= hm false))
656
+ (.put ^java.util.Map paging "hasMore" hm)
657
+ (reset! explicit-more true)))))
616
658
  ;; Cursor presence only INFERS another page. When the
617
659
  ;; server stated the answer outright — relay's
618
660
  ;; `hasNextPage: false`, or a body `hasMore` — that
@@ -625,6 +667,16 @@
625
667
  (boolean (or (mget paging "hasMore") (some? (mget paging "next"))
626
668
  (some? (mget paging "cursor")) (some? (mget paging "nextPage")))))))
627
669
  (core/oset! result :paging paging)
670
+ (when-let [ctrl (core/oget ctx :ctrl)]
671
+ (let [held (core/oget ctrl :paging)]
672
+ (if (vs/ismap held)
673
+ ;; The caller holds this map, so refill it in place
674
+ ;; as the other typed ports do; a fresh map on ctrl
675
+ ;; would never reach them. Every key of the record
676
+ ;; is written, so no key of an earlier page lives on.
677
+ (doseq [k (vec (vs/keysof paging))]
678
+ (.put ^java.util.Map held k (mget paging k)))
679
+ (core/oset! ctrl :paging paging))))
628
680
  (track-set! fa "_paging" (vs/jm "last" paging)))))))
629
681
  )
630
682
  fa))
@@ -690,7 +690,7 @@ inline Context::Context(const CtxSpec& cs, const CtxPtr& basectx) {
690
690
  if (a.is_string()) ctrl->actor = a.as_string();
691
691
  Value p = getp(cs.ctrlMap, "paging");
692
692
  if (p.is_map()) ctrl->paging = p;
693
- } else if (basectx && basectx->ctrl) {
693
+ } else if (basectx && basectx->ctrl && cs.opname.empty()) {
694
694
  ctrl = basectx->ctrl;
695
695
  }
696
696
 
@@ -3,7 +3,8 @@
3
3
  // page/limit (or a cursor) into the request query; on the way back
4
4
  // (PreResult) it reads the server's pagination signals — a `Link` rel="next"
5
5
  // header, `X-Page`/`X-Next-Page`/`X-Total-Count` headers, or
6
- // `next`/`cursor`/`nextCursor`/`hasMore` body fields — onto ctx.result.paging.
6
+ // `next`/`cursor`/`nextCursor`/`hasMore` body fields (snake_case forms too)
7
+ // — onto ctx.result.paging and the caller's ctrl paging.
7
8
  // A per-call cursor/page from ctrl takes priority (auto-iteration).
8
9
 
9
10
  #ifndef SDK_FEATURE_PAGING_HPP
@@ -61,7 +62,10 @@ public:
61
62
  if (!is_nullish(cursor)) {
62
63
  map_put(spec->query, cursorParam, cursor);
63
64
  } else if (is_nullish(getp(spec->query, pageParam))) {
64
- Value page = getp(paging, "page");
65
+ // A record written back by preResult holds the page just fetched as
66
+ // "page" and the one to fetch as "nextPage", so nextPage wins.
67
+ Value page = getp(paging, "nextPage");
68
+ if (is_nullish(page)) page = getp(paging, "page");
65
69
  if (!is_nullish(page)) {
66
70
  map_put(spec->query, pageParam, page);
67
71
  } else {
@@ -171,12 +175,16 @@ public:
171
175
  }
172
176
  }
173
177
 
174
- // Body-level cursors.
178
+ // Body-level signals; snake_case forms are read first so camelCase wins.
175
179
  if (body.is_map()) {
176
180
  Value bnext = getp(body, "next");
177
181
  if (!is_nullish(bnext) && is_nullish(getp(paging, "next"))) {
178
182
  map_put(paging, "next", bnext);
179
183
  }
184
+ Value bsnakeCursor = getp(body, "next_cursor");
185
+ if (!is_nullish(bsnakeCursor)) {
186
+ map_put(paging, "cursor", bsnakeCursor);
187
+ }
180
188
  Value bcursor = getp(body, "cursor");
181
189
  if (!is_nullish(bcursor)) {
182
190
  map_put(paging, "cursor", bcursor);
@@ -185,6 +193,18 @@ public:
185
193
  if (!is_nullish(bnextCursor)) {
186
194
  map_put(paging, "cursor", bnextCursor);
187
195
  }
196
+ if (is_nullish(getp(paging, "nextPage"))) {
197
+ Value np = getp(body, "nextPage");
198
+ if (is_nullish(np)) np = getp(body, "next_page");
199
+ if (np.is_number() || np.is_string()) {
200
+ map_put(paging, "nextPage", np);
201
+ }
202
+ }
203
+ Value bsnakeMore = getp(body, "has_more");
204
+ if (bsnakeMore.is_bool()) {
205
+ map_put(paging, "hasMore", bsnakeMore);
206
+ explicitMore = true;
207
+ }
188
208
  Value bhasMore = getp(body, "hasMore");
189
209
  if (bhasMore.is_bool()) {
190
210
  map_put(paging, "hasMore", bhasMore);
@@ -205,6 +225,19 @@ public:
205
225
 
206
226
  result->paging = paging;
207
227
  last = paging;
228
+
229
+ if (ctx->ctrl) {
230
+ // Value maps are shared_ptr-backed, so the caller's map is refilled in
231
+ // place; a fresh map on ctrl never reaches the caller.
232
+ if (ctx->ctrl->paging.is_map()) {
233
+ ctx->ctrl->paging.as_map()->clear();
234
+ for (const auto& kv : *paging.as_map()) {
235
+ map_put(ctx->ctrl->paging, kv.first, kv.second);
236
+ }
237
+ } else {
238
+ ctx->ctrl->paging = paging;
239
+ }
240
+ }
208
241
  }
209
242
 
210
243
  private: