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.
Files changed (154) hide show
  1. package/README.md +63 -1
  2. package/dist/adapters/index.js +58 -0
  3. package/dist/adapters/registry.js +149 -0
  4. package/dist/adapters/sites/declarative.js +178 -0
  5. package/dist/adapters/sites/hackernews.js +94 -0
  6. package/dist/adapters/sites/youtube.js +165 -0
  7. package/dist/adapters/types.js +0 -0
  8. package/dist/bin.js +3197 -402
  9. package/dist/cjs/adapters/index.js +86 -0
  10. package/dist/cjs/adapters/registry.js +178 -0
  11. package/dist/cjs/adapters/sites/declarative.js +202 -0
  12. package/dist/cjs/adapters/sites/hackernews.js +117 -0
  13. package/dist/cjs/adapters/sites/youtube.js +191 -0
  14. package/dist/cjs/adapters/types.js +16 -0
  15. package/dist/cjs/constants.js +2 -2
  16. package/dist/cjs/extractors/index.js +5 -0
  17. package/dist/cjs/extractors/lib/constants.js +186 -0
  18. package/dist/cjs/extractors/lib/sanitize.js +425 -0
  19. package/dist/cjs/extractors/lib/score.js +264 -0
  20. package/dist/cjs/extractors/lib/terminators.js +131 -0
  21. package/dist/cjs/extractors/lib/ui-chrome.js +119 -0
  22. package/dist/cjs/extractors/pipeExtractors.js +12 -9
  23. package/dist/cjs/extractors/presets/auto.js +44 -0
  24. package/dist/cjs/extractors/presets/minimal-filter.js +27 -48
  25. package/dist/cjs/extractors/presets/takumi.js +84 -122
  26. package/dist/cjs/html-to-markdown.js +44 -7
  27. package/dist/cjs/html-to-mdast.js +9 -1
  28. package/dist/cjs/index.js +31 -2
  29. package/dist/cjs/mdast-handlers/custom-a-handler.js +25 -9
  30. package/dist/cjs/mdast-handlers/custom-img-handler.js +23 -1
  31. package/dist/cjs/mdast-handlers/custom-table-handler.js +16 -0
  32. package/dist/cjs/mdast-handlers/definition-list-handler.js +99 -0
  33. package/dist/cjs/mdast-handlers/math-handler.js +12 -3
  34. package/dist/cjs/mdast-handlers/sup-sub-handler.js +39 -0
  35. package/dist/cjs/metadata/index.js +223 -0
  36. package/dist/cjs/normalize/index.js +168 -0
  37. package/dist/cjs/platform/client.js +147 -0
  38. package/dist/cjs/platform/error.js +36 -0
  39. package/dist/cjs/platform/fetch.js +37 -0
  40. package/dist/cjs/platform/index.js +40 -0
  41. package/dist/cjs/platform/types.js +34 -0
  42. package/dist/cjs/utils/hast-fast.js +284 -0
  43. package/dist/constants.js +2 -2
  44. package/dist/extractors/index.js +3 -0
  45. package/dist/extractors/lib/constants.js +150 -0
  46. package/dist/extractors/lib/sanitize.js +415 -0
  47. package/dist/extractors/lib/score.js +242 -0
  48. package/dist/extractors/lib/terminators.js +107 -0
  49. package/dist/extractors/lib/ui-chrome.js +96 -0
  50. package/dist/extractors/pipeExtractors.js +12 -9
  51. package/dist/extractors/presets/auto.js +20 -0
  52. package/dist/extractors/presets/minimal-filter.js +35 -47
  53. package/dist/extractors/presets/takumi.js +91 -122
  54. package/dist/html-to-markdown.js +42 -6
  55. package/dist/html-to-mdast.js +9 -1
  56. package/dist/index.js +31 -2
  57. package/dist/mdast-handlers/custom-a-handler.js +25 -9
  58. package/dist/mdast-handlers/custom-img-handler.js +23 -1
  59. package/dist/mdast-handlers/custom-table-handler.js +16 -0
  60. package/dist/mdast-handlers/definition-list-handler.js +76 -0
  61. package/dist/mdast-handlers/math-handler.js +12 -3
  62. package/dist/mdast-handlers/sup-sub-handler.js +16 -0
  63. package/dist/metadata/index.js +198 -0
  64. package/dist/normalize/index.js +149 -0
  65. package/dist/platform/client.js +125 -0
  66. package/dist/platform/error.js +13 -0
  67. package/dist/platform/fetch.js +14 -0
  68. package/dist/platform/index.js +19 -0
  69. package/dist/platform/types.js +9 -0
  70. package/dist/types/adapters/index.d.ts +24 -0
  71. package/dist/types/adapters/index.js.map +1 -0
  72. package/dist/types/adapters/registry.d.ts +35 -0
  73. package/dist/types/adapters/registry.js.map +1 -0
  74. package/dist/types/adapters/sites/declarative.d.ts +13 -0
  75. package/dist/types/adapters/sites/declarative.js.map +1 -0
  76. package/dist/types/adapters/sites/hackernews.d.ts +13 -0
  77. package/dist/types/adapters/sites/hackernews.js.map +1 -0
  78. package/dist/types/adapters/sites/youtube.d.ts +31 -0
  79. package/dist/types/adapters/sites/youtube.js.map +1 -0
  80. package/dist/types/adapters/types.d.ts +99 -0
  81. package/dist/types/adapters/types.js.map +1 -0
  82. package/dist/types/cli/bin.js.map +1 -1
  83. package/dist/types/cli/commands/skill/content.d.ts +9 -0
  84. package/dist/types/cli/commands/skill/content.js.map +1 -0
  85. package/dist/types/cli/commands/skill/index.d.ts +19 -0
  86. package/dist/types/cli/commands/skill/index.js.map +1 -0
  87. package/dist/types/cli/commands/webforai/interactive.d.ts +7 -0
  88. package/dist/types/cli/commands/webforai/interactive.js.map +1 -0
  89. package/dist/types/cli/commands/webforai/loadHtml.js.map +1 -1
  90. package/dist/types/cli/commands/webforai/options.d.ts +55 -0
  91. package/dist/types/cli/commands/webforai/options.js.map +1 -0
  92. package/dist/types/cli/commands/webforai/run.d.ts +10 -0
  93. package/dist/types/cli/commands/webforai/run.js.map +1 -0
  94. package/dist/types/cli/constants.d.ts +14 -4
  95. package/dist/types/cli/constants.js.map +1 -1
  96. package/dist/types/cli/helpers/selectExtractMode.js.map +1 -1
  97. package/dist/types/cli/helpers/selectLoader.js.map +1 -1
  98. package/dist/types/constants.d.ts +7 -1
  99. package/dist/types/constants.js.map +1 -1
  100. package/dist/types/extractors/index.d.ts +1 -0
  101. package/dist/types/extractors/index.js.map +1 -1
  102. package/dist/types/extractors/lib/constants.d.ts +81 -0
  103. package/dist/types/extractors/lib/constants.js.map +1 -0
  104. package/dist/types/extractors/lib/sanitize.d.ts +66 -0
  105. package/dist/types/extractors/lib/sanitize.js.map +1 -0
  106. package/dist/types/extractors/lib/score.d.ts +85 -0
  107. package/dist/types/extractors/lib/score.js.map +1 -0
  108. package/dist/types/extractors/lib/terminators.d.ts +26 -0
  109. package/dist/types/extractors/lib/terminators.js.map +1 -0
  110. package/dist/types/extractors/lib/ui-chrome.d.ts +18 -0
  111. package/dist/types/extractors/lib/ui-chrome.js.map +1 -0
  112. package/dist/types/extractors/pipeExtractors.d.ts +5 -0
  113. package/dist/types/extractors/pipeExtractors.js.map +1 -1
  114. package/dist/types/extractors/presets/auto.d.ts +30 -0
  115. package/dist/types/extractors/presets/auto.js.map +1 -0
  116. package/dist/types/extractors/presets/minimal-filter.d.ts +10 -2
  117. package/dist/types/extractors/presets/minimal-filter.js.map +1 -1
  118. package/dist/types/extractors/presets/takumi.d.ts +19 -3
  119. package/dist/types/extractors/presets/takumi.js.map +1 -1
  120. package/dist/types/extractors/types.d.ts +8 -0
  121. package/dist/types/html-to-markdown.d.ts +38 -0
  122. package/dist/types/html-to-markdown.js.map +1 -1
  123. package/dist/types/html-to-mdast.d.ts +11 -0
  124. package/dist/types/html-to-mdast.js.map +1 -1
  125. package/dist/types/index.d.ts +6 -3
  126. package/dist/types/index.js.map +1 -1
  127. package/dist/types/mdast-handlers/custom-a-handler.js.map +1 -1
  128. package/dist/types/mdast-handlers/custom-img-handler.js.map +1 -1
  129. package/dist/types/mdast-handlers/custom-table-handler.js.map +1 -1
  130. package/dist/types/mdast-handlers/definition-list-handler.d.ts +13 -0
  131. package/dist/types/mdast-handlers/definition-list-handler.js.map +1 -0
  132. package/dist/types/mdast-handlers/math-handler.js.map +1 -1
  133. package/dist/types/mdast-handlers/sup-sub-handler.d.ts +10 -0
  134. package/dist/types/mdast-handlers/sup-sub-handler.js.map +1 -0
  135. package/dist/types/metadata/index.d.ts +47 -0
  136. package/dist/types/metadata/index.js.map +1 -0
  137. package/dist/types/normalize/index.d.ts +53 -0
  138. package/dist/types/normalize/index.js.map +1 -0
  139. package/dist/types/platform/client.d.ts +54 -0
  140. package/dist/types/platform/client.js.map +1 -0
  141. package/dist/types/platform/error.d.ts +20 -0
  142. package/dist/types/platform/error.js.map +1 -0
  143. package/dist/types/platform/fetch.d.ts +34 -0
  144. package/dist/types/platform/fetch.js.map +1 -0
  145. package/dist/types/platform/index.d.ts +4 -0
  146. package/dist/types/platform/index.js.map +1 -0
  147. package/dist/types/platform/types.d.ts +135 -0
  148. package/dist/types/platform/types.js.map +1 -0
  149. package/dist/types/utils/hast-fast.d.ts +101 -0
  150. package/dist/types/utils/hast-fast.js.map +1 -0
  151. package/dist/utils/hast-fast.js +246 -0
  152. package/package.json +10 -3
  153. package/dist/types/cli/commands/webforai/index.d.ts +0 -6
  154. package/dist/types/cli/commands/webforai/index.js.map +0 -1
@@ -0,0 +1,165 @@
1
+ // src/adapters/sites/youtube.ts
2
+ import { collectElements, isElement } from "../../utils/hast-fast.js";
3
+ var findObjectEnd = (source, start) => {
4
+ let depth = 0;
5
+ let inString = false;
6
+ let escaped = false;
7
+ for (let index = start; index < source.length; index++) {
8
+ const character = source[index];
9
+ if (escaped) {
10
+ escaped = false;
11
+ } else if (character === "\\") {
12
+ escaped = true;
13
+ } else if (character === '"') {
14
+ inString = !inString;
15
+ } else if (!inString) {
16
+ if (character === "{") {
17
+ depth += 1;
18
+ } else if (character === "}" && --depth === 0) {
19
+ return index + 1;
20
+ }
21
+ }
22
+ }
23
+ return -1;
24
+ };
25
+ var extractAssignedJson = (source, name) => {
26
+ const markerIndex = source.indexOf(`${name} =`);
27
+ if (markerIndex === -1) {
28
+ return void 0;
29
+ }
30
+ const start = source.indexOf("{", markerIndex);
31
+ if (start === -1) {
32
+ return void 0;
33
+ }
34
+ const end = findObjectEnd(source, start);
35
+ if (end === -1) {
36
+ return void 0;
37
+ }
38
+ try {
39
+ return JSON.parse(source.slice(start, end));
40
+ } catch {
41
+ return void 0;
42
+ }
43
+ };
44
+ var scriptText = (root) => collectElements(root, (element2) => element2.tagName === "script").map(
45
+ (script) => script.children.map((child) => child.type === "text" ? child.value : "").join("")
46
+ );
47
+ var findPlayerResponse = (root) => {
48
+ for (const source of scriptText(root)) {
49
+ if (!source.includes("ytInitialPlayerResponse")) {
50
+ continue;
51
+ }
52
+ const parsed = extractAssignedJson(source, "ytInitialPlayerResponse");
53
+ if (parsed && typeof parsed === "object") {
54
+ return parsed;
55
+ }
56
+ }
57
+ return void 0;
58
+ };
59
+ var youtubeCaptionTracks = (root) => {
60
+ const player = findPlayerResponse(root);
61
+ const renderer = player?.captions?.playerCaptionsTracklistRenderer;
62
+ const tracks = renderer?.captionTracks;
63
+ if (!Array.isArray(tracks)) {
64
+ return [];
65
+ }
66
+ return tracks.flatMap((track) => {
67
+ const url = typeof track.baseUrl === "string" ? track.baseUrl : void 0;
68
+ const languageCode = typeof track.languageCode === "string" ? track.languageCode : void 0;
69
+ if (!(url && languageCode)) {
70
+ return [];
71
+ }
72
+ const name = track.name?.simpleText;
73
+ return [
74
+ {
75
+ url,
76
+ languageCode,
77
+ name: typeof name === "string" ? name : void 0,
78
+ isAutomatic: track.kind === "asr"
79
+ }
80
+ ];
81
+ });
82
+ };
83
+ var text = (value) => ({ type: "text", value });
84
+ var element = (tagName, children) => ({
85
+ type: "element",
86
+ tagName,
87
+ properties: {},
88
+ children
89
+ });
90
+ var heading = (depth, value) => element(`h${depth}`, [text(value)]);
91
+ var paragraph = (value) => element("p", [text(value)]);
92
+ var descriptionNodes = (description) => description.split(/\n{2,}/).map((block) => block.trim()).filter((block) => block.length > 0).map(
93
+ (block) => element(
94
+ "p",
95
+ block.split("\n").flatMap((line, index) => index === 0 ? [text(line)] : [element("br", []), text(line)])
96
+ )
97
+ );
98
+ var formatDuration = (seconds) => {
99
+ const hours = Math.floor(seconds / 3600);
100
+ const minutes = Math.floor(seconds % 3600 / 60);
101
+ const remainder = seconds % 60;
102
+ const pad = (value) => String(value).padStart(2, "0");
103
+ return hours > 0 ? `${hours}:${pad(minutes)}:${pad(remainder)}` : `${minutes}:${pad(remainder)}`;
104
+ };
105
+ var metadataList = (details) => {
106
+ const items = [];
107
+ if (details.author) {
108
+ items.push(element("li", [text(`Channel: ${details.author}`)]));
109
+ }
110
+ const seconds = Number(details.lengthSeconds);
111
+ if (Number.isFinite(seconds) && seconds > 0) {
112
+ items.push(element("li", [text(`Duration: ${formatDuration(seconds)}`)]));
113
+ }
114
+ const views = Number(details.viewCount);
115
+ if (Number.isFinite(views) && views > 0) {
116
+ items.push(element("li", [text(`Views: ${views.toLocaleString("en-US")}`)]));
117
+ }
118
+ return items.length > 0 ? element("ul", items) : void 0;
119
+ };
120
+ var youtubeAdapter = {
121
+ id: "youtube",
122
+ matches: ({ url }) => {
123
+ if (!url) {
124
+ return false;
125
+ }
126
+ try {
127
+ return /(^|\.)(youtube\.com|youtu\.be|youtube-nocookie\.com)$/.test(new URL(url).hostname);
128
+ } catch {
129
+ return false;
130
+ }
131
+ },
132
+ // Scanning every script body for the JSON blob would cost a full traversal on every page, so
133
+ // the fallback keys off markers the signature already collected.
134
+ matchesFingerprint: ({ signature }) => Boolean(signature?.ids.has("movie_player") || signature?.classes.has("ytd-app")),
135
+ extract: ({ hast }) => {
136
+ const player = findPlayerResponse(hast);
137
+ const details = player?.videoDetails;
138
+ if (!details?.title) {
139
+ return void 0;
140
+ }
141
+ const children = [heading(1, details.title)];
142
+ const metadata = metadataList(details);
143
+ if (metadata) {
144
+ children.push(metadata);
145
+ }
146
+ const description = details.shortDescription?.trim();
147
+ if (description) {
148
+ children.push(heading(2, "Description"));
149
+ children.push(...descriptionNodes(description));
150
+ }
151
+ const tracks = youtubeCaptionTracks(hast);
152
+ if (tracks.length > 0) {
153
+ const languages = [...new Set(tracks.map((track) => track.languageCode))].sort();
154
+ children.push(paragraph(`Captions available: ${languages.join(", ")}`));
155
+ }
156
+ return { type: "root", children };
157
+ }
158
+ };
159
+ var isYoutubeElement = isElement;
160
+ export {
161
+ extractAssignedJson,
162
+ isYoutubeElement,
163
+ youtubeAdapter,
164
+ youtubeCaptionTracks
165
+ };
File without changes