@boatdev/sdk 1.1.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/.openapi-generator/FILES +2 -0
- package/dist/apis/BoatApi.d.ts +2 -2
- package/dist/apis/BoatApi.js +2 -2
- package/dist/boat-helpers.d.ts +17 -1
- package/dist/boat-helpers.js +61 -0
- package/dist/esm/apis/BoatApi.d.ts +2 -2
- package/dist/esm/apis/BoatApi.js +2 -2
- package/dist/esm/boat-helpers.d.ts +17 -1
- package/dist/esm/boat-helpers.js +60 -0
- package/dist/esm/models/CommandRequest.d.ts +6 -0
- package/dist/esm/models/CommandRequest.js +2 -0
- package/dist/esm/models/CommandStreamFrame.d.ts +85 -0
- package/dist/esm/models/CommandStreamFrame.js +67 -0
- package/dist/esm/models/CreateSandboxRequest.d.ts +12 -0
- package/dist/esm/models/CreateSandboxRequest.js +4 -0
- package/dist/esm/models/DataRetentionPolicyResponse.d.ts +12 -0
- package/dist/esm/models/DataRetentionPolicyResponse.js +4 -0
- package/dist/esm/models/DataRetentionUpdateRequest.d.ts +8 -2
- package/dist/esm/models/DataRetentionUpdateRequest.js +3 -3
- package/dist/esm/models/Sandbox.d.ts +6 -0
- package/dist/esm/models/Sandbox.js +2 -0
- package/dist/esm/models/index.d.ts +1 -0
- package/dist/esm/models/index.js +1 -0
- package/dist/models/CommandRequest.d.ts +6 -0
- package/dist/models/CommandRequest.js +2 -0
- package/dist/models/CommandStreamFrame.d.ts +85 -0
- package/dist/models/CommandStreamFrame.js +75 -0
- package/dist/models/CreateSandboxRequest.d.ts +12 -0
- package/dist/models/CreateSandboxRequest.js +4 -0
- package/dist/models/DataRetentionPolicyResponse.d.ts +12 -0
- package/dist/models/DataRetentionPolicyResponse.js +4 -0
- package/dist/models/DataRetentionUpdateRequest.d.ts +8 -2
- package/dist/models/DataRetentionUpdateRequest.js +3 -3
- package/dist/models/Sandbox.d.ts +6 -0
- package/dist/models/Sandbox.js +2 -0
- package/dist/models/index.d.ts +1 -0
- package/dist/models/index.js +1 -0
- package/docs/BoatApi.md +4 -3
- package/docs/CommandRequest.md +2 -0
- package/docs/CommandStreamFrame.md +47 -0
- package/docs/CreateSandboxRequest.md +4 -0
- package/docs/DataRetentionPolicyResponse.md +4 -0
- package/docs/DataRetentionUpdateRequest.md +3 -0
- package/docs/Sandbox.md +2 -0
- package/package.json +1 -1
- package/src/apis/BoatApi.ts +7 -2
- package/src/boat-helpers.ts +75 -1
- package/src/models/CommandRequest.ts +8 -0
- package/src/models/CommandStreamFrame.ts +136 -0
- package/src/models/CreateSandboxRequest.ts +16 -0
- package/src/models/DataRetentionPolicyResponse.ts +16 -0
- package/src/models/DataRetentionUpdateRequest.ts +11 -4
- package/src/models/Sandbox.ts +8 -0
- package/src/models/index.ts +1 -0
package/.openapi-generator/FILES
CHANGED
|
@@ -25,6 +25,7 @@ docs/CommandRequest.md
|
|
|
25
25
|
docs/CommandResponse.md
|
|
26
26
|
docs/CommandStartedResponse.md
|
|
27
27
|
docs/CommandStatusResponse.md
|
|
28
|
+
docs/CommandStreamFrame.md
|
|
28
29
|
docs/CompletionEvent.md
|
|
29
30
|
docs/Conversation.md
|
|
30
31
|
docs/ConversationsResponse.md
|
|
@@ -163,6 +164,7 @@ src/models/CommandRequest.ts
|
|
|
163
164
|
src/models/CommandResponse.ts
|
|
164
165
|
src/models/CommandStartedResponse.ts
|
|
165
166
|
src/models/CommandStatusResponse.ts
|
|
167
|
+
src/models/CommandStreamFrame.ts
|
|
166
168
|
src/models/CompletionEvent.ts
|
|
167
169
|
src/models/Conversation.ts
|
|
168
170
|
src/models/ConversationsResponse.ts
|
package/dist/apis/BoatApi.d.ts
CHANGED
|
@@ -387,12 +387,12 @@ export declare class BoatApi extends runtime.BaseAPI {
|
|
|
387
387
|
*/
|
|
388
388
|
commandRequestOpts(input: CommandOperationRequest | runtime.FlatBody<CommandOperationRequest, 'commandRequest'>): Promise<runtime.RequestOpts>;
|
|
389
389
|
/**
|
|
390
|
-
* Runs the command synchronously by default (timeout configurable via `timeoutSeconds`, 600s cap). With `detached: true` the command starts in the background and a process id is returned immediately; poll `/sandboxes/{sandboxId}/commands/{processId}` for status and logs. Returns 400 invalid_timeout when `timeoutSeconds` is not an integer in 1-600.
|
|
390
|
+
* Runs the command synchronously by default (timeout configurable via `timeoutSeconds`, 600s cap). With `detached: true` the command starts in the background and a process id is returned immediately; poll `/sandboxes/{sandboxId}/commands/{processId}` for status and logs. With `stream: true` the output arrives as the command writes it, as newline-delimited JSON (`application/x-ndjson`): `{\"type\":\"started\"}`, then `{\"type\":\"stdout\"|\"stderr\",\"data\":\"...\"}` per chunk, and last `{\"type\":\"exit\",...}` (the synchronous result without stdout/stderr) or `{\"type\":\"error\",\"error\":\"...\",\"message\":\"...\"}`. Returns 400 invalid_timeout when `timeoutSeconds` is not an integer in 1-600. A command sent while the sandbox is still starting (right after a resume) waits up to 60s for it to be ready instead of failing; 409 boat_starting (retryable) is returned only if it is still not ready by then. Command execution is never retried automatically: a 502 boat_direct_failed means the command may already be running on the sandbox.
|
|
391
391
|
* Execute a command in a sandbox
|
|
392
392
|
*/
|
|
393
393
|
commandRaw(requestParameters: CommandOperationRequest | runtime.FlatBody<CommandOperationRequest, 'commandRequest'>, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<Command200Response>>;
|
|
394
394
|
/**
|
|
395
|
-
* Runs the command synchronously by default (timeout configurable via `timeoutSeconds`, 600s cap). With `detached: true` the command starts in the background and a process id is returned immediately; poll `/sandboxes/{sandboxId}/commands/{processId}` for status and logs. Returns 400 invalid_timeout when `timeoutSeconds` is not an integer in 1-600.
|
|
395
|
+
* Runs the command synchronously by default (timeout configurable via `timeoutSeconds`, 600s cap). With `detached: true` the command starts in the background and a process id is returned immediately; poll `/sandboxes/{sandboxId}/commands/{processId}` for status and logs. With `stream: true` the output arrives as the command writes it, as newline-delimited JSON (`application/x-ndjson`): `{\"type\":\"started\"}`, then `{\"type\":\"stdout\"|\"stderr\",\"data\":\"...\"}` per chunk, and last `{\"type\":\"exit\",...}` (the synchronous result without stdout/stderr) or `{\"type\":\"error\",\"error\":\"...\",\"message\":\"...\"}`. Returns 400 invalid_timeout when `timeoutSeconds` is not an integer in 1-600. A command sent while the sandbox is still starting (right after a resume) waits up to 60s for it to be ready instead of failing; 409 boat_starting (retryable) is returned only if it is still not ready by then. Command execution is never retried automatically: a 502 boat_direct_failed means the command may already be running on the sandbox.
|
|
396
396
|
* Execute a command in a sandbox
|
|
397
397
|
*/
|
|
398
398
|
command(requestParameters: CommandOperationRequest | runtime.FlatBody<CommandOperationRequest, 'commandRequest'>, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<Command200Response>;
|
package/dist/apis/BoatApi.js
CHANGED
|
@@ -331,7 +331,7 @@ class BoatApi extends runtime.BaseAPI {
|
|
|
331
331
|
};
|
|
332
332
|
}
|
|
333
333
|
/**
|
|
334
|
-
* Runs the command synchronously by default (timeout configurable via `timeoutSeconds`, 600s cap). With `detached: true` the command starts in the background and a process id is returned immediately; poll `/sandboxes/{sandboxId}/commands/{processId}` for status and logs. Returns 400 invalid_timeout when `timeoutSeconds` is not an integer in 1-600.
|
|
334
|
+
* Runs the command synchronously by default (timeout configurable via `timeoutSeconds`, 600s cap). With `detached: true` the command starts in the background and a process id is returned immediately; poll `/sandboxes/{sandboxId}/commands/{processId}` for status and logs. With `stream: true` the output arrives as the command writes it, as newline-delimited JSON (`application/x-ndjson`): `{\"type\":\"started\"}`, then `{\"type\":\"stdout\"|\"stderr\",\"data\":\"...\"}` per chunk, and last `{\"type\":\"exit\",...}` (the synchronous result without stdout/stderr) or `{\"type\":\"error\",\"error\":\"...\",\"message\":\"...\"}`. Returns 400 invalid_timeout when `timeoutSeconds` is not an integer in 1-600. A command sent while the sandbox is still starting (right after a resume) waits up to 60s for it to be ready instead of failing; 409 boat_starting (retryable) is returned only if it is still not ready by then. Command execution is never retried automatically: a 502 boat_direct_failed means the command may already be running on the sandbox.
|
|
335
335
|
* Execute a command in a sandbox
|
|
336
336
|
*/
|
|
337
337
|
async commandRaw(requestParameters, initOverrides) {
|
|
@@ -340,7 +340,7 @@ class BoatApi extends runtime.BaseAPI {
|
|
|
340
340
|
return new runtime.JSONApiResponse(response, (jsonValue) => (0, Command200Response_1.Command200ResponseFromJSON)(jsonValue));
|
|
341
341
|
}
|
|
342
342
|
/**
|
|
343
|
-
* Runs the command synchronously by default (timeout configurable via `timeoutSeconds`, 600s cap). With `detached: true` the command starts in the background and a process id is returned immediately; poll `/sandboxes/{sandboxId}/commands/{processId}` for status and logs. Returns 400 invalid_timeout when `timeoutSeconds` is not an integer in 1-600.
|
|
343
|
+
* Runs the command synchronously by default (timeout configurable via `timeoutSeconds`, 600s cap). With `detached: true` the command starts in the background and a process id is returned immediately; poll `/sandboxes/{sandboxId}/commands/{processId}` for status and logs. With `stream: true` the output arrives as the command writes it, as newline-delimited JSON (`application/x-ndjson`): `{\"type\":\"started\"}`, then `{\"type\":\"stdout\"|\"stderr\",\"data\":\"...\"}` per chunk, and last `{\"type\":\"exit\",...}` (the synchronous result without stdout/stderr) or `{\"type\":\"error\",\"error\":\"...\",\"message\":\"...\"}`. Returns 400 invalid_timeout when `timeoutSeconds` is not an integer in 1-600. A command sent while the sandbox is still starting (right after a resume) waits up to 60s for it to be ready instead of failing; 409 boat_starting (retryable) is returned only if it is still not ready by then. Command execution is never retried automatically: a 502 boat_direct_failed means the command may already be running on the sandbox.
|
|
344
344
|
* Execute a command in a sandbox
|
|
345
345
|
*/
|
|
346
346
|
async command(requestParameters, initOverrides) {
|
package/dist/boat-helpers.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BoatApi } from './apis/BoatApi';
|
|
2
|
-
import type { Sandbox, SandboxEvent, DesktopResponse, PromptRequest, PromptRun } from './models';
|
|
2
|
+
import type { Sandbox, SandboxEvent, DesktopResponse, PromptRequest, PromptRun, CommandStreamFrame } from './models';
|
|
3
3
|
export type WaitOptions = {
|
|
4
4
|
timeoutMs?: number;
|
|
5
5
|
intervalMs?: number;
|
|
@@ -54,3 +54,19 @@ export declare function stopAndRemove(api: BoatApi, sandboxId: string, options?:
|
|
|
54
54
|
export declare function readText(api: BoatApi, sandboxId: string, path: string): Promise<string>;
|
|
55
55
|
export declare function writeText(api: BoatApi, sandboxId: string, path: string, content: string): Promise<import("./models").FileWriteResponse>;
|
|
56
56
|
export declare function execCommand(api: BoatApi, sandboxId: string, command: string, cwd?: string, timeoutSeconds?: number): Promise<import("./models").Command200Response>;
|
|
57
|
+
/** One line of a streamed command, as sent (an `exit` frame also carries e.g. `signal`, `oomKilled`). */
|
|
58
|
+
export type CommandFrame = CommandStreamFrame & Record<string, unknown>;
|
|
59
|
+
export type StreamCommandOptions = {
|
|
60
|
+
cwd?: string;
|
|
61
|
+
timeoutSeconds?: number;
|
|
62
|
+
signal?: AbortSignal;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Run a command and yield its output as the command writes it: `started`, then
|
|
66
|
+
* `stdout`/`stderr` chunks (`frame.data`), then exactly one `exit` (`exitCode`,
|
|
67
|
+
* `timedOut`, ...) or `error` (`error`, `message`).
|
|
68
|
+
*
|
|
69
|
+
* Safe to call right after `resume()`, without waiting: the API holds a command
|
|
70
|
+
* sent to a starting sandbox for up to 60 s instead of refusing it.
|
|
71
|
+
*/
|
|
72
|
+
export declare function streamCommand(api: BoatApi, sandboxId: string, command: string, options?: StreamCommandOptions): AsyncGenerator<CommandFrame>;
|
package/dist/boat-helpers.js
CHANGED
|
@@ -11,6 +11,7 @@ exports.stopAndRemove = stopAndRemove;
|
|
|
11
11
|
exports.readText = readText;
|
|
12
12
|
exports.writeText = writeText;
|
|
13
13
|
exports.execCommand = execCommand;
|
|
14
|
+
exports.streamCommand = streamCommand;
|
|
14
15
|
const terminalPromptStatuses = new Set(['finished', 'failed']);
|
|
15
16
|
function delay(ms) {
|
|
16
17
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -174,3 +175,63 @@ async function writeText(api, sandboxId, path, content) {
|
|
|
174
175
|
async function execCommand(api, sandboxId, command, cwd, timeoutSeconds = 30) {
|
|
175
176
|
return api.command({ sandboxId, commandRequest: { command, cwd, timeoutSeconds } });
|
|
176
177
|
}
|
|
178
|
+
// A refusal that provably never ran the command (the sandbox is still restoring
|
|
179
|
+
// its disk, `retryable: true` before `started`) is retried for this long.
|
|
180
|
+
const STREAM_RETRY_MS = 60000;
|
|
181
|
+
async function* ndjsonFrames(response) {
|
|
182
|
+
if (!response.body)
|
|
183
|
+
throw new Error('The command stream has no body');
|
|
184
|
+
const reader = response.body.getReader();
|
|
185
|
+
const decoder = new TextDecoder();
|
|
186
|
+
let buffered = '';
|
|
187
|
+
let done = false;
|
|
188
|
+
try {
|
|
189
|
+
while (!done) {
|
|
190
|
+
const chunk = await reader.read();
|
|
191
|
+
done = chunk.done;
|
|
192
|
+
buffered += done ? decoder.decode() : decoder.decode(chunk.value, { stream: true });
|
|
193
|
+
let newline = buffered.indexOf('\n');
|
|
194
|
+
while (newline !== -1) {
|
|
195
|
+
const line = buffered.slice(0, newline).trim();
|
|
196
|
+
buffered = buffered.slice(newline + 1);
|
|
197
|
+
if (line)
|
|
198
|
+
yield JSON.parse(line);
|
|
199
|
+
newline = buffered.indexOf('\n');
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (buffered.trim())
|
|
203
|
+
yield JSON.parse(buffered);
|
|
204
|
+
}
|
|
205
|
+
finally {
|
|
206
|
+
// The caller stopped early: drop the connection instead of reading the rest.
|
|
207
|
+
if (!done)
|
|
208
|
+
await reader.cancel().catch(() => undefined);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Run a command and yield its output as the command writes it: `started`, then
|
|
213
|
+
* `stdout`/`stderr` chunks (`frame.data`), then exactly one `exit` (`exitCode`,
|
|
214
|
+
* `timedOut`, ...) or `error` (`error`, `message`).
|
|
215
|
+
*
|
|
216
|
+
* Safe to call right after `resume()`, without waiting: the API holds a command
|
|
217
|
+
* sent to a starting sandbox for up to 60 s instead of refusing it.
|
|
218
|
+
*/
|
|
219
|
+
async function* streamCommand(api, sandboxId, command, options) {
|
|
220
|
+
const deadline = Date.now() + STREAM_RETRY_MS;
|
|
221
|
+
for (;;) {
|
|
222
|
+
const response = await api.commandRaw({ sandboxId, commandRequest: { command, cwd: options === null || options === void 0 ? void 0 : options.cwd, timeoutSeconds: options === null || options === void 0 ? void 0 : options.timeoutSeconds, stream: true } }, { signal: options === null || options === void 0 ? void 0 : options.signal });
|
|
223
|
+
let started = false;
|
|
224
|
+
let retry = false;
|
|
225
|
+
for await (const frame of ndjsonFrames(response.raw)) {
|
|
226
|
+
started = started || frame.type === 'started';
|
|
227
|
+
if (!started && frame.type === 'error' && frame.retryable === true && Date.now() < deadline) {
|
|
228
|
+
retry = true;
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
yield frame;
|
|
232
|
+
}
|
|
233
|
+
if (!retry)
|
|
234
|
+
return;
|
|
235
|
+
await delay(1000);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
@@ -387,12 +387,12 @@ export declare class BoatApi extends runtime.BaseAPI {
|
|
|
387
387
|
*/
|
|
388
388
|
commandRequestOpts(input: CommandOperationRequest | runtime.FlatBody<CommandOperationRequest, 'commandRequest'>): Promise<runtime.RequestOpts>;
|
|
389
389
|
/**
|
|
390
|
-
* Runs the command synchronously by default (timeout configurable via `timeoutSeconds`, 600s cap). With `detached: true` the command starts in the background and a process id is returned immediately; poll `/sandboxes/{sandboxId}/commands/{processId}` for status and logs. Returns 400 invalid_timeout when `timeoutSeconds` is not an integer in 1-600.
|
|
390
|
+
* Runs the command synchronously by default (timeout configurable via `timeoutSeconds`, 600s cap). With `detached: true` the command starts in the background and a process id is returned immediately; poll `/sandboxes/{sandboxId}/commands/{processId}` for status and logs. With `stream: true` the output arrives as the command writes it, as newline-delimited JSON (`application/x-ndjson`): `{\"type\":\"started\"}`, then `{\"type\":\"stdout\"|\"stderr\",\"data\":\"...\"}` per chunk, and last `{\"type\":\"exit\",...}` (the synchronous result without stdout/stderr) or `{\"type\":\"error\",\"error\":\"...\",\"message\":\"...\"}`. Returns 400 invalid_timeout when `timeoutSeconds` is not an integer in 1-600. A command sent while the sandbox is still starting (right after a resume) waits up to 60s for it to be ready instead of failing; 409 boat_starting (retryable) is returned only if it is still not ready by then. Command execution is never retried automatically: a 502 boat_direct_failed means the command may already be running on the sandbox.
|
|
391
391
|
* Execute a command in a sandbox
|
|
392
392
|
*/
|
|
393
393
|
commandRaw(requestParameters: CommandOperationRequest | runtime.FlatBody<CommandOperationRequest, 'commandRequest'>, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<Command200Response>>;
|
|
394
394
|
/**
|
|
395
|
-
* Runs the command synchronously by default (timeout configurable via `timeoutSeconds`, 600s cap). With `detached: true` the command starts in the background and a process id is returned immediately; poll `/sandboxes/{sandboxId}/commands/{processId}` for status and logs. Returns 400 invalid_timeout when `timeoutSeconds` is not an integer in 1-600.
|
|
395
|
+
* Runs the command synchronously by default (timeout configurable via `timeoutSeconds`, 600s cap). With `detached: true` the command starts in the background and a process id is returned immediately; poll `/sandboxes/{sandboxId}/commands/{processId}` for status and logs. With `stream: true` the output arrives as the command writes it, as newline-delimited JSON (`application/x-ndjson`): `{\"type\":\"started\"}`, then `{\"type\":\"stdout\"|\"stderr\",\"data\":\"...\"}` per chunk, and last `{\"type\":\"exit\",...}` (the synchronous result without stdout/stderr) or `{\"type\":\"error\",\"error\":\"...\",\"message\":\"...\"}`. Returns 400 invalid_timeout when `timeoutSeconds` is not an integer in 1-600. A command sent while the sandbox is still starting (right after a resume) waits up to 60s for it to be ready instead of failing; 409 boat_starting (retryable) is returned only if it is still not ready by then. Command execution is never retried automatically: a 502 boat_direct_failed means the command may already be running on the sandbox.
|
|
396
396
|
* Execute a command in a sandbox
|
|
397
397
|
*/
|
|
398
398
|
command(requestParameters: CommandOperationRequest | runtime.FlatBody<CommandOperationRequest, 'commandRequest'>, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<Command200Response>;
|
package/dist/esm/apis/BoatApi.js
CHANGED
|
@@ -295,7 +295,7 @@ export class BoatApi extends runtime.BaseAPI {
|
|
|
295
295
|
};
|
|
296
296
|
}
|
|
297
297
|
/**
|
|
298
|
-
* Runs the command synchronously by default (timeout configurable via `timeoutSeconds`, 600s cap). With `detached: true` the command starts in the background and a process id is returned immediately; poll `/sandboxes/{sandboxId}/commands/{processId}` for status and logs. Returns 400 invalid_timeout when `timeoutSeconds` is not an integer in 1-600.
|
|
298
|
+
* Runs the command synchronously by default (timeout configurable via `timeoutSeconds`, 600s cap). With `detached: true` the command starts in the background and a process id is returned immediately; poll `/sandboxes/{sandboxId}/commands/{processId}` for status and logs. With `stream: true` the output arrives as the command writes it, as newline-delimited JSON (`application/x-ndjson`): `{\"type\":\"started\"}`, then `{\"type\":\"stdout\"|\"stderr\",\"data\":\"...\"}` per chunk, and last `{\"type\":\"exit\",...}` (the synchronous result without stdout/stderr) or `{\"type\":\"error\",\"error\":\"...\",\"message\":\"...\"}`. Returns 400 invalid_timeout when `timeoutSeconds` is not an integer in 1-600. A command sent while the sandbox is still starting (right after a resume) waits up to 60s for it to be ready instead of failing; 409 boat_starting (retryable) is returned only if it is still not ready by then. Command execution is never retried automatically: a 502 boat_direct_failed means the command may already be running on the sandbox.
|
|
299
299
|
* Execute a command in a sandbox
|
|
300
300
|
*/
|
|
301
301
|
async commandRaw(requestParameters, initOverrides) {
|
|
@@ -304,7 +304,7 @@ export class BoatApi extends runtime.BaseAPI {
|
|
|
304
304
|
return new runtime.JSONApiResponse(response, (jsonValue) => Command200ResponseFromJSON(jsonValue));
|
|
305
305
|
}
|
|
306
306
|
/**
|
|
307
|
-
* Runs the command synchronously by default (timeout configurable via `timeoutSeconds`, 600s cap). With `detached: true` the command starts in the background and a process id is returned immediately; poll `/sandboxes/{sandboxId}/commands/{processId}` for status and logs. Returns 400 invalid_timeout when `timeoutSeconds` is not an integer in 1-600.
|
|
307
|
+
* Runs the command synchronously by default (timeout configurable via `timeoutSeconds`, 600s cap). With `detached: true` the command starts in the background and a process id is returned immediately; poll `/sandboxes/{sandboxId}/commands/{processId}` for status and logs. With `stream: true` the output arrives as the command writes it, as newline-delimited JSON (`application/x-ndjson`): `{\"type\":\"started\"}`, then `{\"type\":\"stdout\"|\"stderr\",\"data\":\"...\"}` per chunk, and last `{\"type\":\"exit\",...}` (the synchronous result without stdout/stderr) or `{\"type\":\"error\",\"error\":\"...\",\"message\":\"...\"}`. Returns 400 invalid_timeout when `timeoutSeconds` is not an integer in 1-600. A command sent while the sandbox is still starting (right after a resume) waits up to 60s for it to be ready instead of failing; 409 boat_starting (retryable) is returned only if it is still not ready by then. Command execution is never retried automatically: a 502 boat_direct_failed means the command may already be running on the sandbox.
|
|
308
308
|
* Execute a command in a sandbox
|
|
309
309
|
*/
|
|
310
310
|
async command(requestParameters, initOverrides) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BoatApi } from './apis/BoatApi';
|
|
2
|
-
import type { Sandbox, SandboxEvent, DesktopResponse, PromptRequest, PromptRun } from './models';
|
|
2
|
+
import type { Sandbox, SandboxEvent, DesktopResponse, PromptRequest, PromptRun, CommandStreamFrame } from './models';
|
|
3
3
|
export type WaitOptions = {
|
|
4
4
|
timeoutMs?: number;
|
|
5
5
|
intervalMs?: number;
|
|
@@ -54,3 +54,19 @@ export declare function stopAndRemove(api: BoatApi, sandboxId: string, options?:
|
|
|
54
54
|
export declare function readText(api: BoatApi, sandboxId: string, path: string): Promise<string>;
|
|
55
55
|
export declare function writeText(api: BoatApi, sandboxId: string, path: string, content: string): Promise<import("./models").FileWriteResponse>;
|
|
56
56
|
export declare function execCommand(api: BoatApi, sandboxId: string, command: string, cwd?: string, timeoutSeconds?: number): Promise<import("./models").Command200Response>;
|
|
57
|
+
/** One line of a streamed command, as sent (an `exit` frame also carries e.g. `signal`, `oomKilled`). */
|
|
58
|
+
export type CommandFrame = CommandStreamFrame & Record<string, unknown>;
|
|
59
|
+
export type StreamCommandOptions = {
|
|
60
|
+
cwd?: string;
|
|
61
|
+
timeoutSeconds?: number;
|
|
62
|
+
signal?: AbortSignal;
|
|
63
|
+
};
|
|
64
|
+
/**
|
|
65
|
+
* Run a command and yield its output as the command writes it: `started`, then
|
|
66
|
+
* `stdout`/`stderr` chunks (`frame.data`), then exactly one `exit` (`exitCode`,
|
|
67
|
+
* `timedOut`, ...) or `error` (`error`, `message`).
|
|
68
|
+
*
|
|
69
|
+
* Safe to call right after `resume()`, without waiting: the API holds a command
|
|
70
|
+
* sent to a starting sandbox for up to 60 s instead of refusing it.
|
|
71
|
+
*/
|
|
72
|
+
export declare function streamCommand(api: BoatApi, sandboxId: string, command: string, options?: StreamCommandOptions): AsyncGenerator<CommandFrame>;
|
package/dist/esm/boat-helpers.js
CHANGED
|
@@ -161,3 +161,63 @@ export async function writeText(api, sandboxId, path, content) {
|
|
|
161
161
|
export async function execCommand(api, sandboxId, command, cwd, timeoutSeconds = 30) {
|
|
162
162
|
return api.command({ sandboxId, commandRequest: { command, cwd, timeoutSeconds } });
|
|
163
163
|
}
|
|
164
|
+
// A refusal that provably never ran the command (the sandbox is still restoring
|
|
165
|
+
// its disk, `retryable: true` before `started`) is retried for this long.
|
|
166
|
+
const STREAM_RETRY_MS = 60000;
|
|
167
|
+
async function* ndjsonFrames(response) {
|
|
168
|
+
if (!response.body)
|
|
169
|
+
throw new Error('The command stream has no body');
|
|
170
|
+
const reader = response.body.getReader();
|
|
171
|
+
const decoder = new TextDecoder();
|
|
172
|
+
let buffered = '';
|
|
173
|
+
let done = false;
|
|
174
|
+
try {
|
|
175
|
+
while (!done) {
|
|
176
|
+
const chunk = await reader.read();
|
|
177
|
+
done = chunk.done;
|
|
178
|
+
buffered += done ? decoder.decode() : decoder.decode(chunk.value, { stream: true });
|
|
179
|
+
let newline = buffered.indexOf('\n');
|
|
180
|
+
while (newline !== -1) {
|
|
181
|
+
const line = buffered.slice(0, newline).trim();
|
|
182
|
+
buffered = buffered.slice(newline + 1);
|
|
183
|
+
if (line)
|
|
184
|
+
yield JSON.parse(line);
|
|
185
|
+
newline = buffered.indexOf('\n');
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (buffered.trim())
|
|
189
|
+
yield JSON.parse(buffered);
|
|
190
|
+
}
|
|
191
|
+
finally {
|
|
192
|
+
// The caller stopped early: drop the connection instead of reading the rest.
|
|
193
|
+
if (!done)
|
|
194
|
+
await reader.cancel().catch(() => undefined);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Run a command and yield its output as the command writes it: `started`, then
|
|
199
|
+
* `stdout`/`stderr` chunks (`frame.data`), then exactly one `exit` (`exitCode`,
|
|
200
|
+
* `timedOut`, ...) or `error` (`error`, `message`).
|
|
201
|
+
*
|
|
202
|
+
* Safe to call right after `resume()`, without waiting: the API holds a command
|
|
203
|
+
* sent to a starting sandbox for up to 60 s instead of refusing it.
|
|
204
|
+
*/
|
|
205
|
+
export async function* streamCommand(api, sandboxId, command, options) {
|
|
206
|
+
const deadline = Date.now() + STREAM_RETRY_MS;
|
|
207
|
+
for (;;) {
|
|
208
|
+
const response = await api.commandRaw({ sandboxId, commandRequest: { command, cwd: options === null || options === void 0 ? void 0 : options.cwd, timeoutSeconds: options === null || options === void 0 ? void 0 : options.timeoutSeconds, stream: true } }, { signal: options === null || options === void 0 ? void 0 : options.signal });
|
|
209
|
+
let started = false;
|
|
210
|
+
let retry = false;
|
|
211
|
+
for await (const frame of ndjsonFrames(response.raw)) {
|
|
212
|
+
started = started || frame.type === 'started';
|
|
213
|
+
if (!started && frame.type === 'error' && frame.retryable === true && Date.now() < deadline) {
|
|
214
|
+
retry = true;
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
yield frame;
|
|
218
|
+
}
|
|
219
|
+
if (!retry)
|
|
220
|
+
return;
|
|
221
|
+
await delay(1000);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
@@ -39,6 +39,12 @@ export interface CommandRequest {
|
|
|
39
39
|
* @memberof CommandRequest
|
|
40
40
|
*/
|
|
41
41
|
detached?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Stream the output as the command writes it: the response is newline-delimited JSON (application/x-ndjson), one CommandStreamFrame per line. Ignored with detached.
|
|
44
|
+
* @type {boolean}
|
|
45
|
+
* @memberof CommandRequest
|
|
46
|
+
*/
|
|
47
|
+
stream?: boolean;
|
|
42
48
|
}
|
|
43
49
|
/**
|
|
44
50
|
* Check if a given object implements the CommandRequest interface.
|
|
@@ -31,6 +31,7 @@ export function CommandRequestFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
31
31
|
'cwd': json['cwd'] == null ? undefined : json['cwd'],
|
|
32
32
|
'timeoutSeconds': json['timeoutSeconds'] == null ? undefined : json['timeoutSeconds'],
|
|
33
33
|
'detached': json['detached'] == null ? undefined : json['detached'],
|
|
34
|
+
'stream': json['stream'] == null ? undefined : json['stream'],
|
|
34
35
|
};
|
|
35
36
|
}
|
|
36
37
|
export function CommandRequestToJSON(json) {
|
|
@@ -45,5 +46,6 @@ export function CommandRequestToJSONTyped(value, ignoreDiscriminator = false) {
|
|
|
45
46
|
'cwd': value['cwd'],
|
|
46
47
|
'timeoutSeconds': value['timeoutSeconds'],
|
|
47
48
|
'detached': value['detached'],
|
|
49
|
+
'stream': value['stream'],
|
|
48
50
|
};
|
|
49
51
|
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boat Public API v1
|
|
3
|
+
* Public JSON API for creating, operating, prompting, observing, and exposing sandboxes from backend services, CI jobs, hosted workers, and Boat automation products. The v1 reference intentionally documents the developer integration surface only. Dashboard billing actions are not part of v1.
|
|
4
|
+
*
|
|
5
|
+
* The version of the OpenAPI document: 1.0.0
|
|
6
|
+
*
|
|
7
|
+
*
|
|
8
|
+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
|
9
|
+
* https://openapi-generator.tech
|
|
10
|
+
* Do not edit the class manually.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* One line of a streamed command. `started` first, then `stdout`/`stderr` chunks, then exactly one `exit` (the synchronous result, without stdout/stderr) or `error`.
|
|
14
|
+
* @export
|
|
15
|
+
* @interface CommandStreamFrame
|
|
16
|
+
*/
|
|
17
|
+
export interface CommandStreamFrame {
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @type {CommandStreamFrameTypeEnum}
|
|
21
|
+
* @memberof CommandStreamFrame
|
|
22
|
+
*/
|
|
23
|
+
type: CommandStreamFrameTypeEnum;
|
|
24
|
+
/**
|
|
25
|
+
* stdout/stderr: the chunk of output, UTF-8.
|
|
26
|
+
* @type {string}
|
|
27
|
+
* @memberof CommandStreamFrame
|
|
28
|
+
*/
|
|
29
|
+
data?: string;
|
|
30
|
+
/**
|
|
31
|
+
*
|
|
32
|
+
* @type {number}
|
|
33
|
+
* @memberof CommandStreamFrame
|
|
34
|
+
*/
|
|
35
|
+
exitCode?: number | null;
|
|
36
|
+
/**
|
|
37
|
+
*
|
|
38
|
+
* @type {boolean}
|
|
39
|
+
* @memberof CommandStreamFrame
|
|
40
|
+
*/
|
|
41
|
+
success?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
*
|
|
44
|
+
* @type {boolean}
|
|
45
|
+
* @memberof CommandStreamFrame
|
|
46
|
+
*/
|
|
47
|
+
timedOut?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
*
|
|
50
|
+
* @type {string}
|
|
51
|
+
* @memberof CommandStreamFrame
|
|
52
|
+
*/
|
|
53
|
+
error?: string;
|
|
54
|
+
/**
|
|
55
|
+
*
|
|
56
|
+
* @type {string}
|
|
57
|
+
* @memberof CommandStreamFrame
|
|
58
|
+
*/
|
|
59
|
+
message?: string;
|
|
60
|
+
/**
|
|
61
|
+
* error: true when the command provably never ran (the sandbox is still restoring its disk), so sending it again is safe.
|
|
62
|
+
* @type {boolean}
|
|
63
|
+
* @memberof CommandStreamFrame
|
|
64
|
+
*/
|
|
65
|
+
retryable?: boolean;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* @export
|
|
69
|
+
*/
|
|
70
|
+
export declare const CommandStreamFrameTypeEnum: {
|
|
71
|
+
readonly Started: 'started';
|
|
72
|
+
readonly Stdout: 'stdout';
|
|
73
|
+
readonly Stderr: 'stderr';
|
|
74
|
+
readonly Exit: 'exit';
|
|
75
|
+
readonly Error: 'error';
|
|
76
|
+
};
|
|
77
|
+
export type CommandStreamFrameTypeEnum = typeof CommandStreamFrameTypeEnum[keyof typeof CommandStreamFrameTypeEnum];
|
|
78
|
+
/**
|
|
79
|
+
* Check if a given object implements the CommandStreamFrame interface.
|
|
80
|
+
*/
|
|
81
|
+
export declare function instanceOfCommandStreamFrame(value: object): value is CommandStreamFrame;
|
|
82
|
+
export declare function CommandStreamFrameFromJSON(json: any): CommandStreamFrame;
|
|
83
|
+
export declare function CommandStreamFrameFromJSONTyped(json: any, ignoreDiscriminator: boolean): CommandStreamFrame;
|
|
84
|
+
export declare function CommandStreamFrameToJSON(json: any): CommandStreamFrame;
|
|
85
|
+
export declare function CommandStreamFrameToJSONTyped(value?: CommandStreamFrame | null, ignoreDiscriminator?: boolean): any;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
/**
|
|
4
|
+
* Boat Public API v1
|
|
5
|
+
* Public JSON API for creating, operating, prompting, observing, and exposing sandboxes from backend services, CI jobs, hosted workers, and Boat automation products. The v1 reference intentionally documents the developer integration surface only. Dashboard billing actions are not part of v1.
|
|
6
|
+
*
|
|
7
|
+
* The version of the OpenAPI document: 1.0.0
|
|
8
|
+
*
|
|
9
|
+
*
|
|
10
|
+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
|
|
11
|
+
* https://openapi-generator.tech
|
|
12
|
+
* Do not edit the class manually.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* @export
|
|
16
|
+
*/
|
|
17
|
+
export const CommandStreamFrameTypeEnum = {
|
|
18
|
+
Started: 'started',
|
|
19
|
+
Stdout: 'stdout',
|
|
20
|
+
Stderr: 'stderr',
|
|
21
|
+
Exit: 'exit',
|
|
22
|
+
Error: 'error'
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Check if a given object implements the CommandStreamFrame interface.
|
|
26
|
+
*/
|
|
27
|
+
export function instanceOfCommandStreamFrame(value) {
|
|
28
|
+
if (!('type' in value) || value['type'] === undefined)
|
|
29
|
+
return false;
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
export function CommandStreamFrameFromJSON(json) {
|
|
33
|
+
return CommandStreamFrameFromJSONTyped(json, false);
|
|
34
|
+
}
|
|
35
|
+
export function CommandStreamFrameFromJSONTyped(json, ignoreDiscriminator) {
|
|
36
|
+
if (json == null) {
|
|
37
|
+
return json;
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
'type': json['type'],
|
|
41
|
+
'data': json['data'] == null ? undefined : json['data'],
|
|
42
|
+
'exitCode': json['exitCode'] == null ? undefined : json['exitCode'],
|
|
43
|
+
'success': json['success'] == null ? undefined : json['success'],
|
|
44
|
+
'timedOut': json['timedOut'] == null ? undefined : json['timedOut'],
|
|
45
|
+
'error': json['error'] == null ? undefined : json['error'],
|
|
46
|
+
'message': json['message'] == null ? undefined : json['message'],
|
|
47
|
+
'retryable': json['retryable'] == null ? undefined : json['retryable'],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
export function CommandStreamFrameToJSON(json) {
|
|
51
|
+
return CommandStreamFrameToJSONTyped(json, false);
|
|
52
|
+
}
|
|
53
|
+
export function CommandStreamFrameToJSONTyped(value, ignoreDiscriminator = false) {
|
|
54
|
+
if (value == null) {
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
'type': value['type'],
|
|
59
|
+
'data': value['data'],
|
|
60
|
+
'exitCode': value['exitCode'],
|
|
61
|
+
'success': value['success'],
|
|
62
|
+
'timedOut': value['timedOut'],
|
|
63
|
+
'error': value['error'],
|
|
64
|
+
'message': value['message'],
|
|
65
|
+
'retryable': value['retryable'],
|
|
66
|
+
};
|
|
67
|
+
}
|
|
@@ -47,6 +47,18 @@ export interface CreateSandboxRequest {
|
|
|
47
47
|
* @memberof CreateSandboxRequest
|
|
48
48
|
*/
|
|
49
49
|
noEnv?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Pass `false` to never snapshot this sandbox. Nothing is captured in the background, so it pays no CPU or memory for it, and stopping it erases its disk the way zero data retention does. It cannot be resumed, forked, or saved as a named snapshot, and if its machine fails there is no backup to rebuild it from.
|
|
52
|
+
* @type {boolean}
|
|
53
|
+
* @memberof CreateSandboxRequest
|
|
54
|
+
*/
|
|
55
|
+
snapshots?: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Pass `true` to get a sandbox only if a machine of this type is ready right now. The call answers within about 1.5 s: either the usual `202` with the sandbox, or `503` `no_ready_machine` with nothing created, billed, or counted against your start limits, so you can retry or fall back at once. Without it, a create waits for a machine to be built when none is ready. Not combinable with `from`.
|
|
58
|
+
* @type {boolean}
|
|
59
|
+
* @memberof CreateSandboxRequest
|
|
60
|
+
*/
|
|
61
|
+
failFast?: boolean;
|
|
50
62
|
/**
|
|
51
63
|
* Shell script that runs on the sandbox after it is ready. Ready means "ready to accept the user", not "setup done": the script starts in the background once provisioning completes and never blocks the sandbox becoming usable. It runs as the sandbox user via `bash`, with the sandbox's environment applied, and its output goes to a log file on the sandbox. Observe the outcome as `setupStatus` (pending/running/done/failed) and `setupError` on the sandbox. Rejected with a 400 `invalid_setup_script` error when it is not a string or exceeds 64KB.
|
|
52
64
|
* @type {string}
|
|
@@ -38,6 +38,8 @@ export function CreateSandboxRequestFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
38
38
|
'env': json['env'] == null ? undefined : json['env'],
|
|
39
39
|
'environment': json['environment'] == null ? undefined : json['environment'],
|
|
40
40
|
'noEnv': json['noEnv'] == null ? undefined : json['noEnv'],
|
|
41
|
+
'snapshots': json['snapshots'] == null ? undefined : json['snapshots'],
|
|
42
|
+
'failFast': json['failFast'] == null ? undefined : json['failFast'],
|
|
41
43
|
'setupScript': json['setupScript'] == null ? undefined : json['setupScript'],
|
|
42
44
|
'org': json['org'] == null ? undefined : json['org'],
|
|
43
45
|
'teamId': json['teamId'] == null ? undefined : json['teamId'],
|
|
@@ -57,6 +59,8 @@ export function CreateSandboxRequestToJSONTyped(value, ignoreDiscriminator = fal
|
|
|
57
59
|
'env': value['env'],
|
|
58
60
|
'environment': value['environment'],
|
|
59
61
|
'noEnv': value['noEnv'],
|
|
62
|
+
'snapshots': value['snapshots'],
|
|
63
|
+
'failFast': value['failFast'],
|
|
60
64
|
'setupScript': value['setupScript'],
|
|
61
65
|
'org': value['org'],
|
|
62
66
|
'teamId': value['teamId'],
|
|
@@ -51,6 +51,18 @@ export interface DataRetentionPolicyResponse {
|
|
|
51
51
|
* @memberof DataRetentionPolicyResponse
|
|
52
52
|
*/
|
|
53
53
|
acceptedDeletionOperationsIrreversible?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* When true, every new sandbox of this account is created with snapshots off.
|
|
56
|
+
* @type {boolean}
|
|
57
|
+
* @memberof DataRetentionPolicyResponse
|
|
58
|
+
*/
|
|
59
|
+
snapshotsOff?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
*
|
|
62
|
+
* @type {Date}
|
|
63
|
+
* @memberof DataRetentionPolicyResponse
|
|
64
|
+
*/
|
|
65
|
+
snapshotsOffAt?: Date | null;
|
|
54
66
|
}
|
|
55
67
|
/**
|
|
56
68
|
* @export
|
|
@@ -46,6 +46,8 @@ export function DataRetentionPolicyResponseFromJSONTyped(json, ignoreDiscriminat
|
|
|
46
46
|
'enabledAt': (json['enabledAt'] == null ? null : new Date(json['enabledAt'])),
|
|
47
47
|
'queuedSandboxes': json['queuedSandboxes'] == null ? undefined : json['queuedSandboxes'],
|
|
48
48
|
'acceptedDeletionOperationsIrreversible': json['acceptedDeletionOperationsIrreversible'] == null ? undefined : json['acceptedDeletionOperationsIrreversible'],
|
|
49
|
+
'snapshotsOff': json['snapshotsOff'] == null ? undefined : json['snapshotsOff'],
|
|
50
|
+
'snapshotsOffAt': json['snapshotsOffAt'] == null ? undefined : (new Date(json['snapshotsOffAt'])),
|
|
49
51
|
};
|
|
50
52
|
}
|
|
51
53
|
export function DataRetentionPolicyResponseToJSON(json) {
|
|
@@ -62,5 +64,7 @@ export function DataRetentionPolicyResponseToJSONTyped(value, ignoreDiscriminato
|
|
|
62
64
|
'enabledAt': value['enabledAt'] == null ? value['enabledAt'] : value['enabledAt'].toISOString(),
|
|
63
65
|
'queuedSandboxes': value['queuedSandboxes'],
|
|
64
66
|
'acceptedDeletionOperationsIrreversible': value['acceptedDeletionOperationsIrreversible'],
|
|
67
|
+
'snapshotsOff': value['snapshotsOff'],
|
|
68
|
+
'snapshotsOffAt': value['snapshotsOffAt'] == null ? value['snapshotsOffAt'] : value['snapshotsOffAt'].toISOString(),
|
|
65
69
|
};
|
|
66
70
|
}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* Do not edit the class manually.
|
|
11
11
|
*/
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* Pass `enabled` to change zero data retention, or `snapshotsOff` alone to change the account's snapshots-off setting.
|
|
14
14
|
* @export
|
|
15
15
|
* @interface DataRetentionUpdateRequest
|
|
16
16
|
*/
|
|
@@ -20,7 +20,13 @@ export interface DataRetentionUpdateRequest {
|
|
|
20
20
|
* @type {boolean}
|
|
21
21
|
* @memberof DataRetentionUpdateRequest
|
|
22
22
|
*/
|
|
23
|
-
enabled
|
|
23
|
+
enabled?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Turn snapshots off for every sandbox created from now on. Existing sandboxes keep their setting. While on, a create or fork that passes `snapshots: true` is refused with 409 `snapshots_off_for_account`.
|
|
26
|
+
* @type {boolean}
|
|
27
|
+
* @memberof DataRetentionUpdateRequest
|
|
28
|
+
*/
|
|
29
|
+
snapshotsOff?: boolean;
|
|
24
30
|
/**
|
|
25
31
|
* Required when enabling and must exactly equal `delete archived sandbox data`.
|
|
26
32
|
* @type {DataRetentionUpdateRequestConfirmationEnum}
|
|
@@ -21,8 +21,6 @@ export const DataRetentionUpdateRequestConfirmationEnum = {
|
|
|
21
21
|
* Check if a given object implements the DataRetentionUpdateRequest interface.
|
|
22
22
|
*/
|
|
23
23
|
export function instanceOfDataRetentionUpdateRequest(value) {
|
|
24
|
-
if (!('enabled' in value) || value['enabled'] === undefined)
|
|
25
|
-
return false;
|
|
26
24
|
return true;
|
|
27
25
|
}
|
|
28
26
|
export function DataRetentionUpdateRequestFromJSON(json) {
|
|
@@ -33,7 +31,8 @@ export function DataRetentionUpdateRequestFromJSONTyped(json, ignoreDiscriminato
|
|
|
33
31
|
return json;
|
|
34
32
|
}
|
|
35
33
|
return {
|
|
36
|
-
'enabled': json['enabled'],
|
|
34
|
+
'enabled': json['enabled'] == null ? undefined : json['enabled'],
|
|
35
|
+
'snapshotsOff': json['snapshotsOff'] == null ? undefined : json['snapshotsOff'],
|
|
37
36
|
'confirmation': json['confirmation'] == null ? undefined : json['confirmation'],
|
|
38
37
|
};
|
|
39
38
|
}
|
|
@@ -46,6 +45,7 @@ export function DataRetentionUpdateRequestToJSONTyped(value, ignoreDiscriminator
|
|
|
46
45
|
}
|
|
47
46
|
return {
|
|
48
47
|
'enabled': value['enabled'],
|
|
48
|
+
'snapshotsOff': value['snapshotsOff'],
|
|
49
49
|
'confirmation': value['confirmation'],
|
|
50
50
|
};
|
|
51
51
|
}
|
|
@@ -118,6 +118,12 @@ export interface Sandbox {
|
|
|
118
118
|
* @memberof Sandbox
|
|
119
119
|
*/
|
|
120
120
|
desktopUrl?: string | null;
|
|
121
|
+
/**
|
|
122
|
+
* False when the sandbox was created with snapshots off.
|
|
123
|
+
* @type {boolean}
|
|
124
|
+
* @memberof Sandbox
|
|
125
|
+
*/
|
|
126
|
+
snapshots?: boolean;
|
|
121
127
|
/**
|
|
122
128
|
*
|
|
123
129
|
* @type {boolean}
|