@j-o-r/sh 1.0.6 → 1.0.8
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/lib/SHDispatch.js +6 -4
- package/lib/SHExecute.js +24 -4
- package/package.json +1 -1
- package/types/SHDispatch.d.ts +5 -1
- package/types/SHExecute.d.ts +2 -0
package/lib/SHDispatch.js
CHANGED
|
@@ -18,6 +18,7 @@ import SHExec from './SHExecute.js';
|
|
|
18
18
|
* @property {string} [prefix] - The prefix commands to ensure a safe execution environment. e.g: prefix: 'set -euo pipefail;/usr/bin/env',
|
|
19
19
|
* @property {StdioOptions|StdioOption} [stdio] - The stdio configuration.
|
|
20
20
|
* @property {number} [timeout] - default 20000: a timeout error is triggerd when a process execution time is exceeded, 0 is no timeout
|
|
21
|
+
* @property {boolean} [detached] - default false, when true it runnes as a background process
|
|
21
22
|
*/
|
|
22
23
|
/**
|
|
23
24
|
* @typedef {('pipe' | 'ignore' | 'inherit' | number)} StdioOption
|
|
@@ -86,6 +87,7 @@ const defaultOptions = {
|
|
|
86
87
|
cwd: process.cwd(),
|
|
87
88
|
env: process.env,
|
|
88
89
|
shell: 'bash',
|
|
90
|
+
detached: false,
|
|
89
91
|
prefix: '/usr/bin/env',
|
|
90
92
|
stdio: ['inherit', 'pipe', 'pipe'],
|
|
91
93
|
timeout: 10000 // when 0 there is no timeout
|
|
@@ -140,11 +142,11 @@ class SHDispatch {
|
|
|
140
142
|
// @ts-ignore
|
|
141
143
|
return new SHExec(this.#cmd, this.#options).runSync(payload);
|
|
142
144
|
}
|
|
143
|
-
async kill() {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
} catch (_e) { }
|
|
145
|
+
async kill(signal = 'SIGTERM') {
|
|
146
|
+
let res = [];
|
|
147
|
+
res = await this.#proc.kill(signal);
|
|
147
148
|
this.#proc = undefined;
|
|
149
|
+
return res;
|
|
148
150
|
}
|
|
149
151
|
}
|
|
150
152
|
|
package/lib/SHExecute.js
CHANGED
|
@@ -20,7 +20,7 @@ const killProcesses = (processPid, signal) => {
|
|
|
20
20
|
reject(new Error(stderr));
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
|
-
const pids = stdout.split(/\r?\n/).filter(pid => pid);
|
|
23
|
+
const pids = stdout.split(/\r?\n/).filter(pid => pid) || [];
|
|
24
24
|
// Kill each child process
|
|
25
25
|
try {
|
|
26
26
|
for (const pid of pids) {
|
|
@@ -48,6 +48,7 @@ class SHExecute {
|
|
|
48
48
|
/**
|
|
49
49
|
* @type {import('child_process').ChildProcess}
|
|
50
50
|
*/
|
|
51
|
+
#forcedKill = false;
|
|
51
52
|
#proc;
|
|
52
53
|
#command = '';
|
|
53
54
|
#options = {};
|
|
@@ -72,7 +73,7 @@ class SHExecute {
|
|
|
72
73
|
if (payload && typeof payload !== 'string') {
|
|
73
74
|
throw new Error('Argument is not a string');
|
|
74
75
|
}
|
|
75
|
-
let { cwd, shell, env, stdio } = this.#options;
|
|
76
|
+
let { cwd, shell, env, stdio, detached } = this.#options;
|
|
76
77
|
// pipe need to be set on stdin when posting a payload
|
|
77
78
|
if (payload) stdio[0] = 'pipe';
|
|
78
79
|
const input = payload || undefined;
|
|
@@ -80,6 +81,7 @@ class SHExecute {
|
|
|
80
81
|
cwd,
|
|
81
82
|
shell,
|
|
82
83
|
stdio,
|
|
84
|
+
detached,
|
|
83
85
|
windowsHide: true,
|
|
84
86
|
env,
|
|
85
87
|
input
|
|
@@ -127,6 +129,11 @@ class SHExecute {
|
|
|
127
129
|
}
|
|
128
130
|
this.#proc.on('close', (code) => {
|
|
129
131
|
if (timeout) clearTimeout(timeout);
|
|
132
|
+
if (this.#forcedKill) {
|
|
133
|
+
// Resolve without content
|
|
134
|
+
resolve();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
130
137
|
if (code === 0) {
|
|
131
138
|
resolve(this.#stdout.trim());
|
|
132
139
|
} else {
|
|
@@ -140,13 +147,26 @@ class SHExecute {
|
|
|
140
147
|
});
|
|
141
148
|
}
|
|
142
149
|
/**
|
|
150
|
+
* Kill this process and possible child processes
|
|
151
|
+
* @param {string} signal - kill signal
|
|
143
152
|
* @returns {Promise<number[]>}
|
|
144
153
|
*/
|
|
145
154
|
async kill(signal = 'SIGTERM') {
|
|
146
155
|
if (!this.#proc) throw new Error('Trying to kill a process without creating one.');
|
|
147
156
|
if (!this.#proc.pid) throw new Error('The process pid is undefined.');
|
|
148
|
-
|
|
149
|
-
|
|
157
|
+
this.#forcedKill = true;
|
|
158
|
+
let res = [];
|
|
159
|
+
try {
|
|
160
|
+
// Try to kill pid 'childs'
|
|
161
|
+
res = await killProcesses(this.#proc.pid, signal);
|
|
162
|
+
} catch (_e) { }
|
|
163
|
+
if (!res.includes(this.#proc.pid)) {
|
|
164
|
+
// Kill self if I am not allready killed
|
|
165
|
+
res.push(this.#proc.pid);
|
|
166
|
+
this.#proc.kill(signal);
|
|
167
|
+
}
|
|
168
|
+
this.#proc = undefined;
|
|
169
|
+
return res;
|
|
150
170
|
}
|
|
151
171
|
}
|
|
152
172
|
|
package/package.json
CHANGED
package/types/SHDispatch.d.ts
CHANGED
|
@@ -53,6 +53,10 @@ export type SHOptions = {
|
|
|
53
53
|
* - default 20000: a timeout error is triggerd when a process execution time is exceeded, 0 is no timeout
|
|
54
54
|
*/
|
|
55
55
|
timeout?: number | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* - default false, when true it runnes as a background process
|
|
58
|
+
*/
|
|
59
|
+
detached?: boolean | undefined;
|
|
56
60
|
};
|
|
57
61
|
export type StdioOption = ("pipe" | "ignore" | "inherit" | number);
|
|
58
62
|
export type StdioOptions = Array<StdioOption> | StdioOption;
|
|
@@ -77,6 +81,6 @@ declare class SHDispatch {
|
|
|
77
81
|
* @returns {SpawnSyncResponse}
|
|
78
82
|
*/
|
|
79
83
|
runSync(payload?: string | undefined): SpawnSyncResponse;
|
|
80
|
-
kill(): Promise<
|
|
84
|
+
kill(signal?: string): Promise<number[]>;
|
|
81
85
|
#private;
|
|
82
86
|
}
|
package/types/SHExecute.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ declare class SHExecute {
|
|
|
16
16
|
*/
|
|
17
17
|
run(payload?: string | undefined): Promise<any>;
|
|
18
18
|
/**
|
|
19
|
+
* Kill this process and possible child processes
|
|
20
|
+
* @param {string} signal - kill signal
|
|
19
21
|
* @returns {Promise<number[]>}
|
|
20
22
|
*/
|
|
21
23
|
kill(signal?: string): Promise<number[]>;
|