react-nest-cli 1.0.2 → 1.0.4

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.
@@ -0,0 +1,3 @@
1
+ giget
2
+ javascriptx
3
+ liaolonghui
package/.editorconfig ADDED
@@ -0,0 +1,5 @@
1
+ [*]
2
+ semi = true
3
+ singleQuote = true
4
+ tabWidth = 4
5
+ trailingComma = "none"
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env sh
2
+
3
+ npx commitlint --edit "$1"
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env sh
2
+
3
+ pnpm spellcheck && pnpm typecheck && npx lint-staged
@@ -0,0 +1 @@
1
+ /dist
@@ -0,0 +1,113 @@
1
+ import { defineConfig, type CommitizenGitOptions } from 'cz-git'
2
+
3
+ export default defineConfig({
4
+ extends: ['@commitlint/config-conventional'], // 引入 conventional 规则
5
+ rules: {
6
+ // @see: https://commitlint.js.org/#/reference-rules
7
+ },
8
+ prompt: {
9
+ alias: { fd: 'docs: fix typos' },
10
+ messages: {
11
+ type: "Select the type of change that you're committing:",
12
+ scope: 'Denote the SCOPE of this change (optional):',
13
+ customScope: 'Denote the SCOPE of this change:',
14
+ subject:
15
+ 'Write a SHORT, IMPERATIVE tense description of the change:\n',
16
+ body: 'Provide a LONGER description of the change (optional). Use "|" to break new line:\n',
17
+ breaking:
18
+ 'List any BREAKING CHANGES (optional). Use "|" to break new line:\n',
19
+ footerPrefixesSelect:
20
+ 'Select the ISSUES type of changeList by this change (optional):',
21
+ customFooterPrefix: 'Input ISSUES prefix:',
22
+ footer: 'List any ISSUES by this change. E.g.: #31, #34:\n',
23
+ generatingByAI: 'Generating your AI commit subject...',
24
+ generatedSelectByAI: 'Select suitable subject by AI generated:',
25
+ confirmCommit:
26
+ 'Are you sure you want to proceed with the commit above?',
27
+ },
28
+ types: [
29
+ {
30
+ value: 'feat',
31
+ name: 'feat: ✨ A new feature',
32
+ emoji: ':sparkles:',
33
+ },
34
+ { value: 'fix', name: 'fix: 🐛 A bug fix', emoji: ':bug:' },
35
+ {
36
+ value: 'docs',
37
+ name: 'docs: 📝 Documentation only changes',
38
+ emoji: ':memo:',
39
+ },
40
+ {
41
+ value: 'style',
42
+ name: 'style: 💄 Changes that do not affect the meaning of the code',
43
+ emoji: ':lipstick:',
44
+ },
45
+ {
46
+ value: 'refactor',
47
+ name: 'refactor: ♻️ A code change that neither fixes a bug nor adds a feature',
48
+ emoji: ':recycle:',
49
+ },
50
+ {
51
+ value: 'perf',
52
+ name: 'perf: ⚡️ A code change that improves performance',
53
+ emoji: ':zap:',
54
+ },
55
+ {
56
+ value: 'test',
57
+ name: 'test: ✅ Adding missing tests or correcting existing tests',
58
+ emoji: ':white_check_mark:',
59
+ },
60
+ {
61
+ value: 'build',
62
+ name: 'build: 📦️ Changes that affect the build system or external dependencies',
63
+ emoji: ':package:',
64
+ },
65
+ {
66
+ value: 'ci',
67
+ name: 'ci: 🎡 Changes to our CI configuration files and scripts',
68
+ emoji: ':ferris_wheel:',
69
+ },
70
+ {
71
+ value: 'chore',
72
+ name: "chore: 🔨 Other changes that don't modify src or test files",
73
+ emoji: ':hammer:',
74
+ },
75
+ {
76
+ value: 'revert',
77
+ name: 'revert: ⏪️ Reverts a previous commit',
78
+ emoji: ':rewind:',
79
+ },
80
+ ],
81
+ useEmoji: true,
82
+ emojiAlign: 'center',
83
+ useAI: false,
84
+ aiNumber: 1,
85
+ themeColorCode: '',
86
+ scopes: [],
87
+ allowCustomScopes: true,
88
+ allowEmptyScopes: true,
89
+ customScopesAlign: 'bottom',
90
+ customScopesAlias: 'custom',
91
+ emptyScopesAlias: 'empty',
92
+ upperCaseSubject: null,
93
+ markBreakingChangeMode: false,
94
+ allowBreakingChanges: ['feat', 'fix'],
95
+ breaklineNumber: 100,
96
+ breaklineChar: '|',
97
+ skipQuestions: [],
98
+ issuePrefixes: [
99
+ { value: 'closed', name: 'closed: ISSUES has been processed' },
100
+ ],
101
+ customIssuePrefixAlign: 'top',
102
+ emptyIssuePrefixAlias: 'skip',
103
+ customIssuePrefixAlias: 'custom',
104
+ allowCustomIssuePrefix: true,
105
+ allowEmptyIssuePrefix: true,
106
+ confirmColorize: true,
107
+ // scopeOverrides: undefined,
108
+ defaultBody: '',
109
+ defaultIssues: '',
110
+ defaultScope: '',
111
+ defaultSubject: '',
112
+ } as CommitizenGitOptions,
113
+ })
@@ -0,0 +1,16 @@
1
+ // TypeScript version of the CSpell config.
2
+ // Requires Node.js >= 22.18 to run natively.
3
+ import { defineConfig } from 'cspell'
4
+
5
+ export default defineConfig({
6
+ version: '0.2',
7
+ dictionaryDefinitions: [
8
+ {
9
+ name: 'project-words',
10
+ path: './.cspell/project-words.txt',
11
+ addWords: true,
12
+ },
13
+ ],
14
+ dictionaries: ['project-words'],
15
+ ignorePaths: ['node_modules', './.cspell/project-words.txt'],
16
+ })
@@ -0,0 +1,52 @@
1
+ import js from '@eslint/js'
2
+ import globals from 'globals'
3
+ import tseslint from 'typescript-eslint'
4
+ import { defineConfig } from 'eslint/config'
5
+ import simpleImportSort from 'eslint-plugin-simple-import-sort'
6
+ import prettier from 'eslint-plugin-prettier'
7
+ import prettierConfig from 'eslint-config-prettier'
8
+
9
+ export default defineConfig([
10
+ {
11
+ files: ['**/*.{js,mjs,cjs,ts,mts,cts}'],
12
+ ignores: [
13
+ '**/dist/**',
14
+ 'node_modules/**',
15
+ '**/*.config.ts',
16
+ '**/packages/templates/**',
17
+ ],
18
+ plugins: {
19
+ 'simple-import-sort': simpleImportSort,
20
+ prettier: prettier,
21
+ },
22
+ rules: {
23
+ '@typescript-eslint/array-type': 'error',
24
+ '@typescript-eslint/no-for-in-array': 'error',
25
+ 'no-undef': 'warn',
26
+ 'no-unused-vars': 'error',
27
+ 'no-console': 'warn',
28
+ 'prettier/prettier': 'error',
29
+ ...prettierConfig.rules,
30
+
31
+ // "simple-import-sort/imports": [
32
+ // "error",
33
+ // ],
34
+ // "simple-import-sort/exports": [
35
+ // "error",
36
+ // ],
37
+ },
38
+ extends: [js.configs.recommended, ...tseslint.configs.recommended],
39
+ languageOptions: {
40
+ globals: {
41
+ ...globals.browser,
42
+ ...globals.node,
43
+ },
44
+ parser: tseslint.parser,
45
+ parserOptions: {
46
+ projects: ['eslint.config.ts', 'tsconfig.json'],
47
+ tsconfigRootDir: import.meta.dirname,
48
+ },
49
+ },
50
+ },
51
+ tseslint.configs.recommended,
52
+ ])
package/package.json CHANGED
@@ -1,40 +1,84 @@
1
1
  {
2
- "name": "react-nest-cli",
3
- "version": "1.0.2",
4
- "description": "一个脚手架工具,用于快速生成 react+nest 项目",
5
- "type": "module",
6
- "bin": {
7
- "react-nest": "./packages/cli/dist/index.js"
8
- },
9
- "main": "./packages/cli/dist/index.js",
10
- "scripts": {
11
- "build": "tsup",
12
- "start": "ts-node ./packages/cli/src/index.ts",
13
- "preview": "tsup && node ./packages/cli/dist/index.js"
14
- },
15
- "keywords": [
16
- "react",
17
- "nest",
18
- "脚手架"
19
- ],
20
- "author": "liaolonghui",
21
- "license": "ISC",
22
- "dependencies": {
23
- "commander": "^14.0.3",
24
- "consola": "^3.4.2",
25
- "figlet": "^1.10.0",
26
- "fs-extra": "^11.3.3",
27
- "giget": "^3.1.2",
28
- "ora": "^9.3.0",
29
- "picocolors": "^1.1.1",
30
- "prompts": "^2.4.2",
31
- "tsup": "^8.5.1"
32
- },
33
- "devDependencies": {
34
- "@types/fs-extra": "^11.0.4",
35
- "@types/node": "^25.2.1",
36
- "@types/prompts": "^2.4.9",
37
- "ts-node": "^10.9.2",
38
- "typescript": "^5.9.3"
39
- }
2
+ "name": "react-nest-cli",
3
+ "version": "1.0.4",
4
+ "description": "一个脚手架工具,用于快速生成 react+nest 项目",
5
+ "type": "module",
6
+ "packageManager": "pnpm@9.6.0",
7
+ "bin": {
8
+ "react-nest": "./packages/cli/dist/index.js"
9
+ },
10
+ "main": "./packages/cli/dist/index.js",
11
+ "scripts": {
12
+ "build": "tsup",
13
+ "start": "ts-node ./packages/cli/src/index.ts",
14
+ "preview": "tsup && node ./packages/cli/dist/index.js",
15
+ "commit": "git-cz",
16
+ "prepare": "husky",
17
+ "typecheck": "tsc --noEmit",
18
+ "lint": "eslint \"{packages,apps}/**/*.{js,jsx,ts,tsx}\"",
19
+ "format": "prettier --write .",
20
+ "spellcheck": "cspell lint --dot --gitignore --color --cache --show-suggestions \"(packages)/**/*.@(html|ts|js|tsx|jsx|css|scss|json|md)\"",
21
+ "graph": "madge --extensions ts --ts-config tsconfig.json packages/*/src"
22
+ },
23
+ "keywords": [
24
+ "react",
25
+ "nest",
26
+ "脚手架"
27
+ ],
28
+ "author": "liaolonghui",
29
+ "license": "ISC",
30
+ "config": {
31
+ "commitizen": {
32
+ "path": "node_modules/cz-git"
33
+ }
34
+ },
35
+ "lint-staged": {
36
+ "*.{json|md}": [
37
+ "prettier --cache --write --no-error-on-unmatched-pattern"
38
+ ],
39
+ "*.{js|jsx}": [
40
+ "eslint --fix",
41
+ "prettier --cache --write --no-error-on-unmatched-pattern"
42
+ ],
43
+ "*.{ts|tsx}": [
44
+ "eslint --fix",
45
+ "prettier --cache --parser=typescript --write"
46
+ ]
47
+ },
48
+ "dependencies": {
49
+ "commander": "^14.0.3",
50
+ "consola": "^3.4.2",
51
+ "figlet": "^1.10.0",
52
+ "fs-extra": "^11.3.3",
53
+ "giget": "^3.1.2",
54
+ "ora": "^9.3.0",
55
+ "picocolors": "^1.1.1",
56
+ "prompts": "^2.4.2",
57
+ "tsup": "^8.5.1"
58
+ },
59
+ "devDependencies": {
60
+ "@commitlint/cli": "^20.4.1",
61
+ "@commitlint/config-conventional": "^20.4.1",
62
+ "@eslint/js": "^10.0.1",
63
+ "@types/fs-extra": "^11.0.4",
64
+ "@types/node": "^25.2.1",
65
+ "@types/prompts": "^2.4.9",
66
+ "@typescript-eslint/eslint-plugin": "^8.54.0",
67
+ "commitizen": "^4.3.1",
68
+ "cspell": "^9.6.4",
69
+ "cz-git": "^1.12.0",
70
+ "eslint": "^10.0.0",
71
+ "eslint-config-prettier": "^10.1.8",
72
+ "eslint-plugin-prettier": "^5.5.5",
73
+ "eslint-plugin-simple-import-sort": "^12.1.1",
74
+ "globals": "^17.3.0",
75
+ "husky": "^9.1.7",
76
+ "lint-staged": "^16.2.7",
77
+ "madge": "^8.0.0",
78
+ "prettier": "^3.8.1",
79
+ "ts-node": "^10.9.2",
80
+ "turbo": "^2.8.3",
81
+ "typescript": "^5.9.3",
82
+ "typescript-eslint": "^8.54.0"
83
+ }
40
84
  }
@@ -2,14 +2,34 @@
2
2
 
3
3
  // packages/cli/src/index.ts
4
4
  import { program } from "commander";
5
- import picocolors from "picocolors";
6
- import figlet from "figlet";
7
- import prompts from "prompts";
5
+
6
+ // packages/cli/package.json
7
+ var package_default = {
8
+ name: "@react-nest/cli",
9
+ version: "1.0.4",
10
+ description: "\u4E00\u4E2A\u811A\u624B\u67B6\u5DE5\u5177\uFF0C\u7528\u4E8E\u5FEB\u901F\u751F\u6210 react+nest \u9879\u76EE",
11
+ main: "index.js",
12
+ type: "module",
13
+ scripts: {
14
+ test: 'echo "Error: no test specified" && exit 1'
15
+ },
16
+ keywords: [],
17
+ author: "",
18
+ license: "ISC"
19
+ };
20
+
21
+ // packages/cli/src/commands/baseRegisterCommands.ts
22
+ function baseRegisterCommands(program2) {
23
+ return function registerCommand2(fn) {
24
+ fn(program2);
25
+ };
26
+ }
27
+ var baseRegisterCommands_default = baseRegisterCommands;
28
+
29
+ // packages/cli/src/commands/base/info.ts
8
30
  import consola from "consola";
9
- import ora from "ora";
10
- import { downloadTemplate } from "giget";
11
- import path from "path";
12
- import fsExtra from "fs-extra";
31
+ import figlet from "figlet";
32
+ import picocolors from "picocolors";
13
33
 
14
34
  // packages/cli/src/configs/text.config.ts
15
35
  var text_config_default = {
@@ -20,6 +40,32 @@ var text_config_default = {
20
40
  whitespaceBreak: true
21
41
  };
22
42
 
43
+ // packages/cli/src/commands/base/info.ts
44
+ var logInfo = (program2) => {
45
+ console.log(
46
+ picocolors.yellow(figlet.textSync("React Nest CLI", text_config_default))
47
+ );
48
+ consola.start(picocolors.yellow(program2.description()));
49
+ consola.info(picocolors.yellow(program2.version()));
50
+ };
51
+ function info(program2) {
52
+ program2.command("info").description("\u8F93\u51FA\u9879\u76EE\u4FE1\u606F").action(() => logInfo(program2));
53
+ }
54
+
55
+ // packages/cli/src/commands/base/version.ts
56
+ import consola2 from "consola";
57
+ import figlet2 from "figlet";
58
+ function version(program2) {
59
+ program2.command("version").description("\u8F93\u51FA\u7248\u672C\u53F7").action(() => {
60
+ consola2.info(
61
+ figlet2.textSync(`version ==> ${program2.version()}`, text_config_default)
62
+ );
63
+ });
64
+ }
65
+
66
+ // packages/cli/src/commands/base/init.ts
67
+ import prompts from "prompts";
68
+
23
69
  // packages/cli/src/configs/prompts.config.ts
24
70
  var prompts_config_default = {
25
71
  templates: [
@@ -28,66 +74,71 @@ var prompts_config_default = {
28
74
  ]
29
75
  };
30
76
 
31
- // packages/cli/src/index.ts
32
- var logInfo = () => {
33
- console.info(picocolors.yellow(figlet.textSync("React Nest CLI", text_config_default)));
34
- consola.start(picocolors.yellow(program.description()));
35
- consola.info(picocolors.yellow(program.version()));
36
- };
37
- var packageJsonPath = path.resolve(import.meta.dirname, "../../../package.json");
38
- var packageJson = JSON.parse(fsExtra.readFileSync(packageJsonPath, "utf-8"));
39
- console.log(packageJsonPath, packageJson);
40
- program.version(packageJson.version, "-V, --version", "\u8F93\u51FA\u7248\u672C\u53F7").helpOption("-h, --help", "\u8F93\u51FA\u5E2E\u52A9\u4FE1\u606F").description(packageJson.description).action(logInfo);
41
- program.command("info").description("\u8F93\u51FA\u9879\u76EE\u4FE1\u606F").action(logInfo);
42
- program.command("init").description("\u521D\u59CB\u5316\u9879\u76EE").argument("[project-name]", "\u9879\u76EE\u540D\u79F0").option("--template <template-name>", "\u9879\u76EE\u6A21\u677F\u540D\u79F0").action(async (projectName, rest) => {
43
- let { template } = rest || {};
44
- if (!projectName) {
45
- const response = await prompts({
46
- type: "text",
47
- initial: "my-project",
48
- // 默认值
49
- name: "projectName",
50
- message: "\u8BF7\u8F93\u5165\u9879\u76EE\u540D\u79F0"
51
- // validate: value => value.length ? true : '请输入项目名称'
52
- });
53
- projectName = response.projectName;
54
- }
55
- const noTemplate = template && !prompts_config_default.templates.find((item) => item.value === template);
56
- if (!template || noTemplate) {
57
- if (noTemplate) {
58
- consola.error(`\u9879\u76EE\u6A21\u677F ${template} \u4E0D\u5B58\u5728, \u8BF7\u9009\u62E9\u5176\u4ED6\u6A21\u677F`);
77
+ // packages/cli/src/commands/base/init.ts
78
+ import consola3 from "consola";
79
+ import fsExtra from "fs-extra";
80
+ import path from "path";
81
+ import { cwd } from "process";
82
+ import { downloadTemplate } from "giget";
83
+ import ora from "ora";
84
+ function init(program2) {
85
+ program2.command("init").description("\u521D\u59CB\u5316\u9879\u76EE").argument("[project-name]", "\u9879\u76EE\u540D\u79F0").option("--template <template-name>", "\u9879\u76EE\u6A21\u677F\u540D\u79F0").action(async (projectName, rest) => {
86
+ let { template } = rest || {};
87
+ if (!projectName) {
88
+ const response = await prompts({
89
+ type: "text",
90
+ initial: "my-project",
91
+ // 默认值
92
+ name: "projectName",
93
+ message: "\u8BF7\u8F93\u5165\u9879\u76EE\u540D\u79F0"
94
+ // validate: value => value.length ? true : '请输入项目名称'
95
+ });
96
+ projectName = response.projectName;
59
97
  }
60
- const response = await prompts({
61
- type: "select",
62
- name: "template",
63
- message: "\u8BF7\u9009\u62E9\u9879\u76EE\u6A21\u677F",
64
- choices: prompts_config_default.templates,
65
- initial: 0
66
- // 默认选择第一个
98
+ const noTemplate = template && !prompts_config_default.templates.find((item) => item.value === template);
99
+ if (!template || noTemplate) {
100
+ if (noTemplate) {
101
+ consola3.error(`\u9879\u76EE\u6A21\u677F ${template} \u4E0D\u5B58\u5728, \u8BF7\u9009\u62E9\u5176\u4ED6\u6A21\u677F`);
102
+ }
103
+ const response = await prompts({
104
+ type: "select",
105
+ name: "template",
106
+ message: "\u8BF7\u9009\u62E9\u9879\u76EE\u6A21\u677F",
107
+ choices: prompts_config_default.templates,
108
+ initial: 0
109
+ // 默认选择第一个
110
+ });
111
+ template = response.template;
112
+ }
113
+ const tip = `\u521D\u59CB\u5316\u9879\u76EE ${projectName}\uFF0C\u6A21\u677F ${template}`;
114
+ const spinner = ora({
115
+ text: tip,
116
+ color: "blue"
117
+ // spinner: 'growVertical',
118
+ // isEnabled: false
67
119
  });
68
- template = response.template;
69
- }
70
- const tip = `\u521D\u59CB\u5316\u9879\u76EE ${projectName}\uFF0C\u6A21\u677F ${template}`;
71
- const spinner = ora({
72
- text: tip,
73
- color: "blue"
74
- // spinner: 'growVertical',
75
- // isEnabled: false
76
- });
77
- spinner.start();
78
- const projectDir = path.resolve(import.meta.dirname, projectName);
79
- if (fsExtra.existsSync(projectDir)) {
80
- spinner.fail(`\u{1F4A5}\u521D\u59CB\u5316\u5931\u8D25: \u9879\u76EE\u76EE\u5F55 ${projectName} \u5DF2\u5B58\u5728`);
81
- return;
82
- }
83
- const res = await downloadTemplate(`github:liaolonghui/react-nest-cli/packages/templates/${template}#main`, {
84
- dir: projectDir
120
+ spinner.start();
121
+ const projectDir = path.resolve(cwd(), projectName);
122
+ if (fsExtra.existsSync(projectDir)) {
123
+ spinner.fail(`\u{1F4A5}\u521D\u59CB\u5316\u5931\u8D25: \u9879\u76EE\u76EE\u5F55 ${projectName} \u5DF2\u5B58\u5728`);
124
+ return;
125
+ }
126
+ const res = await downloadTemplate(
127
+ `github:liaolonghui/react-nest-cli/packages/templates/${template}#main`,
128
+ {
129
+ dir: projectDir
130
+ }
131
+ );
132
+ const { dir } = res;
133
+ spinner.succeed(`\u9879\u76EE\u521D\u59CB\u5316\u6210\u529F\uFF0C\u9879\u76EE\u76EE\u5F55\uFF1A${dir}`);
85
134
  });
86
- const { dir } = res;
87
- spinner.succeed(`\u9879\u76EE\u521D\u59CB\u5316\u6210\u529F\uFF0C\u9879\u76EE\u76EE\u5F55\uFF1A${dir}`);
88
- });
89
- program.command("version").description("\u8F93\u51FA\u7248\u672C\u53F7").action(() => {
90
- consola.info(figlet.textSync(`version ==> ${program.version()}`, text_config_default));
91
- });
135
+ }
136
+
137
+ // packages/cli/src/index.ts
138
+ program.version(package_default.version, "-V, --version", "\u8F93\u51FA\u7248\u672C\u53F7").helpOption("-h, --help", "\u8F93\u51FA\u5E2E\u52A9\u4FE1\u606F").description(package_default.description).action(() => logInfo(program));
139
+ var registerCommand = baseRegisterCommands_default(program);
140
+ registerCommand(info);
141
+ registerCommand(init);
142
+ registerCommand(version);
92
143
  program.parse();
93
144
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/configs/text.config.ts","../src/configs/prompts.config.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { program } from \"commander\";\nimport picocolors from \"picocolors\"; // 也可用chalk\nimport figlet from 'figlet';\nimport prompts from 'prompts'; // 也可用inquirer、手动readline等\nimport consola from \"consola\";\nimport ora from 'ora';\nimport { downloadTemplate } from 'giget';\nimport path from 'node:path';\nimport fsExtra from 'fs-extra';\nimport textConfig from './configs/text.config.ts';\nimport promptsConfig from \"./configs/prompts.config.ts\";\n\n\n// 输出项目信息\nconst logInfo = () => {\n console.info(picocolors.yellow(figlet.textSync('React Nest CLI', textConfig)))\n consola.start(picocolors.yellow(program.description()))\n consola.info(picocolors.yellow(program.version()))\n}\n\nconst packageJsonPath = path.resolve(import.meta.dirname, '../../../package.json');\nconst packageJson = JSON.parse(fsExtra.readFileSync(packageJsonPath, 'utf-8'));\n\nconsole.log(packageJsonPath, packageJson);\n\nprogram\n .version(packageJson.version, '-V, --version', '输出版本号')\n .helpOption('-h, --help', '输出帮助信息')\n // .help((str) => '帮助信息:\\n' + str)\n .description(packageJson.description)\n .action(logInfo);\n\n// 输出项目信息\nprogram\n .command('info')\n .description('输出项目信息')\n .action(logInfo);\n\n// 初始化项目\nprogram\n .command('init')\n .description('初始化项目')\n .argument('[project-name]', '项目名称')\n .option('--template <template-name>', '项目模板名称')\n .action(async (projectName, rest) => {\n let { template } = rest || {};\n // 如果projectName没有提供,让用户输入\n if (!projectName) {\n const response = await prompts({\n type: 'text',\n initial: 'my-project', // 默认值\n name: 'projectName',\n message: '请输入项目名称',\n // validate: value => value.length ? true : '请输入项目名称'\n });\n projectName = response.projectName;\n }\n\n // 如果template没有提供或者template不存在,让用户选择\n const noTemplate = (template && !promptsConfig.templates.find(item => item.value === template));\n if (!template || noTemplate) {\n if (noTemplate) {\n consola.error(`项目模板 ${template} 不存在, 请选择其他模板`);\n }\n const response = await prompts({\n type: 'select',\n name: 'template',\n message: '请选择项目模板',\n choices: promptsConfig.templates,\n initial: 0, // 默认选择第一个\n });\n template = response.template;\n }\n\n const tip = `初始化项目 ${projectName},模板 ${template}`;\n const spinner = ora({\n text: tip,\n color: 'blue',\n // spinner: 'growVertical',\n // isEnabled: false\n });\n spinner.start();\n\n const projectDir = path.resolve(import.meta.dirname, projectName);\n if (fsExtra.existsSync(projectDir)) {\n spinner.fail(`💥初始化失败: 项目目录 ${projectName} 已存在`);\n return;\n }\n\n const res = await downloadTemplate(`github:liaolonghui/react-nest-cli/packages/templates/${template}#main`, {\n dir: projectDir,\n });\n const { dir } = res;\n spinner.succeed(`项目初始化成功,项目目录:${dir}`);\n // console.log(res);\n\n });\n\n// 输出版本号\nprogram.command('version')\n .description('输出版本号')\n .action(() => {\n // 全局option -V, --version 已被注册,这里无需再注册version命令,只是为了演示\n consola.info(figlet.textSync(`version ==> ${program.version()}`, textConfig));\n });\n\nprogram.parse();","import type { FigletOptions } from \"figlet\";\n\nexport default {\n font: \"Ghost\",\n horizontalLayout: \"default\",\n verticalLayout: \"default\",\n width: 200,\n whitespaceBreak: true,\n} as FigletOptions","\n\nexport default {\n templates: [\n { title: 'React + Nest', value: 'react-nest', description: '这个模板包含了 React + Nest 项目的基本配置', disabled: false },\n { title: 'React + Nest + TypeScript', value: 'react-nest-ts', description: '这个模板包含了 React + Nest + TypeScript 项目的基本配置', disabled: false },\n ]\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../package.json","../src/commands/baseRegisterCommands.ts","../src/commands/base/info.ts","../src/configs/text.config.ts","../src/commands/base/version.ts","../src/commands/base/init.ts","../src/configs/prompts.config.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { program } from 'commander'\nimport packageJson from '../package.json' with { type: 'json' }\nimport baseRegisterCommands from './commands/baseRegisterCommands.ts'\nimport info, { logInfo } from './commands/base/info.ts'\nimport version from './commands/base/version.ts'\nimport init from './commands/base/init.ts'\n\n// import.meta.dirname 指向当前文件所在目录\n// process.cwd() 指向当前工作目录 (实际运行时目录,不是当前文件所在目录)\n// const cwd = process.cwd();\n// const dirname = import.meta.dirname;\n\nprogram\n .version(packageJson.version, '-V, --version', '输出版本号')\n .helpOption('-h, --help', '输出帮助信息')\n // .help((str) => '帮助信息:\\n' + str)\n .description(packageJson.description)\n .action(() => logInfo(program))\n\nconst registerCommand = baseRegisterCommands(program)\n// 注册info命令\nregisterCommand(info)\n// 初始化项目命令\nregisterCommand(init)\n// 输出版本号命令\nregisterCommand(version)\n\nprogram.parse()\n","{\n \"name\": \"@react-nest/cli\",\n \"version\": \"1.0.4\",\n \"description\": \"一个脚手架工具,用于快速生成 react+nest 项目\",\n \"main\": \"index.js\",\n \"type\": \"module\",\n \"scripts\": {\n \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n },\n \"keywords\": [],\n \"author\": \"\",\n \"license\": \"ISC\"\n}\n","import type { Command } from 'commander'\n\nfunction baseRegisterCommands(program: Command) {\n return function registerCommand(fn: (program: Command) => void) {\n fn(program)\n }\n}\n\nexport default baseRegisterCommands\n","import type { Command } from 'commander'\nimport consola from 'consola'\nimport figlet from 'figlet'\nimport picocolors from 'picocolors'\nimport textConfig from '../../configs/text.config.ts'\n\n// 输出项目信息\nexport const logInfo = (program: Command) => {\n console.log(\n picocolors.yellow(figlet.textSync('React Nest CLI', textConfig))\n )\n consola.start(picocolors.yellow(program.description()))\n consola.info(picocolors.yellow(program.version()))\n}\n\nexport default function info(program: Command) {\n // 输出项目信息\n program\n .command('info')\n .description('输出项目信息')\n .action(() => logInfo(program))\n}\n","import type { FigletOptions } from \"figlet\";\n\nexport default {\n font: \"Ghost\",\n horizontalLayout: \"default\",\n verticalLayout: \"default\",\n width: 200,\n whitespaceBreak: true,\n} as FigletOptions","import type { Command } from 'commander'\nimport consola from 'consola'\nimport figlet from 'figlet'\nimport textConfig from '../../configs/text.config.ts'\n\nexport default function version(program: Command) {\n // 输出版本号\n program\n .command('version')\n .description('输出版本号')\n .action(() => {\n consola.info(\n figlet.textSync(`version ==> ${program.version()}`, textConfig)\n )\n })\n}\n","import type { Command } from 'commander'\nimport prompts from 'prompts'\nimport promptsConfig from '../../configs/prompts.config.ts'\nimport consola from 'consola'\nimport fsExtra from 'fs-extra'\nimport path from 'node:path'\nimport { cwd } from 'node:process'\nimport { downloadTemplate } from 'giget'\nimport ora from 'ora'\n\nexport default function init(program: Command) {\n program\n .command('init')\n .description('初始化项目')\n .argument('[project-name]', '项目名称')\n .option('--template <template-name>', '项目模板名称')\n .action(async (projectName, rest) => {\n let { template } = rest || {}\n // 如果projectName没有提供,让用户输入\n if (!projectName) {\n const response = await prompts({\n type: 'text',\n initial: 'my-project', // 默认值\n name: 'projectName',\n message: '请输入项目名称',\n // validate: value => value.length ? true : '请输入项目名称'\n })\n projectName = response.projectName\n }\n\n // 如果template没有提供或者template不存在,让用户选择\n const noTemplate =\n template &&\n !promptsConfig.templates.find((item) => item.value === template)\n if (!template || noTemplate) {\n if (noTemplate) {\n consola.error(`项目模板 ${template} 不存在, 请选择其他模板`)\n }\n const response = await prompts({\n type: 'select',\n name: 'template',\n message: '请选择项目模板',\n choices: promptsConfig.templates,\n initial: 0, // 默认选择第一个\n })\n template = response.template\n }\n\n const tip = `初始化项目 ${projectName},模板 ${template}`\n const spinner = ora({\n text: tip,\n color: 'blue',\n // spinner: 'growVertical',\n // isEnabled: false\n })\n spinner.start()\n\n const projectDir = path.resolve(cwd(), projectName)\n if (fsExtra.existsSync(projectDir)) {\n spinner.fail(`💥初始化失败: 项目目录 ${projectName} 已存在`)\n return\n }\n\n const res = await downloadTemplate(\n `github:liaolonghui/react-nest-cli/packages/templates/${template}#main`,\n {\n dir: projectDir,\n }\n )\n const { dir } = res\n spinner.succeed(`项目初始化成功,项目目录:${dir}`)\n // console.log(res);\n })\n}\n","\n\nexport default {\n templates: [\n { title: 'React + Nest', value: 'react-nest', description: '这个模板包含了 React + Nest 项目的基本配置', disabled: false },\n { title: 'React + Nest + TypeScript', value: 'react-nest-ts', description: '这个模板包含了 React + Nest + TypeScript 项目的基本配置', disabled: false },\n ]\n}"],"mappings":"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","names":["program","registerCommand","program","consola","figlet","program","consola","figlet","consola","program"]}
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "@react-nest/cli",
3
+ "version": "1.0.4",
4
+ "description": "一个脚手架工具,用于快速生成 react+nest 项目",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "test": "echo \"Error: no test specified\" && exit 1"
9
+ },
10
+ "keywords": [],
11
+ "author": "",
12
+ "license": "ISC"
13
+ }
@@ -0,0 +1,22 @@
1
+ import type { Command } from 'commander'
2
+ import consola from 'consola'
3
+ import figlet from 'figlet'
4
+ import picocolors from 'picocolors'
5
+ import textConfig from '../../configs/text.config.ts'
6
+
7
+ // 输出项目信息
8
+ export const logInfo = (program: Command) => {
9
+ console.log(
10
+ picocolors.yellow(figlet.textSync('React Nest CLI', textConfig))
11
+ )
12
+ consola.start(picocolors.yellow(program.description()))
13
+ consola.info(picocolors.yellow(program.version()))
14
+ }
15
+
16
+ export default function info(program: Command) {
17
+ // 输出项目信息
18
+ program
19
+ .command('info')
20
+ .description('输出项目信息')
21
+ .action(() => logInfo(program))
22
+ }
@@ -0,0 +1,74 @@
1
+ import type { Command } from 'commander'
2
+ import prompts from 'prompts'
3
+ import promptsConfig from '../../configs/prompts.config.ts'
4
+ import consola from 'consola'
5
+ import fsExtra from 'fs-extra'
6
+ import path from 'node:path'
7
+ import { cwd } from 'node:process'
8
+ import { downloadTemplate } from 'giget'
9
+ import ora from 'ora'
10
+
11
+ export default function init(program: Command) {
12
+ program
13
+ .command('init')
14
+ .description('初始化项目')
15
+ .argument('[project-name]', '项目名称')
16
+ .option('--template <template-name>', '项目模板名称')
17
+ .action(async (projectName, rest) => {
18
+ let { template } = rest || {}
19
+ // 如果projectName没有提供,让用户输入
20
+ if (!projectName) {
21
+ const response = await prompts({
22
+ type: 'text',
23
+ initial: 'my-project', // 默认值
24
+ name: 'projectName',
25
+ message: '请输入项目名称',
26
+ // validate: value => value.length ? true : '请输入项目名称'
27
+ })
28
+ projectName = response.projectName
29
+ }
30
+
31
+ // 如果template没有提供或者template不存在,让用户选择
32
+ const noTemplate =
33
+ template &&
34
+ !promptsConfig.templates.find((item) => item.value === template)
35
+ if (!template || noTemplate) {
36
+ if (noTemplate) {
37
+ consola.error(`项目模板 ${template} 不存在, 请选择其他模板`)
38
+ }
39
+ const response = await prompts({
40
+ type: 'select',
41
+ name: 'template',
42
+ message: '请选择项目模板',
43
+ choices: promptsConfig.templates,
44
+ initial: 0, // 默认选择第一个
45
+ })
46
+ template = response.template
47
+ }
48
+
49
+ const tip = `初始化项目 ${projectName},模板 ${template}`
50
+ const spinner = ora({
51
+ text: tip,
52
+ color: 'blue',
53
+ // spinner: 'growVertical',
54
+ // isEnabled: false
55
+ })
56
+ spinner.start()
57
+
58
+ const projectDir = path.resolve(cwd(), projectName)
59
+ if (fsExtra.existsSync(projectDir)) {
60
+ spinner.fail(`💥初始化失败: 项目目录 ${projectName} 已存在`)
61
+ return
62
+ }
63
+
64
+ const res = await downloadTemplate(
65
+ `github:liaolonghui/react-nest-cli/packages/templates/${template}#main`,
66
+ {
67
+ dir: projectDir,
68
+ }
69
+ )
70
+ const { dir } = res
71
+ spinner.succeed(`项目初始化成功,项目目录:${dir}`)
72
+ // console.log(res);
73
+ })
74
+ }
@@ -0,0 +1,16 @@
1
+ import type { Command } from 'commander'
2
+ import consola from 'consola'
3
+ import figlet from 'figlet'
4
+ import textConfig from '../../configs/text.config.ts'
5
+
6
+ export default function version(program: Command) {
7
+ // 输出版本号
8
+ program
9
+ .command('version')
10
+ .description('输出版本号')
11
+ .action(() => {
12
+ consola.info(
13
+ figlet.textSync(`version ==> ${program.version()}`, textConfig)
14
+ )
15
+ })
16
+ }
@@ -0,0 +1,9 @@
1
+ import type { Command } from 'commander'
2
+
3
+ function baseRegisterCommands(program: Command) {
4
+ return function registerCommand(fn: (program: Command) => void) {
5
+ fn(program)
6
+ }
7
+ }
8
+
9
+ export default baseRegisterCommands
@@ -1,108 +1,29 @@
1
1
  #!/usr/bin/env node
2
- import { program } from "commander";
3
- import picocolors from "picocolors"; // 也可用chalk
4
- import figlet from 'figlet';
5
- import prompts from 'prompts'; // 也可用inquirer、手动readline等
6
- import consola from "consola";
7
- import ora from 'ora';
8
- import { downloadTemplate } from 'giget';
9
- import path from 'node:path';
10
- import fsExtra from 'fs-extra';
11
- import textConfig from './configs/text.config.ts';
12
- import promptsConfig from "./configs/prompts.config.ts";
13
-
14
-
15
- // 输出项目信息
16
- const logInfo = () => {
17
- console.info(picocolors.yellow(figlet.textSync('React Nest CLI', textConfig)))
18
- consola.start(picocolors.yellow(program.description()))
19
- consola.info(picocolors.yellow(program.version()))
20
- }
21
-
22
- const packageJsonPath = path.resolve(import.meta.dirname, '../../../package.json');
23
- const packageJson = JSON.parse(fsExtra.readFileSync(packageJsonPath, 'utf-8'));
24
-
25
- console.log(packageJsonPath, packageJson);
2
+ import { program } from 'commander'
3
+ import packageJson from '../package.json' with { type: 'json' }
4
+ import baseRegisterCommands from './commands/baseRegisterCommands.ts'
5
+ import info, { logInfo } from './commands/base/info.ts'
6
+ import version from './commands/base/version.ts'
7
+ import init from './commands/base/init.ts'
8
+
9
+ // import.meta.dirname 指向当前文件所在目录
10
+ // process.cwd() 指向当前工作目录 (实际运行时目录,不是当前文件所在目录)
11
+ // const cwd = process.cwd();
12
+ // const dirname = import.meta.dirname;
26
13
 
27
14
  program
28
15
  .version(packageJson.version, '-V, --version', '输出版本号')
29
16
  .helpOption('-h, --help', '输出帮助信息')
30
17
  // .help((str) => '帮助信息:\n' + str)
31
18
  .description(packageJson.description)
32
- .action(logInfo);
33
-
34
- // 输出项目信息
35
- program
36
- .command('info')
37
- .description('输出项目信息')
38
- .action(logInfo);
39
-
40
- // 初始化项目
41
- program
42
- .command('init')
43
- .description('初始化项目')
44
- .argument('[project-name]', '项目名称')
45
- .option('--template <template-name>', '项目模板名称')
46
- .action(async (projectName, rest) => {
47
- let { template } = rest || {};
48
- // 如果projectName没有提供,让用户输入
49
- if (!projectName) {
50
- const response = await prompts({
51
- type: 'text',
52
- initial: 'my-project', // 默认值
53
- name: 'projectName',
54
- message: '请输入项目名称',
55
- // validate: value => value.length ? true : '请输入项目名称'
56
- });
57
- projectName = response.projectName;
58
- }
59
-
60
- // 如果template没有提供或者template不存在,让用户选择
61
- const noTemplate = (template && !promptsConfig.templates.find(item => item.value === template));
62
- if (!template || noTemplate) {
63
- if (noTemplate) {
64
- consola.error(`项目模板 ${template} 不存在, 请选择其他模板`);
65
- }
66
- const response = await prompts({
67
- type: 'select',
68
- name: 'template',
69
- message: '请选择项目模板',
70
- choices: promptsConfig.templates,
71
- initial: 0, // 默认选择第一个
72
- });
73
- template = response.template;
74
- }
75
-
76
- const tip = `初始化项目 ${projectName},模板 ${template}`;
77
- const spinner = ora({
78
- text: tip,
79
- color: 'blue',
80
- // spinner: 'growVertical',
81
- // isEnabled: false
82
- });
83
- spinner.start();
84
-
85
- const projectDir = path.resolve(import.meta.dirname, projectName);
86
- if (fsExtra.existsSync(projectDir)) {
87
- spinner.fail(`💥初始化失败: 项目目录 ${projectName} 已存在`);
88
- return;
89
- }
90
-
91
- const res = await downloadTemplate(`github:liaolonghui/react-nest-cli/packages/templates/${template}#main`, {
92
- dir: projectDir,
93
- });
94
- const { dir } = res;
95
- spinner.succeed(`项目初始化成功,项目目录:${dir}`);
96
- // console.log(res);
97
-
98
- });
19
+ .action(() => logInfo(program))
99
20
 
100
- // 输出版本号
101
- program.command('version')
102
- .description('输出版本号')
103
- .action(() => {
104
- // 全局option -V, --version 已被注册,这里无需再注册version命令,只是为了演示
105
- consola.info(figlet.textSync(`version ==> ${program.version()}`, textConfig));
106
- });
21
+ const registerCommand = baseRegisterCommands(program)
22
+ // 注册info命令
23
+ registerCommand(info)
24
+ // 初始化项目命令
25
+ registerCommand(init)
26
+ // 输出版本号命令
27
+ registerCommand(version)
107
28
 
108
- program.parse();
29
+ program.parse()
@@ -0,0 +1 @@
1
+ console.log('react-nest template')
@@ -0,0 +1 @@
1
+ console.log('react-nest-ts template')
@@ -0,0 +1,6 @@
1
+ export default {
2
+ trailingComma: 'es5',
3
+ tabWidth: 4,
4
+ semi: false,
5
+ singleQuote: true,
6
+ }
package/tsup.config.ts CHANGED
@@ -1,11 +1,17 @@
1
- import { defineConfig } from "tsup";
2
-
1
+ import { defineConfig } from 'tsup'
3
2
 
4
3
  export default defineConfig({
5
4
  entry: ['packages/cli/src/index.ts'],
6
5
  outDir: 'packages/cli/dist',
7
- format: ['esm'],
6
+ format: ['esm'], // ['cjs']
8
7
  dts: true,
9
8
  sourcemap: true,
10
9
  clean: true,
11
- })
10
+ splitting: true,
11
+ minify: false,
12
+ outExtension() {
13
+ return {
14
+ js: '.js',
15
+ }
16
+ },
17
+ })
package/turbo.json ADDED
File without changes