webforai 2.1.1 → 3.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 +63 -1
- package/dist/adapters/index.js +58 -0
- package/dist/adapters/registry.js +149 -0
- package/dist/adapters/sites/declarative.js +178 -0
- package/dist/adapters/sites/hackernews.js +94 -0
- package/dist/adapters/sites/youtube.js +165 -0
- package/dist/adapters/types.js +0 -0
- package/dist/bin.js +3197 -402
- package/dist/cjs/adapters/index.js +86 -0
- package/dist/cjs/adapters/registry.js +178 -0
- package/dist/cjs/adapters/sites/declarative.js +202 -0
- package/dist/cjs/adapters/sites/hackernews.js +117 -0
- package/dist/cjs/adapters/sites/youtube.js +191 -0
- package/dist/cjs/adapters/types.js +16 -0
- package/dist/cjs/constants.js +2 -2
- package/dist/cjs/extractors/index.js +5 -0
- package/dist/cjs/extractors/lib/constants.js +186 -0
- package/dist/cjs/extractors/lib/sanitize.js +425 -0
- package/dist/cjs/extractors/lib/score.js +264 -0
- package/dist/cjs/extractors/lib/terminators.js +131 -0
- package/dist/cjs/extractors/lib/ui-chrome.js +119 -0
- package/dist/cjs/extractors/pipeExtractors.js +12 -9
- package/dist/cjs/extractors/presets/auto.js +44 -0
- package/dist/cjs/extractors/presets/minimal-filter.js +27 -48
- package/dist/cjs/extractors/presets/takumi.js +84 -122
- package/dist/cjs/html-to-markdown.js +44 -7
- package/dist/cjs/html-to-mdast.js +9 -1
- package/dist/cjs/index.js +31 -2
- package/dist/cjs/mdast-handlers/custom-a-handler.js +25 -9
- package/dist/cjs/mdast-handlers/custom-img-handler.js +23 -1
- package/dist/cjs/mdast-handlers/custom-table-handler.js +16 -0
- package/dist/cjs/mdast-handlers/definition-list-handler.js +99 -0
- package/dist/cjs/mdast-handlers/math-handler.js +12 -3
- package/dist/cjs/mdast-handlers/sup-sub-handler.js +39 -0
- package/dist/cjs/metadata/index.js +223 -0
- package/dist/cjs/normalize/index.js +168 -0
- package/dist/cjs/platform/client.js +147 -0
- package/dist/cjs/platform/error.js +36 -0
- package/dist/cjs/platform/fetch.js +37 -0
- package/dist/cjs/platform/index.js +40 -0
- package/dist/cjs/platform/types.js +34 -0
- package/dist/cjs/utils/hast-fast.js +284 -0
- package/dist/constants.js +2 -2
- package/dist/extractors/index.js +3 -0
- package/dist/extractors/lib/constants.js +150 -0
- package/dist/extractors/lib/sanitize.js +415 -0
- package/dist/extractors/lib/score.js +242 -0
- package/dist/extractors/lib/terminators.js +107 -0
- package/dist/extractors/lib/ui-chrome.js +96 -0
- package/dist/extractors/pipeExtractors.js +12 -9
- package/dist/extractors/presets/auto.js +20 -0
- package/dist/extractors/presets/minimal-filter.js +35 -47
- package/dist/extractors/presets/takumi.js +91 -122
- package/dist/html-to-markdown.js +42 -6
- package/dist/html-to-mdast.js +9 -1
- package/dist/index.js +31 -2
- package/dist/mdast-handlers/custom-a-handler.js +25 -9
- package/dist/mdast-handlers/custom-img-handler.js +23 -1
- package/dist/mdast-handlers/custom-table-handler.js +16 -0
- package/dist/mdast-handlers/definition-list-handler.js +76 -0
- package/dist/mdast-handlers/math-handler.js +12 -3
- package/dist/mdast-handlers/sup-sub-handler.js +16 -0
- package/dist/metadata/index.js +198 -0
- package/dist/normalize/index.js +149 -0
- package/dist/platform/client.js +125 -0
- package/dist/platform/error.js +13 -0
- package/dist/platform/fetch.js +14 -0
- package/dist/platform/index.js +19 -0
- package/dist/platform/types.js +9 -0
- package/dist/types/adapters/index.d.ts +24 -0
- package/dist/types/adapters/index.js.map +1 -0
- package/dist/types/adapters/registry.d.ts +35 -0
- package/dist/types/adapters/registry.js.map +1 -0
- package/dist/types/adapters/sites/declarative.d.ts +13 -0
- package/dist/types/adapters/sites/declarative.js.map +1 -0
- package/dist/types/adapters/sites/hackernews.d.ts +13 -0
- package/dist/types/adapters/sites/hackernews.js.map +1 -0
- package/dist/types/adapters/sites/youtube.d.ts +31 -0
- package/dist/types/adapters/sites/youtube.js.map +1 -0
- package/dist/types/adapters/types.d.ts +99 -0
- package/dist/types/adapters/types.js.map +1 -0
- package/dist/types/cli/bin.js.map +1 -1
- package/dist/types/cli/commands/skill/content.d.ts +9 -0
- package/dist/types/cli/commands/skill/content.js.map +1 -0
- package/dist/types/cli/commands/skill/index.d.ts +19 -0
- package/dist/types/cli/commands/skill/index.js.map +1 -0
- package/dist/types/cli/commands/webforai/interactive.d.ts +7 -0
- package/dist/types/cli/commands/webforai/interactive.js.map +1 -0
- package/dist/types/cli/commands/webforai/loadHtml.js.map +1 -1
- package/dist/types/cli/commands/webforai/options.d.ts +55 -0
- package/dist/types/cli/commands/webforai/options.js.map +1 -0
- package/dist/types/cli/commands/webforai/run.d.ts +10 -0
- package/dist/types/cli/commands/webforai/run.js.map +1 -0
- package/dist/types/cli/constants.d.ts +14 -4
- package/dist/types/cli/constants.js.map +1 -1
- package/dist/types/cli/helpers/selectExtractMode.js.map +1 -1
- package/dist/types/cli/helpers/selectLoader.js.map +1 -1
- package/dist/types/constants.d.ts +7 -1
- package/dist/types/constants.js.map +1 -1
- package/dist/types/extractors/index.d.ts +1 -0
- package/dist/types/extractors/index.js.map +1 -1
- package/dist/types/extractors/lib/constants.d.ts +81 -0
- package/dist/types/extractors/lib/constants.js.map +1 -0
- package/dist/types/extractors/lib/sanitize.d.ts +66 -0
- package/dist/types/extractors/lib/sanitize.js.map +1 -0
- package/dist/types/extractors/lib/score.d.ts +85 -0
- package/dist/types/extractors/lib/score.js.map +1 -0
- package/dist/types/extractors/lib/terminators.d.ts +26 -0
- package/dist/types/extractors/lib/terminators.js.map +1 -0
- package/dist/types/extractors/lib/ui-chrome.d.ts +18 -0
- package/dist/types/extractors/lib/ui-chrome.js.map +1 -0
- package/dist/types/extractors/pipeExtractors.d.ts +5 -0
- package/dist/types/extractors/pipeExtractors.js.map +1 -1
- package/dist/types/extractors/presets/auto.d.ts +30 -0
- package/dist/types/extractors/presets/auto.js.map +1 -0
- package/dist/types/extractors/presets/minimal-filter.d.ts +10 -2
- package/dist/types/extractors/presets/minimal-filter.js.map +1 -1
- package/dist/types/extractors/presets/takumi.d.ts +19 -3
- package/dist/types/extractors/presets/takumi.js.map +1 -1
- package/dist/types/extractors/types.d.ts +8 -0
- package/dist/types/html-to-markdown.d.ts +38 -0
- package/dist/types/html-to-markdown.js.map +1 -1
- package/dist/types/html-to-mdast.d.ts +11 -0
- package/dist/types/html-to-mdast.js.map +1 -1
- package/dist/types/index.d.ts +6 -3
- package/dist/types/index.js.map +1 -1
- package/dist/types/mdast-handlers/custom-a-handler.js.map +1 -1
- package/dist/types/mdast-handlers/custom-img-handler.js.map +1 -1
- package/dist/types/mdast-handlers/custom-table-handler.js.map +1 -1
- package/dist/types/mdast-handlers/definition-list-handler.d.ts +13 -0
- package/dist/types/mdast-handlers/definition-list-handler.js.map +1 -0
- package/dist/types/mdast-handlers/math-handler.js.map +1 -1
- package/dist/types/mdast-handlers/sup-sub-handler.d.ts +10 -0
- package/dist/types/mdast-handlers/sup-sub-handler.js.map +1 -0
- package/dist/types/metadata/index.d.ts +47 -0
- package/dist/types/metadata/index.js.map +1 -0
- package/dist/types/normalize/index.d.ts +53 -0
- package/dist/types/normalize/index.js.map +1 -0
- package/dist/types/platform/client.d.ts +54 -0
- package/dist/types/platform/client.js.map +1 -0
- package/dist/types/platform/error.d.ts +20 -0
- package/dist/types/platform/error.js.map +1 -0
- package/dist/types/platform/fetch.d.ts +34 -0
- package/dist/types/platform/fetch.js.map +1 -0
- package/dist/types/platform/index.d.ts +4 -0
- package/dist/types/platform/index.js.map +1 -0
- package/dist/types/platform/types.d.ts +135 -0
- package/dist/types/platform/types.js.map +1 -0
- package/dist/types/utils/hast-fast.d.ts +101 -0
- package/dist/types/utils/hast-fast.js.map +1 -0
- package/dist/utils/hast-fast.js +246 -0
- package/package.json +10 -3
- package/dist/types/cli/commands/webforai/index.d.ts +0 -6
- package/dist/types/cli/commands/webforai/index.js.map +0 -1
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var adapters_exports = {};
|
|
20
|
+
__export(adapters_exports, {
|
|
21
|
+
BUILTIN_ADAPTERS: () => BUILTIN_ADAPTERS,
|
|
22
|
+
DECLARATIVE_ADAPTERS: () => import_declarative2.DECLARATIVE_ADAPTERS,
|
|
23
|
+
adapterById: () => adapterById,
|
|
24
|
+
buildPageSignature: () => import_registry2.buildPageSignature,
|
|
25
|
+
defineSelectorAdapter: () => import_registry2.defineSelectorAdapter,
|
|
26
|
+
hackernewsAdapter: () => import_hackernews2.hackernewsAdapter,
|
|
27
|
+
removeAll: () => import_registry2.removeAll,
|
|
28
|
+
resolveAdapter: () => import_registry2.resolveAdapter,
|
|
29
|
+
runAdapters: () => runAdapters,
|
|
30
|
+
selectFirst: () => import_registry2.selectFirst,
|
|
31
|
+
youtubeAdapter: () => import_youtube2.youtubeAdapter,
|
|
32
|
+
youtubeCaptionTracks: () => import_youtube2.youtubeCaptionTracks
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(adapters_exports);
|
|
35
|
+
var import_sanitize = require("../extractors/lib/sanitize");
|
|
36
|
+
var import_hast_fast = require("../utils/hast-fast");
|
|
37
|
+
var import_registry = require("./registry");
|
|
38
|
+
var import_declarative = require("./sites/declarative");
|
|
39
|
+
var import_hackernews = require("./sites/hackernews");
|
|
40
|
+
var import_youtube = require("./sites/youtube");
|
|
41
|
+
var import_registry2 = require("./registry");
|
|
42
|
+
var import_declarative2 = require("./sites/declarative");
|
|
43
|
+
var import_hackernews2 = require("./sites/hackernews");
|
|
44
|
+
var import_youtube2 = require("./sites/youtube");
|
|
45
|
+
const BUILTIN_ADAPTERS = [import_youtube.youtubeAdapter, import_hackernews.hackernewsAdapter, ...import_declarative.DECLARATIVE_ADAPTERS];
|
|
46
|
+
const adapterById = (id) => BUILTIN_ADAPTERS.find((adapter) => adapter.id === id);
|
|
47
|
+
const MIN_ADAPTER_TEXT = 40;
|
|
48
|
+
const runAdapters = (context, adapters = BUILTIN_ADAPTERS) => {
|
|
49
|
+
let matched = (0, import_registry.resolveAdapterByHost)(context, adapters);
|
|
50
|
+
let withSignature = context;
|
|
51
|
+
if (!matched) {
|
|
52
|
+
withSignature = { ...context, signature: context.signature ?? (0, import_registry.buildPageSignature)(context.hast) };
|
|
53
|
+
matched = (0, import_registry.resolveAdapterByFingerprint)(withSignature, adapters);
|
|
54
|
+
}
|
|
55
|
+
const adapter = matched;
|
|
56
|
+
if (!adapter) {
|
|
57
|
+
return void 0;
|
|
58
|
+
}
|
|
59
|
+
const target = withSignature.owned ? withSignature : { ...withSignature, hast: (0, import_hast_fast.cloneHast)(withSignature.hast), owned: true };
|
|
60
|
+
let extracted;
|
|
61
|
+
try {
|
|
62
|
+
extracted = adapter.extract(target);
|
|
63
|
+
} catch {
|
|
64
|
+
return void 0;
|
|
65
|
+
}
|
|
66
|
+
if (!extracted) {
|
|
67
|
+
return void 0;
|
|
68
|
+
}
|
|
69
|
+
(0, import_sanitize.stripNonContent)(extracted);
|
|
70
|
+
return new import_hast_fast.MetricsCollector().textLength(extracted) >= MIN_ADAPTER_TEXT ? extracted : void 0;
|
|
71
|
+
};
|
|
72
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
73
|
+
0 && (module.exports = {
|
|
74
|
+
BUILTIN_ADAPTERS,
|
|
75
|
+
DECLARATIVE_ADAPTERS,
|
|
76
|
+
adapterById,
|
|
77
|
+
buildPageSignature,
|
|
78
|
+
defineSelectorAdapter,
|
|
79
|
+
hackernewsAdapter,
|
|
80
|
+
removeAll,
|
|
81
|
+
resolveAdapter,
|
|
82
|
+
runAdapters,
|
|
83
|
+
selectFirst,
|
|
84
|
+
youtubeAdapter,
|
|
85
|
+
youtubeCaptionTracks
|
|
86
|
+
});
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var registry_exports = {};
|
|
20
|
+
__export(registry_exports, {
|
|
21
|
+
buildPageSignature: () => buildPageSignature,
|
|
22
|
+
defineSelectorAdapter: () => defineSelectorAdapter,
|
|
23
|
+
removeAll: () => removeAll,
|
|
24
|
+
resolveAdapter: () => resolveAdapter,
|
|
25
|
+
resolveAdapterByFingerprint: () => resolveAdapterByFingerprint,
|
|
26
|
+
resolveAdapterByHost: () => resolveAdapterByHost,
|
|
27
|
+
selectFirst: () => selectFirst
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(registry_exports);
|
|
30
|
+
var import_hast_util_select = require("hast-util-select");
|
|
31
|
+
var import_hast_fast = require("../utils/hast-fast");
|
|
32
|
+
const EMPTY_SIGNATURE = {
|
|
33
|
+
classes: /* @__PURE__ */ new Set(),
|
|
34
|
+
ids: /* @__PURE__ */ new Set(),
|
|
35
|
+
tags: /* @__PURE__ */ new Set(),
|
|
36
|
+
generator: "",
|
|
37
|
+
meta: ""
|
|
38
|
+
};
|
|
39
|
+
const buildPageSignature = (root) => {
|
|
40
|
+
const classes = /* @__PURE__ */ new Set();
|
|
41
|
+
const ids = /* @__PURE__ */ new Set();
|
|
42
|
+
const tags = /* @__PURE__ */ new Set();
|
|
43
|
+
const generatorParts = [];
|
|
44
|
+
const metaParts = [];
|
|
45
|
+
(0, import_hast_fast.walk)(root, (node) => {
|
|
46
|
+
if (!(0, import_hast_fast.isElement)(node)) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
tags.add(node.tagName);
|
|
50
|
+
for (const name of (0, import_hast_fast.classList)(node)) {
|
|
51
|
+
classes.add(name);
|
|
52
|
+
}
|
|
53
|
+
const id = (0, import_hast_fast.stringProperty)(node, "id");
|
|
54
|
+
if (id) {
|
|
55
|
+
ids.add(id);
|
|
56
|
+
}
|
|
57
|
+
if (node.tagName === "meta") {
|
|
58
|
+
const key = (0, import_hast_fast.stringProperty)(node, "name") ?? (0, import_hast_fast.stringProperty)(node, "property") ?? "";
|
|
59
|
+
const content = (0, import_hast_fast.stringProperty)(node, "content") ?? "";
|
|
60
|
+
metaParts.push(`${key}=${content}`);
|
|
61
|
+
if (key.toLowerCase() === "generator") {
|
|
62
|
+
generatorParts.push(content);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
return {
|
|
67
|
+
classes,
|
|
68
|
+
ids,
|
|
69
|
+
tags,
|
|
70
|
+
generator: generatorParts.join(" ").toLowerCase(),
|
|
71
|
+
meta: metaParts.join("\n").toLowerCase()
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
const DEFAULT_MIN_LENGTH = 40;
|
|
75
|
+
const hostOf = (url) => {
|
|
76
|
+
if (!url) {
|
|
77
|
+
return void 0;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
return new URL(url).hostname;
|
|
81
|
+
} catch {
|
|
82
|
+
return void 0;
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const defineSelectorAdapter = (spec) => ({
|
|
86
|
+
id: spec.id,
|
|
87
|
+
matches: (context) => {
|
|
88
|
+
const host = hostOf(context.url);
|
|
89
|
+
return Boolean(host && spec.hosts?.test(host));
|
|
90
|
+
},
|
|
91
|
+
matchesFingerprint: (context) => {
|
|
92
|
+
const signature = context.signature ?? EMPTY_SIGNATURE;
|
|
93
|
+
return spec.fingerprint?.(signature) ?? false;
|
|
94
|
+
},
|
|
95
|
+
extract: (context) => {
|
|
96
|
+
for (const selector of spec.content) {
|
|
97
|
+
const content = tryContentSelector(selector, spec, context);
|
|
98
|
+
if (content) {
|
|
99
|
+
return content;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return void 0;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
const tryContentSelector = (selector, spec, context) => {
|
|
106
|
+
const found = (0, import_hast_util_select.selectAll)(selector, context.hast);
|
|
107
|
+
if (found.length === 0) {
|
|
108
|
+
return void 0;
|
|
109
|
+
}
|
|
110
|
+
for (const element of found) {
|
|
111
|
+
removeAll(element, spec.remove);
|
|
112
|
+
}
|
|
113
|
+
const total = found.reduce((sum, element) => sum + new import_hast_fast.MetricsCollector().textLength(element), 0);
|
|
114
|
+
if (total < (spec.minLength ?? DEFAULT_MIN_LENGTH)) {
|
|
115
|
+
return void 0;
|
|
116
|
+
}
|
|
117
|
+
const decorated = spec.decorate?.(found, context);
|
|
118
|
+
if (decorated) {
|
|
119
|
+
return decorated;
|
|
120
|
+
}
|
|
121
|
+
return found.length === 1 ? found[0] : { type: "root", children: found };
|
|
122
|
+
};
|
|
123
|
+
const removeAll = (root, selectors) => {
|
|
124
|
+
if (!selectors || selectors.length === 0) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const doomed = /* @__PURE__ */ new Set();
|
|
128
|
+
for (const selector of selectors) {
|
|
129
|
+
for (const element of (0, import_hast_util_select.selectAll)(selector, root)) {
|
|
130
|
+
doomed.add(element);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (doomed.size > 0) {
|
|
134
|
+
(0, import_hast_fast.pruneInPlace)(root, (node) => !((0, import_hast_fast.isElement)(node) && doomed.has(node)));
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
const selectFirst = (root, selectors) => {
|
|
138
|
+
for (const selector of selectors) {
|
|
139
|
+
const found = (0, import_hast_util_select.select)(selector, root);
|
|
140
|
+
if (found) {
|
|
141
|
+
return found;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return void 0;
|
|
145
|
+
};
|
|
146
|
+
const resolveAdapterByHost = (context, adapters) => {
|
|
147
|
+
for (const adapter of adapters) {
|
|
148
|
+
try {
|
|
149
|
+
if (adapter.matches(context)) {
|
|
150
|
+
return adapter;
|
|
151
|
+
}
|
|
152
|
+
} catch {
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return void 0;
|
|
156
|
+
};
|
|
157
|
+
const resolveAdapterByFingerprint = (context, adapters) => {
|
|
158
|
+
for (const adapter of adapters) {
|
|
159
|
+
try {
|
|
160
|
+
if (adapter.matchesFingerprint?.(context)) {
|
|
161
|
+
return adapter;
|
|
162
|
+
}
|
|
163
|
+
} catch {
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return void 0;
|
|
167
|
+
};
|
|
168
|
+
const resolveAdapter = (context, adapters) => resolveAdapterByHost(context, adapters) ?? resolveAdapterByFingerprint(context, adapters);
|
|
169
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
170
|
+
0 && (module.exports = {
|
|
171
|
+
buildPageSignature,
|
|
172
|
+
defineSelectorAdapter,
|
|
173
|
+
removeAll,
|
|
174
|
+
resolveAdapter,
|
|
175
|
+
resolveAdapterByFingerprint,
|
|
176
|
+
resolveAdapterByHost,
|
|
177
|
+
selectFirst
|
|
178
|
+
});
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var declarative_exports = {};
|
|
20
|
+
__export(declarative_exports, {
|
|
21
|
+
DECLARATIVE_ADAPTERS: () => DECLARATIVE_ADAPTERS,
|
|
22
|
+
declarativeAdapterById: () => declarativeAdapterById
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(declarative_exports);
|
|
25
|
+
var import_registry = require("../registry");
|
|
26
|
+
const COMMON_NOISE = [
|
|
27
|
+
".sr-only",
|
|
28
|
+
"[aria-hidden='true'][class*='icon']",
|
|
29
|
+
"button",
|
|
30
|
+
".social-share",
|
|
31
|
+
".share-buttons",
|
|
32
|
+
".newsletter-signup"
|
|
33
|
+
];
|
|
34
|
+
const SPECS = [
|
|
35
|
+
{
|
|
36
|
+
id: "github",
|
|
37
|
+
hosts: /(^|\.)github\.com$/,
|
|
38
|
+
// Issues and PRs expose a testid; repository landing pages render the README instead.
|
|
39
|
+
content: ["[data-testid='issue-body']", "article.markdown-body", ".markdown-body"],
|
|
40
|
+
remove: [".js-comment-edit-history", ".Details-content--hidden", "clipboard-copy", ...COMMON_NOISE],
|
|
41
|
+
minLength: 30
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
id: "stackoverflow",
|
|
45
|
+
hosts: /(^|\.)(stackoverflow\.com|stackexchange\.com|superuser\.com|serverfault\.com|askubuntu\.com)$/,
|
|
46
|
+
content: ["#mainbar", ".question, .answer"],
|
|
47
|
+
remove: [
|
|
48
|
+
".js-post-menu",
|
|
49
|
+
".post-menu",
|
|
50
|
+
".user-info",
|
|
51
|
+
".votecell",
|
|
52
|
+
".comments-link",
|
|
53
|
+
".js-add-link",
|
|
54
|
+
...COMMON_NOISE
|
|
55
|
+
],
|
|
56
|
+
minLength: 100
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: "npm",
|
|
60
|
+
hosts: /(^|\.)npmjs\.com$/,
|
|
61
|
+
content: ["#readme", "#package-tab-readme", "[class*='markdown']"],
|
|
62
|
+
remove: COMMON_NOISE,
|
|
63
|
+
minLength: 50
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: "zenn",
|
|
67
|
+
hosts: /(^|\.)zenn\.dev$/,
|
|
68
|
+
content: [".znc"],
|
|
69
|
+
remove: COMMON_NOISE,
|
|
70
|
+
minLength: 50
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: "qiita",
|
|
74
|
+
hosts: /(^|\.)qiita\.com$/,
|
|
75
|
+
content: [".it-MdContent", "[class*='mdContent']", "article"],
|
|
76
|
+
remove: [".code-copy", ...COMMON_NOISE],
|
|
77
|
+
minLength: 50
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: "medium",
|
|
81
|
+
hosts: /(^|\.)medium\.com$/,
|
|
82
|
+
// Medium also powers custom domains; the fingerprint catches those.
|
|
83
|
+
fingerprint: (signature) => signature.meta.includes("al:android:app_name=medium"),
|
|
84
|
+
content: ["article section", "article", "[data-testid='storyContent']"],
|
|
85
|
+
remove: ["[data-testid='audioPlayButton']", "[role='separator']", ...COMMON_NOISE],
|
|
86
|
+
minLength: 200
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "substack",
|
|
90
|
+
hosts: /(^|\.)substack\.com$/,
|
|
91
|
+
// Substack's custom domains are far more common than *.substack.com.
|
|
92
|
+
fingerprint: (signature) => signature.classes.has("available-content"),
|
|
93
|
+
content: [".available-content", ".body.markup", ".post-content"],
|
|
94
|
+
remove: [".subscription-widget-wrap", ".button-wrapper", ".paywall", ...COMMON_NOISE],
|
|
95
|
+
minLength: 200
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
id: "note",
|
|
99
|
+
hosts: /(^|\.)note\.com$/,
|
|
100
|
+
content: [".note-common-styles__textnote-body", "[class*='textnote-body']"],
|
|
101
|
+
remove: COMMON_NOISE,
|
|
102
|
+
minLength: 50
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: "hatena",
|
|
106
|
+
hosts: /(^|\.)(hatenablog\.com|hatenadiary\.(com|jp)|hateblo\.jp|hatenastaff\.com)$/,
|
|
107
|
+
fingerprint: (signature) => signature.classes.has("hatenablog-entry") || signature.classes.has("hatena-body"),
|
|
108
|
+
content: [".entry-content"],
|
|
109
|
+
remove: [".entry-footer", ".social-buttons", ".hatena-asin-detail", ...COMMON_NOISE],
|
|
110
|
+
minLength: 100
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: "wordpress",
|
|
114
|
+
// Deliberately fingerprint-only: WordPress powers a large share of the web on its own
|
|
115
|
+
// domains, so keying off a hostname would cover almost none of it.
|
|
116
|
+
fingerprint: (signature) => signature.generator.includes("wordpress") || signature.classes.has("wp-block-post-content") || signature.classes.has("wp-singular"),
|
|
117
|
+
content: [".wp-block-post-content", ".entry-content", ".post-content", "article .content"],
|
|
118
|
+
remove: [".sharedaddy", ".jp-relatedposts", ".wp-block-comments", "#comments", ...COMMON_NOISE],
|
|
119
|
+
minLength: 150
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: "wikipedia",
|
|
123
|
+
hosts: /(^|\.)(wikipedia\.org|wikimedia\.org|wikibooks\.org|wiktionary\.org|wikisource\.org)$/,
|
|
124
|
+
fingerprint: (signature) => signature.classes.has("mw-parser-output"),
|
|
125
|
+
content: [".mw-parser-output", "#mw-content-text"],
|
|
126
|
+
remove: [
|
|
127
|
+
".mw-editsection",
|
|
128
|
+
".navbox",
|
|
129
|
+
".navbox-inner",
|
|
130
|
+
".vertical-navbox",
|
|
131
|
+
".sidebar",
|
|
132
|
+
".side-box",
|
|
133
|
+
".metadata",
|
|
134
|
+
".reflist",
|
|
135
|
+
".refbegin",
|
|
136
|
+
".sistersitebox",
|
|
137
|
+
".ambox",
|
|
138
|
+
".hatnote",
|
|
139
|
+
".shortdescription",
|
|
140
|
+
".mw-jump-link",
|
|
141
|
+
".printfooter",
|
|
142
|
+
".catlinks",
|
|
143
|
+
"#toc",
|
|
144
|
+
".toc",
|
|
145
|
+
"table.mbox-small",
|
|
146
|
+
...COMMON_NOISE
|
|
147
|
+
],
|
|
148
|
+
minLength: 200
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
id: "reddit",
|
|
152
|
+
hosts: /(^|\.)reddit\.com$/,
|
|
153
|
+
content: ["shreddit-post [slot='text-body']", "[data-test-id='post-content']", ".Post"],
|
|
154
|
+
remove: ["faceplate-tracker[noun='comment_action_bar']", "shreddit-comment-action-row", ...COMMON_NOISE],
|
|
155
|
+
// Reddit renders most of a thread into shadow roots that never reach the serialised HTML,
|
|
156
|
+
// so a weak match here is worse than generic extraction. Decline unless a substantial
|
|
157
|
+
// post body is actually present in the document.
|
|
158
|
+
minLength: 600
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
id: "docusaurus",
|
|
162
|
+
fingerprint: (signature) => signature.classes.has("theme-doc-markdown") || signature.classes.has("docusaurus-mt-lg"),
|
|
163
|
+
content: [".theme-doc-markdown", "article .markdown"],
|
|
164
|
+
remove: [".theme-doc-toc-mobile", ".pagination-nav", ".theme-doc-version-banner", ...COMMON_NOISE],
|
|
165
|
+
minLength: 150
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
id: "vitepress",
|
|
169
|
+
fingerprint: (signature) => signature.classes.has("vp-doc") || signature.classes.has("VPDoc"),
|
|
170
|
+
content: [".vp-doc > div", ".vp-doc", ".VPDoc .content-container"],
|
|
171
|
+
remove: [".VPDocFooter", ".vp-doc-footer", ".header-anchor", ...COMMON_NOISE],
|
|
172
|
+
minLength: 150
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
id: "mkdocs",
|
|
176
|
+
fingerprint: (signature) => signature.classes.has("md-content__inner"),
|
|
177
|
+
content: [".md-content__inner", "[data-md-component='content']"],
|
|
178
|
+
remove: [".md-source-file", ".md-feedback", ".headerlink", ...COMMON_NOISE],
|
|
179
|
+
minLength: 150
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
id: "readthedocs",
|
|
183
|
+
fingerprint: (signature) => signature.classes.has("rst-content"),
|
|
184
|
+
content: [".rst-content", "[role='main']"],
|
|
185
|
+
remove: [".headerlink", ".rst-footer-buttons", ".wy-breadcrumbs", ...COMMON_NOISE],
|
|
186
|
+
minLength: 150
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
id: "gitbook",
|
|
190
|
+
fingerprint: (signature) => signature.classes.has("gitbook-root"),
|
|
191
|
+
content: ["[data-testid='page.contentEditor']", "main article"],
|
|
192
|
+
remove: COMMON_NOISE,
|
|
193
|
+
minLength: 150
|
|
194
|
+
}
|
|
195
|
+
];
|
|
196
|
+
const DECLARATIVE_ADAPTERS = SPECS.map(import_registry.defineSelectorAdapter);
|
|
197
|
+
const declarativeAdapterById = (id) => DECLARATIVE_ADAPTERS.find((adapter) => adapter.id === id);
|
|
198
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
199
|
+
0 && (module.exports = {
|
|
200
|
+
DECLARATIVE_ADAPTERS,
|
|
201
|
+
declarativeAdapterById
|
|
202
|
+
});
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var hackernews_exports = {};
|
|
20
|
+
__export(hackernews_exports, {
|
|
21
|
+
hackernewsAdapter: () => hackernewsAdapter
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(hackernews_exports);
|
|
24
|
+
var import_hast_util_select = require("hast-util-select");
|
|
25
|
+
var import_hast_fast = require("../../utils/hast-fast");
|
|
26
|
+
const MAX_QUOTE_DEPTH = 6;
|
|
27
|
+
const text = (value) => ({ type: "text", value });
|
|
28
|
+
const element = (tagName, children) => ({
|
|
29
|
+
type: "element",
|
|
30
|
+
tagName,
|
|
31
|
+
properties: {},
|
|
32
|
+
children
|
|
33
|
+
});
|
|
34
|
+
const commentDepth = (row) => {
|
|
35
|
+
const cell = (0, import_hast_util_select.select)("td.ind", row);
|
|
36
|
+
if (!cell) {
|
|
37
|
+
return 0;
|
|
38
|
+
}
|
|
39
|
+
const indent = (0, import_hast_fast.numericProperty)(cell, "indent");
|
|
40
|
+
if (indent !== void 0) {
|
|
41
|
+
return indent;
|
|
42
|
+
}
|
|
43
|
+
const spacer = (0, import_hast_util_select.select)("img", cell);
|
|
44
|
+
const width = spacer ? (0, import_hast_fast.numericProperty)(spacer, "width") : void 0;
|
|
45
|
+
return width === void 0 ? 0 : Math.round(width / 40);
|
|
46
|
+
};
|
|
47
|
+
const nest = (content, depth) => {
|
|
48
|
+
let current = content;
|
|
49
|
+
for (let level = 0; level < Math.min(depth, MAX_QUOTE_DEPTH); level++) {
|
|
50
|
+
current = [element("blockquote", current)];
|
|
51
|
+
}
|
|
52
|
+
return current[0];
|
|
53
|
+
};
|
|
54
|
+
const storyNodes = (root) => {
|
|
55
|
+
const nodes = [];
|
|
56
|
+
const titleLink = (0, import_hast_util_select.select)(".titleline > a", root);
|
|
57
|
+
if (titleLink) {
|
|
58
|
+
nodes.push(element("h1", [...titleLink.children]));
|
|
59
|
+
const href = (0, import_hast_fast.stringProperty)(titleLink, "href");
|
|
60
|
+
if (href && /^https?:/.test(href)) {
|
|
61
|
+
nodes.push(element("p", [{ ...titleLink, children: [text(href)] }]));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
const topText = (0, import_hast_util_select.select)(".toptext", root);
|
|
65
|
+
if (topText) {
|
|
66
|
+
nodes.push(element("div", [...topText.children]));
|
|
67
|
+
}
|
|
68
|
+
return nodes;
|
|
69
|
+
};
|
|
70
|
+
const commentNodes = (root) => {
|
|
71
|
+
const nodes = [];
|
|
72
|
+
for (const row of (0, import_hast_util_select.selectAll)("tr.comtr, tr.athing.comtr", root)) {
|
|
73
|
+
const body = (0, import_hast_util_select.select)(".commtext", row);
|
|
74
|
+
if (!body) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const author = (0, import_hast_util_select.select)(".hnuser", row);
|
|
78
|
+
const header = author ? [element("strong", [...author.children])] : [];
|
|
79
|
+
const content = [
|
|
80
|
+
...header.length > 0 ? [element("p", header)] : [],
|
|
81
|
+
element("div", [...body.children])
|
|
82
|
+
];
|
|
83
|
+
nodes.push(nest(content, commentDepth(row)));
|
|
84
|
+
}
|
|
85
|
+
return nodes;
|
|
86
|
+
};
|
|
87
|
+
const hackernewsAdapter = {
|
|
88
|
+
id: "hackernews",
|
|
89
|
+
matches: ({ url }) => {
|
|
90
|
+
if (!url) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
return /(^|\.)ycombinator\.com$/.test(new URL(url).hostname);
|
|
95
|
+
} catch {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
matchesFingerprint: ({ signature }) => Boolean(signature?.ids.has("hnmain") || signature?.classes.has("fatitem")),
|
|
100
|
+
extract: ({ hast }) => {
|
|
101
|
+
const story = storyNodes(hast);
|
|
102
|
+
const comments = commentNodes(hast);
|
|
103
|
+
if (story.length === 0 && comments.length === 0) {
|
|
104
|
+
return void 0;
|
|
105
|
+
}
|
|
106
|
+
const children = [...story];
|
|
107
|
+
if (comments.length > 0) {
|
|
108
|
+
children.push(element("h2", [text("Comments")]));
|
|
109
|
+
children.push(...comments);
|
|
110
|
+
}
|
|
111
|
+
return { type: "root", children };
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
115
|
+
0 && (module.exports = {
|
|
116
|
+
hackernewsAdapter
|
|
117
|
+
});
|