@@ -8,9 +8,11 @@ import { fileURLToPath } from 'url';
88const __filename = fileURLToPath ( import . meta. url ) ;
99const __dirname = path . dirname ( __filename ) ;
1010
11-
1211function toKebabCase ( str ) {
13- return str . replace ( / ( [ a - z 0 - 9 ] ) ( [ A - Z ] ) / g, '$1-$2' ) . toLowerCase ( ) . replace ( / \s + / g, '-' ) ;
12+ return str
13+ . replace ( / ( [ a - z 0 - 9 ] ) ( [ A - Z ] ) / g, '$1-$2' )
14+ . toLowerCase ( )
15+ . replace ( / \s + / g, '-' ) ;
1416}
1517
1618export default class extends Generator {
@@ -68,7 +70,7 @@ export default class extends Generator {
6870 default : false ,
6971 } ) ;
7072
71- this . installNextJS = async function ( ) {
73+ this . installNextJS = async function ( ) {
7274 // Clone Next.js template with Tailwind if specified, using the project name
7375 const createNextAppCommand = [ '-y' , '[email protected] ' ] ; 7476 createNextAppCommand . push ( toKebabCase ( this . options . project ) ) ; // Use the project name for the directory
@@ -80,52 +82,71 @@ export default class extends Generator {
8082 createNextAppCommand . push ( '@/*' ) ;
8183 createNextAppCommand . push ( '--use-npm' ) ;
8284 createNextAppCommand . push ( '--eslint' ) ;
83-
85+
8486 if ( this . options . typescript ) {
8587 createNextAppCommand . push ( '--typescript' ) ; // This will avoid the TypeScript prompt
8688 } else {
8789 createNextAppCommand . push ( '--js' ) ;
8890 }
89-
91+
9092 if ( this . options . tailwind ) {
9193 createNextAppCommand . push ( '--tailwind' ) ;
9294 }
93-
94- this . log ( " Installing Next.js..." ) ;
95- const patchPackages = '' ; //'next@14 react@18 react-dom@18';
95+
96+ this . log ( ' Installing Next.js...' ) ;
97+ const patchPackages = '' ; //'next@14 react@18 react-dom@18';
9698 const additionalPackages = `react-tooltip ${ patchPackages } ` ;
97- await new Promise ( ( resolve , error ) => { exec ( `npx ${ createNextAppCommand . join ( ' ' ) } && cd ${ toKebabCase ( this . options . project ) } && npm install ${ additionalPackages } ` ) . on ( 'exit' , ( code ) => {
98- this . destinationRoot ( this . destinationPath ( toKebabCase ( this . options . project ) ) ) ;
99- resolve ( ) ;
100- } ) ; } ) ;
101- }
99+ await new Promise ( ( resolve , error ) => {
100+ exec (
101+ `npx ${ createNextAppCommand . join ( ' ' ) } && cd ${ toKebabCase (
102+ this . options . project
103+ ) } && npm install ${ additionalPackages } `
104+ ) . on ( 'exit' , ( code ) => {
105+ this . destinationRoot (
106+ this . destinationPath ( toKebabCase ( this . options . project ) )
107+ ) ;
108+ resolve ( ) ;
109+ } ) ;
110+ } ) ;
111+ } ;
102112
103- this . installStorybook = function ( ) {
113+ this . installStorybook = function ( ) {
104114 // Conditionally initialize Storybook
105115 if ( this . options . storybook ) {
106116 this . log ( 'Installing Storybook...' ) ;
107- this . spawnCommandSync ( 'npx' , [ '-y' , 'storybook@^8.4' , 'init' , '--no-dev' ] ) ;
117+ this . spawnCommandSync ( 'npx' , [
118+ '-y' ,
119+ 'storybook@^8.4' ,
120+ 'init' ,
121+ '--no-dev' ,
122+ ] ) ;
108123 this . log ( 'Storybook installed!' ) ;
109124 // if (this.options.tailwind && this.options.storybook) {
110125 // Tailwind CSS specific setup for older versions of Storybook
111126 // this.spawnCommandSync('npx', ['storybook@latest', 'add', '@storybook/addon-styling-webpack']);
112127 // }
113128 }
114- }
115-
116- this . installCypress = function ( ) {
129+ } ;
130+
131+ this . installCypress = function ( ) {
117132 // Conditionally add Cypress
118133 if ( this . options . cypress ) {
119134 this . log ( 'Installing Cypress...' ) ;
120135 this . spawnCommandSync ( 'npm' , [ 'install' , '--save-dev' , 'cypress' ] ) ;
121136 this . log ( 'Cypress installed!' ) ;
122137 if ( this . options . bitloops ) {
123- this . spawnCommandSync ( 'npm' , [ 'install' , '--save-dev' , 'mochawesome' , 'mochawesome-merge' , 'mochawesome-report-generator' ] ) ;
138+ this . spawnCommandSync ( 'npm' , [
139+ 'install' ,
140+ '--save-dev' ,
141+ 'mochawesome' ,
142+ 'mochawesome-merge' ,
143+ 'mochawesome-report-generator' ,
144+ ] ) ;
124145 }
125146 }
126- }
127-
128- this . patchFiles = async function ( ) {
147+ } ;
148+
149+ this . patchFiles = async function ( ) {
129150 // Conditionally initialize Storybook
130151 if ( this . options . storybook ) {
131152 this . log ( 'Making Storybook changes...' ) ;
@@ -134,102 +155,134 @@ export default class extends Generator {
134155 this . log ( 'Setting up Tailwind CSS with Storybook...' ) ;
135156 this . fs . copyTpl (
136157 this . templatePath ( 'storybook.preview.ts' ) ,
137- this . destinationPath ( '.storybook/preview.ts' ) ,
138- ) ;
158+ this . destinationPath ( '.storybook/preview.ts' )
159+ ) ;
139160 }
140161 this . log ( 'Removing default Storybook stories...' ) ;
141162 try {
142- fs . rmSync ( this . destinationPath ( 'src/stories' ) , { recursive : true , force : true } ) ;
163+ fs . rmSync ( this . destinationPath ( 'src/stories' ) , {
164+ recursive : true ,
165+ force : true ,
166+ } ) ;
143167 console . log ( 'Sample stories directory deleted successfully!' ) ;
144168 } catch ( err ) {
145- console . error ( 'Error deleting sample stories directory:' , err ) ;
169+ console . error ( 'Error deleting sample stories directory:' , err ) ;
146170 }
147171 fs . unlinkSync ( this . destinationPath ( 'tailwind.config.ts' ) ) ;
148172 this . fs . copyTpl (
149173 this . templatePath ( 'tailwind.config.ts' ) ,
150- this . destinationPath ( 'tailwind.config.ts' ) ,
174+ this . destinationPath ( 'tailwind.config.ts' )
151175 ) ;
152176 }
153-
177+
154178 if ( this . options . cypress ) {
155179 this . log ( 'Adding Cypress config...' ) ;
156180 this . fs . copyTpl (
157181 this . templatePath ( 'cypress.config.ts' ) ,
158- this . destinationPath ( 'cypress.config.ts' ) ,
159- ) ;
182+ this . destinationPath ( 'cypress.config.ts' )
183+ ) ;
160184 }
161-
185+
162186 fs . unlinkSync ( this . destinationPath ( 'src/app/page.tsx' ) ) ;
163187 this . fs . copyTpl (
164188 this . templatePath ( 'next.app.page.tsx' ) ,
165- this . destinationPath ( 'src/app/page.tsx' ) ,
166- ) ;
167-
189+ this . destinationPath ( 'src/app/page.tsx' )
190+ ) ;
191+
168192 fs . unlinkSync ( this . destinationPath ( 'src/app/layout.tsx' ) ) ;
169193 this . fs . copyTpl (
170194 this . templatePath ( 'next.app.layout.tsx' ) ,
171195 this . destinationPath ( 'src/app/layout.tsx' ) ,
172- { projectName : this . options . project } ,
196+ { projectName : this . options . project }
173197 ) ;
174-
198+
175199 this . log ( 'Adding Meyer reset in global.css...' ) ;
176200 fs . unlinkSync ( this . destinationPath ( 'src/app/globals.css' ) ) ;
177201 this . fs . copyTpl (
178202 this . templatePath ( 'globals.css' ) ,
179- this . destinationPath ( 'src/app/globals.css' ) ,
180- ) ;
203+ this . destinationPath ( 'src/app/globals.css' )
204+ ) ;
181205
182206 if ( this . options . bitloops ) {
183207 this . log ( 'Adding Bitloops support components...' ) ;
184- const path = 'src/components/bitloops/Unsupported.tsx' ;
208+ const unsupportedPath =
209+ 'src/components/bitloops/unsupported/Unsupported.tsx' ;
210+ this . fs . copyTpl (
211+ this . templatePath ( unsupportedPath ) ,
212+ this . destinationPath ( unsupportedPath )
213+ ) ;
214+ const buttonPath = 'src/components/bitloops/button/Button.tsx' ;
185215 this . fs . copyTpl (
186- this . templatePath ( path ) ,
187- this . destinationPath ( path ) ,
188- ) ;
216+ this . templatePath ( buttonPath ) ,
217+ this . destinationPath ( buttonPath )
218+ ) ;
189219 if ( this . options . storybook ) {
190- const path = 'src/components/bitloops/Unsupported.stories.tsx' ;
220+ const unsupportedPath =
221+ 'src/components/bitloops/unsupported/Unsupported.stories.tsx' ;
191222 this . fs . copyTpl (
192- this . templatePath ( path ) ,
193- this . destinationPath ( path ) ,
194- ) ;
223+ this . templatePath ( unsupportedPath ) ,
224+ this . destinationPath ( unsupportedPath )
225+ ) ;
226+ const buttonPath =
227+ 'src/components/bitloops/button/Button.stories.tsx' ;
228+ this . fs . copyTpl (
229+ this . templatePath ( buttonPath ) ,
230+ this . destinationPath ( buttonPath )
231+ ) ;
195232 }
196233 if ( this . options . cypress ) {
197234 const path = 'cypress/helpers/index.ts' ;
198- this . fs . copyTpl (
199- this . templatePath ( path ) ,
200- this . destinationPath ( path ) ,
201- ) ;
235+ this . fs . copyTpl ( this . templatePath ( path ) , this . destinationPath ( path ) ) ;
202236 }
237+ this . spawnCommandSync ( 'npm' , [
238+ 'install' ,
239+ '--save-dev' ,
240+ 'react-aria-components' ,
241+ ] ) ;
203242 }
204- }
243+ } ;
205244
206- this . commitChanges = async function ( ) {
245+ this . commitChanges = async function ( ) {
207246 this . log ( 'Committing changes to git...' ) ;
208- await new Promise ( ( resolve ) => { exec ( `cd ${ toKebabCase ( this . options . project ) } && git add . && git commit -m "Initial setup"` ) . on ( 'exit' , ( code ) => {
209- if ( code !== 0 ) {
210- this . log ( 'Error committing changes to git! ' , code ) ;
247+ await new Promise ( ( resolve ) => {
248+ exec (
249+ `cd ${ toKebabCase (
250+ this . options . project
251+ ) } && git add . && git commit -m "Initial setup"`
252+ ) . on ( 'exit' , ( code ) => {
253+ if ( code !== 0 ) {
254+ this . log ( 'Error committing changes to git! ' , code ) ;
255+ resolve ( ) ;
256+ }
257+ this . log ( 'Git changes committed!' ) ;
211258 resolve ( ) ;
212- }
213- this . log ( 'Git changes committed!' ) ;
214- resolve ( ) ;
215- } ) ; } ) ;
216- }
259+ } ) ;
260+ } ) ;
261+ } ;
217262 }
218263
219264 initializing ( ) {
220265 // Check if the project name and --nextjs flag are provided
221266 if ( ! this . options . project ) {
222- this . log ( "Error: --project option is required to specify the project name." ) ;
267+ this . log (
268+ 'Error: --project option is required to specify the project name.'
269+ ) ;
223270 process . exit ( 1 ) ;
224271 }
225272
226273 if ( ! this . options . nextjs ) {
227- this . log ( "Error: --nextjs option is currently required to scaffold a project." ) ;
274+ this . log (
275+ 'Error: --nextjs option is currently required to scaffold a project.'
276+ ) ;
228277 process . exit ( 1 ) ;
229278 }
230279
231- this . log ( `Initializing project ${ toKebabCase ( this . options . project ) } with the selected options...` ) ;
232- }
280+ this . log (
281+ `Initializing project ${ toKebabCase (
282+ this . options . project
283+ ) } with the selected options...`
284+ ) ;
285+ }
233286
234287 async main ( ) {
235288 await this . installNextJS ( ) ;
@@ -242,12 +295,21 @@ export default class extends Generator {
242295 }
243296
244297 end ( ) {
245- this . log ( `Your Bitloops project '${ toKebabCase ( this . options . project ) } ' setup is complete! 🎉🎉🎉` ) ;
298+ this . log (
299+ `Your Bitloops project '${ toKebabCase (
300+ this . options . project
301+ ) } ' setup is complete! 🎉🎉🎉`
302+ ) ;
246303 this . log ( '' ) ;
247304 this . log ( 'Use the following commands to start:' ) ;
248- this . log ( "- `npm run dev` to start the Next.js app." ) ;
249- if ( this . options . storybook ) this . log ( "- `npm run storybook` to start Storybook." ) ;
250- if ( this . options . cypress ) this . log ( "- `npx cypress open --e2e --browser chrome` to open Cypress." ) ;
251- if ( this . options . cypress ) this . log ( "- `npx cypress run --e2e --browser chrome` to run Cypress on the terminal." ) ;
305+ this . log ( '- `npm run dev` to start the Next.js app.' ) ;
306+ if ( this . options . storybook )
307+ this . log ( '- `npm run storybook` to start Storybook.' ) ;
308+ if ( this . options . cypress )
309+ this . log ( '- `npx cypress open --e2e --browser chrome` to open Cypress.' ) ;
310+ if ( this . options . cypress )
311+ this . log (
312+ '- `npx cypress run --e2e --browser chrome` to run Cypress on the terminal.'
313+ ) ;
252314 }
253- } ;
315+ }
0 commit comments