view-ignored 0.4.2 → 0.4.4
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 +68 -20
- package/out/browser/binds/index.js +16 -4
- package/out/browser/binds/plugins/git.js +8 -3
- package/out/browser/binds/plugins/jsr.js +17 -6
- package/out/browser/binds/plugins/npm.js +12 -4
- package/out/browser/binds/plugins/vsce.js +12 -4
- package/out/browser/binds/plugins/yarn.js +10 -4
- package/out/browser/binds/scanner.d.ts +2 -0
- package/out/browser/binds/scanner.js +63 -23
- package/out/browser/filtering.js +2 -1
- package/out/browser/fs/directory.d.ts +1 -1
- package/out/browser/fs/directory.js +21 -7
- package/out/browser/fs/file-info.js +12 -5
- package/out/browser/fs/source-info.js +1 -1
- package/out/browser/lib.d.ts +1 -1
- package/out/browser/sorting.js +7 -1
- package/out/browser/styling.d.ts +2 -2
- package/out/browser/styling.js +11 -5
- package/out/cli.d.ts +1 -2
- package/out/cli.js +104 -98
- package/out/config.d.ts +4 -1
- package/out/config.js +29 -8
- package/package.json +113 -113
package/README.md
CHANGED
|
@@ -5,14 +5,25 @@
|
|
|
5
5
|
[](https://github.com/Mopsgamer/view-ignored)
|
|
6
6
|
[](https://github.com/Mopsgamer/view-ignored/issues)
|
|
7
7
|
|
|
8
|
-
Retrieve list of files ignored/included by Git, NPM, Yarn, JSR, VSCE or other
|
|
8
|
+
Retrieve list of files ignored/included by Git, NPM, Yarn, JSR, VSCE or other
|
|
9
|
+
tools.
|
|
10
|
+
|
|
11
|
+
## Requirements
|
|
12
|
+
|
|
13
|
+
Requires Node.js vXX or later.
|
|
9
14
|
|
|
10
15
|
## Highlights
|
|
11
16
|
|
|
12
|
-
- **Multi-target.** Get list of included files
|
|
13
|
-
|
|
14
|
-
- **
|
|
15
|
-
|
|
17
|
+
- **Multi-target.** Get a list of included files using configuration file
|
|
18
|
+
readers, not command-line wrappers.
|
|
19
|
+
- **Use in browser.** view-ignored can run in the browser using a file system
|
|
20
|
+
adapter.
|
|
21
|
+
- **Command-line.** Supports no-color and multiple output styles (tree, list,
|
|
22
|
+
parsable, etc.), including
|
|
23
|
+
[Nerd Fonts](https://github.com/ryanoasis/nerd-fonts).
|
|
24
|
+
- **Plugins.** view-ignored allows you to add new [targets](#targets)
|
|
25
|
+
programmatically. Command-line interface supports plugins through `--plugins`
|
|
26
|
+
option.
|
|
16
27
|
|
|
17
28
|
## Install
|
|
18
29
|
|
|
@@ -20,10 +31,14 @@ Retrieve list of files ignored/included by Git, NPM, Yarn, JSR, VSCE or other to
|
|
|
20
31
|
npm i view-ignored
|
|
21
32
|
```
|
|
22
33
|
|
|
34
|
+
TypeScript types are included.
|
|
35
|
+
|
|
23
36
|
## Usage
|
|
24
37
|
|
|
25
38
|
### Command-line
|
|
26
39
|
|
|
40
|
+
After installing globally, you can use the following commands:
|
|
41
|
+
|
|
27
42
|
```bash
|
|
28
43
|
# get started
|
|
29
44
|
npm i -g view-ignored
|
|
@@ -31,26 +46,27 @@ viewig --help
|
|
|
31
46
|
view-ignored --help
|
|
32
47
|
|
|
33
48
|
# scan: git (default) and npm
|
|
34
|
-
viewig scan
|
|
35
|
-
viewig scan
|
|
36
|
-
viewig scan
|
|
49
|
+
viewig scan
|
|
50
|
+
viewig scan --target=npm
|
|
51
|
+
viewig scan --parsable
|
|
37
52
|
|
|
38
53
|
# scan: plugins (space, comma or pipe separated)
|
|
39
54
|
# all built-in plugins loaded automatically
|
|
40
|
-
|
|
41
|
-
viewig scan
|
|
42
|
-
viewig scan
|
|
43
|
-
viewig scan
|
|
55
|
+
# Replace example1/example2 with real plugin names
|
|
56
|
+
viewig scan --plugins="example1, example2"
|
|
57
|
+
viewig scan --plugins="example1 example2"
|
|
58
|
+
viewig scan --plugins example1 example2
|
|
59
|
+
viewig scan --plugins example1, example2
|
|
44
60
|
|
|
45
61
|
# config: print configuration entries
|
|
46
62
|
viewig config get
|
|
47
63
|
viewig config get --real
|
|
48
64
|
# config: set npm as default target and scan for npm
|
|
49
65
|
viewig config set target=npm
|
|
50
|
-
viewig scan
|
|
66
|
+
viewig scan
|
|
51
67
|
# config: always use nerdfonts
|
|
52
68
|
viewig config set style=tree
|
|
53
|
-
# config: always use
|
|
69
|
+
# config: always use Nerd Fonts for decoration
|
|
54
70
|
viewig config set decor=nerdfonts
|
|
55
71
|
# config: always use plugins
|
|
56
72
|
viewig config set plugins=example1,example2
|
|
@@ -58,7 +74,7 @@ viewig config set plugins=example1,example2
|
|
|
58
74
|
|
|
59
75
|
### Programmatically
|
|
60
76
|
|
|
61
|
-
|
|
77
|
+
To use programmatically:
|
|
62
78
|
|
|
63
79
|
```js
|
|
64
80
|
import * as vign from "view-ignored"; // or "view-ignored/browser"
|
|
@@ -68,12 +84,20 @@ await vign.Plugins.loadBuiltIns(); // load all built-in plugins
|
|
|
68
84
|
await vign.Plugins.loadPlugins(["example"]); // load third-party plugins
|
|
69
85
|
|
|
70
86
|
// scan - options available
|
|
71
|
-
const fileInfoList = await vign.scan(".", {
|
|
72
|
-
|
|
87
|
+
const fileInfoList = await vign.scan(".", {
|
|
88
|
+
target: "git",
|
|
89
|
+
cwd: process.cwd(),
|
|
90
|
+
});
|
|
91
|
+
const fileInfoList2 = await vign.scan(["./path/to/file"], {
|
|
92
|
+
target: "git",
|
|
93
|
+
cwd: process.cwd(),
|
|
94
|
+
});
|
|
73
95
|
|
|
74
96
|
// use results
|
|
75
|
-
|
|
97
|
+
for (const fileInfo of fileInfoList) {
|
|
98
|
+
if (fileInfo.ignored) {
|
|
76
99
|
superCodeEditor.explorer.colorFile(fileInfo.relativePath, "gray");
|
|
100
|
+
}
|
|
77
101
|
}
|
|
78
102
|
```
|
|
79
103
|
|
|
@@ -81,14 +105,38 @@ if (fileInfo.ignored) {
|
|
|
81
105
|
|
|
82
106
|
```js
|
|
83
107
|
const sorter = vign.Sorting.firstFolders;
|
|
84
|
-
const fileInfoList = await vign.scan(".", {target: "npm"});
|
|
85
|
-
const fileInfoSorted = fileInfoList.sort((a, b) =>
|
|
108
|
+
const fileInfoList = await vign.scan(".", { target: "npm" });
|
|
109
|
+
const fileInfoSorted = fileInfoList.sort((a, b) =>
|
|
110
|
+
sorter(String(a), String(b))
|
|
111
|
+
);
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
#### Plugin export example
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
const bind: Plugins.TargetBind = {
|
|
118
|
+
id,
|
|
119
|
+
icon,
|
|
120
|
+
name,
|
|
121
|
+
testCommand,
|
|
122
|
+
scanOptions: {
|
|
123
|
+
target: methodologyGitignoreLike(".gitignore"),
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
const git: Plugins.PluginExport = { viewignored: { addTargets: [bind] } };
|
|
127
|
+
export default git;
|
|
86
128
|
```
|
|
87
129
|
|
|
88
130
|
### Targets
|
|
89
131
|
|
|
132
|
+
The following built-in plugins are available:
|
|
133
|
+
|
|
90
134
|
- `git`
|
|
91
135
|
- `npm` (compatible with Bun, PNPM, and others)
|
|
92
136
|
- `yarn`
|
|
93
137
|
- `vsce`
|
|
94
138
|
- `jsr` (compatible with Deno)
|
|
139
|
+
|
|
140
|
+
## License
|
|
141
|
+
|
|
142
|
+
MIT License. See [LICENSE.txt](LICENSE.txt) for details.
|
|
@@ -26,7 +26,8 @@ export function isPluginExport(value) {
|
|
|
26
26
|
}
|
|
27
27
|
const vign = value.viewignored;
|
|
28
28
|
return (vign?.constructor === Object)
|
|
29
|
-
&& 'addTargets' in vign && Array.isArray(vign.addTargets)
|
|
29
|
+
&& 'addTargets' in vign && Array.isArray(vign.addTargets)
|
|
30
|
+
&& vign.addTargets.every(v => isTargetBind(v));
|
|
30
31
|
}
|
|
31
32
|
/**
|
|
32
33
|
* Imports the plugin's exported data.
|
|
@@ -43,8 +44,15 @@ export function importPlugin(exportData) {
|
|
|
43
44
|
*/
|
|
44
45
|
export async function loadPlugin(modulePath, useImport = false) {
|
|
45
46
|
try {
|
|
46
|
-
const exports = useImport
|
|
47
|
-
|
|
47
|
+
const exports = useImport
|
|
48
|
+
? Object.getOwnPropertyDescriptor(await import(modulePath), 'default')
|
|
49
|
+
?.value
|
|
50
|
+
: await load(modulePath);
|
|
51
|
+
const result = {
|
|
52
|
+
resource: modulePath,
|
|
53
|
+
isLoaded: true,
|
|
54
|
+
exports,
|
|
55
|
+
};
|
|
48
56
|
if (isPluginExport(exports)) {
|
|
49
57
|
importPlugin(exports);
|
|
50
58
|
}
|
|
@@ -56,7 +64,11 @@ export async function loadPlugin(modulePath, useImport = false) {
|
|
|
56
64
|
if (r?.code === 'ERR_MODULE_NOT_FOUND') {
|
|
57
65
|
reason = r.message;
|
|
58
66
|
}
|
|
59
|
-
const fail = {
|
|
67
|
+
const fail = {
|
|
68
|
+
resource: modulePath,
|
|
69
|
+
isLoaded: false,
|
|
70
|
+
exports: reason,
|
|
71
|
+
};
|
|
60
72
|
return fail;
|
|
61
73
|
}
|
|
62
74
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { icons } from '@m234/nerd-fonts';
|
|
2
|
-
import {
|
|
2
|
+
import { Directory, File, InvalidPatternError, NoSourceError, SourceInfo, } from '../../index.js';
|
|
3
3
|
import { ScannerGitignore } from '../scanner.js';
|
|
4
4
|
const id = 'git';
|
|
5
5
|
const name = 'Git';
|
|
@@ -41,7 +41,8 @@ export const methodologyGitignoreLike = (base) => function (tree, o) {
|
|
|
41
41
|
}
|
|
42
42
|
for (const sourceFile of sourceList) {
|
|
43
43
|
const scanner = new ScannerGitignore({ exclude: matcherExclude });
|
|
44
|
-
const content = o.modules.fs.readFileSync(sourceFile.absolutePath)
|
|
44
|
+
const content = o.modules.fs.readFileSync(sourceFile.absolutePath)
|
|
45
|
+
.toString();
|
|
45
46
|
const pattern = content;
|
|
46
47
|
if (!scanner.isValid(pattern)) {
|
|
47
48
|
throw new InvalidPatternError(sourceFile, pattern);
|
|
@@ -52,7 +53,11 @@ export const methodologyGitignoreLike = (base) => function (tree, o) {
|
|
|
52
53
|
return map;
|
|
53
54
|
};
|
|
54
55
|
const bind = {
|
|
55
|
-
id,
|
|
56
|
+
id,
|
|
57
|
+
icon,
|
|
58
|
+
name,
|
|
59
|
+
testCommand,
|
|
60
|
+
scanOptions: {
|
|
56
61
|
target: methodologyGitignoreLike('.gitignore'),
|
|
57
62
|
},
|
|
58
63
|
};
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { icons } from '@m234/nerd-fonts';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { Directory, InvalidPatternError,
|
|
3
|
+
import { BadSourceError, Directory, InvalidPatternError, } from '../../index.js';
|
|
4
4
|
import { ScannerGitignore } from '../scanner.js';
|
|
5
5
|
import * as git from './git.js';
|
|
6
6
|
const id = 'jsr';
|
|
7
7
|
const name = 'JSR';
|
|
8
|
-
const icon = {
|
|
8
|
+
const icon = {
|
|
9
|
+
...icons['nf-ple-pixelated_squares_big'],
|
|
10
|
+
color: '#F5DD1E',
|
|
11
|
+
};
|
|
9
12
|
/**
|
|
10
13
|
* @internal
|
|
11
14
|
*/
|
|
@@ -61,7 +64,8 @@ export const sourceSearch = (priority, scanner) => function (tree, o) {
|
|
|
61
64
|
throw new BadSourceError(sourceFile, 'Must have \'name\', \'version\'.');
|
|
62
65
|
}
|
|
63
66
|
const { exclude, include, publish } = manifest;
|
|
64
|
-
if (exclude === undefined && include === undefined
|
|
67
|
+
if (exclude === undefined && include === undefined
|
|
68
|
+
&& publish === undefined) {
|
|
65
69
|
continue;
|
|
66
70
|
}
|
|
67
71
|
const pattern = publish?.include ?? include;
|
|
@@ -75,7 +79,8 @@ export const sourceSearch = (priority, scanner) => function (tree, o) {
|
|
|
75
79
|
}
|
|
76
80
|
}
|
|
77
81
|
else {
|
|
78
|
-
const content = o.modules.fs.readFileSync(sourceFile.absolutePath)
|
|
82
|
+
const content = o.modules.fs.readFileSync(sourceFile.absolutePath)
|
|
83
|
+
.toString();
|
|
79
84
|
const pattern = content;
|
|
80
85
|
if (!scanner.isValid(pattern)) {
|
|
81
86
|
throw new InvalidPatternError(sourceFile, pattern);
|
|
@@ -88,8 +93,14 @@ export const sourceSearch = (priority, scanner) => function (tree, o) {
|
|
|
88
93
|
return useChildren(tree, map, child => sourceSearch(priority, scanner)(child, o));
|
|
89
94
|
};
|
|
90
95
|
const bind = {
|
|
91
|
-
id,
|
|
92
|
-
|
|
96
|
+
id,
|
|
97
|
+
icon,
|
|
98
|
+
name,
|
|
99
|
+
scanOptions: {
|
|
100
|
+
target: sourceSearch(['deno.json', 'deno.jsonc', 'jsr.json', 'jsr.jsonc'], new ScannerGitignore({
|
|
101
|
+
exclude: matcherExclude,
|
|
102
|
+
include: matcherInclude,
|
|
103
|
+
})),
|
|
93
104
|
},
|
|
94
105
|
};
|
|
95
106
|
const npm = { viewignored: { addTargets: [bind] } };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { icons } from '@m234/nerd-fonts';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { Directory, InvalidPatternError,
|
|
3
|
+
import { BadSourceError, Directory, InvalidPatternError, NoSourceError, } from '../../index.js';
|
|
4
4
|
import { ScannerGitignore } from '../scanner.js';
|
|
5
5
|
import * as git from './git.js';
|
|
6
6
|
const id = 'npm';
|
|
@@ -89,7 +89,8 @@ export const sourceSearch = (priority, scanner) => function (tree, o) {
|
|
|
89
89
|
scanner.pattern = pattern;
|
|
90
90
|
}
|
|
91
91
|
else {
|
|
92
|
-
const content = o.modules.fs.readFileSync(sourceFile.absolutePath)
|
|
92
|
+
const content = o.modules.fs.readFileSync(sourceFile.absolutePath)
|
|
93
|
+
.toString();
|
|
93
94
|
const pattern = content;
|
|
94
95
|
if (!scanner.isValid(pattern)) {
|
|
95
96
|
throw new InvalidPatternError(sourceFile, pattern);
|
|
@@ -128,8 +129,15 @@ export const methodologyManifestNpmLike = (priority, scanner) => function (tree,
|
|
|
128
129
|
return sourceSearch(priority, scanner)(tree, o);
|
|
129
130
|
};
|
|
130
131
|
const bind = {
|
|
131
|
-
id,
|
|
132
|
-
|
|
132
|
+
id,
|
|
133
|
+
icon,
|
|
134
|
+
name,
|
|
135
|
+
testCommand,
|
|
136
|
+
scanOptions: {
|
|
137
|
+
target: methodologyManifestNpmLike(['package.json', '.npmignore', '.gitignore'], new ScannerGitignore({
|
|
138
|
+
exclude: matcherExclude,
|
|
139
|
+
include: matcherInclude,
|
|
140
|
+
})),
|
|
133
141
|
},
|
|
134
142
|
};
|
|
135
143
|
const npm = { viewignored: { addTargets: [bind] } };
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { icons } from '@m234/nerd-fonts';
|
|
2
|
-
import {
|
|
2
|
+
import { BadSourceError, File, NoSourceError, } from '../../index.js';
|
|
3
3
|
import * as git from './git.js';
|
|
4
4
|
const id = 'vsce';
|
|
5
5
|
const name = 'VSCE';
|
|
6
|
-
const icon = {
|
|
6
|
+
const icon = {
|
|
7
|
+
...icons['nf-md-microsoft_visual_studio_code'],
|
|
8
|
+
color: '#23A9F1',
|
|
9
|
+
};
|
|
7
10
|
const testCommand = 'vsce ls';
|
|
8
11
|
/**
|
|
9
12
|
* @internal
|
|
@@ -36,7 +39,8 @@ export const methodologyManifestVsce = function (tree, o) {
|
|
|
36
39
|
if (packageJson === undefined) {
|
|
37
40
|
throw new NoSourceError('package.json');
|
|
38
41
|
}
|
|
39
|
-
const packageJsonContent = o.modules.fs.readFileSync(packageJson.absolutePath)
|
|
42
|
+
const packageJsonContent = o.modules.fs.readFileSync(packageJson.absolutePath)
|
|
43
|
+
.toString();
|
|
40
44
|
let manifest;
|
|
41
45
|
try {
|
|
42
46
|
manifest = JSON.parse(packageJsonContent);
|
|
@@ -53,7 +57,11 @@ export const methodologyManifestVsce = function (tree, o) {
|
|
|
53
57
|
return git.methodologyGitignoreLike('.vscodeignore')(tree, o);
|
|
54
58
|
};
|
|
55
59
|
const bind = {
|
|
56
|
-
id,
|
|
60
|
+
id,
|
|
61
|
+
icon,
|
|
62
|
+
name,
|
|
63
|
+
testCommand,
|
|
64
|
+
scanOptions: {
|
|
57
65
|
target: methodologyManifestVsce,
|
|
58
66
|
},
|
|
59
67
|
};
|
|
@@ -9,8 +9,8 @@ const icon = { ...icons['nf-seti-yarn'], color: '#2E2A65' };
|
|
|
9
9
|
*/
|
|
10
10
|
export const matcherExclude = [
|
|
11
11
|
...npm.matcherExclude,
|
|
12
|
-
'
|
|
13
|
-
'
|
|
12
|
+
'**/.yarnignore',
|
|
13
|
+
'**/.yarnrc',
|
|
14
14
|
];
|
|
15
15
|
/**
|
|
16
16
|
* @internal
|
|
@@ -19,8 +19,14 @@ export const matcherInclude = [
|
|
|
19
19
|
...npm.matcherInclude,
|
|
20
20
|
];
|
|
21
21
|
const bind = {
|
|
22
|
-
id,
|
|
23
|
-
|
|
22
|
+
id,
|
|
23
|
+
icon,
|
|
24
|
+
name,
|
|
25
|
+
scanOptions: {
|
|
26
|
+
target: npm.methodologyManifestNpmLike(['package.json', '.yarnignore', '.npmignore', '.gitignore'], new ScannerGitignore({
|
|
27
|
+
exclude: matcherExclude,
|
|
28
|
+
include: matcherInclude,
|
|
29
|
+
})),
|
|
24
30
|
},
|
|
25
31
|
};
|
|
26
32
|
const yarn = { viewignored: { addTargets: [bind] } };
|
|
@@ -15,6 +15,7 @@ export type PatternScanner = Scanner & {
|
|
|
15
15
|
ignores(path: string, options?: PatternScannerOptions): boolean;
|
|
16
16
|
ignores(path: string, argument?: PatternScannerOptions | string | string[]): boolean;
|
|
17
17
|
};
|
|
18
|
+
export declare function ArrayPatternToString(pattern: string[] | string): string;
|
|
18
19
|
export declare class ScannerMinimatch implements PatternScanner {
|
|
19
20
|
negated: boolean;
|
|
20
21
|
protected _pattern: string | string[];
|
|
@@ -28,6 +29,7 @@ export declare class ScannerMinimatch implements PatternScanner {
|
|
|
28
29
|
set include(value: string | string[]);
|
|
29
30
|
constructor(options?: PatternScannerOptions);
|
|
30
31
|
isValid(value: unknown): value is string | string[];
|
|
32
|
+
private isMatch;
|
|
31
33
|
ignores(path: string, pattern: string | string[]): boolean;
|
|
32
34
|
ignores(path: string, options?: PatternScannerOptions): boolean;
|
|
33
35
|
}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as minimatch from 'minimatch';
|
|
2
2
|
import { gitignoreToMinimatch } from '@humanwhocodes/gitignore-to-minimatch';
|
|
3
|
+
import z from 'zod';
|
|
4
|
+
const { minimatch: isMatch, makeRe } = minimatch;
|
|
5
|
+
export function ArrayPatternToString(pattern) {
|
|
6
|
+
if (Array.isArray(pattern)) {
|
|
7
|
+
pattern = pattern.join('\n').trim();
|
|
8
|
+
}
|
|
9
|
+
return pattern.trim();
|
|
10
|
+
}
|
|
3
11
|
export class ScannerMinimatch {
|
|
4
12
|
negated;
|
|
5
13
|
_pattern;
|
|
@@ -30,46 +38,77 @@ export class ScannerMinimatch {
|
|
|
30
38
|
this.negated = options?.negated ?? false;
|
|
31
39
|
}
|
|
32
40
|
isValid(value) {
|
|
33
|
-
if (
|
|
34
|
-
return value.every(p => !Array.isArray(p) && this.isValid(value));
|
|
35
|
-
}
|
|
36
|
-
if (typeof value !== 'string') {
|
|
41
|
+
if (!z.string().or(z.array(z.string())).safeParse(value).success) {
|
|
37
42
|
return false;
|
|
38
43
|
}
|
|
44
|
+
const val = ArrayPatternToString(value);
|
|
45
|
+
if (val === '') {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
39
48
|
try {
|
|
40
|
-
|
|
49
|
+
makeRe(val);
|
|
41
50
|
return true;
|
|
42
51
|
}
|
|
43
52
|
catch {
|
|
44
53
|
return false;
|
|
45
54
|
}
|
|
46
55
|
}
|
|
56
|
+
isMatch(p, pattern, options) {
|
|
57
|
+
const patternList = pattern.split('\n');
|
|
58
|
+
const positiveList = [], negativeList = [];
|
|
59
|
+
for (const pat of patternList) {
|
|
60
|
+
if (pat[0] === '!') {
|
|
61
|
+
negativeList.push(pat.substring(1));
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
positiveList.push(pat);
|
|
65
|
+
}
|
|
66
|
+
for (const pat of negativeList) {
|
|
67
|
+
if (!isMatch(p, pat, options))
|
|
68
|
+
continue;
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
for (const pat of positiveList) {
|
|
72
|
+
if (!isMatch(p, pat, options))
|
|
73
|
+
continue;
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
47
78
|
ignores(path, argument) {
|
|
48
|
-
if (Array.isArray(argument)) {
|
|
49
|
-
argument = argument
|
|
79
|
+
if (Array.isArray(argument) || typeof argument === 'string') {
|
|
80
|
+
argument = ArrayPatternToString(argument);
|
|
50
81
|
}
|
|
82
|
+
const minimatchOptions = {
|
|
83
|
+
dot: true,
|
|
84
|
+
matchBase: true,
|
|
85
|
+
};
|
|
86
|
+
let check;
|
|
51
87
|
if (typeof argument === 'string') {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
return someMatch;
|
|
88
|
+
check = this.isMatch(path, argument, minimatchOptions);
|
|
89
|
+
return this.negated ? !check : check;
|
|
55
90
|
}
|
|
56
|
-
let
|
|
57
|
-
check = this.
|
|
91
|
+
let pattern = ArrayPatternToString(argument?.exclude ?? this.exclude);
|
|
92
|
+
check = this.isMatch(path, pattern, minimatchOptions);
|
|
58
93
|
if (check) {
|
|
59
94
|
return true;
|
|
60
95
|
}
|
|
61
|
-
|
|
96
|
+
pattern = ArrayPatternToString(argument?.include ?? this.include);
|
|
97
|
+
check = this.isMatch(path, pattern, minimatchOptions);
|
|
62
98
|
if (check) {
|
|
63
99
|
return false;
|
|
64
100
|
}
|
|
65
|
-
|
|
66
|
-
|
|
101
|
+
pattern = ArrayPatternToString(argument?.pattern ?? this.pattern);
|
|
102
|
+
const negated = argument?.negated ?? this.negated;
|
|
103
|
+
check = this.isMatch(path, pattern, minimatchOptions);
|
|
104
|
+
return negated ? !check : check;
|
|
67
105
|
}
|
|
68
106
|
}
|
|
69
107
|
export class ScannerGitignore extends ScannerMinimatch {
|
|
70
108
|
static gitignoreToMinimatch(argument) {
|
|
71
109
|
if (typeof argument === 'string') {
|
|
72
|
-
return ScannerGitignore.gitignoreToMinimatch(argument.split(/\r?\n/))
|
|
110
|
+
return ScannerGitignore.gitignoreToMinimatch(argument.split(/\r?\n/))
|
|
111
|
+
.join('\n');
|
|
73
112
|
}
|
|
74
113
|
return argument
|
|
75
114
|
.map(p => p.replaceAll(/(#.+$|(?<!\\) )/gm, ''))
|
|
@@ -89,15 +128,16 @@ export class ScannerGitignore extends ScannerMinimatch {
|
|
|
89
128
|
super(options);
|
|
90
129
|
}
|
|
91
130
|
isValid(value) {
|
|
92
|
-
if (
|
|
93
|
-
return value.every(p => !Array.isArray(p) || this.isValid(value));
|
|
94
|
-
}
|
|
95
|
-
if (typeof value !== 'string') {
|
|
131
|
+
if (!z.string().or(z.array(z.string())).safeParse(value).success) {
|
|
96
132
|
return false;
|
|
97
133
|
}
|
|
134
|
+
const val = ArrayPatternToString(value);
|
|
135
|
+
if (val === '') {
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
98
138
|
try {
|
|
99
|
-
const converted = ScannerGitignore.gitignoreToMinimatch(
|
|
100
|
-
|
|
139
|
+
const converted = ScannerGitignore.gitignoreToMinimatch(val);
|
|
140
|
+
makeRe(converted);
|
|
101
141
|
return true;
|
|
102
142
|
}
|
|
103
143
|
catch {
|
package/out/browser/filtering.js
CHANGED
|
@@ -6,5 +6,6 @@ export const filterNameList = ['ignored', 'included', 'all'];
|
|
|
6
6
|
* Checks if the value is the {@link FilterName}.
|
|
7
7
|
*/
|
|
8
8
|
export function isFilterName(value) {
|
|
9
|
-
return typeof value === 'string'
|
|
9
|
+
return typeof value === 'string'
|
|
10
|
+
&& filterNameList.includes(value);
|
|
10
11
|
}
|
|
@@ -119,7 +119,7 @@ export declare class Directory implements ParsedPath {
|
|
|
119
119
|
*/
|
|
120
120
|
toString(): string;
|
|
121
121
|
get<T extends string>(key: T): (T extends `${string}/` ? Directory : File) | undefined;
|
|
122
|
-
set<T extends string>(key: T, value:
|
|
122
|
+
set<T extends string>(key: T, value: T extends `${string}/` ? Directory : File): typeof this.children;
|
|
123
123
|
/**
|
|
124
124
|
* @returns The cache for each file of the directory with last time edited number.
|
|
125
125
|
* @see {@link modified}.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { join, parse, relative
|
|
1
|
+
import { join, parse, relative } from 'node:path';
|
|
2
2
|
import EventEmitter from 'node:events';
|
|
3
3
|
import * as FSP from 'node:fs/promises';
|
|
4
4
|
import process from 'node:process';
|
|
@@ -20,7 +20,10 @@ export class Directory {
|
|
|
20
20
|
*/
|
|
21
21
|
static async deepCount(directoryPath, options) {
|
|
22
22
|
const { modules, cwd, concurrency, progress = {
|
|
23
|
-
current: 0,
|
|
23
|
+
current: 0,
|
|
24
|
+
total: 0,
|
|
25
|
+
files: 0,
|
|
26
|
+
directories: 0,
|
|
24
27
|
}, } = options;
|
|
25
28
|
const limit = pLimit(concurrency);
|
|
26
29
|
const readdir = modules.fs.promises.readdir ?? FSP.readdir;
|
|
@@ -53,9 +56,15 @@ export class Directory {
|
|
|
53
56
|
});
|
|
54
57
|
});
|
|
55
58
|
controller.run = async function () {
|
|
56
|
-
const data = await Directory.deepStreamNested(directoryPath, {
|
|
59
|
+
const data = await Directory.deepStreamNested(directoryPath, {
|
|
60
|
+
...optionsReal,
|
|
61
|
+
controller,
|
|
62
|
+
});
|
|
57
63
|
const { progress, target } = data;
|
|
58
|
-
const dataRoot = {
|
|
64
|
+
const dataRoot = {
|
|
65
|
+
progress,
|
|
66
|
+
tree: target,
|
|
67
|
+
};
|
|
59
68
|
controller.emit('end', dataRoot);
|
|
60
69
|
return dataRoot;
|
|
61
70
|
};
|
|
@@ -111,8 +120,10 @@ export class Directory {
|
|
|
111
120
|
*/
|
|
112
121
|
static async deepStreamNested(directoryPath, options) {
|
|
113
122
|
const { modules, cwd, concurrency, parent } = options;
|
|
114
|
-
const controller = options.controller
|
|
115
|
-
|
|
123
|
+
const controller = options.controller
|
|
124
|
+
?? new EventEmitter();
|
|
125
|
+
const progress = options.progress
|
|
126
|
+
?? await Directory.deepCount(directoryPath, options);
|
|
116
127
|
controller.emit('progress', progress);
|
|
117
128
|
const limit = pLimit(concurrency);
|
|
118
129
|
const readdir = modules.fs.promises.readdir ?? FSP.readdir;
|
|
@@ -126,7 +137,10 @@ export class Directory {
|
|
|
126
137
|
const relativePath = modules.path.relative(cwd, absolutePath);
|
|
127
138
|
if (entry.isDirectory() && !entry.isSymbolicLink()) {
|
|
128
139
|
const data = await Directory.deepStreamNested(relativePath, {
|
|
129
|
-
...options,
|
|
140
|
+
...options,
|
|
141
|
+
controller,
|
|
142
|
+
progress,
|
|
143
|
+
parent,
|
|
130
144
|
});
|
|
131
145
|
++progress.current;
|
|
132
146
|
controller.emit('progress', progress);
|
|
@@ -42,19 +42,25 @@ export class FileInfo extends File {
|
|
|
42
42
|
* @returns Relative file path. Optionally formatted.
|
|
43
43
|
*/
|
|
44
44
|
toString(options) {
|
|
45
|
-
const { fileIcon, chalk, usePrefix = false, source: useSource = false, entire = true, posix = false } = options ?? {};
|
|
45
|
+
const { fileIcon, chalk, usePrefix = false, source: useSource = false, entire = true, posix = false, } = options ?? {};
|
|
46
46
|
const patha = posix ? PATH.posix : PATH;
|
|
47
47
|
const parsed = PATH.parse(this.relativePath);
|
|
48
48
|
const glyph = nf.Seti.fromParsedPath(parsed);
|
|
49
49
|
const fIcon = fileIcon
|
|
50
50
|
? decorCondition(fileIcon, {
|
|
51
51
|
ifEmoji: '📄',
|
|
52
|
-
ifNerd: chalk && glyph.color !== undefined
|
|
52
|
+
ifNerd: chalk && glyph.color !== undefined
|
|
53
|
+
? chalk.hex(glyph.color)(glyph.value)
|
|
54
|
+
: glyph.value,
|
|
53
55
|
postfix: ' ',
|
|
54
56
|
})
|
|
55
57
|
: '';
|
|
56
|
-
let prefix = usePrefix && this.status !== 'non-target'
|
|
57
|
-
|
|
58
|
+
let prefix = usePrefix && this.status !== 'non-target'
|
|
59
|
+
? (this.status === 'ignored' ? '!' : '+')
|
|
60
|
+
: '';
|
|
61
|
+
let postfix = useSource && this.source !== undefined
|
|
62
|
+
? ' < ' + this.source.toString()
|
|
63
|
+
: '';
|
|
58
64
|
if (chalk) {
|
|
59
65
|
prefix = chalk.dim(prefix);
|
|
60
66
|
postfix = chalk.dim(postfix);
|
|
@@ -64,7 +70,8 @@ export class FileInfo extends File {
|
|
|
64
70
|
if (entire) {
|
|
65
71
|
return fIcon + clr(prefix + this.relativePath + postfix);
|
|
66
72
|
}
|
|
67
|
-
return parsed.dir + patha.sep + fIcon
|
|
73
|
+
return parsed.dir + patha.sep + fIcon
|
|
74
|
+
+ clr(prefix + parsed.base + postfix);
|
|
68
75
|
}
|
|
69
76
|
if (entire) {
|
|
70
77
|
return prefix + this.relativePath + postfix;
|
package/out/browser/lib.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as PATH from 'node:path';
|
|
2
2
|
import * as FS from 'node:fs';
|
|
3
|
-
import { Directory, File, FileInfo, type
|
|
3
|
+
import { type DeepStreamEventEmitter, Directory, File, FileInfo, type SourceInfo } from './fs/index.js';
|
|
4
4
|
import { type FilterName } from './filtering.js';
|
|
5
5
|
export * from './errors.js';
|
|
6
6
|
export * from './fs/index.js';
|