feedscout 1.8.1 → 1.9.1

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 +18 -11
  3. package/dist/blogrolls/defaults.d.cts +1 -2
  4. package/dist/blogrolls/defaults.d.ts +1 -2
  5. package/dist/blogrolls/defaults.js +19 -11
  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 +18 -0
  15. package/dist/common/uris/html/handlers.js +18 -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 +6 -4
  19. package/dist/common/uris/html/types.d.ts +6 -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 +129 -10
  25. package/dist/feeds/defaults.d.cts +5 -3
  26. package/dist/feeds/defaults.d.ts +5 -3
  27. package/dist/feeds/defaults.js +128 -11
  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 +2 -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,68 @@
1
+ import { composeHint, isAnyOf, isHostOf } from "../../../common/utils.js";
2
+ //#region src/feeds/platform/handlers/nebula.ts
3
+ const hosts = ["nebula.tv", "www.nebula.tv"];
4
+ const excludedPaths = [
5
+ "about",
6
+ "classes",
7
+ "library",
8
+ "login",
9
+ "originals",
10
+ "pricing",
11
+ "privacy",
12
+ "search",
13
+ "settings",
14
+ "signup",
15
+ "terms"
16
+ ];
17
+ const globalPaths = new Set(["videos", "explore"]);
18
+ const nebulaHandler = {
19
+ match: (url) => {
20
+ return isHostOf(url, hosts);
21
+ },
22
+ resolve: (url) => {
23
+ const { pathname, searchParams } = new URL(url);
24
+ const pathSegments = pathname.split("/").filter(Boolean);
25
+ if (pathSegments.length === 0 || globalPaths.has(pathSegments[0])) {
26
+ const rawCategory = searchParams.get("category");
27
+ const category = rawCategory ? rawCategory.toLowerCase() : null;
28
+ const uris = [];
29
+ if (category) {
30
+ uris.push({
31
+ uri: `https://rss.nebula.app/video/categories/${category}.rss`,
32
+ hint: composeHint("nebula:category")
33
+ });
34
+ uris.push({
35
+ uri: `https://rss.nebula.app/video/categories/${category}.rss?plus=true`,
36
+ hint: composeHint("nebula:category-plus")
37
+ });
38
+ }
39
+ uris.push({
40
+ uri: "https://rss.nebula.app/video.rss",
41
+ hint: composeHint("nebula:videos-all")
42
+ });
43
+ uris.push({
44
+ uri: "https://rss.nebula.app/video.rss?plus=true",
45
+ hint: composeHint("nebula:videos-all-plus")
46
+ });
47
+ uris.push({
48
+ uri: "https://rss.nebula.app/video/channels.rss",
49
+ hint: composeHint("nebula:channels")
50
+ });
51
+ return uris;
52
+ }
53
+ const slug = pathSegments[0];
54
+ if (isAnyOf(slug, excludedPaths)) return [];
55
+ const uris = [];
56
+ uris.push({
57
+ uri: `https://rss.nebula.app/video/channels/${slug}.rss`,
58
+ hint: composeHint("nebula:videos")
59
+ });
60
+ uris.push({
61
+ uri: `https://rss.nebula.app/video/channels/${slug}.rss?plus=true`,
62
+ hint: composeHint("nebula:videos-plus")
63
+ });
64
+ return uris;
65
+ }
66
+ };
67
+ //#endregion
68
+ export { nebulaHandler };
@@ -0,0 +1,53 @@
1
+ const require_utils = require("../../../common/utils.cjs");
2
+ //#region src/feeds/platform/handlers/note.ts
3
+ const hosts = ["note.com", "www.note.com"];
4
+ const excludedPaths = [
5
+ "about",
6
+ "api",
7
+ "explore",
8
+ "hashtag",
9
+ "help",
10
+ "login",
11
+ "m",
12
+ "n",
13
+ "premium",
14
+ "privacy",
15
+ "ranking",
16
+ "search",
17
+ "settings",
18
+ "signup",
19
+ "terms"
20
+ ];
21
+ const hashtagRegex = /^\/hashtag\/([^/]+)/;
22
+ const magazineRegex = /^\/([^/]+)\/m\/([^/]+)/;
23
+ const noteHandler = {
24
+ match: (url) => {
25
+ return require_utils.isHostOf(url, hosts);
26
+ },
27
+ resolve: (url) => {
28
+ const { pathname } = new URL(url);
29
+ const hashtagMatch = pathname.match(hashtagRegex);
30
+ if (hashtagMatch?.[1]) return [{
31
+ uri: `https://note.com/hashtag/${hashtagMatch[1]}/rss`,
32
+ hint: require_utils.composeHint("note:hashtag")
33
+ }];
34
+ const magazineMatch = pathname.match(magazineRegex);
35
+ if (magazineMatch?.[1] && magazineMatch?.[2]) return [{
36
+ uri: `https://note.com/${magazineMatch[1]}/m/${magazineMatch[2]}/rss`,
37
+ hint: require_utils.composeHint("note:magazine")
38
+ }];
39
+ const pathSegments = pathname.split("/").filter(Boolean);
40
+ if (pathSegments.length === 0) return [{
41
+ uri: "https://note.com/rss",
42
+ hint: require_utils.composeHint("note:featured")
43
+ }];
44
+ const username = pathSegments[0];
45
+ if (require_utils.isAnyOf(username, excludedPaths)) return [];
46
+ return [{
47
+ uri: `https://note.com/${username}/rss`,
48
+ hint: require_utils.composeHint("note:blog")
49
+ }];
50
+ }
51
+ };
52
+ //#endregion
53
+ exports.noteHandler = noteHandler;
@@ -0,0 +1,53 @@
1
+ import { composeHint, isAnyOf, isHostOf } from "../../../common/utils.js";
2
+ //#region src/feeds/platform/handlers/note.ts
3
+ const hosts = ["note.com", "www.note.com"];
4
+ const excludedPaths = [
5
+ "about",
6
+ "api",
7
+ "explore",
8
+ "hashtag",
9
+ "help",
10
+ "login",
11
+ "m",
12
+ "n",
13
+ "premium",
14
+ "privacy",
15
+ "ranking",
16
+ "search",
17
+ "settings",
18
+ "signup",
19
+ "terms"
20
+ ];
21
+ const hashtagRegex = /^\/hashtag\/([^/]+)/;
22
+ const magazineRegex = /^\/([^/]+)\/m\/([^/]+)/;
23
+ const noteHandler = {
24
+ match: (url) => {
25
+ return isHostOf(url, hosts);
26
+ },
27
+ resolve: (url) => {
28
+ const { pathname } = new URL(url);
29
+ const hashtagMatch = pathname.match(hashtagRegex);
30
+ if (hashtagMatch?.[1]) return [{
31
+ uri: `https://note.com/hashtag/${hashtagMatch[1]}/rss`,
32
+ hint: composeHint("note:hashtag")
33
+ }];
34
+ const magazineMatch = pathname.match(magazineRegex);
35
+ if (magazineMatch?.[1] && magazineMatch?.[2]) return [{
36
+ uri: `https://note.com/${magazineMatch[1]}/m/${magazineMatch[2]}/rss`,
37
+ hint: composeHint("note:magazine")
38
+ }];
39
+ const pathSegments = pathname.split("/").filter(Boolean);
40
+ if (pathSegments.length === 0) return [{
41
+ uri: "https://note.com/rss",
42
+ hint: composeHint("note:featured")
43
+ }];
44
+ const username = pathSegments[0];
45
+ if (isAnyOf(username, excludedPaths)) return [];
46
+ return [{
47
+ uri: `https://note.com/${username}/rss`,
48
+ hint: composeHint("note:blog")
49
+ }];
50
+ }
51
+ };
52
+ //#endregion
53
+ export { noteHandler };
@@ -0,0 +1,34 @@
1
+ const require_utils = require("../../../common/utils.cjs");
2
+ //#region src/feeds/platform/handlers/observable.ts
3
+ const hosts = ["observablehq.com", "www.observablehq.com"];
4
+ const collectionRegex = /^\/@([^/]+)\/collection\/([^/]+)/;
5
+ const userRegex = /^\/@([^/]+)/;
6
+ const observableHandler = {
7
+ match: (url) => {
8
+ return require_utils.isHostOf(url, hosts);
9
+ },
10
+ resolve: (url) => {
11
+ const { pathname } = new URL(url);
12
+ if (pathname === "/recent" || pathname === "/recent/") return [{
13
+ uri: "https://api.observablehq.com/documents/public.rss",
14
+ hint: require_utils.composeHint("observable:recent")
15
+ }];
16
+ if (pathname === "/trending" || pathname === "/trending/") return [{
17
+ uri: "https://api.observablehq.com/documents/trending.rss",
18
+ hint: require_utils.composeHint("observable:trending")
19
+ }];
20
+ const collectionMatch = pathname.match(collectionRegex);
21
+ if (collectionMatch?.[1] && collectionMatch?.[2]) return [{
22
+ uri: `https://api.observablehq.com/collection/@${collectionMatch[1]}/${collectionMatch[2]}.rss`,
23
+ hint: require_utils.composeHint("observable:collection")
24
+ }];
25
+ const userMatch = pathname.match(userRegex);
26
+ if (!userMatch?.[1]) return [];
27
+ return [{
28
+ uri: `https://api.observablehq.com/documents/@${userMatch[1]}.rss`,
29
+ hint: require_utils.composeHint("observable:notebooks")
30
+ }];
31
+ }
32
+ };
33
+ //#endregion
34
+ exports.observableHandler = observableHandler;
@@ -0,0 +1,34 @@
1
+ import { composeHint, isHostOf } from "../../../common/utils.js";
2
+ //#region src/feeds/platform/handlers/observable.ts
3
+ const hosts = ["observablehq.com", "www.observablehq.com"];
4
+ const collectionRegex = /^\/@([^/]+)\/collection\/([^/]+)/;
5
+ const userRegex = /^\/@([^/]+)/;
6
+ const observableHandler = {
7
+ match: (url) => {
8
+ return isHostOf(url, hosts);
9
+ },
10
+ resolve: (url) => {
11
+ const { pathname } = new URL(url);
12
+ if (pathname === "/recent" || pathname === "/recent/") return [{
13
+ uri: "https://api.observablehq.com/documents/public.rss",
14
+ hint: composeHint("observable:recent")
15
+ }];
16
+ if (pathname === "/trending" || pathname === "/trending/") return [{
17
+ uri: "https://api.observablehq.com/documents/trending.rss",
18
+ hint: composeHint("observable:trending")
19
+ }];
20
+ const collectionMatch = pathname.match(collectionRegex);
21
+ if (collectionMatch?.[1] && collectionMatch?.[2]) return [{
22
+ uri: `https://api.observablehq.com/collection/@${collectionMatch[1]}/${collectionMatch[2]}.rss`,
23
+ hint: composeHint("observable:collection")
24
+ }];
25
+ const userMatch = pathname.match(userRegex);
26
+ if (!userMatch?.[1]) return [];
27
+ return [{
28
+ uri: `https://api.observablehq.com/documents/@${userMatch[1]}.rss`,
29
+ hint: composeHint("observable:notebooks")
30
+ }];
31
+ }
32
+ };
33
+ //#endregion
34
+ export { observableHandler };
@@ -0,0 +1,20 @@
1
+ const require_utils = require("../../../common/utils.cjs");
2
+ //#region src/feeds/platform/handlers/odysee.ts
3
+ const hosts = ["odysee.com", "www.odysee.com"];
4
+ const channelRegex = /^\/(@[^/:]+:[a-f0-9]+)/i;
5
+ const odyseeHandler = {
6
+ match: (url) => {
7
+ return require_utils.isHostOf(url, hosts);
8
+ },
9
+ resolve: (url) => {
10
+ const { pathname } = new URL(url);
11
+ const match = pathname.match(channelRegex);
12
+ if (!match?.[1]) return [];
13
+ return [{
14
+ uri: `https://odysee.com/$/rss/${match[1]}`,
15
+ hint: require_utils.composeHint("odysee:videos")
16
+ }];
17
+ }
18
+ };
19
+ //#endregion
20
+ exports.odyseeHandler = odyseeHandler;
@@ -0,0 +1,20 @@
1
+ import { composeHint, isHostOf } from "../../../common/utils.js";
2
+ //#region src/feeds/platform/handlers/odysee.ts
3
+ const hosts = ["odysee.com", "www.odysee.com"];
4
+ const channelRegex = /^\/(@[^/:]+:[a-f0-9]+)/i;
5
+ const odyseeHandler = {
6
+ match: (url) => {
7
+ return isHostOf(url, hosts);
8
+ },
9
+ resolve: (url) => {
10
+ const { pathname } = new URL(url);
11
+ const match = pathname.match(channelRegex);
12
+ if (!match?.[1]) return [];
13
+ return [{
14
+ uri: `https://odysee.com/$/rss/${match[1]}`,
15
+ hint: composeHint("odysee:videos")
16
+ }];
17
+ }
18
+ };
19
+ //#endregion
20
+ export { odyseeHandler };
@@ -0,0 +1,16 @@
1
+ const require_utils = require("../../../common/utils.cjs");
2
+ //#region src/feeds/platform/handlers/pagecord.ts
3
+ const pagecordHandler = {
4
+ match: (url) => {
5
+ return require_utils.isSubdomainOf(url, "pagecord.com") && !require_utils.isHostOf(url, "www.pagecord.com");
6
+ },
7
+ resolve: (url) => {
8
+ const { origin } = new URL(url);
9
+ return [{
10
+ uri: `${origin}/feed.xml`,
11
+ hint: require_utils.composeHint("pagecord:blog")
12
+ }];
13
+ }
14
+ };
15
+ //#endregion
16
+ exports.pagecordHandler = pagecordHandler;
@@ -0,0 +1,16 @@
1
+ import { composeHint, isHostOf, isSubdomainOf } from "../../../common/utils.js";
2
+ //#region src/feeds/platform/handlers/pagecord.ts
3
+ const pagecordHandler = {
4
+ match: (url) => {
5
+ return isSubdomainOf(url, "pagecord.com") && !isHostOf(url, "www.pagecord.com");
6
+ },
7
+ resolve: (url) => {
8
+ const { origin } = new URL(url);
9
+ return [{
10
+ uri: `${origin}/feed.xml`,
11
+ hint: composeHint("pagecord:blog")
12
+ }];
13
+ }
14
+ };
15
+ //#endregion
16
+ export { pagecordHandler };
@@ -10,9 +10,8 @@ const paragraphHandler = {
10
10
  const { pathname } = new URL(url);
11
11
  const userMatch = pathname.match(userRegex);
12
12
  if (!userMatch?.[1]) return [];
13
- const username = userMatch[1];
14
13
  return [{
15
- uri: [`https://paragraph.com/@${username}/feed`, `https://paragraph.com/@${username}/rss`],
14
+ uri: `https://api.paragraph.com/blogs/rss/@${userMatch[1]}`,
16
15
  hint: require_utils.composeHint("paragraph:blog")
17
16
  }];
18
17
  }
@@ -10,9 +10,8 @@ const paragraphHandler = {
10
10
  const { pathname } = new URL(url);
11
11
  const userMatch = pathname.match(userRegex);
12
12
  if (!userMatch?.[1]) return [];
13
- const username = userMatch[1];
14
13
  return [{
15
- uri: [`https://paragraph.com/@${username}/feed`, `https://paragraph.com/@${username}/rss`],
14
+ uri: `https://api.paragraph.com/blogs/rss/@${userMatch[1]}`,
16
15
  hint: composeHint("paragraph:blog")
17
16
  }];
18
17
  }
@@ -0,0 +1,35 @@
1
+ const require_utils = require("../../../common/utils.cjs");
2
+ //#region src/feeds/platform/handlers/pika.ts
3
+ const tagRegex = /^\/tag\/([^/]+)/;
4
+ const pikaHandler = {
5
+ match: (url) => {
6
+ return require_utils.isSubdomainOf(url, "pika.page");
7
+ },
8
+ resolve: (url) => {
9
+ const { origin, pathname } = new URL(url);
10
+ const uris = [];
11
+ const tagMatch = pathname.match(tagRegex);
12
+ if (tagMatch?.[1]) {
13
+ const tag = tagMatch[1];
14
+ uris.push({
15
+ uri: `${origin}/tag/${tag}/feed`,
16
+ hint: require_utils.composeHint("pika:tag-atom")
17
+ });
18
+ uris.push({
19
+ uri: `${origin}/tag/${tag}/feed.rss`,
20
+ hint: require_utils.composeHint("pika:tag-rss")
21
+ });
22
+ }
23
+ uris.push({
24
+ uri: `${origin}/posts_feed`,
25
+ hint: require_utils.composeHint("pika:posts-atom")
26
+ });
27
+ uris.push({
28
+ uri: `${origin}/posts_feed.rss`,
29
+ hint: require_utils.composeHint("pika:posts-rss")
30
+ });
31
+ return uris;
32
+ }
33
+ };
34
+ //#endregion
35
+ exports.pikaHandler = pikaHandler;
@@ -0,0 +1,35 @@
1
+ import { composeHint, isSubdomainOf } from "../../../common/utils.js";
2
+ //#region src/feeds/platform/handlers/pika.ts
3
+ const tagRegex = /^\/tag\/([^/]+)/;
4
+ const pikaHandler = {
5
+ match: (url) => {
6
+ return isSubdomainOf(url, "pika.page");
7
+ },
8
+ resolve: (url) => {
9
+ const { origin, pathname } = new URL(url);
10
+ const uris = [];
11
+ const tagMatch = pathname.match(tagRegex);
12
+ if (tagMatch?.[1]) {
13
+ const tag = tagMatch[1];
14
+ uris.push({
15
+ uri: `${origin}/tag/${tag}/feed`,
16
+ hint: composeHint("pika:tag-atom")
17
+ });
18
+ uris.push({
19
+ uri: `${origin}/tag/${tag}/feed.rss`,
20
+ hint: composeHint("pika:tag-rss")
21
+ });
22
+ }
23
+ uris.push({
24
+ uri: `${origin}/posts_feed`,
25
+ hint: composeHint("pika:posts-atom")
26
+ });
27
+ uris.push({
28
+ uri: `${origin}/posts_feed.rss`,
29
+ hint: composeHint("pika:posts-rss")
30
+ });
31
+ return uris;
32
+ }
33
+ };
34
+ //#endregion
35
+ export { pikaHandler };
@@ -34,6 +34,19 @@ const pinterestHandler = {
34
34
  if (pathSegments.length === 0) return [];
35
35
  const username = pathSegments[0];
36
36
  if (require_utils.isAnyOf(username, excludedPaths)) return [];
37
+ const reservedBoardSlugs = new Set([
38
+ "pins",
39
+ "boards",
40
+ "_saved",
41
+ "_created",
42
+ "followers",
43
+ "following"
44
+ ]);
45
+ const board = pathSegments[1];
46
+ if (board && !reservedBoardSlugs.has(board)) return [{
47
+ uri: `https://www.pinterest.com/${username}/${board}.rss`,
48
+ hint: require_utils.composeHint("pinterest:board")
49
+ }];
37
50
  return [{
38
51
  uri: `https://www.pinterest.com/${username}/feed.rss`,
39
52
  hint: require_utils.composeHint("pinterest:pins")
@@ -34,6 +34,19 @@ const pinterestHandler = {
34
34
  if (pathSegments.length === 0) return [];
35
35
  const username = pathSegments[0];
36
36
  if (isAnyOf(username, excludedPaths)) return [];
37
+ const reservedBoardSlugs = new Set([
38
+ "pins",
39
+ "boards",
40
+ "_saved",
41
+ "_created",
42
+ "followers",
43
+ "following"
44
+ ]);
45
+ const board = pathSegments[1];
46
+ if (board && !reservedBoardSlugs.has(board)) return [{
47
+ uri: `https://www.pinterest.com/${username}/${board}.rss`,
48
+ hint: composeHint("pinterest:board")
49
+ }];
37
50
  return [{
38
51
  uri: `https://www.pinterest.com/${username}/feed.rss`,
39
52
  hint: composeHint("pinterest:pins")
@@ -0,0 +1,46 @@
1
+ const require_utils = require("../../../common/utils.cjs");
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 require_utils.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: require_utils.composeHint("pixelfed:posts")
40
+ }];
41
+ } catch {}
42
+ return [];
43
+ }
44
+ };
45
+ //#endregion
46
+ exports.pixelfedHandler = pixelfedHandler;
@@ -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
+ const require_utils = require("../../../common/utils.cjs");
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: require_utils.composeHint("pleroma:posts")
25
+ }, {
26
+ uri: `${origin}/users/${match[1]}/feed.rss`,
27
+ hint: require_utils.composeHint("pleroma:posts-rss")
28
+ }];
29
+ } catch {}
30
+ return [];
31
+ }
32
+ };
33
+ //#endregion
34
+ exports.pleromaHandler = pleromaHandler;
@@ -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,29 @@
1
+ const require_utils = require("../../../common/utils.cjs");
2
+ //#region src/feeds/platform/handlers/podbean.ts
3
+ const domainSuffix = /\.podbean\.com$/i;
4
+ const reservedSlugs = new Set([
5
+ "www",
6
+ "feed",
7
+ "pbcdn1",
8
+ "sponsorship",
9
+ "podads",
10
+ "help",
11
+ "blog",
12
+ "support"
13
+ ]);
14
+ const podbeanHandler = {
15
+ match: (url) => {
16
+ if (!require_utils.isSubdomainOf(url, "podbean.com")) return false;
17
+ const slug = new URL(url).hostname.toLowerCase().replace(domainSuffix, "");
18
+ return !reservedSlugs.has(slug);
19
+ },
20
+ resolve: (url) => {
21
+ const { hostname } = new URL(url);
22
+ return [{
23
+ uri: `https://feed.podbean.com/${hostname.replace(domainSuffix, "")}/feed.xml`,
24
+ hint: require_utils.composeHint("podbean:podcast")
25
+ }];
26
+ }
27
+ };
28
+ //#endregion
29
+ exports.podbeanHandler = podbeanHandler;