node-simctl 8.1.7 → 8.2.1

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 (62) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/lib/helpers.d.ts +0 -6
  3. package/build/lib/helpers.d.ts.map +1 -1
  4. package/build/lib/helpers.js +0 -10
  5. package/build/lib/helpers.js.map +1 -1
  6. package/build/lib/simctl.d.ts +31 -31
  7. package/build/lib/simctl.d.ts.map +1 -1
  8. package/build/lib/simctl.js +55 -55
  9. package/build/lib/simctl.js.map +1 -1
  10. package/build/lib/subcommands/appinfo.d.ts.map +1 -1
  11. package/build/lib/subcommands/appinfo.js +4 -5
  12. package/build/lib/subcommands/appinfo.js.map +1 -1
  13. package/build/lib/subcommands/boot.d.ts.map +1 -1
  14. package/build/lib/subcommands/boot.js +1 -5
  15. package/build/lib/subcommands/boot.js.map +1 -1
  16. package/build/lib/subcommands/bootstatus.d.ts.map +1 -1
  17. package/build/lib/subcommands/bootstatus.js +1 -5
  18. package/build/lib/subcommands/bootstatus.js.map +1 -1
  19. package/build/lib/subcommands/create.d.ts.map +1 -1
  20. package/build/lib/subcommands/create.js +2 -6
  21. package/build/lib/subcommands/create.js.map +1 -1
  22. package/build/lib/subcommands/io.js +2 -2
  23. package/build/lib/subcommands/io.js.map +1 -1
  24. package/build/lib/subcommands/keychain.d.ts.map +1 -1
  25. package/build/lib/subcommands/keychain.js +20 -21
  26. package/build/lib/subcommands/keychain.js.map +1 -1
  27. package/build/lib/subcommands/launch.d.ts.map +1 -1
  28. package/build/lib/subcommands/launch.js +1 -5
  29. package/build/lib/subcommands/launch.js.map +1 -1
  30. package/build/lib/subcommands/list.d.ts.map +1 -1
  31. package/build/lib/subcommands/list.js +12 -13
  32. package/build/lib/subcommands/list.js.map +1 -1
  33. package/build/lib/subcommands/location.d.ts.map +1 -1
  34. package/build/lib/subcommands/location.js +14 -14
  35. package/build/lib/subcommands/location.js.map +1 -1
  36. package/build/lib/subcommands/push.js +2 -2
  37. package/build/lib/subcommands/push.js.map +1 -1
  38. package/build/lib/subcommands/shutdown.d.ts.map +1 -1
  39. package/build/lib/subcommands/shutdown.js +1 -5
  40. package/build/lib/subcommands/shutdown.js.map +1 -1
  41. package/build/lib/subcommands/spawn.d.ts.map +1 -1
  42. package/build/lib/subcommands/spawn.js +4 -8
  43. package/build/lib/subcommands/spawn.js.map +1 -1
  44. package/build/lib/subcommands/ui.d.ts.map +1 -1
  45. package/build/lib/subcommands/ui.js +3 -7
  46. package/build/lib/subcommands/ui.js.map +1 -1
  47. package/lib/helpers.ts +0 -10
  48. package/lib/simctl.ts +60 -63
  49. package/lib/subcommands/appinfo.ts +6 -2
  50. package/lib/subcommands/boot.ts +1 -2
  51. package/lib/subcommands/bootstatus.ts +4 -4
  52. package/lib/subcommands/create.ts +2 -3
  53. package/lib/subcommands/io.ts +2 -2
  54. package/lib/subcommands/keychain.ts +22 -23
  55. package/lib/subcommands/launch.ts +1 -2
  56. package/lib/subcommands/list.ts +15 -17
  57. package/lib/subcommands/location.ts +15 -15
  58. package/lib/subcommands/push.ts +2 -2
  59. package/lib/subcommands/shutdown.ts +1 -2
  60. package/lib/subcommands/spawn.ts +4 -5
  61. package/lib/subcommands/ui.ts +3 -4
  62. package/package.json +1 -6
@@ -1,4 +1,3 @@
1
- import _ from 'lodash';
2
1
  import {log, LOG_PREFIX} from '../logger';
3
2
  import {retryInterval} from 'asyncbox';
4
3
  import {SIM_RUNTIME_NAME, normalizeVersion} from '../helpers';
@@ -36,7 +35,7 @@ export async function createDevice(
36
35
  runtimeIds.push(await this.getRuntimeForPlatformVersionViaJson(platformVersion, platform));
37
36
  } catch {}
38
37
 
39
- if (_.isEmpty(runtimeIds)) {
38
+ if (runtimeIds.length === 0) {
40
39
  // at first make sure that the runtime id is the right one
41
40
  // in some versions of Xcode it will be a patch version
42
41
  let runtimeId: string;
@@ -95,7 +94,7 @@ export async function createDevice(
95
94
  // make sure that it gets out of the "Creating" state
96
95
  const retries = parseInt(`${timeout / 1000}`, 10);
97
96
  await retryInterval(retries, 1000, async () => {
98
- const devices = _.flatMap(_.values(await this.getDevices()));
97
+ const devices = Object.values(await this.getDevices()).flatMap((entries) => entries);
99
98
  for (const device of devices) {
100
99
  if (device.udid === udid) {
101
100
  if (device.state === 'Creating') {
@@ -1,8 +1,8 @@
1
1
  import {rimraf} from 'rimraf';
2
+ import {randomUUID} from 'node:crypto';
2
3
  import path from 'node:path';
3
4
  import os from 'node:os';
4
5
  import fs from 'node:fs/promises';
5
- import {uuidV4} from '../helpers';
6
6
  import type {Simctl} from '../simctl';
7
7
 
8
8
  /**
@@ -17,7 +17,7 @@ import type {Simctl} from '../simctl';
17
17
  */
18
18
  export async function getScreenshot(this: Simctl): Promise<string> {
19
19
  const udid = this.requireUdid('io screenshot');
20
- const pathToScreenshotPng = path.resolve(os.tmpdir(), `${await uuidV4()}.png`);
20
+ const pathToScreenshotPng = path.resolve(os.tmpdir(), `${randomUUID()}.png`);
21
21
  try {
22
22
  await this.exec('io', {
23
23
  args: [udid, 'screenshot', pathToScreenshotPng],
@@ -1,33 +1,11 @@
1
1
  import os from 'node:os';
2
2
  import fs from 'node:fs/promises';
3
- import {uuidV4} from '../helpers';
3
+ import {randomUUID} from 'node:crypto';
4
4
  import path from 'node:path';
5
- import _ from 'lodash';
6
5
  import {rimraf} from 'rimraf';
7
6
  import type {Simctl} from '../simctl';
8
7
  import type {CertOptions} from '../types';
9
8
 
10
- /**
11
- * @param payload - Certificate payload (string or Buffer)
12
- * @param onPayloadStored - Callback function to execute with the file path
13
- */
14
- async function handleRawPayload(
15
- payload: string | Buffer,
16
- onPayloadStored: (filePath: string) => Promise<any>,
17
- ): Promise<void> {
18
- const filePath = path.resolve(os.tmpdir(), `${await uuidV4()}.pem`);
19
- try {
20
- if (_.isBuffer(payload)) {
21
- await fs.writeFile(filePath, payload);
22
- } else {
23
- await fs.writeFile(filePath, payload, 'utf8');
24
- }
25
- await onPayloadStored(filePath);
26
- } finally {
27
- await rimraf(filePath);
28
- }
29
- }
30
-
31
9
  /**
32
10
  * Adds the given certificate to the Trusted Root Store on the simulator
33
11
  *
@@ -99,3 +77,24 @@ export async function resetKeychain(this: Simctl): Promise<void> {
99
77
  args: [this.requireUdid('keychain reset'), 'reset'],
100
78
  });
101
79
  }
80
+
81
+ /**
82
+ * @param payload - Certificate payload (string or Buffer)
83
+ * @param onPayloadStored - Callback function to execute with the file path
84
+ */
85
+ async function handleRawPayload(
86
+ payload: string | Buffer,
87
+ onPayloadStored: (filePath: string) => Promise<any>,
88
+ ): Promise<void> {
89
+ const filePath = path.resolve(os.tmpdir(), `${randomUUID()}.pem`);
90
+ try {
91
+ if (Buffer.isBuffer(payload)) {
92
+ await fs.writeFile(filePath, payload);
93
+ } else {
94
+ await fs.writeFile(filePath, payload, 'utf8');
95
+ }
96
+ await onPayloadStored(filePath);
97
+ } finally {
98
+ await rimraf(filePath);
99
+ }
100
+ }
@@ -1,4 +1,3 @@
1
- import _ from 'lodash';
2
1
  import {retryInterval} from 'asyncbox';
3
2
  import type {Simctl} from '../simctl';
4
3
 
@@ -25,7 +24,7 @@ export async function launchApp(
25
24
  const {stdout} = await this.exec('launch', {
26
25
  args: [this.requireUdid('launch'), bundleId],
27
26
  });
28
- return _.trim(stdout) || '';
27
+ return stdout.trim() || '';
29
28
  });
30
29
  return result || '';
31
30
  }
@@ -1,4 +1,3 @@
1
- import _ from 'lodash';
2
1
  import {SIM_RUNTIME_NAME, normalizeVersion} from '../helpers';
3
2
  import {log, LOG_PREFIX} from '../logger';
4
3
  import type {Simctl} from '../simctl';
@@ -32,20 +31,16 @@ export async function getDevicesByParsing(
32
31
  // ...
33
32
  // so, get the `-- iOS X.X --` line to find the sdk (X.X)
34
33
  // and the rest of the listing in order to later find the devices
35
- const deviceSectionRe =
36
- _.isEmpty(platform) || !platform
37
- ? new RegExp(`\\-\\-\\s+(\\S+)\\s+(\\S+)\\s+\\-\\-(\\n\\s{4}.+)*`, 'mgi')
38
- : new RegExp(
39
- `\\-\\-\\s+${_.escapeRegExp(platform)}\\s+(\\S+)\\s+\\-\\-(\\n\\s{4}.+)*`,
40
- 'mgi',
41
- );
34
+ const deviceSectionRe = !platform
35
+ ? new RegExp(`\\-\\-\\s+(\\S+)\\s+(\\S+)\\s+\\-\\-(\\n\\s{4}.+)*`, 'mgi')
36
+ : new RegExp(`\\-\\-\\s+${escapeRegExp(platform)}\\s+(\\S+)\\s+\\-\\-(\\n\\s{4}.+)*`, 'mgi');
42
37
  const matches: RegExpExecArray[] = [];
43
38
  let match: RegExpExecArray | null;
44
39
  // make an entry for each sdk version
45
40
  while ((match = deviceSectionRe.exec(stdout))) {
46
41
  matches.push(match);
47
42
  }
48
- if (_.isEmpty(matches)) {
43
+ if (matches.length === 0) {
49
44
  throw new Error('Could not find device section');
50
45
  }
51
46
 
@@ -135,11 +130,10 @@ export async function getDevices(
135
130
  * }
136
131
  * }
137
132
  */
138
- const versionMatchRe =
139
- _.isEmpty(platform) || !platform
140
- ? new RegExp(`^([^\\s-]+)[\\s-](\\S+)`, 'i')
141
- : new RegExp(`^${_.escapeRegExp(platform)}[\\s-](\\S+)`, 'i');
142
- for (const [sdkNameRaw, entries] of _.toPairs(JSON.parse(stdout).devices)) {
133
+ const versionMatchRe = !platform
134
+ ? new RegExp(`^([^\\s-]+)[\\s-](\\S+)`, 'i')
135
+ : new RegExp(`^${escapeRegExp(platform)}[\\s-](\\S+)`, 'i');
136
+ for (const [sdkNameRaw, entries] of Object.entries(JSON.parse(stdout).devices)) {
143
137
  // there could be a longer name, so remove it
144
138
  const sdkName = sdkNameRaw.replace(SIM_RUNTIME_NAME, '');
145
139
  const versionMatch = versionMatchRe.exec(sdkName);
@@ -152,7 +146,7 @@ export async function getDevices(
152
146
  devices[sdk] = devices[sdk] || [];
153
147
  devices[sdk].push(
154
148
  ...(entries as any[])
155
- .filter((el) => _.isUndefined(el.isAvailable) || el.isAvailable)
149
+ .filter((el) => el.isAvailable === undefined || el.isAvailable)
156
150
  .map((el: any) => {
157
151
  delete el.availability;
158
152
  return {
@@ -178,7 +172,7 @@ export async function getDevices(
178
172
  }
179
173
 
180
174
  let errMsg = `'${forSdk}' does not exist in the list of simctl SDKs.`;
181
- const availableSDKs = _.keys(devices);
175
+ const availableSDKs = Object.keys(devices);
182
176
  errMsg += availableSDKs.length
183
177
  ? ` Only the following Simulator SDK versions are available on your system: ${availableSDKs.join(', ')}`
184
178
  : ` No Simulator SDK versions are available on your system. Please install some via Xcode preferences.`;
@@ -234,7 +228,7 @@ export async function getRuntimeForPlatformVersion(
234
228
  });
235
229
  // https://regex101.com/r/UykjQZ/1
236
230
  const runtimeRe = new RegExp(
237
- `${_.escapeRegExp(platform)}\\s+(\\d+\\.\\d+)\\s+\\((\\d+\\.\\d+\\.*\\d*)`,
231
+ `${escapeRegExp(platform)}\\s+(\\d+\\.\\d+)\\s+\\((\\d+\\.\\d+\\.*\\d*)`,
238
232
  'i',
239
233
  );
240
234
  for (const line of stdout.split('\n')) {
@@ -322,3 +316,7 @@ export async function list(this: Simctl): Promise<any> {
322
316
  throw new Error(`Unable to parse simctl list: ${e.message}`);
323
317
  }
324
318
  }
319
+
320
+ function escapeRegExp(value: string): string {
321
+ return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
322
+ }
@@ -1,20 +1,5 @@
1
1
  import type {Simctl} from '../simctl';
2
2
 
3
- /**
4
- * Formats the given location argument for simctl usage
5
- *
6
- * @param name Argument name
7
- * @param value Location argument value
8
- * @returns Formatted value, for example -73.768254
9
- */
10
- function formatArg(name: string, value: string | number): string {
11
- const flt = parseFloat(`${value}`);
12
- if (isNaN(flt)) {
13
- throw new TypeError(`${name} must be a valid number, got '${value}' instead`);
14
- }
15
- return flt.toFixed(7);
16
- }
17
-
18
3
  /**
19
4
  * Set the Simulator location to a specific latitude and longitude.
20
5
  * This functionality is only available since Xcode 14.
@@ -47,3 +32,18 @@ export async function clearLocation(this: Simctl): Promise<void> {
47
32
  args: [this.requireUdid('location'), 'clear'],
48
33
  });
49
34
  }
35
+
36
+ /**
37
+ * Formats the given location argument for simctl usage
38
+ *
39
+ * @param name Argument name
40
+ * @param value Location argument value
41
+ * @returns Formatted value, for example -73.768254
42
+ */
43
+ function formatArg(name: string, value: string | number): string {
44
+ const flt = parseFloat(`${value}`);
45
+ if (isNaN(flt)) {
46
+ throw new TypeError(`${name} must be a valid number, got '${value}' instead`);
47
+ }
48
+ return flt.toFixed(7);
49
+ }
@@ -1,5 +1,5 @@
1
1
  import {rimraf} from 'rimraf';
2
- import {uuidV4} from '../helpers';
2
+ import {randomUUID} from 'node:crypto';
3
3
  import path from 'node:path';
4
4
  import os from 'node:os';
5
5
  import fs from 'node:fs/promises';
@@ -26,7 +26,7 @@ import type {Simctl} from '../simctl';
26
26
  * @throws {Error} If the `udid` instance property is unset
27
27
  */
28
28
  export async function pushNotification(this: Simctl, payload: Record<string, any>): Promise<void> {
29
- const dstPath = path.resolve(os.tmpdir(), `${await uuidV4()}.json`);
29
+ const dstPath = path.resolve(os.tmpdir(), `${randomUUID()}.json`);
30
30
  try {
31
31
  await fs.writeFile(dstPath, JSON.stringify(payload), 'utf8');
32
32
  await this.exec('push', {
@@ -1,4 +1,3 @@
1
- import _ from 'lodash';
2
1
  import {log, LOG_PREFIX} from '../logger';
3
2
  import type {Simctl} from '../simctl';
4
3
 
@@ -15,7 +14,7 @@ export async function shutdownDevice(this: Simctl): Promise<void> {
15
14
  args: [this.requireUdid('shutdown')],
16
15
  });
17
16
  } catch (e: any) {
18
- if (!_.includes(e.message, 'current state: Shutdown')) {
17
+ if (!e.message?.includes('current state: Shutdown')) {
19
18
  throw e;
20
19
  }
21
20
  log.debug(LOG_PREFIX, `Simulator already in 'Shutdown' state. Continuing`);
@@ -1,4 +1,3 @@
1
- import _ from 'lodash';
2
1
  import type {Simctl} from '../simctl';
3
2
  import type {TeenProcessExecResult, SubProcess} from 'teen_process';
4
3
 
@@ -18,12 +17,12 @@ export async function spawnProcess(
18
17
  args: string | string[],
19
18
  env: Record<string, any> = {},
20
19
  ): Promise<TeenProcessExecResult<string>> {
21
- if (_.isEmpty(args)) {
20
+ if ((Array.isArray(args) && args.length === 0) || args === '') {
22
21
  throw new Error('Spawn arguments are required');
23
22
  }
24
23
 
25
24
  return await this.exec('spawn', {
26
- args: [this.requireUdid('spawn'), ...(_.isArray(args) ? args : [args])],
25
+ args: [this.requireUdid('spawn'), ...(Array.isArray(args) ? args : [args])],
27
26
  env,
28
27
  });
29
28
  }
@@ -42,12 +41,12 @@ export async function spawnSubProcess(
42
41
  args: string | string[],
43
42
  env: Record<string, any> = {},
44
43
  ): Promise<SubProcess> {
45
- if (_.isEmpty(args)) {
44
+ if ((Array.isArray(args) && args.length === 0) || args === '') {
46
45
  throw new Error('Spawn arguments are required');
47
46
  }
48
47
 
49
48
  return (await this.exec('spawn', {
50
- args: [this.requireUdid('spawn'), ...(_.isArray(args) ? args : [args])],
49
+ args: [this.requireUdid('spawn'), ...(Array.isArray(args) ? args : [args])],
51
50
  env,
52
51
  asynchronous: true,
53
52
  })) as SubProcess;
@@ -1,4 +1,3 @@
1
- import _ from 'lodash';
2
1
  import type {Simctl} from '../simctl';
3
2
 
4
3
  /**
@@ -14,7 +13,7 @@ export async function getAppearance(this: Simctl): Promise<string> {
14
13
  const {stdout} = await this.exec('ui', {
15
14
  args: [this.requireUdid('ui'), 'appearance'],
16
15
  });
17
- return _.trim(stdout);
16
+ return stdout.trim();
18
17
  }
19
18
 
20
19
  /**
@@ -52,7 +51,7 @@ export async function getIncreaseContrast(this: Simctl): Promise<string> {
52
51
  const {stdout} = await this.exec('ui', {
53
52
  args: [this.requireUdid('ui'), 'increase_contrast'],
54
53
  });
55
- return _.trim(stdout);
54
+ return stdout.trim();
56
55
  }
57
56
 
58
57
  /**
@@ -99,7 +98,7 @@ export async function getContentSize(this: Simctl): Promise<string> {
99
98
  const {stdout} = await this.exec('ui', {
100
99
  args: [this.requireUdid('ui'), 'content_size'],
101
100
  });
102
- return _.trim(stdout);
101
+ return stdout.trim();
103
102
  }
104
103
 
105
104
  /**
package/package.json CHANGED
@@ -6,7 +6,7 @@
6
6
  "ios",
7
7
  "simctl"
8
8
  ],
9
- "version": "8.1.7",
9
+ "version": "8.2.1",
10
10
  "author": "Appium Contributors",
11
11
  "license": "Apache-2.0",
12
12
  "repository": {
@@ -33,12 +33,9 @@
33
33
  "dependencies": {
34
34
  "@appium/logger": "^2.0.0-rc.1",
35
35
  "asyncbox": "^6.0.1",
36
- "bluebird": "^3.5.1",
37
- "lodash": "^4.2.1",
38
36
  "rimraf": "^6.0.1",
39
37
  "semver": "^7.0.0",
40
38
  "teen_process": "^4.0.4",
41
- "uuid": "^13.0.0",
42
39
  "which": "^6.0.0"
43
40
  },
44
41
  "scripts": {
@@ -65,8 +62,6 @@
65
62
  "@appium/types": "^1.0.0-rc.1",
66
63
  "@semantic-release/changelog": "^6.0.1",
67
64
  "@semantic-release/git": "^10.0.1",
68
- "@types/bluebird": "^3.5.38",
69
- "@types/lodash": "^4.14.196",
70
65
  "@types/mocha": "^10.0.1",
71
66
  "@types/node": "^25.0.0",
72
67
  "appium-xcode": "^6.0.0",