@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.
- package/dist/cmp/AgentGuideContent.js +5 -0
- package/dist/cmp/AgentGuideContent.js.map +1 -1
- package/dist/cmp/Feature.js +13 -0
- package/dist/cmp/Feature.js.map +1 -1
- package/dist/helpers/canonType.d.ts +3 -1
- package/dist/helpers/canonType.js +44 -1
- package/dist/helpers/canonType.js.map +1 -1
- package/dist/helpers/packageMeta.js +7 -0
- package/dist/helpers/packageMeta.js.map +1 -1
- package/dist/sdkgen.d.ts +3 -3
- package/dist/sdkgen.js +4 -1
- package/dist/sdkgen.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +7 -6
- package/project/.sdk/model/feature/paging.aontu +7 -0
- package/project/.sdk/model/target/py-data.aontu +64 -0
- package/project/.sdk/src/cmp/c/fragment/Main.fragment.c +89 -1
- package/project/.sdk/src/cmp/clojure/Main_clojure.ts +1 -0
- package/project/.sdk/src/cmp/csharp/fragment/Main.fragment.cs +97 -0
- package/project/.sdk/src/cmp/dart/fragment/Main.fragment.dart +78 -0
- package/project/.sdk/src/cmp/elixir/fragment/Main.fragment.ex +84 -0
- package/project/.sdk/src/cmp/go/fragment/Main.fragment.go +87 -0
- package/project/.sdk/src/cmp/js/fragment/Main.fragment.js +75 -0
- package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +85 -0
- package/project/.sdk/src/cmp/ocaml/Main_ocaml.ts +4 -0
- package/project/.sdk/src/cmp/perl/fragment/Main.fragment.pm +80 -0
- package/project/.sdk/src/cmp/php/fragment/Main.fragment.php +86 -0
- package/project/.sdk/src/cmp/py/Entity_py.ts +9 -2
- package/project/.sdk/src/cmp/py/MainEntity_py.ts +1 -1
- package/project/.sdk/src/cmp/py/Main_py.ts +34 -6
- package/project/.sdk/src/cmp/py/Package_py.ts +6 -9
- package/project/.sdk/src/cmp/py/TestDirect_py.ts +2 -2
- package/project/.sdk/src/cmp/py/TestEntity_py.ts +3 -3
- package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +2 -2
- package/project/.sdk/src/cmp/py/fragment/EntityCreateOp.fragment.py +2 -2
- package/project/.sdk/src/cmp/py/fragment/EntityLoadOp.fragment.py +2 -2
- package/project/.sdk/src/cmp/py/fragment/EntityRemoveOp.fragment.py +2 -2
- package/project/.sdk/src/cmp/py/fragment/EntityUpdateOp.fragment.py +2 -2
- package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +75 -8
- package/project/.sdk/src/cmp/py-data/Main_py-data.ts +987 -0
- package/project/.sdk/src/cmp/rb/fragment/Main.fragment.rb +71 -0
- package/project/.sdk/src/cmp/rust/fragment/Main.fragment.rs +95 -0
- package/project/.sdk/src/cmp/swift/fragment/Main.fragment.swift +86 -0
- package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +75 -0
- package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +95 -0
- package/project/.sdk/tm/c/core/sdk.h +7 -0
- package/project/.sdk/tm/c/feature/paging.c +141 -2
- package/project/.sdk/tm/c/utility/graphql.c +178 -0
- package/project/.sdk/tm/c/utility/make_options.c +1 -1
- package/project/.sdk/tm/c/utility/make_response.c +6 -0
- package/project/.sdk/tm/c/utility/make_spec.c +23 -3
- package/project/.sdk/tm/clojure/src/sdk/client.clj +64 -1
- package/project/.sdk/tm/clojure/src/sdk/core.clj +126 -3
- package/project/.sdk/tm/clojure/src/sdk/features.clj +80 -14
- package/project/.sdk/tm/cpp/core/types.hpp +83 -0
- package/project/.sdk/tm/cpp/feature/paging.hpp +103 -1
- package/project/.sdk/tm/cpp/utility/pipeline.hpp +152 -3
- package/project/.sdk/tm/csharp/core/Utility.cs +4 -0
- package/project/.sdk/tm/csharp/feature/PagingFeature.cs +118 -1
- package/project/.sdk/tm/csharp/utility/Graphql.cs +190 -0
- package/project/.sdk/tm/csharp/utility/MakeOptions.cs +1 -1
- package/project/.sdk/tm/csharp/utility/MakeResponse.cs +7 -0
- package/project/.sdk/tm/csharp/utility/MakeSpec.cs +21 -2
- package/project/.sdk/tm/csharp/utility/Register.cs +2 -0
- package/project/.sdk/tm/dart/lib/Point.dart +7 -0
- package/project/.sdk/tm/dart/lib/feature/paging/PagingFeature.dart +99 -4
- package/project/.sdk/tm/dart/lib/utility/GraphqlUtility.dart +162 -0
- package/project/.sdk/tm/dart/lib/utility/MakeOptionsUtility.dart +1 -1
- package/project/.sdk/tm/dart/lib/utility/MakeResponseUtility.dart +5 -0
- package/project/.sdk/tm/dart/lib/utility/MakeSpecUtility.dart +18 -2
- package/project/.sdk/tm/dart/lib/utility/PrepareMethodUtility.dart +6 -1
- package/project/.sdk/tm/dart/lib/utility/Utility.dart +9 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/paging.ex +136 -13
- package/project/.sdk/tm/elixir/lib/projectname/utility.ex +187 -3
- package/project/.sdk/tm/go/core/utility_type.go +2 -0
- package/project/.sdk/tm/go/feature/paging_feature.go +87 -1
- package/project/.sdk/tm/go/utility/graphql.go +168 -0
- package/project/.sdk/tm/go/utility/make_options.go +1 -1
- package/project/.sdk/tm/go/utility/make_response.go +6 -0
- package/project/.sdk/tm/go/utility/make_spec.go +19 -2
- package/project/.sdk/tm/go/utility/register.go +2 -0
- package/project/.sdk/tm/haskell/src/SdkFeatures.hs +146 -7
- package/project/.sdk/tm/haskell/src/SdkRuntime.hs +153 -3
- package/project/.sdk/tm/java/core/SdkClient.java +93 -0
- package/project/.sdk/tm/java/core/Utility.java +4 -0
- package/project/.sdk/tm/java/feature/PagingFeature.java +100 -1
- package/project/.sdk/tm/java/utility/Graphql.java +191 -0
- package/project/.sdk/tm/java/utility/MakeOptions.java +1 -1
- package/project/.sdk/tm/java/utility/MakeResponse.java +6 -0
- package/project/.sdk/tm/java/utility/MakeSpec.java +17 -2
- package/project/.sdk/tm/java/utility/Register.java +2 -0
- package/project/.sdk/tm/js/src/Point.js +5 -0
- package/project/.sdk/tm/js/src/feature/paging/PagingFeature.js +82 -3
- package/project/.sdk/tm/js/src/feature/test/TestFeature.js +14 -2
- package/project/.sdk/tm/js/src/utility/GraphqlUtility.js +148 -0
- package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +1 -1
- package/project/.sdk/tm/js/src/utility/MakeResponseUtility.js +7 -0
- package/project/.sdk/tm/js/src/utility/MakeSpecUtility.js +19 -2
- package/project/.sdk/tm/js/src/utility/Utility.js +4 -0
- package/project/.sdk/tm/kotlin/core/SdkClient.kt +84 -0
- package/project/.sdk/tm/kotlin/core/Utility.kt +2 -0
- package/project/.sdk/tm/kotlin/feature/PagingFeature.kt +92 -1
- package/project/.sdk/tm/kotlin/utility/Graphql.kt +145 -0
- package/project/.sdk/tm/kotlin/utility/MakeOptions.kt +1 -1
- package/project/.sdk/tm/kotlin/utility/MakeReqRes.kt +6 -0
- package/project/.sdk/tm/kotlin/utility/MakeSpecUrl.kt +17 -2
- package/project/.sdk/tm/kotlin/utility/Register.kt +2 -0
- package/project/.sdk/tm/lean/src/SdkUtility.lean +134 -1
- package/project/.sdk/tm/lua/feature/paging_feature.lua +97 -2
- package/project/.sdk/tm/lua/utility/graphql.lua +163 -0
- package/project/.sdk/tm/lua/utility/make_options.lua +1 -1
- package/project/.sdk/tm/lua/utility/make_response.lua +6 -0
- package/project/.sdk/tm/lua/utility/make_spec.lua +18 -2
- package/project/.sdk/tm/lua/utility/register.lua +3 -0
- package/project/.sdk/tm/ocaml/sdk_features.ml +164 -20
- package/project/.sdk/tm/ocaml/sdk_runtime.ml +143 -4
- package/project/.sdk/tm/ocaml/sdk_types.ml +2 -0
- package/project/.sdk/tm/perl/feature/paging_feature.pm +91 -3
- package/project/.sdk/tm/perl/utility/graphql.pm +150 -0
- package/project/.sdk/tm/perl/utility/make_options.pm +1 -1
- package/project/.sdk/tm/perl/utility/make_response.pm +6 -0
- package/project/.sdk/tm/perl/utility/make_spec.pm +20 -2
- package/project/.sdk/tm/perl/utility/register.pm +1 -0
- package/project/.sdk/tm/php/core/UtilityType.php +2 -0
- package/project/.sdk/tm/php/feature/PagingFeature.php +106 -4
- package/project/.sdk/tm/php/utility/Graphql.php +176 -0
- package/project/.sdk/tm/php/utility/MakeOptions.php +1 -1
- package/project/.sdk/tm/php/utility/MakeResponse.php +7 -0
- package/project/.sdk/tm/php/utility/MakeSpec.php +20 -2
- package/project/.sdk/tm/php/utility/Register.php +3 -0
- package/project/.sdk/tm/py/pkg/core/__init__.py +0 -0
- package/project/.sdk/tm/py/{core → pkg/core}/context.py +8 -8
- package/project/.sdk/tm/py/{core → pkg/core}/operation.py +1 -1
- package/project/.sdk/tm/py/{core → pkg/core}/response.py +1 -1
- package/project/.sdk/tm/py/{core → pkg/core}/result.py +1 -1
- package/project/.sdk/tm/py/{core → pkg/core}/utility_type.py +2 -0
- package/project/.sdk/tm/py/pkg/entity/__init__.py +0 -0
- package/project/.sdk/tm/py/pkg/feature/__init__.py +0 -0
- package/project/.sdk/tm/py/{feature → pkg/feature}/audit_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/cache_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/clienttrack_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/debug_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/idempotency_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/log_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/metrics_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/netsim_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/paging_feature.py +87 -6
- package/project/.sdk/tm/py/{feature → pkg/feature}/proxy_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/ratelimit_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/rbac_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/retry_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/streaming_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/telemetry_feature.py +1 -1
- package/project/.sdk/tm/py/{feature → pkg/feature}/test_feature.py +2 -2
- package/project/.sdk/tm/py/{feature → pkg/feature}/timeout_feature.py +1 -1
- package/project/.sdk/tm/py/pkg/utility/__init__.py +0 -0
- package/project/.sdk/tm/py/{utility → pkg/utility}/feature_init.py +1 -1
- package/project/.sdk/tm/py/{utility → pkg/utility}/fetcher.py +1 -1
- package/project/.sdk/tm/py/pkg/utility/graphql.py +145 -0
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_context.py +1 -1
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_error.py +5 -5
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_fetch_def.py +2 -2
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_options.py +2 -2
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_point.py +2 -2
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_request.py +2 -2
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_response.py +6 -0
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_spec.py +19 -4
- package/project/.sdk/tm/py/{utility → pkg/utility}/make_url.py +1 -1
- package/project/.sdk/tm/py/{utility → pkg/utility}/param.py +2 -2
- package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_auth.py +1 -1
- package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_headers.py +1 -1
- package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_method.py +1 -1
- package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_params.py +1 -1
- package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_path.py +1 -1
- package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_query.py +1 -1
- package/project/.sdk/tm/py/pkg/utility/register.py +71 -0
- package/project/.sdk/tm/py/{utility → pkg/utility}/transform_request.py +2 -2
- package/project/.sdk/tm/py/{utility → pkg/utility}/transform_response.py +2 -2
- package/project/.sdk/tm/py/test/feature_harness.py +6 -6
- package/project/.sdk/tm/py/test/runner.py +1 -1
- package/project/.sdk/tm/py/test/struct_runner.py +1 -1
- package/project/.sdk/tm/py/test/test_pipeline.py +5 -5
- package/project/.sdk/tm/py/test/test_primary_utility.py +8 -8
- package/project/.sdk/tm/py/test/test_struct_utility.py +3 -3
- package/project/.sdk/tm/py-data/LICENSE +22 -0
- package/project/.sdk/tm/py-data/Makefile +57 -0
- package/project/.sdk/tm/py-data/pkg/auth.py +131 -0
- package/project/.sdk/tm/py-data/pkg/fetch.py +178 -0
- package/project/.sdk/tm/py-data/pkg/frames.py +236 -0
- package/project/.sdk/tm/py-data/src/feature/README.md +8 -0
- package/project/.sdk/tm/py-data/src/feature/debug/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/idempotency/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/log/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/metrics/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/netsim/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/paging/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/proxy/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/ratelimit/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/rbac/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/retry/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/streaming/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/telemetry/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/test/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/src/feature/timeout/.gitkeep +0 -0
- package/project/.sdk/tm/py-data/test/__init__.py +0 -0
- package/project/.sdk/tm/py-data/test/test_auth.py +95 -0
- package/project/.sdk/tm/py-data/test/test_fetch.py +152 -0
- package/project/.sdk/tm/py-data/test/test_frames.py +250 -0
- package/project/.sdk/tm/rb/core/utility_type.rb +1 -0
- package/project/.sdk/tm/rb/feature/paging_feature.rb +89 -3
- package/project/.sdk/tm/rb/utility/graphql.rb +131 -0
- package/project/.sdk/tm/rb/utility/make_options.rb +1 -1
- package/project/.sdk/tm/rb/utility/make_response.rb +6 -0
- package/project/.sdk/tm/rb/utility/make_spec.rb +18 -2
- package/project/.sdk/tm/rb/utility/register.rb +3 -0
- package/project/.sdk/tm/rust/feature/paging.rs +124 -2
- package/project/.sdk/tm/rust/utility/graphql.rs +193 -0
- package/project/.sdk/tm/rust/utility/make_options.rs +1 -1
- package/project/.sdk/tm/rust/utility/make_response.rs +6 -0
- package/project/.sdk/tm/rust/utility/make_spec.rs +32 -4
- package/project/.sdk/tm/rust/utility/mod.rs +1 -0
- package/project/.sdk/tm/scala/core/SdkClient.scala +90 -0
- package/project/.sdk/tm/scala/core/Utility.scala +4 -0
- package/project/.sdk/tm/scala/feature/PagingFeature.scala +104 -3
- package/project/.sdk/tm/scala/utility/Graphql.scala +160 -0
- package/project/.sdk/tm/scala/utility/Make.scala +7 -1
- package/project/.sdk/tm/scala/utility/MakeSpec.scala +22 -2
- package/project/.sdk/tm/scala/utility/Register.scala +2 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Utility.swift +4 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/PagingFeature.swift +86 -1
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Graphql.swift +142 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Make.swift +24 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +1 -1
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Register.swift +2 -0
- package/project/.sdk/tm/ts/src/Point.ts +7 -0
- package/project/.sdk/tm/ts/src/feature/paging/PagingFeature.ts +82 -3
- package/project/.sdk/tm/ts/src/feature/test/TestFeature.ts +14 -2
- package/project/.sdk/tm/ts/src/utility/GraphqlUtility.ts +152 -0
- package/project/.sdk/tm/ts/src/utility/MakeOptionsUtility.ts +1 -1
- package/project/.sdk/tm/ts/src/utility/MakeResponseUtility.ts +7 -0
- package/project/.sdk/tm/ts/src/utility/MakeSpecUtility.ts +19 -2
- package/project/.sdk/tm/ts/src/utility/Utility.ts +4 -0
- package/project/.sdk/tm/zig/core/utility.zig +198 -3
- package/project/.sdk/tm/zig/feature/paging.zig +128 -1
- package/src/cmp/AgentGuideContent.ts +5 -0
- package/src/cmp/Feature.ts +13 -0
- package/src/helpers/canonType.ts +46 -0
- package/src/helpers/packageMeta.ts +7 -0
- package/src/sdkgen.ts +6 -1
- package/project/.sdk/tm/py/utility/register.py +0 -68
- /package/project/.sdk/tm/py/{core → pkg/core}/control.py +0 -0
- /package/project/.sdk/tm/py/{core → pkg/core}/error.py +0 -0
- /package/project/.sdk/tm/py/{core → pkg/core}/helpers.py +0 -0
- /package/project/.sdk/tm/py/{core → pkg/core}/spec.py +0 -0
- /package/project/.sdk/tm/py/{feature → pkg/feature}/base_feature.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/clean.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/done.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/feature_add.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/feature_hook.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/make_result.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/prepare_body.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/result_basic.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/result_body.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/result_headers.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/voxgig_struct/__init__.py +0 -0
- /package/project/.sdk/tm/py/{utility → pkg/utility}/voxgig_struct/voxgig_struct.py +0 -0
- /package/project/.sdk/tm/{py/core/__init__.py → py-data/src/feature/audit/.gitkeep} +0 -0
- /package/project/.sdk/tm/{py/entity/__init__.py → py-data/src/feature/base/.gitkeep} +0 -0
- /package/project/.sdk/tm/{py/feature/__init__.py → py-data/src/feature/cache/.gitkeep} +0 -0
- /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
|
-
|
|
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) {
|
|
@@ -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
|
|