feedscout 1.0.0-beta.2 → 1.0.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 +99 -68
- package/dist/blogrolls/defaults.cjs +13 -13
- package/dist/blogrolls/defaults.d.cts +5 -5
- package/dist/blogrolls/defaults.d.ts +5 -5
- package/dist/blogrolls/defaults.js +10 -10
- package/dist/blogrolls/extractors.cjs +2 -2
- package/dist/blogrolls/extractors.d.cts +3 -3
- package/dist/blogrolls/extractors.d.ts +3 -3
- package/dist/blogrolls/extractors.js +2 -2
- package/dist/blogrolls/index.cjs +1 -1
- package/dist/blogrolls/index.d.cts +2 -2
- package/dist/blogrolls/index.d.ts +2 -2
- package/dist/blogrolls/index.js +2 -2
- package/dist/blogrolls/types.d.cts +2 -2
- package/dist/blogrolls/types.d.ts +2 -2
- package/dist/blogrolls.cjs +5 -5
- package/dist/blogrolls.d.cts +4 -4
- package/dist/blogrolls.d.ts +4 -4
- package/dist/blogrolls.js +3 -3
- package/dist/common/discover/index.cjs +2 -2
- package/dist/common/discover/index.js +2 -2
- package/dist/common/discover/utils.cjs +0 -9
- package/dist/common/discover/utils.js +0 -9
- package/dist/common/types.d.cts +2 -30
- package/dist/common/types.d.ts +2 -30
- package/dist/common/uris/guess/types.d.cts +0 -21
- package/dist/common/uris/guess/types.d.ts +0 -21
- package/dist/common/uris/guess/utils.cjs +2 -53
- package/dist/common/uris/guess/utils.d.cts +1 -52
- package/dist/common/uris/guess/utils.d.ts +1 -52
- package/dist/common/uris/guess/utils.js +2 -53
- package/dist/feeds/defaults.cjs +14 -14
- package/dist/feeds/defaults.d.cts +5 -5
- package/dist/feeds/defaults.d.ts +5 -5
- package/dist/feeds/defaults.js +10 -10
- package/dist/feeds/extractors.cjs +2 -2
- package/dist/feeds/extractors.d.cts +3 -3
- package/dist/feeds/extractors.d.ts +3 -3
- package/dist/feeds/extractors.js +2 -2
- package/dist/feeds/index.cjs +1 -1
- package/dist/feeds/index.d.cts +2 -2
- package/dist/feeds/index.d.ts +2 -2
- package/dist/feeds/index.js +2 -2
- package/dist/feeds/types.d.cts +2 -3
- package/dist/feeds/types.d.ts +2 -3
- package/dist/feeds.cjs +6 -6
- package/dist/feeds.d.cts +4 -4
- package/dist/feeds.d.ts +4 -4
- package/dist/feeds.js +3 -3
- package/dist/index.d.cts +2 -3
- package/dist/index.d.ts +2 -3
- package/package.json +6 -7
package/README.md
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/feedscout)
|
|
5
5
|
[](https://github.com/macieklamberski/feedscout/blob/main/LICENSE)
|
|
6
6
|
|
|
7
|
-
Advanced feed autodiscovery for JavaScript. Collect
|
|
7
|
+
Advanced feed autodiscovery for JavaScript. Collect feed information from any webpage using multiple discovery methods.
|
|
8
|
+
|
|
9
|
+
Finds feeds by scanning links and anchors in HTML content, parsing HTTP headers, and guessing common paths, then validates each URL by fetching and parsing the feed.
|
|
8
10
|
|
|
9
11
|
**[Read full docs ↗](https://feedscout.dev)**
|
|
10
12
|
·
|
|
@@ -12,36 +14,62 @@ Advanced feed autodiscovery for JavaScript. Collect feeds from webpages using mu
|
|
|
12
14
|
|
|
13
15
|
---
|
|
14
16
|
|
|
15
|
-
##
|
|
17
|
+
## Features
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
### Supported Content
|
|
18
20
|
|
|
19
|
-
|
|
21
|
+
- **Feeds** — RSS, Atom, JSON Feed, and RDF. Each feed is validated and returns metadata like format, title, description, and site URL.
|
|
22
|
+
- **Blogrolls** — OPML files containing feed subscriptions. Validated and returns title.
|
|
23
|
+
- **WebSub hubs** — Find hubs for real-time feed update notifications.
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
### Discovery Methods
|
|
22
26
|
|
|
23
|
-
- **
|
|
24
|
-
- **
|
|
27
|
+
- **HTML** — Scans `<link>` elements with feed MIME types and `<a>` elements matching feed patterns or labels like "RSS", "Subscribe".
|
|
28
|
+
- **Headers** — Parses HTTP `Link` headers for `rel="alternate"` with feed MIME types per RFC 8288.
|
|
29
|
+
- **Guess** — Tests common paths (e.g. `/feed`, `/rss.xml`, `/atom.xml`) against the base URL as a fallback.
|
|
25
30
|
|
|
26
|
-
|
|
31
|
+
### Customization
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
- **Custom extractors** — Override the default parser to extract additional metadata from feeds and blogrolls.
|
|
34
|
+
- **Configurable methods** — Enable/disable discovery methods or customize their options.
|
|
35
|
+
- **Adapter system** — Use native fetch or integrate with Axios, Got, or Ky.
|
|
36
|
+
- **Concurrency control** — Limit parallel requests during validation.
|
|
37
|
+
- **Progress tracking** — Monitor discovery progress with callbacks.
|
|
38
|
+
- **Type-safe** — Full TypeScript support with exported types.
|
|
39
|
+
- **Tree-shakable** — Import only what you need.
|
|
29
40
|
|
|
30
|
-
|
|
41
|
+
## Quick Start
|
|
31
42
|
|
|
32
|
-
|
|
43
|
+
This is a short guide on how to get you up and running with Feedscout.
|
|
33
44
|
|
|
34
|
-
|
|
45
|
+
For a full overview of all the features, [visit the documentation](https://feedscout.dev).
|
|
35
46
|
|
|
36
|
-
|
|
47
|
+
### Installation
|
|
37
48
|
|
|
38
49
|
```bash
|
|
39
50
|
npm install feedscout
|
|
40
51
|
```
|
|
41
52
|
|
|
42
|
-
###
|
|
53
|
+
### Discover Feeds
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { discoverFeeds } from 'feedscout'
|
|
57
|
+
|
|
58
|
+
const feeds = await discoverFeeds('https://example.com', {
|
|
59
|
+
methods: ['html', 'headers'],
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
// [{
|
|
63
|
+
// url: 'https://example.com/feed.xml',
|
|
64
|
+
// isValid: true,
|
|
65
|
+
// format: 'rss',
|
|
66
|
+
// title: 'Example Blog',
|
|
67
|
+
// description: 'A blog about examples',
|
|
68
|
+
// siteUrl: 'https://example.com',
|
|
69
|
+
// }]
|
|
70
|
+
```
|
|
43
71
|
|
|
44
|
-
|
|
72
|
+
Or with existing HTML content:
|
|
45
73
|
|
|
46
74
|
```html
|
|
47
75
|
<html>
|
|
@@ -54,76 +82,79 @@ Given HTML content on https://example.com:
|
|
|
54
82
|
</html>
|
|
55
83
|
```
|
|
56
84
|
|
|
57
|
-
Feedscout discovers and extracts feeds data:
|
|
58
|
-
|
|
59
85
|
```typescript
|
|
60
|
-
import { discoverFeeds } from 'feedscout'
|
|
61
|
-
|
|
62
86
|
const feeds = await discoverFeeds(
|
|
63
87
|
{ url: 'https://example.com', content: html },
|
|
64
|
-
{ methods: ['html'
|
|
88
|
+
{ methods: ['html'] },
|
|
65
89
|
)
|
|
66
90
|
|
|
67
|
-
// [
|
|
91
|
+
// [
|
|
92
|
+
// {
|
|
93
|
+
// url: 'https://example.com/feed.xml',
|
|
94
|
+
// isValid: true,
|
|
95
|
+
// format: 'rss',
|
|
96
|
+
// title: 'Example Blog',
|
|
97
|
+
// description: 'A blog about examples',
|
|
98
|
+
// siteUrl: 'https://example.com',
|
|
99
|
+
// },
|
|
100
|
+
// {
|
|
101
|
+
// url: 'https://example.com/rss',
|
|
102
|
+
// isValid: true,
|
|
103
|
+
// format: 'rss',
|
|
104
|
+
// title: 'Example Blog',
|
|
105
|
+
// description: 'A blog about examples',
|
|
106
|
+
// siteUrl: 'https://example.com',
|
|
107
|
+
// },
|
|
108
|
+
// ]
|
|
68
109
|
```
|
|
69
110
|
|
|
70
|
-
|
|
111
|
+
Or with HTTP headers:
|
|
112
|
+
|
|
113
|
+
```http
|
|
114
|
+
Link: </feed.xml>; rel="alternate"; type="application/rss+xml"
|
|
115
|
+
```
|
|
71
116
|
|
|
72
117
|
```typescript
|
|
73
|
-
|
|
74
|
-
|
|
118
|
+
const feeds = await discoverFeeds(
|
|
119
|
+
{ url: 'https://example.com', headers },
|
|
120
|
+
{ methods: ['headers'] },
|
|
121
|
+
)
|
|
75
122
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
123
|
+
// [{
|
|
124
|
+
// url: 'https://example.com/feed.xml',
|
|
125
|
+
// isValid: true,
|
|
126
|
+
// format: 'rss',
|
|
127
|
+
// title: 'Example Blog',
|
|
128
|
+
// description: 'A blog about examples',
|
|
129
|
+
// siteUrl: 'https://example.com',
|
|
130
|
+
// }]
|
|
80
131
|
```
|
|
81
132
|
|
|
82
|
-
|
|
83
|
-
|---------|---------|
|
|
84
|
-
| `createNativeFetchAdapter` | Native `fetch` (default) |
|
|
85
|
-
| `createAxiosAdapter` | [axios](https://axios-http.com) |
|
|
86
|
-
| `createGotAdapter` | [got](https://github.com/sindresorhus/got) |
|
|
87
|
-
| `createKyAdapter` | [ky](https://github.com/sindresorhus/ky) |
|
|
88
|
-
|
|
133
|
+
### Discover Blogrolls
|
|
89
134
|
|
|
90
|
-
|
|
135
|
+
```typescript
|
|
136
|
+
import { discoverBlogrolls } from 'feedscout'
|
|
91
137
|
|
|
92
|
-
|
|
138
|
+
const blogrolls = await discoverBlogrolls('https://example.com', {
|
|
139
|
+
methods: ['html'],
|
|
140
|
+
})
|
|
93
141
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
headers: responseHeaders,
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
methods: ['html', 'headers', 'guess'],
|
|
103
|
-
},
|
|
104
|
-
)
|
|
142
|
+
// [{
|
|
143
|
+
// url: 'https://example.com/blogroll.opml',
|
|
144
|
+
// isValid: true,
|
|
145
|
+
// title: 'My Blogroll',
|
|
146
|
+
// }]
|
|
105
147
|
```
|
|
106
148
|
|
|
107
|
-
###
|
|
108
|
-
|
|
109
|
-
If you want more control over what types of links, anchors or labels are treated as feeds, use object syntax to customize method options:
|
|
149
|
+
### Discover WebSub Hubs
|
|
110
150
|
|
|
111
151
|
```typescript
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
anchorLabels: ['rss', 'feed', 'subscribe'],
|
|
116
|
-
anchorUris: ['/feed', '/rss'],
|
|
117
|
-
},
|
|
118
|
-
headers: true, // Use defaults
|
|
119
|
-
guess: {
|
|
120
|
-
uris: ['/custom-feed', '/blog/rss'],
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
concurrency: 5,
|
|
124
|
-
stopOnFirst: true,
|
|
125
|
-
}
|
|
126
|
-
)
|
|
127
|
-
```
|
|
152
|
+
import { discoverHubs } from 'feedscout'
|
|
153
|
+
|
|
154
|
+
const hubs = await discoverHubs('https://example.com/feed.xml')
|
|
128
155
|
|
|
129
|
-
|
|
156
|
+
// [{
|
|
157
|
+
// hub: 'https://pubsubhubbub.appspot.com',
|
|
158
|
+
// topic: 'https://example.com/feed.xml',
|
|
159
|
+
// }]
|
|
160
|
+
```
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
|
|
2
2
|
//#region src/blogrolls/defaults.ts
|
|
3
|
-
const
|
|
3
|
+
const mimeTypes = [
|
|
4
4
|
"text/x-opml",
|
|
5
5
|
"application/xml",
|
|
6
6
|
"text/xml"
|
|
7
7
|
];
|
|
8
|
-
const
|
|
8
|
+
const urisMinimal = [
|
|
9
9
|
"/.well-known/recommendations.opml",
|
|
10
10
|
"/blogroll.opml",
|
|
11
11
|
"/opml.xml"
|
|
12
12
|
];
|
|
13
|
-
const
|
|
14
|
-
...
|
|
13
|
+
const urisBalanced = [
|
|
14
|
+
...urisMinimal,
|
|
15
15
|
"/blogroll.xml",
|
|
16
16
|
"/subscriptions.opml",
|
|
17
17
|
"/recommendations.opml"
|
|
18
18
|
];
|
|
19
|
-
const
|
|
20
|
-
...
|
|
19
|
+
const urisComprehensive = [
|
|
20
|
+
...urisBalanced,
|
|
21
21
|
"/links.opml",
|
|
22
22
|
"/feeds.opml",
|
|
23
23
|
"/subscriptions.xml"
|
|
@@ -30,24 +30,24 @@ const anchorLabels = [
|
|
|
30
30
|
];
|
|
31
31
|
const linkSelectors = [{ rel: "blogroll" }, {
|
|
32
32
|
rel: "outline",
|
|
33
|
-
types:
|
|
33
|
+
types: mimeTypes
|
|
34
34
|
}];
|
|
35
35
|
const defaultHtmlOptions = {
|
|
36
36
|
linkSelectors,
|
|
37
|
-
anchorUris:
|
|
37
|
+
anchorUris: urisComprehensive,
|
|
38
38
|
anchorIgnoredUris: [],
|
|
39
39
|
anchorLabels
|
|
40
40
|
};
|
|
41
41
|
const defaultHeadersOptions = { linkSelectors };
|
|
42
|
-
const defaultGuessOptions = { uris:
|
|
42
|
+
const defaultGuessOptions = { uris: urisBalanced };
|
|
43
43
|
|
|
44
44
|
//#endregion
|
|
45
45
|
exports.anchorLabels = anchorLabels;
|
|
46
|
-
exports.blogrollUrisBalanced = blogrollUrisBalanced;
|
|
47
|
-
exports.blogrollUrisComprehensive = blogrollUrisComprehensive;
|
|
48
|
-
exports.blogrollUrisMinimal = blogrollUrisMinimal;
|
|
49
46
|
exports.defaultGuessOptions = defaultGuessOptions;
|
|
50
47
|
exports.defaultHeadersOptions = defaultHeadersOptions;
|
|
51
48
|
exports.defaultHtmlOptions = defaultHtmlOptions;
|
|
52
49
|
exports.linkSelectors = linkSelectors;
|
|
53
|
-
exports.
|
|
50
|
+
exports.mimeTypes = mimeTypes;
|
|
51
|
+
exports.urisBalanced = urisBalanced;
|
|
52
|
+
exports.urisComprehensive = urisComprehensive;
|
|
53
|
+
exports.urisMinimal = urisMinimal;
|
|
@@ -4,14 +4,14 @@ import { HtmlMethodOptions } from "../common/uris/html/types.cjs";
|
|
|
4
4
|
import { LinkSelector } from "../common/types.cjs";
|
|
5
5
|
|
|
6
6
|
//#region src/blogrolls/defaults.d.ts
|
|
7
|
-
declare const
|
|
8
|
-
declare const
|
|
9
|
-
declare const
|
|
10
|
-
declare const
|
|
7
|
+
declare const mimeTypes: string[];
|
|
8
|
+
declare const urisMinimal: string[];
|
|
9
|
+
declare const urisBalanced: string[];
|
|
10
|
+
declare const urisComprehensive: string[];
|
|
11
11
|
declare const anchorLabels: string[];
|
|
12
12
|
declare const linkSelectors: Array<LinkSelector>;
|
|
13
13
|
declare const defaultHtmlOptions: Omit<HtmlMethodOptions, 'baseUrl'>;
|
|
14
14
|
declare const defaultHeadersOptions: Omit<HeadersMethodOptions, 'baseUrl'>;
|
|
15
15
|
declare const defaultGuessOptions: Omit<GuessMethodOptions, 'baseUrl'>;
|
|
16
16
|
//#endregion
|
|
17
|
-
export { anchorLabels,
|
|
17
|
+
export { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
|
|
@@ -4,14 +4,14 @@ 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
|
|
8
|
-
declare const
|
|
9
|
-
declare const
|
|
10
|
-
declare const
|
|
7
|
+
declare const mimeTypes: string[];
|
|
8
|
+
declare const urisMinimal: string[];
|
|
9
|
+
declare const urisBalanced: string[];
|
|
10
|
+
declare const urisComprehensive: string[];
|
|
11
11
|
declare const anchorLabels: string[];
|
|
12
12
|
declare const linkSelectors: Array<LinkSelector>;
|
|
13
13
|
declare const defaultHtmlOptions: Omit<HtmlMethodOptions, 'baseUrl'>;
|
|
14
14
|
declare const defaultHeadersOptions: Omit<HeadersMethodOptions, 'baseUrl'>;
|
|
15
15
|
declare const defaultGuessOptions: Omit<GuessMethodOptions, 'baseUrl'>;
|
|
16
16
|
//#endregion
|
|
17
|
-
export { anchorLabels,
|
|
17
|
+
export { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
//#region src/blogrolls/defaults.ts
|
|
2
|
-
const
|
|
2
|
+
const mimeTypes = [
|
|
3
3
|
"text/x-opml",
|
|
4
4
|
"application/xml",
|
|
5
5
|
"text/xml"
|
|
6
6
|
];
|
|
7
|
-
const
|
|
7
|
+
const urisMinimal = [
|
|
8
8
|
"/.well-known/recommendations.opml",
|
|
9
9
|
"/blogroll.opml",
|
|
10
10
|
"/opml.xml"
|
|
11
11
|
];
|
|
12
|
-
const
|
|
13
|
-
...
|
|
12
|
+
const urisBalanced = [
|
|
13
|
+
...urisMinimal,
|
|
14
14
|
"/blogroll.xml",
|
|
15
15
|
"/subscriptions.opml",
|
|
16
16
|
"/recommendations.opml"
|
|
17
17
|
];
|
|
18
|
-
const
|
|
19
|
-
...
|
|
18
|
+
const urisComprehensive = [
|
|
19
|
+
...urisBalanced,
|
|
20
20
|
"/links.opml",
|
|
21
21
|
"/feeds.opml",
|
|
22
22
|
"/subscriptions.xml"
|
|
@@ -29,16 +29,16 @@ const anchorLabels = [
|
|
|
29
29
|
];
|
|
30
30
|
const linkSelectors = [{ rel: "blogroll" }, {
|
|
31
31
|
rel: "outline",
|
|
32
|
-
types:
|
|
32
|
+
types: mimeTypes
|
|
33
33
|
}];
|
|
34
34
|
const defaultHtmlOptions = {
|
|
35
35
|
linkSelectors,
|
|
36
|
-
anchorUris:
|
|
36
|
+
anchorUris: urisComprehensive,
|
|
37
37
|
anchorIgnoredUris: [],
|
|
38
38
|
anchorLabels
|
|
39
39
|
};
|
|
40
40
|
const defaultHeadersOptions = { linkSelectors };
|
|
41
|
-
const defaultGuessOptions = { uris:
|
|
41
|
+
const defaultGuessOptions = { uris: urisBalanced };
|
|
42
42
|
|
|
43
43
|
//#endregion
|
|
44
|
-
export { anchorLabels,
|
|
44
|
+
export { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
let feedsmith = require("feedsmith");
|
|
2
2
|
|
|
3
3
|
//#region src/blogrolls/extractors.ts
|
|
4
|
-
const
|
|
4
|
+
const defaultExtractor = async ({ content, url }) => {
|
|
5
5
|
if (!content) return {
|
|
6
6
|
url,
|
|
7
7
|
isValid: false
|
|
@@ -21,4 +21,4 @@ const feedsmithExtractor = async ({ content, url }) => {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
//#endregion
|
|
24
|
-
exports.
|
|
24
|
+
exports.defaultExtractor = defaultExtractor;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DiscoverExtractFn } from "../common/types.cjs";
|
|
2
|
-
import {
|
|
2
|
+
import { BlogrollResult } from "./types.cjs";
|
|
3
3
|
|
|
4
4
|
//#region src/blogrolls/extractors.d.ts
|
|
5
|
-
declare const
|
|
5
|
+
declare const defaultExtractor: DiscoverExtractFn<BlogrollResult>;
|
|
6
6
|
//#endregion
|
|
7
|
-
export {
|
|
7
|
+
export { defaultExtractor };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DiscoverExtractFn } from "../common/types.js";
|
|
2
|
-
import {
|
|
2
|
+
import { BlogrollResult } from "./types.js";
|
|
3
3
|
|
|
4
4
|
//#region src/blogrolls/extractors.d.ts
|
|
5
|
-
declare const
|
|
5
|
+
declare const defaultExtractor: DiscoverExtractFn<BlogrollResult>;
|
|
6
6
|
//#endregion
|
|
7
|
-
export {
|
|
7
|
+
export { defaultExtractor };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { parseOpml } from "feedsmith";
|
|
2
2
|
|
|
3
3
|
//#region src/blogrolls/extractors.ts
|
|
4
|
-
const
|
|
4
|
+
const defaultExtractor = async ({ content, url }) => {
|
|
5
5
|
if (!content) return {
|
|
6
6
|
url,
|
|
7
7
|
isValid: false
|
|
@@ -21,4 +21,4 @@ const feedsmithExtractor = async ({ content, url }) => {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
//#endregion
|
|
24
|
-
export {
|
|
24
|
+
export { defaultExtractor };
|
package/dist/blogrolls/index.cjs
CHANGED
|
@@ -9,7 +9,7 @@ const discoverBlogrolls = async (input, options) => {
|
|
|
9
9
|
return require_index.discover(input, {
|
|
10
10
|
...options,
|
|
11
11
|
fetchFn: options.fetchFn ?? require_adapters.createNativeFetchAdapter(),
|
|
12
|
-
extractFn: options.extractFn ?? require_extractors.
|
|
12
|
+
extractFn: options.extractFn ?? require_extractors.defaultExtractor,
|
|
13
13
|
normalizeUrlFn: options.normalizeUrlFn ?? require_utils.normalizeUrl
|
|
14
14
|
}, {
|
|
15
15
|
html: require_defaults.defaultHtmlOptions,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DiscoverInput, DiscoverOptions, DiscoverResult } from "../common/types.cjs";
|
|
2
|
-
import {
|
|
2
|
+
import { BlogrollResult } from "./types.cjs";
|
|
3
3
|
|
|
4
4
|
//#region src/blogrolls/index.d.ts
|
|
5
|
-
declare const discoverBlogrolls: <TValid extends
|
|
5
|
+
declare const discoverBlogrolls: <TValid extends BlogrollResult = BlogrollResult>(input: DiscoverInput, options: DiscoverOptions<TValid>) => Promise<Array<DiscoverResult<TValid>>>;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { discoverBlogrolls };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DiscoverInput, DiscoverOptions, DiscoverResult } from "../common/types.js";
|
|
2
|
-
import {
|
|
2
|
+
import { BlogrollResult } from "./types.js";
|
|
3
3
|
|
|
4
4
|
//#region src/blogrolls/index.d.ts
|
|
5
|
-
declare const discoverBlogrolls: <TValid extends
|
|
5
|
+
declare const discoverBlogrolls: <TValid extends BlogrollResult = BlogrollResult>(input: DiscoverInput, options: DiscoverOptions<TValid>) => Promise<Array<DiscoverResult<TValid>>>;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { discoverBlogrolls };
|
package/dist/blogrolls/index.js
CHANGED
|
@@ -2,14 +2,14 @@ import { createNativeFetchAdapter } from "../common/discover/adapters.js";
|
|
|
2
2
|
import { normalizeUrl } from "../common/utils.js";
|
|
3
3
|
import { discover } from "../common/discover/index.js";
|
|
4
4
|
import { defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions } from "./defaults.js";
|
|
5
|
-
import {
|
|
5
|
+
import { defaultExtractor } from "./extractors.js";
|
|
6
6
|
|
|
7
7
|
//#region src/blogrolls/index.ts
|
|
8
8
|
const discoverBlogrolls = async (input, options) => {
|
|
9
9
|
return discover(input, {
|
|
10
10
|
...options,
|
|
11
11
|
fetchFn: options.fetchFn ?? createNativeFetchAdapter(),
|
|
12
|
-
extractFn: options.extractFn ??
|
|
12
|
+
extractFn: options.extractFn ?? defaultExtractor,
|
|
13
13
|
normalizeUrlFn: options.normalizeUrlFn ?? normalizeUrl
|
|
14
14
|
}, {
|
|
15
15
|
html: defaultHtmlOptions,
|
package/dist/blogrolls.cjs
CHANGED
|
@@ -2,12 +2,12 @@ const require_defaults = require('./blogrolls/defaults.cjs');
|
|
|
2
2
|
const require_extractors = require('./blogrolls/extractors.cjs');
|
|
3
3
|
|
|
4
4
|
exports.anchorLabels = require_defaults.anchorLabels;
|
|
5
|
-
exports.
|
|
6
|
-
exports.blogrollUrisComprehensive = require_defaults.blogrollUrisComprehensive;
|
|
7
|
-
exports.blogrollUrisMinimal = require_defaults.blogrollUrisMinimal;
|
|
5
|
+
exports.defaultExtractor = require_extractors.defaultExtractor;
|
|
8
6
|
exports.defaultGuessOptions = require_defaults.defaultGuessOptions;
|
|
9
7
|
exports.defaultHeadersOptions = require_defaults.defaultHeadersOptions;
|
|
10
8
|
exports.defaultHtmlOptions = require_defaults.defaultHtmlOptions;
|
|
11
|
-
exports.feedsmithExtractor = require_extractors.feedsmithExtractor;
|
|
12
9
|
exports.linkSelectors = require_defaults.linkSelectors;
|
|
13
|
-
exports.
|
|
10
|
+
exports.mimeTypes = require_defaults.mimeTypes;
|
|
11
|
+
exports.urisBalanced = require_defaults.urisBalanced;
|
|
12
|
+
exports.urisComprehensive = require_defaults.urisComprehensive;
|
|
13
|
+
exports.urisMinimal = require_defaults.urisMinimal;
|
package/dist/blogrolls.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { anchorLabels,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
1
|
+
import { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal } from "./blogrolls/defaults.cjs";
|
|
2
|
+
import { BlogrollResult } from "./blogrolls/types.cjs";
|
|
3
|
+
import { defaultExtractor } from "./blogrolls/extractors.cjs";
|
|
4
|
+
export { BlogrollResult, anchorLabels, defaultExtractor, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
|
package/dist/blogrolls.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { anchorLabels,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
1
|
+
import { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal } from "./blogrolls/defaults.js";
|
|
2
|
+
import { BlogrollResult } from "./blogrolls/types.js";
|
|
3
|
+
import { defaultExtractor } from "./blogrolls/extractors.js";
|
|
4
|
+
export { BlogrollResult, anchorLabels, defaultExtractor, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
|
package/dist/blogrolls.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { anchorLabels,
|
|
2
|
-
import {
|
|
1
|
+
import { anchorLabels, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal } from "./blogrolls/defaults.js";
|
|
2
|
+
import { defaultExtractor } from "./blogrolls/extractors.js";
|
|
3
3
|
|
|
4
|
-
export { anchorLabels,
|
|
4
|
+
export { anchorLabels, defaultExtractor, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
|
|
@@ -4,7 +4,7 @@ const require_utils$1 = require('./utils.cjs');
|
|
|
4
4
|
|
|
5
5
|
//#region src/common/discover/index.ts
|
|
6
6
|
const discover = async (input, options, defaults) => {
|
|
7
|
-
const { methods, fetchFn, extractFn, normalizeUrlFn, concurrency = 3,
|
|
7
|
+
const { methods, fetchFn, extractFn, normalizeUrlFn, concurrency = 3, stopOnFirstResult = false, includeInvalid = false, onProgress } = options;
|
|
8
8
|
const normalizedInput = await require_utils$1.normalizeInput(input, fetchFn);
|
|
9
9
|
if (normalizedInput.content) {
|
|
10
10
|
const result = await extractFn({
|
|
@@ -45,7 +45,7 @@ const discover = async (input, options, defaults) => {
|
|
|
45
45
|
};
|
|
46
46
|
await require_utils.processConcurrently(uris, processUri, {
|
|
47
47
|
concurrency,
|
|
48
|
-
shouldStop: () =>
|
|
48
|
+
shouldStop: () => stopOnFirstResult && found > 0
|
|
49
49
|
});
|
|
50
50
|
return includeInvalid ? results : results.filter((result) => result.isValid);
|
|
51
51
|
};
|
|
@@ -4,7 +4,7 @@ import { normalizeInput, normalizeMethodsConfig } from "./utils.js";
|
|
|
4
4
|
|
|
5
5
|
//#region src/common/discover/index.ts
|
|
6
6
|
const discover = async (input, options, defaults) => {
|
|
7
|
-
const { methods, fetchFn, extractFn, normalizeUrlFn, concurrency = 3,
|
|
7
|
+
const { methods, fetchFn, extractFn, normalizeUrlFn, concurrency = 3, stopOnFirstResult = false, includeInvalid = false, onProgress } = options;
|
|
8
8
|
const normalizedInput = await normalizeInput(input, fetchFn);
|
|
9
9
|
if (normalizedInput.content) {
|
|
10
10
|
const result = await extractFn({
|
|
@@ -45,7 +45,7 @@ const discover = async (input, options, defaults) => {
|
|
|
45
45
|
};
|
|
46
46
|
await processConcurrently(uris, processUri, {
|
|
47
47
|
concurrency,
|
|
48
|
-
shouldStop: () =>
|
|
48
|
+
shouldStop: () => stopOnFirstResult && found > 0
|
|
49
49
|
});
|
|
50
50
|
return includeInvalid ? results : results.filter((result) => result.isValid);
|
|
51
51
|
};
|
|
@@ -10,15 +10,6 @@ const normalizeInput = async (input, fetchFn) => {
|
|
|
10
10
|
headers: response.headers
|
|
11
11
|
};
|
|
12
12
|
};
|
|
13
|
-
/**
|
|
14
|
-
* Normalizes user-facing methods config to internal methods config format.
|
|
15
|
-
*
|
|
16
|
-
* Handles:
|
|
17
|
-
* - Array → object conversion
|
|
18
|
-
* - true → {} normalization
|
|
19
|
-
* - Merging with default options
|
|
20
|
-
* - Building complete method configurations with input data
|
|
21
|
-
*/
|
|
22
13
|
const normalizeMethodsConfig = (input, methods, defaults) => {
|
|
23
14
|
const methodsObj = Array.isArray(methods) ? Object.fromEntries(methods.map((method) => [method, true])) : methods;
|
|
24
15
|
const methodsConfig = {};
|
|
@@ -10,15 +10,6 @@ const normalizeInput = async (input, fetchFn) => {
|
|
|
10
10
|
headers: response.headers
|
|
11
11
|
};
|
|
12
12
|
};
|
|
13
|
-
/**
|
|
14
|
-
* Normalizes user-facing methods config to internal methods config format.
|
|
15
|
-
*
|
|
16
|
-
* Handles:
|
|
17
|
-
* - Array → object conversion
|
|
18
|
-
* - true → {} normalization
|
|
19
|
-
* - Merging with default options
|
|
20
|
-
* - Building complete method configurations with input data
|
|
21
|
-
*/
|
|
22
13
|
const normalizeMethodsConfig = (input, methods, defaults) => {
|
|
23
14
|
const methodsObj = Array.isArray(methods) ? Object.fromEntries(methods.map((method) => [method, true])) : methods;
|
|
24
15
|
const methodsConfig = {};
|