diff --git a/packages/create-nx-workspace/bin/create-nx-workspace.ts b/packages/create-nx-workspace/bin/create-nx-workspace.ts index ebf3074dd2256..36bce6debd497 100644 --- a/packages/create-nx-workspace/bin/create-nx-workspace.ts +++ b/packages/create-nx-workspace/bin/create-nx-workspace.ts @@ -36,13 +36,9 @@ interface BaseArguments extends CreateWorkspaceOptions { interface NoneArguments extends BaseArguments { stack: 'none'; - workspaceType: 'package-based' | 'integrated'; -} - -interface TsArguments extends BaseArguments { - stack: 'ts'; - workspaceType: 'standalone' | 'integrated'; + workspaceType: 'package-based' | 'integrated' | 'standalone'; js: boolean; + appName: string | undefined; } interface ReactArguments extends BaseArguments { @@ -78,7 +74,6 @@ interface UnknownStackArguments extends BaseArguments { type Arguments = | NoneArguments - | TsArguments | ReactArguments | AngularArguments | NodeArguments @@ -316,7 +311,7 @@ async function determineFolder( async function determineStack( parsedArgs: yargs.Arguments -): Promise<'none' | 'ts' | 'react' | 'angular' | 'node' | 'unknown'> { +): Promise<'none' | 'react' | 'angular' | 'node' | 'unknown'> { if (parsedArgs.preset) { switch (parsedArgs.preset) { case Preset.Angular: @@ -338,10 +333,9 @@ async function determineStack( case Preset.Empty: case Preset.Apps: case Preset.NPM: - return 'none'; case Preset.TS: case Preset.TsStandalone: - return 'ts'; + return 'none'; case Preset.WebComponents: case Preset.ReactNative: case Preset.Expo: @@ -351,7 +345,7 @@ async function determineStack( } const { stack } = await enquirer.prompt<{ - stack: 'none' | 'ts' | 'react' | 'angular' | 'node'; + stack: 'none' | 'react' | 'angular' | 'node'; }>([ { name: 'stack', @@ -360,23 +354,19 @@ async function determineStack( choices: [ { name: `none`, - message: `None: Configures a minimal structure without specific frameworks or technologies.`, - }, - { - name: `ts`, - message: `TS/JS: Configures a TypeScript/JavaScript package without specific frameworks or platforms.`, + message: `None: Configures a TypeScript/JavaScript project with minimal structure.`, }, { name: `react`, - message: `React: Configures a React app with your framework of choice.`, + message: `React: Configures a React application with your framework of choice.`, }, { name: `angular`, - message: `Angular: Configures a Angular app with modern tooling.`, + message: `Angular: Configures a Angular application with modern tooling.`, }, { name: `node`, - message: `Node: Configures a Node API with your framework of choice.`, + message: `Node: Configures a Node API application with your framework of choice.`, }, ], }, @@ -391,8 +381,6 @@ async function determinePresetOptions( switch (parsedArgs.stack) { case 'none': return determineNoneOptions(parsedArgs); - case 'ts': - return determineTsOptions(parsedArgs); case 'react': return determineReactOptions(parsedArgs); case 'angular': @@ -405,56 +393,25 @@ async function determinePresetOptions( } async function determineNoneOptions( - parsedArgs: yargs.Arguments -): Promise> { - if (parsedArgs.preset) return parsedArgs; - - const { workspaceType } = await enquirer.prompt<{ - workspaceType: 'package-based' | 'integrated'; - }>([ - { - type: 'autocomplete', - name: 'workspaceType', - message: `Package-based or integrated?`, - initial: 'package-based' as any, - choices: [ - { - name: 'package-based', - message: - 'Package-based: Nx makes it fast, but lets you run things your way.', - }, - { - name: 'integrated', - message: - 'Integrated: Nx creates a workspace structure most suitable for building apps.', - }, - ], - }, - ]); - - if (workspaceType === 'integrated') { - return { - preset: Preset.Apps, - }; - } else { - return { - preset: Preset.NPM, - }; - } -} - -async function determineTsOptions( - parsedArgs: yargs.Arguments -): Promise> { + parsedArgs: yargs.Arguments +): Promise> { let preset: Preset; - let workspaceType: 'standalone' | 'integrated' | undefined = undefined; + let workspaceType: 'package-based' | 'standalone' | 'integrated' | undefined = + undefined; let appName: string | undefined = undefined; - let js = false; + let js: boolean | undefined; if (parsedArgs.preset) { preset = parsedArgs.preset; } else { - workspaceType = await determineStandAloneOrMonorepo(); + workspaceType = await determinePackageBasedOrIntegratedOrStandalone(); + if (workspaceType === 'standalone') { + preset = Preset.TsStandalone; + } else if (workspaceType === 'integrated') { + preset = Preset.Apps; + } else { + preset = Preset.NPM; + } preset = workspaceType === 'standalone' ? Preset.TsStandalone : Preset.TS; } @@ -512,7 +469,7 @@ async function determineReactOptions( const workspaceType = framework === 'react-native' || framework === 'expo' ? 'integrated' - : await determineStandAloneOrMonorepo(); + : await determineStandaloneOrMonorepo(); if (workspaceType === 'standalone') { appName = parsedArgs.name; @@ -614,7 +571,7 @@ async function determineAngularOptions( appName = await determineAppName(parsedArgs); } } else { - const workspaceType = await determineStandAloneOrMonorepo(); + const workspaceType = await determineStandaloneOrMonorepo(); if (workspaceType === 'standalone') { preset = Preset.AngularStandalone; @@ -731,7 +688,7 @@ async function determineNodeOptions( } else { framework = await determineNodeFramework(parsedArgs); - const workspaceType = await determineStandAloneOrMonorepo(); + const workspaceType = await determineStandaloneOrMonorepo(); if (workspaceType === 'standalone') { preset = Preset.NodeStandalone; appName = parsedArgs.name; @@ -773,28 +730,68 @@ async function determineNodeOptions( }; } -async function determineStandAloneOrMonorepo(): Promise< - 'integrated' | 'standalone' +async function determinePackageBasedOrIntegratedOrStandalone(): Promise< + 'package-based' | 'integrated' | 'standalone' > { const { workspaceType } = await enquirer.prompt<{ - workspaceType: 'standalone' | 'integrated'; + workspaceType: 'standalone' | 'integrated' | 'package-based'; }>([ { type: 'autocomplete', name: 'workspaceType', - message: `Standalone project or integrated monorepo?`, - initial: 'standalone' as any, + message: `Package-based monorepo, integrated monorepo, or standalone project?`, + initial: 'package-based' as any, choices: [ + { + name: 'package-based', + message: + 'Package-based Monorepo: Nx makes it fast, but lets you run things your way.', + }, + { + name: 'integrated', + message: + 'Integrated Monorepo: Nx creates a monorepo that contains multiple projects.', + }, { name: 'standalone', message: - 'Standalone: Nx creates a single project and makes it fast.', + 'Standalone: Nx creates a single project and makes it fast.', }, + ], + }, + ]); + + invariant(workspaceType, { + title: 'Invalid workspace type', + bodyLines: [ + `It must be one of the following: standalone, integrated. Got ${workspaceType}`, + ], + }); + + return workspaceType; +} +async function determineStandaloneOrMonorepo(): Promise< + 'integrated' | 'standalone' +> { + const { workspaceType } = await enquirer.prompt<{ + workspaceType: 'standalone' | 'integrated'; + }>([ + { + type: 'autocomplete', + name: 'workspaceType', + message: `Integrated monorepo, or standalone project?`, + initial: 'standalone' as any, + choices: [ { name: 'integrated', message: 'Integrated Monorepo: Nx creates a monorepo that contains multiple projects.', }, + { + name: 'standalone', + message: + 'Standalone: Nx creates a single project and makes it fast.', + }, ], }, ]);