nsgm-cli 2.1.24 → 2.1.26

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/README.md CHANGED
@@ -39,6 +39,7 @@ NSGM CLI is a comprehensive full-stack development framework that combines the p
39
39
  ### ⚡ **Rapid Development**
40
40
 
41
41
  - **Code Generation**: Automatic CRUD operations, API endpoints, and database schemas
42
+ - **Config-Based Generation**: Batch create multiple modules from JSON configuration files
42
43
  - **Hot Reload**: Instant development feedback
43
44
  - **Type Safety**: Full TypeScript support throughout the stack
44
45
 
@@ -139,14 +140,15 @@ Your application will be available at `http://localhost:3000` with:
139
140
 
140
141
  ### Core Commands
141
142
 
142
- | Command | Description | Mode | Example |
143
- | ------------- | ----------------------------- | --------------- | --------------------- |
144
- | `nsgm init` | Initialize new project | Interactive/CLI | `nsgm init blog-app` |
145
- | `nsgm create` | Generate controller with CRUD | Interactive/CLI | `nsgm create user` |
146
- | `nsgm delete` | Remove controller and files | Interactive/CLI | `nsgm delete product` |
147
- | `nsgm dev` | Start development server | CLI | `nsgm dev` |
148
- | `nsgm build` | Build for production | CLI | `nsgm build` |
149
- | `nsgm start` | Start production server | CLI | `nsgm start` |
143
+ | Command | Description | Mode | Example |
144
+ | ---------------- | ------------------------------- | --------------- | ----------------------------- |
145
+ | `nsgm init` | Initialize new project | Interactive/CLI | `nsgm init blog-app` |
146
+ | `nsgm create` | Generate controller with CRUD | Interactive/CLI | `nsgm create user` |
147
+ | `nsgm delete` | Remove controller and files | Interactive/CLI | `nsgm delete product` |
148
+ | `nsgm create-config` | Batch create from config file | CLI | `nsgm create-config config/modules.json` |
149
+ | `nsgm dev` | Start development server | CLI | `nsgm dev` |
150
+ | `nsgm build` | Build for production | CLI | `nsgm build` |
151
+ | `nsgm start` | Start production server | CLI | `nsgm start` |
150
152
 
151
153
  ### Advanced Commands
152
154
 
@@ -154,6 +156,11 @@ Your application will be available at `http://localhost:3000` with:
154
156
  # Database operations
155
157
  nsgm deletedb user # Delete controller + database table
156
158
 
159
+ # Batch module creation
160
+ nsgm create-config config/modules.json # Create all modules from config
161
+ nsgm create-config config/modules.json --module category # Create specific module
162
+ nsgm create-config config/modules.json --dry-run # Preview without creating
163
+
157
164
  # Project maintenance
158
165
  nsgm upgrade # Upgrade project base files
159
166
  nsgm export # Export static pages
@@ -455,10 +462,103 @@ npm run tsbuild
455
462
  ## 📖 Documentation
456
463
 
457
464
  - [Security Guide](SECURITY.md) - Security best practices
465
+ - [Config-Based Generation Guide](docs/CONFIG-CMD-IMPLEMENTATION.md) - Batch module creation from config files
458
466
  - [API Reference](docs/api.md) - Complete API documentation
459
467
  - [Migration Guide](docs/migration.md) - Upgrade instructions
460
468
  - [Troubleshooting](docs/troubleshooting.md) - Common issues and solutions
461
469
 
470
+ ## 📋 Configuration File-Based Generation
471
+
472
+ NSGM CLI supports batch module creation from JSON configuration files, making it easy to generate multiple modules at once.
473
+
474
+ ### Configuration File Format
475
+
476
+ Create a JSON file (e.g., `config/modules.json`) with your module definitions:
477
+
478
+ ```json
479
+ [
480
+ {
481
+ "controller": "category",
482
+ "action": "manage",
483
+ "dictionary": ".",
484
+ "fields": [
485
+ {
486
+ "name": "id",
487
+ "type": "integer",
488
+ "required": true,
489
+ "comment": "Primary key",
490
+ "isPrimaryKey": true,
491
+ "isAutoIncrement": true
492
+ },
493
+ {
494
+ "name": "name",
495
+ "type": "varchar",
496
+ "length": 100,
497
+ "required": true,
498
+ "comment": "Category name",
499
+ "showInList": true,
500
+ "showInForm": true,
501
+ "searchable": true
502
+ }
503
+ ]
504
+ }
505
+ ]
506
+ ```
507
+
508
+ ### Usage Examples
509
+
510
+ ```bash
511
+ # Create all modules from config
512
+ nsgm create-config config/modules.json
513
+
514
+ # Or use npm script with default config
515
+ npm run create-config
516
+
517
+ # Create specific module
518
+ nsgm create-config config/modules.json --module category
519
+
520
+ # Preview mode (dry-run)
521
+ nsgm create-config config/modules.json --dry-run
522
+ ```
523
+
524
+ ### Field Naming Convention
525
+
526
+ **Always use snake_case for field names:**
527
+
528
+ ```json
529
+ {
530
+ "name": "user_id", // ✅ Correct
531
+ "name": "category_id", // ✅ Correct
532
+ "name": "total_amount", // ✅ Correct
533
+ "name": "create_date", // ✅ Correct
534
+ "name": "update_date" // ✅ Correct
535
+ }
536
+ ```
537
+
538
+ Avoid camelCase:
539
+
540
+ ```json
541
+ {
542
+ "name": "userId", // ❌ Not recommended
543
+ "name": "categoryId", // ❌ Not recommended
544
+ "name": "totalAmount", // ❌ Not recommended
545
+ }
546
+ ```
547
+
548
+ ### Configuration File Location
549
+
550
+ Generated projects include a `config/` directory with example configuration files:
551
+
552
+ ```
553
+ project/
554
+ ├── config/
555
+ │ ├── modules.json # Default module configuration
556
+ └── your-custom-config.json # Your custom configurations
557
+ ├── server/
558
+ ├── client/
559
+ └── ...
560
+ ```
561
+
462
562
  ## 🐛 Troubleshooting
463
563
 
464
564
  ### Common Issues
@@ -245,14 +245,20 @@ module.exports = {
245
245
  ### 使用方法
246
246
 
247
247
  ```bash
248
- # 创建所有模块
249
- npm run create-config config/modules.json
248
+ # 创建所有模块(使用默认配置文件 config/modules.json)
249
+ npm run create-config
250
+
251
+ # 或指定配置文件路径
252
+ nsgm create-config config/modules.json
250
253
 
251
254
  # 创建指定模块
252
- npm run create-config config/modules.json --module category
255
+ npm run create-config --module category
253
256
 
254
257
  # 预览模式(不实际创建)
255
- npm run create-config config/modules.json --dry-run
258
+ npm run create-config --dry-run
259
+
260
+ # 使用自定义配置文件
261
+ nsgm create-config path/to/your-config.json
256
262
  ```
257
263
 
258
264
  ### 字段命名规范
@@ -13,7 +13,7 @@
13
13
  "create": "nsgm create",
14
14
  "delete": "nsgm delete",
15
15
  "deletedb": "nsgm deletedb",
16
- "create-config": "nsgm create-config",
16
+ "create-config": "nsgm create-config config/modules.json",
17
17
  "generate-password": "node scripts/generate-password-hash.js",
18
18
  "postversion": "git push && git push --tags",
19
19
  "test": "jest",
@@ -44,7 +44,13 @@ exports.createConfigCommand = {
44
44
  try {
45
45
  // 获取配置文件路径
46
46
  const args = process.argv.slice(2);
47
- if (args.length === 0 || args[0].startsWith("-")) {
47
+ // 跳过命令名和别名
48
+ let configPathIndex = 0;
49
+ const commandNames = ["create-config", "-cc", "--create-config"];
50
+ while (configPathIndex < args.length && commandNames.includes(args[configPathIndex])) {
51
+ configPathIndex++;
52
+ }
53
+ if (configPathIndex >= args.length || args[configPathIndex].startsWith("-")) {
48
54
  utils_1.Console.error("请指定配置文件路径");
49
55
  utils_1.Console.info("使用方法:");
50
56
  utils_1.Console.info(" nsgm create-config <config-file> [--module <name>]");
@@ -56,7 +62,7 @@ exports.createConfigCommand = {
56
62
  utils_1.Console.info(" nsgm create-config config/modules.json --all");
57
63
  process.exit(1);
58
64
  }
59
- const configPath = args[0];
65
+ const configPath = args[configPathIndex];
60
66
  // 检查配置文件是否存在
61
67
  if (!fs_1.default.existsSync(configPath)) {
62
68
  utils_1.Console.error(`配置文件不存在: ${configPath}`);
@@ -15,6 +15,7 @@ declare const scriptsPathSource = "../scripts";
15
15
  declare const scriptsPath = "./scripts";
16
16
  declare const typesPathSource = "../types";
17
17
  declare const typesPath = "./types";
18
+ declare const configPath = "./config";
18
19
  declare const reduxPath = "/redux";
19
20
  declare const servicePath = "/service";
20
21
  declare const styledPath = "/styled";
@@ -39,6 +40,7 @@ declare const sourcePagesPath: string;
39
40
  declare const sourcePublicPath: string;
40
41
  declare const sourceScriptsPath: string;
41
42
  declare const sourceTypesPath: string;
43
+ declare const sourceConfigPath: string;
42
44
  declare const destClientPath: string;
43
45
  declare const destClientReduxPath: string;
44
46
  declare const destClientServicePath: string;
@@ -55,9 +57,10 @@ declare const destPagesPath: string;
55
57
  declare const destPublicPath: string;
56
58
  declare const destScriptsPath: string;
57
59
  declare const destTypesPath: string;
60
+ declare const destConfigPath: string;
58
61
  declare const destClientUtilsMenuPath: string;
59
62
  declare const destClientReduxReducersAllPath: string;
60
63
  declare const destPublicHealthCheckPath: string;
61
64
  declare const destPackagePath: string;
62
65
  declare const destServerRestPath: string;
63
- export { sourceFolder, destFolder, isLocal, generationPath, clientPathSource, clientPath, serverPathSource, serverPath, pagesPathSource, pagesPath, publicPathSource, publicPath, scriptsPathSource, scriptsPath, typesPathSource, typesPath, reduxPath, servicePath, styledPath, styledLayoutPath, utilsPath, layoutPath, componentsPath, modulesPath, apisPath, sqlPath, utilsMenuPath, reduxReducersPath, slbHealthCheckPath, packagePath, restPath, sourceGenerationPath, sourceClientPath, sourceClientPathGeneration, sourceServerPath, sourceServerPathGeneration, sourcePagesPath, sourcePublicPath, sourceScriptsPath, sourceTypesPath, destClientPath, destClientReduxPath, destClientServicePath, destClientStyledPath, destClientStyledLayoutPath, destClientUtilsPath, destClientLayoutPath, destServerPath, destServerModulesPath, destServerApisPath, destServerSqlPath, destServerUtilsPath, destPagesPath, destPublicPath, destScriptsPath, destTypesPath, destClientUtilsMenuPath, destClientReduxReducersAllPath, destPublicHealthCheckPath, destPackagePath, destServerRestPath, mysqlUser, mysqlPassword, mysqlHost, mysqlPort, mysqlDatabase, };
66
+ export { sourceFolder, destFolder, isLocal, generationPath, clientPathSource, clientPath, serverPathSource, serverPath, pagesPathSource, pagesPath, publicPathSource, publicPath, scriptsPathSource, scriptsPath, typesPathSource, typesPath, configPath, reduxPath, servicePath, styledPath, styledLayoutPath, utilsPath, layoutPath, componentsPath, modulesPath, apisPath, sqlPath, utilsMenuPath, reduxReducersPath, slbHealthCheckPath, packagePath, restPath, sourceGenerationPath, sourceClientPath, sourceClientPathGeneration, sourceServerPath, sourceServerPathGeneration, sourcePagesPath, sourcePublicPath, sourceScriptsPath, sourceTypesPath, sourceConfigPath, destClientPath, destClientReduxPath, destClientServicePath, destClientStyledPath, destClientStyledLayoutPath, destClientUtilsPath, destClientLayoutPath, destServerPath, destServerModulesPath, destServerApisPath, destServerSqlPath, destServerUtilsPath, destPagesPath, destPublicPath, destScriptsPath, destTypesPath, destConfigPath, destClientUtilsMenuPath, destClientReduxReducersAllPath, destPublicHealthCheckPath, destPackagePath, destServerRestPath, mysqlUser, mysqlPassword, mysqlHost, mysqlPort, mysqlDatabase, };
package/lib/constants.js CHANGED
@@ -36,8 +36,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.destServerApisPath = exports.destServerModulesPath = exports.destServerPath = exports.destClientLayoutPath = exports.destClientUtilsPath = exports.destClientStyledLayoutPath = exports.destClientStyledPath = exports.destClientServicePath = exports.destClientReduxPath = exports.destClientPath = exports.sourceTypesPath = exports.sourceScriptsPath = exports.sourcePublicPath = exports.sourcePagesPath = exports.sourceServerPathGeneration = exports.sourceServerPath = exports.sourceClientPathGeneration = exports.sourceClientPath = exports.sourceGenerationPath = exports.restPath = exports.packagePath = exports.slbHealthCheckPath = exports.reduxReducersPath = exports.utilsMenuPath = exports.sqlPath = exports.apisPath = exports.modulesPath = exports.componentsPath = exports.layoutPath = exports.utilsPath = exports.styledLayoutPath = exports.styledPath = exports.servicePath = exports.reduxPath = exports.typesPath = exports.typesPathSource = exports.scriptsPath = exports.scriptsPathSource = exports.publicPath = exports.publicPathSource = exports.pagesPath = exports.pagesPathSource = exports.serverPath = exports.serverPathSource = exports.clientPath = exports.clientPathSource = exports.generationPath = exports.isLocal = exports.destFolder = exports.sourceFolder = void 0;
40
- exports.mysqlDatabase = exports.mysqlPort = exports.mysqlHost = exports.mysqlPassword = exports.mysqlUser = exports.destServerRestPath = exports.destPackagePath = exports.destPublicHealthCheckPath = exports.destClientReduxReducersAllPath = exports.destClientUtilsMenuPath = exports.destTypesPath = exports.destScriptsPath = exports.destPublicPath = exports.destPagesPath = exports.destServerUtilsPath = exports.destServerSqlPath = void 0;
39
+ exports.destServerPath = exports.destClientLayoutPath = exports.destClientUtilsPath = exports.destClientStyledLayoutPath = exports.destClientStyledPath = exports.destClientServicePath = exports.destClientReduxPath = exports.destClientPath = exports.sourceConfigPath = exports.sourceTypesPath = exports.sourceScriptsPath = exports.sourcePublicPath = exports.sourcePagesPath = exports.sourceServerPathGeneration = exports.sourceServerPath = exports.sourceClientPathGeneration = exports.sourceClientPath = exports.sourceGenerationPath = exports.restPath = exports.packagePath = exports.slbHealthCheckPath = exports.reduxReducersPath = exports.utilsMenuPath = exports.sqlPath = exports.apisPath = exports.modulesPath = exports.componentsPath = exports.layoutPath = exports.utilsPath = exports.styledLayoutPath = exports.styledPath = exports.servicePath = exports.reduxPath = exports.configPath = exports.typesPath = exports.typesPathSource = exports.scriptsPath = exports.scriptsPathSource = exports.publicPath = exports.publicPathSource = exports.pagesPath = exports.pagesPathSource = exports.serverPath = exports.serverPathSource = exports.clientPath = exports.clientPathSource = exports.generationPath = exports.isLocal = exports.destFolder = exports.sourceFolder = void 0;
40
+ exports.mysqlDatabase = exports.mysqlPort = exports.mysqlHost = exports.mysqlPassword = exports.mysqlUser = exports.destServerRestPath = exports.destPackagePath = exports.destPublicHealthCheckPath = exports.destClientReduxReducersAllPath = exports.destClientUtilsMenuPath = exports.destConfigPath = exports.destTypesPath = exports.destScriptsPath = exports.destPublicPath = exports.destPagesPath = exports.destServerUtilsPath = exports.destServerSqlPath = exports.destServerApisPath = exports.destServerModulesPath = void 0;
41
41
  const path_1 = __importStar(require("path"));
42
42
  const db_1 = __importDefault(require("./server/db"));
43
43
  const sourceFolder = __dirname;
@@ -80,6 +80,8 @@ const typesPathSource = "../types";
80
80
  exports.typesPathSource = typesPathSource;
81
81
  const typesPath = "./types";
82
82
  exports.typesPath = typesPath;
83
+ const configPath = "./config";
84
+ exports.configPath = configPath;
83
85
  const reduxPath = "/redux";
84
86
  exports.reduxPath = reduxPath;
85
87
  const servicePath = "/service";
@@ -128,6 +130,8 @@ const sourceScriptsPath = path_1.default.join(sourceFolder, scriptsPathSource);
128
130
  exports.sourceScriptsPath = sourceScriptsPath;
129
131
  const sourceTypesPath = path_1.default.join(sourceFolder, typesPathSource);
130
132
  exports.sourceTypesPath = sourceTypesPath;
133
+ const sourceConfigPath = path_1.default.join(sourceGenerationPath, configPath);
134
+ exports.sourceConfigPath = sourceConfigPath;
131
135
  const destClientPath = path_1.default.join(destFolder, clientPath);
132
136
  exports.destClientPath = destClientPath;
133
137
  const destClientReduxPath = (0, path_1.resolve)(destClientPath + reduxPath);
@@ -160,6 +164,8 @@ const destScriptsPath = path_1.default.join(destFolder, scriptsPath);
160
164
  exports.destScriptsPath = destScriptsPath;
161
165
  const destTypesPath = path_1.default.join(destFolder, typesPath);
162
166
  exports.destTypesPath = destTypesPath;
167
+ const destConfigPath = path_1.default.join(destFolder, configPath);
168
+ exports.destConfigPath = destConfigPath;
163
169
  const destClientUtilsMenuPath = (0, path_1.resolve)(destClientUtilsPath + utilsMenuPath);
164
170
  exports.destClientUtilsMenuPath = destClientUtilsMenuPath;
165
171
  const destClientReduxReducersAllPath = (0, path_1.resolve)(destClientReduxPath + reduxReducersPath);
package/lib/generate.js CHANGED
@@ -74,6 +74,7 @@ const initFiles = (dictionary, upgradeFlag = false, projectConfig) => {
74
74
  const { destPackagePath } = (0, generate_init_1.initRootFiles)(normalizedDictionary, newDestFolder);
75
75
  (0, generate_init_1.initTestFiles)(normalizedDictionary, newDestFolder);
76
76
  (0, generate_init_1.initTypesFiles)(normalizedDictionary, newDestFolder);
77
+ (0, generate_init_1.initConfigFiles)(normalizedDictionary, newDestFolder);
77
78
  // 如果提供了项目配置,应用到生成的文件中
78
79
  if (projectConfig) {
79
80
  console.log("应用项目配置...");
@@ -53,4 +53,10 @@ export declare const initTypesFiles: (dictionary: string, newDestFolder: string)
53
53
  * @param newDestFolder 新的目标文件夹路径
54
54
  */
55
55
  export declare const initTestFiles: (dictionary: string, newDestFolder: string) => void;
56
+ /**
57
+ * 初始化配置文件和目录
58
+ * @param dictionary 目标目录名称
59
+ * @param newDestFolder 新的目标文件夹路径
60
+ */
61
+ export declare const initConfigFiles: (dictionary: string, newDestFolder: string) => void;
56
62
  export {};
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.initTestFiles = exports.initTypesFiles = exports.initRootFiles = exports.initScriptsFiles = exports.initPublicFiles = exports.initServerFiles = exports.initPagesFiles = exports.initClientFiles = void 0;
36
+ exports.initConfigFiles = exports.initTestFiles = exports.initTypesFiles = exports.initRootFiles = exports.initScriptsFiles = exports.initPublicFiles = exports.initServerFiles = exports.initPagesFiles = exports.initClientFiles = void 0;
37
37
  const path_1 = __importStar(require("path"));
38
38
  const constants_1 = require("./constants");
39
39
  const utils_1 = require("./utils");
@@ -616,3 +616,43 @@ const initTestFiles = (dictionary, newDestFolder) => {
616
616
  }
617
617
  };
618
618
  exports.initTestFiles = initTestFiles;
619
+ /**
620
+ * 初始化配置文件和目录
621
+ * @param dictionary 目标目录名称
622
+ * @param newDestFolder 新的目标文件夹路径
623
+ */
624
+ const initConfigFiles = (dictionary, newDestFolder) => {
625
+ console.log("Initializing config files...");
626
+ try {
627
+ // 1. 确定目标路径
628
+ const baseDestPath = dictionary === "" ? constants_1.destFolder : newDestFolder;
629
+ const configDestPath = path_1.default.join(baseDestPath, constants_1.configPath);
630
+ // 2. 创建配置目录
631
+ createDirectoryStructure([configDestPath]);
632
+ // 3. 复制 config 目录下的所有文件
633
+ const sourceConfigDir = (0, path_1.resolve)(constants_1.sourceConfigPath);
634
+ if ((0, fs_1.existsSync)(sourceConfigDir)) {
635
+ const copyConfigRecursive = (sourceDir, destDir) => {
636
+ const items = (0, fs_1.readdirSync)(sourceDir, { withFileTypes: true });
637
+ items.forEach((item) => {
638
+ const sourcePath = (0, path_1.resolve)(sourceDir, item.name);
639
+ const destPath = (0, path_1.resolve)(destDir, item.name);
640
+ if (item.isDirectory()) {
641
+ (0, utils_1.mkdirSync)(destPath);
642
+ copyConfigRecursive(sourcePath, destPath);
643
+ }
644
+ else {
645
+ (0, utils_1.copyFileSync)(sourcePath, destPath, false);
646
+ }
647
+ });
648
+ };
649
+ copyConfigRecursive(sourceConfigDir, configDestPath);
650
+ }
651
+ console.log("Config files initialization completed");
652
+ }
653
+ catch (error) {
654
+ console.error("Failed to initialize config files:", error);
655
+ throw error;
656
+ }
657
+ };
658
+ exports.initConfigFiles = initConfigFiles;