UNPKG

graphiql-code-exporter

Version:

Export working code snippets from GraphiQL queries

182 lines (145 loc) 9.25 kB
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); import capitalizeFirstLetter from '../../utils/capitalizeFirstLetter'; import commentsFactory from '../../utils/jsCommentsFactory.js'; import { isOperationNamed, collapseExtraNewlines, addLeftWhitespace } from '../../utils'; import 'codemirror/mode/javascript/javascript'; var snippetOptions = [{ id: 'server', label: 'server-side usage', initial: false }, { id: 'asyncAwait', label: 'async/await', initial: true }]; var comments = { setup: 'This setup is only needed once per application', nodeFetch: 'Node doesn\'t implement fetch so we have to import it', graphqlError: 'handle those errors like a pro', graphqlData: 'do something great with this precious data', fetchError: 'handle errors from fetch itself' }; function generateDocumentQuery(operationDataList) { var body = operationDataList.map(function (operationData) { return operationData.query; }).join('\n\n').trim(); return 'const operationsDoc = `\n' + addLeftWhitespace(body, 2) + '\n`;'; } var fetcherName = 'fetchGraphQL'; function operationFunctionName(operationData) { var type = operationData.type; var prefix = type === 'query' ? 'fetch' : type === 'mutation' ? 'execute' : type === 'subscription' ? 'subscribeTo' : ''; var fnName = prefix + (prefix.length > 0 ? capitalizeFirstLetter(operationData.name) : operationData.name); return fnName; } // Promise-based functions function promiseFetcher(serverUrl, headers) { return 'function ' + fetcherName + '(operationsDoc, operationName, variables) {\n return fetch(\n "' + serverUrl + '",\n {\n method: "POST",' + (headers ? '\n headers: {\n' + addLeftWhitespace(headers, 8) + '\n },' : '') + '\n body: JSON.stringify({\n query: operationsDoc,\n variables: variables,\n operationName: operationName\n })\n }\n ).then((result) => result.json());\n}'; } function fetcherFunctions(operationDataList) { return operationDataList.map(function (operationData) { var fnName = operationFunctionName(operationData); var params = (operationData.operationDefinition.variableDefinitions || []).map(function (def) { return def.variable.name.value; }); var variablesBody = params.map(function (param) { return '"' + param + '": ' + param; }).join(', '); var variables = '{' + variablesBody + '}'; return 'function ' + fnName + '(' + params.join(', ') + ') {\n return ' + fetcherName + '(\n operationsDoc,\n "' + operationData.name + '",\n ' + variables + '\n );\n}'; }).join('\n\n'); } function promiseFetcherInvocation(getComment, operationDataList, vars) { return operationDataList.map(function (namedOperationData) { var params = (namedOperationData.operationDefinition.variableDefinitions || []).map(function (def) { return def.variable.name.value; }); var variables = Object.entries(namedOperationData.variables || {}).map(function (_ref) { var _ref2 = _slicedToArray(_ref, 2), key = _ref2[0], value = _ref2[1]; return 'const ' + key + ' = ' + JSON.stringify(value, null, 2) + ';'; }); return variables.join('\n') + '\n\n' + operationFunctionName(namedOperationData) + '(' + params.join(', ') + ')\n .then(({ data, errors }) => {\n if (errors) {\n ' + getComment('graphqlError') + '\n console.error(errors);\n }\n ' + getComment('graphqlData') + '\n console.log(data);\n })\n .catch((error) => {\n ' + getComment('fetchError') + '\n console.error(error);\n });'; }).join('\n\n'); } // Async-await-based functions function asyncFetcher(serverUrl, headers) { return 'async function ' + fetcherName + '(operationsDoc, operationName, variables) {\n const result = await fetch(\n "' + serverUrl + '",\n {\n method: "POST",' + (headers ? '\n headers: {\n' + addLeftWhitespace(headers, 8) + '\n },' : '') + '\n body: JSON.stringify({\n query: operationsDoc,\n variables: variables,\n operationName: operationName\n })\n }\n );\n\n return await result.json();\n}'; } function asyncFetcherInvocation(getComment, operationDataList, vars) { return operationDataList.map(function (namedOperationData) { var params = (namedOperationData.operationDefinition.variableDefinitions || []).map(function (def) { return def.variable.name.value; }); var variables = Object.entries(namedOperationData.variables || {}).map(function (_ref3) { var _ref4 = _slicedToArray(_ref3, 2), key = _ref4[0], value = _ref4[1]; return 'const ' + key + ' = ' + JSON.stringify(value, null, 2) + ';'; }); return 'async function start' + capitalizeFirstLetter(operationFunctionName(namedOperationData)) + '(' + params.join(', ') + ') {\n const { errors, data } = await ' + operationFunctionName(namedOperationData) + '(' + params.join(', ') + ');\n\n if (errors) {\n ' + getComment('graphqlError') + '\n console.error(errors);\n }\n\n ' + getComment('graphqlData') + '\n console.log(data);\n}\n\n' + variables.join('\n') + '\n\nstart' + capitalizeFirstLetter(operationFunctionName(namedOperationData)) + '(' + params.join(', ') + ');'; }).join('\n\n'); } // Snippet generation! var snippet = { language: 'JavaScript', codeMirrorMode: 'javascript', name: 'fetch', options: snippetOptions, generate: function generate(opts) { var serverUrl = opts.serverUrl, headers = opts.headers, options = opts.options; var operationDataList = opts.operationDataList.map(function (operationData, idx) { if (!isOperationNamed(operationData)) { return _extends({}, operationData, { name: ('unnamed' + capitalizeFirstLetter(operationData.type) + (idx + 1)).trim(), query: '# Consider giving this ' + operationData.type + ' a unique, descriptive\n# name in your application as a best practice\n' + operationData.type + ' unnamed' + capitalizeFirstLetter(operationData.type) + (idx + 1) + ' ' + operationData.query.trim().replace(/^(query|mutation|subscription) /i, '') }); } else { return operationData; } }); var getComment = commentsFactory(true, comments); var serverComment = options.server ? getComment('nodeFetch') : ''; var serverImport = options.server ? 'import fetch from "node-fetch";\n' : ''; var graphqlQuery = generateDocumentQuery(operationDataList); var vars = JSON.stringify({}, null, 2); var headersValues = []; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = Object.keys(headers)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var header = _step.value; if (header && headers[header]) { headersValues.push('"' + header + '": "' + headers[header] + '"'); } } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } var heads = headersValues.length ? '' + headersValues.join(',\n') : ''; var requiredDeps = [options.server ? '"node-fetch": "^2.5.0"' : null].filter(Boolean); var packageDeps = requiredDeps.length > 0 ? '/*\nAdd these to your `package.json`:\n' + addLeftWhitespace(requiredDeps.join(',\n'), 2) + '\n*/\n' : ''; var fetcher = options.asyncAwait ? asyncFetcher(serverUrl, heads) : promiseFetcher(serverUrl, heads); var fetcherFunctionsDefs = fetcherFunctions(operationDataList); var fetcherInvocation = options.asyncAwait ? asyncFetcherInvocation(getComment, operationDataList, vars) : promiseFetcherInvocation(getComment, operationDataList, vars); var snippet = '\n/*\nThis is an example snippet - you should consider tailoring it\nto your service.\n*/\n' + packageDeps + '\n' + serverComment + '\n' + serverImport + '\n\n' + fetcher + '\n\n' + graphqlQuery + '\n\n' + fetcherFunctionsDefs + '\n\n' + fetcherInvocation; return collapseExtraNewlines(snippet.trim()); } }; export default snippet;