nsgm-cli 2.1.19 → 2.1.21
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/client/components/Button.tsx +3 -3
- package/client/components/ClientProviders.tsx +12 -12
- package/client/components/LanguageSwitcher.tsx +26 -26
- package/client/components/SSRSafeAntdProvider.tsx +7 -7
- package/client/components/SuppressHydrationWarnings.tsx +30 -30
- package/client/components/__tests__/Button.test.tsx +12 -12
- package/client/layout/index.tsx +124 -124
- package/client/redux/reducers.ts +2 -2
- package/client/redux/store.ts +24 -24
- package/client/redux/template/manage/actions.ts +40 -40
- package/client/redux/template/manage/reducers.ts +32 -32
- package/client/redux/template/manage/types.ts +19 -19
- package/client/service/template/manage.ts +29 -29
- package/client/styled/common.ts +6 -6
- package/client/styled/layout/index.ts +17 -17
- package/client/styled/template/manage.ts +19 -19
- package/client/utils/common.ts +54 -54
- package/client/utils/cookie.ts +30 -30
- package/client/utils/fetch.ts +111 -111
- package/client/utils/i18n.ts +41 -41
- package/client/utils/menu.tsx +12 -12
- package/client/utils/navigation.ts +22 -22
- package/client/utils/sso.ts +124 -124
- package/client/utils/suppressWarnings.ts +17 -17
- package/generation/prettierrc +6 -0
- package/lib/args.js +19 -19
- package/lib/cli/app.d.ts +1 -1
- package/lib/cli/app.js +2 -2
- package/lib/cli/commands/build.d.ts +1 -1
- package/lib/cli/commands/build.js +9 -9
- package/lib/cli/commands/create.d.ts +1 -1
- package/lib/cli/commands/create.js +36 -36
- package/lib/cli/commands/delete.d.ts +1 -1
- package/lib/cli/commands/delete.js +55 -55
- package/lib/cli/commands/export.d.ts +1 -1
- package/lib/cli/commands/export.js +12 -12
- package/lib/cli/commands/help.d.ts +1 -1
- package/lib/cli/commands/help.js +29 -29
- package/lib/cli/commands/init.d.ts +1 -1
- package/lib/cli/commands/init.js +31 -31
- package/lib/cli/commands/server.d.ts +1 -1
- package/lib/cli/commands/server.js +12 -12
- package/lib/cli/commands/upgrade.d.ts +1 -1
- package/lib/cli/commands/upgrade.js +13 -13
- package/lib/cli/commands/version.d.ts +1 -1
- package/lib/cli/commands/version.js +7 -7
- package/lib/cli/index.d.ts +13 -13
- package/lib/cli/parser.d.ts +1 -1
- package/lib/cli/parser.js +12 -12
- package/lib/cli/registry.d.ts +1 -1
- package/lib/cli/types.d.ts +2 -2
- package/lib/cli/utils/console.d.ts +2 -2
- package/lib/cli/utils/console.js +22 -22
- package/lib/cli/utils/index.d.ts +2 -2
- package/lib/cli/utils/prompt.d.ts +1 -1
- package/lib/cli/utils/prompt.js +98 -98
- package/lib/constants.js +28 -28
- package/lib/generate.d.ts +2 -2
- package/lib/generate.js +19 -19
- package/lib/generate_create.d.ts +1 -1
- package/lib/generate_create.js +38 -38
- package/lib/generate_delete.js +63 -63
- package/lib/generate_init.js +94 -94
- package/lib/generators/base-generator.d.ts +1 -1
- package/lib/generators/base-generator.js +23 -23
- package/lib/generators/file-generator.js +15 -15
- package/lib/generators/generator-factory.d.ts +5 -5
- package/lib/generators/i18n-generator.d.ts +1 -1
- package/lib/generators/i18n-generator.js +127 -127
- package/lib/generators/page-generator.d.ts +1 -1
- package/lib/generators/page-generator.js +25 -25
- package/lib/generators/resolver-generator.d.ts +1 -1
- package/lib/generators/resolver-generator.js +27 -27
- package/lib/generators/schema-generator.d.ts +1 -1
- package/lib/generators/schema-generator.js +4 -4
- package/lib/generators/service-generator.d.ts +1 -1
- package/lib/generators/service-generator.js +29 -29
- package/lib/generators/sql-generator.d.ts +1 -1
- package/lib/generators/sql-generator.js +10 -10
- package/lib/index.js +23 -23
- package/lib/server/csrf.d.ts +3 -3
- package/lib/server/csrf.js +20 -20
- package/lib/server/db.d.ts +1 -1
- package/lib/server/db.js +21 -21
- package/lib/server/graphql.js +26 -26
- package/lib/server/plugins/date.d.ts +1 -1
- package/lib/server/plugins/date.js +6 -6
- package/lib/server/utils/graphql-cache.js +5 -5
- package/lib/tsconfig.build.tsbuildinfo +1 -1
- package/lib/utils/project-config.d.ts +1 -1
- package/lib/utils/project-config.js +20 -20
- package/lib/utils.js +3 -3
- package/package.json +1 -1
- package/pages/_app.tsx +62 -62
- package/pages/_document.tsx +15 -15
- package/pages/_error.tsx +26 -26
- package/pages/index.tsx +48 -48
- package/pages/login.tsx +64 -64
- package/pages/template/manage.tsx +175 -175
package/lib/cli/utils/prompt.js
CHANGED
|
@@ -15,8 +15,8 @@ class Prompt {
|
|
|
15
15
|
*/
|
|
16
16
|
static async confirm(message, defaultValue = false) {
|
|
17
17
|
const { confirmed } = await inquirer_1.default.prompt({
|
|
18
|
-
type:
|
|
19
|
-
name:
|
|
18
|
+
type: "confirm",
|
|
19
|
+
name: "confirmed",
|
|
20
20
|
message,
|
|
21
21
|
default: defaultValue,
|
|
22
22
|
});
|
|
@@ -27,8 +27,8 @@ class Prompt {
|
|
|
27
27
|
*/
|
|
28
28
|
static async input(message, defaultValue, validate) {
|
|
29
29
|
const config = {
|
|
30
|
-
type:
|
|
31
|
-
name:
|
|
30
|
+
type: "input",
|
|
31
|
+
name: "value",
|
|
32
32
|
message,
|
|
33
33
|
validate: validate || (() => true),
|
|
34
34
|
};
|
|
@@ -43,8 +43,8 @@ class Prompt {
|
|
|
43
43
|
*/
|
|
44
44
|
static async password(message, validate) {
|
|
45
45
|
const { value } = await inquirer_1.default.prompt({
|
|
46
|
-
type:
|
|
47
|
-
name:
|
|
46
|
+
type: "password",
|
|
47
|
+
name: "value",
|
|
48
48
|
message,
|
|
49
49
|
validate: validate || (() => true),
|
|
50
50
|
});
|
|
@@ -55,8 +55,8 @@ class Prompt {
|
|
|
55
55
|
*/
|
|
56
56
|
static async select(message, choices) {
|
|
57
57
|
const { selected } = await inquirer_1.default.prompt({
|
|
58
|
-
type:
|
|
59
|
-
name:
|
|
58
|
+
type: "list",
|
|
59
|
+
name: "selected",
|
|
60
60
|
message,
|
|
61
61
|
choices,
|
|
62
62
|
});
|
|
@@ -67,8 +67,8 @@ class Prompt {
|
|
|
67
67
|
*/
|
|
68
68
|
static async multiSelect(message, choices) {
|
|
69
69
|
const { selected } = await inquirer_1.default.prompt({
|
|
70
|
-
type:
|
|
71
|
-
name:
|
|
70
|
+
type: "checkbox",
|
|
71
|
+
name: "selected",
|
|
72
72
|
message,
|
|
73
73
|
choices,
|
|
74
74
|
});
|
|
@@ -84,41 +84,41 @@ class Prompt {
|
|
|
84
84
|
* 项目初始化向导
|
|
85
85
|
*/
|
|
86
86
|
static async initWizard() {
|
|
87
|
-
console_1.Console.title(
|
|
87
|
+
console_1.Console.title("🚀 NSGM 项目初始化向导");
|
|
88
88
|
console_1.Console.newLine();
|
|
89
89
|
const answers = await inquirer_1.default.prompt([
|
|
90
90
|
{
|
|
91
|
-
type:
|
|
92
|
-
name:
|
|
93
|
-
message:
|
|
94
|
-
default:
|
|
91
|
+
type: "input",
|
|
92
|
+
name: "projectName",
|
|
93
|
+
message: "项目目录:",
|
|
94
|
+
default: "my-nsgm-project",
|
|
95
95
|
validate: (input) => {
|
|
96
96
|
if (!input.trim())
|
|
97
|
-
return
|
|
97
|
+
return "项目目录不能为空";
|
|
98
98
|
// 允许路径格式,包括相对路径和绝对路径
|
|
99
99
|
if (!/^[a-zA-Z0-9\-_./\\]+$/.test(input))
|
|
100
|
-
return
|
|
100
|
+
return "项目目录只能包含字母、数字、横线、下划线和路径分隔符";
|
|
101
101
|
return true;
|
|
102
102
|
},
|
|
103
103
|
},
|
|
104
104
|
{
|
|
105
|
-
type:
|
|
106
|
-
name:
|
|
107
|
-
message:
|
|
108
|
-
default:
|
|
105
|
+
type: "input",
|
|
106
|
+
name: "description",
|
|
107
|
+
message: "项目描述:",
|
|
108
|
+
default: "A NSGM fullstack project",
|
|
109
109
|
},
|
|
110
110
|
{
|
|
111
|
-
type:
|
|
112
|
-
name:
|
|
113
|
-
message:
|
|
114
|
-
default:
|
|
111
|
+
type: "input",
|
|
112
|
+
name: "author",
|
|
113
|
+
message: "作者:",
|
|
114
|
+
default: "Your Name",
|
|
115
115
|
},
|
|
116
116
|
]);
|
|
117
117
|
// 设置默认配置
|
|
118
118
|
const result = {
|
|
119
119
|
...answers,
|
|
120
120
|
database: true,
|
|
121
|
-
features: [
|
|
121
|
+
features: ["nextjs", "styled-components", "graphql", "mysql", "typescript", "eslint"],
|
|
122
122
|
};
|
|
123
123
|
return result;
|
|
124
124
|
}
|
|
@@ -126,47 +126,47 @@ class Prompt {
|
|
|
126
126
|
* 控制器创建向导
|
|
127
127
|
*/
|
|
128
128
|
static async createControllerWizard() {
|
|
129
|
-
console_1.Console.title(
|
|
129
|
+
console_1.Console.title("📝 创建控制器向导 (包含完整CRUD + 导入导出 + 批量删除功能)");
|
|
130
130
|
console_1.Console.newLine();
|
|
131
131
|
const answers = await inquirer_1.default.prompt([
|
|
132
132
|
{
|
|
133
|
-
type:
|
|
134
|
-
name:
|
|
135
|
-
message:
|
|
136
|
-
default:
|
|
133
|
+
type: "input",
|
|
134
|
+
name: "dictionary",
|
|
135
|
+
message: "项目目录:",
|
|
136
|
+
default: ".",
|
|
137
137
|
validate: (input) => {
|
|
138
138
|
if (!input.trim())
|
|
139
|
-
return
|
|
139
|
+
return "项目目录不能为空";
|
|
140
140
|
return true;
|
|
141
141
|
},
|
|
142
142
|
},
|
|
143
143
|
{
|
|
144
|
-
type:
|
|
145
|
-
name:
|
|
146
|
-
message:
|
|
144
|
+
type: "input",
|
|
145
|
+
name: "controller",
|
|
146
|
+
message: "控制器名称:",
|
|
147
147
|
validate: (input) => {
|
|
148
148
|
if (!input.trim())
|
|
149
|
-
return
|
|
149
|
+
return "控制器名称不能为空";
|
|
150
150
|
if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(input))
|
|
151
|
-
return
|
|
151
|
+
return "控制器名称必须以字母开头,只能包含字母和数字";
|
|
152
152
|
return true;
|
|
153
153
|
},
|
|
154
154
|
},
|
|
155
155
|
{
|
|
156
|
-
type:
|
|
157
|
-
name:
|
|
158
|
-
message:
|
|
156
|
+
type: "input",
|
|
157
|
+
name: "description",
|
|
158
|
+
message: "控制器描述:",
|
|
159
159
|
default: (answers) => `${answers.controller} 控制器`,
|
|
160
160
|
},
|
|
161
161
|
{
|
|
162
|
-
type:
|
|
163
|
-
name:
|
|
164
|
-
message:
|
|
162
|
+
type: "confirm",
|
|
163
|
+
name: "useCustomFields",
|
|
164
|
+
message: "是否自定义字段配置?(默认字段: id, name, create_date, update_date)",
|
|
165
165
|
default: false,
|
|
166
166
|
},
|
|
167
167
|
]);
|
|
168
168
|
// 设置默认action为manage(包含完整的CRUD + 导入 + 导出 + 批量删除功能)
|
|
169
|
-
answers.action =
|
|
169
|
+
answers.action = "manage";
|
|
170
170
|
answers.includeDatabase = true;
|
|
171
171
|
if (answers.useCustomFields) {
|
|
172
172
|
// 如果用户选择自定义字段,收集字段定义
|
|
@@ -175,19 +175,19 @@ class Prompt {
|
|
|
175
175
|
else {
|
|
176
176
|
// 使用默认字段配置
|
|
177
177
|
answers.fields = [
|
|
178
|
-
{ name:
|
|
178
|
+
{ name: "id", type: "integer", required: true, comment: "主键", isPrimaryKey: true, isAutoIncrement: true },
|
|
179
179
|
{
|
|
180
|
-
name:
|
|
181
|
-
type:
|
|
180
|
+
name: "name",
|
|
181
|
+
type: "varchar",
|
|
182
182
|
length: 100,
|
|
183
183
|
required: true,
|
|
184
|
-
comment:
|
|
184
|
+
comment: "名称",
|
|
185
185
|
showInList: true,
|
|
186
186
|
showInForm: true,
|
|
187
187
|
searchable: true,
|
|
188
188
|
},
|
|
189
|
-
{ name:
|
|
190
|
-
{ name:
|
|
189
|
+
{ name: "create_date", type: "timestamp", required: true, comment: "创建时间", isSystemField: true },
|
|
190
|
+
{ name: "update_date", type: "timestamp", required: true, comment: "更新时间", isSystemField: true },
|
|
191
191
|
];
|
|
192
192
|
}
|
|
193
193
|
return answers;
|
|
@@ -199,14 +199,14 @@ class Prompt {
|
|
|
199
199
|
const fields = [];
|
|
200
200
|
// 默认添加ID字段
|
|
201
201
|
fields.push({
|
|
202
|
-
name:
|
|
203
|
-
type:
|
|
202
|
+
name: "id",
|
|
203
|
+
type: "integer",
|
|
204
204
|
required: true,
|
|
205
|
-
comment:
|
|
205
|
+
comment: "主键",
|
|
206
206
|
isPrimaryKey: true,
|
|
207
207
|
isAutoIncrement: true,
|
|
208
208
|
});
|
|
209
|
-
console_1.Console.info(
|
|
209
|
+
console_1.Console.info("💡 输入字段信息,输入空白字段名结束添加");
|
|
210
210
|
let fieldIndex = 1;
|
|
211
211
|
while (true) {
|
|
212
212
|
const fieldName = await this.input(`字段${fieldIndex} 名称 (留空结束):`);
|
|
@@ -214,34 +214,34 @@ class Prompt {
|
|
|
214
214
|
break;
|
|
215
215
|
// 验证字段名
|
|
216
216
|
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(fieldName)) {
|
|
217
|
-
console_1.Console.error(
|
|
217
|
+
console_1.Console.error("字段名称格式无效,请重新输入");
|
|
218
218
|
continue;
|
|
219
219
|
}
|
|
220
|
-
if (fields.some((f) => f.name === fieldName) || [
|
|
221
|
-
console_1.Console.error(
|
|
220
|
+
if (fields.some((f) => f.name === fieldName) || ["create_date", "update_date"].includes(fieldName)) {
|
|
221
|
+
console_1.Console.error("字段名称已存在或为系统保留字段,请重新输入");
|
|
222
222
|
continue;
|
|
223
223
|
}
|
|
224
224
|
// 简化的字段类型选择
|
|
225
|
-
const fieldType = await this.select(
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
225
|
+
const fieldType = await this.select("字段类型:", [
|
|
226
|
+
"varchar",
|
|
227
|
+
"text",
|
|
228
|
+
"integer",
|
|
229
|
+
"decimal",
|
|
230
|
+
"boolean",
|
|
231
|
+
"date",
|
|
232
|
+
"datetime",
|
|
233
233
|
]);
|
|
234
234
|
// 只对需要长度的类型询问长度
|
|
235
235
|
let length;
|
|
236
|
-
if (fieldType ===
|
|
237
|
-
length = await this.input(
|
|
236
|
+
if (fieldType === "varchar") {
|
|
237
|
+
length = await this.input("字符串长度:", "255");
|
|
238
238
|
}
|
|
239
|
-
else if (fieldType ===
|
|
240
|
-
length = await this.input(
|
|
239
|
+
else if (fieldType === "decimal") {
|
|
240
|
+
length = await this.input("小数精度 (如: 10,2):", "10,2");
|
|
241
241
|
}
|
|
242
242
|
// 简化配置:只询问是否必填和注释
|
|
243
|
-
const required = await this.confirm(
|
|
244
|
-
const comment = await this.input(
|
|
243
|
+
const required = await this.confirm("是否必填:", true);
|
|
244
|
+
const comment = await this.input("字段注释:", fieldName);
|
|
245
245
|
const field = {
|
|
246
246
|
name: fieldName,
|
|
247
247
|
type: fieldType,
|
|
@@ -249,7 +249,7 @@ class Prompt {
|
|
|
249
249
|
comment,
|
|
250
250
|
showInList: true, // 默认在列表显示
|
|
251
251
|
showInForm: true, // 默认在表单显示
|
|
252
|
-
searchable: fieldType ===
|
|
252
|
+
searchable: fieldType === "varchar", // varchar类型默认可搜索
|
|
253
253
|
};
|
|
254
254
|
// 只有当length有值时才添加
|
|
255
255
|
if (length) {
|
|
@@ -260,16 +260,16 @@ class Prompt {
|
|
|
260
260
|
}
|
|
261
261
|
// 自动添加系统字段
|
|
262
262
|
fields.push({
|
|
263
|
-
name:
|
|
264
|
-
type:
|
|
263
|
+
name: "create_date",
|
|
264
|
+
type: "timestamp",
|
|
265
265
|
required: true,
|
|
266
|
-
comment:
|
|
266
|
+
comment: "创建时间",
|
|
267
267
|
isSystemField: true,
|
|
268
268
|
}, {
|
|
269
|
-
name:
|
|
270
|
-
type:
|
|
269
|
+
name: "update_date",
|
|
270
|
+
type: "timestamp",
|
|
271
271
|
required: true,
|
|
272
|
-
comment:
|
|
272
|
+
comment: "更新时间",
|
|
273
273
|
isSystemField: true,
|
|
274
274
|
});
|
|
275
275
|
return fields;
|
|
@@ -278,46 +278,46 @@ class Prompt {
|
|
|
278
278
|
* 控制器删除向导
|
|
279
279
|
*/
|
|
280
280
|
static async deleteControllerWizard() {
|
|
281
|
-
console_1.Console.title(
|
|
281
|
+
console_1.Console.title("🗑️ 删除控制器向导");
|
|
282
282
|
console_1.Console.newLine();
|
|
283
283
|
const answers = await inquirer_1.default.prompt([
|
|
284
284
|
{
|
|
285
|
-
type:
|
|
286
|
-
name:
|
|
287
|
-
message:
|
|
288
|
-
default:
|
|
285
|
+
type: "input",
|
|
286
|
+
name: "dictionary",
|
|
287
|
+
message: "项目目录:",
|
|
288
|
+
default: ".",
|
|
289
289
|
validate: (input) => {
|
|
290
290
|
if (!input.trim())
|
|
291
|
-
return
|
|
291
|
+
return "项目目录不能为空";
|
|
292
292
|
return true;
|
|
293
293
|
},
|
|
294
294
|
},
|
|
295
295
|
{
|
|
296
|
-
type:
|
|
297
|
-
name:
|
|
298
|
-
message:
|
|
296
|
+
type: "input",
|
|
297
|
+
name: "controller",
|
|
298
|
+
message: "控制器名称:",
|
|
299
299
|
validate: (input) => {
|
|
300
300
|
if (!input.trim())
|
|
301
|
-
return
|
|
301
|
+
return "控制器名称不能为空";
|
|
302
302
|
if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(input))
|
|
303
|
-
return
|
|
303
|
+
return "控制器名称必须以字母开头,只能包含字母和数字";
|
|
304
304
|
return true;
|
|
305
305
|
},
|
|
306
306
|
},
|
|
307
307
|
{
|
|
308
|
-
type:
|
|
309
|
-
name:
|
|
310
|
-
message:
|
|
308
|
+
type: "list",
|
|
309
|
+
name: "action",
|
|
310
|
+
message: "删除范围:",
|
|
311
311
|
choices: [
|
|
312
|
-
{ name:
|
|
313
|
-
{ name:
|
|
312
|
+
{ name: "删除所有相关文件", value: "all" },
|
|
313
|
+
{ name: "仅删除指定操作", value: "manage" },
|
|
314
314
|
],
|
|
315
|
-
default:
|
|
315
|
+
default: "all",
|
|
316
316
|
},
|
|
317
317
|
{
|
|
318
|
-
type:
|
|
319
|
-
name:
|
|
320
|
-
message:
|
|
318
|
+
type: "confirm",
|
|
319
|
+
name: "deleteDatabase",
|
|
320
|
+
message: "是否同时删除数据库表?",
|
|
321
321
|
default: false,
|
|
322
322
|
},
|
|
323
323
|
]);
|
package/lib/constants.js
CHANGED
|
@@ -54,61 +54,61 @@ exports.mysqlPassword = mysqlPassword;
|
|
|
54
54
|
exports.mysqlHost = mysqlHost;
|
|
55
55
|
exports.mysqlPort = mysqlPort;
|
|
56
56
|
exports.mysqlDatabase = mysqlDatabase;
|
|
57
|
-
const generationPath =
|
|
57
|
+
const generationPath = "../generation";
|
|
58
58
|
exports.generationPath = generationPath;
|
|
59
|
-
const clientPathSource =
|
|
59
|
+
const clientPathSource = "../client";
|
|
60
60
|
exports.clientPathSource = clientPathSource;
|
|
61
|
-
const clientPath =
|
|
61
|
+
const clientPath = "./client";
|
|
62
62
|
exports.clientPath = clientPath;
|
|
63
|
-
const serverPathSource =
|
|
63
|
+
const serverPathSource = "../server";
|
|
64
64
|
exports.serverPathSource = serverPathSource;
|
|
65
|
-
const serverPath =
|
|
65
|
+
const serverPath = "./server";
|
|
66
66
|
exports.serverPath = serverPath;
|
|
67
|
-
const pagesPathSource =
|
|
67
|
+
const pagesPathSource = "../pages";
|
|
68
68
|
exports.pagesPathSource = pagesPathSource;
|
|
69
|
-
const pagesPath =
|
|
69
|
+
const pagesPath = "./pages";
|
|
70
70
|
exports.pagesPath = pagesPath;
|
|
71
|
-
const publicPathSource =
|
|
71
|
+
const publicPathSource = "../public";
|
|
72
72
|
exports.publicPathSource = publicPathSource;
|
|
73
|
-
const publicPath =
|
|
73
|
+
const publicPath = "./public";
|
|
74
74
|
exports.publicPath = publicPath;
|
|
75
|
-
const scriptsPathSource =
|
|
75
|
+
const scriptsPathSource = "../scripts";
|
|
76
76
|
exports.scriptsPathSource = scriptsPathSource;
|
|
77
|
-
const scriptsPath =
|
|
77
|
+
const scriptsPath = "./scripts";
|
|
78
78
|
exports.scriptsPath = scriptsPath;
|
|
79
|
-
const typesPathSource =
|
|
79
|
+
const typesPathSource = "../types";
|
|
80
80
|
exports.typesPathSource = typesPathSource;
|
|
81
|
-
const typesPath =
|
|
81
|
+
const typesPath = "./types";
|
|
82
82
|
exports.typesPath = typesPath;
|
|
83
|
-
const reduxPath =
|
|
83
|
+
const reduxPath = "/redux";
|
|
84
84
|
exports.reduxPath = reduxPath;
|
|
85
|
-
const servicePath =
|
|
85
|
+
const servicePath = "/service";
|
|
86
86
|
exports.servicePath = servicePath;
|
|
87
|
-
const styledPath =
|
|
87
|
+
const styledPath = "/styled";
|
|
88
88
|
exports.styledPath = styledPath;
|
|
89
|
-
const styledLayoutPath =
|
|
89
|
+
const styledLayoutPath = "/layout";
|
|
90
90
|
exports.styledLayoutPath = styledLayoutPath;
|
|
91
|
-
const utilsPath =
|
|
91
|
+
const utilsPath = "/utils";
|
|
92
92
|
exports.utilsPath = utilsPath;
|
|
93
|
-
const layoutPath =
|
|
93
|
+
const layoutPath = "/layout";
|
|
94
94
|
exports.layoutPath = layoutPath;
|
|
95
|
-
const componentsPath =
|
|
95
|
+
const componentsPath = "/components";
|
|
96
96
|
exports.componentsPath = componentsPath;
|
|
97
|
-
const modulesPath =
|
|
97
|
+
const modulesPath = "/modules";
|
|
98
98
|
exports.modulesPath = modulesPath;
|
|
99
|
-
const apisPath =
|
|
99
|
+
const apisPath = "/apis";
|
|
100
100
|
exports.apisPath = apisPath;
|
|
101
|
-
const sqlPath =
|
|
101
|
+
const sqlPath = "/sql";
|
|
102
102
|
exports.sqlPath = sqlPath;
|
|
103
|
-
const utilsMenuPath =
|
|
103
|
+
const utilsMenuPath = "/menu.tsx";
|
|
104
104
|
exports.utilsMenuPath = utilsMenuPath;
|
|
105
|
-
const reduxReducersPath =
|
|
105
|
+
const reduxReducersPath = "/reducers.ts";
|
|
106
106
|
exports.reduxReducersPath = reduxReducersPath;
|
|
107
|
-
const slbHealthCheckPath =
|
|
107
|
+
const slbHealthCheckPath = "/slbhealthcheck.html";
|
|
108
108
|
exports.slbHealthCheckPath = slbHealthCheckPath;
|
|
109
|
-
const packagePath =
|
|
109
|
+
const packagePath = "/package.json";
|
|
110
110
|
exports.packagePath = packagePath;
|
|
111
|
-
const restPath =
|
|
111
|
+
const restPath = "/rest.js";
|
|
112
112
|
exports.restPath = restPath;
|
|
113
113
|
const sourceGenerationPath = path_1.default.join(sourceFolder, generationPath);
|
|
114
114
|
exports.sourceGenerationPath = sourceGenerationPath;
|
package/lib/generate.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ProjectConfig } from
|
|
2
|
-
import { FieldDefinition } from
|
|
1
|
+
import { ProjectConfig } from "./cli/types/project";
|
|
2
|
+
import { FieldDefinition } from "./cli/utils/prompt";
|
|
3
3
|
/**
|
|
4
4
|
* 初始化项目文件和目录结构
|
|
5
5
|
* @param dictionary 目标目录名称,空字符串表示当前目录
|
package/lib/generate.js
CHANGED
|
@@ -13,24 +13,24 @@ const generate_init_1 = require("./generate_init");
|
|
|
13
13
|
const generate_create_1 = require("./generate_create");
|
|
14
14
|
const generate_delete_1 = require("./generate_delete");
|
|
15
15
|
// 常量提取
|
|
16
|
-
const NPM_INSTALL_FLAGS =
|
|
16
|
+
const NPM_INSTALL_FLAGS = "--legacy-peer-deps";
|
|
17
17
|
// 辅助函数
|
|
18
18
|
const normalizeDirectory = (dictionary) => {
|
|
19
19
|
// 禁止绝对路径,强制所有生成目录都在 cwd 下
|
|
20
|
-
if (!dictionary || dictionary ===
|
|
21
|
-
return
|
|
20
|
+
if (!dictionary || dictionary === "/" || dictionary.trim() === "") {
|
|
21
|
+
return ".";
|
|
22
22
|
}
|
|
23
23
|
return dictionary.trim();
|
|
24
24
|
};
|
|
25
25
|
const installNpmPackages = (targetDir) => {
|
|
26
26
|
try {
|
|
27
|
-
const prefix = targetDir ? `cd ${targetDir} && ` :
|
|
28
|
-
console.log(
|
|
27
|
+
const prefix = targetDir ? `cd ${targetDir} && ` : "";
|
|
28
|
+
console.log("Installing all dependencies from package.json...");
|
|
29
29
|
const installResult = shelljs_1.default.exec(`${prefix}npm install ${NPM_INSTALL_FLAGS}`);
|
|
30
30
|
return installResult.code === 0;
|
|
31
31
|
}
|
|
32
32
|
catch (error) {
|
|
33
|
-
console.error(
|
|
33
|
+
console.error("Failed to install npm packages:", error);
|
|
34
34
|
return false;
|
|
35
35
|
}
|
|
36
36
|
};
|
|
@@ -39,13 +39,13 @@ const updateProjectFiles = (projectName, destPackagePath, destPublicHealthCheckP
|
|
|
39
39
|
const cleanProjectName = path_1.default.basename(projectName);
|
|
40
40
|
if (!skipPackageUpdate) {
|
|
41
41
|
console.log(`Updating project name to: ${cleanProjectName}`);
|
|
42
|
-
shelljs_1.default.sed(
|
|
42
|
+
shelljs_1.default.sed("-i", /nsgm-cli-project/g, `${cleanProjectName}-project`, destPackagePath);
|
|
43
43
|
}
|
|
44
|
-
shelljs_1.default.sed(
|
|
44
|
+
shelljs_1.default.sed("-i", /NSGM-CLI/g, cleanProjectName, destPublicHealthCheckPath);
|
|
45
45
|
return true;
|
|
46
46
|
}
|
|
47
47
|
catch (error) {
|
|
48
|
-
console.error(
|
|
48
|
+
console.error("Failed to update project files:", error);
|
|
49
49
|
return false;
|
|
50
50
|
}
|
|
51
51
|
};
|
|
@@ -61,11 +61,11 @@ const initFiles = (dictionary, upgradeFlag = false, projectConfig) => {
|
|
|
61
61
|
}
|
|
62
62
|
const normalizedDictionary = normalizeDirectory(dictionary);
|
|
63
63
|
let newDestFolder = constants_1.destFolder;
|
|
64
|
-
if (normalizedDictionary !==
|
|
64
|
+
if (normalizedDictionary !== ".") {
|
|
65
65
|
newDestFolder = path_1.default.join(constants_1.destFolder, normalizedDictionary);
|
|
66
66
|
(0, utils_1.mkdirSync)(newDestFolder);
|
|
67
67
|
}
|
|
68
|
-
console.log(
|
|
68
|
+
console.log("initFiles", normalizedDictionary === "." ? "." : normalizedDictionary, upgradeFlag);
|
|
69
69
|
(0, generate_init_1.initClientFiles)(normalizedDictionary, newDestFolder, upgradeFlag);
|
|
70
70
|
(0, generate_init_1.initPagesFiles)(normalizedDictionary, newDestFolder, upgradeFlag);
|
|
71
71
|
(0, generate_init_1.initServerFiles)(normalizedDictionary, newDestFolder, upgradeFlag);
|
|
@@ -76,21 +76,21 @@ const initFiles = (dictionary, upgradeFlag = false, projectConfig) => {
|
|
|
76
76
|
(0, generate_init_1.initTypesFiles)(normalizedDictionary, newDestFolder);
|
|
77
77
|
// 如果提供了项目配置,应用到生成的文件中
|
|
78
78
|
if (projectConfig) {
|
|
79
|
-
console.log(
|
|
79
|
+
console.log("应用项目配置...");
|
|
80
80
|
(0, project_config_1.applyProjectConfig)(newDestFolder, projectConfig);
|
|
81
81
|
}
|
|
82
|
-
const installFlag = !upgradeFlag && (!constants_1.isLocal || dictionary.indexOf(
|
|
82
|
+
const installFlag = !upgradeFlag && (!constants_1.isLocal || dictionary.indexOf("..") !== -1);
|
|
83
83
|
if (installFlag) {
|
|
84
|
-
const projectName = normalizedDictionary !==
|
|
84
|
+
const projectName = normalizedDictionary !== "." ? normalizedDictionary : path_1.default.basename(constants_1.destFolder);
|
|
85
85
|
// 如果有项目配置,跳过 package.json 的默认更新,因为 applyProjectConfig 已经处理了
|
|
86
86
|
const skipPackageUpdate = !!projectConfig;
|
|
87
87
|
const updateSuccess = updateProjectFiles(projectName, destPackagePath, destPublicHealthCheckPath, skipPackageUpdate);
|
|
88
|
-
const installSuccess = installNpmPackages(normalizedDictionary !==
|
|
88
|
+
const installSuccess = installNpmPackages(normalizedDictionary !== "." ? normalizedDictionary : undefined);
|
|
89
89
|
if (!updateSuccess || !installSuccess) {
|
|
90
|
-
console.warn(
|
|
90
|
+
console.warn("Some operations failed during project initialization");
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
|
-
console.log(
|
|
93
|
+
console.log("initFiles finished");
|
|
94
94
|
};
|
|
95
95
|
exports.initFiles = initFiles;
|
|
96
96
|
/**
|
|
@@ -100,7 +100,7 @@ exports.initFiles = initFiles;
|
|
|
100
100
|
* @param dictionary 目标目录名称,空字符串表示当前目录
|
|
101
101
|
* @param fields 字段定义数组
|
|
102
102
|
*/
|
|
103
|
-
const createFiles = (controller, action, dictionary =
|
|
103
|
+
const createFiles = (controller, action, dictionary = "", fields) => {
|
|
104
104
|
const normalizedDictionary = normalizeDirectory(dictionary);
|
|
105
105
|
(0, generate_create_1.createFiles)(controller, action, normalizedDictionary, fields);
|
|
106
106
|
};
|
|
@@ -112,7 +112,7 @@ exports.createFiles = createFiles;
|
|
|
112
112
|
* @param deleteDBFlag 是否删除数据库相关文件
|
|
113
113
|
* @param dictionary 目标目录名称,空字符串表示当前目录
|
|
114
114
|
*/
|
|
115
|
-
const deleteFiles = (controller, action, deleteDBFlag = false, dictionary =
|
|
115
|
+
const deleteFiles = (controller, action, deleteDBFlag = false, dictionary = "") => {
|
|
116
116
|
const normalizedDictionary = normalizeDirectory(dictionary);
|
|
117
117
|
(0, generate_delete_1.deleteFiles)(controller, action, deleteDBFlag, normalizedDictionary);
|
|
118
118
|
};
|
package/lib/generate_create.d.ts
CHANGED