skybase 0.1.93 → 0.1.95
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/CHANGELOG.md +14 -0
- package/lib/middleware/sky-api-register.js +13 -11
- package/lib/middleware/sky-body-parse.js +1 -2
- package/lib/middleware/sky-check-param.js +10 -10
- package/lib/middleware/sky-check-token.js +8 -5
- package/lib/middleware/sky-output.js +15 -12
- package/lib/sky.js +37 -8
- package/lib/sky_extend.js +15 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [0.1.94](https://github.com/kongnet/skybase/compare/v0.1.93...v0.1.94) (2023-04-25)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### :bug:
|
|
5
|
+
|
|
6
|
+
* 一些提示修改成en ([a9da814](https://github.com/kongnet/skybase/commit/a9da814c939f37cab35dadb46456519e84868024))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## [0.1.93](https://github.com/kongnet/skybase/compare/v0.1.92...v0.1.93) (2022-09-01)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
1
15
|
## [0.1.92](https://github.com/kongnet/skybase/compare/v0.1.91...v0.1.92) (2022-08-31)
|
|
2
16
|
|
|
3
17
|
|
|
@@ -12,7 +12,7 @@ Mock.Random.extend($.Mock)
|
|
|
12
12
|
const mockFn = {
|
|
13
13
|
noMock () {
|
|
14
14
|
return function (ctx) {
|
|
15
|
-
ctx.ok('controller未定义 & mock未定义'
|
|
15
|
+
ctx.ok('base:controller or mock not defined') //'controller未定义 & mock未定义'
|
|
16
16
|
}
|
|
17
17
|
},
|
|
18
18
|
mockRouter (mockModels) {
|
|
@@ -55,11 +55,12 @@ const routerLog = (result, name, apiPath, ms) => {
|
|
|
55
55
|
: `:"${item[1]}"`
|
|
56
56
|
}
|
|
57
57
|
)
|
|
58
|
-
let resultKey = resultValue.replace(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
let resultKey = resultValue.replace(
|
|
59
|
+
/"([a-zA-Z0-9_\$\.]+)" *:/g,
|
|
60
|
+
function (...item) {
|
|
61
|
+
return `"${$.c.dimy(item[1])}":`
|
|
62
|
+
}
|
|
63
|
+
)
|
|
63
64
|
resultKey = resultKey.slice(0, 1000)
|
|
64
65
|
$.log(
|
|
65
66
|
'[router处理]=>',
|
|
@@ -147,7 +148,7 @@ const limitReqAction = (action, apiPath) => {
|
|
|
147
148
|
ctx.body = {
|
|
148
149
|
code: 402,
|
|
149
150
|
data: diff,
|
|
150
|
-
msg: '访问过快请稍后再试!'
|
|
151
|
+
msg: 'base:request limit, pls try later' //'访问过快请稍后再试!'
|
|
151
152
|
}
|
|
152
153
|
|
|
153
154
|
routerLog(ctx.body, name || desc, apiPath, Date.now() - start)
|
|
@@ -178,7 +179,7 @@ const limitReqAction = (action, apiPath) => {
|
|
|
178
179
|
ctx.body = {
|
|
179
180
|
code: 406,
|
|
180
181
|
data: {},
|
|
181
|
-
msg: `${apiPath}的Control不存在,请在api定义中定义mock对象`
|
|
182
|
+
msg: `${apiPath} base:Control not exist, pls defined mock Object in Api` //`${apiPath}的Control不存在,请在api定义中定义mock对象`
|
|
182
183
|
}
|
|
183
184
|
}
|
|
184
185
|
|
|
@@ -256,9 +257,10 @@ const checkApi = (apiDir, apiPath = '') => {
|
|
|
256
257
|
} else {
|
|
257
258
|
const ap = require(dir)
|
|
258
259
|
for (const [p, opt] of Object.entries(ap)) {
|
|
259
|
-
const path = (
|
|
260
|
-
|
|
261
|
-
|
|
260
|
+
const path = (
|
|
261
|
+
p.indexOf('/') === 0
|
|
262
|
+
? p
|
|
263
|
+
: `${apiPath}/${files[i].split('.')[0]}/${p}`
|
|
262
264
|
)
|
|
263
265
|
.split('/')
|
|
264
266
|
.filter(v => !!v)
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
// NOTICE: 经过body格式格式化一下内容才可对象化
|
|
3
2
|
const $ = require('meeko')
|
|
4
3
|
const { bodyParse } = require('../../skyconfig')
|
|
@@ -17,7 +16,7 @@ module.exports = async (ctx, next) => {
|
|
|
17
16
|
$.err('用户输入错误e.message', e.stack)
|
|
18
17
|
switch (e.type) {
|
|
19
18
|
case 'entity.too.large':
|
|
20
|
-
ctx.throwCode(413, 'request entity too large')
|
|
19
|
+
ctx.throwCode(413, 'base:request entity too large')
|
|
21
20
|
break
|
|
22
21
|
default:
|
|
23
22
|
ctx.throwCode(400, e.message)
|
|
@@ -60,8 +60,8 @@ const checkCache = (ctx, method, url) => {
|
|
|
60
60
|
|
|
61
61
|
// 快速检查是否可以不执行具体方法
|
|
62
62
|
const preCheck = (ctx, method, url, apiPath) => {
|
|
63
|
-
if (!['get', 'post'].includes(method)) {
|
|
64
|
-
ctx.throwCode(ctx.status, '只支持get/post/all方式'
|
|
63
|
+
if (!['get', 'post', 'all'].includes(method)) {
|
|
64
|
+
ctx.throwCode(ctx.status, 'base:only get/post/all method') //'只支持get/post/all方式'
|
|
65
65
|
return { succ: false, continue: false }
|
|
66
66
|
}
|
|
67
67
|
if (checkRedirect(ctx, apiPath)) {
|
|
@@ -89,7 +89,7 @@ const preCheck = (ctx, method, url, apiPath) => {
|
|
|
89
89
|
]
|
|
90
90
|
}
|
|
91
91
|
if (!apiSetting) {
|
|
92
|
-
ctx.throwCode(404, '接口不存在'
|
|
92
|
+
ctx.throwCode(404, 'base:interface does not exist') //'接口不存在'
|
|
93
93
|
return { succ: false, continue: false }
|
|
94
94
|
}
|
|
95
95
|
|
|
@@ -97,7 +97,7 @@ const preCheck = (ctx, method, url, apiPath) => {
|
|
|
97
97
|
if (method !== needMethod && needMethod !== 'all') {
|
|
98
98
|
// 允许get和post都接入
|
|
99
99
|
$.err(`方法类型不对,应为${needMethod},不能为${method}`)
|
|
100
|
-
ctx.throwCode(405, '方法类型不对'
|
|
100
|
+
ctx.throwCode(405, 'base:method type error') //'方法类型不对'
|
|
101
101
|
return { succ: false, continue: false }
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -108,12 +108,12 @@ module.exports = async (ctx, next) => {
|
|
|
108
108
|
const method = ctx.method.toLowerCase()
|
|
109
109
|
const url = ctx.request.url
|
|
110
110
|
const apiPath = url.split('?')[0]
|
|
111
|
-
const {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
)
|
|
111
|
+
const {
|
|
112
|
+
continue: canContinue,
|
|
113
|
+
succ,
|
|
114
|
+
needMethod,
|
|
115
|
+
apiSetting
|
|
116
|
+
} = preCheck(ctx, method, url, apiPath)
|
|
117
117
|
if (!canContinue) {
|
|
118
118
|
apiCheckLog(apiPath, ctx.body, method, null, ctx)
|
|
119
119
|
return succ ? 1 : 0
|
|
@@ -12,7 +12,7 @@ module.exports = async (ctx, next) => {
|
|
|
12
12
|
const data = await checkToken(token)
|
|
13
13
|
if (!data && needToken) {
|
|
14
14
|
$.log(token + ' 非法用户')
|
|
15
|
-
return ctx.throwCode(401, '请登录!'
|
|
15
|
+
return ctx.throwCode(401, 'base:pls login!') //'请登录!'
|
|
16
16
|
}
|
|
17
17
|
ctx.checkedToken = data
|
|
18
18
|
if (data && ctx.checkedData) {
|
|
@@ -20,12 +20,13 @@ module.exports = async (ctx, next) => {
|
|
|
20
20
|
}
|
|
21
21
|
} else {
|
|
22
22
|
$.log('接口需要token')
|
|
23
|
-
return ctx.throwCode(401, '需要token,或需登录'
|
|
23
|
+
return ctx.throwCode(401, 'base:need token or no login') //'需要token,或需登录'
|
|
24
24
|
}
|
|
25
|
-
} else {
|
|
25
|
+
} else {
|
|
26
|
+
// 兼容微服务
|
|
26
27
|
ctx.checkedToken = { headers: ctx.request.headers }
|
|
27
28
|
}
|
|
28
|
-
next && await next()
|
|
29
|
+
next && (await next())
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
// // 删除原先的登录凭证
|
|
@@ -62,7 +63,9 @@ async function checkToken (token, tokenPre = 'userlogin') {
|
|
|
62
63
|
keyStr = keyStr.trim()
|
|
63
64
|
let o = JSON.parse(await redis.get(keyStr))
|
|
64
65
|
$.log(keyStr, o)
|
|
65
|
-
if (o === null) {
|
|
66
|
+
if (o === null) {
|
|
67
|
+
return 0
|
|
68
|
+
}
|
|
66
69
|
if (o.id) {
|
|
67
70
|
let ot = await redis.get(Config.tokenName + ':id:' + o.id)
|
|
68
71
|
if (ot !== token) {
|
|
@@ -2,32 +2,32 @@
|
|
|
2
2
|
* 记录api运行前后的状态,并封装到response中
|
|
3
3
|
* */
|
|
4
4
|
|
|
5
|
-
const $G = global.$G = global.$G || {}
|
|
5
|
+
const $G = (global.$G = global.$G || {})
|
|
6
6
|
const $ = require('meeko')
|
|
7
7
|
|
|
8
8
|
// 是否停止接收新的网络请求。如果设为 true ,来了新请求,还是会先判断参数是否正确,是否登录,然后返回 503
|
|
9
9
|
$G.stopNewRequest = false
|
|
10
10
|
|
|
11
11
|
// 拦截最后的返回
|
|
12
|
-
const interceptLastReturn =
|
|
12
|
+
const interceptLastReturn = ctx => {
|
|
13
13
|
switch (ctx.status) {
|
|
14
14
|
case 200:
|
|
15
15
|
break
|
|
16
16
|
case 204:
|
|
17
|
-
ctx.throwCode(204, 'sys:无内容返回'
|
|
17
|
+
ctx.throwCode(204, 'base:no content') //'sys:无内容返回'
|
|
18
18
|
break
|
|
19
19
|
case 405:
|
|
20
|
-
ctx.throwCode(405, 'sys:无访问api权限'
|
|
20
|
+
ctx.throwCode(405, 'base:api no rights') //'sys:无访问api权限'
|
|
21
21
|
break
|
|
22
22
|
case 404:
|
|
23
23
|
// ctx.throwCode.call(ctx, 404, 'sys:无此api或api发生错误', '', ctx)
|
|
24
|
-
ctx.throwCode(404, 'sys:无此api或api发生错误'
|
|
24
|
+
ctx.throwCode(404, 'base:api not found or api error') //'sys:无此api或api发生错误'
|
|
25
25
|
break
|
|
26
26
|
case 401:
|
|
27
|
-
ctx.throwCode(401, 'sys:无权限'
|
|
27
|
+
ctx.throwCode(401, 'base:no rights') //'sys:无权限'
|
|
28
28
|
break
|
|
29
29
|
default:
|
|
30
|
-
ctx.throwCode(ctx.status, 'sys:服务端未知错误'
|
|
30
|
+
ctx.throwCode(ctx.status, 'base:unknown error') //'sys:服务端未知错误'
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -36,7 +36,7 @@ module.exports = async (ctx, next) => {
|
|
|
36
36
|
const start = Date.now()
|
|
37
37
|
try {
|
|
38
38
|
if ($G.stopNewRequest) {
|
|
39
|
-
ctx.throwCode(503, '服务端暂时停止服务,请稍后再试'
|
|
39
|
+
ctx.throwCode(503, 'base:server stop respone,pls try later') //'服务端暂时停止服务,请稍后再试'
|
|
40
40
|
} else {
|
|
41
41
|
await next()
|
|
42
42
|
}
|
|
@@ -44,13 +44,16 @@ module.exports = async (ctx, next) => {
|
|
|
44
44
|
$.err(e.stack)
|
|
45
45
|
switch (true) {
|
|
46
46
|
case e.message.indexOf('ETIMEDOUT') > -1:
|
|
47
|
-
ctx.throwCode(599, '服务端超时'
|
|
47
|
+
ctx.throwCode(599, 'base:server timeout') //'服务端超时'
|
|
48
48
|
break
|
|
49
49
|
case e.message.indexOf('ENOENT') > -1:
|
|
50
|
-
ctx.throwCode(598, '服务端找不到路径'
|
|
50
|
+
ctx.throwCode(598, 'base:not found path') //'服务端找不到路径'
|
|
51
51
|
break
|
|
52
|
-
case e.message === 'request entity too large':
|
|
53
|
-
ctx.throwCode(
|
|
52
|
+
case e.message === 'base:request entity too large':
|
|
53
|
+
ctx.throwCode(
|
|
54
|
+
413,
|
|
55
|
+
`base:request entity too large: ${e.length} / ${e.limit} bytes`
|
|
56
|
+
) //`请求体过大:${e.length} / ${e.limit} 字节`
|
|
54
57
|
break
|
|
55
58
|
default:
|
|
56
59
|
ctx.throwCode(500, e.message, e)
|
package/lib/sky.js
CHANGED
|
@@ -1,11 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict'
|
|
3
|
+
const os = require('os')
|
|
4
|
+
|
|
5
|
+
const networkInterfaces = os.networkInterfaces()
|
|
6
|
+
let localIP = Object.keys(networkInterfaces).map((ifname, index) => {
|
|
7
|
+
const iface = networkInterfaces[ifname]
|
|
8
|
+
const arr = iface.map(x => {
|
|
9
|
+
if (
|
|
10
|
+
x?.family === 'IPv4' &&
|
|
11
|
+
!x?.internal &&
|
|
12
|
+
x?.mac !== '00:00:00:00:00:00'
|
|
13
|
+
) {
|
|
14
|
+
return x.address
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
return arr.filter(Boolean)
|
|
18
|
+
})
|
|
19
|
+
|
|
3
20
|
const $G = (global.$G = global.$G || {})
|
|
4
21
|
// global.Promise = require('bluebird')
|
|
5
22
|
|
|
6
23
|
const skyExt = require('./sky_extend')
|
|
7
24
|
const path = require('path')
|
|
8
25
|
const http = require('http')
|
|
26
|
+
const https = require('https')
|
|
9
27
|
|
|
10
28
|
// 全局对象
|
|
11
29
|
const $ = (global.$ = require('meeko'))
|
|
@@ -54,9 +72,17 @@ const getPort = async (port, beforeListenPort) => {
|
|
|
54
72
|
return portTemp
|
|
55
73
|
}
|
|
56
74
|
|
|
57
|
-
const createWebServer = async (port, afterCreateServer) => {
|
|
58
|
-
|
|
59
|
-
|
|
75
|
+
const createWebServer = async (port, afterCreateServer, httpsOption) => {
|
|
76
|
+
let option = {}
|
|
77
|
+
let server
|
|
78
|
+
if (httpsOption) {
|
|
79
|
+
option = httpsOption
|
|
80
|
+
server = https.createServer(option, app.callback())
|
|
81
|
+
} else {
|
|
82
|
+
server = http.createServer(app.callback())
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (afterCreateServer) {
|
|
60
86
|
await afterCreateServer(server)
|
|
61
87
|
}
|
|
62
88
|
|
|
@@ -84,7 +110,7 @@ async function init (option, cbFun) {
|
|
|
84
110
|
const {
|
|
85
111
|
name,
|
|
86
112
|
port,
|
|
87
|
-
|
|
113
|
+
https,
|
|
88
114
|
beforeMount,
|
|
89
115
|
beforeLoadMiddlewares,
|
|
90
116
|
afterLoadMiddlewares,
|
|
@@ -157,12 +183,15 @@ async function init (option, cbFun) {
|
|
|
157
183
|
|
|
158
184
|
// 侦听端口
|
|
159
185
|
const portFinal = await getPort(port, beforeListenPort)
|
|
160
|
-
$G.server = await createWebServer(portFinal, afterCreateServer)
|
|
161
|
-
|
|
186
|
+
$G.server = await createWebServer(portFinal, afterCreateServer, https)
|
|
162
187
|
$.log(
|
|
163
188
|
$.c.g('✔'),
|
|
164
|
-
`${$.c.y(name)} WebServer [${$.c.y('0.0.0.0')}]
|
|
165
|
-
|
|
189
|
+
`${$.c.y(name)} WebServer [${$.c.y('0.0.0.0')}] [${localIP
|
|
190
|
+
.flat(1)
|
|
191
|
+
.join(',')}] Listen at`,
|
|
192
|
+
`${$.c.y(portFinal)} ${
|
|
193
|
+
https ? 'https' : 'http'
|
|
194
|
+
}://127.0.0.1:${portFinal}/`
|
|
166
195
|
)
|
|
167
196
|
skyExt.artTxt(name, 'Graceful')
|
|
168
197
|
}
|
package/lib/sky_extend.js
CHANGED
|
@@ -4,21 +4,21 @@ const figlet = require('figlet')
|
|
|
4
4
|
|
|
5
5
|
const deconstructionCode = (errCode, errMsg, data) => {
|
|
6
6
|
if (errCode instanceof Array) {
|
|
7
|
-
[errCode, errMsg, data] = errCode
|
|
7
|
+
;[errCode, errMsg, data] = errCode
|
|
8
8
|
} else if (errCode && Object === errCode.constructor) {
|
|
9
|
-
({ data, msg: errMsg, code: errCode } = errCode)
|
|
9
|
+
;({ data, msg: errMsg, code: errCode } = errCode)
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
if (!errCode && errCode !== 0) {
|
|
13
13
|
errCode = 500
|
|
14
|
-
errMsg = errMsg || '未配置errCode'
|
|
14
|
+
errMsg = errMsg || 'base:unset errCode' //'未配置errCode'
|
|
15
15
|
} else {
|
|
16
16
|
const olderrCode = errCode
|
|
17
17
|
errCode = parseInt(errCode)
|
|
18
18
|
if (isNaN(errCode)) {
|
|
19
19
|
console.log('【errCode配置不正确】', olderrCode)
|
|
20
20
|
errCode = 500
|
|
21
|
-
errMsg = errMsg || 'errCode配置不正确'
|
|
21
|
+
errMsg = errMsg || 'base: errCode setting Incorrect' //'errCode配置不正确'
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -26,7 +26,6 @@ const deconstructionCode = (errCode, errMsg, data) => {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
const appContext = {
|
|
29
|
-
|
|
30
29
|
/**
|
|
31
30
|
* 向body写入统一的数据格式
|
|
32
31
|
*
|
|
@@ -43,9 +42,8 @@ const appContext = {
|
|
|
43
42
|
* */
|
|
44
43
|
|
|
45
44
|
throwCode: function (errCode, errMsg, data) {
|
|
46
|
-
this.type = 'json'
|
|
47
|
-
|
|
48
|
-
({ errCode, errMsg, data } = deconstructionCode(errCode, errMsg, data))
|
|
45
|
+
this.type = 'json'
|
|
46
|
+
;({ errCode, errMsg, data } = deconstructionCode(errCode, errMsg, data))
|
|
49
47
|
|
|
50
48
|
// ps. 这里不 JSON.stringify ,就会在中间件:bodyParseFn 解析body的时候报错,
|
|
51
49
|
// 那里同时处理输入和输出的数据,没法区分是输入的错还是输出的错
|
|
@@ -59,8 +57,13 @@ const appContext = {
|
|
|
59
57
|
|
|
60
58
|
return this.body
|
|
61
59
|
} catch (e) {
|
|
62
|
-
console.error(
|
|
63
|
-
|
|
60
|
+
console.error(
|
|
61
|
+
this.request.url,
|
|
62
|
+
{ code: 500, msg: '输出的数据无法解析' },
|
|
63
|
+
this.method.toLowerCase(),
|
|
64
|
+
data
|
|
65
|
+
)
|
|
66
|
+
this.throwCode(500, 'output data parse error') //'输出的数据无法解析'
|
|
64
67
|
}
|
|
65
68
|
},
|
|
66
69
|
ok: function (data, msg) {
|
|
@@ -87,7 +90,8 @@ const errStackFn = e => {
|
|
|
87
90
|
process.on('uncaughtException', errStackFn)
|
|
88
91
|
process.on('unhandledRejection', errStackFn)
|
|
89
92
|
|
|
90
|
-
const artTxt = (s = 'SKY', font = 'Star Wars') =>
|
|
93
|
+
const artTxt = (s = 'SKY', font = 'Star Wars') =>
|
|
94
|
+
$.log($.c.c(figlet.textSync(s, { font })))
|
|
91
95
|
const artStage = s => {
|
|
92
96
|
const len = s.length + 4
|
|
93
97
|
const char = '─'.times(len)
|