@aerol-ai/aerolvm-sdk 0.2.2 → 0.3.1
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/dist/index.d.ts +1 -1
- package/dist/internal/api/v1/paths.d.ts +15 -0
- package/dist/internal/api/v1/paths.js +19 -0
- package/dist/internal/client.d.ts +23 -1
- package/dist/internal/client.js +49 -1
- package/dist/types.d.ts +29 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ export { MicroVM } from "./MicroVM.js";
|
|
|
2
2
|
export { Sandbox } from "./Sandbox.js";
|
|
3
3
|
export { Image } from "./Image.js";
|
|
4
4
|
export type { MicroVMConfig } from "./MicroVM.js";
|
|
5
|
-
export type { BinaryLike, BuildImageOptions, BuildImagePushOptions, BuildImageResult, CreateOptions, CreateSessionOptions, ExecRequest, ExecResult, ExecExitInfo, ExposedPort, ExposePortOptions, ExposeProtocol, ExposeResult, Failover, FailoverPolicy, HealthStatus, Lifecycle, MountSpec, MountSpecRedacted, MountType, RegisterSnapshotOptions, RegistryAuth, ResizeOptions, Sandbox as SandboxData, SandboxSnapshot, SandboxStatus, Session, SessionAttachHandle, SessionAttachOptions, SessionStatus, UpdateLifecycleOptions, } from "./types.js";
|
|
5
|
+
export type { BinaryLike, BuildImageOptions, BuildImagePushOptions, BuildImageResult, CreateOptions, CreateSessionOptions, CustomDomain, CustomDomainStatus, ExecRequest, ExecResult, ExecExitInfo, ExposedPort, ExposePortOptions, ExposeProtocol, ExposeResult, Failover, FailoverPolicy, HealthStatus, Lifecycle, MountSpec, MountSpecRedacted, MountType, RegisterSnapshotOptions, RegistryAuth, ResizeOptions, Sandbox as SandboxData, SandboxSnapshot, SandboxStatus, Session, SessionAttachHandle, SessionAttachOptions, SessionStatus, UpdateLifecycleOptions, } from "./types.js";
|
|
@@ -1 +1,16 @@
|
|
|
1
1
|
export declare const PATH_PREFIX = "/v1";
|
|
2
|
+
/**
|
|
3
|
+
* Collection URL for a sandbox's custom-domain bindings. Used for both POST
|
|
4
|
+
* (add) and GET (list). The DELETE variant lives at
|
|
5
|
+
* {@link sandboxCustomDomainPath}.
|
|
6
|
+
*
|
|
7
|
+
* `id` is interpolated verbatim — sandbox IDs are server-generated opaque
|
|
8
|
+
* tokens and already URL-safe.
|
|
9
|
+
*/
|
|
10
|
+
export declare function sandboxCustomDomainsPath(prefix: string, id: string): string;
|
|
11
|
+
/**
|
|
12
|
+
* URL for a single custom-domain binding. The hostname is percent-encoded so
|
|
13
|
+
* IDN punycode (`xn--...`) and wildcard labels round-trip safely through
|
|
14
|
+
* `DELETE /v1/sandboxes/{id}/custom-domains/{hostname}`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function sandboxCustomDomainPath(prefix: string, id: string, hostname: string): string;
|
|
@@ -5,3 +5,22 @@
|
|
|
5
5
|
//
|
|
6
6
|
// Keep this in sync with pkg/api/v1/dto.go::PathPrefix on the server.
|
|
7
7
|
export const PATH_PREFIX = "/v1";
|
|
8
|
+
/**
|
|
9
|
+
* Collection URL for a sandbox's custom-domain bindings. Used for both POST
|
|
10
|
+
* (add) and GET (list). The DELETE variant lives at
|
|
11
|
+
* {@link sandboxCustomDomainPath}.
|
|
12
|
+
*
|
|
13
|
+
* `id` is interpolated verbatim — sandbox IDs are server-generated opaque
|
|
14
|
+
* tokens and already URL-safe.
|
|
15
|
+
*/
|
|
16
|
+
export function sandboxCustomDomainsPath(prefix, id) {
|
|
17
|
+
return `${prefix}/sandboxes/${id}/custom-domains`;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* URL for a single custom-domain binding. The hostname is percent-encoded so
|
|
21
|
+
* IDN punycode (`xn--...`) and wildcard labels round-trip safely through
|
|
22
|
+
* `DELETE /v1/sandboxes/{id}/custom-domains/{hostname}`.
|
|
23
|
+
*/
|
|
24
|
+
export function sandboxCustomDomainPath(prefix, id, hostname) {
|
|
25
|
+
return `${prefix}/sandboxes/${id}/custom-domains/${encodeURIComponent(hostname)}`;
|
|
26
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Image } from "../Image.js";
|
|
2
|
-
import type { BinaryLike, BuildImageOptions, BuildImageResult, CreateOptions, CreateSessionOptions, ExecRequest, ExecResult, ExecStreamHandle, ExecStreamOptions, ExposedPort, ExposePortOptions, ExposeResult, Failover, HealthStatus, Lifecycle, ListOptions, MountSpecRedacted, NetworkUsage, RegisterSnapshotOptions, SetNetworkLimitsOptions, ResizeOptions, Sandbox, SandboxSnapshot, Session, SessionAttachHandle, SessionAttachOptions } from "../types.js";
|
|
2
|
+
import type { BinaryLike, BuildImageOptions, BuildImageResult, CreateOptions, CreateSessionOptions, CustomDomain, ExecRequest, ExecResult, ExecStreamHandle, ExecStreamOptions, ExposedPort, ExposePortOptions, ExposeResult, Failover, HealthStatus, Lifecycle, ListOptions, MountSpecRedacted, NetworkUsage, RegisterSnapshotOptions, SetNetworkLimitsOptions, ResizeOptions, Sandbox, SandboxSnapshot, Session, SessionAttachHandle, SessionAttachOptions } from "../types.js";
|
|
3
3
|
type FetchLike = typeof fetch;
|
|
4
4
|
/**
|
|
5
5
|
* Wire version of the v1-style sandbox endpoints (`/v1/sandboxes`, etc.) this
|
|
@@ -93,6 +93,15 @@ export declare class APIClient {
|
|
|
93
93
|
*/
|
|
94
94
|
exposePort(id: string, port: number, options?: ExposePortOptions): Promise<ExposeResult>;
|
|
95
95
|
unexposePort(id: string, port: number): Promise<void>;
|
|
96
|
+
/**
|
|
97
|
+
* Bind a custom hostname to a sandbox. The server lowercases the hostname
|
|
98
|
+
* and returns the post-add list of bindings (sorted by hostname). Calling
|
|
99
|
+
* with an already-registered hostname is idempotent and returns the
|
|
100
|
+
* existing list.
|
|
101
|
+
*/
|
|
102
|
+
addCustomDomain(id: string, hostname: string): Promise<CustomDomain[]>;
|
|
103
|
+
listCustomDomains(id: string): Promise<CustomDomain[]>;
|
|
104
|
+
removeCustomDomain(id: string, hostname: string): Promise<void>;
|
|
96
105
|
reconcile(): Promise<void>;
|
|
97
106
|
health(): Promise<HealthStatus>;
|
|
98
107
|
mounts(id: string): Promise<MountSpecRedacted[]>;
|
|
@@ -146,6 +155,19 @@ export declare class SandboxResource implements Sandbox {
|
|
|
146
155
|
downloadFile(targetPath: string): Promise<Uint8Array>;
|
|
147
156
|
exposePort(port: number, options?: ExposePortOptions): Promise<ExposeResult>;
|
|
148
157
|
unexposePort(port: number): Promise<void>;
|
|
158
|
+
/**
|
|
159
|
+
* Per-sandbox custom-hostname bindings. Exposed as a namespaced accessor
|
|
160
|
+
* (rather than `addCustomDomain`/`removeCustomDomain`/`listCustomDomains`
|
|
161
|
+
* methods on the resource) so call sites read like
|
|
162
|
+
* `sandbox.customDomains.add("api.acme.com")`, mirroring the noun in the
|
|
163
|
+
* `/v1/.../custom-domains` URL space. A fresh object is returned per access
|
|
164
|
+
* so the closures always see the current `id` even after `refresh()`.
|
|
165
|
+
*/
|
|
166
|
+
get customDomains(): {
|
|
167
|
+
add(hostname: string): Promise<CustomDomain[]>;
|
|
168
|
+
remove(hostname: string): Promise<void>;
|
|
169
|
+
list(): Promise<CustomDomain[]>;
|
|
170
|
+
};
|
|
149
171
|
createSnapshot(name: string): Promise<SandboxSnapshot>;
|
|
150
172
|
start(): Promise<this>;
|
|
151
173
|
stop(): Promise<this>;
|
package/dist/internal/client.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { basename } from "node:path";
|
|
2
|
-
import { PATH_PREFIX as V1_PATH_PREFIX } from "./api/v1/paths.js";
|
|
2
|
+
import { PATH_PREFIX as V1_PATH_PREFIX, sandboxCustomDomainPath as v1SandboxCustomDomainPath, sandboxCustomDomainsPath as v1SandboxCustomDomainsPath, } from "./api/v1/paths.js";
|
|
3
3
|
import { Image } from "../Image.js";
|
|
4
4
|
const DEFAULT_API_VERSION = "v1";
|
|
5
5
|
const PATH_PREFIXES = {
|
|
@@ -220,6 +220,23 @@ export class APIClient {
|
|
|
220
220
|
async unexposePort(id, port) {
|
|
221
221
|
await this.doJSON("DELETE", `${this.versionPrefix}/sandboxes/${id}/ports/${port}`);
|
|
222
222
|
}
|
|
223
|
+
/**
|
|
224
|
+
* Bind a custom hostname to a sandbox. The server lowercases the hostname
|
|
225
|
+
* and returns the post-add list of bindings (sorted by hostname). Calling
|
|
226
|
+
* with an already-registered hostname is idempotent and returns the
|
|
227
|
+
* existing list.
|
|
228
|
+
*/
|
|
229
|
+
async addCustomDomain(id, hostname) {
|
|
230
|
+
const response = await this.doJSON("POST", v1SandboxCustomDomainsPath(this.versionPrefix, id), { hostname });
|
|
231
|
+
return response.custom_domains.map(fromApiCustomDomain);
|
|
232
|
+
}
|
|
233
|
+
async listCustomDomains(id) {
|
|
234
|
+
const response = await this.doJSON("GET", v1SandboxCustomDomainsPath(this.versionPrefix, id));
|
|
235
|
+
return response.custom_domains.map(fromApiCustomDomain);
|
|
236
|
+
}
|
|
237
|
+
async removeCustomDomain(id, hostname) {
|
|
238
|
+
await this.doJSON("DELETE", v1SandboxCustomDomainPath(this.versionPrefix, id, hostname));
|
|
239
|
+
}
|
|
223
240
|
async reconcile() {
|
|
224
241
|
await this.doJSON("POST", this.versioned("/admin/reconcile"));
|
|
225
242
|
}
|
|
@@ -334,6 +351,23 @@ export class SandboxResource {
|
|
|
334
351
|
async unexposePort(port) {
|
|
335
352
|
await this.client.unexposePort(this.id, port);
|
|
336
353
|
}
|
|
354
|
+
/**
|
|
355
|
+
* Per-sandbox custom-hostname bindings. Exposed as a namespaced accessor
|
|
356
|
+
* (rather than `addCustomDomain`/`removeCustomDomain`/`listCustomDomains`
|
|
357
|
+
* methods on the resource) so call sites read like
|
|
358
|
+
* `sandbox.customDomains.add("api.acme.com")`, mirroring the noun in the
|
|
359
|
+
* `/v1/.../custom-domains` URL space. A fresh object is returned per access
|
|
360
|
+
* so the closures always see the current `id` even after `refresh()`.
|
|
361
|
+
*/
|
|
362
|
+
get customDomains() {
|
|
363
|
+
const client = this.client;
|
|
364
|
+
const id = this.id;
|
|
365
|
+
return {
|
|
366
|
+
add: (hostname) => client.addCustomDomain(id, hostname),
|
|
367
|
+
remove: (hostname) => client.removeCustomDomain(id, hostname),
|
|
368
|
+
list: () => client.listCustomDomains(id),
|
|
369
|
+
};
|
|
370
|
+
}
|
|
337
371
|
async createSnapshot(name) {
|
|
338
372
|
return this.client.createSnapshot(this.id, name);
|
|
339
373
|
}
|
|
@@ -390,6 +424,7 @@ function toApiCreateOptions(options) {
|
|
|
390
424
|
lifecycle: options.lifecycle ? toApiLifecycle(options.lifecycle) : undefined,
|
|
391
425
|
failover: options.failover ? toApiFailover(options.failover) : undefined,
|
|
392
426
|
runtime: options.runtime,
|
|
427
|
+
custom_domains: options.customDomains,
|
|
393
428
|
};
|
|
394
429
|
}
|
|
395
430
|
function toApiRegisterSnapshotOptions(options) {
|
|
@@ -439,6 +474,7 @@ function toApiLifecycle(lifecycle) {
|
|
|
439
474
|
destroy_if_idle_for: lifecycle.destroyIfIdleFor,
|
|
440
475
|
stop_at_age: lifecycle.stopAtAge,
|
|
441
476
|
destroy_at_age: lifecycle.destroyAtAge,
|
|
477
|
+
serverless: lifecycle.serverless,
|
|
442
478
|
};
|
|
443
479
|
}
|
|
444
480
|
function toApiFailover(failover) {
|
|
@@ -521,6 +557,15 @@ function fromApiSession(session) {
|
|
|
521
557
|
attached: session.attached,
|
|
522
558
|
};
|
|
523
559
|
}
|
|
560
|
+
function fromApiCustomDomain(domain) {
|
|
561
|
+
return {
|
|
562
|
+
hostname: domain.hostname,
|
|
563
|
+
status: domain.status,
|
|
564
|
+
lastError: domain.last_error,
|
|
565
|
+
createdAt: domain.created_at,
|
|
566
|
+
updatedAt: domain.updated_at,
|
|
567
|
+
};
|
|
568
|
+
}
|
|
524
569
|
function fromApiExposedPort(port) {
|
|
525
570
|
return {
|
|
526
571
|
sandboxID: port.sandbox_id,
|
|
@@ -614,6 +659,9 @@ function fromApiLifecycle(lifecycle) {
|
|
|
614
659
|
if (lifecycle?.destroy_at_age !== undefined) {
|
|
615
660
|
result.destroyAtAge = lifecycle.destroy_at_age;
|
|
616
661
|
}
|
|
662
|
+
if (lifecycle?.serverless) {
|
|
663
|
+
result.serverless = true;
|
|
664
|
+
}
|
|
617
665
|
return result;
|
|
618
666
|
}
|
|
619
667
|
function fromApiFailover(failover) {
|
package/dist/types.d.ts
CHANGED
|
@@ -73,6 +73,13 @@ export interface Lifecycle {
|
|
|
73
73
|
stopAtAge?: number;
|
|
74
74
|
/** Duration in integer nanoseconds. */
|
|
75
75
|
destroyAtAge?: number;
|
|
76
|
+
/**
|
|
77
|
+
* Opt the sandbox into HTTP wake-on-request: auto-stop when idle,
|
|
78
|
+
* resume on the next inbound HTTP request. Requires `stopIfIdleFor`
|
|
79
|
+
* to be set explicitly — the server rejects `serverless: true`
|
|
80
|
+
* without an idle window. TCP and TLS exposures stay always-on.
|
|
81
|
+
*/
|
|
82
|
+
serverless?: boolean;
|
|
76
83
|
}
|
|
77
84
|
export type UpdateLifecycleOptions = Lifecycle;
|
|
78
85
|
export type FailoverPolicy = "none" | "recreate";
|
|
@@ -163,6 +170,13 @@ export interface CreateOptions {
|
|
|
163
170
|
* Not compatible with runtime="gvisor".
|
|
164
171
|
*/
|
|
165
172
|
gpus?: GPUOptions;
|
|
173
|
+
/**
|
|
174
|
+
* Custom hostnames to bind to this sandbox at create-time. Each entry is
|
|
175
|
+
* lowercased server-side and progresses through the standard custom-domain
|
|
176
|
+
* lifecycle (pending_dns → issuing → ready). Equivalent to calling
|
|
177
|
+
* `sandbox.customDomains.add(host)` for each entry after create.
|
|
178
|
+
*/
|
|
179
|
+
customDomains?: string[];
|
|
166
180
|
}
|
|
167
181
|
export interface ResizeOptions {
|
|
168
182
|
/** Number of CPU cores. Fractional values supported (e.g. 0.5). */
|
|
@@ -212,6 +226,21 @@ export interface ExposedPort {
|
|
|
212
226
|
publicURL: string;
|
|
213
227
|
createdAt: string;
|
|
214
228
|
}
|
|
229
|
+
/**
|
|
230
|
+
* Lifecycle states for a per-sandbox custom hostname.
|
|
231
|
+
* - "pending_dns": hostname registered; awaiting DNS to point at the daemon.
|
|
232
|
+
* - "issuing": DNS resolves; Caddy is acquiring an ACME certificate.
|
|
233
|
+
* - "ready": certificate issued; traffic served end-to-end on the host.
|
|
234
|
+
* - "failed": ACME or DNS validation failed; see `lastError`.
|
|
235
|
+
*/
|
|
236
|
+
export type CustomDomainStatus = "pending_dns" | "issuing" | "ready" | "failed";
|
|
237
|
+
export interface CustomDomain {
|
|
238
|
+
hostname: string;
|
|
239
|
+
status: CustomDomainStatus;
|
|
240
|
+
lastError?: string;
|
|
241
|
+
createdAt: string;
|
|
242
|
+
updatedAt: string;
|
|
243
|
+
}
|
|
215
244
|
/**
|
|
216
245
|
* Wire protocol an exposure publishes through:
|
|
217
246
|
* - "http": Caddy HTTP reverse proxy at https://<id>-<port>.<domain>.
|