source: frontend/node_modules/@rushstack/eslint-patch/lib-esm/eslint-bulk-suppressions/bulk-suppressions-patch.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 13 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 9.2 KB
Line 
1// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
2// See LICENSE in the project root for license information.
3import fs from 'node:fs';
4import * as Guards from './ast-guards';
5import { eslintFolder } from '../_patch-base';
6import { ESLINT_BULK_ENABLE_ENV_VAR_NAME, ESLINT_BULK_PRUNE_ENV_VAR_NAME, ESLINT_BULK_SUPPRESS_ENV_VAR_NAME } from './constants';
7import { getSuppressionsConfigForEslintConfigFolderPath, serializeSuppression, writeSuppressionsJsonToFile, getAllBulkSuppressionsConfigsByEslintConfigFolderPath } from './bulk-suppressions-file';
8const ESLINT_CONFIG_FILENAMES = [
9 'eslint.config.js',
10 'eslint.config.cjs',
11 'eslint.config.mjs',
12 '.eslintrc.js',
13 '.eslintrc.cjs'
14 // Several other filenames are allowed, but this patch requires that it be loaded via a JS config file,
15 // so we only need to check for the JS-based filenames
16];
17const SUPPRESSION_SYMBOL = Symbol('suppression');
18const ESLINT_BULK_SUPPRESS_ENV_VAR_VALUE = process.env[ESLINT_BULK_SUPPRESS_ENV_VAR_NAME];
19const SUPPRESS_ALL_RULES = ESLINT_BULK_SUPPRESS_ENV_VAR_VALUE === '*';
20const RULES_TO_SUPPRESS = ESLINT_BULK_SUPPRESS_ENV_VAR_VALUE
21 ? new Set(ESLINT_BULK_SUPPRESS_ENV_VAR_VALUE.split(','))
22 : undefined;
23function getNodeName(node) {
24 if (Guards.isClassDeclarationWithName(node)) {
25 return node.id.name;
26 }
27 else if (Guards.isFunctionDeclarationWithName(node)) {
28 return node.id.name;
29 }
30 else if (Guards.isClassExpressionWithName(node)) {
31 return node.id.name;
32 }
33 else if (Guards.isFunctionExpressionWithName(node)) {
34 return node.id.name;
35 }
36 else if (Guards.isNormalVariableDeclaratorWithAnonymousExpressionAssigned(node)) {
37 return node.id.name;
38 }
39 else if (Guards.isNormalObjectPropertyWithAnonymousExpressionAssigned(node)) {
40 return node.key.name;
41 }
42 else if (Guards.isNormalClassPropertyDefinitionWithAnonymousExpressionAssigned(node)) {
43 return node.key.name;
44 }
45 else if (Guards.isNormalAssignmentPatternWithAnonymousExpressionAssigned(node)) {
46 return node.left.name;
47 }
48 else if (Guards.isNormalMethodDefinition(node)) {
49 return node.key.name;
50 }
51 else if (Guards.isTSEnumDeclaration(node)) {
52 return node.id.name;
53 }
54 else if (Guards.isTSInterfaceDeclaration(node)) {
55 return node.id.name;
56 }
57 else if (Guards.isTSTypeAliasDeclaration(node)) {
58 return node.id.name;
59 }
60}
61function calculateScopeId(node) {
62 const scopeIds = [];
63 for (let current = node; current; current = current.parent) {
64 const scopeIdForASTNode = getNodeName(current);
65 if (scopeIdForASTNode !== undefined) {
66 scopeIds.unshift(scopeIdForASTNode);
67 }
68 }
69 if (scopeIds.length === 0) {
70 return '.';
71 }
72 else {
73 return '.' + scopeIds.join('.');
74 }
75}
76const eslintConfigPathByFileOrFolderPath = new Map();
77function findEslintConfigFolderPathForNormalizedFileAbsolutePath(normalizedFilePath) {
78 const cachedFolderPathForFilePath = eslintConfigPathByFileOrFolderPath.get(normalizedFilePath);
79 if (cachedFolderPathForFilePath) {
80 return cachedFolderPathForFilePath;
81 }
82 const normalizedFileFolderPath = normalizedFilePath.substring(0, normalizedFilePath.lastIndexOf('/'));
83 const pathsToCache = [normalizedFilePath];
84 let eslintConfigFolderPath;
85 findEslintConfigFileLoop: for (let currentFolder = normalizedFileFolderPath; currentFolder; // 'something'.substring(0, -1) is ''
86 currentFolder = currentFolder.substring(0, currentFolder.lastIndexOf('/'))) {
87 const cachedEslintrcFolderPath = eslintConfigPathByFileOrFolderPath.get(currentFolder);
88 if (cachedEslintrcFolderPath) {
89 // Need to cache this result into the intermediate paths
90 eslintConfigFolderPath = cachedEslintrcFolderPath;
91 break;
92 }
93 pathsToCache.push(currentFolder);
94 for (const eslintConfigFilename of ESLINT_CONFIG_FILENAMES) {
95 if (fs.existsSync(`${currentFolder}/${eslintConfigFilename}`)) {
96 eslintConfigFolderPath = currentFolder;
97 break findEslintConfigFileLoop;
98 }
99 }
100 }
101 if (eslintConfigFolderPath) {
102 for (const checkedFolder of pathsToCache) {
103 eslintConfigPathByFileOrFolderPath.set(checkedFolder, eslintConfigFolderPath);
104 }
105 return eslintConfigFolderPath;
106 }
107 else {
108 throw new Error(`Cannot locate an ESLint configuration file for ${normalizedFilePath}`);
109 }
110}
111// One-line insert into the ruleContext report method to prematurely exit if the ESLint problem has been suppressed
112export function shouldBulkSuppress(params) {
113 // Use this ENV variable to turn off eslint-bulk-suppressions functionality, default behavior is on
114 if (process.env[ESLINT_BULK_ENABLE_ENV_VAR_NAME] === 'false') {
115 return false;
116 }
117 const { filename: fileAbsolutePath, currentNode, ruleId: rule, problem } = params;
118 const normalizedFileAbsolutePath = fileAbsolutePath.replace(/\\/g, '/');
119 const eslintConfigDirectory = findEslintConfigFolderPathForNormalizedFileAbsolutePath(normalizedFileAbsolutePath);
120 const fileRelativePath = normalizedFileAbsolutePath.substring(eslintConfigDirectory.length + 1);
121 const scopeId = calculateScopeId(currentNode);
122 const suppression = { file: fileRelativePath, scopeId, rule };
123 const config = getSuppressionsConfigForEslintConfigFolderPath(eslintConfigDirectory);
124 const serializedSuppression = serializeSuppression(suppression);
125 const currentNodeIsSuppressed = config.serializedSuppressions.has(serializedSuppression);
126 if (currentNodeIsSuppressed || SUPPRESS_ALL_RULES || (RULES_TO_SUPPRESS === null || RULES_TO_SUPPRESS === void 0 ? void 0 : RULES_TO_SUPPRESS.has(suppression.rule))) {
127 problem[SUPPRESSION_SYMBOL] = {
128 suppression,
129 serializedSuppression,
130 config
131 };
132 }
133 return process.env[ESLINT_BULK_PRUNE_ENV_VAR_NAME] !== '1' && currentNodeIsSuppressed;
134}
135export function prune() {
136 for (const [eslintConfigFolderPath, suppressionsConfig] of getAllBulkSuppressionsConfigsByEslintConfigFolderPath()) {
137 if (suppressionsConfig) {
138 const { newSerializedSuppressions, newJsonObject } = suppressionsConfig;
139 const newSuppressionsConfig = {
140 serializedSuppressions: newSerializedSuppressions,
141 jsonObject: newJsonObject,
142 newSerializedSuppressions: new Set(),
143 newJsonObject: { suppressions: [] }
144 };
145 writeSuppressionsJsonToFile(eslintConfigFolderPath, newSuppressionsConfig);
146 }
147 }
148}
149export function write() {
150 for (const [eslintrcFolderPath, suppressionsConfig] of getAllBulkSuppressionsConfigsByEslintConfigFolderPath()) {
151 if (suppressionsConfig) {
152 writeSuppressionsJsonToFile(eslintrcFolderPath, suppressionsConfig);
153 }
154 }
155}
156// utility function for linter-patch.js to make require statements that use relative paths in linter.js work in linter-patch.js
157export function requireFromPathToLinterJS(importPath) {
158 if (!eslintFolder) {
159 return require(importPath);
160 }
161 const pathToLinterFolder = `${eslintFolder}/lib/linter`;
162 const moduleAbsolutePath = require.resolve(importPath, { paths: [pathToLinterFolder] });
163 return require(moduleAbsolutePath);
164}
165export function patchClass(originalClass, patchedClass) {
166 // Get all the property names of the patched class prototype
167 const patchedProperties = Object.getOwnPropertyNames(patchedClass.prototype);
168 // Loop through all the properties
169 for (const prop of patchedProperties) {
170 // Override the property in the original class
171 originalClass.prototype[prop] = patchedClass.prototype[prop];
172 }
173 // Handle getters and setters
174 for (const [prop, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(patchedClass.prototype))) {
175 if (descriptor.get || descriptor.set) {
176 Object.defineProperty(originalClass.prototype, prop, descriptor);
177 }
178 }
179}
180/**
181 * This returns a wrapped version of the "verify" function from ESLint's Linter class
182 * that postprocesses rule violations that weren't suppressed by comments. This postprocessing
183 * records suppressions that weren't otherwise suppressed by comments to be used
184 * by the "suppress" and "prune" commands.
185 */
186export function extendVerifyFunction(originalFn) {
187 return function (...args) {
188 const problems = originalFn.apply(this, args);
189 if (problems) {
190 for (const problem of problems) {
191 if (problem[SUPPRESSION_SYMBOL]) {
192 const { serializedSuppression, suppression, config: { newSerializedSuppressions, jsonObject: { suppressions }, newJsonObject: { suppressions: newSuppressions } } } = problem[SUPPRESSION_SYMBOL];
193 if (!newSerializedSuppressions.has(serializedSuppression)) {
194 newSerializedSuppressions.add(serializedSuppression);
195 newSuppressions.push(suppression);
196 suppressions.push(suppression);
197 }
198 }
199 }
200 }
201 return problems;
202 };
203}
204//# sourceMappingURL=bulk-suppressions-patch.js.map
Note: See TracBrowser for help on using the repository browser.