dembrandt 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -354
- package/index.js +11 -7
- package/lib/display.js +575 -205
- package/lib/extractors.js +1188 -369
- package/package.json +7 -6
package/README.md
CHANGED
|
@@ -4,403 +4,101 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/dembrandt)
|
|
5
5
|
[](https://github.com/thevangelist/dembrandt/blob/main/LICENSE)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Extract any website’s design system into design tokens in a few seconds: logo, colors, typography, borders, and more. One command.
|
|
8
8
|
|
|
9
9
|

|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Install
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
npx dembrandt
|
|
14
|
+
npx dembrandt bmw.de
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Or install globally: `npm install -g dembrandt` then run `dembrandt bmw.de`
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Requires Node.js 18+
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
## What to expect from extraction?
|
|
22
22
|
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
-
|
|
31
|
-
- **Inputs** — Form field styles (input, textarea, select)
|
|
32
|
-
- **Links** — Link styles with hover states and decorations
|
|
33
|
-
- **Breakpoints** — Responsive design breakpoints from media queries
|
|
34
|
-
- **Icons** — Icon system detection (Font Awesome, Material Icons, SVG)
|
|
35
|
-
- **Frameworks** — CSS framework detection (Tailwind, Bootstrap, Material-UI, Chakra)
|
|
36
|
-
|
|
37
|
-
Perfect for competitive analysis, brand audits, or rebuilding a brand when you don't have design guidelines.
|
|
38
|
-
|
|
39
|
-
## Why It Matters
|
|
40
|
-
|
|
41
|
-
**Designers** — Analyze competitor systems, document production tokens, audit brand consistency
|
|
42
|
-
|
|
43
|
-
**Developers** — Migrate design tokens, reverse engineer components, validate implementations
|
|
44
|
-
|
|
45
|
-
**Product Managers** — Track competitor evolution, quantify design debt, evaluate vendors
|
|
46
|
-
|
|
47
|
-
**Marketing** — Audit competitor brands, plan rebrands, monitor brand compliance
|
|
48
|
-
|
|
49
|
-
**Engineering Leaders** — Measure technical debt, plan migrations, assess acquisition targets
|
|
50
|
-
|
|
51
|
-
## How It Works
|
|
52
|
-
|
|
53
|
-
Uses Playwright to render the page, extracts computed styles from the DOM, analyzes color usage and confidence, groups similar typography, detects spacing patterns, and returns actionable design tokens.
|
|
54
|
-
|
|
55
|
-
### Extraction Process
|
|
56
|
-
|
|
57
|
-
1. **Browser Launch** - Launches Chromium with stealth configuration
|
|
58
|
-
2. **Anti-Detection** - Injects scripts to bypass bot detection
|
|
59
|
-
3. **Navigation** - Navigates to target URL with retry logic
|
|
60
|
-
4. **Hydration** - Waits for SPAs to fully load (8s initial + 4s stabilization)
|
|
61
|
-
5. **Content Validation** - Verifies page content is substantial (>500 chars)
|
|
62
|
-
6. **Parallel Extraction** - Runs all extractors concurrently for speed
|
|
63
|
-
7. **Analysis** - Analyzes computed styles, DOM structure, and CSS variables
|
|
64
|
-
8. **Scoring** - Assigns confidence scores based on context and usage
|
|
65
|
-
|
|
66
|
-
### Color Confidence
|
|
67
|
-
|
|
68
|
-
- **High** — Logo, brand elements, primary buttons
|
|
69
|
-
- **Medium** — Interactive elements, icons, navigation
|
|
70
|
-
- **Low** — Generic UI components (filtered from display)
|
|
71
|
-
|
|
72
|
-
Only shows high and medium confidence colors in terminal. Full palette in JSON.
|
|
73
|
-
|
|
74
|
-
### Typography Detection
|
|
75
|
-
|
|
76
|
-
Samples all heading levels (h1-h6), body text, buttons, links. Groups by font family, size, and weight. Detects Google Fonts, Adobe Fonts, custom @font-face.
|
|
77
|
-
|
|
78
|
-
### Framework Detection
|
|
79
|
-
|
|
80
|
-
Recognizes Tailwind CSS, Bootstrap, Material-UI, and others by class patterns and CDN links.
|
|
81
|
-
|
|
82
|
-
## Installation
|
|
83
|
-
|
|
84
|
-
### Using npx (Recommended)
|
|
85
|
-
|
|
86
|
-
No installation needed! Run directly with `npx`:
|
|
87
|
-
|
|
88
|
-
```bash
|
|
89
|
-
npx dembrandt stripe.com
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
The first run will automatically install Chromium (~170MB).
|
|
93
|
-
|
|
94
|
-
### Global Installation
|
|
95
|
-
|
|
96
|
-
Install globally for repeated use:
|
|
97
|
-
|
|
98
|
-
```bash
|
|
99
|
-
npm install -g dembrandt
|
|
100
|
-
dembrandt stripe.com
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
### Prerequisites
|
|
104
|
-
|
|
105
|
-
- Node.js 18 or higher
|
|
106
|
-
|
|
107
|
-
### Development Setup
|
|
108
|
-
|
|
109
|
-
For contributors who want to work on dembrandt:
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
git clone https://github.com/thevangelist/dembrandt.git
|
|
113
|
-
cd dembrandt
|
|
114
|
-
npm install
|
|
115
|
-
npm link
|
|
116
|
-
```
|
|
23
|
+
- Colors (semantic, palette, CSS variables)
|
|
24
|
+
- Typography (fonts, sizes, weights, sources)
|
|
25
|
+
- Spacing (margin/padding scales)
|
|
26
|
+
- Borders (radius, widths, styles, colors)
|
|
27
|
+
- Shadows
|
|
28
|
+
- Components (buttons, inputs, links)
|
|
29
|
+
- Breakpoints
|
|
30
|
+
- Icons & frameworks
|
|
117
31
|
|
|
118
32
|
## Usage
|
|
119
33
|
|
|
120
|
-
### Basic Usage
|
|
121
|
-
|
|
122
|
-
```bash
|
|
123
|
-
# Using npx (no installation)
|
|
124
|
-
npx dembrandt <url>
|
|
125
|
-
|
|
126
|
-
# Or if installed globally
|
|
127
|
-
dembrandt <url>
|
|
128
|
-
|
|
129
|
-
# Examples
|
|
130
|
-
dembrandt stripe.com
|
|
131
|
-
dembrandt https://github.com
|
|
132
|
-
dembrandt tailwindcss.com
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### Options
|
|
136
|
-
|
|
137
|
-
**`--json-only`** - Output raw JSON to stdout instead of formatted terminal display
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
dembrandt stripe.com --json-only > tokens.json
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
Note: JSON is automatically saved to `output/domain.com/` regardless of this flag.
|
|
144
|
-
|
|
145
|
-
**`-d, --debug`** - Run with visible browser and detailed logs
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
dembrandt stripe.com --debug
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
Useful for troubleshooting bot detection, timeouts, or extraction issues.
|
|
152
|
-
|
|
153
|
-
**`--verbose-colors`** - Show medium and low confidence colors in terminal output
|
|
154
|
-
|
|
155
|
-
```bash
|
|
156
|
-
dembrandt stripe.com --verbose-colors
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
By default, only high-confidence colors are shown. Use this flag to see all detected colors.
|
|
160
|
-
|
|
161
|
-
**`--dark-mode`** - Extract colors from dark mode
|
|
162
|
-
|
|
163
|
-
```bash
|
|
164
|
-
dembrandt stripe.com --dark-mode
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
Enables dark mode preference detection for sites that support it.
|
|
168
|
-
|
|
169
|
-
**`--mobile`** - Extract from mobile viewport
|
|
170
|
-
|
|
171
|
-
```bash
|
|
172
|
-
dembrandt stripe.com --mobile
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
Simulates a mobile device viewport for responsive design token extraction.
|
|
176
|
-
|
|
177
|
-
## Output
|
|
178
|
-
|
|
179
|
-
### Automatic JSON Saves
|
|
180
|
-
|
|
181
|
-
Every extraction is automatically saved to `output/domain.com/YYYY-MM-DDTHH-MM-SS.json` with:
|
|
182
|
-
|
|
183
|
-
- Complete design token data
|
|
184
|
-
- Timestamped for version tracking
|
|
185
|
-
- Organized by domain
|
|
186
|
-
|
|
187
|
-
Example: `output/stripe.com/2025-11-22T14-30-45.json`
|
|
188
|
-
|
|
189
|
-
### Terminal Output
|
|
190
|
-
|
|
191
|
-
Clean, formatted tables showing:
|
|
192
|
-
|
|
193
|
-
- Color palette with confidence ratings (with visual swatches)
|
|
194
|
-
- CSS variables with color previews
|
|
195
|
-
- Typography hierarchy with context
|
|
196
|
-
- Spacing scale (4px/8px grid detection)
|
|
197
|
-
- Shadow system
|
|
198
|
-
- Button variants
|
|
199
|
-
- Component style breakdowns
|
|
200
|
-
- Framework and icon system detection
|
|
201
|
-
|
|
202
|
-
### JSON Output Format
|
|
203
|
-
|
|
204
|
-
Complete extraction data for programmatic use:
|
|
205
|
-
|
|
206
|
-
```json
|
|
207
|
-
{
|
|
208
|
-
"url": "https://example.com",
|
|
209
|
-
"extractedAt": "2025-11-22T...",
|
|
210
|
-
"logo": { "source": "img", "url": "...", "width": 120, "height": 40 },
|
|
211
|
-
"colors": {
|
|
212
|
-
"semantic": { "primary": "#3b82f6", ... },
|
|
213
|
-
"palette": [{ "color": "#3b82f6", "confidence": "high", "count": 45, "sources": [...] }],
|
|
214
|
-
"cssVariables": { "--color-primary": "#3b82f6", ... }
|
|
215
|
-
},
|
|
216
|
-
"typography": {
|
|
217
|
-
"styles": [{ "fontFamily": "Inter", "fontSize": "16px", "fontWeight": "400", ... }],
|
|
218
|
-
"sources": { "googleFonts": [...], "adobeFonts": false, "customFonts": [...] }
|
|
219
|
-
},
|
|
220
|
-
"spacing": { "scaleType": "8px", "commonValues": [{ "px": "16px", "rem": "1rem", "count": 42 }, ...] },
|
|
221
|
-
"borderRadius": { "values": [{ "value": "8px", "count": 15, "confidence": "high" }, ...] },
|
|
222
|
-
"shadows": [{ "shadow": "0 2px 4px rgba(0,0,0,0.1)", "count": 8, "confidence": "high" }, ...],
|
|
223
|
-
"components": {
|
|
224
|
-
"buttons": [{ "backgroundColor": "...", "color": "...", "padding": "...", ... }],
|
|
225
|
-
"inputs": [{ "type": "input", "border": "...", "borderRadius": "...", ... }]
|
|
226
|
-
},
|
|
227
|
-
"breakpoints": [{ "px": "768px" }, ...],
|
|
228
|
-
"iconSystem": [{ "name": "Font Awesome", "type": "icon-font" }, ...],
|
|
229
|
-
"frameworks": [{ "name": "Tailwind CSS", "confidence": "high", "evidence": "class patterns" }]
|
|
230
|
-
}
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
## Examples
|
|
234
|
-
|
|
235
|
-
### Extract Design Tokens
|
|
236
|
-
|
|
237
34
|
```bash
|
|
238
|
-
#
|
|
239
|
-
dembrandt
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
dembrandt stripe.com --json-only | jq '.colors.semantic'
|
|
246
|
-
|
|
247
|
-
# Debug mode for difficult sites
|
|
248
|
-
dembrandt example.com --debug
|
|
35
|
+
dembrandt <url> # Basic extraction
|
|
36
|
+
dembrandt bmw.de --save-output # Save JSON to output folder
|
|
37
|
+
dembrandt bmw.de --json-only # JSON output only (no save)
|
|
38
|
+
dembrandt bmw.de --debug # Visible browser
|
|
39
|
+
dembrandt bmw.de --dark-mode # Dark mode
|
|
40
|
+
dembrandt bmw.de --mobile # Mobile viewport
|
|
41
|
+
dembrandt bmw.de --slow # 3x timeouts
|
|
249
42
|
```
|
|
250
43
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
```bash
|
|
254
|
-
# Extract tokens from multiple competitors (auto-saved to output/)
|
|
255
|
-
for site in stripe.com square.com paypal.com; do
|
|
256
|
-
dembrandt $site
|
|
257
|
-
done
|
|
258
|
-
|
|
259
|
-
# Compare color palettes from most recent extractions
|
|
260
|
-
jq '.colors.palette[] | select(.confidence=="high")' output/stripe.com/2025-11-22T*.json output/square.com/2025-11-22T*.json
|
|
261
|
-
|
|
262
|
-
# Compare semantic colors across competitors
|
|
263
|
-
jq '.colors.semantic' output/*/2025-11-22T*.json
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
### Integration with Design Tools
|
|
267
|
-
|
|
268
|
-
```bash
|
|
269
|
-
# Extract and convert to custom config format
|
|
270
|
-
dembrandt mysite.com --json-only | jq '{
|
|
271
|
-
colors: .colors.semantic,
|
|
272
|
-
fontFamily: .typography.sources,
|
|
273
|
-
spacing: .spacing.commonValues
|
|
274
|
-
}' > design-tokens.json
|
|
275
|
-
```
|
|
44
|
+
By default, results display in terminal only. Use `--save-output` to save JSON to `output/bmw.de/YYYY-MM-DDTHH-MM-SS.json`
|
|
276
45
|
|
|
277
46
|
## Use Cases
|
|
278
47
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
### Competitive Analysis
|
|
48
|
+
- Brand audits & competitive analysis
|
|
49
|
+
- Design system documentation
|
|
50
|
+
- Reverse engineering brands
|
|
51
|
+
- Multi-site brand consolidation
|
|
284
52
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
### Design System Migration
|
|
288
|
-
|
|
289
|
-
Document legacy design tokens before migrating to a new system.
|
|
290
|
-
|
|
291
|
-
### Reverse Engineering
|
|
292
|
-
|
|
293
|
-
Rebuild a brand when original design guidelines are unavailable.
|
|
294
|
-
|
|
295
|
-
### Quality Assurance
|
|
296
|
-
|
|
297
|
-
Verify design consistency across different pages and environments.
|
|
298
|
-
|
|
299
|
-
## Advanced Features
|
|
300
|
-
|
|
301
|
-
### Bot Detection Avoidance
|
|
302
|
-
|
|
303
|
-
- Stealth mode with anti-detection scripts
|
|
304
|
-
- Automatic fallback to visible browser on detection
|
|
305
|
-
- Human-like interaction simulation (mouse movement, scrolling)
|
|
306
|
-
- Custom user agent and browser fingerprinting
|
|
307
|
-
|
|
308
|
-
### Smart Retry Logic
|
|
309
|
-
|
|
310
|
-
- Automatic retry on navigation failures (up to 2 attempts)
|
|
311
|
-
- SPA hydration detection and waiting
|
|
312
|
-
- Content validation to ensure page is fully loaded
|
|
313
|
-
- Detailed progress logging at each step
|
|
314
|
-
|
|
315
|
-
### Comprehensive Logging
|
|
316
|
-
|
|
317
|
-
- Real-time spinner with step-by-step progress
|
|
318
|
-
- Detailed extraction metrics (colors found, styles detected, etc.)
|
|
319
|
-
- Error context with URL, stage, and attempt information
|
|
320
|
-
- Debug mode with full stack traces
|
|
321
|
-
|
|
322
|
-
## Troubleshooting
|
|
323
|
-
|
|
324
|
-
### Bot Detection Issues
|
|
325
|
-
|
|
326
|
-
If you encounter timeouts or network errors:
|
|
327
|
-
|
|
328
|
-
```bash
|
|
329
|
-
dembrandt example.com --debug
|
|
330
|
-
```
|
|
331
|
-
|
|
332
|
-
This will automatically retry with a visible browser.
|
|
333
|
-
|
|
334
|
-
### Page Not Loading
|
|
335
|
-
|
|
336
|
-
Some sites require longer load times. The tool waits 8 seconds for SPA hydration, but you can modify this in the source.
|
|
53
|
+
## How It Works
|
|
337
54
|
|
|
338
|
-
|
|
55
|
+
Uses Playwright to render the page, extracts computed styles from the DOM, analyzes color usage and confidence, groups similar typography, detects spacing patterns, and returns actionable design tokens.
|
|
339
56
|
|
|
340
|
-
|
|
57
|
+
### Extraction Process
|
|
341
58
|
|
|
342
|
-
|
|
59
|
+
1. Browser Launch - Launches Chromium with stealth configuration
|
|
60
|
+
2. Anti-Detection - Injects scripts to bypass bot detection
|
|
61
|
+
3. Navigation - Navigates to target URL with retry logic
|
|
62
|
+
4. Hydration - Waits for SPAs to fully load (8s initial + 4s stabilization)
|
|
63
|
+
5. Content Validation - Verifies page content is substantial (>500 chars)
|
|
64
|
+
6. Parallel Extraction - Runs all extractors concurrently for speed
|
|
65
|
+
7. Analysis - Analyzes computed styles, DOM structure, and CSS variables
|
|
66
|
+
8. Scoring - Assigns confidence scores based on context and usage
|
|
343
67
|
|
|
344
|
-
|
|
68
|
+
### Color Confidence
|
|
345
69
|
|
|
346
|
-
-
|
|
347
|
-
-
|
|
348
|
-
-
|
|
349
|
-
-
|
|
70
|
+
- High — Logo, brand elements, primary buttons
|
|
71
|
+
- Medium — Interactive elements, icons, navigation
|
|
72
|
+
- Low — Generic UI components (filtered from display)
|
|
73
|
+
- Only shows high and medium confidence colors in terminal. Full palette in JSON.
|
|
350
74
|
|
|
351
75
|
## Limitations
|
|
352
76
|
|
|
353
|
-
- Dark mode requires
|
|
77
|
+
- Dark mode requires --dark-mode flag (not automatically detected)
|
|
354
78
|
- Hover/focus states extracted from CSS (not fully interactive)
|
|
355
79
|
- Canvas/WebGL-rendered sites cannot be analyzed (e.g., Tesla, Apple Vision Pro demos)
|
|
356
80
|
- JavaScript-heavy sites require hydration time (8s initial + 4s stabilization)
|
|
357
81
|
- Some dynamically-loaded content may be missed
|
|
358
|
-
- Default viewport is 1920x1080 (use
|
|
359
|
-
|
|
360
|
-
## Architecture
|
|
361
|
-
|
|
362
|
-
```
|
|
363
|
-
dembrandt/
|
|
364
|
-
├── index.js # CLI entry point, command handling
|
|
365
|
-
├── lib/
|
|
366
|
-
│ ├── extractors.js # Core extraction logic with stealth mode
|
|
367
|
-
│ └── display.js # Terminal output formatting
|
|
368
|
-
├── output/ # Auto-saved JSON extractions (gitignored)
|
|
369
|
-
│ ├── stripe.com/
|
|
370
|
-
│ │ ├── 2025-11-22T14-30-45.json
|
|
371
|
-
│ │ └── 2025-11-22T15-12-33.json
|
|
372
|
-
│ └── github.com/
|
|
373
|
-
│ └── 2025-11-22T14-35-12.json
|
|
374
|
-
├── package.json
|
|
375
|
-
└── README.md
|
|
376
|
-
```
|
|
82
|
+
- Default viewport is 1920x1080 (use --mobile for responsive analysis)
|
|
377
83
|
|
|
378
84
|
## Ethics & Legality
|
|
379
85
|
|
|
380
86
|
Dembrandt extracts publicly available design information (colors, fonts, spacing) from website DOMs for analysis purposes. This falls under fair use in most jurisdictions (USA's DMCA § 1201(f), EU Software Directive 2009/24/EC) when used for competitive analysis, documentation, or learning.
|
|
381
87
|
|
|
382
|
-
|
|
88
|
+
Legal: Analyzing public HTML/CSS is generally legal. Does not bypass protections or violate copyright. Check site ToS before mass extraction.
|
|
383
89
|
|
|
384
|
-
|
|
90
|
+
Ethical: Use for inspiration and analysis, not direct copying. Respect servers (no mass crawling), give credit to sources, be transparent about data origin.
|
|
385
91
|
|
|
386
92
|
## Contributing
|
|
387
93
|
|
|
388
|
-
|
|
94
|
+
Bugs you found? Weird websites that make it cry? Pull requests (even one-liners make me happy)?
|
|
389
95
|
|
|
390
|
-
|
|
391
|
-
- Example URLs that demonstrate the problem
|
|
392
|
-
- Expected vs actual behavior
|
|
96
|
+
Spam me in [Issues](https://github.com/thevangelist/dembrandt/issues) or PRs. I reply to everything.
|
|
393
97
|
|
|
394
|
-
|
|
98
|
+
Let's keep the light alive together.
|
|
395
99
|
|
|
396
|
-
|
|
100
|
+
@thevangelist
|
|
397
101
|
|
|
398
|
-
|
|
102
|
+
---
|
|
399
103
|
|
|
400
|
-
|
|
401
|
-
- [x] Mobile viewport support (via `--mobile` flag)
|
|
402
|
-
- [x] Clickable terminal links for modern terminals
|
|
403
|
-
- [ ] Animation/transition detection
|
|
404
|
-
- [ ] Interactive state capture (hover, focus, active)
|
|
405
|
-
- [ ] Multi-page analysis
|
|
406
|
-
- [ ] Configuration file support
|
|
104
|
+
MIT — do whatever you want with it.
|
package/index.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { program } from "commander";
|
|
11
11
|
import chalk from "chalk";
|
|
12
12
|
import ora from "ora";
|
|
13
|
-
import { chromium } from "playwright";
|
|
13
|
+
import { chromium } from "playwright-core";
|
|
14
14
|
import { extractBranding } from "./lib/extractors.js";
|
|
15
15
|
import { displayResults } from "./lib/display.js";
|
|
16
16
|
import { writeFileSync, mkdirSync } from "fs";
|
|
@@ -23,9 +23,11 @@ program
|
|
|
23
23
|
.argument("<url>")
|
|
24
24
|
.option("--json-only", "Output raw JSON")
|
|
25
25
|
.option("-d, --debug", "Force visible browser")
|
|
26
|
+
.option("--save-output", "Save JSON file to output folder")
|
|
26
27
|
.option("--verbose-colors", "Show medium and low confidence colors")
|
|
27
28
|
.option("--dark-mode", "Extract colors from dark mode")
|
|
28
29
|
.option("--mobile", "Extract from mobile viewport")
|
|
30
|
+
.option("--slow", "3x longer timeouts for slow-loading sites")
|
|
29
31
|
.action(async (input, opts) => {
|
|
30
32
|
let url = input;
|
|
31
33
|
if (!url.match(/^https?:\/\//)) url = "https://" + url;
|
|
@@ -64,6 +66,7 @@ program
|
|
|
64
66
|
navigationTimeout: 90000,
|
|
65
67
|
darkMode: opts.darkMode,
|
|
66
68
|
mobile: opts.mobile,
|
|
69
|
+
slow: opts.slow,
|
|
67
70
|
});
|
|
68
71
|
break;
|
|
69
72
|
} catch (err) {
|
|
@@ -89,10 +92,10 @@ program
|
|
|
89
92
|
}
|
|
90
93
|
}
|
|
91
94
|
|
|
92
|
-
|
|
95
|
+
console.log();
|
|
93
96
|
|
|
94
|
-
// Save JSON output
|
|
95
|
-
if (!opts.jsonOnly) {
|
|
97
|
+
// Save JSON output only if --save-output is specified
|
|
98
|
+
if (opts.saveOutput && !opts.jsonOnly) {
|
|
96
99
|
try {
|
|
97
100
|
const domain = new URL(url).hostname.replace("www.", "");
|
|
98
101
|
const timestamp = new Date()
|
|
@@ -109,14 +112,14 @@ program
|
|
|
109
112
|
|
|
110
113
|
console.log(
|
|
111
114
|
chalk.dim(
|
|
112
|
-
|
|
115
|
+
`💾 JSON saved to: ${chalk.hex('#8BE9FD')(
|
|
113
116
|
`output/${domain}/${filename}`
|
|
114
117
|
)}`
|
|
115
118
|
)
|
|
116
119
|
);
|
|
117
120
|
} catch (err) {
|
|
118
121
|
console.log(
|
|
119
|
-
chalk.
|
|
122
|
+
chalk.hex('#FFB86C')(`⚠ Could not save JSON file: ${err.message}`)
|
|
120
123
|
);
|
|
121
124
|
}
|
|
122
125
|
}
|
|
@@ -125,6 +128,7 @@ program
|
|
|
125
128
|
if (opts.jsonOnly) {
|
|
126
129
|
console.log(JSON.stringify(result, null, 2));
|
|
127
130
|
} else {
|
|
131
|
+
console.log();
|
|
128
132
|
displayResults(result, { verboseColors: opts.verboseColors });
|
|
129
133
|
}
|
|
130
134
|
} catch (err) {
|
|
@@ -140,7 +144,7 @@ program
|
|
|
140
144
|
|
|
141
145
|
if (!opts.debug) {
|
|
142
146
|
console.log(
|
|
143
|
-
chalk.
|
|
147
|
+
chalk.hex('#FFB86C')(
|
|
144
148
|
"\nTip: Try with --debug flag for tough sites and detailed error logs"
|
|
145
149
|
)
|
|
146
150
|
);
|