@blaxel/core 0.2.89 → 0.2.90-dev.181

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.
Files changed (80) hide show
  1. package/README.md +37 -2
  2. package/dist/cjs/.tsbuildinfo +1 -1
  3. package/dist/cjs/client/sdk.gen.js +63 -12
  4. package/dist/cjs/common/h2fetch.js +1 -1
  5. package/dist/cjs/common/pagination.js +87 -0
  6. package/dist/cjs/common/pagination.test.js +62 -0
  7. package/dist/cjs/common/settings.js +3 -3
  8. package/dist/cjs/common/settings.test.js +3 -3
  9. package/dist/cjs/drive/index.js +39 -3
  10. package/dist/cjs/index.js +1 -0
  11. package/dist/cjs/jobs/jobs.js +42 -9
  12. package/dist/cjs/sandbox/client/sdk.gen.js +1 -1
  13. package/dist/cjs/sandbox/preview.js +8 -3
  14. package/dist/cjs/sandbox/sandbox.js +41 -4
  15. package/dist/cjs/types/client/sdk.gen.d.ts +34 -19
  16. package/dist/cjs/types/client/types.gen.d.ts +704 -22
  17. package/dist/cjs/types/common/pagination.d.ts +35 -0
  18. package/dist/cjs/types/common/pagination.test.d.ts +1 -0
  19. package/dist/cjs/types/drive/index.d.ts +35 -4
  20. package/dist/cjs/types/index.d.ts +1 -0
  21. package/dist/cjs/types/jobs/jobs.d.ts +33 -3
  22. package/dist/cjs/types/sandbox/client/sdk.gen.d.ts +1 -1
  23. package/dist/cjs/types/sandbox/client/types.gen.d.ts +24 -0
  24. package/dist/cjs/types/sandbox/preview.d.ts +2 -2
  25. package/dist/cjs/types/sandbox/sandbox.d.ts +36 -2
  26. package/dist/cjs/types/volume/index.d.ts +37 -4
  27. package/dist/cjs/volume/index.js +41 -3
  28. package/dist/cjs-browser/.tsbuildinfo +1 -1
  29. package/dist/cjs-browser/client/sdk.gen.js +63 -12
  30. package/dist/cjs-browser/common/pagination.js +87 -0
  31. package/dist/cjs-browser/common/pagination.test.js +62 -0
  32. package/dist/cjs-browser/common/settings.js +3 -3
  33. package/dist/cjs-browser/common/settings.test.js +3 -3
  34. package/dist/cjs-browser/drive/index.js +39 -3
  35. package/dist/cjs-browser/index.js +1 -0
  36. package/dist/cjs-browser/jobs/jobs.js +42 -9
  37. package/dist/cjs-browser/sandbox/client/sdk.gen.js +1 -1
  38. package/dist/cjs-browser/sandbox/preview.js +8 -3
  39. package/dist/cjs-browser/sandbox/sandbox.js +41 -4
  40. package/dist/cjs-browser/types/client/sdk.gen.d.ts +34 -19
  41. package/dist/cjs-browser/types/client/types.gen.d.ts +704 -22
  42. package/dist/cjs-browser/types/common/pagination.d.ts +35 -0
  43. package/dist/cjs-browser/types/common/pagination.test.d.ts +1 -0
  44. package/dist/cjs-browser/types/drive/index.d.ts +35 -4
  45. package/dist/cjs-browser/types/index.d.ts +1 -0
  46. package/dist/cjs-browser/types/jobs/jobs.d.ts +33 -3
  47. package/dist/cjs-browser/types/sandbox/client/sdk.gen.d.ts +1 -1
  48. package/dist/cjs-browser/types/sandbox/client/types.gen.d.ts +24 -0
  49. package/dist/cjs-browser/types/sandbox/preview.d.ts +2 -2
  50. package/dist/cjs-browser/types/sandbox/sandbox.d.ts +36 -2
  51. package/dist/cjs-browser/types/volume/index.d.ts +37 -4
  52. package/dist/cjs-browser/volume/index.js +41 -3
  53. package/dist/esm/.tsbuildinfo +1 -1
  54. package/dist/esm/client/sdk.gen.js +57 -9
  55. package/dist/esm/common/h2fetch.js +1 -1
  56. package/dist/esm/common/pagination.js +83 -0
  57. package/dist/esm/common/pagination.test.js +60 -0
  58. package/dist/esm/common/settings.js +3 -3
  59. package/dist/esm/common/settings.test.js +3 -3
  60. package/dist/esm/drive/index.js +39 -3
  61. package/dist/esm/index.js +1 -0
  62. package/dist/esm/jobs/jobs.js +42 -9
  63. package/dist/esm/sandbox/client/sdk.gen.js +1 -1
  64. package/dist/esm/sandbox/preview.js +8 -3
  65. package/dist/esm/sandbox/sandbox.js +41 -4
  66. package/dist/esm/volume/index.js +41 -3
  67. package/dist/esm-browser/.tsbuildinfo +1 -1
  68. package/dist/esm-browser/client/sdk.gen.js +57 -9
  69. package/dist/esm-browser/common/pagination.js +83 -0
  70. package/dist/esm-browser/common/pagination.test.js +60 -0
  71. package/dist/esm-browser/common/settings.js +3 -3
  72. package/dist/esm-browser/common/settings.test.js +3 -3
  73. package/dist/esm-browser/drive/index.js +39 -3
  74. package/dist/esm-browser/index.js +1 -0
  75. package/dist/esm-browser/jobs/jobs.js +42 -9
  76. package/dist/esm-browser/sandbox/client/sdk.gen.js +1 -1
  77. package/dist/esm-browser/sandbox/preview.js +8 -3
  78. package/dist/esm-browser/sandbox/sandbox.js +41 -4
  79. package/dist/esm-browser/volume/index.js +41 -3
  80. package/package.json +1 -1
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  // This file is auto-generated by @hey-api/openapi-ts
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.createJob = exports.listJobs = exports.getIntegrationConnectionModel = exports.listIntegrationConnectionModels = exports.getIntegrationConnectionModelEndpointConfigurations = exports.updateIntegrationConnection = exports.getIntegrationConnection = exports.deleteIntegrationConnection = exports.createIntegrationConnection = exports.listIntegrationConnections = exports.getIntegration = exports.deleteImageTag = exports.unshareImage = exports.shareImage = exports.listImageShares = exports.getImage = exports.deleteImage = exports.createImage = exports.listImages = exports.cleanupImages = exports.listFunctionRevisions = exports.updateFunction = exports.getFunction = exports.deleteFunction = exports.createFunction = exports.listFunctions = exports.testFeatureFlag = exports.getWorkspaceFeatures = exports.listAllEgressIps = exports.listAllEgressGateways = exports.getDriveJwks = exports.createDriveAccessToken = exports.updateDrive = exports.getDrive = exports.deleteDrive = exports.createDrive = exports.listDrives = exports.verifyCustomDomain = exports.updateCustomDomain = exports.getCustomDomain = exports.deleteCustomDomain = exports.createCustomDomain = exports.listCustomDomains = exports.getConfiguration = exports.listAgentRevisions = exports.updateAgent = exports.getAgent = exports.deleteAgent = exports.createAgent = exports.listAgents = void 0;
5
- exports.inviteWorkspaceUser = exports.listWorkspaceUsers = exports.getTemplate = exports.listTemplates = exports.deleteApiKeyForServiceAccount = exports.createApiKeyForServiceAccount = exports.listApiKeysForServiceAccount = exports.updateWorkspaceServiceAccount = exports.deleteWorkspaceServiceAccount = exports.createWorkspaceServiceAccount = exports.getWorkspaceServiceAccounts = exports.deleteSandboxPreviewToken = exports.createSandboxPreviewToken = exports.listSandboxPreviewTokens = exports.updateSandboxPreview = exports.getSandboxPreview = exports.deleteSandboxPreview = exports.createSandboxPreview = exports.listSandboxPreviews = exports.updateSandbox = exports.getSandbox = exports.deleteSandbox = exports.createSandbox = exports.listSandboxes = exports.listSandboxHubDefinitions = exports.listPublicIps = exports.updatePolicy = exports.getPolicy = exports.deletePolicy = exports.createPolicy = exports.listPolicies = exports.declineImageShare = exports.acceptImageShare = exports.listPendingImageShares = exports.listModelRevisions = exports.updateModel = exports.getModel = exports.deleteModel = exports.createModel = exports.listModels = exports.listMcpHubDefinitions = exports.listLocations = exports.listJobRevisions = exports.getJobExecution = exports.deleteJobExecution = exports.createJobExecution = exports.listJobExecutions = exports.updateJob = exports.getJob = exports.deleteJob = void 0;
6
- exports.checkWorkspaceAvailability = exports.leaveWorkspace = exports.acceptWorkspaceInvitation = exports.declineWorkspaceInvitation = exports.updateWorkspace = exports.getWorkspace = exports.deleteWorkspace = exports.createWorkspace = exports.listWorkspaces = exports.getEgressIp = exports.deleteEgressIp = exports.createEgressIp = exports.listEgressIps = exports.getEgressGateway = exports.deleteEgressGateway = exports.createEgressGateway = exports.listEgressGateways = exports.getVpc = exports.deleteVpc = exports.createVpc = exports.listVpcs = exports.updateVolume = exports.getVolume = exports.deleteVolume = exports.createVolume = exports.listVolumes = exports.deleteVolumeTemplateVersion = exports.updateVolumeTemplate = exports.getVolumeTemplate = exports.deleteVolumeTemplate = exports.createVolumeTemplate = exports.listVolumeTemplates = exports.updateWorkspaceUserRole = exports.removeWorkspaceUser = void 0;
4
+ exports.listJobs = exports.getIntegrationConnectionModel = exports.listIntegrationConnectionModels = exports.getIntegrationConnectionModelEndpointConfigurations = exports.updateIntegrationConnection = exports.getIntegrationConnection = exports.deleteIntegrationConnection = exports.createIntegrationConnection = exports.listIntegrationConnections = exports.getIntegration = exports.deleteImageTag = exports.unshareImage = exports.shareImage = exports.listImageShares = exports.getImage = exports.deleteImage = exports.createImage = exports.listImages = exports.cleanupImages = exports.listFunctionRevisions = exports.updateFunction = exports.getFunction = exports.deleteFunction = exports.createFunction = exports.listFunctions = exports.testFeatureFlag = exports.getWorkspaceFeatures = exports.listAllEgressIps = exports.getEgressGatewayUsage = exports.listAllEgressGateways = exports.getDriveJwks = exports.createDriveAccessToken = exports.updateDrive = exports.getDrive = exports.deleteDrive = exports.createDrive = exports.listDrives = exports.verifyCustomDomain = exports.updateCustomDomain = exports.getCustomDomain = exports.deleteCustomDomain = exports.createCustomDomain = exports.listCustomDomains = exports.getConfiguration = exports.listAgentRevisions = exports.updateAgent = exports.getAgent = exports.deleteAgent = exports.createAgent = exports.listAgents = void 0;
5
+ exports.listTemplates = exports.deleteApiKeyForServiceAccount = exports.createApiKeyForServiceAccount = exports.listApiKeysForServiceAccount = exports.updateWorkspaceServiceAccount = exports.deleteWorkspaceServiceAccount = exports.createWorkspaceServiceAccount = exports.getWorkspaceServiceAccounts = exports.deleteSandboxPreviewToken = exports.createSandboxPreviewToken = exports.listSandboxPreviewTokens = exports.updateSandboxPreview = exports.getSandboxPreview = exports.deleteSandboxPreview = exports.createSandboxPreview = exports.listSandboxPreviews = exports.updateSandbox = exports.getSandbox = exports.deleteSandbox = exports.createSandbox = exports.listSandboxes = exports.listSandboxHubDefinitions = exports.listPublicIps = exports.getPolicyUsages = exports.updatePolicy = exports.getPolicy = exports.deletePolicy = exports.createPolicy = exports.listPolicies = exports.declineImageShare = exports.acceptImageShare = exports.listPendingImageShares = exports.listModelRevisions = exports.updateModel = exports.getModel = exports.deleteModel = exports.createModel = exports.listModels = exports.listMcpHubDefinitions = exports.listLocations = exports.listJobRevisions = exports.listJobExecutionTasks = exports.getJobExecution = exports.deleteJobExecution = exports.createJobExecution = exports.listJobExecutions = exports.updateJob = exports.getJob = exports.deleteJob = exports.createJob = void 0;
6
+ exports.checkWorkspaceAvailability = exports.leaveWorkspace = exports.acceptWorkspaceInvitation = exports.declineWorkspaceInvitation = exports.updateWorkspace = exports.getWorkspace = exports.deleteWorkspace = exports.createWorkspace = exports.listWorkspaces = exports.getEgressIp = exports.deleteEgressIp = exports.createEgressIp = exports.listEgressIps = exports.getEgressGateway = exports.deleteEgressGateway = exports.createEgressGateway = exports.listEgressGateways = exports.getVpc = exports.deleteVpc = exports.createVpc = exports.listVpcs = exports.updateVolume = exports.getVolume = exports.deleteVolume = exports.createVolume = exports.listVolumes = exports.deleteVolumeTemplateVersion = exports.updateVolumeTemplate = exports.getVolumeTemplate = exports.deleteVolumeTemplate = exports.createVolumeTemplate = exports.listVolumeTemplates = exports.updateWorkspaceUserRole = exports.removeWorkspaceUser = exports.inviteWorkspaceUser = exports.listWorkspaceUsers = exports.getTemplate = void 0;
7
7
  const client_gen_1 = require("./client.gen");
8
8
  /**
9
9
  * List all agents
10
- * Returns all AI agents deployed in the workspace. Each agent includes its deployment status, runtime configuration, and global inference endpoint URL.
10
+ * Returns AI agents deployed in the workspace. Each agent includes its deployment status, runtime configuration, and global inference endpoint URL. Starting with API version 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older versions keep returning a bare array with all agents.
11
11
  */
12
12
  const listAgents = (options) => {
13
13
  return (options?.client ?? client_gen_1.client).get({
@@ -239,7 +239,7 @@ const verifyCustomDomain = (options) => {
239
239
  exports.verifyCustomDomain = verifyCustomDomain;
240
240
  /**
241
241
  * List drives
242
- * Returns all drives in the workspace. Drives provide persistent storage that can be attached to agents, functions, and sandboxes.
242
+ * Returns all drives in the workspace. Drives provide persistent storage that can be attached to agents, functions, and sandboxes. Starting with API version 2026-04-28, the response wraps items in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older versions keep returning a bare array with all drives.
243
243
  */
244
244
  const listDrives = (options) => {
245
245
  return (options?.client ?? client_gen_1.client).get({
@@ -374,6 +374,23 @@ const listAllEgressGateways = (options) => {
374
374
  });
375
375
  };
376
376
  exports.listAllEgressGateways = listAllEgressGateways;
377
+ /**
378
+ * Egress gateway sandbox attachments
379
+ * Returns the inverse map (gateway → sandbox names) for the workspace. Used by the egress-IPs UI to render attachment counts without fetching the sandboxes listing full client-side.
380
+ */
381
+ const getEgressGatewayUsage = (options) => {
382
+ return (options?.client ?? client_gen_1.client).get({
383
+ security: [
384
+ {
385
+ scheme: 'bearer',
386
+ type: 'http'
387
+ }
388
+ ],
389
+ url: '/egressgateways/usage',
390
+ ...options
391
+ });
392
+ };
393
+ exports.getEgressGatewayUsage = getEgressGatewayUsage;
377
394
  /**
378
395
  * List all egress IPs across all VPCs and gateways in the workspace
379
396
  */
@@ -426,7 +443,7 @@ const testFeatureFlag = (options) => {
426
443
  exports.testFeatureFlag = testFeatureFlag;
427
444
  /**
428
445
  * List all MCP servers
429
- * Returns all MCP server functions deployed in the workspace. Each function includes its deployment status, transport protocol (websocket or http-stream), and endpoint URL.
446
+ * Returns MCP server functions deployed in the workspace. Each function includes its deployment status, transport protocol (websocket or http-stream), and endpoint URL. Starting with API version 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older versions keep returning a bare array with all functions.
430
447
  */
431
448
  const listFunctions = (options) => {
432
449
  return (options?.client ?? client_gen_1.client).get({
@@ -858,7 +875,7 @@ const getIntegrationConnectionModel = (options) => {
858
875
  exports.getIntegrationConnectionModel = getIntegrationConnectionModel;
859
876
  /**
860
877
  * List batch jobs
861
- * Returns all batch job definitions in the workspace. Each job can be triggered to run multiple parallel tasks with configurable concurrency and retry settings.
878
+ * Returns batch job definitions in the workspace. Each job can be triggered to run multiple parallel tasks with configurable concurrency and retry settings. Starting with API version 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older versions keep returning a bare array with all jobs.
862
879
  */
863
880
  const listJobs = (options) => {
864
881
  return (options?.client ?? client_gen_1.client).get({
@@ -951,7 +968,7 @@ const updateJob = (options) => {
951
968
  exports.updateJob = updateJob;
952
969
  /**
953
970
  * List job executions
954
- * Returns paginated list of executions for a batch job, sorted by creation time. Each execution contains status, task counts, and timing information.
971
+ * Returns executions for a batch job. Starting with API version 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older versions keep the legacy offset/limit contract and return a bare array.
955
972
  */
956
973
  const listJobExecutions = (options) => {
957
974
  return (options.client ?? client_gen_1.client).get({
@@ -1021,6 +1038,23 @@ const getJobExecution = (options) => {
1021
1038
  });
1022
1039
  };
1023
1040
  exports.getJobExecution = getJobExecution;
1041
+ /**
1042
+ * List execution tasks
1043
+ * Returns one cursor-paginated page of an execution's tasks. Tasks are derived from event history each request; only the in-memory slicing is paginated, the events scan still fetches the whole event log behind the scenes. Available starting with API version 2026-04-28.
1044
+ */
1045
+ const listJobExecutionTasks = (options) => {
1046
+ return (options.client ?? client_gen_1.client).get({
1047
+ security: [
1048
+ {
1049
+ scheme: 'bearer',
1050
+ type: 'http'
1051
+ }
1052
+ ],
1053
+ url: '/jobs/{jobId}/executions/{executionId}/tasks',
1054
+ ...options
1055
+ });
1056
+ };
1057
+ exports.listJobExecutionTasks = listJobExecutionTasks;
1024
1058
  /**
1025
1059
  * List job revisions
1026
1060
  * Returns revisions for a job by name.
@@ -1074,7 +1108,7 @@ const listMcpHubDefinitions = (options) => {
1074
1108
  exports.listMcpHubDefinitions = listMcpHubDefinitions;
1075
1109
  /**
1076
1110
  * List model endpoints
1077
- * Returns all model gateway endpoints configured in the workspace. Each model represents a proxy to an external LLM provider (OpenAI, Anthropic, etc.) with unified access control.
1111
+ * Returns model gateway endpoints configured in the workspace. Each model represents a proxy to an external LLM provider (OpenAI, Anthropic, etc.) with unified access control. Starting with API version 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older versions keep returning a bare array with all models.
1078
1112
  */
1079
1113
  const listModels = (options) => {
1080
1114
  return (options?.client ?? client_gen_1.client).get({
@@ -1235,7 +1269,7 @@ const declineImageShare = (options) => {
1235
1269
  exports.declineImageShare = declineImageShare;
1236
1270
  /**
1237
1271
  * List governance policies
1238
- * Returns all governance policies in the workspace. Policies control deployment locations, hardware flavors, and token limits for agents, functions, and models.
1272
+ * Returns governance policies in the workspace. Policies control deployment locations, hardware flavors, and token limits for agents, functions, and models. Starting with API version 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older versions keep returning a bare array with all policies.
1239
1273
  */
1240
1274
  const listPolicies = (options) => {
1241
1275
  return (options?.client ?? client_gen_1.client).get({
@@ -1326,6 +1360,23 @@ const updatePolicy = (options) => {
1326
1360
  });
1327
1361
  };
1328
1362
  exports.updatePolicy = updatePolicy;
1363
+ /**
1364
+ * List resources using a policy
1365
+ * Returns the names of every resource (agent, function, model, sandbox, job) currently referencing the given policy. Replaces the client-side fan-out the policies UI used to do over the listings.
1366
+ */
1367
+ const getPolicyUsages = (options) => {
1368
+ return (options.client ?? client_gen_1.client).get({
1369
+ security: [
1370
+ {
1371
+ scheme: 'bearer',
1372
+ type: 'http'
1373
+ }
1374
+ ],
1375
+ url: '/policies/{policyName}/usages',
1376
+ ...options
1377
+ });
1378
+ };
1379
+ exports.getPolicyUsages = getPolicyUsages;
1329
1380
  /**
1330
1381
  * List public ips
1331
1382
  * Returns a list of all public ips used in Blaxel..
@@ -1362,7 +1413,7 @@ const listSandboxHubDefinitions = (options) => {
1362
1413
  exports.listSandboxHubDefinitions = listSandboxHubDefinitions;
1363
1414
  /**
1364
1415
  * List sandboxes
1365
- * Returns all sandboxes in the workspace. Each sandbox includes its configuration, status, and endpoint URL.
1416
+ * Returns sandboxes in the workspace. Each sandbox includes its configuration, status, and endpoint URL. Terminated sandboxes are hidden by default; pass `showTerminated=true` to include them. Starting with API version 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older versions keep returning a bare array of all sandboxes.
1366
1417
  */
1367
1418
  const listSandboxes = (options) => {
1368
1419
  return (options?.client ?? client_gen_1.client).get({
@@ -1954,7 +2005,7 @@ const deleteVolumeTemplateVersion = (options) => {
1954
2005
  exports.deleteVolumeTemplateVersion = deleteVolumeTemplateVersion;
1955
2006
  /**
1956
2007
  * List persistent volumes
1957
- * Returns all persistent storage volumes in the workspace. Volumes can be attached to sandboxes for durable file storage that persists across sessions and sandbox deletions.
2008
+ * Returns persistent storage volumes in the workspace. Volumes can be attached to sandboxes for durable file storage that persists across sessions and sandbox deletions. Starting with API version 2026-04-28 the response is wrapped in `{data, meta}` and supports cursor pagination via the `cursor` and `limit` query parameters; older versions keep returning a bare array of volumes.
1958
2009
  */
1959
2010
  const listVolumes = (options) => {
1960
2011
  return (options?.client ?? client_gen_1.client).get({
@@ -7,7 +7,7 @@ exports.h2RequestDirectFromPool = h2RequestDirectFromPool;
7
7
  exports.h2RequestDirect = h2RequestDirect;
8
8
  const settings_js_1 = require("./settings.js");
9
9
  const h2ref_js_1 = require("./h2ref.js");
10
- const MIN_H2_SESSION_MAX_LISTENERS = 64;
10
+ const MIN_H2_SESSION_MAX_LISTENERS = 256;
11
11
  const sessionsWithListenerBudget = new WeakSet();
12
12
  /**
13
13
  * Per-domain async semaphore that bounds the number of in-flight HTTP/2
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.unwrapListData = unwrapListData;
4
+ exports.createPaginatedList = createPaginatedList;
5
+ function unwrapListData(response) {
6
+ if (!response) {
7
+ return [];
8
+ }
9
+ if (Array.isArray(response)) {
10
+ return response;
11
+ }
12
+ return response.data ?? [];
13
+ }
14
+ function unwrapListMeta(response) {
15
+ if (!response || Array.isArray(response)) {
16
+ return { hasMore: false };
17
+ }
18
+ return response.meta ?? { hasMore: false };
19
+ }
20
+ async function createPaginatedList({ response, fetchPage, mapItem, query, seenCursors, }) {
21
+ const meta = unwrapListMeta(response);
22
+ const data = await Promise.all(unwrapListData(response).map(mapItem));
23
+ const cursors = new Set(seenCursors);
24
+ if (query?.cursor) {
25
+ cursors.add(query.cursor);
26
+ }
27
+ const list = {
28
+ data,
29
+ meta,
30
+ get hasMore() {
31
+ return Boolean(meta.hasMore);
32
+ },
33
+ get nextCursor() {
34
+ return meta.nextCursor || undefined;
35
+ },
36
+ async nextPage() {
37
+ const cursor = list.nextCursor;
38
+ if (!cursor) {
39
+ return null;
40
+ }
41
+ if (cursors.has(cursor)) {
42
+ throw new Error("Pagination returned a repeated cursor");
43
+ }
44
+ const nextQuery = { ...(query ?? {}), cursor };
45
+ const nextSeenCursors = new Set(cursors);
46
+ nextSeenCursors.add(cursor);
47
+ return createPaginatedList({
48
+ response: await fetchPage(nextQuery),
49
+ fetchPage,
50
+ mapItem,
51
+ query: nextQuery,
52
+ seenCursors: nextSeenCursors,
53
+ });
54
+ },
55
+ async autoPagingEach(onItem) {
56
+ for await (const item of list) {
57
+ const shouldContinue = await onItem(item);
58
+ if (shouldContinue === false) {
59
+ return;
60
+ }
61
+ }
62
+ },
63
+ async autoPagingToArray(options) {
64
+ if (!options || !Number.isFinite(options.limit) || options.limit <= 0) {
65
+ throw new Error("autoPagingToArray requires a positive limit");
66
+ }
67
+ const items = [];
68
+ for await (const item of list) {
69
+ items.push(item);
70
+ if (items.length >= options.limit) {
71
+ return items;
72
+ }
73
+ }
74
+ return items;
75
+ },
76
+ async *[Symbol.asyncIterator]() {
77
+ let page = list;
78
+ while (page) {
79
+ for (const item of page.data) {
80
+ yield item;
81
+ }
82
+ page = await page.nextPage();
83
+ }
84
+ },
85
+ };
86
+ return list;
87
+ }
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const pagination_js_1 = require("./pagination.js");
5
+ (0, vitest_1.describe)("pagination helpers", () => {
6
+ (0, vitest_1.it)("unwraps legacy array and paginated list responses", () => {
7
+ (0, vitest_1.expect)((0, pagination_js_1.unwrapListData)([{ name: "legacy" }])).toEqual([{ name: "legacy" }]);
8
+ (0, vitest_1.expect)((0, pagination_js_1.unwrapListData)({
9
+ data: [{ name: "paginated" }],
10
+ meta: { hasMore: false },
11
+ })).toEqual([{ name: "paginated" }]);
12
+ });
13
+ (0, vitest_1.it)("returns page data and lets callers request the next page", async () => {
14
+ const cursors = [];
15
+ const fetchPage = async (query) => {
16
+ await Promise.resolve();
17
+ cursors.push(query?.cursor);
18
+ if (!query?.cursor) {
19
+ return {
20
+ data: ["first"],
21
+ meta: { hasMore: true, nextCursor: "next-page" },
22
+ };
23
+ }
24
+ return {
25
+ data: ["second"],
26
+ meta: { hasMore: false },
27
+ };
28
+ };
29
+ const page = await (0, pagination_js_1.createPaginatedList)({
30
+ response: await fetchPage(),
31
+ fetchPage,
32
+ mapItem: (item) => item.toUpperCase(),
33
+ });
34
+ (0, vitest_1.expect)(page.data).toEqual(["FIRST"]);
35
+ (0, vitest_1.expect)(page.hasMore).toBe(true);
36
+ (0, vitest_1.expect)(page.nextCursor).toBe("next-page");
37
+ const nextPage = await page.nextPage();
38
+ (0, vitest_1.expect)(nextPage?.data).toEqual(["SECOND"]);
39
+ (0, vitest_1.expect)(cursors).toEqual([undefined, "next-page"]);
40
+ });
41
+ (0, vitest_1.it)("supports auto paging with an explicit limit", async () => {
42
+ const fetchPage = async (query) => {
43
+ await Promise.resolve();
44
+ if (!query?.cursor) {
45
+ return {
46
+ data: ["first"],
47
+ meta: { hasMore: true, nextCursor: "next-page" },
48
+ };
49
+ }
50
+ return {
51
+ data: ["second"],
52
+ meta: { hasMore: false },
53
+ };
54
+ };
55
+ const page = await (0, pagination_js_1.createPaginatedList)({
56
+ response: await fetchPage(),
57
+ fetchPage,
58
+ mapItem: (item) => item,
59
+ });
60
+ await (0, vitest_1.expect)(page.autoPagingToArray({ limit: 2 })).resolves.toEqual(["first", "second"]);
61
+ });
62
+ });
@@ -28,10 +28,10 @@ function missingCredentialsMessage() {
28
28
  return "No Blaxel credentials found. Set the BL_API_KEY and BL_WORKSPACE environment variables, or run `bl login`.";
29
29
  }
30
30
  // Build info - these placeholders are replaced at build time by build:replace-imports
31
- const BUILD_VERSION = "0.2.89";
32
- const BUILD_COMMIT = "c481e2f6670b3cef6832875dbc9f2bc6b0b198f4";
31
+ const BUILD_VERSION = "0.2.90-dev.181";
32
+ const BUILD_COMMIT = "588f48a812b2e4e0ff556b9008896ad944741f53";
33
33
  const BUILD_SENTRY_DSN = "https://fd5e60e1c9820e1eef5ccebb84a07127@o4508714045276160.ingest.us.sentry.io/4510465864564736";
34
- const BLAXEL_API_VERSION = "2026-04-16";
34
+ const BLAXEL_API_VERSION = "2026-04-28";
35
35
  // Cache for config.yaml tracking value
36
36
  let configTrackingValue = null;
37
37
  let configTrackingLoaded = false;
@@ -43,10 +43,10 @@ const env_js_1 = require("./env.js");
43
43
  (0, vitest_1.afterEach)(() => {
44
44
  delete env_js_1.env.BL_API_VERSION;
45
45
  });
46
- (0, vitest_1.it)('defaults to 2026-04-16 when BL_API_VERSION is not set', async () => {
46
+ (0, vitest_1.it)('defaults to 2026-04-28 when BL_API_VERSION is not set', async () => {
47
47
  delete env_js_1.env.BL_API_VERSION;
48
48
  const { settings } = await Promise.resolve().then(() => __importStar(require('./settings.js')));
49
- (0, vitest_1.expect)(settings.apiVersion).toBe('2026-04-16');
49
+ (0, vitest_1.expect)(settings.apiVersion).toBe('2026-04-28');
50
50
  });
51
51
  (0, vitest_1.it)('headers include Blaxel-Version set to the default', async () => {
52
52
  delete env_js_1.env.BL_API_VERSION;
@@ -55,7 +55,7 @@ const env_js_1 = require("./env.js");
55
55
  const previous = settings.credentials;
56
56
  settings.credentials = new apikey_js_1.ApiKey({ apiKey: 'test-key', workspace: 'test-ws' });
57
57
  try {
58
- (0, vitest_1.expect)(settings.headers['Blaxel-Version']).toBe('2026-04-16');
58
+ (0, vitest_1.expect)(settings.headers['Blaxel-Version']).toBe('2026-04-28');
59
59
  }
60
60
  finally {
61
61
  settings.credentials = previous;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DriveInstance = void 0;
4
4
  const uuid_1 = require("uuid");
5
5
  const index_js_1 = require("../client/index.js");
6
+ const pagination_js_1 = require("../common/pagination.js");
6
7
  const settings_js_1 = require("../common/settings.js");
7
8
  class DriveInstance {
8
9
  drive;
@@ -86,9 +87,44 @@ class DriveInstance {
86
87
  });
87
88
  return new DriveInstance(data);
88
89
  }
89
- static async list() {
90
- const { data } = await (0, index_js_1.listDrives)({ throwOnError: true });
91
- return data.map((drive) => new DriveInstance(drive));
90
+ /**
91
+ * List one page of drives.
92
+ *
93
+ * The returned page exposes `data` for the current page, `meta` for cursor
94
+ * metadata, and helpers to fetch more pages only when you need them.
95
+ *
96
+ * @example
97
+ * ```ts
98
+ * const page = await DriveInstance.list({ limit: 50 });
99
+ *
100
+ * for (const drive of page.data) {
101
+ * console.log(drive.name);
102
+ * }
103
+ *
104
+ * const nextPage = await page.nextPage();
105
+ * ```
106
+ *
107
+ * @example
108
+ * ```ts
109
+ * const allDrives = await (await DriveInstance.list()).autoPagingToArray({
110
+ * limit: 1000,
111
+ * });
112
+ * ```
113
+ */
114
+ static async list(query) {
115
+ const fetchPage = async (pageQuery) => {
116
+ const { data } = await (0, index_js_1.listDrives)({
117
+ query: pageQuery,
118
+ throwOnError: true,
119
+ });
120
+ return data;
121
+ };
122
+ return (0, pagination_js_1.createPaginatedList)({
123
+ response: await fetchPage(query),
124
+ fetchPage,
125
+ mapItem: (drive) => new DriveInstance(drive),
126
+ query,
127
+ });
92
128
  }
93
129
  static async delete(driveName) {
94
130
  const { data } = await (0, index_js_1.deleteDrive)({
package/dist/cjs/index.js CHANGED
@@ -23,6 +23,7 @@ __exportStar(require("./common/node.js"), exports);
23
23
  __exportStar(require("./common/errors.js"), exports);
24
24
  __exportStar(require("./common/internal.js"), exports);
25
25
  __exportStar(require("./common/logger.js"), exports);
26
+ __exportStar(require("./common/pagination.js"), exports);
26
27
  __exportStar(require("./common/settings.js"), exports);
27
28
  __exportStar(require("./common/webhook.js"), exports);
28
29
  __exportStar(require("./drive/index.js"), exports);
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.blJob = void 0;
4
4
  const index_js_1 = require("../client/index.js");
5
5
  const logger_js_1 = require("../common/logger.js");
6
+ const pagination_js_1 = require("../common/pagination.js");
6
7
  const settings_js_1 = require("../common/settings.js");
7
8
  const telemetry_js_1 = require("../telemetry/telemetry.js");
8
9
  class BlJob {
@@ -78,18 +79,50 @@ class BlJob {
78
79
  return data;
79
80
  }
80
81
  /**
81
- * List all executions for this job
82
+ * List one page of executions for this job.
83
+ *
84
+ * The returned page exposes `data` for the current page, `meta` for cursor
85
+ * metadata, and helpers to fetch more pages only when you need them.
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * const job = blJob("daily-import");
90
+ * const page = await job.listExecutions({ limit: 50 });
91
+ *
92
+ * for (const execution of page.data) {
93
+ * console.log(execution.status);
94
+ * }
95
+ *
96
+ * const nextPage = await page.nextPage();
97
+ * ```
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * const job = blJob("daily-import");
102
+ * const executions = await (await job.listExecutions()).autoPagingToArray({
103
+ * limit: 1000,
104
+ * });
105
+ * ```
82
106
  */
83
- async listExecutions() {
107
+ async listExecutions(query) {
84
108
  logger_js_1.logger.debug(`Listing executions for job: ${this.jobName}`);
85
- const { data } = await (0, index_js_1.listJobExecutions)({
86
- path: {
87
- jobId: this.jobName,
88
- },
89
- headers: settings_js_1.settings.headers,
90
- throwOnError: true,
109
+ const fetchPage = async (pageQuery) => {
110
+ const { data } = await (0, index_js_1.listJobExecutions)({
111
+ path: {
112
+ jobId: this.jobName,
113
+ },
114
+ query: pageQuery,
115
+ headers: settings_js_1.settings.headers,
116
+ throwOnError: true,
117
+ });
118
+ return data;
119
+ };
120
+ return (0, pagination_js_1.createPaginatedList)({
121
+ response: await fetchPage(query),
122
+ fetchPage,
123
+ mapItem: (execution) => execution,
124
+ query,
91
125
  });
92
- return data ?? [];
93
126
  }
94
127
  /**
95
128
  * Get the status of a specific execution
@@ -92,7 +92,7 @@ const getDrivesMount = (options) => {
92
92
  exports.getDrivesMount = getDrivesMount;
93
93
  /**
94
94
  * Attach a drive to a local path
95
- * Mounts an agent drive using the blfs binary to a local path, optionally mounting a subpath within the drive
95
+ * Mounts an agent drive using the blfs binary to a local path, optionally mounting a subpath within the drive. Supports optional UID/GID mapping to remap file ownership between the local sandbox and the filer (always mapped to filer UID/GID 0). Mapping values can be set per-request via uidMap/gidMap fields, or globally via BLFS_UID_MAP/BLFS_GID_MAP environment variables (request values take precedence).
96
96
  */
97
97
  const postDrivesMount = (options) => {
98
98
  return (options.client ?? client_gen_1.client).post({
@@ -105,24 +105,29 @@ class SandboxPreviews {
105
105
  });
106
106
  return data.map((preview) => new SandboxPreview(preview));
107
107
  }
108
- async create(preview) {
108
+ async create(preview, force) {
109
+ const query = {};
110
+ if (force) {
111
+ query['force'] = 'true';
112
+ }
109
113
  const { data } = await (0, index_js_1.createSandboxPreview)({
110
114
  path: {
111
115
  sandboxName: this.sandboxName,
112
116
  },
117
+ query,
113
118
  body: preview,
114
119
  throwOnError: true,
115
120
  });
116
121
  return new SandboxPreview(data);
117
122
  }
118
- async createIfNotExists(preview) {
123
+ async createIfNotExists(preview, force) {
119
124
  try {
120
125
  const previewInstance = await this.get(preview.metadata.name);
121
126
  return previewInstance;
122
127
  }
123
128
  catch (e) {
124
129
  if (typeof e === "object" && e !== null && "code" in e && e.code === 404) {
125
- return this.create(preview);
130
+ return this.create(preview, force);
126
131
  }
127
132
  throw e;
128
133
  }
@@ -37,6 +37,7 @@ exports.SandboxInstance = void 0;
37
37
  const uuid_1 = require("uuid");
38
38
  const index_js_1 = require("../client/index.js");
39
39
  const logger_js_1 = require("../common/logger.js");
40
+ const pagination_js_1 = require("../common/pagination.js");
40
41
  const settings_js_1 = require("../common/settings.js");
41
42
  const index_js_2 = require("./codegen/index.js");
42
43
  const index_js_3 = require("./drive/index.js");
@@ -272,10 +273,46 @@ class SandboxInstance {
272
273
  const instance = new SandboxInstance(data);
273
274
  return SandboxInstance.attachH2Session(instance);
274
275
  }
275
- static async list() {
276
- const { data } = await (0, index_js_1.listSandboxes)({ throwOnError: true });
277
- const instances = data.map((sandbox) => new SandboxInstance(sandbox));
278
- return Promise.all(instances.map((instance) => SandboxInstance.attachH2Session(instance)));
276
+ /**
277
+ * List one page of sandboxes.
278
+ *
279
+ * The returned page exposes `data` for the current page, `meta` for cursor
280
+ * metadata, and helpers to fetch more pages only when you need them.
281
+ *
282
+ * @example
283
+ * ```ts
284
+ * const page = await SandboxInstance.list({ limit: 50 });
285
+ *
286
+ * for (const sandbox of page.data) {
287
+ * console.log(sandbox.metadata.name);
288
+ * }
289
+ *
290
+ * const nextPage = await page.nextPage();
291
+ * ```
292
+ *
293
+ * @example
294
+ * ```ts
295
+ * const page = await SandboxInstance.list({ limit: 100 });
296
+ *
297
+ * for await (const sandbox of page) {
298
+ * console.log(sandbox.metadata.name);
299
+ * }
300
+ * ```
301
+ */
302
+ static async list(query) {
303
+ const fetchPage = async (pageQuery) => {
304
+ const { data } = await (0, index_js_1.listSandboxes)({
305
+ query: pageQuery,
306
+ throwOnError: true,
307
+ });
308
+ return data;
309
+ };
310
+ return (0, pagination_js_1.createPaginatedList)({
311
+ response: await fetchPage(query),
312
+ fetchPage,
313
+ mapItem: (sandbox) => SandboxInstance.attachH2Session(new SandboxInstance(sandbox)),
314
+ query,
315
+ });
279
316
  }
280
317
  static async delete(sandboxName) {
281
318
  const { data } = await (0, index_js_1.deleteSandbox)({