@@ -10,6 +10,7 @@ const {
1010 blue,
1111 blueBright,
1212 cyan,
13+ gray,
1314 green,
1415 greenBright,
1516 magenta,
@@ -311,6 +312,7 @@ async function init() {
311312 }
312313
313314 let targetDir = argTargetDir || defaultTargetDir
315+ const pkgInfo = pkgFromUserAgent ( process . env . npm_config_user_agent )
314316 const getProjectName = ( ) => path . basename ( path . resolve ( targetDir ) )
315317
316318 let result : prompts . Answers <
@@ -402,9 +404,16 @@ async function init() {
402404 choices : ( framework : Framework ) =>
403405 framework . variants . map ( ( variant ) => {
404406 const variantColor = variant . color
407+ const command = variant . customCommand
408+ ? getFullCustomCommand ( variant . customCommand , pkgInfo ) . replace (
409+ / T A R G E T _ D I R $ / ,
410+ '' ,
411+ )
412+ : undefined
405413 return {
406414 title : variantColor ( variant . display || variant . name ) ,
407415 value : variant . name ,
416+ description : command ? gray ( command ) : undefined ,
408417 }
409418 } ) ,
410419 } ,
@@ -439,40 +448,13 @@ async function init() {
439448 template = template . replace ( '-swc' , '' )
440449 }
441450
442- const pkgInfo = pkgFromUserAgent ( process . env . npm_config_user_agent )
443451 const pkgManager = pkgInfo ? pkgInfo . name : 'npm'
444- const isYarn1 = pkgManager === 'yarn' && pkgInfo ?. version . startsWith ( '1.' )
445452
446453 const { customCommand } =
447454 FRAMEWORKS . flatMap ( ( f ) => f . variants ) . find ( ( v ) => v . name === template ) ?? { }
448455
449456 if ( customCommand ) {
450- const fullCustomCommand = customCommand
451- . replace ( / ^ n p m c r e a t e / , ( ) => {
452- // `bun create` uses it's own set of templates,
453- // the closest alternative is using `bun x` directly on the package
454- if ( pkgManager === 'bun' ) {
455- return 'bun x create-'
456- }
457- return `${ pkgManager } create `
458- } )
459- // Only Yarn 1.x doesn't support `@version` in the `create` command
460- . replace ( '@latest' , ( ) => ( isYarn1 ? '' : '@latest' ) )
461- . replace ( / ^ n p m e x e c / , ( ) => {
462- // Prefer `pnpm dlx`, `yarn dlx`, or `bun x`
463- if ( pkgManager === 'pnpm' ) {
464- return 'pnpm dlx'
465- }
466- if ( pkgManager === 'yarn' && ! isYarn1 ) {
467- return 'yarn dlx'
468- }
469- if ( pkgManager === 'bun' ) {
470- return 'bun x'
471- }
472- // Use `npm exec` in all other cases,
473- // including Yarn 1.x and other custom npm clients.
474- return 'npm exec'
475- } )
457+ const fullCustomCommand = getFullCustomCommand ( customCommand , pkgInfo )
476458
477459 const [ command , ...args ] = fullCustomCommand . split ( ' ' )
478460 // we replace TARGET_DIR here because targetDir may include a space
@@ -595,7 +577,12 @@ function emptyDir(dir: string) {
595577 }
596578}
597579
598- function pkgFromUserAgent ( userAgent : string | undefined ) {
580+ interface PkgInfo {
581+ name : string
582+ version : string
583+ }
584+
585+ function pkgFromUserAgent ( userAgent : string | undefined ) : PkgInfo | undefined {
599586 if ( ! userAgent ) return undefined
600587 const pkgSpec = userAgent . split ( ' ' ) [ 0 ]
601588 const pkgSpecArr = pkgSpec . split ( '/' )
@@ -625,6 +612,40 @@ function editFile(file: string, callback: (content: string) => string) {
625612 fs . writeFileSync ( file , callback ( content ) , 'utf-8' )
626613}
627614
615+ function getFullCustomCommand ( customCommand : string , pkgInfo ?: PkgInfo ) {
616+ const pkgManager = pkgInfo ? pkgInfo . name : 'npm'
617+ const isYarn1 = pkgManager === 'yarn' && pkgInfo ?. version . startsWith ( '1.' )
618+
619+ return (
620+ customCommand
621+ . replace ( / ^ n p m c r e a t e / , ( ) => {
622+ // `bun create` uses it's own set of templates,
623+ // the closest alternative is using `bun x` directly on the package
624+ if ( pkgManager === 'bun' ) {
625+ return 'bun x create-'
626+ }
627+ return `${ pkgManager } create `
628+ } )
629+ // Only Yarn 1.x doesn't support `@version` in the `create` command
630+ . replace ( '@latest' , ( ) => ( isYarn1 ? '' : '@latest' ) )
631+ . replace ( / ^ n p m e x e c / , ( ) => {
632+ // Prefer `pnpm dlx`, `yarn dlx`, or `bun x`
633+ if ( pkgManager === 'pnpm' ) {
634+ return 'pnpm dlx'
635+ }
636+ if ( pkgManager === 'yarn' && ! isYarn1 ) {
637+ return 'yarn dlx'
638+ }
639+ if ( pkgManager === 'bun' ) {
640+ return 'bun x'
641+ }
642+ // Use `npm exec` in all other cases,
643+ // including Yarn 1.x and other custom npm clients.
644+ return 'npm exec'
645+ } )
646+ )
647+ }
648+
628649init ( ) . catch ( ( e ) => {
629650 console . error ( e )
630651} )
0 commit comments