@j-o-r/sh 1.0.4 → 1.0.6

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
@@ -59,7 +59,7 @@ The `SH` method accepts a template literal string enclosed in backticks as its a
59
59
  ### Additional Utilities
60
60
 
61
61
  The module also provides additional utilities for common tasks:
62
- - `args(command)`: Parsing a command from a string into an arguments array
62
+ - `parseArgs(process.args)`: Transform an array of strings into an object
63
63
  - `cd(dir)`: Change the working directory.
64
64
  - `sleep(duration)`: Pause execution for a specified duration.
65
65
  - `retry(count, interval, callback)`: Retry a command a specified number of times with an optional interval.
@@ -94,7 +94,7 @@ This class is returned by the `SH` function. Here's a summary of its methods and
94
94
 
95
95
  - Create a command from a string
96
96
  ```javascript
97
- const command = args("uname -r");
97
+ const command = "uname -r";
98
98
  const content = await SH`${command}`.run();
99
99
  console.log(content);
100
100
  ```
package/lib/SH.js CHANGED
@@ -29,7 +29,6 @@
29
29
  import assert from 'node:assert';
30
30
  import SHDispatch from './SHDispatch.js';
31
31
 
32
-
33
32
  /**
34
33
  * Creates a new SHDispatch object that represents a command to be executed.
35
34
  *
@@ -45,37 +44,6 @@ import SHDispatch from './SHDispatch.js';
45
44
  * const command = await SH`echo 'Hello, world!'`.run();
46
45
  */
47
46
 
48
- /**
49
- * escape paramater commands
50
- * @param {string} arg
51
- * @returns {string}
52
- */
53
- const quote = (arg) => {
54
- if (/^[a-z0-9/_.\-@:=]+$/i.test(arg) || arg === '') {
55
- return arg;
56
- }
57
- return (`'` +
58
- arg
59
- .replace(/\\/g, '\\\\')
60
- .replace(/'/g, "\\'")
61
- .replace(/\f/g, '\\f')
62
- .replace(/\n/g, '\\n')
63
- .replace(/\r/g, '\\r')
64
- .replace(/\t/g, '\\t')
65
- .replace(/\v/g, '\\v')
66
- .replace(/\0/g, '\\0') +
67
- `'`);
68
- }
69
- /**
70
- * Escape CLI arguments
71
- * @param {string[]} arg
72
- * @retruns {string}
73
- */
74
- const sanitizeArg = (arg) => {
75
- const s = `${arg}`;
76
- return quote(s);
77
- }
78
-
79
47
  /**
80
48
  * 4ms, 5s || 5
81
49
  * @param {number|string} d
@@ -104,57 +72,15 @@ const SH = new Proxy(function(pieces, ...args) {
104
72
  while (i < args.length) {
105
73
  let s;
106
74
  if (Array.isArray(args[i])) {
107
- s = args[i].map((x) => sanitizeArg(x)).join(' ');
75
+ s = args[i].map((x) => x).join(' ');
108
76
  }
109
77
  else {
110
- s = sanitizeArg(args[i]);
78
+ s = args[i];
111
79
  }
112
80
  cmd += s + pieces[++i];
113
81
  }
114
82
  return new SHDispatch(cmd);
115
83
  }, {});
116
- /**
117
- * Splits a command string into an array of arguments, handling quoted strings.
118
- * This fixes a problem when a command is like this: SH`${command}`
119
- *
120
- * @param {string} command - The command string to split.
121
- * @returns {string[]} - The array of command arguments.
122
- */
123
- const args = (command) => {
124
- const args = [];
125
- let currentArg = '';
126
- let insideQuotes = false;
127
- let quoteChar = null;
128
-
129
- for (let i = 0; i < command.length; i++) {
130
- const char = command[i];
131
-
132
- if (char === '"' || char === "'") {
133
- if (insideQuotes && quoteChar === char && command[i - 1] !== '\\') {
134
- insideQuotes = false;
135
- quoteChar = null;
136
- } else if (!insideQuotes) {
137
- insideQuotes = true;
138
- quoteChar = char;
139
- } else {
140
- currentArg += char;
141
- }
142
- } else if (char === ' ' && !insideQuotes) {
143
- if (currentArg.length > 0) {
144
- args.push(currentArg);
145
- currentArg = '';
146
- }
147
- } else {
148
- currentArg += char;
149
- }
150
- }
151
-
152
- if (currentArg.length > 0) {
153
- args.push(currentArg);
154
- }
155
-
156
- return args.map(arg => arg.replace(/\\(['"])/g, '$1'));
157
- }
158
84
  /**
159
85
  * Create a async context in an sync block
160
86
  * @param {function} callback - async function
@@ -284,13 +210,41 @@ function* expBackoff(max = '60s', rand = '100ms') {
284
210
  yield Math.min(2 ** n++, maxMs) + ms;
285
211
  }
286
212
  }
213
+ /**
214
+ * Parses command-line arguments into an object.
215
+ *
216
+ * The function recognizes arguments that start with two dashes (`--`) as keys,
217
+ * and the subsequent value (if not another key) as the corresponding value.
218
+ * If a key does not have a value, it defaults to `true`.
219
+ * All unrecognized arguments are collected in an array under the `_` property.
220
+ *
221
+ * @param {string[]} args - An array of command-line arguments.
222
+ * @returns {object} An object where:
223
+ * - Each key corresponds to an argument that starts with `--`,
224
+ * - The value is either the next argument or `true` if no value is provided,
225
+ * - The `_` property contains an array of unbound arguments.
226
+ */
227
+ const parseArgs = (args) => {
228
+ const result = { _: [] }; // Initialize result with an empty array for unbound values
229
+ for (let i = 0; i < args.length; i++) {
230
+ if (args[i].startsWith('--')) {
231
+ const key = args[i].substring(2);
232
+ const value = args[i + 1] && !args[i + 1].startsWith('--') ? args[i + 1] : true;
233
+ result[key] = value;
234
+ if (value !== true) i++; // Skip the next element as it is a value
235
+ } else {
236
+ result._.push(args[i]); // Add unbound value to the array
237
+ }
238
+ }
239
+ return result;
240
+ }
287
241
  export {
288
242
  SH,
289
- args,
290
243
  cd,
291
244
  sleep,
292
245
  retry,
293
246
  readIn,
294
247
  within,
295
248
  expBackoff,
249
+ parseArgs
296
250
  }
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.0.4",
5
+ "version": "1.0.6",
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",
package/types/SH.d.ts CHANGED
@@ -6,14 +6,6 @@ export type Shell = Function;
6
6
  export const SH: Shell & {
7
7
  (pieces: TemplateStringsArray, ...args: any): SHDispatch;
8
8
  };
9
- /**
10
- * Splits a command string into an array of arguments, handling quoted strings.
11
- * This fixes a problem when a command is like this: SH`${command}`
12
- *
13
- * @param {string} command - The command string to split.
14
- * @returns {string[]} - The array of command arguments.
15
- */
16
- export function args(command: string): string[];
17
9
  /**
18
10
  * Change working directory
19
11
  * @param {string} dir
@@ -76,4 +68,19 @@ export function within(callback: Function): void;
76
68
  * @yields {number} The backoff time in milliseconds.
77
69
  */
78
70
  export function expBackoff(max?: string | undefined, rand?: string | undefined): Generator<number, void, unknown>;
71
+ /**
72
+ * Parses command-line arguments into an object.
73
+ *
74
+ * The function recognizes arguments that start with two dashes (`--`) as keys,
75
+ * and the subsequent value (if not another key) as the corresponding value.
76
+ * If a key does not have a value, it defaults to `true`.
77
+ * All unrecognized arguments are collected in an array under the `_` property.
78
+ *
79
+ * @param {string[]} args - An array of command-line arguments.
80
+ * @returns {object} An object where:
81
+ * - Each key corresponds to an argument that starts with `--`,
82
+ * - The value is either the next argument or `true` if no value is provided,
83
+ * - The `_` property contains an array of unbound arguments.
84
+ */
85
+ export function parseArgs(args: string[]): object;
79
86
  import SHDispatch from './SHDispatch.js';