graphiql-code-exporter
Version:
Export working code snippets from GraphiQL queries
178 lines (130 loc) • 9.67 kB
JavaScript
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"); } }; }();
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; };
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
import capitalizeFirstLetter from '../../utils/capitalizeFirstLetter';
import commentsFactory from '../../utils/jsCommentsFactory.js';
import { distinct, isOperationNamed, collapseExtraNewlines, addLeftWhitespace } from '../../utils/index.js';
import 'codemirror/mode/jsx/jsx';
var comments = {
setup: 'This setup is only needed once per application'
};
function formatVariableName(operationData) {
var name = operationData.name;
return name.charAt(0).toUpperCase() + name.slice(1).replace(/[A-Z]/g, '_$&').toUpperCase();
}
function operationVariableName(operation) {
var type = operation.type;
return formatVariableName(operation) + '_' + type.toUpperCase();
}
function operationVariables(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 + '}';
var propsBody = params.map(function (param) {
return '"' + param + '": props.' + param;
}).join(', ');
var props = '{' + propsBody + '}';
return { params: params, variables: variables, props: props };
}
function operationComponentName(operationData) {
var type = operationData.type;
var suffix = type === 'query' ? 'Query' : type === 'mutation' ? 'Mutation' : type === 'subscription' ? 'Subscription' : '';
return suffix.length > 0 ? '' + capitalizeFirstLetter(operationData.name) + suffix : capitalizeFirstLetter(operationData.name);
}
function mutationComponent(getComment, options, element, operationData, heads, vars) {
var _operationVariables = operationVariables(operationData),
params = _operationVariables.params,
variables = _operationVariables.variables;
var call = operationData.name + '(' + (params.length === 0 ? '' : '' + variables) + ')';
var onClick = '() => ' + call;
return '<Mutation\n mutation={' + operationVariableName(operationData) + '}' + (heads === '{}' ? '' : '\n context={{ headers: ' + heads + ' }}\n') + '>\n {(' + operationData.name + ', { loading, error, data }) => {\n if (loading) return <' + element + '>Loading</' + element + '>\n\n if (error)\n return (\n <' + element + '>\n Error in ' + operationVariableName(operationData) + '\n {JSON.stringify(error, null, 2)}\n </' + element + '>\n );\n\n const dataEl = data ? (\n <' + element + '>{JSON.stringify(data, null, 2)}</' + element + '>\n ) : null;\n\n return (\n <div>\n {dataEl}\n\n <button onClick={' + onClick + '}>\n Run mutation: ' + operationData.name + '\n </button>\n </div>\n );\n }}\n</Mutation>';
}
var queryComponent = function queryComponent(getComment, options, element, operationData, heads, vars) {
var _operationVariables2 = operationVariables(operationData),
params = _operationVariables2.params,
props = _operationVariables2.props;
return '<Query\n query={' + operationVariableName(operationData) + '}' + (heads === '{}' ? '' : '\n context={{ headers: ' + heads + ' }}') + ' ' + (params.length === 0 ? '' : '\n variables={' + props + '}') + '>\n {({ loading, error, data }) => {\n if (loading) return <' + element + '>Loading</' + element + '>\n if (error)\n return (\n <' + element + '>\n Error in ' + operationVariableName(operationData) + '\n {JSON.stringify(error, null, 2)}\n </' + element + '>\n );\n\n if (data) {\n return (\n <' + element + '>{JSON.stringify(data, null, 2)}</' + element + '>\n )\n }\n }}\n</Query>';
};
var snippet = {
language: 'JavaScript',
codeMirrorMode: 'jsx',
name: 'react-apollo',
options: [{
id: 'client',
label: 'with client setup',
initial: true
}, {
id: 'imports',
label: 'with required imports',
initial: true
}],
generate: function generate(opts) {
var headers = opts.headers,
options = opts.options,
serverUrl = opts.serverUrl;
var getComment = commentsFactory(true, comments);
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 element = options.reactNative ? 'View' : 'pre';
var vars = JSON.stringify({}, null, 2);
var headersValues = [].concat(_toConsumableArray(Object.keys(headers || []))).filter(function (k) {
return headers[k];
}).map(function (k) {
return '"' + k + '": "' + headers[k] + '"';
}).join(',\n');
var heads = '{' + headersValues + '}';
var packageDeps = '/*\n Add these to your `package.json`:\n "apollo-boost": "^0.3.1",\n "graphql": "^14.2.1",\n "graphql-tag": "^2.10.0",\n "react-apollo": "^2.5.5"\n*/\n\n';
var clientSetup = options.client ? getComment('setup') + ';\nconst apolloClient = new ApolloClient({\n cache: new InMemoryCache(),\n link: new HttpLink({\n uri: "' + serverUrl + '",\n }),\n});\n' : '';
var operationTypes = distinct(operationDataList.map(function (operationData) {
return operationData.type;
}));
var imports = [operationTypes.indexOf('query') > -1 ? 'Query' : null, operationTypes.indexOf('mutation') > -1 ? 'Mutation' : null, 'ApolloProvider'].filter(Boolean);
var reactApolloImports = 'import { ' + imports.join(', ') + ' } from "react-apollo";';
var reactImports = 'import React from "react";\nimport ReactDOM from "react-dom";\nimport { ' + (options.client ? 'ApolloClient, ' : '') + 'InMemoryCache, HttpLink } from "apollo-boost";';
var gqlImport = 'import gql from "graphql-tag";';
var generalImports = options.imports ? gqlImport + '\n' + reactImports + '\n' + reactApolloImports : '';
var components = operationDataList.map(function (operationData) {
var componentFn = operationData.type === 'query' ? queryComponent : operationData.type === 'mutation' ? mutationComponent : function () {
return '"We don\'t support ' + operationData.type + ' GraphQL operations yet"';
};
var graphqlOperation = 'const ' + operationVariableName(operationData) + ' = gql`\n' + addLeftWhitespace(operationData.query, 2) + '\n`;';
var component = graphqlOperation + '\n\nconst ' + operationComponentName(operationData) + ' = (props) => {\n return (\n' + addLeftWhitespace(componentFn(
// $FlowFixMe: Add flow type to utils fn
getComment, options, element, operationData, heads, vars), 4) + '\n )\n};';
return component;
}).join('\n\n');
var componentInstantiations = operationDataList.map(function (operationData) {
var _operationVariables3 = operationVariables(operationData),
params = _operationVariables3.params;
var props = params.map(function (param) {
return param + '={' + param + '}';
}).join(' ');
return '<' + operationComponentName(operationData) + ' ' + props + ' />';
}).join('\n');
var variableInstantiations = operationDataList.map(function (operationData) {
var variables = Object.entries(operationData.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');
}).join('\n\n');
var containerComponent = variableInstantiations + '\n\nconst container = (\n <ApolloProvider client={apolloClient}>\n' + addLeftWhitespace(componentInstantiations, 4) + '\n </ApolloProvider>\n);';
var snippet = '\n/* This is an example snippet - you should consider tailoring it\nto your service.\n*/\n' + packageDeps + generalImports + '\n\n' + clientSetup + '\n\n' + components + '\n\n' + containerComponent + '\n\nReactDOM.render(container, document.getElementById("root"));';
return collapseExtraNewlines(snippet.trim());
}
};
export default snippet;