view-ignored 0.5.1 → 0.6.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 (69) hide show
  1. package/README.md +98 -41
  2. package/out/browser.d.ts +3 -0
  3. package/out/browser.js +2 -0
  4. package/out/browser_scan.d.ts +20 -0
  5. package/out/browser_scan.js +54 -0
  6. package/out/browser_stream.d.ts +12 -0
  7. package/out/browser_stream.js +46 -0
  8. package/out/getDepth.d.ts +4 -0
  9. package/out/getDepth.js +21 -0
  10. package/out/index.d.ts +3 -1
  11. package/out/index.js +2 -1
  12. package/out/normalizeCwd.d.ts +1 -0
  13. package/out/normalizeCwd.js +4 -0
  14. package/out/opendir.d.ts +3 -0
  15. package/out/opendir.js +18 -0
  16. package/out/patterns/extractor.d.ts +80 -0
  17. package/out/patterns/extractor.js +1 -0
  18. package/out/patterns/gitignore.d.ts +9 -3
  19. package/out/patterns/gitignore.js +14 -25
  20. package/out/patterns/ignores.d.ts +19 -0
  21. package/out/patterns/ignores.js +1 -0
  22. package/out/patterns/index.d.ts +13 -4
  23. package/out/patterns/index.js +13 -4
  24. package/out/patterns/jsrjson.d.ts +16 -4
  25. package/out/patterns/jsrjson.js +30 -13
  26. package/out/patterns/matcherContext.d.ts +71 -0
  27. package/out/patterns/matcherContext.js +1 -0
  28. package/out/patterns/matcherContextPatch.d.ts +16 -0
  29. package/out/patterns/matcherContextPatch.js +151 -0
  30. package/out/patterns/matcherStream.d.ts +64 -0
  31. package/out/patterns/matcherStream.js +9 -0
  32. package/out/patterns/packagejson.d.ts +9 -3
  33. package/out/patterns/packagejson.js +20 -13
  34. package/out/patterns/pattern.d.ts +44 -0
  35. package/out/patterns/pattern.js +21 -0
  36. package/out/patterns/patternMatcher.d.ts +23 -0
  37. package/out/patterns/patternMatcher.js +1 -0
  38. package/out/patterns/resolveSources.d.ts +34 -0
  39. package/out/patterns/resolveSources.js +142 -0
  40. package/out/patterns/signedPattern.d.ts +117 -0
  41. package/out/patterns/signedPattern.js +110 -0
  42. package/out/patterns/source.d.ts +57 -0
  43. package/out/patterns/source.js +20 -0
  44. package/out/patterns/stringCompile.d.ts +9 -0
  45. package/out/patterns/stringCompile.js +28 -0
  46. package/out/scan.d.ts +5 -37
  47. package/out/scan.js +8 -102
  48. package/out/stream.d.ts +9 -0
  49. package/out/stream.js +12 -0
  50. package/out/targets/git.d.ts +4 -1
  51. package/out/targets/git.js +26 -17
  52. package/out/targets/index.d.ts +6 -6
  53. package/out/targets/index.js +6 -6
  54. package/out/targets/jsr.d.ts +4 -1
  55. package/out/targets/jsr.js +34 -20
  56. package/out/targets/npm.d.ts +4 -1
  57. package/out/targets/npm.js +47 -40
  58. package/out/targets/target.d.ts +17 -3
  59. package/out/targets/vsce.d.ts +4 -1
  60. package/out/targets/vsce.js +30 -19
  61. package/out/targets/yarn.d.ts +4 -1
  62. package/out/targets/yarn.js +53 -43
  63. package/out/types.d.ts +116 -0
  64. package/out/types.js +1 -0
  65. package/out/walk.d.ts +11 -2
  66. package/out/walk.js +101 -13
  67. package/package.json +113 -78
  68. package/out/patterns/matcher.d.ts +0 -102
  69. package/out/patterns/matcher.js +0 -125
@@ -1,18 +1,28 @@
1
- import { type } from 'arktype';
2
- import stripJsonComments from 'strip-json-comments';
1
+ import { type } from "arktype";
2
+ import stripJsonComments from "strip-json-comments";
3
+ import { signedPatternCompile } from "./resolveSources.js";
3
4
  const jsrManifest = type({
4
- exclude: 'string[]?',
5
- include: 'string[]?',
6
- publish: {
7
- exclude: 'string[]?',
8
- include: 'string[]?',
5
+ exclude: "string[]?",
6
+ include: "string[]?",
7
+ "publish?": {
8
+ exclude: "string[]?",
9
+ include: "string[]?",
9
10
  },
10
11
  });
11
- const parse = jsrManifest.pipe((s) => JSON.parse(s));
12
- export function extractJsrJson(source, content) {
12
+ const parse = type("string")
13
+ .pipe((s) => JSON.parse(s))
14
+ .pipe(jsrManifest);
15
+ /**
16
+ * Extracts and compiles patterns from the file.
17
+ *
18
+ * @since 0.0.6
19
+ */
20
+ export function extractJsrJson(source, content, ctx) {
13
21
  const dist = parse(content.toString());
14
22
  if (dist instanceof type.errors) {
15
- return dist;
23
+ source.error = new Error("Invalid '" + source.path + "': " + dist.summary, { cause: dist });
24
+ ctx.failed.push(source);
25
+ return;
16
26
  }
17
27
  if (!dist.publish) {
18
28
  if (dist.exclude) {
@@ -30,10 +40,17 @@ export function extractJsrJson(source, content) {
30
40
  else if (dist.publish.include) {
31
41
  source.pattern.include.push(...dist.publish.include);
32
42
  }
33
- return;
43
+ signedPatternCompile(source.pattern);
34
44
  }
35
45
  extractJsrJson;
36
- export function extractJsrJsonc(source, content) {
37
- return extractJsrJson(source, Buffer.from(stripJsonComments(content.toString())));
46
+ /**
47
+ * Extracts and compiles patterns from the file.
48
+ *
49
+ * @see {@link signedPatternCompile}
50
+ *
51
+ * @since 0.0.6
52
+ */
53
+ export function extractJsrJsonc(source, content, ctx) {
54
+ extractJsrJson(source, Buffer.from(stripJsonComments(content.toString())), ctx);
38
55
  }
39
56
  extractJsrJsonc;
@@ -0,0 +1,71 @@
1
+ import type { SignedPatternMatch } from "./signedPattern.js";
2
+ import type { Source } from "./source.js";
3
+ /**
4
+ * Post-scan results.
5
+ *
6
+ * @since 0.0.6
7
+ */
8
+ export interface MatcherContext {
9
+ /**
10
+ * Paths and their corresponding sources.
11
+ * Directory paths are having the slash suffix.
12
+ *
13
+ * @since 0.0.6
14
+ */
15
+ paths: Map<string, SignedPatternMatch>;
16
+ /**
17
+ * Maps directory paths to their corresponding sources.
18
+ *
19
+ * @example
20
+ * "dir" => Source
21
+ * "dir/subdir" => Source
22
+ *
23
+ * @since 0.0.6
24
+ */
25
+ external: Map<string, Source | "none">;
26
+ /**
27
+ * If any fatal errors were encountered during source extractions,
28
+ * this property will contain an array of failed sources.
29
+ *
30
+ * @since 0.0.6
31
+ */
32
+ failed: Source[];
33
+ /**
34
+ * Maps directory paths to the quantity of files they contain.
35
+ *
36
+ * @example
37
+ * // for
38
+ * "src/"
39
+ * "src/components/"
40
+ * "src/views/"
41
+ * "src/views/index.html"
42
+ *
43
+ * // depth: 0
44
+ * "src" => 1
45
+ *
46
+ * // depth: 1
47
+ * "src/components" => 0
48
+ * "src/views" => 1
49
+ *
50
+ * @since 0.0.6
51
+ */
52
+ depthPaths: Map<string, number>;
53
+ /**
54
+ * Total number of files scanned.
55
+ *
56
+ * @since 0.0.6
57
+ */
58
+ totalFiles: number;
59
+ /**
60
+ * Total number of files matched by the target.
61
+ *
62
+ * @since 0.0.6
63
+ */
64
+ totalMatchedFiles: number;
65
+ /**
66
+ * Total number of directories scanned.
67
+ *
68
+ * @since 0.0.6
69
+ */
70
+ totalDirs: number;
71
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ import type { ScanOptions } from "../types.js";
2
+ import type { MatcherContext } from "./matcherContext.js";
3
+ /**
4
+ * Provides patching abilities for the given {@link MatcherContext}.
5
+ * Directories should have the slash suffix.
6
+ *
7
+ * @since 0.0.6
8
+ */
9
+ export declare function matcherContextAddPath(ctx: MatcherContext, options: Required<ScanOptions>, entry: string): Promise<boolean>;
10
+ /**
11
+ * Provides patching abilities for the given {@link MatcherContext}.
12
+ * Directories should have the slash suffix.
13
+ *
14
+ * @since 0.0.6
15
+ */
16
+ export declare function matcherContextRemovePath(ctx: MatcherContext, options: Required<ScanOptions>, entry: string): Promise<boolean>;
@@ -0,0 +1,151 @@
1
+ import { resolve, dirname } from "node:path";
2
+ import { getDepth } from "../getDepth.js";
3
+ import { normalizeCwd } from "../normalizeCwd.js";
4
+ import { opendir } from "../opendir.js";
5
+ import { walkIncludes } from "../walk.js";
6
+ /**
7
+ * Provides patching abilities for the given {@link MatcherContext}.
8
+ * Directories should have the slash suffix.
9
+ *
10
+ * @since 0.0.6
11
+ */
12
+ export async function matcherContextAddPath(ctx, options, entry) {
13
+ if (ctx.paths.has(entry)) {
14
+ return false;
15
+ }
16
+ const { target, fs, cwd } = options;
17
+ const isDir = entry.endsWith("/");
18
+ if (isDir) {
19
+ // recursive parent population
20
+ const direntPath = entry.replace(/\/$/, "");
21
+ if (direntPath === ".") {
22
+ return true;
23
+ }
24
+ ctx.paths.set(entry, await target.ignores({ fs, cwd, entry: direntPath, ctx }));
25
+ if (ctx.totalFiles >= 0) {
26
+ ctx.totalDirs++;
27
+ }
28
+ const parent = dirname(direntPath);
29
+ if (parent !== ".") {
30
+ void (await matcherContextAddPath(ctx, options, parent + "/"));
31
+ }
32
+ return true;
33
+ }
34
+ const parent = dirname(entry);
35
+ const isSource = target.extractors.some((e) => e.path === entry);
36
+ if (isSource) {
37
+ // add pattern sources
38
+ await matcherContextRemovePath(ctx, options, parent + "/");
39
+ await rescan(ctx, { ...options, within: parent });
40
+ }
41
+ // add paths
42
+ // 1. recursively populate parents
43
+ await matcherContextAddPath(ctx, options, parent + "/");
44
+ // 2. if ignored, remove, otherwise add
45
+ const match = await target.ignores({ fs, cwd, entry, ctx });
46
+ if (match.ignored) {
47
+ // 2.1. remove
48
+ await matcherContextRemovePath(ctx, options, entry);
49
+ return false;
50
+ }
51
+ // 2.2. add
52
+ if (ctx.totalFiles >= 0) {
53
+ ctx.totalFiles++;
54
+ ctx.totalMatchedFiles++;
55
+ }
56
+ ctx.paths.set(entry, match);
57
+ return true;
58
+ }
59
+ /**
60
+ * Provides patching abilities for the given {@link MatcherContext}.
61
+ * Directories should have the slash suffix.
62
+ *
63
+ * @since 0.0.6
64
+ */
65
+ export async function matcherContextRemovePath(ctx, options, entry) {
66
+ const isDir = entry.endsWith("/");
67
+ if (isDir) {
68
+ // remove directories
69
+ const direntPath = entry.replace(/\/$/, "");
70
+ for (const [element] of ctx.paths) {
71
+ if (entry !== "./" && !element.startsWith(entry)) {
72
+ continue;
73
+ }
74
+ if (ctx.totalFiles >= 0) {
75
+ const isDir = element.endsWith("/");
76
+ if (isDir) {
77
+ ctx.totalDirs--;
78
+ }
79
+ else {
80
+ ctx.totalFiles--;
81
+ ctx.totalMatchedFiles--;
82
+ }
83
+ }
84
+ ctx.paths.delete(element);
85
+ }
86
+ for (const [element] of ctx.depthPaths) {
87
+ if (entry !== "./" && !element.startsWith(direntPath)) {
88
+ continue;
89
+ }
90
+ ctx.depthPaths.delete(element);
91
+ }
92
+ for (const [element] of ctx.external) {
93
+ if (entry !== "./" && !element.startsWith(direntPath)) {
94
+ continue;
95
+ }
96
+ if (ctx.external.delete(element) && ctx.failed.length) {
97
+ // 3.1. remove failed sources
98
+ const failedEntryIndex = ctx.failed.findIndex((fail) => dirname(fail.path) === element);
99
+ if (failedEntryIndex >= 0) {
100
+ ctx.failed.splice(failedEntryIndex, 1);
101
+ }
102
+ }
103
+ }
104
+ return true;
105
+ }
106
+ const parent = dirname(entry);
107
+ const isSource = options.target.extractors.some((e) => e.path === entry);
108
+ if (isSource) {
109
+ // remove pattern sources
110
+ // rescan directory and repopulate stats
111
+ await matcherContextRemovePath(ctx, options, parent + "/");
112
+ await rescan(ctx, { ...options, within: parent });
113
+ return true;
114
+ }
115
+ // remove path
116
+ // 1. change stats
117
+ {
118
+ if (ctx.totalFiles >= 0) {
119
+ ctx.totalFiles--;
120
+ ctx.totalMatchedFiles--;
121
+ }
122
+ // 1.1 remove depthPaths
123
+ const { depthSlash } = getDepth(entry, options.depth);
124
+ if (depthSlash >= 0) {
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
+ }
136
+ }
137
+ }
138
+ // 2. remove from paths
139
+ ctx.paths.delete(entry);
140
+ return true;
141
+ }
142
+ async function rescan(ctx, options) {
143
+ const normalCwd = normalizeCwd(options.cwd);
144
+ await opendir(options.fs, resolve(normalCwd, options.within), (entry) => walkIncludes({
145
+ entry,
146
+ ctx,
147
+ stream: undefined,
148
+ scanOptions: { ...options, cwd: normalCwd },
149
+ }));
150
+ ctx.totalDirs = ctx.totalFiles = ctx.totalMatchedFiles = -1;
151
+ }
@@ -0,0 +1,64 @@
1
+ import { EventEmitter } from "node:events";
2
+ import type { Dirent } from "node:fs";
3
+ import type { MatcherContext } from "../patterns/matcherContext.js";
4
+ import type { SignedPatternMatch } from "./signedPattern.js";
5
+ /**
6
+ * Post-scan entry information.
7
+ *
8
+ * @since 0.0.6
9
+ */
10
+ export type EntryInfo = {
11
+ /**
12
+ * The relative path of the entry.
13
+ *
14
+ * @since 0.0.6
15
+ */
16
+ path: string;
17
+ /**
18
+ * The directory entry.
19
+ *
20
+ * @since 0.0.6
21
+ */
22
+ dirent: Dirent;
23
+ /**
24
+ * Whether the entry was ignored.
25
+ *
26
+ * @since 0.0.6
27
+ */
28
+ match: SignedPatternMatch;
29
+ /**
30
+ * The matcher context.
31
+ *
32
+ * @since 0.0.6
33
+ */
34
+ ctx: MatcherContext;
35
+ };
36
+ /**
37
+ * @see {@link MatcherStream} uses it for the "dirent" event.
38
+ *
39
+ * @since 0.0.6
40
+ */
41
+ export type EntryListener = (info: EntryInfo) => void;
42
+ /**
43
+ * @see {@link MatcherStream} uses it for the "end" event.
44
+ *
45
+ * @since 0.0.6
46
+ */
47
+ export type EndListener = (ctx: MatcherContext) => void;
48
+ /**
49
+ * @see {@link MatcherStream} uses it for its event map.
50
+ *
51
+ * @since 0.0.6
52
+ */
53
+ export type EventMap = {
54
+ dirent: [EntryInfo];
55
+ end: [MatcherContext];
56
+ };
57
+ /**
58
+ * Event emitter.
59
+ * @extends EventEmitter
60
+ *
61
+ * @since 0.0.6
62
+ */
63
+ export declare class MatcherStream extends EventEmitter<EventMap> {
64
+ }
@@ -0,0 +1,9 @@
1
+ import { EventEmitter } from "node:events";
2
+ /**
3
+ * Event emitter.
4
+ * @extends EventEmitter
5
+ *
6
+ * @since 0.0.6
7
+ */
8
+ export class MatcherStream extends EventEmitter {
9
+ }
@@ -1,3 +1,9 @@
1
- import { type } from 'arktype';
2
- import type { Source } from './matcher.js';
3
- export declare function extractPackageJson(source: Source, content: Buffer<ArrayBuffer>): type.errors | undefined;
1
+ import { type Source } from "./source.js";
2
+ /**
3
+ * Extracts and compiles patterns from the file.
4
+ *
5
+ * @see {@link signedPatternCompile}
6
+ *
7
+ * @since 0.0.6
8
+ */
9
+ export declare function extractPackageJson(source: Source, content: Buffer): void | "none";
@@ -1,25 +1,32 @@
1
- import { type } from 'arktype';
1
+ import { type } from "arktype";
2
+ import { signedPatternCompile } from "./resolveSources.js";
3
+ import { sourcePushNegatable } from "./source.js";
2
4
  const nodeJsManifest = type({
3
- files: 'string[]?',
5
+ files: "string[]?",
4
6
  });
5
- const parse = nodeJsManifest.pipe((s) => JSON.parse(s));
7
+ const parse = type("string")
8
+ .pipe((s) => JSON.parse(s))
9
+ .pipe(nodeJsManifest);
10
+ /**
11
+ * Extracts and compiles patterns from the file.
12
+ *
13
+ * @see {@link signedPatternCompile}
14
+ *
15
+ * @since 0.0.6
16
+ */
6
17
  export function extractPackageJson(source, content) {
7
18
  source.inverted = true;
8
19
  const dist = parse(content.toString());
9
20
  if (dist instanceof type.errors) {
10
- return dist;
21
+ source.error = new Error("Invalid '" + source.path + "': " + dist.summary, { cause: dist });
22
+ return;
11
23
  }
12
24
  if (!dist.files) {
13
- return;
25
+ return "none";
14
26
  }
15
- for (const p of dist.files) {
16
- if (p.startsWith('!')) {
17
- source.pattern.exclude.push(...p.substring(1));
18
- }
19
- else {
20
- source.pattern.include.push(...p);
21
- }
27
+ for (const pattern of dist.files) {
28
+ sourcePushNegatable(source, pattern);
22
29
  }
23
- return;
30
+ signedPatternCompile(source.pattern);
24
31
  }
25
32
  extractPackageJson;
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Compiled pattern.
3
+ *
4
+ * @see {@link stringCompile}
5
+ * @see {@link signedPatternCompile}
6
+ *
7
+ * @since 0.0.6
8
+ */
9
+ export type PatternMinimatch = {
10
+ re: RegExp;
11
+ /**
12
+ * The original pattern string this minimatch was compiled from.
13
+ *
14
+ * @since 0.0.6
15
+ */
16
+ pattern: string;
17
+ /**
18
+ * The original pattern list this pattern was compiled from.
19
+ *
20
+ * @since 0.0.6
21
+ */
22
+ patternContext: Pattern;
23
+ };
24
+ /**
25
+ * Safely calls RegExp.test.
26
+ *
27
+ * @since 0.0.6
28
+ */
29
+ export declare function patternMinimatchTest(pattern: PatternMinimatch, path: string): boolean;
30
+ /**
31
+ * Represents a list of positive minimatch patterns.
32
+ *
33
+ * @since 0.0.6
34
+ */
35
+ export type Pattern = string[];
36
+ /**
37
+ * Compiles the {@link Pattern}.
38
+ *
39
+ * @see {@link stringCompile}
40
+ * @see {@link signedPatternCompile}
41
+ *
42
+ * @since 0.0.6
43
+ */
44
+ export declare function patternCompile(pattern: Pattern): PatternMinimatch[];
@@ -0,0 +1,21 @@
1
+ import { stringCompile } from "./stringCompile.js";
2
+ /**
3
+ * Safely calls RegExp.test.
4
+ *
5
+ * @since 0.0.6
6
+ */
7
+ export function patternMinimatchTest(pattern, path) {
8
+ pattern.re.lastIndex = 0;
9
+ return pattern.re.test(path);
10
+ }
11
+ /**
12
+ * Compiles the {@link Pattern}.
13
+ *
14
+ * @see {@link stringCompile}
15
+ * @see {@link signedPatternCompile}
16
+ *
17
+ * @since 0.0.6
18
+ */
19
+ export function patternCompile(pattern) {
20
+ return pattern.map(stringCompile);
21
+ }
@@ -0,0 +1,23 @@
1
+ import type { SignedPattern } from "./signedPattern.js";
2
+ /**
3
+ * Combined internal and external patterns for matching.
4
+ *
5
+ * @see {@link signedPatternIgnores}
6
+ *
7
+ * @since 0.0.6
8
+ */
9
+ export type PatternMatcher = {
10
+ /**
11
+ * Internal patterns are provided by the target.
12
+ * Almost always they are predefined.
13
+ *
14
+ * @since 0.0.6
15
+ */
16
+ internal: SignedPattern;
17
+ /**
18
+ * External patterns are sourced from existing project files at runtime.
19
+ *
20
+ * @since 0.0.6
21
+ */
22
+ external: SignedPattern;
23
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,34 @@
1
+ import type { PatternFinderOptions } from "./extractor.js";
2
+ import type { SignedPattern } from "./signedPattern.js";
3
+ /**
4
+ * Compiles the {@link SignedPattern} (forced).
5
+ * Can be compiled at any time.
6
+ * Extractors are compiling it.
7
+ *
8
+ * @see {@link patternCompile}
9
+ *
10
+ * @since 0.0.6
11
+ */
12
+ export declare function signedPatternCompile(signedPattern: SignedPattern): SignedPattern;
13
+ /**
14
+ * @see {@link resolveSources}
15
+ *
16
+ * @since 0.0.6
17
+ */
18
+ export interface ResolveSourcesOptions extends PatternFinderOptions {
19
+ /**
20
+ * Relative directory path.
21
+ *
22
+ * @example
23
+ * "dir/subdir"
24
+ *
25
+ * @since 0.0.6
26
+ */
27
+ dir: string;
28
+ }
29
+ /**
30
+ * Populates the {@link MatcherContext.external} map with {@link Source} objects.
31
+ *
32
+ * @since 0.0.6
33
+ */
34
+ export declare function resolveSources(options: ResolveSourcesOptions): Promise<void>;