printable-shell-command 0.3.0 → 0.3.2

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 CHANGED
@@ -47,7 +47,7 @@ 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.toCommandWithFlatAr()); // Note the `...`
50
+ const child_process = spawn(...command.toCommandWithFlatArgs()); // Note the `...`
51
51
 
52
52
  // or directly
53
53
  await command.spawnNode().success;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "printable-shell-command",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "main": "./src/index.ts",
5
5
  "type": "module",
6
6
  "exports": {
@@ -17,5 +17,10 @@
17
17
  "optionalDependencies": {
18
18
  "@types/bun": "^1.2.11",
19
19
  "@types/node": "^22.15.3"
20
- }
20
+ },
21
+ "files": [
22
+ "README.md",
23
+ "src",
24
+ "tsconfig.json"
25
+ ]
21
26
  }
package/src/index.ts CHANGED
@@ -278,6 +278,9 @@ export class PrintableShellCommand {
278
278
  return this;
279
279
  }
280
280
 
281
+ /**
282
+ * The returned child process includes a `.success` `Promise` field, per https://github.com/oven-sh/bun/issues/8313
283
+ */
281
284
  public spawnNode<
282
285
  Stdin extends NodeStdioNull | NodeStdioPipe,
283
286
  Stdout extends NodeStdioNull | NodeStdioPipe,
@@ -290,6 +293,7 @@ export class PrintableShellCommand {
290
293
  ): // TODO: figure out how to return `ChildProcessByStdio<…>` without duplicating fragile boilerplate.
291
294
  NodeChildProcess & { success: Promise<void> } {
292
295
  const { spawn } = process.getBuiltinModule("node:child_process");
296
+ // @ts-ignore: The TypeScript checker has trouble reconciling the optional (i.e. potentially `undefined`) `options` with the third argument.
293
297
  const subprocess = spawn(...this.forNode(), options) as NodeChildProcess & {
294
298
  success: Promise<void>;
295
299
  };
@@ -313,9 +317,9 @@ export class PrintableShellCommand {
313
317
  return subprocess;
314
318
  }
315
319
 
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).
320
+ /** A wrapper for `.spawnNode(…)` that sets stdio to `"inherit"` (common for
321
+ * invoking commands from scripts whose output and interaction should be
322
+ * surfaced to the user). */
319
323
  public spawnNodeInherit(
320
324
  options?: Omit<NodeSpawnOptions, "stdio">,
321
325
  ): NodeChildProcess & { success: Promise<void> } {
@@ -337,7 +341,9 @@ export class PrintableShellCommand {
337
341
  await this.print().spawnNodeInherit(options).success;
338
342
  }
339
343
 
340
- // The returned subprocess includes a `.success` `Promise` field, per https://github.com/oven-sh/bun/issues/8313
344
+ /**
345
+ * The returned subprocess includes a `.success` `Promise` field, per https://github.com/oven-sh/bun/issues/8313
346
+ */
341
347
  public spawnBun<
342
348
  const In extends BunSpawnOptions.Writable = "ignore",
343
349
  const Out extends BunSpawnOptions.Readable = "pipe",
@@ -376,9 +382,11 @@ export class PrintableShellCommand {
376
382
  return subprocess;
377
383
  }
378
384
 
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).
385
+ /**
386
+ * A wrapper for `.spawnBunInherit(…)` that sets stdio to `"inherit"` (common
387
+ * for invoking commands from scripts whose output and interaction should be
388
+ * surfaced to the user).
389
+ */
382
390
  public spawnBunInherit(
383
391
  options?: Omit<
384
392
  Omit<
@@ -399,6 +407,24 @@ export class PrintableShellCommand {
399
407
  });
400
408
  }
401
409
 
410
+ /** Equivalent to:
411
+ *
412
+ * ```
413
+ * new Response(this.spawnBun(options).stdout);
414
+ * ```
415
+ */
416
+ public spawnBunStdout(
417
+ options?: Omit<
418
+ Omit<
419
+ BunSpawnOptions.OptionsObject<"inherit", "inherit", "inherit">,
420
+ "cmd"
421
+ >,
422
+ "stdio"
423
+ >,
424
+ ): Response {
425
+ return new Response(this.spawnBun(options).stdout);
426
+ }
427
+
402
428
  /** Equivalent to:
403
429
  *
404
430
  * ```
@@ -1,14 +0,0 @@
1
- name: CI
2
-
3
- on: [push, pull_request]
4
-
5
- jobs:
6
- test:
7
- runs-on: ubuntu-latest
8
-
9
- steps:
10
- - uses: actions/checkout@v4
11
- - uses: oven-sh/setup-bun@v1
12
- - run: make setup
13
- - run: make lint
14
- - run: make test-js
@@ -1,13 +0,0 @@
1
- name: Publish GitHub release
2
-
3
- on:
4
- push:
5
- tags:
6
- - v*
7
-
8
- jobs:
9
- Publish:
10
- permissions:
11
- contents: write
12
- if: startsWith(github.ref, 'refs/tags/v')
13
- uses: cubing/actions-workflows/.github/workflows/publish-github-release.yaml@main
package/Makefile DELETED
@@ -1,35 +0,0 @@
1
- .PHONY: test
2
- test: lint test-js
3
-
4
- .PHONY: lint
5
- lint: setup
6
- bun x @biomejs/biome check
7
-
8
- .PHONY: format
9
- format: setup
10
- bun x @biomejs/biome check --write
11
-
12
- .PHONY: test-js
13
- test-js: setup
14
- bun test
15
-
16
- # https://github.com/lgarron/repo
17
- REPO_COMMANDS = publish
18
-
19
- publish: setup
20
-
21
- .PHONY: ${REPO_COMMANDS}
22
- ${REPO_COMMANDS}:
23
- repo $@
24
-
25
- .PHONY: setup
26
- setup:
27
- bun install --frozen-lockfile
28
-
29
- .PHONY: clean
30
- clean:
31
- # No-op
32
-
33
- .PHONY: reset
34
- reset: clean
35
- rm -rf ./node_modules
package/biome.json DELETED
@@ -1,12 +0,0 @@
1
- {
2
- "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
3
- "files": {
4
- "ignore": ["./dist", "./package.json", "./target"]
5
- },
6
- "linter": {
7
- "enabled": true,
8
- "rules": {
9
- "recommended": true
10
- }
11
- }
12
- }
package/bun.lock DELETED
@@ -1,46 +0,0 @@
1
- {
2
- "lockfileVersion": 1,
3
- "workspaces": {
4
- "": {
5
- "name": "printable-shell-command",
6
- "dependencies": {
7
- "@types/bun": "^1.2.11",
8
- "@types/node": "^22.15.3",
9
- },
10
- "devDependencies": {
11
- "@biomejs/biome": "^1.9.4",
12
- },
13
- },
14
- },
15
- "packages": {
16
- "@biomejs/biome": ["@biomejs/biome@1.9.4", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "1.9.4", "@biomejs/cli-darwin-x64": "1.9.4", "@biomejs/cli-linux-arm64": "1.9.4", "@biomejs/cli-linux-arm64-musl": "1.9.4", "@biomejs/cli-linux-x64": "1.9.4", "@biomejs/cli-linux-x64-musl": "1.9.4", "@biomejs/cli-win32-arm64": "1.9.4", "@biomejs/cli-win32-x64": "1.9.4" }, "bin": { "biome": "bin/biome" } }, "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog=="],
17
-
18
- "@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@1.9.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw=="],
19
-
20
- "@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@1.9.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg=="],
21
-
22
- "@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@1.9.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g=="],
23
-
24
- "@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@1.9.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA=="],
25
-
26
- "@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@1.9.4", "", { "os": "linux", "cpu": "x64" }, "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg=="],
27
-
28
- "@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@1.9.4", "", { "os": "linux", "cpu": "x64" }, "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg=="],
29
-
30
- "@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@1.9.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg=="],
31
-
32
- "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@1.9.4", "", { "os": "win32", "cpu": "x64" }, "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA=="],
33
-
34
- "@types/bun": ["@types/bun@1.2.11", "", { "dependencies": { "bun-types": "1.2.11" } }, "sha512-ZLbbI91EmmGwlWTRWuV6J19IUiUC5YQ3TCEuSHI3usIP75kuoA8/0PVF+LTrbEnVc8JIhpElWOxv1ocI1fJBbw=="],
35
-
36
- "@types/node": ["@types/node@22.15.3", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw=="],
37
-
38
- "bun-types": ["bun-types@1.2.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-dbkp5Lo8HDrXkLrONm6bk+yiiYQSntvFUzQp0v3pzTAsXk6FtgVMjdQ+lzFNVAmQFUkPQZ3WMZqH5tTo+Dp/IA=="],
39
-
40
- "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
41
-
42
- "bun-types/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="],
43
-
44
- "bun-types/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="],
45
- }
46
- }
Binary file
@@ -1,152 +0,0 @@
1
- import { expect, test } from "bun:test";
2
- import { PrintableShellCommand } from "../src";
3
-
4
- const rsyncCommand = new PrintableShellCommand("rsync", [
5
- "-avz",
6
- ["--exclude", ".DS_Store"],
7
- ["--exclude", ".git"],
8
- "./dist/web/experiments.cubing.net/test/deploy/",
9
- "experiments.cubing.net:~/experiments.cubing.net/test/deploy/",
10
- ]);
11
-
12
- test("args for commands", () => {
13
- expect(rsyncCommand.toCommandWithFlatArgs()).toEqual([
14
- "rsync",
15
- [
16
- "-avz",
17
- "--exclude",
18
- ".DS_Store",
19
- "--exclude",
20
- ".git",
21
- "./dist/web/experiments.cubing.net/test/deploy/",
22
- "experiments.cubing.net:~/experiments.cubing.net/test/deploy/",
23
- ],
24
- ]);
25
- expect(rsyncCommand.toFlatCommand()).toEqual([
26
- "rsync",
27
- "-avz",
28
- "--exclude",
29
- ".DS_Store",
30
- "--exclude",
31
- ".git",
32
- "./dist/web/experiments.cubing.net/test/deploy/",
33
- "experiments.cubing.net:~/experiments.cubing.net/test/deploy/",
34
- ]);
35
- expect(rsyncCommand.toCommandWithFlatArgs()).toEqual(rsyncCommand.forNode());
36
- expect(rsyncCommand.toFlatCommand()).toEqual(rsyncCommand.forBun());
37
- });
38
-
39
- test("default formatting", () => {
40
- expect(rsyncCommand.getPrintableCommand()).toEqual(
41
- `rsync \\
42
- -avz \\
43
- --exclude .DS_Store \\
44
- --exclude .git \\
45
- ./dist/web/experiments.cubing.net/test/deploy/ \\
46
- experiments.cubing.net:~/experiments.cubing.net/test/deploy/`,
47
- );
48
- expect(
49
- rsyncCommand.getPrintableCommand({
50
- quoting: "auto",
51
- argumentLineWrapping: "by-entry",
52
- }),
53
- ).toEqual(rsyncCommand.getPrintableCommand());
54
- });
55
-
56
- test("extra-safe quoting", () => {
57
- expect(rsyncCommand.getPrintableCommand({ quoting: "extra-safe" })).toEqual(
58
- `'rsync' \\
59
- '-avz' \\
60
- '--exclude' '.DS_Store' \\
61
- '--exclude' '.git' \\
62
- './dist/web/experiments.cubing.net/test/deploy/' \\
63
- 'experiments.cubing.net:~/experiments.cubing.net/test/deploy/'`,
64
- );
65
- });
66
-
67
- test("indentation", () => {
68
- expect(
69
- rsyncCommand.getPrintableCommand({ argIndentation: "\t \t" }),
70
- ).toEqual(
71
- `rsync \\
72
- -avz \\
73
- --exclude .DS_Store \\
74
- --exclude .git \\
75
- ./dist/web/experiments.cubing.net/test/deploy/ \\
76
- experiments.cubing.net:~/experiments.cubing.net/test/deploy/`,
77
- );
78
- expect(rsyncCommand.getPrintableCommand({ argIndentation: "↪ " })).toEqual(
79
- `rsync \\
80
- ↪ -avz \\
81
- ↪ --exclude .DS_Store \\
82
- ↪ --exclude .git \\
83
- ↪ ./dist/web/experiments.cubing.net/test/deploy/ \\
84
- ↪ experiments.cubing.net:~/experiments.cubing.net/test/deploy/`,
85
- );
86
- expect(rsyncCommand.getPrintableCommand({ mainIndentation: " " })).toEqual(
87
- ` rsync \\
88
- -avz \\
89
- --exclude .DS_Store \\
90
- --exclude .git \\
91
- ./dist/web/experiments.cubing.net/test/deploy/ \\
92
- experiments.cubing.net:~/experiments.cubing.net/test/deploy/`,
93
- );
94
- expect(
95
- rsyncCommand.getPrintableCommand({
96
- mainIndentation: "🙈",
97
- argIndentation: "🙉",
98
- }),
99
- ).toEqual(
100
- `🙈rsync \\
101
- 🙈🙉-avz \\
102
- 🙈🙉--exclude .DS_Store \\
103
- 🙈🙉--exclude .git \\
104
- 🙈🙉./dist/web/experiments.cubing.net/test/deploy/ \\
105
- 🙈🙉experiments.cubing.net:~/experiments.cubing.net/test/deploy/`,
106
- );
107
- });
108
-
109
- test("line wrapping", () => {
110
- expect(
111
- rsyncCommand.getPrintableCommand({ argumentLineWrapping: "by-entry" }),
112
- ).toEqual(rsyncCommand.getPrintableCommand());
113
- expect(
114
- rsyncCommand.getPrintableCommand({
115
- argumentLineWrapping: "nested-by-entry",
116
- }),
117
- ).toEqual(`rsync \\
118
- -avz \\
119
- --exclude \\
120
- .DS_Store \\
121
- --exclude \\
122
- .git \\
123
- ./dist/web/experiments.cubing.net/test/deploy/ \\
124
- experiments.cubing.net:~/experiments.cubing.net/test/deploy/`);
125
- expect(
126
- rsyncCommand.getPrintableCommand({ argumentLineWrapping: "by-argument" }),
127
- ).toEqual(`rsync \\
128
- -avz \\
129
- --exclude \\
130
- .DS_Store \\
131
- --exclude \\
132
- .git \\
133
- ./dist/web/experiments.cubing.net/test/deploy/ \\
134
- experiments.cubing.net:~/experiments.cubing.net/test/deploy/`);
135
- expect(
136
- rsyncCommand.getPrintableCommand({
137
- argumentLineWrapping: "inline",
138
- }),
139
- ).toEqual(
140
- "rsync -avz --exclude .DS_Store --exclude .git ./dist/web/experiments.cubing.net/test/deploy/ experiments.cubing.net:~/experiments.cubing.net/test/deploy/",
141
- );
142
- });
143
-
144
- test("command with space is escaped by default", () => {
145
- const command = new PrintableShellCommand(
146
- "/Applications/My App.app/Contents/Resources/my-app",
147
- );
148
-
149
- expect(command.getPrintableCommand()).toEqual(
150
- `'/Applications/My App.app/Contents/Resources/my-app'`,
151
- );
152
- });
@@ -1,10 +0,0 @@
1
- import { PrintableShellCommand } from "../src";
2
-
3
- const command = new PrintableShellCommand("ffmpeg", [
4
- ["-i", "./test/My video.mp4"],
5
- ["-filter:v", "setpts=2.0*PTS"],
6
- ["-filter:a", "atempo=0.5"],
7
- "./test/My video (slow-mo).mov",
8
- ]);
9
-
10
- await command.shellOutBun();
@@ -1,10 +0,0 @@
1
- import { PrintableShellCommand } from "../src";
2
-
3
- const command = new PrintableShellCommand("ffmpeg", [
4
- ["-i", "./test/My video.mp4"],
5
- ["-filter:v", "setpts=2.0*PTS"],
6
- ["-filter:a", "atempo=0.5"],
7
- "./test/My video (slow-mo).mov",
8
- ]);
9
-
10
- command.print().shellOutNode();