@watasu/sdk 0.1.30 → 0.1.50
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 +13 -7
- package/dist/codeInterpreter.d.ts +141 -16
- package/dist/codeInterpreter.js +74 -19
- package/dist/commands.d.ts +16 -8
- package/dist/commands.js +17 -16
- package/dist/connectionConfig.d.ts +25 -0
- package/dist/connectionConfig.js +49 -2
- package/dist/errors.d.ts +21 -0
- package/dist/errors.js +54 -4
- package/dist/filesystem.d.ts +20 -20
- package/dist/filesystem.js +51 -12
- package/dist/git.d.ts +6 -4
- package/dist/git.js +7 -3
- package/dist/index.d.ts +22 -10
- package/dist/index.js +7 -5
- package/dist/process.d.ts +1 -1
- package/dist/process.js +11 -7
- package/dist/processSocket.d.ts +17 -4
- package/dist/processSocket.js +112 -8
- package/dist/pty.d.ts +3 -3
- package/dist/pty.js +10 -8
- package/dist/sandbox.d.ts +44 -30
- package/dist/sandbox.js +103 -59
- package/dist/template.d.ts +39 -9
- package/dist/template.js +117 -31
- package/dist/terminal.d.ts +3 -3
- package/dist/terminal.js +7 -4
- package/dist/transport.d.ts +2 -0
- package/dist/transport.js +23 -6
- package/dist/volume.d.ts +15 -8
- package/dist/volume.js +28 -9
- package/package.json +2 -2
|
@@ -1,14 +1,20 @@
|
|
|
1
1
|
export declare const KEEPALIVE_PING_INTERVAL_SEC = 50;
|
|
2
2
|
export declare const SESSION_OPERATION_REQUEST_TIMEOUT_MS = 150000;
|
|
3
|
+
export type Username = string;
|
|
3
4
|
/** Connection options accepted by Watasu SDK entrypoints. */
|
|
4
5
|
export interface ConnectionOpts {
|
|
5
6
|
apiKey?: string;
|
|
6
7
|
accessToken?: string;
|
|
7
8
|
domain?: string;
|
|
8
9
|
apiUrl?: string;
|
|
10
|
+
/** Absolute sandbox data-plane URL override, primarily for local runtimes. */
|
|
11
|
+
sandboxUrl?: string;
|
|
9
12
|
dataPlaneDomain?: string;
|
|
10
13
|
requestTimeoutMs?: number;
|
|
11
14
|
headers?: Record<string, string>;
|
|
15
|
+
apiHeaders?: Record<string, string>;
|
|
16
|
+
debug?: boolean;
|
|
17
|
+
signal?: AbortSignal;
|
|
12
18
|
proxy?: unknown;
|
|
13
19
|
}
|
|
14
20
|
/** Resolved connection settings used by control-plane and data-plane clients. */
|
|
@@ -16,11 +22,30 @@ export declare class ConnectionConfig {
|
|
|
16
22
|
readonly apiKey?: string;
|
|
17
23
|
readonly domain: string;
|
|
18
24
|
readonly apiUrl: string;
|
|
25
|
+
/** Absolute sandbox data-plane URL override, primarily for local runtimes. */
|
|
26
|
+
readonly sandboxUrl?: string;
|
|
19
27
|
readonly dataPlaneDomain: string;
|
|
20
28
|
readonly requestTimeoutMs: number;
|
|
21
29
|
readonly headers: Record<string, string>;
|
|
30
|
+
readonly apiHeaders: Record<string, string>;
|
|
31
|
+
readonly debug: boolean;
|
|
32
|
+
readonly signal?: AbortSignal;
|
|
22
33
|
readonly proxy?: unknown;
|
|
23
34
|
constructor(opts?: ConnectionOpts);
|
|
24
35
|
/** HTTP headers including the configured bearer token. */
|
|
25
36
|
get authHeaders(): Record<string, string>;
|
|
37
|
+
/** Return an abort signal that follows the caller signal and optional timeout. */
|
|
38
|
+
getSignal(requestTimeoutMs?: number, signal?: AbortSignal | undefined): AbortSignal | undefined;
|
|
39
|
+
/** Return the sandbox data-plane API URL for a Watasu route token. */
|
|
40
|
+
getSandboxUrl(sandboxId: string, opts: {
|
|
41
|
+
sandboxDomain?: string;
|
|
42
|
+
envdPort: number;
|
|
43
|
+
}): string;
|
|
44
|
+
/** Return the direct sandbox data-plane API URL for a Watasu route token. */
|
|
45
|
+
getSandboxDirectUrl(sandboxId: string, opts: {
|
|
46
|
+
sandboxDomain?: string;
|
|
47
|
+
envdPort: number;
|
|
48
|
+
}): string;
|
|
49
|
+
/** Return the public hostname for a Watasu sandbox route token and port. */
|
|
50
|
+
getHost(sandboxId: string, port: number, sandboxDomain?: string): string;
|
|
26
51
|
}
|
package/dist/connectionConfig.js
CHANGED
|
@@ -5,9 +5,14 @@ export class ConnectionConfig {
|
|
|
5
5
|
apiKey;
|
|
6
6
|
domain;
|
|
7
7
|
apiUrl;
|
|
8
|
+
/** Absolute sandbox data-plane URL override, primarily for local runtimes. */
|
|
9
|
+
sandboxUrl;
|
|
8
10
|
dataPlaneDomain;
|
|
9
11
|
requestTimeoutMs;
|
|
10
12
|
headers;
|
|
13
|
+
apiHeaders;
|
|
14
|
+
debug;
|
|
15
|
+
signal;
|
|
11
16
|
proxy;
|
|
12
17
|
constructor(opts = {}) {
|
|
13
18
|
const env = typeof process !== 'undefined' ? process.env : {};
|
|
@@ -18,18 +23,60 @@ export class ConnectionConfig {
|
|
|
18
23
|
this.domain = opts.domain ?? env.WATASU_DOMAIN ?? 'watasu.io';
|
|
19
24
|
this.apiUrl =
|
|
20
25
|
opts.apiUrl ?? env.WATASU_API_URL ?? `https://api.${this.domain}/v1`;
|
|
26
|
+
this.sandboxUrl =
|
|
27
|
+
opts.sandboxUrl ??
|
|
28
|
+
env.WATASU_SANDBOX_URL;
|
|
21
29
|
this.dataPlaneDomain =
|
|
22
30
|
opts.dataPlaneDomain ??
|
|
23
31
|
env.WATASU_DATA_PLANE_DOMAIN ??
|
|
24
32
|
'watasuhost.com';
|
|
25
33
|
this.requestTimeoutMs = opts.requestTimeoutMs ?? 60_000;
|
|
26
34
|
this.headers = opts.headers ?? {};
|
|
35
|
+
this.apiHeaders = opts.apiHeaders ?? {};
|
|
36
|
+
this.debug = opts.debug ?? false;
|
|
37
|
+
this.signal = opts.signal;
|
|
27
38
|
this.proxy = opts.proxy;
|
|
28
39
|
}
|
|
29
40
|
/** HTTP headers including the configured bearer token. */
|
|
30
41
|
get authHeaders() {
|
|
31
42
|
return this.apiKey
|
|
32
|
-
? { ...this.headers, Authorization: `Bearer ${this.apiKey}` }
|
|
33
|
-
: { ...this.headers };
|
|
43
|
+
? { ...this.headers, ...this.apiHeaders, Authorization: `Bearer ${this.apiKey}` }
|
|
44
|
+
: { ...this.headers, ...this.apiHeaders };
|
|
45
|
+
}
|
|
46
|
+
/** Return an abort signal that follows the caller signal and optional timeout. */
|
|
47
|
+
getSignal(requestTimeoutMs = this.requestTimeoutMs, signal = this.signal) {
|
|
48
|
+
if (requestTimeoutMs === undefined && signal === undefined)
|
|
49
|
+
return undefined;
|
|
50
|
+
const controller = new AbortController();
|
|
51
|
+
if (signal?.aborted)
|
|
52
|
+
controller.abort();
|
|
53
|
+
else
|
|
54
|
+
signal?.addEventListener('abort', () => controller.abort(), { once: true });
|
|
55
|
+
if (requestTimeoutMs > 0) {
|
|
56
|
+
const timeout = setTimeout(() => controller.abort(), requestTimeoutMs);
|
|
57
|
+
const maybeTimeout = timeout;
|
|
58
|
+
if (typeof maybeTimeout.unref === 'function')
|
|
59
|
+
maybeTimeout.unref();
|
|
60
|
+
controller.signal.addEventListener('abort', () => clearTimeout(timeout), { once: true });
|
|
61
|
+
}
|
|
62
|
+
return controller.signal;
|
|
63
|
+
}
|
|
64
|
+
/** Return the sandbox data-plane API URL for a Watasu route token. */
|
|
65
|
+
getSandboxUrl(sandboxId, opts) {
|
|
66
|
+
if (this.sandboxUrl)
|
|
67
|
+
return this.sandboxUrl;
|
|
68
|
+
if (this.debug)
|
|
69
|
+
return `http://localhost:${opts.envdPort}`;
|
|
70
|
+
return `https://${sandboxId}.sandbox.${opts.sandboxDomain ?? this.dataPlaneDomain}`;
|
|
71
|
+
}
|
|
72
|
+
/** Return the direct sandbox data-plane API URL for a Watasu route token. */
|
|
73
|
+
getSandboxDirectUrl(sandboxId, opts) {
|
|
74
|
+
return this.getSandboxUrl(sandboxId, opts);
|
|
75
|
+
}
|
|
76
|
+
/** Return the public hostname for a Watasu sandbox route token and port. */
|
|
77
|
+
getHost(sandboxId, port, sandboxDomain = this.dataPlaneDomain) {
|
|
78
|
+
if (this.debug)
|
|
79
|
+
return `localhost:${port}`;
|
|
80
|
+
return `p${port}-${sandboxId}.sandbox.${sandboxDomain}`;
|
|
34
81
|
}
|
|
35
82
|
}
|
package/dist/errors.d.ts
CHANGED
|
@@ -25,6 +25,27 @@ export declare class NotEnoughSpaceError extends SandboxError {
|
|
|
25
25
|
export declare class FileNotFoundError extends NotFoundError {
|
|
26
26
|
constructor(message?: string);
|
|
27
27
|
}
|
|
28
|
+
export declare class SandboxNotFoundError extends NotFoundError {
|
|
29
|
+
constructor(message?: string);
|
|
30
|
+
}
|
|
31
|
+
export declare class GitAuthError extends AuthenticationError {
|
|
32
|
+
constructor(message?: string);
|
|
33
|
+
}
|
|
34
|
+
export declare class GitUpstreamError extends SandboxError {
|
|
35
|
+
constructor(message?: string);
|
|
36
|
+
}
|
|
37
|
+
export declare class TemplateError extends SandboxError {
|
|
38
|
+
constructor(message?: string);
|
|
39
|
+
}
|
|
40
|
+
export declare class BuildError extends Error {
|
|
41
|
+
constructor(message?: string);
|
|
42
|
+
}
|
|
43
|
+
export declare class FileUploadError extends BuildError {
|
|
44
|
+
constructor(message?: string);
|
|
45
|
+
}
|
|
46
|
+
export declare class VolumeError extends Error {
|
|
47
|
+
constructor(message?: string);
|
|
48
|
+
}
|
|
28
49
|
export declare function unsupported(feature: string): never;
|
|
29
50
|
export declare class NotImplementedError extends Error {
|
|
30
51
|
constructor(message: string);
|
package/dist/errors.js
CHANGED
|
@@ -52,6 +52,48 @@ export class FileNotFoundError extends NotFoundError {
|
|
|
52
52
|
this.name = 'FileNotFoundError';
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
+
export class SandboxNotFoundError extends NotFoundError {
|
|
56
|
+
constructor(message = 'Sandbox not found') {
|
|
57
|
+
super(message);
|
|
58
|
+
this.name = 'SandboxNotFoundError';
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export class GitAuthError extends AuthenticationError {
|
|
62
|
+
constructor(message = 'Git authentication failed') {
|
|
63
|
+
super(message);
|
|
64
|
+
this.name = 'GitAuthError';
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export class GitUpstreamError extends SandboxError {
|
|
68
|
+
constructor(message = 'Git upstream tracking is missing') {
|
|
69
|
+
super(message);
|
|
70
|
+
this.name = 'GitUpstreamError';
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export class TemplateError extends SandboxError {
|
|
74
|
+
constructor(message = 'Template error') {
|
|
75
|
+
super(message);
|
|
76
|
+
this.name = 'TemplateError';
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export class BuildError extends Error {
|
|
80
|
+
constructor(message = 'Build error') {
|
|
81
|
+
super(message);
|
|
82
|
+
this.name = 'BuildError';
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export class FileUploadError extends BuildError {
|
|
86
|
+
constructor(message = 'File upload failed') {
|
|
87
|
+
super(message);
|
|
88
|
+
this.name = 'FileUploadError';
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
export class VolumeError extends Error {
|
|
92
|
+
constructor(message = 'Volume error') {
|
|
93
|
+
super(message);
|
|
94
|
+
this.name = 'VolumeError';
|
|
95
|
+
}
|
|
96
|
+
}
|
|
55
97
|
export function unsupported(feature) {
|
|
56
98
|
throw new NotImplementedError(`${feature} is not supported by Watasu yet`);
|
|
57
99
|
}
|
|
@@ -78,6 +120,18 @@ export function errorFromResponse(status, payload) {
|
|
|
78
120
|
listMessage(body.errors) ||
|
|
79
121
|
code ||
|
|
80
122
|
`Request failed with status ${status}`;
|
|
123
|
+
if (code === 'not_enough_space')
|
|
124
|
+
return new NotEnoughSpaceError(message);
|
|
125
|
+
if (code === 'file_not_found')
|
|
126
|
+
return new FileNotFoundError(message);
|
|
127
|
+
if (code === 'sandbox_not_found')
|
|
128
|
+
return new SandboxNotFoundError(message);
|
|
129
|
+
if (code === 'git_auth')
|
|
130
|
+
return new GitAuthError(message);
|
|
131
|
+
if (code === 'git_upstream')
|
|
132
|
+
return new GitUpstreamError(message);
|
|
133
|
+
if (code === 'template_error')
|
|
134
|
+
return new TemplateError(message);
|
|
81
135
|
if (status === 401 || status === 403)
|
|
82
136
|
return new AuthenticationError(message);
|
|
83
137
|
if (status === 404)
|
|
@@ -90,10 +144,6 @@ export function errorFromResponse(status, payload) {
|
|
|
90
144
|
return new InvalidArgumentError(message);
|
|
91
145
|
if (status === 429)
|
|
92
146
|
return new RateLimitError(message);
|
|
93
|
-
if (code === 'not_enough_space')
|
|
94
|
-
return new NotEnoughSpaceError(message);
|
|
95
|
-
if (code === 'file_not_found')
|
|
96
|
-
return new FileNotFoundError(message);
|
|
97
147
|
return new ApiError(message, status, code);
|
|
98
148
|
}
|
|
99
149
|
function asRecord(value) {
|
package/dist/filesystem.d.ts
CHANGED
|
@@ -8,6 +8,13 @@ export declare enum FileType {
|
|
|
8
8
|
/** Symbolic link. */
|
|
9
9
|
SYMLINK = "symlink"
|
|
10
10
|
}
|
|
11
|
+
export declare enum FilesystemEventType {
|
|
12
|
+
CHMOD = "chmod",
|
|
13
|
+
CREATE = "create",
|
|
14
|
+
REMOVE = "remove",
|
|
15
|
+
RENAME = "rename",
|
|
16
|
+
WRITE = "write"
|
|
17
|
+
}
|
|
11
18
|
/** Metadata for one sandbox filesystem entry. */
|
|
12
19
|
export interface EntryInfo {
|
|
13
20
|
name: string;
|
|
@@ -27,7 +34,8 @@ export interface WriteEntry {
|
|
|
27
34
|
data: WriteData;
|
|
28
35
|
}
|
|
29
36
|
export interface FilesystemEvent {
|
|
30
|
-
|
|
37
|
+
name: string;
|
|
38
|
+
type: FilesystemEventType | string;
|
|
31
39
|
path: string;
|
|
32
40
|
entry?: EntryInfo;
|
|
33
41
|
raw: Record<string, unknown>;
|
|
@@ -35,11 +43,15 @@ export interface FilesystemEvent {
|
|
|
35
43
|
export interface WatchOpts {
|
|
36
44
|
recursive?: boolean;
|
|
37
45
|
includeEntry?: boolean;
|
|
46
|
+
allowNetworkMounts?: boolean;
|
|
38
47
|
requestTimeoutMs?: number;
|
|
48
|
+
signal?: AbortSignal;
|
|
49
|
+
user?: string;
|
|
39
50
|
onExit?: (error?: Error) => void | Promise<void>;
|
|
40
51
|
}
|
|
41
52
|
export interface FilesystemRequestOpts {
|
|
42
53
|
requestTimeoutMs?: number;
|
|
54
|
+
signal?: AbortSignal;
|
|
43
55
|
user?: string;
|
|
44
56
|
}
|
|
45
57
|
export interface FilesystemReadOpts extends FilesystemRequestOpts {
|
|
@@ -47,6 +59,7 @@ export interface FilesystemReadOpts extends FilesystemRequestOpts {
|
|
|
47
59
|
}
|
|
48
60
|
export interface FilesystemWriteOpts extends FilesystemRequestOpts {
|
|
49
61
|
gzip?: boolean;
|
|
62
|
+
useOctetStream?: boolean;
|
|
50
63
|
metadata?: Record<string, string>;
|
|
51
64
|
}
|
|
52
65
|
/** Live filesystem watcher. Call `stop()` to close the local watch stream. */
|
|
@@ -56,8 +69,6 @@ export declare class WatchHandle {
|
|
|
56
69
|
constructor(socket: ProcessSocket, events: AsyncIterable<ProcessFrame>, onEvent: (event: FilesystemEvent) => void | Promise<void>, onExit?: (error?: Error) => void | Promise<void>);
|
|
57
70
|
/** Stop watching the directory. */
|
|
58
71
|
stop(): void;
|
|
59
|
-
/** Alias for `stop`. */
|
|
60
|
-
close(): void;
|
|
61
72
|
/** Resolves when the watcher stream exits. */
|
|
62
73
|
wait(): Promise<void>;
|
|
63
74
|
private pump;
|
|
@@ -102,30 +113,19 @@ export declare class Filesystem {
|
|
|
102
113
|
/** Write several files in one runtime API call. */
|
|
103
114
|
writeFiles(files: WriteEntry[], opts?: FilesystemWriteOpts): Promise<WriteInfo[]>;
|
|
104
115
|
/** List directory entries below `path`. */
|
|
105
|
-
list(path: string, opts?: {
|
|
106
|
-
requestTimeoutMs?: number;
|
|
116
|
+
list(path: string, opts?: FilesystemRequestOpts & {
|
|
107
117
|
depth?: number;
|
|
108
118
|
}): Promise<EntryInfo[]>;
|
|
109
119
|
/** Return whether a file or directory exists at `path`. */
|
|
110
|
-
exists(path: string, opts?:
|
|
111
|
-
requestTimeoutMs?: number;
|
|
112
|
-
}): Promise<boolean>;
|
|
120
|
+
exists(path: string, opts?: FilesystemRequestOpts): Promise<boolean>;
|
|
113
121
|
/** Return stat metadata for `path`. */
|
|
114
|
-
getInfo(path: string, opts?:
|
|
115
|
-
requestTimeoutMs?: number;
|
|
116
|
-
}): Promise<EntryInfo>;
|
|
122
|
+
getInfo(path: string, opts?: FilesystemRequestOpts): Promise<EntryInfo>;
|
|
117
123
|
/** Remove a file at `path`. */
|
|
118
|
-
remove(path: string, opts?:
|
|
119
|
-
requestTimeoutMs?: number;
|
|
120
|
-
}): Promise<void>;
|
|
124
|
+
remove(path: string, opts?: FilesystemRequestOpts): Promise<void>;
|
|
121
125
|
/** Move or rename a file. */
|
|
122
|
-
rename(oldPath: string, newPath: string, opts?:
|
|
123
|
-
requestTimeoutMs?: number;
|
|
124
|
-
}): Promise<EntryInfo>;
|
|
126
|
+
rename(oldPath: string, newPath: string, opts?: FilesystemRequestOpts): Promise<EntryInfo>;
|
|
125
127
|
/** Create a directory. */
|
|
126
|
-
makeDir(path: string, opts?:
|
|
127
|
-
requestTimeoutMs?: number;
|
|
128
|
-
}): Promise<boolean>;
|
|
128
|
+
makeDir(path: string, opts?: FilesystemRequestOpts): Promise<boolean>;
|
|
129
129
|
/** Start watching a directory for filesystem events. */
|
|
130
130
|
watchDir(path: string): FilesystemWatcher;
|
|
131
131
|
watchDir(path: string, onEvent: (event: FilesystemEvent) => void | Promise<void>, opts?: WatchOpts): Promise<FilesystemWatcher>;
|
package/dist/filesystem.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { gzipSync } from 'node:zlib';
|
|
1
2
|
import { withQuery } from './transport.js';
|
|
2
3
|
import { FileNotFoundError, InvalidArgumentError } from './errors.js';
|
|
3
4
|
import { ProcessSocket, base64Encode } from './processSocket.js';
|
|
@@ -10,6 +11,14 @@ export var FileType;
|
|
|
10
11
|
/** Symbolic link. */
|
|
11
12
|
FileType["SYMLINK"] = "symlink";
|
|
12
13
|
})(FileType || (FileType = {}));
|
|
14
|
+
export var FilesystemEventType;
|
|
15
|
+
(function (FilesystemEventType) {
|
|
16
|
+
FilesystemEventType["CHMOD"] = "chmod";
|
|
17
|
+
FilesystemEventType["CREATE"] = "create";
|
|
18
|
+
FilesystemEventType["REMOVE"] = "remove";
|
|
19
|
+
FilesystemEventType["RENAME"] = "rename";
|
|
20
|
+
FilesystemEventType["WRITE"] = "write";
|
|
21
|
+
})(FilesystemEventType || (FilesystemEventType = {}));
|
|
13
22
|
/** Live filesystem watcher. Call `stop()` to close the local watch stream. */
|
|
14
23
|
export class WatchHandle {
|
|
15
24
|
socket;
|
|
@@ -22,10 +31,6 @@ export class WatchHandle {
|
|
|
22
31
|
stop() {
|
|
23
32
|
this.socket.close();
|
|
24
33
|
}
|
|
25
|
-
/** Alias for `stop`. */
|
|
26
|
-
close() {
|
|
27
|
-
this.stop();
|
|
28
|
-
}
|
|
29
34
|
/** Resolves when the watcher stream exits. */
|
|
30
35
|
wait() {
|
|
31
36
|
return this.done;
|
|
@@ -66,7 +71,12 @@ export class FilesystemWatcher {
|
|
|
66
71
|
if (this.handle)
|
|
67
72
|
return;
|
|
68
73
|
const nextOpts = { ...this.opts, ...opts };
|
|
69
|
-
const socket = await new ProcessSocket(this.dataPlane.baseUrl, this.dataPlane.token, withQuery('/runtime/v1/files/watch', {
|
|
74
|
+
const socket = await new ProcessSocket(this.dataPlane.baseUrl, this.dataPlane.token, withQuery('/runtime/v1/files/watch', {
|
|
75
|
+
path: this.path,
|
|
76
|
+
recursive: nextOpts.recursive ?? false,
|
|
77
|
+
include_entry: nextOpts.includeEntry,
|
|
78
|
+
allow_network_mounts: nextOpts.allowNetworkMounts,
|
|
79
|
+
}), nextOpts.requestTimeoutMs, this.dataPlane.headers).connect();
|
|
70
80
|
this.handle = new WatchHandle(socket, socket, async (event) => {
|
|
71
81
|
for (const listener of this.listeners)
|
|
72
82
|
await listener(event);
|
|
@@ -113,8 +123,8 @@ export class Filesystem {
|
|
|
113
123
|
if (Array.isArray(pathOrFiles)) {
|
|
114
124
|
return this.writeFiles(pathOrFiles, dataOrOpts);
|
|
115
125
|
}
|
|
116
|
-
const body = await writeDataToBytes(dataOrOpts);
|
|
117
|
-
const payload = await this.dataPlane.putJson(withQuery('/runtime/v1/files', { path: pathOrFiles, gzip: opts.gzip }), body, opts);
|
|
126
|
+
const body = maybeGzip(await writeDataToBytes(dataOrOpts), opts.gzip);
|
|
127
|
+
const payload = await this.dataPlane.putJson(withQuery('/runtime/v1/files', { path: pathOrFiles, gzip: opts.gzip }), body, requestOpts(opts, opts.gzip ? { 'content-encoding': 'gzip' } : undefined));
|
|
118
128
|
return entryInfo(payload.file ?? payload);
|
|
119
129
|
}
|
|
120
130
|
/** Write raw bytes to a file. */
|
|
@@ -126,11 +136,12 @@ export class Filesystem {
|
|
|
126
136
|
if (files.length === 0)
|
|
127
137
|
return [];
|
|
128
138
|
const payload = await this.dataPlane.postJson('/runtime/v1/files/write_files', {
|
|
129
|
-
...opts,
|
|
139
|
+
...requestOpts(opts),
|
|
130
140
|
json: {
|
|
131
141
|
files: await Promise.all(files.map(async (file) => ({
|
|
132
142
|
path: file.path,
|
|
133
|
-
data_base64: base64Encode(await writeDataToBytes(file.data)),
|
|
143
|
+
data_base64: base64Encode(maybeGzip(await writeDataToBytes(file.data), opts.gzip)),
|
|
144
|
+
...(opts.gzip ? { gzip: true } : {}),
|
|
134
145
|
}))),
|
|
135
146
|
},
|
|
136
147
|
});
|
|
@@ -198,6 +209,19 @@ async function writeDataToBytes(data) {
|
|
|
198
209
|
return readStreamToBytes(data);
|
|
199
210
|
throw new InvalidArgumentError(`Unsupported file data type: ${Object.prototype.toString.call(data)}`);
|
|
200
211
|
}
|
|
212
|
+
function requestOpts(opts, headers) {
|
|
213
|
+
const out = {};
|
|
214
|
+
if (opts.requestTimeoutMs !== undefined)
|
|
215
|
+
out.requestTimeoutMs = opts.requestTimeoutMs;
|
|
216
|
+
if (opts.signal !== undefined)
|
|
217
|
+
out.signal = opts.signal;
|
|
218
|
+
if (headers !== undefined)
|
|
219
|
+
out.headers = headers;
|
|
220
|
+
return out;
|
|
221
|
+
}
|
|
222
|
+
function maybeGzip(bytes, enabled) {
|
|
223
|
+
return enabled ? new Uint8Array(gzipSync(bytes)) : bytes;
|
|
224
|
+
}
|
|
201
225
|
function toArrayBuffer(bytes) {
|
|
202
226
|
const buffer = new ArrayBuffer(bytes.byteLength);
|
|
203
227
|
new Uint8Array(buffer).set(bytes);
|
|
@@ -257,17 +281,32 @@ function recordOfStrings(value) {
|
|
|
257
281
|
}
|
|
258
282
|
function filesystemEvent(value) {
|
|
259
283
|
const item = value && typeof value === 'object' ? value : {};
|
|
284
|
+
const path = String(item.path ?? '');
|
|
260
285
|
return {
|
|
261
286
|
type: normalizeEventType(String(item.type ?? 'modify')),
|
|
262
|
-
|
|
287
|
+
name: String(item.name ?? relativeName(path)),
|
|
288
|
+
path,
|
|
263
289
|
entry: item.file && typeof item.file === 'object' ? entryInfo(item.file) : undefined,
|
|
264
290
|
raw: item,
|
|
265
291
|
};
|
|
266
292
|
}
|
|
267
293
|
function normalizeEventType(value) {
|
|
268
294
|
if (value === 'delete')
|
|
269
|
-
return
|
|
295
|
+
return FilesystemEventType.REMOVE;
|
|
270
296
|
if (value === 'modify')
|
|
271
|
-
return
|
|
297
|
+
return FilesystemEventType.WRITE;
|
|
298
|
+
if (value === 'chmod')
|
|
299
|
+
return FilesystemEventType.CHMOD;
|
|
300
|
+
if (value === 'create')
|
|
301
|
+
return FilesystemEventType.CREATE;
|
|
302
|
+
if (value === 'remove')
|
|
303
|
+
return FilesystemEventType.REMOVE;
|
|
304
|
+
if (value === 'rename')
|
|
305
|
+
return FilesystemEventType.RENAME;
|
|
306
|
+
if (value === 'write')
|
|
307
|
+
return FilesystemEventType.WRITE;
|
|
272
308
|
return value;
|
|
273
309
|
}
|
|
310
|
+
function relativeName(path) {
|
|
311
|
+
return path.split('/').filter(Boolean).pop() ?? '';
|
|
312
|
+
}
|
package/dist/git.d.ts
CHANGED
|
@@ -20,16 +20,15 @@ export interface GitAuthOpts {
|
|
|
20
20
|
envs?: Record<string, string>;
|
|
21
21
|
user?: string;
|
|
22
22
|
cwd?: string;
|
|
23
|
-
timeout?: number;
|
|
24
23
|
timeoutMs?: number;
|
|
25
24
|
requestTimeoutMs?: number;
|
|
25
|
+
signal?: AbortSignal;
|
|
26
26
|
}
|
|
27
27
|
export interface GitCloneOpts extends GitAuthOpts {
|
|
28
28
|
path?: string;
|
|
29
29
|
branch?: string;
|
|
30
30
|
depth?: number;
|
|
31
31
|
recursive?: boolean;
|
|
32
|
-
submodules?: boolean;
|
|
33
32
|
dangerouslyStoreCredentials?: boolean;
|
|
34
33
|
}
|
|
35
34
|
export interface GitRequestOpts extends GitAuthOpts {
|
|
@@ -51,13 +50,15 @@ export interface GitCredentialOpts extends GitRequestOpts {
|
|
|
51
50
|
host?: string;
|
|
52
51
|
protocol?: string;
|
|
53
52
|
}
|
|
53
|
+
export type GitDangerouslyAuthenticateOpts = GitCredentialOpts;
|
|
54
54
|
export interface GitConfigureUserOpts extends GitRequestOpts {
|
|
55
|
-
scope?:
|
|
55
|
+
scope?: GitConfigScope;
|
|
56
56
|
path?: string;
|
|
57
57
|
}
|
|
58
58
|
export interface GitBranchOpts extends GitRequestOpts {
|
|
59
59
|
force?: boolean;
|
|
60
60
|
}
|
|
61
|
+
export type GitDeleteBranchOpts = GitBranchOpts;
|
|
61
62
|
export interface GitAddOpts extends GitRequestOpts {
|
|
62
63
|
files?: string[];
|
|
63
64
|
all?: boolean;
|
|
@@ -84,9 +85,10 @@ export interface GitRemoteAddOpts extends GitRequestOpts {
|
|
|
84
85
|
overwrite?: boolean;
|
|
85
86
|
}
|
|
86
87
|
export interface GitConfigOpts extends GitRequestOpts {
|
|
87
|
-
scope?:
|
|
88
|
+
scope?: GitConfigScope;
|
|
88
89
|
path?: string;
|
|
89
90
|
}
|
|
91
|
+
export type GitConfigScope = 'global' | 'local' | 'system';
|
|
90
92
|
export interface GitBranches {
|
|
91
93
|
path?: string;
|
|
92
94
|
branches: string[];
|
package/dist/git.js
CHANGED
|
@@ -9,7 +9,7 @@ export class Git {
|
|
|
9
9
|
return this.run('/runtime/v1/git/clone', {
|
|
10
10
|
url,
|
|
11
11
|
...gitOpts(opts),
|
|
12
|
-
...pick(opts, ['path', 'branch', 'depth', 'recursive', '
|
|
12
|
+
...pick(opts, ['path', 'branch', 'depth', 'recursive', 'username', 'password']),
|
|
13
13
|
dangerously_store_credentials: opts.dangerouslyStoreCredentials,
|
|
14
14
|
}, opts);
|
|
15
15
|
}
|
|
@@ -163,7 +163,11 @@ export class Git {
|
|
|
163
163
|
return String(result.value ?? '');
|
|
164
164
|
}
|
|
165
165
|
async run(path, json, opts) {
|
|
166
|
-
const payload = await this.dataPlane.postJson(path, {
|
|
166
|
+
const payload = await this.dataPlane.postJson(path, {
|
|
167
|
+
json: compact(json),
|
|
168
|
+
requestTimeoutMs: opts.requestTimeoutMs,
|
|
169
|
+
signal: opts.signal,
|
|
170
|
+
});
|
|
167
171
|
return gitResult(payload.git ?? payload);
|
|
168
172
|
}
|
|
169
173
|
}
|
|
@@ -172,7 +176,7 @@ function gitOpts(opts) {
|
|
|
172
176
|
env_vars: opts.envs,
|
|
173
177
|
user: opts.user,
|
|
174
178
|
cwd: opts.cwd,
|
|
175
|
-
timeout_seconds: opts.
|
|
179
|
+
timeout_seconds: opts.timeoutMs === undefined ? undefined : Math.ceil(opts.timeoutMs / 1000),
|
|
176
180
|
};
|
|
177
181
|
}
|
|
178
182
|
function pick(source, keys) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,24 +1,36 @@
|
|
|
1
|
-
export { ApiError, AuthenticationError, ConflictError, FileNotFoundError, InvalidArgumentError, NotEnoughSpaceError, NotFoundError, NotImplementedError, RateLimitError, SandboxError, TimeoutError, } from './errors.js';
|
|
1
|
+
export { ApiError, AuthenticationError, BuildError, ConflictError, FileNotFoundError, FileUploadError, GitAuthError, GitUpstreamError, InvalidArgumentError, NotEnoughSpaceError, NotFoundError, NotImplementedError, RateLimitError, SandboxError, SandboxNotFoundError, TemplateError, TimeoutError, VolumeError, } from './errors.js';
|
|
2
2
|
export { ConnectionConfig, KEEPALIVE_PING_INTERVAL_SEC } from './connectionConfig.js';
|
|
3
|
-
export {
|
|
3
|
+
export type { ConnectionOpts, Username } from './connectionConfig.js';
|
|
4
|
+
export { ControlClient as ApiClient } from './transport.js';
|
|
5
|
+
export { ALL_TRAFFIC, Sandbox, SandboxPaginator, SnapshotPaginator, getSignature, } from './sandbox.js';
|
|
4
6
|
export { Sandbox as CodeInterpreterSandbox } from './codeInterpreter.js';
|
|
5
|
-
export type { CreateSnapshotOpts, RestoreSnapshotOpts, SandboxCreateOpts, SandboxConnectOpts, SandboxInfo, SandboxInfoLifecycle, SandboxLifecycle, SandboxListOpts, SandboxMetrics, SandboxMetricsOpts, McpServer, McpServerName, SandboxNetworkSelector, SandboxNetworkUpdate, SandboxNetworkUpdateOpts, SandboxUrlOpts, SnapshotInfo, FileUrlInfo, } from './sandbox.js';
|
|
7
|
+
export type { CreateSnapshotOpts, RestoreSnapshotOpts, SandboxApiOpts, SandboxCreateOpts, SandboxConnectOpts, SandboxInfo, SandboxInfoLifecycle, SandboxLifecycle, SandboxListOpts, SandboxMetrics, SandboxMetricsOpts, McpServer, McpServerName, SandboxNetworkInfo, SandboxNetworkOpts, SandboxNetworkRule, SandboxNetworkRuleInfo, SandboxNetworkRules, SandboxNetworkSelector, SandboxNetworkSelectorContext, SandboxNetworkTransform, SandboxNetworkUpdate, SandboxNetworkUpdateOpts, SandboxOpts, SandboxState, SandboxUrlOpts, SignatureOpts, SnapshotInfo, SnapshotListOpts, FileUrlInfo, } from './sandbox.js';
|
|
6
8
|
export type { CreateCodeContextOpts, RunCodeLanguage, RunCodeOpts, } from './codeInterpreter.js';
|
|
7
9
|
export { Context as CodeInterpreterContext, Execution as CodeInterpreterExecution, ExecutionError as CodeInterpreterExecutionError, OutputMessage as CodeInterpreterOutputMessage, Result as CodeInterpreterResult, } from './codeInterpreter.js';
|
|
8
10
|
export { CommandExitError, CommandHandle, Commands } from './commands.js';
|
|
9
|
-
export type { CommandResult, CommandStartOpts, ProcessInfo } from './commands.js';
|
|
11
|
+
export type { CommandConnectOpts, CommandRequestOpts, CommandResult, CommandStartOpts, ProcessInfo, PtyOutput, Stderr, Stdout, } from './commands.js';
|
|
10
12
|
export { Process, ProcessManager, ProcessMessage, ProcessOutput } from './process.js';
|
|
11
13
|
export type { ProcessOpts } from './process.js';
|
|
12
|
-
export { FileType, Filesystem, FilesystemWatcher, WatchHandle } from './filesystem.js';
|
|
14
|
+
export { FileType, Filesystem, FilesystemEventType, FilesystemWatcher, WatchHandle, } from './filesystem.js';
|
|
13
15
|
export type { EntryInfo, FilesystemEvent, FilesystemReadOpts, FilesystemRequestOpts, FilesystemWriteOpts, WatchOpts, WriteData, WriteEntry, WriteInfo, } from './filesystem.js';
|
|
14
16
|
export { Git } from './git.js';
|
|
15
|
-
export type { GitAddOpts, GitAuthOpts, GitBranches, GitBranchOpts, GitCloneOpts, GitCommandResult, GitConfigOpts, GitConfigureUserOpts, GitCredentialOpts, GitCommitOpts, GitFileStatus, GitInitOpts, GitPullOpts, GitPushOpts, GitRemoteAddOpts, GitResetMode, GitResetOpts, GitRestoreOpts, GitRequestOpts, GitStatus, } from './git.js';
|
|
17
|
+
export type { GitAddOpts, GitAuthOpts, GitBranches, GitBranchOpts, GitCloneOpts, GitCommandResult, GitConfigScope, GitConfigOpts, GitConfigureUserOpts, GitCredentialOpts, GitCommitOpts, GitDangerouslyAuthenticateOpts, GitDeleteBranchOpts, GitFileStatus, GitInitOpts, GitPullOpts, GitPushOpts, GitRemoteAddOpts, GitResetMode, GitResetOpts, GitRestoreOpts, GitRequestOpts, GitStatus, } from './git.js';
|
|
16
18
|
export { Pty } from './pty.js';
|
|
17
19
|
export type { PtyConnectOpts, PtyCreateOpts, PtySize } from './pty.js';
|
|
18
20
|
export { Terminal, TerminalManager, TerminalOutput } from './terminal.js';
|
|
19
21
|
export type { TerminalOpts } from './terminal.js';
|
|
20
|
-
export { Volume } from './volume.js';
|
|
21
|
-
export type { VolumeApiParams,
|
|
22
|
+
export { Volume, VolumeConnectionConfig, VolumeFileType } from './volume.js';
|
|
23
|
+
export type { VolumeAndToken, VolumeApiParams, VolumeApiOpts, VolumeEntryStat, VolumeInfo, VolumeListFilesOpts, VolumeListOpts, VolumeMetadataOpts, VolumeMetadataOptions, VolumeReadFileOpts, VolumeReadFormat, VolumeWriteData, VolumeWriteFileOpts, VolumeWriteOptions, } from './volume.js';
|
|
22
24
|
export { ProcessSocket, base64DecodeBytes, base64DecodeText, base64Encode } from './processSocket.js';
|
|
23
|
-
export { ReadyCmd, Template, TemplateBase, waitForFile, waitForPort, waitForProcess, waitForTimeout, waitForURL,
|
|
24
|
-
export type { BuildInfo, BuildOptions, BuildStatusReason, CopyItem, GetBuildStatusOptions,
|
|
25
|
+
export { ReadyCmd, Template, TemplateBase, LogEntry, LogEntryEnd, LogEntryStart, defaultBuildLogger, waitForFile, waitForPort, waitForProcess, waitForTimeout, waitForURL, } from './template.js';
|
|
26
|
+
export type { BuildInfo, BuildOptions, BuildStatusReason, CopyItem, GetBuildStatusOptions, LogEntryLevel, Logger, ReadyCommand, TemplateBuildStatus, TemplateBuildStatusResponse, TemplateBuilder, TemplateClass, TemplateFactory, TemplateFinal, TemplateFromImage, TemplateOptions, TemplateTag, TemplateTagInfo, } from './template.js';
|
|
27
|
+
export interface components {
|
|
28
|
+
schemas: Record<string, unknown>;
|
|
29
|
+
responses: Record<string, unknown>;
|
|
30
|
+
parameters: Record<string, unknown>;
|
|
31
|
+
requestBodies: Record<string, unknown>;
|
|
32
|
+
headers: Record<string, unknown>;
|
|
33
|
+
pathItems: Record<string, unknown>;
|
|
34
|
+
}
|
|
35
|
+
export type paths = Record<string, unknown>;
|
|
36
|
+
export { Sandbox as default } from './sandbox.js';
|
package/dist/index.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
export { ApiError, AuthenticationError, ConflictError, FileNotFoundError, InvalidArgumentError, NotEnoughSpaceError, NotFoundError, NotImplementedError, RateLimitError, SandboxError, TimeoutError, } from './errors.js';
|
|
1
|
+
export { ApiError, AuthenticationError, BuildError, ConflictError, FileNotFoundError, FileUploadError, GitAuthError, GitUpstreamError, InvalidArgumentError, NotEnoughSpaceError, NotFoundError, NotImplementedError, RateLimitError, SandboxError, SandboxNotFoundError, TemplateError, TimeoutError, VolumeError, } from './errors.js';
|
|
2
2
|
export { ConnectionConfig, KEEPALIVE_PING_INTERVAL_SEC } from './connectionConfig.js';
|
|
3
|
-
export {
|
|
3
|
+
export { ControlClient as ApiClient } from './transport.js';
|
|
4
|
+
export { ALL_TRAFFIC, Sandbox, SandboxPaginator, SnapshotPaginator, getSignature, } from './sandbox.js';
|
|
4
5
|
export { Sandbox as CodeInterpreterSandbox } from './codeInterpreter.js';
|
|
5
6
|
export { Context as CodeInterpreterContext, Execution as CodeInterpreterExecution, ExecutionError as CodeInterpreterExecutionError, OutputMessage as CodeInterpreterOutputMessage, Result as CodeInterpreterResult, } from './codeInterpreter.js';
|
|
6
7
|
export { CommandExitError, CommandHandle, Commands } from './commands.js';
|
|
7
8
|
export { Process, ProcessManager, ProcessMessage, ProcessOutput } from './process.js';
|
|
8
|
-
export { FileType, Filesystem, FilesystemWatcher, WatchHandle } from './filesystem.js';
|
|
9
|
+
export { FileType, Filesystem, FilesystemEventType, FilesystemWatcher, WatchHandle, } from './filesystem.js';
|
|
9
10
|
export { Git } from './git.js';
|
|
10
11
|
export { Pty } from './pty.js';
|
|
11
12
|
export { Terminal, TerminalManager, TerminalOutput } from './terminal.js';
|
|
12
|
-
export { Volume } from './volume.js';
|
|
13
|
+
export { Volume, VolumeConnectionConfig, VolumeFileType } from './volume.js';
|
|
13
14
|
export { ProcessSocket, base64DecodeBytes, base64DecodeText, base64Encode } from './processSocket.js';
|
|
14
|
-
export { ReadyCmd, Template, TemplateBase, waitForFile, waitForPort, waitForProcess, waitForTimeout, waitForURL,
|
|
15
|
+
export { ReadyCmd, Template, TemplateBase, LogEntry, LogEntryEnd, LogEntryStart, defaultBuildLogger, waitForFile, waitForPort, waitForProcess, waitForTimeout, waitForURL, } from './template.js';
|
|
16
|
+
export { Sandbox as default } from './sandbox.js';
|
package/dist/process.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ export declare class Process {
|
|
|
41
41
|
private waitPromise?;
|
|
42
42
|
constructor(processID: string, handle: CommandHandle, output: ProcessOutput, onExit?: ((exitCode: number) => Promise<void> | void) | undefined);
|
|
43
43
|
kill(): Promise<void>;
|
|
44
|
-
wait(
|
|
44
|
+
wait(timeoutMs?: number): Promise<ProcessOutput>;
|
|
45
45
|
private waitOnce;
|
|
46
46
|
sendStdin(data: string): Promise<void>;
|
|
47
47
|
}
|
package/dist/process.js
CHANGED
|
@@ -40,11 +40,15 @@ export class ProcessOutput {
|
|
|
40
40
|
this._error = true;
|
|
41
41
|
}
|
|
42
42
|
replace(result) {
|
|
43
|
+
const streamedStdout = this.stdout;
|
|
44
|
+
const streamedStderr = this.stderr;
|
|
43
45
|
this.messages = [];
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
this.
|
|
46
|
+
const stdout = result.stdout || streamedStdout;
|
|
47
|
+
const stderr = result.stderr || streamedStderr;
|
|
48
|
+
if (stdout)
|
|
49
|
+
this.addStdout(processMessage(stdout, false));
|
|
50
|
+
if (stderr)
|
|
51
|
+
this.addStderr(processMessage(stderr, true));
|
|
48
52
|
this.setExitCode(result.exitCode);
|
|
49
53
|
}
|
|
50
54
|
}
|
|
@@ -67,10 +71,10 @@ export class Process {
|
|
|
67
71
|
async kill() {
|
|
68
72
|
await this.handle.kill();
|
|
69
73
|
}
|
|
70
|
-
async wait(
|
|
74
|
+
async wait(timeoutMs) {
|
|
71
75
|
if (!this.waitPromise)
|
|
72
76
|
this.waitPromise = this.waitOnce();
|
|
73
|
-
return waitFor(this.waitPromise,
|
|
77
|
+
return waitFor(this.waitPromise, timeoutMs);
|
|
74
78
|
}
|
|
75
79
|
async waitOnce() {
|
|
76
80
|
try {
|
|
@@ -126,7 +130,7 @@ export class ProcessManager {
|
|
|
126
130
|
}
|
|
127
131
|
async startAndWait(cmdOrOpts) {
|
|
128
132
|
const process = await this.start(cmdOrOpts);
|
|
129
|
-
return process.wait(typeof cmdOrOpts === 'string' ? undefined : cmdOrOpts.
|
|
133
|
+
return process.wait(typeof cmdOrOpts === 'string' ? undefined : cmdOrOpts.timeoutMs);
|
|
130
134
|
}
|
|
131
135
|
}
|
|
132
136
|
function processOpts(cmdOrOpts) {
|