feedscout 1.4.0 → 1.6.0

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.
Files changed (201) hide show
  1. package/README.md +12 -17
  2. package/dist/blogrolls/defaults.cjs +1 -3
  3. package/dist/blogrolls/defaults.js +1 -2
  4. package/dist/blogrolls/extractors.cjs +6 -9
  5. package/dist/blogrolls/extractors.js +6 -9
  6. package/dist/blogrolls/index.cjs +6 -9
  7. package/dist/blogrolls/index.d.cts +1 -1
  8. package/dist/blogrolls/index.d.ts +1 -1
  9. package/dist/blogrolls/index.js +1 -4
  10. package/dist/blogrolls.cjs +4 -5
  11. package/dist/blogrolls.js +1 -2
  12. package/dist/common/discover/index.cjs +60 -21
  13. package/dist/common/discover/index.js +58 -19
  14. package/dist/common/discover/utils.cjs +30 -9
  15. package/dist/common/discover/utils.js +28 -8
  16. package/dist/common/locales.cjs +127 -8
  17. package/dist/common/locales.js +116 -2
  18. package/dist/common/types.cjs +10 -0
  19. package/dist/common/types.d.cts +23 -5
  20. package/dist/common/types.d.ts +23 -5
  21. package/dist/common/types.js +10 -0
  22. package/dist/common/uris/feed/index.cjs +12 -0
  23. package/dist/common/uris/feed/index.d.cts +6 -0
  24. package/dist/common/uris/feed/index.d.ts +6 -0
  25. package/dist/common/uris/feed/index.js +12 -0
  26. package/dist/common/uris/feed/types.d.cts +9 -0
  27. package/dist/common/uris/feed/types.d.ts +9 -0
  28. package/dist/common/uris/guess/index.cjs +2 -4
  29. package/dist/common/uris/guess/index.d.cts +2 -1
  30. package/dist/common/uris/guess/index.d.ts +2 -1
  31. package/dist/common/uris/guess/index.js +1 -3
  32. package/dist/common/uris/guess/types.d.cts +3 -1
  33. package/dist/common/uris/guess/types.d.ts +3 -1
  34. package/dist/common/uris/guess/utils.cjs +5 -4
  35. package/dist/common/uris/guess/utils.d.cts +3 -1
  36. package/dist/common/uris/guess/utils.d.ts +3 -1
  37. package/dist/common/uris/guess/utils.js +5 -3
  38. package/dist/common/uris/headers/index.cjs +2 -4
  39. package/dist/common/uris/headers/index.js +1 -3
  40. package/dist/common/uris/html/handlers.cjs +2 -4
  41. package/dist/common/uris/html/handlers.js +1 -3
  42. package/dist/common/uris/html/index.cjs +2 -4
  43. package/dist/common/uris/html/index.js +1 -3
  44. package/dist/common/uris/index.cjs +23 -17
  45. package/dist/common/uris/index.js +19 -13
  46. package/dist/common/uris/platform/index.cjs +3 -5
  47. package/dist/common/uris/platform/index.d.cts +7 -0
  48. package/dist/common/uris/platform/index.d.ts +7 -0
  49. package/dist/common/uris/platform/index.js +3 -4
  50. package/dist/common/uris/platform/types.d.cts +4 -2
  51. package/dist/common/uris/platform/types.d.ts +4 -2
  52. package/dist/common/utils.cjs +25 -8
  53. package/dist/common/utils.d.cts +2 -2
  54. package/dist/common/utils.d.ts +2 -2
  55. package/dist/common/utils.js +23 -7
  56. package/dist/favicons/defaults.cjs +60 -0
  57. package/dist/favicons/defaults.d.cts +18 -0
  58. package/dist/favicons/defaults.d.ts +18 -0
  59. package/dist/favicons/defaults.js +53 -0
  60. package/dist/favicons/extractors.cjs +13 -0
  61. package/dist/favicons/extractors.d.cts +7 -0
  62. package/dist/favicons/extractors.d.ts +7 -0
  63. package/dist/favicons/extractors.js +13 -0
  64. package/dist/favicons/index.cjs +29 -0
  65. package/dist/favicons/index.d.cts +7 -0
  66. package/dist/favicons/index.d.ts +7 -0
  67. package/dist/favicons/index.js +29 -0
  68. package/dist/favicons/platform/handlers/bluesky.cjs +27 -0
  69. package/dist/favicons/platform/handlers/bluesky.js +27 -0
  70. package/dist/favicons/platform/handlers/codeberg.cjs +18 -0
  71. package/dist/favicons/platform/handlers/codeberg.js +18 -0
  72. package/dist/favicons/platform/handlers/deviantart.cjs +29 -0
  73. package/dist/favicons/platform/handlers/deviantart.js +29 -0
  74. package/dist/favicons/platform/handlers/github.cjs +18 -0
  75. package/dist/favicons/platform/handlers/github.js +18 -0
  76. package/dist/favicons/platform/handlers/githubGist.cjs +18 -0
  77. package/dist/favicons/platform/handlers/githubGist.js +18 -0
  78. package/dist/favicons/platform/handlers/lobsters.cjs +21 -0
  79. package/dist/favicons/platform/handlers/lobsters.js +21 -0
  80. package/dist/favicons/platform/handlers/mastodon.cjs +36 -0
  81. package/dist/favicons/platform/handlers/mastodon.js +34 -0
  82. package/dist/favicons/platform/handlers/reddit.cjs +41 -0
  83. package/dist/favicons/platform/handlers/reddit.js +41 -0
  84. package/dist/favicons/platform/handlers/sourceforge.cjs +21 -0
  85. package/dist/favicons/platform/handlers/sourceforge.js +21 -0
  86. package/dist/favicons/platform/handlers/tumblr.cjs +16 -0
  87. package/dist/favicons/platform/handlers/tumblr.js +16 -0
  88. package/dist/favicons/types.d.cts +4 -0
  89. package/dist/favicons/types.d.ts +4 -0
  90. package/dist/favicons.cjs +12 -0
  91. package/dist/favicons.d.cts +4 -0
  92. package/dist/favicons.d.ts +4 -0
  93. package/dist/favicons.js +3 -0
  94. package/dist/feeds/defaults.cjs +66 -37
  95. package/dist/feeds/defaults.d.cts +2 -2
  96. package/dist/feeds/defaults.d.ts +2 -2
  97. package/dist/feeds/defaults.js +52 -23
  98. package/dist/feeds/extractors.cjs +1 -3
  99. package/dist/feeds/extractors.js +1 -3
  100. package/dist/feeds/index.cjs +6 -8
  101. package/dist/feeds/index.d.cts +1 -1
  102. package/dist/feeds/index.d.ts +1 -1
  103. package/dist/feeds/index.js +1 -3
  104. package/dist/feeds/platform/handlers/behance.cjs +10 -6
  105. package/dist/feeds/platform/handlers/behance.js +10 -6
  106. package/dist/feeds/platform/handlers/blogspot.cjs +19 -8
  107. package/dist/feeds/platform/handlers/blogspot.js +19 -7
  108. package/dist/feeds/platform/handlers/bluesky.cjs +7 -6
  109. package/dist/feeds/platform/handlers/bluesky.js +7 -6
  110. package/dist/feeds/platform/handlers/codeberg.cjs +69 -0
  111. package/dist/feeds/platform/handlers/codeberg.js +67 -0
  112. package/dist/feeds/platform/handlers/csdn.cjs +19 -0
  113. package/dist/feeds/platform/handlers/csdn.js +19 -0
  114. package/dist/feeds/platform/handlers/dailymotion.cjs +10 -6
  115. package/dist/feeds/platform/handlers/dailymotion.js +10 -6
  116. package/dist/feeds/platform/handlers/deviantart.cjs +20 -8
  117. package/dist/feeds/platform/handlers/deviantart.js +18 -8
  118. package/dist/feeds/platform/handlers/devto.cjs +10 -6
  119. package/dist/feeds/platform/handlers/devto.js +10 -6
  120. package/dist/feeds/platform/handlers/douban.cjs +54 -0
  121. package/dist/feeds/platform/handlers/douban.js +54 -0
  122. package/dist/feeds/platform/handlers/github.cjs +37 -16
  123. package/dist/feeds/platform/handlers/github.js +35 -16
  124. package/dist/feeds/platform/handlers/githubGist.cjs +17 -17
  125. package/dist/feeds/platform/handlers/githubGist.js +15 -17
  126. package/dist/feeds/platform/handlers/gitlab.cjs +18 -8
  127. package/dist/feeds/platform/handlers/gitlab.js +18 -8
  128. package/dist/feeds/platform/handlers/goodreads.cjs +39 -0
  129. package/dist/feeds/platform/handlers/goodreads.js +39 -0
  130. package/dist/feeds/platform/handlers/hashnode.cjs +16 -0
  131. package/dist/feeds/platform/handlers/hashnode.js +16 -0
  132. package/dist/feeds/platform/handlers/hatenablog.cjs +53 -0
  133. package/dist/feeds/platform/handlers/hatenablog.js +53 -0
  134. package/dist/feeds/platform/handlers/itchio.cjs +88 -0
  135. package/dist/feeds/platform/handlers/itchio.js +88 -0
  136. package/dist/feeds/platform/handlers/kickstarter.cjs +10 -6
  137. package/dist/feeds/platform/handlers/kickstarter.js +10 -6
  138. package/dist/feeds/platform/handlers/letterboxd.cjs +42 -0
  139. package/dist/feeds/platform/handlers/letterboxd.js +42 -0
  140. package/dist/feeds/platform/handlers/lobsters.cjs +35 -12
  141. package/dist/feeds/platform/handlers/lobsters.js +34 -12
  142. package/dist/feeds/platform/handlers/mastodon.cjs +40 -0
  143. package/dist/feeds/platform/handlers/mastodon.js +40 -0
  144. package/dist/feeds/platform/handlers/medium.cjs +26 -10
  145. package/dist/feeds/platform/handlers/medium.js +26 -10
  146. package/dist/feeds/platform/handlers/paragraph.cjs +21 -0
  147. package/dist/feeds/platform/handlers/paragraph.js +21 -0
  148. package/dist/feeds/platform/handlers/pinterest.cjs +6 -10
  149. package/dist/feeds/platform/handlers/pinterest.js +6 -10
  150. package/dist/feeds/platform/handlers/producthunt.cjs +14 -7
  151. package/dist/feeds/platform/handlers/producthunt.js +14 -7
  152. package/dist/feeds/platform/handlers/reddit.cjs +35 -12
  153. package/dist/feeds/platform/handlers/reddit.js +34 -12
  154. package/dist/feeds/platform/handlers/soundcloud.cjs +6 -5
  155. package/dist/feeds/platform/handlers/soundcloud.js +6 -5
  156. package/dist/feeds/platform/handlers/sourceforge.cjs +20 -0
  157. package/dist/feeds/platform/handlers/sourceforge.js +19 -0
  158. package/dist/feeds/platform/handlers/stackExchange.cjs +37 -0
  159. package/dist/feeds/platform/handlers/stackExchange.js +37 -0
  160. package/dist/feeds/platform/handlers/steam.cjs +26 -0
  161. package/dist/feeds/platform/handlers/steam.js +26 -0
  162. package/dist/feeds/platform/handlers/substack.cjs +6 -5
  163. package/dist/feeds/platform/handlers/substack.js +6 -5
  164. package/dist/feeds/platform/handlers/tumblr.cjs +13 -7
  165. package/dist/feeds/platform/handlers/tumblr.js +12 -7
  166. package/dist/feeds/platform/handlers/v2ex.cjs +33 -0
  167. package/dist/feeds/platform/handlers/v2ex.js +33 -0
  168. package/dist/feeds/platform/handlers/vimeo.cjs +68 -0
  169. package/dist/feeds/platform/handlers/vimeo.js +68 -0
  170. package/dist/feeds/platform/handlers/wordpress.cjs +46 -12
  171. package/dist/feeds/platform/handlers/wordpress.js +46 -12
  172. package/dist/feeds/platform/handlers/wpengine.cjs +10 -0
  173. package/dist/feeds/platform/handlers/wpengine.js +11 -0
  174. package/dist/feeds/platform/handlers/ximalaya.cjs +19 -0
  175. package/dist/feeds/platform/handlers/ximalaya.js +19 -0
  176. package/dist/feeds/platform/handlers/youtube.cjs +35 -13
  177. package/dist/feeds/platform/handlers/youtube.js +35 -13
  178. package/dist/feeds.cjs +4 -5
  179. package/dist/feeds.js +1 -2
  180. package/dist/hubs/discover/index.cjs +7 -9
  181. package/dist/hubs/discover/index.js +1 -3
  182. package/dist/hubs/discover/utils.cjs +1 -3
  183. package/dist/hubs/discover/utils.js +1 -2
  184. package/dist/hubs/feed/index.cjs +1 -3
  185. package/dist/hubs/feed/index.js +1 -3
  186. package/dist/hubs/headers/index.cjs +3 -5
  187. package/dist/hubs/headers/index.js +1 -3
  188. package/dist/hubs/html/index.cjs +3 -5
  189. package/dist/hubs/html/index.js +1 -3
  190. package/dist/hubs.js +1 -1
  191. package/dist/index.cjs +8 -7
  192. package/dist/index.d.cts +3 -2
  193. package/dist/index.d.ts +3 -2
  194. package/dist/index.js +2 -2
  195. package/dist/methods.cjs +13 -10
  196. package/dist/methods.d.cts +3 -1
  197. package/dist/methods.d.ts +3 -1
  198. package/dist/methods.js +3 -2
  199. package/dist/utils.cjs +3 -4
  200. package/dist/utils.js +1 -2
  201. package/package.json +15 -5
@@ -1,5 +1,4 @@
1
- const require_utils = require('../../../common/utils.cjs');
2
-
1
+ const require_utils = require("../../../common/utils.cjs");
3
2
  //#region src/feeds/platform/handlers/reddit.ts
4
3
  const hosts = [
5
4
  "reddit.com",
@@ -20,28 +19,52 @@ const redditHandler = {
20
19
  },
21
20
  resolve: (url) => {
22
21
  const { pathname } = new URL(url);
23
- if (pathname.split("/").filter(Boolean).length === 0) return ["https://www.reddit.com/.rss"];
22
+ if (pathname.split("/").filter(Boolean).length === 0) return [{
23
+ uri: "https://www.reddit.com/.rss",
24
+ hint: require_utils.composeHint("reddit:posts")
25
+ }];
24
26
  const commentsMatch = pathname.match(/^\/r\/([^/]+)\/comments\/([^/]+)/);
25
- if (commentsMatch?.[1] && commentsMatch?.[2]) return [`https://www.reddit.com/r/${commentsMatch[1]}/comments/${commentsMatch[2]}/.rss`];
27
+ if (commentsMatch?.[1] && commentsMatch?.[2]) return [{
28
+ uri: `https://www.reddit.com/r/${commentsMatch[1]}/comments/${commentsMatch[2]}/.rss`,
29
+ hint: require_utils.composeHint("reddit:post-comments")
30
+ }];
26
31
  const subredditMatch = pathname.match(/^\/r\/([^/]+)(?:\/([^/]+))?/);
27
32
  if (subredditMatch?.[1]) {
28
33
  const subreddit = subredditMatch[1];
29
34
  const sort = subredditMatch[2];
30
35
  const uris = [];
31
- if (sort && require_utils.isAnyOf(sort, sortOptions)) uris.push(`https://www.reddit.com/r/${subreddit}/${sort}/.rss`);
32
- else uris.push(`https://www.reddit.com/r/${subreddit}/.rss`);
33
- uris.push(`https://www.reddit.com/r/${subreddit}/comments/.rss`);
36
+ if (sort && require_utils.isAnyOf(sort, sortOptions)) uris.push({
37
+ uri: `https://www.reddit.com/r/${subreddit}/${sort}/.rss`,
38
+ hint: require_utils.composeHint("reddit:posts")
39
+ });
40
+ else uris.push({
41
+ uri: `https://www.reddit.com/r/${subreddit}/.rss`,
42
+ hint: require_utils.composeHint("reddit:posts")
43
+ });
44
+ uris.push({
45
+ uri: `https://www.reddit.com/r/${subreddit}/comments/.rss`,
46
+ hint: require_utils.composeHint("reddit:comments")
47
+ });
34
48
  return uris;
35
49
  }
36
50
  const multiredditMatch = pathname.match(/^\/user\/([^/]+)\/m\/([^/]+)/);
37
- if (multiredditMatch?.[1] && multiredditMatch?.[2]) return [`https://www.reddit.com/user/${multiredditMatch[1]}/m/${multiredditMatch[2]}/.rss`];
51
+ if (multiredditMatch?.[1] && multiredditMatch?.[2]) return [{
52
+ uri: `https://www.reddit.com/user/${multiredditMatch[1]}/m/${multiredditMatch[2]}/.rss`,
53
+ hint: require_utils.composeHint("reddit:multireddit")
54
+ }];
38
55
  const userMatch = pathname.match(/^\/(u|user)\/([^/]+)/);
39
- if (userMatch?.[2]) return [`https://www.reddit.com/user/${userMatch[2]}/.rss`];
56
+ if (userMatch?.[2]) return [{
57
+ uri: `https://www.reddit.com/user/${userMatch[2]}/.rss`,
58
+ hint: require_utils.composeHint("reddit:posts")
59
+ }];
40
60
  const domainMatch = pathname.match(/^\/domain\/([^/]+)/);
41
- if (domainMatch?.[1]) return [`https://www.reddit.com/domain/${domainMatch[1]}/.rss`];
61
+ if (domainMatch?.[1]) return [{
62
+ uri: `https://www.reddit.com/domain/${domainMatch[1]}/.rss`,
63
+ hint: require_utils.composeHint("reddit:posts")
64
+ }];
42
65
  return [];
43
66
  }
44
67
  };
45
-
46
68
  //#endregion
47
- exports.redditHandler = redditHandler;
69
+ exports.hosts = hosts;
70
+ exports.redditHandler = redditHandler;
@@ -1,5 +1,4 @@
1
- import { isAnyOf, isHostOf } from "../../../common/utils.js";
2
-
1
+ import { composeHint, isAnyOf, isHostOf } from "../../../common/utils.js";
3
2
  //#region src/feeds/platform/handlers/reddit.ts
4
3
  const hosts = [
5
4
  "reddit.com",
@@ -20,28 +19,51 @@ const redditHandler = {
20
19
  },
21
20
  resolve: (url) => {
22
21
  const { pathname } = new URL(url);
23
- if (pathname.split("/").filter(Boolean).length === 0) return ["https://www.reddit.com/.rss"];
22
+ if (pathname.split("/").filter(Boolean).length === 0) return [{
23
+ uri: "https://www.reddit.com/.rss",
24
+ hint: composeHint("reddit:posts")
25
+ }];
24
26
  const commentsMatch = pathname.match(/^\/r\/([^/]+)\/comments\/([^/]+)/);
25
- if (commentsMatch?.[1] && commentsMatch?.[2]) return [`https://www.reddit.com/r/${commentsMatch[1]}/comments/${commentsMatch[2]}/.rss`];
27
+ if (commentsMatch?.[1] && commentsMatch?.[2]) return [{
28
+ uri: `https://www.reddit.com/r/${commentsMatch[1]}/comments/${commentsMatch[2]}/.rss`,
29
+ hint: composeHint("reddit:post-comments")
30
+ }];
26
31
  const subredditMatch = pathname.match(/^\/r\/([^/]+)(?:\/([^/]+))?/);
27
32
  if (subredditMatch?.[1]) {
28
33
  const subreddit = subredditMatch[1];
29
34
  const sort = subredditMatch[2];
30
35
  const uris = [];
31
- if (sort && isAnyOf(sort, sortOptions)) uris.push(`https://www.reddit.com/r/${subreddit}/${sort}/.rss`);
32
- else uris.push(`https://www.reddit.com/r/${subreddit}/.rss`);
33
- uris.push(`https://www.reddit.com/r/${subreddit}/comments/.rss`);
36
+ if (sort && isAnyOf(sort, sortOptions)) uris.push({
37
+ uri: `https://www.reddit.com/r/${subreddit}/${sort}/.rss`,
38
+ hint: composeHint("reddit:posts")
39
+ });
40
+ else uris.push({
41
+ uri: `https://www.reddit.com/r/${subreddit}/.rss`,
42
+ hint: composeHint("reddit:posts")
43
+ });
44
+ uris.push({
45
+ uri: `https://www.reddit.com/r/${subreddit}/comments/.rss`,
46
+ hint: composeHint("reddit:comments")
47
+ });
34
48
  return uris;
35
49
  }
36
50
  const multiredditMatch = pathname.match(/^\/user\/([^/]+)\/m\/([^/]+)/);
37
- if (multiredditMatch?.[1] && multiredditMatch?.[2]) return [`https://www.reddit.com/user/${multiredditMatch[1]}/m/${multiredditMatch[2]}/.rss`];
51
+ if (multiredditMatch?.[1] && multiredditMatch?.[2]) return [{
52
+ uri: `https://www.reddit.com/user/${multiredditMatch[1]}/m/${multiredditMatch[2]}/.rss`,
53
+ hint: composeHint("reddit:multireddit")
54
+ }];
38
55
  const userMatch = pathname.match(/^\/(u|user)\/([^/]+)/);
39
- if (userMatch?.[2]) return [`https://www.reddit.com/user/${userMatch[2]}/.rss`];
56
+ if (userMatch?.[2]) return [{
57
+ uri: `https://www.reddit.com/user/${userMatch[2]}/.rss`,
58
+ hint: composeHint("reddit:posts")
59
+ }];
40
60
  const domainMatch = pathname.match(/^\/domain\/([^/]+)/);
41
- if (domainMatch?.[1]) return [`https://www.reddit.com/domain/${domainMatch[1]}/.rss`];
61
+ if (domainMatch?.[1]) return [{
62
+ uri: `https://www.reddit.com/domain/${domainMatch[1]}/.rss`,
63
+ hint: composeHint("reddit:posts")
64
+ }];
42
65
  return [];
43
66
  }
44
67
  };
45
-
46
68
  //#endregion
47
- export { redditHandler };
69
+ export { hosts, redditHandler };
@@ -1,5 +1,4 @@
1
- const require_utils = require('../../../common/utils.cjs');
2
-
1
+ const require_utils = require("../../../common/utils.cjs");
3
2
  //#region src/feeds/platform/handlers/soundcloud.ts
4
3
  const hosts = [
5
4
  "soundcloud.com",
@@ -29,9 +28,11 @@ const soundcloudHandler = {
29
28
  if (!content) return [];
30
29
  const userId = extractUserIdFromContent(content);
31
30
  if (!userId) return [];
32
- return [`https://feeds.soundcloud.com/users/soundcloud:users:${userId}/sounds.rss`];
31
+ return [{
32
+ uri: `https://feeds.soundcloud.com/users/soundcloud:users:${userId}/sounds.rss`,
33
+ hint: require_utils.composeHint("soundcloud:tracks")
34
+ }];
33
35
  }
34
36
  };
35
-
36
37
  //#endregion
37
- exports.soundcloudHandler = soundcloudHandler;
38
+ exports.soundcloudHandler = soundcloudHandler;
@@ -1,5 +1,4 @@
1
- import { isAnyOf, isHostOf } from "../../../common/utils.js";
2
-
1
+ import { composeHint, isAnyOf, isHostOf } from "../../../common/utils.js";
3
2
  //#region src/feeds/platform/handlers/soundcloud.ts
4
3
  const hosts = [
5
4
  "soundcloud.com",
@@ -29,9 +28,11 @@ const soundcloudHandler = {
29
28
  if (!content) return [];
30
29
  const userId = extractUserIdFromContent(content);
31
30
  if (!userId) return [];
32
- return [`https://feeds.soundcloud.com/users/soundcloud:users:${userId}/sounds.rss`];
31
+ return [{
32
+ uri: `https://feeds.soundcloud.com/users/soundcloud:users:${userId}/sounds.rss`,
33
+ hint: composeHint("soundcloud:tracks")
34
+ }];
33
35
  }
34
36
  };
35
-
36
37
  //#endregion
37
- export { soundcloudHandler };
38
+ export { soundcloudHandler };
@@ -0,0 +1,20 @@
1
+ const require_utils = require("../../../common/utils.cjs");
2
+ //#region src/feeds/platform/handlers/sourceforge.ts
3
+ const hosts = ["sourceforge.net", "www.sourceforge.net"];
4
+ const sourceforgeHandler = {
5
+ match: (url) => {
6
+ return require_utils.isHostOf(url, hosts);
7
+ },
8
+ resolve: (url) => {
9
+ const { origin, pathname } = new URL(url);
10
+ const pathSegments = pathname.split("/").filter(Boolean);
11
+ if (pathSegments[0] === "projects" && pathSegments[1]) return [{
12
+ uri: `${origin}/projects/${pathSegments[1]}/rss`,
13
+ hint: require_utils.composeHint("sourceforge:activity")
14
+ }];
15
+ return [];
16
+ }
17
+ };
18
+ //#endregion
19
+ exports.hosts = hosts;
20
+ exports.sourceforgeHandler = sourceforgeHandler;
@@ -0,0 +1,19 @@
1
+ import { composeHint, isHostOf } from "../../../common/utils.js";
2
+ //#region src/feeds/platform/handlers/sourceforge.ts
3
+ const hosts = ["sourceforge.net", "www.sourceforge.net"];
4
+ const sourceforgeHandler = {
5
+ match: (url) => {
6
+ return isHostOf(url, hosts);
7
+ },
8
+ resolve: (url) => {
9
+ const { origin, pathname } = new URL(url);
10
+ const pathSegments = pathname.split("/").filter(Boolean);
11
+ if (pathSegments[0] === "projects" && pathSegments[1]) return [{
12
+ uri: `${origin}/projects/${pathSegments[1]}/rss`,
13
+ hint: composeHint("sourceforge:activity")
14
+ }];
15
+ return [];
16
+ }
17
+ };
18
+ //#endregion
19
+ export { hosts, sourceforgeHandler };
@@ -0,0 +1,37 @@
1
+ const require_utils = require("../../../common/utils.cjs");
2
+ //#region src/feeds/platform/handlers/stackExchange.ts
3
+ const domains = [
4
+ "stackoverflow.com",
5
+ "serverfault.com",
6
+ "superuser.com",
7
+ "askubuntu.com",
8
+ "stackapps.com",
9
+ "mathoverflow.net",
10
+ "stackexchange.com"
11
+ ];
12
+ const stackExchangeHandler = {
13
+ match: (url) => {
14
+ return require_utils.isHostOf(url, domains) || require_utils.isSubdomainOf(url, domains);
15
+ },
16
+ resolve: (url) => {
17
+ const { origin, pathname } = new URL(url);
18
+ const tagMatch = pathname.match(/^\/questions\/tagged\/([\w.+-]+)/);
19
+ if (tagMatch?.[1]) return [{
20
+ uri: `${origin}/feeds/tag/${tagMatch[1]}`,
21
+ hint: require_utils.composeHint("stackexchange:tag")
22
+ }];
23
+ const questionMatch = pathname.match(/^\/questions\/(\d+)/);
24
+ if (questionMatch?.[1]) return [{
25
+ uri: `${origin}/feeds/question/${questionMatch[1]}`,
26
+ hint: require_utils.composeHint("stackexchange:question")
27
+ }];
28
+ const userMatch = pathname.match(/^\/users\/(\d+)/);
29
+ if (userMatch?.[1]) return [{
30
+ uri: `${origin}/feeds/user/${userMatch[1]}`,
31
+ hint: require_utils.composeHint("stackexchange:user")
32
+ }];
33
+ return [];
34
+ }
35
+ };
36
+ //#endregion
37
+ exports.stackExchangeHandler = stackExchangeHandler;
@@ -0,0 +1,37 @@
1
+ import { composeHint, isHostOf, isSubdomainOf } from "../../../common/utils.js";
2
+ //#region src/feeds/platform/handlers/stackExchange.ts
3
+ const domains = [
4
+ "stackoverflow.com",
5
+ "serverfault.com",
6
+ "superuser.com",
7
+ "askubuntu.com",
8
+ "stackapps.com",
9
+ "mathoverflow.net",
10
+ "stackexchange.com"
11
+ ];
12
+ const stackExchangeHandler = {
13
+ match: (url) => {
14
+ return isHostOf(url, domains) || isSubdomainOf(url, domains);
15
+ },
16
+ resolve: (url) => {
17
+ const { origin, pathname } = new URL(url);
18
+ const tagMatch = pathname.match(/^\/questions\/tagged\/([\w.+-]+)/);
19
+ if (tagMatch?.[1]) return [{
20
+ uri: `${origin}/feeds/tag/${tagMatch[1]}`,
21
+ hint: composeHint("stackexchange:tag")
22
+ }];
23
+ const questionMatch = pathname.match(/^\/questions\/(\d+)/);
24
+ if (questionMatch?.[1]) return [{
25
+ uri: `${origin}/feeds/question/${questionMatch[1]}`,
26
+ hint: composeHint("stackexchange:question")
27
+ }];
28
+ const userMatch = pathname.match(/^\/users\/(\d+)/);
29
+ if (userMatch?.[1]) return [{
30
+ uri: `${origin}/feeds/user/${userMatch[1]}`,
31
+ hint: composeHint("stackexchange:user")
32
+ }];
33
+ return [];
34
+ }
35
+ };
36
+ //#endregion
37
+ export { stackExchangeHandler };
@@ -0,0 +1,26 @@
1
+ const require_utils = require("../../../common/utils.cjs");
2
+ //#region src/feeds/platform/handlers/steam.ts
3
+ const hosts = ["store.steampowered.com", "steamcommunity.com"];
4
+ const steamHandler = {
5
+ match: (url) => {
6
+ return require_utils.isHostOf(url, hosts);
7
+ },
8
+ resolve: (url) => {
9
+ const { hostname, pathname } = new URL(url);
10
+ const appMatch = pathname.match(/^\/(?:news\/)?app\/(\d+)/);
11
+ if (appMatch?.[1]) return [{
12
+ uri: `https://store.steampowered.com/feeds/news/app/${appMatch[1]}/`,
13
+ hint: require_utils.composeHint("steam:news")
14
+ }];
15
+ if (hostname === "steamcommunity.com") {
16
+ const groupMatch = pathname.match(/^\/groups\/([^/]+)/);
17
+ if (groupMatch?.[1]) return [{
18
+ uri: `https://steamcommunity.com/groups/${groupMatch[1]}/rss`,
19
+ hint: require_utils.composeHint("steam:group")
20
+ }];
21
+ }
22
+ return [];
23
+ }
24
+ };
25
+ //#endregion
26
+ exports.steamHandler = steamHandler;
@@ -0,0 +1,26 @@
1
+ import { composeHint, isHostOf } from "../../../common/utils.js";
2
+ //#region src/feeds/platform/handlers/steam.ts
3
+ const hosts = ["store.steampowered.com", "steamcommunity.com"];
4
+ const steamHandler = {
5
+ match: (url) => {
6
+ return isHostOf(url, hosts);
7
+ },
8
+ resolve: (url) => {
9
+ const { hostname, pathname } = new URL(url);
10
+ const appMatch = pathname.match(/^\/(?:news\/)?app\/(\d+)/);
11
+ if (appMatch?.[1]) return [{
12
+ uri: `https://store.steampowered.com/feeds/news/app/${appMatch[1]}/`,
13
+ hint: composeHint("steam:news")
14
+ }];
15
+ if (hostname === "steamcommunity.com") {
16
+ const groupMatch = pathname.match(/^\/groups\/([^/]+)/);
17
+ if (groupMatch?.[1]) return [{
18
+ uri: `https://steamcommunity.com/groups/${groupMatch[1]}/rss`,
19
+ hint: composeHint("steam:group")
20
+ }];
21
+ }
22
+ return [];
23
+ }
24
+ };
25
+ //#endregion
26
+ export { steamHandler };
@@ -1,5 +1,4 @@
1
- const require_utils = require('../../../common/utils.cjs');
2
-
1
+ const require_utils = require("../../../common/utils.cjs");
3
2
  //#region src/feeds/platform/handlers/substack.ts
4
3
  const substackHandler = {
5
4
  match: (url) => {
@@ -7,9 +6,11 @@ const substackHandler = {
7
6
  },
8
7
  resolve: (url) => {
9
8
  const { origin } = new URL(url);
10
- return [`${origin}/feed`];
9
+ return [{
10
+ uri: `${origin}/feed`,
11
+ hint: require_utils.composeHint("substack:newsletter")
12
+ }];
11
13
  }
12
14
  };
13
-
14
15
  //#endregion
15
- exports.substackHandler = substackHandler;
16
+ exports.substackHandler = substackHandler;
@@ -1,5 +1,4 @@
1
- import { isSubdomainOf } from "../../../common/utils.js";
2
-
1
+ import { composeHint, isSubdomainOf } from "../../../common/utils.js";
3
2
  //#region src/feeds/platform/handlers/substack.ts
4
3
  const substackHandler = {
5
4
  match: (url) => {
@@ -7,9 +6,11 @@ const substackHandler = {
7
6
  },
8
7
  resolve: (url) => {
9
8
  const { origin } = new URL(url);
10
- return [`${origin}/feed`];
9
+ return [{
10
+ uri: `${origin}/feed`,
11
+ hint: composeHint("substack:newsletter")
12
+ }];
11
13
  }
12
14
  };
13
-
14
15
  //#endregion
15
- export { substackHandler };
16
+ export { substackHandler };
@@ -1,18 +1,24 @@
1
- const require_utils = require('../../../common/utils.cjs');
2
-
1
+ const require_utils = require("../../../common/utils.cjs");
3
2
  //#region src/feeds/platform/handlers/tumblr.ts
3
+ const domains = ["tumblr.com"];
4
4
  const tagPathRegex = /^\/tagged\/([^/]+)/;
5
5
  const tumblrHandler = {
6
6
  match: (url) => {
7
- return require_utils.isSubdomainOf(url, "tumblr.com");
7
+ return require_utils.isSubdomainOf(url, domains);
8
8
  },
9
9
  resolve: (url) => {
10
10
  const { origin, pathname } = new URL(url);
11
11
  const tagMatch = pathname.match(tagPathRegex);
12
- if (tagMatch?.[1]) return [`${origin}/tagged/${tagMatch[1]}/rss`];
13
- return [`${origin}/rss`];
12
+ if (tagMatch?.[1]) return [{
13
+ uri: `${origin}/tagged/${tagMatch[1]}/rss`,
14
+ hint: require_utils.composeHint("tumblr:tag")
15
+ }];
16
+ return [{
17
+ uri: `${origin}/rss`,
18
+ hint: require_utils.composeHint("tumblr:posts")
19
+ }];
14
20
  }
15
21
  };
16
-
17
22
  //#endregion
18
- exports.tumblrHandler = tumblrHandler;
23
+ exports.domains = domains;
24
+ exports.tumblrHandler = tumblrHandler;
@@ -1,18 +1,23 @@
1
- import { isSubdomainOf } from "../../../common/utils.js";
2
-
1
+ import { composeHint, isSubdomainOf } from "../../../common/utils.js";
3
2
  //#region src/feeds/platform/handlers/tumblr.ts
3
+ const domains = ["tumblr.com"];
4
4
  const tagPathRegex = /^\/tagged\/([^/]+)/;
5
5
  const tumblrHandler = {
6
6
  match: (url) => {
7
- return isSubdomainOf(url, "tumblr.com");
7
+ return isSubdomainOf(url, domains);
8
8
  },
9
9
  resolve: (url) => {
10
10
  const { origin, pathname } = new URL(url);
11
11
  const tagMatch = pathname.match(tagPathRegex);
12
- if (tagMatch?.[1]) return [`${origin}/tagged/${tagMatch[1]}/rss`];
13
- return [`${origin}/rss`];
12
+ if (tagMatch?.[1]) return [{
13
+ uri: `${origin}/tagged/${tagMatch[1]}/rss`,
14
+ hint: composeHint("tumblr:tag")
15
+ }];
16
+ return [{
17
+ uri: `${origin}/rss`,
18
+ hint: composeHint("tumblr:posts")
19
+ }];
14
20
  }
15
21
  };
16
-
17
22
  //#endregion
18
- export { tumblrHandler };
23
+ export { domains, tumblrHandler };
@@ -0,0 +1,33 @@
1
+ const require_utils = require("../../../common/utils.cjs");
2
+ //#region src/feeds/platform/handlers/v2ex.ts
3
+ const hosts = ["www.v2ex.com", "v2ex.com"];
4
+ const v2exHandler = {
5
+ match: (url) => {
6
+ return require_utils.isHostOf(url, hosts);
7
+ },
8
+ resolve: (url) => {
9
+ const { pathname, searchParams } = new URL(url);
10
+ const nodeMatch = pathname.match(/^\/go\/([^/]+)/);
11
+ if (nodeMatch?.[1]) return [{
12
+ uri: `https://www.v2ex.com/feed/${nodeMatch[1]}.xml`,
13
+ hint: require_utils.composeHint("v2ex:node")
14
+ }];
15
+ const memberMatch = pathname.match(/^\/member\/([^/]+)/);
16
+ if (memberMatch?.[1]) return [{
17
+ uri: `https://www.v2ex.com/feed/member/${memberMatch[1]}.xml`,
18
+ hint: require_utils.composeHint("v2ex:member")
19
+ }];
20
+ const tab = searchParams.get("tab");
21
+ if (tab) return [{
22
+ uri: `https://www.v2ex.com/feed/tab/${tab}.xml`,
23
+ hint: require_utils.composeHint("v2ex:tab")
24
+ }];
25
+ if (pathname === "/" || pathname === "") return [{
26
+ uri: "https://www.v2ex.com/index.xml",
27
+ hint: require_utils.composeHint("v2ex:index")
28
+ }];
29
+ return [];
30
+ }
31
+ };
32
+ //#endregion
33
+ exports.v2exHandler = v2exHandler;
@@ -0,0 +1,33 @@
1
+ import { composeHint, isHostOf } from "../../../common/utils.js";
2
+ //#region src/feeds/platform/handlers/v2ex.ts
3
+ const hosts = ["www.v2ex.com", "v2ex.com"];
4
+ const v2exHandler = {
5
+ match: (url) => {
6
+ return isHostOf(url, hosts);
7
+ },
8
+ resolve: (url) => {
9
+ const { pathname, searchParams } = new URL(url);
10
+ const nodeMatch = pathname.match(/^\/go\/([^/]+)/);
11
+ if (nodeMatch?.[1]) return [{
12
+ uri: `https://www.v2ex.com/feed/${nodeMatch[1]}.xml`,
13
+ hint: composeHint("v2ex:node")
14
+ }];
15
+ const memberMatch = pathname.match(/^\/member\/([^/]+)/);
16
+ if (memberMatch?.[1]) return [{
17
+ uri: `https://www.v2ex.com/feed/member/${memberMatch[1]}.xml`,
18
+ hint: composeHint("v2ex:member")
19
+ }];
20
+ const tab = searchParams.get("tab");
21
+ if (tab) return [{
22
+ uri: `https://www.v2ex.com/feed/tab/${tab}.xml`,
23
+ hint: composeHint("v2ex:tab")
24
+ }];
25
+ if (pathname === "/" || pathname === "") return [{
26
+ uri: "https://www.v2ex.com/index.xml",
27
+ hint: composeHint("v2ex:index")
28
+ }];
29
+ return [];
30
+ }
31
+ };
32
+ //#endregion
33
+ export { v2exHandler };
@@ -0,0 +1,68 @@
1
+ const require_utils = require("../../../common/utils.cjs");
2
+ //#region src/feeds/platform/handlers/vimeo.ts
3
+ const hosts = ["vimeo.com", "www.vimeo.com"];
4
+ const excludedPaths = [
5
+ "about",
6
+ "blog",
7
+ "business",
8
+ "careers",
9
+ "categories",
10
+ "channels",
11
+ "create",
12
+ "enterprise",
13
+ "explore",
14
+ "features",
15
+ "for-hire",
16
+ "groups",
17
+ "help",
18
+ "join",
19
+ "log_in",
20
+ "manage",
21
+ "ondemand",
22
+ "ott",
23
+ "plus",
24
+ "pricing",
25
+ "pro",
26
+ "search",
27
+ "settings",
28
+ "site_map",
29
+ "solutions",
30
+ "stock",
31
+ "upload",
32
+ "upgrade",
33
+ "watch"
34
+ ];
35
+ const vimeoHandler = {
36
+ match: (url) => {
37
+ return require_utils.isHostOf(url, hosts);
38
+ },
39
+ resolve: (url) => {
40
+ const { origin, pathname } = new URL(url);
41
+ const pathSegments = pathname.split("/").filter(Boolean);
42
+ if (pathSegments[0] === "channels" && pathSegments[1]) return [{
43
+ uri: `${origin}/channels/${pathSegments[1]}/videos/rss`,
44
+ hint: require_utils.composeHint("vimeo:channel")
45
+ }];
46
+ if (pathSegments[0] === "groups" && pathSegments[1]) return [{
47
+ uri: `${origin}/groups/${pathSegments[1]}/videos/rss`,
48
+ hint: require_utils.composeHint("vimeo:group")
49
+ }];
50
+ if (pathSegments.length >= 1) {
51
+ const user = pathSegments[0];
52
+ if (!require_utils.isAnyOf(user, excludedPaths) && !/^\d+$/.test(user)) {
53
+ const feeds = [{
54
+ uri: `${origin}/${user}/videos/rss`,
55
+ hint: require_utils.composeHint("vimeo:videos")
56
+ }];
57
+ if (pathSegments[1] === "likes") feeds.unshift({
58
+ uri: `${origin}/${user}/likes/rss`,
59
+ hint: require_utils.composeHint("vimeo:likes")
60
+ });
61
+ return feeds;
62
+ }
63
+ }
64
+ return [];
65
+ }
66
+ };
67
+ //#endregion
68
+ exports.vimeoHandler = vimeoHandler;