{"version":3,"file":"index.mjs","names":["remoteCwd: string","events: ProcessOutputEvent[]","resolveKilled!: () => void"],"sources":["../../../src/providers/daytona/index.ts"],"sourcesContent":["import { Daytona, type Sandbox as DaytonaSandbox } from \"@daytona/sdk\";\nimport { randomUUID } from \"node:crypto\";\nimport { normalizeError } from \"../../core/errors\";\nimport type { SandboxProvider } from \"../../core/provider\";\nimport type { ProcessOutputEvent, SandboxProcess } from \"../../core/types\";\nimport {\n  commandString,\n  portResult,\n  toUint8Array,\n  unsupportedSnapshots,\n} from \"../../internal/provider-utils\";\nimport { daytonaCapabilities } from \"../capabilities\";\nimport { withManagedSessions } from \"../../internal/managed-provider\";\n\nexport interface DaytonaOptions {\n  apiKey?: string;\n  apiUrl?: string;\n  target?: string;\n  image?: string;\n  language?: string;\n  name?: string;\n  public?: boolean;\n}\n\nexport { daytonaCapabilities } from \"../capabilities\";\n\nexport function daytona(options: DaytonaOptions = {}): SandboxProvider<DaytonaSandbox> {\n  return withManagedSessions(\n    {\n      id: \"daytona\",\n      capabilities: daytonaCapabilities,\n      async create(createOptions) {\n        const client = new Daytona({\n          apiKey: options.apiKey,\n          apiUrl: options.apiUrl,\n          target: options.target,\n        });\n        const raw = await client.create(\n          {\n            ...(options.image ? { image: options.image } : {}),\n            language: options.language,\n            name: options.name,\n            public: options.public,\n            envVars: { ...createOptions.env },\n          },\n          {\n            timeout: createOptions.timeout ? Math.ceil(createOptions.timeout / 1_000) : undefined,\n          },\n        );\n        let remoteCwd: string;\n        try {\n          const nativeWorkDir = (await raw.getWorkDir()) ?? createOptions.cwd;\n          remoteCwd = `${nativeWorkDir.replace(/\\/$/, \"\")}/${createOptions.cwd.replace(/^\\/+/, \"\")}`;\n          try {\n            await raw.fs.getFileDetails(remoteCwd);\n          } catch (error) {\n            if (!isDaytonaNotFound(error, \"sandbox.create.cwd\")) throw error;\n            await raw.fs.createFolder(remoteCwd, \"755\");\n          }\n        } catch (error) {\n          await client.delete(raw);\n          throw error;\n        }\n        const toRemotePath = (path: string) =>\n          replacePathPrefix(path, createOptions.cwd, remoteCwd);\n        const toVirtualPath = (path: string) =>\n          replacePathPrefix(path, remoteCwd, createOptions.cwd);\n        return {\n          id: raw.id,\n          raw,\n          capabilities: daytonaCapabilities,\n          files: {\n            async write(path, value) {\n              await raw.fs.uploadFile(Buffer.from(await toUint8Array(value)), toRemotePath(path));\n            },\n            async read(path) {\n              return new Uint8Array(await raw.fs.downloadFile(toRemotePath(path)));\n            },\n            async list(path) {\n              const remotePath = toRemotePath(path);\n              return (await raw.fs.listFiles(remotePath)).map((entry) => ({\n                name: entry.name,\n                path: toVirtualPath(entry.path ?? `${remotePath.replace(/\\/$/, \"\")}/${entry.name}`),\n                type: entry.isDir ? (\"directory\" as const) : (\"file\" as const),\n                size: entry.size,\n              }));\n            },\n            async mkdir(path) {\n              await raw.fs.createFolder(toRemotePath(path), \"755\");\n            },\n            async remove(path) {\n              await raw.fs.deleteFile(toRemotePath(path), true);\n            },\n            async exists(path) {\n              try {\n                await raw.fs.getFileDetails(toRemotePath(path));\n                return true;\n              } catch (error) {\n                if (isDaytonaNotFound(error, \"files.exists\")) return false;\n                throw error;\n              }\n            },\n          },\n          async run(command, runOptions) {\n            try {\n              const started = performance.now();\n              const result = await raw.process.executeCommand(\n                commandString(command),\n                toRemotePath(runOptions.cwd!),\n                { ...runOptions.env },\n                runOptions.timeout ? Math.ceil(runOptions.timeout / 1_000) : undefined,\n              );\n              return {\n                stdout: result.result,\n                stderr: \"\",\n                exitCode: result.exitCode,\n                success: result.exitCode === 0,\n                durationMs: Math.round(performance.now() - started),\n              };\n            } catch (error) {\n              throw normalizeError(\"daytona\", \"process.run\", error);\n            }\n          },\n          async start(command, runOptions) {\n            const sessionId = `sandbox-sdk-${randomUUID()}`;\n            await raw.process.createSession(sessionId);\n            const response = await raw.process.executeSessionCommand(\n              sessionId,\n              {\n                command: sessionCommand(\n                  commandString(command),\n                  toRemotePath(runOptions.cwd!),\n                  runOptions.env,\n                ),\n                runAsync: true,\n                suppressInputEcho: true,\n              },\n              runOptions.timeout ? Math.ceil(runOptions.timeout / 1_000) : undefined,\n            );\n            const commandId = response.cmdId;\n            const events: ProcessOutputEvent[] = [];\n            const waiters = new Set<() => void>();\n            let running = true;\n            let killed = false;\n            let exitCode = 1;\n            let resolveKilled!: () => void;\n            const killedPromise = new Promise<void>((resolve) => {\n              resolveKilled = resolve;\n            });\n            const push = (stream: \"stdout\" | \"stderr\", data: string) => {\n              events.push({ stream, data, timestamp: new Date() });\n              for (const wake of waiters) wake();\n              waiters.clear();\n            };\n            const completed = raw.process\n              .getSessionCommandLogs(\n                sessionId,\n                commandId,\n                (data) => push(\"stdout\", data),\n                (data) => push(\"stderr\", data),\n              )\n              .then(async () => {\n                const info = await raw.process.getSessionCommand(sessionId, commandId);\n                exitCode = info.exitCode ?? 1;\n              })\n              .catch((error) => {\n                if (!killed) throw error;\n              })\n              .finally(() => {\n                running = false;\n                for (const wake of waiters) wake();\n                waiters.clear();\n              });\n            const process: SandboxProcess = {\n              id: commandId,\n              async status() {\n                if (killed) return \"killed\";\n                if (!running) return \"exited\";\n                const commandInfo = await raw.process.getSessionCommand(sessionId, commandId);\n                return commandInfo.exitCode == null ? \"running\" : \"exited\";\n              },\n              async *output() {\n                let index = 0;\n                while (running || index < events.length) {\n                  while (index < events.length) yield events[index++]!;\n                  if (!running) break;\n                  await new Promise<void>((resolve) => waiters.add(resolve));\n                }\n              },\n              write: (value) =>\n                raw.process.sendSessionCommandInput(\n                  sessionId,\n                  commandId,\n                  typeof value === \"string\" ? value : new TextDecoder().decode(value),\n                ),\n              async wait() {\n                await Promise.race([completed, killedPromise]);\n                return { exitCode };\n              },\n              async kill() {\n                killed = true;\n                try {\n                  await raw.process.deleteSession(sessionId);\n                } catch (error) {\n                  killed = false;\n                  throw error;\n                }\n                exitCode = 137;\n                running = false;\n                resolveKilled();\n                for (const wake of waiters) wake();\n                waiters.clear();\n              },\n            };\n            return process;\n          },\n          async expose(port) {\n            const preview = await raw.getPreviewLink(port);\n            return portResult(port, preview.url, raw.public, !raw.public, (path = \"/\", init = {}) =>\n              fetch(new URL(path, preview.url), {\n                ...init,\n                headers: {\n                  ...Object.fromEntries(new Headers(init.headers)),\n                  ...(preview.token ? { \"x-daytona-preview-token\": preview.token } : {}),\n                },\n              }),\n            );\n          },\n          snapshots: unsupportedSnapshots(\"daytona\"),\n          async stop() {\n            await client.delete(raw);\n          },\n        };\n      },\n    },\n    [],\n    {\n      stop: (sandbox) => sandbox.raw.stop(),\n      resume: (sandbox) => sandbox.raw.start(),\n      destroy: (sandbox) => sandbox.raw.delete(),\n    },\n  );\n}\n\nexport type { DaytonaSandbox };\n\nfunction isDaytonaNotFound(error: unknown, operation: string): boolean {\n  if (\n    typeof error === \"object\" &&\n    error !== null &&\n    \"statusCode\" in error &&\n    error.statusCode === 404\n  ) {\n    return true;\n  }\n  return normalizeError(\"daytona\", operation, error).code === \"not_found\";\n}\n\nfunction replacePathPrefix(path: string, from: string, to: string): string {\n  if (path === from) return to;\n  const prefix = `${from.replace(/\\/$/, \"\")}/`;\n  return path.startsWith(prefix) ? `${to.replace(/\\/$/, \"\")}/${path.slice(prefix.length)}` : path;\n}\n\nfunction sessionCommand(\n  command: string,\n  cwd: string,\n  env: Readonly<Record<string, string>> | undefined,\n): string {\n  const assignments = Object.entries(env ?? {}).map(([key, value]) =>\n    shellQuote(`${key}=${value}`),\n  );\n  return `cd ${shellQuote(cwd)} && ${assignments.length ? `env ${assignments.join(\" \")} ` : \"\"}${command}`;\n}\n\nfunction shellQuote(value: string): string {\n  return `'${value.replaceAll(\"'\", `'\"'\"'`)}'`;\n}\n"],"mappings":";;;;;;;;;;AA0BA,SAAgB,QAAQ,UAA0B,EAAE,EAAmC;AACrF,QAAO,oBACL;EACE,IAAI;EACJ,cAAc;EACd,MAAM,OAAO,eAAe;GAC1B,MAAM,SAAS,IAAI,QAAQ;IACzB,QAAQ,QAAQ;IAChB,QAAQ,QAAQ;IAChB,QAAQ,QAAQ;IACjB,CAAC;GACF,MAAM,MAAM,MAAM,OAAO,OACvB;IACE,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,OAAO,GAAG,EAAE;IACjD,UAAU,QAAQ;IAClB,MAAM,QAAQ;IACd,QAAQ,QAAQ;IAChB,SAAS,EAAE,GAAG,cAAc,KAAK;IAClC,EACD,EACE,SAAS,cAAc,UAAU,KAAK,KAAK,cAAc,UAAU,IAAM,GAAG,QAC7E,CACF;GACD,IAAIA;AACJ,OAAI;AAEF,gBAAY,IADW,MAAM,IAAI,YAAY,IAAK,cAAc,KACnC,QAAQ,OAAO,GAAG,CAAC,GAAG,cAAc,IAAI,QAAQ,QAAQ,GAAG;AACxF,QAAI;AACF,WAAM,IAAI,GAAG,eAAe,UAAU;aAC/B,OAAO;AACd,SAAI,CAAC,kBAAkB,OAAO,qBAAqB,CAAE,OAAM;AAC3D,WAAM,IAAI,GAAG,aAAa,WAAW,MAAM;;YAEtC,OAAO;AACd,UAAM,OAAO,OAAO,IAAI;AACxB,UAAM;;GAER,MAAM,gBAAgB,SACpB,kBAAkB,MAAM,cAAc,KAAK,UAAU;GACvD,MAAM,iBAAiB,SACrB,kBAAkB,MAAM,WAAW,cAAc,IAAI;AACvD,UAAO;IACL,IAAI,IAAI;IACR;IACA,cAAc;IACd,OAAO;KACL,MAAM,MAAM,MAAM,OAAO;AACvB,YAAM,IAAI,GAAG,WAAW,OAAO,KAAK,MAAM,aAAa,MAAM,CAAC,EAAE,aAAa,KAAK,CAAC;;KAErF,MAAM,KAAK,MAAM;AACf,aAAO,IAAI,WAAW,MAAM,IAAI,GAAG,aAAa,aAAa,KAAK,CAAC,CAAC;;KAEtE,MAAM,KAAK,MAAM;MACf,MAAM,aAAa,aAAa,KAAK;AACrC,cAAQ,MAAM,IAAI,GAAG,UAAU,WAAW,EAAE,KAAK,WAAW;OAC1D,MAAM,MAAM;OACZ,MAAM,cAAc,MAAM,QAAQ,GAAG,WAAW,QAAQ,OAAO,GAAG,CAAC,GAAG,MAAM,OAAO;OACnF,MAAM,MAAM,QAAS,cAAyB;OAC9C,MAAM,MAAM;OACb,EAAE;;KAEL,MAAM,MAAM,MAAM;AAChB,YAAM,IAAI,GAAG,aAAa,aAAa,KAAK,EAAE,MAAM;;KAEtD,MAAM,OAAO,MAAM;AACjB,YAAM,IAAI,GAAG,WAAW,aAAa,KAAK,EAAE,KAAK;;KAEnD,MAAM,OAAO,MAAM;AACjB,UAAI;AACF,aAAM,IAAI,GAAG,eAAe,aAAa,KAAK,CAAC;AAC/C,cAAO;eACA,OAAO;AACd,WAAI,kBAAkB,OAAO,eAAe,CAAE,QAAO;AACrD,aAAM;;;KAGX;IACD,MAAM,IAAI,SAAS,YAAY;AAC7B,SAAI;MACF,MAAM,UAAU,YAAY,KAAK;MACjC,MAAM,SAAS,MAAM,IAAI,QAAQ,eAC/B,cAAc,QAAQ,EACtB,aAAa,WAAW,IAAK,EAC7B,EAAE,GAAG,WAAW,KAAK,EACrB,WAAW,UAAU,KAAK,KAAK,WAAW,UAAU,IAAM,GAAG,OAC9D;AACD,aAAO;OACL,QAAQ,OAAO;OACf,QAAQ;OACR,UAAU,OAAO;OACjB,SAAS,OAAO,aAAa;OAC7B,YAAY,KAAK,MAAM,YAAY,KAAK,GAAG,QAAQ;OACpD;cACM,OAAO;AACd,YAAM,eAAe,WAAW,eAAe,MAAM;;;IAGzD,MAAM,MAAM,SAAS,YAAY;KAC/B,MAAM,YAAY,eAAe,YAAY;AAC7C,WAAM,IAAI,QAAQ,cAAc,UAAU;KAc1C,MAAM,aAbW,MAAM,IAAI,QAAQ,sBACjC,WACA;MACE,SAAS,eACP,cAAc,QAAQ,EACtB,aAAa,WAAW,IAAK,EAC7B,WAAW,IACZ;MACD,UAAU;MACV,mBAAmB;MACpB,EACD,WAAW,UAAU,KAAK,KAAK,WAAW,UAAU,IAAM,GAAG,OAC9D,EAC0B;KAC3B,MAAMC,SAA+B,EAAE;KACvC,MAAM,0BAAU,IAAI,KAAiB;KACrC,IAAI,UAAU;KACd,IAAI,SAAS;KACb,IAAI,WAAW;KACf,IAAIC;KACJ,MAAM,gBAAgB,IAAI,SAAe,YAAY;AACnD,sBAAgB;OAChB;KACF,MAAM,QAAQ,QAA6B,SAAiB;AAC1D,aAAO,KAAK;OAAE;OAAQ;OAAM,2BAAW,IAAI,MAAM;OAAE,CAAC;AACpD,WAAK,MAAM,QAAQ,QAAS,OAAM;AAClC,cAAQ,OAAO;;KAEjB,MAAM,YAAY,IAAI,QACnB,sBACC,WACA,YACC,SAAS,KAAK,UAAU,KAAK,GAC7B,SAAS,KAAK,UAAU,KAAK,CAC/B,CACA,KAAK,YAAY;AAEhB,kBADa,MAAM,IAAI,QAAQ,kBAAkB,WAAW,UAAU,EACtD,YAAY;OAC5B,CACD,OAAO,UAAU;AAChB,UAAI,CAAC,OAAQ,OAAM;OACnB,CACD,cAAc;AACb,gBAAU;AACV,WAAK,MAAM,QAAQ,QAAS,OAAM;AAClC,cAAQ,OAAO;OACf;AA0CJ,YAzCgC;MAC9B,IAAI;MACJ,MAAM,SAAS;AACb,WAAI,OAAQ,QAAO;AACnB,WAAI,CAAC,QAAS,QAAO;AAErB,eADoB,MAAM,IAAI,QAAQ,kBAAkB,WAAW,UAAU,EAC1D,YAAY,OAAO,YAAY;;MAEpD,OAAO,SAAS;OACd,IAAI,QAAQ;AACZ,cAAO,WAAW,QAAQ,OAAO,QAAQ;AACvC,eAAO,QAAQ,OAAO,OAAQ,OAAM,OAAO;AAC3C,YAAI,CAAC,QAAS;AACd,cAAM,IAAI,SAAe,YAAY,QAAQ,IAAI,QAAQ,CAAC;;;MAG9D,QAAQ,UACN,IAAI,QAAQ,wBACV,WACA,WACA,OAAO,UAAU,WAAW,QAAQ,IAAI,aAAa,CAAC,OAAO,MAAM,CACpE;MACH,MAAM,OAAO;AACX,aAAM,QAAQ,KAAK,CAAC,WAAW,cAAc,CAAC;AAC9C,cAAO,EAAE,UAAU;;MAErB,MAAM,OAAO;AACX,gBAAS;AACT,WAAI;AACF,cAAM,IAAI,QAAQ,cAAc,UAAU;gBACnC,OAAO;AACd,iBAAS;AACT,cAAM;;AAER,kBAAW;AACX,iBAAU;AACV,sBAAe;AACf,YAAK,MAAM,QAAQ,QAAS,OAAM;AAClC,eAAQ,OAAO;;MAElB;;IAGH,MAAM,OAAO,MAAM;KACjB,MAAM,UAAU,MAAM,IAAI,eAAe,KAAK;AAC9C,YAAO,WAAW,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,IAAI,SAAS,OAAO,KAAK,OAAO,EAAE,KAClF,MAAM,IAAI,IAAI,MAAM,QAAQ,IAAI,EAAE;MAChC,GAAG;MACH,SAAS;OACP,GAAG,OAAO,YAAY,IAAI,QAAQ,KAAK,QAAQ,CAAC;OAChD,GAAI,QAAQ,QAAQ,EAAE,2BAA2B,QAAQ,OAAO,GAAG,EAAE;OACtE;MACF,CAAC,CACH;;IAEH,WAAW,qBAAqB,UAAU;IAC1C,MAAM,OAAO;AACX,WAAM,OAAO,OAAO,IAAI;;IAE3B;;EAEJ,EACD,EAAE,EACF;EACE,OAAO,YAAY,QAAQ,IAAI,MAAM;EACrC,SAAS,YAAY,QAAQ,IAAI,OAAO;EACxC,UAAU,YAAY,QAAQ,IAAI,QAAQ;EAC3C,CACF;;AAKH,SAAS,kBAAkB,OAAgB,WAA4B;AACrE,KACE,OAAO,UAAU,YACjB,UAAU,QACV,gBAAgB,SAChB,MAAM,eAAe,IAErB,QAAO;AAET,QAAO,eAAe,WAAW,WAAW,MAAM,CAAC,SAAS;;AAG9D,SAAS,kBAAkB,MAAc,MAAc,IAAoB;AACzE,KAAI,SAAS,KAAM,QAAO;CAC1B,MAAM,SAAS,GAAG,KAAK,QAAQ,OAAO,GAAG,CAAC;AAC1C,QAAO,KAAK,WAAW,OAAO,GAAG,GAAG,GAAG,QAAQ,OAAO,GAAG,CAAC,GAAG,KAAK,MAAM,OAAO,OAAO,KAAK;;AAG7F,SAAS,eACP,SACA,KACA,KACQ;CACR,MAAM,cAAc,OAAO,QAAQ,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,WACvD,WAAW,GAAG,IAAI,GAAG,QAAQ,CAC9B;AACD,QAAO,MAAM,WAAW,IAAI,CAAC,MAAM,YAAY,SAAS,OAAO,YAAY,KAAK,IAAI,CAAC,KAAK,KAAK;;AAGjG,SAAS,WAAW,OAAuB;AACzC,QAAO,IAAI,MAAM,WAAW,KAAK,QAAQ,CAAC"}