@qapilot/appium-module 1.0.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 (219) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +269 -0
  3. package/dist/commands/actions/perform-actions.command.d.ts +16 -0
  4. package/dist/commands/actions/perform-actions.command.d.ts.map +1 -0
  5. package/dist/commands/actions/perform-actions.command.js +23 -0
  6. package/dist/commands/actions/perform-actions.command.js.map +1 -0
  7. package/dist/commands/actions/touch-perform.command.d.ts +21 -0
  8. package/dist/commands/actions/touch-perform.command.d.ts.map +1 -0
  9. package/dist/commands/actions/touch-perform.command.js +28 -0
  10. package/dist/commands/actions/touch-perform.command.js.map +1 -0
  11. package/dist/commands/base.command.d.ts +36 -0
  12. package/dist/commands/base.command.d.ts.map +1 -0
  13. package/dist/commands/base.command.js +41 -0
  14. package/dist/commands/base.command.js.map +1 -0
  15. package/dist/commands/command.registry.d.ts +12 -0
  16. package/dist/commands/command.registry.d.ts.map +1 -0
  17. package/dist/commands/command.registry.js +111 -0
  18. package/dist/commands/command.registry.js.map +1 -0
  19. package/dist/commands/context/get-context.command.d.ts +13 -0
  20. package/dist/commands/context/get-context.command.d.ts.map +1 -0
  21. package/dist/commands/context/get-context.command.js +14 -0
  22. package/dist/commands/context/get-context.command.js.map +1 -0
  23. package/dist/commands/context/get-contexts.command.d.ts +13 -0
  24. package/dist/commands/context/get-contexts.command.d.ts.map +1 -0
  25. package/dist/commands/context/get-contexts.command.js +17 -0
  26. package/dist/commands/context/get-contexts.command.js.map +1 -0
  27. package/dist/commands/context/set-context.command.d.ts +17 -0
  28. package/dist/commands/context/set-context.command.d.ts.map +1 -0
  29. package/dist/commands/context/set-context.command.js +27 -0
  30. package/dist/commands/context/set-context.command.js.map +1 -0
  31. package/dist/commands/device/activate-app.command.d.ts +16 -0
  32. package/dist/commands/device/activate-app.command.d.ts.map +1 -0
  33. package/dist/commands/device/activate-app.command.js +23 -0
  34. package/dist/commands/device/activate-app.command.js.map +1 -0
  35. package/dist/commands/device/hide-keyboard.command.d.ts +17 -0
  36. package/dist/commands/device/hide-keyboard.command.d.ts.map +1 -0
  37. package/dist/commands/device/hide-keyboard.command.js +18 -0
  38. package/dist/commands/device/hide-keyboard.command.js.map +1 -0
  39. package/dist/commands/device/is-keyboard-shown.command.d.ts +13 -0
  40. package/dist/commands/device/is-keyboard-shown.command.d.ts.map +1 -0
  41. package/dist/commands/device/is-keyboard-shown.command.js +14 -0
  42. package/dist/commands/device/is-keyboard-shown.command.js.map +1 -0
  43. package/dist/commands/device/press-keycode.command.d.ts +19 -0
  44. package/dist/commands/device/press-keycode.command.d.ts.map +1 -0
  45. package/dist/commands/device/press-keycode.command.js +28 -0
  46. package/dist/commands/device/press-keycode.command.js.map +1 -0
  47. package/dist/commands/device/set-location.command.d.ts +16 -0
  48. package/dist/commands/device/set-location.command.d.ts.map +1 -0
  49. package/dist/commands/device/set-location.command.js +24 -0
  50. package/dist/commands/device/set-location.command.js.map +1 -0
  51. package/dist/commands/device/set-orientation.command.d.ts +16 -0
  52. package/dist/commands/device/set-orientation.command.d.ts.map +1 -0
  53. package/dist/commands/device/set-orientation.command.js +23 -0
  54. package/dist/commands/device/set-orientation.command.js.map +1 -0
  55. package/dist/commands/device/terminate-app.command.d.ts +16 -0
  56. package/dist/commands/device/terminate-app.command.d.ts.map +1 -0
  57. package/dist/commands/device/terminate-app.command.js +23 -0
  58. package/dist/commands/device/terminate-app.command.js.map +1 -0
  59. package/dist/commands/element/clear-element.command.d.ts +14 -0
  60. package/dist/commands/element/clear-element.command.d.ts.map +1 -0
  61. package/dist/commands/element/clear-element.command.js +13 -0
  62. package/dist/commands/element/clear-element.command.js.map +1 -0
  63. package/dist/commands/element/click-element.command.d.ts +14 -0
  64. package/dist/commands/element/click-element.command.d.ts.map +1 -0
  65. package/dist/commands/element/click-element.command.js +13 -0
  66. package/dist/commands/element/click-element.command.js.map +1 -0
  67. package/dist/commands/element/find-element.command.d.ts +17 -0
  68. package/dist/commands/element/find-element.command.d.ts.map +1 -0
  69. package/dist/commands/element/find-element.command.js +36 -0
  70. package/dist/commands/element/find-element.command.js.map +1 -0
  71. package/dist/commands/element/find-elements.command.d.ts +17 -0
  72. package/dist/commands/element/find-elements.command.d.ts.map +1 -0
  73. package/dist/commands/element/find-elements.command.js +39 -0
  74. package/dist/commands/element/find-elements.command.js.map +1 -0
  75. package/dist/commands/element/get-element-attribute.command.d.ts +16 -0
  76. package/dist/commands/element/get-element-attribute.command.d.ts.map +1 -0
  77. package/dist/commands/element/get-element-attribute.command.js +25 -0
  78. package/dist/commands/element/get-element-attribute.command.js.map +1 -0
  79. package/dist/commands/element/get-element-displayed.command.d.ts +14 -0
  80. package/dist/commands/element/get-element-displayed.command.d.ts.map +1 -0
  81. package/dist/commands/element/get-element-displayed.command.js +14 -0
  82. package/dist/commands/element/get-element-displayed.command.js.map +1 -0
  83. package/dist/commands/element/get-element-location.command.d.ts +15 -0
  84. package/dist/commands/element/get-element-location.command.d.ts.map +1 -0
  85. package/dist/commands/element/get-element-location.command.js +18 -0
  86. package/dist/commands/element/get-element-location.command.js.map +1 -0
  87. package/dist/commands/element/get-element-rect.command.d.ts +15 -0
  88. package/dist/commands/element/get-element-rect.command.d.ts.map +1 -0
  89. package/dist/commands/element/get-element-rect.command.js +20 -0
  90. package/dist/commands/element/get-element-rect.command.js.map +1 -0
  91. package/dist/commands/element/get-element-size.command.d.ts +15 -0
  92. package/dist/commands/element/get-element-size.command.d.ts.map +1 -0
  93. package/dist/commands/element/get-element-size.command.js +18 -0
  94. package/dist/commands/element/get-element-size.command.js.map +1 -0
  95. package/dist/commands/element/get-element-text.command.d.ts +14 -0
  96. package/dist/commands/element/get-element-text.command.d.ts.map +1 -0
  97. package/dist/commands/element/get-element-text.command.js +14 -0
  98. package/dist/commands/element/get-element-text.command.js.map +1 -0
  99. package/dist/commands/element/set-value.command.d.ts +16 -0
  100. package/dist/commands/element/set-value.command.d.ts.map +1 -0
  101. package/dist/commands/element/set-value.command.js +27 -0
  102. package/dist/commands/element/set-value.command.js.map +1 -0
  103. package/dist/commands/page/get-screenshot.command.d.ts +14 -0
  104. package/dist/commands/page/get-screenshot.command.d.ts.map +1 -0
  105. package/dist/commands/page/get-screenshot.command.js +15 -0
  106. package/dist/commands/page/get-screenshot.command.js.map +1 -0
  107. package/dist/commands/page/get-source.command.d.ts +13 -0
  108. package/dist/commands/page/get-source.command.d.ts.map +1 -0
  109. package/dist/commands/page/get-source.command.js +14 -0
  110. package/dist/commands/page/get-source.command.js.map +1 -0
  111. package/dist/commands/script/execute-script-sync.command.d.ts +20 -0
  112. package/dist/commands/script/execute-script-sync.command.d.ts.map +1 -0
  113. package/dist/commands/script/execute-script-sync.command.js +31 -0
  114. package/dist/commands/script/execute-script-sync.command.js.map +1 -0
  115. package/dist/commands/script/execute-script.command.d.ts +16 -0
  116. package/dist/commands/script/execute-script.command.d.ts.map +1 -0
  117. package/dist/commands/script/execute-script.command.js +27 -0
  118. package/dist/commands/script/execute-script.command.js.map +1 -0
  119. package/dist/commands/session/create-session.command.d.ts +16 -0
  120. package/dist/commands/session/create-session.command.d.ts.map +1 -0
  121. package/dist/commands/session/create-session.command.js +39 -0
  122. package/dist/commands/session/create-session.command.js.map +1 -0
  123. package/dist/commands/session/delete-session.command.d.ts +13 -0
  124. package/dist/commands/session/delete-session.command.d.ts.map +1 -0
  125. package/dist/commands/session/delete-session.command.js +13 -0
  126. package/dist/commands/session/delete-session.command.js.map +1 -0
  127. package/dist/commands/session/get-session.command.d.ts +14 -0
  128. package/dist/commands/session/get-session.command.d.ts.map +1 -0
  129. package/dist/commands/session/get-session.command.js +18 -0
  130. package/dist/commands/session/get-session.command.js.map +1 -0
  131. package/dist/commands/window/get-window-handles.command.d.ts +13 -0
  132. package/dist/commands/window/get-window-handles.command.d.ts.map +1 -0
  133. package/dist/commands/window/get-window-handles.command.js +17 -0
  134. package/dist/commands/window/get-window-handles.command.js.map +1 -0
  135. package/dist/commands/window/get-window.command.d.ts +13 -0
  136. package/dist/commands/window/get-window.command.d.ts.map +1 -0
  137. package/dist/commands/window/get-window.command.js +14 -0
  138. package/dist/commands/window/get-window.command.js.map +1 -0
  139. package/dist/commands/window/switch-window.command.d.ts +15 -0
  140. package/dist/commands/window/switch-window.command.d.ts.map +1 -0
  141. package/dist/commands/window/switch-window.command.js +23 -0
  142. package/dist/commands/window/switch-window.command.js.map +1 -0
  143. package/dist/http/middleware/error-handler.d.ts +3 -0
  144. package/dist/http/middleware/error-handler.d.ts.map +1 -0
  145. package/dist/http/middleware/error-handler.js +29 -0
  146. package/dist/http/middleware/error-handler.js.map +1 -0
  147. package/dist/http/middleware/request-validator.d.ts +3 -0
  148. package/dist/http/middleware/request-validator.d.ts.map +1 -0
  149. package/dist/http/middleware/request-validator.js +37 -0
  150. package/dist/http/middleware/request-validator.js.map +1 -0
  151. package/dist/http/router.d.ts +3 -0
  152. package/dist/http/router.d.ts.map +1 -0
  153. package/dist/http/router.js +43 -0
  154. package/dist/http/router.js.map +1 -0
  155. package/dist/index.d.ts +19 -0
  156. package/dist/index.d.ts.map +1 -0
  157. package/dist/index.js +19 -0
  158. package/dist/index.js.map +1 -0
  159. package/dist/invoker/command-invoker.d.ts +3 -0
  160. package/dist/invoker/command-invoker.d.ts.map +1 -0
  161. package/dist/invoker/command-invoker.js +94 -0
  162. package/dist/invoker/command-invoker.js.map +1 -0
  163. package/dist/logger/index.d.ts +4 -0
  164. package/dist/logger/index.d.ts.map +1 -0
  165. package/dist/logger/index.js +19 -0
  166. package/dist/logger/index.js.map +1 -0
  167. package/dist/providers/base.provider.d.ts +11 -0
  168. package/dist/providers/base.provider.d.ts.map +1 -0
  169. package/dist/providers/base.provider.js +51 -0
  170. package/dist/providers/base.provider.js.map +1 -0
  171. package/dist/providers/browserstack/browserstack.config.d.ts +11 -0
  172. package/dist/providers/browserstack/browserstack.config.d.ts.map +1 -0
  173. package/dist/providers/browserstack/browserstack.config.js +32 -0
  174. package/dist/providers/browserstack/browserstack.config.js.map +1 -0
  175. package/dist/providers/browserstack/browserstack.provider.d.ts +15 -0
  176. package/dist/providers/browserstack/browserstack.provider.d.ts.map +1 -0
  177. package/dist/providers/browserstack/browserstack.provider.js +80 -0
  178. package/dist/providers/browserstack/browserstack.provider.js.map +1 -0
  179. package/dist/providers/lambdatest/lambdatest.config.d.ts +11 -0
  180. package/dist/providers/lambdatest/lambdatest.config.d.ts.map +1 -0
  181. package/dist/providers/lambdatest/lambdatest.config.js +28 -0
  182. package/dist/providers/lambdatest/lambdatest.config.js.map +1 -0
  183. package/dist/providers/lambdatest/lambdatest.provider.d.ts +15 -0
  184. package/dist/providers/lambdatest/lambdatest.provider.d.ts.map +1 -0
  185. package/dist/providers/lambdatest/lambdatest.provider.js +74 -0
  186. package/dist/providers/lambdatest/lambdatest.provider.js.map +1 -0
  187. package/dist/providers/local/local.provider.d.ts +15 -0
  188. package/dist/providers/local/local.provider.d.ts.map +1 -0
  189. package/dist/providers/local/local.provider.js +40 -0
  190. package/dist/providers/local/local.provider.js.map +1 -0
  191. package/dist/providers/provider.factory.d.ts +10 -0
  192. package/dist/providers/provider.factory.d.ts.map +1 -0
  193. package/dist/providers/provider.factory.js +32 -0
  194. package/dist/providers/provider.factory.js.map +1 -0
  195. package/dist/providers/provider.interface.d.ts +30 -0
  196. package/dist/providers/provider.interface.d.ts.map +1 -0
  197. package/dist/providers/provider.interface.js +2 -0
  198. package/dist/providers/provider.interface.js.map +1 -0
  199. package/dist/server.d.ts +2 -0
  200. package/dist/server.d.ts.map +1 -0
  201. package/dist/server.js +13 -0
  202. package/dist/server.js.map +1 -0
  203. package/dist/types/command.types.d.ts +24 -0
  204. package/dist/types/command.types.d.ts.map +1 -0
  205. package/dist/types/command.types.js +2 -0
  206. package/dist/types/command.types.js.map +1 -0
  207. package/dist/types/error.types.d.ts +25 -0
  208. package/dist/types/error.types.d.ts.map +1 -0
  209. package/dist/types/error.types.js +26 -0
  210. package/dist/types/error.types.js.map +1 -0
  211. package/dist/types/provider.types.d.ts +13 -0
  212. package/dist/types/provider.types.d.ts.map +1 -0
  213. package/dist/types/provider.types.js +2 -0
  214. package/dist/types/provider.types.js.map +1 -0
  215. package/dist/types/webdriver.types.d.ts +55 -0
  216. package/dist/types/webdriver.types.d.ts.map +1 -0
  217. package/dist/types/webdriver.types.js +4 -0
  218. package/dist/types/webdriver.types.js.map +1 -0
  219. package/package.json +66 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.provider.d.ts","sourceRoot":"","sources":["../../src/providers/base.provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAYtE,8BAAsB,YAAY;IAChC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC/C,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE9C,SAAS,CAAC,YAAY,CAAC,WAAW,EAAE,mBAAmB,GAAG,MAAM;IAOhE,SAAS,CAAC,oBAAoB,CAAC,WAAW,EAAE,mBAAmB,GAAG,MAAM;IAMxE,SAAS,CAAC,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,kBAAkB;IAgB5E,OAAO,CAAC,qBAAqB;CAc9B"}
@@ -0,0 +1,51 @@
1
+ import { AppiumErrorCode } from '../types/error.types.js';
2
+ // W3C WebDriver error status codes to our error codes
3
+ const W3C_ERROR_MAP = {
4
+ 'no such session': AppiumErrorCode.SESSION_NOT_FOUND,
5
+ 'no such element': AppiumErrorCode.ELEMENT_NOT_FOUND,
6
+ 'invalid selector': AppiumErrorCode.INVALID_SELECTOR,
7
+ 'stale element reference': AppiumErrorCode.STALE_ELEMENT,
8
+ 'timeout': AppiumErrorCode.COMMAND_TIMEOUT,
9
+ 'script timeout': AppiumErrorCode.COMMAND_TIMEOUT,
10
+ };
11
+ export class BaseProvider {
12
+ buildBaseUrl(credentials) {
13
+ if (credentials.hubUrl) {
14
+ return credentials.hubUrl.replace(/\/$/, '');
15
+ }
16
+ return `${this.hubBaseUrl}${this.wdHubPath}`;
17
+ }
18
+ buildBasicAuthHeader(credentials) {
19
+ const user = credentials.username ?? '';
20
+ const key = credentials.accessKey ?? '';
21
+ return `Basic ${Buffer.from(`${user}:${key}`).toString('base64')}`;
22
+ }
23
+ mapW3CError(statusCode, body) {
24
+ const errorBody = body;
25
+ const value = errorBody?.['value'];
26
+ const errorMessage = value?.['message'] ?? 'Unknown error';
27
+ const errorCode = value?.['error'] ?? '';
28
+ const mappedCode = W3C_ERROR_MAP[errorCode] ?? this.httpStatusToErrorCode(statusCode);
29
+ return {
30
+ code: mappedCode,
31
+ message: errorMessage,
32
+ httpStatus: statusCode,
33
+ raw: body,
34
+ };
35
+ }
36
+ httpStatusToErrorCode(statusCode) {
37
+ switch (statusCode) {
38
+ case 404:
39
+ return AppiumErrorCode.SESSION_NOT_FOUND;
40
+ case 408:
41
+ return AppiumErrorCode.COMMAND_TIMEOUT;
42
+ case 500:
43
+ return AppiumErrorCode.PROVIDER_ERROR;
44
+ case 503:
45
+ return AppiumErrorCode.PROVIDER_UNREACHABLE;
46
+ default:
47
+ return AppiumErrorCode.UNKNOWN_ERROR;
48
+ }
49
+ }
50
+ }
51
+ //# sourceMappingURL=base.provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.provider.js","sourceRoot":"","sources":["../../src/providers/base.provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAA2B,MAAM,yBAAyB,CAAC;AAGnF,sDAAsD;AACtD,MAAM,aAAa,GAAoC;IACrD,iBAAiB,EAAE,eAAe,CAAC,iBAAiB;IACpD,iBAAiB,EAAE,eAAe,CAAC,iBAAiB;IACpD,kBAAkB,EAAE,eAAe,CAAC,gBAAgB;IACpD,yBAAyB,EAAE,eAAe,CAAC,aAAa;IACxD,SAAS,EAAE,eAAe,CAAC,eAAe;IAC1C,gBAAgB,EAAE,eAAe,CAAC,eAAe;CAClD,CAAC;AAEF,MAAM,OAAgB,YAAY;IAItB,YAAY,CAAC,WAAgC;QACrD,IAAI,WAAW,CAAC,MAAM,EAAE,CAAC;YACvB,OAAO,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;IAC/C,CAAC;IAES,oBAAoB,CAAC,WAAgC;QAC7D,MAAM,IAAI,GAAG,WAAW,CAAC,QAAQ,IAAI,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,WAAW,CAAC,SAAS,IAAI,EAAE,CAAC;QACxC,OAAO,SAAS,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;IACrE,CAAC;IAES,WAAW,CAAC,UAAkB,EAAE,IAAa;QACrD,MAAM,SAAS,GAAG,IAAsC,CAAC;QACzD,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC,OAAO,CAAmC,CAAC;QACrE,MAAM,YAAY,GAAI,KAAK,EAAE,CAAC,SAAS,CAAY,IAAI,eAAe,CAAC;QACvE,MAAM,SAAS,GAAI,KAAK,EAAE,CAAC,OAAO,CAAY,IAAI,EAAE,CAAC;QAErD,MAAM,UAAU,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,CAAC;QAEtF,OAAO;YACL,IAAI,EAAE,UAAU;YAChB,OAAO,EAAE,YAAY;YACrB,UAAU,EAAE,UAAU;YACtB,GAAG,EAAE,IAAI;SACV,CAAC;IACJ,CAAC;IAEO,qBAAqB,CAAC,UAAkB;QAC9C,QAAQ,UAAU,EAAE,CAAC;YACnB,KAAK,GAAG;gBACN,OAAO,eAAe,CAAC,iBAAiB,CAAC;YAC3C,KAAK,GAAG;gBACN,OAAO,eAAe,CAAC,eAAe,CAAC;YACzC,KAAK,GAAG;gBACN,OAAO,eAAe,CAAC,cAAc,CAAC;YACxC,KAAK,GAAG;gBACN,OAAO,eAAe,CAAC,oBAAoB,CAAC;YAC9C;gBACE,OAAO,eAAe,CAAC,aAAa,CAAC;QACzC,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ export declare const BROWSERSTACK_CONFIG: {
2
+ readonly hubBaseUrl: "https://hub-cloud.browserstack.com";
3
+ readonly wdHubPath: "/wd/hub";
4
+ readonly optionsKey: "bstack:options";
5
+ };
6
+ /**
7
+ * Default capabilities applied to every BrowserStack session.
8
+ * User-supplied capabilities always override these.
9
+ */
10
+ export declare const BROWSERSTACK_DEFAULT_CAPS: Record<string, unknown>;
11
+ //# sourceMappingURL=browserstack.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browserstack.config.d.ts","sourceRoot":"","sources":["../../../src/providers/browserstack/browserstack.config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB;;;;CAItB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAuB7D,CAAC"}
@@ -0,0 +1,32 @@
1
+ export const BROWSERSTACK_CONFIG = {
2
+ hubBaseUrl: 'https://hub-cloud.browserstack.com',
3
+ wdHubPath: '/wd/hub',
4
+ optionsKey: 'bstack:options',
5
+ };
6
+ /**
7
+ * Default capabilities applied to every BrowserStack session.
8
+ * User-supplied capabilities always override these.
9
+ */
10
+ export const BROWSERSTACK_DEFAULT_CAPS = {
11
+ // Session stability
12
+ newCommandTimeout: 120000,
13
+ autoGrantPermissions: true,
14
+ noReset: false,
15
+ fullReset: false,
16
+ unicodeKeyboard: true,
17
+ appWaitActivity: '*',
18
+ // UI / rendering
19
+ disableWindowAnimation: true,
20
+ deviceOrientation: 'portrait',
21
+ screenshotQuality: 1,
22
+ allowInvisibleElements: false,
23
+ // BrowserStack-specific (normalized into bstack:options)
24
+ 'browserstack.idleTimeout': 300,
25
+ 'browserstack.video': 'true',
26
+ 'browserstack.debug': true,
27
+ 'browserstack.networkLogs': 'false',
28
+ interactiveDebugging: false,
29
+ disableAnimations: true,
30
+ acceptInsecureCerts: true,
31
+ };
32
+ //# sourceMappingURL=browserstack.config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browserstack.config.js","sourceRoot":"","sources":["../../../src/providers/browserstack/browserstack.config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,UAAU,EAAE,oCAAoC;IAChD,SAAS,EAAE,SAAS;IACpB,UAAU,EAAE,gBAAgB;CACpB,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAA4B;IAChE,oBAAoB;IACpB,iBAAiB,EAAE,MAAM;IACzB,oBAAoB,EAAE,IAAI;IAC1B,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,KAAK;IAChB,eAAe,EAAE,IAAI;IACrB,eAAe,EAAE,GAAG;IAEpB,iBAAiB;IACjB,sBAAsB,EAAE,IAAI;IAC5B,iBAAiB,EAAE,UAAU;IAC7B,iBAAiB,EAAE,CAAC;IACpB,sBAAsB,EAAE,KAAK;IAE7B,yDAAyD;IACzD,0BAA0B,EAAE,GAAG;IAC/B,oBAAoB,EAAE,MAAM;IAC5B,oBAAoB,EAAE,IAAI;IAC1B,0BAA0B,EAAE,OAAO;IACnC,oBAAoB,EAAE,KAAK;IAC3B,iBAAiB,EAAE,IAAI;IACvB,mBAAmB,EAAE,IAAI;CAC1B,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { AppiumServiceError } from '../../types/error.types.js';
2
+ import type { ProviderCredentials, ProviderName } from '../../types/provider.types.js';
3
+ import { BaseProvider } from '../base.provider.js';
4
+ import type { IAppiumProvider } from '../provider.interface.js';
5
+ export declare class BrowserStackProvider extends BaseProvider implements IAppiumProvider {
6
+ readonly name: ProviderName;
7
+ protected readonly hubBaseUrl: "https://hub-cloud.browserstack.com";
8
+ protected readonly wdHubPath: "/wd/hub";
9
+ buildUrl(_sessionId: string | null, path: string, credentials: ProviderCredentials): string;
10
+ buildHeaders(credentials: ProviderCredentials): Record<string, string>;
11
+ normalizeCapabilities(caps: Record<string, unknown>): Record<string, unknown>;
12
+ normalizeError(statusCode: number, body: unknown): AppiumServiceError;
13
+ getDefaultCapabilities(): Record<string, unknown>;
14
+ }
15
+ //# sourceMappingURL=browserstack.provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browserstack.provider.d.ts","sourceRoot":"","sources":["../../../src/providers/browserstack/browserstack.provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACvF,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAoChE,qBAAa,oBAAqB,SAAQ,YAAa,YAAW,eAAe;IAC/E,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAkB;IAC7C,SAAS,CAAC,QAAQ,CAAC,UAAU,uCAAkC;IAC/D,SAAS,CAAC,QAAQ,CAAC,SAAS,YAAiC;IAE7D,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,mBAAmB,GAAG,MAAM;IAK3F,YAAY,CAAC,WAAW,EAAE,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAOtE,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAyB7E,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,kBAAkB;IAIrE,sBAAsB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAGlD"}
@@ -0,0 +1,80 @@
1
+ import { BaseProvider } from '../base.provider.js';
2
+ import { BROWSERSTACK_CONFIG, BROWSERSTACK_DEFAULT_CAPS } from './browserstack.config.js';
3
+ // These keys are moved into bstack:options when normalizing capabilities
4
+ const BSTACK_SPECIFIC_KEYS = new Set([
5
+ 'browserstack.user',
6
+ 'browserstack.key',
7
+ 'browserstack.debug',
8
+ 'browserstack.networkLogs',
9
+ 'browserstack.console',
10
+ 'browserstack.video',
11
+ 'browserstack.local',
12
+ 'browserstack.localIdentifier',
13
+ 'browserstack.appiumVersion',
14
+ 'browserstack.idleTimeout',
15
+ 'browserstack.maskCommands',
16
+ 'build',
17
+ 'name',
18
+ 'project',
19
+ 'sessionName',
20
+ 'buildTag',
21
+ 'geoLocation',
22
+ 'timezone',
23
+ 'networkProfile',
24
+ 'customNetwork',
25
+ 'realMobile',
26
+ 'enablePasscode',
27
+ 'resignApp',
28
+ 'acceptInsecureCerts',
29
+ 'wsLocalSupport',
30
+ 'disableAnimations',
31
+ 'interactiveDebugging',
32
+ 'uploadMedia',
33
+ 'midSessionInstallApps',
34
+ ]);
35
+ export class BrowserStackProvider extends BaseProvider {
36
+ name = 'browserstack';
37
+ hubBaseUrl = BROWSERSTACK_CONFIG.hubBaseUrl;
38
+ wdHubPath = BROWSERSTACK_CONFIG.wdHubPath;
39
+ buildUrl(_sessionId, path, credentials) {
40
+ const base = this.buildBaseUrl(credentials);
41
+ return `${base}${path}`;
42
+ }
43
+ buildHeaders(credentials) {
44
+ return {
45
+ 'Content-Type': 'application/json',
46
+ Authorization: this.buildBasicAuthHeader(credentials),
47
+ };
48
+ }
49
+ normalizeCapabilities(caps) {
50
+ const bstackOptions = {
51
+ ...caps[BROWSERSTACK_CONFIG.optionsKey],
52
+ };
53
+ const rest = {};
54
+ for (const [key, value] of Object.entries(caps)) {
55
+ if (key === BROWSERSTACK_CONFIG.optionsKey)
56
+ continue;
57
+ if (BSTACK_SPECIFIC_KEYS.has(key)) {
58
+ // Strip "browserstack." prefix when moving into bstack:options
59
+ const normalizedKey = key.startsWith('browserstack.')
60
+ ? key.slice('browserstack.'.length)
61
+ : key;
62
+ bstackOptions[normalizedKey] = value;
63
+ }
64
+ else {
65
+ rest[key] = value;
66
+ }
67
+ }
68
+ return {
69
+ ...rest,
70
+ [BROWSERSTACK_CONFIG.optionsKey]: bstackOptions,
71
+ };
72
+ }
73
+ normalizeError(statusCode, body) {
74
+ return this.mapW3CError(statusCode, body);
75
+ }
76
+ getDefaultCapabilities() {
77
+ return { ...BROWSERSTACK_DEFAULT_CAPS };
78
+ }
79
+ }
80
+ //# sourceMappingURL=browserstack.provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browserstack.provider.js","sourceRoot":"","sources":["../../../src/providers/browserstack/browserstack.provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAE1F,yEAAyE;AACzE,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,mBAAmB;IACnB,kBAAkB;IAClB,oBAAoB;IACpB,0BAA0B;IAC1B,sBAAsB;IACtB,oBAAoB;IACpB,oBAAoB;IACpB,8BAA8B;IAC9B,4BAA4B;IAC5B,0BAA0B;IAC1B,2BAA2B;IAC3B,OAAO;IACP,MAAM;IACN,SAAS;IACT,aAAa;IACb,UAAU;IACV,aAAa;IACb,UAAU;IACV,gBAAgB;IAChB,eAAe;IACf,YAAY;IACZ,gBAAgB;IAChB,WAAW;IACX,qBAAqB;IACrB,gBAAgB;IAChB,mBAAmB;IACnB,sBAAsB;IACtB,aAAa;IACb,uBAAuB;CACxB,CAAC,CAAC;AAEH,MAAM,OAAO,oBAAqB,SAAQ,YAAY;IAC3C,IAAI,GAAiB,cAAc,CAAC;IAC1B,UAAU,GAAG,mBAAmB,CAAC,UAAU,CAAC;IAC5C,SAAS,GAAG,mBAAmB,CAAC,SAAS,CAAC;IAE7D,QAAQ,CAAC,UAAyB,EAAE,IAAY,EAAE,WAAgC;QAChF,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QAC5C,OAAO,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED,YAAY,CAAC,WAAgC;QAC3C,OAAO;YACL,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC;SACtD,CAAC;IACJ,CAAC;IAED,qBAAqB,CAAC,IAA6B;QACjD,MAAM,aAAa,GAA4B;YAC7C,GAAI,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAyC;SACjF,CAAC;QACF,MAAM,IAAI,GAA4B,EAAE,CAAC;QAEzC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,IAAI,GAAG,KAAK,mBAAmB,CAAC,UAAU;gBAAE,SAAS;YACrD,IAAI,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClC,+DAA+D;gBAC/D,MAAM,aAAa,GAAG,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC;oBACnD,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC;oBACnC,CAAC,CAAC,GAAG,CAAC;gBACR,aAAa,CAAC,aAAa,CAAC,GAAG,KAAK,CAAC;YACvC,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACpB,CAAC;QACH,CAAC;QAED,OAAO;YACL,GAAG,IAAI;YACP,CAAC,mBAAmB,CAAC,UAAU,CAAC,EAAE,aAAa;SAChD,CAAC;IACJ,CAAC;IAED,cAAc,CAAC,UAAkB,EAAE,IAAa;QAC9C,OAAO,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,sBAAsB;QACpB,OAAO,EAAE,GAAG,yBAAyB,EAAE,CAAC;IAC1C,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ export declare const LAMBDATEST_CONFIG: {
2
+ readonly hubBaseUrl: "https://mobile-hub.lambdatest.com";
3
+ readonly wdHubPath: "/wd/hub";
4
+ readonly optionsKey: "lt:options";
5
+ };
6
+ /**
7
+ * Default capabilities applied to every LambdaTest session.
8
+ * User-supplied capabilities always override these.
9
+ */
10
+ export declare const LAMBDATEST_DEFAULT_CAPS: Record<string, unknown>;
11
+ //# sourceMappingURL=lambdatest.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lambdatest.config.d.ts","sourceRoot":"","sources":["../../../src/providers/lambdatest/lambdatest.config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB;;;;CAIpB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAkB3D,CAAC"}
@@ -0,0 +1,28 @@
1
+ export const LAMBDATEST_CONFIG = {
2
+ hubBaseUrl: 'https://mobile-hub.lambdatest.com',
3
+ wdHubPath: '/wd/hub',
4
+ optionsKey: 'lt:options',
5
+ };
6
+ /**
7
+ * Default capabilities applied to every LambdaTest session.
8
+ * User-supplied capabilities always override these.
9
+ */
10
+ export const LAMBDATEST_DEFAULT_CAPS = {
11
+ // UI / rendering
12
+ disableWindowAnimation: true,
13
+ deviceOrientation: 'portrait',
14
+ allowInvisibleElements: false,
15
+ // LambdaTest-specific (normalized into lt:options)
16
+ devicelog: true,
17
+ video: true,
18
+ network: false,
19
+ isRealMobile: true,
20
+ idleTimeout: 300,
21
+ dedicatedProxy: true,
22
+ ignoreUnimportantViews: true,
23
+ appProfiling: true,
24
+ eventTimings: true,
25
+ autoGrantPermissions: true,
26
+ autoAcceptAlerts: true,
27
+ };
28
+ //# sourceMappingURL=lambdatest.config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lambdatest.config.js","sourceRoot":"","sources":["../../../src/providers/lambdatest/lambdatest.config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,UAAU,EAAE,mCAAmC;IAC/C,SAAS,EAAE,SAAS;IACpB,UAAU,EAAE,YAAY;CAChB,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAA4B;IAC9D,iBAAiB;IACjB,sBAAsB,EAAE,IAAI;IAC5B,iBAAiB,EAAE,UAAU;IAC7B,sBAAsB,EAAE,KAAK;IAE7B,mDAAmD;IACnD,SAAS,EAAE,IAAI;IACf,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,KAAK;IACd,YAAY,EAAE,IAAI;IAClB,WAAW,EAAE,GAAG;IAChB,cAAc,EAAE,IAAI;IACpB,sBAAsB,EAAE,IAAI;IAC5B,YAAY,EAAE,IAAI;IAClB,YAAY,EAAE,IAAI;IAClB,oBAAoB,EAAE,IAAI;IAC1B,gBAAgB,EAAE,IAAI;CACvB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { AppiumServiceError } from '../../types/error.types.js';
2
+ import type { ProviderCredentials, ProviderName } from '../../types/provider.types.js';
3
+ import { BaseProvider } from '../base.provider.js';
4
+ import type { IAppiumProvider } from '../provider.interface.js';
5
+ export declare class LambdaTestProvider extends BaseProvider implements IAppiumProvider {
6
+ readonly name: ProviderName;
7
+ protected readonly hubBaseUrl: "https://mobile-hub.lambdatest.com";
8
+ protected readonly wdHubPath: "/wd/hub";
9
+ buildUrl(_sessionId: string | null, path: string, credentials: ProviderCredentials): string;
10
+ buildHeaders(credentials: ProviderCredentials): Record<string, string>;
11
+ normalizeCapabilities(caps: Record<string, unknown>): Record<string, unknown>;
12
+ normalizeError(statusCode: number, body: unknown): AppiumServiceError;
13
+ getDefaultCapabilities(): Record<string, unknown>;
14
+ }
15
+ //# sourceMappingURL=lambdatest.provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lambdatest.provider.d.ts","sourceRoot":"","sources":["../../../src/providers/lambdatest/lambdatest.provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACvF,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAkChE,qBAAa,kBAAmB,SAAQ,YAAa,YAAW,eAAe;IAC7E,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAgB;IAC3C,SAAS,CAAC,QAAQ,CAAC,UAAU,sCAAgC;IAC7D,SAAS,CAAC,QAAQ,CAAC,SAAS,YAA+B;IAE3D,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,mBAAmB,GAAG,MAAM;IAK3F,YAAY,CAAC,WAAW,EAAE,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAOtE,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAqB7E,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,kBAAkB;IAIrE,sBAAsB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAGlD"}
@@ -0,0 +1,74 @@
1
+ import { BaseProvider } from '../base.provider.js';
2
+ import { LAMBDATEST_CONFIG, LAMBDATEST_DEFAULT_CAPS } from './lambdatest.config.js';
3
+ // Keys that belong inside lt:options
4
+ const LT_SPECIFIC_KEYS = new Set([
5
+ 'build',
6
+ 'name',
7
+ 'project',
8
+ 'video',
9
+ 'visual',
10
+ 'network',
11
+ 'console',
12
+ 'tunnel',
13
+ 'tunnelName',
14
+ 'geoLocation',
15
+ 'timezone',
16
+ 'idleTimeout',
17
+ 'queueTimeout',
18
+ 'devicelog',
19
+ 'autoGrantPermissions',
20
+ 'autoAcceptAlerts',
21
+ 'isRealMobile',
22
+ 'resignApp',
23
+ 'w3c',
24
+ 'plugin',
25
+ 'appProfiling',
26
+ 'packageVersion',
27
+ 'appiumVersion',
28
+ 'sessionName',
29
+ 'dedicatedProxy',
30
+ 'ignoreUnimportantViews',
31
+ 'eventTimings',
32
+ ]);
33
+ export class LambdaTestProvider extends BaseProvider {
34
+ name = 'lambdatest';
35
+ hubBaseUrl = LAMBDATEST_CONFIG.hubBaseUrl;
36
+ wdHubPath = LAMBDATEST_CONFIG.wdHubPath;
37
+ buildUrl(_sessionId, path, credentials) {
38
+ const base = this.buildBaseUrl(credentials);
39
+ return `${base}${path}`;
40
+ }
41
+ buildHeaders(credentials) {
42
+ return {
43
+ 'Content-Type': 'application/json',
44
+ Authorization: this.buildBasicAuthHeader(credentials),
45
+ };
46
+ }
47
+ normalizeCapabilities(caps) {
48
+ const ltOptions = {
49
+ ...caps[LAMBDATEST_CONFIG.optionsKey],
50
+ };
51
+ const rest = {};
52
+ for (const [key, value] of Object.entries(caps)) {
53
+ if (key === LAMBDATEST_CONFIG.optionsKey)
54
+ continue;
55
+ if (LT_SPECIFIC_KEYS.has(key)) {
56
+ ltOptions[key] = value;
57
+ }
58
+ else {
59
+ rest[key] = value;
60
+ }
61
+ }
62
+ return {
63
+ ...rest,
64
+ [LAMBDATEST_CONFIG.optionsKey]: ltOptions,
65
+ };
66
+ }
67
+ normalizeError(statusCode, body) {
68
+ return this.mapW3CError(statusCode, body);
69
+ }
70
+ getDefaultCapabilities() {
71
+ return { ...LAMBDATEST_DEFAULT_CAPS };
72
+ }
73
+ }
74
+ //# sourceMappingURL=lambdatest.provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lambdatest.provider.js","sourceRoot":"","sources":["../../../src/providers/lambdatest/lambdatest.provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEpF,qCAAqC;AACrC,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IAC/B,OAAO;IACP,MAAM;IACN,SAAS;IACT,OAAO;IACP,QAAQ;IACR,SAAS;IACT,SAAS;IACT,QAAQ;IACR,YAAY;IACZ,aAAa;IACb,UAAU;IACV,aAAa;IACb,cAAc;IACd,WAAW;IACX,sBAAsB;IACtB,kBAAkB;IAClB,cAAc;IACd,WAAW;IACX,KAAK;IACL,QAAQ;IACR,cAAc;IACd,gBAAgB;IAChB,eAAe;IACf,aAAa;IACb,gBAAgB;IAChB,wBAAwB;IACxB,cAAc;CACf,CAAC,CAAC;AAEH,MAAM,OAAO,kBAAmB,SAAQ,YAAY;IACzC,IAAI,GAAiB,YAAY,CAAC;IACxB,UAAU,GAAG,iBAAiB,CAAC,UAAU,CAAC;IAC1C,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC;IAE3D,QAAQ,CAAC,UAAyB,EAAE,IAAY,EAAE,WAAgC;QAChF,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QAC5C,OAAO,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED,YAAY,CAAC,WAAgC;QAC3C,OAAO;YACL,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC;SACtD,CAAC;IACJ,CAAC;IAED,qBAAqB,CAAC,IAA6B;QACjD,MAAM,SAAS,GAA4B;YACzC,GAAI,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAyC;SAC/E,CAAC;QACF,MAAM,IAAI,GAA4B,EAAE,CAAC;QAEzC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,IAAI,GAAG,KAAK,iBAAiB,CAAC,UAAU;gBAAE,SAAS;YACnD,IAAI,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC9B,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACpB,CAAC;QACH,CAAC;QAED,OAAO;YACL,GAAG,IAAI;YACP,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,SAAS;SAC1C,CAAC;IACJ,CAAC;IAED,cAAc,CAAC,UAAkB,EAAE,IAAa;QAC9C,OAAO,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,sBAAsB;QACpB,OAAO,EAAE,GAAG,uBAAuB,EAAE,CAAC;IACxC,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ import type { AppiumServiceError } from '../../types/error.types.js';
2
+ import type { ProviderCredentials, ProviderName } from '../../types/provider.types.js';
3
+ import { BaseProvider } from '../base.provider.js';
4
+ import type { IAppiumProvider } from '../provider.interface.js';
5
+ export declare class LocalProvider extends BaseProvider implements IAppiumProvider {
6
+ readonly name: ProviderName;
7
+ protected readonly hubBaseUrl: string;
8
+ protected readonly wdHubPath = "";
9
+ buildUrl(_sessionId: string | null, path: string, credentials: ProviderCredentials): string;
10
+ buildHeaders(_credentials: ProviderCredentials): Record<string, string>;
11
+ normalizeCapabilities(caps: Record<string, unknown>): Record<string, unknown>;
12
+ normalizeError(statusCode: number, body: unknown): AppiumServiceError;
13
+ getDefaultCapabilities(): Record<string, unknown>;
14
+ }
15
+ //# sourceMappingURL=local.provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.provider.d.ts","sourceRoot":"","sources":["../../../src/providers/local/local.provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AACvF,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAgBhE,qBAAa,aAAc,SAAQ,YAAa,YAAW,eAAe;IACxE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAW;IACtC,SAAS,CAAC,QAAQ,CAAC,UAAU,SAAqB;IAClD,SAAS,CAAC,QAAQ,CAAC,SAAS,MAAM;IAElC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,mBAAmB,GAAG,MAAM;IAO3F,YAAY,CAAC,YAAY,EAAE,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAMvE,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAK7E,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,kBAAkB;IAIrE,sBAAsB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAGlD"}
@@ -0,0 +1,40 @@
1
+ import { BaseProvider } from '../base.provider.js';
2
+ const DEFAULT_LOCAL_URL = process.env['LOCAL_APPIUM_URL'] ?? 'http://localhost:4723';
3
+ /**
4
+ * Default capabilities applied to every local Appium session.
5
+ * User-supplied capabilities always override these.
6
+ */
7
+ const LOCAL_DEFAULT_CAPS = {
8
+ 'appium:automationName': 'UiAutomator2',
9
+ 'appium:autoGrantPermissions': true,
10
+ 'appium:newCommandTimeout': 120000,
11
+ 'appium:unicodeKeyboard': true,
12
+ 'appium:appWaitActivity': '*',
13
+ };
14
+ export class LocalProvider extends BaseProvider {
15
+ name = 'local';
16
+ hubBaseUrl = DEFAULT_LOCAL_URL;
17
+ wdHubPath = '';
18
+ buildUrl(_sessionId, path, credentials) {
19
+ const base = credentials.hubUrl
20
+ ? credentials.hubUrl.replace(/\/$/, '')
21
+ : `${this.hubBaseUrl}${this.wdHubPath}`;
22
+ return `${base}${path}`;
23
+ }
24
+ buildHeaders(_credentials) {
25
+ return {
26
+ 'Content-Type': 'application/json',
27
+ };
28
+ }
29
+ normalizeCapabilities(caps) {
30
+ // Local Appium: pass capabilities through as-is
31
+ return caps;
32
+ }
33
+ normalizeError(statusCode, body) {
34
+ return this.mapW3CError(statusCode, body);
35
+ }
36
+ getDefaultCapabilities() {
37
+ return { ...LOCAL_DEFAULT_CAPS };
38
+ }
39
+ }
40
+ //# sourceMappingURL=local.provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local.provider.js","sourceRoot":"","sources":["../../../src/providers/local/local.provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGnD,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,uBAAuB,CAAC;AAErF;;;GAGG;AACH,MAAM,kBAAkB,GAA4B;IAClD,uBAAuB,EAAE,cAAc;IACvC,6BAA6B,EAAE,IAAI;IACnC,0BAA0B,EAAE,MAAM;IAClC,wBAAwB,EAAE,IAAI;IAC9B,wBAAwB,EAAE,GAAG;CAC9B,CAAC;AAEF,MAAM,OAAO,aAAc,SAAQ,YAAY;IACpC,IAAI,GAAiB,OAAO,CAAC;IACnB,UAAU,GAAG,iBAAiB,CAAC;IAC/B,SAAS,GAAG,EAAE,CAAC;IAElC,QAAQ,CAAC,UAAyB,EAAE,IAAY,EAAE,WAAgC;QAChF,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM;YAC7B,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;YACvC,CAAC,CAAC,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAC1C,OAAO,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED,YAAY,CAAC,YAAiC;QAC5C,OAAO;YACL,cAAc,EAAE,kBAAkB;SACnC,CAAC;IACJ,CAAC;IAED,qBAAqB,CAAC,IAA6B;QACjD,gDAAgD;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,cAAc,CAAC,UAAkB,EAAE,IAAa;QAC9C,OAAO,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC;IAED,sBAAsB;QACpB,OAAO,EAAE,GAAG,kBAAkB,EAAE,CAAC;IACnC,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ import type { ProviderName } from '../types/provider.types.js';
2
+ import type { IAppiumProvider } from './provider.interface.js';
3
+ export declare function getProvider(name: ProviderName): IAppiumProvider;
4
+ /**
5
+ * Register a custom provider at runtime.
6
+ * Use this to add providers without modifying the factory source.
7
+ */
8
+ export declare function registerProvider(provider: IAppiumProvider): void;
9
+ export declare function getSupportedProviders(): ProviderName[];
10
+ //# sourceMappingURL=provider.factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.factory.d.ts","sourceRoot":"","sources":["../../src/providers/provider.factory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAW/D,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,eAAe,CAU/D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI,CAEhE;AAED,wBAAgB,qBAAqB,IAAI,YAAY,EAAE,CAEtD"}
@@ -0,0 +1,32 @@
1
+ import { AppiumError, AppiumErrorCode } from '../types/error.types.js';
2
+ import { BrowserStackProvider } from './browserstack/browserstack.provider.js';
3
+ import { LambdaTestProvider } from './lambdatest/lambdatest.provider.js';
4
+ import { LocalProvider } from './local/local.provider.js';
5
+ // Singleton instances — providers are stateless, safe to reuse
6
+ const providerInstances = new Map([
7
+ ['browserstack', new BrowserStackProvider()],
8
+ ['lambdatest', new LambdaTestProvider()],
9
+ ['local', new LocalProvider()],
10
+ ]);
11
+ export function getProvider(name) {
12
+ const provider = providerInstances.get(name);
13
+ if (!provider) {
14
+ throw new AppiumError({
15
+ code: AppiumErrorCode.UNKNOWN_ERROR,
16
+ message: `Unknown provider: "${name}". Supported providers: ${[...providerInstances.keys()].join(', ')}`,
17
+ httpStatus: 400,
18
+ });
19
+ }
20
+ return provider;
21
+ }
22
+ /**
23
+ * Register a custom provider at runtime.
24
+ * Use this to add providers without modifying the factory source.
25
+ */
26
+ export function registerProvider(provider) {
27
+ providerInstances.set(provider.name, provider);
28
+ }
29
+ export function getSupportedProviders() {
30
+ return [...providerInstances.keys()];
31
+ }
32
+ //# sourceMappingURL=provider.factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.factory.js","sourceRoot":"","sources":["../../src/providers/provider.factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAE/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE1D,+DAA+D;AAC/D,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAgC;IAC/D,CAAC,cAAc,EAAE,IAAI,oBAAoB,EAAE,CAAC;IAC5C,CAAC,YAAY,EAAE,IAAI,kBAAkB,EAAE,CAAC;IACxC,CAAC,OAAO,EAAE,IAAI,aAAa,EAAE,CAAC;CAC/B,CAAC,CAAC;AAEH,MAAM,UAAU,WAAW,CAAC,IAAkB;IAC5C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,WAAW,CAAC;YACpB,IAAI,EAAE,eAAe,CAAC,aAAa;YACnC,OAAO,EAAE,sBAAsB,IAAI,2BAA2B,CAAC,GAAG,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACxG,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;IACL,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAyB;IACxD,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,CAAC,GAAG,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { AppiumServiceError } from '../types/error.types.js';
2
+ import type { ProviderCredentials, ProviderName } from '../types/provider.types.js';
3
+ export interface IAppiumProvider {
4
+ readonly name: ProviderName;
5
+ /**
6
+ * Build the full Appium hub URL for a given W3C path segment.
7
+ * e.g. buildUrl('abc123', '/session/abc123/element') => 'https://hub.browserstack.com/wd/hub/session/abc123/element'
8
+ */
9
+ buildUrl(sessionId: string | null, path: string, credentials: ProviderCredentials): string;
10
+ /**
11
+ * Build the HTTP headers required by this provider (auth, content-type, etc.)
12
+ */
13
+ buildHeaders(credentials: ProviderCredentials): Record<string, string>;
14
+ /**
15
+ * Transform generic desired capabilities into provider-specific format.
16
+ * e.g. BrowserStack wraps extras in "bstack:options", LambdaTest in "lt:options"
17
+ */
18
+ normalizeCapabilities(caps: Record<string, unknown>): Record<string, unknown>;
19
+ /**
20
+ * Map a provider-specific HTTP error response into our unified AppiumServiceError.
21
+ */
22
+ normalizeError(statusCode: number, body: unknown): AppiumServiceError;
23
+ /**
24
+ * Return provider-specific default capabilities.
25
+ * These are shallow-merged with user-supplied caps before session creation,
26
+ * with user-supplied values always taking priority.
27
+ */
28
+ getDefaultCapabilities(): Record<string, unknown>;
29
+ }
30
+ //# sourceMappingURL=provider.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.interface.d.ts","sourceRoot":"","sources":["../../src/providers/provider.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAEpF,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAE5B;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,mBAAmB,GAAG,MAAM,CAAC;IAE3F;;OAEG;IACH,YAAY,CAAC,WAAW,EAAE,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEvE;;;OAGG;IACH,qBAAqB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE9E;;OAEG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,kBAAkB,CAAC;IAEtE;;;;OAIG;IACH,sBAAsB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=provider.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.interface.js","sourceRoot":"","sources":["../../src/providers/provider.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":""}
package/dist/server.js ADDED
@@ -0,0 +1,13 @@
1
+ import express from 'express';
2
+ import logger from './logger/index.js';
3
+ import router from './http/router.js';
4
+ import { errorHandler } from './http/middleware/error-handler.js';
5
+ const PORT = Number(process.env['PORT'] ?? 8000);
6
+ const app = express();
7
+ app.use(express.json({ limit: '10mb' }));
8
+ app.use('/api/v1', router);
9
+ app.use(errorHandler);
10
+ app.listen(PORT, () => {
11
+ logger.info({ port: PORT }, 'Appium HTTP Service started');
12
+ });
13
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,MAAM,MAAM,mBAAmB,CAAC;AACvC,OAAO,MAAM,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAElE,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC;AAEjD,MAAM,GAAG,GAAG,OAAO,EAAE,CAAC;AAEtB,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;AAEzC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAE3B,GAAG,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AAEtB,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;IACpB,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,6BAA6B,CAAC,CAAC;AAC7D,CAAC,CAAC,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { AppiumErrorCode } from './error.types.js';
2
+ import type { ProviderCredentials, ProviderName } from './provider.types.js';
3
+ export interface ExecuteRequest {
4
+ commandName: string;
5
+ provider: ProviderName;
6
+ credentials: ProviderCredentials;
7
+ params: Record<string, unknown>;
8
+ }
9
+ export interface ExecuteResponse<T = unknown> {
10
+ success: boolean;
11
+ data?: T;
12
+ error?: {
13
+ code: AppiumErrorCode;
14
+ message: string;
15
+ httpStatus: number;
16
+ raw?: unknown;
17
+ };
18
+ }
19
+ export interface CommandRequestConfig {
20
+ method: string;
21
+ path: string;
22
+ body?: unknown;
23
+ }
24
+ //# sourceMappingURL=command.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.types.d.ts","sourceRoot":"","sources":["../../src/types/command.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAE7E,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,EAAE,mBAAmB,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,eAAe,CAAC,CAAC,GAAG,OAAO;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE;QACN,IAAI,EAAE,eAAe,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,GAAG,CAAC,EAAE,OAAO,CAAC;KACf,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=command.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.types.js","sourceRoot":"","sources":["../../src/types/command.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,25 @@
1
+ export declare enum AppiumErrorCode {
2
+ PROVIDER_UNREACHABLE = "PROVIDER_UNREACHABLE",
3
+ SESSION_NOT_FOUND = "SESSION_NOT_FOUND",
4
+ ELEMENT_NOT_FOUND = "ELEMENT_NOT_FOUND",
5
+ INVALID_SELECTOR = "INVALID_SELECTOR",
6
+ STALE_ELEMENT = "STALE_ELEMENT",
7
+ COMMAND_TIMEOUT = "COMMAND_TIMEOUT",
8
+ VALIDATION_ERROR = "VALIDATION_ERROR",
9
+ UNKNOWN_COMMAND = "UNKNOWN_COMMAND",
10
+ PROVIDER_ERROR = "PROVIDER_ERROR",
11
+ UNKNOWN_ERROR = "UNKNOWN_ERROR"
12
+ }
13
+ export interface AppiumServiceError {
14
+ code: AppiumErrorCode;
15
+ message: string;
16
+ httpStatus: number;
17
+ raw?: unknown;
18
+ }
19
+ export declare class AppiumError extends Error {
20
+ readonly code: AppiumErrorCode;
21
+ readonly httpStatus: number;
22
+ readonly raw?: unknown;
23
+ constructor(error: AppiumServiceError);
24
+ }
25
+ //# sourceMappingURL=error.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.types.d.ts","sourceRoot":"","sources":["../../src/types/error.types.ts"],"names":[],"mappings":"AAAA,oBAAY,eAAe;IACzB,oBAAoB,yBAAyB;IAC7C,iBAAiB,sBAAsB;IACvC,iBAAiB,sBAAsB;IACvC,gBAAgB,qBAAqB;IACrC,aAAa,kBAAkB;IAC/B,eAAe,oBAAoB;IACnC,gBAAgB,qBAAqB;IACrC,eAAe,oBAAoB;IACnC,cAAc,mBAAmB;IACjC,aAAa,kBAAkB;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,qBAAa,WAAY,SAAQ,KAAK;IACpC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC;gBAEX,KAAK,EAAE,kBAAkB;CAOtC"}