nsgm-cli 2.1.13 → 2.1.15

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 (147) hide show
  1. package/README.md +394 -156
  2. package/client/components/Button.tsx +3 -5
  3. package/client/components/ClientProviders.tsx +29 -0
  4. package/client/components/LanguageSwitcher.tsx +59 -0
  5. package/client/components/SSRSafeAntdProvider.tsx +24 -0
  6. package/client/components/SuppressHydrationWarnings.tsx +55 -0
  7. package/client/components/__tests__/Button.test.tsx +10 -10
  8. package/client/layout/index.tsx +153 -185
  9. package/client/redux/reducers.ts +1 -1
  10. package/client/redux/store.ts +2 -1
  11. package/client/redux/template/manage/actions.ts +77 -88
  12. package/client/redux/template/manage/reducers.ts +25 -37
  13. package/client/redux/template/manage/types.ts +1 -1
  14. package/client/service/template/manage.ts +20 -21
  15. package/client/styled/common.ts +12 -14
  16. package/client/styled/layout/index.ts +234 -120
  17. package/client/styled/template/manage.ts +102 -14
  18. package/client/utils/common.ts +23 -21
  19. package/client/utils/cookie.ts +18 -19
  20. package/client/utils/fetch.ts +64 -100
  21. package/client/utils/i18n.ts +68 -0
  22. package/client/utils/menu.tsx +42 -23
  23. package/client/utils/navigation.ts +58 -0
  24. package/client/utils/sso.ts +74 -84
  25. package/client/utils/suppressWarnings.ts +32 -0
  26. package/eslint.config.js +53 -19
  27. package/generation/README.md +25 -6
  28. package/generation/__tests__/example.test.js +41 -0
  29. package/generation/client/redux/reducers.ts +1 -1
  30. package/generation/client/utils/menu.tsx +36 -23
  31. package/generation/env +3 -0
  32. package/generation/env.example +3 -0
  33. package/generation/eslint.config.js +112 -0
  34. package/generation/gitignore +6 -1
  35. package/generation/jest.config.js +40 -0
  36. package/generation/next.config.js +7 -3
  37. package/generation/package.json +28 -4
  38. package/generation/tsconfig.json +6 -19
  39. package/jest.config.js +23 -6
  40. package/lib/args.js +9 -1
  41. package/lib/cli/app.d.ts +28 -0
  42. package/lib/cli/app.js +99 -0
  43. package/lib/cli/commands/build.d.ts +2 -0
  44. package/lib/cli/commands/build.js +29 -0
  45. package/lib/cli/commands/create.d.ts +2 -0
  46. package/lib/cli/commands/create.js +113 -0
  47. package/lib/cli/commands/delete.d.ts +3 -0
  48. package/lib/cli/commands/delete.js +151 -0
  49. package/lib/cli/commands/export.d.ts +2 -0
  50. package/lib/cli/commands/export.js +42 -0
  51. package/lib/cli/commands/help.d.ts +2 -0
  52. package/lib/cli/commands/help.js +42 -0
  53. package/lib/cli/commands/init.d.ts +2 -0
  54. package/lib/cli/commands/init.js +115 -0
  55. package/lib/cli/commands/server.d.ts +3 -0
  56. package/lib/cli/commands/server.js +26 -0
  57. package/lib/cli/commands/upgrade.d.ts +2 -0
  58. package/lib/cli/commands/upgrade.js +38 -0
  59. package/lib/cli/commands/version.d.ts +2 -0
  60. package/lib/cli/commands/version.js +24 -0
  61. package/lib/cli/index.d.ts +16 -0
  62. package/lib/cli/index.js +33 -0
  63. package/lib/cli/parser.d.ts +22 -0
  64. package/lib/cli/parser.js +115 -0
  65. package/lib/cli/registry.d.ts +33 -0
  66. package/lib/cli/registry.js +81 -0
  67. package/lib/cli/types/project.d.ts +10 -0
  68. package/lib/cli/types/project.js +2 -0
  69. package/lib/cli/types.d.ts +31 -0
  70. package/lib/cli/types.js +20 -0
  71. package/lib/cli/utils/console.d.ts +62 -0
  72. package/lib/cli/utils/console.js +148 -0
  73. package/lib/cli/utils/index.d.ts +2 -0
  74. package/lib/cli/utils/index.js +7 -0
  75. package/lib/cli/utils/prompt.d.ts +83 -0
  76. package/lib/cli/utils/prompt.js +327 -0
  77. package/lib/constants.d.ts +65 -0
  78. package/lib/constants.js +177 -0
  79. package/lib/generate.d.ts +25 -3
  80. package/lib/generate.js +98 -621
  81. package/lib/generate_create.d.ts +9 -0
  82. package/lib/generate_create.js +329 -0
  83. package/lib/generate_delete.d.ts +8 -0
  84. package/lib/generate_delete.js +233 -0
  85. package/lib/generate_init.d.ts +56 -0
  86. package/lib/generate_init.js +612 -0
  87. package/lib/generators/base-generator.d.ts +47 -0
  88. package/lib/generators/base-generator.js +92 -0
  89. package/lib/generators/file-generator.d.ts +48 -0
  90. package/lib/generators/file-generator.js +455 -0
  91. package/lib/generators/generator-factory.d.ts +20 -0
  92. package/lib/generators/generator-factory.js +25 -0
  93. package/lib/generators/i18n-generator.d.ts +51 -0
  94. package/lib/generators/i18n-generator.js +320 -0
  95. package/lib/generators/page-generator.d.ts +45 -0
  96. package/lib/generators/page-generator.js +578 -0
  97. package/lib/generators/resolver-generator.d.ts +14 -0
  98. package/lib/generators/resolver-generator.js +342 -0
  99. package/lib/generators/schema-generator.d.ts +7 -0
  100. package/lib/generators/schema-generator.js +57 -0
  101. package/lib/generators/service-generator.d.ts +11 -0
  102. package/lib/generators/service-generator.js +233 -0
  103. package/lib/generators/sql-generator.d.ts +8 -0
  104. package/lib/generators/sql-generator.js +52 -0
  105. package/lib/index.d.ts +1 -1
  106. package/lib/index.js +14 -173
  107. package/lib/server/csrf.js +9 -16
  108. package/lib/server/db.js +6 -7
  109. package/lib/server/graphql.js +5 -6
  110. package/lib/server/plugins/date.js +1 -1
  111. package/lib/server/utils/graphql-cache.js +3 -3
  112. package/lib/tsconfig.build.tsbuildinfo +1 -1
  113. package/lib/utils/project-config.d.ts +5 -0
  114. package/lib/utils/project-config.js +145 -0
  115. package/lib/utils.js +1 -1
  116. package/next-i18next.config.js +18 -0
  117. package/next.config.js +61 -18
  118. package/package.json +16 -8
  119. package/pages/_app.tsx +77 -33
  120. package/pages/_document.tsx +78 -21
  121. package/pages/_error.tsx +66 -0
  122. package/pages/index.tsx +109 -47
  123. package/pages/login.tsx +66 -41
  124. package/pages/template/manage.tsx +162 -151
  125. package/public/fonts/font-awesome.min.css +4 -0
  126. package/public/fonts/fontawesome-webfont.woff +0 -0
  127. package/public/fonts/fontawesome-webfont.woff2 +0 -0
  128. package/public/locales/en-US/common.json +48 -0
  129. package/public/locales/en-US/home.json +57 -0
  130. package/public/locales/en-US/layout.json +22 -0
  131. package/public/locales/en-US/login.json +13 -0
  132. package/public/locales/en-US/template.json +42 -0
  133. package/public/locales/ja-JP/common.json +48 -0
  134. package/public/locales/ja-JP/home.json +57 -0
  135. package/public/locales/ja-JP/layout.json +22 -0
  136. package/public/locales/ja-JP/login.json +13 -0
  137. package/public/locales/ja-JP/template.json +42 -0
  138. package/public/locales/zh-CN/common.json +48 -0
  139. package/public/locales/zh-CN/home.json +57 -0
  140. package/public/locales/zh-CN/layout.json +22 -0
  141. package/public/locales/zh-CN/login.json +13 -0
  142. package/public/locales/zh-CN/template.json +42 -0
  143. package/public/slbhealthcheck.html +1 -1
  144. package/server/apis/template.js +0 -2
  145. package/server/utils/validation.js +163 -0
  146. package/types/i18next.d.ts +10 -0
  147. package/generation/eslintrc.js +0 -16
@@ -0,0 +1,112 @@
1
+ const js = require('@eslint/js');
2
+ const typescript = require('@typescript-eslint/eslint-plugin');
3
+ const typescriptParser = require('@typescript-eslint/parser');
4
+ const prettier = require('eslint-plugin-prettier');
5
+
6
+ module.exports = [
7
+ js.configs.recommended,
8
+ {
9
+ files: ['client/**/*.{ts,tsx}', 'pages/**/*.{ts,tsx}', 'src/**/*.{ts,tsx}'],
10
+ languageOptions: {
11
+ parser: typescriptParser,
12
+ parserOptions: {
13
+ ecmaVersion: 2022,
14
+ sourceType: 'module',
15
+ project: './tsconfig.json'
16
+ },
17
+ globals: {
18
+ __dirname: 'readonly',
19
+ __filename: 'readonly',
20
+ process: 'readonly',
21
+ Buffer: 'readonly',
22
+ console: 'readonly'
23
+ }
24
+ },
25
+ plugins: {
26
+ '@typescript-eslint': typescript,
27
+ 'prettier': prettier
28
+ },
29
+ rules: {
30
+ 'no-console': 'off',
31
+ 'no-undef': 'off',
32
+ 'no-unused-vars': 'off',
33
+ 'prefer-const': 'warn',
34
+ 'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'warn',
35
+ '@typescript-eslint/no-var-requires': 'off',
36
+ '@typescript-eslint/no-explicit-any': 'warn',
37
+ '@typescript-eslint/no-unused-vars': ['warn', {
38
+ argsIgnorePattern: '^_',
39
+ varsIgnorePattern: '^_'
40
+ }],
41
+ 'prettier/prettier': 'error',
42
+ 'no-unreachable': 'error',
43
+ 'no-duplicate-imports': 'error',
44
+ 'prefer-template': 'warn',
45
+ '@typescript-eslint/prefer-optional-chain': 'warn'
46
+ }
47
+ },
48
+ {
49
+ files: ['**/__tests__/**/*.{ts,tsx,js}', '**/*.test.{ts,tsx,js}', '**/*.spec.{ts,tsx,js}'],
50
+ languageOptions: {
51
+ parser: typescriptParser,
52
+ parserOptions: {
53
+ ecmaVersion: 2022,
54
+ sourceType: 'module'
55
+ },
56
+ globals: {
57
+ describe: 'readonly',
58
+ test: 'readonly',
59
+ expect: 'readonly',
60
+ beforeEach: 'readonly',
61
+ afterEach: 'readonly',
62
+ beforeAll: 'readonly',
63
+ afterAll: 'readonly',
64
+ jest: 'readonly',
65
+ __dirname: 'readonly',
66
+ __filename: 'readonly',
67
+ process: 'readonly',
68
+ Buffer: 'readonly',
69
+ console: 'readonly'
70
+ }
71
+ },
72
+ plugins: {
73
+ '@typescript-eslint': typescript,
74
+ 'prettier': prettier
75
+ },
76
+ rules: {
77
+ 'no-console': 'off',
78
+ 'no-undef': 'off',
79
+ 'no-unused-vars': 'off',
80
+ '@typescript-eslint/no-explicit-any': 'off',
81
+ 'prettier/prettier': 'error'
82
+ }
83
+ },
84
+ {
85
+ files: ['**/*.js'],
86
+ languageOptions: {
87
+ ecmaVersion: 2022,
88
+ sourceType: 'commonjs',
89
+ globals: {
90
+ require: 'readonly',
91
+ module: 'readonly',
92
+ exports: 'readonly',
93
+ __dirname: 'readonly',
94
+ __filename: 'readonly',
95
+ process: 'readonly',
96
+ Buffer: 'readonly',
97
+ console: 'readonly'
98
+ }
99
+ },
100
+ rules: {
101
+ 'no-console': 'off'
102
+ }
103
+ },
104
+ {
105
+ ignores: [
106
+ 'node_modules/**',
107
+ '.next/**',
108
+ 'coverage/**',
109
+ '*.config.js'
110
+ ]
111
+ }
112
+ ];
@@ -2,4 +2,9 @@ node_modules
2
2
  .next
3
3
  out
4
4
  build
5
- scripts/dump.*
5
+ scripts/dump.*
6
+ .env
7
+ .env.local
8
+ .env.production
9
+ .env.development
10
+ *.log
@@ -0,0 +1,40 @@
1
+ module.exports = {
2
+ testEnvironment: 'jsdom',
3
+ setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
4
+ transform: {
5
+ '^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }]
6
+ },
7
+ transformIgnorePatterns: ['/node_modules/', '^.+\\.module\\.(css|sass|scss|less)$'],
8
+ moduleNameMapper: {
9
+ '^@/(.*)$': '<rootDir>/$1',
10
+ '^~/(.*)$': '<rootDir>/$1'
11
+ },
12
+ setupFiles: ['<rootDir>/jest.setup-globals.js'],
13
+ testMatch: [
14
+ '**/__tests__/**/*.(ts|tsx|js)',
15
+ '**/*.(test|spec).(ts|tsx|js)'
16
+ ],
17
+ collectCoverage: true,
18
+ collectCoverageFrom: [
19
+ 'client/**/*.{js,jsx,ts,tsx}',
20
+ 'pages/**/*.{js,jsx,ts,tsx}',
21
+ 'server/**/*.{js,jsx,ts,tsx}',
22
+ '!**/*.d.ts',
23
+ '!**/node_modules/**',
24
+ '!**/.next/**',
25
+ '!**/coverage/**',
26
+ '!**/*.config.js'
27
+ ],
28
+ coverageDirectory: 'coverage',
29
+ coverageReporters: ['json', 'lcov', 'text', 'clover', 'html'],
30
+ coverageThreshold: {
31
+ global: {
32
+ branches: 70,
33
+ functions: 70,
34
+ lines: 70,
35
+ statements: 70
36
+ }
37
+ },
38
+ testPathIgnorePatterns: ['<rootDir>/.next/', '<rootDir>/node_modules/'],
39
+ moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node']
40
+ }
@@ -1,7 +1,11 @@
1
1
  const { nextConfig } = require('nsgm-cli')
2
+ const { i18n } = require('./next-i18next.config')
2
3
 
3
4
  module.exports = (phase, defaultConfig) => {
4
- let configObj = nextConfig(phase, defaultConfig)
5
+ let configObj = nextConfig(phase, defaultConfig)
5
6
 
6
- return configObj
7
- }
7
+ // 确保国际化配置被正确应用
8
+ configObj.i18n = i18n
9
+
10
+ return configObj
11
+ }
@@ -2,7 +2,7 @@
2
2
  "name": "nsgm-cli-project",
3
3
  "version": "1.0.0",
4
4
  "description": "",
5
- "main": "index.js",
5
+ "main": "app.js",
6
6
  "scripts": {
7
7
  "dev": "nsgm dev",
8
8
  "build": "nsgm build",
@@ -15,8 +15,32 @@
15
15
  "deletedb": "nsgm deletedb",
16
16
  "generate-password": "node scripts/generate-password-hash.js",
17
17
  "postversion": "git push && git push --tags",
18
- "test": "echo \"Error: no test specified\" && exit 1"
18
+ "test": "jest",
19
+ "test:watch": "jest --watch",
20
+ "test:coverage": "jest --coverage"
19
21
  },
20
22
  "author": "",
21
- "license": "ISC"
22
- }
23
+ "license": "ISC",
24
+ "dependencies": {
25
+ "nsgm-cli": "^2"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^20",
29
+ "@types/react": "^18",
30
+ "@types/lodash": "^4",
31
+ "typescript": "^5",
32
+ "jest": "^30",
33
+ "jest-environment-jsdom": "^30",
34
+ "@testing-library/jest-dom": "^6",
35
+ "@testing-library/react": "^14",
36
+ "@testing-library/user-event": "^14",
37
+ "@types/jest": "^30",
38
+ "eslint": "^9",
39
+ "eslint-config-prettier": "^10",
40
+ "eslint-plugin-prettier": "^5",
41
+ "prettier": "^3",
42
+ "next-i18next": "^15",
43
+ "react-i18next": "^15",
44
+ "i18next": "^24"
45
+ }
46
+ }
@@ -5,25 +5,20 @@
5
5
  "module": "commonjs",
6
6
  "declaration": true,
7
7
  "strict": true,
8
- "lib": [
9
- "dom",
10
- "ES2022"
11
- ],
8
+ "lib": ["dom", "ES2022"],
12
9
  "esModuleInterop": true,
13
10
  "allowJs": true,
14
11
  "skipLibCheck": true,
15
12
  "forceConsistentCasingInFileNames": true,
16
13
  "noEmit": false,
17
- "moduleResolution": "node",
14
+ "moduleResolution": "bundler",
18
15
  "resolveJsonModule": true,
19
16
  "isolatedModules": true,
20
17
  "noImplicitAny": false,
21
18
  "incremental": true,
22
19
  "baseUrl": ".",
23
20
  "paths": {
24
- "@/*": [
25
- "client/*"
26
- ]
21
+ "@/*": ["client/*"]
27
22
  },
28
23
  "noUnusedLocals": true,
29
24
  "noUnusedParameters": true,
@@ -31,14 +26,6 @@
31
26
  "noImplicitReturns": true,
32
27
  "noFallthroughCasesInSwitch": true
33
28
  },
34
- "include": [
35
- "client/**/*",
36
- "pages/**/*"
37
- ],
38
- "exclude": [
39
- "node_modules",
40
- "**/__tests__/*",
41
- ".next",
42
- "lib"
43
- ]
44
- }
29
+ "include": ["client/**/*", "pages/**/*"],
30
+ "exclude": ["node_modules", "**/__tests__/*", ".next", "lib"]
31
+ }
package/jest.config.js CHANGED
@@ -4,6 +4,19 @@ module.exports = {
4
4
  transform: {
5
5
  '^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { presets: ['next/babel'] }]
6
6
  },
7
+ transformIgnorePatterns: ['/node_modules/', '^.+\\.module\\.(css|sass|scss|less)$'],
8
+ moduleNameMapper: {
9
+ '^replace-in-file$': '<rootDir>/__mocks__/replace-in-file.js',
10
+ '^replace$': '<rootDir>/__mocks__/replace.js',
11
+ '^fs$': '<rootDir>/__mocks__/fs.js',
12
+ '^next$': '<rootDir>/__mocks__/next.js',
13
+ '^express$': '<rootDir>/__mocks__/express.js',
14
+ '^body-parser$': '<rootDir>/__mocks__/body-parser.js',
15
+ '^url$': '<rootDir>/__mocks__/url.js',
16
+ '^dotenv$': '<rootDir>/__mocks__/dotenv.js',
17
+ '^chalk$': '<rootDir>/__mocks__/chalk.js'
18
+ },
19
+ setupFiles: ['<rootDir>/jest.setup-globals.js'],
7
20
  testMatch: [
8
21
  '**/__tests__/**/*.(ts|tsx|js)',
9
22
  '**/*.(test|spec).(ts|tsx|js)'
@@ -16,14 +29,18 @@ module.exports = {
16
29
  'src/**/*.{js,jsx,ts,tsx}',
17
30
  '!**/*.d.ts',
18
31
  '!**/node_modules/**',
19
- '!**/.next/**'
32
+ '!**/.next/**',
33
+ '!**/coverage/**',
34
+ '!**/*.config.js'
20
35
  ],
21
36
  coverageDirectory: 'coverage',
22
- coverageReporters: ['json', 'lcov', 'text', 'clover'],
23
- extensionsToTreatAsEsm: ['.ts', '.tsx'],
24
- globals: {
25
- 'ts-jest': {
26
- useESM: true
37
+ coverageReporters: ['json', 'lcov', 'text', 'clover', 'html'],
38
+ coverageThreshold: {
39
+ global: {
40
+ branches: 70,
41
+ functions: 70,
42
+ lines: 70,
43
+ statements: 70
27
44
  }
28
45
  }
29
46
  }
package/lib/args.js CHANGED
@@ -11,7 +11,7 @@ const getProcessArgvs = (removeItems = 2) => {
11
11
  command: '', // dev, start, build, export, create, delete, init, help
12
12
  dictionary: '', // export/init dictionary=${dictionary}
13
13
  controller: '',
14
- action: '' // create/delete controller=${controller} action=${action}
14
+ action: '', // create/delete controller=${controller} action=${action}
15
15
  };
16
16
  lodash_1.default.each(args, (item, index) => {
17
17
  if (item.indexOf('=') !== -1) {
@@ -44,6 +44,14 @@ const getProcessArgvs = (removeItems = 2) => {
44
44
  result.action = item;
45
45
  }
46
46
  break;
47
+ case 3:
48
+ if (command === 'create' ||
49
+ command === '-c' ||
50
+ command.indexOf('delete') !== -1 ||
51
+ command.indexOf('-d') !== -1) {
52
+ result.dictionary = item;
53
+ }
54
+ break;
47
55
  }
48
56
  }
49
57
  });
@@ -0,0 +1,28 @@
1
+ import { CommandRegistry } from './registry';
2
+ /**
3
+ * CLI 应用程序主类
4
+ */
5
+ export declare class CliApp {
6
+ private registry;
7
+ constructor();
8
+ /**
9
+ * 运行 CLI 应用
10
+ */
11
+ run(args?: string[]): Promise<void>;
12
+ /**
13
+ * 查找相似的命令(简单的字符串匹配)
14
+ */
15
+ private findSimilarCommands;
16
+ /**
17
+ * 应用命令默认值
18
+ */
19
+ private applyCommandDefaults;
20
+ /**
21
+ * 获取命令注册表(用于测试)
22
+ */
23
+ getRegistry(): CommandRegistry;
24
+ }
25
+ /**
26
+ * 创建并运行 CLI 应用的便捷函数
27
+ */
28
+ export declare function runCli(args?: string[]): Promise<void>;
package/lib/cli/app.js ADDED
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CliApp = void 0;
4
+ exports.runCli = runCli;
5
+ const parser_1 = require("./parser");
6
+ const registry_1 = require("./registry");
7
+ const utils_1 = require("./utils");
8
+ /**
9
+ * CLI 应用程序主类
10
+ */
11
+ class CliApp {
12
+ constructor() {
13
+ this.registry = new registry_1.CommandRegistry();
14
+ }
15
+ /**
16
+ * 运行 CLI 应用
17
+ */
18
+ async run(args = process.argv.slice(2)) {
19
+ try {
20
+ const { command, options } = parser_1.ArgumentParser.parse(args);
21
+ // 查找命令
22
+ const cmd = this.registry.get(command);
23
+ if (!cmd) {
24
+ utils_1.Console.error(`未知命令: ${command}`);
25
+ utils_1.Console.info('使用 "nsgm help" 查看可用命令');
26
+ utils_1.Console.newLine();
27
+ // 提供建议的命令
28
+ const availableCommands = this.registry.getAllCommands().map((c) => c.name);
29
+ const suggestions = this.findSimilarCommands(command, availableCommands);
30
+ if (suggestions.length > 0) {
31
+ utils_1.Console.subtitle('你是否想要运行:');
32
+ suggestions.forEach((suggestion) => {
33
+ console.log(` nsgm ${suggestion}`);
34
+ });
35
+ }
36
+ process.exit(1);
37
+ }
38
+ // 应用命令选项的默认值
39
+ const finalOptions = this.applyCommandDefaults(cmd, options);
40
+ // 执行命令
41
+ await cmd.execute(finalOptions);
42
+ }
43
+ catch (error) {
44
+ utils_1.Console.error(`执行命令时发生错误: ${error}`);
45
+ utils_1.Console.debug('使用 "nsgm help" 查看帮助信息');
46
+ process.exit(1);
47
+ }
48
+ }
49
+ /**
50
+ * 查找相似的命令(简单的字符串匹配)
51
+ */
52
+ findSimilarCommands(input, commands) {
53
+ const suggestions = [];
54
+ // 查找包含输入字符的命令
55
+ for (const cmd of commands) {
56
+ if (cmd.includes(input) || input.includes(cmd)) {
57
+ suggestions.push(cmd);
58
+ }
59
+ }
60
+ // 如果没有找到,查找第一个字符相同的
61
+ if (suggestions.length === 0) {
62
+ for (const cmd of commands) {
63
+ if (cmd[0] === input[0]) {
64
+ suggestions.push(cmd);
65
+ }
66
+ }
67
+ }
68
+ return suggestions.slice(0, 3); // 最多返回3个建议
69
+ }
70
+ /**
71
+ * 应用命令默认值
72
+ */
73
+ applyCommandDefaults(cmd, options) {
74
+ const result = { ...options };
75
+ // 应用命令选项中定义的默认值
76
+ if (cmd.options) {
77
+ for (const option of cmd.options) {
78
+ if (option.default !== undefined && (result[option.name] === undefined || result[option.name] === '')) {
79
+ result[option.name] = option.default;
80
+ }
81
+ }
82
+ }
83
+ return result;
84
+ }
85
+ /**
86
+ * 获取命令注册表(用于测试)
87
+ */
88
+ getRegistry() {
89
+ return this.registry;
90
+ }
91
+ }
92
+ exports.CliApp = CliApp;
93
+ /**
94
+ * 创建并运行 CLI 应用的便捷函数
95
+ */
96
+ async function runCli(args) {
97
+ const app = new CliApp();
98
+ await app.run(args);
99
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from '../types';
2
+ export declare const buildCommand: Command;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildCommand = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const util_1 = require("util");
6
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
7
+ exports.buildCommand = {
8
+ name: 'build',
9
+ aliases: [],
10
+ description: '构建生产版本',
11
+ usage: 'nsgm build',
12
+ examples: ['nsgm build'],
13
+ execute: async (_options) => {
14
+ try {
15
+ console.log('🔨 开始构建生产版本...');
16
+ const { stdout, stderr } = await execAsync('next build');
17
+ if (stderr) {
18
+ console.error('构建警告:', stderr);
19
+ }
20
+ console.log('✅ 构建完成!');
21
+ console.log(stdout);
22
+ process.exit(0);
23
+ }
24
+ catch (error) {
25
+ console.error('❌ 构建失败:', error);
26
+ process.exit(1);
27
+ }
28
+ },
29
+ };
@@ -0,0 +1,2 @@
1
+ import { Command } from '../types';
2
+ export declare const createCommand: Command;
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCommand = void 0;
4
+ const parser_1 = require("../parser");
5
+ const utils_1 = require("../utils");
6
+ const generate_1 = require("../../generate");
7
+ exports.createCommand = {
8
+ name: 'create',
9
+ aliases: ['-c', '--create'],
10
+ description: '创建控制器和操作',
11
+ usage: 'nsgm create [controller] [action] [dictionary] [options]',
12
+ examples: ['nsgm create', 'nsgm create user', 'nsgm create user manage', 'nsgm create user manage myproject'],
13
+ options: [
14
+ {
15
+ name: 'controller',
16
+ description: '控制器名称',
17
+ required: false,
18
+ type: 'string',
19
+ },
20
+ {
21
+ name: 'action',
22
+ description: '操作名称',
23
+ default: 'manage',
24
+ type: 'string',
25
+ },
26
+ {
27
+ name: 'dictionary',
28
+ description: '项目目录',
29
+ default: '',
30
+ type: 'string',
31
+ },
32
+ {
33
+ name: 'interactive',
34
+ description: '使用交互式向导',
35
+ default: true,
36
+ type: 'boolean',
37
+ },
38
+ ],
39
+ execute: async (options) => {
40
+ try {
41
+ // 智能判断是否使用交互模式:如果用户提供了 controller 参数,则自动使用非交互模式
42
+ if (options.controller && options.controller.trim() !== '') {
43
+ options.interactive = false;
44
+ }
45
+ // 如果启用交互模式
46
+ if (options.interactive) {
47
+ const wizardResult = await utils_1.Prompt.createControllerWizard();
48
+ utils_1.Console.separator();
49
+ utils_1.Console.title('📋 控制器配置确认');
50
+ utils_1.Console.info(`项目目录: ${wizardResult.dictionary}`);
51
+ utils_1.Console.info(`控制器名称: ${wizardResult.controller}`);
52
+ utils_1.Console.info(`功能模块: 完整CRUD + 导入导出 + 批量删除`);
53
+ utils_1.Console.info(`描述: ${wizardResult.description}`);
54
+ utils_1.Console.info(`数据库表: ${wizardResult.includeDatabase ? '是' : '否'}`);
55
+ if (wizardResult.includeDatabase && wizardResult.fields.length > 0) {
56
+ const fieldNames = wizardResult.fields.map((field) => field.name).join(', ');
57
+ utils_1.Console.info(`字段: ${fieldNames}`);
58
+ }
59
+ utils_1.Console.separator();
60
+ const confirmed = await utils_1.Prompt.confirm('确认创建控制器?', true);
61
+ if (!confirmed) {
62
+ utils_1.Console.warning('控制器创建已取消');
63
+ process.exit(0);
64
+ }
65
+ // 更新选项
66
+ options.controller = wizardResult.controller;
67
+ options.action = wizardResult.action;
68
+ options.dictionary = wizardResult.dictionary;
69
+ options.fields = wizardResult.fields;
70
+ }
71
+ // 验证必需参数(仅在非交互模式下)
72
+ if (!options.interactive) {
73
+ const missing = parser_1.ArgumentParser.validateRequired(options, ['controller']);
74
+ if (missing.length > 0) {
75
+ utils_1.Console.error(`缺少必需参数: ${missing.join(', ')}`);
76
+ utils_1.Console.info('使用方法:');
77
+ utils_1.Console.info(' 交互模式: nsgm create');
78
+ utils_1.Console.info(' 命令行模式: nsgm create [controller] [action] [dictionary]');
79
+ process.exit(1);
80
+ }
81
+ }
82
+ const finalOptions = parser_1.ArgumentParser.applyDefaults(options, {
83
+ action: 'manage',
84
+ dictionary: '',
85
+ });
86
+ utils_1.Console.highlight(`🎯 创建控制器: ${finalOptions.controller}`);
87
+ utils_1.Console.info(`📝 操作: ${finalOptions.action}`);
88
+ if (finalOptions.dictionary) {
89
+ utils_1.Console.info(`📁 目录: ${finalOptions.dictionary}`);
90
+ }
91
+ const spinner = utils_1.Console.spinner('正在创建文件...', 'green');
92
+ spinner.start();
93
+ try {
94
+ // 模拟创建过程
95
+ await new Promise((resolve) => setTimeout(resolve, 800));
96
+ (0, generate_1.createFiles)(finalOptions.controller, finalOptions.action, finalOptions.dictionary, finalOptions.fields);
97
+ spinner.succeed('控制器创建完成!');
98
+ utils_1.Console.newLine();
99
+ utils_1.Console.box(`控制器 "${finalOptions.controller}" 已创建成功!\n\n` +
100
+ `操作: ${finalOptions.action}\n` +
101
+ `路径: ${finalOptions.dictionary || './'}`, 'success');
102
+ }
103
+ catch (error) {
104
+ spinner.fail('控制器创建失败');
105
+ throw error;
106
+ }
107
+ }
108
+ catch (error) {
109
+ utils_1.Console.error(`创建失败: ${error}`);
110
+ process.exit(1);
111
+ }
112
+ },
113
+ };
@@ -0,0 +1,3 @@
1
+ import { Command } from '../types';
2
+ export declare const deleteCommand: Command;
3
+ export declare const deleteDbCommand: Command;