wok-server 0.5.0 → 0.6.0
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.en.md +61 -0
- package/README.md +44 -29
- package/dist/cache/cache.js +98 -98
- package/dist/cache/config.js +19 -19
- package/dist/cache/index.js +27 -27
- package/dist/cache/purge-task.js +46 -46
- package/dist/cache/stat.js +47 -47
- package/dist/config/convert.js +36 -36
- package/dist/config/exception.js +14 -14
- package/dist/config/index.js +81 -81
- package/dist/http-client/index.js +136 -136
- package/dist/i18n/ar.js +17 -17
- package/dist/i18n/de.js +17 -17
- package/dist/i18n/en-us.js +17 -17
- package/dist/i18n/es.js +17 -17
- package/dist/i18n/fr.js +17 -17
- package/dist/i18n/i18n.js +231 -231
- package/dist/i18n/index.js +52 -52
- package/dist/i18n/ja.js +17 -17
- package/dist/i18n/ko.js +17 -17
- package/dist/i18n/msg.js +2 -2
- package/dist/i18n/pt.js +17 -17
- package/dist/i18n/ru.js +17 -17
- package/dist/i18n/tag.js +18 -18
- package/dist/i18n/zh-HK.js +17 -17
- package/dist/i18n/zh-TW.js +17 -17
- package/dist/i18n/zh-cn.js +17 -17
- package/dist/index.js +14 -14
- package/dist/lock/index.js +114 -114
- package/dist/log/config.js +35 -35
- package/dist/log/date.js +21 -21
- package/dist/log/file.js +198 -198
- package/dist/log/index.js +135 -135
- package/dist/log/level.js +33 -33
- package/dist/log/log.js +56 -56
- package/dist/log/store.js +19 -19
- package/dist/mongodb/collection.js +2 -2
- package/dist/mongodb/config.js +34 -34
- package/dist/mongodb/doc.js +2 -2
- package/dist/mongodb/exception.js +14 -14
- package/dist/mongodb/index.js +58 -58
- package/dist/mongodb/manager/base.js +563 -563
- package/dist/mongodb/manager/index.js +63 -63
- package/dist/mongodb/manager/tx-strict.js +84 -84
- package/dist/mongodb/manager/tx.js +30 -30
- package/dist/mongodb/migration.js +52 -52
- package/dist/mvc/access-log.js +33 -33
- package/dist/mvc/config.js +27 -27
- package/dist/mvc/exchange.js +113 -113
- package/dist/mvc/handler/index.js +7 -6
- package/dist/mvc/handler/json.js +65 -65
- package/dist/mvc/handler/restful.js +35 -35
- package/dist/mvc/handler/sse.js +65 -0
- package/dist/mvc/handler/upload.js +31 -31
- package/dist/mvc/index.js +50 -50
- package/dist/mvc/interceptor.js +2 -2
- package/dist/mvc/query.js +43 -43
- package/dist/mvc/render/file.js +132 -132
- package/dist/mvc/render/html/html.js +90 -90
- package/dist/mvc/render/html/index.js +18 -18
- package/dist/mvc/render/html/style.js +2 -2
- package/dist/mvc/render/index.js +7 -7
- package/dist/mvc/render/json.js +26 -26
- package/dist/mvc/render/text.js +16 -16
- package/dist/mvc/router.js +2 -2
- package/dist/mvc/server.js +272 -272
- package/dist/mvc/static/header.js +67 -67
- package/dist/mvc/static/index.js +6 -6
- package/dist/mvc/static/mime-type.js +84 -84
- package/dist/mvc/static/server-cache-config.js +66 -66
- package/dist/mvc/static/server-cache.js +133 -133
- package/dist/mvc/static/static-handler.js +372 -372
- package/dist/mysql/config.js +51 -51
- package/dist/mysql/exception.js +14 -14
- package/dist/mysql/index.js +87 -87
- package/dist/mysql/manager/base.js +239 -239
- package/dist/mysql/manager/index.js +107 -107
- package/dist/mysql/manager/ops/count.js +20 -20
- package/dist/mysql/manager/ops/criteria.js +356 -356
- package/dist/mysql/manager/ops/delete.js +65 -65
- package/dist/mysql/manager/ops/exist.js +26 -26
- package/dist/mysql/manager/ops/find.js +169 -169
- package/dist/mysql/manager/ops/index.js +14 -14
- package/dist/mysql/manager/ops/insert.js +106 -106
- package/dist/mysql/manager/ops/modify.js +10 -10
- package/dist/mysql/manager/ops/paginate.js +23 -23
- package/dist/mysql/manager/ops/query.js +9 -9
- package/dist/mysql/manager/ops/update.js +216 -216
- package/dist/mysql/manager/ops/utils.js +24 -24
- package/dist/mysql/manager/tx-strict.js +103 -103
- package/dist/mysql/manager/tx.js +30 -30
- package/dist/mysql/manager/utils.js +56 -56
- package/dist/mysql/migration.js +136 -136
- package/dist/mysql/table-info.js +8 -8
- package/dist/task/daily.js +59 -59
- package/dist/task/fixed-delay.js +38 -38
- package/dist/task/fixed-rate.js +42 -42
- package/dist/task/index.js +9 -9
- package/dist/task/task.js +56 -56
- package/dist/validation/exception.js +36 -36
- package/dist/validation/index.js +40 -40
- package/dist/validation/validator/array.js +34 -34
- package/dist/validation/validator/enum.js +28 -28
- package/dist/validation/validator/index.js +14 -14
- package/dist/validation/validator/length.js +40 -40
- package/dist/validation/validator/max-length.js +35 -35
- package/dist/validation/validator/max.js +29 -29
- package/dist/validation/validator/min-length.js +33 -33
- package/dist/validation/validator/min.js +29 -29
- package/dist/validation/validator/not-blank.js +33 -33
- package/dist/validation/validator/not-null.js +21 -21
- package/dist/validation/validator/plain-obj.js +32 -32
- package/dist/validation/validator/regexp.js +34 -34
- package/documentation/en/cache.md +56 -0
- package/documentation/en/config.md +96 -0
- package/documentation/en/engineering.md +256 -0
- package/documentation/en/http-client.md +32 -0
- package/documentation/en/i18n.md +143 -0
- package/documentation/en/index.md +24 -0
- package/documentation/en/lock.md +51 -0
- package/documentation/en/log.md +109 -0
- package/documentation/en/mongodb.md +256 -0
- package/documentation/en/mvc.md +688 -0
- package/documentation/en/mysql.md +552 -0
- package/documentation/en/task.md +45 -0
- package/documentation/en/test.md +56 -0
- package/documentation/en/validate.md +130 -0
- package/documentation/zh-cn/mvc.md +66 -24
- package/package.json +3 -1
- package/skills/wok-server-api-rules/SKILL.md +350 -0
- package/skills/wok-server-cache/SKILL.md +216 -0
- package/skills/wok-server-config/SKILL.md +200 -0
- package/skills/wok-server-getting-started/SKILL.md +123 -0
- package/skills/wok-server-getting-started/references/engineering.md +169 -0
- package/skills/wok-server-http-client/SKILL.md +164 -0
- package/skills/wok-server-i18n/SKILL.md +214 -0
- package/skills/wok-server-lock/SKILL.md +144 -0
- package/skills/wok-server-log/SKILL.md +218 -0
- package/skills/wok-server-mongodb/SKILL.md +235 -0
- package/skills/wok-server-mvc/SKILL.md +251 -0
- package/skills/wok-server-mvc/references/respond-html.md +157 -0
- package/skills/wok-server-mvc/references/sse.md +121 -0
- package/skills/wok-server-mvc/references/static-files.md +47 -0
- package/skills/wok-server-mvc/references/upload.md +62 -0
- package/skills/wok-server-mvc/references/websocket.md +30 -0
- package/skills/wok-server-mysql/SKILL.md +315 -0
- package/skills/wok-server-mysql/references/multi-datasource.md +76 -0
- package/skills/wok-server-mysql/references/version-control.md +22 -0
- package/skills/wok-server-task/SKILL.md +158 -0
- package/skills/wok-server-validate/SKILL.md +167 -0
- package/src/cache/cache.ts +118 -0
- package/src/cache/config.ts +53 -0
- package/src/cache/index.ts +27 -0
- package/src/cache/purge-task.ts +53 -0
- package/src/cache/stat.ts +47 -0
- package/src/config/convert.ts +27 -0
- package/src/config/exception.ts +8 -0
- package/src/config/index.ts +92 -0
- package/src/http-client/index.ts +202 -0
- package/src/i18n/ar.ts +16 -0
- package/src/i18n/de.ts +16 -0
- package/src/i18n/en-us.ts +16 -0
- package/src/i18n/es.ts +16 -0
- package/src/i18n/fr.ts +16 -0
- package/src/i18n/i18n.ts +230 -0
- package/src/i18n/index.ts +50 -0
- package/src/i18n/ja.ts +16 -0
- package/src/i18n/ko.ts +16 -0
- package/src/i18n/msg.ts +50 -0
- package/src/i18n/pt.ts +16 -0
- package/src/i18n/ru.ts +16 -0
- package/src/i18n/tag.ts +18 -0
- package/src/i18n/zh-HK.ts +16 -0
- package/src/i18n/zh-TW.ts +16 -0
- package/src/i18n/zh-cn.ts +16 -0
- package/src/index.ts +11 -0
- package/src/lock/index.ts +164 -0
- package/src/log/config.ts +71 -0
- package/src/log/date.ts +19 -0
- package/src/log/file.ts +215 -0
- package/src/log/index.ts +136 -0
- package/src/log/level.ts +29 -0
- package/src/log/log.ts +77 -0
- package/src/log/store.ts +31 -0
- package/src/mongodb/collection.ts +25 -0
- package/src/mongodb/config.ts +69 -0
- package/src/mongodb/doc.ts +12 -0
- package/src/mongodb/exception.ts +8 -0
- package/src/mongodb/index.ts +71 -0
- package/src/mongodb/manager/base.ts +674 -0
- package/src/mongodb/manager/index.ts +80 -0
- package/src/mongodb/manager/tx-strict.ts +153 -0
- package/src/mongodb/manager/tx.ts +34 -0
- package/src/mongodb/migration.ts +66 -0
- package/src/mvc/access-log.ts +33 -0
- package/src/mvc/config.ts +70 -0
- package/src/mvc/exchange.ts +126 -0
- package/src/mvc/handler/index.ts +4 -0
- package/src/mvc/handler/json.ts +96 -0
- package/src/mvc/handler/restful.ts +39 -0
- package/src/mvc/handler/sse.ts +90 -0
- package/src/mvc/handler/upload.ts +54 -0
- package/src/mvc/index.ts +48 -0
- package/src/mvc/interceptor.ts +12 -0
- package/src/mvc/query.ts +36 -0
- package/src/mvc/render/file.ts +148 -0
- package/src/mvc/render/html/html.ts +187 -0
- package/src/mvc/render/html/index.ts +16 -0
- package/src/mvc/render/html/style.ts +1201 -0
- package/src/mvc/render/index.ts +4 -0
- package/src/mvc/render/json.ts +24 -0
- package/src/mvc/render/text.ts +14 -0
- package/src/mvc/router.ts +13 -0
- package/src/mvc/server.ts +315 -0
- package/src/mvc/static/header.ts +86 -0
- package/src/mvc/static/index.ts +3 -0
- package/src/mvc/static/mime-type.ts +81 -0
- package/src/mvc/static/server-cache-config.ts +92 -0
- package/src/mvc/static/server-cache.ts +171 -0
- package/src/mvc/static/static-handler.ts +445 -0
- package/src/mysql/config.ts +130 -0
- package/src/mysql/exception.ts +8 -0
- package/src/mysql/index.ts +88 -0
- package/src/mysql/manager/base.ts +285 -0
- package/src/mysql/manager/index.ts +112 -0
- package/src/mysql/manager/ops/count.ts +30 -0
- package/src/mysql/manager/ops/criteria.ts +412 -0
- package/src/mysql/manager/ops/delete.ts +96 -0
- package/src/mysql/manager/ops/exist.ts +41 -0
- package/src/mysql/manager/ops/find.ts +226 -0
- package/src/mysql/manager/ops/index.ts +11 -0
- package/src/mysql/manager/ops/insert.ts +120 -0
- package/src/mysql/manager/ops/modify.ts +14 -0
- package/src/mysql/manager/ops/paginate.ts +60 -0
- package/src/mysql/manager/ops/query.ts +13 -0
- package/src/mysql/manager/ops/update.ts +294 -0
- package/src/mysql/manager/ops/utils.ts +20 -0
- package/src/mysql/manager/tx-strict.ts +138 -0
- package/src/mysql/manager/tx.ts +31 -0
- package/src/mysql/manager/utils.ts +75 -0
- package/src/mysql/migration.ts +149 -0
- package/src/mysql/table-info.ts +41 -0
- package/src/task/daily.ts +70 -0
- package/src/task/fixed-delay.ts +45 -0
- package/src/task/fixed-rate.ts +49 -0
- package/src/task/index.ts +4 -0
- package/src/task/task.ts +70 -0
- package/src/validation/exception.ts +27 -0
- package/src/validation/index.ts +61 -0
- package/src/validation/validator/array.ts +32 -0
- package/src/validation/validator/enum.ts +25 -0
- package/src/validation/validator/index.ts +11 -0
- package/src/validation/validator/length.ts +42 -0
- package/src/validation/validator/max-length.ts +33 -0
- package/src/validation/validator/max.ts +26 -0
- package/src/validation/validator/min-length.ts +31 -0
- package/src/validation/validator/min.ts +26 -0
- package/src/validation/validator/not-blank.ts +31 -0
- package/src/validation/validator/not-null.ts +19 -0
- package/src/validation/validator/plain-obj.ts +30 -0
- package/src/validation/validator/regexp.ts +32 -0
- package/types/cache/cache.d.ts +52 -52
- package/types/cache/config.d.ts +32 -32
- package/types/cache/index.d.ts +2 -2
- package/types/cache/purge-task.d.ts +11 -11
- package/types/cache/stat.d.ts +26 -26
- package/types/config/convert.d.ts +6 -6
- package/types/config/exception.d.ts +7 -7
- package/types/config/index.d.ts +25 -25
- package/types/http-client/index.d.ts +71 -71
- package/types/i18n/ar.d.ts +2 -2
- package/types/i18n/de.d.ts +2 -2
- package/types/i18n/en-us.d.ts +2 -2
- package/types/i18n/es.d.ts +2 -2
- package/types/i18n/fr.d.ts +2 -2
- package/types/i18n/i18n.d.ts +102 -102
- package/types/i18n/index.d.ts +9 -9
- package/types/i18n/ja.d.ts +2 -2
- package/types/i18n/ko.d.ts +2 -2
- package/types/i18n/msg.d.ts +50 -50
- package/types/i18n/pt.d.ts +2 -2
- package/types/i18n/ru.d.ts +2 -2
- package/types/i18n/tag.d.ts +11 -11
- package/types/i18n/zh-HK.d.ts +2 -2
- package/types/i18n/zh-TW.d.ts +2 -2
- package/types/i18n/zh-cn.d.ts +2 -2
- package/types/index.d.ts +11 -11
- package/types/lock/index.d.ts +64 -64
- package/types/log/config.d.ts +35 -35
- package/types/log/date.d.ts +2 -2
- package/types/log/file.d.ts +13 -13
- package/types/log/index.d.ts +53 -53
- package/types/log/level.d.ts +14 -14
- package/types/log/log.d.ts +40 -40
- package/types/log/store.d.ts +19 -19
- package/types/mongodb/collection.d.ts +25 -25
- package/types/mongodb/config.d.ts +45 -45
- package/types/mongodb/doc.d.ts +11 -11
- package/types/mongodb/exception.d.ts +7 -7
- package/types/mongodb/index.d.ts +29 -29
- package/types/mongodb/manager/base.d.ts +188 -188
- package/types/mongodb/manager/index.d.ts +38 -38
- package/types/mongodb/manager/tx-strict.d.ts +41 -41
- package/types/mongodb/manager/tx.d.ts +21 -21
- package/types/mongodb/migration.d.ts +12 -12
- package/types/mvc/access-log.d.ts +7 -7
- package/types/mvc/config.d.ts +42 -42
- package/types/mvc/exchange.d.ts +72 -72
- package/types/mvc/handler/index.d.ts +4 -3
- package/types/mvc/handler/json.d.ts +44 -44
- package/types/mvc/handler/restful.d.ts +11 -11
- package/types/mvc/handler/sse.d.ts +34 -0
- package/types/mvc/handler/upload.d.ts +36 -36
- package/types/mvc/index.d.ts +22 -22
- package/types/mvc/interceptor.d.ts +11 -11
- package/types/mvc/query.d.ts +13 -13
- package/types/mvc/render/file.d.ts +10 -10
- package/types/mvc/render/html/html.d.ts +98 -98
- package/types/mvc/render/html/index.d.ts +11 -11
- package/types/mvc/render/html/style.d.ts +1201 -1201
- package/types/mvc/render/index.d.ts +4 -4
- package/types/mvc/render/json.d.ts +17 -17
- package/types/mvc/render/text.d.ts +10 -10
- package/types/mvc/router.d.ts +11 -11
- package/types/mvc/server.d.ts +90 -90
- package/types/mvc/static/header.d.ts +27 -27
- package/types/mvc/static/index.d.ts +3 -3
- package/types/mvc/static/mime-type.d.ts +2 -2
- package/types/mvc/static/server-cache-config.d.ts +30 -30
- package/types/mvc/static/server-cache.d.ts +76 -76
- package/types/mvc/static/static-handler.d.ts +77 -77
- package/types/mysql/config.d.ts +90 -90
- package/types/mysql/exception.d.ts +7 -7
- package/types/mysql/index.d.ts +16 -16
- package/types/mysql/manager/base.d.ts +165 -165
- package/types/mysql/manager/index.d.ts +36 -36
- package/types/mysql/manager/ops/count.d.ts +13 -13
- package/types/mysql/manager/ops/criteria.d.ts +134 -134
- package/types/mysql/manager/ops/delete.d.ts +46 -46
- package/types/mysql/manager/ops/exist.d.ts +6 -6
- package/types/mysql/manager/ops/find.d.ts +86 -86
- package/types/mysql/manager/ops/index.d.ts +10 -10
- package/types/mysql/manager/ops/insert.d.ts +18 -18
- package/types/mysql/manager/ops/modify.d.ts +3 -3
- package/types/mysql/manager/ops/paginate.d.ts +36 -36
- package/types/mysql/manager/ops/query.d.ts +3 -3
- package/types/mysql/manager/ops/update.d.ts +76 -76
- package/types/mysql/manager/ops/utils.d.ts +5 -5
- package/types/mysql/manager/tx-strict.d.ts +36 -36
- package/types/mysql/manager/tx.d.ts +15 -15
- package/types/mysql/manager/utils.d.ts +17 -17
- package/types/mysql/migration.d.ts +8 -8
- package/types/mysql/table-info.d.ts +36 -36
- package/types/task/daily.d.ts +16 -16
- package/types/task/fixed-delay.d.ts +9 -9
- package/types/task/fixed-rate.d.ts +9 -9
- package/types/task/index.d.ts +4 -4
- package/types/task/task.d.ts +34 -34
- package/types/validation/exception.d.ts +38 -38
- package/types/validation/index.d.ts +32 -32
- package/types/validation/validator/array.d.ts +5 -5
- package/types/validation/validator/enum.d.ts +8 -8
- package/types/validation/validator/index.d.ts +11 -11
- package/types/validation/validator/length.d.ts +10 -10
- package/types/validation/validator/max-length.d.ts +8 -8
- package/types/validation/validator/max.d.ts +7 -7
- package/types/validation/validator/min-length.d.ts +6 -6
- package/types/validation/validator/min.d.ts +7 -7
- package/types/validation/validator/not-blank.d.ts +7 -7
- package/types/validation/validator/not-null.d.ts +6 -6
- package/types/validation/validator/plain-obj.d.ts +7 -7
- package/types/validation/validator/regexp.d.ts +8 -8
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wok-server-validate
|
|
3
|
+
description: wok-server 校验组件使用指南,提供对象属性校验、内置规则和自定义规则的完整支持。
|
|
4
|
+
license: MIT
|
|
5
|
+
metadata:
|
|
6
|
+
author: Peak Tai
|
|
7
|
+
email: peaktai@qq.com
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# wok-server 校验组件
|
|
11
|
+
|
|
12
|
+
## 概述
|
|
13
|
+
|
|
14
|
+
校验组件提供 `validate` 函数校验对象属性,内置 11 种通用校验规则,支持嵌套对象/数组校验和自定义规则。校验器通过国际化组件自动生成多语言错误提示。
|
|
15
|
+
|
|
16
|
+
## 源码与类型定义
|
|
17
|
+
|
|
18
|
+
安装 `wok-server` 后,可通过以下路径查看源码与类型定义:
|
|
19
|
+
|
|
20
|
+
- 源码目录:`node_modules/wok-server/src/validation/`
|
|
21
|
+
- 类型定义:`node_modules/wok-server/types/` (引用 validation 组件的 `.d.ts` 文件)
|
|
22
|
+
|
|
23
|
+
核心源码文件:
|
|
24
|
+
|
|
25
|
+
| 文件 | 说明 |
|
|
26
|
+
| :------------------ | :--------------------------------- |
|
|
27
|
+
| `index.ts` | 模块入口,`validate` 函数 |
|
|
28
|
+
| `exception.ts` | `ValidationException` 异常类 |
|
|
29
|
+
| `validator/` | 内置校验规则函数目录 |
|
|
30
|
+
| `validator/index.ts`| 导出所有内置校验器 |
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 基本使用
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { validate, notNull, length } from 'wok-server'
|
|
38
|
+
|
|
39
|
+
validate(
|
|
40
|
+
{ name: 'tom' },
|
|
41
|
+
{ name: [notNull(), length({ min: 2, max: 16 })] }
|
|
42
|
+
)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
- 校验通过无返回值
|
|
46
|
+
- 校验失败抛出 `ValidationException`(含 `errMsg`、`validator`、`propertyPath`、`val`)
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
try {
|
|
50
|
+
validate(obj, rules)
|
|
51
|
+
} catch (e) {
|
|
52
|
+
if (e instanceof ValidationException) {
|
|
53
|
+
console.log(e.propertyPath) // 如 "profile.theme"
|
|
54
|
+
console.log(e.errMsg) // 如 "不能为空"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 内置校验规则
|
|
60
|
+
|
|
61
|
+
| 函数 | 作用 | 空值行为 |
|
|
62
|
+
| :------------ | :-------------------------------------- | :--------------- |
|
|
63
|
+
| `notNull` | 不能是 `null` 或 `undefined` | — |
|
|
64
|
+
| `notBlank` | 不能是 `null`/`undefined`/空白字符串 | — |
|
|
65
|
+
| `min(n)` | 数字必须 ≥ n | 空值跳过 |
|
|
66
|
+
| `max(n)` | 数字必须 ≤ n | 空值跳过 |
|
|
67
|
+
| `length` | 字符串/数组长度必须在 [min, max] 之间 | 空值跳过 |
|
|
68
|
+
| `maxLength(n)`| 长度必须 ≤ n | 空值跳过 |
|
|
69
|
+
| `minLength(n)`| 长度必须 ≥ n | 空值跳过 |
|
|
70
|
+
| `regexp` | 正则校验 | 空值跳过 |
|
|
71
|
+
| `enumerate` | 值必须在指定列表中 | 空值跳过 |
|
|
72
|
+
| `array` | 校验数组元素 | — |
|
|
73
|
+
| `plainObject` | 校验嵌套对象 | — |
|
|
74
|
+
|
|
75
|
+
**空值行为**:大部分较验器对空值(`null`/`undefined`)返回 `{ ok: true }` 跳过,需配合 `notNull` 使用。`notNull` 和 `notBlank` 本身才校验空。
|
|
76
|
+
|
|
77
|
+
### 国际化支持
|
|
78
|
+
|
|
79
|
+
所有内置校验器的默认错误消息通过 `getI18n().buildMsg(...)` 自动生成,支持多语言。也可以覆盖 `message` 参数。
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
notNull('名称不能为空')
|
|
83
|
+
length({ min: 2, max: 16, message: '名称必须是2到16个字' })
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## 嵌套校验
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
import { array, plainObject } from 'wok-server'
|
|
92
|
+
|
|
93
|
+
interface Tag { id: string; name: string }
|
|
94
|
+
interface User { profile: { theme: string }; tags: Tag[] }
|
|
95
|
+
|
|
96
|
+
validate<User>(data, {
|
|
97
|
+
profile: [notNull(), plainObject({
|
|
98
|
+
theme: [notBlank()]
|
|
99
|
+
})],
|
|
100
|
+
tags: [notNull(), maxLength(5), array([
|
|
101
|
+
notNull(),
|
|
102
|
+
plainObject({
|
|
103
|
+
id: [notBlank()],
|
|
104
|
+
name: [notBlank()]
|
|
105
|
+
})
|
|
106
|
+
])]
|
|
107
|
+
})
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
- `plainObject` 为嵌套对象定义子校验规则
|
|
111
|
+
- `array` 为数组元素定义校验规则(每个元素都校验)
|
|
112
|
+
- `ValidationException.propertyPath` 会记录完整路径(如 `tags[0].name`)
|
|
113
|
+
|
|
114
|
+
**⚠️ 建议嵌套不超过一层**,否则难以维护。
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 自定义校验规则
|
|
119
|
+
|
|
120
|
+
```ts
|
|
121
|
+
import { PropValidator } from 'wok-server'
|
|
122
|
+
|
|
123
|
+
function customValidate(): PropValidator<string> {
|
|
124
|
+
const validator = 'custom'
|
|
125
|
+
return val => {
|
|
126
|
+
if (!val) return { ok: true } // 不校验空
|
|
127
|
+
if (typeof val !== 'string') {
|
|
128
|
+
return { ok: false, validator, message: '值不是字符串' }
|
|
129
|
+
}
|
|
130
|
+
if (val.startsWith('t')) {
|
|
131
|
+
return { ok: false, validator, message: '不能以 t 开头' }
|
|
132
|
+
}
|
|
133
|
+
return { ok: true }
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
validate({ name: 'tim' }, { name: [customValidate()] })
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`PropValidator<T>` 定义为 `(val: T) => ValidationResult`。
|
|
141
|
+
- `ok: true` 校验通过
|
|
142
|
+
- `ok: false` 校验失败,需提供 `validator` 名称和 `message` 错误信息
|
|
143
|
+
- 可附带 `propPath` 字段(在被 `array`/`plainObject` 内部逐层拼接使用)
|
|
144
|
+
|
|
145
|
+
自定义校验器需要国际化时,自行调用 `getI18n().buildMsg()`。
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## validate 函数实现
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
function validate<T>(obj: T, opts: ValidationOpts<T>): void
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
内部遍历 `opts` 的每个 key,取出对应的值,依次运行该 key 的所有校验器函数。第一个失败即抛出 `ValidationException`。属性路径通过 `propPath` 逐级拼接(嵌套时 `array`/`plainObject` 校验器内部会设置)。
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## ValidationOpts 类型
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
type ValidationOpts<T> = Partial<{
|
|
163
|
+
[key in keyof T]: PropValidator<T[key]>[]
|
|
164
|
+
}>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
即对象的每个属性对应一个校验器函数数组。
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { config } from './config'
|
|
2
|
+
import { CacheStat } from './stat'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 缓存内容
|
|
6
|
+
*/
|
|
7
|
+
export interface CacheContent {
|
|
8
|
+
/**
|
|
9
|
+
* 保存的值
|
|
10
|
+
*/
|
|
11
|
+
val: any
|
|
12
|
+
/**
|
|
13
|
+
* 过期时间
|
|
14
|
+
*/
|
|
15
|
+
expireAt: number
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class Cache {
|
|
19
|
+
/**
|
|
20
|
+
* promise 表,作用是处理异步并发问题,如果有相同的 key 同时请求,保证异步的 provider 只执行一次
|
|
21
|
+
*/
|
|
22
|
+
private promiseMap = new Map<string, Promise<any>>()
|
|
23
|
+
|
|
24
|
+
constructor(
|
|
25
|
+
private readonly valueMap: Map<string, CacheContent>,
|
|
26
|
+
private readonly stat?: CacheStat
|
|
27
|
+
) {}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* 放入缓存
|
|
31
|
+
* @param key
|
|
32
|
+
* @param val
|
|
33
|
+
* @param expiresInSeconds
|
|
34
|
+
*/
|
|
35
|
+
put(key: string, val: any, expiresInSeconds?: number) {
|
|
36
|
+
const finalExpiresInSeconds =
|
|
37
|
+
typeof expiresInSeconds === 'number' ? expiresInSeconds : config.defaultExpireInSeconds
|
|
38
|
+
this.valueMap.set(key, {
|
|
39
|
+
val,
|
|
40
|
+
expireAt: new Date().getTime() + finalExpiresInSeconds * 1000
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 获取缓存值
|
|
46
|
+
* @param key
|
|
47
|
+
* @returns
|
|
48
|
+
*/
|
|
49
|
+
get<T>(key: string): T | undefined {
|
|
50
|
+
const content = this.valueMap.get(key)
|
|
51
|
+
if (!content) {
|
|
52
|
+
this.stat?.addGet(false)
|
|
53
|
+
return undefined
|
|
54
|
+
}
|
|
55
|
+
if (content.expireAt < new Date().getTime()) {
|
|
56
|
+
this.stat?.addGet(false)
|
|
57
|
+
this.valueMap.delete(key)
|
|
58
|
+
return undefined
|
|
59
|
+
}
|
|
60
|
+
this.stat?.addGet(true)
|
|
61
|
+
return content.val
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 清除所有缓存
|
|
65
|
+
*/
|
|
66
|
+
clear() {
|
|
67
|
+
this.valueMap.clear()
|
|
68
|
+
this.stat?.clear()
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* 删除.
|
|
73
|
+
* @param key
|
|
74
|
+
*/
|
|
75
|
+
remove(key: string) {
|
|
76
|
+
this.valueMap.delete(key)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* 在缓存值不存在时计算缓存的值,然后放入并返回.
|
|
81
|
+
* @param key
|
|
82
|
+
* @param provider
|
|
83
|
+
* @param expiresInSeconds
|
|
84
|
+
*/
|
|
85
|
+
async computeIfAbsent<T>(
|
|
86
|
+
key: string,
|
|
87
|
+
provider: () => Promise<T> | T,
|
|
88
|
+
expiresInSeconds?: number
|
|
89
|
+
): Promise<T> {
|
|
90
|
+
const content = this.valueMap.get(key)
|
|
91
|
+
if (content && content.expireAt >= new Date().getTime()) {
|
|
92
|
+
this.stat?.addGet(true)
|
|
93
|
+
return content.val
|
|
94
|
+
}
|
|
95
|
+
this.stat?.addGet(false)
|
|
96
|
+
// 如果已经在处理中,则直接返回 promise
|
|
97
|
+
const ep = this.promiseMap.get(key)
|
|
98
|
+
if (ep) {
|
|
99
|
+
return ep
|
|
100
|
+
}
|
|
101
|
+
// 创建新的异步流程
|
|
102
|
+
const promise = Promise.resolve().then(async () => {
|
|
103
|
+
try {
|
|
104
|
+
const finalExpireInSeconds =
|
|
105
|
+
typeof expiresInSeconds === 'number' ? expiresInSeconds : config.defaultExpireInSeconds
|
|
106
|
+
// 计算值
|
|
107
|
+
const res = provider()
|
|
108
|
+
const val = res instanceof Promise ? await res : res
|
|
109
|
+
this.put(key, val, finalExpireInSeconds)
|
|
110
|
+
return val
|
|
111
|
+
} finally {
|
|
112
|
+
this.promiseMap.delete(key)
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
this.promiseMap.set(key, promise)
|
|
116
|
+
return promise
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { registerConfig } from '../config'
|
|
2
|
+
import { max, min, notNull } from '../validation'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 缓存的配置
|
|
6
|
+
*/
|
|
7
|
+
interface CacheConfig {
|
|
8
|
+
/**
|
|
9
|
+
* 默认的存活时长,取值:1-3600,默认 60。存活时间应该尽可能的短,尤其是当缓存的内容比较大时,
|
|
10
|
+
* 否则缓存的内容长时间占用内存,会对 gc 造成影响。
|
|
11
|
+
*/
|
|
12
|
+
defaultExpireInSeconds: number
|
|
13
|
+
/**
|
|
14
|
+
* 是否启用统计任务,启用后每隔指定的时间打印一次缓存统计信息,用于了解缓存的情况.
|
|
15
|
+
*/
|
|
16
|
+
statTaskEnabled: boolean
|
|
17
|
+
/**
|
|
18
|
+
* 统计任务执行的周期,单位秒,取值 60-3600。统计周期也即是时间窗口,
|
|
19
|
+
* 每个周期都是独立的,只统计这个周期内的缓存使用情况。
|
|
20
|
+
*/
|
|
21
|
+
statInterval: number
|
|
22
|
+
/**
|
|
23
|
+
* 最大元素数量,为了控制缓存占用的内存空间,可以将 maxElements 设置的低一些。
|
|
24
|
+
*/
|
|
25
|
+
maxElements: number
|
|
26
|
+
/**
|
|
27
|
+
* 数据清理任务执行周期,单位秒.取值 1-3600,清理任务完成两件事:删除过期数据和驱逐多余记录。
|
|
28
|
+
* 如果项目规模小,缓存的内容非常少,可以将间隔设置长一些,降低频率.
|
|
29
|
+
* 如果缓存的内容很多,频率需要高一些,及时将无效数据清理掉。
|
|
30
|
+
* 否则缓存会长时间占用很高的内存无法被回收,回收器完成检查却需要很长时间,影响gc效率.
|
|
31
|
+
*/
|
|
32
|
+
cleaningInterval: number
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const ENV_PREFIX = 'CACHE'
|
|
36
|
+
|
|
37
|
+
export const config = registerConfig<CacheConfig>(
|
|
38
|
+
{
|
|
39
|
+
defaultExpireInSeconds: 60,
|
|
40
|
+
statTaskEnabled: false,
|
|
41
|
+
statInterval: 300,
|
|
42
|
+
maxElements: 1024,
|
|
43
|
+
cleaningInterval: 60
|
|
44
|
+
},
|
|
45
|
+
ENV_PREFIX,
|
|
46
|
+
{
|
|
47
|
+
defaultExpireInSeconds: [notNull(), min(1), max(3600)],
|
|
48
|
+
statTaskEnabled: [notNull()],
|
|
49
|
+
statInterval: [notNull(), min(1), max(3600 * 24)],
|
|
50
|
+
maxElements: [notNull(), min(1), max(Number.MAX_VALUE)],
|
|
51
|
+
cleaningInterval: [notNull(), min(1), max(3600)]
|
|
52
|
+
}
|
|
53
|
+
)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { scheduleWithFixedDelay } from '../task'
|
|
2
|
+
import { Cache } from './cache'
|
|
3
|
+
import { config } from './config'
|
|
4
|
+
import { PurgeTask } from './purge-task'
|
|
5
|
+
import { CacheStat } from './stat'
|
|
6
|
+
|
|
7
|
+
const valueMap = new Map<string, any>()
|
|
8
|
+
const stat = config.statTaskEnabled ? new CacheStat(valueMap) : undefined
|
|
9
|
+
const cache = new Cache(valueMap, stat)
|
|
10
|
+
|
|
11
|
+
// 清理任务
|
|
12
|
+
scheduleWithFixedDelay(config.cleaningInterval, config.cleaningInterval, new PurgeTask(valueMap))
|
|
13
|
+
|
|
14
|
+
// 统计任务
|
|
15
|
+
if (config.statTaskEnabled) {
|
|
16
|
+
scheduleWithFixedDelay(config.statInterval, config.statInterval, {
|
|
17
|
+
name: 'Cache statistics',
|
|
18
|
+
async run() {
|
|
19
|
+
stat?.log()
|
|
20
|
+
stat?.clear()
|
|
21
|
+
}
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function getCache() {
|
|
26
|
+
return cache
|
|
27
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { getLogger } from '../log'
|
|
2
|
+
import { Task } from '../task'
|
|
3
|
+
import { CacheContent } from './cache'
|
|
4
|
+
import { config } from './config'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* 缓存清理任务
|
|
8
|
+
*/
|
|
9
|
+
export class PurgeTask implements Task {
|
|
10
|
+
readonly name = 'Cache purge'
|
|
11
|
+
|
|
12
|
+
constructor(private readonly valueMap: Map<string, CacheContent>) {}
|
|
13
|
+
|
|
14
|
+
async run(): Promise<void> {
|
|
15
|
+
let removeCount = 0
|
|
16
|
+
for (const entry of this.valueMap.entries()) {
|
|
17
|
+
const [key, value] = entry
|
|
18
|
+
if (value.expireAt < new Date().getTime()) {
|
|
19
|
+
this.valueMap.delete(key)
|
|
20
|
+
removeCount++
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (removeCount > 0) {
|
|
24
|
+
getLogger().info(
|
|
25
|
+
`A total of ${removeCount} expired cache ${
|
|
26
|
+
removeCount > 1 ? 'records' : 'record'
|
|
27
|
+
} have been cleared.`
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// 如果过期的都清理掉,但是元素总数仍然超出,则删除多余元素,删除是从头开始删除的
|
|
32
|
+
// 看上去是按put顺序清理最早的,实际上随机的,重复 set 相同的 key,key 的位置是不会变的,不保证 key 的顺序
|
|
33
|
+
// 所以,缓存是随机驱逐的
|
|
34
|
+
// 目前没有考虑支持其它的策略,因为需要额外记录信息,清理的逻辑也可能更复杂
|
|
35
|
+
// nodejs 是单线程模式的,规模上去后,可能需要执行较长的时间带来阻塞
|
|
36
|
+
if (this.valueMap.size > config.maxElements) {
|
|
37
|
+
let diff = this.valueMap.size - config.maxElements
|
|
38
|
+
let evictedCount = 0
|
|
39
|
+
for (const key of this.valueMap.keys()) {
|
|
40
|
+
this.valueMap.delete(key)
|
|
41
|
+
evictedCount++
|
|
42
|
+
if (evictedCount >= diff) {
|
|
43
|
+
break
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
getLogger().info(
|
|
47
|
+
`A total of ${evictedCount} cache ${
|
|
48
|
+
evictedCount > 1 ? 'records' : 'record'
|
|
49
|
+
} have been evicted.`
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { getLogger } from '../log'
|
|
2
|
+
import { formatDateTime } from '../log/date'
|
|
3
|
+
import { config } from './config'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 缓存统计.
|
|
7
|
+
*/
|
|
8
|
+
export class CacheStat {
|
|
9
|
+
/**
|
|
10
|
+
* 开始统计时间
|
|
11
|
+
*/
|
|
12
|
+
private start: Date
|
|
13
|
+
private totalGet = 0
|
|
14
|
+
private totalHit = 0
|
|
15
|
+
|
|
16
|
+
constructor(private readonly valueMap: Map<string, any>) {
|
|
17
|
+
this.start = new Date()
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 添加 get 次数
|
|
21
|
+
* @param hit 是否命中
|
|
22
|
+
*/
|
|
23
|
+
addGet(hit: boolean) {
|
|
24
|
+
this.totalGet++
|
|
25
|
+
if (hit) {
|
|
26
|
+
this.totalHit++
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 清空统计信息,重新开始统计.
|
|
31
|
+
*/
|
|
32
|
+
clear() {
|
|
33
|
+
this.start = new Date()
|
|
34
|
+
this.totalGet = 0
|
|
35
|
+
this.totalHit = 0
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 输出日志
|
|
39
|
+
*/
|
|
40
|
+
log() {
|
|
41
|
+
getLogger().info(
|
|
42
|
+
`Cache statistics,time window :${formatDateTime(this.start)} - now, hit :${
|
|
43
|
+
this.totalHit
|
|
44
|
+
}/${this.totalGet},capacity:${this.valueMap.size}/${config.maxElements}`
|
|
45
|
+
)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ConfigException } from './exception'
|
|
2
|
+
/**
|
|
3
|
+
* 转换值.
|
|
4
|
+
* @param val
|
|
5
|
+
* @param defaultVal
|
|
6
|
+
*/
|
|
7
|
+
export function convert(val: string, defaultVal: any): string | number | boolean {
|
|
8
|
+
if (typeof defaultVal === 'string') {
|
|
9
|
+
return val
|
|
10
|
+
} else if (typeof defaultVal === 'number') {
|
|
11
|
+
const num = parseFloat(val)
|
|
12
|
+
if (isNaN(num)) {
|
|
13
|
+
throw new ConfigException(`Unable to convert value to number :${val}`)
|
|
14
|
+
}
|
|
15
|
+
return num
|
|
16
|
+
} else if (typeof defaultVal === 'boolean') {
|
|
17
|
+
if (val === 'true') {
|
|
18
|
+
return true
|
|
19
|
+
} else if (val === 'false') {
|
|
20
|
+
return false
|
|
21
|
+
} else {
|
|
22
|
+
throw new ConfigException(`Cannot convert value to a boolean type:${val}`)
|
|
23
|
+
}
|
|
24
|
+
} else {
|
|
25
|
+
throw new ConfigException(`Unsupported conversion type :${typeof defaultVal}`)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { config } from 'dotenv'
|
|
2
|
+
import { validate, ValidationOpts } from '../validation'
|
|
3
|
+
import { convert } from './convert'
|
|
4
|
+
import { ConfigException } from './exception'
|
|
5
|
+
|
|
6
|
+
// 初始化 .env 文件
|
|
7
|
+
config()
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* 环境变量配置表.
|
|
11
|
+
*/
|
|
12
|
+
const configEnvMap = new Map<string, any>()
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 获取配置
|
|
16
|
+
* @param envPrefix
|
|
17
|
+
*/
|
|
18
|
+
export function getConfig<T>(envPrefix: string): T | undefined {
|
|
19
|
+
return configEnvMap.get(envPrefix)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 注册配置信息.
|
|
24
|
+
* @param defaultConfig 默认值, 模块会根据默认值来映射环境变量,默认值所有的属性都不能是 undefined,否则无法映射.
|
|
25
|
+
* @param envPrefix 环境变量前缀.
|
|
26
|
+
* @param validation 校验规则,如果有值,初始化的时候会对配置进行校验
|
|
27
|
+
* @returns 映射了环境变量后的配置
|
|
28
|
+
*/
|
|
29
|
+
export function registerConfig<T extends {}>(
|
|
30
|
+
defaultConfig: T,
|
|
31
|
+
envPrefix: string,
|
|
32
|
+
validation?: ValidationOpts<T>
|
|
33
|
+
): T {
|
|
34
|
+
if (configEnvMap.has(envPrefix)) {
|
|
35
|
+
throw new ConfigException(`The prefix "${envPrefix}" has already been registered`)
|
|
36
|
+
}
|
|
37
|
+
const config = generateConfig(defaultConfig, envPrefix, validation)
|
|
38
|
+
configEnvMap.set(envPrefix, config)
|
|
39
|
+
return config
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 根据环境变量来生成配置对象,与 registerConfig 的参数是一致的,和 registerConfig 不同的是
|
|
44
|
+
* generateConfig 可以多次重复使用,方便在运行时更改环境变量后再生成配置,而调用 registerConfig
|
|
45
|
+
* 一旦注册后不能再被更改。之所以这样设计是为了方便程序的测试,模拟不同的环境来运行程序,和其它的
|
|
46
|
+
* 一些特殊需求。
|
|
47
|
+
* @param defaultConfig
|
|
48
|
+
* @param envPrefix
|
|
49
|
+
* @param validation
|
|
50
|
+
*/
|
|
51
|
+
export function generateConfig<T extends {}>(
|
|
52
|
+
defaultConfig: T,
|
|
53
|
+
envPrefix: string,
|
|
54
|
+
validation?: ValidationOpts<T>
|
|
55
|
+
) {
|
|
56
|
+
// 环境变量匹配
|
|
57
|
+
for (const propName in defaultConfig) {
|
|
58
|
+
const defaultVal = defaultConfig[propName]
|
|
59
|
+
const envName = buildEnvName(envPrefix, propName)
|
|
60
|
+
const envVal = process.env[envName]
|
|
61
|
+
console.log(
|
|
62
|
+
`[CONFIG]prefix:${envPrefix},env variable:${envName} ,value:${envVal},mapping property:${propName}`
|
|
63
|
+
)
|
|
64
|
+
if (!envVal) {
|
|
65
|
+
continue
|
|
66
|
+
}
|
|
67
|
+
const finalVal = convert(envVal, defaultVal)
|
|
68
|
+
;(defaultConfig as any)[propName] = finalVal
|
|
69
|
+
}
|
|
70
|
+
// 校验
|
|
71
|
+
if (validation) {
|
|
72
|
+
try {
|
|
73
|
+
validate(defaultConfig, validation)
|
|
74
|
+
} catch (e) {
|
|
75
|
+
console.error(e)
|
|
76
|
+
throw new ConfigException(
|
|
77
|
+
`Error in verifying configuration information, configuration prefix:${envPrefix}`
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return defaultConfig
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function buildEnvName(envPrefix: string, propName: string) {
|
|
85
|
+
let part2 = propName.replace(/[A-Z]+/g, subStr => `_${subStr}`)
|
|
86
|
+
if (part2.startsWith('_')) {
|
|
87
|
+
part2 = part2.substring(1)
|
|
88
|
+
}
|
|
89
|
+
return `${envPrefix.toUpperCase()}_${part2.toUpperCase()}`
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export * from './exception'
|