wok-server 0.4.13 → 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.
Files changed (376) hide show
  1. package/README.en.md +61 -0
  2. package/README.md +44 -29
  3. package/dist/cache/cache.js +98 -98
  4. package/dist/cache/config.js +19 -19
  5. package/dist/cache/index.js +27 -27
  6. package/dist/cache/purge-task.js +46 -46
  7. package/dist/cache/stat.js +47 -47
  8. package/dist/config/convert.js +36 -36
  9. package/dist/config/exception.js +14 -14
  10. package/dist/config/index.js +81 -81
  11. package/dist/http-client/index.js +136 -136
  12. package/dist/i18n/ar.js +17 -17
  13. package/dist/i18n/de.js +17 -17
  14. package/dist/i18n/en-us.js +17 -17
  15. package/dist/i18n/es.js +17 -17
  16. package/dist/i18n/fr.js +17 -17
  17. package/dist/i18n/i18n.js +231 -231
  18. package/dist/i18n/index.js +52 -52
  19. package/dist/i18n/ja.js +17 -17
  20. package/dist/i18n/ko.js +17 -17
  21. package/dist/i18n/msg.js +2 -2
  22. package/dist/i18n/pt.js +17 -17
  23. package/dist/i18n/ru.js +17 -17
  24. package/dist/i18n/tag.js +18 -18
  25. package/dist/i18n/zh-HK.js +17 -17
  26. package/dist/i18n/zh-TW.js +17 -17
  27. package/dist/i18n/zh-cn.js +17 -17
  28. package/dist/index.js +14 -14
  29. package/dist/lock/index.js +114 -114
  30. package/dist/log/config.js +35 -29
  31. package/dist/log/date.js +21 -21
  32. package/dist/log/file.js +198 -72
  33. package/dist/log/index.js +135 -105
  34. package/dist/log/level.js +33 -33
  35. package/dist/log/log.js +56 -0
  36. package/dist/log/store.js +19 -16
  37. package/dist/mongodb/collection.js +2 -2
  38. package/dist/mongodb/config.js +34 -34
  39. package/dist/mongodb/doc.js +2 -2
  40. package/dist/mongodb/exception.js +14 -14
  41. package/dist/mongodb/index.js +58 -58
  42. package/dist/mongodb/manager/base.js +563 -563
  43. package/dist/mongodb/manager/index.js +63 -63
  44. package/dist/mongodb/manager/tx-strict.js +84 -84
  45. package/dist/mongodb/manager/tx.js +30 -30
  46. package/dist/mongodb/migration.js +52 -52
  47. package/dist/mvc/access-log.js +33 -33
  48. package/dist/mvc/config.js +27 -27
  49. package/dist/mvc/exchange.js +113 -113
  50. package/dist/mvc/handler/index.js +7 -6
  51. package/dist/mvc/handler/json.js +65 -65
  52. package/dist/mvc/handler/restful.js +35 -35
  53. package/dist/mvc/handler/sse.js +65 -0
  54. package/dist/mvc/handler/upload.js +31 -31
  55. package/dist/mvc/index.js +50 -50
  56. package/dist/mvc/interceptor.js +2 -2
  57. package/dist/mvc/query.js +43 -43
  58. package/dist/mvc/render/file.js +132 -132
  59. package/dist/mvc/render/html/html.js +90 -90
  60. package/dist/mvc/render/html/index.js +18 -18
  61. package/dist/mvc/render/html/style.js +2 -2
  62. package/dist/mvc/render/index.js +7 -7
  63. package/dist/mvc/render/json.js +26 -26
  64. package/dist/mvc/render/text.js +16 -16
  65. package/dist/mvc/router.js +2 -2
  66. package/dist/mvc/server.js +272 -272
  67. package/dist/mvc/static/header.js +67 -67
  68. package/dist/mvc/static/index.js +6 -6
  69. package/dist/mvc/static/mime-type.js +84 -84
  70. package/dist/mvc/static/server-cache-config.js +66 -66
  71. package/dist/mvc/static/server-cache.js +133 -133
  72. package/dist/mvc/static/static-handler.js +372 -372
  73. package/dist/mysql/config.js +51 -51
  74. package/dist/mysql/exception.js +14 -14
  75. package/dist/mysql/index.js +87 -87
  76. package/dist/mysql/manager/base.js +239 -231
  77. package/dist/mysql/manager/index.js +107 -107
  78. package/dist/mysql/manager/ops/count.js +20 -20
  79. package/dist/mysql/manager/ops/criteria.js +356 -356
  80. package/dist/mysql/manager/ops/delete.js +65 -65
  81. package/dist/mysql/manager/ops/exist.js +26 -26
  82. package/dist/mysql/manager/ops/find.js +169 -130
  83. package/dist/mysql/manager/ops/index.js +14 -14
  84. package/dist/mysql/manager/ops/insert.js +106 -106
  85. package/dist/mysql/manager/ops/modify.js +10 -10
  86. package/dist/mysql/manager/ops/paginate.js +23 -23
  87. package/dist/mysql/manager/ops/query.js +9 -9
  88. package/dist/mysql/manager/ops/update.js +216 -216
  89. package/dist/mysql/manager/ops/utils.js +24 -24
  90. package/dist/mysql/manager/tx-strict.js +103 -100
  91. package/dist/mysql/manager/tx.js +30 -30
  92. package/dist/mysql/manager/utils.js +56 -56
  93. package/dist/mysql/migration.js +136 -136
  94. package/dist/mysql/table-info.js +8 -8
  95. package/dist/task/daily.js +59 -59
  96. package/dist/task/fixed-delay.js +38 -38
  97. package/dist/task/fixed-rate.js +42 -42
  98. package/dist/task/index.js +9 -9
  99. package/dist/task/task.js +56 -56
  100. package/dist/validation/exception.js +36 -36
  101. package/dist/validation/index.js +40 -40
  102. package/dist/validation/validator/array.js +34 -34
  103. package/dist/validation/validator/enum.js +28 -28
  104. package/dist/validation/validator/index.js +14 -14
  105. package/dist/validation/validator/length.js +40 -40
  106. package/dist/validation/validator/max-length.js +35 -35
  107. package/dist/validation/validator/max.js +29 -29
  108. package/dist/validation/validator/min-length.js +33 -33
  109. package/dist/validation/validator/min.js +29 -29
  110. package/dist/validation/validator/not-blank.js +33 -33
  111. package/dist/validation/validator/not-null.js +21 -21
  112. package/dist/validation/validator/plain-obj.js +32 -32
  113. package/dist/validation/validator/regexp.js +34 -34
  114. package/documentation/en/cache.md +56 -0
  115. package/documentation/en/config.md +96 -0
  116. package/documentation/en/engineering.md +256 -0
  117. package/documentation/en/http-client.md +32 -0
  118. package/documentation/en/i18n.md +143 -0
  119. package/documentation/en/index.md +24 -0
  120. package/documentation/en/lock.md +51 -0
  121. package/documentation/en/log.md +109 -0
  122. package/documentation/en/mongodb.md +256 -0
  123. package/documentation/en/mvc.md +688 -0
  124. package/documentation/en/mysql.md +552 -0
  125. package/documentation/en/task.md +45 -0
  126. package/documentation/en/test.md +56 -0
  127. package/documentation/en/validate.md +130 -0
  128. package/documentation/zh-cn/engineering.md +1 -1
  129. package/documentation/zh-cn/log.md +81 -8
  130. package/documentation/zh-cn/mvc.md +66 -24
  131. package/documentation/zh-cn/mysql.md +24 -23
  132. package/documentation/zh-cn/validate.md +2 -2
  133. package/package.json +3 -1
  134. package/skills/wok-server-api-rules/SKILL.md +350 -0
  135. package/skills/wok-server-cache/SKILL.md +216 -0
  136. package/skills/wok-server-config/SKILL.md +200 -0
  137. package/skills/wok-server-getting-started/SKILL.md +123 -0
  138. package/skills/wok-server-getting-started/references/engineering.md +169 -0
  139. package/skills/wok-server-http-client/SKILL.md +164 -0
  140. package/skills/wok-server-i18n/SKILL.md +214 -0
  141. package/skills/wok-server-lock/SKILL.md +144 -0
  142. package/skills/wok-server-log/SKILL.md +218 -0
  143. package/skills/wok-server-mongodb/SKILL.md +235 -0
  144. package/skills/wok-server-mvc/SKILL.md +251 -0
  145. package/skills/wok-server-mvc/references/respond-html.md +157 -0
  146. package/skills/wok-server-mvc/references/sse.md +121 -0
  147. package/skills/wok-server-mvc/references/static-files.md +47 -0
  148. package/skills/wok-server-mvc/references/upload.md +62 -0
  149. package/skills/wok-server-mvc/references/websocket.md +30 -0
  150. package/skills/wok-server-mysql/SKILL.md +315 -0
  151. package/skills/wok-server-mysql/references/multi-datasource.md +76 -0
  152. package/skills/wok-server-mysql/references/version-control.md +22 -0
  153. package/skills/wok-server-task/SKILL.md +158 -0
  154. package/skills/wok-server-validate/SKILL.md +167 -0
  155. package/src/cache/cache.ts +118 -0
  156. package/src/cache/config.ts +53 -0
  157. package/src/cache/index.ts +27 -0
  158. package/src/cache/purge-task.ts +53 -0
  159. package/src/cache/stat.ts +47 -0
  160. package/src/config/convert.ts +27 -0
  161. package/src/config/exception.ts +8 -0
  162. package/src/config/index.ts +92 -0
  163. package/src/http-client/index.ts +202 -0
  164. package/src/i18n/ar.ts +16 -0
  165. package/src/i18n/de.ts +16 -0
  166. package/src/i18n/en-us.ts +16 -0
  167. package/src/i18n/es.ts +16 -0
  168. package/src/i18n/fr.ts +16 -0
  169. package/src/i18n/i18n.ts +230 -0
  170. package/src/i18n/index.ts +50 -0
  171. package/src/i18n/ja.ts +16 -0
  172. package/src/i18n/ko.ts +16 -0
  173. package/src/i18n/msg.ts +50 -0
  174. package/src/i18n/pt.ts +16 -0
  175. package/src/i18n/ru.ts +16 -0
  176. package/src/i18n/tag.ts +18 -0
  177. package/src/i18n/zh-HK.ts +16 -0
  178. package/src/i18n/zh-TW.ts +16 -0
  179. package/src/i18n/zh-cn.ts +16 -0
  180. package/src/index.ts +11 -0
  181. package/src/lock/index.ts +164 -0
  182. package/src/log/config.ts +71 -0
  183. package/src/log/date.ts +19 -0
  184. package/src/log/file.ts +215 -0
  185. package/src/log/index.ts +136 -0
  186. package/src/log/level.ts +29 -0
  187. package/src/log/log.ts +77 -0
  188. package/src/log/store.ts +31 -0
  189. package/src/mongodb/collection.ts +25 -0
  190. package/src/mongodb/config.ts +69 -0
  191. package/src/mongodb/doc.ts +12 -0
  192. package/src/mongodb/exception.ts +8 -0
  193. package/src/mongodb/index.ts +71 -0
  194. package/src/mongodb/manager/base.ts +674 -0
  195. package/src/mongodb/manager/index.ts +80 -0
  196. package/src/mongodb/manager/tx-strict.ts +153 -0
  197. package/src/mongodb/manager/tx.ts +34 -0
  198. package/src/mongodb/migration.ts +66 -0
  199. package/src/mvc/access-log.ts +33 -0
  200. package/src/mvc/config.ts +70 -0
  201. package/src/mvc/exchange.ts +126 -0
  202. package/src/mvc/handler/index.ts +4 -0
  203. package/src/mvc/handler/json.ts +96 -0
  204. package/src/mvc/handler/restful.ts +39 -0
  205. package/src/mvc/handler/sse.ts +90 -0
  206. package/src/mvc/handler/upload.ts +54 -0
  207. package/src/mvc/index.ts +48 -0
  208. package/src/mvc/interceptor.ts +12 -0
  209. package/src/mvc/query.ts +36 -0
  210. package/src/mvc/render/file.ts +148 -0
  211. package/src/mvc/render/html/html.ts +187 -0
  212. package/src/mvc/render/html/index.ts +16 -0
  213. package/src/mvc/render/html/style.ts +1201 -0
  214. package/src/mvc/render/index.ts +4 -0
  215. package/src/mvc/render/json.ts +24 -0
  216. package/src/mvc/render/text.ts +14 -0
  217. package/src/mvc/router.ts +13 -0
  218. package/src/mvc/server.ts +315 -0
  219. package/src/mvc/static/header.ts +86 -0
  220. package/src/mvc/static/index.ts +3 -0
  221. package/src/mvc/static/mime-type.ts +81 -0
  222. package/src/mvc/static/server-cache-config.ts +92 -0
  223. package/src/mvc/static/server-cache.ts +171 -0
  224. package/src/mvc/static/static-handler.ts +445 -0
  225. package/src/mysql/config.ts +130 -0
  226. package/src/mysql/exception.ts +8 -0
  227. package/src/mysql/index.ts +88 -0
  228. package/src/mysql/manager/base.ts +285 -0
  229. package/src/mysql/manager/index.ts +112 -0
  230. package/src/mysql/manager/ops/count.ts +30 -0
  231. package/src/mysql/manager/ops/criteria.ts +412 -0
  232. package/src/mysql/manager/ops/delete.ts +96 -0
  233. package/src/mysql/manager/ops/exist.ts +41 -0
  234. package/src/mysql/manager/ops/find.ts +226 -0
  235. package/src/mysql/manager/ops/index.ts +11 -0
  236. package/src/mysql/manager/ops/insert.ts +120 -0
  237. package/src/mysql/manager/ops/modify.ts +14 -0
  238. package/src/mysql/manager/ops/paginate.ts +60 -0
  239. package/src/mysql/manager/ops/query.ts +13 -0
  240. package/src/mysql/manager/ops/update.ts +294 -0
  241. package/src/mysql/manager/ops/utils.ts +20 -0
  242. package/src/mysql/manager/tx-strict.ts +138 -0
  243. package/src/mysql/manager/tx.ts +31 -0
  244. package/src/mysql/manager/utils.ts +75 -0
  245. package/src/mysql/migration.ts +149 -0
  246. package/src/mysql/table-info.ts +41 -0
  247. package/src/task/daily.ts +70 -0
  248. package/src/task/fixed-delay.ts +45 -0
  249. package/src/task/fixed-rate.ts +49 -0
  250. package/src/task/index.ts +4 -0
  251. package/src/task/task.ts +70 -0
  252. package/src/validation/exception.ts +27 -0
  253. package/src/validation/index.ts +61 -0
  254. package/src/validation/validator/array.ts +32 -0
  255. package/src/validation/validator/enum.ts +25 -0
  256. package/src/validation/validator/index.ts +11 -0
  257. package/src/validation/validator/length.ts +42 -0
  258. package/src/validation/validator/max-length.ts +33 -0
  259. package/src/validation/validator/max.ts +26 -0
  260. package/src/validation/validator/min-length.ts +31 -0
  261. package/src/validation/validator/min.ts +26 -0
  262. package/src/validation/validator/not-blank.ts +31 -0
  263. package/src/validation/validator/not-null.ts +19 -0
  264. package/src/validation/validator/plain-obj.ts +30 -0
  265. package/src/validation/validator/regexp.ts +32 -0
  266. package/types/cache/cache.d.ts +52 -52
  267. package/types/cache/config.d.ts +32 -32
  268. package/types/cache/index.d.ts +2 -2
  269. package/types/cache/purge-task.d.ts +11 -11
  270. package/types/cache/stat.d.ts +26 -26
  271. package/types/config/convert.d.ts +6 -6
  272. package/types/config/exception.d.ts +7 -7
  273. package/types/config/index.d.ts +25 -25
  274. package/types/http-client/index.d.ts +71 -71
  275. package/types/i18n/ar.d.ts +2 -2
  276. package/types/i18n/de.d.ts +2 -2
  277. package/types/i18n/en-us.d.ts +2 -2
  278. package/types/i18n/es.d.ts +2 -2
  279. package/types/i18n/fr.d.ts +2 -2
  280. package/types/i18n/i18n.d.ts +102 -102
  281. package/types/i18n/index.d.ts +9 -9
  282. package/types/i18n/ja.d.ts +2 -2
  283. package/types/i18n/ko.d.ts +2 -2
  284. package/types/i18n/msg.d.ts +50 -50
  285. package/types/i18n/pt.d.ts +2 -2
  286. package/types/i18n/ru.d.ts +2 -2
  287. package/types/i18n/tag.d.ts +11 -11
  288. package/types/i18n/zh-HK.d.ts +2 -2
  289. package/types/i18n/zh-TW.d.ts +2 -2
  290. package/types/i18n/zh-cn.d.ts +2 -2
  291. package/types/index.d.ts +11 -11
  292. package/types/lock/index.d.ts +64 -64
  293. package/types/log/config.d.ts +35 -27
  294. package/types/log/date.d.ts +2 -2
  295. package/types/log/file.d.ts +13 -5
  296. package/types/log/index.d.ts +53 -34
  297. package/types/log/level.d.ts +14 -14
  298. package/types/log/log.d.ts +40 -0
  299. package/types/log/store.d.ts +19 -12
  300. package/types/mongodb/collection.d.ts +25 -25
  301. package/types/mongodb/config.d.ts +45 -45
  302. package/types/mongodb/doc.d.ts +11 -11
  303. package/types/mongodb/exception.d.ts +7 -7
  304. package/types/mongodb/index.d.ts +29 -29
  305. package/types/mongodb/manager/base.d.ts +188 -188
  306. package/types/mongodb/manager/index.d.ts +38 -38
  307. package/types/mongodb/manager/tx-strict.d.ts +41 -41
  308. package/types/mongodb/manager/tx.d.ts +21 -21
  309. package/types/mongodb/migration.d.ts +12 -12
  310. package/types/mvc/access-log.d.ts +7 -7
  311. package/types/mvc/config.d.ts +42 -42
  312. package/types/mvc/exchange.d.ts +72 -72
  313. package/types/mvc/handler/index.d.ts +4 -3
  314. package/types/mvc/handler/json.d.ts +44 -44
  315. package/types/mvc/handler/restful.d.ts +11 -11
  316. package/types/mvc/handler/sse.d.ts +34 -0
  317. package/types/mvc/handler/upload.d.ts +36 -36
  318. package/types/mvc/index.d.ts +22 -22
  319. package/types/mvc/interceptor.d.ts +11 -11
  320. package/types/mvc/query.d.ts +13 -13
  321. package/types/mvc/render/file.d.ts +10 -10
  322. package/types/mvc/render/html/html.d.ts +98 -98
  323. package/types/mvc/render/html/index.d.ts +11 -11
  324. package/types/mvc/render/html/style.d.ts +1201 -1201
  325. package/types/mvc/render/index.d.ts +4 -4
  326. package/types/mvc/render/json.d.ts +17 -17
  327. package/types/mvc/render/text.d.ts +10 -10
  328. package/types/mvc/router.d.ts +11 -11
  329. package/types/mvc/server.d.ts +90 -90
  330. package/types/mvc/static/header.d.ts +27 -27
  331. package/types/mvc/static/index.d.ts +3 -3
  332. package/types/mvc/static/mime-type.d.ts +2 -2
  333. package/types/mvc/static/server-cache-config.d.ts +30 -30
  334. package/types/mvc/static/server-cache.d.ts +76 -76
  335. package/types/mvc/static/static-handler.d.ts +77 -77
  336. package/types/mysql/config.d.ts +90 -90
  337. package/types/mysql/exception.d.ts +7 -7
  338. package/types/mysql/index.d.ts +16 -16
  339. package/types/mysql/manager/base.d.ts +165 -159
  340. package/types/mysql/manager/index.d.ts +36 -36
  341. package/types/mysql/manager/ops/count.d.ts +13 -13
  342. package/types/mysql/manager/ops/criteria.d.ts +134 -134
  343. package/types/mysql/manager/ops/delete.d.ts +46 -46
  344. package/types/mysql/manager/ops/exist.d.ts +6 -6
  345. package/types/mysql/manager/ops/find.d.ts +86 -70
  346. package/types/mysql/manager/ops/index.d.ts +10 -10
  347. package/types/mysql/manager/ops/insert.d.ts +18 -18
  348. package/types/mysql/manager/ops/modify.d.ts +3 -3
  349. package/types/mysql/manager/ops/paginate.d.ts +36 -36
  350. package/types/mysql/manager/ops/query.d.ts +3 -3
  351. package/types/mysql/manager/ops/update.d.ts +76 -76
  352. package/types/mysql/manager/ops/utils.d.ts +5 -5
  353. package/types/mysql/manager/tx-strict.d.ts +36 -35
  354. package/types/mysql/manager/tx.d.ts +15 -15
  355. package/types/mysql/manager/utils.d.ts +17 -17
  356. package/types/mysql/migration.d.ts +8 -8
  357. package/types/mysql/table-info.d.ts +36 -36
  358. package/types/task/daily.d.ts +16 -16
  359. package/types/task/fixed-delay.d.ts +9 -9
  360. package/types/task/fixed-rate.d.ts +9 -9
  361. package/types/task/index.d.ts +4 -4
  362. package/types/task/task.d.ts +34 -34
  363. package/types/validation/exception.d.ts +38 -38
  364. package/types/validation/index.d.ts +32 -32
  365. package/types/validation/validator/array.d.ts +5 -5
  366. package/types/validation/validator/enum.d.ts +8 -8
  367. package/types/validation/validator/index.d.ts +11 -11
  368. package/types/validation/validator/length.d.ts +10 -10
  369. package/types/validation/validator/max-length.d.ts +8 -8
  370. package/types/validation/validator/max.d.ts +7 -7
  371. package/types/validation/validator/min-length.d.ts +6 -6
  372. package/types/validation/validator/min.d.ts +7 -7
  373. package/types/validation/validator/not-blank.d.ts +7 -7
  374. package/types/validation/validator/not-null.d.ts +6 -6
  375. package/types/validation/validator/plain-obj.d.ts +7 -7
  376. package/types/validation/validator/regexp.d.ts +8 -8
@@ -0,0 +1,41 @@
1
+ import { notBlank, ValidationOpts } from '../validation'
2
+
3
+ /**
4
+ * 表信息. 表的字段分为三个部分:主键、普通列、时间列,分别对应的属性是:id、columns
5
+ * 和 createDate 还有 updatedDate,这三部分配置的字段名称不允许有重叠,否则会产生错误.
6
+ */
7
+ export interface Table<T> {
8
+ /**
9
+ * 表名.
10
+ */
11
+ tableName: string
12
+ /**
13
+ * id 字段名称.
14
+ */
15
+ id: keyof T
16
+ /**
17
+ * 列字段名称.只有配置了名称的字段才会参与数据库的查询与更新,没有配置的其它字段可作其它用途。
18
+ * 注意:columns 配置的字段不能和 id 或更新时间和创建时间重叠,否则在更新时产生错误,将数据改错。
19
+ * 程序本身是不会做检查的,编写的时候必须要注意。
20
+ */
21
+ columns: Array<keyof T>
22
+ /**
23
+ * 创建时间字段信息.
24
+ */
25
+ createdDate?: {
26
+ column: keyof T
27
+ type: 'number' | 'date'
28
+ }
29
+ /**
30
+ * 更新时间字段信息.
31
+ */
32
+ updatedDate?: {
33
+ column: keyof T
34
+ type: 'number' | 'date'
35
+ }
36
+ }
37
+
38
+ export const tableValidation: ValidationOpts<Table<any>> = {
39
+ tableName: [notBlank('表名不能为空')],
40
+ id: [notBlank('id 不能为空')]
41
+ }
@@ -0,0 +1,70 @@
1
+ import { max, min, notNull, validate } from '../validation'
2
+ import { Task, TaskController, execTask } from './task'
3
+
4
+ /**
5
+ * 每日任务.
6
+ * @param hours 时
7
+ * @param minutes 分
8
+ * @param task 要执行的任务
9
+ * @param timeout 任务超时时间,单位毫秒
10
+ * @returns
11
+ */
12
+ export function scheduleDailyTask(
13
+ hours: number,
14
+ minutes: number,
15
+ task: Task,
16
+ timeout?: number
17
+ ): TaskController {
18
+ // 校验
19
+ validate(
20
+ { hours, minutes },
21
+ {
22
+ hours: [notNull(), min(0), max(23)],
23
+ minutes: [notNull(), min(0), max(59)]
24
+ }
25
+ )
26
+ const taskController = new TaskController()
27
+ const delay = dailyTaskDelay(hours, minutes)
28
+ setTimeout(() => exec(hours, minutes, task, taskController, timeout), delay)
29
+ return taskController
30
+ }
31
+ /**
32
+ * 计算到下次指定时间点的延迟
33
+ * @param hours
34
+ * @param minutes
35
+ */
36
+ export function dailyTaskDelay(hours: number, minutes: number): number {
37
+ const now = new Date()
38
+ let todayTime = new Date()
39
+ todayTime.setHours(hours)
40
+ todayTime.setMinutes(minutes)
41
+ todayTime.setSeconds(0)
42
+ todayTime.setMilliseconds(0)
43
+ // 如果今天还没有到指定的点,今天就执行,否则明天执行
44
+ if (todayTime > now) {
45
+ return todayTime.getTime() - now.getTime()
46
+ }
47
+ // 明天时间
48
+ const oneDayMilliseconds = 1000 * 3600 * 24
49
+ const tomorrowTime = todayTime.getTime() + oneDayMilliseconds
50
+ return tomorrowTime - now.getTime()
51
+ }
52
+
53
+ function exec(
54
+ hours: number,
55
+ minutes: number,
56
+ task: Task,
57
+ controller: TaskController,
58
+ timeout?: number
59
+ ) {
60
+ Promise.resolve()
61
+ .then(async () => {
62
+ if (controller.isStopped()) {
63
+ return
64
+ }
65
+ await execTask(task, timeout)
66
+ const delay = dailyTaskDelay(hours, minutes)
67
+ setTimeout(() => exec(hours, minutes, task, controller), delay)
68
+ })
69
+ .catch(console.error)
70
+ }
@@ -0,0 +1,45 @@
1
+ import { getLockManager } from '../lock'
2
+ import { getLogger } from '../log'
3
+ import { max, min, notNull, validate } from '../validation'
4
+ import { Task, TaskController, execTask } from './task'
5
+
6
+ /**
7
+ * 固定延迟执行任务
8
+ * @param initialDelay 第一次执行延迟的时间,单位秒
9
+ * @param delay 每次的延迟时间,单位秒
10
+ * @param task 任务
11
+ * @param timeout 任务超时时间,单位毫秒
12
+ */
13
+ export function scheduleWithFixedDelay(
14
+ initialDelay: number,
15
+ delay: number,
16
+ task: Task,
17
+ timeout?: number
18
+ ): TaskController {
19
+ validate(
20
+ { initialDelay, delay },
21
+ {
22
+ initialDelay: [notNull(), min(0), max(3600 * 24)],
23
+ delay: [notNull(), min(1), max(3600 * 24)]
24
+ }
25
+ )
26
+ const controller = new TaskController()
27
+ setTimeout(() => exec(delay, task, controller, timeout), initialDelay * 1000)
28
+ return controller
29
+ }
30
+
31
+ function exec(delay: number, task: Task, controller: TaskController, timeout?: number) {
32
+ Promise.resolve()
33
+ .then(async () => {
34
+ if (controller.isStopped()) {
35
+ return
36
+ }
37
+ await execTask(task, timeout)
38
+ // 下次执行
39
+ setTimeout(() => exec(delay, task, controller), delay * 1000)
40
+ })
41
+ .catch(e => {
42
+ getLogger().error(`EXEC TASK ERROR: ${task.name}`, e)
43
+ })
44
+ .catch(console.error)
45
+ }
@@ -0,0 +1,49 @@
1
+ import { getLogger } from '../log'
2
+ import { max, min, notNull, validate } from '../validation'
3
+ import { Task, TaskController, execTask } from './task'
4
+
5
+ /**
6
+ * 固定延迟执行任务
7
+ * @param initialDelay 第一次执行延迟的时间,单位秒
8
+ * @param period 每次的延迟时间,单位秒
9
+ * @param task 任务
10
+ * @param timeout 任务超时时间,单位毫秒
11
+ */
12
+ export function scheduleWithFixedRate(
13
+ initialDelay: number,
14
+ period: number,
15
+ task: Task,
16
+ timeout?: number
17
+ ): TaskController {
18
+ validate(
19
+ { initialDelay, period },
20
+ {
21
+ initialDelay: [notNull(), min(0), max(3600 * 24)],
22
+ period: [notNull(), min(1), max(3600 * 24)]
23
+ }
24
+ )
25
+
26
+ const taskController = new TaskController()
27
+ setTimeout(() => exec(period, task, taskController, timeout), initialDelay * 1000)
28
+ return taskController
29
+ }
30
+
31
+ function exec(fixedDelay: number, task: Task, controller: TaskController, timeout?: number) {
32
+ Promise.resolve()
33
+ .then(async () => {
34
+ if (controller.isStopped()) {
35
+ return
36
+ }
37
+ const res = await execTask(task, timeout)
38
+ // 下次执行
39
+ let delay = res.start + fixedDelay * 1000 - new Date().getTime()
40
+ if (delay < 0) {
41
+ delay = 0
42
+ }
43
+ setTimeout(() => exec(fixedDelay, task, controller), delay)
44
+ })
45
+ .catch(e => {
46
+ getLogger().error(`EXEC TASK ERROR: ${task.name}`, e)
47
+ })
48
+ .catch(console.error)
49
+ }
@@ -0,0 +1,4 @@
1
+ export { Task, TaskController } from './task'
2
+ export * from './fixed-delay'
3
+ export * from './fixed-rate'
4
+ export * from './daily'
@@ -0,0 +1,70 @@
1
+ import { getLogger } from '../log'
2
+
3
+ /**
4
+ * 任务.
5
+ */
6
+ export interface Task {
7
+ /**
8
+ * 任务的名称,用于跟踪任务的执行情况,定位错误.
9
+ * 当任务执行时间过长或任务失败时,相关的错误提示信息会显示名称,以便于排查.
10
+ */
11
+ name: string
12
+ /**
13
+ * 任务运行.
14
+ * @returns
15
+ */
16
+ run: () => Promise<void>
17
+ }
18
+
19
+ /**
20
+ * 任务控制器
21
+ */
22
+ export class TaskController {
23
+ #stopped = false
24
+ isStopped() {
25
+ return this.#stopped
26
+ }
27
+
28
+ stop() {
29
+ this.#stopped = true
30
+ }
31
+ }
32
+
33
+ /**
34
+ * 任务执行,封装任务执行过程中的一些通用信息输出和异常控制.
35
+ * @param task
36
+ * @param timeout 任务超时时间,单位毫秒
37
+ * @returns
38
+ */
39
+ export async function execTask(
40
+ task: Task,
41
+ timeout?: number
42
+ ): Promise<{ start: number; cost: number; end: number }> {
43
+ const start = new Date().getTime()
44
+ try {
45
+ getLogger().debug(`START TASK:${task.name}`)
46
+ // 支持任务超时设置
47
+ if (timeout && timeout > 0) {
48
+ await Promise.race([
49
+ task.run(),
50
+ new Promise<void>((_, reject) => {
51
+ setTimeout(() => {
52
+ reject('The task has timed out.')
53
+ }, timeout)
54
+ })
55
+ ])
56
+ } else {
57
+ await task.run()
58
+ }
59
+ } catch (e) {
60
+ getLogger().error(`TASK ERROR: ${task.name}`, e)
61
+ }
62
+ const end = Date.now()
63
+ const cost = end - start
64
+ if (cost > 1000 * 60 * 5) {
65
+ getLogger().warn(`Task "${task.name}" takes too long ,cost ${cost}ms`)
66
+ } else {
67
+ getLogger().debug(`Task "${task.name}" has finished, taking a total of ${cost} milliseconds.`)
68
+ }
69
+ return { start, cost, end }
70
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * 校验异常.
3
+ */
4
+ export class ValidationException extends Error {
5
+ constructor(
6
+ /**
7
+ * 异常信息,如 “不能为空” 之类的.
8
+ */
9
+ readonly errMsg: string,
10
+ /**
11
+ * 校验器名称,如 length 、notNull 之类的.
12
+ */
13
+ readonly validator: string,
14
+ /**
15
+ * 校验出错的路径.
16
+ */
17
+ readonly propertyPath: string,
18
+ /**
19
+ * 值
20
+ */
21
+ readonly val: any
22
+ ) {
23
+ super(
24
+ `Field "${propertyPath}" failed to validate by validator ${validator} ,value:${val},info:${errMsg}`
25
+ )
26
+ }
27
+ }
@@ -0,0 +1,61 @@
1
+ import { ValidationException } from './exception'
2
+ /**
3
+ * 校验结果。message:错误信息,反馈给调用处;validator 校验器名称,用于记录错误信息来自哪个校验器,
4
+ * 以便于程序在出错时知道信息来自哪里。
5
+ */
6
+ export type ValidationResult =
7
+ | { ok: true }
8
+ | {
9
+ ok: false
10
+ message: string
11
+ validator: string
12
+ /**
13
+ * 如果校验的是层级深的对象,内部的属性发生了错误,可用于标记属性的路径
14
+ */
15
+ propPath?: string[]
16
+ }
17
+ /**
18
+ * 校验器.
19
+ */
20
+ export type PropValidator<T> = (val: T) => ValidationResult
21
+
22
+ /**
23
+ * 对象的校验选项
24
+ */
25
+ export type ValidationOpts<T> = Partial<{ [key in keyof T]: PropValidator<T[key]>[] }>
26
+
27
+ /**
28
+ * 校验对象.
29
+ * @param obj
30
+ */
31
+ export function validate<T>(obj: T, opts: ValidationOpts<T>) {
32
+ for (const entry of Object.entries(opts)) {
33
+ const [prop, validators] = entry
34
+ const val = obj[prop as keyof T]
35
+ for (const validator of validators as PropValidator<any>[]) {
36
+ const result = validator(val)
37
+ if (!result.ok) {
38
+ const propPath = [prop]
39
+ if (result.propPath) {
40
+ propPath.push(...result.propPath)
41
+ }
42
+ const fullPath = propPath
43
+ .map((prop, idx) => {
44
+ if (idx === 0) {
45
+ return prop
46
+ }
47
+ if (prop.startsWith('[') && prop.endsWith(']')) {
48
+ return prop
49
+ }
50
+ return '.' + prop
51
+ })
52
+ .join('')
53
+ throw new ValidationException(result.message, result.validator, fullPath, val)
54
+ }
55
+ }
56
+ }
57
+ }
58
+
59
+ // 导出
60
+ export * from './exception'
61
+ export * from './validator'
@@ -0,0 +1,32 @@
1
+ import { PropValidator } from '..'
2
+ import { getI18n } from '../../i18n'
3
+
4
+ /**
5
+ * 校验数组的条目.
6
+ */
7
+ export function array<T>(opts: PropValidator<T>[]): PropValidator<T[] | undefined> {
8
+ const validator = 'array'
9
+ return val => {
10
+ if (!val) {
11
+ return { ok: true }
12
+ }
13
+ if (!Array.isArray(val)) {
14
+ return { ok: false, validator, message: getI18n().buildMsg('validate-err-array') }
15
+ }
16
+ // 条目处理
17
+ for (let i = 0; i < val.length; i++) {
18
+ const item = val[i] as T
19
+ for (const validation of opts) {
20
+ const result = validation(item)
21
+ if (!result.ok) {
22
+ const propPath = [`[${i}]`]
23
+ if (result.propPath) {
24
+ propPath.push(...result.propPath)
25
+ }
26
+ return { ok: false, validator, message: result.message, propPath }
27
+ }
28
+ }
29
+ }
30
+ return { ok: true }
31
+ }
32
+ }
@@ -0,0 +1,25 @@
1
+ import { PropValidator } from '..'
2
+ import { getI18n } from '../../i18n'
3
+ /**
4
+ * 枚举,校验值必须是指定列表中的一个.
5
+ * @param list 支持的值列表,仅支持数字和字符串类型
6
+ * @param msg
7
+ * @returns
8
+ */
9
+ export function enumerate<T>(list: (number | string)[], msg?: string): PropValidator<T> {
10
+ const validator = 'enumerate'
11
+ return val => {
12
+ if (!val) {
13
+ return { ok: true }
14
+ }
15
+ if (!list.some(item => item === val)) {
16
+ return {
17
+ ok: false,
18
+ validator,
19
+ // must be one of [1,2,3]
20
+ message: msg || getI18n().buildMsg('validate-err-enum', `[${list.join(',')}]`)
21
+ }
22
+ }
23
+ return { ok: true }
24
+ }
25
+ }
@@ -0,0 +1,11 @@
1
+ export * from './not-null'
2
+ export * from './not-blank'
3
+ export * from './max'
4
+ export * from './min'
5
+ export * from './regexp'
6
+ export * from './length'
7
+ export * from './enum'
8
+ export * from './array'
9
+ export * from './plain-obj'
10
+ export * from './max-length'
11
+ export * from './min-length'
@@ -0,0 +1,42 @@
1
+ import { PropValidator } from '..'
2
+ import { getI18n } from '../../i18n'
3
+
4
+ /**
5
+ * length 校验,可用于字符串或数组.
6
+ * @returns
7
+ */
8
+ export function length<T>(opts: {
9
+ min?: number
10
+ max?: number
11
+ message?: string
12
+ }): PropValidator<T> {
13
+ const validator = 'length'
14
+ return val => {
15
+ // 不校验空
16
+ if (!val) {
17
+ return { ok: true }
18
+ }
19
+ if (typeof (val as any).length !== 'number') {
20
+ return { ok: false, validator, message: getI18n().buildMsg('validate-err-no-length') }
21
+ }
22
+ const { length } = val as any
23
+ if (typeof length !== 'number') {
24
+ return { ok: false, validator, message: getI18n().buildMsg('validate-err-length-not-number') }
25
+ }
26
+ if (typeof opts.min === 'number' && length < opts.min) {
27
+ return {
28
+ ok: false,
29
+ validator,
30
+ message: opts.message || getI18n().buildMsg('validate-err-min-length', `${opts.min}`)
31
+ }
32
+ }
33
+ if (typeof opts.max === 'number' && length > opts.max) {
34
+ return {
35
+ ok: false,
36
+ validator,
37
+ message: opts.message || getI18n().buildMsg('validate-err-max-length', `${opts.max}`)
38
+ }
39
+ }
40
+ return { ok: true }
41
+ }
42
+ }
@@ -0,0 +1,33 @@
1
+ import { PropValidator } from '..'
2
+ import { getI18n } from '../../i18n'
3
+
4
+ /**
5
+ * 最大长度校验,可用于字符串或数组.
6
+ * @param maxLength
7
+ * @param message
8
+ * @returns
9
+ */
10
+ export function maxLength<T>(maxLength: number, message?: string): PropValidator<T> {
11
+ const validator = 'maxLength'
12
+ return val => {
13
+ // 不校验空
14
+ if (!val) {
15
+ return { ok: true }
16
+ }
17
+ if (typeof (val as any).length !== 'number') {
18
+ return { ok: false, validator, message: getI18n().buildMsg('validate-err-no-length') }
19
+ }
20
+ const { length } = val as any
21
+ if (typeof length !== 'number') {
22
+ return { ok: false, validator, message: getI18n().buildMsg('validate-err-length-not-number') }
23
+ }
24
+ if (length > maxLength) {
25
+ return {
26
+ ok: false,
27
+ validator,
28
+ message: message || getI18n().buildMsg('validate-err-max-length', `${maxLength}`)
29
+ }
30
+ }
31
+ return { ok: true }
32
+ }
33
+ }
@@ -0,0 +1,26 @@
1
+ import { PropValidator } from '..'
2
+ import { getI18n } from '../../i18n'
3
+ /**
4
+ * 最大值校验.
5
+ * @param max 最大值
6
+ * @param msg 错误消息
7
+ */
8
+ export function max<T>(max: number, msg?: string): PropValidator<T> {
9
+ const validator = 'max'
10
+ return val => {
11
+ if (val == undefined || val === null) {
12
+ return { ok: true }
13
+ }
14
+ if (typeof val !== 'number') {
15
+ return { ok: false, validator, message: getI18n().buildMsg('validate-err-numer') }
16
+ }
17
+ if (val > max) {
18
+ return {
19
+ ok: false,
20
+ validator,
21
+ message: msg || getI18n().buildMsg('validate-err-max', `${max}`)
22
+ }
23
+ }
24
+ return { ok: true }
25
+ }
26
+ }
@@ -0,0 +1,31 @@
1
+ import { PropValidator } from '..'
2
+ import { getI18n } from '../../i18n'
3
+
4
+ /**
5
+ * 最小长度校验,可用于字符串或数组.
6
+ * @returns
7
+ */
8
+ export function minLength<T>(minLength: number, message?: string): PropValidator<T> {
9
+ const validator = 'minLength'
10
+ return val => {
11
+ // 不校验空
12
+ if (!val) {
13
+ return { ok: true }
14
+ }
15
+ if (typeof (val as any).length !== 'number') {
16
+ return { ok: false, validator, message: getI18n().buildMsg('validate-err-no-length') }
17
+ }
18
+ const { length } = val as any
19
+ if (typeof length !== 'number') {
20
+ return { ok: false, validator, message: getI18n().buildMsg('validate-err-length-not-number') }
21
+ }
22
+ if (length < minLength) {
23
+ return {
24
+ ok: false,
25
+ validator,
26
+ message: message || getI18n().buildMsg('validate-err-min-length', `${minLength}`)
27
+ }
28
+ }
29
+ return { ok: true }
30
+ }
31
+ }
@@ -0,0 +1,26 @@
1
+ import { PropValidator } from '..'
2
+ import { getI18n } from '../../i18n'
3
+ /**
4
+ * 最小值校验.
5
+ * @param min 最小值
6
+ * @param msg 错误消息
7
+ */
8
+ export function min<T>(min: number, msg?: string): PropValidator<T> {
9
+ const validator = 'min'
10
+ return val => {
11
+ if (val == undefined || val === null) {
12
+ return { ok: true }
13
+ }
14
+ if (typeof val !== 'number') {
15
+ return { ok: false, validator, message: getI18n().buildMsg('validate-err-numer') }
16
+ }
17
+ if (val < min) {
18
+ return {
19
+ ok: false,
20
+ validator,
21
+ message: msg || getI18n().buildMsg('validate-err-min', `${min}`)
22
+ }
23
+ }
24
+ return { ok: true }
25
+ }
26
+ }
@@ -0,0 +1,31 @@
1
+ import { PropValidator } from '..'
2
+ import { getI18n } from '../../i18n'
3
+
4
+ /**
5
+ * 字符串非空校验,以下的情况不会通过校验:undefined,null,非 string 类型,空白字符串.
6
+ * @param message
7
+ * @returns
8
+ */
9
+ export function notBlank<T>(message?: string): PropValidator<T> {
10
+ const validator = 'notBlank'
11
+ return val => {
12
+ if (val === undefined || val === null) {
13
+ return {
14
+ ok: false,
15
+ validator,
16
+ message: message || getI18n().buildMsg('validate-err-empty')
17
+ }
18
+ }
19
+ if (typeof val !== 'string') {
20
+ return { ok: false, validator, message: getI18n().buildMsg('validate-err-string') }
21
+ }
22
+ if (!val.trim()) {
23
+ return {
24
+ ok: false,
25
+ validator,
26
+ message: message || getI18n().buildMsg('validate-err-empty')
27
+ }
28
+ }
29
+ return { ok: true }
30
+ }
31
+ }
@@ -0,0 +1,19 @@
1
+ import { PropValidator } from '..'
2
+ import { getI18n } from '../../i18n'
3
+
4
+ /**
5
+ * 非空校验.
6
+ * @param message
7
+ */
8
+ export function notNull<T>(message?: string): PropValidator<T> {
9
+ return val => {
10
+ if (val === null || val === undefined) {
11
+ return {
12
+ ok: false,
13
+ message: message || getI18n().buildMsg('validate-err-empty'),
14
+ validator: 'notNull'
15
+ }
16
+ }
17
+ return { ok: true }
18
+ }
19
+ }
@@ -0,0 +1,30 @@
1
+ import { PropValidator, ValidationOpts } from '..'
2
+
3
+ /**
4
+ * 普通对象校验.
5
+ * @param opts
6
+ * @returns
7
+ */
8
+ export function plainObject<T>(opts: ValidationOpts<Exclude<T, undefined>>): PropValidator<T> {
9
+ const validator = 'plainObject'
10
+ return val => {
11
+ if (!val) {
12
+ return { ok: true }
13
+ }
14
+ for (const entry of Object.entries(opts)) {
15
+ const [prop, validators] = entry
16
+ const v = val[prop as keyof T]
17
+ for (const validate of validators as PropValidator<any>[]) {
18
+ const result = validate(v)
19
+ if (!result.ok) {
20
+ const propPath = [prop]
21
+ if (result.propPath) {
22
+ propPath.push(...result.propPath)
23
+ }
24
+ return { ok: false, validator, message: result.message, propPath }
25
+ }
26
+ }
27
+ }
28
+ return { ok: true }
29
+ }
30
+ }