@appium/support 7.0.4 → 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.
- package/build/lib/console.d.ts +42 -88
- package/build/lib/console.d.ts.map +1 -1
- package/build/lib/console.js +25 -85
- package/build/lib/console.js.map +1 -1
- package/build/lib/doctor.d.ts +6 -18
- package/build/lib/doctor.d.ts.map +1 -1
- package/build/lib/doctor.js +0 -15
- package/build/lib/doctor.js.map +1 -1
- package/build/lib/env.d.ts +14 -20
- package/build/lib/env.d.ts.map +1 -1
- package/build/lib/env.js +24 -61
- package/build/lib/env.js.map +1 -1
- package/build/lib/fs.d.ts +109 -148
- package/build/lib/fs.d.ts.map +1 -1
- package/build/lib/fs.js +130 -230
- package/build/lib/fs.js.map +1 -1
- package/build/lib/image-util.d.ts +7 -6
- package/build/lib/image-util.d.ts.map +1 -1
- package/build/lib/image-util.js +9 -6
- package/build/lib/image-util.js.map +1 -1
- package/build/lib/index.d.ts +19 -17
- package/build/lib/index.d.ts.map +1 -1
- package/build/lib/logger.d.ts +1 -1
- package/build/lib/logger.d.ts.map +1 -1
- package/build/lib/logger.js +1 -1
- package/build/lib/logger.js.map +1 -1
- package/build/lib/logging.d.ts +7 -15
- package/build/lib/logging.d.ts.map +1 -1
- package/build/lib/logging.js +36 -62
- package/build/lib/logging.js.map +1 -1
- package/build/lib/mjpeg.d.ts +19 -56
- package/build/lib/mjpeg.d.ts.map +1 -1
- package/build/lib/mjpeg.js +55 -78
- package/build/lib/mjpeg.js.map +1 -1
- package/build/lib/mkdirp.d.ts +4 -1
- package/build/lib/mkdirp.d.ts.map +1 -1
- package/build/lib/mkdirp.js +1 -2
- package/build/lib/mkdirp.js.map +1 -1
- package/build/lib/net.d.ts +52 -90
- package/build/lib/net.d.ts.map +1 -1
- package/build/lib/net.js +104 -193
- package/build/lib/net.js.map +1 -1
- package/build/lib/node.d.ts +16 -17
- package/build/lib/node.d.ts.map +1 -1
- package/build/lib/node.js +115 -120
- package/build/lib/node.js.map +1 -1
- package/build/lib/npm.d.ts +65 -86
- package/build/lib/npm.d.ts.map +1 -1
- package/build/lib/npm.js +64 -122
- package/build/lib/npm.js.map +1 -1
- package/build/lib/plist.d.ts +36 -29
- package/build/lib/plist.d.ts.map +1 -1
- package/build/lib/plist.js +62 -59
- package/build/lib/plist.js.map +1 -1
- package/build/lib/process.d.ts +19 -2
- package/build/lib/process.d.ts.map +1 -1
- package/build/lib/process.js +24 -7
- package/build/lib/process.js.map +1 -1
- package/build/lib/system.d.ts +41 -6
- package/build/lib/system.d.ts.map +1 -1
- package/build/lib/system.js +49 -14
- package/build/lib/system.js.map +1 -1
- package/build/lib/tempdir.d.ts +26 -49
- package/build/lib/tempdir.d.ts.map +1 -1
- package/build/lib/tempdir.js +46 -78
- package/build/lib/tempdir.js.map +1 -1
- package/build/lib/timing.d.ts +28 -22
- package/build/lib/timing.d.ts.map +1 -1
- package/build/lib/timing.js +16 -17
- package/build/lib/timing.js.map +1 -1
- package/build/lib/util.d.ts +164 -181
- package/build/lib/util.d.ts.map +1 -1
- package/build/lib/util.js +198 -253
- package/build/lib/util.js.map +1 -1
- package/build/lib/zip.d.ts +81 -139
- package/build/lib/zip.d.ts.map +1 -1
- package/build/lib/zip.js +235 -283
- package/build/lib/zip.js.map +1 -1
- package/lib/console.ts +139 -0
- package/lib/{doctor.js → doctor.ts} +6 -20
- package/lib/{env.js → env.ts} +34 -62
- package/lib/fs.ts +453 -0
- package/lib/image-util.ts +40 -0
- package/lib/index.ts +1 -0
- package/lib/{logger.js → logger.ts} +1 -1
- package/lib/logging.ts +157 -0
- package/lib/mjpeg.ts +186 -0
- package/lib/{mkdirp.js → mkdirp.ts} +2 -2
- package/lib/net.ts +305 -0
- package/lib/{node.js → node.ts} +136 -135
- package/lib/npm.ts +291 -0
- package/lib/plist.ts +187 -0
- package/lib/process.ts +62 -0
- package/lib/system.ts +95 -0
- package/lib/tempdir.ts +115 -0
- package/lib/{timing.js → timing.ts} +28 -33
- package/lib/util.ts +561 -0
- package/lib/{zip.js → zip.ts} +344 -299
- package/package.json +24 -26
- package/tsconfig.json +3 -5
- package/index.js +0 -1
- package/lib/console.js +0 -173
- package/lib/fs.js +0 -496
- package/lib/image-util.js +0 -32
- package/lib/logging.js +0 -145
- package/lib/mjpeg.js +0 -207
- package/lib/net.js +0 -336
- package/lib/npm.js +0 -310
- package/lib/plist.js +0 -182
- package/lib/process.js +0 -46
- package/lib/system.js +0 -48
- package/lib/tempdir.js +0 -131
- package/lib/util.js +0 -585
package/lib/fs.js
DELETED
|
@@ -1,496 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
import B from 'bluebird';
|
|
4
|
-
import crypto from '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 'fs';
|
|
16
|
-
import { glob } from 'glob';
|
|
17
|
-
import klaw from 'klaw';
|
|
18
|
-
import _ from 'lodash';
|
|
19
|
-
import ncp from 'ncp';
|
|
20
|
-
import path from 'path';
|
|
21
|
-
import pkgDir from 'pkg-dir';
|
|
22
|
-
import readPkg 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(pkgDir.sync);
|
|
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 readPkg.sync(
|
|
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(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
|
-
*/
|