feat(karakeep): bookmark fetch client
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
11
lib/karakeep/client.js
Normal file
11
lib/karakeep/client.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
export async function getBookmark(id) {
|
||||||
|
const base = process.env.KARAKEEP_API_URL || 'https://karakeep.hynesy.com';
|
||||||
|
const tok = process.env.KARAKEEP_API_TOKEN || '';
|
||||||
|
const res = await fetch(`${base}/api/v1/bookmarks/${encodeURIComponent(id)}`, {
|
||||||
|
headers: { Authorization: 'Bearer ' + tok },
|
||||||
|
signal: AbortSignal.timeout(10_000)
|
||||||
|
});
|
||||||
|
if (res.status === 404) return null;
|
||||||
|
if (!res.ok) throw new Error(`karakeep ${res.status}`);
|
||||||
|
return res.json();
|
||||||
|
}
|
||||||
35
tests/karakeep/client.test.js
Normal file
35
tests/karakeep/client.test.js
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||||||
|
import { getBookmark } from '../../lib/karakeep/client.js';
|
||||||
|
|
||||||
|
let lastInit;
|
||||||
|
beforeEach(() => {
|
||||||
|
lastInit = null;
|
||||||
|
global.fetch = vi.fn(async (url, init) => {
|
||||||
|
lastInit = init;
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({ id: 'b-1', url: 'https://example.com', title: 'X', tags: [{ name: 'archive' }] }),
|
||||||
|
{ status: 200, headers: { 'content-type': 'application/json' }}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
afterEach(() => { vi.restoreAllMocks(); });
|
||||||
|
|
||||||
|
describe('karakeep client', () => {
|
||||||
|
it('fetches a bookmark with bearer token', async () => {
|
||||||
|
process.env.KARAKEEP_API_URL = 'https://karakeep.test';
|
||||||
|
process.env.KARAKEEP_API_TOKEN = 'tok-123';
|
||||||
|
const bm = await getBookmark('b-1');
|
||||||
|
expect(bm.url).toBe('https://example.com');
|
||||||
|
expect(lastInit.headers.Authorization).toBe('Bearer tok-123');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns null on 404', async () => {
|
||||||
|
global.fetch = vi.fn(async () => new Response('', { status: 404 }));
|
||||||
|
expect(await getBookmark('nope')).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws on other non-2xx', async () => {
|
||||||
|
global.fetch = vi.fn(async () => new Response('boom', { status: 503 }));
|
||||||
|
await expect(getBookmark('x')).rejects.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user