feedscout 1.4.0 → 1.5.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 (73) hide show
  1. package/dist/common/discover/index.cjs +45 -14
  2. package/dist/common/discover/index.js +46 -15
  3. package/dist/common/discover/utils.cjs +12 -1
  4. package/dist/common/discover/utils.js +11 -1
  5. package/dist/common/locales.cjs +75 -0
  6. package/dist/common/locales.js +70 -1
  7. package/dist/common/types.cjs +11 -0
  8. package/dist/common/types.d.cts +15 -2
  9. package/dist/common/types.d.ts +15 -2
  10. package/dist/common/types.js +10 -0
  11. package/dist/common/uris/guess/index.d.cts +2 -1
  12. package/dist/common/uris/guess/index.d.ts +2 -1
  13. package/dist/common/uris/guess/types.d.cts +3 -1
  14. package/dist/common/uris/guess/types.d.ts +3 -1
  15. package/dist/common/uris/guess/utils.cjs +4 -1
  16. package/dist/common/uris/guess/utils.d.cts +3 -1
  17. package/dist/common/uris/guess/utils.d.ts +3 -1
  18. package/dist/common/uris/guess/utils.js +4 -1
  19. package/dist/common/uris/index.cjs +13 -10
  20. package/dist/common/uris/index.js +13 -10
  21. package/dist/common/uris/platform/types.d.cts +3 -1
  22. package/dist/common/uris/platform/types.d.ts +3 -1
  23. package/dist/common/utils.cjs +6 -0
  24. package/dist/common/utils.js +7 -1
  25. package/dist/feeds/defaults.cjs +12 -13
  26. package/dist/feeds/defaults.d.cts +2 -2
  27. package/dist/feeds/defaults.d.ts +2 -2
  28. package/dist/feeds/defaults.js +12 -13
  29. package/dist/feeds/platform/handlers/behance.cjs +8 -2
  30. package/dist/feeds/platform/handlers/behance.js +9 -3
  31. package/dist/feeds/platform/handlers/blogspot.cjs +13 -3
  32. package/dist/feeds/platform/handlers/blogspot.js +14 -3
  33. package/dist/feeds/platform/handlers/bluesky.cjs +4 -1
  34. package/dist/feeds/platform/handlers/bluesky.js +5 -2
  35. package/dist/feeds/platform/handlers/dailymotion.cjs +8 -2
  36. package/dist/feeds/platform/handlers/dailymotion.js +9 -3
  37. package/dist/feeds/platform/handlers/deviantart.cjs +16 -4
  38. package/dist/feeds/platform/handlers/deviantart.js +17 -5
  39. package/dist/feeds/platform/handlers/devto.cjs +8 -2
  40. package/dist/feeds/platform/handlers/devto.js +9 -3
  41. package/dist/feeds/platform/handlers/github.cjs +32 -12
  42. package/dist/feeds/platform/handlers/github.js +33 -13
  43. package/dist/feeds/platform/handlers/githubGist.cjs +13 -13
  44. package/dist/feeds/platform/handlers/githubGist.js +14 -14
  45. package/dist/feeds/platform/handlers/gitlab.cjs +16 -4
  46. package/dist/feeds/platform/handlers/gitlab.js +17 -5
  47. package/dist/feeds/platform/handlers/kickstarter.cjs +8 -2
  48. package/dist/feeds/platform/handlers/kickstarter.js +9 -3
  49. package/dist/feeds/platform/handlers/lobsters.cjs +32 -8
  50. package/dist/feeds/platform/handlers/lobsters.js +33 -9
  51. package/dist/feeds/platform/handlers/medium.cjs +24 -6
  52. package/dist/feeds/platform/handlers/medium.js +25 -7
  53. package/dist/feeds/platform/handlers/pinterest.cjs +12 -3
  54. package/dist/feeds/platform/handlers/pinterest.js +13 -4
  55. package/dist/feeds/platform/handlers/producthunt.cjs +12 -3
  56. package/dist/feeds/platform/handlers/producthunt.js +13 -4
  57. package/dist/feeds/platform/handlers/reddit.cjs +32 -8
  58. package/dist/feeds/platform/handlers/reddit.js +33 -9
  59. package/dist/feeds/platform/handlers/soundcloud.cjs +4 -1
  60. package/dist/feeds/platform/handlers/soundcloud.js +5 -2
  61. package/dist/feeds/platform/handlers/substack.cjs +4 -1
  62. package/dist/feeds/platform/handlers/substack.js +5 -2
  63. package/dist/feeds/platform/handlers/tumblr.cjs +8 -2
  64. package/dist/feeds/platform/handlers/tumblr.js +9 -3
  65. package/dist/feeds/platform/handlers/wordpress.cjs +44 -8
  66. package/dist/feeds/platform/handlers/wordpress.js +45 -9
  67. package/dist/feeds/platform/handlers/wpengine.cjs +13 -0
  68. package/dist/feeds/platform/handlers/wpengine.js +13 -0
  69. package/dist/feeds/platform/handlers/youtube.cjs +20 -9
  70. package/dist/feeds/platform/handlers/youtube.js +21 -10
  71. package/dist/index.d.cts +2 -2
  72. package/dist/index.d.ts +2 -2
  73. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { isAnyOf, isHostOf } from "../../../common/utils.js";
1
+ import { composeHint, isAnyOf, isHostOf } from "../../../common/utils.js";
2
2
 
3
3
  //#region src/feeds/platform/handlers/github.ts
4
4
  const hosts = ["github.com", "www.github.com"];
@@ -56,30 +56,50 @@ const githubHandler = {
56
56
  const { pathname } = new URL(url);
57
57
  const uris = [];
58
58
  const userMatch = pathname.match(/^\/([^/]+)\/?$/);
59
- if (userMatch?.[1] && !isAnyOf(userMatch[1], excludedPaths)) {
60
- const user = userMatch[1];
61
- uris.push(`https://github.com/${user}.atom`);
62
- return uris;
63
- }
59
+ if (userMatch?.[1] && !isAnyOf(userMatch[1], excludedPaths)) return [{
60
+ uri: `https://github.com/${userMatch[1]}.atom`,
61
+ hint: composeHint("github:activity")
62
+ }];
64
63
  const repoMatch = pathname.match(/^\/([^/]+)\/([^/]+)/);
65
64
  const owner = repoMatch?.[1];
66
65
  const repo = repoMatch?.[2];
67
66
  if (!owner || !repo || isAnyOf(owner, excludedPaths)) return [];
68
- uris.push(`https://github.com/${owner}/${repo}/releases.atom`);
69
- uris.push(`https://github.com/${owner}/${repo}/commits.atom`);
70
- uris.push(`https://github.com/${owner}/${repo}/tags.atom`);
71
- if (/\/wiki(\/|$)/.test(pathname)) uris.push(`https://github.com/${owner}/${repo}/wiki.atom`);
72
- if (/\/discussions(\/|$)/.test(pathname)) uris.push(`https://github.com/${owner}/${repo}/discussions.atom`);
67
+ uris.push({
68
+ uri: `https://github.com/${owner}/${repo}/releases.atom`,
69
+ hint: composeHint("github:releases")
70
+ });
71
+ uris.push({
72
+ uri: `https://github.com/${owner}/${repo}/commits.atom`,
73
+ hint: composeHint("github:commits")
74
+ });
75
+ uris.push({
76
+ uri: `https://github.com/${owner}/${repo}/tags.atom`,
77
+ hint: composeHint("github:tags")
78
+ });
79
+ if (/\/wiki(\/|$)/.test(pathname)) uris.push({
80
+ uri: `https://github.com/${owner}/${repo}/wiki.atom`,
81
+ hint: composeHint("github:wiki")
82
+ });
83
+ if (/\/discussions(\/|$)/.test(pathname)) uris.push({
84
+ uri: `https://github.com/${owner}/${repo}/discussions.atom`,
85
+ hint: composeHint("github:discussions")
86
+ });
73
87
  const branchMatch = pathname.match(/^\/[^/]+\/[^/]+\/tree\/([^/]+)\/?$/);
74
88
  if (branchMatch?.[1]) {
75
89
  const branch = branchMatch[1];
76
- uris.push(`https://github.com/${owner}/${repo}/commits/${branch}.atom`);
90
+ uris.push({
91
+ uri: `https://github.com/${owner}/${repo}/commits/${branch}.atom`,
92
+ hint: composeHint("github:branch-commits")
93
+ });
77
94
  }
78
95
  const fileMatch = pathname.match(/^\/[^/]+\/[^/]+\/(?:blob|commits)\/([^/]+)\/(.+)/);
79
96
  if (fileMatch?.[1] && fileMatch?.[2]) {
80
97
  const branch = fileMatch[1];
81
98
  const filePath = fileMatch[2];
82
- uris.push(`https://github.com/${owner}/${repo}/commits/${branch}/${filePath}.atom`);
99
+ uris.push({
100
+ uri: `https://github.com/${owner}/${repo}/commits/${branch}/${filePath}.atom`,
101
+ hint: composeHint("github:file-history")
102
+ });
83
103
  }
84
104
  return uris;
85
105
  }
@@ -15,25 +15,25 @@ const githubGistHandler = {
15
15
  },
16
16
  resolve: (url) => {
17
17
  const { pathname } = new URL(url);
18
- const uris = [];
19
18
  const gistMatch = pathname.match(/^\/([^/]+)\/([a-f0-9]+)/);
20
19
  if (gistMatch?.[1] && gistMatch?.[2]) {
21
20
  const username = gistMatch[1];
22
- if (!require_utils.isAnyOf(username, excludedPaths)) uris.push(`https://gist.github.com/${username}.atom`);
23
- return uris;
21
+ if (!require_utils.isAnyOf(username, excludedPaths)) return [{
22
+ uri: `https://gist.github.com/${username}.atom`,
23
+ hint: require_utils.composeHint("github-gist:gists")
24
+ }];
25
+ return [];
24
26
  }
25
27
  const starredMatch = pathname.match(/^\/([^/]+)\/starred\/?$/);
26
- if (starredMatch?.[1] && !require_utils.isAnyOf(starredMatch[1], excludedPaths)) {
27
- const username = starredMatch[1];
28
- uris.push(`https://gist.github.com/${username}/starred.atom`);
29
- return uris;
30
- }
28
+ if (starredMatch?.[1] && !require_utils.isAnyOf(starredMatch[1], excludedPaths)) return [{
29
+ uri: `https://gist.github.com/${starredMatch[1]}/starred.atom`,
30
+ hint: require_utils.composeHint("github-gist:starred")
31
+ }];
31
32
  const userMatch = pathname.match(/^\/([^/]+)\/?$/);
32
- if (userMatch?.[1] && !require_utils.isAnyOf(userMatch[1], excludedPaths)) {
33
- const username = userMatch[1];
34
- uris.push(`https://gist.github.com/${username}.atom`);
35
- return uris;
36
- }
33
+ if (userMatch?.[1] && !require_utils.isAnyOf(userMatch[1], excludedPaths)) return [{
34
+ uri: `https://gist.github.com/${userMatch[1]}.atom`,
35
+ hint: require_utils.composeHint("github-gist:gists")
36
+ }];
37
37
  return [];
38
38
  }
39
39
  };
@@ -1,4 +1,4 @@
1
- import { isAnyOf, isHostOf } from "../../../common/utils.js";
1
+ import { composeHint, isAnyOf, isHostOf } from "../../../common/utils.js";
2
2
 
3
3
  //#region src/feeds/platform/handlers/githubGist.ts
4
4
  const hosts = ["gist.github.com"];
@@ -15,25 +15,25 @@ const githubGistHandler = {
15
15
  },
16
16
  resolve: (url) => {
17
17
  const { pathname } = new URL(url);
18
- const uris = [];
19
18
  const gistMatch = pathname.match(/^\/([^/]+)\/([a-f0-9]+)/);
20
19
  if (gistMatch?.[1] && gistMatch?.[2]) {
21
20
  const username = gistMatch[1];
22
- if (!isAnyOf(username, excludedPaths)) uris.push(`https://gist.github.com/${username}.atom`);
23
- return uris;
21
+ if (!isAnyOf(username, excludedPaths)) return [{
22
+ uri: `https://gist.github.com/${username}.atom`,
23
+ hint: composeHint("github-gist:gists")
24
+ }];
25
+ return [];
24
26
  }
25
27
  const starredMatch = pathname.match(/^\/([^/]+)\/starred\/?$/);
26
- if (starredMatch?.[1] && !isAnyOf(starredMatch[1], excludedPaths)) {
27
- const username = starredMatch[1];
28
- uris.push(`https://gist.github.com/${username}/starred.atom`);
29
- return uris;
30
- }
28
+ if (starredMatch?.[1] && !isAnyOf(starredMatch[1], excludedPaths)) return [{
29
+ uri: `https://gist.github.com/${starredMatch[1]}/starred.atom`,
30
+ hint: composeHint("github-gist:starred")
31
+ }];
31
32
  const userMatch = pathname.match(/^\/([^/]+)\/?$/);
32
- if (userMatch?.[1] && !isAnyOf(userMatch[1], excludedPaths)) {
33
- const username = userMatch[1];
34
- uris.push(`https://gist.github.com/${username}.atom`);
35
- return uris;
36
- }
33
+ if (userMatch?.[1] && !isAnyOf(userMatch[1], excludedPaths)) return [{
34
+ uri: `https://gist.github.com/${userMatch[1]}.atom`,
35
+ hint: composeHint("github-gist:gists")
36
+ }];
37
37
  return [];
38
38
  }
39
39
  };
@@ -34,15 +34,27 @@ const gitlabHandler = {
34
34
  const pathSegments = pathname.split("/").filter(Boolean);
35
35
  if (pathSegments.length === 1) {
36
36
  const user = pathSegments[0];
37
- if (!require_utils.isAnyOf(user, excludedPaths)) return [`${origin}/${user}.atom`];
37
+ if (!require_utils.isAnyOf(user, excludedPaths)) return [{
38
+ uri: `${origin}/${user}.atom`,
39
+ hint: require_utils.composeHint("gitlab:activity")
40
+ }];
38
41
  }
39
42
  if (pathSegments.length >= 2) {
40
43
  const user = pathSegments[0];
41
44
  const repo = pathSegments[1];
42
45
  if (!require_utils.isAnyOf(user, excludedPaths)) return [
43
- `${origin}/${user}/${repo}/-/releases.atom`,
44
- `${origin}/${user}/${repo}/-/tags?format=atom`,
45
- `${origin}/${user}/${repo}.atom`
46
+ {
47
+ uri: `${origin}/${user}/${repo}/-/releases.atom`,
48
+ hint: require_utils.composeHint("gitlab:releases")
49
+ },
50
+ {
51
+ uri: `${origin}/${user}/${repo}/-/tags?format=atom`,
52
+ hint: require_utils.composeHint("gitlab:tags")
53
+ },
54
+ {
55
+ uri: `${origin}/${user}/${repo}.atom`,
56
+ hint: require_utils.composeHint("gitlab:activity")
57
+ }
46
58
  ];
47
59
  }
48
60
  return [];
@@ -1,4 +1,4 @@
1
- import { isAnyOf, isHostOf } from "../../../common/utils.js";
1
+ import { composeHint, isAnyOf, isHostOf } from "../../../common/utils.js";
2
2
 
3
3
  //#region src/feeds/platform/handlers/gitlab.ts
4
4
  const hosts = ["gitlab.com", "www.gitlab.com"];
@@ -34,15 +34,27 @@ const gitlabHandler = {
34
34
  const pathSegments = pathname.split("/").filter(Boolean);
35
35
  if (pathSegments.length === 1) {
36
36
  const user = pathSegments[0];
37
- if (!isAnyOf(user, excludedPaths)) return [`${origin}/${user}.atom`];
37
+ if (!isAnyOf(user, excludedPaths)) return [{
38
+ uri: `${origin}/${user}.atom`,
39
+ hint: composeHint("gitlab:activity")
40
+ }];
38
41
  }
39
42
  if (pathSegments.length >= 2) {
40
43
  const user = pathSegments[0];
41
44
  const repo = pathSegments[1];
42
45
  if (!isAnyOf(user, excludedPaths)) return [
43
- `${origin}/${user}/${repo}/-/releases.atom`,
44
- `${origin}/${user}/${repo}/-/tags?format=atom`,
45
- `${origin}/${user}/${repo}.atom`
46
+ {
47
+ uri: `${origin}/${user}/${repo}/-/releases.atom`,
48
+ hint: composeHint("gitlab:releases")
49
+ },
50
+ {
51
+ uri: `${origin}/${user}/${repo}/-/tags?format=atom`,
52
+ hint: composeHint("gitlab:tags")
53
+ },
54
+ {
55
+ uri: `${origin}/${user}/${repo}.atom`,
56
+ hint: composeHint("gitlab:activity")
57
+ }
46
58
  ];
47
59
  }
48
60
  return [];
@@ -9,8 +9,14 @@ const kickstarterHandler = {
9
9
  resolve: (url) => {
10
10
  const { pathname } = new URL(url);
11
11
  const pathSegments = pathname.split("/").filter(Boolean);
12
- if (pathSegments.length >= 3 && pathSegments[0] === "projects") return [`https://www.kickstarter.com/projects/${pathSegments[1]}/${pathSegments[2]}/posts.atom`];
13
- return ["https://www.kickstarter.com/projects/feed.atom"];
12
+ if (pathSegments.length >= 3 && pathSegments[0] === "projects") return [{
13
+ uri: `https://www.kickstarter.com/projects/${pathSegments[1]}/${pathSegments[2]}/posts.atom`,
14
+ hint: require_utils.composeHint("kickstarter:updates")
15
+ }];
16
+ return [{
17
+ uri: "https://www.kickstarter.com/projects/feed.atom",
18
+ hint: require_utils.composeHint("kickstarter:projects")
19
+ }];
14
20
  }
15
21
  };
16
22
 
@@ -1,4 +1,4 @@
1
- import { isHostOf } from "../../../common/utils.js";
1
+ import { composeHint, isHostOf } from "../../../common/utils.js";
2
2
 
3
3
  //#region src/feeds/platform/handlers/kickstarter.ts
4
4
  const hosts = ["kickstarter.com", "www.kickstarter.com"];
@@ -9,8 +9,14 @@ const kickstarterHandler = {
9
9
  resolve: (url) => {
10
10
  const { pathname } = new URL(url);
11
11
  const pathSegments = pathname.split("/").filter(Boolean);
12
- if (pathSegments.length >= 3 && pathSegments[0] === "projects") return [`https://www.kickstarter.com/projects/${pathSegments[1]}/${pathSegments[2]}/posts.atom`];
13
- return ["https://www.kickstarter.com/projects/feed.atom"];
12
+ if (pathSegments.length >= 3 && pathSegments[0] === "projects") return [{
13
+ uri: `https://www.kickstarter.com/projects/${pathSegments[1]}/${pathSegments[2]}/posts.atom`,
14
+ hint: composeHint("kickstarter:updates")
15
+ }];
16
+ return [{
17
+ uri: "https://www.kickstarter.com/projects/feed.atom",
18
+ hint: composeHint("kickstarter:projects")
19
+ }];
14
20
  }
15
21
  };
16
22
 
@@ -13,20 +13,44 @@ const lobstersHandler = {
13
13
  resolve: (url) => {
14
14
  const { pathname } = new URL(url);
15
15
  const tagMatch = pathname.match(tagPathRegex);
16
- if (tagMatch?.[1]) return [`https://lobste.rs/t/${tagMatch[1]}.rss`];
16
+ if (tagMatch?.[1]) return [{
17
+ uri: `https://lobste.rs/t/${tagMatch[1]}.rss`,
18
+ hint: require_utils.composeHint("lobsters:tag")
19
+ }];
17
20
  const domainMatch = pathname.match(domainPathRegex);
18
- if (domainMatch?.[1]) return [`https://lobste.rs/domains/${domainMatch[1]}.rss`];
21
+ if (domainMatch?.[1]) return [{
22
+ uri: `https://lobste.rs/domains/${domainMatch[1]}.rss`,
23
+ hint: require_utils.composeHint("lobsters:domain")
24
+ }];
19
25
  const userMatch = pathname.match(userPathRegex);
20
- if (userMatch?.[1]) return [`https://lobste.rs/~${userMatch[1]}/stories.rss`];
26
+ if (userMatch?.[1]) return [{
27
+ uri: `https://lobste.rs/~${userMatch[1]}/stories.rss`,
28
+ hint: require_utils.composeHint("lobsters:stories")
29
+ }];
21
30
  const topMatch = pathname.match(topPathRegex);
22
31
  if (topMatch) {
23
32
  const period = topMatch[1];
24
- if (period) return [`https://lobste.rs/top/${period}/rss`];
25
- return ["https://lobste.rs/top/rss"];
33
+ if (period) return [{
34
+ uri: `https://lobste.rs/top/${period}/rss`,
35
+ hint: require_utils.composeHint("lobsters:top")
36
+ }];
37
+ return [{
38
+ uri: "https://lobste.rs/top/rss",
39
+ hint: require_utils.composeHint("lobsters:top")
40
+ }];
26
41
  }
27
- if (pathname === "/newest" || pathname === "/newest/") return ["https://lobste.rs/newest.rss"];
28
- if (pathname === "/comments" || pathname === "/comments/") return ["https://lobste.rs/comments.rss"];
29
- return ["https://lobste.rs/rss"];
42
+ if (pathname === "/newest" || pathname === "/newest/") return [{
43
+ uri: "https://lobste.rs/newest.rss",
44
+ hint: require_utils.composeHint("lobsters:newest")
45
+ }];
46
+ if (pathname === "/comments" || pathname === "/comments/") return [{
47
+ uri: "https://lobste.rs/comments.rss",
48
+ hint: require_utils.composeHint("lobsters:comments")
49
+ }];
50
+ return [{
51
+ uri: "https://lobste.rs/rss",
52
+ hint: require_utils.composeHint("lobsters:stories")
53
+ }];
30
54
  }
31
55
  };
32
56
 
@@ -1,4 +1,4 @@
1
- import { isHostOf } from "../../../common/utils.js";
1
+ import { composeHint, isHostOf } from "../../../common/utils.js";
2
2
 
3
3
  //#region src/feeds/platform/handlers/lobsters.ts
4
4
  const hosts = ["lobste.rs"];
@@ -13,20 +13,44 @@ const lobstersHandler = {
13
13
  resolve: (url) => {
14
14
  const { pathname } = new URL(url);
15
15
  const tagMatch = pathname.match(tagPathRegex);
16
- if (tagMatch?.[1]) return [`https://lobste.rs/t/${tagMatch[1]}.rss`];
16
+ if (tagMatch?.[1]) return [{
17
+ uri: `https://lobste.rs/t/${tagMatch[1]}.rss`,
18
+ hint: composeHint("lobsters:tag")
19
+ }];
17
20
  const domainMatch = pathname.match(domainPathRegex);
18
- if (domainMatch?.[1]) return [`https://lobste.rs/domains/${domainMatch[1]}.rss`];
21
+ if (domainMatch?.[1]) return [{
22
+ uri: `https://lobste.rs/domains/${domainMatch[1]}.rss`,
23
+ hint: composeHint("lobsters:domain")
24
+ }];
19
25
  const userMatch = pathname.match(userPathRegex);
20
- if (userMatch?.[1]) return [`https://lobste.rs/~${userMatch[1]}/stories.rss`];
26
+ if (userMatch?.[1]) return [{
27
+ uri: `https://lobste.rs/~${userMatch[1]}/stories.rss`,
28
+ hint: composeHint("lobsters:stories")
29
+ }];
21
30
  const topMatch = pathname.match(topPathRegex);
22
31
  if (topMatch) {
23
32
  const period = topMatch[1];
24
- if (period) return [`https://lobste.rs/top/${period}/rss`];
25
- return ["https://lobste.rs/top/rss"];
33
+ if (period) return [{
34
+ uri: `https://lobste.rs/top/${period}/rss`,
35
+ hint: composeHint("lobsters:top")
36
+ }];
37
+ return [{
38
+ uri: "https://lobste.rs/top/rss",
39
+ hint: composeHint("lobsters:top")
40
+ }];
26
41
  }
27
- if (pathname === "/newest" || pathname === "/newest/") return ["https://lobste.rs/newest.rss"];
28
- if (pathname === "/comments" || pathname === "/comments/") return ["https://lobste.rs/comments.rss"];
29
- return ["https://lobste.rs/rss"];
42
+ if (pathname === "/newest" || pathname === "/newest/") return [{
43
+ uri: "https://lobste.rs/newest.rss",
44
+ hint: composeHint("lobsters:newest")
45
+ }];
46
+ if (pathname === "/comments" || pathname === "/comments/") return [{
47
+ uri: "https://lobste.rs/comments.rss",
48
+ hint: composeHint("lobsters:comments")
49
+ }];
50
+ return [{
51
+ uri: "https://lobste.rs/rss",
52
+ hint: composeHint("lobsters:stories")
53
+ }];
30
54
  }
31
55
  };
32
56
 
@@ -18,26 +18,44 @@ const mediumHandler = {
18
18
  const lowerHostname = hostname.toLowerCase();
19
19
  if (hosts.includes(lowerHostname)) {
20
20
  const userMatch = pathname.match(/^\/@([^/]+)/);
21
- if (userMatch?.[1]) return [`https://medium.com/feed/@${userMatch[1]}`];
21
+ if (userMatch?.[1]) return [{
22
+ uri: `https://medium.com/feed/@${userMatch[1]}`,
23
+ hint: require_utils.composeHint("medium:posts")
24
+ }];
22
25
  const tagMatch = pathname.match(/^\/tag\/([^/]+)/);
23
- if (tagMatch?.[1]) return [`https://medium.com/feed/tag/${tagMatch[1]}`];
26
+ if (tagMatch?.[1]) return [{
27
+ uri: `https://medium.com/feed/tag/${tagMatch[1]}`,
28
+ hint: require_utils.composeHint("medium:tag")
29
+ }];
24
30
  const pubTagMatch = pathname.match(/^\/([^/@][^/]+)\/tagged\/([^/]+)/);
25
31
  if (pubTagMatch?.[1] && pubTagMatch?.[2]) {
26
32
  const publication = pubTagMatch[1];
27
33
  const tag = pubTagMatch[2];
28
- if (!require_utils.isAnyOf(publication, excludedPaths)) return [`https://medium.com/feed/${publication}/tagged/${tag}`];
34
+ if (!require_utils.isAnyOf(publication, excludedPaths)) return [{
35
+ uri: `https://medium.com/feed/${publication}/tagged/${tag}`,
36
+ hint: require_utils.composeHint("medium:tagged")
37
+ }];
29
38
  }
30
39
  const pubMatch = pathname.match(/^\/([^/@][^/]+)/);
31
40
  if (pubMatch?.[1]) {
32
41
  const publication = pubMatch[1];
33
- if (!require_utils.isAnyOf(publication, excludedPaths)) return [`https://medium.com/feed/${publication}`];
42
+ if (!require_utils.isAnyOf(publication, excludedPaths)) return [{
43
+ uri: `https://medium.com/feed/${publication}`,
44
+ hint: require_utils.composeHint("medium:publication")
45
+ }];
34
46
  }
35
47
  }
36
48
  if (lowerHostname.endsWith(".medium.com") && lowerHostname !== "medium.com" && lowerHostname !== "www.medium.com") {
37
49
  const subdomain = lowerHostname.replace(".medium.com", "");
38
50
  const tagMatch = pathname.match(/^\/tagged\/([^/]+)/);
39
- if (tagMatch?.[1]) return [`https://medium.com/feed/${subdomain}/tagged/${tagMatch[1]}`];
40
- return [`https://medium.com/feed/${subdomain}`];
51
+ if (tagMatch?.[1]) return [{
52
+ uri: `https://medium.com/feed/${subdomain}/tagged/${tagMatch[1]}`,
53
+ hint: require_utils.composeHint("medium:tagged")
54
+ }];
55
+ return [{
56
+ uri: `https://medium.com/feed/${subdomain}`,
57
+ hint: require_utils.composeHint("medium:publication")
58
+ }];
41
59
  }
42
60
  return [];
43
61
  }
@@ -1,4 +1,4 @@
1
- import { isAnyOf, isHostOf, isSubdomainOf } from "../../../common/utils.js";
1
+ import { composeHint, isAnyOf, isHostOf, isSubdomainOf } from "../../../common/utils.js";
2
2
 
3
3
  //#region src/feeds/platform/handlers/medium.ts
4
4
  const hosts = ["medium.com", "www.medium.com"];
@@ -18,26 +18,44 @@ const mediumHandler = {
18
18
  const lowerHostname = hostname.toLowerCase();
19
19
  if (hosts.includes(lowerHostname)) {
20
20
  const userMatch = pathname.match(/^\/@([^/]+)/);
21
- if (userMatch?.[1]) return [`https://medium.com/feed/@${userMatch[1]}`];
21
+ if (userMatch?.[1]) return [{
22
+ uri: `https://medium.com/feed/@${userMatch[1]}`,
23
+ hint: composeHint("medium:posts")
24
+ }];
22
25
  const tagMatch = pathname.match(/^\/tag\/([^/]+)/);
23
- if (tagMatch?.[1]) return [`https://medium.com/feed/tag/${tagMatch[1]}`];
26
+ if (tagMatch?.[1]) return [{
27
+ uri: `https://medium.com/feed/tag/${tagMatch[1]}`,
28
+ hint: composeHint("medium:tag")
29
+ }];
24
30
  const pubTagMatch = pathname.match(/^\/([^/@][^/]+)\/tagged\/([^/]+)/);
25
31
  if (pubTagMatch?.[1] && pubTagMatch?.[2]) {
26
32
  const publication = pubTagMatch[1];
27
33
  const tag = pubTagMatch[2];
28
- if (!isAnyOf(publication, excludedPaths)) return [`https://medium.com/feed/${publication}/tagged/${tag}`];
34
+ if (!isAnyOf(publication, excludedPaths)) return [{
35
+ uri: `https://medium.com/feed/${publication}/tagged/${tag}`,
36
+ hint: composeHint("medium:tagged")
37
+ }];
29
38
  }
30
39
  const pubMatch = pathname.match(/^\/([^/@][^/]+)/);
31
40
  if (pubMatch?.[1]) {
32
41
  const publication = pubMatch[1];
33
- if (!isAnyOf(publication, excludedPaths)) return [`https://medium.com/feed/${publication}`];
42
+ if (!isAnyOf(publication, excludedPaths)) return [{
43
+ uri: `https://medium.com/feed/${publication}`,
44
+ hint: composeHint("medium:publication")
45
+ }];
34
46
  }
35
47
  }
36
48
  if (lowerHostname.endsWith(".medium.com") && lowerHostname !== "medium.com" && lowerHostname !== "www.medium.com") {
37
49
  const subdomain = lowerHostname.replace(".medium.com", "");
38
50
  const tagMatch = pathname.match(/^\/tagged\/([^/]+)/);
39
- if (tagMatch?.[1]) return [`https://medium.com/feed/${subdomain}/tagged/${tagMatch[1]}`];
40
- return [`https://medium.com/feed/${subdomain}`];
51
+ if (tagMatch?.[1]) return [{
52
+ uri: `https://medium.com/feed/${subdomain}/tagged/${tagMatch[1]}`,
53
+ hint: composeHint("medium:tagged")
54
+ }];
55
+ return [{
56
+ uri: `https://medium.com/feed/${subdomain}`,
57
+ hint: composeHint("medium:publication")
58
+ }];
41
59
  }
42
60
  return [];
43
61
  }
@@ -37,10 +37,19 @@ const pinterestHandler = {
37
37
  if (require_utils.isAnyOf(username, excludedPaths)) return [];
38
38
  if (pathSegments.length >= 2) {
39
39
  const boardname = pathSegments[1];
40
- if (boardname.startsWith("_") || boardname === "pins" || boardname === "boards") return [`https://www.pinterest.com/${username}/feed.rss`];
41
- return [`https://www.pinterest.com/${username}/${boardname}.rss`];
40
+ if (boardname.startsWith("_") || boardname === "pins" || boardname === "boards") return [{
41
+ uri: `https://www.pinterest.com/${username}/feed.rss`,
42
+ hint: require_utils.composeHint("pinterest:pins")
43
+ }];
44
+ return [{
45
+ uri: `https://www.pinterest.com/${username}/${boardname}.rss`,
46
+ hint: require_utils.composeHint("pinterest:board")
47
+ }];
42
48
  }
43
- return [`https://www.pinterest.com/${username}/feed.rss`];
49
+ return [{
50
+ uri: `https://www.pinterest.com/${username}/feed.rss`,
51
+ hint: require_utils.composeHint("pinterest:pins")
52
+ }];
44
53
  }
45
54
  };
46
55
 
@@ -1,4 +1,4 @@
1
- import { isAnyOf, isHostOf } from "../../../common/utils.js";
1
+ import { composeHint, isAnyOf, isHostOf } from "../../../common/utils.js";
2
2
 
3
3
  //#region src/feeds/platform/handlers/pinterest.ts
4
4
  const hosts = [
@@ -37,10 +37,19 @@ const pinterestHandler = {
37
37
  if (isAnyOf(username, excludedPaths)) return [];
38
38
  if (pathSegments.length >= 2) {
39
39
  const boardname = pathSegments[1];
40
- if (boardname.startsWith("_") || boardname === "pins" || boardname === "boards") return [`https://www.pinterest.com/${username}/feed.rss`];
41
- return [`https://www.pinterest.com/${username}/${boardname}.rss`];
40
+ if (boardname.startsWith("_") || boardname === "pins" || boardname === "boards") return [{
41
+ uri: `https://www.pinterest.com/${username}/feed.rss`,
42
+ hint: composeHint("pinterest:pins")
43
+ }];
44
+ return [{
45
+ uri: `https://www.pinterest.com/${username}/${boardname}.rss`,
46
+ hint: composeHint("pinterest:board")
47
+ }];
42
48
  }
43
- return [`https://www.pinterest.com/${username}/feed.rss`];
49
+ return [{
50
+ uri: `https://www.pinterest.com/${username}/feed.rss`,
51
+ hint: composeHint("pinterest:pins")
52
+ }];
44
53
  }
45
54
  };
46
55
 
@@ -11,10 +11,19 @@ const producthuntHandler = {
11
11
  resolve: (url) => {
12
12
  const { pathname } = new URL(url);
13
13
  const topicMatch = pathname.match(topicPathRegex);
14
- if (topicMatch?.[1]) return [`https://www.producthunt.com/feed?topic=${topicMatch[1]}`];
14
+ if (topicMatch?.[1]) return [{
15
+ uri: `https://www.producthunt.com/feed?topic=${topicMatch[1]}`,
16
+ hint: require_utils.composeHint("producthunt:topic")
17
+ }];
15
18
  const categoryMatch = pathname.match(categoryPathRegex);
16
- if (categoryMatch?.[1]) return [`https://www.producthunt.com/feed?category=${categoryMatch[1]}`];
17
- return ["https://www.producthunt.com/feed"];
19
+ if (categoryMatch?.[1]) return [{
20
+ uri: `https://www.producthunt.com/feed?category=${categoryMatch[1]}`,
21
+ hint: require_utils.composeHint("producthunt:category")
22
+ }];
23
+ return [{
24
+ uri: "https://www.producthunt.com/feed",
25
+ hint: require_utils.composeHint("producthunt:products")
26
+ }];
18
27
  }
19
28
  };
20
29
 
@@ -1,4 +1,4 @@
1
- import { isHostOf } from "../../../common/utils.js";
1
+ import { composeHint, isHostOf } from "../../../common/utils.js";
2
2
 
3
3
  //#region src/feeds/platform/handlers/producthunt.ts
4
4
  const hosts = ["producthunt.com", "www.producthunt.com"];
@@ -11,10 +11,19 @@ const producthuntHandler = {
11
11
  resolve: (url) => {
12
12
  const { pathname } = new URL(url);
13
13
  const topicMatch = pathname.match(topicPathRegex);
14
- if (topicMatch?.[1]) return [`https://www.producthunt.com/feed?topic=${topicMatch[1]}`];
14
+ if (topicMatch?.[1]) return [{
15
+ uri: `https://www.producthunt.com/feed?topic=${topicMatch[1]}`,
16
+ hint: composeHint("producthunt:topic")
17
+ }];
15
18
  const categoryMatch = pathname.match(categoryPathRegex);
16
- if (categoryMatch?.[1]) return [`https://www.producthunt.com/feed?category=${categoryMatch[1]}`];
17
- return ["https://www.producthunt.com/feed"];
19
+ if (categoryMatch?.[1]) return [{
20
+ uri: `https://www.producthunt.com/feed?category=${categoryMatch[1]}`,
21
+ hint: composeHint("producthunt:category")
22
+ }];
23
+ return [{
24
+ uri: "https://www.producthunt.com/feed",
25
+ hint: composeHint("producthunt:products")
26
+ }];
18
27
  }
19
28
  };
20
29