From e3db4c22ab515b44bf60e1c70150f80dbb3246ef Mon Sep 17 00:00:00 2001 From: Jayden Seric Date: Mon, 23 Oct 2023 23:32:26 +1100 Subject: [PATCH] Add a new option `print` for the function `createUploadLink`. Closes https://github.com/jaydenseric/apollo-upload-client/pull/274 . --- changelog.md | 6 ++++ createUploadLink.mjs | 10 ++++-- createUploadLink.test.mjs | 66 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index 61e3f54..2b3584c 100644 --- a/changelog.md +++ b/changelog.md @@ -61,6 +61,12 @@ - [`compilerOptions.maxNodeModuleJsDepth`](https://www.typescriptlang.org/tsconfig#maxNodeModuleJsDepth) should be reasonably large, e.g. `10`. - [`compilerOptions.module`](https://www.typescriptlang.org/tsconfig#module) should be `"node16"` or `"nodenext"`. +- Internally, use the function `selectHttpOptionsAndBodyInternal` that was added in [`@apollo/client`](https://npm.im/@apollo/client) [v3.5.5](https://github.com/apollographql/apollo-client/releases/tag/v3.5.5). + +### Minor + +- Added a new option `print` for the function `createUploadLink`, to customize how the GraphQL query or mutation AST prints to a string for transport. It that works like the same option for [`HttpLink`](https://www.apollographql.com/docs/react/api/link/apollo-link-http). + ### Patch - Updated dev dependencies. diff --git a/createUploadLink.mjs b/createUploadLink.mjs index 32d06e3..c3ca867 100644 --- a/createUploadLink.mjs +++ b/createUploadLink.mjs @@ -5,8 +5,9 @@ import { createSignalIfSupported } from "@apollo/client/link/http/createSignalIf import { parseAndCheckHttpResponse } from "@apollo/client/link/http/parseAndCheckHttpResponse.js"; import { rewriteURIForGET } from "@apollo/client/link/http/rewriteURIForGET.js"; import { + defaultPrinter, fallbackHttpConfig, - selectHttpOptionsAndBody, + selectHttpOptionsAndBodyInternal, } from "@apollo/client/link/http/selectHttpOptionsAndBody.js"; import { selectURI } from "@apollo/client/link/http/selectURI.js"; import { serializeFetchParameter } from "@apollo/client/link/http/serializeFetchParameter.js"; @@ -46,6 +47,9 @@ import isExtractableFile from "./isExtractableFile.mjs"; * Customizes how extracted files are appended to the * [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) * instance. Defaults to {@linkcode formDataAppendFile}. + * @param {import("@apollo/client/link/http/selectHttpOptionsAndBody.js").Printer} [options.print] + * Prints the GraphQL query or mutation AST to a string for transport. + * Defaults to {@linkcode defaultPrinter}. * @param {typeof fetch} [options.fetch] [`fetch`](https://fetch.spec.whatwg.org) * implementation. Defaults to the {@linkcode fetch} global. * @param {RequestInit} [options.fetchOptions] `fetch` options; overridden by @@ -78,6 +82,7 @@ export default function createUploadLink({ isExtractableFile: customIsExtractableFile = isExtractableFile, FormData: CustomFormData, formDataAppendFile: customFormDataAppendFile = formDataAppendFile, + print = defaultPrinter, fetch: customFetch, fetchOptions, credentials, @@ -122,8 +127,9 @@ export default function createUploadLink({ }, }; - const { options, body } = selectHttpOptionsAndBody( + const { options, body } = selectHttpOptionsAndBodyInternal( operation, + print, fallbackHttpConfig, linkConfig, contextConfig, diff --git a/createUploadLink.test.mjs b/createUploadLink.test.mjs index 56cccff..e5f6890 100644 --- a/createUploadLink.test.mjs +++ b/createUploadLink.test.mjs @@ -8,6 +8,7 @@ import { describe, it } from "node:test"; import { ApolloLink } from "@apollo/client/link/core/ApolloLink.js"; import { concat } from "@apollo/client/link/core/concat.js"; import { execute } from "@apollo/client/link/core/execute.js"; +import { stripIgnoredCharacters } from "graphql"; import { gql } from "graphql-tag"; import revertableGlobals from "revertable-globals"; @@ -315,6 +316,71 @@ describe("Function `createUploadLink`.", { concurrency: true }, () => { deepStrictEqual(nextData, payload); }); + it("Option `print`.", async () => { + /** @type {unknown} */ + let fetchInput; + + /** @type {RequestInit | undefined} */ + let fetchOptions; + + /** @type {unknown} */ + let nextData; + + const query = "{\n a\n}"; + const payload = { data: { a: true } }; + + await timeLimitPromise( + /** @type {Promise} */ ( + new Promise((resolve, reject) => { + execute( + createUploadLink({ + print: (ast, originalPrint) => + stripIgnoredCharacters(originalPrint(ast)), + async fetch(input, options) { + fetchInput = input; + fetchOptions = options; + + return new Response( + JSON.stringify(payload), + graphqlResponseOptions, + ); + }, + }), + { + query: gql(query), + }, + ).subscribe({ + next(data) { + nextData = data; + }, + error() { + reject(createUnexpectedCallError()); + }, + complete() { + resolve(); + }, + }); + }) + ), + ); + + strictEqual(fetchInput, defaultUri); + ok(typeof fetchOptions === "object"); + + const { signal: fetchOptionsSignal, ...fetchOptionsRest } = fetchOptions; + + ok(fetchOptionsSignal instanceof AbortSignal); + deepEqual(fetchOptionsRest, { + method: "POST", + headers: { accept: "*/*", "content-type": "application/json" }, + body: JSON.stringify({ + variables: {}, + query: stripIgnoredCharacters(query), + }), + }); + deepStrictEqual(nextData, payload); + }); + it("Option `fetchOptions.method`.", async () => { /** @type {unknown} */ let fetchInput;