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.
Files changed (99) hide show
  1. package/client/components/Button.tsx +3 -3
  2. package/client/components/ClientProviders.tsx +12 -12
  3. package/client/components/LanguageSwitcher.tsx +26 -26
  4. package/client/components/SSRSafeAntdProvider.tsx +7 -7
  5. package/client/components/SuppressHydrationWarnings.tsx +30 -30
  6. package/client/components/__tests__/Button.test.tsx +12 -12
  7. package/client/layout/index.tsx +124 -124
  8. package/client/redux/reducers.ts +2 -2
  9. package/client/redux/store.ts +24 -24
  10. package/client/redux/template/manage/actions.ts +40 -40
  11. package/client/redux/template/manage/reducers.ts +32 -32
  12. package/client/redux/template/manage/types.ts +19 -19
  13. package/client/service/template/manage.ts +29 -29
  14. package/client/styled/common.ts +6 -6
  15. package/client/styled/layout/index.ts +17 -17
  16. package/client/styled/template/manage.ts +19 -19
  17. package/client/utils/common.ts +54 -54
  18. package/client/utils/cookie.ts +30 -30
  19. package/client/utils/fetch.ts +111 -111
  20. package/client/utils/i18n.ts +41 -41
  21. package/client/utils/menu.tsx +12 -12
  22. package/client/utils/navigation.ts +22 -22
  23. package/client/utils/sso.ts +124 -124
  24. package/client/utils/suppressWarnings.ts +17 -17
  25. package/generation/prettierrc +6 -0
  26. package/lib/args.js +19 -19
  27. package/lib/cli/app.d.ts +1 -1
  28. package/lib/cli/app.js +2 -2
  29. package/lib/cli/commands/build.d.ts +1 -1
  30. package/lib/cli/commands/build.js +9 -9
  31. package/lib/cli/commands/create.d.ts +1 -1
  32. package/lib/cli/commands/create.js +36 -36
  33. package/lib/cli/commands/delete.d.ts +1 -1
  34. package/lib/cli/commands/delete.js +55 -55
  35. package/lib/cli/commands/export.d.ts +1 -1
  36. package/lib/cli/commands/export.js +12 -12
  37. package/lib/cli/commands/help.d.ts +1 -1
  38. package/lib/cli/commands/help.js +29 -29
  39. package/lib/cli/commands/init.d.ts +1 -1
  40. package/lib/cli/commands/init.js +31 -31
  41. package/lib/cli/commands/server.d.ts +1 -1
  42. package/lib/cli/commands/server.js +12 -12
  43. package/lib/cli/commands/upgrade.d.ts +1 -1
  44. package/lib/cli/commands/upgrade.js +13 -13
  45. package/lib/cli/commands/version.d.ts +1 -1
  46. package/lib/cli/commands/version.js +7 -7
  47. package/lib/cli/index.d.ts +13 -13
  48. package/lib/cli/parser.d.ts +1 -1
  49. package/lib/cli/parser.js +12 -12
  50. package/lib/cli/registry.d.ts +1 -1
  51. package/lib/cli/types.d.ts +2 -2
  52. package/lib/cli/utils/console.d.ts +2 -2
  53. package/lib/cli/utils/console.js +22 -22
  54. package/lib/cli/utils/index.d.ts +2 -2
  55. package/lib/cli/utils/prompt.d.ts +1 -1
  56. package/lib/cli/utils/prompt.js +98 -98
  57. package/lib/constants.js +28 -28
  58. package/lib/generate.d.ts +2 -2
  59. package/lib/generate.js +19 -19
  60. package/lib/generate_create.d.ts +1 -1
  61. package/lib/generate_create.js +38 -38
  62. package/lib/generate_delete.js +63 -63
  63. package/lib/generate_init.js +94 -94
  64. package/lib/generators/base-generator.d.ts +1 -1
  65. package/lib/generators/base-generator.js +23 -23
  66. package/lib/generators/file-generator.js +15 -15
  67. package/lib/generators/generator-factory.d.ts +5 -5
  68. package/lib/generators/i18n-generator.d.ts +1 -1
  69. package/lib/generators/i18n-generator.js +127 -127
  70. package/lib/generators/page-generator.d.ts +1 -1
  71. package/lib/generators/page-generator.js +25 -25
  72. package/lib/generators/resolver-generator.d.ts +1 -1
  73. package/lib/generators/resolver-generator.js +27 -27
  74. package/lib/generators/schema-generator.d.ts +1 -1
  75. package/lib/generators/schema-generator.js +4 -4
  76. package/lib/generators/service-generator.d.ts +1 -1
  77. package/lib/generators/service-generator.js +29 -29
  78. package/lib/generators/sql-generator.d.ts +1 -1
  79. package/lib/generators/sql-generator.js +10 -10
  80. package/lib/index.js +23 -23
  81. package/lib/server/csrf.d.ts +3 -3
  82. package/lib/server/csrf.js +20 -20
  83. package/lib/server/db.d.ts +1 -1
  84. package/lib/server/db.js +21 -21
  85. package/lib/server/graphql.js +26 -26
  86. package/lib/server/plugins/date.d.ts +1 -1
  87. package/lib/server/plugins/date.js +6 -6
  88. package/lib/server/utils/graphql-cache.js +5 -5
  89. package/lib/tsconfig.build.tsbuildinfo +1 -1
  90. package/lib/utils/project-config.d.ts +1 -1
  91. package/lib/utils/project-config.js +20 -20
  92. package/lib/utils.js +3 -3
  93. package/package.json +1 -1
  94. package/pages/_app.tsx +62 -62
  95. package/pages/_document.tsx +15 -15
  96. package/pages/_error.tsx +26 -26
  97. package/pages/index.tsx +48 -48
  98. package/pages/login.tsx +64 -64
  99. package/pages/template/manage.tsx +175 -175
@@ -7,21 +7,21 @@ const base_generator_1 = require("./base-generator");
7
7
  */
8
8
  class ResolverGenerator extends base_generator_1.BaseGenerator {
9
9
  generate() {
10
- const selectFields = this.fields.map((f) => f.name).join(', ');
10
+ const selectFields = this.fields.map((f) => f.name).join(", ");
11
11
  const insertFields = this.getFormFields();
12
12
  const searchableFields = this.getSearchableFields();
13
- const insertFieldNames = insertFields.map((f) => f.name).join(', ');
14
- const insertPlaceholders = insertFields.map(() => '?').join(', ');
13
+ const insertFieldNames = insertFields.map((f) => f.name).join(", ");
14
+ const insertPlaceholders = insertFields.map(() => "?").join(", ");
15
15
  const insertValues = insertFields
16
16
  .map((f) => {
17
- if (f.type === 'integer') {
17
+ if (f.type === "integer") {
18
18
  return `valid${f.name.charAt(0).toUpperCase() + f.name.slice(1)}`;
19
19
  }
20
20
  return `data.${f.name}`;
21
21
  })
22
- .join(', ');
22
+ .join(", ");
23
23
  const searchConditions = this.generateSearchConditions(searchableFields);
24
- const updateFields = insertFields.map((f) => `${f.name} = ?`).join(', ');
24
+ const updateFields = insertFields.map((f) => `${f.name} = ?`).join(", ");
25
25
  return `const { executeQuery, executePaginatedQuery } = require('../../utils/common')
26
26
  const { validateInteger, validatePagination, validateId } = require('../../utils/validation')
27
27
 
@@ -230,9 +230,9 @@ ${this.generateUpdateValidation(insertFields)}
230
230
  }
231
231
  generateSearchConditions(searchableFields) {
232
232
  if (searchableFields.length === 0)
233
- return '';
233
+ return "";
234
234
  const conditions = searchableFields.map((field) => {
235
- if (field.type === 'varchar' || field.type === 'text') {
235
+ if (field.type === "varchar" || field.type === "text") {
236
236
  return ` if (data.${field.name} && data.${field.name}.trim() !== '') {
237
237
  whereSql += ' AND ${field.name} LIKE ?';
238
238
  const ${field.name}Pattern = \`%\${data.${field.name}.trim()}%\`;
@@ -240,7 +240,7 @@ ${this.generateUpdateValidation(insertFields)}
240
240
  countValues.push(${field.name}Pattern);
241
241
  }`;
242
242
  }
243
- else if (field.type === 'integer') {
243
+ else if (field.type === "integer") {
244
244
  return ` if (data.${field.name} !== undefined && data.${field.name} !== null && data.${field.name} !== '') {
245
245
  // 使用通用验证工具验证 ${field.name}
246
246
  const valid${field.name.charAt(0).toUpperCase() + field.name.slice(1)} = validateInteger(data.${field.name}, '${field.name}', { min: 0, max: 150 });
@@ -259,13 +259,13 @@ ${this.generateUpdateValidation(insertFields)}
259
259
  }`;
260
260
  }
261
261
  });
262
- return conditions.join('\n\n');
262
+ return conditions.join("\n\n");
263
263
  }
264
264
  generateNewValidationCalls(insertFields) {
265
265
  return insertFields
266
266
  .map((f) => {
267
- if (f.type === 'integer') {
268
- const validationOptions = f.name === 'age' ? '{ min: 0, max: 150, required: true }' : '{ required: true }';
267
+ if (f.type === "integer") {
268
+ const validationOptions = f.name === "age" ? "{ min: 0, max: 150, required: true }" : "{ required: true }";
269
269
  return ` const valid${f.name.charAt(0).toUpperCase() + f.name.slice(1)} = validateInteger(data.${f.name}, '${f.name}', ${validationOptions});`;
270
270
  }
271
271
  else if (f.required) {
@@ -273,16 +273,16 @@ ${this.generateUpdateValidation(insertFields)}
273
273
  throw new Error('${f.comment || f.name}是必填字段');
274
274
  }`;
275
275
  }
276
- return '';
276
+ return "";
277
277
  })
278
278
  .filter((call) => call.length > 0)
279
- .join('\n');
279
+ .join("\n");
280
280
  }
281
281
  generateBatchValidation(insertFields) {
282
282
  return insertFields
283
283
  .map((f) => {
284
- if (f.type === 'integer') {
285
- const validationOptions = f.name === 'age' ? '{ min: 0, max: 150, required: true }' : '{ required: true }';
284
+ if (f.type === "integer") {
285
+ const validationOptions = f.name === "age" ? "{ min: 0, max: 150, required: true }" : "{ required: true }";
286
286
  return ` const valid${f.name.charAt(0).toUpperCase() + f.name.slice(1)} = validateInteger(data.${f.name}, \`第\${index + 1}条数据的${f.name}\`, ${validationOptions});`;
287
287
  }
288
288
  else if (f.required) {
@@ -290,16 +290,16 @@ ${this.generateUpdateValidation(insertFields)}
290
290
  throw new Error('${f.comment || f.name}是必填字段');
291
291
  }`;
292
292
  }
293
- return '';
293
+ return "";
294
294
  })
295
295
  .filter((call) => call.length > 0)
296
- .join('\n');
296
+ .join("\n");
297
297
  }
298
298
  generateUpdateValidation(insertFields) {
299
299
  return insertFields
300
300
  .map((f) => {
301
- if (f.type === 'integer') {
302
- const validationOptions = f.name === 'age' ? '{ min: 0, max: 150, required: true }' : '{ required: true }';
301
+ if (f.type === "integer") {
302
+ const validationOptions = f.name === "age" ? "{ min: 0, max: 150, required: true }" : "{ required: true }";
303
303
  return ` let valid${f.name.charAt(0).toUpperCase() + f.name.slice(1)} = data.${f.name};
304
304
  if (data.${f.name} !== undefined) {
305
305
  valid${f.name.charAt(0).toUpperCase() + f.name.slice(1)} = validateInteger(data.${f.name}, '${f.name}', ${validationOptions});
@@ -310,33 +310,33 @@ ${this.generateUpdateValidation(insertFields)}
310
310
  throw new Error('${f.comment || f.name}是必填字段');
311
311
  }`;
312
312
  }
313
- return '';
313
+ return "";
314
314
  })
315
315
  .filter((call) => call.length > 0)
316
- .join('\n');
316
+ .join("\n");
317
317
  }
318
318
  generateUpdateValues(insertFields) {
319
319
  return insertFields
320
320
  .map((f) => {
321
- if (f.type === 'integer') {
321
+ if (f.type === "integer") {
322
322
  return `valid${f.name.charAt(0).toUpperCase() + f.name.slice(1)}`;
323
323
  }
324
324
  return `data.${f.name}`;
325
325
  })
326
- .join(', ');
326
+ .join(", ");
327
327
  }
328
328
  generateBatchReturnObject(insertFields) {
329
329
  return insertFields
330
330
  .map((f) => {
331
- if (f.type === 'integer') {
331
+ if (f.type === "integer") {
332
332
  return `${f.name}: valid${f.name.charAt(0).toUpperCase() + f.name.slice(1)}`;
333
333
  }
334
334
  return `${f.name}: data.${f.name}`;
335
335
  })
336
- .join(', ');
336
+ .join(", ");
337
337
  }
338
338
  generateBatchInsertValues(insertFields) {
339
- return insertFields.map((f) => `data.${f.name}`).join(', ');
339
+ return insertFields.map((f) => `data.${f.name}`).join(", ");
340
340
  }
341
341
  }
342
342
  exports.ResolverGenerator = ResolverGenerator;
@@ -1,4 +1,4 @@
1
- import { BaseGenerator } from './base-generator';
1
+ import { BaseGenerator } from "./base-generator";
2
2
  /**
3
3
  * GraphQL Schema生成器
4
4
  */
@@ -11,14 +11,14 @@ class SchemaGenerator extends base_generator_1.BaseGenerator {
11
11
  const pluralTypeName = `${capitalizedTypeName}s`;
12
12
  const typeFields = this.getNonSystemFields()
13
13
  .map((field) => ` ${field.name}: ${this.getGraphQLType(field.type)}`)
14
- .join('\n');
14
+ .join("\n");
15
15
  const inputFields = this.getFormFields()
16
16
  .map((field) => ` ${field.name}: ${this.getGraphQLType(field.type)}`)
17
- .join('\n');
17
+ .join("\n");
18
18
  const searchableFields = this.getSearchableFields();
19
19
  const searchFields = searchableFields.length > 0
20
- ? searchableFields.map((field) => ` ${field.name}: ${this.getGraphQLType(field.type)}`).join('\n')
21
- : ' name: String';
20
+ ? searchableFields.map((field) => ` ${field.name}: ${this.getGraphQLType(field.type)}`).join("\n")
21
+ : " name: String";
22
22
  return `module.exports = {
23
23
  query: \`
24
24
  ${this.controller}(page: Int, pageSize: Int): ${pluralTypeName}
@@ -1,4 +1,4 @@
1
- import { BaseGenerator } from './base-generator';
1
+ import { BaseGenerator } from "./base-generator";
2
2
  /**
3
3
  * 客户端服务生成器
4
4
  */
@@ -10,14 +10,14 @@ class ServiceGenerator extends base_generator_1.BaseGenerator {
10
10
  const capitalizedTypeName = this.getCapitalizedController();
11
11
  // 排除系统字段 create_date 和 update_date
12
12
  const selectFields = this.fields
13
- .filter((f) => !['create_date', 'update_date'].includes(f.name))
13
+ .filter((f) => !["create_date", "update_date"].includes(f.name))
14
14
  .map((f) => f.name)
15
- .join(' ');
15
+ .join(" ");
16
16
  const inputFields = this.getFormFields();
17
17
  const searchFields = this.getSearchableFields();
18
18
  // 检查是否有integer类型字段需要验证
19
- const hasIntegerFields = inputFields.some((field) => field.type === 'integer');
20
- const validationFunctions = hasIntegerFields ? this.generateValidationFunctions(inputFields) : '';
19
+ const hasIntegerFields = inputFields.some((field) => field.type === "integer");
20
+ const validationFunctions = hasIntegerFields ? this.generateValidationFunctions(inputFields) : "";
21
21
  return `import { getLocalGraphql } from '@/utils/fetch'
22
22
  import _ from 'lodash'
23
23
 
@@ -49,9 +49,9 @@ export const search${capitalizedTypeName}ByIdService = (id: number) => {
49
49
  }
50
50
 
51
51
  export const search${capitalizedTypeName}Service = (page = 0, pageSize = 10, data: any) => {
52
- const { ${searchFields.map((f) => f.name).join(', ')} } = data
52
+ const { ${searchFields.map((f) => f.name).join(", ")} } = data
53
53
 
54
- ${this.generateValidationCallsForService(searchFields, ' ', false)}
54
+ ${this.generateValidationCallsForService(searchFields, " ", false)}
55
55
 
56
56
  const search${capitalizedTypeName}Query = \`query ($page: Int, $pageSize: Int, $data: ${capitalizedTypeName}SearchInput) {
57
57
  ${this.controller}Search(page: $page, pageSize: $pageSize, data: $data) {
@@ -71,9 +71,9 @@ ${this.generateDataObjectWithValidation(searchFields)}
71
71
  }
72
72
 
73
73
  export const add${capitalizedTypeName}Service = (data: any) => {
74
- const { ${inputFields.map((f) => f.name).join(', ')} } = data
74
+ const { ${inputFields.map((f) => f.name).join(", ")} } = data
75
75
 
76
- ${this.generateValidationCallsForService(inputFields, ' ', true)}
76
+ ${this.generateValidationCallsForService(inputFields, " ", true)}
77
77
 
78
78
  const add${capitalizedTypeName}Query = \`mutation ($data: ${capitalizedTypeName}AddInput) { ${this.controller}Add(data: $data) }\`
79
79
 
@@ -85,9 +85,9 @@ ${this.generateDataObjectWithValidation(inputFields)}
85
85
  }
86
86
 
87
87
  export const update${capitalizedTypeName}Service = (id: number, data: any) => {
88
- const { ${inputFields.map((f) => f.name).join(', ')} } = data
88
+ const { ${inputFields.map((f) => f.name).join(", ")} } = data
89
89
 
90
- ${this.generateValidationCallsForService(inputFields, ' ', true)}
90
+ ${this.generateValidationCallsForService(inputFields, " ", true)}
91
91
 
92
92
  const update${capitalizedTypeName}Query = \`mutation ($id: Int, $data: ${capitalizedTypeName}AddInput) { ${this.controller}Update(id: $id, data: $data) }\`
93
93
 
@@ -108,7 +108,7 @@ export const delete${capitalizedTypeName}Service = (id: number) => {
108
108
  }
109
109
 
110
110
  export const batchAdd${capitalizedTypeName}Service = (datas: any) => {
111
- ${this.generateBatchValidationCalls(inputFields, ' ')}
111
+ ${this.generateBatchValidationCalls(inputFields, " ")}
112
112
 
113
113
  const batchAdd${capitalizedTypeName}Query = \`mutation ($datas: [${capitalizedTypeName}AddInput]) { ${this.controller}BatchAdd(datas: $datas) }\`
114
114
 
@@ -127,9 +127,9 @@ export const batchDelete${capitalizedTypeName}Service = (ids: any) => {
127
127
  `;
128
128
  }
129
129
  generateValidationFunctions(inputFields) {
130
- const integerFields = inputFields.filter((field) => field.type === 'integer');
130
+ const integerFields = inputFields.filter((field) => field.type === "integer");
131
131
  if (integerFields.length === 0) {
132
- return '';
132
+ return "";
133
133
  }
134
134
  const validationFunctions = integerFields.map((field) => {
135
135
  const fieldName = field.name;
@@ -156,18 +156,18 @@ const validate${capitalizedName} = (${fieldName}: any, required = false) => {
156
156
  return { valid: true, value: parsed${capitalizedName} }
157
157
  }`;
158
158
  });
159
- return `${validationFunctions.join('\n\n')}\n\n`;
159
+ return `${validationFunctions.join("\n\n")}\n\n`;
160
160
  }
161
161
  generateValidationCallsForService(inputFields, indent, required) {
162
- const integerFields = inputFields.filter((field) => field.type === 'integer');
162
+ const integerFields = inputFields.filter((field) => field.type === "integer");
163
163
  if (integerFields.length === 0) {
164
- return '';
164
+ return "";
165
165
  }
166
166
  const validationCalls = integerFields.map((field) => {
167
167
  const fieldName = field.name;
168
168
  const capitalizedName = fieldName.charAt(0).toUpperCase() + fieldName.slice(1);
169
- const requiredStr = required ? 'true' : 'false';
170
- return `${indent}// 验证${required ? '必填' : ''}${fieldName}
169
+ const requiredStr = required ? "true" : "false";
170
+ return `${indent}// 验证${required ? "必填" : ""}${fieldName}
171
171
  ${indent}const ${fieldName}Validation = validate${capitalizedName}(${fieldName}, ${requiredStr})
172
172
  ${indent}if (!${fieldName}Validation.valid) {
173
173
  ${indent} return Promise.reject({
@@ -177,37 +177,37 @@ ${indent} code: ${fieldName}Validation.code
177
177
  ${indent} })
178
178
  ${indent}}`;
179
179
  });
180
- return validationCalls.join('\n\n') + (validationCalls.length > 0 ? '\n\n' : '');
180
+ return validationCalls.join("\n\n") + (validationCalls.length > 0 ? "\n\n" : "");
181
181
  }
182
182
  generateDataObjectWithValidation(inputFields) {
183
183
  return inputFields
184
184
  .map((field) => {
185
- if (field.type === 'integer') {
185
+ if (field.type === "integer") {
186
186
  return ` ${field.name}: ${field.name}Validation.value`;
187
187
  }
188
188
  return ` ${field.name}`;
189
189
  })
190
- .join(',\n');
190
+ .join(",\n");
191
191
  }
192
192
  generateBatchValidationCalls(inputFields, indent) {
193
- const integerFields = inputFields.filter((field) => field.type === 'integer');
193
+ const integerFields = inputFields.filter((field) => field.type === "integer");
194
194
  if (integerFields.length === 0) {
195
195
  return `${indent}// 验证批量数据
196
- ${indent}const validatedDatas: Array<{ ${inputFields.map((f) => `${f.name}: any`).join('; ')} }> = []
196
+ ${indent}const validatedDatas: Array<{ ${inputFields.map((f) => `${f.name}: any`).join("; ")} }> = []
197
197
 
198
198
  ${indent}for (let i = 0; i < datas.length; i++) {
199
- ${indent} const { ${inputFields.map((f) => f.name).join(', ')} } = datas[i]
199
+ ${indent} const { ${inputFields.map((f) => f.name).join(", ")} } = datas[i]
200
200
 
201
201
  ${indent} validatedDatas.push({
202
- ${indent} ${inputFields.map((f) => f.name).join(',\n ')}
202
+ ${indent} ${inputFields.map((f) => f.name).join(",\n ")}
203
203
  ${indent} })
204
204
  ${indent}}`;
205
205
  }
206
206
  return `${indent}// 验证批量数据
207
- ${indent}const validatedDatas: Array<{ ${inputFields.map((f) => `${f.name}: ${f.type === 'integer' ? 'number' : 'any'}`).join('; ')} }> = []
207
+ ${indent}const validatedDatas: Array<{ ${inputFields.map((f) => `${f.name}: ${f.type === "integer" ? "number" : "any"}`).join("; ")} }> = []
208
208
 
209
209
  ${indent}for (let i = 0; i < datas.length; i++) {
210
- ${indent} const { ${inputFields.map((f) => f.name).join(', ')} } = datas[i]
210
+ ${indent} const { ${inputFields.map((f) => f.name).join(", ")} } = datas[i]
211
211
 
212
212
  ${integerFields
213
213
  .map((field) => {
@@ -222,10 +222,10 @@ ${indent} code: ${fieldName}Validation.code
222
222
  ${indent} })
223
223
  ${indent} }`;
224
224
  })
225
- .join('\n\n')}
225
+ .join("\n\n")}
226
226
 
227
227
  ${indent} validatedDatas.push({
228
- ${indent} ${inputFields.map((field) => (field.type === 'integer' ? `${field.name}: ${field.name}Validation.value!` : field.name)).join(',\n ')}
228
+ ${indent} ${inputFields.map((field) => (field.type === "integer" ? `${field.name}: ${field.name}Validation.value!` : field.name)).join(",\n ")}
229
229
  ${indent} })
230
230
  ${indent}}`;
231
231
  }
@@ -1,4 +1,4 @@
1
- import { BaseGenerator } from './base-generator';
1
+ import { BaseGenerator } from "./base-generator";
2
2
  /**
3
3
  * SQL生成器
4
4
  * 专门负责生成数据库表结构
@@ -14,23 +14,23 @@ class SQLGenerator extends base_generator_1.BaseGenerator {
14
14
  sql += ` ${this.getSQLType(field)}`;
15
15
  // 是否必填
16
16
  if (field.required && !field.isAutoIncrement) {
17
- sql += ' NOT NULL';
17
+ sql += " NOT NULL";
18
18
  }
19
19
  else if (!field.required) {
20
- sql += ' DEFAULT NULL';
20
+ sql += " DEFAULT NULL";
21
21
  }
22
22
  // 自增
23
23
  if (field.isAutoIncrement) {
24
- sql += ' AUTO_INCREMENT';
24
+ sql += " AUTO_INCREMENT";
25
25
  }
26
26
  // 默认值
27
- if (field.type === 'timestamp' && field.name === 'create_date') {
28
- sql += ' DEFAULT CURRENT_TIMESTAMP(3)';
27
+ if (field.type === "timestamp" && field.name === "create_date") {
28
+ sql += " DEFAULT CURRENT_TIMESTAMP(3)";
29
29
  }
30
- else if (field.type === 'timestamp' && field.name === 'update_date') {
31
- sql += ' DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)';
30
+ else if (field.type === "timestamp" && field.name === "update_date") {
31
+ sql += " DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)";
32
32
  }
33
- else if (field.type === 'varchar' && field.name !== 'id' && !field.required) {
33
+ else if (field.type === "varchar" && field.name !== "id" && !field.required) {
34
34
  sql += " DEFAULT ''";
35
35
  }
36
36
  // 注释
@@ -40,11 +40,11 @@ class SQLGenerator extends base_generator_1.BaseGenerator {
40
40
  return sql;
41
41
  });
42
42
  const primaryKeyField = this.fields.find((f) => f.isPrimaryKey);
43
- const primaryKey = primaryKeyField ? ` PRIMARY KEY (\`${primaryKeyField.name}\`)` : '';
43
+ const primaryKey = primaryKeyField ? ` PRIMARY KEY (\`${primaryKeyField.name}\`)` : "";
44
44
  return `use crm_demo;
45
45
 
46
46
  CREATE TABLE \`${this.controller}\` (
47
- ${fieldDefinitions.join(',\n')},
47
+ ${fieldDefinitions.join(",\n")},
48
48
  ${primaryKey}
49
49
  ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;`;
50
50
  }
package/lib/index.js CHANGED
@@ -6,10 +6,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.startExpress = void 0;
8
8
  // 加载环境变量
9
- require('dotenv').config({ quiet: true });
9
+ require("dotenv").config({ quiet: true });
10
10
  // 仅在开发环境中禁用TLS证书验证
11
- if (process.env.NODE_ENV === 'development') {
12
- process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
11
+ if (process.env.NODE_ENV === "development") {
12
+ process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
13
13
  }
14
14
  const next_1 = __importDefault(require("next"));
15
15
  const express_1 = __importDefault(require("express"));
@@ -38,15 +38,15 @@ const handleServer = (server, prefix, _command) => {
38
38
  // 只看单个文件,不看目录
39
39
  if (isFile) {
40
40
  let filename = item;
41
- if (item.indexOf('.') !== -1) {
42
- filename = item.split('.')[0];
41
+ if (item.indexOf(".") !== -1) {
42
+ filename = item.split(".")[0];
43
43
  }
44
- if (server && filename !== undefined && filename !== '') {
44
+ if (server && filename !== undefined && filename !== "") {
45
45
  try {
46
46
  const routeModule = require(resolverPath);
47
47
  // 检查导入的模块是否是有效的Express中间件
48
- if (typeof routeModule === 'function' ||
49
- (routeModule && typeof routeModule === 'object' && routeModule.router)) {
48
+ if (typeof routeModule === "function" ||
49
+ (routeModule && typeof routeModule === "object" && routeModule.router)) {
50
50
  server.use(`/${filename}`, routeModule);
51
51
  server.use(`${prefix}/${filename}`, routeModule);
52
52
  }
@@ -63,7 +63,7 @@ const handleServer = (server, prefix, _command) => {
63
63
  });
64
64
  }
65
65
  };
66
- const startExpress = (options, callback, command = 'dev') => {
66
+ const startExpress = (options, callback, command = "dev") => {
67
67
  // console.info('startExpress', curFolder)
68
68
  const app = (0, next_1.default)(options);
69
69
  const handle = app.getRequestHandler();
@@ -78,25 +78,25 @@ const startExpress = (options, callback, command = 'dev') => {
78
78
  try {
79
79
  const dbPoolManager = require(resolve(`${curFolder}/server/utils/db-pool-manager`));
80
80
  await dbPoolManager.initialize();
81
- console.log('数据库连接池初始化完成');
81
+ console.log("数据库连接池初始化完成");
82
82
  }
83
83
  catch (error) {
84
84
  const errorMessage = error instanceof Error ? error.message : String(error);
85
- console.error('数据库连接池初始化失败:', errorMessage);
85
+ console.error("数据库连接池初始化失败:", errorMessage);
86
86
  // 不要因为数据库连接失败就退出,允许应用继续运行
87
87
  }
88
88
  const server = (0, express_1.default)();
89
89
  // 配置 session(CSRF 保护需要)
90
90
  server.use((0, express_session_1.default)({
91
- secret: process.env.SESSION_SECRET || 'nsgm-default-secret-key-change-in-production',
91
+ secret: process.env.SESSION_SECRET || "nsgm-default-secret-key-change-in-production",
92
92
  resave: false,
93
93
  saveUninitialized: true, // 改为 true,确保 session 被创建
94
- name: 'sessionId', // 明确指定 session cookie 名称
94
+ name: "sessionId", // 明确指定 session cookie 名称
95
95
  cookie: {
96
96
  secure: false, // 开发环境总是使用 false,生产环境再考虑 HTTPS
97
97
  httpOnly: true,
98
98
  maxAge: 24 * 60 * 60 * 1000, // 24小时
99
- sameSite: 'lax', // 设置 SameSite 策略
99
+ sameSite: "lax", // 设置 SameSite 策略
100
100
  domain: undefined, // 不设置 domain,使用默认
101
101
  },
102
102
  }));
@@ -108,31 +108,31 @@ const startExpress = (options, callback, command = 'dev') => {
108
108
  // 支持跨域,nsgm export 之后前后分离
109
109
  server.use((0, cors_1.default)({
110
110
  credentials: true, // 允许发送 cookies
111
- origin: process.env.ALLOWED_ORIGINS?.split(',') || ['http://localhost:3000'],
111
+ origin: process.env.ALLOWED_ORIGINS?.split(",") || ["http://localhost:3000"],
112
112
  }));
113
113
  server.use(body_parser_1.default.json());
114
114
  // 添加基本安全中间件
115
115
  server.use(csrf_1.securityMiddleware.basicHeaders);
116
- if (process.env.NODE_ENV === 'production') {
116
+ if (process.env.NODE_ENV === "production") {
117
117
  server.use((0, csrf_1.createCSPMiddleware)()); // 内容安全策略
118
118
  }
119
119
  // 添加 CSRF 保护中间件(在解析 body 之后)
120
120
  server.use(csrf_1.csrfProtection);
121
121
  server.use((0, express_fileupload_1.default)());
122
- server.use('/static', express_1.default.static(path_1.default.join(__dirname, 'public')));
123
- server.use('/graphql', (0, graphql_1.default)(command));
122
+ server.use("/static", express_1.default.static(path_1.default.join(__dirname, "public")));
123
+ server.use("/graphql", (0, graphql_1.default)(command));
124
124
  const nextConfig = (0, config_1.default)();
125
125
  const { publicRuntimeConfig } = nextConfig;
126
126
  const { host, port, prefix } = publicRuntimeConfig;
127
127
  // 提供 CSRF token 的端点
128
- server.get('/csrf-token', csrf_1.getCSRFToken);
129
- if (prefix !== '') {
128
+ server.get("/csrf-token", csrf_1.getCSRFToken);
129
+ if (prefix !== "") {
130
130
  server.get(`${prefix}/csrf-token`, csrf_1.getCSRFToken);
131
- server.use(`${prefix}/static`, express_1.default.static(path_1.default.join(__dirname, 'public')));
131
+ server.use(`${prefix}/static`, express_1.default.static(path_1.default.join(__dirname, "public")));
132
132
  server.use(`${prefix}/graphql`, (0, graphql_1.default)(command));
133
133
  }
134
134
  handleServer(server, prefix, command);
135
- server.get('*', (req, res) => {
135
+ server.get("*", (req, res) => {
136
136
  const { url } = req;
137
137
  const parsedUrl = (0, url_1.parse)(url, true);
138
138
  return handle(req, res, parsedUrl);
@@ -149,6 +149,6 @@ const startExpress = (options, callback, command = 'dev') => {
149
149
  exports.startExpress = startExpress;
150
150
  // 使用新的 CLI 架构
151
151
  (0, cli_1.runCli)().catch((error) => {
152
- console.error('CLI 执行失败:', error);
152
+ console.error("CLI 执行失败:", error);
153
153
  process.exit(1);
154
154
  });
@@ -1,10 +1,10 @@
1
- import { Request, Response, NextFunction } from 'express';
2
- declare module 'express-session' {
1
+ import { Request, Response, NextFunction } from "express";
2
+ declare module "express-session" {
3
3
  interface SessionData {
4
4
  _csrf?: string;
5
5
  }
6
6
  }
7
- declare module 'express-serve-static-core' {
7
+ declare module "express-serve-static-core" {
8
8
  interface Request {
9
9
  csrfToken?: () => string;
10
10
  }
@@ -9,36 +9,36 @@ const lusca_1 = __importDefault(require("lusca"));
9
9
  const luscaConfig = {
10
10
  // CSRF 保护 - 修正配置格式
11
11
  csrf: {
12
- header: 'x-csrf-token', // 从 header 中读取 token
13
- cookie: '_csrf', // cookie 名称
14
- key: 'csrf', // session key
15
- secret: process.env.CSRF_SECRET || 'your-csrf-secret-change-in-production',
12
+ header: "x-csrf-token", // 从 header 中读取 token
13
+ cookie: "_csrf", // cookie 名称
14
+ key: "csrf", // session key
15
+ secret: process.env.CSRF_SECRET || "your-csrf-secret-change-in-production",
16
16
  },
17
17
  // 内容安全策略
18
18
  csp: {
19
19
  policy: {
20
- 'default-src': "'self'",
21
- 'script-src': "'self' 'unsafe-inline'",
22
- 'style-src': "'self' 'unsafe-inline'",
23
- 'img-src': "'self' data: https:",
24
- 'font-src': "'self' https:",
25
- 'connect-src': "'self'",
20
+ "default-src": "'self'",
21
+ "script-src": "'self' 'unsafe-inline'",
22
+ "style-src": "'self' 'unsafe-inline'",
23
+ "img-src": "'self' data: https:",
24
+ "font-src": "'self' https:",
25
+ "connect-src": "'self'",
26
26
  },
27
27
  },
28
28
  // 其他安全设置
29
- xframe: 'SAMEORIGIN',
29
+ xframe: "SAMEORIGIN",
30
30
  nosniff: true,
31
31
  xssProtection: true,
32
- referrerPolicy: 'same-origin',
32
+ referrerPolicy: "same-origin",
33
33
  };
34
34
  // 条件性 CSRF 保护中间件
35
35
  const csrfProtection = (req, res, next) => {
36
36
  // 跳过 GET 请求和某些不需要 CSRF 保护的路径
37
- if (req.method === 'GET' ||
38
- req.path.startsWith('/static') ||
39
- req.path === '/csrf-token' ||
40
- req.path.startsWith('/_next') || // Next.js 内部资源
41
- req.path.startsWith('/__next') // Next.js 开发模式内部端点
37
+ if (req.method === "GET" ||
38
+ req.path.startsWith("/static") ||
39
+ req.path === "/csrf-token" ||
40
+ req.path.startsWith("/_next") || // Next.js 内部资源
41
+ req.path.startsWith("/__next") // Next.js 开发模式内部端点
42
42
  ) {
43
43
  return next();
44
44
  }
@@ -67,10 +67,10 @@ const getCSRFToken = (req, res) => {
67
67
  }
68
68
  }
69
69
  catch (error) {
70
- console.error('获取 CSRF token 错误:', error);
70
+ console.error("获取 CSRF token 错误:", error);
71
71
  res.status(500).json({
72
- error: 'Failed to generate CSRF token',
73
- message: '生成 CSRF 令牌失败',
72
+ error: "Failed to generate CSRF token",
73
+ message: "生成 CSRF 令牌失败",
74
74
  });
75
75
  }
76
76
  };
@@ -1,4 +1,4 @@
1
- import mysql from 'mysql2';
1
+ import mysql from "mysql2";
2
2
  declare const _default: {
3
3
  getMysqlConfig: () => null;
4
4
  getConnection: () => Promise<unknown>;