1
1
#!/usr/bin/env node
2
2
3
- import path from " node:path" ;
4
- import { fileURLToPath } from " node:url" ;
5
- import { Command } from " commander" ;
6
- import fse from " fs-extra" ;
7
- import logSymbols from " log-symbols" ;
8
- import ora from " ora" ;
9
- import { tree } from " ./tree.js" ;
3
+ import path from ' node:path' ;
4
+ import { fileURLToPath } from ' node:url' ;
5
+ import { Command } from ' commander' ;
6
+ import fse from ' fs-extra' ;
7
+ import logSymbols from ' log-symbols' ;
8
+ import ora from ' ora' ;
9
+ import { tree } from ' ./tree.js' ;
10
10
11
11
const filename = fileURLToPath ( import . meta. url ) ;
12
12
const dirname = path . dirname ( filename ) ;
13
13
14
14
const packageJson = JSON . parse (
15
- fse . readFileSync ( path . resolve ( dirname , " ../package.json" ) , " utf8" ) ,
15
+ fse . readFileSync ( path . resolve ( dirname , ' ../package.json' ) , ' utf8' ) ,
16
16
) ;
17
17
18
18
const getLatestVersionOfTag = async ( packageName , tag ) => {
19
- const cacheFilename = `${ packageName . replaceAll ( "/" , "-" ) } -${ tag } .json` ;
20
-
21
- const cacheDir = path . join ( path . dirname ( fileURLToPath ( import . meta. url ) ) , '..' , '.cache' ) ;
22
-
19
+ const cacheFilename = `${ packageName . replaceAll ( '/' , '-' ) } -${ tag } .json` ;
20
+
21
+ const cacheDir = path . join (
22
+ path . dirname ( fileURLToPath ( import . meta. url ) ) ,
23
+ '..' ,
24
+ '.cache' ,
25
+ ) ;
26
+
23
27
if ( ! fse . existsSync ( cacheDir ) ) {
24
28
fse . mkdirSync ( cacheDir , { recursive : true , mode : 0o700 } ) ;
25
29
}
26
-
30
+
27
31
const cachePath = path . join ( cacheDir , cacheFilename ) ;
28
-
32
+
29
33
let data ;
30
34
try {
31
35
const response = await fetch (
32
36
`https://registry.npmjs.org/${ packageName } /${ tag } ` ,
33
37
) ;
34
38
data = await response . json ( ) ;
35
-
39
+
36
40
fse . writeFileSync ( cachePath , JSON . stringify ( data ) , { mode : 0o600 } ) ;
37
41
} catch ( exception ) {
38
42
if ( fse . existsSync ( cachePath ) ) {
@@ -45,32 +49,32 @@ const getLatestVersionOfTag = async (packageName, tag) => {
45
49
}
46
50
}
47
51
48
- if ( typeof data === " string" && data . startsWith ( " version not found" ) ) {
52
+ if ( typeof data === ' string' && data . startsWith ( ' version not found' ) ) {
49
53
console . error ( `Tag ${ tag } does not exist for ${ packageName } .` ) ;
50
54
process . exit ( 1 ) ;
51
55
}
52
56
53
57
const { version } = data ;
54
58
55
59
if ( ! / ^ \d + \. \d + \. \d + .* $ / . test ( version ) ) {
56
- console . error ( " Invalid version received, something has gone very wrong." ) ;
60
+ console . error ( ' Invalid version received, something has gone very wrong.' ) ;
57
61
}
58
-
62
+
59
63
return version ;
60
64
} ;
61
65
62
66
const init = async ( name , { tag } ) => {
63
67
let projectPath = name ;
64
68
65
69
if ( ! projectPath ) {
66
- projectPath = path . join ( process . cwd ( ) , " react-email-starter" ) ;
70
+ projectPath = path . join ( process . cwd ( ) , ' react-email-starter' ) ;
67
71
}
68
72
69
- if ( typeof projectPath === " string" ) {
73
+ if ( typeof projectPath === ' string' ) {
70
74
projectPath = projectPath . trim ( ) ;
71
75
}
72
76
73
- const templatePath = path . resolve ( dirname , " ../template" ) ;
77
+ const templatePath = path . resolve ( dirname , ' ../template' ) ;
74
78
const resolvedProjectPath = path . resolve ( projectPath ) ;
75
79
76
80
if ( fse . existsSync ( resolvedProjectPath ) ) {
@@ -79,51 +83,51 @@ const init = async (name, { tag }) => {
79
83
}
80
84
81
85
const spinner = ora ( {
82
- text : " Preparing files...\n" ,
86
+ text : ' Preparing files...\n' ,
83
87
} ) . start ( ) ;
84
88
85
89
fse . copySync ( templatePath , resolvedProjectPath , {
86
90
recursive : true ,
87
91
} ) ;
88
92
const templatePackageJsonPath = path . resolve (
89
93
resolvedProjectPath ,
90
- " ./package.json" ,
94
+ ' ./package.json' ,
91
95
) ;
92
- const templatePackageJson = fse . readFileSync ( templatePackageJsonPath , " utf8" ) ;
96
+ const templatePackageJson = fse . readFileSync ( templatePackageJsonPath , ' utf8' ) ;
93
97
fse . writeFileSync (
94
98
templatePackageJsonPath ,
95
99
templatePackageJson
96
100
. replace (
97
- " INSERT_COMPONENTS_VERSION" ,
98
- await getLatestVersionOfTag ( " @react-email/components" , tag ) ,
101
+ ' INSERT_COMPONENTS_VERSION' ,
102
+ await getLatestVersionOfTag ( ' @react-email/components' , tag ) ,
99
103
)
100
104
. replace (
101
- " INSERT_REACT_EMAIL_VERSION" ,
102
- await getLatestVersionOfTag ( " react-email" , tag ) ,
105
+ ' INSERT_REACT_EMAIL_VERSION' ,
106
+ await getLatestVersionOfTag ( ' react-email' , tag ) ,
103
107
) ,
104
- " utf8" ,
108
+ ' utf8' ,
105
109
) ;
106
110
107
111
spinner . stopAndPersist ( {
108
112
symbol : logSymbols . success ,
109
- text : " React Email Starter files ready" ,
113
+ text : ' React Email Starter files ready' ,
110
114
} ) ;
111
115
112
116
// eslint-disable-next-line no-console
113
117
console . info (
114
118
await tree ( resolvedProjectPath , 4 , ( dirent ) => {
115
119
return ! path
116
120
. join ( dirent . parentPath , dirent . name )
117
- . includes ( " node_modules" ) ;
121
+ . includes ( ' node_modules' ) ;
118
122
} ) ,
119
123
) ;
120
124
} ;
121
125
122
126
new Command ( )
123
127
. name ( packageJson . name )
124
128
. version ( packageJson . version )
125
- . description ( " The easiest way to get started with React Email" )
126
- . arguments ( " [dir]" , " Path to initialize the project" )
127
- . option ( " -t, --tag <tag>" , " Tag of React Email versions to use" , " latest" )
129
+ . description ( ' The easiest way to get started with React Email' )
130
+ . arguments ( ' [dir]' , ' Path to initialize the project' )
131
+ . option ( ' -t, --tag <tag>' , ' Tag of React Email versions to use' , ' latest' )
128
132
. action ( init )
129
133
. parse ( process . argv ) ;
0 commit comments