251127:1700 Frontend Start Build
This commit is contained in:
932
frontend/.ignored_node_modules/eslint/lib/eslint/eslint-helpers.js
generated
Normal file
932
frontend/.ignored_node_modules/eslint/lib/eslint/eslint-helpers.js
generated
Normal file
@@ -0,0 +1,932 @@
|
||||
/**
|
||||
* @fileoverview Helper functions for ESLint class
|
||||
* @author Nicholas C. Zakas
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const fsp = fs.promises;
|
||||
const isGlob = require("is-glob");
|
||||
const hash = require("../cli-engine/hash");
|
||||
const minimatch = require("minimatch");
|
||||
const fswalk = require("@nodelib/fs.walk");
|
||||
const globParent = require("glob-parent");
|
||||
const isPathInside = require("is-path-inside");
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Fixup references
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const Minimatch = minimatch.Minimatch;
|
||||
const MINIMATCH_OPTIONS = { dot: true };
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Types
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @typedef {Object} GlobSearch
|
||||
* @property {Array<string>} patterns The normalized patterns to use for a search.
|
||||
* @property {Array<string>} rawPatterns The patterns as entered by the user
|
||||
* before doing any normalization.
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Errors
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The error type when no files match a glob.
|
||||
*/
|
||||
class NoFilesFoundError extends Error {
|
||||
|
||||
/**
|
||||
* @param {string} pattern The glob pattern which was not found.
|
||||
* @param {boolean} globEnabled If `false` then the pattern was a glob pattern, but glob was disabled.
|
||||
*/
|
||||
constructor(pattern, globEnabled) {
|
||||
super(`No files matching '${pattern}' were found${!globEnabled ? " (glob was disabled)" : ""}.`);
|
||||
this.messageTemplate = "file-not-found";
|
||||
this.messageData = { pattern, globDisabled: !globEnabled };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The error type when a search fails to match multiple patterns.
|
||||
*/
|
||||
class UnmatchedSearchPatternsError extends Error {
|
||||
|
||||
/**
|
||||
* @param {Object} options The options for the error.
|
||||
* @param {string} options.basePath The directory that was searched.
|
||||
* @param {Array<string>} options.unmatchedPatterns The glob patterns
|
||||
* which were not found.
|
||||
* @param {Array<string>} options.patterns The glob patterns that were
|
||||
* searched.
|
||||
* @param {Array<string>} options.rawPatterns The raw glob patterns that
|
||||
* were searched.
|
||||
*/
|
||||
constructor({ basePath, unmatchedPatterns, patterns, rawPatterns }) {
|
||||
super(`No files matching '${rawPatterns}' in '${basePath}' were found.`);
|
||||
this.basePath = basePath;
|
||||
this.unmatchedPatterns = unmatchedPatterns;
|
||||
this.patterns = patterns;
|
||||
this.rawPatterns = rawPatterns;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The error type when there are files matched by a glob, but all of them have been ignored.
|
||||
*/
|
||||
class AllFilesIgnoredError extends Error {
|
||||
|
||||
/**
|
||||
* @param {string} pattern The glob pattern which was not found.
|
||||
*/
|
||||
constructor(pattern) {
|
||||
super(`All files matched by '${pattern}' are ignored.`);
|
||||
this.messageTemplate = "all-files-ignored";
|
||||
this.messageData = { pattern };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// General Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Check if a given value is a non-empty string or not.
|
||||
* @param {any} x The value to check.
|
||||
* @returns {boolean} `true` if `x` is a non-empty string.
|
||||
*/
|
||||
function isNonEmptyString(x) {
|
||||
return typeof x === "string" && x.trim() !== "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given value is an array of non-empty strings or not.
|
||||
* @param {any} x The value to check.
|
||||
* @returns {boolean} `true` if `x` is an array of non-empty strings.
|
||||
*/
|
||||
function isArrayOfNonEmptyString(x) {
|
||||
return Array.isArray(x) && x.every(isNonEmptyString);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// File-related Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Normalizes slashes in a file pattern to posix-style.
|
||||
* @param {string} pattern The pattern to replace slashes in.
|
||||
* @returns {string} The pattern with slashes normalized.
|
||||
*/
|
||||
function normalizeToPosix(pattern) {
|
||||
return pattern.replace(/\\/gu, "/");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a string is a glob pattern or not.
|
||||
* @param {string} pattern A glob pattern.
|
||||
* @returns {boolean} `true` if the string is a glob pattern.
|
||||
*/
|
||||
function isGlobPattern(pattern) {
|
||||
return isGlob(path.sep === "\\" ? normalizeToPosix(pattern) : pattern);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines if a given glob pattern will return any results.
|
||||
* Used primarily to help with useful error messages.
|
||||
* @param {Object} options The options for the function.
|
||||
* @param {string} options.basePath The directory to search.
|
||||
* @param {string} options.pattern A glob pattern to match.
|
||||
* @returns {Promise<boolean>} True if there is a glob match, false if not.
|
||||
*/
|
||||
function globMatch({ basePath, pattern }) {
|
||||
|
||||
let found = false;
|
||||
const patternToUse = path.isAbsolute(pattern)
|
||||
? normalizeToPosix(path.relative(basePath, pattern))
|
||||
: pattern;
|
||||
|
||||
const matcher = new Minimatch(patternToUse, MINIMATCH_OPTIONS);
|
||||
|
||||
const fsWalkSettings = {
|
||||
|
||||
deepFilter(entry) {
|
||||
const relativePath = normalizeToPosix(path.relative(basePath, entry.path));
|
||||
|
||||
return !found && matcher.match(relativePath, true);
|
||||
},
|
||||
|
||||
entryFilter(entry) {
|
||||
if (found || entry.dirent.isDirectory()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const relativePath = normalizeToPosix(path.relative(basePath, entry.path));
|
||||
|
||||
if (matcher.match(relativePath)) {
|
||||
found = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
return new Promise(resolve => {
|
||||
|
||||
// using a stream so we can exit early because we just need one match
|
||||
const globStream = fswalk.walkStream(basePath, fsWalkSettings);
|
||||
|
||||
globStream.on("data", () => {
|
||||
globStream.destroy();
|
||||
resolve(true);
|
||||
});
|
||||
|
||||
// swallow errors as they're not important here
|
||||
globStream.on("error", () => { });
|
||||
|
||||
globStream.on("end", () => {
|
||||
resolve(false);
|
||||
});
|
||||
globStream.read();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches a directory looking for matching glob patterns. This uses
|
||||
* the config array's logic to determine if a directory or file should
|
||||
* be ignored, so it is consistent with how ignoring works throughout
|
||||
* ESLint.
|
||||
* @param {Object} options The options for this function.
|
||||
* @param {string} options.basePath The directory to search.
|
||||
* @param {Array<string>} options.patterns An array of glob patterns
|
||||
* to match.
|
||||
* @param {Array<string>} options.rawPatterns An array of glob patterns
|
||||
* as the user inputted them. Used for errors.
|
||||
* @param {FlatConfigArray} options.configs The config array to use for
|
||||
* determining what to ignore.
|
||||
* @param {boolean} options.errorOnUnmatchedPattern Determines if an error
|
||||
* should be thrown when a pattern is unmatched.
|
||||
* @returns {Promise<Array<string>>} An array of matching file paths
|
||||
* or an empty array if there are no matches.
|
||||
* @throws {UnmatchedSearchPatternsError} If there is a pattern that doesn't
|
||||
* match any files.
|
||||
*/
|
||||
async function globSearch({
|
||||
basePath,
|
||||
patterns,
|
||||
rawPatterns,
|
||||
configs,
|
||||
errorOnUnmatchedPattern
|
||||
}) {
|
||||
|
||||
if (patterns.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
/*
|
||||
* In this section we are converting the patterns into Minimatch
|
||||
* instances for performance reasons. Because we are doing the same
|
||||
* matches repeatedly, it's best to compile those patterns once and
|
||||
* reuse them multiple times.
|
||||
*
|
||||
* To do that, we convert any patterns with an absolute path into a
|
||||
* relative path and normalize it to Posix-style slashes. We also keep
|
||||
* track of the relative patterns to map them back to the original
|
||||
* patterns, which we need in order to throw an error if there are any
|
||||
* unmatched patterns.
|
||||
*/
|
||||
const relativeToPatterns = new Map();
|
||||
const matchers = patterns.map((pattern, i) => {
|
||||
const patternToUse = path.isAbsolute(pattern)
|
||||
? normalizeToPosix(path.relative(basePath, pattern))
|
||||
: pattern;
|
||||
|
||||
relativeToPatterns.set(patternToUse, patterns[i]);
|
||||
|
||||
return new Minimatch(patternToUse, MINIMATCH_OPTIONS);
|
||||
});
|
||||
|
||||
/*
|
||||
* We track unmatched patterns because we may want to throw an error when
|
||||
* they occur. To start, this set is initialized with all of the patterns.
|
||||
* Every time a match occurs, the pattern is removed from the set, making
|
||||
* it easy to tell if we have any unmatched patterns left at the end of
|
||||
* search.
|
||||
*/
|
||||
const unmatchedPatterns = new Set([...relativeToPatterns.keys()]);
|
||||
|
||||
const filePaths = (await new Promise((resolve, reject) => {
|
||||
|
||||
let promiseRejected = false;
|
||||
|
||||
/**
|
||||
* Wraps a boolean-returning filter function. The wrapped function will reject the promise if an error occurs.
|
||||
* @param {Function} filter A filter function to wrap.
|
||||
* @returns {Function} A function similar to the wrapped filter that rejects the promise if an error occurs.
|
||||
*/
|
||||
function wrapFilter(filter) {
|
||||
return (...args) => {
|
||||
|
||||
// No need to run the filter if an error has been thrown.
|
||||
if (!promiseRejected) {
|
||||
try {
|
||||
return filter(...args);
|
||||
} catch (error) {
|
||||
promiseRejected = true;
|
||||
reject(error);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
fswalk.walk(
|
||||
basePath,
|
||||
{
|
||||
deepFilter: wrapFilter(entry => {
|
||||
const relativePath = normalizeToPosix(path.relative(basePath, entry.path));
|
||||
const matchesPattern = matchers.some(matcher => matcher.match(relativePath, true));
|
||||
|
||||
return matchesPattern && !configs.isDirectoryIgnored(entry.path);
|
||||
}),
|
||||
entryFilter: wrapFilter(entry => {
|
||||
const relativePath = normalizeToPosix(path.relative(basePath, entry.path));
|
||||
|
||||
// entries may be directories or files so filter out directories
|
||||
if (entry.dirent.isDirectory()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Optimization: We need to track when patterns are left unmatched
|
||||
* and so we use `unmatchedPatterns` to do that. There is a bit of
|
||||
* complexity here because the same file can be matched by more than
|
||||
* one pattern. So, when we start, we actually need to test every
|
||||
* pattern against every file. Once we know there are no remaining
|
||||
* unmatched patterns, then we can switch to just looking for the
|
||||
* first matching pattern for improved speed.
|
||||
*/
|
||||
const matchesPattern = unmatchedPatterns.size > 0
|
||||
? matchers.reduce((previousValue, matcher) => {
|
||||
const pathMatches = matcher.match(relativePath);
|
||||
|
||||
/*
|
||||
* We updated the unmatched patterns set only if the path
|
||||
* matches and the file isn't ignored. If the file is
|
||||
* ignored, that means there wasn't a match for the
|
||||
* pattern so it should not be removed.
|
||||
*
|
||||
* Performance note: isFileIgnored() aggressively caches
|
||||
* results so there is no performance penalty for calling
|
||||
* it twice with the same argument.
|
||||
*/
|
||||
if (pathMatches && !configs.isFileIgnored(entry.path)) {
|
||||
unmatchedPatterns.delete(matcher.pattern);
|
||||
}
|
||||
|
||||
return pathMatches || previousValue;
|
||||
}, false)
|
||||
: matchers.some(matcher => matcher.match(relativePath));
|
||||
|
||||
return matchesPattern && !configs.isFileIgnored(entry.path);
|
||||
})
|
||||
},
|
||||
(error, entries) => {
|
||||
|
||||
// If the promise is already rejected, calling `resolve` or `reject` will do nothing.
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(entries);
|
||||
}
|
||||
}
|
||||
);
|
||||
})).map(entry => entry.path);
|
||||
|
||||
// now check to see if we have any unmatched patterns
|
||||
if (errorOnUnmatchedPattern && unmatchedPatterns.size > 0) {
|
||||
throw new UnmatchedSearchPatternsError({
|
||||
basePath,
|
||||
unmatchedPatterns: [...unmatchedPatterns].map(
|
||||
pattern => relativeToPatterns.get(pattern)
|
||||
),
|
||||
patterns,
|
||||
rawPatterns
|
||||
});
|
||||
}
|
||||
|
||||
return filePaths;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an error for unmatched patterns. The error will only contain information about the first one.
|
||||
* Checks to see if there are any ignored results for a given search.
|
||||
* @param {Object} options The options for this function.
|
||||
* @param {string} options.basePath The directory to search.
|
||||
* @param {Array<string>} options.patterns An array of glob patterns
|
||||
* that were used in the original search.
|
||||
* @param {Array<string>} options.rawPatterns An array of glob patterns
|
||||
* as the user inputted them. Used for errors.
|
||||
* @param {Array<string>} options.unmatchedPatterns A non-empty array of glob patterns
|
||||
* that were unmatched in the original search.
|
||||
* @returns {void} Always throws an error.
|
||||
* @throws {NoFilesFoundError} If the first unmatched pattern
|
||||
* doesn't match any files even when there are no ignores.
|
||||
* @throws {AllFilesIgnoredError} If the first unmatched pattern
|
||||
* matches some files when there are no ignores.
|
||||
*/
|
||||
async function throwErrorForUnmatchedPatterns({
|
||||
basePath,
|
||||
patterns,
|
||||
rawPatterns,
|
||||
unmatchedPatterns
|
||||
}) {
|
||||
|
||||
const pattern = unmatchedPatterns[0];
|
||||
const rawPattern = rawPatterns[patterns.indexOf(pattern)];
|
||||
|
||||
const patternHasMatch = await globMatch({
|
||||
basePath,
|
||||
pattern
|
||||
});
|
||||
|
||||
if (patternHasMatch) {
|
||||
throw new AllFilesIgnoredError(rawPattern);
|
||||
}
|
||||
|
||||
// if we get here there are truly no matches
|
||||
throw new NoFilesFoundError(rawPattern, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs multiple glob searches in parallel.
|
||||
* @param {Object} options The options for this function.
|
||||
* @param {Map<string,GlobSearch>} options.searches
|
||||
* An array of glob patterns to match.
|
||||
* @param {FlatConfigArray} options.configs The config array to use for
|
||||
* determining what to ignore.
|
||||
* @param {boolean} options.errorOnUnmatchedPattern Determines if an
|
||||
* unmatched glob pattern should throw an error.
|
||||
* @returns {Promise<Array<string>>} An array of matching file paths
|
||||
* or an empty array if there are no matches.
|
||||
*/
|
||||
async function globMultiSearch({ searches, configs, errorOnUnmatchedPattern }) {
|
||||
|
||||
/*
|
||||
* For convenience, we normalized the search map into an array of objects.
|
||||
* Next, we filter out all searches that have no patterns. This happens
|
||||
* primarily for the cwd, which is prepopulated in the searches map as an
|
||||
* optimization. However, if it has no patterns, it means all patterns
|
||||
* occur outside of the cwd and we can safely filter out that search.
|
||||
*/
|
||||
const normalizedSearches = [...searches].map(
|
||||
([basePath, { patterns, rawPatterns }]) => ({ basePath, patterns, rawPatterns })
|
||||
).filter(({ patterns }) => patterns.length > 0);
|
||||
|
||||
const results = await Promise.allSettled(
|
||||
normalizedSearches.map(
|
||||
({ basePath, patterns, rawPatterns }) => globSearch({
|
||||
basePath,
|
||||
patterns,
|
||||
rawPatterns,
|
||||
configs,
|
||||
errorOnUnmatchedPattern
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
const filePaths = [];
|
||||
|
||||
for (let i = 0; i < results.length; i++) {
|
||||
|
||||
const result = results[i];
|
||||
const currentSearch = normalizedSearches[i];
|
||||
|
||||
if (result.status === "fulfilled") {
|
||||
|
||||
// if the search was successful just add the results
|
||||
if (result.value.length > 0) {
|
||||
filePaths.push(...result.value);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we make it here then there was an error
|
||||
const error = result.reason;
|
||||
|
||||
// unexpected errors should be re-thrown
|
||||
if (!error.basePath) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (errorOnUnmatchedPattern) {
|
||||
|
||||
await throwErrorForUnmatchedPatterns({
|
||||
...currentSearch,
|
||||
unmatchedPatterns: error.unmatchedPatterns
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return filePaths;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all files matching the options specified.
|
||||
* @param {Object} args The arguments objects.
|
||||
* @param {Array<string>} args.patterns An array of glob patterns.
|
||||
* @param {boolean} args.globInputPaths true to interpret glob patterns,
|
||||
* false to not interpret glob patterns.
|
||||
* @param {string} args.cwd The current working directory to find from.
|
||||
* @param {FlatConfigArray} args.configs The configs for the current run.
|
||||
* @param {boolean} args.errorOnUnmatchedPattern Determines if an unmatched pattern
|
||||
* should throw an error.
|
||||
* @returns {Promise<Array<string>>} The fully resolved file paths.
|
||||
* @throws {AllFilesIgnoredError} If there are no results due to an ignore pattern.
|
||||
* @throws {NoFilesFoundError} If no files matched the given patterns.
|
||||
*/
|
||||
async function findFiles({
|
||||
patterns,
|
||||
globInputPaths,
|
||||
cwd,
|
||||
configs,
|
||||
errorOnUnmatchedPattern
|
||||
}) {
|
||||
|
||||
const results = [];
|
||||
const missingPatterns = [];
|
||||
let globbyPatterns = [];
|
||||
let rawPatterns = [];
|
||||
const searches = new Map([[cwd, { patterns: globbyPatterns, rawPatterns: [] }]]);
|
||||
|
||||
// check to see if we have explicit files and directories
|
||||
const filePaths = patterns.map(filePath => path.resolve(cwd, filePath));
|
||||
const stats = await Promise.all(
|
||||
filePaths.map(
|
||||
filePath => fsp.stat(filePath).catch(() => { })
|
||||
)
|
||||
);
|
||||
|
||||
stats.forEach((stat, index) => {
|
||||
|
||||
const filePath = filePaths[index];
|
||||
const pattern = normalizeToPosix(patterns[index]);
|
||||
|
||||
if (stat) {
|
||||
|
||||
// files are added directly to the list
|
||||
if (stat.isFile()) {
|
||||
results.push(filePath);
|
||||
}
|
||||
|
||||
// directories need extensions attached
|
||||
if (stat.isDirectory()) {
|
||||
|
||||
// group everything in cwd together and split out others
|
||||
if (isPathInside(filePath, cwd)) {
|
||||
({ patterns: globbyPatterns, rawPatterns } = searches.get(cwd));
|
||||
} else {
|
||||
if (!searches.has(filePath)) {
|
||||
searches.set(filePath, { patterns: [], rawPatterns: [] });
|
||||
}
|
||||
({ patterns: globbyPatterns, rawPatterns } = searches.get(filePath));
|
||||
}
|
||||
|
||||
globbyPatterns.push(`${normalizeToPosix(filePath)}/**`);
|
||||
rawPatterns.push(pattern);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// save patterns for later use based on whether globs are enabled
|
||||
if (globInputPaths && isGlobPattern(pattern)) {
|
||||
|
||||
const basePath = path.resolve(cwd, globParent(pattern));
|
||||
|
||||
// group in cwd if possible and split out others
|
||||
if (isPathInside(basePath, cwd)) {
|
||||
({ patterns: globbyPatterns, rawPatterns } = searches.get(cwd));
|
||||
} else {
|
||||
if (!searches.has(basePath)) {
|
||||
searches.set(basePath, { patterns: [], rawPatterns: [] });
|
||||
}
|
||||
({ patterns: globbyPatterns, rawPatterns } = searches.get(basePath));
|
||||
}
|
||||
|
||||
globbyPatterns.push(filePath);
|
||||
rawPatterns.push(pattern);
|
||||
} else {
|
||||
missingPatterns.push(pattern);
|
||||
}
|
||||
});
|
||||
|
||||
// there were patterns that didn't match anything, tell the user
|
||||
if (errorOnUnmatchedPattern && missingPatterns.length) {
|
||||
throw new NoFilesFoundError(missingPatterns[0], globInputPaths);
|
||||
}
|
||||
|
||||
// now we are safe to do the search
|
||||
const globbyResults = await globMultiSearch({
|
||||
searches,
|
||||
configs,
|
||||
errorOnUnmatchedPattern
|
||||
});
|
||||
|
||||
return [
|
||||
...new Set([
|
||||
...results,
|
||||
...globbyResults.map(filePath => path.resolve(filePath))
|
||||
])
|
||||
];
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Results-related Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Checks if the given message is an error message.
|
||||
* @param {LintMessage} message The message to check.
|
||||
* @returns {boolean} Whether or not the message is an error message.
|
||||
* @private
|
||||
*/
|
||||
function isErrorMessage(message) {
|
||||
return message.severity === 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns result with warning by ignore settings
|
||||
* @param {string} filePath File path of checked code
|
||||
* @param {string} baseDir Absolute path of base directory
|
||||
* @returns {LintResult} Result with single warning
|
||||
* @private
|
||||
*/
|
||||
function createIgnoreResult(filePath, baseDir) {
|
||||
let message;
|
||||
const isInNodeModules = baseDir && path.dirname(path.relative(baseDir, filePath)).split(path.sep).includes("node_modules");
|
||||
|
||||
if (isInNodeModules) {
|
||||
message = "File ignored by default because it is located under the node_modules directory. Use ignore pattern \"!**/node_modules/\" to disable file ignore settings or use \"--no-warn-ignored\" to suppress this warning.";
|
||||
} else {
|
||||
message = "File ignored because of a matching ignore pattern. Use \"--no-ignore\" to disable file ignore settings or use \"--no-warn-ignored\" to suppress this warning.";
|
||||
}
|
||||
|
||||
return {
|
||||
filePath: path.resolve(filePath),
|
||||
messages: [
|
||||
{
|
||||
ruleId: null,
|
||||
fatal: false,
|
||||
severity: 1,
|
||||
message,
|
||||
nodeType: null
|
||||
}
|
||||
],
|
||||
suppressedMessages: [],
|
||||
errorCount: 0,
|
||||
warningCount: 1,
|
||||
fatalErrorCount: 0,
|
||||
fixableErrorCount: 0,
|
||||
fixableWarningCount: 0
|
||||
};
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Options-related Helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Check if a given value is a valid fix type or not.
|
||||
* @param {any} x The value to check.
|
||||
* @returns {boolean} `true` if `x` is valid fix type.
|
||||
*/
|
||||
function isFixType(x) {
|
||||
return x === "directive" || x === "problem" || x === "suggestion" || x === "layout";
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given value is an array of fix types or not.
|
||||
* @param {any} x The value to check.
|
||||
* @returns {boolean} `true` if `x` is an array of fix types.
|
||||
*/
|
||||
function isFixTypeArray(x) {
|
||||
return Array.isArray(x) && x.every(isFixType);
|
||||
}
|
||||
|
||||
/**
|
||||
* The error for invalid options.
|
||||
*/
|
||||
class ESLintInvalidOptionsError extends Error {
|
||||
constructor(messages) {
|
||||
super(`Invalid Options:\n- ${messages.join("\n- ")}`);
|
||||
this.code = "ESLINT_INVALID_OPTIONS";
|
||||
Error.captureStackTrace(this, ESLintInvalidOptionsError);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates and normalizes options for the wrapped CLIEngine instance.
|
||||
* @param {FlatESLintOptions} options The options to process.
|
||||
* @throws {ESLintInvalidOptionsError} If of any of a variety of type errors.
|
||||
* @returns {FlatESLintOptions} The normalized options.
|
||||
*/
|
||||
function processOptions({
|
||||
allowInlineConfig = true, // ← we cannot use `overrideConfig.noInlineConfig` instead because `allowInlineConfig` has side-effect that suppress warnings that show inline configs are ignored.
|
||||
baseConfig = null,
|
||||
cache = false,
|
||||
cacheLocation = ".eslintcache",
|
||||
cacheStrategy = "metadata",
|
||||
cwd = process.cwd(),
|
||||
errorOnUnmatchedPattern = true,
|
||||
fix = false,
|
||||
fixTypes = null, // ← should be null by default because if it's an array then it suppresses rules that don't have the `meta.type` property.
|
||||
globInputPaths = true,
|
||||
ignore = true,
|
||||
ignorePatterns = null,
|
||||
overrideConfig = null,
|
||||
overrideConfigFile = null,
|
||||
plugins = {},
|
||||
warnIgnored = true,
|
||||
...unknownOptions
|
||||
}) {
|
||||
const errors = [];
|
||||
const unknownOptionKeys = Object.keys(unknownOptions);
|
||||
|
||||
if (unknownOptionKeys.length >= 1) {
|
||||
errors.push(`Unknown options: ${unknownOptionKeys.join(", ")}`);
|
||||
if (unknownOptionKeys.includes("cacheFile")) {
|
||||
errors.push("'cacheFile' has been removed. Please use the 'cacheLocation' option instead.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("configFile")) {
|
||||
errors.push("'configFile' has been removed. Please use the 'overrideConfigFile' option instead.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("envs")) {
|
||||
errors.push("'envs' has been removed.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("extensions")) {
|
||||
errors.push("'extensions' has been removed.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("resolvePluginsRelativeTo")) {
|
||||
errors.push("'resolvePluginsRelativeTo' has been removed.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("globals")) {
|
||||
errors.push("'globals' has been removed. Please use the 'overrideConfig.languageOptions.globals' option instead.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("ignorePath")) {
|
||||
errors.push("'ignorePath' has been removed.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("ignorePattern")) {
|
||||
errors.push("'ignorePattern' has been removed. Please use the 'overrideConfig.ignorePatterns' option instead.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("parser")) {
|
||||
errors.push("'parser' has been removed. Please use the 'overrideConfig.languageOptions.parser' option instead.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("parserOptions")) {
|
||||
errors.push("'parserOptions' has been removed. Please use the 'overrideConfig.languageOptions.parserOptions' option instead.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("rules")) {
|
||||
errors.push("'rules' has been removed. Please use the 'overrideConfig.rules' option instead.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("rulePaths")) {
|
||||
errors.push("'rulePaths' has been removed. Please define your rules using plugins.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("reportUnusedDisableDirectives")) {
|
||||
errors.push("'reportUnusedDisableDirectives' has been removed. Please use the 'overrideConfig.linterOptions.reportUnusedDisableDirectives' option instead.");
|
||||
}
|
||||
}
|
||||
if (typeof allowInlineConfig !== "boolean") {
|
||||
errors.push("'allowInlineConfig' must be a boolean.");
|
||||
}
|
||||
if (typeof baseConfig !== "object") {
|
||||
errors.push("'baseConfig' must be an object or null.");
|
||||
}
|
||||
if (typeof cache !== "boolean") {
|
||||
errors.push("'cache' must be a boolean.");
|
||||
}
|
||||
if (!isNonEmptyString(cacheLocation)) {
|
||||
errors.push("'cacheLocation' must be a non-empty string.");
|
||||
}
|
||||
if (
|
||||
cacheStrategy !== "metadata" &&
|
||||
cacheStrategy !== "content"
|
||||
) {
|
||||
errors.push("'cacheStrategy' must be any of \"metadata\", \"content\".");
|
||||
}
|
||||
if (!isNonEmptyString(cwd) || !path.isAbsolute(cwd)) {
|
||||
errors.push("'cwd' must be an absolute path.");
|
||||
}
|
||||
if (typeof errorOnUnmatchedPattern !== "boolean") {
|
||||
errors.push("'errorOnUnmatchedPattern' must be a boolean.");
|
||||
}
|
||||
if (typeof fix !== "boolean" && typeof fix !== "function") {
|
||||
errors.push("'fix' must be a boolean or a function.");
|
||||
}
|
||||
if (fixTypes !== null && !isFixTypeArray(fixTypes)) {
|
||||
errors.push("'fixTypes' must be an array of any of \"directive\", \"problem\", \"suggestion\", and \"layout\".");
|
||||
}
|
||||
if (typeof globInputPaths !== "boolean") {
|
||||
errors.push("'globInputPaths' must be a boolean.");
|
||||
}
|
||||
if (typeof ignore !== "boolean") {
|
||||
errors.push("'ignore' must be a boolean.");
|
||||
}
|
||||
if (!isArrayOfNonEmptyString(ignorePatterns) && ignorePatterns !== null) {
|
||||
errors.push("'ignorePatterns' must be an array of non-empty strings or null.");
|
||||
}
|
||||
if (typeof overrideConfig !== "object") {
|
||||
errors.push("'overrideConfig' must be an object or null.");
|
||||
}
|
||||
if (!isNonEmptyString(overrideConfigFile) && overrideConfigFile !== null && overrideConfigFile !== true) {
|
||||
errors.push("'overrideConfigFile' must be a non-empty string, null, or true.");
|
||||
}
|
||||
if (typeof plugins !== "object") {
|
||||
errors.push("'plugins' must be an object or null.");
|
||||
} else if (plugins !== null && Object.keys(plugins).includes("")) {
|
||||
errors.push("'plugins' must not include an empty string.");
|
||||
}
|
||||
if (Array.isArray(plugins)) {
|
||||
errors.push("'plugins' doesn't add plugins to configuration to load. Please use the 'overrideConfig.plugins' option instead.");
|
||||
}
|
||||
if (typeof warnIgnored !== "boolean") {
|
||||
errors.push("'warnIgnored' must be a boolean.");
|
||||
}
|
||||
if (errors.length > 0) {
|
||||
throw new ESLintInvalidOptionsError(errors);
|
||||
}
|
||||
|
||||
return {
|
||||
allowInlineConfig,
|
||||
baseConfig,
|
||||
cache,
|
||||
cacheLocation,
|
||||
cacheStrategy,
|
||||
|
||||
// when overrideConfigFile is true that means don't do config file lookup
|
||||
configFile: overrideConfigFile === true ? false : overrideConfigFile,
|
||||
overrideConfig,
|
||||
cwd: path.normalize(cwd),
|
||||
errorOnUnmatchedPattern,
|
||||
fix,
|
||||
fixTypes,
|
||||
globInputPaths,
|
||||
ignore,
|
||||
ignorePatterns,
|
||||
warnIgnored
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Cache-related helpers
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* return the cacheFile to be used by eslint, based on whether the provided parameter is
|
||||
* a directory or looks like a directory (ends in `path.sep`), in which case the file
|
||||
* name will be the `cacheFile/.cache_hashOfCWD`
|
||||
*
|
||||
* if cacheFile points to a file or looks like a file then in will just use that file
|
||||
* @param {string} cacheFile The name of file to be used to store the cache
|
||||
* @param {string} cwd Current working directory
|
||||
* @returns {string} the resolved path to the cache file
|
||||
*/
|
||||
function getCacheFile(cacheFile, cwd) {
|
||||
|
||||
/*
|
||||
* make sure the path separators are normalized for the environment/os
|
||||
* keeping the trailing path separator if present
|
||||
*/
|
||||
const normalizedCacheFile = path.normalize(cacheFile);
|
||||
|
||||
const resolvedCacheFile = path.resolve(cwd, normalizedCacheFile);
|
||||
const looksLikeADirectory = normalizedCacheFile.slice(-1) === path.sep;
|
||||
|
||||
/**
|
||||
* return the name for the cache file in case the provided parameter is a directory
|
||||
* @returns {string} the resolved path to the cacheFile
|
||||
*/
|
||||
function getCacheFileForDirectory() {
|
||||
return path.join(resolvedCacheFile, `.cache_${hash(cwd)}`);
|
||||
}
|
||||
|
||||
let fileStats;
|
||||
|
||||
try {
|
||||
fileStats = fs.lstatSync(resolvedCacheFile);
|
||||
} catch {
|
||||
fileStats = null;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* in case the file exists we need to verify if the provided path
|
||||
* is a directory or a file. If it is a directory we want to create a file
|
||||
* inside that directory
|
||||
*/
|
||||
if (fileStats) {
|
||||
|
||||
/*
|
||||
* is a directory or is a file, but the original file the user provided
|
||||
* looks like a directory but `path.resolve` removed the `last path.sep`
|
||||
* so we need to still treat this like a directory
|
||||
*/
|
||||
if (fileStats.isDirectory() || looksLikeADirectory) {
|
||||
return getCacheFileForDirectory();
|
||||
}
|
||||
|
||||
// is file so just use that file
|
||||
return resolvedCacheFile;
|
||||
}
|
||||
|
||||
/*
|
||||
* here we known the file or directory doesn't exist,
|
||||
* so we will try to infer if its a directory if it looks like a directory
|
||||
* for the current operating system.
|
||||
*/
|
||||
|
||||
// if the last character passed is a path separator we assume is a directory
|
||||
if (looksLikeADirectory) {
|
||||
return getCacheFileForDirectory();
|
||||
}
|
||||
|
||||
return resolvedCacheFile;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Exports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
module.exports = {
|
||||
isGlobPattern,
|
||||
findFiles,
|
||||
|
||||
isNonEmptyString,
|
||||
isArrayOfNonEmptyString,
|
||||
|
||||
createIgnoreResult,
|
||||
isErrorMessage,
|
||||
|
||||
processOptions,
|
||||
|
||||
getCacheFile
|
||||
};
|
||||
707
frontend/.ignored_node_modules/eslint/lib/eslint/eslint.js
generated
Normal file
707
frontend/.ignored_node_modules/eslint/lib/eslint/eslint.js
generated
Normal file
@@ -0,0 +1,707 @@
|
||||
/**
|
||||
* @fileoverview Main API Class
|
||||
* @author Kai Cataldo
|
||||
* @author Toru Nagashima
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const { promisify } = require("util");
|
||||
const { CLIEngine, getCLIEngineInternalSlots } = require("../cli-engine/cli-engine");
|
||||
const BuiltinRules = require("../rules");
|
||||
const {
|
||||
Legacy: {
|
||||
ConfigOps: {
|
||||
getRuleSeverity
|
||||
}
|
||||
}
|
||||
} = require("@eslint/eslintrc");
|
||||
const { version } = require("../../package.json");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Typedefs
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/** @typedef {import("../cli-engine/cli-engine").LintReport} CLIEngineLintReport */
|
||||
/** @typedef {import("../shared/types").DeprecatedRuleInfo} DeprecatedRuleInfo */
|
||||
/** @typedef {import("../shared/types").ConfigData} ConfigData */
|
||||
/** @typedef {import("../shared/types").LintMessage} LintMessage */
|
||||
/** @typedef {import("../shared/types").SuppressedLintMessage} SuppressedLintMessage */
|
||||
/** @typedef {import("../shared/types").Plugin} Plugin */
|
||||
/** @typedef {import("../shared/types").Rule} Rule */
|
||||
/** @typedef {import("../shared/types").LintResult} LintResult */
|
||||
/** @typedef {import("../shared/types").ResultsMeta} ResultsMeta */
|
||||
|
||||
/**
|
||||
* The main formatter object.
|
||||
* @typedef LoadedFormatter
|
||||
* @property {(results: LintResult[], resultsMeta: ResultsMeta) => string | Promise<string>} format format function.
|
||||
*/
|
||||
|
||||
/**
|
||||
* The options with which to configure the ESLint instance.
|
||||
* @typedef {Object} ESLintOptions
|
||||
* @property {boolean} [allowInlineConfig] Enable or disable inline configuration comments.
|
||||
* @property {ConfigData} [baseConfig] Base config object, extended by all configs used with this instance
|
||||
* @property {boolean} [cache] Enable result caching.
|
||||
* @property {string} [cacheLocation] The cache file to use instead of .eslintcache.
|
||||
* @property {"metadata" | "content"} [cacheStrategy] The strategy used to detect changed files.
|
||||
* @property {string} [cwd] The value to use for the current working directory.
|
||||
* @property {boolean} [errorOnUnmatchedPattern] If `false` then `ESLint#lintFiles()` doesn't throw even if no target files found. Defaults to `true`.
|
||||
* @property {string[]} [extensions] An array of file extensions to check.
|
||||
* @property {boolean|Function} [fix] Execute in autofix mode. If a function, should return a boolean.
|
||||
* @property {string[]} [fixTypes] Array of rule types to apply fixes for.
|
||||
* @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file.
|
||||
* @property {boolean} [ignore] False disables use of .eslintignore.
|
||||
* @property {string} [ignorePath] The ignore file to use instead of .eslintignore.
|
||||
* @property {ConfigData} [overrideConfig] Override config object, overrides all configs used with this instance
|
||||
* @property {string} [overrideConfigFile] The configuration file to use.
|
||||
* @property {Record<string,Plugin>|null} [plugins] Preloaded plugins. This is a map-like object, keys are plugin IDs and each value is implementation.
|
||||
* @property {"error" | "warn" | "off"} [reportUnusedDisableDirectives] the severity to report unused eslint-disable directives.
|
||||
* @property {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD.
|
||||
* @property {string[]} [rulePaths] An array of directories to load custom rules from.
|
||||
* @property {boolean} [useEslintrc] False disables looking for .eslintrc.* files.
|
||||
*/
|
||||
|
||||
/**
|
||||
* A rules metadata object.
|
||||
* @typedef {Object} RulesMeta
|
||||
* @property {string} id The plugin ID.
|
||||
* @property {Object} definition The plugin definition.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Private members for the `ESLint` instance.
|
||||
* @typedef {Object} ESLintPrivateMembers
|
||||
* @property {CLIEngine} cliEngine The wrapped CLIEngine instance.
|
||||
* @property {ESLintOptions} options The options used to instantiate the ESLint instance.
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Helpers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const writeFile = promisify(fs.writeFile);
|
||||
|
||||
/**
|
||||
* The map with which to store private class members.
|
||||
* @type {WeakMap<ESLint, ESLintPrivateMembers>}
|
||||
*/
|
||||
const privateMembersMap = new WeakMap();
|
||||
|
||||
/**
|
||||
* Check if a given value is a non-empty string or not.
|
||||
* @param {any} x The value to check.
|
||||
* @returns {boolean} `true` if `x` is a non-empty string.
|
||||
*/
|
||||
function isNonEmptyString(x) {
|
||||
return typeof x === "string" && x.trim() !== "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given value is an array of non-empty strings or not.
|
||||
* @param {any} x The value to check.
|
||||
* @returns {boolean} `true` if `x` is an array of non-empty strings.
|
||||
*/
|
||||
function isArrayOfNonEmptyString(x) {
|
||||
return Array.isArray(x) && x.every(isNonEmptyString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given value is a valid fix type or not.
|
||||
* @param {any} x The value to check.
|
||||
* @returns {boolean} `true` if `x` is valid fix type.
|
||||
*/
|
||||
function isFixType(x) {
|
||||
return x === "directive" || x === "problem" || x === "suggestion" || x === "layout";
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given value is an array of fix types or not.
|
||||
* @param {any} x The value to check.
|
||||
* @returns {boolean} `true` if `x` is an array of fix types.
|
||||
*/
|
||||
function isFixTypeArray(x) {
|
||||
return Array.isArray(x) && x.every(isFixType);
|
||||
}
|
||||
|
||||
/**
|
||||
* The error for invalid options.
|
||||
*/
|
||||
class ESLintInvalidOptionsError extends Error {
|
||||
constructor(messages) {
|
||||
super(`Invalid Options:\n- ${messages.join("\n- ")}`);
|
||||
this.code = "ESLINT_INVALID_OPTIONS";
|
||||
Error.captureStackTrace(this, ESLintInvalidOptionsError);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates and normalizes options for the wrapped CLIEngine instance.
|
||||
* @param {ESLintOptions} options The options to process.
|
||||
* @throws {ESLintInvalidOptionsError} If of any of a variety of type errors.
|
||||
* @returns {ESLintOptions} The normalized options.
|
||||
*/
|
||||
function processOptions({
|
||||
allowInlineConfig = true, // ← we cannot use `overrideConfig.noInlineConfig` instead because `allowInlineConfig` has side-effect that suppress warnings that show inline configs are ignored.
|
||||
baseConfig = null,
|
||||
cache = false,
|
||||
cacheLocation = ".eslintcache",
|
||||
cacheStrategy = "metadata",
|
||||
cwd = process.cwd(),
|
||||
errorOnUnmatchedPattern = true,
|
||||
extensions = null, // ← should be null by default because if it's an array then it suppresses RFC20 feature.
|
||||
fix = false,
|
||||
fixTypes = null, // ← should be null by default because if it's an array then it suppresses rules that don't have the `meta.type` property.
|
||||
globInputPaths = true,
|
||||
ignore = true,
|
||||
ignorePath = null, // ← should be null by default because if it's a string then it may throw ENOENT.
|
||||
overrideConfig = null,
|
||||
overrideConfigFile = null,
|
||||
plugins = {},
|
||||
reportUnusedDisableDirectives = null, // ← should be null by default because if it's a string then it overrides the 'reportUnusedDisableDirectives' setting in config files. And we cannot use `overrideConfig.reportUnusedDisableDirectives` instead because we cannot configure the `error` severity with that.
|
||||
resolvePluginsRelativeTo = null, // ← should be null by default because if it's a string then it suppresses RFC47 feature.
|
||||
rulePaths = [],
|
||||
useEslintrc = true,
|
||||
...unknownOptions
|
||||
}) {
|
||||
const errors = [];
|
||||
const unknownOptionKeys = Object.keys(unknownOptions);
|
||||
|
||||
if (unknownOptionKeys.length >= 1) {
|
||||
errors.push(`Unknown options: ${unknownOptionKeys.join(", ")}`);
|
||||
if (unknownOptionKeys.includes("cacheFile")) {
|
||||
errors.push("'cacheFile' has been removed. Please use the 'cacheLocation' option instead.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("configFile")) {
|
||||
errors.push("'configFile' has been removed. Please use the 'overrideConfigFile' option instead.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("envs")) {
|
||||
errors.push("'envs' has been removed. Please use the 'overrideConfig.env' option instead.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("globals")) {
|
||||
errors.push("'globals' has been removed. Please use the 'overrideConfig.globals' option instead.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("ignorePattern")) {
|
||||
errors.push("'ignorePattern' has been removed. Please use the 'overrideConfig.ignorePatterns' option instead.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("parser")) {
|
||||
errors.push("'parser' has been removed. Please use the 'overrideConfig.parser' option instead.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("parserOptions")) {
|
||||
errors.push("'parserOptions' has been removed. Please use the 'overrideConfig.parserOptions' option instead.");
|
||||
}
|
||||
if (unknownOptionKeys.includes("rules")) {
|
||||
errors.push("'rules' has been removed. Please use the 'overrideConfig.rules' option instead.");
|
||||
}
|
||||
}
|
||||
if (typeof allowInlineConfig !== "boolean") {
|
||||
errors.push("'allowInlineConfig' must be a boolean.");
|
||||
}
|
||||
if (typeof baseConfig !== "object") {
|
||||
errors.push("'baseConfig' must be an object or null.");
|
||||
}
|
||||
if (typeof cache !== "boolean") {
|
||||
errors.push("'cache' must be a boolean.");
|
||||
}
|
||||
if (!isNonEmptyString(cacheLocation)) {
|
||||
errors.push("'cacheLocation' must be a non-empty string.");
|
||||
}
|
||||
if (
|
||||
cacheStrategy !== "metadata" &&
|
||||
cacheStrategy !== "content"
|
||||
) {
|
||||
errors.push("'cacheStrategy' must be any of \"metadata\", \"content\".");
|
||||
}
|
||||
if (!isNonEmptyString(cwd) || !path.isAbsolute(cwd)) {
|
||||
errors.push("'cwd' must be an absolute path.");
|
||||
}
|
||||
if (typeof errorOnUnmatchedPattern !== "boolean") {
|
||||
errors.push("'errorOnUnmatchedPattern' must be a boolean.");
|
||||
}
|
||||
if (!isArrayOfNonEmptyString(extensions) && extensions !== null) {
|
||||
errors.push("'extensions' must be an array of non-empty strings or null.");
|
||||
}
|
||||
if (typeof fix !== "boolean" && typeof fix !== "function") {
|
||||
errors.push("'fix' must be a boolean or a function.");
|
||||
}
|
||||
if (fixTypes !== null && !isFixTypeArray(fixTypes)) {
|
||||
errors.push("'fixTypes' must be an array of any of \"directive\", \"problem\", \"suggestion\", and \"layout\".");
|
||||
}
|
||||
if (typeof globInputPaths !== "boolean") {
|
||||
errors.push("'globInputPaths' must be a boolean.");
|
||||
}
|
||||
if (typeof ignore !== "boolean") {
|
||||
errors.push("'ignore' must be a boolean.");
|
||||
}
|
||||
if (!isNonEmptyString(ignorePath) && ignorePath !== null) {
|
||||
errors.push("'ignorePath' must be a non-empty string or null.");
|
||||
}
|
||||
if (typeof overrideConfig !== "object") {
|
||||
errors.push("'overrideConfig' must be an object or null.");
|
||||
}
|
||||
if (!isNonEmptyString(overrideConfigFile) && overrideConfigFile !== null) {
|
||||
errors.push("'overrideConfigFile' must be a non-empty string or null.");
|
||||
}
|
||||
if (typeof plugins !== "object") {
|
||||
errors.push("'plugins' must be an object or null.");
|
||||
} else if (plugins !== null && Object.keys(plugins).includes("")) {
|
||||
errors.push("'plugins' must not include an empty string.");
|
||||
}
|
||||
if (Array.isArray(plugins)) {
|
||||
errors.push("'plugins' doesn't add plugins to configuration to load. Please use the 'overrideConfig.plugins' option instead.");
|
||||
}
|
||||
if (
|
||||
reportUnusedDisableDirectives !== "error" &&
|
||||
reportUnusedDisableDirectives !== "warn" &&
|
||||
reportUnusedDisableDirectives !== "off" &&
|
||||
reportUnusedDisableDirectives !== null
|
||||
) {
|
||||
errors.push("'reportUnusedDisableDirectives' must be any of \"error\", \"warn\", \"off\", and null.");
|
||||
}
|
||||
if (
|
||||
!isNonEmptyString(resolvePluginsRelativeTo) &&
|
||||
resolvePluginsRelativeTo !== null
|
||||
) {
|
||||
errors.push("'resolvePluginsRelativeTo' must be a non-empty string or null.");
|
||||
}
|
||||
if (!isArrayOfNonEmptyString(rulePaths)) {
|
||||
errors.push("'rulePaths' must be an array of non-empty strings.");
|
||||
}
|
||||
if (typeof useEslintrc !== "boolean") {
|
||||
errors.push("'useEslintrc' must be a boolean.");
|
||||
}
|
||||
|
||||
if (errors.length > 0) {
|
||||
throw new ESLintInvalidOptionsError(errors);
|
||||
}
|
||||
|
||||
return {
|
||||
allowInlineConfig,
|
||||
baseConfig,
|
||||
cache,
|
||||
cacheLocation,
|
||||
cacheStrategy,
|
||||
configFile: overrideConfigFile,
|
||||
cwd: path.normalize(cwd),
|
||||
errorOnUnmatchedPattern,
|
||||
extensions,
|
||||
fix,
|
||||
fixTypes,
|
||||
globInputPaths,
|
||||
ignore,
|
||||
ignorePath,
|
||||
reportUnusedDisableDirectives,
|
||||
resolvePluginsRelativeTo,
|
||||
rulePaths,
|
||||
useEslintrc
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a value has one or more properties and that value is not undefined.
|
||||
* @param {any} obj The value to check.
|
||||
* @returns {boolean} `true` if `obj` has one or more properties that that value is not undefined.
|
||||
*/
|
||||
function hasDefinedProperty(obj) {
|
||||
if (typeof obj === "object" && obj !== null) {
|
||||
for (const key in obj) {
|
||||
if (typeof obj[key] !== "undefined") {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create rulesMeta object.
|
||||
* @param {Map<string,Rule>} rules a map of rules from which to generate the object.
|
||||
* @returns {Object} metadata for all enabled rules.
|
||||
*/
|
||||
function createRulesMeta(rules) {
|
||||
return Array.from(rules).reduce((retVal, [id, rule]) => {
|
||||
retVal[id] = rule.meta;
|
||||
return retVal;
|
||||
}, {});
|
||||
}
|
||||
|
||||
/** @type {WeakMap<ExtractedConfig, DeprecatedRuleInfo[]>} */
|
||||
const usedDeprecatedRulesCache = new WeakMap();
|
||||
|
||||
/**
|
||||
* Create used deprecated rule list.
|
||||
* @param {CLIEngine} cliEngine The CLIEngine instance.
|
||||
* @param {string} maybeFilePath The absolute path to a lint target file or `"<text>"`.
|
||||
* @returns {DeprecatedRuleInfo[]} The used deprecated rule list.
|
||||
*/
|
||||
function getOrFindUsedDeprecatedRules(cliEngine, maybeFilePath) {
|
||||
const {
|
||||
configArrayFactory,
|
||||
options: { cwd }
|
||||
} = getCLIEngineInternalSlots(cliEngine);
|
||||
const filePath = path.isAbsolute(maybeFilePath)
|
||||
? maybeFilePath
|
||||
: path.join(cwd, "__placeholder__.js");
|
||||
const configArray = configArrayFactory.getConfigArrayForFile(filePath);
|
||||
const config = configArray.extractConfig(filePath);
|
||||
|
||||
// Most files use the same config, so cache it.
|
||||
if (!usedDeprecatedRulesCache.has(config)) {
|
||||
const pluginRules = configArray.pluginRules;
|
||||
const retv = [];
|
||||
|
||||
for (const [ruleId, ruleConf] of Object.entries(config.rules)) {
|
||||
if (getRuleSeverity(ruleConf) === 0) {
|
||||
continue;
|
||||
}
|
||||
const rule = pluginRules.get(ruleId) || BuiltinRules.get(ruleId);
|
||||
const meta = rule && rule.meta;
|
||||
|
||||
if (meta && meta.deprecated) {
|
||||
retv.push({ ruleId, replacedBy: meta.replacedBy || [] });
|
||||
}
|
||||
}
|
||||
|
||||
usedDeprecatedRulesCache.set(config, Object.freeze(retv));
|
||||
}
|
||||
|
||||
return usedDeprecatedRulesCache.get(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the linting results generated by a CLIEngine linting report to
|
||||
* match the ESLint class's API.
|
||||
* @param {CLIEngine} cliEngine The CLIEngine instance.
|
||||
* @param {CLIEngineLintReport} report The CLIEngine linting report to process.
|
||||
* @returns {LintResult[]} The processed linting results.
|
||||
*/
|
||||
function processCLIEngineLintReport(cliEngine, { results }) {
|
||||
const descriptor = {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get() {
|
||||
return getOrFindUsedDeprecatedRules(cliEngine, this.filePath);
|
||||
}
|
||||
};
|
||||
|
||||
for (const result of results) {
|
||||
Object.defineProperty(result, "usedDeprecatedRules", descriptor);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* An Array.prototype.sort() compatible compare function to order results by their file path.
|
||||
* @param {LintResult} a The first lint result.
|
||||
* @param {LintResult} b The second lint result.
|
||||
* @returns {number} An integer representing the order in which the two results should occur.
|
||||
*/
|
||||
function compareResultsByFilePath(a, b) {
|
||||
if (a.filePath < b.filePath) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (a.filePath > b.filePath) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main API.
|
||||
*/
|
||||
class ESLint {
|
||||
|
||||
/**
|
||||
* Creates a new instance of the main ESLint API.
|
||||
* @param {ESLintOptions} options The options for this instance.
|
||||
*/
|
||||
constructor(options = {}) {
|
||||
const processedOptions = processOptions(options);
|
||||
const cliEngine = new CLIEngine(processedOptions, { preloadedPlugins: options.plugins });
|
||||
const {
|
||||
configArrayFactory,
|
||||
lastConfigArrays
|
||||
} = getCLIEngineInternalSlots(cliEngine);
|
||||
let updated = false;
|
||||
|
||||
/*
|
||||
* Address `overrideConfig` to set override config.
|
||||
* Operate the `configArrayFactory` internal slot directly because this
|
||||
* functionality doesn't exist as the public API of CLIEngine.
|
||||
*/
|
||||
if (hasDefinedProperty(options.overrideConfig)) {
|
||||
configArrayFactory.setOverrideConfig(options.overrideConfig);
|
||||
updated = true;
|
||||
}
|
||||
|
||||
// Update caches.
|
||||
if (updated) {
|
||||
configArrayFactory.clearCache();
|
||||
lastConfigArrays[0] = configArrayFactory.getConfigArrayForFile();
|
||||
}
|
||||
|
||||
// Initialize private properties.
|
||||
privateMembersMap.set(this, {
|
||||
cliEngine,
|
||||
options: processedOptions
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The version text.
|
||||
* @type {string}
|
||||
*/
|
||||
static get version() {
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs fixes from the given results to files.
|
||||
* @param {LintResult[]} results The lint results.
|
||||
* @returns {Promise<void>} Returns a promise that is used to track side effects.
|
||||
*/
|
||||
static async outputFixes(results) {
|
||||
if (!Array.isArray(results)) {
|
||||
throw new Error("'results' must be an array");
|
||||
}
|
||||
|
||||
await Promise.all(
|
||||
results
|
||||
.filter(result => {
|
||||
if (typeof result !== "object" || result === null) {
|
||||
throw new Error("'results' must include only objects");
|
||||
}
|
||||
return (
|
||||
typeof result.output === "string" &&
|
||||
path.isAbsolute(result.filePath)
|
||||
);
|
||||
})
|
||||
.map(r => writeFile(r.filePath, r.output))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns results that only contains errors.
|
||||
* @param {LintResult[]} results The results to filter.
|
||||
* @returns {LintResult[]} The filtered results.
|
||||
*/
|
||||
static getErrorResults(results) {
|
||||
return CLIEngine.getErrorResults(results);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns meta objects for each rule represented in the lint results.
|
||||
* @param {LintResult[]} results The results to fetch rules meta for.
|
||||
* @returns {Object} A mapping of ruleIds to rule meta objects.
|
||||
*/
|
||||
getRulesMetaForResults(results) {
|
||||
|
||||
const resultRuleIds = new Set();
|
||||
|
||||
// first gather all ruleIds from all results
|
||||
|
||||
for (const result of results) {
|
||||
for (const { ruleId } of result.messages) {
|
||||
resultRuleIds.add(ruleId);
|
||||
}
|
||||
for (const { ruleId } of result.suppressedMessages) {
|
||||
resultRuleIds.add(ruleId);
|
||||
}
|
||||
}
|
||||
|
||||
// create a map of all rules in the results
|
||||
|
||||
const { cliEngine } = privateMembersMap.get(this);
|
||||
const rules = cliEngine.getRules();
|
||||
const resultRules = new Map();
|
||||
|
||||
for (const [ruleId, rule] of rules) {
|
||||
if (resultRuleIds.has(ruleId)) {
|
||||
resultRules.set(ruleId, rule);
|
||||
}
|
||||
}
|
||||
|
||||
return createRulesMeta(resultRules);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the current configuration on an array of file and directory names.
|
||||
* @param {string[]} patterns An array of file and directory names.
|
||||
* @returns {Promise<LintResult[]>} The results of linting the file patterns given.
|
||||
*/
|
||||
async lintFiles(patterns) {
|
||||
if (!isNonEmptyString(patterns) && !isArrayOfNonEmptyString(patterns)) {
|
||||
throw new Error("'patterns' must be a non-empty string or an array of non-empty strings");
|
||||
}
|
||||
const { cliEngine } = privateMembersMap.get(this);
|
||||
|
||||
return processCLIEngineLintReport(
|
||||
cliEngine,
|
||||
cliEngine.executeOnFiles(patterns)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the current configuration on text.
|
||||
* @param {string} code A string of JavaScript code to lint.
|
||||
* @param {Object} [options] The options.
|
||||
* @param {string} [options.filePath] The path to the file of the source code.
|
||||
* @param {boolean} [options.warnIgnored] When set to true, warn if given filePath is an ignored path.
|
||||
* @returns {Promise<LintResult[]>} The results of linting the string of code given.
|
||||
*/
|
||||
async lintText(code, options = {}) {
|
||||
if (typeof code !== "string") {
|
||||
throw new Error("'code' must be a string");
|
||||
}
|
||||
if (typeof options !== "object") {
|
||||
throw new Error("'options' must be an object, null, or undefined");
|
||||
}
|
||||
const {
|
||||
filePath,
|
||||
warnIgnored = false,
|
||||
...unknownOptions
|
||||
} = options || {};
|
||||
|
||||
const unknownOptionKeys = Object.keys(unknownOptions);
|
||||
|
||||
if (unknownOptionKeys.length > 0) {
|
||||
throw new Error(`'options' must not include the unknown option(s): ${unknownOptionKeys.join(", ")}`);
|
||||
}
|
||||
|
||||
if (filePath !== void 0 && !isNonEmptyString(filePath)) {
|
||||
throw new Error("'options.filePath' must be a non-empty string or undefined");
|
||||
}
|
||||
if (typeof warnIgnored !== "boolean") {
|
||||
throw new Error("'options.warnIgnored' must be a boolean or undefined");
|
||||
}
|
||||
|
||||
const { cliEngine } = privateMembersMap.get(this);
|
||||
|
||||
return processCLIEngineLintReport(
|
||||
cliEngine,
|
||||
cliEngine.executeOnText(code, filePath, warnIgnored)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the formatter representing the given formatter name.
|
||||
* @param {string} [name] The name of the formatter to load.
|
||||
* The following values are allowed:
|
||||
* - `undefined` ... Load `stylish` builtin formatter.
|
||||
* - A builtin formatter name ... Load the builtin formatter.
|
||||
* - A third-party formatter name:
|
||||
* - `foo` → `eslint-formatter-foo`
|
||||
* - `@foo` → `@foo/eslint-formatter`
|
||||
* - `@foo/bar` → `@foo/eslint-formatter-bar`
|
||||
* - A file path ... Load the file.
|
||||
* @returns {Promise<LoadedFormatter>} A promise resolving to the formatter object.
|
||||
* This promise will be rejected if the given formatter was not found or not
|
||||
* a function.
|
||||
*/
|
||||
async loadFormatter(name = "stylish") {
|
||||
if (typeof name !== "string") {
|
||||
throw new Error("'name' must be a string");
|
||||
}
|
||||
|
||||
const { cliEngine, options } = privateMembersMap.get(this);
|
||||
const formatter = cliEngine.getFormatter(name);
|
||||
|
||||
if (typeof formatter !== "function") {
|
||||
throw new Error(`Formatter must be a function, but got a ${typeof formatter}.`);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
/**
|
||||
* The main formatter method.
|
||||
* @param {LintResult[]} results The lint results to format.
|
||||
* @param {ResultsMeta} resultsMeta Warning count and max threshold.
|
||||
* @returns {string | Promise<string>} The formatted lint results.
|
||||
*/
|
||||
format(results, resultsMeta) {
|
||||
let rulesMeta = null;
|
||||
|
||||
results.sort(compareResultsByFilePath);
|
||||
|
||||
return formatter(results, {
|
||||
...resultsMeta,
|
||||
get cwd() {
|
||||
return options.cwd;
|
||||
},
|
||||
get rulesMeta() {
|
||||
if (!rulesMeta) {
|
||||
rulesMeta = createRulesMeta(cliEngine.getRules());
|
||||
}
|
||||
|
||||
return rulesMeta;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a configuration object for the given file based on the CLI options.
|
||||
* This is the same logic used by the ESLint CLI executable to determine
|
||||
* configuration for each file it processes.
|
||||
* @param {string} filePath The path of the file to retrieve a config object for.
|
||||
* @returns {Promise<ConfigData>} A configuration object for the file.
|
||||
*/
|
||||
async calculateConfigForFile(filePath) {
|
||||
if (!isNonEmptyString(filePath)) {
|
||||
throw new Error("'filePath' must be a non-empty string");
|
||||
}
|
||||
const { cliEngine } = privateMembersMap.get(this);
|
||||
|
||||
return cliEngine.getConfigForFile(filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given path is ignored by ESLint.
|
||||
* @param {string} filePath The path of the file to check.
|
||||
* @returns {Promise<boolean>} Whether or not the given path is ignored.
|
||||
*/
|
||||
async isPathIgnored(filePath) {
|
||||
if (!isNonEmptyString(filePath)) {
|
||||
throw new Error("'filePath' must be a non-empty string");
|
||||
}
|
||||
const { cliEngine } = privateMembersMap.get(this);
|
||||
|
||||
return cliEngine.isPathIgnored(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of configuration used by this class.
|
||||
* @type {string}
|
||||
* @static
|
||||
*/
|
||||
ESLint.configType = "eslintrc";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
module.exports = {
|
||||
ESLint,
|
||||
|
||||
/**
|
||||
* Get the private class members of a given ESLint instance for tests.
|
||||
* @param {ESLint} instance The ESLint instance to get.
|
||||
* @returns {ESLintPrivateMembers} The instance's private class members.
|
||||
*/
|
||||
getESLintPrivateMembers(instance) {
|
||||
return privateMembersMap.get(instance);
|
||||
}
|
||||
};
|
||||
1159
frontend/.ignored_node_modules/eslint/lib/eslint/flat-eslint.js
generated
Normal file
1159
frontend/.ignored_node_modules/eslint/lib/eslint/flat-eslint.js
generated
Normal file
File diff suppressed because it is too large
Load Diff
9
frontend/.ignored_node_modules/eslint/lib/eslint/index.js
generated
Normal file
9
frontend/.ignored_node_modules/eslint/lib/eslint/index.js
generated
Normal file
@@ -0,0 +1,9 @@
|
||||
"use strict";
|
||||
|
||||
const { ESLint } = require("./eslint");
|
||||
const { FlatESLint } = require("./flat-eslint");
|
||||
|
||||
module.exports = {
|
||||
ESLint,
|
||||
FlatESLint
|
||||
};
|
||||
Reference in New Issue
Block a user