view-ignored 0.10.1 → 0.11.1
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.
- package/README.md +116 -66
- package/out/browser.d.ts +1 -0
- package/out/browser.js +1 -0
- package/out/browser_scan.d.ts +1 -3
- package/out/browser_scan.js +11 -46
- package/out/browser_stream.d.ts +6 -1
- package/out/browser_stream.js +6 -1
- package/out/index.d.ts +1 -0
- package/out/index.js +1 -0
- package/out/patterns/extractor.d.ts +7 -7
- package/out/patterns/gitignore.d.ts +2 -2
- package/out/patterns/gitignore.js +14 -6
- package/out/patterns/ignores.d.ts +17 -8
- package/out/patterns/index.d.ts +1 -0
- package/out/patterns/index.js +1 -0
- package/out/patterns/init.d.ts +2 -2
- package/out/patterns/initState.d.ts +0 -7
- package/out/patterns/jsrjson.d.ts +2 -3
- package/out/patterns/jsrjson.js +25 -38
- package/out/patterns/matcherContext.d.ts +12 -9
- package/out/patterns/matcherContextPatch.js +153 -73
- package/out/patterns/matcherStream.d.ts +19 -59
- package/out/patterns/matcherStream.js +75 -25
- package/out/patterns/matcherStreamTypes.d.ts +65 -0
- package/out/patterns/matcherStreamTypes.js +1 -0
- package/out/patterns/packagejson.d.ts +2 -2
- package/out/patterns/packagejson.js +11 -14
- package/out/patterns/patternCompile.js +35 -37
- package/out/patterns/patternList.d.ts +6 -2
- package/out/patterns/patternList.js +8 -3
- package/out/patterns/resolveSources.d.ts +22 -5
- package/out/patterns/resolveSources.js +153 -97
- package/out/patterns/resource.d.ts +16 -0
- package/out/patterns/resource.js +1 -0
- package/out/patterns/rule.d.ts +59 -11
- package/out/patterns/rule.js +101 -64
- package/out/patterns/source.d.ts +9 -17
- package/out/scan.d.ts +11 -3
- package/out/scan.js +16 -4
- package/out/scanCb.d.ts +16 -0
- package/out/scanCb.js +73 -0
- package/out/scanParallel.d.ts +18 -0
- package/out/scanParallel.js +146 -0
- package/out/stream.d.ts +6 -1
- package/out/stream.js +7 -2
- package/out/targets/bun.js +43 -36
- package/out/targets/deno.js +25 -23
- package/out/targets/git.js +3 -3
- package/out/targets/jsr.js +25 -23
- package/out/targets/jsrManifest.d.ts +8 -7
- package/out/targets/jsrManifest.js +40 -9
- package/out/targets/npm.js +30 -23
- package/out/targets/npmManifest.d.ts +18 -46
- package/out/targets/npmManifest.js +96 -23
- package/out/targets/target.d.ts +8 -16
- package/out/targets/vsce.js +20 -27
- package/out/targets/vsceManifest.d.ts +7 -0
- package/out/targets/vsceManifest.js +18 -0
- package/out/targets/yarn.js +48 -39
- package/out/targets/yarnClassic.js +20 -18
- package/out/types.d.ts +8 -7
- package/out/unixify.d.ts +1 -1
- package/out/unixify.js +40 -21
- package/out/walk.d.ts +42 -4
- package/out/walk.js +146 -92
- package/package.json +42 -27
- package/out/getDepth.d.ts +0 -4
- package/out/getDepth.js +0 -21
- package/out/opendir.d.ts +0 -3
- package/out/opendir.js +0 -28
package/out/patterns/jsrjson.js
CHANGED
|
@@ -1,26 +1,16 @@
|
|
|
1
|
-
import { type } from "arktype";
|
|
2
1
|
import stripJsonComments from "strip-json-comments";
|
|
3
2
|
import { ruleCompile } from "./resolveSources.js";
|
|
4
3
|
import { resolveNegatable } from "./source.js";
|
|
5
|
-
const jsrManifest = type({
|
|
6
|
-
exclude: "string[]?",
|
|
7
|
-
include: "string[]?",
|
|
8
|
-
"publish?": {
|
|
9
|
-
exclude: "string[]?",
|
|
10
|
-
include: "string[]?",
|
|
11
|
-
},
|
|
12
|
-
});
|
|
13
|
-
const parse = type("string")
|
|
14
|
-
.pipe((s) => JSON.parse(s))
|
|
15
|
-
.pipe(jsrManifest);
|
|
16
4
|
/**
|
|
17
5
|
* Extracts and compiles patterns from the file.
|
|
18
6
|
*
|
|
19
7
|
* @since 0.6.0
|
|
20
8
|
*/
|
|
21
|
-
export function extractJsrJson(source, content
|
|
22
|
-
extract(source, content
|
|
23
|
-
|
|
9
|
+
export function extractJsrJson(source, content) {
|
|
10
|
+
const result = extract(source, content);
|
|
11
|
+
if (result instanceof Error)
|
|
12
|
+
return result;
|
|
13
|
+
for (const element of source.rules) {
|
|
24
14
|
ruleCompile(element);
|
|
25
15
|
}
|
|
26
16
|
}
|
|
@@ -32,39 +22,36 @@ extractJsrJson;
|
|
|
32
22
|
*
|
|
33
23
|
* @since 0.6.0
|
|
34
24
|
*/
|
|
35
|
-
export function extractJsrJsonc(source, content
|
|
36
|
-
extractJsrJson(source, Buffer.from(stripJsonComments(content.toString()))
|
|
25
|
+
export function extractJsrJsonc(source, content) {
|
|
26
|
+
return extractJsrJson(source, Buffer.from(stripJsonComments(content.toString())));
|
|
37
27
|
}
|
|
38
28
|
extractJsrJsonc;
|
|
39
|
-
function extract(source, content
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
if (dist instanceof type.errors) {
|
|
44
|
-
source.error = new Error("Invalid '" + source.path + "': " + dist.summary, { cause: dist });
|
|
45
|
-
ctx.failed.push(source);
|
|
46
|
-
return;
|
|
29
|
+
function extract(source, content) {
|
|
30
|
+
let dist;
|
|
31
|
+
try {
|
|
32
|
+
dist = JSON.parse(content.toString());
|
|
47
33
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
exclude.pattern.push(...dist.exclude);
|
|
51
|
-
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
return new Error("Invalid JSON in " + source.path, { cause: e });
|
|
52
36
|
}
|
|
53
|
-
|
|
54
|
-
|
|
37
|
+
// Basic runtime check to ensure dist is an object
|
|
38
|
+
if (!dist || typeof dist !== "object" || Array.isArray(dist)) {
|
|
39
|
+
return new Error("Invalid " + source.path + ": Root must be an object");
|
|
55
40
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
41
|
+
const include = { compiled: null, excludes: false, pattern: [] };
|
|
42
|
+
const exclude = { compiled: null, excludes: true, pattern: [] };
|
|
43
|
+
// Resolve patterns based on the manifest hierarchy
|
|
44
|
+
const target = dist.publish ?? dist;
|
|
45
|
+
if (target.exclude && Array.isArray(target.exclude)) {
|
|
46
|
+
exclude.pattern.push(...target.exclude);
|
|
60
47
|
}
|
|
61
|
-
|
|
62
|
-
include.pattern.push(...
|
|
48
|
+
if (target.include && Array.isArray(target.include)) {
|
|
49
|
+
include.pattern.push(...target.include);
|
|
63
50
|
}
|
|
64
51
|
for (const si of [include, exclude]) {
|
|
65
52
|
for (const pattern of si.pattern) {
|
|
66
53
|
resolveNegatable(pattern, true, include, exclude);
|
|
67
54
|
}
|
|
68
55
|
}
|
|
69
|
-
source.
|
|
56
|
+
source.rules.push(include, exclude);
|
|
70
57
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { Resource, InvalidSource } from "./resource.js";
|
|
1
2
|
import type { RuleMatch } from "./rule.js";
|
|
2
|
-
import type { Source } from "./source.js";
|
|
3
3
|
/**
|
|
4
4
|
* Post-scan results.
|
|
5
5
|
*
|
|
@@ -22,16 +22,16 @@ export interface MatcherContext {
|
|
|
22
22
|
*
|
|
23
23
|
* @since 0.6.0
|
|
24
24
|
*/
|
|
25
|
-
external: Map<string,
|
|
25
|
+
external: Map<string, Resource>;
|
|
26
26
|
/**
|
|
27
27
|
* If any fatal errors were encountered during source extractions,
|
|
28
28
|
* this property will contain an array of failed sources.
|
|
29
29
|
*
|
|
30
30
|
* @since 0.6.0
|
|
31
31
|
*/
|
|
32
|
-
failed:
|
|
32
|
+
failed: InvalidSource[];
|
|
33
33
|
/**
|
|
34
|
-
*
|
|
34
|
+
* Total number of files and directories scanned.
|
|
35
35
|
*
|
|
36
36
|
* @example
|
|
37
37
|
* // for
|
|
@@ -41,15 +41,18 @@ export interface MatcherContext {
|
|
|
41
41
|
* "src/views/index.html"
|
|
42
42
|
*
|
|
43
43
|
* // depth: 0
|
|
44
|
-
* "
|
|
44
|
+
* "." => { totalFiles: 1, totalMatchedFiles: 1, totalDirs: 3 }
|
|
45
|
+
* "src" => { totalFiles: 1, totalMatchedFiles: 1, totalDirs: 2 }
|
|
45
46
|
*
|
|
46
47
|
* // depth: 1
|
|
47
|
-
* "src/components" => 0
|
|
48
|
-
* "src/views" => 1
|
|
48
|
+
* "src/components" => { totalFiles: 0, totalMatchedFiles: 0, totalDirs: 0 }
|
|
49
|
+
* "src/views" => { totalFiles: 1, totalMatchedFiles: 1, totalDirs: 0 }
|
|
49
50
|
*
|
|
50
|
-
* @since 0.
|
|
51
|
+
* @since 0.11.0
|
|
51
52
|
*/
|
|
52
|
-
|
|
53
|
+
total: Map<string, Total>;
|
|
54
|
+
}
|
|
55
|
+
export interface Total {
|
|
53
56
|
/**
|
|
54
57
|
* Total number of files scanned.
|
|
55
58
|
*
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { unixify, join } from "../unixify.js";
|
|
5
|
-
import { walkIncludes } from "../walk.js";
|
|
1
|
+
import { scanParallel } from "../scanParallel.js";
|
|
2
|
+
import { dirname } from "../unixify.js";
|
|
3
|
+
import { walkPatchResult, walkPatchTotal, propagateTotals, } from "../walk.js";
|
|
6
4
|
import { resolveSources } from "./resolveSources.js";
|
|
5
|
+
function promiseCb(resolve, reject) {
|
|
6
|
+
return (err, res) => {
|
|
7
|
+
if (err) {
|
|
8
|
+
reject(err);
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
resolve(res);
|
|
12
|
+
};
|
|
13
|
+
}
|
|
7
14
|
/**
|
|
8
15
|
* Provides patching abilities for the given {@link MatcherContext}.
|
|
9
16
|
* Directories should have the slash suffix.
|
|
@@ -14,46 +21,110 @@ export async function matcherContextAddPath(ctx, options, entry) {
|
|
|
14
21
|
if (ctx.paths.has(entry)) {
|
|
15
22
|
return false;
|
|
16
23
|
}
|
|
17
|
-
const { target, fs, cwd, signal } = options;
|
|
18
24
|
const isDir = entry.endsWith("/");
|
|
25
|
+
const direntPath = isDir ? entry.slice(0, -1) : entry;
|
|
26
|
+
if (isDir && direntPath === ".") {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
const parentPath = dirname(direntPath);
|
|
30
|
+
const { target, fs, cwd, signal, depth: maxDepth } = options;
|
|
19
31
|
if (isDir) {
|
|
20
32
|
// recursive parent population
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
33
|
+
const resource = await new Promise((resolve, reject) => {
|
|
34
|
+
resolveSources({
|
|
35
|
+
cwd,
|
|
36
|
+
dir: direntPath,
|
|
37
|
+
external: ctx.external,
|
|
38
|
+
fs,
|
|
39
|
+
signal,
|
|
40
|
+
target,
|
|
41
|
+
}, promiseCb(resolve, reject));
|
|
42
|
+
});
|
|
43
|
+
ctx.paths.set(entry, await new Promise((resolve, reject) => {
|
|
44
|
+
target.ignores({
|
|
45
|
+
cwd,
|
|
46
|
+
entry: direntPath,
|
|
47
|
+
fs,
|
|
48
|
+
parentPath,
|
|
49
|
+
resource,
|
|
50
|
+
signal,
|
|
51
|
+
target,
|
|
52
|
+
}, promiseCb(resolve, reject));
|
|
53
|
+
}));
|
|
54
|
+
const total = ctx.total.get(parentPath);
|
|
55
|
+
if (!total) {
|
|
56
|
+
ctx.total.set(parentPath, { totalDirs: 1, totalFiles: 0, totalMatchedFiles: 0 });
|
|
24
57
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
ctx.paths.set(entry, await target.ignores({ fs, cwd, entry: direntPath, ctx, signal, target, parentPath }));
|
|
28
|
-
if (ctx.totalFiles >= 0) {
|
|
29
|
-
ctx.totalDirs++;
|
|
58
|
+
else if (total.totalFiles >= 0) {
|
|
59
|
+
total.totalDirs++;
|
|
30
60
|
}
|
|
31
61
|
if (parentPath !== ".") {
|
|
32
62
|
void (await matcherContextAddPath(ctx, options, parentPath + "/"));
|
|
33
63
|
}
|
|
34
64
|
return true;
|
|
35
65
|
}
|
|
36
|
-
const parentPath = dirname(entry);
|
|
37
66
|
const isSource = target.extractors.some((e) => e.path === entry);
|
|
38
67
|
if (isSource) {
|
|
39
68
|
// add pattern sources
|
|
69
|
+
const resultPromise = new Promise((resolve, reject) => {
|
|
70
|
+
scanParallel({
|
|
71
|
+
external: ctx.external,
|
|
72
|
+
failed: ctx.failed,
|
|
73
|
+
onResult: (result) => {
|
|
74
|
+
if ("dir" in result) {
|
|
75
|
+
walkPatchTotal(ctx, maxDepth, result);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
walkPatchResult(ctx, result);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
scanOptions: options,
|
|
82
|
+
stream: undefined,
|
|
83
|
+
within: parentPath,
|
|
84
|
+
}, promiseCb(resolve, reject));
|
|
85
|
+
});
|
|
40
86
|
await matcherContextRemovePath(ctx, options, parentPath + "/");
|
|
41
|
-
await
|
|
87
|
+
await resultPromise;
|
|
88
|
+
propagateTotals(ctx.total);
|
|
42
89
|
}
|
|
43
90
|
// add paths
|
|
44
91
|
// 1. recursively populate parents
|
|
45
92
|
await matcherContextAddPath(ctx, options, parentPath + "/");
|
|
46
93
|
// 2. if ignored, remove, otherwise add
|
|
47
|
-
const
|
|
94
|
+
const resource = (await new Promise((resolve, reject) => {
|
|
95
|
+
resolveSources({
|
|
96
|
+
cwd,
|
|
97
|
+
dir: parentPath,
|
|
98
|
+
external: ctx.external,
|
|
99
|
+
fs,
|
|
100
|
+
signal,
|
|
101
|
+
target,
|
|
102
|
+
}, promiseCb(resolve, reject));
|
|
103
|
+
}));
|
|
104
|
+
const match = await new Promise((resolve, reject) => {
|
|
105
|
+
target.ignores({
|
|
106
|
+
cwd,
|
|
107
|
+
entry,
|
|
108
|
+
fs,
|
|
109
|
+
parentPath,
|
|
110
|
+
resource,
|
|
111
|
+
signal,
|
|
112
|
+
target,
|
|
113
|
+
}, promiseCb(resolve, reject));
|
|
114
|
+
});
|
|
48
115
|
if (match.ignored) {
|
|
49
116
|
// 2.1. remove
|
|
50
117
|
await matcherContextRemovePath(ctx, options, entry);
|
|
51
118
|
return false;
|
|
52
119
|
}
|
|
53
120
|
// 2.2. add
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
ctx.totalMatchedFiles
|
|
121
|
+
const total = ctx.total.get(parentPath);
|
|
122
|
+
if (!total) {
|
|
123
|
+
ctx.total.set(parentPath, { totalDirs: 0, totalFiles: 1, totalMatchedFiles: 1 });
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
total.totalFiles++;
|
|
127
|
+
total.totalMatchedFiles++;
|
|
57
128
|
}
|
|
58
129
|
ctx.paths.set(entry, match);
|
|
59
130
|
return true;
|
|
@@ -66,94 +137,103 @@ export async function matcherContextAddPath(ctx, options, entry) {
|
|
|
66
137
|
*/
|
|
67
138
|
export async function matcherContextRemovePath(ctx, options, entry) {
|
|
68
139
|
const isDir = entry.endsWith("/");
|
|
140
|
+
const direntPath = isDir ? entry.slice(0, -1) : entry;
|
|
141
|
+
if (isDir && direntPath === ".") {
|
|
142
|
+
ctx.paths.clear();
|
|
143
|
+
ctx.external.clear();
|
|
144
|
+
ctx.failed.length = 0;
|
|
145
|
+
ctx.total.set(direntPath, { totalDirs: 0, totalFiles: 0, totalMatchedFiles: 0 });
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
const parentPath = dirname(direntPath);
|
|
149
|
+
const parentPathDir = parentPath + "/";
|
|
69
150
|
if (isDir) {
|
|
70
151
|
// remove directories
|
|
71
|
-
|
|
152
|
+
let deletedDirs = 0, deletedFiles = 0;
|
|
153
|
+
const total = ctx.total.get(direntPath);
|
|
72
154
|
for (const [element] of ctx.paths) {
|
|
73
|
-
if (
|
|
155
|
+
if (!element.startsWith(entry)) {
|
|
74
156
|
continue;
|
|
75
157
|
}
|
|
76
|
-
if (
|
|
158
|
+
if (total && total.totalFiles >= 0) {
|
|
77
159
|
const isDir = element.endsWith("/");
|
|
78
160
|
if (isDir) {
|
|
79
|
-
|
|
161
|
+
deletedDirs++;
|
|
80
162
|
}
|
|
81
163
|
else {
|
|
82
|
-
|
|
83
|
-
ctx.totalMatchedFiles--;
|
|
164
|
+
deletedFiles++;
|
|
84
165
|
}
|
|
85
166
|
}
|
|
86
167
|
ctx.paths.delete(element);
|
|
87
168
|
}
|
|
88
|
-
|
|
89
|
-
|
|
169
|
+
deleteTotals(ctx, entry, deletedDirs, deletedFiles);
|
|
170
|
+
for (const [element] of ctx.external) {
|
|
171
|
+
if (!element.startsWith(direntPath)) {
|
|
90
172
|
continue;
|
|
91
173
|
}
|
|
92
|
-
ctx.
|
|
93
|
-
}
|
|
94
|
-
for (const [element] of ctx.external) {
|
|
95
|
-
if (entry !== "./" && !element.startsWith(direntPath)) {
|
|
174
|
+
if (!ctx.external.delete(element) || !ctx.failed.length) {
|
|
96
175
|
continue;
|
|
97
176
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
ctx.failed.splice(failedEntryIndex, 1);
|
|
103
|
-
}
|
|
177
|
+
// 3.1. remove failed sources
|
|
178
|
+
const failedEntryIndex = ctx.failed.findIndex((fail) => dirname(fail.source.path) === element);
|
|
179
|
+
if (failedEntryIndex >= 0) {
|
|
180
|
+
ctx.failed.splice(failedEntryIndex, 1);
|
|
104
181
|
}
|
|
105
182
|
}
|
|
106
183
|
return true;
|
|
107
184
|
}
|
|
108
|
-
const parent = dirname(entry);
|
|
109
185
|
const isSource = options.target.extractors.some((e) => e.path === entry);
|
|
110
186
|
if (isSource) {
|
|
187
|
+
const maxDepth = options.depth;
|
|
111
188
|
// remove pattern sources
|
|
112
189
|
// rescan directory and repopulate stats
|
|
113
|
-
|
|
114
|
-
|
|
190
|
+
const resultPromise = new Promise((resolve, reject) => {
|
|
191
|
+
scanParallel({
|
|
192
|
+
external: ctx.external,
|
|
193
|
+
failed: ctx.failed,
|
|
194
|
+
onResult: (result) => {
|
|
195
|
+
if ("dir" in result) {
|
|
196
|
+
walkPatchTotal(ctx, maxDepth, result);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
walkPatchResult(ctx, result);
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
scanOptions: options,
|
|
203
|
+
stream: undefined,
|
|
204
|
+
within: parentPath,
|
|
205
|
+
}, promiseCb(resolve, reject));
|
|
206
|
+
});
|
|
207
|
+
await matcherContextRemovePath(ctx, options, parentPathDir);
|
|
208
|
+
await resultPromise;
|
|
209
|
+
propagateTotals(ctx.total);
|
|
115
210
|
return true;
|
|
116
211
|
}
|
|
117
212
|
// remove path
|
|
118
213
|
// 1. change stats
|
|
119
214
|
{
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
ctx.totalMatchedFiles
|
|
215
|
+
const total = ctx.total.get(parentPath);
|
|
216
|
+
if (!total) {
|
|
217
|
+
ctx.total.set(parentPath, { totalDirs: 0, totalFiles: 0, totalMatchedFiles: 0 });
|
|
123
218
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const dir = entry.substring(0, depthSlash);
|
|
128
|
-
let num = ctx.depthPaths.get(dir);
|
|
129
|
-
if (num) {
|
|
130
|
-
num--;
|
|
131
|
-
if (num <= 0) {
|
|
132
|
-
ctx.depthPaths.delete(dir);
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
ctx.depthPaths.set(dir, num);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
219
|
+
else if (total.totalFiles >= 0) {
|
|
220
|
+
total.totalFiles--;
|
|
221
|
+
total.totalMatchedFiles--;
|
|
138
222
|
}
|
|
139
223
|
}
|
|
140
224
|
// 2. remove from paths
|
|
141
225
|
ctx.paths.delete(entry);
|
|
142
226
|
return true;
|
|
143
227
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
let
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
scanOptions: { ...options, cwd: normalCwd },
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
ctx.totalDirs = ctx.totalFiles = ctx.totalMatchedFiles = -1;
|
|
228
|
+
function deleteTotals(ctx, entry, deletedDirs = 0, deletedFiles = 0) {
|
|
229
|
+
if (entry.endsWith("/"))
|
|
230
|
+
ctx.total.delete(entry);
|
|
231
|
+
for (let parent = dirname(entry); parent !== "./"; parent = dirname(parent) + "/") {
|
|
232
|
+
const total = ctx.total.get(parent);
|
|
233
|
+
if (!total)
|
|
234
|
+
continue;
|
|
235
|
+
total.totalDirs -= deletedDirs;
|
|
236
|
+
total.totalFiles -= deletedFiles;
|
|
237
|
+
total.totalMatchedFiles -= deletedFiles;
|
|
238
|
+
}
|
|
159
239
|
}
|
|
@@ -1,79 +1,39 @@
|
|
|
1
|
-
import type { Dirent } from "node:fs";
|
|
2
|
-
import { EventEmitter } from "node:events";
|
|
3
1
|
import type { MatcherContext } from "../patterns/matcherContext.js";
|
|
4
2
|
import type { ScanOptions, FsAdapter } from "../types.js";
|
|
5
|
-
import type {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
* The relative path of the entry.
|
|
14
|
-
*
|
|
15
|
-
* @since 0.6.0
|
|
16
|
-
*/
|
|
17
|
-
path: string;
|
|
18
|
-
/**
|
|
19
|
-
* The directory entry.
|
|
20
|
-
*
|
|
21
|
-
* @since 0.6.0
|
|
22
|
-
*/
|
|
23
|
-
dirent: Dirent;
|
|
24
|
-
/**
|
|
25
|
-
* Whether the entry was ignored.
|
|
26
|
-
*
|
|
27
|
-
* @since 0.6.0
|
|
28
|
-
*/
|
|
29
|
-
match: RuleMatch;
|
|
30
|
-
/**
|
|
31
|
-
* The matcher context.
|
|
32
|
-
*
|
|
33
|
-
* @since 0.6.0
|
|
34
|
-
*/
|
|
35
|
-
ctx: MatcherContext;
|
|
36
|
-
};
|
|
37
|
-
/**
|
|
38
|
-
* @see {@link MatcherStream} uses it for the "dirent" event.
|
|
39
|
-
*
|
|
40
|
-
* @since 0.6.0
|
|
41
|
-
*/
|
|
42
|
-
export type EntryListener = (info: EntryInfo) => void;
|
|
43
|
-
/**
|
|
44
|
-
* @see {@link MatcherStream} uses it for the "end" event.
|
|
45
|
-
*
|
|
46
|
-
* @since 0.6.0
|
|
47
|
-
*/
|
|
48
|
-
export type EndListener = (ctx: MatcherContext) => void;
|
|
49
|
-
/**
|
|
50
|
-
* @see {@link MatcherStream} uses it for its event map.
|
|
51
|
-
*
|
|
52
|
-
* @since 0.6.0
|
|
53
|
-
*/
|
|
54
|
-
export type EventMap = {
|
|
55
|
-
dirent: [EntryInfo];
|
|
56
|
-
end: [MatcherContext];
|
|
57
|
-
};
|
|
3
|
+
import type { EventMap, EventListener, EventListenerObject } from "./matcherStreamTypes.js";
|
|
4
|
+
export type { EntryInfo, EntryListener, EndListener, EventMap } from "./matcherStreamTypes.js";
|
|
5
|
+
export interface AddEventListenerOptions {
|
|
6
|
+
capture?: boolean;
|
|
7
|
+
once?: boolean;
|
|
8
|
+
passive?: boolean;
|
|
9
|
+
signal?: AbortSignal;
|
|
10
|
+
}
|
|
58
11
|
/**
|
|
59
12
|
* Event emitter.
|
|
60
|
-
* @
|
|
13
|
+
* @augments EventTarget
|
|
61
14
|
*
|
|
62
15
|
* @since 0.6.0
|
|
63
16
|
*/
|
|
64
|
-
export declare class MatcherStream extends
|
|
17
|
+
export declare class MatcherStream extends EventTarget {
|
|
65
18
|
#private;
|
|
66
19
|
constructor(options: ScanOptions & {
|
|
67
20
|
fs: FsAdapter;
|
|
68
21
|
cwd: string;
|
|
69
22
|
noTimeout?: boolean;
|
|
70
|
-
} & {
|
|
71
|
-
captureRejections?: boolean;
|
|
72
23
|
});
|
|
24
|
+
addEventListener<K extends keyof EventMap>(type: K, callback: EventListenerObject<K> | EventListener<K> | null, options?: boolean | AddEventListenerOptions): void;
|
|
25
|
+
removeEventListener<K extends keyof EventMap>(type: K, callback: EventListenerObject<K> | EventListener<K> | null, options?: boolean | EventListenerOptions): void;
|
|
26
|
+
dispatchEvent(event: EventMap[keyof EventMap]): boolean;
|
|
73
27
|
/**
|
|
74
28
|
* Resolves when everything is scanned.
|
|
75
29
|
*
|
|
76
30
|
* @since 0.8.0
|
|
77
31
|
*/
|
|
78
32
|
start(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Resolves when everything is scanned. (Callback version)
|
|
35
|
+
*
|
|
36
|
+
* @since 0.11.0
|
|
37
|
+
*/
|
|
38
|
+
startCb(cb: (err: Error | null, ctx: MatcherContext) => void): void;
|
|
79
39
|
}
|