printable-shell-command 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -1
- package/package.json +1 -1
- package/src/index.ts +98 -5
- package/test/simple-test-bun.ts +1 -3
- package/test/simple-test-node.ts +1 -5
package/README.md
CHANGED
|
@@ -47,7 +47,11 @@ import { PrintableShellCommand } from "printable-shell-command";
|
|
|
47
47
|
import { spawn } from "node:child_process";
|
|
48
48
|
|
|
49
49
|
const command = new PrintableShellCommand(/* … */);
|
|
50
|
-
const child_process = spawn(...command.
|
|
50
|
+
const child_process = spawn(...command.toCommandWithFlatAr()); // Note the `...`
|
|
51
|
+
|
|
52
|
+
// or directly
|
|
53
|
+
await command.spawnNode().success;
|
|
54
|
+
await command.spawnNodeInherit().success;
|
|
51
55
|
```
|
|
52
56
|
|
|
53
57
|
### Spawn a process in `bun`
|
|
@@ -58,6 +62,10 @@ import { spawn } from "bun";
|
|
|
58
62
|
|
|
59
63
|
const command = new PrintableShellCommand(/* … */);
|
|
60
64
|
await spawn(command.toFlatCommand()).exited;
|
|
65
|
+
|
|
66
|
+
// or directly
|
|
67
|
+
await command.spawnBun().success;
|
|
68
|
+
await command.spawnBunInherit().success;
|
|
61
69
|
```
|
|
62
70
|
|
|
63
71
|
## Protections
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -273,8 +273,9 @@ export class PrintableShellCommand {
|
|
|
273
273
|
return serializedEntries.join(this.#entrySeparator(options));
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
-
public print(options?: PrintOptions):
|
|
276
|
+
public print(options?: PrintOptions): PrintableShellCommand {
|
|
277
277
|
console.log(this.getPrintableCommand(options));
|
|
278
|
+
return this;
|
|
278
279
|
}
|
|
279
280
|
|
|
280
281
|
public spawnNode<
|
|
@@ -282,14 +283,58 @@ export class PrintableShellCommand {
|
|
|
282
283
|
Stdout extends NodeStdioNull | NodeStdioPipe,
|
|
283
284
|
Stderr extends NodeStdioNull | NodeStdioPipe,
|
|
284
285
|
>(
|
|
285
|
-
options
|
|
286
|
+
options?:
|
|
286
287
|
| NodeSpawnOptions
|
|
287
288
|
| NodeSpawnOptionsWithoutStdio
|
|
288
289
|
| NodeSpawnOptionsWithStdioTuple<Stdin, Stdout, Stderr>,
|
|
289
290
|
): // TODO: figure out how to return `ChildProcessByStdio<…>` without duplicating fragile boilerplate.
|
|
290
|
-
NodeChildProcess {
|
|
291
|
+
NodeChildProcess & { success: Promise<void> } {
|
|
291
292
|
const { spawn } = process.getBuiltinModule("node:child_process");
|
|
292
|
-
|
|
293
|
+
const subprocess = spawn(...this.forNode(), options) as NodeChildProcess & {
|
|
294
|
+
success: Promise<void>;
|
|
295
|
+
};
|
|
296
|
+
Object.defineProperty(subprocess, "success", {
|
|
297
|
+
get() {
|
|
298
|
+
return new Promise<void>((resolve, reject) =>
|
|
299
|
+
this.addListener(
|
|
300
|
+
"exit",
|
|
301
|
+
(exitCode: number /* we only use the first arg */) => {
|
|
302
|
+
if (exitCode === 0) {
|
|
303
|
+
resolve();
|
|
304
|
+
} else {
|
|
305
|
+
reject(`Command failed with non-zero exit code: ${exitCode}`);
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
),
|
|
309
|
+
);
|
|
310
|
+
},
|
|
311
|
+
enumerable: false,
|
|
312
|
+
});
|
|
313
|
+
return subprocess;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// A wrapper for `.spawnNode(…)` that sets stdio to `"inherit"` (common for
|
|
317
|
+
// invoking commands from scripts whose output and interaction should be
|
|
318
|
+
// surfaced to the user).
|
|
319
|
+
public spawnNodeInherit(
|
|
320
|
+
options?: Omit<NodeSpawnOptions, "stdio">,
|
|
321
|
+
): NodeChildProcess & { success: Promise<void> } {
|
|
322
|
+
if (options && "stdio" in options) {
|
|
323
|
+
throw new Error("Unexpected `stdio` field.");
|
|
324
|
+
}
|
|
325
|
+
return this.spawnNode({ ...options, stdio: "inherit" });
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/** Equivalent to:
|
|
329
|
+
*
|
|
330
|
+
* ```
|
|
331
|
+
* await this.print().spawnNodeInherit().success;
|
|
332
|
+
* ```
|
|
333
|
+
*/
|
|
334
|
+
public async shellOutNode(
|
|
335
|
+
options?: Omit<NodeSpawnOptions, "stdio">,
|
|
336
|
+
): Promise<void> {
|
|
337
|
+
await this.print().spawnNodeInherit(options).success;
|
|
293
338
|
}
|
|
294
339
|
|
|
295
340
|
// The returned subprocess includes a `.success` `Promise` field, per https://github.com/oven-sh/bun/issues/8313
|
|
@@ -300,6 +345,9 @@ export class PrintableShellCommand {
|
|
|
300
345
|
>(
|
|
301
346
|
options?: Omit<BunSpawnOptions.OptionsObject<In, Out, Err>, "cmd">,
|
|
302
347
|
): BunSubprocess<In, Out, Err> & { success: Promise<void> } {
|
|
348
|
+
if (options && "cmd" in options) {
|
|
349
|
+
throw new Error("Unexpected `cmd` field.");
|
|
350
|
+
}
|
|
303
351
|
const { spawn } = process.getBuiltinModule("bun") as typeof import("bun");
|
|
304
352
|
const subprocess = spawn({
|
|
305
353
|
...options,
|
|
@@ -313,7 +361,11 @@ export class PrintableShellCommand {
|
|
|
313
361
|
if (exitCode === 0) {
|
|
314
362
|
resolve();
|
|
315
363
|
} else {
|
|
316
|
-
reject(
|
|
364
|
+
reject(
|
|
365
|
+
new Error(
|
|
366
|
+
`Command failed with non-zero exit code: ${exitCode}`,
|
|
367
|
+
),
|
|
368
|
+
);
|
|
317
369
|
}
|
|
318
370
|
})
|
|
319
371
|
.catch(reject),
|
|
@@ -323,4 +375,45 @@ export class PrintableShellCommand {
|
|
|
323
375
|
});
|
|
324
376
|
return subprocess;
|
|
325
377
|
}
|
|
378
|
+
|
|
379
|
+
// A wrapper for `.spawnBunInherit(…)` that sets stdio to `"inherit"` (common for
|
|
380
|
+
// invoking commands from scripts whose output and interaction should be
|
|
381
|
+
// surfaced to the user).
|
|
382
|
+
public spawnBunInherit(
|
|
383
|
+
options?: Omit<
|
|
384
|
+
Omit<
|
|
385
|
+
BunSpawnOptions.OptionsObject<"inherit", "inherit", "inherit">,
|
|
386
|
+
"cmd"
|
|
387
|
+
>,
|
|
388
|
+
"stdio"
|
|
389
|
+
>,
|
|
390
|
+
): BunSubprocess<"inherit", "inherit", "inherit"> & {
|
|
391
|
+
success: Promise<void>;
|
|
392
|
+
} {
|
|
393
|
+
if (options && "stdio" in options) {
|
|
394
|
+
throw new Error("Unexpected `stdio` field.");
|
|
395
|
+
}
|
|
396
|
+
return this.spawnBun({
|
|
397
|
+
...options,
|
|
398
|
+
stdio: ["inherit", "inherit", "inherit"],
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/** Equivalent to:
|
|
403
|
+
*
|
|
404
|
+
* ```
|
|
405
|
+
* await this.print().spawnBunInherit().success;
|
|
406
|
+
* ```
|
|
407
|
+
*/
|
|
408
|
+
public async shellOutBun(
|
|
409
|
+
options?: Omit<
|
|
410
|
+
Omit<
|
|
411
|
+
BunSpawnOptions.OptionsObject<"inherit", "inherit", "inherit">,
|
|
412
|
+
"cmd"
|
|
413
|
+
>,
|
|
414
|
+
"stdio"
|
|
415
|
+
>,
|
|
416
|
+
): Promise<void> {
|
|
417
|
+
await this.print().spawnBunInherit(options).success;
|
|
418
|
+
}
|
|
326
419
|
}
|
package/test/simple-test-bun.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { spawn } from "bun";
|
|
2
1
|
import { PrintableShellCommand } from "../src";
|
|
3
2
|
|
|
4
3
|
const command = new PrintableShellCommand("ffmpeg", [
|
|
@@ -8,5 +7,4 @@ const command = new PrintableShellCommand("ffmpeg", [
|
|
|
8
7
|
"./test/My video (slow-mo).mov",
|
|
9
8
|
]);
|
|
10
9
|
|
|
11
|
-
command.
|
|
12
|
-
await spawn(command.toFlatCommand()).exited;
|
|
10
|
+
await command.shellOutBun();
|
package/test/simple-test-node.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
1
|
import { PrintableShellCommand } from "../src";
|
|
3
2
|
|
|
4
3
|
const command = new PrintableShellCommand("ffmpeg", [
|
|
@@ -8,7 +7,4 @@ const command = new PrintableShellCommand("ffmpeg", [
|
|
|
8
7
|
"./test/My video (slow-mo).mov",
|
|
9
8
|
]);
|
|
10
9
|
|
|
11
|
-
command.print();
|
|
12
|
-
await new Promise((resolve, reject) => {
|
|
13
|
-
spawn(...command.toCommandWithFlatArgs()).addListener("exit", resolve);
|
|
14
|
-
});
|
|
10
|
+
command.print().shellOutNode();
|