source: imaps-frontend/node_modules/chokidar/handler.js@ 0c6b92a

main
Last change on this file since 0c6b92a was 0c6b92a, checked in by stefan toskovski <stefantoska84@…>, 5 weeks ago

Pred finalna verzija

  • Property mode set to 100644
File size: 24.6 KB
RevLine 
[0c6b92a]1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.NodeFsHandler = exports.EVENTS = exports.isIBMi = exports.isLinux = exports.isMacos = exports.isWindows = exports.IDENTITY_FN = exports.EMPTY_FN = exports.STR_CLOSE = exports.STR_END = exports.STR_DATA = void 0;
4const fs_1 = require("fs");
5const promises_1 = require("fs/promises");
6const sysPath = require("path");
7const os_1 = require("os");
8exports.STR_DATA = 'data';
9exports.STR_END = 'end';
10exports.STR_CLOSE = 'close';
11const EMPTY_FN = () => { };
12exports.EMPTY_FN = EMPTY_FN;
13const IDENTITY_FN = (val) => val;
14exports.IDENTITY_FN = IDENTITY_FN;
15const pl = process.platform;
16exports.isWindows = pl === 'win32';
17exports.isMacos = pl === 'darwin';
18exports.isLinux = pl === 'linux';
19exports.isIBMi = (0, os_1.type)() === 'OS400';
20exports.EVENTS = {
21 ALL: 'all',
22 READY: 'ready',
23 ADD: 'add',
24 CHANGE: 'change',
25 ADD_DIR: 'addDir',
26 UNLINK: 'unlink',
27 UNLINK_DIR: 'unlinkDir',
28 RAW: 'raw',
29 ERROR: 'error',
30};
31const EV = exports.EVENTS;
32const THROTTLE_MODE_WATCH = 'watch';
33const statMethods = { lstat: promises_1.lstat, stat: promises_1.stat };
34const KEY_LISTENERS = 'listeners';
35const KEY_ERR = 'errHandlers';
36const KEY_RAW = 'rawEmitters';
37const HANDLER_KEYS = [KEY_LISTENERS, KEY_ERR, KEY_RAW];
38// prettier-ignore
39const binaryExtensions = new Set([
40 '3dm', '3ds', '3g2', '3gp', '7z', 'a', 'aac', 'adp', 'afdesign', 'afphoto', 'afpub', 'ai',
41 'aif', 'aiff', 'alz', 'ape', 'apk', 'appimage', 'ar', 'arj', 'asf', 'au', 'avi',
42 'bak', 'baml', 'bh', 'bin', 'bk', 'bmp', 'btif', 'bz2', 'bzip2',
43 'cab', 'caf', 'cgm', 'class', 'cmx', 'cpio', 'cr2', 'cur', 'dat', 'dcm', 'deb', 'dex', 'djvu',
44 'dll', 'dmg', 'dng', 'doc', 'docm', 'docx', 'dot', 'dotm', 'dra', 'DS_Store', 'dsk', 'dts',
45 'dtshd', 'dvb', 'dwg', 'dxf',
46 'ecelp4800', 'ecelp7470', 'ecelp9600', 'egg', 'eol', 'eot', 'epub', 'exe',
47 'f4v', 'fbs', 'fh', 'fla', 'flac', 'flatpak', 'fli', 'flv', 'fpx', 'fst', 'fvt',
48 'g3', 'gh', 'gif', 'graffle', 'gz', 'gzip',
49 'h261', 'h263', 'h264', 'icns', 'ico', 'ief', 'img', 'ipa', 'iso',
50 'jar', 'jpeg', 'jpg', 'jpgv', 'jpm', 'jxr', 'key', 'ktx',
51 'lha', 'lib', 'lvp', 'lz', 'lzh', 'lzma', 'lzo',
52 'm3u', 'm4a', 'm4v', 'mar', 'mdi', 'mht', 'mid', 'midi', 'mj2', 'mka', 'mkv', 'mmr', 'mng',
53 'mobi', 'mov', 'movie', 'mp3',
54 'mp4', 'mp4a', 'mpeg', 'mpg', 'mpga', 'mxu',
55 'nef', 'npx', 'numbers', 'nupkg',
56 'o', 'odp', 'ods', 'odt', 'oga', 'ogg', 'ogv', 'otf', 'ott',
57 'pages', 'pbm', 'pcx', 'pdb', 'pdf', 'pea', 'pgm', 'pic', 'png', 'pnm', 'pot', 'potm',
58 'potx', 'ppa', 'ppam',
59 'ppm', 'pps', 'ppsm', 'ppsx', 'ppt', 'pptm', 'pptx', 'psd', 'pya', 'pyc', 'pyo', 'pyv',
60 'qt',
61 'rar', 'ras', 'raw', 'resources', 'rgb', 'rip', 'rlc', 'rmf', 'rmvb', 'rpm', 'rtf', 'rz',
62 's3m', 's7z', 'scpt', 'sgi', 'shar', 'snap', 'sil', 'sketch', 'slk', 'smv', 'snk', 'so',
63 'stl', 'suo', 'sub', 'swf',
64 'tar', 'tbz', 'tbz2', 'tga', 'tgz', 'thmx', 'tif', 'tiff', 'tlz', 'ttc', 'ttf', 'txz',
65 'udf', 'uvh', 'uvi', 'uvm', 'uvp', 'uvs', 'uvu',
66 'viv', 'vob',
67 'war', 'wav', 'wax', 'wbmp', 'wdp', 'weba', 'webm', 'webp', 'whl', 'wim', 'wm', 'wma',
68 'wmv', 'wmx', 'woff', 'woff2', 'wrm', 'wvx',
69 'xbm', 'xif', 'xla', 'xlam', 'xls', 'xlsb', 'xlsm', 'xlsx', 'xlt', 'xltm', 'xltx', 'xm',
70 'xmind', 'xpi', 'xpm', 'xwd', 'xz',
71 'z', 'zip', 'zipx',
72]);
73const isBinaryPath = (filePath) => binaryExtensions.has(sysPath.extname(filePath).slice(1).toLowerCase());
74// TODO: emit errors properly. Example: EMFILE on Macos.
75const foreach = (val, fn) => {
76 if (val instanceof Set) {
77 val.forEach(fn);
78 }
79 else {
80 fn(val);
81 }
82};
83const addAndConvert = (main, prop, item) => {
84 let container = main[prop];
85 if (!(container instanceof Set)) {
86 main[prop] = container = new Set([container]);
87 }
88 container.add(item);
89};
90const clearItem = (cont) => (key) => {
91 const set = cont[key];
92 if (set instanceof Set) {
93 set.clear();
94 }
95 else {
96 delete cont[key];
97 }
98};
99const delFromSet = (main, prop, item) => {
100 const container = main[prop];
101 if (container instanceof Set) {
102 container.delete(item);
103 }
104 else if (container === item) {
105 delete main[prop];
106 }
107};
108const isEmptySet = (val) => (val instanceof Set ? val.size === 0 : !val);
109const FsWatchInstances = new Map();
110/**
111 * Instantiates the fs_watch interface
112 * @param path to be watched
113 * @param options to be passed to fs_watch
114 * @param listener main event handler
115 * @param errHandler emits info about errors
116 * @param emitRaw emits raw event data
117 * @returns {NativeFsWatcher}
118 */
119function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
120 const handleEvent = (rawEvent, evPath) => {
121 listener(path);
122 emitRaw(rawEvent, evPath, { watchedPath: path });
123 // emit based on events occurring for files from a directory's watcher in
124 // case the file's watcher misses it (and rely on throttling to de-dupe)
125 if (evPath && path !== evPath) {
126 fsWatchBroadcast(sysPath.resolve(path, evPath), KEY_LISTENERS, sysPath.join(path, evPath));
127 }
128 };
129 try {
130 return (0, fs_1.watch)(path, {
131 persistent: options.persistent,
132 }, handleEvent);
133 }
134 catch (error) {
135 errHandler(error);
136 return undefined;
137 }
138}
139/**
140 * Helper for passing fs_watch event data to a collection of listeners
141 * @param fullPath absolute path bound to fs_watch instance
142 */
143const fsWatchBroadcast = (fullPath, listenerType, val1, val2, val3) => {
144 const cont = FsWatchInstances.get(fullPath);
145 if (!cont)
146 return;
147 foreach(cont[listenerType], (listener) => {
148 listener(val1, val2, val3);
149 });
150};
151/**
152 * Instantiates the fs_watch interface or binds listeners
153 * to an existing one covering the same file system entry
154 * @param path
155 * @param fullPath absolute path
156 * @param options to be passed to fs_watch
157 * @param handlers container for event listener functions
158 */
159const setFsWatchListener = (path, fullPath, options, handlers) => {
160 const { listener, errHandler, rawEmitter } = handlers;
161 let cont = FsWatchInstances.get(fullPath);
162 let watcher;
163 if (!options.persistent) {
164 watcher = createFsWatchInstance(path, options, listener, errHandler, rawEmitter);
165 if (!watcher)
166 return;
167 return watcher.close.bind(watcher);
168 }
169 if (cont) {
170 addAndConvert(cont, KEY_LISTENERS, listener);
171 addAndConvert(cont, KEY_ERR, errHandler);
172 addAndConvert(cont, KEY_RAW, rawEmitter);
173 }
174 else {
175 watcher = createFsWatchInstance(path, options, fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), errHandler, // no need to use broadcast here
176 fsWatchBroadcast.bind(null, fullPath, KEY_RAW));
177 if (!watcher)
178 return;
179 watcher.on(EV.ERROR, async (error) => {
180 const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR);
181 if (cont)
182 cont.watcherUnusable = true; // documented since Node 10.4.1
183 // Workaround for https://github.com/joyent/node/issues/4337
184 if (exports.isWindows && error.code === 'EPERM') {
185 try {
186 const fd = await (0, promises_1.open)(path, 'r');
187 await fd.close();
188 broadcastErr(error);
189 }
190 catch (err) {
191 // do nothing
192 }
193 }
194 else {
195 broadcastErr(error);
196 }
197 });
198 cont = {
199 listeners: listener,
200 errHandlers: errHandler,
201 rawEmitters: rawEmitter,
202 watcher,
203 };
204 FsWatchInstances.set(fullPath, cont);
205 }
206 // const index = cont.listeners.indexOf(listener);
207 // removes this instance's listeners and closes the underlying fs_watch
208 // instance if there are no more listeners left
209 return () => {
210 delFromSet(cont, KEY_LISTENERS, listener);
211 delFromSet(cont, KEY_ERR, errHandler);
212 delFromSet(cont, KEY_RAW, rawEmitter);
213 if (isEmptySet(cont.listeners)) {
214 // Check to protect against issue gh-730.
215 // if (cont.watcherUnusable) {
216 cont.watcher.close();
217 // }
218 FsWatchInstances.delete(fullPath);
219 HANDLER_KEYS.forEach(clearItem(cont));
220 // @ts-ignore
221 cont.watcher = undefined;
222 Object.freeze(cont);
223 }
224 };
225};
226// fs_watchFile helpers
227// object to hold per-process fs_watchFile instances
228// (may be shared across chokidar FSWatcher instances)
229const FsWatchFileInstances = new Map();
230/**
231 * Instantiates the fs_watchFile interface or binds listeners
232 * to an existing one covering the same file system entry
233 * @param path to be watched
234 * @param fullPath absolute path
235 * @param options options to be passed to fs_watchFile
236 * @param handlers container for event listener functions
237 * @returns closer
238 */
239const setFsWatchFileListener = (path, fullPath, options, handlers) => {
240 const { listener, rawEmitter } = handlers;
241 let cont = FsWatchFileInstances.get(fullPath);
242 // let listeners = new Set();
243 // let rawEmitters = new Set();
244 const copts = cont && cont.options;
245 if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) {
246 // "Upgrade" the watcher to persistence or a quicker interval.
247 // This creates some unlikely edge case issues if the user mixes
248 // settings in a very weird way, but solving for those cases
249 // doesn't seem worthwhile for the added complexity.
250 // listeners = cont.listeners;
251 // rawEmitters = cont.rawEmitters;
252 (0, fs_1.unwatchFile)(fullPath);
253 cont = undefined;
254 }
255 if (cont) {
256 addAndConvert(cont, KEY_LISTENERS, listener);
257 addAndConvert(cont, KEY_RAW, rawEmitter);
258 }
259 else {
260 // TODO
261 // listeners.add(listener);
262 // rawEmitters.add(rawEmitter);
263 cont = {
264 listeners: listener,
265 rawEmitters: rawEmitter,
266 options,
267 watcher: (0, fs_1.watchFile)(fullPath, options, (curr, prev) => {
268 foreach(cont.rawEmitters, (rawEmitter) => {
269 rawEmitter(EV.CHANGE, fullPath, { curr, prev });
270 });
271 const currmtime = curr.mtimeMs;
272 if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) {
273 foreach(cont.listeners, (listener) => listener(path, curr));
274 }
275 }),
276 };
277 FsWatchFileInstances.set(fullPath, cont);
278 }
279 // const index = cont.listeners.indexOf(listener);
280 // Removes this instance's listeners and closes the underlying fs_watchFile
281 // instance if there are no more listeners left.
282 return () => {
283 delFromSet(cont, KEY_LISTENERS, listener);
284 delFromSet(cont, KEY_RAW, rawEmitter);
285 if (isEmptySet(cont.listeners)) {
286 FsWatchFileInstances.delete(fullPath);
287 (0, fs_1.unwatchFile)(fullPath);
288 cont.options = cont.watcher = undefined;
289 Object.freeze(cont);
290 }
291 };
292};
293/**
294 * @mixin
295 */
296class NodeFsHandler {
297 constructor(fsW) {
298 this.fsw = fsW;
299 this._boundHandleError = (error) => fsW._handleError(error);
300 }
301 /**
302 * Watch file for changes with fs_watchFile or fs_watch.
303 * @param path to file or dir
304 * @param listener on fs change
305 * @returns closer for the watcher instance
306 */
307 _watchWithNodeFs(path, listener) {
308 const opts = this.fsw.options;
309 const directory = sysPath.dirname(path);
310 const basename = sysPath.basename(path);
311 const parent = this.fsw._getWatchedDir(directory);
312 parent.add(basename);
313 const absolutePath = sysPath.resolve(path);
314 const options = {
315 persistent: opts.persistent,
316 };
317 if (!listener)
318 listener = exports.EMPTY_FN;
319 let closer;
320 if (opts.usePolling) {
321 const enableBin = opts.interval !== opts.binaryInterval;
322 options.interval = enableBin && isBinaryPath(basename) ? opts.binaryInterval : opts.interval;
323 closer = setFsWatchFileListener(path, absolutePath, options, {
324 listener,
325 rawEmitter: this.fsw._emitRaw,
326 });
327 }
328 else {
329 closer = setFsWatchListener(path, absolutePath, options, {
330 listener,
331 errHandler: this._boundHandleError,
332 rawEmitter: this.fsw._emitRaw,
333 });
334 }
335 return closer;
336 }
337 /**
338 * Watch a file and emit add event if warranted.
339 * @returns closer for the watcher instance
340 */
341 _handleFile(file, stats, initialAdd) {
342 if (this.fsw.closed) {
343 return;
344 }
345 const dirname = sysPath.dirname(file);
346 const basename = sysPath.basename(file);
347 const parent = this.fsw._getWatchedDir(dirname);
348 // stats is always present
349 let prevStats = stats;
350 // if the file is already being watched, do nothing
351 if (parent.has(basename))
352 return;
353 const listener = async (path, newStats) => {
354 if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5))
355 return;
356 if (!newStats || newStats.mtimeMs === 0) {
357 try {
358 const newStats = await (0, promises_1.stat)(file);
359 if (this.fsw.closed)
360 return;
361 // Check that change event was not fired because of changed only accessTime.
362 const at = newStats.atimeMs;
363 const mt = newStats.mtimeMs;
364 if (!at || at <= mt || mt !== prevStats.mtimeMs) {
365 this.fsw._emit(EV.CHANGE, file, newStats);
366 }
367 if ((exports.isMacos || exports.isLinux) && prevStats.ino !== newStats.ino) {
368 this.fsw._closeFile(path);
369 prevStats = newStats;
370 const closer = this._watchWithNodeFs(file, listener);
371 if (closer)
372 this.fsw._addPathCloser(path, closer);
373 }
374 else {
375 prevStats = newStats;
376 }
377 }
378 catch (error) {
379 // Fix issues where mtime is null but file is still present
380 this.fsw._remove(dirname, basename);
381 }
382 // add is about to be emitted if file not already tracked in parent
383 }
384 else if (parent.has(basename)) {
385 // Check that change event was not fired because of changed only accessTime.
386 const at = newStats.atimeMs;
387 const mt = newStats.mtimeMs;
388 if (!at || at <= mt || mt !== prevStats.mtimeMs) {
389 this.fsw._emit(EV.CHANGE, file, newStats);
390 }
391 prevStats = newStats;
392 }
393 };
394 // kick off the watcher
395 const closer = this._watchWithNodeFs(file, listener);
396 // emit an add event if we're supposed to
397 if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) {
398 if (!this.fsw._throttle(EV.ADD, file, 0))
399 return;
400 this.fsw._emit(EV.ADD, file, stats);
401 }
402 return closer;
403 }
404 /**
405 * Handle symlinks encountered while reading a dir.
406 * @param entry returned by readdirp
407 * @param directory path of dir being read
408 * @param path of this item
409 * @param item basename of this item
410 * @returns true if no more processing is needed for this entry.
411 */
412 async _handleSymlink(entry, directory, path, item) {
413 if (this.fsw.closed) {
414 return;
415 }
416 const full = entry.fullPath;
417 const dir = this.fsw._getWatchedDir(directory);
418 if (!this.fsw.options.followSymlinks) {
419 // watch symlink directly (don't follow) and detect changes
420 this.fsw._incrReadyCount();
421 let linkPath;
422 try {
423 linkPath = await (0, promises_1.realpath)(path);
424 }
425 catch (e) {
426 this.fsw._emitReady();
427 return true;
428 }
429 if (this.fsw.closed)
430 return;
431 if (dir.has(item)) {
432 if (this.fsw._symlinkPaths.get(full) !== linkPath) {
433 this.fsw._symlinkPaths.set(full, linkPath);
434 this.fsw._emit(EV.CHANGE, path, entry.stats);
435 }
436 }
437 else {
438 dir.add(item);
439 this.fsw._symlinkPaths.set(full, linkPath);
440 this.fsw._emit(EV.ADD, path, entry.stats);
441 }
442 this.fsw._emitReady();
443 return true;
444 }
445 // don't follow the same symlink more than once
446 if (this.fsw._symlinkPaths.has(full)) {
447 return true;
448 }
449 this.fsw._symlinkPaths.set(full, true);
450 }
451 _handleRead(directory, initialAdd, wh, target, dir, depth, throttler) {
452 // Normalize the directory name on Windows
453 directory = sysPath.join(directory, '');
454 throttler = this.fsw._throttle('readdir', directory, 1000);
455 if (!throttler)
456 return;
457 const previous = this.fsw._getWatchedDir(wh.path);
458 const current = new Set();
459 let stream = this.fsw._readdirp(directory, {
460 fileFilter: (entry) => wh.filterPath(entry),
461 directoryFilter: (entry) => wh.filterDir(entry),
462 });
463 if (!stream)
464 return;
465 stream
466 .on(exports.STR_DATA, async (entry) => {
467 if (this.fsw.closed) {
468 stream = undefined;
469 return;
470 }
471 const item = entry.path;
472 let path = sysPath.join(directory, item);
473 current.add(item);
474 if (entry.stats.isSymbolicLink() &&
475 (await this._handleSymlink(entry, directory, path, item))) {
476 return;
477 }
478 if (this.fsw.closed) {
479 stream = undefined;
480 return;
481 }
482 // Files that present in current directory snapshot
483 // but absent in previous are added to watch list and
484 // emit `add` event.
485 if (item === target || (!target && !previous.has(item))) {
486 this.fsw._incrReadyCount();
487 // ensure relativeness of path is preserved in case of watcher reuse
488 path = sysPath.join(dir, sysPath.relative(dir, path));
489 this._addToNodeFs(path, initialAdd, wh, depth + 1);
490 }
491 })
492 .on(EV.ERROR, this._boundHandleError);
493 return new Promise((resolve, reject) => {
494 if (!stream)
495 return reject();
496 stream.once(exports.STR_END, () => {
497 if (this.fsw.closed) {
498 stream = undefined;
499 return;
500 }
501 const wasThrottled = throttler ? throttler.clear() : false;
502 resolve(undefined);
503 // Files that absent in current directory snapshot
504 // but present in previous emit `remove` event
505 // and are removed from @watched[directory].
506 previous
507 .getChildren()
508 .filter((item) => {
509 return item !== directory && !current.has(item);
510 })
511 .forEach((item) => {
512 this.fsw._remove(directory, item);
513 });
514 stream = undefined;
515 // one more time for any missed in case changes came in extremely quickly
516 if (wasThrottled)
517 this._handleRead(directory, false, wh, target, dir, depth, throttler);
518 });
519 });
520 }
521 /**
522 * Read directory to add / remove files from `@watched` list and re-read it on change.
523 * @param dir fs path
524 * @param stats
525 * @param initialAdd
526 * @param depth relative to user-supplied path
527 * @param target child path targeted for watch
528 * @param wh Common watch helpers for this path
529 * @param realpath
530 * @returns closer for the watcher instance.
531 */
532 async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath) {
533 const parentDir = this.fsw._getWatchedDir(sysPath.dirname(dir));
534 const tracked = parentDir.has(sysPath.basename(dir));
535 if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) {
536 this.fsw._emit(EV.ADD_DIR, dir, stats);
537 }
538 // ensure dir is tracked (harmless if redundant)
539 parentDir.add(sysPath.basename(dir));
540 this.fsw._getWatchedDir(dir);
541 let throttler;
542 let closer;
543 const oDepth = this.fsw.options.depth;
544 if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath)) {
545 if (!target) {
546 await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler);
547 if (this.fsw.closed)
548 return;
549 }
550 closer = this._watchWithNodeFs(dir, (dirPath, stats) => {
551 // if current directory is removed, do nothing
552 if (stats && stats.mtimeMs === 0)
553 return;
554 this._handleRead(dirPath, false, wh, target, dir, depth, throttler);
555 });
556 }
557 return closer;
558 }
559 /**
560 * Handle added file, directory, or glob pattern.
561 * Delegates call to _handleFile / _handleDir after checks.
562 * @param path to file or ir
563 * @param initialAdd was the file added at watch instantiation?
564 * @param priorWh depth relative to user-supplied path
565 * @param depth Child path actually targeted for watch
566 * @param target Child path actually targeted for watch
567 */
568 async _addToNodeFs(path, initialAdd, priorWh, depth, target) {
569 const ready = this.fsw._emitReady;
570 if (this.fsw._isIgnored(path) || this.fsw.closed) {
571 ready();
572 return false;
573 }
574 const wh = this.fsw._getWatchHelpers(path);
575 if (priorWh) {
576 wh.filterPath = (entry) => priorWh.filterPath(entry);
577 wh.filterDir = (entry) => priorWh.filterDir(entry);
578 }
579 // evaluate what is at the path we're being asked to watch
580 try {
581 const stats = await statMethods[wh.statMethod](wh.watchPath);
582 if (this.fsw.closed)
583 return;
584 if (this.fsw._isIgnored(wh.watchPath, stats)) {
585 ready();
586 return false;
587 }
588 const follow = this.fsw.options.followSymlinks;
589 let closer;
590 if (stats.isDirectory()) {
591 const absPath = sysPath.resolve(path);
592 const targetPath = follow ? await (0, promises_1.realpath)(path) : path;
593 if (this.fsw.closed)
594 return;
595 closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath);
596 if (this.fsw.closed)
597 return;
598 // preserve this symlink's target path
599 if (absPath !== targetPath && targetPath !== undefined) {
600 this.fsw._symlinkPaths.set(absPath, targetPath);
601 }
602 }
603 else if (stats.isSymbolicLink()) {
604 const targetPath = follow ? await (0, promises_1.realpath)(path) : path;
605 if (this.fsw.closed)
606 return;
607 const parent = sysPath.dirname(wh.watchPath);
608 this.fsw._getWatchedDir(parent).add(wh.watchPath);
609 this.fsw._emit(EV.ADD, wh.watchPath, stats);
610 closer = await this._handleDir(parent, stats, initialAdd, depth, path, wh, targetPath);
611 if (this.fsw.closed)
612 return;
613 // preserve this symlink's target path
614 if (targetPath !== undefined) {
615 this.fsw._symlinkPaths.set(sysPath.resolve(path), targetPath);
616 }
617 }
618 else {
619 closer = this._handleFile(wh.watchPath, stats, initialAdd);
620 }
621 ready();
622 if (closer)
623 this.fsw._addPathCloser(path, closer);
624 return false;
625 }
626 catch (error) {
627 if (this.fsw._handleError(error)) {
628 ready();
629 return path;
630 }
631 }
632 }
633}
634exports.NodeFsHandler = NodeFsHandler;
635//# sourceMappingURL=handler.js.map
Note: See TracBrowser for help on using the repository browser.