UNPKG

@gqlts/runtime

Version:

Gqlts runtime client

102 lines (82 loc) 3 kB
const isReadableStream = (val) => val !== null && typeof val === 'object' && typeof val.pipe === 'function' && typeof val._read === 'function' && typeof val._readableState === 'object'; export class ReactNativeFile { uri: string; name?: string; type?: string; constructor(uri: string, name?: string, type?: string) { this.uri = uri; this.name = name; this.type = type; } } export function isExtractableFile(value: File | Blob | ReadableStream | ReactNativeFile) { return ( (typeof File !== 'undefined' && value instanceof File) || (typeof Blob !== 'undefined' && value instanceof Blob) || isReadableStream(value) || value instanceof ReactNativeFile ); } export function extractFiles(value, path = '', isExtractableFileMethod = isExtractableFile) { // Map of extracted files and their object paths within the input value. const files = new Map(); // Map of arrays and objects recursive within the input value and their clones, // for reusing clones of values that are referenced multiple times within the // input value. const clones = new Map(); /** * Recursively clones the value, extracting files. * @kind function * @name extractFiles~recurse * @param {*} value Value to extract files from. * @param {ObjectPath} path Prefix for object paths for extracted files. * @param {Set} recursive Recursive arrays and objects for avoiding infinite recursion of circular references within the input value. * @returns {*} Clone of the value with files replaced with `null`. * @ignore */ function recurse(value, path, recursive) { let clone = value; if (isExtractableFileMethod(value)) { clone = null; const filePaths = files.get(value); filePaths ? filePaths.push(path) : files.set(value, [path]); } else { const isList = Array.isArray(value) || (typeof FileList !== 'undefined' && value instanceof FileList); const isObject = value && value.constructor === Object; if (isList || isObject) { const hasClone = clones.has(value); if (hasClone) clone = clones.get(value); else { clone = isList ? [] : {}; clones.set(value, clone); } if (!recursive.has(value)) { const pathPrefix = path ? `${path}.` : ''; const recursiveDeeper = new Set(recursive).add(value); if (isList) { let index = 0; // @ts-ignore for (const item of value) { const itemClone = recurse(item, pathPrefix + index++, recursiveDeeper); if (!hasClone) clone.push(itemClone); } } else for (const key in value) { const propertyClone = recurse(value[key], pathPrefix + key, recursiveDeeper); if (!hasClone) clone[key] = propertyClone; } } } } return clone; } return { clone: recurse(value, path, new Set()), files, }; }