UNPKG

@graphql-tools/webpack-loader

Version:

A set of utils for faster development of GraphQL tools

69 lines (68 loc) 2.55 kB
"use strict"; 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;