@aerol-ai/aerolvm-sdk 0.3.1 → 0.3.2

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/MicroVM.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { type APIVersion } from "./internal/client.js";
2
2
  import { Sandbox } from "./Sandbox.js";
3
3
  import { Image } from "./Image.js";
4
- import type { BuildImageOptions, BuildImageResult, CreateOptions, CreateSessionOptions, ExecStreamHandle, ExecStreamOptions, HealthStatus, Lifecycle, ListOptions, MountSpecRedacted, RegisterSnapshotOptions, ResizeOptions, SandboxSnapshot, Session, SessionAttachHandle, SessionAttachOptions } from "./types.js";
4
+ import type { BuildImageOptions, BuildImageResult, CreateOptions, CreateSessionOptions, ExecStreamHandle, ExecStreamOptions, HealthStatus, IngressTarget, Lifecycle, ListOptions, MountSpecRedacted, RegisterSnapshotOptions, ResizeOptions, SandboxSnapshot, Session, SessionAttachHandle, SessionAttachOptions } from "./types.js";
5
5
  type FetchLike = typeof fetch;
6
6
  export interface MicroVMConfig {
7
7
  patToken?: string;
@@ -51,6 +51,16 @@ export declare class MicroVM {
51
51
  sessionLog(sandboxID: string, sessionID: string): Promise<Uint8Array>;
52
52
  sessionRecording(sandboxID: string, sessionID: string): Promise<Uint8Array>;
53
53
  attachSession(sandboxID: string, sessionID: string, options?: SessionAttachOptions): SessionAttachHandle;
54
+ /**
55
+ * Cluster-level DNS helpers. Exposed as a namespaced accessor (rather
56
+ * than a flat `ingressDNS()` method) so call sites read like
57
+ * `microvm.dns.target()`, mirroring the per-sandbox `sandbox.customDomains`
58
+ * pattern. A fresh object is returned per access so the closures always
59
+ * see the current client even if MicroVM is later extended.
60
+ */
61
+ get dns(): {
62
+ target(): Promise<IngressTarget>;
63
+ };
54
64
  private wrap;
55
65
  }
56
66
  export {};
package/dist/MicroVM.js CHANGED
@@ -109,6 +109,19 @@ export class MicroVM {
109
109
  attachSession(sandboxID, sessionID, options = {}) {
110
110
  return this.client.attachSession(sandboxID, sessionID, options);
111
111
  }
112
+ /**
113
+ * Cluster-level DNS helpers. Exposed as a namespaced accessor (rather
114
+ * than a flat `ingressDNS()` method) so call sites read like
115
+ * `microvm.dns.target()`, mirroring the per-sandbox `sandbox.customDomains`
116
+ * pattern. A fresh object is returned per access so the closures always
117
+ * see the current client even if MicroVM is later extended.
118
+ */
119
+ get dns() {
120
+ const client = this.client;
121
+ return {
122
+ target: () => client.ingressDNS(),
123
+ };
124
+ }
112
125
  wrap(sandbox) {
113
126
  return new Sandbox(this.client, sandbox);
114
127
  }
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, 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";
5
+ export type { BinaryLike, BuildImageOptions, BuildImagePushOptions, BuildImageResult, CreateOptions, CreateSessionOptions, CustomDomain, CustomDomainDNSRecords, CustomDomainStatus, DNSRecord, DNSRecordType, ExecRequest, ExecResult, ExecExitInfo, ExposedPort, ExposePortOptions, ExposeProtocol, ExposeResult, Failover, FailoverPolicy, HealthStatus, IngressTarget, IngressTargetSource, Lifecycle, MountSpec, MountSpecRedacted, MountType, RegisterSnapshotOptions, RegistryAuth, ResizeOptions, Sandbox as SandboxData, SandboxSnapshot, SandboxStatus, Session, SessionAttachHandle, SessionAttachOptions, SessionStatus, UpdateLifecycleOptions, } from "./types.js";
@@ -14,3 +14,15 @@ export declare function sandboxCustomDomainsPath(prefix: string, id: string): st
14
14
  * `DELETE /v1/sandboxes/{id}/custom-domains/{hostname}`.
15
15
  */
16
16
  export declare function sandboxCustomDomainPath(prefix: string, id: string, hostname: string): string;
17
+ /**
18
+ * URL for the cluster's published ingress address(es), used by
19
+ * `microvm.dns.target()` to render the CNAME/A target a user must point
20
+ * custom-domain DNS at.
21
+ */
22
+ export declare function ingressDNSPath(prefix: string): string;
23
+ /**
24
+ * URL for the ready-to-paste DNS records of one sandbox's custom-domain
25
+ * bindings. Sibling of {@link sandboxCustomDomainsPath} — same `id` rules
26
+ * apply.
27
+ */
28
+ export declare function sandboxCustomDomainDNSPath(prefix: string, id: string): string;
@@ -24,3 +24,19 @@ export function sandboxCustomDomainsPath(prefix, id) {
24
24
  export function sandboxCustomDomainPath(prefix, id, hostname) {
25
25
  return `${prefix}/sandboxes/${id}/custom-domains/${encodeURIComponent(hostname)}`;
26
26
  }
27
+ /**
28
+ * URL for the cluster's published ingress address(es), used by
29
+ * `microvm.dns.target()` to render the CNAME/A target a user must point
30
+ * custom-domain DNS at.
31
+ */
32
+ export function ingressDNSPath(prefix) {
33
+ return `${prefix}/ingress/dns`;
34
+ }
35
+ /**
36
+ * URL for the ready-to-paste DNS records of one sandbox's custom-domain
37
+ * bindings. Sibling of {@link sandboxCustomDomainsPath} — same `id` rules
38
+ * apply.
39
+ */
40
+ export function sandboxCustomDomainDNSPath(prefix, id) {
41
+ return `${prefix}/sandboxes/${id}/custom-domains/dns`;
42
+ }
@@ -1,5 +1,5 @@
1
1
  import { Image } from "../Image.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";
2
+ import type { BinaryLike, BuildImageOptions, BuildImageResult, CreateOptions, CreateSessionOptions, CustomDomain, CustomDomainDNSRecords, ExecRequest, ExecResult, ExecStreamHandle, ExecStreamOptions, ExposedPort, ExposePortOptions, ExposeResult, Failover, HealthStatus, IngressTarget, 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
@@ -102,6 +102,17 @@ export declare class APIClient {
102
102
  addCustomDomain(id: string, hostname: string): Promise<CustomDomain[]>;
103
103
  listCustomDomains(id: string): Promise<CustomDomain[]>;
104
104
  removeCustomDomain(id: string, hostname: string): Promise<void>;
105
+ /**
106
+ * Fetch the cluster's published ingress address(es) — the CNAME/A target
107
+ * a user must point custom-domain DNS at. Field names already match the
108
+ * SDK's camelCase shape on the wire, so no translation is needed.
109
+ */
110
+ ingressDNS(): Promise<IngressTarget>;
111
+ /**
112
+ * Fetch the ready-to-paste DNS records for one sandbox's custom-domain
113
+ * bindings, along with the {@link IngressTarget} they were composed from.
114
+ */
115
+ customDomainDNS(id: string): Promise<CustomDomainDNSRecords>;
105
116
  reconcile(): Promise<void>;
106
117
  health(): Promise<HealthStatus>;
107
118
  mounts(id: string): Promise<MountSpecRedacted[]>;
@@ -167,6 +178,7 @@ export declare class SandboxResource implements Sandbox {
167
178
  add(hostname: string): Promise<CustomDomain[]>;
168
179
  remove(hostname: string): Promise<void>;
169
180
  list(): Promise<CustomDomain[]>;
181
+ dns(): Promise<CustomDomainDNSRecords>;
170
182
  };
171
183
  createSnapshot(name: string): Promise<SandboxSnapshot>;
172
184
  start(): Promise<this>;
@@ -1,5 +1,5 @@
1
1
  import { basename } from "node:path";
2
- import { PATH_PREFIX as V1_PATH_PREFIX, sandboxCustomDomainPath as v1SandboxCustomDomainPath, sandboxCustomDomainsPath as v1SandboxCustomDomainsPath, } from "./api/v1/paths.js";
2
+ import { PATH_PREFIX as V1_PATH_PREFIX, ingressDNSPath as v1IngressDNSPath, sandboxCustomDomainDNSPath as v1SandboxCustomDomainDNSPath, 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 = {
@@ -237,6 +237,21 @@ export class APIClient {
237
237
  async removeCustomDomain(id, hostname) {
238
238
  await this.doJSON("DELETE", v1SandboxCustomDomainPath(this.versionPrefix, id, hostname));
239
239
  }
240
+ /**
241
+ * Fetch the cluster's published ingress address(es) — the CNAME/A target
242
+ * a user must point custom-domain DNS at. Field names already match the
243
+ * SDK's camelCase shape on the wire, so no translation is needed.
244
+ */
245
+ async ingressDNS() {
246
+ return this.doJSON("GET", v1IngressDNSPath(this.versionPrefix));
247
+ }
248
+ /**
249
+ * Fetch the ready-to-paste DNS records for one sandbox's custom-domain
250
+ * bindings, along with the {@link IngressTarget} they were composed from.
251
+ */
252
+ async customDomainDNS(id) {
253
+ return this.doJSON("GET", v1SandboxCustomDomainDNSPath(this.versionPrefix, id));
254
+ }
240
255
  async reconcile() {
241
256
  await this.doJSON("POST", this.versioned("/admin/reconcile"));
242
257
  }
@@ -366,6 +381,7 @@ export class SandboxResource {
366
381
  add: (hostname) => client.addCustomDomain(id, hostname),
367
382
  remove: (hostname) => client.removeCustomDomain(id, hostname),
368
383
  list: () => client.listCustomDomains(id),
384
+ dns: () => client.customDomainDNS(id),
369
385
  };
370
386
  }
371
387
  async createSnapshot(name) {
package/dist/types.d.ts CHANGED
@@ -241,6 +241,54 @@ export interface CustomDomain {
241
241
  createdAt: string;
242
242
  updatedAt: string;
243
243
  }
244
+ /**
245
+ * Where the SDK derived the ingress address(es) from. Reflects how the
246
+ * operator deployed the cluster:
247
+ * - "hostname": the cluster gossips a stable hostname (CNAME target).
248
+ * - "ips": one or more raw ingress IPs (one A/AAAA record per IP).
249
+ * - "mixed": some nodes gossip a hostname, others raw IPs — prefer
250
+ * the hostname but render both so apex domains still work.
251
+ * - "unknown": no ingress node has gossiped a public address yet; the
252
+ * target is unusable and callers should surface that, not
253
+ * guess.
254
+ */
255
+ export type IngressTargetSource = "hostname" | "ips" | "mixed" | "unknown";
256
+ /**
257
+ * The cluster's published ingress address(es) — the value that DNS for a
258
+ * custom domain must ultimately resolve to. Returned by `microvm.dns.target()`
259
+ * and embedded in {@link CustomDomainDNSRecords}.
260
+ */
261
+ export interface IngressTarget {
262
+ hostname?: string;
263
+ ips?: string[];
264
+ source: IngressTargetSource;
265
+ }
266
+ /** DNS record types the daemon emits for custom-domain wiring. */
267
+ export type DNSRecordType = "CNAME" | "A" | "AAAA";
268
+ /**
269
+ * One ready-to-paste DNS record a user adds at their DNS provider to make a
270
+ * custom domain reach the cluster. `name` is the leftmost label (or "@" for
271
+ * apex) the way DNS UIs accept it. `notes` carries provider-specific gotchas
272
+ * the daemon pre-renders (e.g. Cloudflare "DNS only, gray cloud") when
273
+ * applicable.
274
+ */
275
+ export interface DNSRecord {
276
+ hostname: string;
277
+ type: DNSRecordType;
278
+ name: string;
279
+ value: string;
280
+ notes?: string;
281
+ }
282
+ /**
283
+ * Response from `sandbox.customDomains.dns()`. `records` is the flat
284
+ * ready-to-paste list (one row per custom domain × per ingress address);
285
+ * `target` is the raw aggregation the records were composed from, included
286
+ * so callers can render their own UI without a second round trip.
287
+ */
288
+ export interface CustomDomainDNSRecords {
289
+ records: DNSRecord[];
290
+ target: IngressTarget;
291
+ }
244
292
  /**
245
293
  * Wire protocol an exposure publishes through:
246
294
  * - "http": Caddy HTTP reverse proxy at https://<id>-<port>.<domain>.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aerol-ai/aerolvm-sdk",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,7 +21,7 @@
21
21
  "test": "tsc -p tsconfig.test.json --outDir dist-test && node --test dist-test/*.test.js dist-test/internal/*.test.js"
22
22
  },
23
23
  "devDependencies": {
24
- "@types/node": "^25.8.0",
24
+ "@types/node": "^25.9.1",
25
25
  "typescript": "^6.0.3",
26
26
  "tsx": "^4.22.3"
27
27
  }