fix(ext/node): support encoding option in fs.watch#33634
fix(ext/node): support encoding option in fs.watch#33634nathanwhitbot wants to merge 2 commits intodenoland:mainfrom
encoding option in fs.watch#33634Conversation
`fs.watch(path, { encoding })` previously emitted the filename as a plain
utf8 string regardless of the requested encoding. Match Node:
- `encoding: 'buffer'` returns a `Buffer`,
- any other named encoding (e.g. `'hex'`, `'base64'`) re-encodes the
filename via `Buffer.from(filename).toString(encoding)`,
- the default (`'utf8'` or absent) leaves the string unchanged.
See https://github.com/nodejs/node/blob/main/lib/internal/fs/watchers.js
Enables `parallel/test-fs-watch-encoding.js`.
nathanwhitbot
left a comment
There was a problem hiding this comment.
Encoding paths line up with Node's behavior — utf8/undefined pass-through, 'buffer' returns a Buffer, other named encodings via Buffer.from(filename).toString(encoding). Net effect is the same as Node's Buffer.from(<os-bytes>).toString(encoding): the original UTF-8 bytes get re-interpreted through the target encoding, including the same lossy behavior for utf16le/ucs2 on odd-byte filenames.
The watchListener type is also updated to string | Buffer, matching Node's typings.
fibibot
left a comment
There was a problem hiding this comment.
The substance is right and the helper is concise. Verified against the upstream test:
encoding: 'hex'for filename新建文夹件.txt:Buffer.from(filename).toString('hex')→'e696b0e5bbbae69687e5a4b9e4bbb62e747874'(UTF-8 bytes hex-encoded), which is exactly the value the test asserts.- No encoding (or
'utf8'): early-return the original string ✓. encoding: 'buffer':Buffer.from(filename)→ realBufferinstance, satisfies the test'sfilename instanceof Buffer && filename.toString('utf8') === fncheck ✓.
Buffer (line 92) and BufferEncoding (line 102) are already imported in fs.ts, so no new imports. watchListener type widening to (eventType, string | Buffer) => void correctly reflects the new return shape.
Test enrollment alphabetically positioned correctly (fs-utimes < fs-watch-encoding < fs-watch-file-enoent-after-deletion).
Holding off on autonomous APPROVE per fibibot's CI gate — only license/cla and lint title have run so far. The full CI build needs maintainer authorization to run on this bot's PRs. I'll re-confirm once test node_compat debug and test unit_node debug land green.
One small nit: passing an unknown encoding (e.g., { encoding: 'foo' }) currently falls through to asBuffer.toString('foo' as BufferEncoding) which Buffer will throw on at call time. Node validates the encoding upfront and throws ERR_INVALID_ARG_VALUE synchronously. Not a functional difference for the test, but validateEncoding would surface a cleaner error. Non-blocking.
|
@nathanwhitbot this needs a rebase |
# Conflicts: # ext/node/polyfills/fs.ts
|
|
Summary
fs.watch(path, { encoding })previously emitted the filename as a plain utf8 string regardless of the requested encoding. Match Node'slib/internal/fs/watchers.js:encoding: 'buffer'→ emit aBuffer'hex','base64') → re-encode the filename viaBuffer.from(filename).toString(encoding)'utf8'or absent) → leave the string unchangedEnables
parallel/test-fs-watch-encoding.js.Test plan
parallel/test-fs-watch-encoding.jspasses viacargo test --test node_compatfs-watch*/fs-promises-watch*tests still pass