@vercel/sandbox 0.0.8 → 0.0.9
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 +7 -0
- package/dist/api-client/api-client.d.ts +70 -6
- package/dist/api-client/api-client.js +16 -7
- package/dist/api-client/index.d.ts +1 -0
- package/dist/api-client/index.js +15 -0
- package/dist/api-client/validators.d.ts +343 -50
- package/dist/api-client/validators.js +37 -16
- package/dist/command.d.ts +18 -5
- package/dist/command.js +27 -6
- package/dist/sandbox.d.ts +13 -14
- package/dist/sandbox.js +27 -14
- package/dist/utils/resolveSignal.d.ts +13 -0
- package/dist/utils/resolveSignal.js +21 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/src/api-client/api-client.ts +39 -16
- package/src/api-client/index.ts +1 -0
- package/src/api-client/validators.ts +45 -15
- package/src/command.test.ts +39 -16
- package/src/command.ts +33 -10
- package/src/sandbox.ts +38 -21
- package/src/utils/resolveSignal.ts +24 -0
- package/src/version.ts +1 -1
|
@@ -1,32 +1,53 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LogLine = exports.
|
|
3
|
+
exports.LogLine = exports.EmptyResponse = exports.CommandFinishedResponse = exports.CommandResponse = exports.SandboxAndRoutesResponse = exports.SandboxResponse = exports.Command = exports.SandboxRoute = exports.Sandbox = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
|
-
exports.
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
exports.Sandbox = zod_1.z.object({
|
|
6
|
+
id: zod_1.z.string(),
|
|
7
|
+
memory: zod_1.z.number(),
|
|
8
|
+
vcpus: zod_1.z.number(),
|
|
9
|
+
region: zod_1.z.string(),
|
|
10
|
+
runtime: zod_1.z.string(),
|
|
11
|
+
timeout: zod_1.z.number(),
|
|
12
|
+
status: zod_1.z.enum(["pending", "running", "stopping", "stopped", "failed"]),
|
|
13
|
+
requestedAt: zod_1.z.number(),
|
|
14
|
+
startedAt: zod_1.z.number().optional(),
|
|
15
|
+
requestedStopAt: zod_1.z.number().optional(),
|
|
16
|
+
stoppedAt: zod_1.z.number().optional(),
|
|
17
|
+
duration: zod_1.z.number().optional(),
|
|
18
|
+
createdAt: zod_1.z.number(),
|
|
19
|
+
updatedAt: zod_1.z.number(),
|
|
8
20
|
});
|
|
9
|
-
exports.
|
|
10
|
-
|
|
21
|
+
exports.SandboxRoute = zod_1.z.object({
|
|
22
|
+
url: zod_1.z.string(),
|
|
23
|
+
subdomain: zod_1.z.string(),
|
|
24
|
+
port: zod_1.z.number(),
|
|
11
25
|
});
|
|
12
26
|
exports.Command = zod_1.z.object({
|
|
27
|
+
id: zod_1.z.string(),
|
|
28
|
+
name: zod_1.z.string(),
|
|
13
29
|
args: zod_1.z.array(zod_1.z.string()),
|
|
14
|
-
cmdId: zod_1.z.string(),
|
|
15
30
|
cwd: zod_1.z.string(),
|
|
31
|
+
sandboxId: zod_1.z.string(),
|
|
16
32
|
exitCode: zod_1.z.number().nullable(),
|
|
17
|
-
|
|
33
|
+
startedAt: zod_1.z.number(),
|
|
18
34
|
});
|
|
19
|
-
|
|
20
|
-
args: zod_1.z.array(zod_1.z.string()),
|
|
21
|
-
cmdId: zod_1.z.string(),
|
|
22
|
-
cwd: zod_1.z.string(),
|
|
35
|
+
const CommandFinished = exports.Command.extend({
|
|
23
36
|
exitCode: zod_1.z.number(),
|
|
24
|
-
name: zod_1.z.string(),
|
|
25
37
|
});
|
|
26
|
-
exports.
|
|
27
|
-
exports.
|
|
28
|
-
|
|
38
|
+
exports.SandboxResponse = zod_1.z.object({
|
|
39
|
+
sandbox: exports.Sandbox,
|
|
40
|
+
});
|
|
41
|
+
exports.SandboxAndRoutesResponse = exports.SandboxResponse.extend({
|
|
42
|
+
routes: zod_1.z.array(exports.SandboxRoute),
|
|
43
|
+
});
|
|
44
|
+
exports.CommandResponse = zod_1.z.object({
|
|
45
|
+
command: exports.Command,
|
|
46
|
+
});
|
|
47
|
+
exports.CommandFinishedResponse = zod_1.z.object({
|
|
48
|
+
command: CommandFinished,
|
|
29
49
|
});
|
|
50
|
+
exports.EmptyResponse = zod_1.z.object({});
|
|
30
51
|
exports.LogLine = zod_1.z.object({
|
|
31
52
|
stream: zod_1.z.enum(["stdout", "stderr"]),
|
|
32
53
|
data: zod_1.z.string(),
|
package/dist/command.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { APIClient } from "./api-client";
|
|
1
|
+
import { APIClient, type CommandData } from "./api-client";
|
|
2
|
+
import { Signal } from "./utils/resolveSignal";
|
|
2
3
|
/**
|
|
3
4
|
* A command executed in a Sandbox.
|
|
4
5
|
*
|
|
@@ -19,20 +20,24 @@ export declare class Command {
|
|
|
19
20
|
* ID of the sandbox this command is running in.
|
|
20
21
|
*/
|
|
21
22
|
private sandboxId;
|
|
23
|
+
/**
|
|
24
|
+
* Data for the command execution.
|
|
25
|
+
*/
|
|
26
|
+
private cmd;
|
|
22
27
|
/**
|
|
23
28
|
* ID of the command execution.
|
|
24
29
|
*/
|
|
25
|
-
cmdId: string;
|
|
30
|
+
get cmdId(): string;
|
|
26
31
|
/**
|
|
27
32
|
* @param params - Object containing the client, sandbox ID, and command ID.
|
|
28
33
|
* @param params.client - API client used to interact with the backend.
|
|
29
34
|
* @param params.sandboxId - The ID of the sandbox where the command is running.
|
|
30
35
|
* @param params.cmdId - The ID of the command execution.
|
|
31
36
|
*/
|
|
32
|
-
constructor({ client, sandboxId,
|
|
37
|
+
constructor({ client, sandboxId, cmd, }: {
|
|
33
38
|
client: APIClient;
|
|
34
39
|
sandboxId: string;
|
|
35
|
-
|
|
40
|
+
cmd: CommandData;
|
|
36
41
|
});
|
|
37
42
|
/**
|
|
38
43
|
* Iterate over the output of this command.
|
|
@@ -97,6 +102,14 @@ export declare class Command {
|
|
|
97
102
|
* @returns The standard error output of the command.
|
|
98
103
|
*/
|
|
99
104
|
stderr(): Promise<string>;
|
|
105
|
+
/**
|
|
106
|
+
* Kill a running command in a sandbox.
|
|
107
|
+
*
|
|
108
|
+
* @param params - commandId and the signal to send the running process.
|
|
109
|
+
* Defaults to SIGTERM.
|
|
110
|
+
* @returns Promise<void>.
|
|
111
|
+
*/
|
|
112
|
+
kill(signal?: Signal): Promise<void>;
|
|
100
113
|
}
|
|
101
114
|
/**
|
|
102
115
|
* A command that has finished executing.
|
|
@@ -121,7 +134,7 @@ export declare class CommandFinished extends Command {
|
|
|
121
134
|
constructor(params: {
|
|
122
135
|
client: APIClient;
|
|
123
136
|
sandboxId: string;
|
|
124
|
-
|
|
137
|
+
cmd: CommandData;
|
|
125
138
|
exitCode: number;
|
|
126
139
|
});
|
|
127
140
|
}
|
package/dist/command.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.CommandFinished = exports.Command = void 0;
|
|
4
|
+
const resolveSignal_1 = require("./utils/resolveSignal");
|
|
4
5
|
/**
|
|
5
6
|
* A command executed in a Sandbox.
|
|
6
7
|
*
|
|
@@ -12,16 +13,22 @@ exports.CommandFinished = exports.Command = void 0;
|
|
|
12
13
|
* @hideconstructor
|
|
13
14
|
*/
|
|
14
15
|
class Command {
|
|
16
|
+
/**
|
|
17
|
+
* ID of the command execution.
|
|
18
|
+
*/
|
|
19
|
+
get cmdId() {
|
|
20
|
+
return this.cmd.id;
|
|
21
|
+
}
|
|
15
22
|
/**
|
|
16
23
|
* @param params - Object containing the client, sandbox ID, and command ID.
|
|
17
24
|
* @param params.client - API client used to interact with the backend.
|
|
18
25
|
* @param params.sandboxId - The ID of the sandbox where the command is running.
|
|
19
26
|
* @param params.cmdId - The ID of the command execution.
|
|
20
27
|
*/
|
|
21
|
-
constructor({ client, sandboxId,
|
|
28
|
+
constructor({ client, sandboxId, cmd, }) {
|
|
22
29
|
this.client = client;
|
|
23
30
|
this.sandboxId = sandboxId;
|
|
24
|
-
this.
|
|
31
|
+
this.cmd = cmd;
|
|
25
32
|
}
|
|
26
33
|
/**
|
|
27
34
|
* Iterate over the output of this command.
|
|
@@ -44,7 +51,7 @@ class Command {
|
|
|
44
51
|
logs() {
|
|
45
52
|
return this.client.getLogs({
|
|
46
53
|
sandboxId: this.sandboxId,
|
|
47
|
-
cmdId: this.
|
|
54
|
+
cmdId: this.cmd.id,
|
|
48
55
|
});
|
|
49
56
|
}
|
|
50
57
|
/**
|
|
@@ -62,14 +69,14 @@ class Command {
|
|
|
62
69
|
async wait() {
|
|
63
70
|
const command = await this.client.getCommand({
|
|
64
71
|
sandboxId: this.sandboxId,
|
|
65
|
-
cmdId: this.
|
|
72
|
+
cmdId: this.cmd.id,
|
|
66
73
|
wait: true,
|
|
67
74
|
});
|
|
68
75
|
return new CommandFinished({
|
|
69
76
|
client: this.client,
|
|
70
77
|
sandboxId: this.sandboxId,
|
|
71
|
-
|
|
72
|
-
exitCode: command.json.exitCode,
|
|
78
|
+
cmd: command.json.command,
|
|
79
|
+
exitCode: command.json.command.exitCode,
|
|
73
80
|
});
|
|
74
81
|
}
|
|
75
82
|
/**
|
|
@@ -112,6 +119,20 @@ class Command {
|
|
|
112
119
|
async stderr() {
|
|
113
120
|
return this.output("stderr");
|
|
114
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Kill a running command in a sandbox.
|
|
124
|
+
*
|
|
125
|
+
* @param params - commandId and the signal to send the running process.
|
|
126
|
+
* Defaults to SIGTERM.
|
|
127
|
+
* @returns Promise<void>.
|
|
128
|
+
*/
|
|
129
|
+
async kill(signal) {
|
|
130
|
+
await this.client.killCommand({
|
|
131
|
+
sandboxId: this.sandboxId,
|
|
132
|
+
commandId: this.cmd.id,
|
|
133
|
+
signal: (0, resolveSignal_1.resolveSignal)(signal ?? "SIGTERM"),
|
|
134
|
+
});
|
|
135
|
+
}
|
|
115
136
|
}
|
|
116
137
|
exports.Command = Command;
|
|
117
138
|
/**
|
package/dist/sandbox.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { SandboxData, SandboxRouteData } from "./api-client";
|
|
2
|
+
import type { Writable } from "stream";
|
|
2
3
|
import { APIClient } from "./api-client";
|
|
3
|
-
import { Command, CommandFinished } from "./command";
|
|
4
|
+
import { Command, type CommandFinished } from "./command";
|
|
4
5
|
import { type Credentials } from "./utils/get-credentials";
|
|
5
6
|
/** @inline */
|
|
6
7
|
export interface CreateSandboxParams {
|
|
@@ -102,14 +103,15 @@ export declare class Sandbox {
|
|
|
102
103
|
* Routes from ports to subdomains.
|
|
103
104
|
/* @hidden
|
|
104
105
|
*/
|
|
105
|
-
readonly routes:
|
|
106
|
-
subdomain: string;
|
|
107
|
-
port: number;
|
|
108
|
-
}[];
|
|
106
|
+
readonly routes: SandboxRouteData[];
|
|
109
107
|
/**
|
|
110
108
|
* Unique ID of this sandbox.
|
|
111
109
|
*/
|
|
112
|
-
|
|
110
|
+
get sandboxId(): string;
|
|
111
|
+
/**
|
|
112
|
+
* Data about this sandbox.
|
|
113
|
+
*/
|
|
114
|
+
private readonly sandbox;
|
|
113
115
|
/**
|
|
114
116
|
* Create a new sandbox.
|
|
115
117
|
*
|
|
@@ -131,13 +133,10 @@ export declare class Sandbox {
|
|
|
131
133
|
* @param routes - Port-to-subdomain mappings for exposed ports
|
|
132
134
|
* @param sandboxId - Unique identifier for the sandbox
|
|
133
135
|
*/
|
|
134
|
-
constructor({ client, routes,
|
|
136
|
+
constructor({ client, routes, sandbox, }: {
|
|
135
137
|
client: APIClient;
|
|
136
|
-
routes:
|
|
137
|
-
|
|
138
|
-
port: number;
|
|
139
|
-
}[];
|
|
140
|
-
sandboxId: string;
|
|
138
|
+
routes: SandboxRouteData[];
|
|
139
|
+
sandbox: SandboxData;
|
|
141
140
|
});
|
|
142
141
|
/**
|
|
143
142
|
* Get a previously run command by its ID.
|
|
@@ -145,7 +144,7 @@ export declare class Sandbox {
|
|
|
145
144
|
* @param cmdId - ID of the command to retrieve
|
|
146
145
|
* @returns A {@link Command} instance representing the command
|
|
147
146
|
*/
|
|
148
|
-
getCommand(cmdId: string): Command
|
|
147
|
+
getCommand(cmdId: string): Promise<Command>;
|
|
149
148
|
/**
|
|
150
149
|
* Start executing a command in this sandbox.
|
|
151
150
|
*
|
package/dist/sandbox.js
CHANGED
|
@@ -11,6 +11,12 @@ const get_credentials_1 = require("./utils/get-credentials");
|
|
|
11
11
|
* @hideconstructor
|
|
12
12
|
*/
|
|
13
13
|
class Sandbox {
|
|
14
|
+
/**
|
|
15
|
+
* Unique ID of this sandbox.
|
|
16
|
+
*/
|
|
17
|
+
get sandboxId() {
|
|
18
|
+
return this.sandbox.id;
|
|
19
|
+
}
|
|
14
20
|
/**
|
|
15
21
|
* Create a new sandbox.
|
|
16
22
|
*
|
|
@@ -33,7 +39,7 @@ class Sandbox {
|
|
|
33
39
|
});
|
|
34
40
|
return new Sandbox({
|
|
35
41
|
client,
|
|
36
|
-
|
|
42
|
+
sandbox: sandbox.json.sandbox,
|
|
37
43
|
routes: sandbox.json.routes,
|
|
38
44
|
});
|
|
39
45
|
}
|
|
@@ -49,10 +55,13 @@ class Sandbox {
|
|
|
49
55
|
teamId: credentials.teamId,
|
|
50
56
|
token: credentials.token,
|
|
51
57
|
});
|
|
58
|
+
const sandbox = await client.getSandbox({
|
|
59
|
+
sandboxId: params.sandboxId,
|
|
60
|
+
});
|
|
52
61
|
return new Sandbox({
|
|
53
62
|
client,
|
|
54
|
-
|
|
55
|
-
routes:
|
|
63
|
+
sandbox: sandbox.json.sandbox,
|
|
64
|
+
routes: sandbox.json.routes,
|
|
56
65
|
});
|
|
57
66
|
}
|
|
58
67
|
/**
|
|
@@ -62,10 +71,10 @@ class Sandbox {
|
|
|
62
71
|
* @param routes - Port-to-subdomain mappings for exposed ports
|
|
63
72
|
* @param sandboxId - Unique identifier for the sandbox
|
|
64
73
|
*/
|
|
65
|
-
constructor({ client, routes,
|
|
74
|
+
constructor({ client, routes, sandbox, }) {
|
|
66
75
|
this.client = client;
|
|
67
76
|
this.routes = routes;
|
|
68
|
-
this.
|
|
77
|
+
this.sandbox = sandbox;
|
|
69
78
|
}
|
|
70
79
|
/**
|
|
71
80
|
* Get a previously run command by its ID.
|
|
@@ -73,11 +82,15 @@ class Sandbox {
|
|
|
73
82
|
* @param cmdId - ID of the command to retrieve
|
|
74
83
|
* @returns A {@link Command} instance representing the command
|
|
75
84
|
*/
|
|
76
|
-
getCommand(cmdId) {
|
|
85
|
+
async getCommand(cmdId) {
|
|
86
|
+
const command = await this.client.getCommand({
|
|
87
|
+
sandboxId: this.sandbox.id,
|
|
88
|
+
cmdId,
|
|
89
|
+
});
|
|
77
90
|
return new command_1.Command({
|
|
78
91
|
client: this.client,
|
|
79
|
-
sandboxId: this.
|
|
80
|
-
|
|
92
|
+
sandboxId: this.sandbox.id,
|
|
93
|
+
cmd: command.json.command,
|
|
81
94
|
});
|
|
82
95
|
}
|
|
83
96
|
async runCommand(commandOrParams, args) {
|
|
@@ -94,7 +107,7 @@ class Sandbox {
|
|
|
94
107
|
*/
|
|
95
108
|
async _runCommand(params) {
|
|
96
109
|
const commandResponse = await this.client.runCommand({
|
|
97
|
-
sandboxId: this.
|
|
110
|
+
sandboxId: this.sandbox.id,
|
|
98
111
|
command: params.cmd,
|
|
99
112
|
args: params.args ?? [],
|
|
100
113
|
cwd: params.cwd,
|
|
@@ -102,8 +115,8 @@ class Sandbox {
|
|
|
102
115
|
});
|
|
103
116
|
const command = new command_1.Command({
|
|
104
117
|
client: this.client,
|
|
105
|
-
sandboxId: this.
|
|
106
|
-
|
|
118
|
+
sandboxId: this.sandbox.id,
|
|
119
|
+
cmd: commandResponse.json.command,
|
|
107
120
|
});
|
|
108
121
|
if (params.stdout || params.stderr) {
|
|
109
122
|
(async () => {
|
|
@@ -126,7 +139,7 @@ class Sandbox {
|
|
|
126
139
|
*/
|
|
127
140
|
async mkDir(path) {
|
|
128
141
|
await this.client.mkDir({
|
|
129
|
-
sandboxId: this.
|
|
142
|
+
sandboxId: this.sandbox.id,
|
|
130
143
|
path: path,
|
|
131
144
|
});
|
|
132
145
|
}
|
|
@@ -138,7 +151,7 @@ class Sandbox {
|
|
|
138
151
|
*/
|
|
139
152
|
async writeFiles(files) {
|
|
140
153
|
return this.client.writeFiles({
|
|
141
|
-
sandboxId: this.
|
|
154
|
+
sandboxId: this.sandbox.id,
|
|
142
155
|
files: files,
|
|
143
156
|
});
|
|
144
157
|
}
|
|
@@ -165,7 +178,7 @@ class Sandbox {
|
|
|
165
178
|
*/
|
|
166
179
|
async stop() {
|
|
167
180
|
await this.client.stopSandbox({
|
|
168
|
-
sandboxId: this.
|
|
181
|
+
sandboxId: this.sandbox.id,
|
|
169
182
|
});
|
|
170
183
|
}
|
|
171
184
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
declare const linuxSignalMapping: {
|
|
2
|
+
readonly SIGHUP: 1;
|
|
3
|
+
readonly SIGINT: 2;
|
|
4
|
+
readonly SIGQUIT: 3;
|
|
5
|
+
readonly SIGKILL: 9;
|
|
6
|
+
readonly SIGTERM: 15;
|
|
7
|
+
readonly SIGCONT: 18;
|
|
8
|
+
readonly SIGSTOP: 19;
|
|
9
|
+
};
|
|
10
|
+
type CommonLinuxSignals = keyof typeof linuxSignalMapping;
|
|
11
|
+
export type Signal = CommonLinuxSignals | number;
|
|
12
|
+
export declare function resolveSignal(signal: Signal): number;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveSignal = resolveSignal;
|
|
4
|
+
const linuxSignalMapping = {
|
|
5
|
+
SIGHUP: 1,
|
|
6
|
+
SIGINT: 2,
|
|
7
|
+
SIGQUIT: 3,
|
|
8
|
+
SIGKILL: 9,
|
|
9
|
+
SIGTERM: 15,
|
|
10
|
+
SIGCONT: 18,
|
|
11
|
+
SIGSTOP: 19,
|
|
12
|
+
};
|
|
13
|
+
function resolveSignal(signal) {
|
|
14
|
+
if (typeof signal === "number") {
|
|
15
|
+
return signal;
|
|
16
|
+
}
|
|
17
|
+
if (signal in linuxSignalMapping) {
|
|
18
|
+
return linuxSignalMapping[signal];
|
|
19
|
+
}
|
|
20
|
+
throw new Error(`Unknown signal name: ${String(signal)}`);
|
|
21
|
+
}
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.0.
|
|
1
|
+
export declare const VERSION = "0.0.9";
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -5,13 +5,12 @@ import {
|
|
|
5
5
|
type RequestParams,
|
|
6
6
|
} from "./base-client";
|
|
7
7
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
SandboxAndRoutesResponse,
|
|
9
|
+
SandboxResponse,
|
|
10
|
+
CommandResponse,
|
|
11
|
+
CommandFinishedResponse,
|
|
12
|
+
EmptyResponse,
|
|
12
13
|
LogLine,
|
|
13
|
-
StoppedSandbox,
|
|
14
|
-
WrittenFile,
|
|
15
14
|
} from "./validators";
|
|
16
15
|
import { APIError } from "./api-error";
|
|
17
16
|
import { FileWriter } from "./file-writer";
|
|
@@ -56,6 +55,13 @@ export class APIClient extends BaseClient {
|
|
|
56
55
|
});
|
|
57
56
|
}
|
|
58
57
|
|
|
58
|
+
async getSandbox(params: { sandboxId: string }) {
|
|
59
|
+
return parseOrThrow(
|
|
60
|
+
SandboxAndRoutesResponse,
|
|
61
|
+
await this.request(`/v1/sandboxes/${params.sandboxId}`),
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
59
65
|
async createSandbox(params: {
|
|
60
66
|
ports?: number[];
|
|
61
67
|
projectId: string;
|
|
@@ -67,7 +73,7 @@ export class APIClient extends BaseClient {
|
|
|
67
73
|
runtime?: "node22" | "python3.13";
|
|
68
74
|
}) {
|
|
69
75
|
return parseOrThrow(
|
|
70
|
-
|
|
76
|
+
SandboxAndRoutesResponse,
|
|
71
77
|
await this.request("/v1/sandboxes", {
|
|
72
78
|
method: "POST",
|
|
73
79
|
body: JSON.stringify({
|
|
@@ -90,7 +96,7 @@ export class APIClient extends BaseClient {
|
|
|
90
96
|
env: Record<string, string>;
|
|
91
97
|
}) {
|
|
92
98
|
return parseOrThrow(
|
|
93
|
-
|
|
99
|
+
CommandResponse,
|
|
94
100
|
await this.request(`/v1/sandboxes/${params.sandboxId}/cmd`, {
|
|
95
101
|
method: "POST",
|
|
96
102
|
body: JSON.stringify({
|
|
@@ -107,12 +113,12 @@ export class APIClient extends BaseClient {
|
|
|
107
113
|
sandboxId: string;
|
|
108
114
|
cmdId: string;
|
|
109
115
|
wait: true;
|
|
110
|
-
}): Promise<Parsed<z.infer<typeof
|
|
116
|
+
}): Promise<Parsed<z.infer<typeof CommandFinishedResponse>>>;
|
|
111
117
|
async getCommand(params: {
|
|
112
118
|
sandboxId: string;
|
|
113
119
|
cmdId: string;
|
|
114
120
|
wait?: boolean;
|
|
115
|
-
}): Promise<Parsed<z.infer<typeof
|
|
121
|
+
}): Promise<Parsed<z.infer<typeof CommandResponse>>>;
|
|
116
122
|
async getCommand(params: {
|
|
117
123
|
sandboxId: string;
|
|
118
124
|
cmdId: string;
|
|
@@ -120,14 +126,14 @@ export class APIClient extends BaseClient {
|
|
|
120
126
|
}) {
|
|
121
127
|
return params.wait
|
|
122
128
|
? parseOrThrow(
|
|
123
|
-
|
|
129
|
+
CommandFinishedResponse,
|
|
124
130
|
await this.request(
|
|
125
131
|
`/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}`,
|
|
126
132
|
{ query: { wait: "true" } },
|
|
127
133
|
),
|
|
128
134
|
)
|
|
129
135
|
: parseOrThrow(
|
|
130
|
-
|
|
136
|
+
CommandResponse,
|
|
131
137
|
await this.request(
|
|
132
138
|
`/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}`,
|
|
133
139
|
),
|
|
@@ -136,7 +142,7 @@ export class APIClient extends BaseClient {
|
|
|
136
142
|
|
|
137
143
|
async mkDir(params: { sandboxId: string; path: string; cwd?: string }) {
|
|
138
144
|
return parseOrThrow(
|
|
139
|
-
|
|
145
|
+
EmptyResponse,
|
|
140
146
|
await this.request(`/v1/sandboxes/${params.sandboxId}/fs/mkdir`, {
|
|
141
147
|
method: "POST",
|
|
142
148
|
body: JSON.stringify({ path: params.path, cwd: params.cwd }),
|
|
@@ -169,7 +175,7 @@ export class APIClient extends BaseClient {
|
|
|
169
175
|
}
|
|
170
176
|
|
|
171
177
|
await writer.end();
|
|
172
|
-
await parseOrThrow(
|
|
178
|
+
await parseOrThrow(EmptyResponse, await response);
|
|
173
179
|
}
|
|
174
180
|
|
|
175
181
|
async readFile(params: {
|
|
@@ -192,6 +198,23 @@ export class APIClient extends BaseClient {
|
|
|
192
198
|
return response.body;
|
|
193
199
|
}
|
|
194
200
|
|
|
201
|
+
async killCommand(params: {
|
|
202
|
+
sandboxId: string;
|
|
203
|
+
commandId: string;
|
|
204
|
+
signal: number;
|
|
205
|
+
}) {
|
|
206
|
+
return parseOrThrow(
|
|
207
|
+
CommandResponse,
|
|
208
|
+
await this.request(
|
|
209
|
+
`/v1/sandboxes/${params.sandboxId}/${params.commandId}/kill`,
|
|
210
|
+
{
|
|
211
|
+
method: "POST",
|
|
212
|
+
body: JSON.stringify({ signal: params.signal }),
|
|
213
|
+
},
|
|
214
|
+
),
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
195
218
|
async *getLogs(params: {
|
|
196
219
|
sandboxId: string;
|
|
197
220
|
cmdId: string;
|
|
@@ -226,10 +249,10 @@ export class APIClient extends BaseClient {
|
|
|
226
249
|
|
|
227
250
|
async stopSandbox(params: {
|
|
228
251
|
sandboxId: string;
|
|
229
|
-
}): Promise<Parsed<z.infer<typeof
|
|
252
|
+
}): Promise<Parsed<z.infer<typeof SandboxResponse>>> {
|
|
230
253
|
const url = `/v1/sandboxes/${params.sandboxId}/stop`;
|
|
231
254
|
return parseOrThrow(
|
|
232
|
-
|
|
255
|
+
SandboxResponse,
|
|
233
256
|
await this.request(url, { method: "POST" }),
|
|
234
257
|
);
|
|
235
258
|
}
|
package/src/api-client/index.ts
CHANGED
|
@@ -1,36 +1,66 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
export type SandboxData = z.infer<typeof Sandbox>;
|
|
4
|
+
|
|
5
|
+
export const Sandbox = z.object({
|
|
6
|
+
id: z.string(),
|
|
7
|
+
memory: z.number(),
|
|
8
|
+
vcpus: z.number(),
|
|
9
|
+
region: z.string(),
|
|
10
|
+
runtime: z.string(),
|
|
11
|
+
timeout: z.number(),
|
|
12
|
+
status: z.enum(["pending", "running", "stopping", "stopped", "failed"]),
|
|
13
|
+
requestedAt: z.number(),
|
|
14
|
+
startedAt: z.number().optional(),
|
|
15
|
+
requestedStopAt: z.number().optional(),
|
|
16
|
+
stoppedAt: z.number().optional(),
|
|
17
|
+
duration: z.number().optional(),
|
|
18
|
+
createdAt: z.number(),
|
|
19
|
+
updatedAt: z.number(),
|
|
6
20
|
});
|
|
7
21
|
|
|
8
|
-
export
|
|
9
|
-
|
|
22
|
+
export type SandboxRouteData = z.infer<typeof SandboxRoute>;
|
|
23
|
+
|
|
24
|
+
export const SandboxRoute = z.object({
|
|
25
|
+
url: z.string(),
|
|
26
|
+
subdomain: z.string(),
|
|
27
|
+
port: z.number(),
|
|
10
28
|
});
|
|
11
29
|
|
|
30
|
+
export type CommandData = z.infer<typeof Command>;
|
|
31
|
+
|
|
12
32
|
export const Command = z.object({
|
|
33
|
+
id: z.string(),
|
|
34
|
+
name: z.string(),
|
|
13
35
|
args: z.array(z.string()),
|
|
14
|
-
cmdId: z.string(),
|
|
15
36
|
cwd: z.string(),
|
|
37
|
+
sandboxId: z.string(),
|
|
16
38
|
exitCode: z.number().nullable(),
|
|
17
|
-
|
|
39
|
+
startedAt: z.number(),
|
|
18
40
|
});
|
|
19
41
|
|
|
20
|
-
|
|
21
|
-
args: z.array(z.string()),
|
|
22
|
-
cmdId: z.string(),
|
|
23
|
-
cwd: z.string(),
|
|
42
|
+
const CommandFinished = Command.extend({
|
|
24
43
|
exitCode: z.number(),
|
|
25
|
-
name: z.string(),
|
|
26
44
|
});
|
|
27
45
|
|
|
28
|
-
export const
|
|
46
|
+
export const SandboxResponse = z.object({
|
|
47
|
+
sandbox: Sandbox,
|
|
48
|
+
});
|
|
29
49
|
|
|
30
|
-
export const
|
|
31
|
-
|
|
50
|
+
export const SandboxAndRoutesResponse = SandboxResponse.extend({
|
|
51
|
+
routes: z.array(SandboxRoute),
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
export const CommandResponse = z.object({
|
|
55
|
+
command: Command,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export const CommandFinishedResponse = z.object({
|
|
59
|
+
command: CommandFinished,
|
|
32
60
|
});
|
|
33
61
|
|
|
62
|
+
export const EmptyResponse = z.object({});
|
|
63
|
+
|
|
34
64
|
export const LogLine = z.object({
|
|
35
65
|
stream: z.enum(["stdout", "stderr"]),
|
|
36
66
|
data: z.string(),
|