feedscout 1.0.0 → 1.2.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 (98) hide show
  1. package/README.md +10 -7
  2. package/dist/blogrolls/index.cjs +9 -3
  3. package/dist/blogrolls/index.d.cts +1 -1
  4. package/dist/blogrolls/index.d.ts +1 -1
  5. package/dist/blogrolls/index.js +9 -3
  6. package/dist/common/discover/utils.cjs +26 -0
  7. package/dist/common/discover/utils.js +26 -1
  8. package/dist/common/locales.cjs +1 -0
  9. package/dist/common/locales.js +1 -0
  10. package/dist/common/types.d.cts +7 -5
  11. package/dist/common/types.d.ts +7 -5
  12. package/dist/common/uris/headers/index.cjs +6 -3
  13. package/dist/common/uris/headers/index.js +6 -3
  14. package/dist/common/uris/index.cjs +2 -0
  15. package/dist/common/uris/index.js +2 -0
  16. package/dist/common/uris/platform/index.cjs +12 -0
  17. package/dist/common/uris/platform/index.js +11 -0
  18. package/dist/common/uris/platform/types.d.cts +11 -0
  19. package/dist/common/uris/platform/types.d.ts +11 -0
  20. package/dist/common/utils.cjs +10 -0
  21. package/dist/common/utils.d.cts +9 -0
  22. package/dist/common/utils.d.ts +9 -0
  23. package/dist/common/utils.js +7 -1
  24. package/dist/feeds/defaults.cjs +43 -0
  25. package/dist/feeds/defaults.d.cts +3 -1
  26. package/dist/feeds/defaults.d.ts +3 -1
  27. package/dist/feeds/defaults.js +44 -1
  28. package/dist/feeds/index.cjs +10 -3
  29. package/dist/feeds/index.d.cts +1 -1
  30. package/dist/feeds/index.d.ts +1 -1
  31. package/dist/feeds/index.js +11 -4
  32. package/dist/feeds/platform/handlers/behance.cjs +45 -0
  33. package/dist/feeds/platform/handlers/behance.js +45 -0
  34. package/dist/feeds/platform/handlers/blogspot.cjs +24 -0
  35. package/dist/feeds/platform/handlers/blogspot.js +23 -0
  36. package/dist/feeds/platform/handlers/bluesky.cjs +18 -0
  37. package/dist/feeds/platform/handlers/bluesky.js +18 -0
  38. package/dist/feeds/platform/handlers/dailymotion.cjs +66 -0
  39. package/dist/feeds/platform/handlers/dailymotion.js +66 -0
  40. package/dist/feeds/platform/handlers/deviantart.cjs +50 -0
  41. package/dist/feeds/platform/handlers/deviantart.js +50 -0
  42. package/dist/feeds/platform/handlers/devto.cjs +44 -0
  43. package/dist/feeds/platform/handlers/devto.js +44 -0
  44. package/dist/feeds/platform/handlers/github.cjs +89 -0
  45. package/dist/feeds/platform/handlers/github.js +89 -0
  46. package/dist/feeds/platform/handlers/githubGist.cjs +42 -0
  47. package/dist/feeds/platform/handlers/githubGist.js +42 -0
  48. package/dist/feeds/platform/handlers/gitlab.cjs +53 -0
  49. package/dist/feeds/platform/handlers/gitlab.js +53 -0
  50. package/dist/feeds/platform/handlers/kickstarter.cjs +18 -0
  51. package/dist/feeds/platform/handlers/kickstarter.js +18 -0
  52. package/dist/feeds/platform/handlers/lobsters.cjs +34 -0
  53. package/dist/feeds/platform/handlers/lobsters.js +34 -0
  54. package/dist/feeds/platform/handlers/medium.cjs +47 -0
  55. package/dist/feeds/platform/handlers/medium.js +47 -0
  56. package/dist/feeds/platform/handlers/pinterest.cjs +48 -0
  57. package/dist/feeds/platform/handlers/pinterest.js +48 -0
  58. package/dist/feeds/platform/handlers/producthunt.cjs +22 -0
  59. package/dist/feeds/platform/handlers/producthunt.js +22 -0
  60. package/dist/feeds/platform/handlers/reddit.cjs +47 -0
  61. package/dist/feeds/platform/handlers/reddit.js +47 -0
  62. package/dist/feeds/platform/handlers/soundcloud.cjs +37 -0
  63. package/dist/feeds/platform/handlers/soundcloud.js +37 -0
  64. package/dist/feeds/platform/handlers/substack.cjs +15 -0
  65. package/dist/feeds/platform/handlers/substack.js +15 -0
  66. package/dist/feeds/platform/handlers/tumblr.cjs +18 -0
  67. package/dist/feeds/platform/handlers/tumblr.js +18 -0
  68. package/dist/feeds/platform/handlers/wordpress.cjs +30 -0
  69. package/dist/feeds/platform/handlers/wordpress.js +30 -0
  70. package/dist/feeds/platform/handlers/youtube.cjs +56 -0
  71. package/dist/feeds/platform/handlers/youtube.js +56 -0
  72. package/dist/feeds.cjs +1 -0
  73. package/dist/feeds.d.cts +2 -2
  74. package/dist/feeds.d.ts +2 -2
  75. package/dist/feeds.js +2 -2
  76. package/dist/hubs/discover/index.cjs +7 -6
  77. package/dist/hubs/discover/index.js +5 -4
  78. package/dist/hubs/discover/types.d.cts +2 -1
  79. package/dist/hubs/discover/types.d.ts +2 -1
  80. package/dist/hubs/headers/index.cjs +3 -3
  81. package/dist/hubs/headers/index.js +3 -3
  82. package/dist/hubs/html/index.cjs +3 -3
  83. package/dist/hubs/html/index.js +3 -3
  84. package/dist/index.d.cts +2 -2
  85. package/dist/index.d.ts +2 -2
  86. package/dist/utils.cjs +8 -0
  87. package/dist/utils.d.cts +2 -0
  88. package/dist/utils.d.ts +2 -0
  89. package/dist/utils.js +3 -0
  90. package/package.json +32 -32
  91. package/dist/adapters.cjs +0 -6
  92. package/dist/adapters.d.cts +0 -2
  93. package/dist/adapters.d.ts +0 -2
  94. package/dist/adapters.js +0 -3
  95. package/dist/common/discover/adapters.cjs +0 -76
  96. package/dist/common/discover/adapters.d.cts +0 -10
  97. package/dist/common/discover/adapters.d.ts +0 -10
  98. package/dist/common/discover/adapters.js +0 -72
@@ -1,3 +1,24 @@
1
+ import { behanceHandler } from "./platform/handlers/behance.js";
2
+ import { blogspotHandler } from "./platform/handlers/blogspot.js";
3
+ import { blueskyHandler } from "./platform/handlers/bluesky.js";
4
+ import { dailymotionHandler } from "./platform/handlers/dailymotion.js";
5
+ import { deviantartHandler } from "./platform/handlers/deviantart.js";
6
+ import { devtoHandler } from "./platform/handlers/devto.js";
7
+ import { githubHandler } from "./platform/handlers/github.js";
8
+ import { githubGistHandler } from "./platform/handlers/githubGist.js";
9
+ import { gitlabHandler } from "./platform/handlers/gitlab.js";
10
+ import { kickstarterHandler } from "./platform/handlers/kickstarter.js";
11
+ import { lobstersHandler } from "./platform/handlers/lobsters.js";
12
+ import { mediumHandler } from "./platform/handlers/medium.js";
13
+ import { pinterestHandler } from "./platform/handlers/pinterest.js";
14
+ import { producthuntHandler } from "./platform/handlers/producthunt.js";
15
+ import { redditHandler } from "./platform/handlers/reddit.js";
16
+ import { soundcloudHandler } from "./platform/handlers/soundcloud.js";
17
+ import { substackHandler } from "./platform/handlers/substack.js";
18
+ import { tumblrHandler } from "./platform/handlers/tumblr.js";
19
+ import { wordpressHandler } from "./platform/handlers/wordpress.js";
20
+ import { youtubeHandler } from "./platform/handlers/youtube.js";
21
+
1
22
  //#region src/feeds/defaults.ts
2
23
  const mimeTypes = [
3
24
  "application/rss+xml",
@@ -74,6 +95,28 @@ const defaultHtmlOptions = {
74
95
  };
75
96
  const defaultHeadersOptions = { linkSelectors };
76
97
  const defaultGuessOptions = { uris: urisBalanced };
98
+ const defaultPlatformOptions = { handlers: [
99
+ behanceHandler,
100
+ blogspotHandler,
101
+ blueskyHandler,
102
+ deviantartHandler,
103
+ dailymotionHandler,
104
+ devtoHandler,
105
+ githubHandler,
106
+ githubGistHandler,
107
+ gitlabHandler,
108
+ kickstarterHandler,
109
+ mediumHandler,
110
+ pinterestHandler,
111
+ producthuntHandler,
112
+ lobstersHandler,
113
+ redditHandler,
114
+ soundcloudHandler,
115
+ substackHandler,
116
+ tumblrHandler,
117
+ wordpressHandler,
118
+ youtubeHandler
119
+ ] };
77
120
 
78
121
  //#endregion
79
- export { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, ignoredUris, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
122
+ export { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
@@ -1,17 +1,24 @@
1
- const require_adapters = require('../common/discover/adapters.cjs');
2
1
  const require_utils = require('../common/utils.cjs');
2
+ const require_utils$1 = require('../common/discover/utils.cjs');
3
3
  const require_index = require('../common/discover/index.cjs');
4
4
  const require_defaults = require('./defaults.cjs');
5
5
  const require_extractors = require('./extractors.cjs');
6
6
 
7
7
  //#region src/feeds/index.ts
8
- const discoverFeeds = async (input, options) => {
8
+ const discoverFeeds = async (input, options = {}) => {
9
9
  return require_index.discover(input, {
10
10
  ...options,
11
- fetchFn: options.fetchFn ?? require_adapters.createNativeFetchAdapter(),
11
+ methods: options.methods ?? [
12
+ "platform",
13
+ "html",
14
+ "headers",
15
+ "guess"
16
+ ],
17
+ fetchFn: options.fetchFn ?? require_utils$1.defaultFetchFn,
12
18
  extractFn: options.extractFn ?? require_extractors.defaultExtractor,
13
19
  normalizeUrlFn: options.normalizeUrlFn ?? require_utils.normalizeUrl
14
20
  }, {
21
+ platform: require_defaults.defaultPlatformOptions,
15
22
  html: require_defaults.defaultHtmlOptions,
16
23
  headers: require_defaults.defaultHeadersOptions,
17
24
  guess: require_defaults.defaultGuessOptions
@@ -2,6 +2,6 @@ import { DiscoverInput, DiscoverOptions, DiscoverResult } from "../common/types.
2
2
  import { FeedResult } from "./types.cjs";
3
3
 
4
4
  //#region src/feeds/index.d.ts
5
- declare const discoverFeeds: <TValid extends FeedResult = FeedResult>(input: DiscoverInput, options: DiscoverOptions<TValid>) => Promise<Array<DiscoverResult<TValid>>>;
5
+ declare const discoverFeeds: <TValid extends FeedResult = FeedResult>(input: DiscoverInput, options?: DiscoverOptions<TValid>) => Promise<Array<DiscoverResult<TValid>>>;
6
6
  //#endregion
7
7
  export { discoverFeeds };
@@ -2,6 +2,6 @@ import { DiscoverInput, DiscoverOptions, DiscoverResult } from "../common/types.
2
2
  import { FeedResult } from "./types.js";
3
3
 
4
4
  //#region src/feeds/index.d.ts
5
- declare const discoverFeeds: <TValid extends FeedResult = FeedResult>(input: DiscoverInput, options: DiscoverOptions<TValid>) => Promise<Array<DiscoverResult<TValid>>>;
5
+ declare const discoverFeeds: <TValid extends FeedResult = FeedResult>(input: DiscoverInput, options?: DiscoverOptions<TValid>) => Promise<Array<DiscoverResult<TValid>>>;
6
6
  //#endregion
7
7
  export { discoverFeeds };
@@ -1,17 +1,24 @@
1
- import { createNativeFetchAdapter } from "../common/discover/adapters.js";
2
1
  import { normalizeUrl } from "../common/utils.js";
2
+ import { defaultFetchFn } from "../common/discover/utils.js";
3
3
  import { discover } from "../common/discover/index.js";
4
- import { defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions } from "./defaults.js";
4
+ import { defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions } from "./defaults.js";
5
5
  import { defaultExtractor } from "./extractors.js";
6
6
 
7
7
  //#region src/feeds/index.ts
8
- const discoverFeeds = async (input, options) => {
8
+ const discoverFeeds = async (input, options = {}) => {
9
9
  return discover(input, {
10
10
  ...options,
11
- fetchFn: options.fetchFn ?? createNativeFetchAdapter(),
11
+ methods: options.methods ?? [
12
+ "platform",
13
+ "html",
14
+ "headers",
15
+ "guess"
16
+ ],
17
+ fetchFn: options.fetchFn ?? defaultFetchFn,
12
18
  extractFn: options.extractFn ?? defaultExtractor,
13
19
  normalizeUrlFn: options.normalizeUrlFn ?? normalizeUrl
14
20
  }, {
21
+ platform: defaultPlatformOptions,
15
22
  html: defaultHtmlOptions,
16
23
  headers: defaultHeadersOptions,
17
24
  guess: defaultGuessOptions
@@ -0,0 +1,45 @@
1
+ const require_utils = require('../../../common/utils.cjs');
2
+
3
+ //#region src/feeds/platform/handlers/behance.ts
4
+ const hosts = ["behance.net", "www.behance.net"];
5
+ const userPathRegex = /^\/([a-zA-Z0-9_-]+)(?:\/(appreciated))?\/?$/;
6
+ const excludedPaths = [
7
+ "search",
8
+ "galleries",
9
+ "curated",
10
+ "features",
11
+ "live",
12
+ "joblist",
13
+ "hire",
14
+ "blog",
15
+ "about",
16
+ "privacy",
17
+ "tos",
18
+ "help",
19
+ "onboarding",
20
+ "settings",
21
+ "notifications",
22
+ "messages",
23
+ "adobe"
24
+ ];
25
+ const behanceHandler = {
26
+ match: (url) => {
27
+ return require_utils.isHostOf(url, hosts);
28
+ },
29
+ resolve: (url) => {
30
+ const { pathname } = new URL(url);
31
+ const userMatch = pathname.match(userPathRegex);
32
+ if (userMatch?.[1]) {
33
+ const username = userMatch[1];
34
+ const subpage = userMatch[2];
35
+ if (!require_utils.isAnyOf(username, excludedPaths)) {
36
+ if (subpage === "appreciated") return [`https://www.behance.net/feeds/user?username=${username}&content=appreciated`];
37
+ return [`https://www.behance.net/feeds/user?username=${username}`];
38
+ }
39
+ }
40
+ return [];
41
+ }
42
+ };
43
+
44
+ //#endregion
45
+ exports.behanceHandler = behanceHandler;
@@ -0,0 +1,45 @@
1
+ import { isAnyOf, isHostOf } from "../../../common/utils.js";
2
+
3
+ //#region src/feeds/platform/handlers/behance.ts
4
+ const hosts = ["behance.net", "www.behance.net"];
5
+ const userPathRegex = /^\/([a-zA-Z0-9_-]+)(?:\/(appreciated))?\/?$/;
6
+ const excludedPaths = [
7
+ "search",
8
+ "galleries",
9
+ "curated",
10
+ "features",
11
+ "live",
12
+ "joblist",
13
+ "hire",
14
+ "blog",
15
+ "about",
16
+ "privacy",
17
+ "tos",
18
+ "help",
19
+ "onboarding",
20
+ "settings",
21
+ "notifications",
22
+ "messages",
23
+ "adobe"
24
+ ];
25
+ const behanceHandler = {
26
+ match: (url) => {
27
+ return isHostOf(url, hosts);
28
+ },
29
+ resolve: (url) => {
30
+ const { pathname } = new URL(url);
31
+ const userMatch = pathname.match(userPathRegex);
32
+ if (userMatch?.[1]) {
33
+ const username = userMatch[1];
34
+ const subpage = userMatch[2];
35
+ if (!isAnyOf(username, excludedPaths)) {
36
+ if (subpage === "appreciated") return [`https://www.behance.net/feeds/user?username=${username}&content=appreciated`];
37
+ return [`https://www.behance.net/feeds/user?username=${username}`];
38
+ }
39
+ }
40
+ return [];
41
+ }
42
+ };
43
+
44
+ //#endregion
45
+ export { behanceHandler };
@@ -0,0 +1,24 @@
1
+
2
+ //#region src/feeds/platform/handlers/blogspot.ts
3
+ const blogspotDomainRegex = /^.+\.blogspot\.(?:com|co\.[a-z]{2}|com\.[a-z]{2}|[a-z]{2,3})$/;
4
+ const blogspotHandler = {
5
+ match: (url) => {
6
+ const hostname = new URL(url).hostname.toLowerCase();
7
+ return blogspotDomainRegex.test(hostname);
8
+ },
9
+ resolve: (url) => {
10
+ const { origin, pathname } = new URL(url);
11
+ const uris = [];
12
+ const labelMatch = pathname.match(/^\/search\/label\/([^/]+)/);
13
+ if (labelMatch?.[1]) {
14
+ const label = labelMatch[1];
15
+ uris.push(`${origin}/feeds/posts/default/-/${label}`);
16
+ }
17
+ uris.push(`${origin}/feeds/posts/default`);
18
+ uris.push(`${origin}/feeds/posts/default?alt=rss`);
19
+ return uris;
20
+ }
21
+ };
22
+
23
+ //#endregion
24
+ exports.blogspotHandler = blogspotHandler;
@@ -0,0 +1,23 @@
1
+ //#region src/feeds/platform/handlers/blogspot.ts
2
+ const blogspotDomainRegex = /^.+\.blogspot\.(?:com|co\.[a-z]{2}|com\.[a-z]{2}|[a-z]{2,3})$/;
3
+ const blogspotHandler = {
4
+ match: (url) => {
5
+ const hostname = new URL(url).hostname.toLowerCase();
6
+ return blogspotDomainRegex.test(hostname);
7
+ },
8
+ resolve: (url) => {
9
+ const { origin, pathname } = new URL(url);
10
+ const uris = [];
11
+ const labelMatch = pathname.match(/^\/search\/label\/([^/]+)/);
12
+ if (labelMatch?.[1]) {
13
+ const label = labelMatch[1];
14
+ uris.push(`${origin}/feeds/posts/default/-/${label}`);
15
+ }
16
+ uris.push(`${origin}/feeds/posts/default`);
17
+ uris.push(`${origin}/feeds/posts/default?alt=rss`);
18
+ return uris;
19
+ }
20
+ };
21
+
22
+ //#endregion
23
+ export { blogspotHandler };
@@ -0,0 +1,18 @@
1
+ const require_utils = require('../../../common/utils.cjs');
2
+
3
+ //#region src/feeds/platform/handlers/bluesky.ts
4
+ const hosts = ["bsky.app"];
5
+ const blueskyHandler = {
6
+ match: (url) => {
7
+ return require_utils.isHostOf(url, hosts);
8
+ },
9
+ resolve: (url) => {
10
+ const { pathname } = new URL(url);
11
+ const handle = pathname.match(/^\/profile\/([^/]+)/)?.[1];
12
+ if (!handle) return [];
13
+ return [`https://bsky.app/profile/${handle}/rss`];
14
+ }
15
+ };
16
+
17
+ //#endregion
18
+ exports.blueskyHandler = blueskyHandler;
@@ -0,0 +1,18 @@
1
+ import { isHostOf } from "../../../common/utils.js";
2
+
3
+ //#region src/feeds/platform/handlers/bluesky.ts
4
+ const hosts = ["bsky.app"];
5
+ const blueskyHandler = {
6
+ match: (url) => {
7
+ return isHostOf(url, hosts);
8
+ },
9
+ resolve: (url) => {
10
+ const { pathname } = new URL(url);
11
+ const handle = pathname.match(/^\/profile\/([^/]+)/)?.[1];
12
+ if (!handle) return [];
13
+ return [`https://bsky.app/profile/${handle}/rss`];
14
+ }
15
+ };
16
+
17
+ //#endregion
18
+ export { blueskyHandler };
@@ -0,0 +1,66 @@
1
+ const require_utils = require('../../../common/utils.cjs');
2
+
3
+ //#region src/feeds/platform/handlers/dailymotion.ts
4
+ const hosts = ["dailymotion.com", "www.dailymotion.com"];
5
+ const userPathRegex = /^\/([a-zA-Z0-9_-]+)$/;
6
+ const playlistPathRegex = /^\/playlist\/([a-zA-Z0-9_-]+)/;
7
+ const excludedPaths = [
8
+ "signin",
9
+ "signout",
10
+ "signup",
11
+ "login",
12
+ "logout",
13
+ "register",
14
+ "search",
15
+ "legal",
16
+ "about",
17
+ "careers",
18
+ "terms",
19
+ "privacy",
20
+ "feedback",
21
+ "help",
22
+ "settings",
23
+ "upload",
24
+ "partner",
25
+ "monetize",
26
+ "studio",
27
+ "video",
28
+ "live",
29
+ "channels",
30
+ "playlist",
31
+ "topics",
32
+ "trending",
33
+ "dm",
34
+ "creator",
35
+ "premium",
36
+ "explore",
37
+ "following",
38
+ "subscriptions",
39
+ "notifications",
40
+ "history",
41
+ "watch",
42
+ "contact",
43
+ "ads",
44
+ "dmca",
45
+ "copyright",
46
+ "community"
47
+ ];
48
+ const dailymotionHandler = {
49
+ match: (url) => {
50
+ return require_utils.isHostOf(url, hosts);
51
+ },
52
+ resolve: (url) => {
53
+ const { pathname } = new URL(url);
54
+ const playlistMatch = pathname.match(playlistPathRegex);
55
+ if (playlistMatch?.[1]) return [`https://www.dailymotion.com/rss/playlist/${playlistMatch[1]}`];
56
+ const userMatch = pathname.match(userPathRegex);
57
+ if (userMatch?.[1]) {
58
+ const username = userMatch[1];
59
+ if (!require_utils.isAnyOf(username, excludedPaths)) return [`https://www.dailymotion.com/rss/${username}`];
60
+ }
61
+ return [];
62
+ }
63
+ };
64
+
65
+ //#endregion
66
+ exports.dailymotionHandler = dailymotionHandler;
@@ -0,0 +1,66 @@
1
+ import { isAnyOf, isHostOf } from "../../../common/utils.js";
2
+
3
+ //#region src/feeds/platform/handlers/dailymotion.ts
4
+ const hosts = ["dailymotion.com", "www.dailymotion.com"];
5
+ const userPathRegex = /^\/([a-zA-Z0-9_-]+)$/;
6
+ const playlistPathRegex = /^\/playlist\/([a-zA-Z0-9_-]+)/;
7
+ const excludedPaths = [
8
+ "signin",
9
+ "signout",
10
+ "signup",
11
+ "login",
12
+ "logout",
13
+ "register",
14
+ "search",
15
+ "legal",
16
+ "about",
17
+ "careers",
18
+ "terms",
19
+ "privacy",
20
+ "feedback",
21
+ "help",
22
+ "settings",
23
+ "upload",
24
+ "partner",
25
+ "monetize",
26
+ "studio",
27
+ "video",
28
+ "live",
29
+ "channels",
30
+ "playlist",
31
+ "topics",
32
+ "trending",
33
+ "dm",
34
+ "creator",
35
+ "premium",
36
+ "explore",
37
+ "following",
38
+ "subscriptions",
39
+ "notifications",
40
+ "history",
41
+ "watch",
42
+ "contact",
43
+ "ads",
44
+ "dmca",
45
+ "copyright",
46
+ "community"
47
+ ];
48
+ const dailymotionHandler = {
49
+ match: (url) => {
50
+ return isHostOf(url, hosts);
51
+ },
52
+ resolve: (url) => {
53
+ const { pathname } = new URL(url);
54
+ const playlistMatch = pathname.match(playlistPathRegex);
55
+ if (playlistMatch?.[1]) return [`https://www.dailymotion.com/rss/playlist/${playlistMatch[1]}`];
56
+ const userMatch = pathname.match(userPathRegex);
57
+ if (userMatch?.[1]) {
58
+ const username = userMatch[1];
59
+ if (!isAnyOf(username, excludedPaths)) return [`https://www.dailymotion.com/rss/${username}`];
60
+ }
61
+ return [];
62
+ }
63
+ };
64
+
65
+ //#endregion
66
+ export { dailymotionHandler };
@@ -0,0 +1,50 @@
1
+ const require_utils = require('../../../common/utils.cjs');
2
+
3
+ //#region src/feeds/platform/handlers/deviantart.ts
4
+ const hosts = ["deviantart.com", "www.deviantart.com"];
5
+ const feedBaseUrl = "https://backend.deviantart.com/rss.xml";
6
+ const excludedPaths = [
7
+ "about",
8
+ "join",
9
+ "search",
10
+ "topic",
11
+ "watch",
12
+ "notifications",
13
+ "settings",
14
+ "submit",
15
+ "shop",
16
+ "core-membership",
17
+ "team",
18
+ "developers"
19
+ ];
20
+ const deviantartHandler = {
21
+ match: (url) => {
22
+ return require_utils.isHostOf(url, hosts);
23
+ },
24
+ resolve: (url) => {
25
+ const { pathname } = new URL(url);
26
+ const tagMatch = pathname.match(/^\/tag\/([^/]+)/);
27
+ if (tagMatch?.[1]) {
28
+ const tag = tagMatch[1];
29
+ return [`${feedBaseUrl}?type=deviation&q=${encodeURIComponent(`tag:${tag}`)}`];
30
+ }
31
+ const favMatch = pathname.match(/^\/([a-zA-Z0-9_-]+)\/favourites\/?$/);
32
+ if (favMatch?.[1]) {
33
+ const username = favMatch[1];
34
+ if (!require_utils.isAnyOf(username, excludedPaths)) return [`${feedBaseUrl}?type=deviation&q=${encodeURIComponent(`favby:${username}`)}`];
35
+ }
36
+ const folderMatch = pathname.match(/^\/([a-zA-Z0-9_-]+)\/gallery\/(\d+)(?:\/|$)/);
37
+ if (folderMatch?.[1] && folderMatch?.[2]) {
38
+ const username = folderMatch[1];
39
+ const folderId = folderMatch[2];
40
+ if (!require_utils.isAnyOf(username, excludedPaths)) return [`${feedBaseUrl}?type=deviation&q=${encodeURIComponent(`gallery:${username}/${folderId}`)}`];
41
+ }
42
+ const username = pathname.match(/^\/([a-zA-Z0-9_-]+)(?:\/gallery(?:\/all)?)?(?:\/|$)/)?.[1];
43
+ if (!username || require_utils.isAnyOf(username, excludedPaths)) return [];
44
+ const query = `by:${username} sort:time meta:all`;
45
+ return [`${feedBaseUrl}?type=deviation&q=${encodeURIComponent(query)}`];
46
+ }
47
+ };
48
+
49
+ //#endregion
50
+ exports.deviantartHandler = deviantartHandler;
@@ -0,0 +1,50 @@
1
+ import { isAnyOf, isHostOf } from "../../../common/utils.js";
2
+
3
+ //#region src/feeds/platform/handlers/deviantart.ts
4
+ const hosts = ["deviantart.com", "www.deviantart.com"];
5
+ const feedBaseUrl = "https://backend.deviantart.com/rss.xml";
6
+ const excludedPaths = [
7
+ "about",
8
+ "join",
9
+ "search",
10
+ "topic",
11
+ "watch",
12
+ "notifications",
13
+ "settings",
14
+ "submit",
15
+ "shop",
16
+ "core-membership",
17
+ "team",
18
+ "developers"
19
+ ];
20
+ const deviantartHandler = {
21
+ match: (url) => {
22
+ return isHostOf(url, hosts);
23
+ },
24
+ resolve: (url) => {
25
+ const { pathname } = new URL(url);
26
+ const tagMatch = pathname.match(/^\/tag\/([^/]+)/);
27
+ if (tagMatch?.[1]) {
28
+ const tag = tagMatch[1];
29
+ return [`${feedBaseUrl}?type=deviation&q=${encodeURIComponent(`tag:${tag}`)}`];
30
+ }
31
+ const favMatch = pathname.match(/^\/([a-zA-Z0-9_-]+)\/favourites\/?$/);
32
+ if (favMatch?.[1]) {
33
+ const username = favMatch[1];
34
+ if (!isAnyOf(username, excludedPaths)) return [`${feedBaseUrl}?type=deviation&q=${encodeURIComponent(`favby:${username}`)}`];
35
+ }
36
+ const folderMatch = pathname.match(/^\/([a-zA-Z0-9_-]+)\/gallery\/(\d+)(?:\/|$)/);
37
+ if (folderMatch?.[1] && folderMatch?.[2]) {
38
+ const username = folderMatch[1];
39
+ const folderId = folderMatch[2];
40
+ if (!isAnyOf(username, excludedPaths)) return [`${feedBaseUrl}?type=deviation&q=${encodeURIComponent(`gallery:${username}/${folderId}`)}`];
41
+ }
42
+ const username = pathname.match(/^\/([a-zA-Z0-9_-]+)(?:\/gallery(?:\/all)?)?(?:\/|$)/)?.[1];
43
+ if (!username || isAnyOf(username, excludedPaths)) return [];
44
+ const query = `by:${username} sort:time meta:all`;
45
+ return [`${feedBaseUrl}?type=deviation&q=${encodeURIComponent(query)}`];
46
+ }
47
+ };
48
+
49
+ //#endregion
50
+ export { deviantartHandler };
@@ -0,0 +1,44 @@
1
+ const require_utils = require('../../../common/utils.cjs');
2
+
3
+ //#region src/feeds/platform/handlers/devto.ts
4
+ const hosts = ["dev.to", "www.dev.to"];
5
+ const userPathRegex = /^\/([a-zA-Z0-9_]+)\/?$/;
6
+ const tagPathRegex = /^\/t\/([^/]+)/;
7
+ const excludedPaths = [
8
+ "tag",
9
+ "tags",
10
+ "search",
11
+ "top",
12
+ "latest",
13
+ "about",
14
+ "contact",
15
+ "privacy",
16
+ "terms",
17
+ "code-of-conduct",
18
+ "faq",
19
+ "enter",
20
+ "settings",
21
+ "signout-confirm",
22
+ "notifications",
23
+ "reading-list",
24
+ "dashboard"
25
+ ];
26
+ const devtoHandler = {
27
+ match: (url) => {
28
+ return require_utils.isHostOf(url, hosts);
29
+ },
30
+ resolve: (url) => {
31
+ const { pathname } = new URL(url);
32
+ const userMatch = pathname.match(userPathRegex);
33
+ if (userMatch?.[1]) {
34
+ const username = userMatch[1];
35
+ if (!require_utils.isAnyOf(username, excludedPaths)) return [`https://dev.to/feed/${username}`];
36
+ }
37
+ const tagMatch = pathname.match(tagPathRegex);
38
+ if (tagMatch?.[1]) return [`https://dev.to/feed/tag/${tagMatch[1]}`];
39
+ return [];
40
+ }
41
+ };
42
+
43
+ //#endregion
44
+ exports.devtoHandler = devtoHandler;
@@ -0,0 +1,44 @@
1
+ import { isAnyOf, isHostOf } from "../../../common/utils.js";
2
+
3
+ //#region src/feeds/platform/handlers/devto.ts
4
+ const hosts = ["dev.to", "www.dev.to"];
5
+ const userPathRegex = /^\/([a-zA-Z0-9_]+)\/?$/;
6
+ const tagPathRegex = /^\/t\/([^/]+)/;
7
+ const excludedPaths = [
8
+ "tag",
9
+ "tags",
10
+ "search",
11
+ "top",
12
+ "latest",
13
+ "about",
14
+ "contact",
15
+ "privacy",
16
+ "terms",
17
+ "code-of-conduct",
18
+ "faq",
19
+ "enter",
20
+ "settings",
21
+ "signout-confirm",
22
+ "notifications",
23
+ "reading-list",
24
+ "dashboard"
25
+ ];
26
+ const devtoHandler = {
27
+ match: (url) => {
28
+ return isHostOf(url, hosts);
29
+ },
30
+ resolve: (url) => {
31
+ const { pathname } = new URL(url);
32
+ const userMatch = pathname.match(userPathRegex);
33
+ if (userMatch?.[1]) {
34
+ const username = userMatch[1];
35
+ if (!isAnyOf(username, excludedPaths)) return [`https://dev.to/feed/${username}`];
36
+ }
37
+ const tagMatch = pathname.match(tagPathRegex);
38
+ if (tagMatch?.[1]) return [`https://dev.to/feed/tag/${tagMatch[1]}`];
39
+ return [];
40
+ }
41
+ };
42
+
43
+ //#endregion
44
+ export { devtoHandler };