1
1
#!/usr/bin/env node
2
2
3
3
import { Command , InvalidArgumentError } from "commander" ;
4
- import * as fs from "node:fs/promises" ;
5
- import * as path from "node:path" ;
4
+ import { mkdir , copyFile , readFile , writeFile } from "node:fs/promises" ;
5
+ import { resolve } from "node:path" ;
6
6
import { fileURLToPath } from "node:url" ;
7
7
import { intro , outro , spinner } from "@clack/prompts" ;
8
8
import { execa } from "execa" ;
@@ -25,32 +25,32 @@ async function createApp(projectName: string, options: Required<Options>) {
25
25
const templateDir = fileURLToPath (
26
26
new URL ( "../project-template" , import . meta. url )
27
27
) ;
28
- const targetDir = path . join ( process . cwd ( ) , projectName ) ;
28
+ const targetDir = resolve ( process . cwd ( ) , projectName ) ;
29
29
30
30
async function copyFiles ( files : string [ ] ) {
31
31
for ( const file of files ) {
32
32
const targetFileName = file . replace ( ".tw" , "" ) ;
33
- await fs . copyFile (
34
- path . join ( templateDir , file ) ,
35
- path . join ( targetDir , targetFileName )
33
+ await copyFile (
34
+ resolve ( templateDir , file ) ,
35
+ resolve ( targetDir , targetFileName )
36
36
) ;
37
37
}
38
38
}
39
39
40
40
intro ( `Creating a new TanStack app in ${ targetDir } ...` ) ;
41
41
42
42
// Make the root directory
43
- await fs . mkdir ( targetDir , { recursive : true } ) ;
43
+ await mkdir ( targetDir , { recursive : true } ) ;
44
44
45
45
// Setup the .vscode directory
46
- await fs . mkdir ( path . join ( targetDir , ".vscode" ) , { recursive : true } ) ;
47
- await fs . copyFile (
48
- path . join ( templateDir , ".vscode/settings.json" ) ,
49
- path . join ( targetDir , ".vscode/settings.json" )
46
+ await mkdir ( resolve ( targetDir , ".vscode" ) , { recursive : true } ) ;
47
+ await copyFile (
48
+ resolve ( templateDir , ".vscode/settings.json" ) ,
49
+ resolve ( targetDir , ".vscode/settings.json" )
50
50
) ;
51
51
52
52
// Fill the public directory
53
- await fs . mkdir ( path . join ( targetDir , "public" ) , { recursive : true } ) ;
53
+ await mkdir ( resolve ( targetDir , "public" ) , { recursive : true } ) ;
54
54
copyFiles ( [
55
55
"./public/robots.txt" ,
56
56
"./public/favicon.ico" ,
@@ -60,7 +60,7 @@ async function createApp(projectName: string, options: Required<Options>) {
60
60
] ) ;
61
61
62
62
// Make the src directory
63
- await fs . mkdir ( path . join ( targetDir , "src" ) , { recursive : true } ) ;
63
+ await mkdir ( resolve ( targetDir , "src" ) , { recursive : true } ) ;
64
64
65
65
// Copy in Vite and Tailwind config and CSS
66
66
if ( options . tailwind ) {
@@ -73,8 +73,8 @@ async function createApp(projectName: string, options: Required<Options>) {
73
73
74
74
// Setup the app component. There are four variations, typescript/javascript and tailwind/non-tailwind.
75
75
let appComponent = (
76
- await fs . readFile (
77
- path . join (
76
+ await readFile (
77
+ resolve (
78
78
templateDir ,
79
79
options . tailwind ? "./src/App.tw.tsx" : "./src/App.tsx"
80
80
) ,
@@ -84,17 +84,17 @@ async function createApp(projectName: string, options: Required<Options>) {
84
84
if ( ! options . typescript ) {
85
85
appComponent = appComponent . replace ( "App.tsx" , "App.jsx" ) ;
86
86
}
87
- await fs . writeFile (
88
- path . join ( targetDir , `./src/App${ options . typescript ? ".tsx" : ".jsx" } ` ) ,
87
+ await writeFile (
88
+ resolve ( targetDir , `./src/App${ options . typescript ? ".tsx" : ".jsx" } ` ) ,
89
89
appComponent
90
90
) ;
91
91
92
92
// Setup the main, reportWebVitals and index.html files
93
93
if ( options . typescript ) {
94
94
await copyFiles ( [ "./src/main.tsx" , "./src/reportWebVitals.ts" ] ) ;
95
- await fs . copyFile (
96
- path . join ( templateDir , `./index.ts.html` ) ,
97
- path . join ( targetDir , "./index.html" )
95
+ await copyFile (
96
+ resolve ( templateDir , `./index.ts.html` ) ,
97
+ resolve ( targetDir , "./index.html" )
98
98
) ;
99
99
} else {
100
100
await copyFiles ( [
@@ -111,12 +111,12 @@ async function createApp(projectName: string, options: Required<Options>) {
111
111
112
112
// Setup the package.json file, optionally with typescript and tailwind
113
113
let packageJSON = JSON . parse (
114
- await fs . readFile ( path . join ( templateDir , "package.json" ) , "utf8" )
114
+ await readFile ( resolve ( templateDir , "package.json" ) , "utf8" )
115
115
) ;
116
116
packageJSON . name = projectName ;
117
117
if ( options . typescript ) {
118
118
const tsPackageJSON = JSON . parse (
119
- await fs . readFile ( path . join ( templateDir , "package.ts.json" ) , "utf8" )
119
+ await readFile ( resolve ( templateDir , "package.ts.json" ) , "utf8" )
120
120
) ;
121
121
packageJSON = {
122
122
...packageJSON ,
@@ -128,7 +128,7 @@ async function createApp(projectName: string, options: Required<Options>) {
128
128
}
129
129
if ( options . tailwind ) {
130
130
const twPackageJSON = JSON . parse (
131
- await fs . readFile ( path . join ( templateDir , "package.tw.json" ) , "utf8" )
131
+ await readFile ( resolve ( templateDir , "package.tw.json" ) , "utf8" )
132
132
) ;
133
133
packageJSON = {
134
134
...packageJSON ,
@@ -138,19 +138,19 @@ async function createApp(projectName: string, options: Required<Options>) {
138
138
} ,
139
139
} ;
140
140
}
141
- await fs . writeFile (
142
- path . join ( targetDir , "package.json" ) ,
141
+ await writeFile (
142
+ resolve ( targetDir , "package.json" ) ,
143
143
JSON . stringify ( packageJSON , null , 2 )
144
144
) ;
145
145
146
146
// Add .gitignore and README.md
147
- await fs . copyFile (
148
- path . join ( templateDir , "gitignore" ) ,
149
- path . join ( targetDir , ".gitignore" )
147
+ await copyFile (
148
+ resolve ( templateDir , "gitignore" ) ,
149
+ resolve ( targetDir , ".gitignore" )
150
150
) ;
151
- await fs . copyFile (
152
- path . join ( templateDir , "README.md" ) ,
153
- path . join ( targetDir , "README.md" )
151
+ await copyFile (
152
+ resolve ( templateDir , "README.md" ) ,
153
+ resolve ( targetDir , "README.md" )
154
154
) ;
155
155
156
156
// Install dependencies
0 commit comments