@graphql-inspector/core
Version:
Tooling for GraphQL. Compare GraphQL Schemas, check documents, find breaking changes, find similar types.
54 lines (53 loc) • 2.03 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateTokenCount = calculateTokenCount;
exports.validateTokenCount = validateTokenCount;
const graphql_1 = require("graphql");
const parser_js_1 = require("graphql/language/parser.js");
class ParserWithLexer extends parser_js_1.Parser {
get tokenCount() {
return this.__tokenCount;
}
constructor(source, options) {
super(source, options);
this.__tokenCount = 0;
const lexer = this._lexer;
this._lexer = new Proxy(lexer, {
get: (target, prop, receiver) => {
if (prop === 'advance') {
return () => {
const token = target.advance();
if (token.kind !== graphql_1.TokenKind.EOF) {
this.__tokenCount++;
}
return token;
};
}
return Reflect.get(target, prop, receiver);
},
});
}
}
function calculateTokenCount(args) {
const parser = new ParserWithLexer(args.source);
const document = parser.parseDocument();
let { tokenCount } = parser;
(0, graphql_1.visit)(document, {
FragmentSpread(node) {
const fragmentSource = args.getReferencedFragmentSource(node.name.value);
if (fragmentSource) {
tokenCount += calculateTokenCount({
source: fragmentSource,
getReferencedFragmentSource: args.getReferencedFragmentSource,
});
}
},
});
return tokenCount;
}
function validateTokenCount(args) {
const tokenCount = calculateTokenCount(args);
if (tokenCount > args.maxTokenCount) {
return new graphql_1.GraphQLError(`Query exceeds maximum token count of ${args.maxTokenCount} (actual: ${tokenCount})`, args.document, args.source, args.document.loc?.start ? [args.document.loc.start] : undefined);
}
}
;