Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
18fa6d6
Compile nested generic function declarations and root generic functio…
cramforce Nov 6, 2026
d459f1a
Refuse at compile time a Proxy that enters a class or record slot
cramforce Nov 7, 2026
88d1d6e
Call an optional callable member every arm of a record union declares
cramforce Nov 7, 2026
6caa333
Type a generic rest binding by the type argument's fields
cramforce Nov 7, 2026
5cb98fb
Join separate arguments onto spawnSync's shell command, with DEP0190
cramforce Nov 7, 2026
87fcee8
Join a sparse argument list onto spawnSync's shell command as Node does
cramforce Nov 7, 2026
393c5a1
Address review feedback
ctate Nov 7, 2026
e1a16e2
Hold a predeclared Proxy binding dynamically and refuse shorthand reads
cramforce Nov 7, 2026
b8a639a
Merge remote-tracking branch 'origin/main' into fix/wave2-generics
cramforce Nov 7, 2026
0ac3ebe
Answer a process stream's one runtime stream where a stream class is …
cramforce Nov 7, 2026
d6fc813
Refuse an initializer that names a thread-local; cover identity roots…
cramforce Nov 7, 2026
31e0cda
Merge remote-tracking branch 'origin/main' into fix/wave2-generics
cramforce Nov 7, 2026
bf0d450
Name only the measured classes in the process stream limitation
cramforce Nov 7, 2026
0ae8261
Merge main into fix/proxy-as-class
cramforce Nov 7, 2026
2d43fce
Compile five shapes pi's lowering refused
cramforce Nov 7, 2026
9c7af97
Iterate a typed Headers through keys(), values(), entries() and for...of
cramforce Nov 7, 2026
0971d16
Refuse by name a bytes 'data' listener on process.stdin once an encod…
cramforce Nov 7, 2026
817077e
Refuse read() and for await on process.stdin by name once an encoding…
cramforce Nov 7, 2026
fc1b967
Hold a dictionary that keeps identity in a recursive union
cramforce Nov 7, 2026
bcad2cd
Store union members that share a discriminant literal as one record
cramforce Nov 7, 2026
44a8422
Hand Object.entries' untyped values back by reference
cramforce Nov 7, 2026
e2bcc41
Add the union matrix script
cramforce Nov 7, 2026
b20b033
Read a dictionary record's key map at its own field when the record i…
cramforce Nov 7, 2026
92ab9ec
Hand out Buffers from the stdin stream's async iteration
cramforce Nov 7, 2026
2d93ccd
Merge remote-tracking branch 'origin/fix/process-stream-as-stream-cla…
cramforce Nov 7, 2026
83457a5
Convert Object.entries' index values with the general untyped conversion
cramforce Nov 7, 2026
a4f71e3
Merge main into fix/union-shared-arms
cramforce Nov 7, 2026
56feb42
Name the union back-reference scratch in the journal inventory
cramforce Nov 7, 2026
746252f
Refuse a bytes read of an encoded stdin only where a chunk is handed out
cramforce Nov 7, 2026
23ed577
Keep union member layouts in library builds
cramforce Nov 7, 2026
9460ba4
Merge main into fix/pi-fences-c
cramforce Nov 7, 2026
0f8e309
Merge main into fix/pi-fences-c
cramforce Nov 7, 2026
309b27a
Take spawn's shell option as a boolean decided at run time
cramforce Nov 7, 2026
cd0afe1
Pin spawn's refused values beside its shell line
cramforce Nov 7, 2026
db23f2f
Merge branch 'fix/pi-fences-f' (#3291) into fix/dictionary-spelled-twice
cramforce Nov 7, 2026
a7fe8b7
Merge origin/main into fix/wave2-generics
cramforce Nov 7, 2026
1b55b74
Merge origin/main into fix/proxy-as-class
cramforce Nov 7, 2026
aec54cc
Treat a dictionary type as one type however it is spelled
cramforce Nov 7, 2026
c343247
Merge main into fix/dict-arm-to-dyn
cramforce Nov 7, 2026
3c93456
Compare no mapped type whose members are not known yet
cramforce Nov 7, 2026
9f31f76
Report a dictionary copy only for the dictionary rule's own views
cramforce Nov 7, 2026
8cf57b2
Merge remote-tracking branch 'origin/main' into fix/dictionary-spelle…
cramforce Nov 7, 2026
a87643a
Merge main into fix/union-shared-arms
cramforce Nov 7, 2026
5bfca37
Choose a union arm by the value's properties where several arms hold …
cramforce Nov 7, 2026
ac662c2
Record the measured costs of the two union-arm corpus programs
cramforce Nov 7, 2026
b4e2221
Let a union member outside a class keep its own arm when its discrimi…
cramforce Nov 7, 2026
85fa7c2
Merge remote-tracking branch 'origin/main' into fix/dictionary-spelle…
cramforce Nov 7, 2026
cf77773
Ask the value under its assertions for the discriminant that names it…
cramforce Nov 7, 2026
cd60b1a
Merge branch 'main' into fix/pi-fences-e
cramforce Nov 7, 2026
2f1e7fa
Merge branch 'main' into fix/dict-arm-to-dyn
cramforce Nov 7, 2026
6f6323a
Refuse bytes consumers of process.stdin by name once an encoding is s…
ctate Nov 7, 2026
0af229c
Merge #3101 (fix/wave2-generics) into train/pi-1
cramforce Nov 7, 2026
b4a09aa
Merge #3167 (fix/proxy-as-class) into train/pi-1
cramforce Nov 7, 2026
b9f83ed
Merge #3180 (fix/pi-fences-c) into train/pi-1
cramforce Nov 7, 2026
9005c2a
Merge #3279 (fix/process-stream-as-stream-class) into train/pi-1
cramforce Nov 7, 2026
17c9db4
Merge #3274 (fix/pi-fences-e) into train/pi-1
cramforce Nov 7, 2026
ffb4043
Merge #3291 (fix/pi-fences-f) into train/pi-1
cramforce Nov 7, 2026
43a21e7
Merge #3334 (fix/dictionary-spelled-twice) into train/pi-1
cramforce Nov 7, 2026
f0ec4f7
Merge #3311 (fix/union-shared-arms) into train/pi-1
cramforce Nov 7, 2026
484cd72
Merge #3314 (fix/dict-arm-to-dyn) into train/pi-1
cramforce Nov 7, 2026
25de945
Merge #3339 (fix/pi-fences-g) into train/pi-1
cramforce Nov 7, 2026
ac704a1
Merge origin/main (b3ff41013c: #3303, #3255) into train/pi-1
cramforce Nov 7, 2026
f021e56
Route by properties only among arms that keep each property at its ow…
cramforce Nov 7, 2026
0454792
Merge main into fix/pi-fences-g
cramforce Nov 7, 2026
9554cea
Merge origin/main (aae5d05e10: #3342, #3336, #3321, #3237) into train…
cramforce Nov 7, 2026
999b9fb
Merge origin/main (875ed8ec56: #3331, #3227, #3194) into train/pi-1
cramforce Nov 7, 2026
a74c0df
Format the retag unit test after the merge; record the asserted progr…
cramforce Nov 7, 2026
45d9e13
Say that cp.shellLine and stream.stdioReadable never throw
cramforce Nov 7, 2026
3365372
Merge fix/pi-fences-g at a74c0dfc2b (#3339's review fix) into train/pi-1
cramforce Nov 7, 2026
b39b26d
Pin the shared-discriminant refusal on owners that cannot be one record
cramforce Nov 7, 2026
5efda30
List the shell line unit's warning reference as reached only through …
cramforce Nov 7, 2026
c2554b9
Merge origin/main (23f1b176f3: #3320, #3316, #3308, #3268, #3213, #33…
cramforce Nov 7, 2026
f9003c8
Pin the asserted entry whose arms keep a property at different types
cramforce Nov 7, 2026
3096f0e
Merge fix/pi-fences-g-on-main at f9003c8c6a (#3339: the corpus progra…
cramforce Nov 7, 2026
7977ad7
Merge origin/main (8f47512e31: #3346, #3349, #3324, #3203, #3135) int…
cramforce Nov 7, 2026
f2e45ed
Merge origin/main (04b7d6b0bb: #3109, #3103, #3102, #3333, #3351) int…
cramforce Nov 7, 2026
48c8bc9
Merge origin/main (ef8d82ef7f: #3327, #3345) into train/pi-1
cramforce Nov 7, 2026
44a5922
Hand the stdin stream every raw chunk while an encoding is set
cramforce Nov 7, 2026
f747fe9
Merge origin/main (76a19f9d93: #3315, #3282, #3310, #3169, #3065, #30…
cramforce Nov 7, 2026
d242731
Peel the island-made name with the shared helper (main does not build)
cramforce Nov 7, 2026
71207eb
Merge origin/main (fffd053659: #3003, train lang-1 #3357, #3026, #316…
cramforce Nov 7, 2026
304f74a
Merge origin/main (d24d1d0289: #3363, #3052) into train/pi-1
cramforce Nov 7, 2026
f902cb3
Peel the instanceof operand with the shared helper (main does not build)
cramforce Nov 7, 2026
ade95be
Merge origin/main (4e3f07164b: #3364) into train/pi-1
cramforce Nov 7, 2026
4d32ccd
Merge origin/main (293036c528: #3294, #3269, #3253, #3235, #3219, #31…
cramforce Nov 7, 2026
d1d0f8c
Merge origin/main (8ed8c563a6: #3118, #2968, #2832) into train/pi-1
cramforce Nov 7, 2026
47246a8
Merge origin/main (f88df8d2b2: #3114, #3142, train perf-1 #3365, #305…
cramforce Nov 7, 2026
b897651
Merge origin/main (409af2d478: #3367, the child output order fix, the…
cramforce Nov 7, 2026
8cd6877
Pin reduce with a rest callback over dictionary values as compiled
cramforce Nov 7, 2026
473616d
Merge origin/main (the island weak-key change and what follows) into …
cramforce Nov 7, 2026
0850559
Merge origin/main (37323b08f8: #3137, #3070, #2825, #3069, #2861, #33…
cramforce Nov 7, 2026
d69dfc6
Regenerate the runtime refusal baseline on the merged sources
cramforce Nov 7, 2026
fcd162c
Merge fix/main-red-weak-keys at 396d18c2fe (#3371: main's island weak…
cramforce Nov 7, 2026
b6443c6
Regenerate the runtime refusal baseline after merging main's weak-key…
cramforce Nov 7, 2026
4ed676e
Merge origin/main (1dc939974b: #3371, #3023, #2766) into train/pi-1
cramforce Nov 7, 2026
52d490c
Regenerate the runtime refusal baseline after merging main's symbol e…
cramforce Nov 7, 2026
b94769f
Measure the weak-key memory test in bytes per additional key
cramforce Nov 8, 2026
df2a5f2
Merge origin/main (339481db26: #3373, #3375, train islands-1, #3374, …
cramforce Nov 8, 2026
7246933
Merge origin/main (659a1caaa5: train cli-2, computed import specifier…
cramforce Nov 8, 2026
448ebba
Regenerate the island conformance list: three entries this branch moves
cramforce Nov 8, 2026
3f90be2
Merge origin/main (851b59b90f: trains startup-1, cli-4 and cli-5) int…
cramforce Nov 8, 2026
45a103f
Regenerate the island conformance list on main with train startup-1
cramforce Nov 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/content/docs/limitations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ title: "Limitations"

<include>../limitations/builtin-apis/object-freezing.mdx</include>

<include>../limitations/builtin-apis/proxy.mdx</include>

### Builtin function values

<include>../limitations/builtin-function-values.mdx</include>
Expand Down
12 changes: 12 additions & 0 deletions docs/content/limitations/builtin-apis/proxy.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
- **Proxy:** `new Proxy(target, handler)` builds a Proxy for untyped code and for the binding it initializes: reads, writes, `in`, and key listing through that binding go through the handler's traps.
A Proxy cannot stand in for a class instance.
A binding, field, parameter, return value, or array element typed as a class holds native instances only, so a Proxy that the build sees entering one, or asserted to the class, is refused at compile time with `SC1090`.
For a value that forwards to the current instance, export a binding that is reassigned or a function that returns the instance.
A Proxy passed, returned, stored in a field, or asserted where an interface or object type is expected is refused at compile time with `SC1090`, because that slot would hold a copy of the properties, read through the traps once.
A Proxy whose handler is the empty object literal is converted there as its target is.
A Proxy that reaches a typed slot through a parameter or property typed `any` is converted when the statement runs: a class slot throws a `TypeError`, and an interface or object type takes the copy.
A class method that a trap returns is called with the Proxy as `this` and throws a `TypeError`; return the method bound to the instance.
The handler is an untyped object when each trap declares its parameters and result as `any`; a handler whose traps take their types from `ProxyHandler<T>` is refused at compile time with `SC1090`.
A target that is a class instance or an array is refused at compile time with `SC1090`.
A target written as an asserted object literal, such as `{} as Config`, is an untyped object.
Traps over a target that is a typed record throw an `Error` when the Proxy is used.
13 changes: 13 additions & 0 deletions docs/content/limitations/console-and-process-streams.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,16 @@ The record is a separate value: it is not identical to the stream, and it expose
A record type that also declares a data member, such as `isTTY`, throws `SC2002`.
An instance of a stream class such as `Writable` throws `SC2002` in a record type of methods as well.
For those, pass an object literal that wraps the stream: `const sink: Sink = { write: (text: string) => { process.stdout.write(text); } }`.
Under `@types/node`, `process.stdin` passed, stored or returned where `stream.Readable` is declared is one `Readable` over the process's input, and `process.stdout` and `process.stderr` where `stream.Writable` is declared are one `Writable` each.
Every conversion answers the same stream, and a binding of the stream class compares identical to the process stream it was read from.
The stdin stream receives each chunk once, beside any listener registered on `process.stdin` itself, and ends when the input ends.
Listeners registered on `process.stdin` and listeners registered on the stream are kept separately, so for one event their relative order can differ from Node's registration order.
For the same reason `process.stdin.isPaused()` does not report a `pause()` of the stream, and `listenerCount` does not include the listeners Node itself attaches to a pipe or a terminal.
A process stream held as an untyped value does not convert to a stream class: asserting or passing it as `Readable` or `Writable` throws a TypeError.
Passing `process.stdin` where `Duplex` or `EventEmitter` is declared throws the same TypeError.
The bundled declarations declare `process.stdin` by its own members, so these conversions need `@types/node`.
After `process.stdin.setEncoding`, a `'data'` listener registered on `process.stdin` whose parameter is declared `string` receives the decoded chunks, with a multi-byte sequence split across reads kept whole.
A listener whose parameter is a `Buffer` or `Uint8Array`, which includes a parameter with no annotation, throws a TypeError with code `SC2020` at the first chunk, because Node delivers a string there.
`process.stdin.read()` and `for await` over `process.stdin` answer bytes, so after `setEncoding` they throw the same kind of TypeError at the first chunk they would hand out, where Node answers a string.
A `read()` that hands out no chunk (`read(0)`, or a `read()` with nothing held) answers `null` and an iteration that gets no input ends, as in Node.
To read text that way, leave the encoding unset and decode the Buffers with a `TextDecoder`.
4 changes: 3 additions & 1 deletion docs/content/limitations/language-features/generics.mdx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
- **Generics:** Generic functions declared inside other functions, generic class expressions, and generic methods requiring dynamic dispatch are unsupported.
- **Generics:** A generic `function` declared inside another function compiles when the enclosing function only calls it: captured values travel as the instance's parameters, or through a shared closure environment when one of them is reassigned.
Taking such a declaration as a value, or capturing a value whose type is the enclosing function's own type parameter, remains unsupported.
Generic class expressions and generic methods requiring dynamic dispatch are unsupported.
Generic classes can extend generic bases when each specialization has a concrete layout.
Independent concrete uses have no specialization-count limit; recursively expanding demands and type layouts produce diagnostics.
Other generic calls compile when the target resolves statically.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,17 @@ Assigning an existing value to a binding that keeps its initializer's layout, to
The refusal covers a short-circuit assignment that stores the value (`&&=`, or `??=` on a binding that can be nullish) like the plain assignment it stands for.
A member of another binding that kept its initializer's layout carries that layout into the store, so no refusal is reported when the two layouts already match.
Bracket writes such as `alias["k"] = v` write the field in the kept layout, like their dotted spelling.
The members of a union type that share one value of its discriminant property, such as two `{ type: "retry" }` members with different other properties, are stored as one record that has the properties of all of them, and a value of one of those member types is that record: it keeps its identity when it is stored in the union, narrowed, or passed as the member type.
A value whose type is not one of those members but has the properties of one, such as an object held in a binding whose type was inferred, would be copied into that record, so `scriptc build` reports `SC1090` for it; declaring the value with the union's type or the member's type compiles.
Reading a property that one of those members requires, from a value that an assertion claimed to be that member and that lacks the property, throws a `TypeError` where Node.js answers `undefined`.

Typed records with declared fields, indexed records, and arrays retain identity and mutations through native checked storage.
A record or class instance converted to a string-keyed dictionary type such as `Record<string, string>`, directly, through a `{}`, `object` or `unknown` binding or parameter, or as an element of a constant `unknown[]` array that holds such records, keeps its identity when the program writes through, compares or inspects values of that dictionary type.
Every dictionary type with the same value type then uses checked dynamic storage, which is slower than a native dictionary.
The value type is compared by structure, so a dictionary type is the same type whether it is written inline, through an alias, as a generic instantiation, as `Record<string, V>`, under `Readonly`, in another module or in a declaration file; a `readonly` modifier does not make another type, and arrays, tuples and class instances are the same only as instantiations of one type with the same type arguments.
A dictionary that keeps its identity is copied where it is converted to a dictionary type with another value type, such as a `Record<string, number>` stored as a `Record<string, number | string>`, and `SC6001` reports the conversion where the copy is then written or compared.
A union type that refers to itself and holds such a dictionary, such as a JSON value type `string | number | Json[] | { [key: string]: Json }`, uses checked dynamic storage as a whole.
`scriptc build` reports `SC2009` for such a union when another of its members, such as a `Map`, cannot be held in checked dynamic storage.
Class instances retain identity at their exact type or a base class, and at any interface or object type that a class instance is passed, stored, returned, or asserted as when the program could tell a copy from the instance: values of such a type are checked views of the original object, so writes, identity comparisons, Set and Map keys, `util.inspect`, and `JSON.stringify` through them reach the instance, as in Node.js.
These types use checked dynamic storage, which is slower than native record fields, for all of their values, including plain objects.
A type whose values are only read field by field, from fields the class does not write after construction and does not implement as accessors, stays a native record and holds a copy.
Expand Down
7 changes: 7 additions & 0 deletions docs/content/limitations/runtime-type-checks.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ Reading a value that does not match the dictionary's value type throws a `TypeEr
Casts between program classes are checked too: casting an instance to a class it does not extend throws a `TypeError`, where Node.js reads the members structurally.
`SC6004` reports calls that pass such an instance to a function that casts it.

An object whose methods are typed by a generic interface can be stored as another instantiation of that interface, such as a `Provider<"a" | "b">` listed in a `Provider<Api>[]`.
Each such method then checks its arguments against its own parameter types when it is called.
An argument that holds a union member the parameter type does not include throws a `TypeError`, where Node.js passes the object through.
When that member is an object type with only optional properties, the argument is read as the member of the parameter type that declares the properties the object has, as in Node.js.
It throws a `TypeError` only when no single member declares all of them.
The method receives a copy of an argument record whose type differs between the two instantiations, so a write to that argument in the method does not reach the caller's object, and `SC6001` does not report it.

A Promise converted from `unknown` to a typed result validates its fulfilled value.
A mismatch rejects with a `TypeError`.
Rejection reasons and reference equality are preserved across conversions.
Expand Down
2 changes: 2 additions & 0 deletions internal/compatibility/generated/node-v24-internal.json
Original file line number Diff line number Diff line change
Expand Up @@ -52860,6 +52860,7 @@
"tests/corpus/fetch-headers-copy-cache.ts",
"tests/corpus/fetch-headers-set-cookie-iteration.ts",
"tests/corpus/headers-static-accessors.ts",
"tests/corpus/headers-typed-iteration.ts",
"tests/corpus/js-abort-portable.js",
"tests/corpus/node24-url-factories.ts",
"tests/corpus/node24-url-mutation.ts",
Expand Down Expand Up @@ -53607,6 +53608,7 @@
"tests/corpus/fetch-headers-copy-cache.ts",
"tests/corpus/fetch-headers-set-cookie-iteration.ts",
"tests/corpus/headers-static-accessors.ts",
"tests/corpus/headers-typed-iteration.ts",
"tests/corpus/7735-untyped-headers-iterators.js"
]
},
Expand Down
2 changes: 1 addition & 1 deletion internal/compatibility/static-support.json
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@
{ "chapter": "globals", "symbols": ["URL", "URLSearchParams"], "status": "partial", "evidence": ["tests/corpus/1355-url-parse.ts", "tests/corpus/1791-searchparams-core.ts", "tests/corpus/1792-searchparams-encoding.ts", "tests/corpus/1793-searchparams-iteration.ts", "tests/corpus/1794-searchparams-url-live.ts", "tests/corpus/node24-url-mutation.ts", "tests/corpus/node24-url-factories.ts"] },
{ "chapter": "globals", "symbols": ["structuredClone"], "status": "partial", "evidence": ["tests/corpus/2283-structured-clone.cjs", "tests/corpus/5324-structured-clone-documents.ts"] },
{ "chapter": "globals", "signatures": ["Class: `TextEncoder`", "Class: `TextDecoder`"], "status": "partial", "evidence": ["tests/corpus/1423-text-codec.ts", "tests/corpus/text-codec-values/main.ts", "tests/corpus/3133-text-decoder-streaming.ts", "tests/corpus/7747-text-codec-untyped-slot.js"] },
{ "chapter": "globals", "signatures": ["Class: `Headers`"], "status": "partial", "evidence": ["tests/corpus/fetch-headers-copy-cache.ts", "tests/corpus/fetch-headers-set-cookie-iteration.ts", "tests/corpus/headers-static-accessors.ts", "tests/corpus/7735-untyped-headers-iterators.js"] },
{ "chapter": "globals", "signatures": ["Class: `Headers`"], "status": "partial", "evidence": ["tests/corpus/fetch-headers-copy-cache.ts", "tests/corpus/fetch-headers-set-cookie-iteration.ts", "tests/corpus/headers-static-accessors.ts", "tests/corpus/headers-typed-iteration.ts", "tests/corpus/7735-untyped-headers-iterators.js"] },
{ "chapter": "globals", "signatures": ["Class: `Blob`", "Class: `File`"], "status": "partial", "evidence": ["tests/corpus/5285-blob-construct.ts", "tests/corpus/5286-blob-readers.ts", "tests/corpus/5287-blob-inspect.ts", "tests/corpus/5288-blob-validation.js", "tests/corpus/5290-blob-dynamic.js"] },
{ "chapter": "buffer", "signatures": ["Class: `Blob`", "Class: `File`"], "status": "partial", "evidence": ["tests/corpus/5285-blob-construct.ts", "tests/corpus/5288-blob-validation.js", "tests/fixtures/node-types/blob-file.ts"] },
{ "chapter": "buffer", "signatures": ["`blob.arrayBuffer()`", "`blob.bytes()`", "`blob.text()`", "`blob.slice([start[, end[, type]]])`", "`blob.size`", "`type` Type: {string}", "`name` Type: {string}", "`lastModified` Type: {number}"], "status": "supported", "evidence": ["tests/corpus/5285-blob-construct.ts", "tests/corpus/5286-blob-readers.ts", "tests/corpus/5288-blob-validation.js", "tests/corpus/5289-blob-read-order.ts", "tests/corpus/5290-blob-dynamic.js", "tests/fixtures/node-types/blob-file.ts"] },
Expand Down
25 changes: 13 additions & 12 deletions packages/compiler/ambient/node-fallback/child_process.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@ declare module "child_process" {
* pipes an empty stdin), shell (the complete command line in
* `command`, with a statically empty args list, run by /bin/sh -c),
* and windowsHide (a POSIX no-op).
* The shell form takes no separate args: Node warns DEP0190 because it
* concatenates them unescaped, and a native build has no warning
* channel, so the compiler REFUSES `shell: true` with a non-empty args
* list. */
* The shell form joins a non-empty args list onto the command, as Node
* does: the arguments are concatenated unescaped, never quoted, and
* the first such call of a process reports the DEP0190 warning on
* stderr. */
export interface SpawnSyncOptions {
encoding?: "utf8" | "utf-8";
timeout?: number;
Expand All @@ -61,8 +61,8 @@ declare module "child_process" {
/* Node's shell form: the complete command line in `command`, with
* an empty args list, runs through /bin/sh -c, so quoting and
* operators follow the shell's rules. A non-empty args list with
* shell: true is a compile error (Node warns DEP0190 for unescaped
* shell arguments). */
* shell: true joins onto the command unescaped, and Node's DEP0190
* warning is shown. */
shell?: boolean;
}
export function spawnSync(
Expand Down Expand Up @@ -92,9 +92,9 @@ declare module "child_process" {
stdio?: "pipe" | "ignore" | "inherit" | ("pipe" | "ignore" | "inherit")[];
timeout?: number;
windowsHide?: boolean;
/* Read at the call. The call then takes the command-line form only:
* a statically non-empty args list is a compile error (Node warns
* DEP0190 for unescaped shell arguments). */
/* Read at the call. When it is on, a non-empty args list joins onto
* the command unescaped and Node's DEP0190 warning is issued; when
* off, the list is the arguments passed. */
shell?: boolean;
}

Expand Down Expand Up @@ -202,9 +202,10 @@ declare module "child_process" {
/* detached gives the child its own session and process group
* (POSIX_SPAWN_SETSID); env REPLACES the child environment; cwd
* sets its working directory; windowsHide is a POSIX no-op; shell
* runs the complete command string through /bin/sh or cmd.exe (with
* an empty args list — a non-empty one is a compile error, because
* Node warns DEP0190 for unescaped shell arguments). */
* (a literal or a boolean decided at run time) runs the command line
* through /bin/sh or cmd.exe. A non-empty args list joins onto the
* command unescaped where the shell is on, and Node's DEP0190 warning
* is reported for the first such call. */
detached?: boolean;
env?: { [k: string]: string | undefined };
cwd?: string;
Expand Down
15 changes: 13 additions & 2 deletions packages/compiler/ambient/scriptc-node-fallback.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,10 @@ declare var process: {
* resume, isPaused, read, readableLength), destroy() (full teardown:
* nothing fires after, the loop stops waiting), and async iteration
* (`for await (const chunk of process.stdin)` — chunks are Uint8Array
* values, ending at EOF). setEncoding has no lowering (chunks stay
* bytes; decode with TextDecoder). */
* values, ending at EOF). setEncoding decodes the chunks a 'data'
* listener with a string parameter receives. read() and async iteration
* answer bytes, so once an encoding is set they throw (Node answers
* strings there): leave the encoding unset and decode with TextDecoder. */
stdin: {
readonly isTTY: boolean;
/* The descriptor the stream is built over (Node reports 0 here and
Expand All @@ -384,6 +386,11 @@ declare var process: {
* undefined on a non-TTY stdin (the `x || false` idiom). */
readonly isRaw: boolean;
on(event: "data", listener: (chunk: Uint8Array) => void): void;
/* After setEncoding the chunks are strings: a listener that declares
* its parameter string receives the decoded text. A listener compiled
* for bytes (the overload above, which an unannotated parameter takes)
* throws at the first chunk once an encoding is set. */
on(event: "data", listener: (chunk: string) => void): void;
on(event: "end", listener: () => void): void;
on(event: "error", listener: (err: Error) => void): void;
/* Paused mode, as in Node: input stays buffered for read(), and the
Expand All @@ -396,6 +403,7 @@ declare var process: {
listener: (str: string | undefined, key: import("readline").Key) => void,
): void;
once(event: "data", listener: (chunk: Uint8Array) => void): void;
once(event: "data", listener: (chunk: string) => void): void;
once(event: "end", listener: () => void): void;
once(event: "error", listener: (err: Error) => void): void;
once(event: "readable", listener: () => void): void;
Expand Down Expand Up @@ -1389,6 +1397,9 @@ interface Headers {
callbackfn: (value: string, key: string, parent: Headers) => void,
thisArg?: unknown,
): void;
entries(): IterableIterator<[string, string]>;
keys(): IterableIterator<string>;
values(): IterableIterator<string>;
[Symbol.iterator](): IterableIterator<[string, string]>;
}
declare var Headers: {
Expand Down
2 changes: 2 additions & 0 deletions packages/compiler/src/backend/executable-features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,10 @@ export function executableLinkFeatures(
...(features.promiseGeneric ? { promiseGeneric: true } : {}),
...(features.dynTier ? { dynTier: true } : {}),
...(features.streamDyn ? { streamDyn: true } : {}),
...(features.streamStdin ? { streamStdin: true } : {}),
...(features.handleProps ? { handleProps: true } : {}),
...(features.childLifecycle ? { childLifecycle: true } : {}),
...(features.childShellLine ? { childShellLine: true } : {}),
...(features.childOptionExt ? { childOptionExt: true } : {}),
...(features.spawnCaptureBytes ? { spawnCaptureBytes: true } : {}),
...(features.childErrorFields ? { childErrorFields: true } : {}),
Expand Down
Loading
Loading