eslint-plugin-yaml
Version:
128 lines • 16.1 kB
JavaScript
import { valueToEstree } from "estree-util-value-to-estree";
import { loadAll } from "js-yaml";
import { JSHINT as jshint } from "jshint";
import path from "path";
export class YamlProcessor {
/** Map of file paths to their YAML value and warnings. */
parsedFiles = new Map();
// TODO: Implement autofix
supportsAutofix = false;
/** The preprocess method is called by ESLint before the parser is run. */
preprocess(text, path) {
return [{ text, filename: path }];
}
/** Parser for YAML files. */
parseForESLint(code, options) {
// initialize AST
const ast = {
type: "Program",
body: [],
sourceType: "script",
tokens: [],
comments: [],
range: [0, code.length],
loc: {
start: { line: 1, column: 0 },
end: {
line: code.split("\n")?.length ?? 1,
column: code.split("\n")?.slice(-1)?.[0]?.length ?? 0,
},
},
};
try {
// load YAML
const { yamlDocs, warnings } = this.loadYaml(code, options?.filePath);
// build AST
const statement = {
type: "ExpressionStatement",
expression: valueToEstree(yamlDocs),
};
ast.body.push(statement);
// save warnings for postprocess
this.parsedFiles.set(code, {
value: yamlDocs,
messages: warnings.map((warning) => ({
ruleId: "yaml-warning",
severity: 2,
message: warning.message,
source: warning.mark?.buffer,
line: warning.mark?.line ?? 0,
column: warning.mark?.column ?? 0,
})),
});
}
catch (err) {
const { message, mark } = err;
const key = options?.filePath ?? code;
this.parsedFiles.set(key, {
value: [],
messages: [
{
ruleId: "invalid-yaml",
severity: 2,
message,
line: mark?.line ?? 0,
column: mark?.column ?? 0,
},
],
});
}
return { ast };
}
/** The postprocess method is called by ESLint after the parser is run. */
postprocess(_messages, filePath) {
if (!this.isYaml(filePath)) {
return [];
}
let value = this.parsedFiles.get(filePath);
if (value === undefined) {
// search all the keys that end with filePath
const key = Array.from(this.parsedFiles.keys()).find((key) => key.endsWith(filePath));
if (key === undefined) {
return []; // no value found
}
value = this.parsedFiles.get(key);
}
if (value.messages.length > 0) {
this.parsedFiles.delete(filePath);
return value.messages;
}
const errors = value.value.flatMap((yamlDoc) => this.lintJSON(yamlDoc));
const linter_messages = errors.map((error) => {
const { reason, evidence, line, character } = error;
return {
ruleId: "bad-yaml",
severity: 2,
message: reason,
source: evidence,
line,
column: character,
};
});
this.parsedFiles.delete(filePath);
return linter_messages;
}
isYaml(filePath) {
const fileExtension = path.extname(filePath);
return [".yaml", ".yml"].includes(fileExtension);
}
loadYaml(fileContent, filePath) {
const warnings = [];
const yamlDocs = loadAll(fileContent, undefined, {
filename: filePath,
json: false,
onWarning: (exception) => {
warnings.push(exception);
},
});
return { yamlDocs, warnings };
}
lintJSON(yamlDoc) {
const yaml_json = JSON.stringify(yamlDoc, null, 2);
jshint(yaml_json);
const data = jshint.data();
const errors = data?.errors ?? [];
return errors;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiWWFtbFByb2Nlc3Nvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9ZYW1sUHJvY2Vzc29yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQTtBQUMzRCxPQUFPLEVBQUUsT0FBTyxFQUFzQixNQUFNLFNBQVMsQ0FBQTtBQUNyRCxPQUFPLEVBQXNDLE1BQU0sSUFBSSxNQUFNLEVBQUUsTUFBTSxRQUFRLENBQUE7QUFDN0UsT0FBTyxJQUFJLE1BQU0sTUFBTSxDQUFBO0FBY3ZCLE1BQU0sT0FBTyxhQUFhO0lBQ3hCLDBEQUEwRDtJQUNsRCxXQUFXLEdBQUcsSUFBSSxHQUFHLEVBQXVCLENBQUE7SUFFcEQsMEJBQTBCO0lBQ25CLGVBQWUsR0FBRyxLQUFLLENBQUE7SUFFOUIsMEVBQTBFO0lBQ25FLFVBQVUsQ0FBQyxJQUFZLEVBQUUsSUFBVTtRQUN4QyxPQUFPLENBQUMsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUE7SUFDbkMsQ0FBQztJQUVELDZCQUE2QjtJQUN0QixjQUFjLENBQUMsSUFBWSxFQUFFLE9BQTZCO1FBQy9ELGlCQUFpQjtRQUNqQixNQUFNLEdBQUcsR0FBZ0I7WUFDdkIsSUFBSSxFQUFFLFNBQVM7WUFDZixJQUFJLEVBQUUsRUFBRTtZQUNSLFVBQVUsRUFBRSxRQUFRO1lBQ3BCLE1BQU0sRUFBRSxFQUFFO1lBQ1YsUUFBUSxFQUFFLEVBQUU7WUFDWixLQUFLLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUN2QixHQUFHLEVBQUU7Z0JBQ0gsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFO2dCQUM3QixHQUFHLEVBQUU7b0JBQ0gsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxJQUFJLENBQUM7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QUFFLFNBQVMsRUFBRTtZQUMvQyxRQUFRLEVBQUUsUUFBUTtZQUNsQixJQUFJLEVBQUUsS0FBSztZQUNYLFNBQVMsRUFBRSxDQUFDLFNBQVMsRUFBRSxFQUFFO2dCQUN2QixRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFBO1lBQzFCLENBQUM7U0FDRixDQUFDLENBQUE7UUFDRixPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxDQUFBO0lBQy9CLENBQUM7SUFFTyxRQUFRLENBQUMsT0FBa0M7UUFDakQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFBO1FBQ2xELE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUNqQixNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUE7UUFDMUIsTUFBTSxNQUFNLEdBQUcsSUFBSSxFQUFFLE1BQU0sSUFBSSxFQUFFLENBQUE7UUFDakMsT0FBTyxNQUFNLENBQUE7SUFDZixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IExpbnRlciwgQVNUIH0gZnJvbSBcImVzbGludFwiXG5pbXBvcnQgdHlwZSAqIGFzIGVzdHJlZSBmcm9tIFwiZXN0cmVlXCJcbmltcG9ydCB7IHZhbHVlVG9Fc3RyZWUgfSBmcm9tIFwiZXN0cmVlLXV0aWwtdmFsdWUtdG8tZXN0cmVlXCJcbmltcG9ydCB7IGxvYWRBbGwsIHR5cGUgWUFNTEV4Y2VwdGlvbiB9IGZyb20gXCJqcy15YW1sXCJcbmltcG9ydCB7IHR5cGUgTGludEVycm9yIGFzIEpzSGludExpbnRFcnJvcnMsIEpTSElOVCBhcyBqc2hpbnQgfSBmcm9tIFwianNoaW50XCJcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCJcblxuLy8gaXQgc2VlbXMgbWFyayBjYW4gYmUgdW5kZWZpbmVkIGlzc3VlICM2N1xudHlwZSBMb2FkWWFtbEV4Y2VwdGlvbiA9IHtcbiAgbWVzc2FnZTogc3RyaW5nXG4gIG1hcms/OiB7IGJ1ZmZlcjogc3RyaW5nOyBsaW5lOiBudW1iZXI7IGNvbHVtbjogbnVtYmVyIH1cbn1cbnR5cGUgTG9hZFlhbWxWYWx1ZSA9IHtcbiAgdmFsdWU6IHVua25vd25bXVxuICBtZXNzYWdlczogTGludGVyLkxpbnRNZXNzYWdlW11cbn1cblxudHlwZSBQYXRoID0gc3RyaW5nXG5cbmV4cG9ydCBjbGFzcyBZYW1sUHJvY2Vzc29yIGltcGxlbWVudHMgTGludGVyLlByb2Nlc3NvcjxMaW50ZXIuUHJvY2Vzc29yRmlsZT4ge1xuICAvKiogTWFwIG9mIGZpbGUgcGF0aHMgdG8gdGhlaXIgWUFNTCB2YWx1ZSBhbmQgd2FybmluZ3MuICovXG4gIHByaXZhdGUgcGFyc2VkRmlsZXMgPSBuZXcgTWFwPFBhdGgsIExvYWRZYW1sVmFsdWU+KClcblxuICAvLyBUT0RPOiBJbXBsZW1lbnQgYXV0b2ZpeFxuICBwdWJsaWMgc3VwcG9ydHNBdXRvZml4ID0gZmFsc2VcblxuICAvKiogVGhlIHByZXByb2Nlc3MgbWV0aG9kIGlzIGNhbGxlZCBieSBFU0xpbnQgYmVmb3JlIHRoZSBwYXJzZXIgaXMgcnVuLiAqL1xuICBwdWJsaWMgcHJlcHJvY2Vzcyh0ZXh0OiBzdHJpbmcsIHBhdGg6IFBhdGgpOiBMaW50ZXIuUHJvY2Vzc29yRmlsZVtdIHtcbiAgICByZXR1cm4gW3sgdGV4dCwgZmlsZW5hbWU6IHBhdGggfV1cbiAgfVxuXG4gIC8qKiBQYXJzZXIgZm9yIFlBTUwgZmlsZXMuICovXG4gIHB1YmxpYyBwYXJzZUZvckVTTGludChjb2RlOiBzdHJpbmcsIG9wdGlvbnM/OiB7IGZpbGVQYXRoPzogUGF0aCB9KTogTGludGVyLkVTTGludFBhcnNlUmVzdWx0IHtcbiAgICAvLyBpbml0aWFsaXplIEFTVFxuICAgIGNvbnN0IGFzdDogQVNULlByb2dyYW0gPSB7XG4gICAgICB0eXBlOiBcIlByb2dyYW1cIixcbiAgICAgIGJvZHk6IFtdLFxuICAgICAgc291cmNlVHlwZTogXCJzY3JpcHRcIixcbiAgICAgIHRva2VuczogW10sXG4gICAgICBjb21tZW50czogW10sXG4gICAgICByYW5nZTogWzAsIGNvZGUubGVuZ3RoXSxcbiAgICAgIGxvYzoge1xuICAgICAgICBzdGFydDogeyBsaW5lOiAxLCBjb2x1bW46IDAgfSxcbiAgICAgICAgZW5kOiB7XG4gICAgICAgICAgbGluZTogY29kZS5zcGxpdChcIlxcblwiKT8ubGVuZ3RoID8/IDEsXG4gICAgICAgICAgY29sdW1uOiBjb2RlLnNwbGl0KFwiXFxuXCIpPy5zbGljZSgtMSk/LlswXT8ubGVuZ3RoID8/IDAsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICAvLyBsb2FkIFlBTUxcbiAgICAgIGNvbnN0IHsgeWFtbERvY3MsIHdhcm5pbmdzIH0gPSB0aGlzLmxvYWRZYW1sKGNvZGUsIG9wdGlvbnM/LmZpbGVQYXRoKVxuXG4gICAgICAvLyBidWlsZCBBU1RcbiAgICAgIGNvbnN0IHN0YXRlbWVudDogZXN0cmVlLkV4cHJlc3Npb25TdGF0ZW1lbnQgPSB7XG4gICAgICAgIHR5cGU6IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiLFxuICAgICAgICBleHByZXNzaW9uOiB2YWx1ZVRvRXN0cmVlKHlhbWxEb2NzKSxcbiAgICAgIH1cbiAgICAgIGFzdC5ib2R5LnB1c2goc3RhdGVtZW50KVxuXG4gICAgICAvLyBzYXZlIHdhcm5pbmdzIGZvciBwb3N0cHJvY2Vzc1xuICAgICAgdGhpcy5wYXJzZWRGaWxlcy5zZXQoY29kZSwge1xuICAgICAgICB2YWx1ZTogeWFtbERvY3MsXG4gICAgICAgIG1lc3NhZ2VzOiB3YXJuaW5ncy5tYXAoKHdhcm5pbmcpID0+ICh7XG4gICAgICAgICAgcnVsZUlkOiBcInlhbWwtd2FybmluZ1wiLFxuICAgICAgICAgIHNldmVyaXR5OiAyLFxuICAgICAgICAgIG1lc3NhZ2U6IHdhcm5pbmcubWVzc2FnZSxcbiAgICAgICAgICBzb3VyY2U6IHdhcm5pbmcubWFyaz8uYnVmZmVyLFxuICAgICAgICAgIGxpbmU6IHdhcm5pbmcubWFyaz8ubGluZSA/PyAwLFxuICAgICAgICAgIGNvbHVtbjogd2FybmluZy5tYXJrPy5jb2x1bW4gPz8gMCxcbiAgICAgICAgfSkpLFxuICAgICAgfSlcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIGNvbnN0IHsgbWVzc2FnZSwgbWFyayB9ID0gZXJyIGFzIExvYWRZYW1sRXhjZXB0aW9uXG4gICAgICBjb25zdCBrZXkgPSBvcHRpb25zPy5maWxlUGF0aCA/PyBjb2RlXG4gICAgICB0aGlzLnBhcnNlZEZpbGVzLnNldChrZXksIHtcbiAgICAgICAgdmFsdWU6IFtdLFxuICAgICAgICBtZXNzYWdlczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHJ1bGVJZDogXCJpbnZhbGlkLXlhbWxcIixcbiAgICAgICAgICAgIHNldmVyaXR5OiAyLFxuICAgICAgICAgICAgbWVzc2FnZSxcbiAgICAgICAgICAgIGxpbmU6IG1hcms/LmxpbmUgPz8gMCxcbiAgICAgICAgICAgIGNvbHVtbjogbWFyaz8uY29sdW1uID8/IDAsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgcmV0dXJuIHsgYXN0IH1cbiAgfVxuXG4gIC8qKiBUaGUgcG9zdHByb2Nlc3MgbWV0aG9kIGlzIGNhbGxlZCBieSBFU0xpbnQgYWZ0ZXIgdGhlIHBhcnNlciBpcyBydW4uICovXG4gIHB1YmxpYyBwb3N0cHJvY2VzcyhfbWVzc2FnZXM6IExpbnRlci5MaW50TWVzc2FnZVtdW10sIGZpbGVQYXRoOiBQYXRoKTogTGludGVyLkxpbnRNZXNzYWdlW10ge1xuICAgIGlmICghdGhpcy5pc1lhbWwoZmlsZVBhdGgpKSB7XG4gICAgICByZXR1cm4gW11cbiAgICB9XG5cbiAgICBsZXQgdmFsdWUgPSB0aGlzLnBhcnNlZEZpbGVzLmdldChmaWxlUGF0aClcbiAgICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgLy8gc2VhcmNoIGFsbCB0aGUga2V5cyB0aGF0IGVuZCB3aXRoIGZpbGVQYXRoXG4gICAgICBjb25zdCBrZXkgPSBBcnJheS5mcm9tKHRoaXMucGFyc2VkRmlsZXMua2V5cygpKS5maW5kKChrZXkpID0+IGtleS5lbmRzV2l0aChmaWxlUGF0aCkpXG4gICAgICBpZiAoa2V5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIFtdIC8vIG5vIHZhbHVlIGZvdW5kXG4gICAgICB9XG4gICAgICB2YWx1ZSA9IHRoaXMucGFyc2VkRmlsZXMuZ2V0KGtleSkhXG4gICAgfVxuXG4gICAgaWYgKHZhbHVlLm1lc3NhZ2VzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMucGFyc2VkRmlsZXMuZGVsZXRlKGZpbGVQYXRoKVxuICAgICAgcmV0dXJuIHZhbHVlLm1lc3NhZ2VzXG4gICAgfVxuXG4gICAgY29uc3QgZXJyb3JzID0gdmFsdWUudmFsdWUuZmxhdE1hcCgoeWFtbERvYykgPT4gdGhpcy5saW50SlNPTih5YW1sRG9jKSlcbiAgICBjb25zdCBsaW50ZXJfbWVzc2FnZXM6IExpbnRlci5MaW50TWVzc2FnZVtdID0gZXJyb3JzLm1hcCgoZXJyb3IpID0+IHtcbiAgICAgIGNvbnN0IHsgcmVhc29uLCBldmlkZW5jZSwgbGluZSwgY2hhcmFjdGVyIH0gPSBlcnJvclxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcnVsZUlkOiBcImJhZC15YW1sXCIsXG4gICAgICAgIHNldmVyaXR5OiAyLFxuICAgICAgICBtZXNzYWdlOiByZWFzb24sXG4gICAgICAgIHNvdXJjZTogZXZpZGVuY2UsXG4gICAgICAgIGxpbmUsXG4gICAgICAgIGNvbHVtbjogY2hhcmFjdGVyLFxuICAgICAgfVxuICAgIH0pXG5cbiAgICB0aGlzLnBhcnNlZEZpbGVzLmRlbGV0ZShmaWxlUGF0aClcbiAgICByZXR1cm4gbGludGVyX21lc3NhZ2VzXG4gIH1cblxuICBwcml2YXRlIGlzWWFtbChmaWxlUGF0aDogUGF0aCkge1xuICAgIGNvbnN0IGZpbGVFeHRlbnNpb24gPSBwYXRoLmV4dG5hbWUoZmlsZVBhdGgpXG4gICAgcmV0dXJuIFtcIi55YW1sXCIsIFwiLnltbFwiXS5pbmNsdWRlcyhmaWxlRXh0ZW5zaW9uKVxuICB9XG5cbiAgcHJpdmF0ZSBsb2FkWWFtbChmaWxlQ29udGVudDogc3RyaW5nLCBmaWxlUGF0aD86IFBhdGgpIHtcbiAgICBjb25zdCB3YXJuaW5nczogWUFNTEV4Y2VwdGlvbltdID0gW11cbiAgICBjb25zdCB5YW1sRG9jcyA9IGxvYWRBbGwoZmlsZUNvbnRlbnQsIHVuZGVmaW5lZCwge1xuICAgICAgZmlsZW5hbWU6IGZpbGVQYXRoLFxuICAgICAganNvbjogZmFsc2UsXG4gICAgICBvbldhcm5pbmc6IChleGNlcHRpb24pID0+IHtcbiAgICAgICAgd2FybmluZ3MucHVzaChleGNlcHRpb24pXG4gICAgICB9LFxuICAgIH0pXG4gICAgcmV0dXJuIHsgeWFtbERvY3MsIHdhcm5pbmdzIH1cbiAgfVxuXG4gIHByaXZhdGUgbGludEpTT04oeWFtbERvYzogTG9hZFlhbWxWYWx1ZVtcInZhbHVlXCJdWzBdKTogSnNIaW50TGludEVycm9yc1tdIHtcbiAgICBjb25zdCB5YW1sX2pzb24gPSBKU09OLnN0cmluZ2lmeSh5YW1sRG9jLCBudWxsLCAyKVxuICAgIGpzaGludCh5YW1sX2pzb24pXG4gICAgY29uc3QgZGF0YSA9IGpzaGludC5kYXRhKClcbiAgICBjb25zdCBlcnJvcnMgPSBkYXRhPy5lcnJvcnMgPz8gW11cbiAgICByZXR1cm4gZXJyb3JzXG4gIH1cbn1cbiJdfQ==