printable-shell-command 0.1.1 → 0.1.3
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/Makefile +10 -3
- package/README.md +6 -5
- package/bun.lock +42 -0
- package/package.json +2 -2
- package/src/index.ts +52 -4
- package/bun.lockb +0 -0
package/Makefile
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
.PHONY: lint
|
|
2
|
-
lint:
|
|
2
|
+
lint: setup
|
|
3
3
|
bun x @biomejs/biome check
|
|
4
4
|
|
|
5
5
|
.PHONY: format
|
|
6
|
-
format:
|
|
6
|
+
format: setup
|
|
7
7
|
bun x @biomejs/biome check --write
|
|
8
8
|
|
|
9
9
|
# https://github.com/lgarron/repo
|
|
10
|
-
REPO_COMMANDS =
|
|
10
|
+
REPO_COMMANDS = publish
|
|
11
11
|
|
|
12
|
+
publish: setup
|
|
13
|
+
|
|
14
|
+
.PHONY: ${REPO_COMMANDS}
|
|
12
15
|
${REPO_COMMANDS}:
|
|
13
16
|
repo $@
|
|
17
|
+
|
|
18
|
+
.PHONY: setup
|
|
19
|
+
setup:
|
|
20
|
+
bun install --frozen-lockfile
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A helper class to construct shell commands in a way that allows printing them.
|
|
4
4
|
|
|
5
|
-
The goal is to make it easy to print commands that are
|
|
5
|
+
The goal is to make it easy to print commands that are being run by a program, in a way that makes it easy and safe for a user to copy-and-paste.
|
|
6
6
|
|
|
7
7
|
## Goals
|
|
8
8
|
|
|
@@ -43,19 +43,20 @@ ffmpeg \
|
|
|
43
43
|
### Spawn a process in `node`
|
|
44
44
|
|
|
45
45
|
```typescript
|
|
46
|
-
import {
|
|
46
|
+
import { PrintableShellCommand } from "printable-shell-command";
|
|
47
47
|
import { spawn } from "node:child_process";
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
const child_process = spawn(...command.toCommandWithFlatArgs());
|
|
49
|
+
const command = new PrintableShellCommand(/* … */);
|
|
50
|
+
const child_process = spawn(...command.toCommandWithFlatArgs()); // Note the `...`
|
|
51
51
|
```
|
|
52
52
|
|
|
53
53
|
### Spawn a process in `bun`
|
|
54
54
|
|
|
55
55
|
```typescript
|
|
56
|
-
import {
|
|
56
|
+
import { PrintableShellCommand } from "printable-shell-command";
|
|
57
57
|
import { spawn } from "bun";
|
|
58
58
|
|
|
59
|
+
const command = new PrintableShellCommand(/* … */);
|
|
59
60
|
await spawn(command.toFlatCommand()).exited;
|
|
60
61
|
```
|
|
61
62
|
|
package/bun.lock
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"workspaces": {
|
|
4
|
+
"": {
|
|
5
|
+
"name": "printable-shell-command",
|
|
6
|
+
"devDependencies": {
|
|
7
|
+
"@biomejs/biome": "^1.9.4",
|
|
8
|
+
"@types/bun": "^1.1.14",
|
|
9
|
+
"@types/node": "^22.10.2",
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
"packages": {
|
|
14
|
+
"@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=="],
|
|
15
|
+
|
|
16
|
+
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@1.9.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw=="],
|
|
17
|
+
|
|
18
|
+
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@1.9.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg=="],
|
|
19
|
+
|
|
20
|
+
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@1.9.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g=="],
|
|
21
|
+
|
|
22
|
+
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@1.9.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA=="],
|
|
23
|
+
|
|
24
|
+
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@1.9.4", "", { "os": "linux", "cpu": "x64" }, "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg=="],
|
|
25
|
+
|
|
26
|
+
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@1.9.4", "", { "os": "linux", "cpu": "x64" }, "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg=="],
|
|
27
|
+
|
|
28
|
+
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@1.9.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg=="],
|
|
29
|
+
|
|
30
|
+
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@1.9.4", "", { "os": "win32", "cpu": "x64" }, "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA=="],
|
|
31
|
+
|
|
32
|
+
"@types/bun": ["@types/bun@1.2.4", "", { "dependencies": { "bun-types": "1.2.4" } }, "sha512-QtuV5OMR8/rdKJs213iwXDpfVvnskPXY/S0ZiFbsTjQZycuqPbMW8Gf/XhLfwE5njW8sxI2WjISURXPlHypMFA=="],
|
|
33
|
+
|
|
34
|
+
"@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="],
|
|
35
|
+
|
|
36
|
+
"@types/ws": ["@types/ws@8.5.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw=="],
|
|
37
|
+
|
|
38
|
+
"bun-types": ["bun-types@1.2.4", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-nDPymR207ZZEoWD4AavvEaa/KZe/qlrbMSchqpQwovPZCKc7pwMoENjEtHgMKaAjJhy+x6vfqSBA1QU3bJgs0Q=="],
|
|
39
|
+
|
|
40
|
+
"undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="],
|
|
41
|
+
}
|
|
42
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "printable-shell-command",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"main": "./src/index.ts",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"import": "./src/index.ts"
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
|
-
"
|
|
12
|
+
"devDependencies": {
|
|
13
13
|
"@biomejs/biome": "^1.9.4",
|
|
14
14
|
"@types/bun": "^1.1.14",
|
|
15
15
|
"@types/node": "^22.10.2"
|
package/src/index.ts
CHANGED
|
@@ -49,17 +49,20 @@ const SPECIAL_SHELL_CHARACTERS = new Set([
|
|
|
49
49
|
|
|
50
50
|
// https://mywiki.wooledge.org/BashGuide/SpecialCharacters
|
|
51
51
|
const SPECIAL_SHELL_CHARACTERS_FOR_MAIN_COMMAND =
|
|
52
|
-
|
|
52
|
+
// biome-ignore lint/suspicious/noExplicitAny: Workaround to make this package easier to use in a project that otherwise only uses ES2022.)
|
|
53
|
+
(SPECIAL_SHELL_CHARACTERS as unknown as any).union(new Set(["="]));
|
|
53
54
|
|
|
54
55
|
export class PrintableShellCommand {
|
|
56
|
+
#commandName: string;
|
|
55
57
|
constructor(
|
|
56
|
-
|
|
58
|
+
commandName: string,
|
|
57
59
|
private args: Args = [],
|
|
58
60
|
) {
|
|
59
61
|
if (!isString(commandName)) {
|
|
60
62
|
// biome-ignore lint/suspicious/noExplicitAny: We want to print this, no matter what it is.
|
|
61
63
|
throw new Error("Command name is not a string:", commandName as any);
|
|
62
64
|
}
|
|
65
|
+
this.#commandName = commandName;
|
|
63
66
|
if (typeof args === "undefined") {
|
|
64
67
|
return;
|
|
65
68
|
}
|
|
@@ -83,19 +86,62 @@ export class PrintableShellCommand {
|
|
|
83
86
|
}
|
|
84
87
|
}
|
|
85
88
|
|
|
89
|
+
get commandName(): string {
|
|
90
|
+
return this.#commandName;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// For use with `bun`.
|
|
94
|
+
//
|
|
95
|
+
// Usage example:
|
|
96
|
+
//
|
|
97
|
+
// import { PrintableShellCommand } from "printable-shell-command";
|
|
98
|
+
// import { spawn } from "bun";
|
|
99
|
+
//
|
|
100
|
+
// const command = new PrintableShellCommand(/* … */);
|
|
101
|
+
// await spawn(command.toFlatCommand()).exited;
|
|
102
|
+
//
|
|
86
103
|
public toFlatCommand(): string[] {
|
|
87
104
|
return [this.commandName, ...this.args.flat()];
|
|
88
105
|
}
|
|
89
106
|
|
|
90
107
|
// Convenient alias for `toFlatCommand()`.
|
|
108
|
+
//
|
|
109
|
+
// Usage example:
|
|
110
|
+
//
|
|
111
|
+
// import { PrintableShellCommand } from "printable-shell-command";
|
|
112
|
+
// import { spawn } from "bun";
|
|
113
|
+
//
|
|
114
|
+
// const command = new PrintableShellCommand(/* … */);
|
|
115
|
+
// await spawn(command.forBun()).exited;
|
|
116
|
+
//
|
|
91
117
|
public forBun(): string[] {
|
|
92
118
|
return this.toFlatCommand();
|
|
93
119
|
}
|
|
120
|
+
|
|
94
121
|
// For use with `node:child_process`
|
|
122
|
+
//
|
|
123
|
+
// Usage example:
|
|
124
|
+
//
|
|
125
|
+
// import { PrintableShellCommand } from "printable-shell-command";
|
|
126
|
+
// import { spawn } from "node:child_process";
|
|
127
|
+
//
|
|
128
|
+
// const command = new PrintableShellCommand(/* … */);
|
|
129
|
+
// const child_process = spawn(...command.toCommandWithFlatArgs()); // Note the `...`
|
|
130
|
+
//
|
|
95
131
|
public toCommandWithFlatArgs(): [string, string[]] {
|
|
96
132
|
return [this.commandName, this.args.flat()];
|
|
97
133
|
}
|
|
98
134
|
|
|
135
|
+
// For use with `node:child_process`
|
|
136
|
+
//
|
|
137
|
+
// Usage example:
|
|
138
|
+
//
|
|
139
|
+
// import { PrintableShellCommand } from "printable-shell-command";
|
|
140
|
+
// import { spawn } from "node:child_process";
|
|
141
|
+
//
|
|
142
|
+
// const command = new PrintableShellCommand(/* … */);
|
|
143
|
+
// const child_process = spawn(...command.forNode()); // Note the `...`
|
|
144
|
+
//
|
|
99
145
|
// Convenient alias for `toCommandWithFlatArgs()`.
|
|
100
146
|
public forNode(): [string, string[]] {
|
|
101
147
|
return this.toCommandWithFlatArgs();
|
|
@@ -104,7 +150,7 @@ export class PrintableShellCommand {
|
|
|
104
150
|
#escapeArg(
|
|
105
151
|
arg: string,
|
|
106
152
|
isMainCommand: boolean,
|
|
107
|
-
options
|
|
153
|
+
options?: PrintOptions,
|
|
108
154
|
): string {
|
|
109
155
|
const argCharacters = new Set(arg);
|
|
110
156
|
const specialShellCharacters = isMainCommand
|
|
@@ -112,7 +158,9 @@ export class PrintableShellCommand {
|
|
|
112
158
|
: SPECIAL_SHELL_CHARACTERS;
|
|
113
159
|
if (
|
|
114
160
|
options?.quoting === "extra-safe" ||
|
|
115
|
-
|
|
161
|
+
// biome-ignore lint/suspicious/noExplicitAny: Workaround to make this package easier to use in a project that otherwise only uses ES2022.)
|
|
162
|
+
(argCharacters as unknown as any).intersection(specialShellCharacters)
|
|
163
|
+
.size > 0
|
|
116
164
|
) {
|
|
117
165
|
// Use single quote to reduce the need to escape (and therefore reduce the chance for bugs/security issues).
|
|
118
166
|
const escaped = arg.replaceAll("\\", "\\\\").replaceAll("'", "\\'");
|
package/bun.lockb
DELETED
|
Binary file
|