wuying-agentbay-sdk 0.10.2 → 0.12.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.
- package/dist/chunk-BVWUCG4J.mjs +3402 -0
- package/dist/chunk-BVWUCG4J.mjs.map +1 -0
- package/dist/chunk-SL5GCAQE.cjs +3393 -0
- package/dist/chunk-SL5GCAQE.cjs.map +1 -0
- package/dist/index.cjs +4623 -3978
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +3934 -1964
- package/dist/index.d.ts +3934 -1964
- package/dist/index.mjs +4601 -3956
- package/dist/index.mjs.map +1 -1
- package/dist/key-normalizer-AF7APGQZ.cjs +136 -0
- package/dist/key-normalizer-AF7APGQZ.cjs.map +1 -0
- package/dist/key-normalizer-QDBRLFHF.mjs +145 -0
- package/dist/key-normalizer-QDBRLFHF.mjs.map +1 -0
- package/dist/model-CNCGFWJH.cjs +200 -0
- package/dist/model-CNCGFWJH.cjs.map +1 -0
- package/dist/model-LGWQJWKQ.mjs +209 -0
- package/docs/api/README.md +26 -0
- package/docs/api/browser-use/browser.md +177 -0
- package/docs/api/browser-use/extension.md +284 -0
- package/docs/api/codespace/code.md +77 -0
- package/docs/api/common-features/advanced/agent.md +84 -0
- package/docs/api/common-features/advanced/oss.md +221 -0
- package/docs/api/common-features/basics/agentbay.md +277 -0
- package/docs/api/common-features/basics/command.md +83 -0
- package/docs/api/common-features/basics/context-manager.md +149 -0
- package/docs/api/common-features/basics/context-sync.md +51 -0
- package/docs/api/common-features/basics/context.md +348 -0
- package/docs/api/common-features/basics/filesystem.md +499 -0
- package/docs/api/common-features/basics/logging.md +77 -0
- package/docs/api/common-features/basics/session.md +542 -0
- package/docs/api/computer-use/computer.md +786 -0
- package/docs/api/mobile-use/mobile.md +395 -0
- package/docs/examples/README.md +332 -0
- package/docs/examples/basic-usage.ts +86 -0
- package/docs/examples/browser-use/browser/README.md +356 -0
- package/docs/examples/browser-use/browser/basic-usage.ts +136 -0
- package/docs/examples/browser-use/browser/browser-command-args.ts +117 -0
- package/docs/examples/browser-use/browser/browser-context-cookie-persistence.ts +348 -0
- package/docs/examples/browser-use/browser/browser-fingerprint-basic-usage.ts +121 -0
- package/docs/examples/browser-use/browser/browser-fingerprint-construct.ts +114 -0
- package/docs/examples/browser-use/browser/browser-fingerprint-local-sync.ts +98 -0
- package/docs/examples/browser-use/browser/browser-fingerprint-persistence.ts +242 -0
- package/docs/examples/browser-use/browser/browser-proxies.ts +149 -0
- package/docs/examples/browser-use/browser/browser-type-example.ts +266 -0
- package/docs/examples/browser-use/browser/browser-viewport.ts +129 -0
- package/docs/examples/browser-use/browser/call_for_user_jd.ts +184 -0
- package/docs/examples/browser-use/browser/captcha_tongcheng.ts +151 -0
- package/docs/examples/browser-use/browser/run-2048.ts +209 -0
- package/docs/examples/browser-use/browser/run-sudoku.ts +150 -0
- package/docs/examples/browser-use/browser/screenshot-example.ts +132 -0
- package/docs/examples/browser-use/extension-example/README.md +252 -0
- package/docs/examples/browser-use/extension-example/extension-example.ts +381 -0
- package/docs/examples/codespace/automation/automation-example.ts +322 -0
- package/docs/examples/common-features/advanced/agent-module-example/README.md +40 -0
- package/docs/examples/common-features/advanced/agent-module-example.ts +66 -0
- package/docs/examples/common-features/advanced/archive-upload-mode-example/README.md +212 -0
- package/docs/examples/common-features/advanced/archive-upload-mode-example/archive-upload-mode-example.ts +213 -0
- package/docs/examples/common-features/advanced/vpc-session-example/README.md +47 -0
- package/docs/examples/common-features/advanced/vpc-session-example.ts +106 -0
- package/docs/examples/common-features/basics/archive-upload-mode-example/README.md +236 -0
- package/docs/examples/common-features/basics/archive-upload-mode-example/main.ts +236 -0
- package/docs/examples/common-features/basics/command-example/README.md +47 -0
- package/docs/examples/common-features/basics/command-example/command-example.ts +153 -0
- package/docs/examples/common-features/basics/context-management/README.md +55 -0
- package/docs/examples/common-features/basics/context-management/context-management.ts +140 -0
- package/docs/examples/common-features/basics/data-persistence/README.md +129 -0
- package/docs/examples/common-features/basics/data-persistence/context-sync-demo.md +144 -0
- package/docs/examples/common-features/basics/data-persistence/context-sync-demo.ts +275 -0
- package/docs/examples/common-features/basics/data-persistence/data-persistence.ts +259 -0
- package/docs/examples/common-features/basics/data-persistence/recycle-policy-example.ts +294 -0
- package/docs/examples/common-features/basics/filesystem-example/README.md +57 -0
- package/docs/examples/common-features/basics/filesystem-example/filesystem-example.ts +164 -0
- package/docs/examples/common-features/basics/filesystem-example/filesystem-filetransfer-example.ts +153 -0
- package/docs/examples/common-features/basics/filesystem-example/watch-directory-example.ts +168 -0
- package/docs/examples/common-features/basics/get/README.md +136 -0
- package/docs/examples/common-features/basics/get/main.ts +79 -0
- package/docs/examples/common-features/basics/list_sessions/README.md +54 -0
- package/docs/examples/common-features/basics/list_sessions/main.ts +258 -0
- package/docs/examples/common-features/basics/mcp_tool_direct_call/README.md +142 -0
- package/docs/examples/common-features/basics/mcp_tool_direct_call/main.ts +135 -0
- package/docs/examples/common-features/basics/session-creation/README.md +28 -0
- package/docs/examples/common-features/basics/session-creation/session-creation.ts +295 -0
- package/docs/examples/common-features/basics/session-pause-resume/README.md +53 -0
- package/docs/examples/common-features/basics/session-pause-resume/session-pause-resume.ts +237 -0
- package/docs/examples/mobile-use/mobile-get-adb-url/README.md +92 -0
- package/docs/examples/mobile-use/mobile-get-adb-url/index.ts +80 -0
- package/docs/examples/mobile-use/mobile-get-adb-url/package-lock.json +279 -0
- package/docs/examples/mobile-use/mobile-get-adb-url/package.json +18 -0
- package/docs/examples/mobile-use/mobile-simulate-basic-usage.ts +202 -0
- package/docs/examples/mobile-use/mobile-simulate-with-ctx.ts +170 -0
- package/package.json +19 -12
- package/dist/application-KZWXH46T.mjs +0 -17
- package/dist/application-LMA7KSRH.cjs +0 -8
- package/dist/application-LMA7KSRH.cjs.map +0 -1
- package/dist/chunk-BQNGKBQF.mjs +0 -386
- package/dist/chunk-BQNGKBQF.mjs.map +0 -1
- package/dist/chunk-IOVGAAJL.cjs +0 -558
- package/dist/chunk-IOVGAAJL.cjs.map +0 -1
- package/dist/chunk-UF2TC2R4.mjs +0 -567
- package/dist/chunk-UF2TC2R4.mjs.map +0 -1
- package/dist/chunk-X6MS7Z5L.cjs +0 -377
- package/dist/chunk-X6MS7Z5L.cjs.map +0 -1
- package/dist/window-DH37ZDD5.mjs +0 -17
- package/dist/window-DH37ZDD5.mjs.map +0 -1
- package/dist/window-U7N3H735.cjs +0 -8
- package/dist/window-U7N3H735.cjs.map +0 -1
- /package/dist/{application-KZWXH46T.mjs.map → model-LGWQJWKQ.mjs.map} +0 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { AgentBay, Session, log, logError, newCreateSessionParams } from 'wuying-agentbay-sdk'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Pause and resume a session
|
|
5
|
+
*
|
|
6
|
+
* This example demonstrates how to pause and resume a session using the AgentBay SDK.
|
|
7
|
+
* Pausing a session puts it into a dormant state, consuming fewer resources while
|
|
8
|
+
* maintaining its state. Resuming a session brings it back to an active state.
|
|
9
|
+
*/
|
|
10
|
+
async function pauseAndResumeSession() {
|
|
11
|
+
// Initialize the AgentBay client
|
|
12
|
+
const agentBay = new AgentBay({ apiKey: process.env.AGENTBAY_API_KEY });
|
|
13
|
+
|
|
14
|
+
try {
|
|
15
|
+
// Create a session with labels for identification
|
|
16
|
+
const params = newCreateSessionParams().withLabels({
|
|
17
|
+
project: 'pause-resume-example',
|
|
18
|
+
environment: 'development',
|
|
19
|
+
purpose: 'demonstration'
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
log('Creating session...');
|
|
23
|
+
const createResult = await agentBay.create(params);
|
|
24
|
+
|
|
25
|
+
if (createResult.success && createResult.session) {
|
|
26
|
+
const session = createResult.session;
|
|
27
|
+
log(`✅ Session created successfully with ID: ${session.sessionId}`);
|
|
28
|
+
log(`📎 Request ID: ${createResult.requestId}`);
|
|
29
|
+
|
|
30
|
+
// Perform some work in the session before pausing
|
|
31
|
+
log('Performing some work in the session...');
|
|
32
|
+
const commandResult = await session.command.executeCommand('echo "Hello from paused session!"');
|
|
33
|
+
if (commandResult.success) {
|
|
34
|
+
log(`💻 Command output: ${commandResult.output}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Pause the session
|
|
38
|
+
log('\n⏸️ Pausing session...');
|
|
39
|
+
const pauseResult = await agentBay.pauseAsync(session);
|
|
40
|
+
|
|
41
|
+
if (pauseResult.success) {
|
|
42
|
+
log(`✅ Session pause initiated successfully`);
|
|
43
|
+
log(`📎 Pause Request ID: ${pauseResult.requestId}`);
|
|
44
|
+
|
|
45
|
+
// Check session status after pause
|
|
46
|
+
const sessionStatusAfterPause = await agentBay.getSession(session.sessionId);
|
|
47
|
+
if (sessionStatusAfterPause.success && sessionStatusAfterPause.data) {
|
|
48
|
+
log(`📊 Session status after pause: ${sessionStatusAfterPause.data.status || 'Unknown'}`);
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
log(`❌ Failed to pause session: ${pauseResult.errorMessage}`);
|
|
52
|
+
// Continue with the example even if pause fails
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Wait a bit for the pause to complete
|
|
56
|
+
log('\n⏳ Waiting for session to pause...');
|
|
57
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
58
|
+
|
|
59
|
+
// Resume the session
|
|
60
|
+
log('\n▶️ Resuming session...');
|
|
61
|
+
const resumeResult = await agentBay.resumeAsync(session);
|
|
62
|
+
|
|
63
|
+
if (resumeResult.success) {
|
|
64
|
+
log(`✅ Session resume initiated successfully`);
|
|
65
|
+
log(`📎 Resume Request ID: ${resumeResult.requestId}`);
|
|
66
|
+
|
|
67
|
+
// Check session status after resume
|
|
68
|
+
const sessionStatusAfterResume = await agentBay.getSession(session.sessionId);
|
|
69
|
+
if (sessionStatusAfterResume.success && sessionStatusAfterResume.data) {
|
|
70
|
+
log(`📊 Session status after resume: ${sessionStatusAfterResume.data.status || 'Unknown'}`);
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
log(`❌ Failed to resume session: ${resumeResult.errorMessage}`);
|
|
74
|
+
// Continue with the example even if resume fails
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Wait a bit for the resume to complete
|
|
78
|
+
log('\n⏳ Waiting for session to resume...');
|
|
79
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
80
|
+
|
|
81
|
+
// Perform some work in the session after resuming
|
|
82
|
+
log('\nPerforming some work in the resumed session...');
|
|
83
|
+
const commandResultAfterResume = await session.command.executeCommand('echo "Hello from resumed session!"');
|
|
84
|
+
if (commandResultAfterResume.success) {
|
|
85
|
+
log(`💻 Command output: ${commandResultAfterResume.output}`);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Clean up by deleting the session
|
|
89
|
+
log('\n🧹 Cleaning up - deleting session...');
|
|
90
|
+
const deleteResult = await agentBay.delete(session);
|
|
91
|
+
if (deleteResult.success) {
|
|
92
|
+
log('✅ Session deleted successfully');
|
|
93
|
+
} else {
|
|
94
|
+
log(`❌ Failed to delete session: ${deleteResult.errorMessage}`);
|
|
95
|
+
}
|
|
96
|
+
} else {
|
|
97
|
+
log(`❌ Failed to create session: ${createResult.errorMessage}`);
|
|
98
|
+
}
|
|
99
|
+
} catch (error) {
|
|
100
|
+
logError('Error in pause and resume example:', error);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Handle non-existent session pause/resume
|
|
106
|
+
*
|
|
107
|
+
* This example demonstrates how the SDK handles attempts to pause or resume
|
|
108
|
+
* sessions that don't exist.
|
|
109
|
+
*/
|
|
110
|
+
async function handleNonExistentSession() {
|
|
111
|
+
// Initialize the AgentBay client
|
|
112
|
+
const agentBay = new AgentBay({ apiKey: process.env.AGENTBAY_API_KEY });
|
|
113
|
+
|
|
114
|
+
log('\n' + '='.repeat(50));
|
|
115
|
+
log('Handling Non-Existent Session Example');
|
|
116
|
+
log('='.repeat(50));
|
|
117
|
+
|
|
118
|
+
// Create a session object with invalid ID
|
|
119
|
+
const fakeSessionId = 'session-nonexistent-12345';
|
|
120
|
+
log(`\nCreating session object for non-existent session: ${fakeSessionId}`);
|
|
121
|
+
|
|
122
|
+
// Create a real session object with invalid ID
|
|
123
|
+
const fakeSession = new Session(agentBay, fakeSessionId);
|
|
124
|
+
|
|
125
|
+
try {
|
|
126
|
+
// Try to pause the non-existent session
|
|
127
|
+
log('⏸️ Attempting to pause non-existent session...');
|
|
128
|
+
const pauseResult = await agentBay.pauseAsync(fakeSession);
|
|
129
|
+
log(`Pause result: Success=${pauseResult.success}, Error=${pauseResult.errorMessage || 'None'}`);
|
|
130
|
+
|
|
131
|
+
log('▶️ Attempting to resume non-existent session...');
|
|
132
|
+
const resumeResult = await agentBay.resumeAsync(fakeSession);
|
|
133
|
+
log(`Resume result: Success=${resumeResult.success}, Error=${resumeResult.errorMessage || 'None'}`);
|
|
134
|
+
} catch (error) {
|
|
135
|
+
log(`Expected error when handling non-existent session: ${error}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Pause and resume with custom parameters
|
|
141
|
+
*
|
|
142
|
+
* This example demonstrates how to use custom timeout and polling interval
|
|
143
|
+
* parameters when pausing and resuming sessions.
|
|
144
|
+
*/
|
|
145
|
+
async function pauseAndResumeWithCustomParameters() {
|
|
146
|
+
// Initialize the AgentBay client
|
|
147
|
+
const agentBay = new AgentBay({ apiKey: process.env.AGENTBAY_API_KEY });
|
|
148
|
+
|
|
149
|
+
log('\n' + '='.repeat(50));
|
|
150
|
+
log('Custom Parameters Example');
|
|
151
|
+
log('='.repeat(50));
|
|
152
|
+
|
|
153
|
+
try {
|
|
154
|
+
// Create a session
|
|
155
|
+
const params = newCreateSessionParams().withLabels({
|
|
156
|
+
project: 'pause-resume-custom-example',
|
|
157
|
+
environment: 'development',
|
|
158
|
+
purpose: 'custom-parameters'
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
log('Creating session with custom parameters example...');
|
|
162
|
+
const createResult = await agentBay.create(params);
|
|
163
|
+
|
|
164
|
+
if (createResult.success && createResult.session) {
|
|
165
|
+
const session = createResult.session;
|
|
166
|
+
log(`✅ Session created successfully with ID: ${session.sessionId}`);
|
|
167
|
+
|
|
168
|
+
// Pause the session with custom parameters
|
|
169
|
+
// Using shorter timeout and poll interval for demonstration
|
|
170
|
+
log('\n⏸️ Pausing session with custom parameters (timeout=30s, pollInterval=1s)...');
|
|
171
|
+
const pauseResult = await agentBay.pauseAsync(session, 30, 1);
|
|
172
|
+
|
|
173
|
+
if (pauseResult.success) {
|
|
174
|
+
log(`✅ Session pause with custom parameters initiated successfully`);
|
|
175
|
+
log(`📎 Request ID: ${pauseResult.requestId}`);
|
|
176
|
+
|
|
177
|
+
// Check session status after pause
|
|
178
|
+
const sessionStatusAfterPause = await agentBay.getSession(session.sessionId);
|
|
179
|
+
if (sessionStatusAfterPause.success && sessionStatusAfterPause.data) {
|
|
180
|
+
log(`📊 Session status after pause: ${sessionStatusAfterPause.data.status || 'Unknown'}`);
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
log(`❌ Failed to pause session with custom parameters: ${pauseResult.errorMessage}`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Wait a bit
|
|
187
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
188
|
+
|
|
189
|
+
// Resume the session with custom parameters
|
|
190
|
+
log('\n▶️ Resuming session with custom parameters (timeout=30s, pollInterval=1s)...');
|
|
191
|
+
const resumeResult = await agentBay.resumeAsync(session, 30, 1);
|
|
192
|
+
|
|
193
|
+
if (resumeResult.success) {
|
|
194
|
+
log(`✅ Session resume with custom parameters initiated successfully`);
|
|
195
|
+
log(`📎 Request ID: ${resumeResult.requestId}`);
|
|
196
|
+
|
|
197
|
+
// Check session status after resume
|
|
198
|
+
const sessionStatusAfterResume = await agentBay.getSession(session.sessionId);
|
|
199
|
+
if (sessionStatusAfterResume.success && sessionStatusAfterResume.data) {
|
|
200
|
+
log(`📊 Session status after resume: ${sessionStatusAfterResume.data.status || 'Unknown'}`);
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
log(`❌ Failed to resume session with custom parameters: ${resumeResult.errorMessage}`);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Clean up
|
|
207
|
+
log('\n🧹 Cleaning up - deleting session...');
|
|
208
|
+
const deleteResult = await agentBay.delete(session);
|
|
209
|
+
if (deleteResult.success) {
|
|
210
|
+
log('✅ Session deleted successfully');
|
|
211
|
+
} else {
|
|
212
|
+
log(`❌ Failed to delete session: ${deleteResult.errorMessage}`);
|
|
213
|
+
}
|
|
214
|
+
} else {
|
|
215
|
+
log(`❌ Failed to create session: ${createResult.errorMessage}`);
|
|
216
|
+
}
|
|
217
|
+
} catch (error) {
|
|
218
|
+
logError('Error in custom parameters example:', error);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Run all examples
|
|
224
|
+
*/
|
|
225
|
+
async function main() {
|
|
226
|
+
log('Session Pause and Resume Examples');
|
|
227
|
+
log('=================================');
|
|
228
|
+
|
|
229
|
+
await pauseAndResumeSession();
|
|
230
|
+
await handleNonExistentSession();
|
|
231
|
+
await pauseAndResumeWithCustomParameters();
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
main().catch(error => {
|
|
235
|
+
logError('Error in main:', error);
|
|
236
|
+
process.exit(1);
|
|
237
|
+
});
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Mobile GetAdbUrl Example
|
|
2
|
+
|
|
3
|
+
This example demonstrates how to retrieve an ADB (Android Debug Bridge) connection URL for a mobile session.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Node.js 14 or higher
|
|
8
|
+
- AgentBay API key
|
|
9
|
+
- A mobile session (`mobile_latest` image)
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @aliyun/wuying-agentbay-sdk
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
1. Set your API key:
|
|
20
|
+
```bash
|
|
21
|
+
export AGENTBAY_API_KEY=your_api_key_here
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
2. Run the example:
|
|
25
|
+
```bash
|
|
26
|
+
npx ts-node index.ts
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Expected Output
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
=== Mobile GetAdbUrl Example ===
|
|
33
|
+
|
|
34
|
+
Creating mobile session...
|
|
35
|
+
✅ Session created successfully
|
|
36
|
+
Session ID: session-xxxxx
|
|
37
|
+
Image ID: mobile_latest
|
|
38
|
+
|
|
39
|
+
Getting ADB connection URL...
|
|
40
|
+
✅ ADB URL retrieved successfully
|
|
41
|
+
URL: adb connect xx.xx.xx.xx:xxxxx
|
|
42
|
+
Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
43
|
+
|
|
44
|
+
You can now connect to the mobile device using:
|
|
45
|
+
adb connect xx.xx.xx.xx:xxxxx
|
|
46
|
+
|
|
47
|
+
=== Example completed successfully ===
|
|
48
|
+
|
|
49
|
+
Cleaning up session...
|
|
50
|
+
✅ Session deleted successfully (RequestID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Using the ADB Connection
|
|
54
|
+
|
|
55
|
+
Once you have the ADB URL, you can connect to the mobile device:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Connect to the device
|
|
59
|
+
adb connect xx.xx.xx.xx:xxxxx
|
|
60
|
+
|
|
61
|
+
# Verify the connection
|
|
62
|
+
adb devices
|
|
63
|
+
|
|
64
|
+
# Now you can use standard ADB commands
|
|
65
|
+
adb shell
|
|
66
|
+
adb install app.apk
|
|
67
|
+
adb logcat
|
|
68
|
+
adb pull /sdcard/file.txt
|
|
69
|
+
adb push file.txt /sdcard/
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Important Notes
|
|
73
|
+
|
|
74
|
+
1. **Environment Requirement**: This method only works with `mobile_latest` image sessions
|
|
75
|
+
2. **ADB Public Key**: You need to provide your ADB public key for authentication
|
|
76
|
+
3. **Connection URL Format**: The returned URL is in the format `adb connect <IP>:<Port>`
|
|
77
|
+
4. **Session Cleanup**: Always delete the session when done to avoid resource leaks
|
|
78
|
+
|
|
79
|
+
## Error Handling
|
|
80
|
+
|
|
81
|
+
The example includes proper error handling for common scenarios:
|
|
82
|
+
- Missing API key
|
|
83
|
+
- Session creation failure
|
|
84
|
+
- ADB URL retrieval failure
|
|
85
|
+
- Session deletion issues
|
|
86
|
+
|
|
87
|
+
## See Also
|
|
88
|
+
|
|
89
|
+
- [Mobile API Documentation](../../../api/mobile-use/mobile.md)
|
|
90
|
+
- [Session Management Guide](../../../../../docs/guides/common-features/basics/session-management.md)
|
|
91
|
+
- [Mobile Use Guide](../../../../../docs/guides/mobile-use/README.md)
|
|
92
|
+
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mobile GetAdbUrl Example
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates how to use the getAdbUrl method to retrieve
|
|
5
|
+
* an ADB (Android Debug Bridge) connection URL for a mobile session.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { AgentBay } from '@aliyun/wuying-agentbay-sdk';
|
|
9
|
+
|
|
10
|
+
async function main() {
|
|
11
|
+
// Get API key from environment variable
|
|
12
|
+
const apiKey = process.env.AGENTBAY_API_KEY;
|
|
13
|
+
if (!apiKey) {
|
|
14
|
+
console.error('Error: AGENTBAY_API_KEY environment variable is not set');
|
|
15
|
+
console.error('Please set it with: export AGENTBAY_API_KEY=your_api_key');
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
console.log('=== Mobile GetAdbUrl Example ===\n');
|
|
20
|
+
|
|
21
|
+
// Initialize AgentBay client
|
|
22
|
+
const client = new AgentBay({ apiKey });
|
|
23
|
+
|
|
24
|
+
// Create a mobile session
|
|
25
|
+
console.log('Creating mobile session...');
|
|
26
|
+
const sessionResult = await client.create({
|
|
27
|
+
imageId: 'mobile_latest' // Must use mobile_latest for ADB functionality
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
if (!sessionResult.session) {
|
|
31
|
+
console.error('Failed to create session');
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const session = sessionResult.session;
|
|
36
|
+
console.log(`✅ Session created successfully`);
|
|
37
|
+
console.log(` Session ID: ${session.sessionId}`);
|
|
38
|
+
console.log(` Image ID: ${session.imageId}\n`);
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
// Get ADB URL with public key
|
|
42
|
+
// Note: In production, you should use your actual ADB public key
|
|
43
|
+
// This is a desensitized example key
|
|
44
|
+
const adbkeyPub = "QAAAAM0muSn7yQCY...your_adb_public_key...EAAQAA=";
|
|
45
|
+
|
|
46
|
+
console.log('Getting ADB connection URL...');
|
|
47
|
+
const result = await session.mobile.getAdbUrl(adbkeyPub);
|
|
48
|
+
|
|
49
|
+
if (result.success) {
|
|
50
|
+
console.log(`✅ ADB URL retrieved successfully`);
|
|
51
|
+
console.log(` URL: ${result.data}`);
|
|
52
|
+
console.log(` Request ID: ${result.requestId}\n`);
|
|
53
|
+
console.log('You can now connect to the mobile device using:');
|
|
54
|
+
console.log(` ${result.data}`);
|
|
55
|
+
} else {
|
|
56
|
+
console.error(`❌ Failed to get ADB URL`);
|
|
57
|
+
console.error(` Error: ${result.errorMessage}`);
|
|
58
|
+
console.error(` Request ID: ${result.requestId}`);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
console.log('\n=== Example completed successfully ===');
|
|
63
|
+
} finally {
|
|
64
|
+
// Cleanup: Delete session
|
|
65
|
+
console.log('\nCleaning up session...');
|
|
66
|
+
const deleteResult = await session.delete();
|
|
67
|
+
if (deleteResult.success) {
|
|
68
|
+
console.log(`✅ Session deleted successfully (RequestID: ${deleteResult.requestId})`);
|
|
69
|
+
} else {
|
|
70
|
+
console.warn(`Warning: Failed to delete session: ${deleteResult.errorMessage}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Run the example
|
|
76
|
+
main().catch((error) => {
|
|
77
|
+
console.error('Error:', error);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
});
|
|
80
|
+
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mobile-get-adb-url-example",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"lockfileVersion": 3,
|
|
5
|
+
"requires": true,
|
|
6
|
+
"packages": {
|
|
7
|
+
"": {
|
|
8
|
+
"name": "mobile-get-adb-url-example",
|
|
9
|
+
"version": "1.0.0",
|
|
10
|
+
"dependencies": {
|
|
11
|
+
"@aliyun/wuying-agentbay-sdk": "file:../../../"
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@types/node": "^20.0.0",
|
|
15
|
+
"ts-node": "^10.9.1",
|
|
16
|
+
"typescript": "^5.0.0"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"../../..": {
|
|
20
|
+
"name": "wuying-agentbay-sdk",
|
|
21
|
+
"version": "0.9.4",
|
|
22
|
+
"license": "Apache-2.0",
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@alicloud/openapi-core": "^1.0.4",
|
|
25
|
+
"@darabonba/typescript": "^1.0.0",
|
|
26
|
+
"@types/node-fetch": "^2.6.13",
|
|
27
|
+
"axios": "^1.3.4",
|
|
28
|
+
"node-fetch": "^2.7.0",
|
|
29
|
+
"playwright": "^1.55.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/chai": "^5.2.2",
|
|
33
|
+
"@types/jest": "^26.0.24",
|
|
34
|
+
"@types/mocha": "^10.0.10",
|
|
35
|
+
"@types/node": "^18.15.0",
|
|
36
|
+
"@types/sinon": "^10.0.0",
|
|
37
|
+
"@typescript-eslint/eslint-plugin": "^5.54.0",
|
|
38
|
+
"@typescript-eslint/parser": "^5.54.0",
|
|
39
|
+
"abort-controller": "^3.0.0",
|
|
40
|
+
"axios-mock-adapter": "^2.1.0",
|
|
41
|
+
"chai": "^4.3.7",
|
|
42
|
+
"dotenv": "^16.5.0",
|
|
43
|
+
"eslint": "^8.35.0",
|
|
44
|
+
"jest": "^26.6.3",
|
|
45
|
+
"prettier": "^2.8.4",
|
|
46
|
+
"sinon": "^15.2.0",
|
|
47
|
+
"ts-jest": "^26.5.6",
|
|
48
|
+
"ts-node": "^10.9.2",
|
|
49
|
+
"tsup": "^8.5.0",
|
|
50
|
+
"typescript": "^4.9.5"
|
|
51
|
+
},
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": ">=14.0.0"
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"node_modules/@aliyun/wuying-agentbay-sdk": {
|
|
57
|
+
"resolved": "../../..",
|
|
58
|
+
"link": true
|
|
59
|
+
},
|
|
60
|
+
"node_modules/@cspotcode/source-map-support": {
|
|
61
|
+
"version": "0.8.1",
|
|
62
|
+
"resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
|
|
63
|
+
"integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
|
|
64
|
+
"dev": true,
|
|
65
|
+
"license": "MIT",
|
|
66
|
+
"dependencies": {
|
|
67
|
+
"@jridgewell/trace-mapping": "0.3.9"
|
|
68
|
+
},
|
|
69
|
+
"engines": {
|
|
70
|
+
"node": ">=12"
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"node_modules/@jridgewell/resolve-uri": {
|
|
74
|
+
"version": "3.1.2",
|
|
75
|
+
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
|
76
|
+
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
|
77
|
+
"dev": true,
|
|
78
|
+
"license": "MIT",
|
|
79
|
+
"engines": {
|
|
80
|
+
"node": ">=6.0.0"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"node_modules/@jridgewell/sourcemap-codec": {
|
|
84
|
+
"version": "1.5.5",
|
|
85
|
+
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
|
86
|
+
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
|
87
|
+
"dev": true,
|
|
88
|
+
"license": "MIT"
|
|
89
|
+
},
|
|
90
|
+
"node_modules/@jridgewell/trace-mapping": {
|
|
91
|
+
"version": "0.3.9",
|
|
92
|
+
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
|
|
93
|
+
"integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
|
|
94
|
+
"dev": true,
|
|
95
|
+
"license": "MIT",
|
|
96
|
+
"dependencies": {
|
|
97
|
+
"@jridgewell/resolve-uri": "^3.0.3",
|
|
98
|
+
"@jridgewell/sourcemap-codec": "^1.4.10"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"node_modules/@tsconfig/node10": {
|
|
102
|
+
"version": "1.0.11",
|
|
103
|
+
"resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz",
|
|
104
|
+
"integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==",
|
|
105
|
+
"dev": true,
|
|
106
|
+
"license": "MIT"
|
|
107
|
+
},
|
|
108
|
+
"node_modules/@tsconfig/node12": {
|
|
109
|
+
"version": "1.0.11",
|
|
110
|
+
"resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
|
|
111
|
+
"integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
|
|
112
|
+
"dev": true,
|
|
113
|
+
"license": "MIT"
|
|
114
|
+
},
|
|
115
|
+
"node_modules/@tsconfig/node14": {
|
|
116
|
+
"version": "1.0.3",
|
|
117
|
+
"resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
|
|
118
|
+
"integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
|
|
119
|
+
"dev": true,
|
|
120
|
+
"license": "MIT"
|
|
121
|
+
},
|
|
122
|
+
"node_modules/@tsconfig/node16": {
|
|
123
|
+
"version": "1.0.4",
|
|
124
|
+
"resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
|
|
125
|
+
"integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
|
|
126
|
+
"dev": true,
|
|
127
|
+
"license": "MIT"
|
|
128
|
+
},
|
|
129
|
+
"node_modules/@types/node": {
|
|
130
|
+
"version": "20.19.23",
|
|
131
|
+
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.23.tgz",
|
|
132
|
+
"integrity": "sha512-yIdlVVVHXpmqRhtyovZAcSy0MiPcYWGkoO4CGe/+jpP0hmNuihm4XhHbADpK++MsiLHP5MVlv+bcgdF99kSiFQ==",
|
|
133
|
+
"dev": true,
|
|
134
|
+
"license": "MIT",
|
|
135
|
+
"dependencies": {
|
|
136
|
+
"undici-types": "~6.21.0"
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
"node_modules/acorn": {
|
|
140
|
+
"version": "8.15.0",
|
|
141
|
+
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
|
142
|
+
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
|
143
|
+
"dev": true,
|
|
144
|
+
"license": "MIT",
|
|
145
|
+
"bin": {
|
|
146
|
+
"acorn": "bin/acorn"
|
|
147
|
+
},
|
|
148
|
+
"engines": {
|
|
149
|
+
"node": ">=0.4.0"
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
"node_modules/acorn-walk": {
|
|
153
|
+
"version": "8.3.4",
|
|
154
|
+
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
|
|
155
|
+
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
|
|
156
|
+
"dev": true,
|
|
157
|
+
"license": "MIT",
|
|
158
|
+
"dependencies": {
|
|
159
|
+
"acorn": "^8.11.0"
|
|
160
|
+
},
|
|
161
|
+
"engines": {
|
|
162
|
+
"node": ">=0.4.0"
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
"node_modules/arg": {
|
|
166
|
+
"version": "4.1.3",
|
|
167
|
+
"resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
|
|
168
|
+
"integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
|
|
169
|
+
"dev": true,
|
|
170
|
+
"license": "MIT"
|
|
171
|
+
},
|
|
172
|
+
"node_modules/create-require": {
|
|
173
|
+
"version": "1.1.1",
|
|
174
|
+
"resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
|
|
175
|
+
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
|
176
|
+
"dev": true,
|
|
177
|
+
"license": "MIT"
|
|
178
|
+
},
|
|
179
|
+
"node_modules/diff": {
|
|
180
|
+
"version": "4.0.2",
|
|
181
|
+
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
|
182
|
+
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
|
183
|
+
"dev": true,
|
|
184
|
+
"license": "BSD-3-Clause",
|
|
185
|
+
"engines": {
|
|
186
|
+
"node": ">=0.3.1"
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
"node_modules/make-error": {
|
|
190
|
+
"version": "1.3.6",
|
|
191
|
+
"resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
|
|
192
|
+
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
|
193
|
+
"dev": true,
|
|
194
|
+
"license": "ISC"
|
|
195
|
+
},
|
|
196
|
+
"node_modules/ts-node": {
|
|
197
|
+
"version": "10.9.2",
|
|
198
|
+
"resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz",
|
|
199
|
+
"integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==",
|
|
200
|
+
"dev": true,
|
|
201
|
+
"license": "MIT",
|
|
202
|
+
"dependencies": {
|
|
203
|
+
"@cspotcode/source-map-support": "^0.8.0",
|
|
204
|
+
"@tsconfig/node10": "^1.0.7",
|
|
205
|
+
"@tsconfig/node12": "^1.0.7",
|
|
206
|
+
"@tsconfig/node14": "^1.0.0",
|
|
207
|
+
"@tsconfig/node16": "^1.0.2",
|
|
208
|
+
"acorn": "^8.4.1",
|
|
209
|
+
"acorn-walk": "^8.1.1",
|
|
210
|
+
"arg": "^4.1.0",
|
|
211
|
+
"create-require": "^1.1.0",
|
|
212
|
+
"diff": "^4.0.1",
|
|
213
|
+
"make-error": "^1.1.1",
|
|
214
|
+
"v8-compile-cache-lib": "^3.0.1",
|
|
215
|
+
"yn": "3.1.1"
|
|
216
|
+
},
|
|
217
|
+
"bin": {
|
|
218
|
+
"ts-node": "dist/bin.js",
|
|
219
|
+
"ts-node-cwd": "dist/bin-cwd.js",
|
|
220
|
+
"ts-node-esm": "dist/bin-esm.js",
|
|
221
|
+
"ts-node-script": "dist/bin-script.js",
|
|
222
|
+
"ts-node-transpile-only": "dist/bin-transpile.js",
|
|
223
|
+
"ts-script": "dist/bin-script-deprecated.js"
|
|
224
|
+
},
|
|
225
|
+
"peerDependencies": {
|
|
226
|
+
"@swc/core": ">=1.2.50",
|
|
227
|
+
"@swc/wasm": ">=1.2.50",
|
|
228
|
+
"@types/node": "*",
|
|
229
|
+
"typescript": ">=2.7"
|
|
230
|
+
},
|
|
231
|
+
"peerDependenciesMeta": {
|
|
232
|
+
"@swc/core": {
|
|
233
|
+
"optional": true
|
|
234
|
+
},
|
|
235
|
+
"@swc/wasm": {
|
|
236
|
+
"optional": true
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
},
|
|
240
|
+
"node_modules/typescript": {
|
|
241
|
+
"version": "5.9.3",
|
|
242
|
+
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
|
243
|
+
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
|
244
|
+
"dev": true,
|
|
245
|
+
"license": "Apache-2.0",
|
|
246
|
+
"bin": {
|
|
247
|
+
"tsc": "bin/tsc",
|
|
248
|
+
"tsserver": "bin/tsserver"
|
|
249
|
+
},
|
|
250
|
+
"engines": {
|
|
251
|
+
"node": ">=14.17"
|
|
252
|
+
}
|
|
253
|
+
},
|
|
254
|
+
"node_modules/undici-types": {
|
|
255
|
+
"version": "6.21.0",
|
|
256
|
+
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
|
257
|
+
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
|
258
|
+
"dev": true,
|
|
259
|
+
"license": "MIT"
|
|
260
|
+
},
|
|
261
|
+
"node_modules/v8-compile-cache-lib": {
|
|
262
|
+
"version": "3.0.1",
|
|
263
|
+
"resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
|
|
264
|
+
"integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
|
|
265
|
+
"dev": true,
|
|
266
|
+
"license": "MIT"
|
|
267
|
+
},
|
|
268
|
+
"node_modules/yn": {
|
|
269
|
+
"version": "3.1.1",
|
|
270
|
+
"resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
|
|
271
|
+
"integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
|
|
272
|
+
"dev": true,
|
|
273
|
+
"license": "MIT",
|
|
274
|
+
"engines": {
|
|
275
|
+
"node": ">=6"
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|