Reuse existing transmute functions, lol forgot I already wrote that
This commit is contained in:
parent
6748e13a36
commit
9f81d0d572
|
@ -2,7 +2,7 @@ import { fetchFeed, fetchFollows } from '../client.ts';
|
||||||
import { getKeys } from '../utils.ts';
|
import { getKeys } from '../utils.ts';
|
||||||
|
|
||||||
import type { Context } from '@/deps.ts';
|
import type { Context } from '@/deps.ts';
|
||||||
import type { SignedEvent } from '../event.ts';
|
import { toStatus } from '../transmute.ts';
|
||||||
|
|
||||||
async function homeController(c: Context) {
|
async function homeController(c: Context) {
|
||||||
const keys = getKeys(c);
|
const keys = getKeys(c);
|
||||||
|
@ -16,33 +16,9 @@ async function homeController(c: Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const events = await fetchFeed(follows);
|
const events = await fetchFeed(follows);
|
||||||
const statuses = events.map(toStatus);
|
const statuses = (await Promise.all(events.map(toStatus))).filter(Boolean);
|
||||||
|
|
||||||
return c.json(statuses);
|
return c.json(statuses);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Account {
|
|
||||||
id: string;
|
|
||||||
acct: string;
|
|
||||||
username: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Status {
|
|
||||||
id: string;
|
|
||||||
content: string;
|
|
||||||
account: Account;
|
|
||||||
}
|
|
||||||
|
|
||||||
function toStatus(event: SignedEvent<1>): Status {
|
|
||||||
return {
|
|
||||||
id: event.id,
|
|
||||||
content: event.content,
|
|
||||||
account: {
|
|
||||||
id: event.pubkey,
|
|
||||||
acct: event.pubkey,
|
|
||||||
username: event.pubkey,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export default homeController;
|
export default homeController;
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import { validator, z } from '@/deps.ts';
|
import { validator, z } from '@/deps.ts';
|
||||||
|
|
||||||
import { fetchUser } from '../client.ts';
|
|
||||||
import publish from '../publisher.ts';
|
import publish from '../publisher.ts';
|
||||||
import { toAccount, toStatus } from '../transmute.ts';
|
import { toStatus } from '../transmute.ts';
|
||||||
import { getKeys } from '../utils.ts';
|
import { getKeys } from '../utils.ts';
|
||||||
|
|
||||||
import type { Event } from '../event.ts';
|
import type { Event } from '../event.ts';
|
||||||
|
@ -29,10 +28,7 @@ const createStatusController = validator('json', async (value, c) => {
|
||||||
|
|
||||||
publish(event, privatekey);
|
publish(event, privatekey);
|
||||||
|
|
||||||
return c.json({
|
return c.json(await toStatus(event));
|
||||||
...toStatus(event),
|
|
||||||
account: toAccount((await fetchUser(pubkey))!),
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
return c.json({ error: 'Bad request' }, 400);
|
return c.json({ error: 'Bad request' }, 400);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,16 @@
|
||||||
import { z } from '@/deps.ts';
|
import { z } from '@/deps.ts';
|
||||||
|
|
||||||
|
const jsonSchema = z.string().refine((value) => {
|
||||||
|
try {
|
||||||
|
// FIXME: this calls JSON.parse twice. Can we make it not do that?
|
||||||
|
// https://github.com/colinhacks/zod/discussions/2215
|
||||||
|
JSON.parse(value);
|
||||||
|
return true;
|
||||||
|
} catch (_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}).transform((value) => JSON.parse(value));
|
||||||
|
|
||||||
const optionalString = z.string().optional().catch(undefined);
|
const optionalString = z.string().optional().catch(undefined);
|
||||||
|
|
||||||
const metaContentSchema = z.object({
|
const metaContentSchema = z.object({
|
||||||
|
@ -13,5 +24,5 @@ const metaContentSchema = z.object({
|
||||||
|
|
||||||
type MetaContent = z.infer<typeof metaContentSchema>;
|
type MetaContent = z.infer<typeof metaContentSchema>;
|
||||||
|
|
||||||
export { metaContentSchema };
|
export { jsonSchema, metaContentSchema };
|
||||||
export type { MetaContent };
|
export type { MetaContent };
|
||||||
|
|
|
@ -1,19 +1,27 @@
|
||||||
import { LOCAL_DOMAIN } from './config.ts';
|
import { LOCAL_DOMAIN } from './config.ts';
|
||||||
import { MetaContent, metaContentSchema } from './schema.ts';
|
import { fetchUser } from './client.ts';
|
||||||
|
import { jsonSchema, MetaContent, metaContentSchema } from './schema.ts';
|
||||||
|
|
||||||
import type { Event } from './event.ts';
|
import type { Event } from './event.ts';
|
||||||
|
|
||||||
|
const DEFAULT_AVATAR = 'https://gleasonator.com/images/avi.png';
|
||||||
|
|
||||||
|
function parseContent(event: Event<0>): MetaContent {
|
||||||
|
const json = jsonSchema.parse(event.content);
|
||||||
|
const result = metaContentSchema.safeParse(json);
|
||||||
|
return result.success ? result.data : {};
|
||||||
|
}
|
||||||
|
|
||||||
function toAccount(event: Event<0>) {
|
function toAccount(event: Event<0>) {
|
||||||
const { pubkey } = event;
|
const { pubkey } = event;
|
||||||
const parsed = metaContentSchema.safeParse(JSON.parse(event?.content || ''));
|
const content: MetaContent = parseContent(event);
|
||||||
const content: MetaContent = parsed.success ? parsed.data : {};
|
|
||||||
const { host, origin } = new URL(LOCAL_DOMAIN);
|
const { host, origin } = new URL(LOCAL_DOMAIN);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: pubkey,
|
id: pubkey,
|
||||||
acct: pubkey,
|
acct: content.nip05 || pubkey,
|
||||||
avatar: content.picture,
|
avatar: content.picture || DEFAULT_AVATAR,
|
||||||
avatar_static: content.picture,
|
avatar_static: content.picture || DEFAULT_AVATAR,
|
||||||
bot: false,
|
bot: false,
|
||||||
created_at: event ? new Date(event.created_at * 1000).toISOString() : new Date().toISOString(),
|
created_at: event ? new Date(event.created_at * 1000).toISOString() : new Date().toISOString(),
|
||||||
display_name: content.name,
|
display_name: content.name,
|
||||||
|
@ -27,21 +35,25 @@ function toAccount(event: Event<0>) {
|
||||||
header_static: content.banner,
|
header_static: content.banner,
|
||||||
locked: false,
|
locked: false,
|
||||||
note: content.about,
|
note: content.about,
|
||||||
fqn: `${pubkey}@${host}`,
|
fqn: content.nip05 || `${pubkey}@${host}`,
|
||||||
url: `${origin}/users/${pubkey}`,
|
url: `${origin}/users/${pubkey}`,
|
||||||
username: pubkey,
|
username: content.nip05 || pubkey,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function toStatus(event: Event<1>) {
|
async function toStatus(event: Event<1>) {
|
||||||
|
const profile = await fetchUser(event.pubkey);
|
||||||
|
const account = profile ? toAccount(profile) : undefined;
|
||||||
|
if (!account) return;
|
||||||
|
|
||||||
|
const inReplyTo = event.tags.find((tag) => tag[0] === 'e' && tag[3] === 'reply');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: event.id,
|
id: event.id,
|
||||||
account: {
|
account,
|
||||||
id: event.pubkey,
|
|
||||||
},
|
|
||||||
content: event.content,
|
content: event.content,
|
||||||
created_at: new Date(event.created_at * 1000).toISOString(),
|
created_at: new Date(event.created_at * 1000).toISOString(),
|
||||||
in_reply_to_id: null,
|
in_reply_to_id: inReplyTo ? inReplyTo[1] : null,
|
||||||
in_reply_to_account_id: null,
|
in_reply_to_account_id: null,
|
||||||
sensitive: false,
|
sensitive: false,
|
||||||
spoiler_text: '',
|
spoiler_text: '',
|
||||||
|
|
Loading…
Reference in New Issue