@taodigital/crawler 0.0.0-stage → 1.2.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 (494) hide show
  1. package/Dockerfile +82 -0
  2. package/README.md +10 -2
  3. package/dist/accessibility-auditor.d.ts +29 -0
  4. package/dist/accessibility-auditor.js +57 -0
  5. package/dist/accessibility-auditor.js.map +7 -0
  6. package/dist/accessibility-tree-crawler.d.ts +44 -0
  7. package/dist/accessibility-tree-crawler.js +156 -0
  8. package/dist/accessibility-tree-crawler.js.map +7 -0
  9. package/dist/advanced-ui-probes.d.ts +47 -0
  10. package/dist/advanced-ui-probes.js +310 -0
  11. package/dist/advanced-ui-probes.js.map +7 -0
  12. package/dist/ai-login.d.ts +32 -0
  13. package/dist/ai-login.js +250 -0
  14. package/dist/ai-login.js.map +7 -0
  15. package/dist/auth-token-rotator.d.ts +47 -0
  16. package/dist/auth-token-rotator.js +58 -0
  17. package/dist/auth-token-rotator.js.map +7 -0
  18. package/dist/auth.d.ts +20 -0
  19. package/dist/auth.js +348 -0
  20. package/dist/auth.js.map +7 -0
  21. package/dist/browser-extension.d.ts +37 -0
  22. package/dist/browser-extension.js +113 -0
  23. package/dist/browser-extension.js.map +7 -0
  24. package/dist/captcha-solver.d.ts +16 -0
  25. package/dist/captcha-solver.js +105 -0
  26. package/dist/captcha-solver.js.map +7 -0
  27. package/dist/color-contrast.d.ts +30 -0
  28. package/dist/color-contrast.js +78 -0
  29. package/dist/color-contrast.js.map +7 -0
  30. package/dist/content-chunker.d.ts +18 -0
  31. package/dist/content-chunker.js +152 -0
  32. package/dist/content-chunker.js.map +7 -0
  33. package/dist/content-dedup.d.ts +23 -0
  34. package/dist/content-dedup.js +60 -0
  35. package/dist/content-dedup.js.map +7 -0
  36. package/dist/cookie-consent.d.ts +25 -0
  37. package/dist/cookie-consent.js +78 -0
  38. package/dist/cookie-consent.js.map +7 -0
  39. package/dist/cookie-jar.d.ts +20 -0
  40. package/dist/cookie-jar.js +61 -0
  41. package/dist/cookie-jar.js.map +7 -0
  42. package/dist/crawl-session-manager.d.ts +44 -0
  43. package/dist/crawl-session-manager.js +145 -0
  44. package/dist/crawl-session-manager.js.map +7 -0
  45. package/dist/crawler.d.ts +233 -0
  46. package/dist/crawler.js +6239 -0
  47. package/dist/crawler.js.map +7 -0
  48. package/dist/crud-interaction.d.ts +31 -0
  49. package/dist/crud-interaction.js +264 -0
  50. package/dist/crud-interaction.js.map +7 -0
  51. package/dist/custom-js-injector.d.ts +42 -0
  52. package/dist/custom-js-injector.js +50 -0
  53. package/dist/custom-js-injector.js.map +7 -0
  54. package/dist/dark-mode-capture.d.ts +23 -0
  55. package/dist/dark-mode-capture.js +75 -0
  56. package/dist/dark-mode-capture.js.map +7 -0
  57. package/dist/dead-link-detector.d.ts +37 -0
  58. package/dist/dead-link-detector.js +50 -0
  59. package/dist/dead-link-detector.js.map +7 -0
  60. package/dist/dropdown-enumerator.d.ts +20 -0
  61. package/dist/dropdown-enumerator.js +230 -0
  62. package/dist/dropdown-enumerator.js.map +7 -0
  63. package/dist/element-hash.d.ts +9 -0
  64. package/dist/element-hash.js +9 -0
  65. package/dist/element-hash.js.map +7 -0
  66. package/dist/email-otp.d.ts +42 -0
  67. package/dist/email-otp.js +177 -0
  68. package/dist/email-otp.js.map +7 -0
  69. package/dist/engine-router.d.ts +47 -0
  70. package/dist/engine-router.js +94 -0
  71. package/dist/engine-router.js.map +7 -0
  72. package/dist/export/bulk-export.d.ts +26 -0
  73. package/dist/export/bulk-export.js +76 -0
  74. package/dist/export/bulk-export.js.map +7 -0
  75. package/dist/export/vector-export.d.ts +76 -0
  76. package/dist/export/vector-export.js +85 -0
  77. package/dist/export/vector-export.js.map +7 -0
  78. package/dist/extractors/advanced.d.ts +64 -0
  79. package/dist/extractors/advanced.js +265 -0
  80. package/dist/extractors/advanced.js.map +7 -0
  81. package/dist/extractors/artifact-envelope.d.ts +63 -0
  82. package/dist/extractors/artifact-envelope.js +63 -0
  83. package/dist/extractors/artifact-envelope.js.map +7 -0
  84. package/dist/extractors/branding-extractor.d.ts +46 -0
  85. package/dist/extractors/branding-extractor.js +104 -0
  86. package/dist/extractors/branding-extractor.js.map +7 -0
  87. package/dist/extractors/summary-extractor.d.ts +10 -0
  88. package/dist/extractors/summary-extractor.js +36 -0
  89. package/dist/extractors/summary-extractor.js.map +7 -0
  90. package/dist/failure-analysis-agent.d.ts +16 -0
  91. package/dist/failure-analysis-agent.js +42 -0
  92. package/dist/failure-analysis-agent.js.map +7 -0
  93. package/dist/feature-flag-detector.d.ts +30 -0
  94. package/dist/feature-flag-detector.js +55 -0
  95. package/dist/feature-flag-detector.js.map +7 -0
  96. package/dist/filter-pagination-crawler.d.ts +52 -0
  97. package/dist/filter-pagination-crawler.js +299 -0
  98. package/dist/filter-pagination-crawler.js.map +7 -0
  99. package/dist/form-detector.d.ts +34 -0
  100. package/dist/form-detector.js +58 -0
  101. package/dist/form-detector.js.map +7 -0
  102. package/dist/frontier.d.ts +40 -0
  103. package/dist/frontier.js +103 -0
  104. package/dist/frontier.js.map +7 -0
  105. package/dist/gap-pass.d.ts +36 -0
  106. package/dist/gap-pass.js +115 -0
  107. package/dist/gap-pass.js.map +7 -0
  108. package/dist/graphql-detector.d.ts +39 -0
  109. package/dist/graphql-detector.js +86 -0
  110. package/dist/graphql-detector.js.map +7 -0
  111. package/dist/http-engine.d.ts +80 -0
  112. package/dist/http-engine.js +318 -0
  113. package/dist/http-engine.js.map +7 -0
  114. package/dist/incremental-diff.d.ts +116 -0
  115. package/dist/incremental-diff.js +137 -0
  116. package/dist/incremental-diff.js.map +7 -0
  117. package/dist/index.d.ts +52 -0
  118. package/dist/index.js +83 -0
  119. package/dist/index.js.map +7 -0
  120. package/dist/input-fuzzer.d.ts +30 -0
  121. package/dist/input-fuzzer.js +105 -0
  122. package/dist/input-fuzzer.js.map +7 -0
  123. package/dist/interactive-probe.d.ts +144 -0
  124. package/dist/interactive-probe.js +865 -0
  125. package/dist/interactive-probe.js.map +7 -0
  126. package/dist/job-queue.d.ts +297 -0
  127. package/dist/job-queue.js +3812 -0
  128. package/dist/job-queue.js.map +7 -0
  129. package/dist/js-coverage.d.ts +29 -0
  130. package/dist/js-coverage.js +56 -0
  131. package/dist/js-coverage.js.map +7 -0
  132. package/dist/js-router-detector.d.ts +17 -0
  133. package/dist/js-router-detector.js +90 -0
  134. package/dist/js-router-detector.js.map +7 -0
  135. package/dist/language-detector.d.ts +22 -0
  136. package/dist/language-detector.js +57 -0
  137. package/dist/language-detector.js.map +7 -0
  138. package/dist/link-classifier.d.ts +23 -0
  139. package/dist/link-classifier.js +40 -0
  140. package/dist/link-classifier.js.map +7 -0
  141. package/dist/live-view.d.ts +36 -0
  142. package/dist/live-view.js +105 -0
  143. package/dist/live-view.js.map +7 -0
  144. package/dist/locator-extractor.d.ts +46 -0
  145. package/dist/locator-extractor.js +220 -0
  146. package/dist/locator-extractor.js.map +7 -0
  147. package/dist/logger.d.ts +2 -0
  148. package/dist/logger.js +10 -0
  149. package/dist/logger.js.map +7 -0
  150. package/dist/markdown-extract.d.ts +8 -0
  151. package/dist/markdown-extract.js +54 -0
  152. package/dist/markdown-extract.js.map +7 -0
  153. package/dist/multi-context-handler.d.ts +55 -0
  154. package/dist/multi-context-handler.js +182 -0
  155. package/dist/multi-context-handler.js.map +7 -0
  156. package/dist/native-crawler.d.ts +69 -0
  157. package/dist/native-crawler.js +839 -0
  158. package/dist/native-crawler.js.map +7 -0
  159. package/dist/nested-window-crawler.d.ts +41 -0
  160. package/dist/nested-window-crawler.js +172 -0
  161. package/dist/nested-window-crawler.js.map +7 -0
  162. package/dist/network-action-correlator.d.ts +47 -0
  163. package/dist/network-action-correlator.js +209 -0
  164. package/dist/network-action-correlator.js.map +7 -0
  165. package/dist/network-observer.d.ts +49 -0
  166. package/dist/network-observer.js +149 -0
  167. package/dist/network-observer.js.map +7 -0
  168. package/dist/network-throttle.d.ts +25 -0
  169. package/dist/network-throttle.js +34 -0
  170. package/dist/network-throttle.js.map +7 -0
  171. package/dist/openapi-generator.d.ts +49 -0
  172. package/dist/openapi-generator.js +89 -0
  173. package/dist/openapi-generator.js.map +7 -0
  174. package/dist/pdf-extractor.d.ts +28 -0
  175. package/dist/pdf-extractor.js +81 -0
  176. package/dist/pdf-extractor.js.map +7 -0
  177. package/dist/performance-metrics-collector.d.ts +50 -0
  178. package/dist/performance-metrics-collector.js +155 -0
  179. package/dist/performance-metrics-collector.js.map +7 -0
  180. package/dist/performance-metrics.d.ts +52 -0
  181. package/dist/performance-metrics.js +83 -0
  182. package/dist/performance-metrics.js.map +7 -0
  183. package/dist/phash.d.ts +50 -0
  184. package/dist/phash.js +136 -0
  185. package/dist/phash.js.map +7 -0
  186. package/dist/pii-scrubber.d.ts +21 -0
  187. package/dist/pii-scrubber.js +75 -0
  188. package/dist/pii-scrubber.js.map +7 -0
  189. package/dist/playwright-recorder.d.ts +39 -0
  190. package/dist/playwright-recorder.js +123 -0
  191. package/dist/playwright-recorder.js.map +7 -0
  192. package/dist/policies/crawl-safety.d.ts +9 -0
  193. package/dist/policies/crawl-safety.js +41 -0
  194. package/dist/policies/crawl-safety.js.map +7 -0
  195. package/dist/profiles/domain-profile.d.ts +19 -0
  196. package/dist/profiles/domain-profile.js +160 -0
  197. package/dist/profiles/domain-profile.js.map +7 -0
  198. package/dist/proxy.d.ts +50 -0
  199. package/dist/proxy.js +165 -0
  200. package/dist/proxy.js.map +7 -0
  201. package/dist/rate-limiter.d.ts +31 -0
  202. package/dist/rate-limiter.js +64 -0
  203. package/dist/rate-limiter.js.map +7 -0
  204. package/dist/redirect-tracker.d.ts +37 -0
  205. package/dist/redirect-tracker.js +65 -0
  206. package/dist/redirect-tracker.js.map +7 -0
  207. package/dist/redis-frontier.d.ts +48 -0
  208. package/dist/redis-frontier.js +126 -0
  209. package/dist/redis-frontier.js.map +7 -0
  210. package/dist/redis-queue.d.ts +48 -0
  211. package/dist/redis-queue.js +165 -0
  212. package/dist/redis-queue.js.map +7 -0
  213. package/dist/response-cache.d.ts +38 -0
  214. package/dist/response-cache.js +140 -0
  215. package/dist/response-cache.js.map +7 -0
  216. package/dist/responsive-detector.d.ts +29 -0
  217. package/dist/responsive-detector.js +46 -0
  218. package/dist/responsive-detector.js.map +7 -0
  219. package/dist/retry-policy.d.ts +20 -0
  220. package/dist/retry-policy.js +54 -0
  221. package/dist/retry-policy.js.map +7 -0
  222. package/dist/robots-txt.d.ts +9 -0
  223. package/dist/robots-txt.js +77 -0
  224. package/dist/robots-txt.js.map +7 -0
  225. package/dist/screen-reader.d.ts +15 -0
  226. package/dist/screen-reader.js +48 -0
  227. package/dist/screen-reader.js.map +7 -0
  228. package/dist/screenshot-masker.d.ts +28 -0
  229. package/dist/screenshot-masker.js +62 -0
  230. package/dist/screenshot-masker.js.map +7 -0
  231. package/dist/seo-checker.d.ts +33 -0
  232. package/dist/seo-checker.js +91 -0
  233. package/dist/seo-checker.js.map +7 -0
  234. package/dist/service-worker-interceptor.d.ts +36 -0
  235. package/dist/service-worker-interceptor.js +136 -0
  236. package/dist/service-worker-interceptor.js.map +7 -0
  237. package/dist/session-capture.d.ts +39 -0
  238. package/dist/session-capture.js +274 -0
  239. package/dist/session-capture.js.map +7 -0
  240. package/dist/session-export.d.ts +49 -0
  241. package/dist/session-export.js +117 -0
  242. package/dist/session-export.js.map +7 -0
  243. package/dist/shadow-dom-crawler.d.ts +35 -0
  244. package/dist/shadow-dom-crawler.js +132 -0
  245. package/dist/shadow-dom-crawler.js.map +7 -0
  246. package/dist/sitemap-writer.d.ts +21 -0
  247. package/dist/sitemap-writer.js +47 -0
  248. package/dist/sitemap-writer.js.map +7 -0
  249. package/dist/sitemap.d.ts +51 -0
  250. package/dist/sitemap.js +160 -0
  251. package/dist/sitemap.js.map +7 -0
  252. package/dist/skyvern.d.ts +56 -0
  253. package/dist/skyvern.js +129 -0
  254. package/dist/skyvern.js.map +7 -0
  255. package/dist/sqs-queue.d.ts +13 -0
  256. package/dist/sqs-queue.js +115 -0
  257. package/dist/sqs-queue.js.map +7 -0
  258. package/dist/sso-token.d.ts +29 -0
  259. package/dist/sso-token.js +76 -0
  260. package/dist/sso-token.js.map +7 -0
  261. package/dist/state-graph.d.ts +59 -0
  262. package/dist/state-graph.js +193 -0
  263. package/dist/state-graph.js.map +7 -0
  264. package/dist/stealth/human-behavior.d.ts +20 -0
  265. package/dist/stealth/human-behavior.js +202 -0
  266. package/dist/stealth/human-behavior.js.map +7 -0
  267. package/dist/telemetry.d.ts +34 -0
  268. package/dist/telemetry.js +77 -0
  269. package/dist/telemetry.js.map +7 -0
  270. package/dist/test-executor.d.ts +81 -0
  271. package/dist/test-executor.js +443 -0
  272. package/dist/test-executor.js.map +7 -0
  273. package/dist/tls-fingerprint.d.ts +50 -0
  274. package/dist/tls-fingerprint.js +81 -0
  275. package/dist/tls-fingerprint.js.map +7 -0
  276. package/dist/url-pattern-completer.d.ts +28 -0
  277. package/dist/url-pattern-completer.js +122 -0
  278. package/dist/url-pattern-completer.js.map +7 -0
  279. package/dist/visual-diff-verdict.d.ts +40 -0
  280. package/dist/visual-diff-verdict.js +27 -0
  281. package/dist/visual-diff-verdict.js.map +7 -0
  282. package/dist/webhook-notifier.d.ts +30 -0
  283. package/dist/webhook-notifier.js +76 -0
  284. package/dist/webhook-notifier.js.map +7 -0
  285. package/dist/websocket-detector.d.ts +24 -0
  286. package/dist/websocket-detector.js +60 -0
  287. package/dist/websocket-detector.js.map +7 -0
  288. package/dist/worker.d.ts +1 -0
  289. package/dist/worker.js +33 -0
  290. package/dist/worker.js.map +7 -0
  291. package/package.json +49 -4
  292. package/src/accessibility-auditor.ts +102 -0
  293. package/src/accessibility-tree-crawler.ts +246 -0
  294. package/src/advanced-ui-probes.ts +470 -0
  295. package/src/ai-login.ts +298 -0
  296. package/src/auth-token-rotator.ts +89 -0
  297. package/src/auth.ts +418 -0
  298. package/src/browser-extension.ts +186 -0
  299. package/src/captcha-solver.ts +143 -0
  300. package/src/color-contrast.ts +116 -0
  301. package/src/content-chunker.ts +170 -0
  302. package/src/content-dedup.ts +99 -0
  303. package/src/cookie-consent.ts +106 -0
  304. package/src/cookie-jar.ts +91 -0
  305. package/src/crawl-session-manager.ts +231 -0
  306. package/src/crawler.ts +7123 -0
  307. package/src/crawler.ts.rej +12 -0
  308. package/src/crud-interaction.ts +386 -0
  309. package/src/custom-js-injector.ts +93 -0
  310. package/src/dark-mode-capture.ts +110 -0
  311. package/src/dead-link-detector.ts +76 -0
  312. package/src/dropdown-enumerator.ts +312 -0
  313. package/src/element-hash.ts +16 -0
  314. package/src/email-otp.ts +252 -0
  315. package/src/engine-router.ts +141 -0
  316. package/src/export/bulk-export.ts +85 -0
  317. package/src/export/vector-export.ts +160 -0
  318. package/src/extractors/advanced.ts +309 -0
  319. package/src/extractors/artifact-envelope.ts +111 -0
  320. package/src/extractors/branding-extractor.ts +159 -0
  321. package/src/extractors/summary-extractor.ts +49 -0
  322. package/src/failure-analysis-agent.ts +51 -0
  323. package/src/feature-flag-detector.ts +97 -0
  324. package/src/filter-pagination-crawler.ts +500 -0
  325. package/src/form-detector.ts +103 -0
  326. package/src/frontier.test.ts +64 -0
  327. package/src/frontier.ts +144 -0
  328. package/src/gap-pass.ts +165 -0
  329. package/src/graphql-detector.ts +129 -0
  330. package/src/http-engine.ts +453 -0
  331. package/src/incremental-diff.ts +259 -0
  332. package/src/index.ts +52 -0
  333. package/src/input-fuzzer.ts +129 -0
  334. package/src/interactive-probe.ts +1136 -0
  335. package/src/job-queue.test.ts +187 -0
  336. package/src/job-queue.ts +4504 -0
  337. package/src/js-coverage.ts +87 -0
  338. package/src/js-router-detector.ts +112 -0
  339. package/src/language-detector.ts +82 -0
  340. package/src/link-classifier.ts +65 -0
  341. package/src/live-view.ts +146 -0
  342. package/src/locator-extractor.ts +309 -0
  343. package/src/logger.ts +9 -0
  344. package/src/markdown-extract.test.ts +73 -0
  345. package/src/markdown-extract.ts +76 -0
  346. package/src/multi-context-handler.ts +296 -0
  347. package/src/native-crawler.ts +1108 -0
  348. package/src/nested-window-crawler.ts +310 -0
  349. package/src/network-action-correlator.ts +320 -0
  350. package/src/network-observer.ts +204 -0
  351. package/src/network-throttle.ts +69 -0
  352. package/src/openapi-generator.ts +135 -0
  353. package/src/pdf-extractor.ts +123 -0
  354. package/src/performance-metrics-collector.ts +243 -0
  355. package/src/performance-metrics.ts +134 -0
  356. package/src/phash.ts +184 -0
  357. package/src/pii-scrubber.ts +99 -0
  358. package/src/playwright-recorder.ts +170 -0
  359. package/src/policies/crawl-safety.ts +52 -0
  360. package/src/profiles/domain-profile.ts +190 -0
  361. package/src/proxy.ts +238 -0
  362. package/src/rate-limiter.ts +87 -0
  363. package/src/redirect-tracker.ts +97 -0
  364. package/src/redis-frontier.ts +143 -0
  365. package/src/redis-queue.ts +208 -0
  366. package/src/response-cache.ts +150 -0
  367. package/src/responsive-detector.ts +92 -0
  368. package/src/retry-policy.ts +87 -0
  369. package/src/robots-txt.ts +96 -0
  370. package/src/screen-reader.ts +98 -0
  371. package/src/screenshot-masker.ts +98 -0
  372. package/src/seo-checker.ts +134 -0
  373. package/src/service-worker-interceptor.ts +185 -0
  374. package/src/session-capture.ts +335 -0
  375. package/src/session-export.test.ts +75 -0
  376. package/src/session-export.ts +172 -0
  377. package/src/shadow-dom-crawler.ts +198 -0
  378. package/src/sitemap-writer.ts +65 -0
  379. package/src/sitemap.test.ts +127 -0
  380. package/src/sitemap.ts +233 -0
  381. package/src/skyvern.ts +199 -0
  382. package/src/sqs-queue.ts +129 -0
  383. package/src/sso-token.ts +120 -0
  384. package/src/state-graph.ts +280 -0
  385. package/src/stealth/human-behavior.ts +227 -0
  386. package/src/telemetry.ts +122 -0
  387. package/src/test-executor.test.ts +72 -0
  388. package/src/test-executor.ts +578 -0
  389. package/src/tls-fingerprint.ts +111 -0
  390. package/src/url-pattern-completer.ts +161 -0
  391. package/src/vendor.d.ts +20 -0
  392. package/src/visual-diff-verdict.test.ts +80 -0
  393. package/src/visual-diff-verdict.ts +59 -0
  394. package/src/webhook-notifier.ts +109 -0
  395. package/src/websocket-detector.ts +83 -0
  396. package/src/worker.ts +50 -0
  397. package/tsconfig.json +13 -0
  398. package/types/accessibility-auditor.d.ts +29 -0
  399. package/types/accessibility-tree-crawler.d.ts +44 -0
  400. package/types/advanced-ui-probes.d.ts +47 -0
  401. package/types/ai-login.d.ts +32 -0
  402. package/types/auth-token-rotator.d.ts +47 -0
  403. package/types/auth.d.ts +20 -0
  404. package/types/browser-extension.d.ts +37 -0
  405. package/types/bull-worker.d.ts +6 -0
  406. package/types/captcha-solver.d.ts +16 -0
  407. package/types/color-contrast.d.ts +30 -0
  408. package/types/content-chunker.d.ts +18 -0
  409. package/types/content-dedup.d.ts +23 -0
  410. package/types/cookie-consent.d.ts +25 -0
  411. package/types/cookie-jar.d.ts +20 -0
  412. package/types/crawl-session-manager.d.ts +44 -0
  413. package/types/crawler.d.ts +233 -0
  414. package/types/crud-interaction.d.ts +31 -0
  415. package/types/custom-js-injector.d.ts +42 -0
  416. package/types/dark-mode-capture.d.ts +23 -0
  417. package/types/dead-link-detector.d.ts +37 -0
  418. package/types/dropdown-enumerator.d.ts +20 -0
  419. package/types/element-hash.d.ts +9 -0
  420. package/types/email-otp.d.ts +42 -0
  421. package/types/engine-router.d.ts +47 -0
  422. package/types/export/bulk-export.d.ts +26 -0
  423. package/types/export/vector-export.d.ts +76 -0
  424. package/types/extractors/advanced.d.ts +64 -0
  425. package/types/extractors/artifact-envelope.d.ts +63 -0
  426. package/types/extractors/branding-extractor.d.ts +46 -0
  427. package/types/extractors/summary-extractor.d.ts +10 -0
  428. package/types/failure-analysis-agent.d.ts +16 -0
  429. package/types/feature-flag-detector.d.ts +30 -0
  430. package/types/filter-pagination-crawler.d.ts +52 -0
  431. package/types/form-detector.d.ts +34 -0
  432. package/types/frontier.d.ts +40 -0
  433. package/types/gap-pass.d.ts +36 -0
  434. package/types/graphql-detector.d.ts +39 -0
  435. package/types/http-engine.d.ts +80 -0
  436. package/types/incremental-diff.d.ts +116 -0
  437. package/types/index.d.ts +52 -0
  438. package/types/input-fuzzer.d.ts +30 -0
  439. package/types/interactive-probe.d.ts +144 -0
  440. package/types/job-queue.d.ts +308 -0
  441. package/types/js-coverage.d.ts +29 -0
  442. package/types/js-router-detector.d.ts +17 -0
  443. package/types/language-detector.d.ts +22 -0
  444. package/types/link-classifier.d.ts +23 -0
  445. package/types/live-view.d.ts +36 -0
  446. package/types/locator-extractor.d.ts +46 -0
  447. package/types/logger.d.ts +2 -0
  448. package/types/markdown-extract.d.ts +8 -0
  449. package/types/multi-context-handler.d.ts +55 -0
  450. package/types/native-crawler.d.ts +69 -0
  451. package/types/nested-window-crawler.d.ts +41 -0
  452. package/types/network-action-correlator.d.ts +47 -0
  453. package/types/network-observer.d.ts +49 -0
  454. package/types/network-throttle.d.ts +25 -0
  455. package/types/openapi-generator.d.ts +49 -0
  456. package/types/pdf-extractor.d.ts +28 -0
  457. package/types/performance-metrics-collector.d.ts +50 -0
  458. package/types/performance-metrics.d.ts +52 -0
  459. package/types/phash.d.ts +50 -0
  460. package/types/pii-scrubber.d.ts +21 -0
  461. package/types/playwright-recorder.d.ts +39 -0
  462. package/types/policies/crawl-safety.d.ts +9 -0
  463. package/types/profiles/domain-profile.d.ts +19 -0
  464. package/types/proxy.d.ts +50 -0
  465. package/types/rate-limiter.d.ts +31 -0
  466. package/types/redirect-tracker.d.ts +37 -0
  467. package/types/redis-frontier.d.ts +48 -0
  468. package/types/redis-queue.d.ts +48 -0
  469. package/types/response-cache.d.ts +38 -0
  470. package/types/responsive-detector.d.ts +29 -0
  471. package/types/retry-policy.d.ts +20 -0
  472. package/types/robots-txt.d.ts +9 -0
  473. package/types/screen-reader.d.ts +15 -0
  474. package/types/screenshot-masker.d.ts +28 -0
  475. package/types/seo-checker.d.ts +33 -0
  476. package/types/service-worker-interceptor.d.ts +36 -0
  477. package/types/session-capture.d.ts +39 -0
  478. package/types/session-export.d.ts +49 -0
  479. package/types/shadow-dom-crawler.d.ts +35 -0
  480. package/types/sitemap-writer.d.ts +21 -0
  481. package/types/sitemap.d.ts +51 -0
  482. package/types/skyvern.d.ts +56 -0
  483. package/types/sqs-queue.d.ts +13 -0
  484. package/types/sso-token.d.ts +29 -0
  485. package/types/state-graph.d.ts +59 -0
  486. package/types/stealth/human-behavior.d.ts +20 -0
  487. package/types/telemetry.d.ts +34 -0
  488. package/types/test-executor.d.ts +84 -0
  489. package/types/tls-fingerprint.d.ts +50 -0
  490. package/types/url-pattern-completer.d.ts +28 -0
  491. package/types/visual-diff-verdict.d.ts +40 -0
  492. package/types/webhook-notifier.d.ts +30 -0
  493. package/types/websocket-detector.d.ts +24 -0
  494. package/types/worker.d.ts +1 -0
@@ -0,0 +1,265 @@
1
+ import { parseHTML } from "linkedom";
2
+ function extractByCssSelector(html, selector, attr) {
3
+ try {
4
+ const { document } = parseHTML(html);
5
+ const nodes = Array.from(document.querySelectorAll(selector));
6
+ const matches = nodes.map((n) => {
7
+ if (attr) return n.getAttribute(attr) ?? "";
8
+ return n.textContent?.trim() ?? "";
9
+ }).filter(Boolean);
10
+ return { matches, count: matches.length, method: "css-selector" };
11
+ } catch (e) {
12
+ return { matches: [], count: 0, method: "css-selector-error" };
13
+ }
14
+ }
15
+ function extractByXPath(html, xpath) {
16
+ try {
17
+ const { document, XPathResult } = parseHTML(html);
18
+ const result = document.evaluate(xpath, document, null, XPathResult?.ANY_TYPE ?? 0, null);
19
+ const matches = [];
20
+ let node = result.iterateNext?.();
21
+ while (node) {
22
+ const text = node.textContent?.trim() ?? node.nodeValue?.trim() ?? "";
23
+ if (text) matches.push(text);
24
+ node = result.iterateNext?.();
25
+ }
26
+ return { matches, count: matches.length, method: "xpath" };
27
+ } catch (e) {
28
+ return { matches: [], count: 0, method: "xpath-error" };
29
+ }
30
+ }
31
+ function extractByRegex(text, pattern, flags) {
32
+ try {
33
+ const re = new RegExp(pattern, (flags ?? "g").includes("g") ? flags : (flags ?? "") + "g");
34
+ const matches = [];
35
+ let m;
36
+ while ((m = re.exec(text)) !== null) {
37
+ matches.push(m[1] ?? m[0]);
38
+ if (!re.global) break;
39
+ }
40
+ return { matches, count: matches.length, method: "regex" };
41
+ } catch {
42
+ return { matches: [], count: 0, method: "regex-error" };
43
+ }
44
+ }
45
+ function extractTables(html) {
46
+ try {
47
+ const { document } = parseHTML(html);
48
+ const tables = Array.from(document.querySelectorAll("table"));
49
+ return tables.map((table) => {
50
+ const headers = [];
51
+ const rows = [];
52
+ const ths = [...table.querySelectorAll("thead th, thead td, tr:first-child th")];
53
+ if (ths.length > 0) {
54
+ ths.forEach((th, i) => headers.push(th.textContent?.trim() || `col${i + 1}`));
55
+ }
56
+ const trs = [...table.querySelectorAll("tbody tr, tr")];
57
+ for (const tr of trs) {
58
+ const cells = [...tr.querySelectorAll("td, th")];
59
+ if (cells.length === 0) continue;
60
+ if (headers.length === 0) {
61
+ cells.forEach((_, i) => headers.push(`col${i + 1}`));
62
+ }
63
+ const row = {};
64
+ cells.forEach((cell, i) => {
65
+ const key = headers[i] || `col${i + 1}`;
66
+ row[key] = cell.textContent?.trim() ?? "";
67
+ });
68
+ if (Object.values(row).some((v) => v)) rows.push(row);
69
+ }
70
+ return rows;
71
+ }).filter((t) => t.length > 0);
72
+ } catch {
73
+ return [];
74
+ }
75
+ }
76
+ function extractMetadata(html, url) {
77
+ const meta = {
78
+ title: null,
79
+ description: null,
80
+ keywords: null,
81
+ ogTitle: null,
82
+ ogDescription: null,
83
+ ogImage: null,
84
+ ogUrl: null,
85
+ ogType: null,
86
+ ogSiteName: null,
87
+ ogLocale: null,
88
+ twitterCard: null,
89
+ twitterTitle: null,
90
+ twitterDescription: null,
91
+ twitterImage: null,
92
+ twitterSite: null,
93
+ canonical: null,
94
+ robots: null,
95
+ hreflang: [],
96
+ themeColor: null,
97
+ favicon: null,
98
+ jsonLd: [],
99
+ schemaTypes: [],
100
+ lang: null
101
+ };
102
+ try {
103
+ const { document } = parseHTML(html);
104
+ meta.title = document.title ?? document.querySelector("title")?.textContent?.trim() ?? null;
105
+ meta.lang = document.documentElement?.getAttribute("lang") ?? null;
106
+ const metas = [...document.querySelectorAll("meta")];
107
+ for (const m of metas) {
108
+ const name = m.getAttribute("name")?.toLowerCase() ?? "";
109
+ const prop = m.getAttribute("property")?.toLowerCase() ?? "";
110
+ const content = m.getAttribute("content") ?? "";
111
+ if (name === "description") meta.description = content;
112
+ if (name === "keywords") meta.keywords = content;
113
+ if (name === "robots") meta.robots = content;
114
+ if (name === "twitter:card") meta.twitterCard = content;
115
+ if (name === "twitter:title") meta.twitterTitle = content;
116
+ if (name === "twitter:description") meta.twitterDescription = content;
117
+ if (name === "twitter:image") meta.twitterImage = content;
118
+ if (name === "twitter:site") meta.twitterSite = content;
119
+ if (name === "theme-color") meta.themeColor = content;
120
+ if (prop === "og:title") meta.ogTitle = content;
121
+ if (prop === "og:description") meta.ogDescription = content;
122
+ if (prop === "og:image") meta.ogImage = content;
123
+ if (prop === "og:url") meta.ogUrl = content;
124
+ if (prop === "og:type") meta.ogType = content;
125
+ if (prop === "og:site_name") meta.ogSiteName = content;
126
+ if (prop === "og:locale") meta.ogLocale = content;
127
+ }
128
+ const canonical = document.querySelector('link[rel="canonical"]');
129
+ if (canonical) meta.canonical = canonical.getAttribute("href") ?? null;
130
+ const faviconEl = document.querySelector('link[rel="icon"], link[rel="shortcut icon"]');
131
+ if (faviconEl) meta.favicon = faviconEl.getAttribute("href") ?? null;
132
+ const hreflangEls = [...document.querySelectorAll('link[rel="alternate"][hreflang]')];
133
+ for (const el of hreflangEls) {
134
+ const lang = el.getAttribute("hreflang") ?? "";
135
+ const href = el.getAttribute("href") ?? "";
136
+ if (lang && href) meta.hreflang.push({ lang, href });
137
+ }
138
+ const jsonLdScripts = [...document.querySelectorAll('script[type="application/ld+json"]')];
139
+ for (const s of jsonLdScripts) {
140
+ try {
141
+ const parsed = JSON.parse(s.textContent ?? "{}");
142
+ meta.jsonLd.push(parsed);
143
+ const types = Array.isArray(parsed) ? parsed.map((p) => p["@type"]).flat() : [parsed["@type"]];
144
+ meta.schemaTypes.push(...types.filter(Boolean));
145
+ } catch {
146
+ }
147
+ }
148
+ } catch {
149
+ }
150
+ return meta;
151
+ }
152
+ function extractStructuredProduct(jsonLd) {
153
+ for (const item of jsonLd) {
154
+ try {
155
+ const type = item["@type"];
156
+ const isProduct = Array.isArray(type) ? type.some((t) => typeof t === "string" && t.toLowerCase() === "product") : typeof type === "string" && type.toLowerCase() === "product";
157
+ if (!isProduct) continue;
158
+ const i = item;
159
+ const offers = Array.isArray(i.offers) ? i.offers[0] : i.offers;
160
+ const rawPrice = offers?.price;
161
+ const price = rawPrice != null ? parseFloat(rawPrice) : NaN;
162
+ const rawRating = i.aggregateRating?.ratingValue;
163
+ const rating = rawRating != null ? parseFloat(rawRating) : NaN;
164
+ const rawReviewCount = i.aggregateRating?.reviewCount;
165
+ const reviewCount = rawReviewCount != null ? parseInt(rawReviewCount, 10) : NaN;
166
+ const rawAvailability = offers?.availability;
167
+ const availability = rawAvailability ? rawAvailability.replace(/^https?:\/\/schema\.org\//, "") : null;
168
+ const rawImage = i.image;
169
+ const image = Array.isArray(rawImage) ? rawImage[0] ?? null : rawImage ?? null;
170
+ const brand = i.brand?.name ?? i.brand ?? null;
171
+ return {
172
+ name: i.name ?? null,
173
+ description: i.description ?? null,
174
+ brand: typeof brand === "string" ? brand : null,
175
+ sku: i.sku ?? null,
176
+ price: isNaN(price) ? null : price,
177
+ priceCurrency: offers?.priceCurrency ?? null,
178
+ availability,
179
+ rating: isNaN(rating) ? null : rating,
180
+ reviewCount: isNaN(reviewCount) ? null : reviewCount,
181
+ image,
182
+ url: i.url ?? null
183
+ };
184
+ } catch {
185
+ }
186
+ }
187
+ return null;
188
+ }
189
+ function extractImages(html, baseUrl) {
190
+ try {
191
+ const { document } = parseHTML(html);
192
+ const base = new URL(baseUrl);
193
+ return Array.from(document.querySelectorAll("img")).map((img) => {
194
+ const src = img.getAttribute("src") ?? img.getAttribute("data-src") ?? "";
195
+ if (!src) return null;
196
+ try {
197
+ return {
198
+ src: new URL(src, base).href,
199
+ alt: img.getAttribute("alt") ?? "",
200
+ width: img.getAttribute("width") ? parseInt(img.getAttribute("width")) : void 0,
201
+ height: img.getAttribute("height") ? parseInt(img.getAttribute("height")) : void 0
202
+ };
203
+ } catch {
204
+ return null;
205
+ }
206
+ }).filter((x) => x !== null);
207
+ } catch {
208
+ return [];
209
+ }
210
+ }
211
+ function extractMediaFiles(html, baseUrl) {
212
+ const IMAGE_EXT = /\.(png|jpe?g|gif|webp|svg|ico|avif)(\?.*)?$/i;
213
+ const VIDEO_EXT = /\.(mp4|webm|ogv|mov|avi)(\?.*)?$/i;
214
+ const AUDIO_EXT = /\.(mp3|ogg|wav|flac|aac)(\?.*)?$/i;
215
+ const DOC_EXT = /\.(pdf|docx?|xlsx?|pptx?|csv|zip)(\?.*)?$/i;
216
+ function classify(url, tag) {
217
+ if (tag === "img" || IMAGE_EXT.test(url)) return "image";
218
+ if (tag === "video" || VIDEO_EXT.test(url)) return "video";
219
+ if (tag === "audio" || AUDIO_EXT.test(url)) return "audio";
220
+ if (DOC_EXT.test(url)) return "document";
221
+ return "document";
222
+ }
223
+ try {
224
+ const { document } = parseHTML(html);
225
+ const base = new URL(baseUrl);
226
+ const results = [];
227
+ const seen = /* @__PURE__ */ new Set();
228
+ const selectors = ["img[src],video[src],audio[src],source[src]", "src"];
229
+ const attrPairs = [
230
+ ["img", "src"],
231
+ ["video", "src"],
232
+ ["audio", "src"],
233
+ ["source", "src"],
234
+ ["a", "href"]
235
+ ];
236
+ for (const [sel, attr] of attrPairs) {
237
+ for (const el of [...document.querySelectorAll(sel)]) {
238
+ const raw = el.getAttribute(attr) ?? "";
239
+ if (!raw) continue;
240
+ try {
241
+ const resolved = new URL(raw, base).href;
242
+ if (seen.has(resolved)) continue;
243
+ if (sel === "a" && !DOC_EXT.test(resolved) && !IMAGE_EXT.test(resolved) && !VIDEO_EXT.test(resolved) && !AUDIO_EXT.test(resolved)) continue;
244
+ seen.add(resolved);
245
+ results.push({ url: resolved, type: classify(resolved, sel), tag: sel });
246
+ } catch {
247
+ }
248
+ }
249
+ }
250
+ return results;
251
+ } catch {
252
+ return [];
253
+ }
254
+ }
255
+ export {
256
+ extractByCssSelector,
257
+ extractByRegex,
258
+ extractByXPath,
259
+ extractImages,
260
+ extractMediaFiles,
261
+ extractMetadata,
262
+ extractStructuredProduct,
263
+ extractTables
264
+ };
265
+ //# sourceMappingURL=advanced.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/extractors/advanced.ts"],
4
+ "sourcesContent": ["import { parseHTML } from 'linkedom';\n\nexport interface ExtractionResult {\n matches: string[];\n count: number;\n method: string;\n}\n\nexport type TableRow = Record<string, string>;\n\nexport interface PageMetadata {\n title: string | null;\n description: string | null;\n keywords: string | null;\n ogTitle: string | null;\n ogDescription: string | null;\n ogImage: string | null;\n ogUrl: string | null;\n ogType: string | null;\n ogSiteName: string | null;\n ogLocale: string | null;\n twitterCard: string | null;\n twitterTitle: string | null;\n twitterDescription: string | null;\n twitterImage: string | null;\n twitterSite: string | null;\n canonical: string | null;\n robots: string | null;\n hreflang: Array<{ lang: string; href: string }>;\n themeColor: string | null;\n favicon: string | null;\n jsonLd: object[];\n schemaTypes: string[];\n lang: string | null;\n}\n\nexport function extractByCssSelector(html: string, selector: string, attr?: string): ExtractionResult {\n try {\n const { document } = parseHTML(html);\n const nodes = Array.from(document.querySelectorAll(selector));\n const matches = nodes.map((n: any) => {\n if (attr) return (n as any).getAttribute(attr) ?? '';\n return (n as any).textContent?.trim() ?? '';\n }).filter(Boolean);\n return { matches, count: matches.length, method: 'css-selector' };\n } catch (e) {\n return { matches: [], count: 0, method: 'css-selector-error' };\n }\n}\n\nexport function extractByXPath(html: string, xpath: string): ExtractionResult {\n try {\n const { document, XPathResult } = parseHTML(html) as any;\n const result = document.evaluate(xpath, document, null, XPathResult?.ANY_TYPE ?? 0, null);\n const matches: string[] = [];\n let node = result.iterateNext?.();\n while (node) {\n const text = (node as any).textContent?.trim() ?? (node as any).nodeValue?.trim() ?? '';\n if (text) matches.push(text);\n node = result.iterateNext?.();\n }\n return { matches, count: matches.length, method: 'xpath' };\n } catch (e) {\n return { matches: [], count: 0, method: 'xpath-error' };\n }\n}\n\nexport function extractByRegex(text: string, pattern: string, flags?: string): ExtractionResult {\n try {\n const re = new RegExp(pattern, (flags ?? 'g').includes('g') ? flags : (flags ?? '') + 'g');\n const matches: string[] = [];\n let m: RegExpExecArray | null;\n while ((m = re.exec(text)) !== null) {\n matches.push(m[1] ?? m[0]);\n if (!re.global) break;\n }\n return { matches, count: matches.length, method: 'regex' };\n } catch {\n return { matches: [], count: 0, method: 'regex-error' };\n }\n}\n\nexport function extractTables(html: string): TableRow[][] {\n try {\n const { document } = parseHTML(html);\n const tables = Array.from(document.querySelectorAll('table'));\n return tables.map((table: any) => {\n const headers: string[] = [];\n const rows: TableRow[] = [];\n const ths = [...table.querySelectorAll('thead th, thead td, tr:first-child th')];\n if (ths.length > 0) {\n ths.forEach((th: any, i: number) => headers.push(th.textContent?.trim() || `col${i + 1}`));\n }\n const trs = [...table.querySelectorAll('tbody tr, tr')];\n for (const tr of trs) {\n const cells = [...(tr as any).querySelectorAll('td, th')];\n if (cells.length === 0) continue;\n if (headers.length === 0) {\n cells.forEach((_: any, i: number) => headers.push(`col${i + 1}`));\n }\n const row: TableRow = {};\n cells.forEach((cell: any, i: number) => {\n const key = headers[i] || `col${i + 1}`;\n row[key] = cell.textContent?.trim() ?? '';\n });\n if (Object.values(row).some(v => v)) rows.push(row);\n }\n return rows;\n }).filter(t => t.length > 0);\n } catch {\n return [];\n }\n}\n\nexport function extractMetadata(html: string, url: string): PageMetadata {\n const meta: PageMetadata = {\n title: null, description: null, keywords: null,\n ogTitle: null, ogDescription: null, ogImage: null, ogUrl: null, ogType: null,\n ogSiteName: null, ogLocale: null,\n twitterCard: null, twitterTitle: null, twitterDescription: null,\n twitterImage: null, twitterSite: null,\n canonical: null, robots: null,\n hreflang: [], themeColor: null, favicon: null,\n jsonLd: [], schemaTypes: [], lang: null,\n };\n try {\n const { document } = parseHTML(html);\n meta.title = (document as any).title ?? (document as any).querySelector('title')?.textContent?.trim() ?? null;\n meta.lang = (document as any).documentElement?.getAttribute('lang') ?? null;\n\n const metas = [...(document as any).querySelectorAll('meta')];\n for (const m of metas) {\n const name = (m as any).getAttribute('name')?.toLowerCase() ?? '';\n const prop = (m as any).getAttribute('property')?.toLowerCase() ?? '';\n const content = (m as any).getAttribute('content') ?? '';\n if (name === 'description') meta.description = content;\n if (name === 'keywords') meta.keywords = content;\n if (name === 'robots') meta.robots = content;\n if (name === 'twitter:card') meta.twitterCard = content;\n if (name === 'twitter:title') meta.twitterTitle = content;\n if (name === 'twitter:description') meta.twitterDescription = content;\n if (name === 'twitter:image') meta.twitterImage = content;\n if (name === 'twitter:site') meta.twitterSite = content;\n if (name === 'theme-color') meta.themeColor = content;\n if (prop === 'og:title') meta.ogTitle = content;\n if (prop === 'og:description') meta.ogDescription = content;\n if (prop === 'og:image') meta.ogImage = content;\n if (prop === 'og:url') meta.ogUrl = content;\n if (prop === 'og:type') meta.ogType = content;\n if (prop === 'og:site_name') meta.ogSiteName = content;\n if (prop === 'og:locale') meta.ogLocale = content;\n }\n\n const canonical = (document as any).querySelector('link[rel=\"canonical\"]');\n if (canonical) meta.canonical = canonical.getAttribute('href') ?? null;\n\n const faviconEl = (document as any).querySelector('link[rel=\"icon\"], link[rel=\"shortcut icon\"]');\n if (faviconEl) meta.favicon = faviconEl.getAttribute('href') ?? null;\n\n const hreflangEls = [...(document as any).querySelectorAll('link[rel=\"alternate\"][hreflang]')];\n for (const el of hreflangEls) {\n const lang = (el as any).getAttribute('hreflang') ?? '';\n const href = (el as any).getAttribute('href') ?? '';\n if (lang && href) meta.hreflang.push({ lang, href });\n }\n\n const jsonLdScripts = [...(document as any).querySelectorAll('script[type=\"application/ld+json\"]')];\n for (const s of jsonLdScripts) {\n try {\n const parsed = JSON.parse((s as any).textContent ?? '{}');\n meta.jsonLd.push(parsed);\n const types = Array.isArray(parsed) ? parsed.map((p: any) => p['@type']).flat() : [parsed['@type']];\n meta.schemaTypes.push(...types.filter(Boolean));\n } catch { /* skip invalid JSON-LD */ }\n }\n } catch { /* non-fatal */ }\n return meta;\n}\n\nexport interface ProductData {\n name: string | null;\n description: string | null;\n brand: string | null;\n sku: string | null;\n price: number | null;\n priceCurrency: string | null;\n availability: string | null;\n rating: number | null;\n reviewCount: number | null;\n image: string | null;\n url: string | null;\n}\n\nexport function extractStructuredProduct(jsonLd: object[]): ProductData | null {\n for (const item of jsonLd) {\n try {\n const type = (item as any)['@type'];\n const isProduct = Array.isArray(type)\n ? type.some((t: any) => typeof t === 'string' && t.toLowerCase() === 'product')\n : typeof type === 'string' && type.toLowerCase() === 'product';\n if (!isProduct) continue;\n\n const i = item as any;\n const offers = Array.isArray(i.offers) ? i.offers[0] : i.offers;\n\n const rawPrice = offers?.price;\n const price = rawPrice != null ? parseFloat(rawPrice) : NaN;\n\n const rawRating = i.aggregateRating?.ratingValue;\n const rating = rawRating != null ? parseFloat(rawRating) : NaN;\n\n const rawReviewCount = i.aggregateRating?.reviewCount;\n const reviewCount = rawReviewCount != null ? parseInt(rawReviewCount, 10) : NaN;\n\n const rawAvailability: string | undefined = offers?.availability;\n const availability = rawAvailability\n ? rawAvailability.replace(/^https?:\\/\\/schema\\.org\\//, '')\n : null;\n\n const rawImage = i.image;\n const image = Array.isArray(rawImage) ? (rawImage[0] ?? null) : (rawImage ?? null);\n\n const brand = i.brand?.name ?? i.brand ?? null;\n\n return {\n name: i.name ?? null,\n description: i.description ?? null,\n brand: typeof brand === 'string' ? brand : null,\n sku: i.sku ?? null,\n price: isNaN(price) ? null : price,\n priceCurrency: offers?.priceCurrency ?? null,\n availability,\n rating: isNaN(rating) ? null : rating,\n reviewCount: isNaN(reviewCount) ? null : reviewCount,\n image,\n url: i.url ?? null,\n };\n } catch { /* skip malformed item */ }\n }\n return null;\n}\n\nexport function extractImages(html: string, baseUrl: string): Array<{ src: string; alt: string; width?: number; height?: number }> {\n try {\n const { document } = parseHTML(html);\n const base = new URL(baseUrl);\n return Array.from((document as any).querySelectorAll('img'))\n .map((img: any) => {\n const src = img.getAttribute('src') ?? img.getAttribute('data-src') ?? '';\n if (!src) return null;\n try {\n return {\n src: new URL(src, base).href,\n alt: (img.getAttribute('alt') ?? '') as string,\n width: img.getAttribute('width') ? parseInt(img.getAttribute('width')) : undefined,\n height: img.getAttribute('height') ? parseInt(img.getAttribute('height')) : undefined,\n } as { src: string; alt: string; width?: number; height?: number };\n } catch { return null; }\n })\n .filter((x): x is { src: string; alt: string; width?: number; height?: number } => x !== null);\n } catch {\n return [];\n }\n}\n\nexport function extractMediaFiles(html: string, baseUrl: string): Array<{ url: string; type: 'image' | 'video' | 'audio' | 'document'; tag: string }> {\n const IMAGE_EXT = /\\.(png|jpe?g|gif|webp|svg|ico|avif)(\\?.*)?$/i;\n const VIDEO_EXT = /\\.(mp4|webm|ogv|mov|avi)(\\?.*)?$/i;\n const AUDIO_EXT = /\\.(mp3|ogg|wav|flac|aac)(\\?.*)?$/i;\n const DOC_EXT = /\\.(pdf|docx?|xlsx?|pptx?|csv|zip)(\\?.*)?$/i;\n\n function classify(url: string, tag: string): 'image' | 'video' | 'audio' | 'document' {\n if (tag === 'img' || IMAGE_EXT.test(url)) return 'image';\n if (tag === 'video' || VIDEO_EXT.test(url)) return 'video';\n if (tag === 'audio' || AUDIO_EXT.test(url)) return 'audio';\n if (DOC_EXT.test(url)) return 'document';\n return 'document';\n }\n\n try {\n const { document } = parseHTML(html);\n const base = new URL(baseUrl);\n const results: Array<{ url: string; type: 'image' | 'video' | 'audio' | 'document'; tag: string }> = [];\n const seen = new Set<string>();\n\n const selectors: [string, string] = ['img[src],video[src],audio[src],source[src]', 'src'];\n const attrPairs: Array<[string, string]> = [\n ['img', 'src'], ['video', 'src'], ['audio', 'src'], ['source', 'src'],\n ['a', 'href'],\n ];\n\n for (const [sel, attr] of attrPairs) {\n for (const el of [...(document as any).querySelectorAll(sel)]) {\n const raw = (el as any).getAttribute(attr) ?? '';\n if (!raw) continue;\n try {\n const resolved = new URL(raw, base).href;\n if (seen.has(resolved)) continue;\n if (sel === 'a' && !DOC_EXT.test(resolved) && !IMAGE_EXT.test(resolved) && !VIDEO_EXT.test(resolved) && !AUDIO_EXT.test(resolved)) continue;\n seen.add(resolved);\n results.push({ url: resolved, type: classify(resolved, sel), tag: sel });\n } catch { /* skip */ }\n }\n }\n return results;\n } catch {\n return [];\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,63 @@
1
+ import type { RawElement } from '../screen-reader.js';
2
+ export interface CrawlEvidenceFact {
3
+ type: string;
4
+ payload: unknown;
5
+ }
6
+ export interface CrawlArtifactEnvelope {
7
+ tenantId: string;
8
+ projectId: string;
9
+ jobId?: string;
10
+ url: string;
11
+ canonicalUrl: string;
12
+ screenId?: string;
13
+ status: 'ok' | 'blocked' | 'auth_expired' | 'error' | 'skipped';
14
+ outputs: {
15
+ screenshot?: string;
16
+ html?: string;
17
+ markdown?: string;
18
+ fitMarkdown?: string;
19
+ accessibilityTree?: string;
20
+ structuredJson?: unknown;
21
+ networkTrace?: string;
22
+ consoleLog?: string;
23
+ };
24
+ fingerprints: {
25
+ textHash?: string;
26
+ domHash?: string;
27
+ accessibilityHash?: string;
28
+ urlCanonicalHash: string;
29
+ };
30
+ evidence: CrawlEvidenceFact[];
31
+ }
32
+ export declare function sha256(input: string): string;
33
+ export declare function buildFitMarkdown(markdown: string, keywords?: string[]): string;
34
+ export declare function summarizeStructuredElements(elements: RawElement[]): {
35
+ elementCount: number;
36
+ formFieldCount: number;
37
+ actionCount: number;
38
+ fields: {
39
+ label: string;
40
+ role: string;
41
+ expectedData: string | undefined;
42
+ }[];
43
+ actions: {
44
+ label: string;
45
+ role: string;
46
+ }[];
47
+ };
48
+ export declare function buildCrawlArtifactEnvelope(input: {
49
+ tenantId: string;
50
+ projectId: string;
51
+ jobId?: string;
52
+ url: string;
53
+ canonicalUrl: string;
54
+ screenId?: string;
55
+ screenshotPath?: string;
56
+ domPath?: string;
57
+ domContent?: string;
58
+ markdown?: string;
59
+ fitMarkdown?: string;
60
+ accessibilityElements?: RawElement[];
61
+ structuredJson?: unknown;
62
+ evidence?: CrawlEvidenceFact[];
63
+ }): CrawlArtifactEnvelope;
@@ -0,0 +1,63 @@
1
+ import crypto from "node:crypto";
2
+ function sha256(input) {
3
+ return crypto.createHash("sha256").update(input).digest("hex");
4
+ }
5
+ function buildFitMarkdown(markdown, keywords = []) {
6
+ const lines = markdown.split("\n").map((line) => line.trimEnd()).filter((line) => line.trim().length > 0);
7
+ const lowerKeywords = keywords.map((k) => k.toLowerCase()).filter(Boolean);
8
+ const filtered = lines.filter((line) => {
9
+ const plain = line.replace(/[#*_`>\-[\]()]/g, "").trim();
10
+ if (plain.length < 3) return false;
11
+ if (/^(cookie|privacy|terms|copyright|all rights reserved|subscribe|newsletter)$/i.test(plain)) return false;
12
+ if (lowerKeywords.length === 0) return true;
13
+ const lower = plain.toLowerCase();
14
+ return lowerKeywords.some((kw) => lower.includes(kw)) || /^#{1,4}\s/.test(line);
15
+ });
16
+ const candidate = filtered.join("\n");
17
+ return candidate.length >= 200 ? candidate : markdown;
18
+ }
19
+ function summarizeStructuredElements(elements) {
20
+ const forms = elements.filter((e) => ["email", "password", "text", "tel", "date", "number", "select", "textarea"].includes(e.role));
21
+ const actions = elements.filter((e) => e.role === "button" || e.role === "submit" || e.role === "link" || e.role === "a");
22
+ return {
23
+ elementCount: elements.length,
24
+ formFieldCount: forms.length,
25
+ actionCount: actions.length,
26
+ fields: forms.slice(0, 50).map((e) => ({ label: e.label, role: e.role, expectedData: e.expectedData })),
27
+ actions: actions.slice(0, 50).map((e) => ({ label: e.label, role: e.role }))
28
+ };
29
+ }
30
+ function buildCrawlArtifactEnvelope(input) {
31
+ const accessibilityTree = input.accessibilityElements ? JSON.stringify(input.accessibilityElements) : void 0;
32
+ return {
33
+ tenantId: input.tenantId,
34
+ projectId: input.projectId,
35
+ jobId: input.jobId,
36
+ url: input.url,
37
+ canonicalUrl: input.canonicalUrl,
38
+ screenId: input.screenId,
39
+ status: "ok",
40
+ outputs: {
41
+ screenshot: input.screenshotPath,
42
+ html: input.domPath,
43
+ markdown: input.markdown,
44
+ fitMarkdown: input.fitMarkdown,
45
+ accessibilityTree,
46
+ structuredJson: input.structuredJson
47
+ },
48
+ fingerprints: {
49
+ textHash: input.markdown ? sha256(input.markdown) : void 0,
50
+ domHash: input.domContent ? sha256(input.domContent) : void 0,
51
+ accessibilityHash: accessibilityTree ? sha256(accessibilityTree) : void 0,
52
+ urlCanonicalHash: sha256(input.canonicalUrl)
53
+ },
54
+ evidence: input.evidence ?? []
55
+ };
56
+ }
57
+ export {
58
+ buildCrawlArtifactEnvelope,
59
+ buildFitMarkdown,
60
+ sha256,
61
+ summarizeStructuredElements
62
+ };
63
+ //# sourceMappingURL=artifact-envelope.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/extractors/artifact-envelope.ts"],
4
+ "sourcesContent": ["import crypto from 'node:crypto';\nimport type { RawElement } from '../screen-reader.js';\n\nexport interface CrawlEvidenceFact {\n type: string;\n payload: unknown;\n}\n\nexport interface CrawlArtifactEnvelope {\n tenantId: string;\n projectId: string;\n jobId?: string;\n url: string;\n canonicalUrl: string;\n screenId?: string;\n status: 'ok' | 'blocked' | 'auth_expired' | 'error' | 'skipped';\n outputs: {\n screenshot?: string;\n html?: string;\n markdown?: string;\n fitMarkdown?: string;\n accessibilityTree?: string;\n structuredJson?: unknown;\n networkTrace?: string;\n consoleLog?: string;\n };\n fingerprints: {\n textHash?: string;\n domHash?: string;\n accessibilityHash?: string;\n urlCanonicalHash: string;\n };\n evidence: CrawlEvidenceFact[];\n}\n\nexport function sha256(input: string): string {\n return crypto.createHash('sha256').update(input).digest('hex');\n}\n\nexport function buildFitMarkdown(markdown: string, keywords: string[] = []): string {\n const lines = markdown\n .split('\\n')\n .map((line) => line.trimEnd())\n .filter((line) => line.trim().length > 0);\n const lowerKeywords = keywords.map((k) => k.toLowerCase()).filter(Boolean);\n const filtered = lines.filter((line) => {\n const plain = line.replace(/[#*_`>\\-[\\]()]/g, '').trim();\n if (plain.length < 3) return false;\n if (/^(cookie|privacy|terms|copyright|all rights reserved|subscribe|newsletter)$/i.test(plain)) return false;\n if (lowerKeywords.length === 0) return true;\n const lower = plain.toLowerCase();\n return lowerKeywords.some((kw) => lower.includes(kw)) || /^#{1,4}\\s/.test(line);\n });\n const candidate = filtered.join('\\n');\n return candidate.length >= 200 ? candidate : markdown;\n}\n\nexport function summarizeStructuredElements(elements: RawElement[]) {\n const forms = elements.filter((e) => ['email', 'password', 'text', 'tel', 'date', 'number', 'select', 'textarea'].includes(e.role));\n const actions = elements.filter((e) => e.role === 'button' || e.role === 'submit' || e.role === 'link' || e.role === 'a');\n return {\n elementCount: elements.length,\n formFieldCount: forms.length,\n actionCount: actions.length,\n fields: forms.slice(0, 50).map((e) => ({ label: e.label, role: e.role, expectedData: e.expectedData })),\n actions: actions.slice(0, 50).map((e) => ({ label: e.label, role: e.role })),\n };\n}\n\nexport function buildCrawlArtifactEnvelope(input: {\n tenantId: string;\n projectId: string;\n jobId?: string;\n url: string;\n canonicalUrl: string;\n screenId?: string;\n screenshotPath?: string;\n domPath?: string;\n domContent?: string;\n markdown?: string;\n fitMarkdown?: string;\n accessibilityElements?: RawElement[];\n structuredJson?: unknown;\n evidence?: CrawlEvidenceFact[];\n}): CrawlArtifactEnvelope {\n const accessibilityTree = input.accessibilityElements ? JSON.stringify(input.accessibilityElements) : undefined;\n return {\n tenantId: input.tenantId,\n projectId: input.projectId,\n jobId: input.jobId,\n url: input.url,\n canonicalUrl: input.canonicalUrl,\n screenId: input.screenId,\n status: 'ok',\n outputs: {\n screenshot: input.screenshotPath,\n html: input.domPath,\n markdown: input.markdown,\n fitMarkdown: input.fitMarkdown,\n accessibilityTree,\n structuredJson: input.structuredJson,\n },\n fingerprints: {\n textHash: input.markdown ? sha256(input.markdown) : undefined,\n domHash: input.domContent ? sha256(input.domContent) : undefined,\n accessibilityHash: accessibilityTree ? sha256(accessibilityTree) : undefined,\n urlCanonicalHash: sha256(input.canonicalUrl),\n },\n evidence: input.evidence ?? [],\n };\n}\n"],
5
+ "mappings": "AAAA,OAAO,YAAY;AAmCZ,SAAS,OAAO,OAAuB;AAC5C,SAAO,OAAO,WAAW,QAAQ,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK;AAC/D;AAEO,SAAS,iBAAiB,UAAkB,WAAqB,CAAC,GAAW;AAClF,QAAM,QAAQ,SACX,MAAM,IAAI,EACV,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,EAC5B,OAAO,CAAC,SAAS,KAAK,KAAK,EAAE,SAAS,CAAC;AAC1C,QAAM,gBAAgB,SAAS,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,OAAO;AACzE,QAAM,WAAW,MAAM,OAAO,CAAC,SAAS;AACtC,UAAM,QAAQ,KAAK,QAAQ,mBAAmB,EAAE,EAAE,KAAK;AACvD,QAAI,MAAM,SAAS,EAAG,QAAO;AAC7B,QAAI,+EAA+E,KAAK,KAAK,EAAG,QAAO;AACvG,QAAI,cAAc,WAAW,EAAG,QAAO;AACvC,UAAM,QAAQ,MAAM,YAAY;AAChC,WAAO,cAAc,KAAK,CAAC,OAAO,MAAM,SAAS,EAAE,CAAC,KAAK,YAAY,KAAK,IAAI;AAAA,EAChF,CAAC;AACD,QAAM,YAAY,SAAS,KAAK,IAAI;AACpC,SAAO,UAAU,UAAU,MAAM,YAAY;AAC/C;AAEO,SAAS,4BAA4B,UAAwB;AAClE,QAAM,QAAQ,SAAS,OAAO,CAAC,MAAM,CAAC,SAAS,YAAY,QAAQ,OAAO,QAAQ,UAAU,UAAU,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC;AAClI,QAAM,UAAU,SAAS,OAAO,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,SAAS,YAAY,EAAE,SAAS,UAAU,EAAE,SAAS,GAAG;AACxH,SAAO;AAAA,IACL,cAAc,SAAS;AAAA,IACvB,gBAAgB,MAAM;AAAA,IACtB,aAAa,QAAQ;AAAA,IACrB,QAAQ,MAAM,MAAM,GAAG,EAAE,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,MAAM,EAAE,MAAM,cAAc,EAAE,aAAa,EAAE;AAAA,IACtG,SAAS,QAAQ,MAAM,GAAG,EAAE,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,MAAM,EAAE,KAAK,EAAE;AAAA,EAC7E;AACF;AAEO,SAAS,2BAA2B,OAejB;AACxB,QAAM,oBAAoB,MAAM,wBAAwB,KAAK,UAAU,MAAM,qBAAqB,IAAI;AACtG,SAAO;AAAA,IACL,UAAU,MAAM;AAAA,IAChB,WAAW,MAAM;AAAA,IACjB,OAAO,MAAM;AAAA,IACb,KAAK,MAAM;AAAA,IACX,cAAc,MAAM;AAAA,IACpB,UAAU,MAAM;AAAA,IAChB,QAAQ;AAAA,IACR,SAAS;AAAA,MACP,YAAY,MAAM;AAAA,MAClB,MAAM,MAAM;AAAA,MACZ,UAAU,MAAM;AAAA,MAChB,aAAa,MAAM;AAAA,MACnB;AAAA,MACA,gBAAgB,MAAM;AAAA,IACxB;AAAA,IACA,cAAc;AAAA,MACZ,UAAU,MAAM,WAAW,OAAO,MAAM,QAAQ,IAAI;AAAA,MACpD,SAAS,MAAM,aAAa,OAAO,MAAM,UAAU,IAAI;AAAA,MACvD,mBAAmB,oBAAoB,OAAO,iBAAiB,IAAI;AAAA,MACnE,kBAAkB,OAAO,MAAM,YAAY;AAAA,IAC7C;AAAA,IACA,UAAU,MAAM,YAAY,CAAC;AAAA,EAC/B;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,46 @@
1
+ import type { Page } from 'playwright';
2
+ export interface BrandingColors {
3
+ primary?: string;
4
+ accent?: string;
5
+ background?: string;
6
+ textPrimary?: string;
7
+ link?: string;
8
+ }
9
+ export interface BrandingFont {
10
+ family: string;
11
+ role: 'heading' | 'body';
12
+ }
13
+ export interface BrandingImages {
14
+ logo?: string;
15
+ favicon?: string;
16
+ ogImage?: string;
17
+ }
18
+ export interface BrandingPersonality {
19
+ tone?: string;
20
+ energy?: 'high' | 'medium' | 'low';
21
+ targetAudience?: string;
22
+ }
23
+ export interface BrandingResult {
24
+ colorScheme: 'light' | 'dark';
25
+ colors: BrandingColors;
26
+ fonts: BrandingFont[];
27
+ images: BrandingImages;
28
+ personality?: BrandingPersonality;
29
+ designSystem?: {
30
+ framework?: string;
31
+ componentLibrary?: string;
32
+ };
33
+ metadata?: {
34
+ title?: string;
35
+ description?: string;
36
+ themeColor?: string;
37
+ language?: string;
38
+ };
39
+ confidence: {
40
+ colors: number;
41
+ fonts: number;
42
+ images: number;
43
+ overall: number;
44
+ };
45
+ }
46
+ export declare function extractBranding(page: Page): Promise<BrandingResult>;
@@ -0,0 +1,104 @@
1
+ async function extractBranding(page) {
2
+ try {
3
+ const result = await page.evaluate(() => {
4
+ const bodyStyle = window.getComputedStyle(document.body);
5
+ const isDark = window.matchMedia("(prefers-color-scheme: dark)").matches || document.documentElement.getAttribute("data-theme") === "dark" || document.body.classList.contains("dark");
6
+ const bg = bodyStyle.backgroundColor;
7
+ const text = bodyStyle.color;
8
+ const primaryBtn = document.querySelector(
9
+ 'button[class*="primary"], .btn-primary, [class*="btn-primary"], [class*="button-primary"]'
10
+ );
11
+ const primaryColor = primaryBtn ? window.getComputedStyle(primaryBtn).backgroundColor : void 0;
12
+ const firstLink = document.querySelector("a");
13
+ const linkColor = firstLink ? window.getComputedStyle(firstLink).color : void 0;
14
+ const headingEl = document.querySelector("h1, h2");
15
+ const bodyEl = document.body;
16
+ const headingFont = headingEl ? window.getComputedStyle(headingEl).fontFamily : bodyStyle.fontFamily;
17
+ const bodyFont = bodyStyle.fontFamily;
18
+ const logoEl = document.querySelector(
19
+ 'header img, img[alt*="logo" i], img[class*="logo" i], [class*="logo"] img, [id*="logo"] img'
20
+ );
21
+ const faviconEl = document.querySelector('link[rel="icon"], link[rel="shortcut icon"]');
22
+ const ogImageEl = document.querySelector('meta[property="og:image"]');
23
+ const titleEl = document.querySelector("title");
24
+ const descEl = document.querySelector('meta[name="description"]');
25
+ const themeColorEl = document.querySelector('meta[name="theme-color"]');
26
+ const hasBootstrap = !!document.querySelector('[class*="btn btn-"], .container-fluid, .navbar-expand');
27
+ const hasTailwind = !!document.querySelector('[class*="flex "], [class*="text-"], [class*="bg-"]');
28
+ const hasChakra = !!document.__chakra_factory__ || !!document.querySelector('[class*="chakra-"]');
29
+ const hasMUI = !!document.querySelector(".MuiButton-root, .MuiTypography-root");
30
+ const framework = hasBootstrap ? "Bootstrap" : hasTailwind ? "Tailwind CSS" : hasChakra ? "Chakra UI" : hasMUI ? "Material UI" : null;
31
+ return {
32
+ isDark,
33
+ bg,
34
+ text,
35
+ primaryColor,
36
+ linkColor,
37
+ headingFont,
38
+ bodyFont,
39
+ logo: logoEl?.src || logoEl?.getAttribute("src") || void 0,
40
+ favicon: faviconEl?.href || void 0,
41
+ ogImage: ogImageEl?.content || void 0,
42
+ title: titleEl?.textContent || void 0,
43
+ description: descEl?.content || void 0,
44
+ themeColor: themeColorEl?.content || void 0,
45
+ language: document.documentElement.lang || void 0,
46
+ framework
47
+ };
48
+ });
49
+ const fonts = [];
50
+ if (result.headingFont && result.headingFont !== result.bodyFont) {
51
+ fonts.push({ family: result.headingFont.split(",")[0].replace(/['"]/g, "").trim(), role: "heading" });
52
+ }
53
+ if (result.bodyFont) {
54
+ fonts.push({ family: result.bodyFont.split(",")[0].replace(/['"]/g, "").trim(), role: "body" });
55
+ }
56
+ const colorConfidence = result.bg || result.text || result.primaryColor ? 0.8 : 0.3;
57
+ const fontConfidence = fonts.length > 0 ? 0.7 : 0.2;
58
+ const imageConfidence = result.logo || result.ogImage ? 0.9 : 0.2;
59
+ return {
60
+ colorScheme: result.isDark ? "dark" : "light",
61
+ colors: {
62
+ background: result.bg || void 0,
63
+ textPrimary: result.text || void 0,
64
+ primary: result.primaryColor || void 0,
65
+ link: result.linkColor || void 0
66
+ },
67
+ fonts,
68
+ images: {
69
+ logo: result.logo,
70
+ favicon: result.favicon,
71
+ ogImage: result.ogImage
72
+ },
73
+ designSystem: {
74
+ framework: result.framework || void 0,
75
+ componentLibrary: void 0
76
+ },
77
+ metadata: {
78
+ title: result.title,
79
+ description: result.description,
80
+ themeColor: result.themeColor,
81
+ language: result.language
82
+ },
83
+ confidence: {
84
+ colors: colorConfidence,
85
+ fonts: fontConfidence,
86
+ images: imageConfidence,
87
+ overall: (colorConfidence + fontConfidence + imageConfidence) / 3
88
+ }
89
+ };
90
+ } catch (err) {
91
+ console.warn("[branding-extractor] Extraction failed:", err);
92
+ return {
93
+ colorScheme: "light",
94
+ colors: {},
95
+ fonts: [],
96
+ images: {},
97
+ confidence: { colors: 0, fonts: 0, images: 0, overall: 0 }
98
+ };
99
+ }
100
+ }
101
+ export {
102
+ extractBranding
103
+ };
104
+ //# sourceMappingURL=branding-extractor.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/extractors/branding-extractor.ts"],
4
+ "sourcesContent": ["import type { Page } from 'playwright';\n\nexport interface BrandingColors {\n primary?: string;\n accent?: string;\n background?: string;\n textPrimary?: string;\n link?: string;\n}\n\nexport interface BrandingFont {\n family: string;\n role: 'heading' | 'body';\n}\n\nexport interface BrandingImages {\n logo?: string;\n favicon?: string;\n ogImage?: string;\n}\n\nexport interface BrandingPersonality {\n tone?: string;\n energy?: 'high' | 'medium' | 'low';\n targetAudience?: string;\n}\n\nexport interface BrandingResult {\n colorScheme: 'light' | 'dark';\n colors: BrandingColors;\n fonts: BrandingFont[];\n images: BrandingImages;\n personality?: BrandingPersonality;\n designSystem?: { framework?: string; componentLibrary?: string };\n metadata?: { title?: string; description?: string; themeColor?: string; language?: string };\n confidence: { colors: number; fonts: number; images: number; overall: number };\n}\n\nexport async function extractBranding(page: Page): Promise<BrandingResult> {\n try {\n const result = await page.evaluate(() => {\n const bodyStyle = window.getComputedStyle(document.body);\n const isDark = window.matchMedia('(prefers-color-scheme: dark)').matches ||\n document.documentElement.getAttribute('data-theme') === 'dark' ||\n document.body.classList.contains('dark');\n\n // Extract colors from computed styles\n const bg = bodyStyle.backgroundColor;\n const text = bodyStyle.color;\n\n // Find primary button color\n const primaryBtn = document.querySelector(\n 'button[class*=\"primary\"], .btn-primary, [class*=\"btn-primary\"], [class*=\"button-primary\"]'\n );\n const primaryColor = primaryBtn ? window.getComputedStyle(primaryBtn).backgroundColor : undefined;\n\n // Find link color\n const firstLink = document.querySelector('a');\n const linkColor = firstLink ? window.getComputedStyle(firstLink).color : undefined;\n\n // Extract font families\n const headingEl = document.querySelector('h1, h2');\n const bodyEl = document.body;\n const headingFont = headingEl ? window.getComputedStyle(headingEl).fontFamily : bodyStyle.fontFamily;\n const bodyFont = bodyStyle.fontFamily;\n\n // Extract images\n const logoEl = document.querySelector(\n 'header img, img[alt*=\"logo\" i], img[class*=\"logo\" i], [class*=\"logo\"] img, [id*=\"logo\"] img'\n ) as HTMLImageElement | null;\n const faviconEl = document.querySelector('link[rel=\"icon\"], link[rel=\"shortcut icon\"]') as HTMLLinkElement | null;\n const ogImageEl = document.querySelector('meta[property=\"og:image\"]') as HTMLMetaElement | null;\n\n // Extract metadata\n const titleEl = document.querySelector('title');\n const descEl = document.querySelector('meta[name=\"description\"]') as HTMLMetaElement | null;\n const themeColorEl = document.querySelector('meta[name=\"theme-color\"]') as HTMLMetaElement | null;\n\n // Detect design framework\n const hasBootstrap = !!document.querySelector('[class*=\"btn btn-\"], .container-fluid, .navbar-expand');\n const hasTailwind = !!document.querySelector('[class*=\"flex \"], [class*=\"text-\"], [class*=\"bg-\"]');\n const hasChakra = !!(document as any).__chakra_factory__ || !!document.querySelector('[class*=\"chakra-\"]');\n const hasMUI = !!document.querySelector('.MuiButton-root, .MuiTypography-root');\n\n const framework = hasBootstrap ? 'Bootstrap' : hasTailwind ? 'Tailwind CSS' : hasChakra ? 'Chakra UI' : hasMUI ? 'Material UI' : null;\n\n return {\n isDark,\n bg,\n text,\n primaryColor,\n linkColor,\n headingFont,\n bodyFont,\n logo: logoEl?.src || logoEl?.getAttribute('src') || undefined,\n favicon: faviconEl?.href || undefined,\n ogImage: ogImageEl?.content || undefined,\n title: titleEl?.textContent || undefined,\n description: descEl?.content || undefined,\n themeColor: themeColorEl?.content || undefined,\n language: document.documentElement.lang || undefined,\n framework,\n };\n });\n\n const fonts: BrandingFont[] = [];\n if (result.headingFont && result.headingFont !== result.bodyFont) {\n fonts.push({ family: result.headingFont.split(',')[0].replace(/['\"]/g, '').trim(), role: 'heading' });\n }\n if (result.bodyFont) {\n fonts.push({ family: result.bodyFont.split(',')[0].replace(/['\"]/g, '').trim(), role: 'body' });\n }\n\n const colorConfidence = (result.bg || result.text || result.primaryColor) ? 0.8 : 0.3;\n const fontConfidence = fonts.length > 0 ? 0.7 : 0.2;\n const imageConfidence = (result.logo || result.ogImage) ? 0.9 : 0.2;\n\n return {\n colorScheme: result.isDark ? 'dark' : 'light',\n colors: {\n background: result.bg || undefined,\n textPrimary: result.text || undefined,\n primary: result.primaryColor || undefined,\n link: result.linkColor || undefined,\n },\n fonts,\n images: {\n logo: result.logo,\n favicon: result.favicon,\n ogImage: result.ogImage,\n },\n designSystem: {\n framework: result.framework || undefined,\n componentLibrary: undefined,\n },\n metadata: {\n title: result.title,\n description: result.description,\n themeColor: result.themeColor,\n language: result.language,\n },\n confidence: {\n colors: colorConfidence,\n fonts: fontConfidence,\n images: imageConfidence,\n overall: (colorConfidence + fontConfidence + imageConfidence) / 3,\n },\n };\n } catch (err) {\n console.warn('[branding-extractor] Extraction failed:', err);\n return {\n colorScheme: 'light',\n colors: {},\n fonts: [],\n images: {},\n confidence: { colors: 0, fonts: 0, images: 0, overall: 0 },\n };\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,10 @@
1
+ export interface SummaryResult {
2
+ summary: string;
3
+ wordCount: number;
4
+ method: 'llm' | 'truncated';
5
+ model?: string;
6
+ }
7
+ export declare function extractSummary(markdown: string, options?: {
8
+ model?: string;
9
+ maxTokens?: number;
10
+ }): Promise<SummaryResult>;