@techery/appspector-mcp 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.
- package/LICENSE +21 -0
- package/README.md +293 -0
- package/dist/__tests__/api-client.test.d.ts +2 -0
- package/dist/__tests__/api-client.test.d.ts.map +1 -0
- package/dist/__tests__/api-client.test.js +88 -0
- package/dist/__tests__/api-client.test.js.map +1 -0
- package/dist/__tests__/session-loader.test.d.ts +2 -0
- package/dist/__tests__/session-loader.test.d.ts.map +1 -0
- package/dist/__tests__/session-loader.test.js +189 -0
- package/dist/__tests__/session-loader.test.js.map +1 -0
- package/dist/api-client.d.ts +29 -0
- package/dist/api-client.d.ts.map +1 -0
- package/dist/api-client.js +97 -0
- package/dist/api-client.js.map +1 -0
- package/dist/http-server.d.ts +3 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +426 -0
- package/dist/http-server.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +579 -0
- package/dist/index.js.map +1 -0
- package/dist/session-loader.d.ts +16 -0
- package/dist/session-loader.d.ts.map +1 -0
- package/dist/session-loader.js +258 -0
- package/dist/session-loader.js.map +1 -0
- package/dist/types.d.ts +177 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/package.json +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Techery
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
# AppSpector MCP Server
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) server for AppSpector - enables loading console/network logs from mobile devices and executing curl commands from captured HTTP requests.
|
|
4
|
+
|
|
5
|
+
## Quick Start with npx
|
|
6
|
+
|
|
7
|
+
Run directly without installation:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx @techery/appspector-mcp
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Or with authentication:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
EMAIL=your@email.com PASSWORD=yourpassword npx @techery/appspector-mcp
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
|
|
21
|
+
- **Authentication**: Login with email/password to AppSpector
|
|
22
|
+
- **Apps Management**: List all apps in your account
|
|
23
|
+
- **Sessions**: View online and historical sessions
|
|
24
|
+
- **Console Logs**: Fetch and filter console logs from sessions
|
|
25
|
+
- **HTTP Logs**: View network requests with full details (headers, body, timings)
|
|
26
|
+
- **cURL Generation**: Generate curl commands from captured HTTP requests
|
|
27
|
+
- **cURL Execution**: Execute curl commands directly to replay requests
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
### Global Installation
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm install -g @techery/appspector-mcp
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Then run:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
appspector-mcp
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Local Installation
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
npm install @techery/appspector-mcp
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Configuration for Claude Desktop
|
|
50
|
+
|
|
51
|
+
Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):
|
|
52
|
+
|
|
53
|
+
### Using npx (Recommended)
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"mcpServers": {
|
|
58
|
+
"appspector": {
|
|
59
|
+
"command": "npx",
|
|
60
|
+
"args": ["-y", "@techery/appspector-mcp"],
|
|
61
|
+
"env": {
|
|
62
|
+
"EMAIL": "your@email.com",
|
|
63
|
+
"PASSWORD": "yourpassword"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Using Global Installation
|
|
71
|
+
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"mcpServers": {
|
|
75
|
+
"appspector": {
|
|
76
|
+
"command": "appspector-mcp",
|
|
77
|
+
"env": {
|
|
78
|
+
"EMAIL": "your@email.com",
|
|
79
|
+
"PASSWORD": "yourpassword"
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Without Auto-Login
|
|
87
|
+
|
|
88
|
+
If you prefer to login manually via the `login` tool:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"mcpServers": {
|
|
93
|
+
"appspector": {
|
|
94
|
+
"command": "npx",
|
|
95
|
+
"args": ["-y", "@techery/appspector-mcp"]
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Available Tools
|
|
102
|
+
|
|
103
|
+
### `login`
|
|
104
|
+
Login to AppSpector with your email and password.
|
|
105
|
+
|
|
106
|
+
**Parameters:**
|
|
107
|
+
- `email` (string): Your AppSpector email
|
|
108
|
+
- `password` (string): Your AppSpector password
|
|
109
|
+
|
|
110
|
+
### `get_apps`
|
|
111
|
+
Get list of all apps in your AppSpector account.
|
|
112
|
+
|
|
113
|
+
### `get_sessions`
|
|
114
|
+
Get sessions for an app or all online sessions.
|
|
115
|
+
|
|
116
|
+
**Parameters:**
|
|
117
|
+
- `app_id` (number, optional): App ID to get sessions for
|
|
118
|
+
- `limit` (number, optional): Maximum number of sessions (default: 20)
|
|
119
|
+
|
|
120
|
+
### `get_console_logs`
|
|
121
|
+
Get console logs from a session.
|
|
122
|
+
|
|
123
|
+
**Parameters:**
|
|
124
|
+
- `app_id` (number): App ID
|
|
125
|
+
- `session_id` (string): Session ID
|
|
126
|
+
- `limit` (number, optional): Maximum number of logs (default: 100)
|
|
127
|
+
- `level` (string, optional): Filter by log level (verbose, debug, info, warning, error)
|
|
128
|
+
- `search` (string, optional): Search term to filter logs
|
|
129
|
+
|
|
130
|
+
### `get_http_logs`
|
|
131
|
+
Get HTTP/network logs from a session.
|
|
132
|
+
|
|
133
|
+
**Parameters:**
|
|
134
|
+
- `app_id` (number): App ID
|
|
135
|
+
- `session_id` (string): Session ID
|
|
136
|
+
- `limit` (number, optional): Maximum number of logs (default: 50)
|
|
137
|
+
- `method` (string, optional): Filter by HTTP method
|
|
138
|
+
- `status` (number, optional): Filter by status code
|
|
139
|
+
- `host` (string, optional): Filter by host
|
|
140
|
+
- `search` (string, optional): Search term to filter by URL
|
|
141
|
+
|
|
142
|
+
### `get_http_log_details`
|
|
143
|
+
Get detailed information about a specific HTTP request.
|
|
144
|
+
|
|
145
|
+
**Parameters:**
|
|
146
|
+
- `app_id` (number): App ID
|
|
147
|
+
- `session_id` (string): Session ID
|
|
148
|
+
- `request_uid` (string): Request UID from get_http_logs
|
|
149
|
+
|
|
150
|
+
### `get_curl`
|
|
151
|
+
Generate a curl command from an HTTP request.
|
|
152
|
+
|
|
153
|
+
**Parameters:**
|
|
154
|
+
- `app_id` (number): App ID
|
|
155
|
+
- `session_id` (string): Session ID
|
|
156
|
+
- `request_uid` (string): Request UID from get_http_logs
|
|
157
|
+
|
|
158
|
+
### `execute_curl`
|
|
159
|
+
Execute a curl command (generated from HTTP request or custom).
|
|
160
|
+
|
|
161
|
+
**Parameters:**
|
|
162
|
+
- `app_id` (number, optional): App ID (required with request_uid)
|
|
163
|
+
- `session_id` (string, optional): Session ID (required with request_uid)
|
|
164
|
+
- `request_uid` (string, optional): Request UID to replay
|
|
165
|
+
- `curl_command` (string, optional): Custom curl command
|
|
166
|
+
|
|
167
|
+
### `clear_cache`
|
|
168
|
+
Clear the session data cache.
|
|
169
|
+
|
|
170
|
+
**Parameters:**
|
|
171
|
+
- `session_id` (string, optional): Specific session to clear
|
|
172
|
+
|
|
173
|
+
## Usage Example
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
1. Login to AppSpector
|
|
177
|
+
→ Use login tool with email and password (or set EMAIL/PASSWORD env vars)
|
|
178
|
+
|
|
179
|
+
2. List your apps
|
|
180
|
+
→ Use get_apps tool
|
|
181
|
+
|
|
182
|
+
3. Get sessions for an app
|
|
183
|
+
→ Use get_sessions with app_id
|
|
184
|
+
|
|
185
|
+
4. View HTTP logs
|
|
186
|
+
→ Use get_http_logs with app_id and session_id
|
|
187
|
+
|
|
188
|
+
5. Get details of a specific request
|
|
189
|
+
→ Use get_http_log_details with request_uid
|
|
190
|
+
|
|
191
|
+
6. Generate and execute curl
|
|
192
|
+
→ Use get_curl to generate curl command
|
|
193
|
+
→ Use execute_curl to replay the request
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Deployment Options
|
|
197
|
+
|
|
198
|
+
### 1. npx (Recommended for Claude Desktop)
|
|
199
|
+
|
|
200
|
+
```json
|
|
201
|
+
{
|
|
202
|
+
"mcpServers": {
|
|
203
|
+
"appspector": {
|
|
204
|
+
"command": "npx",
|
|
205
|
+
"args": ["-y", "@techery/appspector-mcp"],
|
|
206
|
+
"env": {
|
|
207
|
+
"EMAIL": "your@email.com",
|
|
208
|
+
"PASSWORD": "yourpassword"
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### 2. HTTP Server (SSE) - for remote deployment
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
npx @techery/appspector-mcp-http
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Or with environment variables:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
EMAIL=your@email.com PASSWORD=yourpassword npx @techery/appspector-mcp-http
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Server runs at `http://localhost:3000` with:
|
|
228
|
+
- `GET /sse` - SSE endpoint for MCP connections
|
|
229
|
+
- `GET /health` - Health check endpoint
|
|
230
|
+
|
|
231
|
+
### 3. Docker
|
|
232
|
+
|
|
233
|
+
Build and run:
|
|
234
|
+
```bash
|
|
235
|
+
# Clone and build
|
|
236
|
+
git clone https://github.com/techery/appspector-mcp.git
|
|
237
|
+
cd appspector-mcp
|
|
238
|
+
npm install
|
|
239
|
+
npm run docker:build
|
|
240
|
+
|
|
241
|
+
# Run
|
|
242
|
+
docker run -p 3000:3000 \
|
|
243
|
+
-e EMAIL=your@email.com \
|
|
244
|
+
-e PASSWORD=yourpassword \
|
|
245
|
+
appspector-mcp
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Or with docker-compose:
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
# Create .env file
|
|
252
|
+
echo "EMAIL=your@email.com" >> .env
|
|
253
|
+
echo "PASSWORD=yourpassword" >> .env
|
|
254
|
+
|
|
255
|
+
# Run
|
|
256
|
+
docker-compose up -d
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Environment Variables
|
|
260
|
+
|
|
261
|
+
| Variable | Description |
|
|
262
|
+
|----------|-------------|
|
|
263
|
+
| `EMAIL` | AppSpector account email for auto-login |
|
|
264
|
+
| `PASSWORD` | AppSpector account password for auto-login |
|
|
265
|
+
| `PORT` | HTTP server port (default: 3000) |
|
|
266
|
+
| `HOST` | HTTP server bind address (default: 0.0.0.0) |
|
|
267
|
+
|
|
268
|
+
## Development
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
# Clone repository
|
|
272
|
+
git clone https://github.com/techery/appspector-mcp.git
|
|
273
|
+
cd appspector-mcp
|
|
274
|
+
|
|
275
|
+
# Install dependencies
|
|
276
|
+
npm install
|
|
277
|
+
|
|
278
|
+
# Run stdio server in dev mode
|
|
279
|
+
npm run dev
|
|
280
|
+
|
|
281
|
+
# Run HTTP server in dev mode
|
|
282
|
+
npm run dev:http
|
|
283
|
+
|
|
284
|
+
# Build
|
|
285
|
+
npm run build
|
|
286
|
+
|
|
287
|
+
# Lint
|
|
288
|
+
npm run lint
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
## License
|
|
292
|
+
|
|
293
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/api-client.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll } from 'vitest';
|
|
2
|
+
import { AppSpectorApiClient } from '../api-client.js';
|
|
3
|
+
const TEST_EMAIL = process.env.TEST_EMAIL;
|
|
4
|
+
const TEST_PASSWORD = process.env.TEST_PASSWORD;
|
|
5
|
+
describe('AppSpectorApiClient', () => {
|
|
6
|
+
const client = new AppSpectorApiClient();
|
|
7
|
+
describe('authentication', () => {
|
|
8
|
+
it('should fail login with invalid credentials', async () => {
|
|
9
|
+
await expect(client.login('invalid@email.com', 'wrongpassword')).rejects.toThrow();
|
|
10
|
+
});
|
|
11
|
+
it('should login with valid credentials', async () => {
|
|
12
|
+
if (!TEST_EMAIL || !TEST_PASSWORD) {
|
|
13
|
+
console.log('Skipping: TEST_EMAIL and TEST_PASSWORD not set');
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
client.setCredentials({ email: TEST_EMAIL, password: TEST_PASSWORD });
|
|
17
|
+
const session = await client.login(TEST_EMAIL, TEST_PASSWORD);
|
|
18
|
+
expect(session).toBeDefined();
|
|
19
|
+
expect(session.email).toBe(TEST_EMAIL);
|
|
20
|
+
expect(session.token).toBeDefined();
|
|
21
|
+
expect(session.account).toBeDefined();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
describe('apps', () => {
|
|
25
|
+
beforeAll(async () => {
|
|
26
|
+
if (TEST_EMAIL && TEST_PASSWORD) {
|
|
27
|
+
client.setCredentials({ email: TEST_EMAIL, password: TEST_PASSWORD });
|
|
28
|
+
await client.login(TEST_EMAIL, TEST_PASSWORD);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
it('should get apps list', async () => {
|
|
32
|
+
if (!TEST_EMAIL || !TEST_PASSWORD) {
|
|
33
|
+
console.log('Skipping: TEST_EMAIL and TEST_PASSWORD not set');
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const apps = await client.getApps();
|
|
37
|
+
expect(apps).toBeDefined();
|
|
38
|
+
expect(Array.isArray(apps)).toBe(true);
|
|
39
|
+
if (apps.length > 0) {
|
|
40
|
+
const app = apps.at(0);
|
|
41
|
+
expect(app).toHaveProperty('id');
|
|
42
|
+
expect(app).toHaveProperty('name');
|
|
43
|
+
expect(app).toHaveProperty('platform');
|
|
44
|
+
expect(app).toHaveProperty('bundleId');
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
describe('sessions', () => {
|
|
49
|
+
beforeAll(async () => {
|
|
50
|
+
if (TEST_EMAIL && TEST_PASSWORD) {
|
|
51
|
+
client.setCredentials({ email: TEST_EMAIL, password: TEST_PASSWORD });
|
|
52
|
+
await client.login(TEST_EMAIL, TEST_PASSWORD);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
it('should get online sessions', async () => {
|
|
56
|
+
if (!TEST_EMAIL || !TEST_PASSWORD) {
|
|
57
|
+
console.log('Skipping: TEST_EMAIL and TEST_PASSWORD not set');
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const sessions = await client.getOnlineSessions();
|
|
61
|
+
expect(sessions).toBeDefined();
|
|
62
|
+
expect(Array.isArray(sessions)).toBe(true);
|
|
63
|
+
});
|
|
64
|
+
it('should get sessions by app', async () => {
|
|
65
|
+
if (!TEST_EMAIL || !TEST_PASSWORD) {
|
|
66
|
+
console.log('Skipping: TEST_EMAIL and TEST_PASSWORD not set');
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const apps = await client.getApps();
|
|
70
|
+
if (apps.length === 0) {
|
|
71
|
+
console.log('Skipping: No apps available');
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const appId = apps.at(0).id;
|
|
75
|
+
const sessions = await client.getSessionsByApp({ appId, limit: 5 });
|
|
76
|
+
expect(sessions).toBeDefined();
|
|
77
|
+
expect(Array.isArray(sessions)).toBe(true);
|
|
78
|
+
if (sessions.length > 0) {
|
|
79
|
+
const session = sessions.at(0);
|
|
80
|
+
expect(session).toHaveProperty('id');
|
|
81
|
+
expect(session).toHaveProperty('appName');
|
|
82
|
+
expect(session).toHaveProperty('device');
|
|
83
|
+
expect(session).toHaveProperty('state');
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
//# sourceMappingURL=api-client.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.test.js","sourceRoot":"","sources":["../../src/__tests__/api-client.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-loader.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/session-loader.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll } from 'vitest';
|
|
2
|
+
import { AppSpectorApiClient } from '../api-client.js';
|
|
3
|
+
import { loadSessionHistory, createCurlString } from '../session-loader.js';
|
|
4
|
+
const TEST_EMAIL = process.env.TEST_EMAIL;
|
|
5
|
+
const TEST_PASSWORD = process.env.TEST_PASSWORD;
|
|
6
|
+
describe('Session Loader', () => {
|
|
7
|
+
const client = new AppSpectorApiClient();
|
|
8
|
+
beforeAll(async () => {
|
|
9
|
+
if (TEST_EMAIL && TEST_PASSWORD) {
|
|
10
|
+
client.setCredentials({ email: TEST_EMAIL, password: TEST_PASSWORD });
|
|
11
|
+
await client.login(TEST_EMAIL, TEST_PASSWORD);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
describe('loadSessionHistory', () => {
|
|
15
|
+
it('should load session history with logs', async () => {
|
|
16
|
+
if (!TEST_EMAIL || !TEST_PASSWORD) {
|
|
17
|
+
console.log('Skipping: TEST_EMAIL and TEST_PASSWORD not set');
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const apps = await client.getApps();
|
|
21
|
+
if (apps.length === 0) {
|
|
22
|
+
console.log('Skipping: No apps available');
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const appId = apps.at(0).id;
|
|
26
|
+
const sessions = await client.getSessionsByApp({ appId, limit: 5 });
|
|
27
|
+
if (sessions.length === 0) {
|
|
28
|
+
console.log('Skipping: No sessions available');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const session = sessions.at(0);
|
|
32
|
+
const token = client.getToken();
|
|
33
|
+
if (!token) {
|
|
34
|
+
throw new Error('No token available');
|
|
35
|
+
}
|
|
36
|
+
const history = await loadSessionHistory({ session, userToken: token });
|
|
37
|
+
expect(history).toBeDefined();
|
|
38
|
+
expect(history).toHaveProperty('httpLogs');
|
|
39
|
+
expect(history).toHaveProperty('consoleLogs');
|
|
40
|
+
expect(Array.isArray(history.httpLogs)).toBe(true);
|
|
41
|
+
expect(Array.isArray(history.consoleLogs)).toBe(true);
|
|
42
|
+
console.log(`Loaded ${history.httpLogs.length} HTTP logs, ${history.consoleLogs.length} console logs`);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
describe('createCurlString', () => {
|
|
46
|
+
it('should generate curl for GET request', () => {
|
|
47
|
+
const log = {
|
|
48
|
+
uid: 'test-uid-1',
|
|
49
|
+
timestamp: Date.now(),
|
|
50
|
+
request: {
|
|
51
|
+
method: 'GET',
|
|
52
|
+
url: 'https://api.example.com/users?page=1',
|
|
53
|
+
protocol: 'https',
|
|
54
|
+
host: 'api.example.com',
|
|
55
|
+
pathname: '/users?page=1',
|
|
56
|
+
headers: {
|
|
57
|
+
'Authorization': 'Bearer token123',
|
|
58
|
+
'Accept': 'application/json',
|
|
59
|
+
},
|
|
60
|
+
body: new Uint8Array(),
|
|
61
|
+
isLargeBody: false,
|
|
62
|
+
},
|
|
63
|
+
response: {
|
|
64
|
+
statusCode: 200,
|
|
65
|
+
headers: { 'Content-Type': 'application/json' },
|
|
66
|
+
body: new Uint8Array(),
|
|
67
|
+
duration: 100,
|
|
68
|
+
isLargeBody: false,
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
const curl = createCurlString(log);
|
|
72
|
+
expect(curl).toBeDefined();
|
|
73
|
+
expect(curl).toContain('curl');
|
|
74
|
+
expect(curl).toContain('https://api.example.com/users?page=1');
|
|
75
|
+
expect(curl).toContain("-H 'Authorization: Bearer token123'");
|
|
76
|
+
expect(curl).toContain("-H 'Accept: application/json'");
|
|
77
|
+
});
|
|
78
|
+
it('should generate curl for POST request with body', () => {
|
|
79
|
+
const bodyContent = JSON.stringify({ name: 'Test', email: 'test@example.com' });
|
|
80
|
+
const bodyBytes = new TextEncoder().encode(bodyContent);
|
|
81
|
+
const log = {
|
|
82
|
+
uid: 'test-uid-2',
|
|
83
|
+
timestamp: Date.now(),
|
|
84
|
+
request: {
|
|
85
|
+
method: 'POST',
|
|
86
|
+
url: 'https://api.example.com/users',
|
|
87
|
+
protocol: 'https',
|
|
88
|
+
host: 'api.example.com',
|
|
89
|
+
pathname: '/users',
|
|
90
|
+
headers: {
|
|
91
|
+
'Content-Type': 'application/json',
|
|
92
|
+
'Authorization': 'Bearer token123',
|
|
93
|
+
},
|
|
94
|
+
body: bodyBytes,
|
|
95
|
+
isLargeBody: false,
|
|
96
|
+
},
|
|
97
|
+
response: {
|
|
98
|
+
statusCode: 201,
|
|
99
|
+
headers: { 'Content-Type': 'application/json' },
|
|
100
|
+
body: new Uint8Array(),
|
|
101
|
+
duration: 150,
|
|
102
|
+
isLargeBody: false,
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
const curl = createCurlString(log);
|
|
106
|
+
expect(curl).toBeDefined();
|
|
107
|
+
expect(curl).toContain('curl');
|
|
108
|
+
expect(curl).toContain('-X POST');
|
|
109
|
+
expect(curl).toContain('https://api.example.com/users');
|
|
110
|
+
expect(curl).toContain("-H 'Content-Type: application/json'");
|
|
111
|
+
expect(curl).toContain("-d '");
|
|
112
|
+
});
|
|
113
|
+
it('should generate curl for PUT request', () => {
|
|
114
|
+
const log = {
|
|
115
|
+
uid: 'test-uid-3',
|
|
116
|
+
timestamp: Date.now(),
|
|
117
|
+
request: {
|
|
118
|
+
method: 'PUT',
|
|
119
|
+
url: 'https://api.example.com/users/123',
|
|
120
|
+
protocol: 'https',
|
|
121
|
+
host: 'api.example.com',
|
|
122
|
+
pathname: '/users/123',
|
|
123
|
+
headers: {
|
|
124
|
+
'Content-Type': 'application/json',
|
|
125
|
+
},
|
|
126
|
+
body: new TextEncoder().encode('{"name":"Updated"}'),
|
|
127
|
+
isLargeBody: false,
|
|
128
|
+
},
|
|
129
|
+
response: {
|
|
130
|
+
statusCode: 200,
|
|
131
|
+
headers: {},
|
|
132
|
+
body: new Uint8Array(),
|
|
133
|
+
duration: 120,
|
|
134
|
+
isLargeBody: false,
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
const curl = createCurlString(log);
|
|
138
|
+
expect(curl).toBeDefined();
|
|
139
|
+
expect(curl).toContain('-X PUT');
|
|
140
|
+
});
|
|
141
|
+
it('should generate curl for DELETE request', () => {
|
|
142
|
+
const log = {
|
|
143
|
+
uid: 'test-uid-4',
|
|
144
|
+
timestamp: Date.now(),
|
|
145
|
+
request: {
|
|
146
|
+
method: 'DELETE',
|
|
147
|
+
url: 'https://api.example.com/users/123',
|
|
148
|
+
protocol: 'https',
|
|
149
|
+
host: 'api.example.com',
|
|
150
|
+
pathname: '/users/123',
|
|
151
|
+
headers: {},
|
|
152
|
+
body: new Uint8Array(),
|
|
153
|
+
isLargeBody: false,
|
|
154
|
+
},
|
|
155
|
+
response: {
|
|
156
|
+
statusCode: 204,
|
|
157
|
+
headers: {},
|
|
158
|
+
body: new Uint8Array(),
|
|
159
|
+
duration: 80,
|
|
160
|
+
isLargeBody: false,
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
const curl = createCurlString(log);
|
|
164
|
+
expect(curl).toBeDefined();
|
|
165
|
+
expect(curl).toContain('-X DELETE');
|
|
166
|
+
});
|
|
167
|
+
it('should handle request without response', () => {
|
|
168
|
+
const log = {
|
|
169
|
+
uid: 'test-uid-5',
|
|
170
|
+
timestamp: Date.now(),
|
|
171
|
+
request: {
|
|
172
|
+
method: 'GET',
|
|
173
|
+
url: 'https://api.example.com/pending',
|
|
174
|
+
protocol: 'https',
|
|
175
|
+
host: 'api.example.com',
|
|
176
|
+
pathname: '/pending',
|
|
177
|
+
headers: {},
|
|
178
|
+
body: new Uint8Array(),
|
|
179
|
+
isLargeBody: false,
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
const curl = createCurlString(log);
|
|
183
|
+
expect(curl).toBeDefined();
|
|
184
|
+
expect(curl).toContain('curl');
|
|
185
|
+
expect(curl).toContain('https://api.example.com/pending');
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
//# sourceMappingURL=session-loader.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-loader.test.js","sourceRoot":"","sources":["../../src/__tests__/session-loader.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { App, Session, UserSession } from './types.js';
|
|
2
|
+
export declare class AppSpectorApiClient {
|
|
3
|
+
private token;
|
|
4
|
+
private sessionCookie;
|
|
5
|
+
private email;
|
|
6
|
+
private password;
|
|
7
|
+
constructor(email?: string, password?: string);
|
|
8
|
+
setCredentials({ email, password }: {
|
|
9
|
+
email: string;
|
|
10
|
+
password: string;
|
|
11
|
+
}): void;
|
|
12
|
+
private ensureAuthenticated;
|
|
13
|
+
private request;
|
|
14
|
+
login(email: string, password: string): Promise<UserSession>;
|
|
15
|
+
getApps(): Promise<ReadonlyArray<App>>;
|
|
16
|
+
getSessionsByApp({ appId, limit, fromId, query, }: {
|
|
17
|
+
appId: number;
|
|
18
|
+
limit?: number;
|
|
19
|
+
fromId?: number;
|
|
20
|
+
query?: string;
|
|
21
|
+
}): Promise<ReadonlyArray<Session>>;
|
|
22
|
+
getOnlineSessions(): Promise<ReadonlyArray<Session>>;
|
|
23
|
+
getSession({ appId, sessionId }: {
|
|
24
|
+
appId: number;
|
|
25
|
+
sessionId: string;
|
|
26
|
+
}): Promise<Session>;
|
|
27
|
+
getToken(): string | null;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=api-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI5D,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,QAAQ,CAAuB;gBAE3B,KAAK,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM;IAK7C,cAAc,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;YAOhE,mBAAmB;YAYnB,OAAO;IAoCf,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IA+B5D,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAMtC,gBAAgB,CAAC,EACrB,KAAK,EACL,KAAU,EACV,MAAU,EACV,KAAU,GACX,EAAE;QACD,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAM7B,iBAAiB,IAAI,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAMpD,UAAU,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAM9F,QAAQ,IAAI,MAAM,GAAG,IAAI;CAG1B"}
|