node-simctl 9.0.0 → 9.1.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.
- package/CHANGELOG.md +12 -0
- package/build/lib/helpers.d.ts.map +1 -1
- package/build/lib/helpers.js +4 -2
- package/build/lib/helpers.js.map +1 -1
- package/build/lib/simctl.d.ts +2 -2
- package/build/lib/simctl.d.ts.map +1 -1
- package/build/lib/simctl.js +11 -15
- package/build/lib/simctl.js.map +1 -1
- package/build/lib/subcommands/addmedia.d.ts +1 -1
- package/build/lib/subcommands/addmedia.d.ts.map +1 -1
- package/build/lib/subcommands/addmedia.js.map +1 -1
- package/build/lib/subcommands/appinfo.d.ts.map +1 -1
- package/build/lib/subcommands/appinfo.js +4 -5
- package/build/lib/subcommands/appinfo.js.map +1 -1
- package/build/lib/subcommands/bootstatus.d.ts +1 -1
- package/build/lib/subcommands/bootstatus.d.ts.map +1 -1
- package/build/lib/subcommands/bootstatus.js +2 -2
- package/build/lib/subcommands/bootstatus.js.map +1 -1
- package/build/lib/subcommands/create.d.ts.map +1 -1
- package/build/lib/subcommands/create.js +1 -1
- package/build/lib/subcommands/create.js.map +1 -1
- package/build/lib/subcommands/erase.d.ts.map +1 -1
- package/build/lib/subcommands/erase.js.map +1 -1
- package/build/lib/subcommands/io.d.ts.map +1 -1
- package/build/lib/subcommands/io.js +3 -3
- package/build/lib/subcommands/io.js.map +1 -1
- package/build/lib/subcommands/keychain.d.ts.map +1 -1
- package/build/lib/subcommands/keychain.js +2 -2
- package/build/lib/subcommands/keychain.js.map +1 -1
- package/build/lib/subcommands/launch.d.ts.map +1 -1
- package/build/lib/subcommands/launch.js.map +1 -1
- package/build/lib/subcommands/list.d.ts.map +1 -1
- package/build/lib/subcommands/list.js.map +1 -1
- package/build/lib/subcommands/location.d.ts.map +1 -1
- package/build/lib/subcommands/location.js.map +1 -1
- package/build/lib/subcommands/openurl.d.ts +1 -1
- package/build/lib/subcommands/openurl.d.ts.map +1 -1
- package/build/lib/subcommands/openurl.js.map +1 -1
- package/build/lib/subcommands/pbcopy.d.ts.map +1 -1
- package/build/lib/subcommands/pbcopy.js.map +1 -1
- package/build/lib/subcommands/pbpaste.d.ts.map +1 -1
- package/build/lib/subcommands/pbpaste.js.map +1 -1
- package/build/lib/subcommands/privacy.d.ts.map +1 -1
- package/build/lib/subcommands/privacy.js.map +1 -1
- package/build/lib/subcommands/push.d.ts.map +1 -1
- package/build/lib/subcommands/push.js +3 -3
- package/build/lib/subcommands/push.js.map +1 -1
- package/build/lib/subcommands/spawn.d.ts +1 -1
- package/build/lib/subcommands/spawn.d.ts.map +1 -1
- package/build/lib/subcommands/spawn.js.map +1 -1
- package/build/lib/types.d.ts.map +1 -1
- package/lib/helpers.ts +5 -5
- package/lib/simctl.ts +13 -22
- package/lib/subcommands/addmedia.ts +3 -5
- package/lib/subcommands/appinfo.ts +5 -11
- package/lib/subcommands/bootstatus.ts +5 -14
- package/lib/subcommands/create.ts +3 -4
- package/lib/subcommands/erase.ts +1 -0
- package/lib/subcommands/io.ts +5 -3
- package/lib/subcommands/keychain.ts +6 -12
- package/lib/subcommands/launch.ts +2 -5
- package/lib/subcommands/list.ts +2 -9
- package/lib/subcommands/location.ts +1 -5
- package/lib/subcommands/openurl.ts +2 -1
- package/lib/subcommands/pbcopy.ts +3 -6
- package/lib/subcommands/pbpaste.ts +1 -4
- package/lib/subcommands/privacy.ts +1 -5
- package/lib/subcommands/push.ts +5 -3
- package/lib/subcommands/spawn.ts +2 -1
- package/lib/types.ts +1 -3
- package/package.json +34 -48
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../lib/subcommands/spawn.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,
|
|
1
|
+
{"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../lib/subcommands/spawn.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,qBAAqB,EAAE,UAAU,EAAC,MAAM,cAAc,CAAC;AAEpE,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AAEzC;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EACvB,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAC5B,OAAO,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CASxC;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EACvB,GAAG,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAC5B,OAAO,CAAC,UAAU,CAAC,CAUrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../../lib/subcommands/spawn.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../../lib/subcommands/spawn.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAEhC,IAAuB,EACvB,MAA2B,EAAE;IAE7B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;QAC9B,IAAI,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3E,GAAG;KACJ,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAEnC,IAAuB,EACvB,MAA2B,EAAE;IAE7B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;QAC/B,IAAI,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3E,GAAG;QACH,YAAY,EAAE,IAAI;KACnB,CAAC,CAAe,CAAC;AACpB,CAAC"}
|
package/build/lib/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAE,qBAAqB,EAAC,MAAM,cAAc,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB;;OAEG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,IAAI,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB;;;OAGG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAClC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC;IACd;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,QAAQ,IAAI,CAAC,SAAS,aAAa,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../lib/types.ts"],"names":[],"mappings":"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"}
|
package/lib/helpers.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import * as semver from 'semver';
|
|
2
1
|
import {spawn} from 'node:child_process';
|
|
3
2
|
import {Readable} from 'node:stream';
|
|
4
3
|
|
|
4
|
+
import * as semver from 'semver';
|
|
5
|
+
|
|
5
6
|
export const DEFAULT_EXEC_TIMEOUT = 10 * 60 * 1000; // ms
|
|
6
7
|
export const SIM_RUNTIME_NAME = 'com.apple.CoreSimulator.SimRuntime.';
|
|
7
8
|
|
|
@@ -61,10 +62,9 @@ export async function convertPlistToJson(plistInput: string): Promise<any> {
|
|
|
61
62
|
});
|
|
62
63
|
} catch (err) {
|
|
63
64
|
plutilProcess.kill(9);
|
|
64
|
-
throw new Error(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
);
|
|
65
|
+
throw new Error(`Failed to convert plist to JSON: ${err instanceof Error ? err.message : String(err)}`, {
|
|
66
|
+
cause: err,
|
|
67
|
+
});
|
|
68
68
|
} finally {
|
|
69
69
|
plutilProcess.removeAllListeners();
|
|
70
70
|
inputStream.removeAllListeners();
|
package/lib/simctl.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import {exec as tpExec, SubProcess} from 'teen_process';
|
|
1
2
|
import which from 'which';
|
|
2
|
-
|
|
3
|
+
|
|
3
4
|
import {DEFAULT_EXEC_TIMEOUT, getXcrunBinary} from './helpers.js';
|
|
4
|
-
import {
|
|
5
|
+
import {log, LOG_PREFIX} from './logger.js';
|
|
5
6
|
import * as addmediaCommands from './subcommands/addmedia.js';
|
|
6
7
|
import * as appinfoCommands from './subcommands/appinfo.js';
|
|
7
8
|
import * as bootCommands from './subcommands/boot.js';
|
|
@@ -10,23 +11,23 @@ import * as createCommands from './subcommands/create.js';
|
|
|
10
11
|
import * as deleteCommands from './subcommands/delete.js';
|
|
11
12
|
import * as eraseCommands from './subcommands/erase.js';
|
|
12
13
|
import * as getappcontainerCommands from './subcommands/get_app_container.js';
|
|
14
|
+
import * as envCommands from './subcommands/getenv.js';
|
|
13
15
|
import * as installCommands from './subcommands/install.js';
|
|
14
16
|
import * as ioCommands from './subcommands/io.js';
|
|
15
17
|
import * as keychainCommands from './subcommands/keychain.js';
|
|
16
18
|
import * as launchCommands from './subcommands/launch.js';
|
|
17
19
|
import * as listCommands from './subcommands/list.js';
|
|
20
|
+
import * as locationCommands from './subcommands/location.js';
|
|
18
21
|
import * as openurlCommands from './subcommands/openurl.js';
|
|
19
22
|
import * as pbcopyCommands from './subcommands/pbcopy.js';
|
|
20
23
|
import * as pbpasteCommands from './subcommands/pbpaste.js';
|
|
21
24
|
import * as privacyCommands from './subcommands/privacy.js';
|
|
22
25
|
import * as pushCommands from './subcommands/push.js';
|
|
23
|
-
import * as envCommands from './subcommands/getenv.js';
|
|
24
26
|
import * as shutdownCommands from './subcommands/shutdown.js';
|
|
25
27
|
import * as spawnCommands from './subcommands/spawn.js';
|
|
26
28
|
import * as terminateCommands from './subcommands/terminate.js';
|
|
27
29
|
import * as uiCommands from './subcommands/ui.js';
|
|
28
30
|
import * as uninstallCommands from './subcommands/uninstall.js';
|
|
29
|
-
import * as locationCommands from './subcommands/location.js';
|
|
30
31
|
import type {XCRun, ExecOpts, SimctlOpts, ExecResult} from './types.js';
|
|
31
32
|
|
|
32
33
|
const SIMCTL_ENV_PREFIX = 'SIMCTL_CHILD_';
|
|
@@ -113,8 +114,7 @@ export class Simctl {
|
|
|
113
114
|
requireUdid(commandName: string | null = null): string {
|
|
114
115
|
if (!this.udid) {
|
|
115
116
|
throw new Error(
|
|
116
|
-
`udid is required to be set for ` +
|
|
117
|
-
(commandName ? `the '${commandName}' command` : 'this simctl command'),
|
|
117
|
+
`udid is required to be set for ` + (commandName ? `the '${commandName}' command` : 'this simctl command'),
|
|
118
118
|
);
|
|
119
119
|
}
|
|
120
120
|
return this.udid;
|
|
@@ -130,10 +130,7 @@ export class Simctl {
|
|
|
130
130
|
try {
|
|
131
131
|
this.xcrun.path = await which(xcrunBinary);
|
|
132
132
|
} catch {
|
|
133
|
-
throw new Error(
|
|
134
|
-
`${xcrunBinary} tool has not been found in PATH. ` +
|
|
135
|
-
`Are Xcode developers tools installed?`,
|
|
136
|
-
);
|
|
133
|
+
throw new Error(`${xcrunBinary} tool has not been found in PATH. Are Xcode developers tools installed?`);
|
|
137
134
|
}
|
|
138
135
|
}
|
|
139
136
|
if (!this.xcrun.path) {
|
|
@@ -163,12 +160,7 @@ export class Simctl {
|
|
|
163
160
|
timeout,
|
|
164
161
|
} = opts ?? ({} as T);
|
|
165
162
|
// run a particular simctl command
|
|
166
|
-
const args = [
|
|
167
|
-
'simctl',
|
|
168
|
-
...(this.devicesSetPath ? ['--set', this.devicesSetPath] : []),
|
|
169
|
-
subcommand,
|
|
170
|
-
...initialArgs,
|
|
171
|
-
];
|
|
163
|
+
const args = ['simctl', ...(this.devicesSetPath ? ['--set', this.devicesSetPath] : []), subcommand, ...initialArgs];
|
|
172
164
|
// Prefix all passed in environment variables with 'SIMCTL_CHILD_', simctl
|
|
173
165
|
// will then pass these to the child (spawned) process.
|
|
174
166
|
const envWithPrefixedKeys = Object.fromEntries(
|
|
@@ -190,17 +182,16 @@ export class Simctl {
|
|
|
190
182
|
try {
|
|
191
183
|
let execArgs: [string, string[], any];
|
|
192
184
|
if (architectures?.length) {
|
|
193
|
-
const archArgs = (Array.isArray(architectures) ? architectures : [architectures]).flatMap(
|
|
194
|
-
|
|
195
|
-
|
|
185
|
+
const archArgs = (Array.isArray(architectures) ? architectures : [architectures]).flatMap((arch) => [
|
|
186
|
+
'-arch',
|
|
187
|
+
arch,
|
|
188
|
+
]);
|
|
196
189
|
execArgs = ['arch', [...archArgs, xcrun, ...args], execOpts];
|
|
197
190
|
} else {
|
|
198
191
|
execArgs = [xcrun, args, execOpts];
|
|
199
192
|
}
|
|
200
193
|
// We know what we are doing here - the type system can't handle the dynamic nature
|
|
201
|
-
return (
|
|
202
|
-
asynchronous ? new SubProcess(...execArgs) : await tpExec(...execArgs)
|
|
203
|
-
) as ExecResult<T>;
|
|
194
|
+
return (asynchronous ? new SubProcess(...execArgs) : await tpExec(...execArgs)) as ExecResult<T>;
|
|
204
195
|
} catch (e: any) {
|
|
205
196
|
if (!this.logErrors || !logErrors) {
|
|
206
197
|
// if we don't want to see the errors, just throw and allow the calling
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type {Simctl} from '../simctl.js';
|
|
2
1
|
import type {TeenProcessExecResult} from 'teen_process';
|
|
3
2
|
|
|
3
|
+
import type {Simctl} from '../simctl.js';
|
|
4
|
+
|
|
4
5
|
/**
|
|
5
6
|
* Add the particular media file to Simulator's library.
|
|
6
7
|
* It is required that Simulator is in _booted_ state.
|
|
@@ -12,10 +13,7 @@ import type {TeenProcessExecResult} from 'teen_process';
|
|
|
12
13
|
* returns non-zero return code.
|
|
13
14
|
* @throws {Error} If the `udid` instance property is unset
|
|
14
15
|
*/
|
|
15
|
-
export async function addMedia(
|
|
16
|
-
this: Simctl,
|
|
17
|
-
filePath: string,
|
|
18
|
-
): Promise<TeenProcessExecResult<string>> {
|
|
16
|
+
export async function addMedia(this: Simctl, filePath: string): Promise<TeenProcessExecResult<string>> {
|
|
19
17
|
return await this.exec('addmedia', {
|
|
20
18
|
args: [this.requireUdid('addmedia'), filePath],
|
|
21
19
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import {convertPlistToJson} from '../helpers.js';
|
|
1
2
|
import type {Simctl} from '../simctl.js';
|
|
2
3
|
import type {AppInfo} from '../types.js';
|
|
3
|
-
import {convertPlistToJson} from '../helpers.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Get information about an app installed on the simulator
|
|
@@ -24,19 +24,13 @@ export async function appInfo(this: Simctl, bundleId: string): Promise<AppInfo>
|
|
|
24
24
|
try {
|
|
25
25
|
result = await convertPlistToJson(stdout);
|
|
26
26
|
} catch (err) {
|
|
27
|
-
throw new Error(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
);
|
|
27
|
+
throw new Error(`Cannot retrieve app info for ${bundleId}: ${err instanceof Error ? err.message : String(err)}`, {
|
|
28
|
+
cause: err,
|
|
29
|
+
});
|
|
31
30
|
}
|
|
32
31
|
}
|
|
33
32
|
|
|
34
|
-
if (
|
|
35
|
-
!result ||
|
|
36
|
-
typeof result !== 'object' ||
|
|
37
|
-
Array.isArray(result) ||
|
|
38
|
-
!('ApplicationType' in result)
|
|
39
|
-
) {
|
|
33
|
+
if (!result || typeof result !== 'object' || Array.isArray(result) || !('ApplicationType' in result)) {
|
|
40
34
|
throw new Error(`App with bundle identifier "${bundleId}" not found. Is it installed?`);
|
|
41
35
|
}
|
|
42
36
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {log, LOG_PREFIX} from '../logger.js';
|
|
2
1
|
import {waitForCondition} from 'asyncbox';
|
|
2
|
+
import type {SubProcess} from 'teen_process';
|
|
3
|
+
|
|
4
|
+
import {log, LOG_PREFIX} from '../logger.js';
|
|
3
5
|
import type {Simctl} from '../simctl.js';
|
|
4
6
|
import type {BootMonitorOptions} from '../types.js';
|
|
5
|
-
import type {SubProcess} from 'teen_process';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Start monitoring for boot status of the particular Simulator.
|
|
@@ -16,18 +17,8 @@ import type {SubProcess} from 'teen_process';
|
|
|
16
17
|
* property is not set.
|
|
17
18
|
* @throws {Error} If the `udid` instance property is unset
|
|
18
19
|
*/
|
|
19
|
-
export async function startBootMonitor(
|
|
20
|
-
|
|
21
|
-
opts: BootMonitorOptions = {},
|
|
22
|
-
): Promise<SubProcess> {
|
|
23
|
-
const {
|
|
24
|
-
timeout = 240000,
|
|
25
|
-
onWaitingDataMigration,
|
|
26
|
-
onWaitingSystemApp,
|
|
27
|
-
onFinished,
|
|
28
|
-
onError,
|
|
29
|
-
shouldPreboot,
|
|
30
|
-
} = opts;
|
|
20
|
+
export async function startBootMonitor(this: Simctl, opts: BootMonitorOptions = {}): Promise<SubProcess> {
|
|
21
|
+
const {timeout = 240000, onWaitingDataMigration, onWaitingSystemApp, onFinished, onError, shouldPreboot} = opts;
|
|
31
22
|
const udid = this.requireUdid('bootstatus');
|
|
32
23
|
|
|
33
24
|
const status: string[] = [];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {log, LOG_PREFIX} from '../logger.js';
|
|
2
1
|
import {retryInterval} from 'asyncbox';
|
|
2
|
+
|
|
3
3
|
import {SIM_RUNTIME_NAME, normalizeVersion} from '../helpers.js';
|
|
4
|
+
import {log, LOG_PREFIX} from '../logger.js';
|
|
4
5
|
import type {Simctl} from '../simctl.js';
|
|
5
6
|
import type {SimCreationOpts} from '../types.js';
|
|
6
7
|
|
|
@@ -58,9 +59,7 @@ export async function createDevice(
|
|
|
58
59
|
// add modified versions, since modern Xcodes use this, then the bare
|
|
59
60
|
// versions, to accomodate older Xcodes
|
|
60
61
|
runtimeIds.push(
|
|
61
|
-
...potentialRuntimeIds.map(
|
|
62
|
-
(id) => `${SIM_RUNTIME_NAME}${platform}-${id.replace(/\./g, '-')}`,
|
|
63
|
-
),
|
|
62
|
+
...potentialRuntimeIds.map((id) => `${SIM_RUNTIME_NAME}${platform}-${id.replace(/\./g, '-')}`),
|
|
64
63
|
...potentialRuntimeIds,
|
|
65
64
|
);
|
|
66
65
|
}
|
package/lib/subcommands/erase.ts
CHANGED
package/lib/subcommands/io.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {rimraf} from 'rimraf';
|
|
2
1
|
import {randomUUID} from 'node:crypto';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import os from 'node:os';
|
|
5
2
|
import fs from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
|
|
6
|
+
import {rimraf} from 'rimraf';
|
|
7
|
+
|
|
6
8
|
import type {Simctl} from '../simctl.js';
|
|
7
9
|
|
|
8
10
|
/**
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import os from 'node:os';
|
|
2
|
-
import fs from 'node:fs/promises';
|
|
3
1
|
import {randomUUID} from 'node:crypto';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
+
|
|
5
6
|
import {rimraf} from 'rimraf';
|
|
7
|
+
|
|
6
8
|
import type {Simctl} from '../simctl.js';
|
|
7
9
|
import type {CertOptions} from '../types.js';
|
|
8
10
|
|
|
@@ -18,11 +20,7 @@ import type {CertOptions} from '../types.js';
|
|
|
18
20
|
* or there was an error while adding the certificate
|
|
19
21
|
* @throws {Error} If the `udid` instance property is unset
|
|
20
22
|
*/
|
|
21
|
-
export async function addRootCertificate(
|
|
22
|
-
this: Simctl,
|
|
23
|
-
cert: string | Buffer,
|
|
24
|
-
opts: CertOptions = {},
|
|
25
|
-
): Promise<void> {
|
|
23
|
+
export async function addRootCertificate(this: Simctl, cert: string | Buffer, opts: CertOptions = {}): Promise<void> {
|
|
26
24
|
const {raw = false} = opts;
|
|
27
25
|
const execMethod = async (certPath: string) =>
|
|
28
26
|
await this.exec('keychain', {
|
|
@@ -47,11 +45,7 @@ export async function addRootCertificate(
|
|
|
47
45
|
* or there was an error while adding the certificate
|
|
48
46
|
* @throws {Error} If the `udid` instance property is unset
|
|
49
47
|
*/
|
|
50
|
-
export async function addCertificate(
|
|
51
|
-
this: Simctl,
|
|
52
|
-
cert: string | Buffer,
|
|
53
|
-
opts: CertOptions = {},
|
|
54
|
-
): Promise<void> {
|
|
48
|
+
export async function addCertificate(this: Simctl, cert: string | Buffer, opts: CertOptions = {}): Promise<void> {
|
|
55
49
|
const {raw = false} = opts;
|
|
56
50
|
const execMethod = async (certPath: string) =>
|
|
57
51
|
await this.exec('keychain', {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {retryInterval} from 'asyncbox';
|
|
2
|
+
|
|
2
3
|
import type {Simctl} from '../simctl.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -15,11 +16,7 @@ import type {Simctl} from '../simctl.js';
|
|
|
15
16
|
* returns non-zero return code.
|
|
16
17
|
* @throws {Error} If the `udid` instance property is unset
|
|
17
18
|
*/
|
|
18
|
-
export async function launchApp(
|
|
19
|
-
this: Simctl,
|
|
20
|
-
bundleId: string,
|
|
21
|
-
tries: number = 5,
|
|
22
|
-
): Promise<string> {
|
|
19
|
+
export async function launchApp(this: Simctl, bundleId: string, tries: number = 5): Promise<string> {
|
|
23
20
|
const result = await retryInterval(tries, 1000, async () => {
|
|
24
21
|
const {stdout} = await this.exec('launch', {
|
|
25
22
|
args: [this.requireUdid('launch'), bundleId],
|
package/lib/subcommands/list.ts
CHANGED
|
@@ -94,11 +94,7 @@ export async function getDevicesByParsing(
|
|
|
94
94
|
* returns non-zero return code or if no matching
|
|
95
95
|
* platform version is found in the system.
|
|
96
96
|
*/
|
|
97
|
-
export async function getDevices(
|
|
98
|
-
this: Simctl,
|
|
99
|
-
forSdk: string,
|
|
100
|
-
platform?: string | null,
|
|
101
|
-
): Promise<DeviceInfo[]>;
|
|
97
|
+
export async function getDevices(this: Simctl, forSdk: string, platform?: string | null): Promise<DeviceInfo[]>;
|
|
102
98
|
export async function getDevices(
|
|
103
99
|
this: Simctl,
|
|
104
100
|
forSdk?: undefined | null,
|
|
@@ -227,10 +223,7 @@ export async function getRuntimeForPlatformVersion(
|
|
|
227
223
|
args: ['runtimes'],
|
|
228
224
|
});
|
|
229
225
|
// https://regex101.com/r/UykjQZ/1
|
|
230
|
-
const runtimeRe = new RegExp(
|
|
231
|
-
`${escapeRegExp(platform)}\\s+(\\d+\\.\\d+)\\s+\\((\\d+\\.\\d+\\.*\\d*)`,
|
|
232
|
-
'i',
|
|
233
|
-
);
|
|
226
|
+
const runtimeRe = new RegExp(`${escapeRegExp(platform)}\\s+(\\d+\\.\\d+)\\s+\\((\\d+\\.\\d+\\.*\\d*)`, 'i');
|
|
234
227
|
for (const line of stdout.split('\n')) {
|
|
235
228
|
const match = runtimeRe.exec(line);
|
|
236
229
|
if (match && match[1] === platformVersion) {
|
|
@@ -10,11 +10,7 @@ import type {Simctl} from '../simctl.js';
|
|
|
10
10
|
* returns non-zero return code.
|
|
11
11
|
* @throws {TypeError} If any of the arguments is not a valid value.
|
|
12
12
|
*/
|
|
13
|
-
export async function setLocation(
|
|
14
|
-
this: Simctl,
|
|
15
|
-
latitude: string | number,
|
|
16
|
-
longitude: string | number,
|
|
17
|
-
): Promise<void> {
|
|
13
|
+
export async function setLocation(this: Simctl, latitude: string | number, longitude: string | number): Promise<void> {
|
|
18
14
|
const lat = formatArg('latitude', latitude);
|
|
19
15
|
const lon = formatArg('longitude', longitude);
|
|
20
16
|
await this.exec('location', {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type {Simctl} from '../simctl.js';
|
|
2
1
|
import type {TeenProcessExecResult} from 'teen_process';
|
|
3
2
|
|
|
3
|
+
import type {Simctl} from '../simctl.js';
|
|
4
|
+
|
|
4
5
|
/**
|
|
5
6
|
* Open URL scheme on Simulator. iOS will automatically try
|
|
6
7
|
* to find a matching application, which supports the given scheme.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type {Simctl} from '../simctl.js';
|
|
2
1
|
import type {SubProcess} from 'teen_process';
|
|
3
2
|
|
|
3
|
+
import type {Simctl} from '../simctl.js';
|
|
4
|
+
|
|
4
5
|
/**
|
|
5
6
|
* Set the content of Simulator pasteboard.
|
|
6
7
|
* It is required that Simulator is in _booted_ state.
|
|
@@ -13,11 +14,7 @@ import type {SubProcess} from 'teen_process';
|
|
|
13
14
|
* returns non-zero return code.
|
|
14
15
|
* @throws {Error} If the `udid` instance property is unset
|
|
15
16
|
*/
|
|
16
|
-
export async function setPasteboard(
|
|
17
|
-
this: Simctl,
|
|
18
|
-
content: string,
|
|
19
|
-
encoding: BufferEncoding = 'utf8',
|
|
20
|
-
): Promise<void> {
|
|
17
|
+
export async function setPasteboard(this: Simctl, content: string, encoding: BufferEncoding = 'utf8'): Promise<void> {
|
|
21
18
|
const pbCopySubprocess = (await this.exec('pbcopy', {
|
|
22
19
|
args: [this.requireUdid('pbcopy')],
|
|
23
20
|
asynchronous: true,
|
|
@@ -12,10 +12,7 @@ import type {Simctl} from '../simctl.js';
|
|
|
12
12
|
* returns non-zero return code.
|
|
13
13
|
* @throws {Error} If the `udid` instance property is unset
|
|
14
14
|
*/
|
|
15
|
-
export async function getPasteboard(
|
|
16
|
-
this: Simctl,
|
|
17
|
-
encoding: BufferEncoding = 'utf8',
|
|
18
|
-
): Promise<string> {
|
|
15
|
+
export async function getPasteboard(this: Simctl, encoding: BufferEncoding = 'utf8'): Promise<string> {
|
|
19
16
|
const {stdout} = await this.exec('pbpaste', {
|
|
20
17
|
args: [this.requireUdid('pbpaste')],
|
|
21
18
|
encoding,
|
|
@@ -42,11 +42,7 @@ export async function grantPermission(this: Simctl, bundleId: string, perm: stri
|
|
|
42
42
|
* or there was an error while revoking the permission
|
|
43
43
|
* @throws {Error} If the `udid` instance property is unset
|
|
44
44
|
*/
|
|
45
|
-
export async function revokePermission(
|
|
46
|
-
this: Simctl,
|
|
47
|
-
bundleId: string,
|
|
48
|
-
perm: string,
|
|
49
|
-
): Promise<void> {
|
|
45
|
+
export async function revokePermission(this: Simctl, bundleId: string, perm: string): Promise<void> {
|
|
50
46
|
await this.exec('privacy', {
|
|
51
47
|
args: [this.requireUdid('privacy revoke'), 'revoke', perm, bundleId],
|
|
52
48
|
});
|
package/lib/subcommands/push.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {rimraf} from 'rimraf';
|
|
2
1
|
import {randomUUID} from 'node:crypto';
|
|
3
|
-
import path from 'node:path';
|
|
4
|
-
import os from 'node:os';
|
|
5
2
|
import fs from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
|
|
6
|
+
import {rimraf} from 'rimraf';
|
|
7
|
+
|
|
6
8
|
import type {Simctl} from '../simctl.js';
|
|
7
9
|
|
|
8
10
|
/**
|
package/lib/subcommands/spawn.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type {Simctl} from '../simctl.js';
|
|
2
1
|
import type {TeenProcessExecResult, SubProcess} from 'teen_process';
|
|
3
2
|
|
|
3
|
+
import type {Simctl} from '../simctl.js';
|
|
4
|
+
|
|
4
5
|
/**
|
|
5
6
|
* Spawn the particular process on Simulator.
|
|
6
7
|
* It is required that Simulator is in _booted_ state.
|
package/lib/types.ts
CHANGED
|
@@ -139,9 +139,7 @@ export interface SimCreationOpts {
|
|
|
139
139
|
/**
|
|
140
140
|
* Result type for exec method - either SubProcess for async or TeenProcessExecResult for sync
|
|
141
141
|
*/
|
|
142
|
-
export type ExecResult<T extends ExecOpts> = T extends AsyncExecOpts
|
|
143
|
-
? SubProcess
|
|
144
|
-
: TeenProcessExecResult<string>;
|
|
142
|
+
export type ExecResult<T extends ExecOpts> = T extends AsyncExecOpts ? SubProcess : TeenProcessExecResult<string>;
|
|
145
143
|
|
|
146
144
|
/**
|
|
147
145
|
* Boot monitor options
|
package/package.json
CHANGED
|
@@ -1,26 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-simctl",
|
|
3
|
+
"version": "9.1.1",
|
|
3
4
|
"description": "Wrapper around Apple's simctl binary",
|
|
4
|
-
"
|
|
5
|
+
"keywords": [
|
|
5
6
|
"apple",
|
|
6
7
|
"ios",
|
|
7
8
|
"simctl"
|
|
8
9
|
],
|
|
9
|
-
"
|
|
10
|
-
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/appium/node-simctl/issues"
|
|
12
|
+
},
|
|
11
13
|
"license": "Apache-2.0",
|
|
14
|
+
"author": "Appium Contributors",
|
|
12
15
|
"repository": {
|
|
13
16
|
"type": "git",
|
|
14
17
|
"url": "https://github.com/appium/node-simctl.git"
|
|
15
18
|
},
|
|
16
|
-
"bugs": {
|
|
17
|
-
"url": "https://github.com/appium/node-simctl/issues"
|
|
18
|
-
},
|
|
19
|
-
"engines": {
|
|
20
|
-
"node": "^20.19.0 || ^22.12.0 || >=24.0.0",
|
|
21
|
-
"npm": ">=10"
|
|
22
|
-
},
|
|
23
|
-
"main": "./build/lib/index.js",
|
|
24
19
|
"bin": {},
|
|
25
20
|
"directories": {
|
|
26
21
|
"lib": "./lib"
|
|
@@ -30,60 +25,51 @@
|
|
|
30
25
|
"build/lib",
|
|
31
26
|
"CHANGELOG.md"
|
|
32
27
|
],
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
28
|
+
"type": "module",
|
|
29
|
+
"main": "./build/lib/index.js",
|
|
30
|
+
"types": "./build/lib/index.d.ts",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./build/lib/index.d.ts",
|
|
34
|
+
"import": "./build/lib/index.js"
|
|
35
|
+
},
|
|
36
|
+
"./package.json": "./package.json"
|
|
40
37
|
},
|
|
41
38
|
"scripts": {
|
|
42
39
|
"build": "tsc -b",
|
|
43
40
|
"clean": "npm run build -- --clean",
|
|
44
41
|
"rebuild": "npm run clean; npm run build",
|
|
45
42
|
"dev": "npm run build -- --watch",
|
|
46
|
-
"lint": "
|
|
47
|
-
"lint:fix": "
|
|
48
|
-
"format": "
|
|
49
|
-
"format:check": "
|
|
43
|
+
"lint": "oxlint -c oxlint.config.mjs .",
|
|
44
|
+
"lint:fix": "oxlint -c oxlint.config.mjs --fix .",
|
|
45
|
+
"format": "oxfmt -c oxfmt.config.mjs .",
|
|
46
|
+
"format:check": "oxfmt -c oxfmt.config.mjs --check .",
|
|
50
47
|
"prepare": "npm run build",
|
|
51
48
|
"test": "node --enable-source-maps --test --test-timeout=60000 \"./build/test/unit/**/*.spec.js\"",
|
|
52
49
|
"e2e-test": "node --enable-source-maps --test --test-force-exit --test-concurrency=1 --test-timeout=300000 \"./build/test/e2e/**/*.spec.js\""
|
|
53
50
|
},
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@appium/logger": "^2.0.0-rc.1",
|
|
53
|
+
"asyncbox": "^6.0.1",
|
|
54
|
+
"rimraf": "^6.0.1",
|
|
55
|
+
"semver": "^7.0.0",
|
|
56
|
+
"teen_process": "^4.0.4",
|
|
57
|
+
"which": "^6.0.0"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@appium/
|
|
61
|
-
"@appium/
|
|
60
|
+
"@appium/oxc-config": "^1.1.0",
|
|
61
|
+
"@appium/semantic-release-config": "^1.1.0",
|
|
62
|
+
"@appium/tsconfig": "^1.2.0",
|
|
62
63
|
"@appium/types": "^1.0.0-rc.1",
|
|
63
|
-
"@semantic-release/changelog": "^6.0.1",
|
|
64
|
-
"@semantic-release/git": "^10.0.1",
|
|
65
|
-
"@types/chai": "^5.2.3",
|
|
66
|
-
"@types/chai-as-promised": "^8.0.2",
|
|
67
64
|
"@types/node": "^26.0.0",
|
|
68
65
|
"@types/semver": "^7.7.1",
|
|
69
66
|
"@types/sinon": "^22.0.0",
|
|
70
67
|
"@types/which": "^3.0.4",
|
|
71
|
-
"appium-xcode": "^
|
|
72
|
-
"
|
|
73
|
-
"chai-as-promised": "^8.0.0",
|
|
74
|
-
"conventional-changelog-conventionalcommits": "^9.3.1",
|
|
75
|
-
"prettier": "^3.0.0",
|
|
76
|
-
"semantic-release": "^25.0.2",
|
|
77
|
-
"sinon": "^22.0.0",
|
|
78
|
-
"typescript": "^6.0.2"
|
|
68
|
+
"appium-xcode": "^7.0.0",
|
|
69
|
+
"sinon": "^22.0.0"
|
|
79
70
|
},
|
|
80
|
-
"
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
".": {
|
|
84
|
-
"types": "./build/lib/index.d.ts",
|
|
85
|
-
"import": "./build/lib/index.js"
|
|
86
|
-
},
|
|
87
|
-
"./package.json": "./package.json"
|
|
71
|
+
"engines": {
|
|
72
|
+
"node": "^20.19.0 || ^22.12.0 || >=24.0.0",
|
|
73
|
+
"npm": ">=10"
|
|
88
74
|
}
|
|
89
75
|
}
|