/** The reviewer API behind https://mangrove.reviews */
export const ORIGINAL_API = 'https://api.mangrove.reviews'
/** The signer behind https://mangrove.reviews */
export const ORIGINAL_SIGNER = 'https://signer.mangrove.reviews'
/** The Fediverse bridge behind https://mangrove.reviews */
export const ORIGINAL_FEDIVERSE = 'https://social.mangrove.reviews'
/**
* Error for a response a Mangrove server refused.
* `status` is the HTTP status and `body` the response text, which names the
* reason, such as the field of a review that is wrong.
*/
export class ApiError extends Error {
/**
* @param {number} status
* @param {string} body
*/
constructor(status, body) {
super(
body
? `Request refused with status ${status}: ${body}`
: `Request refused with status ${status}`
)
this.name = 'ApiError'
this.status = status
this.body = body
}
}
/**
* Fetch a JSON response, or throw an {@link ApiError} for a refused request.
* An empty body, as in a 204 answer, resolves to null.
* @param {string} url
* @param {object} [options]
* @returns {Promise<any>}
*/
export async function request(url, options = {}) {
const response = await fetch(url, options)
const text = await response.text()
if (!response.ok) {
throw new ApiError(response.status, text)
}
return text ? JSON.parse(text) : null
}