@j-o-r/sh 1.1.19 → 1.1.21

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.
Files changed (3) hide show
  1. package/lib/SH.js +42 -9
  2. package/package.json +1 -1
  3. package/types/SH.d.ts +17 -3
package/lib/SH.js CHANGED
@@ -72,6 +72,20 @@ const jsType = (fn) => {
72
72
  const type = Object.prototype.toString.call(fn).slice(8, -1);
73
73
  return type === 'Object' ? fn.constructor.name : type;
74
74
  };
75
+
76
+ /**
77
+ * 'Code Safe' has own prop
78
+ *
79
+ * @param {any} o - object to examine
80
+ * @param {string} p - property to look for
81
+ * @returns {boolean}
82
+ */
83
+ const hasProp = (o, p) => {
84
+ if (typeof o === 'undefined') {
85
+ return false;
86
+ }
87
+ return Object.prototype.hasOwnProperty.call(o, p);
88
+ };
75
89
  /**
76
90
  * 4ms, 5s || 5
77
91
  * @param {number|string} d
@@ -107,6 +121,7 @@ const SH = new Proxy(function(pieces, ...args) {
107
121
  let s;
108
122
 
109
123
  if (Array.isArray(args[i])) {
124
+ // @ts-ignore
110
125
  s = args[i].map(/** @param {string} x */(x) => {
111
126
  // Trim every element
112
127
  let str = String(x).trim();
@@ -163,32 +178,42 @@ const readIn = async () => {
163
178
 
164
179
  /**
165
180
  * Get user input from the command line (stdin)
181
+ * void when input has been aborted
166
182
  * @param {string} prompt - prompt or question
167
- * @returns {Promise<string>}
183
+ * @returns {{input: Promise<string|void>, abort: function(): void}}
168
184
  * @example
169
- * const content = await userIn();
185
+ * const user = userIn('Question: ');
186
+ * const content = await user.input
187
+ * // user.abort()
170
188
  */
171
-
172
- const userIn = (prompt) => new Promise((resolve) => {
189
+ const userIn = (prompt) => {
190
+ let resolvePromise;
191
+ const input = new Promise((resolve) => { resolvePromise = resolve; });
173
192
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
174
193
  let buffer = '';
175
194
  let timer;
176
- /**
177
- * @param {string} chunk
178
- */
195
+ /** @param {string} chunk */
179
196
  const onData = (chunk) => {
180
197
  if (chunk.length > 4 && chunk.includes('\n')) {
181
198
  clearTimeout(timer);
182
199
  timer = setTimeout(resolveFunc, 50);
183
200
  }
184
201
  };
202
+
185
203
  const resolveFunc = () => {
186
204
  let fullText = buffer;
187
205
  if (rl.line) fullText += rl.line;
206
+ cleanup();
207
+ resolvePromise(fullText);
208
+ };
209
+
210
+ const cleanup = () => {
188
211
  process.stdin.removeListener('data', onData);
189
- resolve(fullText);
212
+ rl.removeAllListeners('line');
213
+ clearTimeout(timer);
190
214
  rl.close();
191
215
  };
216
+
192
217
  rl.on('line', (line) => {
193
218
  buffer += line + '\n';
194
219
  clearTimeout(timer);
@@ -198,8 +223,15 @@ const userIn = (prompt) => new Promise((resolve) => {
198
223
 
199
224
  rl.setPrompt(prompt);
200
225
  rl.prompt();
201
- });
202
226
 
227
+ return {
228
+ input,
229
+ abort: () => {
230
+ cleanup();
231
+ resolvePromise();
232
+ }
233
+ };
234
+ };
203
235
  /**
204
236
  * Retries a given asynchronous function a specified number of times with optional delays between attempts.
205
237
  *
@@ -354,6 +386,7 @@ export {
354
386
  expBackoff,
355
387
  parseArgs,
356
388
  jsType,
389
+ hasProp,
357
390
  Test,
358
391
  assert,
359
392
  AsyncTracker
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.19",
5
+ "version": "1.1.21",
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
@@ -62,12 +62,18 @@ export function retry(count: number, a: string | number | typeof expBackoff | Fu
62
62
  export function readIn(): Promise<string>;
63
63
  /**
64
64
  * Get user input from the command line (stdin)
65
+ * void when input has been aborted
65
66
  * @param {string} prompt - prompt or question
66
- * @returns {Promise<string>}
67
+ * @returns {{input: Promise<string|void>, abort: function(): void}}
67
68
  * @example
68
- * const content = await userIn();
69
+ * const user = userIn('Question: ');
70
+ * const content = await user.input
71
+ * // user.abort()
69
72
  */
70
- export function userIn(prompt: string): Promise<string>;
73
+ export function userIn(prompt: string): {
74
+ input: Promise<string | void>;
75
+ abort: () => void;
76
+ };
71
77
  /**
72
78
  * Create a async/sync context in new execution callstack
73
79
  * @param {function} callback - async/sync function
@@ -143,6 +149,14 @@ export function parseArgs(args?: string[]): ArgsObject;
143
149
  * @returns {string} The "real" object / typeof name
144
150
  */
145
151
  export function jsType(fn: any): string;
152
+ /**
153
+ * 'Code Safe' has own prop
154
+ *
155
+ * @param {any} o - object to examine
156
+ * @param {string} p - property to look for
157
+ * @returns {boolean}
158
+ */
159
+ export function hasProp(o: any, p: string): boolean;
146
160
  import Test from './Test.js';
147
161
  import assert from 'node:assert';
148
162
  import AsyncTracker from './AsyncTracker.js';