@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.
- package/README.md +5 -0
- package/dist/api-client/api-client.js +7 -0
- package/dist/api-client/api-client.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/utils/get-credentials.js +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -1
- package/.turbo/turbo-build.log +0 -4
- package/.turbo/turbo-test.log +0 -24
- package/.turbo/turbo-typecheck.log +0 -4
- package/CHANGELOG.md +0 -277
- package/__mocks__/picocolors.ts +0 -13
- package/scripts/inject-version.ts +0 -11
- package/src/api-client/api-client.test.ts +0 -228
- package/src/api-client/api-client.ts +0 -592
- package/src/api-client/api-error.ts +0 -46
- package/src/api-client/base-client.ts +0 -171
- package/src/api-client/file-writer.ts +0 -90
- package/src/api-client/index.ts +0 -2
- package/src/api-client/validators.ts +0 -146
- package/src/api-client/with-retry.ts +0 -131
- package/src/auth/api.ts +0 -31
- package/src/auth/error.ts +0 -8
- package/src/auth/file.ts +0 -69
- package/src/auth/index.ts +0 -9
- package/src/auth/infer-scope.test.ts +0 -178
- package/src/auth/linked-project.test.ts +0 -86
- package/src/auth/linked-project.ts +0 -40
- package/src/auth/oauth.ts +0 -333
- package/src/auth/poll-for-token.ts +0 -89
- package/src/auth/project.ts +0 -92
- package/src/auth/zod.ts +0 -16
- package/src/command.test.ts +0 -103
- package/src/command.ts +0 -287
- package/src/constants.ts +0 -1
- package/src/index.ts +0 -4
- package/src/sandbox.test.ts +0 -171
- package/src/sandbox.ts +0 -677
- package/src/snapshot.ts +0 -110
- package/src/utils/array.ts +0 -15
- package/src/utils/consume-readable.ts +0 -12
- package/src/utils/decode-base64-url.ts +0 -14
- package/src/utils/dev-credentials.test.ts +0 -217
- package/src/utils/dev-credentials.ts +0 -196
- package/src/utils/get-credentials.test.ts +0 -20
- package/src/utils/get-credentials.ts +0 -183
- package/src/utils/jwt-expiry.test.ts +0 -125
- package/src/utils/jwt-expiry.ts +0 -105
- package/src/utils/log.ts +0 -20
- package/src/utils/normalizePath.test.ts +0 -114
- package/src/utils/normalizePath.ts +0 -33
- package/src/utils/resolveSignal.ts +0 -24
- package/src/utils/types.test.js +0 -7
- package/src/utils/types.ts +0 -23
- package/src/version.ts +0 -2
- package/test-utils/mock-response.ts +0 -12
- package/tsconfig.json +0 -16
- package/turbo.json +0 -9
- package/typedoc.json +0 -13
- package/vercel.json +0 -9
- package/vitest.config.ts +0 -9
- 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
|
-
});
|