@graphql-tools/webpack-loader
Version:
A set of utils for faster development of GraphQL tools
86 lines (85 loc) • 3.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = graphqlLoader;
const tslib_1 = require("tslib");
const os_1 = tslib_1.__importDefault(require("os"));
const graphql_1 = require("graphql");
const optimize_1 = require("@graphql-tools/optimize");
const webpack_loader_runtime_1 = require("@graphql-tools/webpack-loader-runtime");
const parser_js_1 = require("./parser.js");
function isSDL(doc) {
return !doc.definitions.some(def => (0, graphql_1.isExecutableDefinitionNode)(def));
}
function expandImports(source, options) {
const lines = source.split(/\r\n|\r|\n/);
let outputCode = options.importHelpers
? `
var useUnique = require('@graphql-tools/webpack-loader-runtime').useUnique;
var unique = useUnique();
`
: `
${webpack_loader_runtime_1.uniqueCode}
`;
lines.some(line => {
if (line[0] === '#' && line.slice(1).split(' ')[0] === 'import') {
const importFile = line.slice(1).split(' ')[1];
const parseDocument = `require(${importFile})`;
const appendDef = `doc.definitions = doc.definitions.concat(unique(${parseDocument}.definitions));`;
outputCode += appendDef + os_1.default.EOL;
}
return line.length !== 0 && line[0] !== '#';
});
return outputCode;
}
function graphqlLoader(source) {
this.cacheable();
// TODO: This should probably use this.getOptions()
const options = this.query || {};
let doc = (0, parser_js_1.parseDocument)(source);
const optimizers = [];
if (options.noDescription) {
optimizers.push(optimize_1.removeDescriptions);
}
if (options.noEmptyNodes) {
optimizers.push(optimize_1.removeEmptyNodes);
}
if (optimizers.length > 0 && isSDL(doc)) {
doc = (0, optimize_1.optimizeDocumentNode)(doc, optimizers);
}
let stringifiedDoc = JSON.stringify(doc);
if (options.replaceKinds) {
for (const identifier in graphql_1.Kind) {
const value = graphql_1.Kind[identifier];
stringifiedDoc = stringifiedDoc.replace(new RegExp(`"kind":"${value}"`, 'g'), `"kind": Kind.${identifier}`);
}
}
const headerCode = `
${options.replaceKinds ? "var Kind = require('graphql/language/kinds');" : ''}
var doc = ${stringifiedDoc};
`;
let outputCode = '';
// Allow multiple query/mutation definitions in a file. This parses out dependencies
// at compile time, and then uses those at load time to create minimal query documents
// We cannot do the latter at compile time due to how the #import code works.
const operationCount = doc.definitions.reduce((accum, op) => {
if (op.kind === graphql_1.Kind.OPERATION_DEFINITION) {
return accum + 1;
}
return accum;
}, 0);
function exportDefaultStatement(identifier) {
if (options.esModule) {
return `export default ${identifier}`;
}
return `module.exports = ${identifier}`;
}
if (operationCount > 1) {
throw new Error('GraphQL Webpack Loader allows only for one GraphQL Operation per file');
}
outputCode += `
${exportDefaultStatement('doc')}
`;
const importOutputCode = expandImports(source, options);
const allCode = [headerCode, importOutputCode, outputCode, ''].join(os_1.default.EOL);
return allCode;
}