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