Spaces:
Runtime error
Runtime error
chatwine-korean
/
vivino-api
/node_modules
/@eslint
/eslintrc
/lib
/config-array
/override-tester.js
/** | |
* @fileoverview `OverrideTester` class. | |
* | |
* `OverrideTester` class handles `files` property and `excludedFiles` property | |
* of `overrides` config. | |
* | |
* It provides one method. | |
* | |
* - `test(filePath)` | |
* Test if a file path matches the pair of `files` property and | |
* `excludedFiles` property. The `filePath` argument must be an absolute | |
* path. | |
* | |
* `ConfigArrayFactory` creates `OverrideTester` objects when it processes | |
* `overrides` properties. | |
* | |
* @author Toru Nagashima <https://github.com/mysticatea> | |
*/ | |
; | |
const assert = require("assert"); | |
const path = require("path"); | |
const util = require("util"); | |
const { Minimatch } = require("minimatch"); | |
const minimatchOpts = { dot: true, matchBase: true }; | |
/** | |
* @typedef {Object} Pattern | |
* @property {InstanceType<Minimatch>[] | null} includes The positive matchers. | |
* @property {InstanceType<Minimatch>[] | null} excludes The negative matchers. | |
*/ | |
/** | |
* Normalize a given pattern to an array. | |
* @param {string|string[]|undefined} patterns A glob pattern or an array of glob patterns. | |
* @returns {string[]|null} Normalized patterns. | |
* @private | |
*/ | |
function normalizePatterns(patterns) { | |
if (Array.isArray(patterns)) { | |
return patterns.filter(Boolean); | |
} | |
if (typeof patterns === "string" && patterns) { | |
return [patterns]; | |
} | |
return []; | |
} | |
/** | |
* Create the matchers of given patterns. | |
* @param {string[]} patterns The patterns. | |
* @returns {InstanceType<Minimatch>[] | null} The matchers. | |
*/ | |
function toMatcher(patterns) { | |
if (patterns.length === 0) { | |
return null; | |
} | |
return patterns.map(pattern => { | |
if (/^\.[/\\]/u.test(pattern)) { | |
return new Minimatch( | |
pattern.slice(2), | |
// `./*.js` should not match with `subdir/foo.js` | |
{ ...minimatchOpts, matchBase: false } | |
); | |
} | |
return new Minimatch(pattern, minimatchOpts); | |
}); | |
} | |
/** | |
* Convert a given matcher to string. | |
* @param {Pattern} matchers The matchers. | |
* @returns {string} The string expression of the matcher. | |
*/ | |
function patternToJson({ includes, excludes }) { | |
return { | |
includes: includes && includes.map(m => m.pattern), | |
excludes: excludes && excludes.map(m => m.pattern) | |
}; | |
} | |
/** | |
* The class to test given paths are matched by the patterns. | |
*/ | |
class OverrideTester { | |
/** | |
* Create a tester with given criteria. | |
* If there are no criteria, returns `null`. | |
* @param {string|string[]} files The glob patterns for included files. | |
* @param {string|string[]} excludedFiles The glob patterns for excluded files. | |
* @param {string} basePath The path to the base directory to test paths. | |
* @returns {OverrideTester|null} The created instance or `null`. | |
*/ | |
static create(files, excludedFiles, basePath) { | |
const includePatterns = normalizePatterns(files); | |
const excludePatterns = normalizePatterns(excludedFiles); | |
let endsWithWildcard = false; | |
if (includePatterns.length === 0) { | |
return null; | |
} | |
// Rejects absolute paths or relative paths to parents. | |
for (const pattern of includePatterns) { | |
if (path.isAbsolute(pattern) || pattern.includes("..")) { | |
throw new Error(`Invalid override pattern (expected relative path not containing '..'): ${pattern}`); | |
} | |
if (pattern.endsWith("*")) { | |
endsWithWildcard = true; | |
} | |
} | |
for (const pattern of excludePatterns) { | |
if (path.isAbsolute(pattern) || pattern.includes("..")) { | |
throw new Error(`Invalid override pattern (expected relative path not containing '..'): ${pattern}`); | |
} | |
} | |
const includes = toMatcher(includePatterns); | |
const excludes = toMatcher(excludePatterns); | |
return new OverrideTester( | |
[{ includes, excludes }], | |
basePath, | |
endsWithWildcard | |
); | |
} | |
/** | |
* Combine two testers by logical and. | |
* If either of the testers was `null`, returns the other tester. | |
* The `basePath` property of the two must be the same value. | |
* @param {OverrideTester|null} a A tester. | |
* @param {OverrideTester|null} b Another tester. | |
* @returns {OverrideTester|null} Combined tester. | |
*/ | |
static and(a, b) { | |
if (!b) { | |
return a && new OverrideTester( | |
a.patterns, | |
a.basePath, | |
a.endsWithWildcard | |
); | |
} | |
if (!a) { | |
return new OverrideTester( | |
b.patterns, | |
b.basePath, | |
b.endsWithWildcard | |
); | |
} | |
assert.strictEqual(a.basePath, b.basePath); | |
return new OverrideTester( | |
a.patterns.concat(b.patterns), | |
a.basePath, | |
a.endsWithWildcard || b.endsWithWildcard | |
); | |
} | |
/** | |
* Initialize this instance. | |
* @param {Pattern[]} patterns The matchers. | |
* @param {string} basePath The base path. | |
* @param {boolean} endsWithWildcard If `true` then a pattern ends with `*`. | |
*/ | |
constructor(patterns, basePath, endsWithWildcard = false) { | |
/** @type {Pattern[]} */ | |
this.patterns = patterns; | |
/** @type {string} */ | |
this.basePath = basePath; | |
/** @type {boolean} */ | |
this.endsWithWildcard = endsWithWildcard; | |
} | |
/** | |
* Test if a given path is matched or not. | |
* @param {string} filePath The absolute path to the target file. | |
* @returns {boolean} `true` if the path was matched. | |
*/ | |
test(filePath) { | |
if (typeof filePath !== "string" || !path.isAbsolute(filePath)) { | |
throw new Error(`'filePath' should be an absolute path, but got ${filePath}.`); | |
} | |
const relativePath = path.relative(this.basePath, filePath); | |
return this.patterns.every(({ includes, excludes }) => ( | |
(!includes || includes.some(m => m.match(relativePath))) && | |
(!excludes || !excludes.some(m => m.match(relativePath))) | |
)); | |
} | |
// eslint-disable-next-line jsdoc/require-description | |
/** | |
* @returns {Object} a JSON compatible object. | |
*/ | |
toJSON() { | |
if (this.patterns.length === 1) { | |
return { | |
...patternToJson(this.patterns[0]), | |
basePath: this.basePath | |
}; | |
} | |
return { | |
AND: this.patterns.map(patternToJson), | |
basePath: this.basePath | |
}; | |
} | |
// eslint-disable-next-line jsdoc/require-description | |
/** | |
* @returns {Object} an object to display by `console.log()`. | |
*/ | |
[util.inspect.custom]() { | |
return this.toJSON(); | |
} | |
} | |
module.exports = { OverrideTester }; | |