@vercel/sandbox 0.0.4 → 0.0.6
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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-typecheck.log +1 -1
- package/CHANGELOG.md +16 -0
- package/README.md +3 -1
- package/dist/{client/client.d.ts → api-client/api-client.d.ts} +31 -17
- package/dist/{client/client.js → api-client/api-client.js} +50 -44
- package/dist/{client → api-client}/base-client.d.ts +1 -1
- package/dist/{client → api-client}/base-client.js +3 -3
- package/dist/api-client/index.d.ts +1 -0
- package/dist/api-client/index.js +5 -0
- package/dist/{client → api-client}/validators.d.ts +20 -1
- package/dist/{client → api-client}/validators.js +9 -2
- package/dist/command.d.ts +127 -0
- package/dist/command.js +137 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -7
- package/dist/sandbox.d.ts +201 -0
- package/dist/sandbox.js +174 -0
- package/dist/utils/decode-base64-url.d.ts +7 -0
- package/dist/utils/decode-base64-url.js +12 -0
- package/dist/utils/get-credentials.d.ts +26 -0
- package/dist/utils/get-credentials.js +84 -0
- package/dist/utils/get-vercel-oidc-token.d.ts +6 -0
- package/dist/utils/get-vercel-oidc-token.js +21 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +10 -3
- package/src/api-client/api-client.ts +225 -0
- package/src/{client → api-client}/base-client.ts +1 -1
- package/src/api-client/index.ts +1 -0
- package/src/{client → api-client}/validators.ts +9 -1
- package/src/command.test.ts +51 -0
- package/src/command.ts +176 -0
- package/src/index.ts +2 -2
- package/src/sandbox.ts +309 -0
- package/src/utils/decode-base64-url.ts +14 -0
- package/src/utils/get-credentials.ts +113 -0
- package/src/utils/get-vercel-oidc-token.ts +31 -0
- package/src/version.ts +1 -1
- package/tsconfig.json +2 -1
- package/typedoc.json +7 -1
- package/vitest.config.ts +8 -0
- package/vitest.setup.ts +4 -0
- package/dist/create-sandbox.d.ts +0 -196
- package/dist/create-sandbox.js +0 -230
- package/dist/utils/deferred-generator.d.ts +0 -5
- package/dist/utils/deferred-generator.js +0 -32
- package/dist/utils/deferred.d.ts +0 -6
- package/dist/utils/deferred.js +0 -12
- package/src/client/client.ts +0 -186
- package/src/create-sandbox.ts +0 -294
- package/src/utils/deferred-generator.ts +0 -38
- package/src/utils/deferred.ts +0 -12
- /package/dist/{client → api-client}/api-error.d.ts +0 -0
- /package/dist/{client → api-client}/api-error.js +0 -0
- /package/dist/{client → api-client}/with-retry.d.ts +0 -0
- /package/dist/{client → api-client}/with-retry.js +0 -0
- /package/src/{client → api-client}/api-error.ts +0 -0
- /package/src/{client → api-client}/with-retry.ts +0 -0
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @vercel/sandbox
|
|
2
2
|
|
|
3
|
+
## 0.0.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Better types for `Command` allowing a shorcut for waiting ([#29](https://github.com/vercel/sandbox-sdk/pull/29))
|
|
8
|
+
|
|
9
|
+
- Remove `SDK` and simplify API surface ([#38](https://github.com/vercel/sandbox-sdk/pull/38))
|
|
10
|
+
|
|
11
|
+
## 0.0.5
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- Allow specifying env vars and cwd when running commands ([#25](https://github.com/vercel/sandbox-sdk/pull/25))
|
|
16
|
+
|
|
17
|
+
- createSandbox: do not require ports to be specified ([#27](https://github.com/vercel/sandbox-sdk/pull/27))
|
|
18
|
+
|
|
3
19
|
## 0.0.4
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@ Vercel Sandbox is in private beta. These examples will not work unless these
|
|
|
13
13
|
APIs are enabled for your team.
|
|
14
14
|
|
|
15
15
|
- Go to your team settings, and copy the team ID.
|
|
16
|
+
- Go to a project's settings, and copy the project ID.
|
|
16
17
|
- Go to your Vercel account settings and [create a token][create-token]. Make
|
|
17
18
|
sure it is scoped to the team ID from the previous step.
|
|
18
19
|
- Create a new project:
|
|
@@ -22,6 +23,7 @@ mkdir sandbox-test
|
|
|
22
23
|
cd sandbox-test
|
|
23
24
|
pnpm init
|
|
24
25
|
pnpm add @vercel/sandbox ms
|
|
26
|
+
pnpm add -D @types/ms @types/node
|
|
25
27
|
```
|
|
26
28
|
|
|
27
29
|
Now create `next-dev.ts`:
|
|
@@ -31,7 +33,7 @@ Now create `next-dev.ts`:
|
|
|
31
33
|
Run it like this:
|
|
32
34
|
|
|
33
35
|
```sh
|
|
34
|
-
VERCEL_TEAM_ID=<team_id> VERCEL_TOKEN=<token> node --experimental-strip-types ./next-dev.ts
|
|
36
|
+
VERCEL_TEAM_ID=<team_id> VERCEL_TOKEN=<token> VERCEL_PROJECT_ID=<project_id> node --experimental-strip-types ./next-dev.ts
|
|
35
37
|
```
|
|
36
38
|
|
|
37
39
|
This will:
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseClient, type Parsed, type RequestParams } from "./base-client";
|
|
2
|
+
import { Command, CommandFinished, LogLine, StoppedSandbox } from "./validators";
|
|
2
3
|
import { Readable } from "stream";
|
|
3
|
-
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
export declare class APIClient extends BaseClient {
|
|
4
6
|
private teamId;
|
|
5
7
|
constructor(params: {
|
|
6
8
|
host?: string;
|
|
@@ -9,14 +11,21 @@ export declare class SandboxClient extends APIClient {
|
|
|
9
11
|
});
|
|
10
12
|
protected request(path: string, params?: RequestParams): Promise<import("node-fetch").Response>;
|
|
11
13
|
createSandbox(params: {
|
|
12
|
-
ports
|
|
14
|
+
ports?: number[];
|
|
13
15
|
projectId: string;
|
|
14
|
-
source
|
|
16
|
+
source?: {
|
|
15
17
|
type: "git";
|
|
16
18
|
url: string;
|
|
19
|
+
} | {
|
|
20
|
+
type: "tarball";
|
|
21
|
+
url: string;
|
|
17
22
|
};
|
|
18
23
|
timeout?: number;
|
|
19
|
-
|
|
24
|
+
resources?: {
|
|
25
|
+
cores: number;
|
|
26
|
+
memory: number;
|
|
27
|
+
};
|
|
28
|
+
}): Promise<Parsed<{
|
|
20
29
|
sandboxId: string;
|
|
21
30
|
routes: {
|
|
22
31
|
port: number;
|
|
@@ -28,20 +37,25 @@ export declare class SandboxClient extends APIClient {
|
|
|
28
37
|
cwd?: string;
|
|
29
38
|
command: string;
|
|
30
39
|
args: string[];
|
|
31
|
-
|
|
40
|
+
env: Record<string, string>;
|
|
41
|
+
}): Promise<Parsed<{
|
|
32
42
|
cmdId: string;
|
|
33
43
|
}>>;
|
|
34
44
|
getCommand(params: {
|
|
35
45
|
sandboxId: string;
|
|
36
46
|
cmdId: string;
|
|
37
|
-
wait
|
|
38
|
-
}): Promise<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
args: string[];
|
|
47
|
+
wait: true;
|
|
48
|
+
}): Promise<Parsed<z.infer<typeof CommandFinished>>>;
|
|
49
|
+
getCommand(params: {
|
|
50
|
+
sandboxId: string;
|
|
42
51
|
cmdId: string;
|
|
43
|
-
|
|
44
|
-
}
|
|
52
|
+
wait?: boolean;
|
|
53
|
+
}): Promise<Parsed<z.infer<typeof Command>>>;
|
|
54
|
+
mkDir(params: {
|
|
55
|
+
sandboxId: string;
|
|
56
|
+
path: string;
|
|
57
|
+
cwd?: string;
|
|
58
|
+
}): Promise<Parsed<{}>>;
|
|
45
59
|
writeFiles(params: {
|
|
46
60
|
sandboxId: string;
|
|
47
61
|
files: {
|
|
@@ -57,8 +71,8 @@ export declare class SandboxClient extends APIClient {
|
|
|
57
71
|
getLogs(params: {
|
|
58
72
|
sandboxId: string;
|
|
59
73
|
cmdId: string;
|
|
60
|
-
}):
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
74
|
+
}): AsyncIterable<z.infer<typeof LogLine>>;
|
|
75
|
+
stopSandbox(params: {
|
|
76
|
+
sandboxId: string;
|
|
77
|
+
}): Promise<Parsed<z.infer<typeof StoppedSandbox>>>;
|
|
64
78
|
}
|
|
@@ -3,16 +3,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.APIClient = void 0;
|
|
7
7
|
const form_data_1 = __importDefault(require("form-data"));
|
|
8
8
|
const base_client_1 = require("./base-client");
|
|
9
9
|
const validators_1 = require("./validators");
|
|
10
10
|
const api_error_1 = require("./api-error");
|
|
11
|
-
const
|
|
11
|
+
const lru_cache_1 = require("lru-cache");
|
|
12
12
|
const version_1 = require("../version");
|
|
13
13
|
const jsonlines_1 = __importDefault(require("jsonlines"));
|
|
14
14
|
const os_1 = __importDefault(require("os"));
|
|
15
|
-
|
|
15
|
+
const ms_1 = __importDefault(require("ms"));
|
|
16
|
+
/**
|
|
17
|
+
* Allows to track the logs hits for a command un a to maximum of items and
|
|
18
|
+
* TTL so that we don't incur in memory leaks in a log running process.
|
|
19
|
+
*/
|
|
20
|
+
const logHits = new lru_cache_1.LRUCache({
|
|
21
|
+
ttl: (0, ms_1.default)("45m"),
|
|
22
|
+
max: 1000,
|
|
23
|
+
});
|
|
24
|
+
class APIClient extends base_client_1.BaseClient {
|
|
16
25
|
constructor(params) {
|
|
17
26
|
super({
|
|
18
27
|
host: params.host ?? "https://api.vercel.com",
|
|
@@ -40,6 +49,7 @@ class SandboxClient extends base_client_1.APIClient {
|
|
|
40
49
|
ports: params.ports,
|
|
41
50
|
source: params.source,
|
|
42
51
|
timeout: params.timeout,
|
|
52
|
+
resources: params.resources,
|
|
43
53
|
}),
|
|
44
54
|
}));
|
|
45
55
|
}
|
|
@@ -50,11 +60,20 @@ class SandboxClient extends base_client_1.APIClient {
|
|
|
50
60
|
command: params.command,
|
|
51
61
|
args: params.args,
|
|
52
62
|
cwd: params.cwd,
|
|
63
|
+
env: params.env,
|
|
53
64
|
}),
|
|
54
65
|
}));
|
|
55
66
|
}
|
|
56
67
|
async getCommand(params) {
|
|
57
|
-
return
|
|
68
|
+
return params.wait
|
|
69
|
+
? (0, base_client_1.parseOrThrow)(validators_1.CommandFinished, await this.request(`/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}`, { query: { wait: "true" } }))
|
|
70
|
+
: (0, base_client_1.parseOrThrow)(validators_1.Command, await this.request(`/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}`));
|
|
71
|
+
}
|
|
72
|
+
async mkDir(params) {
|
|
73
|
+
return (0, base_client_1.parseOrThrow)(validators_1.WrittenFile, await this.request(`/v1/sandboxes/${params.sandboxId}/fs/mkdir`, {
|
|
74
|
+
method: "POST",
|
|
75
|
+
body: JSON.stringify({ path: params.path, cwd: params.cwd }),
|
|
76
|
+
}));
|
|
58
77
|
}
|
|
59
78
|
async writeFiles(params) {
|
|
60
79
|
const formData = new form_data_1.default();
|
|
@@ -77,46 +96,33 @@ class SandboxClient extends base_client_1.APIClient {
|
|
|
77
96
|
}
|
|
78
97
|
return response.body;
|
|
79
98
|
}
|
|
80
|
-
getLogs(params) {
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
message: "Expected a stream of logs",
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
const parser = jsonlines_1.default.parse();
|
|
90
|
-
response.body.pipe(parser);
|
|
91
|
-
parser.on("data", (data) => {
|
|
92
|
-
const parsed = validators_1.LogLine.safeParse(data);
|
|
93
|
-
if (parsed.success) {
|
|
94
|
-
deferred.next({
|
|
95
|
-
value: parsed.data,
|
|
96
|
-
done: false,
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
else {
|
|
100
|
-
deferred.next({
|
|
101
|
-
value: Promise.reject(parsed.error),
|
|
102
|
-
done: false,
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
parser.on("error", (err) => {
|
|
107
|
-
deferred.next({
|
|
108
|
-
value: Promise.reject(err),
|
|
109
|
-
done: false,
|
|
110
|
-
});
|
|
99
|
+
async *getLogs(params) {
|
|
100
|
+
const url = `/v1/sandboxes/${params.sandboxId}/cmd/${params.cmdId}/logs`;
|
|
101
|
+
const response = await this.request(url, { method: "GET" });
|
|
102
|
+
if (response.headers.get("content-type") !== "application/x-ndjson") {
|
|
103
|
+
throw new api_error_1.APIError(response, {
|
|
104
|
+
message: "Expected a stream of logs",
|
|
111
105
|
});
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Currently, once we consume logs in the backend we cannot read them
|
|
109
|
+
* again. This logic writes a warning when the endpoint for a command
|
|
110
|
+
* logs is consumed more than once to alert the user about this.
|
|
111
|
+
*
|
|
112
|
+
* This is a temporary solution, we should be able to handle this in
|
|
113
|
+
* the backend in the future.
|
|
114
|
+
*/
|
|
115
|
+
if (logHits.get(url)) {
|
|
116
|
+
console.warn(`Multiple consumers for logs of command \`${params.cmdId}\`. This may lead to unexpected behavior.`);
|
|
117
|
+
}
|
|
118
|
+
logHits.set(url, true);
|
|
119
|
+
for await (const chunk of response.body.pipe(jsonlines_1.default.parse())) {
|
|
120
|
+
yield validators_1.LogLine.parse(chunk);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async stopSandbox(params) {
|
|
124
|
+
const url = `/v1/sandboxes/${params.sandboxId}/stop`;
|
|
125
|
+
return (0, base_client_1.parseOrThrow)(validators_1.StoppedSandbox, await this.request(url, { method: "POST" }));
|
|
120
126
|
}
|
|
121
127
|
}
|
|
122
|
-
exports.
|
|
128
|
+
exports.APIClient = APIClient;
|
|
@@ -15,7 +15,7 @@ export interface RequestParams extends RequestInit {
|
|
|
15
15
|
* we can pass query parameters as an object, support retries, debugging
|
|
16
16
|
* and automatic authorization.
|
|
17
17
|
*/
|
|
18
|
-
export declare class
|
|
18
|
+
export declare class BaseClient {
|
|
19
19
|
protected token?: string;
|
|
20
20
|
private fetch;
|
|
21
21
|
private debug;
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.BaseClient = void 0;
|
|
7
7
|
exports.parse = parse;
|
|
8
8
|
exports.parseOrThrow = parseOrThrow;
|
|
9
9
|
const api_error_1 = require("./api-error");
|
|
@@ -15,7 +15,7 @@ const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
|
15
15
|
* we can pass query parameters as an object, support retries, debugging
|
|
16
16
|
* and automatic authorization.
|
|
17
17
|
*/
|
|
18
|
-
class
|
|
18
|
+
class BaseClient {
|
|
19
19
|
constructor(params) {
|
|
20
20
|
this.fetch = (0, with_retry_1.withRetry)(node_fetch_1.default);
|
|
21
21
|
this.host = params.host;
|
|
@@ -54,7 +54,7 @@ class APIClient {
|
|
|
54
54
|
return response;
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
|
-
exports.
|
|
57
|
+
exports.BaseClient = BaseClient;
|
|
58
58
|
/**
|
|
59
59
|
* Allows to read the response text and parse it as JSON casting to the given
|
|
60
60
|
* type. If the response is not ok or cannot be parsed it will return error.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { APIClient } from "./api-client";
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.APIClient = void 0;
|
|
4
|
+
var api_client_1 = require("./api-client");
|
|
5
|
+
Object.defineProperty(exports, "APIClient", { enumerable: true, get: function () { return api_client_1.APIClient; } });
|
|
@@ -50,14 +50,33 @@ export declare const Command: z.ZodObject<{
|
|
|
50
50
|
cmdId: string;
|
|
51
51
|
exitCode: number | null;
|
|
52
52
|
}>;
|
|
53
|
-
export declare const
|
|
53
|
+
export declare const CommandFinished: z.ZodObject<{
|
|
54
|
+
args: z.ZodArray<z.ZodString, "many">;
|
|
54
55
|
cmdId: z.ZodString;
|
|
56
|
+
cwd: z.ZodString;
|
|
57
|
+
exitCode: z.ZodNumber;
|
|
58
|
+
name: z.ZodString;
|
|
55
59
|
}, "strip", z.ZodTypeAny, {
|
|
60
|
+
name: string;
|
|
61
|
+
cwd: string;
|
|
62
|
+
args: string[];
|
|
56
63
|
cmdId: string;
|
|
64
|
+
exitCode: number;
|
|
57
65
|
}, {
|
|
66
|
+
name: string;
|
|
67
|
+
cwd: string;
|
|
68
|
+
args: string[];
|
|
58
69
|
cmdId: string;
|
|
70
|
+
exitCode: number;
|
|
59
71
|
}>;
|
|
60
72
|
export declare const WrittenFile: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
73
|
+
export declare const StoppedSandbox: z.ZodObject<{
|
|
74
|
+
sandboxId: z.ZodString;
|
|
75
|
+
}, "strip", z.ZodTypeAny, {
|
|
76
|
+
sandboxId: string;
|
|
77
|
+
}, {
|
|
78
|
+
sandboxId: string;
|
|
79
|
+
}>;
|
|
61
80
|
export declare const LogLine: z.ZodObject<{
|
|
62
81
|
stream: z.ZodEnum<["stdout", "stderr"]>;
|
|
63
82
|
data: z.ZodString;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LogLine = exports.WrittenFile = exports.
|
|
3
|
+
exports.LogLine = exports.StoppedSandbox = exports.WrittenFile = exports.CommandFinished = exports.Command = exports.CreatedCommand = exports.CreatedSandbox = void 0;
|
|
4
4
|
const zod_1 = require("zod");
|
|
5
5
|
exports.CreatedSandbox = zod_1.z.object({
|
|
6
6
|
sandboxId: zod_1.z.string(),
|
|
@@ -16,10 +16,17 @@ exports.Command = zod_1.z.object({
|
|
|
16
16
|
exitCode: zod_1.z.number().nullable(),
|
|
17
17
|
name: zod_1.z.string(),
|
|
18
18
|
});
|
|
19
|
-
exports.
|
|
19
|
+
exports.CommandFinished = zod_1.z.object({
|
|
20
|
+
args: zod_1.z.array(zod_1.z.string()),
|
|
20
21
|
cmdId: zod_1.z.string(),
|
|
22
|
+
cwd: zod_1.z.string(),
|
|
23
|
+
exitCode: zod_1.z.number(),
|
|
24
|
+
name: zod_1.z.string(),
|
|
21
25
|
});
|
|
22
26
|
exports.WrittenFile = zod_1.z.object({});
|
|
27
|
+
exports.StoppedSandbox = zod_1.z.object({
|
|
28
|
+
sandboxId: zod_1.z.string(),
|
|
29
|
+
});
|
|
23
30
|
exports.LogLine = zod_1.z.object({
|
|
24
31
|
stream: zod_1.z.enum(["stdout", "stderr"]),
|
|
25
32
|
data: zod_1.z.string(),
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { APIClient } from "./api-client";
|
|
2
|
+
/**
|
|
3
|
+
* A command executed in a Sandbox.
|
|
4
|
+
*
|
|
5
|
+
* You can {@link wait} on commands to access their {@link CommandFinished.exitCode}, and
|
|
6
|
+
* iterate over their output with {@link logs}.
|
|
7
|
+
*
|
|
8
|
+
* @see {@link Sandbox.runCommand} to start a command.
|
|
9
|
+
*
|
|
10
|
+
* @hideconstructor
|
|
11
|
+
*/
|
|
12
|
+
export declare class Command {
|
|
13
|
+
/**
|
|
14
|
+
* @internal
|
|
15
|
+
* @private
|
|
16
|
+
*/
|
|
17
|
+
protected client: APIClient;
|
|
18
|
+
/**
|
|
19
|
+
* ID of the sandbox this command is running in.
|
|
20
|
+
*/
|
|
21
|
+
private sandboxId;
|
|
22
|
+
/**
|
|
23
|
+
* ID of the command execution.
|
|
24
|
+
*/
|
|
25
|
+
cmdId: string;
|
|
26
|
+
/**
|
|
27
|
+
* @param params - Object containing the client, sandbox ID, and command ID.
|
|
28
|
+
* @param params.client - API client used to interact with the backend.
|
|
29
|
+
* @param params.sandboxId - The ID of the sandbox where the command is running.
|
|
30
|
+
* @param params.cmdId - The ID of the command execution.
|
|
31
|
+
*/
|
|
32
|
+
constructor({ client, sandboxId, cmdId, }: {
|
|
33
|
+
client: APIClient;
|
|
34
|
+
sandboxId: string;
|
|
35
|
+
cmdId: string;
|
|
36
|
+
});
|
|
37
|
+
/**
|
|
38
|
+
* Iterate over the output of this command.
|
|
39
|
+
*
|
|
40
|
+
* ```
|
|
41
|
+
* for await (const log of cmd.logs()) {
|
|
42
|
+
* if (log.stream === "stdout") {
|
|
43
|
+
* process.stdout.write(log.data);
|
|
44
|
+
* } else {
|
|
45
|
+
* process.stderr.write(log.data);
|
|
46
|
+
* }
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @returns An async iterable of log entries from the command output.
|
|
51
|
+
*
|
|
52
|
+
* @see {@link Command.stdout}, {@link Command.stderr}, and {@link Command.output}
|
|
53
|
+
* to access output as a string.
|
|
54
|
+
*/
|
|
55
|
+
logs(): AsyncIterable<{
|
|
56
|
+
data: string;
|
|
57
|
+
stream: "stdout" | "stderr";
|
|
58
|
+
}>;
|
|
59
|
+
/**
|
|
60
|
+
* Wait for a command to exit and populate its exit code.
|
|
61
|
+
*
|
|
62
|
+
* ```
|
|
63
|
+
* await cmd.wait()
|
|
64
|
+
* if (cmd.exitCode != 0) {
|
|
65
|
+
* console.error("Something went wrong...")
|
|
66
|
+
* }
|
|
67
|
+
* ```
|
|
68
|
+
*
|
|
69
|
+
* @returns A {@link CommandFinished} instance with populated exit code.
|
|
70
|
+
*/
|
|
71
|
+
wait(): Promise<CommandFinished>;
|
|
72
|
+
/**
|
|
73
|
+
* Get the output of `stdout`, `stderr`, or both as a string.
|
|
74
|
+
*
|
|
75
|
+
* NOTE: This may throw string conversion errors if the command does
|
|
76
|
+
* not output valid Unicode.
|
|
77
|
+
*
|
|
78
|
+
* @param stream - The output stream to read: "stdout", "stderr", or "both".
|
|
79
|
+
* @returns The output of the specified stream(s) as a string.
|
|
80
|
+
*/
|
|
81
|
+
output(stream?: "stdout" | "stderr" | "both"): Promise<string>;
|
|
82
|
+
/**
|
|
83
|
+
* Get the output of `stdout` as a string.
|
|
84
|
+
*
|
|
85
|
+
* NOTE: This may throw string conversion errors if the command does
|
|
86
|
+
* not output valid Unicode.
|
|
87
|
+
*
|
|
88
|
+
* @returns The standard output of the command.
|
|
89
|
+
*/
|
|
90
|
+
stdout(): Promise<string>;
|
|
91
|
+
/**
|
|
92
|
+
* Get the output of `stderr` as a string.
|
|
93
|
+
*
|
|
94
|
+
* NOTE: This may throw string conversion errors if the command does
|
|
95
|
+
* not output valid Unicode.
|
|
96
|
+
*
|
|
97
|
+
* @returns The standard error output of the command.
|
|
98
|
+
*/
|
|
99
|
+
stderr(): Promise<string>;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* A command that has finished executing.
|
|
103
|
+
*
|
|
104
|
+
* Contains the exit code of the command.
|
|
105
|
+
*
|
|
106
|
+
* @hideconstructor
|
|
107
|
+
*/
|
|
108
|
+
export declare class CommandFinished extends Command {
|
|
109
|
+
/**
|
|
110
|
+
* The exit code of the command, if available. This is set after
|
|
111
|
+
* {@link wait} has returned.
|
|
112
|
+
*/
|
|
113
|
+
exitCode: number;
|
|
114
|
+
/**
|
|
115
|
+
* @param params - Object containing client, sandbox ID, command ID, and exit code.
|
|
116
|
+
* @param params.client - API client used to interact with the backend.
|
|
117
|
+
* @param params.sandboxId - The ID of the sandbox where the command ran.
|
|
118
|
+
* @param params.cmdId - The ID of the command execution.
|
|
119
|
+
* @param params.exitCode - The exit code of the completed command.
|
|
120
|
+
*/
|
|
121
|
+
constructor(params: {
|
|
122
|
+
client: APIClient;
|
|
123
|
+
sandboxId: string;
|
|
124
|
+
cmdId: string;
|
|
125
|
+
exitCode: number;
|
|
126
|
+
});
|
|
127
|
+
}
|
package/dist/command.js
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CommandFinished = exports.Command = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* A command executed in a Sandbox.
|
|
6
|
+
*
|
|
7
|
+
* You can {@link wait} on commands to access their {@link CommandFinished.exitCode}, and
|
|
8
|
+
* iterate over their output with {@link logs}.
|
|
9
|
+
*
|
|
10
|
+
* @see {@link Sandbox.runCommand} to start a command.
|
|
11
|
+
*
|
|
12
|
+
* @hideconstructor
|
|
13
|
+
*/
|
|
14
|
+
class Command {
|
|
15
|
+
/**
|
|
16
|
+
* @param params - Object containing the client, sandbox ID, and command ID.
|
|
17
|
+
* @param params.client - API client used to interact with the backend.
|
|
18
|
+
* @param params.sandboxId - The ID of the sandbox where the command is running.
|
|
19
|
+
* @param params.cmdId - The ID of the command execution.
|
|
20
|
+
*/
|
|
21
|
+
constructor({ client, sandboxId, cmdId, }) {
|
|
22
|
+
this.client = client;
|
|
23
|
+
this.sandboxId = sandboxId;
|
|
24
|
+
this.cmdId = cmdId;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Iterate over the output of this command.
|
|
28
|
+
*
|
|
29
|
+
* ```
|
|
30
|
+
* for await (const log of cmd.logs()) {
|
|
31
|
+
* if (log.stream === "stdout") {
|
|
32
|
+
* process.stdout.write(log.data);
|
|
33
|
+
* } else {
|
|
34
|
+
* process.stderr.write(log.data);
|
|
35
|
+
* }
|
|
36
|
+
* }
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @returns An async iterable of log entries from the command output.
|
|
40
|
+
*
|
|
41
|
+
* @see {@link Command.stdout}, {@link Command.stderr}, and {@link Command.output}
|
|
42
|
+
* to access output as a string.
|
|
43
|
+
*/
|
|
44
|
+
logs() {
|
|
45
|
+
return this.client.getLogs({
|
|
46
|
+
sandboxId: this.sandboxId,
|
|
47
|
+
cmdId: this.cmdId,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Wait for a command to exit and populate its exit code.
|
|
52
|
+
*
|
|
53
|
+
* ```
|
|
54
|
+
* await cmd.wait()
|
|
55
|
+
* if (cmd.exitCode != 0) {
|
|
56
|
+
* console.error("Something went wrong...")
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @returns A {@link CommandFinished} instance with populated exit code.
|
|
61
|
+
*/
|
|
62
|
+
async wait() {
|
|
63
|
+
const command = await this.client.getCommand({
|
|
64
|
+
sandboxId: this.sandboxId,
|
|
65
|
+
cmdId: this.cmdId,
|
|
66
|
+
wait: true,
|
|
67
|
+
});
|
|
68
|
+
return new CommandFinished({
|
|
69
|
+
client: this.client,
|
|
70
|
+
sandboxId: this.sandboxId,
|
|
71
|
+
cmdId: command.json.cmdId,
|
|
72
|
+
exitCode: command.json.exitCode,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Get the output of `stdout`, `stderr`, or both as a string.
|
|
77
|
+
*
|
|
78
|
+
* NOTE: This may throw string conversion errors if the command does
|
|
79
|
+
* not output valid Unicode.
|
|
80
|
+
*
|
|
81
|
+
* @param stream - The output stream to read: "stdout", "stderr", or "both".
|
|
82
|
+
* @returns The output of the specified stream(s) as a string.
|
|
83
|
+
*/
|
|
84
|
+
async output(stream = "both") {
|
|
85
|
+
let data = "";
|
|
86
|
+
for await (const log of this.logs()) {
|
|
87
|
+
if (stream === "both" || log.stream === stream) {
|
|
88
|
+
data += log.data;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return data;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Get the output of `stdout` as a string.
|
|
95
|
+
*
|
|
96
|
+
* NOTE: This may throw string conversion errors if the command does
|
|
97
|
+
* not output valid Unicode.
|
|
98
|
+
*
|
|
99
|
+
* @returns The standard output of the command.
|
|
100
|
+
*/
|
|
101
|
+
async stdout() {
|
|
102
|
+
return this.output("stdout");
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get the output of `stderr` as a string.
|
|
106
|
+
*
|
|
107
|
+
* NOTE: This may throw string conversion errors if the command does
|
|
108
|
+
* not output valid Unicode.
|
|
109
|
+
*
|
|
110
|
+
* @returns The standard error output of the command.
|
|
111
|
+
*/
|
|
112
|
+
async stderr() {
|
|
113
|
+
return this.output("stderr");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.Command = Command;
|
|
117
|
+
/**
|
|
118
|
+
* A command that has finished executing.
|
|
119
|
+
*
|
|
120
|
+
* Contains the exit code of the command.
|
|
121
|
+
*
|
|
122
|
+
* @hideconstructor
|
|
123
|
+
*/
|
|
124
|
+
class CommandFinished extends Command {
|
|
125
|
+
/**
|
|
126
|
+
* @param params - Object containing client, sandbox ID, command ID, and exit code.
|
|
127
|
+
* @param params.client - API client used to interact with the backend.
|
|
128
|
+
* @param params.sandboxId - The ID of the sandbox where the command ran.
|
|
129
|
+
* @param params.cmdId - The ID of the command execution.
|
|
130
|
+
* @param params.exitCode - The exit code of the completed command.
|
|
131
|
+
*/
|
|
132
|
+
constructor(params) {
|
|
133
|
+
super({ ...params });
|
|
134
|
+
this.exitCode = params.exitCode;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
exports.CommandFinished = CommandFinished;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
1
|
+
export { Sandbox } from "./sandbox";
|
|
2
|
+
export { Command, CommandFinished } from "./command";
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
var
|
|
5
|
-
Object.defineProperty(exports, "
|
|
6
|
-
|
|
7
|
-
Object.defineProperty(exports, "Command", { enumerable: true, get: function () { return
|
|
8
|
-
|
|
9
|
-
Object.defineProperty(exports, "SandboxClient", { enumerable: true, get: function () { return client_1.SandboxClient; } });
|
|
3
|
+
exports.CommandFinished = exports.Command = exports.Sandbox = void 0;
|
|
4
|
+
var sandbox_1 = require("./sandbox");
|
|
5
|
+
Object.defineProperty(exports, "Sandbox", { enumerable: true, get: function () { return sandbox_1.Sandbox; } });
|
|
6
|
+
var command_1 = require("./command");
|
|
7
|
+
Object.defineProperty(exports, "Command", { enumerable: true, get: function () { return command_1.Command; } });
|
|
8
|
+
Object.defineProperty(exports, "CommandFinished", { enumerable: true, get: function () { return command_1.CommandFinished; } });
|