@computesdk/codesandbox 1.5.69 → 1.5.70
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 +11 -3
- package/dist/index.d.ts +11 -3
- package/dist/index.js +266 -100
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +267 -101
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as _computesdk_provider from '@computesdk/provider';
|
|
2
1
|
import * as computesdk from 'computesdk';
|
|
2
|
+
import * as _computesdk_provider from '@computesdk/provider';
|
|
3
3
|
import { Sandbox } from '@codesandbox/sdk';
|
|
4
4
|
|
|
5
5
|
interface CodesandboxConfig {
|
|
@@ -12,8 +12,16 @@ interface CodesandboxConfig {
|
|
|
12
12
|
/** Execution timeout in milliseconds */
|
|
13
13
|
timeout?: number;
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* The CodeSandbox SDK sandbox, plus `pause()` (hibernate: memory and disk are
|
|
17
|
+
* kept) and `resume()` (wake the same sandbox id).
|
|
18
|
+
*/
|
|
19
|
+
type CodesandboxSandbox = Sandbox & {
|
|
20
|
+
pause(): Promise<void>;
|
|
21
|
+
resume(): Promise<void>;
|
|
22
|
+
};
|
|
23
|
+
declare const codesandbox: (config: CodesandboxConfig & _computesdk_provider.ProcessRuntimeOptions) => _computesdk_provider.Provider<CodesandboxSandbox, any, any, computesdk.Volume> & {
|
|
16
24
|
readonly sizes: computesdk.InstanceSizeManager;
|
|
17
25
|
};
|
|
18
26
|
|
|
19
|
-
export { type CodesandboxConfig, codesandbox };
|
|
27
|
+
export { type CodesandboxConfig, type CodesandboxSandbox, codesandbox };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as _computesdk_provider from '@computesdk/provider';
|
|
2
1
|
import * as computesdk from 'computesdk';
|
|
2
|
+
import * as _computesdk_provider from '@computesdk/provider';
|
|
3
3
|
import { Sandbox } from '@codesandbox/sdk';
|
|
4
4
|
|
|
5
5
|
interface CodesandboxConfig {
|
|
@@ -12,8 +12,16 @@ interface CodesandboxConfig {
|
|
|
12
12
|
/** Execution timeout in milliseconds */
|
|
13
13
|
timeout?: number;
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* The CodeSandbox SDK sandbox, plus `pause()` (hibernate: memory and disk are
|
|
17
|
+
* kept) and `resume()` (wake the same sandbox id).
|
|
18
|
+
*/
|
|
19
|
+
type CodesandboxSandbox = Sandbox & {
|
|
20
|
+
pause(): Promise<void>;
|
|
21
|
+
resume(): Promise<void>;
|
|
22
|
+
};
|
|
23
|
+
declare const codesandbox: (config: CodesandboxConfig & _computesdk_provider.ProcessRuntimeOptions) => _computesdk_provider.Provider<CodesandboxSandbox, any, any, computesdk.Volume> & {
|
|
16
24
|
readonly sizes: computesdk.InstanceSizeManager;
|
|
17
25
|
};
|
|
18
26
|
|
|
19
|
-
export { type CodesandboxConfig, codesandbox };
|
|
27
|
+
export { type CodesandboxConfig, type CodesandboxSandbox, codesandbox };
|
package/dist/index.js
CHANGED
|
@@ -25,62 +25,189 @@ __export(index_exports, {
|
|
|
25
25
|
module.exports = __toCommonJS(index_exports);
|
|
26
26
|
var import_sdk = require("@codesandbox/sdk");
|
|
27
27
|
var import_provider = require("@computesdk/provider");
|
|
28
|
+
var SNAPSHOT_TAG = "computesdk-snapshot";
|
|
29
|
+
var states = /* @__PURE__ */ new WeakMap();
|
|
30
|
+
var statesById = /* @__PURE__ */ new Map();
|
|
31
|
+
var openClients = /* @__PURE__ */ new Map();
|
|
32
|
+
function resolveApiKey(config) {
|
|
33
|
+
const apiKey = config.apiKey || typeof process !== "undefined" && process.env?.CSB_API_KEY || "";
|
|
34
|
+
if (!apiKey) {
|
|
35
|
+
throw new Error(`Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable.`);
|
|
36
|
+
}
|
|
37
|
+
return apiKey;
|
|
38
|
+
}
|
|
39
|
+
function sdkFor(config) {
|
|
40
|
+
return new import_sdk.CodeSandbox(resolveApiKey(config));
|
|
41
|
+
}
|
|
42
|
+
async function closeClient(sandboxId) {
|
|
43
|
+
const client = openClients.get(sandboxId);
|
|
44
|
+
if (!client) return;
|
|
45
|
+
openClients.delete(sandboxId);
|
|
46
|
+
try {
|
|
47
|
+
const open = await client;
|
|
48
|
+
await open.disconnect().catch(() => void 0);
|
|
49
|
+
open.dispose();
|
|
50
|
+
} catch {
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function track(sdk, native) {
|
|
54
|
+
const state = { sdk, current: native };
|
|
55
|
+
states.set(native, state);
|
|
56
|
+
statesById.set(native.id, state);
|
|
57
|
+
const sandbox = native;
|
|
58
|
+
Object.defineProperty(sandbox, "pause", {
|
|
59
|
+
configurable: true,
|
|
60
|
+
value: async () => {
|
|
61
|
+
await closeClient(sandbox.id);
|
|
62
|
+
state.client = void 0;
|
|
63
|
+
await sdk.sandboxes.hibernate(sandbox.id);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
Object.defineProperty(sandbox, "resume", {
|
|
67
|
+
configurable: true,
|
|
68
|
+
value: async () => {
|
|
69
|
+
await closeClient(sandbox.id);
|
|
70
|
+
state.client = void 0;
|
|
71
|
+
state.current = await sdk.sandboxes.resume(sandbox.id);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
return sandbox;
|
|
75
|
+
}
|
|
76
|
+
async function refreshSession(sandboxId) {
|
|
77
|
+
await closeClient(sandboxId);
|
|
78
|
+
const state = statesById.get(sandboxId);
|
|
79
|
+
if (!state) return;
|
|
80
|
+
state.client = void 0;
|
|
81
|
+
state.current = await state.sdk.sandboxes.resume(sandboxId);
|
|
82
|
+
}
|
|
83
|
+
function getClient(sandbox) {
|
|
84
|
+
const state = states.get(sandbox);
|
|
85
|
+
if (!state) return sandbox.connect();
|
|
86
|
+
if (state.client && openClients.get(sandbox.id) !== state.client) state.client = void 0;
|
|
87
|
+
if (!state.client) {
|
|
88
|
+
const client = state.current.connect();
|
|
89
|
+
state.client = client;
|
|
90
|
+
openClients.set(sandbox.id, client);
|
|
91
|
+
client.catch(() => {
|
|
92
|
+
if (state.client === client) state.client = void 0;
|
|
93
|
+
if (openClients.get(sandbox.id) === client) openClients.delete(sandbox.id);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return state.client;
|
|
97
|
+
}
|
|
98
|
+
function shQuote(value) {
|
|
99
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
100
|
+
}
|
|
101
|
+
function randomToken() {
|
|
102
|
+
return `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;
|
|
103
|
+
}
|
|
104
|
+
var TIMEOUT_EXIT_CODE = 124;
|
|
105
|
+
function wrapCommand(command, token, timeoutMs) {
|
|
106
|
+
const out = `/tmp/.computesdk-${token}.out`;
|
|
107
|
+
const err = `/tmp/.computesdk-${token}.err`;
|
|
108
|
+
const marker = `'__CSDK_' '${token}__'`;
|
|
109
|
+
const body = timeoutMs && timeoutMs > 0 ? `if command -v timeout >/dev/null 2>&1; then timeout -k 2 ${Math.max(1, Math.ceil(timeoutMs / 1e3))} bash -c ${shQuote(command)}; else bash -c ${shQuote(command)}; fi` : command;
|
|
110
|
+
return [
|
|
111
|
+
`(
|
|
112
|
+
${body}
|
|
113
|
+
) </dev/null >${out} 2>${err}; __csdk_ec=$?`,
|
|
114
|
+
`{ printf '%s%s%s:' ${marker} "$__csdk_ec"; base64 ${out} | tr -d '\\n'; printf ':'; base64 ${err} | tr -d '\\n'; printf '%s%s' ${marker}; } >${resultPath(token)}.tmp`,
|
|
115
|
+
`mv -f ${resultPath(token)}.tmp ${resultPath(token)}; rm -f ${out} ${err}; cat ${resultPath(token)}`
|
|
116
|
+
].join("; ");
|
|
117
|
+
}
|
|
118
|
+
function resultPath(token) {
|
|
119
|
+
return `/tmp/.computesdk-${token}.res`;
|
|
120
|
+
}
|
|
121
|
+
function parseWrapped(output, marker) {
|
|
122
|
+
const flat = output.replace(/[\r\n]/g, "");
|
|
123
|
+
const start = flat.indexOf(marker);
|
|
124
|
+
if (start === -1) return void 0;
|
|
125
|
+
const end = flat.indexOf(marker, start + marker.length);
|
|
126
|
+
if (end === -1) return void 0;
|
|
127
|
+
const [code, out = "", err = ""] = flat.slice(start + marker.length, end).split(":");
|
|
128
|
+
const exitCode = Number.parseInt(code, 10);
|
|
129
|
+
if (!Number.isFinite(exitCode)) return void 0;
|
|
130
|
+
return {
|
|
131
|
+
stdout: Buffer.from(out, "base64").toString("utf8"),
|
|
132
|
+
stderr: Buffer.from(err, "base64").toString("utf8"),
|
|
133
|
+
exitCode
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
var SessionError = class extends Error {
|
|
137
|
+
constructor(cause) {
|
|
138
|
+
super(cause instanceof Error ? cause.message : String(cause));
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
async function runToCompletion(client, wrapped, runOpts, resultFile, timeoutMs) {
|
|
142
|
+
const cmd = await client.commands.runBackground(wrapped, runOpts).catch((error) => {
|
|
143
|
+
throw new SessionError(error);
|
|
144
|
+
});
|
|
145
|
+
let settled = false;
|
|
146
|
+
const finished = cmd.waitUntilComplete().then(
|
|
147
|
+
(output) => output,
|
|
148
|
+
(error) => typeof error?.output === "string" ? error.output : ""
|
|
149
|
+
);
|
|
150
|
+
const polled = (async () => {
|
|
151
|
+
for (let delay = 100; !settled; delay = Math.min(delay * 2, 1e3)) {
|
|
152
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
153
|
+
if (settled) break;
|
|
154
|
+
const exists = await client.fs.stat(resultFile).then(() => true, () => false);
|
|
155
|
+
if (exists) {
|
|
156
|
+
cmd.kill().catch(() => void 0);
|
|
157
|
+
return "";
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return "";
|
|
161
|
+
})();
|
|
162
|
+
let timer;
|
|
163
|
+
const deadline = timeoutMs === void 0 ? void 0 : new Promise((resolve) => {
|
|
164
|
+
timer = setTimeout(() => resolve(void 0), timeoutMs);
|
|
165
|
+
});
|
|
166
|
+
try {
|
|
167
|
+
return await Promise.race([finished, polled, ...deadline ? [deadline] : []]);
|
|
168
|
+
} finally {
|
|
169
|
+
settled = true;
|
|
170
|
+
clearTimeout(timer);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
28
173
|
var codesandbox = (0, import_provider.defineProvider)({
|
|
29
174
|
name: "codesandbox",
|
|
30
175
|
methods: {
|
|
31
176
|
instances: {
|
|
32
177
|
create: async (config, options) => {
|
|
33
|
-
const
|
|
34
|
-
if (!apiKey) {
|
|
35
|
-
throw new Error(`Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable.`);
|
|
36
|
-
}
|
|
37
|
-
const sdk = new import_sdk.CodeSandbox(apiKey);
|
|
178
|
+
const sdk = sdkFor(config);
|
|
38
179
|
try {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const createOptions = { ...providerOptions };
|
|
58
|
-
const templateId = optTemplateId || config.templateId;
|
|
59
|
-
if (templateId) createOptions.id = templateId;
|
|
60
|
-
if (envs && Object.keys(envs).length > 0) createOptions.envVars = envs;
|
|
61
|
-
sandbox = await sdk.sandboxes.create(createOptions);
|
|
62
|
-
sandboxId = sandbox.id;
|
|
63
|
-
}
|
|
64
|
-
return { instance: sandbox, instanceId: sandboxId };
|
|
180
|
+
const {
|
|
181
|
+
timeout: _timeout,
|
|
182
|
+
envs,
|
|
183
|
+
name: _name,
|
|
184
|
+
metadata: _metadata,
|
|
185
|
+
templateId: optTemplateId,
|
|
186
|
+
snapshotId,
|
|
187
|
+
sandboxId: _sandboxId,
|
|
188
|
+
namespace: _namespace,
|
|
189
|
+
directory: _directory,
|
|
190
|
+
...providerOptions
|
|
191
|
+
} = options || {};
|
|
192
|
+
const createOptions = { ...providerOptions };
|
|
193
|
+
const templateId = snapshotId || optTemplateId || config.templateId;
|
|
194
|
+
if (templateId) createOptions.id = templateId;
|
|
195
|
+
if (envs && Object.keys(envs).length > 0) createOptions.envVars = envs;
|
|
196
|
+
const sandbox = await sdk.sandboxes.create(createOptions);
|
|
197
|
+
return { instance: track(sdk, sandbox), instanceId: sandbox.id };
|
|
65
198
|
} catch (error) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
if (error.message.includes("quota") || error.message.includes("limit")) {
|
|
71
|
-
throw new Error(`CodeSandbox quota exceeded. Please check your usage at https://codesandbox.io/dashboard`);
|
|
72
|
-
}
|
|
199
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
200
|
+
if (/unauthori[sz]ed|API key/i.test(message)) {
|
|
201
|
+
throw new Error(`CodeSandbox authentication failed. Please check your CSB_API_KEY environment variable. (${message})`);
|
|
73
202
|
}
|
|
74
|
-
throw new Error(`Failed to create CodeSandbox sandbox: ${
|
|
203
|
+
throw new Error(`Failed to create CodeSandbox sandbox: ${message}`);
|
|
75
204
|
}
|
|
76
205
|
},
|
|
77
206
|
getById: async (config, sandboxId) => {
|
|
78
|
-
const
|
|
79
|
-
if (!apiKey) throw new Error(`Missing CodeSandbox API key.`);
|
|
80
|
-
const sdk = new import_sdk.CodeSandbox(apiKey);
|
|
207
|
+
const sdk = sdkFor(config);
|
|
81
208
|
try {
|
|
82
209
|
const sandbox = await sdk.sandboxes.resume(sandboxId);
|
|
83
|
-
return { instance: sandbox, instanceId: sandboxId };
|
|
210
|
+
return { instance: track(sdk, sandbox), instanceId: sandboxId };
|
|
84
211
|
} catch {
|
|
85
212
|
return null;
|
|
86
213
|
}
|
|
@@ -89,49 +216,72 @@ var codesandbox = (0, import_provider.defineProvider)({
|
|
|
89
216
|
throw new Error(`CodeSandbox provider does not support listing sandboxes.`);
|
|
90
217
|
},
|
|
91
218
|
destroy: async (config, sandboxId) => {
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
219
|
+
const sdk = sdkFor(config);
|
|
220
|
+
await closeClient(sandboxId);
|
|
221
|
+
statesById.delete(sandboxId);
|
|
95
222
|
try {
|
|
96
223
|
await sdk.sandboxes.shutdown(sandboxId);
|
|
97
224
|
} catch {
|
|
98
225
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
226
|
+
let lastError;
|
|
227
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
228
|
+
try {
|
|
229
|
+
await sdk.sandboxes.delete(sandboxId);
|
|
230
|
+
return;
|
|
231
|
+
} catch (error) {
|
|
232
|
+
const message2 = error instanceof Error ? error.message : String(error);
|
|
233
|
+
if (/not found|404/i.test(message2)) return;
|
|
234
|
+
lastError = error;
|
|
235
|
+
await new Promise((resolve) => setTimeout(resolve, 2e3 * (attempt + 1)));
|
|
105
236
|
}
|
|
106
237
|
}
|
|
238
|
+
const message = lastError instanceof Error ? lastError.message : String(lastError);
|
|
239
|
+
throw new Error(`Failed to delete CodeSandbox sandbox "${sandboxId}": ${message}`);
|
|
107
240
|
},
|
|
108
241
|
runCommand: async (sandbox, command, options) => {
|
|
109
242
|
const startTime = Date.now();
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
243
|
+
const runOpts = {};
|
|
244
|
+
if (options?.env && Object.keys(options.env).length > 0) runOpts.env = options.env;
|
|
245
|
+
if (options?.cwd) runOpts.cwd = options.cwd;
|
|
246
|
+
const run = async () => {
|
|
247
|
+
const client = await getClient(sandbox).catch((error) => {
|
|
248
|
+
throw new SessionError(error);
|
|
249
|
+
});
|
|
250
|
+
if (options?.background) {
|
|
251
|
+
await client.commands.runBackground(`setsid bash -c ${shQuote(command)} </dev/null >/dev/null 2>&1 &`, runOpts).catch((error) => {
|
|
252
|
+
throw new SessionError(error);
|
|
253
|
+
});
|
|
254
|
+
return { stdout: "", stderr: "", exitCode: 0, durationMs: Date.now() - startTime };
|
|
255
|
+
}
|
|
256
|
+
const token = randomToken();
|
|
257
|
+
const marker = `__CSDK_${token}__`;
|
|
258
|
+
const clientTimeoutMs = options?.timeout && options.timeout > 0 ? options.timeout + 1e4 : void 0;
|
|
259
|
+
const output = await runToCompletion(client, wrapCommand(command, token, options?.timeout), runOpts, resultPath(token), clientTimeoutMs);
|
|
260
|
+
if (output === void 0) {
|
|
261
|
+
return { stdout: "", stderr: `Command timed out after ${options.timeout}ms`, exitCode: TIMEOUT_EXIT_CODE, durationMs: Date.now() - startTime };
|
|
262
|
+
}
|
|
263
|
+
let parsed = parseWrapped(output, marker);
|
|
264
|
+
if (!parsed) {
|
|
265
|
+
const saved = await client.fs.readTextFile(resultPath(token)).catch(() => void 0);
|
|
266
|
+
parsed = saved === void 0 ? void 0 : parseWrapped(saved, marker);
|
|
116
267
|
}
|
|
117
|
-
|
|
118
|
-
if (
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return
|
|
268
|
+
client.fs.remove(resultPath(token)).catch(() => void 0);
|
|
269
|
+
if (!parsed) {
|
|
270
|
+
return { stdout: output.replace(/\r\n/g, "\n"), stderr: "", exitCode: 0, durationMs: Date.now() - startTime };
|
|
271
|
+
}
|
|
272
|
+
return { ...parsed, durationMs: Date.now() - startTime };
|
|
273
|
+
};
|
|
274
|
+
try {
|
|
275
|
+
try {
|
|
276
|
+
return await run();
|
|
277
|
+
} catch (error) {
|
|
278
|
+
if (!(error instanceof SessionError)) throw error;
|
|
279
|
+
await refreshSession(sandbox.id);
|
|
280
|
+
return await run();
|
|
126
281
|
}
|
|
127
|
-
const after = output.substring(delimIdx + delim.length);
|
|
128
|
-
const newlineIdx = after.indexOf("\n");
|
|
129
|
-
const exitCode = parseInt(newlineIdx === -1 ? after : after.substring(0, newlineIdx), 10) || 0;
|
|
130
|
-
const stderr = newlineIdx === -1 ? "" : after.substring(newlineIdx + 1);
|
|
131
|
-
const stdout = output.substring(0, delimIdx).replace(/\n$/, "");
|
|
132
|
-
return { stdout, stderr, exitCode, durationMs: Date.now() - startTime };
|
|
133
282
|
} catch (error) {
|
|
134
|
-
|
|
283
|
+
const exitCode = typeof error?.exitCode === "number" ? error.exitCode : 127;
|
|
284
|
+
return { stdout: "", stderr: error instanceof Error ? error.message : String(error), exitCode, durationMs: Date.now() - startTime };
|
|
135
285
|
}
|
|
136
286
|
},
|
|
137
287
|
getInfo: async (sandbox) => ({
|
|
@@ -148,68 +298,84 @@ var codesandbox = (0, import_provider.defineProvider)({
|
|
|
148
298
|
},
|
|
149
299
|
filesystem: {
|
|
150
300
|
readFile: async (sandbox, path) => {
|
|
151
|
-
const client = await sandbox
|
|
301
|
+
const client = await getClient(sandbox);
|
|
152
302
|
return client.fs.readTextFile(path);
|
|
153
303
|
},
|
|
154
304
|
writeFile: async (sandbox, path, content) => {
|
|
155
|
-
const client = await sandbox
|
|
305
|
+
const client = await getClient(sandbox);
|
|
156
306
|
await client.fs.writeTextFile(path, content);
|
|
157
307
|
},
|
|
158
308
|
mkdir: async (sandbox, path) => {
|
|
159
|
-
const client = await sandbox
|
|
160
|
-
await client.
|
|
309
|
+
const client = await getClient(sandbox);
|
|
310
|
+
await client.fs.mkdir(path, true);
|
|
161
311
|
},
|
|
162
312
|
readdir: async (sandbox, path) => {
|
|
163
|
-
const client = await sandbox
|
|
313
|
+
const client = await getClient(sandbox);
|
|
164
314
|
const entries = await client.fs.readdir(path);
|
|
165
315
|
return entries.map((entry) => ({
|
|
166
316
|
name: entry.name,
|
|
167
|
-
type: entry.
|
|
168
|
-
size:
|
|
169
|
-
modified:
|
|
317
|
+
type: entry.type === "directory" ? "directory" : "file",
|
|
318
|
+
size: 0,
|
|
319
|
+
modified: /* @__PURE__ */ new Date()
|
|
170
320
|
}));
|
|
171
321
|
},
|
|
172
322
|
exists: async (sandbox, path) => {
|
|
173
|
-
const client = await sandbox
|
|
323
|
+
const client = await getClient(sandbox);
|
|
174
324
|
try {
|
|
175
|
-
await client.
|
|
325
|
+
await client.fs.stat(path);
|
|
176
326
|
return true;
|
|
177
327
|
} catch {
|
|
178
328
|
return false;
|
|
179
329
|
}
|
|
180
330
|
},
|
|
181
331
|
remove: async (sandbox, path) => {
|
|
182
|
-
const client = await sandbox
|
|
183
|
-
await client.fs.remove(path);
|
|
332
|
+
const client = await getClient(sandbox);
|
|
333
|
+
await client.fs.remove(path, true);
|
|
184
334
|
}
|
|
185
335
|
},
|
|
336
|
+
// Hibernate keeps the VM's memory and disk; resume wakes the same sandbox id.
|
|
337
|
+
pause: (sandbox) => sandbox.pause(),
|
|
338
|
+
resume: (sandbox) => sandbox.resume(),
|
|
339
|
+
pauseCapabilities: { memory: true },
|
|
186
340
|
getInstance: (sandbox) => sandbox
|
|
187
341
|
},
|
|
188
342
|
snapshot: {
|
|
343
|
+
// A fork of the running sandbox (memory, processes and disk), hibernated
|
|
344
|
+
// so it persists as a restore point independent of the source.
|
|
189
345
|
create: async (config, sandboxId, options) => {
|
|
190
|
-
const
|
|
191
|
-
if (!apiKey) throw new Error(`Missing CodeSandbox API key.`);
|
|
192
|
-
const sdk = new import_sdk.CodeSandbox(apiKey);
|
|
346
|
+
const sdk = sdkFor(config);
|
|
193
347
|
try {
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
348
|
+
const fork = await sdk.sandboxes.create({
|
|
349
|
+
id: sandboxId,
|
|
350
|
+
tags: [SNAPSHOT_TAG],
|
|
351
|
+
...options?.name ? { title: options.name } : {}
|
|
352
|
+
});
|
|
353
|
+
await sdk.sandboxes.hibernate(fork.id);
|
|
354
|
+
await refreshSession(sandboxId);
|
|
355
|
+
return { id: fork.id, provider: "codesandbox", createdAt: /* @__PURE__ */ new Date(), metadata: { name: options?.name, sourceSandboxId: sandboxId } };
|
|
197
356
|
} catch (error) {
|
|
198
357
|
throw new Error(`Failed to create CodeSandbox snapshot: ${error instanceof Error ? error.message : String(error)}`);
|
|
199
358
|
}
|
|
200
359
|
},
|
|
201
|
-
list: async (
|
|
202
|
-
|
|
360
|
+
list: async (config) => {
|
|
361
|
+
const sdk = sdkFor(config);
|
|
362
|
+
const { sandboxes } = await sdk.sandboxes.list({ tags: [SNAPSHOT_TAG] });
|
|
363
|
+
return sandboxes.filter((s) => s.tags?.includes(SNAPSHOT_TAG)).map((s) => ({ id: s.id, provider: "codesandbox", createdAt: s.createdAt, metadata: { name: s.title } }));
|
|
203
364
|
},
|
|
204
365
|
delete: async (config, snapshotId) => {
|
|
205
|
-
const
|
|
206
|
-
if (!apiKey) throw new Error(`Missing CodeSandbox API key.`);
|
|
207
|
-
const sdk = new import_sdk.CodeSandbox(apiKey);
|
|
366
|
+
const sdk = sdkFor(config);
|
|
208
367
|
try {
|
|
209
|
-
await sdk.sandboxes.
|
|
210
|
-
} catch {
|
|
368
|
+
await sdk.sandboxes.delete(snapshotId);
|
|
369
|
+
} catch (error) {
|
|
370
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
371
|
+
if (!/not found|404/i.test(message)) {
|
|
372
|
+
throw new Error(`Failed to delete CodeSandbox snapshot "${snapshotId}": ${message}`);
|
|
373
|
+
}
|
|
211
374
|
}
|
|
212
|
-
}
|
|
375
|
+
},
|
|
376
|
+
// Forks keep the whole VM, memory and /tmp included; the source keeps
|
|
377
|
+
// running, and each restore is an independent fork of the snapshot.
|
|
378
|
+
capabilities: { scope: "rootfs", memory: true, destroysSource: false, source: "kept", fork: true, readiness: "immediate" }
|
|
213
379
|
},
|
|
214
380
|
template: {
|
|
215
381
|
create: async (_config, _options) => {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Codesandbox Provider - Factory-based Implementation\n */\n\nimport { CodeSandbox } from '@codesandbox/sdk';\nimport type { Sandbox as CodesandboxSandbox } from '@codesandbox/sdk';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\n\nimport type { CommandResult, InstanceInfo, CreateInstanceOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\nexport interface CodesandboxConfig {\n /** CodeSandbox API key - if not provided, will fallback to CSB_API_KEY environment variable */\n apiKey?: string;\n /** Template to use for new sandboxes */\n templateId?: string;\n /** Default runtime environment (e.g. 'node', 'python') */\n runtime?: string;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\nexport const codesandbox = defineProvider<CodesandboxSandbox, CodesandboxConfig, any, any>({\n name: 'codesandbox',\n methods: {\n instances: {\n create: async (config: CodesandboxConfig, options?: CreateInstanceOptions) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n if (!apiKey) {\n throw new Error(`Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable.`);\n }\n const sdk = new CodeSandbox(apiKey);\n try {\n let sandbox: CodesandboxSandbox;\n let sandboxId: string;\n if (options?.snapshotId) {\n sandbox = await sdk.sandboxes.resume(options.snapshotId);\n sandboxId = options.snapshotId;\n } else {\n const {\n timeout: _timeout, envs, name: _name, metadata: _metadata,\n templateId: optTemplateId, snapshotId: _snapshotId, sandboxId: _sandboxId,\n namespace: _namespace, directory: _directory, ...providerOptions\n } = options || {};\n const createOptions: any = { ...providerOptions };\n const templateId = optTemplateId || config.templateId;\n if (templateId) createOptions.id = templateId;\n if (envs && Object.keys(envs).length > 0) createOptions.envVars = envs;\n sandbox = await sdk.sandboxes.create(createOptions);\n sandboxId = sandbox.id;\n }\n return { instance: sandbox, instanceId: sandboxId };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('API key')) {\n throw new Error(`CodeSandbox authentication failed. Please check your CSB_API_KEY environment variable.`);\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(`CodeSandbox quota exceeded. Please check your usage at https://codesandbox.io/dashboard`);\n }\n }\n throw new Error(`Failed to create CodeSandbox sandbox: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n getById: async (config: CodesandboxConfig, sandboxId: string) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n if (!apiKey) throw new Error(`Missing CodeSandbox API key.`);\n const sdk = new CodeSandbox(apiKey);\n try {\n const sandbox = await sdk.sandboxes.resume(sandboxId);\n return { instance: sandbox, instanceId: sandboxId };\n } catch { return null; }\n },\n\n list: async (_config: CodesandboxConfig) => {\n throw new Error(`CodeSandbox provider does not support listing sandboxes.`);\n },\n\n destroy: async (config: CodesandboxConfig, sandboxId: string) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n if (!apiKey) throw new Error(`Missing CodeSandbox API key.`);\n const sdk = new CodeSandbox(apiKey);\n try { await sdk.sandboxes.shutdown(sandboxId); } catch { /* ignore */ }\n try {\n await sdk.sandboxes.delete(sandboxId);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (!message.includes('not found') && !message.includes('404')) {\n throw new Error(`Failed to delete CodeSandbox sandbox \"${sandboxId}\": ${message}`);\n }\n }\n },\n\n runCommand: async (sandbox: CodesandboxSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n try {\n const client = await sandbox.connect();\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(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 // commands.run returns a bare output string — capture the real exit\n // code and stderr in-band via a delimiter + stderr file.\n const errFile = `/tmp/.computesdk-stderr-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n const delim = `__COMPUTESDK_EXIT_${Date.now()}_${Math.random().toString(36).slice(2)}__`;\n const wrapped = `{ ${fullCommand} ; } 2>${escapeShellArg(errFile)}; __cs_ec=$?; echo \"${delim}$__cs_ec\"; cat ${escapeShellArg(errFile)} 2>/dev/null; rm -f ${escapeShellArg(errFile)}`;\n const output = await client.commands.run(wrapped);\n const delimIdx = output.lastIndexOf(delim);\n if (delimIdx === -1) {\n return { stdout: output, stderr: '', exitCode: 0, durationMs: Date.now() - startTime };\n }\n const after = output.substring(delimIdx + delim.length);\n const newlineIdx = after.indexOf('\\n');\n const exitCode = parseInt(newlineIdx === -1 ? after : after.substring(0, newlineIdx), 10) || 0;\n const stderr = newlineIdx === -1 ? '' : after.substring(newlineIdx + 1);\n const stdout = output.substring(0, delimIdx).replace(/\\n$/, '');\n return { stdout, stderr, exitCode, 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: CodesandboxSandbox): Promise<InstanceInfo> => ({\n id: sandbox.id,\n provider: 'codesandbox',\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: { cluster: sandbox.cluster, bootupType: sandbox.bootupType, isUpToDate: sandbox.isUpToDate }\n }),\n\n getUrl: async (sandbox: CodesandboxSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n const protocol = options.protocol || 'https';\n return `${protocol}://${sandbox.id}.${sandbox.cluster}.csb.app:${options.port}`;\n },\n\n filesystem: {\n readFile: async (sandbox: CodesandboxSandbox, path: string): Promise<string> => {\n const client = await sandbox.connect();\n return client.fs.readTextFile(path);\n },\n writeFile: async (sandbox: CodesandboxSandbox, path: string, content: string): Promise<void> => {\n const client = await sandbox.connect();\n await client.fs.writeTextFile(path, content);\n },\n mkdir: async (sandbox: CodesandboxSandbox, path: string): Promise<void> => {\n const client = await sandbox.connect();\n await client.commands.run(`mkdir -p \"${path}\"`);\n },\n readdir: async (sandbox: CodesandboxSandbox, path: string): Promise<FileEntry[]> => {\n const client = await sandbox.connect();\n const entries = await client.fs.readdir(path);\n return entries.map((entry: any) => ({\n name: entry.name,\n type: entry.isDirectory ? 'directory' as const : 'file' as const,\n size: entry.size || 0,\n modified: entry.lastModified ? new Date(entry.lastModified) : new Date()\n }));\n },\n exists: async (sandbox: CodesandboxSandbox, path: string): Promise<boolean> => {\n const client = await sandbox.connect();\n try { await client.commands.run(`ls \"${path}\"`); return true; } catch { return false; }\n },\n remove: async (sandbox: CodesandboxSandbox, path: string): Promise<void> => {\n const client = await sandbox.connect();\n await client.fs.remove(path);\n }\n },\n\n getInstance: (sandbox: CodesandboxSandbox): CodesandboxSandbox => sandbox,\n },\n\n snapshot: {\n create: async (config: CodesandboxConfig, sandboxId: string, options?: { name?: string }) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n if (!apiKey) throw new Error(`Missing CodeSandbox API key.`);\n const sdk = new CodeSandbox(apiKey);\n try {\n const sandbox = await sdk.sandboxes.resume(sandboxId);\n await sdk.sandboxes.hibernate(sandboxId);\n return { id: sandbox.id, provider: 'codesandbox', createdAt: new Date(), metadata: { name: options?.name, bootupType: sandbox.bootupType } };\n } catch (error) {\n throw new Error(`Failed to create CodeSandbox snapshot: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n list: async (_config: CodesandboxConfig) => { throw new Error(`CodeSandbox provider does not support listing snapshots.`); },\n delete: async (config: CodesandboxConfig, snapshotId: string) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n if (!apiKey) throw new Error(`Missing CodeSandbox API key.`);\n const sdk = new CodeSandbox(apiKey);\n try { await sdk.sandboxes.shutdown(snapshotId); } catch { /* ignore */ }\n }\n },\n\n template: {\n create: async (_config: CodesandboxConfig, _options: { name: string }) => {\n throw new Error(`CodeSandbox templates must be created via the dashboard.`);\n },\n list: async (_config: CodesandboxConfig) => { throw new Error(`CodeSandbox provider does not support listing templates via API.`); },\n delete: async (_config: CodesandboxConfig, _templateId: string) => { throw new Error(`CodeSandbox templates must be deleted via the dashboard.`); }\n }\n }\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Codesandbox Provider - Factory-based Implementation\n */\n\nimport { CodeSandbox } from '@codesandbox/sdk';\nimport type { Sandbox as CodesandboxNativeSandbox, SandboxClient } from '@codesandbox/sdk';\nimport { defineProvider } from '@computesdk/provider';\n\nimport type { CommandResult, InstanceInfo, CreateInstanceOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\nexport interface CodesandboxConfig {\n /** CodeSandbox API key - if not provided, will fallback to CSB_API_KEY environment variable */\n apiKey?: string;\n /** Template to use for new sandboxes */\n templateId?: string;\n /** Default runtime environment (e.g. 'node', 'python') */\n runtime?: string;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * The CodeSandbox SDK sandbox, plus `pause()` (hibernate: memory and disk are\n * kept) and `resume()` (wake the same sandbox id).\n */\nexport type CodesandboxSandbox = CodesandboxNativeSandbox & {\n pause(): Promise<void>;\n resume(): Promise<void>;\n};\n\n/** Tag carried by sandboxes that serve as snapshots (hibernated forks). */\nconst SNAPSHOT_TAG = 'computesdk-snapshot';\n\ninterface SandboxState {\n sdk: CodeSandbox;\n /** Latest SDK handle for this sandbox id (replaced on resume). */\n current: CodesandboxNativeSandbox;\n client?: Promise<SandboxClient>;\n}\n\nconst states = new WeakMap<CodesandboxNativeSandbox, SandboxState>();\n/** Tracked states by sandbox id, so a snapshot can refresh its source's session. */\nconst statesById = new Map<string, SandboxState>();\n/** Open clients by sandbox id, so destroy can close the session before deleting. */\nconst openClients = new Map<string, Promise<SandboxClient>>();\n\nfunction resolveApiKey(config: CodesandboxConfig): string {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n if (!apiKey) {\n throw new Error(`Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable.`);\n }\n return apiKey;\n}\n\nfunction sdkFor(config: CodesandboxConfig): CodeSandbox {\n return new CodeSandbox(resolveApiKey(config));\n}\n\nasync function closeClient(sandboxId: string): Promise<void> {\n const client = openClients.get(sandboxId);\n if (!client) return;\n openClients.delete(sandboxId);\n try {\n const open = await client;\n await open.disconnect().catch(() => undefined);\n open.dispose();\n } catch { /* already gone */ }\n}\n\nfunction track(sdk: CodeSandbox, native: CodesandboxNativeSandbox): CodesandboxSandbox {\n const state: SandboxState = { sdk, current: native };\n states.set(native, state);\n statesById.set(native.id, state);\n const sandbox = native as CodesandboxSandbox;\n Object.defineProperty(sandbox, 'pause', {\n configurable: true,\n value: async () => {\n await closeClient(sandbox.id);\n state.client = undefined;\n await sdk.sandboxes.hibernate(sandbox.id);\n },\n });\n Object.defineProperty(sandbox, 'resume', {\n configurable: true,\n value: async () => {\n await closeClient(sandbox.id);\n state.client = undefined;\n state.current = await sdk.sandboxes.resume(sandbox.id);\n },\n });\n return sandbox;\n}\n\n/** Reopens a running sandbox's session with fresh connection details. */\nasync function refreshSession(sandboxId: string): Promise<void> {\n await closeClient(sandboxId);\n const state = statesById.get(sandboxId);\n if (!state) return;\n state.client = undefined;\n state.current = await state.sdk.sandboxes.resume(sandboxId);\n}\n\nfunction getClient(sandbox: CodesandboxNativeSandbox): Promise<SandboxClient> {\n const state = states.get(sandbox);\n if (!state) return sandbox.connect();\n if (state.client && openClients.get(sandbox.id) !== state.client) state.client = undefined;\n if (!state.client) {\n const client = state.current.connect();\n state.client = client;\n openClients.set(sandbox.id, client);\n client.catch(() => {\n if (state.client === client) state.client = undefined;\n if (openClients.get(sandbox.id) === client) openClients.delete(sandbox.id);\n });\n }\n return state.client;\n}\n\nfunction shQuote(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nfunction randomToken(): string {\n return `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Exit code `timeout(1)` reports when it stops a command. */\nconst TIMEOUT_EXIT_CODE = 124;\n\n/**\n * `commands.run` executes in a terminal: stdout and stdin are a TTY, stdout and\n * stderr are merged with CRLF line endings, a non-zero exit throws with the\n * output dropped, and a command that finishes before the SDK subscribes to it\n * can lose its output or never report its exit. So the\n * command runs with stdin from /dev/null and stdout and stderr captured to\n * files; the exit code and base64 of both streams are written between two\n * markers to a result file, which is printed and, if the printed copy is\n * missing, read back; the file appearing also counts as completion. The marker is printed in two pieces so it never appears\n * verbatim in the command text.\n */\nfunction wrapCommand(command: string, token: string, timeoutMs?: number): string {\n const out = `/tmp/.computesdk-${token}.out`;\n const err = `/tmp/.computesdk-${token}.err`;\n const marker = `'__CSDK_' '${token}__'`;\n const body = timeoutMs && timeoutMs > 0\n ? `if command -v timeout >/dev/null 2>&1; then timeout -k 2 ${Math.max(1, Math.ceil(timeoutMs / 1000))} bash -c ${shQuote(command)}; else bash -c ${shQuote(command)}; fi`\n : command;\n return [\n `(\\n${body}\\n) </dev/null >${out} 2>${err}; __csdk_ec=$?`,\n `{ printf '%s%s%s:' ${marker} \"$__csdk_ec\"; base64 ${out} | tr -d '\\\\n'; printf ':'; base64 ${err} | tr -d '\\\\n'; printf '%s%s' ${marker}; } >${resultPath(token)}.tmp`,\n `mv -f ${resultPath(token)}.tmp ${resultPath(token)}; rm -f ${out} ${err}; cat ${resultPath(token)}`,\n ].join('; ');\n}\n\nfunction resultPath(token: string): string {\n return `/tmp/.computesdk-${token}.res`;\n}\n\nfunction parseWrapped(output: string, marker: string): { stdout: string; stderr: string; exitCode: number } | undefined {\n const flat = output.replace(/[\\r\\n]/g, '');\n const start = flat.indexOf(marker);\n if (start === -1) return undefined;\n const end = flat.indexOf(marker, start + marker.length);\n if (end === -1) return undefined;\n const [code, out = '', err = ''] = flat.slice(start + marker.length, end).split(':');\n const exitCode = Number.parseInt(code, 10);\n if (!Number.isFinite(exitCode)) return undefined;\n return {\n stdout: Buffer.from(out, 'base64').toString('utf8'),\n stderr: Buffer.from(err, 'base64').toString('utf8'),\n exitCode,\n };\n}\n\n/** The session failed before the command started, so it is safe to retry. */\nclass SessionError extends Error {\n constructor(cause: unknown) {\n super(cause instanceof Error ? cause.message : String(cause));\n }\n}\n\n/**\n * Runs a wrapped command and resolves with its printed output once the SDK\n * reports it finished or its result file exists (`''` if only the file did),\n * or `undefined` past `timeoutMs`.\n */\nasync function runToCompletion(\n client: SandboxClient,\n wrapped: string,\n runOpts: { env?: Record<string, string>; cwd?: string },\n resultFile: string,\n timeoutMs?: number,\n): Promise<string | undefined> {\n const cmd = await client.commands.runBackground(wrapped, runOpts).catch((error) => { throw new SessionError(error); });\n let settled = false;\n const finished = cmd.waitUntilComplete().then(\n (output) => output,\n (error) => (typeof (error as any)?.output === 'string' ? (error as any).output : ''),\n );\n const polled = (async () => {\n for (let delay = 100; !settled; delay = Math.min(delay * 2, 1000)) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n if (settled) break;\n const exists = await client.fs.stat(resultFile).then(() => true, () => false);\n if (exists) {\n // The SDK missed the exit; drop its shell so its listeners go too.\n cmd.kill().catch(() => undefined);\n return '';\n }\n }\n return '';\n })();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const deadline = timeoutMs === undefined\n ? undefined\n : new Promise<undefined>((resolve) => { timer = setTimeout(() => resolve(undefined), timeoutMs); });\n try {\n return await Promise.race([finished, polled, ...(deadline ? [deadline] : [])]);\n } finally {\n settled = true;\n clearTimeout(timer);\n }\n}\n\nexport const codesandbox = defineProvider<CodesandboxSandbox, CodesandboxConfig, any, any>({\n name: 'codesandbox',\n methods: {\n instances: {\n create: async (config: CodesandboxConfig, options?: CreateInstanceOptions) => {\n const sdk = sdkFor(config);\n try {\n const {\n timeout: _timeout, envs, name: _name, metadata: _metadata,\n templateId: optTemplateId, snapshotId, sandboxId: _sandboxId,\n namespace: _namespace, directory: _directory, ...providerOptions\n } = options || {};\n const createOptions: any = { ...providerOptions };\n // A snapshot is a hibernated fork: restoring forks it again, so the\n // snapshot stays reusable and every restore is a new sandbox.\n const templateId = snapshotId || optTemplateId || config.templateId;\n if (templateId) createOptions.id = templateId;\n if (envs && Object.keys(envs).length > 0) createOptions.envVars = envs;\n const sandbox = await sdk.sandboxes.create(createOptions);\n return { instance: track(sdk, sandbox), instanceId: sandbox.id };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (/unauthori[sz]ed|API key/i.test(message)) {\n throw new Error(`CodeSandbox authentication failed. Please check your CSB_API_KEY environment variable. (${message})`);\n }\n throw new Error(`Failed to create CodeSandbox sandbox: ${message}`);\n }\n },\n\n getById: async (config: CodesandboxConfig, sandboxId: string) => {\n const sdk = sdkFor(config);\n try {\n const sandbox = await sdk.sandboxes.resume(sandboxId);\n return { instance: track(sdk, sandbox), instanceId: sandboxId };\n } catch { return null; }\n },\n\n list: async (_config: CodesandboxConfig) => {\n throw new Error(`CodeSandbox provider does not support listing sandboxes.`);\n },\n\n destroy: async (config: CodesandboxConfig, sandboxId: string) => {\n const sdk = sdkFor(config);\n // Deleting a running VM intermittently fails with \"An unexpected error\n // occurred\", so close our session and shut the VM down first, then retry.\n await closeClient(sandboxId);\n statesById.delete(sandboxId);\n try { await sdk.sandboxes.shutdown(sandboxId); } catch { /* delete reports the real error */ }\n let lastError: unknown;\n for (let attempt = 0; attempt < 3; attempt++) {\n try {\n await sdk.sandboxes.delete(sandboxId);\n return;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (/not found|404/i.test(message)) return;\n lastError = error;\n await new Promise((resolve) => setTimeout(resolve, 2000 * (attempt + 1)));\n }\n }\n const message = lastError instanceof Error ? lastError.message : String(lastError);\n throw new Error(`Failed to delete CodeSandbox sandbox \"${sandboxId}\": ${message}`);\n },\n\n runCommand: async (sandbox: CodesandboxSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n const runOpts: { env?: Record<string, string>; cwd?: string } = {};\n if (options?.env && Object.keys(options.env).length > 0) runOpts.env = options.env;\n if (options?.cwd) runOpts.cwd = options.cwd;\n const run = async (): Promise<CommandResult> => {\n const client = await getClient(sandbox).catch((error) => { throw new SessionError(error); });\n if (options?.background) {\n await client.commands.runBackground(`setsid bash -c ${shQuote(command)} </dev/null >/dev/null 2>&1 &`, runOpts)\n .catch((error) => { throw new SessionError(error); });\n return { stdout: '', stderr: '', exitCode: 0, durationMs: Date.now() - startTime };\n }\n const token = randomToken();\n const marker = `__CSDK_${token}__`;\n const clientTimeoutMs = options?.timeout && options.timeout > 0 ? options.timeout + 10_000 : undefined;\n const output = await runToCompletion(client, wrapCommand(command, token, options?.timeout), runOpts, resultPath(token), clientTimeoutMs);\n if (output === undefined) {\n return { stdout: '', stderr: `Command timed out after ${options!.timeout}ms`, exitCode: TIMEOUT_EXIT_CODE, durationMs: Date.now() - startTime };\n }\n let parsed = parseWrapped(output, marker);\n if (!parsed) {\n const saved = await client.fs.readTextFile(resultPath(token)).catch(() => undefined);\n parsed = saved === undefined ? undefined : parseWrapped(saved, marker);\n }\n client.fs.remove(resultPath(token)).catch(() => undefined);\n if (!parsed) {\n return { stdout: output.replace(/\\r\\n/g, '\\n'), stderr: '', exitCode: 0, durationMs: Date.now() - startTime };\n }\n return { ...parsed, durationMs: Date.now() - startTime };\n };\n try {\n try {\n return await run();\n } catch (error) {\n if (!(error instanceof SessionError)) throw error;\n // A stale session, e.g. after the VM was suspended: reconnect once.\n await refreshSession(sandbox.id);\n return await run();\n }\n } catch (error) {\n const exitCode = typeof (error as any)?.exitCode === 'number' ? (error as any).exitCode : 127;\n return { stdout: '', stderr: error instanceof Error ? error.message : String(error), exitCode, durationMs: Date.now() - startTime };\n }\n },\n\n getInfo: async (sandbox: CodesandboxSandbox): Promise<InstanceInfo> => ({\n id: sandbox.id,\n provider: 'codesandbox',\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: { cluster: sandbox.cluster, bootupType: sandbox.bootupType, isUpToDate: sandbox.isUpToDate }\n }),\n\n getUrl: async (sandbox: CodesandboxSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n const protocol = options.protocol || 'https';\n return `${protocol}://${sandbox.id}.${sandbox.cluster}.csb.app:${options.port}`;\n },\n\n filesystem: {\n readFile: async (sandbox: CodesandboxSandbox, path: string): Promise<string> => {\n const client = await getClient(sandbox);\n return client.fs.readTextFile(path);\n },\n writeFile: async (sandbox: CodesandboxSandbox, path: string, content: string): Promise<void> => {\n const client = await getClient(sandbox);\n await client.fs.writeTextFile(path, content);\n },\n mkdir: async (sandbox: CodesandboxSandbox, path: string): Promise<void> => {\n const client = await getClient(sandbox);\n await client.fs.mkdir(path, true);\n },\n readdir: async (sandbox: CodesandboxSandbox, path: string): Promise<FileEntry[]> => {\n const client = await getClient(sandbox);\n const entries = await client.fs.readdir(path);\n return entries.map((entry) => ({\n name: entry.name,\n type: entry.type === 'directory' ? 'directory' as const : 'file' as const,\n size: 0,\n modified: new Date()\n }));\n },\n exists: async (sandbox: CodesandboxSandbox, path: string): Promise<boolean> => {\n const client = await getClient(sandbox);\n try { await client.fs.stat(path); return true; } catch { return false; }\n },\n remove: async (sandbox: CodesandboxSandbox, path: string): Promise<void> => {\n const client = await getClient(sandbox);\n await client.fs.remove(path, true);\n }\n },\n\n // Hibernate keeps the VM's memory and disk; resume wakes the same sandbox id.\n pause: (sandbox: CodesandboxSandbox) => sandbox.pause(),\n resume: (sandbox: CodesandboxSandbox) => sandbox.resume(),\n pauseCapabilities: { memory: true },\n\n getInstance: (sandbox: CodesandboxSandbox): CodesandboxSandbox => sandbox,\n },\n\n snapshot: {\n // A fork of the running sandbox (memory, processes and disk), hibernated\n // so it persists as a restore point independent of the source.\n create: async (config: CodesandboxConfig, sandboxId: string, options?: { name?: string }) => {\n const sdk = sdkFor(config);\n try {\n const fork = await sdk.sandboxes.create({\n id: sandboxId,\n tags: [SNAPSHOT_TAG],\n ...(options?.name ? { title: options.name } : {}),\n });\n await sdk.sandboxes.hibernate(fork.id);\n // Forking suspends and resumes the source VM, which can drop its session.\n await refreshSession(sandboxId);\n return { id: fork.id, provider: 'codesandbox', createdAt: new Date(), metadata: { name: options?.name, sourceSandboxId: sandboxId } };\n } catch (error) {\n throw new Error(`Failed to create CodeSandbox snapshot: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n list: async (config: CodesandboxConfig) => {\n const sdk = sdkFor(config);\n const { sandboxes } = await sdk.sandboxes.list({ tags: [SNAPSHOT_TAG] });\n return sandboxes\n .filter((s) => s.tags?.includes(SNAPSHOT_TAG))\n .map((s) => ({ id: s.id, provider: 'codesandbox', createdAt: s.createdAt, metadata: { name: s.title } }));\n },\n delete: async (config: CodesandboxConfig, snapshotId: string) => {\n const sdk = sdkFor(config);\n try {\n await sdk.sandboxes.delete(snapshotId);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (!/not found|404/i.test(message)) {\n throw new Error(`Failed to delete CodeSandbox snapshot \"${snapshotId}\": ${message}`);\n }\n }\n },\n // Forks keep the whole VM, memory and /tmp included; the source keeps\n // running, and each restore is an independent fork of the snapshot.\n capabilities: { scope: 'rootfs', memory: true, destroysSource: false, source: 'kept', fork: true, readiness: 'immediate' },\n },\n\n template: {\n create: async (_config: CodesandboxConfig, _options: { name: string }) => {\n throw new Error(`CodeSandbox templates must be created via the dashboard.`);\n },\n list: async (_config: CodesandboxConfig) => { throw new Error(`CodeSandbox provider does not support listing templates via API.`); },\n delete: async (_config: CodesandboxConfig, _templateId: string) => { throw new Error(`CodeSandbox templates must be deleted via the dashboard.`); }\n }\n }\n});\n"],"mappings":"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","names":["message"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,62 +1,189 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import { CodeSandbox } from "@codesandbox/sdk";
|
|
3
|
-
import { defineProvider
|
|
3
|
+
import { defineProvider } from "@computesdk/provider";
|
|
4
|
+
var SNAPSHOT_TAG = "computesdk-snapshot";
|
|
5
|
+
var states = /* @__PURE__ */ new WeakMap();
|
|
6
|
+
var statesById = /* @__PURE__ */ new Map();
|
|
7
|
+
var openClients = /* @__PURE__ */ new Map();
|
|
8
|
+
function resolveApiKey(config) {
|
|
9
|
+
const apiKey = config.apiKey || typeof process !== "undefined" && process.env?.CSB_API_KEY || "";
|
|
10
|
+
if (!apiKey) {
|
|
11
|
+
throw new Error(`Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable.`);
|
|
12
|
+
}
|
|
13
|
+
return apiKey;
|
|
14
|
+
}
|
|
15
|
+
function sdkFor(config) {
|
|
16
|
+
return new CodeSandbox(resolveApiKey(config));
|
|
17
|
+
}
|
|
18
|
+
async function closeClient(sandboxId) {
|
|
19
|
+
const client = openClients.get(sandboxId);
|
|
20
|
+
if (!client) return;
|
|
21
|
+
openClients.delete(sandboxId);
|
|
22
|
+
try {
|
|
23
|
+
const open = await client;
|
|
24
|
+
await open.disconnect().catch(() => void 0);
|
|
25
|
+
open.dispose();
|
|
26
|
+
} catch {
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function track(sdk, native) {
|
|
30
|
+
const state = { sdk, current: native };
|
|
31
|
+
states.set(native, state);
|
|
32
|
+
statesById.set(native.id, state);
|
|
33
|
+
const sandbox = native;
|
|
34
|
+
Object.defineProperty(sandbox, "pause", {
|
|
35
|
+
configurable: true,
|
|
36
|
+
value: async () => {
|
|
37
|
+
await closeClient(sandbox.id);
|
|
38
|
+
state.client = void 0;
|
|
39
|
+
await sdk.sandboxes.hibernate(sandbox.id);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(sandbox, "resume", {
|
|
43
|
+
configurable: true,
|
|
44
|
+
value: async () => {
|
|
45
|
+
await closeClient(sandbox.id);
|
|
46
|
+
state.client = void 0;
|
|
47
|
+
state.current = await sdk.sandboxes.resume(sandbox.id);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return sandbox;
|
|
51
|
+
}
|
|
52
|
+
async function refreshSession(sandboxId) {
|
|
53
|
+
await closeClient(sandboxId);
|
|
54
|
+
const state = statesById.get(sandboxId);
|
|
55
|
+
if (!state) return;
|
|
56
|
+
state.client = void 0;
|
|
57
|
+
state.current = await state.sdk.sandboxes.resume(sandboxId);
|
|
58
|
+
}
|
|
59
|
+
function getClient(sandbox) {
|
|
60
|
+
const state = states.get(sandbox);
|
|
61
|
+
if (!state) return sandbox.connect();
|
|
62
|
+
if (state.client && openClients.get(sandbox.id) !== state.client) state.client = void 0;
|
|
63
|
+
if (!state.client) {
|
|
64
|
+
const client = state.current.connect();
|
|
65
|
+
state.client = client;
|
|
66
|
+
openClients.set(sandbox.id, client);
|
|
67
|
+
client.catch(() => {
|
|
68
|
+
if (state.client === client) state.client = void 0;
|
|
69
|
+
if (openClients.get(sandbox.id) === client) openClients.delete(sandbox.id);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return state.client;
|
|
73
|
+
}
|
|
74
|
+
function shQuote(value) {
|
|
75
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
76
|
+
}
|
|
77
|
+
function randomToken() {
|
|
78
|
+
return `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;
|
|
79
|
+
}
|
|
80
|
+
var TIMEOUT_EXIT_CODE = 124;
|
|
81
|
+
function wrapCommand(command, token, timeoutMs) {
|
|
82
|
+
const out = `/tmp/.computesdk-${token}.out`;
|
|
83
|
+
const err = `/tmp/.computesdk-${token}.err`;
|
|
84
|
+
const marker = `'__CSDK_' '${token}__'`;
|
|
85
|
+
const body = timeoutMs && timeoutMs > 0 ? `if command -v timeout >/dev/null 2>&1; then timeout -k 2 ${Math.max(1, Math.ceil(timeoutMs / 1e3))} bash -c ${shQuote(command)}; else bash -c ${shQuote(command)}; fi` : command;
|
|
86
|
+
return [
|
|
87
|
+
`(
|
|
88
|
+
${body}
|
|
89
|
+
) </dev/null >${out} 2>${err}; __csdk_ec=$?`,
|
|
90
|
+
`{ printf '%s%s%s:' ${marker} "$__csdk_ec"; base64 ${out} | tr -d '\\n'; printf ':'; base64 ${err} | tr -d '\\n'; printf '%s%s' ${marker}; } >${resultPath(token)}.tmp`,
|
|
91
|
+
`mv -f ${resultPath(token)}.tmp ${resultPath(token)}; rm -f ${out} ${err}; cat ${resultPath(token)}`
|
|
92
|
+
].join("; ");
|
|
93
|
+
}
|
|
94
|
+
function resultPath(token) {
|
|
95
|
+
return `/tmp/.computesdk-${token}.res`;
|
|
96
|
+
}
|
|
97
|
+
function parseWrapped(output, marker) {
|
|
98
|
+
const flat = output.replace(/[\r\n]/g, "");
|
|
99
|
+
const start = flat.indexOf(marker);
|
|
100
|
+
if (start === -1) return void 0;
|
|
101
|
+
const end = flat.indexOf(marker, start + marker.length);
|
|
102
|
+
if (end === -1) return void 0;
|
|
103
|
+
const [code, out = "", err = ""] = flat.slice(start + marker.length, end).split(":");
|
|
104
|
+
const exitCode = Number.parseInt(code, 10);
|
|
105
|
+
if (!Number.isFinite(exitCode)) return void 0;
|
|
106
|
+
return {
|
|
107
|
+
stdout: Buffer.from(out, "base64").toString("utf8"),
|
|
108
|
+
stderr: Buffer.from(err, "base64").toString("utf8"),
|
|
109
|
+
exitCode
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
var SessionError = class extends Error {
|
|
113
|
+
constructor(cause) {
|
|
114
|
+
super(cause instanceof Error ? cause.message : String(cause));
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
async function runToCompletion(client, wrapped, runOpts, resultFile, timeoutMs) {
|
|
118
|
+
const cmd = await client.commands.runBackground(wrapped, runOpts).catch((error) => {
|
|
119
|
+
throw new SessionError(error);
|
|
120
|
+
});
|
|
121
|
+
let settled = false;
|
|
122
|
+
const finished = cmd.waitUntilComplete().then(
|
|
123
|
+
(output) => output,
|
|
124
|
+
(error) => typeof error?.output === "string" ? error.output : ""
|
|
125
|
+
);
|
|
126
|
+
const polled = (async () => {
|
|
127
|
+
for (let delay = 100; !settled; delay = Math.min(delay * 2, 1e3)) {
|
|
128
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
129
|
+
if (settled) break;
|
|
130
|
+
const exists = await client.fs.stat(resultFile).then(() => true, () => false);
|
|
131
|
+
if (exists) {
|
|
132
|
+
cmd.kill().catch(() => void 0);
|
|
133
|
+
return "";
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return "";
|
|
137
|
+
})();
|
|
138
|
+
let timer;
|
|
139
|
+
const deadline = timeoutMs === void 0 ? void 0 : new Promise((resolve) => {
|
|
140
|
+
timer = setTimeout(() => resolve(void 0), timeoutMs);
|
|
141
|
+
});
|
|
142
|
+
try {
|
|
143
|
+
return await Promise.race([finished, polled, ...deadline ? [deadline] : []]);
|
|
144
|
+
} finally {
|
|
145
|
+
settled = true;
|
|
146
|
+
clearTimeout(timer);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
4
149
|
var codesandbox = defineProvider({
|
|
5
150
|
name: "codesandbox",
|
|
6
151
|
methods: {
|
|
7
152
|
instances: {
|
|
8
153
|
create: async (config, options) => {
|
|
9
|
-
const
|
|
10
|
-
if (!apiKey) {
|
|
11
|
-
throw new Error(`Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable.`);
|
|
12
|
-
}
|
|
13
|
-
const sdk = new CodeSandbox(apiKey);
|
|
154
|
+
const sdk = sdkFor(config);
|
|
14
155
|
try {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const createOptions = { ...providerOptions };
|
|
34
|
-
const templateId = optTemplateId || config.templateId;
|
|
35
|
-
if (templateId) createOptions.id = templateId;
|
|
36
|
-
if (envs && Object.keys(envs).length > 0) createOptions.envVars = envs;
|
|
37
|
-
sandbox = await sdk.sandboxes.create(createOptions);
|
|
38
|
-
sandboxId = sandbox.id;
|
|
39
|
-
}
|
|
40
|
-
return { instance: sandbox, instanceId: sandboxId };
|
|
156
|
+
const {
|
|
157
|
+
timeout: _timeout,
|
|
158
|
+
envs,
|
|
159
|
+
name: _name,
|
|
160
|
+
metadata: _metadata,
|
|
161
|
+
templateId: optTemplateId,
|
|
162
|
+
snapshotId,
|
|
163
|
+
sandboxId: _sandboxId,
|
|
164
|
+
namespace: _namespace,
|
|
165
|
+
directory: _directory,
|
|
166
|
+
...providerOptions
|
|
167
|
+
} = options || {};
|
|
168
|
+
const createOptions = { ...providerOptions };
|
|
169
|
+
const templateId = snapshotId || optTemplateId || config.templateId;
|
|
170
|
+
if (templateId) createOptions.id = templateId;
|
|
171
|
+
if (envs && Object.keys(envs).length > 0) createOptions.envVars = envs;
|
|
172
|
+
const sandbox = await sdk.sandboxes.create(createOptions);
|
|
173
|
+
return { instance: track(sdk, sandbox), instanceId: sandbox.id };
|
|
41
174
|
} catch (error) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
if (error.message.includes("quota") || error.message.includes("limit")) {
|
|
47
|
-
throw new Error(`CodeSandbox quota exceeded. Please check your usage at https://codesandbox.io/dashboard`);
|
|
48
|
-
}
|
|
175
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
176
|
+
if (/unauthori[sz]ed|API key/i.test(message)) {
|
|
177
|
+
throw new Error(`CodeSandbox authentication failed. Please check your CSB_API_KEY environment variable. (${message})`);
|
|
49
178
|
}
|
|
50
|
-
throw new Error(`Failed to create CodeSandbox sandbox: ${
|
|
179
|
+
throw new Error(`Failed to create CodeSandbox sandbox: ${message}`);
|
|
51
180
|
}
|
|
52
181
|
},
|
|
53
182
|
getById: async (config, sandboxId) => {
|
|
54
|
-
const
|
|
55
|
-
if (!apiKey) throw new Error(`Missing CodeSandbox API key.`);
|
|
56
|
-
const sdk = new CodeSandbox(apiKey);
|
|
183
|
+
const sdk = sdkFor(config);
|
|
57
184
|
try {
|
|
58
185
|
const sandbox = await sdk.sandboxes.resume(sandboxId);
|
|
59
|
-
return { instance: sandbox, instanceId: sandboxId };
|
|
186
|
+
return { instance: track(sdk, sandbox), instanceId: sandboxId };
|
|
60
187
|
} catch {
|
|
61
188
|
return null;
|
|
62
189
|
}
|
|
@@ -65,49 +192,72 @@ var codesandbox = defineProvider({
|
|
|
65
192
|
throw new Error(`CodeSandbox provider does not support listing sandboxes.`);
|
|
66
193
|
},
|
|
67
194
|
destroy: async (config, sandboxId) => {
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
195
|
+
const sdk = sdkFor(config);
|
|
196
|
+
await closeClient(sandboxId);
|
|
197
|
+
statesById.delete(sandboxId);
|
|
71
198
|
try {
|
|
72
199
|
await sdk.sandboxes.shutdown(sandboxId);
|
|
73
200
|
} catch {
|
|
74
201
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
202
|
+
let lastError;
|
|
203
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
204
|
+
try {
|
|
205
|
+
await sdk.sandboxes.delete(sandboxId);
|
|
206
|
+
return;
|
|
207
|
+
} catch (error) {
|
|
208
|
+
const message2 = error instanceof Error ? error.message : String(error);
|
|
209
|
+
if (/not found|404/i.test(message2)) return;
|
|
210
|
+
lastError = error;
|
|
211
|
+
await new Promise((resolve) => setTimeout(resolve, 2e3 * (attempt + 1)));
|
|
81
212
|
}
|
|
82
213
|
}
|
|
214
|
+
const message = lastError instanceof Error ? lastError.message : String(lastError);
|
|
215
|
+
throw new Error(`Failed to delete CodeSandbox sandbox "${sandboxId}": ${message}`);
|
|
83
216
|
},
|
|
84
217
|
runCommand: async (sandbox, command, options) => {
|
|
85
218
|
const startTime = Date.now();
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
219
|
+
const runOpts = {};
|
|
220
|
+
if (options?.env && Object.keys(options.env).length > 0) runOpts.env = options.env;
|
|
221
|
+
if (options?.cwd) runOpts.cwd = options.cwd;
|
|
222
|
+
const run = async () => {
|
|
223
|
+
const client = await getClient(sandbox).catch((error) => {
|
|
224
|
+
throw new SessionError(error);
|
|
225
|
+
});
|
|
226
|
+
if (options?.background) {
|
|
227
|
+
await client.commands.runBackground(`setsid bash -c ${shQuote(command)} </dev/null >/dev/null 2>&1 &`, runOpts).catch((error) => {
|
|
228
|
+
throw new SessionError(error);
|
|
229
|
+
});
|
|
230
|
+
return { stdout: "", stderr: "", exitCode: 0, durationMs: Date.now() - startTime };
|
|
231
|
+
}
|
|
232
|
+
const token = randomToken();
|
|
233
|
+
const marker = `__CSDK_${token}__`;
|
|
234
|
+
const clientTimeoutMs = options?.timeout && options.timeout > 0 ? options.timeout + 1e4 : void 0;
|
|
235
|
+
const output = await runToCompletion(client, wrapCommand(command, token, options?.timeout), runOpts, resultPath(token), clientTimeoutMs);
|
|
236
|
+
if (output === void 0) {
|
|
237
|
+
return { stdout: "", stderr: `Command timed out after ${options.timeout}ms`, exitCode: TIMEOUT_EXIT_CODE, durationMs: Date.now() - startTime };
|
|
238
|
+
}
|
|
239
|
+
let parsed = parseWrapped(output, marker);
|
|
240
|
+
if (!parsed) {
|
|
241
|
+
const saved = await client.fs.readTextFile(resultPath(token)).catch(() => void 0);
|
|
242
|
+
parsed = saved === void 0 ? void 0 : parseWrapped(saved, marker);
|
|
92
243
|
}
|
|
93
|
-
|
|
94
|
-
if (
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
return
|
|
244
|
+
client.fs.remove(resultPath(token)).catch(() => void 0);
|
|
245
|
+
if (!parsed) {
|
|
246
|
+
return { stdout: output.replace(/\r\n/g, "\n"), stderr: "", exitCode: 0, durationMs: Date.now() - startTime };
|
|
247
|
+
}
|
|
248
|
+
return { ...parsed, durationMs: Date.now() - startTime };
|
|
249
|
+
};
|
|
250
|
+
try {
|
|
251
|
+
try {
|
|
252
|
+
return await run();
|
|
253
|
+
} catch (error) {
|
|
254
|
+
if (!(error instanceof SessionError)) throw error;
|
|
255
|
+
await refreshSession(sandbox.id);
|
|
256
|
+
return await run();
|
|
102
257
|
}
|
|
103
|
-
const after = output.substring(delimIdx + delim.length);
|
|
104
|
-
const newlineIdx = after.indexOf("\n");
|
|
105
|
-
const exitCode = parseInt(newlineIdx === -1 ? after : after.substring(0, newlineIdx), 10) || 0;
|
|
106
|
-
const stderr = newlineIdx === -1 ? "" : after.substring(newlineIdx + 1);
|
|
107
|
-
const stdout = output.substring(0, delimIdx).replace(/\n$/, "");
|
|
108
|
-
return { stdout, stderr, exitCode, durationMs: Date.now() - startTime };
|
|
109
258
|
} catch (error) {
|
|
110
|
-
|
|
259
|
+
const exitCode = typeof error?.exitCode === "number" ? error.exitCode : 127;
|
|
260
|
+
return { stdout: "", stderr: error instanceof Error ? error.message : String(error), exitCode, durationMs: Date.now() - startTime };
|
|
111
261
|
}
|
|
112
262
|
},
|
|
113
263
|
getInfo: async (sandbox) => ({
|
|
@@ -124,68 +274,84 @@ var codesandbox = defineProvider({
|
|
|
124
274
|
},
|
|
125
275
|
filesystem: {
|
|
126
276
|
readFile: async (sandbox, path) => {
|
|
127
|
-
const client = await sandbox
|
|
277
|
+
const client = await getClient(sandbox);
|
|
128
278
|
return client.fs.readTextFile(path);
|
|
129
279
|
},
|
|
130
280
|
writeFile: async (sandbox, path, content) => {
|
|
131
|
-
const client = await sandbox
|
|
281
|
+
const client = await getClient(sandbox);
|
|
132
282
|
await client.fs.writeTextFile(path, content);
|
|
133
283
|
},
|
|
134
284
|
mkdir: async (sandbox, path) => {
|
|
135
|
-
const client = await sandbox
|
|
136
|
-
await client.
|
|
285
|
+
const client = await getClient(sandbox);
|
|
286
|
+
await client.fs.mkdir(path, true);
|
|
137
287
|
},
|
|
138
288
|
readdir: async (sandbox, path) => {
|
|
139
|
-
const client = await sandbox
|
|
289
|
+
const client = await getClient(sandbox);
|
|
140
290
|
const entries = await client.fs.readdir(path);
|
|
141
291
|
return entries.map((entry) => ({
|
|
142
292
|
name: entry.name,
|
|
143
|
-
type: entry.
|
|
144
|
-
size:
|
|
145
|
-
modified:
|
|
293
|
+
type: entry.type === "directory" ? "directory" : "file",
|
|
294
|
+
size: 0,
|
|
295
|
+
modified: /* @__PURE__ */ new Date()
|
|
146
296
|
}));
|
|
147
297
|
},
|
|
148
298
|
exists: async (sandbox, path) => {
|
|
149
|
-
const client = await sandbox
|
|
299
|
+
const client = await getClient(sandbox);
|
|
150
300
|
try {
|
|
151
|
-
await client.
|
|
301
|
+
await client.fs.stat(path);
|
|
152
302
|
return true;
|
|
153
303
|
} catch {
|
|
154
304
|
return false;
|
|
155
305
|
}
|
|
156
306
|
},
|
|
157
307
|
remove: async (sandbox, path) => {
|
|
158
|
-
const client = await sandbox
|
|
159
|
-
await client.fs.remove(path);
|
|
308
|
+
const client = await getClient(sandbox);
|
|
309
|
+
await client.fs.remove(path, true);
|
|
160
310
|
}
|
|
161
311
|
},
|
|
312
|
+
// Hibernate keeps the VM's memory and disk; resume wakes the same sandbox id.
|
|
313
|
+
pause: (sandbox) => sandbox.pause(),
|
|
314
|
+
resume: (sandbox) => sandbox.resume(),
|
|
315
|
+
pauseCapabilities: { memory: true },
|
|
162
316
|
getInstance: (sandbox) => sandbox
|
|
163
317
|
},
|
|
164
318
|
snapshot: {
|
|
319
|
+
// A fork of the running sandbox (memory, processes and disk), hibernated
|
|
320
|
+
// so it persists as a restore point independent of the source.
|
|
165
321
|
create: async (config, sandboxId, options) => {
|
|
166
|
-
const
|
|
167
|
-
if (!apiKey) throw new Error(`Missing CodeSandbox API key.`);
|
|
168
|
-
const sdk = new CodeSandbox(apiKey);
|
|
322
|
+
const sdk = sdkFor(config);
|
|
169
323
|
try {
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
324
|
+
const fork = await sdk.sandboxes.create({
|
|
325
|
+
id: sandboxId,
|
|
326
|
+
tags: [SNAPSHOT_TAG],
|
|
327
|
+
...options?.name ? { title: options.name } : {}
|
|
328
|
+
});
|
|
329
|
+
await sdk.sandboxes.hibernate(fork.id);
|
|
330
|
+
await refreshSession(sandboxId);
|
|
331
|
+
return { id: fork.id, provider: "codesandbox", createdAt: /* @__PURE__ */ new Date(), metadata: { name: options?.name, sourceSandboxId: sandboxId } };
|
|
173
332
|
} catch (error) {
|
|
174
333
|
throw new Error(`Failed to create CodeSandbox snapshot: ${error instanceof Error ? error.message : String(error)}`);
|
|
175
334
|
}
|
|
176
335
|
},
|
|
177
|
-
list: async (
|
|
178
|
-
|
|
336
|
+
list: async (config) => {
|
|
337
|
+
const sdk = sdkFor(config);
|
|
338
|
+
const { sandboxes } = await sdk.sandboxes.list({ tags: [SNAPSHOT_TAG] });
|
|
339
|
+
return sandboxes.filter((s) => s.tags?.includes(SNAPSHOT_TAG)).map((s) => ({ id: s.id, provider: "codesandbox", createdAt: s.createdAt, metadata: { name: s.title } }));
|
|
179
340
|
},
|
|
180
341
|
delete: async (config, snapshotId) => {
|
|
181
|
-
const
|
|
182
|
-
if (!apiKey) throw new Error(`Missing CodeSandbox API key.`);
|
|
183
|
-
const sdk = new CodeSandbox(apiKey);
|
|
342
|
+
const sdk = sdkFor(config);
|
|
184
343
|
try {
|
|
185
|
-
await sdk.sandboxes.
|
|
186
|
-
} catch {
|
|
344
|
+
await sdk.sandboxes.delete(snapshotId);
|
|
345
|
+
} catch (error) {
|
|
346
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
347
|
+
if (!/not found|404/i.test(message)) {
|
|
348
|
+
throw new Error(`Failed to delete CodeSandbox snapshot "${snapshotId}": ${message}`);
|
|
349
|
+
}
|
|
187
350
|
}
|
|
188
|
-
}
|
|
351
|
+
},
|
|
352
|
+
// Forks keep the whole VM, memory and /tmp included; the source keeps
|
|
353
|
+
// running, and each restore is an independent fork of the snapshot.
|
|
354
|
+
capabilities: { scope: "rootfs", memory: true, destroysSource: false, source: "kept", fork: true, readiness: "immediate" }
|
|
189
355
|
},
|
|
190
356
|
template: {
|
|
191
357
|
create: async (_config, _options) => {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Codesandbox Provider - Factory-based Implementation\n */\n\nimport { CodeSandbox } from '@codesandbox/sdk';\nimport type { Sandbox as CodesandboxSandbox } from '@codesandbox/sdk';\nimport { defineProvider, escapeShellArg } from '@computesdk/provider';\n\nimport type { CommandResult, InstanceInfo, CreateInstanceOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\nexport interface CodesandboxConfig {\n /** CodeSandbox API key - if not provided, will fallback to CSB_API_KEY environment variable */\n apiKey?: string;\n /** Template to use for new sandboxes */\n templateId?: string;\n /** Default runtime environment (e.g. 'node', 'python') */\n runtime?: string;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\nexport const codesandbox = defineProvider<CodesandboxSandbox, CodesandboxConfig, any, any>({\n name: 'codesandbox',\n methods: {\n instances: {\n create: async (config: CodesandboxConfig, options?: CreateInstanceOptions) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n if (!apiKey) {\n throw new Error(`Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable.`);\n }\n const sdk = new CodeSandbox(apiKey);\n try {\n let sandbox: CodesandboxSandbox;\n let sandboxId: string;\n if (options?.snapshotId) {\n sandbox = await sdk.sandboxes.resume(options.snapshotId);\n sandboxId = options.snapshotId;\n } else {\n const {\n timeout: _timeout, envs, name: _name, metadata: _metadata,\n templateId: optTemplateId, snapshotId: _snapshotId, sandboxId: _sandboxId,\n namespace: _namespace, directory: _directory, ...providerOptions\n } = options || {};\n const createOptions: any = { ...providerOptions };\n const templateId = optTemplateId || config.templateId;\n if (templateId) createOptions.id = templateId;\n if (envs && Object.keys(envs).length > 0) createOptions.envVars = envs;\n sandbox = await sdk.sandboxes.create(createOptions);\n sandboxId = sandbox.id;\n }\n return { instance: sandbox, instanceId: sandboxId };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('API key')) {\n throw new Error(`CodeSandbox authentication failed. Please check your CSB_API_KEY environment variable.`);\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(`CodeSandbox quota exceeded. Please check your usage at https://codesandbox.io/dashboard`);\n }\n }\n throw new Error(`Failed to create CodeSandbox sandbox: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n getById: async (config: CodesandboxConfig, sandboxId: string) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n if (!apiKey) throw new Error(`Missing CodeSandbox API key.`);\n const sdk = new CodeSandbox(apiKey);\n try {\n const sandbox = await sdk.sandboxes.resume(sandboxId);\n return { instance: sandbox, instanceId: sandboxId };\n } catch { return null; }\n },\n\n list: async (_config: CodesandboxConfig) => {\n throw new Error(`CodeSandbox provider does not support listing sandboxes.`);\n },\n\n destroy: async (config: CodesandboxConfig, sandboxId: string) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n if (!apiKey) throw new Error(`Missing CodeSandbox API key.`);\n const sdk = new CodeSandbox(apiKey);\n try { await sdk.sandboxes.shutdown(sandboxId); } catch { /* ignore */ }\n try {\n await sdk.sandboxes.delete(sandboxId);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (!message.includes('not found') && !message.includes('404')) {\n throw new Error(`Failed to delete CodeSandbox sandbox \"${sandboxId}\": ${message}`);\n }\n }\n },\n\n runCommand: async (sandbox: CodesandboxSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n try {\n const client = await sandbox.connect();\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(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 // commands.run returns a bare output string — capture the real exit\n // code and stderr in-band via a delimiter + stderr file.\n const errFile = `/tmp/.computesdk-stderr-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n const delim = `__COMPUTESDK_EXIT_${Date.now()}_${Math.random().toString(36).slice(2)}__`;\n const wrapped = `{ ${fullCommand} ; } 2>${escapeShellArg(errFile)}; __cs_ec=$?; echo \"${delim}$__cs_ec\"; cat ${escapeShellArg(errFile)} 2>/dev/null; rm -f ${escapeShellArg(errFile)}`;\n const output = await client.commands.run(wrapped);\n const delimIdx = output.lastIndexOf(delim);\n if (delimIdx === -1) {\n return { stdout: output, stderr: '', exitCode: 0, durationMs: Date.now() - startTime };\n }\n const after = output.substring(delimIdx + delim.length);\n const newlineIdx = after.indexOf('\\n');\n const exitCode = parseInt(newlineIdx === -1 ? after : after.substring(0, newlineIdx), 10) || 0;\n const stderr = newlineIdx === -1 ? '' : after.substring(newlineIdx + 1);\n const stdout = output.substring(0, delimIdx).replace(/\\n$/, '');\n return { stdout, stderr, exitCode, 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: CodesandboxSandbox): Promise<InstanceInfo> => ({\n id: sandbox.id,\n provider: 'codesandbox',\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: { cluster: sandbox.cluster, bootupType: sandbox.bootupType, isUpToDate: sandbox.isUpToDate }\n }),\n\n getUrl: async (sandbox: CodesandboxSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n const protocol = options.protocol || 'https';\n return `${protocol}://${sandbox.id}.${sandbox.cluster}.csb.app:${options.port}`;\n },\n\n filesystem: {\n readFile: async (sandbox: CodesandboxSandbox, path: string): Promise<string> => {\n const client = await sandbox.connect();\n return client.fs.readTextFile(path);\n },\n writeFile: async (sandbox: CodesandboxSandbox, path: string, content: string): Promise<void> => {\n const client = await sandbox.connect();\n await client.fs.writeTextFile(path, content);\n },\n mkdir: async (sandbox: CodesandboxSandbox, path: string): Promise<void> => {\n const client = await sandbox.connect();\n await client.commands.run(`mkdir -p \"${path}\"`);\n },\n readdir: async (sandbox: CodesandboxSandbox, path: string): Promise<FileEntry[]> => {\n const client = await sandbox.connect();\n const entries = await client.fs.readdir(path);\n return entries.map((entry: any) => ({\n name: entry.name,\n type: entry.isDirectory ? 'directory' as const : 'file' as const,\n size: entry.size || 0,\n modified: entry.lastModified ? new Date(entry.lastModified) : new Date()\n }));\n },\n exists: async (sandbox: CodesandboxSandbox, path: string): Promise<boolean> => {\n const client = await sandbox.connect();\n try { await client.commands.run(`ls \"${path}\"`); return true; } catch { return false; }\n },\n remove: async (sandbox: CodesandboxSandbox, path: string): Promise<void> => {\n const client = await sandbox.connect();\n await client.fs.remove(path);\n }\n },\n\n getInstance: (sandbox: CodesandboxSandbox): CodesandboxSandbox => sandbox,\n },\n\n snapshot: {\n create: async (config: CodesandboxConfig, sandboxId: string, options?: { name?: string }) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n if (!apiKey) throw new Error(`Missing CodeSandbox API key.`);\n const sdk = new CodeSandbox(apiKey);\n try {\n const sandbox = await sdk.sandboxes.resume(sandboxId);\n await sdk.sandboxes.hibernate(sandboxId);\n return { id: sandbox.id, provider: 'codesandbox', createdAt: new Date(), metadata: { name: options?.name, bootupType: sandbox.bootupType } };\n } catch (error) {\n throw new Error(`Failed to create CodeSandbox snapshot: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n list: async (_config: CodesandboxConfig) => { throw new Error(`CodeSandbox provider does not support listing snapshots.`); },\n delete: async (config: CodesandboxConfig, snapshotId: string) => {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n if (!apiKey) throw new Error(`Missing CodeSandbox API key.`);\n const sdk = new CodeSandbox(apiKey);\n try { await sdk.sandboxes.shutdown(snapshotId); } catch { /* ignore */ }\n }\n },\n\n template: {\n create: async (_config: CodesandboxConfig, _options: { name: string }) => {\n throw new Error(`CodeSandbox templates must be created via the dashboard.`);\n },\n list: async (_config: CodesandboxConfig) => { throw new Error(`CodeSandbox provider does not support listing templates via API.`); },\n delete: async (_config: CodesandboxConfig, _templateId: string) => { throw new Error(`CodeSandbox templates must be deleted via the dashboard.`); }\n }\n }\n});\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Codesandbox Provider - Factory-based Implementation\n */\n\nimport { CodeSandbox } from '@codesandbox/sdk';\nimport type { Sandbox as CodesandboxNativeSandbox, SandboxClient } from '@codesandbox/sdk';\nimport { defineProvider } from '@computesdk/provider';\n\nimport type { CommandResult, InstanceInfo, CreateInstanceOptions, FileEntry, RunCommandOptions } from '@computesdk/provider';\n\nexport interface CodesandboxConfig {\n /** CodeSandbox API key - if not provided, will fallback to CSB_API_KEY environment variable */\n apiKey?: string;\n /** Template to use for new sandboxes */\n templateId?: string;\n /** Default runtime environment (e.g. 'node', 'python') */\n runtime?: string;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * The CodeSandbox SDK sandbox, plus `pause()` (hibernate: memory and disk are\n * kept) and `resume()` (wake the same sandbox id).\n */\nexport type CodesandboxSandbox = CodesandboxNativeSandbox & {\n pause(): Promise<void>;\n resume(): Promise<void>;\n};\n\n/** Tag carried by sandboxes that serve as snapshots (hibernated forks). */\nconst SNAPSHOT_TAG = 'computesdk-snapshot';\n\ninterface SandboxState {\n sdk: CodeSandbox;\n /** Latest SDK handle for this sandbox id (replaced on resume). */\n current: CodesandboxNativeSandbox;\n client?: Promise<SandboxClient>;\n}\n\nconst states = new WeakMap<CodesandboxNativeSandbox, SandboxState>();\n/** Tracked states by sandbox id, so a snapshot can refresh its source's session. */\nconst statesById = new Map<string, SandboxState>();\n/** Open clients by sandbox id, so destroy can close the session before deleting. */\nconst openClients = new Map<string, Promise<SandboxClient>>();\n\nfunction resolveApiKey(config: CodesandboxConfig): string {\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.CSB_API_KEY) || '';\n if (!apiKey) {\n throw new Error(`Missing CodeSandbox API key. Provide 'apiKey' in config or set CSB_API_KEY environment variable.`);\n }\n return apiKey;\n}\n\nfunction sdkFor(config: CodesandboxConfig): CodeSandbox {\n return new CodeSandbox(resolveApiKey(config));\n}\n\nasync function closeClient(sandboxId: string): Promise<void> {\n const client = openClients.get(sandboxId);\n if (!client) return;\n openClients.delete(sandboxId);\n try {\n const open = await client;\n await open.disconnect().catch(() => undefined);\n open.dispose();\n } catch { /* already gone */ }\n}\n\nfunction track(sdk: CodeSandbox, native: CodesandboxNativeSandbox): CodesandboxSandbox {\n const state: SandboxState = { sdk, current: native };\n states.set(native, state);\n statesById.set(native.id, state);\n const sandbox = native as CodesandboxSandbox;\n Object.defineProperty(sandbox, 'pause', {\n configurable: true,\n value: async () => {\n await closeClient(sandbox.id);\n state.client = undefined;\n await sdk.sandboxes.hibernate(sandbox.id);\n },\n });\n Object.defineProperty(sandbox, 'resume', {\n configurable: true,\n value: async () => {\n await closeClient(sandbox.id);\n state.client = undefined;\n state.current = await sdk.sandboxes.resume(sandbox.id);\n },\n });\n return sandbox;\n}\n\n/** Reopens a running sandbox's session with fresh connection details. */\nasync function refreshSession(sandboxId: string): Promise<void> {\n await closeClient(sandboxId);\n const state = statesById.get(sandboxId);\n if (!state) return;\n state.client = undefined;\n state.current = await state.sdk.sandboxes.resume(sandboxId);\n}\n\nfunction getClient(sandbox: CodesandboxNativeSandbox): Promise<SandboxClient> {\n const state = states.get(sandbox);\n if (!state) return sandbox.connect();\n if (state.client && openClients.get(sandbox.id) !== state.client) state.client = undefined;\n if (!state.client) {\n const client = state.current.connect();\n state.client = client;\n openClients.set(sandbox.id, client);\n client.catch(() => {\n if (state.client === client) state.client = undefined;\n if (openClients.get(sandbox.id) === client) openClients.delete(sandbox.id);\n });\n }\n return state.client;\n}\n\nfunction shQuote(value: string): string {\n return `'${value.replace(/'/g, `'\\\\''`)}'`;\n}\n\nfunction randomToken(): string {\n return `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/** Exit code `timeout(1)` reports when it stops a command. */\nconst TIMEOUT_EXIT_CODE = 124;\n\n/**\n * `commands.run` executes in a terminal: stdout and stdin are a TTY, stdout and\n * stderr are merged with CRLF line endings, a non-zero exit throws with the\n * output dropped, and a command that finishes before the SDK subscribes to it\n * can lose its output or never report its exit. So the\n * command runs with stdin from /dev/null and stdout and stderr captured to\n * files; the exit code and base64 of both streams are written between two\n * markers to a result file, which is printed and, if the printed copy is\n * missing, read back; the file appearing also counts as completion. The marker is printed in two pieces so it never appears\n * verbatim in the command text.\n */\nfunction wrapCommand(command: string, token: string, timeoutMs?: number): string {\n const out = `/tmp/.computesdk-${token}.out`;\n const err = `/tmp/.computesdk-${token}.err`;\n const marker = `'__CSDK_' '${token}__'`;\n const body = timeoutMs && timeoutMs > 0\n ? `if command -v timeout >/dev/null 2>&1; then timeout -k 2 ${Math.max(1, Math.ceil(timeoutMs / 1000))} bash -c ${shQuote(command)}; else bash -c ${shQuote(command)}; fi`\n : command;\n return [\n `(\\n${body}\\n) </dev/null >${out} 2>${err}; __csdk_ec=$?`,\n `{ printf '%s%s%s:' ${marker} \"$__csdk_ec\"; base64 ${out} | tr -d '\\\\n'; printf ':'; base64 ${err} | tr -d '\\\\n'; printf '%s%s' ${marker}; } >${resultPath(token)}.tmp`,\n `mv -f ${resultPath(token)}.tmp ${resultPath(token)}; rm -f ${out} ${err}; cat ${resultPath(token)}`,\n ].join('; ');\n}\n\nfunction resultPath(token: string): string {\n return `/tmp/.computesdk-${token}.res`;\n}\n\nfunction parseWrapped(output: string, marker: string): { stdout: string; stderr: string; exitCode: number } | undefined {\n const flat = output.replace(/[\\r\\n]/g, '');\n const start = flat.indexOf(marker);\n if (start === -1) return undefined;\n const end = flat.indexOf(marker, start + marker.length);\n if (end === -1) return undefined;\n const [code, out = '', err = ''] = flat.slice(start + marker.length, end).split(':');\n const exitCode = Number.parseInt(code, 10);\n if (!Number.isFinite(exitCode)) return undefined;\n return {\n stdout: Buffer.from(out, 'base64').toString('utf8'),\n stderr: Buffer.from(err, 'base64').toString('utf8'),\n exitCode,\n };\n}\n\n/** The session failed before the command started, so it is safe to retry. */\nclass SessionError extends Error {\n constructor(cause: unknown) {\n super(cause instanceof Error ? cause.message : String(cause));\n }\n}\n\n/**\n * Runs a wrapped command and resolves with its printed output once the SDK\n * reports it finished or its result file exists (`''` if only the file did),\n * or `undefined` past `timeoutMs`.\n */\nasync function runToCompletion(\n client: SandboxClient,\n wrapped: string,\n runOpts: { env?: Record<string, string>; cwd?: string },\n resultFile: string,\n timeoutMs?: number,\n): Promise<string | undefined> {\n const cmd = await client.commands.runBackground(wrapped, runOpts).catch((error) => { throw new SessionError(error); });\n let settled = false;\n const finished = cmd.waitUntilComplete().then(\n (output) => output,\n (error) => (typeof (error as any)?.output === 'string' ? (error as any).output : ''),\n );\n const polled = (async () => {\n for (let delay = 100; !settled; delay = Math.min(delay * 2, 1000)) {\n await new Promise((resolve) => setTimeout(resolve, delay));\n if (settled) break;\n const exists = await client.fs.stat(resultFile).then(() => true, () => false);\n if (exists) {\n // The SDK missed the exit; drop its shell so its listeners go too.\n cmd.kill().catch(() => undefined);\n return '';\n }\n }\n return '';\n })();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const deadline = timeoutMs === undefined\n ? undefined\n : new Promise<undefined>((resolve) => { timer = setTimeout(() => resolve(undefined), timeoutMs); });\n try {\n return await Promise.race([finished, polled, ...(deadline ? [deadline] : [])]);\n } finally {\n settled = true;\n clearTimeout(timer);\n }\n}\n\nexport const codesandbox = defineProvider<CodesandboxSandbox, CodesandboxConfig, any, any>({\n name: 'codesandbox',\n methods: {\n instances: {\n create: async (config: CodesandboxConfig, options?: CreateInstanceOptions) => {\n const sdk = sdkFor(config);\n try {\n const {\n timeout: _timeout, envs, name: _name, metadata: _metadata,\n templateId: optTemplateId, snapshotId, sandboxId: _sandboxId,\n namespace: _namespace, directory: _directory, ...providerOptions\n } = options || {};\n const createOptions: any = { ...providerOptions };\n // A snapshot is a hibernated fork: restoring forks it again, so the\n // snapshot stays reusable and every restore is a new sandbox.\n const templateId = snapshotId || optTemplateId || config.templateId;\n if (templateId) createOptions.id = templateId;\n if (envs && Object.keys(envs).length > 0) createOptions.envVars = envs;\n const sandbox = await sdk.sandboxes.create(createOptions);\n return { instance: track(sdk, sandbox), instanceId: sandbox.id };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (/unauthori[sz]ed|API key/i.test(message)) {\n throw new Error(`CodeSandbox authentication failed. Please check your CSB_API_KEY environment variable. (${message})`);\n }\n throw new Error(`Failed to create CodeSandbox sandbox: ${message}`);\n }\n },\n\n getById: async (config: CodesandboxConfig, sandboxId: string) => {\n const sdk = sdkFor(config);\n try {\n const sandbox = await sdk.sandboxes.resume(sandboxId);\n return { instance: track(sdk, sandbox), instanceId: sandboxId };\n } catch { return null; }\n },\n\n list: async (_config: CodesandboxConfig) => {\n throw new Error(`CodeSandbox provider does not support listing sandboxes.`);\n },\n\n destroy: async (config: CodesandboxConfig, sandboxId: string) => {\n const sdk = sdkFor(config);\n // Deleting a running VM intermittently fails with \"An unexpected error\n // occurred\", so close our session and shut the VM down first, then retry.\n await closeClient(sandboxId);\n statesById.delete(sandboxId);\n try { await sdk.sandboxes.shutdown(sandboxId); } catch { /* delete reports the real error */ }\n let lastError: unknown;\n for (let attempt = 0; attempt < 3; attempt++) {\n try {\n await sdk.sandboxes.delete(sandboxId);\n return;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (/not found|404/i.test(message)) return;\n lastError = error;\n await new Promise((resolve) => setTimeout(resolve, 2000 * (attempt + 1)));\n }\n }\n const message = lastError instanceof Error ? lastError.message : String(lastError);\n throw new Error(`Failed to delete CodeSandbox sandbox \"${sandboxId}\": ${message}`);\n },\n\n runCommand: async (sandbox: CodesandboxSandbox, command: string, options?: RunCommandOptions): Promise<CommandResult> => {\n const startTime = Date.now();\n const runOpts: { env?: Record<string, string>; cwd?: string } = {};\n if (options?.env && Object.keys(options.env).length > 0) runOpts.env = options.env;\n if (options?.cwd) runOpts.cwd = options.cwd;\n const run = async (): Promise<CommandResult> => {\n const client = await getClient(sandbox).catch((error) => { throw new SessionError(error); });\n if (options?.background) {\n await client.commands.runBackground(`setsid bash -c ${shQuote(command)} </dev/null >/dev/null 2>&1 &`, runOpts)\n .catch((error) => { throw new SessionError(error); });\n return { stdout: '', stderr: '', exitCode: 0, durationMs: Date.now() - startTime };\n }\n const token = randomToken();\n const marker = `__CSDK_${token}__`;\n const clientTimeoutMs = options?.timeout && options.timeout > 0 ? options.timeout + 10_000 : undefined;\n const output = await runToCompletion(client, wrapCommand(command, token, options?.timeout), runOpts, resultPath(token), clientTimeoutMs);\n if (output === undefined) {\n return { stdout: '', stderr: `Command timed out after ${options!.timeout}ms`, exitCode: TIMEOUT_EXIT_CODE, durationMs: Date.now() - startTime };\n }\n let parsed = parseWrapped(output, marker);\n if (!parsed) {\n const saved = await client.fs.readTextFile(resultPath(token)).catch(() => undefined);\n parsed = saved === undefined ? undefined : parseWrapped(saved, marker);\n }\n client.fs.remove(resultPath(token)).catch(() => undefined);\n if (!parsed) {\n return { stdout: output.replace(/\\r\\n/g, '\\n'), stderr: '', exitCode: 0, durationMs: Date.now() - startTime };\n }\n return { ...parsed, durationMs: Date.now() - startTime };\n };\n try {\n try {\n return await run();\n } catch (error) {\n if (!(error instanceof SessionError)) throw error;\n // A stale session, e.g. after the VM was suspended: reconnect once.\n await refreshSession(sandbox.id);\n return await run();\n }\n } catch (error) {\n const exitCode = typeof (error as any)?.exitCode === 'number' ? (error as any).exitCode : 127;\n return { stdout: '', stderr: error instanceof Error ? error.message : String(error), exitCode, durationMs: Date.now() - startTime };\n }\n },\n\n getInfo: async (sandbox: CodesandboxSandbox): Promise<InstanceInfo> => ({\n id: sandbox.id,\n provider: 'codesandbox',\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: { cluster: sandbox.cluster, bootupType: sandbox.bootupType, isUpToDate: sandbox.isUpToDate }\n }),\n\n getUrl: async (sandbox: CodesandboxSandbox, options: { port: number; protocol?: string }): Promise<string> => {\n const protocol = options.protocol || 'https';\n return `${protocol}://${sandbox.id}.${sandbox.cluster}.csb.app:${options.port}`;\n },\n\n filesystem: {\n readFile: async (sandbox: CodesandboxSandbox, path: string): Promise<string> => {\n const client = await getClient(sandbox);\n return client.fs.readTextFile(path);\n },\n writeFile: async (sandbox: CodesandboxSandbox, path: string, content: string): Promise<void> => {\n const client = await getClient(sandbox);\n await client.fs.writeTextFile(path, content);\n },\n mkdir: async (sandbox: CodesandboxSandbox, path: string): Promise<void> => {\n const client = await getClient(sandbox);\n await client.fs.mkdir(path, true);\n },\n readdir: async (sandbox: CodesandboxSandbox, path: string): Promise<FileEntry[]> => {\n const client = await getClient(sandbox);\n const entries = await client.fs.readdir(path);\n return entries.map((entry) => ({\n name: entry.name,\n type: entry.type === 'directory' ? 'directory' as const : 'file' as const,\n size: 0,\n modified: new Date()\n }));\n },\n exists: async (sandbox: CodesandboxSandbox, path: string): Promise<boolean> => {\n const client = await getClient(sandbox);\n try { await client.fs.stat(path); return true; } catch { return false; }\n },\n remove: async (sandbox: CodesandboxSandbox, path: string): Promise<void> => {\n const client = await getClient(sandbox);\n await client.fs.remove(path, true);\n }\n },\n\n // Hibernate keeps the VM's memory and disk; resume wakes the same sandbox id.\n pause: (sandbox: CodesandboxSandbox) => sandbox.pause(),\n resume: (sandbox: CodesandboxSandbox) => sandbox.resume(),\n pauseCapabilities: { memory: true },\n\n getInstance: (sandbox: CodesandboxSandbox): CodesandboxSandbox => sandbox,\n },\n\n snapshot: {\n // A fork of the running sandbox (memory, processes and disk), hibernated\n // so it persists as a restore point independent of the source.\n create: async (config: CodesandboxConfig, sandboxId: string, options?: { name?: string }) => {\n const sdk = sdkFor(config);\n try {\n const fork = await sdk.sandboxes.create({\n id: sandboxId,\n tags: [SNAPSHOT_TAG],\n ...(options?.name ? { title: options.name } : {}),\n });\n await sdk.sandboxes.hibernate(fork.id);\n // Forking suspends and resumes the source VM, which can drop its session.\n await refreshSession(sandboxId);\n return { id: fork.id, provider: 'codesandbox', createdAt: new Date(), metadata: { name: options?.name, sourceSandboxId: sandboxId } };\n } catch (error) {\n throw new Error(`Failed to create CodeSandbox snapshot: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n list: async (config: CodesandboxConfig) => {\n const sdk = sdkFor(config);\n const { sandboxes } = await sdk.sandboxes.list({ tags: [SNAPSHOT_TAG] });\n return sandboxes\n .filter((s) => s.tags?.includes(SNAPSHOT_TAG))\n .map((s) => ({ id: s.id, provider: 'codesandbox', createdAt: s.createdAt, metadata: { name: s.title } }));\n },\n delete: async (config: CodesandboxConfig, snapshotId: string) => {\n const sdk = sdkFor(config);\n try {\n await sdk.sandboxes.delete(snapshotId);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n if (!/not found|404/i.test(message)) {\n throw new Error(`Failed to delete CodeSandbox snapshot \"${snapshotId}\": ${message}`);\n }\n }\n },\n // Forks keep the whole VM, memory and /tmp included; the source keeps\n // running, and each restore is an independent fork of the snapshot.\n capabilities: { scope: 'rootfs', memory: true, destroysSource: false, source: 'kept', fork: true, readiness: 'immediate' },\n },\n\n template: {\n create: async (_config: CodesandboxConfig, _options: { name: string }) => {\n throw new Error(`CodeSandbox templates must be created via the dashboard.`);\n },\n list: async (_config: CodesandboxConfig) => { throw new Error(`CodeSandbox provider does not support listing templates via API.`); },\n delete: async (_config: CodesandboxConfig, _templateId: string) => { throw new Error(`CodeSandbox templates must be deleted via the dashboard.`); }\n }\n }\n});\n"],"mappings":"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","names":["message"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@computesdk/codesandbox",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.70",
|
|
4
4
|
"description": "CodeSandbox provider for ComputeSDK - fast browser-compatible sandboxes with npm and Python support",
|
|
5
5
|
"author": "Garrison",
|
|
6
6
|
"license": "MIT",
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@codesandbox/sdk": "^2.4.2",
|
|
22
|
-
"@computesdk/provider": "2.1.
|
|
23
|
-
"computesdk": "4.1.
|
|
22
|
+
"@computesdk/provider": "2.1.22",
|
|
23
|
+
"computesdk": "4.1.16"
|
|
24
24
|
},
|
|
25
25
|
"keywords": [
|
|
26
26
|
"computesdk",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"tsup": "^8.0.0",
|
|
52
52
|
"typescript": "^5.0.0",
|
|
53
53
|
"vitest": "^1.0.0",
|
|
54
|
-
"@computesdk/test-utils": "2.0.
|
|
54
|
+
"@computesdk/test-utils": "2.0.6"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"build": "tsup",
|