@declaw/sdk 1.4.0 → 1.5.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/dist/index.d.cts CHANGED
@@ -1639,9 +1639,15 @@ declare class TemplateError extends SandboxError {
1639
1639
  }
1640
1640
  /** Thrown when a template build fails. */
1641
1641
  declare class BuildError extends TemplateError {
1642
+ /** The failed build's ID, when the error comes from a build that ran (`Template.build`). */
1643
+ buildId?: string;
1644
+ /** The failed build's full output, when the error comes from a build that ran. */
1645
+ logs: string[];
1642
1646
  constructor(message: string, opts?: {
1643
1647
  sandboxId?: string;
1644
1648
  code?: string;
1649
+ buildId?: string;
1650
+ logs?: string[];
1645
1651
  });
1646
1652
  }
1647
1653
  /** Thrown when a file upload fails. */
@@ -1769,7 +1775,13 @@ declare class TemplateBase {
1769
1775
  fromDockerfile(content: string): this;
1770
1776
  /** Add a run command (as array of command + args). */
1771
1777
  runCmd(cmds: string[]): this;
1772
- /** Add a file copy operation. */
1778
+ /**
1779
+ * Copy a local file into the template.
1780
+ *
1781
+ * Not supported yet: a template build cannot upload local files, so
1782
+ * building a template that uses `copy()` throws `InvalidArgumentError`.
1783
+ * Fetch the file in a `runCmd` step, or use `fromDockerfile`.
1784
+ */
1773
1785
  copy(src: string, dst: string, mode?: number): this;
1774
1786
  /** Set environment variables. */
1775
1787
  setEnvs(envs: Record<string, string>): this;
@@ -1777,22 +1789,37 @@ declare class TemplateBase {
1777
1789
  aptInstall(...packages: string[]): this;
1778
1790
  /** Set the start command. */
1779
1791
  setStartCmd(cmd: string): this;
1792
+ /**
1793
+ * Whether `copy()` was used. Builds reject such a template until builds can
1794
+ * upload local files.
1795
+ * @internal
1796
+ */
1797
+ hasCopies(): boolean;
1780
1798
  /** Serialize the template to a JSON-friendly object. */
1781
1799
  toJSON(): Record<string, any>;
1782
1800
  }
1783
1801
  /** Information about a template build. */
1784
1802
  interface BuildInfo {
1785
1803
  buildId: string;
1804
+ /** `building`, then `completed` or `failed`. */
1786
1805
  status: string;
1787
1806
  templateId?: string;
1807
+ /**
1808
+ * Build output. Empty in the response to starting a build; filled when
1809
+ * `Template.build()` returns a finished build.
1810
+ */
1811
+ logs: string[];
1788
1812
  }
1789
1813
  /** Parse raw JSON data into BuildInfo. */
1790
1814
  declare function parseBuildInfo(data: Record<string, any>): BuildInfo;
1791
1815
  /** Status of a template build. */
1792
1816
  interface TemplateBuildStatus {
1793
1817
  buildId: string;
1818
+ /** `building`, then `completed` or `failed`. */
1794
1819
  status: string;
1820
+ /** Build output so far. */
1795
1821
  logs: string[];
1822
+ templateId?: string;
1796
1823
  }
1797
1824
  /** Parse raw JSON data into TemplateBuildStatus. */
1798
1825
  declare function parseTemplateBuildStatus(data: Record<string, any>): TemplateBuildStatus;
@@ -1805,8 +1832,10 @@ interface TemplateBuildOpts {
1805
1832
  memoryMb?: number;
1806
1833
  /** Disk size in MB for the build (128–102400). */
1807
1834
  diskMb?: number;
1808
- /** Callback invoked for each build log entry. */
1835
+ /** Called with each new line of build output while `build()` waits. */
1809
1836
  onBuildLogs?: (log: string) => void;
1837
+ /** How long `build()` waits for the build to finish, in milliseconds. Defaults to one hour. */
1838
+ buildTimeout?: number;
1810
1839
  /** API key override. */
1811
1840
  apiKey?: string;
1812
1841
  /** Domain override. */
@@ -1831,20 +1860,26 @@ interface GetBuildStatusOpts {
1831
1860
  */
1832
1861
  declare class Template {
1833
1862
  /**
1834
- * Build a template and wait for completion.
1863
+ * Build a template and wait for the build to finish.
1864
+ *
1865
+ * Builds usually take several minutes. While waiting, each new line of build
1866
+ * output is passed to `onBuildLogs`. Sandboxes are created from the finished
1867
+ * template by its alias: `Sandbox.create({ template: alias })`.
1835
1868
  *
1836
- * Sends POST /templates/build with the template definition.
1837
- * Invokes onBuildLogs for each log entry in the response.
1869
+ * @throws {BuildError} The build failed; the error carries its logs.
1870
+ * @throws {TimeoutError} The build was still running after `buildTimeout`.
1871
+ * It keeps running; follow it with `getBuildStatus()`.
1872
+ * @throws {InvalidArgumentError} The template uses `copy()`, which is not
1873
+ * supported yet.
1838
1874
  */
1839
1875
  static build(template: TemplateBase, alias: string, opts?: TemplateBuildOpts): Promise<BuildInfo>;
1840
1876
  /**
1841
- * Start a template build in the background.
1842
- *
1843
- * Sends POST /templates/build with `background: true`.
1877
+ * Start a template build and return as soon as the server has accepted it,
1878
+ * with status `building`. Follow the build with `getBuildStatus()`.
1844
1879
  */
1845
- static buildInBackground(template: TemplateBase, alias: string, opts?: Omit<TemplateBuildOpts, 'onBuildLogs'>): Promise<BuildInfo>;
1880
+ static buildInBackground(template: TemplateBase, alias: string, opts?: Omit<TemplateBuildOpts, 'onBuildLogs' | 'buildTimeout'>): Promise<BuildInfo>;
1846
1881
  /**
1847
- * Get the status of a template build.
1882
+ * Get the status of a template build, including its logs so far.
1848
1883
  *
1849
1884
  * Sends GET /templates/builds/:buildId.
1850
1885
  */
package/dist/index.d.ts CHANGED
@@ -1639,9 +1639,15 @@ declare class TemplateError extends SandboxError {
1639
1639
  }
1640
1640
  /** Thrown when a template build fails. */
1641
1641
  declare class BuildError extends TemplateError {
1642
+ /** The failed build's ID, when the error comes from a build that ran (`Template.build`). */
1643
+ buildId?: string;
1644
+ /** The failed build's full output, when the error comes from a build that ran. */
1645
+ logs: string[];
1642
1646
  constructor(message: string, opts?: {
1643
1647
  sandboxId?: string;
1644
1648
  code?: string;
1649
+ buildId?: string;
1650
+ logs?: string[];
1645
1651
  });
1646
1652
  }
1647
1653
  /** Thrown when a file upload fails. */
@@ -1769,7 +1775,13 @@ declare class TemplateBase {
1769
1775
  fromDockerfile(content: string): this;
1770
1776
  /** Add a run command (as array of command + args). */
1771
1777
  runCmd(cmds: string[]): this;
1772
- /** Add a file copy operation. */
1778
+ /**
1779
+ * Copy a local file into the template.
1780
+ *
1781
+ * Not supported yet: a template build cannot upload local files, so
1782
+ * building a template that uses `copy()` throws `InvalidArgumentError`.
1783
+ * Fetch the file in a `runCmd` step, or use `fromDockerfile`.
1784
+ */
1773
1785
  copy(src: string, dst: string, mode?: number): this;
1774
1786
  /** Set environment variables. */
1775
1787
  setEnvs(envs: Record<string, string>): this;
@@ -1777,22 +1789,37 @@ declare class TemplateBase {
1777
1789
  aptInstall(...packages: string[]): this;
1778
1790
  /** Set the start command. */
1779
1791
  setStartCmd(cmd: string): this;
1792
+ /**
1793
+ * Whether `copy()` was used. Builds reject such a template until builds can
1794
+ * upload local files.
1795
+ * @internal
1796
+ */
1797
+ hasCopies(): boolean;
1780
1798
  /** Serialize the template to a JSON-friendly object. */
1781
1799
  toJSON(): Record<string, any>;
1782
1800
  }
1783
1801
  /** Information about a template build. */
1784
1802
  interface BuildInfo {
1785
1803
  buildId: string;
1804
+ /** `building`, then `completed` or `failed`. */
1786
1805
  status: string;
1787
1806
  templateId?: string;
1807
+ /**
1808
+ * Build output. Empty in the response to starting a build; filled when
1809
+ * `Template.build()` returns a finished build.
1810
+ */
1811
+ logs: string[];
1788
1812
  }
1789
1813
  /** Parse raw JSON data into BuildInfo. */
1790
1814
  declare function parseBuildInfo(data: Record<string, any>): BuildInfo;
1791
1815
  /** Status of a template build. */
1792
1816
  interface TemplateBuildStatus {
1793
1817
  buildId: string;
1818
+ /** `building`, then `completed` or `failed`. */
1794
1819
  status: string;
1820
+ /** Build output so far. */
1795
1821
  logs: string[];
1822
+ templateId?: string;
1796
1823
  }
1797
1824
  /** Parse raw JSON data into TemplateBuildStatus. */
1798
1825
  declare function parseTemplateBuildStatus(data: Record<string, any>): TemplateBuildStatus;
@@ -1805,8 +1832,10 @@ interface TemplateBuildOpts {
1805
1832
  memoryMb?: number;
1806
1833
  /** Disk size in MB for the build (128–102400). */
1807
1834
  diskMb?: number;
1808
- /** Callback invoked for each build log entry. */
1835
+ /** Called with each new line of build output while `build()` waits. */
1809
1836
  onBuildLogs?: (log: string) => void;
1837
+ /** How long `build()` waits for the build to finish, in milliseconds. Defaults to one hour. */
1838
+ buildTimeout?: number;
1810
1839
  /** API key override. */
1811
1840
  apiKey?: string;
1812
1841
  /** Domain override. */
@@ -1831,20 +1860,26 @@ interface GetBuildStatusOpts {
1831
1860
  */
1832
1861
  declare class Template {
1833
1862
  /**
1834
- * Build a template and wait for completion.
1863
+ * Build a template and wait for the build to finish.
1864
+ *
1865
+ * Builds usually take several minutes. While waiting, each new line of build
1866
+ * output is passed to `onBuildLogs`. Sandboxes are created from the finished
1867
+ * template by its alias: `Sandbox.create({ template: alias })`.
1835
1868
  *
1836
- * Sends POST /templates/build with the template definition.
1837
- * Invokes onBuildLogs for each log entry in the response.
1869
+ * @throws {BuildError} The build failed; the error carries its logs.
1870
+ * @throws {TimeoutError} The build was still running after `buildTimeout`.
1871
+ * It keeps running; follow it with `getBuildStatus()`.
1872
+ * @throws {InvalidArgumentError} The template uses `copy()`, which is not
1873
+ * supported yet.
1838
1874
  */
1839
1875
  static build(template: TemplateBase, alias: string, opts?: TemplateBuildOpts): Promise<BuildInfo>;
1840
1876
  /**
1841
- * Start a template build in the background.
1842
- *
1843
- * Sends POST /templates/build with `background: true`.
1877
+ * Start a template build and return as soon as the server has accepted it,
1878
+ * with status `building`. Follow the build with `getBuildStatus()`.
1844
1879
  */
1845
- static buildInBackground(template: TemplateBase, alias: string, opts?: Omit<TemplateBuildOpts, 'onBuildLogs'>): Promise<BuildInfo>;
1880
+ static buildInBackground(template: TemplateBase, alias: string, opts?: Omit<TemplateBuildOpts, 'onBuildLogs' | 'buildTimeout'>): Promise<BuildInfo>;
1846
1881
  /**
1847
- * Get the status of a template build.
1882
+ * Get the status of a template build, including its logs so far.
1848
1883
  *
1849
1884
  * Sends GET /templates/builds/:buildId.
1850
1885
  */
package/dist/index.js CHANGED
@@ -123,9 +123,15 @@ var TemplateError = class extends SandboxError {
123
123
  }
124
124
  };
125
125
  var BuildError = class extends TemplateError {
126
+ /** The failed build's ID, when the error comes from a build that ran (`Template.build`). */
127
+ buildId;
128
+ /** The failed build's full output, when the error comes from a build that ran. */
129
+ logs;
126
130
  constructor(message, opts) {
127
131
  super(message, opts);
128
132
  this.name = "BuildError";
133
+ this.buildId = opts?.buildId;
134
+ this.logs = opts?.logs ?? [];
129
135
  }
130
136
  };
131
137
  var FileUploadError = class extends SandboxError {
@@ -3108,7 +3114,13 @@ var TemplateBase = class {
3108
3114
  this._runCmds.push(cmds);
3109
3115
  return this;
3110
3116
  }
3111
- /** Add a file copy operation. */
3117
+ /**
3118
+ * Copy a local file into the template.
3119
+ *
3120
+ * Not supported yet: a template build cannot upload local files, so
3121
+ * building a template that uses `copy()` throws `InvalidArgumentError`.
3122
+ * Fetch the file in a `runCmd` step, or use `fromDockerfile`.
3123
+ */
3112
3124
  copy(src, dst, mode) {
3113
3125
  this._copies.push({ src, dst, mode });
3114
3126
  return this;
@@ -3128,6 +3140,14 @@ var TemplateBase = class {
3128
3140
  this._startCmd = cmd;
3129
3141
  return this;
3130
3142
  }
3143
+ /**
3144
+ * Whether `copy()` was used. Builds reject such a template until builds can
3145
+ * upload local files.
3146
+ * @internal
3147
+ */
3148
+ hasCopies() {
3149
+ return this._copies.length > 0;
3150
+ }
3131
3151
  /** Serialize the template to a JSON-friendly object. */
3132
3152
  toJSON() {
3133
3153
  if (this._dockerfile !== void 0) {
@@ -3139,14 +3159,11 @@ var TemplateBase = class {
3139
3159
  if (this._runCmds.length > 0) {
3140
3160
  result.run_cmds = this._runCmds.map((c) => c.join(" "));
3141
3161
  }
3142
- if (this._copies.length > 0) {
3143
- result.copies = this._copies;
3144
- }
3145
3162
  if (Object.keys(this._envs).length > 0) {
3146
3163
  result.envs = this._envs;
3147
3164
  }
3148
3165
  if (this._aptPackages.length > 0) {
3149
- result.apt_packages = this._aptPackages;
3166
+ result.packages = this._aptPackages;
3150
3167
  }
3151
3168
  if (this._startCmd !== void 0) {
3152
3169
  result.start_cmd = this._startCmd;
@@ -3158,19 +3175,70 @@ function parseBuildInfo(data) {
3158
3175
  return {
3159
3176
  buildId: data.build_id ?? data.buildId ?? "",
3160
3177
  status: data.status ?? "",
3161
- templateId: data.template_id ?? data.templateId ?? void 0
3178
+ templateId: data.template_id ?? data.templateId ?? void 0,
3179
+ logs: data.logs ?? []
3162
3180
  };
3163
3181
  }
3164
3182
  function parseTemplateBuildStatus(data) {
3165
3183
  return {
3166
3184
  buildId: data.build_id ?? data.buildId ?? "",
3167
3185
  status: data.status ?? "",
3168
- logs: data.logs ?? []
3186
+ // A build with no output yet serializes its logs as null.
3187
+ logs: data.logs ?? [],
3188
+ templateId: data.template_id ?? data.templateId ?? void 0
3169
3189
  };
3170
3190
  }
3171
3191
 
3172
3192
  // src/template/template.ts
3173
3193
  var VALID_BUILD_ID_RE = /^[a-zA-Z0-9_-]+$/;
3194
+ var BUILD_STATUS_COMPLETED = "completed";
3195
+ var BUILD_STATUS_FAILED = "failed";
3196
+ var DEFAULT_BUILD_TIMEOUT_MS = 60 * 60 * 1e3;
3197
+ var FAILURE_LOG_LINES = 20;
3198
+ var buildPolling = {
3199
+ /** How often a waiting build is re-read. */
3200
+ intervalMs: 3e3,
3201
+ /**
3202
+ * How long status checks may keep failing temporarily (5xx, 408, 429, or no
3203
+ * response) before the wait gives up. It rides out a sandbox-manager
3204
+ * restart; the build itself keeps running.
3205
+ */
3206
+ errorWindowMs: 2 * 60 * 1e3
3207
+ };
3208
+ var BUILD_LOG_TRUNCATION_NOTICE = "... [earlier build output truncated]";
3209
+ var LOG_ANCHOR_LINES = 64;
3210
+ var REJECTIONS = [
3211
+ AuthenticationError,
3212
+ ConflictError,
3213
+ InvalidArgumentError,
3214
+ NotEnoughSpaceError,
3215
+ NotFoundError
3216
+ ];
3217
+ var LogCursor = class {
3218
+ seen = 0;
3219
+ tail = [];
3220
+ newLines(logs) {
3221
+ const fresh = logs.length === 0 || logs[0] !== BUILD_LOG_TRUNCATION_NOTICE ? logs.slice(this.seen) : this.afterTail(logs);
3222
+ this.seen = logs.length;
3223
+ this.tail = [...this.tail, ...fresh].slice(-LOG_ANCHOR_LINES);
3224
+ return fresh;
3225
+ }
3226
+ afterTail(logs) {
3227
+ const window = logs.slice(1);
3228
+ const n = this.tail.length;
3229
+ if (n > 0) {
3230
+ for (let end = window.length; end >= n; end--) {
3231
+ if (window[end - 1] === this.tail[n - 1] && this.tail.every((line, i) => window[end - n + i] === line)) {
3232
+ return window.slice(end);
3233
+ }
3234
+ }
3235
+ }
3236
+ return logs;
3237
+ }
3238
+ };
3239
+ function isTemporaryPollError(err) {
3240
+ return err instanceof SandboxError && !REJECTIONS.some((Rejection) => err instanceof Rejection);
3241
+ }
3174
3242
  function assertValidBuildId(buildId) {
3175
3243
  if (!buildId || !VALID_BUILD_ID_RE.test(buildId)) {
3176
3244
  throw new InvalidArgumentError(
@@ -3178,72 +3246,131 @@ function assertValidBuildId(buildId) {
3178
3246
  );
3179
3247
  }
3180
3248
  }
3249
+ function buildRequestBody(template, alias, opts) {
3250
+ if (template.hasCopies()) {
3251
+ throw new InvalidArgumentError(
3252
+ "TemplateBase.copy() is not supported yet: a template build cannot upload local files. Fetch them in a runCmd step, or use fromDockerfile()."
3253
+ );
3254
+ }
3255
+ const body = {
3256
+ template: template.toJSON(),
3257
+ alias
3258
+ };
3259
+ if (opts?.cpuCount !== void 0) {
3260
+ body.cpu_count = opts.cpuCount;
3261
+ }
3262
+ if (opts?.memoryMb !== void 0) {
3263
+ body.memory_mb = opts.memoryMb;
3264
+ }
3265
+ if (opts?.diskMb !== void 0) {
3266
+ body.disk_mb = opts.diskMb;
3267
+ }
3268
+ return body;
3269
+ }
3270
+ function buildFailedError(status) {
3271
+ let message = `template build ${status.buildId} failed`;
3272
+ const tail = status.logs.slice(-FAILURE_LOG_LINES);
3273
+ if (tail.length > 0) {
3274
+ message += ":\n" + tail.join("\n");
3275
+ }
3276
+ return new BuildError(message, { buildId: status.buildId, logs: status.logs });
3277
+ }
3181
3278
  var Template = class {
3182
3279
  /**
3183
- * Build a template and wait for completion.
3280
+ * Build a template and wait for the build to finish.
3184
3281
  *
3185
- * Sends POST /templates/build with the template definition.
3186
- * Invokes onBuildLogs for each log entry in the response.
3282
+ * Builds usually take several minutes. While waiting, each new line of build
3283
+ * output is passed to `onBuildLogs`. Sandboxes are created from the finished
3284
+ * template by its alias: `Sandbox.create({ template: alias })`.
3285
+ *
3286
+ * @throws {BuildError} The build failed; the error carries its logs.
3287
+ * @throws {TimeoutError} The build was still running after `buildTimeout`.
3288
+ * It keeps running; follow it with `getBuildStatus()`.
3289
+ * @throws {InvalidArgumentError} The template uses `copy()`, which is not
3290
+ * supported yet.
3187
3291
  */
3188
3292
  static async build(template, alias, opts) {
3293
+ const body = buildRequestBody(template, alias, opts);
3189
3294
  const config = new ConnectionConfig({
3190
3295
  apiKey: opts?.apiKey,
3191
3296
  domain: opts?.domain,
3192
3297
  requestTimeout: opts?.requestTimeout
3193
3298
  });
3194
3299
  const client = getSharedClient(config);
3195
- const body = {
3196
- template: template.toJSON(),
3197
- alias
3198
- };
3199
- if (opts?.cpuCount !== void 0) {
3200
- body.cpu_count = opts.cpuCount;
3201
- }
3202
- if (opts?.memoryMb !== void 0) {
3203
- body.memory_mb = opts.memoryMb;
3204
- }
3205
- if (opts?.diskMb !== void 0) {
3206
- body.disk_mb = opts.diskMb;
3207
- }
3208
3300
  const data = await client.post("/templates/build", {
3209
3301
  json: body,
3210
3302
  timeout: opts?.requestTimeout
3211
3303
  });
3212
- const response = data;
3213
- const result = parseBuildInfo(response);
3214
- if (opts?.onBuildLogs && Array.isArray(response.logs)) {
3215
- for (const log of response.logs) {
3216
- opts.onBuildLogs(log);
3304
+ const info = parseBuildInfo(data);
3305
+ assertValidBuildId(info.buildId);
3306
+ let status = {
3307
+ buildId: info.buildId,
3308
+ status: info.status,
3309
+ logs: info.logs,
3310
+ templateId: info.templateId
3311
+ };
3312
+ const buildTimeout = opts?.buildTimeout ?? DEFAULT_BUILD_TIMEOUT_MS;
3313
+ const deadline = Date.now() + buildTimeout;
3314
+ const timedOut = (cause) => new TimeoutError(
3315
+ `template build ${info.buildId} was still running after ${buildTimeout}ms. It keeps running; follow it with Template.getBuildStatus('${info.buildId}').` + (cause instanceof Error ? ` Last status check: ${cause.message}` : "")
3316
+ );
3317
+ const cursor = new LogCursor();
3318
+ for (; ; ) {
3319
+ if (opts?.onBuildLogs) {
3320
+ for (const line of cursor.newLines(status.logs)) {
3321
+ opts.onBuildLogs(line);
3322
+ }
3323
+ }
3324
+ if (status.status === BUILD_STATUS_COMPLETED) {
3325
+ return {
3326
+ buildId: status.buildId,
3327
+ status: status.status,
3328
+ templateId: status.templateId ?? info.templateId,
3329
+ logs: status.logs
3330
+ };
3331
+ }
3332
+ if (status.status === BUILD_STATUS_FAILED) {
3333
+ throw buildFailedError(status);
3334
+ }
3335
+ if (Date.now() >= deadline) {
3336
+ throw timedOut();
3337
+ }
3338
+ let failingSince;
3339
+ for (; ; ) {
3340
+ await new Promise((resolve) => setTimeout(resolve, buildPolling.intervalMs));
3341
+ try {
3342
+ const next = await client.get(`/templates/builds/${info.buildId}`, {
3343
+ timeout: opts?.requestTimeout
3344
+ });
3345
+ status = parseTemplateBuildStatus(next);
3346
+ break;
3347
+ } catch (err) {
3348
+ if (!isTemporaryPollError(err)) {
3349
+ throw err;
3350
+ }
3351
+ failingSince ??= Date.now();
3352
+ if (Date.now() - failingSince >= buildPolling.errorWindowMs) {
3353
+ throw err;
3354
+ }
3355
+ if (Date.now() >= deadline) {
3356
+ throw timedOut(err);
3357
+ }
3358
+ }
3217
3359
  }
3218
3360
  }
3219
- return result;
3220
3361
  }
3221
3362
  /**
3222
- * Start a template build in the background.
3223
- *
3224
- * Sends POST /templates/build with `background: true`.
3363
+ * Start a template build and return as soon as the server has accepted it,
3364
+ * with status `building`. Follow the build with `getBuildStatus()`.
3225
3365
  */
3226
3366
  static async buildInBackground(template, alias, opts) {
3367
+ const body = buildRequestBody(template, alias, opts);
3227
3368
  const config = new ConnectionConfig({
3228
3369
  apiKey: opts?.apiKey,
3229
3370
  domain: opts?.domain,
3230
3371
  requestTimeout: opts?.requestTimeout
3231
3372
  });
3232
3373
  const client = getSharedClient(config);
3233
- const body = {
3234
- template: template.toJSON(),
3235
- alias,
3236
- background: true
3237
- };
3238
- if (opts?.cpuCount !== void 0) {
3239
- body.cpu_count = opts.cpuCount;
3240
- }
3241
- if (opts?.memoryMb !== void 0) {
3242
- body.memory_mb = opts.memoryMb;
3243
- }
3244
- if (opts?.diskMb !== void 0) {
3245
- body.disk_mb = opts.diskMb;
3246
- }
3247
3374
  const data = await client.post("/templates/build", {
3248
3375
  json: body,
3249
3376
  timeout: opts?.requestTimeout
@@ -3251,7 +3378,7 @@ var Template = class {
3251
3378
  return parseBuildInfo(data);
3252
3379
  }
3253
3380
  /**
3254
- * Get the status of a template build.
3381
+ * Get the status of a template build, including its logs so far.
3255
3382
  *
3256
3383
  * Sends GET /templates/builds/:buildId.
3257
3384
  */