UNPKG

15.2 kBTypeScriptView Raw
1/// <reference types="node" />
2import * as fs from "fs";
3/**
4 * Comparison options.
5 */
6export interface Options {
7 /**
8 * Properties to be used in various extension points ie. result builder.
9 */
10 [key: string]: any;
11 /**
12 * Compares files by size. Defaults to 'false'.
13 *
14 * Usually one of `compareSize` or `compareContent` options has to be activated. Otherwise files are compared by name disregarding size or content.
15 */
16 compareSize?: boolean;
17 /**
18 * Compares files by content. Defaults to 'false'.
19 *
20 * Usually one of `compareSize` or `compareContent` options has to be activated. Otherwise files are compared by name disregarding size or content.
21 */
22 compareContent?: boolean;
23 /**
24 * Compares files by date of modification (stat.mtime). Defaults to 'false'.
25 *
26 * Also see [[Options.dateTolerance]].
27 */
28 compareDate?: boolean;
29 /**
30 * Two files are considered to have the same date if the difference between their modification dates fits within date tolerance. Defaults to 1000 ms.
31 */
32 dateTolerance?: number;
33 /**
34 * Compares entries by symlink. Defaults to 'false'.
35
36 * If this option is enabled two entries must have the same type in order to be considered equal.
37 * They have to be either two fies, two directories or two symlinks.
38 *
39 * If left entry is a file and right entry is a symlink, they are considered distinct disregarding the content of the file.
40 *
41 * Further if both entries are symlinks they need to have the same link value. For example if one symlink points to '/x/b.txt' and the other to '/x/../x/b.txt' the symlinks are considered distinct even if they point to the same file.
42 */
43 compareSymlink?: boolean;
44 /**
45 * Skips sub directories. Defaults to 'false'.
46 */
47 skipSubdirs?: boolean;
48 /**
49 * Ignore empty directories. Defaults to 'false'.
50 */
51 skipEmptyDirs?: boolean;
52 /**
53 * Ignore symbolic links. Defaults to 'false'.
54 */
55 skipSymlinks?: boolean;
56 /**
57 * Ignores case when comparing names. Defaults to 'false'.
58 */
59 ignoreCase?: boolean;
60 /**
61 * Toggles presence of diffSet in output. If true, only statistics are provided. Use this when comparing large number of files to avoid out of memory situations. Defaults to 'false'.
62 */
63 noDiffSet?: boolean;
64 /**
65 * File name filter. Comma separated minimatch patterns. See [Glob patterns](https://github.com/gliviu/dir-compare#glob-patterns).
66 */
67 includeFilter?: string;
68 /**
69 * File/directory name exclude filter. Comma separated minimatch patterns. See [Glob patterns](https://github.com/gliviu/dir-compare#glob-patterns)
70 */
71 excludeFilter?: string;
72 /**
73 * Handle permission denied errors. Defaults to 'false'.
74 *
75 * By default when some entry cannot be read due to `EACCES` error the comparison will
76 * stop immediately with an exception.
77 *
78 * If `handlePermissionDenied` is set to true the comparison will continue when unreadable entries are encountered.
79 *
80 * Offending entries will be reported within [[Difference.permissionDeniedState]], [[Difference.reason]] and [[Result.permissionDenied]].
81 *
82 * Lets consider we want to compare two identical folders `A` and `B` with `B/dir2` being unreadable for the current user.
83 * ```
84 * A B
85 * ├── dir1 ├── dir1
86 * ├──── file1 ├──── file1
87 * ├── dir2 ├── dir2 (permission denied)
88 * └─────file2 └─────file2
89 * ```
90 *
91 * [[Result.diffSet]] will look like:
92 *
93 * |relativePath |path1 |path2 | state |reason |permissionDeniedState|
94 * |--------------|---------|---------|------------|------------------------|---------------------|
95 * |[/] |dir1 |dir1 |`equal` | | |
96 * |[/dir1] |file1 |file1 |`equal` | | |
97 * |[/] |dir2 |dir2 |`distinct` | `permission-denied` |`access-error-right` |
98 * |[/dir2] |file2 |missing |`left` | | |
99 *
100 * And [[Result.permissionDenied]] statistics look like - left: 0, right: 1, distinct: 0, total: 1
101 *
102 */
103 handlePermissionDenied?: boolean;
104 /**
105 * Callback for constructing result. Called for each compared entry pair.
106 *
107 * Updates 'statistics' and 'diffSet'.
108 *
109 * See [Custom result builder](https://github.com/gliviu/dir-compare#custom-result-builder).
110 */
111 resultBuilder?: ResultBuilder;
112 /**
113 * File comparison handler. See [Custom file comparators](https://github.com/gliviu/dir-compare#custom-file-content-comparators).
114 */
115 compareFileSync?: CompareFileSync;
116 /**
117 * File comparison handler. See [Custom file comparators](https://github.com/gliviu/dir-compare#custom-file-content-comparators).
118 */
119 compareFileAsync?: CompareFileAsync;
120 /**
121 * Entry name comparison handler. See [Custom name comparators](https://github.com/gliviu/dir-compare#custom-name-comparators).
122 */
123 compareNameHandler?: CompareNameHandler;
124}
125/**
126 * Callback for constructing result. Called for each compared entry pair.
127 *
128 * Updates 'statistics' and 'diffSet'.
129 */
130export declare type ResultBuilder =
131/**
132 * @param entry1 Left entry.
133 * @param entry2 Right entry.
134 * @param state See [[DifferenceState]].
135 * @param level Depth level relative to root dir.
136 * @param relativePath Path relative to root dir.
137 * @param statistics Statistics to be updated.
138 * @param diffSet Status per each entry to be appended.
139 * Do not append if [[Options.noDiffSet]] is false.
140 * @param reason See [[Reason]]. Not available if entries are equal.
141 */
142(entry1: Entry | undefined, entry2: Entry | undefined, state: DifferenceState, level: number, relativePath: string, options: Options, statistics: Statistics, diffSet: Array<Difference> | undefined, reason: Reason | undefined) => void;
143export interface Entry {
144 name: string;
145 absolutePath: string;
146 path: string;
147 stat: fs.Stats;
148 lstat: fs.Stats;
149 symlink: boolean;
150 /**
151 * True when this entry is not readable.
152 * This value is set only when [[Options.handlePermissionDenied]] is enabled.
153 */
154 isPermissionDenied: boolean;
155}
156/**
157 * Comparison result.
158 */
159export interface Result extends Statistics {
160 /**
161 * List of changes (present if [[Options.noDiffSet]] is false).
162 */
163 diffSet?: Array<Difference>;
164}
165export interface Statistics {
166 /**
167 * Any property is allowed if default result builder is not used.
168 */
169 [key: string]: any;
170 /**
171 * True if directories are identical.
172 */
173 same: boolean;
174 /**
175 * Number of distinct entries.
176 */
177 distinct: number;
178 /**
179 * Number of equal entries.
180 */
181 equal: number;
182 /**
183 * Number of entries only in path1.
184 */
185 left: number;
186 /**
187 * Number of entries only in path2.
188 */
189 right: number;
190 /**
191 * Total number of differences (distinct+left+right).
192 */
193 differences: number;
194 /**
195 * Total number of entries (differences+equal).
196 */
197 total: number;
198 /**
199 * Number of distinct files.
200 */
201 distinctFiles: number;
202 /**
203 * Number of equal files.
204 */
205 equalFiles: number;
206 /**
207 * Number of files only in path1.
208 */
209 leftFiles: number;
210 /**
211 * Number of files only in path2
212 */
213 rightFiles: number;
214 /**
215 * Total number of different files (distinctFiles+leftFiles+rightFiles).
216 */
217 differencesFiles: number;
218 /**
219 * Total number of files (differencesFiles+equalFiles).
220 */
221 totalFiles: number;
222 /**
223 * Number of distinct directories.
224 */
225 distinctDirs: number;
226 /**
227 * Number of equal directories.
228 */
229 equalDirs: number;
230 /**
231 * Number of directories only in path1.
232 */
233 leftDirs: number;
234 /**
235 * Number of directories only in path2.
236 */
237 rightDirs: number;
238 /**
239 * Total number of different directories (distinctDirs+leftDirs+rightDirs).
240 */
241 differencesDirs: number;
242 /**
243 * Total number of directories (differencesDirs+equalDirs).
244 */
245 totalDirs: number;
246 /**
247 * Stats about broken links.
248 */
249 brokenLinks: BrokenLinksStatistics;
250 /**
251 * Statistics available if 'compareSymlink' options is used.
252 */
253 symlinks?: SymlinkStatistics;
254 /**
255 * Stats about entries that could not be accessed.
256 */
257 permissionDenied: PermissionDeniedStatistics;
258}
259export interface BrokenLinksStatistics {
260 /**
261 * Number of broken links only in path1
262 */
263 leftBrokenLinks: number;
264 /**
265 * Number of broken links only in path2
266 */
267 rightBrokenLinks: number;
268 /**
269 * Number of broken links with same name appearing in both path1 and path2 (leftBrokenLinks + rightBrokenLinks + distinctBrokenLinks)
270 */
271 distinctBrokenLinks: number;
272 /**
273 * Total number of broken links
274 */
275 totalBrokenLinks: number;
276}
277export interface PermissionDeniedStatistics {
278 /**
279 * Number of forbidden entries found only in path1
280 */
281 leftPermissionDenied: number;
282 /**
283 * Number of forbidden entries found only in path2
284 */
285 rightPermissionDenied: number;
286 /**
287 * Number of forbidden entries with same name appearing in both path1 and path2 (leftPermissionDenied + rightPermissionDenied + distinctPermissionDenied)
288 */
289 distinctPermissionDenied: number;
290 /**
291 * Total number of forbidden entries
292 */
293 totalPermissionDenied: number;
294}
295export interface SymlinkStatistics {
296 /**
297 * Number of distinct links.
298 */
299 distinctSymlinks: number;
300 /**
301 * Number of equal links.
302 */
303 equalSymlinks: number;
304 /**
305 * Number of links only in path1.
306 */
307 leftSymlinks: number;
308 /**
309 * Number of links only in path2
310 */
311 rightSymlinks: number;
312 /**
313 * Total number of different links (distinctSymlinks+leftSymlinks+rightSymlinks).
314 */
315 differencesSymlinks: number;
316 /**
317 * Total number of links (differencesSymlinks+equalSymlinks).
318 */
319 totalSymlinks: number;
320}
321/**
322 * State of left/right entries relative to each other.
323 * * `equal` - Identical entries are found in both left/right dirs.
324 * * `left` - Entry is found only in left dir.
325 * * `right` - Entry is found only in right dir.
326 * * `distinct` - Entries exist in both left/right dir but have different content. See [[Difference.reason]] to understan why entries are considered distinct.
327 */
328export declare type DifferenceState = "equal" | "left" | "right" | "distinct";
329/**
330 * Permission related state of left/right entries. Available only when [[Options.handlePermissionDenied]] is enabled.
331 * * `access-ok` - Both entries are accessible.
332 * * `access-error-both` - Neither entry can be accessed.
333 * * `access-error-left` - Left entry cannot be accessed.
334 * * `access-error-right` - Right entry cannot be accessed.
335 */
336export declare type PermissionDeniedState = "access-ok" | "access-error-both" | "access-error-left" | "access-error-right";
337/**
338 * Type of entry.
339 */
340export declare type DifferenceType = "missing" | "file" | "directory" | "broken-link";
341/**
342 * Provides reason when two identically named entries are distinct.
343 *
344 * Not available if entries are equal.
345 *
346 * * `different-size` - Files differ in size.
347 * * `different-date - Entry dates are different. Used when [[Options.compareDate]] is `true`.
348 * * `different-content` - File contents are different. Used when [[Options.compareContent]] is `true`.
349 * * `broken-link` - Both left/right entries are broken links.
350 * * `different-symlink` - Symlinks are different. See [[Options.compareSymlink]] for details.
351 * * `permission-denied` - One or both left/right entries are not accessible. See [[Options.handlePermissionDenied]] for details.
352 */
353export declare type Reason = undefined | "different-size" | "different-date" | "different-content" | "broken-link" | 'different-symlink' | 'permission-denied';
354export interface Difference {
355 /**
356 * Any property is allowed if default result builder is not used.
357 */
358 [key: string]: any;
359 /**
360 * Path not including file/directory name; can be relative or absolute depending on call to compare().
361 * Is undefined if missing on the left side.
362 */
363 path1?: string;
364 /**
365 * Path not including file/directory name; can be relative or absolute depending on call to compare().
366 * Is undefined if missing on the right side.
367 */
368 path2?: string;
369 /**
370 * Path relative to root dir.
371 */
372 relativePath: string;
373 /**
374 * Left file/directory name.
375 * Is undefined if missing on the left side.
376 */
377 name1?: string;
378 /**
379 * Right file/directory name.
380 * Is undefined if missing on the right side.
381 */
382 name2?: string;
383 /**
384 * See [[DifferenceState]]
385 */
386 state: DifferenceState;
387 /**
388 * Permission related state of left/right entries.
389 */
390 permissionDeniedState: PermissionDeniedState;
391 /**
392 * Type of left entry.
393 * Is undefined if missing on the left side.
394 */
395 type1: DifferenceType;
396 /**
397 * Type of right entry.
398 * Is undefined if missing on the right side.
399 */
400 type2: DifferenceType;
401 /**
402 * Left file size.
403 * Is undefined if missing on the left side.
404 */
405 size1?: number;
406 /**
407 * Right file size.
408 * Is undefined if missing on the right side.
409 */
410 size2?: number;
411 /**
412 * Left entry modification date (stat.mtime).
413 * Is undefined if missing on the left side.
414 */
415 date1?: number;
416 /**
417 * Right entry modification date (stat.mtime).
418 * Is undefined if missing on the right side.
419 */
420 date2?: number;
421 /**
422 * Depth level relative to root dir.
423 */
424 level: number;
425 /**
426 * Provides reason when two identically named entries are distinct.
427 */
428 reason: Reason;
429}
430/**
431 * Synchronous file content comparison handler.
432 */
433export declare type CompareFileSync = (path1: string, stat1: fs.Stats, path2: string, stat2: fs.Stats, options: Options) => boolean;
434/**
435 * Asynchronous file content comparison handler.
436 */
437export declare type CompareFileAsync = (path1: string, stat1: fs.Stats, path2: string, stat2: fs.Stats, options: Options) => Promise<boolean>;
438export interface CompareFileHandler {
439 compareSync: CompareFileSync;
440 compareAsync: CompareFileAsync;
441}
442/**
443 * Compares the names of two entries.
444 * The comparison should be dependent on received options (ie. case sensitive, ...).
445 * Returns 0 if names are identical, -1 if name1<name2, 1 if name1>name2.
446 */
447export declare type CompareNameHandler = (name1: string, name2: string, options: Options) => 0 | 1 | -1;
448//# sourceMappingURL=types.d.ts.map
\No newline at end of file