create-nx-workspace 16.3.0-beta.9 → 16.3.0

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,338 @@ 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 'none';
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: `none`,
249
+ message: `None: Configures a minimal structure without specific frameworks or technologies.`,
285
250
  },
286
251
  {
287
- name: preset + '-monorepo',
288
- message: `${preset}-monorepo: a monorepo with the apps and libs folders.`,
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.`,
258
+ },
259
+ {
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
+ return stack;
267
+ });
268
+ }
269
+ function determinePresetOptions(parsedArgs) {
270
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
271
+ switch (parsedArgs.stack) {
272
+ case 'none':
273
+ return determineNoneptions(parsedArgs);
274
+ case 'react':
275
+ return determineReactOptions(parsedArgs);
276
+ case 'angular':
277
+ return determineAngularOptions(parsedArgs);
278
+ case 'node':
279
+ return determineNodeOptions(parsedArgs);
280
+ default:
281
+ return parsedArgs;
298
282
  }
299
- return a.MonorepoOrStandalone;
300
283
  });
301
284
  }
302
- function determineMonorepoStyle() {
285
+ function determineNoneptions(parsedArgs) {
303
286
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
304
- const a = yield enquirer.prompt([
287
+ if (parsedArgs.preset)
288
+ return parsedArgs;
289
+ const { workspaceType } = yield enquirer.prompt([
305
290
  {
306
- name: 'MonorepoStyle',
307
- message: `Choose what to create `,
308
291
  type: 'autocomplete',
292
+ name: 'workspaceType',
293
+ message: `Package-based or integrated?`,
294
+ initial: 'package-based',
309
295
  choices: [
310
296
  {
311
297
  name: 'package-based',
312
- message: 'Package-based monorepo: Nx makes it fast, but lets you run things your way.',
298
+ message: 'Package-based: Nx makes it fast, but lets you run things your way.',
313
299
  },
314
300
  {
315
301
  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.',
302
+ message: 'Integrated: Nx creates a workspace structure most suitable for building apps.',
329
303
  },
330
304
  ],
331
305
  },
332
306
  ]);
333
- if (!a.MonorepoStyle) {
334
- output_1.output.error({
335
- title: 'Invalid monorepo style',
336
- });
337
- process.exit(1);
307
+ if (workspaceType === 'integrated') {
308
+ return {
309
+ preset: preset_1.Preset.Apps,
310
+ };
311
+ }
312
+ else {
313
+ return {
314
+ preset: preset_1.Preset.NPM,
315
+ };
338
316
  }
339
- return a.MonorepoStyle;
340
317
  });
341
318
  }
342
- function determinePreset(parsedArgs) {
319
+ function determineReactOptions(parsedArgs) {
320
+ var _a;
343
321
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
322
+ let preset;
323
+ let style = undefined;
324
+ let appName;
325
+ let bundler = undefined;
326
+ let nextAppDir = false;
344
327
  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);
328
+ preset = parsedArgs.preset;
329
+ if (preset === preset_1.Preset.ReactStandalone ||
330
+ preset === preset_1.Preset.NextJsStandalone) {
331
+ appName = (_a = parsedArgs.appName) !== null && _a !== void 0 ? _a : parsedArgs.name;
355
332
  }
356
333
  else {
357
- return Promise.resolve(parsedArgs.preset);
334
+ appName = yield determineAppName(parsedArgs);
358
335
  }
359
336
  }
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('');
337
+ else {
338
+ const framework = yield determineReactFramework(parsedArgs);
339
+ // React Native and Expo only support integrated monorepos for now.
340
+ // TODO(jack): Add standalone support for React Native and Expo.
341
+ const workspaceType = framework === 'react-native' || framework === 'expo'
342
+ ? 'integrated'
343
+ : yield determineStandAloneOrMonorepo();
344
+ if (workspaceType === 'standalone') {
345
+ appName = parsedArgs.name;
346
+ }
347
+ else {
348
+ appName = yield determineAppName(parsedArgs);
349
+ }
350
+ if (framework === 'nextjs') {
351
+ if (workspaceType === 'standalone') {
352
+ preset = preset_1.Preset.NextJsStandalone;
353
+ }
354
+ else {
355
+ preset = preset_1.Preset.NextJs;
356
+ }
357
+ }
358
+ else if (framework === 'react-native') {
359
+ preset = preset_1.Preset.ReactNative;
360
+ }
361
+ else if (framework === 'expo') {
362
+ preset = preset_1.Preset.Expo;
363
+ }
364
+ else {
365
+ if (workspaceType === 'standalone') {
366
+ preset = preset_1.Preset.ReactStandalone;
367
+ }
368
+ else {
369
+ preset = preset_1.Preset.ReactMonorepo;
370
+ }
371
+ }
381
372
  }
382
- if (parsedArgs.appName) {
383
- return Promise.resolve(parsedArgs.appName);
373
+ if (preset === preset_1.Preset.ReactStandalone || preset === preset_1.Preset.ReactMonorepo) {
374
+ bundler = yield determineReactBundler(parsedArgs);
384
375
  }
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
- });
376
+ else if (preset === preset_1.Preset.NextJs || preset === preset_1.Preset.NextJsStandalone) {
377
+ nextAppDir = yield determineNextAppDir(parsedArgs);
378
+ }
379
+ if (parsedArgs.style) {
380
+ style = parsedArgs.style;
381
+ }
382
+ else if (preset === preset_1.Preset.ReactStandalone ||
383
+ preset === preset_1.Preset.ReactMonorepo ||
384
+ preset === preset_1.Preset.NextJs ||
385
+ preset === preset_1.Preset.NextJsStandalone) {
386
+ const reply = yield enquirer.prompt([
387
+ {
388
+ name: 'style',
389
+ message: `Default stylesheet format`,
390
+ initial: 'css',
391
+ type: 'autocomplete',
392
+ choices: [
393
+ {
394
+ name: 'css',
395
+ message: 'CSS',
396
+ },
397
+ {
398
+ name: 'scss',
399
+ message: 'SASS(.scss) [ http://sass-lang.com ]',
400
+ },
401
+ {
402
+ name: 'less',
403
+ message: 'LESS [ http://lesscss.org ]',
404
+ },
405
+ {
406
+ name: 'styled-components',
407
+ message: 'styled-components [ https://styled-components.com ]',
408
+ },
409
+ {
410
+ name: '@emotion/styled',
411
+ message: 'emotion [ https://emotion.sh ]',
412
+ },
413
+ {
414
+ name: 'styled-jsx',
415
+ message: 'styled-jsx [ https://www.npmjs.com/package/styled-jsx ]',
416
+ },
417
+ ],
418
+ },
419
+ ]);
420
+ style = reply.style;
421
+ }
422
+ return { preset, style, appName, bundler, nextAppDir };
403
423
  });
404
424
  }
405
- function determineFramework(parsedArgs) {
425
+ function determineAngularOptions(parsedArgs) {
406
426
  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([
427
+ let preset;
428
+ let style;
429
+ let appName;
430
+ let standaloneApi;
431
+ let routing;
432
+ if (parsedArgs.preset) {
433
+ preset = parsedArgs.preset;
434
+ if (preset === preset_1.Preset.AngularStandalone) {
435
+ appName = parsedArgs.name;
436
+ }
437
+ else {
438
+ appName = yield determineAppName(parsedArgs);
439
+ }
440
+ }
441
+ else {
442
+ const workspaceType = yield determineStandAloneOrMonorepo();
443
+ if (workspaceType === 'standalone') {
444
+ preset = preset_1.Preset.AngularStandalone;
445
+ appName = parsedArgs.name;
446
+ }
447
+ else {
448
+ preset = preset_1.Preset.AngularMonorepo;
449
+ appName = yield determineAppName(parsedArgs);
450
+ }
451
+ }
452
+ if (parsedArgs.style) {
453
+ style = parsedArgs.style;
454
+ }
455
+ else {
456
+ const reply = yield enquirer.prompt([
432
457
  {
433
- message: 'What framework should be used?',
458
+ name: 'style',
459
+ message: `Default stylesheet format`,
460
+ initial: 'css',
434
461
  type: 'autocomplete',
435
- name: 'framework',
436
- choices: frameworkChoices,
462
+ choices: [
463
+ {
464
+ name: 'css',
465
+ message: 'CSS',
466
+ },
467
+ {
468
+ name: 'scss',
469
+ message: 'SASS(.scss) [ http://sass-lang.com ]',
470
+ },
471
+ {
472
+ name: 'less',
473
+ message: 'LESS [ http://lesscss.org ]',
474
+ },
475
+ ],
437
476
  },
438
- ])
439
- .then((a) => a.framework);
477
+ ]);
478
+ style = reply.style;
440
479
  }
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);
480
+ if (parsedArgs.standaloneApi !== undefined) {
481
+ standaloneApi = parsedArgs.standaloneApi;
454
482
  }
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([
483
+ else {
484
+ const reply = yield enquirer.prompt([
463
485
  {
464
486
  name: 'standaloneApi',
465
487
  message: 'Would you like to use Standalone Components in your application?',
466
488
  type: 'autocomplete',
489
+ choices: [
490
+ {
491
+ name: 'No',
492
+ },
493
+ {
494
+ name: 'Yes',
495
+ },
496
+ ],
497
+ initial: 'No',
498
+ },
499
+ ]);
500
+ standaloneApi = reply.standaloneApi === 'Yes';
501
+ }
502
+ if (parsedArgs.routing !== undefined) {
503
+ routing = parsedArgs.routing;
504
+ }
505
+ else {
506
+ const reply = yield enquirer.prompt([
507
+ {
508
+ name: 'routing',
509
+ message: 'Would you like to add routing?',
510
+ type: 'autocomplete',
467
511
  choices: [
468
512
  {
469
513
  name: 'Yes',
@@ -472,19 +516,54 @@ function determineStandaloneApi(parsedArgs) {
472
516
  name: 'No',
473
517
  },
474
518
  ],
475
- initial: 'No',
519
+ initial: 'Yes',
476
520
  },
477
- ])
478
- .then((a) => a.standaloneApi === 'Yes');
521
+ ]);
522
+ routing = reply.routing === 'Yes';
479
523
  }
480
- return parsedArgs.standaloneApi;
524
+ return { preset, style, appName, standaloneApi, routing };
481
525
  });
482
526
  }
483
- function determineDockerfile(parsedArgs) {
527
+ function determineNodeOptions(parsedArgs) {
484
528
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
485
- if (parsedArgs.docker === undefined) {
486
- return enquirer
487
- .prompt([
529
+ let preset;
530
+ let appName;
531
+ let framework;
532
+ let docker;
533
+ if (parsedArgs.preset) {
534
+ preset = parsedArgs.preset;
535
+ if (preset === preset_1.Preset.Nest ||
536
+ preset === preset_1.Preset.Express ||
537
+ preset === preset_1.Preset.NodeMonorepo) {
538
+ appName = yield determineAppName(parsedArgs);
539
+ }
540
+ else {
541
+ appName = parsedArgs.name;
542
+ }
543
+ if (preset === preset_1.Preset.NodeStandalone || preset === preset_1.Preset.NodeMonorepo) {
544
+ framework = yield determineNodeFramework(parsedArgs);
545
+ }
546
+ else {
547
+ framework = 'none';
548
+ }
549
+ }
550
+ else {
551
+ framework = yield determineNodeFramework(parsedArgs);
552
+ const workspaceType = yield determineStandAloneOrMonorepo();
553
+ if (workspaceType === 'standalone') {
554
+ preset = preset_1.Preset.NodeStandalone;
555
+ appName = parsedArgs.name;
556
+ }
557
+ else {
558
+ preset = preset_1.Preset.NodeMonorepo;
559
+ appName = yield determineAppName(parsedArgs);
560
+ }
561
+ }
562
+ if (parsedArgs.docker !== undefined) {
563
+ docker = parsedArgs.docker;
564
+ }
565
+ else {
566
+ const reply = yield enquirer.prompt([
488
567
  {
489
568
  name: 'docker',
490
569
  message: 'Would you like to generate a Dockerfile? [https://docs.docker.com/]',
@@ -500,23 +579,68 @@ function determineDockerfile(parsedArgs) {
500
579
  ],
501
580
  initial: 'No',
502
581
  },
503
- ])
504
- .then((a) => a.docker === 'Yes');
505
- }
506
- else {
507
- return Promise.resolve(parsedArgs.docker);
582
+ ]);
583
+ docker = reply.docker === 'Yes';
508
584
  }
585
+ return {
586
+ preset,
587
+ appName,
588
+ framework,
589
+ docker,
590
+ };
591
+ });
592
+ }
593
+ function determineStandAloneOrMonorepo() {
594
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
595
+ const { workspaceType } = yield enquirer.prompt([
596
+ {
597
+ type: 'autocomplete',
598
+ name: 'workspaceType',
599
+ message: `Standalone project or integrated monorepo?`,
600
+ initial: 'standalone',
601
+ choices: [
602
+ {
603
+ name: 'standalone',
604
+ message: 'Standalone: Nx creates a single project and makes it fast.',
605
+ },
606
+ {
607
+ name: 'integrated',
608
+ message: 'Integrated Monorepo: Nx creates a monorepo that contains multiple projects.',
609
+ },
610
+ ],
611
+ },
612
+ ]);
613
+ invariant(workspaceType, {
614
+ title: 'Invalid workspace type',
615
+ bodyLines: [
616
+ `It must be one of the following: standalone, integrated. Got ${workspaceType}`,
617
+ ],
618
+ });
619
+ return workspaceType;
620
+ });
621
+ }
622
+ function determineAppName(parsedArgs) {
623
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
624
+ if (parsedArgs.appName)
625
+ return parsedArgs.appName;
626
+ const { appName } = yield enquirer.prompt([
627
+ {
628
+ name: 'appName',
629
+ message: `Application name`,
630
+ type: 'input',
631
+ initial: parsedArgs.name,
632
+ },
633
+ ]);
634
+ invariant(appName, {
635
+ title: 'Invalid name',
636
+ bodyLines: [`Name cannot be empty`],
637
+ });
638
+ return appName;
509
639
  });
510
640
  }
511
641
  function determineReactFramework(parsedArgs) {
512
642
  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([
643
+ const reply = yield enquirer.prompt([
520
644
  {
521
645
  name: 'framework',
522
646
  message: 'What framework would you like to use?',
@@ -525,188 +649,112 @@ function determineReactFramework(parsedArgs) {
525
649
  {
526
650
  name: 'none',
527
651
  message: 'None',
528
- hint: 'I only want React',
652
+ hint: ' I only want react and react-dom',
653
+ },
654
+ {
655
+ name: 'nextjs',
656
+ message: 'Next.js [ https://nextjs.org/ ]',
529
657
  },
530
658
  {
531
- name: 'next.js',
532
- message: 'Next.js [https://nextjs.org/]',
659
+ name: 'expo',
660
+ message: 'Expo [ https://expo.io/ ]',
661
+ },
662
+ {
663
+ name: 'react-native',
664
+ message: 'React Native [ https://reactnative.dev/ ]',
533
665
  },
534
666
  ],
535
667
  initial: 'none',
536
668
  },
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
- }
669
+ ]);
670
+ return reply.framework;
568
671
  });
569
672
  }
570
- function determineStyle(preset, parsedArgs) {
673
+ function determineReactBundler(parsedArgs) {
571
674
  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 = [
675
+ if (parsedArgs.bundler)
676
+ return parsedArgs.bundler;
677
+ const reply = yield enquirer.prompt([
585
678
  {
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),
679
+ name: 'bundler',
680
+ message: `Which bundler would you like to use?`,
681
+ type: 'autocomplete',
682
+ choices: [
683
+ {
684
+ name: 'vite',
685
+ message: 'Vite [ https://vitejs.dev/ ]',
686
+ },
687
+ {
688
+ name: 'webpack',
689
+ message: 'Webpack [ https://webpack.js.org/ ]',
690
+ },
691
+ {
692
+ name: 'rspack',
693
+ message: 'Rspack [ https://www.rspack.dev/ ]',
694
+ },
636
695
  ],
637
- });
638
- process.exit(1);
639
- }
640
- return Promise.resolve(parsedArgs.style);
696
+ },
697
+ ]);
698
+ return reply.bundler;
641
699
  });
642
700
  }
643
- function determineRouting(parsedArgs) {
701
+ function determineNextAppDir(parsedArgs) {
644
702
  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;
703
+ if (parsedArgs.nextAppDir !== undefined)
704
+ return parsedArgs.nextAppDir;
705
+ const reply = yield enquirer.prompt([
706
+ {
707
+ name: 'nextAppDir',
708
+ message: 'Would you like to use the App Router (recommended)?',
709
+ type: 'autocomplete',
710
+ choices: [
711
+ {
712
+ name: 'Yes',
713
+ },
714
+ {
715
+ name: 'No',
716
+ },
717
+ ],
718
+ initial: 'Yes',
719
+ },
720
+ ]);
721
+ return reply.nextAppDir === 'Yes';
666
722
  });
667
723
  }
668
- function determineBundler(parsedArgs) {
724
+ function determineNodeFramework(parsedArgs) {
669
725
  return tslib_1.__awaiter(this, void 0, void 0, function* () {
670
- const choices = [
671
- {
672
- name: 'vite',
673
- message: 'Vite [ https://vitejs.dev/ ]',
674
- },
675
- {
676
- name: 'webpack',
677
- message: 'Webpack [ https://webpack.js.org/ ]',
678
- },
726
+ if (parsedArgs.framework)
727
+ return parsedArgs.framework;
728
+ const reply = yield enquirer.prompt([
679
729
  {
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),
730
+ message: 'What framework should be used?',
731
+ type: 'autocomplete',
732
+ name: 'framework',
733
+ choices: [
734
+ {
735
+ name: 'none',
736
+ message: 'None',
737
+ },
738
+ {
739
+ name: 'express',
740
+ message: 'Express [ https://expressjs.com/ ]',
741
+ },
742
+ {
743
+ name: 'fastify',
744
+ message: 'Fastify [ https://www.fastify.io/ ]',
745
+ },
746
+ {
747
+ name: 'koa',
748
+ message: 'Koa [ https://koajs.com/ ]',
749
+ },
750
+ {
751
+ name: 'nest',
752
+ message: 'NestJs [ https://nestjs.com/ ]',
753
+ },
705
754
  ],
706
- });
707
- process.exit(1);
708
- }
709
- return parsedArgs.bundler;
755
+ },
756
+ ]);
757
+ return reply.framework;
710
758
  });
711
759
  }
712
760
  //# sourceMappingURL=create-nx-workspace.js.map