@mobilewright/protocol 0.0.51 → 0.0.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/driver.d.ts CHANGED
@@ -1,4 +1,32 @@
1
- import type { AppInfo, ConnectionConfig, DeviceInfo, DeviceSettings, GestureSequence, HardwareButton, LaunchOptions, ListDevicesOptions, Orientation, RecordingOptions, RecordingResult, ScreenSize, ScreenshotOptions, Session, SwipeDirection, SwipeOptions, ViewNode, WebViewInfo } from './types.js';
1
+ import type { AppInfo, ConnectionConfig, DeviceInfo, DeviceSettings, DeviceType, GestureSequence, HardwareButton, LaunchOptions, ListDevicesOptions, Orientation, Platform, RecordingOptions, RecordingResult, ScreenSize, ScreenshotOptions, Session, SwipeDirection, SwipeOptions, ViewNode, WebViewInfo } from './types.js';
2
+ /**
3
+ * Thrown by `MobilewrightDriver.allocate` when no device is currently
4
+ * available but one may become available later (e.g. all matching devices
5
+ * are already taken). The device pool treats this as a temporary condition
6
+ * and re-queues the waiter rather than rejecting it outright.
7
+ */
8
+ export declare class NoDeviceAvailableError extends Error {
9
+ constructor(message: string);
10
+ }
11
+ export interface AllocationCriteria {
12
+ platform?: Platform;
13
+ /** Regex source (`RegExp.prototype.source`) matched against device name. */
14
+ deviceNamePattern?: string;
15
+ deviceId?: string;
16
+ /** Restrict to simulators, emulators, or real devices. */
17
+ deviceType?: DeviceType;
18
+ /** OS version constraint expression, e.g. "17", "26.0" or ">=17 <19". See `parseOsVersion`. */
19
+ osVersion?: string;
20
+ }
21
+ export interface AllocatedDevice {
22
+ deviceId: string;
23
+ platform: Platform;
24
+ /** Free-form label identifying which driver produced this allocation (e.g. "mobilecli"). Informational only. */
25
+ driver?: string;
26
+ model?: string;
27
+ osVersion?: string;
28
+ type?: DeviceType;
29
+ }
2
30
  export interface WebViewSession {
3
31
  /** Evaluate a JavaScript expression in the webview and return its result. */
4
32
  evaluate<T = unknown>(expr: string): Promise<T>;
@@ -25,7 +53,35 @@ export interface WebViewBridge {
25
53
  /** Attach to the webview with the given id and return a session for driving it. */
26
54
  attachWebView(id: string): Promise<WebViewSession>;
27
55
  }
28
- export interface MobilewrightDriver {
56
+ /**
57
+ * Reserves and releases devices from a pool. Implemented by the same class
58
+ * as `MobilewrightSession` for every driver in this repo, but the device-pool
59
+ * coordinator only ever depends on this narrower shape — it never connects
60
+ * to or controls a device directly.
61
+ */
62
+ export interface DeviceAllocator {
63
+ /**
64
+ * Reserve a device matching `criteria`. Async because it may involve a
65
+ * network round-trip (cloud pool) or local enumeration.
66
+ * `takenDeviceIds` excludes devices already handed to other pool slots —
67
+ * needed by drivers that enumerate devices locally (e.g. mobilecli), since
68
+ * cloud drivers already guarantee exclusivity per allocation call and can
69
+ * ignore it. Throws `NoDeviceAvailableError` when nothing currently
70
+ * matches (a temporary condition the pool will retry). Drivers should
71
+ * honor `signal` and abort promptly, but the pool also enforces its own
72
+ * timeout independently of signal handling and will release any device
73
+ * returned after that timeout instead of publishing it.
74
+ */
75
+ allocate(criteria: AllocationCriteria, takenDeviceIds: ReadonlySet<string>, signal?: AbortSignal): Promise<AllocatedDevice>;
76
+ /** Release a device back to the pool. No-op for drivers with nothing to release. */
77
+ release(deviceId: string): Promise<void>;
78
+ /** Prepare this driver for use (e.g. start a local server process) before any device-pool workers connect. Called once by the coordinator at startup. */
79
+ prepare?(): Promise<void>;
80
+ /** Release resources acquired by `prepare()` (e.g. kill a spawned server). Called once at coordinator shutdown. */
81
+ dispose?(): Promise<void>;
82
+ }
83
+ /** Connects to and controls a single already-allocated device. */
84
+ export interface MobilewrightSession {
29
85
  /** Connect to the device described by `config` and start a session. */
30
86
  connect(config: ConnectionConfig): Promise<Session>;
31
87
  /** End the active session and release the device. */
@@ -76,7 +132,7 @@ export interface MobilewrightDriver {
76
132
  installApp(path: string): Promise<void>;
77
133
  /** Uninstall the app with the given bundle id. */
78
134
  uninstallApp(bundleId: string): Promise<void>;
79
- /** List the devices available to this driver. */
135
+ /** List the devices available to this driver, online and offline. */
80
136
  listDevices(opts?: ListDevicesOptions): Promise<DeviceInfo[]>;
81
137
  /** Open the given URL on the device (deep link or web URL). */
82
138
  openUrl(url: string): Promise<void>;
@@ -87,4 +143,81 @@ export interface MobilewrightDriver {
87
143
  /** Bridge for inspecting and driving webviews; absent on drivers without webview support. */
88
144
  webViewBridge?: WebViewBridge;
89
145
  }
146
+ /** A location in a test source file. */
147
+ export interface SourceLocation {
148
+ file: string;
149
+ line: number;
150
+ column: number;
151
+ }
152
+ /** Summary of a test run, delivered at `onRunStart`. */
153
+ export interface TestRunInfo {
154
+ /** Total number of tests scheduled in this run. */
155
+ totalTests: number;
156
+ }
157
+ /** Identifying information about a single test, delivered at `onTestEnd`. */
158
+ export interface TestInfo {
159
+ /** Stable test id — matches `spec.id` in Playwright's JSON report. */
160
+ id: string;
161
+ title: string;
162
+ /**
163
+ * Full title path as Playwright reports it: root suite (empty string),
164
+ * project name, file, describe blocks, then the test title. The project
165
+ * entry distinguishes e.g. ios/android runs of the same test.
166
+ */
167
+ titlePath: string[];
168
+ location?: SourceLocation;
169
+ }
170
+ /** A single step (or nested step) within a test result. */
171
+ export interface TestStepInfo {
172
+ title: string;
173
+ /** Playwright step category, e.g. 'test.step', 'expect', 'hook'. */
174
+ category: string;
175
+ duration: number;
176
+ error?: string;
177
+ location?: SourceLocation;
178
+ steps: TestStepInfo[];
179
+ }
180
+ /** Outcome of a single test attempt, delivered at `onTestEnd`. */
181
+ export interface TestResultInfo {
182
+ status: 'passed' | 'failed' | 'timedOut' | 'skipped' | 'interrupted';
183
+ retry: number;
184
+ duration: number;
185
+ errors: string[];
186
+ steps: TestStepInfo[];
187
+ }
188
+ /** Outcome of an entire test run, delivered at `onRunEnd`. */
189
+ export interface RunResultInfo {
190
+ status: 'passed' | 'failed' | 'timedout' | 'interrupted';
191
+ startTime: Date;
192
+ duration: number;
193
+ /**
194
+ * Lazily read Playwright's JSON report for this run, when available.
195
+ * Transitional escape hatch — prefer the event hooks; this may be removed
196
+ * once drivers no longer need the raw report.
197
+ */
198
+ jsonReport?(): Promise<unknown>;
199
+ }
200
+ /**
201
+ * Optional test-lifecycle observer implemented by a driver. Hooks are invoked
202
+ * in the runner process (same instance that performed allocation), forwarded
203
+ * from Playwright's reporter events by mobilewright's internal shim reporter.
204
+ * All hooks are optional; `onRunEnd` is awaited (uploads go there).
205
+ */
206
+ export interface TestObserver {
207
+ onRunStart?(run: TestRunInfo): void | Promise<void>;
208
+ onTestEnd?(test: TestInfo, result: TestResultInfo): void;
209
+ onRunEnd?(result: RunResultInfo): void | Promise<void>;
210
+ }
211
+ /**
212
+ * The full driver contract: reserves devices from a pool AND controls a
213
+ * connected one. Every driver in this repo implements both roles on one
214
+ * class. `defineConfig({ driver })` needs both — the device-pool coordinator
215
+ * process uses only the `DeviceAllocator` half, the connecting worker
216
+ * process uses only the `MobilewrightSession` half, but both are constructed
217
+ * from the same `driver` instance you configure.
218
+ */
219
+ export type MobilewrightDriver = DeviceAllocator & MobilewrightSession & {
220
+ /** Optional test-lifecycle observer — receives test run events (e.g. to upload results). */
221
+ observer?: TestObserver;
222
+ };
90
223
  //# sourceMappingURL=driver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../src/driver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../src/driver.ts"],"names":[],"mappings":"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"}
package/dist/driver.js CHANGED
@@ -1,2 +1,13 @@
1
- export {};
1
+ /**
2
+ * Thrown by `MobilewrightDriver.allocate` when no device is currently
3
+ * available but one may become available later (e.g. all matching devices
4
+ * are already taken). The device pool treats this as a temporary condition
5
+ * and re-queues the waiter rather than rejecting it outright.
6
+ */
7
+ export class NoDeviceAvailableError extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = 'NoDeviceAvailableError';
11
+ }
12
+ }
2
13
  //# sourceMappingURL=driver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"driver.js","sourceRoot":"","sources":["../src/driver.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"driver.js","sourceRoot":"","sources":["../src/driver.ts"],"names":[],"mappings":"AAuBA;;;;;GAKG;AACH,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC/C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;IACvC,CAAC;CACF"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,6 @@
1
1
  export type * from './types.js';
2
2
  export type * from './driver.js';
3
+ export { NoDeviceAvailableError } from './driver.js';
4
+ export { parseOsVersion, osVersionSatisfies } from './os-version.js';
5
+ export type { OsVersionBound, OsVersionRange } from './os-version.js';
3
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAC;AAChC,mBAAmB,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAC;AAChC,mBAAmB,aAAa,CAAC;AACjC,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrE,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
- export {};
1
+ export { NoDeviceAvailableError } from './driver.js';
2
+ export { parseOsVersion, osVersionSatisfies } from './os-version.js';
2
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * OS-version constraint expressions for device allocation.
3
+ *
4
+ * Grammar:
5
+ * - bare version: "17" or "26.0" — prefix match: >= the version, < the
6
+ * version with its last given segment bumped ("17" → >=17 <18).
7
+ * - comparators: ">=17", ">=17 <19" — space-separated, at most one lower
8
+ * bound (>= or >) and one upper bound (< or <=).
9
+ */
10
+ export interface OsVersionBound {
11
+ version: string;
12
+ inclusive: boolean;
13
+ }
14
+ export interface OsVersionRange {
15
+ min?: OsVersionBound;
16
+ max?: OsVersionBound;
17
+ }
18
+ export declare function parseOsVersion(expr: string): OsVersionRange;
19
+ export declare function osVersionSatisfies(version: string, expr: string): boolean;
20
+ //# sourceMappingURL=os-version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"os-version.d.ts","sourceRoot":"","sources":["../src/os-version.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB,GAAG,CAAC,EAAE,cAAc,CAAC;CACtB;AA+BD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CA0C3D;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAezE"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * OS-version constraint expressions for device allocation.
3
+ *
4
+ * Grammar:
5
+ * - bare version: "17" or "26.0" — prefix match: >= the version, < the
6
+ * version with its last given segment bumped ("17" → >=17 <18).
7
+ * - comparators: ">=17", ">=17 <19" — space-separated, at most one lower
8
+ * bound (>= or >) and one upper bound (< or <=).
9
+ */
10
+ const VERSION_RE = /^\d+(\.\d+)*$/;
11
+ function assertValidVersion(version) {
12
+ if (!VERSION_RE.test(version)) {
13
+ throw new Error(`invalid OS version "${version}" — expected digits separated by dots, e.g. "17" or "26.0"`);
14
+ }
15
+ }
16
+ /** Numeric dot-segment comparison; missing segments count as 0. */
17
+ function compareVersions(a, b) {
18
+ const as = a.split('.').map(Number);
19
+ const bs = b.split('.').map(Number);
20
+ const len = Math.max(as.length, bs.length);
21
+ for (let i = 0; i < len; i++) {
22
+ const diff = (as[i] ?? 0) - (bs[i] ?? 0);
23
+ if (diff !== 0) {
24
+ return diff;
25
+ }
26
+ }
27
+ return 0;
28
+ }
29
+ /** "26.0" → "26.1", "17" → "18" — the exclusive upper bound of a prefix match. */
30
+ function bumpLastSegment(version) {
31
+ const segments = version.split('.').map(Number);
32
+ segments[segments.length - 1] += 1;
33
+ return segments.join('.');
34
+ }
35
+ export function parseOsVersion(expr) {
36
+ const parts = expr.trim().split(/\s+/).filter((p) => p.length > 0);
37
+ if (parts.length === 0) {
38
+ throw new Error('empty OS version expression');
39
+ }
40
+ if (parts.length === 1 && VERSION_RE.test(parts[0])) {
41
+ return {
42
+ min: { version: parts[0], inclusive: true },
43
+ max: { version: bumpLastSegment(parts[0]), inclusive: false },
44
+ };
45
+ }
46
+ const range = {};
47
+ for (const part of parts) {
48
+ const match = /^(>=|<=|>|<)(.+)$/.exec(part);
49
+ if (!match) {
50
+ throw new Error(`invalid OS version constraint "${part}" — expected ">=", ">", "<=" or "<" followed by a version, or a single bare version`);
51
+ }
52
+ const [, op, version] = match;
53
+ assertValidVersion(version);
54
+ const isLower = op === '>=' || op === '>';
55
+ const bound = { version, inclusive: op === '>=' || op === '<=' };
56
+ if (isLower) {
57
+ if (range.min) {
58
+ throw new Error(`duplicate lower bound in OS version expression "${expr}"`);
59
+ }
60
+ range.min = bound;
61
+ }
62
+ else {
63
+ if (range.max) {
64
+ throw new Error(`duplicate upper bound in OS version expression "${expr}"`);
65
+ }
66
+ range.max = bound;
67
+ }
68
+ }
69
+ if (range.min && range.max) {
70
+ const cmp = compareVersions(range.min.version, range.max.version);
71
+ if (cmp > 0 || (cmp === 0 && !(range.min.inclusive && range.max.inclusive))) {
72
+ throw new Error(`impossible OS version range "${expr}" — no version can satisfy it`);
73
+ }
74
+ }
75
+ return range;
76
+ }
77
+ export function osVersionSatisfies(version, expr) {
78
+ const range = parseOsVersion(expr);
79
+ if (range.min) {
80
+ const cmp = compareVersions(version, range.min.version);
81
+ if (cmp < 0 || (cmp === 0 && !range.min.inclusive)) {
82
+ return false;
83
+ }
84
+ }
85
+ if (range.max) {
86
+ const cmp = compareVersions(version, range.max.version);
87
+ if (cmp > 0 || (cmp === 0 && !range.max.inclusive)) {
88
+ return false;
89
+ }
90
+ }
91
+ return true;
92
+ }
93
+ //# sourceMappingURL=os-version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"os-version.js","sourceRoot":"","sources":["../src/os-version.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=os-version.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"os-version.test.d.ts","sourceRoot":"","sources":["../src/os-version.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,81 @@
1
+ import { test, expect } from '@playwright/test';
2
+ import { parseOsVersion, osVersionSatisfies } from './os-version.js';
3
+ // ─── bare version = prefix match ─────────────────────────────
4
+ test('a bare major version matches any release of that major', () => {
5
+ expect(osVersionSatisfies('17.0', '17')).toBe(true);
6
+ expect(osVersionSatisfies('17.5.1', '17')).toBe(true);
7
+ expect(osVersionSatisfies('17', '17')).toBe(true);
8
+ });
9
+ test('a bare major version rejects neighboring majors', () => {
10
+ expect(osVersionSatisfies('16.9', '17')).toBe(false);
11
+ expect(osVersionSatisfies('18.0', '17')).toBe(false);
12
+ expect(osVersionSatisfies('18', '17')).toBe(false);
13
+ });
14
+ test('a two-segment version matches only that minor release', () => {
15
+ expect(osVersionSatisfies('26.0', '26.0')).toBe(true);
16
+ expect(osVersionSatisfies('26.0.1', '26.0')).toBe(true);
17
+ expect(osVersionSatisfies('26.1', '26.0')).toBe(false);
18
+ expect(osVersionSatisfies('26.5', '26.0')).toBe(false);
19
+ });
20
+ // ─── comparators ─────────────────────────────────────────────
21
+ test('>= matches the version itself and anything above', () => {
22
+ expect(osVersionSatisfies('17', '>=17')).toBe(true);
23
+ expect(osVersionSatisfies('19.2', '>=17')).toBe(true);
24
+ expect(osVersionSatisfies('16.9', '>=17')).toBe(false);
25
+ });
26
+ test('a >= and < pair expresses a range', () => {
27
+ expect(osVersionSatisfies('17.0', '>=17 <19')).toBe(true);
28
+ expect(osVersionSatisfies('18.4', '>=17 <19')).toBe(true);
29
+ expect(osVersionSatisfies('19.0', '>=17 <19')).toBe(false);
30
+ expect(osVersionSatisfies('16.9', '>=17 <19')).toBe(false);
31
+ });
32
+ test('strict > excludes the version itself', () => {
33
+ expect(osVersionSatisfies('17.0', '>17')).toBe(false);
34
+ expect(osVersionSatisfies('17.0.1', '>17')).toBe(true);
35
+ });
36
+ test('<= includes the version itself', () => {
37
+ expect(osVersionSatisfies('18', '<=18')).toBe(true);
38
+ expect(osVersionSatisfies('18.0.1', '<=18')).toBe(false);
39
+ });
40
+ // ─── numeric (not lexicographic) comparison ──────────────────
41
+ test('segments compare numerically so 10 sorts above 9', () => {
42
+ expect(osVersionSatisfies('10.0', '>=9')).toBe(true);
43
+ expect(osVersionSatisfies('17.10', '>=17.9')).toBe(true);
44
+ });
45
+ // ─── parse output (used to build fleet API filters) ──────────
46
+ test('parsing a bare version yields inclusive lower and exclusive upper bounds', () => {
47
+ expect(parseOsVersion('17')).toEqual({
48
+ min: { version: '17', inclusive: true },
49
+ max: { version: '18', inclusive: false },
50
+ });
51
+ expect(parseOsVersion('26.0')).toEqual({
52
+ min: { version: '26.0', inclusive: true },
53
+ max: { version: '26.1', inclusive: false },
54
+ });
55
+ });
56
+ test('parsing comparators yields only the bounds given', () => {
57
+ expect(parseOsVersion('>=17')).toEqual({ min: { version: '17', inclusive: true } });
58
+ expect(parseOsVersion('>=17 <19')).toEqual({
59
+ min: { version: '17', inclusive: true },
60
+ max: { version: '19', inclusive: false },
61
+ });
62
+ });
63
+ // ─── invalid input fails loudly ──────────────────────────────
64
+ test('malformed expressions throw', () => {
65
+ expect(() => parseOsVersion('')).toThrow();
66
+ expect(() => parseOsVersion('abc')).toThrow();
67
+ expect(() => parseOsVersion('>=x')).toThrow();
68
+ expect(() => parseOsVersion('~17')).toThrow();
69
+ expect(() => parseOsVersion('17 <19')).toThrow(); // bare version cannot mix with comparators
70
+ expect(() => parseOsVersion('>=17 >=18')).toThrow(); // duplicate lower bounds
71
+ });
72
+ test('contradictory ranges throw', () => {
73
+ expect(() => parseOsVersion('>=19 <17')).toThrow(); // lower above upper
74
+ expect(() => parseOsVersion('>17 <=17')).toThrow(); // equal bounds, exclusive lower
75
+ expect(() => parseOsVersion('>=17 <17')).toThrow(); // equal bounds, exclusive upper
76
+ });
77
+ test('an inclusive equal-bound range means exactly that version and stays valid', () => {
78
+ expect(osVersionSatisfies('17', '>=17 <=17')).toBe(true);
79
+ expect(osVersionSatisfies('17.1', '>=17 <=17')).toBe(false);
80
+ });
81
+ //# sourceMappingURL=os-version.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"os-version.test.js","sourceRoot":"","sources":["../src/os-version.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mobilewright/protocol",
3
- "version": "0.0.51",
3
+ "version": "0.0.53",
4
4
  "description": "Protocol interfaces for Mobilewright drivers",
5
5
  "homepage": "https://mobilewright.dev",
6
6
  "license": "Apache-2.0",