@graphql-tools/webpack-loader
Version:
A set of utils for faster development of GraphQL tools
69 lines (68 loc) • 2.55 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseDocument = void 0;
const graphql_1 = require("@graphql-tools/graphql");
/**
* Strip insignificant whitespace
* Note that this could do a lot more, such as reorder fields etc.
*/
function normalize(str) {
return str.replace(/[\s,]+/g, ' ').trim();
}
// A map docString -> graphql document
const docCache = {};
// A map fragmentName -> [normalized source]
const fragmentSourceMap = {};
function cacheKeyFromFragment(fragment) {
return normalize((0, graphql_1.print)(fragment));
}
/**
* Take a unstripped parsed document (query/mutation or even fragment), and
* check all fragment definitions, checking for name->source uniqueness.
* We also want to make sure only unique fragments exist in the document.
*/
function processFragments(ast) {
const astFragmentMap = {};
const definitions = [];
for (let i = 0; i < ast.definitions.length; i++) {
const fragmentDefinition = ast.definitions[i];
if (fragmentDefinition.kind === graphql_1.Kind.FRAGMENT_DEFINITION) {
const fragmentName = fragmentDefinition.name.value;
const sourceKey = cacheKeyFromFragment(fragmentDefinition);
// We know something about this fragment
if (fragmentSourceMap.hasOwnProperty(fragmentName) && !fragmentSourceMap[fragmentName][sourceKey]) {
fragmentSourceMap[fragmentName][sourceKey] = true;
}
else if (!fragmentSourceMap.hasOwnProperty(fragmentName)) {
fragmentSourceMap[fragmentName] = {};
fragmentSourceMap[fragmentName][sourceKey] = true;
}
if (!astFragmentMap[sourceKey]) {
astFragmentMap[sourceKey] = true;
definitions.push(fragmentDefinition);
}
}
else {
definitions.push(fragmentDefinition);
}
}
ast.definitions = definitions;
return ast;
}
function parseDocument(doc) {
const cacheKey = normalize(doc);
if (docCache[cacheKey]) {
return docCache[cacheKey];
}
const parsed = (0, graphql_1.parse)(doc, {
noLocation: true,
});
if (!parsed || parsed.kind !== 'Document') {
throw new Error('Not a valid GraphQL document.');
}
// check that all "new" fragments inside the documents are consistent with
// existing fragments of the same name
docCache[cacheKey] = processFragments(parsed);
return parsed;
}
exports.parseDocument = parseDocument;