1
1
import type { CrawlProgress } from './crawl.ts'
2
2
import type { CrawlOptions } from './types.ts'
3
- import { readFileSync } from 'node:fs'
3
+ import { readFileSync , writeFileSync , unlinkSync } from 'node:fs'
4
+ import { accessSync , constants , mkdirSync } from 'node:fs'
4
5
import { fileURLToPath } from 'node:url'
5
6
import * as p from '@clack/prompts'
6
7
import { dirname , join , resolve } from 'pathe'
@@ -15,6 +16,49 @@ const packageJsonPath = join(__dirname, '..', 'package.json')
15
16
const packageJson = JSON . parse ( readFileSync ( packageJsonPath , 'utf-8' ) )
16
17
const version = packageJson . version
17
18
19
+ function checkOutputDirectoryPermissions ( outputDir : string ) : { success : boolean , error ?: string } {
20
+ try {
21
+ // Try to create the directory if it doesn't exist
22
+ mkdirSync ( outputDir , { recursive : true } )
23
+
24
+ // Check if we can write to the directory
25
+ accessSync ( outputDir , constants . W_OK )
26
+
27
+ // Try to create a test file to ensure we can actually write
28
+ const testFile = join ( outputDir , '.mdream-test' )
29
+ try {
30
+ writeFileSync ( testFile , 'test' )
31
+ unlinkSync ( testFile )
32
+ }
33
+ catch ( err ) {
34
+ return {
35
+ success : false ,
36
+ error : `Cannot write to output directory: ${ err instanceof Error ? err . message : 'Unknown error' } `
37
+ }
38
+ }
39
+
40
+ return { success : true }
41
+ }
42
+ catch ( err ) {
43
+ if ( err instanceof Error ) {
44
+ if ( err . message . includes ( 'EACCES' ) ) {
45
+ return {
46
+ success : false ,
47
+ error : `Permission denied: Cannot write to output directory '${ outputDir } '. Please check permissions or run with appropriate privileges.`
48
+ }
49
+ }
50
+ return {
51
+ success : false ,
52
+ error : `Failed to access output directory: ${ err . message } `
53
+ }
54
+ }
55
+ return {
56
+ success : false ,
57
+ error : 'Failed to access output directory'
58
+ }
59
+ }
60
+ }
61
+
18
62
async function interactiveCrawl ( ) : Promise < CrawlOptions | null > {
19
63
console . clear ( )
20
64
@@ -462,6 +506,16 @@ async function main() {
462
506
process . exit ( 0 )
463
507
}
464
508
509
+ // Check output directory permissions before proceeding
510
+ const permCheck = checkOutputDirectoryPermissions ( options . outputDir )
511
+ if ( ! permCheck . success ) {
512
+ p . log . error ( permCheck . error ! )
513
+ if ( permCheck . error ?. includes ( 'Permission denied' ) ) {
514
+ p . log . info ( 'Tip: Try running with elevated privileges (e.g., sudo) or change the output directory permissions.' )
515
+ }
516
+ process . exit ( 1 )
517
+ }
518
+
465
519
// Check playwright installation if needed
466
520
if ( options . driver === 'playwright' ) {
467
521
// Check Chrome support and configure if available
0 commit comments