From 381277ae3578749414a908c60d577201467e53fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Ribaudo?= Date: Thu, 28 Oct 2021 22:41:55 +0200 Subject: [PATCH] Add ESLint 8 support to `@babel/eslint-parser` (#13782) * Add ESLint 8 support to `@babel/eslint-parser` * Only read eslint version dynamically during dev * Fix tests * Update ESLint * Use ESLint 8 stable * Review * Check * Fix babel config --- babel.config.js | 36 +++ eslint/babel-eslint-parser/package.json | 5 +- .../src/convert/convertAST.cjs | 21 +- .../src/convert/convertTokens.cjs | 45 ++- .../src/utils/eslint-version.cjs | 1 + .../src/worker/configuration.cjs | 4 +- eslint/babel-eslint-parser/test/index.js | 296 ++++++++++++++++-- yarn.lock | 167 +++++++++- 8 files changed, 518 insertions(+), 57 deletions(-) create mode 100644 eslint/babel-eslint-parser/src/utils/eslint-version.cjs diff --git a/babel.config.js b/babel.config.js index 124a101380ce..5ea6cfb229e9 100644 --- a/babel.config.js +++ b/babel.config.js @@ -58,6 +58,7 @@ module.exports = function (api) { let ignoreLib = true; let includeRegeneratorRuntime = false; let needsPolyfillsForOldNode = false; + let dynamicESLintVersionCheck = false; let transformRuntimeOptions; @@ -99,6 +100,8 @@ module.exports = function (api) { needsPolyfillsForOldNode = true; break; case "test-legacy": // In test-legacy environment, we build babel on latest node but test on minimum supported legacy versions + dynamicESLintVersionCheck = true; + // fall through case "production": // Config during builds before publish. targets = { node: nodeVersion }; @@ -107,10 +110,12 @@ module.exports = function (api) { case "test": targets = { node: "current" }; needsPolyfillsForOldNode = true; + dynamicESLintVersionCheck = true; break; case "development": envOpts.debug = true; targets = { node: "current" }; + dynamicESLintVersionCheck = true; break; } @@ -218,6 +223,10 @@ module.exports = function (api) { exclude: /regenerator-runtime/, plugins: [["@babel/transform-runtime", transformRuntimeOptions]], }, + dynamicESLintVersionCheck && { + test: ["./eslint/*/src"].map(normalize), + plugins: [pluginDynamicESLintVersionCheck], + }, ].filter(Boolean), }; @@ -654,3 +663,30 @@ function pluginBabelParserTokenType({ tokenTypesMapping.set(tokenTypesDefinition[i].key.name, i); } })(); + +// Transforms +// ESLINT_VERSION +// to +// process.env.ESLINT_VERSION_FOR_BABEL +// ? parseInt(process.env.ESLINT_VERSION_FOR_BABEL, 10) +// : ESLINT_VERSION +function pluginDynamicESLintVersionCheck({ template }) { + const transformed = new WeakSet(); + + return { + visitor: { + ReferencedIdentifier(path) { + if (path.node.name !== "ESLINT_VERSION") return; + + if (transformed.has(path.node)) return; + transformed.add(path.node); + + path.replaceWith(template.expression.ast` + process.env.ESLINT_VERSION_FOR_BABEL + ? parseInt(process.env.ESLINT_VERSION_FOR_BABEL, 10) + : ${path.node} + `); + }, + }, + }; +} diff --git a/eslint/babel-eslint-parser/package.json b/eslint/babel-eslint-parser/package.json index 18bbab7affe3..4c342f8ff03b 100644 --- a/eslint/babel-eslint-parser/package.json +++ b/eslint/babel-eslint-parser/package.json @@ -28,7 +28,7 @@ }, "peerDependencies": { "@babel/core": ">=7.11.0", - "eslint": ">=7.5.0" + "eslint": "^7.5.0 || ^8.0.0" }, "dependencies": { "eslint-scope": "^5.1.1", @@ -38,6 +38,7 @@ "devDependencies": { "@babel/core": "workspace:^", "dedent": "^0.7.0", - "eslint": "^7.27.0" + "eslint": "^7.27.0", + "eslint-8": "npm:eslint@^8.0.0" } } diff --git a/eslint/babel-eslint-parser/src/convert/convertAST.cjs b/eslint/babel-eslint-parser/src/convert/convertAST.cjs index 85c95052216d..1bc12d077e1d 100644 --- a/eslint/babel-eslint-parser/src/convert/convertAST.cjs +++ b/eslint/babel-eslint-parser/src/convert/convertAST.cjs @@ -1,3 +1,5 @@ +const ESLINT_VERSION = require("../utils/eslint-version.cjs"); + function* it(children) { if (Array.isArray(children)) yield* children; else yield children; @@ -40,7 +42,7 @@ const convertNodesVisitor = { delete node.extra; } - if (node?.loc.identifierName) { + if (node.loc.identifierName) { delete node.loc.identifierName; } @@ -89,6 +91,15 @@ const convertNodesVisitor = { } else { q.loc.end.column += 2; } + + if (ESLINT_VERSION >= 8) { + q.start -= 1; + if (q.tail) { + q.end += 1; + } else { + q.end += 2; + } + } } } }, @@ -117,6 +128,10 @@ function convertProgramNode(ast) { ast.range[1] = lastToken.end; ast.loc.end.line = lastToken.loc.end.line; ast.loc.end.column = lastToken.loc.end.column; + + if (ESLINT_VERSION >= 8) { + ast.end = lastToken.end; + } } } } else { @@ -129,6 +144,10 @@ function convertProgramNode(ast) { if (ast.body && ast.body.length > 0) { ast.loc.start.line = ast.body[0].loc.start.line; ast.range[0] = ast.body[0].start; + + if (ESLINT_VERSION >= 8) { + ast.start = ast.body[0].start; + } } } diff --git a/eslint/babel-eslint-parser/src/convert/convertTokens.cjs b/eslint/babel-eslint-parser/src/convert/convertTokens.cjs index c1c40e68b313..a05a0a09824a 100644 --- a/eslint/babel-eslint-parser/src/convert/convertTokens.cjs +++ b/eslint/babel-eslint-parser/src/convert/convertTokens.cjs @@ -1,3 +1,5 @@ +const ESLINT_VERSION = require("../utils/eslint-version.cjs"); + function convertTemplateType(tokens, tl) { let curlyBrace = null; let templateTokens = []; @@ -190,12 +192,45 @@ function convertToken(token, source, tl) { // Acorn does not have rightAssociative delete token.type.rightAssociative; } - - return token; } module.exports = function convertTokens(tokens, code, tl) { - return convertTemplateType(tokens, tl) - .filter(t => t.type !== "CommentLine" && t.type !== "CommentBlock") - .map(t => convertToken(t, code, tl)); + const result = []; + + const withoutComments = convertTemplateType(tokens, tl).filter( + t => t.type !== "CommentLine" && t.type !== "CommentBlock", + ); + for (let i = 0, { length } = withoutComments; i < length; i++) { + const token = withoutComments[i]; + + if (!process.env.BABEL_8_BREAKING) { + // Babel 8 already produces a single token + + if ( + ESLINT_VERSION >= 8 && + i + 1 < length && + token.type.label === tl.hash + ) { + const nextToken = withoutComments[i + 1]; + + // We must disambiguate private identifier from the hack pipes topic token + if (nextToken.type.label === tl.name && token.end === nextToken.start) { + i++; + + nextToken.type = "PrivateIdentifier"; + nextToken.start -= 1; + nextToken.loc.start.column -= 1; + nextToken.range = [nextToken.start, nextToken.end]; + + result.push(nextToken); + continue; + } + } + } + + convertToken(token, code, tl); + result.push(token); + } + + return result; }; diff --git a/eslint/babel-eslint-parser/src/utils/eslint-version.cjs b/eslint/babel-eslint-parser/src/utils/eslint-version.cjs new file mode 100644 index 000000000000..2afb5fc97550 --- /dev/null +++ b/eslint/babel-eslint-parser/src/utils/eslint-version.cjs @@ -0,0 +1 @@ +module.exports = parseInt(require("eslint/package.json").version, 10); diff --git a/eslint/babel-eslint-parser/src/worker/configuration.cjs b/eslint/babel-eslint-parser/src/worker/configuration.cjs index fe5386fd7f61..28b1294b04fc 100644 --- a/eslint/babel-eslint-parser/src/worker/configuration.cjs +++ b/eslint/babel-eslint-parser/src/worker/configuration.cjs @@ -1,4 +1,5 @@ const babel = require("./babel-core.cjs"); +const ESLINT_VERSION = require("../utils/eslint-version.cjs"); /** * Merge user supplied estree plugin options to default estree plugin options @@ -8,8 +9,7 @@ const babel = require("./babel-core.cjs"); */ function getParserPlugins(babelOptions) { const babelParserPlugins = babelOptions.parserOpts?.plugins ?? []; - // todo: enable classFeatures when it is supported by ESLint - const estreeOptions = { classFeatures: false }; + const estreeOptions = { classFeatures: ESLINT_VERSION >= 8 }; for (const plugin of babelParserPlugins) { if (Array.isArray(plugin) && plugin[0] === "estree") { Object.assign(estreeOptions, plugin[1]); diff --git a/eslint/babel-eslint-parser/test/index.js b/eslint/babel-eslint-parser/test/index.js index 8461dfec1e6f..ff02e22551d2 100644 --- a/eslint/babel-eslint-parser/test/index.js +++ b/eslint/babel-eslint-parser/test/index.js @@ -5,6 +5,16 @@ import { fileURLToPath } from "url"; import { createRequire } from "module"; import { parseForESLint } from "../lib/index.cjs"; +function parseForESLint8(code, options) { + const { ESLINT_VERSION_FOR_BABEL } = process.env; + process.env.ESLINT_VERSION_FOR_BABEL = "8"; + try { + return parseForESLint(code, options); + } finally { + process.env.ESLINT_VERSION_FOR_BABEL = ESLINT_VERSION_FOR_BABEL; + } +} + const dirname = path.dirname(fileURLToPath(import.meta.url)); const BABEL_OPTIONS = { @@ -18,6 +28,8 @@ const PROPS_TO_REMOVE = [ "exportKind", "variance", "typeArguments", + "filename", + "identifierName", ]; function deeplyRemoveProperties(obj, props) { @@ -46,35 +58,61 @@ function deeplyRemoveProperties(obj, props) { } describe("Babel and Espree", () => { - let espree; - - function parseAndAssertSame(code) { + let espree7, espree8; + + const espreeOptions = { + ecmaFeatures: { + // enable JSX parsing + jsx: true, + // enable return in global scope + globalReturn: true, + // enable implied strict mode (if ecmaVersion >= 5) + impliedStrict: true, + // allow experimental object rest/spread + experimentalObjectRestSpread: true, + }, + tokens: true, + loc: true, + range: true, + comment: true, + sourceType: "module", + }; + + function parseAndAssertSame(code, /* optional */ eslintVersion) { code = unpad(code); - const espreeAST = espree.parse(code, { - ecmaFeatures: { - // enable JSX parsing - jsx: true, - // enable return in global scope - globalReturn: true, - // enable implied strict mode (if ecmaVersion >= 5) - impliedStrict: true, - // allow experimental object rest/spread - experimentalObjectRestSpread: true, - }, - tokens: true, - loc: true, - range: true, - comment: true, - ecmaVersion: 2021, - sourceType: "module", - }); - const babelAST = parseForESLint(code, { - eslintVisitorKeys: true, - eslintScopeManager: true, - babelOptions: BABEL_OPTIONS, - }).ast; - deeplyRemoveProperties(babelAST, PROPS_TO_REMOVE); - expect(babelAST).toEqual(espreeAST); + + if (eslintVersion !== 8) { + // ESLint 7 + const espreeAST = espree7.parse(code, { + ...espreeOptions, + ecmaVersion: 2021, + }); + const babelAST = parseForESLint(code, { + eslintVisitorKeys: true, + eslintScopeManager: true, + babelOptions: BABEL_OPTIONS, + }).ast; + + deeplyRemoveProperties(babelAST, PROPS_TO_REMOVE); + expect(babelAST).toEqual(espreeAST); + } + + if (eslintVersion !== 7) { + // ESLint 8 + const espreeAST = espree8.parse(code, { + ...espreeOptions, + ecmaVersion: 2022, + }); + + const babelAST = parseForESLint8(code, { + eslintVisitorKeys: true, + eslintScopeManager: true, + babelOptions: BABEL_OPTIONS, + }).ast; + + deeplyRemoveProperties(babelAST, PROPS_TO_REMOVE); + expect(babelAST).toEqual(espreeAST); + } } beforeAll(() => { @@ -82,11 +120,28 @@ describe("Babel and Espree", () => { // Use the version of Espree that is a dependency of // the version of ESLint we are testing against. - const espreePath = require.resolve("espree", { + const espree7Path = require.resolve("espree", { paths: [path.dirname(require.resolve("eslint"))], }); + const espree8Path = require.resolve("espree", { + paths: [path.dirname(require.resolve("eslint-8"))], + }); - espree = require(espreePath); + espree7 = require(espree7Path); + espree8 = require(espree8Path); + + const espree7pkg = require(require.resolve("espree/package.json", { + paths: [path.dirname(require.resolve("eslint"))], + })); + const espree8pkg = require(require.resolve("espree/package.json", { + paths: [path.dirname(require.resolve("eslint-8"))], + })); + if (!espree7pkg.version.startsWith("7.")) { + throw new Error(`Expected espree 7, but found ${espree7pkg.version}`); + } + if (!espree8pkg.version.startsWith("9.")) { + throw new Error(`Expected espree 9, but found ${espree8pkg.version}`); + } }); describe("compatibility", () => { @@ -381,7 +436,7 @@ describe("Babel and Espree", () => { }); if (process.env.BABEL_8_BREAKING) { - it("hash (token)", () => { + it("private identifier (token) - ESLint 7", () => { const code = "class A { #x }"; const babylonAST = parseForESLint(code, { eslintVisitorKeys: true, @@ -392,8 +447,7 @@ describe("Babel and Espree", () => { expect(babylonAST.tokens[3].value).toEqual("x"); }); } else { - // Espree doesn't support private fields yet - it("hash (token)", () => { + it("hash (token) - ESLint 7", () => { const code = "class A { #x }"; const babylonAST = parseForESLint(code, { eslintVisitorKeys: true, @@ -405,6 +459,18 @@ describe("Babel and Espree", () => { }); } + it("private identifier (token) - ESLint 8", () => { + const code = "class A { #x }"; + const babylonAST = parseForESLint8(code, { + eslintVisitorKeys: true, + eslintScopeManager: true, + babelOptions: BABEL_OPTIONS, + }).ast; + + expect(babylonAST.tokens[3].type).toEqual("PrivateIdentifier"); + expect(babylonAST.tokens[3].value).toEqual("x"); + }); + it("static (token)", () => { const code = ` import { static as foo } from "foo"; @@ -450,6 +516,170 @@ describe("Babel and Espree", () => { expect(classDeclaration.body.body[0].type).toEqual("PropertyDefinition"); }); + it("class fields with ESLint 8", () => { + parseAndAssertSame( + ` + class A { + x = 2; + static #y = 3; + asi + #m() {} + } + `, + 8, + ); + }); + + it("static (token) - ESLint 7", () => { + const code = ` + class A { + static m() {} + static() {} + static x; + static #y; + static; + static = 2; + } + `; + const babylonAST = parseForESLint(code, { + eslintVisitorKeys: true, + eslintScopeManager: true, + babelOptions: BABEL_OPTIONS, + }).ast; + + const staticKw = { type: "Keyword", value: "static" }; + + expect(babylonAST.tokens[3]).toMatchObject(staticKw); + expect(babylonAST.tokens[9]).toMatchObject(staticKw); + expect(babylonAST.tokens[14]).toMatchObject(staticKw); + expect(babylonAST.tokens[17]).toMatchObject(staticKw); + expect( + babylonAST.tokens[process.env.BABEL_8_BREAKING ? 20 : 21], + ).toMatchObject(staticKw); + expect( + babylonAST.tokens[process.env.BABEL_8_BREAKING ? 22 : 23], + ).toMatchObject(staticKw); + }); + + it("static (token) - ESLint 8", () => { + const code = ` + class A { + static m() {} + static() {} + static x; + static #y; + static; + static = 2; + } + `; + const babylonAST = parseForESLint8(code, { + eslintVisitorKeys: true, + eslintScopeManager: true, + babelOptions: BABEL_OPTIONS, + }).ast; + + const staticKw = { type: "Keyword", value: "static" }; + + expect(babylonAST.tokens[3]).toMatchObject(staticKw); + expect(babylonAST.tokens[9]).toMatchObject(staticKw); + expect(babylonAST.tokens[14]).toMatchObject(staticKw); + expect(babylonAST.tokens[17]).toMatchObject(staticKw); + expect(babylonAST.tokens[20]).toMatchObject(staticKw); + expect(babylonAST.tokens[22]).toMatchObject(staticKw); + }); + + if (process.env.BABEL_8_BREAKING) { + it("pipeline # topic token - ESLint 7", () => { + const code = ` + x |> # + y |> #[0] + class A { + #x = y |> + # + z + } + `; + const babylonAST = parseForESLint(code, { + eslintVisitorKeys: true, + eslintScopeManager: true, + babelOptions: { + filename: "test.js", + parserOpts: { + plugins: [ + ["pipelineOperator", { proposal: "hack", topicToken: "#" }], + ], + tokens: true, + }, + }, + }).ast; + + const topicToken = { type: "Punctuator", value: "#" }; + expect(babylonAST.tokens[2]).toMatchObject(topicToken); + expect(babylonAST.tokens[5]).toMatchObject(topicToken); + expect(babylonAST.tokens[16]).toMatchObject(topicToken); + }); + } else { + it("pipeline # topic token - ESLint 7", () => { + const code = ` + x |> # + y |> #[0] + class A { + #x = y |> + # + z + } + `; + const babylonAST = parseForESLint(code, { + eslintVisitorKeys: true, + eslintScopeManager: true, + babelOptions: { + filename: "test.js", + parserOpts: { + plugins: [ + ["pipelineOperator", { proposal: "hack", topicToken: "#" }], + ], + tokens: true, + }, + }, + }).ast; + + const topicToken = { type: "Punctuator", value: "#" }; + expect(babylonAST.tokens[2]).toMatchObject(topicToken); + expect(babylonAST.tokens[5]).toMatchObject(topicToken); + expect(babylonAST.tokens[17]).toMatchObject(topicToken); + }); + } + + it("pipeline # topic token - ESLint 8", () => { + const code = ` + x |> # + y |> #[0] + class A { + #x = y |> + # + z + } + `; + const babylonAST = parseForESLint8(code, { + eslintVisitorKeys: true, + eslintScopeManager: true, + babelOptions: { + filename: "test.js", + parserOpts: { + plugins: [ + ["pipelineOperator", { proposal: "hack", topicToken: "#" }], + ], + tokens: true, + }, + }, + }).ast; + + const topicToken = { type: "Punctuator", value: "#" }; + expect(babylonAST.tokens[2]).toMatchObject(topicToken); + expect(babylonAST.tokens[5]).toMatchObject(topicToken); + expect(babylonAST.tokens[16]).toMatchObject(topicToken); + }); + it("empty program with line comment", () => { parseAndAssertSame("// single comment"); }); diff --git a/yarn.lock b/yarn.lock index 33a241a4ee82..952c37c33e72 100644 --- a/yarn.lock +++ b/yarn.lock @@ -324,12 +324,13 @@ __metadata: "@babel/core": "workspace:^" dedent: ^0.7.0 eslint: ^7.27.0 + eslint-8: "npm:eslint@^8.0.0" eslint-scope: ^5.1.1 eslint-visitor-keys: ^2.1.0 semver: "condition:BABEL_8_BREAKING ? ^7.3.4 : ^6.3.0" peerDependencies: "@babel/core": ">=7.11.0" - eslint: ">=7.5.0" + eslint: ^7.5.0 || ^8.0.0 languageName: unknown linkType: soft @@ -3656,6 +3657,41 @@ __metadata: languageName: node linkType: hard +"@eslint/eslintrc@npm:^1.0.2": + version: 1.0.2 + resolution: "@eslint/eslintrc@npm:1.0.2" + dependencies: + ajv: ^6.12.4 + debug: ^4.3.2 + espree: ^9.0.0 + globals: ^13.9.0 + ignore: ^4.0.6 + import-fresh: ^3.2.1 + js-yaml: ^3.13.1 + minimatch: ^3.0.4 + strip-json-comments: ^3.1.1 + checksum: bc57f1cfb8809552072e8dedf219753972f804c4d3efffbb365946fc1e09218b5e032da91afffee23739f21ecb761e151d72d5058245b5064183735c7a20fffb + languageName: node + linkType: hard + +"@humanwhocodes/config-array@npm:^0.6.0": + version: 0.6.0 + resolution: "@humanwhocodes/config-array@npm:0.6.0" + dependencies: + "@humanwhocodes/object-schema": ^1.2.0 + debug: ^4.1.1 + minimatch: ^3.0.4 + checksum: 1025b07514b7bfd10a05e8b6cb5e6520878e9c8836b3dd0569fc07df29a09e428c2df1e0760b1d461da8ed6f81ca83ecb02e24198f80b0a177a2acbf532e267c + languageName: node + linkType: hard + +"@humanwhocodes/object-schema@npm:^1.2.0": + version: 1.2.0 + resolution: "@humanwhocodes/object-schema@npm:1.2.0" + checksum: 40b75480376de8104d65f7c44a7dd76d30fb57823ca8ba3a3239b2b568323be894d93440578a72fd8e5e2cc3df3577ce0d2f0fe308b990dd51cf35392bf3c9a2 + languageName: node + linkType: hard + "@istanbuljs/load-nyc-config@npm:^1.0.0": version: 1.1.0 resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" @@ -5016,12 +5052,12 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.0.4, acorn@npm:^8.2.4": - version: 8.2.4 - resolution: "acorn@npm:8.2.4" +"acorn@npm:^8.0.4, acorn@npm:^8.2.4, acorn@npm:^8.5.0": + version: 8.5.0 + resolution: "acorn@npm:8.5.0" bin: acorn: bin/acorn - checksum: cb4ffa2746bebd8ea808e98e139e2e497eaa254de45877abea6a2bad4e65a824fc37e23f6d163562b1e4ee12fcc8fa03948986c0a353b314bff78a0327168cb2 + checksum: 2e4c1dbed3da327684863debf31d341bf8882c6893c506653872c00977eee45675feb9129255d6c74c88424d2b20d889ca6de5b39776e5e3cccfc756b3ca1da8 languageName: node linkType: hard @@ -5286,6 +5322,13 @@ __metadata: languageName: node linkType: hard +"argparse@npm:^2.0.1": + version: 2.0.1 + resolution: "argparse@npm:2.0.1" + checksum: 83644b56493e89a254bae05702abf3a1101b4fa4d0ca31df1c9985275a5a5bd47b3c27b7fa0b71098d41114d8ca000e6ed90cad764b306f8a503665e4d517ced + languageName: node + linkType: hard + "arr-diff@npm:^1.0.1": version: 1.1.0 resolution: "arr-diff@npm:1.1.0" @@ -7039,7 +7082,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.0.1, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1": +"debug@npm:4, debug@npm:^4.0.1, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.1, debug@npm:^4.3.2": version: 4.3.2 resolution: "debug@npm:4.3.2" dependencies: @@ -7680,6 +7723,54 @@ __metadata: languageName: node linkType: hard +"eslint-8@npm:eslint@^8.0.0": + version: 8.0.0 + resolution: "eslint@npm:8.0.0" + dependencies: + "@eslint/eslintrc": ^1.0.2 + "@humanwhocodes/config-array": ^0.6.0 + ajv: ^6.10.0 + chalk: ^4.0.0 + cross-spawn: ^7.0.2 + debug: ^4.3.2 + doctrine: ^3.0.0 + enquirer: ^2.3.5 + escape-string-regexp: ^4.0.0 + eslint-scope: ^6.0.0 + eslint-utils: ^3.0.0 + eslint-visitor-keys: ^3.0.0 + espree: ^9.0.0 + esquery: ^1.4.0 + esutils: ^2.0.2 + fast-deep-equal: ^3.1.3 + file-entry-cache: ^6.0.1 + functional-red-black-tree: ^1.0.1 + glob-parent: ^6.0.1 + globals: ^13.6.0 + ignore: ^4.0.6 + import-fresh: ^3.0.0 + imurmurhash: ^0.1.4 + is-glob: ^4.0.0 + js-yaml: ^4.1.0 + json-stable-stringify-without-jsonify: ^1.0.1 + levn: ^0.4.1 + lodash.merge: ^4.6.2 + minimatch: ^3.0.4 + natural-compare: ^1.4.0 + optionator: ^0.9.1 + progress: ^2.0.0 + regexpp: ^3.2.0 + semver: ^7.2.1 + strip-ansi: ^6.0.0 + strip-json-comments: ^3.1.0 + text-table: ^0.2.0 + v8-compile-cache: ^2.0.3 + bin: + eslint: bin/eslint.js + checksum: 68ba2838862782d9cbf6100218cbf0d69873b6d5d1de5860627b5424f067e2145d334810168142452fb93692666aa1cbeb4d0a94eea089a7d54d3ae32e99942c + languageName: node + linkType: hard + "eslint-import-resolver-node@npm:^0.3.4": version: 0.3.4 resolution: "eslint-import-resolver-node@npm:0.3.4" @@ -7794,6 +7885,16 @@ __metadata: languageName: node linkType: hard +"eslint-scope@npm:^6.0.0": + version: 6.0.0 + resolution: "eslint-scope@npm:6.0.0" + dependencies: + esrecurse: ^4.3.0 + estraverse: ^5.2.0 + checksum: 3f1b3578f288c3820f68ad2aae102300e546be8a98a958f515405dc20cc2fe64fda583d364977628bb14fe3d4f96f37de5e9bc5d6eb26bc310da33ba2a677dc3 + languageName: node + linkType: hard + "eslint-utils@npm:^2.0.0, eslint-utils@npm:^2.1.0": version: 2.1.0 resolution: "eslint-utils@npm:2.1.0" @@ -7828,6 +7929,13 @@ __metadata: languageName: node linkType: hard +"eslint-visitor-keys@npm:^3.0.0": + version: 3.0.0 + resolution: "eslint-visitor-keys@npm:3.0.0" + checksum: 352607f367a2e0e2f9f234e40d6d9b34c39399345b8a9f204e1343749ddfae505d8343909cba6c4abc2ca03add4cdc0530af5e98f870ad7183fc2a89458669e5 + languageName: node + linkType: hard + "eslint@npm:^7.27.0": version: 7.27.0 resolution: "eslint@npm:7.27.0" @@ -7888,6 +7996,17 @@ __metadata: languageName: node linkType: hard +"espree@npm:^9.0.0": + version: 9.0.0 + resolution: "espree@npm:9.0.0" + dependencies: + acorn: ^8.5.0 + acorn-jsx: ^5.3.1 + eslint-visitor-keys: ^3.0.0 + checksum: f313c642e35587ce62a419f57ceea47937a719b084c7b31f649d2ca15ed92bc2dde58e2ac4fc381a74364b0db0b97d9cdb2a5d1ca0ccd7483bde9b4b04fe23e8 + languageName: node + linkType: hard + "esprima@npm:^4.0.0, esprima@npm:^4.0.1": version: 4.0.1 resolution: "esprima@npm:4.0.1" @@ -8788,6 +8907,15 @@ fsevents@^1.2.7: languageName: node linkType: hard +"glob-parent@npm:^6.0.1": + version: 6.0.1 + resolution: "glob-parent@npm:6.0.1" + dependencies: + is-glob: ^4.0.1 + checksum: 0468cf300b8c7a483dbd8c031704fa1003331cbc65ded095f768328ed35eec78dd199c224c7436db997569863c0cbc0b7fd7c3cb45508e6134c502be9e691dc5 + languageName: node + linkType: hard + "glob-stream@npm:^6.1.0": version: 6.1.0 resolution: "glob-stream@npm:6.1.0" @@ -8901,12 +9029,12 @@ fsevents@^1.2.7: languageName: node linkType: hard -"globals@npm:^13.6.0": - version: 13.8.0 - resolution: "globals@npm:13.8.0" +"globals@npm:^13.6.0, globals@npm:^13.9.0": + version: 13.11.0 + resolution: "globals@npm:13.11.0" dependencies: type-fest: ^0.20.2 - checksum: acbfcad2b8aeff34d977a2df62bda863d7537e19f5b30cc3452493ce636b5193be9f68da46a53f41875f49052ddd7d550cd2568ecc818ddde3603e30def1fef3 + checksum: e9e5624154261a3e5344d2105a94886c5f2ca48028fa8258cd7b9119c5f00cf2909392817bb2d162c9a1a31b55d9b2c14e8f2271c45a22f77806f5b9322541cf languageName: node linkType: hard @@ -10565,6 +10693,17 @@ fsevents@^1.2.7: languageName: node linkType: hard +"js-yaml@npm:^4.1.0": + version: 4.1.0 + resolution: "js-yaml@npm:4.1.0" + dependencies: + argparse: ^2.0.1 + bin: + js-yaml: bin/js-yaml.js + checksum: c7830dfd456c3ef2c6e355cc5a92e6700ceafa1d14bba54497b34a99f0376cecbb3e9ac14d3e5849b426d5a5140709a66237a8c991c675431271c4ce5504151a + languageName: node + linkType: hard + "jsbn@npm:~0.1.0": version: 0.1.1 resolution: "jsbn@npm:0.1.1" @@ -13056,10 +13195,10 @@ fsevents@^1.2.7: languageName: node linkType: hard -"regexpp@npm:^3.0.0, regexpp@npm:^3.1.0": - version: 3.1.0 - resolution: "regexpp@npm:3.1.0" - checksum: 63bcb2c98d63274774c79bef256e03f716d25f1fa8427267d0302d1436a83fa0d905f4e8a172fdfa99fb4d84833df2fb3bf7da2a1a868f156e913174c32b1139 +"regexpp@npm:^3.0.0, regexpp@npm:^3.1.0, regexpp@npm:^3.2.0": + version: 3.2.0 + resolution: "regexpp@npm:3.2.0" + checksum: a78dc5c7158ad9ddcfe01aa9144f46e192ddbfa7b263895a70a5c6c73edd9ce85faf7c0430e59ac38839e1734e275b9c3de5c57ee3ab6edc0e0b1bdebefccef8 languageName: node linkType: hard