@taodigital/crawler 0.0.0-stage → 1.2.1
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/Dockerfile +82 -0
- package/README.md +10 -2
- package/dist/accessibility-auditor.d.ts +29 -0
- package/dist/accessibility-auditor.js +57 -0
- package/dist/accessibility-auditor.js.map +7 -0
- package/dist/accessibility-tree-crawler.d.ts +44 -0
- package/dist/accessibility-tree-crawler.js +156 -0
- package/dist/accessibility-tree-crawler.js.map +7 -0
- package/dist/advanced-ui-probes.d.ts +47 -0
- package/dist/advanced-ui-probes.js +310 -0
- package/dist/advanced-ui-probes.js.map +7 -0
- package/dist/ai-login.d.ts +32 -0
- package/dist/ai-login.js +250 -0
- package/dist/ai-login.js.map +7 -0
- package/dist/auth-token-rotator.d.ts +47 -0
- package/dist/auth-token-rotator.js +58 -0
- package/dist/auth-token-rotator.js.map +7 -0
- package/dist/auth.d.ts +20 -0
- package/dist/auth.js +348 -0
- package/dist/auth.js.map +7 -0
- package/dist/browser-extension.d.ts +37 -0
- package/dist/browser-extension.js +113 -0
- package/dist/browser-extension.js.map +7 -0
- package/dist/captcha-solver.d.ts +16 -0
- package/dist/captcha-solver.js +105 -0
- package/dist/captcha-solver.js.map +7 -0
- package/dist/color-contrast.d.ts +30 -0
- package/dist/color-contrast.js +78 -0
- package/dist/color-contrast.js.map +7 -0
- package/dist/content-chunker.d.ts +18 -0
- package/dist/content-chunker.js +152 -0
- package/dist/content-chunker.js.map +7 -0
- package/dist/content-dedup.d.ts +23 -0
- package/dist/content-dedup.js +60 -0
- package/dist/content-dedup.js.map +7 -0
- package/dist/cookie-consent.d.ts +25 -0
- package/dist/cookie-consent.js +78 -0
- package/dist/cookie-consent.js.map +7 -0
- package/dist/cookie-jar.d.ts +20 -0
- package/dist/cookie-jar.js +61 -0
- package/dist/cookie-jar.js.map +7 -0
- package/dist/crawl-session-manager.d.ts +44 -0
- package/dist/crawl-session-manager.js +145 -0
- package/dist/crawl-session-manager.js.map +7 -0
- package/dist/crawler.d.ts +233 -0
- package/dist/crawler.js +6239 -0
- package/dist/crawler.js.map +7 -0
- package/dist/crud-interaction.d.ts +31 -0
- package/dist/crud-interaction.js +264 -0
- package/dist/crud-interaction.js.map +7 -0
- package/dist/custom-js-injector.d.ts +42 -0
- package/dist/custom-js-injector.js +50 -0
- package/dist/custom-js-injector.js.map +7 -0
- package/dist/dark-mode-capture.d.ts +23 -0
- package/dist/dark-mode-capture.js +75 -0
- package/dist/dark-mode-capture.js.map +7 -0
- package/dist/dead-link-detector.d.ts +37 -0
- package/dist/dead-link-detector.js +50 -0
- package/dist/dead-link-detector.js.map +7 -0
- package/dist/dropdown-enumerator.d.ts +20 -0
- package/dist/dropdown-enumerator.js +230 -0
- package/dist/dropdown-enumerator.js.map +7 -0
- package/dist/element-hash.d.ts +9 -0
- package/dist/element-hash.js +9 -0
- package/dist/element-hash.js.map +7 -0
- package/dist/email-otp.d.ts +42 -0
- package/dist/email-otp.js +177 -0
- package/dist/email-otp.js.map +7 -0
- package/dist/engine-router.d.ts +47 -0
- package/dist/engine-router.js +94 -0
- package/dist/engine-router.js.map +7 -0
- package/dist/export/bulk-export.d.ts +26 -0
- package/dist/export/bulk-export.js +76 -0
- package/dist/export/bulk-export.js.map +7 -0
- package/dist/export/vector-export.d.ts +76 -0
- package/dist/export/vector-export.js +85 -0
- package/dist/export/vector-export.js.map +7 -0
- package/dist/extractors/advanced.d.ts +64 -0
- package/dist/extractors/advanced.js +265 -0
- package/dist/extractors/advanced.js.map +7 -0
- package/dist/extractors/artifact-envelope.d.ts +63 -0
- package/dist/extractors/artifact-envelope.js +63 -0
- package/dist/extractors/artifact-envelope.js.map +7 -0
- package/dist/extractors/branding-extractor.d.ts +46 -0
- package/dist/extractors/branding-extractor.js +104 -0
- package/dist/extractors/branding-extractor.js.map +7 -0
- package/dist/extractors/summary-extractor.d.ts +10 -0
- package/dist/extractors/summary-extractor.js +36 -0
- package/dist/extractors/summary-extractor.js.map +7 -0
- package/dist/failure-analysis-agent.d.ts +16 -0
- package/dist/failure-analysis-agent.js +42 -0
- package/dist/failure-analysis-agent.js.map +7 -0
- package/dist/feature-flag-detector.d.ts +30 -0
- package/dist/feature-flag-detector.js +55 -0
- package/dist/feature-flag-detector.js.map +7 -0
- package/dist/filter-pagination-crawler.d.ts +52 -0
- package/dist/filter-pagination-crawler.js +299 -0
- package/dist/filter-pagination-crawler.js.map +7 -0
- package/dist/form-detector.d.ts +34 -0
- package/dist/form-detector.js +58 -0
- package/dist/form-detector.js.map +7 -0
- package/dist/frontier.d.ts +40 -0
- package/dist/frontier.js +103 -0
- package/dist/frontier.js.map +7 -0
- package/dist/gap-pass.d.ts +36 -0
- package/dist/gap-pass.js +115 -0
- package/dist/gap-pass.js.map +7 -0
- package/dist/graphql-detector.d.ts +39 -0
- package/dist/graphql-detector.js +86 -0
- package/dist/graphql-detector.js.map +7 -0
- package/dist/http-engine.d.ts +80 -0
- package/dist/http-engine.js +318 -0
- package/dist/http-engine.js.map +7 -0
- package/dist/incremental-diff.d.ts +116 -0
- package/dist/incremental-diff.js +137 -0
- package/dist/incremental-diff.js.map +7 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.js +83 -0
- package/dist/index.js.map +7 -0
- package/dist/input-fuzzer.d.ts +30 -0
- package/dist/input-fuzzer.js +105 -0
- package/dist/input-fuzzer.js.map +7 -0
- package/dist/interactive-probe.d.ts +144 -0
- package/dist/interactive-probe.js +865 -0
- package/dist/interactive-probe.js.map +7 -0
- package/dist/job-queue.d.ts +297 -0
- package/dist/job-queue.js +3812 -0
- package/dist/job-queue.js.map +7 -0
- package/dist/js-coverage.d.ts +29 -0
- package/dist/js-coverage.js +56 -0
- package/dist/js-coverage.js.map +7 -0
- package/dist/js-router-detector.d.ts +17 -0
- package/dist/js-router-detector.js +90 -0
- package/dist/js-router-detector.js.map +7 -0
- package/dist/language-detector.d.ts +22 -0
- package/dist/language-detector.js +57 -0
- package/dist/language-detector.js.map +7 -0
- package/dist/link-classifier.d.ts +23 -0
- package/dist/link-classifier.js +40 -0
- package/dist/link-classifier.js.map +7 -0
- package/dist/live-view.d.ts +36 -0
- package/dist/live-view.js +105 -0
- package/dist/live-view.js.map +7 -0
- package/dist/locator-extractor.d.ts +46 -0
- package/dist/locator-extractor.js +220 -0
- package/dist/locator-extractor.js.map +7 -0
- package/dist/logger.d.ts +2 -0
- package/dist/logger.js +10 -0
- package/dist/logger.js.map +7 -0
- package/dist/markdown-extract.d.ts +8 -0
- package/dist/markdown-extract.js +54 -0
- package/dist/markdown-extract.js.map +7 -0
- package/dist/multi-context-handler.d.ts +55 -0
- package/dist/multi-context-handler.js +182 -0
- package/dist/multi-context-handler.js.map +7 -0
- package/dist/native-crawler.d.ts +69 -0
- package/dist/native-crawler.js +839 -0
- package/dist/native-crawler.js.map +7 -0
- package/dist/nested-window-crawler.d.ts +41 -0
- package/dist/nested-window-crawler.js +172 -0
- package/dist/nested-window-crawler.js.map +7 -0
- package/dist/network-action-correlator.d.ts +47 -0
- package/dist/network-action-correlator.js +209 -0
- package/dist/network-action-correlator.js.map +7 -0
- package/dist/network-observer.d.ts +49 -0
- package/dist/network-observer.js +149 -0
- package/dist/network-observer.js.map +7 -0
- package/dist/network-throttle.d.ts +25 -0
- package/dist/network-throttle.js +34 -0
- package/dist/network-throttle.js.map +7 -0
- package/dist/openapi-generator.d.ts +49 -0
- package/dist/openapi-generator.js +89 -0
- package/dist/openapi-generator.js.map +7 -0
- package/dist/pdf-extractor.d.ts +28 -0
- package/dist/pdf-extractor.js +81 -0
- package/dist/pdf-extractor.js.map +7 -0
- package/dist/performance-metrics-collector.d.ts +50 -0
- package/dist/performance-metrics-collector.js +155 -0
- package/dist/performance-metrics-collector.js.map +7 -0
- package/dist/performance-metrics.d.ts +52 -0
- package/dist/performance-metrics.js +83 -0
- package/dist/performance-metrics.js.map +7 -0
- package/dist/phash.d.ts +50 -0
- package/dist/phash.js +136 -0
- package/dist/phash.js.map +7 -0
- package/dist/pii-scrubber.d.ts +21 -0
- package/dist/pii-scrubber.js +75 -0
- package/dist/pii-scrubber.js.map +7 -0
- package/dist/playwright-recorder.d.ts +39 -0
- package/dist/playwright-recorder.js +123 -0
- package/dist/playwright-recorder.js.map +7 -0
- package/dist/policies/crawl-safety.d.ts +9 -0
- package/dist/policies/crawl-safety.js +41 -0
- package/dist/policies/crawl-safety.js.map +7 -0
- package/dist/profiles/domain-profile.d.ts +19 -0
- package/dist/profiles/domain-profile.js +160 -0
- package/dist/profiles/domain-profile.js.map +7 -0
- package/dist/proxy.d.ts +50 -0
- package/dist/proxy.js +165 -0
- package/dist/proxy.js.map +7 -0
- package/dist/rate-limiter.d.ts +31 -0
- package/dist/rate-limiter.js +64 -0
- package/dist/rate-limiter.js.map +7 -0
- package/dist/redirect-tracker.d.ts +37 -0
- package/dist/redirect-tracker.js +65 -0
- package/dist/redirect-tracker.js.map +7 -0
- package/dist/redis-frontier.d.ts +48 -0
- package/dist/redis-frontier.js +126 -0
- package/dist/redis-frontier.js.map +7 -0
- package/dist/redis-queue.d.ts +48 -0
- package/dist/redis-queue.js +165 -0
- package/dist/redis-queue.js.map +7 -0
- package/dist/response-cache.d.ts +38 -0
- package/dist/response-cache.js +140 -0
- package/dist/response-cache.js.map +7 -0
- package/dist/responsive-detector.d.ts +29 -0
- package/dist/responsive-detector.js +46 -0
- package/dist/responsive-detector.js.map +7 -0
- package/dist/retry-policy.d.ts +20 -0
- package/dist/retry-policy.js +54 -0
- package/dist/retry-policy.js.map +7 -0
- package/dist/robots-txt.d.ts +9 -0
- package/dist/robots-txt.js +77 -0
- package/dist/robots-txt.js.map +7 -0
- package/dist/screen-reader.d.ts +15 -0
- package/dist/screen-reader.js +48 -0
- package/dist/screen-reader.js.map +7 -0
- package/dist/screenshot-masker.d.ts +28 -0
- package/dist/screenshot-masker.js +62 -0
- package/dist/screenshot-masker.js.map +7 -0
- package/dist/seo-checker.d.ts +33 -0
- package/dist/seo-checker.js +91 -0
- package/dist/seo-checker.js.map +7 -0
- package/dist/service-worker-interceptor.d.ts +36 -0
- package/dist/service-worker-interceptor.js +136 -0
- package/dist/service-worker-interceptor.js.map +7 -0
- package/dist/session-capture.d.ts +39 -0
- package/dist/session-capture.js +274 -0
- package/dist/session-capture.js.map +7 -0
- package/dist/session-export.d.ts +49 -0
- package/dist/session-export.js +117 -0
- package/dist/session-export.js.map +7 -0
- package/dist/shadow-dom-crawler.d.ts +35 -0
- package/dist/shadow-dom-crawler.js +132 -0
- package/dist/shadow-dom-crawler.js.map +7 -0
- package/dist/sitemap-writer.d.ts +21 -0
- package/dist/sitemap-writer.js +47 -0
- package/dist/sitemap-writer.js.map +7 -0
- package/dist/sitemap.d.ts +51 -0
- package/dist/sitemap.js +160 -0
- package/dist/sitemap.js.map +7 -0
- package/dist/skyvern.d.ts +56 -0
- package/dist/skyvern.js +129 -0
- package/dist/skyvern.js.map +7 -0
- package/dist/sqs-queue.d.ts +13 -0
- package/dist/sqs-queue.js +115 -0
- package/dist/sqs-queue.js.map +7 -0
- package/dist/sso-token.d.ts +29 -0
- package/dist/sso-token.js +76 -0
- package/dist/sso-token.js.map +7 -0
- package/dist/state-graph.d.ts +59 -0
- package/dist/state-graph.js +193 -0
- package/dist/state-graph.js.map +7 -0
- package/dist/stealth/human-behavior.d.ts +20 -0
- package/dist/stealth/human-behavior.js +202 -0
- package/dist/stealth/human-behavior.js.map +7 -0
- package/dist/telemetry.d.ts +34 -0
- package/dist/telemetry.js +77 -0
- package/dist/telemetry.js.map +7 -0
- package/dist/test-executor.d.ts +81 -0
- package/dist/test-executor.js +443 -0
- package/dist/test-executor.js.map +7 -0
- package/dist/tls-fingerprint.d.ts +50 -0
- package/dist/tls-fingerprint.js +81 -0
- package/dist/tls-fingerprint.js.map +7 -0
- package/dist/url-pattern-completer.d.ts +28 -0
- package/dist/url-pattern-completer.js +122 -0
- package/dist/url-pattern-completer.js.map +7 -0
- package/dist/visual-diff-verdict.d.ts +40 -0
- package/dist/visual-diff-verdict.js +27 -0
- package/dist/visual-diff-verdict.js.map +7 -0
- package/dist/webhook-notifier.d.ts +30 -0
- package/dist/webhook-notifier.js +76 -0
- package/dist/webhook-notifier.js.map +7 -0
- package/dist/websocket-detector.d.ts +24 -0
- package/dist/websocket-detector.js +60 -0
- package/dist/websocket-detector.js.map +7 -0
- package/dist/worker.d.ts +1 -0
- package/dist/worker.js +33 -0
- package/dist/worker.js.map +7 -0
- package/package.json +49 -4
- package/src/accessibility-auditor.ts +102 -0
- package/src/accessibility-tree-crawler.ts +246 -0
- package/src/advanced-ui-probes.ts +470 -0
- package/src/ai-login.ts +298 -0
- package/src/auth-token-rotator.ts +89 -0
- package/src/auth.ts +418 -0
- package/src/browser-extension.ts +186 -0
- package/src/captcha-solver.ts +143 -0
- package/src/color-contrast.ts +116 -0
- package/src/content-chunker.ts +170 -0
- package/src/content-dedup.ts +99 -0
- package/src/cookie-consent.ts +106 -0
- package/src/cookie-jar.ts +91 -0
- package/src/crawl-session-manager.ts +231 -0
- package/src/crawler.ts +7123 -0
- package/src/crawler.ts.rej +12 -0
- package/src/crud-interaction.ts +386 -0
- package/src/custom-js-injector.ts +93 -0
- package/src/dark-mode-capture.ts +110 -0
- package/src/dead-link-detector.ts +76 -0
- package/src/dropdown-enumerator.ts +312 -0
- package/src/element-hash.ts +16 -0
- package/src/email-otp.ts +252 -0
- package/src/engine-router.ts +141 -0
- package/src/export/bulk-export.ts +85 -0
- package/src/export/vector-export.ts +160 -0
- package/src/extractors/advanced.ts +309 -0
- package/src/extractors/artifact-envelope.ts +111 -0
- package/src/extractors/branding-extractor.ts +159 -0
- package/src/extractors/summary-extractor.ts +49 -0
- package/src/failure-analysis-agent.ts +51 -0
- package/src/feature-flag-detector.ts +97 -0
- package/src/filter-pagination-crawler.ts +500 -0
- package/src/form-detector.ts +103 -0
- package/src/frontier.test.ts +64 -0
- package/src/frontier.ts +144 -0
- package/src/gap-pass.ts +165 -0
- package/src/graphql-detector.ts +129 -0
- package/src/http-engine.ts +453 -0
- package/src/incremental-diff.ts +259 -0
- package/src/index.ts +52 -0
- package/src/input-fuzzer.ts +129 -0
- package/src/interactive-probe.ts +1136 -0
- package/src/job-queue.test.ts +187 -0
- package/src/job-queue.ts +4504 -0
- package/src/js-coverage.ts +87 -0
- package/src/js-router-detector.ts +112 -0
- package/src/language-detector.ts +82 -0
- package/src/link-classifier.ts +65 -0
- package/src/live-view.ts +146 -0
- package/src/locator-extractor.ts +309 -0
- package/src/logger.ts +9 -0
- package/src/markdown-extract.test.ts +73 -0
- package/src/markdown-extract.ts +76 -0
- package/src/multi-context-handler.ts +296 -0
- package/src/native-crawler.ts +1108 -0
- package/src/nested-window-crawler.ts +310 -0
- package/src/network-action-correlator.ts +320 -0
- package/src/network-observer.ts +204 -0
- package/src/network-throttle.ts +69 -0
- package/src/openapi-generator.ts +135 -0
- package/src/pdf-extractor.ts +123 -0
- package/src/performance-metrics-collector.ts +243 -0
- package/src/performance-metrics.ts +134 -0
- package/src/phash.ts +184 -0
- package/src/pii-scrubber.ts +99 -0
- package/src/playwright-recorder.ts +170 -0
- package/src/policies/crawl-safety.ts +52 -0
- package/src/profiles/domain-profile.ts +190 -0
- package/src/proxy.ts +238 -0
- package/src/rate-limiter.ts +87 -0
- package/src/redirect-tracker.ts +97 -0
- package/src/redis-frontier.ts +143 -0
- package/src/redis-queue.ts +208 -0
- package/src/response-cache.ts +150 -0
- package/src/responsive-detector.ts +92 -0
- package/src/retry-policy.ts +87 -0
- package/src/robots-txt.ts +96 -0
- package/src/screen-reader.ts +98 -0
- package/src/screenshot-masker.ts +98 -0
- package/src/seo-checker.ts +134 -0
- package/src/service-worker-interceptor.ts +185 -0
- package/src/session-capture.ts +335 -0
- package/src/session-export.test.ts +75 -0
- package/src/session-export.ts +172 -0
- package/src/shadow-dom-crawler.ts +198 -0
- package/src/sitemap-writer.ts +65 -0
- package/src/sitemap.test.ts +127 -0
- package/src/sitemap.ts +233 -0
- package/src/skyvern.ts +199 -0
- package/src/sqs-queue.ts +129 -0
- package/src/sso-token.ts +120 -0
- package/src/state-graph.ts +280 -0
- package/src/stealth/human-behavior.ts +227 -0
- package/src/telemetry.ts +122 -0
- package/src/test-executor.test.ts +72 -0
- package/src/test-executor.ts +578 -0
- package/src/tls-fingerprint.ts +111 -0
- package/src/url-pattern-completer.ts +161 -0
- package/src/vendor.d.ts +20 -0
- package/src/visual-diff-verdict.test.ts +80 -0
- package/src/visual-diff-verdict.ts +59 -0
- package/src/webhook-notifier.ts +109 -0
- package/src/websocket-detector.ts +83 -0
- package/src/worker.ts +50 -0
- package/tsconfig.json +13 -0
- package/types/accessibility-auditor.d.ts +29 -0
- package/types/accessibility-tree-crawler.d.ts +44 -0
- package/types/advanced-ui-probes.d.ts +47 -0
- package/types/ai-login.d.ts +32 -0
- package/types/auth-token-rotator.d.ts +47 -0
- package/types/auth.d.ts +20 -0
- package/types/browser-extension.d.ts +37 -0
- package/types/bull-worker.d.ts +6 -0
- package/types/captcha-solver.d.ts +16 -0
- package/types/color-contrast.d.ts +30 -0
- package/types/content-chunker.d.ts +18 -0
- package/types/content-dedup.d.ts +23 -0
- package/types/cookie-consent.d.ts +25 -0
- package/types/cookie-jar.d.ts +20 -0
- package/types/crawl-session-manager.d.ts +44 -0
- package/types/crawler.d.ts +233 -0
- package/types/crud-interaction.d.ts +31 -0
- package/types/custom-js-injector.d.ts +42 -0
- package/types/dark-mode-capture.d.ts +23 -0
- package/types/dead-link-detector.d.ts +37 -0
- package/types/dropdown-enumerator.d.ts +20 -0
- package/types/element-hash.d.ts +9 -0
- package/types/email-otp.d.ts +42 -0
- package/types/engine-router.d.ts +47 -0
- package/types/export/bulk-export.d.ts +26 -0
- package/types/export/vector-export.d.ts +76 -0
- package/types/extractors/advanced.d.ts +64 -0
- package/types/extractors/artifact-envelope.d.ts +63 -0
- package/types/extractors/branding-extractor.d.ts +46 -0
- package/types/extractors/summary-extractor.d.ts +10 -0
- package/types/failure-analysis-agent.d.ts +16 -0
- package/types/feature-flag-detector.d.ts +30 -0
- package/types/filter-pagination-crawler.d.ts +52 -0
- package/types/form-detector.d.ts +34 -0
- package/types/frontier.d.ts +40 -0
- package/types/gap-pass.d.ts +36 -0
- package/types/graphql-detector.d.ts +39 -0
- package/types/http-engine.d.ts +80 -0
- package/types/incremental-diff.d.ts +116 -0
- package/types/index.d.ts +52 -0
- package/types/input-fuzzer.d.ts +30 -0
- package/types/interactive-probe.d.ts +144 -0
- package/types/job-queue.d.ts +308 -0
- package/types/js-coverage.d.ts +29 -0
- package/types/js-router-detector.d.ts +17 -0
- package/types/language-detector.d.ts +22 -0
- package/types/link-classifier.d.ts +23 -0
- package/types/live-view.d.ts +36 -0
- package/types/locator-extractor.d.ts +46 -0
- package/types/logger.d.ts +2 -0
- package/types/markdown-extract.d.ts +8 -0
- package/types/multi-context-handler.d.ts +55 -0
- package/types/native-crawler.d.ts +69 -0
- package/types/nested-window-crawler.d.ts +41 -0
- package/types/network-action-correlator.d.ts +47 -0
- package/types/network-observer.d.ts +49 -0
- package/types/network-throttle.d.ts +25 -0
- package/types/openapi-generator.d.ts +49 -0
- package/types/pdf-extractor.d.ts +28 -0
- package/types/performance-metrics-collector.d.ts +50 -0
- package/types/performance-metrics.d.ts +52 -0
- package/types/phash.d.ts +50 -0
- package/types/pii-scrubber.d.ts +21 -0
- package/types/playwright-recorder.d.ts +39 -0
- package/types/policies/crawl-safety.d.ts +9 -0
- package/types/profiles/domain-profile.d.ts +19 -0
- package/types/proxy.d.ts +50 -0
- package/types/rate-limiter.d.ts +31 -0
- package/types/redirect-tracker.d.ts +37 -0
- package/types/redis-frontier.d.ts +48 -0
- package/types/redis-queue.d.ts +48 -0
- package/types/response-cache.d.ts +38 -0
- package/types/responsive-detector.d.ts +29 -0
- package/types/retry-policy.d.ts +20 -0
- package/types/robots-txt.d.ts +9 -0
- package/types/screen-reader.d.ts +15 -0
- package/types/screenshot-masker.d.ts +28 -0
- package/types/seo-checker.d.ts +33 -0
- package/types/service-worker-interceptor.d.ts +36 -0
- package/types/session-capture.d.ts +39 -0
- package/types/session-export.d.ts +49 -0
- package/types/shadow-dom-crawler.d.ts +35 -0
- package/types/sitemap-writer.d.ts +21 -0
- package/types/sitemap.d.ts +51 -0
- package/types/skyvern.d.ts +56 -0
- package/types/sqs-queue.d.ts +13 -0
- package/types/sso-token.d.ts +29 -0
- package/types/state-graph.d.ts +59 -0
- package/types/stealth/human-behavior.d.ts +20 -0
- package/types/telemetry.d.ts +34 -0
- package/types/test-executor.d.ts +84 -0
- package/types/tls-fingerprint.d.ts +50 -0
- package/types/url-pattern-completer.d.ts +28 -0
- package/types/visual-diff-verdict.d.ts +40 -0
- package/types/webhook-notifier.d.ts +30 -0
- package/types/websocket-detector.d.ts +24 -0
- 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>;
|