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.
- package/README.md +394 -156
- package/client/components/Button.tsx +3 -5
- package/client/components/ClientProviders.tsx +29 -0
- package/client/components/LanguageSwitcher.tsx +59 -0
- package/client/components/SSRSafeAntdProvider.tsx +24 -0
- package/client/components/SuppressHydrationWarnings.tsx +55 -0
- package/client/components/__tests__/Button.test.tsx +10 -10
- package/client/layout/index.tsx +153 -185
- package/client/redux/reducers.ts +1 -1
- package/client/redux/store.ts +2 -1
- package/client/redux/template/manage/actions.ts +77 -88
- package/client/redux/template/manage/reducers.ts +25 -37
- package/client/redux/template/manage/types.ts +1 -1
- package/client/service/template/manage.ts +20 -21
- package/client/styled/common.ts +12 -14
- package/client/styled/layout/index.ts +234 -120
- package/client/styled/template/manage.ts +102 -14
- package/client/utils/common.ts +23 -21
- package/client/utils/cookie.ts +18 -19
- package/client/utils/fetch.ts +64 -100
- package/client/utils/i18n.ts +68 -0
- package/client/utils/menu.tsx +42 -23
- package/client/utils/navigation.ts +58 -0
- package/client/utils/sso.ts +74 -84
- package/client/utils/suppressWarnings.ts +32 -0
- package/eslint.config.js +53 -19
- package/generation/README.md +25 -6
- package/generation/__tests__/example.test.js +41 -0
- package/generation/client/redux/reducers.ts +1 -1
- package/generation/client/utils/menu.tsx +36 -23
- package/generation/env +3 -0
- package/generation/env.example +3 -0
- package/generation/eslint.config.js +112 -0
- package/generation/gitignore +6 -1
- package/generation/jest.config.js +40 -0
- package/generation/next.config.js +7 -3
- package/generation/package.json +28 -4
- package/generation/tsconfig.json +6 -19
- package/jest.config.js +23 -6
- package/lib/args.js +9 -1
- package/lib/cli/app.d.ts +28 -0
- package/lib/cli/app.js +99 -0
- package/lib/cli/commands/build.d.ts +2 -0
- package/lib/cli/commands/build.js +29 -0
- package/lib/cli/commands/create.d.ts +2 -0
- package/lib/cli/commands/create.js +113 -0
- package/lib/cli/commands/delete.d.ts +3 -0
- package/lib/cli/commands/delete.js +151 -0
- package/lib/cli/commands/export.d.ts +2 -0
- package/lib/cli/commands/export.js +42 -0
- package/lib/cli/commands/help.d.ts +2 -0
- package/lib/cli/commands/help.js +42 -0
- package/lib/cli/commands/init.d.ts +2 -0
- package/lib/cli/commands/init.js +115 -0
- package/lib/cli/commands/server.d.ts +3 -0
- package/lib/cli/commands/server.js +26 -0
- package/lib/cli/commands/upgrade.d.ts +2 -0
- package/lib/cli/commands/upgrade.js +38 -0
- package/lib/cli/commands/version.d.ts +2 -0
- package/lib/cli/commands/version.js +24 -0
- package/lib/cli/index.d.ts +16 -0
- package/lib/cli/index.js +33 -0
- package/lib/cli/parser.d.ts +22 -0
- package/lib/cli/parser.js +115 -0
- package/lib/cli/registry.d.ts +33 -0
- package/lib/cli/registry.js +81 -0
- package/lib/cli/types/project.d.ts +10 -0
- package/lib/cli/types/project.js +2 -0
- package/lib/cli/types.d.ts +31 -0
- package/lib/cli/types.js +20 -0
- package/lib/cli/utils/console.d.ts +62 -0
- package/lib/cli/utils/console.js +148 -0
- package/lib/cli/utils/index.d.ts +2 -0
- package/lib/cli/utils/index.js +7 -0
- package/lib/cli/utils/prompt.d.ts +83 -0
- package/lib/cli/utils/prompt.js +327 -0
- package/lib/constants.d.ts +65 -0
- package/lib/constants.js +177 -0
- package/lib/generate.d.ts +25 -3
- package/lib/generate.js +98 -621
- package/lib/generate_create.d.ts +9 -0
- package/lib/generate_create.js +329 -0
- package/lib/generate_delete.d.ts +8 -0
- package/lib/generate_delete.js +233 -0
- package/lib/generate_init.d.ts +56 -0
- package/lib/generate_init.js +612 -0
- package/lib/generators/base-generator.d.ts +47 -0
- package/lib/generators/base-generator.js +92 -0
- package/lib/generators/file-generator.d.ts +48 -0
- package/lib/generators/file-generator.js +455 -0
- package/lib/generators/generator-factory.d.ts +20 -0
- package/lib/generators/generator-factory.js +25 -0
- package/lib/generators/i18n-generator.d.ts +51 -0
- package/lib/generators/i18n-generator.js +320 -0
- package/lib/generators/page-generator.d.ts +45 -0
- package/lib/generators/page-generator.js +578 -0
- package/lib/generators/resolver-generator.d.ts +14 -0
- package/lib/generators/resolver-generator.js +342 -0
- package/lib/generators/schema-generator.d.ts +7 -0
- package/lib/generators/schema-generator.js +57 -0
- package/lib/generators/service-generator.d.ts +11 -0
- package/lib/generators/service-generator.js +233 -0
- package/lib/generators/sql-generator.d.ts +8 -0
- package/lib/generators/sql-generator.js +52 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.js +14 -173
- package/lib/server/csrf.js +9 -16
- package/lib/server/db.js +6 -7
- package/lib/server/graphql.js +5 -6
- package/lib/server/plugins/date.js +1 -1
- package/lib/server/utils/graphql-cache.js +3 -3
- package/lib/tsconfig.build.tsbuildinfo +1 -1
- package/lib/utils/project-config.d.ts +5 -0
- package/lib/utils/project-config.js +145 -0
- package/lib/utils.js +1 -1
- package/next-i18next.config.js +18 -0
- package/next.config.js +61 -18
- package/package.json +16 -8
- package/pages/_app.tsx +77 -33
- package/pages/_document.tsx +78 -21
- package/pages/_error.tsx +66 -0
- package/pages/index.tsx +109 -47
- package/pages/login.tsx +66 -41
- package/pages/template/manage.tsx +162 -151
- package/public/fonts/font-awesome.min.css +4 -0
- package/public/fonts/fontawesome-webfont.woff +0 -0
- package/public/fonts/fontawesome-webfont.woff2 +0 -0
- package/public/locales/en-US/common.json +48 -0
- package/public/locales/en-US/home.json +57 -0
- package/public/locales/en-US/layout.json +22 -0
- package/public/locales/en-US/login.json +13 -0
- package/public/locales/en-US/template.json +42 -0
- package/public/locales/ja-JP/common.json +48 -0
- package/public/locales/ja-JP/home.json +57 -0
- package/public/locales/ja-JP/layout.json +22 -0
- package/public/locales/ja-JP/login.json +13 -0
- package/public/locales/ja-JP/template.json +42 -0
- package/public/locales/zh-CN/common.json +48 -0
- package/public/locales/zh-CN/home.json +57 -0
- package/public/locales/zh-CN/layout.json +22 -0
- package/public/locales/zh-CN/login.json +13 -0
- package/public/locales/zh-CN/template.json +42 -0
- package/public/slbhealthcheck.html +1 -1
- package/server/apis/template.js +0 -2
- package/server/utils/validation.js +163 -0
- package/types/i18next.d.ts +10 -0
- package/generation/eslintrc.js +0 -16
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SQLGenerator = void 0;
|
|
4
|
+
const base_generator_1 = require("./base-generator");
|
|
5
|
+
/**
|
|
6
|
+
* SQL生成器
|
|
7
|
+
* 专门负责生成数据库表结构
|
|
8
|
+
*/
|
|
9
|
+
class SQLGenerator extends base_generator_1.BaseGenerator {
|
|
10
|
+
generate() {
|
|
11
|
+
const fieldDefinitions = this.fields.map((field) => {
|
|
12
|
+
let sql = ` \`${field.name}\``;
|
|
13
|
+
// 数据类型
|
|
14
|
+
sql += ` ${this.getSQLType(field)}`;
|
|
15
|
+
// 是否必填
|
|
16
|
+
if (field.required && !field.isAutoIncrement) {
|
|
17
|
+
sql += ' NOT NULL';
|
|
18
|
+
}
|
|
19
|
+
else if (!field.required) {
|
|
20
|
+
sql += ' DEFAULT NULL';
|
|
21
|
+
}
|
|
22
|
+
// 自增
|
|
23
|
+
if (field.isAutoIncrement) {
|
|
24
|
+
sql += ' AUTO_INCREMENT';
|
|
25
|
+
}
|
|
26
|
+
// 默认值
|
|
27
|
+
if (field.type === 'timestamp' && field.name === 'create_date') {
|
|
28
|
+
sql += ' DEFAULT CURRENT_TIMESTAMP(3)';
|
|
29
|
+
}
|
|
30
|
+
else if (field.type === 'timestamp' && field.name === 'update_date') {
|
|
31
|
+
sql += ' DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)';
|
|
32
|
+
}
|
|
33
|
+
else if (field.type === 'varchar' && field.name !== 'id' && !field.required) {
|
|
34
|
+
sql += " DEFAULT ''";
|
|
35
|
+
}
|
|
36
|
+
// 注释
|
|
37
|
+
if (field.comment) {
|
|
38
|
+
sql += ` COMMENT '${field.comment}'`;
|
|
39
|
+
}
|
|
40
|
+
return sql;
|
|
41
|
+
});
|
|
42
|
+
const primaryKeyField = this.fields.find((f) => f.isPrimaryKey);
|
|
43
|
+
const primaryKey = primaryKeyField ? ` PRIMARY KEY (\`${primaryKeyField.name}\`)` : '';
|
|
44
|
+
return `use crm_demo;
|
|
45
|
+
|
|
46
|
+
CREATE TABLE \`${this.controller}\` (
|
|
47
|
+
${fieldDefinitions.join(',\n')},
|
|
48
|
+
${primaryKey}
|
|
49
|
+
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.SQLGenerator = SQLGenerator;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#! /usr/bin/env node
|
|
2
|
-
export declare const startExpress: (options: any, callback?: () => void) => void;
|
|
2
|
+
export declare const startExpress: (options: any, callback?: () => void, command?: string) => void;
|
package/lib/index.js
CHANGED
|
@@ -6,7 +6,7 @@ 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();
|
|
9
|
+
require('dotenv').config({ quiet: true });
|
|
10
10
|
// 仅在开发环境中禁用TLS证书验证
|
|
11
11
|
if (process.env.NODE_ENV === 'development') {
|
|
12
12
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
|
|
@@ -16,24 +16,17 @@ const express_1 = __importDefault(require("express"));
|
|
|
16
16
|
const url_1 = require("url");
|
|
17
17
|
const fs_1 = __importDefault(require("fs"));
|
|
18
18
|
const path_1 = __importDefault(require("path"));
|
|
19
|
-
const child_process_1 = require("child_process");
|
|
20
19
|
const body_parser_1 = __importDefault(require("body-parser"));
|
|
21
20
|
const express_fileupload_1 = __importDefault(require("express-fileupload"));
|
|
22
|
-
const args_1 = require("./args");
|
|
23
21
|
const graphql_1 = __importDefault(require("./server/graphql"));
|
|
24
22
|
const config_1 = __importDefault(require("next/config"));
|
|
25
|
-
const generate_1 = require("./generate");
|
|
26
|
-
const lodash_1 = __importDefault(require("lodash"));
|
|
27
23
|
const cors_1 = __importDefault(require("cors"));
|
|
28
24
|
const express_session_1 = __importDefault(require("express-session"));
|
|
29
25
|
const csrf_1 = require("./server/csrf");
|
|
26
|
+
const cli_1 = require("./cli");
|
|
30
27
|
const { resolve } = path_1.default;
|
|
31
28
|
const curFolder = process.cwd();
|
|
32
|
-
const
|
|
33
|
-
// console.log('processArgvs', processArgvs)
|
|
34
|
-
const { command, dictionary, controller, action } = processArgvs;
|
|
35
|
-
// console.log('processArgvs', processArgvs)
|
|
36
|
-
const handleServer = (server, prefix) => {
|
|
29
|
+
const handleServer = (server, prefix, _command) => {
|
|
37
30
|
// 本项目路径是 NSGM-CLI/server 目录,生成项目路径是 generation/server 目录
|
|
38
31
|
const serverPath = resolve(`${curFolder}/server/`);
|
|
39
32
|
if (fs_1.default.existsSync(serverPath)) {
|
|
@@ -48,7 +41,6 @@ const handleServer = (server, prefix) => {
|
|
|
48
41
|
if (item.indexOf('.') !== -1) {
|
|
49
42
|
filename = item.split('.')[0];
|
|
50
43
|
}
|
|
51
|
-
// console.log('resolverPath', resolverPath, filename)
|
|
52
44
|
if (server && filename !== undefined && filename !== '') {
|
|
53
45
|
try {
|
|
54
46
|
const routeModule = require(resolverPath);
|
|
@@ -71,7 +63,7 @@ const handleServer = (server, prefix) => {
|
|
|
71
63
|
});
|
|
72
64
|
}
|
|
73
65
|
};
|
|
74
|
-
const startExpress = (options, callback) => {
|
|
66
|
+
const startExpress = (options, callback, command = 'dev') => {
|
|
75
67
|
// console.info('startExpress', curFolder)
|
|
76
68
|
const app = (0, next_1.default)(options);
|
|
77
69
|
const handle = app.getRequestHandler();
|
|
@@ -105,18 +97,18 @@ const startExpress = (options, callback) => {
|
|
|
105
97
|
httpOnly: true,
|
|
106
98
|
maxAge: 24 * 60 * 60 * 1000, // 24小时
|
|
107
99
|
sameSite: 'lax', // 设置 SameSite 策略
|
|
108
|
-
domain: undefined // 不设置 domain,使用默认
|
|
109
|
-
}
|
|
100
|
+
domain: undefined, // 不设置 domain,使用默认
|
|
101
|
+
},
|
|
110
102
|
}));
|
|
111
103
|
// 初始化 CSRF token - 移除全局初始化,让每个端点自己处理
|
|
112
104
|
// server.use(setupCSRFToken)
|
|
113
105
|
server.use(body_parser_1.default.urlencoded({
|
|
114
|
-
extended: false
|
|
106
|
+
extended: false,
|
|
115
107
|
}));
|
|
116
108
|
// 支持跨域,nsgm export 之后前后分离
|
|
117
109
|
server.use((0, cors_1.default)({
|
|
118
110
|
credentials: true, // 允许发送 cookies
|
|
119
|
-
origin: process.env.ALLOWED_ORIGINS?.split(',') || ['http://localhost:3000']
|
|
111
|
+
origin: process.env.ALLOWED_ORIGINS?.split(',') || ['http://localhost:3000'],
|
|
120
112
|
}));
|
|
121
113
|
server.use(body_parser_1.default.json());
|
|
122
114
|
// 添加基本安全中间件
|
|
@@ -139,10 +131,9 @@ const startExpress = (options, callback) => {
|
|
|
139
131
|
server.use(`${prefix}/static`, express_1.default.static(path_1.default.join(__dirname, 'public')));
|
|
140
132
|
server.use(`${prefix}/graphql`, (0, graphql_1.default)(command));
|
|
141
133
|
}
|
|
142
|
-
handleServer(server, prefix);
|
|
134
|
+
handleServer(server, prefix, command);
|
|
143
135
|
server.get('*', (req, res) => {
|
|
144
136
|
const { url } = req;
|
|
145
|
-
// console.log('url: ' + url)
|
|
146
137
|
const parsedUrl = (0, url_1.parse)(url, true);
|
|
147
138
|
return handle(req, res, parsedUrl);
|
|
148
139
|
});
|
|
@@ -156,158 +147,8 @@ const startExpress = (options, callback) => {
|
|
|
156
147
|
});
|
|
157
148
|
};
|
|
158
149
|
exports.startExpress = startExpress;
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
case 'start':
|
|
165
|
-
(0, exports.startExpress)({ dev: false }, undefined);
|
|
166
|
-
break;
|
|
167
|
-
case 'build':
|
|
168
|
-
(0, child_process_1.exec)('next build', {}, (err, stdout) => {
|
|
169
|
-
if (err) {
|
|
170
|
-
console.log(err);
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
console.log(`stdout: ${stdout}`);
|
|
174
|
-
process.exit(0);
|
|
175
|
-
});
|
|
176
|
-
break;
|
|
177
|
-
case 'export':
|
|
178
|
-
let shellCommand = `next ${command}`;
|
|
179
|
-
// console.log('dictionary', dictionary)
|
|
180
|
-
if (dictionary === '') {
|
|
181
|
-
shellCommand += ' -o webapp';
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
shellCommand += ` -o ${dictionary}`;
|
|
185
|
-
}
|
|
186
|
-
(0, child_process_1.exec)(shellCommand, {}, (err, stdout) => {
|
|
187
|
-
if (err) {
|
|
188
|
-
console.log(err);
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
console.log(`stdout: ${stdout}`);
|
|
192
|
-
process.exit(0);
|
|
193
|
-
});
|
|
194
|
-
break;
|
|
195
|
-
case '-i':
|
|
196
|
-
case 'init':
|
|
197
|
-
case '--init':
|
|
198
|
-
let initFlag = true;
|
|
199
|
-
// console.log('process.argv', process.argv)
|
|
200
|
-
const argvArr = process.argv;
|
|
201
|
-
const argvArrLen = argvArr.length;
|
|
202
|
-
let fileName = '';
|
|
203
|
-
if (argvArrLen > 2) {
|
|
204
|
-
fileName = argvArr[2];
|
|
205
|
-
}
|
|
206
|
-
else if (argvArrLen > 1) {
|
|
207
|
-
fileName = argvArr[1];
|
|
208
|
-
}
|
|
209
|
-
// console.log('fileName', fileName)
|
|
210
|
-
if (fileName !== '') {
|
|
211
|
-
if (fileName.indexOf('\\') !== -1) {
|
|
212
|
-
fileName = fileName.replace(/\\/g, '/');
|
|
213
|
-
// console.log('fileName2', fileName)
|
|
214
|
-
}
|
|
215
|
-
const fileNameArr = fileName.split('/');
|
|
216
|
-
const fileNameArrLen = fileNameArr.length;
|
|
217
|
-
const fileNameStr = fileNameArr[fileNameArrLen - 1];
|
|
218
|
-
// console.log('fileNameStr', fileNameStr)
|
|
219
|
-
if (fileNameStr === 'app') {
|
|
220
|
-
initFlag = false;
|
|
221
|
-
}
|
|
222
|
-
lodash_1.default.each(fileNameArr, (item) => {
|
|
223
|
-
if (item === 'pm2') {
|
|
224
|
-
initFlag = false;
|
|
225
|
-
return false;
|
|
226
|
-
}
|
|
227
|
-
return;
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
console.log('initFlag', initFlag);
|
|
231
|
-
if (initFlag) {
|
|
232
|
-
(0, generate_1.initFiles)(dictionary);
|
|
233
|
-
}
|
|
234
|
-
process.exit(0);
|
|
235
|
-
case '-u':
|
|
236
|
-
case 'upgrade':
|
|
237
|
-
case '--upgrade':
|
|
238
|
-
(0, generate_1.initFiles)(dictionary, true);
|
|
239
|
-
process.exit(0);
|
|
240
|
-
case '-c':
|
|
241
|
-
case 'create':
|
|
242
|
-
case '--create':
|
|
243
|
-
console.log(command, controller, action);
|
|
244
|
-
if (controller !== '') {
|
|
245
|
-
if (action === '') {
|
|
246
|
-
(0, generate_1.createFiles)(controller, 'manage');
|
|
247
|
-
}
|
|
248
|
-
else {
|
|
249
|
-
(0, generate_1.createFiles)(controller, action);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
break;
|
|
253
|
-
case '-d':
|
|
254
|
-
case 'delete':
|
|
255
|
-
case '--delete':
|
|
256
|
-
console.log(command, controller, action);
|
|
257
|
-
if (controller !== '') {
|
|
258
|
-
if (action === '' || action === 'all') {
|
|
259
|
-
(0, generate_1.deleteFiles)(controller, 'all');
|
|
260
|
-
}
|
|
261
|
-
else {
|
|
262
|
-
(0, generate_1.deleteFiles)(controller, action);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
break;
|
|
266
|
-
case '-db':
|
|
267
|
-
case 'deletedb':
|
|
268
|
-
case '--deletedb':
|
|
269
|
-
console.log(command, controller, action);
|
|
270
|
-
if (controller !== '') {
|
|
271
|
-
if (action === '' || action === 'all') {
|
|
272
|
-
(0, generate_1.deleteFiles)(controller, 'all', true);
|
|
273
|
-
}
|
|
274
|
-
else {
|
|
275
|
-
(0, generate_1.deleteFiles)(controller, action);
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
break;
|
|
279
|
-
case '-v':
|
|
280
|
-
case 'version':
|
|
281
|
-
case '--version':
|
|
282
|
-
const { version } = require('../package.json');
|
|
283
|
-
console.log(`version: ${version}`);
|
|
284
|
-
/*
|
|
285
|
-
startExpress({ dev: true, quiet: true, dir: '.' }, () => {
|
|
286
|
-
const nextConfig = getConfig()
|
|
287
|
-
const { publicRuntimeConfig } = nextConfig
|
|
288
|
-
const { version } = publicRuntimeConfig
|
|
289
|
-
console.log('version: ' + version)
|
|
290
|
-
process.exit(0)
|
|
291
|
-
})
|
|
292
|
-
*/
|
|
293
|
-
process.exit(0);
|
|
294
|
-
case '-h':
|
|
295
|
-
case 'help':
|
|
296
|
-
case '--help':
|
|
297
|
-
default:
|
|
298
|
-
console.log('Welcome to use NSGM');
|
|
299
|
-
console.log(` -h or help: get nsgm help infomation`);
|
|
300
|
-
console.log(` -v or version: get nsgm version`);
|
|
301
|
-
console.log(` -i or init: nsgm init dictionary (default dictionary is .)`);
|
|
302
|
-
console.log(` -u or upgrade: nsgm upgrade`);
|
|
303
|
-
console.log(` -c or create: nsgm create controller action (default action is manage)`);
|
|
304
|
-
console.log(` -d or delete: nsgm delete controller action (default action is manage)`);
|
|
305
|
-
console.log(` dev: nsgm dev (development mode)`);
|
|
306
|
-
console.log(` build: nsgm build (production mode)`);
|
|
307
|
-
console.log(` start: nsgm start (production mode)`);
|
|
308
|
-
console.log(` export: nsgm export dictionary (default dictionary is webapp)`);
|
|
309
|
-
console.log('Happy to use');
|
|
310
|
-
console.log('If you have some question, please contact Erishen (787058731@qq.com). Thanks!');
|
|
311
|
-
break;
|
|
312
|
-
}
|
|
313
|
-
console.log();
|
|
150
|
+
// 使用新的 CLI 架构
|
|
151
|
+
(0, cli_1.runCli)().catch((error) => {
|
|
152
|
+
console.error('CLI 执行失败:', error);
|
|
153
|
+
process.exit(1);
|
|
154
|
+
});
|
package/lib/server/csrf.js
CHANGED
|
@@ -12,7 +12,7 @@ const luscaConfig = {
|
|
|
12
12
|
header: 'x-csrf-token', // 从 header 中读取 token
|
|
13
13
|
cookie: '_csrf', // cookie 名称
|
|
14
14
|
key: 'csrf', // session key
|
|
15
|
-
secret: process.env.CSRF_SECRET || 'your-csrf-secret-change-in-production'
|
|
15
|
+
secret: process.env.CSRF_SECRET || 'your-csrf-secret-change-in-production',
|
|
16
16
|
},
|
|
17
17
|
// 内容安全策略
|
|
18
18
|
csp: {
|
|
@@ -22,18 +22,17 @@ const luscaConfig = {
|
|
|
22
22
|
'style-src': "'self' 'unsafe-inline'",
|
|
23
23
|
'img-src': "'self' data: https:",
|
|
24
24
|
'font-src': "'self' https:",
|
|
25
|
-
'connect-src': "'self'"
|
|
26
|
-
}
|
|
25
|
+
'connect-src': "'self'",
|
|
26
|
+
},
|
|
27
27
|
},
|
|
28
28
|
// 其他安全设置
|
|
29
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
|
-
// console.log('CSRF 中间件 - 路径:', req.path, '方法:', req.method)
|
|
37
36
|
// 跳过 GET 请求和某些不需要 CSRF 保护的路径
|
|
38
37
|
if (req.method === 'GET' ||
|
|
39
38
|
req.path.startsWith('/static') ||
|
|
@@ -41,11 +40,9 @@ const csrfProtection = (req, res, next) => {
|
|
|
41
40
|
req.path.startsWith('/_next') || // Next.js 内部资源
|
|
42
41
|
req.path.startsWith('/__next') // Next.js 开发模式内部端点
|
|
43
42
|
) {
|
|
44
|
-
// console.log('CSRF 中间件 - 跳过保护')
|
|
45
43
|
return next();
|
|
46
44
|
}
|
|
47
45
|
// 对其他请求应用 Lusca CSRF 保护
|
|
48
|
-
// console.log('CSRF 中间件 - 应用 Lusca 保护')
|
|
49
46
|
return lusca_1.default.csrf(luscaConfig.csrf)(req, res, next);
|
|
50
47
|
};
|
|
51
48
|
exports.csrfProtection = csrfProtection;
|
|
@@ -58,18 +55,14 @@ const getCSRFToken = (req, res) => {
|
|
|
58
55
|
// 如果没有 token,先生成一个
|
|
59
56
|
lusca_1.default.csrf(luscaConfig.csrf)(req, res, () => {
|
|
60
57
|
const newToken = req.session._csrf || req.session[luscaConfig.csrf.key] || req.csrfToken?.();
|
|
61
|
-
// console.log('生成新的 CSRF token:', newToken)
|
|
62
|
-
// console.log('Token 生成时的 Session ID:', req.sessionID)
|
|
63
58
|
res.json({
|
|
64
|
-
csrfToken: newToken
|
|
59
|
+
csrfToken: newToken,
|
|
65
60
|
});
|
|
66
61
|
});
|
|
67
62
|
}
|
|
68
63
|
else {
|
|
69
|
-
// console.log('返回现有 CSRF token:', csrfToken)
|
|
70
|
-
// console.log('Token 生成时的 Session ID:', req.sessionID)
|
|
71
64
|
res.json({
|
|
72
|
-
csrfToken: csrfToken
|
|
65
|
+
csrfToken: csrfToken,
|
|
73
66
|
});
|
|
74
67
|
}
|
|
75
68
|
}
|
|
@@ -77,7 +70,7 @@ const getCSRFToken = (req, res) => {
|
|
|
77
70
|
console.error('获取 CSRF token 错误:', error);
|
|
78
71
|
res.status(500).json({
|
|
79
72
|
error: 'Failed to generate CSRF token',
|
|
80
|
-
message: '生成 CSRF 令牌失败'
|
|
73
|
+
message: '生成 CSRF 令牌失败',
|
|
81
74
|
});
|
|
82
75
|
}
|
|
83
76
|
};
|
|
@@ -89,8 +82,8 @@ exports.securityMiddleware = {
|
|
|
89
82
|
xframe: luscaConfig.xframe,
|
|
90
83
|
nosniff: luscaConfig.nosniff,
|
|
91
84
|
xssProtection: luscaConfig.xssProtection,
|
|
92
|
-
referrerPolicy: luscaConfig.referrerPolicy
|
|
93
|
-
})
|
|
85
|
+
referrerPolicy: luscaConfig.referrerPolicy,
|
|
86
|
+
}),
|
|
94
87
|
};
|
|
95
88
|
// CSP 中间件
|
|
96
89
|
const createCSPMiddleware = () => {
|
package/lib/server/db.js
CHANGED
|
@@ -20,7 +20,6 @@ const getMysqlConfig = () => {
|
|
|
20
20
|
mysqlConfig = require('../../mysql.config.js');
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
|
-
// console.log('mysqlConfig', mysqlConfig)
|
|
24
23
|
return mysqlConfig;
|
|
25
24
|
};
|
|
26
25
|
// 创建连接池
|
|
@@ -39,7 +38,7 @@ const createPool = ({ user, password, host, port, database }) => {
|
|
|
39
38
|
maxIdle: 10, // 最大空闲连接数
|
|
40
39
|
multipleStatements: false, // 禁用多语句查询以提高安全性
|
|
41
40
|
bigNumberStrings: true, // 将大数字作为字符串返回
|
|
42
|
-
supportBigNumbers: true // 支持大数字
|
|
41
|
+
supportBigNumbers: true, // 支持大数字
|
|
43
42
|
});
|
|
44
43
|
// 监听连接池事件
|
|
45
44
|
pool.on('connection', (connection) => {
|
|
@@ -101,7 +100,7 @@ const executePaginatedQuery = async (sql, countSql, values, countValues = []) =>
|
|
|
101
100
|
const [results, countResults] = await Promise.all([executeQuery(sql, values), executeQuery(countSql, countValues)]);
|
|
102
101
|
return {
|
|
103
102
|
totalCounts: countResults[0].counts,
|
|
104
|
-
items: results
|
|
103
|
+
items: results,
|
|
105
104
|
};
|
|
106
105
|
}
|
|
107
106
|
catch (error) {
|
|
@@ -141,13 +140,13 @@ const mysqlConnect = ({ user, password, host, port, database }) => {
|
|
|
141
140
|
resolve(connection);
|
|
142
141
|
}
|
|
143
142
|
else {
|
|
144
|
-
console.
|
|
143
|
+
console.error('err_mysqlConnect: ', err);
|
|
145
144
|
reject();
|
|
146
145
|
}
|
|
147
146
|
});
|
|
148
147
|
}
|
|
149
148
|
catch (e) {
|
|
150
|
-
console.
|
|
149
|
+
console.error('e_mysqlConnect: ', e);
|
|
151
150
|
reject();
|
|
152
151
|
}
|
|
153
152
|
}
|
|
@@ -167,7 +166,7 @@ const getConnection = () => {
|
|
|
167
166
|
mysqlConnect(mysqlOptions)
|
|
168
167
|
.then(resolve)
|
|
169
168
|
.catch((err) => {
|
|
170
|
-
console.
|
|
169
|
+
console.error('e_getConnection', err);
|
|
171
170
|
reject(err);
|
|
172
171
|
});
|
|
173
172
|
}
|
|
@@ -188,5 +187,5 @@ exports.default = {
|
|
|
188
187
|
getPool, // 新的连接池方法
|
|
189
188
|
executeQuery, // 新的查询方法
|
|
190
189
|
executePaginatedQuery, // 新的分页查询方法
|
|
191
|
-
closePool // 关闭连接池方法
|
|
190
|
+
closePool, // 关闭连接池方法
|
|
192
191
|
};
|
package/lib/server/graphql.js
CHANGED
|
@@ -35,7 +35,7 @@ const handleOutPlugins = () => {
|
|
|
35
35
|
const pluginModule = require(resolverPath);
|
|
36
36
|
result = {
|
|
37
37
|
...result,
|
|
38
|
-
...(pluginModule.default || pluginModule)
|
|
38
|
+
...(pluginModule.default || pluginModule),
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
41
|
});
|
|
@@ -50,7 +50,7 @@ function generateTypeDefsAndResolvers() {
|
|
|
50
50
|
if (process.env.NODE_ENV === 'production' && cachedSchema && cachedResolvers) {
|
|
51
51
|
return {
|
|
52
52
|
schemaStr: cachedSchema,
|
|
53
|
-
resolvers: cachedResolvers
|
|
53
|
+
resolvers: cachedResolvers,
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
56
|
const querySchemes = ['_: Boolean'];
|
|
@@ -59,14 +59,13 @@ function generateTypeDefsAndResolvers() {
|
|
|
59
59
|
const typeSchemes = [];
|
|
60
60
|
const resolvers = {
|
|
61
61
|
...date_1.default,
|
|
62
|
-
...handleOutPlugins()
|
|
62
|
+
...handleOutPlugins(),
|
|
63
63
|
};
|
|
64
64
|
const scalars = lodash_1.default.keys(resolvers);
|
|
65
65
|
let scalarStr = '';
|
|
66
66
|
lodash_1.default.each(scalars, (item) => {
|
|
67
67
|
scalarStr += `scalar ${item}\n `;
|
|
68
68
|
});
|
|
69
|
-
// console.log('resolvers', resolvers, _.keys(resolvers), scalarStr)
|
|
70
69
|
const _generateAllComponentRecursive = (path = defaultPath) => {
|
|
71
70
|
if (!fs_1.default.existsSync(path))
|
|
72
71
|
return;
|
|
@@ -149,7 +148,7 @@ function generateTypeDefsAndResolvers() {
|
|
|
149
148
|
return { querySchemes, mutationSchemes, subscriptionSchemes, typeSchemes, resolvers, scalarStr, schemaStr };
|
|
150
149
|
}
|
|
151
150
|
const generateResult = generateTypeDefsAndResolvers();
|
|
152
|
-
const { querySchemes: querySchemesV, mutationSchemes: mutationSchemesV, subscriptionSchemes: subscriptionSchemesV, typeSchemes: typeSchemesV, resolvers: resolversV, scalarStr: scalarStrV, schemaStr: generatedSchemaStr } = generateResult;
|
|
151
|
+
const { querySchemes: querySchemesV, mutationSchemes: mutationSchemesV, subscriptionSchemes: subscriptionSchemesV, typeSchemes: typeSchemesV, resolvers: resolversV, scalarStr: scalarStrV, schemaStr: generatedSchemaStr, } = generateResult;
|
|
153
152
|
// 导出 handler 函数,兼容 express 用法
|
|
154
153
|
const handler = (command) => {
|
|
155
154
|
const schemaStr = generatedSchemaStr ||
|
|
@@ -177,7 +176,7 @@ const handler = (command) => {
|
|
|
177
176
|
// graphql-http 不再内置 graphiql,需手动集成 playground 或 altair,以下为基础 handler
|
|
178
177
|
return (0, express_1.createHandler)({
|
|
179
178
|
schema: (0, graphql_1.buildSchema)(schemaStr),
|
|
180
|
-
rootValue: resolversV
|
|
179
|
+
rootValue: resolversV,
|
|
181
180
|
});
|
|
182
181
|
};
|
|
183
182
|
exports.default = handler;
|
|
@@ -27,7 +27,7 @@ const graphqlCacheMiddleware = (req, res, next) => {
|
|
|
27
27
|
if (!data.errors) {
|
|
28
28
|
queryCache.set(cacheKey, {
|
|
29
29
|
data,
|
|
30
|
-
timestamp: now
|
|
30
|
+
timestamp: now,
|
|
31
31
|
});
|
|
32
32
|
// 清理过期缓存
|
|
33
33
|
cleanExpiredCache();
|
|
@@ -62,8 +62,8 @@ const getCacheStats = () => {
|
|
|
62
62
|
size: queryCache.size,
|
|
63
63
|
entries: Array.from(queryCache.keys()).map((key) => ({
|
|
64
64
|
query: `${key.substring(0, 100)}...`,
|
|
65
|
-
age: Date.now() - queryCache.get(key).timestamp
|
|
66
|
-
}))
|
|
65
|
+
age: Date.now() - queryCache.get(key).timestamp,
|
|
66
|
+
})),
|
|
67
67
|
};
|
|
68
68
|
};
|
|
69
69
|
exports.getCacheStats = getCacheStats;
|