a tool for shared writing and social publishing
at update/reader 95 lines 3.0 kB view raw
1import { AtUri } from "@atproto/syntax"; 2import { PubLeafletPublication } from "lexicons/api"; 3import { isProductionDomain } from "src/utils/isProductionDeployment"; 4import { Json } from "supabase/database.types"; 5import { 6 normalizePublicationRecord, 7 isLeafletPublication, 8 hasLeafletContent, 9 type NormalizedDocument, 10 type NormalizedPublication, 11} from "src/utils/normalizeRecords"; 12 13type PublicationInput = 14 | { uri: string; record: Json | NormalizedPublication | null } 15 | { uri: string; record: unknown }; 16 17/** 18 * Gets the public URL for a publication. 19 * Works with both pub.leaflet.publication and site.standard.publication records. 20 */ 21export function getPublicationURL(pub: PublicationInput): string { 22 const normalized = normalizePublicationRecord(pub.record); 23 24 // If we have a normalized record with a URL (site.standard format), use it 25 if (normalized?.url && isProductionDomain()) { 26 return normalized.url; 27 } 28 29 // Fall back to checking raw record for legacy base_path 30 if ( 31 isLeafletPublication(pub.record) && 32 pub.record.base_path && 33 isProductionDomain() 34 ) { 35 return `https://${pub.record.base_path}`; 36 } 37 38 return getBasePublicationURL(pub); 39} 40 41export function getBasePublicationURL(pub: PublicationInput): string { 42 const normalized = normalizePublicationRecord(pub.record); 43 const aturi = new AtUri(pub.uri); 44 45 //use rkey, fallback to name 46 const name = aturi.rkey || normalized?.name; 47 return `/lish/${aturi.host}/${encodeURIComponent(name || "")}`; 48} 49 50/** 51 * Gets the full URL for a document. 52 * Always appends the document's path property. 53 * For non-leaflet documents (content.$type !== "pub.leaflet.content"), 54 * always uses the full publication site URL, not internal /lish/ URLs. 55 */ 56export function getDocumentURL( 57 doc: NormalizedDocument, 58 docUri: string, 59 publication?: PublicationInput | NormalizedPublication | null, 60): string { 61 let path = doc.path || "/" + new AtUri(docUri).rkey; 62 if (path[0] !== "/") path = "/" + path; 63 const aturi = new AtUri(docUri); 64 65 const isNormalized = 66 !!publication && 67 (publication as NormalizedPublication).$type === 68 "site.standard.publication"; 69 const normPub = isNormalized 70 ? (publication as NormalizedPublication) 71 : publication 72 ? normalizePublicationRecord((publication as PublicationInput).record) 73 : null; 74 const pubInput = isNormalized 75 ? null 76 : (publication as PublicationInput | null); 77 78 // Non-leaflet documents always use the full publication site URL 79 if (doc.content && !hasLeafletContent(doc) && normPub?.url) { 80 return normPub.url + path; 81 } 82 83 // For leaflet documents, use getPublicationURL (may return /lish/ internal paths) 84 if (pubInput) { 85 return getPublicationURL(pubInput) + path; 86 } 87 88 // When we only have a normalized publication, use its URL directly 89 if (normPub?.url) { 90 return normPub.url + path; 91 } 92 93 // Standalone document fallback 94 return `/p/${aturi.host}${path}`; 95}