chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
// A minimal Cloudflare API client. Calls ride through the PDS's /cf-api
// passthrough, which forwards the Authorization header and keeps nothing;
// api.cloudflare.com itself answers no CORS preflight.
/** @param {string} token @param {string} [base] */
export function cfClient(token, base = '/cf-api') {
/**
* @param {string} path
* @param {RequestInit} [init]
*/
async function call(path, init = {}) {
const response = await fetch(`${base}${path}`, {
...init,
headers: {
Authorization: `Bearer ${token}`,
...(init.body && !(init.body instanceof FormData)
? { 'Content-Type': 'application/json' }
: {}),
...init.headers,
},
});
const body = await response.json().catch(() => null);
if (!body) {
throw new Error(`Cloudflare API returned ${response.status}`);
}
if (!body.success) {
const messages = (body.errors ?? [])
.map((/** @type {{code?: number, message: string}} */ e) =>
e.code ? `${e.message} (code ${e.code})` : e.message,
)
.join('; ');
const error = new Error(
messages || `Cloudflare API error ${response.status}`,
);
/** @type {any} */ (error).codes = (body.errors ?? []).map(
(/** @type {{code?: number}} */ e) => e.code,
);
throw error;
}
return body.result;
}
return {
/** @param {string} path */
get: (path) => call(path),
/** @param {string} path @param {unknown} [body] */
post: (path, body) =>
call(path, {
method: 'POST',
body: body ? JSON.stringify(body) : undefined,
}),
/** @param {string} path @param {unknown} body */
put: (path, body) =>
call(path, { method: 'PUT', body: JSON.stringify(body) }),
/** @param {string} path @param {unknown} body */
patch: (path, body) =>
call(path, { method: 'PATCH', body: JSON.stringify(body) }),
/** @param {string} path @param {FormData} form */
putForm: (path, form) => call(path, { method: 'PUT', body: form }),
};
}