This commit is contained in:
parent
d7e1358495
commit
66b593add8
2 changed files with 76 additions and 15 deletions
|
@ -1,19 +1,20 @@
|
||||||
import { createCacheBucket } from "~platform/cache";
|
import { createCacheBucket } from "~platform/cache";
|
||||||
|
import { MastoHttpError, MastoTimeoutError, MastoUnexpectedError } from "masto";
|
||||||
|
|
||||||
export const CACHE_BUCKET_NAME = "mastodon"
|
export const CACHE_BUCKET_NAME = "mastodon";
|
||||||
|
|
||||||
export const cacheBucket = /* @__PURE__ */ createCacheBucket(CACHE_BUCKET_NAME);
|
export const cacheBucket = /* @__PURE__ */ createCacheBucket(CACHE_BUCKET_NAME);
|
||||||
|
|
||||||
export function toSmallCamelCase<T>(object: T) :T {
|
export function toSmallCamelCase<T>(object: T): T {
|
||||||
if (!object || typeof object !== "object") {
|
if (!object || typeof object !== "object") {
|
||||||
return object;
|
return object;
|
||||||
} else if (Array.isArray(object)) {
|
} else if (Array.isArray(object)) {
|
||||||
return object.map(toSmallCamelCase) as T
|
return object.map(toSmallCamelCase) as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = {} as Record<keyof any, unknown>;
|
const result = {} as Record<keyof any, unknown>;
|
||||||
for (const k in object) {
|
for (const k in object) {
|
||||||
const value = toSmallCamelCase(object[k])
|
const value = toSmallCamelCase(object[k]);
|
||||||
const nk =
|
const nk =
|
||||||
typeof k === "string"
|
typeof k === "string"
|
||||||
? k.replace(/_(.)/g, (_, match) => match.toUpperCase())
|
? k.replace(/_(.)/g, (_, match) => match.toUpperCase())
|
||||||
|
@ -23,3 +24,61 @@ export function toSmallCamelCase<T>(object: T) :T {
|
||||||
|
|
||||||
return result as T;
|
return result as T;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function contentTypeOf(headers: Headers) {
|
||||||
|
const raw = headers.get("Content-Type")?.replace(/\s*;.*$/, "");
|
||||||
|
if (!raw) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrpas the error reason into masto's errors:
|
||||||
|
* {@link MastoHttpError} if the reason is a {@link Response},
|
||||||
|
* {@link MastoTimeoutError} if the reason is a timeout error.
|
||||||
|
*
|
||||||
|
* @throws If the reason is unexpected, {@link MastoUnexpectedError} will be thrown.
|
||||||
|
*/
|
||||||
|
export async function wrapsError(reason: Response): Promise<MastoHttpError>;
|
||||||
|
export async function wrapsError(reason: {
|
||||||
|
name: "TimeoutError";
|
||||||
|
}): Promise<MastoTimeoutError>;
|
||||||
|
export async function wrapsError<T>(reason: T): Promise<T>;
|
||||||
|
|
||||||
|
export async function wrapsError(reason: unknown) {
|
||||||
|
if (reason instanceof Response) {
|
||||||
|
const contentType = contentTypeOf(reason.headers);
|
||||||
|
if (!contentType) {
|
||||||
|
throw new MastoUnexpectedError(
|
||||||
|
"The server returned data with an unknown encoding. The server may be down",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await reason.json();
|
||||||
|
const {
|
||||||
|
error: message,
|
||||||
|
errorDescription,
|
||||||
|
details,
|
||||||
|
...additionalProperties
|
||||||
|
} = data;
|
||||||
|
|
||||||
|
return new MastoHttpError(
|
||||||
|
{
|
||||||
|
statusCode: reason.status,
|
||||||
|
message,
|
||||||
|
description: errorDescription,
|
||||||
|
details,
|
||||||
|
additionalProperties,
|
||||||
|
},
|
||||||
|
{ cause: reason },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reason && (reason as { name?: string }).name === "TimeoutError") {
|
||||||
|
return new MastoTimeoutError("Request timed out", { cause: reason });
|
||||||
|
}
|
||||||
|
|
||||||
|
return reason;
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
import { CachedFetch } from "~platform/cache";
|
import { CachedFetch } from "~platform/cache";
|
||||||
import { cacheBucket, toSmallCamelCase } from "./base";
|
import { cacheBucket, toSmallCamelCase, wrapsError } from "./base";
|
||||||
import {
|
import { isAccountKey, type RemoteServer } from "../accounts/stores";
|
||||||
isAccountKey,
|
import { type mastodon } from "masto";
|
||||||
type RemoteServer,
|
|
||||||
} from "../accounts/stores";
|
|
||||||
import type { mastodon } from "masto";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const fetchStatus = /* @__PURE__ */ new CachedFetch(
|
export const fetchStatus = /* @__PURE__ */ new CachedFetch(
|
||||||
cacheBucket,
|
cacheBucket,
|
||||||
|
@ -23,8 +18,15 @@ export const fetchStatus = /* @__PURE__ */ new CachedFetch(
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
async (response) => {
|
async (response) => {
|
||||||
return toSmallCamelCase(
|
try {
|
||||||
await response.json(),
|
if (!response.ok) {
|
||||||
) as unknown as mastodon.v1.Status;
|
throw response;
|
||||||
|
}
|
||||||
|
return toSmallCamelCase(
|
||||||
|
await response.json(),
|
||||||
|
) as unknown as mastodon.v1.Status;
|
||||||
|
} catch (reason) {
|
||||||
|
throw wrapsError(reason);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Reference in a new issue