Skip to content

Commit bcb6eff

Browse files
feat(create-qwik-nx): include configurations (#149)
1 parent e5ca33d commit bcb6eff

File tree

7 files changed

+341
-25
lines changed

7 files changed

+341
-25
lines changed

package.json

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@
1818
"@commitlint/config-angular": "^17.3.0",
1919
"@commitlint/config-conventional": "^17.3.0",
2020
"@jscutlery/semver": "^2.29.0",
21+
"@nx/cypress": "16.0.0",
22+
"@nx/devkit": "16.0.0",
23+
"@nx/eslint-plugin": "16.0.0",
24+
"@nx/jest": "16.0.0",
25+
"@nx/js": "16.0.0",
26+
"@nx/linter": "16.0.0",
27+
"@nx/plugin": "16.0.0",
28+
"@nx/storybook": "16.0.0",
29+
"@nx/vite": "16.0.0",
30+
"@nx/workspace": "16.0.0",
2131
"@nxkit/playwright": "^3.0.0",
2232
"@swc-node/register": "^1.4.2",
2333
"@swc/cli": "0.1.62",
@@ -26,13 +36,16 @@
2636
"@types/jest": "29.4.0",
2737
"@types/node": "16.11.7",
2838
"@types/tcp-port-used": "1.0.1",
39+
"@types/yargs": "17.0.24",
2940
"@typescript-eslint/eslint-plugin": "5.59.1",
3041
"@typescript-eslint/parser": "5.59.1",
3142
"all-contributors-cli": "^6.24.0",
3243
"chalk": "^4.1.0",
3344
"commitizen": "^4.2.5",
3445
"commitlint": "^17.3.0",
46+
"create-nx-workspace": "16.0.0",
3547
"cz-conventional-changelog": "^3.3.0",
48+
"enquirer": "2.3.6",
3649
"eslint": "~8.15.0",
3750
"eslint-config-prettier": "8.1.0",
3851
"eslint-plugin-unused-imports": "2.0.0",
@@ -46,6 +59,7 @@
4659
"kill-port": "2.0.1",
4760
"ngx-deploy-npm": "^5.2.0",
4861
"nx": "16.0.0",
62+
"nx-cloud": "16.0.5",
4963
"prettier": "^2.8.0",
5064
"pretty-quick": "^3.1.3",
5165
"tcp-port-used": "1.0.2",
@@ -56,18 +70,7 @@
5670
"typescript": "4.9.5",
5771
"verdaccio": "5.21.1",
5872
"vite": "4.1.1",
59-
"yargs": "17.7.1",
60-
"nx-cloud": "16.0.5",
61-
"@nx/devkit": "16.0.0",
62-
"@nx/workspace": "16.0.0",
63-
"@nx/js": "16.0.0",
64-
"@nx/linter": "16.0.0",
65-
"@nx/storybook": "16.0.0",
66-
"@nx/cypress": "16.0.0",
67-
"@nx/eslint-plugin": "16.0.0",
68-
"@nx/jest": "16.0.0",
69-
"@nx/vite": "16.0.0",
70-
"@nx/plugin": "16.0.0"
73+
"yargs": "17.7.1"
7174
},
7275
"dependencies": {
7376
"@swc/helpers": "0.5.1",
Lines changed: 266 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,269 @@
1-
#!/usr/bin/env node
1+
import * as enquirer from 'enquirer';
2+
import * as yargs from 'yargs';
3+
import * as chalk from 'chalk';
24

3-
import { execSync } from 'child_process';
5+
import { CreateWorkspaceOptions, createWorkspace } from 'create-nx-workspace';
6+
import { output } from 'create-nx-workspace/src/utils/output';
7+
import { printNxCloudSuccessMessage } from 'create-nx-workspace/src/utils/nx/nx-cloud';
8+
import {
9+
determineCI,
10+
determineDefaultBase,
11+
determineNxCloud,
12+
determinePackageManager,
13+
} from 'create-nx-workspace/src/internal-utils/prompts';
14+
import {
15+
withAllPrompts,
16+
withCI,
17+
withGitOptions,
18+
withNxCloud,
19+
withOptions,
20+
withPackageManager,
21+
} from 'create-nx-workspace/src/internal-utils/yargs-options';
422

5-
// Delegating to create-nx-workspace
23+
interface Arguments extends CreateWorkspaceOptions {
24+
/** Friendly name for the qwikAppName option */
25+
appName: string;
26+
/** Friendly name for the qwikAppStyle option */
27+
style: string;
28+
qwikAppName: string;
29+
qwikAppStyle: string;
30+
qwikNxVersion: string;
31+
}
632

7-
execSync(`npx -y create-nx-workspace@latest --preset=qwik-nx`, {
8-
stdio: [0, 1, 2],
9-
});
33+
export const commandsObject: yargs.Argv<Arguments> = yargs
34+
.wrap(yargs.terminalWidth())
35+
.parserConfiguration({
36+
'strip-dashed': true,
37+
'dot-notation': true,
38+
})
39+
.command<Arguments>(
40+
// this is the default and only command
41+
'$0 [name] [options]',
42+
'Create a new Nx workspace',
43+
(yargs) =>
44+
withOptions(
45+
yargs
46+
.option('name', {
47+
describe: chalk.dim`Workspace name (e.g. org name)`,
48+
type: 'string',
49+
})
50+
.option('appName', {
51+
describe: chalk.dim`The name of the Qwik application `,
52+
type: 'string',
53+
})
54+
.option('interactive', {
55+
describe: chalk.dim`Enable interactive mode with presets`,
56+
type: 'boolean',
57+
default: true,
58+
})
59+
.option('style', {
60+
describe: chalk.dim`Style option to be used with your Qwik app.`,
61+
type: 'string',
62+
})
63+
.option('qwikNxVersion', {
64+
describe: chalk.dim`Version of the qwik-nx package to be used. Latest by default.`,
65+
type: 'string',
66+
}),
67+
withNxCloud,
68+
withCI,
69+
withAllPrompts,
70+
withPackageManager,
71+
withGitOptions
72+
),
73+
74+
async (argv: yargs.ArgumentsCamelCase<Arguments>) => {
75+
await main(argv).catch((error) => {
76+
const { version } = require('../package.json');
77+
output.error({
78+
title: `Something went wrong! v${version}`,
79+
});
80+
throw error;
81+
});
82+
},
83+
[normalizeArgsMiddleware as yargs.MiddlewareFunction<unknown>]
84+
)
85+
.help('help', chalk.dim`Show help`)
86+
.version(
87+
'version',
88+
chalk.dim`Show version`,
89+
require('../package.json').version
90+
) as yargs.Argv<Arguments>;
91+
92+
async function main(parsedArgs: yargs.Arguments<Arguments>) {
93+
output.log({
94+
title: `Creating your workspace.`,
95+
bodyLines: [
96+
'To make sure the command works reliably in all environments, and that the preset is applied correctly,',
97+
`Nx will run "${parsedArgs.packageManager} install" several times. Please wait.`,
98+
],
99+
});
100+
101+
let presetName = 'qwik-nx';
102+
103+
if (parsedArgs.qwikNxVersion) {
104+
presetName += `@${parsedArgs.qwikNxVersion}`;
105+
}
106+
const workspaceInfo = await createWorkspace<Arguments>(
107+
presetName,
108+
parsedArgs
109+
);
110+
111+
if (parsedArgs.nxCloud && workspaceInfo.nxCloudInfo) {
112+
printNxCloudSuccessMessage(workspaceInfo.nxCloudInfo);
113+
}
114+
115+
output.log({
116+
title: `Successfully initialized the qwik-nx repo`,
117+
});
118+
}
119+
120+
async function normalizeArgsMiddleware(
121+
argv: yargs.Arguments<Arguments>
122+
): Promise<void> {
123+
// "appName" and "style" args should be applied with prefix,
124+
// because this is what "qwik-nx:preset" generator expects in order to be compatible with "create-nx-workspace --preset=qwik-nx"
125+
argv.qwikAppName ??= argv.appName;
126+
argv.qwikAppStyle ??= argv.style;
127+
128+
try {
129+
output.log({
130+
title:
131+
"Let's create a new workspace [https://nx.dev/getting-started/intro]",
132+
});
133+
134+
const preset = 'qwik-nx';
135+
const name = await determineRepoName(argv);
136+
const qwikAppName = await determineAppName(argv);
137+
const qwikAppStyle = await determineStyle(argv);
138+
139+
const packageManager = await determinePackageManager(argv);
140+
const defaultBase = await determineDefaultBase(argv);
141+
const nxCloud = await determineNxCloud(argv);
142+
const ci = await determineCI(argv, nxCloud);
143+
144+
Object.assign(argv, {
145+
name,
146+
preset,
147+
qwikAppName,
148+
qwikAppStyle,
149+
nxCloud,
150+
packageManager,
151+
defaultBase,
152+
ci,
153+
});
154+
} catch (e) {
155+
console.error(e);
156+
process.exit(1);
157+
}
158+
}
159+
160+
async function determineRepoName(
161+
parsedArgs: yargs.Arguments<Arguments>
162+
): Promise<string> {
163+
const repoName: string = parsedArgs._[0]
164+
? parsedArgs._[0].toString()
165+
: parsedArgs.name;
166+
167+
if (repoName) {
168+
return Promise.resolve(repoName);
169+
}
170+
171+
const a = await enquirer.prompt<{ RepoName: string }>([
172+
{
173+
name: 'RepoName',
174+
message: `Repository name `,
175+
type: 'input',
176+
},
177+
]);
178+
if (!a.RepoName) {
179+
output.error({
180+
title: 'Invalid repository name',
181+
bodyLines: [`Repository name cannot be empty`],
182+
});
183+
process.exit(1);
184+
}
185+
return a.RepoName;
186+
}
187+
188+
async function determineAppName(
189+
parsedArgs: yargs.Arguments<Arguments>
190+
): Promise<string> {
191+
if (parsedArgs.qwikAppName) {
192+
return Promise.resolve(parsedArgs.qwikAppName);
193+
}
194+
195+
return enquirer
196+
.prompt<{ AppName: string }>([
197+
{
198+
name: 'AppName',
199+
message: `Application name `,
200+
type: 'input',
201+
},
202+
])
203+
.then((a) => {
204+
if (!a.AppName) {
205+
output.error({
206+
title: 'Invalid name',
207+
bodyLines: [`Name cannot be empty`],
208+
});
209+
process.exit(1);
210+
}
211+
return a.AppName;
212+
});
213+
}
214+
215+
async function determineStyle(
216+
parsedArgs: yargs.Arguments<Arguments>
217+
): Promise<string | null> {
218+
const choices = [
219+
{
220+
name: 'css',
221+
message: 'CSS',
222+
},
223+
{
224+
name: 'scss',
225+
message: 'SASS(.scss) [ http://sass-lang.com ]',
226+
},
227+
{
228+
name: 'styl',
229+
message: 'Stylus(.styl) [ http://stylus-lang.com ]',
230+
},
231+
{
232+
name: 'less',
233+
message: 'LESS [ http://lesscss.org ]',
234+
},
235+
];
236+
237+
if (!parsedArgs.qwikAppStyle) {
238+
return enquirer
239+
.prompt<{ style: string }>([
240+
{
241+
name: 'style',
242+
message: `Default stylesheet format `,
243+
initial: 'css' as any,
244+
type: 'autocomplete',
245+
choices: choices,
246+
},
247+
])
248+
.then((a: { style: string }) => a.style);
249+
}
250+
251+
const foundStyle = choices.find(
252+
(choice) => choice.name === parsedArgs.qwikAppStyle
253+
);
254+
255+
if (foundStyle === undefined) {
256+
output.error({
257+
title: 'Invalid style',
258+
bodyLines: [
259+
`It must be one of the following:`,
260+
'',
261+
...choices.map((choice) => choice.name),
262+
],
263+
});
264+
265+
process.exit(1);
266+
}
267+
268+
return Promise.resolve(parsedArgs.qwikAppStyle);
269+
}

packages/create-qwik-nx/bin/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env node
2+
3+
import { commandsObject } from './create-qwik-nx';
4+
5+
commandsObject.argv;

packages/create-qwik-nx/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,17 @@
1616
"CLI"
1717
],
1818
"bin": {
19-
"create-qwik-nx": "./bin/create-qwik-nx.js"
19+
"create-qwik-nx": "./bin/index.js"
2020
},
2121
"author": "Shai Reznik",
2222
"license": "MIT",
2323
"bugs": {
2424
"url": "https://github.com/qwikifiers/qwik-nx/issues"
2525
},
2626
"homepage": "https://github.com/qwikifiers/qwik-nx",
27-
"dependencies": {},
27+
"dependencies": {
28+
"create-nx-workspace": "^16.0.0"
29+
},
2830
"publishConfig": {
2931
"access": "public"
3032
}

packages/create-qwik-nx/project.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@
8282
"executor": "ngx-deploy-npm:deploy",
8383
"options": {
8484
"access": "public"
85+
},
86+
"configurations": {
87+
"local": {
88+
"registry": "http://localhost:4873"
89+
}
8590
}
8691
},
8792
"push-to-github": {

packages/create-qwik-nx/tsconfig.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
"extends": "../../tsconfig.base.json",
33
"compilerOptions": {
44
"types": ["node", "jest"],
5-
"resolveJsonModule": true,
6-
"esModuleInterop": true
5+
"strict": true
76
},
87
"include": [],
98
"files": [],

0 commit comments

Comments
 (0)