diff options
Diffstat (limited to 'kittybox-rs/companion-lite/src/micropub_api.ts')
-rw-r--r-- | kittybox-rs/companion-lite/src/micropub_api.ts | 125 |
1 files changed, 0 insertions, 125 deletions
diff --git a/kittybox-rs/companion-lite/src/micropub_api.ts b/kittybox-rs/companion-lite/src/micropub_api.ts deleted file mode 100644 index fa1c431..0000000 --- a/kittybox-rs/companion-lite/src/micropub_api.ts +++ /dev/null @@ -1,125 +0,0 @@ -export interface MicropubChannel { - readonly uid: string, - readonly name: string -} - -export interface MF2 { - type: string[], - properties: { [key:string]: (string | MF2 | {[key:string]: string})[] | undefined } -} - -export interface MicropubConfig { - readonly channels?: MicropubChannel[], - readonly "media-endpoint"?: string -} - -export interface MicropubErrorMessage { - readonly error: string, - readonly error_description: string | undefined -} - -export class MicropubError extends Error { - readonly status: number | null - readonly response: MicropubErrorMessage | null - - constructor(status: number | null, response: MicropubErrorMessage | null, cause: Error | null = null) { - // Needs to pass both `message` and `options` to install the "cause" property. - if (status == null) { - super("Micropub endpoint didn't respond properly", { cause }); - } else if (response == null) { - super(`Micropub endpoint returned HTTP ${status}`, { cause }); - } else { - super( - `Micropub endpoint returned ${response.error}: ${response.error_description ?? "(no description was provided)"}`, - { cause } - ) - } - - this.status = status; - this.response = response; - } -} - -export class Micropub { - readonly token: string - readonly micropub_endpoint: URL - private config_response: MicropubConfig | null - - constructor({ endpoint, token }: { endpoint: URL, token: string }) { - this.micropub_endpoint = endpoint; - this.token = token; - this.config_response = null; - } - - async config(): Promise<MicropubConfig> { - if (this.config_response != null) { - return this.config_response - } - let url = this.micropub_endpoint; - let params = new URLSearchParams(); - for (const [key, val] of url.searchParams) { - params.append(key, val) - } - params.set("q", "config") - - url.search = "?" + params.toString(); - - const response = await fetch(url, { - headers: { - "Authorization": `Bearer ${this.token}` - } - }); - if (response.ok) { - const config = await response.json() as MicropubConfig; - this.config_response = config - - return config - } else { - throw new MicropubError(response.status, await response.json() as MicropubErrorMessage); - } - } - - async submit(mf2: MF2): Promise<URL> { - const response = await fetch(this.micropub_endpoint, { - method: "POST", - headers: { - "Authorization": `Bearer ${this.token}`, - "Content-Type": "application/json" - }, - body: JSON.stringify(mf2) - }) - - if (response.status != 201 && response.status != 202) { - let err = await response.json() as MicropubErrorMessage; - - throw new MicropubError(response.status, err) - } else { - return new URL(response.headers.get("Location") as string) - } - } - - async upload(file: File): Promise<URL> { - const config = await this.config(); - const media = config["media-endpoint"]; - if (media == null) { - throw new Error("Micropub endpoint doesn't support file uploads") - } - - const form = new FormData(); - form.set("file", file); - - const response = await fetch(media, { - method: "POST", - headers: { - "Authorization": `Bearer ${this.token}`, - }, - body: form - }) - - if (response.ok) { - return new URL(response.headers.get("Location") as string) - } else { - throw new MicropubError(response.status, await response.json()); - } - } -} |