@voxgig/sdkgen 1.5.1 → 2.0.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 (270) hide show
  1. package/dist/cmp/AgentGuideContent.js +5 -0
  2. package/dist/cmp/AgentGuideContent.js.map +1 -1
  3. package/dist/cmp/Feature.js +13 -0
  4. package/dist/cmp/Feature.js.map +1 -1
  5. package/dist/helpers/canonType.d.ts +3 -1
  6. package/dist/helpers/canonType.js +44 -1
  7. package/dist/helpers/canonType.js.map +1 -1
  8. package/dist/helpers/packageMeta.js +7 -0
  9. package/dist/helpers/packageMeta.js.map +1 -1
  10. package/dist/sdkgen.d.ts +3 -3
  11. package/dist/sdkgen.js +4 -1
  12. package/dist/sdkgen.js.map +1 -1
  13. package/dist/tsconfig.tsbuildinfo +1 -1
  14. package/package.json +3 -3
  15. package/project/.sdk/model/feature/paging.aontu +7 -0
  16. package/project/.sdk/model/target/py-data.aontu +64 -0
  17. package/project/.sdk/src/cmp/c/fragment/Main.fragment.c +89 -1
  18. package/project/.sdk/src/cmp/clojure/Main_clojure.ts +1 -0
  19. package/project/.sdk/src/cmp/csharp/fragment/Main.fragment.cs +97 -0
  20. package/project/.sdk/src/cmp/dart/fragment/Main.fragment.dart +78 -0
  21. package/project/.sdk/src/cmp/elixir/fragment/Main.fragment.ex +84 -0
  22. package/project/.sdk/src/cmp/go/fragment/Main.fragment.go +87 -0
  23. package/project/.sdk/src/cmp/js/fragment/Main.fragment.js +75 -0
  24. package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +85 -0
  25. package/project/.sdk/src/cmp/ocaml/Main_ocaml.ts +4 -0
  26. package/project/.sdk/src/cmp/perl/fragment/Main.fragment.pm +80 -0
  27. package/project/.sdk/src/cmp/php/fragment/Main.fragment.php +86 -0
  28. package/project/.sdk/src/cmp/py/Entity_py.ts +9 -2
  29. package/project/.sdk/src/cmp/py/MainEntity_py.ts +1 -1
  30. package/project/.sdk/src/cmp/py/Main_py.ts +34 -6
  31. package/project/.sdk/src/cmp/py/Package_py.ts +6 -9
  32. package/project/.sdk/src/cmp/py/TestDirect_py.ts +2 -2
  33. package/project/.sdk/src/cmp/py/TestEntity_py.ts +3 -3
  34. package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +2 -2
  35. package/project/.sdk/src/cmp/py/fragment/EntityCreateOp.fragment.py +2 -2
  36. package/project/.sdk/src/cmp/py/fragment/EntityLoadOp.fragment.py +2 -2
  37. package/project/.sdk/src/cmp/py/fragment/EntityRemoveOp.fragment.py +2 -2
  38. package/project/.sdk/src/cmp/py/fragment/EntityUpdateOp.fragment.py +2 -2
  39. package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +75 -8
  40. package/project/.sdk/src/cmp/py-data/Main_py-data.ts +987 -0
  41. package/project/.sdk/src/cmp/rb/fragment/Main.fragment.rb +71 -0
  42. package/project/.sdk/src/cmp/rust/fragment/Main.fragment.rs +95 -0
  43. package/project/.sdk/src/cmp/swift/fragment/Main.fragment.swift +86 -0
  44. package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +75 -0
  45. package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +95 -0
  46. package/project/.sdk/tm/c/core/sdk.h +7 -0
  47. package/project/.sdk/tm/c/feature/paging.c +141 -2
  48. package/project/.sdk/tm/c/utility/graphql.c +178 -0
  49. package/project/.sdk/tm/c/utility/make_options.c +1 -1
  50. package/project/.sdk/tm/c/utility/make_response.c +6 -0
  51. package/project/.sdk/tm/c/utility/make_spec.c +23 -3
  52. package/project/.sdk/tm/clojure/src/sdk/client.clj +64 -1
  53. package/project/.sdk/tm/clojure/src/sdk/core.clj +126 -3
  54. package/project/.sdk/tm/clojure/src/sdk/features.clj +80 -14
  55. package/project/.sdk/tm/cpp/core/types.hpp +83 -0
  56. package/project/.sdk/tm/cpp/feature/paging.hpp +103 -1
  57. package/project/.sdk/tm/cpp/utility/pipeline.hpp +152 -3
  58. package/project/.sdk/tm/csharp/core/Utility.cs +4 -0
  59. package/project/.sdk/tm/csharp/feature/PagingFeature.cs +118 -1
  60. package/project/.sdk/tm/csharp/utility/Graphql.cs +190 -0
  61. package/project/.sdk/tm/csharp/utility/MakeOptions.cs +1 -1
  62. package/project/.sdk/tm/csharp/utility/MakeResponse.cs +7 -0
  63. package/project/.sdk/tm/csharp/utility/MakeSpec.cs +21 -2
  64. package/project/.sdk/tm/csharp/utility/Register.cs +2 -0
  65. package/project/.sdk/tm/dart/lib/Point.dart +7 -0
  66. package/project/.sdk/tm/dart/lib/feature/paging/PagingFeature.dart +99 -4
  67. package/project/.sdk/tm/dart/lib/utility/GraphqlUtility.dart +162 -0
  68. package/project/.sdk/tm/dart/lib/utility/MakeOptionsUtility.dart +1 -1
  69. package/project/.sdk/tm/dart/lib/utility/MakeResponseUtility.dart +5 -0
  70. package/project/.sdk/tm/dart/lib/utility/MakeSpecUtility.dart +18 -2
  71. package/project/.sdk/tm/dart/lib/utility/PrepareMethodUtility.dart +6 -1
  72. package/project/.sdk/tm/dart/lib/utility/Utility.dart +9 -0
  73. package/project/.sdk/tm/elixir/lib/projectname/feature/paging.ex +136 -13
  74. package/project/.sdk/tm/elixir/lib/projectname/utility.ex +187 -3
  75. package/project/.sdk/tm/go/core/utility_type.go +2 -0
  76. package/project/.sdk/tm/go/feature/paging_feature.go +87 -1
  77. package/project/.sdk/tm/go/utility/graphql.go +168 -0
  78. package/project/.sdk/tm/go/utility/make_options.go +1 -1
  79. package/project/.sdk/tm/go/utility/make_response.go +6 -0
  80. package/project/.sdk/tm/go/utility/make_spec.go +19 -2
  81. package/project/.sdk/tm/go/utility/register.go +2 -0
  82. package/project/.sdk/tm/haskell/src/SdkFeatures.hs +146 -7
  83. package/project/.sdk/tm/haskell/src/SdkRuntime.hs +153 -3
  84. package/project/.sdk/tm/java/core/SdkClient.java +93 -0
  85. package/project/.sdk/tm/java/core/Utility.java +4 -0
  86. package/project/.sdk/tm/java/feature/PagingFeature.java +100 -1
  87. package/project/.sdk/tm/java/utility/Graphql.java +191 -0
  88. package/project/.sdk/tm/java/utility/MakeOptions.java +1 -1
  89. package/project/.sdk/tm/java/utility/MakeResponse.java +6 -0
  90. package/project/.sdk/tm/java/utility/MakeSpec.java +17 -2
  91. package/project/.sdk/tm/java/utility/Register.java +2 -0
  92. package/project/.sdk/tm/js/src/Point.js +5 -0
  93. package/project/.sdk/tm/js/src/feature/paging/PagingFeature.js +82 -3
  94. package/project/.sdk/tm/js/src/feature/test/TestFeature.js +14 -2
  95. package/project/.sdk/tm/js/src/utility/GraphqlUtility.js +148 -0
  96. package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +1 -1
  97. package/project/.sdk/tm/js/src/utility/MakeResponseUtility.js +7 -0
  98. package/project/.sdk/tm/js/src/utility/MakeSpecUtility.js +19 -2
  99. package/project/.sdk/tm/js/src/utility/Utility.js +4 -0
  100. package/project/.sdk/tm/kotlin/core/SdkClient.kt +84 -0
  101. package/project/.sdk/tm/kotlin/core/Utility.kt +2 -0
  102. package/project/.sdk/tm/kotlin/feature/PagingFeature.kt +92 -1
  103. package/project/.sdk/tm/kotlin/utility/Graphql.kt +145 -0
  104. package/project/.sdk/tm/kotlin/utility/MakeOptions.kt +1 -1
  105. package/project/.sdk/tm/kotlin/utility/MakeReqRes.kt +6 -0
  106. package/project/.sdk/tm/kotlin/utility/MakeSpecUrl.kt +17 -2
  107. package/project/.sdk/tm/kotlin/utility/Register.kt +2 -0
  108. package/project/.sdk/tm/lean/src/SdkUtility.lean +134 -1
  109. package/project/.sdk/tm/lua/feature/paging_feature.lua +97 -2
  110. package/project/.sdk/tm/lua/utility/graphql.lua +163 -0
  111. package/project/.sdk/tm/lua/utility/make_options.lua +1 -1
  112. package/project/.sdk/tm/lua/utility/make_response.lua +6 -0
  113. package/project/.sdk/tm/lua/utility/make_spec.lua +18 -2
  114. package/project/.sdk/tm/lua/utility/register.lua +3 -0
  115. package/project/.sdk/tm/ocaml/sdk_features.ml +164 -20
  116. package/project/.sdk/tm/ocaml/sdk_runtime.ml +143 -4
  117. package/project/.sdk/tm/ocaml/sdk_types.ml +2 -0
  118. package/project/.sdk/tm/perl/feature/paging_feature.pm +91 -3
  119. package/project/.sdk/tm/perl/utility/graphql.pm +150 -0
  120. package/project/.sdk/tm/perl/utility/make_options.pm +1 -1
  121. package/project/.sdk/tm/perl/utility/make_response.pm +6 -0
  122. package/project/.sdk/tm/perl/utility/make_spec.pm +20 -2
  123. package/project/.sdk/tm/perl/utility/register.pm +1 -0
  124. package/project/.sdk/tm/php/core/UtilityType.php +2 -0
  125. package/project/.sdk/tm/php/feature/PagingFeature.php +106 -4
  126. package/project/.sdk/tm/php/utility/Graphql.php +176 -0
  127. package/project/.sdk/tm/php/utility/MakeOptions.php +1 -1
  128. package/project/.sdk/tm/php/utility/MakeResponse.php +7 -0
  129. package/project/.sdk/tm/php/utility/MakeSpec.php +20 -2
  130. package/project/.sdk/tm/php/utility/Register.php +3 -0
  131. package/project/.sdk/tm/py/pkg/core/__init__.py +0 -0
  132. package/project/.sdk/tm/py/{core → pkg/core}/context.py +8 -8
  133. package/project/.sdk/tm/py/{core → pkg/core}/operation.py +1 -1
  134. package/project/.sdk/tm/py/{core → pkg/core}/response.py +1 -1
  135. package/project/.sdk/tm/py/{core → pkg/core}/result.py +1 -1
  136. package/project/.sdk/tm/py/{core → pkg/core}/utility_type.py +2 -0
  137. package/project/.sdk/tm/py/pkg/entity/__init__.py +0 -0
  138. package/project/.sdk/tm/py/pkg/feature/__init__.py +0 -0
  139. package/project/.sdk/tm/py/{feature → pkg/feature}/audit_feature.py +1 -1
  140. package/project/.sdk/tm/py/{feature → pkg/feature}/cache_feature.py +1 -1
  141. package/project/.sdk/tm/py/{feature → pkg/feature}/clienttrack_feature.py +1 -1
  142. package/project/.sdk/tm/py/{feature → pkg/feature}/debug_feature.py +1 -1
  143. package/project/.sdk/tm/py/{feature → pkg/feature}/idempotency_feature.py +1 -1
  144. package/project/.sdk/tm/py/{feature → pkg/feature}/log_feature.py +1 -1
  145. package/project/.sdk/tm/py/{feature → pkg/feature}/metrics_feature.py +1 -1
  146. package/project/.sdk/tm/py/{feature → pkg/feature}/netsim_feature.py +1 -1
  147. package/project/.sdk/tm/py/{feature → pkg/feature}/paging_feature.py +87 -6
  148. package/project/.sdk/tm/py/{feature → pkg/feature}/proxy_feature.py +1 -1
  149. package/project/.sdk/tm/py/{feature → pkg/feature}/ratelimit_feature.py +1 -1
  150. package/project/.sdk/tm/py/{feature → pkg/feature}/rbac_feature.py +1 -1
  151. package/project/.sdk/tm/py/{feature → pkg/feature}/retry_feature.py +1 -1
  152. package/project/.sdk/tm/py/{feature → pkg/feature}/streaming_feature.py +1 -1
  153. package/project/.sdk/tm/py/{feature → pkg/feature}/telemetry_feature.py +1 -1
  154. package/project/.sdk/tm/py/{feature → pkg/feature}/test_feature.py +2 -2
  155. package/project/.sdk/tm/py/{feature → pkg/feature}/timeout_feature.py +1 -1
  156. package/project/.sdk/tm/py/pkg/utility/__init__.py +0 -0
  157. package/project/.sdk/tm/py/{utility → pkg/utility}/feature_init.py +1 -1
  158. package/project/.sdk/tm/py/{utility → pkg/utility}/fetcher.py +1 -1
  159. package/project/.sdk/tm/py/pkg/utility/graphql.py +145 -0
  160. package/project/.sdk/tm/py/{utility → pkg/utility}/make_context.py +1 -1
  161. package/project/.sdk/tm/py/{utility → pkg/utility}/make_error.py +5 -5
  162. package/project/.sdk/tm/py/{utility → pkg/utility}/make_fetch_def.py +2 -2
  163. package/project/.sdk/tm/py/{utility → pkg/utility}/make_options.py +2 -2
  164. package/project/.sdk/tm/py/{utility → pkg/utility}/make_point.py +2 -2
  165. package/project/.sdk/tm/py/{utility → pkg/utility}/make_request.py +2 -2
  166. package/project/.sdk/tm/py/{utility → pkg/utility}/make_response.py +6 -0
  167. package/project/.sdk/tm/py/{utility → pkg/utility}/make_spec.py +19 -4
  168. package/project/.sdk/tm/py/{utility → pkg/utility}/make_url.py +1 -1
  169. package/project/.sdk/tm/py/{utility → pkg/utility}/param.py +2 -2
  170. package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_auth.py +1 -1
  171. package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_headers.py +1 -1
  172. package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_method.py +1 -1
  173. package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_params.py +1 -1
  174. package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_path.py +1 -1
  175. package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_query.py +1 -1
  176. package/project/.sdk/tm/py/pkg/utility/register.py +71 -0
  177. package/project/.sdk/tm/py/{utility → pkg/utility}/transform_request.py +2 -2
  178. package/project/.sdk/tm/py/{utility → pkg/utility}/transform_response.py +2 -2
  179. package/project/.sdk/tm/py/test/feature_harness.py +6 -6
  180. package/project/.sdk/tm/py/test/runner.py +1 -1
  181. package/project/.sdk/tm/py/test/struct_runner.py +1 -1
  182. package/project/.sdk/tm/py/test/test_pipeline.py +5 -5
  183. package/project/.sdk/tm/py/test/test_primary_utility.py +8 -8
  184. package/project/.sdk/tm/py/test/test_struct_utility.py +3 -3
  185. package/project/.sdk/tm/py-data/LICENSE +22 -0
  186. package/project/.sdk/tm/py-data/Makefile +57 -0
  187. package/project/.sdk/tm/py-data/pkg/auth.py +131 -0
  188. package/project/.sdk/tm/py-data/pkg/fetch.py +178 -0
  189. package/project/.sdk/tm/py-data/pkg/frames.py +236 -0
  190. package/project/.sdk/tm/py-data/src/feature/README.md +8 -0
  191. package/project/.sdk/tm/py-data/src/feature/debug/.gitkeep +0 -0
  192. package/project/.sdk/tm/py-data/src/feature/idempotency/.gitkeep +0 -0
  193. package/project/.sdk/tm/py-data/src/feature/log/.gitkeep +0 -0
  194. package/project/.sdk/tm/py-data/src/feature/metrics/.gitkeep +0 -0
  195. package/project/.sdk/tm/py-data/src/feature/netsim/.gitkeep +0 -0
  196. package/project/.sdk/tm/py-data/src/feature/paging/.gitkeep +0 -0
  197. package/project/.sdk/tm/py-data/src/feature/proxy/.gitkeep +0 -0
  198. package/project/.sdk/tm/py-data/src/feature/ratelimit/.gitkeep +0 -0
  199. package/project/.sdk/tm/py-data/src/feature/rbac/.gitkeep +0 -0
  200. package/project/.sdk/tm/py-data/src/feature/retry/.gitkeep +0 -0
  201. package/project/.sdk/tm/py-data/src/feature/streaming/.gitkeep +0 -0
  202. package/project/.sdk/tm/py-data/src/feature/telemetry/.gitkeep +0 -0
  203. package/project/.sdk/tm/py-data/src/feature/test/.gitkeep +0 -0
  204. package/project/.sdk/tm/py-data/src/feature/timeout/.gitkeep +0 -0
  205. package/project/.sdk/tm/py-data/test/__init__.py +0 -0
  206. package/project/.sdk/tm/py-data/test/test_auth.py +95 -0
  207. package/project/.sdk/tm/py-data/test/test_fetch.py +152 -0
  208. package/project/.sdk/tm/py-data/test/test_frames.py +250 -0
  209. package/project/.sdk/tm/rb/core/utility_type.rb +1 -0
  210. package/project/.sdk/tm/rb/feature/paging_feature.rb +89 -3
  211. package/project/.sdk/tm/rb/utility/graphql.rb +131 -0
  212. package/project/.sdk/tm/rb/utility/make_options.rb +1 -1
  213. package/project/.sdk/tm/rb/utility/make_response.rb +6 -0
  214. package/project/.sdk/tm/rb/utility/make_spec.rb +18 -2
  215. package/project/.sdk/tm/rb/utility/register.rb +3 -0
  216. package/project/.sdk/tm/rust/feature/paging.rs +124 -2
  217. package/project/.sdk/tm/rust/utility/graphql.rs +193 -0
  218. package/project/.sdk/tm/rust/utility/make_options.rs +1 -1
  219. package/project/.sdk/tm/rust/utility/make_response.rs +6 -0
  220. package/project/.sdk/tm/rust/utility/make_spec.rs +32 -4
  221. package/project/.sdk/tm/rust/utility/mod.rs +1 -0
  222. package/project/.sdk/tm/scala/core/SdkClient.scala +90 -0
  223. package/project/.sdk/tm/scala/core/Utility.scala +4 -0
  224. package/project/.sdk/tm/scala/feature/PagingFeature.scala +104 -3
  225. package/project/.sdk/tm/scala/utility/Graphql.scala +160 -0
  226. package/project/.sdk/tm/scala/utility/Make.scala +7 -1
  227. package/project/.sdk/tm/scala/utility/MakeSpec.scala +22 -2
  228. package/project/.sdk/tm/scala/utility/Register.scala +2 -0
  229. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Utility.swift +4 -0
  230. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/PagingFeature.swift +86 -1
  231. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Graphql.swift +142 -0
  232. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Make.swift +24 -2
  233. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +1 -1
  234. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Register.swift +2 -0
  235. package/project/.sdk/tm/ts/src/Point.ts +7 -0
  236. package/project/.sdk/tm/ts/src/feature/paging/PagingFeature.ts +82 -3
  237. package/project/.sdk/tm/ts/src/feature/test/TestFeature.ts +14 -2
  238. package/project/.sdk/tm/ts/src/utility/GraphqlUtility.ts +152 -0
  239. package/project/.sdk/tm/ts/src/utility/MakeOptionsUtility.ts +1 -1
  240. package/project/.sdk/tm/ts/src/utility/MakeResponseUtility.ts +7 -0
  241. package/project/.sdk/tm/ts/src/utility/MakeSpecUtility.ts +19 -2
  242. package/project/.sdk/tm/ts/src/utility/Utility.ts +4 -0
  243. package/project/.sdk/tm/zig/core/utility.zig +198 -3
  244. package/project/.sdk/tm/zig/feature/paging.zig +128 -1
  245. package/src/cmp/AgentGuideContent.ts +5 -0
  246. package/src/cmp/Feature.ts +13 -0
  247. package/src/helpers/canonType.ts +46 -0
  248. package/src/helpers/packageMeta.ts +7 -0
  249. package/src/sdkgen.ts +6 -1
  250. package/project/.sdk/tm/py/utility/register.py +0 -68
  251. /package/project/.sdk/tm/py/{core → pkg/core}/control.py +0 -0
  252. /package/project/.sdk/tm/py/{core → pkg/core}/error.py +0 -0
  253. /package/project/.sdk/tm/py/{core → pkg/core}/helpers.py +0 -0
  254. /package/project/.sdk/tm/py/{core → pkg/core}/spec.py +0 -0
  255. /package/project/.sdk/tm/py/{feature → pkg/feature}/base_feature.py +0 -0
  256. /package/project/.sdk/tm/py/{utility → pkg/utility}/clean.py +0 -0
  257. /package/project/.sdk/tm/py/{utility → pkg/utility}/done.py +0 -0
  258. /package/project/.sdk/tm/py/{utility → pkg/utility}/feature_add.py +0 -0
  259. /package/project/.sdk/tm/py/{utility → pkg/utility}/feature_hook.py +0 -0
  260. /package/project/.sdk/tm/py/{utility → pkg/utility}/make_result.py +0 -0
  261. /package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_body.py +0 -0
  262. /package/project/.sdk/tm/py/{utility → pkg/utility}/result_basic.py +0 -0
  263. /package/project/.sdk/tm/py/{utility → pkg/utility}/result_body.py +0 -0
  264. /package/project/.sdk/tm/py/{utility → pkg/utility}/result_headers.py +0 -0
  265. /package/project/.sdk/tm/py/{utility → pkg/utility}/voxgig_struct/__init__.py +0 -0
  266. /package/project/.sdk/tm/py/{utility → pkg/utility}/voxgig_struct/voxgig_struct.py +0 -0
  267. /package/project/.sdk/tm/{py/core/__init__.py → py-data/src/feature/audit/.gitkeep} +0 -0
  268. /package/project/.sdk/tm/{py/entity/__init__.py → py-data/src/feature/base/.gitkeep} +0 -0
  269. /package/project/.sdk/tm/{py/feature/__init__.py → py-data/src/feature/cache/.gitkeep} +0 -0
  270. /package/project/.sdk/tm/{py/utility/__init__.py → py-data/src/feature/clienttrack/.gitkeep} +0 -0
@@ -10,6 +10,8 @@
10
10
 
11
11
  using System.Text.RegularExpressions;
12
12
 
13
+ using Voxgig.Struct;
14
+
13
15
  using static ProjectNameSdk.Feature.FeatureOptions;
14
16
 
15
17
  namespace ProjectNameSdk.Feature;
@@ -59,6 +61,16 @@ public class PagingFeature : BaseFeature
59
61
  // A per-call cursor/page from ctrl takes priority (auto-iteration).
60
62
  var paging = ctx.Ctrl?.Paging;
61
63
 
64
+ // GraphQL paginates through operation VARIABLES, not the query
65
+ // string. This hook runs after MakeSpec, so spec.Body already holds
66
+ // the { query, variables } envelope, and before MakeFetchDef
67
+ // serialises it.
68
+ if ("graphql" == StructUtils.GetProp(ctx.Point, "kind") as string)
69
+ {
70
+ GraphqlPreRequest(ctx, paging);
71
+ return;
72
+ }
73
+
62
74
  object? cursor = null;
63
75
  var hasCursor = paging != null && paging.TryGetValue("cursor", out cursor) && cursor != null;
64
76
  if (hasCursor)
@@ -79,6 +91,60 @@ public class PagingFeature : BaseFeature
79
91
  }
80
92
  }
81
93
 
94
+ // Relay pagination: the cursor is the `after` variable (or whatever the
95
+ // model named it), and the page size is `first`.
96
+ private void GraphqlPreRequest(Context ctx, Dictionary<string, object?>? paging)
97
+ {
98
+ if (ctx.Spec?.Body is not Dictionary<string, object?> body)
99
+ {
100
+ return;
101
+ }
102
+
103
+ if (body.TryGetValue("variables", out var vv) &&
104
+ vv is Dictionary<string, object?> existing)
105
+ {
106
+ // reuse
107
+ vv = existing;
108
+ }
109
+ else
110
+ {
111
+ vv = new Dictionary<string, object?>();
112
+ body["variables"] = vv;
113
+ }
114
+ var variables = (Dictionary<string, object?>)vv;
115
+
116
+ var afterVar = FoptStr(_options, "afterVar", "after");
117
+ var firstVar = FoptStr(_options, "firstVar", "first");
118
+
119
+ // Only bind variables the operation actually declares, or the server
120
+ // rejects the document.
121
+ var declared = new HashSet<string>();
122
+ if (StructUtils.GetPath(ctx.Point, StructUtils.Jt("graphql", "vars"))
123
+ is List<object?> varlist)
124
+ {
125
+ foreach (var v in varlist)
126
+ {
127
+ if (StructUtils.GetProp(v, "name") is string name)
128
+ {
129
+ declared.Add(name);
130
+ }
131
+ }
132
+ }
133
+
134
+ object? cursor = null;
135
+ if (paging != null && paging.TryGetValue("cursor", out cursor) &&
136
+ cursor != null && declared.Contains(afterVar))
137
+ {
138
+ variables[afterVar] = cursor;
139
+ }
140
+
141
+ if (Opt(_options, "limit") != null && declared.Contains(firstVar) &&
142
+ (!variables.TryGetValue(firstVar, out var fv) || fv == null))
143
+ {
144
+ variables[firstVar] = FoptInt(_options, "limit", 0);
145
+ }
146
+ }
147
+
82
148
  public override void PreResult(Context ctx)
83
149
  {
84
150
  if (!Active || !IsList(ctx))
@@ -113,6 +179,51 @@ public class PagingFeature : BaseFeature
113
179
  }
114
180
  }
115
181
 
182
+ // Set when the response states hasMore outright, rather than leaving
183
+ // it to be inferred from the presence of a cursor.
184
+ var explicitMore = false;
185
+
186
+ // Relay connections carry the cursor in pageInfo, at the path the
187
+ // model recorded for this op.
188
+ if (StructUtils.GetPath(ctx.Point, StructUtils.Jt("graphql", "page"))
189
+ is Dictionary<string, object?> page
190
+ && body is Dictionary<string, object?>)
191
+ {
192
+ // `connpath` locates the connection object inside the response
193
+ // envelope (data.<field>); the cursor/more paths are relative
194
+ // to it.
195
+ object? conn = body;
196
+ if (page.TryGetValue("connpath", out var cpv) &&
197
+ cpv is string connpath && "" != connpath)
198
+ {
199
+ var sub = StructUtils.GetPath(body, connpath);
200
+ if (sub != null)
201
+ {
202
+ conn = sub;
203
+ }
204
+ }
205
+
206
+ if (page.TryGetValue("cursor", out var curv) &&
207
+ curv is string cursorpath && "" != cursorpath)
208
+ {
209
+ var c = StructUtils.GetPath(conn, cursorpath);
210
+ if (c != null)
211
+ {
212
+ paging["cursor"] = c;
213
+ }
214
+ }
215
+
216
+ if (page.TryGetValue("more", out var mv) &&
217
+ mv is string morepath && "" != morepath)
218
+ {
219
+ if (StructUtils.GetPath(conn, morepath) is bool more)
220
+ {
221
+ paging["hasMore"] = more;
222
+ explicitMore = true;
223
+ }
224
+ }
225
+ }
226
+
116
227
  // Body-level cursors.
117
228
  if (body is Dictionary<string, object?> bm)
118
229
  {
@@ -132,10 +243,16 @@ public class PagingFeature : BaseFeature
132
243
  if (bm.TryGetValue("hasMore", out var hasMore) && hasMore is bool hmb)
133
244
  {
134
245
  paging["hasMore"] = hmb;
246
+ explicitMore = true;
135
247
  }
136
248
  }
137
249
 
138
- if (!Equals(paging["hasMore"], true) &&
250
+ // Cursor presence only INFERS another page. When the server stated
251
+ // the answer outright - relay's `hasNextPage: false`, or a body
252
+ // `hasMore` - that wins: a final page normally carries both an end
253
+ // cursor and hasNextPage false, and inferring from the cursor there
254
+ // would send the caller back for a page that does not exist, forever.
255
+ if (!explicitMore && !Equals(paging["hasMore"], true) &&
139
256
  ((paging.TryGetValue("next", out var n2) && n2 != null) ||
140
257
  (paging.TryGetValue("cursor", out var c2) && c2 != null) ||
141
258
  (paging.TryGetValue("nextPage", out var np2) && np2 != null)))
@@ -0,0 +1,190 @@
1
+ // ProjectName SDK utility: graphql
2
+ //
3
+ // GraphQL transport. API-INDEPENDENT: every GraphQL SDK this generator
4
+ // produces uses this file unchanged. The API-specific part — which
5
+ // operations exist and what each one's document is — is model data,
6
+ // computed once by apidef and emitted into Config.
7
+ //
8
+ // Two jobs:
9
+ //
10
+ // GraphqlBodyUtil — build { query, variables } for a point, binding the
11
+ // op's arguments to the document's declared variables.
12
+ //
13
+ // GraphqlErrorsUtil — lift a GraphQL failure into an SDK error. GraphQL
14
+ // reports failures as a top-level `errors` array under
15
+ // HTTP 200, so the status-driven path in ResultBasic
16
+ // never sees them.
17
+
18
+ using Voxgig.Struct;
19
+
20
+ namespace ProjectNameSdk.Util;
21
+
22
+ public static partial class SdkUtility
23
+ {
24
+ // Content type every GraphQL-over-HTTP request uses.
25
+ internal const string GraphqlContentType = "application/json";
26
+
27
+ // Map a GraphQL error to the same error codes the HTTP path produces,
28
+ // so a caller handles auth or rate limiting identically on both
29
+ // transports. Servers put the machine-readable code in
30
+ // `extensions.code`; Linear-style APIs use `extensions.type`.
31
+ internal static string GraphqlErrorCode(object? gqlerr)
32
+ {
33
+ var ext = StructUtils.GetProp(gqlerr, "extensions");
34
+
35
+ var code = StructUtils.GetProp(ext, "code") as string;
36
+ if (string.IsNullOrEmpty(code))
37
+ {
38
+ code = StructUtils.GetProp(ext, "type") as string;
39
+ }
40
+
41
+ var raw = (code ?? "").ToUpperInvariant();
42
+
43
+ if (raw.Contains("AUTH") || raw.Contains("FORBIDDEN")
44
+ || raw.Contains("UNAUTHENTICATED"))
45
+ {
46
+ return "request_auth";
47
+ }
48
+ if (raw.Contains("RATELIMIT") || raw.Contains("RATE_LIMIT")
49
+ || raw.Contains("TOO_MANY"))
50
+ {
51
+ return "request_ratelimit";
52
+ }
53
+ if (raw.Contains("BAD_USER_INPUT") || raw.Contains("VALIDATION")
54
+ || raw.Contains("INVALID"))
55
+ {
56
+ return "request_invalid";
57
+ }
58
+
59
+ return "request_graphql";
60
+ }
61
+
62
+ // Build the request body for a GraphQL point.
63
+ //
64
+ // Variables come from the op's own arguments: a named variable binds to
65
+ // the like-named argument (`from`), and the input-object variable
66
+ // (empty `from`) takes the request data as a whole — which is what
67
+ // makes a generated create/update call look exactly like its REST
68
+ // equivalent.
69
+ internal static object? GraphqlBodyUtil(Context ctx)
70
+ {
71
+ var gql = StructUtils.GetProp(ctx.Point, "graphql")
72
+ as Dictionary<string, object?>;
73
+ if (null == gql)
74
+ {
75
+ return null;
76
+ }
77
+
78
+ // reqmatch/reqdata hold the caller's arguments for THIS call;
79
+ // data/match hold the entity's current state. Which pair depends on
80
+ // whether the op takes match or data input. A named variable falls
81
+ // back to the current state, so updating a loaded entity with just
82
+ // {title} still binds the stored id the mutation requires.
83
+ var reqsrc = ctx.Reqmatch;
84
+ var datasrc = ctx.Match;
85
+ if (null != ctx.Op && "data" == ctx.Op.Input)
86
+ {
87
+ reqsrc = ctx.Reqdata;
88
+ datasrc = ctx.Data;
89
+ }
90
+ reqsrc ??= new Dictionary<string, object?>();
91
+ datasrc ??= new Dictionary<string, object?>();
92
+
93
+ var variables = new Dictionary<string, object?>();
94
+
95
+ var varlist = StructUtils.GetProp(gql, "vars") as List<object?>;
96
+ if (null != varlist)
97
+ {
98
+ foreach (var entry in varlist)
99
+ {
100
+ if (entry is not Dictionary<string, object?> spec)
101
+ {
102
+ continue;
103
+ }
104
+
105
+ var name = StructUtils.GetProp(spec, "name") as string;
106
+ if (null == name)
107
+ {
108
+ continue;
109
+ }
110
+
111
+ var from = StructUtils.GetProp(spec, "from") as string;
112
+
113
+ if (string.IsNullOrEmpty(from))
114
+ {
115
+ // The input object IS the request body. Strip the
116
+ // action selector, which is an SDK-side point
117
+ // discriminator, not an API field.
118
+ var body = new Dictionary<string, object?>();
119
+ foreach (var kv in reqsrc)
120
+ {
121
+ if ("$action" != kv.Key)
122
+ {
123
+ body[kv.Key] = kv.Value;
124
+ }
125
+ }
126
+ variables[name] = body;
127
+ continue;
128
+ }
129
+
130
+ // Only send variables the caller actually supplied: sending
131
+ // an explicit null would clear a field on many APIs.
132
+ var val = StructUtils.GetProp(reqsrc, from)
133
+ ?? StructUtils.GetProp(datasrc, from);
134
+ if (null != val)
135
+ {
136
+ variables[name] = val;
137
+ }
138
+ }
139
+ }
140
+
141
+ return new Dictionary<string, object?>
142
+ {
143
+ ["query"] = StructUtils.GetProp(gql, "doc"),
144
+ ["variables"] = variables,
145
+ };
146
+ }
147
+
148
+ // Inspect a decoded GraphQL response body and record a failure when the
149
+ // server reported one. Returns true when an error was recorded.
150
+ //
151
+ // Partial data (`data` alongside `errors`) is treated as failure: the
152
+ // REST surface has no partial-success concept, and silently returning
153
+ // half an object would be worse than failing.
154
+ internal static bool GraphqlErrorsUtil(Context ctx)
155
+ {
156
+ var result = ctx.Result;
157
+
158
+ if (null == result || null == ctx.Point)
159
+ {
160
+ return false;
161
+ }
162
+
163
+ if ("graphql" != StructUtils.GetProp(ctx.Point, "kind") as string)
164
+ {
165
+ return false;
166
+ }
167
+
168
+ if (StructUtils.GetProp(result.Body, "errors") is not List<object?> errors
169
+ || 0 == errors.Count)
170
+ {
171
+ return false;
172
+ }
173
+
174
+ var first = errors[0];
175
+ var msg = StructUtils.GetProp(first, "message") as string;
176
+ if (string.IsNullOrEmpty(msg))
177
+ {
178
+ msg = "graphql error";
179
+ }
180
+ if (1 < errors.Count)
181
+ {
182
+ msg = msg + " (+" + (errors.Count - 1) + " more)";
183
+ }
184
+
185
+ result.Err = ctx.MakeError(GraphqlErrorCode(first), "graphql: " + msg);
186
+ result.Ok = false;
187
+
188
+ return true;
189
+ }
190
+ }
@@ -76,7 +76,7 @@ public static partial class SdkUtility
76
76
  ["allow"] = new Dictionary<string, object?>
77
77
  {
78
78
  ["method"] = "GET,PUT,POST,PATCH,DELETE,OPTIONS",
79
- ["op"] = "create,update,load,list,remove,command,direct",
79
+ ["op"] = "create,update,load,list,remove,command,direct,graphql",
80
80
  },
81
81
  ["entity"] = new Dictionary<string, object?>
82
82
  {
@@ -38,6 +38,13 @@ public static partial class SdkUtility
38
38
  utility.ResultBasic(ctx);
39
39
  utility.ResultHeaders(ctx);
40
40
  utility.ResultBody(ctx);
41
+
42
+ // GraphQL reports failures as a top-level `errors` array under HTTP
43
+ // 200, so ResultBasic's status check never sees them. Lift them
44
+ // here, before the response transform tries to unwrap data that is
45
+ // not there.
46
+ utility.GraphqlErrors(ctx);
47
+
41
48
  utility.TransformResponse(ctx);
42
49
 
43
50
  if (result.Err == null)
@@ -48,8 +48,27 @@ public static partial class SdkUtility
48
48
  ctx.Spec.Params = utility.PrepareParams(ctx);
49
49
  ctx.Spec.Query = utility.PrepareQuery(ctx);
50
50
  ctx.Spec.Headers = utility.PrepareHeaders(ctx);
51
- ctx.Spec.Body = utility.PrepareBody(ctx);
52
- ctx.Spec.Path = utility.PreparePath(ctx);
51
+
52
+ if ("graphql" == StructUtils.GetProp(point, "kind") as string)
53
+ {
54
+ // GraphQL addresses one endpoint: no path parts, no query
55
+ // string, and the body carries the operation. PrepareBody is
56
+ // skipped deliberately — it only emits a body for data-input
57
+ // ops, whereas every GraphQL op posts one, including
58
+ // load/list/remove.
59
+ ctx.Spec.Body = utility.GraphqlBody(ctx);
60
+ ctx.Spec.Path = "";
61
+ // PrepareQuery already copied the op's match arguments into the
62
+ // query string. Those same values are bound as operation
63
+ // variables, so leaving them would send /graphql?id=i1.
64
+ ctx.Spec.Query = new Dictionary<string, object?>();
65
+ ctx.Spec.Headers["content-type"] = GraphqlContentType;
66
+ }
67
+ else
68
+ {
69
+ ctx.Spec.Body = utility.PrepareBody(ctx);
70
+ ctx.Spec.Path = utility.PreparePath(ctx);
71
+ }
53
72
 
54
73
  if (ctx.Ctrl.Explain != null)
55
74
  {
@@ -32,6 +32,8 @@ public static partial class SdkUtility
32
32
  u.PrepareParams = PrepareParamsUtil;
33
33
  u.PreparePath = PreparePathUtil;
34
34
  u.PrepareQuery = PrepareQueryUtil;
35
+ u.GraphqlBody = GraphqlBodyUtil;
36
+ u.GraphqlErrors = GraphqlErrorsUtil;
35
37
  u.ResultBasic = ResultBasicUtil;
36
38
  u.ResultBody = ResultBodyUtil;
37
39
  u.ResultHeaders = ResultHeadersUtil;
@@ -2,6 +2,11 @@ import 'utility/voxgig_struct.dart' as vs;
2
2
 
3
3
  class Point {
4
4
  dynamic args;
5
+ // Transport this point speaks: 'http' (default) or 'graphql'. GraphQL
6
+ // points carry their operation document in `graphql` and address the
7
+ // single endpoint, so method is always POST and parts is empty.
8
+ dynamic kind;
9
+ dynamic graphql;
5
10
  dynamic rename;
6
11
  dynamic method;
7
12
  dynamic orig;
@@ -15,6 +20,8 @@ class Point {
15
20
 
16
21
  Point(dynamic altmap) {
17
22
  args = vs.getprop(altmap, 'args', {'params': []});
23
+ kind = vs.getprop(altmap, 'kind', 'http');
24
+ graphql = vs.getprop(altmap, 'graphql');
18
25
  rename = vs.getprop(altmap, 'rename', {'params': {}});
19
26
  method = vs.getprop(altmap, 'method', '');
20
27
  orig = vs.getprop(altmap, 'orig', '');
@@ -1,5 +1,7 @@
1
1
  // ignore_for_file: non_constant_identifier_names
2
2
 
3
+ import '../../utility/voxgig_struct.dart' as vs;
4
+
3
5
  import '../base/BaseFeature.dart';
4
6
 
5
7
  // Pagination support for list operations. On the way out (PreRequest) it
@@ -45,6 +47,14 @@ class PagingFeature extends BaseFeature {
45
47
  // A per-call cursor/page from ctrl takes priority (used by auto-iteration).
46
48
  final paging = (ctx.ctrl is Map ? ctx.ctrl['paging'] : null) ?? {};
47
49
 
50
+ // GraphQL paginates through operation VARIABLES, not the query string.
51
+ // This hook runs after makeSpec, so spec.body already holds the
52
+ // { query, variables } envelope, and before makeFetchDef serialises it.
53
+ if ('graphql' == ctx.point?.kind) {
54
+ _graphqlPreRequest(ctx, paging);
55
+ return null;
56
+ }
57
+
48
58
  if (null != paging['cursor']) {
49
59
  spec.query[cursorParam] = paging['cursor'];
50
60
  } else if (null == spec.query[pageParam]) {
@@ -58,6 +68,46 @@ class PagingFeature extends BaseFeature {
58
68
  return null;
59
69
  }
60
70
 
71
+ // Relay pagination: the cursor is the `after` variable (or whatever the
72
+ // model named it), and the page size is `first`.
73
+ void _graphqlPreRequest(dynamic ctx, dynamic paging) {
74
+ final body = ctx.spec.body;
75
+ if (body is! Map) {
76
+ return;
77
+ }
78
+
79
+ var variables = body['variables'];
80
+ if (variables is! Map) {
81
+ variables = <String, dynamic>{};
82
+ body['variables'] = variables;
83
+ }
84
+
85
+ final afterVar = options['afterVar'] ?? 'after';
86
+ final firstVar = options['firstVar'] ?? 'first';
87
+
88
+ // Only bind variables the operation actually declares, or the server
89
+ // rejects the document.
90
+ final declared = <String>{};
91
+ final varlist = vs.getprop(ctx.point?.graphql, 'vars');
92
+ if (varlist is List) {
93
+ for (final v in varlist) {
94
+ final name = vs.getprop(v, 'name');
95
+ if (null != name) {
96
+ declared.add(name.toString());
97
+ }
98
+ }
99
+ }
100
+
101
+ if (null != paging['cursor'] && declared.contains(afterVar)) {
102
+ variables[afterVar] = paging['cursor'];
103
+ }
104
+
105
+ if (null != options['limit'] && null == variables[firstVar] &&
106
+ declared.contains(firstVar)) {
107
+ variables[firstVar] = options['limit'];
108
+ }
109
+ }
110
+
61
111
  @override
62
112
  dynamic PreResult(dynamic ctx) {
63
113
  if (!_isList(ctx)) {
@@ -90,6 +140,43 @@ class PagingFeature extends BaseFeature {
90
140
  }
91
141
  }
92
142
 
143
+ // Set when the response states hasMore outright, rather than leaving it
144
+ // to be inferred from the presence of a cursor.
145
+ var explicitMore = false;
146
+
147
+ // Relay connections carry the cursor in pageInfo, at the path the model
148
+ // recorded for this op.
149
+ final page = vs.getprop(ctx.point?.graphql, 'page');
150
+ if (page is Map && body is Map) {
151
+ // `connpath` locates the connection object inside the response
152
+ // envelope (data.<field>); the cursor/more paths are relative to it.
153
+ var conn = body;
154
+ final connpath = page['connpath'];
155
+ if (connpath is String && '' != connpath) {
156
+ final sub = vs.getpath(body, connpath);
157
+ if (sub is Map) {
158
+ conn = sub;
159
+ }
160
+ }
161
+
162
+ final cursorpath = page['cursor'];
163
+ if (cursorpath is String && '' != cursorpath) {
164
+ final cursor = vs.getpath(conn, cursorpath);
165
+ if (null != cursor) {
166
+ paging['cursor'] = cursor;
167
+ }
168
+ }
169
+
170
+ final morepath = page['more'];
171
+ if (morepath is String && '' != morepath) {
172
+ final more = vs.getpath(conn, morepath);
173
+ if (more is bool) {
174
+ paging['hasMore'] = more;
175
+ explicitMore = true;
176
+ }
177
+ }
178
+ }
179
+
93
180
  // Body-level cursors.
94
181
  if (body is Map) {
95
182
  if (null != body['next']) {
@@ -103,13 +190,21 @@ class PagingFeature extends BaseFeature {
103
190
  }
104
191
  if (body['hasMore'] is bool) {
105
192
  paging['hasMore'] = body['hasMore'];
193
+ explicitMore = true;
106
194
  }
107
195
  }
108
196
 
109
- paging['hasMore'] = true == paging['hasMore'] ||
110
- null != paging['next'] ||
111
- null != paging['cursor'] ||
112
- null != paging['nextPage'];
197
+ // Cursor presence only INFERS another page. When the server stated the
198
+ // answer outright — relay's `hasNextPage: false`, or a body `hasMore` —
199
+ // that wins: a final page normally carries both an end cursor and
200
+ // hasNextPage false, and inferring from the cursor there would send the
201
+ // caller back for a page that does not exist, forever.
202
+ if (!explicitMore) {
203
+ paging['hasMore'] = true == paging['hasMore'] ||
204
+ null != paging['next'] ||
205
+ null != paging['cursor'] ||
206
+ null != paging['nextPage'];
207
+ }
113
208
 
114
209
  result.paging = paging;
115
210