feedscout 1.3.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 +46 -15
  2. package/dist/common/discover/index.js +47 -16
  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 +18 -4
  9. package/dist/common/types.d.ts +18 -4
  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 +18 -6
  20. package/dist/common/uris/index.js +18 -6
  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,10 +1,11 @@
1
+ const require_types = require('../types.cjs');
1
2
  const require_utils = require('../utils.cjs');
2
3
  const require_index = require('../uris/index.cjs');
3
4
  const require_utils$1 = require('./utils.cjs');
4
5
 
5
6
  //#region src/common/discover/index.ts
6
7
  const discover = async (input, options, defaults) => {
7
- const { methods, fetchFn, extractFn, normalizeUrlFn, concurrency = 3, stopOnFirstResult = false, includeInvalid = false, onProgress } = options;
8
+ const { methods, fetchFn, extractFn, normalizeUrlFn, stopOnFirstMethod = false, stopOnFirstResult = false, concurrency = 3, includeInvalid = false, onProgress } = options;
8
9
  const normalizedInput = await require_utils$1.normalizeInput(input, fetchFn);
9
10
  if (normalizedInput.content) {
10
11
  const result = await extractFn({
@@ -13,40 +14,70 @@ const discover = async (input, options, defaults) => {
13
14
  });
14
15
  if (result.isValid) return [result];
15
16
  }
16
- const rawUris = require_index.discoverUris(require_utils$1.normalizeMethodsConfig(normalizedInput, methods, defaults));
17
- const uris = [...new Set(rawUris.map((uri) => normalizeUrlFn(uri, normalizedInput.url)))];
17
+ const urisByMethod = require_index.discoverUris(require_utils$1.normalizeMethodsConfig(normalizedInput, methods, defaults));
18
+ const seen = /* @__PURE__ */ new Set();
19
+ const methodGroups = [];
20
+ for (const method of require_types.discoverMethodOrder) {
21
+ const rawUris = urisByMethod[method];
22
+ if (!rawUris?.length) continue;
23
+ const unique = rawUris.map((entry) => {
24
+ return require_utils$1.normalizeUriEntry(entry, normalizeUrlFn, normalizedInput.url);
25
+ }).filter((entry) => {
26
+ const key = typeof entry.uri === "string" ? entry.uri : entry.uri.join("\0");
27
+ if (seen.has(key)) return false;
28
+ seen.add(key);
29
+ return true;
30
+ });
31
+ if (unique.length > 0) methodGroups.push(unique);
32
+ }
33
+ const total = methodGroups.reduce((sum, group) => sum + group.length, 0);
18
34
  const results = [];
19
35
  let tested = 0;
20
36
  let found = 0;
21
- const processUri = async (url) => {
37
+ const fetchAndExtract = async (url) => {
22
38
  try {
23
39
  const fetchResult = await fetchFn(url);
24
- const extractResult = await extractFn({
40
+ return await extractFn({
25
41
  url: fetchResult.url,
26
42
  content: typeof fetchResult.body === "string" ? fetchResult.body : ""
27
43
  });
28
- results.push(extractResult);
29
- if (extractResult.isValid) found += 1;
30
44
  } catch (error) {
31
- results.push({
45
+ return {
32
46
  url,
33
47
  isValid: false,
34
48
  error
35
- });
36
- } finally {
49
+ };
50
+ }
51
+ };
52
+ const processUri = async (entry) => {
53
+ const alternatives = typeof entry.uri === "string" ? [entry.uri] : entry.uri;
54
+ for (const url of alternatives) {
55
+ const result = await fetchAndExtract(url);
56
+ results.push(entry.hint ? {
57
+ ...result,
58
+ hint: entry.hint
59
+ } : result);
37
60
  tested += 1;
61
+ if (result.isValid) found += 1;
38
62
  onProgress?.({
39
63
  tested,
40
- total: uris.length,
64
+ total,
41
65
  found,
42
66
  current: url
43
67
  });
68
+ if (result.isValid) break;
44
69
  }
45
70
  };
46
- await require_utils.processConcurrently(uris, processUri, {
47
- concurrency,
48
- shouldStop: () => stopOnFirstResult && found > 0
49
- });
71
+ for (const group of methodGroups) {
72
+ const foundBefore = found;
73
+ await require_utils.processConcurrently(group, processUri, {
74
+ concurrency,
75
+ shouldStop: () => {
76
+ return stopOnFirstResult && found > 0;
77
+ }
78
+ });
79
+ if (stopOnFirstMethod && found > foundBefore) break;
80
+ }
50
81
  return includeInvalid ? results : results.filter((result) => result.isValid);
51
82
  };
52
83
 
@@ -1,10 +1,11 @@
1
+ import { discoverMethodOrder } from "../types.js";
1
2
  import { processConcurrently } from "../utils.js";
2
3
  import { discoverUris } from "../uris/index.js";
3
- import { normalizeInput, normalizeMethodsConfig } from "./utils.js";
4
+ import { normalizeInput, normalizeMethodsConfig, normalizeUriEntry } from "./utils.js";
4
5
 
5
6
  //#region src/common/discover/index.ts
6
7
  const discover = async (input, options, defaults) => {
7
- const { methods, fetchFn, extractFn, normalizeUrlFn, concurrency = 3, stopOnFirstResult = false, includeInvalid = false, onProgress } = options;
8
+ const { methods, fetchFn, extractFn, normalizeUrlFn, stopOnFirstMethod = false, stopOnFirstResult = false, concurrency = 3, includeInvalid = false, onProgress } = options;
8
9
  const normalizedInput = await normalizeInput(input, fetchFn);
9
10
  if (normalizedInput.content) {
10
11
  const result = await extractFn({
@@ -13,40 +14,70 @@ const discover = async (input, options, defaults) => {
13
14
  });
14
15
  if (result.isValid) return [result];
15
16
  }
16
- const rawUris = discoverUris(normalizeMethodsConfig(normalizedInput, methods, defaults));
17
- const uris = [...new Set(rawUris.map((uri) => normalizeUrlFn(uri, normalizedInput.url)))];
17
+ const urisByMethod = discoverUris(normalizeMethodsConfig(normalizedInput, methods, defaults));
18
+ const seen = /* @__PURE__ */ new Set();
19
+ const methodGroups = [];
20
+ for (const method of discoverMethodOrder) {
21
+ const rawUris = urisByMethod[method];
22
+ if (!rawUris?.length) continue;
23
+ const unique = rawUris.map((entry) => {
24
+ return normalizeUriEntry(entry, normalizeUrlFn, normalizedInput.url);
25
+ }).filter((entry) => {
26
+ const key = typeof entry.uri === "string" ? entry.uri : entry.uri.join("\0");
27
+ if (seen.has(key)) return false;
28
+ seen.add(key);
29
+ return true;
30
+ });
31
+ if (unique.length > 0) methodGroups.push(unique);
32
+ }
33
+ const total = methodGroups.reduce((sum, group) => sum + group.length, 0);
18
34
  const results = [];
19
35
  let tested = 0;
20
36
  let found = 0;
21
- const processUri = async (url) => {
37
+ const fetchAndExtract = async (url) => {
22
38
  try {
23
39
  const fetchResult = await fetchFn(url);
24
- const extractResult = await extractFn({
40
+ return await extractFn({
25
41
  url: fetchResult.url,
26
42
  content: typeof fetchResult.body === "string" ? fetchResult.body : ""
27
43
  });
28
- results.push(extractResult);
29
- if (extractResult.isValid) found += 1;
30
44
  } catch (error) {
31
- results.push({
45
+ return {
32
46
  url,
33
47
  isValid: false,
34
48
  error
35
- });
36
- } finally {
49
+ };
50
+ }
51
+ };
52
+ const processUri = async (entry) => {
53
+ const alternatives = typeof entry.uri === "string" ? [entry.uri] : entry.uri;
54
+ for (const url of alternatives) {
55
+ const result = await fetchAndExtract(url);
56
+ results.push(entry.hint ? {
57
+ ...result,
58
+ hint: entry.hint
59
+ } : result);
37
60
  tested += 1;
61
+ if (result.isValid) found += 1;
38
62
  onProgress?.({
39
63
  tested,
40
- total: uris.length,
64
+ total,
41
65
  found,
42
66
  current: url
43
67
  });
68
+ if (result.isValid) break;
44
69
  }
45
70
  };
46
- await processConcurrently(uris, processUri, {
47
- concurrency,
48
- shouldStop: () => stopOnFirstResult && found > 0
49
- });
71
+ for (const group of methodGroups) {
72
+ const foundBefore = found;
73
+ await processConcurrently(group, processUri, {
74
+ concurrency,
75
+ shouldStop: () => {
76
+ return stopOnFirstResult && found > 0;
77
+ }
78
+ });
79
+ if (stopOnFirstMethod && found > foundBefore) break;
80
+ }
50
81
  return includeInvalid ? results : results.filter((result) => result.isValid);
51
82
  };
52
83
 
@@ -23,6 +23,16 @@ const normalizeInput = async (input, fetchFn) => {
23
23
  headers: response.headers
24
24
  };
25
25
  };
26
+ const normalizeUriEntry = (entry, normalizeUrlFn, baseUrl) => {
27
+ if (typeof entry.uri === "string") return {
28
+ ...entry,
29
+ uri: normalizeUrlFn(entry.uri, baseUrl)
30
+ };
31
+ return {
32
+ ...entry,
33
+ uri: entry.uri.map((uri) => normalizeUrlFn(uri, baseUrl))
34
+ };
35
+ };
26
36
  const normalizeMethodsConfig = (input, methods, defaults) => {
27
37
  const methodsObj = Array.isArray(methods) ? Object.fromEntries(methods.map((method) => [method, true])) : methods;
28
38
  const methodsConfig = {};
@@ -77,4 +87,5 @@ const normalizeMethodsConfig = (input, methods, defaults) => {
77
87
  //#endregion
78
88
  exports.defaultFetchFn = defaultFetchFn;
79
89
  exports.normalizeInput = normalizeInput;
80
- exports.normalizeMethodsConfig = normalizeMethodsConfig;
90
+ exports.normalizeMethodsConfig = normalizeMethodsConfig;
91
+ exports.normalizeUriEntry = normalizeUriEntry;
@@ -23,6 +23,16 @@ const normalizeInput = async (input, fetchFn) => {
23
23
  headers: response.headers
24
24
  };
25
25
  };
26
+ const normalizeUriEntry = (entry, normalizeUrlFn, baseUrl) => {
27
+ if (typeof entry.uri === "string") return {
28
+ ...entry,
29
+ uri: normalizeUrlFn(entry.uri, baseUrl)
30
+ };
31
+ return {
32
+ ...entry,
33
+ uri: entry.uri.map((uri) => normalizeUrlFn(uri, baseUrl))
34
+ };
35
+ };
26
36
  const normalizeMethodsConfig = (input, methods, defaults) => {
27
37
  const methodsObj = Array.isArray(methods) ? Object.fromEntries(methods.map((method) => [method, true])) : methods;
28
38
  const methodsConfig = {};
@@ -75,4 +85,4 @@ const normalizeMethodsConfig = (input, methods, defaults) => {
75
85
  };
76
86
 
77
87
  //#endregion
78
- export { defaultFetchFn, normalizeInput, normalizeMethodsConfig };
88
+ export { defaultFetchFn, normalizeInput, normalizeMethodsConfig, normalizeUriEntry };
@@ -6,6 +6,75 @@ var errors = {
6
6
  "headersMethodRequiresHeaders": "Headers method requires headers to be provided in input",
7
7
  "guessMethodRequiresUrl": "Guess method requires url to be provided in input"
8
8
  };
9
+ var hints = {
10
+ "youtube:all": "All uploads",
11
+ "youtube:videos": "Videos only",
12
+ "youtube:shorts": "Shorts only",
13
+ "youtube:playlist": "Playlist",
14
+ "github:activity": "Activity",
15
+ "github:releases": "Releases",
16
+ "github:commits": "Commits",
17
+ "github:tags": "Tags",
18
+ "github:wiki": "Wiki",
19
+ "github:discussions": "Discussions",
20
+ "github:branch-commits": "Branch commits",
21
+ "github:file-history": "File history",
22
+ "reddit:posts": "Posts",
23
+ "reddit:post-comments": "Post comments",
24
+ "reddit:comments": "Comments",
25
+ "reddit:multireddit": "Multireddit",
26
+ "gitlab:activity": "Activity",
27
+ "gitlab:releases": "Releases",
28
+ "gitlab:tags": "Tags",
29
+ "wordpress:category": "Category",
30
+ "wordpress:tag": "Tag",
31
+ "wordpress:author": "Author",
32
+ "wordpress:posts-rss2": "Posts (RSS 2.0)",
33
+ "wordpress:posts-rss2-alt": "Posts (RSS 2.0)",
34
+ "wordpress:posts-rdf": "Posts (RDF)",
35
+ "wordpress:posts-atom": "Posts (Atom)",
36
+ "wordpress:comments": "Comments",
37
+ "wordpress:comments-rss2": "Comments (RSS 2.0)",
38
+ "wordpress:comments-rdf": "Comments (RDF)",
39
+ "wordpress:comments-atom": "Comments (Atom)",
40
+ "blogspot:label": "Label",
41
+ "blogspot:posts-atom": "Posts (Atom)",
42
+ "blogspot:posts-rss": "Posts (RSS)",
43
+ "behance:portfolio": "Portfolio",
44
+ "behance:appreciated": "Appreciated",
45
+ "bluesky:posts": "Posts",
46
+ "dailymotion:videos": "Videos",
47
+ "dailymotion:playlist": "Playlist",
48
+ "deviantart:tag": "Tag",
49
+ "deviantart:favorites": "Favorites",
50
+ "deviantart:gallery": "Gallery",
51
+ "deviantart:deviations": "Deviations",
52
+ "devto:posts": "Posts",
53
+ "devto:tag": "Tag",
54
+ "github-gist:gists": "Gists",
55
+ "github-gist:starred": "Starred",
56
+ "kickstarter:updates": "Updates",
57
+ "kickstarter:projects": "Projects",
58
+ "lobsters:tag": "Tag",
59
+ "lobsters:domain": "Domain",
60
+ "lobsters:stories": "Stories",
61
+ "lobsters:top": "Top stories",
62
+ "lobsters:newest": "Newest",
63
+ "lobsters:comments": "Comments",
64
+ "medium:posts": "Posts",
65
+ "medium:tag": "Tag",
66
+ "medium:tagged": "Tagged",
67
+ "medium:publication": "Publication",
68
+ "pinterest:pins": "Pins",
69
+ "pinterest:board": "Board",
70
+ "producthunt:topic": "Topic",
71
+ "producthunt:category": "Category",
72
+ "producthunt:products": "Products",
73
+ "soundcloud:tracks": "Tracks",
74
+ "substack:newsletter": "Newsletter",
75
+ "tumblr:posts": "Posts",
76
+ "tumblr:tag": "Tag"
77
+ };
9
78
 
10
79
  //#endregion
11
80
  Object.defineProperty(exports, 'errors', {
@@ -13,4 +82,10 @@ Object.defineProperty(exports, 'errors', {
13
82
  get: function () {
14
83
  return errors;
15
84
  }
85
+ });
86
+ Object.defineProperty(exports, 'hints', {
87
+ enumerable: true,
88
+ get: function () {
89
+ return hints;
90
+ }
16
91
  });
@@ -5,6 +5,75 @@ var errors = {
5
5
  "headersMethodRequiresHeaders": "Headers method requires headers to be provided in input",
6
6
  "guessMethodRequiresUrl": "Guess method requires url to be provided in input"
7
7
  };
8
+ var hints = {
9
+ "youtube:all": "All uploads",
10
+ "youtube:videos": "Videos only",
11
+ "youtube:shorts": "Shorts only",
12
+ "youtube:playlist": "Playlist",
13
+ "github:activity": "Activity",
14
+ "github:releases": "Releases",
15
+ "github:commits": "Commits",
16
+ "github:tags": "Tags",
17
+ "github:wiki": "Wiki",
18
+ "github:discussions": "Discussions",
19
+ "github:branch-commits": "Branch commits",
20
+ "github:file-history": "File history",
21
+ "reddit:posts": "Posts",
22
+ "reddit:post-comments": "Post comments",
23
+ "reddit:comments": "Comments",
24
+ "reddit:multireddit": "Multireddit",
25
+ "gitlab:activity": "Activity",
26
+ "gitlab:releases": "Releases",
27
+ "gitlab:tags": "Tags",
28
+ "wordpress:category": "Category",
29
+ "wordpress:tag": "Tag",
30
+ "wordpress:author": "Author",
31
+ "wordpress:posts-rss2": "Posts (RSS 2.0)",
32
+ "wordpress:posts-rss2-alt": "Posts (RSS 2.0)",
33
+ "wordpress:posts-rdf": "Posts (RDF)",
34
+ "wordpress:posts-atom": "Posts (Atom)",
35
+ "wordpress:comments": "Comments",
36
+ "wordpress:comments-rss2": "Comments (RSS 2.0)",
37
+ "wordpress:comments-rdf": "Comments (RDF)",
38
+ "wordpress:comments-atom": "Comments (Atom)",
39
+ "blogspot:label": "Label",
40
+ "blogspot:posts-atom": "Posts (Atom)",
41
+ "blogspot:posts-rss": "Posts (RSS)",
42
+ "behance:portfolio": "Portfolio",
43
+ "behance:appreciated": "Appreciated",
44
+ "bluesky:posts": "Posts",
45
+ "dailymotion:videos": "Videos",
46
+ "dailymotion:playlist": "Playlist",
47
+ "deviantart:tag": "Tag",
48
+ "deviantart:favorites": "Favorites",
49
+ "deviantart:gallery": "Gallery",
50
+ "deviantart:deviations": "Deviations",
51
+ "devto:posts": "Posts",
52
+ "devto:tag": "Tag",
53
+ "github-gist:gists": "Gists",
54
+ "github-gist:starred": "Starred",
55
+ "kickstarter:updates": "Updates",
56
+ "kickstarter:projects": "Projects",
57
+ "lobsters:tag": "Tag",
58
+ "lobsters:domain": "Domain",
59
+ "lobsters:stories": "Stories",
60
+ "lobsters:top": "Top stories",
61
+ "lobsters:newest": "Newest",
62
+ "lobsters:comments": "Comments",
63
+ "medium:posts": "Posts",
64
+ "medium:tag": "Tag",
65
+ "medium:tagged": "Tagged",
66
+ "medium:publication": "Publication",
67
+ "pinterest:pins": "Pins",
68
+ "pinterest:board": "Board",
69
+ "producthunt:topic": "Topic",
70
+ "producthunt:category": "Category",
71
+ "producthunt:products": "Products",
72
+ "soundcloud:tracks": "Tracks",
73
+ "substack:newsletter": "Newsletter",
74
+ "tumblr:posts": "Posts",
75
+ "tumblr:tag": "Tag"
76
+ };
8
77
 
9
78
  //#endregion
10
- export { errors };
79
+ export { errors, hints };
@@ -0,0 +1,11 @@
1
+
2
+ //#region src/common/types.ts
3
+ const discoverMethodOrder = [
4
+ "platform",
5
+ "html",
6
+ "headers",
7
+ "guess"
8
+ ];
9
+
10
+ //#endregion
11
+ exports.discoverMethodOrder = discoverMethodOrder;
@@ -4,6 +4,17 @@ import { HtmlMethodOptions } from "./uris/html/types.cjs";
4
4
  import { PlatformMethodOptions } from "./uris/platform/types.cjs";
5
5
 
6
6
  //#region src/common/types.d.ts
7
+ type UriEntry = string | Array<string>;
8
+ type DiscoverUriHint = {
9
+ key: string;
10
+ label: string;
11
+ };
12
+ type DiscoverUriEntry = {
13
+ uri: UriEntry;
14
+ hint?: DiscoverUriHint;
15
+ };
16
+ declare const discoverMethodOrder: readonly ["platform", "html", "headers", "guess"];
17
+ type DiscoverMethod = (typeof discoverMethodOrder)[number];
7
18
  type LinkSelector = {
8
19
  rel: string;
9
20
  types?: Array<string>;
@@ -31,9 +42,11 @@ type DiscoverOnProgressFn = (progress: DiscoverProgress) => void;
31
42
  type DiscoverResult<TValid = object> = ({
32
43
  url: string;
33
44
  isValid: true;
45
+ hint?: DiscoverUriHint;
34
46
  } & TValid) | {
35
47
  url: string;
36
48
  isValid: false;
49
+ hint?: DiscoverUriHint;
37
50
  error?: unknown;
38
51
  };
39
52
  type DiscoverExtractFn<TValid> = (input: {
@@ -47,7 +60,7 @@ type DiscoverInputObject = {
47
60
  headers?: Headers;
48
61
  };
49
62
  type DiscoverInput = string | DiscoverInputObject;
50
- type DiscoverMethodsConfig = Array<'platform' | 'html' | 'headers' | 'guess'> | {
63
+ type DiscoverMethodsConfig = Array<DiscoverMethod> | {
51
64
  platform?: true | Partial<PlatformMethodOptions>;
52
65
  html?: true | Partial<Omit<HtmlMethodOptions, 'baseUrl'>>;
53
66
  headers?: true | Partial<Omit<HeadersMethodOptions, 'baseUrl'>>;
@@ -58,10 +71,11 @@ type DiscoverOptions<TValid> = {
58
71
  fetchFn?: DiscoverFetchFn;
59
72
  extractFn?: DiscoverExtractFn<TValid>;
60
73
  normalizeUrlFn?: DiscoverNormalizeUrlFn;
61
- concurrency?: number;
74
+ stopOnFirstMethod?: boolean;
62
75
  stopOnFirstResult?: boolean;
63
- includeInvalid?: boolean;
76
+ concurrency?: number;
64
77
  onProgress?: DiscoverOnProgressFn;
78
+ includeInvalid?: boolean;
65
79
  };
66
80
  //#endregion
67
- export { DiscoverExtractFn, DiscoverFetchFn, DiscoverFetchFnOptions, DiscoverFetchFnResponse, DiscoverInput, DiscoverInputObject, DiscoverMethodsConfig, DiscoverNormalizeUrlFn, DiscoverOnProgressFn, DiscoverOptions, DiscoverProgress, DiscoverResult, LinkSelector };
81
+ export { DiscoverExtractFn, DiscoverFetchFn, DiscoverFetchFnOptions, DiscoverFetchFnResponse, DiscoverInput, DiscoverInputObject, DiscoverMethodsConfig, DiscoverNormalizeUrlFn, DiscoverOnProgressFn, DiscoverOptions, DiscoverProgress, DiscoverResult, DiscoverUriEntry, DiscoverUriHint, LinkSelector, UriEntry };
@@ -4,6 +4,17 @@ import { HtmlMethodOptions } from "./uris/html/types.js";
4
4
  import { PlatformMethodOptions } from "./uris/platform/types.js";
5
5
 
6
6
  //#region src/common/types.d.ts
7
+ type UriEntry = string | Array<string>;
8
+ type DiscoverUriHint = {
9
+ key: string;
10
+ label: string;
11
+ };
12
+ type DiscoverUriEntry = {
13
+ uri: UriEntry;
14
+ hint?: DiscoverUriHint;
15
+ };
16
+ declare const discoverMethodOrder: readonly ["platform", "html", "headers", "guess"];
17
+ type DiscoverMethod = (typeof discoverMethodOrder)[number];
7
18
  type LinkSelector = {
8
19
  rel: string;
9
20
  types?: Array<string>;
@@ -31,9 +42,11 @@ type DiscoverOnProgressFn = (progress: DiscoverProgress) => void;
31
42
  type DiscoverResult<TValid = object> = ({
32
43
  url: string;
33
44
  isValid: true;
45
+ hint?: DiscoverUriHint;
34
46
  } & TValid) | {
35
47
  url: string;
36
48
  isValid: false;
49
+ hint?: DiscoverUriHint;
37
50
  error?: unknown;
38
51
  };
39
52
  type DiscoverExtractFn<TValid> = (input: {
@@ -47,7 +60,7 @@ type DiscoverInputObject = {
47
60
  headers?: Headers;
48
61
  };
49
62
  type DiscoverInput = string | DiscoverInputObject;
50
- type DiscoverMethodsConfig = Array<'platform' | 'html' | 'headers' | 'guess'> | {
63
+ type DiscoverMethodsConfig = Array<DiscoverMethod> | {
51
64
  platform?: true | Partial<PlatformMethodOptions>;
52
65
  html?: true | Partial<Omit<HtmlMethodOptions, 'baseUrl'>>;
53
66
  headers?: true | Partial<Omit<HeadersMethodOptions, 'baseUrl'>>;
@@ -58,10 +71,11 @@ type DiscoverOptions<TValid> = {
58
71
  fetchFn?: DiscoverFetchFn;
59
72
  extractFn?: DiscoverExtractFn<TValid>;
60
73
  normalizeUrlFn?: DiscoverNormalizeUrlFn;
61
- concurrency?: number;
74
+ stopOnFirstMethod?: boolean;
62
75
  stopOnFirstResult?: boolean;
63
- includeInvalid?: boolean;
76
+ concurrency?: number;
64
77
  onProgress?: DiscoverOnProgressFn;
78
+ includeInvalid?: boolean;
65
79
  };
66
80
  //#endregion
67
- export { DiscoverExtractFn, DiscoverFetchFn, DiscoverFetchFnOptions, DiscoverFetchFnResponse, DiscoverInput, DiscoverInputObject, DiscoverMethodsConfig, DiscoverNormalizeUrlFn, DiscoverOnProgressFn, DiscoverOptions, DiscoverProgress, DiscoverResult, LinkSelector };
81
+ export { DiscoverExtractFn, DiscoverFetchFn, DiscoverFetchFnOptions, DiscoverFetchFnResponse, DiscoverInput, DiscoverInputObject, DiscoverMethodsConfig, DiscoverNormalizeUrlFn, DiscoverOnProgressFn, DiscoverOptions, DiscoverProgress, DiscoverResult, DiscoverUriEntry, DiscoverUriHint, LinkSelector, UriEntry };
@@ -0,0 +1,10 @@
1
+ //#region src/common/types.ts
2
+ const discoverMethodOrder = [
3
+ "platform",
4
+ "html",
5
+ "headers",
6
+ "guess"
7
+ ];
8
+
9
+ //#endregion
10
+ export { discoverMethodOrder };
@@ -1,6 +1,7 @@
1
1
  import { GuessMethodOptions } from "./types.cjs";
2
+ import { UriEntry } from "../../types.cjs";
2
3
 
3
4
  //#region src/common/uris/guess/index.d.ts
4
- declare const discoverUrisFromGuess: (options: GuessMethodOptions) => Array<string>;
5
+ declare const discoverUrisFromGuess: (options: GuessMethodOptions) => Array<UriEntry>;
5
6
  //#endregion
6
7
  export { discoverUrisFromGuess };
@@ -1,6 +1,7 @@
1
1
  import { GuessMethodOptions } from "./types.js";
2
+ import { UriEntry } from "../../types.js";
2
3
 
3
4
  //#region src/common/uris/guess/index.d.ts
4
- declare const discoverUrisFromGuess: (options: GuessMethodOptions) => Array<string>;
5
+ declare const discoverUrisFromGuess: (options: GuessMethodOptions) => Array<UriEntry>;
5
6
  //#endregion
6
7
  export { discoverUrisFromGuess };
@@ -1,7 +1,9 @@
1
+ import { UriEntry } from "../../types.cjs";
2
+
1
3
  //#region src/common/uris/guess/types.d.ts
2
4
  type GuessMethodOptions = {
3
5
  baseUrl: string;
4
- uris: Array<string>;
6
+ uris: Array<UriEntry>;
5
7
  additionalBaseUrls?: Array<string>;
6
8
  };
7
9
  //#endregion
@@ -1,7 +1,9 @@
1
+ import { UriEntry } from "../../types.js";
2
+
1
3
  //#region src/common/uris/guess/types.d.ts
2
4
  type GuessMethodOptions = {
3
5
  baseUrl: string;
4
- uris: Array<string>;
6
+ uris: Array<UriEntry>;
5
7
  additionalBaseUrls?: Array<string>;
6
8
  };
7
9
  //#endregion
@@ -3,7 +3,10 @@
3
3
  const generateUrlCombinations = (baseUrls, uris) => {
4
4
  return baseUrls.flatMap((base) => {
5
5
  return uris.map((uri) => {
6
- return new URL(uri, base).toString();
6
+ if (typeof uri === "string") return new URL(uri, base).toString();
7
+ return uri.map((alternative) => {
8
+ return new URL(alternative, base).toString();
9
+ });
7
10
  });
8
11
  });
9
12
  };
@@ -1,5 +1,7 @@
1
+ import { UriEntry } from "../../types.cjs";
2
+
1
3
  //#region src/common/uris/guess/utils.d.ts
2
- declare const generateUrlCombinations: (baseUrls: Array<string>, uris: Array<string>) => Array<string>;
4
+ declare const generateUrlCombinations: (baseUrls: Array<string>, uris: Array<UriEntry>) => Array<UriEntry>;
3
5
  declare const getWwwCounterpart: (baseUrl: string) => string;
4
6
  declare const getSubdomainVariants: (baseUrl: string, prefixes: Array<string>) => Array<string>;
5
7
  //#endregion
@@ -1,5 +1,7 @@
1
+ import { UriEntry } from "../../types.js";
2
+
1
3
  //#region src/common/uris/guess/utils.d.ts
2
- declare const generateUrlCombinations: (baseUrls: Array<string>, uris: Array<string>) => Array<string>;
4
+ declare const generateUrlCombinations: (baseUrls: Array<string>, uris: Array<UriEntry>) => Array<UriEntry>;
3
5
  declare const getWwwCounterpart: (baseUrl: string) => string;
4
6
  declare const getSubdomainVariants: (baseUrl: string, prefixes: Array<string>) => Array<string>;
5
7
  //#endregion
@@ -2,7 +2,10 @@
2
2
  const generateUrlCombinations = (baseUrls, uris) => {
3
3
  return baseUrls.flatMap((base) => {
4
4
  return uris.map((uri) => {
5
- return new URL(uri, base).toString();
5
+ if (typeof uri === "string") return new URL(uri, base).toString();
6
+ return uri.map((alternative) => {
7
+ return new URL(alternative, base).toString();
8
+ });
6
9
  });
7
10
  });
8
11
  };
@@ -5,12 +5,24 @@ const require_index$3 = require('./platform/index.cjs');
5
5
 
6
6
  //#region src/common/uris/index.ts
7
7
  const discoverUris = (config) => {
8
- const uris = /* @__PURE__ */ new Set();
9
- if (config.platform) for (const uri of require_index$3.discoverUrisFromPlatform(config.platform.html, config.platform.options)) uris.add(uri);
10
- if (config.html) for (const uri of require_index$2.discoverUrisFromHtml(config.html.html, config.html.options)) uris.add(uri);
11
- if (config.headers) for (const uri of require_index$1.discoverUrisFromHeaders(config.headers.headers, config.headers.options)) uris.add(uri);
12
- if (config.guess) for (const uri of require_index.discoverUrisFromGuess(config.guess.options)) uris.add(uri);
13
- return Array.from(uris);
8
+ const result = {};
9
+ if (config.platform) {
10
+ const uris = require_index$3.discoverUrisFromPlatform(config.platform.html, config.platform.options);
11
+ if (uris.length > 0) result.platform = uris;
12
+ }
13
+ if (config.html) {
14
+ const uris = require_index$2.discoverUrisFromHtml(config.html.html, config.html.options);
15
+ if (uris.length > 0) result.html = uris.map((uri) => ({ uri }));
16
+ }
17
+ if (config.headers) {
18
+ const uris = require_index$1.discoverUrisFromHeaders(config.headers.headers, config.headers.options);
19
+ if (uris.length > 0) result.headers = uris.map((uri) => ({ uri }));
20
+ }
21
+ if (config.guess) {
22
+ const uris = require_index.discoverUrisFromGuess(config.guess.options);
23
+ if (uris.length > 0) result.guess = uris.map((uri) => ({ uri }));
24
+ }
25
+ return result;
14
26
  };
15
27
 
16
28
  //#endregion