@j-o-r/sh 1.1.7 → 1.1.9

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/SH.js CHANGED
@@ -31,7 +31,7 @@ import SHDispatch from './SHDispatch.js';
31
31
  import Test from './Test.js'
32
32
 
33
33
  /**
34
- * @typedef {Object.<string, string | string[]>} ArgsObject
34
+ * @typedef {Object.<string, string>} ArgsObject
35
35
  * @property {string} [key: string] - Any string key maps to a string value
36
36
  * @property {string[]} _ - Array of strings, unnamed parameters
37
37
  * @description Parsed parameters result.
@@ -111,8 +111,6 @@ const SH = new Proxy(function(pieces, ...args) {
111
111
  /**
112
112
  * Create a async/sync context in new execution callstack
113
113
  * @param {function} callback - async/sync function
114
- * @param {ResolveCallback} [resolve] - optional resolve/result callback
115
- * @param {RejectCallback} [reject] - optional reject/error callback
116
114
  * @example
117
115
  * const p = within(async () => {
118
116
  * const res = await Promise.all([
@@ -124,24 +122,8 @@ const SH = new Proxy(function(pieces, ...args) {
124
122
  * return 'res';
125
123
  * });
126
124
  */
127
- const within = (callback, resolve, reject) => {
128
- // optional, custom resolve/reject functions from an outside promise/function
129
- const RCB = jsType(resolve) === 'Function';
130
- const ECB = jsType(reject) === 'Function';
131
- (async () => {
132
- try {
133
- const res = await Promise.resolve(callback());
134
- if (RCB) {
135
- resolve(res);
136
- }
137
- } catch (e) {
138
- if (ECB) {
139
- reject(e)
140
- } else {
141
- throw (e);
142
- }
143
- }
144
- })()
125
+ const within = async (callback) => {
126
+ return await callback();
145
127
  }
146
128
 
147
129
  /**
@@ -259,34 +241,6 @@ function* expBackoff(max = '60s', rand = '100ms') {
259
241
  /**
260
242
  * Parses command-line arguments into an object.
261
243
  *
262
- * The function recognizes arguments that start with two dashes (`--`) as keys,
263
- * and the subsequent value (if not another key) as the corresponding value.
264
- * If a key does not have a value, it defaults to `true`.
265
- * All unrecognized arguments are collected in an array under the `_` property.
266
- *
267
- * @param {string[]} args - An array of command-line arguments.
268
- * @returns {ArgsObject} An object where:
269
- * - Each key corresponds to an argument that starts with `--`,
270
- * - The value is either the next argument or `true` if no value is provided,
271
- * - The `_` property contains an array of unbound arguments.
272
- */
273
- const parseArgsOld = (args) => {
274
- const result = { _: [] }; // Initialize result with an empty array for unbound values
275
- for (let i = 0; i < args.length; i++) {
276
- if (args[i].startsWith('--')) {
277
- const key = args[i].substring(2);
278
- const value = args[i + 1] && !args[i + 1].startsWith('--') ? args[i + 1] : true;
279
- result[key] = value;
280
- if (value !== true) i++; // Skip the next element as it is a value
281
- } else {
282
- result._.push(args[i]); // Add unbound value to the array
283
- }
284
- }
285
- return result;
286
- }
287
- /**
288
- * Parses command-line arguments into an object.
289
- *
290
244
  * The function recognizes arguments that start with two dashes (`--`) or one dash (`-`) as keys,
291
245
  * and the subsequent value (if not another key) as the corresponding value.
292
246
  * If a key does not have a value, it defaults to `true`.
@@ -325,6 +279,7 @@ const parseArgs = (args) => {
325
279
  result._.push(args[i]);
326
280
  }
327
281
  }
282
+ // @ts-ignore
328
283
  return result;
329
284
  };
330
285
 
package/lib/SHDispatch.js CHANGED
@@ -8,15 +8,18 @@ import SHExec from './SHExecute.js';
8
8
  * @property {Buffer|null} stdout - The standard output of the child process.
9
9
  * @property {Buffer|null} stderr - The standard error of the child process.
10
10
  */
11
- /**
12
- * Default options for the execution environment.
13
- *
11
+ /**
14
12
  * @typedef {Object} SHOptions
15
- * @property {string} [cwd] - The current working directory.
16
- * @property {NodeJS.ProcessEnv} [env] - The environment variables.
17
- * @property {string} [shell] - The shell to use for execution.
18
- * @property {StdioOptions|StdioOption} [stdio] - The stdio configuration.
19
- * @property {number} [timeout] - default 20000: a timeout error is triggerd when a process execution time is exceeded, 0 is no timeout
13
+ * @property {string} [cwd] - Current working directory of the child process.
14
+ * @property {Object} [env] - Environment key-value pairs.
15
+ * @property {Array|string} [argv0] - Explicitly set the value of `argv[0]` sent to the child process.
16
+ * @property {boolean} [detached=false] - If true, the child will be a process group leader.
17
+ * @property {number} [uid] - Sets the user identity of the process.
18
+ * @property {number} [gid] - Sets the group identity of the process.
19
+ * @property {StdioOptions|StdioOption} [stdio='pipe'] - Child's stdio configuration.
20
+ * @property {boolean|string} [shell="bash"] - If true, runs command inside a shell.
21
+ * @property {number} [timeout=0] - In milliseconds, specifies when to terminate the child process.
22
+ * @property {string|Buffer|URL} [input] - The input to write to stdin.
20
23
  */
21
24
  /**
22
25
  * @typedef {('pipe' | 'ignore' | 'inherit' | number)} StdioOption
@@ -49,22 +52,24 @@ import SHExec from './SHExecute.js';
49
52
  * @returns {SHOptions}
50
53
  */
51
54
  const mergeOptions = (predefined, options) => {
52
- const keys = Object.keys(predefined);
53
- const mergedObj = keys.reduce((acc, key) => {
54
- acc[key] = options[key] !== undefined ? options[key] : predefined[key];
55
- return acc;
56
- }, {});
55
+ const mergedObj = { ...predefined };
56
+
57
+ for (const key in options) {
58
+ if (options[key] !== undefined) {
59
+ mergedObj[key] = options[key];
60
+ }
61
+ }
62
+
57
63
  return mergedObj;
58
64
  }
59
65
 
60
-
61
66
  /** @type {SHOptions} */
62
67
  const defaultOptions = {
63
68
  cwd: process.cwd(),
64
69
  env: process.env,
65
70
  shell: 'bash',
66
71
  stdio: ['inherit', 'pipe', 'pipe'],
67
- timeout: 10000 // when 0 there is no timeout
72
+ timeout: 0 // when 0 there is no timeout
68
73
  };
69
74
 
70
75
 
@@ -107,6 +112,7 @@ class SHDispatch {
107
112
  this.#options = mergeOptions(defaultOptions, options)
108
113
  return this;
109
114
  }
115
+
110
116
  /**
111
117
  * @param {string} [payload]
112
118
  * @returns {Promise<string>}
@@ -117,7 +123,7 @@ class SHDispatch {
117
123
  }
118
124
 
119
125
  /**
120
- * Works for screen takeovers like editors
126
+ * Works for terminal screen takeovers like editors
121
127
  * @param {string} [payload]
122
128
  * @returns {import('child_process').SpawnSyncReturns}
123
129
  */
package/lib/SHExecute.js CHANGED
@@ -93,13 +93,9 @@ class SHExecute {
93
93
  * @retuns {Promise<string>}
94
94
  */
95
95
  run(payload) {
96
- let to = 0;
97
96
  if (payload && typeof payload !== 'string') {
98
97
  throw new Error('Argument is not a string');
99
98
  }
100
- if (this.#options.timeout) {
101
- to = this.#options.timeout;
102
- }
103
99
  /** @type {import('node:child_process').SpawnOptions} */
104
100
  const options = this.#options;
105
101
  // pipe need to be set on stdin when posting a payload
@@ -117,21 +113,14 @@ class SHExecute {
117
113
  this.#proc.stdin.end(payload);
118
114
  }
119
115
  return new Promise((resolve, reject) => {
120
- let timeout;
121
- if (to > 0) {
122
- timeout = setTimeout(async () => {
123
- this.#proc.kill();
124
- reject(new Error(`Process timed out: ${this.#command}`));
125
- }, to); // options.timeout
126
- }
127
116
  this.#proc.on('close', (code) => {
128
- if (timeout) clearTimeout(timeout);
129
117
  if (this.#forcedKill) {
130
118
  // Resolve without content
131
119
  resolve();
132
120
  return;
133
121
  }
134
- if (code === 0) {
122
+ // Detached does not closes with an exitcode
123
+ if (code === 0 || code === null || typeof (code) === 'undefined') {
135
124
  resolve(this.#stdout.trim());
136
125
  } else {
137
126
  reject(new Error(`${code}: ${this.#command} "${this.#stderr.trim()}"`));
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@j-o-r/sh",
3
3
  "author": "Jorrit Duin <j-o-r@duin.work>",
4
4
  "type": "module",
5
- "version": "1.1.7",
5
+ "version": "1.1.9",
6
6
  "description": "Execute shell commands on Linux-based systems from javascript",
7
7
  "main": "lib/SH.js",
8
8
  "types": "types/SH.d.ts",
@@ -50,4 +50,4 @@
50
50
  "process-promise",
51
51
  "process-output"
52
52
  ]
53
- }
53
+ }
package/types/SH.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export type ArgsObject = {
2
- [x: string]: string | string[];
2
+ [x: string]: string;
3
3
  };
4
4
  export type RejectCallback = Function;
5
5
  export type ResolveCallback = Function;
@@ -54,8 +54,6 @@ export function readIn(): Promise<string>;
54
54
  /**
55
55
  * Create a async/sync context in new execution callstack
56
56
  * @param {function} callback - async/sync function
57
- * @param {ResolveCallback} [resolve] - optional resolve/result callback
58
- * @param {RejectCallback} [reject] - optional reject/error callback
59
57
  * @example
60
58
  * const p = within(async () => {
61
59
  * const res = await Promise.all([
@@ -67,7 +65,7 @@ export function readIn(): Promise<string>;
67
65
  * return 'res';
68
66
  * });
69
67
  */
70
- export function within(callback: Function, resolve?: ResolveCallback, reject?: RejectCallback): void;
68
+ export function within(callback: Function): Promise<any>;
71
69
  /**
72
70
  * Generates an exponential backoff time with a random jitter.
73
71
  *
@@ -94,7 +92,7 @@ export function expBackoff(max?: string, rand?: string): Generator<number, void,
94
92
  */
95
93
  export function parseArgs(args?: string[]): ArgsObject;
96
94
  /**
97
- * @typedef {Object.<string, string | string[]>} ArgsObject
95
+ * @typedef {Object.<string, string>} ArgsObject
98
96
  * @property {string} [key: string] - Any string key maps to a string value
99
97
  * @property {string[]} _ - Array of strings, unnamed parameters
100
98
  * @description Parsed parameters result.
@@ -25,30 +25,47 @@ export type SpawnSyncResponse = {
25
25
  */
26
26
  stderr: Buffer | null;
27
27
  };
28
- /**
29
- * Default options for the execution environment.
30
- */
31
28
  export type SHOptions = {
32
29
  /**
33
- * - The current working directory.
30
+ * - Current working directory of the child process.
34
31
  */
35
32
  cwd?: string | undefined;
36
33
  /**
37
- * - The environment variables.
34
+ * - Environment key-value pairs.
38
35
  */
39
- env?: NodeJS.ProcessEnv | undefined;
36
+ env?: Object | undefined;
40
37
  /**
41
- * - The shell to use for execution.
38
+ * - Explicitly set the value of `argv[0]` sent to the child process.
42
39
  */
43
- shell?: string | undefined;
40
+ argv0?: string | any[] | undefined;
44
41
  /**
45
- * - The stdio configuration.
42
+ * - If true, the child will be a process group leader.
43
+ */
44
+ detached?: boolean | undefined;
45
+ /**
46
+ * - Sets the user identity of the process.
47
+ */
48
+ uid?: number | undefined;
49
+ /**
50
+ * - Sets the group identity of the process.
51
+ */
52
+ gid?: number | undefined;
53
+ /**
54
+ * - Child's stdio configuration.
46
55
  */
47
56
  stdio?: number | "pipe" | "ignore" | "inherit" | StdioOption[] | undefined;
48
57
  /**
49
- * - default 20000: a timeout error is triggerd when a process execution time is exceeded, 0 is no timeout
58
+ * - If true, runs command inside a shell.
59
+ */
60
+ shell?: string | boolean | undefined;
61
+ /**
62
+ * - In milliseconds, specifies when to terminate the child process.
50
63
  */
51
64
  timeout?: number | undefined;
65
+ /**
66
+ * - The input to write to stdin.
67
+ */
68
+ input?: string | Buffer<ArrayBufferLike> | URL | undefined;
52
69
  };
53
70
  export type StdioOption = ("pipe" | "ignore" | "inherit" | number);
54
71
  export type StdioOptions = Array<StdioOption> | StdioOption;
@@ -69,7 +86,7 @@ declare class SHDispatch {
69
86
  */
70
87
  run(payload?: string): Promise<string>;
71
88
  /**
72
- * Works for screen takeovers like editors
89
+ * Works for terminal screen takeovers like editors
73
90
  * @param {string} [payload]
74
91
  * @returns {import('child_process').SpawnSyncReturns}
75
92
  */