@vercel/sandbox 0.0.20 → 0.0.22
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 +1 -1
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +14 -0
- package/dist/api-client/api-client.d.ts +22 -10
- package/dist/api-client/api-client.js +14 -4
- package/dist/api-client/base-client.d.ts +1 -0
- package/dist/api-client/base-client.js +7 -0
- package/dist/api-client/validators.d.ts +46 -46
- package/dist/command.d.ts +27 -8
- package/dist/command.js +22 -10
- package/dist/sandbox.d.ts +43 -7
- package/dist/sandbox.js +31 -10
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -1
- package/src/api-client/api-client.ts +36 -6
- package/src/api-client/base-client.ts +8 -0
- package/src/command.ts +26 -10
- package/src/sandbox.ts +60 -10
- package/src/version.ts +1 -1
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @vercel/sandbox
|
|
2
2
|
|
|
3
|
+
## 0.0.22
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- add AbortSignal support in public interface ([#137](https://github.com/vercel/sandbox-sdk/pull/137))
|
|
8
|
+
|
|
9
|
+
- add AbortSignal support to command.wait ([#136](https://github.com/vercel/sandbox-sdk/pull/136))
|
|
10
|
+
|
|
11
|
+
## 0.0.21
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Disable Undici body timeout ([#126](https://github.com/vercel/sandbox-sdk/pull/126))
|
|
16
|
+
|
|
3
17
|
## 0.0.20
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
|
@@ -15,18 +15,19 @@ export declare class APIClient extends BaseClient {
|
|
|
15
15
|
protected request(path: string, params?: RequestParams): Promise<Response>;
|
|
16
16
|
getSandbox(params: {
|
|
17
17
|
sandboxId: string;
|
|
18
|
+
signal?: AbortSignal;
|
|
18
19
|
}): Promise<Parsed<{
|
|
19
20
|
sandbox: {
|
|
20
21
|
region: string;
|
|
21
22
|
status: "pending" | "running" | "stopping" | "stopped" | "failed";
|
|
23
|
+
timeout: number;
|
|
24
|
+
cwd: string;
|
|
22
25
|
id: string;
|
|
23
26
|
memory: number;
|
|
24
27
|
vcpus: number;
|
|
25
28
|
runtime: string;
|
|
26
|
-
timeout: number;
|
|
27
29
|
requestedAt: number;
|
|
28
30
|
createdAt: number;
|
|
29
|
-
cwd: string;
|
|
30
31
|
updatedAt: number;
|
|
31
32
|
duration?: number | undefined;
|
|
32
33
|
startedAt?: number | undefined;
|
|
@@ -35,8 +36,8 @@ export declare class APIClient extends BaseClient {
|
|
|
35
36
|
};
|
|
36
37
|
routes: {
|
|
37
38
|
url: string;
|
|
38
|
-
subdomain: string;
|
|
39
39
|
port: number;
|
|
40
|
+
subdomain: string;
|
|
40
41
|
}[];
|
|
41
42
|
}>>;
|
|
42
43
|
createSandbox(params: WithPrivate<{
|
|
@@ -58,18 +59,19 @@ export declare class APIClient extends BaseClient {
|
|
|
58
59
|
vcpus: number;
|
|
59
60
|
};
|
|
60
61
|
runtime?: "node22" | "python3.13" | (string & {});
|
|
62
|
+
signal?: AbortSignal;
|
|
61
63
|
}>): Promise<Parsed<{
|
|
62
64
|
sandbox: {
|
|
63
65
|
region: string;
|
|
64
66
|
status: "pending" | "running" | "stopping" | "stopped" | "failed";
|
|
67
|
+
timeout: number;
|
|
68
|
+
cwd: string;
|
|
65
69
|
id: string;
|
|
66
70
|
memory: number;
|
|
67
71
|
vcpus: number;
|
|
68
72
|
runtime: string;
|
|
69
|
-
timeout: number;
|
|
70
73
|
requestedAt: number;
|
|
71
74
|
createdAt: number;
|
|
72
|
-
cwd: string;
|
|
73
75
|
updatedAt: number;
|
|
74
76
|
duration?: number | undefined;
|
|
75
77
|
startedAt?: number | undefined;
|
|
@@ -78,8 +80,8 @@ export declare class APIClient extends BaseClient {
|
|
|
78
80
|
};
|
|
79
81
|
routes: {
|
|
80
82
|
url: string;
|
|
81
|
-
subdomain: string;
|
|
82
83
|
port: number;
|
|
84
|
+
subdomain: string;
|
|
83
85
|
}[];
|
|
84
86
|
}>>;
|
|
85
87
|
runCommand(params: {
|
|
@@ -89,13 +91,14 @@ export declare class APIClient extends BaseClient {
|
|
|
89
91
|
args: string[];
|
|
90
92
|
env: Record<string, string>;
|
|
91
93
|
sudo: boolean;
|
|
94
|
+
signal?: AbortSignal;
|
|
92
95
|
}): Promise<Parsed<{
|
|
93
96
|
command: {
|
|
94
97
|
name: string;
|
|
95
98
|
args: string[];
|
|
99
|
+
cwd: string;
|
|
96
100
|
id: string;
|
|
97
101
|
startedAt: number;
|
|
98
|
-
cwd: string;
|
|
99
102
|
sandboxId: string;
|
|
100
103
|
exitCode: number | null;
|
|
101
104
|
};
|
|
@@ -104,20 +107,24 @@ export declare class APIClient extends BaseClient {
|
|
|
104
107
|
sandboxId: string;
|
|
105
108
|
cmdId: string;
|
|
106
109
|
wait: true;
|
|
110
|
+
signal?: AbortSignal;
|
|
107
111
|
}): Promise<Parsed<z.infer<typeof CommandFinishedResponse>>>;
|
|
108
112
|
getCommand(params: {
|
|
109
113
|
sandboxId: string;
|
|
110
114
|
cmdId: string;
|
|
111
115
|
wait?: boolean;
|
|
116
|
+
signal?: AbortSignal;
|
|
112
117
|
}): Promise<Parsed<z.infer<typeof CommandResponse>>>;
|
|
113
118
|
mkDir(params: {
|
|
114
119
|
sandboxId: string;
|
|
115
120
|
path: string;
|
|
116
121
|
cwd?: string;
|
|
122
|
+
signal?: AbortSignal;
|
|
117
123
|
}): Promise<Parsed<{}>>;
|
|
118
124
|
getFileWriter(params: {
|
|
119
125
|
sandboxId: string;
|
|
120
126
|
extractDir: string;
|
|
127
|
+
signal?: AbortSignal;
|
|
121
128
|
}): {
|
|
122
129
|
response: Promise<Response>;
|
|
123
130
|
writer: FileWriter;
|
|
@@ -143,18 +150,19 @@ export declare class APIClient extends BaseClient {
|
|
|
143
150
|
* @example 1540095775951
|
|
144
151
|
*/
|
|
145
152
|
until?: number | Date;
|
|
153
|
+
signal?: AbortSignal;
|
|
146
154
|
}): Promise<Parsed<{
|
|
147
155
|
sandboxes: {
|
|
148
156
|
region: string;
|
|
149
157
|
status: "pending" | "running" | "stopping" | "stopped" | "failed";
|
|
158
|
+
timeout: number;
|
|
159
|
+
cwd: string;
|
|
150
160
|
id: string;
|
|
151
161
|
memory: number;
|
|
152
162
|
vcpus: number;
|
|
153
163
|
runtime: string;
|
|
154
|
-
timeout: number;
|
|
155
164
|
requestedAt: number;
|
|
156
165
|
createdAt: number;
|
|
157
|
-
cwd: string;
|
|
158
166
|
updatedAt: number;
|
|
159
167
|
duration?: number | undefined;
|
|
160
168
|
startedAt?: number | undefined;
|
|
@@ -175,23 +183,26 @@ export declare class APIClient extends BaseClient {
|
|
|
175
183
|
content: Buffer;
|
|
176
184
|
}[];
|
|
177
185
|
extractDir: string;
|
|
186
|
+
signal?: AbortSignal;
|
|
178
187
|
}): Promise<void>;
|
|
179
188
|
readFile(params: {
|
|
180
189
|
sandboxId: string;
|
|
181
190
|
path: string;
|
|
182
191
|
cwd?: string;
|
|
192
|
+
signal?: AbortSignal;
|
|
183
193
|
}): Promise<NodeJS.ReadableStream | null>;
|
|
184
194
|
killCommand(params: {
|
|
185
195
|
sandboxId: string;
|
|
186
196
|
commandId: string;
|
|
187
197
|
signal: number;
|
|
198
|
+
abortSignal?: AbortSignal;
|
|
188
199
|
}): Promise<Parsed<{
|
|
189
200
|
command: {
|
|
190
201
|
name: string;
|
|
191
202
|
args: string[];
|
|
203
|
+
cwd: string;
|
|
192
204
|
id: string;
|
|
193
205
|
startedAt: number;
|
|
194
|
-
cwd: string;
|
|
195
206
|
sandboxId: string;
|
|
196
207
|
exitCode: number | null;
|
|
197
208
|
};
|
|
@@ -205,5 +216,6 @@ export declare class APIClient extends BaseClient {
|
|
|
205
216
|
};
|
|
206
217
|
stopSandbox(params: {
|
|
207
218
|
sandboxId: string;
|
|
219
|
+
signal?: AbortSignal;
|
|
208
220
|
}): Promise<Parsed<z.infer<typeof SandboxResponse>>>;
|
|
209
221
|
}
|
|
@@ -53,7 +53,9 @@ class APIClient extends base_client_1.BaseClient {
|
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
55
|
async getSandbox(params) {
|
|
56
|
-
return (0, base_client_1.parseOrThrow)(validators_1.SandboxAndRoutesResponse, await this.request(`/v1/sandboxes/${params.sandboxId}
|
|
56
|
+
return (0, base_client_1.parseOrThrow)(validators_1.SandboxAndRoutesResponse, await this.request(`/v1/sandboxes/${params.sandboxId}`, {
|
|
57
|
+
signal: params.signal,
|
|
58
|
+
}));
|
|
57
59
|
}
|
|
58
60
|
async createSandbox(params) {
|
|
59
61
|
const privateParams = (0, types_1.getPrivateParams)(params);
|
|
@@ -68,6 +70,7 @@ class APIClient extends base_client_1.BaseClient {
|
|
|
68
70
|
runtime: params.runtime,
|
|
69
71
|
...privateParams,
|
|
70
72
|
}),
|
|
73
|
+
signal: params.signal,
|
|
71
74
|
}));
|
|
72
75
|
}
|
|
73
76
|
async runCommand(params) {
|
|
@@ -80,17 +83,19 @@ class APIClient extends base_client_1.BaseClient {
|
|
|
80
83
|
env: params.env,
|
|
81
84
|
sudo: params.sudo,
|
|
82
85
|
}),
|
|
86
|
+
signal: params.signal,
|
|
83
87
|
}));
|
|
84
88
|
}
|
|
85
89
|
async getCommand(params) {
|
|
86
90
|
return params.wait
|
|
87
|
-
? (0, base_client_1.parseOrThrow)(validators_1.CommandFinishedResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}`, { query: { wait: "true" } }))
|
|
88
|
-
: (0, base_client_1.parseOrThrow)(validators_1.CommandResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}
|
|
91
|
+
? (0, base_client_1.parseOrThrow)(validators_1.CommandFinishedResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}`, { signal: params.signal, query: { wait: "true" } }))
|
|
92
|
+
: (0, base_client_1.parseOrThrow)(validators_1.CommandResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}`, { signal: params.signal }));
|
|
89
93
|
}
|
|
90
94
|
async mkDir(params) {
|
|
91
95
|
return (0, base_client_1.parseOrThrow)(validators_1.EmptyResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/fs/mkdir`, {
|
|
92
96
|
method: "POST",
|
|
93
97
|
body: JSON.stringify({ path: params.path, cwd: params.cwd }),
|
|
98
|
+
signal: params.signal,
|
|
94
99
|
}));
|
|
95
100
|
}
|
|
96
101
|
getFileWriter(params) {
|
|
@@ -104,6 +109,7 @@ class APIClient extends base_client_1.BaseClient {
|
|
|
104
109
|
"x-cwd": params.extractDir,
|
|
105
110
|
},
|
|
106
111
|
body: await (0, consume_readable_1.consumeReadable)(writer.readable),
|
|
112
|
+
signal: params.signal,
|
|
107
113
|
});
|
|
108
114
|
})(),
|
|
109
115
|
writer,
|
|
@@ -122,12 +128,14 @@ class APIClient extends base_client_1.BaseClient {
|
|
|
122
128
|
: params.until?.getTime(),
|
|
123
129
|
},
|
|
124
130
|
method: "GET",
|
|
131
|
+
signal: params.signal,
|
|
125
132
|
}));
|
|
126
133
|
}
|
|
127
134
|
async writeFiles(params) {
|
|
128
135
|
const { writer, response } = this.getFileWriter({
|
|
129
136
|
sandboxId: params.sandboxId,
|
|
130
137
|
extractDir: params.extractDir,
|
|
138
|
+
signal: params.signal,
|
|
131
139
|
});
|
|
132
140
|
for (const file of params.files) {
|
|
133
141
|
await writer.addFile({
|
|
@@ -146,6 +154,7 @@ class APIClient extends base_client_1.BaseClient {
|
|
|
146
154
|
const response = await this.request(`/v1/sandboxes/${params.sandboxId}/fs/read`, {
|
|
147
155
|
method: "POST",
|
|
148
156
|
body: JSON.stringify({ path: params.path, cwd: params.cwd }),
|
|
157
|
+
signal: params.signal,
|
|
149
158
|
});
|
|
150
159
|
if (response.status === 404) {
|
|
151
160
|
return null;
|
|
@@ -159,6 +168,7 @@ class APIClient extends base_client_1.BaseClient {
|
|
|
159
168
|
return (0, base_client_1.parseOrThrow)(validators_1.CommandResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/${params.commandId}/kill`, {
|
|
160
169
|
method: "POST",
|
|
161
170
|
body: JSON.stringify({ signal: params.signal }),
|
|
171
|
+
signal: params.abortSignal,
|
|
162
172
|
}));
|
|
163
173
|
}
|
|
164
174
|
getLogs(params) {
|
|
@@ -200,7 +210,7 @@ class APIClient extends base_client_1.BaseClient {
|
|
|
200
210
|
}
|
|
201
211
|
async stopSandbox(params) {
|
|
202
212
|
const url = `/v1/sandboxes/${params.sandboxId}/stop`;
|
|
203
|
-
return (0, base_client_1.parseOrThrow)(validators_1.SandboxResponse, await this.request(url, { method: "POST" }));
|
|
213
|
+
return (0, base_client_1.parseOrThrow)(validators_1.SandboxResponse, await this.request(url, { method: "POST", signal: params.signal }));
|
|
204
214
|
}
|
|
205
215
|
}
|
|
206
216
|
exports.APIClient = APIClient;
|
|
@@ -6,6 +6,7 @@ exports.parseOrThrow = parseOrThrow;
|
|
|
6
6
|
const api_error_1 = require("./api-error");
|
|
7
7
|
const array_1 = require("../utils/array");
|
|
8
8
|
const with_retry_1 = require("./with-retry");
|
|
9
|
+
const undici_1 = require("undici");
|
|
9
10
|
/**
|
|
10
11
|
* A base API client that provides a convenience wrapper for fetching where
|
|
11
12
|
* we can pass query parameters as an object, support retries, debugging
|
|
@@ -17,6 +18,9 @@ class BaseClient {
|
|
|
17
18
|
this.host = params.host;
|
|
18
19
|
this.debug = params.debug ?? process.env.DEBUG_FETCH === "true";
|
|
19
20
|
this.token = params.token;
|
|
21
|
+
this.agent = new undici_1.Agent({
|
|
22
|
+
bodyTimeout: 0, // disable body timeout to allow long logs streaming
|
|
23
|
+
});
|
|
20
24
|
}
|
|
21
25
|
async request(path, opts) {
|
|
22
26
|
const url = new URL(path, this.host);
|
|
@@ -35,6 +39,9 @@ class BaseClient {
|
|
|
35
39
|
headers: this.token
|
|
36
40
|
? { Authorization: `Bearer ${this.token}`, ...opts?.headers }
|
|
37
41
|
: opts?.headers,
|
|
42
|
+
// @ts-expect-error Node.js' and undici's Agent have different types
|
|
43
|
+
dispatcher: this.agent,
|
|
44
|
+
signal: opts?.signal,
|
|
38
45
|
});
|
|
39
46
|
if (this.debug) {
|
|
40
47
|
const duration = Date.now() - start;
|