diff --git a/package.json b/package.json index ae85a446..c5c79f76 100644 --- a/package.json +++ b/package.json @@ -40,6 +40,7 @@ "chalk": "^4.1.0", "cosmiconfig": "^6.0.0", "debug": "^4.3.1", + "eslint-plugin-package-json": "file:./src/eslint", "globby": "^11.0.2", "ignore": "^5.1.8", "is-plain-obj": "^3.0.0", diff --git a/src/eslint/index.js b/src/eslint/index.js new file mode 100644 index 00000000..4565d2e2 --- /dev/null +++ b/src/eslint/index.js @@ -0,0 +1,5 @@ +const rule = require('./rule'); + +module.exports.rules = { + 'package-json': rule, +}; diff --git a/src/eslint/package.json b/src/eslint/package.json new file mode 100644 index 00000000..f39a3f85 --- /dev/null +++ b/src/eslint/package.json @@ -0,0 +1,11 @@ +{ + "name": "eslint-plugin-package-json", + "version": "1.0.0", + "description": "", + "main": "index.js", + "dependencies": { + "npm-package-json-lint": "file:../../" + }, + "author": "", + "license": "ISC" +} diff --git a/src/eslint/parser.js b/src/eslint/parser.js new file mode 100644 index 00000000..3645c65d --- /dev/null +++ b/src/eslint/parser.js @@ -0,0 +1,21 @@ +module.exports = { + parseForESLint(code, {filePath}) { + // We don't have JS, so this AST is for empty JS file + return { + ast: { + type: 'Program', + start: 0, + end: 0, + loc: {start: {line: 1, column: 0}, end: {line: 1, column: 0}}, + range: [0, 0], + body: [], + tokens: [], + comments: [], + }, + services: { + getPackageJson: () => code, + getPath: () => filePath, + }, + }; + }, +}; diff --git a/src/eslint/rule.js b/src/eslint/rule.js new file mode 100644 index 00000000..150b95c4 --- /dev/null +++ b/src/eslint/rule.js @@ -0,0 +1,41 @@ +const {NpmPackageJsonLint} = require('npm-package-json-lint'); + +module.exports = { + meta: { + type: 'problem', + fixable: 'code', + schema: [ + { + type: 'object', + properties: { + rules: { + type: 'object', + additionalProperties: true, + }, + }, + additionalProperties: false, + }, + ], + }, + create(context) { + return { + Program(node) { + const linter = new NpmPackageJsonLint({ + packageJsonObject: JSON.parse(context.parserServices.getPackageJson()), + packageJsonFilePath: context.parserServices.getPath(), + config: context.options[0], + }); + const results = linter.lint(); + + if (results.results.length > 0) { + results.results[0].issues.forEach(({lintMessage, lintId}) => { + context.report({ + node, + message: `(${lintId}) ${lintMessage}`, + }); + }); + } + }, + }; + }, +}; diff --git a/test/integration/eslint/.eslintrc.js b/test/integration/eslint/.eslintrc.js new file mode 100644 index 00000000..5aa90d10 --- /dev/null +++ b/test/integration/eslint/.eslintrc.js @@ -0,0 +1,19 @@ +module.exports = { + root: true, + overrides: [ + { + plugins: ['package-json'], + files: ['**/package.json'], + parser: '../../../src/eslint/parser.js', + rules: { + 'package-json/package-json': ['error', { + rules: { + 'require-name': 'error', + 'require-version': 'error', + 'prefer-alphabetical-scripts': 'error', + } + }], + }, + }, + ], +}; diff --git a/test/integration/eslint/example1/package.json b/test/integration/eslint/example1/package.json new file mode 100644 index 00000000..b2cc7f5f --- /dev/null +++ b/test/integration/eslint/example1/package.json @@ -0,0 +1,10 @@ +{ + "main": "index.js", + "scripts": { + "build": "build script", + "test": "jest", + "start": "node index.js" + }, + "author": "", + "license": "ISC" +}