@nhost/nhost-js
Version:
Nhost JavaScript SDK
1 lines • 9.06 kB
Source Map (JSON)
{"version":3,"file":"graphql-Cg1kBTkm.cjs","names":[],"sources":["../src/graphql/client.ts"],"sourcesContent":["/**\n * GraphQL client for the Nhost JavaScript SDK.\n *\n * This module provides functionality for executing GraphQL operations against\n * a Hasura GraphQL API.\n */\n\nimport type { TypedDocumentNode } from '@graphql-typed-document-node/core';\nimport {\n type ChainFunction,\n createEnhancedFetch,\n FetchError,\n type FetchResponse,\n} from '../fetch';\n\n/**\n * Variables object for GraphQL operations.\n * Key-value pairs of variable names and their values.\n */\nexport type GraphQLVariables = Record<string, unknown>;\n\n/**\n * GraphQL request object used for queries and mutations.\n */\nexport interface GraphQLRequest<TVariables = GraphQLVariables> {\n /** The GraphQL query or mutation string */\n query: string;\n /** Optional variables for parameterized queries */\n variables?: TVariables;\n /** Optional name of the operation to execute */\n operationName?: string;\n}\n\n/**\n * Represents a GraphQL error returned from the server.\n */\nexport interface GraphQLError {\n /** Error message */\n message: string;\n /** Source locations in the GraphQL document where the error occurred */\n locations?: { line: number; column: number }[];\n /** Path in the query where the error occurred */\n path?: string[];\n /** Additional error information specific to the GraphQL implementation */\n extensions?: { path: string; code: string };\n}\n\n/**\n * Standard GraphQL response format as defined by the GraphQL specification.\n */\nexport interface GraphQLResponse<TResponseData = unknown> {\n /** The data returned from successful execution */\n data?: TResponseData;\n /** Array of errors if execution was unsuccessful or partially successful */\n errors?: GraphQLError[];\n}\n\n/**\n * GraphQL client interface providing methods for executing queries and mutations\n */\nexport interface Client {\n /**\n * Execute a GraphQL query operation\n *\n * Queries are used to fetch data and should not modify any data on the server.\n *\n * @param request - GraphQL request object containing query and optional variables\n * @param options - Additional fetch options to apply to the request\n * @returns Promise with the GraphQL response and metadata\n */\n request<TResponseData = unknown, TVariables = GraphQLVariables>(\n request: GraphQLRequest<TVariables>,\n options?: RequestInit,\n ): Promise<FetchResponse<GraphQLResponse<TResponseData>>>;\n\n /**\n * Execute a GraphQL query operation using a typed document node\n *\n * Duplicate fragment definitions are deduplicated on a best-effort basis\n * when the document's definition nodes include `loc` offsets.\n *\n * @param document - TypedDocumentNode containing the query and type information\n * @param variables - Variables for the GraphQL operation\n * @param options - Additional fetch options to apply to the request\n * @returns Promise with the GraphQL response and metadata\n */\n request<TResponseData, TVariables = GraphQLVariables>(\n document: TypedDocumentNode<TResponseData, TVariables>,\n variables?: TVariables,\n options?: RequestInit,\n ): Promise<FetchResponse<GraphQLResponse<TResponseData>>>;\n\n /**\n * URL for the GraphQL endpoint.\n */\n url: string;\n\n /** Add a middleware function to the fetch chain\n * @param chainFunction - The middleware function to add\n */\n pushChainFunction(chainFunction: ChainFunction): void;\n}\n\n/**\n * Extracts a deduplicated query string from a TypedDocumentNode.\n *\n * When definition nodes have loc offsets (e.g. codegen output), deduplicates\n * fragment definitions by name and reconstructs the query from AST slices.\n * Falls back to the raw source text when loc is unavailable.\n */\nexport const extractQueryFromDocument = <TResponseData, TVariables>(\n document: TypedDocumentNode<TResponseData, TVariables>,\n): string => {\n const source = document.loc?.source.body;\n if (!source) {\n return '';\n }\n\n if (!document.definitions.every((def) => def.loc)) {\n return source;\n }\n\n const seen = new Set<string>();\n return document.definitions\n .filter((def) => {\n if (def.kind === 'FragmentDefinition' && 'name' in def) {\n const name = (def.name as { value: string }).value;\n if (seen.has(name)) {\n return false;\n }\n seen.add(name);\n }\n return true;\n })\n .map((def) => source.slice(def.loc?.start, def.loc?.end))\n .join('\\n\\n');\n};\n\n/**\n * Creates a GraphQL API client for interacting with a GraphQL endpoint.\n *\n * This client provides methods for executing queries and mutations against\n * a GraphQL API, with support for middleware functions to handle authentication,\n * error handling, and other cross-cutting concerns.\n *\n * @param url - Base URL for the GraphQL endpoint\n * @param chainFunctions - Array of middleware functions for the fetch chain\n * @returns GraphQL client with query and mutation methods\n */\nexport const createAPIClient = (\n url: string,\n chainFunctions: ChainFunction[] = [],\n): Client => {\n let enhancedFetch = createEnhancedFetch(chainFunctions);\n\n const pushChainFunction = (chainFunction: ChainFunction) => {\n chainFunctions.push(chainFunction);\n enhancedFetch = createEnhancedFetch(chainFunctions);\n };\n\n const executeOperation = async <\n TResponseData = unknown,\n TVariables = GraphQLVariables,\n >(\n request: GraphQLRequest<TVariables>,\n options?: RequestInit,\n ): Promise<FetchResponse<GraphQLResponse<TResponseData>>> => {\n const headers = new Headers(options?.headers);\n if (!headers.has('Content-Type')) {\n headers.set('Content-Type', 'application/json');\n }\n\n const response = await enhancedFetch(`${url}`, {\n ...options,\n method: 'POST',\n headers,\n body: JSON.stringify(request),\n });\n\n const body = await response.text();\n const data: GraphQLResponse<TResponseData> = (\n body ? JSON.parse(body) : {}\n ) as GraphQLResponse<TResponseData>;\n\n const resp = {\n body: data,\n status: response.status,\n headers: response.headers,\n };\n\n if (data.errors) {\n throw new FetchError(data, response.status, response.headers);\n }\n\n return resp;\n };\n\n function request<TResponseData = unknown, TVariables = GraphQLVariables>(\n request: GraphQLRequest<TVariables>,\n options?: RequestInit,\n ): Promise<FetchResponse<GraphQLResponse<TResponseData>>>;\n function request<TResponseData, TVariables = GraphQLVariables>(\n document: TypedDocumentNode<TResponseData, TVariables>,\n variables?: TVariables,\n options?: RequestInit,\n ): Promise<FetchResponse<GraphQLResponse<TResponseData>>>;\n function request<TResponseData, TVariables = GraphQLVariables>(\n requestOrDocument:\n | GraphQLRequest<TVariables>\n | TypedDocumentNode<TResponseData, TVariables>,\n variablesOrOptions?: TVariables | RequestInit,\n options?: RequestInit,\n ): Promise<FetchResponse<GraphQLResponse<TResponseData>>> {\n if (typeof requestOrDocument === 'object' && 'kind' in requestOrDocument) {\n const definition = requestOrDocument.definitions[0];\n\n const request: GraphQLRequest<TVariables> = {\n query: extractQueryFromDocument(requestOrDocument),\n variables: variablesOrOptions as TVariables,\n operationName:\n definition && 'name' in definition\n ? definition.name?.value\n : undefined,\n };\n return executeOperation(request, options);\n } else {\n // Handle GraphQLRequest\n const request = requestOrDocument;\n const requestOptions = variablesOrOptions as RequestInit;\n return executeOperation(request, requestOptions);\n }\n }\n\n return {\n request,\n url,\n pushChainFunction,\n } as Client;\n};\n"],"mappings":"wCA8GA,IAAa,EACX,IAEA,MAAM,EAAS,EAAS,KAAK,OAAO,KACpC,IAAK,EACH,MAAO,GAGT,IAAK,EAAS,YAAY,OAAO,GAAQ,EAAI,MAC3C,OAAO,EAGT,MAAM,EAAO,IAAI,IACjB,OAAO,EAAS,YACb,QAAQ,IACP,GAAiB,uBAAb,EAAI,MAAiC,SAAU,EAAK,CACtD,MAAM,EAAQ,EAAI,KAA2B,MAC7C,GAAI,EAAK,IAAI,GACX,OAAO,EAET,EAAK,IAAI,EACX,CACA,OAAO,CAAA,IAER,KAAK,GAAQ,EAAO,MAAM,EAAI,KAAK,MAAO,EAAI,KAAK,OACnD,KAAK,OAAM,EAcH,EAAA,CACX,EACA,EAAkC,MAElC,IAAI,EAAgB,EAAA,oBAAoB,GAExC,MAKM,EAAmB,MAIvB,EACA,KAEA,MAAM,EAAU,IAAI,QAAQ,GAAS,SAChC,EAAQ,IAAI,iBACf,EAAQ,IAAI,eAAgB,oBAG9B,MAAM,QAAiB,EAAc,GAAG,IAAO,IAC1C,EACH,OAAQ,OACR,UACA,KAAM,KAAK,UAAU,KAGjB,QAAa,EAAS,OACtB,EACJ,EAAO,KAAK,MAAM,GAAQ,CAAC,EAGvB,EAAO,CACX,KAAM,EACN,OAAQ,EAAS,OACjB,QAAS,EAAS,SAGpB,GAAI,EAAK,OACP,MAAM,IAAI,EAAA,WAAW,EAAM,EAAS,OAAQ,EAAS,SAGvD,OAAO,CAAA,EAuCT,MAAO,CACL,QA5BF,SACE,EAGA,EACA,GAEA,GAAiC,iBAAtB,GAAkC,SAAU,EAAmB,CACxE,MAAM,EAAa,EAAkB,YAAY,GAUjD,OAAO,EAAiB,CAPtB,MAAO,EAAyB,GAChC,UAAW,EACX,cACE,GAAc,SAAU,EACpB,EAAW,MAAM,WACjB,GAEyB,EACnC,CAIE,OAAO,EAAiB,EAAS,EAErC,EAIE,MACA,kBAjFyB,IACzB,EAAe,KAAK,GACpB,EAAgB,EAAA,oBAAoB,EAAc,EAgFpD"}