import type { Agent } from "@atproto/api"; export const REDIRECT_DELAY_SECONDS = 5; // ============================================================================ // Helpers // ============================================================================ export function withReturnToParam( returnTo: string | undefined, key: string, value: string, ): string | undefined { if (!returnTo) return undefined; try { const url = new URL(returnTo); url.searchParams.set(key, value); return url.toString(); } catch { return returnTo; } } /** * Scan a repo for a record in `collection` where `record[field] === uri`. * Returns the record AT-URI, or null if not found. */ export async function findExistingRecord( agent: Agent, did: string, collection: string, field: string, uri: string, ): Promise { let cursor: string | undefined; do { const result = await agent.com.atproto.repo.listRecords({ repo: did, collection, limit: 100, cursor, }); for (const record of result.data.records) { const value = record.value as Record; if (value[field] === uri) { return record.uri; } } cursor = result.data.cursor; } while (cursor); return null; } // ============================================================================ // HTML rendering // ============================================================================ export function renderHandleForm( params: { resourceUri: string; resourceField: string; loginPath: string; title: string; description: string; buttonLabel: string; returnTo?: string; error?: string; action?: string; }, styleHref: string, ): string { const { resourceUri, resourceField, loginPath, title, description, buttonLabel, returnTo, error, action, } = params; const errorHtml = error ? `

${escapeHtml(error)}

` : ""; const returnToInput = returnTo ? `` : ""; const actionInput = action ? `` : ""; return page( `

${escapeHtml(title)}

${escapeHtml(description)}

${errorHtml}
${returnToInput} ${actionInput}
`, styleHref, ); } export function renderSuccess( params: { resourceUri: string; resourceLabel: string; recordUri: string | null; heading: string; msg: string; returnTo?: string; }, styleHref: string, ): string { const { resourceUri, resourceLabel, recordUri, heading, msg, returnTo } = params; const escapedResourceUri = escapeHtml(resourceUri); const escapedReturnTo = returnTo ? escapeHtml(returnTo) : ""; const redirectHtml = returnTo ? `

Redirecting to ${escapedReturnTo} in ${REDIRECT_DELAY_SECONDS}\u00a0seconds\u2026

` : ""; const headExtra = returnTo ? `` : ""; return page( `

${escapeHtml(heading)}

${msg}

${redirectHtml} ${ recordUri ? `` : "" }
${escapeHtml(resourceLabel)}
Record
`, styleHref, headExtra, ); } export function renderError(message: string, styleHref: string): string { return page( `

Error

${escapeHtml(message)}

`, styleHref, ); } export function page(body: string, styleHref: string, headExtra = ""): string { return ` Sequoia ${headExtra}
${body}
`; } export function escapeHtml(text: string): string { return text .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """); }