@@ -10,6 +10,7 @@ const {
10
10
blue,
11
11
blueBright,
12
12
cyan,
13
+ gray,
13
14
green,
14
15
greenBright,
15
16
magenta,
@@ -311,6 +312,7 @@ async function init() {
311
312
}
312
313
313
314
let targetDir = argTargetDir || defaultTargetDir
315
+ const pkgInfo = pkgFromUserAgent ( process . env . npm_config_user_agent )
314
316
const getProjectName = ( ) => path . basename ( path . resolve ( targetDir ) )
315
317
316
318
let result : prompts . Answers <
@@ -402,9 +404,16 @@ async function init() {
402
404
choices : ( framework : Framework ) =>
403
405
framework . variants . map ( ( variant ) => {
404
406
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
405
413
return {
406
414
title : variantColor ( variant . display || variant . name ) ,
407
415
value : variant . name ,
416
+ description : command ? gray ( command ) : undefined ,
408
417
}
409
418
} ) ,
410
419
} ,
@@ -439,40 +448,13 @@ async function init() {
439
448
template = template . replace ( '-swc' , '' )
440
449
}
441
450
442
- const pkgInfo = pkgFromUserAgent ( process . env . npm_config_user_agent )
443
451
const pkgManager = pkgInfo ? pkgInfo . name : 'npm'
444
- const isYarn1 = pkgManager === 'yarn' && pkgInfo ?. version . startsWith ( '1.' )
445
452
446
453
const { customCommand } =
447
454
FRAMEWORKS . flatMap ( ( f ) => f . variants ) . find ( ( v ) => v . name === template ) ?? { }
448
455
449
456
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 )
476
458
477
459
const [ command , ...args ] = fullCustomCommand . split ( ' ' )
478
460
// we replace TARGET_DIR here because targetDir may include a space
@@ -595,7 +577,12 @@ function emptyDir(dir: string) {
595
577
}
596
578
}
597
579
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 {
599
586
if ( ! userAgent ) return undefined
600
587
const pkgSpec = userAgent . split ( ' ' ) [ 0 ]
601
588
const pkgSpecArr = pkgSpec . split ( '/' )
@@ -625,6 +612,40 @@ function editFile(file: string, callback: (content: string) => string) {
625
612
fs . writeFileSync ( file , callback ( content ) , 'utf-8' )
626
613
}
627
614
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
+
628
649
init ( ) . catch ( ( e ) => {
629
650
console . error ( e )
630
651
} )
0 commit comments