@nhost/nhost-js
Version:
Nhost JavaScript SDK
103 lines • 3.67 kB
JavaScript
/**
* GraphQL client for the Nhost JavaScript SDK.
*
* This module provides functionality for executing GraphQL operations against
* a Hasura GraphQL API.
*/
import { createEnhancedFetch, FetchError, } from '../fetch';
/**
* Extracts a deduplicated query string from a TypedDocumentNode.
*
* When definition nodes have loc offsets (e.g. codegen output), deduplicates
* fragment definitions by name and reconstructs the query from AST slices.
* Falls back to the raw source text when loc is unavailable.
*/
export const extractQueryFromDocument = (document) => {
const source = document.loc?.source.body;
if (!source) {
return '';
}
if (!document.definitions.every((def) => def.loc)) {
return source;
}
const seen = new Set();
return document.definitions
.filter((def) => {
if (def.kind === 'FragmentDefinition' && 'name' in def) {
const name = def.name.value;
if (seen.has(name)) {
return false;
}
seen.add(name);
}
return true;
})
.map((def) => source.slice(def.loc?.start, def.loc?.end))
.join('\n\n');
};
/**
* Creates a GraphQL API client for interacting with a GraphQL endpoint.
*
* This client provides methods for executing queries and mutations against
* a GraphQL API, with support for middleware functions to handle authentication,
* error handling, and other cross-cutting concerns.
*
* @param url - Base URL for the GraphQL endpoint
* @param chainFunctions - Array of middleware functions for the fetch chain
* @returns GraphQL client with query and mutation methods
*/
export const createAPIClient = (url, chainFunctions = []) => {
let enhancedFetch = createEnhancedFetch(chainFunctions);
const pushChainFunction = (chainFunction) => {
chainFunctions.push(chainFunction);
enhancedFetch = createEnhancedFetch(chainFunctions);
};
const executeOperation = async (request, options) => {
const headers = new Headers(options?.headers);
if (!headers.has('Content-Type')) {
headers.set('Content-Type', 'application/json');
}
const response = await enhancedFetch(`${url}`, {
...options,
method: 'POST',
headers,
body: JSON.stringify(request),
});
const body = await response.text();
const data = (body ? JSON.parse(body) : {});
const resp = {
body: data,
status: response.status,
headers: response.headers,
};
if (data.errors) {
throw new FetchError(data, response.status, response.headers);
}
return resp;
};
function request(requestOrDocument, variablesOrOptions, options) {
if (typeof requestOrDocument === 'object' && 'kind' in requestOrDocument) {
const definition = requestOrDocument.definitions[0];
const request = {
query: extractQueryFromDocument(requestOrDocument),
variables: variablesOrOptions,
operationName: definition && 'name' in definition
? definition.name?.value
: undefined,
};
return executeOperation(request, options);
}
else {
// Handle GraphQLRequest
const request = requestOrDocument;
const requestOptions = variablesOrOptions;
return executeOperation(request, requestOptions);
}
}
return {
request,
url,
pushChainFunction,
};
};
//# sourceMappingURL=client.js.map