@graphql-eslint/eslint-plugin
Version:
GraphQL plugin for ESLint
97 lines (96 loc) • 4.4 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.processor = void 0;
const path_1 = require("path");
const graphql_tag_pluck_1 = require("@graphql-tools/graphql-tag-pluck");
const utils_1 = require("@graphql-tools/utils");
const graphql_config_js_1 = require("./graphql-config.js");
const utils_js_1 = require("./utils.js");
const blocksMap = new Map();
let onDiskConfig;
let onDiskConfigLoaded = false;
const RELEVANT_KEYWORDS = ['gql', 'graphql', 'GraphQL'];
exports.processor = {
supportsAutofix: true,
preprocess(code, filePath) {
if (!onDiskConfigLoaded) {
onDiskConfig = (0, graphql_config_js_1.loadOnDiskGraphQLConfig)(filePath);
onDiskConfigLoaded = true;
}
let keywords = RELEVANT_KEYWORDS;
const pluckConfig = onDiskConfig === null || onDiskConfig === void 0 ? void 0 : onDiskConfig.getProjectForFile(filePath).extensions.pluckConfig;
if (pluckConfig) {
const { modules = [], globalGqlIdentifierName = ['gql', 'graphql'], gqlMagicComment = 'GraphQL', } = pluckConfig;
keywords = [
...new Set([
...modules.map(({ identifier }) => identifier),
...(0, utils_1.asArray)(globalGqlIdentifierName),
gqlMagicComment,
].filter(utils_js_1.truthy)),
];
}
if (keywords.every(keyword => !code.includes(keyword))) {
return [code];
}
try {
const sources = (0, graphql_tag_pluck_1.gqlPluckFromCodeStringSync)(filePath, code, {
skipIndent: true,
...pluckConfig,
});
const blocks = sources.map(item => ({
filename: 'document.graphql',
text: item.body,
lineOffset: item.locationOffset.line - 1,
// @ts-expect-error -- `index` field exist but show ts error
offset: item.locationOffset.index + 1,
}));
blocksMap.set(filePath, blocks);
return [...blocks, code /* source code must be provided and be last */];
}
catch (error) {
if (error instanceof Error) {
error.message = `[graphql-eslint] Error while preprocessing "${(0, path_1.relative)(utils_js_1.CWD, filePath)}" file\n\n${error.message}`;
}
// eslint-disable-next-line no-console
console.error(error);
// in case of parsing error return code as is
return [code];
}
},
postprocess(messages, filePath) {
const blocks = blocksMap.get(filePath) || [];
for (let i = 0; i < blocks.length; i += 1) {
const { lineOffset, offset } = blocks[i];
for (const message of messages[i] || []) {
const isVueOrSvelte = /\.(vue|svelte)$/.test(filePath);
if (isVueOrSvelte) {
// We can't show correct report location because after processing with
// graphql-tag-pluck location is incorrect, disable fixes as well
delete message.endLine;
delete message.endColumn;
delete message.fix;
delete message.suggestions;
Object.assign(message, utils_js_1.REPORT_ON_FIRST_CHARACTER);
continue;
}
message.line += lineOffset;
// endLine can not exist if only `loc: { start, column }` was provided to context.report
if (typeof message.endLine === 'number') {
message.endLine += lineOffset;
}
if (message.fix) {
message.fix.range[0] += offset;
message.fix.range[1] += offset;
}
for (const suggestion of message.suggestions || []) {
// DO NOT mutate until https://github.com/eslint/eslint/issues/16716
const [start, end] = suggestion.fix.range;
suggestion.fix.range = [start + offset, end + offset];
}
}
}
const result = messages.flat();
// sort eslint/graphql-eslint messages by line/column
return result.sort((a, b) => a.line - b.line || a.column - b.column);
},
};