@blaxel/core 0.3.22 → 0.3.23
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/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/client/sdk.gen.js +26 -9
- package/dist/cjs/common/settings.js +3 -3
- package/dist/cjs/common/settings.test.js +3 -3
- package/dist/cjs/image/image.js +32 -0
- package/dist/cjs/image/pagination.test.js +105 -0
- package/dist/cjs/types/client/sdk.gen.d.ts +22 -10
- package/dist/cjs/types/client/types.gen.d.ts +138 -17
- package/dist/cjs/types/common/pagination.d.ts +2 -0
- package/dist/cjs/types/drive/index.d.ts +2 -0
- package/dist/cjs/types/image/image.d.ts +19 -0
- package/dist/cjs/types/image/index.d.ts +1 -0
- package/dist/cjs/types/image/pagination.test.d.ts +1 -0
- package/dist/cjs-browser/.tsbuildinfo +1 -1
- package/dist/cjs-browser/client/sdk.gen.js +26 -9
- package/dist/cjs-browser/common/settings.js +3 -3
- package/dist/cjs-browser/common/settings.test.js +3 -3
- package/dist/cjs-browser/image/pagination.test.js +105 -0
- package/dist/cjs-browser/types/client/sdk.gen.d.ts +22 -10
- package/dist/cjs-browser/types/client/types.gen.d.ts +138 -17
- package/dist/cjs-browser/types/common/pagination.d.ts +2 -0
- package/dist/cjs-browser/types/drive/index.d.ts +2 -0
- package/dist/cjs-browser/types/image/image.d.ts +19 -0
- package/dist/cjs-browser/types/image/index.d.ts +1 -0
- package/dist/cjs-browser/types/image/pagination.test.d.ts +1 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/client/sdk.gen.js +22 -6
- package/dist/esm/common/settings.js +3 -3
- package/dist/esm/common/settings.test.js +3 -3
- package/dist/esm/image/image.js +32 -0
- package/dist/esm/image/pagination.test.js +70 -0
- package/dist/esm-browser/.tsbuildinfo +1 -1
- package/dist/esm-browser/client/sdk.gen.js +22 -6
- package/dist/esm-browser/common/settings.js +3 -3
- package/dist/esm-browser/common/settings.test.js +3 -3
- package/dist/esm-browser/image/pagination.test.js +70 -0
- package/package.json +1 -1
|
@@ -442,7 +442,7 @@ export const createDrive = (options) => {
|
|
|
442
442
|
};
|
|
443
443
|
/**
|
|
444
444
|
* Delete a drive
|
|
445
|
-
*
|
|
445
|
+
* Starts the deletion of a drive. The drive is marked DELETING and its storage is wiped asynchronously; the drive disappears from listings once the cleanup completes.
|
|
446
446
|
*/
|
|
447
447
|
export const deleteDrive = (options) => {
|
|
448
448
|
return (options.client ?? _heyApiClient).delete({
|
|
@@ -734,7 +734,7 @@ export const cleanupImages = (options) => {
|
|
|
734
734
|
};
|
|
735
735
|
/**
|
|
736
736
|
* List container images
|
|
737
|
-
* Returns
|
|
737
|
+
* Returns paginated image summaries starting with API version 2026-09-22. Older versions return a bare array including all tags.
|
|
738
738
|
*/
|
|
739
739
|
export const listImages = (options) => {
|
|
740
740
|
return (options?.client ?? _heyApiClient).get({
|
|
@@ -786,7 +786,7 @@ export const deleteImage = (options) => {
|
|
|
786
786
|
};
|
|
787
787
|
/**
|
|
788
788
|
* Get container image
|
|
789
|
-
* Returns
|
|
789
|
+
* Returns a bounded image summary starting with API version 2026-09-22. Older versions return the image with all tags.
|
|
790
790
|
*/
|
|
791
791
|
export const getImage = (options) => {
|
|
792
792
|
return (options.client ?? _heyApiClient).get({
|
|
@@ -852,6 +852,22 @@ export const unshareImage = (options) => {
|
|
|
852
852
|
...options
|
|
853
853
|
});
|
|
854
854
|
};
|
|
855
|
+
/**
|
|
856
|
+
* List image tags
|
|
857
|
+
* Returns a bounded page of image tags. Search by prefix or exact name. Tags are ordered by name only. Send Blaxel-Version 2026-09-22 with image catalog requests.
|
|
858
|
+
*/
|
|
859
|
+
export const listImageTags = (options) => {
|
|
860
|
+
return (options.client ?? _heyApiClient).get({
|
|
861
|
+
security: [
|
|
862
|
+
{
|
|
863
|
+
scheme: 'bearer',
|
|
864
|
+
type: 'http'
|
|
865
|
+
}
|
|
866
|
+
],
|
|
867
|
+
url: '/images/{resourceType}/{imageName}/tags',
|
|
868
|
+
...options
|
|
869
|
+
});
|
|
870
|
+
};
|
|
855
871
|
/**
|
|
856
872
|
* Delete container image tag
|
|
857
873
|
* Deletes a specific tag from a container image. The underlying image layers are kept if other tags reference them. Will fail if the tag is currently in use.
|
|
@@ -1634,7 +1650,7 @@ export const archiveSandbox = (options) => {
|
|
|
1634
1650
|
};
|
|
1635
1651
|
/**
|
|
1636
1652
|
* Fork sandbox
|
|
1637
|
-
* 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.
|
|
1653
|
+
* 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. With no snapshotId, a fork to a sandbox copies the source sandbox's live state directly and no snapshot is persisted, while a fork to an application takes a snapshot its revision then references. This is a WIP endpoint — the full implementation depends on the execution plane.
|
|
1638
1654
|
*/
|
|
1639
1655
|
export const forkSandbox = (options) => {
|
|
1640
1656
|
return (options.client ?? _heyApiClient).post({
|
|
@@ -1934,7 +1950,7 @@ export const createSandboxSnapshot = (options) => {
|
|
|
1934
1950
|
};
|
|
1935
1951
|
/**
|
|
1936
1952
|
* Delete sandbox snapshot
|
|
1937
|
-
* Deletes a snapshot of a sandbox by its ID.
|
|
1953
|
+
* Deletes a snapshot of a sandbox, addressed by its name among that sandbox's snapshots (or by its ID).
|
|
1938
1954
|
*/
|
|
1939
1955
|
export const deleteSandboxSnapshot = (options) => {
|
|
1940
1956
|
return (options.client ?? _heyApiClient).delete({
|
|
@@ -2222,7 +2238,7 @@ export const deleteSnapshot = (options) => {
|
|
|
2222
2238
|
};
|
|
2223
2239
|
/**
|
|
2224
2240
|
* Get snapshot
|
|
2225
|
-
* Returns a snapshot of the workspace by
|
|
2241
|
+
* Returns a snapshot of the workspace by ID.
|
|
2226
2242
|
*/
|
|
2227
2243
|
export const getSnapshot = (options) => {
|
|
2228
2244
|
return (options.client ?? _heyApiClient).get({
|
|
@@ -24,10 +24,10 @@ function missingCredentialsMessage() {
|
|
|
24
24
|
return "No Blaxel credentials found. Set the BL_API_KEY and BL_WORKSPACE environment variables, or run `bl login`.";
|
|
25
25
|
}
|
|
26
26
|
// Build info - these placeholders are replaced at build time by build:replace-imports
|
|
27
|
-
const BUILD_VERSION = "0.3.
|
|
28
|
-
const BUILD_COMMIT = "
|
|
27
|
+
const BUILD_VERSION = "0.3.23";
|
|
28
|
+
const BUILD_COMMIT = "3f7319f88bf305c481c80932c29c7513c85b543d";
|
|
29
29
|
const BUILD_SENTRY_DSN = "https://fd5e60e1c9820e1eef5ccebb84a07127@o4508714045276160.ingest.us.sentry.io/4510465864564736";
|
|
30
|
-
const BLAXEL_API_VERSION = "2026-
|
|
30
|
+
const BLAXEL_API_VERSION = "2026-09-22";
|
|
31
31
|
// Bun < 1.3.11 never sends connection-level WINDOW_UPDATE: the pooled h2
|
|
32
32
|
// session freezes after exactly 65535 cumulative body bytes and every request
|
|
33
33
|
// on it hangs until the edge resets the streams (~330s).
|
|
@@ -9,10 +9,10 @@ describe('Settings.apiVersion', () => {
|
|
|
9
9
|
afterEach(() => {
|
|
10
10
|
delete env.BL_API_VERSION;
|
|
11
11
|
});
|
|
12
|
-
it('defaults to 2026-
|
|
12
|
+
it('defaults to 2026-09-22 when BL_API_VERSION is not set', async () => {
|
|
13
13
|
delete env.BL_API_VERSION;
|
|
14
14
|
const { settings } = await import('./settings.js');
|
|
15
|
-
expect(settings.apiVersion).toBe('2026-
|
|
15
|
+
expect(settings.apiVersion).toBe('2026-09-22');
|
|
16
16
|
});
|
|
17
17
|
it('headers include Blaxel-Version set to the default', async () => {
|
|
18
18
|
delete env.BL_API_VERSION;
|
|
@@ -21,7 +21,7 @@ describe('Settings.apiVersion', () => {
|
|
|
21
21
|
const previous = settings.credentials;
|
|
22
22
|
settings.credentials = new ApiKey({ apiKey: 'test-key', workspace: 'test-ws' });
|
|
23
23
|
try {
|
|
24
|
-
expect(settings.headers['Blaxel-Version']).toBe('2026-
|
|
24
|
+
expect(settings.headers['Blaxel-Version']).toBe('2026-09-22');
|
|
25
25
|
}
|
|
26
26
|
finally {
|
|
27
27
|
settings.credentials = previous;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
3
|
+
import { initialize } from "../common/autoload.js";
|
|
4
|
+
import { settings } from "../common/settings.js";
|
|
5
|
+
import { ImageInstance } from "./image.js";
|
|
6
|
+
// Exercise the generated client, authentication headers and cursor helpers over HTTP.
|
|
7
|
+
describe("image pagination HTTP contract", () => {
|
|
8
|
+
let server;
|
|
9
|
+
const requests = [];
|
|
10
|
+
const previousConfig = { ...settings.config };
|
|
11
|
+
const previousCredentials = settings.credentials;
|
|
12
|
+
beforeEach(async () => {
|
|
13
|
+
requests.length = 0;
|
|
14
|
+
server = createServer((request, response) => {
|
|
15
|
+
const url = new URL(request.url, "http://localhost");
|
|
16
|
+
requests.push({ url, version: request.headers["blaxel-version"] });
|
|
17
|
+
const cursor = url.searchParams.get("cursor");
|
|
18
|
+
const tag = url.pathname.endsWith("/tags");
|
|
19
|
+
const item = tag ? { name: "v2", size: 123 } : { metadata: { name: "example" }, spec: { size: 123, tagCount: 10000 } };
|
|
20
|
+
response.writeHead(200, { "Content-Type": "application/json" });
|
|
21
|
+
response.end(JSON.stringify({
|
|
22
|
+
data: cursor === "empty" ? [] : [item],
|
|
23
|
+
meta: cursor === "end" ? {} : { total: 10000, totalIsPartial: true, hasMore: true, nextCursor: cursor ? "end" : "empty" },
|
|
24
|
+
}));
|
|
25
|
+
});
|
|
26
|
+
await new Promise((resolve) => server.listen(0, "127.0.0.1", resolve));
|
|
27
|
+
const address = server.address();
|
|
28
|
+
if (!address || typeof address === "string")
|
|
29
|
+
throw new Error("Expected TCP server");
|
|
30
|
+
initialize({ apiKey: "test-key", workspace: "test", disableH2: true });
|
|
31
|
+
const { ensureAutoloaded } = await import("../common/lazyInit.js");
|
|
32
|
+
ensureAutoloaded();
|
|
33
|
+
const { client } = await import("../client/client.gen.js");
|
|
34
|
+
client.setConfig({ baseUrl: `http://127.0.0.1:${address.port}`, fetch });
|
|
35
|
+
});
|
|
36
|
+
afterEach(async () => {
|
|
37
|
+
settings.config = previousConfig;
|
|
38
|
+
settings.credentials = previousCredentials;
|
|
39
|
+
server.closeAllConnections();
|
|
40
|
+
await new Promise((resolve, reject) => server.close((error) => error ? reject(error) : resolve()));
|
|
41
|
+
});
|
|
42
|
+
it("lists summaries lazily and follows empty pages without fetching tags", async () => {
|
|
43
|
+
const page = await ImageInstance.list({ limit: 1, q: "ex", sort: "name:asc" });
|
|
44
|
+
expect(requests).toHaveLength(1);
|
|
45
|
+
expect(page.data[0].spec.tagCount).toBe(10000);
|
|
46
|
+
expect(page.meta.totalIsPartial).toBe(true);
|
|
47
|
+
const items = await page.autoPagingToArray({ limit: 10 });
|
|
48
|
+
expect(items).toHaveLength(2);
|
|
49
|
+
expect(requests.map(({ url }) => url.pathname)).toEqual(["/images", "/images", "/images"]);
|
|
50
|
+
expect(requests.map(({ url }) => url.searchParams.get("cursor"))).toEqual([null, "empty", "end"]);
|
|
51
|
+
for (const request of requests) {
|
|
52
|
+
expect(request.version).toBe("2026-09-22");
|
|
53
|
+
expect(request.url.searchParams.get("q")).toBe("ex");
|
|
54
|
+
expect(request.url.searchParams.get("limit")).toBe("1");
|
|
55
|
+
expect(request.url.searchParams.get("sort")).toBe("name:asc");
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
it("preserves shared-owner and tag filters on every page", async () => {
|
|
59
|
+
const page = await ImageInstance.listTags("sandbox", "example", {
|
|
60
|
+
limit: 1, name: "v2", sourceWorkspace: "owner", sort: "name:desc",
|
|
61
|
+
});
|
|
62
|
+
expect(await page.autoPagingToArray({ limit: 10 })).toHaveLength(2);
|
|
63
|
+
for (const { url } of requests) {
|
|
64
|
+
expect(url.pathname).toBe("/images/sandbox/example/tags");
|
|
65
|
+
expect(url.searchParams.get("sourceWorkspace")).toBe("owner");
|
|
66
|
+
expect(url.searchParams.get("name")).toBe("v2");
|
|
67
|
+
expect(url.searchParams.get("sort")).toBe("name:desc");
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
});
|