UNPKG

@computesdk/daytona

Version:

Daytona provider for ComputeSDK - standardized development environments with devcontainer support

278 lines (277 loc) 11.6 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { daytona: () => daytona }); module.exports = __toCommonJS(index_exports); var import_sdk = require("@daytonaio/sdk"); var import_provider = require("@computesdk/provider"); var daytona = (0, import_provider.defineProvider)({ name: "daytona", methods: { sandbox: { create: async (config, options) => { const apiKey = config.apiKey || typeof process !== "undefined" && process.env?.DAYTONA_API_KEY || ""; if (!apiKey) { throw new Error( `Missing Daytona API key. Provide 'apiKey' in config or set DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/` ); } const runtime = options?.runtime || config.runtime || "node"; const timeout = options?.timeout ?? config.timeout; try { const daytona2 = new import_sdk.Daytona({ apiKey }); const { timeout: _timeout, envs, name, metadata, templateId, snapshotId, sandboxId: _sandboxId, namespace: _namespace, directory: _directory, ...providerOptions } = options || {}; const createParams = { language: runtime === "python" ? "python" : "javascript", ...providerOptions }; if (envs && Object.keys(envs).length > 0) { createParams.envVars = envs; } if (name) { createParams.name = name; } if (metadata && typeof metadata === "object") { const labels = {}; for (const [k, v] of Object.entries(metadata)) { labels[k] = typeof v === "string" ? v : JSON.stringify(v); } createParams.labels = labels; } const sourceId = templateId || snapshotId; if (sourceId) { createParams.snapshot = sourceId; } const createOptions = timeout ? { timeout: Math.ceil(timeout / 1e3) } : void 0; const session = await daytona2.create(createParams, createOptions); const sandboxId = session.id; return { sandbox: session, sandboxId }; } catch (error) { if (error instanceof Error) { if (error.message.includes("unauthorized") || error.message.includes("API key")) { throw new Error(`Daytona authentication failed. Please check your DAYTONA_API_KEY environment variable.`); } if (error.message.includes("quota") || error.message.includes("limit")) { throw new Error(`Daytona quota exceeded. Please check your usage at https://daytona.io/`); } } throw new Error(`Failed to create Daytona sandbox: ${error instanceof Error ? error.message : String(error)}`); } }, getById: async (config, sandboxId) => { const apiKey = config.apiKey || process.env.DAYTONA_API_KEY; try { const daytona2 = new import_sdk.Daytona({ apiKey }); const session = await daytona2.get(sandboxId); return { sandbox: session, sandboxId }; } catch (error) { if (error instanceof Error && (error.message.includes("not found") || error.message.includes("404"))) { return null; } throw new Error(`Failed to get Daytona sandbox ${sandboxId}: ${error instanceof Error ? error.message : String(error)}`); } }, list: async (config) => { const apiKey = config.apiKey || process.env.DAYTONA_API_KEY; try { const daytona2 = new import_sdk.Daytona({ apiKey }); const result = await daytona2.list(); return result.items.map((session) => ({ sandbox: session, sandboxId: session.id })); } catch (error) { throw new Error(`Failed to list Daytona sandboxes: ${error instanceof Error ? error.message : String(error)}`); } }, destroy: async (config, sandboxId) => { const apiKey = config.apiKey || process.env.DAYTONA_API_KEY; try { const daytona2 = new import_sdk.Daytona({ apiKey }); const sandbox = await daytona2.get(sandboxId); await sandbox.delete(); } catch (error) { if (error instanceof Error && (error.message.includes("not found") || error.message.includes("404"))) { return; } throw new Error(`Failed to destroy Daytona sandbox ${sandboxId}: ${error instanceof Error ? error.message : String(error)}`); } }, runCommand: async (sandbox, command, options) => { const startTime = Date.now(); try { let fullCommand = command; if (options?.env && Object.keys(options.env).length > 0) { const envPrefix = Object.entries(options.env).map(([k, v]) => `${k}="${(0, import_provider.escapeShellArg)(v)}"`).join(" "); fullCommand = `${envPrefix} ${fullCommand}`; } if (options?.cwd) fullCommand = `cd "${(0, import_provider.escapeShellArg)(options.cwd)}" && ${fullCommand}`; if (options?.background) fullCommand = `nohup ${fullCommand} > /dev/null 2>&1 &`; const response = await sandbox.process.executeCommand(fullCommand); return { stdout: response.result || "", stderr: "", exitCode: response.exitCode || 0, durationMs: Date.now() - startTime }; } catch (error) { throw new Error(`Daytona command execution failed: ${error instanceof Error ? error.message : String(error)}`); } }, getInfo: async (sandbox) => { return { id: sandbox.id, provider: "daytona", status: "running", createdAt: /* @__PURE__ */ new Date(), timeout: 3e5, metadata: { daytonaSandboxId: sandbox.id } }; }, getUrl: async (sandbox, options) => { try { const previewInfo = await sandbox.getPreviewLink(options.port); let url = previewInfo.url; if (options.protocol) { const urlObj = new URL(url); urlObj.protocol = options.protocol + ":"; url = urlObj.toString(); } return url; } catch (error) { throw new Error(`Failed to get Daytona preview URL for port ${options.port}: ${error instanceof Error ? error.message : String(error)}`); } }, filesystem: { readFile: async (sandbox, path) => { const response = await sandbox.process.executeCommand(`cat "${path}"`); if (response.exitCode !== 0) throw new Error(`File not found or cannot be read: ${path}`); return response.result || ""; }, writeFile: async (sandbox, path, content) => { const encoded = Buffer.from(content).toString("base64"); const response = await sandbox.process.executeCommand(`echo "${encoded}" | base64 -d > "${path}"`); if (response.exitCode !== 0) throw new Error(`Failed to write to file: ${path}`); }, mkdir: async (sandbox, path) => { const response = await sandbox.process.executeCommand(`mkdir -p "${path}"`); if (response.exitCode !== 0) throw new Error(`Failed to create directory: ${path}`); }, readdir: async (sandbox, path) => { const response = await sandbox.process.executeCommand(`ls -la "${path}"`); if (response.exitCode !== 0) throw new Error(`Directory not found or cannot be read: ${path}`); const lines = response.result.split("\n").filter((l) => l.trim()); const entries = []; for (const line of lines) { if (line.startsWith("total ") || line.endsWith(" .") || line.endsWith(" ..")) continue; const parts = line.trim().split(/\s+/); if (parts.length >= 9) { entries.push({ name: parts.slice(8).join(" "), type: parts[0].startsWith("d") ? "directory" : "file", size: parseInt(parts[4]) || 0, modified: /* @__PURE__ */ new Date() }); } } return entries; }, exists: async (sandbox, path) => { const response = await sandbox.process.executeCommand(`test -e "${path}"`); return response.exitCode === 0; }, remove: async (sandbox, path) => { const response = await sandbox.process.executeCommand(`rm -rf "${path}"`); if (response.exitCode !== 0) throw new Error(`Failed to remove: ${path}`); } }, getInstance: (sandbox) => sandbox }, snapshot: { create: async (config, sandboxId, options) => { const apiKey = config.apiKey || process.env.DAYTONA_API_KEY; const daytona2 = new import_sdk.Daytona({ apiKey }); try { const snapshot = await daytona2.snapshots.create({ workspaceId: sandboxId, name: options?.name || `snapshot-${Date.now()}` }); return snapshot; } catch (error) { throw new Error(`Failed to create Daytona snapshot: ${error instanceof Error ? error.message : String(error)}`); } }, list: async (config) => { const apiKey = config.apiKey || process.env.DAYTONA_API_KEY; const daytona2 = new import_sdk.Daytona({ apiKey }); try { return await daytona2.snapshots.list(); } catch { return []; } }, delete: async (config, snapshotId) => { const apiKey = config.apiKey || process.env.DAYTONA_API_KEY; const daytona2 = new import_sdk.Daytona({ apiKey }); try { await daytona2.snapshots.delete(snapshotId); } catch { } } }, template: { create: async (_config, _options) => { throw new Error("To create a template in Daytona, create a snapshot from a running sandbox using snapshot.create()"); }, list: async (config) => { const apiKey = config.apiKey || process.env.DAYTONA_API_KEY; const daytona2 = new import_sdk.Daytona({ apiKey }); try { return await daytona2.snapshots.list(); } catch { return []; } }, delete: async (config, templateId) => { const apiKey = config.apiKey || process.env.DAYTONA_API_KEY; const daytona2 = new import_sdk.Daytona({ apiKey }); try { await daytona2.snapshots.delete(templateId); } catch { } } } } }); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { daytona }); //# sourceMappingURL=index.js.map