@cloudflare/sandbox 0.4.12 → 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.
Files changed (79) hide show
  1. package/.turbo/turbo-build.log +13 -47
  2. package/CHANGELOG.md +38 -16
  3. package/Dockerfile +15 -9
  4. package/README.md +0 -1
  5. package/dist/index.d.ts +1889 -9
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +3144 -65
  8. package/dist/index.js.map +1 -1
  9. package/package.json +5 -5
  10. package/src/clients/base-client.ts +39 -24
  11. package/src/clients/command-client.ts +8 -8
  12. package/src/clients/file-client.ts +31 -26
  13. package/src/clients/git-client.ts +3 -4
  14. package/src/clients/index.ts +12 -16
  15. package/src/clients/interpreter-client.ts +51 -47
  16. package/src/clients/port-client.ts +10 -10
  17. package/src/clients/process-client.ts +11 -8
  18. package/src/clients/sandbox-client.ts +2 -4
  19. package/src/clients/types.ts +6 -2
  20. package/src/clients/utility-client.ts +10 -6
  21. package/src/errors/adapter.ts +90 -32
  22. package/src/errors/classes.ts +189 -64
  23. package/src/errors/index.ts +9 -5
  24. package/src/file-stream.ts +11 -6
  25. package/src/index.ts +22 -15
  26. package/src/interpreter.ts +50 -41
  27. package/src/request-handler.ts +24 -21
  28. package/src/sandbox.ts +339 -149
  29. package/src/security.ts +21 -6
  30. package/src/sse-parser.ts +4 -3
  31. package/src/version.ts +1 -1
  32. package/tests/base-client.test.ts +116 -80
  33. package/tests/command-client.test.ts +149 -112
  34. package/tests/file-client.test.ts +309 -197
  35. package/tests/file-stream.test.ts +24 -20
  36. package/tests/get-sandbox.test.ts +10 -10
  37. package/tests/git-client.test.ts +188 -101
  38. package/tests/port-client.test.ts +100 -108
  39. package/tests/process-client.test.ts +204 -179
  40. package/tests/request-handler.test.ts +117 -65
  41. package/tests/sandbox.test.ts +219 -67
  42. package/tests/sse-parser.test.ts +17 -16
  43. package/tests/utility-client.test.ts +79 -72
  44. package/tsdown.config.ts +12 -0
  45. package/vitest.config.ts +6 -6
  46. package/dist/chunk-BFVUNTP4.js +0 -104
  47. package/dist/chunk-BFVUNTP4.js.map +0 -1
  48. package/dist/chunk-EKSWCBCA.js +0 -86
  49. package/dist/chunk-EKSWCBCA.js.map +0 -1
  50. package/dist/chunk-JXZMAU2C.js +0 -559
  51. package/dist/chunk-JXZMAU2C.js.map +0 -1
  52. package/dist/chunk-UJ3TV4M6.js +0 -7
  53. package/dist/chunk-UJ3TV4M6.js.map +0 -1
  54. package/dist/chunk-YE265ASX.js +0 -2484
  55. package/dist/chunk-YE265ASX.js.map +0 -1
  56. package/dist/chunk-Z532A7QC.js +0 -78
  57. package/dist/chunk-Z532A7QC.js.map +0 -1
  58. package/dist/file-stream.d.ts +0 -43
  59. package/dist/file-stream.js +0 -9
  60. package/dist/file-stream.js.map +0 -1
  61. package/dist/interpreter.d.ts +0 -33
  62. package/dist/interpreter.js +0 -8
  63. package/dist/interpreter.js.map +0 -1
  64. package/dist/request-handler.d.ts +0 -18
  65. package/dist/request-handler.js +0 -13
  66. package/dist/request-handler.js.map +0 -1
  67. package/dist/sandbox-CLZWpfGc.d.ts +0 -613
  68. package/dist/sandbox.d.ts +0 -4
  69. package/dist/sandbox.js +0 -13
  70. package/dist/sandbox.js.map +0 -1
  71. package/dist/security.d.ts +0 -31
  72. package/dist/security.js +0 -13
  73. package/dist/security.js.map +0 -1
  74. package/dist/sse-parser.d.ts +0 -28
  75. package/dist/sse-parser.js +0 -11
  76. package/dist/sse-parser.js.map +0 -1
  77. package/dist/version.d.ts +0 -8
  78. package/dist/version.js +0 -7
  79. package/dist/version.js.map +0 -1
@@ -1,8 +1,8 @@
1
1
  import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
- import type {
3
- ExposePortResponse,
2
+ import type {
3
+ ExposePortResponse,
4
4
  GetExposedPortsResponse,
5
- UnexposePortResponse
5
+ UnexposePortResponse
6
6
  } from '../src/clients';
7
7
  import { PortClient } from '../src/clients/port-client';
8
8
  import {
@@ -11,7 +11,7 @@ import {
11
11
  PortError,
12
12
  PortInUseError,
13
13
  PortNotExposedError,
14
- SandboxError,
14
+ SandboxError,
15
15
  ServiceNotRespondingError
16
16
  } from '../src/errors';
17
17
 
@@ -21,13 +21,13 @@ describe('PortClient', () => {
21
21
 
22
22
  beforeEach(() => {
23
23
  vi.clearAllMocks();
24
-
24
+
25
25
  mockFetch = vi.fn();
26
26
  global.fetch = mockFetch as unknown as typeof fetch;
27
-
27
+
28
28
  client = new PortClient({
29
29
  baseUrl: 'http://test.com',
30
- port: 3000,
30
+ port: 3000
31
31
  });
32
32
  });
33
33
 
@@ -42,13 +42,12 @@ describe('PortClient', () => {
42
42
  port: 3001,
43
43
  exposedAt: 'https://preview-abc123.workers.dev',
44
44
  name: 'web-server',
45
- timestamp: '2023-01-01T00:00:00Z',
45
+ timestamp: '2023-01-01T00:00:00Z'
46
46
  };
47
-
48
- mockFetch.mockResolvedValue(new Response(
49
- JSON.stringify(mockResponse),
50
- { status: 200 }
51
- ));
47
+
48
+ mockFetch.mockResolvedValue(
49
+ new Response(JSON.stringify(mockResponse), { status: 200 })
50
+ );
52
51
 
53
52
  const result = await client.exposePort(3001, 'session-123', 'web-server');
54
53
 
@@ -65,13 +64,12 @@ describe('PortClient', () => {
65
64
  port: 8080,
66
65
  exposedAt: 'https://api-def456.workers.dev',
67
66
  name: 'api-server',
68
- timestamp: '2023-01-01T00:00:00Z',
67
+ timestamp: '2023-01-01T00:00:00Z'
69
68
  };
70
-
71
- mockFetch.mockResolvedValue(new Response(
72
- JSON.stringify(mockResponse),
73
- { status: 200 }
74
- ));
69
+
70
+ mockFetch.mockResolvedValue(
71
+ new Response(JSON.stringify(mockResponse), { status: 200 })
72
+ );
75
73
 
76
74
  const result = await client.exposePort(8080, 'session-456', 'api-server');
77
75
 
@@ -86,13 +84,12 @@ describe('PortClient', () => {
86
84
  success: true,
87
85
  port: 5000,
88
86
  exposedAt: 'https://service-ghi789.workers.dev',
89
- timestamp: '2023-01-01T00:00:00Z',
87
+ timestamp: '2023-01-01T00:00:00Z'
90
88
  };
91
-
92
- mockFetch.mockResolvedValue(new Response(
93
- JSON.stringify(mockResponse),
94
- { status: 200 }
95
- ));
89
+
90
+ mockFetch.mockResolvedValue(
91
+ new Response(JSON.stringify(mockResponse), { status: 200 })
92
+ );
96
93
 
97
94
  const result = await client.exposePort(5000, 'session-789');
98
95
 
@@ -101,7 +98,6 @@ describe('PortClient', () => {
101
98
  expect(result.name).toBeUndefined();
102
99
  expect(result.exposedAt).toBeDefined();
103
100
  });
104
-
105
101
  });
106
102
 
107
103
  describe('service management', () => {
@@ -112,35 +108,34 @@ describe('PortClient', () => {
112
108
  {
113
109
  port: 3000,
114
110
  exposedAt: 'https://frontend-abc123.workers.dev',
115
- name: 'frontend',
111
+ name: 'frontend'
116
112
  },
117
113
  {
118
114
  port: 4000,
119
115
  exposedAt: 'https://api-def456.workers.dev',
120
- name: 'api',
116
+ name: 'api'
121
117
  },
122
118
  {
123
119
  port: 5432,
124
120
  exposedAt: 'https://db-ghi789.workers.dev',
125
- name: 'database',
121
+ name: 'database'
126
122
  }
127
123
  ],
128
124
  count: 3,
129
- timestamp: '2023-01-01T00:10:00Z',
125
+ timestamp: '2023-01-01T00:10:00Z'
130
126
  };
131
-
132
- mockFetch.mockResolvedValue(new Response(
133
- JSON.stringify(mockResponse),
134
- { status: 200 }
135
- ));
127
+
128
+ mockFetch.mockResolvedValue(
129
+ new Response(JSON.stringify(mockResponse), { status: 200 })
130
+ );
136
131
 
137
132
  const result = await client.getExposedPorts('session-list');
138
133
 
139
134
  expect(result.success).toBe(true);
140
135
  expect(result.count).toBe(3);
141
136
  expect(result.ports).toHaveLength(3);
142
-
143
- result.ports.forEach(service => {
137
+
138
+ result.ports.forEach((service) => {
144
139
  expect(service.exposedAt).toContain('.workers.dev');
145
140
  expect(service.port).toBeGreaterThan(0);
146
141
  expect(service.name).toBeDefined();
@@ -152,13 +147,12 @@ describe('PortClient', () => {
152
147
  success: true,
153
148
  ports: [],
154
149
  count: 0,
155
- timestamp: '2023-01-01T00:00:00Z',
150
+ timestamp: '2023-01-01T00:00:00Z'
156
151
  };
157
-
158
- mockFetch.mockResolvedValue(new Response(
159
- JSON.stringify(mockResponse),
160
- { status: 200 }
161
- ));
152
+
153
+ mockFetch.mockResolvedValue(
154
+ new Response(JSON.stringify(mockResponse), { status: 200 })
155
+ );
162
156
 
163
157
  const result = await client.getExposedPorts('session-empty');
164
158
 
@@ -171,20 +165,18 @@ describe('PortClient', () => {
171
165
  const mockResponse: UnexposePortResponse = {
172
166
  success: true,
173
167
  port: 3001,
174
- timestamp: '2023-01-01T00:15:00Z',
168
+ timestamp: '2023-01-01T00:15:00Z'
175
169
  };
176
-
177
- mockFetch.mockResolvedValue(new Response(
178
- JSON.stringify(mockResponse),
179
- { status: 200 }
180
- ));
170
+
171
+ mockFetch.mockResolvedValue(
172
+ new Response(JSON.stringify(mockResponse), { status: 200 })
173
+ );
181
174
 
182
175
  const result = await client.unexposePort(3001, 'session-unexpose');
183
176
 
184
177
  expect(result.success).toBe(true);
185
178
  expect(result.port).toBe(3001);
186
179
  });
187
-
188
180
  });
189
181
 
190
182
  describe('port validation and error handling', () => {
@@ -193,14 +185,14 @@ describe('PortClient', () => {
193
185
  error: 'Port already exposed: 3000',
194
186
  code: 'PORT_ALREADY_EXPOSED'
195
187
  };
196
-
197
- mockFetch.mockResolvedValue(new Response(
198
- JSON.stringify(errorResponse),
199
- { status: 409 }
200
- ));
201
-
202
- await expect(client.exposePort(3000, 'session-err'))
203
- .rejects.toThrow(PortAlreadyExposedError);
188
+
189
+ mockFetch.mockResolvedValue(
190
+ new Response(JSON.stringify(errorResponse), { status: 409 })
191
+ );
192
+
193
+ await expect(client.exposePort(3000, 'session-err')).rejects.toThrow(
194
+ PortAlreadyExposedError
195
+ );
204
196
  });
205
197
 
206
198
  it('should handle invalid port numbers', async () => {
@@ -208,14 +200,14 @@ describe('PortClient', () => {
208
200
  error: 'Invalid port number: 0',
209
201
  code: 'INVALID_PORT_NUMBER'
210
202
  };
211
-
212
- mockFetch.mockResolvedValue(new Response(
213
- JSON.stringify(errorResponse),
214
- { status: 400 }
215
- ));
216
-
217
- await expect(client.exposePort(0, 'session-err'))
218
- .rejects.toThrow(InvalidPortError);
203
+
204
+ mockFetch.mockResolvedValue(
205
+ new Response(JSON.stringify(errorResponse), { status: 400 })
206
+ );
207
+
208
+ await expect(client.exposePort(0, 'session-err')).rejects.toThrow(
209
+ InvalidPortError
210
+ );
219
211
  });
220
212
 
221
213
  it('should handle port in use errors', async () => {
@@ -223,14 +215,14 @@ describe('PortClient', () => {
223
215
  error: 'Port in use: 3000 is already bound by another process',
224
216
  code: 'PORT_IN_USE'
225
217
  };
226
-
227
- mockFetch.mockResolvedValue(new Response(
228
- JSON.stringify(errorResponse),
229
- { status: 409 }
230
- ));
231
-
232
- await expect(client.exposePort(3000, 'session-err'))
233
- .rejects.toThrow(PortInUseError);
218
+
219
+ mockFetch.mockResolvedValue(
220
+ new Response(JSON.stringify(errorResponse), { status: 409 })
221
+ );
222
+
223
+ await expect(client.exposePort(3000, 'session-err')).rejects.toThrow(
224
+ PortInUseError
225
+ );
234
226
  });
235
227
 
236
228
  it('should handle service not responding errors', async () => {
@@ -238,14 +230,14 @@ describe('PortClient', () => {
238
230
  error: 'Service not responding on port 8080',
239
231
  code: 'SERVICE_NOT_RESPONDING'
240
232
  };
241
-
242
- mockFetch.mockResolvedValue(new Response(
243
- JSON.stringify(errorResponse),
244
- { status: 503 }
245
- ));
246
-
247
- await expect(client.exposePort(8080, 'session-err'))
248
- .rejects.toThrow(ServiceNotRespondingError);
233
+
234
+ mockFetch.mockResolvedValue(
235
+ new Response(JSON.stringify(errorResponse), { status: 503 })
236
+ );
237
+
238
+ await expect(client.exposePort(8080, 'session-err')).rejects.toThrow(
239
+ ServiceNotRespondingError
240
+ );
249
241
  });
250
242
 
251
243
  it('should handle unexpose non-existent port', async () => {
@@ -253,14 +245,14 @@ describe('PortClient', () => {
253
245
  error: 'Port not exposed: 9999',
254
246
  code: 'PORT_NOT_EXPOSED'
255
247
  };
256
-
257
- mockFetch.mockResolvedValue(new Response(
258
- JSON.stringify(errorResponse),
259
- { status: 404 }
260
- ));
261
-
262
- await expect(client.unexposePort(9999, 'session-err'))
263
- .rejects.toThrow(PortNotExposedError);
248
+
249
+ mockFetch.mockResolvedValue(
250
+ new Response(JSON.stringify(errorResponse), { status: 404 })
251
+ );
252
+
253
+ await expect(client.unexposePort(9999, 'session-err')).rejects.toThrow(
254
+ PortNotExposedError
255
+ );
264
256
  });
265
257
 
266
258
  it('should handle port operation failures', async () => {
@@ -268,14 +260,14 @@ describe('PortClient', () => {
268
260
  error: 'Port operation failed: unable to setup proxy',
269
261
  code: 'PORT_OPERATION_ERROR'
270
262
  };
271
-
272
- mockFetch.mockResolvedValue(new Response(
273
- JSON.stringify(errorResponse),
274
- { status: 500 }
275
- ));
276
-
277
- await expect(client.exposePort(3000, 'session-err'))
278
- .rejects.toThrow(PortError);
263
+
264
+ mockFetch.mockResolvedValue(
265
+ new Response(JSON.stringify(errorResponse), { status: 500 })
266
+ );
267
+
268
+ await expect(client.exposePort(3000, 'session-err')).rejects.toThrow(
269
+ PortError
270
+ );
279
271
  });
280
272
  });
281
273
 
@@ -283,19 +275,19 @@ describe('PortClient', () => {
283
275
  it('should handle network failures gracefully', async () => {
284
276
  mockFetch.mockRejectedValue(new Error('Network connection failed'));
285
277
 
286
- await expect(client.exposePort(3000, 'session-net'))
287
- .rejects.toThrow('Network connection failed');
278
+ await expect(client.exposePort(3000, 'session-net')).rejects.toThrow(
279
+ 'Network connection failed'
280
+ );
288
281
  });
289
282
 
290
283
  it('should handle malformed server responses', async () => {
291
- mockFetch.mockResolvedValue(new Response(
292
- 'invalid json {',
293
- { status: 200 }
294
- ));
284
+ mockFetch.mockResolvedValue(
285
+ new Response('invalid json {', { status: 200 })
286
+ );
295
287
 
296
- await expect(client.exposePort(3000, 'session-malform'))
297
- .rejects.toThrow(SandboxError);
288
+ await expect(client.exposePort(3000, 'session-malform')).rejects.toThrow(
289
+ SandboxError
290
+ );
298
291
  });
299
-
300
292
  });
301
- });
293
+ });