@alchemy.run/e2b 0.0.0 → 2.0.0-beta.86

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.
Files changed (284) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +56 -4
  3. package/lib/ApiKey.d.ts +53 -0
  4. package/lib/ApiKey.d.ts.map +1 -0
  5. package/lib/ApiKey.js +107 -0
  6. package/lib/ApiKey.js.map +1 -0
  7. package/lib/AuthProvider.d.ts +60 -0
  8. package/lib/AuthProvider.d.ts.map +1 -0
  9. package/lib/AuthProvider.js +293 -0
  10. package/lib/AuthProvider.js.map +1 -0
  11. package/lib/Bootstrap.d.ts +7 -0
  12. package/lib/Bootstrap.d.ts.map +1 -0
  13. package/lib/Bootstrap.js +25 -0
  14. package/lib/Bootstrap.js.map +1 -0
  15. package/lib/ConnectSandbox.d.ts +67 -0
  16. package/lib/ConnectSandbox.d.ts.map +1 -0
  17. package/lib/ConnectSandbox.js +3 -0
  18. package/lib/ConnectSandbox.js.map +1 -0
  19. package/lib/ConnectSandboxHttp.d.ts +22 -0
  20. package/lib/ConnectSandboxHttp.d.ts.map +1 -0
  21. package/lib/ConnectSandboxHttp.js +30 -0
  22. package/lib/ConnectSandboxHttp.js.map +1 -0
  23. package/lib/Contributions.d.ts +7 -0
  24. package/lib/Contributions.d.ts.map +1 -0
  25. package/lib/Contributions.js +6 -0
  26. package/lib/Contributions.js.map +1 -0
  27. package/lib/CreateSandbox.d.ts +139 -0
  28. package/lib/CreateSandbox.d.ts.map +1 -0
  29. package/lib/CreateSandbox.js +3 -0
  30. package/lib/CreateSandbox.js.map +1 -0
  31. package/lib/CreateSandboxHttp.d.ts +22 -0
  32. package/lib/CreateSandboxHttp.d.ts.map +1 -0
  33. package/lib/CreateSandboxHttp.js +99 -0
  34. package/lib/CreateSandboxHttp.js.map +1 -0
  35. package/lib/CreateSecret.d.ts +57 -0
  36. package/lib/CreateSecret.d.ts.map +1 -0
  37. package/lib/CreateSecret.js +3 -0
  38. package/lib/CreateSecret.js.map +1 -0
  39. package/lib/CreateSecretHttp.d.ts +20 -0
  40. package/lib/CreateSecretHttp.d.ts.map +1 -0
  41. package/lib/CreateSecretHttp.js +64 -0
  42. package/lib/CreateSecretHttp.js.map +1 -0
  43. package/lib/CreateSnapshot.d.ts +53 -0
  44. package/lib/CreateSnapshot.d.ts.map +1 -0
  45. package/lib/CreateSnapshot.js +3 -0
  46. package/lib/CreateSnapshot.js.map +1 -0
  47. package/lib/CreateSnapshotHttp.d.ts +20 -0
  48. package/lib/CreateSnapshotHttp.d.ts.map +1 -0
  49. package/lib/CreateSnapshotHttp.js +41 -0
  50. package/lib/CreateSnapshotHttp.js.map +1 -0
  51. package/lib/CreateTemplate.d.ts +96 -0
  52. package/lib/CreateTemplate.d.ts.map +1 -0
  53. package/lib/CreateTemplate.js +3 -0
  54. package/lib/CreateTemplate.js.map +1 -0
  55. package/lib/CreateTemplateHttp.d.ts +20 -0
  56. package/lib/CreateTemplateHttp.d.ts.map +1 -0
  57. package/lib/CreateTemplateHttp.js +99 -0
  58. package/lib/CreateTemplateHttp.js.map +1 -0
  59. package/lib/CreateVolume.d.ts +58 -0
  60. package/lib/CreateVolume.d.ts.map +1 -0
  61. package/lib/CreateVolume.js +3 -0
  62. package/lib/CreateVolume.js.map +1 -0
  63. package/lib/CreateVolumeHttp.d.ts +20 -0
  64. package/lib/CreateVolumeHttp.d.ts.map +1 -0
  65. package/lib/CreateVolumeHttp.js +51 -0
  66. package/lib/CreateVolumeHttp.js.map +1 -0
  67. package/lib/Credentials.d.ts +18 -0
  68. package/lib/Credentials.d.ts.map +1 -0
  69. package/lib/Credentials.js +55 -0
  70. package/lib/Credentials.js.map +1 -0
  71. package/lib/E2BBindings.d.ts +35 -0
  72. package/lib/E2BBindings.d.ts.map +1 -0
  73. package/lib/E2BBindings.js +127 -0
  74. package/lib/E2BBindings.js.map +1 -0
  75. package/lib/Errors.d.ts +61 -0
  76. package/lib/Errors.d.ts.map +1 -0
  77. package/lib/Errors.js +23 -0
  78. package/lib/Errors.js.map +1 -0
  79. package/lib/InferEnv.d.ts +26 -0
  80. package/lib/InferEnv.d.ts.map +1 -0
  81. package/lib/InferEnv.js +1 -0
  82. package/lib/InferEnv.js.map +1 -0
  83. package/lib/MountVolume.d.ts +86 -0
  84. package/lib/MountVolume.d.ts.map +1 -0
  85. package/lib/MountVolume.js +3 -0
  86. package/lib/MountVolume.js.map +1 -0
  87. package/lib/MountVolumeLive.d.ts +23 -0
  88. package/lib/MountVolumeLive.d.ts.map +1 -0
  89. package/lib/MountVolumeLive.js +41 -0
  90. package/lib/MountVolumeLive.js.map +1 -0
  91. package/lib/Providers.d.ts +14 -0
  92. package/lib/Providers.d.ts.map +1 -0
  93. package/lib/Providers.js +23 -0
  94. package/lib/Providers.js.map +1 -0
  95. package/lib/ReadTeam.d.ts +41 -0
  96. package/lib/ReadTeam.d.ts.map +1 -0
  97. package/lib/ReadTeam.js +3 -0
  98. package/lib/ReadTeam.js.map +1 -0
  99. package/lib/ReadTeamHttp.d.ts +20 -0
  100. package/lib/ReadTeamHttp.d.ts.map +1 -0
  101. package/lib/ReadTeamHttp.js +40 -0
  102. package/lib/ReadTeamHttp.js.map +1 -0
  103. package/lib/ReadVolume.d.ts +25 -0
  104. package/lib/ReadVolume.d.ts.map +1 -0
  105. package/lib/ReadVolume.js +3 -0
  106. package/lib/ReadVolume.js.map +1 -0
  107. package/lib/ReadVolumeHttp.d.ts +20 -0
  108. package/lib/ReadVolumeHttp.d.ts.map +1 -0
  109. package/lib/ReadVolumeHttp.js +27 -0
  110. package/lib/ReadVolumeHttp.js.map +1 -0
  111. package/lib/ReadWebhook.d.ts +32 -0
  112. package/lib/ReadWebhook.d.ts.map +1 -0
  113. package/lib/ReadWebhook.js +3 -0
  114. package/lib/ReadWebhook.js.map +1 -0
  115. package/lib/ReadWebhookHttp.d.ts +20 -0
  116. package/lib/ReadWebhookHttp.d.ts.map +1 -0
  117. package/lib/ReadWebhookHttp.js +31 -0
  118. package/lib/ReadWebhookHttp.js.map +1 -0
  119. package/lib/ReadWriteVolume.d.ts +26 -0
  120. package/lib/ReadWriteVolume.d.ts.map +1 -0
  121. package/lib/ReadWriteVolume.js +3 -0
  122. package/lib/ReadWriteVolume.js.map +1 -0
  123. package/lib/ReadWriteVolumeHttp.d.ts +20 -0
  124. package/lib/ReadWriteVolumeHttp.d.ts.map +1 -0
  125. package/lib/ReadWriteVolumeHttp.js +27 -0
  126. package/lib/ReadWriteVolumeHttp.js.map +1 -0
  127. package/lib/Sandbox.d.ts +295 -0
  128. package/lib/Sandbox.d.ts.map +1 -0
  129. package/lib/Sandbox.js +351 -0
  130. package/lib/Sandbox.js.map +1 -0
  131. package/lib/SandboxClient.d.ts +226 -0
  132. package/lib/SandboxClient.d.ts.map +1 -0
  133. package/lib/SandboxClient.js +1 -0
  134. package/lib/SandboxClient.js.map +1 -0
  135. package/lib/SandboxEvents.d.ts +87 -0
  136. package/lib/SandboxEvents.d.ts.map +1 -0
  137. package/lib/SandboxEvents.js +39 -0
  138. package/lib/SandboxEvents.js.map +1 -0
  139. package/lib/SandboxEventsLive.d.ts +13 -0
  140. package/lib/SandboxEventsLive.d.ts.map +1 -0
  141. package/lib/SandboxEventsLive.js +80 -0
  142. package/lib/SandboxEventsLive.js.map +1 -0
  143. package/lib/Secret.d.ts +105 -0
  144. package/lib/Secret.d.ts.map +1 -0
  145. package/lib/Secret.js +161 -0
  146. package/lib/Secret.js.map +1 -0
  147. package/lib/Snapshot.d.ts +118 -0
  148. package/lib/Snapshot.d.ts.map +1 -0
  149. package/lib/Snapshot.js +158 -0
  150. package/lib/Snapshot.js.map +1 -0
  151. package/lib/Template.d.ts +313 -0
  152. package/lib/Template.d.ts.map +1 -0
  153. package/lib/Template.js +421 -0
  154. package/lib/Template.js.map +1 -0
  155. package/lib/Volume.d.ts +88 -0
  156. package/lib/Volume.d.ts.map +1 -0
  157. package/lib/Volume.js +136 -0
  158. package/lib/Volume.js.map +1 -0
  159. package/lib/VolumeFiles.d.ts +39 -0
  160. package/lib/VolumeFiles.d.ts.map +1 -0
  161. package/lib/VolumeFiles.js +1 -0
  162. package/lib/VolumeFiles.js.map +1 -0
  163. package/lib/Webhook.d.ts +83 -0
  164. package/lib/Webhook.d.ts.map +1 -0
  165. package/lib/Webhook.js +138 -0
  166. package/lib/Webhook.js.map +1 -0
  167. package/lib/WriteSecret.d.ts +34 -0
  168. package/lib/WriteSecret.d.ts.map +1 -0
  169. package/lib/WriteSecret.js +3 -0
  170. package/lib/WriteSecret.js.map +1 -0
  171. package/lib/WriteSecretHttp.d.ts +20 -0
  172. package/lib/WriteSecretHttp.d.ts.map +1 -0
  173. package/lib/WriteSecretHttp.js +37 -0
  174. package/lib/WriteSecretHttp.js.map +1 -0
  175. package/lib/WriteVolume.d.ts +25 -0
  176. package/lib/WriteVolume.d.ts.map +1 -0
  177. package/lib/WriteVolume.js +3 -0
  178. package/lib/WriteVolume.js.map +1 -0
  179. package/lib/WriteVolumeHttp.d.ts +20 -0
  180. package/lib/WriteVolumeHttp.d.ts.map +1 -0
  181. package/lib/WriteVolumeHttp.js +27 -0
  182. package/lib/WriteVolumeHttp.js.map +1 -0
  183. package/lib/index.d.ts +43 -0
  184. package/lib/index.d.ts.map +1 -0
  185. package/lib/index.js +43 -0
  186. package/lib/index.js.map +1 -0
  187. package/lib/internal/Declared.d.ts +29 -0
  188. package/lib/internal/Declared.d.ts.map +1 -0
  189. package/lib/internal/Declared.js +31 -0
  190. package/lib/internal/Declared.js.map +1 -0
  191. package/lib/internal/Login.d.ts +45 -0
  192. package/lib/internal/Login.d.ts.map +1 -0
  193. package/lib/internal/Login.js +157 -0
  194. package/lib/internal/Login.js.map +1 -0
  195. package/lib/internal/Ownership.d.ts +29 -0
  196. package/lib/internal/Ownership.d.ts.map +1 -0
  197. package/lib/internal/Ownership.js +49 -0
  198. package/lib/internal/Ownership.js.map +1 -0
  199. package/lib/internal/Program.d.ts +31 -0
  200. package/lib/internal/Program.d.ts.map +1 -0
  201. package/lib/internal/Program.js +60 -0
  202. package/lib/internal/Program.js.map +1 -0
  203. package/lib/internal/SandboxHandle.d.ts +25 -0
  204. package/lib/internal/SandboxHandle.d.ts.map +1 -0
  205. package/lib/internal/SandboxHandle.js +316 -0
  206. package/lib/internal/SandboxHandle.js.map +1 -0
  207. package/lib/internal/SnapshotBuild.d.ts +19 -0
  208. package/lib/internal/SnapshotBuild.d.ts.map +1 -0
  209. package/lib/internal/SnapshotBuild.js +49 -0
  210. package/lib/internal/SnapshotBuild.js.map +1 -0
  211. package/lib/internal/Tar.d.ts +10 -0
  212. package/lib/internal/Tar.d.ts.map +1 -0
  213. package/lib/internal/Tar.js +61 -0
  214. package/lib/internal/Tar.js.map +1 -0
  215. package/lib/internal/TemplateBuild.d.ts +142 -0
  216. package/lib/internal/TemplateBuild.d.ts.map +1 -0
  217. package/lib/internal/TemplateBuild.js +220 -0
  218. package/lib/internal/TemplateBuild.js.map +1 -0
  219. package/lib/internal/TemplatePlan.d.ts +57 -0
  220. package/lib/internal/TemplatePlan.d.ts.map +1 -0
  221. package/lib/internal/TemplatePlan.js +185 -0
  222. package/lib/internal/TemplatePlan.js.map +1 -0
  223. package/lib/internal/VolumeHttp.d.ts +5 -0
  224. package/lib/internal/VolumeHttp.d.ts.map +1 -0
  225. package/lib/internal/VolumeHttp.js +46 -0
  226. package/lib/internal/VolumeHttp.js.map +1 -0
  227. package/package.json +62 -3
  228. package/src/ApiKey.ts +148 -0
  229. package/src/AuthProvider.ts +437 -0
  230. package/src/Bootstrap.ts +51 -0
  231. package/src/ConnectSandbox.ts +71 -0
  232. package/src/ConnectSandboxHttp.ts +38 -0
  233. package/src/Contributions.ts +9 -0
  234. package/src/CreateSandbox.ts +157 -0
  235. package/src/CreateSandboxHttp.ts +131 -0
  236. package/src/CreateSecret.ts +65 -0
  237. package/src/CreateSecretHttp.ts +94 -0
  238. package/src/CreateSnapshot.ts +64 -0
  239. package/src/CreateSnapshotHttp.ts +55 -0
  240. package/src/CreateTemplate.ts +135 -0
  241. package/src/CreateTemplateHttp.ts +152 -0
  242. package/src/CreateVolume.ts +65 -0
  243. package/src/CreateVolumeHttp.ts +80 -0
  244. package/src/Credentials.ts +81 -0
  245. package/src/E2BBindings.ts +160 -0
  246. package/src/Errors.ts +47 -0
  247. package/src/InferEnv.ts +27 -0
  248. package/src/MountVolume.ts +92 -0
  249. package/src/MountVolumeLive.ts +49 -0
  250. package/src/Providers.ts +48 -0
  251. package/src/ReadTeam.ts +55 -0
  252. package/src/ReadTeamHttp.ts +44 -0
  253. package/src/ReadVolume.ts +29 -0
  254. package/src/ReadVolumeHttp.ts +32 -0
  255. package/src/ReadWebhook.ts +41 -0
  256. package/src/ReadWebhookHttp.ts +42 -0
  257. package/src/ReadWriteVolume.ts +30 -0
  258. package/src/ReadWriteVolumeHttp.ts +32 -0
  259. package/src/Sandbox.ts +581 -0
  260. package/src/SandboxClient.ts +268 -0
  261. package/src/SandboxEvents.ts +101 -0
  262. package/src/SandboxEventsLive.ts +118 -0
  263. package/src/Secret.ts +229 -0
  264. package/src/Snapshot.ts +234 -0
  265. package/src/Template.ts +636 -0
  266. package/src/Volume.ts +173 -0
  267. package/src/VolumeFiles.ts +53 -0
  268. package/src/Webhook.ts +215 -0
  269. package/src/WriteSecret.ts +39 -0
  270. package/src/WriteSecretHttp.ts +43 -0
  271. package/src/WriteVolume.ts +29 -0
  272. package/src/WriteVolumeHttp.ts +32 -0
  273. package/src/globals.d.ts +2 -0
  274. package/src/index.ts +42 -0
  275. package/src/internal/Declared.ts +80 -0
  276. package/src/internal/Login.ts +210 -0
  277. package/src/internal/Ownership.ts +67 -0
  278. package/src/internal/Program.ts +75 -0
  279. package/src/internal/SandboxHandle.ts +534 -0
  280. package/src/internal/SnapshotBuild.ts +74 -0
  281. package/src/internal/Tar.ts +74 -0
  282. package/src/internal/TemplateBuild.ts +383 -0
  283. package/src/internal/TemplatePlan.ts +230 -0
  284. package/src/internal/VolumeHttp.ts +88 -0
package/src/Errors.ts ADDED
@@ -0,0 +1,47 @@
1
+ import * as Data from "effect/Data";
2
+
3
+ /** E2B answered in a way a lifecycle step cannot continue from (e.g. a resource vanished right after create). */
4
+ export class E2BUnexpectedResponse extends Data.TaggedError("E2B.UnexpectedResponse")<{
5
+ readonly message: string;
6
+ readonly cause?: unknown;
7
+ }> {}
8
+
9
+ /** A template build finished in a failed state. */
10
+ export class TemplateBuildFailed extends Data.TaggedError("E2B.TemplateBuildFailed")<{
11
+ readonly message: string;
12
+ readonly templateId: string;
13
+ readonly buildId: string;
14
+ readonly reason?: string;
15
+ readonly logs?: ReadonlyArray<string>;
16
+ }> {}
17
+
18
+ /** A Dockerfile uses something E2B's builder does not support. Raised at plan time. */
19
+ export class UnsupportedDockerfileInstruction extends Data.TaggedError(
20
+ "E2B.UnsupportedDockerfileInstruction",
21
+ )<{
22
+ readonly message: string;
23
+ readonly line?: number;
24
+ }> {}
25
+
26
+ /** A command run while building a snapshot exited non-zero. */
27
+ export class SnapshotSetupFailed extends Data.TaggedError("E2B.SnapshotSetupFailed")<{
28
+ readonly message: string;
29
+ readonly command: string;
30
+ readonly exitCode: number;
31
+ readonly stderr: string;
32
+ }> {}
33
+
34
+ /** `E2B.CreateSandbox()` was bound without a base and `create()` was called without `templateID`. */
35
+ export class SandboxBaseMissing extends Data.TaggedError("E2B.SandboxBaseMissing")<{
36
+ readonly message: string;
37
+ }> {}
38
+
39
+ /** `exec` killed a command that ran past its `timeout`. */
40
+ export class ExecTimedOut extends Data.TaggedError("E2B.ExecTimedOut")<{
41
+ readonly pid: number;
42
+ readonly timeoutMs: number;
43
+ }> {
44
+ override get message() {
45
+ return `process ${this.pid} ran longer than ${this.timeoutMs}ms and was killed`;
46
+ }
47
+ }
@@ -0,0 +1,27 @@
1
+ import type * as Effect from "effect/Effect";
2
+
3
+ /**
4
+ * Typed `env` for an async (non-Effect) {@link Template} program. A
5
+ * template program reads its bindings from environment variables, so every
6
+ * entry is a `string`: cast `process.env` to it.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * export const Worker = E2B.Template("Worker", {
11
+ * image: "node:22-bookworm",
12
+ * main: "./src/worker.mjs",
13
+ * env: { QUEUE_URL: queue.url },
14
+ * });
15
+ * export type WorkerEnv = E2B.InferEnv<typeof Worker>;
16
+ * ```
17
+ */
18
+ export type InferEnv<F> =
19
+ F extends Effect.Effect<infer A, infer _E, infer _R>
20
+ ? InferEnv<A>
21
+ : F extends { readonly Props: { readonly env?: infer E } }
22
+ ? InferEnvRecord<Exclude<E, undefined>>
23
+ : InferEnvRecord<F>;
24
+
25
+ type InferEnvRecord<E> = {
26
+ readonly [K in keyof E]: string;
27
+ };
@@ -0,0 +1,92 @@
1
+ import * as Binding from "alchemy/Binding";
2
+ import type { RuntimeContext } from "alchemy/RuntimeContext";
3
+ import type * as Effect from "effect/Effect";
4
+ import type { Volume } from "./Volume.ts";
5
+
6
+ /**
7
+ * A volume to mount: a declared `E2B.Volume`, or a volume `CreateVolume`
8
+ * returned. E2B mounts volumes by name.
9
+ */
10
+ export interface MountableVolume {
11
+ readonly name: string;
12
+ }
13
+
14
+ /** A volume mounted into a sandbox at `path`. */
15
+ export interface VolumeMount {
16
+ readonly volume: MountableVolume;
17
+ /** Absolute path inside the sandbox. */
18
+ readonly path: string;
19
+ }
20
+
21
+ /**
22
+ * A volume bound to a host with `E2B.MountVolume`. Its name is read at
23
+ * runtime, so pass the whole reference to `mounts`.
24
+ */
25
+ export interface BoundVolumeMount {
26
+ readonly volume: { readonly name: Effect.Effect<string, never, RuntimeContext> };
27
+ /** Absolute path inside the sandbox. */
28
+ readonly path: string;
29
+ }
30
+
31
+ export interface MountVolumeOptions {
32
+ /** Absolute path inside the sandbox. */
33
+ readonly path: string;
34
+ }
35
+
36
+ /**
37
+ * Mount a declared `E2B.Volume` at a path.
38
+ *
39
+ * In an `E2B.Template` program, the mount becomes part of the template:
40
+ * every sandbox created from it (with `CreateSandbox(template)` or
41
+ * `E2B.Sandbox({ template })`) mounts the volume, and the program finds its
42
+ * files at `path`. E2B attaches volumes when a sandbox is created, so a
43
+ * sandbox already running keeps the mounts it started with.
44
+ *
45
+ * Anywhere else (a Worker, a Function), it returns a reference to pass to
46
+ * `create({ mounts })`.
47
+ *
48
+ * E2B enables volumes per team; on a team without them, deploying the
49
+ * volume fails with `VolumesNotEnabled`.
50
+ *
51
+ * ### In a template program
52
+ * **Example:** A program that serves a volume's files
53
+ * ```typescript
54
+ * export default class Api extends E2B.Template<Api>()(
55
+ * "Api",
56
+ * { main: import.meta.url },
57
+ * Effect.gen(function* () {
58
+ * const data = yield* E2B.MountVolume(Data, { path: "/data" });
59
+ * const fs = yield* FileSystem.FileSystem;
60
+ * return {
61
+ * fetch: Effect.gen(function* () {
62
+ * const files = yield* fs.readDirectory(data.path);
63
+ * return yield* HttpServerResponse.json(files);
64
+ * }).pipe(Effect.orDie),
65
+ * };
66
+ * }).pipe(Effect.provide(E2B.MountVolumeLive)),
67
+ * ) {}
68
+ * ```
69
+ *
70
+ * ### From a Worker
71
+ * **Example:** Mount a shared volume and a per-user one
72
+ * ```typescript
73
+ * const data = yield* E2B.MountVolume(Data, { path: "/data" });
74
+ * const sandboxes = yield* E2B.CreateSandbox(Agent);
75
+ * const volumes = yield* E2B.CreateVolume();
76
+ * // in fetch:
77
+ * const home = yield* volumes.getOrCreate(`home-${user}`);
78
+ * const sandbox = yield* sandboxes.create({
79
+ * mounts: [data, { volume: home, path: "/home/user/work" }],
80
+ * });
81
+ * ```
82
+ *
83
+ * @binding
84
+ * @product Volume
85
+ */
86
+ export interface MountVolume extends Binding.Service<
87
+ MountVolume,
88
+ "E2B.MountVolume",
89
+ (volume: Volume, options: MountVolumeOptions) => Effect.Effect<BoundVolumeMount>
90
+ > {}
91
+
92
+ export const MountVolume = Binding.Service<MountVolume>("E2B.MountVolume");
@@ -0,0 +1,49 @@
1
+ import * as Binding from "alchemy/Binding";
2
+ import * as Output from "alchemy/Output";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Layer from "effect/Layer";
5
+ import { MountVolume, type BoundVolumeMount, type MountVolumeOptions } from "./MountVolume.ts";
6
+ import type { Template } from "./Template.ts";
7
+ import type { Volume } from "./Volume.ts";
8
+
9
+ /**
10
+ * The implementation of {@link MountVolume}. It makes no API call: E2B
11
+ * mounts a volume by name when a sandbox is created, so the binding binds
12
+ * the name onto the host and, in an `E2B.Template` program, adds the mount
13
+ * to the template.
14
+ *
15
+ * ### Provide the layer
16
+ * **Example:** On a Worker
17
+ * ```typescript
18
+ * Effect.gen(function* () {
19
+ * const data = yield* E2B.MountVolume(Data, { path: "/data" });
20
+ * // ...
21
+ * }).pipe(Effect.provide(E2B.MountVolumeLive))
22
+ * ```
23
+ *
24
+ * @layer
25
+ * @product Volume
26
+ * @provides E2B.MountVolume
27
+ */
28
+ export const MountVolumeLive = Layer.succeed(
29
+ MountVolume,
30
+ Effect.fn("E2B.MountVolume")(function* (volume: Volume, options: MountVolumeOptions) {
31
+ if (!globalThis.__ALCHEMY_RUNTIME__) {
32
+ const host = yield* Binding.Host;
33
+ // A mount is part of a template program's own sandboxes, so it is
34
+ // attached to the template itself. `Binding.Host` is typed as a bare
35
+ // `ResourceLike` (a host's binding contract is only known per type),
36
+ // hence the cast once the type is checked.
37
+ if (host?.Type === "E2B.Template") {
38
+ yield* (host as unknown as Template).bind`${volume}`({
39
+ volumes: [{ volume: { name: volume.name }, path: options.path }],
40
+ });
41
+ }
42
+ }
43
+ const name = yield* Output.named(
44
+ volume.name as Output.Output<string, never>,
45
+ `E2B_VOLUME_${volume.LogicalId}`,
46
+ ).asEffect();
47
+ return { volume: { name }, path: options.path } satisfies BoundVolumeMount;
48
+ }),
49
+ );
@@ -0,0 +1,48 @@
1
+ import { CredentialsStoreLive } from "alchemy/Auth/Credentials";
2
+ import { ProfileStoreLive } from "alchemy/Auth/Profile";
3
+ import * as Provider from "alchemy/Provider";
4
+ import * as FetchHttpClient from "effect/http/FetchHttpClient";
5
+ import * as Layer from "effect/Layer";
6
+ import { ApiKey, ApiKeyProvider } from "./ApiKey.ts";
7
+ import { E2BAuth } from "./AuthProvider.ts";
8
+ import * as Credentials from "./Credentials.ts";
9
+ import { Sandbox, SandboxProvider } from "./Sandbox.ts";
10
+ import { Secret, SecretProvider } from "./Secret.ts";
11
+ import { Snapshot, SnapshotProvider } from "./Snapshot.ts";
12
+ import { Template, TemplateProvider } from "./Template.ts";
13
+ import { Volume, VolumeProvider } from "./Volume.ts";
14
+ import { Webhook, WebhookProvider } from "./Webhook.ts";
15
+
16
+ export { Credentials } from "@distilled.cloud/e2b/Credentials";
17
+
18
+ export class Providers extends Provider.ProviderCollection<Providers>()("E2B") {}
19
+
20
+ export type ProviderRequirements = Layer.Services<ReturnType<typeof providers>>;
21
+
22
+ /**
23
+ * E2B providers and credentials. Wires up every E2B resource and registers
24
+ * the E2B AuthProvider so `alchemy profile edit --add E2B` can configure it.
25
+ */
26
+ export const providers = () =>
27
+ Layer.effect(
28
+ Providers,
29
+ Provider.collection([ApiKey, Sandbox, Secret, Snapshot, Template, Volume, Webhook]),
30
+ ).pipe(
31
+ Layer.provide(
32
+ Layer.mergeAll(
33
+ ApiKeyProvider(),
34
+ SandboxProvider(),
35
+ SecretProvider(),
36
+ SnapshotProvider(),
37
+ TemplateProvider(),
38
+ VolumeProvider(),
39
+ WebhookProvider(),
40
+ ),
41
+ ),
42
+ Layer.provideMerge(Credentials.fromAuthProvider()),
43
+ Layer.provideMerge(FetchHttpClient.layer),
44
+ Layer.provideMerge(E2BAuth),
45
+ Layer.provideMerge(ProfileStoreLive),
46
+ Layer.provideMerge(CredentialsStoreLive),
47
+ Layer.orDie,
48
+ );
@@ -0,0 +1,55 @@
1
+ import type * as auth from "@distilled.cloud/e2b/auth";
2
+ import type * as events from "@distilled.cloud/e2b/events";
3
+ import * as Binding from "alchemy/Binding";
4
+ import type { RuntimeContext } from "alchemy/RuntimeContext";
5
+ import type * as Effect from "effect/Effect";
6
+ import type { E2BError } from "./SandboxClient.ts";
7
+
8
+ /** Team usage and the sandbox lifecycle event log. */
9
+ export interface TeamClient {
10
+ /** The team's id: the deployer's team, which the host's key belongs to. */
11
+ readonly teamId: Effect.Effect<string, never, RuntimeContext>;
12
+ /** Concurrent sandboxes and sandbox start rate over time (unix seconds). */
13
+ metrics(
14
+ options?: Omit<auth.ListTeamMetricsRequest, "teamID">,
15
+ ): Effect.Effect<auth.ListTeamMetricsResponse, E2BError, RuntimeContext>;
16
+ /** The peak of one metric over a window. */
17
+ maxMetric(
18
+ options: Omit<auth.GetTeamMetricsMaxRequest, "teamID">,
19
+ ): Effect.Effect<auth.MaxTeamMetric, E2BError, RuntimeContext>;
20
+ /** Lifecycle events of every sandbox in the team, newest first by default. */
21
+ events(
22
+ options?: events.ListTeamSandboxEventsRequest,
23
+ ): Effect.Effect<events.ListTeamSandboxEventsResponse, E2BError, RuntimeContext>;
24
+ /** Lifecycle events of one sandbox. */
25
+ sandboxEvents(
26
+ sandboxId: string,
27
+ options?: Omit<events.ListSandboxEventsRequest, "sandboxID">,
28
+ ): Effect.Effect<events.ListSandboxEventsResponse, E2BError, RuntimeContext>;
29
+ }
30
+
31
+ /**
32
+ * Read the team's sandbox usage and lifecycle event log: dashboards, quotas,
33
+ * auditing which sandboxes started, paused and were killed.
34
+ *
35
+ * To react to lifecycle events as they happen, use `E2B.SandboxEvents`.
36
+ *
37
+ * ### Reading usage
38
+ * **Example:** Concurrent sandboxes over the last hour
39
+ * ```typescript
40
+ * const team = yield* E2B.ReadTeam();
41
+ * // in fetch:
42
+ * const now = Math.floor(Date.now() / 1000);
43
+ * const metrics = yield* team.metrics({ start: now - 3600, end: now });
44
+ * ```
45
+ *
46
+ * @binding
47
+ * @product Team
48
+ */
49
+ export interface ReadTeam extends Binding.Service<
50
+ ReadTeam,
51
+ "E2B.ReadTeam",
52
+ () => Effect.Effect<TeamClient>
53
+ > {}
54
+
55
+ export const ReadTeam = Binding.Service<ReadTeam>("E2B.ReadTeam");
@@ -0,0 +1,44 @@
1
+ import * as auth from "@distilled.cloud/e2b/auth";
2
+ import * as events from "@distilled.cloud/e2b/events";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Layer from "effect/Layer";
5
+ import { bindE2B } from "./E2BBindings.ts";
6
+ import { ReadTeam, type TeamClient } from "./ReadTeam.ts";
7
+
8
+ /**
9
+ * HTTP implementation of {@link ReadTeam}. Works on any host.
10
+ *
11
+ * ### Provide the layer
12
+ * **Example:** On a Worker
13
+ * ```typescript
14
+ * Effect.gen(function* () {
15
+ * const team = yield* E2B.ReadTeam();
16
+ * // ...
17
+ * }).pipe(Effect.provide(E2B.ReadTeamHttp))
18
+ * ```
19
+ *
20
+ * @layer
21
+ * @product Team
22
+ * @provides E2B.ReadTeam
23
+ */
24
+ export const ReadTeamHttp = Layer.succeed(
25
+ ReadTeam,
26
+ Effect.fn("E2B.ReadTeam")(function* () {
27
+ const e2b = yield* bindE2B;
28
+ const client: TeamClient = {
29
+ teamId: e2b.teamId,
30
+ metrics: Effect.fn("E2B.ReadTeam.metrics")(function* (options) {
31
+ const teamID = yield* e2b.teamId;
32
+ return yield* e2b.authorize(auth.listTeamMetrics({ ...options, teamID }));
33
+ }),
34
+ maxMetric: Effect.fn("E2B.ReadTeam.maxMetric")(function* (options) {
35
+ const teamID = yield* e2b.teamId;
36
+ return yield* e2b.authorize(auth.getTeamMetricsMax({ ...options, teamID }));
37
+ }),
38
+ events: (options) => e2b.authorize(events.listTeamSandboxEvents({ ...options })),
39
+ sandboxEvents: (sandboxId, options) =>
40
+ e2b.authorize(events.listSandboxEvents({ ...options, sandboxID: sandboxId })),
41
+ };
42
+ return client;
43
+ }),
44
+ );
@@ -0,0 +1,29 @@
1
+ import * as Binding from "alchemy/Binding";
2
+ import type * as Effect from "effect/Effect";
3
+ import type { Volume } from "./Volume.ts";
4
+ import type { ReadVolumeClient } from "./VolumeFiles.ts";
5
+
6
+ /**
7
+ * Read a {@link Volume}'s files from outside any sandbox: a report a sandbox wrote, a dataset to inspect.
8
+ *
9
+ * The client talks to E2B's volume content API with the volume's own token,
10
+ * looked up once through the host's API key.
11
+ *
12
+ * ### Using the client
13
+ * **Example:** In a Worker
14
+ * ```typescript
15
+ * const reports = yield* E2B.ReadVolume(Reports);
16
+ * // in fetch:
17
+ * const report = yield* reports.readText("/report.json");
18
+ * ```
19
+ *
20
+ * @binding
21
+ * @product Volume
22
+ */
23
+ export interface ReadVolume extends Binding.Service<
24
+ ReadVolume,
25
+ "E2B.ReadVolume",
26
+ (volume: Volume) => Effect.Effect<ReadVolumeClient>
27
+ > {}
28
+
29
+ export const ReadVolume = Binding.Service<ReadVolume>("E2B.ReadVolume");
@@ -0,0 +1,32 @@
1
+ import type * as Output from "alchemy/Output";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Layer from "effect/Layer";
4
+ import { bindE2B } from "./E2BBindings.ts";
5
+ import { makeVolumeFiles } from "./internal/VolumeHttp.ts";
6
+ import { ReadVolume } from "./ReadVolume.ts";
7
+ import type { Volume } from "./Volume.ts";
8
+
9
+ /**
10
+ * HTTP implementation of {@link ReadVolume}. Works on any host.
11
+ *
12
+ * ### Provide the layer
13
+ * **Example:** On a Worker
14
+ * ```typescript
15
+ * Effect.gen(function* () {
16
+ * const reports = yield* E2B.ReadVolume(Reports);
17
+ * // ...
18
+ * }).pipe(Effect.provide(E2B.ReadVolumeHttp))
19
+ * ```
20
+ *
21
+ * @layer
22
+ * @product Volume
23
+ * @provides E2B.ReadVolume
24
+ */
25
+ export const ReadVolumeHttp = Layer.succeed(
26
+ ReadVolume,
27
+ Effect.fn("E2B.ReadVolume")(function* (volume: Volume) {
28
+ const auth = yield* bindE2B;
29
+ const volumeId = yield* (volume.volumeId as Output.Output<string, never>).asEffect();
30
+ return makeVolumeFiles(auth, volumeId);
31
+ }),
32
+ );
@@ -0,0 +1,41 @@
1
+ import type * as webhooks from "@distilled.cloud/e2b/webhooks";
2
+ import * as Binding from "alchemy/Binding";
3
+ import type { RuntimeContext } from "alchemy/RuntimeContext";
4
+ import type * as Effect from "effect/Effect";
5
+ import type { E2BError } from "./SandboxClient.ts";
6
+ import type { Webhook } from "./Webhook.ts";
7
+
8
+ /** A webhook's delivery history and stats. */
9
+ export interface WebhookClient {
10
+ /** Deliveries grouped by event, newest first, with each attempt's request and response. */
11
+ deliveries(
12
+ options?: Omit<webhooks.ListWebhookDeliveriesRequest, "webhookID">,
13
+ ): Effect.Effect<webhooks.WebhookDeliveriesListPayload, E2BError, RuntimeContext>;
14
+ /** Delivery counts, failures and latency over time. */
15
+ stats(
16
+ options?: Omit<webhooks.GetWebhookStatsRequest, "webhookID">,
17
+ ): Effect.Effect<webhooks.WebhookDeliveryStats, E2BError, RuntimeContext>;
18
+ }
19
+
20
+ /**
21
+ * Read an E2B {@link Webhook}'s delivery history and stats: debug a failing
22
+ * endpoint, or alert on failed deliveries.
23
+ *
24
+ * ### Reading deliveries
25
+ * **Example:** Failed deliveries in the last hour
26
+ * ```typescript
27
+ * const hook = yield* E2B.ReadWebhook(Lifecycle);
28
+ * // in fetch:
29
+ * const failed = yield* hook.deliveries({ deliveryStatus: ["failed"] });
30
+ * ```
31
+ *
32
+ * @binding
33
+ * @product Webhook
34
+ */
35
+ export interface ReadWebhook extends Binding.Service<
36
+ ReadWebhook,
37
+ "E2B.ReadWebhook",
38
+ (webhook: Webhook) => Effect.Effect<WebhookClient>
39
+ > {}
40
+
41
+ export const ReadWebhook = Binding.Service<ReadWebhook>("E2B.ReadWebhook");
@@ -0,0 +1,42 @@
1
+ import * as webhooks from "@distilled.cloud/e2b/webhooks";
2
+ import type * as Output from "alchemy/Output";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Layer from "effect/Layer";
5
+ import { bindE2B } from "./E2BBindings.ts";
6
+ import { ReadWebhook, type WebhookClient } from "./ReadWebhook.ts";
7
+ import type { Webhook } from "./Webhook.ts";
8
+
9
+ /**
10
+ * HTTP implementation of {@link ReadWebhook}. Works on any host.
11
+ *
12
+ * ### Provide the layer
13
+ * **Example:** On a Worker
14
+ * ```typescript
15
+ * Effect.gen(function* () {
16
+ * const hook = yield* E2B.ReadWebhook(Lifecycle);
17
+ * // ...
18
+ * }).pipe(Effect.provide(E2B.ReadWebhookHttp))
19
+ * ```
20
+ *
21
+ * @layer
22
+ * @product Webhook
23
+ * @provides E2B.ReadWebhook
24
+ */
25
+ export const ReadWebhookHttp = Layer.succeed(
26
+ ReadWebhook,
27
+ Effect.fn("E2B.ReadWebhook")(function* (webhook: Webhook) {
28
+ const auth = yield* bindE2B;
29
+ const webhookId = yield* (webhook.webhookId as Output.Output<string, never>).asEffect();
30
+ const client: WebhookClient = {
31
+ deliveries: (options) =>
32
+ Effect.flatMap(webhookId, (id) =>
33
+ auth.authorize(webhooks.listWebhookDeliveries({ ...options, webhookID: id })),
34
+ ),
35
+ stats: (options) =>
36
+ Effect.flatMap(webhookId, (id) =>
37
+ auth.authorize(webhooks.getWebhookStats({ ...options, webhookID: id })),
38
+ ),
39
+ };
40
+ return client;
41
+ }),
42
+ );
@@ -0,0 +1,30 @@
1
+ import * as Binding from "alchemy/Binding";
2
+ import type * as Effect from "effect/Effect";
3
+ import type { Volume } from "./Volume.ts";
4
+ import type { ReadWriteVolumeClient } from "./VolumeFiles.ts";
5
+
6
+ /**
7
+ * Read and write a {@link Volume}'s files from outside any sandbox.
8
+ *
9
+ * The client talks to E2B's volume content API with the volume's own token,
10
+ * looked up once through the host's API key.
11
+ *
12
+ * ### Using the client
13
+ * **Example:** In a Worker
14
+ * ```typescript
15
+ * const cache = yield* E2B.ReadWriteVolume(Cache);
16
+ * // in fetch:
17
+ * yield* cache.write("/notes.md", "hello");
18
+ * const notes = yield* cache.readText("/notes.md");
19
+ * ```
20
+ *
21
+ * @binding
22
+ * @product Volume
23
+ */
24
+ export interface ReadWriteVolume extends Binding.Service<
25
+ ReadWriteVolume,
26
+ "E2B.ReadWriteVolume",
27
+ (volume: Volume) => Effect.Effect<ReadWriteVolumeClient>
28
+ > {}
29
+
30
+ export const ReadWriteVolume = Binding.Service<ReadWriteVolume>("E2B.ReadWriteVolume");
@@ -0,0 +1,32 @@
1
+ import type * as Output from "alchemy/Output";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Layer from "effect/Layer";
4
+ import { bindE2B } from "./E2BBindings.ts";
5
+ import { makeVolumeFiles } from "./internal/VolumeHttp.ts";
6
+ import { ReadWriteVolume } from "./ReadWriteVolume.ts";
7
+ import type { Volume } from "./Volume.ts";
8
+
9
+ /**
10
+ * HTTP implementation of {@link ReadWriteVolume}. Works on any host.
11
+ *
12
+ * ### Provide the layer
13
+ * **Example:** On a Worker
14
+ * ```typescript
15
+ * Effect.gen(function* () {
16
+ * const cache = yield* E2B.ReadWriteVolume(Cache);
17
+ * // ...
18
+ * }).pipe(Effect.provide(E2B.ReadWriteVolumeHttp))
19
+ * ```
20
+ *
21
+ * @layer
22
+ * @product Volume
23
+ * @provides E2B.ReadWriteVolume
24
+ */
25
+ export const ReadWriteVolumeHttp = Layer.succeed(
26
+ ReadWriteVolume,
27
+ Effect.fn("E2B.ReadWriteVolume")(function* (volume: Volume) {
28
+ const auth = yield* bindE2B;
29
+ const volumeId = yield* (volume.volumeId as Output.Output<string, never>).asEffect();
30
+ return makeVolumeFiles(auth, volumeId);
31
+ }),
32
+ );