UNPKG

graphql-request

Version:

Minimal GraphQL client supporting Node and browsers for scripts or simple apps

69 lines (55 loc) 2.1 kB
import { isExtractableFile, extractFiles, ExtractableFile } from 'extract-files' import FormDataNode from 'form-data' import { defaultJsonSerializer } from './defaultJsonSerializer' import { Variables } from './types' /** * Duck type if NodeJS stream * https://github.com/sindresorhus/is-stream/blob/3750505b0727f6df54324784fe369365ef78841e/index.js#L3 */ const isExtractableFileEnhanced = (value: any): value is ExtractableFile | { pipe: Function } => isExtractableFile(value) || (value !== null && typeof value === 'object' && typeof value.pipe === 'function') /** * Returns Multipart Form if body contains files * (https://github.com/jaydenseric/graphql-multipart-request-spec) * Otherwise returns JSON */ export default function createRequestBody( query: string | string[], variables?: Variables | Variables[], operationName?: string, jsonSerializer = defaultJsonSerializer ): string | FormData { const { clone, files } = extractFiles({ query, variables, operationName }, '', isExtractableFileEnhanced) if (files.size === 0) { if (!Array.isArray(query)) { return jsonSerializer.stringify(clone) } if (typeof variables !== 'undefined' && !Array.isArray(variables)) { throw new Error('Cannot create request body with given variable type, array expected') } // Batch support const payload = query.reduce<{ query: string; variables: Variables | undefined }[]>( (accu, currentQuery, index) => { accu.push({ query: currentQuery, variables: variables ? variables[index] : undefined }) return accu }, [] ) return jsonSerializer.stringify(payload) } const Form = typeof FormData === 'undefined' ? FormDataNode : FormData const form = new Form() form.append('operations', jsonSerializer.stringify(clone)) const map: { [key: number]: string[] } = {} let i = 0 files.forEach((paths) => { map[++i] = paths }) form.append('map', jsonSerializer.stringify(map)) i = 0 files.forEach((paths, file) => { form.append(`${++i}`, file as any) }) return form as FormData }