@computesdk/daytona 1.0.1 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -20,255 +20,257 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- DaytonaProvider: () => DaytonaProvider,
24
23
  daytona: () => daytona
25
24
  });
26
25
  module.exports = __toCommonJS(index_exports);
27
26
  var import_sdk = require("@daytonaio/sdk");
28
- var DaytonaSandboxImpl = class {
29
- constructor(session, runtime = "python") {
30
- this.provider = "daytona";
31
- this.session = session;
32
- this.sandboxId = session.id;
33
- this.runtime = runtime;
34
- this.filesystem = new DaytonaFileSystem(this.session);
35
- this.terminal = new DaytonaTerminal(this.session);
36
- }
37
- async runCode(code, runtime) {
38
- const startTime = Date.now();
39
- try {
40
- const response = await this.session.process.codeRun(code);
41
- return {
42
- stdout: response.result || "",
43
- stderr: "",
44
- // Daytona doesn't separate stderr in the response
45
- exitCode: response.exitCode || 0,
46
- executionTime: Date.now() - startTime,
47
- sandboxId: this.sandboxId,
48
- provider: this.provider
49
- };
50
- } catch (error) {
51
- throw new Error(
52
- `Daytona execution failed: ${error instanceof Error ? error.message : String(error)}`
53
- );
54
- }
55
- }
56
- async runCommand(command, args = []) {
57
- const startTime = Date.now();
58
- try {
59
- const fullCommand = args.length > 0 ? `${command} ${args.join(" ")}` : command;
60
- const response = await this.session.process.executeCommand(fullCommand);
61
- return {
62
- stdout: response.result || "",
63
- stderr: "",
64
- // Daytona doesn't separate stderr in the response
65
- exitCode: response.exitCode || 0,
66
- executionTime: Date.now() - startTime,
67
- sandboxId: this.sandboxId,
68
- provider: this.provider
69
- };
70
- } catch (error) {
71
- throw new Error(
72
- `Daytona command execution failed: ${error instanceof Error ? error.message : String(error)}`
73
- );
74
- }
75
- }
76
- async getInfo() {
77
- return {
78
- id: this.sandboxId,
79
- provider: this.provider,
80
- runtime: this.runtime,
81
- status: this.session.state === "started" ? "running" : "stopped",
82
- createdAt: this.session.createdAt ? new Date(this.session.createdAt) : /* @__PURE__ */ new Date(),
83
- timeout: 3e5,
84
- // Default Daytona timeout
85
- metadata: {
86
- daytonaSessionId: this.sandboxId,
87
- state: this.session.state,
88
- target: this.session.target,
89
- cpu: this.session.cpu,
90
- memory: this.session.memory,
91
- disk: this.session.disk
92
- }
93
- };
94
- }
95
- async kill() {
96
- try {
97
- throw new Error("Sandbox deletion must be handled by the DaytonaSandboxManager");
98
- } catch (error) {
99
- throw new Error(
100
- `Failed to kill Daytona session: ${error instanceof Error ? error.message : String(error)}`
101
- );
102
- }
103
- }
104
- };
105
- var DaytonaFileSystem = class {
106
- constructor(session) {
107
- this.session = session;
108
- }
109
- async readFile(path) {
110
- try {
111
- const buffer = await this.session.fs.downloadFile(path);
112
- return buffer.toString("utf-8");
113
- } catch (error) {
114
- throw new Error(`Failed to read file ${path}: ${error instanceof Error ? error.message : String(error)}`);
115
- }
116
- }
117
- async writeFile(path, content) {
118
- try {
119
- const buffer = Buffer.from(content, "utf-8");
120
- await this.session.fs.uploadFile(buffer, path);
121
- } catch (error) {
122
- throw new Error(`Failed to write file ${path}: ${error instanceof Error ? error.message : String(error)}`);
123
- }
124
- }
125
- async mkdir(path) {
126
- try {
127
- await this.session.fs.createFolder(path, "755");
128
- } catch (error) {
129
- throw new Error(`Failed to create directory ${path}: ${error instanceof Error ? error.message : String(error)}`);
130
- }
131
- }
132
- async readdir(path) {
133
- try {
134
- const entries = await this.session.fs.listFiles(path);
135
- return entries.map((entry) => ({
136
- name: entry.name,
137
- path: entry.path || `${path}/${entry.name}`,
138
- isDirectory: Boolean(entry.isDir || entry.isDirectory || entry.type === "directory"),
139
- size: entry.size || 0,
140
- lastModified: new Date(entry.modTime || entry.lastModified || Date.now())
141
- }));
142
- } catch (error) {
143
- throw new Error(`Failed to read directory ${path}: ${error instanceof Error ? error.message : String(error)}`);
144
- }
145
- }
146
- async exists(path) {
147
- try {
148
- await this.session.fs.getFileDetails(path);
149
- return true;
150
- } catch (error) {
151
- return false;
152
- }
153
- }
154
- async remove(path) {
155
- try {
156
- await this.session.fs.deleteFile(path);
157
- } catch (error) {
158
- throw new Error(`Failed to remove ${path}: ${error instanceof Error ? error.message : String(error)}`);
159
- }
160
- }
161
- };
162
- var DaytonaTerminal = class {
163
- constructor(session) {
164
- this.session = session;
165
- }
166
- async create(options = {}) {
167
- throw new Error("Terminal operations are not supported by Daytona provider. Use runCode() or runCommand() instead.");
168
- }
169
- async list() {
170
- return [];
171
- }
172
- };
173
- var DaytonaSandboxManager = class {
174
- constructor(config) {
175
- this.config = config;
176
- this.activeSandboxes = /* @__PURE__ */ new Map();
177
- const apiKey = config.apiKey || typeof process !== "undefined" && process.env?.DAYTONA_API_KEY || "";
178
- if (!apiKey) {
179
- throw new Error(
180
- `Missing Daytona API key. Provide 'apiKey' in config or set DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/`
181
- );
182
- }
183
- this.daytona = new import_sdk.Daytona({ apiKey });
184
- }
185
- async create(options) {
186
- const runtime = options?.runtime || this.config.runtime || "python";
187
- try {
188
- let session;
189
- if (options?.sandboxId) {
190
- session = await this.daytona.get(options.sandboxId);
191
- } else {
192
- session = await this.daytona.create({
193
- language: runtime === "python" ? "python" : "typescript"
194
- });
195
- }
196
- const sandbox = new DaytonaSandboxImpl(session, runtime);
197
- this.activeSandboxes.set(sandbox.sandboxId, sandbox);
198
- return sandbox;
199
- } catch (error) {
200
- if (error instanceof Error) {
201
- if (error.message.includes("unauthorized") || error.message.includes("API key")) {
27
+ var import_computesdk = require("computesdk");
28
+ var daytona = (0, import_computesdk.createProvider)({
29
+ name: "daytona",
30
+ methods: {
31
+ sandbox: {
32
+ // Collection operations (compute.sandbox.*)
33
+ create: async (config, options) => {
34
+ const apiKey = config.apiKey || typeof process !== "undefined" && process.env?.DAYTONA_API_KEY || "";
35
+ if (!apiKey) {
202
36
  throw new Error(
203
- `Daytona authentication failed. Please check your DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/`
37
+ `Missing Daytona API key. Provide 'apiKey' in config or set DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/`
204
38
  );
205
39
  }
206
- if (error.message.includes("quota") || error.message.includes("limit")) {
40
+ const runtime = options?.runtime || config.runtime || "node";
41
+ try {
42
+ const daytona2 = new import_sdk.Daytona({ apiKey });
43
+ let session;
44
+ let sandboxId;
45
+ if (options?.sandboxId) {
46
+ session = await daytona2.get(options.sandboxId);
47
+ sandboxId = options.sandboxId;
48
+ } else {
49
+ session = await daytona2.create({
50
+ language: runtime === "python" ? "python" : "javascript"
51
+ });
52
+ sandboxId = session.id;
53
+ }
54
+ return {
55
+ sandbox: session,
56
+ sandboxId
57
+ };
58
+ } catch (error) {
59
+ if (error instanceof Error) {
60
+ if (error.message.includes("unauthorized") || error.message.includes("API key")) {
61
+ throw new Error(
62
+ `Daytona authentication failed. Please check your DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/`
63
+ );
64
+ }
65
+ if (error.message.includes("quota") || error.message.includes("limit")) {
66
+ throw new Error(
67
+ `Daytona quota exceeded. Please check your usage at https://daytona.io/`
68
+ );
69
+ }
70
+ }
207
71
  throw new Error(
208
- `Daytona quota exceeded. Please check your usage at https://daytona.io/`
72
+ `Failed to create Daytona sandbox: ${error instanceof Error ? error.message : String(error)}`
209
73
  );
210
74
  }
211
- }
212
- throw new Error(
213
- `Failed to create Daytona sandbox: ${error instanceof Error ? error.message : String(error)}`
214
- );
215
- }
216
- }
217
- async getById(sandboxId) {
218
- const existing = this.activeSandboxes.get(sandboxId);
219
- if (existing) {
220
- return existing;
221
- }
222
- try {
223
- const session = await this.daytona.get(sandboxId);
224
- const sandbox = new DaytonaSandboxImpl(session, this.config.runtime || "python");
225
- this.activeSandboxes.set(sandboxId, sandbox);
226
- return sandbox;
227
- } catch (error) {
228
- return null;
229
- }
230
- }
231
- async list() {
232
- try {
233
- const sessions = await this.daytona.list();
234
- const sandboxes = [];
235
- for (const session of sessions) {
236
- let sandbox = this.activeSandboxes.get(session.id);
237
- if (!sandbox) {
238
- sandbox = new DaytonaSandboxImpl(session, this.config.runtime || "python");
239
- this.activeSandboxes.set(session.id, sandbox);
75
+ },
76
+ getById: async (config, sandboxId) => {
77
+ const apiKey = config.apiKey || process.env.DAYTONA_API_KEY;
78
+ try {
79
+ const daytona2 = new import_sdk.Daytona({ apiKey });
80
+ const session = await daytona2.get(sandboxId);
81
+ return {
82
+ sandbox: session,
83
+ sandboxId
84
+ };
85
+ } catch (error) {
86
+ return null;
87
+ }
88
+ },
89
+ list: async (config) => {
90
+ const apiKey = config.apiKey || process.env.DAYTONA_API_KEY;
91
+ try {
92
+ const daytona2 = new import_sdk.Daytona({ apiKey });
93
+ const sandboxes = await daytona2.list();
94
+ return sandboxes.map((session) => ({
95
+ sandbox: session,
96
+ sandboxId: session.id
97
+ }));
98
+ } catch (error) {
99
+ return [];
100
+ }
101
+ },
102
+ destroy: async (config, sandboxId) => {
103
+ const apiKey = config.apiKey || process.env.DAYTONA_API_KEY;
104
+ try {
105
+ const daytona2 = new import_sdk.Daytona({ apiKey });
106
+ const sandbox = await daytona2.get(sandboxId);
107
+ await sandbox.delete();
108
+ } catch (error) {
109
+ }
110
+ },
111
+ // Instance operations (sandbox.*)
112
+ runCode: async (sandbox, code, runtime) => {
113
+ const startTime = Date.now();
114
+ try {
115
+ const effectiveRuntime = runtime || // Strong Python indicators
116
+ (code.includes("print(") || code.includes("import ") || code.includes("def ") || code.includes("sys.") || code.includes("json.") || code.includes("__") || code.includes('f"') || code.includes("f'") ? "python" : "node");
117
+ let response;
118
+ const encoded = Buffer.from(code).toString("base64");
119
+ if (effectiveRuntime === "python") {
120
+ response = await sandbox.process.executeCommand(`echo "${encoded}" | base64 -d | python3`);
121
+ } else {
122
+ response = await sandbox.process.executeCommand(`echo "${encoded}" | base64 -d | node`);
123
+ }
124
+ const output = response.result || "";
125
+ const hasError = output.includes("Error:") || output.includes("error TS") || output.includes("SyntaxError:") || output.includes("TypeError:") || output.includes("ReferenceError:") || output.includes("Traceback (most recent call last)");
126
+ if (hasError && (output.includes("SyntaxError:") || output.includes("invalid syntax") || output.includes("Unexpected token") || output.includes("Unexpected identifier") || output.includes("error TS1434"))) {
127
+ throw new Error(`Syntax error: ${output.trim()}`);
128
+ }
129
+ const actualExitCode = hasError ? 1 : response.exitCode || 0;
130
+ return {
131
+ stdout: hasError ? "" : output,
132
+ stderr: hasError ? output : "",
133
+ exitCode: actualExitCode,
134
+ executionTime: Date.now() - startTime,
135
+ sandboxId: sandbox.id,
136
+ provider: "daytona"
137
+ };
138
+ } catch (error) {
139
+ if (error instanceof Error && error.message.includes("Syntax error")) {
140
+ throw error;
141
+ }
142
+ throw new Error(
143
+ `Daytona execution failed: ${error instanceof Error ? error.message : String(error)}`
144
+ );
145
+ }
146
+ },
147
+ runCommand: async (sandbox, command, args = []) => {
148
+ const startTime = Date.now();
149
+ try {
150
+ const fullCommand = args.length > 0 ? `${command} ${args.join(" ")}` : command;
151
+ const response = await sandbox.process.executeCommand(fullCommand);
152
+ return {
153
+ stdout: response.result || "",
154
+ stderr: "",
155
+ // Daytona doesn't separate stderr in the response
156
+ exitCode: response.exitCode || 0,
157
+ executionTime: Date.now() - startTime,
158
+ sandboxId: sandbox.id,
159
+ provider: "daytona"
160
+ };
161
+ } catch (error) {
162
+ throw new Error(
163
+ `Daytona command execution failed: ${error instanceof Error ? error.message : String(error)}`
164
+ );
165
+ }
166
+ },
167
+ getInfo: async (sandbox) => {
168
+ return {
169
+ id: sandbox.id,
170
+ provider: "daytona",
171
+ runtime: "python",
172
+ // Daytona default
173
+ status: "running",
174
+ createdAt: /* @__PURE__ */ new Date(),
175
+ timeout: 3e5,
176
+ metadata: {
177
+ daytonaSandboxId: sandbox.id
178
+ }
179
+ };
180
+ },
181
+ // Filesystem operations via terminal commands
182
+ filesystem: {
183
+ readFile: async (sandbox, path) => {
184
+ try {
185
+ const response = await sandbox.process.executeCommand(`cat "${path}"`);
186
+ if (response.exitCode !== 0) {
187
+ throw new Error(`File not found or cannot be read: ${path}`);
188
+ }
189
+ return response.result || "";
190
+ } catch (error) {
191
+ throw new Error(`Failed to read file ${path}: ${error instanceof Error ? error.message : String(error)}`);
192
+ }
193
+ },
194
+ writeFile: async (sandbox, path, content) => {
195
+ try {
196
+ const encoded = Buffer.from(content).toString("base64");
197
+ const response = await sandbox.process.executeCommand(`echo "${encoded}" | base64 -d > "${path}"`);
198
+ if (response.exitCode !== 0) {
199
+ throw new Error(`Failed to write to file: ${path}`);
200
+ }
201
+ } catch (error) {
202
+ throw new Error(`Failed to write file ${path}: ${error instanceof Error ? error.message : String(error)}`);
203
+ }
204
+ },
205
+ mkdir: async (sandbox, path) => {
206
+ try {
207
+ const response = await sandbox.process.executeCommand(`mkdir -p "${path}"`);
208
+ if (response.exitCode !== 0) {
209
+ throw new Error(`Failed to create directory: ${path}`);
210
+ }
211
+ } catch (error) {
212
+ throw new Error(`Failed to create directory ${path}: ${error instanceof Error ? error.message : String(error)}`);
213
+ }
214
+ },
215
+ readdir: async (sandbox, path) => {
216
+ try {
217
+ const response = await sandbox.process.executeCommand(`ls -la "${path}"`);
218
+ if (response.exitCode !== 0) {
219
+ throw new Error(`Directory not found or cannot be read: ${path}`);
220
+ }
221
+ const lines = response.result.split("\n").filter((line) => line.trim());
222
+ const entries = [];
223
+ for (const line of lines) {
224
+ if (line.startsWith("total ") || line.endsWith(" .") || line.endsWith(" ..")) {
225
+ continue;
226
+ }
227
+ const parts = line.trim().split(/\s+/);
228
+ if (parts.length >= 9) {
229
+ const permissions = parts[0];
230
+ const name = parts.slice(8).join(" ");
231
+ const isDirectory = permissions.startsWith("d");
232
+ const size = parseInt(parts[4]) || 0;
233
+ entries.push({
234
+ name,
235
+ path: `${path}/${name}`.replace(/\/+/g, "/"),
236
+ // Clean up double slashes
237
+ isDirectory,
238
+ size,
239
+ lastModified: /* @__PURE__ */ new Date()
240
+ // ls -la date parsing is complex, use current time
241
+ });
242
+ }
243
+ }
244
+ return entries;
245
+ } catch (error) {
246
+ throw new Error(`Failed to read directory ${path}: ${error instanceof Error ? error.message : String(error)}`);
247
+ }
248
+ },
249
+ exists: async (sandbox, path) => {
250
+ try {
251
+ const response = await sandbox.process.executeCommand(`test -e "${path}"`);
252
+ return response.exitCode === 0;
253
+ } catch (error) {
254
+ return false;
255
+ }
256
+ },
257
+ remove: async (sandbox, path) => {
258
+ try {
259
+ const response = await sandbox.process.executeCommand(`rm -rf "${path}"`);
260
+ if (response.exitCode !== 0) {
261
+ throw new Error(`Failed to remove: ${path}`);
262
+ }
263
+ } catch (error) {
264
+ throw new Error(`Failed to remove ${path}: ${error instanceof Error ? error.message : String(error)}`);
265
+ }
240
266
  }
241
- sandboxes.push(sandbox);
242
267
  }
243
- return sandboxes;
244
- } catch (error) {
245
- return Array.from(this.activeSandboxes.values());
268
+ // Terminal operations not implemented - Daytona session API needs verification
246
269
  }
247
270
  }
248
- async destroy(sandboxId) {
249
- const sandbox = this.activeSandboxes.get(sandboxId);
250
- if (sandbox) {
251
- this.activeSandboxes.delete(sandboxId);
252
- }
253
- try {
254
- const session = await this.daytona.get(sandboxId);
255
- await this.daytona.delete(session);
256
- } catch (error) {
257
- }
258
- }
259
- };
260
- var DaytonaProvider = class {
261
- constructor(config = {}) {
262
- this.name = "daytona";
263
- this.sandbox = new DaytonaSandboxManager(config);
264
- }
265
- };
266
- function daytona(config = {}) {
267
- return new DaytonaProvider(config);
268
- }
271
+ });
269
272
  // Annotate the CommonJS export names for ESM import in node:
270
273
  0 && (module.exports = {
271
- DaytonaProvider,
272
274
  daytona
273
275
  });
274
276
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { Daytona, Sandbox as DaytonaSandbox } from '@daytonaio/sdk';\nimport type {\n ExecutionResult,\n Runtime,\n SandboxInfo,\n FileEntry,\n SandboxFileSystem,\n SandboxTerminal,\n TerminalSession,\n TerminalCreateOptions,\n Provider,\n ProviderSandboxManager,\n Sandbox,\n CreateSandboxOptions,\n} from 'computesdk';\n\n/**\n * Daytona-specific configuration options\n */\nexport interface DaytonaConfig {\n /** Daytona API key - if not provided, will fallback to DAYTONA_API_KEY environment variable */\n apiKey?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * Daytona Sandbox implementation\n */\nclass DaytonaSandboxImpl implements Sandbox {\n readonly sandboxId: string;\n readonly provider = 'daytona';\n readonly filesystem: SandboxFileSystem;\n readonly terminal: SandboxTerminal;\n\n private session: DaytonaSandbox;\n private readonly runtime: Runtime;\n\n constructor(session: DaytonaSandbox, runtime: Runtime = 'python') {\n this.session = session;\n this.sandboxId = session.id;\n this.runtime = runtime;\n \n // Initialize filesystem and terminal\n this.filesystem = new DaytonaFileSystem(this.session);\n this.terminal = new DaytonaTerminal(this.session);\n }\n\n async runCode(code: string, runtime?: Runtime): Promise<ExecutionResult> {\n const startTime = Date.now();\n\n try {\n // Execute code using Daytona's process.codeRun method\n const response = await this.session.process.codeRun(code);\n \n return {\n stdout: response.result || '',\n stderr: '', // Daytona doesn't separate stderr in the response\n exitCode: response.exitCode || 0,\n executionTime: Date.now() - startTime,\n sandboxId: this.sandboxId,\n provider: this.provider\n };\n } catch (error) {\n throw new Error(\n `Daytona execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n async runCommand(command: string, args: string[] = []): Promise<ExecutionResult> {\n const startTime = Date.now();\n\n try {\n // Construct full command with arguments\n const fullCommand = args.length > 0 ? `${command} ${args.join(' ')}` : command;\n\n // Execute command using Daytona's process.executeCommand method\n const response = await this.session.process.executeCommand(fullCommand);\n \n return {\n stdout: response.result || '',\n stderr: '', // Daytona doesn't separate stderr in the response\n exitCode: response.exitCode || 0,\n executionTime: Date.now() - startTime,\n sandboxId: this.sandboxId,\n provider: this.provider\n };\n } catch (error) {\n throw new Error(\n `Daytona command execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n async getInfo(): Promise<SandboxInfo> {\n return {\n id: this.sandboxId,\n provider: this.provider,\n runtime: this.runtime,\n status: this.session.state === 'started' ? 'running' : 'stopped',\n createdAt: this.session.createdAt ? new Date(this.session.createdAt) : new Date(),\n timeout: 300000, // Default Daytona timeout\n metadata: {\n daytonaSessionId: this.sandboxId,\n state: this.session.state,\n target: this.session.target,\n cpu: this.session.cpu,\n memory: this.session.memory,\n disk: this.session.disk\n }\n };\n }\n\n async kill(): Promise<void> {\n try {\n // Use the Daytona client to delete the sandbox\n // Note: We need access to the Daytona client instance for this\n // For now, we'll throw an error indicating this needs to be handled by the manager\n throw new Error('Sandbox deletion must be handled by the DaytonaSandboxManager');\n } catch (error) {\n throw new Error(\n `Failed to kill Daytona session: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n}\n\n/**\n * Daytona FileSystem implementation\n */\nclass DaytonaFileSystem implements SandboxFileSystem {\n constructor(private session: DaytonaSandbox) {}\n\n async readFile(path: string): Promise<string> {\n try {\n // Use Daytona's file system API to download file as buffer, then convert to string\n const buffer = await this.session.fs.downloadFile(path);\n return buffer.toString('utf-8');\n } catch (error) {\n throw new Error(`Failed to read file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n async writeFile(path: string, content: string): Promise<void> {\n try {\n // Use Daytona's file system API to upload file from buffer\n const buffer = Buffer.from(content, 'utf-8');\n await this.session.fs.uploadFile(buffer, path);\n } catch (error) {\n throw new Error(`Failed to write file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n async mkdir(path: string): Promise<void> {\n try {\n // Use Daytona's file system API to create directory\n await this.session.fs.createFolder(path, '755');\n } catch (error) {\n throw new Error(`Failed to create directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n async readdir(path: string): Promise<FileEntry[]> {\n try {\n // Use Daytona's file system API to list directory\n const entries = await this.session.fs.listFiles(path);\n\n return entries.map((entry: any) => ({\n name: entry.name,\n path: entry.path || `${path}/${entry.name}`,\n isDirectory: Boolean(entry.isDir || entry.isDirectory || entry.type === 'directory'),\n size: entry.size || 0,\n lastModified: new Date(entry.modTime || entry.lastModified || Date.now())\n }));\n } catch (error) {\n throw new Error(`Failed to read directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n // Use Daytona's file system API to get file details - if it succeeds, file exists\n await this.session.fs.getFileDetails(path);\n return true;\n } catch (error) {\n // If the API call fails, assume file doesn't exist\n return false;\n }\n }\n\n async remove(path: string): Promise<void> {\n try {\n // Use Daytona's file system API to delete file/directory\n await this.session.fs.deleteFile(path);\n } catch (error) {\n throw new Error(`Failed to remove ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n}\n\n/**\n * Daytona Terminal implementation (Note: Daytona doesn't support terminal operations by design)\n */\nclass DaytonaTerminal implements SandboxTerminal {\n constructor(private session: DaytonaSandbox) {}\n\n async create(options: TerminalCreateOptions = {}): Promise<TerminalSession> {\n // Daytona doesn't support terminal operations by design\n throw new Error('Terminal operations are not supported by Daytona provider. Use runCode() or runCommand() instead.');\n }\n\n async list(): Promise<TerminalSession[]> {\n // Daytona doesn't support terminal operations by design\n return [];\n }\n}\n\n/**\n * Daytona Sandbox Manager - implements ProviderSandboxManager\n */\nclass DaytonaSandboxManager implements ProviderSandboxManager {\n private activeSandboxes: Map<string, DaytonaSandboxImpl> = new Map();\n private daytona: Daytona;\n\n constructor(private config: DaytonaConfig) {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.DAYTONA_API_KEY) || '';\n \n if (!apiKey) {\n throw new Error(\n `Missing Daytona API key. Provide 'apiKey' in config or set DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/`\n );\n }\n\n // Initialize Daytona client\n this.daytona = new Daytona({ apiKey: apiKey });\n }\n\n async create(options?: CreateSandboxOptions): Promise<Sandbox> {\n const runtime = options?.runtime || this.config.runtime || 'python';\n\n try {\n let session: DaytonaSandbox;\n\n if (options?.sandboxId) {\n // Reconnect to existing Daytona session\n session = await this.daytona.get(options.sandboxId);\n } else {\n // Create new Daytona session\n session = await this.daytona.create({\n language: runtime === 'python' ? 'python' : 'typescript',\n });\n }\n\n const sandbox = new DaytonaSandboxImpl(session, runtime);\n this.activeSandboxes.set(sandbox.sandboxId, sandbox);\n \n return sandbox;\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('API key')) {\n throw new Error(\n `Daytona authentication failed. Please check your DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `Daytona quota exceeded. Please check your usage at https://daytona.io/`\n );\n }\n }\n throw new Error(\n `Failed to create Daytona sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n async getById(sandboxId: string): Promise<Sandbox | null> {\n // Check if we have it in our active sandboxes\n const existing = this.activeSandboxes.get(sandboxId);\n if (existing) {\n return existing;\n }\n\n // Try to reconnect to existing Daytona session\n try {\n const session = await this.daytona.get(sandboxId);\n \n const sandbox = new DaytonaSandboxImpl(session, this.config.runtime || 'python');\n this.activeSandboxes.set(sandboxId, sandbox);\n \n return sandbox;\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n }\n\n async list(): Promise<Sandbox[]> {\n try {\n // Use Daytona's list API to get all sandboxes\n const sessions = await this.daytona.list();\n const sandboxes: Sandbox[] = [];\n\n for (const session of sessions) {\n let sandbox = this.activeSandboxes.get(session.id);\n if (!sandbox) {\n sandbox = new DaytonaSandboxImpl(session, this.config.runtime || 'python');\n this.activeSandboxes.set(session.id, sandbox);\n }\n sandboxes.push(sandbox);\n }\n\n return sandboxes;\n } catch (error) {\n // If list fails, return our active sandboxes\n return Array.from(this.activeSandboxes.values());\n }\n }\n\n async destroy(sandboxId: string): Promise<void> {\n const sandbox = this.activeSandboxes.get(sandboxId);\n if (sandbox) {\n this.activeSandboxes.delete(sandboxId);\n }\n \n // Use Daytona client to delete the sandbox\n try {\n const session = await this.daytona.get(sandboxId);\n await this.daytona.delete(session);\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n }\n}\n\n/**\n * Daytona Provider implementation\n */\nexport class DaytonaProvider implements Provider {\n readonly name = 'daytona';\n readonly sandbox: ProviderSandboxManager;\n\n constructor(config: DaytonaConfig = {}) {\n this.sandbox = new DaytonaSandboxManager(config);\n }\n}\n\n/**\n * Create a Daytona provider instance\n */\nexport function daytona(config: DaytonaConfig = {}): DaytonaProvider {\n return new DaytonaProvider(config);\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Daytona Provider - Factory-based Implementation\n * \n * Code execution only provider using the factory pattern.\n * Reduces ~300 lines of boilerplate to ~80 lines of core logic.\n */\n\nimport { Daytona, Sandbox as DaytonaSandbox } from '@daytonaio/sdk';\nimport { createProvider } from 'computesdk';\nimport type { Runtime, ExecutionResult, SandboxInfo, CreateSandboxOptions, FileEntry } from 'computesdk';\n\n/**\n * Daytona-specific configuration options\n */\nexport interface DaytonaConfig {\n /** Daytona API key - if not provided, will fallback to DAYTONA_API_KEY environment variable */\n apiKey?: string;\n /** Default runtime environment */\n runtime?: Runtime;\n /** Execution timeout in milliseconds */\n timeout?: number;\n}\n\n/**\n * Create a Daytona provider instance using the factory pattern\n */\nexport const daytona = createProvider<DaytonaSandbox, DaytonaConfig>({\n name: 'daytona',\n methods: {\n sandbox: {\n // Collection operations (compute.sandbox.*)\n create: async (config: DaytonaConfig, options?: CreateSandboxOptions) => {\n // Validate API key\n const apiKey = config.apiKey || (typeof process !== 'undefined' && process.env?.DAYTONA_API_KEY) || '';\n\n if (!apiKey) {\n throw new Error(\n `Missing Daytona API key. Provide 'apiKey' in config or set DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/`\n );\n }\n\n const runtime = options?.runtime || config.runtime || 'node';\n\n try {\n // Initialize Daytona client\n const daytona = new Daytona({ apiKey: apiKey });\n\n let session: DaytonaSandbox;\n let sandboxId: string;\n\n if (options?.sandboxId) {\n // Reconnect to existing Daytona sandbox\n session = await daytona.get(options.sandboxId);\n sandboxId = options.sandboxId;\n } else {\n // Create new Daytona sandbox\n session = await daytona.create({\n language: runtime === 'python' ? 'python' : 'javascript',\n });\n sandboxId = session.id;\n }\n\n return {\n sandbox: session,\n sandboxId\n };\n } catch (error) {\n if (error instanceof Error) {\n if (error.message.includes('unauthorized') || error.message.includes('API key')) {\n throw new Error(\n `Daytona authentication failed. Please check your DAYTONA_API_KEY environment variable. Get your API key from https://daytona.io/`\n );\n }\n if (error.message.includes('quota') || error.message.includes('limit')) {\n throw new Error(\n `Daytona quota exceeded. Please check your usage at https://daytona.io/`\n );\n }\n }\n throw new Error(\n `Failed to create Daytona sandbox: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getById: async (config: DaytonaConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.DAYTONA_API_KEY!;\n\n try {\n const daytona = new Daytona({ apiKey: apiKey });\n const session = await daytona.get(sandboxId);\n\n return {\n sandbox: session,\n sandboxId\n };\n } catch (error) {\n // Sandbox doesn't exist or can't be accessed\n return null;\n }\n },\n\n list: async (config: DaytonaConfig) => {\n const apiKey = config.apiKey || process.env.DAYTONA_API_KEY!;\n\n try {\n const daytona = new Daytona({ apiKey: apiKey });\n const sandboxes = await daytona.list();\n\n return sandboxes.map((session: any) => ({\n sandbox: session,\n sandboxId: session.id\n }));\n } catch (error) {\n // Return empty array if listing fails\n return [];\n }\n },\n\n destroy: async (config: DaytonaConfig, sandboxId: string) => {\n const apiKey = config.apiKey || process.env.DAYTONA_API_KEY!;\n\n try {\n const daytona = new Daytona({ apiKey: apiKey });\n // Note: Daytona SDK expects a Sandbox object, but we only have the ID\n // This is a limitation of the current Daytona SDK design\n // For now, we'll skip the delete operation\n const sandbox = await daytona.get(sandboxId);\n await sandbox.delete();\n } catch (error) {\n // Sandbox might already be destroyed or doesn't exist\n // This is acceptable for destroy operations\n }\n },\n\n // Instance operations (sandbox.*)\n runCode: async (sandbox: DaytonaSandbox, code: string, runtime?: Runtime): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Auto-detect runtime if not specified\n const effectiveRuntime = runtime || (\n // Strong Python indicators\n code.includes('print(') || \n code.includes('import ') ||\n code.includes('def ') ||\n code.includes('sys.') ||\n code.includes('json.') ||\n code.includes('__') ||\n code.includes('f\"') ||\n code.includes(\"f'\")\n ? 'python'\n // Default to Node.js for all other cases (including ambiguous)\n : 'node'\n );\n \n // Use direct command execution like Vercel for consistency\n let response;\n \n // Use base64 encoding for both runtimes for reliability and consistency\n const encoded = Buffer.from(code).toString('base64');\n \n if (effectiveRuntime === 'python') {\n response = await sandbox.process.executeCommand(`echo \"${encoded}\" | base64 -d | python3`);\n } else {\n response = await sandbox.process.executeCommand(`echo \"${encoded}\" | base64 -d | node`);\n }\n\n // Daytona always returns exitCode: 0, so we need to detect errors from output\n const output = response.result || '';\n const hasError = output.includes('Error:') || \n output.includes('error TS') || \n output.includes('SyntaxError:') ||\n output.includes('TypeError:') ||\n output.includes('ReferenceError:') ||\n output.includes('Traceback (most recent call last)');\n\n // Check for syntax errors and throw them (similar to Vercel behavior)\n if (hasError && (output.includes('SyntaxError:') || \n output.includes('invalid syntax') ||\n output.includes('Unexpected token') ||\n output.includes('Unexpected identifier') ||\n output.includes('error TS1434'))) {\n throw new Error(`Syntax error: ${output.trim()}`);\n }\n\n const actualExitCode = hasError ? 1 : (response.exitCode || 0);\n\n return {\n stdout: hasError ? '' : output,\n stderr: hasError ? output : '',\n exitCode: actualExitCode,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.id,\n provider: 'daytona'\n };\n } catch (error) {\n // Re-throw syntax errors\n if (error instanceof Error && error.message.includes('Syntax error')) {\n throw error;\n }\n throw new Error(\n `Daytona execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n runCommand: async (sandbox: DaytonaSandbox, command: string, args: string[] = []): Promise<ExecutionResult> => {\n const startTime = Date.now();\n\n try {\n // Construct full command with arguments\n const fullCommand = args.length > 0 ? `${command} ${args.join(' ')}` : command;\n\n // Execute command using Daytona's process.executeCommand method\n const response = await sandbox.process.executeCommand(fullCommand);\n\n return {\n stdout: response.result || '',\n stderr: '', // Daytona doesn't separate stderr in the response\n exitCode: response.exitCode || 0,\n executionTime: Date.now() - startTime,\n sandboxId: sandbox.id,\n provider: 'daytona'\n };\n } catch (error) {\n throw new Error(\n `Daytona command execution failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n },\n\n getInfo: async (sandbox: DaytonaSandbox): Promise<SandboxInfo> => {\n return {\n id: sandbox.id,\n provider: 'daytona',\n runtime: 'python', // Daytona default\n status: 'running',\n createdAt: new Date(),\n timeout: 300000,\n metadata: {\n daytonaSandboxId: sandbox.id\n }\n };\n },\n\n // Filesystem operations via terminal commands\n filesystem: {\n readFile: async (sandbox: DaytonaSandbox, path: string): Promise<string> => {\n try {\n const response = await sandbox.process.executeCommand(`cat \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`File not found or cannot be read: ${path}`);\n }\n return response.result || '';\n } catch (error) {\n throw new Error(`Failed to read file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n writeFile: async (sandbox: DaytonaSandbox, path: string, content: string): Promise<void> => {\n try {\n // Use base64 encoding to safely handle special characters, newlines, and binary content\n const encoded = Buffer.from(content).toString('base64');\n const response = await sandbox.process.executeCommand(`echo \"${encoded}\" | base64 -d > \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Failed to write to file: ${path}`);\n }\n } catch (error) {\n throw new Error(`Failed to write file ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n mkdir: async (sandbox: DaytonaSandbox, path: string): Promise<void> => {\n try {\n const response = await sandbox.process.executeCommand(`mkdir -p \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Failed to create directory: ${path}`);\n }\n } catch (error) {\n throw new Error(`Failed to create directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n readdir: async (sandbox: DaytonaSandbox, path: string): Promise<FileEntry[]> => {\n try {\n const response = await sandbox.process.executeCommand(`ls -la \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Directory not found or cannot be read: ${path}`);\n }\n\n // Parse ls -la output into FileEntry objects\n const lines = response.result.split('\\n').filter(line => line.trim());\n const entries: FileEntry[] = [];\n\n for (const line of lines) {\n // Skip total line and current/parent directory entries\n if (line.startsWith('total ') || line.endsWith(' .') || line.endsWith(' ..')) {\n continue;\n }\n\n // Parse ls -la format: permissions links owner group size date time name\n const parts = line.trim().split(/\\s+/);\n if (parts.length >= 9) {\n const permissions = parts[0];\n const name = parts.slice(8).join(' '); // Handle filenames with spaces\n const isDirectory = permissions.startsWith('d');\n const size = parseInt(parts[4]) || 0;\n\n entries.push({\n name,\n path: `${path}/${name}`.replace(/\\/+/g, '/'), // Clean up double slashes\n isDirectory,\n size,\n lastModified: new Date() // ls -la date parsing is complex, use current time\n });\n }\n }\n\n return entries;\n } catch (error) {\n throw new Error(`Failed to read directory ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n },\n\n exists: async (sandbox: DaytonaSandbox, path: string): Promise<boolean> => {\n try {\n const response = await sandbox.process.executeCommand(`test -e \"${path}\"`);\n return response.exitCode === 0;\n } catch (error) {\n // If command execution fails, assume file doesn't exist\n return false;\n }\n },\n\n remove: async (sandbox: DaytonaSandbox, path: string): Promise<void> => {\n try {\n const response = await sandbox.process.executeCommand(`rm -rf \"${path}\"`);\n if (response.exitCode !== 0) {\n throw new Error(`Failed to remove: ${path}`);\n }\n } catch (error) {\n throw new Error(`Failed to remove ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n }\n\n // Terminal operations not implemented - Daytona session API needs verification\n }\n }\n});\n"],"mappings":"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","names":["daytona"]}