diff --git a/.circleci/config.yml b/.circleci/config.yml index 7ecc73606..456376308 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -2,13 +2,12 @@ workflows: version: 2 node-multi-build: jobs: - - node-v8 - - node-v10 + - eslint-v6 - eslint-v7 - - eslint-v8 - ts-eslint-v4 - node-v12 - node-v14 + - node-v16 - lint version: 2 @@ -35,9 +34,9 @@ jobs: # paths: # - node_modules - node-v8: + eslint-v6: docker: - - image: node:8 + - image: node:12 steps: - run: name: Versions @@ -46,25 +45,7 @@ jobs: - run: name: Install eslint@6 command: | - npm install --save-exact eslint@6.8.0 @typescript-eslint/parser@3.10.1 typescript@4.0.8 - - run: - name: Install dependencies - command: npm install - - run: - name: Test - command: npm test - node-v10: - docker: - - image: node:10 - steps: - - run: - name: Versions - command: npm version - - checkout - - run: - name: Install eslint@7 and @typescript-eslint/parser@4 - command: | - npm install eslint@7 @typescript-eslint/parser@^4 + npm install --save-exact eslint@6.8.0 - run: name: Install dependencies command: npm install @@ -73,7 +54,7 @@ jobs: command: npm test eslint-v7: docker: - - image: node:10 + - image: node:14 steps: - run: name: Versions @@ -89,24 +70,6 @@ jobs: - run: name: Test command: npm test - eslint-v8: - docker: - - image: node:14 - steps: - - run: - name: Versions - command: npm version - - checkout - - run: - name: Install eslint@8 - command: | - npm install eslint@^8.0.0-0 - - run: - name: Install dependencies - command: npm install - - run: - name: Test - command: npm test ts-eslint-v4: docker: - image: node:14 @@ -116,9 +79,9 @@ jobs: command: npm version - checkout - run: - name: Install @typescript-eslint/parser@4 + name: Install @typescript-eslint/parser@4 eslint@7 command: | - npm install @typescript-eslint/parser@^4 + npm install @typescript-eslint/parser@^4 eslint@7 - run: name: Install dependencies command: npm install @@ -133,6 +96,10 @@ jobs: <<: *node-base docker: - image: node:14 + node-v16: + <<: *node-base + docker: + - image: node:16 lint: docker: @@ -153,5 +120,5 @@ jobs: paths: - node_modules - run: - name: Test + name: Lint command: npm run lint diff --git a/.eslintrc.js b/.eslintrc.js index af1b9e745..3229de98d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -10,7 +10,12 @@ module.exports = { node: true, mocha: true }, - extends: ['plugin:eslint-plugin/recommended', 'prettier'], + extends: [ + 'plugin:eslint-plugin/recommended', + 'prettier', + 'plugin:node-dependencies/recommended', + 'plugin:jsonc/recommended-with-jsonc' + ], plugins: ['eslint-plugin', 'prettier'], rules: { 'accessor-pairs': 2, @@ -142,6 +147,12 @@ module.exports = { 'no-invalid-meta': 'error', 'no-invalid-meta-docs-categories': 'error' } + }, + { + files: ['*.json'], + rules: { + 'prettier/prettier': 'off' + } } ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 2c99a4943..7bb646536 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,7 +6,9 @@ "eslint.validate": [ "javascript", "javascriptreact", - "vue" + "vue", + "json", + "jsonc" ], "typescript.tsdk": "node_modules/typescript/lib", "vetur.validation.script": false, diff --git a/docs/user-guide/README.md b/docs/user-guide/README.md index 1a62fbf71..dc1d6e1e0 100644 --- a/docs/user-guide/README.md +++ b/docs/user-guide/README.md @@ -23,7 +23,7 @@ yarn add -D eslint eslint-plugin-vue ::: tip Requirements - ESLint v6.2.0 and above -- Node.js v8.10.0 and above +- Node.js v12.22.x, v14.17.x, v16.x and above We have started supporting ESLint v8.0.0 beta, but note that beta support will be dropped once the stable version is released. diff --git a/eslint-internal-rules/.eslintrc.json b/eslint-internal-rules/.eslintrc.json index 42c0f65b1..16e3fcf9b 100644 --- a/eslint-internal-rules/.eslintrc.json +++ b/eslint-internal-rules/.eslintrc.json @@ -2,5 +2,13 @@ "rules": { "no-invalid-meta-docs-categories": "error", "no-invalid-meta": "error" - } + }, + "overrides": [ + { + "files": ["*.json"], + "rules": { + "no-invalid-meta": "off" + } + } + ] } diff --git a/lib/rules/no-unsupported-features.js b/lib/rules/no-unsupported-features.js index def5ca3f6..f7d51dce9 100644 --- a/lib/rules/no-unsupported-features.js +++ b/lib/rules/no-unsupported-features.js @@ -137,7 +137,7 @@ module.exports = { * @returns {boolean} `true` if it's supporting. */ function isNotSupportingVersion(aCase) { - return !semverSubset(versionRange, getSemverRange(aCase.supported)) + return !semver.subset(versionRange, getSemverRange(aCase.supported)) } /** @type {TemplateListener} */ @@ -171,208 +171,3 @@ module.exports = { ) } } - -// TODO replace semver.subset() in the major version. -/** - * semver.subset() - * - * We need to use a copy of the semver source code until a major version upgrade. - * - * @see https://github.com/npm/node-semver/blob/e79ac3a450e8bb504e78b8159e3efc70895699b8/ranges/subset.js#L43 - * @license ISC at Isaac Z. Schlueter and Contributors - * https://github.com/npm/node-semver/blob/master/LICENSE - * - * @param {semver.Range} sub - * @param {semver.Range} dom - */ -function semverSubset(sub, dom) { - if (sub === dom) return true - - sub = new semver.Range(sub) - dom = new semver.Range(dom) - let sawNonNull = false - - // eslint-disable-next-line no-labels - OUTER: for (const simpleSub of sub.set) { - for (const simpleDom of dom.set) { - const isSub = simpleSubset(simpleSub, simpleDom) - sawNonNull = sawNonNull || isSub !== null - // eslint-disable-next-line no-labels - if (isSub) continue OUTER - } - if (sawNonNull) return false - } - return true -} - -/** - * @license ISC at Isaac Z. Schlueter and Contributors - * https://github.com/npm/node-semver/blob/master/LICENSE - * @param {readonly semver.Comparator[]} sub - * @param {readonly semver.Comparator[]} dom - */ -function simpleSubset(sub, dom) { - if (sub === dom) return true - - /** - * @param {semver.Comparator} c - */ - function isAny(c) { - return Object.keys(c.semver).length === 0 - } - - if (sub.length === 1 && isAny(sub[0])) { - if (dom.length === 1 && isAny(dom[0])) return true - else sub = [new semver.Comparator('>=0.0.0')] - } - - if (dom.length === 1 && isAny(dom[0])) { - dom = [new semver.Comparator('>=0.0.0')] - } - - const eqSet = new Set() - let gt, lt - for (const c of sub) { - if (c.operator === '>' || c.operator === '>=') gt = higherGT(gt, c) - else if (c.operator === '<' || c.operator === '<=') lt = lowerLT(lt, c) - else eqSet.add(c.semver) - } - - if (eqSet.size > 1) return null - - let gtltComp - if (gt && lt) { - gtltComp = semver.compare(gt.semver, lt.semver) - if (gtltComp > 0) return null - else if (gtltComp === 0 && (gt.operator !== '>=' || lt.operator !== '<=')) - return null - } - - // will iterate one or zero times - for (const eq of eqSet) { - if (gt && !semver.satisfies(eq, String(gt))) return null - - if (lt && !semver.satisfies(eq, String(lt))) return null - - for (const c of dom) { - if (!semver.satisfies(eq, String(c))) return false - } - - return true - } - - let higher, lower - let hasDomLT, hasDomGT - // if the subset has a prerelease, we need a comparator in the superset - // with the same tuple and a prerelease, or it's not a subset - let needDomLTPre = lt && lt.semver.prerelease.length ? lt.semver : false - let needDomGTPre = gt && gt.semver.prerelease.length ? gt.semver : false - // exception: <1.2.3-0 is the same as <1.2.3 - if ( - needDomLTPre && - needDomLTPre.prerelease.length === 1 && - lt && - lt.operator === '<' && - needDomLTPre.prerelease[0] === 0 - ) { - needDomLTPre = false - } - - for (const c of dom) { - hasDomGT = hasDomGT || c.operator === '>' || c.operator === '>=' - hasDomLT = hasDomLT || c.operator === '<' || c.operator === '<=' - if (gt) { - if (needDomGTPre) { - if ( - c.semver.prerelease && - c.semver.prerelease.length && - c.semver.major === needDomGTPre.major && - c.semver.minor === needDomGTPre.minor && - c.semver.patch === needDomGTPre.patch - ) { - needDomGTPre = false - } - } - if (c.operator === '>' || c.operator === '>=') { - higher = higherGT(gt, c) - if (higher === c && higher !== gt) return false - } else if ( - gt.operator === '>=' && - !semver.satisfies(gt.semver, String(c)) - ) - return false - } - if (lt) { - if (needDomLTPre) { - if ( - c.semver.prerelease && - c.semver.prerelease.length && - c.semver.major === needDomLTPre.major && - c.semver.minor === needDomLTPre.minor && - c.semver.patch === needDomLTPre.patch - ) { - needDomLTPre = false - } - } - if (c.operator === '<' || c.operator === '<=') { - lower = lowerLT(lt, c) - if (lower === c && lower !== lt) return false - } else if ( - lt.operator === '<=' && - !semver.satisfies(lt.semver, String(c)) - ) - return false - } - if (!c.operator && (lt || gt) && gtltComp !== 0) return false - } - - // if there was a < or >, and nothing in the dom, then must be false - // UNLESS it was limited by another range in the other direction. - // Eg, >1.0.0 <1.0.1 is still a subset of <2.0.0 - if (gt && hasDomLT && !lt && gtltComp !== 0) return false - - if (lt && hasDomGT && !gt && gtltComp !== 0) return false - - // we needed a prerelease range in a specific tuple, but didn't get one - // then this isn't a subset. eg >=1.2.3-pre is not a subset of >=1.0.0, - // because it includes prereleases in the 1.2.3 tuple - if (needDomGTPre || needDomLTPre) return false - - return true -} - -/** - * @license ISC at Isaac Z. Schlueter and Contributors - * https://github.com/npm/node-semver/blob/master/LICENSE - * @param {semver.Comparator | void} a - * @param {semver.Comparator} b - */ -const higherGT = (a, b) => { - if (!a) return b - const comp = semver.compare(a.semver, b.semver) - return comp > 0 - ? a - : comp < 0 - ? b - : b.operator === '>' && a.operator === '>=' - ? b - : a -} - -/** - * @license ISC at Isaac Z. Schlueter and Contributors - * https://github.com/npm/node-semver/blob/master/LICENSE - * @param {semver.Comparator | void} a - * @param {semver.Comparator} b - */ -const lowerLT = (a, b) => { - if (!a) return b - const comp = semver.compare(a.semver, b.semver) - return comp < 0 - ? a - : comp > 0 - ? b - : b.operator === '<' && a.operator === '<=' - ? b - : a -} diff --git a/package.json b/package.json index 37075adcf..c11a3880c 100644 --- a/package.json +++ b/package.json @@ -48,15 +48,15 @@ "url": "https://github.com/vuejs/eslint-plugin-vue/issues" }, "engines": { - "node": ">=8.10" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "peerDependencies": { "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0" }, "dependencies": { - "eslint-utils": "^2.1.0", + "eslint-utils": "^3.0.0", "natural-compare": "^1.4.0", - "semver": "^6.3.0", + "semver": "^7.3.5", "vue-eslint-parser": "^7.10.0" }, "devDependencies": { @@ -73,6 +73,8 @@ "eslint-config-prettier": "^6.11.0", "eslint-plugin-eslint-plugin": "^3.5.3", "eslint-plugin-import": "^2.20.2", + "eslint-plugin-jsonc": "^1.4.0", + "eslint-plugin-node-dependencies": ">=0.5.0 <1.0.0", "eslint-plugin-prettier": "^3.1.3", "eslint-plugin-vue": "file:.", "espree": "^9.0.0", diff --git a/tests/integrations/eslint-plugin-import/package.json b/tests/integrations/eslint-plugin-import/package.json index 63ba52e00..6de5b12e5 100644 --- a/tests/integrations/eslint-plugin-import/package.json +++ b/tests/integrations/eslint-plugin-import/package.json @@ -8,8 +8,8 @@ "author": "Toru Nagashima (https://github.com/mysticatea)", "license": "MIT", "dependencies": { - "eslint": "~7.0.0", - "eslint-plugin-import": "~2.18.2", + "eslint": "^7.0.0", + "eslint-plugin-import": "~2.23.4", "eslint-plugin-vue": "file:../../.." } } diff --git a/tests/lib/rules/require-expose.js b/tests/lib/rules/require-expose.js index ca78e55b8..64d073c24 100644 --- a/tests/lib/rules/require-expose.js +++ b/tests/lib/rules/require-expose.js @@ -17,16 +17,6 @@ const tester = new RuleTester({ tester.run('require-expose', rule, { valid: [ - { - filename: 'ValidComponent.vue', - code: ` - - ` - }, { filename: 'ValidComponent.vue', code: `