@voxgig/sdkgen 1.5.0 → 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 +7 -6
  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
@@ -139,7 +139,29 @@ static voxgig_value* err_map(const char* msg) {
139
139
  return cmap(2, "ok", v_bool(false), "err", v_str(msg));
140
140
  }
141
141
 
142
- voxgig_value* sdk_direct(ProjectNameSDK* sdk, voxgig_value* fetchargs, PNError** err) {
142
+ // Is this raw-access op permitted by the SDK's allow.op option?
143
+ static bool sdk_op_allowed(ProjectNameSDK* sdk, const char* op) {
144
+ voxgig_value* allow_op = getpath2(sdk->options, "allow", "op");
145
+ if (!voxgig_is_string(allow_op)) return false;
146
+ return NULL != strstr(voxgig_as_string(allow_op), op);
147
+ }
148
+
149
+ static voxgig_value* sdk_op_denied(ProjectNameSDK* sdk, const char* op) {
150
+ voxgig_value* allow_op = getpath2(sdk->options, "allow", "op");
151
+ const char* allow = voxgig_is_string(allow_op) ? voxgig_as_string(allow_op) : "";
152
+ char msg[512];
153
+ snprintf(msg, sizeof(msg),
154
+ "ProjectNameSDK: %s: operation not allowed by"
155
+ " SDK option allow.op value: \"%s\"", op, allow);
156
+ return err_map(msg);
157
+ }
158
+
159
+ // Ungated request path shared by sdk_direct and sdk_graphql, each of which
160
+ // checks its own allow.op token first. Static, rather than a flag on
161
+ // fetchargs: a caller-supplied marker would let anyone opt straight back out
162
+ // of the gate by passing it.
163
+ static voxgig_value* sdk_raw_request(
164
+ ProjectNameSDK* sdk, voxgig_value* fetchargs, PNError** err) {
143
165
  *err = NULL;
144
166
  Utility* utility = sdk->utility;
145
167
 
@@ -202,6 +224,72 @@ voxgig_value* sdk_direct(ProjectNameSDK* sdk, voxgig_value* fetchargs, PNError**
202
224
  return err_map("invalid response type");
203
225
  }
204
226
 
227
+ // Raw endpoint access is operator-controllable, like every entity op.
228
+ // Blocking it means denying BOTH the 'direct' and 'graphql' tokens, since
229
+ // either one reaches the same endpoint.
230
+ voxgig_value* sdk_direct(ProjectNameSDK* sdk, voxgig_value* fetchargs, PNError** err) {
231
+ *err = NULL;
232
+
233
+ if (!sdk_op_allowed(sdk, "direct")) {
234
+ return sdk_op_denied(sdk, "direct");
235
+ }
236
+
237
+ return sdk_raw_request(sdk, fetchargs, err);
238
+ }
239
+
240
+ // Raw GraphQL access: the pressure valve that makes the generated surface's
241
+ // deliberate omissions (per-call selection sets, typed filter builders,
242
+ // batching, subscriptions) livable — the whole schema stays reachable.
243
+ //
244
+ // Thin wrapper over the same prepare/fetch path sdk_direct uses, with the one
245
+ // thing raw direct cannot do for GraphQL: a GraphQL failure rides HTTP 200 as
246
+ // a top-level `errors` array, so status alone would report a failed query as
247
+ // ok.
248
+ //
249
+ // NOTE: like sdk_direct, this bypasses the feature pipeline — no retry,
250
+ // ratelimit or paging features apply.
251
+ voxgig_value* sdk_graphql(ProjectNameSDK* sdk, const char* query,
252
+ voxgig_value* variables, voxgig_value* ctrl,
253
+ PNError** err) {
254
+ *err = NULL;
255
+
256
+ if (!sdk_op_allowed(sdk, "graphql")) {
257
+ return sdk_op_denied(sdk, "graphql");
258
+ }
259
+
260
+ voxgig_value* vars = voxgig_is_map(variables) ? v_share(variables) : voxgig_new_map();
261
+ voxgig_value* ctl = voxgig_is_map(ctrl) ? v_share(ctrl) : voxgig_new_map();
262
+
263
+ voxgig_value* fetchargs = cmap(4,
264
+ "method", v_str("POST"),
265
+ "headers", cmap(1, "content-type", v_str(GRAPHQL_CONTENT_TYPE)),
266
+ "body", cmap(2, "query", v_str(query ? query : ""), "variables", vars),
267
+ "ctrl", ctl);
268
+
269
+ voxgig_value* res = sdk_raw_request(sdk, fetchargs, err);
270
+ if (*err || !voxgig_is_map(res)) return res;
271
+
272
+ // Errors are read BEFORE any status check: a GraphQL parse or validation
273
+ // failure comes back as HTTP 400 carrying the standard { errors: [...] }
274
+ // body, and the raw path represents a non-2xx as ok:false with no err — so
275
+ // returning early on status would discard the server's own diagnostics,
276
+ // which are the only useful part of that response.
277
+ voxgig_value* errors = getp(getp(res, "data"), "errors");
278
+
279
+ if (voxgig_is_list(errors) && 0 < voxgig_as_list(errors)->len) {
280
+ voxgig_value* first = voxgig_as_list(errors)->items[0];
281
+ const char* m = get_str(first, "message");
282
+ if (!m || '\0' == m[0]) m = "graphql error";
283
+ char msg[512];
284
+ snprintf(msg, sizeof(msg), "ProjectNameSDK: graphql: %s", m);
285
+ setp(res, "ok", v_bool(false));
286
+ setp(res, "err", v_str(msg));
287
+ setp(res, "graphql", v_share(errors));
288
+ }
289
+
290
+ return res;
291
+ }
292
+
205
293
  // <[SLOT]>
206
294
 
207
295
  ProjectNameSDK* test_sdk(voxgig_value* testopts, voxgig_value* sdkopts) {
@@ -69,6 +69,7 @@ const Main = cmp(async function Main(props: any) {
69
69
  (def make-sdk client/make-sdk)
70
70
  (def test-sdk client/test-sdk)
71
71
  (def direct client/direct)
72
+ (def graphql client/graphql)
72
73
  (def prepare client/prepare)
73
74
  (def options-map client/options-map)
74
75
  `)
@@ -162,7 +162,44 @@ public class ProjectNameSDK
162
162
  return utility.MakeFetchDef(ctx);
163
163
  }
164
164
 
165
+ // Raw endpoint access is operator-controllable, like every entity op.
166
+ // Blocking it means denying BOTH the 'direct' and 'graphql' tokens,
167
+ // since either one reaches the same endpoint.
165
168
  public Dictionary<string, object?> Direct(Dictionary<string, object?>? fetchargs)
169
+ {
170
+ if (!OpAllowed("direct"))
171
+ {
172
+ return OpDenied("direct");
173
+ }
174
+
175
+ return RawRequest(fetchargs);
176
+ }
177
+
178
+ // Is this raw-access op permitted by the SDK's allow.op option?
179
+ private bool OpAllowed(string op)
180
+ {
181
+ return StructUtils.GetPath(_options, StructUtils.Jt("allow", "op"))
182
+ is string allow && allow.Contains(op);
183
+ }
184
+
185
+ private Dictionary<string, object?> OpDenied(string op)
186
+ {
187
+ var allow = StructUtils.GetPath(_options, StructUtils.Jt("allow", "op"))
188
+ as string ?? "";
189
+ return new Dictionary<string, object?>
190
+ {
191
+ ["ok"] = false,
192
+ ["err"] = new Exception("ProjectNameSDK: " + op +
193
+ ": operation not allowed by SDK option allow.op value: \"" +
194
+ allow + "\""),
195
+ };
196
+ }
197
+
198
+ // Ungated request path shared by Direct and Graphql, each of which
199
+ // checks its own allow.op token first. Private, rather than a flag on
200
+ // fetchargs: a caller-supplied marker would let anyone opt straight back
201
+ // out of the gate by passing it.
202
+ private Dictionary<string, object?> RawRequest(Dictionary<string, object?>? fetchargs)
166
203
  {
167
204
  var utility = _utility;
168
205
 
@@ -254,6 +291,66 @@ public class ProjectNameSDK
254
291
  };
255
292
  }
256
293
 
294
+ // Raw GraphQL access: the pressure valve that makes the generated
295
+ // surface's deliberate omissions (per-call selection sets, typed filter
296
+ // builders, batching, subscriptions) livable — the whole schema stays
297
+ // reachable.
298
+ //
299
+ // Thin wrapper over the same prepare/fetch path Direct uses, with the
300
+ // one thing raw Direct cannot do for GraphQL: a GraphQL failure rides
301
+ // HTTP 200 as a top-level `errors` array, so status alone would report a
302
+ // failed query as ok.
303
+ //
304
+ // NOTE: like Direct, this bypasses the feature pipeline — no retry,
305
+ // ratelimit or paging features apply.
306
+ public Dictionary<string, object?> Graphql(string query,
307
+ Dictionary<string, object?>? variables = null,
308
+ Dictionary<string, object?>? ctrl = null)
309
+ {
310
+ if (!OpAllowed("graphql"))
311
+ {
312
+ return OpDenied("graphql");
313
+ }
314
+
315
+ var res = RawRequest(new Dictionary<string, object?>
316
+ {
317
+ ["method"] = "POST",
318
+ ["headers"] = new Dictionary<string, object?>
319
+ {
320
+ ["content-type"] = "application/json",
321
+ },
322
+ ["body"] = new Dictionary<string, object?>
323
+ {
324
+ ["query"] = query,
325
+ ["variables"] = variables ?? new Dictionary<string, object?>(),
326
+ },
327
+ ["ctrl"] = ctrl ?? new Dictionary<string, object?>(),
328
+ });
329
+
330
+ // Errors are read BEFORE any status check: a GraphQL parse or
331
+ // validation failure comes back as HTTP 400 carrying the standard
332
+ // { errors: [...] } body, and the raw path represents a non-2xx as
333
+ // ok:false with no err — so returning early on status would discard
334
+ // the server's own diagnostics, which are the only useful part of
335
+ // that response.
336
+ var errors = StructUtils.GetPath(res, StructUtils.Jt("data", "errors"))
337
+ as List<object?>;
338
+
339
+ if (null != errors && 0 < errors.Count)
340
+ {
341
+ var msg = StructUtils.GetProp(errors[0], "message") as string;
342
+ if (string.IsNullOrEmpty(msg))
343
+ {
344
+ msg = "graphql error";
345
+ }
346
+ res["ok"] = false;
347
+ res["err"] = new Exception("ProjectNameSDK: graphql: " + msg);
348
+ res["graphql"] = errors;
349
+ }
350
+
351
+ return res;
352
+ }
353
+
257
354
  // <[SLOT]>
258
355
 
259
356
  public static ProjectNameSDK TestSDK(Dictionary<string, object?>? testopts,
@@ -139,7 +139,37 @@ class ProjectNameSDK {
139
139
  return makeFetchDef(ctx);
140
140
  }
141
141
 
142
+ // Raw endpoint access is operator-controllable, like every entity op.
143
+ // Blocking it means denying BOTH the 'direct' and 'graphql' tokens, since
144
+ // either one reaches the same endpoint.
142
145
  Future<dynamic> direct([dynamic fetchargs]) async {
146
+ if (!_opAllowed('direct')) {
147
+ return _opDenied('direct');
148
+ }
149
+
150
+ return _rawRequest(fetchargs);
151
+ }
152
+
153
+ // Is this raw-access op permitted by the SDK's allow.op option?
154
+ bool _opAllowed(String op) {
155
+ final allow = _utility.struct.getpath(_options, 'allow.op');
156
+ return allow is String && allow.contains(op);
157
+ }
158
+
159
+ dynamic _opDenied(String op) {
160
+ final allow = _utility.struct.getpath(_options, 'allow.op');
161
+ return {
162
+ 'ok': false,
163
+ 'err': Exception('ProjectNameSDK: $op: operation not allowed by'
164
+ ' SDK option allow.op value: "${allow ?? ''}"'),
165
+ };
166
+ }
167
+
168
+ // Ungated request path shared by direct and graphql, each of which checks
169
+ // its own allow.op token first. Private, rather than a flag on fetchargs:
170
+ // a caller-supplied marker would let anyone opt straight back out of the
171
+ // gate by passing it.
172
+ Future<dynamic> _rawRequest([dynamic fetchargs]) async {
143
173
  final utility = _utility;
144
174
  final fetcher = utility.fetcher;
145
175
  final makeContext = utility.makeContext;
@@ -203,6 +233,54 @@ class ProjectNameSDK {
203
233
  }
204
234
  }
205
235
 
236
+ // Raw GraphQL access: the pressure valve that makes the generated
237
+ // surface's deliberate omissions (per-call selection sets, typed filter
238
+ // builders, batching, subscriptions) livable — the whole schema stays
239
+ // reachable.
240
+ //
241
+ // Thin wrapper over the same prepare/fetch path direct uses, with the one
242
+ // thing raw direct cannot do for GraphQL: a GraphQL failure rides HTTP 200
243
+ // as a top-level `errors` array, so status alone would report a failed
244
+ // query as ok.
245
+ //
246
+ // NOTE: like direct, this bypasses the feature pipeline — no retry,
247
+ // ratelimit or paging features apply.
248
+ Future<dynamic> graphql(String query,
249
+ [dynamic variables, dynamic ctrl]) async {
250
+ if (!_opAllowed('graphql')) {
251
+ return _opDenied('graphql');
252
+ }
253
+
254
+ final dynamic res = await _rawRequest({
255
+ 'method': 'POST',
256
+ 'headers': {'content-type': 'application/json'},
257
+ 'body': {'query': query, 'variables': variables ?? {}},
258
+ 'ctrl': ctrl ?? {},
259
+ });
260
+
261
+ if (res is! Map) {
262
+ return res;
263
+ }
264
+
265
+ // Errors are read BEFORE any status check: a GraphQL parse or validation
266
+ // failure comes back as HTTP 400 carrying the standard { errors: [...] }
267
+ // body, and the raw path represents a non-2xx as ok:false with no err —
268
+ // so returning early on status would discard the server's own
269
+ // diagnostics, which are the only useful part of that response.
270
+ final errors = _utility.struct.getpath(res, 'data.errors');
271
+
272
+ if (errors is List && 0 < errors.length) {
273
+ final first = errors[0];
274
+ final msg = (first is Map ? first['message'] : null);
275
+ res['ok'] = false;
276
+ res['err'] = Exception('ProjectNameSDK: graphql: '
277
+ '${msg is String && msg.isNotEmpty ? msg : 'graphql error'}');
278
+ res['graphql'] = errors;
279
+ }
280
+
281
+ return res;
282
+ }
283
+
206
284
  // <[SLOT]>
207
285
 
208
286
  static ProjectNameSDK test([dynamic testoptsarg, dynamic sdkoptsarg]) {
@@ -151,7 +151,41 @@ defmodule ProjectName do
151
151
  fetchdef
152
152
  end
153
153
 
154
+ # Raw endpoint access is operator-controllable, like every entity op.
155
+ # Blocking it means denying BOTH the 'direct' and 'graphql' tokens, since
156
+ # either one reaches the same endpoint.
154
157
  def direct(client, fetchargs \\ nil) do
158
+ if op_allowed?(client, "direct") do
159
+ raw_request(client, fetchargs)
160
+ else
161
+ op_denied(client, "direct")
162
+ end
163
+ end
164
+
165
+ # Is this raw-access op permitted by the SDK's allow.op option?
166
+ defp op_allowed?(client, op) do
167
+ allow = S.getpath(S.getprop(client, "options"), "allow.op")
168
+ is_binary(allow) and String.contains?(allow, op)
169
+ end
170
+
171
+ defp op_denied(client, op) do
172
+ allow = S.getpath(S.getprop(client, "options"), "allow.op")
173
+ allow = if is_binary(allow), do: allow, else: ""
174
+
175
+ S.jm([
176
+ "ok",
177
+ false,
178
+ "err",
179
+ "ProjectNameSDK: " <> op <> ": operation not allowed by" <>
180
+ " SDK option allow.op value: \"" <> allow <> "\""
181
+ ])
182
+ end
183
+
184
+ # Ungated request path shared by direct and graphql, each of which checks
185
+ # its own allow.op token first. Private, rather than a flag on fetchargs: a
186
+ # caller-supplied marker would let anyone opt straight back out of the gate
187
+ # by passing it.
188
+ defp raw_request(client, fetchargs) do
155
189
  fetchdef =
156
190
  try do
157
191
  prepare(client, fetchargs)
@@ -212,6 +246,56 @@ defmodule ProjectName do
212
246
  end
213
247
  end
214
248
 
249
+ # Raw GraphQL access: the pressure valve that makes the generated surface's
250
+ # deliberate omissions (per-call selection sets, typed filter builders,
251
+ # batching, subscriptions) livable — the whole schema stays reachable.
252
+ #
253
+ # Thin wrapper over the same prepare/fetch path direct uses, with the one
254
+ # thing raw direct cannot do for GraphQL: a GraphQL failure rides HTTP 200
255
+ # as a top-level `errors` array, so status alone would report a failed
256
+ # query as ok.
257
+ #
258
+ # NOTE: like direct, this bypasses the feature pipeline — no retry,
259
+ # ratelimit or paging features apply.
260
+ def graphql(client, query, variables \\ nil, ctrl \\ nil) do
261
+ if not op_allowed?(client, "graphql") do
262
+ op_denied(client, "graphql")
263
+ else
264
+ res =
265
+ raw_request(client, S.jm([
266
+ "method", "POST",
267
+ "headers", S.jm(["content-type", "application/json"]),
268
+ "body", S.jm([
269
+ "query", query,
270
+ "variables", if(S.ismap(variables), do: variables, else: S.jm([]))
271
+ ]),
272
+ "ctrl", if(S.ismap(ctrl), do: ctrl, else: S.jm([]))
273
+ ]))
274
+
275
+ # Errors are read BEFORE any status check: a GraphQL parse or
276
+ # validation failure comes back as HTTP 400 carrying the standard
277
+ # { errors: [...] } body, and the raw path represents a non-2xx as
278
+ # ok:false with no err — so returning early on status would discard the
279
+ # server's own diagnostics, which are the only useful part of that
280
+ # response.
281
+ errors = S.getpath(res, "data.errors")
282
+ count = if S.islist(errors), do: S.size(errors), else: 0
283
+
284
+ if count == 0 do
285
+ res
286
+ else
287
+ first = S.getelem(errors, 0)
288
+ msg = strp(S.getprop(first, "message"))
289
+ msg = if msg == "", do: "graphql error", else: msg
290
+
291
+ S.setprop(res, "ok", false)
292
+ S.setprop(res, "err", "ProjectNameSDK: graphql: " <> msg)
293
+ S.setprop(res, "graphql", errors)
294
+ res
295
+ end
296
+ end
297
+ end
298
+
215
299
  defp strp(v), do: if(is_binary(v), do: v, else: "")
216
300
 
217
301
  # <[SLOT]>
@@ -2,6 +2,7 @@ package core
2
2
 
3
3
  import (
4
4
  "fmt"
5
+ "strings"
5
6
 
6
7
  vs "github.com/voxgig/struct"
7
8
  )
@@ -174,7 +175,37 @@ func (sdk *ProjectNameSDK) Prepare(fetchargs map[string]any) (map[string]any, er
174
175
  return utility.MakeFetchDef(ctx)
175
176
  }
176
177
 
178
+ // Raw endpoint access is operator-controllable, like every entity op.
179
+ // Blocking it means denying BOTH the 'direct' and 'graphql' tokens, since
180
+ // either one reaches the same endpoint.
177
181
  func (sdk *ProjectNameSDK) Direct(fetchargs map[string]any) (map[string]any, error) {
182
+ if !sdk.opAllowed("direct") {
183
+ return sdk.opDenied("direct"), nil
184
+ }
185
+
186
+ return sdk.rawRequest(fetchargs)
187
+ }
188
+
189
+ // Is this raw-access op permitted by the SDK's allow.op option?
190
+ func (sdk *ProjectNameSDK) opAllowed(op string) bool {
191
+ allowOp, _ := vs.GetPath([]any{"allow", "op"}, sdk.options).(string)
192
+ return strings.Contains(allowOp, op)
193
+ }
194
+
195
+ func (sdk *ProjectNameSDK) opDenied(op string) map[string]any {
196
+ allowOp, _ := vs.GetPath([]any{"allow", "op"}, sdk.options).(string)
197
+ return map[string]any{
198
+ "ok": false,
199
+ "err": fmt.Errorf("ProjectNameSDK: %s: operation not allowed by"+
200
+ " SDK option allow.op value: \"%s\"", op, allowOp),
201
+ }
202
+ }
203
+
204
+ // Ungated request path shared by Direct and Graphql, each of which checks
205
+ // its own allow.op token first. Unexported, rather than a flag on fetchargs:
206
+ // a caller-supplied marker would let anyone opt straight back out of the
207
+ // gate by passing it.
208
+ func (sdk *ProjectNameSDK) rawRequest(fetchargs map[string]any) (map[string]any, error) {
178
209
  utility := sdk.utility
179
210
 
180
211
  fetchdef, err := sdk.Prepare(fetchargs)
@@ -250,6 +281,62 @@ func (sdk *ProjectNameSDK) Direct(fetchargs map[string]any) (map[string]any, err
250
281
  return map[string]any{"ok": false, "err": ctx.MakeError("direct_invalid", "invalid response type")}, nil
251
282
  }
252
283
 
284
+ // Raw GraphQL access: the pressure valve that makes the generated surface's
285
+ // deliberate omissions (per-call selection sets, typed filter builders,
286
+ // batching, subscriptions) livable — the whole schema stays reachable.
287
+ //
288
+ // Thin wrapper over the same prepare/fetch path Direct uses, with the one
289
+ // thing raw Direct cannot do for GraphQL: a GraphQL failure rides HTTP 200
290
+ // as a top-level `errors` array, so status alone would report a failed query
291
+ // as ok.
292
+ //
293
+ // NOTE: like Direct, this bypasses the feature pipeline — no retry,
294
+ // ratelimit or paging features apply.
295
+ func (sdk *ProjectNameSDK) Graphql(
296
+ query string, variables map[string]any, ctrl map[string]any,
297
+ ) (map[string]any, error) {
298
+ if !sdk.opAllowed("graphql") {
299
+ return sdk.opDenied("graphql"), nil
300
+ }
301
+
302
+ if variables == nil {
303
+ variables = map[string]any{}
304
+ }
305
+ if ctrl == nil {
306
+ ctrl = map[string]any{}
307
+ }
308
+
309
+ res, err := sdk.rawRequest(map[string]any{
310
+ "method": "POST",
311
+ "headers": map[string]any{"content-type": "application/json"},
312
+ "body": map[string]any{"query": query, "variables": variables},
313
+ "ctrl": ctrl,
314
+ })
315
+
316
+ if err != nil {
317
+ return res, err
318
+ }
319
+
320
+ // Errors are read BEFORE any status check: a GraphQL parse or validation
321
+ // failure comes back as HTTP 400 carrying the standard { errors: [...] }
322
+ // body, and the raw path represents a non-2xx as ok:false with no err —
323
+ // so returning early on status would discard the server's own
324
+ // diagnostics, which are the only useful part of that response.
325
+ errors, _ := vs.GetPath([]any{"data", "errors"}, res).([]any)
326
+
327
+ if 0 < len(errors) {
328
+ msg, _ := vs.GetProp(errors[0], "message").(string)
329
+ if msg == "" {
330
+ msg = "graphql error"
331
+ }
332
+ res["ok"] = false
333
+ res["err"] = fmt.Errorf("ProjectNameSDK: graphql: %s", msg)
334
+ res["graphql"] = errors
335
+ }
336
+
337
+ return res, nil
338
+ }
339
+
253
340
  // <[SLOT]>
254
341
 
255
342
  func TestSDK(testopts map[string]any, sdkopts map[string]any) *ProjectNameSDK {
@@ -138,8 +138,29 @@ class ProjectNameSDK {
138
138
  }
139
139
 
140
140
 
141
+ // Raw endpoint access is operator-controllable, like every entity op.
142
+ // Blocking it means denying BOTH the 'direct' and 'graphql' tokens, since
143
+ // either one reaches the same endpoint.
141
144
  async direct(fetchargs) {
145
+ if (!this._options.allow.op.includes('direct')) {
146
+ return {
147
+ ok: false,
148
+ err: new Error('ProjectNameSDK: direct: operation not allowed by' +
149
+ ' SDK option allow.op value: "' + this._options.allow.op + '"'),
150
+ }
151
+ }
152
+
153
+ return this._rawRequest(fetchargs)
154
+ }
155
+
156
+
157
+ // Ungated request path shared by direct() and graphql(), each of which
158
+ // checks its own allow.op token first. Private, rather than a flag on
159
+ // fetchargs: a caller-supplied marker would let anyone opt straight back
160
+ // out of the gate by passing it.
161
+ async _rawRequest(fetchargs) {
142
162
  const utility = this._utility
163
+
143
164
  const fetcher = utility.fetcher
144
165
  const makeContext = utility.makeContext
145
166
 
@@ -179,6 +200,60 @@ class ProjectNameSDK {
179
200
  }
180
201
 
181
202
 
203
+
204
+ // Raw GraphQL access: the pressure valve that makes the generated
205
+ // surface's deliberate omissions (per-call selection sets, typed filter
206
+ // builders, batching, subscriptions) livable — the whole schema stays
207
+ // reachable.
208
+ //
209
+ // Thin wrapper over the same prepare/fetch path `direct` uses, with the
210
+ // one thing raw `direct` cannot do for GraphQL: a GraphQL failure rides
211
+ // HTTP 200 as a top-level `errors` array, so status alone would report a
212
+ // failed query as ok.
213
+ //
214
+ // NOTE: like `direct`, this bypasses the feature pipeline — no retry,
215
+ // ratelimit or paging features apply.
216
+ async graphql(query, variables, ctrl) {
217
+ const options = this._options
218
+
219
+ if (!options.allow.op.includes('graphql')) {
220
+ return {
221
+ ok: false,
222
+ err: new Error('ProjectNameSDK: graphql: operation not allowed by' +
223
+ ' SDK option allow.op value: "' + options.allow.op + '"'),
224
+ }
225
+ }
226
+
227
+ const res = await this._rawRequest({
228
+ method: 'POST',
229
+ headers: { 'content-type': 'application/json' },
230
+ body: { query, variables: variables || {} },
231
+ ctrl,
232
+ })
233
+
234
+ if (res instanceof Error) {
235
+ return res
236
+ }
237
+
238
+ // Errors are read BEFORE any status check: a GraphQL parse or validation
239
+ // failure comes back as HTTP 400 carrying the standard { errors: [...] }
240
+ // body, and the raw path represents a non-2xx as { ok: false } with no
241
+ // err — so returning early on status would discard the server's own
242
+ // diagnostics, which are the only useful part of that response.
243
+ const errors = null == res.data ? undefined : res.data.errors
244
+
245
+ if (null != errors && Array.isArray(errors) && 0 < errors.length) {
246
+ const first = errors[0] || {}
247
+ const err = new Error('ProjectNameSDK: graphql: ' +
248
+ (first.message || 'graphql error'))
249
+ err.graphql = errors
250
+ return { ok: false, status: res.status, headers: res.headers, err, data: res.data }
251
+ }
252
+
253
+ return res
254
+ }
255
+
256
+
182
257
  // <[SLOT]>
183
258
 
184
259