@vercel/sandbox 0.0.6 → 0.0.8
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/README.md +1 -1
- package/dist/api-client/api-client.d.ts +12 -4
- package/dist/api-client/api-client.js +19 -8
- package/dist/api-client/file-writer.d.ts +52 -0
- package/dist/api-client/file-writer.js +62 -0
- package/dist/sandbox.d.ts +16 -5
- package/dist/sandbox.js +2 -4
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -1
- package/src/api-client/api-client.ts +26 -15
- package/src/api-client/file-writer.ts +90 -0
- package/src/sandbox.ts +20 -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.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Write files using a single compressed stream ([#44](https://github.com/vercel/sandbox-sdk/pull/44))
|
|
8
|
+
- Expose `runtime` parameter ([#46](https://github.com/vercel/sandbox-sdk/pull/46))
|
|
9
|
+
- Add git depth and revision options to sandbox source ([#47](https://github.com/vercel/sandbox-sdk/pull/47))
|
|
10
|
+
|
|
11
|
+
## 0.0.7
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Rename `cores` to `vcpus` ([#41](https://github.com/vercel/sandbox-sdk/pull/41))
|
|
16
|
+
|
|
3
17
|
## 0.0.6
|
|
4
18
|
|
|
5
19
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ All while streaming logs to your local terminal.
|
|
|
49
49
|
|
|
50
50
|
- Sandbox only supports cloning public repositories at the moment.
|
|
51
51
|
- `sudo` is not available. User code is executed as the `vercel-sandbox` user.
|
|
52
|
-
- Max resources:
|
|
52
|
+
- Max resources: 8 vCPUs. You will get 2048 MB of memory per vCPU.
|
|
53
53
|
- All APIs of the SDK are subject to change. **We make no stability promises.**
|
|
54
54
|
|
|
55
55
|
## System
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseClient, type Parsed, type RequestParams } from "./base-client";
|
|
2
2
|
import { Command, CommandFinished, LogLine, StoppedSandbox } from "./validators";
|
|
3
|
-
import {
|
|
3
|
+
import { FileWriter } from "./file-writer";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
export declare class APIClient extends BaseClient {
|
|
6
6
|
private teamId;
|
|
@@ -16,15 +16,17 @@ export declare class APIClient extends BaseClient {
|
|
|
16
16
|
source?: {
|
|
17
17
|
type: "git";
|
|
18
18
|
url: string;
|
|
19
|
+
depth?: number;
|
|
20
|
+
revision?: string;
|
|
19
21
|
} | {
|
|
20
22
|
type: "tarball";
|
|
21
23
|
url: string;
|
|
22
24
|
};
|
|
23
25
|
timeout?: number;
|
|
24
26
|
resources?: {
|
|
25
|
-
|
|
26
|
-
memory: number;
|
|
27
|
+
vcpus: number;
|
|
27
28
|
};
|
|
29
|
+
runtime?: "node22" | "python3.13";
|
|
28
30
|
}): Promise<Parsed<{
|
|
29
31
|
sandboxId: string;
|
|
30
32
|
routes: {
|
|
@@ -56,11 +58,17 @@ export declare class APIClient extends BaseClient {
|
|
|
56
58
|
path: string;
|
|
57
59
|
cwd?: string;
|
|
58
60
|
}): Promise<Parsed<{}>>;
|
|
61
|
+
getFileWriter(params: {
|
|
62
|
+
sandboxId: string;
|
|
63
|
+
}): {
|
|
64
|
+
response: Promise<import("node-fetch").Response>;
|
|
65
|
+
writer: FileWriter;
|
|
66
|
+
};
|
|
59
67
|
writeFiles(params: {
|
|
60
68
|
sandboxId: string;
|
|
61
69
|
files: {
|
|
62
70
|
path: string;
|
|
63
|
-
stream:
|
|
71
|
+
stream: Buffer;
|
|
64
72
|
}[];
|
|
65
73
|
}): Promise<void>;
|
|
66
74
|
readFile(params: {
|
|
@@ -4,10 +4,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.APIClient = void 0;
|
|
7
|
-
const form_data_1 = __importDefault(require("form-data"));
|
|
8
7
|
const base_client_1 = require("./base-client");
|
|
9
8
|
const validators_1 = require("./validators");
|
|
10
9
|
const api_error_1 = require("./api-error");
|
|
10
|
+
const file_writer_1 = require("./file-writer");
|
|
11
11
|
const lru_cache_1 = require("lru-cache");
|
|
12
12
|
const version_1 = require("../version");
|
|
13
13
|
const jsonlines_1 = __importDefault(require("jsonlines"));
|
|
@@ -50,6 +50,7 @@ class APIClient extends base_client_1.BaseClient {
|
|
|
50
50
|
source: params.source,
|
|
51
51
|
timeout: params.timeout,
|
|
52
52
|
resources: params.resources,
|
|
53
|
+
runtime: params.runtime,
|
|
53
54
|
}),
|
|
54
55
|
}));
|
|
55
56
|
}
|
|
@@ -75,16 +76,26 @@ class APIClient extends base_client_1.BaseClient {
|
|
|
75
76
|
body: JSON.stringify({ path: params.path, cwd: params.cwd }),
|
|
76
77
|
}));
|
|
77
78
|
}
|
|
79
|
+
getFileWriter(params) {
|
|
80
|
+
const writer = new file_writer_1.FileWriter();
|
|
81
|
+
return {
|
|
82
|
+
response: this.request(`/v1/sandboxes/${params.sandboxId}/fs/write`, {
|
|
83
|
+
method: "POST",
|
|
84
|
+
headers: { "content-type": "application/gzip" },
|
|
85
|
+
body: writer.readable,
|
|
86
|
+
}),
|
|
87
|
+
writer,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
78
90
|
async writeFiles(params) {
|
|
79
|
-
const
|
|
91
|
+
const { writer, response } = this.getFileWriter({
|
|
92
|
+
sandboxId: params.sandboxId,
|
|
93
|
+
});
|
|
80
94
|
for (const file of params.files) {
|
|
81
|
-
|
|
95
|
+
await writer.addFile({ name: file.path, content: file.stream });
|
|
82
96
|
}
|
|
83
|
-
await (
|
|
84
|
-
|
|
85
|
-
headers: { ...formData.getHeaders() },
|
|
86
|
-
body: formData,
|
|
87
|
-
}));
|
|
97
|
+
await writer.end();
|
|
98
|
+
await (0, base_client_1.parseOrThrow)(validators_1.WrittenFile, await response);
|
|
88
99
|
}
|
|
89
100
|
async readFile(params) {
|
|
90
101
|
const response = await this.request(`/v1/sandboxes/${params.sandboxId}/fs/read`, {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Readable } from "stream";
|
|
2
|
+
interface FileBuffer {
|
|
3
|
+
/**
|
|
4
|
+
* The name (path) of the file to write.
|
|
5
|
+
*/
|
|
6
|
+
name: string;
|
|
7
|
+
/**
|
|
8
|
+
* The content of the file as a Buffer.
|
|
9
|
+
*/
|
|
10
|
+
content: Buffer;
|
|
11
|
+
}
|
|
12
|
+
interface FileStream {
|
|
13
|
+
/**
|
|
14
|
+
* The name (path) of the file to write.
|
|
15
|
+
*/
|
|
16
|
+
name: string;
|
|
17
|
+
/**
|
|
18
|
+
* A Readable stream to consume the content of the file.
|
|
19
|
+
*/
|
|
20
|
+
content: Readable;
|
|
21
|
+
/**
|
|
22
|
+
* The expected size of the file. This is required to write
|
|
23
|
+
* the header of the compressed file.
|
|
24
|
+
*/
|
|
25
|
+
size: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Allows to create a Readable stream with methods to write files
|
|
29
|
+
* to it and to finish it. Files written are compressed together
|
|
30
|
+
* and gzipped in the stream.
|
|
31
|
+
*/
|
|
32
|
+
export declare class FileWriter {
|
|
33
|
+
readable: Readable;
|
|
34
|
+
private pack;
|
|
35
|
+
constructor();
|
|
36
|
+
/**
|
|
37
|
+
* Allows to add a file to the stream. Size is required to write
|
|
38
|
+
* the tarball header so when content is a stream it must be
|
|
39
|
+
* provided.
|
|
40
|
+
*
|
|
41
|
+
* Returns a Promise resolved once the file is written in the
|
|
42
|
+
* stream.
|
|
43
|
+
*/
|
|
44
|
+
addFile(file: FileBuffer | FileStream): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Allows to finish the stream returning a Promise that will
|
|
47
|
+
* resolve once the readable is effectively closed or
|
|
48
|
+
* errored.
|
|
49
|
+
*/
|
|
50
|
+
end(): Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.FileWriter = void 0;
|
|
7
|
+
const zlib_1 = __importDefault(require("zlib"));
|
|
8
|
+
const tar_stream_1 = __importDefault(require("tar-stream"));
|
|
9
|
+
const stream_1 = require("stream");
|
|
10
|
+
/**
|
|
11
|
+
* Allows to create a Readable stream with methods to write files
|
|
12
|
+
* to it and to finish it. Files written are compressed together
|
|
13
|
+
* and gzipped in the stream.
|
|
14
|
+
*/
|
|
15
|
+
class FileWriter {
|
|
16
|
+
constructor() {
|
|
17
|
+
const gzip = zlib_1.default.createGzip();
|
|
18
|
+
this.pack = tar_stream_1.default.pack();
|
|
19
|
+
this.readable = this.pack.pipe(gzip);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Allows to add a file to the stream. Size is required to write
|
|
23
|
+
* the tarball header so when content is a stream it must be
|
|
24
|
+
* provided.
|
|
25
|
+
*
|
|
26
|
+
* Returns a Promise resolved once the file is written in the
|
|
27
|
+
* stream.
|
|
28
|
+
*/
|
|
29
|
+
async addFile(file) {
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
const entry = this.pack.entry("size" in file
|
|
32
|
+
? { name: file.name, size: file.size }
|
|
33
|
+
: { name: file.name, size: file.content.length }, (error) => {
|
|
34
|
+
if (error) {
|
|
35
|
+
return reject(error);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
resolve();
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
if (file.content instanceof stream_1.Readable) {
|
|
42
|
+
file.content.pipe(entry);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
entry.end(file.content);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Allows to finish the stream returning a Promise that will
|
|
51
|
+
* resolve once the readable is effectively closed or
|
|
52
|
+
* errored.
|
|
53
|
+
*/
|
|
54
|
+
async end() {
|
|
55
|
+
return new Promise((resolve, reject) => {
|
|
56
|
+
this.readable.on("error", reject);
|
|
57
|
+
this.readable.on("end", resolve);
|
|
58
|
+
this.pack.finalize();
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.FileWriter = FileWriter;
|
package/dist/sandbox.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type Writable } from "stream";
|
|
2
2
|
import { APIClient } from "./api-client";
|
|
3
3
|
import { Command, CommandFinished } from "./command";
|
|
4
4
|
import { type Credentials } from "./utils/get-credentials";
|
|
@@ -8,10 +8,16 @@ export interface CreateSandboxParams {
|
|
|
8
8
|
* The source of the sandbox.
|
|
9
9
|
*
|
|
10
10
|
* Omit this parameter start a sandbox without a source.
|
|
11
|
+
*
|
|
12
|
+
* For git sources:
|
|
13
|
+
* - `depth`: Creates shallow clones with limited commit history (minimum: 1)
|
|
14
|
+
* - `revision`: Clones and checks out a specific commit, branch, or tag
|
|
11
15
|
*/
|
|
12
16
|
source?: {
|
|
13
17
|
type: "git";
|
|
14
18
|
url: string;
|
|
19
|
+
depth?: number;
|
|
20
|
+
revision?: string;
|
|
15
21
|
} | {
|
|
16
22
|
type: "tarball";
|
|
17
23
|
url: string;
|
|
@@ -27,12 +33,17 @@ export interface CreateSandboxParams {
|
|
|
27
33
|
/**
|
|
28
34
|
* Resources to allocate to the sandbox.
|
|
29
35
|
*
|
|
30
|
-
* Your sandbox will get the amount of
|
|
31
|
-
*
|
|
36
|
+
* Your sandbox will get the amount of vCPUs you specify here and
|
|
37
|
+
* 2048 MB of memory per vCPU.
|
|
32
38
|
*/
|
|
33
39
|
resources?: {
|
|
34
|
-
|
|
40
|
+
vcpus: number;
|
|
35
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* The runtime of the sandbox, currently only `node22` and `python3.13` are supported.
|
|
44
|
+
* If not specified, the default runtime `node22` will be used.
|
|
45
|
+
*/
|
|
46
|
+
runtime?: "node22" | "python3.13";
|
|
36
47
|
}
|
|
37
48
|
/** @inline */
|
|
38
49
|
interface GetSandboxParams {
|
|
@@ -181,7 +192,7 @@ export declare class Sandbox {
|
|
|
181
192
|
*/
|
|
182
193
|
writeFiles(files: {
|
|
183
194
|
path: string;
|
|
184
|
-
stream:
|
|
195
|
+
stream: Buffer;
|
|
185
196
|
}[]): Promise<void>;
|
|
186
197
|
/**
|
|
187
198
|
* Get the public domain of a port of this sandbox.
|
package/dist/sandbox.js
CHANGED
|
@@ -28,10 +28,8 @@ class Sandbox {
|
|
|
28
28
|
projectId: credentials.projectId,
|
|
29
29
|
ports: params?.ports ?? [],
|
|
30
30
|
timeout: params?.timeout,
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
memory: 2048 * params.resources.cores,
|
|
34
|
-
}),
|
|
31
|
+
resources: params?.resources,
|
|
32
|
+
runtime: params?.runtime,
|
|
35
33
|
});
|
|
36
34
|
return new Sandbox({
|
|
37
35
|
client,
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.0.
|
|
1
|
+
export declare const VERSION = "0.0.8";
|
package/dist/version.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/sandbox",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
"lru-cache": "11.1.0",
|
|
16
16
|
"ms": "2.1.3",
|
|
17
17
|
"node-fetch": "2.6.11",
|
|
18
|
+
"tar-stream": "3.1.7",
|
|
19
|
+
"zlib": "1.0.5",
|
|
18
20
|
"zod": "3.24.4"
|
|
19
21
|
},
|
|
20
22
|
"devDependencies": {
|
|
@@ -23,6 +25,7 @@
|
|
|
23
25
|
"@types/ms": "2.1.0",
|
|
24
26
|
"@types/node": "22.15.12",
|
|
25
27
|
"@types/node-fetch": "2.6.12",
|
|
28
|
+
"@types/tar-stream": "3.1.4",
|
|
26
29
|
"dotenv": "16.5.0",
|
|
27
30
|
"typedoc": "0.28.5",
|
|
28
31
|
"typescript": "5.8.3",
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import FormData from "form-data";
|
|
2
1
|
import {
|
|
3
2
|
BaseClient,
|
|
4
3
|
parseOrThrow,
|
|
@@ -14,8 +13,8 @@ import {
|
|
|
14
13
|
StoppedSandbox,
|
|
15
14
|
WrittenFile,
|
|
16
15
|
} from "./validators";
|
|
17
|
-
import { Readable } from "stream";
|
|
18
16
|
import { APIError } from "./api-error";
|
|
17
|
+
import { FileWriter } from "./file-writer";
|
|
19
18
|
import { LRUCache } from "lru-cache";
|
|
20
19
|
import { VERSION } from "../version";
|
|
21
20
|
import { z } from "zod";
|
|
@@ -60,9 +59,12 @@ export class APIClient extends BaseClient {
|
|
|
60
59
|
async createSandbox(params: {
|
|
61
60
|
ports?: number[];
|
|
62
61
|
projectId: string;
|
|
63
|
-
source?:
|
|
62
|
+
source?:
|
|
63
|
+
| { type: "git"; url: string; depth?: number; revision?: string }
|
|
64
|
+
| { type: "tarball"; url: string };
|
|
64
65
|
timeout?: number;
|
|
65
|
-
resources?: {
|
|
66
|
+
resources?: { vcpus: number };
|
|
67
|
+
runtime?: "node22" | "python3.13";
|
|
66
68
|
}) {
|
|
67
69
|
return parseOrThrow(
|
|
68
70
|
CreatedSandbox,
|
|
@@ -74,6 +76,7 @@ export class APIClient extends BaseClient {
|
|
|
74
76
|
source: params.source,
|
|
75
77
|
timeout: params.timeout,
|
|
76
78
|
resources: params.resources,
|
|
79
|
+
runtime: params.runtime,
|
|
77
80
|
}),
|
|
78
81
|
}),
|
|
79
82
|
);
|
|
@@ -141,24 +144,32 @@ export class APIClient extends BaseClient {
|
|
|
141
144
|
);
|
|
142
145
|
}
|
|
143
146
|
|
|
147
|
+
getFileWriter(params: { sandboxId: string }) {
|
|
148
|
+
const writer = new FileWriter();
|
|
149
|
+
return {
|
|
150
|
+
response: this.request(`/v1/sandboxes/${params.sandboxId}/fs/write`, {
|
|
151
|
+
method: "POST",
|
|
152
|
+
headers: { "content-type": "application/gzip" },
|
|
153
|
+
body: writer.readable,
|
|
154
|
+
}),
|
|
155
|
+
writer,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
144
159
|
async writeFiles(params: {
|
|
145
160
|
sandboxId: string;
|
|
146
|
-
files: { path: string; stream:
|
|
161
|
+
files: { path: string; stream: Buffer }[];
|
|
147
162
|
}) {
|
|
148
|
-
const
|
|
163
|
+
const { writer, response } = this.getFileWriter({
|
|
164
|
+
sandboxId: params.sandboxId,
|
|
165
|
+
});
|
|
149
166
|
|
|
150
167
|
for (const file of params.files) {
|
|
151
|
-
|
|
168
|
+
await writer.addFile({ name: file.path, content: file.stream });
|
|
152
169
|
}
|
|
153
170
|
|
|
154
|
-
await
|
|
155
|
-
|
|
156
|
-
await this.request(`/v1/sandboxes/${params.sandboxId}/fs/write`, {
|
|
157
|
-
method: "POST",
|
|
158
|
-
headers: { ...formData.getHeaders() },
|
|
159
|
-
body: formData,
|
|
160
|
-
}),
|
|
161
|
-
);
|
|
171
|
+
await writer.end();
|
|
172
|
+
await parseOrThrow(WrittenFile, await response);
|
|
162
173
|
}
|
|
163
174
|
|
|
164
175
|
async readFile(params: {
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import zlib from "zlib";
|
|
2
|
+
import tar, { type Pack } from "tar-stream";
|
|
3
|
+
import { Readable } from "stream";
|
|
4
|
+
|
|
5
|
+
interface FileBuffer {
|
|
6
|
+
/**
|
|
7
|
+
* The name (path) of the file to write.
|
|
8
|
+
*/
|
|
9
|
+
name: string;
|
|
10
|
+
/**
|
|
11
|
+
* The content of the file as a Buffer.
|
|
12
|
+
*/
|
|
13
|
+
content: Buffer;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface FileStream {
|
|
17
|
+
/**
|
|
18
|
+
* The name (path) of the file to write.
|
|
19
|
+
*/
|
|
20
|
+
name: string;
|
|
21
|
+
/**
|
|
22
|
+
* A Readable stream to consume the content of the file.
|
|
23
|
+
*/
|
|
24
|
+
content: Readable;
|
|
25
|
+
/**
|
|
26
|
+
* The expected size of the file. This is required to write
|
|
27
|
+
* the header of the compressed file.
|
|
28
|
+
*/
|
|
29
|
+
size: number;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Allows to create a Readable stream with methods to write files
|
|
34
|
+
* to it and to finish it. Files written are compressed together
|
|
35
|
+
* and gzipped in the stream.
|
|
36
|
+
*/
|
|
37
|
+
export class FileWriter {
|
|
38
|
+
public readable: Readable;
|
|
39
|
+
private pack: Pack;
|
|
40
|
+
|
|
41
|
+
constructor() {
|
|
42
|
+
const gzip = zlib.createGzip();
|
|
43
|
+
this.pack = tar.pack();
|
|
44
|
+
this.readable = this.pack.pipe(gzip);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Allows to add a file to the stream. Size is required to write
|
|
49
|
+
* the tarball header so when content is a stream it must be
|
|
50
|
+
* provided.
|
|
51
|
+
*
|
|
52
|
+
* Returns a Promise resolved once the file is written in the
|
|
53
|
+
* stream.
|
|
54
|
+
*/
|
|
55
|
+
async addFile(file: FileBuffer | FileStream) {
|
|
56
|
+
return new Promise<void>((resolve, reject) => {
|
|
57
|
+
const entry = this.pack.entry(
|
|
58
|
+
"size" in file
|
|
59
|
+
? { name: file.name, size: file.size }
|
|
60
|
+
: { name: file.name, size: file.content.length },
|
|
61
|
+
(error) => {
|
|
62
|
+
if (error) {
|
|
63
|
+
return reject(error);
|
|
64
|
+
} else {
|
|
65
|
+
resolve();
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
if (file.content instanceof Readable) {
|
|
71
|
+
file.content.pipe(entry);
|
|
72
|
+
} else {
|
|
73
|
+
entry.end(file.content);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Allows to finish the stream returning a Promise that will
|
|
80
|
+
* resolve once the readable is effectively closed or
|
|
81
|
+
* errored.
|
|
82
|
+
*/
|
|
83
|
+
async end() {
|
|
84
|
+
return new Promise<void>((resolve, reject) => {
|
|
85
|
+
this.readable.on("error", reject);
|
|
86
|
+
this.readable.on("end", resolve);
|
|
87
|
+
this.pack.finalize();
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
package/src/sandbox.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type Writable } from "stream";
|
|
2
2
|
import { APIClient } from "./api-client";
|
|
3
3
|
import { Command, CommandFinished } from "./command";
|
|
4
4
|
import { getCredentials, type Credentials } from "./utils/get-credentials";
|
|
@@ -9,8 +9,14 @@ export interface CreateSandboxParams {
|
|
|
9
9
|
* The source of the sandbox.
|
|
10
10
|
*
|
|
11
11
|
* Omit this parameter start a sandbox without a source.
|
|
12
|
+
*
|
|
13
|
+
* For git sources:
|
|
14
|
+
* - `depth`: Creates shallow clones with limited commit history (minimum: 1)
|
|
15
|
+
* - `revision`: Clones and checks out a specific commit, branch, or tag
|
|
12
16
|
*/
|
|
13
|
-
source?:
|
|
17
|
+
source?:
|
|
18
|
+
| { type: "git"; url: string; depth?: number; revision?: string }
|
|
19
|
+
| { type: "tarball"; url: string };
|
|
14
20
|
/**
|
|
15
21
|
* Array of port numbers to expose from the sandbox.
|
|
16
22
|
*/
|
|
@@ -22,10 +28,16 @@ export interface CreateSandboxParams {
|
|
|
22
28
|
/**
|
|
23
29
|
* Resources to allocate to the sandbox.
|
|
24
30
|
*
|
|
25
|
-
* Your sandbox will get the amount of
|
|
26
|
-
*
|
|
31
|
+
* Your sandbox will get the amount of vCPUs you specify here and
|
|
32
|
+
* 2048 MB of memory per vCPU.
|
|
33
|
+
*/
|
|
34
|
+
resources?: { vcpus: number };
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The runtime of the sandbox, currently only `node22` and `python3.13` are supported.
|
|
38
|
+
* If not specified, the default runtime `node22` will be used.
|
|
27
39
|
*/
|
|
28
|
-
|
|
40
|
+
runtime?: "node22" | "python3.13";
|
|
29
41
|
}
|
|
30
42
|
|
|
31
43
|
/** @inline */
|
|
@@ -112,10 +124,8 @@ export class Sandbox {
|
|
|
112
124
|
projectId: credentials.projectId,
|
|
113
125
|
ports: params?.ports ?? [],
|
|
114
126
|
timeout: params?.timeout,
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
memory: 2048 * params.resources.cores,
|
|
118
|
-
}),
|
|
127
|
+
resources: params?.resources,
|
|
128
|
+
runtime: params?.runtime,
|
|
119
129
|
});
|
|
120
130
|
|
|
121
131
|
return new Sandbox({
|
|
@@ -273,7 +283,7 @@ export class Sandbox {
|
|
|
273
283
|
* @param files - Array of files with path and stream/buffer contents
|
|
274
284
|
* @returns A promise that resolves when the files are written
|
|
275
285
|
*/
|
|
276
|
-
async writeFiles(files: { path: string; stream:
|
|
286
|
+
async writeFiles(files: { path: string; stream: Buffer }[]) {
|
|
277
287
|
return this.client.writeFiles({
|
|
278
288
|
sandboxId: this.sandboxId,
|
|
279
289
|
files: files,
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Autogenerated by inject-version.ts
|
|
2
|
-
export const VERSION = "0.0.
|
|
2
|
+
export const VERSION = "0.0.8";
|