@vercel/sandbox 2.0.0-beta.10 → 2.0.0-beta.12

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 (196) hide show
  1. package/README.md +8 -0
  2. package/dist/_virtual/rolldown_runtime.cjs +29 -0
  3. package/dist/api-client/api-client.cjs +456 -0
  4. package/dist/api-client/api-client.cjs.map +1 -0
  5. package/dist/api-client/api-client.d.cts +788 -0
  6. package/dist/api-client/api-client.d.ts +782 -777
  7. package/dist/api-client/api-client.js +445 -471
  8. package/dist/api-client/api-client.js.map +1 -1
  9. package/dist/api-client/api-error.cjs +32 -0
  10. package/dist/api-client/api-error.cjs.map +1 -0
  11. package/dist/api-client/api-error.d.cts +29 -0
  12. package/dist/api-client/api-error.d.ts +21 -18
  13. package/dist/api-client/api-error.js +28 -33
  14. package/dist/api-client/api-error.js.map +1 -1
  15. package/dist/api-client/base-client.cjs +125 -0
  16. package/dist/api-client/base-client.cjs.map +1 -0
  17. package/dist/api-client/base-client.d.cts +38 -0
  18. package/dist/api-client/base-client.d.ts +31 -36
  19. package/dist/api-client/base-client.js +110 -130
  20. package/dist/api-client/base-client.js.map +1 -1
  21. package/dist/api-client/file-writer.cjs +62 -0
  22. package/dist/api-client/file-writer.cjs.map +1 -0
  23. package/dist/api-client/file-writer.d.cts +66 -0
  24. package/dist/api-client/file-writer.d.ts +56 -52
  25. package/dist/api-client/file-writer.js +57 -61
  26. package/dist/api-client/file-writer.js.map +1 -1
  27. package/dist/api-client/index.cjs +2 -0
  28. package/dist/api-client/index.d.ts +2 -2
  29. package/dist/api-client/index.js +4 -21
  30. package/dist/api-client/validators.cjs +181 -0
  31. package/dist/api-client/validators.cjs.map +1 -0
  32. package/dist/api-client/validators.d.cts +1469 -0
  33. package/dist/api-client/validators.d.ts +1282 -3699
  34. package/dist/api-client/validators.js +154 -170
  35. package/dist/api-client/validators.js.map +1 -1
  36. package/dist/api-client/with-retry.cjs +89 -0
  37. package/dist/api-client/with-retry.cjs.map +1 -0
  38. package/dist/api-client/with-retry.d.cts +10 -0
  39. package/dist/api-client/with-retry.d.ts +9 -13
  40. package/dist/api-client/with-retry.js +81 -102
  41. package/dist/api-client/with-retry.js.map +1 -1
  42. package/dist/auth/api.cjs +29 -0
  43. package/dist/auth/api.cjs.map +1 -0
  44. package/dist/auth/api.js +26 -25
  45. package/dist/auth/api.js.map +1 -1
  46. package/dist/auth/error.cjs +13 -0
  47. package/dist/auth/error.cjs.map +1 -0
  48. package/dist/auth/error.js +11 -11
  49. package/dist/auth/error.js.map +1 -1
  50. package/dist/auth/file.cjs +64 -0
  51. package/dist/auth/file.cjs.map +1 -0
  52. package/dist/auth/file.d.cts +26 -0
  53. package/dist/auth/file.d.ts +19 -15
  54. package/dist/auth/file.js +49 -64
  55. package/dist/auth/file.js.map +1 -1
  56. package/dist/auth/index.cjs +12 -0
  57. package/dist/auth/index.d.cts +5 -0
  58. package/dist/auth/index.d.ts +5 -6
  59. package/dist/auth/index.js +6 -27
  60. package/dist/auth/linked-project.cjs +38 -0
  61. package/dist/auth/linked-project.cjs.map +1 -0
  62. package/dist/auth/linked-project.js +30 -64
  63. package/dist/auth/linked-project.js.map +1 -1
  64. package/dist/auth/oauth.cjs +205 -0
  65. package/dist/auth/oauth.cjs.map +1 -0
  66. package/dist/auth/oauth.d.cts +135 -0
  67. package/dist/auth/oauth.d.ts +113 -109
  68. package/dist/auth/oauth.js +185 -252
  69. package/dist/auth/oauth.js.map +1 -1
  70. package/dist/auth/poll-for-token.cjs +82 -0
  71. package/dist/auth/poll-for-token.cjs.map +1 -0
  72. package/dist/auth/poll-for-token.d.cts +28 -0
  73. package/dist/auth/poll-for-token.d.ts +23 -15
  74. package/dist/auth/poll-for-token.js +79 -64
  75. package/dist/auth/poll-for-token.js.map +1 -1
  76. package/dist/auth/project.cjs +80 -0
  77. package/dist/auth/project.cjs.map +1 -0
  78. package/dist/auth/project.d.cts +44 -0
  79. package/dist/auth/project.d.ts +12 -8
  80. package/dist/auth/project.js +70 -72
  81. package/dist/auth/project.js.map +1 -1
  82. package/dist/auth/zod.cjs +22 -0
  83. package/dist/auth/zod.cjs.map +1 -0
  84. package/dist/auth/zod.js +18 -17
  85. package/dist/auth/zod.js.map +1 -1
  86. package/dist/command.cjs +328 -0
  87. package/dist/command.cjs.map +1 -0
  88. package/dist/command.d.cts +289 -0
  89. package/dist/command.d.ts +265 -171
  90. package/dist/command.js +323 -226
  91. package/dist/command.js.map +1 -1
  92. package/dist/constants.d.cts +5 -0
  93. package/dist/constants.d.ts +5 -1
  94. package/dist/index.cjs +13 -0
  95. package/dist/index.d.cts +7 -0
  96. package/dist/index.d.ts +7 -6
  97. package/dist/index.js +7 -17
  98. package/dist/network-policy.d.cts +100 -0
  99. package/dist/network-policy.d.ts +32 -28
  100. package/dist/sandbox.cjs +688 -0
  101. package/dist/sandbox.cjs.map +1 -0
  102. package/dist/sandbox.d.cts +780 -0
  103. package/dist/sandbox.d.ts +767 -711
  104. package/dist/sandbox.js +680 -612
  105. package/dist/sandbox.js.map +1 -1
  106. package/dist/session.cjs +520 -0
  107. package/dist/session.cjs.map +1 -0
  108. package/dist/session.d.cts +406 -0
  109. package/dist/session.d.ts +398 -367
  110. package/dist/session.js +517 -505
  111. package/dist/session.js.map +1 -1
  112. package/dist/snapshot.cjs +116 -0
  113. package/dist/snapshot.cjs.map +1 -0
  114. package/dist/snapshot.d.cts +107 -0
  115. package/dist/snapshot.d.ts +98 -91
  116. package/dist/snapshot.js +114 -115
  117. package/dist/snapshot.js.map +1 -1
  118. package/dist/utils/array.cjs +17 -0
  119. package/dist/utils/array.cjs.map +1 -0
  120. package/dist/utils/array.js +12 -15
  121. package/dist/utils/array.js.map +1 -1
  122. package/dist/utils/consume-readable.cjs +18 -0
  123. package/dist/utils/consume-readable.cjs.map +1 -0
  124. package/dist/utils/consume-readable.js +13 -12
  125. package/dist/utils/consume-readable.js.map +1 -1
  126. package/dist/utils/decode-base64-url.cjs +15 -0
  127. package/dist/utils/decode-base64-url.cjs.map +1 -0
  128. package/dist/utils/decode-base64-url.js +10 -9
  129. package/dist/utils/decode-base64-url.js.map +1 -1
  130. package/dist/utils/dev-credentials.cjs +142 -0
  131. package/dist/utils/dev-credentials.cjs.map +1 -0
  132. package/dist/utils/dev-credentials.js +126 -184
  133. package/dist/utils/dev-credentials.js.map +1 -1
  134. package/dist/utils/get-credentials.cjs +123 -0
  135. package/dist/utils/get-credentials.cjs.map +1 -0
  136. package/dist/utils/get-credentials.d.cts +21 -0
  137. package/dist/utils/get-credentials.d.ts +19 -61
  138. package/dist/utils/get-credentials.js +106 -140
  139. package/dist/utils/get-credentials.js.map +1 -1
  140. package/dist/utils/log.cjs +25 -0
  141. package/dist/utils/log.cjs.map +1 -0
  142. package/dist/utils/log.js +15 -17
  143. package/dist/utils/log.js.map +1 -1
  144. package/dist/utils/network-policy.cjs +65 -0
  145. package/dist/utils/network-policy.cjs.map +1 -0
  146. package/dist/utils/network-policy.js +58 -77
  147. package/dist/utils/network-policy.js.map +1 -1
  148. package/dist/utils/normalizePath.cjs +27 -0
  149. package/dist/utils/normalizePath.cjs.map +1 -0
  150. package/dist/utils/normalizePath.js +21 -28
  151. package/dist/utils/normalizePath.js.map +1 -1
  152. package/dist/utils/resolveSignal.cjs +20 -0
  153. package/dist/utils/resolveSignal.cjs.map +1 -0
  154. package/dist/utils/resolveSignal.d.cts +15 -0
  155. package/dist/utils/resolveSignal.d.ts +12 -10
  156. package/dist/utils/resolveSignal.js +14 -17
  157. package/dist/utils/resolveSignal.js.map +1 -1
  158. package/dist/utils/sandbox-snapshot.cjs +14 -0
  159. package/dist/utils/sandbox-snapshot.cjs.map +1 -0
  160. package/dist/utils/sandbox-snapshot.d.cts +10 -0
  161. package/dist/utils/sandbox-snapshot.d.ts +11 -0
  162. package/dist/utils/sandbox-snapshot.js +14 -0
  163. package/dist/utils/sandbox-snapshot.js.map +1 -0
  164. package/dist/utils/types.cjs +13 -0
  165. package/dist/utils/types.cjs.map +1 -0
  166. package/dist/utils/types.d.cts +11 -0
  167. package/dist/utils/types.d.ts +5 -7
  168. package/dist/utils/types.js +8 -8
  169. package/dist/utils/types.js.map +1 -1
  170. package/dist/version.cjs +7 -0
  171. package/dist/version.cjs.map +1 -0
  172. package/dist/version.js +5 -5
  173. package/dist/version.js.map +1 -1
  174. package/package.json +23 -3
  175. package/dist/api-client/index.js.map +0 -1
  176. package/dist/auth/api.d.ts +0 -6
  177. package/dist/auth/error.d.ts +0 -11
  178. package/dist/auth/index.js.map +0 -1
  179. package/dist/auth/linked-project.d.ts +0 -10
  180. package/dist/auth/zod.d.ts +0 -5
  181. package/dist/constants.js +0 -3
  182. package/dist/constants.js.map +0 -1
  183. package/dist/index.js.map +0 -1
  184. package/dist/network-policy.js +0 -3
  185. package/dist/network-policy.js.map +0 -1
  186. package/dist/utils/array.d.ts +0 -9
  187. package/dist/utils/consume-readable.d.ts +0 -5
  188. package/dist/utils/convert-sandbox.d.ts +0 -6
  189. package/dist/utils/convert-sandbox.js +0 -14
  190. package/dist/utils/convert-sandbox.js.map +0 -1
  191. package/dist/utils/decode-base64-url.d.ts +0 -7
  192. package/dist/utils/dev-credentials.d.ts +0 -37
  193. package/dist/utils/log.d.ts +0 -2
  194. package/dist/utils/network-policy.d.ts +0 -7
  195. package/dist/utils/normalizePath.d.ts +0 -17
  196. package/dist/version.d.ts +0 -1
package/README.md CHANGED
@@ -181,6 +181,14 @@ const sandbox = await Sandbox.create({
181
181
  });
182
182
  ```
183
183
 
184
+ ## Workflow DevKit integration
185
+
186
+ `Sandbox` and `CommandFinished` support serialization with the
187
+ [Workflow DevKit](https://vercel.com/docs/workflow). When a sandbox instance
188
+ crosses a step boundary the SDK serializes sandbox metadata and routes, then
189
+ rehydrates synchronously from that snapshot. Deserialized instances lazily
190
+ recreate an API client using OIDC or environment credentials when needed.
191
+
184
192
  ## Limitations
185
193
 
186
194
  - Max resources: 8 vCPUs. You will get 2048 MB of memory per vCPU.
@@ -0,0 +1,29 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) {
13
+ __defProp(to, key, {
14
+ get: ((k) => from[k]).bind(null, key),
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ }
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
+ value: mod,
24
+ enumerable: true
25
+ }) : target, mod));
26
+
27
+ //#endregion
28
+
29
+ exports.__toESM = __toESM;
@@ -0,0 +1,456 @@
1
+ const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
2
+ const require_api_error = require('./api-error.cjs');
3
+ const require_base_client = require('./base-client.cjs');
4
+ const require_validators = require('./validators.cjs');
5
+ const require_file_writer = require('./file-writer.cjs');
6
+ const require_version = require('../version.cjs');
7
+ const require_consume_readable = require('../utils/consume-readable.cjs');
8
+ const require_normalizePath = require('../utils/normalizePath.cjs');
9
+ const require_network_policy = require('../utils/network-policy.cjs');
10
+ const require_types = require('../utils/types.cjs');
11
+ let node_timers_promises = require("node:timers/promises");
12
+ let zod = require("zod");
13
+ let stream = require("stream");
14
+ let jsonlines = require("jsonlines");
15
+ jsonlines = require_rolldown_runtime.__toESM(jsonlines);
16
+ let os = require("os");
17
+ os = require_rolldown_runtime.__toESM(os);
18
+ let __vercel_oidc = require("@vercel/oidc");
19
+
20
+ //#region src/api-client/api-client.ts
21
+ function decodeUnverifiedToken(token) {
22
+ if (token.split(".").length !== 3) return null;
23
+ try {
24
+ const payload = JSON.parse(Buffer.from(token.split(".")[1], "base64url").toString("utf8"));
25
+ if (payload.owner_id) return {
26
+ owner_id: payload.owner_id,
27
+ project_id: payload.project_id
28
+ };
29
+ return null;
30
+ } catch {
31
+ return null;
32
+ }
33
+ }
34
+ var APIClient = class extends require_base_client.BaseClient {
35
+ constructor(params) {
36
+ super({
37
+ baseUrl: params.baseUrl ?? "https://vercel.com/api",
38
+ token: params.token,
39
+ debug: false,
40
+ fetch: params.fetch
41
+ });
42
+ this.teamId = params.teamId;
43
+ this.isJwtToken = false;
44
+ const claims = decodeUnverifiedToken(params.token);
45
+ if (claims) {
46
+ this.isJwtToken = true;
47
+ this.projectId = claims.project_id;
48
+ this.teamId = claims.owner_id;
49
+ }
50
+ }
51
+ async ensureValidToken() {
52
+ if (!this.isJwtToken) return;
53
+ try {
54
+ const freshToken = await (0, __vercel_oidc.getVercelOidcToken)({
55
+ expirationBufferMs: 300 * 1e3,
56
+ team: this.teamId,
57
+ project: this.projectId
58
+ });
59
+ if (freshToken !== this.token) {
60
+ this.token = freshToken;
61
+ const claims = decodeUnverifiedToken(freshToken);
62
+ if (claims) this.teamId = claims.owner_id;
63
+ }
64
+ } catch {}
65
+ }
66
+ async request(path, params) {
67
+ await this.ensureValidToken();
68
+ return super.request(path, {
69
+ ...params,
70
+ query: {
71
+ teamId: this.teamId,
72
+ ...params?.query
73
+ },
74
+ headers: {
75
+ "content-type": "application/json",
76
+ "user-agent": `vercel/sandbox/${require_version.VERSION} (Node.js/${process.version}; ${os.default.platform()}/${os.default.arch()})`,
77
+ ...params?.headers
78
+ }
79
+ });
80
+ }
81
+ async getSession(params) {
82
+ const privateParams = require_types.getPrivateParams(params);
83
+ let querystring = new URLSearchParams(privateParams).toString();
84
+ querystring = querystring ? `?${querystring}` : "";
85
+ return require_base_client.parseOrThrow(require_validators.SessionAndRoutesResponse, await this.request(`/v2/sandboxes/sessions/${params.sessionId}${querystring}`, { signal: params.signal }));
86
+ }
87
+ async createSandbox(params) {
88
+ const privateParams = require_types.getPrivateParams(params);
89
+ return require_base_client.parseOrThrow(require_validators.SandboxAndSessionResponse, await this.request("/v2/sandboxes", {
90
+ method: "POST",
91
+ body: JSON.stringify({
92
+ projectId: params.projectId,
93
+ ports: params.ports,
94
+ source: params.source,
95
+ timeout: params.timeout,
96
+ resources: params.resources,
97
+ runtime: params.runtime,
98
+ name: params.name,
99
+ persistent: params.persistent,
100
+ networkPolicy: params.networkPolicy ? require_network_policy.toAPINetworkPolicy(params.networkPolicy) : void 0,
101
+ env: params.env,
102
+ tags: params.tags,
103
+ snapshotExpiration: params.snapshotExpiration,
104
+ ...privateParams
105
+ }),
106
+ signal: params.signal
107
+ }));
108
+ }
109
+ async runCommand(params) {
110
+ if (params.wait) {
111
+ const response = await this.request(`/v2/sandboxes/sessions/${params.sessionId}/cmd`, {
112
+ method: "POST",
113
+ body: JSON.stringify({
114
+ command: params.command,
115
+ args: params.args,
116
+ cwd: params.cwd,
117
+ env: params.env,
118
+ sudo: params.sudo,
119
+ wait: true
120
+ }),
121
+ signal: params.signal
122
+ });
123
+ if (!response.ok) await require_base_client.parseOrThrow(zod.z.any(), response);
124
+ if (response.headers.get("content-type") !== "application/x-ndjson") throw new require_api_error.APIError(response, {
125
+ message: "Expected a stream of command data",
126
+ sessionId: params.sessionId
127
+ });
128
+ if (response.body === null) throw new require_api_error.APIError(response, {
129
+ message: "No response body",
130
+ sessionId: params.sessionId
131
+ });
132
+ const jsonlinesStream = jsonlines.default.parse();
133
+ pipe(response.body, jsonlinesStream, { signal: params.signal }).catch((err) => {
134
+ console.error("Error piping command stream:", err);
135
+ });
136
+ const iterator = jsonlinesStream[Symbol.asyncIterator]();
137
+ const commandChunk = await iterator.next();
138
+ if (commandChunk.done) throw new require_api_error.StreamError("stream_ended_early", "Stream ended before command data was received", params.sessionId);
139
+ const { command } = require_validators.CommandResponse.parse(commandChunk.value);
140
+ return {
141
+ command,
142
+ finished: (async () => {
143
+ const finishedChunk = await iterator.next();
144
+ if (finishedChunk.done) throw new require_api_error.StreamError("stream_ended_early", "Stream ended before command finished", params.sessionId);
145
+ const { command: command$1 } = require_validators.CommandFinishedResponse.parse(finishedChunk.value);
146
+ return command$1;
147
+ })()
148
+ };
149
+ }
150
+ return require_base_client.parseOrThrow(require_validators.CommandResponse, await this.request(`/v2/sandboxes/sessions/${params.sessionId}/cmd`, {
151
+ method: "POST",
152
+ body: JSON.stringify({
153
+ command: params.command,
154
+ args: params.args,
155
+ cwd: params.cwd,
156
+ env: params.env,
157
+ sudo: params.sudo
158
+ }),
159
+ signal: params.signal
160
+ }));
161
+ }
162
+ async getCommand(params) {
163
+ return params.wait ? require_base_client.parseOrThrow(require_validators.CommandFinishedResponse, await this.request(`/v2/sandboxes/sessions/${params.sessionId}/cmd/${params.cmdId}`, {
164
+ signal: params.signal,
165
+ query: { wait: "true" }
166
+ })) : require_base_client.parseOrThrow(require_validators.CommandResponse, await this.request(`/v2/sandboxes/sessions/${params.sessionId}/cmd/${params.cmdId}`, { signal: params.signal }));
167
+ }
168
+ async mkDir(params) {
169
+ return require_base_client.parseOrThrow(require_validators.EmptyResponse, await this.request(`/v2/sandboxes/sessions/${params.sessionId}/fs/mkdir`, {
170
+ method: "POST",
171
+ body: JSON.stringify({
172
+ path: params.path,
173
+ cwd: params.cwd
174
+ }),
175
+ signal: params.signal
176
+ }));
177
+ }
178
+ getFileWriter(params) {
179
+ const writer = new require_file_writer.FileWriter();
180
+ return {
181
+ response: (async () => {
182
+ return this.request(`/v2/sandboxes/sessions/${params.sessionId}/fs/write`, {
183
+ method: "POST",
184
+ headers: {
185
+ "content-type": "application/gzip",
186
+ "x-cwd": params.extractDir
187
+ },
188
+ body: await require_consume_readable.consumeReadable(writer.readable),
189
+ signal: params.signal
190
+ });
191
+ })(),
192
+ writer
193
+ };
194
+ }
195
+ async listSessions(params) {
196
+ return require_base_client.parseOrThrow(require_validators.SessionsResponse, await this.request(`/v2/sandboxes/sessions`, {
197
+ query: {
198
+ project: params.projectId,
199
+ name: params.name,
200
+ limit: params.limit,
201
+ cursor: params.cursor,
202
+ sortOrder: params.sortOrder
203
+ },
204
+ method: "GET",
205
+ signal: params.signal
206
+ }));
207
+ }
208
+ async listSnapshots(params) {
209
+ return require_base_client.parseOrThrow(require_validators.SnapshotsResponse, await this.request(`/v2/sandboxes/snapshots`, {
210
+ query: {
211
+ project: params.projectId,
212
+ name: params.name,
213
+ limit: params.limit,
214
+ cursor: params.cursor,
215
+ sortOrder: params.sortOrder
216
+ },
217
+ method: "GET",
218
+ signal: params.signal
219
+ }));
220
+ }
221
+ async writeFiles(params) {
222
+ const { writer, response } = this.getFileWriter({
223
+ sessionId: params.sessionId,
224
+ extractDir: params.extractDir,
225
+ signal: params.signal
226
+ });
227
+ for (const file of params.files) await writer.addFile({
228
+ name: require_normalizePath.normalizePath({
229
+ filePath: file.path,
230
+ extractDir: params.extractDir,
231
+ cwd: params.cwd
232
+ }),
233
+ content: file.content,
234
+ mode: file.mode
235
+ });
236
+ writer.end();
237
+ await require_base_client.parseOrThrow(require_validators.EmptyResponse, await response);
238
+ }
239
+ async readFile(params) {
240
+ const response = await this.request(`/v2/sandboxes/sessions/${params.sessionId}/fs/read`, {
241
+ method: "POST",
242
+ body: JSON.stringify({
243
+ path: params.path,
244
+ cwd: params.cwd
245
+ }),
246
+ signal: params.signal
247
+ });
248
+ if (response.status === 404) return null;
249
+ if (!response.ok) await require_base_client.parseOrThrow(zod.z.any(), response);
250
+ if (response.body === null) return null;
251
+ return stream.Readable.fromWeb(response.body);
252
+ }
253
+ async killCommand(params) {
254
+ return require_base_client.parseOrThrow(require_validators.CommandResponse, await this.request(`/v2/sandboxes/sessions/${params.sessionId}/cmd/${params.commandId}/kill`, {
255
+ method: "POST",
256
+ body: JSON.stringify({ signal: params.signal }),
257
+ signal: params.abortSignal
258
+ }));
259
+ }
260
+ getLogs(params) {
261
+ const self = this;
262
+ const disposer = new AbortController();
263
+ const signal = !params.signal ? disposer.signal : mergeSignals(params.signal, disposer.signal);
264
+ const generator = (async function* () {
265
+ const url = `/v2/sandboxes/sessions/${params.sessionId}/cmd/${params.cmdId}/logs`;
266
+ const response = await self.request(url, {
267
+ method: "GET",
268
+ signal
269
+ });
270
+ if (!response.ok) await require_base_client.parseOrThrow(zod.z.any(), response);
271
+ if (response.headers.get("content-type") !== "application/x-ndjson") throw new require_api_error.APIError(response, {
272
+ message: "Expected a stream of logs",
273
+ sessionId: params.sessionId
274
+ });
275
+ if (response.body === null) throw new require_api_error.APIError(response, {
276
+ message: "No response body",
277
+ sessionId: params.sessionId
278
+ });
279
+ const jsonlinesStream = jsonlines.default.parse();
280
+ pipe(response.body, jsonlinesStream, { signal }).catch((err) => {
281
+ console.error("Error piping logs:", err);
282
+ });
283
+ for await (const chunk of jsonlinesStream) {
284
+ const parsed = require_validators.LogLine.parse(chunk);
285
+ if (parsed.stream === "error") throw new require_api_error.StreamError(parsed.data.code, parsed.data.message, params.sessionId);
286
+ yield parsed;
287
+ }
288
+ })();
289
+ return Object.assign(generator, {
290
+ [Symbol.dispose]() {
291
+ disposer.abort("Disposed");
292
+ },
293
+ close: () => disposer.abort("Disposed")
294
+ });
295
+ }
296
+ async stopSession(params) {
297
+ const url = `/v2/sandboxes/sessions/${params.sessionId}/stop`;
298
+ const response = await require_base_client.parseOrThrow(require_validators.SessionResponse, await this.request(url, {
299
+ method: "POST",
300
+ signal: params.signal
301
+ }));
302
+ if (params.blocking) {
303
+ let session = response.json.session;
304
+ while (session.status !== "stopped" && session.status !== "failed" && session.status !== "aborted") {
305
+ await (0, node_timers_promises.setTimeout)(500, void 0, { signal: params.signal });
306
+ session = (await this.getSession({
307
+ sessionId: params.sessionId,
308
+ signal: params.signal
309
+ })).json.session;
310
+ response.json.session = session;
311
+ }
312
+ }
313
+ return response;
314
+ }
315
+ async updateNetworkPolicy(params) {
316
+ const url = `/v2/sandboxes/sessions/${params.sessionId}/network-policy`;
317
+ return require_base_client.parseOrThrow(require_validators.SessionResponse, await this.request(url, {
318
+ method: "POST",
319
+ body: JSON.stringify(require_network_policy.toAPINetworkPolicy(params.networkPolicy)),
320
+ signal: params.signal
321
+ }));
322
+ }
323
+ async extendTimeout(params) {
324
+ const url = `/v2/sandboxes/sessions/${params.sessionId}/extend-timeout`;
325
+ return require_base_client.parseOrThrow(require_validators.SessionResponse, await this.request(url, {
326
+ method: "POST",
327
+ body: JSON.stringify({ duration: params.duration }),
328
+ signal: params.signal
329
+ }));
330
+ }
331
+ async createSnapshot(params) {
332
+ const url = `/v2/sandboxes/sessions/${params.sessionId}/snapshot`;
333
+ const body = params.expiration === void 0 ? void 0 : JSON.stringify({ expiration: params.expiration });
334
+ return require_base_client.parseOrThrow(require_validators.CreateSnapshotResponse, await this.request(url, {
335
+ method: "POST",
336
+ body,
337
+ signal: params.signal
338
+ }));
339
+ }
340
+ async deleteSnapshot(params) {
341
+ const url = `/v2/sandboxes/snapshots/${params.snapshotId}`;
342
+ return require_base_client.parseOrThrow(require_validators.SnapshotResponse, await this.request(url, {
343
+ method: "DELETE",
344
+ signal: params.signal
345
+ }));
346
+ }
347
+ async getSnapshot(params) {
348
+ const url = `/v2/sandboxes/snapshots/${params.snapshotId}`;
349
+ return require_base_client.parseOrThrow(require_validators.SnapshotResponse, await this.request(url, { signal: params.signal }));
350
+ }
351
+ async getSandbox(params) {
352
+ const privateParams = require_types.getPrivateParams(params);
353
+ const query = {
354
+ projectId: params.projectId,
355
+ ...privateParams
356
+ };
357
+ if (params.resume !== void 0) query.resume = String(params.resume);
358
+ return require_base_client.parseOrThrow(require_validators.SandboxAndSessionResponse, await this.request(`/v2/sandboxes/${encodeURIComponent(params.name)}`, {
359
+ query,
360
+ signal: params.signal
361
+ }));
362
+ }
363
+ async listSandboxes(params) {
364
+ return require_base_client.parseOrThrow(require_validators.SandboxesPaginationResponse, await this.request(`/v2/sandboxes`, {
365
+ query: {
366
+ project: params.projectId,
367
+ limit: params.limit,
368
+ sortBy: params.sortBy,
369
+ sortOrder: params.sortOrder,
370
+ namePrefix: params.namePrefix,
371
+ cursor: params.cursor,
372
+ tags: toTagsFilter(params.tags)
373
+ },
374
+ method: "GET",
375
+ signal: params.signal
376
+ }));
377
+ }
378
+ async updateSandbox(params) {
379
+ return require_base_client.parseOrThrow(require_validators.UpdateSandboxResponse, await this.request(`/v2/sandboxes/${encodeURIComponent(params.name)}`, {
380
+ method: "PATCH",
381
+ query: { projectId: params.projectId },
382
+ body: JSON.stringify({
383
+ persistent: params.persistent,
384
+ resources: params.resources,
385
+ runtime: params.runtime,
386
+ timeout: params.timeout,
387
+ networkPolicy: params.networkPolicy ? require_network_policy.toAPINetworkPolicy(params.networkPolicy) : void 0,
388
+ tags: params.tags,
389
+ snapshotExpiration: params.snapshotExpiration
390
+ }),
391
+ signal: params.signal
392
+ }));
393
+ }
394
+ async deleteSandbox(params) {
395
+ return require_base_client.parseOrThrow(require_validators.UpdateSandboxResponse, await this.request(`/v2/sandboxes/${encodeURIComponent(params.name)}`, {
396
+ method: "DELETE",
397
+ query: { projectId: params.projectId },
398
+ signal: params.signal
399
+ }));
400
+ }
401
+ };
402
+ async function pipe(readable, output, options) {
403
+ const reader = readable.getReader();
404
+ let aborted = false;
405
+ const signal = options?.signal;
406
+ const onAbort = () => {
407
+ aborted = true;
408
+ const reason = signal?.reason ?? new DOMException("The operation was aborted.", "AbortError");
409
+ reader.cancel(reason).catch(() => {});
410
+ if ("destroy" in output && typeof output.destroy === "function") {
411
+ output.destroy(reason);
412
+ return;
413
+ }
414
+ output.emit("error", reason);
415
+ output.end();
416
+ };
417
+ if (signal) if (signal.aborted) onAbort();
418
+ else signal.addEventListener("abort", onAbort, { once: true });
419
+ try {
420
+ while (true) {
421
+ const read = await reader.read();
422
+ if (read.value) output.write(Buffer.from(read.value));
423
+ if (read.done) break;
424
+ }
425
+ } catch (err) {
426
+ if (!aborted) output.emit("error", err);
427
+ } finally {
428
+ signal?.removeEventListener("abort", onAbort);
429
+ if (!aborted) output.end();
430
+ }
431
+ }
432
+ function mergeSignals(...signals) {
433
+ const controller = new AbortController();
434
+ const onAbort = () => {
435
+ controller.abort();
436
+ for (const signal of signals) signal.removeEventListener("abort", onAbort);
437
+ };
438
+ for (const signal of signals) {
439
+ if (signal.aborted) {
440
+ controller.abort();
441
+ break;
442
+ }
443
+ signal.addEventListener("abort", onAbort);
444
+ }
445
+ return controller.signal;
446
+ }
447
+ function toTagsFilter(tags) {
448
+ if (tags === void 0) return void 0;
449
+ const entries = Object.entries(tags);
450
+ if (entries.length === 0) return void 0;
451
+ return entries.map(([key, value]) => `${key}:${value}`);
452
+ }
453
+
454
+ //#endregion
455
+ exports.APIClient = APIClient;
456
+ //# sourceMappingURL=api-client.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.cjs","names":["BaseClient","VERSION","getPrivateParams","parseOrThrow","SessionAndRoutesResponse","SandboxAndSessionResponse","toAPINetworkPolicy","z","APIError","StreamError","CommandResponse","CommandFinishedResponse","command","EmptyResponse","FileWriter","consumeReadable","SessionsResponse","SnapshotsResponse","normalizePath","Readable","LogLine","SessionResponse","CreateSnapshotResponse","SnapshotResponse","query: Record<string, string | undefined>","SandboxesPaginationResponse","UpdateSandboxResponse"],"sources":["../../src/api-client/api-client.ts"],"sourcesContent":["import {\n BaseClient,\n parseOrThrow,\n type Parsed,\n type RequestParams,\n} from \"./base-client.js\";\nimport {\n type CommandFinishedData,\n SessionAndRoutesResponse,\n SessionResponse,\n SessionsResponse,\n CommandResponse,\n CommandFinishedResponse,\n EmptyResponse,\n LogLine,\n type LogLineStdout,\n type LogLineStderr,\n SnapshotsResponse,\n SnapshotResponse,\n CreateSnapshotResponse,\n SandboxAndSessionResponse,\n SandboxesPaginationResponse,\n UpdateSandboxResponse,\n type CommandData,\n} from \"./validators.js\";\nimport { APIError, StreamError } from \"./api-error.js\";\nimport { FileWriter } from \"./file-writer.js\";\nimport { VERSION } from \"../version.js\";\nimport { consumeReadable } from \"../utils/consume-readable.js\";\nimport { z } from \"zod\";\nimport jsonlines from \"jsonlines\";\nimport os from \"os\";\nimport { Readable } from \"stream\";\nimport { normalizePath } from \"../utils/normalizePath.js\";\nimport { getVercelOidcToken } from \"@vercel/oidc\";\nimport { NetworkPolicy } from \"../network-policy.js\";\nimport {\n toAPINetworkPolicy,\n fromAPINetworkPolicy,\n} from \"../utils/network-policy.js\";\nimport { getPrivateParams, WithPrivate } from \"../utils/types.js\";\nimport { RUNTIMES } from \"../constants.js\";\nimport { setTimeout } from \"node:timers/promises\";\n\ninterface Claims {\n owner_id: string;\n project_id?: string;\n}\n\nfunction decodeUnverifiedToken(token: string): Claims | null {\n if (token.split(\".\").length !== 3) {\n return null;\n }\n try {\n const payload = JSON.parse(\n Buffer.from(token.split(\".\")[1], \"base64url\").toString(\"utf8\"),\n );\n if (payload.owner_id) {\n return { owner_id: payload.owner_id, project_id: payload.project_id };\n }\n return null;\n } catch {\n return null;\n }\n}\n\nexport interface WithFetchOptions {\n fetch?: typeof globalThis.fetch;\n}\n\nexport class APIClient extends BaseClient {\n private teamId: string;\n private projectId: string | undefined;\n private isJwtToken: boolean;\n\n constructor(params: {\n baseUrl?: string;\n teamId: string;\n token: string;\n fetch?: typeof globalThis.fetch;\n }) {\n super({\n baseUrl: params.baseUrl ?? \"https://vercel.com/api\",\n token: params.token,\n debug: false,\n fetch: params.fetch,\n });\n\n this.teamId = params.teamId;\n this.isJwtToken = false;\n\n const claims = decodeUnverifiedToken(params.token);\n if (claims) {\n this.isJwtToken = true;\n this.projectId = claims.project_id;\n this.teamId = claims.owner_id;\n }\n }\n\n private async ensureValidToken(): Promise<void> {\n if (!this.isJwtToken) {\n return;\n }\n\n try {\n // Use getVercelOidcToken to refresh the token with team/project scope\n const freshToken = await getVercelOidcToken({\n expirationBufferMs: 5 * 60 * 1000, // 5 minutes\n team: this.teamId,\n project: this.projectId,\n });\n\n // Update token if it changed\n if (freshToken !== this.token) {\n this.token = freshToken;\n\n const claims = decodeUnverifiedToken(freshToken);\n if (claims) {\n this.teamId = claims.owner_id;\n }\n }\n } catch {\n // Ignore refresh errors and continue with current token\n }\n }\n\n protected async request(path: string, params?: RequestParams) {\n await this.ensureValidToken();\n\n return super.request(path, {\n ...params,\n query: { teamId: this.teamId, ...params?.query },\n headers: {\n \"content-type\": \"application/json\",\n \"user-agent\": `vercel/sandbox/${VERSION} (Node.js/${process.version}; ${os.platform()}/${os.arch()})`,\n ...params?.headers,\n },\n });\n }\n\n async getSession(\n params: WithPrivate<{ sessionId: string; signal?: AbortSignal }>,\n ) {\n const privateParams = getPrivateParams(params);\n let querystring = new URLSearchParams(privateParams).toString();\n querystring = querystring ? `?${querystring}` : \"\";\n return parseOrThrow(\n SessionAndRoutesResponse,\n await this.request(`/v2/sandboxes/sessions/${params.sessionId}${querystring}`, {\n signal: params.signal,\n }),\n );\n }\n\n async createSandbox(\n params: WithPrivate<{\n name?: string;\n ports?: number[];\n projectId: string;\n source?:\n | {\n type: \"git\";\n url: string;\n depth?: number;\n revision?: string;\n username?: string;\n password?: string;\n }\n | { type: \"tarball\"; url: string }\n | { type: \"snapshot\"; snapshotId: string };\n timeout?: number;\n resources?: { vcpus: number };\n persistent?: boolean;\n runtime?: RUNTIMES | (string & {});\n networkPolicy?: NetworkPolicy;\n env?: Record<string, string>;\n tags?: Record<string, string>;\n snapshotExpiration?: number;\n signal?: AbortSignal;\n }>,\n ) {\n const privateParams = getPrivateParams(params);\n return parseOrThrow(\n SandboxAndSessionResponse,\n await this.request(\"/v2/sandboxes\", {\n method: \"POST\",\n body: JSON.stringify({\n projectId: params.projectId,\n ports: params.ports,\n source: params.source,\n timeout: params.timeout,\n resources: params.resources,\n runtime: params.runtime,\n name: params.name,\n persistent: params.persistent,\n networkPolicy: params.networkPolicy\n ? toAPINetworkPolicy(params.networkPolicy)\n : undefined,\n env: params.env,\n tags: params.tags,\n snapshotExpiration: params.snapshotExpiration,\n ...privateParams,\n }),\n signal: params.signal,\n }),\n );\n }\n\n async runCommand(params: {\n sessionId: string;\n cwd?: string;\n command: string;\n args: string[];\n env: Record<string, string>;\n sudo: boolean;\n wait: true;\n signal?: AbortSignal;\n }): Promise<{ command: CommandData; finished: Promise<CommandFinishedData> }>;\n async runCommand(params: {\n sessionId: string;\n cwd?: string;\n command: string;\n args: string[];\n env: Record<string, string>;\n sudo: boolean;\n wait?: false;\n signal?: AbortSignal;\n }): Promise<Parsed<z.infer<typeof CommandResponse>>>;\n async runCommand(params: {\n sessionId: string;\n cwd?: string;\n command: string;\n args: string[];\n env: Record<string, string>;\n sudo: boolean;\n wait?: boolean;\n signal?: AbortSignal;\n }) {\n if (params.wait) {\n const response = await this.request(\n `/v2/sandboxes/sessions/${params.sessionId}/cmd`,\n {\n method: \"POST\",\n body: JSON.stringify({\n command: params.command,\n args: params.args,\n cwd: params.cwd,\n env: params.env,\n sudo: params.sudo,\n wait: true,\n }),\n signal: params.signal,\n },\n );\n\n if (!response.ok) {\n await parseOrThrow(z.any(), response);\n }\n\n if (response.headers.get(\"content-type\") !== \"application/x-ndjson\") {\n throw new APIError(response, {\n message: \"Expected a stream of command data\",\n sessionId: params.sessionId,\n });\n }\n\n if (response.body === null) {\n throw new APIError(response, {\n message: \"No response body\",\n sessionId: params.sessionId,\n });\n }\n\n const jsonlinesStream = jsonlines.parse();\n pipe(response.body, jsonlinesStream, { signal: params.signal }).catch(\n (err) => {\n console.error(\"Error piping command stream:\", err);\n },\n );\n\n const iterator = jsonlinesStream[Symbol.asyncIterator]();\n const commandChunk = await iterator.next();\n if (commandChunk.done) {\n throw new StreamError(\n \"stream_ended_early\",\n \"Stream ended before command data was received\",\n params.sessionId,\n );\n }\n const { command } = CommandResponse.parse(commandChunk.value);\n\n const finished = (async () => {\n const finishedChunk = await iterator.next();\n if (finishedChunk.done) {\n throw new StreamError(\n \"stream_ended_early\",\n \"Stream ended before command finished\",\n params.sessionId,\n );\n }\n const { command } = CommandFinishedResponse.parse(finishedChunk.value);\n return command;\n })();\n\n return { command, finished };\n }\n\n return parseOrThrow(\n CommandResponse,\n await this.request(`/v2/sandboxes/sessions/${params.sessionId}/cmd`, {\n method: \"POST\",\n body: JSON.stringify({\n command: params.command,\n args: params.args,\n cwd: params.cwd,\n env: params.env,\n sudo: params.sudo,\n }),\n signal: params.signal,\n }),\n );\n }\n\n async getCommand(params: {\n sessionId: string;\n cmdId: string;\n wait: true;\n signal?: AbortSignal;\n }): Promise<Parsed<z.infer<typeof CommandFinishedResponse>>>;\n async getCommand(params: {\n sessionId: string;\n cmdId: string;\n wait?: boolean;\n signal?: AbortSignal;\n }): Promise<Parsed<z.infer<typeof CommandResponse>>>;\n async getCommand(params: {\n sessionId: string;\n cmdId: string;\n wait?: boolean;\n signal?: AbortSignal;\n }) {\n return params.wait\n ? parseOrThrow(\n CommandFinishedResponse,\n await this.request(\n `/v2/sandboxes/sessions/${params.sessionId}/cmd/${params.cmdId}`,\n { signal: params.signal, query: { wait: \"true\" } },\n ),\n )\n : parseOrThrow(\n CommandResponse,\n await this.request(\n `/v2/sandboxes/sessions/${params.sessionId}/cmd/${params.cmdId}`,\n { signal: params.signal },\n ),\n );\n }\n\n async mkDir(params: {\n sessionId: string;\n path: string;\n cwd?: string;\n signal?: AbortSignal;\n }) {\n return parseOrThrow(\n EmptyResponse,\n await this.request(`/v2/sandboxes/sessions/${params.sessionId}/fs/mkdir`, {\n method: \"POST\",\n body: JSON.stringify({ path: params.path, cwd: params.cwd }),\n signal: params.signal,\n }),\n );\n }\n\n getFileWriter(params: {\n sessionId: string;\n extractDir: string;\n signal?: AbortSignal;\n }) {\n const writer = new FileWriter();\n return {\n response: (async () => {\n return this.request(`/v2/sandboxes/sessions/${params.sessionId}/fs/write`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/gzip\",\n \"x-cwd\": params.extractDir,\n },\n body: await consumeReadable(writer.readable),\n signal: params.signal,\n });\n })(),\n writer,\n };\n }\n\n async listSessions(params: {\n /**\n * The ID or name of the project to which the sessions belong.\n * @example \"my-project\"\n */\n projectId: string;\n /**\n * Filter sessions by sandbox name.\n */\n name?: string;\n /**\n * Maximum number of sessions to list from a request.\n * @example 10\n */\n limit?: number;\n /**\n * Cursor for pagination.\n */\n cursor?: string;\n /**\n * Sort order for results.\n */\n sortOrder?: \"asc\" | \"desc\";\n signal?: AbortSignal;\n }) {\n return parseOrThrow(\n SessionsResponse,\n await this.request(`/v2/sandboxes/sessions`, {\n query: {\n project: params.projectId,\n name: params.name,\n limit: params.limit,\n cursor: params.cursor,\n sortOrder: params.sortOrder,\n },\n method: \"GET\",\n signal: params.signal,\n }),\n );\n }\n\n async listSnapshots(params: {\n /**\n * The ID or name of the project to which the snapshots belong.\n * @example \"my-project\"\n */\n projectId: string;\n /**\n * Filter snapshots by sandbox name.\n */\n name?: string;\n /**\n * Maximum number of snapshots to list from a request.\n * @example 10\n */\n limit?: number;\n /**\n * Cursor for pagination.\n */\n cursor?: string;\n /**\n * Sort order for results.\n */\n sortOrder?: \"asc\" | \"desc\";\n signal?: AbortSignal;\n }) {\n return parseOrThrow(\n SnapshotsResponse,\n await this.request(`/v2/sandboxes/snapshots`, {\n query: {\n project: params.projectId,\n name: params.name,\n limit: params.limit,\n cursor: params.cursor,\n sortOrder: params.sortOrder,\n },\n method: \"GET\",\n signal: params.signal,\n }),\n );\n }\n\n async writeFiles(params: {\n sessionId: string;\n cwd: string;\n files: {\n path: string;\n content: string | Uint8Array;\n mode?: number;\n }[];\n extractDir: string;\n signal?: AbortSignal;\n }) {\n const { writer, response } = this.getFileWriter({\n sessionId: params.sessionId,\n extractDir: params.extractDir,\n signal: params.signal,\n });\n\n for (const file of params.files) {\n await writer.addFile({\n name: normalizePath({\n filePath: file.path,\n extractDir: params.extractDir,\n cwd: params.cwd,\n }),\n content: file.content,\n mode: file.mode,\n });\n }\n\n writer.end();\n await parseOrThrow(EmptyResponse, await response);\n }\n\n async readFile(params: {\n sessionId: string;\n path: string;\n cwd?: string;\n signal?: AbortSignal;\n }): Promise<Readable | null> {\n const response = await this.request(\n `/v2/sandboxes/sessions/${params.sessionId}/fs/read`,\n {\n method: \"POST\",\n body: JSON.stringify({ path: params.path, cwd: params.cwd }),\n signal: params.signal,\n },\n );\n\n if (response.status === 404) {\n return null;\n }\n\n if (!response.ok) {\n await parseOrThrow(z.any(), response);\n }\n\n if (response.body === null) {\n return null;\n }\n\n return Readable.fromWeb(response.body);\n }\n\n async killCommand(params: {\n sessionId: string;\n commandId: string;\n signal: number;\n abortSignal?: AbortSignal;\n }) {\n return parseOrThrow(\n CommandResponse,\n await this.request(\n `/v2/sandboxes/sessions/${params.sessionId}/cmd/${params.commandId}/kill`,\n {\n method: \"POST\",\n body: JSON.stringify({ signal: params.signal }),\n signal: params.abortSignal,\n },\n ),\n );\n }\n\n getLogs(params: {\n sessionId: string;\n cmdId: string;\n signal?: AbortSignal;\n }): AsyncGenerator<\n z.infer<typeof LogLineStdout> | z.infer<typeof LogLineStderr>,\n void,\n void\n > &\n Disposable & { close(): void } {\n const self = this;\n const disposer = new AbortController();\n const signal = !params.signal\n ? disposer.signal\n : mergeSignals(params.signal, disposer.signal);\n\n const generator = (async function* () {\n const url = `/v2/sandboxes/sessions/${params.sessionId}/cmd/${params.cmdId}/logs`;\n const response = await self.request(url, {\n method: \"GET\",\n signal,\n });\n\n if (!response.ok) {\n await parseOrThrow(z.any(), response);\n }\n\n if (response.headers.get(\"content-type\") !== \"application/x-ndjson\") {\n throw new APIError(response, {\n message: \"Expected a stream of logs\",\n sessionId: params.sessionId,\n });\n }\n\n if (response.body === null) {\n throw new APIError(response, {\n message: \"No response body\",\n sessionId: params.sessionId,\n });\n }\n\n const jsonlinesStream = jsonlines.parse();\n pipe(response.body, jsonlinesStream, { signal }).catch((err) => {\n console.error(\"Error piping logs:\", err);\n });\n\n for await (const chunk of jsonlinesStream) {\n const parsed = LogLine.parse(chunk);\n if (parsed.stream === \"error\") {\n throw new StreamError(\n parsed.data.code,\n parsed.data.message,\n params.sessionId,\n );\n }\n yield parsed;\n }\n })();\n\n return Object.assign(generator, {\n [Symbol.dispose]() {\n disposer.abort(\"Disposed\");\n },\n close: () => disposer.abort(\"Disposed\"),\n });\n }\n\n async stopSession(params: {\n sessionId: string;\n signal?: AbortSignal;\n blocking?: boolean;\n }): Promise<Parsed<z.infer<typeof SessionResponse>>> {\n const url = `/v2/sandboxes/sessions/${params.sessionId}/stop`;\n const response = await parseOrThrow(\n SessionResponse,\n await this.request(url, { method: \"POST\", signal: params.signal }),\n );\n\n if (params.blocking) {\n let session = response.json.session;\n while (\n session.status !== \"stopped\" &&\n session.status !== \"failed\" &&\n session.status !== \"aborted\"\n ) {\n await setTimeout(500, undefined, { signal: params.signal });\n const poll = await this.getSession({\n sessionId: params.sessionId,\n signal: params.signal,\n });\n session = poll.json.session;\n response.json.session = session;\n }\n }\n\n return response;\n }\n\n async updateNetworkPolicy(params: {\n sessionId: string;\n networkPolicy: NetworkPolicy;\n signal?: AbortSignal;\n }): Promise<Parsed<z.infer<typeof SessionResponse>>> {\n const url = `/v2/sandboxes/sessions/${params.sessionId}/network-policy`;\n return parseOrThrow(\n SessionResponse,\n await this.request(url, {\n method: \"POST\",\n body: JSON.stringify(toAPINetworkPolicy(params.networkPolicy)),\n signal: params.signal,\n }),\n );\n }\n\n async extendTimeout(params: {\n sessionId: string;\n duration: number;\n signal?: AbortSignal;\n }): Promise<Parsed<z.infer<typeof SessionResponse>>> {\n const url = `/v2/sandboxes/sessions/${params.sessionId}/extend-timeout`;\n return parseOrThrow(\n SessionResponse,\n await this.request(url, {\n method: \"POST\",\n body: JSON.stringify({ duration: params.duration }),\n signal: params.signal,\n }),\n );\n }\n\n async createSnapshot(params: {\n sessionId: string;\n expiration?: number;\n signal?: AbortSignal;\n }): Promise<Parsed<z.infer<typeof CreateSnapshotResponse>>> {\n const url = `/v2/sandboxes/sessions/${params.sessionId}/snapshot`;\n const body =\n params.expiration === undefined\n ? undefined\n : JSON.stringify({ expiration: params.expiration });\n return parseOrThrow(\n CreateSnapshotResponse,\n await this.request(url, {\n method: \"POST\",\n body,\n signal: params.signal,\n }),\n );\n }\n\n async deleteSnapshot(params: {\n snapshotId: string;\n signal?: AbortSignal;\n }): Promise<Parsed<z.infer<typeof SnapshotResponse>>> {\n const url = `/v2/sandboxes/snapshots/${params.snapshotId}`;\n return parseOrThrow(\n SnapshotResponse,\n await this.request(url, { method: \"DELETE\", signal: params.signal }),\n );\n }\n\n async getSnapshot(params: {\n snapshotId: string;\n signal?: AbortSignal;\n }): Promise<Parsed<z.infer<typeof SnapshotResponse>>> {\n const url = `/v2/sandboxes/snapshots/${params.snapshotId}`;\n return parseOrThrow(\n SnapshotResponse,\n await this.request(url, { signal: params.signal }),\n );\n }\n\n async getSandbox(params: WithPrivate<{\n name: string;\n projectId: string;\n resume?: boolean;\n signal?: AbortSignal;\n }>) {\n const privateParams = getPrivateParams(params);\n const query: Record<string, string | undefined> = {\n projectId: params.projectId,\n ...privateParams,\n };\n if (params.resume !== undefined) {\n query.resume = String(params.resume);\n }\n return parseOrThrow(\n SandboxAndSessionResponse,\n await this.request(`/v2/sandboxes/${encodeURIComponent(params.name)}`, {\n query,\n signal: params.signal,\n }),\n );\n }\n\n async listSandboxes(params: {\n projectId: string;\n limit?: number;\n sortBy?: \"createdAt\" | \"name\" | \"statusUpdatedAt\";\n sortOrder?: \"asc\" | \"desc\";\n namePrefix?: string;\n cursor?: string;\n tags?: Record<string, string>;\n signal?: AbortSignal;\n }) {\n return parseOrThrow(\n SandboxesPaginationResponse,\n await this.request(`/v2/sandboxes`, {\n query: {\n project: params.projectId,\n limit: params.limit,\n sortBy: params.sortBy,\n sortOrder: params.sortOrder,\n namePrefix: params.namePrefix,\n cursor: params.cursor,\n tags: toTagsFilter(params.tags),\n },\n method: \"GET\",\n signal: params.signal,\n }),\n );\n }\n\n async updateSandbox(params: {\n name: string;\n projectId: string;\n persistent?: boolean;\n resources?: { vcpus?: number; memory?: number };\n runtime?: RUNTIMES | (string & {});\n timeout?: number;\n networkPolicy?: NetworkPolicy;\n tags?: Record<string, string>;\n snapshotExpiration?: number;\n signal?: AbortSignal;\n }) {\n return parseOrThrow(\n UpdateSandboxResponse,\n await this.request(`/v2/sandboxes/${encodeURIComponent(params.name)}`, {\n method: \"PATCH\",\n query: {\n projectId: params.projectId,\n },\n body: JSON.stringify({\n persistent: params.persistent,\n resources: params.resources,\n runtime: params.runtime,\n timeout: params.timeout,\n networkPolicy: params.networkPolicy\n ? toAPINetworkPolicy(params.networkPolicy)\n : undefined,\n tags: params.tags,\n snapshotExpiration: params.snapshotExpiration,\n }),\n signal: params.signal,\n }),\n );\n }\n\n async deleteSandbox(params: {\n name: string;\n projectId: string;\n signal?: AbortSignal;\n }) {\n return parseOrThrow(\n UpdateSandboxResponse,\n await this.request(`/v2/sandboxes/${encodeURIComponent(params.name)}`, {\n method: \"DELETE\",\n query: {\n projectId: params.projectId,\n },\n signal: params.signal,\n }),\n );\n }\n}\n\nasync function pipe(\n readable: ReadableStream<Uint8Array>,\n output: NodeJS.WritableStream,\n options?: { signal?: AbortSignal },\n) {\n const reader = readable.getReader();\n let aborted = false;\n\n const signal = options?.signal;\n const onAbort = () => {\n aborted = true;\n const reason =\n signal?.reason ??\n new DOMException(\"The operation was aborted.\", \"AbortError\");\n void reader.cancel(reason).catch(() => {\n // ignore cancel errors when aborting\n });\n\n if (\"destroy\" in output && typeof output.destroy === \"function\") {\n output.destroy(reason as Error);\n return;\n }\n\n output.emit(\"error\", reason);\n output.end();\n };\n\n if (signal) {\n if (signal.aborted) {\n onAbort();\n } else {\n signal.addEventListener(\"abort\", onAbort, { once: true });\n }\n }\n\n try {\n while (true) {\n const read = await reader.read();\n if (read.value) {\n output.write(Buffer.from(read.value));\n }\n if (read.done) {\n break;\n }\n }\n } catch (err) {\n if (!aborted) {\n output.emit(\"error\", err);\n }\n } finally {\n signal?.removeEventListener(\"abort\", onAbort);\n if (!aborted) {\n output.end();\n }\n }\n}\n\nfunction mergeSignals(...signals: [AbortSignal, ...AbortSignal[]]) {\n const controller = new AbortController();\n const onAbort = () => {\n controller.abort();\n for (const signal of signals) {\n signal.removeEventListener(\"abort\", onAbort);\n }\n };\n for (const signal of signals) {\n if (signal.aborted) {\n controller.abort();\n break;\n }\n signal.addEventListener(\"abort\", onAbort);\n }\n return controller.signal;\n}\n\nfunction toTagsFilter(\n tags: Record<string, string> | undefined,\n): string[] | undefined {\n if (tags === undefined) return undefined;\n const entries = Object.entries(tags);\n if (entries.length === 0) return undefined;\n return entries.map(([key, value]) => `${key}:${value}`);\n}\n"],"mappings":"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"}