@alchemy.run/daytona 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 (274) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +76 -4
  3. package/lib/ApiKey.d.ts +99 -0
  4. package/lib/ApiKey.d.ts.map +1 -0
  5. package/lib/ApiKey.js +152 -0
  6. package/lib/ApiKey.js.map +1 -0
  7. package/lib/AuthProvider.d.ts +55 -0
  8. package/lib/AuthProvider.d.ts.map +1 -0
  9. package/lib/AuthProvider.js +280 -0
  10. package/lib/AuthProvider.js.map +1 -0
  11. package/lib/Bootstrap.d.ts +8 -0
  12. package/lib/Bootstrap.d.ts.map +1 -0
  13. package/lib/Bootstrap.js +28 -0
  14. package/lib/Bootstrap.js.map +1 -0
  15. package/lib/ConnectSandbox.d.ts +72 -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 +5 -0
  20. package/lib/ConnectSandboxHttp.d.ts.map +1 -0
  21. package/lib/ConnectSandboxHttp.js +22 -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 +86 -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 +5 -0
  32. package/lib/CreateSandboxHttp.d.ts.map +1 -0
  33. package/lib/CreateSandboxHttp.js +65 -0
  34. package/lib/CreateSandboxHttp.js.map +1 -0
  35. package/lib/CreateSecret.d.ts +56 -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 +5 -0
  40. package/lib/CreateSecretHttp.d.ts.map +1 -0
  41. package/lib/CreateSecretHttp.js +39 -0
  42. package/lib/CreateSecretHttp.js.map +1 -0
  43. package/lib/CreateSnapshot.d.ts +80 -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 +5 -0
  48. package/lib/CreateSnapshotHttp.d.ts.map +1 -0
  49. package/lib/CreateSnapshotHttp.js +47 -0
  50. package/lib/CreateSnapshotHttp.js.map +1 -0
  51. package/lib/CreateVolume.d.ts +81 -0
  52. package/lib/CreateVolume.d.ts.map +1 -0
  53. package/lib/CreateVolume.js +10 -0
  54. package/lib/CreateVolume.js.map +1 -0
  55. package/lib/CreateVolumeHttp.d.ts +5 -0
  56. package/lib/CreateVolumeHttp.d.ts.map +1 -0
  57. package/lib/CreateVolumeHttp.js +31 -0
  58. package/lib/CreateVolumeHttp.js.map +1 -0
  59. package/lib/Credentials.d.ts +9 -0
  60. package/lib/Credentials.d.ts.map +1 -0
  61. package/lib/Credentials.js +18 -0
  62. package/lib/Credentials.js.map +1 -0
  63. package/lib/DaytonaBindings.d.ts +51 -0
  64. package/lib/DaytonaBindings.d.ts.map +1 -0
  65. package/lib/DaytonaBindings.js +61 -0
  66. package/lib/DaytonaBindings.js.map +1 -0
  67. package/lib/IdentityProvider.d.ts +80 -0
  68. package/lib/IdentityProvider.d.ts.map +1 -0
  69. package/lib/IdentityProvider.js +111 -0
  70. package/lib/IdentityProvider.js.map +1 -0
  71. package/lib/MountVolume.d.ts +86 -0
  72. package/lib/MountVolume.d.ts.map +1 -0
  73. package/lib/MountVolume.js +27 -0
  74. package/lib/MountVolume.js.map +1 -0
  75. package/lib/OAuthClient.d.ts +14 -0
  76. package/lib/OAuthClient.d.ts.map +1 -0
  77. package/lib/OAuthClient.js +23 -0
  78. package/lib/OAuthClient.js.map +1 -0
  79. package/lib/Organization.d.ts +40 -0
  80. package/lib/Organization.d.ts.map +1 -0
  81. package/lib/Organization.js +80 -0
  82. package/lib/Organization.js.map +1 -0
  83. package/lib/OrganizationInvitation.d.ts +70 -0
  84. package/lib/OrganizationInvitation.d.ts.map +1 -0
  85. package/lib/OrganizationInvitation.js +109 -0
  86. package/lib/OrganizationInvitation.js.map +1 -0
  87. package/lib/OrganizationMember.d.ts +86 -0
  88. package/lib/OrganizationMember.d.ts.map +1 -0
  89. package/lib/OrganizationMember.js +109 -0
  90. package/lib/OrganizationMember.js.map +1 -0
  91. package/lib/OrganizationOtelConfig.d.ts +59 -0
  92. package/lib/OrganizationOtelConfig.d.ts.map +1 -0
  93. package/lib/OrganizationOtelConfig.js +87 -0
  94. package/lib/OrganizationOtelConfig.js.map +1 -0
  95. package/lib/OrganizationRole.d.ts +66 -0
  96. package/lib/OrganizationRole.d.ts.map +1 -0
  97. package/lib/OrganizationRole.js +106 -0
  98. package/lib/OrganizationRole.js.map +1 -0
  99. package/lib/OrganizationSettings.d.ts +76 -0
  100. package/lib/OrganizationSettings.d.ts.map +1 -0
  101. package/lib/OrganizationSettings.js +107 -0
  102. package/lib/OrganizationSettings.js.map +1 -0
  103. package/lib/Providers.d.ts +14 -0
  104. package/lib/Providers.d.ts.map +1 -0
  105. package/lib/Providers.js +53 -0
  106. package/lib/Providers.js.map +1 -0
  107. package/lib/ReadAuditLogs.d.ts +30 -0
  108. package/lib/ReadAuditLogs.d.ts.map +1 -0
  109. package/lib/ReadAuditLogs.js +17 -0
  110. package/lib/ReadAuditLogs.js.map +1 -0
  111. package/lib/ReadOrganization.d.ts +39 -0
  112. package/lib/ReadOrganization.d.ts.map +1 -0
  113. package/lib/ReadOrganization.js +39 -0
  114. package/lib/ReadOrganization.js.map +1 -0
  115. package/lib/ReadUsage.d.ts +31 -0
  116. package/lib/ReadUsage.d.ts.map +1 -0
  117. package/lib/ReadUsage.js +17 -0
  118. package/lib/ReadUsage.js.map +1 -0
  119. package/lib/Region.d.ts +78 -0
  120. package/lib/Region.d.ts.map +1 -0
  121. package/lib/Region.js +169 -0
  122. package/lib/Region.js.map +1 -0
  123. package/lib/Registry.d.ts +84 -0
  124. package/lib/Registry.d.ts.map +1 -0
  125. package/lib/Registry.js +97 -0
  126. package/lib/Registry.js.map +1 -0
  127. package/lib/Runner.d.ts +66 -0
  128. package/lib/Runner.d.ts.map +1 -0
  129. package/lib/Runner.js +116 -0
  130. package/lib/Runner.js.map +1 -0
  131. package/lib/Sandbox.d.ts +376 -0
  132. package/lib/Sandbox.d.ts.map +1 -0
  133. package/lib/Sandbox.js +565 -0
  134. package/lib/Sandbox.js.map +1 -0
  135. package/lib/SandboxClient.d.ts +258 -0
  136. package/lib/SandboxClient.d.ts.map +1 -0
  137. package/lib/SandboxClient.js +233 -0
  138. package/lib/SandboxClient.js.map +1 -0
  139. package/lib/Secret.d.ts +93 -0
  140. package/lib/Secret.d.ts.map +1 -0
  141. package/lib/Secret.js +130 -0
  142. package/lib/Secret.js.map +1 -0
  143. package/lib/Snapshot.d.ts +327 -0
  144. package/lib/Snapshot.d.ts.map +1 -0
  145. package/lib/Snapshot.js +447 -0
  146. package/lib/Snapshot.js.map +1 -0
  147. package/lib/Volume.d.ts +99 -0
  148. package/lib/Volume.d.ts.map +1 -0
  149. package/lib/Volume.js +152 -0
  150. package/lib/Volume.js.map +1 -0
  151. package/lib/WarmPool.d.ts +61 -0
  152. package/lib/WarmPool.d.ts.map +1 -0
  153. package/lib/WarmPool.js +81 -0
  154. package/lib/WarmPool.js.map +1 -0
  155. package/lib/Webhooks.d.ts +58 -0
  156. package/lib/Webhooks.d.ts.map +1 -0
  157. package/lib/Webhooks.js +75 -0
  158. package/lib/Webhooks.js.map +1 -0
  159. package/lib/index.d.ts +37 -0
  160. package/lib/index.d.ts.map +1 -0
  161. package/lib/index.js +36 -0
  162. package/lib/index.js.map +1 -0
  163. package/lib/internal/BuildContext.d.ts +16 -0
  164. package/lib/internal/BuildContext.d.ts.map +1 -0
  165. package/lib/internal/BuildContext.js +50 -0
  166. package/lib/internal/BuildContext.js.map +1 -0
  167. package/lib/internal/Declared.d.ts +29 -0
  168. package/lib/internal/Declared.d.ts.map +1 -0
  169. package/lib/internal/Declared.js +31 -0
  170. package/lib/internal/Declared.js.map +1 -0
  171. package/lib/internal/Derived.d.ts +40 -0
  172. package/lib/internal/Derived.d.ts.map +1 -0
  173. package/lib/internal/Derived.js +64 -0
  174. package/lib/internal/Derived.js.map +1 -0
  175. package/lib/internal/Errors.d.ts +4 -0
  176. package/lib/internal/Errors.d.ts.map +1 -0
  177. package/lib/internal/Errors.js +1 -0
  178. package/lib/internal/Errors.js.map +1 -0
  179. package/lib/internal/Labels.d.ts +20 -0
  180. package/lib/internal/Labels.d.ts.map +1 -0
  181. package/lib/internal/Labels.js +22 -0
  182. package/lib/internal/Labels.js.map +1 -0
  183. package/lib/internal/Names.d.ts +18 -0
  184. package/lib/internal/Names.d.ts.map +1 -0
  185. package/lib/internal/Names.js +25 -0
  186. package/lib/internal/Names.js.map +1 -0
  187. package/lib/internal/Organization.d.ts +27 -0
  188. package/lib/internal/Organization.d.ts.map +1 -0
  189. package/lib/internal/Organization.js +32 -0
  190. package/lib/internal/Organization.js.map +1 -0
  191. package/lib/internal/Process.d.ts +14 -0
  192. package/lib/internal/Process.d.ts.map +1 -0
  193. package/lib/internal/Process.js +15 -0
  194. package/lib/internal/Process.js.map +1 -0
  195. package/lib/internal/Program.d.ts +83 -0
  196. package/lib/internal/Program.d.ts.map +1 -0
  197. package/lib/internal/Program.js +169 -0
  198. package/lib/internal/Program.js.map +1 -0
  199. package/lib/internal/Ref.d.ts +14 -0
  200. package/lib/internal/Ref.d.ts.map +1 -0
  201. package/lib/internal/Ref.js +7 -0
  202. package/lib/internal/Ref.js.map +1 -0
  203. package/lib/internal/Scoped.d.ts +31 -0
  204. package/lib/internal/Scoped.d.ts.map +1 -0
  205. package/lib/internal/Scoped.js +48 -0
  206. package/lib/internal/Scoped.js.map +1 -0
  207. package/lib/internal/Tar.d.ts +13 -0
  208. package/lib/internal/Tar.d.ts.map +1 -0
  209. package/lib/internal/Tar.js +62 -0
  210. package/lib/internal/Tar.js.map +1 -0
  211. package/lib/internal/Toolbox.d.ts +11 -0
  212. package/lib/internal/Toolbox.d.ts.map +1 -0
  213. package/lib/internal/Toolbox.js +20 -0
  214. package/lib/internal/Toolbox.js.map +1 -0
  215. package/lib/internal/Wait.d.ts +49 -0
  216. package/lib/internal/Wait.d.ts.map +1 -0
  217. package/lib/internal/Wait.js +57 -0
  218. package/lib/internal/Wait.js.map +1 -0
  219. package/package.json +64 -3
  220. package/src/ApiKey.ts +221 -0
  221. package/src/AuthProvider.ts +406 -0
  222. package/src/Bootstrap.ts +55 -0
  223. package/src/ConnectSandbox.ts +76 -0
  224. package/src/ConnectSandboxHttp.ts +26 -0
  225. package/src/Contributions.ts +9 -0
  226. package/src/CreateSandbox.ts +107 -0
  227. package/src/CreateSandboxHttp.ts +97 -0
  228. package/src/CreateSecret.ts +73 -0
  229. package/src/CreateSecretHttp.ts +58 -0
  230. package/src/CreateSnapshot.ts +133 -0
  231. package/src/CreateSnapshotHttp.ts +77 -0
  232. package/src/CreateVolume.ts +104 -0
  233. package/src/CreateVolumeHttp.ts +50 -0
  234. package/src/Credentials.ts +37 -0
  235. package/src/DaytonaBindings.ts +111 -0
  236. package/src/IdentityProvider.ts +181 -0
  237. package/src/MountVolume.ts +122 -0
  238. package/src/OAuthClient.ts +27 -0
  239. package/src/Organization.ts +121 -0
  240. package/src/OrganizationInvitation.ts +174 -0
  241. package/src/OrganizationMember.ts +174 -0
  242. package/src/OrganizationOtelConfig.ts +138 -0
  243. package/src/OrganizationRole.ts +167 -0
  244. package/src/OrganizationSettings.ts +187 -0
  245. package/src/Providers.ts +93 -0
  246. package/src/ReadAuditLogs.ts +50 -0
  247. package/src/ReadOrganization.ts +83 -0
  248. package/src/ReadUsage.ts +51 -0
  249. package/src/Region.ts +226 -0
  250. package/src/Registry.ts +164 -0
  251. package/src/Runner.ts +166 -0
  252. package/src/Sandbox.ts +927 -0
  253. package/src/SandboxClient.ts +625 -0
  254. package/src/Secret.ts +203 -0
  255. package/src/Snapshot.ts +685 -0
  256. package/src/Volume.ts +229 -0
  257. package/src/WarmPool.ts +128 -0
  258. package/src/Webhooks.ts +121 -0
  259. package/src/globals.d.ts +2 -0
  260. package/src/index.ts +46 -0
  261. package/src/internal/BuildContext.ts +62 -0
  262. package/src/internal/Declared.ts +80 -0
  263. package/src/internal/Derived.ts +97 -0
  264. package/src/internal/Errors.ts +4 -0
  265. package/src/internal/Labels.ts +39 -0
  266. package/src/internal/Names.ts +37 -0
  267. package/src/internal/Organization.ts +40 -0
  268. package/src/internal/Process.ts +25 -0
  269. package/src/internal/Program.ts +239 -0
  270. package/src/internal/Ref.ts +15 -0
  271. package/src/internal/Scoped.ts +102 -0
  272. package/src/internal/Tar.ts +72 -0
  273. package/src/internal/Toolbox.ts +27 -0
  274. package/src/internal/Wait.ts +105 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alchemy.run/daytona",
3
- "version": "0.0.0",
3
+ "version": "2.0.0-beta.86",
4
4
  "description": "Daytona sandboxes, snapshots, volumes, secrets and the in-sandbox toolbox for Alchemy.",
5
5
  "keywords": [
6
6
  "ai-agents",
@@ -10,12 +10,73 @@
10
10
  "infrastructure-as-code",
11
11
  "sandbox"
12
12
  ],
13
+ "homepage": "https://alchemy.run",
14
+ "bugs": {
15
+ "url": "https://github.com/alchemy-run/alchemy/issues"
16
+ },
13
17
  "license": "Apache-2.0",
14
18
  "author": "Sam Goodwin <sam@alchemy.run>",
15
- "homepage": "https://alchemy.run",
16
19
  "repository": {
17
20
  "type": "git",
18
21
  "url": "git+https://github.com/alchemy-run/alchemy.git",
19
22
  "directory": "packages/daytona"
23
+ },
24
+ "files": [
25
+ "lib",
26
+ "src"
27
+ ],
28
+ "type": "module",
29
+ "sideEffects": false,
30
+ "exports": {
31
+ ".": {
32
+ "types": "./lib/index.d.ts",
33
+ "bun": "./src/index.ts",
34
+ "worker": "./src/index.ts",
35
+ "default": "./lib/index.js"
36
+ },
37
+ "./internal/*": null,
38
+ "./*": {
39
+ "types": "./lib/*.d.ts",
40
+ "bun": "./src/*.ts",
41
+ "worker": "./src/*.ts",
42
+ "default": "./lib/*.js"
43
+ },
44
+ "./package.json": "./package.json"
45
+ },
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
49
+ "dependencies": {
50
+ "@alchemy.run/docker": "2.0.0-beta.86",
51
+ "@distilled.cloud/aws": "1.0.0-rc.19",
52
+ "@distilled.cloud/core": "1.0.0-rc.19",
53
+ "@distilled.cloud/daytona": "1.0.0-rc.19",
54
+ "rolldown": "1.2.16"
55
+ },
56
+ "devDependencies": {
57
+ "@effect/platform-node": "^4.1.4",
58
+ "@types/bun": "1.4.3",
59
+ "alchemy": "2.0.0-beta.86",
60
+ "effect": "^4.1.4",
61
+ "typescript": "^7.1.0-dev.20261105.1"
62
+ },
63
+ "peerDependencies": {
64
+ "@effect/platform-node": "^4.1.4",
65
+ "alchemy": "2.0.0-beta.86",
66
+ "effect": "^4.1.4"
67
+ },
68
+ "peerDependenciesMeta": {
69
+ "@effect/platform-node": {
70
+ "optional": true
71
+ }
72
+ },
73
+ "alchemy": {
74
+ "contributes": [
75
+ "@alchemy.run/daytona/Contributions"
76
+ ]
77
+ },
78
+ "scripts": {
79
+ "build": "pnpm -r --filter \"{.}...\" run build:package",
80
+ "build:package": "node scripts/build.ts"
20
81
  }
21
- }
82
+ }
package/src/ApiKey.ts ADDED
@@ -0,0 +1,221 @@
1
+ import * as apiKeys from "@distilled.cloud/daytona/api_keys";
2
+ import { Credentials } from "@distilled.cloud/daytona/Credentials";
3
+ import { Unowned } from "alchemy/AdoptPolicy";
4
+ import { deepEqual, isResolved } from "alchemy/Diff";
5
+ import * as Provider from "alchemy/Provider";
6
+ import { Resource } from "alchemy/Resource";
7
+ import * as Data from "effect/Data";
8
+ import * as Effect from "effect/Effect";
9
+ import * as Redacted from "effect/Redacted";
10
+ import { isOwnedName, resolveName } from "./internal/Names.ts";
11
+ import { currentOrganizationId } from "./internal/Organization.ts";
12
+ import type { Providers } from "./Providers.ts";
13
+
14
+ /**
15
+ * A permission an API key or organization role grants. Daytona checks
16
+ * them per kind of object: `write:sandboxes` allows creating any sandbox in
17
+ * the organization, not one in particular.
18
+ */
19
+ export type Permission = apiKeys.CreateApiKeyRequestPermissionsItem;
20
+
21
+ export interface ApiKeyProps {
22
+ /**
23
+ * Key name, unique in the organization. If omitted, a unique name is
24
+ * generated from the stack, stage and logical ID. Changing it replaces
25
+ * the key.
26
+ */
27
+ name?: string;
28
+ /**
29
+ * What the key may do. Changing them replaces the key, since Daytona
30
+ * keys can't be edited.
31
+ */
32
+ permissions: Permission[];
33
+ /**
34
+ * When the key stops working, as an ISO 8601 timestamp. Changing it
35
+ * replaces the key.
36
+ */
37
+ expiresAt?: string;
38
+ }
39
+
40
+ export interface ApiKeyAttributes {
41
+ /** Key name. */
42
+ name: string;
43
+ /** Permissions the key grants. */
44
+ permissions: Permission[];
45
+ /** When the key expires, if it does. */
46
+ expiresAt: string | undefined;
47
+ /** When the key was created. */
48
+ createdAt: string;
49
+ /** The Daytona API root the key belongs to. */
50
+ apiBaseUrl: string;
51
+ /** The organization the key acts on. */
52
+ organizationId: string;
53
+ /**
54
+ * The key itself, sent as `Authorization: Bearer <value>`. Daytona shows
55
+ * it only when the key is created, so alchemy keeps it in state.
56
+ */
57
+ value: Redacted.Redacted<string>;
58
+ }
59
+
60
+ export type ApiKey = Resource<"Daytona.ApiKey", ApiKeyProps, ApiKeyAttributes, never, Providers>;
61
+
62
+ /**
63
+ * A Daytona API key with a fixed set of permissions. Give each app the
64
+ * narrowest key it needs; Daytona checks every request against it.
65
+ *
66
+ * The runtime bindings (`Daytona.CreateSandbox`, `Daytona.CreateVolume`, …)
67
+ * mint one of these per host for you, with only the permissions the
68
+ * binding needs. Declare one yourself for CI or for a program outside
69
+ * alchemy.
70
+ *
71
+ * Daytona shows a key's value only once, so alchemy stores it in state as
72
+ * a `Redacted` value. Keys can't be edited: changing any prop mints a new
73
+ * key and deletes the old one.
74
+ *
75
+ * Creating keys needs a signed-in profile, or an API key with
76
+ * `manage:api_keys` (Daytona's managed API keys, enabled on request);
77
+ * otherwise Daytona refuses with `ManagedApiKeysNotEnabled`.
78
+ * @see https://www.daytona.io/docs/en/api-keys/
79
+ *
80
+ * ### Creating a Key
81
+ * **Example:** A key that can only create and delete sandboxes
82
+ * ```typescript
83
+ * const key = yield* Daytona.ApiKey("Ci", {
84
+ * permissions: ["write:sandboxes", "delete:sandboxes"],
85
+ * });
86
+ * ```
87
+ *
88
+ * **Example:** A key that expires
89
+ * ```typescript
90
+ * const key = yield* Daytona.ApiKey("Preview", {
91
+ * permissions: ["write:sandboxes"],
92
+ * expiresAt: "2027-01-01T00:00:00Z",
93
+ * });
94
+ * ```
95
+ *
96
+ * @resource
97
+ * @product API Key
98
+ */
99
+ export const ApiKey = Resource<ApiKey>("Daytona.ApiKey");
100
+
101
+ /** Daytona created a key but returned no value for it. */
102
+ export class ApiKeyValueMissing extends Data.TaggedError("Daytona.ApiKeyValueMissing")<{
103
+ readonly keyName: string;
104
+ }> {
105
+ override get message() {
106
+ return `Daytona returned no value for the new API key ${this.keyName}`;
107
+ }
108
+ }
109
+
110
+ const sorted = (permissions: readonly string[]) => [...permissions].sort();
111
+
112
+ const apiRoot = Effect.gen(function* () {
113
+ const credentials = yield* Credentials;
114
+ return (yield* credentials).apiBaseUrl;
115
+ });
116
+
117
+ export const ApiKeyProvider = () =>
118
+ Provider.effect(
119
+ ApiKey,
120
+ Effect.gen(function* () {
121
+ const getKey = (name: string) =>
122
+ apiKeys.getApiKey({ name }).pipe(Effect.catchTag("ApiKeyNotFound", () => Effect.undefined));
123
+ const deleteKey = (name: string) =>
124
+ apiKeys.deleteApiKey({ name }).pipe(Effect.catchTag("ApiKeyNotFound", () => Effect.void));
125
+
126
+ return {
127
+ stables: ["name", "createdAt", "value"],
128
+ list: Effect.fn(function* () {
129
+ const keys = yield* apiKeys.listApiKeys({});
130
+ const apiBaseUrl = yield* apiRoot;
131
+ return keys.map((key) => ({
132
+ name: key.name,
133
+ permissions: key.permissions,
134
+ expiresAt: key.expiresAt ?? undefined,
135
+ createdAt: key.createdAt,
136
+ apiBaseUrl,
137
+ organizationId: key.organizationId ?? "",
138
+ value: Redacted.make(""),
139
+ }));
140
+ }),
141
+ diff: Effect.fn(function* ({ id, olds, news, output }) {
142
+ if (!isResolved(news) || output === undefined) return undefined;
143
+ const name = yield* resolveName(
144
+ id,
145
+ news.name,
146
+ olds?.name === news.name ? output.name : undefined,
147
+ );
148
+ if (
149
+ name !== output.name ||
150
+ !deepEqual(sorted(news.permissions), sorted(output.permissions)) ||
151
+ (news.expiresAt ?? undefined) !== (olds?.expiresAt ?? undefined)
152
+ ) {
153
+ // A pinned name can't be held by two keys at once.
154
+ return { action: "replace", deleteFirst: name === output.name } as const;
155
+ }
156
+ }),
157
+ read: Effect.fn(function* ({ id, olds, output }) {
158
+ const name = yield* resolveName(id, olds?.name, output?.name);
159
+ const observed = yield* getKey(name);
160
+ if (observed === undefined) return undefined;
161
+ const attrs = {
162
+ name: observed.name,
163
+ permissions: observed.permissions,
164
+ expiresAt: observed.expiresAt ?? undefined,
165
+ createdAt: observed.createdAt,
166
+ apiBaseUrl: output?.apiBaseUrl ?? (yield* apiRoot),
167
+ organizationId: output?.organizationId ?? (yield* currentOrganizationId),
168
+ value: output?.value ?? Redacted.make(""),
169
+ };
170
+ // The value is only shown at creation, so a key with no state
171
+ // can't be adopted with it; reconcile re-mints it.
172
+ return (yield* isOwnedName(id, name, output !== undefined)) ? attrs : Unowned(attrs);
173
+ }),
174
+ reconcile: Effect.fn(function* ({ id, news, output, session }) {
175
+ const name = yield* resolveName(id, news.name, output?.name);
176
+
177
+ // Observe
178
+ const observed = yield* getKey(name);
179
+ if (
180
+ observed !== undefined &&
181
+ output !== undefined &&
182
+ Redacted.value(output.value) !== ""
183
+ ) {
184
+ return {
185
+ ...output,
186
+ permissions: observed.permissions,
187
+ expiresAt: observed.expiresAt ?? undefined,
188
+ };
189
+ }
190
+
191
+ // Ensure: a key whose value we don't hold (lost create, adoption)
192
+ // is deleted and minted again.
193
+ if (observed !== undefined) {
194
+ yield* session.note(`Re-minting Daytona API key ${name}...`);
195
+ yield* deleteKey(name);
196
+ }
197
+ const created = yield* apiKeys.createApiKey({
198
+ name,
199
+ permissions: news.permissions,
200
+ expiresAt: news.expiresAt,
201
+ });
202
+ const value = Redacted.isRedacted(created.value)
203
+ ? created.value
204
+ : Redacted.make(created.value);
205
+ if (Redacted.value(value) === "") return yield* new ApiKeyValueMissing({ keyName: name });
206
+ return {
207
+ name: created.name,
208
+ permissions: created.permissions,
209
+ expiresAt: created.expiresAt ?? undefined,
210
+ createdAt: created.createdAt,
211
+ apiBaseUrl: yield* apiRoot,
212
+ organizationId: yield* currentOrganizationId,
213
+ value,
214
+ };
215
+ }),
216
+ delete: Effect.fn(function* ({ output }) {
217
+ yield* deleteKey(output.name);
218
+ }),
219
+ };
220
+ }),
221
+ );