withruntime 0.4.0 → 0.5.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/DAYTONA.md +129 -0
- package/E2B.md +3 -3
- package/README.md +47 -9
- package/VERCEL.md +127 -0
- package/dist/ai/index.d.ts +33 -0
- package/dist/ai/index.js +38 -0
- package/dist/claude-agent-sdk/index.d.ts +7 -0
- package/dist/claude-agent-sdk/index.js +65 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.js +959 -102
- package/dist/client.d.ts +25 -2
- package/dist/client.js +14 -1
- package/dist/credentials.d.ts +10 -0
- package/dist/credentials.js +56 -1
- package/dist/daytona/client.d.ts +44 -0
- package/dist/daytona/client.js +40 -0
- package/dist/daytona/context.d.ts +31 -0
- package/dist/daytona/context.js +25 -0
- package/dist/daytona/daytona.d.ts +185 -0
- package/dist/daytona/daytona.js +416 -0
- package/dist/daytona/errors.d.ts +106 -0
- package/dist/daytona/errors.js +182 -0
- package/dist/daytona/filesystem.d.ts +84 -0
- package/dist/daytona/filesystem.js +206 -0
- package/dist/daytona/git.d.ts +33 -0
- package/dist/daytona/git.js +128 -0
- package/dist/daytona/image.d.ts +45 -0
- package/dist/daytona/image.js +140 -0
- package/dist/daytona/index.d.ts +50 -0
- package/dist/daytona/index.js +50 -0
- package/dist/daytona/process.d.ts +86 -0
- package/dist/daytona/process.js +341 -0
- package/dist/daytona/sandbox.d.ts +196 -0
- package/dist/daytona/sandbox.js +448 -0
- package/dist/e2b/commands.js +6 -2
- package/dist/e2b/sandbox.d.ts +22 -2
- package/dist/e2b/sandbox.js +39 -7
- package/dist/errors.d.ts +10 -4
- package/dist/errors.js +26 -6
- package/dist/image-context.d.ts +39 -0
- package/dist/image-context.js +176 -0
- package/dist/index.d.ts +19 -2
- package/dist/index.js +17 -2
- package/dist/keys.d.ts +43 -0
- package/dist/keys.js +196 -0
- package/dist/login.js +14 -2
- package/dist/openai-agents/index.d.ts +132 -0
- package/dist/openai-agents/index.js +791 -0
- package/dist/products/audit.d.ts +48 -0
- package/dist/products/audit.js +10 -0
- package/dist/products/images.d.ts +113 -7
- package/dist/products/images.js +186 -27
- package/dist/products/index.d.ts +11 -0
- package/dist/products/index.js +17 -1
- package/dist/products/observability.d.ts +186 -0
- package/dist/products/observability.js +117 -0
- package/dist/products/secrets.d.ts +40 -0
- package/dist/products/secrets.js +24 -0
- package/dist/products/switching.d.ts +96 -0
- package/dist/products/switching.js +25 -0
- package/dist/sandbox.d.ts +26 -1
- package/dist/sandbox.js +101 -1
- package/dist/ssh.d.ts +21 -0
- package/dist/ssh.js +324 -0
- package/dist/tar.d.ts +1 -0
- package/dist/tar.js +4 -4
- package/dist/tools/index.d.ts +62 -0
- package/dist/tools/index.js +180 -0
- package/dist/transport.d.ts +12 -2
- package/dist/transport.js +31 -4
- package/dist/tunnel.d.ts +70 -0
- package/dist/tunnel.js +316 -0
- package/dist/types.d.ts +57 -1
- package/dist/vercel/client.d.ts +40 -0
- package/dist/vercel/client.js +39 -0
- package/dist/vercel/command.d.ts +70 -0
- package/dist/vercel/command.js +148 -0
- package/dist/vercel/errors.d.ts +53 -0
- package/dist/vercel/errors.js +113 -0
- package/dist/vercel/filesystem.d.ts +150 -0
- package/dist/vercel/filesystem.js +248 -0
- package/dist/vercel/index.d.ts +30 -0
- package/dist/vercel/index.js +38 -0
- package/dist/vercel/sandbox.d.ts +317 -0
- package/dist/vercel/sandbox.js +726 -0
- package/dist/vercel/snapshot.d.ts +93 -0
- package/dist/vercel/snapshot.js +123 -0
- package/package.json +56 -4
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import type { Files } from "../sandbox.js";
|
|
2
|
+
import type { FileEntry } from "../types.js";
|
|
3
|
+
/** What `sandbox.fs` needs from its sandbox. */
|
|
4
|
+
export interface FsContext {
|
|
5
|
+
readonly name: string;
|
|
6
|
+
files(): Promise<Files>;
|
|
7
|
+
/** Runs argv without a shell; resolves with the exit code and output. */
|
|
8
|
+
run(argv: string[]): Promise<{
|
|
9
|
+
exitCode: number | null;
|
|
10
|
+
stdout: string;
|
|
11
|
+
stderr: string;
|
|
12
|
+
}>;
|
|
13
|
+
resolve(path: string, cwd?: string): string;
|
|
14
|
+
}
|
|
15
|
+
type WriteFileData = string | Uint8Array;
|
|
16
|
+
type Encoding = "utf8" | "utf-8" | "ascii" | "latin1" | "base64" | "hex" | "binary";
|
|
17
|
+
/** Node's Stats, as far as a sandbox file can answer. uid, gid, ino and the
|
|
18
|
+
* other inode fields are 0. */
|
|
19
|
+
export declare class Stats {
|
|
20
|
+
#private;
|
|
21
|
+
readonly size: number;
|
|
22
|
+
readonly mode: number;
|
|
23
|
+
readonly mtime: Date;
|
|
24
|
+
readonly mtimeMs: number;
|
|
25
|
+
readonly atime: Date;
|
|
26
|
+
readonly atimeMs: number;
|
|
27
|
+
readonly ctime: Date;
|
|
28
|
+
readonly ctimeMs: number;
|
|
29
|
+
readonly birthtime: Date;
|
|
30
|
+
readonly birthtimeMs: number;
|
|
31
|
+
readonly uid = 0;
|
|
32
|
+
readonly gid = 0;
|
|
33
|
+
readonly dev = 0;
|
|
34
|
+
readonly ino = 0;
|
|
35
|
+
readonly nlink = 1;
|
|
36
|
+
readonly rdev = 0;
|
|
37
|
+
readonly blksize = 4096;
|
|
38
|
+
readonly blocks: number;
|
|
39
|
+
constructor(entry: FileEntry);
|
|
40
|
+
isFile(): boolean;
|
|
41
|
+
isDirectory(): boolean;
|
|
42
|
+
isSymbolicLink(): boolean;
|
|
43
|
+
isBlockDevice(): boolean;
|
|
44
|
+
isCharacterDevice(): boolean;
|
|
45
|
+
isFIFO(): boolean;
|
|
46
|
+
isSocket(): boolean;
|
|
47
|
+
}
|
|
48
|
+
/** Node's Dirent, from a sandbox listing. */
|
|
49
|
+
export declare class Dirent {
|
|
50
|
+
#private;
|
|
51
|
+
readonly name: string;
|
|
52
|
+
readonly parentPath: string;
|
|
53
|
+
readonly path: string;
|
|
54
|
+
constructor(entry: FileEntry, parent: string);
|
|
55
|
+
isFile(): boolean;
|
|
56
|
+
isDirectory(): boolean;
|
|
57
|
+
isSymbolicLink(): boolean;
|
|
58
|
+
isBlockDevice(): boolean;
|
|
59
|
+
isCharacterDevice(): boolean;
|
|
60
|
+
isFIFO(): boolean;
|
|
61
|
+
isSocket(): boolean;
|
|
62
|
+
}
|
|
63
|
+
/** `sandbox.fs`: node:fs/promises over Runtime's files API and a few
|
|
64
|
+
* commands. Relative paths resolve against the sandbox's working directory,
|
|
65
|
+
* `/vercel/sandbox`, which is `/workspace` on Runtime. Errors carry Node's
|
|
66
|
+
* codes: `ENOENT` for a missing path. */
|
|
67
|
+
export declare class FileSystem {
|
|
68
|
+
#private;
|
|
69
|
+
constructor(ctx: FsContext);
|
|
70
|
+
readFile(path: string, options?: {
|
|
71
|
+
encoding?: null;
|
|
72
|
+
signal?: AbortSignal;
|
|
73
|
+
} | null): Promise<Buffer>;
|
|
74
|
+
readFile(path: string, options: {
|
|
75
|
+
encoding: Encoding;
|
|
76
|
+
signal?: AbortSignal;
|
|
77
|
+
} | Encoding): Promise<string>;
|
|
78
|
+
writeFile(path: string, data: WriteFileData, options?: {
|
|
79
|
+
encoding?: Encoding;
|
|
80
|
+
signal?: AbortSignal;
|
|
81
|
+
} | Encoding): Promise<void>;
|
|
82
|
+
appendFile(path: string, data: WriteFileData, options?: {
|
|
83
|
+
encoding?: Encoding;
|
|
84
|
+
signal?: AbortSignal;
|
|
85
|
+
} | Encoding): Promise<void>;
|
|
86
|
+
mkdir(path: string, options?: {
|
|
87
|
+
recursive?: boolean;
|
|
88
|
+
signal?: AbortSignal;
|
|
89
|
+
} | number): Promise<string | undefined>;
|
|
90
|
+
readdir(path: string, options?: {
|
|
91
|
+
signal?: AbortSignal;
|
|
92
|
+
withFileTypes?: false;
|
|
93
|
+
}): Promise<string[]>;
|
|
94
|
+
readdir(path: string, options: {
|
|
95
|
+
signal?: AbortSignal;
|
|
96
|
+
withFileTypes: true;
|
|
97
|
+
}): Promise<Dirent[]>;
|
|
98
|
+
lstat(path: string, _options?: {
|
|
99
|
+
signal?: AbortSignal;
|
|
100
|
+
}): Promise<Stats>;
|
|
101
|
+
/** Follows symbolic links. */
|
|
102
|
+
stat(path: string, options?: {
|
|
103
|
+
signal?: AbortSignal;
|
|
104
|
+
}): Promise<Stats>;
|
|
105
|
+
unlink(path: string, _options?: {
|
|
106
|
+
signal?: AbortSignal;
|
|
107
|
+
}): Promise<void>;
|
|
108
|
+
rm(path: string, options?: {
|
|
109
|
+
recursive?: boolean;
|
|
110
|
+
force?: boolean;
|
|
111
|
+
signal?: AbortSignal;
|
|
112
|
+
}): Promise<void>;
|
|
113
|
+
rmdir(path: string, _options?: {
|
|
114
|
+
signal?: AbortSignal;
|
|
115
|
+
}): Promise<void>;
|
|
116
|
+
rename(oldPath: string, newPath: string, _options?: {
|
|
117
|
+
signal?: AbortSignal;
|
|
118
|
+
}): Promise<void>;
|
|
119
|
+
copyFile(src: string, dest: string, _options?: {
|
|
120
|
+
signal?: AbortSignal;
|
|
121
|
+
}): Promise<void>;
|
|
122
|
+
access(path: string, _options?: {
|
|
123
|
+
signal?: AbortSignal;
|
|
124
|
+
}): Promise<void>;
|
|
125
|
+
exists(path: string, _options?: {
|
|
126
|
+
signal?: AbortSignal;
|
|
127
|
+
}): Promise<boolean>;
|
|
128
|
+
chmod(path: string, mode: number | string, _options?: {
|
|
129
|
+
signal?: AbortSignal;
|
|
130
|
+
}): Promise<void>;
|
|
131
|
+
chown(path: string, uid: number, gid: number, _options?: {
|
|
132
|
+
signal?: AbortSignal;
|
|
133
|
+
}): Promise<void>;
|
|
134
|
+
symlink(target: string, path: string, _options?: {
|
|
135
|
+
signal?: AbortSignal;
|
|
136
|
+
}): Promise<void>;
|
|
137
|
+
readlink(path: string, _options?: {
|
|
138
|
+
signal?: AbortSignal;
|
|
139
|
+
}): Promise<string>;
|
|
140
|
+
realpath(path: string, _options?: {
|
|
141
|
+
signal?: AbortSignal;
|
|
142
|
+
}): Promise<string>;
|
|
143
|
+
truncate(path: string, len?: number, _options?: {
|
|
144
|
+
signal?: AbortSignal;
|
|
145
|
+
}): Promise<void>;
|
|
146
|
+
mkdtemp(prefix: string, _options?: {
|
|
147
|
+
signal?: AbortSignal;
|
|
148
|
+
}): Promise<string>;
|
|
149
|
+
}
|
|
150
|
+
export {};
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { RuntimeError } from "../errors.js";
|
|
2
|
+
import { fsError, translate } from "./errors.js";
|
|
3
|
+
/** Node's Stats, as far as a sandbox file can answer. uid, gid, ino and the
|
|
4
|
+
* other inode fields are 0. */
|
|
5
|
+
export class Stats {
|
|
6
|
+
size;
|
|
7
|
+
mode;
|
|
8
|
+
mtime;
|
|
9
|
+
mtimeMs;
|
|
10
|
+
atime;
|
|
11
|
+
atimeMs;
|
|
12
|
+
ctime;
|
|
13
|
+
ctimeMs;
|
|
14
|
+
birthtime;
|
|
15
|
+
birthtimeMs;
|
|
16
|
+
uid = 0;
|
|
17
|
+
gid = 0;
|
|
18
|
+
dev = 0;
|
|
19
|
+
ino = 0;
|
|
20
|
+
nlink = 1;
|
|
21
|
+
rdev = 0;
|
|
22
|
+
blksize = 4096;
|
|
23
|
+
blocks;
|
|
24
|
+
#type;
|
|
25
|
+
constructor(entry) {
|
|
26
|
+
this.#type = entry.type;
|
|
27
|
+
this.size = entry.size;
|
|
28
|
+
const typeBits = entry.type === "directory" ? 0o040000 : entry.type === "symlink" ? 0o120000 : 0o100000;
|
|
29
|
+
this.mode = typeBits | ((parseInt(entry.mode, 8) || 0) & 0o7777);
|
|
30
|
+
this.mtime = this.atime = this.ctime = this.birthtime = new Date(entry.modifiedAt);
|
|
31
|
+
this.mtimeMs = this.atimeMs = this.ctimeMs = this.birthtimeMs = this.mtime.getTime();
|
|
32
|
+
this.blocks = Math.ceil(entry.size / 512);
|
|
33
|
+
}
|
|
34
|
+
isFile() {
|
|
35
|
+
return this.#type === "file";
|
|
36
|
+
}
|
|
37
|
+
isDirectory() {
|
|
38
|
+
return this.#type === "directory";
|
|
39
|
+
}
|
|
40
|
+
isSymbolicLink() {
|
|
41
|
+
return this.#type === "symlink";
|
|
42
|
+
}
|
|
43
|
+
isBlockDevice() {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
isCharacterDevice() {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
isFIFO() {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
isSocket() {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/** Node's Dirent, from a sandbox listing. */
|
|
57
|
+
export class Dirent {
|
|
58
|
+
name;
|
|
59
|
+
parentPath;
|
|
60
|
+
path;
|
|
61
|
+
#type;
|
|
62
|
+
constructor(entry, parent) {
|
|
63
|
+
this.name = entry.name;
|
|
64
|
+
this.parentPath = this.path = parent;
|
|
65
|
+
this.#type = entry.type;
|
|
66
|
+
}
|
|
67
|
+
isFile() {
|
|
68
|
+
return this.#type === "file";
|
|
69
|
+
}
|
|
70
|
+
isDirectory() {
|
|
71
|
+
return this.#type === "directory";
|
|
72
|
+
}
|
|
73
|
+
isSymbolicLink() {
|
|
74
|
+
return this.#type === "symlink";
|
|
75
|
+
}
|
|
76
|
+
isBlockDevice() {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
isCharacterDevice() {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
isFIFO() {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
isSocket() {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const encodingOf = (options) => typeof options === "string" ? options : (options?.encoding ?? null);
|
|
90
|
+
const bytesOf = (data, encoding) => typeof data === "string" ? Buffer.from(data, encoding ?? "utf8") : Buffer.from(data);
|
|
91
|
+
function missing(error) {
|
|
92
|
+
return error instanceof RuntimeError && (error.code === "file_not_found" || error.status === 404);
|
|
93
|
+
}
|
|
94
|
+
/** `sandbox.fs`: node:fs/promises over Runtime's files API and a few
|
|
95
|
+
* commands. Relative paths resolve against the sandbox's working directory,
|
|
96
|
+
* `/vercel/sandbox`, which is `/workspace` on Runtime. Errors carry Node's
|
|
97
|
+
* codes: `ENOENT` for a missing path. */
|
|
98
|
+
export class FileSystem {
|
|
99
|
+
#ctx;
|
|
100
|
+
constructor(ctx) {
|
|
101
|
+
this.#ctx = ctx;
|
|
102
|
+
}
|
|
103
|
+
async #call(syscall, path, work) {
|
|
104
|
+
try {
|
|
105
|
+
return await work();
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
if (missing(error))
|
|
109
|
+
throw fsError("ENOENT", syscall, path);
|
|
110
|
+
throw translate(error, this.#ctx.name);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/** Runs a coreutils command; a failure is a Node-style error. */
|
|
114
|
+
async #run(syscall, path, argv) {
|
|
115
|
+
const result = await this.#call(syscall, path, () => this.#ctx.run(argv));
|
|
116
|
+
if (result.exitCode === 0)
|
|
117
|
+
return result.stdout;
|
|
118
|
+
if (/No such file or directory/.test(result.stderr))
|
|
119
|
+
throw fsError("ENOENT", syscall, path);
|
|
120
|
+
if (/File exists/.test(result.stderr))
|
|
121
|
+
throw fsError("EEXIST", syscall, path);
|
|
122
|
+
if (/Is a directory/.test(result.stderr))
|
|
123
|
+
throw fsError("EISDIR", syscall, path);
|
|
124
|
+
if (/Not a directory/.test(result.stderr))
|
|
125
|
+
throw fsError("ENOTDIR", syscall, path);
|
|
126
|
+
throw Object.assign(new Error(`${syscall} '${path}' failed: ${result.stderr.trim()}`), {
|
|
127
|
+
code: "EIO",
|
|
128
|
+
syscall,
|
|
129
|
+
path,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
async readFile(path, options) {
|
|
133
|
+
const target = this.#ctx.resolve(path);
|
|
134
|
+
const files = await this.#ctx.files();
|
|
135
|
+
const bytes = await this.#call("open", target, () => files.read(target, typeof options === "object" && options?.signal ? { signal: options.signal } : {}));
|
|
136
|
+
const encoding = encodingOf(options);
|
|
137
|
+
const buffer = Buffer.from(bytes);
|
|
138
|
+
return encoding ? buffer.toString(encoding) : buffer;
|
|
139
|
+
}
|
|
140
|
+
async writeFile(path, data, options) {
|
|
141
|
+
const target = this.#ctx.resolve(path);
|
|
142
|
+
const files = await this.#ctx.files();
|
|
143
|
+
await this.#call("open", target, () => files.write(target, bytesOf(data, encodingOf(options))));
|
|
144
|
+
}
|
|
145
|
+
async appendFile(path, data, options) {
|
|
146
|
+
const target = this.#ctx.resolve(path);
|
|
147
|
+
const files = await this.#ctx.files();
|
|
148
|
+
const before = await files.read(target).catch((error) => {
|
|
149
|
+
if (missing(error))
|
|
150
|
+
return new Uint8Array();
|
|
151
|
+
throw translate(error, this.#ctx.name);
|
|
152
|
+
});
|
|
153
|
+
await this.#call("open", target, () => files.write(target, Buffer.concat([before, bytesOf(data, encodingOf(options))])));
|
|
154
|
+
}
|
|
155
|
+
async mkdir(path, options) {
|
|
156
|
+
const target = this.#ctx.resolve(path);
|
|
157
|
+
const recursive = typeof options === "object" && options.recursive === true;
|
|
158
|
+
await this.#run("mkdir", target, recursive ? ["mkdir", "-p", target] : ["mkdir", target]);
|
|
159
|
+
return recursive ? target : undefined;
|
|
160
|
+
}
|
|
161
|
+
async readdir(path, options = {}) {
|
|
162
|
+
const target = this.#ctx.resolve(path);
|
|
163
|
+
const files = await this.#ctx.files();
|
|
164
|
+
const entries = await this.#call("scandir", target, () => files.list(target, { depth: 1, hidden: true }));
|
|
165
|
+
return options.withFileTypes
|
|
166
|
+
? entries.map((entry) => new Dirent(entry, target))
|
|
167
|
+
: entries.map((entry) => entry.name);
|
|
168
|
+
}
|
|
169
|
+
async lstat(path, _options = {}) {
|
|
170
|
+
const target = this.#ctx.resolve(path);
|
|
171
|
+
const files = await this.#ctx.files();
|
|
172
|
+
const found = await this.#call("lstat", target, () => files.stat(target));
|
|
173
|
+
if (!found.exists)
|
|
174
|
+
throw fsError("ENOENT", "lstat", target);
|
|
175
|
+
return new Stats(found);
|
|
176
|
+
}
|
|
177
|
+
/** Follows symbolic links. */
|
|
178
|
+
async stat(path, options = {}) {
|
|
179
|
+
const target = this.#ctx.resolve(path);
|
|
180
|
+
const first = await this.lstat(target, options);
|
|
181
|
+
if (!first.isSymbolicLink())
|
|
182
|
+
return first;
|
|
183
|
+
return this.lstat(await this.realpath(target), options);
|
|
184
|
+
}
|
|
185
|
+
async unlink(path, _options = {}) {
|
|
186
|
+
const target = this.#ctx.resolve(path);
|
|
187
|
+
await this.#run("unlink", target, ["rm", "--", target]);
|
|
188
|
+
}
|
|
189
|
+
async rm(path, options = {}) {
|
|
190
|
+
const target = this.#ctx.resolve(path);
|
|
191
|
+
const flags = `${options.recursive ? "r" : ""}${options.force ? "f" : ""}`;
|
|
192
|
+
await this.#run("rm", target, flags ? ["rm", `-${flags}`, "--", target] : ["rm", "--", target]);
|
|
193
|
+
}
|
|
194
|
+
async rmdir(path, _options = {}) {
|
|
195
|
+
const target = this.#ctx.resolve(path);
|
|
196
|
+
await this.#run("rmdir", target, ["rmdir", "--", target]);
|
|
197
|
+
}
|
|
198
|
+
async rename(oldPath, newPath, _options = {}) {
|
|
199
|
+
const from = this.#ctx.resolve(oldPath);
|
|
200
|
+
const to = this.#ctx.resolve(newPath);
|
|
201
|
+
const files = await this.#ctx.files();
|
|
202
|
+
await this.#call("rename", from, () => files.rename(from, to, { overwrite: true }));
|
|
203
|
+
}
|
|
204
|
+
async copyFile(src, dest, _options = {}) {
|
|
205
|
+
const from = this.#ctx.resolve(src);
|
|
206
|
+
const to = this.#ctx.resolve(dest);
|
|
207
|
+
await this.#run("copyfile", from, ["cp", "--", from, to]);
|
|
208
|
+
}
|
|
209
|
+
async access(path, _options = {}) {
|
|
210
|
+
const target = this.#ctx.resolve(path);
|
|
211
|
+
if (!(await this.exists(target)))
|
|
212
|
+
throw fsError("ENOENT", "access", target);
|
|
213
|
+
}
|
|
214
|
+
async exists(path, _options = {}) {
|
|
215
|
+
const target = this.#ctx.resolve(path);
|
|
216
|
+
const files = await this.#ctx.files();
|
|
217
|
+
return this.#call("access", target, () => files.exists(target));
|
|
218
|
+
}
|
|
219
|
+
async chmod(path, mode, _options = {}) {
|
|
220
|
+
const target = this.#ctx.resolve(path);
|
|
221
|
+
const octal = typeof mode === "number" ? mode.toString(8) : mode;
|
|
222
|
+
await this.#run("chmod", target, ["chmod", octal, "--", target]);
|
|
223
|
+
}
|
|
224
|
+
async chown(path, uid, gid, _options = {}) {
|
|
225
|
+
const target = this.#ctx.resolve(path);
|
|
226
|
+
await this.#run("chown", target, ["sudo", "chown", `${uid}:${gid}`, "--", target]);
|
|
227
|
+
}
|
|
228
|
+
async symlink(target, path, _options = {}) {
|
|
229
|
+
const link = this.#ctx.resolve(path);
|
|
230
|
+
await this.#run("symlink", link, ["ln", "-s", "--", target, link]);
|
|
231
|
+
}
|
|
232
|
+
async readlink(path, _options = {}) {
|
|
233
|
+
const target = this.#ctx.resolve(path);
|
|
234
|
+
return (await this.#run("readlink", target, ["readlink", "--", target])).replace(/\n$/, "");
|
|
235
|
+
}
|
|
236
|
+
async realpath(path, _options = {}) {
|
|
237
|
+
const target = this.#ctx.resolve(path);
|
|
238
|
+
return (await this.#run("realpath", target, ["realpath", "-e", "--", target])).replace(/\n$/, "");
|
|
239
|
+
}
|
|
240
|
+
async truncate(path, len = 0, _options = {}) {
|
|
241
|
+
const target = this.#ctx.resolve(path);
|
|
242
|
+
await this.#run("open", target, ["truncate", "-s", String(len), "--", target]);
|
|
243
|
+
}
|
|
244
|
+
async mkdtemp(prefix, _options = {}) {
|
|
245
|
+
const base = this.#ctx.resolve(prefix);
|
|
246
|
+
return (await this.#run("mkdtemp", base, ["mktemp", "-d", `${base}XXXXXX`])).replace(/\n$/, "");
|
|
247
|
+
}
|
|
248
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export { Sandbox, DEFAULT_TIMEOUT_MS, DEFAULT_VCPUS, MEMORY_MIB_PER_VCPU, networkRules, toRuntimePath, type CreateSandboxParams, type RunCommandParams, type NetworkPolicy, type SandboxRoute, } from "./sandbox.js";
|
|
2
|
+
export { Command, CommandFinished, type CommandOutput, type LogOutputLine, type Signal, } from "./command.js";
|
|
3
|
+
export { FileSystem, Stats, Dirent } from "./filesystem.js";
|
|
4
|
+
export { Snapshot } from "./snapshot.js";
|
|
5
|
+
export { APIError, StreamError, AuthenticationError, NotSupportedError } from "./errors.js";
|
|
6
|
+
export type { Credentials, WithRuntime } from "./client.js";
|
|
7
|
+
/** Vercel's default region; Runtime runs in one US region. */
|
|
8
|
+
export declare const DEFAULT_SANDBOX_REGION = "iad1";
|
|
9
|
+
export declare const Drive: {
|
|
10
|
+
(...args: unknown[]): never;
|
|
11
|
+
new (...args: unknown[]): never;
|
|
12
|
+
readonly [key: string]: (...args: unknown[]) => never;
|
|
13
|
+
};
|
|
14
|
+
export declare const Session: {
|
|
15
|
+
(...args: unknown[]): never;
|
|
16
|
+
new (...args: unknown[]): never;
|
|
17
|
+
readonly [key: string]: (...args: unknown[]) => never;
|
|
18
|
+
};
|
|
19
|
+
export declare const SandboxUser: {
|
|
20
|
+
(...args: unknown[]): never;
|
|
21
|
+
new (...args: unknown[]): never;
|
|
22
|
+
readonly [key: string]: (...args: unknown[]) => never;
|
|
23
|
+
};
|
|
24
|
+
export declare class SandboxUserAlreadyExistsError extends Error {
|
|
25
|
+
}
|
|
26
|
+
export declare const defineSandboxProxy: {
|
|
27
|
+
(...args: unknown[]): never;
|
|
28
|
+
new (...args: unknown[]): never;
|
|
29
|
+
readonly [key: string]: (...args: unknown[]) => never;
|
|
30
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Code written for Vercel Sandbox's SDK, on Runtime Cloud. Change the import:
|
|
2
|
+
*
|
|
3
|
+
* import { Sandbox } from "withruntime/vercel"; // was: from "@vercel/sandbox"
|
|
4
|
+
*
|
|
5
|
+
* and set RUNTIME_API_KEY, or run `npx withruntime login` once. A Vercel token
|
|
6
|
+
* is never sent anywhere. What Runtime cannot do the way Vercel does throws
|
|
7
|
+
* NotSupportedError, naming what to use. */
|
|
8
|
+
import { NotSupportedError } from "./errors.js";
|
|
9
|
+
export { Sandbox, DEFAULT_TIMEOUT_MS, DEFAULT_VCPUS, MEMORY_MIB_PER_VCPU, networkRules, toRuntimePath, } from "./sandbox.js";
|
|
10
|
+
export { Command, CommandFinished, } from "./command.js";
|
|
11
|
+
export { FileSystem, Stats, Dirent } from "./filesystem.js";
|
|
12
|
+
export { Snapshot } from "./snapshot.js";
|
|
13
|
+
export { APIError, StreamError, AuthenticationError, NotSupportedError } from "./errors.js";
|
|
14
|
+
/** Vercel's default region; Runtime runs in one US region. */
|
|
15
|
+
export const DEFAULT_SANDBOX_REGION = "iad1";
|
|
16
|
+
/** A stand-in for a Vercel export Runtime has no counterpart for. Importing it
|
|
17
|
+
* works, so a module that only mentions it still loads; calling it, building it
|
|
18
|
+
* or reading anything from it throws NotSupportedError naming the alternative. */
|
|
19
|
+
function unsupportedExport(name, alternative) {
|
|
20
|
+
const fail = () => {
|
|
21
|
+
throw new NotSupportedError(`Vercel's ${name}`, alternative);
|
|
22
|
+
};
|
|
23
|
+
return new Proxy(function unsupported() { }, {
|
|
24
|
+
apply: fail,
|
|
25
|
+
construct: fail,
|
|
26
|
+
get: (_target, property) => {
|
|
27
|
+
if (typeof property === "symbol" || property === "then" || property === "prototype")
|
|
28
|
+
return undefined;
|
|
29
|
+
return fail();
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
export const Drive = unsupportedExport("Drive", "Use a Runtime volume (runtime.volumes) and mount it with withruntime: { create: { volumes: [{ volumeId, path }] } }.");
|
|
34
|
+
export const Session = unsupportedExport("Session", "A Runtime sandbox is its own session: call the methods on the sandbox.");
|
|
35
|
+
export const SandboxUser = unsupportedExport("SandboxUser", "Commands run as the sandbox owner with passwordless sudo; create users with `sudo useradd` in runCommand.");
|
|
36
|
+
export class SandboxUserAlreadyExistsError extends Error {
|
|
37
|
+
}
|
|
38
|
+
export const defineSandboxProxy = unsupportedExport("sandbox proxy (defineSandboxProxy)", "Share a port with sandbox.withruntime.previews.create(port) instead.");
|