view-ignored 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/README.md +23 -27
  2. package/bin/viewig +3 -1
  3. package/out/src/browser/binds/index.d.ts +40 -21
  4. package/out/src/browser/binds/index.js +62 -48
  5. package/out/src/browser/binds/plugins/git.d.ts +22 -3
  6. package/out/src/browser/binds/plugins/git.js +57 -21
  7. package/out/src/browser/binds/plugins/npm.d.ts +36 -9
  8. package/out/src/browser/binds/plugins/npm.js +125 -59
  9. package/out/src/browser/binds/plugins/vsce.d.ts +24 -8
  10. package/out/src/browser/binds/plugins/vsce.js +56 -16
  11. package/out/src/browser/binds/plugins/yarn.d.ts +5 -10
  12. package/out/src/browser/binds/plugins/yarn.js +18 -68
  13. package/out/src/browser/binds/scanner.d.ts +56 -0
  14. package/out/src/browser/binds/scanner.js +134 -0
  15. package/out/src/browser/binds/targets.d.ts +35 -11
  16. package/out/src/browser/binds/targets.js +10 -17
  17. package/out/src/browser/errors.d.ts +58 -7
  18. package/out/src/browser/errors.js +40 -12
  19. package/out/src/browser/filtering.d.ts +15 -0
  20. package/out/src/browser/filtering.js +12 -0
  21. package/out/src/browser/fs/directory.d.ts +181 -0
  22. package/out/src/browser/fs/directory.js +235 -0
  23. package/out/src/browser/{fileinfo.d.ts → fs/file-info.d.ts} +38 -27
  24. package/out/src/browser/fs/file-info.js +86 -0
  25. package/out/src/browser/fs/file.d.ts +41 -0
  26. package/out/src/browser/fs/file.js +43 -0
  27. package/out/src/browser/fs/index.d.ts +4 -0
  28. package/out/src/browser/fs/index.js +4 -0
  29. package/out/src/browser/fs/source-info.d.ts +29 -0
  30. package/out/src/browser/fs/source-info.js +31 -0
  31. package/out/src/browser/index.d.ts +2 -2
  32. package/out/src/browser/index.js +2 -2
  33. package/out/src/browser/lib.d.ts +102 -101
  34. package/out/src/browser/lib.js +86 -120
  35. package/out/src/browser/sorting.d.ts +22 -2
  36. package/out/src/browser/sorting.js +37 -32
  37. package/out/src/browser/styling.d.ts +41 -15
  38. package/out/src/browser/styling.js +28 -97
  39. package/out/src/cli.d.ts +73 -34
  40. package/out/src/cli.js +308 -155
  41. package/out/src/config.d.ts +163 -65
  42. package/out/src/config.js +285 -171
  43. package/out/src/errors.d.ts +7 -0
  44. package/out/src/errors.js +1 -0
  45. package/out/src/index.d.ts +2 -2
  46. package/out/src/index.js +2 -2
  47. package/out/src/lib.d.ts +4 -4
  48. package/out/src/lib.js +4 -4
  49. package/out/src/styling.d.ts +10 -4
  50. package/out/src/styling.js +46 -33
  51. package/package.json +37 -24
  52. package/out/src/bin.d.ts +0 -2
  53. package/out/src/bin.js +0 -3
  54. package/out/src/browser/fileinfo.js +0 -78
  55. package/out/src/browser/scanner.d.ts +0 -103
  56. package/out/src/browser/scanner.js +0 -161
  57. package/out/src/browser/sourceinfo.d.ts +0 -62
  58. package/out/src/browser/sourceinfo.js +0 -107
@@ -1,71 +1,137 @@
1
- import getValue from "get-value";
2
- export const id = "npm";
3
- export const name = "NPM";
4
- export const testCommand = "npm pack --dry-run";
1
+ import { icons } from '@m234/nerd-fonts';
2
+ import { Directory, InvalidPatternError, BadSourceError, NoSourceError, } from '../../index.js';
3
+ import { ScannerGitignore } from '../scanner.js';
4
+ import * as git from './git.js';
5
+ const id = 'npm';
6
+ const name = 'NPM';
7
+ const icon = { ...icons['nf-seti-npm'], color: 0xCA_04_04 };
8
+ const testCommand = 'npm pack --dry-run';
9
+ /**
10
+ * @private
11
+ */
5
12
  export const matcherExclude = [
6
- 'node_modules/**',
7
- '.*.swp',
8
- '._*',
9
- '.DS_Store/**',
10
- '.git/**',
11
- '.gitignore',
12
- '.hg/**',
13
- '.npmignore',
14
- '.npmrc',
15
- '.lock-wscript',
16
- '.svn/**',
17
- '.wafpickle-*',
18
- 'config.gypi',
19
- 'CVS/**',
20
- 'npm-debug.log',
13
+ ...git.matcherExclude,
14
+ '**/node_modules/**',
15
+ '**/.*.swp',
16
+ '**/._*',
17
+ '**/.DS_Store/**',
18
+ '**/.git/**',
19
+ '**/.gitignore',
20
+ '**/.hg/**',
21
+ '**/.npmignore',
22
+ '**/.npmrc',
23
+ '**/.lock-wscript',
24
+ '**/.svn/**',
25
+ '**/.wafpickle-*',
26
+ '**/config.gypi',
27
+ '**/CVS/**',
28
+ '**/npm-debug.log',
21
29
  ];
30
+ /**
31
+ * @private
32
+ */
22
33
  export const matcherInclude = [
23
- '/bin/',
24
- '/package.json',
25
- '/README',
26
- '/README.*',
27
- '/LICENSE',
28
- '/LICENSE.*',
29
- '/LICENCE',
30
- '/LICENCE.*',
34
+ 'bin/**',
35
+ 'package.json',
36
+ 'README*',
37
+ 'LICENSE*',
38
+ 'LICENCE*',
31
39
  ];
32
- export const scanGit = function (data) {
33
- const { scanner, content } = data;
34
- const pat = content?.toString();
35
- if (!scanner.patternIsValid(pat)) {
40
+ /**
41
+ * @private
42
+ */
43
+ export function isValidManifest(value) {
44
+ if (value?.constructor !== Object) {
36
45
  return false;
37
46
  }
38
- scanner.add(pat);
39
- return true;
40
- };
41
- export const scanPackageJsonFiles = function (data) {
42
- const { scanner, content } = data;
43
- let parsed;
44
- try {
45
- const pat = content?.toString();
46
- if (!pat) {
47
- return false;
47
+ const value_ = value;
48
+ return ('name' in value_ && typeof value_.name === 'string')
49
+ && ('version' in value_ && typeof value_.version === 'string')
50
+ && (value_.files === undefined || (Array.isArray(value_.files) && value_.files.every(element => typeof element === 'string')));
51
+ }
52
+ /**
53
+ * @private
54
+ */
55
+ export function useChildren(tree, map, getMap) {
56
+ for (const child of Array.from(tree.children.values())) {
57
+ if (!(child instanceof Directory)) {
58
+ continue;
48
59
  }
49
- const json = JSON.parse(pat);
50
- if (json?.constructor !== Object) {
51
- return false;
60
+ const submap = getMap(child);
61
+ for (const [key, value] of submap.entries()) {
62
+ map.set(key, value);
52
63
  }
53
- parsed = json;
54
64
  }
55
- catch {
56
- return false;
65
+ return map;
66
+ }
67
+ /**
68
+ * @private
69
+ */
70
+ export const sourceSearch = (priority, scanner) => function (tree, o) {
71
+ const map = new Map();
72
+ for (const element of priority) {
73
+ const sourceFile = tree.get(element);
74
+ if (sourceFile === undefined) {
75
+ continue;
76
+ }
77
+ if (sourceFile.base === 'package.json') {
78
+ const manifest = JSON.parse(o.modules.fs.readFileSync(sourceFile.absolutePath).toString());
79
+ if (!isValidManifest(manifest)) {
80
+ throw new BadSourceError(sourceFile, 'Must have \'name\', \'version\' and \'files\'.');
81
+ }
82
+ const { files: pattern } = manifest;
83
+ if (pattern === undefined) {
84
+ continue;
85
+ }
86
+ if (!scanner.isValid(pattern)) {
87
+ throw new BadSourceError(sourceFile, `Invalid pattern, got ${JSON.stringify(pattern)}`);
88
+ }
89
+ scanner.negated = true;
90
+ scanner.pattern = pattern;
91
+ }
92
+ else {
93
+ const content = o.modules.fs.readFileSync(sourceFile.absolutePath).toString();
94
+ const pattern = content;
95
+ if (!scanner.isValid(pattern)) {
96
+ throw new InvalidPatternError(sourceFile, pattern);
97
+ }
98
+ scanner.negated = false;
99
+ scanner.pattern = pattern;
100
+ }
101
+ return git.useSourceFile(map, sourceFile, scanner);
57
102
  }
58
- const propVal = getValue(parsed, "files");
59
- if (!scanner.patternIsValid(propVal)) {
60
- return false;
103
+ return useChildren(tree, map, child => sourceSearch(priority, scanner)(child, o));
104
+ };
105
+ /**
106
+ * @param priority The list of file names from highest to lowest priority.
107
+ * @param scanner The pattern scanner.
108
+ * @private
109
+ */
110
+ export const methodologyManifestNpmLike = (priority, scanner) => function (tree, o) {
111
+ const packageJson = tree.get('package.json');
112
+ if (packageJson === undefined) {
113
+ throw new NoSourceError('\'package.json\' in the root');
61
114
  }
62
- scanner.add(propVal);
63
- return true;
115
+ const packageJsonContent = o.modules.fs.readFileSync(packageJson.absolutePath).toString();
116
+ let manifest;
117
+ try {
118
+ manifest = JSON.parse(packageJsonContent);
119
+ }
120
+ catch (error) {
121
+ if (error instanceof Error) {
122
+ throw new BadSourceError(packageJson, error.message);
123
+ }
124
+ throw error;
125
+ }
126
+ if (!isValidManifest(manifest)) {
127
+ throw new BadSourceError(packageJson, 'Must have \'name\', \'version\' and \'files\'.');
128
+ }
129
+ return sourceSearch(priority, scanner)(tree, o);
64
130
  };
65
- export const methodology = [
66
- { pattern: ["**/package.json"], matcherNegated: true, matcher: "gitignore", scan: scanPackageJsonFiles, matcherInclude, matcherExclude },
67
- { pattern: ["**/.npmignore"], matcher: "gitignore", scan: scanGit, matcherInclude, matcherExclude },
68
- { pattern: ["**/.gitignore"], matcher: "gitignore", scan: scanGit, matcherInclude, matcherExclude },
69
- ];
70
- const bind = { id, name, methodology, testCommand };
71
- export default { viewignored: { addTargets: [bind] } };
131
+ const bind = {
132
+ id, icon, name, testCommand, scanOptions: {
133
+ target: methodologyManifestNpmLike(['package.json', '.npmignore', '.gitignore'], new ScannerGitignore({ exclude: matcherExclude, include: matcherInclude })),
134
+ },
135
+ };
136
+ const npm = { viewignored: { addTargets: [bind] } };
137
+ export default npm;
@@ -1,9 +1,25 @@
1
- import { Plugins, ScanMethod, Methodology } from "../../index.js";
2
- export declare const id = "vsce";
3
- export declare const name = "VSC Extension";
4
- export declare const testCommand = "vsce ls";
1
+ import { type Plugins, type Methodology } from '../../index.js';
2
+ /**
3
+ * @private
4
+ */
5
5
  export declare const matcherExclude: string[];
6
- export declare const scan: ScanMethod;
7
- export declare const methodology: Methodology[];
8
- declare const _default: Plugins.PluginExport;
9
- export default _default;
6
+ /**
7
+ * @private
8
+ */
9
+ export type ValidManifestVsce = {
10
+ name: string;
11
+ version: string;
12
+ engines: {
13
+ vscode: string;
14
+ };
15
+ };
16
+ /**
17
+ * @private
18
+ */
19
+ export declare function isValidManifest(value: unknown): value is ValidManifestVsce;
20
+ /**
21
+ * @private
22
+ */
23
+ export declare const methodologyManifestVsce: Methodology;
24
+ declare const vsce: Plugins.PluginExport;
25
+ export default vsce;
@@ -1,21 +1,61 @@
1
- export const id = "vsce";
2
- export const name = "VSC Extension";
3
- export const testCommand = "vsce ls";
1
+ import { icons } from '@m234/nerd-fonts';
2
+ import { NoSourceError, File, BadSourceError, } from '../../index.js';
3
+ import * as git from './git.js';
4
+ const id = 'vsce';
5
+ const name = 'VSCE';
6
+ const icon = { ...icons['nf-md-microsoft_visual_studio_code'], color: 0x23_A9_F1 };
7
+ const testCommand = 'vsce ls';
8
+ /**
9
+ * @private
10
+ */
4
11
  export const matcherExclude = [
5
- ".git/**",
6
- ".DS_Store/**"
12
+ ...git.matcherExclude,
7
13
  ];
8
- export const scan = function (data) {
9
- const { scanner, content } = data;
10
- const pat = content?.toString();
11
- if (!scanner.patternIsValid(pat)) {
14
+ /**
15
+ * @private
16
+ */
17
+ export function isValidManifest(value) {
18
+ if (value?.constructor !== Object) {
12
19
  return false;
13
20
  }
14
- scanner.add(pat);
15
- return true;
21
+ const value_ = value;
22
+ const isManifestBase = ('name' in value_ && typeof value_.name === 'string')
23
+ && ('version' in value_ && typeof value_.version === 'string')
24
+ && ('engines' in value_ && value_.engines?.constructor === Object);
25
+ if (!isManifestBase) {
26
+ return false;
27
+ }
28
+ const { engines } = value;
29
+ return 'vscode' in engines && typeof engines.vscode === 'string';
30
+ }
31
+ /**
32
+ * @private
33
+ */
34
+ export const methodologyManifestVsce = function (tree, o) {
35
+ const packageJson = Array.from(tree.deepIterator()).find(dirent => dirent instanceof File && dirent.base === 'package.json');
36
+ if (packageJson === undefined) {
37
+ throw new NoSourceError('package.json');
38
+ }
39
+ const packageJsonContent = o.modules.fs.readFileSync(packageJson.absolutePath).toString();
40
+ let manifest;
41
+ try {
42
+ manifest = JSON.parse(packageJsonContent);
43
+ }
44
+ catch (error) {
45
+ if (error instanceof Error) {
46
+ throw new BadSourceError(packageJson, error.message);
47
+ }
48
+ throw error;
49
+ }
50
+ if (!isValidManifest(manifest)) {
51
+ throw new BadSourceError(packageJson, 'Must have name, version and engines->vscode.');
52
+ }
53
+ return git.methodologyGitignoreLike('.vscodeignore')(tree, o);
16
54
  };
17
- export const methodology = [
18
- { pattern: "**/.vscodeignore", matcher: "minimatch", scan, matcherExclude },
19
- ];
20
- const bind = { id, name, methodology, testCommand };
21
- export default { viewignored: { addTargets: [bind] } };
55
+ const bind = {
56
+ id, icon, name, testCommand, scanOptions: {
57
+ target: methodologyManifestVsce,
58
+ },
59
+ };
60
+ const vsce = { viewignored: { addTargets: [bind] } };
61
+ export default vsce;
@@ -1,16 +1,11 @@
1
- import { Plugins, Methodology, ScanMethod } from "../../index.js";
2
- export declare const id = "yarn";
3
- export declare const name = "Yarn";
1
+ import { type Plugins } from '../../index.js';
4
2
  /**
5
- * [!WARNING] All patterns copied from npm plugin, so they should be verified with yarn docs.
3
+ * @private
6
4
  */
7
5
  export declare const matcherExclude: string[];
8
6
  /**
9
- * [!WARNING] All patterns copied from npm plugin, so they should be verified with yarn docs.
7
+ * @private
10
8
  */
11
9
  export declare const matcherInclude: string[];
12
- export declare const scanGit: ScanMethod;
13
- export declare const scanPackageJsonFiles: ScanMethod;
14
- export declare const methodology: Methodology[];
15
- declare const _default: Plugins.PluginExport;
16
- export default _default;
10
+ declare const yarn: Plugins.PluginExport;
11
+ export default yarn;
@@ -1,78 +1,28 @@
1
- import getValue from "get-value";
2
- export const id = "yarn";
3
- export const name = "Yarn";
1
+ import { icons } from '@m234/nerd-fonts';
2
+ import { ScannerGitignore } from '../scanner.js';
3
+ import * as npm from './npm.js';
4
+ const id = 'yarn';
5
+ const name = 'Yarn';
6
+ const icon = { ...icons['nf-seti-yarn'], color: 0x2E_2A_65 };
7
+ // FIXME: Yarn can all this stuff another way.
4
8
  /**
5
- * [!WARNING] All patterns copied from npm plugin, so they should be verified with yarn docs.
9
+ * @private
6
10
  */
7
11
  export const matcherExclude = [
8
- 'node_modules/**',
9
- '.*.swp',
10
- '._*',
11
- '.DS_Store/**',
12
- '.git/**',
13
- '.gitignore',
14
- '.hg/**',
12
+ ...npm.matcherExclude,
15
13
  '.yarnignore',
16
- '.npmignore',
17
- '.npmrc',
18
- '.lock-wscript',
19
- '.svn/**',
20
- '.wafpickle-*',
21
- 'config.gypi',
22
- 'CVS/**',
23
- 'npm-debug.log',
14
+ '.yarnrc',
24
15
  ];
25
16
  /**
26
- * [!WARNING] All patterns copied from npm plugin, so they should be verified with yarn docs.
17
+ * @private
27
18
  */
28
19
  export const matcherInclude = [
29
- '/bin/',
30
- '/package.json',
31
- '/README',
32
- '/README.*',
33
- '/LICENSE',
34
- '/LICENSE.*',
35
- '/LICENCE',
36
- '/LICENCE.*',
20
+ ...npm.matcherInclude,
37
21
  ];
38
- export const scanGit = function (data) {
39
- const { scanner, content } = data;
40
- const pat = content?.toString();
41
- if (!scanner.patternIsValid(pat)) {
42
- return false;
43
- }
44
- scanner.add(pat);
45
- return true;
22
+ const bind = {
23
+ id, icon, name, scanOptions: {
24
+ target: npm.methodologyManifestNpmLike(['package.json', '.yarnignore', '.npmignore', '.gitignore'], new ScannerGitignore({ exclude: matcherExclude, include: matcherInclude })),
25
+ },
46
26
  };
47
- export const scanPackageJsonFiles = function (data) {
48
- const { scanner, content } = data;
49
- let parsed;
50
- try {
51
- const pat = content?.toString();
52
- if (!pat) {
53
- return false;
54
- }
55
- const json = JSON.parse(pat);
56
- if (json?.constructor !== Object) {
57
- return false;
58
- }
59
- parsed = json;
60
- }
61
- catch {
62
- return false;
63
- }
64
- const propVal = getValue(parsed, "files");
65
- if (!scanner.patternIsValid(propVal)) {
66
- return false;
67
- }
68
- scanner.add(propVal);
69
- return true;
70
- };
71
- export const methodology = [
72
- { pattern: "**/package.json", matcherNegated: true, matcher: "gitignore", scan: scanPackageJsonFiles, matcherInclude, matcherExclude },
73
- { pattern: "**/.yarnignore", matcher: "gitignore", scan: scanGit, matcherInclude, matcherExclude },
74
- { pattern: "**/.npmignore", matcher: "gitignore", scan: scanGit, matcherInclude, matcherExclude },
75
- { pattern: "**/.gitignore", matcher: "gitignore", scan: scanGit, matcherInclude, matcherExclude },
76
- ];
77
- const bind = { id, name, methodology };
78
- export default { viewignored: { addTargets: [bind] } };
27
+ const yarn = { viewignored: { addTargets: [bind] } };
28
+ export default yarn;
@@ -0,0 +1,56 @@
1
+ import { type Scanner } from '../lib.js';
2
+ /**
3
+ * @public
4
+ */
5
+ export type PatternScannerOptions = {
6
+ pattern?: string | string[];
7
+ exclude?: string | string[];
8
+ include?: string | string[];
9
+ negated?: boolean;
10
+ };
11
+ /**
12
+ * @public
13
+ */
14
+ export type PatternScanner = Scanner & {
15
+ pattern: string | string[];
16
+ exclude: string | string[];
17
+ include: string | string[];
18
+ negated: boolean;
19
+ isValid(value: unknown): value is string | string[];
20
+ ignores(path: string, pattern: string | string[]): boolean;
21
+ ignores(path: string, options?: PatternScannerOptions): boolean;
22
+ ignores(path: string, argument?: PatternScannerOptions | string | string[]): boolean;
23
+ };
24
+ /**
25
+ * @public
26
+ */
27
+ export declare class ScannerMinimatch implements PatternScanner {
28
+ negated: boolean;
29
+ protected _pattern: string | string[];
30
+ get pattern(): string | string[];
31
+ set pattern(value: string | string[]);
32
+ protected _exclude: string | string[];
33
+ get exclude(): string | string[];
34
+ set exclude(value: string | string[]);
35
+ protected _include: string | string[];
36
+ get include(): string | string[];
37
+ set include(value: string | string[]);
38
+ constructor(options?: PatternScannerOptions);
39
+ isValid(value: unknown): value is string | string[];
40
+ ignores(path: string, pattern: string | string[]): boolean;
41
+ ignores(path: string, options?: PatternScannerOptions): boolean;
42
+ }
43
+ /**
44
+ * @public
45
+ */
46
+ export declare class ScannerGitignore extends ScannerMinimatch {
47
+ private static gitignoreToMinimatch;
48
+ constructor(options?: PatternScannerOptions);
49
+ isValid(value: unknown): value is string | string[];
50
+ get pattern(): string | string[];
51
+ set pattern(value: string | string[]);
52
+ get include(): string | string[];
53
+ set include(value: string | string[]);
54
+ get exclude(): string | string[];
55
+ set exclude(value: string | string[]);
56
+ }
@@ -0,0 +1,134 @@
1
+ import { minimatch } from 'minimatch';
2
+ import { gitignoreToMinimatch } from '@humanwhocodes/gitignore-to-minimatch';
3
+ /**
4
+ * @public
5
+ */
6
+ export class ScannerMinimatch {
7
+ negated;
8
+ _pattern;
9
+ get pattern() {
10
+ return this.pattern;
11
+ }
12
+ set pattern(value) {
13
+ this._pattern = value;
14
+ }
15
+ _exclude;
16
+ get exclude() {
17
+ return this._exclude;
18
+ }
19
+ set exclude(value) {
20
+ this._exclude = value;
21
+ }
22
+ _include;
23
+ get include() {
24
+ return this._include;
25
+ }
26
+ set include(value) {
27
+ this._include = value;
28
+ }
29
+ constructor(options) {
30
+ this._pattern = options?.pattern ?? [];
31
+ this._exclude = options?.exclude ?? [];
32
+ this._include = options?.include ?? [];
33
+ this.negated = options?.negated ?? false;
34
+ }
35
+ isValid(value) {
36
+ if (Array.isArray(value)) {
37
+ return value.every(p => !Array.isArray(p) && this.isValid(value));
38
+ }
39
+ if (typeof value !== 'string') {
40
+ return false;
41
+ }
42
+ try {
43
+ minimatch.makeRe(value);
44
+ return true;
45
+ }
46
+ catch {
47
+ return false;
48
+ }
49
+ }
50
+ ignores(path, argument) {
51
+ if (Array.isArray(argument)) {
52
+ argument = argument.join('\n');
53
+ }
54
+ if (typeof argument === 'string') {
55
+ const patternList = argument.split(/\r?\n/);
56
+ const someMatch = patternList.some(pattern => minimatch(path, pattern, { dot: true, matchBase: true }));
57
+ return someMatch;
58
+ }
59
+ let check;
60
+ check = this.ignores(path, argument?.exclude ?? this.exclude);
61
+ if (check) {
62
+ return true;
63
+ }
64
+ check = this.ignores(path, argument?.include ?? this.include);
65
+ if (check) {
66
+ return false;
67
+ }
68
+ check = this.ignores(path, argument?.pattern ?? this.pattern);
69
+ return (argument?.negated ?? this.negated) ? !check : check;
70
+ }
71
+ }
72
+ /**
73
+ * @public
74
+ */
75
+ export class ScannerGitignore extends ScannerMinimatch {
76
+ static gitignoreToMinimatch(argument) {
77
+ if (typeof argument === 'string') {
78
+ return ScannerGitignore.gitignoreToMinimatch(argument.split(/\r?\n/)).join('\n');
79
+ }
80
+ return argument
81
+ .map(p => p.replaceAll(/(#.+$|(?<!\\) )/gm, ''))
82
+ .filter(s => s !== '')
83
+ .map(p => gitignoreToMinimatch(p));
84
+ }
85
+ constructor(options) {
86
+ const newOptions = { ...options };
87
+ for (const key of ['pattern', 'exclude', 'include']) {
88
+ const value = newOptions[key];
89
+ if (!Object.hasOwn(newOptions, key) || value === undefined) {
90
+ continue;
91
+ }
92
+ const newPattern = ScannerGitignore.gitignoreToMinimatch(value);
93
+ newOptions[key] = newPattern;
94
+ }
95
+ super(options);
96
+ }
97
+ isValid(value) {
98
+ if (Array.isArray(value)) {
99
+ return value.every(p => !Array.isArray(p) || this.isValid(value));
100
+ }
101
+ if (typeof value !== 'string') {
102
+ return false;
103
+ }
104
+ try {
105
+ const converted = ScannerGitignore.gitignoreToMinimatch(value);
106
+ minimatch.makeRe(converted);
107
+ return true;
108
+ }
109
+ catch {
110
+ return false;
111
+ }
112
+ }
113
+ get pattern() {
114
+ return this._pattern;
115
+ }
116
+ set pattern(value) {
117
+ const newPattern = ScannerGitignore.gitignoreToMinimatch(value);
118
+ this._pattern = newPattern;
119
+ }
120
+ get include() {
121
+ return this._include;
122
+ }
123
+ set include(value) {
124
+ const newPattern = ScannerGitignore.gitignoreToMinimatch(value);
125
+ this._include = newPattern;
126
+ }
127
+ get exclude() {
128
+ return this._exclude;
129
+ }
130
+ set exclude(value) {
131
+ const newPattern = ScannerGitignore.gitignoreToMinimatch(value);
132
+ this._exclude = newPattern;
133
+ }
134
+ }