@@ -15,6 +15,7 @@ import { intro, log, multiselect, outro, spinner } from '@clack/prompts'
1515import { execa } from 'execa'
1616import { render } from 'ejs'
1717import { format } from 'prettier'
18+ import chalk from 'chalk'
1819
1920import {
2021 SUPPORTED_PACKAGE_MANAGERS ,
@@ -64,6 +65,9 @@ type AddOn = {
6465 args ?: Array < string >
6566 }
6667 readme ?: string
68+ phase : 'setup' | 'add-on'
69+ shadcnComponents ?: Array < string >
70+ warning ?: string
6771}
6872
6973interface Options {
@@ -306,11 +310,11 @@ async function copyFilesRecursively(
306310 }
307311 } else {
308312 if ( source . endsWith ( '.ejs' ) ) {
309- const target = source . replace ( '.ejs' , '' )
310- await mkdir ( dirname ( target ) , {
313+ const targetPath = target . replace ( '.ejs' , '' )
314+ await mkdir ( dirname ( targetPath ) , {
311315 recursive : true ,
312316 } )
313- await templateFile ( source , target )
317+ await templateFile ( source , targetPath )
314318 } else {
315319 await mkdir ( dirname ( target ) , {
316320 recursive : true ,
@@ -466,22 +470,57 @@ async function createApp(projectName: string, options: Required<Options>) {
466470 )
467471
468472 // Copy all the asset files from the addons
469- for ( const addOn of options . chosenAddOns ) {
470- const addOnDir = resolve ( addOn . directory , 'assets' )
471- if ( existsSync ( addOnDir ) ) {
472- await copyFilesRecursively (
473- addOnDir ,
474- targetDir ,
475- copyFile ,
476- async ( file : string , targetFileName ?: string ) =>
477- templateFile ( addOnDir , file , targetFileName ) ,
478- )
473+ const s = spinner ( )
474+ for ( const phase of [ 'setup' , 'add-on' ] ) {
475+ for ( const addOn of options . chosenAddOns . filter (
476+ ( addOn ) => addOn . phase === phase ,
477+ ) ) {
478+ s . start ( `Setting up ${ addOn . name } ...` )
479+ const addOnDir = resolve ( addOn . directory , 'assets' )
480+ if ( existsSync ( addOnDir ) ) {
481+ await copyFilesRecursively (
482+ addOnDir ,
483+ targetDir ,
484+ copyFile ,
485+ async ( file : string , targetFileName ?: string ) =>
486+ templateFile ( addOnDir , file , targetFileName ) ,
487+ )
488+ }
489+
490+ if ( addOn . command ) {
491+ await execa ( addOn . command . command , addOn . command . args || [ ] , {
492+ cwd : targetDir ,
493+ } )
494+ }
495+ s . stop ( `${ addOn . name } setup complete` )
479496 }
497+ }
480498
481- if ( addOn . command ) {
482- await execa ( addOn . command . command , addOn . command . args || [ ] , {
499+ if ( isAddOnEnabled ( 'shadcn' ) ) {
500+ const shadcnComponents = new Set < string > ( )
501+ for ( const addOn of options . chosenAddOns ) {
502+ if ( addOn . shadcnComponents ) {
503+ for ( const component of addOn . shadcnComponents ) {
504+ shadcnComponents . add ( component )
505+ }
506+ }
507+ }
508+
509+ if ( shadcnComponents . size > 0 ) {
510+ s . start (
511+ `Installing shadcn components (${ Array . from ( shadcnComponents ) . join ( ', ' ) } )...` ,
512+ )
513+ await execa ( 'npx' , [ 'shadcn@canary' , 'add' , ...shadcnComponents ] , {
483514 cwd : targetDir ,
484515 } )
516+ s . stop ( `Installed shadcn components` )
517+ }
518+ }
519+
520+ const warnings : Array < string > = [ ]
521+ for ( const addOn of options . chosenAddOns ) {
522+ if ( addOn . warning ) {
523+ warnings . push ( addOn . warning )
485524 }
486525 }
487526
@@ -495,17 +534,20 @@ async function createApp(projectName: string, options: Required<Options>) {
495534 await templateFile ( templateDirBase , 'README.md.ejs' )
496535
497536 // Install dependencies
498- const s = spinner ( )
499537 s . start ( `Installing dependencies via ${ options . packageManager } ...` )
500538 await execa ( options . packageManager , [ 'install' ] , { cwd : targetDir } )
501539 s . stop ( `Installed dependencies` )
502540
541+ if ( warnings . length > 0 ) {
542+ log . warn ( chalk . red ( warnings . join ( '\n' ) ) )
543+ }
544+
503545 outro ( `Created your new TanStack app in ${ targetDir } .
504546
505547Use the following commands to start your app:
506548
507549% cd ${ projectName }
508- % ${ options . packageManager } start
550+ % ${ options . packageManager } ${ isAddOnEnabled ( ' start' ) ? 'dev' : 'start' }
509551
510552Please read README.md for more information on testing, styling, adding routes, react-query, etc.
511553` )
0 commit comments