printable-shell-command 0.2.0 → 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 +6 -4
- package/src/index.ts +103 -8
- 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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "printable-shell-command",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"main": "./src/index.ts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -9,11 +9,13 @@
|
|
|
9
9
|
"import": "./src/index.ts"
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
|
-
"
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"@biomejs/biome": "^1.9.4",
|
|
13
14
|
"@types/bun": "^1.2.11",
|
|
14
15
|
"@types/node": "^22.15.3"
|
|
15
16
|
},
|
|
16
|
-
"
|
|
17
|
-
"@
|
|
17
|
+
"optionalDependencies": {
|
|
18
|
+
"@types/bun": "^1.2.11",
|
|
19
|
+
"@types/node": "^22.15.3"
|
|
18
20
|
}
|
|
19
21
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ChildProcess as NodeChildProcess,
|
|
3
|
+
SpawnOptions as NodeSpawnOptions,
|
|
3
4
|
SpawnOptionsWithStdioTuple as NodeSpawnOptionsWithStdioTuple,
|
|
5
|
+
SpawnOptionsWithoutStdio as NodeSpawnOptionsWithoutStdio,
|
|
4
6
|
StdioNull as NodeStdioNull,
|
|
5
7
|
StdioPipe as NodeStdioPipe,
|
|
6
|
-
SpawnOptions as NodeSpawnOptions,
|
|
7
|
-
SpawnOptionsWithoutStdio as NodeSpawnOptionsWithoutStdio,
|
|
8
8
|
} from "node:child_process";
|
|
9
9
|
import type {
|
|
10
10
|
SpawnOptions as BunSpawnOptions,
|
|
@@ -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,12 +283,58 @@ export class PrintableShellCommand {
|
|
|
282
283
|
Stdout extends NodeStdioNull | NodeStdioPipe,
|
|
283
284
|
Stderr extends NodeStdioNull | NodeStdioPipe,
|
|
284
285
|
>(
|
|
285
|
-
options
|
|
286
|
-
|
|
286
|
+
options?:
|
|
287
|
+
| NodeSpawnOptions
|
|
288
|
+
| NodeSpawnOptionsWithoutStdio
|
|
289
|
+
| NodeSpawnOptionsWithStdioTuple<Stdin, Stdout, Stderr>,
|
|
287
290
|
): // TODO: figure out how to return `ChildProcessByStdio<…>` without duplicating fragile boilerplate.
|
|
288
|
-
NodeChildProcess {
|
|
291
|
+
NodeChildProcess & { success: Promise<void> } {
|
|
289
292
|
const { spawn } = process.getBuiltinModule("node:child_process");
|
|
290
|
-
|
|
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;
|
|
291
338
|
}
|
|
292
339
|
|
|
293
340
|
// The returned subprocess includes a `.success` `Promise` field, per https://github.com/oven-sh/bun/issues/8313
|
|
@@ -298,6 +345,9 @@ export class PrintableShellCommand {
|
|
|
298
345
|
>(
|
|
299
346
|
options?: Omit<BunSpawnOptions.OptionsObject<In, Out, Err>, "cmd">,
|
|
300
347
|
): BunSubprocess<In, Out, Err> & { success: Promise<void> } {
|
|
348
|
+
if (options && "cmd" in options) {
|
|
349
|
+
throw new Error("Unexpected `cmd` field.");
|
|
350
|
+
}
|
|
301
351
|
const { spawn } = process.getBuiltinModule("bun") as typeof import("bun");
|
|
302
352
|
const subprocess = spawn({
|
|
303
353
|
...options,
|
|
@@ -311,7 +361,11 @@ export class PrintableShellCommand {
|
|
|
311
361
|
if (exitCode === 0) {
|
|
312
362
|
resolve();
|
|
313
363
|
} else {
|
|
314
|
-
reject(
|
|
364
|
+
reject(
|
|
365
|
+
new Error(
|
|
366
|
+
`Command failed with non-zero exit code: ${exitCode}`,
|
|
367
|
+
),
|
|
368
|
+
);
|
|
315
369
|
}
|
|
316
370
|
})
|
|
317
371
|
.catch(reject),
|
|
@@ -321,4 +375,45 @@ export class PrintableShellCommand {
|
|
|
321
375
|
});
|
|
322
376
|
return subprocess;
|
|
323
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
|
+
}
|
|
324
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();
|