feedscout 2.0.0-next.2 → 2.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/README.md +1 -1
  2. package/dist/blogrolls.d.ts +4 -4
  3. package/dist/blogrolls.js +3 -3
  4. package/dist/favicons.d.ts +3 -3
  5. package/dist/favicons.js +2 -2
  6. package/dist/feeds.d.ts +4 -4
  7. package/dist/feeds.js +3 -3
  8. package/dist/hubs.d.ts +1 -1
  9. package/dist/index.d.ts +7 -7
  10. package/dist/index.js +6 -6
  11. package/dist/methods.d.ts +6 -6
  12. package/dist/methods.js +6 -6
  13. package/dist/node_modules/trousse/dist/arrays.js +9 -0
  14. package/dist/node_modules/trousse/dist/is.js +19 -0
  15. package/dist/node_modules/trousse/dist/matching.js +37 -0
  16. package/dist/node_modules/trousse/dist/urls.js +20 -0
  17. package/dist/{blogrolls → src/blogrolls}/defaults.d.ts +1 -2
  18. package/dist/{blogrolls → src/blogrolls}/defaults.js +19 -11
  19. package/dist/{blogrolls → src/blogrolls}/extractors.js +3 -2
  20. package/dist/{common → src/common}/discover/defaults.js +1 -3
  21. package/dist/{common → src/common}/discover/index.js +23 -10
  22. package/dist/{common → src/common}/discover/utils.js +9 -3
  23. package/dist/src/common/locales.js +337 -0
  24. package/dist/{common → src/common}/types.d.ts +9 -1
  25. package/dist/{common → src/common}/uris/feed/index.js +1 -1
  26. package/dist/src/common/uris/headers/index.js +14 -0
  27. package/dist/{common → src/common}/uris/html/handlers.js +18 -1
  28. package/dist/{common → src/common}/uris/html/index.js +17 -1
  29. package/dist/src/common/uris/html/types.d.ts +14 -0
  30. package/dist/src/common/utils.js +51 -0
  31. package/dist/{favicons → src/favicons}/defaults.js +1 -1
  32. package/dist/{favicons → src/favicons}/extractors.js +3 -8
  33. package/dist/{favicons → src/favicons}/platform/handlers/bluesky.js +3 -2
  34. package/dist/{favicons → src/favicons}/platform/handlers/codeberg.js +2 -1
  35. package/dist/{favicons → src/favicons}/platform/handlers/deviantart.js +2 -1
  36. package/dist/{favicons → src/favicons}/platform/handlers/devto.js +4 -2
  37. package/dist/{favicons → src/favicons}/platform/handlers/github.js +2 -1
  38. package/dist/{favicons → src/favicons}/platform/handlers/githubGist.js +2 -1
  39. package/dist/{favicons → src/favicons}/platform/handlers/gitlab.js +4 -2
  40. package/dist/{favicons → src/favicons}/platform/handlers/lobsters.js +1 -1
  41. package/dist/{favicons → src/favicons}/platform/handlers/mastodon.js +2 -1
  42. package/dist/{favicons → src/favicons}/platform/handlers/reddit.js +3 -2
  43. package/dist/{favicons → src/favicons}/platform/handlers/sourceforge.js +1 -1
  44. package/dist/{favicons → src/favicons}/platform/handlers/tumblr.js +1 -1
  45. package/dist/{favicons → src/favicons}/utils.js +1 -4
  46. package/dist/{feeds → src/feeds}/defaults.d.ts +5 -3
  47. package/dist/{feeds → src/feeds}/defaults.js +128 -11
  48. package/dist/{feeds → src/feeds}/extractors.js +3 -2
  49. package/dist/src/feeds/platform/handlers/acast.js +28 -0
  50. package/dist/src/feeds/platform/handlers/ameblo.js +38 -0
  51. package/dist/{feeds → src/feeds}/platform/handlers/applePodcasts.js +3 -2
  52. package/dist/src/feeds/platform/handlers/arena.js +44 -0
  53. package/dist/src/feeds/platform/handlers/artstation.js +54 -0
  54. package/dist/src/feeds/platform/handlers/audioboom.js +24 -0
  55. package/dist/src/feeds/platform/handlers/bearblog.js +46 -0
  56. package/dist/{feeds → src/feeds}/platform/handlers/behance.js +10 -1
  57. package/dist/src/feeds/platform/handlers/blogspot.js +72 -0
  58. package/dist/{feeds → src/feeds}/platform/handlers/bluesky.js +2 -1
  59. package/dist/src/feeds/platform/handlers/bookwyrm.js +48 -0
  60. package/dist/src/feeds/platform/handlers/buttondown.js +45 -0
  61. package/dist/src/feeds/platform/handlers/buzzsprout.js +23 -0
  62. package/dist/{feeds → src/feeds}/platform/handlers/codeberg.js +8 -6
  63. package/dist/{feeds → src/feeds}/platform/handlers/csdn.js +2 -1
  64. package/dist/{feeds → src/feeds}/platform/handlers/dailymotion.js +19 -1
  65. package/dist/{feeds → src/feeds}/platform/handlers/deviantart.js +28 -7
  66. package/dist/{feeds → src/feeds}/platform/handlers/devto.js +11 -1
  67. package/dist/src/feeds/platform/handlers/discourse.js +66 -0
  68. package/dist/{feeds → src/feeds}/platform/handlers/douban.js +2 -1
  69. package/dist/src/feeds/platform/handlers/dreamwidth.js +49 -0
  70. package/dist/src/feeds/platform/handlers/exblog.js +36 -0
  71. package/dist/src/feeds/platform/handlers/fireside.js +25 -0
  72. package/dist/src/feeds/platform/handlers/friendica.js +44 -0
  73. package/dist/src/feeds/platform/handlers/ghost.js +31 -0
  74. package/dist/{feeds → src/feeds}/platform/handlers/github.js +9 -1
  75. package/dist/{feeds → src/feeds}/platform/handlers/githubGist.js +19 -6
  76. package/dist/{feeds → src/feeds}/platform/handlers/gitlab.js +34 -14
  77. package/dist/{feeds → src/feeds}/platform/handlers/goodreads.js +20 -9
  78. package/dist/src/feeds/platform/handlers/hackernews.js +22 -0
  79. package/dist/{feeds → src/feeds}/platform/handlers/hashnode.js +3 -2
  80. package/dist/{feeds → src/feeds}/platform/handlers/hatenablog.js +6 -2
  81. package/dist/src/feeds/platform/handlers/hearthis.js +34 -0
  82. package/dist/src/feeds/platform/handlers/heyWorld.js +19 -0
  83. package/dist/src/feeds/platform/handlers/insanejournal.js +70 -0
  84. package/dist/{feeds → src/feeds}/platform/handlers/itchio.js +27 -2
  85. package/dist/{feeds → src/feeds}/platform/handlers/kickstarter.js +2 -1
  86. package/dist/src/feeds/platform/handlers/lemmy.js +88 -0
  87. package/dist/{feeds → src/feeds}/platform/handlers/letterboxd.js +7 -1
  88. package/dist/src/feeds/platform/handlers/libsyn.js +26 -0
  89. package/dist/src/feeds/platform/handlers/listed.js +21 -0
  90. package/dist/src/feeds/platform/handlers/livejournal.js +69 -0
  91. package/dist/{feeds → src/feeds}/platform/handlers/lobsters.js +2 -1
  92. package/dist/{feeds → src/feeds}/platform/handlers/mastodon.js +32 -0
  93. package/dist/src/feeds/platform/handlers/mataroa.js +17 -0
  94. package/dist/{feeds → src/feeds}/platform/handlers/medium.js +5 -3
  95. package/dist/src/feeds/platform/handlers/microblog.js +56 -0
  96. package/dist/src/feeds/platform/handlers/misskey.js +40 -0
  97. package/dist/src/feeds/platform/handlers/myanimelist.js +44 -0
  98. package/dist/src/feeds/platform/handlers/naverBlog.js +22 -0
  99. package/dist/src/feeds/platform/handlers/nebula.js +70 -0
  100. package/dist/src/feeds/platform/handlers/note.js +55 -0
  101. package/dist/src/feeds/platform/handlers/observable.js +35 -0
  102. package/dist/src/feeds/platform/handlers/odysee.js +21 -0
  103. package/dist/src/feeds/platform/handlers/pagecord.js +17 -0
  104. package/dist/{feeds → src/feeds}/platform/handlers/paragraph.js +3 -3
  105. package/dist/src/feeds/platform/handlers/pika.js +36 -0
  106. package/dist/{feeds → src/feeds}/platform/handlers/pinterest.js +16 -1
  107. package/dist/src/feeds/platform/handlers/pixelfed.js +46 -0
  108. package/dist/src/feeds/platform/handlers/pleroma.js +34 -0
  109. package/dist/src/feeds/platform/handlers/podbean.js +30 -0
  110. package/dist/src/feeds/platform/handlers/podigee.js +30 -0
  111. package/dist/src/feeds/platform/handlers/posthaven.js +25 -0
  112. package/dist/{feeds → src/feeds}/platform/handlers/producthunt.js +2 -1
  113. package/dist/src/feeds/platform/handlers/prose.js +27 -0
  114. package/dist/src/feeds/platform/handlers/qiita.js +60 -0
  115. package/dist/src/feeds/platform/handlers/reddit.js +150 -0
  116. package/dist/src/feeds/platform/handlers/rssCom.js +21 -0
  117. package/dist/src/feeds/platform/handlers/seesaa.js +23 -0
  118. package/dist/{feeds → src/feeds}/platform/handlers/soundcloud.js +3 -1
  119. package/dist/src/feeds/platform/handlers/sourceforge.js +53 -0
  120. package/dist/src/feeds/platform/handlers/spreaker.js +22 -0
  121. package/dist/{feeds → src/feeds}/platform/handlers/stackExchange.js +28 -3
  122. package/dist/{feeds → src/feeds}/platform/handlers/steam.js +9 -1
  123. package/dist/{feeds → src/feeds}/platform/handlers/substack.js +2 -1
  124. package/dist/src/feeds/platform/handlers/tildes.js +42 -0
  125. package/dist/src/feeds/platform/handlers/tistory.js +17 -0
  126. package/dist/src/feeds/platform/handlers/transistor.js +30 -0
  127. package/dist/{feeds → src/feeds}/platform/handlers/tumblr.js +2 -1
  128. package/dist/{feeds → src/feeds}/platform/handlers/v2ex.js +2 -1
  129. package/dist/src/feeds/platform/handlers/velog.js +25 -0
  130. package/dist/{feeds → src/feeds}/platform/handlers/vimeo.js +9 -1
  131. package/dist/src/feeds/platform/handlers/weblogLol.js +27 -0
  132. package/dist/src/feeds/platform/handlers/weebly.js +26 -0
  133. package/dist/src/feeds/platform/handlers/wordpress.js +210 -0
  134. package/dist/{feeds → src/feeds}/platform/handlers/wpengine.js +1 -1
  135. package/dist/src/feeds/platform/handlers/writeas.js +53 -0
  136. package/dist/{feeds → src/feeds}/platform/handlers/ximalaya.js +3 -2
  137. package/dist/{feeds → src/feeds}/platform/handlers/youtube.js +6 -2
  138. package/dist/src/feeds/platform/handlers/zenn.js +56 -0
  139. package/package.json +10 -11
  140. package/dist/common/locales.js +0 -133
  141. package/dist/common/uris/headers/index.js +0 -26
  142. package/dist/common/uris/html/types.d.ts +0 -12
  143. package/dist/common/utils.d.ts +0 -10
  144. package/dist/common/utils.js +0 -79
  145. package/dist/feeds/platform/handlers/blogspot.js +0 -36
  146. package/dist/feeds/platform/handlers/lemmy.js +0 -46
  147. package/dist/feeds/platform/handlers/reddit.js +0 -74
  148. package/dist/feeds/platform/handlers/sourceforge.js +0 -19
  149. package/dist/feeds/platform/handlers/wordpress.js +0 -64
  150. package/dist/utils.d.ts +0 -2
  151. package/dist/utils.js +0 -2
  152. /package/dist/{blogrolls → src/blogrolls}/extractors.d.ts +0 -0
  153. /package/dist/{blogrolls → src/blogrolls}/index.d.ts +0 -0
  154. /package/dist/{blogrolls → src/blogrolls}/index.js +0 -0
  155. /package/dist/{blogrolls → src/blogrolls}/types.d.ts +0 -0
  156. /package/dist/{common → src/common}/discover/defaults.d.ts +0 -0
  157. /package/dist/{common → src/common}/discover/utils.d.ts +0 -0
  158. /package/dist/{common → src/common}/types.js +0 -0
  159. /package/dist/{common → src/common}/uris/feed/index.d.ts +0 -0
  160. /package/dist/{common → src/common}/uris/feed/types.d.ts +0 -0
  161. /package/dist/{common → src/common}/uris/guess/index.d.ts +0 -0
  162. /package/dist/{common → src/common}/uris/guess/index.js +0 -0
  163. /package/dist/{common → src/common}/uris/guess/types.d.ts +0 -0
  164. /package/dist/{common → src/common}/uris/guess/utils.d.ts +0 -0
  165. /package/dist/{common → src/common}/uris/guess/utils.js +0 -0
  166. /package/dist/{common → src/common}/uris/headers/index.d.ts +0 -0
  167. /package/dist/{common → src/common}/uris/headers/types.d.ts +0 -0
  168. /package/dist/{common → src/common}/uris/html/index.d.ts +0 -0
  169. /package/dist/{common → src/common}/uris/index.js +0 -0
  170. /package/dist/{common → src/common}/uris/platform/index.d.ts +0 -0
  171. /package/dist/{common → src/common}/uris/platform/index.js +0 -0
  172. /package/dist/{common → src/common}/uris/platform/types.d.ts +0 -0
  173. /package/dist/{favicons → src/favicons}/defaults.d.ts +0 -0
  174. /package/dist/{favicons → src/favicons}/extractors.d.ts +0 -0
  175. /package/dist/{favicons → src/favicons}/index.d.ts +0 -0
  176. /package/dist/{favicons → src/favicons}/index.js +0 -0
  177. /package/dist/{favicons → src/favicons}/types.d.ts +0 -0
  178. /package/dist/{feeds → src/feeds}/extractors.d.ts +0 -0
  179. /package/dist/{feeds → src/feeds}/index.d.ts +0 -0
  180. /package/dist/{feeds → src/feeds}/index.js +0 -0
  181. /package/dist/{feeds → src/feeds}/types.d.ts +0 -0
  182. /package/dist/{hubs → src/hubs}/discover/index.d.ts +0 -0
  183. /package/dist/{hubs → src/hubs}/discover/index.js +0 -0
  184. /package/dist/{hubs → src/hubs}/discover/types.d.ts +0 -0
  185. /package/dist/{hubs → src/hubs}/feed/index.js +0 -0
  186. /package/dist/{hubs → src/hubs}/headers/index.js +0 -0
  187. /package/dist/{hubs → src/hubs}/html/index.js +0 -0
package/README.md CHANGED
@@ -23,7 +23,7 @@ Finds feeds by scanning links and anchors in HTML content, parsing HTTP headers,
23
23
  | Feeds | RSS, Atom, JSON Feed, and RDF. Each feed is validated and returns metadata like format, title, description, and site URL. |
24
24
  | Blogrolls | OPML files containing feed subscriptions. Validated and returns title. |
25
25
  | Favicons | Site icons from HTML, feeds, platform APIs, and common paths. Validated to ensure URLs point to actual images. |
26
- | WebSub hubs | Find hubs for real-time feed update notifications. |
26
+ | WebSub | Find hubs for real-time feed update notifications. |
27
27
 
28
28
  ### Discovery Methods
29
29
 
@@ -1,4 +1,4 @@
1
- import { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal } from "./blogrolls/defaults.js";
2
- import { BlogrollResult } from "./blogrolls/types.js";
3
- import { defaultExtractFn } from "./blogrolls/extractors.js";
4
- export { BlogrollResult, anchorLabels, defaultExtractFn, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
1
+ import { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, urisBalanced, urisComprehensive, urisMinimal } from "./src/blogrolls/defaults.js";
2
+ import { BlogrollResult } from "./src/blogrolls/types.js";
3
+ import { defaultExtractFn } from "./src/blogrolls/extractors.js";
4
+ export { BlogrollResult, anchorLabels, defaultExtractFn, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, urisBalanced, urisComprehensive, urisMinimal };
package/dist/blogrolls.js CHANGED
@@ -1,3 +1,3 @@
1
- import { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal } from "./blogrolls/defaults.js";
2
- import { defaultExtractFn } from "./blogrolls/extractors.js";
3
- export { anchorLabels, defaultExtractFn, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
1
+ import { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, urisBalanced, urisComprehensive, urisMinimal } from "./src/blogrolls/defaults.js";
2
+ import { defaultExtractFn } from "./src/blogrolls/extractors.js";
3
+ export { anchorLabels, defaultExtractFn, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, urisBalanced, urisComprehensive, urisMinimal };
@@ -1,4 +1,4 @@
1
- import { defaultFeedOptions, defaultGuessOptions, defaultGuessPaths, defaultHeadersOptions, defaultHtmlOptions, defaultIconRels, defaultPlatformOptions, linkSelectors } from "./favicons/defaults.js";
2
- import { FaviconResult } from "./favicons/types.js";
3
- import { defaultExtractFn } from "./favicons/extractors.js";
1
+ import { defaultFeedOptions, defaultGuessOptions, defaultGuessPaths, defaultHeadersOptions, defaultHtmlOptions, defaultIconRels, defaultPlatformOptions, linkSelectors } from "./src/favicons/defaults.js";
2
+ import { FaviconResult } from "./src/favicons/types.js";
3
+ import { defaultExtractFn } from "./src/favicons/extractors.js";
4
4
  export { FaviconResult, defaultExtractFn, defaultFeedOptions, defaultGuessOptions, defaultGuessPaths, defaultHeadersOptions, defaultHtmlOptions, defaultIconRels, defaultPlatformOptions, linkSelectors };
package/dist/favicons.js CHANGED
@@ -1,3 +1,3 @@
1
- import { defaultFeedOptions, defaultGuessOptions, defaultGuessPaths, defaultHeadersOptions, defaultHtmlOptions, defaultIconRels, defaultPlatformOptions, linkSelectors } from "./favicons/defaults.js";
2
- import { defaultExtractFn } from "./favicons/extractors.js";
1
+ import { defaultFeedOptions, defaultGuessOptions, defaultGuessPaths, defaultHeadersOptions, defaultHtmlOptions, defaultIconRels, defaultPlatformOptions, linkSelectors } from "./src/favicons/defaults.js";
2
+ import { defaultExtractFn } from "./src/favicons/extractors.js";
3
3
  export { defaultExtractFn, defaultFeedOptions, defaultGuessOptions, defaultGuessPaths, defaultHeadersOptions, defaultHtmlOptions, defaultIconRels, defaultPlatformOptions, linkSelectors };
package/dist/feeds.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal } from "./feeds/defaults.js";
2
- import { FeedResult } from "./feeds/types.js";
3
- import { defaultExtractFn } from "./feeds/extractors.js";
4
- export { FeedResult, anchorLabels, defaultExtractFn, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
1
+ import { anchorAttributes, anchorLabels, anchorPathSegments, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal } from "./src/feeds/defaults.js";
2
+ import { FeedResult } from "./src/feeds/types.js";
3
+ import { defaultExtractFn } from "./src/feeds/extractors.js";
4
+ export { FeedResult, anchorAttributes, anchorLabels, anchorPathSegments, defaultExtractFn, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
package/dist/feeds.js CHANGED
@@ -1,3 +1,3 @@
1
- import { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal } from "./feeds/defaults.js";
2
- import { defaultExtractFn } from "./feeds/extractors.js";
3
- export { anchorLabels, defaultExtractFn, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
1
+ import { anchorAttributes, anchorLabels, anchorPathSegments, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal } from "./src/feeds/defaults.js";
2
+ import { defaultExtractFn } from "./src/feeds/extractors.js";
3
+ export { anchorAttributes, anchorLabels, anchorPathSegments, defaultExtractFn, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
package/dist/hubs.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { DiscoverHubsMethodsConfig, DiscoverHubsOptions, HubResult } from "./hubs/discover/types.js";
1
+ import { DiscoverHubsMethodsConfig, DiscoverHubsOptions, HubResult } from "./src/hubs/discover/types.js";
2
2
  export { DiscoverHubsMethodsConfig, DiscoverHubsOptions, HubResult };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { DiscoverExtractFn, DiscoverFetchFn, DiscoverFetchFnOptions, DiscoverFetchFnResponse, DiscoverInput, DiscoverInputObject, DiscoverMethod, DiscoverMethodsConfig, DiscoverOnProgressFn, DiscoverOptions, DiscoverProgress, DiscoverResolveSiteUrlFn, DiscoverResolveUrlFn, DiscoverResult, DiscoverUriEntry, DiscoverUriHint, UriEntry } from "./common/types.js";
2
- import { discoverBlogrolls } from "./blogrolls/index.js";
3
- import { defaultResolveSiteUrlFn } from "./common/discover/defaults.js";
4
- import { getFeedSiteUrl } from "./common/discover/utils.js";
5
- import { discoverFavicons } from "./favicons/index.js";
6
- import { discoverFeeds } from "./feeds/index.js";
7
- import { discoverHubs } from "./hubs/discover/index.js";
1
+ import { DiscoverExtractFn, DiscoverFetchFn, DiscoverFetchFnOptions, DiscoverFetchFnResponse, DiscoverInput, DiscoverInputObject, DiscoverMethod, DiscoverMethodsConfig, DiscoverOnProgressFn, DiscoverOptions, DiscoverProgress, DiscoverResolveSiteUrlFn, DiscoverResolveUrlFn, DiscoverResult, DiscoverUriEntry, DiscoverUriHint, UriEntry } from "./src/common/types.js";
2
+ import { discoverBlogrolls } from "./src/blogrolls/index.js";
3
+ import { defaultResolveSiteUrlFn } from "./src/common/discover/defaults.js";
4
+ import { getFeedSiteUrl } from "./src/common/discover/utils.js";
5
+ import { discoverFavicons } from "./src/favicons/index.js";
6
+ import { discoverFeeds } from "./src/feeds/index.js";
7
+ import { discoverHubs } from "./src/hubs/discover/index.js";
8
8
  export { type DiscoverExtractFn, type DiscoverFetchFn, type DiscoverFetchFnOptions, type DiscoverFetchFnResponse, type DiscoverInput, type DiscoverInputObject, type DiscoverMethod, type DiscoverMethodsConfig, type DiscoverOnProgressFn, type DiscoverOptions, type DiscoverProgress, type DiscoverResolveSiteUrlFn, type DiscoverResolveUrlFn, type DiscoverResult, type DiscoverUriEntry, type DiscoverUriHint, type UriEntry, defaultResolveSiteUrlFn, discoverBlogrolls, discoverFavicons, discoverFeeds, discoverHubs, getFeedSiteUrl };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { getFeedSiteUrl } from "./common/discover/utils.js";
2
- import { defaultResolveSiteUrlFn } from "./common/discover/defaults.js";
3
- import { discoverBlogrolls } from "./blogrolls/index.js";
4
- import { discoverFavicons } from "./favicons/index.js";
5
- import { discoverFeeds } from "./feeds/index.js";
6
- import { discoverHubs } from "./hubs/discover/index.js";
1
+ import { getFeedSiteUrl } from "./src/common/discover/utils.js";
2
+ import { defaultResolveSiteUrlFn } from "./src/common/discover/defaults.js";
3
+ import { discoverBlogrolls } from "./src/blogrolls/index.js";
4
+ import { discoverFavicons } from "./src/favicons/index.js";
5
+ import { discoverFeeds } from "./src/feeds/index.js";
6
+ import { discoverHubs } from "./src/hubs/discover/index.js";
7
7
  export { defaultResolveSiteUrlFn, discoverBlogrolls, discoverFavicons, discoverFeeds, discoverHubs, getFeedSiteUrl };
package/dist/methods.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { discoverUrisFromFeed } from "./common/uris/feed/index.js";
2
- import { discoverUrisFromGuess } from "./common/uris/guess/index.js";
3
- import { generateUrlCombinations, getSubdomainVariants, getWwwCounterpart } from "./common/uris/guess/utils.js";
4
- import { discoverUrisFromHeaders } from "./common/uris/headers/index.js";
5
- import { discoverUrisFromHtml } from "./common/uris/html/index.js";
6
- import { discoverUrisFromPlatform } from "./common/uris/platform/index.js";
1
+ import { discoverUrisFromFeed } from "./src/common/uris/feed/index.js";
2
+ import { discoverUrisFromGuess } from "./src/common/uris/guess/index.js";
3
+ import { generateUrlCombinations, getSubdomainVariants, getWwwCounterpart } from "./src/common/uris/guess/utils.js";
4
+ import { discoverUrisFromHeaders } from "./src/common/uris/headers/index.js";
5
+ import { discoverUrisFromHtml } from "./src/common/uris/html/index.js";
6
+ import { discoverUrisFromPlatform } from "./src/common/uris/platform/index.js";
7
7
  export { discoverUrisFromFeed, discoverUrisFromGuess, discoverUrisFromHeaders, discoverUrisFromHtml, discoverUrisFromPlatform, generateUrlCombinations, getSubdomainVariants, getWwwCounterpart };
package/dist/methods.js CHANGED
@@ -1,7 +1,7 @@
1
- import { discoverUrisFromFeed } from "./common/uris/feed/index.js";
2
- import { generateUrlCombinations, getSubdomainVariants, getWwwCounterpart } from "./common/uris/guess/utils.js";
3
- import { discoverUrisFromGuess } from "./common/uris/guess/index.js";
4
- import { discoverUrisFromHeaders } from "./common/uris/headers/index.js";
5
- import { discoverUrisFromHtml } from "./common/uris/html/index.js";
6
- import { discoverUrisFromPlatform } from "./common/uris/platform/index.js";
1
+ import { discoverUrisFromFeed } from "./src/common/uris/feed/index.js";
2
+ import { generateUrlCombinations, getSubdomainVariants, getWwwCounterpart } from "./src/common/uris/guess/utils.js";
3
+ import { discoverUrisFromGuess } from "./src/common/uris/guess/index.js";
4
+ import { discoverUrisFromHeaders } from "./src/common/uris/headers/index.js";
5
+ import { discoverUrisFromHtml } from "./src/common/uris/html/index.js";
6
+ import { discoverUrisFromPlatform } from "./src/common/uris/platform/index.js";
7
7
  export { discoverUrisFromFeed, discoverUrisFromGuess, discoverUrisFromHeaders, discoverUrisFromHtml, discoverUrisFromPlatform, generateUrlCombinations, getSubdomainVariants, getWwwCounterpart };
@@ -0,0 +1,9 @@
1
+ import { isPresent } from "./is.js";
2
+ //#region node_modules/trousse/dist/arrays.js
3
+ const omitEmpty = (array) => {
4
+ const result = [];
5
+ for (const item of array) if (isPresent(item) && item !== "") result.push(item);
6
+ return result;
7
+ };
8
+ //#endregion
9
+ export { omitEmpty };
@@ -0,0 +1,19 @@
1
+ //#region node_modules/trousse/dist/is.js
2
+ const isString = (value) => {
3
+ return typeof value === "string";
4
+ };
5
+ const isPresent = (value) => {
6
+ return value != null;
7
+ };
8
+ const isObject = (value) => {
9
+ return value !== null && typeof value === "object" && !Array.isArray(value);
10
+ };
11
+ const whitespaceOnlyRegex = /^\p{White_Space}*$/u;
12
+ const isNonEmptyString = (value) => {
13
+ if (!isString(value) || value === "") return false;
14
+ const code = value.charCodeAt(0);
15
+ if (code > 32 && code < 127) return true;
16
+ return !whitespaceOnlyRegex.test(value);
17
+ };
18
+ //#endregion
19
+ export { isNonEmptyString, isObject, isPresent };
@@ -0,0 +1,37 @@
1
+ //#region node_modules/trousse/dist/matching.js
2
+ const whitespaceRegex = /\s+/;
3
+ const isAnyOf = (value, patterns, parser) => {
4
+ const parsedValue = parser ? parser(value) : value?.toLowerCase()?.trim();
5
+ return patterns.some((pattern) => {
6
+ if (pattern instanceof RegExp) return pattern.test(parsedValue);
7
+ return parsedValue === pattern.toLowerCase().trim();
8
+ });
9
+ };
10
+ const includesAnyOf = (value, patterns, parser) => {
11
+ const parsedValue = parser ? parser(value) : value?.toLowerCase();
12
+ return patterns.some((pattern) => {
13
+ if (pattern instanceof RegExp) return pattern.test(parsedValue);
14
+ return pattern && parsedValue?.includes(pattern.toLowerCase());
15
+ });
16
+ };
17
+ const endsWithAnyOf = (value, patterns) => {
18
+ const lowerValue = value.toLowerCase();
19
+ return patterns.some((pattern) => {
20
+ if (pattern instanceof RegExp) return pattern.test(lowerValue);
21
+ return pattern && lowerValue.endsWith(pattern.toLowerCase());
22
+ });
23
+ };
24
+ const anyWordMatchesAnyOf = (value, patterns) => {
25
+ const stringPatterns = [];
26
+ const regexPatterns = [];
27
+ for (const pattern of patterns) if (pattern instanceof RegExp) regexPatterns.push(pattern);
28
+ else stringPatterns.push(pattern.toLowerCase().trim());
29
+ const words = value.toLowerCase().split(whitespaceRegex);
30
+ for (const word of words) {
31
+ for (const stringPattern of stringPatterns) if (word === stringPattern) return true;
32
+ for (const regexPattern of regexPatterns) if (regexPattern.test(word)) return true;
33
+ }
34
+ return false;
35
+ };
36
+ //#endregion
37
+ export { anyWordMatchesAnyOf, endsWithAnyOf, includesAnyOf, isAnyOf };
@@ -0,0 +1,20 @@
1
+ import { endsWithAnyOf, isAnyOf } from "./matching.js";
2
+ //#region node_modules/trousse/dist/urls.js
3
+ const parseUrl = (value, base) => {
4
+ if (value instanceof URL && base === void 0) return value;
5
+ try {
6
+ return new URL(value, base);
7
+ } catch {}
8
+ };
9
+ const isHostOf = (url, hosts) => {
10
+ const hostname = parseUrl(url)?.hostname;
11
+ if (!hostname) return false;
12
+ return isAnyOf(hostname, Array.isArray(hosts) ? hosts : [hosts]);
13
+ };
14
+ const isSubdomainOf = (url, domains) => {
15
+ const hostname = parseUrl(url)?.hostname;
16
+ if (!hostname) return false;
17
+ return endsWithAnyOf(hostname, (Array.isArray(domains) ? domains : [domains]).map((domain) => `.${domain}`));
18
+ };
19
+ //#endregion
20
+ export { isHostOf, isSubdomainOf, parseUrl };
@@ -4,7 +4,6 @@ import { HtmlMethodOptions } from "../common/uris/html/types.js";
4
4
  import { LinkSelector } from "../common/types.js";
5
5
 
6
6
  //#region src/blogrolls/defaults.d.ts
7
- declare const mimeTypes: string[];
8
7
  declare const urisMinimal: string[];
9
8
  declare const urisBalanced: string[];
10
9
  declare const urisComprehensive: string[];
@@ -14,4 +13,4 @@ declare const defaultHtmlOptions: Omit<HtmlMethodOptions, 'baseUrl'>;
14
13
  declare const defaultHeadersOptions: Omit<HeadersMethodOptions, 'baseUrl'>;
15
14
  declare const defaultGuessOptions: Omit<GuessMethodOptions, 'baseUrl'>;
16
15
  //#endregion
17
- export { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
16
+ export { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, urisBalanced, urisComprehensive, urisMinimal };
@@ -1,9 +1,4 @@
1
1
  //#region src/blogrolls/defaults.ts
2
- const mimeTypes = [
3
- "text/x-opml",
4
- "application/xml",
5
- "text/xml"
6
- ];
7
2
  const urisMinimal = [
8
3
  "/.well-known/recommendations.opml",
9
4
  "/blogroll.opml",
@@ -27,17 +22,30 @@ const anchorLabels = [
27
22
  "subscriptions",
28
23
  "reading list"
29
24
  ];
30
- const linkSelectors = [{ rel: "blogroll" }, {
31
- rel: "outline",
32
- types: mimeTypes
33
- }];
25
+ const linkSelectors = [
26
+ { rel: "blogroll" },
27
+ {
28
+ rel: "outline",
29
+ types: [
30
+ "text/x-opml",
31
+ "application/opml+xml",
32
+ "application/xml",
33
+ "text/xml"
34
+ ]
35
+ },
36
+ {
37
+ rel: "alternate",
38
+ types: ["text/x-opml", "application/opml+xml"]
39
+ }
40
+ ];
34
41
  const defaultHtmlOptions = {
35
42
  linkSelectors,
36
43
  anchorUris: urisComprehensive,
37
44
  anchorIgnoredUris: [],
38
- anchorLabels
45
+ anchorLabels,
46
+ anchorAttributes: ["aria-label", "title"]
39
47
  };
40
48
  const defaultHeadersOptions = { linkSelectors };
41
49
  const defaultGuessOptions = { uris: urisBalanced };
42
50
  //#endregion
43
- export { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
51
+ export { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, urisBalanced, urisComprehensive, urisMinimal };
@@ -1,7 +1,8 @@
1
+ import { isSuccessfulStatus } from "../common/utils.js";
1
2
  import { parseOpml } from "feedsmith";
2
3
  //#region src/blogrolls/extractors.ts
3
- const defaultExtractFn = ({ content, url }) => {
4
- if (!content) return {
4
+ const defaultExtractFn = ({ content, url, status }) => {
5
+ if (!content || !isSuccessfulStatus(status)) return {
5
6
  url,
6
7
  isValid: false
7
8
  };
@@ -17,9 +17,7 @@ const defaultFetchFn = async (url, options) => {
17
17
  const defaultResolveUrlFn = (url, baseUrl) => {
18
18
  try {
19
19
  return new URL(url, baseUrl).href;
20
- } catch {
21
- return;
22
- }
20
+ } catch {}
23
21
  };
24
22
  const defaultResolveSiteUrlFn = (input, resolveUrlFn) => {
25
23
  if (!input.content) return;
@@ -1,11 +1,13 @@
1
1
  import { normalizeInput, normalizeMethodsConfig, normalizeUriEntry } from "./utils.js";
2
2
  import { discoverMethodOrder } from "../types.js";
3
- import { processConcurrently } from "../utils.js";
3
+ import { processConcurrently, toPositiveInteger } from "../utils.js";
4
4
  import { discoverUris } from "../uris/index.js";
5
5
  //#region src/common/discover/index.ts
6
6
  const discover = async (input, options, defaults) => {
7
- const { methods, fetchFn, extractFn, resolveUrlFn, resolveSiteUrlFn, stopOnFirstMethod = false, stopOnFirstResult = false, concurrency = 3, includeInvalid = false, onProgress } = options;
8
- const sourceInput = await normalizeInput(input, fetchFn);
7
+ const { methods, fetchFn, extractFn, resolveUrlFn, resolveSiteUrlFn, stopOnFirstMethod = false, stopOnFirstResult = false, concurrency = 3, maxUris = 50, includeInvalid = false, onProgress, onError } = options;
8
+ const safeConcurrency = toPositiveInteger(concurrency, 3);
9
+ const safeMaxUris = toPositiveInteger(maxUris, 50);
10
+ const sourceInput = await normalizeInput(input, fetchFn, onError);
9
11
  if (sourceInput.content) {
10
12
  const result = await extractFn({
11
13
  url: sourceInput.url,
@@ -24,26 +26,37 @@ const discover = async (input, options, defaults) => {
24
26
  content: typeof response.body === "string" ? response.body : "",
25
27
  headers: response.headers
26
28
  };
27
- } catch {}
29
+ } catch (error) {
30
+ onError?.(error, {
31
+ phase: "resolveSiteUrl",
32
+ url: siteUrl
33
+ });
34
+ }
28
35
  }
29
36
  const urisByMethod = await discoverUris(normalizeMethodsConfig(sourceInput, siteInput, methods, defaults), fetchFn);
30
37
  const seen = /* @__PURE__ */ new Set();
31
38
  const methodGroups = [];
39
+ let remaining = safeMaxUris;
32
40
  for (const method of discoverMethodOrder) {
41
+ if (remaining <= 0) break;
33
42
  const rawUris = urisByMethod[method];
34
43
  if (!rawUris || rawUris.length === 0) continue;
35
44
  const unique = rawUris.map((entry) => {
36
45
  return normalizeUriEntry(entry, resolveUrlFn, sourceInput.url);
37
46
  }).filter((entry) => {
38
- const key = typeof entry.uri === "string" ? entry.uri : entry.uri.join("\0");
47
+ const key = typeof entry.uri === "string" ? entry.uri : [...entry.uri].sort().join("\0");
39
48
  if (seen.has(key)) return false;
40
49
  seen.add(key);
41
50
  return true;
42
51
  });
43
- if (unique.length > 0) methodGroups.push({
44
- method,
45
- entries: unique
46
- });
52
+ if (unique.length > 0) {
53
+ const capped = unique.slice(0, remaining);
54
+ remaining -= capped.length;
55
+ methodGroups.push({
56
+ method,
57
+ entries: capped
58
+ });
59
+ }
47
60
  }
48
61
  const total = methodGroups.reduce((sum, group) => sum + group.entries.length, 0);
49
62
  const results = [];
@@ -92,7 +105,7 @@ const discover = async (input, options, defaults) => {
92
105
  for (const { method, entries } of methodGroups) {
93
106
  const foundBefore = found;
94
107
  await processConcurrently(entries, (entry) => processUri(entry, method), {
95
- concurrency,
108
+ concurrency: safeConcurrency,
96
109
  shouldStop: () => {
97
110
  return stopOnFirstResult && found > 0;
98
111
  }
@@ -1,7 +1,8 @@
1
+ import { isObject } from "../../../node_modules/trousse/dist/is.js";
1
2
  import { errors } from "../locales.js";
2
3
  //#region src/common/discover/utils.ts
3
- const normalizeInput = async (input, fetchFn) => {
4
- if (typeof input === "object") return input;
4
+ const normalizeInput = async (input, fetchFn, onError) => {
5
+ if (isObject(input)) return input;
5
6
  try {
6
7
  const response = await fetchFn(input);
7
8
  return {
@@ -9,7 +10,12 @@ const normalizeInput = async (input, fetchFn) => {
9
10
  content: typeof response.body === "string" ? response.body : void 0,
10
11
  headers: response.headers
11
12
  };
12
- } catch {}
13
+ } catch (error) {
14
+ onError?.(error, {
15
+ phase: "fetchInput",
16
+ url: input
17
+ });
18
+ }
13
19
  return { url: input };
14
20
  };
15
21
  const getLinkOfType = (links, rel) => {