appium-adb 14.0.5 → 14.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/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## [14.0.6](https://github.com/appium/appium-adb/compare/v14.0.5...v14.0.6) (2025-12-05)
2
+
3
+ ### Miscellaneous Chores
4
+
5
+ * Migrate apk-utils and device-settings to typescript ([#844](https://github.com/appium/appium-adb/issues/844)) ([d5bd207](https://github.com/appium/appium-adb/commit/d5bd20751e1f69b1f54db173241d42a55ffb596c))
6
+
1
7
  ## [14.0.5](https://github.com/appium/appium-adb/compare/v14.0.4...v14.0.5) (2025-12-04)
2
8
 
3
9
  ### Miscellaneous Chores
@@ -1,122 +1,99 @@
1
+ import type { ADB } from '../adb.js';
2
+ import type { UninstallOptions, ShellExecOptions, CachingOptions, InstallOptions, InstallOrUpgradeOptions, InstallOrUpgradeResult, ApkStrings, AppInfo, InstallState, StringRecord } from './types.js';
3
+ export declare const REMOTE_CACHE_ROOT = "/data/local/tmp/appium_cache";
1
4
  /**
2
5
  * Uninstall the given package from the device under test.
3
6
  *
4
- * @this {import('../adb.js').ADB}
5
- * @param {string} pkg - The name of the package to be uninstalled.
6
- * @param {import('./types').UninstallOptions} [options={}] - The set of uninstall options.
7
- * @return {Promise<boolean>} True if the package was found on the device and
7
+ * @param pkg - The name of the package to be uninstalled.
8
+ * @param options - The set of uninstall options.
9
+ * @returns True if the package was found on the device and
8
10
  * successfully uninstalled.
9
11
  */
10
- export function uninstallApk(this: import("../adb.js").ADB, pkg: string, options?: import("./types").UninstallOptions): Promise<boolean>;
12
+ export declare function uninstallApk(this: ADB, pkg: string, options?: UninstallOptions): Promise<boolean>;
11
13
  /**
12
14
  * Install the package after it was pushed to the device under test.
13
15
  *
14
- * @this {import('../adb.js').ADB}
15
- * @param {string} apkPathOnDevice - The full path to the package on the device file system.
16
- * @param {import('./types').ShellExecOptions} [opts={}] Additional exec options.
17
- * @throws {error} If there was a failure during application install.
16
+ * @param apkPathOnDevice - The full path to the package on the device file system.
17
+ * @param opts - Additional exec options.
18
+ * @throws If there was a failure during application install.
18
19
  */
19
- export function installFromDevicePath(this: import("../adb.js").ADB, apkPathOnDevice: string, opts?: import("./types").ShellExecOptions): Promise<void>;
20
+ export declare function installFromDevicePath(this: ADB, apkPathOnDevice: string, opts?: ShellExecOptions): Promise<void>;
20
21
  /**
21
22
  * Caches the given APK at a remote location to speed up further APK deployments.
22
23
  *
23
- * @this {import('../adb.js').ADB}
24
- * @param {string} apkPath - Full path to the apk on the local FS
25
- * @param {import('./types').CachingOptions} [options={}] - Caching options
26
- * @returns {Promise<string>} - Full path to the cached apk on the remote file system
27
- * @throws {Error} if there was a failure while caching the app
24
+ * @param apkPath - Full path to the apk on the local FS
25
+ * @param options - Caching options
26
+ * @returns Full path to the cached apk on the remote file system
27
+ * @throws if there was a failure while caching the app
28
28
  */
29
- export function cacheApk(this: import("../adb.js").ADB, apkPath: string, options?: import("./types").CachingOptions): Promise<string>;
30
- export class cacheApk {
31
- /**
32
- * Caches the given APK at a remote location to speed up further APK deployments.
33
- *
34
- * @this {import('../adb.js').ADB}
35
- * @param {string} apkPath - Full path to the apk on the local FS
36
- * @param {import('./types').CachingOptions} [options={}] - Caching options
37
- * @returns {Promise<string>} - Full path to the cached apk on the remote file system
38
- * @throws {Error} if there was a failure while caching the app
39
- */
40
- constructor(this: import("../adb.js").ADB, apkPath: string, options?: import("./types").CachingOptions);
41
- _areExtendedLsOptionsSupported: boolean | undefined;
42
- remoteAppsCache: LRUCache<string, string, unknown>;
43
- }
29
+ export declare function cacheApk(this: ADB, apkPath: string, options?: CachingOptions): Promise<string>;
44
30
  /**
45
31
  * Install the package from the local file system.
46
32
  *
47
- * @this {import('../adb.js').ADB}
48
- * @param {string} appPath - The full path to the local package.
49
- * @param {import('./types').InstallOptions} [options={}] - The set of installation options.
50
- * @throws {Error} If an unexpected error happens during install.
33
+ * @param appPath - The full path to the local package.
34
+ * @param options - The set of installation options.
35
+ * @throws If an unexpected error happens during install.
51
36
  */
52
- export function install(this: import("../adb.js").ADB, appPath: string, options?: import("./types").InstallOptions): Promise<void>;
37
+ export declare function install(this: ADB, appPath: string, options?: InstallOptions): Promise<void>;
53
38
  /**
54
39
  * Retrieves the current installation state of the particular application
55
40
  *
56
- * @this {import('../adb.js').ADB}
57
- * @param {string} appPath - Full path to the application
58
- * @param {string?} [pkg=null] - Package identifier. If omitted then the script will
41
+ * @param appPath - Full path to the application
42
+ * @param pkg - Package identifier. If omitted then the script will
59
43
  * try to extract it on its own
60
- * @returns {Promise<import('./types').InstallState>} One of `APP_INSTALL_STATE` constants
44
+ * @returns One of `APP_INSTALL_STATE` constants
61
45
  */
62
- export function getApplicationInstallState(this: import("../adb.js").ADB, appPath: string, pkg?: string | null): Promise<import("./types").InstallState>;
46
+ export declare function getApplicationInstallState(this: ADB, appPath: string, pkg?: string | null): Promise<InstallState>;
63
47
  /**
64
48
  * Install the package from the local file system or upgrade it if an older
65
49
  * version of the same package is already installed.
66
50
  *
67
- * @this {import('../adb.js').ADB}
68
- * @param {string} appPath - The full path to the local package.
69
- * @param {string?} [pkg=null] - The name of the installed package. The method will
51
+ * @param appPath - The full path to the local package.
52
+ * @param pkg - The name of the installed package. The method will
70
53
  * perform faster if it is set.
71
- * @param {import('./types').InstallOrUpgradeOptions} [options={}] - Set of install options.
72
- * @throws {Error} If an unexpected error happens during install.
73
- * @returns {Promise<import('./types').InstallOrUpgradeResult>}
54
+ * @param options - Set of install options.
55
+ * @throws If an unexpected error happens during install.
74
56
  */
75
- export function installOrUpgrade(this: import("../adb.js").ADB, appPath: string, pkg?: string | null, options?: import("./types").InstallOrUpgradeOptions): Promise<import("./types").InstallOrUpgradeResult>;
57
+ export declare function installOrUpgrade(this: ADB, appPath: string, pkg?: string | null, options?: InstallOrUpgradeOptions): Promise<InstallOrUpgradeResult>;
76
58
  /**
77
59
  * Extract string resources from the given package on local file system.
78
60
  *
79
- * @this {import('../adb.js').ADB}
80
- * @param {string} appPath - The full path to the .apk(s) package.
81
- * @param {string?} [language=null] - The name of the language to extract the resources for.
61
+ * @param appPath - The full path to the .apk(s) package.
62
+ * @param language - The name of the language to extract the resources for.
82
63
  * The default language is used if this equals to `null`
83
- * @param {string?} [outRoot=null] - The name of the destination folder on the local file system to
64
+ * @param outRoot - The name of the destination folder on the local file system to
84
65
  * store the extracted file to. If not provided then the `localPath` property in the returned object
85
66
  * will be undefined.
86
- * @return {Promise<import('./types').ApkStrings>}
87
67
  */
88
- export function extractStringsFromApk(this: import("../adb.js").ADB, appPath: string, language?: string | null, outRoot?: string | null): Promise<import("./types").ApkStrings>;
68
+ export declare function extractStringsFromApk(this: ADB, appPath: string, language?: string | null, outRoot?: string | null): Promise<ApkStrings>;
89
69
  /**
90
70
  * Get the package info from local apk file.
91
71
  *
92
- * @this {import('../adb.js').ADB}
93
- * @param {string} appPath - The full path to existing .apk(s) package on the local
72
+ * @param appPath - The full path to existing .apk(s) package on the local
94
73
  * file system.
95
- * @return {Promise<import('./types').AppInfo|{}>} The parsed application information.
74
+ * @returns The parsed application information.
96
75
  */
97
- export function getApkInfo(this: import("../adb.js").ADB, appPath: string): Promise<import("./types").AppInfo | {}>;
76
+ export declare function getApkInfo(this: ADB, appPath: string): Promise<AppInfo | {}>;
98
77
  /**
99
78
  * Parses apk strings from aapt2 tool output
100
79
  *
101
- * @param {string} rawOutput The actual tool output
102
- * @param {string} configMarker The config marker. Usually
80
+ * @param rawOutput The actual tool output
81
+ * @param configMarker The config marker. Usually
103
82
  * a language abbreviation or an empty string for the default one
104
- * @returns {Object} Strings ids to values mapping. Plural
83
+ * @returns Strings ids to values mapping. Plural
105
84
  * values are represented as arrays. If no config found for the
106
85
  * given marker then an empty mapping is returned.
107
86
  */
108
- export function parseAapt2Strings(rawOutput: string, configMarker: string): any;
87
+ export declare function parseAapt2Strings(rawOutput: string, configMarker: string): StringRecord;
109
88
  /**
110
89
  * Parses apk strings from aapt tool output
111
90
  *
112
- * @param {string} rawOutput The actual tool output
113
- * @param {string} configMarker The config marker. Usually
91
+ * @param rawOutput The actual tool output
92
+ * @param configMarker The config marker. Usually
114
93
  * a language abbreviation or `(default)`
115
- * @returns {Object} Strings ids to values mapping. Plural
94
+ * @returns Strings ids to values mapping. Plural
116
95
  * values are represented as arrays. If no config found for the
117
96
  * given marker then an empty mapping is returned.
118
97
  */
119
- export function parseAaptStrings(rawOutput: string, configMarker: string): any;
120
- export const REMOTE_CACHE_ROOT: "/data/local/tmp/appium_cache";
121
- import { LRUCache } from 'lru-cache';
98
+ export declare function parseAaptStrings(rawOutput: string, configMarker: string): StringRecord;
122
99
  //# sourceMappingURL=apk-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"apk-utils.d.ts","sourceRoot":"","sources":["../../../lib/tools/apk-utils.js"],"names":[],"mappings":"AAgBA;;;;;;;;GAQG;AACH,iEALW,MAAM,YACN,OAAO,SAAS,EAAE,gBAAgB,GACjC,OAAO,CAAC,OAAO,CAAC,CA8B3B;AAED;;;;;;;GAOG;AACH,sFAJW,MAAM,SACN,OAAO,SAAS,EAAE,gBAAgB,iBAQ5C;AAED;;;;;;;;GAQG;AACH,iEALW,MAAM,YACN,OAAO,SAAS,EAAE,cAAc,GAC9B,OAAO,CAAC,MAAM,CAAC,CA+E3B;;IArFD;;;;;;;;OAQG;IACH,oDALW,MAAM,YACN,OAAO,SAAS,EAAE,cAAc,EAgF1C;IA3DK,oDAA2C;IAmC7C,mDAEE;;AAwBN;;;;;;;GAOG;AACH,gEAJW,MAAM,YACN,OAAO,SAAS,EAAE,cAAc,iBAmG1C;AAED;;;;;;;;GAQG;AACH,mFALW,MAAM,QACN,MAAM,OAAC,GAEL,OAAO,CAAC,OAAO,SAAS,EAAE,YAAY,CAAC,CAiEnD;AAED;;;;;;;;;;;GAWG;AACH,yEAPW,MAAM,QACN,MAAM,OAAC,YAEP,OAAO,SAAS,EAAE,uBAAuB,GAEvC,OAAO,CAAC,OAAO,SAAS,EAAE,sBAAsB,CAAC,CAyE7D;AAED;;;;;;;;;;;GAWG;AACH,8EARW,MAAM,aACN,MAAM,OAAC,YAEP,MAAM,OAAC,GAGN,OAAO,CAAC,OAAO,SAAS,EAAE,UAAU,CAAC,CAqEhD;AAED;;;;;;;GAOG;AACH,mEAJW,MAAM,GAEL,OAAO,CAAC,OAAO,SAAS,EAAE,OAAO,GAAC,EAAE,CAAC,CAsBhD;AAiCD;;;;;;;;;GASG;AACH,6CAPW,MAAM,gBACN,MAAM,OA8GhB;AAED;;;;;;;;;GASG;AACH,4CAPW,MAAM,gBACN,MAAM,OA0EhB;AAvuBD,gCAAiC,8BAA8B,CAAC;yBAFvC,WAAW"}
1
+ {"version":3,"file":"apk-utils.d.ts","sourceRoot":"","sources":["../../../lib/tools/apk-utils.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,uBAAuB,EACvB,sBAAsB,EACtB,UAAU,EACV,OAAO,EACP,YAAY,EACZ,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,iBAAiB,iCAAiC,CAAC;AAEhE;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,CA4B5G;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAAE,IAAI,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,EAAE,IAAI,GAAE,gBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAK3H;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CA8EzG;AAED;;;;;;GAMG;AACH,wBAAsB,OAAO,CAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkGtG;AAED;;;;;;;GAOG;AACH,wBAAsB,0BAA0B,CAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,GAAG,IAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CA8D9H;AAED;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,GAAG,IAAW,EAAE,OAAO,GAAE,uBAA4B,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAwErK;AAED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,GAAG,EACT,OAAO,EAAE,MAAM,EACf,QAAQ,GAAE,MAAM,GAAG,IAAW,EAC9B,OAAO,GAAE,MAAM,GAAG,IAAW,GAC5B,OAAO,CAAC,UAAU,CAAC,CAiErB;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,EAAE,CAAC,CAqBnF;AAiCD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,YAAY,CAwGxF;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,YAAY,CAoEvF"}
@@ -60,10 +60,9 @@ exports.REMOTE_CACHE_ROOT = '/data/local/tmp/appium_cache';
60
60
  /**
61
61
  * Uninstall the given package from the device under test.
62
62
  *
63
- * @this {import('../adb.js').ADB}
64
- * @param {string} pkg - The name of the package to be uninstalled.
65
- * @param {import('./types').UninstallOptions} [options={}] - The set of uninstall options.
66
- * @return {Promise<boolean>} True if the package was found on the device and
63
+ * @param pkg - The name of the package to be uninstalled.
64
+ * @param options - The set of uninstall options.
65
+ * @returns True if the package was found on the device and
67
66
  * successfully uninstalled.
68
67
  */
69
68
  async function uninstallApk(pkg, options = {}) {
@@ -83,7 +82,8 @@ async function uninstallApk(pkg, options = {}) {
83
82
  stdout = (await this.adbExec(cmd, { timeout: options.timeout })).trim();
84
83
  }
85
84
  catch (e) {
86
- throw new Error(`Unable to uninstall APK. Original error: ${e.message}`);
85
+ const err = e;
86
+ throw new Error(`Unable to uninstall APK. Original error: ${err.message}`);
87
87
  }
88
88
  logger_js_1.log.debug(`'adb ${cmd.join(' ')}' command output: ${stdout}`);
89
89
  if (stdout.includes('Success')) {
@@ -96,13 +96,12 @@ async function uninstallApk(pkg, options = {}) {
96
96
  /**
97
97
  * Install the package after it was pushed to the device under test.
98
98
  *
99
- * @this {import('../adb.js').ADB}
100
- * @param {string} apkPathOnDevice - The full path to the package on the device file system.
101
- * @param {import('./types').ShellExecOptions} [opts={}] Additional exec options.
102
- * @throws {error} If there was a failure during application install.
99
+ * @param apkPathOnDevice - The full path to the package on the device file system.
100
+ * @param opts - Additional exec options.
101
+ * @throws If there was a failure during application install.
103
102
  */
104
103
  async function installFromDevicePath(apkPathOnDevice, opts = {}) {
105
- const stdout = /** @type {string} */ (await this.shell(['pm', 'install', '-r', apkPathOnDevice], opts));
104
+ const stdout = await this.shell(['pm', 'install', '-r', apkPathOnDevice], opts);
106
105
  if (stdout.includes('Failure')) {
107
106
  throw new Error(`Remote install failed: ${stdout}`);
108
107
  }
@@ -110,11 +109,10 @@ async function installFromDevicePath(apkPathOnDevice, opts = {}) {
110
109
  /**
111
110
  * Caches the given APK at a remote location to speed up further APK deployments.
112
111
  *
113
- * @this {import('../adb.js').ADB}
114
- * @param {string} apkPath - Full path to the apk on the local FS
115
- * @param {import('./types').CachingOptions} [options={}] - Caching options
116
- * @returns {Promise<string>} - Full path to the cached apk on the remote file system
117
- * @throws {Error} if there was a failure while caching the app
112
+ * @param apkPath - Full path to the apk on the local FS
113
+ * @param options - Caching options
114
+ * @returns Full path to the cached apk on the remote file system
115
+ * @throws if there was a failure while caching the app
118
116
  */
119
117
  async function cacheApk(apkPath, options = {}) {
120
118
  const appHash = await support_1.fs.hash(apkPath);
@@ -146,7 +144,8 @@ async function cacheApk(apkPath, options = {}) {
146
144
  .filter(Boolean)));
147
145
  }
148
146
  catch (e) {
149
- logger_js_1.log.debug(`Got an error '${e.message.trim()}' while getting the list of files in the cache. ` +
147
+ const err = e;
148
+ logger_js_1.log.debug(`Got an error '${err.message.trim()}' while getting the list of files in the cache. ` +
150
149
  `Assuming the cache does not exist yet`);
151
150
  await this.shell(['mkdir', '-p', exports.REMOTE_CACHE_ROOT]);
152
151
  }
@@ -170,27 +169,28 @@ async function cacheApk(apkPath, options = {}) {
170
169
  }
171
170
  if (!this.remoteAppsCache) {
172
171
  this.remoteAppsCache = new lru_cache_1.LRUCache({
173
- max: /** @type {number} */ (this.remoteAppsCacheLimit),
172
+ max: this.remoteAppsCacheLimit,
174
173
  });
175
174
  }
176
175
  // Cleanup the invalid entries from the cache
177
176
  lodash_1.default.difference([...this.remoteAppsCache.keys()], remoteCachedFiles.map(toHash))
178
- .forEach((hash) => ( /** @type {LRUCache} */(this.remoteAppsCache)).delete(hash));
177
+ .forEach((hash) => this.remoteAppsCache.delete(hash));
179
178
  // Bump the cache record for the recently cached item
180
179
  this.remoteAppsCache.set(appHash, remotePath);
181
180
  // If the remote cache exceeds this.remoteAppsCacheLimit, remove the least recently used entries
182
181
  const entriesToCleanup = remoteCachedFiles
183
182
  .map((x) => path_1.default.posix.join(exports.REMOTE_CACHE_ROOT, x))
184
- .filter((x) => !( /** @type {LRUCache} */(this.remoteAppsCache)).has(toHash(x)))
185
- .slice(( /** @type {number} */(this.remoteAppsCacheLimit)) - [...this.remoteAppsCache.keys()].length);
183
+ .filter((x) => !this.remoteAppsCache.has(toHash(x)))
184
+ .slice(this.remoteAppsCacheLimit - [...this.remoteAppsCache.keys()].length);
186
185
  if (!lodash_1.default.isEmpty(entriesToCleanup)) {
187
186
  try {
188
187
  await this.shell(['rm', '-f', ...entriesToCleanup]);
189
188
  logger_js_1.log.debug(`Deleted ${entriesToCleanup.length} expired application cache entries`);
190
189
  }
191
190
  catch (e) {
191
+ const err = e;
192
192
  logger_js_1.log.warn(`Cannot delete ${entriesToCleanup.length} expired application cache entries. ` +
193
- `Original error: ${e.message}`);
193
+ `Original error: ${err.message}`);
194
194
  }
195
195
  }
196
196
  return remotePath;
@@ -198,10 +198,9 @@ async function cacheApk(apkPath, options = {}) {
198
198
  /**
199
199
  * Install the package from the local file system.
200
200
  *
201
- * @this {import('../adb.js').ADB}
202
- * @param {string} appPath - The full path to the local package.
203
- * @param {import('./types').InstallOptions} [options={}] - The set of installation options.
204
- * @throws {Error} If an unexpected error happens during install.
201
+ * @param appPath - The full path to the local package.
202
+ * @param options - The set of installation options.
203
+ * @throws If an unexpected error happens during install.
205
204
  */
206
205
  async function install(appPath, options = {}) {
207
206
  if (appPath.endsWith(helpers_js_1.APKS_EXTENSION)) {
@@ -230,7 +229,7 @@ async function install(appPath, options = {}) {
230
229
  ];
231
230
  let performAppInstall = async () => await this.adbExec(installCmd, installOpts);
232
231
  // this.remoteAppsCacheLimit <= 0 means no caching should be applied
233
- let shouldCacheApp = ( /** @type {number} */(this.remoteAppsCacheLimit)) > 0;
232
+ let shouldCacheApp = this.remoteAppsCacheLimit > 0;
234
233
  if (shouldCacheApp) {
235
234
  shouldCacheApp = !(await this.isStreamedInstallSupported());
236
235
  if (!shouldCacheApp) {
@@ -269,15 +268,16 @@ async function install(appPath, options = {}) {
269
268
  };
270
269
  }
271
270
  catch (e) {
272
- logger_js_1.log.debug(e);
273
- logger_js_1.log.warn(`There was a failure while caching '${appPath}': ${e.message}`);
271
+ const err = e;
272
+ logger_js_1.log.debug(err);
273
+ logger_js_1.log.warn(`There was a failure while caching '${appPath}': ${err.message}`);
274
274
  logger_js_1.log.warn('Falling back to the default installation procedure');
275
275
  await clearCache();
276
276
  }
277
277
  }
278
278
  try {
279
279
  const timer = new support_1.timing.Timer().start();
280
- const output = /** @type {string} */ (await performAppInstall());
280
+ const output = await performAppInstall();
281
281
  logger_js_1.log.info(`The installation of '${path_1.default.basename(appPath)}' took ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`);
282
282
  const truncatedOutput = (!lodash_1.default.isString(output) || output.length <= 300) ?
283
283
  output : `${output.substring(0, 150)}...${output.substring(output.length - 150)}`;
@@ -292,10 +292,11 @@ async function install(appPath, options = {}) {
292
292
  }
293
293
  }
294
294
  catch (err) {
295
+ const error = err;
295
296
  // on some systems this will throw an error if the app already
296
297
  // exists
297
- if (!err.message.includes('INSTALL_FAILED_ALREADY_EXISTS')) {
298
- throw err;
298
+ if (!error.message.includes('INSTALL_FAILED_ALREADY_EXISTS')) {
299
+ throw error;
299
300
  }
300
301
  logger_js_1.log.debug(`Application '${appPath}' already installed. Continuing.`);
301
302
  }
@@ -303,18 +304,16 @@ async function install(appPath, options = {}) {
303
304
  /**
304
305
  * Retrieves the current installation state of the particular application
305
306
  *
306
- * @this {import('../adb.js').ADB}
307
- * @param {string} appPath - Full path to the application
308
- * @param {string?} [pkg=null] - Package identifier. If omitted then the script will
307
+ * @param appPath - Full path to the application
308
+ * @param pkg - Package identifier. If omitted then the script will
309
309
  * try to extract it on its own
310
- * @returns {Promise<import('./types').InstallState>} One of `APP_INSTALL_STATE` constants
310
+ * @returns One of `APP_INSTALL_STATE` constants
311
311
  */
312
312
  async function getApplicationInstallState(appPath, pkg = null) {
313
313
  let apkInfo = null;
314
314
  if (!pkg) {
315
- apkInfo = await this.getApkInfo(appPath);
316
- // @ts-ignore We are ok if this prop does not exist
317
- pkg = apkInfo.name;
315
+ apkInfo = (await this.getApkInfo(appPath));
316
+ pkg = apkInfo?.name;
318
317
  }
319
318
  if (!pkg) {
320
319
  logger_js_1.log.warn(`Cannot read the package name of '${appPath}'`);
@@ -327,10 +326,10 @@ async function getApplicationInstallState(appPath, pkg = null) {
327
326
  }
328
327
  const pkgVersionName = semver.valid(semver.coerce(pkgVersionNameStr));
329
328
  if (!apkInfo) {
330
- apkInfo = await this.getApkInfo(appPath);
329
+ apkInfo = (await this.getApkInfo(appPath));
331
330
  }
332
331
  // @ts-ignore We validate the values below
333
- const { versionCode: apkVersionCode, versionName: apkVersionNameStr } = apkInfo;
332
+ const { versionCode: apkVersionCode, versionName: apkVersionNameStr } = apkInfo || {};
334
333
  const apkVersionName = semver.valid(semver.coerce(apkVersionNameStr));
335
334
  if (!lodash_1.default.isInteger(apkVersionCode) || !lodash_1.default.isInteger(pkgVersionCode)) {
336
335
  logger_js_1.log.warn(`Cannot read version codes of '${appPath}' and/or '${pkg}'`);
@@ -340,7 +339,7 @@ async function getApplicationInstallState(appPath, pkg = null) {
340
339
  }
341
340
  }
342
341
  if (lodash_1.default.isInteger(apkVersionCode) && lodash_1.default.isInteger(pkgVersionCode)) {
343
- if (( /** @type {number} */(pkgVersionCode)) > apkVersionCode) {
342
+ if (pkgVersionCode > apkVersionCode) {
344
343
  logger_js_1.log.debug(`The version code of the installed '${pkg}' is greater than the application version code (${pkgVersionCode} > ${apkVersionCode})`);
345
344
  return this.APP_INSTALL_STATE.NEWER_VERSION_INSTALLED;
346
345
  }
@@ -371,13 +370,11 @@ async function getApplicationInstallState(appPath, pkg = null) {
371
370
  * Install the package from the local file system or upgrade it if an older
372
371
  * version of the same package is already installed.
373
372
  *
374
- * @this {import('../adb.js').ADB}
375
- * @param {string} appPath - The full path to the local package.
376
- * @param {string?} [pkg=null] - The name of the installed package. The method will
373
+ * @param appPath - The full path to the local package.
374
+ * @param pkg - The name of the installed package. The method will
377
375
  * perform faster if it is set.
378
- * @param {import('./types').InstallOrUpgradeOptions} [options={}] - Set of install options.
379
- * @throws {Error} If an unexpected error happens during install.
380
- * @returns {Promise<import('./types').InstallOrUpgradeResult>}
376
+ * @param options - Set of install options.
377
+ * @throws If an unexpected error happens during install.
381
378
  */
382
379
  async function installOrUpgrade(appPath, pkg = null, options = {}) {
383
380
  if (!pkg) {
@@ -394,7 +391,7 @@ async function installOrUpgrade(appPath, pkg = null, options = {}) {
394
391
  const appState = await this.getApplicationInstallState(appPath, pkg);
395
392
  let wasUninstalled = false;
396
393
  const uninstallPackage = async () => {
397
- if (!await this.uninstallApk(/** @type {string} */ (pkg), { skipInstallCheck: true })) {
394
+ if (!await this.uninstallApk(pkg, { skipInstallCheck: true })) {
398
395
  throw new Error(`'${pkg}' package cannot be uninstalled`);
399
396
  }
400
397
  wasUninstalled = true;
@@ -438,7 +435,8 @@ async function installOrUpgrade(appPath, pkg = null, options = {}) {
438
435
  await this.install(appPath, { ...options, replace: true });
439
436
  }
440
437
  catch (err) {
441
- logger_js_1.log.warn(`Cannot install/upgrade '${pkg}' because of '${err.message}'. Trying full reinstall`);
438
+ const error = err;
439
+ logger_js_1.log.warn(`Cannot install/upgrade '${pkg}' because of '${error.message}'. Trying full reinstall`);
442
440
  await uninstallPackage();
443
441
  await this.install(appPath, { ...options, replace: false });
444
442
  }
@@ -450,14 +448,12 @@ async function installOrUpgrade(appPath, pkg = null, options = {}) {
450
448
  /**
451
449
  * Extract string resources from the given package on local file system.
452
450
  *
453
- * @this {import('../adb.js').ADB}
454
- * @param {string} appPath - The full path to the .apk(s) package.
455
- * @param {string?} [language=null] - The name of the language to extract the resources for.
451
+ * @param appPath - The full path to the .apk(s) package.
452
+ * @param language - The name of the language to extract the resources for.
456
453
  * The default language is used if this equals to `null`
457
- * @param {string?} [outRoot=null] - The name of the destination folder on the local file system to
454
+ * @param outRoot - The name of the destination folder on the local file system to
458
455
  * store the extracted file to. If not provided then the `localPath` property in the returned object
459
456
  * will be undefined.
460
- * @return {Promise<import('./types').ApkStrings>}
461
457
  */
462
458
  async function extractStringsFromApk(appPath, language = null, outRoot = null) {
463
459
  logger_js_1.log.debug(`Extracting strings from for language: ${language || 'default'}`);
@@ -470,35 +466,37 @@ async function extractStringsFromApk(appPath, language = null, outRoot = null) {
470
466
  try {
471
467
  await this.initAapt();
472
468
  configMarker = await formatConfigMarker(async () => {
473
- const { stdout } = await (0, teen_process_1.exec)(( /** @type {import('./types').StringRecord} */(this.binaries)).aapt, [
469
+ const { stdout } = await (0, teen_process_1.exec)(this.binaries.aapt, [
474
470
  'd', 'configurations', appPath,
475
471
  ]);
476
472
  return lodash_1.default.uniq(stdout.split(os_1.default.EOL));
477
473
  }, language, '(default)');
478
- const { stdout } = await (0, teen_process_1.exec)(( /** @type {import('./types').StringRecord} */(this.binaries)).aapt, [
474
+ const { stdout } = await (0, teen_process_1.exec)(this.binaries.aapt, [
479
475
  'd', '--values', 'resources', appPath,
480
476
  ]);
481
477
  apkStrings = parseAaptStrings(stdout, configMarker);
482
478
  }
483
479
  catch (e) {
480
+ const err = e;
484
481
  logger_js_1.log.debug('Cannot extract resources using aapt. Trying aapt2. ' +
485
- `Original error: ${e.stderr || e.message}`);
482
+ `Original error: ${err.stderr || err.message}`);
486
483
  await this.initAapt2();
487
484
  configMarker = await formatConfigMarker(async () => {
488
- const { stdout } = await (0, teen_process_1.exec)(( /** @type {import('./types').StringRecord} */(this.binaries)).aapt2, [
485
+ const { stdout } = await (0, teen_process_1.exec)(this.binaries.aapt2, [
489
486
  'd', 'configurations', appPath,
490
487
  ]);
491
488
  return lodash_1.default.uniq(stdout.split(os_1.default.EOL));
492
489
  }, language, '');
493
490
  try {
494
- const { stdout } = await (0, teen_process_1.exec)(( /** @type {import('./types').StringRecord} */(this.binaries)).aapt2, [
491
+ const { stdout } = await (0, teen_process_1.exec)(this.binaries.aapt2, [
495
492
  'd', 'resources', appPath,
496
493
  ]);
497
494
  apkStrings = parseAapt2Strings(stdout, configMarker);
498
495
  }
499
496
  catch (e) {
497
+ const error = e;
500
498
  throw new Error(`Cannot extract resources from '${originalAppPath}'. ` +
501
- `Original error: ${e.message}`);
499
+ `Original error: ${error.message}`);
502
500
  }
503
501
  }
504
502
  if (lodash_1.default.isEmpty(apkStrings)) {
@@ -520,10 +518,9 @@ async function extractStringsFromApk(appPath, language = null, outRoot = null) {
520
518
  /**
521
519
  * Get the package info from local apk file.
522
520
  *
523
- * @this {import('../adb.js').ADB}
524
- * @param {string} appPath - The full path to existing .apk(s) package on the local
521
+ * @param appPath - The full path to existing .apk(s) package on the local
525
522
  * file system.
526
- * @return {Promise<import('./types').AppInfo|{}>} The parsed application information.
523
+ * @returns The parsed application information.
527
524
  */
528
525
  async function getApkInfo(appPath) {
529
526
  if (!await support_1.fs.exists(appPath)) {
@@ -541,7 +538,8 @@ async function getApkInfo(appPath) {
541
538
  };
542
539
  }
543
540
  catch (e) {
544
- logger_js_1.log.warn(`Error '${e.message}' while getting badging info`);
541
+ const err = e;
542
+ logger_js_1.log.warn(`Error '${err.message}' while getting badging info`);
545
543
  }
546
544
  return {};
547
545
  }
@@ -550,11 +548,11 @@ async function getApkInfo(appPath) {
550
548
  * Formats the config marker, which is then passed to parse.. methods
551
549
  * to make it compatible with resource formats generated by aapt(2) tool
552
550
  *
553
- * @param {Function} configsGetter The function whose result is a list
551
+ * @param configsGetter The function whose result is a list
554
552
  * of apk configs
555
- * @param {string?} desiredMarker The desired config marker value
556
- * @param {string} defaultMarker The default config marker value
557
- * @return {Promise<string>} The formatted config marker
553
+ * @param desiredMarker The desired config marker value
554
+ * @param defaultMarker The default config marker value
555
+ * @returns The formatted config marker
558
556
  */
559
557
  async function formatConfigMarker(configsGetter, desiredMarker, defaultMarker) {
560
558
  let configMarker = desiredMarker || defaultMarker;
@@ -578,10 +576,10 @@ async function formatConfigMarker(configsGetter, desiredMarker, defaultMarker) {
578
576
  /**
579
577
  * Parses apk strings from aapt2 tool output
580
578
  *
581
- * @param {string} rawOutput The actual tool output
582
- * @param {string} configMarker The config marker. Usually
579
+ * @param rawOutput The actual tool output
580
+ * @param configMarker The config marker. Usually
583
581
  * a language abbreviation or an empty string for the default one
584
- * @returns {Object} Strings ids to values mapping. Plural
582
+ * @returns Strings ids to values mapping. Plural
585
583
  * values are represented as arrays. If no config found for the
586
584
  * given marker then an empty mapping is returned.
587
585
  */
@@ -669,7 +667,7 @@ function parseAapt2Strings(rawOutput, configMarker) {
669
667
  lineIndex = idx;
670
668
  if (lodash_1.default.isString(content)) {
671
669
  apkStrings[currentResourceId] = [
672
- ...(apkStrings[currentResourceId] || []),
670
+ ...(Array.isArray(apkStrings[currentResourceId]) ? apkStrings[currentResourceId] : []),
673
671
  content,
674
672
  ];
675
673
  }
@@ -691,10 +689,10 @@ function parseAapt2Strings(rawOutput, configMarker) {
691
689
  /**
692
690
  * Parses apk strings from aapt tool output
693
691
  *
694
- * @param {string} rawOutput The actual tool output
695
- * @param {string} configMarker The config marker. Usually
692
+ * @param rawOutput The actual tool output
693
+ * @param configMarker The config marker. Usually
696
694
  * a language abbreviation or `(default)`
697
- * @returns {Object} Strings ids to values mapping. Plural
695
+ * @returns Strings ids to values mapping. Plural
698
696
  * values are represented as arrays. If no config found for the
699
697
  * given marker then an empty mapping is returned.
700
698
  */
@@ -752,7 +750,7 @@ function parseAaptStrings(rawOutput, configMarker) {
752
750
  const match = quotedStringPattern.exec(trimmedLine);
753
751
  if (match) {
754
752
  apkStrings[currentResourceId] = [
755
- ...(apkStrings[currentResourceId] || []),
753
+ ...(Array.isArray(apkStrings[currentResourceId]) ? apkStrings[currentResourceId] : []),
756
754
  normalizeStringMatch(match[0]),
757
755
  ];
758
756
  }