@cloudflare/sandbox 0.4.11 → 0.4.14
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/.turbo/turbo-build.log +13 -47
- package/CHANGELOG.md +44 -16
- package/Dockerfile +15 -9
- package/README.md +0 -1
- package/dist/index.d.ts +1889 -9
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3144 -65
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/clients/base-client.ts +39 -24
- package/src/clients/command-client.ts +8 -8
- package/src/clients/file-client.ts +31 -26
- package/src/clients/git-client.ts +3 -4
- package/src/clients/index.ts +12 -16
- package/src/clients/interpreter-client.ts +51 -47
- package/src/clients/port-client.ts +10 -10
- package/src/clients/process-client.ts +11 -8
- package/src/clients/sandbox-client.ts +2 -4
- package/src/clients/types.ts +6 -2
- package/src/clients/utility-client.ts +10 -6
- package/src/errors/adapter.ts +90 -32
- package/src/errors/classes.ts +189 -64
- package/src/errors/index.ts +9 -5
- package/src/file-stream.ts +11 -6
- package/src/index.ts +22 -15
- package/src/interpreter.ts +50 -41
- package/src/request-handler.ts +24 -21
- package/src/sandbox.ts +370 -148
- package/src/security.ts +21 -6
- package/src/sse-parser.ts +4 -3
- package/src/version.ts +1 -1
- package/tests/base-client.test.ts +116 -80
- package/tests/command-client.test.ts +149 -112
- package/tests/file-client.test.ts +309 -197
- package/tests/file-stream.test.ts +24 -20
- package/tests/get-sandbox.test.ts +45 -6
- package/tests/git-client.test.ts +188 -101
- package/tests/port-client.test.ts +100 -108
- package/tests/process-client.test.ts +204 -179
- package/tests/request-handler.test.ts +117 -65
- package/tests/sandbox.test.ts +220 -68
- package/tests/sse-parser.test.ts +17 -16
- package/tests/utility-client.test.ts +79 -72
- package/tsdown.config.ts +12 -0
- package/vitest.config.ts +6 -6
- package/dist/chunk-BFVUNTP4.js +0 -104
- package/dist/chunk-BFVUNTP4.js.map +0 -1
- package/dist/chunk-EKSWCBCA.js +0 -86
- package/dist/chunk-EKSWCBCA.js.map +0 -1
- package/dist/chunk-FE4PJSRB.js +0 -7
- package/dist/chunk-FE4PJSRB.js.map +0 -1
- package/dist/chunk-JXZMAU2C.js +0 -559
- package/dist/chunk-JXZMAU2C.js.map +0 -1
- package/dist/chunk-SVWLTRHD.js +0 -2456
- package/dist/chunk-SVWLTRHD.js.map +0 -1
- package/dist/chunk-Z532A7QC.js +0 -78
- package/dist/chunk-Z532A7QC.js.map +0 -1
- package/dist/file-stream.d.ts +0 -43
- package/dist/file-stream.js +0 -9
- package/dist/file-stream.js.map +0 -1
- package/dist/interpreter.d.ts +0 -33
- package/dist/interpreter.js +0 -8
- package/dist/interpreter.js.map +0 -1
- package/dist/request-handler.d.ts +0 -18
- package/dist/request-handler.js +0 -13
- package/dist/request-handler.js.map +0 -1
- package/dist/sandbox-DWQVgVTY.d.ts +0 -603
- package/dist/sandbox.d.ts +0 -4
- package/dist/sandbox.js +0 -13
- package/dist/sandbox.js.map +0 -1
- package/dist/security.d.ts +0 -31
- package/dist/security.js +0 -13
- package/dist/security.js.map +0 -1
- package/dist/sse-parser.d.ts +0 -28
- package/dist/sse-parser.js +0 -11
- package/dist/sse-parser.js.map +0 -1
- package/dist/version.d.ts +0 -8
- package/dist/version.js +0 -7
- package/dist/version.js.map +0 -1
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
2
|
import type { ExecuteResponse } from '../src/clients';
|
|
3
3
|
import { CommandClient } from '../src/clients/command-client';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
CommandError,
|
|
6
|
+
CommandNotFoundError,
|
|
7
|
+
SandboxError
|
|
8
|
+
} from '../src/errors';
|
|
5
9
|
|
|
6
10
|
describe('CommandClient', () => {
|
|
7
11
|
let client: CommandClient;
|
|
@@ -11,18 +15,18 @@ describe('CommandClient', () => {
|
|
|
11
15
|
|
|
12
16
|
beforeEach(() => {
|
|
13
17
|
vi.clearAllMocks();
|
|
14
|
-
|
|
18
|
+
|
|
15
19
|
mockFetch = vi.fn();
|
|
16
20
|
global.fetch = mockFetch as unknown as typeof fetch;
|
|
17
|
-
|
|
21
|
+
|
|
18
22
|
onCommandComplete = vi.fn();
|
|
19
23
|
onError = vi.fn();
|
|
20
|
-
|
|
24
|
+
|
|
21
25
|
client = new CommandClient({
|
|
22
26
|
baseUrl: 'http://test.com',
|
|
23
27
|
port: 3000,
|
|
24
28
|
onCommandComplete,
|
|
25
|
-
onError
|
|
29
|
+
onError
|
|
26
30
|
});
|
|
27
31
|
});
|
|
28
32
|
|
|
@@ -38,13 +42,12 @@ describe('CommandClient', () => {
|
|
|
38
42
|
stderr: '',
|
|
39
43
|
exitCode: 0,
|
|
40
44
|
command: 'echo "Hello World"',
|
|
41
|
-
timestamp: '2023-01-01T00:00:00Z'
|
|
45
|
+
timestamp: '2023-01-01T00:00:00Z'
|
|
42
46
|
};
|
|
43
47
|
|
|
44
|
-
mockFetch.mockResolvedValue(
|
|
45
|
-
JSON.stringify(mockResponse),
|
|
46
|
-
|
|
47
|
-
));
|
|
48
|
+
mockFetch.mockResolvedValue(
|
|
49
|
+
new Response(JSON.stringify(mockResponse), { status: 200 })
|
|
50
|
+
);
|
|
48
51
|
|
|
49
52
|
const result = await client.execute('echo "Hello World"', 'session-exec');
|
|
50
53
|
|
|
@@ -54,7 +57,11 @@ describe('CommandClient', () => {
|
|
|
54
57
|
expect(result.exitCode).toBe(0);
|
|
55
58
|
expect(result.command).toBe('echo "Hello World"');
|
|
56
59
|
expect(onCommandComplete).toHaveBeenCalledWith(
|
|
57
|
-
true,
|
|
60
|
+
true,
|
|
61
|
+
0,
|
|
62
|
+
'Hello World\n',
|
|
63
|
+
'',
|
|
64
|
+
'echo "Hello World"'
|
|
58
65
|
);
|
|
59
66
|
});
|
|
60
67
|
|
|
@@ -65,13 +72,12 @@ describe('CommandClient', () => {
|
|
|
65
72
|
stderr: 'command not found: nonexistent-cmd\n',
|
|
66
73
|
exitCode: 127,
|
|
67
74
|
command: 'nonexistent-cmd',
|
|
68
|
-
timestamp: '2023-01-01T00:00:00Z'
|
|
75
|
+
timestamp: '2023-01-01T00:00:00Z'
|
|
69
76
|
};
|
|
70
77
|
|
|
71
|
-
mockFetch.mockResolvedValue(
|
|
72
|
-
JSON.stringify(mockResponse),
|
|
73
|
-
|
|
74
|
-
));
|
|
78
|
+
mockFetch.mockResolvedValue(
|
|
79
|
+
new Response(JSON.stringify(mockResponse), { status: 200 })
|
|
80
|
+
);
|
|
75
81
|
|
|
76
82
|
const result = await client.execute('nonexistent-cmd', 'session-exec');
|
|
77
83
|
|
|
@@ -80,7 +86,11 @@ describe('CommandClient', () => {
|
|
|
80
86
|
expect(result.stderr).toContain('command not found');
|
|
81
87
|
expect(result.stdout).toBe('');
|
|
82
88
|
expect(onCommandComplete).toHaveBeenCalledWith(
|
|
83
|
-
false,
|
|
89
|
+
false,
|
|
90
|
+
127,
|
|
91
|
+
'',
|
|
92
|
+
'command not found: nonexistent-cmd\n',
|
|
93
|
+
'nonexistent-cmd'
|
|
84
94
|
);
|
|
85
95
|
});
|
|
86
96
|
|
|
@@ -93,13 +103,13 @@ describe('CommandClient', () => {
|
|
|
93
103
|
timestamp: new Date().toISOString()
|
|
94
104
|
};
|
|
95
105
|
|
|
96
|
-
mockFetch.mockResolvedValue(
|
|
97
|
-
JSON.stringify(errorResponse),
|
|
98
|
-
|
|
99
|
-
));
|
|
106
|
+
mockFetch.mockResolvedValue(
|
|
107
|
+
new Response(JSON.stringify(errorResponse), { status: 404 })
|
|
108
|
+
);
|
|
100
109
|
|
|
101
|
-
await expect(client.execute('invalidcmd', 'session-err'))
|
|
102
|
-
|
|
110
|
+
await expect(client.execute('invalidcmd', 'session-err')).rejects.toThrow(
|
|
111
|
+
CommandNotFoundError
|
|
112
|
+
);
|
|
103
113
|
expect(onError).toHaveBeenCalledWith(
|
|
104
114
|
expect.stringContaining('Command not found'),
|
|
105
115
|
'invalidcmd'
|
|
@@ -109,30 +119,34 @@ describe('CommandClient', () => {
|
|
|
109
119
|
it('should handle network failures gracefully', async () => {
|
|
110
120
|
mockFetch.mockRejectedValue(new Error('Network connection failed'));
|
|
111
121
|
|
|
112
|
-
await expect(client.execute('ls', 'session-err'))
|
|
113
|
-
|
|
122
|
+
await expect(client.execute('ls', 'session-err')).rejects.toThrow(
|
|
123
|
+
'Network connection failed'
|
|
124
|
+
);
|
|
114
125
|
expect(onError).toHaveBeenCalledWith('Network connection failed', 'ls');
|
|
115
126
|
});
|
|
116
127
|
|
|
117
128
|
it('should handle server errors with proper status codes', async () => {
|
|
118
129
|
const scenarios = [
|
|
119
130
|
{ status: 400, code: 'COMMAND_EXECUTION_ERROR', error: CommandError },
|
|
120
|
-
{ status: 500, code: 'EXECUTION_ERROR', error: SandboxError }
|
|
131
|
+
{ status: 500, code: 'EXECUTION_ERROR', error: SandboxError }
|
|
121
132
|
];
|
|
122
133
|
|
|
123
134
|
for (const scenario of scenarios) {
|
|
124
|
-
mockFetch.mockResolvedValueOnce(
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
135
|
+
mockFetch.mockResolvedValueOnce(
|
|
136
|
+
new Response(
|
|
137
|
+
JSON.stringify({
|
|
138
|
+
code: scenario.code,
|
|
139
|
+
message: 'Test error',
|
|
140
|
+
context: {},
|
|
141
|
+
httpStatus: scenario.status,
|
|
142
|
+
timestamp: new Date().toISOString()
|
|
143
|
+
}),
|
|
144
|
+
{ status: scenario.status }
|
|
145
|
+
)
|
|
146
|
+
);
|
|
147
|
+
await expect(
|
|
148
|
+
client.execute('test-command', 'session-err')
|
|
149
|
+
).rejects.toThrow(scenario.error);
|
|
136
150
|
}
|
|
137
151
|
});
|
|
138
152
|
|
|
@@ -144,13 +158,12 @@ describe('CommandClient', () => {
|
|
|
144
158
|
stderr: '',
|
|
145
159
|
exitCode: 0,
|
|
146
160
|
command: 'find / -type f',
|
|
147
|
-
timestamp: '2023-01-01T00:00:00Z'
|
|
161
|
+
timestamp: '2023-01-01T00:00:00Z'
|
|
148
162
|
};
|
|
149
163
|
|
|
150
|
-
mockFetch.mockResolvedValue(
|
|
151
|
-
JSON.stringify(mockResponse),
|
|
152
|
-
|
|
153
|
-
));
|
|
164
|
+
mockFetch.mockResolvedValue(
|
|
165
|
+
new Response(JSON.stringify(mockResponse), { status: 200 })
|
|
166
|
+
);
|
|
154
167
|
|
|
155
168
|
const result = await client.execute('find / -type f', 'session-exec');
|
|
156
169
|
|
|
@@ -164,22 +177,24 @@ describe('CommandClient', () => {
|
|
|
164
177
|
mockFetch.mockImplementation((url: string, options: RequestInit) => {
|
|
165
178
|
const body = JSON.parse(options.body as string);
|
|
166
179
|
const command = body.command;
|
|
167
|
-
return Promise.resolve(
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
180
|
+
return Promise.resolve(
|
|
181
|
+
new Response(
|
|
182
|
+
JSON.stringify({
|
|
183
|
+
success: true,
|
|
184
|
+
stdout: `output for ${command}\n`,
|
|
185
|
+
stderr: '',
|
|
186
|
+
exitCode: 0,
|
|
187
|
+
command: command,
|
|
188
|
+
timestamp: '2023-01-01T00:00:00Z'
|
|
189
|
+
}),
|
|
190
|
+
{ status: 200 }
|
|
191
|
+
)
|
|
192
|
+
);
|
|
178
193
|
});
|
|
179
194
|
|
|
180
195
|
const commands = ['echo 1', 'echo 2', 'echo 3', 'pwd', 'ls'];
|
|
181
196
|
const results = await Promise.all(
|
|
182
|
-
commands.map(cmd => client.execute(cmd, 'session-concurrent'))
|
|
197
|
+
commands.map((cmd) => client.execute(cmd, 'session-concurrent'))
|
|
183
198
|
);
|
|
184
199
|
|
|
185
200
|
expect(results).toHaveLength(5);
|
|
@@ -192,13 +207,16 @@ describe('CommandClient', () => {
|
|
|
192
207
|
});
|
|
193
208
|
|
|
194
209
|
it('should handle malformed server responses', async () => {
|
|
195
|
-
mockFetch.mockResolvedValue(
|
|
196
|
-
'invalid json {',
|
|
197
|
-
|
|
198
|
-
|
|
210
|
+
mockFetch.mockResolvedValue(
|
|
211
|
+
new Response('invalid json {', {
|
|
212
|
+
status: 200,
|
|
213
|
+
headers: { 'Content-Type': 'application/json' }
|
|
214
|
+
})
|
|
215
|
+
);
|
|
199
216
|
|
|
200
|
-
await expect(client.execute('ls', 'session-err'))
|
|
201
|
-
|
|
217
|
+
await expect(client.execute('ls', 'session-err')).rejects.toThrow(
|
|
218
|
+
SandboxError
|
|
219
|
+
);
|
|
202
220
|
expect(onError).toHaveBeenCalled();
|
|
203
221
|
});
|
|
204
222
|
|
|
@@ -211,13 +229,13 @@ describe('CommandClient', () => {
|
|
|
211
229
|
timestamp: new Date().toISOString()
|
|
212
230
|
};
|
|
213
231
|
|
|
214
|
-
mockFetch.mockResolvedValue(
|
|
215
|
-
JSON.stringify(errorResponse),
|
|
216
|
-
|
|
217
|
-
));
|
|
232
|
+
mockFetch.mockResolvedValue(
|
|
233
|
+
new Response(JSON.stringify(errorResponse), { status: 400 })
|
|
234
|
+
);
|
|
218
235
|
|
|
219
|
-
await expect(client.execute('', 'session-err'))
|
|
220
|
-
|
|
236
|
+
await expect(client.execute('', 'session-err')).rejects.toThrow(
|
|
237
|
+
CommandError
|
|
238
|
+
);
|
|
221
239
|
});
|
|
222
240
|
|
|
223
241
|
it('should handle streaming command execution', async () => {
|
|
@@ -235,12 +253,17 @@ describe('CommandClient', () => {
|
|
|
235
253
|
}
|
|
236
254
|
});
|
|
237
255
|
|
|
238
|
-
mockFetch.mockResolvedValue(
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
256
|
+
mockFetch.mockResolvedValue(
|
|
257
|
+
new Response(mockStream, {
|
|
258
|
+
status: 200,
|
|
259
|
+
headers: { 'Content-Type': 'text/event-stream' }
|
|
260
|
+
})
|
|
261
|
+
);
|
|
242
262
|
|
|
243
|
-
const stream = await client.executeStream(
|
|
263
|
+
const stream = await client.executeStream(
|
|
264
|
+
'tail -f app.log',
|
|
265
|
+
'session-stream'
|
|
266
|
+
);
|
|
244
267
|
expect(stream).toBeInstanceOf(ReadableStream);
|
|
245
268
|
|
|
246
269
|
const reader = stream.getReader();
|
|
@@ -263,7 +286,6 @@ describe('CommandClient', () => {
|
|
|
263
286
|
expect(content).toContain('"type":"complete"');
|
|
264
287
|
});
|
|
265
288
|
|
|
266
|
-
|
|
267
289
|
it('should handle streaming errors gracefully', async () => {
|
|
268
290
|
const errorResponse = {
|
|
269
291
|
code: 'STREAM_START_ERROR',
|
|
@@ -273,13 +295,13 @@ describe('CommandClient', () => {
|
|
|
273
295
|
timestamp: new Date().toISOString()
|
|
274
296
|
};
|
|
275
297
|
|
|
276
|
-
mockFetch.mockResolvedValue(
|
|
277
|
-
JSON.stringify(errorResponse),
|
|
278
|
-
|
|
279
|
-
));
|
|
298
|
+
mockFetch.mockResolvedValue(
|
|
299
|
+
new Response(JSON.stringify(errorResponse), { status: 400 })
|
|
300
|
+
);
|
|
280
301
|
|
|
281
|
-
await expect(
|
|
282
|
-
.
|
|
302
|
+
await expect(
|
|
303
|
+
client.executeStream('invalid-stream-command', 'session-err')
|
|
304
|
+
).rejects.toThrow(CommandError);
|
|
283
305
|
expect(onError).toHaveBeenCalledWith(
|
|
284
306
|
expect.stringContaining('Command failed to start streaming'),
|
|
285
307
|
'invalid-stream-command'
|
|
@@ -287,20 +309,26 @@ describe('CommandClient', () => {
|
|
|
287
309
|
});
|
|
288
310
|
|
|
289
311
|
it('should handle streaming without response body', async () => {
|
|
290
|
-
mockFetch.mockResolvedValue(
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
312
|
+
mockFetch.mockResolvedValue(
|
|
313
|
+
new Response(null, {
|
|
314
|
+
status: 200,
|
|
315
|
+
headers: { 'Content-Type': 'text/event-stream' }
|
|
316
|
+
})
|
|
317
|
+
);
|
|
294
318
|
|
|
295
|
-
await expect(
|
|
296
|
-
.
|
|
319
|
+
await expect(
|
|
320
|
+
client.executeStream('test-command', 'session-err')
|
|
321
|
+
).rejects.toThrow('No response body for streaming');
|
|
297
322
|
});
|
|
298
323
|
|
|
299
324
|
it('should handle network failures during streaming setup', async () => {
|
|
300
|
-
mockFetch.mockRejectedValue(
|
|
325
|
+
mockFetch.mockRejectedValue(
|
|
326
|
+
new Error('Connection lost during streaming')
|
|
327
|
+
);
|
|
301
328
|
|
|
302
|
-
await expect(
|
|
303
|
-
.
|
|
329
|
+
await expect(
|
|
330
|
+
client.executeStream('stream-command', 'session-err')
|
|
331
|
+
).rejects.toThrow('Connection lost during streaming');
|
|
304
332
|
expect(onError).toHaveBeenCalledWith(
|
|
305
333
|
'Connection lost during streaming',
|
|
306
334
|
'stream-command'
|
|
@@ -312,7 +340,7 @@ describe('CommandClient', () => {
|
|
|
312
340
|
it('should work without any callbacks', async () => {
|
|
313
341
|
const clientWithoutCallbacks = new CommandClient({
|
|
314
342
|
baseUrl: 'http://test.com',
|
|
315
|
-
port: 3000
|
|
343
|
+
port: 3000
|
|
316
344
|
});
|
|
317
345
|
|
|
318
346
|
const mockResponse: ExecuteResponse = {
|
|
@@ -321,15 +349,17 @@ describe('CommandClient', () => {
|
|
|
321
349
|
stderr: '',
|
|
322
350
|
exitCode: 0,
|
|
323
351
|
command: 'echo test',
|
|
324
|
-
timestamp: '2023-01-01T00:00:00Z'
|
|
352
|
+
timestamp: '2023-01-01T00:00:00Z'
|
|
325
353
|
};
|
|
326
354
|
|
|
327
|
-
mockFetch.mockResolvedValue(
|
|
328
|
-
JSON.stringify(mockResponse),
|
|
329
|
-
|
|
330
|
-
));
|
|
355
|
+
mockFetch.mockResolvedValue(
|
|
356
|
+
new Response(JSON.stringify(mockResponse), { status: 200 })
|
|
357
|
+
);
|
|
331
358
|
|
|
332
|
-
const result = await clientWithoutCallbacks.execute(
|
|
359
|
+
const result = await clientWithoutCallbacks.execute(
|
|
360
|
+
'echo test',
|
|
361
|
+
'session-nocb'
|
|
362
|
+
);
|
|
333
363
|
|
|
334
364
|
expect(result.success).toBe(true);
|
|
335
365
|
expect(result.stdout).toBe('test output\n');
|
|
@@ -338,13 +368,14 @@ describe('CommandClient', () => {
|
|
|
338
368
|
it('should handle errors gracefully without callbacks', async () => {
|
|
339
369
|
const clientWithoutCallbacks = new CommandClient({
|
|
340
370
|
baseUrl: 'http://test.com',
|
|
341
|
-
port: 3000
|
|
371
|
+
port: 3000
|
|
342
372
|
});
|
|
343
373
|
|
|
344
374
|
mockFetch.mockRejectedValue(new Error('Network failed'));
|
|
345
375
|
|
|
346
|
-
await expect(
|
|
347
|
-
.
|
|
376
|
+
await expect(
|
|
377
|
+
clientWithoutCallbacks.execute('test', 'session-nocb')
|
|
378
|
+
).rejects.toThrow('Network failed');
|
|
348
379
|
});
|
|
349
380
|
|
|
350
381
|
it('should call onCommandComplete for both success and failure', async () => {
|
|
@@ -354,17 +385,20 @@ describe('CommandClient', () => {
|
|
|
354
385
|
stderr: '',
|
|
355
386
|
exitCode: 0,
|
|
356
387
|
command: 'echo success',
|
|
357
|
-
timestamp: '2023-01-01T00:00:00Z'
|
|
388
|
+
timestamp: '2023-01-01T00:00:00Z'
|
|
358
389
|
};
|
|
359
390
|
|
|
360
|
-
mockFetch.mockResolvedValueOnce(
|
|
361
|
-
JSON.stringify(successResponse),
|
|
362
|
-
|
|
363
|
-
));
|
|
391
|
+
mockFetch.mockResolvedValueOnce(
|
|
392
|
+
new Response(JSON.stringify(successResponse), { status: 200 })
|
|
393
|
+
);
|
|
364
394
|
|
|
365
395
|
await client.execute('echo success', 'session-cb');
|
|
366
396
|
expect(onCommandComplete).toHaveBeenLastCalledWith(
|
|
367
|
-
true,
|
|
397
|
+
true,
|
|
398
|
+
0,
|
|
399
|
+
'success\n',
|
|
400
|
+
'',
|
|
401
|
+
'echo success'
|
|
368
402
|
);
|
|
369
403
|
|
|
370
404
|
const failureResponse: ExecuteResponse = {
|
|
@@ -373,17 +407,20 @@ describe('CommandClient', () => {
|
|
|
373
407
|
stderr: 'error\n',
|
|
374
408
|
exitCode: 1,
|
|
375
409
|
command: 'false',
|
|
376
|
-
timestamp: '2023-01-01T00:00:00Z'
|
|
410
|
+
timestamp: '2023-01-01T00:00:00Z'
|
|
377
411
|
};
|
|
378
412
|
|
|
379
|
-
mockFetch.mockResolvedValueOnce(
|
|
380
|
-
JSON.stringify(failureResponse),
|
|
381
|
-
|
|
382
|
-
));
|
|
413
|
+
mockFetch.mockResolvedValueOnce(
|
|
414
|
+
new Response(JSON.stringify(failureResponse), { status: 200 })
|
|
415
|
+
);
|
|
383
416
|
|
|
384
417
|
await client.execute('false', 'session-cb');
|
|
385
418
|
expect(onCommandComplete).toHaveBeenLastCalledWith(
|
|
386
|
-
false,
|
|
419
|
+
false,
|
|
420
|
+
1,
|
|
421
|
+
'',
|
|
422
|
+
'error\n',
|
|
423
|
+
'false'
|
|
387
424
|
);
|
|
388
425
|
});
|
|
389
426
|
});
|
|
@@ -399,9 +436,9 @@ describe('CommandClient', () => {
|
|
|
399
436
|
baseUrl: 'http://custom.com',
|
|
400
437
|
port: 8080,
|
|
401
438
|
onCommandComplete: vi.fn(),
|
|
402
|
-
onError: vi.fn()
|
|
439
|
+
onError: vi.fn()
|
|
403
440
|
});
|
|
404
441
|
expect(fullOptionsClient).toBeDefined();
|
|
405
442
|
});
|
|
406
443
|
});
|
|
407
|
-
});
|
|
444
|
+
});
|