@aturi.to/waypoints 0.1.2 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +253 -5
- package/dist/icons.cjs +106 -0
- package/dist/icons.cjs.map +1 -0
- package/dist/icons.d.cts +80 -0
- package/dist/icons.d.ts +80 -0
- package/dist/icons.js +73 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.cjs +411 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +265 -4
- package/dist/index.d.ts +265 -4
- package/dist/index.js +398 -10
- package/dist/index.js.map +1 -1
- package/package.json +22 -3
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/waypoints.data.ts","../src/upstreamFetch.ts","../src/uriParser.ts","../src/reverseParsers.ts","../src/resolve.ts"],"names":["identifier"],"mappings":"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","file":"index.cjs","sourcesContent":["export type WaypointType = 'post' | 'profile' | 'list' | 'record' | 'unknown';\n\n/**\n * Keys identifying which \"data family\" a waypoint belongs to for auto-redirect\n * purposes. Two waypoints can only be the endpoints of an auto-redirect when\n * they share at least one family key (i.e. they render the same underlying\n * atproto collections). Display groupings live in `WAYPOINT_CATEGORIES_DATA`\n * and are independent of this.\n */\nexport type RedirectCompatFamily =\n | 'bluesky-social'\n | 'standard-site'\n | 'tangled'\n | 'margin'\n | 'grain'\n | 'pinksky'\n | 'semble'\n | 'streamplace'\n | 'popfeed'\n | 'sifa'\n | 'blento'\n | 'atproto-explorer';\n\nexport type WaypointData = {\n id: string;\n name: string;\n description: string | ((collection?: string, type?: WaypointType) => string);\n getUrl: (handle: string, collection?: string, rkey?: string, did?: string) => string | null;\n supportedTypes: WaypointType[];\n category: string;\n /**\n * Data families this waypoint participates in. Auto-redirect rules are only\n * emitted between waypoints that share at least one family. An empty array\n * means the waypoint can never be an auto-redirect source *or* destination\n * (dev tools / generic record viewers land here by design).\n */\n redirectCompat: RedirectCompatFamily[];\n /**\n * NSID prefixes that signal this waypoint is meaningfully usable for the\n * target repo. When set, the extension can call describeRepo on the target\n * DID and check whether any of the user's collections start with one of\n * these prefixes — if none do, the waypoint is flagged as \"no records\n * found\" in the popup and demoted in smart recommendations.\n *\n * Use trailing-dot prefixes for whole namespaces (e.g. `'sh.tangled.'`)\n * or full NSIDs for single-collection apps. Atmosphere apps typically\n * declare a reversed-domain prefix (`semble.so` → `so.semble.`) so the\n * popup can flag accounts that haven't published any of that app's\n * records. Omit the field entirely for generic explorers (PDSls,\n * atp.tools, Aturi) — those stay in the \"unknown\" / no-opinion state.\n */\n expectedCollections?: string[];\n};\n\nexport type CompatFamilyMeta = {\n id: RedirectCompatFamily;\n name: string;\n description: string;\n};\n\n/**\n * Registry of compat families. `description` is shown in the options UI so the\n * user understands what each \"Favorite for X\" controls.\n */\nexport const COMPAT_FAMILIES: Record<RedirectCompatFamily, CompatFamilyMeta> = {\n 'bluesky-social': {\n id: 'bluesky-social',\n name: 'Bluesky clients',\n description: 'Apps that render bsky posts, profiles, and lists at /profile/:handle.',\n },\n 'standard-site': {\n id: 'standard-site',\n name: 'Publications',\n description: 'Readers for Standard Site and Leaflet publications.',\n },\n tangled: {\n id: 'tangled',\n name: 'Tangled',\n description: 'Tangled repositories and related records.',\n },\n margin: {\n id: 'margin',\n name: 'Margin',\n description: 'Annotations, highlights, and bookmarks on margin.at.',\n },\n grain: {\n id: 'grain',\n name: 'Grain',\n description: 'Photo galleries on grain.social.',\n },\n pinksky: {\n id: 'pinksky',\n name: 'Pinkleap',\n description: 'Pinkleap browsing experience.',\n },\n semble: {\n id: 'semble',\n name: 'Semble',\n description: 'Semble profiles.',\n },\n streamplace: {\n id: 'streamplace',\n name: 'Streamplace',\n description: 'Streamplace profiles.',\n },\n popfeed: {\n id: 'popfeed',\n name: 'Popfeed',\n description: 'Popfeed profiles.',\n },\n sifa: {\n id: 'sifa',\n name: 'Sifa',\n description: 'Sifa profiles.',\n },\n blento: {\n id: 'blento',\n name: 'Blento',\n description: 'Blento profiles.',\n },\n 'atproto-explorer': {\n id: 'atproto-explorer',\n name: 'Record explorers',\n description:\n 'Raw AT Protocol record explorers (pdsls, atp.tools, Aturi Explore) that render any record by its AT URI.',\n },\n};\n\nexport const COMPAT_FAMILY_ORDER: RedirectCompatFamily[] = [\n 'bluesky-social',\n 'standard-site',\n 'pinksky',\n 'tangled',\n 'margin',\n 'grain',\n 'semble',\n 'streamplace',\n 'popfeed',\n 'sifa',\n 'blento',\n 'atproto-explorer',\n];\n\nexport type WaypointCategoryData = {\n id: string;\n name: string;\n description?: string;\n defaultWaypointId: string;\n subcategories?: WaypointCategoryData[];\n};\n\nexport type CategorizedWaypointsData = {\n category: WaypointCategoryData;\n waypoints: WaypointData[];\n};\n\nexport const WAYPOINT_DESTINATIONS_DATA: Record<string, WaypointData> = {\n aturi: {\n id: 'aturi',\n name: 'Aturi',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on aturi.to';\n if (collection === 'app.bsky.graph.list') return 'View list on aturi.to';\n if (collection?.startsWith('site.standard.') || collection?.startsWith('pub.leaflet.')) {\n return 'View document on aturi.to';\n }\n if (collection) return 'View record on aturi.to';\n return 'View profile on aturi.to';\n },\n getUrl: (handle, collection, rkey, did) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://aturi.to/profile/${handle}/post/${rkey}`;\n }\n if (collection === 'app.bsky.graph.list') {\n return `https://aturi.to/profile/${handle}/lists/${rkey}`;\n }\n // Generic AT-record viewer; prefer the DID (stable across handle changes)\n // when one is available, falling back to the handle otherwise.\n const identifier = did || handle;\n return `https://aturi.to/profile/${identifier}/${collection}/${rkey}`;\n }\n return `https://aturi.to/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['bluesky-social', 'standard-site'],\n },\n\n anisota: {\n id: 'anisota',\n name: 'Anisota',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on anisota.net';\n if (collection === 'app.bsky.graph.list') return 'View list on anisota.net';\n if (collection?.startsWith('site.standard.') || collection?.startsWith('pub.leaflet.')) {\n return 'View document on anisota.net';\n }\n return 'View profile on anisota.net';\n },\n getUrl: (handle, collection, rkey, did) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://anisota.net/profile/${handle}/post/${rkey}`;\n }\n if (collection === 'app.bsky.graph.list') {\n return `https://anisota.net/profile/${handle}/lists/${rkey}`;\n }\n if (collection.startsWith('site.standard.') || collection.startsWith('pub.leaflet.')) {\n // Anisota's document viewer addresses records by DID when available.\n const identifier = did || handle;\n return `https://anisota.net/profile/${identifier}/document/${rkey}`;\n }\n return `https://anisota.net/profile/${handle}`;\n }\n return `https://anisota.net/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyClients',\n redirectCompat: ['bluesky-social', 'standard-site'],\n expectedCollections: ['app.bsky.', 'net.anisota.'],\n },\n\n bluesky: {\n id: 'bluesky',\n name: 'Bluesky',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on bsky.app';\n if (collection === 'app.bsky.graph.list') return 'View list on bsky.app';\n return 'View profile on bsky.app';\n },\n getUrl: (handle, collection, rkey) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://bsky.app/profile/${handle}/post/${rkey}`;\n }\n return `https://bsky.app/profile/${handle}`;\n }\n return `https://bsky.app/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyClients',\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n blacksky: {\n id: 'blacksky',\n name: 'Blacksky',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on blacksky.community';\n if (collection === 'app.bsky.graph.list') return 'View list on blacksky.community';\n return 'View profile on blacksky.community';\n },\n getUrl: (handle, collection, rkey) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://blacksky.community/profile/${handle}/post/${rkey}`;\n }\n return `https://blacksky.community/profile/${handle}`;\n }\n return `https://blacksky.community/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyForks',\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n reddwarf: {\n id: 'reddwarf',\n name: 'Red Dwarf',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on reddwarf.app';\n if (collection === 'app.bsky.graph.list') return 'View list on reddwarf.app';\n return 'View profile on reddwarf.app';\n },\n getUrl: (handle, collection, rkey) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://reddwarf.app/profile/${handle}/post/${rkey}`;\n }\n return `https://reddwarf.app/profile/${handle}`;\n }\n return `https://reddwarf.app/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyClients',\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n impro: {\n id: 'impro',\n name: 'Impro',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on impro.social';\n if (collection === 'app.bsky.graph.list') return 'View list on impro.social';\n return 'View profile on impro.social';\n },\n getUrl: (handle, collection, rkey) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://impro.social/profile/${handle}/post/${rkey}`;\n }\n if (collection === 'app.bsky.graph.list') {\n return `https://impro.social/profile/${handle}/lists/${rkey}`;\n }\n return `https://impro.social/profile/${handle}`;\n }\n return `https://impro.social/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyClients',\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n leaflet: {\n id: 'leaflet',\n name: 'Leaflet',\n description: 'View profile on leaflet.pub',\n getUrl: (handle) => {\n return `https://leaflet.pub/p/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'publications',\n redirectCompat: ['standard-site'],\n expectedCollections: ['pub.leaflet.', 'site.standard.'],\n },\n\n pdsls: {\n id: 'pdsls',\n name: 'PDSls',\n description: 'View raw record on pdsls.dev',\n getUrl: (handle, collection, rkey, did) => {\n const identifier = did || handle;\n if (collection && rkey) {\n return `https://pdsls.dev/at://${identifier}/${collection}/${rkey}`;\n }\n return `https://pdsls.dev/at://${identifier}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'devTools',\n redirectCompat: ['atproto-explorer'],\n },\n\n aturiExplore: {\n id: 'aturiExplore',\n name: 'Aturi Explore',\n description: (collection) => {\n if (collection) return 'Inspect record on aturi.to/explore';\n return 'Browse repo on aturi.to/explore';\n },\n getUrl: (handle, collection, rkey, did) => {\n // The explorer keys URLs by DID when available so handle changes don't\n // break shared links. Falls back to the handle when no DID was passed.\n const identifier = did || handle;\n if (collection && rkey) {\n return `https://aturi.to/explore/${identifier}/${collection}/${encodeURIComponent(rkey)}`;\n }\n if (collection) {\n return `https://aturi.to/explore/${identifier}/${collection}`;\n }\n return `https://aturi.to/explore/${identifier}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'devTools',\n redirectCompat: ['atproto-explorer'],\n },\n\n atptools: {\n id: 'atptools',\n name: 'atp.tools',\n description: 'View raw record on atp.tools',\n getUrl: (handle, collection, rkey, did) => {\n const identifier = did || handle;\n if (collection && rkey) {\n return `https://atp.tools/at:/${identifier}/${collection}/${rkey}`;\n }\n return `https://atp.tools/at:/${identifier}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'devTools',\n redirectCompat: ['atproto-explorer'],\n },\n\n bluepy: {\n id: 'bluepy',\n name: 'Bluepy',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on bluepy.social';\n if (collection === 'app.bsky.graph.list') return 'View list on bluepy.social';\n if (collection) return 'View record on bluepy.social';\n return 'View profile on bluepy.social';\n },\n getUrl: (handle, collection, rkey, did) => {\n const identifier = did || handle;\n if (collection && rkey) {\n return `https://bluepy.social/at://${identifier}/${collection}/${rkey}`;\n }\n return `https://bluepy.social/at://${identifier}/app.bsky.actor.profile/self`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyClients',\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n witchsky: {\n id: 'witchsky',\n name: 'Witchsky',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on witchsky.app';\n if (collection === 'app.bsky.graph.list') return 'View list on witchsky.app';\n return 'View profile on witchsky.app';\n },\n getUrl: (handle, collection, rkey) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://witchsky.app/profile/${handle}/post/${rkey}`;\n }\n return `https://witchsky.app/profile/${handle}`;\n }\n return `https://witchsky.app/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyForks',\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n deer: {\n id: 'deer',\n name: 'Deer',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on deer.social';\n if (collection === 'app.bsky.graph.list') return 'View list on deer.social';\n return 'View profile on deer.social';\n },\n getUrl: (handle, collection, rkey) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://deer.social/profile/${handle}/post/${rkey}`;\n }\n return `https://deer.social/profile/${handle}`;\n }\n return `https://deer.social/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyForks',\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n mu: {\n id: 'mu',\n name: 'Mu',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on mu.social';\n if (collection === 'app.bsky.graph.list') return 'View list on mu.social';\n return 'View profile on mu.social';\n },\n getUrl: (handle, collection, rkey) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://mu.social/profile/${handle}/post/${rkey}`;\n }\n return `https://mu.social/profile/${handle}`;\n }\n return `https://mu.social/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyForks',\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n tangled: {\n id: 'tangled',\n name: 'Tangled',\n description: 'View profile on tangled.org',\n getUrl: (handle) => {\n return `https://tangled.org/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['tangled'],\n expectedCollections: ['sh.tangled.'],\n },\n\n\n pinksky: {\n id: 'pinksky',\n name: 'Pinkleap',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on pinkleap.app';\n return 'View profile on pinkleap.app';\n },\n getUrl: (handle, collection, rkey, did) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n const identifier = did || handle;\n const atUri = `at://${identifier}/${collection}/${rkey}`;\n const encodedUri = encodeURIComponent(atUri);\n const encodedDid = encodeURIComponent(identifier);\n return `https://pinkleap.app/feed?uri=${encodedUri}&src=profile&index=1&did=${encodedDid}&showThreads=${encodedDid}`;\n }\n return `https://pinkleap.app/profile/${handle}`;\n }\n return `https://pinkleap.app/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['pinksky'],\n expectedCollections: ['app.bsky.'],\n },\n\n margin: {\n id: 'margin',\n name: 'Margin',\n description: (collection) => {\n if (collection === 'at.margin.annotation') return 'View annotation on margin.at';\n if (collection === 'at.margin.highlight') return 'View highlight on margin.at';\n if (collection === 'at.margin.bookmark') return 'View bookmark on margin.at';\n if (collection?.startsWith('at.margin.')) return 'View on margin.at';\n return 'View profile on margin.at';\n },\n getUrl: (handle, collection, rkey, did) => {\n if (collection && rkey && collection.startsWith('at.margin.')) {\n const recordType = collection.replace('at.margin.', '');\n const identifier = did || handle;\n\n if (recordType === 'annotation' || recordType === 'highlight' || recordType === 'bookmark') {\n const handleLooksLikeDomain = handle.includes('.') && !handle.startsWith('did:');\n const domain = handleLooksLikeDomain ? handle : identifier;\n\n return `https://margin.at/${domain}/${recordType}/${rkey}`;\n }\n\n return `https://margin.at/profile/${identifier}`;\n }\n\n const identifier = did || handle;\n return `https://margin.at/profile/${identifier}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['margin'],\n expectedCollections: ['at.margin.'],\n },\n\n semble: {\n id: 'semble',\n name: 'Semble',\n description: 'View profile on semble.so',\n getUrl: (handle) => {\n return `https://semble.so/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['semble'],\n expectedCollections: ['so.semble.'],\n },\n\n streamplace: {\n id: 'streamplace',\n name: 'Streamplace',\n description: 'View profile on stream.place',\n getUrl: (handle) => {\n return `https://stream.place/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['streamplace'],\n expectedCollections: ['place.stream.'],\n },\n\n grain: {\n id: 'grain',\n name: 'Grain',\n description: (collection) => {\n if (collection === 'social.grain.gallery') return 'View gallery on grain.social';\n return 'View profile on grain.social';\n },\n getUrl: (handle, collection, rkey, did) => {\n const identifier = did || handle;\n if (collection === 'social.grain.gallery' && rkey) {\n return `https://grain.social/profile/${identifier}/gallery/${rkey}`;\n }\n return `https://grain.social/profile/${identifier}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['grain'],\n expectedCollections: ['social.grain.'],\n },\n\n popfeed: {\n id: 'popfeed',\n name: 'Popfeed',\n description: 'View profile on popfeed.social',\n getUrl: (handle, collection, rkey, did) => {\n const identifier = did || handle;\n return `https://popfeed.social/profile/${identifier}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['popfeed'],\n expectedCollections: ['social.popfeed.'],\n },\n\n sifa: {\n id: 'sifa',\n name: 'Sifa',\n description: 'View profile on sifa.id',\n getUrl: (handle) => {\n return `https://sifa.id/p/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['sifa'],\n expectedCollections: ['id.sifa.'],\n },\n\n blento: {\n id: 'blento',\n name: 'Blento',\n description: 'View profile on blento.app',\n getUrl: (handle) => {\n return `https://blento.app/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['blento'],\n expectedCollections: ['app.blento.'],\n },\n\n anisotaReader: {\n id: 'anisotaReader',\n name: 'Anisota Reader',\n description: (collection) => {\n if (collection?.startsWith('site.standard.') || collection?.startsWith('pub.leaflet.')) {\n return 'Read document on anisota.net';\n }\n return 'View publications on anisota.net';\n },\n getUrl: (handle, collection, rkey, did) => {\n if (collection && rkey) {\n if (collection.startsWith('site.standard.') || collection.startsWith('pub.leaflet.')) {\n const identifier = did || handle;\n return `https://anisota.net/profile/${identifier}/document/${rkey}`;\n }\n }\n return `https://anisota.net/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'publications',\n redirectCompat: ['standard-site'],\n expectedCollections: ['pub.leaflet.', 'site.standard.'],\n },\n\n offprint: {\n id: 'offprint',\n name: 'Offprint',\n description: (collection) => {\n if (collection?.startsWith('site.standard.') || collection?.startsWith('pub.leaflet.')) {\n return 'Read document on offprint.app';\n }\n return 'View on offprint.app';\n },\n getUrl: (handle, collection, rkey, did) => {\n // offprint only has record-level URLs; without a collection+rkey there's\n // no meaningful destination, so hide the waypoint in profile-only views.\n if (!collection || !rkey) return null;\n const identifier = did || handle;\n return `https://offprint.app/${identifier}/${collection}/${rkey}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'publications',\n redirectCompat: ['standard-site'],\n expectedCollections: ['pub.leaflet.', 'site.standard.'],\n },\n\n pckt: {\n id: 'pckt',\n name: 'pckt',\n description: (collection) => {\n if (collection?.startsWith('site.standard.') || collection?.startsWith('pub.leaflet.')) {\n return 'Read document on pckt.blog';\n }\n return 'View on pckt.blog';\n },\n getUrl: (handle, collection, rkey, did) => {\n // pckt only has record-level URLs; without a collection+rkey there's no\n // meaningful destination, so hide the waypoint in profile-only views.\n if (!collection || !rkey) return null;\n const identifier = did || handle;\n return `https://pckt.blog/${identifier}/${collection}/${rkey}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'publications',\n redirectCompat: ['standard-site'],\n expectedCollections: ['pub.leaflet.', 'site.standard.'],\n },\n\n standardReader: {\n id: 'standardReader',\n name: 'Standard Reader',\n description: (collection) => {\n if (collection?.startsWith('site.standard.') || collection?.startsWith('pub.leaflet.')) {\n return 'Read document on standard-reader.app';\n }\n return 'View documents on standard-reader.app';\n },\n getUrl: (handle, collection, rkey, did) => {\n const identifier = did || handle;\n if (\n collection &&\n rkey &&\n (collection.startsWith('site.standard.') || collection.startsWith('pub.leaflet.'))\n ) {\n return `https://standard-reader.app/a/${identifier}/${rkey}`;\n }\n return `https://standard-reader.app/u/${identifier}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'publications',\n redirectCompat: ['standard-site'],\n expectedCollections: ['pub.leaflet.', 'site.standard.'],\n },\n\n taproot: {\n id: 'taproot',\n name: 'Taproot',\n description: (collection) => {\n if (collection) return 'Inspect record on atproto.at';\n return 'Browse repo on atproto.at';\n },\n getUrl: (handle, collection, rkey, did) => {\n const identifier = did || handle;\n if (collection && rkey) {\n return `https://atproto.at/uri/at://${identifier}/${collection}/${rkey}`;\n }\n return `https://atproto.at/uri/at://${identifier}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'devTools',\n redirectCompat: [],\n },\n};\n\nexport const WAYPOINT_ORDER = [\n 'anisota',\n 'bluesky',\n 'bluepy',\n 'reddwarf',\n 'impro',\n 'blacksky',\n 'leaflet',\n 'aturi',\n 'pinksky',\n 'margin',\n 'semble',\n 'streamplace',\n 'grain',\n 'popfeed',\n 'sifa',\n 'blento',\n 'anisotaReader',\n 'offprint',\n 'pckt',\n 'standardReader',\n 'aturiExplore',\n 'pdsls',\n 'tangled',\n 'atptools',\n 'taproot',\n 'witchsky',\n 'mu',\n 'deer',\n];\n\nexport function getWaypointDataForType(type: WaypointType): WaypointData[] {\n return WAYPOINT_ORDER\n .map(id => WAYPOINT_DESTINATIONS_DATA[id])\n .filter(waypoint => waypoint.supportedTypes.includes(type));\n}\n\nexport function getWaypointCountData(): number {\n return WAYPOINT_ORDER.length;\n}\n\nexport const WAYPOINT_CATEGORIES_DATA: Record<string, WaypointCategoryData> = {\n blueskyClients: {\n id: 'blueskyClients',\n name: 'Bluesky Clients',\n description: 'Official and alternative Bluesky clients',\n defaultWaypointId: 'bluesky',\n subcategories: [{\n id: 'blueskyForks',\n name: 'Bluesky Forks',\n description: 'Community-built Bluesky variants',\n defaultWaypointId: 'blacksky',\n }],\n },\n blueskyForks: {\n id: 'blueskyForks',\n name: 'Bluesky Forks',\n description: 'Community-built Bluesky variants',\n defaultWaypointId: 'blacksky',\n },\n publications: {\n id: 'publications',\n name: 'Publications',\n description: 'Readers for Standard Site and Leaflet publications',\n defaultWaypointId: 'leaflet',\n },\n atmosphereApps: {\n id: 'atmosphereApps',\n name: 'Atmosphere',\n description: 'Apps built on the AT Protocol',\n defaultWaypointId: 'tangled',\n },\n devTools: {\n id: 'devTools',\n name: 'Dev Tools',\n description: 'Tools for developers and debugging',\n defaultWaypointId: 'aturiExplore',\n },\n};\n\nexport const CATEGORY_ORDER = [\n 'blueskyClients',\n 'blueskyForks',\n 'publications',\n 'atmosphereApps',\n 'devTools',\n];\n\nexport function getCategorizedWaypointsData(type: WaypointType): CategorizedWaypointsData[] {\n const availableWaypoints = getWaypointDataForType(type);\n const categorized: CategorizedWaypointsData[] = [];\n\n // Categories that are declared as subcategories of another category should\n // not also appear as standalone top-level categories. Their waypoints will\n // be rendered nested under their parent by the picker.\n const subcategoryIds = new Set<string>();\n for (const category of Object.values(WAYPOINT_CATEGORIES_DATA)) {\n for (const subcat of category.subcategories ?? []) {\n subcategoryIds.add(subcat.id);\n }\n }\n\n for (const categoryId of CATEGORY_ORDER) {\n if (subcategoryIds.has(categoryId)) continue;\n\n const category = WAYPOINT_CATEGORIES_DATA[categoryId];\n const waypoints = availableWaypoints.filter(w => w.category === categoryId);\n\n if (waypoints.length > 0) {\n categorized.push({ category, waypoints });\n }\n }\n\n return categorized;\n}\n\ntype RecommendedConfig = {\n waypointIds: string[];\n label?: string;\n};\n\nconst RECOMMENDED_WAYPOINTS: Record<string, RecommendedConfig> = {\n 'app.bsky.feed.post': {\n waypointIds: ['bluesky', 'anisota', 'blacksky'],\n label: 'Recommended for Posts',\n },\n 'profile': {\n waypointIds: ['bluesky', 'anisota'],\n label: 'Recommended for Profiles',\n },\n 'app.bsky.graph.list': {\n waypointIds: ['bluesky', 'anisota'],\n label: 'Recommended for Lists',\n },\n 'community.lexicon.calendar.event': {\n waypointIds: ['aturiExplore', 'pdsls', 'atptools'],\n label: 'Recommended for Events',\n },\n 'sh.tangled.repo': {\n waypointIds: ['tangled'],\n label: 'Recommended for Repos',\n },\n 'record': {\n waypointIds: ['aturiExplore', 'pdsls', 'atptools', 'taproot'],\n label: 'Recommended for Records',\n },\n};\n\n/**\n * Recommendations keyed by collection NSID prefix. When a collection is checked,\n * we walk its dotted segments from longest to shortest looking for a registered\n * prefix (e.g. `standard.site.blog.entry` matches `standard.site`). Use this for\n * apps/lexicons that own a whole namespace and have a consistent set of compatible\n * waypoints across all of their record types.\n */\nconst RECOMMENDED_NAMESPACE_PREFIXES: Record<string, RecommendedConfig> = {\n 'site.standard': {\n waypointIds: ['leaflet', 'standardReader', 'anisotaReader', 'offprint', 'pckt', 'pdsls'],\n label: 'Recommended for Publications',\n },\n 'pub.leaflet': {\n waypointIds: ['leaflet', 'anisotaReader', 'offprint', 'pckt', 'pdsls'],\n label: 'Recommended for Publications',\n },\n 'sh.tangled': {\n waypointIds: ['tangled', 'pdsls', 'atptools'],\n label: 'Recommended for Tangled',\n },\n 'at.margin': {\n waypointIds: ['margin', 'pdsls', 'atptools'],\n label: 'Recommended for Margin',\n },\n 'social.grain': {\n waypointIds: ['grain', 'pdsls', 'atptools'],\n label: 'Recommended for Grain',\n },\n};\n\nfunction findNamespacePrefixMatch(collection: string): RecommendedConfig | undefined {\n const segments = collection.split('.');\n for (let i = segments.length - 1; i >= 2; i--) {\n const prefix = segments.slice(0, i).join('.');\n if (RECOMMENDED_NAMESPACE_PREFIXES[prefix]) {\n return RECOMMENDED_NAMESPACE_PREFIXES[prefix];\n }\n }\n return undefined;\n}\n\nexport function getRecommendedWaypointsData(\n type: WaypointType,\n collection?: string\n): { waypoints: WaypointData[]; label: string } {\n let config: RecommendedConfig | undefined;\n\n if (collection && RECOMMENDED_WAYPOINTS[collection]) {\n config = RECOMMENDED_WAYPOINTS[collection];\n } else if (collection) {\n config = findNamespacePrefixMatch(collection);\n }\n\n if (!config && RECOMMENDED_WAYPOINTS[type]) {\n config = RECOMMENDED_WAYPOINTS[type];\n }\n\n if (!config) {\n config = {\n waypointIds: ['bluesky'],\n label: 'Recommended',\n };\n }\n\n const waypoints = config.waypointIds\n .map(id => WAYPOINT_DESTINATIONS_DATA[id])\n .filter(Boolean);\n\n return {\n waypoints,\n label: config.label || 'Recommended',\n };\n}\n\nexport function getFeaturedWaypointData(\n type: WaypointType,\n collection?: string\n): WaypointData | null {\n const { waypoints } = getRecommendedWaypointsData(type, collection);\n return waypoints[0] || null;\n}\n\n/**\n * Result of comparing a waypoint's `expectedCollections` against the set of\n * NSIDs found in the target repo.\n *\n * - 'present' — the user has at least one record under a matching prefix.\n * - 'absent' — the waypoint declared collections but none are in the repo.\n * - 'unknown' — the waypoint didn't declare any expectations, or we\n * haven't scanned the repo yet (e.g. scan disabled, no DID).\n */\nexport type WaypointActivity = 'present' | 'absent' | 'unknown';\n\n/**\n * Classify a waypoint against the set of collection NSIDs known to exist on\n * the target repo. Prefix-matches each entry in `expectedCollections` against\n * `repoCollections`. Returns 'unknown' when the waypoint has no declared\n * expectations or the caller passed `null` for `repoCollections` (i.e. scan\n * disabled or still in flight).\n */\nexport function waypointActivity(\n waypoint: Pick<WaypointData, 'expectedCollections'>,\n repoCollections: ReadonlySet<string> | null,\n): WaypointActivity {\n if (!repoCollections) return 'unknown';\n const expected = waypoint.expectedCollections;\n if (!expected || expected.length === 0) return 'unknown';\n for (const c of repoCollections) {\n for (const prefix of expected) {\n if (c === prefix || c.startsWith(prefix)) return 'present';\n }\n }\n return 'absent';\n}\n","/**\n * Shared fetch wrapper for upstream atproto services (appview, PLC\n * directory, PDS hosts).\n *\n * Every server-rendered page ultimately funnels through these upstream\n * calls, so two failure modes matter in production:\n *\n * - A hung TCP connection with no timeout keeps the whole function alive\n * until the platform kills it (observed as 300s Vercel timeouts).\n * - Transient socket resets (ECONNRESET against public.api.bsky.app) fail\n * requests that would succeed on an immediate retry.\n *\n * This wrapper bounds every request with AbortSignal.timeout and retries\n * once on network-level failures (never on HTTP error statuses, which are\n * meaningful responses). Works in Node, edge, and browser runtimes — the\n * extension imports sibling modules from this directory.\n */\n\nexport type UpstreamFetchOptions = RequestInit & {\n /** Per-attempt timeout in milliseconds. Defaults to 8000. */\n timeoutMs?: number;\n /** Extra attempts after a network-level failure. Defaults to 1. */\n retries?: number;\n};\n\nconst RETRY_DELAY_MS = 250;\n\nexport async function upstreamFetch(\n url: string,\n { timeoutMs = 8000, retries = 1, ...init }: UpstreamFetchOptions = {}\n): Promise<Response> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n return await fetch(url, {\n ...init,\n signal: AbortSignal.timeout(timeoutMs),\n });\n } catch (error) {\n lastError = error;\n if (attempt < retries) {\n await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY_MS));\n }\n }\n }\n\n throw lastError;\n}\n\n/**\n * Log an upstream HTTP error at the right level: 4xx responses are almost\n * always caused by user-supplied input (a bad handle or rkey in a shared\n * link) and are expected, so they log as warnings; 5xx and everything else\n * logs as an error. Keeps the production error dashboard signal-rich.\n */\nexport function logUpstreamHttpError(context: string, response: Response): void {\n if (response.status >= 400 && response.status < 500) {\n console.warn(`${context}: HTTP ${response.status} (expected for bad input)`);\n } else {\n console.error(`${context}: HTTP ${response.status}`);\n }\n}\n","import { upstreamFetch } from './upstreamFetch';\n\nexport type ParsedURI = {\n type: 'post' | 'profile' | 'list' | 'record' | 'unknown';\n uri: string;\n handle: string;\n did?: string;\n collection?: string;\n rkey?: string;\n error?: string;\n};\n\n/**\n * Parse URL path segments into structured AT URI data\n * Examples:\n * - /alice.bsky.social -> profile\n * - /alice.bsky.social/app.bsky.feed.post/3k7qw... -> post\n * - /did:plc:xxx/app.bsky.graph.list/abc -> list\n */\nexport function parseURI(handle: string, collection?: string, rkey?: string): ParsedURI {\n // Handle is required\n if (!handle) {\n return {\n type: 'unknown',\n uri: '',\n handle: '',\n error: 'Handle or DID is required',\n };\n }\n\n // Profile case (no collection/rkey)\n if (!collection && !rkey) {\n return {\n type: 'profile',\n uri: `at://${handle}`,\n handle,\n did: handle.startsWith('did:') ? handle : undefined,\n };\n }\n\n // Record case (has collection and rkey)\n if (collection && rkey) {\n let type: 'post' | 'list' | 'record' = 'record';\n \n if (collection === 'app.bsky.feed.post') {\n type = 'post';\n } else if (collection === 'app.bsky.graph.list') {\n type = 'list';\n }\n // All other collections are treated as generic records\n\n return {\n type,\n uri: `at://${handle}/${collection}/${rkey}`,\n handle,\n did: handle.startsWith('did:') ? handle : undefined,\n collection,\n rkey,\n };\n }\n\n // Invalid case\n return {\n type: 'unknown',\n uri: '',\n handle,\n error: 'Invalid URI structure',\n };\n}\n\n/**\n * Resolve a handle to a DID using the Bluesky API\n */\n/**\n * Handle resolution that distinguishes a definitive \"no such handle\" from a\n * transient \"resolver unavailable\". Callers that need to decide between a real\n * 404 and a retry state use this; `resolveHandle` remains for the common\n * did-or-null case.\n *\n * - `not-found`: the appview returned a 4xx (invalid/unknown handle). Safe to\n * surface as a 404.\n * - `unavailable`: network failure or 5xx. Must NOT be shown as a 404 — it's a\n * real account we couldn't look up right now.\n */\nexport type HandleResolution =\n | { did: string; reason?: undefined }\n | { did: null; reason: 'not-found' | 'unavailable' };\n\nexport async function resolveHandleStatus(handle: string): Promise<HandleResolution> {\n if (handle.startsWith('did:')) {\n return { did: handle };\n }\n\n try {\n const apiUrl = process.env.NEXT_PUBLIC_BSKY_API_URL || 'https://public.api.bsky.app';\n const response = await upstreamFetch(\n `${apiUrl}/xrpc/com.atproto.identity.resolveHandle?handle=${encodeURIComponent(handle)}`\n );\n\n if (!response.ok) {\n return { did: null, reason: response.status >= 500 ? 'unavailable' : 'not-found' };\n }\n\n const data = await response.json();\n if (data.did) return { did: data.did };\n return { did: null, reason: 'not-found' };\n } catch (error) {\n console.error('Error resolving handle:', error);\n return { did: null, reason: 'unavailable' };\n }\n}\n\nexport async function resolveHandle(handle: string): Promise<string | null> {\n return (await resolveHandleStatus(handle)).did;\n}\n\n/**\n * Get display name from handle or DID\n */\nexport function getDisplayName(handle: string, did?: string): string {\n if (handle.startsWith('did:')) {\n return did ? `@${did.slice(0, 16)}...` : 'Unknown';\n }\n return `@${handle}`;\n}\n\n\n","import type { ParsedURI } from './uriParser';\n\nexport type SourceApp =\n | 'aturi'\n | 'aturiExplore'\n | 'bluesky'\n | 'bluepy'\n | 'blacksky'\n | 'reddwarf'\n | 'impro'\n | 'witchsky'\n | 'deer'\n | 'mu'\n | 'anisota'\n | 'pinksky'\n | 'leaflet'\n | 'tangled'\n | 'margin'\n | 'pdsls'\n | 'atptools'\n | 'semble'\n | 'streamplace'\n | 'grain'\n | 'popfeed'\n | 'sifa'\n | 'blento'\n | 'standardReader'\n | 'taproot'\n | 'offprint'\n | 'pckt'\n | 'headDetected';\n\nexport type ReverseMatch = {\n source: SourceApp;\n parsed: ParsedURI;\n};\n\ntype HostConfig = {\n source: SourceApp;\n hosts: string[];\n /**\n * When true, any subdomain of the listed hosts is treated as this source\n * too (e.g. Anisota gives each publication its own `*.anisota.net` host).\n */\n matchSubdomains?: boolean;\n};\n\n/**\n * Hosts that share the Bluesky-style `/profile/:handle[/(post|lists)/:rkey]` layout.\n */\nconst BLUESKY_FAMILY: HostConfig[] = [\n { source: 'bluesky', hosts: ['bsky.app'] },\n { source: 'blacksky', hosts: ['blacksky.community'] },\n { source: 'reddwarf', hosts: ['reddwarf.app'] },\n { source: 'impro', hosts: ['impro.social'] },\n { source: 'witchsky', hosts: ['witchsky.app'] },\n { source: 'deer', hosts: ['deer.social'] },\n { source: 'mu', hosts: ['mu.social'] },\n { source: 'anisota', hosts: ['anisota.net'], matchSubdomains: true },\n];\n\n/**\n * Base hosts whose subdomains are also recognized (e.g. `*.anisota.net`).\n * Derived from the `matchSubdomains` opt-in so there's one source of truth.\n */\nconst SUBDOMAIN_HOSTS: string[] = BLUESKY_FAMILY.filter(f => f.matchSubdomains).flatMap(\n f => f.hosts,\n);\n\nfunction normalizeHost(host: string): string {\n return host.toLowerCase().replace(/^www\\./, '');\n}\n\n/** True when `host` is a subdomain of `base` (a real dotted-label boundary). */\nfunction isSubdomainOf(host: string, base: string): boolean {\n return host.endsWith(`.${base}`);\n}\n\n/** Exact host match, or a subdomain match when the config opts in. */\nfunction hostMatchesConfig(host: string, config: HostConfig): boolean {\n if (config.hosts.includes(host)) return true;\n if (!config.matchSubdomains) return false;\n return config.hosts.some(h => isSubdomainOf(host, h));\n}\n\nfunction matchBlueskyFamily(host: string, parts: string[]): ReverseMatch | null {\n const entry = BLUESKY_FAMILY.find(f => hostMatchesConfig(host, f));\n if (!entry) return null;\n\n if (parts[0] !== 'profile' || !parts[1]) return null;\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n\n if (!parts[2]) {\n return {\n source: entry.source,\n parsed: {\n type: 'profile',\n uri: `at://${handle}`,\n handle,\n did,\n },\n };\n }\n\n if (parts[2] === 'post' && parts[3]) {\n return {\n source: entry.source,\n parsed: {\n type: 'post',\n uri: `at://${handle}/app.bsky.feed.post/${parts[3]}`,\n handle,\n did,\n collection: 'app.bsky.feed.post',\n rkey: parts[3],\n },\n };\n }\n\n if ((parts[2] === 'lists' || parts[2] === 'list') && parts[3]) {\n return {\n source: entry.source,\n parsed: {\n type: 'list',\n uri: `at://${handle}/app.bsky.graph.list/${parts[3]}`,\n handle,\n did,\n collection: 'app.bsky.graph.list',\n rkey: parts[3],\n },\n };\n }\n\n // Anisota's reader addresses Standard Site / Leaflet documents at\n // `/profile/:handle/document/:rkey` without the collection NSID in the URL.\n // Mirror Standard Reader's convention and reconstruct the canonical\n // `site.standard.document` collection so the record still resolves.\n if (parts[2] === 'document' && parts[3]) {\n return {\n source: entry.source,\n parsed: {\n type: 'record',\n uri: `at://${handle}/site.standard.document/${parts[3]}`,\n handle,\n did,\n collection: 'site.standard.document',\n rkey: parts[3],\n },\n };\n }\n\n return {\n source: entry.source,\n parsed: {\n type: 'profile',\n uri: `at://${handle}`,\n handle,\n did,\n },\n };\n}\n\nfunction inferType(collection: string): 'post' | 'list' | 'record' {\n if (collection === 'app.bsky.feed.post') return 'post';\n if (collection === 'app.bsky.graph.list') return 'list';\n return 'record';\n}\n\nfunction matchPinksky(host: string, parts: string[], search: URLSearchParams): ReverseMatch | null {\n if (host !== 'pinkleap.app') return null;\n\n if (parts[0] === 'feed') {\n const uri = search.get('uri');\n if (uri && uri.startsWith('at://')) {\n const stripped = uri.slice('at://'.length);\n const [handle, collection, rkey] = stripped.split('/');\n if (handle) {\n const did = handle.startsWith('did:') ? handle : undefined;\n if (collection && rkey) {\n return {\n source: 'pinksky',\n parsed: {\n type: inferType(collection),\n uri,\n handle,\n did,\n collection,\n rkey,\n },\n };\n }\n return {\n source: 'pinksky',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n }\n }\n }\n\n if (parts[0] === 'profile' && parts[1]) {\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'pinksky',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n }\n\n return null;\n}\n\nfunction matchLeaflet(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'leaflet.pub') return null;\n if (parts[0] !== 'p' || !parts[1]) return null;\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'leaflet',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchTangled(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'tangled.org') return null;\n if (!parts[0]) return null;\n const handle = parts[0];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'tangled',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchMargin(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'margin.at') return null;\n\n if (parts[0] === 'profile' && parts[1]) {\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'margin',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n }\n\n if (parts[0] && parts[1] && parts[2]) {\n const recordType = parts[1];\n if (recordType === 'annotation' || recordType === 'highlight' || recordType === 'bookmark') {\n const handle = parts[0];\n const did = handle.startsWith('did:') ? handle : undefined;\n const collection = `at.margin.${recordType}`;\n const rkey = parts[2];\n return {\n source: 'margin',\n parsed: {\n type: 'record',\n uri: `at://${handle}/${collection}/${rkey}`,\n handle,\n did,\n collection,\n rkey,\n },\n };\n }\n }\n\n return null;\n}\n\n/**\n * Parse a path segment of the form `at://identifier[/collection/rkey]` or\n * `at:/identifier[/collection/rkey]` used by pdsls.dev and atp.tools.\n *\n * The leading `at://` or `at:/` is collapsed by the URL parser so the raw\n * `pathname` exposes it as `/at:/identifier/...`. We accept both forms.\n */\nfunction parseAtUriPath(pathname: string): {\n handle: string;\n collection?: string;\n rkey?: string;\n} | null {\n const cleaned = pathname.replace(/^\\/+/, '');\n const match = cleaned.match(/^at:\\/{1,2}(.+)$/);\n if (!match) return null;\n const rest = match[1];\n const segments = rest.split('/').filter(Boolean);\n if (segments.length === 0) return null;\n return {\n handle: segments[0],\n collection: segments[1],\n rkey: segments[2],\n };\n}\n\nfunction matchPdsls(host: string, pathname: string): ReverseMatch | null {\n if (host !== 'pdsls.dev') return null;\n const atUri = parseAtUriPath(pathname);\n if (!atUri) return null;\n const { handle, collection, rkey } = atUri;\n const did = handle.startsWith('did:') ? handle : undefined;\n\n if (collection && rkey) {\n return {\n source: 'pdsls',\n parsed: {\n type: inferType(collection),\n uri: `at://${handle}/${collection}/${rkey}`,\n handle,\n did,\n collection,\n rkey,\n },\n };\n }\n\n return {\n source: 'pdsls',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchAtpTools(host: string, pathname: string): ReverseMatch | null {\n if (host !== 'atp.tools') return null;\n const atUri = parseAtUriPath(pathname);\n if (!atUri) return null;\n const { handle, collection, rkey } = atUri;\n const did = handle.startsWith('did:') ? handle : undefined;\n\n if (collection && rkey) {\n return {\n source: 'atptools',\n parsed: {\n type: inferType(collection),\n uri: `at://${handle}/${collection}/${rkey}`,\n handle,\n did,\n collection,\n rkey,\n },\n };\n }\n\n return {\n source: 'atptools',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchBluepy(host: string, pathname: string): ReverseMatch | null {\n if (host !== 'bluepy.social') return null;\n const atUri = parseAtUriPath(pathname);\n if (!atUri) return null;\n const { handle, collection, rkey } = atUri;\n const did = handle.startsWith('did:') ? handle : undefined;\n\n if (collection === 'app.bsky.actor.profile') {\n return {\n source: 'bluepy',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n }\n\n if (collection && rkey) {\n return {\n source: 'bluepy',\n parsed: {\n type: inferType(collection),\n uri: `at://${handle}/${collection}/${rkey}`,\n handle,\n did,\n collection,\n rkey,\n },\n };\n }\n\n return {\n source: 'bluepy',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchSemble(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'semble.so') return null;\n if (parts[0] !== 'profile' || !parts[1]) return null;\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'semble',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchStreamplace(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'stream.place') return null;\n if (!parts[0]) return null;\n const handle = parts[0];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'streamplace',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchGrain(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'grain.social') return null;\n if (parts[0] !== 'profile' || !parts[1]) return null;\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n\n if (parts[2] === 'gallery' && parts[3]) {\n return {\n source: 'grain',\n parsed: {\n type: 'record',\n uri: `at://${handle}/social.grain.gallery/${parts[3]}`,\n handle,\n did,\n collection: 'social.grain.gallery',\n rkey: parts[3],\n },\n };\n }\n\n return {\n source: 'grain',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchPopfeed(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'popfeed.social') return null;\n if (parts[0] !== 'profile' || !parts[1]) return null;\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'popfeed',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchSifa(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'sifa.id') return null;\n if (parts[0] !== 'p' || !parts[1]) return null;\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'sifa',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchBlento(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'blento.app') return null;\n if (!parts[0]) return null;\n const handle = parts[0];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'blento',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\n/**\n * Standard Reader: `/u/<identifier>` is a profile (document list) and\n * `/a/<identifier>/<rkey>` is a document. The document route omits the\n * collection NSID, but every `/a/` link is a Standard Site document, so we\n * reconstruct the full `site.standard.document/<rkey>` AT URI.\n */\nfunction matchStandardReader(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'standard-reader.app') return null;\n\n if (parts[0] === 'a' && parts[1] && parts[2]) {\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n const rkey = parts[2];\n return {\n source: 'standardReader',\n parsed: {\n type: 'record',\n uri: `at://${handle}/site.standard.document/${rkey}`,\n handle,\n did,\n collection: 'site.standard.document',\n rkey,\n },\n };\n }\n\n if (parts[0] === 'u' && parts[1]) {\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'standardReader',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n }\n\n return null;\n}\n\n/**\n * Offprint (offprint.app) and pckt (pckt.blog) address publications at the\n * flat path `/<identifier>/<collection>/<rkey>` — the collection NSID sits in\n * the path verbatim, so we can round-trip it straight back. Both only expose\n * record-level URLs, so a profile-only path has no meaningful match.\n */\nfunction matchFlatRecordHost(\n host: string,\n parts: string[],\n target: { host: string; source: SourceApp },\n): ReverseMatch | null {\n if (host !== target.host) return null;\n const [handle, collection, rkey] = parts;\n if (!handle || !collection || !rkey) return null;\n // Guard against non-record pages (settings, landing, …): a real record path\n // always carries an NSID collection segment.\n if (!collection.includes('.')) return null;\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: target.source,\n parsed: {\n type: inferType(collection),\n uri: `at://${handle}/${collection}/${rkey}`,\n handle,\n did,\n collection,\n rkey,\n },\n };\n}\n\n/**\n * Taproot (atproto.at): a generic AT-URI explorer addressed at\n * `/uri/at://<identifier>[/<collection>/<rkey>]`.\n */\nfunction matchTaproot(host: string, pathname: string): ReverseMatch | null {\n if (host !== 'atproto.at') return null;\n const m = pathname.replace(/^\\/+/, '').match(/^uri\\/at:\\/{1,2}(.+)$/);\n if (!m) return null;\n const segments = m[1].split('/').filter(Boolean);\n if (segments.length === 0) return null;\n const handle = segments[0];\n const collection = segments[1];\n const rkey = segments[2];\n const did = handle.startsWith('did:') ? handle : undefined;\n\n if (collection && rkey) {\n return {\n source: 'taproot',\n parsed: {\n type: inferType(collection),\n uri: `at://${handle}/${collection}/${rkey}`,\n handle,\n did,\n collection,\n rkey,\n },\n };\n }\n\n return {\n source: 'taproot',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\n/**\n * Aturi's own pages. Two URL spaces share the aturi.to host:\n * - `/explore/<identifier>[/<collection>[/<rkey>]]` — the raw record explorer\n * (source id `aturiExplore`).\n * - `/profile/<identifier>[/post/<rkey> | /lists/<rkey> | /<collection>/<rkey>]`\n * — the universal-link view (source id `aturi`).\n *\n * Detecting these lets the popup offer jumps to other clients and explorers\n * while you're already on Aturi. Reporting the source id as the matching\n * waypoint (`aturiExplore` vs `aturi`) also keeps the page you're on out of the\n * suggestion list.\n */\nfunction matchAturi(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'aturi.to') return null;\n\n // A repo identifier is always a DID (`did:…`) or a dotted handle. This rules\n // out the explorer's own sub-tools — `/explore/lexicons`, `/explore/pds` —\n // whose first segment is a bare word, not an account.\n const isIdentifier = (seg: string | undefined): boolean =>\n !!seg && (seg.startsWith('did:') || seg.includes('.'));\n\n // Explorer: /explore/<identifier>[/<collection>[/<rkey>]]\n if (parts[0] === 'explore' && isIdentifier(parts[1])) {\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n const collection = parts[2];\n const rkey = parts[3];\n if (collection && rkey) {\n return {\n source: 'aturiExplore',\n parsed: {\n type: inferType(collection),\n uri: `at://${handle}/${collection}/${rkey}`,\n handle,\n did,\n collection,\n rkey,\n },\n };\n }\n // Repo browse or a collection listing (no rkey): treat as profile-level so\n // the popup offers profile waypoints for the identifier.\n return {\n source: 'aturiExplore',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n }\n\n // Universal-link view: /profile/<identifier>[/post|/lists|/<collection>/<rkey>]\n if (parts[0] === 'profile' && isIdentifier(parts[1])) {\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n\n if (parts[2] === 'post' && parts[3]) {\n return {\n source: 'aturi',\n parsed: {\n type: 'post',\n uri: `at://${handle}/app.bsky.feed.post/${parts[3]}`,\n handle,\n did,\n collection: 'app.bsky.feed.post',\n rkey: parts[3],\n },\n };\n }\n\n if (parts[2] === 'lists' && parts[3]) {\n return {\n source: 'aturi',\n parsed: {\n type: 'list',\n uri: `at://${handle}/app.bsky.graph.list/${parts[3]}`,\n handle,\n did,\n collection: 'app.bsky.graph.list',\n rkey: parts[3],\n },\n };\n }\n\n // Generic record view: /profile/<identifier>/<collection>/<rkey>. Guard on\n // the dot so non-record profile subpages don't masquerade as records.\n if (parts[2] && parts[2].includes('.') && parts[3]) {\n return {\n source: 'aturi',\n parsed: {\n type: inferType(parts[2]),\n uri: `at://${handle}/${parts[2]}/${parts[3]}`,\n handle,\n did,\n collection: parts[2],\n rkey: parts[3],\n },\n };\n }\n\n return {\n source: 'aturi',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n }\n\n return null;\n}\n\n/**\n * Reverse-match any supported Aturi waypoint site URL back into a structured\n * ParsedURI (handle/collection/rkey). Returns `null` if the URL isn't on a\n * supported site or isn't a shape we recognize.\n */\nexport function matchSupportedUrl(url: URL): ReverseMatch | null {\n const host = normalizeHost(url.hostname);\n const parts = url.pathname.split('/').filter(Boolean);\n const search = url.searchParams;\n\n return (\n matchAturi(host, parts) ||\n matchBlueskyFamily(host, parts) ||\n matchPinksky(host, parts, search) ||\n matchLeaflet(host, parts) ||\n matchTangled(host, parts) ||\n matchMargin(host, parts) ||\n matchPdsls(host, url.pathname) ||\n matchAtpTools(host, url.pathname) ||\n matchBluepy(host, url.pathname) ||\n matchSemble(host, parts) ||\n matchStreamplace(host, parts) ||\n matchGrain(host, parts) ||\n matchPopfeed(host, parts) ||\n matchSifa(host, parts) ||\n matchBlento(host, parts) ||\n matchStandardReader(host, parts) ||\n matchFlatRecordHost(host, parts, { host: 'offprint.app', source: 'offprint' }) ||\n matchFlatRecordHost(host, parts, { host: 'pckt.blog', source: 'pckt' }) ||\n matchTaproot(host, url.pathname)\n );\n}\n\n/**\n * Parse an AT URI string (e.g. \"at://did:plc:abc123/collection/rkey\") into\n * its components. Used by head-based detection when an AT URI is found in\n * a <link> tag's href attribute.\n */\nexport function parseAtUri(uri: string): ReverseMatch | null {\n if (!uri.startsWith('at://')) return null;\n const rest = uri.slice('at://'.length);\n const segments = rest.split('/').filter(Boolean);\n if (segments.length === 0) return null;\n\n const handle = segments[0];\n const did = handle.startsWith('did:') ? handle : undefined;\n const collection = segments[1];\n const rkey = segments[2];\n\n if (collection && rkey) {\n return {\n source: 'headDetected' as SourceApp,\n parsed: {\n type: inferType(collection),\n uri,\n handle,\n did,\n collection,\n rkey,\n },\n };\n }\n\n return {\n source: 'headDetected' as SourceApp,\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\n/**\n * All host names we know how to reverse-parse. Used by the popup + background\n * worker to decide if a tab is \"relevant\" before doing more expensive work.\n */\nexport const SUPPORTED_HOSTS: string[] = [\n 'aturi.to',\n ...BLUESKY_FAMILY.flatMap(e => e.hosts),\n 'pinkleap.app',\n 'leaflet.pub',\n 'tangled.org',\n 'margin.at',\n 'pdsls.dev',\n 'atp.tools',\n 'bluepy.social',\n 'semble.so',\n 'stream.place',\n 'grain.social',\n 'popfeed.social',\n 'sifa.id',\n 'blento.app',\n 'standard-reader.app',\n 'offprint.app',\n 'pckt.blog',\n 'atproto.at',\n];\n\n/**\n * Whether a hostname belongs to a supported waypoint. Prefer this over a raw\n * `SUPPORTED_HOSTS.includes(...)` check: it strips a leading `www.` and also\n * recognizes subdomains of hosts that opt in (e.g. `eclose.anisota.net`), so\n * the extension popup and resolve API treat those tabs as known.\n */\nexport function isSupportedHost(host: string): boolean {\n const h = normalizeHost(host);\n if (SUPPORTED_HOSTS.includes(h)) return true;\n return SUBDOMAIN_HOSTS.some(base => isSubdomainOf(h, base));\n}\n","import {\n WAYPOINT_DESTINATIONS_DATA,\n WAYPOINT_ORDER,\n getRecommendedWaypointsData,\n type WaypointType,\n} from './waypoints.data';\nimport {\n matchSupportedUrl,\n parseAtUri,\n type SourceApp,\n} from './reverseParsers';\nimport type { ParsedURI } from './uriParser';\n\nexport type ResolvedWaypoint = {\n id: string;\n name: string;\n category: string;\n url: string;\n};\n\nexport type ResolvedRecommendation = {\n ids: string[];\n label: string;\n};\n\nexport type ResolveResult = {\n parsed: ParsedURI;\n source: SourceApp;\n did: string | null;\n didResolved: boolean;\n waypoints: ResolvedWaypoint[];\n recommended: ResolvedRecommendation;\n};\n\n/**\n * Waypoints whose `getUrl` only produces a useful destination when a DID is\n * available. These are filtered out unless a DID is known. Mirrors the hosted\n * aturi.to/api/resolve route exactly.\n */\nexport const DID_REQUIRED_WAYPOINTS: ReadonlySet<string> = new Set([\n 'pdsls',\n 'atptools',\n 'margin',\n 'grain',\n 'popfeed',\n]);\n\nexport type BuildWaypointsOptions = {\n /** DID to pass to each waypoint's getUrl. Falls back to `parsed.did`. */\n did?: string;\n /** Waypoint id to omit (e.g. the source app the user is already on). */\n excludeSourceId?: string;\n};\n\n/**\n * Turn a parsed AT URI into the list of waypoints that can render it plus the\n * recommended set, applying the DID-required filter and dropping waypoints\n * whose getUrl returns null. This is the framework-agnostic core of the\n * hosted resolve endpoint.\n */\nexport function buildWaypointsForParsed(\n parsed: ParsedURI,\n options: BuildWaypointsOptions = {},\n): { waypoints: ResolvedWaypoint[]; recommended: ResolvedRecommendation } {\n const did = options.did ?? parsed.did;\n const exclude = options.excludeSourceId;\n const type: WaypointType = parsed.type === 'unknown' ? 'profile' : parsed.type;\n\n const waypoints = WAYPOINT_ORDER.map((id) => WAYPOINT_DESTINATIONS_DATA[id])\n .filter((w): w is NonNullable<typeof w> => !!w)\n .filter((w) => w.id !== exclude)\n .filter((w) => w.supportedTypes.includes(type))\n .map((w): ResolvedWaypoint | null => {\n if (DID_REQUIRED_WAYPOINTS.has(w.id) && !did) return null;\n const url = w.getUrl(parsed.handle, parsed.collection, parsed.rkey, did);\n if (!url) return null;\n return { id: w.id, name: w.name, category: w.category, url };\n })\n .filter((w): w is ResolvedWaypoint => !!w);\n\n const recommendedRaw = getRecommendedWaypointsData(type, parsed.collection);\n const availableIds = new Set(waypoints.map((w) => w.id));\n const ids = recommendedRaw.waypoints\n .map((w) => w.id)\n .filter((id) => id !== exclude && availableIds.has(id));\n\n return { waypoints, recommended: { ids, label: recommendedRaw.label } };\n}\n\n/**\n * Resolve an AT URI string (e.g. \"at://did:plc:abc/app.bsky.feed.post/rkey\")\n * directly into its waypoints. Returns null if the string isn't a valid AT URI.\n */\nexport function resolveAtUri(uri: string): ResolveResult | null {\n const match = parseAtUri(uri);\n if (!match) return null;\n const { parsed, source } = match;\n const { waypoints, recommended } = buildWaypointsForParsed(parsed);\n return {\n parsed,\n source,\n did: parsed.did ?? null,\n didResolved: false,\n waypoints,\n recommended,\n };\n}\n\nexport type ResolveUrlOptions = {\n /**\n * When the URL pattern isn't recognized, fetch the page and look for a\n * `<link href=\"at://…\">` in <head>. Off by default to keep the resolver\n * isomorphic (no network unless explicitly requested).\n */\n fetchHead?: boolean;\n /** Timeout for the optional head probe. Defaults to 4000ms. */\n fetchHeadTimeoutMs?: number;\n /**\n * Resolve a handle to a DID so DID-only waypoints (pdsls, atptools, margin,\n * grain, popfeed) are included. Pass `resolveHandle` from this package, or\n * your own implementation.\n */\n resolveHandle?: (handle: string) => Promise<string | null>;\n};\n\n/**\n * Resolve a pasted/shared page URL back into the AT URI it represents and the\n * waypoints that can render it. Uses local URL-pattern matching by default;\n * optionally falls back to a `<head>` link probe and/or handle→DID resolution.\n *\n * The source app's own waypoint is omitted from the result (you're already\n * there), mirroring the extension popup and hosted endpoint.\n */\nexport async function resolveUrl(\n url: string | URL,\n options: ResolveUrlOptions = {},\n): Promise<ResolveResult | null> {\n let target: URL;\n try {\n target = typeof url === 'string' ? new URL(url) : url;\n } catch {\n return null;\n }\n if (!/^https?:$/.test(target.protocol)) return null;\n\n let match = matchSupportedUrl(target);\n if (!match && options.fetchHead) {\n const headUri = await detectAtUriInHead(\n target.toString(),\n options.fetchHeadTimeoutMs ?? 4000,\n );\n if (headUri) match = parseAtUri(headUri);\n }\n if (!match) return null;\n\n const { parsed, source } = match;\n let did = parsed.did;\n let didResolved = false;\n if (!did && options.resolveHandle) {\n try {\n const resolved = await options.resolveHandle(parsed.handle);\n if (resolved) {\n did = resolved;\n didResolved = true;\n }\n } catch {\n // Swallow; DID-required waypoints will simply be omitted from the result.\n }\n }\n\n const { waypoints, recommended } = buildWaypointsForParsed(parsed, {\n did,\n excludeSourceId: source,\n });\n return {\n parsed: { ...parsed, did },\n source,\n did: did ?? null,\n didResolved,\n waypoints,\n recommended,\n };\n}\n\nexport type ResolveApiInput = {\n url?: string;\n atUri?: string;\n /** Set false to skip the server-side <head> probe. */\n headDetect?: boolean;\n};\n\nexport type ResolveApiParsed = {\n type: WaypointType;\n uri: string;\n handle: string;\n did: string | null;\n collection: string | null;\n rkey: string | null;\n};\n\nexport type ResolveApiSuccess = {\n ok: true;\n inputKind: 'atUri' | 'url';\n detectedVia: 'atUri' | 'urlPattern' | 'headLink' | null;\n source: SourceApp;\n isKnownHost: boolean;\n parsed: ResolveApiParsed;\n didResolved: boolean;\n recommended: ResolvedRecommendation;\n waypoints: ResolvedWaypoint[];\n};\n\nexport type ResolveApiFailure = {\n ok: false;\n input?: string | null;\n inputKind?: 'atUri' | 'url';\n isKnownHost?: boolean;\n reason?: string;\n message?: string;\n error?: string;\n};\n\nexport type ResolveApiResponse = ResolveApiSuccess | ResolveApiFailure;\n\nexport type ResolveViaApiOptions = {\n /** Defaults to the hosted endpoint, https://aturi.to/api/resolve. */\n endpoint?: string;\n /** Custom fetch implementation (e.g. a polyfill or instrumented client). */\n fetch?: typeof fetch;\n signal?: AbortSignal;\n};\n\n/**\n * Typed client for the hosted resolve endpoint. Use this when you want the\n * server to do the work — notably the <head> link probe, which needs to fetch\n * the target page (something you may not want to do from the browser for CORS\n * reasons). Returns the same response shape the route emits.\n */\nexport async function resolveViaApi(\n input: ResolveApiInput,\n options: ResolveViaApiOptions = {},\n): Promise<ResolveApiResponse> {\n const endpoint = options.endpoint ?? 'https://aturi.to/api/resolve';\n const fetchImpl = options.fetch ?? fetch;\n const params = new URLSearchParams();\n if (input.atUri) {\n params.set('atUri', input.atUri);\n } else if (input.url) {\n params.set('url', input.url);\n } else {\n throw new Error('resolveViaApi requires either `url` or `atUri`');\n }\n if (input.headDetect === false) params.set('headDetect', 'false');\n\n const res = await fetchImpl(`${endpoint}?${params.toString()}`, {\n method: 'GET',\n headers: { Accept: 'application/json' },\n signal: options.signal,\n });\n return (await res.json()) as ResolveApiResponse;\n}\n\n/**\n * Best-effort <head> probe for a `<link href=\"at://…\">`. Reads the response as\n * text, scans the document head, and returns the first AT URI found. Returns\n * null on any error, non-HTML content, or timeout.\n */\nasync function detectAtUriInHead(\n url: string,\n timeoutMs: number,\n): Promise<string | null> {\n if (typeof fetch === 'undefined') return null;\n const controller =\n typeof AbortController !== 'undefined' ? new AbortController() : null;\n const timeout = controller\n ? setTimeout(() => controller.abort(), timeoutMs)\n : null;\n try {\n const response = await fetch(url, {\n signal: controller?.signal,\n redirect: 'follow',\n headers: {\n 'User-Agent':\n 'Mozilla/5.0 (compatible; AturiResolver/1.0; +https://aturi.to)',\n Accept:\n 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.5',\n },\n });\n if (!response.ok) return null;\n\n const ct = response.headers.get('content-type') || '';\n if (!/text\\/html|application\\/xhtml/i.test(ct)) return null;\n\n const html = await response.text();\n const headMatch = html.match(/<head[\\s\\S]*?<\\/head>/i);\n const haystack = headMatch ? headMatch[0] : html.slice(0, 256 * 1024);\n const linkRe =\n /<link\\b[^>]*\\bhref\\s*=\\s*[\"'](at:\\/\\/[^\"']+)[\"'][^>]*>/gi;\n let m: RegExpExecArray | null;\n while ((m = linkRe.exec(haystack)) !== null) {\n if (m[1].startsWith('at://')) return m[1];\n }\n return null;\n } catch {\n return null;\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/waypoints.data.ts","../src/requestDeadline.ts","../src/upstreamFetch.ts","../src/uriParser.ts","../src/reverseParsers.ts","../src/resolve.ts","../src/universalLinks.ts"],"names":["identifier","seg"],"mappings":"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","file":"index.cjs","sourcesContent":["export type WaypointType = 'post' | 'profile' | 'list' | 'record' | 'unknown';\n\n/**\n * Keys identifying which \"data family\" a waypoint belongs to for auto-redirect\n * purposes. Two waypoints can only be the endpoints of an auto-redirect when\n * they share at least one family key (i.e. they render the same underlying\n * atproto collections). Display groupings live in `WAYPOINT_CATEGORIES_DATA`\n * and are independent of this.\n */\nexport type RedirectCompatFamily =\n | 'bluesky-social'\n | 'standard-site'\n | 'tangled'\n | 'margin'\n | 'grain'\n | 'pinksky'\n | 'semble'\n | 'streamplace'\n | 'popfeed'\n | 'sifa'\n | 'blento'\n | 'atproto-explorer';\n\n/**\n * A client's support for Bluesky-style *compose intent links*: a URL that opens\n * the app's composer, optionally pre-filled with text.\n * See https://docs.bsky.app/docs/advanced-guides/intent-links.\n *\n * bsky.app established `/intent/compose?text=…`, and the social-app forks in the\n * catalog inherit the same route, so a link built for one works on any of them.\n * Only add an entry once the client's own route has been confirmed — a link to\n * a client that doesn't handle it lands the user on a 404 or an empty home feed.\n */\nexport type ComposeIntentData = {\n /**\n * The compose route, absolute and free of any query string\n * (e.g. `https://bsky.app/intent/compose`).\n */\n url: string;\n /**\n * Query parameter carrying the pre-filled post text. Omitted when the client\n * routes the intent but ignores the text: the link still opens a composer,\n * just an empty one. Check this before offering a \"share this to…\" affordance,\n * since there the text is the whole point.\n *\n * Bluesky's post limit is 300 grapheme clusters; longer text is the caller's\n * problem to truncate.\n */\n textParam?: string;\n /**\n * Deep link into the client's native app for the same intent, when it\n * publishes a scheme (e.g. `bluesky://intent/compose`).\n */\n appUrl?: string;\n};\n\nexport type WaypointData = {\n id: string;\n name: string;\n description: string | ((collection?: string, type?: WaypointType) => string);\n getUrl: (handle: string, collection?: string, rkey?: string, did?: string) => string | null;\n supportedTypes: WaypointType[];\n category: string;\n /**\n * Compose intent support, when the client has a confirmed intent route.\n * Absent means \"no known support\" rather than a proven absence — read it with\n * `supportsComposeIntent` / `getComposeIntentUrl`.\n */\n composeIntent?: ComposeIntentData;\n /**\n * Data families this waypoint participates in. Auto-redirect rules are only\n * emitted between waypoints that share at least one family. An empty array\n * means the waypoint can never be an auto-redirect source *or* destination\n * (dev tools / generic record viewers land here by design).\n */\n redirectCompat: RedirectCompatFamily[];\n /**\n * NSID prefixes that signal this waypoint is meaningfully usable for the\n * target repo. When set, the extension can call describeRepo on the target\n * DID and check whether any of the user's collections start with one of\n * these prefixes — if none do, the waypoint is flagged as \"no records\n * found\" in the popup and demoted in smart recommendations.\n *\n * Use trailing-dot prefixes for whole namespaces (e.g. `'sh.tangled.'`)\n * or full NSIDs for single-collection apps. Atmosphere apps typically\n * declare a reversed-domain prefix (`semble.so` → `so.semble.`) so the\n * popup can flag accounts that haven't published any of that app's\n * records. Omit the field entirely for generic explorers (PDSls,\n * atp.tools, Aturi) — those stay in the \"unknown\" / no-opinion state.\n */\n expectedCollections?: string[];\n};\n\nexport type CompatFamilyMeta = {\n id: RedirectCompatFamily;\n name: string;\n description: string;\n};\n\n/**\n * Registry of compat families. `description` is shown in the options UI so the\n * user understands what each \"Favorite for X\" controls.\n */\nexport const COMPAT_FAMILIES: Record<RedirectCompatFamily, CompatFamilyMeta> = {\n 'bluesky-social': {\n id: 'bluesky-social',\n name: 'Bluesky clients',\n description: 'Apps that render bsky posts, profiles, and lists at /profile/:handle.',\n },\n 'standard-site': {\n id: 'standard-site',\n name: 'Publications',\n description: 'Readers for Standard Site and Leaflet publications.',\n },\n tangled: {\n id: 'tangled',\n name: 'Tangled',\n description: 'Tangled repositories and related records.',\n },\n margin: {\n id: 'margin',\n name: 'Margin',\n description: 'Annotations, highlights, and bookmarks on margin.at.',\n },\n grain: {\n id: 'grain',\n name: 'Grain',\n description: 'Photo galleries on grain.social.',\n },\n pinksky: {\n id: 'pinksky',\n name: 'Pinkleap',\n description: 'Pinkleap browsing experience.',\n },\n semble: {\n id: 'semble',\n name: 'Semble',\n description: 'Semble profiles.',\n },\n streamplace: {\n id: 'streamplace',\n name: 'Streamplace',\n description: 'Streamplace profiles.',\n },\n popfeed: {\n id: 'popfeed',\n name: 'Popfeed',\n description: 'Popfeed profiles.',\n },\n sifa: {\n id: 'sifa',\n name: 'Sifa',\n description: 'Sifa profiles.',\n },\n blento: {\n id: 'blento',\n name: 'Blento',\n description: 'Blento profiles.',\n },\n 'atproto-explorer': {\n id: 'atproto-explorer',\n name: 'Record explorers',\n description:\n 'Raw AT Protocol record explorers (pdsls, atp.tools, Aturi Explore) that render any record by its AT URI.',\n },\n};\n\nexport const COMPAT_FAMILY_ORDER: RedirectCompatFamily[] = [\n 'bluesky-social',\n 'standard-site',\n 'pinksky',\n 'tangled',\n 'margin',\n 'grain',\n 'semble',\n 'streamplace',\n 'popfeed',\n 'sifa',\n 'blento',\n 'atproto-explorer',\n];\n\nexport type WaypointCategoryData = {\n id: string;\n name: string;\n description?: string;\n defaultWaypointId: string;\n subcategories?: WaypointCategoryData[];\n};\n\nexport type CategorizedWaypointsData = {\n category: WaypointCategoryData;\n waypoints: WaypointData[];\n};\n\n/**\n * The `/intent/compose?text=…` shape bsky.app established and every social-app\n * fork inherits verbatim, down to the parameter name.\n */\nfunction socialAppComposeIntent(origin: string): ComposeIntentData {\n return { url: `${origin}/intent/compose`, textParam: 'text' };\n}\n\nexport const WAYPOINT_DESTINATIONS_DATA: Record<string, WaypointData> = {\n aturi: {\n id: 'aturi',\n name: 'Aturi',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on aturi.to';\n if (collection === 'app.bsky.graph.list') return 'View list on aturi.to';\n if (collection?.startsWith('site.standard.') || collection?.startsWith('pub.leaflet.')) {\n return 'View document on aturi.to';\n }\n if (collection) return 'View record on aturi.to';\n return 'View profile on aturi.to';\n },\n getUrl: (handle, collection, rkey, did) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://aturi.to/profile/${handle}/post/${rkey}`;\n }\n if (collection === 'app.bsky.graph.list') {\n return `https://aturi.to/profile/${handle}/lists/${rkey}`;\n }\n // Generic AT-record viewer; prefer the DID (stable across handle changes)\n // when one is available, falling back to the handle otherwise.\n const identifier = did || handle;\n return `https://aturi.to/profile/${identifier}/${collection}/${rkey}`;\n }\n return `https://aturi.to/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['bluesky-social', 'standard-site'],\n },\n\n anisota: {\n id: 'anisota',\n name: 'Anisota',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on anisota.net';\n if (collection === 'app.bsky.graph.list') return 'View list on anisota.net';\n if (collection?.startsWith('site.standard.') || collection?.startsWith('pub.leaflet.')) {\n return 'View document on anisota.net';\n }\n return 'View profile on anisota.net';\n },\n getUrl: (handle, collection, rkey, did) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://anisota.net/profile/${handle}/post/${rkey}`;\n }\n if (collection === 'app.bsky.graph.list') {\n return `https://anisota.net/profile/${handle}/lists/${rkey}`;\n }\n if (collection.startsWith('site.standard.') || collection.startsWith('pub.leaflet.')) {\n // Anisota's document viewer addresses records by DID when available.\n const identifier = did || handle;\n return `https://anisota.net/profile/${identifier}/document/${rkey}`;\n }\n return `https://anisota.net/profile/${handle}`;\n }\n return `https://anisota.net/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyClients',\n // Anisota implements the Bluesky shape deliberately, then extends it with\n // `url`, `tags`, `channel`, and `title` (and answers `/post` with the same\n // query). What's declared here is the interoperable subset every caller can\n // rely on; the extras are Anisota-only and unrepresentable in this field.\n composeIntent: socialAppComposeIntent('https://anisota.net'),\n // Bluesky-shaped records only. anisota.net also reads Standard Site and\n // Leaflet documents, but that role belongs to `anisotaReader`: listing both\n // under `standard-site` put two entries for the same site in every\n // \"Publications\" destination list, and this one's `expectedCollections`\n // already says it does not claim those collections.\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.', 'net.anisota.'],\n },\n\n bluesky: {\n id: 'bluesky',\n name: 'Bluesky',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on bsky.app';\n if (collection === 'app.bsky.graph.list') return 'View list on bsky.app';\n return 'View profile on bsky.app';\n },\n getUrl: (handle, collection, rkey) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://bsky.app/profile/${handle}/post/${rkey}`;\n }\n if (collection === 'app.bsky.graph.list') {\n return `https://bsky.app/profile/${handle}/lists/${rkey}`;\n }\n return `https://bsky.app/profile/${handle}`;\n }\n return `https://bsky.app/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyClients',\n composeIntent: {\n ...socialAppComposeIntent('https://bsky.app'),\n appUrl: 'bluesky://intent/compose',\n },\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n blacksky: {\n id: 'blacksky',\n name: 'Blacksky',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on blacksky.community';\n if (collection === 'app.bsky.graph.list') return 'View list on blacksky.community';\n return 'View profile on blacksky.community';\n },\n getUrl: (handle, collection, rkey) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://blacksky.community/profile/${handle}/post/${rkey}`;\n }\n if (collection === 'app.bsky.graph.list') {\n return `https://blacksky.community/profile/${handle}/lists/${rkey}`;\n }\n return `https://blacksky.community/profile/${handle}`;\n }\n return `https://blacksky.community/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyForks',\n composeIntent: socialAppComposeIntent('https://blacksky.community'),\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n reddwarf: {\n id: 'reddwarf',\n name: 'Red Dwarf',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on reddwarf.app';\n return 'View profile on reddwarf.app';\n },\n getUrl: (handle, collection, rkey) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://reddwarf.app/profile/${handle}/post/${rkey}`;\n }\n return `https://reddwarf.app/profile/${handle}`;\n }\n return `https://reddwarf.app/profile/${handle}`;\n },\n // No `list`: unlike the social-app forks in this family, Red Dwarf has no\n // `/profile/:handle/lists/:rkey` route, so offering it for a list would\n // silently land the user on the list's author instead.\n supportedTypes: ['post', 'profile', 'record'],\n category: 'blueskyClients',\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n impro: {\n id: 'impro',\n name: 'Impro',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on impro.social';\n if (collection === 'app.bsky.graph.list') return 'View list on impro.social';\n return 'View profile on impro.social';\n },\n getUrl: (handle, collection, rkey) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://impro.social/profile/${handle}/post/${rkey}`;\n }\n if (collection === 'app.bsky.graph.list') {\n return `https://impro.social/profile/${handle}/lists/${rkey}`;\n }\n return `https://impro.social/profile/${handle}`;\n }\n return `https://impro.social/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyClients',\n // Impro routes /intent/compose to its home view, which opens the composer\n // for a signed-in user — but it never reads `?text`, so no textParam here.\n composeIntent: { url: 'https://impro.social/intent/compose' },\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n lea: {\n id: 'lea',\n name: 'Lea',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on lea.ac';\n return 'View profile on lea.ac';\n },\n getUrl: (handle, collection, rkey) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://lea.ac/profile/${handle}/post/${rkey}`;\n }\n return `https://lea.ac/profile/${handle}`;\n }\n return `https://lea.ac/profile/${handle}`;\n },\n // No `list`: like Red Dwarf, Lea serves only `/profile/:handle` and\n // `/profile/:handle/post/:rkey` — `/lists/:rkey` 404s — so claiming list\n // support would drop the user on an error page instead of the list.\n supportedTypes: ['post', 'profile', 'record'],\n category: 'blueskyClients',\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n leaflet: {\n id: 'leaflet',\n name: 'Leaflet',\n description: 'View profile on leaflet.pub',\n getUrl: (handle) => {\n return `https://leaflet.pub/p/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'publications',\n redirectCompat: ['standard-site'],\n expectedCollections: ['pub.leaflet.', 'site.standard.'],\n },\n\n pdsls: {\n id: 'pdsls',\n name: 'PDSls',\n description: 'View raw record on pdsls.dev',\n getUrl: (handle, collection, rkey, did) => {\n const identifier = did || handle;\n if (collection && rkey) {\n return `https://pdsls.dev/at://${identifier}/${collection}/${rkey}`;\n }\n return `https://pdsls.dev/at://${identifier}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'devTools',\n redirectCompat: ['atproto-explorer'],\n },\n\n aturiExplore: {\n id: 'aturiExplore',\n name: 'Aturi Explore',\n description: (collection) => {\n if (collection) return 'Inspect record on aturi.to/explore';\n return 'Browse repo on aturi.to/explore';\n },\n getUrl: (handle, collection, rkey, did) => {\n // The explorer keys URLs by DID when available so handle changes don't\n // break shared links. Falls back to the handle when no DID was passed.\n const identifier = did || handle;\n if (collection && rkey) {\n return `https://aturi.to/explore/${identifier}/${collection}/${encodeURIComponent(rkey)}`;\n }\n if (collection) {\n return `https://aturi.to/explore/${identifier}/${collection}`;\n }\n return `https://aturi.to/explore/${identifier}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'devTools',\n redirectCompat: ['atproto-explorer'],\n },\n\n atptools: {\n id: 'atptools',\n name: 'atp.tools',\n description: 'View raw record on atp.tools',\n getUrl: (handle, collection, rkey, did) => {\n const identifier = did || handle;\n if (collection && rkey) {\n return `https://atp.tools/at:/${identifier}/${collection}/${rkey}`;\n }\n return `https://atp.tools/at:/${identifier}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'devTools',\n redirectCompat: ['atproto-explorer'],\n },\n\n bluepy: {\n id: 'bluepy',\n name: 'Bluepy',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on bluepy.social';\n if (collection === 'app.bsky.graph.list') return 'View list on bluepy.social';\n if (collection) return 'View record on bluepy.social';\n return 'View profile on bluepy.social';\n },\n getUrl: (handle, collection, rkey, did) => {\n const identifier = did || handle;\n if (collection && rkey) {\n return `https://bluepy.social/at://${identifier}/${collection}/${rkey}`;\n }\n return `https://bluepy.social/at://${identifier}/app.bsky.actor.profile/self`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyClients',\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n witchsky: {\n id: 'witchsky',\n name: 'Witchsky',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on witchsky.app';\n if (collection === 'app.bsky.graph.list') return 'View list on witchsky.app';\n return 'View profile on witchsky.app';\n },\n getUrl: (handle, collection, rkey) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://witchsky.app/profile/${handle}/post/${rkey}`;\n }\n if (collection === 'app.bsky.graph.list') {\n return `https://witchsky.app/profile/${handle}/lists/${rkey}`;\n }\n return `https://witchsky.app/profile/${handle}`;\n }\n return `https://witchsky.app/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyForks',\n composeIntent: socialAppComposeIntent('https://witchsky.app'),\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n deer: {\n id: 'deer',\n name: 'Deer',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on deer.social';\n if (collection === 'app.bsky.graph.list') return 'View list on deer.social';\n return 'View profile on deer.social';\n },\n getUrl: (handle, collection, rkey) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://deer.social/profile/${handle}/post/${rkey}`;\n }\n if (collection === 'app.bsky.graph.list') {\n return `https://deer.social/profile/${handle}/lists/${rkey}`;\n }\n return `https://deer.social/profile/${handle}`;\n }\n return `https://deer.social/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyForks',\n composeIntent: socialAppComposeIntent('https://deer.social'),\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n mu: {\n id: 'mu',\n name: 'Mu',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on mu.social';\n if (collection === 'app.bsky.graph.list') return 'View list on mu.social';\n return 'View profile on mu.social';\n },\n getUrl: (handle, collection, rkey) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://mu.social/profile/${handle}/post/${rkey}`;\n }\n if (collection === 'app.bsky.graph.list') {\n return `https://mu.social/profile/${handle}/lists/${rkey}`;\n }\n return `https://mu.social/profile/${handle}`;\n }\n return `https://mu.social/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyForks',\n composeIntent: socialAppComposeIntent('https://mu.social'),\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n northsky: {\n id: 'northsky',\n name: 'Northsky',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on northsky.app';\n if (collection === 'app.bsky.graph.list') return 'View list on northsky.app';\n return 'View profile on northsky.app';\n },\n getUrl: (handle, collection, rkey) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n return `https://northsky.app/profile/${handle}/post/${rkey}`;\n }\n if (collection === 'app.bsky.graph.list') {\n return `https://northsky.app/profile/${handle}/lists/${rkey}`;\n }\n return `https://northsky.app/profile/${handle}`;\n }\n return `https://northsky.app/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'blueskyForks',\n composeIntent: socialAppComposeIntent('https://northsky.app'),\n redirectCompat: ['bluesky-social'],\n expectedCollections: ['app.bsky.'],\n },\n\n tangled: {\n id: 'tangled',\n name: 'Tangled',\n description: 'View profile on tangled.org',\n getUrl: (handle) => {\n return `https://tangled.org/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['tangled'],\n expectedCollections: ['sh.tangled.'],\n },\n\n\n pinksky: {\n id: 'pinksky',\n name: 'Pinkleap',\n description: (collection) => {\n if (collection === 'app.bsky.feed.post') return 'View post on pinkleap.app';\n return 'View profile on pinkleap.app';\n },\n getUrl: (handle, collection, rkey, did) => {\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n const identifier = did || handle;\n const atUri = `at://${identifier}/${collection}/${rkey}`;\n const encodedUri = encodeURIComponent(atUri);\n const encodedDid = encodeURIComponent(identifier);\n return `https://pinkleap.app/feed?uri=${encodedUri}&src=profile&index=1&did=${encodedDid}&showThreads=${encodedDid}`;\n }\n return `https://pinkleap.app/profile/${handle}`;\n }\n return `https://pinkleap.app/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['pinksky'],\n expectedCollections: ['app.bsky.'],\n },\n\n margin: {\n id: 'margin',\n name: 'Margin',\n description: (collection) => {\n if (collection === 'at.margin.annotation') return 'View annotation on margin.at';\n if (collection === 'at.margin.highlight') return 'View highlight on margin.at';\n if (collection === 'at.margin.bookmark') return 'View bookmark on margin.at';\n if (collection?.startsWith('at.margin.')) return 'View on margin.at';\n return 'View profile on margin.at';\n },\n getUrl: (handle, collection, rkey, did) => {\n if (collection && rkey && collection.startsWith('at.margin.')) {\n const recordType = collection.replace('at.margin.', '');\n const identifier = did || handle;\n\n if (recordType === 'annotation' || recordType === 'highlight' || recordType === 'bookmark') {\n const handleLooksLikeDomain = handle.includes('.') && !handle.startsWith('did:');\n const domain = handleLooksLikeDomain ? handle : identifier;\n\n return `https://margin.at/${domain}/${recordType}/${rkey}`;\n }\n\n return `https://margin.at/profile/${identifier}`;\n }\n\n const identifier = did || handle;\n return `https://margin.at/profile/${identifier}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['margin'],\n expectedCollections: ['at.margin.'],\n },\n\n semble: {\n id: 'semble',\n name: 'Semble',\n description: 'View profile on semble.so',\n getUrl: (handle) => {\n return `https://semble.so/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['semble'],\n expectedCollections: ['so.semble.'],\n },\n\n streamplace: {\n id: 'streamplace',\n name: 'Streamplace',\n description: 'View profile on stream.place',\n getUrl: (handle) => {\n return `https://stream.place/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['streamplace'],\n expectedCollections: ['place.stream.'],\n },\n\n grain: {\n id: 'grain',\n name: 'Grain',\n description: (collection) => {\n if (collection === 'social.grain.gallery') return 'View gallery on grain.social';\n return 'View profile on grain.social';\n },\n getUrl: (handle, collection, rkey, did) => {\n const identifier = did || handle;\n if (collection === 'social.grain.gallery' && rkey) {\n return `https://grain.social/profile/${identifier}/gallery/${rkey}`;\n }\n return `https://grain.social/profile/${identifier}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['grain'],\n expectedCollections: ['social.grain.'],\n },\n\n popfeed: {\n id: 'popfeed',\n name: 'Popfeed',\n description: 'View profile on popfeed.social',\n getUrl: (handle, collection, rkey, did) => {\n const identifier = did || handle;\n return `https://popfeed.social/profile/${identifier}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['popfeed'],\n expectedCollections: ['social.popfeed.'],\n },\n\n sifa: {\n id: 'sifa',\n name: 'Sifa',\n description: 'View profile on sifa.id',\n getUrl: (handle) => {\n return `https://sifa.id/p/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['sifa'],\n expectedCollections: ['id.sifa.'],\n },\n\n blento: {\n id: 'blento',\n name: 'Blento',\n description: 'View profile on blento.app',\n getUrl: (handle) => {\n return `https://blento.app/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'atmosphereApps',\n redirectCompat: ['blento'],\n expectedCollections: ['app.blento.'],\n },\n\n anisotaReader: {\n id: 'anisotaReader',\n name: 'Anisota Reader',\n description: (collection) => {\n if (collection?.startsWith('site.standard.') || collection?.startsWith('pub.leaflet.')) {\n return 'Read document on anisota.net';\n }\n return 'View publications on anisota.net';\n },\n getUrl: (handle, collection, rkey, did) => {\n if (collection && rkey) {\n if (collection.startsWith('site.standard.') || collection.startsWith('pub.leaflet.')) {\n const identifier = did || handle;\n return `https://anisota.net/profile/${identifier}/document/${rkey}`;\n }\n }\n return `https://anisota.net/profile/${handle}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'publications',\n redirectCompat: ['standard-site'],\n expectedCollections: ['pub.leaflet.', 'site.standard.'],\n },\n\n offprint: {\n id: 'offprint',\n name: 'Offprint',\n description: (collection) => {\n if (collection?.startsWith('site.standard.') || collection?.startsWith('pub.leaflet.')) {\n return 'Read document on offprint.app';\n }\n return 'View on offprint.app';\n },\n getUrl: (handle, collection, rkey, did) => {\n // offprint only has record-level URLs; without a collection+rkey there's\n // no meaningful destination, so hide the waypoint in profile-only views.\n if (!collection || !rkey) return null;\n const identifier = did || handle;\n return `https://offprint.app/${identifier}/${collection}/${rkey}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'publications',\n redirectCompat: ['standard-site'],\n expectedCollections: ['pub.leaflet.', 'site.standard.'],\n },\n\n pckt: {\n id: 'pckt',\n name: 'pckt',\n description: (collection) => {\n if (collection?.startsWith('site.standard.') || collection?.startsWith('pub.leaflet.')) {\n return 'Read document on pckt.blog';\n }\n return 'View on pckt.blog';\n },\n getUrl: (handle, collection, rkey, did) => {\n // pckt only has record-level URLs; without a collection+rkey there's no\n // meaningful destination, so hide the waypoint in profile-only views.\n if (!collection || !rkey) return null;\n const identifier = did || handle;\n return `https://pckt.blog/${identifier}/${collection}/${rkey}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'publications',\n redirectCompat: ['standard-site'],\n expectedCollections: ['pub.leaflet.', 'site.standard.'],\n },\n\n standardReader: {\n id: 'standardReader',\n name: 'Standard Reader',\n description: (collection) => {\n if (collection?.startsWith('site.standard.') || collection?.startsWith('pub.leaflet.')) {\n return 'Read document on standard-reader.app';\n }\n return 'View documents on standard-reader.app';\n },\n getUrl: (handle, collection, rkey, did) => {\n const identifier = did || handle;\n if (\n collection &&\n rkey &&\n (collection.startsWith('site.standard.') || collection.startsWith('pub.leaflet.'))\n ) {\n return `https://standard-reader.app/a/${identifier}/${rkey}`;\n }\n return `https://standard-reader.app/u/${identifier}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'publications',\n redirectCompat: ['standard-site'],\n expectedCollections: ['pub.leaflet.', 'site.standard.'],\n },\n\n taproot: {\n id: 'taproot',\n name: 'Taproot',\n description: (collection) => {\n if (collection) return 'Inspect record on atproto.at';\n return 'Browse repo on atproto.at';\n },\n getUrl: (handle, collection, rkey, did) => {\n const identifier = did || handle;\n if (collection && rkey) {\n return `https://atproto.at/uri/at://${identifier}/${collection}/${rkey}`;\n }\n return `https://atproto.at/uri/at://${identifier}`;\n },\n supportedTypes: ['post', 'profile', 'list', 'record'],\n category: 'devTools',\n redirectCompat: [],\n },\n};\n\nexport const WAYPOINT_ORDER = [\n 'anisota',\n 'bluesky',\n 'bluepy',\n 'reddwarf',\n 'impro',\n 'blacksky',\n 'leaflet',\n 'aturi',\n 'pinksky',\n 'margin',\n 'semble',\n 'streamplace',\n 'grain',\n 'popfeed',\n 'sifa',\n 'blento',\n 'anisotaReader',\n 'offprint',\n 'pckt',\n 'standardReader',\n 'aturiExplore',\n 'pdsls',\n 'tangled',\n 'atptools',\n 'taproot',\n 'witchsky',\n 'mu',\n 'deer',\n 'lea',\n 'northsky',\n];\n\nexport function getWaypointDataForType(type: WaypointType): WaypointData[] {\n return WAYPOINT_ORDER\n .map(id => WAYPOINT_DESTINATIONS_DATA[id])\n .filter(waypoint => waypoint.supportedTypes.includes(type));\n}\n\nexport function getWaypointCountData(): number {\n return WAYPOINT_ORDER.length;\n}\n\nexport const WAYPOINT_CATEGORIES_DATA: Record<string, WaypointCategoryData> = {\n blueskyClients: {\n id: 'blueskyClients',\n name: 'Bluesky Clients',\n description: 'Official and alternative Bluesky clients',\n defaultWaypointId: 'bluesky',\n subcategories: [{\n id: 'blueskyForks',\n name: 'Bluesky Forks',\n description: 'Community-built Bluesky variants',\n defaultWaypointId: 'blacksky',\n }],\n },\n blueskyForks: {\n id: 'blueskyForks',\n name: 'Bluesky Forks',\n description: 'Community-built Bluesky variants',\n defaultWaypointId: 'blacksky',\n },\n publications: {\n id: 'publications',\n name: 'Publications',\n description: 'Readers for Standard Site and Leaflet publications',\n defaultWaypointId: 'leaflet',\n },\n atmosphereApps: {\n id: 'atmosphereApps',\n name: 'Atmosphere',\n description: 'Apps built on the AT Protocol',\n defaultWaypointId: 'tangled',\n },\n devTools: {\n id: 'devTools',\n name: 'Dev Tools',\n description: 'Tools for developers and debugging',\n defaultWaypointId: 'aturiExplore',\n },\n};\n\nexport const CATEGORY_ORDER = [\n 'blueskyClients',\n 'blueskyForks',\n 'publications',\n 'atmosphereApps',\n 'devTools',\n];\n\nexport function getCategorizedWaypointsData(type: WaypointType): CategorizedWaypointsData[] {\n const availableWaypoints = getWaypointDataForType(type);\n const categorized: CategorizedWaypointsData[] = [];\n\n // Categories that are declared as subcategories of another category should\n // not also appear as standalone top-level categories. Their waypoints will\n // be rendered nested under their parent by the picker.\n const subcategoryIds = new Set<string>();\n for (const category of Object.values(WAYPOINT_CATEGORIES_DATA)) {\n for (const subcat of category.subcategories ?? []) {\n subcategoryIds.add(subcat.id);\n }\n }\n\n for (const categoryId of CATEGORY_ORDER) {\n if (subcategoryIds.has(categoryId)) continue;\n\n const category = WAYPOINT_CATEGORIES_DATA[categoryId];\n const waypoints = availableWaypoints.filter(w => w.category === categoryId);\n\n if (waypoints.length > 0) {\n categorized.push({ category, waypoints });\n }\n }\n\n return categorized;\n}\n\ntype RecommendedConfig = {\n waypointIds: string[];\n label?: string;\n};\n\nconst RECOMMENDED_WAYPOINTS: Record<string, RecommendedConfig> = {\n 'app.bsky.feed.post': {\n waypointIds: ['bluesky', 'anisota', 'blacksky'],\n label: 'Recommended for Posts',\n },\n 'profile': {\n waypointIds: ['bluesky', 'anisota'],\n label: 'Recommended for Profiles',\n },\n 'app.bsky.graph.list': {\n waypointIds: ['bluesky', 'anisota'],\n label: 'Recommended for Lists',\n },\n 'community.lexicon.calendar.event': {\n waypointIds: ['aturiExplore', 'pdsls', 'atptools'],\n label: 'Recommended for Events',\n },\n 'sh.tangled.repo': {\n waypointIds: ['tangled'],\n label: 'Recommended for Repos',\n },\n 'record': {\n waypointIds: ['aturiExplore', 'pdsls', 'atptools', 'taproot'],\n label: 'Recommended for Records',\n },\n};\n\n/**\n * Recommendations keyed by collection NSID prefix. When a collection is checked,\n * we walk its dotted segments from longest to shortest looking for a registered\n * prefix (e.g. `standard.site.blog.entry` matches `standard.site`). Use this for\n * apps/lexicons that own a whole namespace and have a consistent set of compatible\n * waypoints across all of their record types.\n */\nconst RECOMMENDED_NAMESPACE_PREFIXES: Record<string, RecommendedConfig> = {\n 'site.standard': {\n waypointIds: ['leaflet', 'standardReader', 'anisotaReader', 'offprint', 'pckt', 'pdsls'],\n label: 'Recommended for Publications',\n },\n 'pub.leaflet': {\n waypointIds: ['leaflet', 'anisotaReader', 'offprint', 'pckt', 'pdsls'],\n label: 'Recommended for Publications',\n },\n 'sh.tangled': {\n waypointIds: ['tangled', 'pdsls', 'atptools'],\n label: 'Recommended for Tangled',\n },\n 'at.margin': {\n waypointIds: ['margin', 'pdsls', 'atptools'],\n label: 'Recommended for Margin',\n },\n 'social.grain': {\n waypointIds: ['grain', 'pdsls', 'atptools'],\n label: 'Recommended for Grain',\n },\n};\n\nfunction findNamespacePrefixMatch(collection: string): RecommendedConfig | undefined {\n const segments = collection.split('.');\n for (let i = segments.length - 1; i >= 2; i--) {\n const prefix = segments.slice(0, i).join('.');\n if (RECOMMENDED_NAMESPACE_PREFIXES[prefix]) {\n return RECOMMENDED_NAMESPACE_PREFIXES[prefix];\n }\n }\n return undefined;\n}\n\nexport function getRecommendedWaypointsData(\n type: WaypointType,\n collection?: string\n): { waypoints: WaypointData[]; label: string } {\n let config: RecommendedConfig | undefined;\n\n if (collection && RECOMMENDED_WAYPOINTS[collection]) {\n config = RECOMMENDED_WAYPOINTS[collection];\n } else if (collection) {\n config = findNamespacePrefixMatch(collection);\n }\n\n if (!config && RECOMMENDED_WAYPOINTS[type]) {\n config = RECOMMENDED_WAYPOINTS[type];\n }\n\n if (!config) {\n config = {\n waypointIds: ['bluesky'],\n label: 'Recommended',\n };\n }\n\n const waypoints = config.waypointIds\n .map(id => WAYPOINT_DESTINATIONS_DATA[id])\n .filter(Boolean);\n\n return {\n waypoints,\n label: config.label || 'Recommended',\n };\n}\n\nexport function getFeaturedWaypointData(\n type: WaypointType,\n collection?: string\n): WaypointData | null {\n const { waypoints } = getRecommendedWaypointsData(type, collection);\n return waypoints[0] || null;\n}\n\n/**\n * Result of comparing a waypoint's `expectedCollections` against the set of\n * NSIDs found in the target repo.\n *\n * - 'present' — the user has at least one record under a matching prefix.\n * - 'absent' — the waypoint declared collections but none are in the repo.\n * - 'unknown' — the waypoint didn't declare any expectations, or we\n * haven't scanned the repo yet (e.g. scan disabled, no DID).\n */\nexport type WaypointActivity = 'present' | 'absent' | 'unknown';\n\n/**\n * Classify a waypoint against the set of collection NSIDs known to exist on\n * the target repo. Prefix-matches each entry in `expectedCollections` against\n * `repoCollections`. Returns 'unknown' when the waypoint has no declared\n * expectations or the caller passed `null` for `repoCollections` (i.e. scan\n * disabled or still in flight).\n */\nexport function waypointActivity(\n waypoint: Pick<WaypointData, 'expectedCollections'>,\n repoCollections: ReadonlySet<string> | null,\n): WaypointActivity {\n if (!repoCollections) return 'unknown';\n const expected = waypoint.expectedCollections;\n if (!expected || expected.length === 0) return 'unknown';\n for (const c of repoCollections) {\n for (const prefix of expected) {\n if (c === prefix || c.startsWith(prefix)) return 'present';\n }\n }\n return 'absent';\n}\n\n/** Placeholder a compose intent template leaves for the caller's post text. */\nexport const COMPOSE_INTENT_TEXT_PLACEHOLDER = '{text}';\n\n/** Whether the client can be handed a link that opens its composer. */\nexport function supportsComposeIntent(\n waypoint: Pick<WaypointData, 'composeIntent'>,\n): boolean {\n return !!waypoint.composeIntent;\n}\n\n/**\n * Build a link that opens the client's composer, pre-filled with `text` when\n * the client reads it. Returns null when the client has no known intent route.\n *\n * getComposeIntentUrl(WAYPOINT_DESTINATIONS_DATA.deer, 'hello!')\n * // 'https://deer.social/intent/compose?text=hello!'\n */\nexport function getComposeIntentUrl(\n waypoint: Pick<WaypointData, 'composeIntent'>,\n text?: string,\n): string | null {\n const intent = waypoint.composeIntent;\n if (!intent) return null;\n return appendComposeText(intent.url, intent.textParam, text);\n}\n\n/**\n * The native-app flavour of `getComposeIntentUrl`. Null unless the client\n * publishes a scheme of its own — most web clients don't, so fall back to the\n * https link rather than treating null as \"unsupported\".\n */\nexport function getComposeIntentAppUrl(\n waypoint: Pick<WaypointData, 'composeIntent'>,\n text?: string,\n): string | null {\n const intent = waypoint.composeIntent;\n if (!intent?.appUrl) return null;\n return appendComposeText(intent.appUrl, intent.textParam, text);\n}\n\n/**\n * The client's intent URL with a literal `{text}` where the post text goes, for\n * handing to consumers that build their own links (JSON APIs, docs, templates).\n * Substitute the placeholder with URL-encoded text. Clients that ignore the\n * text get a template with no placeholder at all.\n */\nexport function getComposeIntentTemplate(\n waypoint: Pick<WaypointData, 'composeIntent'>,\n): string | null {\n const intent = waypoint.composeIntent;\n if (!intent) return null;\n if (!intent.textParam) return intent.url;\n return `${intent.url}?${intent.textParam}=${COMPOSE_INTENT_TEXT_PLACEHOLDER}`;\n}\n\n/**\n * Catalog-ordered list of every client with a compose intent route, optionally\n * narrowed to those that also render a given record type.\n */\nexport function getComposeIntentWaypoints(type?: WaypointType): WaypointData[] {\n const waypoints = type\n ? getWaypointDataForType(type)\n : WAYPOINT_ORDER.map(id => WAYPOINT_DESTINATIONS_DATA[id]).filter(Boolean);\n return waypoints.filter(supportsComposeIntent);\n}\n\n/**\n * JSON-safe view of a client's compose intent, for surfaces that can't ship a\n * function (HTTP responses, the extension's message passing, docs tables).\n */\nexport type ComposeIntentDescriptor = {\n /** Ready to open. Pre-filled when `text` was supplied and the client reads it. */\n url: string;\n /** The same URL with a literal `{text}` where the post text goes. */\n urlTemplate: string;\n /** Query parameter carrying the text; null when the client ignores it. */\n textParam: string | null;\n /**\n * False when the composer opens empty no matter what you pass — the link is\n * still a valid \"start a post over there\" jump, just not a share.\n */\n prefillsText: boolean;\n /** Native-app deep link for the same intent, when the client publishes one. */\n appUrl?: string;\n};\n\n/** Serialize a waypoint's compose intent. Null when it has none. */\nexport function describeComposeIntent(\n waypoint: Pick<WaypointData, 'composeIntent'>,\n text?: string,\n): ComposeIntentDescriptor | null {\n const intent = waypoint.composeIntent;\n if (!intent) return null;\n const descriptor: ComposeIntentDescriptor = {\n url: getComposeIntentUrl(waypoint, text)!,\n urlTemplate: getComposeIntentTemplate(waypoint)!,\n textParam: intent.textParam ?? null,\n prefillsText: !!intent.textParam,\n };\n const appUrl = getComposeIntentAppUrl(waypoint, text);\n if (appUrl) descriptor.appUrl = appUrl;\n return descriptor;\n}\n\nfunction appendComposeText(\n base: string,\n textParam: string | undefined,\n text: string | undefined,\n): string {\n if (!textParam || !text) return base;\n return `${base}?${textParam}=${encodeURIComponent(text)}`;\n}\n","/**\n * Deadline and identification for the direct-fetch upstream clients.\n *\n * Most outbound calls go through `upstreamFetch`, which bounds and retries\n * them. A handful of clients (appview, slingshot, constellation, plc,\n * identity, ufos) deliberately use bare `fetch` instead: they swallow failures\n * into null rather than throwing, and they must not retry. They still need a\n * deadline, since a host that accepts a connection and never answers would\n * otherwise hold a serverless invocation until the platform kills it.\n *\n * Both concerns live here rather than being repeated per module, so the\n * timeout and the User-Agent cannot drift apart between them.\n */\n\n/** Matches upstreamFetch's per-attempt budget. */\nexport const UPSTREAM_TIMEOUT_MS = 8000;\n\n/** The caller's signal, if any, combined with the deadline. */\nexport function withDeadline(signal?: AbortSignal | null): AbortSignal {\n const deadline = AbortSignal.timeout(UPSTREAM_TIMEOUT_MS);\n return signal ? AbortSignal.any([signal, deadline]) : deadline;\n}\n\n/**\n * Identify this deployment to the services it reads.\n *\n * Constellation, Slingshot and UFOs are run by volunteers, and Bluesky's\n * public AppView is a courtesy; an operator seeing unusual traffic should be\n * able to tell who it is and where to complain. Set only off-browser: a\n * browser forbids scripts from setting User-Agent, and these modules are\n * imported by the extension too.\n */\nexport const UPSTREAM_USER_AGENT = 'aturi.to (+https://aturi.to/mcp)';\n\n/**\n * The identifying headers to merge into an outbound request, or nothing at\n * all in a browser, where scripts are forbidden from setting User-Agent and\n * the attempt is either ignored or throws.\n */\nexport function identifyingHeaders(\n existing?: HeadersInit,\n): Record<string, string> | undefined {\n const headers = existing as Record<string, string> | undefined;\n if (typeof window !== 'undefined') return headers;\n return { ...headers, 'User-Agent': UPSTREAM_USER_AGENT };\n}\n\nexport function withIdentification(init?: RequestInit): RequestInit {\n const merged: RequestInit = { ...init, signal: withDeadline(init?.signal) };\n const headers = identifyingHeaders(init?.headers);\n if (headers) merged.headers = headers;\n return merged;\n}\n","/**\n * Shared fetch wrapper for upstream atproto services (appview, PLC\n * directory, PDS hosts).\n *\n * Every server-rendered page ultimately funnels through these upstream\n * calls, so two failure modes matter in production:\n *\n * - A hung TCP connection with no timeout keeps the whole function alive\n * until the platform kills it (observed as 300s Vercel timeouts).\n * - Transient socket resets (ECONNRESET against public.api.bsky.app) fail\n * requests that would succeed on an immediate retry.\n *\n * This wrapper bounds every request with AbortSignal.timeout and retries\n * once on network-level failures (never on HTTP error statuses, which are\n * meaningful responses). Works in Node, edge, and browser runtimes — the\n * extension imports sibling modules from this directory.\n *\n * It also identifies the caller. These requests reach personal data servers\n * and plc.directory, run by individuals and by a small team; an operator\n * looking at unfamiliar traffic should be able to see whose it is without\n * having to guess. Without this the requests go out as undici's default\n * `node`, which says nothing.\n */\n\nimport { identifyingHeaders } from './requestDeadline';\n\nexport type UpstreamFetchOptions = RequestInit & {\n /** Per-attempt timeout in milliseconds. Defaults to 8000. */\n timeoutMs?: number;\n /** Extra attempts after a network-level failure. Defaults to 1. */\n retries?: number;\n};\n\nconst RETRY_DELAY_MS = 250;\n\nexport async function upstreamFetch(\n url: string,\n { timeoutMs = 8000, retries = 1, ...init }: UpstreamFetchOptions = {}\n): Promise<Response> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= retries; attempt++) {\n try {\n const headers = identifyingHeaders(init.headers);\n return await fetch(url, {\n ...init,\n ...(headers ? { headers } : {}),\n signal: AbortSignal.timeout(timeoutMs),\n });\n } catch (error) {\n lastError = error;\n if (attempt < retries) {\n await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY_MS));\n }\n }\n }\n\n throw lastError;\n}\n\n/**\n * Log an upstream HTTP error at the right level: 4xx responses are almost\n * always caused by user-supplied input (a bad handle or rkey in a shared\n * link) and are expected, so they log as warnings; 5xx and everything else\n * logs as an error. Keeps the production error dashboard signal-rich.\n */\nexport function logUpstreamHttpError(context: string, response: Response): void {\n if (response.status >= 400 && response.status < 500) {\n console.warn(`${context}: HTTP ${response.status} (expected for bad input)`);\n } else {\n console.error(`${context}: HTTP ${response.status}`);\n }\n}\n","import { upstreamFetch } from './upstreamFetch';\n\nexport type ParsedURI = {\n type: 'post' | 'profile' | 'list' | 'record' | 'unknown';\n uri: string;\n handle: string;\n did?: string;\n collection?: string;\n rkey?: string;\n error?: string;\n};\n\n/**\n * Parse URL path segments into structured AT URI data\n * Examples:\n * - /alice.bsky.social -> profile\n * - /alice.bsky.social/app.bsky.feed.post/3k7qw... -> post\n * - /did:plc:xxx/app.bsky.graph.list/abc -> list\n */\nexport function parseURI(handle: string, collection?: string, rkey?: string): ParsedURI {\n // Handle is required\n if (!handle) {\n return {\n type: 'unknown',\n uri: '',\n handle: '',\n error: 'Handle or DID is required',\n };\n }\n\n // Profile case (no collection/rkey)\n if (!collection && !rkey) {\n return {\n type: 'profile',\n uri: `at://${handle}`,\n handle,\n did: handle.startsWith('did:') ? handle : undefined,\n };\n }\n\n // The literal `space` marker sits where a public collection NSID would in a\n // permissioned AT URI (at://{did}/space/{type}/{skey}/…). An NSID always\n // carries at least two dots and the marker carries none, so the two never\n // collide. A space address needs four or more segments and names private\n // data, so the three-segment universal-link route can never render one.\n // Kept as a local literal rather than an import: this file is copied verbatim\n // into @aturi.to/waypoints, which cannot resolve src/utils/atproto/*.\n if (collection === 'space') {\n return {\n type: 'unknown',\n uri: '',\n handle,\n error: 'Space URIs are not public records',\n };\n }\n\n // Record case (has collection and rkey)\n if (collection && rkey) {\n let type: 'post' | 'list' | 'record' = 'record';\n \n if (collection === 'app.bsky.feed.post') {\n type = 'post';\n } else if (collection === 'app.bsky.graph.list') {\n type = 'list';\n }\n // All other collections are treated as generic records\n\n return {\n type,\n uri: `at://${handle}/${collection}/${rkey}`,\n handle,\n did: handle.startsWith('did:') ? handle : undefined,\n collection,\n rkey,\n };\n }\n\n // Invalid case\n return {\n type: 'unknown',\n uri: '',\n handle,\n error: 'Invalid URI structure',\n };\n}\n\n/**\n * Resolve a handle to a DID using the Bluesky API\n */\n/**\n * Handle resolution that distinguishes a definitive \"no such handle\" from a\n * transient \"resolver unavailable\". Callers that need to decide between a real\n * 404 and a retry state use this; `resolveHandle` remains for the common\n * did-or-null case.\n *\n * - `not-found`: the appview returned a 4xx (invalid/unknown handle). Safe to\n * surface as a 404.\n * - `unavailable`: network failure or 5xx. Must NOT be shown as a 404 — it's a\n * real account we couldn't look up right now.\n */\nexport type HandleResolution =\n | { did: string; reason?: undefined }\n | { did: null; reason: 'not-found' | 'unavailable' };\n\nexport async function resolveHandleStatus(handle: string): Promise<HandleResolution> {\n if (handle.startsWith('did:')) {\n return { did: handle };\n }\n\n try {\n const apiUrl = process.env.NEXT_PUBLIC_BSKY_API_URL || 'https://public.api.bsky.app';\n const response = await upstreamFetch(\n `${apiUrl}/xrpc/com.atproto.identity.resolveHandle?handle=${encodeURIComponent(handle)}`\n );\n\n if (!response.ok) {\n return { did: null, reason: response.status >= 500 ? 'unavailable' : 'not-found' };\n }\n\n const data = await response.json();\n if (data.did) return { did: data.did };\n return { did: null, reason: 'not-found' };\n } catch (error) {\n console.error('Error resolving handle:', error);\n return { did: null, reason: 'unavailable' };\n }\n}\n\nexport async function resolveHandle(handle: string): Promise<string | null> {\n return (await resolveHandleStatus(handle)).did;\n}\n\n/**\n * Get display name from handle or DID\n */\nexport function getDisplayName(handle: string, did?: string): string {\n if (handle.startsWith('did:')) {\n return did ? `@${did.slice(0, 16)}...` : 'Unknown';\n }\n return `@${handle}`;\n}\n\n\n","import type { ParsedURI } from './uriParser';\n\nexport type SourceApp =\n | 'aturi'\n | 'aturiExplore'\n | 'bluesky'\n | 'bluepy'\n | 'blacksky'\n | 'reddwarf'\n | 'impro'\n | 'lea'\n | 'witchsky'\n | 'deer'\n | 'northsky'\n | 'mu'\n | 'anisota'\n | 'pinksky'\n | 'leaflet'\n | 'tangled'\n | 'margin'\n | 'pdsls'\n | 'atptools'\n | 'semble'\n | 'streamplace'\n | 'grain'\n | 'popfeed'\n | 'sifa'\n | 'blento'\n | 'standardReader'\n | 'taproot'\n | 'offprint'\n | 'pckt'\n | 'headDetected';\n\nexport type ReverseMatch = {\n source: SourceApp;\n parsed: ParsedURI;\n};\n\ntype HostConfig = {\n source: SourceApp;\n hosts: string[];\n /**\n * When true, any subdomain of the listed hosts is treated as this source\n * too (e.g. Anisota gives each publication its own `*.anisota.net` host).\n */\n matchSubdomains?: boolean;\n};\n\n/**\n * Hosts that share the Bluesky-style `/profile/:handle[/(post|lists)/:rkey]` layout.\n */\nconst BLUESKY_FAMILY: HostConfig[] = [\n { source: 'bluesky', hosts: ['bsky.app'] },\n { source: 'blacksky', hosts: ['blacksky.community'] },\n { source: 'reddwarf', hosts: ['reddwarf.app'] },\n { source: 'impro', hosts: ['impro.social'] },\n { source: 'lea', hosts: ['lea.ac'] },\n { source: 'witchsky', hosts: ['witchsky.app'] },\n { source: 'deer', hosts: ['deer.social'] },\n { source: 'northsky', hosts: ['northsky.app'] },\n { source: 'mu', hosts: ['mu.social'] },\n { source: 'anisota', hosts: ['anisota.net'], matchSubdomains: true },\n];\n\n/**\n * Base hosts whose subdomains are also recognized (e.g. `*.anisota.net`).\n * Derived from the `matchSubdomains` opt-in so there's one source of truth.\n */\nconst SUBDOMAIN_HOSTS: string[] = BLUESKY_FAMILY.filter(f => f.matchSubdomains).flatMap(\n f => f.hosts,\n);\n\nfunction normalizeHost(host: string): string {\n return host.toLowerCase().replace(/^www\\./, '');\n}\n\n/** True when `host` is a subdomain of `base` (a real dotted-label boundary). */\nfunction isSubdomainOf(host: string, base: string): boolean {\n return host.endsWith(`.${base}`);\n}\n\n/** Exact host match, or a subdomain match when the config opts in. */\nfunction hostMatchesConfig(host: string, config: HostConfig): boolean {\n if (config.hosts.includes(host)) return true;\n if (!config.matchSubdomains) return false;\n return config.hosts.some(h => isSubdomainOf(host, h));\n}\n\nfunction matchBlueskyFamily(host: string, parts: string[]): ReverseMatch | null {\n const entry = BLUESKY_FAMILY.find(f => hostMatchesConfig(host, f));\n if (!entry) return null;\n\n if (parts[0] !== 'profile' || !parts[1]) return null;\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n\n if (!parts[2]) {\n return {\n source: entry.source,\n parsed: {\n type: 'profile',\n uri: `at://${handle}`,\n handle,\n did,\n },\n };\n }\n\n if (parts[2] === 'post' && parts[3]) {\n return {\n source: entry.source,\n parsed: {\n type: 'post',\n uri: `at://${handle}/app.bsky.feed.post/${parts[3]}`,\n handle,\n did,\n collection: 'app.bsky.feed.post',\n rkey: parts[3],\n },\n };\n }\n\n if ((parts[2] === 'lists' || parts[2] === 'list') && parts[3]) {\n return {\n source: entry.source,\n parsed: {\n type: 'list',\n uri: `at://${handle}/app.bsky.graph.list/${parts[3]}`,\n handle,\n did,\n collection: 'app.bsky.graph.list',\n rkey: parts[3],\n },\n };\n }\n\n // Anisota's reader addresses Standard Site / Leaflet documents at\n // `/profile/:handle/document/:rkey` without the collection NSID in the URL.\n // Mirror Standard Reader's convention and reconstruct the canonical\n // `site.standard.document` collection so the record still resolves.\n if (parts[2] === 'document' && parts[3]) {\n return {\n source: entry.source,\n parsed: {\n type: 'record',\n uri: `at://${handle}/site.standard.document/${parts[3]}`,\n handle,\n did,\n collection: 'site.standard.document',\n rkey: parts[3],\n },\n };\n }\n\n return {\n source: entry.source,\n parsed: {\n type: 'profile',\n uri: `at://${handle}`,\n handle,\n did,\n },\n };\n}\n\nfunction inferType(collection: string): 'post' | 'list' | 'record' {\n if (collection === 'app.bsky.feed.post') return 'post';\n if (collection === 'app.bsky.graph.list') return 'list';\n return 'record';\n}\n\nfunction matchPinksky(host: string, parts: string[], search: URLSearchParams): ReverseMatch | null {\n if (host !== 'pinkleap.app') return null;\n\n if (parts[0] === 'feed') {\n const uri = search.get('uri');\n if (uri && uri.startsWith('at://')) {\n const stripped = uri.slice('at://'.length);\n const [handle, collection, rkey] = stripped.split('/');\n if (handle) {\n const did = handle.startsWith('did:') ? handle : undefined;\n if (collection && rkey) {\n return {\n source: 'pinksky',\n parsed: {\n type: inferType(collection),\n uri,\n handle,\n did,\n collection,\n rkey,\n },\n };\n }\n return {\n source: 'pinksky',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n }\n }\n }\n\n if (parts[0] === 'profile' && parts[1]) {\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'pinksky',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n }\n\n return null;\n}\n\nfunction matchLeaflet(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'leaflet.pub') return null;\n if (parts[0] !== 'p' || !parts[1]) return null;\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'leaflet',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchTangled(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'tangled.org') return null;\n if (!parts[0]) return null;\n const handle = parts[0];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'tangled',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchMargin(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'margin.at') return null;\n\n if (parts[0] === 'profile' && parts[1]) {\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'margin',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n }\n\n if (parts[0] && parts[1] && parts[2]) {\n const recordType = parts[1];\n if (recordType === 'annotation' || recordType === 'highlight' || recordType === 'bookmark') {\n const handle = parts[0];\n const did = handle.startsWith('did:') ? handle : undefined;\n const collection = `at.margin.${recordType}`;\n const rkey = parts[2];\n return {\n source: 'margin',\n parsed: {\n type: 'record',\n uri: `at://${handle}/${collection}/${rkey}`,\n handle,\n did,\n collection,\n rkey,\n },\n };\n }\n }\n\n return null;\n}\n\n/**\n * Parse a path segment of the form `at://identifier[/collection/rkey]` or\n * `at:/identifier[/collection/rkey]` used by pdsls.dev and atp.tools.\n *\n * The leading `at://` or `at:/` is collapsed by the URL parser so the raw\n * `pathname` exposes it as `/at:/identifier/...`. We accept both forms.\n */\nfunction parseAtUriPath(pathname: string): {\n handle: string;\n collection?: string;\n rkey?: string;\n} | null {\n const cleaned = pathname.replace(/^\\/+/, '');\n const match = cleaned.match(/^at:\\/{1,2}(.+)$/);\n if (!match) return null;\n const rest = match[1];\n const segments = rest.split('/').filter(Boolean);\n if (segments.length === 0) return null;\n // Permissioned space addresses must never be handed to a public explorer;\n // see the note in matchAturi. The literal is duplicated because this file is\n // copied verbatim into @aturi.to/waypoints.\n if (segments[1] === 'space') return null;\n return {\n handle: segments[0],\n collection: segments[1],\n rkey: segments[2],\n };\n}\n\nfunction matchPdsls(host: string, pathname: string): ReverseMatch | null {\n if (host !== 'pdsls.dev') return null;\n const atUri = parseAtUriPath(pathname);\n if (!atUri) return null;\n const { handle, collection, rkey } = atUri;\n const did = handle.startsWith('did:') ? handle : undefined;\n\n if (collection && rkey) {\n return {\n source: 'pdsls',\n parsed: {\n type: inferType(collection),\n uri: `at://${handle}/${collection}/${rkey}`,\n handle,\n did,\n collection,\n rkey,\n },\n };\n }\n\n return {\n source: 'pdsls',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchAtpTools(host: string, pathname: string): ReverseMatch | null {\n if (host !== 'atp.tools') return null;\n const atUri = parseAtUriPath(pathname);\n if (!atUri) return null;\n const { handle, collection, rkey } = atUri;\n const did = handle.startsWith('did:') ? handle : undefined;\n\n if (collection && rkey) {\n return {\n source: 'atptools',\n parsed: {\n type: inferType(collection),\n uri: `at://${handle}/${collection}/${rkey}`,\n handle,\n did,\n collection,\n rkey,\n },\n };\n }\n\n return {\n source: 'atptools',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchBluepy(host: string, pathname: string): ReverseMatch | null {\n if (host !== 'bluepy.social') return null;\n const atUri = parseAtUriPath(pathname);\n if (!atUri) return null;\n const { handle, collection, rkey } = atUri;\n const did = handle.startsWith('did:') ? handle : undefined;\n\n if (collection === 'app.bsky.actor.profile') {\n return {\n source: 'bluepy',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n }\n\n if (collection && rkey) {\n return {\n source: 'bluepy',\n parsed: {\n type: inferType(collection),\n uri: `at://${handle}/${collection}/${rkey}`,\n handle,\n did,\n collection,\n rkey,\n },\n };\n }\n\n return {\n source: 'bluepy',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchSemble(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'semble.so') return null;\n if (parts[0] !== 'profile' || !parts[1]) return null;\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'semble',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchStreamplace(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'stream.place') return null;\n if (!parts[0]) return null;\n const handle = parts[0];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'streamplace',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchGrain(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'grain.social') return null;\n if (parts[0] !== 'profile' || !parts[1]) return null;\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n\n if (parts[2] === 'gallery' && parts[3]) {\n return {\n source: 'grain',\n parsed: {\n type: 'record',\n uri: `at://${handle}/social.grain.gallery/${parts[3]}`,\n handle,\n did,\n collection: 'social.grain.gallery',\n rkey: parts[3],\n },\n };\n }\n\n return {\n source: 'grain',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchPopfeed(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'popfeed.social') return null;\n if (parts[0] !== 'profile' || !parts[1]) return null;\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'popfeed',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchSifa(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'sifa.id') return null;\n if (parts[0] !== 'p' || !parts[1]) return null;\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'sifa',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\nfunction matchBlento(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'blento.app') return null;\n if (!parts[0]) return null;\n const handle = parts[0];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'blento',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\n/**\n * Standard Reader: `/u/<identifier>` is a profile (document list) and\n * `/a/<identifier>/<rkey>` is a document. The document route omits the\n * collection NSID, but every `/a/` link is a Standard Site document, so we\n * reconstruct the full `site.standard.document/<rkey>` AT URI.\n */\nfunction matchStandardReader(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'standard-reader.app') return null;\n\n if (parts[0] === 'a' && parts[1] && parts[2]) {\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n const rkey = parts[2];\n return {\n source: 'standardReader',\n parsed: {\n type: 'record',\n uri: `at://${handle}/site.standard.document/${rkey}`,\n handle,\n did,\n collection: 'site.standard.document',\n rkey,\n },\n };\n }\n\n if (parts[0] === 'u' && parts[1]) {\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: 'standardReader',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n }\n\n return null;\n}\n\n/**\n * Offprint (offprint.app) and pckt (pckt.blog) address publications at the\n * flat path `/<identifier>/<collection>/<rkey>` — the collection NSID sits in\n * the path verbatim, so we can round-trip it straight back. Both only expose\n * record-level URLs, so a profile-only path has no meaningful match.\n */\nfunction matchFlatRecordHost(\n host: string,\n parts: string[],\n target: { host: string; source: SourceApp },\n): ReverseMatch | null {\n if (host !== target.host) return null;\n const [handle, collection, rkey] = parts;\n if (!handle || !collection || !rkey) return null;\n // Guard against non-record pages (settings, landing, …): a real record path\n // always carries an NSID collection segment.\n if (!collection.includes('.')) return null;\n const did = handle.startsWith('did:') ? handle : undefined;\n return {\n source: target.source,\n parsed: {\n type: inferType(collection),\n uri: `at://${handle}/${collection}/${rkey}`,\n handle,\n did,\n collection,\n rkey,\n },\n };\n}\n\n/**\n * Taproot (atproto.at): a generic AT-URI explorer addressed at\n * `/uri/at://<identifier>[/<collection>/<rkey>]`.\n */\nfunction matchTaproot(host: string, pathname: string): ReverseMatch | null {\n if (host !== 'atproto.at') return null;\n const m = pathname.replace(/^\\/+/, '').match(/^uri\\/at:\\/{1,2}(.+)$/);\n if (!m) return null;\n const segments = m[1].split('/').filter(Boolean);\n if (segments.length === 0) return null;\n // Permissioned space addresses must never be handed to a public explorer;\n // see the note in matchAturi. The literal is duplicated because this file is\n // copied verbatim into @aturi.to/waypoints.\n if (segments[1] === 'space') return null;\n const handle = segments[0];\n const collection = segments[1];\n const rkey = segments[2];\n const did = handle.startsWith('did:') ? handle : undefined;\n\n if (collection && rkey) {\n return {\n source: 'taproot',\n parsed: {\n type: inferType(collection),\n uri: `at://${handle}/${collection}/${rkey}`,\n handle,\n did,\n collection,\n rkey,\n },\n };\n }\n\n return {\n source: 'taproot',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\n/**\n * Aturi's own pages. Two URL spaces share the aturi.to host:\n * - `/explore/<identifier>[/<collection>[/<rkey>]]` — the raw record explorer\n * (source id `aturiExplore`).\n * - `/profile/<identifier>[/post/<rkey> | /lists/<rkey> | /<collection>/<rkey>]`\n * — the universal-link view (source id `aturi`).\n *\n * Detecting these lets the popup offer jumps to other clients and explorers\n * while you're already on Aturi. Reporting the source id as the matching\n * waypoint (`aturiExplore` vs `aturi`) also keeps the page you're on out of the\n * suggestion list.\n */\nfunction matchAturi(host: string, parts: string[]): ReverseMatch | null {\n if (host !== 'aturi.to') return null;\n\n // A repo identifier is always a DID (`did:…`) or a dotted handle. This rules\n // out the explorer's own sub-tools — `/explore/lexicons`, `/explore/pds` —\n // whose first segment is a bare word, not an account.\n const isIdentifier = (seg: string | undefined): boolean =>\n !!seg && (seg.startsWith('did:') || seg.includes('.'));\n\n // Explorer: /explore/<identifier>[/<collection>[/<rkey>]]\n if (parts[0] === 'explore' && isIdentifier(parts[1])) {\n // `/explore/<did>/space/…` addresses permissioned data. A match here would\n // be handed to the popup as a record other explorers can open, leaking the\n // address of private data to public tools, so the tab reads as\n // unrecognized instead. The marker is a local literal because this file is\n // copied verbatim into @aturi.to/waypoints, which cannot resolve\n // src/utils/atproto/*. A real NSID never equals `space` — it needs dots.\n if (parts[2] === 'space') return null;\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n const collection = parts[2];\n const rkey = parts[3];\n if (collection && rkey) {\n return {\n source: 'aturiExplore',\n parsed: {\n type: inferType(collection),\n uri: `at://${handle}/${collection}/${rkey}`,\n handle,\n did,\n collection,\n rkey,\n },\n };\n }\n // Repo browse or a collection listing (no rkey): treat as profile-level so\n // the popup offers profile waypoints for the identifier.\n return {\n source: 'aturiExplore',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n }\n\n // Universal-link view: /profile/<identifier>[/post|/lists|/<collection>/<rkey>]\n if (parts[0] === 'profile' && isIdentifier(parts[1])) {\n const handle = parts[1];\n const did = handle.startsWith('did:') ? handle : undefined;\n\n if (parts[2] === 'post' && parts[3]) {\n return {\n source: 'aturi',\n parsed: {\n type: 'post',\n uri: `at://${handle}/app.bsky.feed.post/${parts[3]}`,\n handle,\n did,\n collection: 'app.bsky.feed.post',\n rkey: parts[3],\n },\n };\n }\n\n if (parts[2] === 'lists' && parts[3]) {\n return {\n source: 'aturi',\n parsed: {\n type: 'list',\n uri: `at://${handle}/app.bsky.graph.list/${parts[3]}`,\n handle,\n did,\n collection: 'app.bsky.graph.list',\n rkey: parts[3],\n },\n };\n }\n\n // Generic record view: /profile/<identifier>/<collection>/<rkey>. Guard on\n // the dot so non-record profile subpages don't masquerade as records.\n if (parts[2] && parts[2].includes('.') && parts[3]) {\n return {\n source: 'aturi',\n parsed: {\n type: inferType(parts[2]),\n uri: `at://${handle}/${parts[2]}/${parts[3]}`,\n handle,\n did,\n collection: parts[2],\n rkey: parts[3],\n },\n };\n }\n\n return {\n source: 'aturi',\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n }\n\n return null;\n}\n\n/**\n * Reverse-match any supported Aturi waypoint site URL back into a structured\n * ParsedURI (handle/collection/rkey). Returns `null` if the URL isn't on a\n * supported site or isn't a shape we recognize.\n */\nexport function matchSupportedUrl(url: URL): ReverseMatch | null {\n const host = normalizeHost(url.hostname);\n const parts = url.pathname.split('/').filter(Boolean);\n const search = url.searchParams;\n\n return (\n matchAturi(host, parts) ||\n matchBlueskyFamily(host, parts) ||\n matchPinksky(host, parts, search) ||\n matchLeaflet(host, parts) ||\n matchTangled(host, parts) ||\n matchMargin(host, parts) ||\n matchPdsls(host, url.pathname) ||\n matchAtpTools(host, url.pathname) ||\n matchBluepy(host, url.pathname) ||\n matchSemble(host, parts) ||\n matchStreamplace(host, parts) ||\n matchGrain(host, parts) ||\n matchPopfeed(host, parts) ||\n matchSifa(host, parts) ||\n matchBlento(host, parts) ||\n matchStandardReader(host, parts) ||\n matchFlatRecordHost(host, parts, { host: 'offprint.app', source: 'offprint' }) ||\n matchFlatRecordHost(host, parts, { host: 'pckt.blog', source: 'pckt' }) ||\n matchTaproot(host, url.pathname)\n );\n}\n\n/**\n * Parse an AT URI string (e.g. \"at://did:plc:abc123/collection/rkey\") into\n * its components. Used by head-based detection when an AT URI is found in\n * a <link> tag's href attribute.\n */\nexport function parseAtUri(uri: string): ReverseMatch | null {\n if (!uri.startsWith('at://')) return null;\n const rest = uri.slice('at://'.length);\n const segments = rest.split('/').filter(Boolean);\n if (segments.length === 0) return null;\n // Permissioned space addresses must never be handed to a public explorer;\n // see the note in matchAturi. The literal is duplicated because this file is\n // copied verbatim into @aturi.to/waypoints.\n if (segments[1] === 'space') return null;\n\n const handle = segments[0];\n const did = handle.startsWith('did:') ? handle : undefined;\n const collection = segments[1];\n const rkey = segments[2];\n\n if (collection && rkey) {\n return {\n source: 'headDetected' as SourceApp,\n parsed: {\n type: inferType(collection),\n uri,\n handle,\n did,\n collection,\n rkey,\n },\n };\n }\n\n return {\n source: 'headDetected' as SourceApp,\n parsed: { type: 'profile', uri: `at://${handle}`, handle, did },\n };\n}\n\n/**\n * All host names we know how to reverse-parse. Used by the popup + background\n * worker to decide if a tab is \"relevant\" before doing more expensive work.\n */\nexport const SUPPORTED_HOSTS: string[] = [\n 'aturi.to',\n ...BLUESKY_FAMILY.flatMap(e => e.hosts),\n 'pinkleap.app',\n 'leaflet.pub',\n 'tangled.org',\n 'margin.at',\n 'pdsls.dev',\n 'atp.tools',\n 'bluepy.social',\n 'semble.so',\n 'stream.place',\n 'grain.social',\n 'popfeed.social',\n 'sifa.id',\n 'blento.app',\n 'standard-reader.app',\n 'offprint.app',\n 'pckt.blog',\n 'atproto.at',\n];\n\n/**\n * Whether a hostname belongs to a supported waypoint. Prefer this over a raw\n * `SUPPORTED_HOSTS.includes(...)` check: it strips a leading `www.` and also\n * recognizes subdomains of hosts that opt in (e.g. `eclose.anisota.net`), so\n * the extension popup and resolve API treat those tabs as known.\n */\nexport function isSupportedHost(host: string): boolean {\n const h = normalizeHost(host);\n if (SUPPORTED_HOSTS.includes(h)) return true;\n return SUBDOMAIN_HOSTS.some(base => isSubdomainOf(h, base));\n}\n","import {\n WAYPOINT_DESTINATIONS_DATA,\n WAYPOINT_ORDER,\n describeComposeIntent,\n getRecommendedWaypointsData,\n type ComposeIntentDescriptor,\n type WaypointType,\n} from './waypoints.data';\nimport {\n matchSupportedUrl,\n parseAtUri,\n type SourceApp,\n} from './reverseParsers';\nimport type { ParsedURI } from './uriParser';\n\nexport type ResolvedWaypoint = {\n id: string;\n name: string;\n category: string;\n url: string;\n /**\n * Whether this client can be handed a link that opens its composer, and how\n * to build one. Null when it has no confirmed compose intent route. Supply\n * `composeText` to get the links back pre-filled.\n */\n composeIntent: ComposeIntentDescriptor | null;\n};\n\nexport type ResolvedRecommendation = {\n ids: string[];\n label: string;\n};\n\nexport type ResolveResult = {\n parsed: ParsedURI;\n source: SourceApp;\n did: string | null;\n didResolved: boolean;\n waypoints: ResolvedWaypoint[];\n recommended: ResolvedRecommendation;\n};\n\n/**\n * Waypoints whose `getUrl` only produces a useful destination when a DID is\n * available. These are filtered out unless a DID is known. Mirrors the hosted\n * aturi.to/api/resolve route exactly.\n */\nexport const DID_REQUIRED_WAYPOINTS: ReadonlySet<string> = new Set([\n 'pdsls',\n 'atptools',\n 'margin',\n 'grain',\n 'popfeed',\n]);\n\nexport type BuildWaypointsOptions = {\n /** DID to pass to each waypoint's getUrl. Falls back to `parsed.did`. */\n did?: string;\n /** Waypoint id to omit (e.g. the source app the user is already on). */\n excludeSourceId?: string;\n /** Text to pre-fill into each waypoint's compose intent link, if it has one. */\n composeText?: string;\n};\n\n/**\n * Turn a parsed AT URI into the list of waypoints that can render it plus the\n * recommended set, applying the DID-required filter and dropping waypoints\n * whose getUrl returns null. This is the framework-agnostic core of the\n * hosted resolve endpoint.\n */\nexport function buildWaypointsForParsed(\n parsed: ParsedURI,\n options: BuildWaypointsOptions = {},\n): { waypoints: ResolvedWaypoint[]; recommended: ResolvedRecommendation } {\n const did = options.did ?? parsed.did;\n const exclude = options.excludeSourceId;\n const type: WaypointType = parsed.type === 'unknown' ? 'profile' : parsed.type;\n\n const waypoints = WAYPOINT_ORDER.map((id) => WAYPOINT_DESTINATIONS_DATA[id])\n .filter((w): w is NonNullable<typeof w> => !!w)\n .filter((w) => w.id !== exclude)\n .filter((w) => w.supportedTypes.includes(type))\n .map((w): ResolvedWaypoint | null => {\n if (DID_REQUIRED_WAYPOINTS.has(w.id) && !did) return null;\n const url = w.getUrl(parsed.handle, parsed.collection, parsed.rkey, did);\n if (!url) return null;\n return {\n id: w.id,\n name: w.name,\n category: w.category,\n url,\n composeIntent: describeComposeIntent(w, options.composeText),\n };\n })\n .filter((w): w is ResolvedWaypoint => !!w);\n\n const recommendedRaw = getRecommendedWaypointsData(type, parsed.collection);\n const availableIds = new Set(waypoints.map((w) => w.id));\n const ids = recommendedRaw.waypoints\n .map((w) => w.id)\n .filter((id) => id !== exclude && availableIds.has(id));\n\n return { waypoints, recommended: { ids, label: recommendedRaw.label } };\n}\n\n/**\n * Resolve an AT URI string (e.g. \"at://did:plc:abc/app.bsky.feed.post/rkey\")\n * directly into its waypoints. Returns null if the string isn't a valid AT URI.\n */\nexport function resolveAtUri(\n uri: string,\n options: Pick<BuildWaypointsOptions, 'composeText'> = {},\n): ResolveResult | null {\n const match = parseAtUri(uri);\n if (!match) return null;\n const { parsed, source } = match;\n const { waypoints, recommended } = buildWaypointsForParsed(parsed, {\n composeText: options.composeText,\n });\n return {\n parsed,\n source,\n did: parsed.did ?? null,\n didResolved: false,\n waypoints,\n recommended,\n };\n}\n\nexport type ResolveUrlOptions = {\n /**\n * When the URL pattern isn't recognized, fetch the page and look for a\n * `<link href=\"at://…\">` in <head>. Off by default to keep the resolver\n * isomorphic (no network unless explicitly requested).\n */\n fetchHead?: boolean;\n /** Timeout for the optional head probe. Defaults to 4000ms. */\n fetchHeadTimeoutMs?: number;\n /**\n * Resolve a handle to a DID so DID-only waypoints (pdsls, atptools, margin,\n * grain, popfeed) are included. Pass `resolveHandle` from this package, or\n * your own implementation.\n */\n resolveHandle?: (handle: string) => Promise<string | null>;\n /** Text to pre-fill into each waypoint's compose intent link, if it has one. */\n composeText?: string;\n};\n\n/**\n * Resolve a pasted/shared page URL back into the AT URI it represents and the\n * waypoints that can render it. Uses local URL-pattern matching by default;\n * optionally falls back to a `<head>` link probe and/or handle→DID resolution.\n *\n * The source app's own waypoint is omitted from the result (you're already\n * there), mirroring the extension popup and hosted endpoint.\n */\nexport async function resolveUrl(\n url: string | URL,\n options: ResolveUrlOptions = {},\n): Promise<ResolveResult | null> {\n let target: URL;\n try {\n target = typeof url === 'string' ? new URL(url) : url;\n } catch {\n return null;\n }\n if (!/^https?:$/.test(target.protocol)) return null;\n\n let match = matchSupportedUrl(target);\n if (!match && options.fetchHead) {\n const headUri = await detectAtUriInHead(\n target.toString(),\n options.fetchHeadTimeoutMs ?? 4000,\n );\n if (headUri) match = parseAtUri(headUri);\n }\n if (!match) return null;\n\n const { parsed, source } = match;\n let did = parsed.did;\n let didResolved = false;\n if (!did && options.resolveHandle) {\n try {\n const resolved = await options.resolveHandle(parsed.handle);\n if (resolved) {\n did = resolved;\n didResolved = true;\n }\n } catch {\n // Swallow; DID-required waypoints will simply be omitted from the result.\n }\n }\n\n const { waypoints, recommended } = buildWaypointsForParsed(parsed, {\n did,\n excludeSourceId: source,\n composeText: options.composeText,\n });\n return {\n parsed: { ...parsed, did },\n source,\n did: did ?? null,\n didResolved,\n waypoints,\n recommended,\n };\n}\n\nexport type ResolveApiInput = {\n url?: string;\n atUri?: string;\n /** Set false to skip the server-side <head> probe. */\n headDetect?: boolean;\n /** Text to pre-fill into the returned compose intent links. */\n composeText?: string;\n};\n\nexport type ResolveApiParsed = {\n type: WaypointType;\n uri: string;\n handle: string;\n did: string | null;\n collection: string | null;\n rkey: string | null;\n};\n\nexport type ResolveApiSuccess = {\n ok: true;\n inputKind: 'atUri' | 'url';\n /**\n * How the endpoint found the AT URI. `atTags` means the page declared it\n * itself via `<meta name=\"at:canonical\">` (or `at:alternate`); `headLink` is\n * the older `<link href=\"at://…\">` the same probe falls back to.\n */\n detectedVia: 'atUri' | 'urlPattern' | 'atTags' | 'headLink' | null;\n source: SourceApp;\n isKnownHost: boolean;\n parsed: ResolveApiParsed;\n didResolved: boolean;\n recommended: ResolvedRecommendation;\n waypoints: ResolvedWaypoint[];\n};\n\nexport type ResolveApiFailure = {\n ok: false;\n input?: string | null;\n inputKind?: 'atUri' | 'url';\n isKnownHost?: boolean;\n reason?: string;\n message?: string;\n error?: string;\n};\n\nexport type ResolveApiResponse = ResolveApiSuccess | ResolveApiFailure;\n\nexport type ResolveViaApiOptions = {\n /** Defaults to the hosted endpoint, https://aturi.to/api/resolve. */\n endpoint?: string;\n /** Custom fetch implementation (e.g. a polyfill or instrumented client). */\n fetch?: typeof fetch;\n signal?: AbortSignal;\n};\n\n/**\n * Typed client for the hosted resolve endpoint. Use this when you want the\n * server to do the work — notably the <head> link probe, which needs to fetch\n * the target page (something you may not want to do from the browser for CORS\n * reasons). Returns the same response shape the route emits.\n */\nexport async function resolveViaApi(\n input: ResolveApiInput,\n options: ResolveViaApiOptions = {},\n): Promise<ResolveApiResponse> {\n const endpoint = options.endpoint ?? 'https://aturi.to/api/resolve';\n const fetchImpl = options.fetch ?? fetch;\n const params = new URLSearchParams();\n if (input.atUri) {\n params.set('atUri', input.atUri);\n } else if (input.url) {\n params.set('url', input.url);\n } else {\n throw new Error('resolveViaApi requires either `url` or `atUri`');\n }\n if (input.headDetect === false) params.set('headDetect', 'false');\n if (input.composeText) params.set('composeText', input.composeText);\n\n const res = await fetchImpl(`${endpoint}?${params.toString()}`, {\n method: 'GET',\n headers: { Accept: 'application/json' },\n signal: options.signal,\n });\n return (await res.json()) as ResolveApiResponse;\n}\n\n/**\n * Best-effort <head> probe for a `<link href=\"at://…\">`. Reads the response as\n * text, scans the document head, and returns the first AT URI found. Returns\n * null on any error, non-HTML content, or timeout.\n */\nasync function detectAtUriInHead(\n url: string,\n timeoutMs: number,\n): Promise<string | null> {\n if (typeof fetch === 'undefined') return null;\n const controller =\n typeof AbortController !== 'undefined' ? new AbortController() : null;\n const timeout = controller\n ? setTimeout(() => controller.abort(), timeoutMs)\n : null;\n try {\n const response = await fetch(url, {\n signal: controller?.signal,\n redirect: 'follow',\n headers: {\n 'User-Agent':\n 'Mozilla/5.0 (compatible; AturiResolver/1.0; +https://aturi.to)',\n Accept:\n 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.5',\n },\n });\n if (!response.ok) return null;\n\n const ct = response.headers.get('content-type') || '';\n if (!/text\\/html|application\\/xhtml/i.test(ct)) return null;\n\n const html = await response.text();\n const headMatch = html.match(/<head[\\s\\S]*?<\\/head>/i);\n const haystack = headMatch ? headMatch[0] : html.slice(0, 256 * 1024);\n const linkRe =\n /<link\\b[^>]*\\bhref\\s*=\\s*[\"'](at:\\/\\/[^\"']+)[\"'][^>]*>/gi;\n let m: RegExpExecArray | null;\n while ((m = linkRe.exec(haystack)) !== null) {\n if (m[1].startsWith('at://')) return m[1];\n }\n return null;\n } catch {\n return null;\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n}\n","import { matchSupportedUrl, parseAtUri } from './reverseParsers';\nimport type { ParsedURI } from './uriParser';\nimport type { WaypointType } from './waypoints.data';\n\n/**\n * Universal links: the aturi.to URL for a record or an identity.\n *\n * A universal link is the client-agnostic address of an atproto record. Drop\n * one anywhere and the recipient lands on a preview of the record and picks\n * the client they want to open it in, instead of being pushed into whichever\n * app the sender happened to use.\n *\n * This module is the whole round trip:\n * - `buildUniversalLink` returns that address for anything that names a\n * record: an AT URI, a handle, a DID, a URL from any client in the catalog.\n * - `parseUniversalLink` turns one back into a `ParsedURI`.\n * - `describeUniversalLink` adds the strings a share sheet or a copy button\n * needs (a label, a `navigator.share()` payload, markdown/HTML snippets).\n * - `buildUniversalLinkTags` emits the `<head>` tags that let *other* apps\n * be resolved back into records, the read side of the same trip.\n *\n * Everything here is pure and synchronous. Nothing fetches.\n */\n\n/** Where universal links point unless an `origin` says otherwise. */\nexport const UNIVERSAL_LINK_ORIGIN = 'https://aturi.to';\n\n/**\n * The hosted oEmbed endpoint. Only `app.bsky.feed.post` records render, so\n * the oEmbed pointer is omitted for everything else rather than advertising a\n * URL that 404s.\n */\nconst OEMBED_PATH = '/api/oembed';\nconst OEMBED_COLLECTION = 'app.bsky.feed.post';\n\n/** The oEmbed link `type` attribute, per the spec's discovery section. */\nexport const OEMBED_LINK_TYPE = 'application/json+oembed';\n\n/**\n * Anything that names a record or an identity:\n * - an AT URI (`at://did:plc:abc/app.bsky.feed.post/3k7`)\n * - a bare handle or DID (`alice.bsky.social`, `@alice.bsky.social`, `did:plc:abc`)\n * - a scheme-less AT URI (`alice.bsky.social/app.bsky.feed.post/3k7`)\n * - a page URL from any client in the catalog, an aturi.to link included\n * - a `ParsedURI` you already have from `parseURI` / `matchSupportedUrl`\n */\nexport type UniversalLinkTarget = string | ParsedURI;\n\nexport type UniversalLinkOptions = {\n /**\n * Origin to build against. Defaults to aturi.to; point it at your own\n * deployment if you run a fork. Trailing slashes are trimmed.\n */\n origin?: string;\n /**\n * DID for the target, for input that only carries a handle. Handle → DID\n * resolution is a network call, so this package never does it for you:\n * pass `resolveHandle`'s result if you want DID-stable links.\n */\n did?: string;\n /**\n * Address every link by DID instead of handle. A handle can be reassigned\n * to another identity; a DID is stable for the life of the account, so a\n * DID link never rots. Ignored when no DID is known.\n */\n preferDid?: boolean;\n /** Query parameters to append, e.g. `{ ref: 'my-app' }`. Empty values are dropped. */\n params?: Record<string, string | number | boolean | null | undefined>;\n};\n\n/** `navigator.share()`'s payload, which most native share sheets also accept. */\nexport type UniversalLinkSharePayload = {\n title: string;\n text: string;\n url: string;\n};\n\n/** Ready-to-paste forms of the same link. */\nexport type UniversalLinkSnippets = {\n url: string;\n atUri: string;\n markdown: string;\n html: string;\n};\n\nexport type UniversalLink = {\n url: string;\n atUri: string;\n type: WaypointType;\n handle: string;\n did: string | null;\n collection: string | null;\n rkey: string | null;\n /** Human label for the target, e.g. `Post by @alice.bsky.social`. */\n label: string;\n share: UniversalLinkSharePayload;\n snippets: UniversalLinkSnippets;\n /** oEmbed endpoint for this link, or null for anything that isn't a post. */\n oembedUrl: string | null;\n};\n\nexport type DescribeUniversalLinkOptions = UniversalLinkOptions & {\n /** Override the share sheet's title. Defaults to the label. */\n title?: string;\n /** Override the share sheet's text. Defaults to the label. */\n text?: string;\n};\n\nexport type UniversalLinkMetaTag = { name: string; content: string };\nexport type UniversalLinkLinkTag = { rel: string; href: string; type?: string };\n\nexport type UniversalLinkTags = {\n meta: UniversalLinkMetaTag[];\n link: UniversalLinkLinkTag[];\n /** The same tags as a ready-to-paste `<head>` fragment. */\n html: string;\n};\n\n/**\n * Build the aturi.to link for a target. Returns null for input that doesn't\n * name a record or an identity.\n *\n * ```ts\n * buildUniversalLink('at://did:plc:abc/app.bsky.feed.post/3k7');\n * // 'https://aturi.to/profile/did:plc:abc/post/3k7'\n * buildUniversalLink('https://bsky.app/profile/alice.bsky.social/post/3k7');\n * // 'https://aturi.to/profile/alice.bsky.social/post/3k7'\n * ```\n */\nexport function buildUniversalLink(\n input: UniversalLinkTarget,\n options: UniversalLinkOptions = {},\n): string | null {\n const parsed = parseTarget(input);\n if (!parsed) return null;\n\n const origin = normalizeOrigin(options.origin);\n const did = options.did ?? parsed.did;\n const { collection, rkey } = parsed;\n\n // Deliberately the same shape the `aturi` waypoint's own `getUrl` produces,\n // so a link copied out of the catalog and a link built here are the same\n // string: posts and lists take the friendly `/post/` and `/lists/` aliases\n // and keep whichever identifier they were given, while the generic record\n // route prefers a DID when one is known. `preferDid` overrides all of it.\n const identifier = options.preferDid && did ? did : parsed.handle;\n\n let path: string;\n if (collection && rkey) {\n if (collection === 'app.bsky.feed.post') {\n path = `/profile/${seg(identifier)}/post/${seg(rkey)}`;\n } else if (collection === 'app.bsky.graph.list') {\n path = `/profile/${seg(identifier)}/lists/${seg(rkey)}`;\n } else {\n path = `/profile/${seg(did || parsed.handle)}/${seg(collection)}/${seg(rkey)}`;\n }\n } else {\n path = `/profile/${seg(identifier)}`;\n }\n\n return `${origin}${path}${queryString(options.params)}`;\n}\n\n/**\n * Turn an aturi.to URL back into the record it addresses. Accepts every shape\n * the site serves: the canonical `/profile/…` links, the `/explore/…` record\n * views, the legacy bare-path (`aturi.to/{handle}/{collection}/{rkey}`) and\n * `at://`-in-path forms. Returns null for any other host or path.\n */\nexport function parseUniversalLink(\n url: string | URL,\n options: Pick<UniversalLinkOptions, 'origin'> = {},\n): ParsedURI | null {\n let target: URL;\n try {\n target = typeof url === 'string' ? new URL(url.trim()) : url;\n } catch {\n return null;\n }\n if (!/^https?:$/.test(target.protocol)) return null;\n\n let expectedHost: string;\n try {\n expectedHost = bareHost(new URL(normalizeOrigin(options.origin)).hostname);\n } catch {\n return null;\n }\n if (bareHost(target.hostname) !== expectedHost) return null;\n\n // The catalog's reverse parsers key off the aturi.to hostname, so a link\n // from a fork's own origin is rewritten onto it before matching. The host\n // has already been checked against `origin` above.\n const probe = new URL(target.toString());\n probe.protocol = 'https:';\n probe.hostname = 'aturi.to';\n probe.port = '';\n\n const match = matchSupportedUrl(probe);\n if (match && (match.source === 'aturi' || match.source === 'aturiExplore')) {\n return normalizeParsed(match.parsed);\n }\n\n return parseEmbeddedAtUri(probe.pathname) ?? parsePath(probe.pathname);\n}\n\n/** Whether a URL is an aturi.to link this package can resolve to a record. */\nexport function isUniversalLink(\n url: string | URL,\n options: Pick<UniversalLinkOptions, 'origin'> = {},\n): boolean {\n return parseUniversalLink(url, options) !== null;\n}\n\n/**\n * Everything a copy button or a share sheet needs for one target: the link\n * itself, a human label, a `navigator.share()` payload, and the link in the\n * forms people paste it in.\n *\n * ```ts\n * const link = describeUniversalLink('at://did:plc:abc/app.bsky.feed.post/3k7');\n * await navigator.share(link.share);\n * await navigator.clipboard.writeText(link.snippets.markdown);\n * ```\n */\nexport function describeUniversalLink(\n input: UniversalLinkTarget,\n options: DescribeUniversalLinkOptions = {},\n): UniversalLink | null {\n const parsed = parseTarget(input);\n if (!parsed) return null;\n const url = buildUniversalLink(parsed, options);\n if (!url) return null;\n\n const did = options.did ?? parsed.did ?? null;\n const collection = parsed.collection ?? null;\n const rkey = parsed.rkey ?? null;\n // A caller who supplies a DID gets AT URIs addressed by it, the canonical\n // rename-proof form. Without one, the input's own identifier is echoed back\n // rather than silently changing what was passed in.\n const authority = did ?? parsed.handle;\n const atUri = collection && rkey\n ? `at://${authority}/${collection}/${rkey}`\n : `at://${authority}`;\n const label = describeTarget(parsed);\n\n return {\n url,\n atUri,\n type: parsed.type,\n handle: parsed.handle,\n did,\n collection,\n rkey,\n label,\n share: {\n title: options.title ?? label,\n text: options.text ?? label,\n url,\n },\n snippets: {\n url,\n atUri,\n markdown: `[${label}](${url})`,\n html: `<a href=\"${escapeHtml(url)}\">${escapeHtml(label)}</a>`,\n },\n oembedUrl: buildOEmbedUrl(url, collection, options.origin),\n };\n}\n\n/**\n * `<head>` tags that connect a page to the record it renders, so the rest of\n * the Atmosphere can find its way back. Two consumers today:\n *\n * - `<meta name=\"at:canonical\">` is the AT Tags proposal\n * (https://tangled.org/chrisshank.com/at-tags/). Aturi's browser extension\n * reads it off the live page and `aturi.to/api/resolve` reads it off the\n * HTML, which is what turns your URL into \"…and here are the 25 other\n * clients that can open this\". The `<link rel=\"alternate\" href=\"at://…\">`\n * alongside it is the older spelling of the same declaration, kept because\n * the resolver still falls back to it.\n * - `<link type=\"application/json+oembed\">` points unfurlers at the hosted\n * oEmbed endpoint, so a link to your page previews as the post it is.\n * Emitted for posts only, since that's all the endpoint renders.\n *\n * Serving these does not hand anything to aturi.to; they're static strings\n * describing a record you already display.\n */\nexport function buildUniversalLinkTags(\n input: UniversalLinkTarget,\n options: UniversalLinkOptions = {},\n): UniversalLinkTags | null {\n const described = describeUniversalLink(input, options);\n if (!described) return null;\n\n const meta: UniversalLinkMetaTag[] = [\n { name: 'at:canonical', content: described.atUri },\n ];\n // A record lives in its author's repo, so the repo identifier *is* the\n // author. For a profile the canonical tag already says so; a second tag\n // naming the same identity would be noise.\n if (described.collection && described.rkey) {\n meta.push({\n name: 'at:author',\n content: `at://${described.did ?? described.handle}`,\n });\n }\n\n const link: UniversalLinkLinkTag[] = [\n { rel: 'alternate', href: described.atUri },\n ];\n if (described.oembedUrl) {\n link.push({\n rel: 'alternate',\n type: OEMBED_LINK_TYPE,\n href: described.oembedUrl,\n });\n }\n\n const html = [\n ...meta.map(\n (tag) =>\n `<meta name=\"${escapeHtml(tag.name)}\" content=\"${escapeHtml(tag.content)}\" />`,\n ),\n ...link.map((tag) => {\n const type = tag.type ? ` type=\"${escapeHtml(tag.type)}\"` : '';\n return `<link rel=\"${escapeHtml(tag.rel)}\"${type} href=\"${escapeHtml(tag.href)}\" />`;\n }),\n ].join('\\n');\n\n return { meta, link, html };\n}\n\n/**\n * Coerce any accepted target into a `ParsedURI`. Order matters: AT URIs and\n * page URLs are unambiguous, so they're tried first, and the loose bare-input\n * forms only get a look once those have declined.\n */\nfunction parseTarget(input: UniversalLinkTarget): ParsedURI | null {\n if (typeof input !== 'string') {\n return input && input.handle ? normalizeParsed(input) : null;\n }\n\n const trimmed = input.trim();\n if (!trimmed) return null;\n\n if (trimmed.toLowerCase().startsWith('at://')) {\n const parsed = parseAtUri(trimmed)?.parsed;\n return parsed ? normalizeParsed(parsed) : null;\n }\n\n if (/^https?:\\/\\//i.test(trimmed)) {\n let target: URL;\n try {\n target = new URL(trimmed);\n } catch {\n return null;\n }\n // Any host can carry an AT URI in its path: `example.com/at://did:plc:…`,\n // and the single-slash `at:/…` spelling servers and browsers normalize it\n // to. Checked before the catalog's URL patterns because a host in the\n // catalog can serve both shapes.\n const embedded = parseEmbeddedAtUri(target.pathname);\n if (embedded) return embedded;\n const matched = matchSupportedUrl(target)?.parsed;\n return matched ? normalizeParsed(matched) : null;\n }\n\n // Bare identifiers and scheme-less AT URIs.\n return parsePath(trimmed.startsWith('@') ? trimmed.slice(1) : trimmed);\n}\n\n/**\n * Parse `{identifier}[/{collection}/{rkey}]`, the shape shared by a bare\n * handle, a scheme-less AT URI, and aturi.to's legacy bare paths. The\n * identifier must look like a DID or a dotted handle, which is what keeps\n * ordinary site paths (`/docs`, `/explore/lexicons`) from parsing as repos.\n */\nfunction parsePath(path: string): ParsedURI | null {\n const segments = path.split('/').filter(Boolean);\n const handle = decodeSegment(segments[0] ?? '');\n if (!handle) return null;\n if (!handle.startsWith('did:') && !handle.includes('.')) return null;\n\n // Parsed from the raw segments so an escaped character can never be mistaken\n // for a path separator, then decoded on the way out.\n const parsed = parseAtUri(`at://${segments.join('/')}`)?.parsed;\n if (!parsed) return null;\n\n const collection = parsed.collection\n ? decodeSegment(parsed.collection)\n : undefined;\n const rkey = parsed.rkey ? decodeSegment(parsed.rkey) : undefined;\n return {\n ...parsed,\n handle,\n did: handle.startsWith('did:') ? handle : undefined,\n collection,\n rkey,\n uri:\n collection && rkey\n ? `at://${handle}/${collection}/${rkey}`\n : `at://${handle}`,\n };\n}\n\n/**\n * An `@` in front of a handle is display sugar, never part of the identifier,\n * but some clients put it in the path (`tangled.org/@alice.example`), so the\n * catalog's reverse parsers hand it back attached. Strip it before it reaches\n * a URL, where it would be escaped to `%40` and address nobody.\n */\nfunction normalizeParsed(parsed: ParsedURI): ParsedURI {\n if (!parsed.handle.startsWith('@')) return parsed;\n const handle = parsed.handle.slice(1);\n if (!handle) return parsed;\n return {\n ...parsed,\n handle,\n uri:\n parsed.collection && parsed.rkey\n ? `at://${handle}/${parsed.collection}/${parsed.rkey}`\n : `at://${handle}`,\n };\n}\n\n/** Pull `at://…` out of a URL path that embeds one. */\nfunction parseEmbeddedAtUri(pathname: string): ParsedURI | null {\n const match = /^\\/at:\\/{1,2}(.+)$/i.exec(pathname);\n if (!match) return null;\n return parsePath(match[1]);\n}\n\nfunction buildOEmbedUrl(\n url: string,\n collection: string | null,\n origin?: string,\n): string | null {\n if (collection !== OEMBED_COLLECTION) return null;\n return `${normalizeOrigin(origin)}${OEMBED_PATH}?url=${encodeURIComponent(url)}`;\n}\n\nfunction describeTarget(parsed: ParsedURI): string {\n const who = parsed.handle.startsWith('did:')\n ? parsed.handle\n : `@${parsed.handle}`;\n if (parsed.type === 'post') return `Post by ${who}`;\n if (parsed.type === 'list') return `List by ${who}`;\n if (parsed.collection) return `${parsed.collection} record by ${who}`;\n return who;\n}\n\nfunction normalizeOrigin(origin?: string): string {\n if (!origin) return UNIVERSAL_LINK_ORIGIN;\n return origin.trim().replace(/\\/+$/, '') || UNIVERSAL_LINK_ORIGIN;\n}\n\n/** Hostnames compare without a `www.` prefix; aturi.to serves both. */\nfunction bareHost(hostname: string): string {\n return hostname.toLowerCase().replace(/^www\\./, '');\n}\n\n/**\n * Percent-encode a path segment without touching the characters atproto\n * identifiers are made of. `encodeURIComponent` would turn the colons in\n * `did:plc:…` into `%3A`, and these routes serve DIDs unencoded, so an encoded\n * one points at a URL that doesn't exist. DIDs, NSIDs and record keys are\n * drawn from alphabets that need no escaping, so they pass through\n * byte-identical; anything else still gets escaped rather than forming a\n * broken URL.\n */\nfunction seg(value: string): string {\n return encodeURIComponent(value).replace(/%3A/gi, ':');\n}\n\nfunction decodeSegment(value: string): string {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n\nfunction queryString(params?: UniversalLinkOptions['params']): string {\n if (!params) return '';\n const search = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n if (value === null || value === undefined || value === '') continue;\n search.set(key, String(value));\n }\n const query = search.toString();\n return query ? `?${query}` : '';\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n"]}
|