view-ignored 0.4.3 → 0.4.5
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 +69 -20
- package/bin/viewig +0 -0
- package/out/browser/binds/index.js +16 -4
- package/out/browser/binds/plugins/git.js +8 -3
- package/out/browser/binds/plugins/jsr.js +28 -9
- 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 +8 -2
- package/out/browser/binds/scanner.js +14 -14
- 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/out/styling.js +2 -2
- package/out/test/directory.test.d.ts +1 -0
- package/out/test/scanner.test.d.ts +1 -0
- package/out/test/targets.test.d.ts +1 -0
- package/package.json +117 -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 v18 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,28 @@ viewig --help
|
|
|
31
46
|
view-ignored --help
|
|
32
47
|
|
|
33
48
|
# scan: git (default) and npm
|
|
34
|
-
viewig scan
|
|
35
|
-
viewig scan
|
|
36
|
-
viewig
|
|
49
|
+
viewig scan
|
|
50
|
+
viewig scan --target=npm
|
|
51
|
+
viewig sc -t npm
|
|
52
|
+
viewig scan --parsable
|
|
37
53
|
|
|
38
54
|
# scan: plugins (space, comma or pipe separated)
|
|
39
55
|
# all built-in plugins loaded automatically
|
|
40
|
-
|
|
41
|
-
viewig scan
|
|
42
|
-
viewig scan
|
|
43
|
-
viewig scan
|
|
56
|
+
# Replace example1/example2 with real plugin names
|
|
57
|
+
viewig scan --plugins="example1, example2"
|
|
58
|
+
viewig scan --plugins="example1 example2"
|
|
59
|
+
viewig scan --plugins example1 example2
|
|
60
|
+
viewig scan --plugins example1, example2
|
|
44
61
|
|
|
45
62
|
# config: print configuration entries
|
|
46
63
|
viewig config get
|
|
47
64
|
viewig config get --real
|
|
48
65
|
# config: set npm as default target and scan for npm
|
|
49
66
|
viewig config set target=npm
|
|
50
|
-
viewig scan
|
|
67
|
+
viewig scan
|
|
51
68
|
# config: always use nerdfonts
|
|
52
69
|
viewig config set style=tree
|
|
53
|
-
# config: always use
|
|
70
|
+
# config: always use Nerd Fonts for decoration
|
|
54
71
|
viewig config set decor=nerdfonts
|
|
55
72
|
# config: always use plugins
|
|
56
73
|
viewig config set plugins=example1,example2
|
|
@@ -58,7 +75,7 @@ viewig config set plugins=example1,example2
|
|
|
58
75
|
|
|
59
76
|
### Programmatically
|
|
60
77
|
|
|
61
|
-
|
|
78
|
+
To use programmatically:
|
|
62
79
|
|
|
63
80
|
```js
|
|
64
81
|
import * as vign from "view-ignored"; // or "view-ignored/browser"
|
|
@@ -68,12 +85,20 @@ await vign.Plugins.loadBuiltIns(); // load all built-in plugins
|
|
|
68
85
|
await vign.Plugins.loadPlugins(["example"]); // load third-party plugins
|
|
69
86
|
|
|
70
87
|
// scan - options available
|
|
71
|
-
const fileInfoList = await vign.scan(".", {
|
|
72
|
-
|
|
88
|
+
const fileInfoList = await vign.scan(".", {
|
|
89
|
+
target: "git",
|
|
90
|
+
cwd: process.cwd(),
|
|
91
|
+
});
|
|
92
|
+
const fileInfoList2 = await vign.scan(["./path/to/file"], {
|
|
93
|
+
target: "git",
|
|
94
|
+
cwd: process.cwd(),
|
|
95
|
+
});
|
|
73
96
|
|
|
74
97
|
// use results
|
|
75
|
-
|
|
98
|
+
for (const fileInfo of fileInfoList) {
|
|
99
|
+
if (fileInfo.ignored) {
|
|
76
100
|
superCodeEditor.explorer.colorFile(fileInfo.relativePath, "gray");
|
|
101
|
+
}
|
|
77
102
|
}
|
|
78
103
|
```
|
|
79
104
|
|
|
@@ -81,14 +106,38 @@ if (fileInfo.ignored) {
|
|
|
81
106
|
|
|
82
107
|
```js
|
|
83
108
|
const sorter = vign.Sorting.firstFolders;
|
|
84
|
-
const fileInfoList = await vign.scan(".", {target: "npm"});
|
|
85
|
-
const fileInfoSorted = fileInfoList.sort((a, b) =>
|
|
109
|
+
const fileInfoList = await vign.scan(".", { target: "npm" });
|
|
110
|
+
const fileInfoSorted = fileInfoList.sort((a, b) =>
|
|
111
|
+
sorter(String(a), String(b))
|
|
112
|
+
);
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
#### Plugin export example
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
const bind: Plugins.TargetBind = {
|
|
119
|
+
id,
|
|
120
|
+
icon,
|
|
121
|
+
name,
|
|
122
|
+
testCommand,
|
|
123
|
+
scanOptions: {
|
|
124
|
+
target: methodologyGitignoreLike(".gitignore"),
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
const git: Plugins.PluginExport = { viewignored: { addTargets: [bind] } };
|
|
128
|
+
export default git;
|
|
86
129
|
```
|
|
87
130
|
|
|
88
131
|
### Targets
|
|
89
132
|
|
|
133
|
+
The following built-in plugins are available:
|
|
134
|
+
|
|
90
135
|
- `git`
|
|
91
136
|
- `npm` (compatible with Bun, PNPM, and others)
|
|
92
137
|
- `yarn`
|
|
93
138
|
- `vsce`
|
|
94
139
|
- `jsr` (compatible with Deno)
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
MIT License. See [LICENSE.txt](LICENSE.txt) for details.
|
package/bin/viewig
CHANGED
|
File without changes
|
|
@@ -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,15 @@
|
|
|
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
|
+
import stripJsonComments from 'strip-json-comments';
|
|
6
7
|
const id = 'jsr';
|
|
7
8
|
const name = 'JSR';
|
|
8
|
-
const icon = {
|
|
9
|
+
const icon = {
|
|
10
|
+
...icons['nf-ple-pixelated_squares_big'],
|
|
11
|
+
color: '#F5DD1E',
|
|
12
|
+
};
|
|
9
13
|
/**
|
|
10
14
|
* @internal
|
|
11
15
|
*/
|
|
@@ -21,7 +25,10 @@ export function isValidManifestJsr(value) {
|
|
|
21
25
|
return z.object({
|
|
22
26
|
name: z.string(),
|
|
23
27
|
version: z.string(),
|
|
24
|
-
exports: z.
|
|
28
|
+
exports: z.union([
|
|
29
|
+
z.string(),
|
|
30
|
+
z.record(z.string(), z.string()),
|
|
31
|
+
]).optional(),
|
|
25
32
|
exclude: z.array(z.string()).optional(),
|
|
26
33
|
include: z.array(z.string()).optional(),
|
|
27
34
|
publish: z.object({
|
|
@@ -56,12 +63,17 @@ export const sourceSearch = (priority, scanner) => function (tree, o) {
|
|
|
56
63
|
continue;
|
|
57
64
|
}
|
|
58
65
|
if (/^(deno|jsr).jsonc?$/.test(sourceFile.base)) {
|
|
59
|
-
|
|
66
|
+
let manifestString = o.modules.fs.readFileSync(sourceFile.absolutePath).toString();
|
|
67
|
+
if (sourceFile.base[sourceFile.base.length - 1] === 'c') {
|
|
68
|
+
manifestString = stripJsonComments(manifestString, { whitespace: false, trailingCommas: false });
|
|
69
|
+
}
|
|
70
|
+
const manifest = JSON.parse(manifestString);
|
|
60
71
|
if (!isValidManifestJsr(manifest)) {
|
|
61
|
-
throw new BadSourceError(sourceFile, 'Must have \'name\', \'version\'.');
|
|
72
|
+
throw new BadSourceError(sourceFile, 'Must have \'name\', \'version\', valid \'export\', \'exclude\' and \'include\'.');
|
|
62
73
|
}
|
|
63
74
|
const { exclude, include, publish } = manifest;
|
|
64
|
-
if (exclude === undefined && include === undefined
|
|
75
|
+
if (exclude === undefined && include === undefined
|
|
76
|
+
&& publish === undefined) {
|
|
65
77
|
continue;
|
|
66
78
|
}
|
|
67
79
|
const pattern = publish?.include ?? include;
|
|
@@ -75,7 +87,8 @@ export const sourceSearch = (priority, scanner) => function (tree, o) {
|
|
|
75
87
|
}
|
|
76
88
|
}
|
|
77
89
|
else {
|
|
78
|
-
const content = o.modules.fs.readFileSync(sourceFile.absolutePath)
|
|
90
|
+
const content = o.modules.fs.readFileSync(sourceFile.absolutePath)
|
|
91
|
+
.toString();
|
|
79
92
|
const pattern = content;
|
|
80
93
|
if (!scanner.isValid(pattern)) {
|
|
81
94
|
throw new InvalidPatternError(sourceFile, pattern);
|
|
@@ -88,8 +101,14 @@ export const sourceSearch = (priority, scanner) => function (tree, o) {
|
|
|
88
101
|
return useChildren(tree, map, child => sourceSearch(priority, scanner)(child, o));
|
|
89
102
|
};
|
|
90
103
|
const bind = {
|
|
91
|
-
id,
|
|
92
|
-
|
|
104
|
+
id,
|
|
105
|
+
icon,
|
|
106
|
+
name,
|
|
107
|
+
scanOptions: {
|
|
108
|
+
target: sourceSearch(['deno.json', 'deno.jsonc', 'jsr.json', 'jsr.jsonc'], new ScannerGitignore({
|
|
109
|
+
exclude: matcherExclude,
|
|
110
|
+
include: matcherInclude,
|
|
111
|
+
})),
|
|
93
112
|
},
|
|
94
113
|
};
|
|
95
114
|
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
|
};
|
|
@@ -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] } };
|
|
@@ -55,20 +55,16 @@ export class ScannerMinimatch {
|
|
|
55
55
|
}
|
|
56
56
|
isMatch(p, pattern, options) {
|
|
57
57
|
const patternList = pattern.split('\n');
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
while (patternList.length) {
|
|
59
|
+
const pat = patternList.pop();
|
|
60
|
+
if (!/^[*/]$/.test(pat[pat.length - 1])) {
|
|
61
|
+
patternList.push(pat + '/**');
|
|
62
|
+
}
|
|
60
63
|
if (pat[0] === '!') {
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
if (!isMatch(p, pat.substring(1), options))
|
|
65
|
+
continue;
|
|
66
|
+
return false;
|
|
63
67
|
}
|
|
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
68
|
if (!isMatch(p, pat, options))
|
|
73
69
|
continue;
|
|
74
70
|
return true;
|
|
@@ -79,7 +75,10 @@ export class ScannerMinimatch {
|
|
|
79
75
|
if (Array.isArray(argument) || typeof argument === 'string') {
|
|
80
76
|
argument = ArrayPatternToString(argument);
|
|
81
77
|
}
|
|
82
|
-
const minimatchOptions = {
|
|
78
|
+
const minimatchOptions = {
|
|
79
|
+
dot: true,
|
|
80
|
+
matchBase: true,
|
|
81
|
+
};
|
|
83
82
|
let check;
|
|
84
83
|
if (typeof argument === 'string') {
|
|
85
84
|
check = this.isMatch(path, argument, minimatchOptions);
|
|
@@ -104,7 +103,8 @@ export class ScannerMinimatch {
|
|
|
104
103
|
export class ScannerGitignore extends ScannerMinimatch {
|
|
105
104
|
static gitignoreToMinimatch(argument) {
|
|
106
105
|
if (typeof argument === 'string') {
|
|
107
|
-
return ScannerGitignore.gitignoreToMinimatch(argument.split(/\r?\n/))
|
|
106
|
+
return ScannerGitignore.gitignoreToMinimatch(argument.split(/\r?\n/))
|
|
107
|
+
.join('\n');
|
|
108
108
|
}
|
|
109
109
|
return argument
|
|
110
110
|
.map(p => p.replaceAll(/(#.+$|(?<!\\) )/gm, ''))
|
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';
|
package/out/browser/sorting.js
CHANGED
|
@@ -2,7 +2,13 @@ import path from 'node:path';
|
|
|
2
2
|
/**
|
|
3
3
|
* Contains all file sort names.
|
|
4
4
|
*/
|
|
5
|
-
export const sortNameList = [
|
|
5
|
+
export const sortNameList = [
|
|
6
|
+
'firstFolders',
|
|
7
|
+
'firstFiles',
|
|
8
|
+
'type',
|
|
9
|
+
'mixed',
|
|
10
|
+
'modified',
|
|
11
|
+
];
|
|
6
12
|
/**
|
|
7
13
|
* Checks if the value is the {@link SortName}.
|
|
8
14
|
*/
|
package/out/browser/styling.d.ts
CHANGED
|
@@ -8,8 +8,8 @@ export type FormatFilesOptions = {
|
|
|
8
8
|
* resolved UNC forms, eg instead of `'C:\\foo\\bar'`, it would return
|
|
9
9
|
* `'//?/C:/foo/bar'`
|
|
10
10
|
* @default false
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
* @returns `/` delimited paths, even on Windows.
|
|
12
|
+
*/
|
|
13
13
|
posix?: boolean;
|
|
14
14
|
/**
|
|
15
15
|
* @default false
|
package/out/browser/styling.js
CHANGED
|
@@ -11,7 +11,11 @@ export function formatFiles(files, options) {
|
|
|
11
11
|
const patha = posix ? PATH.posix : PATH;
|
|
12
12
|
const isPaths = style === 'paths';
|
|
13
13
|
const paths = files.map(f => f.toString({
|
|
14
|
-
fileIcon: decor,
|
|
14
|
+
fileIcon: decor,
|
|
15
|
+
usePrefix: true,
|
|
16
|
+
chalk,
|
|
17
|
+
source: showSources,
|
|
18
|
+
entire: isPaths,
|
|
15
19
|
}));
|
|
16
20
|
if (isPaths) {
|
|
17
21
|
return paths.join('\n') + '\n';
|
|
@@ -29,7 +33,8 @@ export const styleNameList = ['tree', 'paths'];
|
|
|
29
33
|
* Checks if the value is the {@link StyleName}.
|
|
30
34
|
*/
|
|
31
35
|
export function isStyleName(value) {
|
|
32
|
-
return typeof value === 'string'
|
|
36
|
+
return typeof value === 'string'
|
|
37
|
+
&& styleNameList.includes(value);
|
|
33
38
|
}
|
|
34
39
|
/**
|
|
35
40
|
* Contains all decor names.
|
|
@@ -39,7 +44,8 @@ export const decorNameList = ['normal', 'emoji', 'nerdfonts'];
|
|
|
39
44
|
* Checks if the value is the {@link DecorName}.
|
|
40
45
|
*/
|
|
41
46
|
export function isDecorName(value) {
|
|
42
|
-
return typeof value === 'string'
|
|
47
|
+
return typeof value === 'string'
|
|
48
|
+
&& decorNameList.includes(value);
|
|
43
49
|
}
|
|
44
50
|
/**
|
|
45
51
|
* Formats the string for specific style types.
|
|
@@ -63,13 +69,13 @@ export function decorCondition(decor, condition) {
|
|
|
63
69
|
* Make a message in a red box. Or without color.
|
|
64
70
|
*/
|
|
65
71
|
export function boxError(message, options) {
|
|
66
|
-
let result =
|
|
72
|
+
let result = '\n' + boxen(message, {
|
|
67
73
|
titleAlignment: 'left',
|
|
68
74
|
padding: { left: 2, right: 2 },
|
|
69
75
|
borderColor: 'redBright',
|
|
70
76
|
borderStyle: 'round',
|
|
71
77
|
...options,
|
|
72
|
-
})
|
|
78
|
+
});
|
|
73
79
|
if (options?.noColor) {
|
|
74
80
|
result = stripVTControlCharacters(result);
|
|
75
81
|
}
|