diff --git a/src/accounts/stores.ts b/src/accounts/stores.ts index c44a012..6a9fdca 100644 --- a/src/accounts/stores.ts +++ b/src/accounts/stores.ts @@ -6,10 +6,19 @@ import { } from "masto"; import { createMastoClientFor } from "../masto/clients"; -export type Account = { +export type RemoteServer = { site: string; - accessToken: string; +}; +export type AccountKey = RemoteServer & { + accessToken: string; +}; + +export function isAccountKey(object: RemoteServer): object is AccountKey { + return !!(object as Record)["accessToken"]; +} + +export type Account = AccountKey & { tokenType: string; scope: string; createdAt: number; @@ -17,6 +26,10 @@ export type Account = { inf?: mastodon.v1.AccountCredentials; }; +export function isAccount(object: AccountKey) { + return !!(object as Record)["tokenType"]; +} + export const $accounts = persistentAtom("accounts", [], { encode: JSON.stringify, decode: JSON.parse, diff --git a/src/masto/base.ts b/src/masto/base.ts new file mode 100644 index 0000000..823fad7 --- /dev/null +++ b/src/masto/base.ts @@ -0,0 +1,23 @@ +import { createCacheBucket } from "~platform/cache"; + +export const cacheBucket = /* @__PURE__ */ createCacheBucket("mastodon"); + +export function toSmallCamelCase(object: T) :T { + if (!object || typeof object !== "object") { + return object; + } else if (Array.isArray(object)) { + return object.map(toSmallCamelCase) as T + } + + const result = {} as Record; + for (const k in object) { + const value = toSmallCamelCase(object[k]) + const nk = + typeof k === "string" + ? k.replace(/_(.)/g, (_, match) => match.toUpperCase()) + : k; + result[nk] = value; + } + + return result as T; +} diff --git a/src/masto/statuses.ts b/src/masto/statuses.ts new file mode 100644 index 0000000..91fdc7a --- /dev/null +++ b/src/masto/statuses.ts @@ -0,0 +1,30 @@ +import { CachedFetch } from "~platform/cache"; +import { cacheBucket, toSmallCamelCase } from "./base"; +import { + isAccountKey, + type RemoteServer, +} from "../accounts/stores"; +import type { mastodon } from "masto"; + + + +export const fetchStatus = /* @__PURE__ */ new CachedFetch( + cacheBucket, + (session: RemoteServer, id: string) => { + const headers = new Headers({ + Accept: "application/json", + }); + if (isAccountKey(session)) { + headers.set("Authorization", `Bearer ${session.accessToken}`); + } + return { + url: new URL(`./api/v1/statuses/${id}`, session.site).toString(), + headers, + }; + }, + async (response) => { + return toSmallCamelCase( + await response.json(), + ) as unknown as mastodon.v1.Status; + }, +);