BREAKING(unstable): Improve Deno.spawn() stdio API (#14919)

- "SpawnOutput" extends "ChildStatus" instead of composing it
- "SpawnOutput::stdout", "SpawnOutput::stderr", "Child::stdin", 
"Child::stdout" and "Child::stderr" are no longer optional, instead 
made them getters that throw at runtime if that stream wasn't set 
to "piped". 
- Remove the complicated "<T extends SpawnOptions = SpawnOptions>" 
which we currently need to give proper type hints for the availability of 
these fields. Their typings for these would get increasingly complex 
if it became dependent on more options (e.g. "SpawnOptions::pty" 
which if set should make the stdio streams unavailable)
This commit is contained in:
Nayeem Rahman 2022-07-18 14:16:12 +01:00 committed by GitHub
parent 0f6b455c96
commit 45c49034a7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 176 additions and 149 deletions

View file

@ -77,21 +77,27 @@
return this.#pid;
}
#stdinRid;
#stdin = null;
get stdin() {
if (this.#stdin == null) {
throw new TypeError("stdin is not piped");
}
return this.#stdin;
}
#stdoutRid;
#stdout = null;
get stdout() {
if (this.#stdout == null) {
throw new TypeError("stdout is not piped");
}
return this.#stdout;
}
#stderrRid;
#stderr = null;
get stderr() {
if (this.#stderr == null) {
throw new TypeError("stderr is not piped");
}
return this.#stderr;
}
@ -111,17 +117,14 @@
this.#pid = pid;
if (stdinRid !== null) {
this.#stdinRid = stdinRid;
this.#stdin = writableStreamForRid(stdinRid);
}
if (stdoutRid !== null) {
this.#stdoutRid = stdoutRid;
this.#stdout = readableStreamForRid(stdoutRid);
}
if (stderrRid !== null) {
this.#stderrRid = stderrRid;
this.#stderr = readableStreamForRid(stderrRid);
}
@ -159,9 +162,21 @@
]);
return {
status,
stdout,
stderr,
success: status.success,
code: status.code,
signal: status.signal,
get stdout() {
if (stdout == null) {
throw new TypeError("stdout is not piped");
}
return stdout;
},
get stderr() {
if (stderr == null) {
throw new TypeError("stderr is not piped");
}
return stderr;
},
};
}
@ -198,7 +213,7 @@
"Piped stdin is not supported for this function, use 'Deno.spawnChild()' instead",
);
}
return core.opSync("op_spawn_sync", {
const result = core.opSync("op_spawn_sync", {
cmd: pathFromURL(command),
args: ArrayPrototypeMap(args, String),
cwd: pathFromURL(cwd),
@ -210,6 +225,23 @@
stdout,
stderr,
});
return {
success: result.status.success,
code: result.status.code,
signal: result.status.signal,
get stdout() {
if (result.stdout == null) {
throw new TypeError("stdout is not piped");
}
return result.stdout;
},
get stderr() {
if (result.stderr == null) {
throw new TypeError("stderr is not piped");
}
return result.stderr;
},
};
}
window.__bootstrap.spawn = {