feedscout 2.0.0-next.2 → 2.0.0-rc.2
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 +1 -1
- package/dist/blogrolls.d.ts +4 -4
- package/dist/blogrolls.js +3 -3
- package/dist/favicons.d.ts +3 -3
- package/dist/favicons.js +2 -2
- package/dist/feeds.d.ts +4 -4
- package/dist/feeds.js +3 -3
- package/dist/hubs.d.ts +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.js +6 -6
- package/dist/methods.d.ts +7 -7
- package/dist/methods.js +7 -7
- package/dist/node_modules/trousse/dist/arrays.js +9 -0
- package/dist/node_modules/trousse/dist/is.js +19 -0
- package/dist/node_modules/trousse/dist/matching.js +37 -0
- package/dist/node_modules/trousse/dist/urls.js +23 -0
- package/dist/{blogrolls → src/blogrolls}/defaults.d.ts +1 -2
- package/dist/{blogrolls → src/blogrolls}/defaults.js +19 -11
- package/dist/{blogrolls → src/blogrolls}/extractors.js +3 -2
- package/dist/{common → src/common}/discover/defaults.js +1 -3
- package/dist/{common → src/common}/discover/index.js +23 -10
- package/dist/{common → src/common}/discover/utils.js +10 -3
- package/dist/src/common/locales.js +337 -0
- package/dist/{common → src/common}/types.d.ts +9 -1
- package/dist/{common → src/common}/uris/feed/index.js +1 -1
- package/dist/src/common/uris/guess/index.js +16 -0
- package/dist/{common → src/common}/uris/guess/types.d.ts +3 -0
- package/dist/{common → src/common}/uris/guess/utils.d.ts +2 -1
- package/dist/src/common/uris/guess/utils.js +83 -0
- package/dist/src/common/uris/headers/index.js +14 -0
- package/dist/{common → src/common}/uris/html/handlers.js +18 -1
- package/dist/{common → src/common}/uris/html/index.js +17 -1
- package/dist/src/common/uris/html/types.d.ts +14 -0
- package/dist/src/common/utils.js +51 -0
- package/dist/{favicons → src/favicons}/defaults.js +1 -1
- package/dist/{favicons → src/favicons}/extractors.js +3 -8
- package/dist/{favicons → src/favicons}/platform/handlers/bluesky.js +3 -2
- package/dist/{favicons → src/favicons}/platform/handlers/codeberg.js +2 -1
- package/dist/{favicons → src/favicons}/platform/handlers/deviantart.js +2 -1
- package/dist/{favicons → src/favicons}/platform/handlers/devto.js +4 -2
- package/dist/{favicons → src/favicons}/platform/handlers/github.js +2 -1
- package/dist/{favicons → src/favicons}/platform/handlers/githubGist.js +2 -1
- package/dist/{favicons → src/favicons}/platform/handlers/gitlab.js +4 -2
- package/dist/{favicons → src/favicons}/platform/handlers/lobsters.js +1 -1
- package/dist/{favicons → src/favicons}/platform/handlers/mastodon.js +2 -1
- package/dist/{favicons → src/favicons}/platform/handlers/reddit.js +3 -2
- package/dist/{favicons → src/favicons}/platform/handlers/sourceforge.js +1 -1
- package/dist/{favicons → src/favicons}/platform/handlers/tumblr.js +1 -1
- package/dist/{favicons → src/favicons}/utils.js +1 -4
- package/dist/{feeds → src/feeds}/defaults.d.ts +6 -3
- package/dist/src/feeds/defaults.js +300 -0
- package/dist/{feeds → src/feeds}/extractors.js +3 -2
- package/dist/src/feeds/platform/handlers/acast.js +28 -0
- package/dist/src/feeds/platform/handlers/ameblo.js +38 -0
- package/dist/{feeds → src/feeds}/platform/handlers/applePodcasts.js +3 -2
- package/dist/src/feeds/platform/handlers/arena.js +44 -0
- package/dist/src/feeds/platform/handlers/artstation.js +54 -0
- package/dist/src/feeds/platform/handlers/audioboom.js +24 -0
- package/dist/src/feeds/platform/handlers/bearblog.js +46 -0
- package/dist/{feeds → src/feeds}/platform/handlers/behance.js +10 -1
- package/dist/src/feeds/platform/handlers/blogspot.js +72 -0
- package/dist/{feeds → src/feeds}/platform/handlers/bluesky.js +2 -1
- package/dist/src/feeds/platform/handlers/bookwyrm.js +48 -0
- package/dist/src/feeds/platform/handlers/buttondown.js +45 -0
- package/dist/src/feeds/platform/handlers/buzzsprout.js +23 -0
- package/dist/{feeds → src/feeds}/platform/handlers/codeberg.js +8 -6
- package/dist/{feeds → src/feeds}/platform/handlers/csdn.js +2 -1
- package/dist/{feeds → src/feeds}/platform/handlers/dailymotion.js +19 -1
- package/dist/{feeds → src/feeds}/platform/handlers/deviantart.js +28 -7
- package/dist/{feeds → src/feeds}/platform/handlers/devto.js +11 -1
- package/dist/src/feeds/platform/handlers/discourse.js +66 -0
- package/dist/{feeds → src/feeds}/platform/handlers/douban.js +2 -1
- package/dist/src/feeds/platform/handlers/dreamwidth.js +49 -0
- package/dist/src/feeds/platform/handlers/exblog.js +36 -0
- package/dist/src/feeds/platform/handlers/fireside.js +25 -0
- package/dist/src/feeds/platform/handlers/friendica.js +44 -0
- package/dist/src/feeds/platform/handlers/ghost.js +31 -0
- package/dist/{feeds → src/feeds}/platform/handlers/github.js +9 -1
- package/dist/{feeds → src/feeds}/platform/handlers/githubGist.js +19 -6
- package/dist/{feeds → src/feeds}/platform/handlers/gitlab.js +34 -14
- package/dist/{feeds → src/feeds}/platform/handlers/goodreads.js +20 -9
- package/dist/src/feeds/platform/handlers/hackernews.js +22 -0
- package/dist/{feeds → src/feeds}/platform/handlers/hashnode.js +3 -2
- package/dist/{feeds → src/feeds}/platform/handlers/hatenablog.js +6 -2
- package/dist/src/feeds/platform/handlers/hearthis.js +34 -0
- package/dist/src/feeds/platform/handlers/heyWorld.js +19 -0
- package/dist/src/feeds/platform/handlers/insanejournal.js +70 -0
- package/dist/{feeds → src/feeds}/platform/handlers/itchio.js +27 -2
- package/dist/{feeds → src/feeds}/platform/handlers/kickstarter.js +2 -1
- package/dist/src/feeds/platform/handlers/lemmy.js +88 -0
- package/dist/{feeds → src/feeds}/platform/handlers/letterboxd.js +7 -1
- package/dist/src/feeds/platform/handlers/libsyn.js +26 -0
- package/dist/src/feeds/platform/handlers/listed.js +21 -0
- package/dist/src/feeds/platform/handlers/livejournal.js +69 -0
- package/dist/{feeds → src/feeds}/platform/handlers/lobsters.js +2 -1
- package/dist/{feeds → src/feeds}/platform/handlers/mastodon.js +32 -0
- package/dist/src/feeds/platform/handlers/mataroa.js +17 -0
- package/dist/{feeds → src/feeds}/platform/handlers/medium.js +5 -3
- package/dist/src/feeds/platform/handlers/microblog.js +56 -0
- package/dist/src/feeds/platform/handlers/misskey.js +40 -0
- package/dist/src/feeds/platform/handlers/myanimelist.js +44 -0
- package/dist/src/feeds/platform/handlers/naverBlog.js +22 -0
- package/dist/src/feeds/platform/handlers/nebula.js +70 -0
- package/dist/src/feeds/platform/handlers/note.js +55 -0
- package/dist/src/feeds/platform/handlers/observable.js +35 -0
- package/dist/src/feeds/platform/handlers/odysee.js +21 -0
- package/dist/src/feeds/platform/handlers/pagecord.js +17 -0
- package/dist/{feeds → src/feeds}/platform/handlers/paragraph.js +3 -3
- package/dist/src/feeds/platform/handlers/pika.js +36 -0
- package/dist/{feeds → src/feeds}/platform/handlers/pinterest.js +16 -1
- package/dist/src/feeds/platform/handlers/pixelfed.js +46 -0
- package/dist/src/feeds/platform/handlers/pleroma.js +34 -0
- package/dist/src/feeds/platform/handlers/podbean.js +30 -0
- package/dist/src/feeds/platform/handlers/podigee.js +30 -0
- package/dist/src/feeds/platform/handlers/posthaven.js +25 -0
- package/dist/{feeds → src/feeds}/platform/handlers/producthunt.js +2 -1
- package/dist/src/feeds/platform/handlers/prose.js +27 -0
- package/dist/src/feeds/platform/handlers/qiita.js +60 -0
- package/dist/src/feeds/platform/handlers/reddit.js +150 -0
- package/dist/src/feeds/platform/handlers/rssCom.js +21 -0
- package/dist/src/feeds/platform/handlers/seesaa.js +23 -0
- package/dist/{feeds → src/feeds}/platform/handlers/soundcloud.js +3 -1
- package/dist/src/feeds/platform/handlers/sourceforge.js +53 -0
- package/dist/src/feeds/platform/handlers/spreaker.js +22 -0
- package/dist/{feeds → src/feeds}/platform/handlers/stackExchange.js +28 -3
- package/dist/{feeds → src/feeds}/platform/handlers/steam.js +9 -1
- package/dist/{feeds → src/feeds}/platform/handlers/substack.js +2 -1
- package/dist/src/feeds/platform/handlers/tildes.js +42 -0
- package/dist/src/feeds/platform/handlers/tistory.js +17 -0
- package/dist/src/feeds/platform/handlers/transistor.js +30 -0
- package/dist/{feeds → src/feeds}/platform/handlers/tumblr.js +2 -1
- package/dist/{feeds → src/feeds}/platform/handlers/v2ex.js +2 -1
- package/dist/src/feeds/platform/handlers/velog.js +25 -0
- package/dist/{feeds → src/feeds}/platform/handlers/vimeo.js +9 -1
- package/dist/src/feeds/platform/handlers/weblogLol.js +27 -0
- package/dist/src/feeds/platform/handlers/weebly.js +26 -0
- package/dist/src/feeds/platform/handlers/wordpress.js +210 -0
- package/dist/{feeds → src/feeds}/platform/handlers/wpengine.js +1 -1
- package/dist/src/feeds/platform/handlers/writeas.js +53 -0
- package/dist/{feeds → src/feeds}/platform/handlers/ximalaya.js +3 -2
- package/dist/{feeds → src/feeds}/platform/handlers/youtube.js +6 -2
- package/dist/src/feeds/platform/handlers/zenn.js +56 -0
- package/package.json +10 -11
- package/dist/common/locales.js +0 -133
- package/dist/common/uris/guess/index.js +0 -8
- package/dist/common/uris/guess/utils.js +0 -40
- package/dist/common/uris/headers/index.js +0 -26
- package/dist/common/uris/html/types.d.ts +0 -12
- package/dist/common/utils.d.ts +0 -10
- package/dist/common/utils.js +0 -79
- package/dist/feeds/defaults.js +0 -168
- package/dist/feeds/platform/handlers/blogspot.js +0 -36
- package/dist/feeds/platform/handlers/lemmy.js +0 -46
- package/dist/feeds/platform/handlers/reddit.js +0 -74
- package/dist/feeds/platform/handlers/sourceforge.js +0 -19
- package/dist/feeds/platform/handlers/wordpress.js +0 -64
- package/dist/utils.d.ts +0 -2
- package/dist/utils.js +0 -2
- /package/dist/{blogrolls → src/blogrolls}/extractors.d.ts +0 -0
- /package/dist/{blogrolls → src/blogrolls}/index.d.ts +0 -0
- /package/dist/{blogrolls → src/blogrolls}/index.js +0 -0
- /package/dist/{blogrolls → src/blogrolls}/types.d.ts +0 -0
- /package/dist/{common → src/common}/discover/defaults.d.ts +0 -0
- /package/dist/{common → src/common}/discover/utils.d.ts +0 -0
- /package/dist/{common → src/common}/types.js +0 -0
- /package/dist/{common → src/common}/uris/feed/index.d.ts +0 -0
- /package/dist/{common → src/common}/uris/feed/types.d.ts +0 -0
- /package/dist/{common → src/common}/uris/guess/index.d.ts +0 -0
- /package/dist/{common → src/common}/uris/headers/index.d.ts +0 -0
- /package/dist/{common → src/common}/uris/headers/types.d.ts +0 -0
- /package/dist/{common → src/common}/uris/html/index.d.ts +0 -0
- /package/dist/{common → src/common}/uris/index.js +0 -0
- /package/dist/{common → src/common}/uris/platform/index.d.ts +0 -0
- /package/dist/{common → src/common}/uris/platform/index.js +0 -0
- /package/dist/{common → src/common}/uris/platform/types.d.ts +0 -0
- /package/dist/{favicons → src/favicons}/defaults.d.ts +0 -0
- /package/dist/{favicons → src/favicons}/extractors.d.ts +0 -0
- /package/dist/{favicons → src/favicons}/index.d.ts +0 -0
- /package/dist/{favicons → src/favicons}/index.js +0 -0
- /package/dist/{favicons → src/favicons}/types.d.ts +0 -0
- /package/dist/{feeds → src/feeds}/extractors.d.ts +0 -0
- /package/dist/{feeds → src/feeds}/index.d.ts +0 -0
- /package/dist/{feeds → src/feeds}/index.js +0 -0
- /package/dist/{feeds → src/feeds}/types.d.ts +0 -0
- /package/dist/{hubs → src/hubs}/discover/index.d.ts +0 -0
- /package/dist/{hubs → src/hubs}/discover/index.js +0 -0
- /package/dist/{hubs → src/hubs}/discover/types.d.ts +0 -0
- /package/dist/{hubs → src/hubs}/feed/index.js +0 -0
- /package/dist/{hubs → src/hubs}/headers/index.js +0 -0
- /package/dist/{hubs → src/hubs}/html/index.js +0 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isAnyOf } from "../../../../node_modules/trousse/dist/matching.js";
|
|
2
|
+
import { isHostOf } from "../../../../node_modules/trousse/dist/urls.js";
|
|
3
|
+
import { composeHint } from "../../../common/utils.js";
|
|
2
4
|
//#region src/feeds/platform/handlers/pinterest.ts
|
|
3
5
|
const hosts = [
|
|
4
6
|
"pinterest.com",
|
|
@@ -34,6 +36,19 @@ const pinterestHandler = {
|
|
|
34
36
|
if (pathSegments.length === 0) return [];
|
|
35
37
|
const username = pathSegments[0];
|
|
36
38
|
if (isAnyOf(username, excludedPaths)) return [];
|
|
39
|
+
const reservedBoardSlugs = /* @__PURE__ */ new Set([
|
|
40
|
+
"pins",
|
|
41
|
+
"boards",
|
|
42
|
+
"_saved",
|
|
43
|
+
"_created",
|
|
44
|
+
"followers",
|
|
45
|
+
"following"
|
|
46
|
+
]);
|
|
47
|
+
const board = pathSegments[1];
|
|
48
|
+
if (board && !reservedBoardSlugs.has(board)) return [{
|
|
49
|
+
uri: `https://www.pinterest.com/${username}/${board}.rss`,
|
|
50
|
+
hint: composeHint("pinterest:board")
|
|
51
|
+
}];
|
|
37
52
|
return [{
|
|
38
53
|
uri: `https://www.pinterest.com/${username}/feed.rss`,
|
|
39
54
|
hint: composeHint("pinterest:pins")
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { composeHint, hasMetaContent } from "../../../common/utils.js";
|
|
2
|
+
//#region src/feeds/platform/handlers/pixelfed.ts
|
|
3
|
+
const profileRegex = /^\/(?:users\/)?([a-zA-Z0-9_]+)\/?$/;
|
|
4
|
+
const excludedPaths = [
|
|
5
|
+
"admin",
|
|
6
|
+
"api",
|
|
7
|
+
"discover",
|
|
8
|
+
"i",
|
|
9
|
+
"login",
|
|
10
|
+
"notifications",
|
|
11
|
+
"p",
|
|
12
|
+
"register",
|
|
13
|
+
"settings",
|
|
14
|
+
"site",
|
|
15
|
+
"storage",
|
|
16
|
+
"timeline",
|
|
17
|
+
"users"
|
|
18
|
+
];
|
|
19
|
+
const isPixelfedHtml = (content) => {
|
|
20
|
+
return hasMetaContent(content, "generator", "pixelfed");
|
|
21
|
+
};
|
|
22
|
+
const pixelfedHandler = {
|
|
23
|
+
match: (url, content) => {
|
|
24
|
+
try {
|
|
25
|
+
if (!content || !isPixelfedHtml(content)) return false;
|
|
26
|
+
const { pathname } = new URL(url);
|
|
27
|
+
const match = pathname.match(profileRegex);
|
|
28
|
+
return Boolean(match?.[1] && !excludedPaths.includes(match[1]));
|
|
29
|
+
} catch {}
|
|
30
|
+
return false;
|
|
31
|
+
},
|
|
32
|
+
resolve: (url) => {
|
|
33
|
+
try {
|
|
34
|
+
const { origin, pathname } = new URL(url);
|
|
35
|
+
const match = pathname.match(profileRegex);
|
|
36
|
+
if (!match?.[1] || excludedPaths.includes(match[1])) return [];
|
|
37
|
+
return [{
|
|
38
|
+
uri: `${origin}/users/${match[1]}.atom`,
|
|
39
|
+
hint: composeHint("pixelfed:posts")
|
|
40
|
+
}];
|
|
41
|
+
} catch {}
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
//#endregion
|
|
46
|
+
export { pixelfedHandler };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { composeHint } from "../../../common/utils.js";
|
|
2
|
+
//#region src/feeds/platform/handlers/pleroma.ts
|
|
3
|
+
const profileRegex = /^\/users\/([^/]+)/;
|
|
4
|
+
const pleromaApiRegex = /\/api\/pleroma\//i;
|
|
5
|
+
const isPleromaHtml = (content) => {
|
|
6
|
+
return pleromaApiRegex.test(content);
|
|
7
|
+
};
|
|
8
|
+
const pleromaHandler = {
|
|
9
|
+
match: (url, content) => {
|
|
10
|
+
try {
|
|
11
|
+
if (!content || !isPleromaHtml(content)) return false;
|
|
12
|
+
const { pathname } = new URL(url);
|
|
13
|
+
return profileRegex.test(pathname);
|
|
14
|
+
} catch {}
|
|
15
|
+
return false;
|
|
16
|
+
},
|
|
17
|
+
resolve: (url) => {
|
|
18
|
+
try {
|
|
19
|
+
const { origin, pathname } = new URL(url);
|
|
20
|
+
const match = pathname.match(profileRegex);
|
|
21
|
+
if (!match?.[1]) return [];
|
|
22
|
+
return [{
|
|
23
|
+
uri: `${origin}/users/${match[1]}/feed.atom`,
|
|
24
|
+
hint: composeHint("pleroma:posts")
|
|
25
|
+
}, {
|
|
26
|
+
uri: `${origin}/users/${match[1]}/feed.rss`,
|
|
27
|
+
hint: composeHint("pleroma:posts-rss")
|
|
28
|
+
}];
|
|
29
|
+
} catch {}
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
//#endregion
|
|
34
|
+
export { pleromaHandler };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { isSubdomainOf } from "../../../../node_modules/trousse/dist/urls.js";
|
|
2
|
+
import { composeHint } from "../../../common/utils.js";
|
|
3
|
+
//#region src/feeds/platform/handlers/podbean.ts
|
|
4
|
+
const domainSuffixRegex = /\.podbean\.com$/i;
|
|
5
|
+
const reservedSlugs = /* @__PURE__ */ new Set([
|
|
6
|
+
"www",
|
|
7
|
+
"feed",
|
|
8
|
+
"pbcdn1",
|
|
9
|
+
"sponsorship",
|
|
10
|
+
"podads",
|
|
11
|
+
"help",
|
|
12
|
+
"blog",
|
|
13
|
+
"support"
|
|
14
|
+
]);
|
|
15
|
+
const podbeanHandler = {
|
|
16
|
+
match: (url) => {
|
|
17
|
+
if (!isSubdomainOf(url, "podbean.com")) return false;
|
|
18
|
+
const slug = new URL(url).hostname.toLowerCase().replace(domainSuffixRegex, "");
|
|
19
|
+
return !reservedSlugs.has(slug);
|
|
20
|
+
},
|
|
21
|
+
resolve: (url) => {
|
|
22
|
+
const { hostname } = new URL(url);
|
|
23
|
+
return [{
|
|
24
|
+
uri: `https://feed.podbean.com/${hostname.replace(domainSuffixRegex, "")}/feed.xml`,
|
|
25
|
+
hint: composeHint("podbean:podcast")
|
|
26
|
+
}];
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
//#endregion
|
|
30
|
+
export { podbeanHandler };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { isSubdomainOf } from "../../../../node_modules/trousse/dist/urls.js";
|
|
2
|
+
import { composeHint } from "../../../common/utils.js";
|
|
3
|
+
//#region src/feeds/platform/handlers/podigee.ts
|
|
4
|
+
const domainSuffixRegex = /\.podigee\.io$/i;
|
|
5
|
+
const reservedSlugs = /* @__PURE__ */ new Set([
|
|
6
|
+
"www",
|
|
7
|
+
"app",
|
|
8
|
+
"help",
|
|
9
|
+
"hilfe",
|
|
10
|
+
"blog",
|
|
11
|
+
"status",
|
|
12
|
+
"player",
|
|
13
|
+
"cdn"
|
|
14
|
+
]);
|
|
15
|
+
const podigeeHandler = {
|
|
16
|
+
match: (url) => {
|
|
17
|
+
if (!isSubdomainOf(url, "podigee.io")) return false;
|
|
18
|
+
const slug = new URL(url).hostname.toLowerCase().replace(domainSuffixRegex, "");
|
|
19
|
+
return !reservedSlugs.has(slug);
|
|
20
|
+
},
|
|
21
|
+
resolve: (url) => {
|
|
22
|
+
const { origin } = new URL(url);
|
|
23
|
+
return [{
|
|
24
|
+
uri: `${origin}/feed/mp3`,
|
|
25
|
+
hint: composeHint("podigee:podcast")
|
|
26
|
+
}];
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
//#endregion
|
|
30
|
+
export { podigeeHandler };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { isSubdomainOf } from "../../../../node_modules/trousse/dist/urls.js";
|
|
2
|
+
import { composeHint } from "../../../common/utils.js";
|
|
3
|
+
//#region src/feeds/platform/handlers/posthaven.ts
|
|
4
|
+
const tagRegex = /^\/tag\/([^/]+)/;
|
|
5
|
+
const posthavenHandler = {
|
|
6
|
+
match: (url) => {
|
|
7
|
+
return isSubdomainOf(url, "posthaven.com");
|
|
8
|
+
},
|
|
9
|
+
resolve: (url) => {
|
|
10
|
+
const { origin, pathname } = new URL(url);
|
|
11
|
+
const uris = [];
|
|
12
|
+
const tagMatch = pathname.match(tagRegex);
|
|
13
|
+
if (tagMatch?.[1]) uris.push({
|
|
14
|
+
uri: `${origin}/tag/${tagMatch[1]}.atom`,
|
|
15
|
+
hint: composeHint("posthaven:tag")
|
|
16
|
+
});
|
|
17
|
+
uris.push({
|
|
18
|
+
uri: `${origin}/posts.atom`,
|
|
19
|
+
hint: composeHint("posthaven:posts")
|
|
20
|
+
});
|
|
21
|
+
return uris;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
//#endregion
|
|
25
|
+
export { posthavenHandler };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isHostOf } from "../../../../node_modules/trousse/dist/urls.js";
|
|
2
|
+
import { composeHint } from "../../../common/utils.js";
|
|
2
3
|
//#region src/feeds/platform/handlers/producthunt.ts
|
|
3
4
|
const hosts = ["producthunt.com", "www.producthunt.com"];
|
|
4
5
|
const topicRegex = /^\/topics\/([a-zA-Z0-9_-]+)/;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { isHostOf, isSubdomainOf } from "../../../../node_modules/trousse/dist/urls.js";
|
|
2
|
+
import { composeHint } from "../../../common/utils.js";
|
|
3
|
+
//#region src/feeds/platform/handlers/prose.ts
|
|
4
|
+
const apexHosts = ["prose.sh", "www.prose.sh"];
|
|
5
|
+
const proseHandler = {
|
|
6
|
+
match: (url) => {
|
|
7
|
+
return isSubdomainOf(url, "prose.sh") || isHostOf(url, apexHosts);
|
|
8
|
+
},
|
|
9
|
+
resolve: (url) => {
|
|
10
|
+
const { origin, searchParams } = new URL(url);
|
|
11
|
+
if (isHostOf(url, apexHosts)) return [{
|
|
12
|
+
uri: "https://prose.sh/rss",
|
|
13
|
+
hint: composeHint("prose:discovery")
|
|
14
|
+
}];
|
|
15
|
+
const tag = searchParams.get("tag");
|
|
16
|
+
if (tag) return [{
|
|
17
|
+
uri: `${origin}/rss?tag=${encodeURIComponent(tag)}`,
|
|
18
|
+
hint: composeHint("prose:tag")
|
|
19
|
+
}];
|
|
20
|
+
return [{
|
|
21
|
+
uri: `${origin}/rss`,
|
|
22
|
+
hint: composeHint("prose:blog")
|
|
23
|
+
}];
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { proseHandler };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { isAnyOf } from "../../../../node_modules/trousse/dist/matching.js";
|
|
2
|
+
import { isHostOf } from "../../../../node_modules/trousse/dist/urls.js";
|
|
3
|
+
import { composeHint } from "../../../common/utils.js";
|
|
4
|
+
//#region src/feeds/platform/handlers/qiita.ts
|
|
5
|
+
const hosts = ["qiita.com", "www.qiita.com"];
|
|
6
|
+
const excludedPaths = [
|
|
7
|
+
"about",
|
|
8
|
+
"api",
|
|
9
|
+
"login",
|
|
10
|
+
"official-columns",
|
|
11
|
+
"organizations",
|
|
12
|
+
"popular-items",
|
|
13
|
+
"privacy",
|
|
14
|
+
"search",
|
|
15
|
+
"settings",
|
|
16
|
+
"signup",
|
|
17
|
+
"tags",
|
|
18
|
+
"terms",
|
|
19
|
+
"trend"
|
|
20
|
+
];
|
|
21
|
+
const tagRegex = /^\/tags\/([^/]+)/;
|
|
22
|
+
const organizationRegex = /^\/organizations\/([^/]+)/;
|
|
23
|
+
const popularItemsRegex = /^\/popular-items(\/|$)/;
|
|
24
|
+
const officialColumnsRegex = /^\/official-columns(\/|$)/;
|
|
25
|
+
const qiitaHandler = {
|
|
26
|
+
match: (url) => {
|
|
27
|
+
return isHostOf(url, hosts);
|
|
28
|
+
},
|
|
29
|
+
resolve: (url) => {
|
|
30
|
+
const { pathname } = new URL(url);
|
|
31
|
+
const tagMatch = pathname.match(tagRegex);
|
|
32
|
+
if (tagMatch?.[1]) return [{
|
|
33
|
+
uri: `https://qiita.com/tags/${tagMatch[1]}/feed.atom`,
|
|
34
|
+
hint: composeHint("qiita:tag")
|
|
35
|
+
}];
|
|
36
|
+
const orgMatch = pathname.match(organizationRegex);
|
|
37
|
+
if (orgMatch?.[1]) return [{
|
|
38
|
+
uri: `https://qiita.com/organizations/${orgMatch[1]}/activities.atom`,
|
|
39
|
+
hint: composeHint("qiita:organization")
|
|
40
|
+
}];
|
|
41
|
+
if (popularItemsRegex.test(pathname)) return [{
|
|
42
|
+
uri: "https://qiita.com/popular-items/feed.atom",
|
|
43
|
+
hint: composeHint("qiita:popular")
|
|
44
|
+
}];
|
|
45
|
+
if (officialColumnsRegex.test(pathname)) return [{
|
|
46
|
+
uri: "https://qiita.com/official-columns/feed/",
|
|
47
|
+
hint: composeHint("qiita:zine")
|
|
48
|
+
}];
|
|
49
|
+
const pathSegments = pathname.split("/").filter(Boolean);
|
|
50
|
+
if (pathSegments.length === 0) return [];
|
|
51
|
+
const username = pathSegments[0];
|
|
52
|
+
if (isAnyOf(username, excludedPaths)) return [];
|
|
53
|
+
return [{
|
|
54
|
+
uri: `https://qiita.com/${username}/feed.atom`,
|
|
55
|
+
hint: composeHint("qiita:posts")
|
|
56
|
+
}];
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
//#endregion
|
|
60
|
+
export { qiitaHandler };
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { isAnyOf } from "../../../../node_modules/trousse/dist/matching.js";
|
|
2
|
+
import { isHostOf } from "../../../../node_modules/trousse/dist/urls.js";
|
|
3
|
+
import { composeHint } from "../../../common/utils.js";
|
|
4
|
+
//#region src/feeds/platform/handlers/reddit.ts
|
|
5
|
+
const commentsRegex = /^\/r\/([^/]+)\/comments\/([^/]+)/;
|
|
6
|
+
const subredditWikiRegex = /^\/r\/([^/]+)\/wiki/;
|
|
7
|
+
const subredditSearchRegex = /^\/r\/([^/]+)\/search/;
|
|
8
|
+
const subredditRegex = /^\/r\/([^/]+)(?:\/([^/]+))?/;
|
|
9
|
+
const multiredditRegex = /^\/user\/([^/]+)\/m\/([^/]+)/;
|
|
10
|
+
const userRegex = /^\/(?:u|user)\/([^/]+)(?:\/(submitted|comments))?/;
|
|
11
|
+
const domainRegex = /^\/domain\/([^/]+)/;
|
|
12
|
+
const subredditsRegex = /^\/(?:subreddits|reddits)(?:\/(new|popular))?/;
|
|
13
|
+
const hosts = [
|
|
14
|
+
"reddit.com",
|
|
15
|
+
"www.reddit.com",
|
|
16
|
+
"old.reddit.com",
|
|
17
|
+
"new.reddit.com"
|
|
18
|
+
];
|
|
19
|
+
const sortOptions = [
|
|
20
|
+
"hot",
|
|
21
|
+
"new",
|
|
22
|
+
"rising",
|
|
23
|
+
"controversial",
|
|
24
|
+
"top",
|
|
25
|
+
"best"
|
|
26
|
+
];
|
|
27
|
+
const timeOptions = /* @__PURE__ */ new Set([
|
|
28
|
+
"hour",
|
|
29
|
+
"day",
|
|
30
|
+
"week",
|
|
31
|
+
"month",
|
|
32
|
+
"year",
|
|
33
|
+
"all"
|
|
34
|
+
]);
|
|
35
|
+
const timeFilteredSorts = /* @__PURE__ */ new Set(["top", "controversial"]);
|
|
36
|
+
const getTimeframeSuffix = (sort, searchParams) => {
|
|
37
|
+
if (!timeFilteredSorts.has(sort)) return "";
|
|
38
|
+
const timeframe = searchParams.get("t");
|
|
39
|
+
if (timeframe && timeOptions.has(timeframe)) return `?t=${timeframe}`;
|
|
40
|
+
return "";
|
|
41
|
+
};
|
|
42
|
+
const redditHandler = {
|
|
43
|
+
match: (url) => {
|
|
44
|
+
return isHostOf(url, hosts);
|
|
45
|
+
},
|
|
46
|
+
resolve: (url) => {
|
|
47
|
+
const { pathname, searchParams } = new URL(url);
|
|
48
|
+
const pathSegments = pathname.split("/").filter(Boolean);
|
|
49
|
+
if (pathSegments.length === 0) return [{
|
|
50
|
+
uri: "https://www.reddit.com/.rss",
|
|
51
|
+
hint: composeHint("reddit:posts")
|
|
52
|
+
}];
|
|
53
|
+
if (pathSegments.length === 1 && isAnyOf(pathSegments[0], sortOptions)) {
|
|
54
|
+
const sort = pathSegments[0];
|
|
55
|
+
return [{
|
|
56
|
+
uri: `https://www.reddit.com/${sort}/.rss${getTimeframeSuffix(sort, searchParams)}`,
|
|
57
|
+
hint: composeHint("reddit:posts")
|
|
58
|
+
}];
|
|
59
|
+
}
|
|
60
|
+
if (pathSegments[0] === "search") {
|
|
61
|
+
const query = searchParams.get("q");
|
|
62
|
+
if (query) return [{
|
|
63
|
+
uri: `https://www.reddit.com/search.rss?q=${encodeURIComponent(query)}`,
|
|
64
|
+
hint: composeHint("reddit:search")
|
|
65
|
+
}];
|
|
66
|
+
}
|
|
67
|
+
const subredditsMatch = pathname.match(subredditsRegex);
|
|
68
|
+
if (subredditsMatch) {
|
|
69
|
+
const sort = subredditsMatch[1];
|
|
70
|
+
return [{
|
|
71
|
+
uri: `https://www.reddit.com/${sort ? `subreddits/${sort}` : "subreddits"}/.rss`,
|
|
72
|
+
hint: composeHint("reddit:subreddits")
|
|
73
|
+
}];
|
|
74
|
+
}
|
|
75
|
+
const subredditSearchMatch = pathname.match(subredditSearchRegex);
|
|
76
|
+
if (subredditSearchMatch?.[1]) {
|
|
77
|
+
const subreddit = subredditSearchMatch[1];
|
|
78
|
+
const query = searchParams.get("q");
|
|
79
|
+
if (query) return [{
|
|
80
|
+
uri: `https://www.reddit.com/r/${subreddit}/search.rss?q=${encodeURIComponent(query)}&restrict_sr=on`,
|
|
81
|
+
hint: composeHint("reddit:search")
|
|
82
|
+
}];
|
|
83
|
+
}
|
|
84
|
+
const subredditWikiMatch = pathname.match(subredditWikiRegex);
|
|
85
|
+
if (subredditWikiMatch?.[1]) return [{
|
|
86
|
+
uri: `https://www.reddit.com/r/${subredditWikiMatch[1]}/wiki/index.rss`,
|
|
87
|
+
hint: composeHint("reddit:wiki")
|
|
88
|
+
}];
|
|
89
|
+
const commentsMatch = pathname.match(commentsRegex);
|
|
90
|
+
if (commentsMatch?.[1] && commentsMatch?.[2]) return [{
|
|
91
|
+
uri: `https://www.reddit.com/r/${commentsMatch[1]}/comments/${commentsMatch[2]}/.rss`,
|
|
92
|
+
hint: composeHint("reddit:post-comments")
|
|
93
|
+
}];
|
|
94
|
+
const subredditMatch = pathname.match(subredditRegex);
|
|
95
|
+
if (subredditMatch?.[1]) {
|
|
96
|
+
const subreddit = subredditMatch[1];
|
|
97
|
+
const sort = subredditMatch[2];
|
|
98
|
+
const uris = [];
|
|
99
|
+
if (sort && isAnyOf(sort, sortOptions)) uris.push({
|
|
100
|
+
uri: `https://www.reddit.com/r/${subreddit}/${sort}/.rss${getTimeframeSuffix(sort, searchParams)}`,
|
|
101
|
+
hint: composeHint("reddit:posts")
|
|
102
|
+
});
|
|
103
|
+
else uris.push({
|
|
104
|
+
uri: `https://www.reddit.com/r/${subreddit}/.rss`,
|
|
105
|
+
hint: composeHint("reddit:posts")
|
|
106
|
+
});
|
|
107
|
+
uris.push({
|
|
108
|
+
uri: `https://www.reddit.com/r/${subreddit}/comments/.rss`,
|
|
109
|
+
hint: composeHint("reddit:comments")
|
|
110
|
+
});
|
|
111
|
+
return uris;
|
|
112
|
+
}
|
|
113
|
+
const multiredditMatch = pathname.match(multiredditRegex);
|
|
114
|
+
if (multiredditMatch?.[1] && multiredditMatch?.[2]) return [{
|
|
115
|
+
uri: `https://www.reddit.com/user/${multiredditMatch[1]}/m/${multiredditMatch[2]}/.rss`,
|
|
116
|
+
hint: composeHint("reddit:multireddit")
|
|
117
|
+
}];
|
|
118
|
+
const userMatch = pathname.match(userRegex);
|
|
119
|
+
if (userMatch?.[1]) {
|
|
120
|
+
const username = userMatch[1];
|
|
121
|
+
const filter = userMatch[2];
|
|
122
|
+
if (filter === "submitted") return [{
|
|
123
|
+
uri: `https://www.reddit.com/user/${username}/submitted/.rss`,
|
|
124
|
+
hint: composeHint("reddit:user-submitted")
|
|
125
|
+
}, {
|
|
126
|
+
uri: `https://www.reddit.com/user/${username}/.rss`,
|
|
127
|
+
hint: composeHint("reddit:posts")
|
|
128
|
+
}];
|
|
129
|
+
if (filter === "comments") return [{
|
|
130
|
+
uri: `https://www.reddit.com/user/${username}/comments/.rss`,
|
|
131
|
+
hint: composeHint("reddit:user-comments")
|
|
132
|
+
}, {
|
|
133
|
+
uri: `https://www.reddit.com/user/${username}/.rss`,
|
|
134
|
+
hint: composeHint("reddit:posts")
|
|
135
|
+
}];
|
|
136
|
+
return [{
|
|
137
|
+
uri: `https://www.reddit.com/user/${username}/.rss`,
|
|
138
|
+
hint: composeHint("reddit:posts")
|
|
139
|
+
}];
|
|
140
|
+
}
|
|
141
|
+
const domainMatch = pathname.match(domainRegex);
|
|
142
|
+
if (domainMatch?.[1]) return [{
|
|
143
|
+
uri: `https://www.reddit.com/domain/${domainMatch[1]}/.rss`,
|
|
144
|
+
hint: composeHint("reddit:posts")
|
|
145
|
+
}];
|
|
146
|
+
return [];
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
//#endregion
|
|
150
|
+
export { hosts, redditHandler };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { isHostOf } from "../../../../node_modules/trousse/dist/urls.js";
|
|
2
|
+
import { composeHint } from "../../../common/utils.js";
|
|
3
|
+
//#region src/feeds/platform/handlers/rssCom.ts
|
|
4
|
+
const hosts = ["rss.com", "www.rss.com"];
|
|
5
|
+
const podcastRegex = /^\/(?:[a-z]{2}\/)?podcasts\/([^/]+)/;
|
|
6
|
+
const rssComHandler = {
|
|
7
|
+
match: (url) => {
|
|
8
|
+
return isHostOf(url, hosts);
|
|
9
|
+
},
|
|
10
|
+
resolve: (url) => {
|
|
11
|
+
const { pathname } = new URL(url);
|
|
12
|
+
const match = pathname.match(podcastRegex);
|
|
13
|
+
if (!match?.[1]) return [];
|
|
14
|
+
return [{
|
|
15
|
+
uri: `https://media.rss.com/${match[1]}/feed.xml`,
|
|
16
|
+
hint: composeHint("rss-com:podcast")
|
|
17
|
+
}];
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
//#endregion
|
|
21
|
+
export { rssComHandler };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { isSubdomainOf } from "../../../../node_modules/trousse/dist/urls.js";
|
|
2
|
+
import { composeHint } from "../../../common/utils.js";
|
|
3
|
+
//#region src/feeds/platform/handlers/seesaa.ts
|
|
4
|
+
const seesaaHandler = {
|
|
5
|
+
match: (url) => {
|
|
6
|
+
return isSubdomainOf(url, "seesaa.net");
|
|
7
|
+
},
|
|
8
|
+
resolve: (url) => {
|
|
9
|
+
const { origin } = new URL(url);
|
|
10
|
+
const uris = [];
|
|
11
|
+
uris.push({
|
|
12
|
+
uri: `${origin}/index20.rdf`,
|
|
13
|
+
hint: composeHint("seesaa:posts-rss2")
|
|
14
|
+
});
|
|
15
|
+
uris.push({
|
|
16
|
+
uri: `${origin}/index.rdf`,
|
|
17
|
+
hint: composeHint("seesaa:posts-rdf")
|
|
18
|
+
});
|
|
19
|
+
return uris;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
//#endregion
|
|
23
|
+
export { seesaaHandler };
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isAnyOf } from "../../../../node_modules/trousse/dist/matching.js";
|
|
2
|
+
import { isHostOf } from "../../../../node_modules/trousse/dist/urls.js";
|
|
3
|
+
import { composeHint } from "../../../common/utils.js";
|
|
2
4
|
//#region src/feeds/platform/handlers/soundcloud.ts
|
|
3
5
|
const userIdRegex = /soundcloud:\/\/users:(\d+)/;
|
|
4
6
|
const hosts = [
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { isHostOf } from "../../../../node_modules/trousse/dist/urls.js";
|
|
2
|
+
import { composeHint } from "../../../common/utils.js";
|
|
3
|
+
//#region src/feeds/platform/handlers/sourceforge.ts
|
|
4
|
+
const hosts = ["sourceforge.net", "www.sourceforge.net"];
|
|
5
|
+
const sourceforgeHandler = {
|
|
6
|
+
match: (url) => {
|
|
7
|
+
return isHostOf(url, hosts);
|
|
8
|
+
},
|
|
9
|
+
resolve: (url) => {
|
|
10
|
+
const { origin, pathname } = new URL(url);
|
|
11
|
+
const pathSegments = pathname.split("/").filter(Boolean);
|
|
12
|
+
if ((pathSegments[0] === "projects" || pathSegments[0] === "p") && pathSegments[1]) {
|
|
13
|
+
const project = pathSegments[1];
|
|
14
|
+
return [
|
|
15
|
+
{
|
|
16
|
+
uri: `${origin}/p/${project}/activity/feed`,
|
|
17
|
+
hint: composeHint("sourceforge:activity")
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
uri: `${origin}/p/${project}/feed`,
|
|
21
|
+
hint: composeHint("sourceforge:project-feed")
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
uri: `${origin}/projects/${project}/rss`,
|
|
25
|
+
hint: composeHint("sourceforge:files")
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
uri: `${origin}/p/${project}/news/feed.rss`,
|
|
29
|
+
hint: composeHint("sourceforge:news-rss")
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
uri: `${origin}/p/${project}/news/feed.atom`,
|
|
33
|
+
hint: composeHint("sourceforge:news-atom")
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
uri: `${origin}/p/${project}/discussion/feed`,
|
|
37
|
+
hint: composeHint("sourceforge:discussion")
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
uri: `${origin}/p/${project}/discussion/feed.atom`,
|
|
41
|
+
hint: composeHint("sourceforge:discussion-atom")
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
uri: `${origin}/p/${project}/bugs/feed`,
|
|
45
|
+
hint: composeHint("sourceforge:bugs")
|
|
46
|
+
}
|
|
47
|
+
];
|
|
48
|
+
}
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
export { hosts, sourceforgeHandler };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { isHostOf } from "../../../../node_modules/trousse/dist/urls.js";
|
|
2
|
+
import { composeHint } from "../../../common/utils.js";
|
|
3
|
+
//#region src/feeds/platform/handlers/spreaker.ts
|
|
4
|
+
const hosts = ["spreaker.com", "www.spreaker.com"];
|
|
5
|
+
const podcastRegex = /^\/podcast\/[\w-]+--(\d+)/;
|
|
6
|
+
const showRegex = /^\/show\/(\d+)(?:\/|$)/;
|
|
7
|
+
const spreakerHandler = {
|
|
8
|
+
match: (url) => {
|
|
9
|
+
return isHostOf(url, hosts);
|
|
10
|
+
},
|
|
11
|
+
resolve: (url) => {
|
|
12
|
+
const { pathname } = new URL(url);
|
|
13
|
+
const id = pathname.match(podcastRegex)?.[1] ?? pathname.match(showRegex)?.[1];
|
|
14
|
+
if (!id) return [];
|
|
15
|
+
return [{
|
|
16
|
+
uri: `https://www.spreaker.com/show/${id}/episodes/feed`,
|
|
17
|
+
hint: composeHint("spreaker:podcast")
|
|
18
|
+
}];
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
22
|
+
export { spreakerHandler };
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isHostOf, isSubdomainOf } from "../../../../node_modules/trousse/dist/urls.js";
|
|
2
|
+
import { composeHint } from "../../../common/utils.js";
|
|
2
3
|
//#region src/feeds/platform/handlers/stackExchange.ts
|
|
3
4
|
const tagRegex = /^\/questions\/tagged\/([\w.+-]+)/;
|
|
4
5
|
const questionRegex = /^\/questions\/(\d+)/;
|
|
5
6
|
const userRegex = /^\/users\/(\d+)/;
|
|
7
|
+
const collectiveRegex = /^\/collectives\/([^/]+)/;
|
|
6
8
|
const domains = [
|
|
7
9
|
"stackoverflow.com",
|
|
8
10
|
"serverfault.com",
|
|
@@ -12,15 +14,29 @@ const domains = [
|
|
|
12
14
|
"mathoverflow.net",
|
|
13
15
|
"stackexchange.com"
|
|
14
16
|
];
|
|
17
|
+
const validSorts = /* @__PURE__ */ new Set([
|
|
18
|
+
"newest",
|
|
19
|
+
"active",
|
|
20
|
+
"votes",
|
|
21
|
+
"creation",
|
|
22
|
+
"hot",
|
|
23
|
+
"week",
|
|
24
|
+
"month"
|
|
25
|
+
]);
|
|
26
|
+
const getSortSuffix = (searchParams) => {
|
|
27
|
+
const sort = searchParams.get("sort") ?? searchParams.get("tab")?.toLowerCase();
|
|
28
|
+
if (sort && validSorts.has(sort)) return `?sort=${sort}`;
|
|
29
|
+
return "";
|
|
30
|
+
};
|
|
15
31
|
const stackExchangeHandler = {
|
|
16
32
|
match: (url) => {
|
|
17
33
|
return isHostOf(url, domains) || isSubdomainOf(url, domains);
|
|
18
34
|
},
|
|
19
35
|
resolve: (url) => {
|
|
20
|
-
const { origin, pathname } = new URL(url);
|
|
36
|
+
const { origin, pathname, searchParams } = new URL(url);
|
|
21
37
|
const tagMatch = pathname.match(tagRegex);
|
|
22
38
|
if (tagMatch?.[1]) return [{
|
|
23
|
-
uri: `${origin}/feeds/tag/${tagMatch[1]}`,
|
|
39
|
+
uri: `${origin}/feeds/tag/${tagMatch[1]}${getSortSuffix(searchParams)}`,
|
|
24
40
|
hint: composeHint("stackexchange:tag")
|
|
25
41
|
}];
|
|
26
42
|
const questionMatch = pathname.match(questionRegex);
|
|
@@ -33,6 +49,15 @@ const stackExchangeHandler = {
|
|
|
33
49
|
uri: `${origin}/feeds/user/${userMatch[1]}`,
|
|
34
50
|
hint: composeHint("stackexchange:user")
|
|
35
51
|
}];
|
|
52
|
+
const collectiveMatch = pathname.match(collectiveRegex);
|
|
53
|
+
if (collectiveMatch?.[1]) return [{
|
|
54
|
+
uri: `${origin}/feeds/collectives/${collectiveMatch[1]}`,
|
|
55
|
+
hint: composeHint("stackexchange:collective")
|
|
56
|
+
}];
|
|
57
|
+
if (pathname === "/" || pathname === "") return [{
|
|
58
|
+
uri: `${origin}/feeds`,
|
|
59
|
+
hint: composeHint("stackexchange:newest")
|
|
60
|
+
}];
|
|
36
61
|
return [];
|
|
37
62
|
}
|
|
38
63
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isHostOf } from "../../../../node_modules/trousse/dist/urls.js";
|
|
2
|
+
import { composeHint } from "../../../common/utils.js";
|
|
2
3
|
//#region src/feeds/platform/handlers/steam.ts
|
|
3
4
|
const appRegex = /^\/(?:news\/)?app\/(\d+)/;
|
|
4
5
|
const groupRegex = /^\/groups\/([^/]+)/;
|
|
@@ -21,6 +22,13 @@ const steamHandler = {
|
|
|
21
22
|
hint: composeHint("steam:group")
|
|
22
23
|
}];
|
|
23
24
|
}
|
|
25
|
+
if (hostname === "store.steampowered.com" && (pathname === "/" || pathname === "" || pathname.startsWith("/news"))) return [{
|
|
26
|
+
uri: "https://store.steampowered.com/feeds/news.xml",
|
|
27
|
+
hint: composeHint("steam:news-global")
|
|
28
|
+
}, {
|
|
29
|
+
uri: "https://store.steampowered.com/feeds/daily_deals.xml",
|
|
30
|
+
hint: composeHint("steam:daily-deals")
|
|
31
|
+
}];
|
|
24
32
|
return [];
|
|
25
33
|
}
|
|
26
34
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isHostOf, isSubdomainOf } from "../../../../node_modules/trousse/dist/urls.js";
|
|
2
|
+
import { composeHint } from "../../../common/utils.js";
|
|
2
3
|
//#region src/feeds/platform/handlers/substack.ts
|
|
3
4
|
const profileRegex = /^\/@([\w-]+)/;
|
|
4
5
|
const substackHandler = {
|