diff --git a/doc/api/deprecations.md b/doc/api/deprecations.md index 9882b802bf3e3b..5ed95d9dcf8f5a 100644 --- a/doc/api/deprecations.md +++ b/doc/api/deprecations.md @@ -3321,6 +3321,32 @@ In a future version of Node.js, [`message.headers`][], [`message.headersDistinct`][], [`message.trailers`][], and [`message.trailersDistinct`][] will be read-only. + + + + + + + + + + + + +### DEP0178: `dirent.path` + + + +Type: Documentation-only + +The [`dirent.path`][] is deprecated due to its lack of consistency across +release lines. Please use [`dirent.parentPath`][] instead. + [NIST SP 800-38D]: https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf [RFC 6066]: https://tools.ietf.org/html/rfc6066#section-3 [RFC 8247 Section 2.4]: https://www.rfc-editor.org/rfc/rfc8247#section-2.4 @@ -3366,6 +3392,8 @@ In a future version of Node.js, [`message.headers`][], [`decipher.setAuthTag()`]: crypto.md#deciphersetauthtagbuffer-encoding [`diagnostics_channel.subscribe(name, onMessage)`]: diagnostics_channel.md#diagnostics_channelsubscribename-onmessage [`diagnostics_channel.unsubscribe(name, onMessage)`]: diagnostics_channel.md#diagnostics_channelunsubscribename-onmessage +[`dirent.parentPath`]: fs.md#direntparentpath +[`dirent.path`]: fs.md#direntpath [`dns.lookup()`]: dns.md#dnslookuphostname-options-callback [`dnsPromises.lookup()`]: dns.md#dnspromiseslookuphostname-options [`domain`]: domain.md diff --git a/doc/api/fs.md b/doc/api/fs.md index bc2d6b64ca2e51..6c5944878e0ebf 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -6437,12 +6437,28 @@ The file name that this {fs.Dirent} object refers to. The type of this value is determined by the `options.encoding` passed to [`fs.readdir()`][] or [`fs.readdirSync()`][]. +#### `dirent.parentPath` + + + +> Stability: 1 – Experimental + +* {string} + +The path to the parent directory of the file this {fs.Dirent} object refers to. + #### `dirent.path` +> Stability: 0 - Deprecated: Use [`dirent.parentPath`][] instead. + * {string} The base path that this {fs.Dirent} object refers to. @@ -7982,6 +7998,7 @@ the file contents. [`Number.MAX_SAFE_INTEGER`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER [`ReadDirectoryChangesW`]: https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-readdirectorychangesw [`UV_THREADPOOL_SIZE`]: cli.md#uv_threadpool_sizesize +[`dirent.parentPath`]: #direntparentpath [`event ports`]: https://illumos.org/man/port_create [`filehandle.createReadStream()`]: #filehandlecreatereadstreamoptions [`filehandle.createWriteStream()`]: #filehandlecreatewritestreamoptions diff --git a/lib/internal/fs/dir.js b/lib/internal/fs/dir.js index ec0562843d5f5c..a06106affe7d52 100644 --- a/lib/internal/fs/dir.js +++ b/lib/internal/fs/dir.js @@ -152,9 +152,10 @@ class Dir { ArrayPrototypePush( this[kDirBufferedEntries], getDirent( - pathModule.join(path, result[i]), + path, result[i], result[i + 1], + true, // Quirk to not introduce a breaking change. ), ); } diff --git a/lib/internal/fs/utils.js b/lib/internal/fs/utils.js index 00889ffccc4b99..2e9054a675426b 100644 --- a/lib/internal/fs/utils.js +++ b/lib/internal/fs/utils.js @@ -161,9 +161,10 @@ function assertEncoding(encoding) { } class Dirent { - constructor(name, type, path) { + constructor(name, type, path, filepath = path && join(path, name)) { this.name = name; - this.path = path; + this.parentPath = path; + this.path = filepath; this[kType] = type; } @@ -197,8 +198,8 @@ class Dirent { } class DirentFromStats extends Dirent { - constructor(name, stats, path) { - super(name, null, path); + constructor(name, stats, path, filepath) { + super(name, null, path, filepath); this[kStats] = stats; } } @@ -233,7 +234,7 @@ function join(path, name) { } if (typeof path === 'string' && typeof name === 'string') { - return pathModule.basename(path) === name ? path : pathModule.join(path, name); + return pathModule.join(path, name); } if (isUint8Array(path) && isUint8Array(name)) { @@ -268,7 +269,7 @@ function getDirents(path, { 0: names, 1: types }, callback) { callback(err); return; } - names[idx] = new DirentFromStats(name, stats, path); + names[idx] = new DirentFromStats(name, stats, path, filepath); if (--toFinish === 0) { callback(null, names); } @@ -304,7 +305,7 @@ function getDirent(path, name, type, callback) { callback(err); return; } - callback(null, new DirentFromStats(name, stats, filepath)); + callback(null, new DirentFromStats(name, stats, path, filepath)); }); } else { callback(null, new Dirent(name, type, path)); @@ -312,9 +313,13 @@ function getDirent(path, name, type, callback) { } else if (type === UV_DIRENT_UNKNOWN) { const filepath = join(path, name); const stats = lazyLoadFs().lstatSync(filepath); - return new DirentFromStats(name, stats, path); - } else { + // callback === true: Quirk to not introduce a breaking change. + return new DirentFromStats(name, stats, path, callback === true ? filepath : path); + } else if (callback === true) { + // callback === true: Quirk to not introduce a breaking change. return new Dirent(name, type, path); + } else { + return new Dirent(name, type, path, path); } } diff --git a/test/parallel/test-fs-opendir.js b/test/parallel/test-fs-opendir.js index 82ee8e20da31cd..4956b219ee5d43 100644 --- a/test/parallel/test-fs-opendir.js +++ b/test/parallel/test-fs-opendir.js @@ -48,9 +48,11 @@ const invalidCallbackObj = { const entries = files.map(() => { const dirent = dir.readSync(); assertDirent(dirent); - return dirent.name; - }); - assert.deepStrictEqual(files, entries.sort()); + return { name: dirent.name, path: dirent.path, parentPath: dirent.parentPath, toString() { return dirent.name; } }; + }).sort(); + assert.deepStrictEqual(entries.map((d) => d.name), files); + assert.deepStrictEqual(entries.map((d) => d.path), files.map((name) => path.join(testDir, name))); + assert.deepStrictEqual(entries.map((d) => d.parentPath), Array(entries.length).fill(testDir)); // dir.read should return null when no more entries exist assert.strictEqual(dir.readSync(), null);