a tool for shared writing and social publishing
1/** 2 * Utilities for normalizing pub.leaflet and site.standard records from database queries. 3 * 4 * These helpers apply the normalization functions from lexicons/src/normalize.ts 5 * to database query results, providing properly typed normalized records. 6 */ 7 8import { 9 normalizeDocument, 10 normalizePublication, 11 type NormalizedDocument, 12 type NormalizedPublication, 13} from "lexicons/src/normalize"; 14import type { Json } from "supabase/database.types"; 15 16/** 17 * Normalizes a document record from a database query result. 18 * Returns the normalized document or null if the record is invalid/unrecognized. 19 * 20 * @param data - The document record data from the database 21 * @param uri - Optional document URI, used to extract the rkey for the path field when normalizing pub.leaflet records 22 * 23 * @example 24 * const doc = normalizeDocumentRecord(dbResult.data, dbResult.uri); 25 * if (doc) { 26 * // doc is NormalizedDocument with proper typing 27 * console.log(doc.title, doc.site, doc.publishedAt); 28 * } 29 */ 30export function normalizeDocumentRecord( 31 data: Json | unknown, 32 uri?: string 33): NormalizedDocument | null { 34 return normalizeDocument(data, uri); 35} 36 37/** 38 * Normalizes a publication record from a database query result. 39 * Returns the normalized publication or null if the record is invalid/unrecognized. 40 * 41 * @example 42 * const pub = normalizePublicationRecord(dbResult.record); 43 * if (pub) { 44 * // pub is NormalizedPublication with proper typing 45 * console.log(pub.name, pub.url); 46 * } 47 */ 48export function normalizePublicationRecord( 49 record: Json | unknown 50): NormalizedPublication | null { 51 return normalizePublication(record); 52} 53 54/** 55 * Type helper for a document row from the database with normalized data. 56 * Use this when you need the full row but with typed data. 57 */ 58export type DocumentRowWithNormalizedData< 59 T extends { data: Json | unknown } 60> = Omit<T, "data"> & { 61 data: NormalizedDocument | null; 62}; 63 64/** 65 * Type helper for a publication row from the database with normalized record. 66 * Use this when you need the full row but with typed record. 67 */ 68export type PublicationRowWithNormalizedRecord< 69 T extends { record: Json | unknown } 70> = Omit<T, "record"> & { 71 record: NormalizedPublication | null; 72}; 73 74/** 75 * Normalizes a document row in place, returning a properly typed row. 76 * If the row has a `uri` field, it will be used to extract the path. 77 */ 78export function normalizeDocumentRow<T extends { data: Json | unknown; uri?: string }>( 79 row: T 80): DocumentRowWithNormalizedData<T> { 81 return { 82 ...row, 83 data: normalizeDocumentRecord(row.data, row.uri), 84 }; 85} 86 87/** 88 * Normalizes a publication row in place, returning a properly typed row. 89 */ 90export function normalizePublicationRow<T extends { record: Json | unknown }>( 91 row: T 92): PublicationRowWithNormalizedRecord<T> { 93 return { 94 ...row, 95 record: normalizePublicationRecord(row.record), 96 }; 97} 98 99/** 100 * Type guard for filtering normalized document rows with non-null data. 101 * Use with .filter() after .map(normalizeDocumentRow) to narrow the type. 102 */ 103export function hasValidDocument<T extends { data: NormalizedDocument | null }>( 104 row: T 105): row is T & { data: NormalizedDocument } { 106 return row.data !== null; 107} 108 109/** 110 * Type guard for filtering normalized publication rows with non-null record. 111 * Use with .filter() after .map(normalizePublicationRow) to narrow the type. 112 */ 113export function hasValidPublication< 114 T extends { record: NormalizedPublication | null } 115>(row: T): row is T & { record: NormalizedPublication } { 116 return row.record !== null; 117} 118 119// Re-export the core types and functions for convenience 120export { 121 normalizeDocument, 122 normalizePublication, 123 type NormalizedDocument, 124 type NormalizedPublication, 125} from "lexicons/src/normalize"; 126 127export { 128 isLeafletDocument, 129 isStandardDocument, 130 isLeafletPublication, 131 isStandardPublication, 132 hasLeafletContent, 133 getDocumentPages, 134} from "lexicons/src/normalize";