q-koa 13.8.47 → 13.8.49
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/core/app.js
CHANGED
|
@@ -101,6 +101,26 @@ const connectDatabase = (database) => (config) => {
|
|
|
101
101
|
const defaultConfig = require('./config')
|
|
102
102
|
|
|
103
103
|
const is_dev = process.env.NODE_ENV !== 'production'
|
|
104
|
+
|
|
105
|
+
// JWT 兜底配置(应用未配置 jwt 时使用),提为模块级常量避免每个请求重建对象
|
|
106
|
+
const DEFAULT_JWT = {
|
|
107
|
+
secret: 'token',
|
|
108
|
+
tokenKey: 'token',
|
|
109
|
+
expiresIn: '200000000',
|
|
110
|
+
_whiteList: [],
|
|
111
|
+
whiteList: [
|
|
112
|
+
'find',
|
|
113
|
+
'administrator/login',
|
|
114
|
+
'administrator/checkLogin',
|
|
115
|
+
'user/checkLogin',
|
|
116
|
+
'user/login',
|
|
117
|
+
'user/register',
|
|
118
|
+
'common',
|
|
119
|
+
'good/search',
|
|
120
|
+
'category/tree',
|
|
121
|
+
'system',
|
|
122
|
+
],
|
|
123
|
+
}
|
|
104
124
|
class APP {
|
|
105
125
|
constructor(_config) {
|
|
106
126
|
const config = _.defaultsDeep(_config, defaultConfig)
|
|
@@ -181,18 +201,13 @@ class APP {
|
|
|
181
201
|
this.app.use(async (ctx, next) => {
|
|
182
202
|
const { url, host, ip, method } = ctx.request
|
|
183
203
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
ctx.request.header['user-agent'].includes('Tencent Security')
|
|
187
|
-
) {
|
|
204
|
+
const userAgent = ctx.request.header['user-agent'] || ''
|
|
205
|
+
if (userAgent.includes('Tencent Security')) {
|
|
188
206
|
return ctx.ERROR('error')
|
|
189
207
|
}
|
|
190
208
|
|
|
191
|
-
if (
|
|
192
|
-
|
|
193
|
-
ctx.request.header['user-agent'].includes('Apache-HttpClient')
|
|
194
|
-
) {
|
|
195
|
-
throw new Error(`error`)
|
|
209
|
+
if (userAgent.includes('Apache-HttpClient')) {
|
|
210
|
+
throw new Error('error')
|
|
196
211
|
}
|
|
197
212
|
|
|
198
213
|
if (this.config.blackList.includes(ip)) {
|
|
@@ -208,24 +223,7 @@ class APP {
|
|
|
208
223
|
const { secret, whiteList, _whiteList, tokenKey, expiresIn } =
|
|
209
224
|
ctx.app[appName] && ctx.app[appName].appConfig
|
|
210
225
|
? ctx.app[appName].appConfig.jwt
|
|
211
|
-
:
|
|
212
|
-
secret: 'token',
|
|
213
|
-
tokenKey: 'token',
|
|
214
|
-
expiresIn: '200000000',
|
|
215
|
-
_whiteList: [],
|
|
216
|
-
whiteList: [
|
|
217
|
-
'find',
|
|
218
|
-
'administrator/login',
|
|
219
|
-
'administrator/checkLogin',
|
|
220
|
-
'user/checkLogin',
|
|
221
|
-
'user/login',
|
|
222
|
-
'user/register',
|
|
223
|
-
'common',
|
|
224
|
-
'good/search',
|
|
225
|
-
'category/tree',
|
|
226
|
-
'system',
|
|
227
|
-
],
|
|
228
|
-
}
|
|
226
|
+
: DEFAULT_JWT
|
|
229
227
|
|
|
230
228
|
/**
|
|
231
229
|
* 挂在jwt解密方法
|
|
@@ -296,7 +294,12 @@ class APP {
|
|
|
296
294
|
|
|
297
295
|
this.app.on('error', async (err, ctx) => {
|
|
298
296
|
// AggregateError(Node 17+ DNS 双栈解析等场景)取第一个子错误作为实际错误
|
|
299
|
-
if (
|
|
297
|
+
if (
|
|
298
|
+
err &&
|
|
299
|
+
err.name === 'AggregateError' &&
|
|
300
|
+
Array.isArray(err.errors) &&
|
|
301
|
+
err.errors.length > 0
|
|
302
|
+
) {
|
|
300
303
|
err = err.errors[0]
|
|
301
304
|
}
|
|
302
305
|
const { url } = ctx.request
|
|
@@ -333,9 +336,7 @@ class APP {
|
|
|
333
336
|
? this.config.includes[0]
|
|
334
337
|
: this.config.includes[0].app
|
|
335
338
|
if (!this.app[appName]) {
|
|
336
|
-
throw new Error(
|
|
337
|
-
`没有生成应用${this.config.includes[0]},请检查config includes`
|
|
338
|
-
)
|
|
339
|
+
throw new Error(`没有生成应用${appName},请检查config includes`)
|
|
339
340
|
}
|
|
340
341
|
this.server = this.app.listen(this.port, () => {
|
|
341
342
|
console.log(
|
|
@@ -444,9 +445,7 @@ class APP {
|
|
|
444
445
|
dirList = dirList.filter((item) => includeList.some((i) => i.app === item))
|
|
445
446
|
|
|
446
447
|
let dbFlag = false
|
|
447
|
-
for (
|
|
448
|
-
const appName = dirList[i]
|
|
449
|
-
|
|
448
|
+
for (const appName of dirList) {
|
|
450
449
|
console.log(
|
|
451
450
|
chalk.green(`==================== 启动 ${appName} ====================`)
|
|
452
451
|
)
|
|
@@ -671,8 +670,7 @@ class APP {
|
|
|
671
670
|
(item) => !excludesModel.includes(item)
|
|
672
671
|
)
|
|
673
672
|
|
|
674
|
-
for (
|
|
675
|
-
const folder = pluginDirResult[i]
|
|
673
|
+
for (const folder of pluginDirResult) {
|
|
676
674
|
const isFolder = fs
|
|
677
675
|
.lstatSync(path.resolve(pluginDir, folder))
|
|
678
676
|
.isDirectory()
|
|
@@ -775,8 +773,7 @@ class APP {
|
|
|
775
773
|
hookList = [...hookList, 'beforeBulkDestroy']
|
|
776
774
|
}
|
|
777
775
|
let reduceHook = {}
|
|
778
|
-
for (
|
|
779
|
-
const hook = hookList[i]
|
|
776
|
+
for (const hook of hookList) {
|
|
780
777
|
reduceHook = {
|
|
781
778
|
...reduceHook,
|
|
782
779
|
[hook]: (target, t) => {
|
|
@@ -979,8 +976,7 @@ class APP {
|
|
|
979
976
|
},
|
|
980
977
|
this.app[appName]
|
|
981
978
|
)
|
|
982
|
-
for (
|
|
983
|
-
const model = Object.keys(this.app[appName].model)[i]
|
|
979
|
+
for (const model of modelList) {
|
|
984
980
|
|
|
985
981
|
// if (!this.app[appName].include || !this.app[appName].include[model]) {
|
|
986
982
|
// this.app[appName] = _.defaultsDeep(
|
|
@@ -1161,8 +1157,8 @@ class APP {
|
|
|
1161
1157
|
'controller',
|
|
1162
1158
|
'afterExecute',
|
|
1163
1159
|
]
|
|
1164
|
-
for (
|
|
1165
|
-
if (_.get(app, `${appName}.${
|
|
1160
|
+
for (const hook of hooksList) {
|
|
1161
|
+
if (_.get(app, `${appName}.${hook}.${controller}.${fn}`)) {
|
|
1166
1162
|
// if (hooksList[i] === 'controller') {
|
|
1167
1163
|
// process.once('unhandledRejection', (reason, promise) => {
|
|
1168
1164
|
// if (
|
|
@@ -1181,7 +1177,7 @@ class APP {
|
|
|
1181
1177
|
// }
|
|
1182
1178
|
// })
|
|
1183
1179
|
// }
|
|
1184
|
-
await app[appName][
|
|
1180
|
+
await app[appName][hook][controller][fn](ctx)
|
|
1185
1181
|
}
|
|
1186
1182
|
}
|
|
1187
1183
|
|
|
@@ -1209,9 +1205,9 @@ class APP {
|
|
|
1209
1205
|
}
|
|
1210
1206
|
|
|
1211
1207
|
const hooksList = ['beforeValidate', 'validate', 'afterValidate']
|
|
1212
|
-
for (
|
|
1213
|
-
if (_.get(app, `${appName}.${
|
|
1214
|
-
await app[appName][
|
|
1208
|
+
for (const hook of hooksList) {
|
|
1209
|
+
if (_.get(app, `${appName}.${hook}.${controller}.${fn}`)) {
|
|
1210
|
+
await app[appName][hook][controller][fn](ctx)
|
|
1215
1211
|
}
|
|
1216
1212
|
}
|
|
1217
1213
|
if (
|
|
@@ -2270,7 +2266,12 @@ class APP {
|
|
|
2270
2266
|
})
|
|
2271
2267
|
.catch((e) => {
|
|
2272
2268
|
// AggregateError 取第一个子错误作为实际错误
|
|
2273
|
-
if (
|
|
2269
|
+
if (
|
|
2270
|
+
e &&
|
|
2271
|
+
e.name === 'AggregateError' &&
|
|
2272
|
+
Array.isArray(e.errors) &&
|
|
2273
|
+
e.errors.length > 0
|
|
2274
|
+
) {
|
|
2274
2275
|
e = e.errors[0]
|
|
2275
2276
|
}
|
|
2276
2277
|
console.log('错误', e)
|
|
@@ -232,87 +232,6 @@ exports.channel = async (ctx) => {
|
|
|
232
232
|
}
|
|
233
233
|
}
|
|
234
234
|
|
|
235
|
-
exports.swagger = async (ctx) => {
|
|
236
|
-
const { app, appName } = getAppByCtx(ctx)
|
|
237
|
-
if (app.cache && app.cache.get('swagger'))
|
|
238
|
-
return ctx.SUCCESS(app.cache.get('swagger'))
|
|
239
|
-
|
|
240
|
-
const filePath = path.resolve(
|
|
241
|
-
__dirname,
|
|
242
|
-
`${process.cwd()}/app/${appName}/plugins`
|
|
243
|
-
)
|
|
244
|
-
const apis = []
|
|
245
|
-
const pathList = await fsPromise.readdir(filePath)
|
|
246
|
-
for (let i = 0; i < pathList.length; i++) {
|
|
247
|
-
const folder = pathList[i]
|
|
248
|
-
const isFolder = fs.lstatSync(path.resolve(filePath, folder)).isDirectory()
|
|
249
|
-
if (isFolder) {
|
|
250
|
-
const models = []
|
|
251
|
-
if (app.model[folder]) {
|
|
252
|
-
const result = await app.sequelize
|
|
253
|
-
.getQueryInterface()
|
|
254
|
-
.describeTable(folder)
|
|
255
|
-
Object.keys(result).forEach((attr) => {
|
|
256
|
-
models.push(lodash.merge(app.attributes[folder][attr], result[attr]))
|
|
257
|
-
// models[attr] = lodash.merge(app.attributes[folder][attr], result[attr]);
|
|
258
|
-
})
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
const controllers = []
|
|
262
|
-
const controllerFilePath = path.resolve(filePath, folder, 'controller.js')
|
|
263
|
-
const isControllerExist = fs.existsSync(controllerFilePath)
|
|
264
|
-
if (isControllerExist) {
|
|
265
|
-
const controllerFile = await fsPromise.readFile(
|
|
266
|
-
controllerFilePath,
|
|
267
|
-
'utf-8'
|
|
268
|
-
)
|
|
269
|
-
const annotations = controllerFile.match(annotationsReg)
|
|
270
|
-
|
|
271
|
-
if (annotations) {
|
|
272
|
-
for (let j = 0; j < annotations.length; j++) {
|
|
273
|
-
const annotation = annotations[j]
|
|
274
|
-
let res
|
|
275
|
-
const obj = {}
|
|
276
|
-
while ((res = apiReg.exec(annotation))) {
|
|
277
|
-
res = res.map((item) => item.toLowerCase())
|
|
278
|
-
if (res[1] === 'param') {
|
|
279
|
-
const arr = res[3].split('/')
|
|
280
|
-
if (obj[res[1]]) {
|
|
281
|
-
obj[res[1]].push({
|
|
282
|
-
key: arr[0],
|
|
283
|
-
type: arr[1],
|
|
284
|
-
name: arr[2],
|
|
285
|
-
})
|
|
286
|
-
} else {
|
|
287
|
-
obj[res[1]] = []
|
|
288
|
-
|
|
289
|
-
obj[res[1]].push({
|
|
290
|
-
key: arr[0],
|
|
291
|
-
type: arr[1],
|
|
292
|
-
name: arr[2],
|
|
293
|
-
})
|
|
294
|
-
}
|
|
295
|
-
} else {
|
|
296
|
-
obj[res[1]] = res[3]
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
controllers.push(obj)
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
apis.push({
|
|
304
|
-
name: folder,
|
|
305
|
-
desc: lodash.get(app, `config.${folder}.name`, `${folder}`),
|
|
306
|
-
models,
|
|
307
|
-
controllers,
|
|
308
|
-
})
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
app.cache && app.cache.set('swagger', apis)
|
|
312
|
-
// console.log(dir)
|
|
313
|
-
ctx.SUCCESS(apis)
|
|
314
|
-
}
|
|
315
|
-
|
|
316
235
|
exports.getLocation = async (ctx, _data) => {
|
|
317
236
|
const { app } = getAppByCtx(ctx)
|
|
318
237
|
|
|
@@ -215,22 +215,6 @@ exports.initModel = async (ctx) => {
|
|
|
215
215
|
return ctx.ERROR(`app.model没有${model}`)
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
|
-
|
|
219
|
-
exports.customRouter = async (ctx) => {
|
|
220
|
-
// const {
|
|
221
|
-
// app,
|
|
222
|
-
// appName,
|
|
223
|
-
// } = getAppByCtx(ctx);
|
|
224
|
-
|
|
225
|
-
// const list = [{
|
|
226
|
-
// path: 'jiangong_statis',
|
|
227
|
-
// name: '数据面板'
|
|
228
|
-
// }]
|
|
229
|
-
const list = []
|
|
230
|
-
ctx.SUCCESS(list)
|
|
231
|
-
return list
|
|
232
|
-
}
|
|
233
|
-
|
|
234
218
|
exports.showTables = async (ctx, _data) => {
|
|
235
219
|
const { app, appName } = getAppByCtx(ctx)
|
|
236
220
|
const { omit = [] } = _data || ctx.request.body
|
|
@@ -666,21 +650,6 @@ exports.chat = async (ctx) => {
|
|
|
666
650
|
}
|
|
667
651
|
}
|
|
668
652
|
|
|
669
|
-
exports.dashboard = async (ctx) => {
|
|
670
|
-
// const {
|
|
671
|
-
// app,
|
|
672
|
-
// } = getAppByCtx(ctx);
|
|
673
|
-
|
|
674
|
-
const result = [
|
|
675
|
-
// {
|
|
676
|
-
// name: '用户',
|
|
677
|
-
// number: 5,
|
|
678
|
-
// route: 'page/user'
|
|
679
|
-
// }
|
|
680
|
-
]
|
|
681
|
-
ctx.SUCCESS(result)
|
|
682
|
-
}
|
|
683
|
-
|
|
684
653
|
exports.showModelCount = async (ctx) => {
|
|
685
654
|
const { app, appName } = getAppByCtx(ctx)
|
|
686
655
|
const { is_count = false } = ctx.request.body
|