@vercel/sandbox 1.2.0 → 1.3.0

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 (65) hide show
  1. package/README.md +5 -0
  2. package/dist/api-client/api-client.js +7 -0
  3. package/dist/api-client/api-client.js.map +1 -1
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +3 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/utils/get-credentials.js +1 -1
  8. package/dist/version.d.ts +1 -1
  9. package/dist/version.js +1 -1
  10. package/package.json +6 -1
  11. package/.turbo/turbo-build.log +0 -4
  12. package/.turbo/turbo-test.log +0 -24
  13. package/.turbo/turbo-typecheck.log +0 -4
  14. package/CHANGELOG.md +0 -277
  15. package/__mocks__/picocolors.ts +0 -13
  16. package/scripts/inject-version.ts +0 -11
  17. package/src/api-client/api-client.test.ts +0 -228
  18. package/src/api-client/api-client.ts +0 -592
  19. package/src/api-client/api-error.ts +0 -46
  20. package/src/api-client/base-client.ts +0 -171
  21. package/src/api-client/file-writer.ts +0 -90
  22. package/src/api-client/index.ts +0 -2
  23. package/src/api-client/validators.ts +0 -146
  24. package/src/api-client/with-retry.ts +0 -131
  25. package/src/auth/api.ts +0 -31
  26. package/src/auth/error.ts +0 -8
  27. package/src/auth/file.ts +0 -69
  28. package/src/auth/index.ts +0 -9
  29. package/src/auth/infer-scope.test.ts +0 -178
  30. package/src/auth/linked-project.test.ts +0 -86
  31. package/src/auth/linked-project.ts +0 -40
  32. package/src/auth/oauth.ts +0 -333
  33. package/src/auth/poll-for-token.ts +0 -89
  34. package/src/auth/project.ts +0 -92
  35. package/src/auth/zod.ts +0 -16
  36. package/src/command.test.ts +0 -103
  37. package/src/command.ts +0 -287
  38. package/src/constants.ts +0 -1
  39. package/src/index.ts +0 -4
  40. package/src/sandbox.test.ts +0 -171
  41. package/src/sandbox.ts +0 -677
  42. package/src/snapshot.ts +0 -110
  43. package/src/utils/array.ts +0 -15
  44. package/src/utils/consume-readable.ts +0 -12
  45. package/src/utils/decode-base64-url.ts +0 -14
  46. package/src/utils/dev-credentials.test.ts +0 -217
  47. package/src/utils/dev-credentials.ts +0 -196
  48. package/src/utils/get-credentials.test.ts +0 -20
  49. package/src/utils/get-credentials.ts +0 -183
  50. package/src/utils/jwt-expiry.test.ts +0 -125
  51. package/src/utils/jwt-expiry.ts +0 -105
  52. package/src/utils/log.ts +0 -20
  53. package/src/utils/normalizePath.test.ts +0 -114
  54. package/src/utils/normalizePath.ts +0 -33
  55. package/src/utils/resolveSignal.ts +0 -24
  56. package/src/utils/types.test.js +0 -7
  57. package/src/utils/types.ts +0 -23
  58. package/src/version.ts +0 -2
  59. package/test-utils/mock-response.ts +0 -12
  60. package/tsconfig.json +0 -16
  61. package/turbo.json +0 -9
  62. package/typedoc.json +0 -13
  63. package/vercel.json +0 -9
  64. package/vitest.config.ts +0 -9
  65. package/vitest.setup.ts +0 -4
@@ -1,228 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from "vitest";
2
- import { APIClient } from "./api-client";
3
- import { APIError, StreamError } from "./api-error";
4
- import { createNdjsonStream } from "../../test-utils/mock-response";
5
-
6
- describe("APIClient", () => {
7
- describe("getLogs", () => {
8
- let client: APIClient;
9
- let mockFetch: ReturnType<typeof vi.fn>;
10
-
11
- beforeEach(() => {
12
- mockFetch = vi.fn();
13
- client = new APIClient({
14
- teamId: "team_123",
15
- token: "1234",
16
- fetch: mockFetch,
17
- });
18
- });
19
-
20
- it("yields stdout log lines", async () => {
21
- const logLines = [
22
- { stream: "stdout", data: "hello" },
23
- { stream: "stdout", data: "world" },
24
- ];
25
-
26
- mockFetch.mockResolvedValue(
27
- new Response(createNdjsonStream(logLines), {
28
- headers: { "content-type": "application/x-ndjson" },
29
- }),
30
- );
31
-
32
- const logs = client.getLogs({ sandboxId: "sbx_123", cmdId: "cmd_456" });
33
- const results: Array<{ stream: string; data: string }> = [];
34
-
35
- for await (const log of logs) {
36
- results.push(log);
37
- }
38
-
39
- expect(results).toHaveLength(2);
40
- expect(results[0]).toEqual({ stream: "stdout", data: "hello" });
41
- expect(results[1]).toEqual({ stream: "stdout", data: "world" });
42
- });
43
-
44
- it("yields stderr log lines", async () => {
45
- const logLines = [{ stream: "stderr", data: "Error" }];
46
-
47
- mockFetch.mockResolvedValue(
48
- new Response(createNdjsonStream(logLines), {
49
- headers: { "content-type": "application/x-ndjson" },
50
- }),
51
- );
52
-
53
- const logs = client.getLogs({ sandboxId: "sbx_123", cmdId: "cmd_456" });
54
- const results: Array<{ stream: string; data: string }> = [];
55
-
56
- for await (const log of logs) {
57
- results.push(log);
58
- }
59
-
60
- expect(results).toHaveLength(1);
61
- expect(results[0]).toEqual({
62
- stream: "stderr",
63
- data: "Error",
64
- });
65
- });
66
-
67
- it("throws APIError when content-type is not application/x-ndjson", async () => {
68
- mockFetch.mockResolvedValue(
69
- new Response(null, {
70
- headers: { "content-type": "application/json" },
71
- }),
72
- );
73
-
74
- const logs = client.getLogs({ sandboxId: "sbx_123", cmdId: "cmd_456" });
75
-
76
- await expect(async () => {
77
- for await (const _ of logs) {
78
- }
79
- }).rejects.toThrow(APIError);
80
- });
81
-
82
- it("throws APIError when response body is null", async () => {
83
- mockFetch.mockResolvedValue(
84
- new Response(null, {
85
- headers: { "content-type": "application/x-ndjson" },
86
- }),
87
- );
88
-
89
- const logs = client.getLogs({ sandboxId: "sbx_123", cmdId: "cmd_456" });
90
-
91
- await expect(async () => {
92
- for await (const _ of logs) {
93
- }
94
- }).rejects.toThrow(APIError);
95
- });
96
-
97
- it("throws StreamError when error log line is received", async () => {
98
- const logLines = [
99
- { stream: "stdout", data: "some logs" },
100
- {
101
- stream: "error",
102
- data: {
103
- code: "sandbox_stream_closed",
104
- message: "Sandbox stream was closed and is not accepting commands.",
105
- },
106
- },
107
- ];
108
-
109
- mockFetch.mockResolvedValue(
110
- new Response(createNdjsonStream(logLines), {
111
- headers: { "content-type": "application/x-ndjson" },
112
- }),
113
- );
114
-
115
- const logs = client.getLogs({ sandboxId: "sbx_123", cmdId: "cmd_456" });
116
- const results: Array<{ stream: string; data: string }> = [];
117
-
118
- await expect(async () => {
119
- for await (const log of logs) {
120
- results.push(log);
121
- }
122
- }).rejects.toThrow(StreamError);
123
-
124
- expect(results).toHaveLength(1);
125
- expect(results[0]).toEqual({ stream: "stdout", data: "some logs" });
126
- });
127
-
128
- it("includes sandboxId in APIError", async () => {
129
- mockFetch.mockResolvedValue(
130
- new Response(null, {
131
- headers: { "content-type": "application/json" },
132
- }),
133
- );
134
-
135
- const logs = client.getLogs({ sandboxId: "sbx_123", cmdId: "cmd_456" });
136
-
137
- try {
138
- for await (const _ of logs) {
139
- }
140
- expect.fail("Expected APIError to be thrown");
141
- } catch (err) {
142
- expect(err).toBeInstanceOf(APIError);
143
- expect((err as APIError<unknown>).sandboxId).toBe("sbx_123");
144
- }
145
- });
146
-
147
- it("includes sandboxId in StreamError", async () => {
148
- const logLines = [
149
- {
150
- stream: "error",
151
- data: {
152
- code: "sandbox_stopped",
153
- message: "Sandbox has stopped",
154
- },
155
- },
156
- ];
157
-
158
- mockFetch.mockResolvedValue(
159
- new Response(createNdjsonStream(logLines), {
160
- headers: { "content-type": "application/x-ndjson" },
161
- }),
162
- );
163
-
164
- const logs = client.getLogs({ sandboxId: "sbx_123", cmdId: "cmd_456" });
165
-
166
- try {
167
- for await (const _ of logs) {
168
- }
169
- expect.fail("Expected StreamError to be thrown");
170
- } catch (err) {
171
- expect(err).toBeInstanceOf(StreamError);
172
- expect((err as StreamError).sandboxId).toBe("sbx_123");
173
- }
174
- });
175
- });
176
-
177
- describe("runCommand", () => {
178
- let client: APIClient;
179
- let mockFetch: ReturnType<typeof vi.fn>;
180
-
181
- beforeEach(() => {
182
- mockFetch = vi.fn();
183
- client = new APIClient({
184
- teamId: "team_123",
185
- token: "1234",
186
- fetch: mockFetch,
187
- });
188
- });
189
-
190
- it("streams command data when wait is true", async () => {
191
- const first = {
192
- command: {
193
- id: "cmd_123",
194
- name: "echo",
195
- args: ["hello"],
196
- cwd: "/",
197
- sandboxId: "sbx_123",
198
- exitCode: null,
199
- startedAt: 1,
200
- },
201
- };
202
- const second = {
203
- command: {
204
- ...first.command,
205
- exitCode: 0,
206
- },
207
- };
208
-
209
- mockFetch.mockResolvedValue(
210
- new Response(createNdjsonStream([first, second]), {
211
- headers: { "content-type": "application/x-ndjson" },
212
- }),
213
- );
214
-
215
- const result = await client.runCommand({
216
- sandboxId: "sbx_123",
217
- command: "echo",
218
- args: ["hello"],
219
- env: {},
220
- sudo: false,
221
- wait: true,
222
- });
223
-
224
- expect(result.command.exitCode).toBeNull();
225
- await expect(result.finished).resolves.toMatchObject({ exitCode: 0 });
226
- });
227
- });
228
- });