graphql-request
Version:
Minimal GraphQL client supporting Node and browsers for scripts or simple apps.
161 lines • 6.27 kB
JavaScript
import { callOrIdentity, HeadersInitToPlainObject } from '../../lib/prelude.js';
import { parseBatchRequestArgs } from '../functions/batchRequests.js';
import { parseRawRequestArgs } from '../functions/rawRequest.js';
import { parseRequestArgs } from '../functions/request.js';
import { analyzeDocument } from '../helpers/analyzeDocument.js';
import { runRequest } from '../helpers/runRequest.js';
/**
* GraphQL Client.
*/
export class GraphQLClient {
url;
requestConfig;
constructor(url, requestConfig = {}) {
this.url = url;
this.requestConfig = requestConfig;
}
/**
* Send a GraphQL query to the server.
*/
rawRequest = async (...args) => {
const [queryOrOptions, variables, requestHeaders] = args;
const rawRequestOptions = parseRawRequestArgs(queryOrOptions, variables, requestHeaders);
const { headers, fetch = globalThis.fetch, method = `POST`, requestMiddleware, responseMiddleware, excludeOperationName, ...fetchOptions } = this.requestConfig;
const { url } = this;
if (rawRequestOptions.signal !== undefined) {
fetchOptions.signal = rawRequestOptions.signal;
}
const document = analyzeDocument(rawRequestOptions.query, excludeOperationName);
const response = await runRequest({
url,
request: {
_tag: `Single`,
document,
variables: rawRequestOptions.variables,
},
headers: {
...HeadersInitToPlainObject(callOrIdentity(headers)),
...HeadersInitToPlainObject(rawRequestOptions.requestHeaders),
},
fetch,
method,
fetchOptions,
middleware: requestMiddleware,
});
if (responseMiddleware) {
await responseMiddleware(response, {
operationName: document.operationName,
variables,
url: this.url,
});
}
if (response instanceof Error) {
throw response;
}
return response;
};
async request(documentOrOptions, ...variablesAndRequestHeaders) {
const [variables, requestHeaders] = variablesAndRequestHeaders;
const requestOptions = parseRequestArgs(documentOrOptions, variables, requestHeaders);
const { headers, fetch = globalThis.fetch, method = `POST`, requestMiddleware, responseMiddleware, excludeOperationName, ...fetchOptions } = this.requestConfig;
const { url } = this;
if (requestOptions.signal !== undefined) {
fetchOptions.signal = requestOptions.signal;
}
const analyzedDocument = analyzeDocument(requestOptions.document, excludeOperationName);
const response = await runRequest({
url,
request: {
_tag: `Single`,
document: analyzedDocument,
variables: requestOptions.variables,
},
headers: {
...HeadersInitToPlainObject(callOrIdentity(headers)),
...HeadersInitToPlainObject(requestOptions.requestHeaders),
},
fetch,
method,
fetchOptions,
middleware: requestMiddleware,
});
if (responseMiddleware) {
await responseMiddleware(response, {
operationName: analyzedDocument.operationName,
variables: requestOptions.variables,
url: this.url,
});
}
if (response instanceof Error) {
throw response;
}
return response.data;
}
async batchRequests(documentsOrOptions, requestHeaders) {
const batchRequestOptions = parseBatchRequestArgs(documentsOrOptions, requestHeaders);
const { headers, excludeOperationName, ...fetchOptions } = this.requestConfig;
if (batchRequestOptions.signal !== undefined) {
fetchOptions.signal = batchRequestOptions.signal;
}
const analyzedDocuments = batchRequestOptions.documents.map(({ document }) => analyzeDocument(document, excludeOperationName));
const expressions = analyzedDocuments.map(({ expression }) => expression);
const hasMutations = analyzedDocuments.some(({ isMutation }) => isMutation);
const variables = batchRequestOptions.documents.map(({ variables }) => variables);
const response = await runRequest({
url: this.url,
request: {
_tag: `Batch`,
operationName: undefined,
query: expressions,
hasMutations,
variables,
},
headers: {
...HeadersInitToPlainObject(callOrIdentity(headers)),
...HeadersInitToPlainObject(batchRequestOptions.requestHeaders),
},
fetch: this.requestConfig.fetch ?? globalThis.fetch,
method: this.requestConfig.method || `POST`,
fetchOptions,
middleware: this.requestConfig.requestMiddleware,
});
if (this.requestConfig.responseMiddleware) {
await this.requestConfig.responseMiddleware(response, {
operationName: undefined,
variables,
url: this.url,
});
}
if (response instanceof Error) {
throw response;
}
return response.data;
}
setHeaders(headers) {
this.requestConfig.headers = headers;
return this;
}
/**
* Attach a header to the client. All subsequent requests will have this header.
*/
setHeader(key, value) {
const { headers } = this.requestConfig;
if (headers) {
// todo what if headers is in nested array form... ?
// @ts-expect-error todo
headers[key] = value;
}
else {
this.requestConfig.headers = { [key]: value };
}
return this;
}
/**
* Change the client endpoint. All subsequent requests will send to this endpoint.
*/
setEndpoint(value) {
this.url = value;
return this;
}
}
//# sourceMappingURL=GraphQLClient.js.map