dollar-shell 1.1.0 → 1.1.1
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 +67 -66
- package/package.json +6 -4
- package/src/index.d.ts +9 -2
- package/src/index.js +15 -4
- package/src/shell/unix.js +5 -1
- package/src/shell/windows.js +2 -1
- package/src/spawn/deno.js +5 -1
- package/src/utils.js +5 -2
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# dollar-shell [![NPM version][npm-image]][npm-url]
|
|
2
2
|
|
|
3
|
-
[npm-image]:
|
|
4
|
-
[npm-url]:
|
|
3
|
+
[npm-image]: https://img.shields.io/npm/v/dollar-shell.svg
|
|
4
|
+
[npm-url]: https://npmjs.org/package/dollar-shell
|
|
5
5
|
|
|
6
6
|
`dollar-shell` is a micro-library for running shell commands and using them in streams with ease in Node, Deno, Bun. It is a tiny, simple, no dependency package with TypeScript typings.
|
|
7
7
|
|
|
@@ -14,21 +14,21 @@ Node, Deno, or Bun.
|
|
|
14
14
|
|
|
15
15
|
Available components:
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
17
|
+
- `$` — spawn a process using a template string.
|
|
18
|
+
- `$.from` — spawn a process and use its `stdout` as a source stream.
|
|
19
|
+
- `$.to` — spawn a process and use its `stdin` as a sink stream.
|
|
20
|
+
- `$.io` AKA `$.through` — spawn a process and use it as
|
|
21
|
+
a transformation step in our pipeline.
|
|
22
|
+
- `$sh` — run a shell command using a template string.
|
|
23
|
+
- `$sh.from` — run a shell command and use its `stdout` as a source stream.
|
|
24
|
+
- `$sh.to` — run a shell command and use its `stdin` as a sink stream.
|
|
25
|
+
- `$sh.io` AKA `$sh.through` — run a shell command and use it as
|
|
26
|
+
a transformation step in our pipeline.
|
|
27
|
+
- Advanced components:
|
|
28
|
+
- `spawn()` — spawn a process with advanced ways to configure and control it.
|
|
29
|
+
- `$$` — spawn a process using a template string based on `spawn()`.
|
|
30
|
+
- `shell()` — a helper to spawn a shell command using a template string based on `spawn()`.
|
|
31
|
+
- Various helpers for them.
|
|
32
32
|
|
|
33
33
|
## Introduction
|
|
34
34
|
|
|
@@ -98,35 +98,35 @@ The signature: `spawn(command, options)`
|
|
|
98
98
|
|
|
99
99
|
Arguments:
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
101
|
+
- `command` — an array of strings. The first element is the command to run. The rest are its arguments.
|
|
102
|
+
- `options` — an optional object with options to configure the process:
|
|
103
|
+
- `cwd` — the optional current working directory as a string. Defaults to `process.cwd()`.
|
|
104
|
+
- `env` — the optional environment variables as an object (key-value pairs). Defaults to `process.env`.
|
|
105
|
+
- `stdin` — the optional source stream. Defaults to `null`.
|
|
106
|
+
- `stdout` — the optional destination stream. Defaults to `null`.
|
|
107
|
+
- `stderr` — the optional destination stream. Defaults to `null`.
|
|
108
108
|
|
|
109
109
|
`stdin`, `stdout` and `stderr` can be a string (one of `'inherit'`, `'ignore'`, `'pipe'` or `'piped'`)
|
|
110
110
|
or `null`. The latter is equivalent to `'ignore'`. `'piped'` is an alias of `'pipe'`:
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
it means that they will be piped to the same target, e.g., the console.
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
- `'inherit'` — inherit streams from the parent process. For output steams (`stdout` and `stderr`),
|
|
113
|
+
it means that they will be piped to the same target, e.g., the console.
|
|
114
|
+
- `'ignore'` — the stream is ignored.
|
|
115
|
+
- `'pipe'` — the stream is available for reading or writing.
|
|
116
116
|
|
|
117
117
|
Returns a sub-process object with the following properties:
|
|
118
118
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
119
|
+
- `command` — the command that was run as an array of strings.
|
|
120
|
+
- `options` — the options that were passed to `spawn()`.
|
|
121
|
+
- `exited` — a promise that resolves to the exit code of the process. It is used to wait for the process to exit.
|
|
122
|
+
- `finished` — a boolean. It is `true` when the process has finished and `false` otherwise.
|
|
123
|
+
- `killed` — a boolean. It is `true` when the process has been killed and `false` otherwise.
|
|
124
|
+
- `exitCode` — the exit code of the process as a number. It is `null` if the process hasn't exited yet.
|
|
125
|
+
- `signalCode` — the signal code of the process as a string. It is `null` if the process hasn't exited yet.
|
|
126
|
+
- `stdin` — the source stream of the process if `options.stdin` was `'pipe'`. It is `null` otherwise.
|
|
127
|
+
- `stdout` — the destination stream of the process if `options.stdout` was `'pipe'`. It is `null` otherwise.
|
|
128
|
+
- `stderr` — the destination stream of the process if `options.stderr` was `'pipe'`. It is `null` otherwise.
|
|
129
|
+
- `kill()` — kills the process. `killed` will be `true` as soon as the process has been killed. It can be used to pipe the input and output. See `spawn()`'s `stdin` and `stdout` above for more details.
|
|
130
130
|
|
|
131
131
|
**Important:** all streams are exposed as [web streams](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API).
|
|
132
132
|
|
|
@@ -135,7 +135,7 @@ Returns a sub-process object with the following properties:
|
|
|
135
135
|
```js
|
|
136
136
|
import {spawn} from 'dollar-shell';
|
|
137
137
|
|
|
138
|
-
const sp = spawn(['sleep', '5'])
|
|
138
|
+
const sp = spawn(['sleep', '5']);
|
|
139
139
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
140
140
|
sp.kill();
|
|
141
141
|
await sp.exited;
|
|
@@ -151,12 +151,12 @@ The same as `spawn()`, but it returns a tag function that can be used as a templ
|
|
|
151
151
|
The signatures:
|
|
152
152
|
|
|
153
153
|
```js
|
|
154
|
-
const sp1 = $$`ls -l ${myFile}`;
|
|
154
|
+
const sp1 = $$`ls -l ${myFile}`; // runs a command the defaults
|
|
155
155
|
|
|
156
156
|
const sp2 = $$(options)`ls -l .`; // runs a command with custom spawn options
|
|
157
157
|
|
|
158
|
-
const $tag = $$(options);
|
|
159
|
-
const sp3 = $tag`ls -l .`;
|
|
158
|
+
const $tag = $$(options); // returns a tag function
|
|
159
|
+
const sp3 = $tag`ls -l .`; // runs a command with custom spawn options
|
|
160
160
|
```
|
|
161
161
|
|
|
162
162
|
This function is effectively a helper for `spawn()`. It parses the template string
|
|
@@ -173,28 +173,28 @@ returns a tag function that can be used as a template string.
|
|
|
173
173
|
This function is similar to `$$` but it uses different default spawn options related to streams and
|
|
174
174
|
different (simpler) return values:
|
|
175
175
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
176
|
+
- `$` — all streams are ignored. It returns a promise that resolves to an object with the following properties:
|
|
177
|
+
- `code` — the exit code of the process. See `spawn()`'s `exitCode` above for more details.
|
|
178
|
+
- `signal` — the signal code of the process. See `spawn()`'s `signalCode` above for more details.
|
|
179
|
+
- `killed` — a boolean. It is `true` when the process has been killed and `false` otherwise. See `spawn()`'s `killed` above for more details.
|
|
180
|
+
- `$.from` — sets `stdout` to `pipe` and returns `stdout` of the process. It can be used to process the output. See `spawn()`'s `stdout` above for more details.
|
|
181
|
+
- `$.to` — sets `stdin` to `pipe` and returns `stdin` of the process. It can be used to pipe the input. See `spawn()`'s `stdin` above for more details.
|
|
182
|
+
- `$.io` AKA `$.through` — sets `stdin` and `stdout` to `pipe` and returns `stdin` and `stdout` of the process as a `{readable, writable}` pair. It can be used to create a pipeline where an external process can be used as a transform step.
|
|
183
183
|
|
|
184
184
|
### `$sh`
|
|
185
185
|
|
|
186
186
|
This function mirrors `$` but runs the command with the shell. It takes an options object that extends
|
|
187
187
|
the spawn options with the following properties:
|
|
188
188
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
the `SHELL` environment variable if specified. Otherwise it is `'/bin/sh'` or `'/system/bin/sh'` on Android.
|
|
192
|
-
|
|
193
|
-
Otherwise it is `cmd.exe`.
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
or `['-e']` for `pwsh.exe` or `powershell.exe`.
|
|
189
|
+
- `shellPath` — the path to the shell.
|
|
190
|
+
- On Unix-like systems it defaults to the value of
|
|
191
|
+
the `SHELL` environment variable if specified. Otherwise it is `'/bin/sh'` or `'/system/bin/sh'` on Android.
|
|
192
|
+
- On Windows it defaults to the value of the `ComSpec` environment variable if specified.
|
|
193
|
+
Otherwise it is `cmd.exe`.
|
|
194
|
+
- `shellArgs` — an array of strings that are passed to the shell as arguments.
|
|
195
|
+
- On Unix-like systems it defaults to `['-c']`.
|
|
196
|
+
- On Windows it defaults to `['/d', '/s', '/c']` for `cmd.exe`
|
|
197
|
+
or `['-e']` for `pwsh.exe` or `powershell.exe`.
|
|
198
198
|
|
|
199
199
|
The rest is identical to `$`: `$sh`, `$sh.from`, `$sh.to` and `$sh.io`/`$sh.through`.
|
|
200
200
|
|
|
@@ -204,10 +204,11 @@ BSD-3-Clause
|
|
|
204
204
|
|
|
205
205
|
## Release History
|
|
206
206
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
207
|
+
- 1.1.1 _Updated dev dependencies._
|
|
208
|
+
- 1.1.0 _Added `asDuplex` to the sub-process object._
|
|
209
|
+
- 1.0.5 _Updated dev dependencies._
|
|
210
|
+
- 1.0.4 _Fixed `raw()` for spawn commands._
|
|
211
|
+
- 1.0.3 _Added TSDoc comments, improved docs, fixed typos, added the missing copying of properties._
|
|
212
|
+
- 1.0.2 _Technical release: fixed references in the package file._
|
|
213
|
+
- 1.0.1 _Technical release: more tests, better documentation._
|
|
214
|
+
- 1.0.0 _The initial release._
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dollar-shell",
|
|
3
3
|
"description": "Run shell commands and use them in streams with ease in Node, Deno, Bun. Tiny, simple, no dependency package.",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
7
7
|
"types": "./src/index.d.ts",
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
"test:bun": "tape6-bun --flags FO",
|
|
18
18
|
"test:deno": "deno run -A `tape6-runner main` --flags FO",
|
|
19
19
|
"test:deno-original": "tape6-deno --flags FO",
|
|
20
|
-
"ts-check": "tsc --noEmit"
|
|
20
|
+
"ts-check": "tsc --noEmit",
|
|
21
|
+
"lint": "prettier --check .",
|
|
22
|
+
"lint:fix": "prettier --write ."
|
|
21
23
|
},
|
|
22
24
|
"files": [
|
|
23
25
|
"/src",
|
|
@@ -46,8 +48,8 @@
|
|
|
46
48
|
},
|
|
47
49
|
"license": "BSD-3-Clause",
|
|
48
50
|
"devDependencies": {
|
|
49
|
-
"tape-six": "^
|
|
50
|
-
"typescript": "^5.
|
|
51
|
+
"tape-six": "^1.4.1",
|
|
52
|
+
"typescript": "^5.9.3"
|
|
51
53
|
},
|
|
52
54
|
"tape6": {
|
|
53
55
|
"tests": [
|
package/src/index.d.ts
CHANGED
|
@@ -148,7 +148,10 @@ export interface ShellEscapeOptions {
|
|
|
148
148
|
/**
|
|
149
149
|
* Escapes a value using the specified options.
|
|
150
150
|
*/
|
|
151
|
-
export declare function shellEscape(
|
|
151
|
+
export declare function shellEscape(
|
|
152
|
+
value: {toString(): string},
|
|
153
|
+
options?: ShellEscapeOptions
|
|
154
|
+
): string;
|
|
152
155
|
|
|
153
156
|
/**
|
|
154
157
|
* The path of the current shell.
|
|
@@ -158,7 +161,11 @@ export declare function currentShellPath(): string;
|
|
|
158
161
|
/**
|
|
159
162
|
* Builds a shell command from a command using the `shell` and its `args`.
|
|
160
163
|
*/
|
|
161
|
-
export declare function buildShellCommand(
|
|
164
|
+
export declare function buildShellCommand(
|
|
165
|
+
shell: string | undefined,
|
|
166
|
+
args: string[] | undefined,
|
|
167
|
+
command: string
|
|
168
|
+
): string[];
|
|
162
169
|
|
|
163
170
|
/**
|
|
164
171
|
* Backticks (tag) function.
|
package/src/index.js
CHANGED
|
@@ -59,7 +59,9 @@ $.through = $.io = throughProcess;
|
|
|
59
59
|
|
|
60
60
|
// define shell functions
|
|
61
61
|
|
|
62
|
-
export const shell = bqShell(shellEscape, (command, options) =>
|
|
62
|
+
export const shell = bqShell(shellEscape, (command, options) =>
|
|
63
|
+
spawn(buildShellCommand(options?.shellPath, options?.shellArgs, command), options)
|
|
64
|
+
);
|
|
63
65
|
export {shell as sh};
|
|
64
66
|
|
|
65
67
|
export const $sh = bqShell(shellEscape, (command, options) => {
|
|
@@ -68,17 +70,26 @@ export const $sh = bqShell(shellEscape, (command, options) => {
|
|
|
68
70
|
});
|
|
69
71
|
|
|
70
72
|
const fromShell = bqShell(shellEscape, (command, options) => {
|
|
71
|
-
const sp = spawn(
|
|
73
|
+
const sp = spawn(
|
|
74
|
+
buildShellCommand(options?.shellPath, options?.shellArgs, command),
|
|
75
|
+
Object.assign({}, options, {stdout: 'pipe'})
|
|
76
|
+
);
|
|
72
77
|
return sp.stdout;
|
|
73
78
|
});
|
|
74
79
|
|
|
75
80
|
const toShell = bqShell(shellEscape, (command, options) => {
|
|
76
|
-
const sp = spawn(
|
|
81
|
+
const sp = spawn(
|
|
82
|
+
buildShellCommand(options?.shellPath, options?.shellArgs, command),
|
|
83
|
+
Object.assign({}, options, {stdin: 'pipe'})
|
|
84
|
+
);
|
|
77
85
|
return sp.stdin;
|
|
78
86
|
});
|
|
79
87
|
|
|
80
88
|
const throughShell = bqShell(shellEscape, (command, options) => {
|
|
81
|
-
const sp = spawn(
|
|
89
|
+
const sp = spawn(
|
|
90
|
+
buildShellCommand(options?.shellPath, options?.shellArgs, command),
|
|
91
|
+
Object.assign({}, options, {stdin: 'pipe', stdout: 'pipe'})
|
|
92
|
+
);
|
|
82
93
|
return sp.asDuplex;
|
|
83
94
|
});
|
|
84
95
|
|
package/src/shell/unix.js
CHANGED
|
@@ -7,4 +7,8 @@ export const shellEscape = s => "'" + String(s).replace(/'/g, "'\\''") + "'";
|
|
|
7
7
|
export const currentShellPath = () => getEnv('SHELL') || (isAndroid ? '/system/bin/sh' : '/bin/sh');
|
|
8
8
|
|
|
9
9
|
// derived from https://github.com/nodejs/node/blob/43f699d4d2799cfc17cbcad5770e1889075d5dbe/lib/child_process.js#L620
|
|
10
|
-
export const buildShellCommand = (shell, args, command) => [
|
|
10
|
+
export const buildShellCommand = (shell, args, command) => [
|
|
11
|
+
shell || currentShellPath(),
|
|
12
|
+
...(args || ['-c']),
|
|
13
|
+
command
|
|
14
|
+
];
|
package/src/shell/windows.js
CHANGED
|
@@ -58,7 +58,8 @@ export const shellEscape = (s, options, isFirst) => {
|
|
|
58
58
|
'"';
|
|
59
59
|
return isFirst ? result.replace(/(0xFF)|([\W])|(\w+)/g, escapeCmd) : result;
|
|
60
60
|
}
|
|
61
|
-
if (isPwsh(shell))
|
|
61
|
+
if (isPwsh(shell))
|
|
62
|
+
return s.replace(/([\t\r\n\f\x00\x1B\x07\x08\x0B\"])|([\W])|(\w+)/g, escapePowerShell);
|
|
62
63
|
return s;
|
|
63
64
|
};
|
|
64
65
|
|
package/src/spawn/deno.js
CHANGED
|
@@ -26,7 +26,11 @@ class Subprocess {
|
|
|
26
26
|
|
|
27
27
|
this.controller = new AbortController();
|
|
28
28
|
|
|
29
|
-
const spawnOptions = {
|
|
29
|
+
const spawnOptions = {
|
|
30
|
+
signal: this.controller.signal,
|
|
31
|
+
args: command.slice(1),
|
|
32
|
+
windowsRawArguments: true
|
|
33
|
+
};
|
|
30
34
|
options.cwd && (spawnOptions.cwd = options.cwd);
|
|
31
35
|
options.env && (spawnOptions.env = options.env);
|
|
32
36
|
|
package/src/utils.js
CHANGED
|
@@ -16,7 +16,8 @@ if (typeof Deno !== 'undefined') {
|
|
|
16
16
|
}
|
|
17
17
|
export {getEnv, isWindows, isAndroid};
|
|
18
18
|
|
|
19
|
-
export const verifyStrings = strings =>
|
|
19
|
+
export const verifyStrings = strings =>
|
|
20
|
+
Array.isArray(strings) && strings.every(s => typeof s === 'string');
|
|
20
21
|
|
|
21
22
|
export const toBase64 = s => {
|
|
22
23
|
// const buf = new TextEncoder().encode(s),
|
|
@@ -34,4 +35,6 @@ export const raw = value => ({[rawValueSymbol]: value});
|
|
|
34
35
|
export const isRawValue = value => value && typeof value === 'object' && rawValueSymbol in value;
|
|
35
36
|
export const getRawValue = value => value[rawValueSymbol];
|
|
36
37
|
|
|
37
|
-
export const winCmdEscape = isWindows
|
|
38
|
+
export const winCmdEscape = isWindows
|
|
39
|
+
? value => raw(String(value).replace(/./g, '^$&'))
|
|
40
|
+
: value => String(value);
|