JavaScript-optional public web frontend for Bluesky anartia.kelinci.net
sveltekit atcute bluesky typescript svelte

refactor: use resolve() for redirector

mary.my.id cb05704a 79856230

verified
Changed files
+77 -29
src
+77 -29
src/lib/redirector.ts
··· 1 - import { base } from '$app/paths'; 1 + import { resolve } from '$app/paths'; 2 2 3 - import { isDid, isHandle, isRecordKey, isTid, parseResourceUri } from '@atcute/lexicons/syntax'; 3 + import { isActorIdentifier, isRecordKey, isTid, parseResourceUri } from '@atcute/lexicons/syntax'; 4 4 5 5 import { 6 6 BSKY_FEED_LINK_RE, ··· 38 38 if ((match = BSKY_PROFILE_LINK_RE.exec(pathname))) { 39 39 const [, actor] = match; 40 40 41 - if (!isHandle(actor) && !isDid(actor)) { 41 + if (!isActorIdentifier(actor)) { 42 42 return null; 43 43 } 44 44 45 - return { type: 'internal', url: `${base}/${match[1]}` }; 45 + return { 46 + type: 'internal', 47 + url: resolve('/(app)/(profile)/[actor=didOrHandle]/(timeline)', { actor: match[1] }), 48 + }; 46 49 } 47 50 48 51 if ((match = BSKY_POST_LINK_RE.exec(pathname))) { 49 52 const [, actor, rkey] = match; 50 53 51 - if (!isHandle(actor) && !isDid(actor)) { 54 + if (!isActorIdentifier(actor)) { 52 55 return null; 53 56 } 54 57 if (!isTid(rkey)) { 55 58 return null; 56 59 } 57 60 58 - return { type: 'internal', url: `${base}/${actor}/${rkey}#main` }; 61 + return { 62 + type: 'internal', 63 + url: resolve('/(app)/[actor=did]/[rkey=tid]', { actor, rkey }) + `#main`, 64 + }; 59 65 } 60 66 61 67 if ((match = BSKY_FEED_LINK_RE.exec(pathname))) { 62 68 const [, actor, rkey] = match; 63 69 64 - if (!isHandle(actor) && !isDid(actor)) { 70 + if (!isActorIdentifier(actor)) { 65 71 return null; 66 72 } 67 73 if (!isRecordKey(rkey)) { 68 74 return null; 69 75 } 70 76 71 - return { type: 'internal', url: `${base}/${actor}/feeds/${rkey}` }; 77 + return { 78 + type: 'internal', 79 + url: resolve('/(app)/[actor=didOrHandle]/feeds/[rkey=rkey]', { actor, rkey }), 80 + }; 72 81 } 73 82 74 83 if ((match = BSKY_LIST_LINK_RE.exec(pathname))) { 75 84 const [, actor, rkey] = match; 76 85 77 - if (!isHandle(actor) && !isDid(actor)) { 86 + if (!isActorIdentifier(actor)) { 78 87 return null; 79 88 } 80 89 if (!isRecordKey(rkey)) { 81 90 return null; 82 91 } 83 92 84 - return { type: 'internal', url: `${base}/${actor}/lists/${rkey}` }; 93 + return { 94 + type: 'internal', 95 + url: resolve('/(app)/[actor=didOrHandle]/lists/[rkey=rkey]', { actor, rkey }), 96 + }; 85 97 } 86 98 87 99 if ((match = BSKY_STARTERPACK_LINK_RE.exec(pathname))) { 88 100 const [, _page, actor, rkey] = match; 89 101 90 - if (!isHandle(actor) && !isDid(actor)) { 102 + if (!isActorIdentifier(actor)) { 91 103 return null; 92 104 } 93 105 if (!isRecordKey(rkey)) { 94 106 return null; 95 107 } 96 108 97 - return { type: 'internal', url: `${base}/${actor}/packs/${rkey}` }; 109 + return { 110 + type: 'internal', 111 + url: resolve('/(app)/[actor=didOrHandle]/packs/[rkey=rkey]', { actor, rkey }), 112 + }; 98 113 } 99 114 100 115 if ((match = BSKY_SEARCH_LINK_RE.exec(pathname))) { ··· 103 118 return null; 104 119 } 105 120 106 - return { type: 'internal', url: `${base}/search/posts?q=${encodeURIComponent(query)}` }; 121 + return { 122 + type: 'internal', 123 + url: resolve('/(app)/search/posts') + `?q=${encodeURIComponent(query)}`, 124 + }; 107 125 } 108 126 109 127 if ((match = BSKY_HASHTAG_LINK_RE.exec(pathname))) { 110 128 const [, tag] = match; 111 129 112 - return { type: 'internal', url: `${base}/search/posts?q=${encodeURIComponent('#' + tag)}` }; 130 + return { 131 + type: 'internal', 132 + url: resolve('/(app)/search/posts') + `?q=${encodeURIComponent('#' + tag)}`, 133 + }; 113 134 } 114 135 115 136 return null; ··· 133 154 if ((match = BSKY_GO_SHORTLINK_RE.exec(pathname))) { 134 155 const [, id] = match; 135 156 136 - return { type: 'internal', url: `${base}/go/${id}` }; 157 + return { 158 + type: 'internal', 159 + url: resolve('/go/[shortid]', { shortid: id }), 160 + }; 137 161 } 138 162 } 139 163 ··· 149 173 let match: RegExpExecArray | null | undefined; 150 174 151 175 if (host === 'blue.mackuba.eu' && pathname === '/skythread/') { 152 - const author = url.searchParams.get('author'); 153 - const post = url.searchParams.get('post'); 176 + const actor = url.searchParams.get('author'); 177 + const rkey = url.searchParams.get('post'); 154 178 155 - if (author === null || post === null) { 179 + if (actor === null || rkey === null) { 156 180 return null; 157 181 } 158 182 159 - if (!isHandle(author) && !isDid(author)) { 183 + if (!isActorIdentifier(actor)) { 160 184 return null; 161 185 } 162 - if (!isTid(post)) { 186 + if (!isTid(rkey)) { 163 187 return null; 164 188 } 165 189 166 - return { type: 'internal', url: `${base}/${author}/${post}#main` }; 190 + return { 191 + type: 'internal', 192 + url: resolve('/(app)/[actor=did]/[rkey=tid]', { actor, rkey }) + `#main`, 193 + }; 167 194 } 168 195 169 196 if (host === 'skywriter.blue') { 170 197 if ((match = SKYWRITER_UNROLL_RE.exec(pathname))) { 171 198 const [, actor, rkey] = match; 172 199 173 - if (!isHandle(actor) && !isDid(actor)) { 200 + if (!isActorIdentifier(actor)) { 174 201 return null; 175 202 } 176 203 if (!isTid(rkey)) { 177 204 return null; 178 205 } 179 206 180 - return { type: 'internal', url: `${base}/${actor}/${rkey}/unroll` }; 207 + return { 208 + type: 'internal', 209 + url: resolve('/(app)/[actor=did]/[rkey=tid]/unroll', { actor, rkey }), 210 + }; 181 211 } 182 212 } 183 213 ··· 215 245 if (uri.rkey) { 216 246 switch (uri.collection) { 217 247 case 'app.bsky.actor.profile': { 218 - return { type: 'internal', url: `${base}/${uri.repo}` }; 248 + return { 249 + type: 'internal', 250 + url: resolve('/(app)/(profile)/[actor=didOrHandle]/(timeline)', { actor: uri.repo }), 251 + }; 219 252 } 220 253 case 'app.bsky.feed.post': { 221 254 if (!isTid(uri.rkey)) { 222 255 return null; 223 256 } 224 257 225 - return { type: 'internal', url: `${base}/${uri.repo}/${uri.rkey}#main` }; 258 + return { 259 + type: 'internal', 260 + url: resolve('/(app)/[actor=did]/[rkey=tid]', { actor: uri.repo, rkey: uri.rkey }) + `#main`, 261 + }; 226 262 } 227 263 case 'app.bsky.feed.generator': { 228 - return { type: 'internal', url: `${base}/${uri.repo}/feeds/${uri.rkey}` }; 264 + return { 265 + type: 'internal', 266 + url: resolve('/(app)/[actor=didOrHandle]/feeds/[rkey=rkey]', { actor: uri.repo, rkey: uri.rkey }), 267 + }; 229 268 } 230 269 case 'app.bsky.graph.list': { 231 - return { type: 'internal', url: `${base}/${uri.repo}/lists/${uri.rkey}` }; 270 + return { 271 + type: 'internal', 272 + url: resolve('/(app)/[actor=didOrHandle]/lists/[rkey=rkey]', { actor: uri.repo, rkey: uri.rkey }), 273 + }; 232 274 } 233 275 case 'app.bsky.graph.starterpack': { 234 - return { type: 'internal', url: `${base}/${uri.repo}/packs/${uri.rkey}` }; 276 + return { 277 + type: 'internal', 278 + url: resolve('/(app)/[actor=didOrHandle]/packs/[rkey=rkey]', { actor: uri.repo, rkey: uri.rkey }), 279 + }; 235 280 } 236 281 } 237 282 } 238 283 239 284 if (uri.collection === undefined) { 240 - return { type: 'internal', url: `${base}/${uri.repo}` }; 285 + return { 286 + type: 'internal', 287 + url: resolve('/(app)/(profile)/[actor=didOrHandle]/(timeline)', { actor: uri.repo }), 288 + }; 241 289 } 242 290 243 291 return null;