fix: keep GraphQL variables in the documented JS SDK call - #1897
fix: keep GraphQL variables in the documented JS SDK call#1897HarshMN2345 wants to merge 2 commits into
Conversation
graphql.query({ query: '...', variables }) matched the params-object
overload because the GraphQL request object also has a `query` key, so
the SDK sent only the query string and dropped `variables`. When a
method's only parameter is a free-form object, a string under its own
name now selects the positional form.
|
| if (count($params) === 1 && $firstParamType === 'object') { | ||
| $operands[] = 'typeof paramsOrFirst.' . $this->escapeKeyword($this->toCamelCase($params[0]->name)) . " !== 'string'"; | ||
| } |
There was a problem hiding this comment.
This subtle overload-dispatch fix affects every SDK inheriting Web behavior, but no automated test exercises a lone free-form object through the documented GraphQL call or verifies that variables reaches the request body. Add a runtime behavior test using the generated SDK and a recording or mock client. An assertion against the emitted condition would only mirror the implementation and would not protect the actual request contract.
Knowledge Base Used: Generation quality assurance
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/SDK/Language/Web.php
Line: 1076-1078
Comment:
**Missing behavior coverage**
This subtle overload-dispatch fix affects every SDK inheriting Web behavior, but no automated test exercises a lone free-form object through the documented GraphQL call or verifies that `variables` reaches the request body. Add a runtime behavior test using the generated SDK and a recording or mock client. An assertion against the emitted condition would only mirror the implementation and would not protect the actual request contract.
**Knowledge Base Used:** [Generation quality assurance](https://app.greptile.com/appwrite/-/custom-context/knowledge-base/appwrite/sdk-generator/-/docs/generation-quality-assurance.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Adds a general.createQuery fixture whose only parameter is a free-form
`query` object, called from the node, web and react-native e2e scripts
with the graphql.query({ query, variables }) shape and the params form.
The mock echoes the received object, so a flattened string or dropped
`variables` fails the run.
What does this PR do?
The JS SDKs (web, node, react-native) drop
variablesfrom the GraphQL call shown in the Appwrite docs.graphql.queryandgraphql.mutationtake a single free-formobjectparameter namedquery. The params-object overload is selected when'query' in paramsOrFirst, and a GraphQL request object has aquerykey as well, so the documented call is read as the params form:Before:
{"query":"mutation CreateAccount($email: String!) { ... }"}After:
{"query":{"query":"mutation CreateAccount($email: String!) { ... }","variables":{"email":"..."}}}Current Appwrite servers answer the flat body with HTTP 500 (appwrite/appwrite#13605 turns it into a 400), so every documented GraphQL call fails with the current SDKs.
When a method's only parameter is a free-form
object,getOverloadConditionnow addstypeof paramsOrFirst.<name> !== 'string'. Generated from the Appwrite 2.0.x spec, this operand ingraphql.queryandgraphql.mutationis the only change in web, node and react-native:'query' in paramsOrFirst && + typeof paramsOrFirst.query !== 'string'The params form (
{ query: { query, variables } },{ query: [...] }), positional batches,{ query: null }and theMissing required parameterthrow for{ query: undefined }behave as before. The documented shape resolves to the positional overload, which stays marked@deprecated.Test Plan
open-api3-2.0.x.jsonbefore and after the change: onlysrc/services/graphql.tsdiffers.npm run format:check,lint,analyseandbuildpass for all three;npm run testpasses for node (832 tests).graphql.tsbefore and after with a recording client and replayed the web payloads against an Appwrite server: the documented mutation reaches the resolver with its variables, and the documented query returns data instead of HTTP 500.vendor/bin/phpunit --testsuite Generation,phpcsandrector --dry-runpass.general.createQueryfixture takes a lone free-formqueryobject; the node, web and react-native scripts call it with{ query, variables }and{ query: { query } }, and the mock echoes what it received. Node20 and WebNode pass; withWeb.phpreverted, Node20 fails withInvalid `query` param: Value must be a valid object.