withruntime 0.12.0 → 0.16.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/BLAXEL.md +97 -32
- package/COMPATIBILITY.md +120 -5
- package/DAYTONA.md +34 -3
- package/E2B.md +34 -5
- package/README.md +36 -3
- package/README.src.md +35 -2
- package/VERCEL.md +52 -5
- package/compatibility-lock.json +71 -111
- package/dist/billing-cli.js +8 -4
- package/dist/blaxel/client.d.ts +11 -0
- package/dist/blaxel/client.js +28 -0
- package/dist/blaxel/errors.d.ts +65 -0
- package/dist/blaxel/errors.js +114 -0
- package/dist/blaxel/index.d.ts +10 -3
- package/dist/blaxel/index.js +23 -4
- package/dist/blaxel/preview.d.ts +29 -4
- package/dist/blaxel/preview.js +79 -5
- package/dist/blaxel/sandbox.d.ts +1 -1
- package/dist/blaxel/sandbox.js +2 -1
- package/dist/blaxel/session.js +4 -2
- package/dist/cli-extras.js +2 -1
- package/dist/cli-words.js +1 -0
- package/dist/cli.d.ts +17 -2
- package/dist/cli.js +291 -85
- package/dist/client.d.ts +1 -1
- package/dist/credentials.d.ts +3 -0
- package/dist/credentials.js +15 -0
- package/dist/daytona/client.d.ts +4 -0
- package/dist/daytona/client.js +8 -3
- package/dist/daytona/daytona.d.ts +4 -1
- package/dist/daytona/daytona.js +3 -2
- package/dist/e2b/sandbox.d.ts +7 -6
- package/dist/e2b/sandbox.js +9 -12
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js +1 -1
- package/dist/freestyle/index.d.ts +77 -5
- package/dist/freestyle/index.js +380 -48
- package/dist/identity.js +36 -18
- package/dist/index.d.ts +4 -3
- package/dist/machine.d.ts +39 -13
- package/dist/machine.js +72 -25
- package/dist/mcp.js +157 -20
- package/dist/modal/index.d.ts +15 -0
- package/dist/modal/index.js +35 -7
- package/dist/morph/index.d.ts +255 -0
- package/dist/morph/index.js +641 -0
- package/dist/network-cli.js +2 -2
- package/dist/product-names.d.ts +2 -2
- package/dist/product-names.js +2 -2
- package/dist/products/api-keys.d.ts +73 -0
- package/dist/products/api-keys.js +23 -0
- package/dist/products/apps.d.ts +12 -31
- package/dist/products/apps.js +8 -113
- package/dist/products/balancers.d.ts +87 -0
- package/dist/products/balancers.js +8 -0
- package/dist/products/builds.d.ts +30 -0
- package/dist/products/builds.js +6 -0
- package/dist/products/index.d.ts +2 -0
- package/dist/products/index.js +2 -0
- package/dist/products/jobs.d.ts +2 -2
- package/dist/products/jobs.js +1 -1
- package/dist/products/limits.d.ts +16 -2
- package/dist/products/limits.js +2 -2
- package/dist/products/mcp.d.ts +5 -0
- package/dist/products/network-products.d.ts +21 -3
- package/dist/products/network-products.js +3 -1
- package/dist/products/observability.d.ts +7 -2
- package/dist/products/previews.d.ts +6 -3
- package/dist/products/previews.js +1 -1
- package/dist/products/resources.d.ts +54 -0
- package/dist/products/resources.js +122 -0
- package/dist/products/secrets.d.ts +22 -0
- package/dist/products/secrets.js +8 -0
- package/dist/products/volumes.d.ts +3 -0
- package/dist/sandbox.d.ts +4 -0
- package/dist/sandbox.js +27 -2
- package/dist/snapshots.d.ts +4 -0
- package/dist/ssh.d.ts +35 -0
- package/dist/ssh.js +93 -1
- package/dist/transport.d.ts +14 -8
- package/dist/transport.js +70 -15
- package/dist/types.d.ts +33 -5
- package/dist/vercel/command.d.ts +48 -1
- package/dist/vercel/command.js +237 -6
- package/dist/vercel/sandbox-user.js +2 -1
- package/dist/vercel/sandbox.d.ts +17 -3
- package/dist/vercel/sandbox.js +46 -3
- package/dist/wallet.d.ts +4 -1
- package/dist/wallet.js +2 -1
- package/package.json +7 -14
- package/dist/cli/logs.test.d.ts +0 -1
- package/dist/cli/logs.test.js +0 -272
- package/dist/products/logs.test.d.ts +0 -1
- package/dist/products/logs.test.js +0 -343
package/dist/transport.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RuntimeError } from "./errors.js";
|
|
2
|
-
export declare const VERSION = "0.
|
|
2
|
+
export declare const VERSION = "0.16.0";
|
|
3
3
|
export declare const DEFAULT_BASE_URL = "https://api.withruntime.com";
|
|
4
4
|
/** Runtime's API as code inside a Runtime sandbox reaches it: the sandbox's
|
|
5
5
|
* own host sends each request on to DEFAULT_BASE_URL over HTTPS. The API runs
|
|
@@ -7,6 +7,9 @@ export declare const DEFAULT_BASE_URL = "https://api.withruntime.com";
|
|
|
7
7
|
* because the hop never leaves the machine: it goes from the program to the
|
|
8
8
|
* guest's own proxy and over the sandbox's private channel to its host. */
|
|
9
9
|
export declare const SANDBOX_BASE_URL = "http://runtime.internal";
|
|
10
|
+
/** How a Runtime secret's placeholder starts, the value a sandbox sees in its
|
|
11
|
+
* place (packages/cloud-guide/docs/security.md). */
|
|
12
|
+
export declare const PLACEHOLDER = "rtsec_";
|
|
10
13
|
/** Every Runtime sandbox has this file; guest-net.py keeps it current. Tests
|
|
11
14
|
* move it, so the machine running them does not decide what they see. */
|
|
12
15
|
export declare const sandboxMarker: {
|
|
@@ -51,14 +54,17 @@ export type Call = RequestOptions & {
|
|
|
51
54
|
/** How long to keep retrying, with the same key and input, a refusal that
|
|
52
55
|
* clears when a sandbox stops or a host frees room (WAITS_FOR_ROOM): a
|
|
53
56
|
* full slots without credit, a full quota, a full region. Then the refusal is thrown as
|
|
54
|
-
* it came.
|
|
57
|
+
* it came. A create, wake or restart sets it; 0 or absent fails at once. */
|
|
55
58
|
waitForCapacityMs?: number;
|
|
56
59
|
/** Called each time a call waits for room, with the refusal it is waiting
|
|
57
60
|
* out and how long it will sleep before sending the call again. */
|
|
58
61
|
onCapacityWait?: (refusal: RuntimeError, waitMs: number) => void;
|
|
59
|
-
/** Internal: when the call's own deadline ends (performance.now()),
|
|
60
|
-
* once the call is prepared; absent when it has none. */
|
|
61
|
-
deadlineAt?: number;
|
|
62
|
+
/** Internal: when the call's own deadline ends now (performance.now()),
|
|
63
|
+
* set once the call is prepared; absent when it has none. */
|
|
64
|
+
deadlineAt?: () => number;
|
|
65
|
+
/** Internal: moves the call's deadline on by a wait for room, so a wait
|
|
66
|
+
* for capacity never spends the caller's own `timeoutMs`. */
|
|
67
|
+
extendDeadline?: (ms: number) => void;
|
|
62
68
|
};
|
|
63
69
|
/** How long one attempt waits for its answer to start. The API starts every
|
|
64
70
|
* answer within 120 s: Caddy answers 503 itself past that, and a longer call
|
|
@@ -66,8 +72,8 @@ export type Call = RequestOptions & {
|
|
|
66
72
|
* with no answer by then is talking to a server that is gone, such as a
|
|
67
73
|
* controller that died with the call in flight while its address moved to
|
|
68
74
|
* the new leader: a client that only waits sends nothing the new leader could
|
|
69
|
-
* refuse, so it waited out the whole deadline and failed (
|
|
70
|
-
*
|
|
75
|
+
* refuse, so it waited out the whole deadline and failed (a controller
|
|
76
|
+
* failover drill, 4 October 2026). It is sent again under the same key. */
|
|
71
77
|
export declare const ANSWER_START_MS = 125000;
|
|
72
78
|
export declare function apiOrigin(value: string): string;
|
|
73
79
|
export declare function encodeQuery(query: Query | undefined): string;
|
|
@@ -87,7 +93,7 @@ export declare const DEFAULT_MAX_CONNECTIONS = 48;
|
|
|
87
93
|
/** AbortSignal.timeout in whole milliseconds, rounded up, never under 1.
|
|
88
94
|
* Node throws ERR_OUT_OF_RANGE on a fraction (Bun accepts one), so a
|
|
89
95
|
* customer's timeoutMs of 1500.5 would be a RangeError instead of a request;
|
|
90
|
-
* the live promise probe broke this way on 9 October 2026
|
|
96
|
+
* the live promise probe broke this way on 9 October 2026. Every
|
|
91
97
|
* deadline the SDK makes from a customer's or a computed value goes through
|
|
92
98
|
* this. */
|
|
93
99
|
export declare function timeoutSignal(ms: number): AbortSignal;
|
package/dist/transport.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ConnectionError, DELIBERATE, errorFor, NOTHING_RAN, RuntimeError, WAITS_FOR_ROOM, } from "./errors.js";
|
|
2
2
|
import { describeRoute, envFetch, openWebSocket } from "./proxy.js";
|
|
3
3
|
import { warningText } from "./product-renames.js";
|
|
4
|
-
export const VERSION = "0.
|
|
4
|
+
export const VERSION = "0.16.0";
|
|
5
5
|
export const DEFAULT_BASE_URL = "https://api.withruntime.com";
|
|
6
6
|
/** Runtime's API as code inside a Runtime sandbox reaches it: the sandbox's
|
|
7
7
|
* own host sends each request on to DEFAULT_BASE_URL over HTTPS. The API runs
|
|
@@ -9,6 +9,9 @@ export const DEFAULT_BASE_URL = "https://api.withruntime.com";
|
|
|
9
9
|
* because the hop never leaves the machine: it goes from the program to the
|
|
10
10
|
* guest's own proxy and over the sandbox's private channel to its host. */
|
|
11
11
|
export const SANDBOX_BASE_URL = "http://runtime.internal";
|
|
12
|
+
/** How a Runtime secret's placeholder starts, the value a sandbox sees in its
|
|
13
|
+
* place (packages/cloud-guide/docs/security.md). */
|
|
14
|
+
export const PLACEHOLDER = "rtsec_";
|
|
12
15
|
/** Every Runtime sandbox has this file; guest-net.py keeps it current. Tests
|
|
13
16
|
* move it, so the machine running them does not decide what they see. */
|
|
14
17
|
export const sandboxMarker = { path: "/run/runtime/environment.json" };
|
|
@@ -45,8 +48,8 @@ const NOTHING_RAN_MS = 300_000;
|
|
|
45
48
|
* with no answer by then is talking to a server that is gone, such as a
|
|
46
49
|
* controller that died with the call in flight while its address moved to
|
|
47
50
|
* the new leader: a client that only waits sends nothing the new leader could
|
|
48
|
-
* refuse, so it waited out the whole deadline and failed (
|
|
49
|
-
*
|
|
51
|
+
* refuse, so it waited out the whole deadline and failed (a controller
|
|
52
|
+
* failover drill, 4 October 2026). It is sent again under the same key. */
|
|
50
53
|
export const ANSWER_START_MS = 125_000;
|
|
51
54
|
export function apiOrigin(value) {
|
|
52
55
|
const url = new URL(value);
|
|
@@ -176,12 +179,36 @@ const KEPT_FOR_CALLS = 8;
|
|
|
176
179
|
/** AbortSignal.timeout in whole milliseconds, rounded up, never under 1.
|
|
177
180
|
* Node throws ERR_OUT_OF_RANGE on a fraction (Bun accepts one), so a
|
|
178
181
|
* customer's timeoutMs of 1500.5 would be a RangeError instead of a request;
|
|
179
|
-
* the live promise probe broke this way on 9 October 2026
|
|
182
|
+
* the live promise probe broke this way on 9 October 2026. Every
|
|
180
183
|
* deadline the SDK makes from a customer's or a computed value goes through
|
|
181
184
|
* this. */
|
|
182
185
|
export function timeoutSignal(ms) {
|
|
183
186
|
return AbortSignal.timeout(Math.max(1, Math.ceil(ms)));
|
|
184
187
|
}
|
|
188
|
+
/** A deadline `ms` from now that `extend` moves later; it aborts with a
|
|
189
|
+
* TimeoutError, as AbortSignal.timeout does. */
|
|
190
|
+
function movableDeadline(ms) {
|
|
191
|
+
const controller = new AbortController();
|
|
192
|
+
let at = performance.now() + ms;
|
|
193
|
+
let timer;
|
|
194
|
+
const arm = () => {
|
|
195
|
+
timer = setTimeout(() => controller.abort(new DOMException("The operation timed out.", "TimeoutError")), Math.max(1, Math.ceil(at - performance.now())));
|
|
196
|
+
// Never keeps a process alive by itself, as AbortSignal.timeout does not.
|
|
197
|
+
timer.unref?.();
|
|
198
|
+
};
|
|
199
|
+
arm();
|
|
200
|
+
return {
|
|
201
|
+
signal: controller.signal,
|
|
202
|
+
at: () => at,
|
|
203
|
+
extend: (by) => {
|
|
204
|
+
if (controller.signal.aborted || by <= 0)
|
|
205
|
+
return;
|
|
206
|
+
at += by;
|
|
207
|
+
clearTimeout(timer);
|
|
208
|
+
arm();
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
}
|
|
185
212
|
export class Transport {
|
|
186
213
|
baseUrl;
|
|
187
214
|
#apiKey;
|
|
@@ -204,7 +231,13 @@ export class Transport {
|
|
|
204
231
|
throw missingKey();
|
|
205
232
|
else
|
|
206
233
|
this.#apiKey = options.apiKey;
|
|
207
|
-
|
|
234
|
+
// A secret's placeholder becomes the key only on its way out through the
|
|
235
|
+
// sandbox's proxy; runtime.internal goes to the host without it, so the
|
|
236
|
+
// API sees the placeholder and answers 401 (land-lander, 11 October 2026:
|
|
237
|
+
// every worker's `check --remote`). Such a key's calls take the public API.
|
|
238
|
+
const placeholder = this.#apiKey?.startsWith(PLACEHOLDER) === true;
|
|
239
|
+
const origin = options.baseUrl || processEnv().RUNTIME_API_URL || DEFAULT_BASE_URL;
|
|
240
|
+
this.baseUrl = apiOrigin(placeholder ? origin : reachable(origin));
|
|
208
241
|
// The environment's proxy (HTTPS_PROXY, NO_PROXY) on Node and Bun alike;
|
|
209
242
|
// a fetch passed in is used as it is.
|
|
210
243
|
this.#fetch = options.fetch ?? envFetch;
|
|
@@ -254,22 +287,29 @@ export class Transport {
|
|
|
254
287
|
* signal through every retry and the complete response body. */
|
|
255
288
|
#prepare(call) {
|
|
256
289
|
const timeoutMs = call.timeoutMs ?? this.#timeoutMs;
|
|
257
|
-
|
|
258
|
-
|
|
290
|
+
// The deadline is the caller's timeoutMs plus only the time actually
|
|
291
|
+
// spent waiting for room (WAITS_FOR_ROOM), which moves it on as it waits:
|
|
292
|
+
// a wake given timeoutMs 20 on a server that never answers still ends at
|
|
293
|
+
// 20 ms, not two minutes later (lifecycle-deadlines.test.ts).
|
|
294
|
+
const deadline = timeoutMs === 0 ? undefined : movableDeadline(timeoutMs);
|
|
259
295
|
const signal = deadline
|
|
260
296
|
? call.signal
|
|
261
|
-
? AbortSignal.any([call.signal, deadline])
|
|
262
|
-
: deadline
|
|
297
|
+
? AbortSignal.any([call.signal, deadline.signal])
|
|
298
|
+
: deadline.signal
|
|
263
299
|
: call.signal;
|
|
264
|
-
|
|
300
|
+
const prepared = {
|
|
265
301
|
...call,
|
|
266
302
|
timeoutMs: 0,
|
|
267
|
-
...(timeoutMs === 0 ? {} : { deadlineAt: performance.now() + timeoutMs + roomMs }),
|
|
268
303
|
...(signal ? { signal } : {}),
|
|
269
304
|
...(call.method !== "GET"
|
|
270
305
|
? { idempotencyKey: call.idempotencyKey ?? crypto.randomUUID() }
|
|
271
306
|
: {}),
|
|
272
307
|
};
|
|
308
|
+
if (deadline) {
|
|
309
|
+
prepared.deadlineAt = deadline.at;
|
|
310
|
+
prepared.extendDeadline = deadline.extend;
|
|
311
|
+
}
|
|
312
|
+
return prepared;
|
|
273
313
|
}
|
|
274
314
|
#connectionError(call, cause) {
|
|
275
315
|
const cancelled = call.signal?.aborted === true;
|
|
@@ -301,6 +341,18 @@ export class Transport {
|
|
|
301
341
|
await sleep(ms, signal);
|
|
302
342
|
await gate?.take();
|
|
303
343
|
}
|
|
344
|
+
/** Wait before sending a refused call again. When the call's deadline
|
|
345
|
+
* ends the wait, the refusal stands: on a loaded machine bun can fire
|
|
346
|
+
* AbortSignal.timeout before a shorter setTimeout, and the call then
|
|
347
|
+
* failed as a timeout although the transport had judged the wait to fit
|
|
348
|
+
* (11 October 2026). A caller's own cancel still ends it as a cancel. */
|
|
349
|
+
async #retryAfter(refusal, ms, signal, gate) {
|
|
350
|
+
await this.#rest(ms, signal, gate).catch((cause) => {
|
|
351
|
+
throw signal?.reason?.name === "TimeoutError"
|
|
352
|
+
? refusal
|
|
353
|
+
: cause;
|
|
354
|
+
});
|
|
355
|
+
}
|
|
304
356
|
async #send(call, consume, gate) {
|
|
305
357
|
let apiKey;
|
|
306
358
|
try {
|
|
@@ -322,7 +374,9 @@ export class Transport {
|
|
|
322
374
|
const retry = call.retry ?? true;
|
|
323
375
|
let attempt = 0;
|
|
324
376
|
// An answer that ran nothing is sent again until the call's deadline.
|
|
325
|
-
|
|
377
|
+
// Read at each use: a wait for room moves the call's deadline on.
|
|
378
|
+
const idleFallback = performance.now() + NOTHING_RAN_MS;
|
|
379
|
+
const idleUntil = () => call.deadlineAt?.() ?? idleFallback;
|
|
326
380
|
let idleAttempt = 0;
|
|
327
381
|
// The last try never left, and was sent again at once.
|
|
328
382
|
let resentAtOnce = false;
|
|
@@ -413,7 +467,8 @@ export class Transport {
|
|
|
413
467
|
inCallback = true;
|
|
414
468
|
call.onCapacityWait?.(error, pause);
|
|
415
469
|
inCallback = false;
|
|
416
|
-
|
|
470
|
+
call.extendDeadline?.(pause);
|
|
471
|
+
await this.#retryAfter(error, pause, signal, gate);
|
|
417
472
|
continue;
|
|
418
473
|
}
|
|
419
474
|
// Nothing ran: safe to send again for any call, past maxRetries,
|
|
@@ -427,9 +482,9 @@ export class Transport {
|
|
|
427
482
|
const header = Number(response.headers.get("retry-after"));
|
|
428
483
|
const base = error.retryAfterMs ?? (Number.isFinite(header) && header > 0 ? header * 1000 : 250);
|
|
429
484
|
const pause = Math.min(30_000, base * 2 ** Math.min(idleAttempt++, 3)) * (0.9 + Math.random() * 0.2);
|
|
430
|
-
if (pause >= idleUntil - performance.now())
|
|
485
|
+
if (pause >= idleUntil() - performance.now())
|
|
431
486
|
throw error;
|
|
432
|
-
await this.#
|
|
487
|
+
await this.#retryAfter(error, pause, signal, gate);
|
|
433
488
|
continue;
|
|
434
489
|
}
|
|
435
490
|
const retryable = [429, 502, 503, 504].includes(status) && !DELIBERATE.has(error.code);
|
package/dist/types.d.ts
CHANGED
|
@@ -62,6 +62,11 @@ export type SandboxInfo = {
|
|
|
62
62
|
/** The names of its own environment variables (`env`), on a create, an
|
|
63
63
|
* update and a read of one sandbox. Values are never shown. */
|
|
64
64
|
envNames?: string[];
|
|
65
|
+
/** On an update with labels by a key that may read secrets, when one of
|
|
66
|
+
* the account's egress secrets is scoped: true once every server running its sandboxes holds the change,
|
|
67
|
+
* so the next request uses the new scope; false while one has not
|
|
68
|
+
* confirmed (it takes it within 15 seconds). */
|
|
69
|
+
secretsEnforced?: boolean;
|
|
65
70
|
/** On a create from an image with a start command: whether it started
|
|
66
71
|
* (and was still running half a second later), became ready (readyMs),
|
|
67
72
|
* timed out, or exited first (exitCode, and stderr's last lines). The create's answer
|
|
@@ -78,6 +83,11 @@ export type SandboxInfo = {
|
|
|
78
83
|
};
|
|
79
84
|
/** Present and true when getOrCreate answered a sandbox that already held the name. */
|
|
80
85
|
reused?: boolean;
|
|
86
|
+
/** An opaque tag for the server it is on, like `pl_3f9a0c1b2d4e5f60`. Your
|
|
87
|
+
* sandboxes and snapshots with the same tag are on the same server. It is
|
|
88
|
+
* never the server's name, and other accounts see unrelated tags. Null
|
|
89
|
+
* before it is placed. Absent from older servers. */
|
|
90
|
+
placement?: string | null;
|
|
81
91
|
[key: string]: unknown;
|
|
82
92
|
};
|
|
83
93
|
export type CreateSandbox = {
|
|
@@ -92,7 +102,7 @@ export type CreateSandbox = {
|
|
|
92
102
|
* `env`. At most 32 variables and 32 KiB. Values are never shown again;
|
|
93
103
|
* answers list only `envNames`. Copies made by fork() keep them. */
|
|
94
104
|
env?: Record<string, string>;
|
|
95
|
-
/** Omit to use the
|
|
105
|
+
/** Omit to use the free usage while it lasts, then prepaid credit. */
|
|
96
106
|
funding?: "trial" | "paid";
|
|
97
107
|
region?: string;
|
|
98
108
|
vcpu?: number;
|
|
@@ -142,6 +152,13 @@ export type CreateSandbox = {
|
|
|
142
152
|
image?: string;
|
|
143
153
|
/** A ready snapshot's id: the sandbox starts as a copy of it, with its shape. Not with image. */
|
|
144
154
|
snapshot?: string;
|
|
155
|
+
/** One to 16 ids of your own sandboxes or snapshots. The new sandbox starts
|
|
156
|
+
* on a server none of them is on, and stays apart if its start is moved.
|
|
157
|
+
* With no other server that has room, the create answers 409 `no_capacity`
|
|
158
|
+
* and nothing is made or charged. A copy of a snapshot starts only where that
|
|
159
|
+
* snapshot is kept, so a `snapshot` with `spreadFrom` naming its server also
|
|
160
|
+
* answers `no_capacity`. */
|
|
161
|
+
spreadFrom?: string[];
|
|
145
162
|
/** Up to four volumes: read-write ("rw", one sandbox at a time) or a
|
|
146
163
|
* read-only "snapshot" copy. */
|
|
147
164
|
volumes?: {
|
|
@@ -295,11 +312,11 @@ export type Usage = {
|
|
|
295
312
|
/** @deprecated Read `availableMs`. Still sent for older clients. */
|
|
296
313
|
reservedMs: number;
|
|
297
314
|
availableMs: number;
|
|
298
|
-
/** `monthly`: the
|
|
299
|
-
* given before 5 October 2026, kept, beside the
|
|
315
|
+
/** `monthly`: the free usage every month only. `hours`: free hours
|
|
316
|
+
* given before 5 October 2026, kept, beside the free usage. Absent
|
|
300
317
|
* from an API older than 5 October 2026. */
|
|
301
318
|
offer?: "monthly" | "hours";
|
|
302
|
-
/** When the
|
|
319
|
+
/** When the free usage renews: the 1st of next month, 00:00 UTC. */
|
|
303
320
|
renewsAt?: string;
|
|
304
321
|
} | null;
|
|
305
322
|
/** What the account uses free this calendar month (UTC), one row per
|
|
@@ -318,9 +335,13 @@ export type Usage = {
|
|
|
318
335
|
/** The month's first day, YYYY-MM-DD. */
|
|
319
336
|
month: string;
|
|
320
337
|
renewsAt: string;
|
|
338
|
+
/** When the free machine time ends for an account that has never paid
|
|
339
|
+
* (30 days after it opened); null once it has paid, when it renews
|
|
340
|
+
* every month. Absent from an API older than 14 October 2026. */
|
|
341
|
+
freeUntil?: string | null;
|
|
321
342
|
}>;
|
|
322
343
|
/** What Runtime for Startups includes (https://withruntime.com/startups).
|
|
323
|
-
* Startup hours are given once, used after this month's
|
|
344
|
+
* Startup hours are given once, used after this month's free usage
|
|
324
345
|
* and before credit, never renewed, and gone after 12 months. Storage is
|
|
325
346
|
* GB kept free each month for those 12 months. Empty unless the account
|
|
326
347
|
* was accepted to the program or given it; absent from an older API. */
|
|
@@ -426,6 +447,13 @@ export type SandboxSettings = {
|
|
|
426
447
|
persistent?: boolean;
|
|
427
448
|
/** Lifetime cap in microdollars; null removes it. */
|
|
428
449
|
maxTotalCostMicros?: number | null;
|
|
450
|
+
/** A new time limit counted from now, 60 to 86400 seconds, sooner or later
|
|
451
|
+
* than the one it had; 0 takes the limit away. A paused sandbox counts it
|
|
452
|
+
* from its next wake. Not for a persistent sandbox. */
|
|
453
|
+
timeoutSeconds?: number;
|
|
454
|
+
/** What the end of its time limit does: pause, stop (keep the disk) or
|
|
455
|
+
* delete. */
|
|
456
|
+
onTimeout?: "pause" | "stop" | "delete";
|
|
429
457
|
};
|
|
430
458
|
/** A deleted sandbox, as `delete()` answers it the first time and every time
|
|
431
459
|
* after. It reads nowhere else afterwards. */
|
package/dist/vercel/command.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Readable } from "node:stream";
|
|
1
2
|
import type { Process } from "../sandbox.js";
|
|
2
3
|
/** One piece of a command's output, as Vercel's `logs()` yields it. */
|
|
3
4
|
export type LogOutputLine = {
|
|
@@ -21,6 +22,8 @@ type Init = {
|
|
|
21
22
|
sandboxName: string;
|
|
22
23
|
process?: Process;
|
|
23
24
|
lines?: LogOutputLine[];
|
|
25
|
+
/** Each line as it arrives, for an attached command's stdout/stderr. */
|
|
26
|
+
onLine?: (line: LogOutputLine) => void;
|
|
24
27
|
};
|
|
25
28
|
/** A command in a sandbox, as Vercel's `Command`. A detached one runs on:
|
|
26
29
|
* `wait()` for its end, `logs()` for its output as it happens. `cmdId` is
|
|
@@ -30,6 +33,8 @@ export declare class Command {
|
|
|
30
33
|
exitCode: number | null;
|
|
31
34
|
durationMs?: number;
|
|
32
35
|
protected readonly init: Init;
|
|
36
|
+
/** Set when the command was started with a `Readable` for stdin. */
|
|
37
|
+
stdinPipe: StdinPipe | null;
|
|
33
38
|
constructor(init: Init);
|
|
34
39
|
get cmdId(): string;
|
|
35
40
|
get cwd(): string;
|
|
@@ -41,7 +46,8 @@ export declare class Command {
|
|
|
41
46
|
}): AsyncGenerator<LogOutputLine, void, void> & Disposable & {
|
|
42
47
|
close(): void;
|
|
43
48
|
};
|
|
44
|
-
/** Waits for the command to end.
|
|
49
|
+
/** Waits for the command to end. With a `Readable` piped to its stdin,
|
|
50
|
+
* rejects if piping fails, and stops piping once the command exits. */
|
|
45
51
|
wait(params?: {
|
|
46
52
|
signal?: AbortSignal;
|
|
47
53
|
}): Promise<CommandFinished>;
|
|
@@ -60,11 +66,52 @@ export declare class Command {
|
|
|
60
66
|
kill(signal?: Signal, opts?: {
|
|
61
67
|
abortSignal?: AbortSignal;
|
|
62
68
|
}): Promise<void>;
|
|
69
|
+
/** Writes to the stdin of a command started with `stdin: true` and
|
|
70
|
+
* `detached: true`. Writes reach the process in call order and resolve once
|
|
71
|
+
* it has accepted the data; Runtime's input offsets make every resend exact,
|
|
72
|
+
* so no byte is written twice. If a write fails, part of it may have been
|
|
73
|
+
* written, and later writes are refused; closeStdin still works. */
|
|
74
|
+
writeStdin(data: string | Uint8Array, opts?: {
|
|
75
|
+
abortSignal?: AbortSignal;
|
|
76
|
+
}): Promise<void>;
|
|
77
|
+
/** Closes the command's stdin, so it reads EOF once it has consumed what
|
|
78
|
+
* was written. */
|
|
79
|
+
closeStdin(opts?: {
|
|
80
|
+
abortSignal?: AbortSignal;
|
|
81
|
+
}): Promise<void>;
|
|
63
82
|
}
|
|
83
|
+
/** A `Readable` being written to a command's stdin. */
|
|
84
|
+
export interface StdinPipe {
|
|
85
|
+
/** Resolves once the stream has ended and stdin is closed, or the command
|
|
86
|
+
* stops accepting input; rejects if a write fails or the stream errors. */
|
|
87
|
+
done: Promise<void>;
|
|
88
|
+
/** Stops reading the stream, for when the command has exited. */
|
|
89
|
+
stop(): void;
|
|
90
|
+
}
|
|
91
|
+
/** Writes a stream to a command's stdin in order, closing stdin when it
|
|
92
|
+
* ends. What is read while a write is in flight goes in the next write, and
|
|
93
|
+
* reading pauses while too much waits. The stream is never ended or
|
|
94
|
+
* destroyed, and every listener is removed once piping stops. */
|
|
95
|
+
export declare function pipeStdin(command: Command, stream: Readable, signal?: AbortSignal): StdinPipe;
|
|
96
|
+
/** Waits for a command to finish, rejecting early if piping its stdin fails,
|
|
97
|
+
* and stops piping once it has exited. Aborting `signal` stops waiting but
|
|
98
|
+
* leaves the pipe running. */
|
|
99
|
+
export declare function waitWithStdinPipe<T>(finished: Promise<T>, pipe: StdinPipe | null, opts?: {
|
|
100
|
+
signal?: AbortSignal;
|
|
101
|
+
onPipeError?: () => void;
|
|
102
|
+
}): Promise<T>;
|
|
64
103
|
/** A command that has ended; `exitCode` is set. */
|
|
65
104
|
export declare class CommandFinished extends Command {
|
|
66
105
|
exitCode: number;
|
|
67
106
|
constructor(init: Init, exitCode: number, durationMs?: number);
|
|
68
107
|
wait(): Promise<CommandFinished>;
|
|
108
|
+
/** Always throws: the command has already exited. */
|
|
109
|
+
writeStdin(_data: string | Uint8Array, _opts?: {
|
|
110
|
+
abortSignal?: AbortSignal;
|
|
111
|
+
}): Promise<never>;
|
|
112
|
+
/** Always throws: the command has already exited. */
|
|
113
|
+
closeStdin(_opts?: {
|
|
114
|
+
abortSignal?: AbortSignal;
|
|
115
|
+
}): Promise<never>;
|
|
69
116
|
}
|
|
70
117
|
export {};
|