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

fast-glob

Package Overview
Dependencies
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fast-glob - npm Package Compare versions

Comparing version 2.2.7 to 3.0.0

out/providers/async.d.ts

44

out/index.d.ts
/// <reference types="node" />
import { IPartialOptions } from './managers/options';
import { ITask } from './managers/tasks';
import { EntryItem } from './types/entries';
import { Pattern } from './types/patterns';
/**
* Synchronous API.
*/
export declare function sync(source: Pattern | Pattern[], opts?: IPartialOptions): EntryItem[];
/**
* Asynchronous API.
*/
export declare function async(source: Pattern | Pattern[], opts?: IPartialOptions): Promise<EntryItem[]>;
/**
* Stream API.
*/
export declare function stream(source: Pattern | Pattern[], opts?: IPartialOptions): NodeJS.ReadableStream;
/**
* Return a set of tasks based on provided patterns.
*/
export declare function generateTasks(source: Pattern | Pattern[], opts?: IPartialOptions): ITask[];
import * as taskManager from './managers/tasks';
import { Options as OptionsInternal } from './settings';
import { Entry as EntryInternal, FileSystemAdapter as FileSystemAdapterInternal, Pattern as PatternInternal } from './types/index';
declare type EntryObjectModePredicate = {
[P in keyof Pick<OptionsInternal, 'objectMode'>]-?: true;
};
declare type EntryStatsPredicate = {
[P in keyof Pick<OptionsInternal, 'stats'>]-?: true;
};
declare type EntryObjectPredicate = EntryObjectModePredicate | EntryStatsPredicate;
declare function FastGlob(source: PatternInternal | PatternInternal[], options: OptionsInternal & EntryObjectPredicate): Promise<EntryInternal[]>;
declare function FastGlob(source: PatternInternal | PatternInternal[], options?: OptionsInternal): Promise<string[]>;
declare namespace FastGlob {
type Options = OptionsInternal;
type Entry = EntryInternal;
type Task = taskManager.Task;
type Pattern = PatternInternal;
type FileSystemAdapter = FileSystemAdapterInternal;
function sync(source: PatternInternal | PatternInternal[], options: OptionsInternal & EntryObjectPredicate): EntryInternal[];
function sync(source: PatternInternal | PatternInternal[], options?: OptionsInternal): string[];
function stream(source: PatternInternal | PatternInternal[], options?: OptionsInternal): NodeJS.ReadableStream;
function generateTasks(source: PatternInternal | PatternInternal[], options?: OptionsInternal): Task[];
}
export = FastGlob;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var optionsManager = require("./managers/options");
var taskManager = require("./managers/tasks");
var reader_async_1 = require("./providers/reader-async");
var reader_stream_1 = require("./providers/reader-stream");
var reader_sync_1 = require("./providers/reader-sync");
var arrayUtils = require("./utils/array");
var streamUtils = require("./utils/stream");
/**
* Synchronous API.
*/
function sync(source, opts) {
assertPatternsInput(source);
var works = getWorks(source, reader_sync_1.default, opts);
return arrayUtils.flatten(works);
}
exports.sync = sync;
/**
* Asynchronous API.
*/
function async(source, opts) {
const taskManager = require("./managers/tasks");
const async_1 = require("./providers/async");
const stream_1 = require("./providers/stream");
const sync_1 = require("./providers/sync");
const settings_1 = require("./settings");
const utils = require("./utils/index");
function FastGlob(source, options) {
try {

@@ -29,35 +15,38 @@ assertPatternsInput(source);

}
var works = getWorks(source, reader_async_1.default, opts);
return Promise.all(works).then(arrayUtils.flatten);
const works = getWorks(source, async_1.default, options);
return Promise.all(works).then(utils.array.flatten);
}
exports.async = async;
/**
* Stream API.
*/
function stream(source, opts) {
assertPatternsInput(source);
var works = getWorks(source, reader_stream_1.default, opts);
return streamUtils.merge(works);
(function (FastGlob) {
function sync(source, options) {
assertPatternsInput(source);
const works = getWorks(source, sync_1.default, options);
return utils.array.flatten(works);
}
FastGlob.sync = sync;
function stream(source, options) {
assertPatternsInput(source);
const works = getWorks(source, stream_1.default, options);
/**
* The stream returned by the provider cannot work with an asynchronous iterator.
* To support asynchronous iterators, regardless of the number of tasks, we always multiplex streams.
* This affects performance (+25%). I don't see best solution right now.
*/
return utils.stream.merge(works);
}
FastGlob.stream = stream;
function generateTasks(source, options) {
assertPatternsInput(source);
const patterns = [].concat(source);
const settings = new settings_1.default(options);
return taskManager.generate(patterns, settings);
}
FastGlob.generateTasks = generateTasks;
})(FastGlob || (FastGlob = {}));
function getWorks(source, _Provider, options) {
const patterns = [].concat(source);
const settings = new settings_1.default(options);
const tasks = taskManager.generate(patterns, settings);
const provider = new _Provider(settings);
return tasks.map(provider.read, provider);
}
exports.stream = stream;
/**
* Return a set of tasks based on provided patterns.
*/
function generateTasks(source, opts) {
assertPatternsInput(source);
var patterns = [].concat(source);
var options = optionsManager.prepare(opts);
return taskManager.generate(patterns, options);
}
exports.generateTasks = generateTasks;
/**
* Returns a set of works based on provided tasks and class of the reader.
*/
function getWorks(source, _Reader, opts) {
var patterns = [].concat(source);
var options = optionsManager.prepare(opts);
var tasks = taskManager.generate(patterns, options);
var reader = new _Reader(options);
return tasks.map(reader.read, reader);
}
function assertPatternsInput(source) {

@@ -73,1 +62,2 @@ if ([].concat(source).every(isString)) {

}
module.exports = FastGlob;

@@ -1,4 +0,4 @@

import { Pattern, PatternsGroup } from '../types/patterns';
import { IOptions } from './options';
export interface ITask {
import Settings from '../settings';
import { Pattern, PatternsGroup } from '../types/index';
export interface Task {
base: string;

@@ -10,29 +10,8 @@ dynamic: boolean;

}
/**
* Generate tasks based on parent directory of each pattern.
*/
export declare function generate(patterns: Pattern[], options: IOptions): ITask[];
/**
* Convert patterns to tasks based on parent directory of each pattern.
*/
export declare function convertPatternsToTasks(positive: Pattern[], negative: Pattern[], dynamic: boolean): ITask[];
/**
* Return only positive patterns.
*/
export declare function generate(patterns: Pattern[], settings: Settings): Task[];
export declare function convertPatternsToTasks(positive: Pattern[], negative: Pattern[], dynamic: boolean): Task[];
export declare function getPositivePatterns(patterns: Pattern[]): Pattern[];
/**
* Return only negative patterns.
*/
export declare function getNegativePatternsAsPositive(patterns: Pattern[], ignore: Pattern[]): Pattern[];
/**
* Group patterns by base directory of each pattern.
*/
export declare function groupPatternsByBaseDirectory(patterns: Pattern[]): PatternsGroup;
/**
* Convert group of patterns to tasks.
*/
export declare function convertPatternGroupsToTasks(positive: PatternsGroup, negative: Pattern[], dynamic: boolean): ITask[];
/**
* Create a task for positive and negative patterns.
*/
export declare function convertPatternGroupToTask(base: string, positive: Pattern[], negative: Pattern[], dynamic: boolean): ITask;
export declare function convertPatternGroupsToTasks(positive: PatternsGroup, negative: Pattern[], dynamic: boolean): Task[];
export declare function convertPatternGroupToTask(base: string, positive: Pattern[], negative: Pattern[], dynamic: boolean): Task;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var patternUtils = require("../utils/pattern");
/**
* Generate tasks based on parent directory of each pattern.
*/
function generate(patterns, options) {
var unixPatterns = patterns.map(patternUtils.unixifyPattern);
var unixIgnore = options.ignore.map(patternUtils.unixifyPattern);
var positivePatterns = getPositivePatterns(unixPatterns);
var negativePatterns = getNegativePatternsAsPositive(unixPatterns, unixIgnore);
const utils = require("../utils/index");
function generate(patterns, settings) {
const positivePatterns = getPositivePatterns(patterns);
const negativePatterns = getNegativePatternsAsPositive(patterns, settings.ignore);
/**
* When the `case` option is disabled, all patterns must be marked as dynamic, because we cannot check filepath
* directly (without read directory).
* When the `caseSensitiveMatch` option is disabled, all patterns must be marked as dynamic, because we cannot check
* filepath directly (without read directory).
*/
var staticPatterns = !options.case ? [] : positivePatterns.filter(patternUtils.isStaticPattern);
var dynamicPatterns = !options.case ? positivePatterns : positivePatterns.filter(patternUtils.isDynamicPattern);
var staticTasks = convertPatternsToTasks(staticPatterns, negativePatterns, /* dynamic */ false);
var dynamicTasks = convertPatternsToTasks(dynamicPatterns, negativePatterns, /* dynamic */ true);
const staticPatterns = !settings.caseSensitiveMatch ? [] : positivePatterns.filter(utils.pattern.isStaticPattern);
const dynamicPatterns = !settings.caseSensitiveMatch ? positivePatterns : positivePatterns.filter(utils.pattern.isDynamicPattern);
const staticTasks = convertPatternsToTasks(staticPatterns, negativePatterns, /* dynamic */ false);
const dynamicTasks = convertPatternsToTasks(dynamicPatterns, negativePatterns, /* dynamic */ true);
return staticTasks.concat(dynamicTasks);
}
exports.generate = generate;
/**
* Convert patterns to tasks based on parent directory of each pattern.
*/
function convertPatternsToTasks(positive, negative, dynamic) {
var positivePatternsGroup = groupPatternsByBaseDirectory(positive);
const positivePatternsGroup = groupPatternsByBaseDirectory(positive);
// When we have a global group – there is no reason to divide the patterns into independent tasks.
// In this case, the global task covers the rest.
if ('.' in positivePatternsGroup) {
var task = convertPatternGroupToTask('.', positive, negative, dynamic);
const task = convertPatternGroupToTask('.', positive, negative, dynamic);
return [task];

@@ -37,24 +29,15 @@ }

exports.convertPatternsToTasks = convertPatternsToTasks;
/**
* Return only positive patterns.
*/
function getPositivePatterns(patterns) {
return patternUtils.getPositivePatterns(patterns);
return utils.pattern.getPositivePatterns(patterns);
}
exports.getPositivePatterns = getPositivePatterns;
/**
* Return only negative patterns.
*/
function getNegativePatternsAsPositive(patterns, ignore) {
var negative = patternUtils.getNegativePatterns(patterns).concat(ignore);
var positive = negative.map(patternUtils.convertToPositivePattern);
const negative = utils.pattern.getNegativePatterns(patterns).concat(ignore);
const positive = negative.map(utils.pattern.convertToPositivePattern);
return positive;
}
exports.getNegativePatternsAsPositive = getNegativePatternsAsPositive;
/**
* Group patterns by base directory of each pattern.
*/
function groupPatternsByBaseDirectory(patterns) {
return patterns.reduce(function (collection, pattern) {
var base = patternUtils.getBaseDirectory(pattern);
return patterns.reduce((collection, pattern) => {
const base = utils.pattern.getBaseDirectory(pattern);
if (base in collection) {

@@ -70,7 +53,4 @@ collection[base].push(pattern);

exports.groupPatternsByBaseDirectory = groupPatternsByBaseDirectory;
/**
* Convert group of patterns to tasks.
*/
function convertPatternGroupsToTasks(positive, negative, dynamic) {
return Object.keys(positive).map(function (base) {
return Object.keys(positive).map((base) => {
return convertPatternGroupToTask(base, positive[base], negative, dynamic);

@@ -80,14 +60,11 @@ });

exports.convertPatternGroupsToTasks = convertPatternGroupsToTasks;
/**
* Create a task for positive and negative patterns.
*/
function convertPatternGroupToTask(base, positive, negative, dynamic) {
return {
base: base,
dynamic: dynamic,
positive: positive,
negative: negative,
patterns: [].concat(positive, negative.map(patternUtils.convertToNegativePattern))
dynamic,
positive,
negative,
base: utils.path.platformify(base),
patterns: [].concat(positive, negative.map(utils.pattern.convertToNegativePattern))
};
}
exports.convertPatternGroupToTask = convertPatternGroupToTask;

@@ -1,45 +0,17 @@

import micromatch = require('micromatch');
import { IOptions } from '../../managers/options';
import { FilterFunction } from '@mrmlnc/readdir-enhanced';
import { Pattern } from '../../types/patterns';
import Settings from '../../settings';
import { EntryFilterFunction, MicromatchOptions, Pattern } from '../../types/index';
export default class DeepFilter {
private readonly options;
private readonly micromatchOptions;
constructor(options: IOptions, micromatchOptions: micromatch.Options);
/**
* Returns filter for directories.
*/
getFilter(positive: Pattern[], negative: Pattern[]): FilterFunction;
/**
* Returns max depth of the provided patterns.
*/
private getMaxPatternDepth;
/**
* Returns RegExp's for patterns that can affect the depth of reading.
*/
private getNegativePatternsRe;
/**
* Returns «true» for directory that should be read.
*/
private filter;
/**
* Returns «true» when the «deep» option is disabled or number and depth of the entry is greater that the option value.
*/
private isSkippedByDeepOption;
/**
* Returns «true» when depth parameter is not an Infinity and entry depth greater that the parameter value.
*/
private isSkippedByMaxPatternDepth;
/**
* Returns «true» for symlinked directory if the «followSymlinkedDirectories» option is disabled.
*/
private isSkippedSymlinkedDirectory;
/**
* Returns «true» for a directory whose name starts with a period if «dot» option is disabled.
*/
private isSkippedDotDirectory;
/**
* Returns «true» for a directory whose path math to any negative pattern.
*/
private isSkippedByNegativePatterns;
private readonly _settings;
private readonly _micromatchOptions;
constructor(_settings: Settings, _micromatchOptions: MicromatchOptions);
getFilter(basePath: string, positive: Pattern[], negative: Pattern[]): EntryFilterFunction;
private _getMaxPatternDepth;
private _getNegativePatternsRe;
private _filter;
private _getEntryDepth;
private _isSkippedByDeep;
private _isSkippedByMaxPatternDepth;
private _isSkippedSymbolicLink;
private _isSkippedDotDirectory;
private _isSkippedByNegativePatterns;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var pathUtils = require("../../utils/path");
var patternUtils = require("../../utils/pattern");
var DeepFilter = /** @class */ (function () {
function DeepFilter(options, micromatchOptions) {
this.options = options;
this.micromatchOptions = micromatchOptions;
const path = require("path");
const utils = require("../../utils/index");
class DeepFilter {
constructor(_settings, _micromatchOptions) {
this._settings = _settings;
this._micromatchOptions = _micromatchOptions;
}
/**
* Returns filter for directories.
*/
DeepFilter.prototype.getFilter = function (positive, negative) {
var _this = this;
var maxPatternDepth = this.getMaxPatternDepth(positive);
var negativeRe = this.getNegativePatternsRe(negative);
return function (entry) { return _this.filter(entry, negativeRe, maxPatternDepth); };
};
/**
* Returns max depth of the provided patterns.
*/
DeepFilter.prototype.getMaxPatternDepth = function (patterns) {
var globstar = patterns.some(patternUtils.hasGlobStar);
return globstar ? Infinity : patternUtils.getMaxNaivePatternsDepth(patterns);
};
/**
* Returns RegExp's for patterns that can affect the depth of reading.
*/
DeepFilter.prototype.getNegativePatternsRe = function (patterns) {
var affectDepthOfReadingPatterns = patterns.filter(patternUtils.isAffectDepthOfReadingPattern);
return patternUtils.convertPatternsToRe(affectDepthOfReadingPatterns, this.micromatchOptions);
};
/**
* Returns «true» for directory that should be read.
*/
DeepFilter.prototype.filter = function (entry, negativeRe, maxPatternDepth) {
if (this.isSkippedByDeepOption(entry.depth)) {
getFilter(basePath, positive, negative) {
const maxPatternDepth = this._getMaxPatternDepth(positive);
const negativeRe = this._getNegativePatternsRe(negative);
return (entry) => this._filter(basePath, entry, negativeRe, maxPatternDepth);
}
_getMaxPatternDepth(patterns) {
const globstar = patterns.some(utils.pattern.hasGlobStar);
return globstar ? Infinity : utils.pattern.getMaxNaivePatternsDepth(patterns);
}
_getNegativePatternsRe(patterns) {
const affectDepthOfReadingPatterns = patterns.filter(utils.pattern.isAffectDepthOfReadingPattern);
return utils.pattern.convertPatternsToRe(affectDepthOfReadingPatterns, this._micromatchOptions);
}
_filter(basePath, entry, negativeRe, maxPatternDepth) {
const depth = this._getEntryDepth(basePath, entry.path);
if (this._isSkippedByDeep(depth)) {
return false;
}
if (this.isSkippedByMaxPatternDepth(entry.depth, maxPatternDepth)) {
if (this._isSkippedByMaxPatternDepth(depth, maxPatternDepth)) {
return false;
}
if (this.isSkippedSymlinkedDirectory(entry)) {
if (this._isSkippedSymbolicLink(entry)) {
return false;
}
if (this.isSkippedDotDirectory(entry)) {
if (this._isSkippedDotDirectory(entry)) {
return false;
}
return this.isSkippedByNegativePatterns(entry, negativeRe);
};
/**
* Returns «true» when the «deep» option is disabled or number and depth of the entry is greater that the option value.
*/
DeepFilter.prototype.isSkippedByDeepOption = function (entryDepth) {
return !this.options.deep || (typeof this.options.deep === 'number' && entryDepth >= this.options.deep);
};
/**
* Returns «true» when depth parameter is not an Infinity and entry depth greater that the parameter value.
*/
DeepFilter.prototype.isSkippedByMaxPatternDepth = function (entryDepth, maxPatternDepth) {
return maxPatternDepth !== Infinity && entryDepth >= maxPatternDepth;
};
/**
* Returns «true» for symlinked directory if the «followSymlinkedDirectories» option is disabled.
*/
DeepFilter.prototype.isSkippedSymlinkedDirectory = function (entry) {
return !this.options.followSymlinkedDirectories && entry.isSymbolicLink();
};
/**
* Returns «true» for a directory whose name starts with a period if «dot» option is disabled.
*/
DeepFilter.prototype.isSkippedDotDirectory = function (entry) {
return !this.options.dot && pathUtils.isDotDirectory(entry.path);
};
/**
* Returns «true» for a directory whose path math to any negative pattern.
*/
DeepFilter.prototype.isSkippedByNegativePatterns = function (entry, negativeRe) {
return !patternUtils.matchAny(entry.path, negativeRe);
};
return DeepFilter;
}());
return this._isSkippedByNegativePatterns(entry, negativeRe);
}
_getEntryDepth(basePath, entryPath) {
const basePathDepth = basePath.split(path.sep).length;
const entryPathDepth = entryPath.split(path.sep).length;
return entryPathDepth - (basePath === '' ? 0 : basePathDepth);
}
_isSkippedByDeep(entryDepth) {
return entryDepth >= this._settings.deep;
}
_isSkippedByMaxPatternDepth(entryDepth, maxPatternDepth) {
return !this._settings.baseNameMatch && maxPatternDepth !== Infinity && entryDepth > maxPatternDepth;
}
_isSkippedSymbolicLink(entry) {
return !this._settings.followSymbolicLinks && entry.dirent.isSymbolicLink();
}
_isSkippedDotDirectory(entry) {
return !this._settings.dot && entry.name.startsWith('.');
}
_isSkippedByNegativePatterns(entry, negativeRe) {
return !utils.pattern.matchAny(entry.path, negativeRe);
}
}
exports.default = DeepFilter;

@@ -1,45 +0,16 @@

import micromatch = require('micromatch');
import { IOptions } from '../../managers/options';
import { FilterFunction } from '@mrmlnc/readdir-enhanced';
import { Pattern } from '../../types/patterns';
import Settings from '../../settings';
import { EntryFilterFunction, MicromatchOptions, Pattern } from '../../types/index';
export default class EntryFilter {
private readonly options;
private readonly micromatchOptions;
private readonly _settings;
private readonly _micromatchOptions;
readonly index: Map<string, undefined>;
constructor(options: IOptions, micromatchOptions: micromatch.Options);
/**
* Returns filter for directories.
*/
getFilter(positive: Pattern[], negative: Pattern[]): FilterFunction;
/**
* Returns true if entry must be added to result.
*/
private filter;
/**
* Return true if the entry already has in the cross reader index.
*/
private isDuplicateEntry;
/**
* Create record in the cross reader index.
*/
private createIndexRecord;
/**
* Returns true for non-files if the «onlyFiles» option is enabled.
*/
private onlyFileFilter;
/**
* Returns true for non-directories if the «onlyDirectories» option is enabled.
*/
private onlyDirectoryFilter;
/**
* Return true when `absolute` option is enabled and matched to the negative patterns.
*/
private isSkippedByAbsoluteNegativePatterns;
/**
* Return true when entry match to provided patterns.
*
* First, just trying to apply patterns to the path.
* Second, trying to apply patterns to the path with final slash (need to micromatch to support «directory/**» patterns).
*/
private isMatchToPatterns;
constructor(_settings: Settings, _micromatchOptions: MicromatchOptions);
getFilter(positive: Pattern[], negative: Pattern[]): EntryFilterFunction;
private _filter;
private _isDuplicateEntry;
private _createIndexRecord;
private _onlyFileFilter;
private _onlyDirectoryFilter;
private _isSkippedByAbsoluteNegativePatterns;
private _isMatchToPatterns;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var pathUtils = require("../../utils/path");
var patternUtils = require("../../utils/pattern");
var EntryFilter = /** @class */ (function () {
function EntryFilter(options, micromatchOptions) {
this.options = options;
this.micromatchOptions = micromatchOptions;
const utils = require("../../utils/index");
class EntryFilter {
constructor(_settings, _micromatchOptions) {
this._settings = _settings;
this._micromatchOptions = _micromatchOptions;
this.index = new Map();
}
/**
* Returns filter for directories.
*/
EntryFilter.prototype.getFilter = function (positive, negative) {
var _this = this;
var positiveRe = patternUtils.convertPatternsToRe(positive, this.micromatchOptions);
var negativeRe = patternUtils.convertPatternsToRe(negative, this.micromatchOptions);
return function (entry) { return _this.filter(entry, positiveRe, negativeRe); };
};
/**
* Returns true if entry must be added to result.
*/
EntryFilter.prototype.filter = function (entry, positiveRe, negativeRe) {
// Exclude duplicate results
if (this.options.unique) {
if (this.isDuplicateEntry(entry)) {
getFilter(positive, negative) {
const positiveRe = utils.pattern.convertPatternsToRe(positive, this._micromatchOptions);
const negativeRe = utils.pattern.convertPatternsToRe(negative, this._micromatchOptions);
return (entry) => this._filter(entry, positiveRe, negativeRe);
}
_filter(entry, positiveRe, negativeRe) {
if (this._settings.unique) {
if (this._isDuplicateEntry(entry)) {
return false;
}
this.createIndexRecord(entry);
this._createIndexRecord(entry);
}
// Filter files and directories by options
if (this.onlyFileFilter(entry) || this.onlyDirectoryFilter(entry)) {
if (this._onlyFileFilter(entry) || this._onlyDirectoryFilter(entry)) {
return false;
}
if (this.isSkippedByAbsoluteNegativePatterns(entry, negativeRe)) {
if (this._isSkippedByAbsoluteNegativePatterns(entry, negativeRe)) {
return false;
}
return this.isMatchToPatterns(entry.path, positiveRe) && !this.isMatchToPatterns(entry.path, negativeRe);
};
/**
* Return true if the entry already has in the cross reader index.
*/
EntryFilter.prototype.isDuplicateEntry = function (entry) {
const filepath = this._settings.baseNameMatch ? entry.name : entry.path;
return this._isMatchToPatterns(filepath, positiveRe) && !this._isMatchToPatterns(entry.path, negativeRe);
}
_isDuplicateEntry(entry) {
return this.index.has(entry.path);
};
/**
* Create record in the cross reader index.
*/
EntryFilter.prototype.createIndexRecord = function (entry) {
}
_createIndexRecord(entry) {
this.index.set(entry.path, undefined);
};
/**
* Returns true for non-files if the «onlyFiles» option is enabled.
*/
EntryFilter.prototype.onlyFileFilter = function (entry) {
return this.options.onlyFiles && !entry.isFile();
};
/**
* Returns true for non-directories if the «onlyDirectories» option is enabled.
*/
EntryFilter.prototype.onlyDirectoryFilter = function (entry) {
return this.options.onlyDirectories && !entry.isDirectory();
};
/**
* Return true when `absolute` option is enabled and matched to the negative patterns.
*/
EntryFilter.prototype.isSkippedByAbsoluteNegativePatterns = function (entry, negativeRe) {
if (!this.options.absolute) {
}
_onlyFileFilter(entry) {
return this._settings.onlyFiles && !entry.dirent.isFile();
}
_onlyDirectoryFilter(entry) {
return this._settings.onlyDirectories && !entry.dirent.isDirectory();
}
_isSkippedByAbsoluteNegativePatterns(entry, negativeRe) {
if (!this._settings.absolute) {
return false;
}
var fullpath = pathUtils.makeAbsolute(this.options.cwd, entry.path);
return this.isMatchToPatterns(fullpath, negativeRe);
};
/**
* Return true when entry match to provided patterns.
*
* First, just trying to apply patterns to the path.
* Second, trying to apply patterns to the path with final slash (need to micromatch to support «directory/**» patterns).
*/
EntryFilter.prototype.isMatchToPatterns = function (filepath, patternsRe) {
return patternUtils.matchAny(filepath, patternsRe) || patternUtils.matchAny(filepath + '/', patternsRe);
};
return EntryFilter;
}());
const fullpath = utils.path.makeAbsolute(this._settings.cwd, entry.path);
return this._isMatchToPatterns(fullpath, negativeRe);
}
_isMatchToPatterns(filepath, patternsRe) {
return utils.pattern.matchAny(filepath, patternsRe);
}
}
exports.default = EntryFilter;

@@ -1,4 +0,1 @@

/**
* Flatten nested arrays (max depth is 2) into a non-nested array of non-array items.
*/
export declare function flatten<T>(items: T[][]): T[];
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Flatten nested arrays (max depth is 2) into a non-nested array of non-array items.
*/
function flatten(items) {
return items.reduce(function (collection, item) { return [].concat(collection, item); }, []);
return items.reduce((collection, item) => [].concat(collection, item), []);
}
exports.flatten = flatten;
/**
* Returns «true» if the last partial of the path starting with a period.
* Designed to work only with simple paths: `dir\\file`.
*/
export declare function isDotDirectory(filepath: string): boolean;
export declare function unixify(filepath: string): string;
/**
* Convert a windows-like path to a unix-style path.
* Simplified version of the `path.normalize` method.
*
* Designed to work only with simple paths: `dir/file`.
*/
export declare function normalize(filepath: string): string;
/**
* Returns normalized absolute path of provided filepath.
*/
export declare function platformify(filepath: string): string;
export declare function makeAbsolute(cwd: string, filepath: string): string;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
const path = require("path");
/**
* Returns «true» if the last partial of the path starting with a period.
* Designed to work only with simple paths: `dir\\file`.
*/
function isDotDirectory(filepath) {
return path.basename(filepath).startsWith('.');
function unixify(filepath) {
return filepath.replace(/\\/g, '/');
}
exports.isDotDirectory = isDotDirectory;
exports.unixify = unixify;
/**
* Convert a windows-like path to a unix-style path.
* Simplified version of the `path.normalize` method.
*
* Designed to work only with simple paths: `dir/file`.
*/
function normalize(filepath) {
return filepath.replace(/\\/g, '/');
function platformify(filepath) {
return filepath.replace(/[\\\/]/g, path.sep);
}
exports.normalize = normalize;
/**
* Returns normalized absolute path of provided filepath.
*/
exports.platformify = platformify;
function makeAbsolute(cwd, filepath) {
return normalize(path.resolve(cwd, filepath));
return path.resolve(cwd, filepath);
}
exports.makeAbsolute = makeAbsolute;

@@ -1,74 +0,18 @@

import micromatch = require('micromatch');
import { Pattern, PatternRe } from '../types/patterns';
/**
* Return true for static pattern.
*/
import { MicromatchOptions, Pattern, PatternRe } from '../types/index';
export declare function isStaticPattern(pattern: Pattern): boolean;
/**
* Return true for pattern that looks like glob.
*/
export declare function isDynamicPattern(pattern: Pattern): boolean;
/**
* Convert a windows «path» to a unix-style «path».
*/
export declare function unixifyPattern(pattern: Pattern): Pattern;
/**
* Returns negative pattern as positive pattern.
*/
export declare function convertToPositivePattern(pattern: Pattern): Pattern;
/**
* Returns positive pattern as negative pattern.
*/
export declare function convertToNegativePattern(pattern: Pattern): Pattern;
/**
* Return true if provided pattern is negative pattern.
*/
export declare function isNegativePattern(pattern: Pattern): boolean;
/**
* Return true if provided pattern is positive pattern.
*/
export declare function isPositivePattern(pattern: Pattern): boolean;
/**
* Extracts negative patterns from array of patterns.
*/
export declare function getNegativePatterns(patterns: Pattern[]): Pattern[];
/**
* Extracts positive patterns from array of patterns.
*/
export declare function getPositivePatterns(patterns: Pattern[]): Pattern[];
/**
* Extract base directory from provided pattern.
*/
export declare function getBaseDirectory(pattern: Pattern): string;
/**
* Return true if provided pattern has globstar.
*/
export declare function hasGlobStar(pattern: Pattern): boolean;
/**
* Return true if provided pattern ends with slash and globstar.
*/
export declare function endsWithSlashGlobStar(pattern: Pattern): boolean;
/**
* Returns «true» when pattern ends with a slash and globstar or the last partial of the pattern is static pattern.
*/
export declare function isAffectDepthOfReadingPattern(pattern: Pattern): boolean;
/**
* Return naive depth of provided pattern without depth of the base directory.
*/
export declare function getNaiveDepth(pattern: Pattern): number;
/**
* Return max naive depth of provided patterns without depth of the base directory.
*/
export declare function getMaxNaivePatternsDepth(patterns: Pattern[]): number;
/**
* Make RegExp for provided pattern.
*/
export declare function makeRe(pattern: Pattern, options: micromatch.Options): PatternRe;
/**
* Convert patterns to regexps.
*/
export declare function convertPatternsToRe(patterns: Pattern[], options: micromatch.Options): PatternRe[];
/**
* Returns true if the entry match any of the given RegExp's.
*/
export declare function makeRe(pattern: Pattern, options: MicromatchOptions): PatternRe;
export declare function convertPatternsToRe(patterns: Pattern[], options: MicromatchOptions): PatternRe[];
export declare function matchAny(entry: string, patternsRe: PatternRe[]): boolean;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var path = require("path");
var globParent = require("glob-parent");
var isGlob = require("is-glob");
var micromatch = require("micromatch");
var GLOBSTAR = '**';
/**
* Return true for static pattern.
*/
const path = require("path");
const globParent = require("glob-parent");
const isGlob = require("is-glob");
const micromatch = require("micromatch");
const GLOBSTAR = '**';
function isStaticPattern(pattern) {

@@ -15,5 +12,2 @@ return !isDynamicPattern(pattern);

exports.isStaticPattern = isStaticPattern;
/**
* Return true for pattern that looks like glob.
*/
function isDynamicPattern(pattern) {

@@ -23,12 +17,2 @@ return isGlob(pattern, { strict: false });

exports.isDynamicPattern = isDynamicPattern;
/**
* Convert a windows «path» to a unix-style «path».
*/
function unixifyPattern(pattern) {
return pattern.replace(/\\/g, '/');
}
exports.unixifyPattern = unixifyPattern;
/**
* Returns negative pattern as positive pattern.
*/
function convertToPositivePattern(pattern) {

@@ -38,5 +22,2 @@ return isNegativePattern(pattern) ? pattern.slice(1) : pattern;

exports.convertToPositivePattern = convertToPositivePattern;
/**
* Returns positive pattern as negative pattern.
*/
function convertToNegativePattern(pattern) {

@@ -46,5 +27,2 @@ return '!' + pattern;

exports.convertToNegativePattern = convertToNegativePattern;
/**
* Return true if provided pattern is negative pattern.
*/
function isNegativePattern(pattern) {

@@ -54,5 +32,2 @@ return pattern.startsWith('!') && pattern[1] !== '(';

exports.isNegativePattern = isNegativePattern;
/**
* Return true if provided pattern is positive pattern.
*/
function isPositivePattern(pattern) {

@@ -62,5 +37,2 @@ return !isNegativePattern(pattern);

exports.isPositivePattern = isPositivePattern;
/**
* Extracts negative patterns from array of patterns.
*/
function getNegativePatterns(patterns) {

@@ -70,5 +42,2 @@ return patterns.filter(isNegativePattern);

exports.getNegativePatterns = getNegativePatterns;
/**
* Extracts positive patterns from array of patterns.
*/
function getPositivePatterns(patterns) {

@@ -78,5 +47,2 @@ return patterns.filter(isPositivePattern);

exports.getPositivePatterns = getPositivePatterns;
/**
* Extract base directory from provided pattern.
*/
function getBaseDirectory(pattern) {

@@ -86,5 +52,2 @@ return globParent(pattern);

exports.getBaseDirectory = getBaseDirectory;
/**
* Return true if provided pattern has globstar.
*/
function hasGlobStar(pattern) {

@@ -94,5 +57,2 @@ return pattern.indexOf(GLOBSTAR) !== -1;

exports.hasGlobStar = hasGlobStar;
/**
* Return true if provided pattern ends with slash and globstar.
*/
function endsWithSlashGlobStar(pattern) {

@@ -102,17 +62,11 @@ return pattern.endsWith('/' + GLOBSTAR);

exports.endsWithSlashGlobStar = endsWithSlashGlobStar;
/**
* Returns «true» when pattern ends with a slash and globstar or the last partial of the pattern is static pattern.
*/
function isAffectDepthOfReadingPattern(pattern) {
var basename = path.basename(pattern);
const basename = path.basename(pattern);
return endsWithSlashGlobStar(pattern) || isStaticPattern(basename);
}
exports.isAffectDepthOfReadingPattern = isAffectDepthOfReadingPattern;
/**
* Return naive depth of provided pattern without depth of the base directory.
*/
function getNaiveDepth(pattern) {
var base = getBaseDirectory(pattern);
var patternDepth = pattern.split('/').length;
var patternBaseDepth = base.split('/').length;
const base = getBaseDirectory(pattern);
const patternDepth = pattern.split('/').length;
const patternBaseDepth = base.split('/').length;
/**

@@ -129,8 +83,5 @@ * This is a hack for pattern that has no base directory.

exports.getNaiveDepth = getNaiveDepth;
/**
* Return max naive depth of provided patterns without depth of the base directory.
*/
function getMaxNaivePatternsDepth(patterns) {
return patterns.reduce(function (max, pattern) {
var depth = getNaiveDepth(pattern);
return patterns.reduce((max, pattern) => {
const depth = getNaiveDepth(pattern);
return depth > max ? depth : max;

@@ -140,5 +91,2 @@ }, 0);

exports.getMaxNaivePatternsDepth = getMaxNaivePatternsDepth;
/**
* Make RegExp for provided pattern.
*/
function makeRe(pattern, options) {

@@ -148,15 +96,10 @@ return micromatch.makeRe(pattern, options);

exports.makeRe = makeRe;
/**
* Convert patterns to regexps.
*/
function convertPatternsToRe(patterns, options) {
return patterns.map(function (pattern) { return makeRe(pattern, options); });
return patterns.map((pattern) => makeRe(pattern, options));
}
exports.convertPatternsToRe = convertPatternsToRe;
/**
* Returns true if the entry match any of the given RegExp's.
*/
function matchAny(entry, patternsRe) {
return patternsRe.some(function (patternRe) { return patternRe.test(entry); });
const filepath = entry.replace(/^\.[\\\/]/, '');
return patternsRe.some((patternRe) => patternRe.test(filepath));
}
exports.matchAny = matchAny;
/// <reference types="node" />
/**
* Merge multiple streams and propagate their errors into one stream in parallel.
*/
export declare function merge(streams: NodeJS.ReadableStream[]): NodeJS.ReadableStream;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var merge2 = require("merge2");
/**
* Merge multiple streams and propagate their errors into one stream in parallel.
*/
const merge2 = require("merge2");
function merge(streams) {
var mergedStream = merge2(streams);
streams.forEach(function (stream) {
stream.on('error', function (err) { return mergedStream.emit('error', err); });
const mergedStream = merge2(streams);
streams.forEach((stream) => {
stream.once('error', (err) => mergedStream.emit('error', err));
});

@@ -12,0 +9,0 @@ return mergedStream;

{
"name": "fast-glob",
"version": "2.2.7",
"description": "Is a faster `node-glob` alternative",
"version": "3.0.0",
"description": "It's a very fast and efficient glob library for Node.js",
"license": "MIT",

@@ -12,6 +12,6 @@ "repository": "mrmlnc/fast-glob",

"engines": {
"node": ">=4.0.0"
"node": ">=8"
},
"main": "index.js",
"typings": "index.d.ts",
"main": "out/index.js",
"typings": "out/index.d.ts",
"keywords": [

@@ -24,3 +24,3 @@ "glob",

"devDependencies": {
"@types/bash-glob": "^2.0.0",
"@nodelib/fs.macchiato": "^1.0.0",
"@types/compute-stdev": "^1.0.0",

@@ -30,6 +30,4 @@ "@types/easy-table": "^0.0.32",

"@types/glob": "^7.1.1",
"@types/glob-parent": "^3.1.0",
"@types/glob-stream": "^6.1.0",
"@types/globby": "^8.0.0",
"@types/is-glob": "^4.0.0",
"@types/glob-parent": "^3.1.1",
"@types/is-glob": "^4.0.1",
"@types/merge2": "^1.1.4",

@@ -39,27 +37,26 @@ "@types/micromatch": "^3.1.0",

"@types/mocha": "^5.2.5",
"@types/node": "^11.13.5",
"@types/node": "^11.13.6",
"@types/rimraf": "^2.0.2",
"bash-glob": "^2.0.0",
"@types/sinon": "^7.0.12",
"compute-stdev": "^1.0.0",
"easy-table": "^1.1.1",
"execa": "^0.9.0",
"execa": "^1.0.0",
"fast-glob": "^2.2.0",
"glob": "^7.1.2",
"glob-stream": "^6.1.0",
"globby": "^8.0.1",
"minimist": "^1.2.0",
"mocha": "^5.2.0",
"mocha": "^6.1.4",
"rimraf": "^2.6.2",
"sinon": "^7.3.2",
"tiny-glob": "^0.2.3",
"tslint": "^5.12.0",
"tslint-config-mrmlnc": "^2.0.1",
"typescript": "^3.1.3"
"tslint": "^5.16.0",
"tslint-config-mrmlnc": "^2.1.0",
"typescript": "^3.4.4"
},
"dependencies": {
"@mrmlnc/readdir-enhanced": "^2.2.1",
"@nodelib/fs.stat": "^1.1.2",
"glob-parent": "^3.1.0",
"@nodelib/fs.stat": "^2.0.0",
"@nodelib/fs.walk": "^1.1.0",
"glob-parent": "^5.0.0",
"is-glob": "^4.0.0",
"merge2": "^1.2.3",
"micromatch": "^3.1.10"
"micromatch": "^4.0.2"
},

@@ -74,16 +71,13 @@ "scripts": {

"watch": "npm run clean && npm run compile -- --sourceMap --watch",
"bench-async-1": "node ./out/benchmark --depth 1",
"bench-async-5": "node ./out/benchmark --depth 5",
"bench-async-10": "node ./out/benchmark --depth 10",
"bench-async-50": "node ./out/benchmark --depth 50",
"bench-async-100": "node ./out/benchmark --depth 100",
"bench-async": "npm run bench-async-1 && npm run bench-async-5 && npm run bench-async-10 && npm run bench-async-50 && npm run bench-async-100",
"bench-sync-1": "node ./out/benchmark --depth 1 --type sync",
"bench-sync-5": "node ./out/benchmark --depth 5 --type sync",
"bench-sync-10": "node ./out/benchmark --depth 10 --type sync",
"bench-sync-50": "node ./out/benchmark --depth 50 --type sync",
"bench-sync-100": "node ./out/benchmark --depth 100 --type sync",
"bench-sync": "npm run bench-sync-1 && npm run bench-sync-5 && npm run bench-sync-10 && npm run bench-sync-50 && npm run bench-sync-100",
"bench": "npm run build && npm run bench-async && npm run bench-sync"
"bench": "npm run bench-async && npm run bench-stream && npm run bench-sync",
"bench-async": "npm run bench-async-flatten && npm run bench-async-deep",
"bench-stream": "npm run bench-stream-flatten && npm run bench-stream-deep",
"bench-sync": "npm run bench-sync-flatten && npm run bench-sync-deep",
"bench-async-flatten": "node ./out/benchmark --type async --pattern \"*\"",
"bench-async-deep": "node ./out/benchmark --type async --pattern \"**\"",
"bench-stream-flatten": "node ./out/benchmark --type stream --pattern \"*\"",
"bench-stream-deep": "node ./out/benchmark --type stream --pattern \"**\"",
"bench-sync-flatten": "node ./out/benchmark --type sync --pattern \"*\"",
"bench-sync-deep": "node ./out/benchmark --type sync --pattern \"**\""
}
}

@@ -1,39 +0,143 @@

# :rocket: fast-glob
# fast-glob
> Is a faster [`node-glob`](https://github.com/isaacs/node-glob) alternative.
> It's a very fast and efficient [glob][glob_definition] library for [Node.js][node_js].
## :bulb: Highlights
This package provides methods for traversing the file system and returning pathnames that matched a defined set of a specified pattern according to the rules used by the Unix Bash shell with some simplifications, meanwhile results are returned in **arbitrary order**. Quick, simple, effective.
* :rocket: Fast by using Streams and Promises. Used [readdir-enhanced](https://github.com/BigstickCarpet/readdir-enhanced) and [micromatch](https://github.com/jonschlinkert/micromatch).
* :beginner: User-friendly, since it supports multiple and negated patterns (`['*', '!*.md']`).
* :vertical_traffic_light: Rational, because it doesn't read excluded directories (`!**/node_modules/**`).
* :gear: Universal, because it supports Synchronous, Promise and Stream API.
* :money_with_wings: Economy, because it provides `fs.Stats` for matched path if you wanted.
## Table of Contents
## Donate
<details>
<summary><strong>Details</strong></summary>
If you want to thank me, or promote your Issue.
* [Highlights](#highlights)
* [Donation](#donation)
* [Old and modern mode](#old-and-modern-mode)
* [Pattern syntax](#pattern-syntax)
* [Basic syntax](#basic-syntax)
* [Advanced syntax](#advanced-syntax)
* [Installation](#installation)
* [API](#api)
* [Asynchronous](#asynchronous)
* [Synchronous](#synchronous)
* [Stream](#stream)
* [patterns](#patterns)
* [[options]](#options)
* [Options](#options-1)
* [Common](#common)
* [concurrency](#concurrency)
* [cwd](#cwd)
* [deep](#deep)
* [followSymbolicLinks](#followsymboliclinks)
* [fs](#fs)
* [ignore](#ignore)
* [suppressErrors](#suppresserrors)
* [throwErrorOnBrokenSymbolicLink](#throwerroronbrokensymboliclink)
* [Output control](#output-control)
* [absolute](#absolute)
* [markDirectories](#markdirectories)
* [objectMode](#objectmode)
* [onlyDirectories](#onlydirectories)
* [onlyFiles](#onlyfiles)
* [stats](#stats)
* [unique](#unique)
* [Matching control](#matching-control)
* [braceExpansion](#braceexpansion)
* [caseSensitiveMatch](#casesensitivematch)
* [dot](#dot)
* [extglob](#extglob)
* [globstar](#globstar)
* [baseNameMatch](#basenamematch)
* [FAQ](#faq)
* [How to write patterns on Windows?](#how-to-write-patterns-on-windows)
* [Why are parentheses match wrong?](#why-are-parentheses-match-wrong)
* [How to exclude directory from reading?](#how-to-exclude-directory-from-reading)
* [How to use UNC path?](#how-to-use-unc-path)
* [Compatible with `node-glob`?](#compatible-with-node-glob)
* [Benchmarks](#benchmarks)
* [Server](#server)
* [Nettop](#nettop)
* [Changelog](#changelog)
* [License](#license)
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/mrmlnc)
</details>
> Sorry, but I have work and support for packages requires some time after work. I will be glad of your support and PR's.
## Highlights
## Install
* Fast. Probably the fastest.
* Supports multiple and negative patterns.
* Synchronous, Promise and Stream API.
* Object mode. Can return more than just strings.
* Error-tolerant.
## Donation
Do you like this project? Support it by donating, creating an issue or pull request.
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)][paypal_mrmlnc]
## Old and modern mode
This package works in two modes, depending on the environment in which it is used.
* **Old mode**. Node.js below 10.10 or when the `stats` option is *enabled*.
* **Modern mode**. Node.js 10.10+ and the `stats` option is *disabled*.
The modern mode is faster. Learn more about the [internal mechanism][nodelib_fs_scandir_old_and_modern_modern].
## Pattern syntax
> :warning: Always use forward-slashes in glob expressions (patterns and [`ignore`](#ignore) option). Use backslashes for escaping characters.
There is more than one form of syntax: basic and advanced. Below is a brief overview of the supported features. Also pay attention to our [FAQ](#faq).
> :book: This package uses a [`micromatch`][micromatch] as a library for pattern matching.
### Basic syntax
* An asterisk (`*`) — matches everything except slashes (path separators), hidden files (names starting with `.`).
* A double star or globstar (`**`) — matches zero or more directories.
* Question mark (`?`) – matches any single character except slashes (path separators).
* Sequence (`[seq]`) — matches any character in sequence.
> :book: A few additional words about the [basic matching behavior][picomatch_matching_behavior].
Some examples:
* `src/**/*.js` — matches all files in the `src` directory (any level of nesting) that have the `.js` extension.
* `src/*.??` — matches all files in the `src` directory (only first level of nesting) that have a two-character extension.
* `file-[01].js` — matches files: `file-0.js`, `file-1.js`.
### Advanced syntax
* [Escapes characters][micromatch_backslashes] (`\\`) — matching special characters (`$^*+?()[]`) as literals.
* [POSIX character classes][picomatch_posix_brackets] (`[[:digit:]]`).
* [Extended globs][micromatch_extglobs] (`?(pattern-list)`).
* [Bash style brace expansions][micromatch_braces] (`{}`).
* [Regexp character classes][micromatch_regex_character_classes] (`[1-5]`).
* [Regex groups][regular_expressions_brackets] (`(a|b)`).
> :book: A few additional words about the [advanced matching behavior][micromatch_extended_globbing].
Some examples:
* `src/**/*.{css,scss)` — matches all files in the `src` directory (any level of nesting) that have the `.css` or `.scss` extension.
* `file-[[:digit:]].js` — matches files: `file-0.js`, `file-1.js`, …, `file-9.js`.
* `file-{1..3}.js` — matches files: `file-1.js`, `file-2.js`, `file-3.js`.
* `file-(1|2)` — matches files: `file-1.js`, `file-2.js`.
## Installation
```console
npm install fast-glob
```
$ npm install --save fast-glob
```
## Usage
## API
#### Asynchronous
### Asynchronous
```js
const fg = require('fast-glob');
fg(['src/**/*.js', '!src/**/*.spec.js']).then((entries) => console.log(entries));
fg.async(['src/**/*.js', '!src/**/*.spec.js']).then((entries) => console.log(entries));
fg(patterns, [options])
```
#### Synchronous
Returns a `Promise` with an array of matching entries.

@@ -43,86 +147,77 @@ ```js

const entries = fg.sync(['src/**/*.js', '!src/**/*.spec.js']);
console.log(entries);
const entries = await fg(['.editorconfig', '**/index.js'], { dot: true });
// ['.editorconfig', 'services/index.js']
```
#### Stream
### Synchronous
```js
fg.sync(patterns, [options])
```
Returns an array of matching entries.
```js
const fg = require('fast-glob');
const stream = fg.stream(['src/**/*.js', '!src/**/*.spec.js']);
const entries = fg.sync(['.editorconfig', '**/index.js'], { dot: true });
const entries = [];
stream.on('data', (entry) => entries.push(entry));
stream.once('error', console.log);
stream.once('end', () => console.log(entries));
// ['.editorconfig', 'services/index.js']
```
## API
### Stream
### fg(patterns, [options])
### fg.async(patterns, [options])
```js
fg.stream(patterns, [options])
```
Returns a `Promise` with an array of matching [entries](#entry).
Returns a [`ReadableStream`][node_js_stream_readable_streams] when the `data` event will be emitted with matching entry.
### fg.sync(patterns, [options])
```js
const fg = require('fast-glob');
Returns an array of matching [entries](#entry).
const stream = fg.sync(['.editorconfig', '**/index.js'], { dot: true });
### fg.stream(patterns, [options])
for await (const entry of stream) {
// .editorconfig
// services/index.js
}
```
Returns a [`ReadableStream`](https://nodejs.org/api/stream.html#stream_readable_streams) when the `data` event will be emitted with [`Entry`](#entry).
#### patterns
* Type: `string|string[]`
* Required: `true`
* Type: `string | string[]`
This package does not respect the order of patterns. First, all the negative patterns are applied, and only then the positive patterns.
Any correct pattern(s).
#### options
> :1234: [Pattern syntax](#pattern-syntax)
>
> :warning: This package does not respect the order of patterns. First, all the negative patterns are applied, and only then the positive patterns. If you want to get a certain order of records, use sorting or split calls.
* Type: `Object`
#### [options]
See [options](#options-1) section for more detailed information.
* Required: `false`
* Type: [`Options`](#options-1)
### fg.generateTasks(patterns, [options])
See [Options](#options-1) section.
Return a set of tasks based on provided patterns. All tasks satisfy the `Task` interface:
## Options
```ts
interface Task {
/**
* Parent directory for all patterns inside this task.
*/
base: string;
/**
* Dynamic or static patterns are in this task.
*/
dynamic: boolean;
/**
* All patterns.
*/
patterns: string[];
/**
* Only positive patterns.
*/
positive: string[];
/**
* Only negative patterns without ! symbol.
*/
negative: string[];
}
```
### Common options
## Entry
#### concurrency
The entry which can be a `string` if the [`stats`](#stats) option is disabled, otherwise `fs.Stats` with two additional `path` and `depth` properties.
* Type: `number`
* Default: `os.cpus().length`
## Options
Specifies the maximum number of concurrent requests from a reader to read directories.
> :book: The higher the number, the higher the performance and load on the file system. If you want to read in quiet mode, set the value to a comfortable number or `1`.
#### cwd
* Type: `string`
* Default: `process.cwd()`
* Type: `string`
* Default: `process.cwd()`

@@ -133,28 +228,53 @@ The current working directory in which to search.

* Type: `number|boolean`
* Default: `true`
* Type: `number`
* Default: `Infinity`
The deep option can be set to `true` to traverse the entire directory structure, or it can be set to a *number* to only traverse that many levels deep.
Specifies the maximum depth of a read directory relative to the start directory.
For example, you have the following tree:
```js
dir/
└── one/ // 1
└── two/ // 2
└── file.js // 3
```
test
└── one
└── two
└── index.js
```js
// With base directory
fg.sync('dir/**', { onlyFiles: false, deep: 1 }); // ['dir/one']
fg.sync('dir/**', { onlyFiles: false, deep: 2 }); // ['dir/one', 'dir/one/two']
// With cwd option
fg.sync('**', { onlyFiles: false, cwd: 'dir', deep: 1 }); // ['one']
fg.sync('**', { onlyFiles: false, cwd: 'dir', deep: 2 }); // ['one', 'one/two']
```
> :book: If you specify a pattern with some base directory, this directory will not participate in the calculation of the depth of the found directories. Think of it as a `cwd` option.
> :book: If you specify a pattern with some base directory, this directory will not participate in the calculation of the depth of the found directories. Think of it as a [`cwd`](#cwd) option.
```js
fg('test/**', { onlyFiles: false, deep: 0 });
// -> ['test/one']
fg('test/**', { onlyFiles: false, deep: 1 });
// -> ['test/one', 'test/one/two']
#### followSymbolicLinks
fg('**', { onlyFiles: false, cwd: 'test', deep: 0 });
// -> ['one']
fg('**', { onlyFiles: false, cwd: 'test', deep: 1 });
// -> ['one', 'one/two']
* Type: `boolean`
* Default: `true`
Indicates whether to traverse descendants of symbolic link directories.
> :book: If the [`stats`](#stats) option is specified, the information about the symbolic link (`fs.lstat`) will be replaced with information about the entry (`fs.stat`) behind it.
#### fs
* Type: `FileSystemAdapter`
* Default: `fs.*`
Custom implementation of methods for working with the file system.
```ts
export interface FileSystemAdapter {
lstat?: typeof fs.lstat;
stat?: typeof fs.stat;
lstatSync?: typeof fs.lstatSync;
statSync?: typeof fs.statSync;
readdir?: typeof fs.readdir;
readdirSync?: typeof fs.readdirSync;
}
```

@@ -164,174 +284,314 @@

* Type: `string[]`
* Default: `[]`
* Type: `string[]`
* Default: `[]`
An array of glob patterns to exclude matches.
An array of glob patterns to exclude matches. This is an alternative way to use negative patterns.
#### dot
```js
dir/
├── package-lock.json
└── package.json
```
* Type: `boolean`
* Default: `false`
```js
fg.sync(['*.json', '!package-lock.json']); // ['package.json']
fg.sync('*.json', { ignore: ['package-lock.json'] }); // ['package.json']
```
Allow patterns to match filenames starting with a period (files & directories), even if the pattern does not explicitly have a period in that spot.
#### suppressErrors
#### stats
* Type: `boolean`
* Default: `false`
* Type: `boolean`
* Default: `false`
By default this package suppress only `ENOENT` errors. Set to `true` to suppress any error.
Return `fs.Stats` with two additional `path` and `depth` properties instead of a `string`.
> :book: Can be useful when the directory has entries with a special level of access.
#### onlyFiles
#### throwErrorOnBrokenSymbolicLink
* Type: `boolean`
* Default: `true`
* Type: `boolean`
* Default: `false`
Return only files.
Throw an error when symbolic link is broken if `true` or safely return `lstat` call if `false`.
> :book: This option has no effect on errors when reading the symbolic link directory.
### Output control
#### absolute
* Type: `boolean`
* Default: `false`
Return the absolute path for entries.
```js
fg.sync('*.js', { absolute: false }); // ['index.js']
fg.sync('*.js', { absolute: true }); // ['/home/user/index.js']
```
> :book: This option is required if you want to use negative patterns with absolute path, for example, `!${__dirname}/*.js`.
#### markDirectories
* Type: `boolean`
* Default: `false`
Mark the directory path with the final slash.
```js
fs.sync('*', { onlyFiles: false, markDirectories: false }); // ['index.js', 'controllers']
fs.sync('*', { onlyFiles: false, markDirectories: true }); // ['index.js', 'controllers/']
```
#### objectMode
* Type: `boolean`
* Default: `false`
Returns objects (instead of strings) describing entries.
```js
fg.sync('*', { objectMode: false }); // ['src/index.js']
fg.sync('*', { objectMode: true }); // [{ name: 'index.js', path: 'src/index.js', dirent: <fs.Dirent> }]
```
The object has the following fields:
* name (`string`) — the last part of the path (basename)
* path (`string`) — full path relative to the pattern base directory
* dirent ([`fs.Dirent`][node_js_fs_class_fs_dirent]) — instance of `fs.Direct`
> :book: An object is an internal representation of entry, so getting it does not affect performance.
#### onlyDirectories
* Type: `boolean`
* Default: `false`
* Type: `boolean`
* Default: `false`
Return only directories.
#### followSymlinkedDirectories
```js
fg.sync('*', { onlyDirectories: false }); // ['index.js', 'src']
fg.sync('*', { onlyDirectories: true }); // ['src']
```
* Type: `boolean`
* Default: `true`
> :book: If `true`, the [`onlyFiles`](#onlyfiles) option is automatically `false`.
Follow symlinked directories when expanding `**` patterns.
#### onlyFiles
#### unique
* Type: `boolean`
* Default: `false`
* Type: `boolean`
* Default: `true`
Return only files.
Prevent duplicate results.
```js
fg.sync('*', { onlyFiles: false }); // ['index.js', 'src']
fg.sync('*', { onlyFiles: true }); // ['index.js']
```
#### markDirectories
#### stats
* Type: `boolean`
* Default: `false`
* Type: `boolean`
* Default: `false`
Add a `/` character to directory entries.
Enables an [object mode](#objectmode) with an additional field:
#### absolute
* stats ([`fs.Stats`][node_js_fs_class_fs_stats]) — instance of `fs.Stats`
* Type: `boolean`
* Default: `false`
```js
fg.sync('*', { stats: false }); // ['src/index.js']
fg.sync('*', { stats: true }); // [{ name: 'index.js', path: 'src/index.js', dirent: <fs.Dirent>, stats: <fs.Stats> }]
```
Return absolute paths for matched entries.
> :book: Returns `fs.stat` instead of `fs.lstat` for symbolic links when the [`followSymbolicLinks`](#followsymboliclinks) option is specified.
>
> :warning: Unlike [object mode](#objectmode) this mode requires additional calls to the file system. On average, this mode is slower at least twice. See [old and modern mode](#old-and-modern-mode) for more details.
> :book: Note that you need to use this option if you want to use absolute negative patterns like `${__dirname}/*.md`.
#### unique
#### nobrace
* Type: `boolean`
* Default: `true`
* Type: `boolean`
* Default: `false`
Ensures that the returned entries are unique.
Disable expansion of brace patterns (`{a,b}`, `{1..3}`).
```js
fg.sync(['*.json', 'package.json'], { unique: false }); // ['package.json', 'package.json']
fg.sync(['*.json', 'package.json'], { unique: true }); // ['package.json']
```
#### brace
If `true` and similar entries are found, the result is the first found.
* Type: `boolean`
* Default: `true`
### Matching control
The [`nobrace`](#nobrace) option without double-negation. This option has a higher priority then `nobrace`.
#### braceExpansion
#### noglobstar
* Type: `boolean`
* Default: `true`
* Type: `boolean`
* Default: `false`
Enables Bash-like brace expansion.
Disable matching with globstars (`**`).
> :1234: [Syntax description][bash_hackers_syntax_expansion_brace] or mode [detailed description][micromatch_braces].
#### globstar
```js
dir/
├── abd
├── acd
└── a{b,c}d
```
* Type: `boolean`
* Default: `true`
```js
fg.sync('a{b,c}d', { braceExpansion: false }); // ['a{b,c}d']
fg.sync('a{b,c}d', { braceExpansion: true }); // ['abd', 'acd']
```
The [`noglobstar`](#noglobstar) option without double-negation. This option has a higher priority then `noglobstar`.
#### caseSensitiveMatch
#### noext
* Type: `boolean`
* Default: `true`
* Type: `boolean`
* Default: `false`
Enables a [case-sensitive][wikipedia_case_sensitivity] mode for matching files.
Disable extglob support (patterns like `+(a|b)`), so that extglobs are regarded as literal characters.
```js
dir/
├── file.txt
└── File.txt
```
#### extension
```js
fg.sync('file.txt', { caseSensitiveMatch: false }); // ['file.txt', 'File.txt']
fg.sync('file.txt', { caseSensitiveMatch: true }); // ['file.txt']
```
* Type: `boolean`
* Default: `true`
#### dot
The [`noext`](#noext) option without double-negation. This option has a higher priority then `noext`.
* Type: `boolean`
* Default: `false`
#### nocase
Allow patterns to match entries that begin with a period (`.`).
* Type: `boolean`
* Default: `false`
> :book: Note that an explicit dot in a portion of the pattern will always match dot files.
Disable a [case-sensitive](https://en.wikipedia.org/wiki/Case_sensitivity) mode for matching files.
```js
dir/
├── .editorconfig
└── package.json
```
##### Examples
```js
fg.sync('file.txt', { dot: false }); // ['package.json']
fg.sync('file.txt', { dot: true }); // ['.editorconfig', 'package.json']
```
* File System: `test/file.md`, `test/File.md`
* Case-sensitive for `test/file.*` pattern (`false`): `test/file.md`
* Case-insensitive for `test/file.*` pattern (`true`): `test/file.md`, `test/File.md`
#### extglob
#### case
* Type: `boolean`
* Default: `true`
* Type: `boolean`
* Default: `true`
Enables Bash-like `extglob` functionality.
The [`nocase`](#nocase) option without double-negation. This option has a higher priority then `nocase`.
> :1234: [Syntax description][micromatch_extglobs].
#### matchBase
```js
dir/
├── README.md
└── package.json
```
* Type: `boolean`
* Default: `false`
```js
fg.sync('*.+(json|md)', { extglob: false }); // []
fg.sync('*.+(json|md)', { extglob: true }); // ['README.md', 'package.json']
```
Allow glob patterns without slashes to match a file path based on its basename. For example, `a?b` would match the path `/xyz/123/acb`, but not `/xyz/acb/123`.
#### globstar
#### transform
* Type: `boolean`
* Default: `true`
* Type: `Function`
* Default: `null`
Enables recursively repeats a pattern containing `**`. If `false`, `**` behaves exactly like `*`.
Allows you to transform a path or `fs.Stats` object before sending to the array.
```js
dir/
└── a
└── b
```
```js
const fg = require('fast-glob');
fg.sync('**', { onlyFiles: false, globstar: false }); // ['a']
fg.sync('**', { onlyFiles: false, globstar: true }); // ['a', 'a/b']
```
const entries1 = fg.sync(['**/*.scss']);
const entries2 = fg.sync(['**/*.scss'], { transform: (entry) => '_' + entry });
#### baseNameMatch
console.log(entries1); // ['a.scss', 'b.scss']
console.log(entries2); // ['_a.scss', '_b.scss']
* Type: `boolean`
* Default: `false`
If set to `true`, then patterns without slashes will be matched against the basename of the path if it contains slashes.
```js
dir/
└── one/
└── file.md
```
If you are using **TypeScript**, you probably want to specify your own type of the returned array.
```js
fg.sync('*.md', { baseNameMatch: false }); // []
fg.sync('*.md', { baseNameMatch: true }); // ['one/file.md']
```
## FAQ
## How to write patterns on Windows?
Always use forward-slashes in glob expressions (patterns and [`ignore`](#ignore) option). Use backslashes for escaping characters. With the [`cwd`](#cwd) option use a convenient format.
**Bad**
```ts
import * as fg from 'fast-glob';
[
'directory\\*',
path.join(process.cwd(), '**')
]
```
interface IMyOwnEntry {
path: string;
}
**Good**
const entries: IMyOwnEntry[] = fg.sync<IMyOwnEntry>(['*.md'], {
transform: (entry) => typeof entry === 'string' ? { path: entry } : { path: entry.path }
// Will throw compilation error for non-IMyOwnEntry types (boolean, for example)
});
```ts
[
'directory/*',
path.join(process.cwd(), '**').replace(/\\/g, '/')
]
```
> :book: Use the [`normalize-path`][npm_normalize_path] or the [`unixify`][npm_unixify] package to convert Windows-style path to a Unix-style path.
Read more about [matching with backslashes][micromatch_backslashes].
## Why are parentheses match wrong?
```js
dir/
└── (special-*file).txt
```
```js
fg.sync(['(special-*file).txt']) // []
```
Refers to Bash. You need to escape special characters:
```js
fg.sync(['\\(special-*file\\).txt']) // ['(special-*file).txt']
```
Read more about [matching special characters as literals][picomatch_matching_special_characters_as_literals].
## How to exclude directory from reading?
You can use a negative pattern like this: `!**/node_modules` or `!**/node_modules/**`. Also you can use `ignore` option. Just look at the example below.
You can use a negative pattern like this: `!**/node_modules` or `!**/node_modules/**`. Also you can use [`ignore`](#ignore) option. Just look at the example below.
```
```js
first/
├── file.md
└── second
└── second/
└── file.txt

@@ -343,4 +603,4 @@ ```

```js
fg.sync(['**/*.md', '!**/second']); // ['first/file.txt']
fg.sync(['**/*.md'], { ignore: '**/second/**' }); // ['first/file.txt']
fg.sync(['**/*.md', '!**/second']); // ['first/file.md']
fg.sync(['**/*.md'], { ignore: ['**/second/**'] }); // ['first/file.md']
```

@@ -354,3 +614,3 @@

You cannot use UNC paths as patterns (due to syntax), but you can use them as `cwd` directory.
You cannot use [Uniform Naming Convention (UNC)][unc_path] paths as patterns (due to syntax), but you can use them as `cwd` directory.

@@ -364,4 +624,2 @@ ```ts

Not fully, because `fast-glob` does not implement all options of `node-glob`. See table below.
| node-glob | fast-glob |

@@ -376,10 +634,10 @@ | :----------: | :-------: |

| `nounique` | [`unique`](#unique) |
| `nobrace` | [`nobrace`](#nobrace) or [`brace`](#brace) |
| `noglobstar` | [`noglobstar`](#noglobstar) or [`globstar`](#globstar) |
| `noext` | [`noext`](#noext) or [`extension`](#extension) |
| `nocase` | [`nocase`](#nocase) or [`case`](#case) |
| `matchBase` | [`matchbase`](#matchbase) |
| `nobrace` | [`braceExpansion`](#braceexpansion) |
| `noglobstar` | [`globstar`](#globstar) |
| `noext` | [`extglob`](#extglob) |
| `nocase` | [`caseSensitiveMatch`](#casesensitivematch) |
| `matchBase` | [`baseNameMatch`](#basenamematch) |
| `nodir` | [`onlyFiles`](#onlyfiles) |
| `ignore` | [`ignore`](#ignore) |
| `follow` | [`followSymlinkedDirectories`](#followsymlinkeddirectories) |
| `follow` | [`followSymbolicLinks`](#followsymboliclinks) |
| `realpath` | – |

@@ -390,24 +648,25 @@ | `absolute` | [`absolute`](#absolute) |

**Tech specs:**
### Server
Server: [Vultr Bare Metal](https://www.vultr.com/pricing/baremetal)
Link: [Vultr Bare Metal][vultr_pricing_baremetal]
* Processor: E3-1270v6 (8 CPU)
* RAM: 32GB
* Disk: SSD
* Processor: E3-1270v6 (8 CPU)
* RAM: 32GB
* Disk: SSD ([Intel DC S3520 SSDSC2BB240G7][intel_ssd])
You can see results [here](https://gist.github.com/mrmlnc/f06246b197f53c356895fa35355a367c) for latest release.
You can see results [here][github_gist_benchmark_server] for latest release.
## Related
### Nettop
* [readdir-enhanced](https://github.com/BigstickCarpet/readdir-enhanced) – Fast functional replacement for `fs.readdir()`.
* [globby](https://github.com/sindresorhus/globby) – User-friendly glob matching.
* [node-glob](https://github.com/isaacs/node-glob) – «Standard» glob functionality for Node.js
* [bash-glob](https://github.com/micromatch/bash-glob) – Bash-powered globbing for node.js.
* [glob-stream](https://github.com/gulpjs/glob-stream) – A Readable Stream interface over node-glob that used in the [gulpjs](https://github.com/gulpjs/gulp).
* [tiny-glob](https://github.com/terkelg/tiny-glob) – Tiny and extremely fast library to match files and folders using glob patterns.
Link: [Zotac bi323][zotac_bi323]
* Processor: Intel N3150 (4 CPU)
* RAM: 8GB
* Disk: SSD ([Silicon Power SP060GBSS3S55S25][silicon_power_ssd])
You can see results [here][github_gist_benchmark_nettop] for latest release.
## Changelog
See the [Releases section of our GitHub project](https://github.com/mrmlnc/fast-glob/releases) for changelogs for each release version.
See the [Releases section of our GitHub project][github_releases] for changelog for each release version.

@@ -417,1 +676,32 @@ ## License

This software is released under the terms of the MIT license.
[bash_hackers_syntax_expansion_brace]: https://wiki.bash-hackers.org/syntax/expansion/brace
[github_gist_benchmark_nettop]: https://gist.github.com/mrmlnc/f06246b197f53c356895fa35355a367c#file-fast_glob_benchmark_nettop-txt
[github_gist_benchmark_server]: https://gist.github.com/mrmlnc/f06246b197f53c356895fa35355a367c#file-fast_glob_benchmark_server-txt
[github_releases]: https://github.com/mrmlnc/fast-glob/releases
[glob_definition]: https://en.wikipedia.org/wiki/Glob_(programming)
[glob_linux_man]: http://man7.org/linux/man-pages/man3/glob.3.html
[intel_ssd]: https://ark.intel.com/content/www/us/en/ark/products/93012/intel-ssd-dc-s3520-series-240gb-2-5in-sata-6gb-s-3d1-mlc.html
[micromatch_backslashes]: https://github.com/micromatch/micromatch#backslashes
[micromatch_braces]: https://github.com/micromatch/braces
[micromatch_extended_globbing]: https://github.com/micromatch/micromatch#extended-globbing
[micromatch_extglobs]: https://github.com/micromatch/micromatch#extglobs
[micromatch_regex_character_classes]: https://github.com/micromatch/micromatch#regex-character-classes
[micromatch]: https://github.com/micromatch/micromatch
[node_js_fs_class_fs_dirent]: https://nodejs.org/api/fs.html#fs_class_fs_dirent
[node_js_fs_class_fs_stats]: https://nodejs.org/api/fs.html#fs_class_fs_stats
[node_js_stream_readable_streams]: https://nodejs.org/api/stream.html#stream_readable_streams
[node_js]: https://nodejs.org/en
[nodelib_fs_scandir_old_and_modern_modern]: https://github.com/nodelib/nodelib/blob/master/packages/fs/fs.scandir/README.md#old-and-modern-mode
[npm_normalize_path]: https://www.npmjs.com/package/normalize-path
[npm_unixify]: https://www.npmjs.com/package/unixify
[paypal_mrmlnc]:https://paypal.me/mrmlnc
[picomatch_matching_behavior]: https://github.com/micromatch/picomatch#matching-behavior-vs-bash
[picomatch_matching_special_characters_as_literals]: https://github.com/micromatch/picomatch#matching-special-characters-as-literals
[picomatch_posix_brackets]: https://github.com/micromatch/picomatch#posix-brackets
[regular_expressions_brackets]: https://www.regular-expressions.info/brackets.html
[silicon_power_ssd]: https://www.silicon-power.com/web/product-1
[unc_path]: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dtyp/62e862f4-2a51-452e-8eeb-dc4ff5ee33cc
[vultr_pricing_baremetal]: https://www.vultr.com/pricing/baremetal
[wikipedia_case_sensitivity]: https://en.wikipedia.org/wiki/Case_sensitivity
[zotac_bi323]: https://www.zotac.com/ee/product/mini_pcs/zbox-bi323
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