Socket
Socket
Sign inDemoInstall

@rushstack/eslint-patch

Package Overview
Dependencies
Maintainers
3
Versions
35
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@rushstack/eslint-patch - npm Package Compare versions

Comparing version 1.7.2 to 1.8.0

.eslintrc.js

7

lib/_patch-base.d.ts
declare const isModuleResolutionError: (ex: unknown) => boolean;
declare let eslintFolder: string | undefined;
declare const eslintMajorVersion: number;
declare let ConfigArrayFactory: any;
export declare const eslintPackageVersion: string;
declare const ESLINT_MAJOR_VERSION: number;
declare let configArrayFactory: any;
declare let ModuleResolver: {

@@ -11,3 +12,3 @@ resolve: any;

};
export { eslintFolder, ConfigArrayFactory, ModuleResolver, Naming, eslintMajorVersion as ESLINT_MAJOR_VERSION, isModuleResolutionError };
export { eslintFolder, configArrayFactory, ModuleResolver, Naming, ESLINT_MAJOR_VERSION, isModuleResolutionError };
//# sourceMappingURL=_patch-base.d.ts.map
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isModuleResolutionError = exports.ESLINT_MAJOR_VERSION = exports.Naming = exports.ModuleResolver = exports.ConfigArrayFactory = exports.eslintFolder = void 0;
exports.isModuleResolutionError = exports.ESLINT_MAJOR_VERSION = exports.Naming = exports.ModuleResolver = exports.configArrayFactory = exports.eslintFolder = exports.eslintPackageVersion = void 0;
// This is a workaround for https://github.com/eslint/eslint/issues/3458

@@ -12,4 +15,3 @@ //

//
const path = require('path');
const fs = require('fs');
const path_1 = __importDefault(require("path"));
const isModuleResolutionError = (ex) => typeof ex === 'object' && !!ex && 'code' in ex && ex.code === 'MODULE_NOT_FOUND';

@@ -40,6 +42,6 @@ exports.isModuleResolutionError = isModuleResolutionError;

try {
const eslintrcFolder = path.dirname(require.resolve('@eslint/eslintrc/package.json', { paths: [currentModule.path] }));
const eslintrcFolderPath = path_1.default.dirname(require.resolve('@eslint/eslintrc/package.json', { paths: [currentModule.path] }));
// Make sure we actually resolved the module in our call path
// and not some other spurious dependency.
const resolvedEslintrcBundlePath = path.join(eslintrcFolder, 'dist/eslintrc.cjs');
const resolvedEslintrcBundlePath = path_1.default.join(eslintrcFolderPath, 'dist/eslintrc.cjs');
if (resolvedEslintrcBundlePath === currentModule.filename) {

@@ -52,3 +54,3 @@ eslintrcBundlePath = resolvedEslintrcBundlePath;

// up our require stack to look for eslint. All other errors
// are rethrown.
// are re-thrown.
if (!isModuleResolutionError(ex)) {

@@ -64,3 +66,3 @@ throw ex;

try {
const eslintCandidateFolder = path.dirname(require.resolve('eslint/package.json', {
const eslintCandidateFolder = path_1.default.dirname(require.resolve('eslint/package.json', {
paths: [currentModule.path]

@@ -70,3 +72,3 @@ }));

// and not some other spurious dependency.
if (currentModule.filename.startsWith(eslintCandidateFolder + path.sep)) {
if (currentModule.filename.startsWith(eslintCandidateFolder + path_1.default.sep)) {
exports.eslintFolder = eslintFolder = eslintCandidateFolder;

@@ -79,3 +81,3 @@ break;

// up our require stack to look for eslint. All other errors
// are rethrown.
// are re-thrown.
if (!isModuleResolutionError(ex)) {

@@ -98,6 +100,6 @@ throw ex;

try {
const eslintrcFolder = path.dirname(require.resolve('@eslint/eslintrc/package.json', {
const eslintrcFolder = path_1.default.dirname(require.resolve('@eslint/eslintrc/package.json', {
paths: [currentModule.path]
}));
const resolvedConfigArrayFactoryPath = path.join(eslintrcFolder, '/lib/config-array-factory.js');
const resolvedConfigArrayFactoryPath = path_1.default.join(eslintrcFolder, '/lib/config-array-factory.js');
if (resolvedConfigArrayFactoryPath === currentModule.filename) {

@@ -112,3 +114,3 @@ configArrayFactoryPath = resolvedConfigArrayFactoryPath;

// up our require stack to look for eslint. All other errors
// are rethrown.
// are re-thrown.
if (!isModuleResolutionError(ex)) {

@@ -123,6 +125,6 @@ throw ex;

try {
const eslintCandidateFolder = path.dirname(require.resolve('eslint/package.json', {
const eslintCandidateFolder = path_1.default.dirname(require.resolve('eslint/package.json', {
paths: [currentModule.path]
}));
if (path.join(eslintCandidateFolder, 'lib/cli-engine/cli-engine.js') == currentModule.filename) {
if (path_1.default.join(eslintCandidateFolder, 'lib/cli-engine/cli-engine.js') === currentModule.filename) {
exports.eslintFolder = eslintFolder = eslintCandidateFolder;

@@ -153,3 +155,3 @@ break;

if (/[\\/]eslint[\\/]lib[\\/]cli-engine[\\/]config-array-factory\.js$/i.test(currentModule.filename)) {
exports.eslintFolder = eslintFolder = path.join(path.dirname(currentModule.filename), '../..');
exports.eslintFolder = eslintFolder = path_1.default.join(path_1.default.dirname(currentModule.filename), '../..');
configArrayFactoryPath = `${eslintFolder}/lib/cli-engine/config-array-factory`;

@@ -161,3 +163,3 @@ moduleResolverPath = `${eslintFolder}/lib/shared/relative-module-resolver`;

try {
eslintrcFolder = path.dirname(require.resolve('@eslint/eslintrc/package.json', {
eslintrcFolder = path_1.default.dirname(require.resolve('@eslint/eslintrc/package.json', {
paths: [currentModule.path]

@@ -185,26 +187,28 @@ }));

const eslintPackageJsonPath = `${eslintFolder}/package.json`;
const eslintPackageJson = fs.readFileSync(eslintPackageJsonPath).toString();
const eslintPackageObject = JSON.parse(eslintPackageJson);
const eslintPackageVersion = eslintPackageObject.version;
const eslintMajorVersion = parseInt(eslintPackageVersion, 10);
exports.ESLINT_MAJOR_VERSION = eslintMajorVersion;
if (isNaN(eslintMajorVersion)) {
throw new Error(`Unable to parse ESLint version "${eslintPackageVersion}" in file "${eslintPackageJsonPath}"`);
const eslintPackageObject = require(eslintPackageJsonPath);
exports.eslintPackageVersion = eslintPackageObject.version;
const ESLINT_MAJOR_VERSION = parseInt(exports.eslintPackageVersion, 10);
exports.ESLINT_MAJOR_VERSION = ESLINT_MAJOR_VERSION;
if (isNaN(ESLINT_MAJOR_VERSION)) {
throw new Error(`Unable to parse ESLint version "${exports.eslintPackageVersion}" in file "${eslintPackageJsonPath}"`);
}
if (!(eslintMajorVersion >= 6 && eslintMajorVersion <= 8)) {
if (!(ESLINT_MAJOR_VERSION >= 6 && ESLINT_MAJOR_VERSION <= 8)) {
throw new Error('The ESLint patch script has only been tested with ESLint version 6.x, 7.x, and 8.x.' +
` (Your version: ${eslintPackageVersion})\n` +
` (Your version: ${exports.eslintPackageVersion})\n` +
'Consider reporting a GitHub issue:\n' +
'https://github.com/microsoft/rushstack/issues');
}
let ConfigArrayFactory;
if (eslintMajorVersion === 8) {
exports.ConfigArrayFactory = ConfigArrayFactory = require(eslintrcBundlePath).Legacy.ConfigArrayFactory;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let configArrayFactory;
if (ESLINT_MAJOR_VERSION === 8) {
exports.configArrayFactory = configArrayFactory = require(eslintrcBundlePath).Legacy.ConfigArrayFactory;
}
else {
exports.ConfigArrayFactory = ConfigArrayFactory = require(configArrayFactoryPath).ConfigArrayFactory;
exports.configArrayFactory = configArrayFactory = require(configArrayFactoryPath).ConfigArrayFactory;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let ModuleResolver;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let Naming;
if (eslintMajorVersion === 8) {
if (ESLINT_MAJOR_VERSION === 8) {
exports.ModuleResolver = ModuleResolver = require(eslintrcBundlePath).Legacy.ModuleResolver;

@@ -211,0 +215,0 @@ exports.Naming = Naming = require(eslintrcBundlePath).Legacy.naming;

@@ -13,8 +13,9 @@ "use strict";

const _patch_base_1 = require("./_patch-base");
if (!_patch_base_1.ConfigArrayFactory.__loadExtendedShareableConfigPatched) {
_patch_base_1.ConfigArrayFactory.__loadExtendedShareableConfigPatched = true;
const originalLoadExtendedShareableConfig = _patch_base_1.ConfigArrayFactory.prototype._loadExtendedShareableConfig;
if (!_patch_base_1.configArrayFactory.__loadExtendedShareableConfigPatched) {
_patch_base_1.configArrayFactory.__loadExtendedShareableConfigPatched = true;
// eslint-disable-next-line @typescript-eslint/typedef
const originalLoadExtendedShareableConfig = _patch_base_1.configArrayFactory.prototype._loadExtendedShareableConfig;
// Common between ESLint versions
// https://github.com/eslint/eslintrc/blob/242d569020dfe4f561e4503787b99ec016337457/lib/config-array-factory.js#L910
_patch_base_1.ConfigArrayFactory.prototype._loadExtendedShareableConfig = function (extendName) {
_patch_base_1.configArrayFactory.prototype._loadExtendedShareableConfig = function (extendName) {
const originalResolve = _patch_base_1.ModuleResolver.resolve;

@@ -21,0 +22,0 @@ try {

@@ -31,52 +31,52 @@ import type { TSESTree } from '@typescript-eslint/types';

export declare function isStringLiteral(node: TSESTree.Node): node is TSESTree.StringLiteral;
export interface ClassExpressionWithName extends TSESTree.ClassExpression {
export interface IClassExpressionWithName extends TSESTree.ClassExpression {
id: TSESTree.Identifier;
}
export declare function isClassExpressionWithName(node: TSESTree.Node): node is ClassExpressionWithName;
export interface FunctionExpressionWithName extends TSESTree.FunctionExpression {
export declare function isClassExpressionWithName(node: TSESTree.Node): node is IClassExpressionWithName;
export interface IFunctionExpressionWithName extends TSESTree.FunctionExpression {
id: TSESTree.Identifier;
}
export declare function isFunctionExpressionWithName(node: TSESTree.Node): node is FunctionExpressionWithName;
export declare function isFunctionExpressionWithName(node: TSESTree.Node): node is IFunctionExpressionWithName;
export type NormalAnonymousExpression = TSESTree.ArrowFunctionExpression | TSESTree.ClassExpression | TSESTree.FunctionExpression | TSESTree.ObjectExpression;
export declare function isNormalAnonymousExpression(node: TSESTree.Node): node is NormalAnonymousExpression;
export interface NormalAssignmentPattern extends TSESTree.AssignmentPattern {
export interface INormalAssignmentPattern extends TSESTree.AssignmentPattern {
left: TSESTree.Identifier;
}
export declare function isNormalAssignmentPattern(node: TSESTree.Node): node is NormalAssignmentPattern;
export interface NormalClassPropertyDefinition extends TSESTree.PropertyDefinitionNonComputedName {
export declare function isNormalAssignmentPattern(node: TSESTree.Node): node is INormalAssignmentPattern;
export interface INormalClassPropertyDefinition extends TSESTree.PropertyDefinitionNonComputedName {
key: TSESTree.PrivateIdentifier | TSESTree.Identifier;
value: TSESTree.Expression;
}
export declare function isNormalClassPropertyDefinition(node: TSESTree.Node): node is NormalClassPropertyDefinition;
export interface NormalMethodDefinition extends TSESTree.MethodDefinitionNonComputedName {
export declare function isNormalClassPropertyDefinition(node: TSESTree.Node): node is INormalClassPropertyDefinition;
export interface INormalMethodDefinition extends TSESTree.MethodDefinitionNonComputedName {
key: TSESTree.PrivateIdentifier | TSESTree.Identifier;
}
export declare function isNormalMethodDefinition(node: TSESTree.Node): node is NormalMethodDefinition;
export interface NormalObjectProperty extends TSESTree.PropertyNonComputedName {
export declare function isNormalMethodDefinition(node: TSESTree.Node): node is INormalMethodDefinition;
export interface INormalObjectProperty extends TSESTree.PropertyNonComputedName {
key: TSESTree.Identifier;
}
export declare function isNormalObjectProperty(node: TSESTree.Node): node is NormalObjectProperty;
export interface NormalVariableDeclarator extends TSESTree.VariableDeclarator {
export declare function isNormalObjectProperty(node: TSESTree.Node): node is INormalObjectProperty;
export interface INormalVariableDeclarator extends TSESTree.VariableDeclarator {
id: TSESTree.Identifier;
init: TSESTree.Expression;
}
export declare function isNormalVariableDeclarator(node: TSESTree.Node): node is NormalVariableDeclarator;
export interface NormalAssignmentPatternWithAnonymousExpressionAssigned extends NormalAssignmentPattern {
export declare function isNormalVariableDeclarator(node: TSESTree.Node): node is INormalVariableDeclarator;
export interface INormalAssignmentPatternWithAnonymousExpressionAssigned extends INormalAssignmentPattern {
right: NormalAnonymousExpression;
}
export declare function isNormalAssignmentPatternWithAnonymousExpressionAssigned(node: TSESTree.Node): node is NormalAssignmentPatternWithAnonymousExpressionAssigned;
export interface NormalVariableDeclaratorWithAnonymousExpressionAssigned extends NormalVariableDeclarator {
export declare function isNormalAssignmentPatternWithAnonymousExpressionAssigned(node: TSESTree.Node): node is INormalAssignmentPatternWithAnonymousExpressionAssigned;
export interface INormalVariableDeclaratorWithAnonymousExpressionAssigned extends INormalVariableDeclarator {
init: NormalAnonymousExpression;
}
export declare function isNormalVariableDeclaratorWithAnonymousExpressionAssigned(node: TSESTree.Node): node is NormalVariableDeclaratorWithAnonymousExpressionAssigned;
export interface NormalObjectPropertyWithAnonymousExpressionAssigned extends NormalObjectProperty {
export declare function isNormalVariableDeclaratorWithAnonymousExpressionAssigned(node: TSESTree.Node): node is INormalVariableDeclaratorWithAnonymousExpressionAssigned;
export interface INormalObjectPropertyWithAnonymousExpressionAssigned extends INormalObjectProperty {
value: NormalAnonymousExpression;
}
export declare function isNormalObjectPropertyWithAnonymousExpressionAssigned(node: TSESTree.Node): node is NormalObjectPropertyWithAnonymousExpressionAssigned;
export interface NormalClassPropertyDefinitionWithAnonymousExpressionAssigned extends NormalClassPropertyDefinition {
export declare function isNormalObjectPropertyWithAnonymousExpressionAssigned(node: TSESTree.Node): node is INormalObjectPropertyWithAnonymousExpressionAssigned;
export interface INormalClassPropertyDefinitionWithAnonymousExpressionAssigned extends INormalClassPropertyDefinition {
value: NormalAnonymousExpression;
}
export declare function isNormalClassPropertyDefinitionWithAnonymousExpressionAssigned(node: TSESTree.Node): node is NormalClassPropertyDefinitionWithAnonymousExpressionAssigned;
export type NodeWithName = TSESTree.ClassDeclarationWithName | TSESTree.FunctionDeclarationWithName | ClassExpressionWithName | FunctionExpressionWithName | NormalVariableDeclaratorWithAnonymousExpressionAssigned | NormalObjectPropertyWithAnonymousExpressionAssigned | NormalClassPropertyDefinitionWithAnonymousExpressionAssigned | NormalAssignmentPatternWithAnonymousExpressionAssigned | NormalMethodDefinition | TSESTree.TSEnumDeclaration | TSESTree.TSInterfaceDeclaration | TSESTree.TSTypeAliasDeclaration;
export declare function isNormalClassPropertyDefinitionWithAnonymousExpressionAssigned(node: TSESTree.Node): node is INormalClassPropertyDefinitionWithAnonymousExpressionAssigned;
export type NodeWithName = TSESTree.ClassDeclarationWithName | TSESTree.FunctionDeclarationWithName | IClassExpressionWithName | IFunctionExpressionWithName | INormalVariableDeclaratorWithAnonymousExpressionAssigned | INormalObjectPropertyWithAnonymousExpressionAssigned | INormalClassPropertyDefinitionWithAnonymousExpressionAssigned | INormalAssignmentPatternWithAnonymousExpressionAssigned | INormalMethodDefinition | TSESTree.TSEnumDeclaration | TSESTree.TSInterfaceDeclaration | TSESTree.TSTypeAliasDeclaration;
export declare function isNodeWithName(node: TSESTree.Node): node is NodeWithName;
//# sourceMappingURL=ast-guards.d.ts.map

@@ -1,8 +0,24 @@

import { TSESTree } from '@typescript-eslint/types';
/**
* @throws Throws an error if the command to retrieve the root path fails.
* @returns The root path of the monorepo.
*/
export declare function getGitRootPath(): string;
export declare const GitRootPath: string;
import type { TSESTree } from '@typescript-eslint/types';
interface ISuppression {
file: string;
scopeId: string;
rule: string;
}
interface IBulkSuppressionsConfig {
serializedSuppressions: Set<string>;
jsonObject: IBulkSuppressionsJson;
newSerializedSuppressions: Set<string>;
newJsonObject: IBulkSuppressionsJson;
}
interface IBulkSuppressionsJson {
suppressions: ISuppression[];
}
declare const SUPPRESSION_SYMBOL: unique symbol;
interface IProblem {
[SUPPRESSION_SYMBOL]?: {
config: IBulkSuppressionsConfig;
suppression: ISuppression;
serializedSuppression: string;
};
}
export declare function shouldBulkSuppress(params: {

@@ -12,11 +28,16 @@ filename: string;

ruleId: string;
problem: IProblem;
}): boolean;
export declare function onFinish(params: {
filename: string;
}): void;
export declare function BulkSuppressionsPrune(params: {
filename: string;
}): void;
export declare function requireFromPathToLinterJS(importPath: string): any;
export declare function prune(): void;
export declare function write(): void;
export declare function requireFromPathToLinterJS(importPath: string): import('eslint').Linter;
export declare function patchClass<T, U extends T>(originalClass: new () => T, patchedClass: new () => U): void;
/**
* This returns a wrapped version of the "verify" function from ESLint's Linter class
* that postprocesses rule violations that weren't suppressed by comments. This postprocessing
* records suppressions that weren't otherwise suppressed by comments to be used
* by the "suppress" and "prune" commands.
*/
export declare function extendVerifyFunction(originalFn: (this: unknown, ...args: unknown[]) => IProblem[] | undefined): (this: unknown, ...args: unknown[]) => IProblem[] | undefined;
export {};
//# sourceMappingURL=bulk-suppressions-patch.d.ts.map

@@ -31,36 +31,59 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.patchClass = exports.requireFromPathToLinterJS = exports.BulkSuppressionsPrune = exports.onFinish = exports.shouldBulkSuppress = exports.GitRootPath = exports.getGitRootPath = void 0;
const child_process_1 = require("child_process");
exports.extendVerifyFunction = exports.patchClass = exports.requireFromPathToLinterJS = exports.write = exports.prune = exports.shouldBulkSuppress = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const Guards = __importStar(require("./ast-guards"));
const _patch_base_1 = require("../_patch-base");
const constants_1 = require("./constants");
const SUPPRESSIONS_JSON_FILENAME = '.eslint-bulk-suppressions.json';
const ESLINTRC_FILENAMES = [
'.eslintrc.js',
'.eslintrc.cjs'
// Several other filenames are allowed, but this patch requires that it be loaded via a JS config file,
// so we only need to check for the JS-based filenames
];
const SUPPRESSION_SYMBOL = Symbol('suppression');
const IS_RUNNING_IN_VSCODE = process.env[constants_1.VSCODE_PID_ENV_VAR_NAME] !== undefined;
const TEN_SECONDS_MS = 10 * 1000;
const ESLINT_BULK_SUPPRESS_ENV_VAR_VALUE = process.env[constants_1.ESLINT_BULK_SUPPRESS_ENV_VAR_NAME];
const SUPPRESS_ALL_RULES = ESLINT_BULK_SUPPRESS_ENV_VAR_VALUE === '*';
const RULES_TO_SUPPRESS = ESLINT_BULK_SUPPRESS_ENV_VAR_VALUE
? new Set(ESLINT_BULK_SUPPRESS_ENV_VAR_VALUE.split(','))
: undefined;
function getNodeName(node) {
if (!Guards.isNodeWithName(node))
return null;
if (Guards.isClassDeclarationWithName(node))
if (Guards.isClassDeclarationWithName(node)) {
return node.id.name;
if (Guards.isFunctionDeclarationWithName(node))
}
else if (Guards.isFunctionDeclarationWithName(node)) {
return node.id.name;
if (Guards.isClassExpressionWithName(node))
}
else if (Guards.isClassExpressionWithName(node)) {
return node.id.name;
if (Guards.isFunctionExpressionWithName(node))
}
else if (Guards.isFunctionExpressionWithName(node)) {
return node.id.name;
if (Guards.isNormalVariableDeclaratorWithAnonymousExpressionAssigned(node))
}
else if (Guards.isNormalVariableDeclaratorWithAnonymousExpressionAssigned(node)) {
return node.id.name;
if (Guards.isNormalObjectPropertyWithAnonymousExpressionAssigned(node))
}
else if (Guards.isNormalObjectPropertyWithAnonymousExpressionAssigned(node)) {
return node.key.name;
if (Guards.isNormalClassPropertyDefinitionWithAnonymousExpressionAssigned(node))
}
else if (Guards.isNormalClassPropertyDefinitionWithAnonymousExpressionAssigned(node)) {
return node.key.name;
if (Guards.isNormalAssignmentPatternWithAnonymousExpressionAssigned(node))
}
else if (Guards.isNormalAssignmentPatternWithAnonymousExpressionAssigned(node)) {
return node.left.name;
if (Guards.isNormalMethodDefinition(node))
}
else if (Guards.isNormalMethodDefinition(node)) {
return node.key.name;
if (Guards.isTSEnumDeclaration(node))
}
else if (Guards.isTSEnumDeclaration(node)) {
return node.id.name;
if (Guards.isTSInterfaceDeclaration(node))
}
else if (Guards.isTSInterfaceDeclaration(node)) {
return node.id.name;
if (Guards.isTSTypeAliasDeclaration(node))
}
else if (Guards.isTSTypeAliasDeclaration(node)) {
return node.id.name;
return null;
}
}

@@ -71,177 +94,220 @@ function calculateScopeId(node) {

const scopeIdForASTNode = getNodeName(current);
if (scopeIdForASTNode !== null)
if (scopeIdForASTNode !== undefined) {
scopeIds.unshift(scopeIdForASTNode);
}
}
if (scopeIds.length === 0)
if (scopeIds.length === 0) {
return '.';
return '.' + scopeIds.join('.');
}
else {
return '.' + scopeIds.join('.');
}
}
/**
* @throws Throws an error if the command to retrieve the root path fails.
* @returns The root path of the monorepo.
*/
function getGitRootPath() {
const result = (0, child_process_1.spawnSync)('git', ['rev-parse', '--show-toplevel'], { encoding: 'utf-8' });
if (result.status !== 0)
throw new Error(`get root path failed`);
return result.stdout.toString().trim();
const eslintrcPathByFileOrFolderPath = new Map();
function findEslintrcFolderPathForNormalizedFileAbsolutePath(normalizedFilePath) {
const cachedFolderPathForFilePath = eslintrcPathByFileOrFolderPath.get(normalizedFilePath);
if (cachedFolderPathForFilePath) {
return cachedFolderPathForFilePath;
}
const normalizedFileFolderPath = normalizedFilePath.substring(0, normalizedFilePath.lastIndexOf('/'));
const pathsToCache = [normalizedFilePath];
let eslintrcFolderPath;
findEslintrcFileLoop: for (let currentFolder = normalizedFileFolderPath; currentFolder; // 'something'.substring(0, -1) is ''
currentFolder = currentFolder.substring(0, currentFolder.lastIndexOf('/'))) {
const cachedEslintrcFolderPath = eslintrcPathByFileOrFolderPath.get(currentFolder);
if (cachedEslintrcFolderPath) {
return cachedEslintrcFolderPath;
}
pathsToCache.push(currentFolder);
for (const eslintrcFilename of ESLINTRC_FILENAMES) {
if (fs_1.default.existsSync(`${currentFolder}/${eslintrcFilename}`)) {
eslintrcFolderPath = currentFolder;
break findEslintrcFileLoop;
}
}
}
if (eslintrcFolderPath) {
for (const checkedFolder of pathsToCache) {
eslintrcPathByFileOrFolderPath.set(checkedFolder, eslintrcFolderPath);
}
return eslintrcFolderPath;
}
else {
throw new Error(`Cannot locate an ESLint configuration file for ${normalizedFilePath}`);
}
}
exports.getGitRootPath = getGitRootPath;
exports.GitRootPath = getGitRootPath();
function findEslintrcDirectory(fileAbsolutePath) {
for (let currentDir = fileAbsolutePath; currentDir.startsWith(exports.GitRootPath); currentDir = path_1.default.dirname(currentDir))
if (['.eslintrc.js', '.eslintrc.cjs'].some((eslintrc) => fs_1.default.existsSync(path_1.default.join(currentDir, eslintrc))))
return currentDir;
throw new Error('Cannot locate eslintrc');
}
function validateSuppressionsJson(json) {
if (typeof json !== 'object')
if (typeof json !== 'object') {
throw new Error(`Invalid JSON object: ${JSON.stringify(json, null, 2)}`);
if (json === null)
}
if (!json) {
throw new Error('JSON object is null.');
if (!json.hasOwnProperty('suppressions'))
}
const EXPECTED_ROOT_PROPERTY_NAMES = new Set(['suppressions']);
for (const propertyName of Object.getOwnPropertyNames(json)) {
if (!EXPECTED_ROOT_PROPERTY_NAMES.has(propertyName)) {
throw new Error(`Unexpected property name: ${propertyName}`);
}
}
const { suppressions } = json;
if (!suppressions) {
throw new Error('Missing "suppressions" property.');
if (!Array.isArray(json.suppressions))
}
if (!Array.isArray(suppressions)) {
throw new Error('"suppressions" property is not an array.');
if (!json.suppressions.every((suppression) => {
if (typeof suppression !== 'object')
}
const EXPECTED_SUPPRESSION_PROPERTY_NAMES = new Set(['file', 'scopeId', 'rule']);
for (const suppression of suppressions) {
if (typeof suppression !== 'object') {
throw new Error(`Invalid suppression: ${JSON.stringify(suppression, null, 2)}`);
if (suppression === null)
}
if (!suppression) {
throw new Error(`Suppression is null: ${JSON.stringify(suppression, null, 2)}`);
if (!suppression.hasOwnProperty('file'))
throw new Error(`Missing "file" property in suppression: ${JSON.stringify(suppression, null, 2)}`);
if (typeof suppression.file !== 'string')
throw new Error(`"file" property in suppression is not a string: ${JSON.stringify(suppression, null, 2)}`);
if (!suppression.hasOwnProperty('scopeId'))
throw new Error(`Missing "scopeId" property in suppression: ${JSON.stringify(suppression, null, 2)}`);
if (typeof suppression.scopeId !== 'string')
throw new Error(`"scopeId" property in suppression is not a string: ${JSON.stringify(suppression, null, 2)}`);
if (!suppression.hasOwnProperty('rule'))
throw new Error(`Missing "rule" property in suppression: ${JSON.stringify(suppression, null, 2)}`);
if (typeof suppression.rule !== 'string')
throw new Error(`"rule" property in suppression is not a string: ${JSON.stringify(suppression, null, 2)}`);
return true;
})) {
throw new Error(`Invalid suppression in "suppressions" array: ${JSON.stringify(json.suppressions, null, 2)}`);
}
for (const propertyName of Object.getOwnPropertyNames(suppression)) {
if (!EXPECTED_SUPPRESSION_PROPERTY_NAMES.has(propertyName)) {
throw new Error(`Unexpected property name: ${propertyName}`);
}
}
for (const propertyName of EXPECTED_SUPPRESSION_PROPERTY_NAMES) {
if (!suppression.hasOwnProperty(propertyName)) {
throw new Error(`Missing "${propertyName}" property in suppression: ${JSON.stringify(suppression, null, 2)}`);
}
else if (typeof suppression[propertyName] !== 'string') {
throw new Error(`"${propertyName}" property in suppression is not a string: ${JSON.stringify(suppression, null, 2)}`);
}
}
}
return true;
}
function readSuppressionsJson(fileAbsolutePath) {
const eslintrcDirectory = findEslintrcDirectory(fileAbsolutePath);
const suppressionsPath = path_1.default.join(eslintrcDirectory, '.eslint-bulk-suppressions.json');
let suppressionsJson = { suppressions: [] };
try {
const fileContent = fs_1.default.readFileSync(suppressionsPath, 'utf-8');
suppressionsJson = JSON.parse(fileContent);
if (!validateSuppressionsJson(suppressionsJson)) {
console.warn(`Unexpected file content in .eslint-bulk-suppressions.json. JSON expected to be in the following format:
{
suppressions: {
file: string;
scopeId: string;
rule: string;
}[];
}
Please check file content, or delete file if suppressions are no longer needed.
`);
suppressionsJson = { suppressions: [] };
const suppressionsJsonByFolderPath = new Map();
function getSuppressionsConfigForEslintrcFolderPath(eslintrcFolderPath) {
const cachedSuppressionsConfig = suppressionsJsonByFolderPath.get(eslintrcFolderPath);
let shouldLoad;
let suppressionsConfig;
if (cachedSuppressionsConfig) {
shouldLoad = IS_RUNNING_IN_VSCODE && cachedSuppressionsConfig.readTime < Date.now() - TEN_SECONDS_MS;
suppressionsConfig = cachedSuppressionsConfig.suppressionsConfig;
}
else {
shouldLoad = true;
}
if (shouldLoad) {
const suppressionsPath = `${eslintrcFolderPath}/${SUPPRESSIONS_JSON_FILENAME}`;
let rawJsonFile;
try {
rawJsonFile = fs_1.default.readFileSync(suppressionsPath).toString();
}
catch (e) {
// Throw an error if any other error than file not found
if (e.code !== 'ENOENT') {
throw e;
}
}
if (!rawJsonFile) {
suppressionsConfig = {
serializedSuppressions: new Set(),
jsonObject: { suppressions: [] },
newSerializedSuppressions: new Set(),
newJsonObject: { suppressions: [] }
};
}
else {
const jsonObject = JSON.parse(rawJsonFile);
validateSuppressionsJson(jsonObject);
const serializedSuppressions = new Set();
for (const suppression of jsonObject.suppressions) {
serializedSuppressions.add(serializeSuppression(suppression));
}
suppressionsConfig = {
serializedSuppressions,
jsonObject,
newSerializedSuppressions: new Set(),
newJsonObject: { suppressions: [] }
};
}
suppressionsJsonByFolderPath.set(eslintrcFolderPath, { readTime: Date.now(), suppressionsConfig });
}
catch (_a) {
// Do nothing and let JSON.parse() log the error. suppressionsJson will stay as the initialized value.
}
return suppressionsJson;
return suppressionsConfig;
}
function shouldWriteSuppression(fileAbsolutePath, suppression) {
if (process.env.ESLINT_BULK_SUPPRESS === undefined)
return false;
if (isSuppressed(fileAbsolutePath, suppression))
return false;
const rulesToSuppress = process.env.ESLINT_BULK_SUPPRESS.split(',');
if (rulesToSuppress.length === 1 && rulesToSuppress[0] === '*')
return true;
return rulesToSuppress.includes(suppression.rule);
}
function isSuppressed(fileAbsolutePath, suppression) {
const suppressionsJson = readSuppressionsJson(fileAbsolutePath);
return (suppressionsJson.suppressions.find((element) => element.file === suppression.file &&
element.scopeId === suppression.scopeId &&
element.rule === suppression.rule) !== undefined);
}
function insort(array, item, compareFunction) {
const index = array.findIndex((element) => compareFunction(element, item) > 0);
if (index === -1)
array.push(item);
else
array.splice(index, 0, item);
}
function compareSuppressions(a, b) {
if (a.file < b.file)
if (a.file < b.file) {
return -1;
if (a.file > b.file)
}
else if (a.file > b.file) {
return 1;
if (a.scopeId < b.scopeId)
}
else if (a.scopeId < b.scopeId) {
return -1;
if (a.scopeId > b.scopeId)
}
else if (a.scopeId > b.scopeId) {
return 1;
if (a.rule < b.rule)
}
else if (a.rule < b.rule) {
return -1;
if (a.rule > b.rule)
}
else if (a.rule > b.rule) {
return 1;
return 0;
}
else {
return 0;
}
}
function writeSuppressionToFile(fileAbsolutePath, suppression) {
const eslintrcDirectory = findEslintrcDirectory(fileAbsolutePath);
const suppressionsJson = readSuppressionsJson(fileAbsolutePath);
insort(suppressionsJson.suppressions, suppression, compareSuppressions);
const suppressionsPath = path_1.default.join(eslintrcDirectory, '.eslint-bulk-suppressions.json');
fs_1.default.writeFileSync(suppressionsPath, JSON.stringify(suppressionsJson, null, 2));
function writeSuppressionsJsonToFile(eslintrcDirectory, suppressionsConfig) {
suppressionsJsonByFolderPath.set(eslintrcDirectory, { readTime: Date.now(), suppressionsConfig });
const suppressionsPath = `${eslintrcDirectory}/${SUPPRESSIONS_JSON_FILENAME}`;
suppressionsConfig.jsonObject.suppressions.sort(compareSuppressions);
fs_1.default.writeFileSync(suppressionsPath, JSON.stringify(suppressionsConfig.jsonObject, undefined, 2));
}
const usedSuppressions = new Set();
function serializeSuppression(fileAbsolutePath, suppression) {
return `${fileAbsolutePath}|${suppression.file}|${suppression.scopeId}|${suppression.rule}`;
function serializeSuppression({ file, scopeId, rule }) {
return `${file}|${scopeId}|${rule}`;
}
function deserializeSuppression(serializedSuppression) {
const [file, scopeId, rule] = serializedSuppression.split('|');
return { file, scopeId, rule };
}
// One-line insert into the ruleContext report method to prematurely exit if the ESLint problem has been suppressed
function shouldBulkSuppress(params) {
// Use this ENV variable to turn off eslint-bulk-suppressions functionality, default behavior is on
if (process.env.ESLINT_BULK_ENABLE === 'false')
if (process.env[constants_1.ESLINT_BULK_ENABLE_ENV_VAR_NAME] === 'false') {
return false;
const { filename: fileAbsolutePath, currentNode, ruleId: rule } = params;
const eslintrcDirectory = findEslintrcDirectory(fileAbsolutePath);
const fileRelativePath = path_1.default.relative(eslintrcDirectory, fileAbsolutePath);
}
const { filename: fileAbsolutePath, currentNode, ruleId: rule, problem } = params;
const normalizedFileAbsolutePath = fileAbsolutePath.replace(/\\/g, '/');
const eslintrcDirectory = findEslintrcFolderPathForNormalizedFileAbsolutePath(normalizedFileAbsolutePath);
const fileRelativePath = normalizedFileAbsolutePath.substring(eslintrcDirectory.length + 1);
const scopeId = calculateScopeId(currentNode);
const suppression = { file: fileRelativePath, scopeId, rule };
if (shouldWriteSuppression(fileAbsolutePath, suppression)) {
writeSuppressionToFile(fileAbsolutePath, suppression);
const config = getSuppressionsConfigForEslintrcFolderPath(eslintrcDirectory);
const serializedSuppression = serializeSuppression(suppression);
const currentNodeIsSuppressed = config.serializedSuppressions.has(serializedSuppression);
if (currentNodeIsSuppressed || SUPPRESS_ALL_RULES || (RULES_TO_SUPPRESS === null || RULES_TO_SUPPRESS === void 0 ? void 0 : RULES_TO_SUPPRESS.has(suppression.rule))) {
problem[SUPPRESSION_SYMBOL] = {
suppression,
serializedSuppression,
config
};
}
const shouldBulkSuppress = isSuppressed(fileAbsolutePath, suppression);
if (shouldBulkSuppress) {
usedSuppressions.add(serializeSuppression(fileAbsolutePath, suppression));
}
return shouldBulkSuppress;
return process.env[constants_1.ESLINT_BULK_PRUNE_ENV_VAR_NAME] !== '1' && currentNodeIsSuppressed;
}
exports.shouldBulkSuppress = shouldBulkSuppress;
function onFinish(params) {
if (process.env.ESLINT_BULK_PRUNE === 'true') {
BulkSuppressionsPrune(params);
function prune() {
for (const [eslintrcFolderPath, { suppressionsConfig }] of suppressionsJsonByFolderPath) {
if (suppressionsConfig) {
const { newSerializedSuppressions, newJsonObject } = suppressionsConfig;
const newSuppressionsConfig = {
serializedSuppressions: newSerializedSuppressions,
jsonObject: newJsonObject,
newSerializedSuppressions: new Set(),
newJsonObject: { suppressions: [] }
};
writeSuppressionsJsonToFile(eslintrcFolderPath, newSuppressionsConfig);
}
}
}
exports.onFinish = onFinish;
function BulkSuppressionsPrune(params) {
const { filename: fileAbsolutePath } = params;
const suppressionsJson = readSuppressionsJson(fileAbsolutePath);
const newSuppressionsJson = {
suppressions: suppressionsJson.suppressions.filter((suppression) => {
return usedSuppressions.has(serializeSuppression(fileAbsolutePath, suppression));
})
};
const eslintrcDirectory = findEslintrcDirectory(fileAbsolutePath);
const suppressionsPath = path_1.default.join(eslintrcDirectory, '.eslint-bulk-suppressions.json');
fs_1.default.writeFileSync(suppressionsPath, JSON.stringify(newSuppressionsJson, null, 2));
exports.prune = prune;
function write() {
for (const [eslintrcFolderPath, { suppressionsConfig }] of suppressionsJsonByFolderPath) {
if (suppressionsConfig) {
writeSuppressionsJsonToFile(eslintrcFolderPath, suppressionsConfig);
}
}
}
exports.BulkSuppressionsPrune = BulkSuppressionsPrune;
exports.write = write;
// utility function for linter-patch.js to make require statements that use relative paths in linter.js work in linter-patch.js

@@ -252,3 +318,3 @@ function requireFromPathToLinterJS(importPath) {

}
const pathToLinterFolder = path_1.default.join(_patch_base_1.eslintFolder, 'lib', 'linter');
const pathToLinterFolder = `${_patch_base_1.eslintFolder}/lib/linter`;
const moduleAbsolutePath = require.resolve(importPath, { paths: [pathToLinterFolder] });

@@ -260,5 +326,5 @@ return require(moduleAbsolutePath);

// Get all the property names of the patched class prototype
let patchedProperties = Object.getOwnPropertyNames(patchedClass.prototype);
const patchedProperties = Object.getOwnPropertyNames(patchedClass.prototype);
// Loop through all the properties
for (let prop of patchedProperties) {
for (const prop of patchedProperties) {
// Override the property in the original class

@@ -268,5 +334,3 @@ originalClass.prototype[prop] = patchedClass.prototype[prop];

// Handle getters and setters
let descriptors = Object.getOwnPropertyDescriptors(patchedClass.prototype);
for (let prop in descriptors) {
let descriptor = descriptors[prop];
for (const [prop, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(patchedClass.prototype))) {
if (descriptor.get || descriptor.set) {

@@ -278,2 +342,27 @@ Object.defineProperty(originalClass.prototype, prop, descriptor);

exports.patchClass = patchClass;
/**
* This returns a wrapped version of the "verify" function from ESLint's Linter class
* that postprocesses rule violations that weren't suppressed by comments. This postprocessing
* records suppressions that weren't otherwise suppressed by comments to be used
* by the "suppress" and "prune" commands.
*/
function extendVerifyFunction(originalFn) {
return function (...args) {
const problems = originalFn.apply(this, args);
if (problems) {
for (const problem of problems) {
if (problem[SUPPRESSION_SYMBOL]) {
const { serializedSuppression, suppression, config: { newSerializedSuppressions, jsonObject: { suppressions }, newJsonObject: { suppressions: newSuppressions } } } = problem[SUPPRESSION_SYMBOL];
if (!newSerializedSuppressions.has(serializedSuppression)) {
newSerializedSuppressions.add(serializedSuppression);
newSuppressions.push(suppression);
suppressions.push(suppression);
}
}
}
}
return problems;
};
}
exports.extendVerifyFunction = extendVerifyFunction;
//# sourceMappingURL=bulk-suppressions-patch.js.map

@@ -1,2 +0,2 @@

export declare function prune(): void;
export declare function pruneAsync(): Promise<void>;
//# sourceMappingURL=prune.d.ts.map

@@ -5,7 +5,7 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.prune = void 0;
const child_process_1 = require("child_process");
const get_eslint_cli_1 = require("./utils/get-eslint-cli");
exports.pruneAsync = void 0;
const print_help_1 = require("./utils/print-help");
function prune() {
const runEslint_1 = require("./runEslint");
const constants_1 = require("../constants");
async function pruneAsync() {
const args = process.argv.slice(3);

@@ -19,19 +19,6 @@ if (args.includes('--help') || args.includes('-h')) {

}
const eslintCLI = (0, get_eslint_cli_1.getEslintCli)(process.cwd());
const env = Object.assign(Object.assign({}, process.env), { ESLINT_BULK_PRUNE: 'true' });
(0, child_process_1.exec)(`${eslintCLI} . --format=json`, { env }, (error, stdout, stderr) => {
// if errorCount != 0, ESLint will process.exit(1) giving the false impression
// that the exec failed, even though linting errors are to be expected
const eslintOutputWithErrorRegex = /"errorCount":(?!0)\d+/;
const isEslintError = error !== null && error.code === 1 && eslintOutputWithErrorRegex.test(stdout);
if (error && !isEslintError) {
throw new Error(`@rushstack/eslint-bulk execution error: ${error.message}`);
}
if (stderr) {
throw new Error(`@rushstack/eslint-bulk ESLint errors: ${stderr}`);
}
console.log(`@rushstack/eslint-bulk: Successfully pruned unused suppressions in all .eslint-bulk-suppressions.json files under directory ${process.cwd()}`);
});
process.env[constants_1.ESLINT_BULK_PRUNE_ENV_VAR_NAME] = '1';
await (0, runEslint_1.runEslintAsync)(['.'], 'prune');
}
exports.prune = prune;
exports.pruneAsync = pruneAsync;
//# sourceMappingURL=prune.js.map

@@ -22,30 +22,24 @@ "use strict";

const subcommand = process.argv[2];
if (subcommand === 'suppress') {
try {
(0, suppress_1.suppress)();
let processPromise;
switch (subcommand) {
case 'suppress': {
processPromise = (0, suppress_1.suppressAsync)();
break;
}
catch (e) {
if (e instanceof Error) {
console.error(e.message);
process.exit(1);
}
throw e;
case 'prune': {
processPromise = (0, prune_1.pruneAsync)();
break;
}
default: {
console.error('@rushstack/eslint-bulk: Unknown subcommand: ' + subcommand);
process.exit(1);
}
}
else if (subcommand === 'prune') {
try {
(0, prune_1.prune)();
processPromise.catch((e) => {
if (e instanceof Error) {
console.error(e.message);
process.exit(1);
}
catch (e) {
if (e instanceof Error) {
console.error(e.message);
process.exit(1);
}
throw e;
}
}
else {
console.error('@rushstack/eslint-bulk: Unknown subcommand: ' + subcommand);
process.exit(1);
}
throw e;
});
//# sourceMappingURL=start.js.map

@@ -1,2 +0,2 @@

export declare function suppress(): void;
export declare function suppressAsync(): Promise<void>;
//# sourceMappingURL=suppress.d.ts.map

@@ -5,7 +5,7 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.suppress = void 0;
const child_process_1 = require("child_process");
const get_eslint_cli_1 = require("./utils/get-eslint-cli");
exports.suppressAsync = void 0;
const print_help_1 = require("./utils/print-help");
function suppress() {
const runEslint_1 = require("./runEslint");
const constants_1 = require("../constants");
async function suppressAsync() {
const args = process.argv.slice(3);

@@ -36,3 +36,4 @@ if (args.includes('--help') || args.includes('-h')) {

if (parsedArgs.files.length === 0) {
throw new Error('@rushstack/eslint-bulk: Files argument is required. Use glob patterns to specify files or use `.` to suppress all files for the specified rules.');
throw new Error('@rushstack/eslint-bulk: Files argument is required. Use glob patterns to specify files or use ' +
'`.` to suppress all files for the specified rules.');
}

@@ -42,3 +43,2 @@ if (parsedArgs.rules.length === 0 && !parsedArgs.all) {

}
const eslintCLI = (0, get_eslint_cli_1.getEslintCli)(process.cwd());
// Find the index of the last argument that starts with '--'

@@ -52,29 +52,17 @@ const lastOptionIndex = args

}
const env = Object.assign({}, process.env);
if (parsedArgs.all) {
env.ESLINT_BULK_SUPPRESS = '*';
process.env[constants_1.ESLINT_BULK_SUPPRESS_ENV_VAR_NAME] = '*';
}
else if (parsedArgs.rules.length > 0) {
env.ESLINT_BULK_SUPPRESS = parsedArgs.rules.join(',');
process.env[constants_1.ESLINT_BULK_SUPPRESS_ENV_VAR_NAME] = parsedArgs.rules.join(',');
}
(0, child_process_1.exec)(`${eslintCLI} ${parsedArgs.files.join(' ')} --format=json`, { env }, (error, stdout, stderr) => {
// if errorCount != 0, ESLint will process.exit(1) giving the false impression
// that the exec failed, even though linting errors are to be expected
const eslintOutputWithErrorRegex = /"errorCount":(?!0)\d+/;
const isEslintError = error !== null && error.code === 1 && eslintOutputWithErrorRegex.test(stdout);
if (error && !isEslintError) {
throw new Error(`@rushstack/eslint-bulk execution error: ${error.message}`);
}
if (stderr) {
throw new Error(`@rushstack/eslint-bulk ESLint errors: ${stderr}`);
}
if (parsedArgs.all) {
console.log(`@rushstack/eslint-bulk: Successfully suppressed all rules for file(s) ${parsedArgs.files}`);
}
else if (parsedArgs.rules.length > 0) {
console.log(`@rushstack/eslint-bulk: Successfully suppressed rules ${parsedArgs.rules} for file(s) ${parsedArgs.files}`);
}
});
await (0, runEslint_1.runEslintAsync)(parsedArgs.files, 'suppress');
if (parsedArgs.all) {
console.log(`@rushstack/eslint-bulk: Successfully suppressed all rules for file(s) ${parsedArgs.files}`);
}
else if (parsedArgs.rules.length > 0) {
console.log(`@rushstack/eslint-bulk: Successfully suppressed rules ${parsedArgs.rules} for file(s) ${parsedArgs.files}`);
}
}
exports.suppress = suppress;
exports.suppressAsync = suppressAsync;
//# sourceMappingURL=suppress.js.map

@@ -1,2 +0,2 @@

export declare function getEslintCli(packagePath: string): string;
export declare function getEslintPath(packagePath: string): string;
//# sourceMappingURL=get-eslint-cli.d.ts.map

@@ -8,24 +8,43 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getEslintCli = void 0;
exports.getEslintPath = void 0;
const path_1 = __importDefault(require("path"));
const TESTED_VERSIONS = ['8.6.0', '8.7.0', '8.21.0', '8.22.0', '8.23.0', '8.23.1'];
function getEslintCli(packagePath) {
const constants_1 = require("../../constants");
// When this list is updated, update the `eslint-bulk-suppressions-newest-test`
// and/or the `eslint-bulk-suppressions-newest-test` projects' eslint dependencies.
const TESTED_VERSIONS = new Set(['8.6.0', '8.7.0', '8.21.0', '8.22.0', '8.23.0', '8.23.1']);
function getEslintPath(packagePath) {
// Try to find a local ESLint installation, the one that should be listed as a dev dependency in package.json
// and installed in node_modules
try {
const localEslintApiPath = require.resolve('eslint', { paths: [packagePath] });
const localEslintApiPath = require.resolve(constants_1.BULK_SUPPRESSIONS_CLI_ESLINT_PACKAGE_NAME, {
paths: [packagePath]
});
const localEslintPath = path_1.default.dirname(path_1.default.dirname(localEslintApiPath));
const eslintPackageJson = require(path_1.default.join(localEslintPath, 'package.json'));
const localEslintVersion = eslintPackageJson.version;
const eslintExecutable = path_1.default.join(localEslintPath, 'bin', 'eslint.js');
if (!TESTED_VERSIONS.includes(localEslintVersion)) {
const { version: localEslintVersion } = require(`${localEslintPath}/package.json`);
if (!TESTED_VERSIONS.has(localEslintVersion)) {
console.warn('@rushstack/eslint-bulk: Be careful, the installed ESLint version has not been tested with eslint-bulk.');
}
return `node ${eslintExecutable}`;
return localEslintApiPath;
}
catch (e) {
throw new Error('@rushstack/eslint-bulk: eslint is specified as a dev dependency in package.json, but eslint-bulk cannot find it in node_modules.');
try {
const { dependencies, devDependencies } = require(`${packagePath}/package.json`);
if (devDependencies === null || devDependencies === void 0 ? void 0 : devDependencies.eslint) {
throw new Error('@rushstack/eslint-bulk: eslint is specified as a dev dependency in package.json, ' +
'but eslint-bulk cannot find it in node_modules.');
}
else if (dependencies === null || dependencies === void 0 ? void 0 : dependencies.eslint) {
throw new Error('@rushstack/eslint-bulk: eslint is specified as a dependency in package.json, ' +
'but eslint-bulk cannot find it in node_modules.');
}
else {
throw new Error('@rushstack/eslint-bulk: eslint is not specified as a dependency in package.json.');
}
}
catch (e) {
throw new Error("@rushstack/eslint-bulk: This command must be run in the same folder as a project's package.json file.");
}
}
}
exports.getEslintCli = getEslintCli;
exports.getEslintPath = getEslintPath;
//# sourceMappingURL=get-eslint-cli.js.map

@@ -10,7 +10,6 @@ "use strict";

const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
function isCorrectCwd(cwd) {
return fs_1.default.existsSync(path_1.default.join(cwd, '.eslintrc.js')) || fs_1.default.existsSync(path_1.default.join(cwd, '.eslintrc.cjs'));
return fs_1.default.existsSync(`${cwd}/.eslintrc.js`) || fs_1.default.existsSync(`${cwd}/.eslintrc.cjs`);
}
exports.isCorrectCwd = isCorrectCwd;
//# sourceMappingURL=is-correct-cwd.js.map
/**
* Dynamically generate file to properly patch many versions of ESLint
* @param inputFilePath Must be an iteration of https://github.com/eslint/eslint/blob/main/lib/linter/linter.js
* @param outputFilePath Some small changes to linter.js
* @param inputFilePath - Must be an iteration of https://github.com/eslint/eslint/blob/main/lib/linter/linter.js
* @param outputFilePath - Some small changes to linter.js
*/
export declare function generatePatchedFileIfDoesntExist(inputFilePath: string, outputFilePath: string): void;
export declare function generatePatchedLinterJsFileIfDoesNotExist(inputFilePath: string, outputFilePath: string): void;
//# sourceMappingURL=generate-patched-file.d.ts.map

@@ -8,11 +8,13 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.generatePatchedFileIfDoesntExist = void 0;
exports.generatePatchedLinterJsFileIfDoesNotExist = void 0;
const fs_1 = __importDefault(require("fs"));
const constants_1 = require("./constants");
/**
* Dynamically generate file to properly patch many versions of ESLint
* @param inputFilePath Must be an iteration of https://github.com/eslint/eslint/blob/main/lib/linter/linter.js
* @param outputFilePath Some small changes to linter.js
* @param inputFilePath - Must be an iteration of https://github.com/eslint/eslint/blob/main/lib/linter/linter.js
* @param outputFilePath - Some small changes to linter.js
*/
function generatePatchedFileIfDoesntExist(inputFilePath, outputFilePath) {
if (fs_1.default.existsSync(outputFilePath)) {
function generatePatchedLinterJsFileIfDoesNotExist(inputFilePath, outputFilePath) {
const generateEnvVarValue = process.env[constants_1.ESLINT_BULK_FORCE_REGENERATE_PATCH_ENV_VAR_NAME];
if (generateEnvVarValue !== 'true' && generateEnvVarValue !== '1' && fs_1.default.existsSync(outputFilePath)) {
return;

@@ -60,4 +62,4 @@ }

* Returns index of next public method
* @param {number} fromIndex index of inputFile to search if public method still exists
* @returns {number} -1 if public method does not exist or index of next public method
* @param fromIndex - index of inputFile to search if public method still exists
* @returns -1 if public method does not exist or index of next public method
*/

@@ -72,3 +74,3 @@ function getIndexOfNextPublicMethod(fromIndex) {

}
let afterMarkerIndex = rest.indexOf(markerForStartOfClassMethod) + markerForStartOfClassMethod.length;
const afterMarkerIndex = rest.indexOf(markerForStartOfClassMethod) + markerForStartOfClassMethod.length;
const isPublicMethod = rest[afterMarkerIndex] !== '_' &&

@@ -83,6 +85,2 @@ rest[afterMarkerIndex] !== '#' &&

}
/**
* @param {number} indexToScanTo
* @returns {string}
*/
function scanUntilIndex(indexToScanTo) {

@@ -103,3 +101,3 @@ const output = inputFile.substring(inputIndex, indexToScanTo);

// --- BEGIN MONKEY PATCH ---
const bulkSuppressionsPatch = require('../../bulk-suppressions-patch');
const bulkSuppressionsPatch = require(process.env.${constants_1.ESLINT_BULK_PATCH_PATH_ENV_VAR_NAME});
const requireFromPathToLinterJS = bulkSuppressionsPatch.requireFromPathToLinterJS;

@@ -141,76 +139,48 @@ `;

// Match this:
// const ruleContext = Object.freeze(
// Object.assign(Object.create(sharedTraversalContext), {
// id: ruleId,
// options: getRuleOptions(configuredRules[ruleId]),
// report(...args) {
// /*
// * Create a report translator lazily.
// ```
// if (reportTranslator === null) {
// reportTranslator = createReportTranslator({
// ruleId,
// severity,
// sourceCode,
// messageIds,
// disableFixes
// });
// }
// const problem = reportTranslator(...args);
//
// if (problem.fix && !(rule.meta && rule.meta.fixable)) {
// throw new Error("Fixable rules must set the `meta.fixable` property to \"code\" or \"whitespace\".");
// }
// ```
//
// Convert to something like this:
// ```
// if (reportTranslator === null) {
// reportTranslator = createReportTranslator({
// ruleId,
// severity,
// sourceCode,
// messageIds,
// disableFixes
// });
// }
// const problem = reportTranslator(...args);
// // --- BEGIN MONKEY PATCH ---
// if (bulkSuppressionsPatch.shouldBulkSuppress({ filename, currentNode, ruleId })) return;
// // --- END MONKEY PATCH ---
//
// const ruleContext = Object.freeze(
// Object.assign(Object.create(sharedTraversalContext), {
// id: ruleId,
// options: getRuleOptions(configuredRules[ruleId]),
// report(...args) {
// if (bulkSuppressionsPatch.shouldBulkSuppress({ filename, currentNode, ruleId })) return;
// /*
// * Create a report translator lazily.
//
outputFile += scanUntilMarker('const ruleContext = Object.freeze(');
outputFile += scanUntilMarker('report(...args) {');
outputFile += scanUntilNewline();
// if (problem.fix && !(rule.meta && rule.meta.fixable)) {
// throw new Error("Fixable rules must set the `meta.fixable` property to \"code\" or \"whitespace\".");
// }
// ```
outputFile += scanUntilMarker('const problem = reportTranslator(...args);');
outputFile += `
// --- BEGIN MONKEY PATCH ---
if (bulkSuppressionsPatch.shouldBulkSuppress({ filename, currentNode, ruleId })) return;
if (bulkSuppressionsPatch.shouldBulkSuppress({ filename, currentNode, ruleId, problem })) return;
// --- END MONKEY PATCH ---
`;
// Match this:
// nodeQueue.forEach((traversalInfo) => {
// currentNode = traversalInfo.node;
//
// try {
// if (traversalInfo.isEntering) {
// eventGenerator.enterNode(currentNode);
// } else {
// eventGenerator.leaveNode(currentNode);
// }
// } catch (err) {
// err.currentNode = currentNode;
// throw err;
// }
// });
//
// return lintingProblems;
//
// Convert to this:
// nodeQueue.forEach((traversalInfo) => {
// currentNode = traversalInfo.node;
//
// try {
// if (traversalInfo.isEntering) {
// eventGenerator.enterNode(currentNode);
// } else {
// eventGenerator.leaveNode(currentNode);
// }
// } catch (err) {
// err.currentNode = currentNode;
// throw err;
// }
// });
//
// // --- BEGIN MONKEY PATCH ---
// bulkSuppressionsPatch.onFinish({ filename });
// // --- END MONKEY PATCH ---
//
// return lintingProblems;
outputFile += scanUntilMarker('nodeQueue.forEach(traversalInfo => {');
outputFile += scanUntilMarker('});');
outputFile += scanUntilNewline();
outputFile += `
// --- BEGIN MONKEY PATCH ---
bulkSuppressionsPatch.onFinish({ filename });
// --- END MONKEY PATCH ---
`;
outputFile += scanUntilMarker('class Linter {');

@@ -256,3 +226,3 @@ outputFile += scanUntilNewline();

}
exports.generatePatchedFileIfDoesntExist = generatePatchedFileIfDoesntExist;
exports.generatePatchedLinterJsFileIfDoesNotExist = generatePatchedLinterJsFileIfDoesNotExist;
//# sourceMappingURL=generate-patched-file.js.map

@@ -9,2 +9,3 @@ "use strict";

const generate_patched_file_1 = require("./generate-patched-file");
const constants_1 = require("./constants");
if (!_patch_base_1.eslintFolder) {

@@ -14,13 +15,15 @@ console.error('@rushstack/eslint-patch/eslint-bulk-suppressions: Could not find ESLint installation to patch.');

}
if (process.env._RUSHSTACK_ESLINT_BULK_DETECT === 'true') {
(0, path_utils_1.findAndConsoleLogPatchPathCli)(__dirname);
const eslintBulkDetectEnvVarValue = process.env[constants_1.ESLINT_BULK_DETECT_ENV_VAR_NAME];
if (eslintBulkDetectEnvVarValue === 'true' || eslintBulkDetectEnvVarValue === '1') {
(0, path_utils_1.findAndConsoleLogPatchPathCli)();
process.exit(0);
}
const pathToLinterJS = (0, path_utils_1.getPathToLinterJS)();
const nameOfGeneratedPatchFile = (0, path_utils_1.getNameOfGeneratedPatchFile)();
const pathToGeneratedPatch = (0, path_utils_1.getPathToGeneratedPatch)(__dirname, nameOfGeneratedPatchFile);
(0, generate_patched_file_1.generatePatchedFileIfDoesntExist)(pathToLinterJS, pathToGeneratedPatch);
process.env[constants_1.ESLINT_BULK_PATCH_PATH_ENV_VAR_NAME] = require.resolve('./bulk-suppressions-patch');
const pathToGeneratedPatch = (0, path_utils_1.ensurePathToGeneratedPatch)();
(0, generate_patched_file_1.generatePatchedLinterJsFileIfDoesNotExist)(pathToLinterJS, pathToGeneratedPatch);
const { Linter: LinterPatch } = require(pathToGeneratedPatch);
LinterPatch.prototype.verify = (0, bulk_suppressions_patch_1.extendVerifyFunction)(LinterPatch.prototype.verify);
const { Linter } = require(pathToLinterJS);
(0, bulk_suppressions_patch_1.patchClass)(Linter, LinterPatch);
//# sourceMappingURL=index.js.map

@@ -1,5 +0,4 @@

export declare function findAndConsoleLogPatchPathCli(patchPath: string): void;
export declare function findAndConsoleLogPatchPathCli(): void;
export declare function getPathToLinterJS(): string;
export declare function getPathToGeneratedPatch(patchPath: string, nameOfGeneratedPatchFile: string): string;
export declare function getNameOfGeneratedPatchFile(): string;
export declare function ensurePathToGeneratedPatch(): string;
//# sourceMappingURL=path-utils.d.ts.map

@@ -8,8 +8,12 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getNameOfGeneratedPatchFile = exports.getPathToGeneratedPatch = exports.getPathToLinterJS = exports.findAndConsoleLogPatchPathCli = void 0;
exports.ensurePathToGeneratedPatch = exports.getPathToLinterJS = exports.findAndConsoleLogPatchPathCli = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const os_1 = __importDefault(require("os"));
const _patch_base_1 = require("../_patch-base");
function findAndConsoleLogPatchPathCli(patchPath) {
if (process.env._RUSHSTACK_ESLINT_BULK_DETECT !== 'true') {
const constants_1 = require("./constants");
const package_json_1 = __importDefault(require("../../package.json"));
const CURRENT_PACKAGE_VERSION = package_json_1.default.version;
function findAndConsoleLogPatchPathCli() {
const eslintBulkDetectEnvVarValue = process.env[constants_1.ESLINT_BULK_DETECT_ENV_VAR_NAME];
if (eslintBulkDetectEnvVarValue !== 'true' && eslintBulkDetectEnvVarValue !== '1') {
return;

@@ -21,9 +25,9 @@ }

/**
* `@rushtack/eslint`-bulk should report an error if its package.json is older than this number
* `@rushstack/eslint-bulk` should report an error if its package.json is older than this number
*/
minCliVersion: '0.0.0',
/**
* `@rushtack/eslint-bulk` will invoke this entry point
* `@rushstack/eslint-bulk` will invoke this entry point
*/
cliEntryPoint: path_1.default.resolve(patchPath, '..', 'exports', 'eslint-bulk.js')
cliEntryPoint: require.resolve('../exports/eslint-bulk')
};

@@ -37,27 +41,12 @@ console.log(startDelimiter + JSON.stringify(configuration) + endDelimiter);

}
return path_1.default.join(_patch_base_1.eslintFolder, 'lib', 'linter', 'linter.js');
return `${_patch_base_1.eslintFolder}/lib/linter/linter.js`;
}
exports.getPathToLinterJS = getPathToLinterJS;
function getPathToGeneratedPatch(patchPath, nameOfGeneratedPatchFile) {
fs_1.default.mkdirSync(path_1.default.join(patchPath, 'temp', 'patches'), { recursive: true });
const pathToGeneratedPatch = path_1.default.join(patchPath, 'temp', 'patches', nameOfGeneratedPatchFile);
function ensurePathToGeneratedPatch() {
const patchesFolderPath = `${os_1.default.tmpdir()}/rushstack-eslint-bulk-${CURRENT_PACKAGE_VERSION}/patches`;
fs_1.default.mkdirSync(patchesFolderPath, { recursive: true });
const pathToGeneratedPatch = `${patchesFolderPath}/linter-patch-v${_patch_base_1.eslintPackageVersion}.js`;
return pathToGeneratedPatch;
}
exports.getPathToGeneratedPatch = getPathToGeneratedPatch;
function getEslintPackageVersion() {
if (!_patch_base_1.eslintFolder) {
throw new Error('Cannot find ESLint installation to patch.');
}
const eslintPackageJsonPath = path_1.default.join(_patch_base_1.eslintFolder, 'package.json');
const eslintPackageJson = fs_1.default.readFileSync(eslintPackageJsonPath).toString();
const eslintPackageObject = JSON.parse(eslintPackageJson);
const eslintPackageVersion = eslintPackageObject.version;
return eslintPackageVersion;
}
function getNameOfGeneratedPatchFile() {
const eslintPackageVersion = getEslintPackageVersion();
const nameOfGeneratedPatchFile = `linter-patch-v${eslintPackageVersion}.js`;
return nameOfGeneratedPatchFile;
}
exports.getNameOfGeneratedPatchFile = getNameOfGeneratedPatchFile;
exports.ensurePathToGeneratedPatch = ensurePathToGeneratedPatch;
//# sourceMappingURL=path-utils.js.map

@@ -0,1 +1,2 @@

import '../eslint-bulk-suppressions/cli/start';
//# sourceMappingURL=eslint-bulk.d.ts.map
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
// "lib/exports/eslint-bulk" is the entry point for the @rushstack/eslint-bulk command line front end.
require('../eslint-bulk-suppressions/cli/start');
require("../eslint-bulk-suppressions/cli/start");
//# sourceMappingURL=eslint-bulk.js.map

@@ -14,9 +14,10 @@ "use strict";

const isInvalidImporterPath = (ex) => (ex === null || ex === void 0 ? void 0 : ex.code) === 'ERR_INVALID_ARG_VALUE';
if (!_patch_base_1.ConfigArrayFactory.__loadPluginPatched) {
_patch_base_1.ConfigArrayFactory.__loadPluginPatched = true;
const originalLoadPlugin = _patch_base_1.ConfigArrayFactory.prototype._loadPlugin;
if (!_patch_base_1.configArrayFactory.__loadPluginPatched) {
_patch_base_1.configArrayFactory.__loadPluginPatched = true;
// eslint-disable-next-line @typescript-eslint/typedef
const originalLoadPlugin = _patch_base_1.configArrayFactory.prototype._loadPlugin;
if (_patch_base_1.ESLINT_MAJOR_VERSION === 6) {
// ESLint 6.x
// https://github.com/eslint/eslint/blob/9738f8cc864d769988ccf42bb70f524444df1349/lib/cli-engine/config-array-factory.js#L915
_patch_base_1.ConfigArrayFactory.prototype._loadPlugin = function (name, importerPath, importerName) {
_patch_base_1.configArrayFactory.prototype._loadPlugin = function (name, importerPath, importerName) {
const originalResolve = _patch_base_1.ModuleResolver.resolve;

@@ -46,3 +47,3 @@ try {

// https://github.com/eslint/eslintrc/blob/242d569020dfe4f561e4503787b99ec016337457/lib/config-array-factory.js#L1023
_patch_base_1.ConfigArrayFactory.prototype._loadPlugin = function (name, ctx) {
_patch_base_1.configArrayFactory.prototype._loadPlugin = function (name, ctx) {
const originalResolve = _patch_base_1.ModuleResolver.resolve;

@@ -49,0 +50,0 @@ try {

{
"name": "@rushstack/eslint-patch",
"version": "1.7.2",
"version": "1.8.0",
"description": "Enhance ESLint with better support for large scale monorepos",

@@ -29,7 +29,10 @@ "main": "lib/usage.js",

"devDependencies": {
"@rushstack/heft": "0.64.0",
"@rushstack/heft-node-rig": "2.4.0",
"@rushstack/heft": "0.65.5",
"@rushstack/heft-node-rig": "2.4.18",
"@types/eslint": "8.2.0",
"@types/node": "18.17.15",
"typescript": "~5.3.3",
"@typescript-eslint/types": "~5.59.2"
"@typescript-eslint/types": "~5.59.2",
"eslint": "~8.7.0",
"eslint-plugin-header": "~3.1.1",
"typescript": "~5.4.2"
},

@@ -36,0 +39,0 @@ "scripts": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc