@humanwhocodes/config-array
Advanced tools
Comparing version 0.10.3 to 0.10.4
394
api.js
@@ -237,3 +237,3 @@ 'use strict'; | ||
// all files outside of the basePath are ignored | ||
if (relativeFilePath.startsWith("..")) { | ||
if (relativeFilePath.startsWith('..')) { | ||
return true; | ||
@@ -403,25 +403,25 @@ } | ||
*/ | ||
constructor(configs,{ | ||
basePath = '', | ||
normalized = false, | ||
schema: customSchema, | ||
extraConfigTypes = [] | ||
} = {} | ||
) { | ||
constructor(configs, { | ||
basePath = '', | ||
normalized = false, | ||
schema: customSchema, | ||
extraConfigTypes = [] | ||
} = {} | ||
) { | ||
super(); | ||
/** | ||
* Tracks if the array has been normalized. | ||
* @property isNormalized | ||
* @type boolean | ||
* @private | ||
*/ | ||
* Tracks if the array has been normalized. | ||
* @property isNormalized | ||
* @type boolean | ||
* @private | ||
*/ | ||
this[ConfigArraySymbol.isNormalized] = normalized; | ||
/** | ||
* The schema used for validating and merging configs. | ||
* @property schema | ||
* @type ObjectSchema | ||
* @private | ||
*/ | ||
* The schema used for validating and merging configs. | ||
* @property schema | ||
* @type ObjectSchema | ||
* @private | ||
*/ | ||
this[ConfigArraySymbol.schema] = new objectSchema.ObjectSchema({ | ||
@@ -433,7 +433,7 @@ ...customSchema, | ||
/** | ||
* The path of the config file that this array was loaded from. | ||
* This is used to calculate filename matches. | ||
* @property basePath | ||
* @type string | ||
*/ | ||
* The path of the config file that this array was loaded from. | ||
* This is used to calculate filename matches. | ||
* @property basePath | ||
* @type string | ||
*/ | ||
this.basePath = basePath; | ||
@@ -444,14 +444,14 @@ | ||
/** | ||
* The supported config types. | ||
* @property configTypes | ||
* @type Array<string> | ||
*/ | ||
* The supported config types. | ||
* @property configTypes | ||
* @type Array<string> | ||
*/ | ||
this.extraConfigTypes = Object.freeze([...extraConfigTypes]); | ||
/** | ||
* A cache to store calculated configs for faster repeat lookup. | ||
* @property configCache | ||
* @type Map | ||
* @private | ||
*/ | ||
* A cache to store calculated configs for faster repeat lookup. | ||
* @property configCache | ||
* @type Map | ||
* @private | ||
*/ | ||
this[ConfigArraySymbol.configCache] = new Map(); | ||
@@ -464,5 +464,5 @@ | ||
if (Array.isArray(configs)) { | ||
this.push(...configs); | ||
this.push(...configs); | ||
} else { | ||
this.push(configs); | ||
this.push(configs); | ||
} | ||
@@ -472,3 +472,3 @@ | ||
/** | ||
/** | ||
* Prevent normal array methods from creating a new `ConfigArray` instance. | ||
@@ -480,7 +480,7 @@ * This is to ensure that methods such as `slice()` won't try to create a | ||
*/ | ||
static get [Symbol.species]() { | ||
return Array; | ||
} | ||
static get [Symbol.species]() { | ||
return Array; | ||
} | ||
/** | ||
/** | ||
* Returns the `files` globs from every config object in the array. | ||
@@ -492,33 +492,33 @@ * This can be used to determine which files will be matched by a | ||
*/ | ||
get files() { | ||
get files() { | ||
assertNormalized(this); | ||
assertNormalized(this); | ||
// if this data has been cached, retrieve it | ||
const cache = dataCache.get(this); | ||
// if this data has been cached, retrieve it | ||
const cache = dataCache.get(this); | ||
if (cache.files) { | ||
return cache.files; | ||
} | ||
if (cache.files) { | ||
return cache.files; | ||
} | ||
// otherwise calculate it | ||
// otherwise calculate it | ||
const result = []; | ||
const result = []; | ||
for (const config of this) { | ||
if (config.files) { | ||
config.files.forEach(filePattern => { | ||
result.push(filePattern); | ||
}); | ||
} | ||
for (const config of this) { | ||
if (config.files) { | ||
config.files.forEach(filePattern => { | ||
result.push(filePattern); | ||
}); | ||
} | ||
} | ||
// store result | ||
cache.files = result; | ||
dataCache.set(this, cache); | ||
// store result | ||
cache.files = result; | ||
dataCache.set(this, cache); | ||
return result; | ||
} | ||
return result; | ||
} | ||
/** | ||
/** | ||
* Returns ignore matchers that should always be ignored regardless of | ||
@@ -530,39 +530,45 @@ * the matching `files` fields in any configs. This is necessary to mimic | ||
*/ | ||
get ignores() { | ||
get ignores() { | ||
assertNormalized(this); | ||
assertNormalized(this); | ||
// if this data has been cached, retrieve it | ||
const cache = dataCache.get(this); | ||
// if this data has been cached, retrieve it | ||
const cache = dataCache.get(this); | ||
if (cache.ignores) { | ||
return cache.ignores; | ||
} | ||
if (cache.ignores) { | ||
return cache.ignores; | ||
} | ||
// otherwise calculate it | ||
// otherwise calculate it | ||
const result = []; | ||
const result = []; | ||
for (const config of this) { | ||
if (config.ignores && !config.files) { | ||
result.push(...config.ignores); | ||
} | ||
for (const config of this) { | ||
/* | ||
* We only count ignores if there are no other keys in the object. | ||
* In this case, it acts list a globally ignored pattern. If there | ||
* are additional keys, then ignores act like exclusions. | ||
*/ | ||
if (config.ignores && Object.keys(config).length === 1) { | ||
result.push(...config.ignores); | ||
} | ||
} | ||
// store result | ||
cache.ignores = result; | ||
dataCache.set(this, cache); | ||
// store result | ||
cache.ignores = result; | ||
dataCache.set(this, cache); | ||
return result; | ||
} | ||
return result; | ||
} | ||
/** | ||
/** | ||
* Indicates if the config array has been normalized. | ||
* @returns {boolean} True if the config array is normalized, false if not. | ||
*/ | ||
isNormalized() { | ||
return this[ConfigArraySymbol.isNormalized]; | ||
} | ||
isNormalized() { | ||
return this[ConfigArraySymbol.isNormalized]; | ||
} | ||
/** | ||
/** | ||
* Normalizes a config array by flattening embedded arrays and executing | ||
@@ -573,18 +579,18 @@ * config functions. | ||
*/ | ||
async normalize(context = {}) { | ||
async normalize(context = {}) { | ||
if (!this.isNormalized()) { | ||
const normalizedConfigs = await normalize(this, context, this.extraConfigTypes); | ||
this.length = 0; | ||
this.push(...normalizedConfigs.map(this[ConfigArraySymbol.preprocessConfig].bind(this))); | ||
this[ConfigArraySymbol.isNormalized] = true; | ||
if (!this.isNormalized()) { | ||
const normalizedConfigs = await normalize(this, context, this.extraConfigTypes); | ||
this.length = 0; | ||
this.push(...normalizedConfigs.map(this[ConfigArraySymbol.preprocessConfig].bind(this))); | ||
this[ConfigArraySymbol.isNormalized] = true; | ||
// prevent further changes | ||
Object.freeze(this); | ||
} | ||
return this; | ||
// prevent further changes | ||
Object.freeze(this); | ||
} | ||
/** | ||
return this; | ||
} | ||
/** | ||
* Normalizes a config array by flattening embedded arrays and executing | ||
@@ -595,18 +601,18 @@ * config functions. | ||
*/ | ||
normalizeSync(context = {}) { | ||
normalizeSync(context = {}) { | ||
if (!this.isNormalized()) { | ||
const normalizedConfigs = normalizeSync(this, context, this.extraConfigTypes); | ||
this.length = 0; | ||
this.push(...normalizedConfigs.map(this[ConfigArraySymbol.preprocessConfig].bind(this))); | ||
this[ConfigArraySymbol.isNormalized] = true; | ||
if (!this.isNormalized()) { | ||
const normalizedConfigs = normalizeSync(this, context, this.extraConfigTypes); | ||
this.length = 0; | ||
this.push(...normalizedConfigs.map(this[ConfigArraySymbol.preprocessConfig].bind(this))); | ||
this[ConfigArraySymbol.isNormalized] = true; | ||
// prevent further changes | ||
Object.freeze(this); | ||
} | ||
return this; | ||
// prevent further changes | ||
Object.freeze(this); | ||
} | ||
/** | ||
return this; | ||
} | ||
/** | ||
* Finalizes the state of a config before being cached and returned by | ||
@@ -618,7 +624,7 @@ * `getConfig()`. Does nothing by default but is provided to be | ||
*/ | ||
[ConfigArraySymbol.finalizeConfig](config) { | ||
return config; | ||
} | ||
[ConfigArraySymbol.finalizeConfig](config) { | ||
return config; | ||
} | ||
/** | ||
/** | ||
* Preprocesses a config during the normalization process. This is the | ||
@@ -631,7 +637,7 @@ * method to override if you want to convert an array item before it is | ||
*/ | ||
[ConfigArraySymbol.preprocessConfig](config) { | ||
return config; | ||
} | ||
[ConfigArraySymbol.preprocessConfig](config) { | ||
return config; | ||
} | ||
/** | ||
/** | ||
* Determines if a given file path explicitly matches a `files` entry | ||
@@ -644,45 +650,45 @@ * and also doesn't match an `ignores` entry. Configs that don't have | ||
*/ | ||
isExplicitMatch(filePath) { | ||
isExplicitMatch(filePath) { | ||
assertNormalized(this); | ||
assertNormalized(this); | ||
const cache = dataCache.get(this); | ||
const cache = dataCache.get(this); | ||
// first check the cache to avoid duplicate work | ||
let result = cache.explicitMatches.get(filePath); | ||
// first check the cache to avoid duplicate work | ||
let result = cache.explicitMatches.get(filePath); | ||
if (typeof result == "boolean") { | ||
return result; | ||
} | ||
if (typeof result == 'boolean') { | ||
return result; | ||
} | ||
// TODO: Maybe move elsewhere? Maybe combine with getConfig() logic? | ||
const relativeFilePath = path.relative(this.basePath, filePath); | ||
// TODO: Maybe move elsewhere? Maybe combine with getConfig() logic? | ||
const relativeFilePath = path.relative(this.basePath, filePath); | ||
if (shouldIgnoreFilePath(this.ignores, filePath, relativeFilePath)) { | ||
debug(`Ignoring ${filePath}`); | ||
if (shouldIgnoreFilePath(this.ignores, filePath, relativeFilePath)) { | ||
debug(`Ignoring ${filePath}`); | ||
// cache and return result | ||
cache.explicitMatches.set(filePath, false); | ||
return false; | ||
} | ||
// cache and return result | ||
cache.explicitMatches.set(filePath, false); | ||
return false; | ||
} | ||
// filePath isn't automatically ignored, so try to find a match | ||
// filePath isn't automatically ignored, so try to find a match | ||
for (const config of this) { | ||
for (const config of this) { | ||
if (!config.files) { | ||
continue; | ||
} | ||
if (!config.files) { | ||
continue; | ||
} | ||
if (pathMatches(filePath, this.basePath, config)) { | ||
debug(`Matching config found for ${filePath}`); | ||
cache.explicitMatches.set(filePath, true); | ||
return true; | ||
} | ||
if (pathMatches(filePath, this.basePath, config)) { | ||
debug(`Matching config found for ${filePath}`); | ||
cache.explicitMatches.set(filePath, true); | ||
return true; | ||
} | ||
return false; | ||
} | ||
/** | ||
return false; | ||
} | ||
/** | ||
* Returns the config object for a given file path. | ||
@@ -692,68 +698,68 @@ * @param {string} filePath The complete path of a file to get a config for. | ||
*/ | ||
getConfig(filePath) { | ||
getConfig(filePath) { | ||
assertNormalized(this); | ||
assertNormalized(this); | ||
// first check the cache to avoid duplicate work | ||
let finalConfig = this[ConfigArraySymbol.configCache].get(filePath); | ||
// first check the cache to avoid duplicate work | ||
let finalConfig = this[ConfigArraySymbol.configCache].get(filePath); | ||
if (finalConfig) { | ||
return finalConfig; | ||
} | ||
if (finalConfig) { | ||
return finalConfig; | ||
} | ||
// TODO: Maybe move elsewhere? | ||
const relativeFilePath = path.relative(this.basePath, filePath); | ||
// TODO: Maybe move elsewhere? | ||
const relativeFilePath = path.relative(this.basePath, filePath); | ||
if (shouldIgnoreFilePath(this.ignores, filePath, relativeFilePath)) { | ||
debug(`Ignoring ${filePath}`); | ||
if (shouldIgnoreFilePath(this.ignores, filePath, relativeFilePath)) { | ||
debug(`Ignoring ${filePath}`); | ||
// cache and return result - finalConfig is undefined at this point | ||
this[ConfigArraySymbol.configCache].set(filePath, finalConfig); | ||
return finalConfig; | ||
} | ||
// cache and return result - finalConfig is undefined at this point | ||
this[ConfigArraySymbol.configCache].set(filePath, finalConfig); | ||
return finalConfig; | ||
} | ||
// filePath isn't automatically ignored, so try to construct config | ||
// filePath isn't automatically ignored, so try to construct config | ||
const matchingConfigs = []; | ||
let matchFound = false; | ||
const matchingConfigs = []; | ||
let matchFound = false; | ||
for (const config of this) { | ||
for (const config of this) { | ||
if (!config.files) { | ||
debug(`Universal config found for ${filePath}`); | ||
matchingConfigs.push(config); | ||
continue; | ||
} | ||
if (pathMatches(filePath, this.basePath, config)) { | ||
debug(`Matching config found for ${filePath}`); | ||
matchingConfigs.push(config); | ||
matchFound = true; | ||
continue; | ||
} | ||
if (!config.files) { | ||
debug(`Universal config found for ${filePath}`); | ||
matchingConfigs.push(config); | ||
continue; | ||
} | ||
// if matching both files and ignores, there will be no config to create | ||
if (!matchFound) { | ||
debug(`No matching configs found for ${filePath}`); | ||
// cache and return result - finalConfig is undefined at this point | ||
this[ConfigArraySymbol.configCache].set(filePath, finalConfig); | ||
return finalConfig; | ||
if (pathMatches(filePath, this.basePath, config)) { | ||
debug(`Matching config found for ${filePath}`); | ||
matchingConfigs.push(config); | ||
matchFound = true; | ||
continue; | ||
} | ||
} | ||
// otherwise construct the config | ||
// if matching both files and ignores, there will be no config to create | ||
if (!matchFound) { | ||
debug(`No matching configs found for ${filePath}`); | ||
finalConfig = matchingConfigs.reduce((result, config) => { | ||
return this[ConfigArraySymbol.schema].merge(result, config); | ||
}, {}, this); | ||
finalConfig = this[ConfigArraySymbol.finalizeConfig](finalConfig); | ||
// cache and return result - finalConfig is undefined at this point | ||
this[ConfigArraySymbol.configCache].set(filePath, finalConfig); | ||
return finalConfig; | ||
} | ||
/** | ||
// otherwise construct the config | ||
finalConfig = matchingConfigs.reduce((result, config) => { | ||
return this[ConfigArraySymbol.schema].merge(result, config); | ||
}, {}, this); | ||
finalConfig = this[ConfigArraySymbol.finalizeConfig](finalConfig); | ||
this[ConfigArraySymbol.configCache].set(filePath, finalConfig); | ||
return finalConfig; | ||
} | ||
/** | ||
* Determines if the given filepath is ignored based on the configs. | ||
@@ -763,5 +769,5 @@ * @param {string} filePath The complete path of a file to check. | ||
*/ | ||
isIgnored(filePath) { | ||
return this.getConfig(filePath) === undefined; | ||
} | ||
isIgnored(filePath) { | ||
return this.getConfig(filePath) === undefined; | ||
} | ||
@@ -768,0 +774,0 @@ } |
# Changelog | ||
### [0.10.4](https://www.github.com/humanwhocodes/config-array/compare/v0.10.3...v0.10.4) (2022-07-29) | ||
### Bug Fixes | ||
* Global ignores only when no other keys ([1f6b6ae](https://www.github.com/humanwhocodes/config-array/commit/1f6b6ae89152c1ebe118f55e7ea05c37e7c960dc)) | ||
* Re-introduce ignores fixes ([b3ec560](https://www.github.com/humanwhocodes/config-array/commit/b3ec560c485bec2f7420fd63a939448b49a073e3)) | ||
### [0.10.3](https://www.github.com/humanwhocodes/config-array/compare/v0.10.2...v0.10.3) (2022-07-20) | ||
@@ -4,0 +12,0 @@ |
{ | ||
"name": "@humanwhocodes/config-array", | ||
"version": "0.10.3", | ||
"version": "0.10.4", | ||
"description": "Glob-based configuration matching.", | ||
@@ -31,3 +31,2 @@ "author": "Nicholas C. Zakas", | ||
"*.js": [ | ||
"nitpik", | ||
"eslint --fix --ignore-pattern '!.eslintrc.js'" | ||
@@ -51,13 +50,13 @@ ] | ||
"devDependencies": { | ||
"@nitpik/javascript": "^0.3.3", | ||
"@nitpik/javascript": "0.3.3", | ||
"@nitpik/node": "0.0.5", | ||
"chai": "^4.2.0", | ||
"eslint": "^6.7.1", | ||
"esm": "^3.2.25", | ||
"lint-staged": "^10.2.8", | ||
"mocha": "^6.2.3", | ||
"nyc": "^14.1.1", | ||
"rollup": "^1.12.3", | ||
"yorkie": "^2.0.0" | ||
"chai": "4.2.0", | ||
"eslint": "6.7.1", | ||
"esm": "3.2.25", | ||
"lint-staged": "10.2.8", | ||
"mocha": "6.2.3", | ||
"nyc": "14.1.1", | ||
"rollup": "1.16.6", | ||
"yorkie": "2.0.0" | ||
} | ||
} |
@@ -179,3 +179,3 @@ # Config Array | ||
You can also specify an `ignores` key that will force files matching those patterns to not be included. If the `ignores` key is in a config object without a `files` key, then those ignores will always be applied; if the `ignores` key is in a config object with a `files` key, then those ignores are only applied when `files` matches. Here's an example: | ||
You can also specify an `ignores` key that will force files matching those patterns to not be included. If the `ignores` key is in a config object without any other keys, then those ignores will always be applied; otherwise those ignores act as exclusions. Here's an example: | ||
@@ -182,0 +182,0 @@ ```js |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
49056
622