diff --git a/src/index.ts b/src/index.ts index ed1af43..f5676b2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,13 +10,32 @@ import { lexToJson, } from "@atproto/lex"; import { custom, ZodMiniCustom } from "zod/mini"; +import type { MarkdownHeading } from "astro"; function getMain(ns: T | { main: T }): T { return "main" in ns ? ns.main : ns; } +// Duplicate from Astro, since it is non-exported. +interface RenderedContent { + /** Rendered HTML string. If present then `render(entry)` will return a component that renders this HTML. */ + html: string; + metadata?: { + /** Any images that are present in this entry. Relative to the {@link DataEntry} filePath. */ + imagePaths?: Array; + /** Any headings that are present in this file. */ + headings?: MarkdownHeading[]; + /** Raw frontmatter, parsed from the file. This may include data from remark plugins. */ + frontmatter?: Record; + /** Any other metadata that is present in this file. */ + [key: string]: unknown; + }; +} + +export type RendererFunction = (data: T) => RenderedContent + /** Configuration for {@link atLoader}. Includes all ATProto `ListOptions`. */ -interface ATLoaderBaseConfig { +interface ATLoaderBaseConfig { /** Repository identifier (DID or handle). Defaults to authenticated user's DID. */ repo?: AtIdentifierString; /** Optional preconfigured ATProto client (for auth, custom headers, etc.). */ @@ -29,20 +48,29 @@ interface ATLoaderBaseConfig { cursor?: string /** If true, returns records in reverse chronological order. */ reverse?: boolean + /** + * A renderer function that will be called with the data. If defined, it will + * transform the content being retrieved and will provide the `render()` function + * and the `` component to be used. + */ + renderer?: RendererFunction> } -interface ATLiveLoaderConfig extends ATLoaderBaseConfig { } +interface ATLiveLoaderConfig extends ATLoaderBaseConfig { } interface ATLoaderMarkdownConfig { /** * If there is Markdown text in the schema, define this function and the loader * will expose a render function to render it to HTML. + * + * **Note**: if `renderer` is defined, it will take precedent, and Markdown will not + * be rendered. */ getMarkdown?: (data: Infer) => string; } interface ATLoaderConfig - extends ATLoaderMarkdownConfig, ATLoaderBaseConfig { } + extends ATLoaderMarkdownConfig, ATLoaderBaseConfig { } /** Filter passed to {@link atLiveLoader} `loadEntry`, forwarded to `client.get()`. */ type ATLoaderEntryFilter = GetOptions; @@ -89,15 +117,15 @@ export function atZodSchema(ns: T | { main: T }) { */ export function atLiveLoader( ns: { main: T }, - config: ATLiveLoaderConfig, + config: ATLiveLoaderConfig, ): LiveLoader, ATLoaderEntryFilter, ATLoaderCollectionFilter, ATLoaderError>; export function atLiveLoader( ns: T, - config: ATLiveLoaderConfig, + config: ATLiveLoaderConfig, ): LiveLoader, ATLoaderEntryFilter, ATLoaderCollectionFilter, ATLoaderError>; export function atLiveLoader( ns: T | { main: T }, - { client: configClient, endpoint, ...options }: ATLiveLoaderConfig = {}, + { client: configClient, endpoint, ...options }: ATLiveLoaderConfig = {}, ): LiveLoader, ATLoaderEntryFilter, ATLoaderCollectionFilter, ATLoaderError> { const schema: T = getMain(ns); return {