@computesdk/beam 0.1.8 → 0.1.10
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/dist/index.d.mts +0 -16
- package/dist/index.d.ts +0 -16
- package/dist/index.js +37 -201
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +37 -201
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -2,28 +2,12 @@ import * as _computesdk_provider from '@computesdk/provider';
|
|
|
2
2
|
import { SandboxInstance } from '@beamcloud/beam-js';
|
|
3
3
|
export { SandboxInstance as BeamSandboxInstance } from '@beamcloud/beam-js';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Beam-specific configuration options
|
|
7
|
-
*/
|
|
8
5
|
interface BeamConfig {
|
|
9
|
-
/** Beam API token - if not provided, will fallback to BEAM_TOKEN environment variable */
|
|
10
6
|
token?: string;
|
|
11
|
-
/** Beam workspace ID - if not provided, will fallback to BEAM_WORKSPACE_ID environment variable */
|
|
12
7
|
workspaceId?: string;
|
|
13
|
-
/** Gateway URL for custom/staging environments */
|
|
14
8
|
gatewayUrl?: string;
|
|
15
|
-
/** Request timeout in milliseconds */
|
|
16
9
|
timeout?: number;
|
|
17
10
|
}
|
|
18
|
-
/**
|
|
19
|
-
* Create a Beam provider instance using the factory pattern
|
|
20
|
-
*
|
|
21
|
-
* Beam provides containerized sandbox environments with:
|
|
22
|
-
* - Process management (exec, runCode)
|
|
23
|
-
* - Filesystem access
|
|
24
|
-
* - Dynamic port exposure
|
|
25
|
-
* - Snapshot and image creation capabilities
|
|
26
|
-
*/
|
|
27
11
|
declare const beam: (config: BeamConfig) => _computesdk_provider.Provider<SandboxInstance, any, any>;
|
|
28
12
|
|
|
29
13
|
export { type BeamConfig, beam };
|
package/dist/index.d.ts
CHANGED
|
@@ -2,28 +2,12 @@ import * as _computesdk_provider from '@computesdk/provider';
|
|
|
2
2
|
import { SandboxInstance } from '@beamcloud/beam-js';
|
|
3
3
|
export { SandboxInstance as BeamSandboxInstance } from '@beamcloud/beam-js';
|
|
4
4
|
|
|
5
|
-
/**
|
|
6
|
-
* Beam-specific configuration options
|
|
7
|
-
*/
|
|
8
5
|
interface BeamConfig {
|
|
9
|
-
/** Beam API token - if not provided, will fallback to BEAM_TOKEN environment variable */
|
|
10
6
|
token?: string;
|
|
11
|
-
/** Beam workspace ID - if not provided, will fallback to BEAM_WORKSPACE_ID environment variable */
|
|
12
7
|
workspaceId?: string;
|
|
13
|
-
/** Gateway URL for custom/staging environments */
|
|
14
8
|
gatewayUrl?: string;
|
|
15
|
-
/** Request timeout in milliseconds */
|
|
16
9
|
timeout?: number;
|
|
17
10
|
}
|
|
18
|
-
/**
|
|
19
|
-
* Create a Beam provider instance using the factory pattern
|
|
20
|
-
*
|
|
21
|
-
* Beam provides containerized sandbox environments with:
|
|
22
|
-
* - Process management (exec, runCode)
|
|
23
|
-
* - Filesystem access
|
|
24
|
-
* - Dynamic port exposure
|
|
25
|
-
* - Snapshot and image creation capabilities
|
|
26
|
-
*/
|
|
27
11
|
declare const beam: (config: BeamConfig) => _computesdk_provider.Provider<SandboxInstance, any, any>;
|
|
28
12
|
|
|
29
13
|
export { type BeamConfig, beam };
|
package/dist/index.js
CHANGED
|
@@ -28,48 +28,17 @@ var import_provider = require("@computesdk/provider");
|
|
|
28
28
|
function configureBeamOpts(config) {
|
|
29
29
|
import_beam_js.beamOpts.token = config.token || typeof process !== "undefined" && process.env?.BEAM_TOKEN || "";
|
|
30
30
|
import_beam_js.beamOpts.workspaceId = config.workspaceId || typeof process !== "undefined" && process.env?.BEAM_WORKSPACE_ID || "";
|
|
31
|
-
if (config.gatewayUrl)
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
if (config.timeout) {
|
|
35
|
-
import_beam_js.beamOpts.timeout = config.timeout;
|
|
36
|
-
}
|
|
31
|
+
if (config.gatewayUrl) import_beam_js.beamOpts.gatewayUrl = config.gatewayUrl;
|
|
32
|
+
if (config.timeout) import_beam_js.beamOpts.timeout = config.timeout;
|
|
37
33
|
}
|
|
38
34
|
function shellEscape(arg) {
|
|
39
35
|
if (arg === "") return "''";
|
|
40
36
|
return `'${arg.replace(/'/g, "'\\''")}'`;
|
|
41
37
|
}
|
|
42
|
-
function isNodeParserFailure(output) {
|
|
43
|
-
const hasSyntaxMarker = output.includes("SyntaxError") || output.includes("Unexpected token") || output.includes("Unexpected identifier") || output.includes("Unexpected end of input") || output.includes("Invalid or unexpected token");
|
|
44
|
-
const hasCompileContext = output.includes("[eval]") || output.includes("makeContextifyScript") || output.includes("compileScript") || output.includes("wrapSafe");
|
|
45
|
-
const hasRuntimeSyntaxSignature = output.includes("at JSON.parse") || output.includes("JSON.parse (<anonymous>)") || output.includes("in JSON at position");
|
|
46
|
-
return hasSyntaxMarker && hasCompileContext && !hasRuntimeSyntaxSignature;
|
|
47
|
-
}
|
|
48
|
-
function isPythonParserFailure(output) {
|
|
49
|
-
const hasSyntaxMarker = output.includes("SyntaxError") || output.includes("IndentationError") || output.includes("TabError");
|
|
50
|
-
const hasStringFileContext = output.includes('File "<string>"');
|
|
51
|
-
const hasRuntimeTraceback = output.includes("Traceback (most recent call last)");
|
|
52
|
-
return hasSyntaxMarker && hasStringFileContext && !hasRuntimeTraceback;
|
|
53
|
-
}
|
|
54
|
-
function isParserFailure(output, runtime) {
|
|
55
|
-
if (!output.trim()) return false;
|
|
56
|
-
if (runtime === "node") {
|
|
57
|
-
return isNodeParserFailure(output);
|
|
58
|
-
}
|
|
59
|
-
if (runtime === "python") {
|
|
60
|
-
return isPythonParserFailure(output);
|
|
61
|
-
}
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
38
|
var beam = (0, import_provider.defineProvider)({
|
|
65
39
|
name: "beam",
|
|
66
40
|
methods: {
|
|
67
41
|
sandbox: {
|
|
68
|
-
/**
|
|
69
|
-
* Create a new Beam sandbox
|
|
70
|
-
*
|
|
71
|
-
* Uses Sandbox class from @beamcloud/beam-js to provision a container.
|
|
72
|
-
*/
|
|
73
42
|
create: async (config, options) => {
|
|
74
43
|
configureBeamOpts(config);
|
|
75
44
|
if (!import_beam_js.beamOpts.token) {
|
|
@@ -83,12 +52,7 @@ var beam = (0, import_provider.defineProvider)({
|
|
|
83
52
|
);
|
|
84
53
|
}
|
|
85
54
|
try {
|
|
86
|
-
if (options?.sandboxId) {
|
|
87
|
-
const instance2 = await import_beam_js.Sandbox.connect(options.sandboxId);
|
|
88
|
-
return { sandbox: instance2, sandboxId: instance2.containerId };
|
|
89
|
-
}
|
|
90
55
|
const {
|
|
91
|
-
runtime: optRuntime,
|
|
92
56
|
timeout: optTimeout,
|
|
93
57
|
envs,
|
|
94
58
|
name,
|
|
@@ -98,20 +62,16 @@ var beam = (0, import_provider.defineProvider)({
|
|
|
98
62
|
sandboxId: _sandboxId,
|
|
99
63
|
namespace: _namespace,
|
|
100
64
|
directory: _directory,
|
|
101
|
-
overlays: _overlays,
|
|
102
|
-
servers: _servers,
|
|
103
65
|
...providerOptions
|
|
104
66
|
} = options || {};
|
|
67
|
+
const optRuntime = options?.runtime;
|
|
105
68
|
const sandboxConfig = {
|
|
106
69
|
name: name || `computesdk-${Date.now()}`,
|
|
107
70
|
keepWarmSeconds: 300,
|
|
108
71
|
...providerOptions
|
|
109
|
-
// Spread provider-specific options
|
|
110
72
|
};
|
|
111
73
|
const timeout = optTimeout ?? config.timeout;
|
|
112
|
-
if (timeout)
|
|
113
|
-
sandboxConfig.keepWarmSeconds = Math.ceil(timeout / 1e3);
|
|
114
|
-
}
|
|
74
|
+
if (timeout) sandboxConfig.keepWarmSeconds = Math.ceil(timeout / 1e3);
|
|
115
75
|
if (optRuntime === "node") {
|
|
116
76
|
sandboxConfig.image = import_beam_js.Image.fromRegistry("node:20-slim");
|
|
117
77
|
}
|
|
@@ -122,28 +82,19 @@ var beam = (0, import_provider.defineProvider)({
|
|
|
122
82
|
const instance = await sandbox.create();
|
|
123
83
|
return { sandbox: instance, sandboxId: instance.containerId };
|
|
124
84
|
} catch (error) {
|
|
125
|
-
if (error instanceof Error) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
);
|
|
130
|
-
}
|
|
85
|
+
if (error instanceof Error && (error.message.includes("unauthorized") || error.message.includes("401"))) {
|
|
86
|
+
throw new Error(
|
|
87
|
+
`Beam authentication failed. Please check your BEAM_TOKEN environment variable. Get your token from https://app.beam.cloud`
|
|
88
|
+
);
|
|
131
89
|
}
|
|
132
90
|
throw new Error(
|
|
133
91
|
`Failed to create Beam sandbox: ${error instanceof Error ? error.message : String(error)}`
|
|
134
92
|
);
|
|
135
93
|
}
|
|
136
94
|
},
|
|
137
|
-
/**
|
|
138
|
-
* Connect to an existing Beam sandbox by ID
|
|
139
|
-
*
|
|
140
|
-
* Uses Sandbox.connect() to reconnect to a running sandbox.
|
|
141
|
-
*/
|
|
142
95
|
getById: async (config, sandboxId) => {
|
|
143
96
|
configureBeamOpts(config);
|
|
144
|
-
if (!import_beam_js.beamOpts.token)
|
|
145
|
-
return null;
|
|
146
|
-
}
|
|
97
|
+
if (!import_beam_js.beamOpts.token) return null;
|
|
147
98
|
try {
|
|
148
99
|
const instance = await import_beam_js.Sandbox.connect(sandboxId);
|
|
149
100
|
return { sandbox: instance, sandboxId: instance.containerId };
|
|
@@ -151,188 +102,80 @@ var beam = (0, import_provider.defineProvider)({
|
|
|
151
102
|
return null;
|
|
152
103
|
}
|
|
153
104
|
},
|
|
154
|
-
|
|
155
|
-
* List all active Beam sandboxes
|
|
156
|
-
*
|
|
157
|
-
* Beam SDK has no sandbox list API; returns empty array.
|
|
158
|
-
*/
|
|
159
|
-
list: async (_config) => {
|
|
160
|
-
return [];
|
|
161
|
-
},
|
|
162
|
-
/**
|
|
163
|
-
* Destroy a Beam sandbox
|
|
164
|
-
*
|
|
165
|
-
* Connects to the sandbox and terminates it.
|
|
166
|
-
*/
|
|
105
|
+
list: async (_config) => [],
|
|
167
106
|
destroy: async (config, sandboxId) => {
|
|
168
107
|
configureBeamOpts(config);
|
|
169
|
-
if (!import_beam_js.beamOpts.token)
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
108
|
+
if (!import_beam_js.beamOpts.token) return;
|
|
172
109
|
try {
|
|
173
110
|
const instance = await import_beam_js.Sandbox.connect(sandboxId);
|
|
174
111
|
await instance.terminate();
|
|
175
112
|
} catch {
|
|
176
113
|
}
|
|
177
114
|
},
|
|
178
|
-
/**
|
|
179
|
-
* Execute code in the sandbox
|
|
180
|
-
*
|
|
181
|
-
* Auto-detects runtime (Python vs Node.js) and executes via sandbox.exec().
|
|
182
|
-
*/
|
|
183
|
-
runCode: async (sandbox, code, runtime) => {
|
|
184
|
-
const effectiveRuntime = runtime || (code.includes("print(") || code.includes("import ") || code.includes("def ") || code.includes("sys.") || code.includes("json.") || code.includes("__") || code.includes('f"') || code.includes("f'") || code.includes("raise ") ? "python" : "node");
|
|
185
|
-
try {
|
|
186
|
-
const command = effectiveRuntime === "python" ? ["python3", "-c", code] : ["node", "-e", code];
|
|
187
|
-
const proc = await sandbox.exec(command);
|
|
188
|
-
await proc.wait();
|
|
189
|
-
const [stdoutStr, stderrStr] = await Promise.all([
|
|
190
|
-
proc.stdout.read(),
|
|
191
|
-
proc.stderr.read()
|
|
192
|
-
]);
|
|
193
|
-
const output = stderrStr ? `${stdoutStr}${stdoutStr && stderrStr ? "\n" : ""}${stderrStr}` : stdoutStr;
|
|
194
|
-
const combinedOutput = `${stdoutStr || ""} ${stderrStr || ""}`;
|
|
195
|
-
if (proc.exitCode !== 0 && isParserFailure(combinedOutput, effectiveRuntime)) {
|
|
196
|
-
throw new Error(`Syntax error: ${(stderrStr || stdoutStr || "").trim()}`);
|
|
197
|
-
}
|
|
198
|
-
if (proc.exitCode !== 0 && !stdoutStr && !stderrStr) {
|
|
199
|
-
throw new Error(`Code execution failed with exit code ${proc.exitCode}`);
|
|
200
|
-
}
|
|
201
|
-
return {
|
|
202
|
-
output,
|
|
203
|
-
exitCode: proc.exitCode,
|
|
204
|
-
language: effectiveRuntime
|
|
205
|
-
};
|
|
206
|
-
} catch (error) {
|
|
207
|
-
if (error instanceof Error && error.message.includes("Syntax error")) {
|
|
208
|
-
throw error;
|
|
209
|
-
}
|
|
210
|
-
throw new Error(
|
|
211
|
-
`Beam execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
|
-
},
|
|
215
|
-
/**
|
|
216
|
-
* Execute a shell command in the sandbox
|
|
217
|
-
*
|
|
218
|
-
* Uses sandbox.exec() with shell command string.
|
|
219
|
-
*/
|
|
220
115
|
runCommand: async (sandbox, command, options) => {
|
|
221
116
|
const startTime = Date.now();
|
|
222
117
|
try {
|
|
223
118
|
let fullCommand = command;
|
|
224
119
|
if (options?.env && Object.keys(options.env).length > 0) {
|
|
225
|
-
const envPrefix = Object.entries(options.env).map(([k, v]) => `${k}="${(0, import_provider.escapeShellArg)(v)}"`).join(" ");
|
|
120
|
+
const envPrefix = Object.entries(options.env).map(([k, v]) => `${k}="${(0, import_provider.escapeShellArg)(String(v))}"`).join(" ");
|
|
226
121
|
fullCommand = `${envPrefix} ${fullCommand}`;
|
|
227
122
|
}
|
|
228
|
-
if (options?.cwd) {
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
if (options?.background) {
|
|
232
|
-
fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;
|
|
233
|
-
}
|
|
123
|
+
if (options?.cwd) fullCommand = `cd "${(0, import_provider.escapeShellArg)(options.cwd)}" && ${fullCommand}`;
|
|
124
|
+
if (options?.background) fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;
|
|
234
125
|
const proc = await sandbox.exec(["sh", "-c", fullCommand]);
|
|
235
126
|
await proc.wait();
|
|
236
|
-
const [stdoutStr, stderrStr] = await Promise.all([
|
|
237
|
-
|
|
238
|
-
proc.stderr.read()
|
|
239
|
-
]);
|
|
240
|
-
return {
|
|
241
|
-
stdout: stdoutStr || "",
|
|
242
|
-
stderr: stderrStr || "",
|
|
243
|
-
exitCode: proc.exitCode || 0,
|
|
244
|
-
durationMs: Date.now() - startTime
|
|
245
|
-
};
|
|
127
|
+
const [stdoutStr, stderrStr] = await Promise.all([proc.stdout.read(), proc.stderr.read()]);
|
|
128
|
+
return { stdout: stdoutStr || "", stderr: stderrStr || "", exitCode: proc.exitCode || 0, durationMs: Date.now() - startTime };
|
|
246
129
|
} catch (error) {
|
|
247
|
-
return {
|
|
248
|
-
stdout: "",
|
|
249
|
-
stderr: error instanceof Error ? error.message : String(error),
|
|
250
|
-
exitCode: 127,
|
|
251
|
-
durationMs: Date.now() - startTime
|
|
252
|
-
};
|
|
130
|
+
return { stdout: "", stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };
|
|
253
131
|
}
|
|
254
132
|
},
|
|
255
|
-
/**
|
|
256
|
-
* Get sandbox information
|
|
257
|
-
*/
|
|
258
133
|
getInfo: async (sandbox) => {
|
|
259
134
|
let runtime = "python";
|
|
260
|
-
const
|
|
261
|
-
if (typeof
|
|
262
|
-
const lower =
|
|
263
|
-
if (lower.includes("node"))
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
runtime = "python";
|
|
274
|
-
}
|
|
275
|
-
} else if (typeof anySandbox.imageName === "string") {
|
|
276
|
-
const imageNameStr = anySandbox.imageName.toLowerCase();
|
|
277
|
-
if (imageNameStr.includes("node")) {
|
|
278
|
-
runtime = "node";
|
|
279
|
-
} else if (imageNameStr.includes("python")) {
|
|
280
|
-
runtime = "python";
|
|
281
|
-
}
|
|
135
|
+
const runtimeHint = sandbox;
|
|
136
|
+
if (typeof runtimeHint.runtime === "string") {
|
|
137
|
+
const lower = runtimeHint.runtime.toLowerCase();
|
|
138
|
+
if (lower.includes("node")) runtime = "node";
|
|
139
|
+
else if (lower.includes("python")) runtime = "python";
|
|
140
|
+
} else if (typeof runtimeHint.image === "string") {
|
|
141
|
+
const imageStr = runtimeHint.image.toLowerCase();
|
|
142
|
+
if (imageStr.includes("node")) runtime = "node";
|
|
143
|
+
else if (imageStr.includes("python")) runtime = "python";
|
|
144
|
+
} else if (typeof runtimeHint.imageName === "string") {
|
|
145
|
+
const imageNameStr = runtimeHint.imageName.toLowerCase();
|
|
146
|
+
if (imageNameStr.includes("node")) runtime = "node";
|
|
147
|
+
else if (imageNameStr.includes("python")) runtime = "python";
|
|
282
148
|
}
|
|
283
149
|
return {
|
|
284
150
|
id: sandbox.containerId,
|
|
285
151
|
provider: "beam",
|
|
286
|
-
runtime,
|
|
287
152
|
status: "running",
|
|
288
153
|
createdAt: /* @__PURE__ */ new Date(),
|
|
289
154
|
timeout: 3e5,
|
|
290
|
-
metadata: {
|
|
291
|
-
containerId: sandbox.containerId
|
|
292
|
-
}
|
|
155
|
+
metadata: { containerId: sandbox.containerId, runtime }
|
|
293
156
|
};
|
|
294
157
|
},
|
|
295
|
-
/**
|
|
296
|
-
* Get public URL for a specific port
|
|
297
|
-
*
|
|
298
|
-
* Uses sandbox.exposePort() to dynamically expose a port.
|
|
299
|
-
*/
|
|
300
158
|
getUrl: async (sandbox, options) => {
|
|
301
159
|
try {
|
|
302
160
|
return await sandbox.exposePort(options.port);
|
|
303
161
|
} catch (error) {
|
|
304
|
-
throw new Error(
|
|
305
|
-
`Failed to get Beam URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`
|
|
306
|
-
);
|
|
162
|
+
throw new Error(`Failed to get Beam URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`);
|
|
307
163
|
}
|
|
308
164
|
},
|
|
309
|
-
/**
|
|
310
|
-
* Filesystem operations
|
|
311
|
-
*
|
|
312
|
-
* Most operations use shell commands via runCommand since Beam's file API
|
|
313
|
-
* is local-path oriented (uploadFile/downloadFile require local filesystem paths).
|
|
314
|
-
* readdir uses the native listFiles API since it returns structured data.
|
|
315
|
-
*/
|
|
316
165
|
filesystem: {
|
|
317
166
|
readFile: async (sandbox, path, runCommand) => {
|
|
318
167
|
const result = await runCommand(sandbox, `cat ${shellEscape(path)}`);
|
|
319
|
-
if (result.exitCode !== 0) {
|
|
320
|
-
throw new Error(`Failed to read file ${path}: ${result.stderr}`);
|
|
321
|
-
}
|
|
168
|
+
if (result.exitCode !== 0) throw new Error(`Failed to read file ${path}: ${result.stderr}`);
|
|
322
169
|
return result.stdout;
|
|
323
170
|
},
|
|
324
171
|
writeFile: async (sandbox, path, content, runCommand) => {
|
|
325
172
|
const b64 = Buffer.from(content).toString("base64");
|
|
326
173
|
const result = await runCommand(sandbox, `echo '${b64}' | base64 -d > ${shellEscape(path)}`);
|
|
327
|
-
if (result.exitCode !== 0) {
|
|
328
|
-
throw new Error(`Failed to write file ${path}: ${result.stderr}`);
|
|
329
|
-
}
|
|
174
|
+
if (result.exitCode !== 0) throw new Error(`Failed to write file ${path}: ${result.stderr}`);
|
|
330
175
|
},
|
|
331
176
|
mkdir: async (sandbox, path, runCommand) => {
|
|
332
177
|
const result = await runCommand(sandbox, `mkdir -p ${shellEscape(path)}`);
|
|
333
|
-
if (result.exitCode !== 0) {
|
|
334
|
-
throw new Error(`Failed to create directory ${path}: ${result.stderr}`);
|
|
335
|
-
}
|
|
178
|
+
if (result.exitCode !== 0) throw new Error(`Failed to create directory ${path}: ${result.stderr}`);
|
|
336
179
|
},
|
|
337
180
|
readdir: async (sandbox, path, _runCommand) => {
|
|
338
181
|
const files = await sandbox.fs.listFiles(path);
|
|
@@ -349,17 +192,10 @@ var beam = (0, import_provider.defineProvider)({
|
|
|
349
192
|
},
|
|
350
193
|
remove: async (sandbox, path, runCommand) => {
|
|
351
194
|
const result = await runCommand(sandbox, `rm -rf ${shellEscape(path)}`);
|
|
352
|
-
if (result.exitCode !== 0) {
|
|
353
|
-
throw new Error(`Failed to remove ${path}: ${result.stderr}`);
|
|
354
|
-
}
|
|
195
|
+
if (result.exitCode !== 0) throw new Error(`Failed to remove ${path}: ${result.stderr}`);
|
|
355
196
|
}
|
|
356
197
|
},
|
|
357
|
-
|
|
358
|
-
* Get the native SandboxInstance for advanced usage
|
|
359
|
-
*/
|
|
360
|
-
getInstance: (sandbox) => {
|
|
361
|
-
return sandbox;
|
|
362
|
-
}
|
|
198
|
+
getInstance: (sandbox) => sandbox
|
|
363
199
|
}
|
|
364
200
|
}
|
|
365
201
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Beam Provider - Factory-based Implementation\n *\n * Containerized sandbox environments using the Beam platform.\n * Beam provides sandboxes with process management, filesystem access,\n * and port exposure capabilities.\n *\n * Features:\n * - Process execution via sandbox.exec()\n * - Code execution in Python, JavaScript\n * - Shell command execution\n * - Filesystem operations (shell-based + native listFiles)\n * - Dynamic port exposure for accessing sandbox services\n */\n\nimport { Sandbox, SandboxInstance, beamOpts, Image } from '@beamcloud/beam-js';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\nimport type {\n CodeResult,\n CommandResult,\n SandboxInfo,\n Runtime,\n CreateSandboxOptions,\n FileEntry,\n RunCommandOptions,\n} from 'computesdk';\n\n/** Type alias for the runCommand function passed to filesystem methods */\ntype RunCommandFn = (sandbox: SandboxInstance, command: string, options?: RunCommandOptions) => Promise<CommandResult>;\n\n/**\n * Beam-specific configuration options\n */\nexport interface BeamConfig {\n /** Beam API token - if not provided, will fallback to BEAM_TOKEN environment variable */\n token?: string;\n /** Beam workspace ID - if not provided, will fallback to BEAM_WORKSPACE_ID environment variable */\n workspaceId?: string;\n /** Gateway URL for custom/staging environments */\n gatewayUrl?: string;\n /** Request timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * Configure the global beamOpts singleton before each SDK call.\n * Beam uses a global config pattern rather than per-call config.\n */\nfunction configureBeamOpts(config: BeamConfig): void {\n beamOpts.token = config.token || (typeof process !== 'undefined' && process.env?.BEAM_TOKEN) || '';\n beamOpts.workspaceId = config.workspaceId || (typeof process !== 'undefined' && process.env?.BEAM_WORKSPACE_ID) || '';\n if (config.gatewayUrl) {\n beamOpts.gatewayUrl = config.gatewayUrl;\n }\n if (config.timeout) {\n (beamOpts as any).timeout = config.timeout;\n }\n}\n\n/**\n * Shell-escape a string using single quotes (POSIX).\n */\nfunction shellEscape(arg: string): string {\n if (arg === '') return \"''\";\n return `'${arg.replace(/'/g, \"'\\\\''\")}'`;\n}\n\n/**\n * Detect Node parser/compile failures while avoiding runtime SyntaxError matches.\n */\nfunction isNodeParserFailure(output: string): boolean {\n const hasSyntaxMarker =\n output.includes('SyntaxError') ||\n output.includes('Unexpected token') ||\n output.includes('Unexpected identifier') ||\n output.includes('Unexpected end of input') ||\n output.includes('Invalid or unexpected token');\n\n const hasCompileContext =\n output.includes('[eval]') ||\n output.includes('makeContextifyScript') ||\n output.includes('compileScript') ||\n output.includes('wrapSafe');\n\n const hasRuntimeSyntaxSignature =\n output.includes('at JSON.parse') ||\n output.includes('JSON.parse (<anonymous>)') ||\n output.includes('in JSON at position');\n\n return hasSyntaxMarker && hasCompileContext && !hasRuntimeSyntaxSignature;\n}\n\n/**\n * Detect Python parser failures (syntax/indentation/tab) emitted by python -c.\n */\nfunction isPythonParserFailure(output: string): boolean {\n const hasSyntaxMarker =\n output.includes('SyntaxError') ||\n output.includes('IndentationError') ||\n output.includes('TabError');\n\n const hasStringFileContext = output.includes('File \"<string>\"');\n const hasRuntimeTraceback = output.includes('Traceback (most recent call last)');\n\n return hasSyntaxMarker && hasStringFileContext && !hasRuntimeTraceback;\n}\n\n/**\n * Detect parser/compile failures that should throw instead of returning CodeResult.\n */\nfunction isParserFailure(output: string, runtime: Runtime): boolean {\n if (!output.trim()) return false;\n\n if (runtime === 'node') {\n return isNodeParserFailure(output);\n }\n\n if (runtime === 'python') {\n return isPythonParserFailure(output);\n }\n\n return false;\n}\n\n/**\n * Create a Beam provider instance using the factory pattern\n *\n * Beam provides containerized sandbox environments with:\n * - Process management (exec, runCode)\n * - Filesystem access\n * - Dynamic port exposure\n * - Snapshot and image creation capabilities\n */\nexport const beam = defineProvider<SandboxInstance, BeamConfig>({\n name: 'beam',\n methods: {\n sandbox: {\n /**\n * Create a new Beam sandbox\n *\n * Uses Sandbox class from @beamcloud/beam-js to provision a container.\n */\n create: async (config: BeamConfig, options?: CreateSandboxOptions) => {\n configureBeamOpts(config);\n\n if (!beamOpts.token) {\n throw new Error(\n `Missing Beam token. Provide 'token' in config or set BEAM_TOKEN environment variable. Get your token from https://app.beam.cloud`\n );\n }\n\n if (!beamOpts.workspaceId) {\n throw new Error(\n `Missing Beam workspace ID. Provide 'workspaceId' in config or set BEAM_WORKSPACE_ID environment variable.`\n );\n }\n try {\n if (options?.sandboxId) {\n const instance = await Sandbox.connect(options.sandboxId);\n return { sandbox: instance, sandboxId: instance.containerId };\n }\n\n // Destructure known ComputeSDK fields, collect the rest for passthrough\n const {\n runtime: optRuntime,\n timeout: optTimeout,\n envs,\n name,\n metadata: _metadata,\n templateId: _templateId,\n snapshotId: _snapshotId,\n sandboxId: _sandboxId,\n namespace: _namespace,\n directory: _directory,\n overlays: _overlays,\n servers: _servers,\n ...providerOptions\n } = options || {};\n\n const sandboxConfig: any = {\n name: name || `computesdk-${Date.now()}`,\n keepWarmSeconds: 300,\n ...providerOptions, // Spread provider-specific options\n };\n\n // options.timeout takes precedence over config.timeout\n const timeout = optTimeout ?? config.timeout;\n if (timeout) {\n sandboxConfig.keepWarmSeconds = Math.ceil(timeout / 1000);\n }\n\n if (optRuntime === 'node') {\n sandboxConfig.image = Image.fromRegistry('node:20-slim');\n }\n\n if (envs) {\n sandboxConfig.envVars = Object.entries(envs).map(([name, value]) => `${name}=${value}`);\n }\n\n const sandbox = new Sandbox(sandboxConfig);\n const instance = await sandbox.create();\n return { sandbox: instance, sandboxId: instance.containerId };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('401')) {\n throw new Error(\n `Beam authentication failed. Please check your BEAM_TOKEN environment variable. Get your token from https://app.beam.cloud`\n );\n }\n }\n throw new Error(\n `Failed to create Beam sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n /**\n * Connect to an existing Beam sandbox by ID\n *\n * Uses Sandbox.connect() to reconnect to a running sandbox.\n */\n getById: async (config: BeamConfig, sandboxId: string) => {\n configureBeamOpts(config);\n\n if (!beamOpts.token) {\n return null;\n }\n\n try {\n const instance = await Sandbox.connect(sandboxId);\n return { sandbox: instance, sandboxId: instance.containerId };\n } catch {\n return null;\n }\n },\n\n /**\n * List all active Beam sandboxes\n *\n * Beam SDK has no sandbox list API; returns empty array.\n */\n list: async (_config: BeamConfig) => {\n return [];\n },\n\n /**\n * Destroy a Beam sandbox\n *\n * Connects to the sandbox and terminates it.\n */\n destroy: async (config: BeamConfig, sandboxId: string) => {\n configureBeamOpts(config);\n\n if (!beamOpts.token) {\n return;\n }\n\n try {\n const instance = await Sandbox.connect(sandboxId);\n await instance.terminate();\n } catch {\n // Sandbox might already be destroyed\n }\n },\n\n /**\n * Execute code in the sandbox\n *\n * Auto-detects runtime (Python vs Node.js) and executes via sandbox.exec().\n */\n runCode: async (sandbox: SandboxInstance, code: string, runtime?: Runtime): Promise<CodeResult> => {\n const effectiveRuntime = runtime || (\n code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')\n ? 'python'\n : 'node'\n );\n\n try {\n const command = effectiveRuntime === 'python'\n ? ['python3', '-c', code]\n : ['node', '-e', code];\n\n const proc = await sandbox.exec(command);\n await proc.wait();\n const [stdoutStr, stderrStr] = await Promise.all([\n proc.stdout.read(),\n proc.stderr.read(),\n ]);\n\n const output = stderrStr\n ? `${stdoutStr}${stdoutStr && stderrStr ? '\\n' : ''}${stderrStr}`\n : stdoutStr;\n\n const combinedOutput = `${stdoutStr || ''} ${stderrStr || ''}`;\n\n if (proc.exitCode !== 0 && isParserFailure(combinedOutput, effectiveRuntime)) {\n throw new Error(`Syntax error: ${(stderrStr || stdoutStr || '').trim()}`);\n }\n\n if (proc.exitCode !== 0 && !stdoutStr && !stderrStr) {\n throw new Error(`Code execution failed with exit code ${proc.exitCode}`);\n }\n\n return {\n output,\n exitCode: proc.exitCode,\n language: effectiveRuntime,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `Beam execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n /**\n * Execute a shell command in the sandbox\n *\n * Uses sandbox.exec() with shell command string.\n */\n runCommand: async (sandbox: SandboxInstance, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n try {\n let fullCommand = command;\n\n if (options?.env && Object.keys(options.env).length > 0) {\n const envPrefix = Object.entries(options.env)\n .map(([k, v]: [string, string]) => `${k}=\"${escapeShellArg(v)}\"`)\n .join(' ');\n fullCommand = `${envPrefix} ${fullCommand}`;\n }\n\n if (options?.cwd) {\n fullCommand = `cd \"${escapeShellArg(options.cwd)}\" && ${fullCommand}`;\n }\n\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\n\n // Wrap in sh -c to get shell parsing (pipes, redirects, etc.)\n const proc = await sandbox.exec(['sh', '-c', fullCommand]);\n await proc.wait();\n const [stdoutStr, stderrStr] = await Promise.all([\n proc.stdout.read(),\n proc.stderr.read(),\n ]);\n\n return {\n stdout: stdoutStr || '',\n stderr: stderrStr || '',\n exitCode: proc.exitCode || 0,\n durationMs: Date.now() - startTime,\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime,\n };\n }\n },\n\n /**\n * Get sandbox information\n */\n getInfo: async (sandbox: SandboxInstance): Promise<SandboxInfo> => {\n // Derive runtime from sandbox instance if available; otherwise default to 'python'\n let runtime: Runtime = 'python';\n const anySandbox = sandbox as any;\n\n if (typeof anySandbox.runtime === 'string') {\n const lower = anySandbox.runtime.toLowerCase();\n if (lower.includes('node')) {\n runtime = 'node';\n } else if (lower.includes('python')) {\n runtime = 'python';\n }\n } else if (typeof anySandbox.image === 'string') {\n const imageStr = anySandbox.image.toLowerCase();\n if (imageStr.includes('node')) {\n runtime = 'node';\n } else if (imageStr.includes('python')) {\n runtime = 'python';\n }\n } else if (typeof anySandbox.imageName === 'string') {\n const imageNameStr = anySandbox.imageName.toLowerCase();\n if (imageNameStr.includes('node')) {\n runtime = 'node';\n } else if (imageNameStr.includes('python')) {\n runtime = 'python';\n }\n }\n\n return {\n id: sandbox.containerId,\n provider: 'beam',\n runtime,\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n containerId: sandbox.containerId,\n },\n };\n },\n\n /**\n * Get public URL for a specific port\n *\n * Uses sandbox.exposePort() to dynamically expose a port.\n */\n getUrl: async (sandbox: SandboxInstance, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n return await sandbox.exposePort(options.port);\n } catch (error) {\n throw new Error(\n `Failed to get Beam URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n /**\n * Filesystem operations\n *\n * Most operations use shell commands via runCommand since Beam's file API\n * is local-path oriented (uploadFile/downloadFile require local filesystem paths).\n * readdir uses the native listFiles API since it returns structured data.\n */\n filesystem: {\n readFile: async (sandbox: SandboxInstance, path: string, runCommand: RunCommandFn): Promise<string> => {\n const result = await runCommand(sandbox, `cat ${shellEscape(path)}`);\n if (result.exitCode !== 0) {\n throw new Error(`Failed to read file ${path}: ${result.stderr}`);\n }\n return result.stdout;\n },\n\n writeFile: async (sandbox: SandboxInstance, path: string, content: string, runCommand: RunCommandFn): Promise<void> => {\n const b64 = Buffer.from(content).toString('base64');\n const result = await runCommand(sandbox, `echo '${b64}' | base64 -d > ${shellEscape(path)}`);\n if (result.exitCode !== 0) {\n throw new Error(`Failed to write file ${path}: ${result.stderr}`);\n }\n },\n\n mkdir: async (sandbox: SandboxInstance, path: string, runCommand: RunCommandFn): Promise<void> => {\n const result = await runCommand(sandbox, `mkdir -p ${shellEscape(path)}`);\n if (result.exitCode !== 0) {\n throw new Error(`Failed to create directory ${path}: ${result.stderr}`);\n }\n },\n\n readdir: async (sandbox: SandboxInstance, path: string, _runCommand: RunCommandFn): Promise<FileEntry[]> => {\n const files = await sandbox.fs.listFiles(path);\n return files.map((file: any) => ({\n name: file.name,\n type: file.isDir ? 'directory' as const : 'file' as const,\n size: Number(file.size) || 0,\n modified: file.modTime ? new Date(file.modTime * 1000) : new Date(),\n }));\n },\n\n exists: async (sandbox: SandboxInstance, path: string, runCommand: RunCommandFn): Promise<boolean> => {\n const result = await runCommand(sandbox, `test -f ${shellEscape(path)} || test -d ${shellEscape(path)}`);\n return result.exitCode === 0;\n },\n\n remove: async (sandbox: SandboxInstance, path: string, runCommand: RunCommandFn): Promise<void> => {\n const result = await runCommand(sandbox, `rm -rf ${shellEscape(path)}`);\n if (result.exitCode !== 0) {\n throw new Error(`Failed to remove ${path}: ${result.stderr}`);\n }\n },\n },\n\n /**\n * Get the native SandboxInstance for advanced usage\n */\n getInstance: (sandbox: SandboxInstance): SandboxInstance => {\n return sandbox;\n },\n },\n },\n});\n\n// Export Beam sandbox type for explicit typing\nexport type { SandboxInstance as BeamSandboxInstance } from '@beamcloud/beam-js';\n"],"mappings":"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","names":["instance","name"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Beam Provider - Factory-based Implementation\n *\n * Containerized sandbox environments using the Beam platform.\n * Beam provides sandboxes with process management, filesystem access,\n * and port exposure capabilities.\n */\n\nimport { Sandbox, SandboxInstance, beamOpts, Image } from '@beamcloud/beam-js';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\nimport type {\n CommandResult,\n SandboxInfo,\n CreateSandboxOptions,\n FileEntry,\n RunCommandOptions,\n} from 'computesdk';\n\ntype RunCommandFn = (sandbox: SandboxInstance, command: string, options?: RunCommandOptions) => Promise<CommandResult>;\n\nexport interface BeamConfig {\n token?: string;\n workspaceId?: string;\n gatewayUrl?: string;\n timeout?: number;\n}\n\nfunction configureBeamOpts(config: BeamConfig): void {\n beamOpts.token = config.token || (typeof process !== 'undefined' && process.env?.BEAM_TOKEN) || '';\n beamOpts.workspaceId = config.workspaceId || (typeof process !== 'undefined' && process.env?.BEAM_WORKSPACE_ID) || '';\n if (config.gatewayUrl) beamOpts.gatewayUrl = config.gatewayUrl;\n if (config.timeout) (beamOpts as any).timeout = config.timeout;\n}\n\nfunction shellEscape(arg: string): string {\n if (arg === '') return \"''\";\n return `'${arg.replace(/'/g, \"'\\\\''\")}'`;\n}\n\nfunction isNodeParserFailure(output: string): boolean {\n const hasSyntaxMarker =\n output.includes('SyntaxError') ||\n output.includes('Unexpected token') ||\n output.includes('Unexpected identifier') ||\n output.includes('Unexpected end of input') ||\n output.includes('Invalid or unexpected token');\n\n const hasCompileContext =\n output.includes('[eval]') ||\n output.includes('makeContextifyScript') ||\n output.includes('compileScript') ||\n output.includes('wrapSafe');\n\n const hasRuntimeSyntaxSignature =\n output.includes('at JSON.parse') ||\n output.includes('JSON.parse (<anonymous>)') ||\n output.includes('in JSON at position');\n\n return hasSyntaxMarker && hasCompileContext && !hasRuntimeSyntaxSignature;\n}\n\nfunction isPythonParserFailure(output: string): boolean {\n const hasSyntaxMarker =\n output.includes('SyntaxError') ||\n output.includes('IndentationError') ||\n output.includes('TabError');\n\n const hasStringFileContext = output.includes('File \"<string>\"');\n const hasRuntimeTraceback = output.includes('Traceback (most recent call last)');\n\n return hasSyntaxMarker && hasStringFileContext && !hasRuntimeTraceback;\n}\n\nfunction isParserFailure(output: string, runtime: string): boolean {\n if (!output.trim()) return false;\n if (runtime === 'node') return isNodeParserFailure(output);\n if (runtime === 'python') return isPythonParserFailure(output);\n return false;\n}\n\nexport const beam = defineProvider<SandboxInstance, BeamConfig>({\n name: 'beam',\n methods: {\n sandbox: {\n create: async (config: BeamConfig, options?: CreateSandboxOptions) => {\n configureBeamOpts(config);\n\n if (!beamOpts.token) {\n throw new Error(\n `Missing Beam token. Provide 'token' in config or set BEAM_TOKEN environment variable. Get your token from https://app.beam.cloud`\n );\n }\n\n if (!beamOpts.workspaceId) {\n throw new Error(\n `Missing Beam workspace ID. Provide 'workspaceId' in config or set BEAM_WORKSPACE_ID environment variable.`\n );\n }\n\n try {\n const {\n timeout: optTimeout,\n envs,\n name,\n metadata: _metadata,\n templateId: _templateId,\n snapshotId: _snapshotId,\n sandboxId: _sandboxId,\n namespace: _namespace,\n directory: _directory,\n ...providerOptions\n } = options || {};\n\n const optRuntime = (options as any)?.runtime as string | undefined;\n\n const sandboxConfig: any = {\n name: name || `computesdk-${Date.now()}`,\n keepWarmSeconds: 300,\n ...providerOptions,\n };\n\n const timeout = optTimeout ?? config.timeout;\n if (timeout) sandboxConfig.keepWarmSeconds = Math.ceil(timeout / 1000);\n\n if (optRuntime === 'node') {\n sandboxConfig.image = Image.fromRegistry('node:20-slim');\n }\n\n if (envs) {\n sandboxConfig.envVars = Object.entries(envs).map(([name, value]) => `${name}=${value}`);\n }\n\n const sandbox = new Sandbox(sandboxConfig);\n const instance = await sandbox.create();\n return { sandbox: instance, sandboxId: instance.containerId };\n } catch (error) {\n if (error instanceof Error && (error.message.includes('unauthorized') || error.message.includes('401'))) {\n throw new Error(\n `Beam authentication failed. Please check your BEAM_TOKEN environment variable. Get your token from https://app.beam.cloud`\n );\n }\n throw new Error(\n `Failed to create Beam sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: BeamConfig, sandboxId: string) => {\n configureBeamOpts(config);\n if (!beamOpts.token) return null;\n try {\n const instance = await Sandbox.connect(sandboxId);\n return { sandbox: instance, sandboxId: instance.containerId };\n } catch { return null; }\n },\n\n list: async (_config: BeamConfig) => [],\n\n destroy: async (config: BeamConfig, sandboxId: string) => {\n configureBeamOpts(config);\n if (!beamOpts.token) return;\n try {\n const instance = await Sandbox.connect(sandboxId);\n await instance.terminate();\n } catch { /* Sandbox might already be destroyed */ }\n },\n\n runCommand: async (sandbox: SandboxInstance, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n try {\n let fullCommand = command;\n if (options?.env && Object.keys(options.env).length > 0) {\n const envPrefix = Object.entries(options.env).map(([k, v]) => `${k}=\"${escapeShellArg(String(v))}\"`).join(' ');\n fullCommand = `${envPrefix} ${fullCommand}`;\n }\n if (options?.cwd) fullCommand = `cd \"${escapeShellArg(options.cwd)}\" && ${fullCommand}`;\n if (options?.background) fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n\n const proc = await sandbox.exec(['sh', '-c', fullCommand]);\n await proc.wait();\n const [stdoutStr, stderrStr] = await Promise.all([proc.stdout.read(), proc.stderr.read()]);\n return { stdout: stdoutStr || '', stderr: stderrStr || '', exitCode: proc.exitCode || 0, durationMs: Date.now() - startTime };\n } catch (error) {\n return { stdout: '', stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };\n }\n },\n\n getInfo: async (sandbox: SandboxInstance): Promise<SandboxInfo> => {\n let runtime = 'python';\n const runtimeHint = sandbox as SandboxInstance & { runtime?: unknown; image?: unknown; imageName?: unknown };\n if (typeof runtimeHint.runtime === 'string') {\n const lower = runtimeHint.runtime.toLowerCase();\n if (lower.includes('node')) runtime = 'node';\n else if (lower.includes('python')) runtime = 'python';\n } else if (typeof runtimeHint.image === 'string') {\n const imageStr = runtimeHint.image.toLowerCase();\n if (imageStr.includes('node')) runtime = 'node';\n else if (imageStr.includes('python')) runtime = 'python';\n } else if (typeof runtimeHint.imageName === 'string') {\n const imageNameStr = runtimeHint.imageName.toLowerCase();\n if (imageNameStr.includes('node')) runtime = 'node';\n else if (imageNameStr.includes('python')) runtime = 'python';\n }\n return {\n id: sandbox.containerId,\n provider: 'beam',\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: { containerId: sandbox.containerId, runtime },\n };\n },\n\n getUrl: async (sandbox: SandboxInstance, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n return await sandbox.exposePort(options.port);\n } catch (error) {\n throw new Error(`Failed to get Beam URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n filesystem: {\n readFile: async (sandbox: SandboxInstance, path: string, runCommand: RunCommandFn): Promise<string> => {\n const result = await runCommand(sandbox, `cat ${shellEscape(path)}`);\n if (result.exitCode !== 0) throw new Error(`Failed to read file ${path}: ${result.stderr}`);\n return result.stdout;\n },\n writeFile: async (sandbox: SandboxInstance, path: string, content: string, runCommand: RunCommandFn): Promise<void> => {\n const b64 = Buffer.from(content).toString('base64');\n const result = await runCommand(sandbox, `echo '${b64}' | base64 -d > ${shellEscape(path)}`);\n if (result.exitCode !== 0) throw new Error(`Failed to write file ${path}: ${result.stderr}`);\n },\n mkdir: async (sandbox: SandboxInstance, path: string, runCommand: RunCommandFn): Promise<void> => {\n const result = await runCommand(sandbox, `mkdir -p ${shellEscape(path)}`);\n if (result.exitCode !== 0) throw new Error(`Failed to create directory ${path}: ${result.stderr}`);\n },\n readdir: async (sandbox: SandboxInstance, path: string, _runCommand: RunCommandFn): Promise<FileEntry[]> => {\n const files = await sandbox.fs.listFiles(path);\n return files.map((file: any) => ({\n name: file.name,\n type: file.isDir ? 'directory' as const : 'file' as const,\n size: Number(file.size) || 0,\n modified: file.modTime ? new Date(file.modTime * 1000) : new Date(),\n }));\n },\n exists: async (sandbox: SandboxInstance, path: string, runCommand: RunCommandFn): Promise<boolean> => {\n const result = await runCommand(sandbox, `test -f ${shellEscape(path)} || test -d ${shellEscape(path)}`);\n return result.exitCode === 0;\n },\n remove: async (sandbox: SandboxInstance, path: string, runCommand: RunCommandFn): Promise<void> => {\n const result = await runCommand(sandbox, `rm -rf ${shellEscape(path)}`);\n if (result.exitCode !== 0) throw new Error(`Failed to remove ${path}: ${result.stderr}`);\n },\n },\n\n getInstance: (sandbox: SandboxInstance): SandboxInstance => sandbox,\n },\n },\n});\n\nexport type { SandboxInstance as BeamSandboxInstance } from '@beamcloud/beam-js';\n"],"mappings":"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","names":["name"]}
|
package/dist/index.mjs
CHANGED
|
@@ -4,48 +4,17 @@ import { defineProvider, escapeShellArg } from "@computesdk/provider";
|
|
|
4
4
|
function configureBeamOpts(config) {
|
|
5
5
|
beamOpts.token = config.token || typeof process !== "undefined" && process.env?.BEAM_TOKEN || "";
|
|
6
6
|
beamOpts.workspaceId = config.workspaceId || typeof process !== "undefined" && process.env?.BEAM_WORKSPACE_ID || "";
|
|
7
|
-
if (config.gatewayUrl)
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
if (config.timeout) {
|
|
11
|
-
beamOpts.timeout = config.timeout;
|
|
12
|
-
}
|
|
7
|
+
if (config.gatewayUrl) beamOpts.gatewayUrl = config.gatewayUrl;
|
|
8
|
+
if (config.timeout) beamOpts.timeout = config.timeout;
|
|
13
9
|
}
|
|
14
10
|
function shellEscape(arg) {
|
|
15
11
|
if (arg === "") return "''";
|
|
16
12
|
return `'${arg.replace(/'/g, "'\\''")}'`;
|
|
17
13
|
}
|
|
18
|
-
function isNodeParserFailure(output) {
|
|
19
|
-
const hasSyntaxMarker = output.includes("SyntaxError") || output.includes("Unexpected token") || output.includes("Unexpected identifier") || output.includes("Unexpected end of input") || output.includes("Invalid or unexpected token");
|
|
20
|
-
const hasCompileContext = output.includes("[eval]") || output.includes("makeContextifyScript") || output.includes("compileScript") || output.includes("wrapSafe");
|
|
21
|
-
const hasRuntimeSyntaxSignature = output.includes("at JSON.parse") || output.includes("JSON.parse (<anonymous>)") || output.includes("in JSON at position");
|
|
22
|
-
return hasSyntaxMarker && hasCompileContext && !hasRuntimeSyntaxSignature;
|
|
23
|
-
}
|
|
24
|
-
function isPythonParserFailure(output) {
|
|
25
|
-
const hasSyntaxMarker = output.includes("SyntaxError") || output.includes("IndentationError") || output.includes("TabError");
|
|
26
|
-
const hasStringFileContext = output.includes('File "<string>"');
|
|
27
|
-
const hasRuntimeTraceback = output.includes("Traceback (most recent call last)");
|
|
28
|
-
return hasSyntaxMarker && hasStringFileContext && !hasRuntimeTraceback;
|
|
29
|
-
}
|
|
30
|
-
function isParserFailure(output, runtime) {
|
|
31
|
-
if (!output.trim()) return false;
|
|
32
|
-
if (runtime === "node") {
|
|
33
|
-
return isNodeParserFailure(output);
|
|
34
|
-
}
|
|
35
|
-
if (runtime === "python") {
|
|
36
|
-
return isPythonParserFailure(output);
|
|
37
|
-
}
|
|
38
|
-
return false;
|
|
39
|
-
}
|
|
40
14
|
var beam = defineProvider({
|
|
41
15
|
name: "beam",
|
|
42
16
|
methods: {
|
|
43
17
|
sandbox: {
|
|
44
|
-
/**
|
|
45
|
-
* Create a new Beam sandbox
|
|
46
|
-
*
|
|
47
|
-
* Uses Sandbox class from @beamcloud/beam-js to provision a container.
|
|
48
|
-
*/
|
|
49
18
|
create: async (config, options) => {
|
|
50
19
|
configureBeamOpts(config);
|
|
51
20
|
if (!beamOpts.token) {
|
|
@@ -59,12 +28,7 @@ var beam = defineProvider({
|
|
|
59
28
|
);
|
|
60
29
|
}
|
|
61
30
|
try {
|
|
62
|
-
if (options?.sandboxId) {
|
|
63
|
-
const instance2 = await Sandbox.connect(options.sandboxId);
|
|
64
|
-
return { sandbox: instance2, sandboxId: instance2.containerId };
|
|
65
|
-
}
|
|
66
31
|
const {
|
|
67
|
-
runtime: optRuntime,
|
|
68
32
|
timeout: optTimeout,
|
|
69
33
|
envs,
|
|
70
34
|
name,
|
|
@@ -74,20 +38,16 @@ var beam = defineProvider({
|
|
|
74
38
|
sandboxId: _sandboxId,
|
|
75
39
|
namespace: _namespace,
|
|
76
40
|
directory: _directory,
|
|
77
|
-
overlays: _overlays,
|
|
78
|
-
servers: _servers,
|
|
79
41
|
...providerOptions
|
|
80
42
|
} = options || {};
|
|
43
|
+
const optRuntime = options?.runtime;
|
|
81
44
|
const sandboxConfig = {
|
|
82
45
|
name: name || `computesdk-${Date.now()}`,
|
|
83
46
|
keepWarmSeconds: 300,
|
|
84
47
|
...providerOptions
|
|
85
|
-
// Spread provider-specific options
|
|
86
48
|
};
|
|
87
49
|
const timeout = optTimeout ?? config.timeout;
|
|
88
|
-
if (timeout)
|
|
89
|
-
sandboxConfig.keepWarmSeconds = Math.ceil(timeout / 1e3);
|
|
90
|
-
}
|
|
50
|
+
if (timeout) sandboxConfig.keepWarmSeconds = Math.ceil(timeout / 1e3);
|
|
91
51
|
if (optRuntime === "node") {
|
|
92
52
|
sandboxConfig.image = Image.fromRegistry("node:20-slim");
|
|
93
53
|
}
|
|
@@ -98,28 +58,19 @@ var beam = defineProvider({
|
|
|
98
58
|
const instance = await sandbox.create();
|
|
99
59
|
return { sandbox: instance, sandboxId: instance.containerId };
|
|
100
60
|
} catch (error) {
|
|
101
|
-
if (error instanceof Error) {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
);
|
|
106
|
-
}
|
|
61
|
+
if (error instanceof Error && (error.message.includes("unauthorized") || error.message.includes("401"))) {
|
|
62
|
+
throw new Error(
|
|
63
|
+
`Beam authentication failed. Please check your BEAM_TOKEN environment variable. Get your token from https://app.beam.cloud`
|
|
64
|
+
);
|
|
107
65
|
}
|
|
108
66
|
throw new Error(
|
|
109
67
|
`Failed to create Beam sandbox: ${error instanceof Error ? error.message : String(error)}`
|
|
110
68
|
);
|
|
111
69
|
}
|
|
112
70
|
},
|
|
113
|
-
/**
|
|
114
|
-
* Connect to an existing Beam sandbox by ID
|
|
115
|
-
*
|
|
116
|
-
* Uses Sandbox.connect() to reconnect to a running sandbox.
|
|
117
|
-
*/
|
|
118
71
|
getById: async (config, sandboxId) => {
|
|
119
72
|
configureBeamOpts(config);
|
|
120
|
-
if (!beamOpts.token)
|
|
121
|
-
return null;
|
|
122
|
-
}
|
|
73
|
+
if (!beamOpts.token) return null;
|
|
123
74
|
try {
|
|
124
75
|
const instance = await Sandbox.connect(sandboxId);
|
|
125
76
|
return { sandbox: instance, sandboxId: instance.containerId };
|
|
@@ -127,188 +78,80 @@ var beam = defineProvider({
|
|
|
127
78
|
return null;
|
|
128
79
|
}
|
|
129
80
|
},
|
|
130
|
-
|
|
131
|
-
* List all active Beam sandboxes
|
|
132
|
-
*
|
|
133
|
-
* Beam SDK has no sandbox list API; returns empty array.
|
|
134
|
-
*/
|
|
135
|
-
list: async (_config) => {
|
|
136
|
-
return [];
|
|
137
|
-
},
|
|
138
|
-
/**
|
|
139
|
-
* Destroy a Beam sandbox
|
|
140
|
-
*
|
|
141
|
-
* Connects to the sandbox and terminates it.
|
|
142
|
-
*/
|
|
81
|
+
list: async (_config) => [],
|
|
143
82
|
destroy: async (config, sandboxId) => {
|
|
144
83
|
configureBeamOpts(config);
|
|
145
|
-
if (!beamOpts.token)
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
84
|
+
if (!beamOpts.token) return;
|
|
148
85
|
try {
|
|
149
86
|
const instance = await Sandbox.connect(sandboxId);
|
|
150
87
|
await instance.terminate();
|
|
151
88
|
} catch {
|
|
152
89
|
}
|
|
153
90
|
},
|
|
154
|
-
/**
|
|
155
|
-
* Execute code in the sandbox
|
|
156
|
-
*
|
|
157
|
-
* Auto-detects runtime (Python vs Node.js) and executes via sandbox.exec().
|
|
158
|
-
*/
|
|
159
|
-
runCode: async (sandbox, code, runtime) => {
|
|
160
|
-
const effectiveRuntime = runtime || (code.includes("print(") || code.includes("import ") || code.includes("def ") || code.includes("sys.") || code.includes("json.") || code.includes("__") || code.includes('f"') || code.includes("f'") || code.includes("raise ") ? "python" : "node");
|
|
161
|
-
try {
|
|
162
|
-
const command = effectiveRuntime === "python" ? ["python3", "-c", code] : ["node", "-e", code];
|
|
163
|
-
const proc = await sandbox.exec(command);
|
|
164
|
-
await proc.wait();
|
|
165
|
-
const [stdoutStr, stderrStr] = await Promise.all([
|
|
166
|
-
proc.stdout.read(),
|
|
167
|
-
proc.stderr.read()
|
|
168
|
-
]);
|
|
169
|
-
const output = stderrStr ? `${stdoutStr}${stdoutStr && stderrStr ? "\n" : ""}${stderrStr}` : stdoutStr;
|
|
170
|
-
const combinedOutput = `${stdoutStr || ""} ${stderrStr || ""}`;
|
|
171
|
-
if (proc.exitCode !== 0 && isParserFailure(combinedOutput, effectiveRuntime)) {
|
|
172
|
-
throw new Error(`Syntax error: ${(stderrStr || stdoutStr || "").trim()}`);
|
|
173
|
-
}
|
|
174
|
-
if (proc.exitCode !== 0 && !stdoutStr && !stderrStr) {
|
|
175
|
-
throw new Error(`Code execution failed with exit code ${proc.exitCode}`);
|
|
176
|
-
}
|
|
177
|
-
return {
|
|
178
|
-
output,
|
|
179
|
-
exitCode: proc.exitCode,
|
|
180
|
-
language: effectiveRuntime
|
|
181
|
-
};
|
|
182
|
-
} catch (error) {
|
|
183
|
-
if (error instanceof Error && error.message.includes("Syntax error")) {
|
|
184
|
-
throw error;
|
|
185
|
-
}
|
|
186
|
-
throw new Error(
|
|
187
|
-
`Beam execution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
},
|
|
191
|
-
/**
|
|
192
|
-
* Execute a shell command in the sandbox
|
|
193
|
-
*
|
|
194
|
-
* Uses sandbox.exec() with shell command string.
|
|
195
|
-
*/
|
|
196
91
|
runCommand: async (sandbox, command, options) => {
|
|
197
92
|
const startTime = Date.now();
|
|
198
93
|
try {
|
|
199
94
|
let fullCommand = command;
|
|
200
95
|
if (options?.env && Object.keys(options.env).length > 0) {
|
|
201
|
-
const envPrefix = Object.entries(options.env).map(([k, v]) => `${k}="${escapeShellArg(v)}"`).join(" ");
|
|
96
|
+
const envPrefix = Object.entries(options.env).map(([k, v]) => `${k}="${escapeShellArg(String(v))}"`).join(" ");
|
|
202
97
|
fullCommand = `${envPrefix} ${fullCommand}`;
|
|
203
98
|
}
|
|
204
|
-
if (options?.cwd) {
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
if (options?.background) {
|
|
208
|
-
fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;
|
|
209
|
-
}
|
|
99
|
+
if (options?.cwd) fullCommand = `cd "${escapeShellArg(options.cwd)}" && ${fullCommand}`;
|
|
100
|
+
if (options?.background) fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;
|
|
210
101
|
const proc = await sandbox.exec(["sh", "-c", fullCommand]);
|
|
211
102
|
await proc.wait();
|
|
212
|
-
const [stdoutStr, stderrStr] = await Promise.all([
|
|
213
|
-
|
|
214
|
-
proc.stderr.read()
|
|
215
|
-
]);
|
|
216
|
-
return {
|
|
217
|
-
stdout: stdoutStr || "",
|
|
218
|
-
stderr: stderrStr || "",
|
|
219
|
-
exitCode: proc.exitCode || 0,
|
|
220
|
-
durationMs: Date.now() - startTime
|
|
221
|
-
};
|
|
103
|
+
const [stdoutStr, stderrStr] = await Promise.all([proc.stdout.read(), proc.stderr.read()]);
|
|
104
|
+
return { stdout: stdoutStr || "", stderr: stderrStr || "", exitCode: proc.exitCode || 0, durationMs: Date.now() - startTime };
|
|
222
105
|
} catch (error) {
|
|
223
|
-
return {
|
|
224
|
-
stdout: "",
|
|
225
|
-
stderr: error instanceof Error ? error.message : String(error),
|
|
226
|
-
exitCode: 127,
|
|
227
|
-
durationMs: Date.now() - startTime
|
|
228
|
-
};
|
|
106
|
+
return { stdout: "", stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };
|
|
229
107
|
}
|
|
230
108
|
},
|
|
231
|
-
/**
|
|
232
|
-
* Get sandbox information
|
|
233
|
-
*/
|
|
234
109
|
getInfo: async (sandbox) => {
|
|
235
110
|
let runtime = "python";
|
|
236
|
-
const
|
|
237
|
-
if (typeof
|
|
238
|
-
const lower =
|
|
239
|
-
if (lower.includes("node"))
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
runtime = "python";
|
|
250
|
-
}
|
|
251
|
-
} else if (typeof anySandbox.imageName === "string") {
|
|
252
|
-
const imageNameStr = anySandbox.imageName.toLowerCase();
|
|
253
|
-
if (imageNameStr.includes("node")) {
|
|
254
|
-
runtime = "node";
|
|
255
|
-
} else if (imageNameStr.includes("python")) {
|
|
256
|
-
runtime = "python";
|
|
257
|
-
}
|
|
111
|
+
const runtimeHint = sandbox;
|
|
112
|
+
if (typeof runtimeHint.runtime === "string") {
|
|
113
|
+
const lower = runtimeHint.runtime.toLowerCase();
|
|
114
|
+
if (lower.includes("node")) runtime = "node";
|
|
115
|
+
else if (lower.includes("python")) runtime = "python";
|
|
116
|
+
} else if (typeof runtimeHint.image === "string") {
|
|
117
|
+
const imageStr = runtimeHint.image.toLowerCase();
|
|
118
|
+
if (imageStr.includes("node")) runtime = "node";
|
|
119
|
+
else if (imageStr.includes("python")) runtime = "python";
|
|
120
|
+
} else if (typeof runtimeHint.imageName === "string") {
|
|
121
|
+
const imageNameStr = runtimeHint.imageName.toLowerCase();
|
|
122
|
+
if (imageNameStr.includes("node")) runtime = "node";
|
|
123
|
+
else if (imageNameStr.includes("python")) runtime = "python";
|
|
258
124
|
}
|
|
259
125
|
return {
|
|
260
126
|
id: sandbox.containerId,
|
|
261
127
|
provider: "beam",
|
|
262
|
-
runtime,
|
|
263
128
|
status: "running",
|
|
264
129
|
createdAt: /* @__PURE__ */ new Date(),
|
|
265
130
|
timeout: 3e5,
|
|
266
|
-
metadata: {
|
|
267
|
-
containerId: sandbox.containerId
|
|
268
|
-
}
|
|
131
|
+
metadata: { containerId: sandbox.containerId, runtime }
|
|
269
132
|
};
|
|
270
133
|
},
|
|
271
|
-
/**
|
|
272
|
-
* Get public URL for a specific port
|
|
273
|
-
*
|
|
274
|
-
* Uses sandbox.exposePort() to dynamically expose a port.
|
|
275
|
-
*/
|
|
276
134
|
getUrl: async (sandbox, options) => {
|
|
277
135
|
try {
|
|
278
136
|
return await sandbox.exposePort(options.port);
|
|
279
137
|
} catch (error) {
|
|
280
|
-
throw new Error(
|
|
281
|
-
`Failed to get Beam URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`
|
|
282
|
-
);
|
|
138
|
+
throw new Error(`Failed to get Beam URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`);
|
|
283
139
|
}
|
|
284
140
|
},
|
|
285
|
-
/**
|
|
286
|
-
* Filesystem operations
|
|
287
|
-
*
|
|
288
|
-
* Most operations use shell commands via runCommand since Beam's file API
|
|
289
|
-
* is local-path oriented (uploadFile/downloadFile require local filesystem paths).
|
|
290
|
-
* readdir uses the native listFiles API since it returns structured data.
|
|
291
|
-
*/
|
|
292
141
|
filesystem: {
|
|
293
142
|
readFile: async (sandbox, path, runCommand) => {
|
|
294
143
|
const result = await runCommand(sandbox, `cat ${shellEscape(path)}`);
|
|
295
|
-
if (result.exitCode !== 0) {
|
|
296
|
-
throw new Error(`Failed to read file ${path}: ${result.stderr}`);
|
|
297
|
-
}
|
|
144
|
+
if (result.exitCode !== 0) throw new Error(`Failed to read file ${path}: ${result.stderr}`);
|
|
298
145
|
return result.stdout;
|
|
299
146
|
},
|
|
300
147
|
writeFile: async (sandbox, path, content, runCommand) => {
|
|
301
148
|
const b64 = Buffer.from(content).toString("base64");
|
|
302
149
|
const result = await runCommand(sandbox, `echo '${b64}' | base64 -d > ${shellEscape(path)}`);
|
|
303
|
-
if (result.exitCode !== 0) {
|
|
304
|
-
throw new Error(`Failed to write file ${path}: ${result.stderr}`);
|
|
305
|
-
}
|
|
150
|
+
if (result.exitCode !== 0) throw new Error(`Failed to write file ${path}: ${result.stderr}`);
|
|
306
151
|
},
|
|
307
152
|
mkdir: async (sandbox, path, runCommand) => {
|
|
308
153
|
const result = await runCommand(sandbox, `mkdir -p ${shellEscape(path)}`);
|
|
309
|
-
if (result.exitCode !== 0) {
|
|
310
|
-
throw new Error(`Failed to create directory ${path}: ${result.stderr}`);
|
|
311
|
-
}
|
|
154
|
+
if (result.exitCode !== 0) throw new Error(`Failed to create directory ${path}: ${result.stderr}`);
|
|
312
155
|
},
|
|
313
156
|
readdir: async (sandbox, path, _runCommand) => {
|
|
314
157
|
const files = await sandbox.fs.listFiles(path);
|
|
@@ -325,17 +168,10 @@ var beam = defineProvider({
|
|
|
325
168
|
},
|
|
326
169
|
remove: async (sandbox, path, runCommand) => {
|
|
327
170
|
const result = await runCommand(sandbox, `rm -rf ${shellEscape(path)}`);
|
|
328
|
-
if (result.exitCode !== 0) {
|
|
329
|
-
throw new Error(`Failed to remove ${path}: ${result.stderr}`);
|
|
330
|
-
}
|
|
171
|
+
if (result.exitCode !== 0) throw new Error(`Failed to remove ${path}: ${result.stderr}`);
|
|
331
172
|
}
|
|
332
173
|
},
|
|
333
|
-
|
|
334
|
-
* Get the native SandboxInstance for advanced usage
|
|
335
|
-
*/
|
|
336
|
-
getInstance: (sandbox) => {
|
|
337
|
-
return sandbox;
|
|
338
|
-
}
|
|
174
|
+
getInstance: (sandbox) => sandbox
|
|
339
175
|
}
|
|
340
176
|
}
|
|
341
177
|
});
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Beam Provider - Factory-based Implementation\n *\n * Containerized sandbox environments using the Beam platform.\n * Beam provides sandboxes with process management, filesystem access,\n * and port exposure capabilities.\n *\n * Features:\n * - Process execution via sandbox.exec()\n * - Code execution in Python, JavaScript\n * - Shell command execution\n * - Filesystem operations (shell-based + native listFiles)\n * - Dynamic port exposure for accessing sandbox services\n */\n\nimport { Sandbox, SandboxInstance, beamOpts, Image } from '@beamcloud/beam-js';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\nimport type {\n CodeResult,\n CommandResult,\n SandboxInfo,\n Runtime,\n CreateSandboxOptions,\n FileEntry,\n RunCommandOptions,\n} from 'computesdk';\n\n/** Type alias for the runCommand function passed to filesystem methods */\ntype RunCommandFn = (sandbox: SandboxInstance, command: string, options?: RunCommandOptions) => Promise<CommandResult>;\n\n/**\n * Beam-specific configuration options\n */\nexport interface BeamConfig {\n /** Beam API token - if not provided, will fallback to BEAM_TOKEN environment variable */\n token?: string;\n /** Beam workspace ID - if not provided, will fallback to BEAM_WORKSPACE_ID environment variable */\n workspaceId?: string;\n /** Gateway URL for custom/staging environments */\n gatewayUrl?: string;\n /** Request timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * Configure the global beamOpts singleton before each SDK call.\n * Beam uses a global config pattern rather than per-call config.\n */\nfunction configureBeamOpts(config: BeamConfig): void {\n beamOpts.token = config.token || (typeof process !== 'undefined' && process.env?.BEAM_TOKEN) || '';\n beamOpts.workspaceId = config.workspaceId || (typeof process !== 'undefined' && process.env?.BEAM_WORKSPACE_ID) || '';\n if (config.gatewayUrl) {\n beamOpts.gatewayUrl = config.gatewayUrl;\n }\n if (config.timeout) {\n (beamOpts as any).timeout = config.timeout;\n }\n}\n\n/**\n * Shell-escape a string using single quotes (POSIX).\n */\nfunction shellEscape(arg: string): string {\n if (arg === '') return \"''\";\n return `'${arg.replace(/'/g, \"'\\\\''\")}'`;\n}\n\n/**\n * Detect Node parser/compile failures while avoiding runtime SyntaxError matches.\n */\nfunction isNodeParserFailure(output: string): boolean {\n const hasSyntaxMarker =\n output.includes('SyntaxError') ||\n output.includes('Unexpected token') ||\n output.includes('Unexpected identifier') ||\n output.includes('Unexpected end of input') ||\n output.includes('Invalid or unexpected token');\n\n const hasCompileContext =\n output.includes('[eval]') ||\n output.includes('makeContextifyScript') ||\n output.includes('compileScript') ||\n output.includes('wrapSafe');\n\n const hasRuntimeSyntaxSignature =\n output.includes('at JSON.parse') ||\n output.includes('JSON.parse (<anonymous>)') ||\n output.includes('in JSON at position');\n\n return hasSyntaxMarker && hasCompileContext && !hasRuntimeSyntaxSignature;\n}\n\n/**\n * Detect Python parser failures (syntax/indentation/tab) emitted by python -c.\n */\nfunction isPythonParserFailure(output: string): boolean {\n const hasSyntaxMarker =\n output.includes('SyntaxError') ||\n output.includes('IndentationError') ||\n output.includes('TabError');\n\n const hasStringFileContext = output.includes('File \"<string>\"');\n const hasRuntimeTraceback = output.includes('Traceback (most recent call last)');\n\n return hasSyntaxMarker && hasStringFileContext && !hasRuntimeTraceback;\n}\n\n/**\n * Detect parser/compile failures that should throw instead of returning CodeResult.\n */\nfunction isParserFailure(output: string, runtime: Runtime): boolean {\n if (!output.trim()) return false;\n\n if (runtime === 'node') {\n return isNodeParserFailure(output);\n }\n\n if (runtime === 'python') {\n return isPythonParserFailure(output);\n }\n\n return false;\n}\n\n/**\n * Create a Beam provider instance using the factory pattern\n *\n * Beam provides containerized sandbox environments with:\n * - Process management (exec, runCode)\n * - Filesystem access\n * - Dynamic port exposure\n * - Snapshot and image creation capabilities\n */\nexport const beam = defineProvider<SandboxInstance, BeamConfig>({\n name: 'beam',\n methods: {\n sandbox: {\n /**\n * Create a new Beam sandbox\n *\n * Uses Sandbox class from @beamcloud/beam-js to provision a container.\n */\n create: async (config: BeamConfig, options?: CreateSandboxOptions) => {\n configureBeamOpts(config);\n\n if (!beamOpts.token) {\n throw new Error(\n `Missing Beam token. Provide 'token' in config or set BEAM_TOKEN environment variable. Get your token from https://app.beam.cloud`\n );\n }\n\n if (!beamOpts.workspaceId) {\n throw new Error(\n `Missing Beam workspace ID. Provide 'workspaceId' in config or set BEAM_WORKSPACE_ID environment variable.`\n );\n }\n try {\n if (options?.sandboxId) {\n const instance = await Sandbox.connect(options.sandboxId);\n return { sandbox: instance, sandboxId: instance.containerId };\n }\n\n // Destructure known ComputeSDK fields, collect the rest for passthrough\n const {\n runtime: optRuntime,\n timeout: optTimeout,\n envs,\n name,\n metadata: _metadata,\n templateId: _templateId,\n snapshotId: _snapshotId,\n sandboxId: _sandboxId,\n namespace: _namespace,\n directory: _directory,\n overlays: _overlays,\n servers: _servers,\n ...providerOptions\n } = options || {};\n\n const sandboxConfig: any = {\n name: name || `computesdk-${Date.now()}`,\n keepWarmSeconds: 300,\n ...providerOptions, // Spread provider-specific options\n };\n\n // options.timeout takes precedence over config.timeout\n const timeout = optTimeout ?? config.timeout;\n if (timeout) {\n sandboxConfig.keepWarmSeconds = Math.ceil(timeout / 1000);\n }\n\n if (optRuntime === 'node') {\n sandboxConfig.image = Image.fromRegistry('node:20-slim');\n }\n\n if (envs) {\n sandboxConfig.envVars = Object.entries(envs).map(([name, value]) => `${name}=${value}`);\n }\n\n const sandbox = new Sandbox(sandboxConfig);\n const instance = await sandbox.create();\n return { sandbox: instance, sandboxId: instance.containerId };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('401')) {\n throw new Error(\n `Beam authentication failed. Please check your BEAM_TOKEN environment variable. Get your token from https://app.beam.cloud`\n );\n }\n }\n throw new Error(\n `Failed to create Beam sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n /**\n * Connect to an existing Beam sandbox by ID\n *\n * Uses Sandbox.connect() to reconnect to a running sandbox.\n */\n getById: async (config: BeamConfig, sandboxId: string) => {\n configureBeamOpts(config);\n\n if (!beamOpts.token) {\n return null;\n }\n\n try {\n const instance = await Sandbox.connect(sandboxId);\n return { sandbox: instance, sandboxId: instance.containerId };\n } catch {\n return null;\n }\n },\n\n /**\n * List all active Beam sandboxes\n *\n * Beam SDK has no sandbox list API; returns empty array.\n */\n list: async (_config: BeamConfig) => {\n return [];\n },\n\n /**\n * Destroy a Beam sandbox\n *\n * Connects to the sandbox and terminates it.\n */\n destroy: async (config: BeamConfig, sandboxId: string) => {\n configureBeamOpts(config);\n\n if (!beamOpts.token) {\n return;\n }\n\n try {\n const instance = await Sandbox.connect(sandboxId);\n await instance.terminate();\n } catch {\n // Sandbox might already be destroyed\n }\n },\n\n /**\n * Execute code in the sandbox\n *\n * Auto-detects runtime (Python vs Node.js) and executes via sandbox.exec().\n */\n runCode: async (sandbox: SandboxInstance, code: string, runtime?: Runtime): Promise<CodeResult> => {\n const effectiveRuntime = runtime || (\n code.includes('print(') ||\n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\") ||\n code.includes('raise ')\n ? 'python'\n : 'node'\n );\n\n try {\n const command = effectiveRuntime === 'python'\n ? ['python3', '-c', code]\n : ['node', '-e', code];\n\n const proc = await sandbox.exec(command);\n await proc.wait();\n const [stdoutStr, stderrStr] = await Promise.all([\n proc.stdout.read(),\n proc.stderr.read(),\n ]);\n\n const output = stderrStr\n ? `${stdoutStr}${stdoutStr && stderrStr ? '\\n' : ''}${stderrStr}`\n : stdoutStr;\n\n const combinedOutput = `${stdoutStr || ''} ${stderrStr || ''}`;\n\n if (proc.exitCode !== 0 && isParserFailure(combinedOutput, effectiveRuntime)) {\n throw new Error(`Syntax error: ${(stderrStr || stdoutStr || '').trim()}`);\n }\n\n if (proc.exitCode !== 0 && !stdoutStr && !stderrStr) {\n throw new Error(`Code execution failed with exit code ${proc.exitCode}`);\n }\n\n return {\n output,\n exitCode: proc.exitCode,\n language: effectiveRuntime,\n };\n } catch (error) {\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `Beam execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n /**\n * Execute a shell command in the sandbox\n *\n * Uses sandbox.exec() with shell command string.\n */\n runCommand: async (sandbox: SandboxInstance, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n try {\n let fullCommand = command;\n\n if (options?.env && Object.keys(options.env).length > 0) {\n const envPrefix = Object.entries(options.env)\n .map(([k, v]: [string, string]) => `${k}=\"${escapeShellArg(v)}\"`)\n .join(' ');\n fullCommand = `${envPrefix} ${fullCommand}`;\n }\n\n if (options?.cwd) {\n fullCommand = `cd \"${escapeShellArg(options.cwd)}\" && ${fullCommand}`;\n }\n\n if (options?.background) {\n fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n }\n\n // Wrap in sh -c to get shell parsing (pipes, redirects, etc.)\n const proc = await sandbox.exec(['sh', '-c', fullCommand]);\n await proc.wait();\n const [stdoutStr, stderrStr] = await Promise.all([\n proc.stdout.read(),\n proc.stderr.read(),\n ]);\n\n return {\n stdout: stdoutStr || '',\n stderr: stderrStr || '',\n exitCode: proc.exitCode || 0,\n durationMs: Date.now() - startTime,\n };\n } catch (error) {\n return {\n stdout: '',\n stderr: error instanceof Error ? error.message : String(error),\n exitCode: 127,\n durationMs: Date.now() - startTime,\n };\n }\n },\n\n /**\n * Get sandbox information\n */\n getInfo: async (sandbox: SandboxInstance): Promise<SandboxInfo> => {\n // Derive runtime from sandbox instance if available; otherwise default to 'python'\n let runtime: Runtime = 'python';\n const anySandbox = sandbox as any;\n\n if (typeof anySandbox.runtime === 'string') {\n const lower = anySandbox.runtime.toLowerCase();\n if (lower.includes('node')) {\n runtime = 'node';\n } else if (lower.includes('python')) {\n runtime = 'python';\n }\n } else if (typeof anySandbox.image === 'string') {\n const imageStr = anySandbox.image.toLowerCase();\n if (imageStr.includes('node')) {\n runtime = 'node';\n } else if (imageStr.includes('python')) {\n runtime = 'python';\n }\n } else if (typeof anySandbox.imageName === 'string') {\n const imageNameStr = anySandbox.imageName.toLowerCase();\n if (imageNameStr.includes('node')) {\n runtime = 'node';\n } else if (imageNameStr.includes('python')) {\n runtime = 'python';\n }\n }\n\n return {\n id: sandbox.containerId,\n provider: 'beam',\n runtime,\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n containerId: sandbox.containerId,\n },\n };\n },\n\n /**\n * Get public URL for a specific port\n *\n * Uses sandbox.exposePort() to dynamically expose a port.\n */\n getUrl: async (sandbox: SandboxInstance, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n return await sandbox.exposePort(options.port);\n } catch (error) {\n throw new Error(\n `Failed to get Beam URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n /**\n * Filesystem operations\n *\n * Most operations use shell commands via runCommand since Beam's file API\n * is local-path oriented (uploadFile/downloadFile require local filesystem paths).\n * readdir uses the native listFiles API since it returns structured data.\n */\n filesystem: {\n readFile: async (sandbox: SandboxInstance, path: string, runCommand: RunCommandFn): Promise<string> => {\n const result = await runCommand(sandbox, `cat ${shellEscape(path)}`);\n if (result.exitCode !== 0) {\n throw new Error(`Failed to read file ${path}: ${result.stderr}`);\n }\n return result.stdout;\n },\n\n writeFile: async (sandbox: SandboxInstance, path: string, content: string, runCommand: RunCommandFn): Promise<void> => {\n const b64 = Buffer.from(content).toString('base64');\n const result = await runCommand(sandbox, `echo '${b64}' | base64 -d > ${shellEscape(path)}`);\n if (result.exitCode !== 0) {\n throw new Error(`Failed to write file ${path}: ${result.stderr}`);\n }\n },\n\n mkdir: async (sandbox: SandboxInstance, path: string, runCommand: RunCommandFn): Promise<void> => {\n const result = await runCommand(sandbox, `mkdir -p ${shellEscape(path)}`);\n if (result.exitCode !== 0) {\n throw new Error(`Failed to create directory ${path}: ${result.stderr}`);\n }\n },\n\n readdir: async (sandbox: SandboxInstance, path: string, _runCommand: RunCommandFn): Promise<FileEntry[]> => {\n const files = await sandbox.fs.listFiles(path);\n return files.map((file: any) => ({\n name: file.name,\n type: file.isDir ? 'directory' as const : 'file' as const,\n size: Number(file.size) || 0,\n modified: file.modTime ? new Date(file.modTime * 1000) : new Date(),\n }));\n },\n\n exists: async (sandbox: SandboxInstance, path: string, runCommand: RunCommandFn): Promise<boolean> => {\n const result = await runCommand(sandbox, `test -f ${shellEscape(path)} || test -d ${shellEscape(path)}`);\n return result.exitCode === 0;\n },\n\n remove: async (sandbox: SandboxInstance, path: string, runCommand: RunCommandFn): Promise<void> => {\n const result = await runCommand(sandbox, `rm -rf ${shellEscape(path)}`);\n if (result.exitCode !== 0) {\n throw new Error(`Failed to remove ${path}: ${result.stderr}`);\n }\n },\n },\n\n /**\n * Get the native SandboxInstance for advanced usage\n */\n getInstance: (sandbox: SandboxInstance): SandboxInstance => {\n return sandbox;\n },\n },\n },\n});\n\n// Export Beam sandbox type for explicit typing\nexport type { SandboxInstance as BeamSandboxInstance } from '@beamcloud/beam-js';\n"],"mappings":"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","names":["instance","name"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Beam Provider - Factory-based Implementation\n *\n * Containerized sandbox environments using the Beam platform.\n * Beam provides sandboxes with process management, filesystem access,\n * and port exposure capabilities.\n */\n\nimport { Sandbox, SandboxInstance, beamOpts, Image } from '@beamcloud/beam-js';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\nimport type {\n CommandResult,\n SandboxInfo,\n CreateSandboxOptions,\n FileEntry,\n RunCommandOptions,\n} from 'computesdk';\n\ntype RunCommandFn = (sandbox: SandboxInstance, command: string, options?: RunCommandOptions) => Promise<CommandResult>;\n\nexport interface BeamConfig {\n token?: string;\n workspaceId?: string;\n gatewayUrl?: string;\n timeout?: number;\n}\n\nfunction configureBeamOpts(config: BeamConfig): void {\n beamOpts.token = config.token || (typeof process !== 'undefined' && process.env?.BEAM_TOKEN) || '';\n beamOpts.workspaceId = config.workspaceId || (typeof process !== 'undefined' && process.env?.BEAM_WORKSPACE_ID) || '';\n if (config.gatewayUrl) beamOpts.gatewayUrl = config.gatewayUrl;\n if (config.timeout) (beamOpts as any).timeout = config.timeout;\n}\n\nfunction shellEscape(arg: string): string {\n if (arg === '') return \"''\";\n return `'${arg.replace(/'/g, \"'\\\\''\")}'`;\n}\n\nfunction isNodeParserFailure(output: string): boolean {\n const hasSyntaxMarker =\n output.includes('SyntaxError') ||\n output.includes('Unexpected token') ||\n output.includes('Unexpected identifier') ||\n output.includes('Unexpected end of input') ||\n output.includes('Invalid or unexpected token');\n\n const hasCompileContext =\n output.includes('[eval]') ||\n output.includes('makeContextifyScript') ||\n output.includes('compileScript') ||\n output.includes('wrapSafe');\n\n const hasRuntimeSyntaxSignature =\n output.includes('at JSON.parse') ||\n output.includes('JSON.parse (<anonymous>)') ||\n output.includes('in JSON at position');\n\n return hasSyntaxMarker && hasCompileContext && !hasRuntimeSyntaxSignature;\n}\n\nfunction isPythonParserFailure(output: string): boolean {\n const hasSyntaxMarker =\n output.includes('SyntaxError') ||\n output.includes('IndentationError') ||\n output.includes('TabError');\n\n const hasStringFileContext = output.includes('File \"<string>\"');\n const hasRuntimeTraceback = output.includes('Traceback (most recent call last)');\n\n return hasSyntaxMarker && hasStringFileContext && !hasRuntimeTraceback;\n}\n\nfunction isParserFailure(output: string, runtime: string): boolean {\n if (!output.trim()) return false;\n if (runtime === 'node') return isNodeParserFailure(output);\n if (runtime === 'python') return isPythonParserFailure(output);\n return false;\n}\n\nexport const beam = defineProvider<SandboxInstance, BeamConfig>({\n name: 'beam',\n methods: {\n sandbox: {\n create: async (config: BeamConfig, options?: CreateSandboxOptions) => {\n configureBeamOpts(config);\n\n if (!beamOpts.token) {\n throw new Error(\n `Missing Beam token. Provide 'token' in config or set BEAM_TOKEN environment variable. Get your token from https://app.beam.cloud`\n );\n }\n\n if (!beamOpts.workspaceId) {\n throw new Error(\n `Missing Beam workspace ID. Provide 'workspaceId' in config or set BEAM_WORKSPACE_ID environment variable.`\n );\n }\n\n try {\n const {\n timeout: optTimeout,\n envs,\n name,\n metadata: _metadata,\n templateId: _templateId,\n snapshotId: _snapshotId,\n sandboxId: _sandboxId,\n namespace: _namespace,\n directory: _directory,\n ...providerOptions\n } = options || {};\n\n const optRuntime = (options as any)?.runtime as string | undefined;\n\n const sandboxConfig: any = {\n name: name || `computesdk-${Date.now()}`,\n keepWarmSeconds: 300,\n ...providerOptions,\n };\n\n const timeout = optTimeout ?? config.timeout;\n if (timeout) sandboxConfig.keepWarmSeconds = Math.ceil(timeout / 1000);\n\n if (optRuntime === 'node') {\n sandboxConfig.image = Image.fromRegistry('node:20-slim');\n }\n\n if (envs) {\n sandboxConfig.envVars = Object.entries(envs).map(([name, value]) => `${name}=${value}`);\n }\n\n const sandbox = new Sandbox(sandboxConfig);\n const instance = await sandbox.create();\n return { sandbox: instance, sandboxId: instance.containerId };\n } catch (error) {\n if (error instanceof Error && (error.message.includes('unauthorized') || error.message.includes('401'))) {\n throw new Error(\n `Beam authentication failed. Please check your BEAM_TOKEN environment variable. Get your token from https://app.beam.cloud`\n );\n }\n throw new Error(\n `Failed to create Beam sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: BeamConfig, sandboxId: string) => {\n configureBeamOpts(config);\n if (!beamOpts.token) return null;\n try {\n const instance = await Sandbox.connect(sandboxId);\n return { sandbox: instance, sandboxId: instance.containerId };\n } catch { return null; }\n },\n\n list: async (_config: BeamConfig) => [],\n\n destroy: async (config: BeamConfig, sandboxId: string) => {\n configureBeamOpts(config);\n if (!beamOpts.token) return;\n try {\n const instance = await Sandbox.connect(sandboxId);\n await instance.terminate();\n } catch { /* Sandbox might already be destroyed */ }\n },\n\n runCommand: async (sandbox: SandboxInstance, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n try {\n let fullCommand = command;\n if (options?.env && Object.keys(options.env).length > 0) {\n const envPrefix = Object.entries(options.env).map(([k, v]) => `${k}=\"${escapeShellArg(String(v))}\"`).join(' ');\n fullCommand = `${envPrefix} ${fullCommand}`;\n }\n if (options?.cwd) fullCommand = `cd \"${escapeShellArg(options.cwd)}\" && ${fullCommand}`;\n if (options?.background) fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`;\n\n const proc = await sandbox.exec(['sh', '-c', fullCommand]);\n await proc.wait();\n const [stdoutStr, stderrStr] = await Promise.all([proc.stdout.read(), proc.stderr.read()]);\n return { stdout: stdoutStr || '', stderr: stderrStr || '', exitCode: proc.exitCode || 0, durationMs: Date.now() - startTime };\n } catch (error) {\n return { stdout: '', stderr: error instanceof Error ? error.message : String(error), exitCode: 127, durationMs: Date.now() - startTime };\n }\n },\n\n getInfo: async (sandbox: SandboxInstance): Promise<SandboxInfo> => {\n let runtime = 'python';\n const runtimeHint = sandbox as SandboxInstance & { runtime?: unknown; image?: unknown; imageName?: unknown };\n if (typeof runtimeHint.runtime === 'string') {\n const lower = runtimeHint.runtime.toLowerCase();\n if (lower.includes('node')) runtime = 'node';\n else if (lower.includes('python')) runtime = 'python';\n } else if (typeof runtimeHint.image === 'string') {\n const imageStr = runtimeHint.image.toLowerCase();\n if (imageStr.includes('node')) runtime = 'node';\n else if (imageStr.includes('python')) runtime = 'python';\n } else if (typeof runtimeHint.imageName === 'string') {\n const imageNameStr = runtimeHint.imageName.toLowerCase();\n if (imageNameStr.includes('node')) runtime = 'node';\n else if (imageNameStr.includes('python')) runtime = 'python';\n }\n return {\n id: sandbox.containerId,\n provider: 'beam',\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: { containerId: sandbox.containerId, runtime },\n };\n },\n\n getUrl: async (sandbox: SandboxInstance, options: { port: number; protocol?: string }): Promise<string> => {\n try {\n return await sandbox.exposePort(options.port);\n } catch (error) {\n throw new Error(`Failed to get Beam URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n filesystem: {\n readFile: async (sandbox: SandboxInstance, path: string, runCommand: RunCommandFn): Promise<string> => {\n const result = await runCommand(sandbox, `cat ${shellEscape(path)}`);\n if (result.exitCode !== 0) throw new Error(`Failed to read file ${path}: ${result.stderr}`);\n return result.stdout;\n },\n writeFile: async (sandbox: SandboxInstance, path: string, content: string, runCommand: RunCommandFn): Promise<void> => {\n const b64 = Buffer.from(content).toString('base64');\n const result = await runCommand(sandbox, `echo '${b64}' | base64 -d > ${shellEscape(path)}`);\n if (result.exitCode !== 0) throw new Error(`Failed to write file ${path}: ${result.stderr}`);\n },\n mkdir: async (sandbox: SandboxInstance, path: string, runCommand: RunCommandFn): Promise<void> => {\n const result = await runCommand(sandbox, `mkdir -p ${shellEscape(path)}`);\n if (result.exitCode !== 0) throw new Error(`Failed to create directory ${path}: ${result.stderr}`);\n },\n readdir: async (sandbox: SandboxInstance, path: string, _runCommand: RunCommandFn): Promise<FileEntry[]> => {\n const files = await sandbox.fs.listFiles(path);\n return files.map((file: any) => ({\n name: file.name,\n type: file.isDir ? 'directory' as const : 'file' as const,\n size: Number(file.size) || 0,\n modified: file.modTime ? new Date(file.modTime * 1000) : new Date(),\n }));\n },\n exists: async (sandbox: SandboxInstance, path: string, runCommand: RunCommandFn): Promise<boolean> => {\n const result = await runCommand(sandbox, `test -f ${shellEscape(path)} || test -d ${shellEscape(path)}`);\n return result.exitCode === 0;\n },\n remove: async (sandbox: SandboxInstance, path: string, runCommand: RunCommandFn): Promise<void> => {\n const result = await runCommand(sandbox, `rm -rf ${shellEscape(path)}`);\n if (result.exitCode !== 0) throw new Error(`Failed to remove ${path}: ${result.stderr}`);\n },\n },\n\n getInstance: (sandbox: SandboxInstance): SandboxInstance => sandbox,\n },\n },\n});\n\nexport type { SandboxInstance as BeamSandboxInstance } from '@beamcloud/beam-js';\n"],"mappings":"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","names":["name"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@computesdk/beam",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "Beam provider for ComputeSDK - containerized sandbox environments with process management and filesystem access",
|
|
5
5
|
"author": "ComputeSDK",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@beamcloud/beam-js": "1.0.0-rc.30",
|
|
22
|
-
"computesdk": "
|
|
23
|
-
"@computesdk/provider": "
|
|
22
|
+
"computesdk": "4.0.0",
|
|
23
|
+
"@computesdk/provider": "2.0.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/node": "^20.0.0",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"tsup": "^8.0.0",
|
|
31
31
|
"typescript": "^5.0.0",
|
|
32
32
|
"vitest": "^1.0.0",
|
|
33
|
-
"@computesdk/test-utils": "
|
|
33
|
+
"@computesdk/test-utils": "2.0.0"
|
|
34
34
|
},
|
|
35
35
|
"keywords": [
|
|
36
36
|
"computesdk",
|