@vercel/sandbox 1.2.0 → 1.2.1
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/dist/api-client/api-client.js +7 -0
- package/dist/api-client/api-client.js.map +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
package/src/sandbox.test.ts
DELETED
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { it, beforeEach, afterEach, expect, describe } from "vitest";
|
|
2
|
-
import { consumeReadable } from "./utils/consume-readable";
|
|
3
|
-
import { Sandbox } from "./sandbox";
|
|
4
|
-
import { APIError } from "./api-client/api-error";
|
|
5
|
-
import { mkdtemp, readFile, rm } from "fs/promises";
|
|
6
|
-
import { tmpdir } from "os";
|
|
7
|
-
import { join, resolve } from "path";
|
|
8
|
-
import ms from "ms";
|
|
9
|
-
|
|
10
|
-
describe.skipIf(process.env.RUN_INTEGRATION_TESTS !== "1")("Sandbox", () => {
|
|
11
|
-
const PORTS = [3000, 4000];
|
|
12
|
-
let sandbox: Sandbox;
|
|
13
|
-
|
|
14
|
-
beforeEach(async () => {
|
|
15
|
-
sandbox = await Sandbox.create({ ports: PORTS });
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
afterEach(async () => {
|
|
19
|
-
await sandbox.stop();
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it("allows to write files and then read them as a stream", async () => {
|
|
23
|
-
await sandbox.writeFiles([
|
|
24
|
-
{ path: "hello1.txt", content: Buffer.from("Hello 1") },
|
|
25
|
-
{ path: "hello2.txt", content: Buffer.from("Hello 2") },
|
|
26
|
-
]);
|
|
27
|
-
|
|
28
|
-
const content1 = await sandbox.readFile({ path: "hello1.txt" });
|
|
29
|
-
const content2 = await sandbox.readFile({ path: "hello2.txt" });
|
|
30
|
-
expect((await consumeReadable(content1!)).toString()).toBe("Hello 1");
|
|
31
|
-
expect((await consumeReadable(content2!)).toString()).toBe("Hello 2");
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it("allows to write files and then read them to a buffer", async () => {
|
|
35
|
-
await sandbox.writeFiles([
|
|
36
|
-
{ path: "hello1.txt", content: Buffer.from("Hello 1") },
|
|
37
|
-
{ path: "hello2.txt", content: Buffer.from("Hello 2") },
|
|
38
|
-
]);
|
|
39
|
-
|
|
40
|
-
const content1 = await sandbox.readFileToBuffer({ path: "hello1.txt" });
|
|
41
|
-
const content2 = await sandbox.readFileToBuffer({ path: "hello2.txt" });
|
|
42
|
-
expect(content1?.toString()).toBe("Hello 1");
|
|
43
|
-
expect(content2?.toString()).toBe("Hello 2");
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it("returns null when reading a non-existent file to buffer", async () => {
|
|
47
|
-
const content = await sandbox.readFileToBuffer({
|
|
48
|
-
path: "non-existent.txt",
|
|
49
|
-
});
|
|
50
|
-
expect(content).toBeNull();
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it("allows downloading a file from the sandbox", async () => {
|
|
54
|
-
const fileContent = "Hello from sandbox";
|
|
55
|
-
await sandbox.writeFiles([
|
|
56
|
-
{ path: "download-test.txt", content: Buffer.from(fileContent) },
|
|
57
|
-
]);
|
|
58
|
-
|
|
59
|
-
const tmpDir = await mkdtemp(join(tmpdir(), "sandbox-test-"));
|
|
60
|
-
|
|
61
|
-
try {
|
|
62
|
-
const result = await sandbox.downloadFile(
|
|
63
|
-
{ path: "download-test.txt" },
|
|
64
|
-
{ path: "downloaded.txt", cwd: tmpDir },
|
|
65
|
-
);
|
|
66
|
-
expect(result).toBe(resolve(tmpDir, "downloaded.txt"));
|
|
67
|
-
expect(await readFile(result!, "utf-8")).toBe(fileContent);
|
|
68
|
-
} finally {
|
|
69
|
-
await rm(tmpDir, { recursive: true });
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it("returns null when downloading a non-existent file", async () => {
|
|
74
|
-
const tmpDir = await mkdtemp(join(tmpdir(), "sandbox-test-"));
|
|
75
|
-
|
|
76
|
-
try {
|
|
77
|
-
const result = await sandbox.downloadFile(
|
|
78
|
-
{ path: "non-existent.txt" },
|
|
79
|
-
{ path: "should-not-exist.txt", cwd: tmpDir },
|
|
80
|
-
);
|
|
81
|
-
expect(result).toBeNull();
|
|
82
|
-
} finally {
|
|
83
|
-
await rm(tmpDir, { recursive: true });
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it("creates parent directories when mkdirRecursive is true", async () => {
|
|
88
|
-
const fileContent = "Hello from sandbox";
|
|
89
|
-
await sandbox.writeFiles([
|
|
90
|
-
{ path: "download-test.txt", content: Buffer.from(fileContent) },
|
|
91
|
-
]);
|
|
92
|
-
|
|
93
|
-
const tmpDir = await mkdtemp(join(tmpdir(), "sandbox-test-"));
|
|
94
|
-
const nestedPath = join(tmpDir, "nested", "dir", "downloaded.txt");
|
|
95
|
-
|
|
96
|
-
try {
|
|
97
|
-
const result = await sandbox.downloadFile(
|
|
98
|
-
{ path: "download-test.txt" },
|
|
99
|
-
{ path: nestedPath },
|
|
100
|
-
{ mkdirRecursive: true },
|
|
101
|
-
);
|
|
102
|
-
expect(result).toBe(nestedPath);
|
|
103
|
-
expect(await readFile(result!, "utf-8")).toBe(fileContent);
|
|
104
|
-
} finally {
|
|
105
|
-
await rm(tmpDir, { recursive: true });
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it("verifies port forwarding works correctly", async () => {
|
|
110
|
-
const serverScript = `
|
|
111
|
-
const http = require('http');
|
|
112
|
-
const ports = process.argv.slice(2);
|
|
113
|
-
|
|
114
|
-
for (const port of ports) {
|
|
115
|
-
const server = http.createServer((req, res) => {
|
|
116
|
-
res.writeHead(200, { 'Content-Type': 'text/plain' });
|
|
117
|
-
res.end(\`hello port \${port}\`);
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
server.listen(port, () => {
|
|
121
|
-
console.log(\`Server running on port \${port}\`);
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
`;
|
|
125
|
-
|
|
126
|
-
await sandbox.writeFiles([
|
|
127
|
-
{ path: "server.js", content: Buffer.from(serverScript) },
|
|
128
|
-
]);
|
|
129
|
-
|
|
130
|
-
const server = await sandbox.runCommand({
|
|
131
|
-
cmd: "node",
|
|
132
|
-
args: ["server.js", ...PORTS.map(String)],
|
|
133
|
-
detached: true,
|
|
134
|
-
stdout: process.stdout,
|
|
135
|
-
stderr: process.stderr,
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
139
|
-
|
|
140
|
-
for (const port of PORTS) {
|
|
141
|
-
const response = await fetch(sandbox.domain(port));
|
|
142
|
-
const text = await response.text();
|
|
143
|
-
expect(text).toBe(`hello port ${port}`);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
await server.kill();
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
it("allows extending the sandbox timeout", async () => {
|
|
150
|
-
const originalTimeout = sandbox.timeout;
|
|
151
|
-
const extensionDuration = ms("5m");
|
|
152
|
-
|
|
153
|
-
await sandbox.extendTimeout(extensionDuration);
|
|
154
|
-
expect(sandbox.timeout).toEqual(originalTimeout + extensionDuration);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
it("raises an error when the timeout cannot be updated", async () => {
|
|
158
|
-
try {
|
|
159
|
-
await sandbox.extendTimeout(ms("5d"));
|
|
160
|
-
expect.fail("Expected extendTimeout to throw an error");
|
|
161
|
-
} catch (error) {
|
|
162
|
-
expect(error).toBeInstanceOf(APIError);
|
|
163
|
-
expect(error).toMatchObject({
|
|
164
|
-
response: { status: 400 },
|
|
165
|
-
json: {
|
|
166
|
-
error: { code: "sandbox_timeout_invalid" },
|
|
167
|
-
},
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
});
|