UNPKG

@kendallgassner/eslint-plugin-package-json

Version:

Rules for valid, consistent, and readable package.json files

65 lines (56 loc) 2.09 kB
const parseErrors = {}; const isPackageJson = filePath => filePath.endsWith('/package.json') || filePath === 'package.json'; const forPackageJsonOnly = fn => (source, filePath) => isPackageJson(filePath) ? fn(source, filePath) : []; const leader = `module.exports = `; // turn package.json into a legal JS file function preprocess(source, filePath) { try { JSON.parse(source); } catch (e) { let line = 0; let column = 0; const posDescription = e.message.match(/position\s+(\d+)/); if (posDescription) { const pos = Number(posDescription[1]); const lines = source.slice(0, pos).split('\n'); line += lines.length; const previousLinesLength = lines.slice(0, -1).join('\n').length; column = pos - previousLinesLength; } parseErrors[filePath] = { ruleId: 'package-json/valid-package-def', severity: 2, message: e.message, line, column, nodeType: 'Program' }; // so eslint can point to the line in its own message, put the invalid // JSON in a comment (escaping comment-closing characters!) return ['/*' + source.replace(/\*\//g, '*\\/') + '*/']; } return [leader + source.trim() + ';']; } // the reverse of preprocess: extract AST node representing package object function extractPackageObjectFromAST(ast) { return ast.body[0].expression.right; } function postprocess(errors, filePath) { if (parseErrors[filePath]) { return [parseErrors[filePath]]; } const flat = [].concat(...errors); flat.forEach(({ fix }) => { if (fix) { fix.range = fix.range.map(i => i - leader.length); } }); return flat; } module.exports.preprocess = forPackageJsonOnly(preprocess); module.exports.postprocess = forPackageJsonOnly(postprocess); module.exports.supportsAutofix = true; module.exports.isPackageJson = isPackageJson; module.exports.extractPackageObjectFromAST = extractPackageObjectFromAST;