You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
8.1 KiB
156 lines
8.1 KiB
4 months ago
|
import { __assign, __rest } from "tslib";
|
||
|
import { invariant } from "../../utilities/globals/index.js";
|
||
|
import { ApolloLink } from "../core/index.js";
|
||
|
import { Observable, hasDirectives } from "../../utilities/index.js";
|
||
|
import { serializeFetchParameter } from "./serializeFetchParameter.js";
|
||
|
import { selectURI } from "./selectURI.js";
|
||
|
import { handleError, readMultipartBody, parseAndCheckHttpResponse, } from "./parseAndCheckHttpResponse.js";
|
||
|
import { checkFetcher } from "./checkFetcher.js";
|
||
|
import { selectHttpOptionsAndBodyInternal, defaultPrinter, fallbackHttpConfig, } from "./selectHttpOptionsAndBody.js";
|
||
|
import { rewriteURIForGET } from "./rewriteURIForGET.js";
|
||
|
import { fromError, filterOperationVariables } from "../utils/index.js";
|
||
|
import { maybe, getMainDefinition, removeClientSetsFromDocument, } from "../../utilities/index.js";
|
||
|
var backupFetch = maybe(function () { return fetch; });
|
||
|
export var createHttpLink = function (linkOptions) {
|
||
|
if (linkOptions === void 0) { linkOptions = {}; }
|
||
|
var _a = linkOptions.uri, uri = _a === void 0 ? "/graphql" : _a,
|
||
|
// use default global fetch if nothing passed in
|
||
|
preferredFetch = linkOptions.fetch, _b = linkOptions.print, print = _b === void 0 ? defaultPrinter : _b, includeExtensions = linkOptions.includeExtensions, preserveHeaderCase = linkOptions.preserveHeaderCase, useGETForQueries = linkOptions.useGETForQueries, _c = linkOptions.includeUnusedVariables, includeUnusedVariables = _c === void 0 ? false : _c, requestOptions = __rest(linkOptions, ["uri", "fetch", "print", "includeExtensions", "preserveHeaderCase", "useGETForQueries", "includeUnusedVariables"]);
|
||
|
if (globalThis.__DEV__ !== false) {
|
||
|
// Make sure at least one of preferredFetch, window.fetch, or backupFetch is
|
||
|
// defined, so requests won't fail at runtime.
|
||
|
checkFetcher(preferredFetch || backupFetch);
|
||
|
}
|
||
|
var linkConfig = {
|
||
|
http: { includeExtensions: includeExtensions, preserveHeaderCase: preserveHeaderCase },
|
||
|
options: requestOptions.fetchOptions,
|
||
|
credentials: requestOptions.credentials,
|
||
|
headers: requestOptions.headers,
|
||
|
};
|
||
|
return new ApolloLink(function (operation) {
|
||
|
var chosenURI = selectURI(operation, uri);
|
||
|
var context = operation.getContext();
|
||
|
// `apollographql-client-*` headers are automatically set if a
|
||
|
// `clientAwareness` object is found in the context. These headers are
|
||
|
// set first, followed by the rest of the headers pulled from
|
||
|
// `context.headers`. If desired, `apollographql-client-*` headers set by
|
||
|
// the `clientAwareness` object can be overridden by
|
||
|
// `apollographql-client-*` headers set in `context.headers`.
|
||
|
var clientAwarenessHeaders = {};
|
||
|
if (context.clientAwareness) {
|
||
|
var _a = context.clientAwareness, name_1 = _a.name, version = _a.version;
|
||
|
if (name_1) {
|
||
|
clientAwarenessHeaders["apollographql-client-name"] = name_1;
|
||
|
}
|
||
|
if (version) {
|
||
|
clientAwarenessHeaders["apollographql-client-version"] = version;
|
||
|
}
|
||
|
}
|
||
|
var contextHeaders = __assign(__assign({}, clientAwarenessHeaders), context.headers);
|
||
|
var contextConfig = {
|
||
|
http: context.http,
|
||
|
options: context.fetchOptions,
|
||
|
credentials: context.credentials,
|
||
|
headers: contextHeaders,
|
||
|
};
|
||
|
if (hasDirectives(["client"], operation.query)) {
|
||
|
var transformedQuery = removeClientSetsFromDocument(operation.query);
|
||
|
if (!transformedQuery) {
|
||
|
return fromError(new Error("HttpLink: Trying to send a client-only query to the server. To send to the server, ensure a non-client field is added to the query or set the `transformOptions.removeClientFields` option to `true`."));
|
||
|
}
|
||
|
operation.query = transformedQuery;
|
||
|
}
|
||
|
//uses fallback, link, and then context to build options
|
||
|
var _b = selectHttpOptionsAndBodyInternal(operation, print, fallbackHttpConfig, linkConfig, contextConfig), options = _b.options, body = _b.body;
|
||
|
if (body.variables && !includeUnusedVariables) {
|
||
|
body.variables = filterOperationVariables(body.variables, operation.query);
|
||
|
}
|
||
|
var controller;
|
||
|
if (!options.signal && typeof AbortController !== "undefined") {
|
||
|
controller = new AbortController();
|
||
|
options.signal = controller.signal;
|
||
|
}
|
||
|
// If requested, set method to GET if there are no mutations.
|
||
|
var definitionIsMutation = function (d) {
|
||
|
return d.kind === "OperationDefinition" && d.operation === "mutation";
|
||
|
};
|
||
|
var definitionIsSubscription = function (d) {
|
||
|
return d.kind === "OperationDefinition" && d.operation === "subscription";
|
||
|
};
|
||
|
var isSubscription = definitionIsSubscription(getMainDefinition(operation.query));
|
||
|
// does not match custom directives beginning with @defer
|
||
|
var hasDefer = hasDirectives(["defer"], operation.query);
|
||
|
if (useGETForQueries &&
|
||
|
!operation.query.definitions.some(definitionIsMutation)) {
|
||
|
options.method = "GET";
|
||
|
}
|
||
|
if (hasDefer || isSubscription) {
|
||
|
options.headers = options.headers || {};
|
||
|
var acceptHeader = "multipart/mixed;";
|
||
|
// Omit defer-specific headers if the user attempts to defer a selection
|
||
|
// set on a subscription and log a warning.
|
||
|
if (isSubscription && hasDefer) {
|
||
|
globalThis.__DEV__ !== false && invariant.warn(38);
|
||
|
}
|
||
|
if (isSubscription) {
|
||
|
acceptHeader +=
|
||
|
"boundary=graphql;subscriptionSpec=1.0,application/json";
|
||
|
}
|
||
|
else if (hasDefer) {
|
||
|
acceptHeader += "deferSpec=20220824,application/json";
|
||
|
}
|
||
|
options.headers.accept = acceptHeader;
|
||
|
}
|
||
|
if (options.method === "GET") {
|
||
|
var _c = rewriteURIForGET(chosenURI, body), newURI = _c.newURI, parseError = _c.parseError;
|
||
|
if (parseError) {
|
||
|
return fromError(parseError);
|
||
|
}
|
||
|
chosenURI = newURI;
|
||
|
}
|
||
|
else {
|
||
|
try {
|
||
|
options.body = serializeFetchParameter(body, "Payload");
|
||
|
}
|
||
|
catch (parseError) {
|
||
|
return fromError(parseError);
|
||
|
}
|
||
|
}
|
||
|
return new Observable(function (observer) {
|
||
|
// Prefer linkOptions.fetch (preferredFetch) if provided, and otherwise
|
||
|
// fall back to the *current* global window.fetch function (see issue
|
||
|
// #7832), or (if all else fails) the backupFetch function we saved when
|
||
|
// this module was first evaluated. This last option protects against the
|
||
|
// removal of window.fetch, which is unlikely but not impossible.
|
||
|
var currentFetch = preferredFetch || maybe(function () { return fetch; }) || backupFetch;
|
||
|
var observerNext = observer.next.bind(observer);
|
||
|
currentFetch(chosenURI, options)
|
||
|
.then(function (response) {
|
||
|
var _a;
|
||
|
operation.setContext({ response: response });
|
||
|
var ctype = (_a = response.headers) === null || _a === void 0 ? void 0 : _a.get("content-type");
|
||
|
if (ctype !== null && /^multipart\/mixed/i.test(ctype)) {
|
||
|
return readMultipartBody(response, observerNext);
|
||
|
}
|
||
|
else {
|
||
|
return parseAndCheckHttpResponse(operation)(response).then(observerNext);
|
||
|
}
|
||
|
})
|
||
|
.then(function () {
|
||
|
controller = undefined;
|
||
|
observer.complete();
|
||
|
})
|
||
|
.catch(function (err) {
|
||
|
controller = undefined;
|
||
|
handleError(err, observer);
|
||
|
});
|
||
|
return function () {
|
||
|
// XXX support canceling this request
|
||
|
// https://developers.google.com/web/updates/2017/09/abortable-fetch
|
||
|
if (controller)
|
||
|
controller.abort();
|
||
|
};
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
//# sourceMappingURL=createHttpLink.js.map
|