Files
clientsflow/microapps/templates/pocketbase-deno-dashboard/pocketbase/client.ts
2026-03-23 11:47:14 +07:00

74 lines
1.7 KiB
TypeScript

type PocketBaseClientOptions = {
baseUrl: string;
email: string;
password: string;
};
type PocketBaseListOptions = {
collectionName: string;
filter?: string;
};
type AuthResponse = {
token: string;
};
type RecordListResponse<TRecord> = {
items: TRecord[];
};
export function createPocketBaseClient(options: PocketBaseClientOptions) {
let cachedToken: string | null = null;
async function authenticate() {
if (cachedToken) return cachedToken;
const response = await fetch(
`${options.baseUrl}/api/collections/_superusers/auth-with-password`,
{
method: "POST",
headers: {
"content-type": "application/json",
},
body: JSON.stringify({
identity: options.email,
password: options.password,
}),
},
);
if (!response.ok) {
throw new Error(`PocketBase auth failed with status ${response.status}`);
}
const payload = await response.json() as AuthResponse;
cachedToken = payload.token;
return cachedToken;
}
return {
async listRecords<TRecord>(input: PocketBaseListOptions) {
const token = await authenticate();
const url = new URL(
`${options.baseUrl}/api/collections/${input.collectionName}/records`,
);
if (input.filter) {
url.searchParams.set("filter", input.filter);
}
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!response.ok) {
throw new Error(`PocketBase list failed with status ${response.status}`);
}
const payload = await response.json() as RecordListResponse<TRecord>;
return payload.items;
},
};
}