@boatdev/sdk 1.9.7 → 1.9.8
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 +4 -0
- package/README.md +2 -2
- package/dist/apis/BoatApi.d.ts +2 -2
- package/dist/apis/BoatApi.js +2 -2
- package/dist/boat-helpers.d.ts +23 -0
- package/dist/boat-helpers.js +97 -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 +23 -0
- package/dist/esm/boat-helpers.js +95 -0
- package/dist/esm/models/CredentialProfile.d.ts +1 -1
- package/dist/esm/models/DeletionOperation.d.ts +1 -3
- package/dist/esm/models/DeletionOperation.js +0 -2
- package/dist/esm/models/LimitsFields.d.ts +7 -0
- package/dist/esm/models/LimitsFields.js +3 -0
- package/dist/esm/models/LimitsFieldsMachineTypesInner.d.ts +54 -0
- package/dist/esm/models/LimitsFieldsMachineTypesInner.js +60 -0
- package/dist/esm/models/LimitsResponse.d.ts +7 -0
- package/dist/esm/models/LimitsResponse.js +3 -0
- package/dist/esm/models/Sandbox.d.ts +15 -2
- package/dist/esm/models/Sandbox.js +5 -0
- package/dist/esm/models/SandboxHydration.d.ts +50 -0
- package/dist/esm/models/SandboxHydration.js +55 -0
- package/dist/esm/models/index.d.ts +2 -0
- package/dist/esm/models/index.js +2 -0
- package/dist/models/CredentialProfile.d.ts +1 -1
- package/dist/models/DeletionOperation.d.ts +1 -3
- package/dist/models/DeletionOperation.js +0 -2
- package/dist/models/LimitsFields.d.ts +7 -0
- package/dist/models/LimitsFields.js +3 -0
- package/dist/models/LimitsFieldsMachineTypesInner.d.ts +54 -0
- package/dist/models/LimitsFieldsMachineTypesInner.js +68 -0
- package/dist/models/LimitsResponse.d.ts +7 -0
- package/dist/models/LimitsResponse.js +3 -0
- package/dist/models/Sandbox.d.ts +15 -2
- package/dist/models/Sandbox.js +5 -0
- package/dist/models/SandboxHydration.d.ts +50 -0
- package/dist/models/SandboxHydration.js +62 -0
- package/dist/models/index.d.ts +2 -0
- package/dist/models/index.js +2 -0
- package/docs/BoatApi.md +1 -1
- package/docs/LimitsFields.md +2 -0
- package/docs/LimitsFieldsMachineTypesInner.md +36 -0
- package/docs/LimitsResponse.md +2 -0
- package/docs/Sandbox.md +4 -0
- package/docs/SandboxHydration.md +39 -0
- package/package.json +2 -2
- package/src/apis/BoatApi.ts +2 -2
- package/src/boat-helpers.ts +109 -0
- package/src/models/CredentialProfile.ts +1 -1
- package/src/models/DeletionOperation.ts +1 -3
- package/src/models/LimitsFields.ts +15 -0
- package/src/models/LimitsFieldsMachineTypesInner.ts +97 -0
- package/src/models/LimitsResponse.ts +15 -0
- package/src/models/Sandbox.ts +25 -2
- package/src/models/SandboxHydration.ts +93 -0
- package/src/models/index.ts +2 -0
package/.openapi-generator/FILES
CHANGED
|
@@ -77,6 +77,7 @@ docs/HostPortResponse.md
|
|
|
77
77
|
docs/LimitsFields.md
|
|
78
78
|
docs/LimitsFieldsCurrentLimits.md
|
|
79
79
|
docs/LimitsFieldsGiftLimit.md
|
|
80
|
+
docs/LimitsFieldsMachineTypesInner.md
|
|
80
81
|
docs/LimitsFieldsSandboxPlanTiersInner.md
|
|
81
82
|
docs/LimitsFieldsStartLimits.md
|
|
82
83
|
docs/LimitsFieldsStarts.md
|
|
@@ -126,6 +127,7 @@ docs/SandboxEnvironmentListResponse.md
|
|
|
126
127
|
docs/SandboxEnvironmentResponse.md
|
|
127
128
|
docs/SandboxEnvironmentVersionSummary.md
|
|
128
129
|
docs/SandboxEvent.md
|
|
130
|
+
docs/SandboxHydration.md
|
|
129
131
|
docs/SandboxInfoResponse.md
|
|
130
132
|
docs/SandboxListResponse.md
|
|
131
133
|
docs/SandboxProcess.md
|
|
@@ -263,6 +265,7 @@ src/models/HostPortResponse.ts
|
|
|
263
265
|
src/models/LimitsFields.ts
|
|
264
266
|
src/models/LimitsFieldsCurrentLimits.ts
|
|
265
267
|
src/models/LimitsFieldsGiftLimit.ts
|
|
268
|
+
src/models/LimitsFieldsMachineTypesInner.ts
|
|
266
269
|
src/models/LimitsFieldsSandboxPlanTiersInner.ts
|
|
267
270
|
src/models/LimitsFieldsStartLimits.ts
|
|
268
271
|
src/models/LimitsFieldsStarts.ts
|
|
@@ -312,6 +315,7 @@ src/models/SandboxEnvironmentListResponse.ts
|
|
|
312
315
|
src/models/SandboxEnvironmentResponse.ts
|
|
313
316
|
src/models/SandboxEnvironmentVersionSummary.ts
|
|
314
317
|
src/models/SandboxEvent.ts
|
|
318
|
+
src/models/SandboxHydration.ts
|
|
315
319
|
src/models/SandboxInfoResponse.ts
|
|
316
320
|
src/models/SandboxListResponse.ts
|
|
317
321
|
src/models/SandboxProcess.ts
|
package/README.md
CHANGED
|
@@ -10,8 +10,8 @@ npm install @boatdev/sdk
|
|
|
10
10
|
|
|
11
11
|
## Links
|
|
12
12
|
|
|
13
|
-
- SDK docs: https://docs.boat.dev/sdks
|
|
14
|
-
- API reference: https://docs.boat.dev/api/
|
|
13
|
+
- SDK docs: https://docs.boat.dev/sdks/overview
|
|
14
|
+
- API reference: https://docs.boat.dev/api/v1
|
|
15
15
|
- Dashboard: https://boat.dev/dashboard
|
|
16
16
|
- API keys: https://boat.dev/dashboard?tab=api-keys
|
|
17
17
|
|
package/dist/apis/BoatApi.d.ts
CHANGED
|
@@ -1281,12 +1281,12 @@ export declare class BoatApi extends runtime.BaseAPI {
|
|
|
1281
1281
|
*/
|
|
1282
1282
|
listCredentialAccountsRequestOpts(requestParameters: ListCredentialAccountsRequest): Promise<runtime.RequestOpts>;
|
|
1283
1283
|
/**
|
|
1284
|
-
* Every account of one credential (several ChatGPT sign-ins, several OpenAI keys), in the order they were added, the one in use marked. Labels only, never a secret. Needs an API key with `account.admin`.
|
|
1284
|
+
* Every account of one credential (several ChatGPT sign-ins, several OpenAI keys), in the order they were added, the one in use marked. Labels only, never a secret. Needs an API key with `account.admin`, on a profile you manage: an org member who only uses an org profile gets `403`.
|
|
1285
1285
|
* List the accounts of a credential
|
|
1286
1286
|
*/
|
|
1287
1287
|
listCredentialAccountsRaw(requestParameters: ListCredentialAccountsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<CredentialAccountsResponse>>;
|
|
1288
1288
|
/**
|
|
1289
|
-
* Every account of one credential (several ChatGPT sign-ins, several OpenAI keys), in the order they were added, the one in use marked. Labels only, never a secret. Needs an API key with `account.admin`.
|
|
1289
|
+
* Every account of one credential (several ChatGPT sign-ins, several OpenAI keys), in the order they were added, the one in use marked. Labels only, never a secret. Needs an API key with `account.admin`, on a profile you manage: an org member who only uses an org profile gets `403`.
|
|
1290
1290
|
* List the accounts of a credential
|
|
1291
1291
|
*/
|
|
1292
1292
|
listCredentialAccounts(requestParameters: ListCredentialAccountsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<CredentialAccountsResponse>;
|
package/dist/apis/BoatApi.js
CHANGED
|
@@ -2716,7 +2716,7 @@ class BoatApi extends runtime.BaseAPI {
|
|
|
2716
2716
|
};
|
|
2717
2717
|
}
|
|
2718
2718
|
/**
|
|
2719
|
-
* Every account of one credential (several ChatGPT sign-ins, several OpenAI keys), in the order they were added, the one in use marked. Labels only, never a secret. Needs an API key with `account.admin`.
|
|
2719
|
+
* Every account of one credential (several ChatGPT sign-ins, several OpenAI keys), in the order they were added, the one in use marked. Labels only, never a secret. Needs an API key with `account.admin`, on a profile you manage: an org member who only uses an org profile gets `403`.
|
|
2720
2720
|
* List the accounts of a credential
|
|
2721
2721
|
*/
|
|
2722
2722
|
async listCredentialAccountsRaw(requestParameters, initOverrides) {
|
|
@@ -2725,7 +2725,7 @@ class BoatApi extends runtime.BaseAPI {
|
|
|
2725
2725
|
return new runtime.JSONApiResponse(response, (jsonValue) => (0, CredentialAccountsResponse_1.CredentialAccountsResponseFromJSON)(jsonValue));
|
|
2726
2726
|
}
|
|
2727
2727
|
/**
|
|
2728
|
-
* Every account of one credential (several ChatGPT sign-ins, several OpenAI keys), in the order they were added, the one in use marked. Labels only, never a secret. Needs an API key with `account.admin`.
|
|
2728
|
+
* Every account of one credential (several ChatGPT sign-ins, several OpenAI keys), in the order they were added, the one in use marked. Labels only, never a secret. Needs an API key with `account.admin`, on a profile you manage: an org member who only uses an org profile gets `403`.
|
|
2729
2729
|
* List the accounts of a credential
|
|
2730
2730
|
*/
|
|
2731
2731
|
async listCredentialAccounts(requestParameters, initOverrides) {
|
package/dist/boat-helpers.d.ts
CHANGED
|
@@ -76,3 +76,26 @@ export type StreamCommandOptions = {
|
|
|
76
76
|
* sent to a starting sandbox for up to 60 s instead of refusing it.
|
|
77
77
|
*/
|
|
78
78
|
export declare function streamCommand(api: BoatApi, sandboxId: string, command: string, options?: StreamCommandOptions): AsyncGenerator<CommandFrame>;
|
|
79
|
+
export type FollowCommandOptions = {
|
|
80
|
+
signal?: AbortSignal;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Yield a detached command's output from its start until it ends: `stdout`/`stderr`
|
|
84
|
+
* chunks (`frame.data`), then exactly one `exit` (`exitCode`, ...) or `error`
|
|
85
|
+
* (`message`). The server ends each connection after 10 minutes; this reconnects
|
|
86
|
+
* from the same offsets, with no gap and no repeat. A network cut is reconnected
|
|
87
|
+
* the same way for up to 60 s.
|
|
88
|
+
*/
|
|
89
|
+
export declare function followCommand(api: BoatApi, sandboxId: string, processId: number, options?: FollowCommandOptions): AsyncGenerator<CommandFrame>;
|
|
90
|
+
export type RunCommandOptions = FollowCommandOptions & {
|
|
91
|
+
cwd?: string;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Run a command with no time limit and yield its output until it ends.
|
|
95
|
+
*
|
|
96
|
+
* The command runs detached, so it has no 600 s cap and survives a dropped
|
|
97
|
+
* connection. Frames: `{ type: 'started', processId }`, then the frames of
|
|
98
|
+
* `followCommand`. Stopping early leaves the command running: call
|
|
99
|
+
* `stopCommand({ sandboxId, processId })` to stop it.
|
|
100
|
+
*/
|
|
101
|
+
export declare function runCommand(api: BoatApi, sandboxId: string, command: string, options?: RunCommandOptions): AsyncGenerator<CommandFrame>;
|
package/dist/boat-helpers.js
CHANGED
|
@@ -12,6 +12,8 @@ exports.readText = readText;
|
|
|
12
12
|
exports.writeText = writeText;
|
|
13
13
|
exports.execCommand = execCommand;
|
|
14
14
|
exports.streamCommand = streamCommand;
|
|
15
|
+
exports.followCommand = followCommand;
|
|
16
|
+
exports.runCommand = runCommand;
|
|
15
17
|
const terminalPromptStatuses = new Set(['finished', 'failed']);
|
|
16
18
|
function delay(ms) {
|
|
17
19
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -259,3 +261,98 @@ async function* streamCommand(api, sandboxId, command, options) {
|
|
|
259
261
|
await delay(1000);
|
|
260
262
|
}
|
|
261
263
|
}
|
|
264
|
+
// The server sends a heartbeat every 15 s, so 60 s of silence is a dead connection.
|
|
265
|
+
const ATTACH_IDLE_MS = 60000;
|
|
266
|
+
// After the first connection, a failed reconnect is tried again for this long.
|
|
267
|
+
const ATTACH_RETRY_MS = 60000;
|
|
268
|
+
function isNetworkError(e, signal) {
|
|
269
|
+
if ((signal === null || signal === void 0 ? void 0 : signal.aborted) || e instanceof SyntaxError)
|
|
270
|
+
return false;
|
|
271
|
+
return !(e === null || e === void 0 ? void 0 : e.response);
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Yield a detached command's output from its start until it ends: `stdout`/`stderr`
|
|
275
|
+
* chunks (`frame.data`), then exactly one `exit` (`exitCode`, ...) or `error`
|
|
276
|
+
* (`message`). The server ends each connection after 10 minutes; this reconnects
|
|
277
|
+
* from the same offsets, with no gap and no repeat. A network cut is reconnected
|
|
278
|
+
* the same way for up to 60 s.
|
|
279
|
+
*/
|
|
280
|
+
async function* followCommand(api, sandboxId, processId, options) {
|
|
281
|
+
var _a, _b, _c;
|
|
282
|
+
var _d, _e, _f, _g;
|
|
283
|
+
const offsets = { stdout: 0, stderr: 0 };
|
|
284
|
+
let connected = false;
|
|
285
|
+
// Set at the first failure after a good connection; any good connection clears it.
|
|
286
|
+
let failingSince;
|
|
287
|
+
for (;;) {
|
|
288
|
+
if ((_a = options === null || options === void 0 ? void 0 : options.signal) === null || _a === void 0 ? void 0 : _a.aborted)
|
|
289
|
+
throw (_d = options.signal.reason) !== null && _d !== void 0 ? _d : new Error('followCommand aborted');
|
|
290
|
+
// One controller per connection: the caller's signal, or 60 s with no line.
|
|
291
|
+
const connection = new AbortController();
|
|
292
|
+
const abort = () => connection.abort();
|
|
293
|
+
(_b = options === null || options === void 0 ? void 0 : options.signal) === null || _b === void 0 ? void 0 : _b.addEventListener('abort', abort);
|
|
294
|
+
let idle;
|
|
295
|
+
const touch = () => {
|
|
296
|
+
clearTimeout(idle);
|
|
297
|
+
idle = setTimeout(abort, ATTACH_IDLE_MS);
|
|
298
|
+
};
|
|
299
|
+
try {
|
|
300
|
+
touch();
|
|
301
|
+
const response = await api.attachCommandRaw({ sandboxId, processId, stdoutOffset: offsets.stdout, stderrOffset: offsets.stderr }, { signal: connection.signal });
|
|
302
|
+
connected = true;
|
|
303
|
+
failingSince = undefined;
|
|
304
|
+
for await (const frame of ndjsonFrames(response.raw)) {
|
|
305
|
+
touch();
|
|
306
|
+
if (frame.type === 'stdout' || frame.type === 'stderr') {
|
|
307
|
+
offsets[frame.type] = (_e = frame.nextOffset) !== null && _e !== void 0 ? _e : offsets[frame.type];
|
|
308
|
+
yield frame;
|
|
309
|
+
}
|
|
310
|
+
else if (frame.type === 'exit' || frame.type === 'error') {
|
|
311
|
+
yield frame;
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
// attached, heartbeat, reconnect: ours to handle, never the caller's.
|
|
316
|
+
offsets.stdout = (_f = frame.stdoutOffset) !== null && _f !== void 0 ? _f : offsets.stdout;
|
|
317
|
+
offsets.stderr = (_g = frame.stderrOffset) !== null && _g !== void 0 ? _g : offsets.stderr;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
catch (e) {
|
|
322
|
+
failingSince !== null && failingSince !== void 0 ? failingSince : (failingSince = Date.now());
|
|
323
|
+
if (!isNetworkError(e, options === null || options === void 0 ? void 0 : options.signal) || !connected || Date.now() - failingSince >= ATTACH_RETRY_MS)
|
|
324
|
+
throw e;
|
|
325
|
+
await delay(1000);
|
|
326
|
+
}
|
|
327
|
+
finally {
|
|
328
|
+
clearTimeout(idle);
|
|
329
|
+
(_c = options === null || options === void 0 ? void 0 : options.signal) === null || _c === void 0 ? void 0 : _c.removeEventListener('abort', abort);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Run a command with no time limit and yield its output until it ends.
|
|
335
|
+
*
|
|
336
|
+
* The command runs detached, so it has no 600 s cap and survives a dropped
|
|
337
|
+
* connection. Frames: `{ type: 'started', processId }`, then the frames of
|
|
338
|
+
* `followCommand`. Stopping early leaves the command running: call
|
|
339
|
+
* `stopCommand({ sandboxId, processId })` to stop it.
|
|
340
|
+
*/
|
|
341
|
+
async function* runCommand(api, sandboxId, command, options) {
|
|
342
|
+
const deadline = Date.now() + STREAM_RETRY_MS;
|
|
343
|
+
let processId;
|
|
344
|
+
for (;;) {
|
|
345
|
+
try {
|
|
346
|
+
const started = await api.command({ sandboxId, commandRequest: { command, cwd: options === null || options === void 0 ? void 0 : options.cwd, detached: true } });
|
|
347
|
+
processId = started.processId;
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
catch (e) {
|
|
351
|
+
if (Date.now() + 1000 >= deadline || !(await isRetryable(e)))
|
|
352
|
+
throw e;
|
|
353
|
+
}
|
|
354
|
+
await delay(1000);
|
|
355
|
+
}
|
|
356
|
+
yield { type: 'started', processId };
|
|
357
|
+
yield* followCommand(api, sandboxId, processId, options);
|
|
358
|
+
}
|
|
@@ -1281,12 +1281,12 @@ export declare class BoatApi extends runtime.BaseAPI {
|
|
|
1281
1281
|
*/
|
|
1282
1282
|
listCredentialAccountsRequestOpts(requestParameters: ListCredentialAccountsRequest): Promise<runtime.RequestOpts>;
|
|
1283
1283
|
/**
|
|
1284
|
-
* Every account of one credential (several ChatGPT sign-ins, several OpenAI keys), in the order they were added, the one in use marked. Labels only, never a secret. Needs an API key with `account.admin`.
|
|
1284
|
+
* Every account of one credential (several ChatGPT sign-ins, several OpenAI keys), in the order they were added, the one in use marked. Labels only, never a secret. Needs an API key with `account.admin`, on a profile you manage: an org member who only uses an org profile gets `403`.
|
|
1285
1285
|
* List the accounts of a credential
|
|
1286
1286
|
*/
|
|
1287
1287
|
listCredentialAccountsRaw(requestParameters: ListCredentialAccountsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<runtime.ApiResponse<CredentialAccountsResponse>>;
|
|
1288
1288
|
/**
|
|
1289
|
-
* Every account of one credential (several ChatGPT sign-ins, several OpenAI keys), in the order they were added, the one in use marked. Labels only, never a secret. Needs an API key with `account.admin`.
|
|
1289
|
+
* Every account of one credential (several ChatGPT sign-ins, several OpenAI keys), in the order they were added, the one in use marked. Labels only, never a secret. Needs an API key with `account.admin`, on a profile you manage: an org member who only uses an org profile gets `403`.
|
|
1290
1290
|
* List the accounts of a credential
|
|
1291
1291
|
*/
|
|
1292
1292
|
listCredentialAccounts(requestParameters: ListCredentialAccountsRequest, initOverrides?: RequestInit | runtime.InitOverrideFunction): Promise<CredentialAccountsResponse>;
|
package/dist/esm/apis/BoatApi.js
CHANGED
|
@@ -2680,7 +2680,7 @@ export class BoatApi extends runtime.BaseAPI {
|
|
|
2680
2680
|
};
|
|
2681
2681
|
}
|
|
2682
2682
|
/**
|
|
2683
|
-
* Every account of one credential (several ChatGPT sign-ins, several OpenAI keys), in the order they were added, the one in use marked. Labels only, never a secret. Needs an API key with `account.admin`.
|
|
2683
|
+
* Every account of one credential (several ChatGPT sign-ins, several OpenAI keys), in the order they were added, the one in use marked. Labels only, never a secret. Needs an API key with `account.admin`, on a profile you manage: an org member who only uses an org profile gets `403`.
|
|
2684
2684
|
* List the accounts of a credential
|
|
2685
2685
|
*/
|
|
2686
2686
|
async listCredentialAccountsRaw(requestParameters, initOverrides) {
|
|
@@ -2689,7 +2689,7 @@ export class BoatApi extends runtime.BaseAPI {
|
|
|
2689
2689
|
return new runtime.JSONApiResponse(response, (jsonValue) => CredentialAccountsResponseFromJSON(jsonValue));
|
|
2690
2690
|
}
|
|
2691
2691
|
/**
|
|
2692
|
-
* Every account of one credential (several ChatGPT sign-ins, several OpenAI keys), in the order they were added, the one in use marked. Labels only, never a secret. Needs an API key with `account.admin`.
|
|
2692
|
+
* Every account of one credential (several ChatGPT sign-ins, several OpenAI keys), in the order they were added, the one in use marked. Labels only, never a secret. Needs an API key with `account.admin`, on a profile you manage: an org member who only uses an org profile gets `403`.
|
|
2693
2693
|
* List the accounts of a credential
|
|
2694
2694
|
*/
|
|
2695
2695
|
async listCredentialAccounts(requestParameters, initOverrides) {
|
|
@@ -76,3 +76,26 @@ export type StreamCommandOptions = {
|
|
|
76
76
|
* sent to a starting sandbox for up to 60 s instead of refusing it.
|
|
77
77
|
*/
|
|
78
78
|
export declare function streamCommand(api: BoatApi, sandboxId: string, command: string, options?: StreamCommandOptions): AsyncGenerator<CommandFrame>;
|
|
79
|
+
export type FollowCommandOptions = {
|
|
80
|
+
signal?: AbortSignal;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Yield a detached command's output from its start until it ends: `stdout`/`stderr`
|
|
84
|
+
* chunks (`frame.data`), then exactly one `exit` (`exitCode`, ...) or `error`
|
|
85
|
+
* (`message`). The server ends each connection after 10 minutes; this reconnects
|
|
86
|
+
* from the same offsets, with no gap and no repeat. A network cut is reconnected
|
|
87
|
+
* the same way for up to 60 s.
|
|
88
|
+
*/
|
|
89
|
+
export declare function followCommand(api: BoatApi, sandboxId: string, processId: number, options?: FollowCommandOptions): AsyncGenerator<CommandFrame>;
|
|
90
|
+
export type RunCommandOptions = FollowCommandOptions & {
|
|
91
|
+
cwd?: string;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Run a command with no time limit and yield its output until it ends.
|
|
95
|
+
*
|
|
96
|
+
* The command runs detached, so it has no 600 s cap and survives a dropped
|
|
97
|
+
* connection. Frames: `{ type: 'started', processId }`, then the frames of
|
|
98
|
+
* `followCommand`. Stopping early leaves the command running: call
|
|
99
|
+
* `stopCommand({ sandboxId, processId })` to stop it.
|
|
100
|
+
*/
|
|
101
|
+
export declare function runCommand(api: BoatApi, sandboxId: string, command: string, options?: RunCommandOptions): AsyncGenerator<CommandFrame>;
|
package/dist/esm/boat-helpers.js
CHANGED
|
@@ -245,3 +245,98 @@ export async function* streamCommand(api, sandboxId, command, options) {
|
|
|
245
245
|
await delay(1000);
|
|
246
246
|
}
|
|
247
247
|
}
|
|
248
|
+
// The server sends a heartbeat every 15 s, so 60 s of silence is a dead connection.
|
|
249
|
+
const ATTACH_IDLE_MS = 60000;
|
|
250
|
+
// After the first connection, a failed reconnect is tried again for this long.
|
|
251
|
+
const ATTACH_RETRY_MS = 60000;
|
|
252
|
+
function isNetworkError(e, signal) {
|
|
253
|
+
if ((signal === null || signal === void 0 ? void 0 : signal.aborted) || e instanceof SyntaxError)
|
|
254
|
+
return false;
|
|
255
|
+
return !(e === null || e === void 0 ? void 0 : e.response);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Yield a detached command's output from its start until it ends: `stdout`/`stderr`
|
|
259
|
+
* chunks (`frame.data`), then exactly one `exit` (`exitCode`, ...) or `error`
|
|
260
|
+
* (`message`). The server ends each connection after 10 minutes; this reconnects
|
|
261
|
+
* from the same offsets, with no gap and no repeat. A network cut is reconnected
|
|
262
|
+
* the same way for up to 60 s.
|
|
263
|
+
*/
|
|
264
|
+
export async function* followCommand(api, sandboxId, processId, options) {
|
|
265
|
+
var _a, _b, _c;
|
|
266
|
+
var _d, _e, _f, _g;
|
|
267
|
+
const offsets = { stdout: 0, stderr: 0 };
|
|
268
|
+
let connected = false;
|
|
269
|
+
// Set at the first failure after a good connection; any good connection clears it.
|
|
270
|
+
let failingSince;
|
|
271
|
+
for (;;) {
|
|
272
|
+
if ((_a = options === null || options === void 0 ? void 0 : options.signal) === null || _a === void 0 ? void 0 : _a.aborted)
|
|
273
|
+
throw (_d = options.signal.reason) !== null && _d !== void 0 ? _d : new Error('followCommand aborted');
|
|
274
|
+
// One controller per connection: the caller's signal, or 60 s with no line.
|
|
275
|
+
const connection = new AbortController();
|
|
276
|
+
const abort = () => connection.abort();
|
|
277
|
+
(_b = options === null || options === void 0 ? void 0 : options.signal) === null || _b === void 0 ? void 0 : _b.addEventListener('abort', abort);
|
|
278
|
+
let idle;
|
|
279
|
+
const touch = () => {
|
|
280
|
+
clearTimeout(idle);
|
|
281
|
+
idle = setTimeout(abort, ATTACH_IDLE_MS);
|
|
282
|
+
};
|
|
283
|
+
try {
|
|
284
|
+
touch();
|
|
285
|
+
const response = await api.attachCommandRaw({ sandboxId, processId, stdoutOffset: offsets.stdout, stderrOffset: offsets.stderr }, { signal: connection.signal });
|
|
286
|
+
connected = true;
|
|
287
|
+
failingSince = undefined;
|
|
288
|
+
for await (const frame of ndjsonFrames(response.raw)) {
|
|
289
|
+
touch();
|
|
290
|
+
if (frame.type === 'stdout' || frame.type === 'stderr') {
|
|
291
|
+
offsets[frame.type] = (_e = frame.nextOffset) !== null && _e !== void 0 ? _e : offsets[frame.type];
|
|
292
|
+
yield frame;
|
|
293
|
+
}
|
|
294
|
+
else if (frame.type === 'exit' || frame.type === 'error') {
|
|
295
|
+
yield frame;
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
// attached, heartbeat, reconnect: ours to handle, never the caller's.
|
|
300
|
+
offsets.stdout = (_f = frame.stdoutOffset) !== null && _f !== void 0 ? _f : offsets.stdout;
|
|
301
|
+
offsets.stderr = (_g = frame.stderrOffset) !== null && _g !== void 0 ? _g : offsets.stderr;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
catch (e) {
|
|
306
|
+
failingSince !== null && failingSince !== void 0 ? failingSince : (failingSince = Date.now());
|
|
307
|
+
if (!isNetworkError(e, options === null || options === void 0 ? void 0 : options.signal) || !connected || Date.now() - failingSince >= ATTACH_RETRY_MS)
|
|
308
|
+
throw e;
|
|
309
|
+
await delay(1000);
|
|
310
|
+
}
|
|
311
|
+
finally {
|
|
312
|
+
clearTimeout(idle);
|
|
313
|
+
(_c = options === null || options === void 0 ? void 0 : options.signal) === null || _c === void 0 ? void 0 : _c.removeEventListener('abort', abort);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Run a command with no time limit and yield its output until it ends.
|
|
319
|
+
*
|
|
320
|
+
* The command runs detached, so it has no 600 s cap and survives a dropped
|
|
321
|
+
* connection. Frames: `{ type: 'started', processId }`, then the frames of
|
|
322
|
+
* `followCommand`. Stopping early leaves the command running: call
|
|
323
|
+
* `stopCommand({ sandboxId, processId })` to stop it.
|
|
324
|
+
*/
|
|
325
|
+
export async function* runCommand(api, sandboxId, command, options) {
|
|
326
|
+
const deadline = Date.now() + STREAM_RETRY_MS;
|
|
327
|
+
let processId;
|
|
328
|
+
for (;;) {
|
|
329
|
+
try {
|
|
330
|
+
const started = await api.command({ sandboxId, commandRequest: { command, cwd: options === null || options === void 0 ? void 0 : options.cwd, detached: true } });
|
|
331
|
+
processId = started.processId;
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
catch (e) {
|
|
335
|
+
if (Date.now() + 1000 >= deadline || !(await isRetryable(e)))
|
|
336
|
+
throw e;
|
|
337
|
+
}
|
|
338
|
+
await delay(1000);
|
|
339
|
+
}
|
|
340
|
+
yield { type: 'started', processId };
|
|
341
|
+
yield* followCommand(api, sandboxId, processId, options);
|
|
342
|
+
}
|
|
@@ -55,7 +55,7 @@ export interface CredentialProfile {
|
|
|
55
55
|
*/
|
|
56
56
|
connected: Array<CredentialId>;
|
|
57
57
|
/**
|
|
58
|
-
* Credentials with several accounts, keyed by credential id. Each lists every account (labels only), the one in use marked `active`.
|
|
58
|
+
* Credentials with several accounts, keyed by credential id. Each lists every account (labels only), the one in use marked `active`. Empty when you cannot manage the profile.
|
|
59
59
|
* @type {{ [key: string]: Array<CredentialAccount>; }}
|
|
60
60
|
* @memberof CredentialProfile
|
|
61
61
|
*/
|
|
@@ -46,7 +46,7 @@ export interface DeletionOperation {
|
|
|
46
46
|
*/
|
|
47
47
|
status: DeletionOperationStatusEnum;
|
|
48
48
|
/**
|
|
49
|
-
* What the background purge is doing. The target is already gone from every list, restore and fork once the operation exists. `waiting_for_uploads`: stored data is erased once the last upload URL issued for it expires (`expectedBy`). `
|
|
49
|
+
* What the background purge is doing. The target is already gone from every list, restore and fork once the operation exists. `waiting_for_uploads`: stored data is erased once the last upload URL issued for it expires (`expectedBy`). `retrying`: a transient fault, retried automatically. `completed`: a newer snapshot, a fork or a named snapshot made from it keeps the data it reads, until that is deleted too.
|
|
50
50
|
* @type {DeletionOperationStageEnum}
|
|
51
51
|
* @memberof DeletionOperation
|
|
52
52
|
*/
|
|
@@ -109,8 +109,6 @@ export type DeletionOperationStatusEnum = typeof DeletionOperationStatusEnum[key
|
|
|
109
109
|
export declare const DeletionOperationStageEnum: {
|
|
110
110
|
readonly Removing: 'removing';
|
|
111
111
|
readonly WaitingForUploads: 'waiting_for_uploads';
|
|
112
|
-
readonly KeptForNewerSnapshots: 'kept_for_newer_snapshots';
|
|
113
|
-
readonly WaitingForRestore: 'waiting_for_restore';
|
|
114
112
|
readonly Retrying: 'retrying';
|
|
115
113
|
readonly Completed: 'completed';
|
|
116
114
|
};
|
|
@@ -41,8 +41,6 @@ export const DeletionOperationStatusEnum = {
|
|
|
41
41
|
export const DeletionOperationStageEnum = {
|
|
42
42
|
Removing: 'removing',
|
|
43
43
|
WaitingForUploads: 'waiting_for_uploads',
|
|
44
|
-
KeptForNewerSnapshots: 'kept_for_newer_snapshots',
|
|
45
|
-
WaitingForRestore: 'waiting_for_restore',
|
|
46
44
|
Retrying: 'retrying',
|
|
47
45
|
Completed: 'completed'
|
|
48
46
|
};
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import type { LimitsFieldsGiftLimit } from './LimitsFieldsGiftLimit';
|
|
13
13
|
import type { LimitsFieldsCurrentLimits } from './LimitsFieldsCurrentLimits';
|
|
14
|
+
import type { LimitsFieldsMachineTypesInner } from './LimitsFieldsMachineTypesInner';
|
|
14
15
|
import type { LimitsFieldsStartLimits } from './LimitsFieldsStartLimits';
|
|
15
16
|
import type { LimitsFieldsStarts } from './LimitsFieldsStarts';
|
|
16
17
|
import type { LimitsFieldsSandboxPlanTiersInner } from './LimitsFieldsSandboxPlanTiersInner';
|
|
@@ -271,6 +272,12 @@ export interface LimitsFields {
|
|
|
271
272
|
* @memberof LimitsFields
|
|
272
273
|
*/
|
|
273
274
|
trialLine?: string | null;
|
|
275
|
+
/**
|
|
276
|
+
* Each sandbox type, and whether this account can create it now. A blocked type carries the reason.
|
|
277
|
+
* @type {Array<LimitsFieldsMachineTypesInner>}
|
|
278
|
+
* @memberof LimitsFields
|
|
279
|
+
*/
|
|
280
|
+
machineTypes?: Array<LimitsFieldsMachineTypesInner>;
|
|
274
281
|
/**
|
|
275
282
|
*
|
|
276
283
|
* @type {LimitsFieldsGiftLimit}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { LimitsFieldsGiftLimitFromJSON, LimitsFieldsGiftLimitToJSON, } from './LimitsFieldsGiftLimit';
|
|
15
15
|
import { LimitsFieldsCurrentLimitsFromJSON, LimitsFieldsCurrentLimitsToJSON, } from './LimitsFieldsCurrentLimits';
|
|
16
|
+
import { LimitsFieldsMachineTypesInnerFromJSON, LimitsFieldsMachineTypesInnerToJSON, } from './LimitsFieldsMachineTypesInner';
|
|
16
17
|
import { LimitsFieldsStartLimitsFromJSON, LimitsFieldsStartLimitsToJSON, } from './LimitsFieldsStartLimits';
|
|
17
18
|
import { LimitsFieldsStartsFromJSON, LimitsFieldsStartsToJSON, } from './LimitsFieldsStarts';
|
|
18
19
|
import { LimitsFieldsSandboxPlanTiersInnerFromJSON, LimitsFieldsSandboxPlanTiersInnerToJSON, } from './LimitsFieldsSandboxPlanTiersInner';
|
|
@@ -80,6 +81,7 @@ export function LimitsFieldsFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
80
81
|
'last24hUsageSeconds': json['last24hUsageSeconds'] == null ? undefined : json['last24hUsageSeconds'],
|
|
81
82
|
'trialComputeCapSeconds': json['trialComputeCapSeconds'] == null ? undefined : json['trialComputeCapSeconds'],
|
|
82
83
|
'trialLine': json['trialLine'] == null ? undefined : json['trialLine'],
|
|
84
|
+
'machineTypes': json['machineTypes'] == null ? undefined : (json['machineTypes'].map(LimitsFieldsMachineTypesInnerFromJSON)),
|
|
83
85
|
'giftLimit': json['giftLimit'] == null ? undefined : LimitsFieldsGiftLimitFromJSON(json['giftLimit']),
|
|
84
86
|
'billingStatus': json['billingStatus'],
|
|
85
87
|
'subscriptionStatus': json['subscriptionStatus'] == null ? undefined : json['subscriptionStatus'],
|
|
@@ -142,6 +144,7 @@ export function LimitsFieldsToJSONTyped(value, ignoreDiscriminator = false) {
|
|
|
142
144
|
'last24hUsageSeconds': value['last24hUsageSeconds'],
|
|
143
145
|
'trialComputeCapSeconds': value['trialComputeCapSeconds'],
|
|
144
146
|
'trialLine': value['trialLine'],
|
|
147
|
+
'machineTypes': value['machineTypes'] == null ? undefined : (value['machineTypes'].map(LimitsFieldsMachineTypesInnerToJSON)),
|
|
145
148
|
'giftLimit': LimitsFieldsGiftLimitToJSON(value['giftLimit']),
|
|
146
149
|
'billingStatus': value['billingStatus'],
|
|
147
150
|
'subscriptionStatus': value['subscriptionStatus'],
|
|
@@ -0,0 +1,54 @@
|
|
|
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
|
+
*
|
|
14
|
+
* @export
|
|
15
|
+
* @interface LimitsFieldsMachineTypesInner
|
|
16
|
+
*/
|
|
17
|
+
export interface LimitsFieldsMachineTypesInner {
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @type {LimitsFieldsMachineTypesInnerTypeEnum}
|
|
21
|
+
* @memberof LimitsFieldsMachineTypesInner
|
|
22
|
+
*/
|
|
23
|
+
type: LimitsFieldsMachineTypesInnerTypeEnum;
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
* @type {boolean}
|
|
27
|
+
* @memberof LimitsFieldsMachineTypesInner
|
|
28
|
+
*/
|
|
29
|
+
available: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Why the type is blocked, for example `not during the free trial; the first payment unlocks it`. Null when available.
|
|
32
|
+
* @type {string}
|
|
33
|
+
* @memberof LimitsFieldsMachineTypesInner
|
|
34
|
+
*/
|
|
35
|
+
reason: string | null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* @export
|
|
39
|
+
*/
|
|
40
|
+
export declare const LimitsFieldsMachineTypesInnerTypeEnum: {
|
|
41
|
+
readonly Small: 'small';
|
|
42
|
+
readonly Default: 'default';
|
|
43
|
+
readonly Large: 'large';
|
|
44
|
+
readonly Xlarge: 'xlarge';
|
|
45
|
+
};
|
|
46
|
+
export type LimitsFieldsMachineTypesInnerTypeEnum = typeof LimitsFieldsMachineTypesInnerTypeEnum[keyof typeof LimitsFieldsMachineTypesInnerTypeEnum];
|
|
47
|
+
/**
|
|
48
|
+
* Check if a given object implements the LimitsFieldsMachineTypesInner interface.
|
|
49
|
+
*/
|
|
50
|
+
export declare function instanceOfLimitsFieldsMachineTypesInner(value: object): value is LimitsFieldsMachineTypesInner;
|
|
51
|
+
export declare function LimitsFieldsMachineTypesInnerFromJSON(json: any): LimitsFieldsMachineTypesInner;
|
|
52
|
+
export declare function LimitsFieldsMachineTypesInnerFromJSONTyped(json: any, ignoreDiscriminator: boolean): LimitsFieldsMachineTypesInner;
|
|
53
|
+
export declare function LimitsFieldsMachineTypesInnerToJSON(json: any): LimitsFieldsMachineTypesInner;
|
|
54
|
+
export declare function LimitsFieldsMachineTypesInnerToJSONTyped(value?: LimitsFieldsMachineTypesInner | null, ignoreDiscriminator?: boolean): any;
|
|
@@ -0,0 +1,60 @@
|
|
|
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 LimitsFieldsMachineTypesInnerTypeEnum = {
|
|
18
|
+
Small: 'small',
|
|
19
|
+
Default: 'default',
|
|
20
|
+
Large: 'large',
|
|
21
|
+
Xlarge: 'xlarge'
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Check if a given object implements the LimitsFieldsMachineTypesInner interface.
|
|
25
|
+
*/
|
|
26
|
+
export function instanceOfLimitsFieldsMachineTypesInner(value) {
|
|
27
|
+
if (!('type' in value) || value['type'] === undefined)
|
|
28
|
+
return false;
|
|
29
|
+
if (!('available' in value) || value['available'] === undefined)
|
|
30
|
+
return false;
|
|
31
|
+
if (!('reason' in value) || value['reason'] === undefined)
|
|
32
|
+
return false;
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
export function LimitsFieldsMachineTypesInnerFromJSON(json) {
|
|
36
|
+
return LimitsFieldsMachineTypesInnerFromJSONTyped(json, false);
|
|
37
|
+
}
|
|
38
|
+
export function LimitsFieldsMachineTypesInnerFromJSONTyped(json, ignoreDiscriminator) {
|
|
39
|
+
if (json == null) {
|
|
40
|
+
return json;
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
'type': json['type'],
|
|
44
|
+
'available': json['available'],
|
|
45
|
+
'reason': json['reason'],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function LimitsFieldsMachineTypesInnerToJSON(json) {
|
|
49
|
+
return LimitsFieldsMachineTypesInnerToJSONTyped(json, false);
|
|
50
|
+
}
|
|
51
|
+
export function LimitsFieldsMachineTypesInnerToJSONTyped(value, ignoreDiscriminator = false) {
|
|
52
|
+
if (value == null) {
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
'type': value['type'],
|
|
57
|
+
'available': value['available'],
|
|
58
|
+
'reason': value['reason'],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import type { LimitsFieldsGiftLimit } from './LimitsFieldsGiftLimit';
|
|
13
13
|
import type { LimitsFieldsCurrentLimits } from './LimitsFieldsCurrentLimits';
|
|
14
|
+
import type { LimitsFieldsMachineTypesInner } from './LimitsFieldsMachineTypesInner';
|
|
14
15
|
import type { LimitsFieldsStartLimits } from './LimitsFieldsStartLimits';
|
|
15
16
|
import type { LimitsFieldsStarts } from './LimitsFieldsStarts';
|
|
16
17
|
import type { LimitsFieldsSandboxPlanTiersInner } from './LimitsFieldsSandboxPlanTiersInner';
|
|
@@ -282,6 +283,12 @@ export interface LimitsResponse {
|
|
|
282
283
|
* @memberof LimitsResponse
|
|
283
284
|
*/
|
|
284
285
|
trialLine?: string;
|
|
286
|
+
/**
|
|
287
|
+
* Each sandbox type, and whether this account can create it now. A blocked type carries the reason.
|
|
288
|
+
* @type {Array<LimitsFieldsMachineTypesInner>}
|
|
289
|
+
* @memberof LimitsResponse
|
|
290
|
+
*/
|
|
291
|
+
machineTypes?: Array<LimitsFieldsMachineTypesInner>;
|
|
285
292
|
/**
|
|
286
293
|
*
|
|
287
294
|
* @type {LimitsFieldsGiftLimit}
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { LimitsFieldsGiftLimitFromJSON, LimitsFieldsGiftLimitToJSON, } from './LimitsFieldsGiftLimit';
|
|
15
15
|
import { LimitsFieldsCurrentLimitsFromJSON, LimitsFieldsCurrentLimitsToJSON, } from './LimitsFieldsCurrentLimits';
|
|
16
|
+
import { LimitsFieldsMachineTypesInnerFromJSON, LimitsFieldsMachineTypesInnerToJSON, } from './LimitsFieldsMachineTypesInner';
|
|
16
17
|
import { LimitsFieldsStartLimitsFromJSON, LimitsFieldsStartLimitsToJSON, } from './LimitsFieldsStartLimits';
|
|
17
18
|
import { LimitsFieldsStartsFromJSON, LimitsFieldsStartsToJSON, } from './LimitsFieldsStarts';
|
|
18
19
|
import { LimitsFieldsSandboxPlanTiersInnerFromJSON, LimitsFieldsSandboxPlanTiersInnerToJSON, } from './LimitsFieldsSandboxPlanTiersInner';
|
|
@@ -85,6 +86,7 @@ export function LimitsResponseFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
85
86
|
'last24hUsageSeconds': json['last24hUsageSeconds'] == null ? undefined : json['last24hUsageSeconds'],
|
|
86
87
|
'trialComputeCapSeconds': json['trialComputeCapSeconds'] == null ? undefined : json['trialComputeCapSeconds'],
|
|
87
88
|
'trialLine': json['trialLine'] == null ? undefined : json['trialLine'],
|
|
89
|
+
'machineTypes': json['machineTypes'] == null ? undefined : (json['machineTypes'].map(LimitsFieldsMachineTypesInnerFromJSON)),
|
|
88
90
|
'giftLimit': json['giftLimit'] == null ? undefined : LimitsFieldsGiftLimitFromJSON(json['giftLimit']),
|
|
89
91
|
'billingStatus': json['billingStatus'],
|
|
90
92
|
'subscriptionStatus': json['subscriptionStatus'] == null ? undefined : json['subscriptionStatus'],
|
|
@@ -148,6 +150,7 @@ export function LimitsResponseToJSONTyped(value, ignoreDiscriminator = false) {
|
|
|
148
150
|
'last24hUsageSeconds': value['last24hUsageSeconds'],
|
|
149
151
|
'trialComputeCapSeconds': value['trialComputeCapSeconds'],
|
|
150
152
|
'trialLine': value['trialLine'],
|
|
153
|
+
'machineTypes': value['machineTypes'] == null ? undefined : (value['machineTypes'].map(LimitsFieldsMachineTypesInnerToJSON)),
|
|
151
154
|
'giftLimit': LimitsFieldsGiftLimitToJSON(value['giftLimit']),
|
|
152
155
|
'billingStatus': value['billingStatus'],
|
|
153
156
|
'subscriptionStatus': value['subscriptionStatus'],
|