@vercel/sandbox 1.9.0 → 1.9.1
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/README.md +8 -0
- package/dist/_virtual/rolldown_runtime.cjs +29 -0
- package/dist/api-client/api-client.cjs +375 -0
- package/dist/api-client/api-client.cjs.map +1 -0
- package/dist/api-client/api-client.d.cts +403 -0
- package/dist/api-client/api-client.d.ts +397 -392
- package/dist/api-client/api-client.js +365 -405
- package/dist/api-client/api-client.js.map +1 -1
- package/dist/api-client/api-error.cjs +31 -0
- package/dist/api-client/api-error.cjs.map +1 -0
- package/dist/api-client/api-error.d.cts +27 -0
- package/dist/api-client/api-error.d.ts +19 -16
- package/dist/api-client/api-error.js +27 -32
- package/dist/api-client/api-error.js.map +1 -1
- package/dist/api-client/base-client.cjs +113 -0
- package/dist/api-client/base-client.cjs.map +1 -0
- package/dist/api-client/base-client.d.cts +38 -0
- package/dist/api-client/base-client.d.ts +31 -36
- package/dist/api-client/base-client.js +101 -118
- package/dist/api-client/base-client.js.map +1 -1
- package/dist/api-client/file-writer.cjs +62 -0
- package/dist/api-client/file-writer.cjs.map +1 -0
- package/dist/api-client/file-writer.d.cts +66 -0
- package/dist/api-client/file-writer.d.ts +56 -52
- package/dist/api-client/file-writer.js +57 -61
- package/dist/api-client/file-writer.js.map +1 -1
- package/dist/api-client/index.cjs +2 -0
- package/dist/api-client/index.d.ts +2 -2
- package/dist/api-client/index.js +4 -21
- package/dist/api-client/validators.cjs +149 -0
- package/dist/api-client/validators.cjs.map +1 -0
- package/dist/api-client/validators.d.cts +1677 -0
- package/dist/api-client/validators.d.ts +1501 -2412
- package/dist/api-client/validators.js +124 -154
- package/dist/api-client/validators.js.map +1 -1
- package/dist/api-client/with-retry.cjs +89 -0
- package/dist/api-client/with-retry.cjs.map +1 -0
- package/dist/api-client/with-retry.d.cts +10 -0
- package/dist/api-client/with-retry.d.ts +9 -13
- package/dist/api-client/with-retry.js +81 -102
- package/dist/api-client/with-retry.js.map +1 -1
- package/dist/auth/api.cjs +29 -0
- package/dist/auth/api.cjs.map +1 -0
- package/dist/auth/api.js +26 -25
- package/dist/auth/api.js.map +1 -1
- package/dist/auth/error.cjs +13 -0
- package/dist/auth/error.cjs.map +1 -0
- package/dist/auth/error.js +11 -11
- package/dist/auth/error.js.map +1 -1
- package/dist/auth/file.cjs +64 -0
- package/dist/auth/file.cjs.map +1 -0
- package/dist/auth/file.d.cts +26 -0
- package/dist/auth/file.d.ts +19 -15
- package/dist/auth/file.js +49 -64
- package/dist/auth/file.js.map +1 -1
- package/dist/auth/index.cjs +12 -0
- package/dist/auth/index.d.cts +5 -0
- package/dist/auth/index.d.ts +5 -6
- package/dist/auth/index.js +6 -27
- package/dist/auth/linked-project.cjs +38 -0
- package/dist/auth/linked-project.cjs.map +1 -0
- package/dist/auth/linked-project.js +30 -64
- package/dist/auth/linked-project.js.map +1 -1
- package/dist/auth/oauth.cjs +205 -0
- package/dist/auth/oauth.cjs.map +1 -0
- package/dist/auth/oauth.d.cts +135 -0
- package/dist/auth/oauth.d.ts +113 -109
- package/dist/auth/oauth.js +185 -252
- package/dist/auth/oauth.js.map +1 -1
- package/dist/auth/poll-for-token.cjs +82 -0
- package/dist/auth/poll-for-token.cjs.map +1 -0
- package/dist/auth/poll-for-token.d.cts +28 -0
- package/dist/auth/poll-for-token.d.ts +23 -15
- package/dist/auth/poll-for-token.js +79 -64
- package/dist/auth/poll-for-token.js.map +1 -1
- package/dist/auth/project.cjs +80 -0
- package/dist/auth/project.cjs.map +1 -0
- package/dist/auth/project.d.cts +44 -0
- package/dist/auth/project.d.ts +12 -8
- package/dist/auth/project.js +70 -72
- package/dist/auth/project.js.map +1 -1
- package/dist/auth/zod.cjs +22 -0
- package/dist/auth/zod.cjs.map +1 -0
- package/dist/auth/zod.js +18 -17
- package/dist/auth/zod.js.map +1 -1
- package/dist/command.cjs +326 -0
- package/dist/command.cjs.map +1 -0
- package/dist/command.d.cts +289 -0
- package/dist/command.d.ts +265 -171
- package/dist/command.js +321 -226
- package/dist/command.js.map +1 -1
- package/dist/constants.d.cts +5 -0
- package/dist/constants.d.ts +5 -1
- package/dist/index.cjs +11 -0
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -5
- package/dist/index.js +6 -15
- package/dist/network-policy.d.cts +100 -0
- package/dist/network-policy.d.ts +32 -28
- package/dist/sandbox.cjs +543 -0
- package/dist/sandbox.cjs.map +1 -0
- package/dist/sandbox.d.cts +538 -0
- package/dist/sandbox.d.ts +521 -479
- package/dist/sandbox.js +539 -512
- package/dist/sandbox.js.map +1 -1
- package/dist/snapshot.cjs +116 -0
- package/dist/snapshot.cjs.map +1 -0
- package/dist/snapshot.d.cts +109 -0
- package/dist/snapshot.d.ts +100 -92
- package/dist/snapshot.js +114 -114
- package/dist/snapshot.js.map +1 -1
- package/dist/utils/array.cjs +17 -0
- package/dist/utils/array.cjs.map +1 -0
- package/dist/utils/array.js +12 -15
- package/dist/utils/array.js.map +1 -1
- package/dist/utils/consume-readable.cjs +18 -0
- package/dist/utils/consume-readable.cjs.map +1 -0
- package/dist/utils/consume-readable.js +13 -12
- package/dist/utils/consume-readable.js.map +1 -1
- package/dist/utils/decode-base64-url.cjs +15 -0
- package/dist/utils/decode-base64-url.cjs.map +1 -0
- package/dist/utils/decode-base64-url.js +10 -9
- package/dist/utils/decode-base64-url.js.map +1 -1
- package/dist/utils/dev-credentials.cjs +142 -0
- package/dist/utils/dev-credentials.cjs.map +1 -0
- package/dist/utils/dev-credentials.js +126 -184
- package/dist/utils/dev-credentials.js.map +1 -1
- package/dist/utils/get-credentials.cjs +123 -0
- package/dist/utils/get-credentials.cjs.map +1 -0
- package/dist/utils/get-credentials.d.cts +21 -0
- package/dist/utils/get-credentials.d.ts +19 -61
- package/dist/utils/get-credentials.js +106 -140
- package/dist/utils/get-credentials.js.map +1 -1
- package/dist/utils/log.cjs +25 -0
- package/dist/utils/log.cjs.map +1 -0
- package/dist/utils/log.js +15 -17
- package/dist/utils/log.js.map +1 -1
- package/dist/utils/network-policy.cjs +65 -0
- package/dist/utils/network-policy.cjs.map +1 -0
- package/dist/utils/network-policy.js +58 -77
- package/dist/utils/network-policy.js.map +1 -1
- package/dist/utils/normalizePath.cjs +27 -0
- package/dist/utils/normalizePath.cjs.map +1 -0
- package/dist/utils/normalizePath.js +21 -28
- package/dist/utils/normalizePath.js.map +1 -1
- package/dist/utils/resolveSignal.cjs +20 -0
- package/dist/utils/resolveSignal.cjs.map +1 -0
- package/dist/utils/resolveSignal.d.cts +15 -0
- package/dist/utils/resolveSignal.d.ts +12 -10
- package/dist/utils/resolveSignal.js +14 -17
- package/dist/utils/resolveSignal.js.map +1 -1
- package/dist/utils/sandbox-snapshot.cjs +14 -0
- package/dist/utils/sandbox-snapshot.cjs.map +1 -0
- package/dist/utils/sandbox-snapshot.d.cts +10 -0
- package/dist/utils/sandbox-snapshot.d.ts +11 -0
- package/dist/utils/sandbox-snapshot.js +14 -0
- package/dist/utils/sandbox-snapshot.js.map +1 -0
- package/dist/utils/types.cjs +13 -0
- package/dist/utils/types.cjs.map +1 -0
- package/dist/utils/types.d.cts +11 -0
- package/dist/utils/types.d.ts +5 -7
- package/dist/utils/types.js +8 -8
- package/dist/utils/types.js.map +1 -1
- package/dist/version.cjs +7 -0
- package/dist/version.cjs.map +1 -0
- package/dist/version.js +5 -5
- package/dist/version.js.map +1 -1
- package/package.json +23 -3
- package/dist/api-client/index.js.map +0 -1
- package/dist/auth/api.d.ts +0 -6
- package/dist/auth/error.d.ts +0 -11
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/linked-project.d.ts +0 -10
- package/dist/auth/zod.d.ts +0 -5
- package/dist/constants.js +0 -3
- package/dist/constants.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/network-policy.js +0 -3
- package/dist/network-policy.js.map +0 -1
- package/dist/utils/array.d.ts +0 -9
- package/dist/utils/consume-readable.d.ts +0 -5
- package/dist/utils/convert-sandbox.d.ts +0 -6
- package/dist/utils/convert-sandbox.js +0 -14
- package/dist/utils/convert-sandbox.js.map +0 -1
- package/dist/utils/decode-base64-url.d.ts +0 -7
- package/dist/utils/dev-credentials.d.ts +0 -37
- package/dist/utils/log.d.ts +0 -2
- package/dist/utils/network-policy.d.ts +0 -7
- package/dist/utils/normalizePath.d.ts +0 -17
- package/dist/version.d.ts +0 -1
package/README.md
CHANGED
|
@@ -142,6 +142,14 @@ const sandbox = await Sandbox.create({
|
|
|
142
142
|
});
|
|
143
143
|
```
|
|
144
144
|
|
|
145
|
+
## Workflow DevKit integration
|
|
146
|
+
|
|
147
|
+
`Sandbox` and `CommandFinished` support serialization with the
|
|
148
|
+
[Workflow DevKit](https://vercel.com/docs/workflow). When a sandbox instance
|
|
149
|
+
crosses a step boundary the SDK serializes sandbox metadata and routes, then
|
|
150
|
+
rehydrates synchronously from that snapshot. Deserialized instances lazily
|
|
151
|
+
recreate an API client using OIDC or environment credentials when needed.
|
|
152
|
+
|
|
145
153
|
## Limitations
|
|
146
154
|
|
|
147
155
|
- Max resources: 8 vCPUs. You will get 2048 MB of memory per vCPU.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//#region rolldown:runtime
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
13
|
+
__defProp(to, key, {
|
|
14
|
+
get: ((k) => from[k]).bind(null, key),
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return to;
|
|
21
|
+
};
|
|
22
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
23
|
+
value: mod,
|
|
24
|
+
enumerable: true
|
|
25
|
+
}) : target, mod));
|
|
26
|
+
|
|
27
|
+
//#endregion
|
|
28
|
+
|
|
29
|
+
exports.__toESM = __toESM;
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_api_error = require('./api-error.cjs');
|
|
3
|
+
const require_base_client = require('./base-client.cjs');
|
|
4
|
+
const require_validators = require('./validators.cjs');
|
|
5
|
+
const require_file_writer = require('./file-writer.cjs');
|
|
6
|
+
const require_version = require('../version.cjs');
|
|
7
|
+
const require_consume_readable = require('../utils/consume-readable.cjs');
|
|
8
|
+
const require_normalizePath = require('../utils/normalizePath.cjs');
|
|
9
|
+
const require_network_policy = require('../utils/network-policy.cjs');
|
|
10
|
+
const require_types = require('../utils/types.cjs');
|
|
11
|
+
let node_timers_promises = require("node:timers/promises");
|
|
12
|
+
let zod = require("zod");
|
|
13
|
+
let stream = require("stream");
|
|
14
|
+
let jsonlines = require("jsonlines");
|
|
15
|
+
jsonlines = require_rolldown_runtime.__toESM(jsonlines);
|
|
16
|
+
let os = require("os");
|
|
17
|
+
os = require_rolldown_runtime.__toESM(os);
|
|
18
|
+
let __vercel_oidc = require("@vercel/oidc");
|
|
19
|
+
|
|
20
|
+
//#region src/api-client/api-client.ts
|
|
21
|
+
function decodeUnverifiedToken(token) {
|
|
22
|
+
if (token.split(".").length !== 3) return null;
|
|
23
|
+
try {
|
|
24
|
+
const payload = JSON.parse(Buffer.from(token.split(".")[1], "base64url").toString("utf8"));
|
|
25
|
+
if (payload.owner_id) return {
|
|
26
|
+
owner_id: payload.owner_id,
|
|
27
|
+
project_id: payload.project_id
|
|
28
|
+
};
|
|
29
|
+
return null;
|
|
30
|
+
} catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
var APIClient = class extends require_base_client.BaseClient {
|
|
35
|
+
constructor(params) {
|
|
36
|
+
super({
|
|
37
|
+
baseUrl: params.baseUrl ?? "https://vercel.com/api",
|
|
38
|
+
token: params.token,
|
|
39
|
+
debug: false,
|
|
40
|
+
fetch: params.fetch
|
|
41
|
+
});
|
|
42
|
+
this.teamId = params.teamId;
|
|
43
|
+
this.isJwtToken = false;
|
|
44
|
+
const claims = decodeUnverifiedToken(params.token);
|
|
45
|
+
if (claims) {
|
|
46
|
+
this.isJwtToken = true;
|
|
47
|
+
this.projectId = claims.project_id;
|
|
48
|
+
this.teamId = claims.owner_id;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async ensureValidToken() {
|
|
52
|
+
if (!this.isJwtToken) return;
|
|
53
|
+
try {
|
|
54
|
+
const freshToken = await (0, __vercel_oidc.getVercelOidcToken)({
|
|
55
|
+
expirationBufferMs: 300 * 1e3,
|
|
56
|
+
team: this.teamId,
|
|
57
|
+
project: this.projectId
|
|
58
|
+
});
|
|
59
|
+
if (freshToken !== this.token) {
|
|
60
|
+
this.token = freshToken;
|
|
61
|
+
const claims = decodeUnverifiedToken(freshToken);
|
|
62
|
+
if (claims) this.teamId = claims.owner_id;
|
|
63
|
+
}
|
|
64
|
+
} catch {}
|
|
65
|
+
}
|
|
66
|
+
async request(path, params) {
|
|
67
|
+
await this.ensureValidToken();
|
|
68
|
+
return super.request(path, {
|
|
69
|
+
...params,
|
|
70
|
+
query: {
|
|
71
|
+
teamId: this.teamId,
|
|
72
|
+
...params?.query
|
|
73
|
+
},
|
|
74
|
+
headers: {
|
|
75
|
+
"content-type": "application/json",
|
|
76
|
+
"user-agent": `vercel/sandbox/${require_version.VERSION} (Node.js/${process.version}; ${os.default.platform()}/${os.default.arch()})`,
|
|
77
|
+
...params?.headers
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
async getSandbox(params) {
|
|
82
|
+
const privateParams = require_types.getPrivateParams(params);
|
|
83
|
+
let querystring = new URLSearchParams(privateParams).toString();
|
|
84
|
+
querystring = querystring ? `?${querystring}` : "";
|
|
85
|
+
return require_base_client.parseOrThrow(require_validators.SandboxAndRoutesResponse, await this.request(`/v1/sandboxes/${params.sandboxId}${querystring}`, { signal: params.signal }));
|
|
86
|
+
}
|
|
87
|
+
async createSandbox(params) {
|
|
88
|
+
const privateParams = require_types.getPrivateParams(params);
|
|
89
|
+
return require_base_client.parseOrThrow(require_validators.SandboxAndRoutesResponse, await this.request("/v1/sandboxes", {
|
|
90
|
+
method: "POST",
|
|
91
|
+
body: JSON.stringify({
|
|
92
|
+
projectId: params.projectId,
|
|
93
|
+
ports: params.ports,
|
|
94
|
+
source: params.source,
|
|
95
|
+
timeout: params.timeout,
|
|
96
|
+
resources: params.resources,
|
|
97
|
+
runtime: params.runtime,
|
|
98
|
+
networkPolicy: params.networkPolicy ? require_network_policy.toAPINetworkPolicy(params.networkPolicy) : void 0,
|
|
99
|
+
env: params.env,
|
|
100
|
+
...privateParams
|
|
101
|
+
}),
|
|
102
|
+
signal: params.signal
|
|
103
|
+
}));
|
|
104
|
+
}
|
|
105
|
+
async runCommand(params) {
|
|
106
|
+
if (params.wait) {
|
|
107
|
+
const response = await this.request(`/v1/sandboxes/${params.sandboxId}/cmd`, {
|
|
108
|
+
method: "POST",
|
|
109
|
+
body: JSON.stringify({
|
|
110
|
+
command: params.command,
|
|
111
|
+
args: params.args,
|
|
112
|
+
cwd: params.cwd,
|
|
113
|
+
env: params.env,
|
|
114
|
+
sudo: params.sudo,
|
|
115
|
+
wait: true
|
|
116
|
+
}),
|
|
117
|
+
signal: params.signal
|
|
118
|
+
});
|
|
119
|
+
if (!response.ok) await require_base_client.parseOrThrow(zod.z.any(), response);
|
|
120
|
+
if (response.headers.get("content-type") !== "application/x-ndjson") throw new require_api_error.APIError(response, {
|
|
121
|
+
message: "Expected a stream of command data",
|
|
122
|
+
sandboxId: params.sandboxId
|
|
123
|
+
});
|
|
124
|
+
if (response.body === null) throw new require_api_error.APIError(response, {
|
|
125
|
+
message: "No response body",
|
|
126
|
+
sandboxId: params.sandboxId
|
|
127
|
+
});
|
|
128
|
+
const jsonlinesStream = jsonlines.default.parse();
|
|
129
|
+
pipe(response.body, jsonlinesStream).catch((err) => {
|
|
130
|
+
console.error("Error piping command stream:", err);
|
|
131
|
+
});
|
|
132
|
+
const iterator = jsonlinesStream[Symbol.asyncIterator]();
|
|
133
|
+
const commandChunk = await iterator.next();
|
|
134
|
+
const { command } = require_validators.CommandResponse.parse(commandChunk.value);
|
|
135
|
+
return {
|
|
136
|
+
command,
|
|
137
|
+
finished: (async () => {
|
|
138
|
+
const finishedChunk = await iterator.next();
|
|
139
|
+
const { command: command$1 } = require_validators.CommandFinishedResponse.parse(finishedChunk.value);
|
|
140
|
+
return command$1;
|
|
141
|
+
})()
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
return require_base_client.parseOrThrow(require_validators.CommandResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/cmd`, {
|
|
145
|
+
method: "POST",
|
|
146
|
+
body: JSON.stringify({
|
|
147
|
+
command: params.command,
|
|
148
|
+
args: params.args,
|
|
149
|
+
cwd: params.cwd,
|
|
150
|
+
env: params.env,
|
|
151
|
+
sudo: params.sudo
|
|
152
|
+
}),
|
|
153
|
+
signal: params.signal
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
async getCommand(params) {
|
|
157
|
+
return params.wait ? require_base_client.parseOrThrow(require_validators.CommandFinishedResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}`, {
|
|
158
|
+
signal: params.signal,
|
|
159
|
+
query: { wait: "true" }
|
|
160
|
+
})) : require_base_client.parseOrThrow(require_validators.CommandResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}`, { signal: params.signal }));
|
|
161
|
+
}
|
|
162
|
+
async mkDir(params) {
|
|
163
|
+
return require_base_client.parseOrThrow(require_validators.EmptyResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/fs/mkdir`, {
|
|
164
|
+
method: "POST",
|
|
165
|
+
body: JSON.stringify({
|
|
166
|
+
path: params.path,
|
|
167
|
+
cwd: params.cwd
|
|
168
|
+
}),
|
|
169
|
+
signal: params.signal
|
|
170
|
+
}));
|
|
171
|
+
}
|
|
172
|
+
getFileWriter(params) {
|
|
173
|
+
const writer = new require_file_writer.FileWriter();
|
|
174
|
+
return {
|
|
175
|
+
response: (async () => {
|
|
176
|
+
return this.request(`/v1/sandboxes/${params.sandboxId}/fs/write`, {
|
|
177
|
+
method: "POST",
|
|
178
|
+
headers: {
|
|
179
|
+
"content-type": "application/gzip",
|
|
180
|
+
"x-cwd": params.extractDir
|
|
181
|
+
},
|
|
182
|
+
body: await require_consume_readable.consumeReadable(writer.readable),
|
|
183
|
+
signal: params.signal
|
|
184
|
+
});
|
|
185
|
+
})(),
|
|
186
|
+
writer
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
async listSandboxes(params) {
|
|
190
|
+
return require_base_client.parseOrThrow(require_validators.SandboxesResponse, await this.request(`/v1/sandboxes`, {
|
|
191
|
+
query: {
|
|
192
|
+
project: params.projectId,
|
|
193
|
+
limit: params.limit,
|
|
194
|
+
since: typeof params.since === "number" ? params.since : params.since?.getTime(),
|
|
195
|
+
until: typeof params.until === "number" ? params.until : params.until?.getTime()
|
|
196
|
+
},
|
|
197
|
+
method: "GET",
|
|
198
|
+
signal: params.signal
|
|
199
|
+
}));
|
|
200
|
+
}
|
|
201
|
+
async listSnapshots(params) {
|
|
202
|
+
return require_base_client.parseOrThrow(require_validators.SnapshotsResponse, await this.request(`/v1/sandboxes/snapshots`, {
|
|
203
|
+
query: {
|
|
204
|
+
project: params.projectId,
|
|
205
|
+
limit: params.limit,
|
|
206
|
+
since: typeof params.since === "number" ? params.since : params.since?.getTime(),
|
|
207
|
+
until: typeof params.until === "number" ? params.until : params.until?.getTime()
|
|
208
|
+
},
|
|
209
|
+
method: "GET",
|
|
210
|
+
signal: params.signal
|
|
211
|
+
}));
|
|
212
|
+
}
|
|
213
|
+
async writeFiles(params) {
|
|
214
|
+
const { writer, response } = this.getFileWriter({
|
|
215
|
+
sandboxId: params.sandboxId,
|
|
216
|
+
extractDir: params.extractDir,
|
|
217
|
+
signal: params.signal
|
|
218
|
+
});
|
|
219
|
+
for (const file of params.files) await writer.addFile({
|
|
220
|
+
name: require_normalizePath.normalizePath({
|
|
221
|
+
filePath: file.path,
|
|
222
|
+
extractDir: params.extractDir,
|
|
223
|
+
cwd: params.cwd
|
|
224
|
+
}),
|
|
225
|
+
content: file.content,
|
|
226
|
+
mode: file.mode
|
|
227
|
+
});
|
|
228
|
+
writer.end();
|
|
229
|
+
await require_base_client.parseOrThrow(require_validators.EmptyResponse, await response);
|
|
230
|
+
}
|
|
231
|
+
async readFile(params) {
|
|
232
|
+
const response = await this.request(`/v1/sandboxes/${params.sandboxId}/fs/read`, {
|
|
233
|
+
method: "POST",
|
|
234
|
+
body: JSON.stringify({
|
|
235
|
+
path: params.path,
|
|
236
|
+
cwd: params.cwd
|
|
237
|
+
}),
|
|
238
|
+
signal: params.signal
|
|
239
|
+
});
|
|
240
|
+
if (response.status === 404) return null;
|
|
241
|
+
if (response.body === null) return null;
|
|
242
|
+
return stream.Readable.fromWeb(response.body);
|
|
243
|
+
}
|
|
244
|
+
async killCommand(params) {
|
|
245
|
+
return require_base_client.parseOrThrow(require_validators.CommandResponse, await this.request(`/v1/sandboxes/${params.sandboxId}/${params.commandId}/kill`, {
|
|
246
|
+
method: "POST",
|
|
247
|
+
body: JSON.stringify({ signal: params.signal }),
|
|
248
|
+
signal: params.abortSignal
|
|
249
|
+
}));
|
|
250
|
+
}
|
|
251
|
+
getLogs(params) {
|
|
252
|
+
const self = this;
|
|
253
|
+
const disposer = new AbortController();
|
|
254
|
+
const signal = !params.signal ? disposer.signal : mergeSignals(params.signal, disposer.signal);
|
|
255
|
+
const generator = (async function* () {
|
|
256
|
+
const url = `/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}/logs`;
|
|
257
|
+
const response = await self.request(url, {
|
|
258
|
+
method: "GET",
|
|
259
|
+
signal
|
|
260
|
+
});
|
|
261
|
+
if (!response.ok) await require_base_client.parseOrThrow(zod.z.any(), response);
|
|
262
|
+
if (response.headers.get("content-type") !== "application/x-ndjson") throw new require_api_error.APIError(response, {
|
|
263
|
+
message: "Expected a stream of logs",
|
|
264
|
+
sandboxId: params.sandboxId
|
|
265
|
+
});
|
|
266
|
+
if (response.body === null) throw new require_api_error.APIError(response, {
|
|
267
|
+
message: "No response body",
|
|
268
|
+
sandboxId: params.sandboxId
|
|
269
|
+
});
|
|
270
|
+
const jsonlinesStream = jsonlines.default.parse();
|
|
271
|
+
pipe(response.body, jsonlinesStream).catch((err) => {
|
|
272
|
+
console.error("Error piping logs:", err);
|
|
273
|
+
});
|
|
274
|
+
for await (const chunk of jsonlinesStream) {
|
|
275
|
+
const parsed = require_validators.LogLine.parse(chunk);
|
|
276
|
+
if (parsed.stream === "error") throw new require_api_error.StreamError(parsed.data.code, parsed.data.message, params.sandboxId);
|
|
277
|
+
yield parsed;
|
|
278
|
+
}
|
|
279
|
+
})();
|
|
280
|
+
return Object.assign(generator, {
|
|
281
|
+
[Symbol.dispose]() {
|
|
282
|
+
disposer.abort("Disposed");
|
|
283
|
+
},
|
|
284
|
+
close: () => disposer.abort("Disposed")
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
async stopSandbox(params) {
|
|
288
|
+
const url = `/v1/sandboxes/${params.sandboxId}/stop`;
|
|
289
|
+
const response = await require_base_client.parseOrThrow(require_validators.SandboxResponse, await this.request(url, {
|
|
290
|
+
method: "POST",
|
|
291
|
+
signal: params.signal
|
|
292
|
+
}));
|
|
293
|
+
if (params.blocking) {
|
|
294
|
+
let sandbox = response.json.sandbox;
|
|
295
|
+
while (sandbox.status !== "stopped" && sandbox.status !== "failed" && sandbox.status !== "aborted") {
|
|
296
|
+
await (0, node_timers_promises.setTimeout)(500, void 0, { signal: params.signal });
|
|
297
|
+
sandbox = (await this.getSandbox({
|
|
298
|
+
sandboxId: params.sandboxId,
|
|
299
|
+
signal: params.signal
|
|
300
|
+
})).json.sandbox;
|
|
301
|
+
response.json.sandbox = sandbox;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return response;
|
|
305
|
+
}
|
|
306
|
+
async updateNetworkPolicy(params) {
|
|
307
|
+
const url = `/v1/sandboxes/${params.sandboxId}/network-policy`;
|
|
308
|
+
return require_base_client.parseOrThrow(require_validators.UpdateNetworkPolicyResponse, await this.request(url, {
|
|
309
|
+
method: "POST",
|
|
310
|
+
body: JSON.stringify(require_network_policy.toAPINetworkPolicy(params.networkPolicy)),
|
|
311
|
+
signal: params.signal
|
|
312
|
+
}));
|
|
313
|
+
}
|
|
314
|
+
async extendTimeout(params) {
|
|
315
|
+
const url = `/v1/sandboxes/${params.sandboxId}/extend-timeout`;
|
|
316
|
+
return require_base_client.parseOrThrow(require_validators.ExtendTimeoutResponse, await this.request(url, {
|
|
317
|
+
method: "POST",
|
|
318
|
+
body: JSON.stringify({ duration: params.duration }),
|
|
319
|
+
signal: params.signal
|
|
320
|
+
}));
|
|
321
|
+
}
|
|
322
|
+
async createSnapshot(params) {
|
|
323
|
+
const url = `/v1/sandboxes/${params.sandboxId}/snapshot`;
|
|
324
|
+
const body = params.expiration === void 0 ? void 0 : JSON.stringify({ expiration: params.expiration });
|
|
325
|
+
return require_base_client.parseOrThrow(require_validators.CreateSnapshotResponse, await this.request(url, {
|
|
326
|
+
method: "POST",
|
|
327
|
+
body,
|
|
328
|
+
signal: params.signal
|
|
329
|
+
}));
|
|
330
|
+
}
|
|
331
|
+
async deleteSnapshot(params) {
|
|
332
|
+
const url = `/v1/sandboxes/snapshots/${params.snapshotId}`;
|
|
333
|
+
return require_base_client.parseOrThrow(require_validators.SnapshotResponse, await this.request(url, {
|
|
334
|
+
method: "DELETE",
|
|
335
|
+
signal: params.signal
|
|
336
|
+
}));
|
|
337
|
+
}
|
|
338
|
+
async getSnapshot(params) {
|
|
339
|
+
const url = `/v1/sandboxes/snapshots/${params.snapshotId}`;
|
|
340
|
+
return require_base_client.parseOrThrow(require_validators.SnapshotResponse, await this.request(url, { signal: params.signal }));
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
async function pipe(readable, output) {
|
|
344
|
+
const reader = readable.getReader();
|
|
345
|
+
try {
|
|
346
|
+
while (true) {
|
|
347
|
+
const read = await reader.read();
|
|
348
|
+
if (read.value) output.write(Buffer.from(read.value));
|
|
349
|
+
if (read.done) break;
|
|
350
|
+
}
|
|
351
|
+
} catch (err) {
|
|
352
|
+
output.emit("error", err);
|
|
353
|
+
} finally {
|
|
354
|
+
output.end();
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
function mergeSignals(...signals) {
|
|
358
|
+
const controller = new AbortController();
|
|
359
|
+
const onAbort = () => {
|
|
360
|
+
controller.abort();
|
|
361
|
+
for (const signal of signals) signal.removeEventListener("abort", onAbort);
|
|
362
|
+
};
|
|
363
|
+
for (const signal of signals) {
|
|
364
|
+
if (signal.aborted) {
|
|
365
|
+
controller.abort();
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
signal.addEventListener("abort", onAbort);
|
|
369
|
+
}
|
|
370
|
+
return controller.signal;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
//#endregion
|
|
374
|
+
exports.APIClient = APIClient;
|
|
375
|
+
//# sourceMappingURL=api-client.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-client.cjs","names":["BaseClient","VERSION","getPrivateParams","parseOrThrow","SandboxAndRoutesResponse","toAPINetworkPolicy","z","APIError","CommandResponse","CommandFinishedResponse","command","EmptyResponse","FileWriter","consumeReadable","SandboxesResponse","SnapshotsResponse","normalizePath","Readable","LogLine","StreamError","SandboxResponse","UpdateNetworkPolicyResponse","ExtendTimeoutResponse","CreateSnapshotResponse","SnapshotResponse"],"sources":["../../src/api-client/api-client.ts"],"sourcesContent":["import {\n BaseClient,\n parseOrThrow,\n type Parsed,\n type RequestParams,\n} from \"./base-client.js\";\nimport {\n CommandFinishedData,\n SandboxAndRoutesResponse,\n SandboxResponse,\n CommandResponse,\n CommandFinishedResponse,\n EmptyResponse,\n LogLine,\n LogLineStdout,\n LogLineStderr,\n SandboxesResponse,\n SnapshotsResponse,\n ExtendTimeoutResponse,\n UpdateNetworkPolicyResponse,\n SnapshotResponse,\n CreateSnapshotResponse,\n type CommandData,\n} from \"./validators.js\";\nimport { APIError, StreamError } from \"./api-error.js\";\nimport { FileWriter } from \"./file-writer.js\";\nimport { VERSION } from \"../version.js\";\nimport { consumeReadable } from \"../utils/consume-readable.js\";\nimport { z } from \"zod\";\nimport jsonlines from \"jsonlines\";\nimport os from \"os\";\nimport { Readable } from \"stream\";\nimport { normalizePath } from \"../utils/normalizePath.js\";\nimport { getVercelOidcToken } from \"@vercel/oidc\";\nimport { NetworkPolicy } from \"../network-policy.js\";\nimport {\n toAPINetworkPolicy,\n fromAPINetworkPolicy,\n} from \"../utils/network-policy.js\";\nimport { getPrivateParams, WithPrivate } from \"../utils/types.js\";\nimport { RUNTIMES } from \"../constants.js\";\nimport { setTimeout } from \"node:timers/promises\";\n\ninterface Claims {\n owner_id: string;\n project_id?: string;\n}\n\nfunction decodeUnverifiedToken(token: string): Claims | null {\n if (token.split(\".\").length !== 3) {\n return null;\n }\n try {\n const payload = JSON.parse(\n Buffer.from(token.split(\".\")[1], \"base64url\").toString(\"utf8\"),\n );\n if (payload.owner_id) {\n return { owner_id: payload.owner_id, project_id: payload.project_id };\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport interface WithFetchOptions {\n fetch?: typeof globalThis.fetch;\n}\n\nexport class APIClient extends BaseClient {\n private teamId: string;\n private projectId: string | undefined;\n private isJwtToken: boolean;\n\n constructor(params: {\n baseUrl?: string;\n teamId: string;\n token: string;\n fetch?: typeof globalThis.fetch;\n }) {\n super({\n baseUrl: params.baseUrl ?? \"https://vercel.com/api\",\n token: params.token,\n debug: false,\n fetch: params.fetch,\n });\n\n this.teamId = params.teamId;\n this.isJwtToken = false;\n\n const claims = decodeUnverifiedToken(params.token);\n if (claims) {\n this.isJwtToken = true;\n this.projectId = claims.project_id;\n this.teamId = claims.owner_id;\n }\n }\n\n private async ensureValidToken(): Promise<void> {\n if (!this.isJwtToken) {\n return;\n }\n\n try {\n // Use getVercelOidcToken to refresh the token with team/project scope\n const freshToken = await getVercelOidcToken({\n expirationBufferMs: 5 * 60 * 1000, // 5 minutes\n team: this.teamId,\n project: this.projectId,\n });\n\n // Update token if it changed\n if (freshToken !== this.token) {\n this.token = freshToken;\n\n const claims = decodeUnverifiedToken(freshToken);\n if (claims) {\n this.teamId = claims.owner_id;\n }\n }\n } catch {\n // Ignore refresh errors and continue with current token\n }\n }\n\n protected async request(path: string, params?: RequestParams) {\n await this.ensureValidToken();\n\n return super.request(path, {\n ...params,\n query: { teamId: this.teamId, ...params?.query },\n headers: {\n \"content-type\": \"application/json\",\n \"user-agent\": `vercel/sandbox/${VERSION} (Node.js/${process.version}; ${os.platform()}/${os.arch()})`,\n ...params?.headers,\n },\n });\n }\n\n async getSandbox(\n params: WithPrivate<{ sandboxId: string; signal?: AbortSignal }>,\n ) {\n const privateParams = getPrivateParams(params);\n let querystring = new URLSearchParams(privateParams).toString();\n querystring = querystring ? `?${querystring}` : \"\";\n return parseOrThrow(\n SandboxAndRoutesResponse,\n await this.request(`/v1/sandboxes/${params.sandboxId}${querystring}`, {\n signal: params.signal,\n }),\n );\n }\n\n async createSandbox(\n params: WithPrivate<{\n ports?: number[];\n projectId: string;\n source?:\n | {\n type: \"git\";\n url: string;\n depth?: number;\n revision?: string;\n username?: string;\n password?: string;\n }\n | { type: \"tarball\"; url: string }\n | { type: \"snapshot\"; snapshotId: string };\n timeout?: number;\n resources?: { vcpus: number };\n runtime?: RUNTIMES | (string & {});\n networkPolicy?: NetworkPolicy;\n env?: Record<string, string>;\n signal?: AbortSignal;\n }>,\n ) {\n const privateParams = getPrivateParams(params);\n return parseOrThrow(\n SandboxAndRoutesResponse,\n await this.request(\"/v1/sandboxes\", {\n method: \"POST\",\n body: JSON.stringify({\n projectId: params.projectId,\n ports: params.ports,\n source: params.source,\n timeout: params.timeout,\n resources: params.resources,\n runtime: params.runtime,\n networkPolicy: params.networkPolicy\n ? toAPINetworkPolicy(params.networkPolicy)\n : undefined,\n env: params.env,\n ...privateParams,\n }),\n signal: params.signal,\n }),\n );\n }\n\n async runCommand(params: {\n sandboxId: string;\n cwd?: string;\n command: string;\n args: string[];\n env: Record<string, string>;\n sudo: boolean;\n wait: true;\n signal?: AbortSignal;\n }): Promise<{ command: CommandData; finished: Promise<CommandFinishedData> }>;\n async runCommand(params: {\n sandboxId: string;\n cwd?: string;\n command: string;\n args: string[];\n env: Record<string, string>;\n sudo: boolean;\n wait?: false;\n signal?: AbortSignal;\n }): Promise<Parsed<z.infer<typeof CommandResponse>>>;\n async runCommand(params: {\n sandboxId: string;\n cwd?: string;\n command: string;\n args: string[];\n env: Record<string, string>;\n sudo: boolean;\n wait?: boolean;\n signal?: AbortSignal;\n }) {\n if (params.wait) {\n const response = await this.request(\n `/v1/sandboxes/${params.sandboxId}/cmd`,\n {\n method: \"POST\",\n body: JSON.stringify({\n command: params.command,\n args: params.args,\n cwd: params.cwd,\n env: params.env,\n sudo: params.sudo,\n wait: true,\n }),\n signal: params.signal,\n },\n );\n\n if (!response.ok) {\n await parseOrThrow(z.any(), response);\n }\n\n if (response.headers.get(\"content-type\") !== \"application/x-ndjson\") {\n throw new APIError(response, {\n message: \"Expected a stream of command data\",\n sandboxId: params.sandboxId,\n });\n }\n\n if (response.body === null) {\n throw new APIError(response, {\n message: \"No response body\",\n sandboxId: params.sandboxId,\n });\n }\n\n const jsonlinesStream = jsonlines.parse();\n pipe(response.body, jsonlinesStream).catch((err) => {\n console.error(\"Error piping command stream:\", err);\n });\n\n const iterator = jsonlinesStream[Symbol.asyncIterator]();\n const commandChunk = await iterator.next();\n const { command } = CommandResponse.parse(commandChunk.value);\n\n const finished = (async () => {\n const finishedChunk = await iterator.next();\n const { command } = CommandFinishedResponse.parse(finishedChunk.value);\n return command;\n })();\n\n return { command, finished };\n }\n\n return parseOrThrow(\n CommandResponse,\n await this.request(`/v1/sandboxes/${params.sandboxId}/cmd`, {\n method: \"POST\",\n body: JSON.stringify({\n command: params.command,\n args: params.args,\n cwd: params.cwd,\n env: params.env,\n sudo: params.sudo,\n }),\n signal: params.signal,\n }),\n );\n }\n\n async getCommand(params: {\n sandboxId: string;\n cmdId: string;\n wait: true;\n signal?: AbortSignal;\n }): Promise<Parsed<z.infer<typeof CommandFinishedResponse>>>;\n async getCommand(params: {\n sandboxId: string;\n cmdId: string;\n wait?: boolean;\n signal?: AbortSignal;\n }): Promise<Parsed<z.infer<typeof CommandResponse>>>;\n async getCommand(params: {\n sandboxId: string;\n cmdId: string;\n wait?: boolean;\n signal?: AbortSignal;\n }) {\n return params.wait\n ? parseOrThrow(\n CommandFinishedResponse,\n await this.request(\n `/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}`,\n { signal: params.signal, query: { wait: \"true\" } },\n ),\n )\n : parseOrThrow(\n CommandResponse,\n await this.request(\n `/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}`,\n { signal: params.signal },\n ),\n );\n }\n\n async mkDir(params: {\n sandboxId: string;\n path: string;\n cwd?: string;\n signal?: AbortSignal;\n }) {\n return parseOrThrow(\n EmptyResponse,\n await this.request(`/v1/sandboxes/${params.sandboxId}/fs/mkdir`, {\n method: \"POST\",\n body: JSON.stringify({ path: params.path, cwd: params.cwd }),\n signal: params.signal,\n }),\n );\n }\n\n getFileWriter(params: {\n sandboxId: string;\n extractDir: string;\n signal?: AbortSignal;\n }) {\n const writer = new FileWriter();\n return {\n response: (async () => {\n return this.request(`/v1/sandboxes/${params.sandboxId}/fs/write`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/gzip\",\n \"x-cwd\": params.extractDir,\n },\n body: await consumeReadable(writer.readable),\n signal: params.signal,\n });\n })(),\n writer,\n };\n }\n\n async listSandboxes(params: {\n /**\n * The ID or name of the project to which the sandboxes belong.\n * @example \"my-project\"\n */\n projectId: string;\n /**\n * Maximum number of sandboxes to list from a request.\n * @example 10\n */\n limit?: number;\n /**\n * Get sandboxes created after this JavaScript timestamp.\n * @example 1540095775941\n */\n since?: number | Date;\n /**\n * Get sandboxes created before this JavaScript timestamp.\n * @example 1540095775951\n */\n until?: number | Date;\n signal?: AbortSignal;\n }) {\n return parseOrThrow(\n SandboxesResponse,\n await this.request(`/v1/sandboxes`, {\n query: {\n project: params.projectId,\n limit: params.limit,\n since:\n typeof params.since === \"number\"\n ? params.since\n : params.since?.getTime(),\n until:\n typeof params.until === \"number\"\n ? params.until\n : params.until?.getTime(),\n },\n method: \"GET\",\n signal: params.signal,\n }),\n );\n }\n\n async listSnapshots(params: {\n /**\n * The ID or name of the project to which the snapshots belong.\n * @example \"my-project\"\n */\n projectId: string;\n /**\n * Maximum number of snapshots to list from a request.\n * @example 10\n */\n limit?: number;\n /**\n * Get snapshots created after this JavaScript timestamp.\n * @example 1540095775941\n */\n since?: number | Date;\n /**\n * Get snapshots created before this JavaScript timestamp.\n * @example 1540095775951\n */\n until?: number | Date;\n signal?: AbortSignal;\n }) {\n return parseOrThrow(\n SnapshotsResponse,\n await this.request(`/v1/sandboxes/snapshots`, {\n query: {\n project: params.projectId,\n limit: params.limit,\n since:\n typeof params.since === \"number\"\n ? params.since\n : params.since?.getTime(),\n until:\n typeof params.until === \"number\"\n ? params.until\n : params.until?.getTime(),\n },\n method: \"GET\",\n signal: params.signal,\n }),\n );\n }\n\n async writeFiles(params: {\n sandboxId: string;\n cwd: string;\n files: {\n path: string;\n content: string | Uint8Array;\n mode?: number;\n }[];\n extractDir: string;\n signal?: AbortSignal;\n }) {\n const { writer, response } = this.getFileWriter({\n sandboxId: params.sandboxId,\n extractDir: params.extractDir,\n signal: params.signal,\n });\n\n for (const file of params.files) {\n await writer.addFile({\n name: normalizePath({\n filePath: file.path,\n extractDir: params.extractDir,\n cwd: params.cwd,\n }),\n content: file.content,\n mode: file.mode,\n });\n }\n\n writer.end();\n await parseOrThrow(EmptyResponse, await response);\n }\n\n async readFile(params: {\n sandboxId: string;\n path: string;\n cwd?: string;\n signal?: AbortSignal;\n }): Promise<Readable | null> {\n const response = await this.request(\n `/v1/sandboxes/${params.sandboxId}/fs/read`,\n {\n method: \"POST\",\n body: JSON.stringify({ path: params.path, cwd: params.cwd }),\n signal: params.signal,\n },\n );\n\n if (response.status === 404) {\n return null;\n }\n\n if (response.body === null) {\n return null;\n }\n\n return Readable.fromWeb(response.body);\n }\n\n async killCommand(params: {\n sandboxId: string;\n commandId: string;\n signal: number;\n abortSignal?: AbortSignal;\n }) {\n return parseOrThrow(\n CommandResponse,\n await this.request(\n `/v1/sandboxes/${params.sandboxId}/${params.commandId}/kill`,\n {\n method: \"POST\",\n body: JSON.stringify({ signal: params.signal }),\n signal: params.abortSignal,\n },\n ),\n );\n }\n\n getLogs(params: {\n sandboxId: string;\n cmdId: string;\n signal?: AbortSignal;\n }): AsyncGenerator<\n z.infer<typeof LogLineStdout> | z.infer<typeof LogLineStderr>,\n void,\n void\n > &\n Disposable & { close(): void } {\n const self = this;\n const disposer = new AbortController();\n const signal = !params.signal\n ? disposer.signal\n : mergeSignals(params.signal, disposer.signal);\n\n const generator = (async function* () {\n const url = `/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}/logs`;\n const response = await self.request(url, {\n method: \"GET\",\n signal,\n });\n\n if (!response.ok) {\n await parseOrThrow(z.any(), response);\n }\n\n if (response.headers.get(\"content-type\") !== \"application/x-ndjson\") {\n throw new APIError(response, {\n message: \"Expected a stream of logs\",\n sandboxId: params.sandboxId,\n });\n }\n\n if (response.body === null) {\n throw new APIError(response, {\n message: \"No response body\",\n sandboxId: params.sandboxId,\n });\n }\n\n const jsonlinesStream = jsonlines.parse();\n pipe(response.body, jsonlinesStream).catch((err) => {\n console.error(\"Error piping logs:\", err);\n });\n\n for await (const chunk of jsonlinesStream) {\n const parsed = LogLine.parse(chunk);\n if (parsed.stream === \"error\") {\n throw new StreamError(\n parsed.data.code,\n parsed.data.message,\n params.sandboxId,\n );\n }\n yield parsed;\n }\n })();\n\n return Object.assign(generator, {\n [Symbol.dispose]() {\n disposer.abort(\"Disposed\");\n },\n close: () => disposer.abort(\"Disposed\"),\n });\n }\n\n async stopSandbox(params: {\n sandboxId: string;\n signal?: AbortSignal;\n blocking?: boolean;\n }): Promise<Parsed<z.infer<typeof SandboxResponse>>> {\n const url = `/v1/sandboxes/${params.sandboxId}/stop`;\n const response = await parseOrThrow(\n SandboxResponse,\n await this.request(url, { method: \"POST\", signal: params.signal }),\n );\n\n if (params.blocking) {\n let sandbox = response.json.sandbox;\n while (\n sandbox.status !== \"stopped\" &&\n sandbox.status !== \"failed\" &&\n sandbox.status !== \"aborted\"\n ) {\n await setTimeout(500, undefined, { signal: params.signal });\n const poll = await this.getSandbox({\n sandboxId: params.sandboxId,\n signal: params.signal,\n });\n sandbox = poll.json.sandbox;\n response.json.sandbox = sandbox;\n }\n }\n\n return response;\n }\n\n async updateNetworkPolicy(params: {\n sandboxId: string;\n networkPolicy: NetworkPolicy;\n signal?: AbortSignal;\n }): Promise<Parsed<z.infer<typeof UpdateNetworkPolicyResponse>>> {\n const url = `/v1/sandboxes/${params.sandboxId}/network-policy`;\n return parseOrThrow(\n UpdateNetworkPolicyResponse,\n await this.request(url, {\n method: \"POST\",\n body: JSON.stringify(toAPINetworkPolicy(params.networkPolicy)),\n signal: params.signal,\n }),\n );\n }\n\n async extendTimeout(params: {\n sandboxId: string;\n duration: number;\n signal?: AbortSignal;\n }): Promise<Parsed<z.infer<typeof ExtendTimeoutResponse>>> {\n const url = `/v1/sandboxes/${params.sandboxId}/extend-timeout`;\n return parseOrThrow(\n ExtendTimeoutResponse,\n await this.request(url, {\n method: \"POST\",\n body: JSON.stringify({ duration: params.duration }),\n signal: params.signal,\n }),\n );\n }\n\n async createSnapshot(params: {\n sandboxId: string;\n expiration?: number;\n signal?: AbortSignal;\n }): Promise<Parsed<z.infer<typeof CreateSnapshotResponse>>> {\n const url = `/v1/sandboxes/${params.sandboxId}/snapshot`;\n const body =\n params.expiration === undefined\n ? undefined\n : JSON.stringify({ expiration: params.expiration });\n return parseOrThrow(\n CreateSnapshotResponse,\n await this.request(url, {\n method: \"POST\",\n body,\n signal: params.signal,\n }),\n );\n }\n\n async deleteSnapshot(params: {\n snapshotId: string;\n signal?: AbortSignal;\n }): Promise<Parsed<z.infer<typeof SnapshotResponse>>> {\n const url = `/v1/sandboxes/snapshots/${params.snapshotId}`;\n return parseOrThrow(\n SnapshotResponse,\n await this.request(url, { method: \"DELETE\", signal: params.signal }),\n );\n }\n\n async getSnapshot(params: {\n snapshotId: string;\n signal?: AbortSignal;\n }): Promise<Parsed<z.infer<typeof SnapshotResponse>>> {\n const url = `/v1/sandboxes/snapshots/${params.snapshotId}`;\n return parseOrThrow(\n SnapshotResponse,\n await this.request(url, { signal: params.signal }),\n );\n }\n}\n\nasync function pipe(\n readable: ReadableStream<Uint8Array>,\n output: NodeJS.WritableStream,\n) {\n const reader = readable.getReader();\n try {\n while (true) {\n const read = await reader.read();\n if (read.value) {\n output.write(Buffer.from(read.value));\n }\n if (read.done) {\n break;\n }\n }\n } catch (err) {\n output.emit(\"error\", err);\n } finally {\n output.end();\n }\n}\n\nfunction mergeSignals(...signals: [AbortSignal, ...AbortSignal[]]) {\n const controller = new AbortController();\n const onAbort = () => {\n controller.abort();\n for (const signal of signals) {\n signal.removeEventListener(\"abort\", onAbort);\n }\n };\n for (const signal of signals) {\n if (signal.aborted) {\n controller.abort();\n break;\n }\n signal.addEventListener(\"abort\", onAbort);\n }\n return controller.signal;\n}\n"],"mappings":"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"}
|