feedscout 2.0.0-rc.1 → 2.0.0-rc.2
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/dist/feeds.d.ts +2 -2
- package/dist/feeds.js +2 -2
- package/dist/methods.d.ts +2 -2
- package/dist/methods.js +2 -2
- package/dist/node_modules/trousse/dist/urls.js +4 -1
- package/dist/src/common/discover/utils.js +1 -0
- package/dist/src/common/uris/guess/index.js +11 -3
- package/dist/src/common/uris/guess/types.d.ts +3 -0
- package/dist/src/common/uris/guess/utils.d.ts +2 -1
- package/dist/src/common/uris/guess/utils.js +44 -1
- package/dist/src/feeds/defaults.d.ts +2 -1
- package/dist/src/feeds/defaults.js +17 -2
- package/package.json +1 -1
package/dist/feeds.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { anchorAttributes, anchorLabels, anchorPathSegments, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal } from "./src/feeds/defaults.js";
|
|
1
|
+
import { anchorAttributes, anchorLabels, anchorPathSegments, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, sectionNames, urisBalanced, urisComprehensive, urisMinimal } from "./src/feeds/defaults.js";
|
|
2
2
|
import { FeedResult } from "./src/feeds/types.js";
|
|
3
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 };
|
|
4
|
+
export { FeedResult, anchorAttributes, anchorLabels, anchorPathSegments, defaultExtractFn, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, sectionNames, urisBalanced, urisComprehensive, urisMinimal };
|
package/dist/feeds.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { anchorAttributes, anchorLabels, anchorPathSegments, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal } from "./src/feeds/defaults.js";
|
|
1
|
+
import { anchorAttributes, anchorLabels, anchorPathSegments, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, sectionNames, urisBalanced, urisComprehensive, urisMinimal } from "./src/feeds/defaults.js";
|
|
2
2
|
import { defaultExtractFn } from "./src/feeds/extractors.js";
|
|
3
|
-
export { anchorAttributes, anchorLabels, anchorPathSegments, defaultExtractFn, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
|
|
3
|
+
export { anchorAttributes, anchorLabels, anchorPathSegments, defaultExtractFn, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, sectionNames, urisBalanced, urisComprehensive, urisMinimal };
|
package/dist/methods.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { discoverUrisFromFeed } from "./src/common/uris/feed/index.js";
|
|
2
2
|
import { discoverUrisFromGuess } from "./src/common/uris/guess/index.js";
|
|
3
|
-
import { generateUrlCombinations, getSubdomainVariants, getWwwCounterpart } from "./src/common/uris/guess/utils.js";
|
|
3
|
+
import { extractSectionBaseUrls, generateUrlCombinations, getSubdomainVariants, getWwwCounterpart } from "./src/common/uris/guess/utils.js";
|
|
4
4
|
import { discoverUrisFromHeaders } from "./src/common/uris/headers/index.js";
|
|
5
5
|
import { discoverUrisFromHtml } from "./src/common/uris/html/index.js";
|
|
6
6
|
import { discoverUrisFromPlatform } from "./src/common/uris/platform/index.js";
|
|
7
|
-
export { discoverUrisFromFeed, discoverUrisFromGuess, discoverUrisFromHeaders, discoverUrisFromHtml, discoverUrisFromPlatform, generateUrlCombinations, getSubdomainVariants, getWwwCounterpart };
|
|
7
|
+
export { discoverUrisFromFeed, discoverUrisFromGuess, discoverUrisFromHeaders, discoverUrisFromHtml, discoverUrisFromPlatform, extractSectionBaseUrls, generateUrlCombinations, getSubdomainVariants, getWwwCounterpart };
|
package/dist/methods.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { discoverUrisFromFeed } from "./src/common/uris/feed/index.js";
|
|
2
|
-
import { generateUrlCombinations, getSubdomainVariants, getWwwCounterpart } from "./src/common/uris/guess/utils.js";
|
|
2
|
+
import { extractSectionBaseUrls, generateUrlCombinations, getSubdomainVariants, getWwwCounterpart } from "./src/common/uris/guess/utils.js";
|
|
3
3
|
import { discoverUrisFromGuess } from "./src/common/uris/guess/index.js";
|
|
4
4
|
import { discoverUrisFromHeaders } from "./src/common/uris/headers/index.js";
|
|
5
5
|
import { discoverUrisFromHtml } from "./src/common/uris/html/index.js";
|
|
6
6
|
import { discoverUrisFromPlatform } from "./src/common/uris/platform/index.js";
|
|
7
|
-
export { discoverUrisFromFeed, discoverUrisFromGuess, discoverUrisFromHeaders, discoverUrisFromHtml, discoverUrisFromPlatform, generateUrlCombinations, getSubdomainVariants, getWwwCounterpart };
|
|
7
|
+
export { discoverUrisFromFeed, discoverUrisFromGuess, discoverUrisFromHeaders, discoverUrisFromHtml, discoverUrisFromPlatform, extractSectionBaseUrls, generateUrlCombinations, getSubdomainVariants, getWwwCounterpart };
|
|
@@ -6,6 +6,9 @@ const parseUrl = (value, base) => {
|
|
|
6
6
|
return new URL(value, base);
|
|
7
7
|
} catch {}
|
|
8
8
|
};
|
|
9
|
+
const getPathSegments = (value) => {
|
|
10
|
+
return parseUrl(value)?.pathname.split("/").filter(Boolean) ?? [];
|
|
11
|
+
};
|
|
9
12
|
const isHostOf = (url, hosts) => {
|
|
10
13
|
const hostname = parseUrl(url)?.hostname;
|
|
11
14
|
if (!hostname) return false;
|
|
@@ -17,4 +20,4 @@ const isSubdomainOf = (url, domains) => {
|
|
|
17
20
|
return endsWithAnyOf(hostname, (Array.isArray(domains) ? domains : [domains]).map((domain) => `.${domain}`));
|
|
18
21
|
};
|
|
19
22
|
//#endregion
|
|
20
|
-
export { isHostOf, isSubdomainOf, parseUrl };
|
|
23
|
+
export { getPathSegments, isHostOf, isSubdomainOf, parseUrl };
|
|
@@ -94,6 +94,7 @@ const normalizeMethodsConfig = (sourceInput, siteInput, methods, defaults) => {
|
|
|
94
94
|
const guessOptions = methodsObj.guess === true ? {} : methodsObj.guess;
|
|
95
95
|
methodsConfig.guess = { options: {
|
|
96
96
|
...defaults.guess,
|
|
97
|
+
content: resolvedInput.content,
|
|
97
98
|
...guessOptions,
|
|
98
99
|
baseUrl: resolvedInput.url
|
|
99
100
|
} };
|
|
@@ -1,8 +1,16 @@
|
|
|
1
|
-
import { generateUrlCombinations } from "./utils.js";
|
|
1
|
+
import { extractSectionBaseUrls, generatePathUrlCombinations, generateUrlCombinations, getAncestorPathBases } from "./utils.js";
|
|
2
2
|
//#region src/common/uris/guess/index.ts
|
|
3
3
|
const discoverUrisFromGuess = (options) => {
|
|
4
|
-
const { baseUrl, uris, additionalBaseUrls = [] } = options;
|
|
5
|
-
|
|
4
|
+
const { baseUrl, uris, additionalBaseUrls = [], maxAncestorDepth = 0 } = options;
|
|
5
|
+
const { content, sectionNames } = options;
|
|
6
|
+
const combinations = generateUrlCombinations([baseUrl, ...additionalBaseUrls], uris);
|
|
7
|
+
const pathBases = [];
|
|
8
|
+
if (maxAncestorDepth > 0) pathBases.push(...getAncestorPathBases(baseUrl, maxAncestorDepth));
|
|
9
|
+
if (content && sectionNames && sectionNames.length > 0) {
|
|
10
|
+
for (const sectionBase of extractSectionBaseUrls(content, baseUrl, sectionNames)) if (!pathBases.includes(sectionBase)) pathBases.push(sectionBase);
|
|
11
|
+
}
|
|
12
|
+
if (pathBases.length > 0) combinations.push(...generatePathUrlCombinations(pathBases, uris));
|
|
13
|
+
return combinations;
|
|
6
14
|
};
|
|
7
15
|
//#endregion
|
|
8
16
|
export { discoverUrisFromGuess };
|
|
@@ -2,7 +2,8 @@ import { UriEntry } from "../../types.js";
|
|
|
2
2
|
|
|
3
3
|
//#region src/common/uris/guess/utils.d.ts
|
|
4
4
|
declare const generateUrlCombinations: (baseUrls: Array<string>, uris: Array<UriEntry>) => Array<UriEntry>;
|
|
5
|
+
declare const extractSectionBaseUrls: (content: string, baseUrl: string, sectionNames: Array<string>) => Array<string>;
|
|
5
6
|
declare const getWwwCounterpart: (baseUrl: string) => string;
|
|
6
7
|
declare const getSubdomainVariants: (baseUrl: string, prefixes: Array<string>) => Array<string>;
|
|
7
8
|
//#endregion
|
|
8
|
-
export { generateUrlCombinations, getSubdomainVariants, getWwwCounterpart };
|
|
9
|
+
export { extractSectionBaseUrls, generateUrlCombinations, getSubdomainVariants, getWwwCounterpart };
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { getPathSegments, parseUrl } from "../../../../node_modules/trousse/dist/urls.js";
|
|
2
|
+
import { Parser } from "htmlparser2";
|
|
1
3
|
//#region src/common/uris/guess/utils.ts
|
|
2
4
|
const ipAddressRegex = /^\d+\.\d+\.\d+\.\d+$/;
|
|
3
5
|
const resolveUri = (uri, base, origin, pathname) => {
|
|
@@ -16,6 +18,47 @@ const generateUrlCombinations = (baseUrls, uris) => {
|
|
|
16
18
|
});
|
|
17
19
|
});
|
|
18
20
|
};
|
|
21
|
+
const resolvePathUri = (uri, base) => {
|
|
22
|
+
if (uri.startsWith("/")) return new URL(uri.slice(1), base).href;
|
|
23
|
+
return new URL(uri, base).href;
|
|
24
|
+
};
|
|
25
|
+
const generatePathUrlCombinations = (pathBases, uris) => {
|
|
26
|
+
return pathBases.flatMap((base) => {
|
|
27
|
+
const normalizedBase = base.endsWith("/") ? base : `${base}/`;
|
|
28
|
+
return uris.map((uri) => {
|
|
29
|
+
if (typeof uri === "string") return resolvePathUri(uri, normalizedBase);
|
|
30
|
+
return uri.map((alternative) => resolvePathUri(alternative, normalizedBase));
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
const getAncestorPathBases = (baseUrl, maxDepth) => {
|
|
35
|
+
const url = parseUrl(baseUrl);
|
|
36
|
+
if (!url) return [];
|
|
37
|
+
const segments = url.pathname.split("/").slice(1, -1).filter((segment) => segment !== "");
|
|
38
|
+
const bases = [];
|
|
39
|
+
let base = `${url.origin}/`;
|
|
40
|
+
for (const segment of segments.slice(0, maxDepth)) {
|
|
41
|
+
base += `${segment}/`;
|
|
42
|
+
bases.push(base);
|
|
43
|
+
}
|
|
44
|
+
return bases;
|
|
45
|
+
};
|
|
46
|
+
const extractSectionBaseUrls = (content, baseUrl, sectionNames) => {
|
|
47
|
+
const base = parseUrl(baseUrl);
|
|
48
|
+
if (!base) return [];
|
|
49
|
+
const bases = /* @__PURE__ */ new Set();
|
|
50
|
+
const parser = new Parser({ onopentag: (name, attributes) => {
|
|
51
|
+
if (name !== "a" || !attributes.href) return;
|
|
52
|
+
const url = parseUrl(attributes.href, base);
|
|
53
|
+
if (!url || url.origin !== base.origin) return;
|
|
54
|
+
const segments = getPathSegments(url);
|
|
55
|
+
const segment = segments.length === 1 ? segments[0] : void 0;
|
|
56
|
+
if (segment && sectionNames.includes(segment.toLowerCase())) bases.add(`${url.origin}/${segment}/`);
|
|
57
|
+
} }, { decodeEntities: true });
|
|
58
|
+
parser.write(content);
|
|
59
|
+
parser.end();
|
|
60
|
+
return [...bases];
|
|
61
|
+
};
|
|
19
62
|
const getWwwCounterpart = (baseUrl) => {
|
|
20
63
|
const url = new URL(baseUrl);
|
|
21
64
|
const port = url.port ? `:${url.port}` : "";
|
|
@@ -37,4 +80,4 @@ const getSubdomainVariants = (baseUrl, prefixes) => {
|
|
|
37
80
|
});
|
|
38
81
|
};
|
|
39
82
|
//#endregion
|
|
40
|
-
export { generateUrlCombinations, getSubdomainVariants, getWwwCounterpart };
|
|
83
|
+
export { extractSectionBaseUrls, generatePathUrlCombinations, generateUrlCombinations, getAncestorPathBases, getSubdomainVariants, getWwwCounterpart };
|
|
@@ -16,7 +16,8 @@ declare const anchorPathSegments: RegExp[];
|
|
|
16
16
|
declare const anchorAttributes: string[];
|
|
17
17
|
declare const defaultHtmlOptions: Omit<HtmlMethodOptions, 'baseUrl'>;
|
|
18
18
|
declare const defaultHeadersOptions: Omit<HeadersMethodOptions, 'baseUrl'>;
|
|
19
|
+
declare const sectionNames: string[];
|
|
19
20
|
declare const defaultGuessOptions: Omit<GuessMethodOptions, 'baseUrl'>;
|
|
20
21
|
declare const defaultPlatformOptions: Omit<PlatformMethodOptions, 'baseUrl'>;
|
|
21
22
|
//#endregion
|
|
22
|
-
export { anchorAttributes, anchorLabels, anchorPathSegments, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
|
|
23
|
+
export { anchorAttributes, anchorLabels, anchorPathSegments, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, sectionNames, urisBalanced, urisComprehensive, urisMinimal };
|
|
@@ -188,7 +188,22 @@ const defaultHtmlOptions = {
|
|
|
188
188
|
anchorAttributes
|
|
189
189
|
};
|
|
190
190
|
const defaultHeadersOptions = { linkSelectors };
|
|
191
|
-
const
|
|
191
|
+
const sectionNames = [
|
|
192
|
+
"blog",
|
|
193
|
+
"news",
|
|
194
|
+
"posts",
|
|
195
|
+
"articles",
|
|
196
|
+
"writing",
|
|
197
|
+
"notes",
|
|
198
|
+
"journal",
|
|
199
|
+
"podcast",
|
|
200
|
+
"changelog"
|
|
201
|
+
];
|
|
202
|
+
const defaultGuessOptions = {
|
|
203
|
+
uris: urisBalanced,
|
|
204
|
+
maxAncestorDepth: 2,
|
|
205
|
+
sectionNames
|
|
206
|
+
};
|
|
192
207
|
const defaultPlatformOptions = { handlers: [
|
|
193
208
|
acastHandler,
|
|
194
209
|
amebloHandler,
|
|
@@ -282,4 +297,4 @@ const defaultPlatformOptions = { handlers: [
|
|
|
282
297
|
zennHandler
|
|
283
298
|
] };
|
|
284
299
|
//#endregion
|
|
285
|
-
export { anchorAttributes, anchorLabels, anchorPathSegments, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, urisBalanced, urisComprehensive, urisMinimal };
|
|
300
|
+
export { anchorAttributes, anchorLabels, anchorPathSegments, defaultGuessOptions, defaultHeadersOptions, defaultHtmlOptions, defaultPlatformOptions, ignoredUris, linkSelectors, mimeTypes, sectionNames, urisBalanced, urisComprehensive, urisMinimal };
|
package/package.json
CHANGED