Skip to content

Commit abf4343

Browse files
authored
Merge pull request #348 from storm2513/add-support-for-include-unused-variables-option
Add function `createUploadLink` option `includeUnusedVariables`, via #348 .
2 parents 6c9c4b4 + c39bd5b commit abf4343

File tree

3 files changed

+156
-0
lines changed

3 files changed

+156
-0
lines changed

changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
- Use the TypeScript v5.5+ JSDoc tag `@import` to import types in modules.
99
- Updated dev dependencies, some of which require newer Node.js versions than previously supported.
1010

11+
### Minor
12+
13+
- Added a new function `createUploadLink` option `includeUnusedVariables` defaulting to `false` to toggle including unused GraphQL variables in the request (similar to the Apollo `BaseHttpLink` option [`includeUnusedVariables`](https://www.apollographql.com/docs/react/api/link/apollo-link-base-http#options-includeunusedvariables)), via [#348](https://github.com/jaydenseric/apollo-upload-client/pull/348).
14+
1115
### Patch
1216

1317
- Updated the package scripts:

createUploadLink.mjs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
} from "@apollo/client/link/http/selectHttpOptionsAndBody.js";
1919
import { selectURI } from "@apollo/client/link/http/selectURI.js";
2020
import { serializeFetchParameter } from "@apollo/client/link/http/serializeFetchParameter.js";
21+
import { filterOperationVariables } from "@apollo/client/link/utils/filterOperationVariables.js";
2122
import { Observable } from "@apollo/client/utilities/observables/Observable.js";
2223
import extractFiles from "extract-files/extractFiles.mjs";
2324

@@ -69,6 +70,8 @@ import isExtractableFile from "./isExtractableFile.mjs";
6970
* {@linkcode fetchOptions}.
7071
* @param {boolean} [options.includeExtensions] Toggles sending `extensions`
7172
* fields to the GraphQL server. Defaults to `false`.
73+
* @param {boolean} [options.includeUnusedVariables] Toggles including unused
74+
* GraphQL variables in the request. Defaults to `false`.
7275
* @returns A [terminating Apollo Link](https://www.apollographql.com/docs/react/api/link/introduction/#the-terminating-link).
7376
* @example
7477
* A basic Apollo Client setup:
@@ -95,6 +98,7 @@ export default function createUploadLink({
9598
credentials,
9699
headers,
97100
includeExtensions,
101+
includeUnusedVariables = false,
98102
} = {}) {
99103
const linkConfig = {
100104
http: { includeExtensions },
@@ -142,6 +146,12 @@ export default function createUploadLink({
142146
contextConfig,
143147
);
144148

149+
if (body.variables && !includeUnusedVariables)
150+
body.variables = filterOperationVariables(
151+
body.variables,
152+
operation.query,
153+
);
154+
145155
const { clone, files } = extractFiles(body, customIsExtractableFile, "");
146156

147157
let uri = selectURI(operation, fetchUri);

createUploadLink.test.mjs

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,147 @@ describe("Function `createUploadLink`.", { concurrency: true }, () => {
314314
deepStrictEqual(nextData, payload);
315315
});
316316

317+
it("Option `includeUnusedVariables`, set to false.", async () => {
318+
/** @type {unknown} */
319+
let fetchInput;
320+
321+
/** @type {RequestInit | undefined} */
322+
let fetchOptions;
323+
324+
/** @type {unknown} */
325+
let nextData;
326+
327+
const query = "query ($a: Boolean) {\n a(a: $a)\n}";
328+
const payload = { data: { a: true } };
329+
330+
await timeLimitPromise(
331+
/** @type {Promise<void>} */ (
332+
new Promise((resolve, reject) => {
333+
execute(
334+
createUploadLink({
335+
includeUnusedVariables: false,
336+
async fetch(input, options) {
337+
fetchInput = input;
338+
fetchOptions = options;
339+
340+
return new Response(
341+
JSON.stringify(payload),
342+
graphqlResponseOptions,
343+
);
344+
},
345+
}),
346+
{
347+
query: gql(query),
348+
variables: {
349+
a: true,
350+
b: true,
351+
},
352+
},
353+
).subscribe({
354+
next(data) {
355+
nextData = data;
356+
},
357+
error() {
358+
reject(createUnexpectedCallError());
359+
},
360+
complete() {
361+
resolve();
362+
},
363+
});
364+
})
365+
),
366+
);
367+
368+
strictEqual(fetchInput, defaultUri);
369+
ok(typeof fetchOptions === "object");
370+
371+
const { signal: fetchOptionsSignal, ...fetchOptionsRest } = fetchOptions;
372+
373+
ok(fetchOptionsSignal instanceof AbortSignal);
374+
deepEqual(fetchOptionsRest, {
375+
method: "POST",
376+
headers: { accept: "*/*", "content-type": "application/json" },
377+
body: JSON.stringify({
378+
variables: {
379+
a: true,
380+
},
381+
query,
382+
}),
383+
});
384+
deepStrictEqual(nextData, payload);
385+
});
386+
387+
it("Option `includeUnusedVariables`, set to true.", async () => {
388+
/** @type {unknown} */
389+
let fetchInput;
390+
391+
/** @type {RequestInit | undefined} */
392+
let fetchOptions;
393+
394+
/** @type {unknown} */
395+
let nextData;
396+
397+
const query = "query ($a: Boolean) {\n a(a: $a)\n}";
398+
const payload = { data: { a: true } };
399+
400+
await timeLimitPromise(
401+
/** @type {Promise<void>} */ (
402+
new Promise((resolve, reject) => {
403+
execute(
404+
createUploadLink({
405+
includeUnusedVariables: true,
406+
async fetch(input, options) {
407+
fetchInput = input;
408+
fetchOptions = options;
409+
410+
return new Response(
411+
JSON.stringify(payload),
412+
graphqlResponseOptions,
413+
);
414+
},
415+
}),
416+
{
417+
query: gql(query),
418+
variables: {
419+
a: true,
420+
b: true,
421+
},
422+
},
423+
).subscribe({
424+
next(data) {
425+
nextData = data;
426+
},
427+
error() {
428+
reject(createUnexpectedCallError());
429+
},
430+
complete() {
431+
resolve();
432+
},
433+
});
434+
})
435+
),
436+
);
437+
438+
strictEqual(fetchInput, defaultUri);
439+
ok(typeof fetchOptions === "object");
440+
441+
const { signal: fetchOptionsSignal, ...fetchOptionsRest } = fetchOptions;
442+
443+
ok(fetchOptionsSignal instanceof AbortSignal);
444+
deepEqual(fetchOptionsRest, {
445+
method: "POST",
446+
headers: { accept: "*/*", "content-type": "application/json" },
447+
body: JSON.stringify({
448+
variables: {
449+
a: true,
450+
b: true,
451+
},
452+
query,
453+
}),
454+
});
455+
deepStrictEqual(nextData, payload);
456+
});
457+
317458
it("Option `print`.", async () => {
318459
/** @type {unknown} */
319460
let fetchInput;
@@ -606,6 +747,7 @@ describe("Function `createUploadLink`.", { concurrency: true }, () => {
606747
execute(
607748
createUploadLink({
608749
useGETForQueries: true,
750+
includeUnusedVariables: true,
609751
async fetch() {
610752
fetched = true;
611753

0 commit comments

Comments
 (0)