Skip to content

Commit a169969

Browse files
authored
fix: no GET on mutations (#663)
1 parent 8f926b8 commit a169969

10 files changed

+203
-104
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
"happy-dom": "^13.3.1",
9292
"json-bigint": "^1.0.0",
9393
"prettier": "^3.2.4",
94+
"tsx": "^4.7.0",
9495
"type-fest": "^4.10.1",
9596
"typescript": "^5.3.3",
9697
"vitest": "^1.2.1",

pnpm-lock.yaml

+24
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/classes/GraphQLClient.ts

+11-10
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { BatchRequestDocument, BatchRequestsOptions, BatchResult } from '..
22
import { parseBatchRequestArgs } from '../functions/batchRequests.js'
33
import { parseRawRequestArgs } from '../functions/rawRequest.js'
44
import { parseRequestArgs } from '../functions/request.js'
5-
import { resolveRequestDocument } from '../helpers/resolveRequestDocument.js'
5+
import { analyzeDocument } from '../helpers/analyzeDocument.js'
66
import { runRequest } from '../helpers/runRequest.js'
77
import type { RequestDocument, RequestOptions, VariablesAndRequestHeadersArgs } from '../helpers/types.js'
88
import {
@@ -45,14 +45,13 @@ export class GraphQLClient {
4545
fetchOptions.signal = rawRequestOptions.signal
4646
}
4747

48-
const { operationName } = resolveRequestDocument(rawRequestOptions.query, excludeOperationName)
48+
const document = analyzeDocument(rawRequestOptions.query, excludeOperationName)
4949

5050
const response = await runRequest({
5151
url,
5252
request: {
5353
_tag: `Single`,
54-
operationName,
55-
query: rawRequestOptions.query,
54+
document,
5655
variables: rawRequestOptions.variables,
5756
},
5857
headers: {
@@ -105,14 +104,13 @@ export class GraphQLClient {
105104
fetchOptions.signal = requestOptions.signal
106105
}
107106

108-
const { query, operationName } = resolveRequestDocument(requestOptions.document, excludeOperationName)
107+
const analyzedDocument = analyzeDocument(requestOptions.document, excludeOperationName)
109108

110109
const response = await runRequest({
111110
url,
112111
request: {
113-
operationName,
114112
_tag: `Single`,
115-
query,
113+
document: analyzedDocument,
116114
variables: requestOptions.variables,
117115
},
118116
headers: {
@@ -152,17 +150,20 @@ export class GraphQLClient {
152150
fetchOptions.signal = batchRequestOptions.signal
153151
}
154152

155-
const queries = batchRequestOptions.documents.map(
156-
({ document }) => resolveRequestDocument(document, excludeOperationName).query
153+
const analyzedDocuments = batchRequestOptions.documents.map(
154+
({ document }) => analyzeDocument(document, excludeOperationName)
157155
)
156+
const expressions = analyzedDocuments.map(({ expression }) => expression)
157+
const hasMutations = analyzedDocuments.some(({ isMutation }) => isMutation)
158158
const variables = batchRequestOptions.documents.map(({ variables }) => variables)
159159

160160
const response= await runRequest({
161161
url: this.url,
162162
request: {
163163
_tag:`Batch`,
164164
operationName: undefined,
165-
query: queries,
165+
query: expressions,
166+
hasMutations,
166167
variables,
167168
},
168169
headers: {

src/entrypoints/main.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export { GraphQLClient } from '../classes/GraphQLClient.js'
1212
export { batchRequests } from '../functions/batchRequests.js'
1313
export { gql } from '../functions/gql.js'
1414
export { rawRequest } from '../functions/rawRequest.js'
15-
export { resolveRequestDocument } from '../helpers/resolveRequestDocument.js'
15+
export { analyzeDocument } from '../helpers/analyzeDocument.js'
1616
export { GraphQLWebSocketClient } from '../lib/graphql-ws.js'
1717
export {
1818
BatchRequestDocument,

src/helpers/analyzeDocument.ts

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { isOperationDefinitionNode } from '../lib/graphql.js'
2+
import { tryCatch } from '../lib/prelude.js'
3+
import type { RequestDocument } from './types.js'
4+
/**
5+
* Refactored imports from `graphql` to be more specific, this helps import only the required files (100KiB)
6+
* instead of the entire package (greater than 500KiB) where tree-shaking is not supported.
7+
* @see https://github.com/jasonkuhrt/graphql-request/pull/543
8+
*/
9+
import { type DocumentNode, OperationTypeNode } from 'graphql/language/ast.js'
10+
import { parse } from 'graphql/language/parser.js'
11+
import { print } from 'graphql/language/printer.js'
12+
13+
/**
14+
* helpers
15+
*/
16+
17+
const extractOperationName = (document: DocumentNode): string | undefined => {
18+
let operationName = undefined
19+
20+
const defs = document.definitions.filter(isOperationDefinitionNode)
21+
22+
if (defs.length === 1) {
23+
operationName = defs[0]!.name?.value
24+
}
25+
26+
return operationName
27+
}
28+
29+
const extractIsMutation = (document: DocumentNode): boolean => {
30+
let isMutation = false
31+
32+
const defs = document.definitions.filter(isOperationDefinitionNode)
33+
34+
if (defs.length === 1) {
35+
isMutation = defs[0]!.operation === OperationTypeNode.MUTATION
36+
}
37+
38+
return isMutation
39+
}
40+
41+
export const analyzeDocument = (
42+
document: RequestDocument,
43+
excludeOperationName?: boolean,
44+
): { expression: string; operationName: string | undefined; isMutation: boolean } => {
45+
const expression = typeof document === `string` ? document : print(document)
46+
47+
let isMutation = false
48+
let operationName = undefined
49+
50+
if (excludeOperationName) {
51+
return { expression, isMutation, operationName }
52+
}
53+
54+
const docNode = tryCatch(() => (typeof document === `string` ? parse(document) : document))
55+
if (docNode instanceof Error) {
56+
return { expression, isMutation, operationName }
57+
}
58+
59+
operationName = extractOperationName(docNode)
60+
isMutation = extractIsMutation(docNode)
61+
62+
return { expression, operationName, isMutation }
63+
}

src/helpers/resolveRequestDocument.ts

-56
This file was deleted.

0 commit comments

Comments
 (0)