@appium/support 7.1.1 → 7.2.0

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 (70) hide show
  1. package/build/lib/console.d.ts.map +1 -1
  2. package/build/lib/console.js +1 -2
  3. package/build/lib/console.js.map +1 -1
  4. package/build/lib/env.d.ts +12 -5
  5. package/build/lib/env.d.ts.map +1 -1
  6. package/build/lib/env.js +5 -5
  7. package/build/lib/env.js.map +1 -1
  8. package/build/lib/fs.d.ts.map +1 -1
  9. package/build/lib/fs.js +2 -3
  10. package/build/lib/fs.js.map +1 -1
  11. package/build/lib/image-util.d.ts.map +1 -1
  12. package/build/lib/image-util.js +1 -1
  13. package/build/lib/image-util.js.map +1 -1
  14. package/build/lib/index.d.ts +1 -1
  15. package/build/lib/index.d.ts.map +1 -1
  16. package/build/lib/logging.d.ts.map +1 -1
  17. package/build/lib/logging.js +5 -8
  18. package/build/lib/logging.js.map +1 -1
  19. package/build/lib/mjpeg.d.ts.map +1 -1
  20. package/build/lib/mjpeg.js +7 -7
  21. package/build/lib/mjpeg.js.map +1 -1
  22. package/build/lib/net.d.ts.map +1 -1
  23. package/build/lib/net.js +20 -14
  24. package/build/lib/net.js.map +1 -1
  25. package/build/lib/node.d.ts.map +1 -1
  26. package/build/lib/node.js +7 -8
  27. package/build/lib/node.js.map +1 -1
  28. package/build/lib/npm.d.ts.map +1 -1
  29. package/build/lib/npm.js +3 -3
  30. package/build/lib/npm.js.map +1 -1
  31. package/build/lib/plist.js +11 -11
  32. package/build/lib/plist.js.map +1 -1
  33. package/build/lib/process.d.ts.map +1 -1
  34. package/build/lib/process.js +2 -2
  35. package/build/lib/process.js.map +1 -1
  36. package/build/lib/system.d.ts.map +1 -1
  37. package/build/lib/system.js +2 -3
  38. package/build/lib/system.js.map +1 -1
  39. package/build/lib/tempdir.d.ts +3 -2
  40. package/build/lib/tempdir.d.ts.map +1 -1
  41. package/build/lib/tempdir.js +2 -2
  42. package/build/lib/tempdir.js.map +1 -1
  43. package/build/lib/timing.d.ts.map +1 -1
  44. package/build/lib/timing.js +3 -7
  45. package/build/lib/timing.js.map +1 -1
  46. package/build/lib/util.d.ts +80 -1
  47. package/build/lib/util.d.ts.map +1 -1
  48. package/build/lib/util.js +158 -22
  49. package/build/lib/util.js.map +1 -1
  50. package/build/lib/zip.d.ts.map +1 -1
  51. package/build/lib/zip.js +3 -4
  52. package/build/lib/zip.js.map +1 -1
  53. package/lib/console.ts +1 -2
  54. package/lib/env.ts +5 -5
  55. package/lib/fs.ts +6 -4
  56. package/lib/image-util.ts +2 -1
  57. package/lib/index.ts +7 -1
  58. package/lib/logging.ts +5 -5
  59. package/lib/mjpeg.ts +9 -7
  60. package/lib/net.ts +21 -15
  61. package/lib/node.ts +7 -8
  62. package/lib/npm.ts +5 -3
  63. package/lib/plist.ts +11 -11
  64. package/lib/process.ts +8 -2
  65. package/lib/system.ts +2 -3
  66. package/lib/tempdir.ts +2 -2
  67. package/lib/timing.ts +3 -5
  68. package/lib/util.ts +171 -18
  69. package/lib/zip.ts +4 -5
  70. package/package.json +8 -9
package/lib/util.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import B from 'bluebird';
2
- import _ from 'lodash';
2
+ import {randomUUID} from 'node:crypto';
3
3
  import os from 'node:os';
4
4
  import path from 'node:path';
5
5
  import stream from 'node:stream';
6
- import {promisify} from 'node:util';
6
+ import {isDeepStrictEqual, promisify} from 'node:util';
7
7
  import {asyncmap} from 'asyncbox';
8
8
  import {fs} from './fs';
9
9
  import * as semver from 'semver';
@@ -11,7 +11,7 @@ import {quote as shellQuote, parse as shellParse} from 'shell-quote';
11
11
  export {shellParse};
12
12
  import pluralizeLib from 'pluralize';
13
13
  import {Base64Encode} from 'base64-stream';
14
- export {v1 as uuidV1, v3 as uuidV3, v4 as uuidV4, v5 as uuidV5} from 'uuid';
14
+ import {v1 as uuidV1Lib, v3 as uuidV3Lib, v5 as uuidV5Lib} from 'uuid';
15
15
  import * as _lockfile from 'lockfile';
16
16
  import type {Element} from '@appium/types';
17
17
 
@@ -28,6 +28,36 @@ export const GiB = MiB * 1024;
28
28
  /** A string which is never `''`. */
29
29
  export type NonEmptyString<T extends string = string> = T extends '' ? never : T;
30
30
 
31
+ /**
32
+ * @deprecated This helper is slated for removal. Please migrate callers away from UUID v1.
33
+ */
34
+ export function uuidV1(...args: Parameters<typeof uuidV1Lib>): ReturnType<typeof uuidV1Lib> {
35
+ return uuidV1Lib(...args);
36
+ }
37
+
38
+ /**
39
+ * @deprecated This helper is slated for removal. Please migrate callers away from UUID v3.
40
+ */
41
+ export function uuidV3(...args: Parameters<typeof uuidV3Lib>): ReturnType<typeof uuidV3Lib> {
42
+ return uuidV3Lib(...args);
43
+ }
44
+
45
+ /**
46
+ * Generates a v4 UUID using Node.js crypto.
47
+ *
48
+ * @returns A UUID v4 string
49
+ */
50
+ export function uuidV4(): string {
51
+ return randomUUID();
52
+ }
53
+
54
+ /**
55
+ * @deprecated This helper is slated for removal. Please migrate callers away from UUID v5.
56
+ */
57
+ export function uuidV5(...args: Parameters<typeof uuidV5Lib>): ReturnType<typeof uuidV5Lib> {
58
+ return uuidV5Lib(...args);
59
+ }
60
+
31
61
  /**
32
62
  * Type guard: returns true if the value is a non-empty string.
33
63
  *
@@ -35,7 +65,7 @@ export type NonEmptyString<T extends string = string> = T extends '' ? never : T
35
65
  * @returns `true` if `val` is a string with at least one character
36
66
  */
37
67
  export function hasContent(val: unknown): val is NonEmptyString {
38
- return _.isString(val) && val !== '';
68
+ return typeof val === 'string' && val !== '';
39
69
  }
40
70
 
41
71
  /**
@@ -45,10 +75,124 @@ export function hasContent(val: unknown): val is NonEmptyString {
45
75
  * @returns `true` if `val` is non-null and non-undefined (and not NaN for numbers)
46
76
  */
47
77
  export function hasValue<T>(val: T): val is NonNullable<T> {
48
- if (_.isNumber(val)) {
49
- return !_.isNaN(val);
78
+ if (typeof val === 'number') {
79
+ return !Number.isNaN(val);
50
80
  }
51
- return !_.isUndefined(val) && !_.isNull(val);
81
+ return val !== undefined && val !== null;
82
+ }
83
+
84
+ /**
85
+ * Creates a memoized version of a function.
86
+ *
87
+ * @param fn - Function to memoize
88
+ * @param resolver - Optional cache key resolver. If omitted, the first argument is used as the cache key.
89
+ * @returns Memoized function with a mutable `.cache` map (compatible with lodash-style cache resets in tests).
90
+ */
91
+ export function memoize<Fn extends (...args: any[]) => any>(
92
+ fn: Fn,
93
+ resolver?: (...args: Parameters<Fn>) => unknown
94
+ ): Fn & {cache: Map<unknown, ReturnType<Fn>>} {
95
+ const memoizedFn = (function (this: unknown, ...args: Parameters<Fn>) {
96
+ const key = resolver ? resolver.apply(this, args) : args[0];
97
+ if (memoizedFn.cache.has(key)) {
98
+ return memoizedFn.cache.get(key) as ReturnType<Fn>;
99
+ }
100
+ const result = fn.apply(this, args);
101
+ memoizedFn.cache.set(key, result);
102
+ return result;
103
+ }) as unknown as Fn & {cache: Map<unknown, ReturnType<Fn>>};
104
+ memoizedFn.cache = new Map<unknown, ReturnType<Fn>>();
105
+ return memoizedFn;
106
+ }
107
+
108
+ /**
109
+ * Returns true if the value is a plain object (Object prototype or null prototype).
110
+ *
111
+ * @param value - Value to check
112
+ * @returns `true` if the value is a plain object
113
+ */
114
+ export function isPlainObject(value: unknown): value is Record<string, unknown> {
115
+ if (value === null || typeof value !== 'object') {
116
+ return false;
117
+ }
118
+ const prototype = Object.getPrototypeOf(value);
119
+ return prototype === null || prototype === Object.prototype;
120
+ }
121
+
122
+ /**
123
+ * Returns true when the value has no elements/properties.
124
+ *
125
+ * @param value - Value to check
126
+ * @returns `true` if the value is empty
127
+ */
128
+ export function isEmpty(value: unknown): boolean {
129
+ if (value == null) {
130
+ return true;
131
+ }
132
+ if (typeof value === 'string' || Array.isArray(value) || Buffer.isBuffer(value)) {
133
+ return value.length === 0;
134
+ }
135
+ if (value instanceof Map || value instanceof Set) {
136
+ return value.size === 0;
137
+ }
138
+ if (typeof value === 'object' || typeof value === 'function') {
139
+ return Object.keys(value).length === 0;
140
+ }
141
+ return true;
142
+ }
143
+
144
+ /**
145
+ * Performs a deep equality check between two values.
146
+ *
147
+ * @param left - First value
148
+ * @param right - Second value
149
+ * @returns `true` when values are deeply equal
150
+ */
151
+ export function isEqual(left: unknown, right: unknown): boolean {
152
+ return isDeepStrictEqual(left, right);
153
+ }
154
+
155
+ /**
156
+ * Escapes RegExp special characters in a string.
157
+ *
158
+ * @param value - Input string
159
+ * @returns Escaped string safe for RegExp source
160
+ */
161
+ export function escapeRegExp(value: string): string {
162
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
163
+ }
164
+
165
+ /**
166
+ * Returns a duplicate-free copy of the input array.
167
+ *
168
+ * @param values - Input array
169
+ * @returns New array with unique values preserving input order
170
+ */
171
+ export function uniq<T>(values: readonly T[]): T[] {
172
+ return [...new Set(values)];
173
+ }
174
+
175
+ /**
176
+ * Truncates a string to a maximum length.
177
+ *
178
+ * @param value - Input string
179
+ * @param options - Truncation options or max length
180
+ * @returns Truncated string
181
+ */
182
+ export function truncateString(value: string, options: TruncateStringOptions | number = {}): string {
183
+ const normalizedOptions = typeof options === 'number' ? {length: options} : options;
184
+ const {length, omission = '…'} = normalizedOptions;
185
+ const stringValue =
186
+ value == null ? '' : typeof value === 'number' && Object.is(value, -0) ? '-0' : String(value);
187
+ const maxLength = length ?? 30;
188
+ if (maxLength <= 0) {
189
+ return omission;
190
+ }
191
+ if (stringValue.length <= maxLength) {
192
+ return stringValue;
193
+ }
194
+ const contentLength = maxLength - omission.length;
195
+ return contentLength > 0 ? `${stringValue.slice(0, contentLength)}${omission}` : omission;
52
196
  }
53
197
 
54
198
  /**
@@ -177,7 +321,7 @@ export function jsonStringify(
177
321
  replacer: ((key: string, value: unknown) => unknown) | null = null,
178
322
  space: number | string = 2
179
323
  ): string {
180
- const replacerFunc = _.isFunction(replacer) ? replacer : (_k: string, v: unknown) => v;
324
+ const replacerFunc = typeof replacer === 'function' ? replacer : (_k: string, v: unknown) => v;
181
325
 
182
326
  const bufferToJSON = Buffer.prototype.toJSON;
183
327
  delete (Buffer.prototype as Record<string, unknown>).toJSON;
@@ -204,7 +348,7 @@ export function jsonStringify(
204
348
  export function unwrapElement(el: Element | string): string {
205
349
  const elObj = el as unknown as Record<string, string>;
206
350
  for (const propName of [W3C_WEB_ELEMENT_IDENTIFIER, 'ELEMENT']) {
207
- if (_.has(elObj, propName)) {
351
+ if (Object.hasOwn(elObj, propName)) {
208
352
  return elObj[propName];
209
353
  }
210
354
  }
@@ -238,11 +382,11 @@ export function filterObject<T extends Record<string, unknown>>(
238
382
  obj: T,
239
383
  predicate?: ((value: unknown, obj: T) => boolean) | unknown
240
384
  ): Partial<T> {
241
- const newObj = _.clone(obj) as Record<string, unknown>;
385
+ const newObj = {...obj} as Record<string, unknown>;
242
386
  let pred: (v: unknown, o: T) => boolean;
243
- if (_.isUndefined(predicate)) {
244
- pred = (v) => !_.isUndefined(v);
245
- } else if (!_.isFunction(predicate)) {
387
+ if (predicate === undefined) {
388
+ pred = (v) => v !== undefined;
389
+ } else if (typeof predicate !== 'function') {
246
390
  const valuePredicate = predicate;
247
391
  pred = (v) => v === valuePredicate;
248
392
  } else {
@@ -374,6 +518,14 @@ export interface LockFileOptions {
374
518
  tryRecovery?: boolean;
375
519
  }
376
520
 
521
+ /** Options for truncateString(). */
522
+ export interface TruncateStringOptions {
523
+ /** Maximum length of the resulting string. Default 30. */
524
+ length?: number;
525
+ /** Suffix appended to truncated strings. Default "…". */
526
+ omission?: string;
527
+ }
528
+
377
529
  /** Guard function that runs the given behavior under the lock. */
378
530
  type LockFileGuardFn<T> = (behavior: () => Promise<T> | T) => Promise<T>;
379
531
 
@@ -415,7 +567,7 @@ export function compareVersions(
415
567
  * @returns Quoted string suitable for shell parsing
416
568
  */
417
569
  export function quote(args: string | string[]): string {
418
- return shellQuote(_.castArray(args));
570
+ return shellQuote(Array.isArray(args) ? args : [args]);
419
571
  }
420
572
 
421
573
  /**
@@ -432,9 +584,9 @@ export function pluralize(
432
584
  options: PluralizeOptions | boolean = {}
433
585
  ): string {
434
586
  let inclusive = false;
435
- if (_.isBoolean(options)) {
587
+ if (typeof options === 'boolean') {
436
588
  inclusive = options;
437
- } else if (_.isBoolean(options?.inclusive)) {
589
+ } else if (typeof options?.inclusive === 'boolean') {
438
590
  inclusive = options.inclusive;
439
591
  }
440
592
  return pluralizeLib(word, count, inclusive);
@@ -537,13 +689,14 @@ export function getLockFileGuard<T>(
537
689
  acquired = true;
538
690
  } catch (e) {
539
691
  const err = e as Error;
540
- if (_.includes(err.message, 'EEXIST') && tryRecovery && !triedRecovery) {
692
+ if (err.message?.includes('EEXIST') && tryRecovery && !triedRecovery) {
541
693
  _lockfile.unlockSync(lockFile);
542
694
  triedRecovery = true;
543
695
  } else {
544
696
  throw new Error(
545
697
  `Could not acquire lock on '${lockFile}' after ${timeout}s. ` +
546
- `Original error: ${err.message}`
698
+ `Original error: ${err.message}`,
699
+ {cause: e}
547
700
  );
548
701
  }
549
702
  }
package/lib/zip.ts CHANGED
@@ -1,4 +1,3 @@
1
- import _ from 'lodash';
2
1
  import {promisify} from 'node:util';
3
2
  import * as yauzl from 'yauzl';
4
3
  import archiver from 'archiver';
@@ -9,7 +8,7 @@ import {pipeline} from 'node:stream/promises';
9
8
  import {fs} from './fs';
10
9
  import {isWindows} from './system';
11
10
  import {Base64Encode} from 'base64-stream';
12
- import {isSubPath, toReadableSizeString, GiB} from './util';
11
+ import {isSubPath, memoize, toReadableSizeString, GiB} from './util';
13
12
  import {Timer} from './timing';
14
13
  import log from './logger';
15
14
  import getStream from 'get-stream';
@@ -554,8 +553,8 @@ async function extractWithSystemUnzip(zipFilePath: string, destDir: string): Pro
554
553
  let executablePath: string;
555
554
  try {
556
555
  executablePath = await getExecutablePath(isWindowsHost ? 'powershell.exe' : 'unzip');
557
- } catch {
558
- throw new Error('Could not find system unzip');
556
+ } catch (e) {
557
+ throw new Error('Could not find system unzip', {cause: e});
559
558
  }
560
559
 
561
560
  if (isWindowsHost) {
@@ -581,7 +580,7 @@ async function extractWithSystemUnzip(zipFilePath: string, destDir: string): Pro
581
580
  * Finds and memoizes the full path to the given executable.
582
581
  * Rejects if it is not found.
583
582
  */
584
- const getExecutablePath = _.memoize(
583
+ const getExecutablePath = memoize(
585
584
  /**
586
585
  * @returns Full Path to the executable
587
586
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appium/support",
3
- "version": "7.1.1",
3
+ "version": "7.2.0",
4
4
  "description": "Support libs used across Appium packages",
5
5
  "keywords": [
6
6
  "automation",
@@ -42,26 +42,25 @@
42
42
  "dependencies": {
43
43
  "@appium/logger": "2.0.7",
44
44
  "@appium/tsconfig": "1.1.2",
45
- "@appium/types": "1.3.1",
45
+ "@appium/types": "1.4.0",
46
46
  "@colors/colors": "1.6.0",
47
47
  "archiver": "7.0.1",
48
- "asyncbox": "6.1.0",
49
- "axios": "1.15.0",
48
+ "asyncbox": "6.2.0",
49
+ "axios": "1.15.2",
50
50
  "base64-stream": "1.0.0",
51
51
  "bluebird": "3.7.2",
52
52
  "bplist-creator": "0.1.1",
53
53
  "bplist-parser": "0.3.2",
54
54
  "form-data": "4.0.5",
55
55
  "get-stream": "9.0.1",
56
- "glob": "13.0.6",
56
+ "glob": "13.0.5",
57
57
  "jsftp": "2.1.3",
58
58
  "klaw": "4.1.0",
59
59
  "lockfile": "1.0.4",
60
- "lodash": "4.18.1",
61
60
  "log-symbols": "7.0.1",
62
61
  "ncp": "2.0.0",
63
62
  "package-directory": "8.2.0",
64
- "plist": "3.1.0",
63
+ "plist": "4.0.0",
65
64
  "pluralize": "8.0.0",
66
65
  "read-pkg": "10.1.0",
67
66
  "resolve-from": "5.0.0",
@@ -69,7 +68,7 @@
69
68
  "semver": "7.7.4",
70
69
  "shell-quote": "1.8.3",
71
70
  "supports-color": "10.2.2",
72
- "teen_process": "4.1.1",
71
+ "teen_process": "4.1.3",
73
72
  "type-fest": "5.6.0",
74
73
  "uuid": "14.0.0",
75
74
  "which": "6.0.1",
@@ -85,5 +84,5 @@
85
84
  "publishConfig": {
86
85
  "access": "public"
87
86
  },
88
- "gitHead": "17f84265d10944fec06ae7684ae8ad77d1224b50"
87
+ "gitHead": "915d767085c6b40ae90b7592d5130c76414ca3b5"
89
88
  }