Skip to content

File tree

4 files changed

+145
-9
lines changed

4 files changed

+145
-9
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { it, describe, expect } from "vitest";
2+
3+
import { TEST_HUB_URL, TEST_ACCESS_TOKEN, TEST_USER } from "../test/consts";
4+
import { addCollectionItem } from "./add-collection-item";
5+
import { listCollections } from "./list-collections";
6+
import { collectionInfo } from "./collection-info";
7+
import { deleteCollectionItem } from "./delete-collection-item";
8+
9+
describe("addCollectionItem", () => {
10+
it("should add a item to a collection", async () => {
11+
let slug: string = "";
12+
let itemId: string = "";
13+
14+
try {
15+
for await (const entry of listCollections({
16+
search: { owner: [TEST_USER] },
17+
limit: 1,
18+
hubUrl: TEST_HUB_URL,
19+
})) {
20+
slug = entry.slug;
21+
break;
22+
}
23+
24+
await addCollectionItem({
25+
slug,
26+
item: {
27+
type: "model",
28+
id: "quanghuynt14/TestAddCollectionItem",
29+
},
30+
note: "This is a test item",
31+
accessToken: TEST_ACCESS_TOKEN,
32+
hubUrl: TEST_HUB_URL,
33+
});
34+
35+
const collection = await collectionInfo({
36+
slug,
37+
accessToken: TEST_ACCESS_TOKEN,
38+
hubUrl: TEST_HUB_URL,
39+
});
40+
41+
const item = collection.items.find((item) => item.id === "quanghuynt14/TestAddCollectionItem");
42+
43+
expect(item).toBeDefined();
44+
45+
itemId = item?._id || "";
46+
} finally {
47+
await deleteCollectionItem({
48+
slug,
49+
itemId,
50+
accessToken: TEST_ACCESS_TOKEN,
51+
hubUrl: TEST_HUB_URL,
52+
});
53+
}
54+
});
55+
});
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { HUB_URL } from "../consts";
2+
import { createApiError } from "../error";
3+
import type { CredentialsParams } from "../types/public";
4+
import { checkCredentials } from "../utils/checkCredentials";
5+
6+
export async function addCollectionItem(
7+
params: {
8+
/**
9+
* The slug of the collection to add the item to.
10+
*/
11+
slug: string;
12+
/**
13+
* The item to add to the collection.
14+
*/
15+
item: {
16+
type: "paper" | "collection" | "space" | "model" | "dataset";
17+
id: string;
18+
};
19+
/**
20+
* A note to attach to the item in the collection. The maximum size for a note is 500 characters.
21+
*/
22+
note?: string;
23+
hubUrl?: string;
24+
/**
25+
* Custom fetch function to use instead of the default one, for example to use a proxy or edit headers.
26+
*/
27+
fetch?: typeof fetch;
28+
} & Partial<CredentialsParams>
29+
): Promise<void> {
30+
const accessToken = checkCredentials(params);
31+
32+
const res = await (params.fetch ?? fetch)(`${params.hubUrl ?? HUB_URL}/api/collections/${params.slug}/items`, {
33+
method: "POST",
34+
body: JSON.stringify({
35+
item: params.item,
36+
note: params.note,
37+
}),
38+
headers: {
39+
Authorization: `Bearer ${accessToken}`,
40+
"Content-Type": "application/json",
41+
},
42+
});
43+
44+
if (!res.ok) {
45+
throw await createApiError(res);
46+
}
47+
}

packages/hub/src/lib/create-collection.spec.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,26 @@
11
import { it, describe, expect } from "vitest";
22

3-
import { TEST_HUB_URL, TEST_ACCESS_TOKEN } from "../test/consts";
3+
import { TEST_HUB_URL, TEST_ACCESS_TOKEN, TEST_USER } from "../test/consts";
44
import { createCollection } from "./create-collection";
5-
import { whoAmI } from "./who-am-i";
65
import { deleteCollection } from "./delete-collection";
76

87
describe("createCollection", () => {
98
it("should create a collection", async () => {
109
let slug: string = "";
1110

1211
try {
13-
const user = await whoAmI({
14-
hubUrl: TEST_HUB_URL,
15-
accessToken: TEST_ACCESS_TOKEN,
16-
});
17-
1812
const result = await createCollection({
1913
collection: {
2014
title: "Test Collection",
21-
namespace: user.name,
15+
namespace: TEST_USER,
2216
description: "This is a test collection",
2317
private: false,
2418
},
2519
accessToken: TEST_ACCESS_TOKEN,
2620
hubUrl: TEST_HUB_URL,
2721
});
2822

29-
expect(result.slug.startsWith(`${user.name}/test-collection`)).toBe(true);
23+
expect(result.slug.startsWith(`${TEST_USER}/test-collection`)).toBe(true);
3024

3125
slug = result.slug;
3226
} finally {
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { HUB_URL } from "../consts";
2+
import { createApiError } from "../error";
3+
import type { CredentialsParams } from "../types/public";
4+
import { checkCredentials } from "../utils/checkCredentials";
5+
6+
export async function deleteCollectionItem(
7+
params: {
8+
/**
9+
* The slug of the collection to delete the item from.
10+
*/
11+
slug: string;
12+
/**
13+
* The item object id which is different from the repo_id/paper_id provided when adding the item to the collection.
14+
* This should be the _id property of the item.
15+
*/
16+
itemId: string;
17+
hubUrl?: string;
18+
/**
19+
* Custom fetch function to use instead of the default one, for example to use a proxy or edit headers.
20+
*/
21+
fetch?: typeof fetch;
22+
} & Partial<CredentialsParams>
23+
): Promise<void> {
24+
const accessToken = checkCredentials(params);
25+
26+
const res = await (params.fetch ?? fetch)(
27+
`${params.hubUrl ?? HUB_URL}/api/collections/${params.slug}/items/${params.itemId}`,
28+
{
29+
method: "DELETE",
30+
headers: {
31+
Authorization: `Bearer ${accessToken}`,
32+
"Content-Type": "application/json",
33+
},
34+
}
35+
);
36+
37+
if (!res.ok) {
38+
throw await createApiError(res);
39+
}
40+
}

0 commit comments

Comments
 (0)