@appium/support 7.0.5 → 7.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.
Files changed (114) hide show
  1. package/LICENSE +201 -0
  2. package/build/lib/console.d.ts +42 -88
  3. package/build/lib/console.d.ts.map +1 -1
  4. package/build/lib/console.js +20 -80
  5. package/build/lib/console.js.map +1 -1
  6. package/build/lib/doctor.d.ts +6 -18
  7. package/build/lib/doctor.d.ts.map +1 -1
  8. package/build/lib/doctor.js +0 -15
  9. package/build/lib/doctor.js.map +1 -1
  10. package/build/lib/env.d.ts +14 -20
  11. package/build/lib/env.d.ts.map +1 -1
  12. package/build/lib/env.js +13 -50
  13. package/build/lib/env.js.map +1 -1
  14. package/build/lib/fs.d.ts +109 -148
  15. package/build/lib/fs.d.ts.map +1 -1
  16. package/build/lib/fs.js +88 -188
  17. package/build/lib/fs.js.map +1 -1
  18. package/build/lib/image-util.d.ts +7 -6
  19. package/build/lib/image-util.d.ts.map +1 -1
  20. package/build/lib/image-util.js +9 -6
  21. package/build/lib/image-util.js.map +1 -1
  22. package/build/lib/index.d.ts +19 -17
  23. package/build/lib/index.d.ts.map +1 -1
  24. package/build/lib/logger.d.ts +1 -1
  25. package/build/lib/logger.d.ts.map +1 -1
  26. package/build/lib/logger.js +1 -1
  27. package/build/lib/logger.js.map +1 -1
  28. package/build/lib/logging.d.ts +7 -15
  29. package/build/lib/logging.d.ts.map +1 -1
  30. package/build/lib/logging.js +36 -62
  31. package/build/lib/logging.js.map +1 -1
  32. package/build/lib/mjpeg.d.ts +19 -56
  33. package/build/lib/mjpeg.d.ts.map +1 -1
  34. package/build/lib/mjpeg.js +53 -76
  35. package/build/lib/mjpeg.js.map +1 -1
  36. package/build/lib/mkdirp.d.ts +4 -1
  37. package/build/lib/mkdirp.d.ts.map +1 -1
  38. package/build/lib/mkdirp.js +1 -2
  39. package/build/lib/mkdirp.js.map +1 -1
  40. package/build/lib/net.d.ts +52 -90
  41. package/build/lib/net.d.ts.map +1 -1
  42. package/build/lib/net.js +104 -193
  43. package/build/lib/net.js.map +1 -1
  44. package/build/lib/node.d.ts +16 -17
  45. package/build/lib/node.d.ts.map +1 -1
  46. package/build/lib/node.js +106 -111
  47. package/build/lib/node.js.map +1 -1
  48. package/build/lib/npm.d.ts +65 -86
  49. package/build/lib/npm.d.ts.map +1 -1
  50. package/build/lib/npm.js +59 -117
  51. package/build/lib/npm.js.map +1 -1
  52. package/build/lib/plist.d.ts +36 -29
  53. package/build/lib/plist.d.ts.map +1 -1
  54. package/build/lib/plist.js +62 -59
  55. package/build/lib/plist.js.map +1 -1
  56. package/build/lib/process.d.ts +19 -2
  57. package/build/lib/process.d.ts.map +1 -1
  58. package/build/lib/process.js +24 -7
  59. package/build/lib/process.js.map +1 -1
  60. package/build/lib/system.d.ts +41 -6
  61. package/build/lib/system.d.ts.map +1 -1
  62. package/build/lib/system.js +46 -11
  63. package/build/lib/system.js.map +1 -1
  64. package/build/lib/tempdir.d.ts +26 -49
  65. package/build/lib/tempdir.d.ts.map +1 -1
  66. package/build/lib/tempdir.js +41 -73
  67. package/build/lib/tempdir.js.map +1 -1
  68. package/build/lib/timing.d.ts +28 -22
  69. package/build/lib/timing.d.ts.map +1 -1
  70. package/build/lib/timing.js +16 -17
  71. package/build/lib/timing.js.map +1 -1
  72. package/build/lib/util.d.ts +164 -181
  73. package/build/lib/util.d.ts.map +1 -1
  74. package/build/lib/util.js +193 -247
  75. package/build/lib/util.js.map +1 -1
  76. package/build/lib/zip.d.ts +81 -139
  77. package/build/lib/zip.d.ts.map +1 -1
  78. package/build/lib/zip.js +210 -258
  79. package/build/lib/zip.js.map +1 -1
  80. package/lib/console.ts +139 -0
  81. package/lib/{doctor.js → doctor.ts} +6 -20
  82. package/lib/{env.js → env.ts} +31 -59
  83. package/lib/fs.ts +453 -0
  84. package/lib/image-util.ts +40 -0
  85. package/lib/index.ts +1 -0
  86. package/lib/{logger.js → logger.ts} +1 -1
  87. package/lib/logging.ts +157 -0
  88. package/lib/mjpeg.ts +186 -0
  89. package/lib/{mkdirp.js → mkdirp.ts} +2 -2
  90. package/lib/net.ts +305 -0
  91. package/lib/{node.js → node.ts} +134 -133
  92. package/lib/npm.ts +291 -0
  93. package/lib/plist.ts +187 -0
  94. package/lib/process.ts +62 -0
  95. package/lib/system.ts +95 -0
  96. package/lib/tempdir.ts +115 -0
  97. package/lib/{timing.js → timing.ts} +28 -33
  98. package/lib/util.ts +561 -0
  99. package/lib/{zip.js → zip.ts} +341 -296
  100. package/package.json +20 -22
  101. package/tsconfig.json +3 -5
  102. package/index.js +0 -1
  103. package/lib/console.js +0 -173
  104. package/lib/fs.js +0 -496
  105. package/lib/image-util.js +0 -32
  106. package/lib/logging.js +0 -145
  107. package/lib/mjpeg.js +0 -207
  108. package/lib/net.js +0 -336
  109. package/lib/npm.js +0 -310
  110. package/lib/plist.js +0 -182
  111. package/lib/process.js +0 -46
  112. package/lib/system.js +0 -48
  113. package/lib/tempdir.js +0 -131
  114. package/lib/util.js +0 -584
package/lib/fs.js DELETED
@@ -1,496 +0,0 @@
1
- // @ts-check
2
-
3
- import B from 'bluebird';
4
- import crypto from 'node:crypto';
5
- import {
6
- close,
7
- constants,
8
- createReadStream,
9
- createWriteStream,
10
- promises as fsPromises,
11
- read,
12
- write,
13
- rmSync,
14
- open,
15
- } from 'node:fs';
16
- import { glob } from 'glob';
17
- import klaw from 'klaw';
18
- import _ from 'lodash';
19
- import ncp from 'ncp';
20
- import {packageDirectorySync} from 'package-directory';
21
- import path from 'node:path';
22
- import {readPackageSync} from 'read-pkg';
23
- import sanitize from 'sanitize-filename';
24
- import which from 'which';
25
- import log from './logger';
26
- import {Timer} from './timing';
27
- import {isWindows} from './system';
28
- import {pluralize} from './util';
29
-
30
- const ncpAsync =
31
- /** @type {(source: string, dest: string, opts: ncp.Options|undefined) => B<void>} */ (
32
- B.promisify(ncp)
33
- );
34
- const findRootCached = _.memoize(packageDirectorySync, (opts) => opts?.cwd);
35
-
36
- const fs = {
37
- /**
38
- * Resolves `true` if `path` is _readable_, which differs from Node.js' default behavior of "can we see it?"
39
- *
40
- * On Windows, ACLs are not supported, so this becomes a simple check for existence.
41
- *
42
- * This function will never reject.
43
- * @param {PathLike} path
44
- * @returns {Promise<boolean>}
45
- */
46
- async hasAccess(path) {
47
- try {
48
- await fsPromises.access(path, constants.R_OK);
49
- } catch {
50
- return false;
51
- }
52
- return true;
53
- },
54
-
55
- /**
56
- * Resolves `true` if `path` is executable; `false` otherwise.
57
- *
58
- * On Windows, this function delegates to {@linkcode fs.hasAccess}.
59
- *
60
- * This function will never reject.
61
- * @param {PathLike} path
62
- * @returns {Promise<boolean>}
63
- */
64
- async isExecutable(path) {
65
- try {
66
- if (isWindows()) {
67
- return await fs.hasAccess(path);
68
- }
69
- await fsPromises.access(path, constants.R_OK | constants.X_OK);
70
- } catch {
71
- return false;
72
- }
73
- return true;
74
- },
75
-
76
- /**
77
- * Alias for {@linkcode fs.hasAccess}
78
- * @param {PathLike} path
79
- */
80
- async exists(path) {
81
- return await fs.hasAccess(path);
82
- },
83
-
84
- /**
85
- * Remove a directory and all its contents, recursively
86
- * @param {PathLike} filepath
87
- * @returns Promise<void>
88
- * @see https://nodejs.org/api/fs.html#fspromisesrmpath-options
89
- */
90
- async rimraf(filepath) {
91
- return await fsPromises.rm(filepath, {recursive: true, force: true});
92
- },
93
-
94
- /**
95
- * Remove a directory and all its contents, recursively in sync
96
- * @param {PathLike} filepath
97
- * @returns undefined
98
- * @see https://nodejs.org/api/fs.html#fsrmsyncpath-options
99
- */
100
- rimrafSync(filepath) {
101
- return rmSync(filepath, {recursive: true, force: true});
102
- },
103
-
104
- /**
105
- * Like Node.js' `fsPromises.mkdir()`, but will _not_ reject if the directory already exists.
106
- *
107
- * @param {string|Buffer|URL} filepath
108
- * @param {import('fs').MakeDirectoryOptions} [opts]
109
- * @returns {Promise<string|undefined>}
110
- * @see https://nodejs.org/api/fs.html#fspromisesmkdirpath-options
111
- */
112
- async mkdir(filepath, opts = {}) {
113
- try {
114
- return await fsPromises.mkdir(filepath, opts);
115
- } catch (err) {
116
- if (err?.code !== 'EEXIST') {
117
- throw err;
118
- }
119
- }
120
- },
121
- /**
122
- * Copies files _and entire directories_
123
- * @param {string} source - Source to copy
124
- * @param {string} destination - Destination to copy to
125
- * @param {ncp.Options} [opts] - Additional arguments to pass to `ncp`
126
- * @see https://npm.im/ncp
127
- * @returns {Promise<void>}
128
- */
129
- async copyFile(source, destination, opts = {}) {
130
- if (!(await fs.hasAccess(source))) {
131
- throw new Error(`The file at '${source}' does not exist or is not accessible`);
132
- }
133
- return await ncpAsync(source, destination, opts);
134
- },
135
-
136
- /**
137
- * Create an MD5 hash of a file.
138
- * @param {PathLike} filePath
139
- * @returns {Promise<string>}
140
- */
141
- async md5(filePath) {
142
- return await fs.hash(filePath, 'md5');
143
- },
144
-
145
- /**
146
- * Move a file or a folder
147
- *
148
- * @param {string} from Source file/folder
149
- * @param {string} to Destination file/folder
150
- * @param {mv} [opts] Move options
151
- * @returns {Promise<void>}
152
- */
153
- async mv(from, to, opts) {
154
- const ensureDestination = async (/** @type {import('fs').PathLike} */ p) => {
155
- if (opts?.mkdirp && !(await this.exists(p))) {
156
- await fsPromises.mkdir(p, { recursive: true });
157
- return true;
158
- }
159
- return false;
160
- };
161
- const renameFile = async (
162
- /** @type {import('fs').PathLike} */ src,
163
- /** @type {import('fs').PathLike} */ dst,
164
- /** @type {boolean} */ skipExistenceCheck
165
- ) => {
166
- if (!skipExistenceCheck && await this.exists(dst)) {
167
- if (opts?.clobber === false) {
168
- const err = new Error(`The destination path '${dst}' already exists`);
169
- // @ts-ignore Legacy compat
170
- err.code = 'EEXIST';
171
- throw err;
172
- }
173
- await this.rimraf(dst);
174
- }
175
- try {
176
- await fsPromises.rename(src, dst);
177
- } catch (err) {
178
- // Handle cross-device link error by falling back to copy-and-delete
179
- if (err.code === 'EXDEV') {
180
- await this.copyFile(String(src), String(dst));
181
- await this.rimraf(src);
182
- } else {
183
- throw err;
184
- }
185
- }
186
- };
187
-
188
- /** @type {import('fs').Stats} */
189
- let fromStat;
190
- try {
191
- fromStat = await fsPromises.stat(from);
192
- } catch (err) {
193
- if (err.code === 'ENOENT') {
194
- throw new Error(`The source path '${from}' does not exist or is not accessible`);
195
- }
196
- throw err;
197
- }
198
- if (fromStat.isFile()) {
199
- const dstRootWasCreated = await ensureDestination(path.dirname(to));
200
- await renameFile(from, to, dstRootWasCreated);
201
- } else if (fromStat.isDirectory()) {
202
- const dstRootWasCreated = await ensureDestination(to);
203
- const items = await fsPromises.readdir(from, { withFileTypes: true });
204
- for (const item of items) {
205
- const srcPath = path.join(from, item.name);
206
- const destPath = path.join(to, item.name);
207
- if (item.isDirectory()) {
208
- await this.mv(srcPath, destPath, opts);
209
- } else if (item.isFile()) {
210
- await renameFile(srcPath, destPath, dstRootWasCreated);
211
- }
212
- }
213
- } else {
214
- return;
215
- }
216
-
217
- await this.rimraf(from);
218
- },
219
-
220
- /**
221
- * Find path to an executable in system `PATH`
222
- * @see https://github.com/npm/node-which
223
- */
224
- which,
225
-
226
- /**
227
- * Given a glob pattern, resolve with list of files matching that pattern
228
- * @see https://github.com/isaacs/node-glob
229
- */
230
- glob: /** @type {(pattern: string, opts?: import('glob').GlobOptions) => B<string[]>} */ (
231
- (pattern, options) => B.resolve(options ? glob(pattern, options) : glob(pattern))
232
- ),
233
-
234
- /**
235
- * Sanitize a filename
236
- * @see https://github.com/parshap/node-sanitize-filename
237
- */
238
- sanitizeName: sanitize,
239
-
240
- /**
241
- * Create a hex digest of some file at `filePath`
242
- * @param {PathLike} filePath
243
- * @param {string} [algorithm]
244
- * @returns {Promise<string>}
245
- */
246
- async hash(filePath, algorithm = 'sha1') {
247
- return await new B((resolve, reject) => {
248
- const fileHash = crypto.createHash(algorithm);
249
- const readStream = createReadStream(filePath);
250
- readStream.on('error', (e) =>
251
- reject(
252
- new Error(
253
- `Cannot calculate ${algorithm} hash for '${filePath}'. Original error: ${e.message}`
254
- )
255
- )
256
- );
257
- readStream.on('data', (chunk) => fileHash.update(chunk));
258
- readStream.on('end', () => resolve(fileHash.digest('hex')));
259
- });
260
- },
261
-
262
- /**
263
- * Returns an `Walker` instance, which is a readable stream (and thusly an async iterator).
264
- *
265
- * @param {string} dir - Dir to start walking at
266
- * @param {import('klaw').Options} [opts]
267
- * @returns {import('klaw').Walker}
268
- * @see https://www.npmjs.com/package/klaw
269
- */
270
- walk(dir, opts) {
271
- return klaw(dir, opts);
272
- },
273
-
274
- /**
275
- * Recursively create a directory.
276
- * @param {PathLike} dir
277
- * @returns {Promise<string|undefined>}
278
- */
279
- async mkdirp(dir) {
280
- return await fs.mkdir(dir, {recursive: true});
281
- },
282
-
283
- /**
284
- * Walks a directory given according to the parameters given. The callback will be invoked with a path joined with the dir parameter
285
- * @param {string} dir Directory path where we will start walking
286
- * @param {boolean} recursive Set it to true if you want to continue walking sub directories
287
- * @param {WalkDirCallback} callback The callback to be called when a new path is found
288
- * @throws {Error} If the `dir` parameter contains a path to an invalid folder
289
- * @returns {Promise<string?>} returns the found path or null if the item was not found
290
- */
291
- // eslint-disable-next-line promise/prefer-await-to-callbacks
292
- async walkDir(dir, recursive, callback) {
293
- let isValidRoot = false;
294
- let errMsg = null;
295
- try {
296
- isValidRoot = (await fs.stat(dir)).isDirectory();
297
- } catch (e) {
298
- errMsg = e.message;
299
- }
300
- if (!isValidRoot) {
301
- throw Error(
302
- `'${dir}' is not a valid root directory` + (errMsg ? `. Original error: ${errMsg}` : '')
303
- );
304
- }
305
-
306
- let walker;
307
- let fileCount = 0;
308
- let directoryCount = 0;
309
- const timer = new Timer().start();
310
- return await new B(function (resolve, reject) {
311
- /** @type {Promise} */
312
- let lastFileProcessed = B.resolve();
313
- walker = klaw(dir, {
314
- depthLimit: recursive ? -1 : 0,
315
- });
316
- walker
317
- .on('data', function (item) {
318
- walker.pause();
319
-
320
- if (!item.stats.isDirectory()) {
321
- fileCount++;
322
- } else {
323
- directoryCount++;
324
- }
325
-
326
- lastFileProcessed = (async () => {
327
- try {
328
- // eslint-disable-next-line promise/prefer-await-to-callbacks
329
- const done = await callback(item.path, item.stats.isDirectory());
330
- if (done) {
331
- return resolve(item.path);
332
- }
333
- walker.resume();
334
- } catch (err) {
335
- return reject(err);
336
- }
337
- })();
338
- })
339
- .on('error', function (err, item) {
340
- log.warn(`Got an error while walking '${item.path}': ${err.message}`);
341
- // klaw cannot get back from an ENOENT error
342
- if (err.code === 'ENOENT') {
343
- log.warn('All files may not have been accessed');
344
- reject(err);
345
- }
346
- })
347
- .on('end', function () {
348
- (async () => {
349
- try {
350
- const file = await lastFileProcessed;
351
- return resolve(/** @type {string|undefined} */ (file) ?? null);
352
- } catch (err) {
353
- log.warn(`Unexpected error: ${err.message}`);
354
- return reject(err);
355
- }
356
- })();
357
- });
358
- }).finally(function () {
359
- log.debug(
360
- `Traversed ${pluralize('directory', directoryCount, true)} ` +
361
- `and ${pluralize('file', fileCount, true)} ` +
362
- `in ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`
363
- );
364
- if (walker) {
365
- walker.destroy();
366
- }
367
- });
368
- },
369
- /**
370
- * Reads the closest `package.json` file from absolute path `dir`.
371
- * @param {string} dir - Directory to search from
372
- * @param {import('read-pkg').Options} [opts] - Additional options for `read-pkg`
373
- * @throws {Error} If there were problems finding or reading a `package.json` file
374
- * @returns {import('read-pkg').NormalizedPackageJson} A parsed `package.json`
375
- */
376
- readPackageJsonFrom(dir, opts = {}) {
377
- const cwd = fs.findRoot(dir);
378
- try {
379
- return readPackageSync(
380
- /** @type {import('read-pkg').NormalizeOptions} */ ({normalize: true, ...opts, cwd})
381
- );
382
- } catch (err) {
383
- err.message = `Failed to read a \`package.json\` from dir \`${dir}\`:\n\n${err.message}`;
384
- throw err;
385
- }
386
- },
387
- /**
388
- * Finds the project root directory from `dir`.
389
- * @param {string} dir - Directory to search from
390
- * @throws {TypeError} If `dir` is not a nonempty string or relative path
391
- * @throws {Error} If there were problems finding the project root
392
- * @returns {string} The closeset parent dir containing `package.json`
393
- */
394
- findRoot(dir) {
395
- if (!dir || !path.isAbsolute(dir)) {
396
- throw new TypeError('`findRoot()` must be provided a non-empty, absolute path');
397
- }
398
- const result = findRootCached({cwd: dir});
399
- if (!result) {
400
- throw new Error(`\`findRoot()\` could not find \`package.json\` from ${dir}`);
401
- }
402
- return result;
403
- },
404
-
405
- // add the supported `fs` functions
406
- access: fsPromises.access,
407
- appendFile: fsPromises.appendFile,
408
- chmod: fsPromises.chmod,
409
- close: B.promisify(close),
410
- constants,
411
- createWriteStream,
412
- createReadStream,
413
- lstat: fsPromises.lstat,
414
- /**
415
- * Warning: this is a promisified {@linkcode open fs.open}.
416
- * It resolves w/a file descriptor instead of a {@linkcode fsPromises.FileHandle FileHandle} object, as {@linkcode fsPromises.open} does. Use {@linkcode fs.openFile} if you want a `FileHandle`.
417
- * @type {(path: PathLike, flags: import('fs').OpenMode, mode?: import('fs').Mode) => Promise<number>}
418
- */
419
- open: B.promisify(open),
420
- openFile: fsPromises.open,
421
- readdir: fsPromises.readdir,
422
-
423
- read: /**
424
- * @type {ReadFn<NodeJS.ArrayBufferView>}
425
- */ (/** @type {unknown} */ (B.promisify(read))),
426
- readFile: fsPromises.readFile,
427
- readlink: fsPromises.readlink,
428
- realpath: fsPromises.realpath,
429
- rename: fsPromises.rename,
430
- stat: fsPromises.stat,
431
- symlink: fsPromises.symlink,
432
- unlink: fsPromises.unlink,
433
- write: B.promisify(write),
434
- writeFile: fsPromises.writeFile,
435
-
436
- // deprecated props
437
-
438
- /**
439
- * Use `constants.F_OK` instead.
440
- * @deprecated
441
- */
442
- F_OK: constants.F_OK,
443
-
444
- /**
445
- * Use `constants.R_OK` instead.
446
- * @deprecated
447
- */
448
- R_OK: constants.R_OK,
449
-
450
- /**
451
- * Use `constants.W_OK` instead.
452
- * @deprecated
453
- */
454
- W_OK: constants.W_OK,
455
-
456
- /**
457
- * Use `constants.X_OK` instead.
458
- * @deprecated
459
- */
460
- X_OK: constants.X_OK,
461
- };
462
-
463
- export {fs};
464
- export default fs;
465
-
466
- /**
467
- * The callback function which will be called during the directory walking
468
- * @callback WalkDirCallback
469
- * @param {string} itemPath The path of the file or folder
470
- * @param {boolean} isDirectory Shows if it is a directory or a file
471
- * @return {boolean|void} return true if you want to stop walking
472
- */
473
-
474
- /**
475
- * @typedef {import('glob')} glob
476
- * @typedef {import('fs').PathLike} PathLike
477
- */
478
-
479
- /**
480
- * @typedef {Object} mv
481
- * @property {boolean} [mkdirp=false] Whether to automatically create the destination folder structure
482
- * @property {boolean} [clobber=true] Set it to false if you want an exception to be thrown
483
- * if the destination file already exists
484
- * @property {number} [limit=16] Legacy deprecated property, not used anymore
485
- */
486
-
487
- /**
488
- * @template {NodeJS.ArrayBufferView} TBuffer
489
- * @callback ReadFn
490
- * @param {number} fd
491
- * @param {TBuffer|import('node:fs').ReadAsyncOptions<TBuffer>} buffer
492
- * @param {number} [offset]
493
- * @param {number} [length]
494
- * @param {number?} [position]
495
- * @returns {B<{bytesRead: number, buffer: TBuffer}>}
496
- */
package/lib/image-util.js DELETED
@@ -1,32 +0,0 @@
1
- let _sharp;
2
-
3
- /**
4
- * @returns {import('sharp')}
5
- */
6
- export function requireSharp() {
7
- if (!_sharp) {
8
- try {
9
- _sharp = require('sharp');
10
- } catch (err) {
11
- throw new Error(
12
- `Cannot load the 'sharp' module needed for images processing. ` +
13
- `Consider visiting https://sharp.pixelplumbing.com/install ` +
14
- `for troubleshooting. Original error: ${err.message}`
15
- );
16
- }
17
- }
18
- return _sharp;
19
- }
20
-
21
- /**
22
- * Crop the image by given rectangle (use base64 string as input and output)
23
- *
24
- * @param {string} base64Image The string with base64 encoded image.
25
- * Supports all image formats natively supported by Sharp library.
26
- * @param {import('sharp').Region} rect The selected region of image
27
- * @return {Promise<string>} base64 encoded string of cropped image
28
- */
29
- export async function cropBase64Image(base64Image, rect) {
30
- const buf = await requireSharp()(Buffer.from(base64Image, 'base64')).extract(rect).toBuffer();
31
- return buf.toString('base64');
32
- }
package/lib/logging.js DELETED
@@ -1,145 +0,0 @@
1
- import globalLog, { markSensitive as _markSensitive } from '@appium/logger';
2
- import _ from 'lodash';
3
- import moment from 'moment';
4
-
5
- /** @type {import('@appium/types').AppiumLoggerLevel[]} */
6
- export const LEVELS = ['silly', 'verbose', 'debug', 'info', 'http', 'warn', 'error'];
7
- const MAX_LOG_RECORDS_COUNT = 3000;
8
- const PREFIX_TIMESTAMP_FORMAT = 'HH-mm-ss:SSS';
9
- // mock log object is used in testing mode to silence the output
10
- const MOCK_LOG = {
11
- unwrap: () => ({
12
- loadSecureValuesPreprocessingRules: () => ({
13
- issues: [],
14
- rules: [],
15
- }),
16
- level: 'verbose',
17
- prefix: '',
18
- log: _.noop,
19
- }),
20
- ...(_.fromPairs(LEVELS.map((l) => [l, _.noop]))),
21
- };
22
- // export a default logger with no prefix
23
- export const log = getLogger();
24
-
25
- /**
26
- *
27
- * @param {AppiumLoggerPrefix?} [prefix=null]
28
- * @returns {AppiumLogger}
29
- */
30
- export function getLogger(prefix = null) {
31
- const [logger, usingGlobalLog] = _getLogger();
32
-
33
- // wrap the logger so that we can catch and modify any logging
34
- const wrappedLogger = {
35
- unwrap: () => logger,
36
- levels: LEVELS,
37
- prefix,
38
- errorWithException (/** @type {any[]} */ ...args) {
39
- this.error(...args);
40
- // make sure we have an `Error` object. Wrap if necessary
41
- return _.isError(args[0]) ? args[0] : new Error(args.join('\n'));
42
- },
43
- errorAndThrow (/** @type {any[]} */ ...args) {
44
- throw this.errorWithException(args);
45
- },
46
- updateAsyncContext(
47
- /** @type {import('@appium/types').AppiumLoggerContext} */ contextInfo,
48
- replace = false,
49
- ) {
50
- // Older Appium dependencies may not have 'updateAsyncStorage'
51
- this.unwrap().updateAsyncStorage?.(contextInfo, replace);
52
- },
53
- };
54
- // allow access to the level of the underlying logger
55
- Object.defineProperty(wrappedLogger, 'level', {
56
- get() {
57
- return logger.level;
58
- },
59
- set(newValue) {
60
- logger.level = newValue;
61
- },
62
- enumerable: true,
63
- configurable: true,
64
- });
65
- const isDebugTimestampLoggingEnabled = process.env._LOG_TIMESTAMP === '1';
66
- // add all the levels from `npmlog`, and map to the underlying logger
67
- for (const level of LEVELS) {
68
- wrappedLogger[level] = /** @param {any[]} args */ function (...args) {
69
- const finalPrefix = getFinalPrefix(this.prefix, isDebugTimestampLoggingEnabled);
70
- if (args.length) {
71
- // @ts-ignore This is OK
72
- logger[level](finalPrefix, ...args);
73
- } else {
74
- logger[level](finalPrefix, '');
75
- }
76
- };
77
- }
78
- if (!usingGlobalLog) {
79
- // if we're not using a global log specified from some top-level package,
80
- // set the log level to a default of verbose. Otherwise, let the top-level
81
- // package set the log level
82
- wrappedLogger.level = 'verbose';
83
- }
84
- return /** @type {AppiumLogger} */ (wrappedLogger);
85
- }
86
-
87
- /**
88
- * Marks arbitrary log message as sensitive.
89
- * This message will then be replaced with the default replacer
90
- * while being logged by any `info`, `debug`, etc. methods if the
91
- * asyncStorage has `isSensitive` flag enabled in its async context.
92
- * The latter is enabled by the corresponding HTTP middleware
93
- * in response to the `X-Appium-Is-Sensitive` request header
94
- * being set to 'true'.
95
- *
96
- * @template {any} T
97
- * @param {T} logMessage
98
- * @returns {{[k: string]: T}}
99
- */
100
- export function markSensitive(logMessage) {
101
- return _markSensitive(logMessage);
102
- }
103
-
104
- /**
105
- *
106
- * @returns {[import('@appium/logger').Logger, boolean]}
107
- */
108
- function _getLogger() {
109
- // check if the user set the `_TESTING` or `_FORCE_LOGS` flag
110
- const testingMode = process.env._TESTING === '1';
111
- const forceLogMode = process.env._FORCE_LOGS === '1';
112
- // if is possible that there is a logger instance that is already around,
113
- // in which case we want t o use that
114
- const useGlobalLog = !!global._global_npmlog;
115
- const logger = testingMode && !forceLogMode
116
- // in testing mode, use a mock logger object that we can query
117
- ? MOCK_LOG
118
- // otherwise, either use the global, or a new `npmlog` object
119
- : (global._global_npmlog || globalLog);
120
- // The default value is 10000, which causes excessive memory usage
121
- logger.maxRecordSize = MAX_LOG_RECORDS_COUNT;
122
- return [logger, useGlobalLog];
123
- }
124
-
125
- /**
126
- * @param {AppiumLoggerPrefix?} prefix
127
- * @param {boolean} [shouldLogTimestamp=false] whether to include timestamps into log prefixes
128
- * @returns {string}
129
- */
130
- function getFinalPrefix(prefix, shouldLogTimestamp = false) {
131
- const result = (_.isFunction(prefix) ? prefix() : prefix) ?? '';
132
- if (!shouldLogTimestamp) {
133
- return result;
134
- }
135
- const formattedTimestamp = `[${moment().format(PREFIX_TIMESTAMP_FORMAT)}]`;
136
- return result ? `${formattedTimestamp} ${result}` : formattedTimestamp;
137
- }
138
-
139
- export default log;
140
-
141
- /**
142
- * @typedef {import('@appium/types').AppiumLoggerPrefix} AppiumLoggerPrefix
143
- * @typedef {import('@appium/types').AppiumLogger} AppiumLogger
144
- * @typedef {import('@appium/types').AppiumLoggerLevel} AppiumLoggerLevel
145
- */