filehound 2.0.0-beta.2 → 2.0.0-beta.3

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 (212) hide show
  1. package/README.md +37 -11
  2. package/dist/arrays.d.ts +1 -0
  3. package/dist/arrays.js +4 -0
  4. package/dist/file.d.ts +108 -0
  5. package/dist/file.js +184 -0
  6. package/dist/filehound.d.ts +322 -0
  7. package/dist/filehound.js +443 -0
  8. package/dist/files.d.ts +4 -0
  9. package/dist/files.js +37 -0
  10. package/dist/filetype.d.ts +10 -0
  11. package/dist/filetype.js +9 -0
  12. package/dist/index.d.ts +4 -0
  13. package/dist/index.js +3 -0
  14. package/dist/matchers.d.ts +297 -0
  15. package/dist/matchers.js +389 -0
  16. package/dist/walker/async.d.ts +4 -0
  17. package/dist/walker/async.js +237 -0
  18. package/dist/walker/heap.d.ts +7 -0
  19. package/dist/walker/heap.js +49 -0
  20. package/dist/walker/sync.d.ts +4 -0
  21. package/dist/walker/sync.js +66 -0
  22. package/dist/walker/walk.d.ts +32 -0
  23. package/dist/walker/walk.js +70 -0
  24. package/package.json +44 -48
  25. package/.github/stale.yml +0 -42
  26. package/.travis.yml +0 -8
  27. package/.vscode/launch.json +0 -21
  28. package/.vscode/settings.json +0 -3
  29. package/CONTRIBUTING.md +0 -8
  30. package/_config.yml +0 -1
  31. package/coverage/coverage.raw.json +0 -1
  32. package/coverage/lcov-report/arrays.ts.html +0 -98
  33. package/coverage/lcov-report/base.css +0 -212
  34. package/coverage/lcov-report/filehound.ts.html +0 -2078
  35. package/coverage/lcov-report/files.ts.html +0 -260
  36. package/coverage/lcov-report/functions.ts.html +0 -122
  37. package/coverage/lcov-report/index.html +0 -132
  38. package/coverage/lcov-report/prettify.css +0 -1
  39. package/coverage/lcov-report/prettify.js +0 -1
  40. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  41. package/coverage/lcov-report/sorter.js +0 -158
  42. package/coverage/lcov.info +0 -378
  43. package/dist/src/arrays.js +0 -15
  44. package/dist/src/arrays.js.map +0 -1
  45. package/dist/src/asyncWalker.js +0 -59
  46. package/dist/src/asyncWalker.js.map +0 -1
  47. package/dist/src/bind.js +0 -15
  48. package/dist/src/bind.js.map +0 -1
  49. package/dist/src/filehound.js +0 -597
  50. package/dist/src/filehound.js.map +0 -1
  51. package/dist/src/files.js +0 -60
  52. package/dist/src/files.js.map +0 -1
  53. package/dist/src/matcher.js +0 -51
  54. package/dist/src/matcher.js.map +0 -1
  55. package/dist/src/syncWalker.js +0 -47
  56. package/dist/src/syncWalker.js.map +0 -1
  57. package/dist/src/walkAsync.js +0 -33
  58. package/dist/src/walkAsync.js.map +0 -1
  59. package/dist/src/walkSync.js +0 -21
  60. package/dist/src/walkSync.js.map +0 -1
  61. package/dist/src/walker/walk.js +0 -68
  62. package/dist/src/walker/walk.js.map +0 -1
  63. package/dist/src/walker/walkAsync.js +0 -33
  64. package/dist/src/walker/walkAsync.js.map +0 -1
  65. package/dist/src/walker/walkSync.js +0 -21
  66. package/dist/src/walker/walkSync.js.map +0 -1
  67. package/dist/test/filehound.js +0 -872
  68. package/dist/test/filehound.js.map +0 -1
  69. package/dist/test/files.js +0 -29
  70. package/dist/test/files.js.map +0 -1
  71. package/docconfig/jsdoc.json +0 -26
  72. package/docconfig/template/LICENSE +0 -61
  73. package/docconfig/template/README.md +0 -86
  74. package/docconfig/template/package.json +0 -22
  75. package/docconfig/template/publish.js +0 -676
  76. package/docconfig/template/static/fonts/OpenSans-Bold-webfont.eot +0 -0
  77. package/docconfig/template/static/fonts/OpenSans-Bold-webfont.svg +0 -1830
  78. package/docconfig/template/static/fonts/OpenSans-Bold-webfont.woff +0 -0
  79. package/docconfig/template/static/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
  80. package/docconfig/template/static/fonts/OpenSans-BoldItalic-webfont.svg +0 -1830
  81. package/docconfig/template/static/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
  82. package/docconfig/template/static/fonts/OpenSans-Italic-webfont.eot +0 -0
  83. package/docconfig/template/static/fonts/OpenSans-Italic-webfont.svg +0 -1830
  84. package/docconfig/template/static/fonts/OpenSans-Italic-webfont.woff +0 -0
  85. package/docconfig/template/static/fonts/OpenSans-Light-webfont.eot +0 -0
  86. package/docconfig/template/static/fonts/OpenSans-Light-webfont.svg +0 -1831
  87. package/docconfig/template/static/fonts/OpenSans-Light-webfont.woff +0 -0
  88. package/docconfig/template/static/fonts/OpenSans-LightItalic-webfont.eot +0 -0
  89. package/docconfig/template/static/fonts/OpenSans-LightItalic-webfont.svg +0 -1835
  90. package/docconfig/template/static/fonts/OpenSans-LightItalic-webfont.woff +0 -0
  91. package/docconfig/template/static/fonts/OpenSans-Regular-webfont.eot +0 -0
  92. package/docconfig/template/static/fonts/OpenSans-Regular-webfont.svg +0 -1831
  93. package/docconfig/template/static/fonts/OpenSans-Regular-webfont.woff +0 -0
  94. package/docconfig/template/static/fonts/OpenSans-Semibold-webfont.eot +0 -0
  95. package/docconfig/template/static/fonts/OpenSans-Semibold-webfont.svg +0 -1830
  96. package/docconfig/template/static/fonts/OpenSans-Semibold-webfont.ttf +0 -0
  97. package/docconfig/template/static/fonts/OpenSans-Semibold-webfont.woff +0 -0
  98. package/docconfig/template/static/fonts/OpenSans-SemiboldItalic-webfont.eot +0 -0
  99. package/docconfig/template/static/fonts/OpenSans-SemiboldItalic-webfont.svg +0 -1830
  100. package/docconfig/template/static/fonts/OpenSans-SemiboldItalic-webfont.ttf +0 -0
  101. package/docconfig/template/static/fonts/OpenSans-SemiboldItalic-webfont.woff +0 -0
  102. package/docconfig/template/static/scripts/linenumber.js +0 -25
  103. package/docconfig/template/static/scripts/prettify/Apache-License-2.0.txt +0 -202
  104. package/docconfig/template/static/scripts/prettify/lang-css.js +0 -2
  105. package/docconfig/template/static/scripts/prettify/prettify.js +0 -28
  106. package/docconfig/template/static/styles/jsdoc-default.css +0 -605
  107. package/docconfig/template/static/styles/prettify-jsdoc.css +0 -111
  108. package/docconfig/template/static/styles/prettify-tomorrow.css +0 -132
  109. package/docconfig/template/tmpl/augments.tmpl +0 -10
  110. package/docconfig/template/tmpl/container.tmpl +0 -183
  111. package/docconfig/template/tmpl/details.tmpl +0 -143
  112. package/docconfig/template/tmpl/example.tmpl +0 -2
  113. package/docconfig/template/tmpl/examples.tmpl +0 -13
  114. package/docconfig/template/tmpl/exceptions.tmpl +0 -32
  115. package/docconfig/template/tmpl/layout.tmpl +0 -47
  116. package/docconfig/template/tmpl/mainpage.tmpl +0 -10
  117. package/docconfig/template/tmpl/members.tmpl +0 -38
  118. package/docconfig/template/tmpl/method.tmpl +0 -105
  119. package/docconfig/template/tmpl/params.tmpl +0 -124
  120. package/docconfig/template/tmpl/properties.tmpl +0 -108
  121. package/docconfig/template/tmpl/returns.tmpl +0 -19
  122. package/docconfig/template/tmpl/source.tmpl +0 -8
  123. package/docconfig/template/tmpl/tutorial.tmpl +0 -19
  124. package/docconfig/template/tmpl/type.tmpl +0 -7
  125. package/docs/FileHound.html +0 -3079
  126. package/docs/FileHound_modified.html +0 -245
  127. package/docs/_config.yml +0 -1
  128. package/docs/filehound.js.html +0 -697
  129. package/docs/fonts/OpenSans-Bold-webfont.eot +0 -0
  130. package/docs/fonts/OpenSans-Bold-webfont.svg +0 -1830
  131. package/docs/fonts/OpenSans-Bold-webfont.woff +0 -0
  132. package/docs/fonts/OpenSans-BoldItalic-webfont.eot +0 -0
  133. package/docs/fonts/OpenSans-BoldItalic-webfont.svg +0 -1830
  134. package/docs/fonts/OpenSans-BoldItalic-webfont.woff +0 -0
  135. package/docs/fonts/OpenSans-Italic-webfont.eot +0 -0
  136. package/docs/fonts/OpenSans-Italic-webfont.svg +0 -1830
  137. package/docs/fonts/OpenSans-Italic-webfont.woff +0 -0
  138. package/docs/fonts/OpenSans-Light-webfont.eot +0 -0
  139. package/docs/fonts/OpenSans-Light-webfont.svg +0 -1831
  140. package/docs/fonts/OpenSans-Light-webfont.woff +0 -0
  141. package/docs/fonts/OpenSans-LightItalic-webfont.eot +0 -0
  142. package/docs/fonts/OpenSans-LightItalic-webfont.svg +0 -1835
  143. package/docs/fonts/OpenSans-LightItalic-webfont.woff +0 -0
  144. package/docs/fonts/OpenSans-Regular-webfont.eot +0 -0
  145. package/docs/fonts/OpenSans-Regular-webfont.svg +0 -1831
  146. package/docs/fonts/OpenSans-Regular-webfont.woff +0 -0
  147. package/docs/fonts/OpenSans-Semibold-webfont.eot +0 -0
  148. package/docs/fonts/OpenSans-Semibold-webfont.svg +0 -1830
  149. package/docs/fonts/OpenSans-Semibold-webfont.ttf +0 -0
  150. package/docs/fonts/OpenSans-Semibold-webfont.woff +0 -0
  151. package/docs/fonts/OpenSans-SemiboldItalic-webfont.eot +0 -0
  152. package/docs/fonts/OpenSans-SemiboldItalic-webfont.svg +0 -1830
  153. package/docs/fonts/OpenSans-SemiboldItalic-webfont.ttf +0 -0
  154. package/docs/fonts/OpenSans-SemiboldItalic-webfont.woff +0 -0
  155. package/docs/global.html +0 -288
  156. package/docs/index.html +0 -154
  157. package/docs/scripts/linenumber.js +0 -25
  158. package/docs/scripts/prettify/Apache-License-2.0.txt +0 -202
  159. package/docs/scripts/prettify/lang-css.js +0 -2
  160. package/docs/scripts/prettify/prettify.js +0 -28
  161. package/docs/styles/jsdoc-default.css +0 -605
  162. package/docs/styles/prettify-jsdoc.css +0 -111
  163. package/docs/styles/prettify-tomorrow.css +0 -132
  164. package/docs.md +0 -164
  165. package/index.js +0 -1
  166. package/issue_template.md +0 -6
  167. package/test/filehound.ts +0 -1076
  168. package/test/files.ts +0 -29
  169. package/test/fixtures/custom/failed.txt +0 -0
  170. package/test/fixtures/custom/passed.txt +0 -0
  171. package/test/fixtures/deeplyNested/c.json +0 -0
  172. package/test/fixtures/deeplyNested/d.json +0 -0
  173. package/test/fixtures/deeplyNested/mydir/e.json +0 -0
  174. package/test/fixtures/deeplyNested/mydir/mydir2/f.json +0 -0
  175. package/test/fixtures/deeplyNested/mydir/mydir2/mydir3/mydir4/failed.json +0 -0
  176. package/test/fixtures/deeplyNested/mydir/mydir2/mydir3/z.json +0 -0
  177. package/test/fixtures/deeplyNested/mydir/mydir2/y.json +0 -0
  178. package/test/fixtures/deeplyNestedWithHiddenDir/c.json +0 -0
  179. package/test/fixtures/deeplyNestedWithHiddenDir/d.json +0 -0
  180. package/test/fixtures/deeplyNestedWithHiddenDir/mydir/e.json +0 -0
  181. package/test/fixtures/deeplyNestedWithHiddenDir/mydir/mydir2/f.json +0 -0
  182. package/test/fixtures/deeplyNestedWithHiddenDir/mydir/mydir2/mydir3/mydir4/.mydir5/.keep +0 -0
  183. package/test/fixtures/deeplyNestedWithHiddenDir/mydir/mydir2/mydir3/mydir4/failed.json +0 -0
  184. package/test/fixtures/deeplyNestedWithHiddenDir/mydir/mydir2/mydir3/z.json +0 -0
  185. package/test/fixtures/deeplyNestedWithHiddenDir/mydir/mydir2/y.json +0 -0
  186. package/test/fixtures/ext/Dummy.java +0 -0
  187. package/test/fixtures/ext/Dumpy.go +0 -0
  188. package/test/fixtures/ext/dummy.json +0 -0
  189. package/test/fixtures/ext/dummy.txt +0 -0
  190. package/test/fixtures/justFiles/a.json +0 -0
  191. package/test/fixtures/justFiles/b.json +0 -0
  192. package/test/fixtures/justFiles/dummy.txt +0 -0
  193. package/test/fixtures/mixed/a.json +0 -0
  194. package/test/fixtures/mixed/aabbcc.json +0 -0
  195. package/test/fixtures/mixed/ab.json +0 -0
  196. package/test/fixtures/mixed/z.json +0 -0
  197. package/test/fixtures/nested/.hidden1/bad.txt +0 -0
  198. package/test/fixtures/nested/c.json +0 -0
  199. package/test/fixtures/nested/d.json +0 -0
  200. package/test/fixtures/nested/mydir/e.json +0 -0
  201. package/test/fixtures/sizes/10b.txt +0 -0
  202. package/test/fixtures/sizes/1b.txt +0 -0
  203. package/test/fixtures/sizes/1k.txt +0 -0
  204. package/test/fixtures/sizes/2k.txt +0 -0
  205. package/test/fixtures/visibility/.hidden/.hidden.json +0 -0
  206. package/test/fixtures/visibility/.hidden/visible.json +0 -3
  207. package/test/fixtures/visibility/.hidden.json +0 -3
  208. package/test/fixtures/visibility/visible/.hidden.json +0 -3
  209. package/test/fixtures/visibility/visible.json +0 -3
  210. package/test/mocha.opts +0 -4
  211. package/tsconfig.json +0 -16
  212. package/tslint.json +0 -44
@@ -0,0 +1,297 @@
1
+ import type { FileView } from './file.js';
2
+ /**
3
+ * A composable test applied to each file found during a search
4
+ */
5
+ export interface FilePredicate {
6
+ /**
7
+ * Negates this predicate
8
+ *
9
+ * @returns a predicate that matches when this one does not
10
+ */
11
+ not(): FilePredicate;
12
+ /**
13
+ * Combines this predicate with another using logical OR
14
+ *
15
+ * @param predicate - the predicate to combine with
16
+ * @returns a predicate that matches when either predicate matches
17
+ */
18
+ or(predicate: FilePredicate): FilePredicate;
19
+ /**
20
+ * Combines this predicate with another using logical AND
21
+ *
22
+ * @param predicate - the predicate to combine with
23
+ * @returns a predicate that matches when both predicates match
24
+ */
25
+ and(predicate: FilePredicate): FilePredicate;
26
+ /**
27
+ * Asynchronously tests whether a file satisfies this predicate. Used by
28
+ * {@link FileHound.find}.
29
+ *
30
+ * @param file - the file to test
31
+ * @returns a Promise that fulfils with true if the file matches
32
+ */
33
+ test(file: FileView): Promise<boolean>;
34
+ /**
35
+ * Synchronously tests whether a file satisfies this predicate. Used by
36
+ * {@link FileHound.findSync}.
37
+ *
38
+ * @param file - the file to test
39
+ * @returns true if the file matches
40
+ * @throws `TypeError`
41
+ * Thrown if the predicate can only be tested asynchronously.
42
+ */
43
+ testSync(file: FileView): boolean;
44
+ }
45
+ declare const sync: unique symbol;
46
+ export interface SyncFilePredicate extends FilePredicate {
47
+ readonly [sync]: true;
48
+ }
49
+ export declare function isSyncPredicate(predicate: FilePredicate): predicate is SyncFilePredicate;
50
+ export declare abstract class AbstractFilePredicate implements FilePredicate {
51
+ or(f: FilePredicate): FilePredicate;
52
+ and(f: FilePredicate): FilePredicate;
53
+ not(): FilePredicate;
54
+ test(file: FileView): Promise<boolean>;
55
+ abstract testSync(file: FileView): boolean;
56
+ }
57
+ export declare class And extends AbstractFilePredicate {
58
+ #private;
59
+ constructor(left: FilePredicate, right: FilePredicate);
60
+ get [sync](): boolean;
61
+ test(file: FileView): Promise<boolean>;
62
+ testSync(file: FileView): boolean;
63
+ }
64
+ export declare class Not extends AbstractFilePredicate {
65
+ #private;
66
+ constructor(filePredicate: FilePredicate);
67
+ get [sync](): boolean;
68
+ test(file: FileView): Promise<boolean>;
69
+ testSync(file: FileView): boolean;
70
+ }
71
+ export declare class Or extends AbstractFilePredicate {
72
+ #private;
73
+ constructor(left: FilePredicate, right: FilePredicate);
74
+ get [sync](): boolean;
75
+ test(file: FileView): Promise<boolean>;
76
+ testSync(file: FileView): boolean;
77
+ }
78
+ export declare class Extension extends AbstractFilePredicate {
79
+ #private;
80
+ readonly [sync] = true;
81
+ constructor(extensions: string[]);
82
+ testSync(file: FileView): boolean;
83
+ }
84
+ export declare class Glob extends AbstractFilePredicate {
85
+ #private;
86
+ readonly [sync] = true;
87
+ constructor(globPattern: string);
88
+ testSync(file: FileView): boolean;
89
+ }
90
+ export declare class TextMatch extends AbstractFilePredicate {
91
+ #private;
92
+ readonly [sync] = true;
93
+ constructor(pattern: string, flags?: string);
94
+ testSync(file: FileView): boolean;
95
+ }
96
+ export declare class CustomFilter extends AbstractFilePredicate {
97
+ #private;
98
+ constructor(fn: (file: FileView) => boolean | Promise<boolean>);
99
+ test(file: FileView): Promise<boolean>;
100
+ testSync(_file: FileView): boolean;
101
+ }
102
+ export declare class CustomFilterSync extends AbstractFilePredicate {
103
+ #private;
104
+ readonly [sync] = true;
105
+ constructor(fn: (file: FileView) => boolean);
106
+ testSync(file: FileView): boolean;
107
+ }
108
+ export declare class Size extends AbstractFilePredicate {
109
+ #private;
110
+ constructor(sizeExpression: string | number);
111
+ test(file: FileView): Promise<boolean>;
112
+ testSync(file: FileView): boolean;
113
+ }
114
+ export declare class Modified extends AbstractFilePredicate {
115
+ #private;
116
+ constructor(expression: string);
117
+ test(file: FileView): Promise<boolean>;
118
+ testSync(file: FileView): boolean;
119
+ }
120
+ export declare class Accessed extends AbstractFilePredicate {
121
+ #private;
122
+ constructor(expression: string);
123
+ test(file: FileView): Promise<boolean>;
124
+ testSync(file: FileView): boolean;
125
+ }
126
+ export declare class Changed extends AbstractFilePredicate {
127
+ #private;
128
+ constructor(expression: string);
129
+ test(file: FileView): Promise<boolean>;
130
+ testSync(file: FileView): boolean;
131
+ }
132
+ export declare class MatchAll extends AbstractFilePredicate {
133
+ readonly [sync] = true;
134
+ testSync(_file: FileView): boolean;
135
+ }
136
+ /**
137
+ * Matches files with any of the given extensions. A leading dot is optional.
138
+ *
139
+ * @param extensions - one or more extensions
140
+ * @returns the predicate
141
+ * @example
142
+ * ```ts
143
+ * FileHound.create().match(ext('json', '.txt'));
144
+ * ```
145
+ */
146
+ export declare function ext(...extensions: string[]): FilePredicate;
147
+ /**
148
+ * Matches files with any of the given extensions. A leading dot is optional.
149
+ *
150
+ * @param extensions - an array of extensions
151
+ * @returns the predicate
152
+ */
153
+ export declare function ext(extensions: string[]): FilePredicate;
154
+ /**
155
+ * Matches every file
156
+ *
157
+ * @returns the predicate
158
+ */
159
+ export declare function matchAll(): FilePredicate;
160
+ /**
161
+ * Matches files by size, using a comparison with optional units, such as
162
+ * `'>10k'` or `'<=1mb'`. The operators are `<`, `<=`, `>`, `>=` and `==`,
163
+ * which is the default, and the units are `b`, `k`, `m`, `g` and `t`, in
164
+ * multiples of 1024. Use {@link sizeEquals} for an exact number of bytes.
165
+ *
166
+ * @param expression - the size expression
167
+ * @returns the predicate
168
+ * @throws `TypeError`
169
+ * Thrown if the expression is not a string.
170
+ * @example
171
+ * ```ts
172
+ * FileHound.create().match(size('>1mb'));
173
+ * ```
174
+ */
175
+ export declare function size(expression: string): FilePredicate;
176
+ /**
177
+ * Matches files of an exact size
178
+ *
179
+ * @param bytes - the size in bytes
180
+ * @returns the predicate
181
+ * @throws `RangeError`
182
+ * Thrown if bytes is negative or not an integer.
183
+ * @example
184
+ * ```ts
185
+ * FileHound.create().match(sizeEquals(1024));
186
+ * ```
187
+ */
188
+ export declare function sizeEquals(bytes: number): FilePredicate;
189
+ /**
190
+ * Matches files with a size of zero bytes
191
+ *
192
+ * @returns the predicate
193
+ */
194
+ export declare function isEmpty(): FilePredicate;
195
+ /**
196
+ * Matches files whose path, relative to the search path, satisfies a glob
197
+ * pattern. Patterns follow Node's `path.matchesGlob` and `fs.glob` rules:
198
+ * `*.json` matches only the top level of the search path, and a leading `**`
199
+ * segment matches at any depth. Wildcards, including `**`, do not match names
200
+ * beginning with a dot.
201
+ *
202
+ * @param globPattern - the glob pattern
203
+ * @returns the predicate
204
+ * @example
205
+ * ```ts
206
+ * FileHound.create().match(glob('*.json'));
207
+ * ```
208
+ */
209
+ export declare function glob(globPattern: string): FilePredicate;
210
+ /**
211
+ * Matches files using a custom function, which may be asynchronous. Can only
212
+ * be used with {@link FileHound.find}; use {@link applyFilterSync} with
213
+ * {@link FileHound.findSync}.
214
+ *
215
+ * @param fn - returns, or fulfils with, true for files to include
216
+ * @returns the predicate
217
+ * @example
218
+ * ```ts
219
+ * FileHound.create().match(applyFilter(async file => await file.size() > 0));
220
+ * ```
221
+ */
222
+ export declare function applyFilter(fn: (file: FileView) => boolean | Promise<boolean>): FilePredicate;
223
+ /**
224
+ * Matches files using a synchronous custom function. Can be used with both
225
+ * {@link FileHound.find} and {@link FileHound.findSync}.
226
+ *
227
+ * @param fn - returns true for files to include
228
+ * @returns the predicate
229
+ * @example
230
+ * ```ts
231
+ * FileHound.create().match(applyFilterSync(file => file.sizeSync() > 0));
232
+ * ```
233
+ */
234
+ export declare function applyFilterSync(fn: (file: FileView) => boolean): FilePredicate;
235
+ /**
236
+ * Matches files whose path satisfies a regular expression pattern
237
+ *
238
+ * @param pattern - the regular expression pattern
239
+ * @returns the predicate
240
+ */
241
+ export declare function like(pattern: string): FilePredicate;
242
+ /**
243
+ * Excludes files whose path satisfies any of the given regular expression patterns
244
+ *
245
+ * @param patterns - one or more regular expression patterns
246
+ * @returns the predicate
247
+ * @example
248
+ * ```ts
249
+ * FileHound.create().match(discard('node_modules', '\\.git'));
250
+ * ```
251
+ */
252
+ export declare function discard(...patterns: string[]): FilePredicate;
253
+ /**
254
+ * Matches files by when they were last modified, using a comparison of their
255
+ * age with optional units, such as `'<2 days'` or `'>8h'`. The operators are
256
+ * `<`, `<=`, `>` and `=`, which is the default and compares to the second.
257
+ * The units are minutes (`m`, `min`), hours (`h`) and days (`d`), which is
258
+ * the default.
259
+ *
260
+ * @param expression - the age expression
261
+ * @returns the predicate
262
+ * @throws `TypeError`
263
+ * Thrown if the expression is not a string.
264
+ * @example
265
+ * ```ts
266
+ * FileHound.create().match(modified('<2 days'));
267
+ * ```
268
+ */
269
+ export declare function modified(expression: string): FilePredicate;
270
+ /**
271
+ * Matches files by when they were last accessed, using an age expression as
272
+ * for {@link modified}
273
+ *
274
+ * @param expression - the age expression
275
+ * @returns the predicate
276
+ * @throws `TypeError`
277
+ * Thrown if the expression is not a string.
278
+ */
279
+ export declare function accessed(expression: string): FilePredicate;
280
+ /**
281
+ * Matches files by when their status, such as their permissions, last
282
+ * changed, using an age expression as for {@link modified}
283
+ *
284
+ * @param expression - the age expression
285
+ * @returns the predicate
286
+ * @throws `TypeError`
287
+ * Thrown if the expression is not a string.
288
+ */
289
+ export declare function changed(expression: string): FilePredicate;
290
+ /**
291
+ * Negates a predicate
292
+ *
293
+ * @param fn - the predicate to negate
294
+ * @returns a predicate that matches when the given one does not
295
+ */
296
+ export declare function not(fn: FilePredicate): FilePredicate;
297
+ export {};
@@ -0,0 +1,389 @@
1
+ import { parseAge, parseSize } from 'unit-compare';
2
+ import { from } from './arrays.js';
3
+ // Brands predicates that test a file without I/O, so find() can call testSync
4
+ // and save a promise per file. The symbol is not exported from the package, so
5
+ // any other predicate is assumed to need I/O and is tested with test().
6
+ const sync = Symbol('SyncFilePredicate');
7
+ export function isSyncPredicate(predicate) {
8
+ return predicate[sync] === true;
9
+ }
10
+ // Predicates that need no I/O only implement testSync
11
+ export class AbstractFilePredicate {
12
+ or(f) {
13
+ return new Or(this, f);
14
+ }
15
+ and(f) {
16
+ return new And(this, f);
17
+ }
18
+ not() {
19
+ return new Not(this);
20
+ }
21
+ async test(file) {
22
+ return this.testSync(file);
23
+ }
24
+ }
25
+ export class And extends AbstractFilePredicate {
26
+ #left;
27
+ #right;
28
+ constructor(left, right) {
29
+ super();
30
+ this.#left = left;
31
+ this.#right = right;
32
+ }
33
+ get [sync]() {
34
+ return isSyncPredicate(this.#left) && isSyncPredicate(this.#right);
35
+ }
36
+ async test(file) {
37
+ return await this.#left.test(file) && this.#right.test(file);
38
+ }
39
+ testSync(file) {
40
+ return this.#left.testSync(file) && this.#right.testSync(file);
41
+ }
42
+ }
43
+ export class Not extends AbstractFilePredicate {
44
+ #filePredicate;
45
+ constructor(filePredicate) {
46
+ super();
47
+ this.#filePredicate = filePredicate;
48
+ }
49
+ get [sync]() {
50
+ return isSyncPredicate(this.#filePredicate);
51
+ }
52
+ async test(file) {
53
+ return !await this.#filePredicate.test(file);
54
+ }
55
+ testSync(file) {
56
+ return !this.#filePredicate.testSync(file);
57
+ }
58
+ }
59
+ export class Or extends AbstractFilePredicate {
60
+ #left;
61
+ #right;
62
+ constructor(left, right) {
63
+ super();
64
+ this.#left = left;
65
+ this.#right = right;
66
+ }
67
+ get [sync]() {
68
+ return isSyncPredicate(this.#left) && isSyncPredicate(this.#right);
69
+ }
70
+ async test(file) {
71
+ return await this.#left.test(file) || this.#right.test(file);
72
+ }
73
+ testSync(file) {
74
+ return this.#left.testSync(file) || this.#right.testSync(file);
75
+ }
76
+ }
77
+ export class Extension extends AbstractFilePredicate {
78
+ [sync] = true;
79
+ #extensions;
80
+ constructor(extensions) {
81
+ super();
82
+ this.#extensions = extensions;
83
+ }
84
+ testSync(file) {
85
+ return this.#extensions.includes(file.getPathExtension());
86
+ }
87
+ }
88
+ export class Glob extends AbstractFilePredicate {
89
+ [sync] = true;
90
+ #globPattern;
91
+ constructor(globPattern) {
92
+ super();
93
+ this.#globPattern = globPattern;
94
+ }
95
+ testSync(file) {
96
+ return file.isMatch(this.#globPattern);
97
+ }
98
+ }
99
+ export class TextMatch extends AbstractFilePredicate {
100
+ [sync] = true;
101
+ #pattern;
102
+ #flags;
103
+ constructor(pattern, flags) {
104
+ super();
105
+ this.#pattern = pattern;
106
+ this.#flags = flags;
107
+ }
108
+ testSync(file) {
109
+ return new RegExp(this.#pattern, this.#flags).test(file.getName());
110
+ }
111
+ }
112
+ export class CustomFilter extends AbstractFilePredicate {
113
+ #fn;
114
+ constructor(fn) {
115
+ super();
116
+ this.#fn = fn;
117
+ }
118
+ async test(file) {
119
+ return this.#fn(file);
120
+ }
121
+ testSync(_file) {
122
+ throw new TypeError('applyFilter() filters can only be used with find(). Use applyFilterSync() with findSync()');
123
+ }
124
+ }
125
+ export class CustomFilterSync extends AbstractFilePredicate {
126
+ [sync] = true;
127
+ #fn;
128
+ constructor(fn) {
129
+ super();
130
+ this.#fn = fn;
131
+ }
132
+ testSync(file) {
133
+ return this.#fn(file);
134
+ }
135
+ }
136
+ export class Size extends AbstractFilePredicate {
137
+ #isMatch;
138
+ constructor(sizeExpression) {
139
+ super();
140
+ this.#isMatch = parseSize(sizeExpression);
141
+ }
142
+ async test(file) {
143
+ return this.#isMatch(await file.size());
144
+ }
145
+ testSync(file) {
146
+ return this.#isMatch(file.sizeSync());
147
+ }
148
+ }
149
+ export class Modified extends AbstractFilePredicate {
150
+ #isMatch;
151
+ constructor(expression) {
152
+ super();
153
+ this.#isMatch = parseAge(expression);
154
+ }
155
+ async test(file) {
156
+ return this.#isMatch(await file.lastModified());
157
+ }
158
+ testSync(file) {
159
+ return this.#isMatch(file.lastModifiedSync());
160
+ }
161
+ }
162
+ export class Accessed extends AbstractFilePredicate {
163
+ #isMatch;
164
+ constructor(expression) {
165
+ super();
166
+ this.#isMatch = parseAge(expression);
167
+ }
168
+ async test(file) {
169
+ return this.#isMatch(await file.lastAccessed());
170
+ }
171
+ testSync(file) {
172
+ return this.#isMatch(file.lastAccessedSync());
173
+ }
174
+ }
175
+ export class Changed extends AbstractFilePredicate {
176
+ #isMatch;
177
+ constructor(expression) {
178
+ super();
179
+ this.#isMatch = parseAge(expression);
180
+ }
181
+ async test(file) {
182
+ return this.#isMatch(await file.lastChanged());
183
+ }
184
+ testSync(file) {
185
+ return this.#isMatch(file.lastChangedSync());
186
+ }
187
+ }
188
+ export class MatchAll extends AbstractFilePredicate {
189
+ [sync] = true;
190
+ testSync(_file) {
191
+ return true;
192
+ }
193
+ }
194
+ export function ext(...args) {
195
+ const extensions = from(args).map(cleanExtension);
196
+ return new Extension(extensions);
197
+ }
198
+ /**
199
+ * Matches every file
200
+ *
201
+ * @returns the predicate
202
+ */
203
+ export function matchAll() {
204
+ return new MatchAll();
205
+ }
206
+ // The matchers are typed, but JavaScript callers could still pass a number
207
+ // where V1 accepted one, so they're told what to use instead
208
+ function expressionFor(matcher, expression, example) {
209
+ if (typeof expression !== 'string') {
210
+ throw new TypeError(`${matcher}() takes an expression, such as '${example}'`);
211
+ }
212
+ return expression;
213
+ }
214
+ /**
215
+ * Matches files by size, using a comparison with optional units, such as
216
+ * `'>10k'` or `'<=1mb'`. The operators are `<`, `<=`, `>`, `>=` and `==`,
217
+ * which is the default, and the units are `b`, `k`, `m`, `g` and `t`, in
218
+ * multiples of 1024. Use {@link sizeEquals} for an exact number of bytes.
219
+ *
220
+ * @param expression - the size expression
221
+ * @returns the predicate
222
+ * @throws `TypeError`
223
+ * Thrown if the expression is not a string.
224
+ * @example
225
+ * ```ts
226
+ * FileHound.create().match(size('>1mb'));
227
+ * ```
228
+ */
229
+ export function size(expression) {
230
+ return new Size(expressionFor('size', expression, '>1kb'));
231
+ }
232
+ /**
233
+ * Matches files of an exact size
234
+ *
235
+ * @param bytes - the size in bytes
236
+ * @returns the predicate
237
+ * @throws `RangeError`
238
+ * Thrown if bytes is negative or not an integer.
239
+ * @example
240
+ * ```ts
241
+ * FileHound.create().match(sizeEquals(1024));
242
+ * ```
243
+ */
244
+ export function sizeEquals(bytes) {
245
+ if (!Number.isSafeInteger(bytes) || bytes < 0) {
246
+ throw new RangeError('Size must be a non-negative integer number of bytes');
247
+ }
248
+ return new Size(bytes);
249
+ }
250
+ /**
251
+ * Matches files with a size of zero bytes
252
+ *
253
+ * @returns the predicate
254
+ */
255
+ export function isEmpty() {
256
+ return new Size(0);
257
+ }
258
+ /**
259
+ * Matches files whose path, relative to the search path, satisfies a glob
260
+ * pattern. Patterns follow Node's `path.matchesGlob` and `fs.glob` rules:
261
+ * `*.json` matches only the top level of the search path, and a leading `**`
262
+ * segment matches at any depth. Wildcards, including `**`, do not match names
263
+ * beginning with a dot.
264
+ *
265
+ * @param globPattern - the glob pattern
266
+ * @returns the predicate
267
+ * @example
268
+ * ```ts
269
+ * FileHound.create().match(glob('*.json'));
270
+ * ```
271
+ */
272
+ export function glob(globPattern) {
273
+ return new Glob(globPattern);
274
+ }
275
+ /**
276
+ * Matches files using a custom function, which may be asynchronous. Can only
277
+ * be used with {@link FileHound.find}; use {@link applyFilterSync} with
278
+ * {@link FileHound.findSync}.
279
+ *
280
+ * @param fn - returns, or fulfils with, true for files to include
281
+ * @returns the predicate
282
+ * @example
283
+ * ```ts
284
+ * FileHound.create().match(applyFilter(async file => await file.size() > 0));
285
+ * ```
286
+ */
287
+ export function applyFilter(fn) {
288
+ return new CustomFilter(fn);
289
+ }
290
+ /**
291
+ * Matches files using a synchronous custom function. Can be used with both
292
+ * {@link FileHound.find} and {@link FileHound.findSync}.
293
+ *
294
+ * @param fn - returns true for files to include
295
+ * @returns the predicate
296
+ * @example
297
+ * ```ts
298
+ * FileHound.create().match(applyFilterSync(file => file.sizeSync() > 0));
299
+ * ```
300
+ */
301
+ export function applyFilterSync(fn) {
302
+ return new CustomFilterSync(fn);
303
+ }
304
+ /**
305
+ * Matches files whose path satisfies a regular expression pattern
306
+ *
307
+ * @param pattern - the regular expression pattern
308
+ * @returns the predicate
309
+ */
310
+ export function like(pattern) {
311
+ return new TextMatch(pattern);
312
+ }
313
+ /**
314
+ * Excludes files whose path satisfies any of the given regular expression patterns
315
+ *
316
+ * @param patterns - one or more regular expression patterns
317
+ * @returns the predicate
318
+ * @example
319
+ * ```ts
320
+ * FileHound.create().match(discard('node_modules', '\\.git'));
321
+ * ```
322
+ */
323
+ export function discard(...patterns) {
324
+ if (patterns.length === 1) {
325
+ return new TextMatch(patterns[0]).not();
326
+ }
327
+ return patterns
328
+ .map((pattern) => new TextMatch(pattern))
329
+ .reduce((a, b) => a.or(b))
330
+ .not();
331
+ }
332
+ function cleanExtension(fileExtension) {
333
+ if (fileExtension.startsWith('.')) {
334
+ return fileExtension.slice(1);
335
+ }
336
+ return fileExtension;
337
+ }
338
+ /**
339
+ * Matches files by when they were last modified, using a comparison of their
340
+ * age with optional units, such as `'<2 days'` or `'>8h'`. The operators are
341
+ * `<`, `<=`, `>` and `=`, which is the default and compares to the second.
342
+ * The units are minutes (`m`, `min`), hours (`h`) and days (`d`), which is
343
+ * the default.
344
+ *
345
+ * @param expression - the age expression
346
+ * @returns the predicate
347
+ * @throws `TypeError`
348
+ * Thrown if the expression is not a string.
349
+ * @example
350
+ * ```ts
351
+ * FileHound.create().match(modified('<2 days'));
352
+ * ```
353
+ */
354
+ export function modified(expression) {
355
+ return new Modified(expressionFor('modified', expression, '<2 days'));
356
+ }
357
+ /**
358
+ * Matches files by when they were last accessed, using an age expression as
359
+ * for {@link modified}
360
+ *
361
+ * @param expression - the age expression
362
+ * @returns the predicate
363
+ * @throws `TypeError`
364
+ * Thrown if the expression is not a string.
365
+ */
366
+ export function accessed(expression) {
367
+ return new Accessed(expressionFor('accessed', expression, '<2 days'));
368
+ }
369
+ /**
370
+ * Matches files by when their status, such as their permissions, last
371
+ * changed, using an age expression as for {@link modified}
372
+ *
373
+ * @param expression - the age expression
374
+ * @returns the predicate
375
+ * @throws `TypeError`
376
+ * Thrown if the expression is not a string.
377
+ */
378
+ export function changed(expression) {
379
+ return new Changed(expressionFor('changed', expression, '<2 days'));
380
+ }
381
+ /**
382
+ * Negates a predicate
383
+ *
384
+ * @param fn - the predicate to negate
385
+ * @returns a predicate that matches when the given one does not
386
+ */
387
+ export function not(fn) {
388
+ return new Not(fn);
389
+ }
@@ -0,0 +1,4 @@
1
+ import { File } from '../file.js';
2
+ import type { FilePredicate } from '../matchers.js';
3
+ import { type WalkOptions } from './walk.js';
4
+ export declare function walkAsync(dir: string, matcher: FilePredicate, opts: WalkOptions): AsyncGenerator<File[]>;