Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@humanwhocodes/config-array

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@humanwhocodes/config-array - npm Package Compare versions

Comparing version 0.9.5 to 0.10.0

370

api.js

@@ -283,10 +283,13 @@ 'use strict';

* @param {Object} config The config object to check.
* @param {string} [mode="implicit"] When set to "implicit", any config
* without a `files` property will match; when set to "explicit",
* any config without a `files` property will not match.
* @returns {boolean} True if the file path is matched by the config,
* false if not.
*/
function pathMatches(filePath, basePath, config) {
function pathMatches(filePath, basePath, config, mode = "implicit") {
// a config without `files` field always match
// a config without `files` field always match implicitly
if (!config.files) {
return true;
return mode === "implicit";
}

@@ -403,26 +406,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({

@@ -434,7 +436,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;

@@ -445,24 +447,24 @@

/**
* 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();
// init cache
dataCache.set(this, {});
dataCache.set(this, { explicitMatches: new Map() });
// load the configs into this array
if (Array.isArray(configs)) {
this.push(...configs);
this.push(...configs);
} else {
this.push(configs);
this.push(configs);
}

@@ -472,3 +474,3 @@

/**
/**
* Prevent normal array methods from creating a new `ConfigArray` instance.

@@ -480,7 +482,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 +494,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 +532,39 @@ * 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) {
if (config.ignores && !config.files) {
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 +575,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);
// prevent further changes
Object.freeze(this);
}
return this;
}
return this;
}
/**
/**
* Normalizes a config array by flattening embedded arrays and executing

@@ -595,18 +597,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]));
this[ConfigArraySymbol.isNormalized] = true;
if (!this.isNormalized()) {
const normalizedConfigs = normalizeSync(this, context, this.extraConfigTypes);
this.length = 0;
this.push(...normalizedConfigs.map(this[ConfigArraySymbol.preprocessConfig]));
this[ConfigArraySymbol.isNormalized] = true;
// prevent further changes
Object.freeze(this);
// prevent further changes
Object.freeze(this);
}
return this;
}
return this;
}
/**
/**
* Finalizes the state of a config before being cached and returned by

@@ -618,7 +620,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 +633,54 @@ * 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
* and also doesn't match an `ignores` entry. Configs that don't have
* a `files` property are not considered an explicit match.
* @param {string} filePath The complete path of a file to check.
* @returns {boolean} True if the file path matches a `files` entry
* or false if not.
*/
isExplicitMatch(filePath) {
assertNormalized(this);
const cache = dataCache.get(this);
// first check the cache to avoid duplicate work
let result = cache.explicitMatches.get(filePath);
if (typeof result == "boolean") {
return result;
}
// 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}`);
// cache and return result
cache.explicitMatches.set(filePath, false);
return false;
}
// filePath isn't automatically ignored, so try to find a match
for (const config of this) {
if (pathMatches(filePath, this.basePath, config, "explicit")) {
debug(`Matching config found for ${filePath}`);
cache.explicitMatches.set(filePath, true);
return true;
} else {
debug(`No matching config found for ${filePath}`);
}
}
return false;
}
/**
* Returns the config object for a given file path.

@@ -641,57 +690,58 @@ * @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)) {
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 = [];
const matchingConfigs = [];
for (const config of this) {
if (pathMatches(filePath, this.basePath, config)) {
debug(`Matching config found for ${filePath}`);
matchingConfigs.push(config);
} else {
debug(`No matching config found for ${filePath}`);
for (const config of this) {
if (pathMatches(filePath, this.basePath, config)) {
debug(`Matching config found for ${filePath}`);
matchingConfigs.push(config);
} else {
debug(`No matching config found for ${filePath}`);
}
}
}
// if matching both files and ignores, there will be no config to create
if (matchingConfigs.length === 0) {
// cache and return result - finalConfig is undefined at this point
this[ConfigArraySymbol.configCache].set(filePath, finalConfig);
return finalConfig;
}
// if matching both files and ignores, there will be no config to create
if (matchingConfigs.length === 0) {
// cache and return result - finalConfig is undefined at this point
this[ConfigArraySymbol.configCache].set(filePath, finalConfig);
return finalConfig;
}
// otherwise construct the config
// otherwise construct the config
finalConfig = matchingConfigs.reduce((result, config) => {
return this[ConfigArraySymbol.schema].merge(result, config);
}, {}, this);
finalConfig = matchingConfigs.reduce((result, config) => {
return this[ConfigArraySymbol.schema].merge(result, config);
}, {}, this);
finalConfig = this[ConfigArraySymbol.finalizeConfig](finalConfig);
finalConfig = this[ConfigArraySymbol.finalizeConfig](finalConfig);
this[ConfigArraySymbol.configCache].set(filePath, finalConfig);
this[ConfigArraySymbol.configCache].set(filePath, finalConfig);
return finalConfig;
}
return finalConfig;
}
/**
/**
* Determines if the given filepath is ignored based on the configs.

@@ -701,5 +751,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;
}

@@ -706,0 +756,0 @@ }

# Changelog
## [0.10.0](https://www.github.com/humanwhocodes/config-array/compare/v0.9.5...v0.10.0) (2022-03-01)
### Features
* Add isExplicitMatch() method ([9ecd90e](https://www.github.com/humanwhocodes/config-array/commit/9ecd90e2a3e984633f535daa4da3cbfb96964fdd))
### [0.9.5](https://www.github.com/humanwhocodes/config-array/compare/v0.9.4...v0.9.5) (2022-02-23)

@@ -4,0 +11,0 @@

{
"name": "@humanwhocodes/config-array",
"version": "0.9.5",
"version": "0.10.0",
"description": "Glob-based configuration matching.",

@@ -5,0 +5,0 @@ "author": "Nicholas C. Zakas",

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc