@@ -44,6 +44,7 @@ export function parseArgumentsIntoOptions(rawArgs) {
4444 {
4545 '--app-name' : String ,
4646 '--db' : String ,
47+ '--use-npm' : Boolean ,
4748 // you can add more flags here if needed
4849 } ,
4950 {
@@ -54,6 +55,7 @@ export function parseArgumentsIntoOptions(rawArgs) {
5455 return {
5556 appName : args [ '--app-name' ] ,
5657 db : args [ '--db' ] ,
58+ useNpm : args [ '--use-npm' ] ,
5759 } ;
5860}
5961
@@ -78,11 +80,21 @@ export async function promptForMissingOptions(options) {
7880 } ) ;
7981 } ;
8082
83+ if ( ! options . useNpm ) {
84+ questions . push ( {
85+ type : 'confirm' ,
86+ name : 'useNpm' ,
87+ message : 'Do you want to use npm instead of pnpm?' ,
88+ default : false ,
89+ } ) ;
90+ }
91+
8192 const answers = await inquirer . prompt ( questions ) ;
8293 return {
8394 ...options ,
8495 appName : options . appName || answers . appName ,
8596 db : options . db || answers . db ,
97+ useNpm : options . useNpm || answers . useNpm ,
8698 } ;
8799}
88100
@@ -230,7 +242,7 @@ async function scaffoldProject(ctx, options, cwd) {
230242 await fse . copy ( sourceAssetsDir , targetAssetsDir ) ;
231243
232244 // Write templated files
233- await writeTemplateFiles ( dirname , projectDir , {
245+ await writeTemplateFiles ( dirname , projectDir , options . useNpm , {
234246 dbUrl : connectionString . toString ( ) ,
235247 dbUrlProd : connectionStringProd ,
236248 prismaDbUrl,
@@ -244,7 +256,7 @@ async function scaffoldProject(ctx, options, cwd) {
244256 return projectDir ; // Return the new directory path
245257}
246258
247- async function writeTemplateFiles ( dirname , cwd , options ) {
259+ async function writeTemplateFiles ( dirname , cwd , useNpm , options ) {
248260 const {
249261 dbUrl, prismaDbUrl, appName, provider, nodeMajor,
250262 dbUrlProd, prismaDbUrlProd, sqliteFile
@@ -268,14 +280,6 @@ async function writeTemplateFiles(dirname, cwd, options) {
268280 dest : 'prisma.config.ts' ,
269281 data : { } ,
270282 } ,
271- {
272- src : 'package.json.hbs' ,
273- dest : 'package.json' ,
274- data : {
275- appName,
276- adminforthVersion : adminforthVersion ,
277- } ,
278- } ,
279283 {
280284 src : 'index.ts.hbs' ,
281285 dest : 'index.ts' ,
@@ -304,7 +308,7 @@ async function writeTemplateFiles(dirname, cwd, options) {
304308 {
305309 src : 'readme.md.hbs' ,
306310 dest : 'README.md' ,
307- data : { dbUrl, prismaDbUrl, appName, sqliteFile } ,
311+ data : { dbUrl, prismaDbUrl, appName, sqliteFile, useNpm } ,
308312 } ,
309313 {
310314 // We'll write .env using the same content as .env.sample
@@ -322,11 +326,6 @@ async function writeTemplateFiles(dirname, cwd, options) {
322326 dest : 'custom/tsconfig.json' ,
323327 data : { } ,
324328 } ,
325- {
326- src : 'Dockerfile.hbs' ,
327- dest : 'Dockerfile' ,
328- data : { nodeMajor } ,
329- } ,
330329 {
331330 src : '.dockerignore.hbs' ,
332331 dest : '.dockerignore' ,
@@ -335,12 +334,39 @@ async function writeTemplateFiles(dirname, cwd, options) {
335334 } ,
336335 } ,
337336 {
338- src : 'pnpm-workspace.yaml.hbs' ,
339- dest : 'pnpm-workspace.yaml' ,
340- data : { } ,
341- }
337+ src : 'Dockerfile.hbs' ,
338+ dest : 'Dockerfile' ,
339+ data : { nodeMajor, useNpm } ,
340+ } ,
341+ {
342+ src : 'package.json.hbs' ,
343+ dest : 'package.json' ,
344+ data : {
345+ appName,
346+ adminforthVersion : adminforthVersion ,
347+ useNpm
348+ } ,
349+ } ,
342350 ] ;
343351
352+ if ( ! useNpm ) {
353+ templateTasks . push (
354+ {
355+ src : 'pnpm_templates/pnpm-workspace.yaml.hbs' ,
356+ dest : 'pnpm-workspace.yaml' ,
357+ data : { } ,
358+ } ,
359+ )
360+ } else {
361+ templateTasks . push (
362+ {
363+ src : 'custom/package.json.hbs' ,
364+ dest : 'custom/package.json' ,
365+ data : { }
366+ }
367+ )
368+ }
369+
344370 for ( const task of templateTasks ) {
345371 // If a condition is specified and false, skip this file
346372 if ( task . condition === false ) continue ;
@@ -358,7 +384,7 @@ async function writeTemplateFiles(dirname, cwd, options) {
358384 }
359385}
360386
361- async function installDependencies ( ctx , cwd ) {
387+ async function installDependenciesPnpm ( ctx , cwd ) {
362388 const isWindows = process . platform === 'win32' ;
363389
364390 const nodeBinary = process . execPath ;
@@ -375,10 +401,28 @@ async function installDependencies(ctx, cwd) {
375401 await execAsync ( `${ nodeBinary } ${ npmPath } install` , { cwd : customDir , env : { PATH : process . env . PATH } } ) ,
376402 ] ) ;
377403 }
378- // console.log(chalk.dim(`Dependencies installed in ${cwd} and ${customDir}: \n${res[0].stdout}${res[1].stdout}`));
379404}
380405
381- function generateFinalInstructions ( skipPrismaSetup , options ) {
406+ async function installDependenciesNpm ( ctx , cwd ) {
407+ const isWindows = process . platform === 'win32' ;
408+
409+ const nodeBinary = process . execPath ;
410+ const npmPath = path . join ( path . dirname ( nodeBinary ) , isWindows ? 'npm.cmd' : 'npm' ) ;
411+ const customDir = ctx . customDir ;
412+ if ( isWindows ) {
413+ const res = await Promise . all ( [
414+ await execAsync ( `npm install` , { cwd, env : { PATH : process . env . PATH } } ) ,
415+ await execAsync ( `npm install` , { cwd : customDir , env : { PATH : process . env . PATH } } ) ,
416+ ] ) ;
417+ } else {
418+ const res = await Promise . all ( [
419+ await execAsync ( `${ nodeBinary } ${ npmPath } install` , { cwd, env : { PATH : process . env . PATH } } ) ,
420+ await execAsync ( `${ nodeBinary } ${ npmPath } install` , { cwd : customDir , env : { PATH : process . env . PATH } } ) ,
421+ ] ) ;
422+ }
423+ }
424+
425+ function generateFinalInstructionsPnpm ( skipPrismaSetup , options ) {
382426 let instruction = '⏭️ Run the following commands to get started:\n' ;
383427 if ( ! skipPrismaSetup )
384428 instruction += `
@@ -399,6 +443,27 @@ function generateFinalInstructions(skipPrismaSetup, options) {
399443 return instruction ;
400444}
401445
446+ function generateFinalInstructionsNpm ( skipPrismaSetup , options ) {
447+ let instruction = '⏭️ Run the following commands to get started:\n' ;
448+ if ( ! skipPrismaSetup )
449+ instruction += `
450+ ${ chalk . dim ( '// Go to the project directory' ) }
451+ ${ chalk . dim ( '$' ) } ${ chalk . cyan ( ` cd ${ options . appName } ` ) } \n` ;
452+
453+ instruction += `
454+ ${ chalk . dim ( '// Generate and apply initial migration' ) }
455+ ${ chalk . dim ( '$' ) } ${ chalk . cyan ( ' npm run makemigration -- --name init && npm run migrate:local' ) } \n` ;
456+
457+ instruction += `
458+ ${ chalk . dim ( '// Start dev server with tsx watch for hot-reloading' ) }
459+ ${ chalk . dim ( '$' ) } ${ chalk . cyan ( ' npm run dev' ) } \n
460+ ` ;
461+
462+ instruction += '😉 Happy coding!' ;
463+
464+ return instruction ;
465+ }
466+
402467function renderHBSTemplate ( templatePath , data ) {
403468 // Example: renderHBRTemplate('path/to/template.hbs', {name: 'John Doe'})
404469 const template = fs . readFileSync ( templatePath , 'utf-8' ) ;
@@ -425,13 +490,23 @@ export function prepareWorkflow(options) {
425490 } ,
426491 {
427492 title : '📦 Installing dependencies...' ,
428- task : async ( ctx ) => installDependencies ( ctx , ctx . projectDir )
493+ task : async ( ctx ) => {
494+ if ( options . useNpm ) {
495+ await installDependenciesNpm ( ctx , ctx . projectDir ) ;
496+ } else {
497+ await installDependenciesPnpm ( ctx , ctx . projectDir ) ;
498+ }
499+ }
429500 } ,
430501 {
431502 title : '📝 Preparing final instructions...' ,
432503 task : ( ctx ) => {
433504 console . log ( chalk . green ( `✅ Successfully created your new Adminforth project in ${ ctx . projectDir } !\n` ) ) ;
434- console . log ( generateFinalInstructions ( ctx . skipPrismaSetup , options ) ) ;
505+ if ( options . useNpm ) {
506+ console . log ( generateFinalInstructionsNpm ( ctx . skipPrismaSetup , options ) ) ;
507+ } else {
508+ console . log ( generateFinalInstructionsPnpm ( ctx . skipPrismaSetup , options ) ) ;
509+ }
435510 console . log ( '\n\n' ) ;
436511 }
437512 }
0 commit comments