@blaxel/core 0.3.3 → 0.3.4-preview.221

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.
@@ -226,6 +226,16 @@ export const listApplicationRevisions = (options) => {
226
226
  ...options
227
227
  });
228
228
  };
229
+ /**
230
+ * Get latest changelog entries
231
+ * Returns the latest public changelog entries for the controlplane UI. The origin response is intentionally not cached in memory; CloudFront caches this endpoint according to the Cache-Control header.
232
+ */
233
+ export const getChangelog = (options) => {
234
+ return (options?.client ?? _heyApiClient).get({
235
+ url: '/changelog',
236
+ ...options
237
+ });
238
+ };
229
239
  /**
230
240
  * Get platform configuration
231
241
  * Returns global platform configuration including available regions, countries, continents, and private locations for deployment policies.
@@ -327,6 +337,58 @@ export const updateCustomDomain = (options) => {
327
337
  }
328
338
  });
329
339
  };
340
+ /**
341
+ * List custom domain shares
342
+ * Returns the list of workspaces (and/or the account) that a custom domain is currently shared with.
343
+ */
344
+ export const listCustomDomainShares = (options) => {
345
+ return (options.client ?? _heyApiClient).get({
346
+ security: [
347
+ {
348
+ scheme: 'bearer',
349
+ type: 'http'
350
+ }
351
+ ],
352
+ url: '/customdomains/{domainName}/share',
353
+ ...options
354
+ });
355
+ };
356
+ /**
357
+ * Share a custom domain
358
+ * Shares a verified custom domain with another workspace of the same account by copying the domain record; the ACM certificate and CloudFront tenant stay with the owner and are reused (not re-provisioned). Use targetWorkspace "account" to make the domain usable by every workspace of the account. Cross-account sharing is not supported.
359
+ */
360
+ export const shareCustomDomain = (options) => {
361
+ return (options.client ?? _heyApiClient).post({
362
+ security: [
363
+ {
364
+ scheme: 'bearer',
365
+ type: 'http'
366
+ }
367
+ ],
368
+ url: '/customdomains/{domainName}/share',
369
+ ...options,
370
+ headers: {
371
+ 'Content-Type': 'application/json',
372
+ ...options?.headers
373
+ }
374
+ });
375
+ };
376
+ /**
377
+ * Unshare a custom domain
378
+ * Revokes sharing of a custom domain with a target workspace (or the account when targetWorkspace is "account"). Removes the shared copy / clears the account-global marker; the owner's domain is not affected.
379
+ */
380
+ export const unshareCustomDomain = (options) => {
381
+ return (options.client ?? _heyApiClient).delete({
382
+ security: [
383
+ {
384
+ scheme: 'bearer',
385
+ type: 'http'
386
+ }
387
+ ],
388
+ url: '/customdomains/{domainName}/share/{targetWorkspace}',
389
+ ...options
390
+ });
391
+ };
330
392
  /**
331
393
  * Verify custom domain
332
394
  */
@@ -446,6 +508,22 @@ export const createDriveAccessToken = (options) => {
446
508
  ...options
447
509
  });
448
510
  };
511
+ /**
512
+ * Get drive by external ID
513
+ * Returns a drive matching the given external ID. If no drive is found, returns 404.
514
+ */
515
+ export const getDriveByExternalId = (options) => {
516
+ return (options.client ?? _heyApiClient).get({
517
+ security: [
518
+ {
519
+ scheme: 'bearer',
520
+ type: 'http'
521
+ }
522
+ ],
523
+ url: '/drives/by-external-id/{externalId}',
524
+ ...options
525
+ });
526
+ };
449
527
  /**
450
528
  * Get drive token JWKS
451
529
  * Returns the JSON Web Key Set containing the Ed25519 public key used to verify drive access tokens. Other S3-compatible storage can use this endpoint to validate Bearer tokens.
@@ -1538,6 +1616,26 @@ export const updateSandbox = (options) => {
1538
1616
  }
1539
1617
  });
1540
1618
  };
1619
+ /**
1620
+ * Fork sandbox
1621
+ * Forks a sandbox into a new sandbox or application. When forking to a sandbox, the target must not already exist (409 if it does). When forking to an application, a new revision is added if the app already exists, or a new application is created. This is a WIP endpoint — the full implementation depends on the execution plane.
1622
+ */
1623
+ export const forkSandbox = (options) => {
1624
+ return (options.client ?? _heyApiClient).post({
1625
+ security: [
1626
+ {
1627
+ scheme: 'bearer',
1628
+ type: 'http'
1629
+ }
1630
+ ],
1631
+ url: '/sandboxes/{sandboxName}/fork',
1632
+ ...options,
1633
+ headers: {
1634
+ 'Content-Type': 'application/json',
1635
+ ...options?.headers
1636
+ }
1637
+ });
1638
+ };
1541
1639
  /**
1542
1640
  * List Sandbox Previews
1543
1641
  * Returns a list of Sandbox Previews in the workspace.
@@ -1782,6 +1880,58 @@ export const updateSandboxSchedule = (options) => {
1782
1880
  }
1783
1881
  });
1784
1882
  };
1883
+ /**
1884
+ * List sandbox snapshots
1885
+ * Returns a list of snapshots for the specified sandbox.
1886
+ */
1887
+ export const listSandboxSnapshots = (options) => {
1888
+ return (options.client ?? _heyApiClient).get({
1889
+ security: [
1890
+ {
1891
+ scheme: 'bearer',
1892
+ type: 'http'
1893
+ }
1894
+ ],
1895
+ url: '/sandboxes/{sandboxName}/snapshots',
1896
+ ...options
1897
+ });
1898
+ };
1899
+ /**
1900
+ * Create sandbox snapshot
1901
+ * Creates a point-in-time snapshot of a sandbox. Snapshots capture the sandbox state and can be used for forking into new sandboxes or applications. This is a WIP endpoint — the full implementation depends on the execution plane.
1902
+ */
1903
+ export const createSandboxSnapshot = (options) => {
1904
+ return (options.client ?? _heyApiClient).post({
1905
+ security: [
1906
+ {
1907
+ scheme: 'bearer',
1908
+ type: 'http'
1909
+ }
1910
+ ],
1911
+ url: '/sandboxes/{sandboxName}/snapshots',
1912
+ ...options,
1913
+ headers: {
1914
+ 'Content-Type': 'application/json',
1915
+ ...options?.headers
1916
+ }
1917
+ });
1918
+ };
1919
+ /**
1920
+ * Delete sandbox snapshot
1921
+ * Deletes a snapshot of a sandbox by its ID.
1922
+ */
1923
+ export const deleteSandboxSnapshot = (options) => {
1924
+ return (options.client ?? _heyApiClient).delete({
1925
+ security: [
1926
+ {
1927
+ scheme: 'bearer',
1928
+ type: 'http'
1929
+ }
1930
+ ],
1931
+ url: '/sandboxes/{sandboxName}/snapshots/{snapshotId}',
1932
+ ...options
1933
+ });
1934
+ };
1785
1935
  /**
1786
1936
  * Get sandbox by external ID
1787
1937
  * Returns the most recent non-terminated sandbox matching the given external ID. If no active sandbox is found, returns 404.
@@ -2218,6 +2368,22 @@ export const updateVolume = (options) => {
2218
2368
  }
2219
2369
  });
2220
2370
  };
2371
+ /**
2372
+ * Get volume by external ID
2373
+ * Returns an active volume matching the given external ID. If no active volume is found, returns 404.
2374
+ */
2375
+ export const getVolumeByExternalId = (options) => {
2376
+ return (options.client ?? _heyApiClient).get({
2377
+ security: [
2378
+ {
2379
+ scheme: 'bearer',
2380
+ type: 'http'
2381
+ }
2382
+ ],
2383
+ url: '/volumes/by-external-id/{externalId}',
2384
+ ...options
2385
+ });
2386
+ };
2221
2387
  /**
2222
2388
  * List all VPCs in the workspace
2223
2389
  */
@@ -2498,38 +2664,6 @@ export const updateWorkspace = (options) => {
2498
2664
  }
2499
2665
  });
2500
2666
  };
2501
- /**
2502
- * Decline invitation to workspace
2503
- * Declines an invitation to a workspace.
2504
- */
2505
- export const declineWorkspaceInvitation = (options) => {
2506
- return (options.client ?? _heyApiClient).post({
2507
- security: [
2508
- {
2509
- scheme: 'bearer',
2510
- type: 'http'
2511
- }
2512
- ],
2513
- url: '/workspaces/{workspaceName}/decline',
2514
- ...options
2515
- });
2516
- };
2517
- /**
2518
- * Accept invitation to workspace
2519
- * Accepts an invitation to a workspace.
2520
- */
2521
- export const acceptWorkspaceInvitation = (options) => {
2522
- return (options.client ?? _heyApiClient).post({
2523
- security: [
2524
- {
2525
- scheme: 'bearer',
2526
- type: 'http'
2527
- }
2528
- ],
2529
- url: '/workspaces/{workspaceName}/join',
2530
- ...options
2531
- });
2532
- };
2533
2667
  /**
2534
2668
  * Leave workspace
2535
2669
  * Leaves a workspace.
@@ -22,8 +22,8 @@ function missingCredentialsMessage() {
22
22
  return "No Blaxel credentials found. Set the BL_API_KEY and BL_WORKSPACE environment variables, or run `bl login`.";
23
23
  }
24
24
  // Build info - these placeholders are replaced at build time by build:replace-imports
25
- const BUILD_VERSION = "0.3.3";
26
- const BUILD_COMMIT = "5bb620b84748d321cde1d41e252eb5681cca991d";
25
+ const BUILD_VERSION = "0.3.4-preview.221";
26
+ const BUILD_COMMIT = "9d266f265a8c16a6786df32a1f37a8c19e3933d6";
27
27
  const BUILD_SENTRY_DSN = "https://fd5e60e1c9820e1eef5ccebb84a07127@o4508714045276160.ingest.us.sentry.io/4510465864564736";
28
28
  const BLAXEL_API_VERSION = "2026-04-28";
29
29
  // Cache for config.yaml tracking value
@@ -69,6 +69,19 @@ export function normalizeVolumes(volumes) {
69
69
  mountPath: volume.mountPath,
70
70
  readOnly: 'readOnly' in volume ? volume.readOnly : false
71
71
  };
72
+ // Ephemeral volumes carry a type and a required size (in MB)
73
+ if ('type' in volume && volume.type) {
74
+ volumeAttachment.type = volume.type;
75
+ }
76
+ if (volumeAttachment.type === 'ephemeral') {
77
+ if (typeof volume.sizeMb !== 'number' || !(volume.sizeMb > 0)) {
78
+ throw new Error(`Ephemeral volume '${volume.name}' must have a positive 'sizeMb': ${JSON.stringify(volume)}`);
79
+ }
80
+ volumeAttachment.sizeMb = volume.sizeMb;
81
+ }
82
+ else if ('sizeMb' in volume && typeof volume.sizeMb === 'number') {
83
+ volumeAttachment.sizeMb = volume.sizeMb;
84
+ }
72
85
  volumeObjects.push(volumeAttachment);
73
86
  }
74
87
  else {