@appium/base-driver 10.5.2 → 10.7.0

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 (189) hide show
  1. package/build/lib/basedriver/capabilities.d.ts +1 -1
  2. package/build/lib/basedriver/capabilities.d.ts.map +1 -1
  3. package/build/lib/basedriver/capabilities.js +58 -50
  4. package/build/lib/basedriver/capabilities.js.map +1 -1
  5. package/build/lib/basedriver/commands/bidi.d.ts.map +1 -1
  6. package/build/lib/basedriver/commands/bidi.js +10 -14
  7. package/build/lib/basedriver/commands/bidi.js.map +1 -1
  8. package/build/lib/basedriver/commands/event.d.ts.map +1 -1
  9. package/build/lib/basedriver/commands/event.js +4 -7
  10. package/build/lib/basedriver/commands/event.js.map +1 -1
  11. package/build/lib/basedriver/commands/execute.js +3 -6
  12. package/build/lib/basedriver/commands/execute.js.map +1 -1
  13. package/build/lib/basedriver/commands/find.d.ts.map +1 -1
  14. package/build/lib/basedriver/commands/find.js +2 -1
  15. package/build/lib/basedriver/commands/find.js.map +1 -1
  16. package/build/lib/basedriver/commands/log.d.ts.map +1 -1
  17. package/build/lib/basedriver/commands/log.js +1 -5
  18. package/build/lib/basedriver/commands/log.js.map +1 -1
  19. package/build/lib/basedriver/commands/timeout.d.ts.map +1 -1
  20. package/build/lib/basedriver/commands/timeout.js +9 -13
  21. package/build/lib/basedriver/commands/timeout.js.map +1 -1
  22. package/build/lib/basedriver/core.d.ts.map +1 -1
  23. package/build/lib/basedriver/core.js +17 -14
  24. package/build/lib/basedriver/core.js.map +1 -1
  25. package/build/lib/basedriver/device-settings.d.ts.map +1 -1
  26. package/build/lib/basedriver/device-settings.js +3 -7
  27. package/build/lib/basedriver/device-settings.js.map +1 -1
  28. package/build/lib/basedriver/driver.d.ts.map +1 -1
  29. package/build/lib/basedriver/driver.js +34 -38
  30. package/build/lib/basedriver/driver.js.map +1 -1
  31. package/build/lib/basedriver/extension-core.d.ts +4 -1
  32. package/build/lib/basedriver/extension-core.d.ts.map +1 -1
  33. package/build/lib/basedriver/extension-core.js +37 -13
  34. package/build/lib/basedriver/extension-core.js.map +1 -1
  35. package/build/lib/basedriver/helpers.d.ts.map +1 -1
  36. package/build/lib/basedriver/helpers.js +47 -33
  37. package/build/lib/basedriver/helpers.js.map +1 -1
  38. package/build/lib/basedriver/ipc.d.ts +36 -0
  39. package/build/lib/basedriver/ipc.d.ts.map +1 -0
  40. package/build/lib/basedriver/ipc.js +157 -0
  41. package/build/lib/basedriver/ipc.js.map +1 -0
  42. package/build/lib/basedriver/validation.d.ts.map +1 -1
  43. package/build/lib/basedriver/validation.js +27 -29
  44. package/build/lib/basedriver/validation.js.map +1 -1
  45. package/build/lib/express/express-logging.d.ts +0 -1
  46. package/build/lib/express/express-logging.d.ts.map +1 -1
  47. package/build/lib/express/express-logging.js +11 -11
  48. package/build/lib/express/express-logging.js.map +1 -1
  49. package/build/lib/express/idempotency.js +3 -6
  50. package/build/lib/express/idempotency.js.map +1 -1
  51. package/build/lib/express/middleware.d.ts.map +1 -1
  52. package/build/lib/express/middleware.js +6 -10
  53. package/build/lib/express/middleware.js.map +1 -1
  54. package/build/lib/express/server.d.ts +1 -1
  55. package/build/lib/express/server.d.ts.map +1 -1
  56. package/build/lib/express/server.js +82 -73
  57. package/build/lib/express/server.js.map +1 -1
  58. package/build/lib/express/websocket.d.ts.map +1 -1
  59. package/build/lib/express/websocket.js +6 -9
  60. package/build/lib/express/websocket.js.map +1 -1
  61. package/build/lib/helpers/capabilities.d.ts.map +1 -1
  62. package/build/lib/helpers/capabilities.js +14 -17
  63. package/build/lib/helpers/capabilities.js.map +1 -1
  64. package/build/lib/helpers/extension-command-name.js +2 -5
  65. package/build/lib/helpers/extension-command-name.js.map +1 -1
  66. package/build/lib/helpers/levenshtein-match.d.ts.map +1 -1
  67. package/build/lib/helpers/levenshtein-match.js +6 -7
  68. package/build/lib/helpers/levenshtein-match.js.map +1 -1
  69. package/build/lib/index.d.ts +2 -1
  70. package/build/lib/index.d.ts.map +1 -1
  71. package/build/lib/index.js +6 -16
  72. package/build/lib/index.js.map +1 -1
  73. package/build/lib/jsonwp-proxy/protocol-converter.d.ts.map +1 -1
  74. package/build/lib/jsonwp-proxy/protocol-converter.js +21 -18
  75. package/build/lib/jsonwp-proxy/protocol-converter.js.map +1 -1
  76. package/build/lib/jsonwp-proxy/proxy-request.d.ts +2 -2
  77. package/build/lib/jsonwp-proxy/proxy-request.d.ts.map +1 -1
  78. package/build/lib/jsonwp-proxy/proxy-request.js +25 -21
  79. package/build/lib/jsonwp-proxy/proxy-request.js.map +1 -1
  80. package/build/lib/jsonwp-proxy/proxy.d.ts.map +1 -1
  81. package/build/lib/jsonwp-proxy/proxy.js +45 -36
  82. package/build/lib/jsonwp-proxy/proxy.js.map +1 -1
  83. package/build/lib/protocol/errors.d.ts.map +1 -1
  84. package/build/lib/protocol/errors.js +33 -37
  85. package/build/lib/protocol/errors.js.map +1 -1
  86. package/build/lib/protocol/helpers.d.ts.map +1 -1
  87. package/build/lib/protocol/helpers.js +9 -8
  88. package/build/lib/protocol/helpers.js.map +1 -1
  89. package/build/lib/protocol/protocol.d.ts +1 -1
  90. package/build/lib/protocol/protocol.d.ts.map +1 -1
  91. package/build/lib/protocol/protocol.js +73 -61
  92. package/build/lib/protocol/protocol.js.map +1 -1
  93. package/build/lib/protocol/routes.d.ts +1 -1
  94. package/build/lib/protocol/routes.d.ts.map +1 -1
  95. package/build/lib/protocol/routes.js +16 -17
  96. package/build/lib/protocol/routes.js.map +1 -1
  97. package/build/lib/protocol/validators.d.ts.map +1 -1
  98. package/build/lib/protocol/validators.js +1 -5
  99. package/build/lib/protocol/validators.js.map +1 -1
  100. package/build/lib/test-pages/crash.d.ts.map +1 -0
  101. package/build/lib/test-pages/crash.js.map +1 -0
  102. package/build/lib/test-pages/env.d.ts +5 -0
  103. package/build/lib/test-pages/env.d.ts.map +1 -0
  104. package/build/lib/test-pages/env.js +12 -0
  105. package/build/lib/test-pages/env.js.map +1 -0
  106. package/build/lib/{express/static.d.ts → test-pages/handlers.d.ts} +1 -2
  107. package/build/lib/test-pages/handlers.d.ts.map +1 -0
  108. package/build/lib/{express/static.js → test-pages/handlers.js} +9 -12
  109. package/build/lib/test-pages/handlers.js.map +1 -0
  110. package/build/lib/test-pages/index.d.ts +6 -0
  111. package/build/lib/test-pages/index.d.ts.map +1 -0
  112. package/build/lib/test-pages/index.js +35 -0
  113. package/build/lib/test-pages/index.js.map +1 -0
  114. package/build/lib/test-pages/static-dir.d.ts +8 -0
  115. package/build/lib/test-pages/static-dir.d.ts.map +1 -0
  116. package/build/lib/test-pages/static-dir.js +24 -0
  117. package/build/lib/test-pages/static-dir.js.map +1 -0
  118. package/build/lib/test-pages/template.d.ts +3 -0
  119. package/build/lib/test-pages/template.d.ts.map +1 -0
  120. package/build/lib/test-pages/template.js +19 -0
  121. package/build/lib/test-pages/template.js.map +1 -0
  122. package/build/lib/utils.d.ts +14 -0
  123. package/build/lib/utils.d.ts.map +1 -0
  124. package/build/lib/utils.js +55 -0
  125. package/build/lib/utils.js.map +1 -0
  126. package/lib/basedriver/capabilities.ts +126 -115
  127. package/lib/basedriver/commands/bidi.ts +11 -11
  128. package/lib/basedriver/commands/event.ts +17 -11
  129. package/lib/basedriver/commands/execute.ts +15 -12
  130. package/lib/basedriver/commands/find.ts +20 -12
  131. package/lib/basedriver/commands/log.ts +4 -3
  132. package/lib/basedriver/commands/timeout.ts +22 -14
  133. package/lib/basedriver/core.ts +26 -26
  134. package/lib/basedriver/device-settings.ts +7 -12
  135. package/lib/basedriver/driver.ts +62 -50
  136. package/lib/basedriver/extension-core.ts +60 -18
  137. package/lib/basedriver/helpers.ts +81 -52
  138. package/lib/basedriver/ipc.ts +198 -0
  139. package/lib/basedriver/validation.ts +37 -30
  140. package/lib/express/express-logging.ts +16 -20
  141. package/lib/express/idempotency.ts +9 -9
  142. package/lib/express/middleware.ts +14 -18
  143. package/lib/express/server.ts +118 -120
  144. package/lib/express/websocket.ts +11 -15
  145. package/lib/helpers/capabilities.ts +21 -16
  146. package/lib/helpers/extension-command-name.ts +3 -3
  147. package/lib/helpers/levenshtein-match.ts +20 -14
  148. package/lib/index.js +3 -12
  149. package/lib/jsonwp-proxy/protocol-converter.ts +58 -35
  150. package/lib/jsonwp-proxy/proxy-request.ts +26 -26
  151. package/lib/jsonwp-proxy/proxy.ts +74 -75
  152. package/lib/protocol/errors.ts +69 -88
  153. package/lib/protocol/helpers.ts +9 -5
  154. package/lib/protocol/protocol.ts +149 -107
  155. package/lib/protocol/routes.ts +17 -17
  156. package/lib/protocol/validators.ts +1 -3
  157. package/lib/test-pages/env.ts +9 -0
  158. package/lib/{express/static.ts → test-pages/handlers.ts} +10 -22
  159. package/lib/test-pages/index.ts +34 -0
  160. package/lib/test-pages/static-dir.ts +19 -0
  161. package/lib/test-pages/template.ts +17 -0
  162. package/lib/utils.ts +65 -0
  163. package/package.json +10 -13
  164. package/tsconfig.json +1 -0
  165. package/build/lib/express/crash.d.ts.map +0 -1
  166. package/build/lib/express/crash.js.map +0 -1
  167. package/build/lib/express/static.d.ts.map +0 -1
  168. package/build/lib/express/static.js.map +0 -1
  169. /package/build/lib/{express → test-pages}/crash.d.ts +0 -0
  170. /package/build/lib/{express → test-pages}/crash.js +0 -0
  171. /package/lib/{express → test-pages}/crash.ts +0 -0
  172. /package/{static → test-fixtures/static}/appium.png +0 -0
  173. /package/{static → test-fixtures/static}/favicon.ico +0 -0
  174. /package/{static → test-fixtures/static}/js/jquery.min.js +0 -0
  175. /package/{static → test-fixtures/static}/test/frameset.html +0 -0
  176. /package/{static → test-fixtures/static}/test/guinea-pig-app-banner.html +0 -0
  177. /package/{static → test-fixtures/static}/test/guinea-pig-scrollable.html +0 -0
  178. /package/{static → test-fixtures/static}/test/guinea-pig.html +0 -0
  179. /package/{static → test-fixtures/static}/test/guinea-pig2.html +0 -0
  180. /package/{static → test-fixtures/static}/test/guinea-pig3.html +0 -0
  181. /package/{static → test-fixtures/static}/test/guinea-pig4.html +0 -0
  182. /package/{static → test-fixtures/static}/test/guinea-pig5.html +0 -0
  183. /package/{static → test-fixtures/static}/test/iframes.html +0 -0
  184. /package/{static → test-fixtures/static}/test/shadow-dom.html +0 -0
  185. /package/{static → test-fixtures/static}/test/subframe1.html +0 -0
  186. /package/{static → test-fixtures/static}/test/subframe2.html +0 -0
  187. /package/{static → test-fixtures/static}/test/subframe3.html +0 -0
  188. /package/{static → test-fixtures/static}/test/touch.html +0 -0
  189. /package/{static → test-fixtures/static}/test/welcome.html +0 -0
@@ -1,6 +1,6 @@
1
1
  import type {Constraint} from '@appium/types';
2
+ import {util} from '@appium/support';
2
3
  import {log} from './logger';
3
- import _ from 'lodash';
4
4
 
5
5
  export class Validator {
6
6
  private readonly _validators: Record<
@@ -8,27 +8,27 @@ export class Validator {
8
8
  (value: any, options?: any, key?: string) => string | null
9
9
  > = {
10
10
  isString: (value: any, options?: any): string | null => {
11
- if (_.isUndefined(value) || _.isNil(options)) {
11
+ if (value === undefined || options == null) {
12
12
  return null;
13
13
  }
14
14
 
15
- if (_.isString(value)) {
15
+ if (typeof value === 'string') {
16
16
  return options ? null : 'must not be of type string';
17
17
  }
18
18
 
19
19
  return options ? 'must be of type string' : null;
20
20
  },
21
21
  isNumber: (value: any, options?: any): string | null => {
22
- if (_.isUndefined(value) || _.isNil(options)) {
22
+ if (value === undefined || options == null) {
23
23
  return null;
24
24
  }
25
25
 
26
- if (_.isNumber(value)) {
26
+ if (typeof value === 'number') {
27
27
  return options ? null : 'must not be of type number';
28
28
  }
29
29
 
30
30
  // allow a string value
31
- if (options && _.isString(value) && !isNaN(Number(value))) {
31
+ if (options && typeof value === 'string' && !isNaN(Number(value))) {
32
32
  log.warn('Number capability passed in as string. Functionality may be compromised.');
33
33
  return null;
34
34
  }
@@ -36,97 +36,105 @@ export class Validator {
36
36
  return options ? 'must be of type number' : null;
37
37
  },
38
38
  isBoolean: (value: any, options?: any): string | null => {
39
- if (_.isUndefined(value) || _.isNil(options)) {
39
+ if (value === undefined || options == null) {
40
40
  return null;
41
41
  }
42
42
 
43
- if (_.isBoolean(value)) {
43
+ if (typeof value === 'boolean') {
44
44
  return options ? null : 'must not be of type boolean';
45
45
  }
46
46
 
47
47
  // allow a string value
48
- if (options && _.isString(value) && ['true', 'false', ''].includes(value)) {
48
+ if (options && typeof value === 'string' && ['true', 'false', ''].includes(value)) {
49
49
  return null;
50
50
  }
51
51
 
52
52
  return options ? 'must be of type boolean' : null;
53
53
  },
54
54
  isObject: (value: any, options?: any): string | null => {
55
- if (_.isUndefined(value) || _.isNil(options)) {
55
+ if (value === undefined || options == null) {
56
56
  return null;
57
57
  }
58
58
 
59
- if (_.isPlainObject(value)) {
59
+ if (util.isPlainObject(value)) {
60
60
  return options ? null : 'must not be a plain object';
61
61
  }
62
62
 
63
63
  return options ? 'must be a plain object' : null;
64
64
  },
65
65
  isArray: (value: any, options?: any): string | null => {
66
- if (_.isUndefined(value) || _.isNil(options)) {
66
+ if (value === undefined || options == null) {
67
67
  return null;
68
68
  }
69
69
 
70
- if (_.isArray(value)) {
70
+ if (Array.isArray(value)) {
71
71
  return options ? null : 'must not be of type array';
72
72
  }
73
73
 
74
74
  return options ? 'must be of type array' : null;
75
75
  },
76
76
  deprecated: (value: any, options?: any, key?: string): string | null => {
77
- if (!_.isUndefined(value) && options) {
77
+ if (value !== undefined && options) {
78
78
  log.warn(
79
79
  `The '${key}' capability has been deprecated and must not be used anymore. ` +
80
- `Please check the driver documentation for possible alternatives.`
80
+ `Please check the driver documentation for possible alternatives.`,
81
81
  );
82
82
  }
83
83
  return null;
84
84
  },
85
85
  inclusion: (value: any, options?: any): string | null => {
86
- if (_.isUndefined(value) || !options) {
86
+ if (value === undefined || !options) {
87
87
  return null;
88
88
  }
89
- const optionsArr = _.isArray(options) ? options : [options];
89
+ const optionsArr = Array.isArray(options) ? options : [options];
90
90
  if (optionsArr.some((opt) => opt === value)) {
91
91
  return null;
92
92
  }
93
93
  return `must be contained by ${JSON.stringify(optionsArr)}`;
94
94
  },
95
95
  inclusionCaseInsensitive: (value: any, options?: any): string | null => {
96
- if (_.isUndefined(value) || !options) {
96
+ if (value === undefined || !options) {
97
97
  return null;
98
98
  }
99
- const optionsArr = _.isArray(options) ? options : [options];
100
- if (optionsArr.some((opt) => _.toLower(opt) === _.toLower(value))) {
99
+ const optionsArr = Array.isArray(options) ? options : [options];
100
+ if (optionsArr.some((opt) => String(opt).toLowerCase() === String(value).toLowerCase())) {
101
101
  return null;
102
102
  }
103
103
  return `must be contained by ${JSON.stringify(optionsArr)}`;
104
104
  },
105
105
  presence: (value: any, options?: any): string | null => {
106
- if (_.isUndefined(value) && options) {
106
+ if (value === undefined && options) {
107
107
  return 'is required to be present';
108
108
  }
109
109
  if (
110
110
  !options?.allowEmpty &&
111
- ((!_.isUndefined(value) && _.isEmpty(value)) || (_.isString(value) && !_.trim(value)))
111
+ ((value !== undefined && util.isEmpty(value)) ||
112
+ (typeof value === 'string' && !value.trim()))
112
113
  ) {
113
114
  return 'must not be empty or blank';
114
115
  }
115
116
  return null;
116
- }
117
+ },
117
118
  };
118
119
 
119
- validate(values: Record<string, any>, constraints: Record<string, Constraint>): Record<string, string[]> | null {
120
+ validate(
121
+ values: Record<string, any>,
122
+ constraints: Record<string, Constraint>,
123
+ ): Record<string, string[]> | null {
120
124
  const result: Record<string, string[]> = {};
121
- for (const [key, constraint] of _.toPairs(constraints)) {
125
+ for (const [key, constraint] of Object.entries(constraints)) {
122
126
  const value = values[key];
123
- for (const [validatorName, options] of _.toPairs(constraint)) {
127
+ for (const [validatorName, options] of Object.entries(constraint)) {
124
128
  if (!(validatorName in this._validators)) {
125
129
  continue;
126
130
  }
127
131
 
128
- const validationError = this._validators[validatorName](value, options, key);
129
- if (_.isNil(validationError)) {
132
+ const validationError = this._validators[validatorName as keyof Constraint](
133
+ value,
134
+ options,
135
+ key,
136
+ );
137
+ if (validationError == null) {
130
138
  continue;
131
139
  }
132
140
 
@@ -137,9 +145,8 @@ export class Validator {
137
145
  }
138
146
  }
139
147
  }
140
- return _.isEmpty(result) ? null : result;
148
+ return util.isEmpty(result) ? null : result;
141
149
  }
142
-
143
150
  }
144
151
 
145
152
  export const validator = new Validator();
@@ -1,10 +1,8 @@
1
- import _ from 'lodash';
2
- import '@colors/colors';
1
+ import {console, logger, util} from '@appium/support';
3
2
  import morgan from 'morgan';
4
3
  import type {Request, RequestHandler, Response} from 'express';
5
4
  import {log} from './logger';
6
5
  import {MAX_LOG_BODY_LENGTH} from '../constants';
7
- import {logger} from '@appium/support';
8
6
 
9
7
  /**
10
8
  * Morgan middleware that logs when the HTTP response finishes.
@@ -24,17 +22,18 @@ export const startLogFormatter: RequestHandler = morgan(startLogFormatterHandler
24
22
  type MorganTokens = unknown;
25
23
  type FormatFn = (tokens: MorganTokens, req: Request, res: Response) => string;
26
24
 
27
- function endLogFormatterHandler(tokens: MorganTokens, req: Request, res: Response): void {
25
+ function endLogFormatterHandler(tokens: MorganTokens, req: Request, res: Response): undefined {
28
26
  log.info(requestEndLoggingFormat(tokens, req, res));
27
+ return undefined;
29
28
  }
30
29
 
31
- function startLogFormatterHandler(tokens: unknown, req: Request, res: Response): void {
30
+ function startLogFormatterHandler(tokens: unknown, req: Request, res: Response): undefined {
32
31
  let reqBody = '';
33
32
  if (req.body) {
34
33
  try {
35
- reqBody = _.truncate(
36
- _.isString(req.body) ? req.body : JSON.stringify(req.body),
37
- {length: MAX_LOG_BODY_LENGTH}
34
+ reqBody = util.truncateString(
35
+ typeof req.body === 'string' ? req.body : JSON.stringify(req.body),
36
+ {length: MAX_LOG_BODY_LENGTH},
38
37
  );
39
38
  } catch {
40
39
  // ignore
@@ -42,8 +41,9 @@ function startLogFormatterHandler(tokens: unknown, req: Request, res: Response):
42
41
  }
43
42
  log.info(
44
43
  requestStartLoggingFormat(tokens, req, res),
45
- logger.markSensitive(reqBody.grey)
44
+ logger.markSensitive(console.styleText('grey', reqBody)),
46
45
  );
46
+ return undefined;
47
47
  }
48
48
 
49
49
  // Copied the morgan compile function over so that cooler formats may be configured
@@ -56,29 +56,25 @@ function compile(fmt: string): FormatFn {
56
56
  return new Function('tokens', 'req', 'res', js) as FormatFn;
57
57
  }
58
58
 
59
- function requestEndLoggingFormat(
60
- tokens: MorganTokens,
61
- req: Request,
62
- res: Response
63
- ): string {
59
+ function requestEndLoggingFormat(tokens: MorganTokens, req: Request, res: Response): string {
64
60
  const status = res.statusCode;
65
61
  let statusStr = ':status';
66
62
  if (status >= 500) {
67
- statusStr = statusStr.red;
63
+ statusStr = console.styleText('red', statusStr);
68
64
  } else if (status >= 400) {
69
- statusStr = statusStr.yellow;
65
+ statusStr = console.styleText('yellow', statusStr);
70
66
  } else if (status >= 300) {
71
- statusStr = statusStr.cyan;
67
+ statusStr = console.styleText('cyan', statusStr);
72
68
  } else {
73
- statusStr = statusStr.green;
69
+ statusStr = console.styleText('green', statusStr);
74
70
  }
75
71
  const fn = compile(
76
- `${'<-- :method :url '.white}${statusStr} ${':response-time ms - :res[content-length]'.grey}`
72
+ `${console.styleText('white', '<-- :method :url ')}${statusStr} ${console.styleText('grey', ':response-time ms - :res[content-length]')}`,
77
73
  );
78
74
  return fn(tokens, req, res);
79
75
  }
80
76
 
81
77
  const requestStartLoggingFormat = compile(
82
- `${'-->'.white} ${':method'.white} ${':url'.white}`
78
+ `${console.styleText('white', '-->')} ${console.styleText('white', ':method')} ${console.styleText('white', ':url')}`,
83
79
  );
84
80
  // #endregion
@@ -1,6 +1,6 @@
1
1
  import {log} from './logger';
2
2
  import {LRUCache} from 'lru-cache';
3
- import _ from 'lodash';
3
+ import {util} from '@appium/support';
4
4
  import {EventEmitter} from 'node:events';
5
5
  import type {Request, Response, NextFunction} from 'express';
6
6
 
@@ -31,15 +31,15 @@ const MAX_CACHED_PAYLOAD_SIZE_BYTES = 1 * 1024 * 1024; // 1 MiB
31
31
  export async function handleIdempotency(
32
32
  req: Request,
33
33
  res: Response,
34
- next: NextFunction
34
+ next: NextFunction,
35
35
  ): Promise<void> {
36
36
  const keyOrArr = req.headers[IDEMPOTENCY_KEY_HEADER];
37
- if (_.isEmpty(keyOrArr) || !keyOrArr) {
37
+ if (util.isEmpty(keyOrArr) || !keyOrArr) {
38
38
  next();
39
39
  return;
40
40
  }
41
41
 
42
- const key = _.isArray(keyOrArr) ? keyOrArr[0] : keyOrArr;
42
+ const key = Array.isArray(keyOrArr) ? keyOrArr[0] : keyOrArr;
43
43
 
44
44
  log.updateAsyncContext({idempotencyKey: key});
45
45
 
@@ -114,7 +114,7 @@ function cacheResponse(key: string, req: Request, res: Response): void {
114
114
  const patchedWriter = (
115
115
  chunk: unknown,
116
116
  encoding: BufferEncoding | (() => void),
117
- next?: (() => void) | ((err?: Error) => void)
117
+ next?: (() => void) | ((err?: Error) => void),
118
118
  ): boolean => {
119
119
  if (errorMessage || !responseRef.deref()) {
120
120
  responseChunks = [];
@@ -122,7 +122,7 @@ function cacheResponse(key: string, req: Request, res: Response): void {
122
122
  return originalSocketWriter(
123
123
  chunk as string | Buffer | Uint8Array,
124
124
  encoding as BufferEncoding,
125
- next as (err?: Error) => void
125
+ next as (err?: Error | null) => void,
126
126
  );
127
127
  }
128
128
 
@@ -139,7 +139,7 @@ function cacheResponse(key: string, req: Request, res: Response): void {
139
139
  return originalSocketWriter(
140
140
  chunk as string | Buffer | Uint8Array,
141
141
  encoding as BufferEncoding,
142
- next as (err?: Error) => void
142
+ next as (err?: Error | null) => void,
143
143
  );
144
144
  };
145
145
  socket.write = patchedWriter as typeof socket.write;
@@ -153,7 +153,7 @@ function cacheResponse(key: string, req: Request, res: Response): void {
153
153
  if (!IDEMPOTENT_RESPONSES.has(key)) {
154
154
  log.info(
155
155
  `Could not cache the response identified by '${key}'. ` +
156
- `Cache consistency has been damaged`
156
+ `Cache consistency has been damaged`,
157
157
  );
158
158
  } else {
159
159
  log.info(`Could not cache the response identified by '${key}': ${errorMessage}`);
@@ -175,7 +175,7 @@ function cacheResponse(key: string, req: Request, res: Response): void {
175
175
  if (!IDEMPOTENT_RESPONSES.has(key)) {
176
176
  log.info(
177
177
  `Could not cache the response identified by '${key}'. ` +
178
- `Cache consistency has been damaged`
178
+ `Cache consistency has been damaged`,
179
179
  );
180
180
  } else if (errorMessage) {
181
181
  log.info(`Could not cache the response identified by '${key}': ${errorMessage}`);
@@ -1,4 +1,4 @@
1
- import _ from 'lodash';
1
+ import {util} from '@appium/support';
2
2
  import type {NextFunction, Request, RequestHandler, Response} from 'express';
3
3
  import type {IncomingMessage} from 'node:http';
4
4
  import type {Duplex} from 'node:stream';
@@ -6,7 +6,6 @@ import {log} from './logger';
6
6
  import {errors} from '../protocol';
7
7
  export {handleIdempotency} from './idempotency';
8
8
  import {match} from 'path-to-regexp';
9
- import {util} from '@appium/support';
10
9
  import {calcSignature} from '../helpers/session';
11
10
  import {getResponseForW3CError} from '../protocol/errors';
12
11
  import type {StringRecord, WSServer} from '@appium/types';
@@ -22,7 +21,7 @@ export function allowCrossDomain(req: Request, res: Response, next: NextFunction
22
21
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, OPTIONS, DELETE');
23
22
  res.header(
24
23
  'Access-Control-Allow-Headers',
25
- 'Cache-Control, Pragma, Origin, X-Requested-With, Content-Type, Accept, User-Agent'
24
+ 'Cache-Control, Pragma, Origin, X-Requested-With, Content-Type, Accept, User-Agent',
26
25
  );
27
26
 
28
27
  if (req.method === 'OPTIONS') {
@@ -43,10 +42,10 @@ export function allowCrossDomainAsyncExecute(basePath: string): RequestHandler {
43
42
  function allowCrossDomainAsyncExecuteHandler(
44
43
  req: Request,
45
44
  res: Response,
46
- next: NextFunction
45
+ next: NextFunction,
47
46
  ): void {
48
47
  const receiveAsyncResponseRegExp = new RegExp(
49
- `${_.escapeRegExp(basePath)}/session/[a-f0-9-]+/(appium/)?receive_async_response`
48
+ `${util.escapeRegExp(basePath)}/session/[a-f0-9-]+/(appium/)?receive_async_response`,
50
49
  );
51
50
  if (!receiveAsyncResponseRegExp.test(req.url)) {
52
51
  next();
@@ -73,9 +72,11 @@ export function handleLogContext(req: Request, _res: Response, next: NextFunctio
73
72
  {
74
73
  requestId,
75
74
  ...sessionInfo,
76
- isSensitive: ['true', '1', 'yes'].includes(_.toLower(isSensitiveHeaderValue)),
75
+ isSensitive: ['true', '1', 'yes'].includes(
76
+ String(isSensitiveHeaderValue ?? '').toLowerCase(),
77
+ ),
77
78
  },
78
- true
79
+ true,
79
80
  );
80
81
 
81
82
  next();
@@ -84,11 +85,7 @@ export function handleLogContext(req: Request, _res: Response, next: NextFunctio
84
85
  /**
85
86
  * Ensures requests default to JSON content-type when none is provided.
86
87
  */
87
- export function defaultToJSONContentType(
88
- req: Request,
89
- _res: Response,
90
- next: NextFunction
91
- ): void {
88
+ export function defaultToJSONContentType(req: Request, _res: Response, next: NextFunction): void {
92
89
  if (!req.headers['content-type']) {
93
90
  req.headers['content-type'] = 'application/json; charset=utf-8';
94
91
  }
@@ -108,9 +105,9 @@ export function tryHandleWebSocketUpgrade(
108
105
  req: IncomingMessage,
109
106
  socket: Duplex,
110
107
  head: Buffer,
111
- webSocketsMapping: StringRecord<WSServer>
108
+ webSocketsMapping: StringRecord<WSServer>,
112
109
  ): boolean {
113
- if (_.toLower(req.headers?.upgrade) !== 'websocket') {
110
+ if (String(req.headers?.upgrade ?? '').toLowerCase() !== 'websocket') {
114
111
  return false;
115
112
  }
116
113
 
@@ -120,7 +117,7 @@ export function tryHandleWebSocketUpgrade(
120
117
  } catch {
121
118
  currentPathname = req.url ?? '';
122
119
  }
123
- for (const [pathname, wsServer] of _.toPairs(webSocketsMapping)) {
120
+ for (const [pathname, wsServer] of Object.entries(webSocketsMapping)) {
124
121
  if (match(pathname)(currentPathname)) {
125
122
  wsServer.handleUpgrade(req, socket, head, (ws) => {
126
123
  wsServer.emit('connection', ws, req);
@@ -158,7 +155,7 @@ export function catchAllHandler(
158
155
  err: Error,
159
156
  _req: Request,
160
157
  res: Response,
161
- next: NextFunction
158
+ next: NextFunction,
162
159
  ): void {
163
160
  if (res.headersSent) {
164
161
  next(err);
@@ -182,6 +179,5 @@ export function catch404Handler(req: Request, res: Response): void {
182
179
 
183
180
  function fetchHeaderValue(req: Request, name: string): string | undefined {
184
181
  const value = req.headers[name];
185
- return _.isArray(value) ? value[0] : (value as string | undefined);
182
+ return Array.isArray(value) ? value[0] : (value as string | undefined);
186
183
  }
187
-