feedscout 1.8.1 → 1.9.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 (192) hide show
  1. package/README.md +1 -1
  2. package/dist/blogrolls/defaults.cjs +16 -10
  3. package/dist/blogrolls/defaults.d.cts +1 -2
  4. package/dist/blogrolls/defaults.d.ts +1 -2
  5. package/dist/blogrolls/defaults.js +17 -10
  6. package/dist/blogrolls.cjs +0 -1
  7. package/dist/blogrolls.d.cts +2 -2
  8. package/dist/blogrolls.d.ts +2 -2
  9. package/dist/blogrolls.js +2 -2
  10. package/dist/common/locales.cjs +214 -10
  11. package/dist/common/locales.js +214 -10
  12. package/dist/common/types.d.cts +2 -1
  13. package/dist/common/types.d.ts +2 -1
  14. package/dist/common/uris/html/handlers.cjs +14 -0
  15. package/dist/common/uris/html/handlers.js +14 -0
  16. package/dist/common/uris/html/index.cjs +17 -1
  17. package/dist/common/uris/html/index.js +17 -1
  18. package/dist/common/uris/html/types.d.cts +5 -4
  19. package/dist/common/uris/html/types.d.ts +5 -4
  20. package/dist/common/utils.cjs +12 -3
  21. package/dist/common/utils.d.cts +6 -4
  22. package/dist/common/utils.d.ts +6 -4
  23. package/dist/common/utils.js +12 -3
  24. package/dist/feeds/defaults.cjs +121 -9
  25. package/dist/feeds/defaults.d.cts +4 -3
  26. package/dist/feeds/defaults.d.ts +4 -3
  27. package/dist/feeds/defaults.js +121 -10
  28. package/dist/feeds/platform/handlers/acast.cjs +26 -0
  29. package/dist/feeds/platform/handlers/acast.js +26 -0
  30. package/dist/feeds/platform/handlers/ameblo.cjs +36 -0
  31. package/dist/feeds/platform/handlers/ameblo.js +36 -0
  32. package/dist/feeds/platform/handlers/applePodcasts.cjs +1 -1
  33. package/dist/feeds/platform/handlers/applePodcasts.js +1 -1
  34. package/dist/feeds/platform/handlers/arena.cjs +42 -0
  35. package/dist/feeds/platform/handlers/arena.js +42 -0
  36. package/dist/feeds/platform/handlers/artstation.cjs +52 -0
  37. package/dist/feeds/platform/handlers/artstation.js +52 -0
  38. package/dist/feeds/platform/handlers/audioboom.cjs +23 -0
  39. package/dist/feeds/platform/handlers/audioboom.js +23 -0
  40. package/dist/feeds/platform/handlers/bearblog.cjs +45 -0
  41. package/dist/feeds/platform/handlers/bearblog.js +45 -0
  42. package/dist/feeds/platform/handlers/behance.cjs +7 -0
  43. package/dist/feeds/platform/handlers/behance.js +7 -0
  44. package/dist/feeds/platform/handlers/blogspot.cjs +38 -2
  45. package/dist/feeds/platform/handlers/blogspot.js +38 -2
  46. package/dist/feeds/platform/handlers/bookwyrm.cjs +48 -0
  47. package/dist/feeds/platform/handlers/bookwyrm.js +48 -0
  48. package/dist/feeds/platform/handlers/buttondown.cjs +43 -0
  49. package/dist/feeds/platform/handlers/buttondown.js +43 -0
  50. package/dist/feeds/platform/handlers/buzzsprout.cjs +22 -0
  51. package/dist/feeds/platform/handlers/buzzsprout.js +22 -0
  52. package/dist/feeds/platform/handlers/codeberg.cjs +5 -5
  53. package/dist/feeds/platform/handlers/codeberg.js +5 -5
  54. package/dist/feeds/platform/handlers/dailymotion.cjs +16 -0
  55. package/dist/feeds/platform/handlers/dailymotion.js +16 -0
  56. package/dist/feeds/platform/handlers/deviantart.cjs +25 -6
  57. package/dist/feeds/platform/handlers/deviantart.js +25 -6
  58. package/dist/feeds/platform/handlers/devto.cjs +8 -0
  59. package/dist/feeds/platform/handlers/devto.js +8 -0
  60. package/dist/feeds/platform/handlers/discourse.cjs +70 -0
  61. package/dist/feeds/platform/handlers/discourse.js +70 -0
  62. package/dist/feeds/platform/handlers/dreamwidth.cjs +48 -0
  63. package/dist/feeds/platform/handlers/dreamwidth.js +48 -0
  64. package/dist/feeds/platform/handlers/exblog.cjs +35 -0
  65. package/dist/feeds/platform/handlers/exblog.js +35 -0
  66. package/dist/feeds/platform/handlers/fireside.cjs +24 -0
  67. package/dist/feeds/platform/handlers/fireside.js +24 -0
  68. package/dist/feeds/platform/handlers/friendica.cjs +44 -0
  69. package/dist/feeds/platform/handlers/friendica.js +44 -0
  70. package/dist/feeds/platform/handlers/ghost.cjs +30 -0
  71. package/dist/feeds/platform/handlers/ghost.js +30 -0
  72. package/dist/feeds/platform/handlers/github.cjs +6 -0
  73. package/dist/feeds/platform/handlers/github.js +6 -0
  74. package/dist/feeds/platform/handlers/githubGist.cjs +16 -5
  75. package/dist/feeds/platform/handlers/githubGist.js +16 -5
  76. package/dist/feeds/platform/handlers/gitlab.cjs +31 -13
  77. package/dist/feeds/platform/handlers/gitlab.js +31 -13
  78. package/dist/feeds/platform/handlers/goodreads.cjs +18 -8
  79. package/dist/feeds/platform/handlers/goodreads.js +18 -8
  80. package/dist/feeds/platform/handlers/hackernews.cjs +21 -0
  81. package/dist/feeds/platform/handlers/hackernews.js +21 -0
  82. package/dist/feeds/platform/handlers/hashnode.cjs +1 -1
  83. package/dist/feeds/platform/handlers/hashnode.js +1 -1
  84. package/dist/feeds/platform/handlers/hatenablog.cjs +4 -1
  85. package/dist/feeds/platform/handlers/hatenablog.js +4 -1
  86. package/dist/feeds/platform/handlers/hearthis.cjs +32 -0
  87. package/dist/feeds/platform/handlers/hearthis.js +32 -0
  88. package/dist/feeds/platform/handlers/heyWorld.cjs +18 -0
  89. package/dist/feeds/platform/handlers/heyWorld.js +18 -0
  90. package/dist/feeds/platform/handlers/insanejournal.cjs +69 -0
  91. package/dist/feeds/platform/handlers/insanejournal.js +69 -0
  92. package/dist/feeds/platform/handlers/itchio.cjs +24 -1
  93. package/dist/feeds/platform/handlers/itchio.js +24 -1
  94. package/dist/feeds/platform/handlers/lemmy.cjs +46 -4
  95. package/dist/feeds/platform/handlers/lemmy.js +46 -4
  96. package/dist/feeds/platform/handlers/letterboxd.cjs +4 -0
  97. package/dist/feeds/platform/handlers/letterboxd.js +4 -0
  98. package/dist/feeds/platform/handlers/libsyn.cjs +25 -0
  99. package/dist/feeds/platform/handlers/libsyn.js +25 -0
  100. package/dist/feeds/platform/handlers/listed.cjs +20 -0
  101. package/dist/feeds/platform/handlers/listed.js +20 -0
  102. package/dist/feeds/platform/handlers/livejournal.cjs +68 -0
  103. package/dist/feeds/platform/handlers/livejournal.js +68 -0
  104. package/dist/feeds/platform/handlers/mastodon.cjs +32 -0
  105. package/dist/feeds/platform/handlers/mastodon.js +32 -0
  106. package/dist/feeds/platform/handlers/mataroa.cjs +16 -0
  107. package/dist/feeds/platform/handlers/mataroa.js +16 -0
  108. package/dist/feeds/platform/handlers/medium.cjs +2 -2
  109. package/dist/feeds/platform/handlers/medium.js +2 -2
  110. package/dist/feeds/platform/handlers/microblog.cjs +55 -0
  111. package/dist/feeds/platform/handlers/microblog.js +55 -0
  112. package/dist/feeds/platform/handlers/misskey.cjs +40 -0
  113. package/dist/feeds/platform/handlers/misskey.js +40 -0
  114. package/dist/feeds/platform/handlers/myanimelist.cjs +43 -0
  115. package/dist/feeds/platform/handlers/myanimelist.js +43 -0
  116. package/dist/feeds/platform/handlers/naverBlog.cjs +21 -0
  117. package/dist/feeds/platform/handlers/naverBlog.js +21 -0
  118. package/dist/feeds/platform/handlers/nebula.cjs +68 -0
  119. package/dist/feeds/platform/handlers/nebula.js +68 -0
  120. package/dist/feeds/platform/handlers/note.cjs +53 -0
  121. package/dist/feeds/platform/handlers/note.js +53 -0
  122. package/dist/feeds/platform/handlers/observable.cjs +34 -0
  123. package/dist/feeds/platform/handlers/observable.js +34 -0
  124. package/dist/feeds/platform/handlers/odysee.cjs +20 -0
  125. package/dist/feeds/platform/handlers/odysee.js +20 -0
  126. package/dist/feeds/platform/handlers/pagecord.cjs +16 -0
  127. package/dist/feeds/platform/handlers/pagecord.js +16 -0
  128. package/dist/feeds/platform/handlers/paragraph.cjs +1 -2
  129. package/dist/feeds/platform/handlers/paragraph.js +1 -2
  130. package/dist/feeds/platform/handlers/pika.cjs +35 -0
  131. package/dist/feeds/platform/handlers/pika.js +35 -0
  132. package/dist/feeds/platform/handlers/pinterest.cjs +13 -0
  133. package/dist/feeds/platform/handlers/pinterest.js +13 -0
  134. package/dist/feeds/platform/handlers/pixelfed.cjs +46 -0
  135. package/dist/feeds/platform/handlers/pixelfed.js +46 -0
  136. package/dist/feeds/platform/handlers/pleroma.cjs +34 -0
  137. package/dist/feeds/platform/handlers/pleroma.js +34 -0
  138. package/dist/feeds/platform/handlers/podbean.cjs +29 -0
  139. package/dist/feeds/platform/handlers/podbean.js +29 -0
  140. package/dist/feeds/platform/handlers/podigee.cjs +29 -0
  141. package/dist/feeds/platform/handlers/podigee.js +29 -0
  142. package/dist/feeds/platform/handlers/posthaven.cjs +24 -0
  143. package/dist/feeds/platform/handlers/posthaven.js +24 -0
  144. package/dist/feeds/platform/handlers/prose.cjs +26 -0
  145. package/dist/feeds/platform/handlers/prose.js +26 -0
  146. package/dist/feeds/platform/handlers/qiita.cjs +58 -0
  147. package/dist/feeds/platform/handlers/qiita.js +58 -0
  148. package/dist/feeds/platform/handlers/reddit.cjs +83 -9
  149. package/dist/feeds/platform/handlers/reddit.js +83 -9
  150. package/dist/feeds/platform/handlers/rssCom.cjs +20 -0
  151. package/dist/feeds/platform/handlers/rssCom.js +20 -0
  152. package/dist/feeds/platform/handlers/seesaa.cjs +22 -0
  153. package/dist/feeds/platform/handlers/seesaa.js +22 -0
  154. package/dist/feeds/platform/handlers/sourceforge.cjs +37 -4
  155. package/dist/feeds/platform/handlers/sourceforge.js +37 -4
  156. package/dist/feeds/platform/handlers/spreaker.cjs +21 -0
  157. package/dist/feeds/platform/handlers/spreaker.js +21 -0
  158. package/dist/feeds/platform/handlers/stackExchange.cjs +26 -2
  159. package/dist/feeds/platform/handlers/stackExchange.js +26 -2
  160. package/dist/feeds/platform/handlers/steam.cjs +7 -0
  161. package/dist/feeds/platform/handlers/steam.js +7 -0
  162. package/dist/feeds/platform/handlers/tildes.cjs +41 -0
  163. package/dist/feeds/platform/handlers/tildes.js +41 -0
  164. package/dist/feeds/platform/handlers/tistory.cjs +16 -0
  165. package/dist/feeds/platform/handlers/tistory.js +16 -0
  166. package/dist/feeds/platform/handlers/transistor.cjs +29 -0
  167. package/dist/feeds/platform/handlers/transistor.js +29 -0
  168. package/dist/feeds/platform/handlers/velog.cjs +24 -0
  169. package/dist/feeds/platform/handlers/velog.js +24 -0
  170. package/dist/feeds/platform/handlers/vimeo.cjs +6 -0
  171. package/dist/feeds/platform/handlers/vimeo.js +6 -0
  172. package/dist/feeds/platform/handlers/weblogLol.cjs +26 -0
  173. package/dist/feeds/platform/handlers/weblogLol.js +26 -0
  174. package/dist/feeds/platform/handlers/weebly.cjs +25 -0
  175. package/dist/feeds/platform/handlers/weebly.js +25 -0
  176. package/dist/feeds/platform/handlers/wordpress.cjs +173 -28
  177. package/dist/feeds/platform/handlers/wordpress.js +173 -28
  178. package/dist/feeds/platform/handlers/writeas.cjs +51 -0
  179. package/dist/feeds/platform/handlers/writeas.js +51 -0
  180. package/dist/feeds/platform/handlers/ximalaya.cjs +1 -1
  181. package/dist/feeds/platform/handlers/ximalaya.js +1 -1
  182. package/dist/feeds/platform/handlers/youtube.cjs +4 -1
  183. package/dist/feeds/platform/handlers/youtube.js +4 -1
  184. package/dist/feeds/platform/handlers/zenn.cjs +54 -0
  185. package/dist/feeds/platform/handlers/zenn.js +54 -0
  186. package/dist/feeds.cjs +1 -0
  187. package/dist/feeds.d.cts +2 -2
  188. package/dist/feeds.d.ts +2 -2
  189. package/dist/feeds.js +2 -2
  190. package/dist/utils.d.cts +2 -1
  191. package/dist/utils.d.ts +2 -1
  192. package/package.json +6 -7
@@ -0,0 +1,22 @@
1
+ const require_utils = require("../../../common/utils.cjs");
2
+ //#region src/feeds/platform/handlers/buzzsprout.ts
3
+ const hosts = ["buzzsprout.com", "www.buzzsprout.com"];
4
+ const numericRegex = /^\d+$/;
5
+ const buzzsproutHandler = {
6
+ match: (url) => {
7
+ return require_utils.isHostOf(url, hosts);
8
+ },
9
+ resolve: (url) => {
10
+ const { pathname } = new URL(url);
11
+ const pathSegments = pathname.split("/").filter(Boolean);
12
+ if (pathSegments.length === 0) return [];
13
+ const podcastId = pathSegments[0];
14
+ if (!numericRegex.test(podcastId)) return [];
15
+ return [{
16
+ uri: `https://rss.buzzsprout.com/${podcastId}.rss`,
17
+ hint: require_utils.composeHint("buzzsprout:podcast")
18
+ }];
19
+ }
20
+ };
21
+ //#endregion
22
+ exports.buzzsproutHandler = buzzsproutHandler;
@@ -0,0 +1,22 @@
1
+ import { composeHint, isHostOf } from "../../../common/utils.js";
2
+ //#region src/feeds/platform/handlers/buzzsprout.ts
3
+ const hosts = ["buzzsprout.com", "www.buzzsprout.com"];
4
+ const numericRegex = /^\d+$/;
5
+ const buzzsproutHandler = {
6
+ match: (url) => {
7
+ return isHostOf(url, hosts);
8
+ },
9
+ resolve: (url) => {
10
+ const { pathname } = new URL(url);
11
+ const pathSegments = pathname.split("/").filter(Boolean);
12
+ if (pathSegments.length === 0) return [];
13
+ const podcastId = pathSegments[0];
14
+ if (!numericRegex.test(podcastId)) return [];
15
+ return [{
16
+ uri: `https://rss.buzzsprout.com/${podcastId}.rss`,
17
+ hint: composeHint("buzzsprout:podcast")
18
+ }];
19
+ }
20
+ };
21
+ //#endregion
22
+ export { buzzsproutHandler };
@@ -27,7 +27,7 @@ const codebergHandler = {
27
27
  if (pathSegments.length === 1) {
28
28
  const user = pathSegments[0];
29
29
  if (!require_utils.isAnyOf(user, excludedPaths)) return [{
30
- uri: `${origin}/${user}.rss`,
30
+ uri: [`${origin}/${user}.atom`, `${origin}/${user}.rss`],
31
31
  hint: require_utils.composeHint("codeberg:activity")
32
32
  }];
33
33
  }
@@ -37,19 +37,19 @@ const codebergHandler = {
37
37
  if (!require_utils.isAnyOf(user, excludedPaths)) {
38
38
  const feeds = [
39
39
  {
40
- uri: `${origin}/${user}/${repo}/releases.rss`,
40
+ uri: [`${origin}/${user}/${repo}/releases.atom`, `${origin}/${user}/${repo}/releases.rss`],
41
41
  hint: require_utils.composeHint("codeberg:releases")
42
42
  },
43
43
  {
44
- uri: `${origin}/${user}/${repo}/tags.rss`,
44
+ uri: [`${origin}/${user}/${repo}/tags.atom`, `${origin}/${user}/${repo}/tags.rss`],
45
45
  hint: require_utils.composeHint("codeberg:tags")
46
46
  },
47
47
  {
48
- uri: `${origin}/${user}/${repo}.rss`,
48
+ uri: [`${origin}/${user}/${repo}.atom`, `${origin}/${user}/${repo}.rss`],
49
49
  hint: require_utils.composeHint("codeberg:activity")
50
50
  }
51
51
  ];
52
- if (pathSegments[2] === "src" && pathSegments[3] === "branch" && pathSegments[4]) {
52
+ if (require_utils.isHostOf(url, ["gitea.com", "www.gitea.com"]) && pathSegments[2] === "src" && pathSegments[3] === "branch" && pathSegments[4]) {
53
53
  const branch = pathSegments[4];
54
54
  const filePath = pathSegments.slice(5).join("/");
55
55
  feeds.unshift({
@@ -27,7 +27,7 @@ const codebergHandler = {
27
27
  if (pathSegments.length === 1) {
28
28
  const user = pathSegments[0];
29
29
  if (!isAnyOf(user, excludedPaths)) return [{
30
- uri: `${origin}/${user}.rss`,
30
+ uri: [`${origin}/${user}.atom`, `${origin}/${user}.rss`],
31
31
  hint: composeHint("codeberg:activity")
32
32
  }];
33
33
  }
@@ -37,19 +37,19 @@ const codebergHandler = {
37
37
  if (!isAnyOf(user, excludedPaths)) {
38
38
  const feeds = [
39
39
  {
40
- uri: `${origin}/${user}/${repo}/releases.rss`,
40
+ uri: [`${origin}/${user}/${repo}/releases.atom`, `${origin}/${user}/${repo}/releases.rss`],
41
41
  hint: composeHint("codeberg:releases")
42
42
  },
43
43
  {
44
- uri: `${origin}/${user}/${repo}/tags.rss`,
44
+ uri: [`${origin}/${user}/${repo}/tags.atom`, `${origin}/${user}/${repo}/tags.rss`],
45
45
  hint: composeHint("codeberg:tags")
46
46
  },
47
47
  {
48
- uri: `${origin}/${user}/${repo}.rss`,
48
+ uri: [`${origin}/${user}/${repo}.atom`, `${origin}/${user}/${repo}.rss`],
49
49
  hint: composeHint("codeberg:activity")
50
50
  }
51
51
  ];
52
- if (pathSegments[2] === "src" && pathSegments[3] === "branch" && pathSegments[4]) {
52
+ if (isHostOf(url, ["gitea.com", "www.gitea.com"]) && pathSegments[2] === "src" && pathSegments[3] === "branch" && pathSegments[4]) {
53
53
  const branch = pathSegments[4];
54
54
  const filePath = pathSegments.slice(5).join("/");
55
55
  feeds.unshift({
@@ -3,6 +3,8 @@ const require_utils = require("../../../common/utils.cjs");
3
3
  const hosts = ["dailymotion.com", "www.dailymotion.com"];
4
4
  const userRegex = /^\/([a-zA-Z0-9_-]+)$/;
5
5
  const playlistRegex = /^\/playlist\/([a-zA-Z0-9_-]+)/;
6
+ const channelRegex = /^\/channel\/([a-zA-Z0-9_-]+)/;
7
+ const searchRegex = /^\/search\/([^/]+)/;
6
8
  const excludedPaths = [
7
9
  "signin",
8
10
  "signout",
@@ -50,11 +52,25 @@ const dailymotionHandler = {
50
52
  },
51
53
  resolve: (url) => {
52
54
  const { pathname } = new URL(url);
55
+ if (pathname === "/" || pathname === "" || pathname === "/trending") return [{
56
+ uri: "https://www.dailymotion.com/rss/trending",
57
+ hint: require_utils.composeHint("dailymotion:trending")
58
+ }];
53
59
  const playlistMatch = pathname.match(playlistRegex);
54
60
  if (playlistMatch?.[1]) return [{
55
61
  uri: `https://www.dailymotion.com/rss/playlist/${playlistMatch[1]}`,
56
62
  hint: require_utils.composeHint("dailymotion:playlist")
57
63
  }];
64
+ const searchMatch = pathname.match(searchRegex);
65
+ if (searchMatch?.[1]) return [{
66
+ uri: `https://www.dailymotion.com/rss/search/${searchMatch[1]}`,
67
+ hint: require_utils.composeHint("dailymotion:search")
68
+ }];
69
+ const channelMatch = pathname.match(channelRegex);
70
+ if (channelMatch?.[1]) return [{
71
+ uri: `https://www.dailymotion.com/rss/channel/${channelMatch[1]}`,
72
+ hint: require_utils.composeHint("dailymotion:channel")
73
+ }];
58
74
  const userMatch = pathname.match(userRegex);
59
75
  if (userMatch?.[1]) {
60
76
  const username = userMatch[1];
@@ -3,6 +3,8 @@ import { composeHint, isAnyOf, isHostOf } from "../../../common/utils.js";
3
3
  const hosts = ["dailymotion.com", "www.dailymotion.com"];
4
4
  const userRegex = /^\/([a-zA-Z0-9_-]+)$/;
5
5
  const playlistRegex = /^\/playlist\/([a-zA-Z0-9_-]+)/;
6
+ const channelRegex = /^\/channel\/([a-zA-Z0-9_-]+)/;
7
+ const searchRegex = /^\/search\/([^/]+)/;
6
8
  const excludedPaths = [
7
9
  "signin",
8
10
  "signout",
@@ -50,11 +52,25 @@ const dailymotionHandler = {
50
52
  },
51
53
  resolve: (url) => {
52
54
  const { pathname } = new URL(url);
55
+ if (pathname === "/" || pathname === "" || pathname === "/trending") return [{
56
+ uri: "https://www.dailymotion.com/rss/trending",
57
+ hint: composeHint("dailymotion:trending")
58
+ }];
53
59
  const playlistMatch = pathname.match(playlistRegex);
54
60
  if (playlistMatch?.[1]) return [{
55
61
  uri: `https://www.dailymotion.com/rss/playlist/${playlistMatch[1]}`,
56
62
  hint: composeHint("dailymotion:playlist")
57
63
  }];
64
+ const searchMatch = pathname.match(searchRegex);
65
+ if (searchMatch?.[1]) return [{
66
+ uri: `https://www.dailymotion.com/rss/search/${searchMatch[1]}`,
67
+ hint: composeHint("dailymotion:search")
68
+ }];
69
+ const channelMatch = pathname.match(channelRegex);
70
+ if (channelMatch?.[1]) return [{
71
+ uri: `https://www.dailymotion.com/rss/channel/${channelMatch[1]}`,
72
+ hint: composeHint("dailymotion:channel")
73
+ }];
58
74
  const userMatch = pathname.match(userRegex);
59
75
  if (userMatch?.[1]) {
60
76
  const username = userMatch[1];
@@ -3,22 +3,25 @@ const require_utils = require("../../../common/utils.cjs");
3
3
  const tagRegex = /^\/tag\/([^/]+)/;
4
4
  const favouritesRegex = /^\/([a-zA-Z0-9_-]+)\/favourites\/?$/;
5
5
  const folderRegex = /^\/([a-zA-Z0-9_-]+)\/gallery\/(\d+)(?:\/|$)/;
6
+ const journalRegex = /^\/([a-zA-Z0-9_-]+)\/journal(?:\/|$)/;
6
7
  const profileRegex = /^\/([a-zA-Z0-9_-]+)(?:\/gallery(?:\/all)?)?(?:\/|$)/;
7
8
  const hosts = ["deviantart.com", "www.deviantart.com"];
8
9
  const feedBaseUrl = "https://backend.deviantart.com/rss.xml";
9
10
  const excludedPaths = [
10
11
  "about",
12
+ "core-membership",
13
+ "daily-deviations",
14
+ "developers",
11
15
  "join",
12
- "search",
13
- "topic",
14
- "watch",
15
16
  "notifications",
17
+ "popular",
18
+ "search",
16
19
  "settings",
17
- "submit",
18
20
  "shop",
19
- "core-membership",
21
+ "submit",
20
22
  "team",
21
- "developers"
23
+ "topic",
24
+ "watch"
22
25
  ];
23
26
  const deviantartHandler = {
24
27
  match: (url) => {
@@ -26,6 +29,14 @@ const deviantartHandler = {
26
29
  },
27
30
  resolve: (url) => {
28
31
  const { pathname } = new URL(url);
32
+ if (pathname === "/daily-deviations" || pathname === "/daily-deviations/") return [{
33
+ uri: `${feedBaseUrl}?q=${encodeURIComponent("special:dd")}`,
34
+ hint: require_utils.composeHint("deviantart:daily-deviations")
35
+ }];
36
+ if (pathname === "/popular" || pathname === "/popular/") return [{
37
+ uri: `${feedBaseUrl}?type=deviation&q=${encodeURIComponent("boost:popular")}`,
38
+ hint: require_utils.composeHint("deviantart:popular")
39
+ }];
29
40
  const tagMatch = pathname.match(tagRegex);
30
41
  if (tagMatch?.[1]) {
31
42
  const tag = tagMatch[1];
@@ -51,6 +62,14 @@ const deviantartHandler = {
51
62
  hint: require_utils.composeHint("deviantart:gallery")
52
63
  }];
53
64
  }
65
+ const journalMatch = pathname.match(journalRegex);
66
+ if (journalMatch?.[1]) {
67
+ const username = journalMatch[1];
68
+ if (!require_utils.isAnyOf(username, excludedPaths)) return [{
69
+ uri: `${feedBaseUrl}?q=${encodeURIComponent(`journal:${username}`)}`,
70
+ hint: require_utils.composeHint("deviantart:journal")
71
+ }];
72
+ }
54
73
  const username = pathname.match(profileRegex)?.[1];
55
74
  if (!username || require_utils.isAnyOf(username, excludedPaths)) return [];
56
75
  const query = `by:${username} sort:time meta:all`;
@@ -3,22 +3,25 @@ import { composeHint, isAnyOf, isHostOf } from "../../../common/utils.js";
3
3
  const tagRegex = /^\/tag\/([^/]+)/;
4
4
  const favouritesRegex = /^\/([a-zA-Z0-9_-]+)\/favourites\/?$/;
5
5
  const folderRegex = /^\/([a-zA-Z0-9_-]+)\/gallery\/(\d+)(?:\/|$)/;
6
+ const journalRegex = /^\/([a-zA-Z0-9_-]+)\/journal(?:\/|$)/;
6
7
  const profileRegex = /^\/([a-zA-Z0-9_-]+)(?:\/gallery(?:\/all)?)?(?:\/|$)/;
7
8
  const hosts = ["deviantart.com", "www.deviantart.com"];
8
9
  const feedBaseUrl = "https://backend.deviantart.com/rss.xml";
9
10
  const excludedPaths = [
10
11
  "about",
12
+ "core-membership",
13
+ "daily-deviations",
14
+ "developers",
11
15
  "join",
12
- "search",
13
- "topic",
14
- "watch",
15
16
  "notifications",
17
+ "popular",
18
+ "search",
16
19
  "settings",
17
- "submit",
18
20
  "shop",
19
- "core-membership",
21
+ "submit",
20
22
  "team",
21
- "developers"
23
+ "topic",
24
+ "watch"
22
25
  ];
23
26
  const deviantartHandler = {
24
27
  match: (url) => {
@@ -26,6 +29,14 @@ const deviantartHandler = {
26
29
  },
27
30
  resolve: (url) => {
28
31
  const { pathname } = new URL(url);
32
+ if (pathname === "/daily-deviations" || pathname === "/daily-deviations/") return [{
33
+ uri: `${feedBaseUrl}?q=${encodeURIComponent("special:dd")}`,
34
+ hint: composeHint("deviantart:daily-deviations")
35
+ }];
36
+ if (pathname === "/popular" || pathname === "/popular/") return [{
37
+ uri: `${feedBaseUrl}?type=deviation&q=${encodeURIComponent("boost:popular")}`,
38
+ hint: composeHint("deviantart:popular")
39
+ }];
29
40
  const tagMatch = pathname.match(tagRegex);
30
41
  if (tagMatch?.[1]) {
31
42
  const tag = tagMatch[1];
@@ -51,6 +62,14 @@ const deviantartHandler = {
51
62
  hint: composeHint("deviantart:gallery")
52
63
  }];
53
64
  }
65
+ const journalMatch = pathname.match(journalRegex);
66
+ if (journalMatch?.[1]) {
67
+ const username = journalMatch[1];
68
+ if (!isAnyOf(username, excludedPaths)) return [{
69
+ uri: `${feedBaseUrl}?q=${encodeURIComponent(`journal:${username}`)}`,
70
+ hint: composeHint("deviantart:journal")
71
+ }];
72
+ }
54
73
  const username = pathname.match(profileRegex)?.[1];
55
74
  if (!username || isAnyOf(username, excludedPaths)) return [];
56
75
  const query = `by:${username} sort:time meta:all`;
@@ -28,6 +28,14 @@ const devtoHandler = {
28
28
  },
29
29
  resolve: (url) => {
30
30
  const { pathname } = new URL(url);
31
+ if (pathname === "/" || pathname === "") return [{
32
+ uri: "https://dev.to/feed",
33
+ hint: require_utils.composeHint("devto:community")
34
+ }];
35
+ if (pathname === "/latest" || pathname === "/latest/") return [{
36
+ uri: "https://dev.to/feed/latest",
37
+ hint: require_utils.composeHint("devto:latest")
38
+ }];
31
39
  const userMatch = pathname.match(userRegex);
32
40
  if (userMatch?.[1]) {
33
41
  const username = userMatch[1];
@@ -28,6 +28,14 @@ const devtoHandler = {
28
28
  },
29
29
  resolve: (url) => {
30
30
  const { pathname } = new URL(url);
31
+ if (pathname === "/" || pathname === "") return [{
32
+ uri: "https://dev.to/feed",
33
+ hint: composeHint("devto:community")
34
+ }];
35
+ if (pathname === "/latest" || pathname === "/latest/") return [{
36
+ uri: "https://dev.to/feed/latest",
37
+ hint: composeHint("devto:latest")
38
+ }];
31
39
  const userMatch = pathname.match(userRegex);
32
40
  if (userMatch?.[1]) {
33
41
  const username = userMatch[1];
@@ -0,0 +1,70 @@
1
+ const require_utils = require("../../../common/utils.cjs");
2
+ //#region src/feeds/platform/handlers/discourse.ts
3
+ const userRegex = /^\/u\/([^/]+)/;
4
+ const categoryRegex = /^\/c\/(.+?)\/?$/;
5
+ const topicRegex = /^\/t\/([^/]+)\/(\d+)/;
6
+ const topRegex = /^\/top(?:\/([^/]+))?\/?$/;
7
+ const validTopPeriods = new Set([
8
+ "daily",
9
+ "weekly",
10
+ "monthly",
11
+ "quarterly",
12
+ "yearly",
13
+ "all"
14
+ ]);
15
+ const getTopPeriodSuffix = (pathPeriod, searchParams) => {
16
+ const period = pathPeriod ?? searchParams.get("period") ?? void 0;
17
+ if (period && validTopPeriods.has(period)) return `?period=${period}`;
18
+ return "";
19
+ };
20
+ const isDiscourseHtml = (content) => {
21
+ return require_utils.hasMetaContent(content, "generator", "Discourse");
22
+ };
23
+ const discourseHandler = {
24
+ match: (url, content) => {
25
+ try {
26
+ if (!content || !isDiscourseHtml(content)) return false;
27
+ new URL(url);
28
+ return true;
29
+ } catch {}
30
+ return false;
31
+ },
32
+ resolve: (url) => {
33
+ try {
34
+ const { origin, pathname, searchParams } = new URL(url);
35
+ const topicMatch = pathname.match(topicRegex);
36
+ if (topicMatch?.[1] && topicMatch?.[2]) return [{
37
+ uri: `${origin}/t/${topicMatch[1]}/${topicMatch[2]}.rss`,
38
+ hint: require_utils.composeHint("discourse:topic")
39
+ }];
40
+ const userMatch = pathname.match(userRegex);
41
+ if (userMatch?.[1]) return [{
42
+ uri: `${origin}/u/${userMatch[1]}/activity.rss`,
43
+ hint: require_utils.composeHint("discourse:activity")
44
+ }];
45
+ const categoryMatch = pathname.match(categoryRegex);
46
+ if (categoryMatch?.[1]) return [{
47
+ uri: `${origin}/c/${categoryMatch[1]}.rss`,
48
+ hint: require_utils.composeHint("discourse:category")
49
+ }];
50
+ const topMatch = pathname.match(topRegex);
51
+ if (topMatch) return [{
52
+ uri: `${origin}/top.rss${getTopPeriodSuffix(topMatch[1], searchParams)}`,
53
+ hint: require_utils.composeHint("discourse:top")
54
+ }];
55
+ const uris = [];
56
+ uris.push({
57
+ uri: `${origin}/latest.rss`,
58
+ hint: require_utils.composeHint("discourse:latest")
59
+ });
60
+ uris.push({
61
+ uri: `${origin}/posts.rss`,
62
+ hint: require_utils.composeHint("discourse:posts")
63
+ });
64
+ return uris;
65
+ } catch {}
66
+ return [];
67
+ }
68
+ };
69
+ //#endregion
70
+ exports.discourseHandler = discourseHandler;
@@ -0,0 +1,70 @@
1
+ import { composeHint, hasMetaContent } from "../../../common/utils.js";
2
+ //#region src/feeds/platform/handlers/discourse.ts
3
+ const userRegex = /^\/u\/([^/]+)/;
4
+ const categoryRegex = /^\/c\/(.+?)\/?$/;
5
+ const topicRegex = /^\/t\/([^/]+)\/(\d+)/;
6
+ const topRegex = /^\/top(?:\/([^/]+))?\/?$/;
7
+ const validTopPeriods = new Set([
8
+ "daily",
9
+ "weekly",
10
+ "monthly",
11
+ "quarterly",
12
+ "yearly",
13
+ "all"
14
+ ]);
15
+ const getTopPeriodSuffix = (pathPeriod, searchParams) => {
16
+ const period = pathPeriod ?? searchParams.get("period") ?? void 0;
17
+ if (period && validTopPeriods.has(period)) return `?period=${period}`;
18
+ return "";
19
+ };
20
+ const isDiscourseHtml = (content) => {
21
+ return hasMetaContent(content, "generator", "Discourse");
22
+ };
23
+ const discourseHandler = {
24
+ match: (url, content) => {
25
+ try {
26
+ if (!content || !isDiscourseHtml(content)) return false;
27
+ new URL(url);
28
+ return true;
29
+ } catch {}
30
+ return false;
31
+ },
32
+ resolve: (url) => {
33
+ try {
34
+ const { origin, pathname, searchParams } = new URL(url);
35
+ const topicMatch = pathname.match(topicRegex);
36
+ if (topicMatch?.[1] && topicMatch?.[2]) return [{
37
+ uri: `${origin}/t/${topicMatch[1]}/${topicMatch[2]}.rss`,
38
+ hint: composeHint("discourse:topic")
39
+ }];
40
+ const userMatch = pathname.match(userRegex);
41
+ if (userMatch?.[1]) return [{
42
+ uri: `${origin}/u/${userMatch[1]}/activity.rss`,
43
+ hint: composeHint("discourse:activity")
44
+ }];
45
+ const categoryMatch = pathname.match(categoryRegex);
46
+ if (categoryMatch?.[1]) return [{
47
+ uri: `${origin}/c/${categoryMatch[1]}.rss`,
48
+ hint: composeHint("discourse:category")
49
+ }];
50
+ const topMatch = pathname.match(topRegex);
51
+ if (topMatch) return [{
52
+ uri: `${origin}/top.rss${getTopPeriodSuffix(topMatch[1], searchParams)}`,
53
+ hint: composeHint("discourse:top")
54
+ }];
55
+ const uris = [];
56
+ uris.push({
57
+ uri: `${origin}/latest.rss`,
58
+ hint: composeHint("discourse:latest")
59
+ });
60
+ uris.push({
61
+ uri: `${origin}/posts.rss`,
62
+ hint: composeHint("discourse:posts")
63
+ });
64
+ return uris;
65
+ } catch {}
66
+ return [];
67
+ }
68
+ };
69
+ //#endregion
70
+ export { discourseHandler };
@@ -0,0 +1,48 @@
1
+ const require_utils = require("../../../common/utils.cjs");
2
+ //#region src/feeds/platform/handlers/dreamwidth.ts
3
+ const usersPathRegex = /^\/(?:users\/|~)([^/]+)/;
4
+ const tagRegex = /^\/tag\/([^/]+)/;
5
+ const dreamwidthHandler = {
6
+ match: (url) => {
7
+ if (!require_utils.isSubdomainOf(url, "dreamwidth.org")) return false;
8
+ if (require_utils.isHostOf(url, ["www.dreamwidth.org", "dreamwidth.org"])) return usersPathRegex.test(new URL(url).pathname);
9
+ return true;
10
+ },
11
+ resolve: (url) => {
12
+ const { origin, pathname } = new URL(url);
13
+ const uris = [];
14
+ let userOrigin = origin;
15
+ if (require_utils.isHostOf(url, ["www.dreamwidth.org", "dreamwidth.org"])) {
16
+ const userMatch = pathname.match(usersPathRegex);
17
+ if (userMatch?.[1]) userOrigin = `https://${userMatch[1]}.dreamwidth.org`;
18
+ else return uris;
19
+ }
20
+ const tagMatch = pathname.match(tagRegex);
21
+ if (tagMatch?.[1]) {
22
+ const tag = encodeURIComponent(tagMatch[1]);
23
+ uris.push({
24
+ uri: `${userOrigin}/data/rss?tag=${tag}`,
25
+ hint: require_utils.composeHint("dreamwidth:posts-tag-rss")
26
+ });
27
+ uris.push({
28
+ uri: `${userOrigin}/data/atom?tag=${tag}`,
29
+ hint: require_utils.composeHint("dreamwidth:posts-tag-atom")
30
+ });
31
+ }
32
+ uris.push({
33
+ uri: `${userOrigin}/data/rss`,
34
+ hint: require_utils.composeHint("dreamwidth:posts-rss")
35
+ });
36
+ uris.push({
37
+ uri: `${userOrigin}/data/atom`,
38
+ hint: require_utils.composeHint("dreamwidth:posts-atom")
39
+ });
40
+ uris.push({
41
+ uri: `${userOrigin}/data/userpics`,
42
+ hint: require_utils.composeHint("dreamwidth:userpics-atom")
43
+ });
44
+ return uris;
45
+ }
46
+ };
47
+ //#endregion
48
+ exports.dreamwidthHandler = dreamwidthHandler;
@@ -0,0 +1,48 @@
1
+ import { composeHint, isHostOf, isSubdomainOf } from "../../../common/utils.js";
2
+ //#region src/feeds/platform/handlers/dreamwidth.ts
3
+ const usersPathRegex = /^\/(?:users\/|~)([^/]+)/;
4
+ const tagRegex = /^\/tag\/([^/]+)/;
5
+ const dreamwidthHandler = {
6
+ match: (url) => {
7
+ if (!isSubdomainOf(url, "dreamwidth.org")) return false;
8
+ if (isHostOf(url, ["www.dreamwidth.org", "dreamwidth.org"])) return usersPathRegex.test(new URL(url).pathname);
9
+ return true;
10
+ },
11
+ resolve: (url) => {
12
+ const { origin, pathname } = new URL(url);
13
+ const uris = [];
14
+ let userOrigin = origin;
15
+ if (isHostOf(url, ["www.dreamwidth.org", "dreamwidth.org"])) {
16
+ const userMatch = pathname.match(usersPathRegex);
17
+ if (userMatch?.[1]) userOrigin = `https://${userMatch[1]}.dreamwidth.org`;
18
+ else return uris;
19
+ }
20
+ const tagMatch = pathname.match(tagRegex);
21
+ if (tagMatch?.[1]) {
22
+ const tag = encodeURIComponent(tagMatch[1]);
23
+ uris.push({
24
+ uri: `${userOrigin}/data/rss?tag=${tag}`,
25
+ hint: composeHint("dreamwidth:posts-tag-rss")
26
+ });
27
+ uris.push({
28
+ uri: `${userOrigin}/data/atom?tag=${tag}`,
29
+ hint: composeHint("dreamwidth:posts-tag-atom")
30
+ });
31
+ }
32
+ uris.push({
33
+ uri: `${userOrigin}/data/rss`,
34
+ hint: composeHint("dreamwidth:posts-rss")
35
+ });
36
+ uris.push({
37
+ uri: `${userOrigin}/data/atom`,
38
+ hint: composeHint("dreamwidth:posts-atom")
39
+ });
40
+ uris.push({
41
+ uri: `${userOrigin}/data/userpics`,
42
+ hint: composeHint("dreamwidth:userpics-atom")
43
+ });
44
+ return uris;
45
+ }
46
+ };
47
+ //#endregion
48
+ export { dreamwidthHandler };
@@ -0,0 +1,35 @@
1
+ const require_utils = require("../../../common/utils.cjs");
2
+ //#region src/feeds/platform/handlers/exblog.ts
3
+ const categoryRegex = /^\/i(\d+)/;
4
+ const exblogHandler = {
5
+ match: (url) => {
6
+ return require_utils.isSubdomainOf(url, "exblog.jp");
7
+ },
8
+ resolve: (url) => {
9
+ const { origin, pathname } = new URL(url);
10
+ const uris = [];
11
+ const categoryMatch = pathname.match(categoryRegex);
12
+ if (categoryMatch?.[1]) {
13
+ const categoryId = categoryMatch[1];
14
+ uris.push({
15
+ uri: `${origin}/i${categoryId}/index.xml`,
16
+ hint: require_utils.composeHint("exblog:category-rss")
17
+ });
18
+ uris.push({
19
+ uri: `${origin}/i${categoryId}/atom.xml`,
20
+ hint: require_utils.composeHint("exblog:category-atom")
21
+ });
22
+ }
23
+ uris.push({
24
+ uri: `${origin}/index.xml`,
25
+ hint: require_utils.composeHint("exblog:posts-rss")
26
+ });
27
+ uris.push({
28
+ uri: `${origin}/atom.xml`,
29
+ hint: require_utils.composeHint("exblog:posts-atom")
30
+ });
31
+ return uris;
32
+ }
33
+ };
34
+ //#endregion
35
+ exports.exblogHandler = exblogHandler;
@@ -0,0 +1,35 @@
1
+ import { composeHint, isSubdomainOf } from "../../../common/utils.js";
2
+ //#region src/feeds/platform/handlers/exblog.ts
3
+ const categoryRegex = /^\/i(\d+)/;
4
+ const exblogHandler = {
5
+ match: (url) => {
6
+ return isSubdomainOf(url, "exblog.jp");
7
+ },
8
+ resolve: (url) => {
9
+ const { origin, pathname } = new URL(url);
10
+ const uris = [];
11
+ const categoryMatch = pathname.match(categoryRegex);
12
+ if (categoryMatch?.[1]) {
13
+ const categoryId = categoryMatch[1];
14
+ uris.push({
15
+ uri: `${origin}/i${categoryId}/index.xml`,
16
+ hint: composeHint("exblog:category-rss")
17
+ });
18
+ uris.push({
19
+ uri: `${origin}/i${categoryId}/atom.xml`,
20
+ hint: composeHint("exblog:category-atom")
21
+ });
22
+ }
23
+ uris.push({
24
+ uri: `${origin}/index.xml`,
25
+ hint: composeHint("exblog:posts-rss")
26
+ });
27
+ uris.push({
28
+ uri: `${origin}/atom.xml`,
29
+ hint: composeHint("exblog:posts-atom")
30
+ });
31
+ return uris;
32
+ }
33
+ };
34
+ //#endregion
35
+ export { exblogHandler };
@@ -0,0 +1,24 @@
1
+ const require_utils = require("../../../common/utils.cjs");
2
+ //#region src/feeds/platform/handlers/fireside.ts
3
+ const domainSuffix = /\.fireside\.fm$/i;
4
+ const firesideHandler = {
5
+ match: (url) => {
6
+ return require_utils.isSubdomainOf(url, "fireside.fm");
7
+ },
8
+ resolve: (url) => {
9
+ const { hostname } = new URL(url);
10
+ const slug = hostname.replace(domainSuffix, "");
11
+ const uris = [];
12
+ uris.push({
13
+ uri: `https://feeds.fireside.fm/${slug}/rss`,
14
+ hint: require_utils.composeHint("fireside:podcast-rss")
15
+ });
16
+ uris.push({
17
+ uri: `https://${slug}.fireside.fm/json`,
18
+ hint: require_utils.composeHint("fireside:podcast-json")
19
+ });
20
+ return uris;
21
+ }
22
+ };
23
+ //#endregion
24
+ exports.firesideHandler = firesideHandler;