create-nx-workspace 22.7.0-beta.0 → 22.7.0-beta.10
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.
- package/assets.json +15 -0
- package/bin/create-nx-workspace.d.ts +15 -1
- package/bin/create-nx-workspace.d.ts.map +1 -1
- package/bin/create-nx-workspace.js +116 -68
- package/bin/decorator.js +12 -11
- package/package.json +4 -6
- package/project.json +6 -41
- package/src/create-empty-workspace.d.ts.map +1 -1
- package/src/create-empty-workspace.js +7 -4
- package/src/create-preset.d.ts.map +1 -1
- package/src/create-preset.js +2 -2
- package/src/create-sandbox.js +3 -2
- package/src/create-workspace-options.d.ts +6 -0
- package/src/create-workspace-options.d.ts.map +1 -1
- package/src/create-workspace.d.ts +2 -0
- package/src/create-workspace.d.ts.map +1 -1
- package/src/create-workspace.js +37 -4
- package/src/internal-utils/prompts.d.ts +1 -1
- package/src/internal-utils/prompts.d.ts.map +1 -1
- package/src/internal-utils/prompts.js +14 -13
- package/src/utils/child-process-utils.d.ts +2 -2
- package/src/utils/child-process-utils.d.ts.map +1 -1
- package/src/utils/child-process-utils.js +20 -5
- package/src/utils/ci/setup-ci.js +3 -2
- package/src/utils/error-utils.d.ts +1 -1
- package/src/utils/error-utils.d.ts.map +1 -1
- package/src/utils/git/default-base.js +1 -1
- package/src/utils/git/git.d.ts +4 -4
- package/src/utils/git/git.d.ts.map +1 -1
- package/src/utils/git/git.js +82 -44
- package/src/utils/nx/ab-testing.d.ts +0 -1
- package/src/utils/nx/ab-testing.d.ts.map +1 -1
- package/src/utils/nx/ab-testing.js +35 -11
- package/src/utils/nx/nx-cloud.d.ts +1 -0
- package/src/utils/nx/nx-cloud.d.ts.map +1 -1
- package/src/utils/nx/nx-cloud.js +17 -2
- package/src/utils/output.d.ts +1 -1
- package/src/utils/output.d.ts.map +1 -1
- package/src/utils/output.js +20 -19
- package/src/utils/package-manager.js +1 -1
- package/src/utils/template/clone-template.d.ts +1 -1
- package/src/utils/template/clone-template.d.ts.map +1 -1
- package/src/utils/template/clone-template.js +2 -2
package/assets.json
ADDED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import yargs from 'yargs';
|
|
2
2
|
import { CreateWorkspaceOptions } from '../src/create-workspace-options';
|
|
3
3
|
import { Preset } from '../src/utils/preset/preset';
|
|
4
4
|
type AngularUnitTestRunner = 'none' | 'jest' | 'vitest-angular' | 'vitest-analog';
|
|
@@ -66,5 +66,19 @@ interface UnknownStackArguments extends BaseArguments {
|
|
|
66
66
|
type Arguments = NoneArguments | ReactArguments | AngularArguments | VueArguments | NodeArguments | UnknownStackArguments;
|
|
67
67
|
export declare const commandsObject: yargs.Argv<Arguments>;
|
|
68
68
|
export declare function validateWorkspaceName(name: string): void;
|
|
69
|
+
/**
|
|
70
|
+
* Resolves special folder name patterns (`.`, `./`, absolute paths) into a
|
|
71
|
+
* workspace name and a `workingDir` override so that downstream functions
|
|
72
|
+
* create the workspace at the intended location.
|
|
73
|
+
*
|
|
74
|
+
* @visibleForTesting
|
|
75
|
+
*
|
|
76
|
+
* Returns `{ name, workingDir }` for special inputs, or `null` if the
|
|
77
|
+
* input is a regular name that needs no special handling.
|
|
78
|
+
*/
|
|
79
|
+
export declare function resolveSpecialFolderName(folderName: string): {
|
|
80
|
+
name: string;
|
|
81
|
+
workingDir: string;
|
|
82
|
+
} | null;
|
|
69
83
|
export {};
|
|
70
84
|
//# sourceMappingURL=create-nx-workspace.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-nx-workspace.d.ts","sourceRoot":"","sources":["../../../../packages/create-nx-workspace/bin/create-nx-workspace.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"create-nx-workspace.d.ts","sourceRoot":"","sources":["../../../../packages/create-nx-workspace/bin/create-nx-workspace.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.commandsObject = void 0;
|
|
4
4
|
exports.validateWorkspaceName = validateWorkspaceName;
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
const
|
|
5
|
+
exports.resolveSpecialFolderName = resolveSpecialFolderName;
|
|
6
|
+
const tslib_1 = require("tslib");
|
|
7
|
+
const enquirer_1 = tslib_1.__importDefault(require("enquirer"));
|
|
8
|
+
const yargs_1 = tslib_1.__importDefault(require("yargs"));
|
|
9
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
8
10
|
const create_workspace_options_1 = require("../src/create-workspace-options");
|
|
9
11
|
const create_workspace_1 = require("../src/create-workspace");
|
|
10
12
|
const preset_1 = require("../src/utils/preset/preset");
|
|
@@ -18,6 +20,7 @@ const yargs_options_1 = require("../src/internal-utils/yargs-options");
|
|
|
18
20
|
const ab_testing_1 = require("../src/utils/nx/ab-testing");
|
|
19
21
|
const error_utils_1 = require("../src/utils/error-utils");
|
|
20
22
|
const fs_1 = require("fs");
|
|
23
|
+
const path_1 = require("path");
|
|
21
24
|
const is_ci_1 = require("../src/utils/ci/is-ci");
|
|
22
25
|
const git_1 = require("../src/utils/git/git");
|
|
23
26
|
const ai_output_1 = require("../src/utils/ai/ai-output");
|
|
@@ -41,8 +44,8 @@ let chosenPreset;
|
|
|
41
44
|
let useCloud;
|
|
42
45
|
// For stats
|
|
43
46
|
let packageManager;
|
|
44
|
-
exports.commandsObject =
|
|
45
|
-
.wrap(
|
|
47
|
+
exports.commandsObject = yargs_1.default
|
|
48
|
+
.wrap(yargs_1.default.terminalWidth())
|
|
46
49
|
.parserConfiguration({
|
|
47
50
|
'strip-dashed': true,
|
|
48
51
|
'dot-notation': true,
|
|
@@ -51,140 +54,140 @@ exports.commandsObject = yargs
|
|
|
51
54
|
// this is the default and only command
|
|
52
55
|
'$0 [name] [options]', 'Create a new Nx workspace', (yargs) => (0, yargs_options_1.withOptions)(yargs
|
|
53
56
|
.option('name', {
|
|
54
|
-
describe:
|
|
57
|
+
describe: chalk_1.default.dim `Workspace name (e.g. org name).`,
|
|
55
58
|
type: 'string',
|
|
56
59
|
})
|
|
57
60
|
.option('preset', {
|
|
58
61
|
// This describe is hard to auto-fix because of the loop in the code.
|
|
59
62
|
// eslint-disable-next-line @nx/workspace/valid-command-object
|
|
60
|
-
describe:
|
|
63
|
+
describe: chalk_1.default.dim `Customizes the initial content of your workspace. Default presets include: [${Object.values(preset_1.Preset)
|
|
61
64
|
.map((p) => `"${p}"`)
|
|
62
65
|
.join(', ')}]. To build your own see https://nx.dev/extending-nx/recipes/create-preset.`,
|
|
63
66
|
type: 'string',
|
|
64
67
|
})
|
|
65
68
|
.option('interactive', {
|
|
66
|
-
describe:
|
|
69
|
+
describe: chalk_1.default.dim `Enable interactive mode with presets.`,
|
|
67
70
|
type: 'boolean',
|
|
68
71
|
default: true,
|
|
69
72
|
})
|
|
70
73
|
.option('workspaceType', {
|
|
71
|
-
describe:
|
|
74
|
+
describe: chalk_1.default.dim `The type of workspace to create.`,
|
|
72
75
|
choices: ['integrated', 'package-based', 'standalone'],
|
|
73
76
|
type: 'string',
|
|
74
77
|
})
|
|
75
78
|
.option('appName', {
|
|
76
|
-
describe:
|
|
79
|
+
describe: chalk_1.default.dim `The name of the app when using a monorepo with certain stacks.`,
|
|
77
80
|
type: 'string',
|
|
78
81
|
})
|
|
79
82
|
.option('style', {
|
|
80
|
-
describe:
|
|
83
|
+
describe: chalk_1.default.dim `Stylesheet type to be used with certain stacks.`,
|
|
81
84
|
type: 'string',
|
|
82
85
|
})
|
|
83
86
|
.option('standaloneApi', {
|
|
84
|
-
describe:
|
|
87
|
+
describe: chalk_1.default.dim `Use Standalone Components if generating an Angular app.`,
|
|
85
88
|
type: 'boolean',
|
|
86
89
|
default: true,
|
|
87
90
|
})
|
|
88
91
|
.option('routing', {
|
|
89
|
-
describe:
|
|
92
|
+
describe: chalk_1.default.dim `Add a routing setup for an Angular or React app.`,
|
|
90
93
|
type: 'boolean',
|
|
91
94
|
default: true,
|
|
92
95
|
})
|
|
93
96
|
.option('useReactRouter', {
|
|
94
|
-
describe:
|
|
97
|
+
describe: chalk_1.default.dim `Generate a Server-Side Rendered (SSR) React app using React Router.`,
|
|
95
98
|
type: 'boolean',
|
|
96
99
|
})
|
|
97
100
|
.option('bundler', {
|
|
98
|
-
describe:
|
|
101
|
+
describe: chalk_1.default.dim `Bundler to be used to build the app.`,
|
|
99
102
|
type: 'string',
|
|
100
103
|
})
|
|
101
104
|
.option('workspaces', {
|
|
102
|
-
describe:
|
|
105
|
+
describe: chalk_1.default.dim `Use package manager workspaces.`,
|
|
103
106
|
type: 'boolean',
|
|
104
107
|
default: true,
|
|
105
108
|
})
|
|
106
109
|
.option('useProjectJson', {
|
|
107
|
-
describe:
|
|
110
|
+
describe: chalk_1.default.dim `Use a 'project.json' file for the Nx configuration instead of a 'package.json' file. This defaults to 'true' when '--no-workspaces' is used. Otherwise, it defaults to 'false'.`,
|
|
108
111
|
type: 'boolean',
|
|
109
112
|
})
|
|
110
113
|
.option('formatter', {
|
|
111
|
-
describe:
|
|
114
|
+
describe: chalk_1.default.dim `Code formatter to use.`,
|
|
112
115
|
type: 'string',
|
|
113
116
|
})
|
|
114
117
|
.option('framework', {
|
|
115
|
-
describe:
|
|
118
|
+
describe: chalk_1.default.dim `Framework option to be used with certain stacks.`,
|
|
116
119
|
type: 'string',
|
|
117
120
|
})
|
|
118
121
|
.option('docker', {
|
|
119
|
-
describe:
|
|
122
|
+
describe: chalk_1.default.dim `Generate a Dockerfile for the Node API.`,
|
|
120
123
|
type: 'boolean',
|
|
121
124
|
})
|
|
122
125
|
.option('nextAppDir', {
|
|
123
|
-
describe:
|
|
126
|
+
describe: chalk_1.default.dim `Enable the App Router for Next.js.`,
|
|
124
127
|
type: 'boolean',
|
|
125
128
|
})
|
|
126
129
|
.option('nextSrcDir', {
|
|
127
|
-
describe:
|
|
130
|
+
describe: chalk_1.default.dim `Generate a 'src/' directory for Next.js.`,
|
|
128
131
|
type: 'boolean',
|
|
129
132
|
})
|
|
130
133
|
.option('e2eTestRunner', {
|
|
131
|
-
describe:
|
|
134
|
+
describe: chalk_1.default.dim `Test runner to use for end to end (E2E) tests.`,
|
|
132
135
|
choices: ['playwright', 'cypress', 'none'],
|
|
133
136
|
type: 'string',
|
|
134
137
|
})
|
|
135
138
|
.option('unitTestRunner', {
|
|
136
|
-
describe:
|
|
139
|
+
describe: chalk_1.default.dim `Test runner to use for unit tests.`,
|
|
137
140
|
choices: ['jest', 'vitest', 'none'],
|
|
138
141
|
type: 'string',
|
|
139
142
|
})
|
|
140
143
|
.option('ssr', {
|
|
141
|
-
describe:
|
|
144
|
+
describe: chalk_1.default.dim `Enable Server-Side Rendering (SSR) and Static Site Generation (SSG/Prerendering) for the Angular application.`,
|
|
142
145
|
type: 'boolean',
|
|
143
146
|
})
|
|
144
147
|
.option('prefix', {
|
|
145
|
-
describe:
|
|
148
|
+
describe: chalk_1.default.dim `Prefix to use for Angular component and directive selectors.`,
|
|
146
149
|
type: 'string',
|
|
147
150
|
})
|
|
148
151
|
.option('zoneless', {
|
|
149
|
-
describe:
|
|
152
|
+
describe: chalk_1.default.dim `Generate an application that does not use 'zone.js'.`,
|
|
150
153
|
type: 'boolean',
|
|
151
154
|
default: true,
|
|
152
155
|
})
|
|
153
156
|
.option('aiAgents', {
|
|
154
|
-
describe:
|
|
157
|
+
describe: chalk_1.default.dim `List of AI agents to configure.`,
|
|
155
158
|
type: 'array',
|
|
156
159
|
choices: [...create_workspace_options_1.supportedAgents],
|
|
157
160
|
})
|
|
158
161
|
.option('template', {
|
|
159
|
-
describe:
|
|
162
|
+
describe: chalk_1.default.dim `GitHub template repository to use. Available templates: nrwl/empty-template, nrwl/react-template, nrwl/angular-template, nrwl/typescript-template`,
|
|
160
163
|
type: 'string',
|
|
161
164
|
}), yargs_options_1.withNxCloud, yargs_options_1.withUseGitHub, yargs_options_1.withAllPrompts, yargs_options_1.withPackageManager, yargs_options_1.withGitOptions, yargs_options_1.withAnalytics), async function handler(argv) {
|
|
162
165
|
await main(argv).catch(handleError);
|
|
163
166
|
}, [normalizeArgsMiddleware])
|
|
164
|
-
.help('help',
|
|
167
|
+
.help('help', chalk_1.default.dim `Show help`)
|
|
165
168
|
.updateLocale(decorator_1.yargsDecorator)
|
|
166
|
-
.version('version',
|
|
169
|
+
.version('version', chalk_1.default.dim `Show version`, nx_version_1.nxVersion);
|
|
167
170
|
// Add AI-specific examples and epilogue only when AI agent detected
|
|
168
171
|
// This keeps --help clean for human users
|
|
169
172
|
if ((0, ai_output_1.isAiAgent)()) {
|
|
170
173
|
exports.commandsObject
|
|
171
|
-
.example(
|
|
172
|
-
.example(' npx create-nx-workspace@latest myorg --template=
|
|
174
|
+
.example(chalk_1.default.green('AI AGENTS (RECOMMENDED):'), '')
|
|
175
|
+
.example(' npx create-nx-workspace@latest myorg --template=empty --nxCloud=yes --interactive=false', '')
|
|
173
176
|
.example('', '')
|
|
174
|
-
.example(
|
|
175
|
-
.example(' --template=
|
|
176
|
-
.example(' --template=
|
|
177
|
-
.example(' --template=
|
|
178
|
-
.example(' --template=
|
|
179
|
-
.epilogue(`${
|
|
177
|
+
.example(chalk_1.default.green('AVAILABLE TEMPLATES:'), '')
|
|
178
|
+
.example(' --template=empty Empty monorepo', '')
|
|
179
|
+
.example(' --template=react React fullstack', '')
|
|
180
|
+
.example(' --template=angular Angular fullstack', '')
|
|
181
|
+
.example(' --template=typescript NPM packages', '')
|
|
182
|
+
.epilogue(`${chalk_1.default.cyan('AI Agent Mode:')}
|
|
180
183
|
Set CLAUDECODE=1 or OPENCODE=1 for JSON output and non-interactive mode.
|
|
181
184
|
In AI mode: auto non-interactive, NDJSON progress output, structured results.
|
|
182
185
|
|
|
183
|
-
${
|
|
186
|
+
${chalk_1.default.cyan('Documentation:')}
|
|
184
187
|
https://nx.dev/getting-started/intro`);
|
|
185
188
|
}
|
|
186
189
|
else {
|
|
187
|
-
exports.commandsObject.epilogue(`${
|
|
190
|
+
exports.commandsObject.epilogue(`${chalk_1.default.cyan('Documentation:')}
|
|
188
191
|
https://nx.dev/getting-started/intro`);
|
|
189
192
|
}
|
|
190
193
|
// Node 24 has stricter readline behavior, and enquirer is not checking for closed state
|
|
@@ -252,6 +255,7 @@ async function main(parsedArgs) {
|
|
|
252
255
|
nxCloudArg: parsedArgs.nxCloud ?? '',
|
|
253
256
|
nxCloudArgRaw: rawArgs.nxCloud ?? '',
|
|
254
257
|
pushedToVcs: workspaceInfo.pushedToVcs ?? '',
|
|
258
|
+
pushFailReason: workspaceInfo.pushFailReason ?? '',
|
|
255
259
|
template: chosenTemplate ?? '',
|
|
256
260
|
preset: chosenPreset ?? '',
|
|
257
261
|
connectUrl: workspaceInfo.connectUrl ?? '',
|
|
@@ -616,14 +620,54 @@ function validateWorkspaceName(name) {
|
|
|
616
620
|
throw new error_utils_1.CnwError('INVALID_WORKSPACE_NAME', `The workspace name "${name}" is invalid. Workspace names must start with a letter. Examples of valid names: myapp, MyApp, my-app, my_app`);
|
|
617
621
|
}
|
|
618
622
|
}
|
|
623
|
+
/**
|
|
624
|
+
* Resolves special folder name patterns (`.`, `./`, absolute paths) into a
|
|
625
|
+
* workspace name and a `workingDir` override so that downstream functions
|
|
626
|
+
* create the workspace at the intended location.
|
|
627
|
+
*
|
|
628
|
+
* @visibleForTesting
|
|
629
|
+
*
|
|
630
|
+
* Returns `{ name, workingDir }` for special inputs, or `null` if the
|
|
631
|
+
* input is a regular name that needs no special handling.
|
|
632
|
+
*/
|
|
633
|
+
function resolveSpecialFolderName(folderName) {
|
|
634
|
+
// Handle "." and "./" — user wants to init in the current directory
|
|
635
|
+
if (folderName === '.' || folderName === './') {
|
|
636
|
+
const cwd = (0, path_1.resolve)(process.cwd());
|
|
637
|
+
if ((0, fs_1.readdirSync)(cwd).length > 0) {
|
|
638
|
+
throw new error_utils_1.CnwError('DIRECTORY_EXISTS', `The current directory is not empty. Use "nx init" to add Nx to an existing project.`);
|
|
639
|
+
}
|
|
640
|
+
return { name: (0, path_1.basename)(cwd), workingDir: (0, path_1.dirname)(cwd) };
|
|
641
|
+
}
|
|
642
|
+
// Handle absolute paths like /tmp/acme
|
|
643
|
+
if ((0, path_1.isAbsolute)(folderName)) {
|
|
644
|
+
const parentDir = (0, path_1.dirname)(folderName);
|
|
645
|
+
const name = (0, path_1.basename)(folderName);
|
|
646
|
+
if (!(0, fs_1.existsSync)(parentDir)) {
|
|
647
|
+
throw new error_utils_1.CnwError('INVALID_PATH', `The parent directory "${parentDir}" does not exist.`);
|
|
648
|
+
}
|
|
649
|
+
return { name, workingDir: parentDir };
|
|
650
|
+
}
|
|
651
|
+
return null;
|
|
652
|
+
}
|
|
619
653
|
async function determineFolder(parsedArgs) {
|
|
620
|
-
const
|
|
654
|
+
const rawFolderName = parsedArgs._[0]
|
|
621
655
|
? parsedArgs._[0].toString()
|
|
622
656
|
: parsedArgs.name;
|
|
623
|
-
if (
|
|
657
|
+
if (rawFolderName) {
|
|
658
|
+
// Resolve ".", "./", and absolute paths before validation
|
|
659
|
+
const resolved = resolveSpecialFolderName(rawFolderName);
|
|
660
|
+
const folderName = resolved?.name ?? rawFolderName;
|
|
661
|
+
if (resolved?.workingDir) {
|
|
662
|
+
parsedArgs.workingDir = resolved.workingDir;
|
|
663
|
+
}
|
|
624
664
|
validateWorkspaceName(folderName);
|
|
625
665
|
// If directory exists, either re-prompt (interactive) or error (non-interactive)
|
|
626
|
-
|
|
666
|
+
// Check relative to workingDir when set (e.g. absolute path resolved to a different parent)
|
|
667
|
+
const targetDir = resolved?.workingDir
|
|
668
|
+
? (0, path_1.join)(resolved.workingDir, folderName)
|
|
669
|
+
: folderName;
|
|
670
|
+
if ((0, fs_1.existsSync)(targetDir)) {
|
|
627
671
|
if (parsedArgs.interactive && !(0, is_ci_1.isCI)()) {
|
|
628
672
|
output_1.output.warn({
|
|
629
673
|
title: `Directory ${folderName} already exists.`,
|
|
@@ -638,7 +682,7 @@ async function determineFolder(parsedArgs) {
|
|
|
638
682
|
return promptForFolder(parsedArgs);
|
|
639
683
|
}
|
|
640
684
|
async function promptForFolder(parsedArgs) {
|
|
641
|
-
const reply = await
|
|
685
|
+
const reply = await enquirer_1.default.prompt([
|
|
642
686
|
{
|
|
643
687
|
name: 'folderName',
|
|
644
688
|
message: `Where would you like to create your workspace?`,
|
|
@@ -701,7 +745,7 @@ async function determineStack(parsedArgs) {
|
|
|
701
745
|
return 'unknown';
|
|
702
746
|
}
|
|
703
747
|
}
|
|
704
|
-
const { stack } = await
|
|
748
|
+
const { stack } = await enquirer_1.default.prompt([
|
|
705
749
|
{
|
|
706
750
|
name: 'stack',
|
|
707
751
|
message: `Which stack do you want to use?`,
|
|
@@ -753,7 +797,7 @@ async function determinePresetOptions(parsedArgs) {
|
|
|
753
797
|
async function determineFormatterOptions(args, opts) {
|
|
754
798
|
if (args.formatter)
|
|
755
799
|
return args.formatter;
|
|
756
|
-
const reply = await
|
|
800
|
+
const reply = await enquirer_1.default.prompt([
|
|
757
801
|
{
|
|
758
802
|
name: 'prettier',
|
|
759
803
|
message: `Would you like to use Prettier for code formatting?`,
|
|
@@ -773,7 +817,7 @@ async function determineFormatterOptions(args, opts) {
|
|
|
773
817
|
return reply.prettier === 'Yes' ? 'prettier' : 'none';
|
|
774
818
|
}
|
|
775
819
|
async function determineLinterOptions(args, opts) {
|
|
776
|
-
const reply = await
|
|
820
|
+
const reply = await enquirer_1.default.prompt([
|
|
777
821
|
{
|
|
778
822
|
name: 'eslint',
|
|
779
823
|
message: `Would you like to use ESLint?`,
|
|
@@ -830,7 +874,7 @@ async function determineNoneOptions(parsedArgs) {
|
|
|
830
874
|
else if (preset === preset_1.Preset.TsStandalone) {
|
|
831
875
|
// Only standalone TS preset generates a default package, so we need to provide --js and --appName options.
|
|
832
876
|
appName = parsedArgs.name;
|
|
833
|
-
const reply = await
|
|
877
|
+
const reply = await enquirer_1.default.prompt([
|
|
834
878
|
{
|
|
835
879
|
name: 'ts',
|
|
836
880
|
message: `Would you like to use TypeScript with this project?`,
|
|
@@ -939,7 +983,7 @@ async function determineReactOptions(parsedArgs) {
|
|
|
939
983
|
preset === preset_1.Preset.ReactMonorepo ||
|
|
940
984
|
preset === preset_1.Preset.NextJs ||
|
|
941
985
|
preset === preset_1.Preset.NextJsStandalone) {
|
|
942
|
-
const reply = await
|
|
986
|
+
const reply = await enquirer_1.default.prompt([
|
|
943
987
|
{
|
|
944
988
|
name: 'style',
|
|
945
989
|
message: `Default stylesheet format`,
|
|
@@ -1060,7 +1104,7 @@ async function determineVueOptions(parsedArgs) {
|
|
|
1060
1104
|
style = parsedArgs.style;
|
|
1061
1105
|
}
|
|
1062
1106
|
else {
|
|
1063
|
-
const reply = await
|
|
1107
|
+
const reply = await enquirer_1.default.prompt([
|
|
1064
1108
|
{
|
|
1065
1109
|
name: 'style',
|
|
1066
1110
|
message: `Default stylesheet format`,
|
|
@@ -1150,11 +1194,15 @@ async function determineAngularOptions(parsedArgs) {
|
|
|
1150
1194
|
appName = await determineAppName(parsedArgs);
|
|
1151
1195
|
}
|
|
1152
1196
|
}
|
|
1197
|
+
const validAngularBundlers = ['esbuild', 'rspack', 'webpack'];
|
|
1153
1198
|
if (parsedArgs.bundler) {
|
|
1199
|
+
if (!validAngularBundlers.includes(parsedArgs.bundler)) {
|
|
1200
|
+
throw new error_utils_1.CnwError('INVALID_BUNDLER', `Invalid bundler "${parsedArgs.bundler}" for Angular. Valid options are: ${validAngularBundlers.join(', ')}`);
|
|
1201
|
+
}
|
|
1154
1202
|
bundler = parsedArgs.bundler;
|
|
1155
1203
|
}
|
|
1156
1204
|
else {
|
|
1157
|
-
const reply = await
|
|
1205
|
+
const reply = await enquirer_1.default.prompt([
|
|
1158
1206
|
{
|
|
1159
1207
|
name: 'bundler',
|
|
1160
1208
|
message: `Which bundler would you like to use?`,
|
|
@@ -1183,7 +1231,7 @@ async function determineAngularOptions(parsedArgs) {
|
|
|
1183
1231
|
style = parsedArgs.style;
|
|
1184
1232
|
}
|
|
1185
1233
|
else {
|
|
1186
|
-
const reply = await
|
|
1234
|
+
const reply = await enquirer_1.default.prompt([
|
|
1187
1235
|
{
|
|
1188
1236
|
name: 'style',
|
|
1189
1237
|
message: `Default stylesheet format`,
|
|
@@ -1212,7 +1260,7 @@ async function determineAngularOptions(parsedArgs) {
|
|
|
1212
1260
|
ssr = parsedArgs.ssr;
|
|
1213
1261
|
}
|
|
1214
1262
|
else {
|
|
1215
|
-
const reply = await
|
|
1263
|
+
const reply = await enquirer_1.default.prompt([
|
|
1216
1264
|
{
|
|
1217
1265
|
name: 'ssr',
|
|
1218
1266
|
message: `Do you want to enable Server-Side Rendering (SSR)${bundler !== 'rspack'
|
|
@@ -1233,7 +1281,7 @@ async function determineAngularOptions(parsedArgs) {
|
|
|
1233
1281
|
unitTestRunner = undefined;
|
|
1234
1282
|
}
|
|
1235
1283
|
else {
|
|
1236
|
-
unitTestRunner = await
|
|
1284
|
+
unitTestRunner = await enquirer_1.default
|
|
1237
1285
|
.prompt([
|
|
1238
1286
|
{
|
|
1239
1287
|
message: 'Which unit test runner would you like to use?',
|
|
@@ -1326,7 +1374,7 @@ async function determineNodeOptions(parsedArgs) {
|
|
|
1326
1374
|
docker = parsedArgs.docker;
|
|
1327
1375
|
}
|
|
1328
1376
|
else {
|
|
1329
|
-
const reply = await
|
|
1377
|
+
const reply = await enquirer_1.default.prompt([
|
|
1330
1378
|
{
|
|
1331
1379
|
name: 'docker',
|
|
1332
1380
|
message: 'Would you like to generate a Dockerfile? [https://docs.docker.com/]',
|
|
@@ -1371,7 +1419,7 @@ async function determineNodeOptions(parsedArgs) {
|
|
|
1371
1419
|
};
|
|
1372
1420
|
}
|
|
1373
1421
|
async function determinePackageBasedOrIntegratedOrStandalone() {
|
|
1374
|
-
const { workspaceType } = await
|
|
1422
|
+
const { workspaceType } = await enquirer_1.default.prompt([
|
|
1375
1423
|
{
|
|
1376
1424
|
type: 'autocomplete',
|
|
1377
1425
|
name: 'workspaceType',
|
|
@@ -1397,7 +1445,7 @@ async function determinePackageBasedOrIntegratedOrStandalone() {
|
|
|
1397
1445
|
return workspaceType;
|
|
1398
1446
|
}
|
|
1399
1447
|
async function determineStandaloneOrMonorepo() {
|
|
1400
|
-
const { workspaceType } = await
|
|
1448
|
+
const { workspaceType } = await enquirer_1.default.prompt([
|
|
1401
1449
|
{
|
|
1402
1450
|
type: 'autocomplete',
|
|
1403
1451
|
name: 'workspaceType',
|
|
@@ -1421,7 +1469,7 @@ async function determineStandaloneOrMonorepo() {
|
|
|
1421
1469
|
async function determineAppName(parsedArgs) {
|
|
1422
1470
|
if (parsedArgs.appName)
|
|
1423
1471
|
return parsedArgs.appName;
|
|
1424
|
-
const { appName } = await
|
|
1472
|
+
const { appName } = await enquirer_1.default.prompt([
|
|
1425
1473
|
{
|
|
1426
1474
|
name: 'appName',
|
|
1427
1475
|
message: `Application name`,
|
|
@@ -1440,7 +1488,7 @@ async function determineReactFramework(parsedArgs) {
|
|
|
1440
1488
|
if (!parsedArgs.interactive) {
|
|
1441
1489
|
return 'none';
|
|
1442
1490
|
}
|
|
1443
|
-
const reply = await
|
|
1491
|
+
const reply = await enquirer_1.default.prompt([
|
|
1444
1492
|
{
|
|
1445
1493
|
name: 'framework',
|
|
1446
1494
|
message: 'What framework would you like to use?',
|
|
@@ -1472,7 +1520,7 @@ async function determineReactFramework(parsedArgs) {
|
|
|
1472
1520
|
async function determineReactBundler(parsedArgs) {
|
|
1473
1521
|
if (parsedArgs.bundler)
|
|
1474
1522
|
return parsedArgs.bundler;
|
|
1475
|
-
const reply = await
|
|
1523
|
+
const reply = await enquirer_1.default.prompt([
|
|
1476
1524
|
{
|
|
1477
1525
|
name: 'bundler',
|
|
1478
1526
|
message: `Which bundler would you like to use?`,
|
|
@@ -1500,7 +1548,7 @@ async function determineReactBundler(parsedArgs) {
|
|
|
1500
1548
|
async function determineNextAppDir(parsedArgs) {
|
|
1501
1549
|
if (parsedArgs.nextAppDir !== undefined)
|
|
1502
1550
|
return parsedArgs.nextAppDir;
|
|
1503
|
-
const reply = await
|
|
1551
|
+
const reply = await enquirer_1.default.prompt([
|
|
1504
1552
|
{
|
|
1505
1553
|
name: 'nextAppDir',
|
|
1506
1554
|
message: 'Would you like to use the App Router (recommended)?',
|
|
@@ -1522,7 +1570,7 @@ async function determineNextAppDir(parsedArgs) {
|
|
|
1522
1570
|
async function determineNextSrcDir(parsedArgs) {
|
|
1523
1571
|
if (parsedArgs.nextSrcDir !== undefined)
|
|
1524
1572
|
return parsedArgs.nextSrcDir;
|
|
1525
|
-
const reply = await
|
|
1573
|
+
const reply = await enquirer_1.default.prompt([
|
|
1526
1574
|
{
|
|
1527
1575
|
name: 'nextSrcDir',
|
|
1528
1576
|
message: 'Would you like to use the src/ directory?',
|
|
@@ -1544,7 +1592,7 @@ async function determineNextSrcDir(parsedArgs) {
|
|
|
1544
1592
|
async function determineVueFramework(parsedArgs) {
|
|
1545
1593
|
if (!!parsedArgs.framework)
|
|
1546
1594
|
return parsedArgs.framework;
|
|
1547
|
-
const reply = await
|
|
1595
|
+
const reply = await enquirer_1.default.prompt([
|
|
1548
1596
|
{
|
|
1549
1597
|
name: 'framework',
|
|
1550
1598
|
message: 'What framework would you like to use?',
|
|
@@ -1569,7 +1617,7 @@ async function determineVueFramework(parsedArgs) {
|
|
|
1569
1617
|
async function determineNodeFramework(parsedArgs) {
|
|
1570
1618
|
if (!!parsedArgs.framework)
|
|
1571
1619
|
return parsedArgs.framework;
|
|
1572
|
-
const reply = await
|
|
1620
|
+
const reply = await enquirer_1.default.prompt([
|
|
1573
1621
|
{
|
|
1574
1622
|
message: 'What framework should be used?',
|
|
1575
1623
|
type: 'autocomplete',
|
|
@@ -1609,7 +1657,7 @@ async function determineUnitTestRunner(parsedArgs, options) {
|
|
|
1609
1657
|
else if (!parsedArgs.workspaces) {
|
|
1610
1658
|
return undefined;
|
|
1611
1659
|
}
|
|
1612
|
-
const reply = await
|
|
1660
|
+
const reply = await enquirer_1.default.prompt([
|
|
1613
1661
|
{
|
|
1614
1662
|
message: 'Which unit test runner would you like to use?',
|
|
1615
1663
|
type: 'autocomplete',
|
|
@@ -1649,7 +1697,7 @@ async function determineUnitTestRunner(parsedArgs, options) {
|
|
|
1649
1697
|
async function determineE2eTestRunner(parsedArgs) {
|
|
1650
1698
|
if (parsedArgs.e2eTestRunner)
|
|
1651
1699
|
return parsedArgs.e2eTestRunner;
|
|
1652
|
-
const reply = await
|
|
1700
|
+
const reply = await enquirer_1.default.prompt([
|
|
1653
1701
|
{
|
|
1654
1702
|
message: 'Test runner to use for end to end (E2E) tests',
|
|
1655
1703
|
type: 'autocomplete',
|
|
@@ -1679,7 +1727,7 @@ async function determineReactRouter(parsedArgs) {
|
|
|
1679
1727
|
return false;
|
|
1680
1728
|
if (parsedArgs.useReactRouter !== undefined)
|
|
1681
1729
|
return parsedArgs.useReactRouter;
|
|
1682
|
-
const reply = await
|
|
1730
|
+
const reply = await enquirer_1.default.prompt([
|
|
1683
1731
|
{
|
|
1684
1732
|
message: 'Would you like to use React Router for server-side rendering [https://reactrouter.com/]?',
|
|
1685
1733
|
type: 'autocomplete',
|
package/bin/decorator.js
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.yargsDecorator = void 0;
|
|
4
|
-
const
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
5
6
|
exports.yargsDecorator = {
|
|
6
|
-
'Options:': `${
|
|
7
|
-
'Examples:': `${
|
|
8
|
-
boolean: `${
|
|
9
|
-
count: `${
|
|
10
|
-
string: `${
|
|
11
|
-
array: `${
|
|
12
|
-
required: `${
|
|
13
|
-
'default:': `${
|
|
14
|
-
'choices:': `${
|
|
15
|
-
'aliases:': `${
|
|
7
|
+
'Options:': `${chalk_1.default.green `Options`}:`,
|
|
8
|
+
'Examples:': `${chalk_1.default.green `Examples`}:`,
|
|
9
|
+
boolean: `${chalk_1.default.blue `boolean`}`,
|
|
10
|
+
count: `${chalk_1.default.blue `count`}`,
|
|
11
|
+
string: `${chalk_1.default.blue `string`}`,
|
|
12
|
+
array: `${chalk_1.default.blue `array`}`,
|
|
13
|
+
required: `${chalk_1.default.blue `required`}`,
|
|
14
|
+
'default:': `${chalk_1.default.blue `default`}:`,
|
|
15
|
+
'choices:': `${chalk_1.default.blue `choices`}:`,
|
|
16
|
+
'aliases:': `${chalk_1.default.blue `aliases`}:`,
|
|
16
17
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-nx-workspace",
|
|
3
|
-
"version": "22.7.0-beta.
|
|
3
|
+
"version": "22.7.0-beta.10",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Smart Monorepos · Fast Builds",
|
|
6
6
|
"repository": {
|
|
@@ -30,10 +30,11 @@
|
|
|
30
30
|
},
|
|
31
31
|
"homepage": "https://nx.dev",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"axios": "
|
|
33
|
+
"axios": "1.13.5",
|
|
34
34
|
"chalk": "^4.1.0",
|
|
35
35
|
"enquirer": "~2.3.6",
|
|
36
36
|
"flat": "^5.0.2",
|
|
37
|
+
"open": "^8.4.0",
|
|
37
38
|
"ora": "5.3.0",
|
|
38
39
|
"tmp": "~0.2.1",
|
|
39
40
|
"tslib": "^2.3.0",
|
|
@@ -41,8 +42,5 @@
|
|
|
41
42
|
},
|
|
42
43
|
"publishConfig": {
|
|
43
44
|
"access": "public"
|
|
44
|
-
}
|
|
45
|
-
"main": "index.js",
|
|
46
|
-
"types": "./src/index.d.ts",
|
|
47
|
-
"type": "commonjs"
|
|
45
|
+
}
|
|
48
46
|
}
|