11import { exec } from 'node:child_process' ;
2- import { mkdirSync , readFileSync , writeFileSync } from 'node:fs' ;
2+ import { existsSync , mkdirSync , readFileSync , writeFileSync } from 'node:fs' ;
33import path from 'node:path' ;
44import { promisify } from 'node:util' ;
5- import { confirm , intro , outro , tasks , text } from '@clack/prompts' ;
5+ import {
6+ cancel ,
7+ confirm ,
8+ intro ,
9+ isCancel ,
10+ log ,
11+ outro ,
12+ tasks ,
13+ text ,
14+ } from '@clack/prompts' ;
615import { Flags } from '@oclif/core' ;
716import chalk from 'chalk' ;
817import { BaseCommand } from '../base.js' ;
@@ -29,18 +38,62 @@ export default class Init extends BaseCommand {
2938 } ) ,
3039 } ;
3140
41+ /**
42+ *
43+ * @returns true if the current directory is a Next.js app
44+ */
45+ private isNextApp ( ) : boolean {
46+ const configFiles = [
47+ 'next.config.js' ,
48+ 'next.config.mjs' ,
49+ 'next.config.ts' ,
50+ 'next.config.cjs' ,
51+ ] ;
52+
53+ return configFiles . some ( ( file ) =>
54+ existsSync ( path . join ( process . cwd ( ) , file ) )
55+ ) ;
56+ }
57+
3258 public async run ( ) : Promise < void > {
3359 const { args, flags } = await this . parse ( Init ) ;
3460
35- intro ( 'create-workflow-app' ) ;
61+ intro ( 'workflow init' ) ;
62+
63+ const isNextApp = this . isNextApp ( ) ;
3664
37- const projectName =
38- args . projectName ||
39- ( ( await text ( {
40- message : 'What is your project name?' ,
41- placeholder : 'my-workflow-app' ,
42- defaultValue : 'my-workflow-app' ,
43- } ) ) as string ) ;
65+ let createNewProject = true ;
66+
67+ if ( isNextApp ) {
68+ log . info ( 'Detected Next.js app' ) ;
69+
70+ createNewProject = ( await confirm ( {
71+ message : 'Create a new project?' ,
72+ initialValue : true ,
73+ } ) ) as boolean ;
74+
75+ if ( isCancel ( createNewProject ) ) {
76+ cancel ( 'Cancelled workflow setup' ) ;
77+ return ;
78+ }
79+ }
80+
81+ let projectName = 'my-workflow-app' ;
82+
83+ if ( createNewProject ) {
84+ projectName =
85+ args . projectName ||
86+ ( ( await text ( {
87+ message : 'What is your project name?' ,
88+ placeholder : 'my-workflow-app' ,
89+ defaultValue : 'my-workflow-app' ,
90+ } ) ) as string ) ;
91+
92+ if ( isCancel ( projectName ) ) {
93+ cancel ( 'Cancelled workflow setup' ) ;
94+ return ;
95+ }
96+ }
4497
4598 const useTsPlugin =
4699 flags . yes ||
@@ -49,11 +102,19 @@ export default class Init extends BaseCommand {
49102 initialValue : true ,
50103 } ) ) as boolean ) ;
51104
52- const projectPath = path . join ( process . cwd ( ) , projectName ) ;
105+ if ( isCancel ( useTsPlugin ) ) {
106+ cancel ( 'Cancelled workflow setup' ) ;
107+ return ;
108+ }
109+
110+ const projectPath = createNewProject
111+ ? path . join ( process . cwd ( ) , projectName )
112+ : process . cwd ( ) ;
53113
54114 await tasks ( [
55115 {
56116 title : 'Creating Next.js app' ,
117+ enabled : createNewProject ,
57118 task : async ( message ) => {
58119 message ( 'Creating a new Next.js app' ) ;
59120 await execAsync ( `npx create-next-app@latest ${ projectName } --yes` ) ;
@@ -185,7 +246,7 @@ export async function POST(request: Request) {
185246
186247 outro (
187248 `${ chalk . green ( 'Success!' ) } Next steps:
188- Run ${ chalk . dim ( `cd ${ projectName } && npm run dev` ) } to start the development server
249+ Run ${ chalk . dim ( `${ createNewProject ? ` cd ${ projectName } && ` : '' } npm run dev` ) } to start the development server
189250 Trigger the workflow: ${ chalk . dim ( 'curl -X POST --json \'{"email":"[email protected] "}\' http://localhost:3000/api/signup' ) } ` 190251 ) ;
191252 }
0 commit comments