view-ignored 0.10.0 → 0.11.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.
- package/README.md +118 -62
- 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 +23 -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 +158 -75
- package/out/patterns/matcherStream.d.ts +30 -11
- package/out/patterns/matcherStream.js +70 -25
- package/out/patterns/packagejson.d.ts +2 -2
- package/out/patterns/packagejson.js +11 -14
- package/out/patterns/patternCompile.js +48 -19
- package/out/patterns/patternList.d.ts +12 -6
- package/out/patterns/patternList.js +8 -4
- 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 +63 -9
- package/out/patterns/rule.js +101 -66
- 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 +43 -4
- package/out/walk.js +146 -84
- package/package.json +27 -23
- 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 -22
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,8 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import { scanParallel } from "../scanParallel.js";
|
|
2
|
+
import { dirname } from "../unixify.js";
|
|
3
|
+
import { walkPatchResult, walkPatchTotal, propagateTotals, } from "../walk.js";
|
|
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
|
+
}
|
|
6
14
|
/**
|
|
7
15
|
* Provides patching abilities for the given {@link MatcherContext}.
|
|
8
16
|
* Directories should have the slash suffix.
|
|
@@ -13,45 +21,110 @@ export async function matcherContextAddPath(ctx, options, entry) {
|
|
|
13
21
|
if (ctx.paths.has(entry)) {
|
|
14
22
|
return false;
|
|
15
23
|
}
|
|
16
|
-
const { target, fs, cwd, signal } = options;
|
|
17
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;
|
|
18
31
|
if (isDir) {
|
|
19
32
|
// recursive parent population
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
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 });
|
|
23
57
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
ctx.totalDirs++;
|
|
58
|
+
else if (total.totalFiles >= 0) {
|
|
59
|
+
total.totalDirs++;
|
|
27
60
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
void (await matcherContextAddPath(ctx, options, parent + "/"));
|
|
61
|
+
if (parentPath !== ".") {
|
|
62
|
+
void (await matcherContextAddPath(ctx, options, parentPath + "/"));
|
|
31
63
|
}
|
|
32
64
|
return true;
|
|
33
65
|
}
|
|
34
|
-
const parent = dirname(entry);
|
|
35
66
|
const isSource = target.extractors.some((e) => e.path === entry);
|
|
36
67
|
if (isSource) {
|
|
37
68
|
// add pattern sources
|
|
38
|
-
|
|
39
|
-
|
|
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
|
+
});
|
|
86
|
+
await matcherContextRemovePath(ctx, options, parentPath + "/");
|
|
87
|
+
await resultPromise;
|
|
88
|
+
propagateTotals(ctx.total);
|
|
40
89
|
}
|
|
41
90
|
// add paths
|
|
42
91
|
// 1. recursively populate parents
|
|
43
|
-
await matcherContextAddPath(ctx, options,
|
|
92
|
+
await matcherContextAddPath(ctx, options, parentPath + "/");
|
|
44
93
|
// 2. if ignored, remove, otherwise add
|
|
45
|
-
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
|
+
});
|
|
46
115
|
if (match.ignored) {
|
|
47
116
|
// 2.1. remove
|
|
48
117
|
await matcherContextRemovePath(ctx, options, entry);
|
|
49
118
|
return false;
|
|
50
119
|
}
|
|
51
120
|
// 2.2. add
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
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++;
|
|
55
128
|
}
|
|
56
129
|
ctx.paths.set(entry, match);
|
|
57
130
|
return true;
|
|
@@ -64,93 +137,103 @@ export async function matcherContextAddPath(ctx, options, entry) {
|
|
|
64
137
|
*/
|
|
65
138
|
export async function matcherContextRemovePath(ctx, options, entry) {
|
|
66
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 + "/";
|
|
67
150
|
if (isDir) {
|
|
68
151
|
// remove directories
|
|
69
|
-
|
|
152
|
+
let deletedDirs = 0, deletedFiles = 0;
|
|
153
|
+
const total = ctx.total.get(direntPath);
|
|
70
154
|
for (const [element] of ctx.paths) {
|
|
71
|
-
if (
|
|
155
|
+
if (!element.startsWith(entry)) {
|
|
72
156
|
continue;
|
|
73
157
|
}
|
|
74
|
-
if (
|
|
158
|
+
if (total && total.totalFiles >= 0) {
|
|
75
159
|
const isDir = element.endsWith("/");
|
|
76
160
|
if (isDir) {
|
|
77
|
-
|
|
161
|
+
deletedDirs++;
|
|
78
162
|
}
|
|
79
163
|
else {
|
|
80
|
-
|
|
81
|
-
ctx.totalMatchedFiles--;
|
|
164
|
+
deletedFiles++;
|
|
82
165
|
}
|
|
83
166
|
}
|
|
84
167
|
ctx.paths.delete(element);
|
|
85
168
|
}
|
|
86
|
-
|
|
87
|
-
|
|
169
|
+
deleteTotals(ctx, entry, deletedDirs, deletedFiles);
|
|
170
|
+
for (const [element] of ctx.external) {
|
|
171
|
+
if (!element.startsWith(direntPath)) {
|
|
88
172
|
continue;
|
|
89
173
|
}
|
|
90
|
-
ctx.
|
|
91
|
-
}
|
|
92
|
-
for (const [element] of ctx.external) {
|
|
93
|
-
if (entry !== "./" && !element.startsWith(direntPath)) {
|
|
174
|
+
if (!ctx.external.delete(element) || !ctx.failed.length) {
|
|
94
175
|
continue;
|
|
95
176
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
ctx.failed.splice(failedEntryIndex, 1);
|
|
101
|
-
}
|
|
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);
|
|
102
181
|
}
|
|
103
182
|
}
|
|
104
183
|
return true;
|
|
105
184
|
}
|
|
106
|
-
const parent = dirname(entry);
|
|
107
185
|
const isSource = options.target.extractors.some((e) => e.path === entry);
|
|
108
186
|
if (isSource) {
|
|
187
|
+
const maxDepth = options.depth;
|
|
109
188
|
// remove pattern sources
|
|
110
189
|
// rescan directory and repopulate stats
|
|
111
|
-
|
|
112
|
-
|
|
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);
|
|
113
210
|
return true;
|
|
114
211
|
}
|
|
115
212
|
// remove path
|
|
116
213
|
// 1. change stats
|
|
117
214
|
{
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
ctx.totalMatchedFiles
|
|
215
|
+
const total = ctx.total.get(parentPath);
|
|
216
|
+
if (!total) {
|
|
217
|
+
ctx.total.set(parentPath, { totalDirs: 0, totalFiles: 0, totalMatchedFiles: 0 });
|
|
121
218
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const dir = entry.substring(0, depthSlash);
|
|
126
|
-
let num = ctx.depthPaths.get(dir);
|
|
127
|
-
if (num) {
|
|
128
|
-
num--;
|
|
129
|
-
if (num <= 0) {
|
|
130
|
-
ctx.depthPaths.delete(dir);
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
ctx.depthPaths.set(dir, num);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
219
|
+
else if (total.totalFiles >= 0) {
|
|
220
|
+
total.totalFiles--;
|
|
221
|
+
total.totalMatchedFiles--;
|
|
136
222
|
}
|
|
137
223
|
}
|
|
138
224
|
// 2. remove from paths
|
|
139
225
|
ctx.paths.delete(entry);
|
|
140
226
|
return true;
|
|
141
227
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
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
|
+
}
|
|
156
239
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { Dirent } from "node:fs";
|
|
2
|
-
import { EventEmitter } from "node:events";
|
|
3
2
|
import type { MatcherContext } from "../patterns/matcherContext.js";
|
|
4
3
|
import type { ScanOptions, FsAdapter } from "../types.js";
|
|
5
4
|
import type { RuleMatch } from "./rule.js";
|
|
@@ -27,12 +26,6 @@ export type EntryInfo = {
|
|
|
27
26
|
* @since 0.6.0
|
|
28
27
|
*/
|
|
29
28
|
match: RuleMatch;
|
|
30
|
-
/**
|
|
31
|
-
* The matcher context.
|
|
32
|
-
*
|
|
33
|
-
* @since 0.6.0
|
|
34
|
-
*/
|
|
35
|
-
ctx: MatcherContext;
|
|
36
29
|
};
|
|
37
30
|
/**
|
|
38
31
|
* @see {@link MatcherStream} uses it for the "dirent" event.
|
|
@@ -52,16 +45,32 @@ export type EndListener = (ctx: MatcherContext) => void;
|
|
|
52
45
|
* @since 0.6.0
|
|
53
46
|
*/
|
|
54
47
|
export type EventMap = {
|
|
55
|
-
dirent:
|
|
56
|
-
end:
|
|
48
|
+
dirent: CustomEvent<EntryInfo>;
|
|
49
|
+
end: CustomEvent<MatcherContext>;
|
|
57
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* @see {@link MatcherStream} uses it for its event map.
|
|
53
|
+
*
|
|
54
|
+
* @since 0.11.0
|
|
55
|
+
*/
|
|
56
|
+
interface EventListener<K extends keyof EventMap> {
|
|
57
|
+
(evt: EventMap[K]): void;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* @see {@link MatcherStream} uses it for its event map.
|
|
61
|
+
*
|
|
62
|
+
* @since 0.11.0
|
|
63
|
+
*/
|
|
64
|
+
interface EventListenerObject<K extends keyof EventMap> {
|
|
65
|
+
handleEvent(object: EventMap[K]): void;
|
|
66
|
+
}
|
|
58
67
|
/**
|
|
59
68
|
* Event emitter.
|
|
60
|
-
* @
|
|
69
|
+
* @augments EventTarget
|
|
61
70
|
*
|
|
62
71
|
* @since 0.6.0
|
|
63
72
|
*/
|
|
64
|
-
export declare class MatcherStream extends
|
|
73
|
+
export declare class MatcherStream extends EventTarget {
|
|
65
74
|
#private;
|
|
66
75
|
constructor(options: ScanOptions & {
|
|
67
76
|
fs: FsAdapter;
|
|
@@ -70,10 +79,20 @@ export declare class MatcherStream extends EventEmitter<EventMap> {
|
|
|
70
79
|
} & {
|
|
71
80
|
captureRejections?: boolean;
|
|
72
81
|
});
|
|
82
|
+
addEventListener<K extends keyof EventMap>(type: K, callback: EventListenerObject<K> | EventListener<K>, options?: boolean | AddEventListenerOptions): void;
|
|
83
|
+
removeEventListener<K extends keyof EventMap>(type: K, callback: EventListenerObject<K> | EventListener<K>, options?: boolean | EventListenerOptions): void;
|
|
84
|
+
dispatchEvent(event: EventMap[keyof EventMap]): boolean;
|
|
73
85
|
/**
|
|
74
86
|
* Resolves when everything is scanned.
|
|
75
87
|
*
|
|
76
88
|
* @since 0.8.0
|
|
77
89
|
*/
|
|
78
90
|
start(): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Resolves when everything is scanned. (Callback version)
|
|
93
|
+
*
|
|
94
|
+
* @since 0.11.0
|
|
95
|
+
*/
|
|
96
|
+
startCb(cb: (err: Error | null, ctx: MatcherContext) => void): void;
|
|
79
97
|
}
|
|
98
|
+
export {};
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { walkIncludes } from "../walk.js";
|
|
1
|
+
import { scanParallel } from "../scanParallel.js";
|
|
2
|
+
import { unixify } from "../unixify.js";
|
|
3
|
+
import { walkPatchResult, walkPatchTotal, propagateTotals } from "../walk.js";
|
|
5
4
|
/**
|
|
6
5
|
* Event emitter.
|
|
7
|
-
* @
|
|
6
|
+
* @augments EventTarget
|
|
8
7
|
*
|
|
9
8
|
* @since 0.6.0
|
|
10
9
|
*/
|
|
11
|
-
export class MatcherStream extends
|
|
10
|
+
export class MatcherStream extends EventTarget {
|
|
12
11
|
#timeout;
|
|
13
12
|
#options;
|
|
14
13
|
constructor(options) {
|
|
15
|
-
super(
|
|
14
|
+
super();
|
|
16
15
|
this.#options = options;
|
|
17
16
|
if (!options.noTimeout) {
|
|
18
17
|
this.#timeout = setTimeout(() => {
|
|
@@ -20,27 +19,48 @@ export class MatcherStream extends EventEmitter {
|
|
|
20
19
|
}, 5e3);
|
|
21
20
|
}
|
|
22
21
|
}
|
|
22
|
+
addEventListener(type, callback, options) {
|
|
23
|
+
super.addEventListener(type, callback, options);
|
|
24
|
+
}
|
|
25
|
+
removeEventListener(type, callback, options) {
|
|
26
|
+
super.removeEventListener(type, callback, options);
|
|
27
|
+
}
|
|
28
|
+
dispatchEvent(event) {
|
|
29
|
+
return super.dispatchEvent(event);
|
|
30
|
+
}
|
|
23
31
|
/**
|
|
24
32
|
* Resolves when everything is scanned.
|
|
25
33
|
*
|
|
26
34
|
* @since 0.8.0
|
|
27
35
|
*/
|
|
28
|
-
|
|
36
|
+
start() {
|
|
37
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
38
|
+
this.startCb((err) => {
|
|
39
|
+
if (err) {
|
|
40
|
+
reject(err);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
resolve();
|
|
44
|
+
});
|
|
45
|
+
return promise;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Resolves when everything is scanned. (Callback version)
|
|
49
|
+
*
|
|
50
|
+
* @since 0.11.0
|
|
51
|
+
*/
|
|
52
|
+
startCb(cb) {
|
|
29
53
|
clearTimeout(this.#timeout);
|
|
30
54
|
const { target, cwd, within = ".", invert = false, depth: maxDepth = Infinity, signal = null, fastDepth = false, fastInternal = false, fs, } = this.#options;
|
|
31
55
|
const ctx = {
|
|
32
|
-
paths: new Map(),
|
|
33
56
|
external: new Map(),
|
|
34
57
|
failed: [],
|
|
35
|
-
|
|
36
|
-
totalFiles: 0,
|
|
37
|
-
totalMatchedFiles: 0,
|
|
38
|
-
totalDirs: 0,
|
|
58
|
+
paths: new Map(),
|
|
59
|
+
total: new Map([[".", { totalDirs: 0, totalFiles: 0, totalMatchedFiles: 0 }]]),
|
|
39
60
|
};
|
|
40
61
|
const normalCwd = unixify(cwd);
|
|
41
62
|
const scanOptions = {
|
|
42
63
|
cwd: normalCwd,
|
|
43
|
-
within,
|
|
44
64
|
depth: maxDepth,
|
|
45
65
|
fastDepth,
|
|
46
66
|
fastInternal,
|
|
@@ -48,19 +68,44 @@ export class MatcherStream extends EventEmitter {
|
|
|
48
68
|
invert,
|
|
49
69
|
signal,
|
|
50
70
|
target,
|
|
71
|
+
within,
|
|
51
72
|
};
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
73
|
+
const startScan = () => {
|
|
74
|
+
scanParallel({
|
|
75
|
+
external: ctx.external,
|
|
76
|
+
failed: ctx.failed,
|
|
77
|
+
onResult: (result) => {
|
|
78
|
+
if ("dir" in result) {
|
|
79
|
+
walkPatchTotal(ctx, scanOptions.depth, result);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
walkPatchResult(ctx, result);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
61
85
|
scanOptions,
|
|
86
|
+
stream: this,
|
|
87
|
+
within,
|
|
88
|
+
}, (err) => {
|
|
89
|
+
if (err) {
|
|
90
|
+
cb(err, null);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
propagateTotals(ctx.total);
|
|
94
|
+
cb(null, ctx);
|
|
95
|
+
this.dispatchEvent(new CustomEvent("end", { detail: ctx }));
|
|
62
96
|
});
|
|
63
|
-
}
|
|
64
|
-
|
|
97
|
+
};
|
|
98
|
+
if (target.init) {
|
|
99
|
+
target.init({ cwd: normalCwd, fs, signal, target }, (err) => {
|
|
100
|
+
if (err) {
|
|
101
|
+
cb(err, null);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
startScan();
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
startScan();
|
|
109
|
+
}
|
|
65
110
|
}
|
|
66
111
|
}
|
|
@@ -6,7 +6,7 @@ import { type Source } from "./source.js";
|
|
|
6
6
|
*
|
|
7
7
|
* @since 0.6.0
|
|
8
8
|
*/
|
|
9
|
-
export declare function extractPackageJson(source: Source, content: Buffer): void |
|
|
9
|
+
export declare function extractPackageJson(source: Source, content: Buffer): void | null | Error;
|
|
10
10
|
/**
|
|
11
11
|
* Extracts and compiles patterns from the file.
|
|
12
12
|
*
|
|
@@ -14,4 +14,4 @@ export declare function extractPackageJson(source: Source, content: Buffer): voi
|
|
|
14
14
|
*
|
|
15
15
|
* @since 0.8.0
|
|
16
16
|
*/
|
|
17
|
-
export declare function extractPackageJsonNocase(source: Source, content: Buffer): void |
|
|
17
|
+
export declare function extractPackageJsonNocase(source: Source, content: Buffer): void | null | Error;
|