fast-glob-fast 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +818 -0
  3. package/out/index.d.ts +49 -0
  4. package/out/index.js +99 -0
  5. package/out/managers/tasks.d.ts +22 -0
  6. package/out/managers/tasks.js +114 -0
  7. package/out/providers/async.d.ts +11 -0
  8. package/out/providers/async.js +24 -0
  9. package/out/providers/filters/deep.d.ts +7 -0
  10. package/out/providers/filters/deep.js +64 -0
  11. package/out/providers/filters/entry.d.ts +8 -0
  12. package/out/providers/filters/entry.js +88 -0
  13. package/out/providers/filters/error.d.ts +7 -0
  14. package/out/providers/filters/error.js +16 -0
  15. package/out/providers/index.d.ts +3 -0
  16. package/out/providers/index.js +19 -0
  17. package/out/providers/matchers/matcher.d.ts +28 -0
  18. package/out/providers/matchers/matcher.js +48 -0
  19. package/out/providers/matchers/partial.d.ts +4 -0
  20. package/out/providers/matchers/partial.js +38 -0
  21. package/out/providers/provider.d.ts +19 -0
  22. package/out/providers/provider.js +55 -0
  23. package/out/providers/stream.d.ts +12 -0
  24. package/out/providers/stream.js +32 -0
  25. package/out/providers/sync.d.ts +11 -0
  26. package/out/providers/sync.js +24 -0
  27. package/out/providers/transformers/entry.d.ts +7 -0
  28. package/out/providers/transformers/entry.js +36 -0
  29. package/out/readers/async.d.ts +16 -0
  30. package/out/readers/async.js +34 -0
  31. package/out/readers/index.d.ts +3 -0
  32. package/out/readers/index.js +19 -0
  33. package/out/readers/reader.d.ts +13 -0
  34. package/out/readers/reader.js +36 -0
  35. package/out/readers/stream.d.ts +16 -0
  36. package/out/readers/stream.js +58 -0
  37. package/out/readers/sync.d.ts +15 -0
  38. package/out/readers/sync.js +41 -0
  39. package/out/settings.d.ts +162 -0
  40. package/out/settings.js +75 -0
  41. package/out/types/index.d.ts +34 -0
  42. package/out/types/index.js +2 -0
  43. package/out/utils/array.d.ts +2 -0
  44. package/out/utils/array.js +22 -0
  45. package/out/utils/errno.d.ts +2 -0
  46. package/out/utils/errno.js +6 -0
  47. package/out/utils/fs.d.ts +9 -0
  48. package/out/utils/fs.js +30 -0
  49. package/out/utils/index.d.ts +7 -0
  50. package/out/utils/index.js +10 -0
  51. package/out/utils/path.d.ts +10 -0
  52. package/out/utils/path.js +65 -0
  53. package/out/utils/pattern.d.ts +49 -0
  54. package/out/utils/pattern.js +210 -0
  55. package/out/utils/stream.d.ts +2 -0
  56. package/out/utils/stream.js +22 -0
  57. package/out/utils/string.d.ts +8 -0
  58. package/out/utils/string.js +22 -0
  59. package/package.json +89 -0
  60. package/scripts/postinstall-test.mjs +138 -0
package/out/index.d.ts ADDED
@@ -0,0 +1,49 @@
1
+ import * as taskManager from './managers/tasks';
2
+ import type { Options as OptionsInternal } from './settings';
3
+ import type { Entry as EntryInternal, FileSystemAdapter as FileSystemAdapterInternal, Pattern as PatternInternal } from './types';
4
+ type InputPattern = PatternInternal | readonly PatternInternal[];
5
+ type EntryObjectModePredicate = {
6
+ [TKey in keyof Pick<OptionsInternal, 'objectMode'>]-?: true;
7
+ };
8
+ type EntryStatsPredicate = {
9
+ [TKey in keyof Pick<OptionsInternal, 'stats'>]-?: true;
10
+ };
11
+ type EntryObjectPredicate = EntryObjectModePredicate | EntryStatsPredicate;
12
+ export type Options = OptionsInternal;
13
+ export type Entry = EntryInternal;
14
+ export type Task = taskManager.Task;
15
+ export type Pattern = PatternInternal;
16
+ export type FileSystemAdapter = FileSystemAdapterInternal;
17
+ export declare function glob(source: InputPattern, options: EntryObjectPredicate & OptionsInternal): Promise<EntryInternal[]>;
18
+ export declare function glob(source: InputPattern, options?: OptionsInternal): Promise<string[]>;
19
+ /**
20
+ * @deprecated
21
+ * This method will be removed in v5, use the `.glob` method instead.
22
+ */
23
+ export declare const async: typeof glob;
24
+ export declare function globSync(source: InputPattern, options: EntryObjectPredicate & OptionsInternal): EntryInternal[];
25
+ export declare function globSync(source: InputPattern, options?: OptionsInternal): string[];
26
+ /**
27
+ * @deprecated
28
+ * This method will be removed in v5, use the `.globSync` method instead.
29
+ */
30
+ export declare const sync: typeof globSync;
31
+ export declare function globStream(source: InputPattern, options?: OptionsInternal): NodeJS.ReadableStream;
32
+ /**
33
+ * @deprecated
34
+ * This method will be removed in v5, use the `.globStream` method instead.
35
+ */
36
+ export declare const stream: typeof globStream;
37
+ export declare function generateTasks(source: InputPattern, options?: OptionsInternal): Task[];
38
+ export declare function isDynamicPattern(source: PatternInternal, options?: OptionsInternal): boolean;
39
+ export declare const escapePath: (source: string) => string;
40
+ export declare const convertPathToPattern: (source: string) => string;
41
+ export declare const posix: {
42
+ escapePath: (source: string) => string;
43
+ convertPathToPattern: (source: string) => string;
44
+ };
45
+ export declare const win32: {
46
+ escapePath: (source: string) => string;
47
+ convertPathToPattern: (source: string) => string;
48
+ };
49
+ export {};
package/out/index.js ADDED
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.win32 = exports.posix = exports.convertPathToPattern = exports.escapePath = exports.stream = exports.sync = exports.async = void 0;
4
+ exports.glob = glob;
5
+ exports.globSync = globSync;
6
+ exports.globStream = globStream;
7
+ exports.generateTasks = generateTasks;
8
+ exports.isDynamicPattern = isDynamicPattern;
9
+ const taskManager = require("./managers/tasks");
10
+ const settings_1 = require("./settings");
11
+ const utils = require("./utils");
12
+ const providers_1 = require("./providers");
13
+ const readers_1 = require("./readers");
14
+ async function glob(source, options) {
15
+ assertPatternsInput(source);
16
+ const settings = new settings_1.default(options);
17
+ const reader = new readers_1.ReaderAsync(settings);
18
+ const provider = new providers_1.ProviderAsync(reader, settings);
19
+ const tasks = getTasks(source, settings);
20
+ const promises = tasks.map((task) => provider.read(task));
21
+ const result = await Promise.all(promises);
22
+ return utils.array.flatFirstLevel(result);
23
+ }
24
+ /**
25
+ * @deprecated
26
+ * This method will be removed in v5, use the `.glob` method instead.
27
+ */
28
+ exports.async = glob;
29
+ function globSync(source, options) {
30
+ assertPatternsInput(source);
31
+ const settings = new settings_1.default(options);
32
+ const reader = new readers_1.ReaderSync(settings);
33
+ const provider = new providers_1.ProviderSync(reader, settings);
34
+ const tasks = getTasks(source, settings);
35
+ const entries = tasks.map((task) => provider.read(task));
36
+ return utils.array.flatFirstLevel(entries);
37
+ }
38
+ /**
39
+ * @deprecated
40
+ * This method will be removed in v5, use the `.globSync` method instead.
41
+ */
42
+ exports.sync = globSync;
43
+ function globStream(source, options) {
44
+ assertPatternsInput(source);
45
+ const settings = new settings_1.default(options);
46
+ const reader = new readers_1.ReaderStream(settings);
47
+ const provider = new providers_1.ProviderStream(reader, settings);
48
+ const tasks = getTasks(source, settings);
49
+ const streams = tasks.map((task) => provider.read(task));
50
+ /**
51
+ * The stream returned by the provider cannot work with an asynchronous iterator.
52
+ * To support asynchronous iterators, regardless of the number of tasks, we always multiplex streams.
53
+ * This affects performance (+25%). I don't see best solution right now.
54
+ */
55
+ return utils.stream.merge(streams);
56
+ }
57
+ /**
58
+ * @deprecated
59
+ * This method will be removed in v5, use the `.globStream` method instead.
60
+ */
61
+ exports.stream = globStream;
62
+ function generateTasks(source, options) {
63
+ assertPatternsInput(source);
64
+ const patterns = [].concat(source);
65
+ const settings = new settings_1.default(options);
66
+ return taskManager.generate(patterns, settings);
67
+ }
68
+ function isDynamicPattern(source, options) {
69
+ assertPatternsInput(source);
70
+ const settings = new settings_1.default(options);
71
+ return utils.pattern.isDynamicPattern(source, settings);
72
+ }
73
+ exports.escapePath = withPatternsInputAssert(utils.path.escape);
74
+ exports.convertPathToPattern = withPatternsInputAssert(utils.path.convertPathToPattern);
75
+ exports.posix = {
76
+ escapePath: withPatternsInputAssert(utils.path.escapePosixPath),
77
+ convertPathToPattern: withPatternsInputAssert(utils.path.convertPosixPathToPattern),
78
+ };
79
+ exports.win32 = {
80
+ escapePath: withPatternsInputAssert(utils.path.escapeWindowsPath),
81
+ convertPathToPattern: withPatternsInputAssert(utils.path.convertWindowsPathToPattern),
82
+ };
83
+ function getTasks(source, settings) {
84
+ const patterns = [].concat(source);
85
+ return taskManager.generate(patterns, settings);
86
+ }
87
+ function assertPatternsInput(input) {
88
+ const source = [].concat(input);
89
+ const isValidSource = source.every((item) => utils.string.isString(item) && !utils.string.isEmpty(item));
90
+ if (!isValidSource) {
91
+ throw new TypeError('Patterns must be a string (non empty) or an array of strings');
92
+ }
93
+ }
94
+ function withPatternsInputAssert(method) {
95
+ return (source) => {
96
+ assertPatternsInput(source);
97
+ return method(source);
98
+ };
99
+ }
@@ -0,0 +1,22 @@
1
+ import type Settings from '../settings';
2
+ import type { Pattern, PatternsGroup } from '../types';
3
+ export interface Task {
4
+ base: string;
5
+ dynamic: boolean;
6
+ patterns: Pattern[];
7
+ positive: Pattern[];
8
+ negative: Pattern[];
9
+ }
10
+ export declare function generate(input: readonly Pattern[], settings: Settings): Task[];
11
+ /**
12
+ * Returns tasks grouped by basic pattern directories.
13
+ *
14
+ * Patterns that can be found inside (`./`) and outside (`../`) the current directory are handled separately.
15
+ * This is necessary because directory traversal starts at the base directory and goes deeper.
16
+ */
17
+ export declare function convertPatternsToTasks(positive: Pattern[], negative: Pattern[], dynamic: boolean): Task[];
18
+ export declare function getPositivePatterns(patterns: Pattern[]): Pattern[];
19
+ export declare function getNegativePatternsAsPositive(patterns: Pattern[], ignore: Pattern[]): Pattern[];
20
+ export declare function groupPatternsByBaseDirectory(patterns: Pattern[]): PatternsGroup;
21
+ export declare function convertPatternGroupsToTasks(positive: PatternsGroup, negative: Pattern[], dynamic: boolean): Task[];
22
+ export declare function convertPatternGroupToTask(base: string, positive: Pattern[], negative: Pattern[], dynamic: boolean): Task;
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generate = generate;
4
+ exports.convertPatternsToTasks = convertPatternsToTasks;
5
+ exports.getPositivePatterns = getPositivePatterns;
6
+ exports.getNegativePatternsAsPositive = getNegativePatternsAsPositive;
7
+ exports.groupPatternsByBaseDirectory = groupPatternsByBaseDirectory;
8
+ exports.convertPatternGroupsToTasks = convertPatternGroupsToTasks;
9
+ exports.convertPatternGroupToTask = convertPatternGroupToTask;
10
+ const utils = require("../utils");
11
+ function generate(input, settings) {
12
+ const patterns = processPatterns([...input], settings);
13
+ const ignore = processPatterns([...settings.ignore], settings);
14
+ const positivePatterns = getPositivePatterns(patterns);
15
+ const negativePatterns = getNegativePatternsAsPositive(patterns, ignore);
16
+ const staticPatterns = positivePatterns.filter((pattern) => utils.pattern.isStaticPattern(pattern, settings));
17
+ const dynamicPatterns = positivePatterns.filter((pattern) => utils.pattern.isDynamicPattern(pattern, settings));
18
+ const staticTasks = convertPatternsToTasks(staticPatterns, negativePatterns, /* dynamic */ false);
19
+ const dynamicTasks = convertPatternsToTasks(dynamicPatterns, negativePatterns, /* dynamic */ true);
20
+ return staticTasks.concat(dynamicTasks);
21
+ }
22
+ function processPatterns(input, settings) {
23
+ let patterns = input;
24
+ /**
25
+ * The original pattern like `{,*,**,a/*}` can lead to problems checking the depth when matching entry
26
+ * and some problems with the micromatch package (see fast-glob issues: #365, #394).
27
+ *
28
+ * To solve this problem, we expand all patterns containing brace expansion. This can lead to a slight slowdown
29
+ * in matching in the case of a large set of patterns after expansion.
30
+ */
31
+ if (settings.braceExpansion) {
32
+ patterns = utils.pattern.expandPatternsWithBraceExpansion(patterns);
33
+ }
34
+ /**
35
+ * If the `baseNameMatch` option is enabled, we must add globstar to patterns, so that they can be used
36
+ * at any nesting level.
37
+ *
38
+ * We do this here, because otherwise we have to complicate the filtering logic. For example, we need to change
39
+ * the pattern in the filter before creating a regular expression. There is no need to change the patterns
40
+ * in the application. Only on the input.
41
+ */
42
+ if (settings.baseNameMatch) {
43
+ patterns = patterns.map((pattern) => pattern.includes('/') ? pattern : `**/${pattern}`);
44
+ }
45
+ /**
46
+ * This method also removes duplicate slashes that may have been in the pattern or formed as a result of expansion.
47
+ */
48
+ return patterns.map((pattern) => utils.pattern.removeDuplicateSlashes(pattern));
49
+ }
50
+ /**
51
+ * Returns tasks grouped by basic pattern directories.
52
+ *
53
+ * Patterns that can be found inside (`./`) and outside (`../`) the current directory are handled separately.
54
+ * This is necessary because directory traversal starts at the base directory and goes deeper.
55
+ */
56
+ function convertPatternsToTasks(positive, negative, dynamic) {
57
+ const tasks = [];
58
+ const patternsOutsideCurrentDirectory = utils.pattern.getPatternsOutsideCurrentDirectory(positive);
59
+ const patternsInsideCurrentDirectory = utils.pattern.getPatternsInsideCurrentDirectory(positive);
60
+ const outsideCurrentDirectoryGroup = groupPatternsByBaseDirectory(patternsOutsideCurrentDirectory);
61
+ const insideCurrentDirectoryGroup = groupPatternsByBaseDirectory(patternsInsideCurrentDirectory);
62
+ tasks.push(...convertPatternGroupsToTasks(outsideCurrentDirectoryGroup, negative, dynamic));
63
+ /*
64
+ * For the sake of reducing future accesses to the file system, we merge all tasks within the current directory
65
+ * into a global task, if at least one pattern refers to the root (`.`). In this case, the global task covers the rest.
66
+ */
67
+ if ('.' in insideCurrentDirectoryGroup) {
68
+ tasks.push(convertPatternGroupToTask('.', patternsInsideCurrentDirectory, negative, dynamic));
69
+ }
70
+ else {
71
+ tasks.push(...convertPatternGroupsToTasks(insideCurrentDirectoryGroup, negative, dynamic));
72
+ }
73
+ return tasks;
74
+ }
75
+ function getPositivePatterns(patterns) {
76
+ return utils.pattern.getPositivePatterns(patterns);
77
+ }
78
+ function getNegativePatternsAsPositive(patterns, ignore) {
79
+ const negative = utils.pattern.getNegativePatterns(patterns).concat(ignore);
80
+ const positive = negative.map((pattern) => utils.pattern.convertToPositivePattern(pattern));
81
+ return positive;
82
+ }
83
+ function groupPatternsByBaseDirectory(patterns) {
84
+ const group = {};
85
+ return patterns.reduce((collection, pattern) => {
86
+ let base = utils.pattern.getBaseDirectory(pattern);
87
+ /**
88
+ * After extracting the basic static part of the pattern, it becomes a path,
89
+ * so escaping leads to referencing non-existent paths.
90
+ */
91
+ base = utils.path.removeBackslashes(base);
92
+ if (base in collection) {
93
+ collection[base].push(pattern);
94
+ }
95
+ else {
96
+ collection[base] = [pattern];
97
+ }
98
+ return collection;
99
+ }, group);
100
+ }
101
+ function convertPatternGroupsToTasks(positive, negative, dynamic) {
102
+ return Object.keys(positive).map((base) => {
103
+ return convertPatternGroupToTask(base, positive[base], negative, dynamic);
104
+ });
105
+ }
106
+ function convertPatternGroupToTask(base, positive, negative, dynamic) {
107
+ return {
108
+ dynamic,
109
+ positive,
110
+ negative,
111
+ base,
112
+ patterns: [].concat(positive, negative.map((pattern) => utils.pattern.convertToNegativePattern(pattern))),
113
+ };
114
+ }
@@ -0,0 +1,11 @@
1
+ import { Provider } from './provider';
2
+ import type { IReaderAsync } from '../readers';
3
+ import type Settings from '../settings';
4
+ import type { Task } from '../managers/tasks';
5
+ import type { Entry, EntryItem, ReaderOptions } from '../types';
6
+ export declare class ProviderAsync extends Provider<Promise<EntryItem[]>> {
7
+ #private;
8
+ constructor(reader: IReaderAsync, settings: Settings);
9
+ read(task: Task): Promise<EntryItem[]>;
10
+ api(root: string, task: Task, options: ReaderOptions): Promise<Entry[]>;
11
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ProviderAsync = void 0;
4
+ const provider_1 = require("./provider");
5
+ class ProviderAsync extends provider_1.Provider {
6
+ #reader;
7
+ constructor(reader, settings) {
8
+ super(settings);
9
+ this.#reader = reader;
10
+ }
11
+ async read(task) {
12
+ const root = this._getRootDirectory(task);
13
+ const options = this._getReaderOptions(task);
14
+ const entries = await this.api(root, task, options);
15
+ return entries.map((entry) => options.transform(entry));
16
+ }
17
+ api(root, task, options) {
18
+ if (task.dynamic) {
19
+ return this.#reader.dynamic(root, options);
20
+ }
21
+ return this.#reader.static(task.patterns, options);
22
+ }
23
+ }
24
+ exports.ProviderAsync = ProviderAsync;
@@ -0,0 +1,7 @@
1
+ import type { MicromatchOptions, EntryFilterFunction, Pattern } from '../../types';
2
+ import type Settings from '../../settings';
3
+ export default class DeepFilter {
4
+ #private;
5
+ constructor(settings: Settings, micromatchOptions: MicromatchOptions);
6
+ getFilter(basePath: string, positive: Pattern[], negative: Pattern[]): EntryFilterFunction;
7
+ }
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils = require("../../utils");
4
+ const partial_1 = require("../matchers/partial");
5
+ class DeepFilter {
6
+ #settings;
7
+ #micromatchOptions;
8
+ constructor(settings, micromatchOptions) {
9
+ this.#settings = settings;
10
+ this.#micromatchOptions = micromatchOptions;
11
+ }
12
+ getFilter(basePath, positive, negative) {
13
+ const matcher = this.#getMatcher(positive);
14
+ const negativeRe = this.#getNegativePatternsRe(negative);
15
+ return (entry) => this.#filter(basePath, entry, matcher, negativeRe);
16
+ }
17
+ #getMatcher(patterns) {
18
+ return new partial_1.default(patterns, this.#settings, this.#micromatchOptions);
19
+ }
20
+ #getNegativePatternsRe(patterns) {
21
+ const affectDepthOfReadingPatterns = patterns.filter((pattern) => utils.pattern.isAffectDepthOfReadingPattern(pattern));
22
+ return utils.pattern.convertPatternsToRe(affectDepthOfReadingPatterns, this.#micromatchOptions);
23
+ }
24
+ #filter(basePath, entry, matcher, negativeRe) {
25
+ if (this.#isSkippedByDeep(basePath, entry.path)) {
26
+ return false;
27
+ }
28
+ if (this.#isSkippedSymbolicLink(entry)) {
29
+ return false;
30
+ }
31
+ const filepath = utils.path.removeLeadingDotSegment(entry.path);
32
+ if (this.#isSkippedByPositivePatterns(filepath, matcher)) {
33
+ return false;
34
+ }
35
+ return this.#isSkippedByNegativePatterns(filepath, negativeRe);
36
+ }
37
+ #isSkippedByDeep(basePath, entryPath) {
38
+ /**
39
+ * Avoid unnecessary depth calculations when it doesn't matter.
40
+ */
41
+ if (this.#settings.deep === Number.POSITIVE_INFINITY) {
42
+ return false;
43
+ }
44
+ return this.#getEntryLevel(basePath, entryPath) >= this.#settings.deep;
45
+ }
46
+ #getEntryLevel(basePath, entryPath) {
47
+ const entryPathDepth = entryPath.split('/').length;
48
+ if (basePath === '') {
49
+ return entryPathDepth;
50
+ }
51
+ const basePathDepth = basePath.split('/').length;
52
+ return entryPathDepth - basePathDepth;
53
+ }
54
+ #isSkippedSymbolicLink(entry) {
55
+ return !this.#settings.followSymbolicLinks && entry.dirent.isSymbolicLink();
56
+ }
57
+ #isSkippedByPositivePatterns(entryPath, matcher) {
58
+ return !this.#settings.baseNameMatch && !matcher.match(entryPath);
59
+ }
60
+ #isSkippedByNegativePatterns(entryPath, patternsRe) {
61
+ return !utils.pattern.matchAny(entryPath, patternsRe);
62
+ }
63
+ }
64
+ exports.default = DeepFilter;
@@ -0,0 +1,8 @@
1
+ import type Settings from '../../settings';
2
+ import type { MicromatchOptions, EntryFilterFunction, Pattern } from '../../types';
3
+ export default class EntryFilter {
4
+ #private;
5
+ readonly index: Map<string, undefined>;
6
+ constructor(settings: Settings, micromatchOptions: MicromatchOptions);
7
+ getFilter(positive: Pattern[], negative: Pattern[]): EntryFilterFunction;
8
+ }
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils = require("../../utils");
4
+ class EntryFilter {
5
+ index = new Map();
6
+ #settings;
7
+ #micromatchOptions;
8
+ constructor(settings, micromatchOptions) {
9
+ this.#settings = settings;
10
+ this.#micromatchOptions = micromatchOptions;
11
+ }
12
+ getFilter(positive, negative) {
13
+ const [absoluteNegative, relativeNegative] = utils.pattern.partitionAbsoluteAndRelative(negative);
14
+ const patterns = {
15
+ positive: {
16
+ all: utils.pattern.convertPatternsToRe(positive, this.#micromatchOptions),
17
+ },
18
+ negative: {
19
+ absolute: utils.pattern.convertPatternsToRe(absoluteNegative, { ...this.#micromatchOptions, dot: true }),
20
+ relative: utils.pattern.convertPatternsToRe(relativeNegative, { ...this.#micromatchOptions, dot: true }),
21
+ },
22
+ };
23
+ return (entry) => this.#filter(entry, patterns);
24
+ }
25
+ #filter(entry, pattens) {
26
+ const filepath = utils.path.removeLeadingDotSegment(entry.path);
27
+ if (this.#settings.unique && this.#isDuplicateEntry(filepath)) {
28
+ return false;
29
+ }
30
+ const isDirectory = entry.dirent.isDirectory();
31
+ if (this.#onlyFileFilter(isDirectory) || this.#onlyDirectoryFilter(isDirectory)) {
32
+ return false;
33
+ }
34
+ const isMatched = this.#isMatchToPatternsSet(filepath, pattens, isDirectory);
35
+ if (this.#settings.unique && isMatched) {
36
+ this.#createIndexRecord(filepath);
37
+ }
38
+ return isMatched;
39
+ }
40
+ #isDuplicateEntry(filepath) {
41
+ return this.index.has(filepath);
42
+ }
43
+ #createIndexRecord(filepath) {
44
+ this.index.set(filepath, undefined);
45
+ }
46
+ #onlyFileFilter(isDirectory) {
47
+ return this.#settings.onlyFiles && isDirectory;
48
+ }
49
+ #onlyDirectoryFilter(isDirectory) {
50
+ return this.#settings.onlyDirectories && !isDirectory;
51
+ }
52
+ #isMatchToPatternsSet(filepath, patterns, isDirectory) {
53
+ const isMatched = this.#isMatchToPatterns(filepath, patterns.positive.all, isDirectory);
54
+ if (!isMatched) {
55
+ return false;
56
+ }
57
+ const isMatchedByRelativeNegative = this.#isMatchToPatterns(filepath, patterns.negative.relative, isDirectory);
58
+ if (isMatchedByRelativeNegative) {
59
+ return false;
60
+ }
61
+ const isMatchedByAbsoluteNegative = this.#isMatchToAbsoluteNegative(filepath, patterns.negative.absolute, isDirectory);
62
+ if (isMatchedByAbsoluteNegative) {
63
+ return false;
64
+ }
65
+ return true;
66
+ }
67
+ #isMatchToAbsoluteNegative(filepath, patternsRe, isDirectory) {
68
+ if (patternsRe.length === 0) {
69
+ return false;
70
+ }
71
+ const fullpath = utils.path.makeAbsolute(this.#settings.cwd, filepath);
72
+ return this.#isMatchToPatterns(fullpath, patternsRe, isDirectory);
73
+ }
74
+ #isMatchToPatterns(filepath, patternsRe, isDirectory) {
75
+ if (patternsRe.length === 0) {
76
+ return false;
77
+ }
78
+ // Trying to match files and directories by patterns.
79
+ const isMatched = utils.pattern.matchAny(filepath, patternsRe);
80
+ // A pattern with a trailling slash can be used for directory matching.
81
+ // To apply such pattern, we need to add a tralling slash to the path.
82
+ if (!isMatched && isDirectory) {
83
+ return utils.pattern.matchAny(`${filepath}/`, patternsRe);
84
+ }
85
+ return isMatched;
86
+ }
87
+ }
88
+ exports.default = EntryFilter;
@@ -0,0 +1,7 @@
1
+ import type Settings from '../../settings';
2
+ import type { ErrorFilterFunction } from '../../types';
3
+ export default class ErrorFilter {
4
+ #private;
5
+ constructor(settings: Settings);
6
+ getFilter(): ErrorFilterFunction;
7
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils = require("../../utils");
4
+ class ErrorFilter {
5
+ #settings;
6
+ constructor(settings) {
7
+ this.#settings = settings;
8
+ }
9
+ getFilter() {
10
+ return (error) => this.#isNonFatalError(error);
11
+ }
12
+ #isNonFatalError(error) {
13
+ return utils.errno.isEnoentCodeError(error) || this.#settings.suppressErrors;
14
+ }
15
+ }
16
+ exports.default = ErrorFilter;
@@ -0,0 +1,3 @@
1
+ export * from './async';
2
+ export * from './stream';
3
+ export * from './sync';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./async"), exports);
18
+ __exportStar(require("./stream"), exports);
19
+ __exportStar(require("./sync"), exports);
@@ -0,0 +1,28 @@
1
+ import type { MicromatchOptions, Pattern, PatternRe } from '../../types';
2
+ import type Settings from '../../settings';
3
+ export type PatternSegment = DynamicPatternSegment | StaticPatternSegment;
4
+ interface StaticPatternSegment {
5
+ dynamic: false;
6
+ pattern: Pattern;
7
+ }
8
+ interface DynamicPatternSegment {
9
+ dynamic: true;
10
+ pattern: Pattern;
11
+ patternRe: PatternRe;
12
+ }
13
+ export type PatternSection = PatternSegment[];
14
+ export interface PatternInfo {
15
+ /**
16
+ * Indicates that the pattern has a globstar (more than a single section).
17
+ */
18
+ complete: boolean;
19
+ pattern: Pattern;
20
+ segments: PatternSegment[];
21
+ sections: PatternSection[];
22
+ }
23
+ export default abstract class Matcher {
24
+ #private;
25
+ protected readonly _storage: PatternInfo[];
26
+ constructor(patterns: Pattern[], settings: Settings, micromatchOptions: MicromatchOptions);
27
+ }
28
+ export {};
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils = require("../../utils");
4
+ class Matcher {
5
+ _storage = [];
6
+ #patterns;
7
+ #settings;
8
+ #micromatchOptions;
9
+ constructor(patterns, settings, micromatchOptions) {
10
+ this.#patterns = patterns;
11
+ this.#settings = settings;
12
+ this.#micromatchOptions = micromatchOptions;
13
+ this.#fillStorage();
14
+ }
15
+ #fillStorage() {
16
+ for (const pattern of this.#patterns) {
17
+ const segments = this.#getPatternSegments(pattern);
18
+ const sections = this.#splitSegmentsIntoSections(segments);
19
+ this._storage.push({
20
+ complete: sections.length <= 1,
21
+ pattern,
22
+ segments,
23
+ sections,
24
+ });
25
+ }
26
+ }
27
+ #getPatternSegments(pattern) {
28
+ const parts = utils.pattern.getPatternParts(pattern, this.#micromatchOptions);
29
+ return parts.map((part) => {
30
+ const dynamic = utils.pattern.isDynamicPattern(part, this.#settings);
31
+ if (!dynamic) {
32
+ return {
33
+ dynamic: false,
34
+ pattern: part,
35
+ };
36
+ }
37
+ return {
38
+ dynamic: true,
39
+ pattern: part,
40
+ patternRe: utils.pattern.makeRe(part, this.#micromatchOptions),
41
+ };
42
+ });
43
+ }
44
+ #splitSegmentsIntoSections(segments) {
45
+ return utils.array.splitWhen(segments, (segment) => segment.dynamic && utils.pattern.hasGlobStar(segment.pattern));
46
+ }
47
+ }
48
+ exports.default = Matcher;
@@ -0,0 +1,4 @@
1
+ import Matcher from './matcher';
2
+ export default class PartialMatcher extends Matcher {
3
+ match(filepath: string): boolean;
4
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const matcher_1 = require("./matcher");
4
+ class PartialMatcher extends matcher_1.default {
5
+ match(filepath) {
6
+ const parts = filepath.split('/');
7
+ const levels = parts.length;
8
+ const patterns = this._storage.filter((info) => !info.complete || info.segments.length > levels);
9
+ for (const pattern of patterns) {
10
+ const section = pattern.sections[0];
11
+ /**
12
+ * In this case, the pattern has a globstar and we must read all directories unconditionally,
13
+ * but only if the level has reached the end of the first group.
14
+ *
15
+ * fixtures/{a,b}/**
16
+ * ^ true/false ^ always true
17
+ */
18
+ if (!pattern.complete && levels > section.length) {
19
+ return true;
20
+ }
21
+ const match = parts.every((part, index) => {
22
+ const segment = pattern.segments[index];
23
+ if (segment.dynamic && segment.patternRe.test(part)) {
24
+ return true;
25
+ }
26
+ if (!segment.dynamic && segment.pattern === part) {
27
+ return true;
28
+ }
29
+ return false;
30
+ });
31
+ if (match) {
32
+ return true;
33
+ }
34
+ }
35
+ return false;
36
+ }
37
+ }
38
+ exports.default = PartialMatcher;