UNPKG

d1-driver

Version:

🌤️ Cloudflare D1 External Fetch Compatible Driver

188 lines (187 loc) 5.89 kB
import { array, boolean, isNull, number, scanner, string, union } from 'typescanner'; const is_message = scanner({ code: string, message: string }); const is_list_response = scanner({ success: boolean, errors: array(is_message), messages: array(is_message), result: array(scanner({ created_at: string, name: string, uuid: string, version: string })), result_info: scanner({ count: number, page: number, per_page: number, total_count: number }) }); const is_create_response = scanner({ success: boolean, errors: array(is_message), messages: array(is_message), result: union(scanner({ created_at: string, name: string, uuid: string, version: string }), isNull) }); const is_delete_response = scanner({ success: boolean, errors: array(is_message), messages: array(is_message), result: isNull }); const is_get_response = scanner({ success: boolean, errors: array(is_message), messages: array(is_message), result: scanner({ created_at: string, file_size: number, name: string, num_tables: number, uuid: string, version: string }) }); const is_query_response = scanner({ success: boolean, errors: array(is_message), messages: array(is_message), result: array(scanner({ success: boolean, results: array(scanner({})), meta: scanner({ changed_db: boolean, changes: number, duration: number, last_row_id: number, rows_read: number, rows_written: number, size_after: number }) })) }); const checkError = (response) => { if (!response.success) { throw new Error(response.errors .map((e) => `D1 Driver: [${e.code}] ${e.message}`) .join('\n')); } }; export class D1 { accountId; apiKey; constructor(accountId, apiKey) { this.accountId = accountId; this.apiKey = apiKey; } async list(params) { const { name, page, per_page } = params ?? {}; const url = new URL(`https://api.cloudflare.com/client/v4/accounts/${this.accountId}/d1/database`); if (name) { url.searchParams.set('name', name); } if (page) { url.searchParams.set('page', page.toString()); } if (per_page) { url.searchParams.set('per_page', per_page.toString()); } const res = await fetch(url.href, { method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${this.apiKey}` } }); const json = await res.json(); checkError(json); if (!is_list_response(json)) { throw new Error('D1 Driver: Invalid list response'); } return json; } async create(name) { const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${this.accountId}/d1/database`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${this.apiKey}` }, body: JSON.stringify({ name }) }); const json = await res.json(); checkError(json); if (!is_create_response(json)) { console.error(json); throw new Error(`D1 Driver: Invalid response in create "${name}"`); } return json; } async delete(uuid) { const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${this.accountId}/d1/database/${uuid}`, { method: 'DELETE', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${this.apiKey}` } }); const json = await res.json(); checkError(json); if (!is_delete_response(json)) { throw new Error(`D1 Driver: Invalid delete response for "${uuid}"`); } return json; } async get(uuid) { const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${this.accountId}/d1/database/${uuid}`, { method: 'GET', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${this.apiKey}` } }); const json = await res.json(); checkError(json); if (!is_get_response(json)) { throw new Error(`D1 Driver: Invalid get response for "${uuid}"`); } return json; } // eslint-disable-next-line @typescript-eslint/no-explicit-any async query(uuid, sql, params = []) { const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${this.accountId}/d1/database/${uuid}/query`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${this.apiKey}` }, body: JSON.stringify({ params, sql }) }); const json = await res.json(); checkError(json); if (!is_query_response(json)) { throw new Error(`D1 Driver: Invalid query response for "${uuid}" with "${sql}"`); } return json; } async raw(uuid, sql, params = []) { const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${this.accountId}/d1/database/${uuid}/query`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${this.apiKey}` }, body: JSON.stringify({ params, sql }) }); const json = await res.json(); return json; } }