feedscout 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -17
- package/dist/blogrolls/defaults.cjs +1 -3
- package/dist/blogrolls/defaults.js +1 -2
- package/dist/blogrolls/extractors.cjs +6 -9
- package/dist/blogrolls/extractors.js +6 -9
- package/dist/blogrolls/index.cjs +6 -9
- package/dist/blogrolls/index.d.cts +1 -1
- package/dist/blogrolls/index.d.ts +1 -1
- package/dist/blogrolls/index.js +1 -4
- package/dist/blogrolls.cjs +4 -5
- package/dist/blogrolls.js +1 -2
- package/dist/common/discover/index.cjs +24 -16
- package/dist/common/discover/index.js +20 -12
- package/dist/common/discover/utils.cjs +19 -9
- package/dist/common/discover/utils.js +18 -8
- package/dist/common/locales.cjs +59 -15
- package/dist/common/locales.js +49 -4
- package/dist/common/types.cjs +2 -3
- package/dist/common/types.d.cts +11 -6
- package/dist/common/types.d.ts +11 -6
- package/dist/common/types.js +2 -2
- package/dist/common/uris/feed/index.cjs +12 -0
- package/dist/common/uris/feed/index.d.cts +6 -0
- package/dist/common/uris/feed/index.d.ts +6 -0
- package/dist/common/uris/feed/index.js +12 -0
- package/dist/common/uris/feed/types.d.cts +9 -0
- package/dist/common/uris/feed/types.d.ts +9 -0
- package/dist/common/uris/guess/index.cjs +2 -4
- package/dist/common/uris/guess/index.js +1 -3
- package/dist/common/uris/guess/utils.cjs +1 -3
- package/dist/common/uris/guess/utils.js +1 -2
- package/dist/common/uris/headers/index.cjs +2 -4
- package/dist/common/uris/headers/index.js +1 -3
- package/dist/common/uris/html/handlers.cjs +2 -4
- package/dist/common/uris/html/handlers.js +1 -3
- package/dist/common/uris/html/index.cjs +2 -4
- package/dist/common/uris/html/index.js +1 -3
- package/dist/common/uris/index.cjs +15 -12
- package/dist/common/uris/index.js +8 -5
- package/dist/common/uris/platform/index.cjs +3 -5
- package/dist/common/uris/platform/index.d.cts +7 -0
- package/dist/common/uris/platform/index.d.ts +7 -0
- package/dist/common/uris/platform/index.js +3 -4
- package/dist/common/uris/platform/types.d.cts +3 -3
- package/dist/common/uris/platform/types.d.ts +3 -3
- package/dist/common/utils.cjs +20 -9
- package/dist/common/utils.d.cts +2 -2
- package/dist/common/utils.d.ts +2 -2
- package/dist/common/utils.js +18 -8
- package/dist/favicons/defaults.cjs +60 -0
- package/dist/favicons/defaults.d.cts +18 -0
- package/dist/favicons/defaults.d.ts +18 -0
- package/dist/favicons/defaults.js +53 -0
- package/dist/favicons/extractors.cjs +13 -0
- package/dist/favicons/extractors.d.cts +7 -0
- package/dist/favicons/extractors.d.ts +7 -0
- package/dist/favicons/extractors.js +13 -0
- package/dist/favicons/index.cjs +29 -0
- package/dist/favicons/index.d.cts +7 -0
- package/dist/favicons/index.d.ts +7 -0
- package/dist/favicons/index.js +29 -0
- package/dist/favicons/platform/handlers/bluesky.cjs +27 -0
- package/dist/favicons/platform/handlers/bluesky.js +27 -0
- package/dist/favicons/platform/handlers/codeberg.cjs +18 -0
- package/dist/favicons/platform/handlers/codeberg.js +18 -0
- package/dist/favicons/platform/handlers/deviantart.cjs +29 -0
- package/dist/favicons/platform/handlers/deviantart.js +29 -0
- package/dist/favicons/platform/handlers/github.cjs +18 -0
- package/dist/favicons/platform/handlers/github.js +18 -0
- package/dist/favicons/platform/handlers/githubGist.cjs +18 -0
- package/dist/favicons/platform/handlers/githubGist.js +18 -0
- package/dist/favicons/platform/handlers/lobsters.cjs +21 -0
- package/dist/favicons/platform/handlers/lobsters.js +21 -0
- package/dist/favicons/platform/handlers/mastodon.cjs +36 -0
- package/dist/favicons/platform/handlers/mastodon.js +34 -0
- package/dist/favicons/platform/handlers/reddit.cjs +41 -0
- package/dist/favicons/platform/handlers/reddit.js +41 -0
- package/dist/favicons/platform/handlers/sourceforge.cjs +21 -0
- package/dist/favicons/platform/handlers/sourceforge.js +21 -0
- package/dist/favicons/platform/handlers/tumblr.cjs +16 -0
- package/dist/favicons/platform/handlers/tumblr.js +16 -0
- package/dist/favicons/types.d.cts +4 -0
- package/dist/favicons/types.d.ts +4 -0
- package/dist/favicons.cjs +12 -0
- package/dist/favicons.d.cts +4 -0
- package/dist/favicons.d.ts +4 -0
- package/dist/favicons.js +3 -0
- package/dist/feeds/defaults.cjs +55 -25
- package/dist/feeds/defaults.js +40 -10
- package/dist/feeds/extractors.cjs +1 -3
- package/dist/feeds/extractors.js +1 -3
- package/dist/feeds/index.cjs +6 -8
- package/dist/feeds/index.d.cts +1 -1
- package/dist/feeds/index.d.ts +1 -1
- package/dist/feeds/index.js +1 -3
- package/dist/feeds/platform/handlers/behance.cjs +2 -4
- package/dist/feeds/platform/handlers/behance.js +1 -3
- package/dist/feeds/platform/handlers/blogspot.cjs +7 -6
- package/dist/feeds/platform/handlers/blogspot.js +6 -5
- package/dist/feeds/platform/handlers/bluesky.cjs +3 -5
- package/dist/feeds/platform/handlers/bluesky.js +2 -4
- package/dist/feeds/platform/handlers/codeberg.cjs +69 -0
- package/dist/feeds/platform/handlers/codeberg.js +67 -0
- package/dist/feeds/platform/handlers/csdn.cjs +19 -0
- package/dist/feeds/platform/handlers/csdn.js +19 -0
- package/dist/feeds/platform/handlers/dailymotion.cjs +2 -4
- package/dist/feeds/platform/handlers/dailymotion.js +1 -3
- package/dist/feeds/platform/handlers/deviantart.cjs +4 -4
- package/dist/feeds/platform/handlers/deviantart.js +1 -3
- package/dist/feeds/platform/handlers/devto.cjs +2 -4
- package/dist/feeds/platform/handlers/devto.js +1 -3
- package/dist/feeds/platform/handlers/douban.cjs +54 -0
- package/dist/feeds/platform/handlers/douban.js +54 -0
- package/dist/feeds/platform/handlers/github.cjs +5 -4
- package/dist/feeds/platform/handlers/github.js +2 -3
- package/dist/feeds/platform/handlers/githubGist.cjs +4 -4
- package/dist/feeds/platform/handlers/githubGist.js +1 -3
- package/dist/feeds/platform/handlers/gitlab.cjs +2 -4
- package/dist/feeds/platform/handlers/gitlab.js +1 -3
- package/dist/feeds/platform/handlers/goodreads.cjs +39 -0
- package/dist/feeds/platform/handlers/goodreads.js +39 -0
- package/dist/feeds/platform/handlers/hashnode.cjs +16 -0
- package/dist/feeds/platform/handlers/hashnode.js +16 -0
- package/dist/feeds/platform/handlers/hatenablog.cjs +53 -0
- package/dist/feeds/platform/handlers/hatenablog.js +53 -0
- package/dist/feeds/platform/handlers/itchio.cjs +88 -0
- package/dist/feeds/platform/handlers/itchio.js +88 -0
- package/dist/feeds/platform/handlers/kickstarter.cjs +2 -4
- package/dist/feeds/platform/handlers/kickstarter.js +1 -3
- package/dist/feeds/platform/handlers/letterboxd.cjs +42 -0
- package/dist/feeds/platform/handlers/letterboxd.js +42 -0
- package/dist/feeds/platform/handlers/lobsters.cjs +3 -4
- package/dist/feeds/platform/handlers/lobsters.js +1 -3
- package/dist/feeds/platform/handlers/mastodon.cjs +40 -0
- package/dist/feeds/platform/handlers/mastodon.js +40 -0
- package/dist/feeds/platform/handlers/medium.cjs +2 -4
- package/dist/feeds/platform/handlers/medium.js +1 -3
- package/dist/feeds/platform/handlers/paragraph.cjs +21 -0
- package/dist/feeds/platform/handlers/paragraph.js +21 -0
- package/dist/feeds/platform/handlers/pinterest.cjs +2 -15
- package/dist/feeds/platform/handlers/pinterest.js +1 -14
- package/dist/feeds/platform/handlers/producthunt.cjs +2 -4
- package/dist/feeds/platform/handlers/producthunt.js +1 -3
- package/dist/feeds/platform/handlers/reddit.cjs +3 -4
- package/dist/feeds/platform/handlers/reddit.js +1 -3
- package/dist/feeds/platform/handlers/soundcloud.cjs +2 -4
- package/dist/feeds/platform/handlers/soundcloud.js +1 -3
- package/dist/feeds/platform/handlers/sourceforge.cjs +20 -0
- package/dist/feeds/platform/handlers/sourceforge.js +19 -0
- package/dist/feeds/platform/handlers/stackExchange.cjs +37 -0
- package/dist/feeds/platform/handlers/stackExchange.js +37 -0
- package/dist/feeds/platform/handlers/steam.cjs +26 -0
- package/dist/feeds/platform/handlers/steam.js +26 -0
- package/dist/feeds/platform/handlers/substack.cjs +2 -4
- package/dist/feeds/platform/handlers/substack.js +1 -3
- package/dist/feeds/platform/handlers/tumblr.cjs +5 -5
- package/dist/feeds/platform/handlers/tumblr.js +3 -4
- package/dist/feeds/platform/handlers/v2ex.cjs +33 -0
- package/dist/feeds/platform/handlers/v2ex.js +33 -0
- package/dist/feeds/platform/handlers/vimeo.cjs +68 -0
- package/dist/feeds/platform/handlers/vimeo.js +68 -0
- package/dist/feeds/platform/handlers/wordpress.cjs +5 -7
- package/dist/feeds/platform/handlers/wordpress.js +4 -6
- package/dist/feeds/platform/handlers/wpengine.cjs +4 -7
- package/dist/feeds/platform/handlers/wpengine.js +2 -4
- package/dist/feeds/platform/handlers/ximalaya.cjs +19 -0
- package/dist/feeds/platform/handlers/ximalaya.js +19 -0
- package/dist/feeds/platform/handlers/youtube.cjs +19 -8
- package/dist/feeds/platform/handlers/youtube.js +18 -7
- package/dist/feeds.cjs +4 -5
- package/dist/feeds.js +1 -2
- package/dist/hubs/discover/index.cjs +7 -9
- package/dist/hubs/discover/index.js +1 -3
- package/dist/hubs/discover/utils.cjs +1 -3
- package/dist/hubs/discover/utils.js +1 -2
- package/dist/hubs/feed/index.cjs +1 -3
- package/dist/hubs/feed/index.js +1 -3
- package/dist/hubs/headers/index.cjs +3 -5
- package/dist/hubs/headers/index.js +1 -3
- package/dist/hubs/html/index.cjs +3 -5
- package/dist/hubs/html/index.js +1 -3
- package/dist/hubs.js +1 -1
- package/dist/index.cjs +8 -7
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -2
- package/dist/methods.cjs +13 -10
- package/dist/methods.d.cts +3 -1
- package/dist/methods.d.ts +3 -1
- package/dist/methods.js +3 -2
- package/dist/utils.cjs +3 -4
- package/dist/utils.js +1 -2
- package/package.json +15 -5
package/dist/common/utils.cjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
const require_locales = require(
|
|
2
|
-
|
|
1
|
+
const require_locales = require("./locales.cjs");
|
|
3
2
|
//#region src/common/utils.ts
|
|
4
3
|
const composeHint = (key) => ({
|
|
5
4
|
key,
|
|
@@ -8,15 +7,23 @@ const composeHint = (key) => ({
|
|
|
8
7
|
const normalizeMimeType = (type) => {
|
|
9
8
|
return type.split(";")[0].trim().toLowerCase();
|
|
10
9
|
};
|
|
11
|
-
const isSubdomainOf = (url,
|
|
12
|
-
|
|
10
|
+
const isSubdomainOf = (url, domains) => {
|
|
11
|
+
try {
|
|
12
|
+
const hostname = new URL(url).hostname.toLowerCase();
|
|
13
|
+
return (Array.isArray(domains) ? domains : [domains]).some((domain) => hostname.endsWith(`.${domain}`));
|
|
14
|
+
} catch {}
|
|
15
|
+
return false;
|
|
13
16
|
};
|
|
14
17
|
const isHostOf = (url, hosts) => {
|
|
15
|
-
|
|
18
|
+
try {
|
|
19
|
+
const list = Array.isArray(hosts) ? hosts : [hosts];
|
|
20
|
+
return isAnyOf(new URL(url).hostname, list);
|
|
21
|
+
} catch {}
|
|
22
|
+
return false;
|
|
16
23
|
};
|
|
17
24
|
const includesAnyOf = (value, patterns, parser) => {
|
|
18
25
|
const parsedValue = parser ? parser(value) : value?.toLowerCase();
|
|
19
|
-
return patterns.map((pattern) => pattern.toLowerCase()).some((pattern) => parsedValue?.includes(pattern));
|
|
26
|
+
return patterns.map((pattern) => pattern.toLowerCase()).some((pattern) => pattern && parsedValue?.includes(pattern));
|
|
20
27
|
};
|
|
21
28
|
const isAnyOf = (value, patterns, parser) => {
|
|
22
29
|
const parsedValue = parser ? parser(value) : value?.toLowerCase()?.trim();
|
|
@@ -27,13 +34,16 @@ const anyWordMatchesAnyOf = (value, patterns) => {
|
|
|
27
34
|
};
|
|
28
35
|
const endsWithAnyOf = (value, patterns) => {
|
|
29
36
|
const lowerValue = value.toLowerCase();
|
|
30
|
-
return patterns.some((pattern) => lowerValue.endsWith(pattern.toLowerCase()));
|
|
37
|
+
return patterns.some((pattern) => pattern && lowerValue.endsWith(pattern.toLowerCase()));
|
|
31
38
|
};
|
|
32
39
|
const isOfAllowedMimeType = (type, allowedTypes) => {
|
|
33
40
|
if (allowedTypes.length === 0) return true;
|
|
34
41
|
if (!type) return false;
|
|
35
42
|
return isAnyOf(type, allowedTypes, normalizeMimeType);
|
|
36
43
|
};
|
|
44
|
+
const omitEmpty = (array) => {
|
|
45
|
+
return array.filter((item) => item != null && item !== "");
|
|
46
|
+
};
|
|
37
47
|
const normalizeUrl = (url, baseUrl) => {
|
|
38
48
|
return baseUrl ? new URL(url, baseUrl).href : url;
|
|
39
49
|
};
|
|
@@ -45,6 +55,7 @@ const matchesAnyOfLinkSelectors = (rel, type, selectors) => {
|
|
|
45
55
|
});
|
|
46
56
|
};
|
|
47
57
|
const processConcurrently = async (items, processFn, options) => {
|
|
58
|
+
if (options.concurrency < 1) return;
|
|
48
59
|
const active = /* @__PURE__ */ new Set();
|
|
49
60
|
let index = 0;
|
|
50
61
|
while (index < items.length || active.size > 0) {
|
|
@@ -59,7 +70,6 @@ const processConcurrently = async (items, processFn, options) => {
|
|
|
59
70
|
if (active.size > 0) await Promise.race(active);
|
|
60
71
|
}
|
|
61
72
|
};
|
|
62
|
-
|
|
63
73
|
//#endregion
|
|
64
74
|
exports.anyWordMatchesAnyOf = anyWordMatchesAnyOf;
|
|
65
75
|
exports.composeHint = composeHint;
|
|
@@ -70,4 +80,5 @@ exports.isHostOf = isHostOf;
|
|
|
70
80
|
exports.isSubdomainOf = isSubdomainOf;
|
|
71
81
|
exports.matchesAnyOfLinkSelectors = matchesAnyOfLinkSelectors;
|
|
72
82
|
exports.normalizeUrl = normalizeUrl;
|
|
73
|
-
exports.
|
|
83
|
+
exports.omitEmpty = omitEmpty;
|
|
84
|
+
exports.processConcurrently = processConcurrently;
|
package/dist/common/utils.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/common/utils.d.ts
|
|
2
|
-
declare const isSubdomainOf: (url: string,
|
|
3
|
-
declare const isHostOf: (url: string, hosts: Array<string>) => boolean;
|
|
2
|
+
declare const isSubdomainOf: (url: string, domains: string | Array<string>) => boolean;
|
|
3
|
+
declare const isHostOf: (url: string, hosts: string | Array<string>) => boolean;
|
|
4
4
|
declare const includesAnyOf: (value: string, patterns: Array<string>, parser?: (value: string) => string) => boolean;
|
|
5
5
|
declare const isAnyOf: (value: string, patterns: Array<string>, parser?: (value: string) => string) => boolean;
|
|
6
6
|
declare const anyWordMatchesAnyOf: (value: string, patterns: Array<string>) => boolean;
|
package/dist/common/utils.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//#region src/common/utils.d.ts
|
|
2
|
-
declare const isSubdomainOf: (url: string,
|
|
3
|
-
declare const isHostOf: (url: string, hosts: Array<string>) => boolean;
|
|
2
|
+
declare const isSubdomainOf: (url: string, domains: string | Array<string>) => boolean;
|
|
3
|
+
declare const isHostOf: (url: string, hosts: string | Array<string>) => boolean;
|
|
4
4
|
declare const includesAnyOf: (value: string, patterns: Array<string>, parser?: (value: string) => string) => boolean;
|
|
5
5
|
declare const isAnyOf: (value: string, patterns: Array<string>, parser?: (value: string) => string) => boolean;
|
|
6
6
|
declare const anyWordMatchesAnyOf: (value: string, patterns: Array<string>) => boolean;
|
package/dist/common/utils.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { hints } from "./locales.js";
|
|
2
|
-
|
|
3
2
|
//#region src/common/utils.ts
|
|
4
3
|
const composeHint = (key) => ({
|
|
5
4
|
key,
|
|
@@ -8,15 +7,23 @@ const composeHint = (key) => ({
|
|
|
8
7
|
const normalizeMimeType = (type) => {
|
|
9
8
|
return type.split(";")[0].trim().toLowerCase();
|
|
10
9
|
};
|
|
11
|
-
const isSubdomainOf = (url,
|
|
12
|
-
|
|
10
|
+
const isSubdomainOf = (url, domains) => {
|
|
11
|
+
try {
|
|
12
|
+
const hostname = new URL(url).hostname.toLowerCase();
|
|
13
|
+
return (Array.isArray(domains) ? domains : [domains]).some((domain) => hostname.endsWith(`.${domain}`));
|
|
14
|
+
} catch {}
|
|
15
|
+
return false;
|
|
13
16
|
};
|
|
14
17
|
const isHostOf = (url, hosts) => {
|
|
15
|
-
|
|
18
|
+
try {
|
|
19
|
+
const list = Array.isArray(hosts) ? hosts : [hosts];
|
|
20
|
+
return isAnyOf(new URL(url).hostname, list);
|
|
21
|
+
} catch {}
|
|
22
|
+
return false;
|
|
16
23
|
};
|
|
17
24
|
const includesAnyOf = (value, patterns, parser) => {
|
|
18
25
|
const parsedValue = parser ? parser(value) : value?.toLowerCase();
|
|
19
|
-
return patterns.map((pattern) => pattern.toLowerCase()).some((pattern) => parsedValue?.includes(pattern));
|
|
26
|
+
return patterns.map((pattern) => pattern.toLowerCase()).some((pattern) => pattern && parsedValue?.includes(pattern));
|
|
20
27
|
};
|
|
21
28
|
const isAnyOf = (value, patterns, parser) => {
|
|
22
29
|
const parsedValue = parser ? parser(value) : value?.toLowerCase()?.trim();
|
|
@@ -27,13 +34,16 @@ const anyWordMatchesAnyOf = (value, patterns) => {
|
|
|
27
34
|
};
|
|
28
35
|
const endsWithAnyOf = (value, patterns) => {
|
|
29
36
|
const lowerValue = value.toLowerCase();
|
|
30
|
-
return patterns.some((pattern) => lowerValue.endsWith(pattern.toLowerCase()));
|
|
37
|
+
return patterns.some((pattern) => pattern && lowerValue.endsWith(pattern.toLowerCase()));
|
|
31
38
|
};
|
|
32
39
|
const isOfAllowedMimeType = (type, allowedTypes) => {
|
|
33
40
|
if (allowedTypes.length === 0) return true;
|
|
34
41
|
if (!type) return false;
|
|
35
42
|
return isAnyOf(type, allowedTypes, normalizeMimeType);
|
|
36
43
|
};
|
|
44
|
+
const omitEmpty = (array) => {
|
|
45
|
+
return array.filter((item) => item != null && item !== "");
|
|
46
|
+
};
|
|
37
47
|
const normalizeUrl = (url, baseUrl) => {
|
|
38
48
|
return baseUrl ? new URL(url, baseUrl).href : url;
|
|
39
49
|
};
|
|
@@ -45,6 +55,7 @@ const matchesAnyOfLinkSelectors = (rel, type, selectors) => {
|
|
|
45
55
|
});
|
|
46
56
|
};
|
|
47
57
|
const processConcurrently = async (items, processFn, options) => {
|
|
58
|
+
if (options.concurrency < 1) return;
|
|
48
59
|
const active = /* @__PURE__ */ new Set();
|
|
49
60
|
let index = 0;
|
|
50
61
|
while (index < items.length || active.size > 0) {
|
|
@@ -59,6 +70,5 @@ const processConcurrently = async (items, processFn, options) => {
|
|
|
59
70
|
if (active.size > 0) await Promise.race(active);
|
|
60
71
|
}
|
|
61
72
|
};
|
|
62
|
-
|
|
63
73
|
//#endregion
|
|
64
|
-
export { anyWordMatchesAnyOf, composeHint, endsWithAnyOf, includesAnyOf, isAnyOf, isHostOf, isSubdomainOf, matchesAnyOfLinkSelectors, normalizeUrl, processConcurrently };
|
|
74
|
+
export { anyWordMatchesAnyOf, composeHint, endsWithAnyOf, includesAnyOf, isAnyOf, isHostOf, isSubdomainOf, matchesAnyOfLinkSelectors, normalizeUrl, omitEmpty, processConcurrently };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const require_utils = require("../common/utils.cjs");
|
|
2
|
+
const require_bluesky = require("./platform/handlers/bluesky.cjs");
|
|
3
|
+
const require_codeberg = require("./platform/handlers/codeberg.cjs");
|
|
4
|
+
const require_deviantart = require("./platform/handlers/deviantart.cjs");
|
|
5
|
+
const require_github = require("./platform/handlers/github.cjs");
|
|
6
|
+
const require_githubGist = require("./platform/handlers/githubGist.cjs");
|
|
7
|
+
const require_lobsters = require("./platform/handlers/lobsters.cjs");
|
|
8
|
+
const require_mastodon = require("./platform/handlers/mastodon.cjs");
|
|
9
|
+
const require_reddit = require("./platform/handlers/reddit.cjs");
|
|
10
|
+
const require_sourceforge = require("./platform/handlers/sourceforge.cjs");
|
|
11
|
+
const require_tumblr = require("./platform/handlers/tumblr.cjs");
|
|
12
|
+
//#region src/favicons/defaults.ts
|
|
13
|
+
const defaultIconRels = [
|
|
14
|
+
"icon",
|
|
15
|
+
"shortcut",
|
|
16
|
+
"apple-touch-icon",
|
|
17
|
+
"apple-touch-icon-precomposed"
|
|
18
|
+
];
|
|
19
|
+
const defaultGuessPaths = [
|
|
20
|
+
"/favicon.ico",
|
|
21
|
+
"/apple-touch-icon.png",
|
|
22
|
+
"/apple-touch-icon-precomposed.png",
|
|
23
|
+
"/favicon.png",
|
|
24
|
+
"/favicon.svg"
|
|
25
|
+
];
|
|
26
|
+
const linkSelectors = defaultIconRels.map((rel) => ({ rel }));
|
|
27
|
+
const defaultFeedOptions = { extractUrls: ({ format, feed }) => {
|
|
28
|
+
if (format === "atom") return require_utils.omitEmpty([feed.icon]);
|
|
29
|
+
if (format === "json") return require_utils.omitEmpty([feed.favicon, feed.icon]);
|
|
30
|
+
return [];
|
|
31
|
+
} };
|
|
32
|
+
const defaultHtmlOptions = {
|
|
33
|
+
linkSelectors,
|
|
34
|
+
anchorUris: [],
|
|
35
|
+
anchorIgnoredUris: [],
|
|
36
|
+
anchorLabels: []
|
|
37
|
+
};
|
|
38
|
+
const defaultHeadersOptions = { linkSelectors };
|
|
39
|
+
const defaultGuessOptions = { uris: defaultGuessPaths };
|
|
40
|
+
const defaultPlatformOptions = { handlers: [
|
|
41
|
+
require_github.githubHandler,
|
|
42
|
+
require_githubGist.githubGistHandler,
|
|
43
|
+
require_mastodon.mastodonHandler,
|
|
44
|
+
require_bluesky.blueskyHandler,
|
|
45
|
+
require_reddit.redditHandler,
|
|
46
|
+
require_tumblr.tumblrHandler,
|
|
47
|
+
require_codeberg.codebergHandler,
|
|
48
|
+
require_lobsters.lobstersHandler,
|
|
49
|
+
require_sourceforge.sourceforgeHandler,
|
|
50
|
+
require_deviantart.deviantartHandler
|
|
51
|
+
] };
|
|
52
|
+
//#endregion
|
|
53
|
+
exports.defaultFeedOptions = defaultFeedOptions;
|
|
54
|
+
exports.defaultGuessOptions = defaultGuessOptions;
|
|
55
|
+
exports.defaultGuessPaths = defaultGuessPaths;
|
|
56
|
+
exports.defaultHeadersOptions = defaultHeadersOptions;
|
|
57
|
+
exports.defaultHtmlOptions = defaultHtmlOptions;
|
|
58
|
+
exports.defaultIconRels = defaultIconRels;
|
|
59
|
+
exports.defaultPlatformOptions = defaultPlatformOptions;
|
|
60
|
+
exports.linkSelectors = linkSelectors;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FeedMethodOptions } from "../common/uris/feed/types.cjs";
|
|
2
|
+
import { GuessMethodOptions } from "../common/uris/guess/types.cjs";
|
|
3
|
+
import { HeadersMethodOptions } from "../common/uris/headers/types.cjs";
|
|
4
|
+
import { HtmlMethodOptions } from "../common/uris/html/types.cjs";
|
|
5
|
+
import { PlatformMethodOptions } from "../common/uris/platform/types.cjs";
|
|
6
|
+
import { LinkSelector } from "../common/types.cjs";
|
|
7
|
+
|
|
8
|
+
//#region src/favicons/defaults.d.ts
|
|
9
|
+
declare const defaultIconRels: string[];
|
|
10
|
+
declare const defaultGuessPaths: string[];
|
|
11
|
+
declare const linkSelectors: Array<LinkSelector>;
|
|
12
|
+
declare const defaultFeedOptions: FeedMethodOptions;
|
|
13
|
+
declare const defaultHtmlOptions: Omit<HtmlMethodOptions, 'baseUrl'>;
|
|
14
|
+
declare const defaultHeadersOptions: Omit<HeadersMethodOptions, 'baseUrl'>;
|
|
15
|
+
declare const defaultGuessOptions: Omit<GuessMethodOptions, 'baseUrl'>;
|
|
16
|
+
declare const defaultPlatformOptions: Omit<PlatformMethodOptions, 'baseUrl'>;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { defaultFeedOptions, defaultGuessOptions, defaultGuessPaths, defaultHeadersOptions, defaultHtmlOptions, defaultIconRels, defaultPlatformOptions, linkSelectors };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FeedMethodOptions } from "../common/uris/feed/types.js";
|
|
2
|
+
import { GuessMethodOptions } from "../common/uris/guess/types.js";
|
|
3
|
+
import { HeadersMethodOptions } from "../common/uris/headers/types.js";
|
|
4
|
+
import { HtmlMethodOptions } from "../common/uris/html/types.js";
|
|
5
|
+
import { PlatformMethodOptions } from "../common/uris/platform/types.js";
|
|
6
|
+
import { LinkSelector } from "../common/types.js";
|
|
7
|
+
|
|
8
|
+
//#region src/favicons/defaults.d.ts
|
|
9
|
+
declare const defaultIconRels: string[];
|
|
10
|
+
declare const defaultGuessPaths: string[];
|
|
11
|
+
declare const linkSelectors: Array<LinkSelector>;
|
|
12
|
+
declare const defaultFeedOptions: FeedMethodOptions;
|
|
13
|
+
declare const defaultHtmlOptions: Omit<HtmlMethodOptions, 'baseUrl'>;
|
|
14
|
+
declare const defaultHeadersOptions: Omit<HeadersMethodOptions, 'baseUrl'>;
|
|
15
|
+
declare const defaultGuessOptions: Omit<GuessMethodOptions, 'baseUrl'>;
|
|
16
|
+
declare const defaultPlatformOptions: Omit<PlatformMethodOptions, 'baseUrl'>;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { defaultFeedOptions, defaultGuessOptions, defaultGuessPaths, defaultHeadersOptions, defaultHtmlOptions, defaultIconRels, defaultPlatformOptions, linkSelectors };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { omitEmpty } from "../common/utils.js";
|
|
2
|
+
import { blueskyHandler } from "./platform/handlers/bluesky.js";
|
|
3
|
+
import { codebergHandler } from "./platform/handlers/codeberg.js";
|
|
4
|
+
import { deviantartHandler } from "./platform/handlers/deviantart.js";
|
|
5
|
+
import { githubHandler } from "./platform/handlers/github.js";
|
|
6
|
+
import { githubGistHandler } from "./platform/handlers/githubGist.js";
|
|
7
|
+
import { lobstersHandler } from "./platform/handlers/lobsters.js";
|
|
8
|
+
import { mastodonHandler } from "./platform/handlers/mastodon.js";
|
|
9
|
+
import { redditHandler } from "./platform/handlers/reddit.js";
|
|
10
|
+
import { sourceforgeHandler } from "./platform/handlers/sourceforge.js";
|
|
11
|
+
import { tumblrHandler } from "./platform/handlers/tumblr.js";
|
|
12
|
+
//#region src/favicons/defaults.ts
|
|
13
|
+
const defaultIconRels = [
|
|
14
|
+
"icon",
|
|
15
|
+
"shortcut",
|
|
16
|
+
"apple-touch-icon",
|
|
17
|
+
"apple-touch-icon-precomposed"
|
|
18
|
+
];
|
|
19
|
+
const defaultGuessPaths = [
|
|
20
|
+
"/favicon.ico",
|
|
21
|
+
"/apple-touch-icon.png",
|
|
22
|
+
"/apple-touch-icon-precomposed.png",
|
|
23
|
+
"/favicon.png",
|
|
24
|
+
"/favicon.svg"
|
|
25
|
+
];
|
|
26
|
+
const linkSelectors = defaultIconRels.map((rel) => ({ rel }));
|
|
27
|
+
const defaultFeedOptions = { extractUrls: ({ format, feed }) => {
|
|
28
|
+
if (format === "atom") return omitEmpty([feed.icon]);
|
|
29
|
+
if (format === "json") return omitEmpty([feed.favicon, feed.icon]);
|
|
30
|
+
return [];
|
|
31
|
+
} };
|
|
32
|
+
const defaultHtmlOptions = {
|
|
33
|
+
linkSelectors,
|
|
34
|
+
anchorUris: [],
|
|
35
|
+
anchorIgnoredUris: [],
|
|
36
|
+
anchorLabels: []
|
|
37
|
+
};
|
|
38
|
+
const defaultHeadersOptions = { linkSelectors };
|
|
39
|
+
const defaultGuessOptions = { uris: defaultGuessPaths };
|
|
40
|
+
const defaultPlatformOptions = { handlers: [
|
|
41
|
+
githubHandler,
|
|
42
|
+
githubGistHandler,
|
|
43
|
+
mastodonHandler,
|
|
44
|
+
blueskyHandler,
|
|
45
|
+
redditHandler,
|
|
46
|
+
tumblrHandler,
|
|
47
|
+
codebergHandler,
|
|
48
|
+
lobstersHandler,
|
|
49
|
+
sourceforgeHandler,
|
|
50
|
+
deviantartHandler
|
|
51
|
+
] };
|
|
52
|
+
//#endregion
|
|
53
|
+
export { defaultFeedOptions, defaultGuessOptions, defaultGuessPaths, defaultHeadersOptions, defaultHtmlOptions, defaultIconRels, defaultPlatformOptions, linkSelectors };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/favicons/extractors.ts
|
|
2
|
+
const defaultExtractor = async ({ url, status }) => {
|
|
3
|
+
if (status !== void 0 && status >= 200 && status < 400) return {
|
|
4
|
+
url,
|
|
5
|
+
isValid: true
|
|
6
|
+
};
|
|
7
|
+
return {
|
|
8
|
+
url,
|
|
9
|
+
isValid: false
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
exports.defaultExtractor = defaultExtractor;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/favicons/extractors.ts
|
|
2
|
+
const defaultExtractor = async ({ url, status }) => {
|
|
3
|
+
if (status !== void 0 && status >= 200 && status < 400) return {
|
|
4
|
+
url,
|
|
5
|
+
isValid: true
|
|
6
|
+
};
|
|
7
|
+
return {
|
|
8
|
+
url,
|
|
9
|
+
isValid: false
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { defaultExtractor };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const require_utils = require("../common/utils.cjs");
|
|
2
|
+
const require_utils$1 = require("../common/discover/utils.cjs");
|
|
3
|
+
const require_index = require("../common/discover/index.cjs");
|
|
4
|
+
const require_defaults = require("./defaults.cjs");
|
|
5
|
+
const require_extractors = require("./extractors.cjs");
|
|
6
|
+
//#region src/favicons/index.ts
|
|
7
|
+
const discoverFavicons = async (input, options = {}) => {
|
|
8
|
+
return require_index.discover(input, {
|
|
9
|
+
...options,
|
|
10
|
+
methods: options.methods ?? [
|
|
11
|
+
"platform",
|
|
12
|
+
"feed",
|
|
13
|
+
"html",
|
|
14
|
+
"headers",
|
|
15
|
+
"guess"
|
|
16
|
+
],
|
|
17
|
+
fetchFn: options.fetchFn ?? require_utils$1.defaultFetchFn,
|
|
18
|
+
extractFn: options.extractFn ?? require_extractors.defaultExtractor,
|
|
19
|
+
normalizeUrlFn: options.normalizeUrlFn ?? require_utils.normalizeUrl
|
|
20
|
+
}, {
|
|
21
|
+
platform: require_defaults.defaultPlatformOptions,
|
|
22
|
+
feed: require_defaults.defaultFeedOptions,
|
|
23
|
+
html: require_defaults.defaultHtmlOptions,
|
|
24
|
+
headers: require_defaults.defaultHeadersOptions,
|
|
25
|
+
guess: require_defaults.defaultGuessOptions
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
//#endregion
|
|
29
|
+
exports.discoverFavicons = discoverFavicons;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DiscoverInput, DiscoverOptions, DiscoverResult } from "../common/types.cjs";
|
|
2
|
+
import { FaviconResult } from "./types.cjs";
|
|
3
|
+
|
|
4
|
+
//#region src/favicons/index.d.ts
|
|
5
|
+
declare const discoverFavicons: <TValid extends FaviconResult = FaviconResult>(input: DiscoverInput, options?: DiscoverOptions<TValid>) => Promise<Array<DiscoverResult<TValid>>>;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { discoverFavicons };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { DiscoverInput, DiscoverOptions, DiscoverResult } from "../common/types.js";
|
|
2
|
+
import { FaviconResult } from "./types.js";
|
|
3
|
+
|
|
4
|
+
//#region src/favicons/index.d.ts
|
|
5
|
+
declare const discoverFavicons: <TValid extends FaviconResult = FaviconResult>(input: DiscoverInput, options?: DiscoverOptions<TValid>) => Promise<Array<DiscoverResult<TValid>>>;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { discoverFavicons };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { normalizeUrl } from "../common/utils.js";
|
|
2
|
+
import { defaultFetchFn } from "../common/discover/utils.js";
|
|
3
|
+
import { discover } from "../common/discover/index.js";
|
|
4
|
+
import { defaultFeedOptions, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions } from "./defaults.js";
|
|
5
|
+
import { defaultExtractor } from "./extractors.js";
|
|
6
|
+
//#region src/favicons/index.ts
|
|
7
|
+
const discoverFavicons = async (input, options = {}) => {
|
|
8
|
+
return discover(input, {
|
|
9
|
+
...options,
|
|
10
|
+
methods: options.methods ?? [
|
|
11
|
+
"platform",
|
|
12
|
+
"feed",
|
|
13
|
+
"html",
|
|
14
|
+
"headers",
|
|
15
|
+
"guess"
|
|
16
|
+
],
|
|
17
|
+
fetchFn: options.fetchFn ?? defaultFetchFn,
|
|
18
|
+
extractFn: options.extractFn ?? defaultExtractor,
|
|
19
|
+
normalizeUrlFn: options.normalizeUrlFn ?? normalizeUrl
|
|
20
|
+
}, {
|
|
21
|
+
platform: defaultPlatformOptions,
|
|
22
|
+
feed: defaultFeedOptions,
|
|
23
|
+
html: defaultHtmlOptions,
|
|
24
|
+
headers: defaultHeadersOptions,
|
|
25
|
+
guess: defaultGuessOptions
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
//#endregion
|
|
29
|
+
export { discoverFavicons };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const require_utils = require("../../../common/utils.cjs");
|
|
2
|
+
//#region src/favicons/platform/handlers/bluesky.ts
|
|
3
|
+
const hosts = ["bsky.app", "www.bsky.app"];
|
|
4
|
+
const isProfilePath = (pathname) => {
|
|
5
|
+
const segments = pathname.split("/").filter(Boolean);
|
|
6
|
+
return segments.length >= 2 && segments[0] === "profile";
|
|
7
|
+
};
|
|
8
|
+
const blueskyHandler = {
|
|
9
|
+
match: (url) => {
|
|
10
|
+
try {
|
|
11
|
+
return require_utils.isHostOf(url, hosts) && isProfilePath(new URL(url).pathname);
|
|
12
|
+
} catch {}
|
|
13
|
+
return false;
|
|
14
|
+
},
|
|
15
|
+
resolve: async (url, _content, _headers, fetchFn) => {
|
|
16
|
+
if (!fetchFn) return [];
|
|
17
|
+
try {
|
|
18
|
+
const { pathname } = new URL(url);
|
|
19
|
+
const response = await fetchFn(`https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=${pathname.split("/").filter(Boolean)[1]}`);
|
|
20
|
+
const data = JSON.parse(typeof response.body === "string" ? response.body : "");
|
|
21
|
+
if (typeof data.avatar === "string" && data.avatar.length > 0) return [{ uri: data.avatar }];
|
|
22
|
+
} catch {}
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
exports.blueskyHandler = blueskyHandler;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { isHostOf } from "../../../common/utils.js";
|
|
2
|
+
//#region src/favicons/platform/handlers/bluesky.ts
|
|
3
|
+
const hosts = ["bsky.app", "www.bsky.app"];
|
|
4
|
+
const isProfilePath = (pathname) => {
|
|
5
|
+
const segments = pathname.split("/").filter(Boolean);
|
|
6
|
+
return segments.length >= 2 && segments[0] === "profile";
|
|
7
|
+
};
|
|
8
|
+
const blueskyHandler = {
|
|
9
|
+
match: (url) => {
|
|
10
|
+
try {
|
|
11
|
+
return isHostOf(url, hosts) && isProfilePath(new URL(url).pathname);
|
|
12
|
+
} catch {}
|
|
13
|
+
return false;
|
|
14
|
+
},
|
|
15
|
+
resolve: async (url, _content, _headers, fetchFn) => {
|
|
16
|
+
if (!fetchFn) return [];
|
|
17
|
+
try {
|
|
18
|
+
const { pathname } = new URL(url);
|
|
19
|
+
const response = await fetchFn(`https://public.api.bsky.app/xrpc/app.bsky.actor.getProfile?actor=${pathname.split("/").filter(Boolean)[1]}`);
|
|
20
|
+
const data = JSON.parse(typeof response.body === "string" ? response.body : "");
|
|
21
|
+
if (typeof data.avatar === "string" && data.avatar.length > 0) return [{ uri: data.avatar }];
|
|
22
|
+
} catch {}
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
//#endregion
|
|
27
|
+
export { blueskyHandler };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const require_utils = require("../../../common/utils.cjs");
|
|
2
|
+
const require_codeberg = require("../../../feeds/platform/handlers/codeberg.cjs");
|
|
3
|
+
//#region src/favicons/platform/handlers/codeberg.ts
|
|
4
|
+
const codebergHandler = {
|
|
5
|
+
match: (url) => {
|
|
6
|
+
return require_utils.isHostOf(url, require_codeberg.hosts);
|
|
7
|
+
},
|
|
8
|
+
resolve: (url) => {
|
|
9
|
+
const { origin, pathname } = new URL(url);
|
|
10
|
+
const segments = pathname.split("/").filter(Boolean);
|
|
11
|
+
if (segments.length === 0) return [];
|
|
12
|
+
const username = segments[0];
|
|
13
|
+
if (require_utils.isAnyOf(username, require_codeberg.excludedPaths)) return [];
|
|
14
|
+
return [{ uri: `${origin}/user/avatar/${username}/512` }];
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
exports.codebergHandler = codebergHandler;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { isAnyOf, isHostOf } from "../../../common/utils.js";
|
|
2
|
+
import { excludedPaths, hosts } from "../../../feeds/platform/handlers/codeberg.js";
|
|
3
|
+
//#region src/favicons/platform/handlers/codeberg.ts
|
|
4
|
+
const codebergHandler = {
|
|
5
|
+
match: (url) => {
|
|
6
|
+
return isHostOf(url, hosts);
|
|
7
|
+
},
|
|
8
|
+
resolve: (url) => {
|
|
9
|
+
const { origin, pathname } = new URL(url);
|
|
10
|
+
const segments = pathname.split("/").filter(Boolean);
|
|
11
|
+
if (segments.length === 0) return [];
|
|
12
|
+
const username = segments[0];
|
|
13
|
+
if (isAnyOf(username, excludedPaths)) return [];
|
|
14
|
+
return [{ uri: `${origin}/user/avatar/${username}/512` }];
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
export { codebergHandler };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const require_utils = require("../../../common/utils.cjs");
|
|
2
|
+
const require_deviantart = require("../../../feeds/platform/handlers/deviantart.cjs");
|
|
3
|
+
//#region src/favicons/platform/handlers/deviantart.ts
|
|
4
|
+
const deviantartHandler = {
|
|
5
|
+
match: (url) => {
|
|
6
|
+
try {
|
|
7
|
+
const { pathname } = new URL(url);
|
|
8
|
+
const segments = pathname.split("/").filter(Boolean);
|
|
9
|
+
if (!require_utils.isHostOf(url, require_deviantart.hosts) || segments.length === 0) return false;
|
|
10
|
+
if (segments[0] === "tag") return false;
|
|
11
|
+
return !require_utils.isAnyOf(segments[0], require_deviantart.excludedPaths);
|
|
12
|
+
} catch {}
|
|
13
|
+
return false;
|
|
14
|
+
},
|
|
15
|
+
resolve: (url) => {
|
|
16
|
+
const { pathname } = new URL(url);
|
|
17
|
+
const segments = pathname.split("/").filter(Boolean);
|
|
18
|
+
if (segments.length === 0 || segments[0] === "tag") return [];
|
|
19
|
+
const username = segments[0].toLowerCase();
|
|
20
|
+
if (require_utils.isAnyOf(username, require_deviantart.excludedPaths) || username.length < 2) return [];
|
|
21
|
+
return [
|
|
22
|
+
`https://a.deviantart.net/avatars-big/${username[0]}/${username[1]}/${username}.jpg`,
|
|
23
|
+
`https://a.deviantart.net/avatars-big/${username[0]}/${username[1]}/${username}.gif`,
|
|
24
|
+
`https://a.deviantart.net/avatars-big/${username[0]}/${username[1]}/${username}.png`
|
|
25
|
+
].map((value) => ({ uri: value }));
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
//#endregion
|
|
29
|
+
exports.deviantartHandler = deviantartHandler;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { isAnyOf, isHostOf } from "../../../common/utils.js";
|
|
2
|
+
import { excludedPaths, hosts } from "../../../feeds/platform/handlers/deviantart.js";
|
|
3
|
+
//#region src/favicons/platform/handlers/deviantart.ts
|
|
4
|
+
const deviantartHandler = {
|
|
5
|
+
match: (url) => {
|
|
6
|
+
try {
|
|
7
|
+
const { pathname } = new URL(url);
|
|
8
|
+
const segments = pathname.split("/").filter(Boolean);
|
|
9
|
+
if (!isHostOf(url, hosts) || segments.length === 0) return false;
|
|
10
|
+
if (segments[0] === "tag") return false;
|
|
11
|
+
return !isAnyOf(segments[0], excludedPaths);
|
|
12
|
+
} catch {}
|
|
13
|
+
return false;
|
|
14
|
+
},
|
|
15
|
+
resolve: (url) => {
|
|
16
|
+
const { pathname } = new URL(url);
|
|
17
|
+
const segments = pathname.split("/").filter(Boolean);
|
|
18
|
+
if (segments.length === 0 || segments[0] === "tag") return [];
|
|
19
|
+
const username = segments[0].toLowerCase();
|
|
20
|
+
if (isAnyOf(username, excludedPaths) || username.length < 2) return [];
|
|
21
|
+
return [
|
|
22
|
+
`https://a.deviantart.net/avatars-big/${username[0]}/${username[1]}/${username}.jpg`,
|
|
23
|
+
`https://a.deviantart.net/avatars-big/${username[0]}/${username[1]}/${username}.gif`,
|
|
24
|
+
`https://a.deviantart.net/avatars-big/${username[0]}/${username[1]}/${username}.png`
|
|
25
|
+
].map((value) => ({ uri: value }));
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
//#endregion
|
|
29
|
+
export { deviantartHandler };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const require_utils = require("../../../common/utils.cjs");
|
|
2
|
+
const require_github = require("../../../feeds/platform/handlers/github.cjs");
|
|
3
|
+
//#region src/favicons/platform/handlers/github.ts
|
|
4
|
+
const githubHandler = {
|
|
5
|
+
match: (url) => {
|
|
6
|
+
return require_utils.isHostOf(url, require_github.hosts);
|
|
7
|
+
},
|
|
8
|
+
resolve: (url) => {
|
|
9
|
+
const { pathname } = new URL(url);
|
|
10
|
+
const segments = pathname.split("/").filter(Boolean);
|
|
11
|
+
if (segments.length === 0) return [];
|
|
12
|
+
const user = segments[0];
|
|
13
|
+
if (require_utils.isAnyOf(user, require_github.excludedPaths)) return [];
|
|
14
|
+
return [{ uri: `https://github.com/${user}.png` }];
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
exports.githubHandler = githubHandler;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { isAnyOf, isHostOf } from "../../../common/utils.js";
|
|
2
|
+
import { excludedPaths, hosts } from "../../../feeds/platform/handlers/github.js";
|
|
3
|
+
//#region src/favicons/platform/handlers/github.ts
|
|
4
|
+
const githubHandler = {
|
|
5
|
+
match: (url) => {
|
|
6
|
+
return isHostOf(url, hosts);
|
|
7
|
+
},
|
|
8
|
+
resolve: (url) => {
|
|
9
|
+
const { pathname } = new URL(url);
|
|
10
|
+
const segments = pathname.split("/").filter(Boolean);
|
|
11
|
+
if (segments.length === 0) return [];
|
|
12
|
+
const user = segments[0];
|
|
13
|
+
if (isAnyOf(user, excludedPaths)) return [];
|
|
14
|
+
return [{ uri: `https://github.com/${user}.png` }];
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
export { githubHandler };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const require_utils = require("../../../common/utils.cjs");
|
|
2
|
+
const require_githubGist = require("../../../feeds/platform/handlers/githubGist.cjs");
|
|
3
|
+
//#region src/favicons/platform/handlers/githubGist.ts
|
|
4
|
+
const githubGistHandler = {
|
|
5
|
+
match: (url) => {
|
|
6
|
+
return require_utils.isHostOf(url, require_githubGist.hosts);
|
|
7
|
+
},
|
|
8
|
+
resolve: (url) => {
|
|
9
|
+
const { pathname } = new URL(url);
|
|
10
|
+
const segments = pathname.split("/").filter(Boolean);
|
|
11
|
+
if (segments.length === 0) return [];
|
|
12
|
+
const user = segments[0];
|
|
13
|
+
if (require_utils.isAnyOf(user, require_githubGist.excludedPaths)) return [];
|
|
14
|
+
return [{ uri: `https://github.com/${user}.png` }];
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
//#endregion
|
|
18
|
+
exports.githubGistHandler = githubGistHandler;
|