/** * Candidate authority domains for an NSID, most specific first. * * Per AT Protocol spec the authority is every segment but the last, reversed * into a domain — app.bsky.feed.post is published at feed.bsky.app. Some * authorities only publish at the two-segment domain instead (and some serve a * wildcard that answers either), so that shorter form follows as a fallback. * Both forms are needed in practice: com.atproto.lexicon.schema resolves only * at lexicon.atproto.com, while social.grain.gallery answers at grain.social. * * @param {string} nsid - e.g., "app.bsky.feed.post" * @returns {string[]} - e.g., ["feed.bsky.app", "bsky.app"] */ export function nsidToDomains(nsid) { const parts = nsid.split('.'); const domains = [ parts.slice(0, -1).reverse().join('.'), parts.slice(0, 2).reverse().join('.'), ]; return [...new Set(domains.filter(Boolean))]; } /** * The spec-form authority domain for an NSID: every segment but the last, * reversed. See nsidToDomains for the fallback an authority may also publish at. * * @param {string} nsid - e.g., "app.bsky.feed.post" * @returns {string} - e.g., "feed.bsky.app" */ export function nsidToDomain(nsid) { return nsidToDomains(nsid)[0]; } /** * Convert domain to AT Protocol lexicon DNS lookup name. * Uses _lexicon subdomain per AT Protocol spec for lexicon authority resolution. * * @param {string} domain - e.g., "bsky.app" * @returns {string} - e.g., "_lexicon.bsky.app" */ export function domainToLexiconDns(domain) { return `_lexicon.${domain}`; }