create-nx-workspace 16.3.0-beta.13 → 16.3.0-beta.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,19 +7,17 @@ const yargs = require("yargs");
7
7
  const chalk = require("chalk");
8
8
  const create_workspace_1 = require("../src/create-workspace");
9
9
  const preset_1 = require("../src/utils/preset/preset");
10
- const preset_options_1 = require("../src/utils/preset/preset-options");
11
10
  const output_1 = require("../src/utils/output");
12
11
  const nx_version_1 = require("../src/utils/nx/nx-version");
13
12
  const point_to_tutorial_and_course_1 = require("../src/utils/preset/point-to-tutorial-and-course");
14
13
  const decorator_1 = require("./decorator");
15
14
  const get_third_party_preset_1 = require("../src/utils/preset/get-third-party-preset");
16
- const framework_list_1 = require("./types/framework-list");
17
- const bundler_list_1 = require("./types/bundler-list");
18
15
  const prompts_1 = require("../src/internal-utils/prompts");
19
16
  const yargs_options_1 = require("../src/internal-utils/yargs-options");
20
17
  const show_nx_warning_1 = require("../src/utils/nx/show-nx-warning");
21
18
  const nx_cloud_1 = require("../src/utils/nx/nx-cloud");
22
19
  const ab_testing_1 = require("../src/utils/nx/ab-testing");
20
+ const fs_1 = require("fs");
23
21
  exports.commandsObject = yargs
24
22
  .wrap(yargs.terminalWidth())
25
23
  .parserConfiguration({
@@ -38,18 +36,23 @@ exports.commandsObject = yargs
38
36
  .map((p) => `"${p}"`)
39
37
  .join(', ')}]. To build your own see https://nx.dev/packages/nx-plugin#preset`,
40
38
  type: 'string',
41
- })
42
- .option('appName', {
43
- describe: chalk.dim `The name of the application when a preset with pregenerated app is selected`,
44
- type: 'string',
45
39
  })
46
40
  .option('interactive', {
47
41
  describe: chalk.dim `Enable interactive mode with presets`,
48
42
  type: 'boolean',
49
43
  default: true,
44
+ })
45
+ .option('workspaceType', {
46
+ describe: chalk.dim `The type of workspace to create`,
47
+ choices: ['integrated', 'package-based', 'standalone'],
48
+ type: 'string',
49
+ })
50
+ .option('appName', {
51
+ describe: chalk.dim `The name of the app when using a monorepo with certain stacks`,
52
+ type: 'string',
50
53
  })
51
54
  .option('style', {
52
- describe: chalk.dim `Style option to be used when a preset with pregenerated app is selected`,
55
+ describe: chalk.dim `Stylesheet type to be used with certain stacks`,
53
56
  type: 'string',
54
57
  })
55
58
  .option('standaloneApi', {
@@ -57,35 +60,35 @@ exports.commandsObject = yargs
57
60
  type: 'boolean',
58
61
  })
59
62
  .option('routing', {
60
- describe: chalk.dim `Add a routing setup when a preset with pregenerated app is selected`,
63
+ describe: chalk.dim `Add a routing setup for an Angular app`,
61
64
  type: 'boolean',
62
65
  })
63
66
  .option('bundler', {
64
- describe: chalk.dim `Bundler to be used to build the application`,
65
- choices: bundler_list_1.bundlerList,
67
+ describe: chalk.dim `Bundler to be used to build the app`,
66
68
  type: 'string',
67
69
  })
68
70
  .option('framework', {
69
- describe: chalk.dim `Framework option to be used when the node-standalone preset is selected`,
70
- choices: framework_list_1.frameworkList,
71
+ describe: chalk.dim `Framework option to be used with certain stacks`,
71
72
  type: 'string',
72
73
  })
73
74
  .option('docker', {
74
- describe: chalk.dim `Generate a Dockerfile with your node-standalone`,
75
+ describe: chalk.dim `Generate a Dockerfile for the Node API`,
75
76
  type: 'boolean',
76
77
  })
77
78
  .option('nextAppDir', {
78
79
  describe: chalk.dim `Enable the App Router for Next.js`,
79
80
  type: 'boolean',
80
- }), yargs_options_1.withNxCloud, yargs_options_1.withCI, yargs_options_1.withAllPrompts, yargs_options_1.withPackageManager, yargs_options_1.withGitOptions), (argv) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
81
- yield main(argv).catch((error) => {
82
- const { version } = require('../package.json');
83
- output_1.output.error({
84
- title: `Something went wrong! v${version}`,
81
+ }), yargs_options_1.withNxCloud, yargs_options_1.withCI, yargs_options_1.withAllPrompts, yargs_options_1.withPackageManager, yargs_options_1.withGitOptions), function handler(argv) {
82
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
83
+ yield main(argv).catch((error) => {
84
+ const { version } = require('../package.json');
85
+ output_1.output.error({
86
+ title: `Something went wrong! v${version}`,
87
+ });
88
+ throw error;
85
89
  });
86
- throw error;
87
90
  });
88
- }), [normalizeArgsMiddleware])
91
+ }, [normalizeArgsMiddleware])
89
92
  .help('help', chalk.dim `Show help`)
90
93
  .updateLocale(decorator_1.yargsDecorator)
91
94
  .version('version', chalk.dim `Show version`, nx_version_1.nxVersion);
@@ -126,14 +129,14 @@ function main(parsedArgs) {
126
129
  * @param argv user arguments
127
130
  */
128
131
  function normalizeArgsMiddleware(argv) {
129
- var _a, _b, _c, _d, _e, _f, _g;
130
132
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
133
+ output_1.output.log({
134
+ title: "Let's create a new workspace [https://nx.dev/getting-started/intro]",
135
+ });
131
136
  try {
132
- let name, appName, style, preset, framework, bundler, docker, nextAppDir, routing, standaloneApi;
133
- output_1.output.log({
134
- title: "Let's create a new workspace [https://nx.dev/getting-started/intro]",
135
- });
136
137
  let thirdPartyPreset;
138
+ // Node options
139
+ let docker;
137
140
  try {
138
141
  thirdPartyPreset = yield (0, get_third_party_preset_1.getThirdPartyPreset)(argv.preset);
139
142
  }
@@ -143,101 +146,28 @@ function normalizeArgsMiddleware(argv) {
143
146
  });
144
147
  process.exit(1);
145
148
  }
149
+ argv.name = yield determineFolder(argv);
146
150
  if (thirdPartyPreset) {
147
- preset = thirdPartyPreset;
148
- name = yield determineRepoName(argv);
149
- appName = '';
150
- style = null;
151
+ Object.assign(argv, {
152
+ preset: thirdPartyPreset,
153
+ appName: '',
154
+ style: '',
155
+ });
151
156
  }
152
157
  else {
153
- if (!argv.preset) {
154
- const monorepoStyle = yield determineMonorepoStyle();
155
- if (monorepoStyle === 'package-based') {
156
- preset = 'npm';
157
- }
158
- else if (monorepoStyle === 'react') {
159
- preset = yield determineReactFramework(argv);
160
- }
161
- else if (monorepoStyle === 'angular') {
162
- preset = preset_1.Preset.AngularStandalone;
163
- }
164
- else if (monorepoStyle === 'node-standalone') {
165
- preset = preset_1.Preset.NodeStandalone;
166
- }
167
- else {
168
- // when choose integrated monorepo, further prompt for preset
169
- preset = yield determinePreset(argv);
170
- }
171
- }
172
- else if (argv.preset === 'react') {
173
- preset = yield monorepoOrStandalone('react');
174
- }
175
- else if (argv.preset === 'angular') {
176
- preset = yield monorepoOrStandalone('angular');
177
- }
178
- else {
179
- preset = argv.preset;
180
- }
181
- if (preset === preset_1.Preset.ReactStandalone ||
182
- preset === preset_1.Preset.AngularStandalone ||
183
- preset === preset_1.Preset.NodeStandalone ||
184
- preset === preset_1.Preset.NextJsStandalone) {
185
- appName =
186
- (_b = (_a = argv.appName) !== null && _a !== void 0 ? _a : argv.name) !== null && _b !== void 0 ? _b : (yield determineAppName(preset, argv));
187
- name = (_c = argv.name) !== null && _c !== void 0 ? _c : appName;
188
- if (preset === preset_1.Preset.NodeStandalone) {
189
- framework = yield determineFramework(argv);
190
- if (framework !== 'none') {
191
- docker = yield determineDockerfile(argv);
192
- }
193
- }
194
- if (preset === preset_1.Preset.NextJsStandalone) {
195
- nextAppDir = yield isNextAppDir(argv);
196
- }
197
- if (preset === preset_1.Preset.ReactStandalone) {
198
- bundler = yield determineBundler(argv);
199
- }
200
- if (preset === preset_1.Preset.AngularStandalone) {
201
- standaloneApi =
202
- (_d = argv.standaloneApi) !== null && _d !== void 0 ? _d : (argv.interactive ? yield determineStandaloneApi(argv) : false);
203
- routing =
204
- (_e = argv.routing) !== null && _e !== void 0 ? _e : (argv.interactive ? yield determineRouting(argv) : true);
205
- }
206
- }
207
- else {
208
- name = yield determineRepoName(argv);
209
- appName = yield determineAppName(preset, argv);
210
- if (preset === preset_1.Preset.ReactMonorepo) {
211
- bundler = yield determineBundler(argv);
212
- }
213
- if (preset === preset_1.Preset.AngularMonorepo) {
214
- standaloneApi =
215
- (_f = argv.standaloneApi) !== null && _f !== void 0 ? _f : (argv.interactive ? yield determineStandaloneApi(argv) : false);
216
- routing =
217
- (_g = argv.routing) !== null && _g !== void 0 ? _g : (argv.interactive ? yield determineRouting(argv) : true);
218
- }
219
- }
220
- style = yield determineStyle(preset, argv);
158
+ argv.stack = yield determineStack(argv);
159
+ const presetOptions = yield determinePresetOptions(argv);
160
+ Object.assign(argv, presetOptions);
221
161
  }
222
162
  const packageManager = yield (0, prompts_1.determinePackageManager)(argv);
223
163
  const defaultBase = yield (0, prompts_1.determineDefaultBase)(argv);
224
164
  const nxCloud = yield (0, prompts_1.determineNxCloud)(argv);
225
165
  const ci = yield (0, prompts_1.determineCI)(argv, nxCloud);
226
166
  Object.assign(argv, {
227
- name,
228
- preset,
229
- appName,
230
- style,
231
- standaloneApi,
232
- routing,
233
- framework,
234
167
  nxCloud,
235
168
  packageManager,
236
169
  defaultBase,
237
170
  ci,
238
- bundler,
239
- docker,
240
- nextAppDir,
241
171
  });
242
172
  }
243
173
  catch (e) {
@@ -246,224 +176,341 @@ function normalizeArgsMiddleware(argv) {
246
176
  }
247
177
  });
248
178
  }
249
- function determineRepoName(parsedArgs) {
179
+ function invariant(predicate, message) {
180
+ if (!predicate) {
181
+ output_1.output.error(message);
182
+ process.exit(1);
183
+ }
184
+ }
185
+ function determineFolder(parsedArgs) {
250
186
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
251
- const repoName = parsedArgs._[0]
187
+ const folderName = parsedArgs._[0]
252
188
  ? parsedArgs._[0].toString()
253
189
  : parsedArgs.name;
254
- if (repoName) {
255
- return Promise.resolve(repoName);
256
- }
257
- const a = yield enquirer.prompt([
190
+ if (folderName)
191
+ return folderName;
192
+ const reply = yield enquirer.prompt([
258
193
  {
259
- name: 'RepoName',
260
- message: `Repository name `,
194
+ name: 'folderName',
195
+ message: `Where would you like to create your workspace?`,
196
+ initial: 'org',
261
197
  type: 'input',
262
198
  },
263
199
  ]);
264
- if (!a.RepoName) {
265
- output_1.output.error({
266
- title: 'Invalid repository name',
267
- bodyLines: [`Repository name cannot be empty`],
268
- });
269
- process.exit(1);
270
- }
271
- return a.RepoName;
200
+ invariant(reply.folderName, {
201
+ title: 'Invalid folder name',
202
+ bodyLines: [`Folder name cannot be empty`],
203
+ });
204
+ invariant(!(0, fs_1.existsSync)(reply.folderName), {
205
+ title: 'That folder is already taken',
206
+ });
207
+ return reply.folderName;
272
208
  });
273
209
  }
274
- function monorepoOrStandalone(preset) {
210
+ function determineStack(parsedArgs) {
275
211
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
276
- const a = yield enquirer.prompt([
212
+ if (parsedArgs.preset) {
213
+ switch (parsedArgs.preset) {
214
+ case preset_1.Preset.Angular:
215
+ case preset_1.Preset.AngularStandalone:
216
+ case preset_1.Preset.AngularMonorepo:
217
+ return 'angular';
218
+ case preset_1.Preset.React:
219
+ case preset_1.Preset.ReactStandalone:
220
+ case preset_1.Preset.ReactMonorepo:
221
+ case preset_1.Preset.NextJs:
222
+ case preset_1.Preset.NextJsStandalone:
223
+ return 'react';
224
+ case preset_1.Preset.Nest:
225
+ case preset_1.Preset.NodeStandalone:
226
+ case preset_1.Preset.Express:
227
+ return 'node';
228
+ case preset_1.Preset.Core:
229
+ case preset_1.Preset.Empty:
230
+ case preset_1.Preset.Apps:
231
+ case preset_1.Preset.NPM:
232
+ return 'minimal';
233
+ case preset_1.Preset.TS:
234
+ case preset_1.Preset.WebComponents:
235
+ case preset_1.Preset.ReactNative:
236
+ case preset_1.Preset.Expo:
237
+ default:
238
+ return 'unknown';
239
+ }
240
+ }
241
+ const { stack } = yield enquirer.prompt([
277
242
  {
278
- name: 'MonorepoOrStandalone',
279
- message: `--preset=${preset} has been replaced with the following:`,
243
+ name: 'stack',
244
+ message: `Which stack do you want to use?`,
280
245
  type: 'autocomplete',
281
246
  choices: [
282
247
  {
283
- name: preset + '-standalone',
284
- message: `${preset}-standalone: a standalone ${preset} application.`,
248
+ name: `minimal`,
249
+ message: `None: Configures a minimal structure without specific frameworks or technologies.`,
250
+ },
251
+ {
252
+ name: `react`,
253
+ message: `React: Configures a React app with your framework of choice.`,
254
+ },
255
+ {
256
+ name: `angular`,
257
+ message: `Angular: Configures a Angular app with modern tooling.`,
285
258
  },
286
259
  {
287
- name: preset + '-monorepo',
288
- message: `${preset}-monorepo: a monorepo with the apps and libs folders.`,
260
+ name: `node`,
261
+ message: `Node: Configures a Node API with your framework of choice.`,
289
262
  },
290
263
  ],
291
264
  },
292
265
  ]);
293
- if (!a.MonorepoOrStandalone) {
294
- output_1.output.error({
295
- title: 'Invalid selection',
296
- });
297
- process.exit(1);
266
+ invariant(stack, {
267
+ title: 'Invalid stack selection',
268
+ });
269
+ return stack;
270
+ });
271
+ }
272
+ function determinePresetOptions(parsedArgs) {
273
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
274
+ switch (parsedArgs.stack) {
275
+ case 'minimal':
276
+ return determineMinimalOptions(parsedArgs);
277
+ case 'react':
278
+ return determineReactOptions(parsedArgs);
279
+ case 'angular':
280
+ return determineAngularOptions(parsedArgs);
281
+ case 'node':
282
+ return determineNodeOptions(parsedArgs);
283
+ default:
284
+ return parsedArgs;
298
285
  }
299
- return a.MonorepoOrStandalone;
300
286
  });
301
287
  }
302
- function determineMonorepoStyle() {
288
+ function determineMinimalOptions(parsedArgs) {
303
289
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
304
- const a = yield enquirer.prompt([
290
+ if (parsedArgs.preset)
291
+ return parsedArgs;
292
+ const { workspaceType } = yield enquirer.prompt([
305
293
  {
306
- name: 'MonorepoStyle',
307
- message: `Choose what to create `,
308
294
  type: 'autocomplete',
295
+ name: 'workspaceType',
296
+ message: `Package-based or integrated?`,
297
+ initial: 'package-based',
309
298
  choices: [
310
299
  {
311
300
  name: 'package-based',
312
- message: 'Package-based monorepo: Nx makes it fast, but lets you run things your way.',
301
+ message: 'Package-based: Nx makes it fast, but lets you run things your way.',
313
302
  },
314
303
  {
315
304
  name: 'integrated',
316
- message: 'Integrated monorepo: Nx configures your favorite frameworks and lets you focus on shipping features.',
317
- },
318
- {
319
- name: 'react',
320
- message: 'Standalone React app: Nx configures a React app with an optional framework (e.g. Next.js).',
321
- },
322
- {
323
- name: 'angular',
324
- message: 'Standalone Angular app: Nx configures Jest, ESLint and Cypress.',
325
- },
326
- {
327
- name: 'node-standalone',
328
- message: 'Standalone Node app: Nx configures a framework (e.g. Express), esbuild, ESlint and Jest.',
305
+ message: 'Integrated: Nx creates a workspace structure most suitable for building apps.',
329
306
  },
330
307
  ],
331
308
  },
332
309
  ]);
333
- if (!a.MonorepoStyle) {
334
- output_1.output.error({
335
- title: 'Invalid monorepo style',
336
- });
337
- process.exit(1);
310
+ if (workspaceType === 'integrated') {
311
+ return {
312
+ preset: preset_1.Preset.Apps,
313
+ };
314
+ }
315
+ else {
316
+ return {
317
+ preset: preset_1.Preset.NPM,
318
+ };
338
319
  }
339
- return a.MonorepoStyle;
340
320
  });
341
321
  }
342
- function determinePreset(parsedArgs) {
322
+ function determineReactOptions(parsedArgs) {
323
+ var _a;
343
324
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
325
+ let preset;
326
+ let style = undefined;
327
+ let appName;
328
+ let bundler = undefined;
329
+ let nextAppDir = false;
344
330
  if (parsedArgs.preset) {
345
- if (Object.values(preset_1.Preset).indexOf(parsedArgs.preset) === -1) {
346
- output_1.output.error({
347
- title: 'Invalid preset',
348
- bodyLines: [
349
- `It must be one of the following:`,
350
- '',
351
- ...Object.values(preset_1.Preset),
352
- ],
353
- });
354
- process.exit(1);
331
+ preset = parsedArgs.preset;
332
+ if (preset === preset_1.Preset.ReactStandalone ||
333
+ preset === preset_1.Preset.NextJsStandalone) {
334
+ appName = (_a = parsedArgs.appName) !== null && _a !== void 0 ? _a : parsedArgs.name;
355
335
  }
356
336
  else {
357
- return Promise.resolve(parsedArgs.preset);
337
+ appName = yield determineAppName(parsedArgs);
358
338
  }
359
339
  }
360
- return enquirer
361
- .prompt([
362
- {
363
- name: 'preset',
364
- message: `What to create in the new workspace `,
365
- initial: 'empty',
366
- type: 'autocomplete',
367
- choices: preset_options_1.presetOptions,
368
- },
369
- ])
370
- .then((a) => a.preset);
371
- });
372
- }
373
- function determineAppName(preset, parsedArgs) {
374
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
375
- if (preset === preset_1.Preset.Apps ||
376
- preset === preset_1.Preset.Core ||
377
- preset === preset_1.Preset.TS ||
378
- preset === preset_1.Preset.Empty ||
379
- preset === preset_1.Preset.NPM) {
380
- return Promise.resolve('');
340
+ else {
341
+ const framework = yield determineReactFramework(parsedArgs);
342
+ // React Native and Expo only support integrated monorepos for now.
343
+ // TODO(jack): Add standalone support for React Native and Expo.
344
+ const workspaceType = framework === 'react-native' || framework === 'expo'
345
+ ? 'integrated'
346
+ : yield determineStandAloneOrMonorepo();
347
+ if (workspaceType === 'standalone') {
348
+ appName = parsedArgs.name;
349
+ }
350
+ else {
351
+ appName = yield determineAppName(parsedArgs);
352
+ }
353
+ if (framework === 'nextjs') {
354
+ if (workspaceType === 'standalone') {
355
+ preset = preset_1.Preset.NextJsStandalone;
356
+ }
357
+ else {
358
+ preset = preset_1.Preset.NextJs;
359
+ }
360
+ }
361
+ else if (framework === 'react-native') {
362
+ preset = preset_1.Preset.ReactNative;
363
+ }
364
+ else if (framework === 'expo') {
365
+ preset = preset_1.Preset.Expo;
366
+ }
367
+ else {
368
+ if (workspaceType === 'standalone') {
369
+ preset = preset_1.Preset.ReactStandalone;
370
+ }
371
+ else {
372
+ preset = preset_1.Preset.ReactMonorepo;
373
+ }
374
+ }
381
375
  }
382
- if (parsedArgs.appName) {
383
- return Promise.resolve(parsedArgs.appName);
376
+ if (preset === preset_1.Preset.ReactStandalone || preset === preset_1.Preset.ReactMonorepo) {
377
+ bundler = yield determineReactBundler(parsedArgs);
384
378
  }
385
- return enquirer
386
- .prompt([
387
- {
388
- name: 'AppName',
389
- message: `Application name `,
390
- type: 'input',
391
- },
392
- ])
393
- .then((a) => {
394
- if (!a.AppName) {
395
- output_1.output.error({
396
- title: 'Invalid name',
397
- bodyLines: [`Name cannot be empty`],
398
- });
399
- process.exit(1);
400
- }
401
- return a.AppName;
402
- });
379
+ else if (preset === preset_1.Preset.NextJs || preset === preset_1.Preset.NextJsStandalone) {
380
+ nextAppDir = yield determineNextAppDir(parsedArgs);
381
+ }
382
+ if (parsedArgs.style) {
383
+ style = parsedArgs.style;
384
+ }
385
+ else if (preset === preset_1.Preset.ReactStandalone ||
386
+ preset === preset_1.Preset.ReactMonorepo ||
387
+ preset === preset_1.Preset.NextJs ||
388
+ preset === preset_1.Preset.NextJsStandalone) {
389
+ const reply = yield enquirer.prompt([
390
+ {
391
+ name: 'style',
392
+ message: `Default stylesheet format `,
393
+ initial: 'css',
394
+ type: 'autocomplete',
395
+ choices: [
396
+ {
397
+ name: 'css',
398
+ message: 'CSS',
399
+ },
400
+ {
401
+ name: 'scss',
402
+ message: 'SASS(.scss) [ http://sass-lang.com ]',
403
+ },
404
+ {
405
+ name: 'less',
406
+ message: 'LESS [ http://lesscss.org ]',
407
+ },
408
+ {
409
+ name: 'styled-components',
410
+ message: 'styled-components [ https://styled-components.com ]',
411
+ },
412
+ {
413
+ name: '@emotion/styled',
414
+ message: 'emotion [ https://emotion.sh ]',
415
+ },
416
+ {
417
+ name: 'styled-jsx',
418
+ message: 'styled-jsx [ https://www.npmjs.com/package/styled-jsx ]',
419
+ },
420
+ ],
421
+ },
422
+ ]);
423
+ style = reply.style;
424
+ }
425
+ return { preset, style, appName, bundler, nextAppDir };
403
426
  });
404
427
  }
405
- function determineFramework(parsedArgs) {
428
+ function determineAngularOptions(parsedArgs) {
406
429
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
407
- const frameworkChoices = [
408
- {
409
- name: 'express',
410
- message: 'Express [https://expressjs.com/]',
411
- },
412
- {
413
- name: 'fastify',
414
- message: 'Fastify [https://www.fastify.io/]',
415
- },
416
- {
417
- name: 'koa',
418
- message: 'Koa [https://koajs.com/]',
419
- },
420
- {
421
- name: 'nest',
422
- message: 'NestJs [https://nestjs.com/]',
423
- },
424
- {
425
- name: 'none',
426
- message: 'None',
427
- },
428
- ];
429
- if (!parsedArgs.framework) {
430
- return enquirer
431
- .prompt([
430
+ let preset;
431
+ let style;
432
+ let appName;
433
+ let standaloneApi;
434
+ let routing;
435
+ if (parsedArgs.preset) {
436
+ preset = parsedArgs.preset;
437
+ if (preset === preset_1.Preset.AngularStandalone) {
438
+ appName = parsedArgs.name;
439
+ }
440
+ else {
441
+ appName = yield determineAppName(parsedArgs);
442
+ }
443
+ }
444
+ else {
445
+ const workspaceType = yield determineStandAloneOrMonorepo();
446
+ if (workspaceType === 'standalone') {
447
+ preset = preset_1.Preset.AngularStandalone;
448
+ appName = parsedArgs.name;
449
+ }
450
+ else {
451
+ preset = preset_1.Preset.AngularMonorepo;
452
+ appName = yield determineAppName(parsedArgs);
453
+ }
454
+ }
455
+ if (parsedArgs.style) {
456
+ style = parsedArgs.style;
457
+ }
458
+ else {
459
+ const reply = yield enquirer.prompt([
432
460
  {
433
- message: 'What framework should be used?',
461
+ name: 'style',
462
+ message: `Default stylesheet format `,
463
+ initial: 'css',
434
464
  type: 'autocomplete',
435
- name: 'framework',
436
- choices: frameworkChoices,
465
+ choices: [
466
+ {
467
+ name: 'css',
468
+ message: 'CSS',
469
+ },
470
+ {
471
+ name: 'scss',
472
+ message: 'SASS(.scss) [ http://sass-lang.com ]',
473
+ },
474
+ {
475
+ name: 'less',
476
+ message: 'LESS [ http://lesscss.org ]',
477
+ },
478
+ ],
437
479
  },
438
- ])
439
- .then((a) => a.framework);
480
+ ]);
481
+ style = reply.style;
440
482
  }
441
- const foundFramework = frameworkChoices
442
- .map(({ name }) => name)
443
- .indexOf(parsedArgs.framework);
444
- if (foundFramework < 0) {
445
- output_1.output.error({
446
- title: 'Invalid framework',
447
- bodyLines: [
448
- `It must be one of the following:`,
449
- '',
450
- ...frameworkChoices.map(({ name }) => name),
451
- ],
452
- });
453
- process.exit(1);
483
+ if (parsedArgs.standaloneApi !== undefined) {
484
+ standaloneApi = parsedArgs.standaloneApi;
454
485
  }
455
- return Promise.resolve(parsedArgs.framework);
456
- });
457
- }
458
- function determineStandaloneApi(parsedArgs) {
459
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
460
- if (parsedArgs.standaloneApi === undefined) {
461
- return enquirer
462
- .prompt([
486
+ else {
487
+ const reply = yield enquirer.prompt([
463
488
  {
464
489
  name: 'standaloneApi',
465
490
  message: 'Would you like to use Standalone Components in your application?',
466
491
  type: 'autocomplete',
492
+ choices: [
493
+ {
494
+ name: 'No',
495
+ },
496
+ {
497
+ name: 'Yes',
498
+ },
499
+ ],
500
+ initial: 'No',
501
+ },
502
+ ]);
503
+ standaloneApi = reply.standaloneApi === 'Yes';
504
+ }
505
+ if (parsedArgs.routing !== undefined) {
506
+ routing = parsedArgs.routing;
507
+ }
508
+ else {
509
+ const reply = yield enquirer.prompt([
510
+ {
511
+ name: 'routing',
512
+ message: 'Would you like to add routing?',
513
+ type: 'autocomplete',
467
514
  choices: [
468
515
  {
469
516
  name: 'Yes',
@@ -472,19 +519,55 @@ function determineStandaloneApi(parsedArgs) {
472
519
  name: 'No',
473
520
  },
474
521
  ],
475
- initial: 'No',
522
+ initial: 'Yes',
476
523
  },
477
- ])
478
- .then((a) => a.standaloneApi === 'Yes');
524
+ ]);
525
+ routing = reply.routing === 'Yes';
479
526
  }
480
- return parsedArgs.standaloneApi;
527
+ return { preset, style, appName, standaloneApi, routing };
481
528
  });
482
529
  }
483
- function determineDockerfile(parsedArgs) {
530
+ function determineNodeOptions(parsedArgs) {
484
531
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
485
- if (parsedArgs.docker === undefined) {
486
- return enquirer
487
- .prompt([
532
+ let preset;
533
+ let appName;
534
+ let framework;
535
+ let docker;
536
+ if (parsedArgs.preset) {
537
+ preset = parsedArgs.preset;
538
+ if (preset === preset_1.Preset.Nest ||
539
+ preset === preset_1.Preset.Express ||
540
+ preset === preset_1.Preset.NodeMonorepo) {
541
+ appName = yield determineAppName(parsedArgs);
542
+ }
543
+ else {
544
+ appName = parsedArgs.name;
545
+ }
546
+ if (preset === preset_1.Preset.NodeStandalone || preset === preset_1.Preset.NodeMonorepo) {
547
+ framework = yield determineNodeFramework(parsedArgs);
548
+ }
549
+ else {
550
+ framework = 'none';
551
+ }
552
+ }
553
+ else {
554
+ framework = yield determineNodeFramework(parsedArgs);
555
+ const workspaceType = yield determineStandAloneOrMonorepo();
556
+ if (workspaceType === 'standalone') {
557
+ preset = preset_1.Preset.NodeStandalone;
558
+ appName = yield determineAppName(parsedArgs);
559
+ appName = parsedArgs.name;
560
+ }
561
+ else {
562
+ preset = preset_1.Preset.NodeMonorepo;
563
+ appName = yield determineAppName(parsedArgs);
564
+ }
565
+ }
566
+ if (parsedArgs.docker !== undefined) {
567
+ docker = parsedArgs.docker;
568
+ }
569
+ else {
570
+ const reply = yield enquirer.prompt([
488
571
  {
489
572
  name: 'docker',
490
573
  message: 'Would you like to generate a Dockerfile? [https://docs.docker.com/]',
@@ -500,23 +583,68 @@ function determineDockerfile(parsedArgs) {
500
583
  ],
501
584
  initial: 'No',
502
585
  },
503
- ])
504
- .then((a) => a.docker === 'Yes');
505
- }
506
- else {
507
- return Promise.resolve(parsedArgs.docker);
586
+ ]);
587
+ docker = reply.docker === 'Yes';
508
588
  }
589
+ return {
590
+ preset,
591
+ appName,
592
+ framework,
593
+ docker,
594
+ };
595
+ });
596
+ }
597
+ function determineStandAloneOrMonorepo() {
598
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
599
+ const { workspaceType } = yield enquirer.prompt([
600
+ {
601
+ type: 'autocomplete',
602
+ name: 'workspaceType',
603
+ message: `Standalone project or integrated monorepo?`,
604
+ initial: 'standalone',
605
+ choices: [
606
+ {
607
+ name: 'standalone',
608
+ message: 'Standalone: Nx creates a single project and makes it fast.',
609
+ },
610
+ {
611
+ name: 'integrated',
612
+ message: 'Integrated Monorepo: Nx creates a monorepo that contains multiple projects.',
613
+ },
614
+ ],
615
+ },
616
+ ]);
617
+ invariant(workspaceType, {
618
+ title: 'Invalid workspace type',
619
+ bodyLines: [
620
+ `It must be one of the following: standalone, integrated. Got ${workspaceType}`,
621
+ ],
622
+ });
623
+ return workspaceType;
624
+ });
625
+ }
626
+ function determineAppName(parsedArgs) {
627
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
628
+ if (parsedArgs.appName)
629
+ return parsedArgs.appName;
630
+ const { appName } = yield enquirer.prompt([
631
+ {
632
+ name: 'appName',
633
+ message: `Application name`,
634
+ type: 'input',
635
+ initial: parsedArgs.name,
636
+ },
637
+ ]);
638
+ invariant(appName, {
639
+ title: 'Invalid name',
640
+ bodyLines: [`Name cannot be empty`],
641
+ });
642
+ return appName;
509
643
  });
510
644
  }
511
645
  function determineReactFramework(parsedArgs) {
512
646
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
513
- if (parsedArgs.framework) {
514
- return parsedArgs.framework === 'next.js'
515
- ? preset_1.Preset.NextJsStandalone
516
- : preset_1.Preset.ReactStandalone;
517
- }
518
- return enquirer
519
- .prompt([
647
+ const reply = yield enquirer.prompt([
520
648
  {
521
649
  name: 'framework',
522
650
  message: 'What framework would you like to use?',
@@ -525,188 +653,112 @@ function determineReactFramework(parsedArgs) {
525
653
  {
526
654
  name: 'none',
527
655
  message: 'None',
528
- hint: 'I only want React',
656
+ hint: ' I only want react and react-dom',
657
+ },
658
+ {
659
+ name: 'nextjs',
660
+ message: 'Next.js [ https://nextjs.org/ ]',
529
661
  },
530
662
  {
531
- name: 'next.js',
532
- message: 'Next.js [https://nextjs.org/]',
663
+ name: 'expo',
664
+ message: 'Expo [ https://expo.io/ ]',
665
+ },
666
+ {
667
+ name: 'react-native',
668
+ message: 'React Native [ https://reactnative.dev/ ]',
533
669
  },
534
670
  ],
535
671
  initial: 'none',
536
672
  },
537
- ])
538
- .then((choice) => choice.framework === 'next.js'
539
- ? preset_1.Preset.NextJsStandalone
540
- : preset_1.Preset.ReactStandalone);
541
- });
542
- }
543
- function isNextAppDir(parsedArgs) {
544
- return tslib_1.__awaiter(this, void 0, void 0, function* () {
545
- if (parsedArgs.nextAppDir === undefined) {
546
- return enquirer
547
- .prompt([
548
- {
549
- name: 'appDir',
550
- message: 'Would you like to use the App Router (recommended)?',
551
- type: 'autocomplete',
552
- choices: [
553
- {
554
- name: 'No',
555
- },
556
- {
557
- name: 'Yes',
558
- },
559
- ],
560
- initial: 'Yes',
561
- },
562
- ])
563
- .then((choice) => choice.appDir === 'Yes');
564
- }
565
- else {
566
- return Promise.resolve(parsedArgs.nextAppDir);
567
- }
673
+ ]);
674
+ return reply.framework;
568
675
  });
569
676
  }
570
- function determineStyle(preset, parsedArgs) {
677
+ function determineReactBundler(parsedArgs) {
571
678
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
572
- if (preset === preset_1.Preset.Apps ||
573
- preset === preset_1.Preset.Core ||
574
- preset === preset_1.Preset.TS ||
575
- preset === preset_1.Preset.Empty ||
576
- preset === preset_1.Preset.NPM ||
577
- preset === preset_1.Preset.Nest ||
578
- preset === preset_1.Preset.Express ||
579
- preset === preset_1.Preset.ReactNative ||
580
- preset === preset_1.Preset.Expo ||
581
- preset === preset_1.Preset.NodeStandalone) {
582
- return Promise.resolve(null);
583
- }
584
- const choices = [
679
+ if (parsedArgs.bundler)
680
+ return parsedArgs.bundler;
681
+ const reply = yield enquirer.prompt([
585
682
  {
586
- name: 'css',
587
- message: 'CSS',
588
- },
589
- {
590
- name: 'scss',
591
- message: 'SASS(.scss) [ http://sass-lang.com ]',
592
- },
593
- {
594
- name: 'less',
595
- message: 'LESS [ http://lesscss.org ]',
596
- },
597
- ];
598
- if ([
599
- preset_1.Preset.ReactMonorepo,
600
- preset_1.Preset.ReactStandalone,
601
- preset_1.Preset.NextJs,
602
- preset_1.Preset.NextJsStandalone,
603
- ].includes(preset)) {
604
- choices.push({
605
- name: 'styled-components',
606
- message: 'styled-components [ https://styled-components.com ]',
607
- }, {
608
- name: '@emotion/styled',
609
- message: 'emotion [ https://emotion.sh ]',
610
- }, {
611
- name: 'styled-jsx',
612
- message: 'styled-jsx [ https://www.npmjs.com/package/styled-jsx ]',
613
- });
614
- }
615
- if (!parsedArgs.style) {
616
- return enquirer
617
- .prompt([
618
- {
619
- name: 'style',
620
- message: `Default stylesheet format `,
621
- initial: 'css',
622
- type: 'autocomplete',
623
- choices: choices,
624
- },
625
- ])
626
- .then((a) => a.style);
627
- }
628
- const foundStyle = choices.find((choice) => choice.name === parsedArgs.style);
629
- if (foundStyle === undefined) {
630
- output_1.output.error({
631
- title: 'Invalid style',
632
- bodyLines: [
633
- `It must be one of the following:`,
634
- '',
635
- ...choices.map((choice) => choice.name),
683
+ name: 'bundler',
684
+ message: `Which bundler would you like to use?`,
685
+ type: 'autocomplete',
686
+ choices: [
687
+ {
688
+ name: 'vite',
689
+ message: 'Vite [ https://vitejs.dev/ ]',
690
+ },
691
+ {
692
+ name: 'webpack',
693
+ message: 'Webpack [ https://webpack.js.org/ ]',
694
+ },
695
+ {
696
+ name: 'rspack',
697
+ message: 'Rspack [ https://www.rspack.dev/ ]',
698
+ },
636
699
  ],
637
- });
638
- process.exit(1);
639
- }
640
- return Promise.resolve(parsedArgs.style);
700
+ },
701
+ ]);
702
+ return reply.bundler;
641
703
  });
642
704
  }
643
- function determineRouting(parsedArgs) {
705
+ function determineNextAppDir(parsedArgs) {
644
706
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
645
- if (!parsedArgs.routing) {
646
- return enquirer
647
- .prompt([
648
- {
649
- name: 'routing',
650
- message: 'Would you like to add routing?',
651
- type: 'autocomplete',
652
- choices: [
653
- {
654
- name: 'Yes',
655
- },
656
- {
657
- name: 'No',
658
- },
659
- ],
660
- initial: 'Yes',
661
- },
662
- ])
663
- .then((a) => a.routing === 'Yes');
664
- }
665
- return parsedArgs.routing;
707
+ if (parsedArgs.nextAppDir !== undefined)
708
+ return parsedArgs.nextAppDir;
709
+ const reply = yield enquirer.prompt([
710
+ {
711
+ name: 'nextAppDir',
712
+ message: 'Would you like to use the App Router (recommended)?',
713
+ type: 'autocomplete',
714
+ choices: [
715
+ {
716
+ name: 'Yes',
717
+ },
718
+ {
719
+ name: 'No',
720
+ },
721
+ ],
722
+ initial: 'Yes',
723
+ },
724
+ ]);
725
+ return reply.nextAppDir === 'Yes';
666
726
  });
667
727
  }
668
- function determineBundler(parsedArgs) {
728
+ function determineNodeFramework(parsedArgs) {
669
729
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
670
- const choices = [
730
+ if (parsedArgs.framework)
731
+ return parsedArgs.framework;
732
+ const reply = yield enquirer.prompt([
671
733
  {
672
- name: 'vite',
673
- message: 'Vite [ https://vitejs.dev/ ]',
674
- },
675
- {
676
- name: 'webpack',
677
- message: 'Webpack [ https://webpack.js.org/ ]',
678
- },
679
- {
680
- name: 'rspack',
681
- message: 'Rspack [ https://www.rspack.dev/ ]',
682
- },
683
- ];
684
- if (!parsedArgs.bundler) {
685
- return enquirer
686
- .prompt([
687
- {
688
- name: 'bundler',
689
- message: `Bundler to be used to build the application`,
690
- initial: 'vite',
691
- type: 'autocomplete',
692
- choices: choices,
693
- },
694
- ])
695
- .then((a) => a.bundler);
696
- }
697
- const foundBundler = choices.find((choice) => choice.name === parsedArgs.bundler);
698
- if (foundBundler === undefined) {
699
- output_1.output.error({
700
- title: 'Invalid bundler',
701
- bodyLines: [
702
- `It must be one of the following:`,
703
- '',
704
- ...choices.map((choice) => choice.name),
734
+ message: 'What framework should be used?',
735
+ type: 'autocomplete',
736
+ name: 'framework',
737
+ choices: [
738
+ {
739
+ name: 'none',
740
+ message: 'None',
741
+ },
742
+ {
743
+ name: 'express',
744
+ message: 'Express [ https://expressjs.com/ ]',
745
+ },
746
+ {
747
+ name: 'fastify',
748
+ message: 'Fastify [ https://www.fastify.io/ ]',
749
+ },
750
+ {
751
+ name: 'koa',
752
+ message: 'Koa [ https://koajs.com/ ]',
753
+ },
754
+ {
755
+ name: 'nest',
756
+ message: 'NestJs [ https://nestjs.com/ ]',
757
+ },
705
758
  ],
706
- });
707
- process.exit(1);
708
- }
709
- return parsedArgs.bundler;
759
+ },
760
+ ]);
761
+ return reply.framework;
710
762
  });
711
763
  }
712
764
  //# sourceMappingURL=create-nx-workspace.js.map