Commit Graph
3145 Commits
Author SHA1 Message Date
Chris Tate 313a984066 Keep regular destination files when fs-extra's copy meets a symlink source
copy and copySync now follow fs-extra's onLink: only a destination that
is itself a symlink is replaced; over a regular file or directory the
symlink call fails with EEXIST and the destination is kept, whatever
overwrite says. The fs-extra corpus program covers both forms.
2026-10-20 10:36:00 -05:00
Malte UblandClaude Opus 5.5 e5b9102e0d Compile compound assignment, ++/-- and ??= through literal-union and index-signature record keys
`totals[side] += n`, where `side` is a union of string literals naming
declared fields of one type, now dispatches over those fields: the
receiver and key evaluate once, the old value is read from the field the
key names, then the right side, then the write to that same field. Every
compound operator, prefix and postfix ++/--, and ??=/||=/&&= share the
path. A single literal key (spelled at the site or carried by a const)
reads and writes the field directly. A key smuggled outside its literal
type throws the fixed-shape TypeError of a keyed write miss.

A string key into a pure index-signature record (`counts[name] += 1`,
`counts[name]++`) reads the entry, NaN for a missing one under numeric
operators, and inserts or replaces it.

Keys naming fields of different types, class instances and JavaScript
sources keep their refusals.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 08:32:19 -07:00
Chris Tate 89f8dbe9e0 Merge main 2026-10-20 10:23:43 -05:00
Chris Tate 23355baa2c Merge main 2026-10-20 10:22:00 -05:00
Chris Tate 7d35fee688 Validate flat request header arrays and drop lookup listeners when a socket closes
- http.request, https.request and get validate each name and value of a
  flat [name, value, ...] headers array, as Node's _storeHeader does: a
  name that is not an HTTP token throws ERR_INVALID_HTTP_TOKEN, a value
  with an invalid character throws ERR_INVALID_CHAR, and an odd length
  throws ERR_INVALID_ARG_VALUE with the inspected array. The
  [[name, value], ...] entry form throws the options fence.
- A closing socket drops its 'lookup' listeners with its other listeners,
  so a listener that holds the socket no longer keeps it alive.
- The options-record diagnostics snapshot no longer expects the
  socketPath refusal.
2026-10-20 10:21:03 -05:00
Chris Tate e0b131c0f9 Merge main into opt/variadic-generic-wrappers 2026-10-20 10:19:08 -05:00
Chris Tate da476df676 Merge main 2026-10-20 10:11:51 -05:00
Malte Ubl aaf1e83ad8 Merge remote-tracking branch 'origin/opt/npm-polyfill-shims' into opt/npm-fs-extra-shim 2026-10-20 08:08:36 -07:00
Malte UblandClaude Opus 5.5 4470bab308 Give the undici shim's Dispatcher an explicit constructor
The implicit constructor forwarded its arguments to EventEmitter's options-taking constructor, which compiles to a deferred runtime fence. Dispatcher takes no options, so it calls super() directly.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 07:58:16 -07:00
Malte UblandClaude Opus 5.5 f669c46f0d Carry runtime-decided dns.lookup answers dynamically, dial Node-typed net lookups, and keep tsc enum exports undefined until assigned
- dns.lookup with options known only at run time (a checked-dynamic
  value, or one cast to an overload's option type) may answer a string or,
  with `all: true`, an address list, whatever the overload the checker
  picked says: an inline callback now binds its parameters as
  checked-dynamic values. Array.isArray tests a checker-narrowed dyn read's
  dyn value instead of folding on the extracted type, so it never answers
  false for an address list the declared type omits.
- net.connect({ lookup }) accepts a lookup of Node's own type
  (net.LookupFunction: options plus a callback taking an address string
  or list), called as Node's autoSelectFamily dial does ({ hints, all:
  true }); the fallback declarations spell net.LookupFunction that way.
  dns.lookup accepts Node's hints flags (ADDRCONFIG, V4MAPPED, ALL) and
  passes them to getaddrinfo.
- A CommonJS export typed as the empty object literal (tsc's enum output
  `exports.E || (exports.E = {})` after `exports.E = void 0`) rides
  checked-dynamic storage, so the preamble's undefined no longer traps at
  module load: @opentelemetry/api loads and its no-op metrics and trace
  APIs run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 07:58:15 -07:00
Chris Tate da0f6b642b Merge main 2026-10-20 09:52:32 -05:00
Chris Tate c91bfea743 Compile object literals that spread index-signature records, unknown spreads, and union-of-records results (#1505) 2026-10-20 09:51:27 -05:00
Chris Tate 5ea3df1244 Merge main 2026-10-20 09:47:20 -05:00
Chris Tate bec87d6ac5 Compile mixed-tuple Promise.all, Boolean callbacks, enum key lookups and nullable regex receivers (#1500) 2026-10-20 09:40:13 -05:00
Chris Tate 6a658c6ae3 Compile the remaining safe-fetch shapes: Promise<never> race entries, typed Array(n).fill, narrowed header entries, lookup option unions and CommonJS export aliases (#1521) 2026-10-20 09:38:23 -05:00
Chris Tate cb99a06fe5 Shadow the export alias only in the scope that declares it again
The export-alias rewrite skipped a whole function when a let or const
anywhere inside it declared the alias's name, so the function's other
references to the alias kept the alias name after its declaration was
removed. A function now shadows the alias only through its parameters,
its own name, its vars and the declarations directly in its body; a
block, case block, catch clause or for loop shadows it through its own
declarations, and the walk skips just that scope.
2026-10-20 09:35:14 -05:00
Chris Tate 39e3b4a5dd Adopt thenable entries and place tuple slots by position in mixed Promise.all
- A checked-dynamic entry of a tuple Promise.all goes through
  PromiseResolve (`dyn.promiseResolve`): a native promise is itself, a
  thenable adopts its settlement through its resolve job, and any other
  value fulfills. Before, a thenable fulfilled the slot with the object.
- Tuple fields read their entry by position. Shape fields are sorted by
  name, so tuples of more than ten entries paired fields with the wrong
  entries.
2026-10-20 09:34:19 -05:00
Chris Tate 90ff0af5b7 Merge main 2026-10-20 09:33:27 -05:00
Chris Tate 53f41e1a09 List an error's own name where it was created (#1482) 2026-10-20 09:31:04 -05:00
Chris Tate e6ca194308 Merge main 2026-10-20 09:26:26 -05:00
Chris Tate c4ce357a9e Merge main and answer false for fixed-parameter function patterns that need more arguments
- Merge origin/main (e1c27176a).
- matchInferSignature answers false when a function needs more arguments
  than a fixed-parameter pattern passes, as TypeScript's assignability
  does (corpus 6398).
- Record corpus costs for the programs this change adds.
2026-10-20 09:24:29 -05:00
Malte UblandClaude Opus 5.5 2081aaa721 Compile readable-stream 3.x as Node's stream module too
readable-stream 3.x is a copy of Node 10's streams. Like 2.x and 4.x it
now compiles as node:stream: readable.js as stream.Readable carrying the
stream classes, Stream, finished and pipeline, and lib/_stream_*.js as the
matching builtin classes. Unlike them, this is not the package's own
READABLE_STREAM=disable mode, which throws on Node 24 (it Object.assigns
every stream export onto stream.Readable, which inherits the getter-only
`promises` accessor). The limitations and dependencies pages and the
compatibility notes say so.

The corpus program readable-stream-3 runs the vendored 3.6.2 under Node and
keeps to behavior its streams share with the builtin.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 07:22:27 -07:00
Chris Tate 575f6491f4 Fix silent wrong output: object identity, Object.prototype values, Date parsing, stored builtins (#1336) 2026-10-20 09:18:37 -05:00
Chris Tate 56de47defc Check programs with tsc-ts by default (#1353) 2026-10-20 09:12:30 -05:00
Chris Tate 0ccb58943a Compile esbuild's lazily initialized ES modules; select @types-typed and untyped dependencies by default (#1422) 2026-10-20 09:06:46 -05:00
Chris Tate 68a3d8f846 Merge main 2026-10-20 09:06:21 -05:00
Chris Tate 7d555c4cf3 Merge main 2026-10-20 09:04:02 -05:00
Chris Tate 55f4eaca5b Merge main 2026-10-20 09:02:52 -05:00
Chris Tate 7cd7b483bf Merge main 2026-10-20 09:02:06 -05:00
Chris Tate ee33951924 Refuse returns a generic callback's inferred result would drop members of (#1507) 2026-10-20 09:01:42 -05:00
Chris Tate 58c858338a Iterate class instances whose Symbol.iterator is a generator method (#1405) 2026-10-20 09:01:06 -05:00
Chris Tate 9e54b4a198 Merge main 2026-10-20 09:00:02 -05:00
Chris Tate f1d78a48b5 Merge main 2026-10-20 08:59:06 -05:00
Chris Tate d850e14d50 Refuse dropped members through conditional and satisfies returns
The refusal of callback returns that the inferred result type would cut
down found the return by walking up through parentheses and await only,
so a return inside a conditional's branch or a `satisfies` expression
converted silently and lost the extended members. It now walks through
every parent whose value can be the expression's own: parentheses,
await, satisfies, non-null assertions, conditional branches, the
operands of ??, || and &&, and the right operand of a comma.
2026-10-20 08:58:50 -05:00
Chris Tate acf8b28f40 Merge main 2026-10-20 08:57:09 -05:00
Chris Tate da4f131651 Merge main 2026-10-20 08:56:12 -05:00
Chris Tate f31f856783 Convert object literals with accessors to unknown again (#1506) 2026-10-20 08:55:35 -05:00
Chris Tate 8a40fb5a9c Compile the packages an import()-loaded module requires; compile TypeScript enums in packages (#1517) 2026-10-20 08:55:04 -05:00
Chris Tate e44f6ccbf2 Decode an AST list's position only when it is read (#1509) 2026-10-20 08:54:40 -05:00
Chris Tate 02fc8ab13c Keep one process-stream Writable per descriptor and never end it from a pipe
Under the general stream representation, every conversion of
process.stdout or process.stderr into a Writable slot made a new stream,
so two NodeJS.WritableStream slots holding process.stdout compared
unequal and kept separate listeners and writable state. A pipe into such
a slot also ended the converted Writable at the source's end, so later
writes through the slot failed; Node never ends process.stdout or
process.stderr from a pipe.

scr_stream_stdio_writable now keeps one Writable per descriptor and
thread, released at exit. Under the general representation, a pipe into
a Writable slot lowers to readable.pipeGeneral (scr_stream_pipe_general,
last in the stream unit), which keeps end off when the destination is
one of those Writables; programs without the general representation
lower pipes as before.

The fallback stream.Writable's on() and once() overloads for drain,
finish, close and error return the stream again, so listener chains such
as out.on("finish", listener).end(data) type-check.

Adds corpus 6468.
2026-10-20 08:54:18 -05:00
Chris Tate fe589fdddf Run SHA-384 and SHA-512 with AVX2, AVX-512VL or the arm64 SHA-512 instructions (#1464) 2026-10-20 08:53:46 -05:00
Chris Tate 5632decbb9 Skip untaken global-detection arms, and fix the shim test checks
- An if statement whose condition is a global-detection test
  (static-typeof.ts) lowers only its taken arm, unless the untaken arm
  declares a var or function binding. Code Node never runs no longer
  counts as a deferred site, so global-detection-typeof.cjs is fully
  static.
- The resolver parity sweep skips specifiers the package-shim registry
  serves: they resolve to the built-in module by design.
- undici-shim-types.test.ts joins the TypeScript 5 import allowlist.
- node-types-timers uses a 200 ms timer, so the immediate runs first on
  a loaded machine as well.
2026-10-20 08:52:39 -05:00
Chris Tate ea6b51fdf1 Merge main 2026-10-20 08:52:14 -05:00
Chris Tate b281d36264 Merge main 2026-10-20 08:51:23 -05:00
Chris Tate 32f2b5d28b Run death-triggered full collections at the event loop's idle moments 2026-10-20 08:50:23 -05:00
Chris Tate 8e87f6f9ef Resolve const aliases when deciding a child stream's setEncoding state
An untyped child-stream 'data' listener takes strings when a setEncoding
call on the same stream precedes it. A const alias of an access path
(`const out = child.stdout`) now resolves to that path, so a setEncoding
through one alias and a listener through another, or through the stream
itself, agree. A setEncoding on another receiver that can hold the same
stream (a let copy, a parameter, a call result) leaves the state unclear
and reports the existing SC1090. Receivers that name different members
of one root, or two const roots each initialized by a call or new, are
treated as different streams.
2026-10-20 08:49:48 -05:00
Malte UblandClaude Opus 5.5 8284e61f1e Add corpus programs for JavaScript stream objects in NodeJS stream slots
6480 passes a plain object, a constructor-function stream and a native
Readable through a NodeJS.ReadableStream function and consumes them in
TypeScript (on("data"), pipe()) and JavaScript, including identity and a
native pipe into JavaScript sinks. 6481 covers NodeJS.WritableStream
slots and a copy helper across native and JavaScript sources and
destinations. 6482 covers the helper shapes real code writes: an async
producer, pipe with { end: false } and unpipe, pause/resume/setEncoding,
an optional destroy through an intersection type, for await and pipeline
over native values.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 06:49:37 -07:00
Malte UblandClaude Opus 5.5 dfd59e18ee Let NodeJS stream interface slots hold JavaScript stream objects
Under the general stream representation, NodeJS.ReadableStream and
NodeJS.WritableStream compile as the runtime Readable and Writable
classes, so a JavaScript stream object (a constructor-function stream, a
plain object with on/pipe, a stream from bundled npm code) passed through
a TypeScript function typed with them took the checked unwrap and threw.

A program that moves an untyped value into a runtime stream class slot,
or passes an untyped pipe() destination or pipeline stage, now lowers
once more with checked-dynamic stream slots: the two interfaces (and
intersections over them) map to dyn. A native stream rides its typed
capsule and keeps its identity; any other value is the JavaScript object
itself. Member calls dispatch per value: stream.dynNative tests for a
boxed native stream, which takes the ordinary class-method lowering;
other values call their own member through dynInvoke. pipe() into a
JavaScript destination follows Node's Readable.prototype.pipe listener
protocol (stream.pipeDyn). for await and pipeline stages keep the
not-supported error for values that are not native streams.

The runtime code lives in scr_stream_dyn.c behind a new streamDyn
feature, so programs without these libCalls link the same objects.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 06:49:37 -07:00
Chris Tate ce5e4294ad Merge main 2026-10-20 08:49:25 -05:00
Chris Tate 6b708392d7 Merge main 2026-10-20 08:48:08 -05:00