appium-android-driver 12.4.8 → 12.4.10

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 (39) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/lib/commands/element.d.ts +90 -66
  3. package/build/lib/commands/element.d.ts.map +1 -1
  4. package/build/lib/commands/element.js +74 -53
  5. package/build/lib/commands/element.js.map +1 -1
  6. package/build/lib/commands/geolocation.d.ts +44 -36
  7. package/build/lib/commands/geolocation.d.ts.map +1 -1
  8. package/build/lib/commands/geolocation.js +38 -32
  9. package/build/lib/commands/geolocation.js.map +1 -1
  10. package/build/lib/commands/log.d.ts +43 -47
  11. package/build/lib/commands/log.d.ts.map +1 -1
  12. package/build/lib/commands/log.js +30 -55
  13. package/build/lib/commands/log.js.map +1 -1
  14. package/build/lib/commands/media-projection.d.ts +32 -36
  15. package/build/lib/commands/media-projection.d.ts.map +1 -1
  16. package/build/lib/commands/media-projection.js +27 -54
  17. package/build/lib/commands/media-projection.js.map +1 -1
  18. package/build/lib/commands/network.d.ts +59 -39
  19. package/build/lib/commands/network.d.ts.map +1 -1
  20. package/build/lib/commands/network.js +65 -45
  21. package/build/lib/commands/network.js.map +1 -1
  22. package/build/lib/commands/permissions.d.ts +47 -19
  23. package/build/lib/commands/permissions.d.ts.map +1 -1
  24. package/build/lib/commands/permissions.js +21 -36
  25. package/build/lib/commands/permissions.js.map +1 -1
  26. package/build/lib/commands/system-bars.d.ts +27 -21
  27. package/build/lib/commands/system-bars.d.ts.map +1 -1
  28. package/build/lib/commands/system-bars.js +23 -40
  29. package/build/lib/commands/system-bars.js.map +1 -1
  30. package/build/lib/driver.d.ts +9 -9
  31. package/lib/commands/element.ts +234 -0
  32. package/lib/commands/{geolocation.js → geolocation.ts} +85 -54
  33. package/lib/commands/{log.js → log.ts} +66 -71
  34. package/lib/commands/{media-projection.js → media-projection.ts} +69 -68
  35. package/lib/commands/{network.js → network.ts} +106 -59
  36. package/lib/commands/{permissions.js → permissions.ts} +58 -50
  37. package/lib/commands/{system-bars.js → system-bars.ts} +59 -50
  38. package/package.json +1 -1
  39. package/lib/commands/element.js +0 -158
@@ -2,8 +2,10 @@ import _ from 'lodash';
2
2
  import {fs, tempDir} from '@appium/support';
3
3
  import path from 'node:path';
4
4
  import B from 'bluebird';
5
+ import type {Location} from '@appium/types';
5
6
  import {SETTINGS_HELPER_ID} from 'io.appium.settings';
6
7
  import {getThirdPartyPackages} from './app-management';
8
+ import type {AndroidDriver} from '../driver';
7
9
 
8
10
  // The value close to zero, but not zero, is needed
9
11
  // to trick JSON generation and send a float value instead of an integer,
@@ -14,17 +16,21 @@ const GEO_EPSILON = Number.MIN_VALUE;
14
16
  const MOCK_APP_IDS_STORE = '/data/local/tmp/mock_apps.json';
15
17
 
16
18
  /**
17
- * @this {import('../driver').AndroidDriver}
18
- * @param {import('@appium/types').Location} location
19
- * @returns {Promise<import('@appium/types').Location>}
19
+ * Sets the device geolocation.
20
+ *
21
+ * @param location The geolocation object containing latitude, longitude, and altitude.
22
+ * @returns Promise that resolves to the current geolocation after setting it.
20
23
  */
21
- export async function setGeoLocation(location) {
24
+ export async function setGeoLocation(
25
+ this: AndroidDriver,
26
+ location: Location,
27
+ ): Promise<Location> {
22
28
  await this.settingsApp.setGeoLocation(location, this.isEmulator());
23
29
  try {
24
30
  return await this.getGeoLocation();
25
31
  } catch (e) {
26
32
  this.log.warn(
27
- `Could not get the current geolocation info: ${/** @type {Error} */ (e).message}`,
33
+ `Could not get the current geolocation info: ${(e as Error).message}`,
28
34
  );
29
35
  this.log.warn(`Returning the default zero'ed values`);
30
36
  return {
@@ -38,28 +44,28 @@ export async function setGeoLocation(location) {
38
44
  /**
39
45
  * Set the device geolocation.
40
46
  *
41
- * @this {import('../driver').AndroidDriver}
42
- * @param {number} latitude Valid latitude value.
43
- * @param {number} longitude Valid longitude value.
44
- * @param {number} [altitude] Valid altitude value.
45
- * @param {number} [satellites] Number of satellites being tracked (1-12). Available for emulators.
46
- * @param {number} [speed] Valid speed value.
47
+ * @param latitude Valid latitude value.
48
+ * @param longitude Valid longitude value.
49
+ * @param altitude Valid altitude value.
50
+ * @param satellites Number of satellites being tracked (1-12). Available for emulators.
51
+ * @param speed Valid speed value.
47
52
  * https://developer.android.com/reference/android/location/Location#setSpeed(float)
48
- * @param {number} [bearing] Valid bearing value. Available for real devices.
53
+ * @param bearing Valid bearing value. Available for real devices.
49
54
  * https://developer.android.com/reference/android/location/Location#setBearing(float)
50
- * @param {number} [accuracy] Valid accuracy value. Available for real devices.
55
+ * @param accuracy Valid accuracy value. Available for real devices.
51
56
  * https://developer.android.com/reference/android/location/Location#setAccuracy(float),
52
57
  * https://developer.android.com/reference/android/location/Criteria
53
58
  */
54
59
  export async function mobileSetGeolocation(
55
- latitude,
56
- longitude,
57
- altitude,
58
- satellites,
59
- speed,
60
- bearing,
61
- accuracy
62
- ) {
60
+ this: AndroidDriver,
61
+ latitude: number,
62
+ longitude: number,
63
+ altitude?: number,
64
+ satellites?: number,
65
+ speed?: number,
66
+ bearing?: number,
67
+ accuracy?: number,
68
+ ): Promise<void> {
63
69
  await this.settingsApp.setGeoLocation({
64
70
  latitude,
65
71
  longitude,
@@ -67,7 +73,7 @@ export async function mobileSetGeolocation(
67
73
  satellites,
68
74
  speed,
69
75
  bearing,
70
- accuracy
76
+ accuracy,
71
77
  }, this.isEmulator());
72
78
  }
73
79
 
@@ -78,22 +84,27 @@ export async function mobileSetGeolocation(
78
84
  * installed. In case the vanilla LocationManager is used the device API level
79
85
  * must be at version 30 (Android R) or higher.
80
86
  *
81
- * @this {import('../driver').AndroidDriver}
82
- * @param {number} [timeoutMs] The maximum number of milliseconds
87
+ * @param timeoutMs The maximum number of milliseconds
83
88
  * to block until GPS cache is refreshed. Providing zero or a negative
84
89
  * value to it skips waiting completely.
85
90
  * 20000ms by default.
86
- * @returns {Promise<void>}
91
+ * @returns Promise that resolves when the GPS cache refresh is initiated.
87
92
  */
88
- export async function mobileRefreshGpsCache(timeoutMs) {
93
+ export async function mobileRefreshGpsCache(
94
+ this: AndroidDriver,
95
+ timeoutMs?: number,
96
+ ): Promise<void> {
89
97
  await this.settingsApp.refreshGeoLocationCache(timeoutMs);
90
98
  }
91
99
 
92
100
  /**
93
- * @this {import('../driver').AndroidDriver}
94
- * @returns {Promise<import('@appium/types').Location>}
101
+ * Gets the current device geolocation.
102
+ *
103
+ * @returns Promise that resolves to the current geolocation object.
95
104
  */
96
- export async function getGeoLocation() {
105
+ export async function getGeoLocation(
106
+ this: AndroidDriver,
107
+ ): Promise<Location> {
97
108
  const {latitude, longitude, altitude} = await this.settingsApp.getGeoLocation();
98
109
  return {
99
110
  latitude: parseFloat(String(latitude)) || GEO_EPSILON,
@@ -103,26 +114,35 @@ export async function getGeoLocation() {
103
114
  }
104
115
 
105
116
  /**
106
- * @this {import('../driver').AndroidDriver}
107
- * @returns {Promise<import('@appium/types').Location>}
117
+ * Gets the current device geolocation.
118
+ *
119
+ * @returns Promise that resolves to the current geolocation object.
108
120
  */
109
- export async function mobileGetGeolocation() {
121
+ export async function mobileGetGeolocation(
122
+ this: AndroidDriver,
123
+ ): Promise<Location> {
110
124
  return await this.getGeoLocation();
111
125
  }
112
126
 
113
127
  /**
114
- * @this {import('../driver').AndroidDriver}
115
- * @returns {Promise<boolean>}
128
+ * Checks if location services are enabled.
129
+ *
130
+ * @returns Promise that resolves to `true` if location services are enabled, `false` otherwise.
116
131
  */
117
- export async function isLocationServicesEnabled() {
132
+ export async function isLocationServicesEnabled(
133
+ this: AndroidDriver,
134
+ ): Promise<boolean> {
118
135
  return (await this.adb.getLocationProviders()).includes('gps');
119
136
  }
120
137
 
121
138
  /**
122
- * @this {import('../driver').AndroidDriver}
123
- * @returns {Promise<void>}
139
+ * Toggles the location services state.
140
+ *
141
+ * @returns Promise that resolves when the location services state is toggled.
124
142
  */
125
- export async function toggleLocationServices() {
143
+ export async function toggleLocationServices(
144
+ this: AndroidDriver,
145
+ ): Promise<void> {
126
146
  this.log.info('Toggling location services');
127
147
  const isGpsEnabled = await this.isLocationServicesEnabled();
128
148
  this.log.debug(
@@ -133,10 +153,14 @@ export async function toggleLocationServices() {
133
153
  }
134
154
 
135
155
  /**
136
- * @this {import('../driver').AndroidDriver}
137
- * @returns {Promise<void>}
156
+ * Resets the geolocation to the default state.
157
+ *
158
+ * @returns Promise that resolves when the geolocation is reset.
159
+ * @throws {Error} If called on an emulator (geolocation reset does not work on emulators).
138
160
  */
139
- export async function mobileResetGeolocation() {
161
+ export async function mobileResetGeolocation(
162
+ this: AndroidDriver,
163
+ ): Promise<void> {
140
164
  if (this.isEmulator()) {
141
165
  throw new Error('Geolocation reset does not work on emulators');
142
166
  }
@@ -146,20 +170,23 @@ export async function mobileResetGeolocation() {
146
170
  // #region Internal helpers
147
171
 
148
172
  /**
149
- * @this {import('../driver').AndroidDriver}
150
- * @param {string} appId
151
- * @returns {Promise<void>}
173
+ * Sets the mock location permission for a specific app.
174
+ *
175
+ * @param appId The application package identifier.
176
+ * @returns Promise that resolves when the mock location permission is set.
152
177
  */
153
- export async function setMockLocationApp(appId) {
178
+ export async function setMockLocationApp(
179
+ this: AndroidDriver,
180
+ appId: string,
181
+ ): Promise<void> {
154
182
  try {
155
183
  await this.adb.shell(['appops', 'set', appId, 'android:mock_location', 'allow']);
156
184
  } catch (err) {
157
- this.log.warn(`Unable to set mock location for app '${appId}': ${err.message}`);
185
+ this.log.warn(`Unable to set mock location for app '${appId}': ${(err as Error).message}`);
158
186
  return;
159
187
  }
160
188
  try {
161
- /** @type {string[]} */
162
- let pkgIds = [];
189
+ let pkgIds: string[] = [];
163
190
  if (await this.adb.fileExists(MOCK_APP_IDS_STORE)) {
164
191
  try {
165
192
  pkgIds = JSON.parse(await this.adb.shell(['cat', MOCK_APP_IDS_STORE]));
@@ -178,18 +205,21 @@ export async function setMockLocationApp(appId) {
178
205
  await fs.rimraf(tmpRoot);
179
206
  }
180
207
  } catch (e) {
181
- this.log.warn(`Unable to persist mock location app id '${appId}': ${e.message}`);
208
+ this.log.warn(`Unable to persist mock location app id '${appId}': ${(e as Error).message}`);
182
209
  }
183
210
  }
184
211
 
185
212
  /**
186
- * @this {import('../driver').AndroidDriver}
187
- * @returns {Promise<void>}
213
+ * Resets the mock location permissions for all apps.
214
+ *
215
+ * @returns Promise that resolves when the mock location permissions are reset.
188
216
  */
189
- async function resetMockLocation() {
217
+ async function resetMockLocation(
218
+ this: AndroidDriver,
219
+ ): Promise<void> {
190
220
  try {
191
221
  const thirdPartyPkgIdsPromise = getThirdPartyPackages.bind(this)();
192
- let pkgIds = [];
222
+ let pkgIds: string[] = [];
193
223
  if (await this.adb.fileExists(MOCK_APP_IDS_STORE)) {
194
224
  try {
195
225
  pkgIds = JSON.parse(await this.adb.shell(['cat', MOCK_APP_IDS_STORE]));
@@ -220,8 +250,9 @@ async function resetMockLocation() {
220
250
  ),
221
251
  );
222
252
  } catch (err) {
223
- this.log.warn(`Unable to reset mock location: ${err.message}`);
253
+ this.log.warn(`Unable to reset mock location: ${(err as Error).message}`);
224
254
  }
225
255
  }
226
256
 
227
257
  // #endregion Internal helpers
258
+
@@ -2,51 +2,42 @@ import {DEFAULT_WS_PATHNAME_PREFIX, BaseDriver} from 'appium/driver';
2
2
  import _ from 'lodash';
3
3
  import os from 'node:os';
4
4
  import WebSocket from 'ws';
5
+ import type {AppiumServer, WSServer} from '@appium/types';
6
+ import type {EventEmitter} from 'node:events';
7
+ import type {ADB} from 'appium-adb';
8
+ import type {Chromedriver} from 'appium-chromedriver';
5
9
  import {
6
10
  GET_SERVER_LOGS_FEATURE,
7
11
  toLogRecord,
8
12
  nativeLogEntryToSeleniumEntry,
13
+ type LogEntry,
9
14
  } from '../utils';
10
15
  import { NATIVE_WIN } from './context/helpers';
11
16
  import { BIDI_EVENT_NAME } from './bidi/constants';
12
17
  import { makeLogEntryAddedEvent } from './bidi/models';
18
+ import type {AndroidDriver} from '../driver';
13
19
 
14
20
  export const supportedLogTypes = {
15
21
  logcat: {
16
22
  description: 'Logs for Android applications on real device and emulators via ADB',
17
- /**
18
- *
19
- * @param {import('../driver').AndroidDriver} self
20
- * @returns
21
- */
22
- getter: (self) => /** @type {ADB} */ (self.adb).getLogcatLogs(),
23
+ getter: (self: AndroidDriver) => (self.adb as ADB).getLogcatLogs(),
23
24
  },
24
25
  bugreport: {
25
26
  description: `'adb bugreport' output for advanced issues diagnostic`,
26
- /**
27
- *
28
- * @param {import('../driver').AndroidDriver} self
29
- * @returns
30
- */
31
- getter: async (self) => {
32
- const output = await /** @type {ADB} */ (self.adb).bugreport();
27
+ getter: async (self: AndroidDriver) => {
28
+ const output = await (self.adb as ADB).bugreport();
33
29
  const timestamp = Date.now();
34
30
  return output.split(os.EOL).map((x) => toLogRecord(timestamp, x));
35
31
  },
36
32
  },
37
33
  server: {
38
34
  description: 'Appium server logs',
39
- /**
40
- *
41
- * @param {import('../driver').AndroidDriver} self
42
- * @returns
43
- */
44
- getter: (self) => {
35
+ getter: (self: AndroidDriver) => {
45
36
  self.assertFeatureEnabled(GET_SERVER_LOGS_FEATURE);
46
37
  return self.log.unwrap().record.map(nativeLogEntryToSeleniumEntry);
47
38
  },
48
39
  },
49
- };
40
+ } as const;
50
41
 
51
42
  /**
52
43
  * Starts Android logcat broadcast websocket on the same host and port
@@ -56,12 +47,13 @@ export const supportedLogTypes = {
56
47
  * Each connected websocket listener will receive logcat log lines
57
48
  * as soon as they are visible to Appium.
58
49
  *
59
- * @this {import('../driver').AndroidDriver}
60
- * @returns {Promise<void>}
50
+ * @returns Promise that resolves when the logcat broadcasting websocket is started.
61
51
  */
62
- export async function mobileStartLogsBroadcast() {
63
- const server = /** @type {import('@appium/types').AppiumServer} */ (this.server);
64
- const pathname = WEBSOCKET_ENDPOINT(/** @type {string} */ (this.sessionId));
52
+ export async function mobileStartLogsBroadcast(
53
+ this: AndroidDriver,
54
+ ): Promise<void> {
55
+ const server = this.server as AppiumServer;
56
+ const pathname = WEBSOCKET_ENDPOINT(this.sessionId as string);
65
57
  if (!_.isEmpty(await server.getWebSocketHandlers(pathname))) {
66
58
  this.log.debug(`The logcat broadcasting web socket server is already listening at ${pathname}`);
67
59
  return;
@@ -78,7 +70,7 @@ export async function mobileStartLogsBroadcast() {
78
70
  wss.on('connection', (ws, req) => {
79
71
  if (req) {
80
72
  const remoteIp = _.isEmpty(req.headers['x-forwarded-for'])
81
- ? req.connection?.remoteAddress
73
+ ? req.socket.remoteAddress
82
74
  : req.headers['x-forwarded-for'];
83
75
  this.log.debug(`Established a new logcat listener web socket connection from ${remoteIp}`);
84
76
  } else {
@@ -86,7 +78,7 @@ export async function mobileStartLogsBroadcast() {
86
78
  }
87
79
 
88
80
  if (_.isEmpty(this._logcatWebsocketListener)) {
89
- this._logcatWebsocketListener = (logRecord) => {
81
+ this._logcatWebsocketListener = (logRecord: LogEntry) => {
90
82
  if (ws?.readyState === WebSocket.OPEN) {
91
83
  ws.send(logRecord.message);
92
84
  }
@@ -112,19 +104,20 @@ export async function mobileStartLogsBroadcast() {
112
104
  this.log.debug(closeMsg);
113
105
  });
114
106
  });
115
- await server.addWebSocketHandler(pathname, /** @type {import('@appium/types').WSServer} */ (wss));
107
+ await server.addWebSocketHandler(pathname, wss as WSServer);
116
108
  }
117
109
 
118
110
  /**
119
111
  * Stops the previously started logcat broadcasting wesocket server.
120
112
  * This method will return immediately if no server is running.
121
113
  *
122
- * @this {import('../driver').AndroidDriver}
123
- * @returns {Promise<void>}
114
+ * @returns Promise that resolves when the logcat broadcasting websocket is stopped.
124
115
  */
125
- export async function mobileStopLogsBroadcast() {
126
- const pathname = WEBSOCKET_ENDPOINT(/** @type {string} */ (this.sessionId));
127
- const server = /** @type {import('@appium/types').AppiumServer} */ (this.server);
116
+ export async function mobileStopLogsBroadcast(
117
+ this: AndroidDriver,
118
+ ): Promise<void> {
119
+ const pathname = WEBSOCKET_ENDPOINT(this.sessionId as string);
120
+ const server = this.server as AppiumServer;
128
121
  if (_.isEmpty(await server.getWebSocketHandlers(pathname))) {
129
122
  return;
130
123
  }
@@ -137,40 +130,44 @@ export async function mobileStopLogsBroadcast() {
137
130
  }
138
131
 
139
132
  /**
140
- * @this {import('../driver').AndroidDriver}
141
- * @returns {Promise<string[]>}
133
+ * Gets the list of available log types.
134
+ *
135
+ * @returns Promise that resolves to an array of log type names.
142
136
  */
143
- export async function getLogTypes() {
137
+ export async function getLogTypes(
138
+ this: AndroidDriver,
139
+ ): Promise<string[]> {
144
140
  // XXX why doesn't `super` work here?
145
141
  const nativeLogTypes = await BaseDriver.prototype.getLogTypes.call(this);
146
142
  if (this.isWebContext()) {
147
- const webLogTypes = /** @type {string[]} */ (
148
- await /** @type {import('appium-chromedriver').Chromedriver} */ (
149
- this.chromedriver
150
- ).jwproxy.command('/log/types', 'GET')
151
- );
143
+ const webLogTypes = await (this.chromedriver as Chromedriver).jwproxy.command('/log/types', 'GET') as string[];
152
144
  return [...nativeLogTypes, ...webLogTypes];
153
145
  }
154
146
  return nativeLogTypes;
155
147
  }
156
148
 
157
149
  /**
150
+ * Assigns a BiDi log listener to an event emitter.
151
+ *
158
152
  * https://w3c.github.io/webdriver-bidi/#event-log-entryAdded
159
153
  *
160
- * @template {import('node:events').EventEmitter} EE
161
- * @this {import('../driver').AndroidDriver}
162
- * @param {EE} logEmitter
163
- * @param {BiDiListenerProperties} properties
164
- * @returns {[EE, LogListener]}
154
+ * @template EE The event emitter type.
155
+ * @param logEmitter The event emitter to attach the listener to.
156
+ * @param properties The BiDi listener properties.
157
+ * @returns A tuple containing the event emitter and the listener function.
165
158
  */
166
- export function assignBiDiLogListener (logEmitter, properties) {
159
+ export function assignBiDiLogListener<EE extends EventEmitter>(
160
+ this: AndroidDriver,
161
+ logEmitter: EE,
162
+ properties: BiDiListenerProperties,
163
+ ): [EE, LogListener] {
167
164
  const {
168
165
  type,
169
166
  context = NATIVE_WIN,
170
167
  srcEventName = 'output',
171
168
  entryTransformer,
172
169
  } = properties;
173
- const listener = (/** @type {import('../utils').LogEntry} */ logEntry) => {
170
+ const listener: LogListener = (logEntry: LogEntry) => {
174
171
  const finalEntry = entryTransformer ? entryTransformer(logEntry) : logEntry;
175
172
  this.eventEmitter.emit(BIDI_EVENT_NAME, makeLogEntryAddedEvent(finalEntry, context, type));
176
173
  };
@@ -179,42 +176,40 @@ export function assignBiDiLogListener (logEmitter, properties) {
179
176
  }
180
177
 
181
178
  /**
182
- * @this {import('../driver').AndroidDriver}
183
- * @param {string} logType
184
- * @returns {Promise<any>}
179
+ * Gets logs of a specific type.
180
+ *
181
+ * @param logType The type of logs to retrieve.
182
+ * @returns Promise that resolves to the logs for the specified type.
185
183
  */
186
- export async function getLog(logType) {
184
+ export async function getLog(
185
+ this: AndroidDriver,
186
+ logType: string,
187
+ ): Promise<any> {
187
188
  if (this.isWebContext() && !_.keys(this.supportedLogTypes).includes(logType)) {
188
- return await /** @type {import('appium-chromedriver').Chromedriver} */ (
189
- this.chromedriver
190
- ).jwproxy.command('/log', 'POST', {type: logType});
189
+ return await (this.chromedriver as Chromedriver).jwproxy.command('/log', 'POST', {type: logType});
191
190
  }
192
- // XXX why doesn't `super` work here?
193
191
  return await BaseDriver.prototype.getLog.call(this, logType);
194
192
  }
195
193
 
196
194
  // #region Internal helpers
197
195
 
198
196
  /**
199
- * @param {string} sessionId
200
- * @returns {string}
197
+ * Generates the websocket endpoint path for logcat broadcasting.
198
+ *
199
+ * @param sessionId The session ID.
200
+ * @returns The websocket endpoint path.
201
201
  */
202
- const WEBSOCKET_ENDPOINT = (sessionId) =>
202
+ const WEBSOCKET_ENDPOINT = (sessionId: string): string =>
203
203
  `${DEFAULT_WS_PATHNAME_PREFIX}/session/${sessionId}/appium/device/logcat`;
204
204
 
205
-
206
205
  // #endregion
207
206
 
208
- /**
209
- * @typedef {import('appium-adb').ADB} ADB
210
- */
207
+ export interface BiDiListenerProperties {
208
+ type: string;
209
+ srcEventName?: string;
210
+ context?: string;
211
+ entryTransformer?: (x: LogEntry) => LogEntry;
212
+ }
211
213
 
212
- /**
213
- * @typedef {Object} BiDiListenerProperties
214
- * @property {string} type
215
- * @property {string} [srcEventName='output']
216
- * @property {string} [context=NATIVE_WIN]
217
- * @property {(x: Object) => import('../utils').LogEntry} [entryTransformer]
218
- */
214
+ export type LogListener = (logEntry: LogEntry) => any;
219
215
 
220
- /** @typedef {(logEntry: import('../utils').LogEntry) => any} LogListener */