UNPKG

fetchero

Version:

_A type-safe, proxy-based HTTP & GraphQL client for modern applications._

106 lines (84 loc) 2.78 kB
// @ts-nocheck function isObject(value) { return Object.prototype.toString.call(value) === '[object Object]'; } export const isValidInitialString = /^(mutation|query)(?:\s+)?{|^(?!mutation|query)\w+(?:\s+)?(?:{|\()/i; export const isEmpty = obj => Object.keys(obj).length === 0; export const inSingleLine = query => query .trim() .replace(/\n/g, ' ') // It is necessary to keep two separate replacements .replace(/\s{2,}/g, ' '); function typeOf(value) { let type = typeof value; if (isObject(value)) { if (value.type) return value.type; type = typeof value.value; } return { number: 'Int', string: 'String', boolean: 'Boolean', }[type]; } function getValue(value, key) { if (['number', 'string', 'boolean'].includes(typeof value)) return value; if (isObject(value) && value.value) return value.value; throw new Error(`The value is not in acceptable format for ${key}`); } function processArgsList(argsList) { const variables = {}; const queryStrings = []; const argsStrings = argsList.map((args, idx) => { const argsString = []; for (let key in args) { const value = getValue(args[key], key); const type = typeOf(args[key]); const variableName = `${key}_${idx}`; if (!type) { throw new Error(`\`type\` is not defined for \`${key}\` property`); } variables[variableName] = value; queryStrings.push(`$${variableName}: ${type}`); argsString.push(`${key}: $${variableName}`); } return argsString.join(', '); }); return { variables, argsStrings, varString: queryStrings.join(', '), }; } function constructString(strings, argsStrings) { const resultString = strings .map((string, position) => { return string + (argsStrings[position] || ''); }) .join(''); const firstPartPat = /^(mutation|query)\s+{/; if (firstPartPat.test(strings[0].trim())) { return resultString.replace(firstPartPat, '').replace(/}$/, ''); } return resultString; } export function buildQuery( strings, ...argsList ): { query: string; variables: Record<string, unknown> } { const initialString = strings[0].trim(); if (!isValidInitialString.test(initialString)) { throw new Error('The query string is not valid'); } const isMutation = /^mutation\s+{/.test(initialString); const queryType = isMutation ? 'mutation' : 'query'; const { variables, argsStrings, varString } = processArgsList(argsList); const queryString = varString ? `my_${queryType}(${varString})` : ''; const query = `${queryType} ${queryString} { ${constructString(strings, argsStrings)} }`; const result = { query: inSingleLine(query) }; if (!isEmpty(variables)) result.variables = variables; return result; }