Commit Graph
122 Commits
Author SHA1 Message Date
Chris Tate 293370e2e7 Merge main 2026-10-15 21:06:45 -05:00
Chris Tate f0151d8c17 Merge main 2026-10-15 19:06:52 -05:00
Chris Tate 05dabea9a6 Merge main 2026-10-15 18:31:17 -05:00
Chris Tate 079a9d1eb5 Add tlsSocket.getProtocol, getCipher, alpnProtocol and tls.DEFAULT_MIN_VERSION/MAX_VERSION
- getProtocol() answers the negotiated version ("TLSv1.2" or
  "TLSv1.3"), the highest version on offer before the handshake as
  OpenSSL does, and null after close.
- getCipher() answers { name, standardName, version }: OpenSSL's name
  for the negotiated suite, its IANA name, and the suite's minimum
  protocol version. A suite without a known OpenSSL name throws the
  "not supported yet" error.
- alpnProtocol is null before the handshake, then the negotiated
  protocol or false.
- tls.DEFAULT_MIN_VERSION and DEFAULT_MAX_VERSION are 'TLSv1.2' and
  'TLSv1.3', and the bundled declarations type the server's
  secureConnection socket as a TLSSocket.
- The limitations page notes that a typed getCipher() read before the
  handshake or after close throws where Node answers undefined or null.
Corpus 5651 covers each case.
2026-10-15 17:46:09 -05:00
Chris Tate 7bb7cfb6a3 Merge main 2026-10-15 17:36:41 -05:00
Chris Tate 1be58648bc Merge main 2026-10-15 17:31:00 -05:00
Chris Tate aa5e626b06 Merge main 2026-10-15 16:32:19 -05:00
Chris Tate a5a3588d3d Add net socket address fields, write/end/setTimeout callbacks, close(hadError) and server connection limits
- socket.remotePort, remoteFamily, localAddress, localPort, localFamily,
  bytesRead, readyState, connecting and pending. The peer's fields are
  cached at first read as remoteAddress is (undefined while
  connecting), and the local ones are undefined while connecting and
  after close.
- write(data, cb) runs cb with null once the data is flushed, and
  end(cb) / end(data, cb) once the socket finishes.
- 'close' listeners receive hadError, 'ready' fires after 'connect',
  and 'data' listeners may take the string chunks setEncoding gives.
- setTimeout(ms, cb) adds cb as a once('timeout') listener (0 removes
  it), and setTimeout throws ERR_OUT_OF_RANGE for a negative, NaN or
  infinite msecs where it disabled the timer before. setKeepAlive
  chains.
- server.maxConnections closes connections past the cap and emits
  'drop' with their addresses; server.getConnections(cb) answers the
  count on the next tick.
- net.isIP, isIPv4 and isIPv6 follow Node's address patterns.
- A callback adapted to a void return keeps the identity of the
  function it wraps, so removing it by that function finds it.
Corpus 5644-5647 cover each case.
2026-10-15 15:59:17 -05:00
Chris Tate a8586d2c8d Merge main 2026-10-15 15:31:10 -05:00
Chris Tate 1ffbb28255 Follow Node's getOptions in the fs option checks
The fs validation ladder and the callback dispatch check their options
argument as Node's getOptions does. null, undefined and functions take
the defaults, and a string is the encoding. Numbers, booleans, bigints
and symbols throw ERR_INVALID_ARG_TYPE ('The "options" argument must be
one of type string or object'). assertEncoding lets 'buffer' through;
before, every 'buffer' encoding threw ERR_INVALID_ARG_VALUE.

With 'buffer':
- readFile and readFileSync read the file first, so a missing file
  reports ENOENT. Then buffer.toString('buffer') throws
  ERR_UNKNOWN_ENCODING; an empty file answers "".
- fs.mkdtemp's callback receives the path as a Buffer.
- mkdtempSync, opendirSync, createReadStream and createWriteStream
  throw the fence error.

fs.mkdtemp's callback form now checks its encoding. It also returns its
path in the requested encoding: re-encoded text for names other than
utf8, as the binding does.

Corpus 5545 covers these forms against Node 24.22.
2026-10-15 14:54:07 -05:00
Chris Tate 93371f83c9 Merge main 2026-10-15 13:42:34 -05:00
Chris Tate 9377dab890 Add fs.opendirSync, fs.promises.opendir and fs.Dir
opendirSync(path[, options]) and fs.promises.opendir(path[, options])
return a Dir that reads one Dirent at a time in OS order, as libuv's
uv_fs_readdir does. Dir supports path, readSync(), read(), closeSync(),
close() and for await. readSync and read answer null at the end. A
closed Dir throws ERR_DIR_CLOSED from readSync and closeSync, and
rejects with it from read and close.

for await over a Dir reads with read() until null and closes the Dir
in a finally, as Node's Dir.entries() does: normal exhaustion, break
and a throw all close it, and a loop whose body closes the Dir ends
with ERR_DIR_CLOSED.

A Dir also crosses 'unknown' slots as a native handle (Dir), so a
closure returning one can be passed to untyped JavaScript functions.
Through such a slot, path and closeSync() work, and other members throw
the "not supported yet" Error.

Open failures carry the opendir syscall and no path. options.bufferSize
is checked after the directory opens, with Node's ERR_OUT_OF_RANGE
messages. The options must be an object literal with a numeric
bufferSize and a utf8 encoding. Recursive walks, buffer encodings and
the callback forms are not lowered. TypeScript sources get a compile
diagnostic for them; in JavaScript sources, recursive walks and the
callback forms throw the fence error when the call runs.

Corpus 5544 covers both forms against Node 24.22.
2026-10-15 11:34:00 -05:00
Chris Tate c2940acacc Merge main 2026-10-15 11:13:49 -05:00
Chris Tate 8f350a5441 Find fs callbacks where Node's signatures put them 2026-10-15 10:56:41 -05:00
Chris Tate d92b6c4ec8 Merge main 2026-10-15 09:23:58 -05:00
Chris Tate cffc2ee71f Merge main 2026-10-15 09:18:26 -05:00
Chris Tate f325b5f116 Add the missing fs/promises functions and Node's fs argument checks 2026-10-15 09:13:46 -05:00
Chris Tate 2c00672bca Merge main 2026-10-15 08:09:02 -05:00
Chris Tate 0b468e40a1 Add fs.globSync, fs.glob and fs/promises glob
The three glob entry points run a port of Node 24's
lib/internal/fs/glob.js walk in scr_glob.c: the same LIFO queue of
(path, patterns) items over the sorted directory listings, the same
lstat, stat, readdir, realpath and seen-pattern caches, the same result
set in insertion order, and the same exclusion checks, so matches come
out in Node's order. Patterns compile with the existing minimatch port.
glob_match is split into a compile step and a test step so the walk can
reuse each compiled pattern and test it segment by segment.
nocaseMagicOnly is now an option, because exclude patterns turn it off.

Patterns (a string or string array) and options (cwd as a path or
file: URL, exclude as patterns or a function, followSymlinks,
withFileTypes) are validated in Node's order with Node's errors,
including the internal assertion Node hits for a non-string cwd with
exclude patterns. withFileTypes results are Dirent rows: name,
parentPath and the type probes. parentPath follows Node's rule for each
form: the joined path for globSync, the resolved path for fs/promises
glob.

fs.glob checks the callback and validates synchronously, then delivers
string[] or the walk's error through the filesystem callback queue.
fs/promises glob lowers as the source of a for await loop. The walk runs
when the loop starts, and the matches found before an error bind before
the error is thrown, as Node's async iterator yields them first. The
older glob(3)-based fs.glob branch is removed.

Corpus 5448-5452 and a node-types fixture check the behavior against
Node.
2026-10-15 07:59:19 -05:00
Chris Tate bbc1d6d0b0 Merge main 2026-10-15 04:52:43 -05:00
Chris Tate af67284e3a Merge main 2026-10-15 04:50:57 -05:00
Chris Tate 9a1effd421 Complete fs.Stats in the typed and callback lanes 2026-10-15 03:03:32 -05:00
Chris Tate 15202442be Merge main 2026-10-15 02:52:25 -05:00
Chris Tate 5d3315e268 Merge main 2026-10-15 02:36:37 -05:00
Chris Tate 4819818cdf Add assert.AssertionError with Node's properties and constructor
Assertion failures throw an assert.AssertionError with Node 24.22's
generatedMessage, code, actual, expected, operator and diff properties,
in Node's key order. new AssertionError(options) validates its options
and builds Node's message from operator, actual and expected.
AssertionError type annotations, instanceof and assert.throws(fn,
AssertionError) compile.

Failure paths record actual, expected and operator before they throw;
passing assertions do no extra work. The deep forms lower through a
per-type function that returns the verdict, so the operands stay call
temporaries. assert.equal and notEqual inspect their operands only when
they fail.

Values without a checked-dynamic form, and values whose type can be
cyclic, record undefined.
2026-10-15 02:27:13 -05:00
Chris Tate 1843399f25 Pass results from fs.mkdir, readFile and write callback forms 2026-10-15 02:18:22 -05:00
Chris Tate 14bcd1aad4 Add secret KeyObjects: createSecretKey, generateKey and generateKeySync
crypto.createSecretKey and generateKey/generateKeySync for "hmac" and
"aes" return SecretKeyObject values, native dyn handles over a copy of
the key bytes. The type and symmetricKeySize getters, export() as a
Buffer or a JWK, equals(), instanceof KeyObject, String(),
JSON.stringify and util.inspect follow Node 24.22, as do the argument
checks, their order and their errors. createHmac and hkdf/hkdfSync
accept these keys. toCryptoKey() and KeyObject.from() need WebCrypto
values and are refused with SC2020.

Dyn handle ops gain a @@toStringTag that differs from the class name
and a flag for views with no properties, which util.inspect prints at
any depth. KeyObject method calls dispatch through dynInvoke.
2026-10-15 01:51:36 -05:00
Chris Tate b245572d31 Compare any view or ArrayBuffer in timingSafeEqual
crypto.timingSafeEqual accepts every TypedArray, DataView, Buffer,
ArrayBuffer and SharedArrayBuffer and compares their bytes. Values of
other types throw Node 24.22's ERR_INVALID_ARG_TYPE for buf1 and then
buf2, before the byte lengths are compared. Views of every element kind
keep the typed call; other arguments take the checks at run time.
2026-10-15 01:15:44 -05:00
Chris Tate 5e9acfcfca Support randomFill, randomInt callbacks, randomUUID options and randomUUIDv7
randomFillSync accepts every TypedArray, DataView, Buffer, ArrayBuffer and
SharedArrayBuffer and returns its argument at its own type. Offsets and
sizes count elements and are checked in bytes with Node 24.22's
ERR_OUT_OF_RANGE and ERR_INVALID_ARG_TYPE errors. randomFill fills the
same buffers and calls back in a later macrotask, or synchronously when
nothing is filled, as Node does.

randomInt takes a callback in both forms, and its errors carry Node's
received values and the max or "max - min" label. Values come from a
6 KiB cache, as in Node, so a callback runs on the next tick while the
cache has data and after an asynchronous refill when it is empty.
randomUUID and the new randomUUIDv7 validate options.disableEntropyCache
and draw from a 128-UUID batch unless it is set.

A non-u8 view passed to randomFillSync no longer needs a Uint8Array
type, and the bytes callback adapters pass views of any element kind
and dyn values through.
2026-10-15 00:41:22 -05:00
Chris Tate c8d2b378d5 Merge main 2026-10-14 23:28:46 -05:00
Chris Tate bd438a6d5e Add Blob and File
Blob and File (globals and node:buffer exports) compile to native
handles in the new scr_blob.c, following Node 24.22's
lib/internal/blob.js and file.js. A Blob is a window over a shared,
immutable byte store plus the byte length of each part. Sources (strings,
typed arrays, DataView, ArrayBuffer, Buffer, other Blobs, Set and Map)
convert as a Web IDL sequence, with each non-buffer part converted to a
string, before the options are read, and are copied when the Blob is
built. The constructors throw Node's Web IDL TypeErrors and its
ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_VALUE and ERR_MISSING_ARGS errors,
and read and convert their options in Node's order. The type is
lowercased, or cleared when it holds a character outside U+0020..U+007E.
endings: "native" rewrites CRLF, CR and LF to the platform's line break.
File takes its name with lone surrogates replaced and lastModified as a
number (Date.now() when absent).

slice() converts its offsets as a [Clamp] long long (rounded half to
even) and keeps the parts Node's data queue keeps. text(), bytes() and
arrayBuffer() settle on the same microtask turn as in Node, which depends
on the part count. util.inspect prints Node's `Blob { size, type }` and
`File { ..., name, lastModified }` forms, with `[Blob]` past the depth
limit. String() and toString() give the class tag, JSON.stringify gives
{}, and structuredClone returns a new Blob or File over the same bytes.
instanceof works for both spellings. stream(), textStream() and the
Object.prototype members other than toString() fail at compile time.
Non-array iterables other than Set and Map throw SC2020.

Three handle-table additions support this: a structuredClone hook, a
JSON `{}` flag, and a bracketed past-depth inspect flag. scr_blob.c is an
optional unit selected by dynAsync, because the dynamic dispatch path
boxes its reads as dyn promises through scr_async_dyn.c.

Corpus 5285-5290 and a node-types fixture check the behavior against
Node.
2026-10-14 21:17:46 -05:00
Chris Tate b5cb8b397a Add the Readable operators, the Readable.from options and stream.compose
The Readable operators (map, filter, forEach, toArray, some, find, every,
flatMap, drop, take, reduce) run over string and Buffer chunk streams with
Node's ordering, errors, and concurrency, highWaterMark and signal options.
Readable.from reads arrays lazily and accepts the objectMode and
highWaterMark options, and its JavaScript form follows from.js's checks.
stream.compose returns a Duplex over a pipeline of stream instances.

pipeline now follows pipeline.js: per-stream destroyers and eos watchers,
and the callback on a tick once every watcher finished. 'finish' waits for
a pending _final or _flush callback, and a failed synchronous write emits
'error' one tick later, as in Node.
2026-10-14 20:58:41 -05:00
Chris Tate 9835ad0d75 Move scriptc to Node 24.22.0
Pin Node v24.22.0 (commit f14cd3aa7bf9, Undici 7.29.1, OpenSSL 3.5.8) in
.node-version, Dockerfile.sandbox, the docs matrix fallback, the
compatibility pin, the fetch profile, and process.version. A node-pin test
checks that these pins agree. The Node compatibility snapshot is
regenerated from the v24.22.0 API docs; the new stream_iter chapter maps
to node:stream/iter, and the SuiteContext rows no longer match the
TestContext evidence.

Runtime and compiler changes follow Node 24.22 behavior:

- fs.read, fs.readSync, and FileHandle.read validate the position before
  the zero-length return.
- fs.statfs results include frsize; Windows reads
  FileFsFullSizeInformation and reports bfree and bavail separately.
- fs.utimes, futimes, and lutimes keep nanosecond precision.
- ServerResponse sets writableFinished where 'finish' is emitted and runs
  end() callbacks before the 'finish' listeners while the socket is still
  attached; a request read to 'end' closes before its response.
- socket.write(string, 'buffer') throws ERR_UNKNOWN_ENCODING.
- URL protocol-setter rejections keep the current URL, the host setter
  no longer leaves a "/." escape when it adds a port to a "//" path, and
  new URLSearchParams(null) parses "null".
- util.stripVTControlCharacters uses Node 24.22's ANSI pattern,
  util.styleText accepts #RGB and #RRGGBB colors, and
  util.types.isDataView has its JS name and length.
- structuredClone and AbortSignal.any use the "cannot be converted to
  sequence" message.
- crypto.getCiphers, getHashes, and constants match Node 24.22.
- dns.lookup, net.connect, and tls.connect throw ERR_INVALID_ARG_VALUE for
  hosts with null bytes.
- fs.readFile validates options.buffer and refuses its valid forms;
  httpValidation and certificateCompression refuse by name.
- url.domainToASCII, url.domainToUnicode, and url.parse hostnames follow
  ada 4.0: ASCII domains are lowercased without checking their xn--
  labels, the RFC 5893 rule checks how LTR labels end and how RTL labels
  start, a Punycode label whose decoded form begins with "xn--" fails, and
  ToUnicode decodes only labels that pass the ToASCII checks. The url
  legacy test cases are regenerated with Node 24.22.

Corpus programs 5275-5279 cover the new behavior. 1640, 2283, 2599, and
3136 are updated where they pinned Node 24.15 output.
2026-10-14 17:27:02 -05:00
Chris Tate 63012c09b1 Add readline/promises, stream.addAbortSignal and the stream/promises options 2026-10-14 14:10:43 -05:00
Chris Tate f951af1e8f Merge main into process and perf_hooks 2026-10-14 12:46:19 -05:00
Chris Tate 5ef650b5e7 Merge main into the legacy url API 2026-10-14 11:30:47 -05:00
Chris Tate 86f77c88e9 Add process.memoryUsage, process identity members, and performance marks and measures 2026-10-14 09:58:18 -05:00
Chris Tate 8043da9e06 Merge main into EventTarget 2026-10-14 08:46:13 -05:00
Chris Tate bd9a994060 Add the legacy url API and url.domainToASCII/domainToUnicode 2026-10-14 08:10:02 -05:00
Chris Tate 3008f2ff1a Support util.inherits, util.deprecate, util.callbackify and util.debuglog 2026-10-14 08:08:06 -05:00
Chris Tate 48ccbddfec Merge main into EventTarget 2026-10-14 08:03:27 -05:00
Chris Tate e3d3380032 Add path.matchesGlob 2026-10-14 03:54:52 -05:00
Chris Tate a4af77ee8d Add EventTarget, Event and CustomEvent 2026-10-14 02:58:57 -05:00
Chris Tate e646b347de Complete node:os and add path.parse and path.format 2026-10-14 00:25:07 -05:00
Chris Tate 124e3204c1 Merge main into lone surrogate strings 2026-10-13 21:07:27 -05:00
Chris Tate 844ef14771 Keep lone surrogates in strings 2026-10-13 19:48:11 -05:00
Chris Tate 12e3da9fee Lower the rest of the global console 2026-10-13 18:55:55 -05:00
Chris Tate 2b280dd25c Merge main into node:console Console support 2026-10-13 10:54:25 -05:00
Chris Tate 8056aafa37 Support node:console Console instances
- Support `new Console(...)` over process stdio and writable streams
- Write `log`/`info`/`debug`/`error`/`warn` output like Node, including `ignoreErrors`
- Mark the `Console` class as partially supported in the compatibility data
2026-10-13 09:15:07 -05:00
Chris Tate 4f44241543 Clarify stream consumer support details
- Describe the consumers' Node Readable scope in the compatibility data
- Renumber the new corpus programs to avoid shared prefixes
2026-10-13 09:13:49 -05:00