From 53655f99bf60d97c4567d2850c1a4ba74059fc05 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Mon, 10 Apr 2023 19:34:00 -0500 Subject: [PATCH] We do a little refactoring --- src/api/statuses.ts | 3 +-- src/client.ts | 2 +- src/gossip.ts | 4 ++-- src/handler.ts | 3 +-- src/{ => nostr}/event.ts | 0 src/nostr/events/kind-0.ts | 32 ++++++++++++++++++++++++++++++++ src/publisher.ts | 3 +-- src/schema.ts | 22 ++++------------------ src/transmute.ts | 11 ++--------- src/utils.ts | 3 +-- 10 files changed, 45 insertions(+), 38 deletions(-) rename src/{ => nostr}/event.ts (100%) create mode 100644 src/nostr/events/kind-0.ts diff --git a/src/api/statuses.ts b/src/api/statuses.ts index c80c2d3..ad0c1bd 100644 --- a/src/api/statuses.ts +++ b/src/api/statuses.ts @@ -1,11 +1,10 @@ import { validator, z } from '@/deps.ts'; +import { type Event } from '@/nostr/event.ts'; import publish from '../publisher.ts'; import { toStatus } from '../transmute.ts'; import { getKeys } from '../utils.ts'; -import type { Event } from '../event.ts'; - const createStatusSchema = z.object({ status: z.string(), }); diff --git a/src/client.ts b/src/client.ts index 7deb3e6..eb5b178 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1,8 +1,8 @@ import { Author, RelayPool } from '@/deps.ts'; +import { type Event, type SignedEvent } from '@/nostr/event.ts'; import { poolRelays } from './config.ts'; -import type { Event, SignedEvent } from './event.ts'; import { eventDateComparator, nostrNow } from './utils.ts'; const pool = new RelayPool(poolRelays); diff --git a/src/gossip.ts b/src/gossip.ts index 7ccb218..4a951e6 100644 --- a/src/gossip.ts +++ b/src/gossip.ts @@ -1,6 +1,6 @@ -import { parseRelay } from './schema.ts'; +import { type Event } from '@/nostr/event.ts'; -import type { Event } from './event.ts'; +import { parseRelay } from './schema.ts'; /** Gets relays which pertain to the author from the event. */ function getAuthorRelays(event: Event): URL[] { diff --git a/src/handler.ts b/src/handler.ts index ad75b10..8322193 100644 --- a/src/handler.ts +++ b/src/handler.ts @@ -1,9 +1,8 @@ import { gossipDB } from '@/db.ts'; +import { type Event } from '@/nostr/event.ts'; import { getAuthorRelays } from './gossip.ts'; -import type { Event } from './event.ts'; - function handleEvent(event: Event): void { handleRelays(event); } diff --git a/src/event.ts b/src/nostr/event.ts similarity index 100% rename from src/event.ts rename to src/nostr/event.ts diff --git a/src/nostr/events/kind-0.ts b/src/nostr/events/kind-0.ts new file mode 100644 index 0000000..2d68abd --- /dev/null +++ b/src/nostr/events/kind-0.ts @@ -0,0 +1,32 @@ +import { z } from '@/deps.ts'; + +import { type Event } from '../event.ts'; + +const optionalString = z.string().optional().catch(undefined); + +const metaContentSchema = z.object({ + name: optionalString, + about: optionalString, + picture: optionalString, + banner: optionalString, + nip05: optionalString, + lud16: optionalString, +}); + +/** Author metadata from Event<0>. */ +type MetaContent = z.infer; + +/** + * Get (and validate) data from a kind 0 event. + * https://github.com/nostr-protocol/nips/blob/master/01.md + */ +function parseContent(event: Event<0>): MetaContent { + try { + const json = JSON.parse(event.content); + return metaContentSchema.parse(json); + } catch (_e) { + return {}; + } +} + +export { type MetaContent, metaContentSchema, parseContent }; diff --git a/src/publisher.ts b/src/publisher.ts index c2cebc3..a152ec1 100644 --- a/src/publisher.ts +++ b/src/publisher.ts @@ -1,10 +1,9 @@ import { getEventHash, signEvent } from '@/deps.ts'; +import { type Event } from '@/nostr/event.ts'; import { pool } from './client.ts'; import { publishRelays } from './config.ts'; -import type { Event } from './event.ts'; - /** Publish an event to the Nostr relay. */ function publish(event: Event, privatekey: string, relays = publishRelays): void { event.id = getEventHash(event); diff --git a/src/schema.ts b/src/schema.ts index 1f3dda8..c61c437 100644 --- a/src/schema.ts +++ b/src/schema.ts @@ -9,26 +9,13 @@ const jsonSchema = z.string().transform((value, ctx) => { } }); -const optionalString = z.string().optional().catch(undefined); - -const metaContentSchema = z.object({ - name: optionalString, - about: optionalString, - picture: optionalString, - banner: optionalString, - nip05: optionalString, - lud16: optionalString, -}); - -type MetaContent = z.infer; - -/** It's like `safeParse` except it returns `T` on success and `undefined` on fail. */ -function parseish(schema: z.ZodType, value: unknown): T | undefined { +/** Alias for `safeParse`, but instead of returning a success object it returns the value (or undefined on fail). */ +function parseValue(schema: z.ZodType, value: unknown): T | undefined { const result = schema.safeParse(value); return result.success ? result.data : undefined; } -const parseRelay = (relay: string | URL) => parseish(relaySchema, relay); +const parseRelay = (relay: string | URL) => parseValue(relaySchema, relay); const relaySchema = z.custom((relay) => { if (typeof relay !== 'string') return false; @@ -40,5 +27,4 @@ const relaySchema = z.custom((relay) => { } }); -export { jsonSchema, metaContentSchema, parseRelay, relaySchema }; -export type { MetaContent }; +export { jsonSchema, parseRelay, relaySchema }; diff --git a/src/transmute.ts b/src/transmute.ts index 7b4b3f8..7c23437 100644 --- a/src/transmute.ts +++ b/src/transmute.ts @@ -1,19 +1,12 @@ import { nip19 } from '@/deps.ts'; +import { type Event } from '@/nostr/event.ts'; +import { type MetaContent, parseContent } from '@/nostr/events/kind-0.ts'; import { LOCAL_DOMAIN } from './config.ts'; import { fetchUser } from './client.ts'; -import { jsonSchema, MetaContent, metaContentSchema } from './schema.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>) { const { pubkey } = event; const { name, nip05, picture, banner, about }: MetaContent = parseContent(event); diff --git a/src/utils.ts b/src/utils.ts index bb7d543..3d1aa9d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,5 @@ import { Context, getPublicKey } from '@/deps.ts'; - -import type { Event } from './event.ts'; +import { type Event } from '@/nostr/event.ts'; /** Get the current time in Nostr format. */ const nostrNow = () => Math.floor(new Date().getTime() / 1000);