Skip to content

Commit fdba49b

Browse files
Refactors excluded path handling and validation
Improves excluded path validation by normalizing paths before comparison, ensuring accurate subdirectory checks. Updates debounceMS validation to include an upper bound, preventing excessively long debounce intervals. Provides a more robust and consistent way of retrieving excluded paths, handling cases where the underlying implementation might not support it. Fixes a bug where file modification detection was not working correctly due to incorrect time comparison.
1 parent 6d28968 commit fdba49b

File tree

2 files changed

+52
-23
lines changed

2 files changed

+52
-23
lines changed

index.d.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ declare module 'nsfw' {
2121
start: () => Promise<void>;
2222
/** Returns a Promise that resolves when NSFW object has halted. */
2323
stop: () => Promise<void>;
24-
/** Returns a Promise that resolves when NSFW object has updated the excluded ppaths. */
25-
updateExcludedPaths: (excludedPaths: [string]) => Promise<void>;
24+
/** Returns a Promise that resolves when NSFW object has updated the excluded paths. */
25+
updateExcludedPaths: (excludedPaths: string[]) => Promise<void>;
26+
/** Returns a Promise that resolves with the current excluded paths. */
27+
getExcludedPaths: () => Promise<string[]>;
2628
}
2729

2830
export const enum ActionType {
@@ -65,7 +67,7 @@ declare module 'nsfw' {
6567
/** callback to fire in the case of errors */
6668
errorCallback?: (err: any) => void;
6769
/** paths to be excluded */
68-
excludedPaths?: [string];
70+
excludedPaths?: string[];
6971
}
7072
}
7173

js/src/index.js

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ function NSFWFilePoller(watchPath, eventCallback, debounceMS) {
1818
fileStatus = status;
1919
eventCallback([{ action: CREATED, directory, file }]);
2020
} else if (
21-
status.mtime - fileStatus.mtime !== 0 ||
22-
status.ctime - fileStatus.ctime !== 0
21+
status.mtime.getTime() !== fileStatus.mtime.getTime() ||
22+
status.ctime.getTime() !== fileStatus.ctime.getTime()
2323
) {
2424
fileStatus = status;
2525
eventCallback([{ action: MODIFIED, directory, file }]);
@@ -50,18 +50,24 @@ function NSFWFilePoller(watchPath, eventCallback, debounceMS) {
5050
this.resume = () => this.start();
5151
}
5252

53-
54-
const buildNSFW = async (watchPath, eventCallback,
55-
{ debounceMS = 500, errorCallback: _errorCallback, excludedPaths = [] } = {}) => {
53+
const buildNSFW = async (
54+
watchPath,
55+
eventCallback,
56+
{ debounceMS = 500, errorCallback: _errorCallback, excludedPaths = [] } = {}
57+
) => {
5658
if (Number.isInteger(debounceMS)) {
57-
if (debounceMS < 1) {
58-
throw new Error('Minimum debounce is 1ms.');
59+
if (debounceMS < 1 || debounceMS > 60000) {
60+
throw new Error('debounceMS must be >= 1 and <= 60000.');
5961
}
6062
} else {
6163
throw new Error('debounceMS must be an integer.');
6264
}
6365

64-
const errorCallback = _errorCallback || ((nsfwError) => { throw nsfwError; });
66+
const errorCallback =
67+
_errorCallback ||
68+
((nsfwError) => {
69+
throw nsfwError;
70+
});
6571

6672
if (!path.isAbsolute(watchPath)) {
6773
throw new Error('Path to watch must be an absolute path.');
@@ -75,23 +81,37 @@ const buildNSFW = async (watchPath, eventCallback,
7581
}
7682

7783
if (excludedPaths) {
84+
const normalizedWatchPath = watchPath.replace(/[\\/]+$/, '');
7885
for (let i = 0; i < excludedPaths.length; i++) {
79-
const excludedPath = excludedPaths[i];
86+
const normalizedExcludedPath = excludedPaths[i].replace(/[\\/]+$/, '');
8087
if (process.platform === 'win32') {
81-
if (!excludedPath.substring(0, watchPath.length - 1).
82-
localeCompare(watchPath, undefined, { sensitivity: 'accent' })) {
83-
throw new Error('Excluded path must be a valid subdirectory of the watching path.');
88+
if (
89+
normalizedExcludedPath
90+
.substring(0, normalizedWatchPath.length)
91+
.localeCompare(normalizedWatchPath, undefined, {
92+
sensitivity: 'accent',
93+
}) !== 0
94+
) {
95+
throw new Error(
96+
'Excluded path must be a valid subdirectory of the watching path.'
97+
);
8498
}
8599
} else {
86-
if (!excludedPath.startsWith(watchPath)) {
87-
throw new Error('Excluded path must be a valid subdirectory of the watching path.');
100+
if (!normalizedExcludedPath.startsWith(normalizedWatchPath)) {
101+
throw new Error(
102+
'Excluded path must be a valid subdirectory of the watching path.'
103+
);
88104
}
89105
}
90106
}
91107
}
92108

93109
if (stats.isDirectory()) {
94-
return new NSFW(watchPath, eventCallback, { debounceMS, errorCallback, excludedPaths });
110+
return new NSFW(watchPath, eventCallback, {
111+
debounceMS,
112+
errorCallback,
113+
excludedPaths,
114+
});
95115
} else if (stats.isFile()) {
96116
return new NSFWFilePoller(watchPath, eventCallback, debounceMS);
97117
} else {
@@ -101,7 +121,9 @@ const buildNSFW = async (watchPath, eventCallback,
101121

102122
function nsfw(watchPath, eventCallback, options) {
103123
if (!(this instanceof nsfw)) {
104-
return buildNSFW(watchPath, eventCallback, options).then(implementation => new nsfw(implementation));
124+
return buildNSFW(watchPath, eventCallback, options).then(
125+
(implementation) => new nsfw(implementation)
126+
);
105127
}
106128

107129
const implementation = watchPath;
@@ -110,16 +132,21 @@ function nsfw(watchPath, eventCallback, options) {
110132
this.stop = () => implementation.stop();
111133
this.pause = () => implementation.pause();
112134
this.resume = () => implementation.resume();
113-
this.getExcludedPaths = () => implementation.getExcludedPaths();
114-
this.updateExcludedPaths = (paths) => implementation.updateExcludedPaths(paths);
135+
this.getExcludedPaths = () =>
136+
implementation.getExcludedPaths
137+
? implementation.getExcludedPaths()
138+
: Promise.resolve([]);
139+
this.updateExcludedPaths = (paths) =>
140+
implementation.updateExcludedPaths
141+
? implementation.updateExcludedPaths(paths)
142+
: Promise.resolve();
115143
}
116144

117-
118145
nsfw.actions = {
119146
CREATED: 0,
120147
DELETED: 1,
121148
MODIFIED: 2,
122-
RENAMED: 3
149+
RENAMED: 3,
123150
};
124151

125152
nsfw._native = NSFW;

0 commit comments

Comments
 (0)