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.
Files changed (372) 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 -35
  31. package/dist/log/date.js +21 -21
  32. package/dist/log/file.js +198 -198
  33. package/dist/log/index.js +135 -135
  34. package/dist/log/level.js +33 -33
  35. package/dist/log/log.js +56 -56
  36. package/dist/log/store.js +19 -19
  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 -239
  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 -169
  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 -103
  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/mvc.md +66 -24
  129. package/package.json +3 -1
  130. package/skills/wok-server-api-rules/SKILL.md +350 -0
  131. package/skills/wok-server-cache/SKILL.md +216 -0
  132. package/skills/wok-server-config/SKILL.md +200 -0
  133. package/skills/wok-server-getting-started/SKILL.md +123 -0
  134. package/skills/wok-server-getting-started/references/engineering.md +169 -0
  135. package/skills/wok-server-http-client/SKILL.md +164 -0
  136. package/skills/wok-server-i18n/SKILL.md +214 -0
  137. package/skills/wok-server-lock/SKILL.md +144 -0
  138. package/skills/wok-server-log/SKILL.md +218 -0
  139. package/skills/wok-server-mongodb/SKILL.md +235 -0
  140. package/skills/wok-server-mvc/SKILL.md +251 -0
  141. package/skills/wok-server-mvc/references/respond-html.md +157 -0
  142. package/skills/wok-server-mvc/references/sse.md +121 -0
  143. package/skills/wok-server-mvc/references/static-files.md +47 -0
  144. package/skills/wok-server-mvc/references/upload.md +62 -0
  145. package/skills/wok-server-mvc/references/websocket.md +30 -0
  146. package/skills/wok-server-mysql/SKILL.md +315 -0
  147. package/skills/wok-server-mysql/references/multi-datasource.md +76 -0
  148. package/skills/wok-server-mysql/references/version-control.md +22 -0
  149. package/skills/wok-server-task/SKILL.md +158 -0
  150. package/skills/wok-server-validate/SKILL.md +167 -0
  151. package/src/cache/cache.ts +118 -0
  152. package/src/cache/config.ts +53 -0
  153. package/src/cache/index.ts +27 -0
  154. package/src/cache/purge-task.ts +53 -0
  155. package/src/cache/stat.ts +47 -0
  156. package/src/config/convert.ts +27 -0
  157. package/src/config/exception.ts +8 -0
  158. package/src/config/index.ts +92 -0
  159. package/src/http-client/index.ts +202 -0
  160. package/src/i18n/ar.ts +16 -0
  161. package/src/i18n/de.ts +16 -0
  162. package/src/i18n/en-us.ts +16 -0
  163. package/src/i18n/es.ts +16 -0
  164. package/src/i18n/fr.ts +16 -0
  165. package/src/i18n/i18n.ts +230 -0
  166. package/src/i18n/index.ts +50 -0
  167. package/src/i18n/ja.ts +16 -0
  168. package/src/i18n/ko.ts +16 -0
  169. package/src/i18n/msg.ts +50 -0
  170. package/src/i18n/pt.ts +16 -0
  171. package/src/i18n/ru.ts +16 -0
  172. package/src/i18n/tag.ts +18 -0
  173. package/src/i18n/zh-HK.ts +16 -0
  174. package/src/i18n/zh-TW.ts +16 -0
  175. package/src/i18n/zh-cn.ts +16 -0
  176. package/src/index.ts +11 -0
  177. package/src/lock/index.ts +164 -0
  178. package/src/log/config.ts +71 -0
  179. package/src/log/date.ts +19 -0
  180. package/src/log/file.ts +215 -0
  181. package/src/log/index.ts +136 -0
  182. package/src/log/level.ts +29 -0
  183. package/src/log/log.ts +77 -0
  184. package/src/log/store.ts +31 -0
  185. package/src/mongodb/collection.ts +25 -0
  186. package/src/mongodb/config.ts +69 -0
  187. package/src/mongodb/doc.ts +12 -0
  188. package/src/mongodb/exception.ts +8 -0
  189. package/src/mongodb/index.ts +71 -0
  190. package/src/mongodb/manager/base.ts +674 -0
  191. package/src/mongodb/manager/index.ts +80 -0
  192. package/src/mongodb/manager/tx-strict.ts +153 -0
  193. package/src/mongodb/manager/tx.ts +34 -0
  194. package/src/mongodb/migration.ts +66 -0
  195. package/src/mvc/access-log.ts +33 -0
  196. package/src/mvc/config.ts +70 -0
  197. package/src/mvc/exchange.ts +126 -0
  198. package/src/mvc/handler/index.ts +4 -0
  199. package/src/mvc/handler/json.ts +96 -0
  200. package/src/mvc/handler/restful.ts +39 -0
  201. package/src/mvc/handler/sse.ts +90 -0
  202. package/src/mvc/handler/upload.ts +54 -0
  203. package/src/mvc/index.ts +48 -0
  204. package/src/mvc/interceptor.ts +12 -0
  205. package/src/mvc/query.ts +36 -0
  206. package/src/mvc/render/file.ts +148 -0
  207. package/src/mvc/render/html/html.ts +187 -0
  208. package/src/mvc/render/html/index.ts +16 -0
  209. package/src/mvc/render/html/style.ts +1201 -0
  210. package/src/mvc/render/index.ts +4 -0
  211. package/src/mvc/render/json.ts +24 -0
  212. package/src/mvc/render/text.ts +14 -0
  213. package/src/mvc/router.ts +13 -0
  214. package/src/mvc/server.ts +315 -0
  215. package/src/mvc/static/header.ts +86 -0
  216. package/src/mvc/static/index.ts +3 -0
  217. package/src/mvc/static/mime-type.ts +81 -0
  218. package/src/mvc/static/server-cache-config.ts +92 -0
  219. package/src/mvc/static/server-cache.ts +171 -0
  220. package/src/mvc/static/static-handler.ts +445 -0
  221. package/src/mysql/config.ts +130 -0
  222. package/src/mysql/exception.ts +8 -0
  223. package/src/mysql/index.ts +88 -0
  224. package/src/mysql/manager/base.ts +285 -0
  225. package/src/mysql/manager/index.ts +112 -0
  226. package/src/mysql/manager/ops/count.ts +30 -0
  227. package/src/mysql/manager/ops/criteria.ts +412 -0
  228. package/src/mysql/manager/ops/delete.ts +96 -0
  229. package/src/mysql/manager/ops/exist.ts +41 -0
  230. package/src/mysql/manager/ops/find.ts +226 -0
  231. package/src/mysql/manager/ops/index.ts +11 -0
  232. package/src/mysql/manager/ops/insert.ts +120 -0
  233. package/src/mysql/manager/ops/modify.ts +14 -0
  234. package/src/mysql/manager/ops/paginate.ts +60 -0
  235. package/src/mysql/manager/ops/query.ts +13 -0
  236. package/src/mysql/manager/ops/update.ts +294 -0
  237. package/src/mysql/manager/ops/utils.ts +20 -0
  238. package/src/mysql/manager/tx-strict.ts +138 -0
  239. package/src/mysql/manager/tx.ts +31 -0
  240. package/src/mysql/manager/utils.ts +75 -0
  241. package/src/mysql/migration.ts +149 -0
  242. package/src/mysql/table-info.ts +41 -0
  243. package/src/task/daily.ts +70 -0
  244. package/src/task/fixed-delay.ts +45 -0
  245. package/src/task/fixed-rate.ts +49 -0
  246. package/src/task/index.ts +4 -0
  247. package/src/task/task.ts +70 -0
  248. package/src/validation/exception.ts +27 -0
  249. package/src/validation/index.ts +61 -0
  250. package/src/validation/validator/array.ts +32 -0
  251. package/src/validation/validator/enum.ts +25 -0
  252. package/src/validation/validator/index.ts +11 -0
  253. package/src/validation/validator/length.ts +42 -0
  254. package/src/validation/validator/max-length.ts +33 -0
  255. package/src/validation/validator/max.ts +26 -0
  256. package/src/validation/validator/min-length.ts +31 -0
  257. package/src/validation/validator/min.ts +26 -0
  258. package/src/validation/validator/not-blank.ts +31 -0
  259. package/src/validation/validator/not-null.ts +19 -0
  260. package/src/validation/validator/plain-obj.ts +30 -0
  261. package/src/validation/validator/regexp.ts +32 -0
  262. package/types/cache/cache.d.ts +52 -52
  263. package/types/cache/config.d.ts +32 -32
  264. package/types/cache/index.d.ts +2 -2
  265. package/types/cache/purge-task.d.ts +11 -11
  266. package/types/cache/stat.d.ts +26 -26
  267. package/types/config/convert.d.ts +6 -6
  268. package/types/config/exception.d.ts +7 -7
  269. package/types/config/index.d.ts +25 -25
  270. package/types/http-client/index.d.ts +71 -71
  271. package/types/i18n/ar.d.ts +2 -2
  272. package/types/i18n/de.d.ts +2 -2
  273. package/types/i18n/en-us.d.ts +2 -2
  274. package/types/i18n/es.d.ts +2 -2
  275. package/types/i18n/fr.d.ts +2 -2
  276. package/types/i18n/i18n.d.ts +102 -102
  277. package/types/i18n/index.d.ts +9 -9
  278. package/types/i18n/ja.d.ts +2 -2
  279. package/types/i18n/ko.d.ts +2 -2
  280. package/types/i18n/msg.d.ts +50 -50
  281. package/types/i18n/pt.d.ts +2 -2
  282. package/types/i18n/ru.d.ts +2 -2
  283. package/types/i18n/tag.d.ts +11 -11
  284. package/types/i18n/zh-HK.d.ts +2 -2
  285. package/types/i18n/zh-TW.d.ts +2 -2
  286. package/types/i18n/zh-cn.d.ts +2 -2
  287. package/types/index.d.ts +11 -11
  288. package/types/lock/index.d.ts +64 -64
  289. package/types/log/config.d.ts +35 -35
  290. package/types/log/date.d.ts +2 -2
  291. package/types/log/file.d.ts +13 -13
  292. package/types/log/index.d.ts +53 -53
  293. package/types/log/level.d.ts +14 -14
  294. package/types/log/log.d.ts +40 -40
  295. package/types/log/store.d.ts +19 -19
  296. package/types/mongodb/collection.d.ts +25 -25
  297. package/types/mongodb/config.d.ts +45 -45
  298. package/types/mongodb/doc.d.ts +11 -11
  299. package/types/mongodb/exception.d.ts +7 -7
  300. package/types/mongodb/index.d.ts +29 -29
  301. package/types/mongodb/manager/base.d.ts +188 -188
  302. package/types/mongodb/manager/index.d.ts +38 -38
  303. package/types/mongodb/manager/tx-strict.d.ts +41 -41
  304. package/types/mongodb/manager/tx.d.ts +21 -21
  305. package/types/mongodb/migration.d.ts +12 -12
  306. package/types/mvc/access-log.d.ts +7 -7
  307. package/types/mvc/config.d.ts +42 -42
  308. package/types/mvc/exchange.d.ts +72 -72
  309. package/types/mvc/handler/index.d.ts +4 -3
  310. package/types/mvc/handler/json.d.ts +44 -44
  311. package/types/mvc/handler/restful.d.ts +11 -11
  312. package/types/mvc/handler/sse.d.ts +34 -0
  313. package/types/mvc/handler/upload.d.ts +36 -36
  314. package/types/mvc/index.d.ts +22 -22
  315. package/types/mvc/interceptor.d.ts +11 -11
  316. package/types/mvc/query.d.ts +13 -13
  317. package/types/mvc/render/file.d.ts +10 -10
  318. package/types/mvc/render/html/html.d.ts +98 -98
  319. package/types/mvc/render/html/index.d.ts +11 -11
  320. package/types/mvc/render/html/style.d.ts +1201 -1201
  321. package/types/mvc/render/index.d.ts +4 -4
  322. package/types/mvc/render/json.d.ts +17 -17
  323. package/types/mvc/render/text.d.ts +10 -10
  324. package/types/mvc/router.d.ts +11 -11
  325. package/types/mvc/server.d.ts +90 -90
  326. package/types/mvc/static/header.d.ts +27 -27
  327. package/types/mvc/static/index.d.ts +3 -3
  328. package/types/mvc/static/mime-type.d.ts +2 -2
  329. package/types/mvc/static/server-cache-config.d.ts +30 -30
  330. package/types/mvc/static/server-cache.d.ts +76 -76
  331. package/types/mvc/static/static-handler.d.ts +77 -77
  332. package/types/mysql/config.d.ts +90 -90
  333. package/types/mysql/exception.d.ts +7 -7
  334. package/types/mysql/index.d.ts +16 -16
  335. package/types/mysql/manager/base.d.ts +165 -165
  336. package/types/mysql/manager/index.d.ts +36 -36
  337. package/types/mysql/manager/ops/count.d.ts +13 -13
  338. package/types/mysql/manager/ops/criteria.d.ts +134 -134
  339. package/types/mysql/manager/ops/delete.d.ts +46 -46
  340. package/types/mysql/manager/ops/exist.d.ts +6 -6
  341. package/types/mysql/manager/ops/find.d.ts +86 -86
  342. package/types/mysql/manager/ops/index.d.ts +10 -10
  343. package/types/mysql/manager/ops/insert.d.ts +18 -18
  344. package/types/mysql/manager/ops/modify.d.ts +3 -3
  345. package/types/mysql/manager/ops/paginate.d.ts +36 -36
  346. package/types/mysql/manager/ops/query.d.ts +3 -3
  347. package/types/mysql/manager/ops/update.d.ts +76 -76
  348. package/types/mysql/manager/ops/utils.d.ts +5 -5
  349. package/types/mysql/manager/tx-strict.d.ts +36 -36
  350. package/types/mysql/manager/tx.d.ts +15 -15
  351. package/types/mysql/manager/utils.d.ts +17 -17
  352. package/types/mysql/migration.d.ts +8 -8
  353. package/types/mysql/table-info.d.ts +36 -36
  354. package/types/task/daily.d.ts +16 -16
  355. package/types/task/fixed-delay.d.ts +9 -9
  356. package/types/task/fixed-rate.d.ts +9 -9
  357. package/types/task/index.d.ts +4 -4
  358. package/types/task/task.d.ts +34 -34
  359. package/types/validation/exception.d.ts +38 -38
  360. package/types/validation/index.d.ts +32 -32
  361. package/types/validation/validator/array.d.ts +5 -5
  362. package/types/validation/validator/enum.d.ts +8 -8
  363. package/types/validation/validator/index.d.ts +11 -11
  364. package/types/validation/validator/length.d.ts +10 -10
  365. package/types/validation/validator/max-length.d.ts +8 -8
  366. package/types/validation/validator/max.d.ts +7 -7
  367. package/types/validation/validator/min-length.d.ts +6 -6
  368. package/types/validation/validator/min.d.ts +7 -7
  369. package/types/validation/validator/not-blank.d.ts +7 -7
  370. package/types/validation/validator/not-null.d.ts +6 -6
  371. package/types/validation/validator/plain-obj.d.ts +7 -7
  372. package/types/validation/validator/regexp.d.ts +8 -8
@@ -0,0 +1,18 @@
1
+ export interface LangTag {
2
+ lang: string
3
+ region?: string
4
+ }
5
+ /**
6
+ * 解析语言标签,语言标签格式非常多,这里仅支持语言加地区的形式,如 zh-CN。
7
+ * 更多信息可以查看 https://www.rfc-editor.org/rfc/bcp/bcp47.txt 。
8
+ * @param tag
9
+ * @returns 语言和地区信息,为了方便匹配,全转小写
10
+ */
11
+ export function parseLangTag(tag: string): LangTag {
12
+ const [lang, region] = tag.split('-')
13
+ // 解析失败,抛出错误
14
+ if (!lang) {
15
+ throw new Error(`Unable to parse lang tag:${tag}`)
16
+ }
17
+ return { lang: lang.toLowerCase(), region: region ? region.toLowerCase() : undefined }
18
+ }
@@ -0,0 +1,16 @@
1
+ import { I18nMsgs } from "./msg";
2
+
3
+ export const zhHK: I18nMsgs = {
4
+ 'validate-err-array': '值不是陣列',
5
+ 'validate-err-enum': '值必須是 {} 其中一個',
6
+ 'validate-err-numer': '值不是數字',
7
+ 'validate-err-max': '不得大於 {}',
8
+ 'validate-err-min': '不得小於 {}',
9
+ 'validate-err-empty': '不能為空',
10
+ 'validate-err-string': '值不是字串型別',
11
+ 'validate-err-incorrect-format': '格式不正確',
12
+ 'validate-err-no-length': '找不到 length 屬性',
13
+ 'validate-err-length-not-number': 'length 屬性不是數字',
14
+ 'validate-err-min-length': '長度不得小於 {}',
15
+ 'validate-err-max-length': '長度不得大於 {}'
16
+ }
@@ -0,0 +1,16 @@
1
+ import { I18nMsgs } from './msg'
2
+
3
+ export const zhTW: I18nMsgs = {
4
+ 'validate-err-array': '值不是陣列',
5
+ 'validate-err-enum': '值必須是 {} 其中一個',
6
+ 'validate-err-numer': '值不是數字',
7
+ 'validate-err-max': '不得大於 {}',
8
+ 'validate-err-min': '不得小於 {}',
9
+ 'validate-err-empty': '不能為空',
10
+ 'validate-err-string': '值不是字串型別',
11
+ 'validate-err-incorrect-format': '格式不正確',
12
+ 'validate-err-no-length': '找不到 length 屬性',
13
+ 'validate-err-length-not-number': 'length 屬性不是數字',
14
+ 'validate-err-min-length': '長度不得小於 {}',
15
+ 'validate-err-max-length': '長度不得大於 {}'
16
+ }
@@ -0,0 +1,16 @@
1
+ import { I18nMsgs } from './msg'
2
+
3
+ export const zhCN: I18nMsgs = {
4
+ 'validate-err-array': '值不是数组',
5
+ 'validate-err-enum': '值必须是 {} 其中一个',
6
+ 'validate-err-numer': '值不是数字',
7
+ 'validate-err-max': '不得大于 {}',
8
+ 'validate-err-min': '不得小于 {}',
9
+ 'validate-err-empty': '不能为空',
10
+ 'validate-err-string': '值不是字符串类型',
11
+ 'validate-err-incorrect-format': '格式不正确',
12
+ 'validate-err-no-length': '找不到 length 属性',
13
+ 'validate-err-length-not-number': 'length 属性不是数字',
14
+ 'validate-err-min-length': '长度不得小于 {}',
15
+ 'validate-err-max-length': '长度不得大于 {}'
16
+ }
package/src/index.ts ADDED
@@ -0,0 +1,11 @@
1
+ export * from './log'
2
+ export * from './i18n'
3
+ export * from './validation'
4
+ export * from './config'
5
+ export * from './cache'
6
+ export * from './task'
7
+ export * from './mvc'
8
+ export * from './mysql'
9
+ export * from './http-client'
10
+ export * from './mongodb'
11
+ export * from './lock'
@@ -0,0 +1,164 @@
1
+ import { randomUUID } from 'crypto'
2
+
3
+ export interface LockInfo {
4
+ /**
5
+ * 一个随机值,用于验证锁是否为当前程序所拥有
6
+ */
7
+ value: string
8
+ /**
9
+ * 锁过期的时间
10
+ */
11
+ expiresAt: number
12
+ }
13
+
14
+ /**
15
+ * 锁管理器,主要用于将不确定的顺序且有冲突的异步操作顺序执行,
16
+ * 防止异步流程庞大穿插执行造成的数据混乱和错误,常见于请求的处理。
17
+ */
18
+ class ServerLockManager {
19
+ /**
20
+ * 存储锁信息的表,值是一个随机值,用于验证锁是否为当前程序所拥有
21
+ */
22
+ private lockMap = new Map<string, LockInfo>()
23
+
24
+ constructor() {
25
+ // 定期清理,将过期的信息移除,防止内存泄漏
26
+ setTimeout(() => {
27
+ const keysToBeDeleted: string[] = []
28
+ const now = Date.now()
29
+ for (const entry of this.lockMap.entries()) {
30
+ const [key, info] = entry
31
+ if (info.expiresAt < now) {
32
+ keysToBeDeleted.push(key)
33
+ }
34
+ }
35
+ if (keysToBeDeleted.length) {
36
+ for (const key of keysToBeDeleted) {
37
+ this.lockMap.delete(key)
38
+ }
39
+ }
40
+ }, 10000)
41
+ }
42
+
43
+ /**
44
+ * 尝试竞争锁,如果成功获取到锁,则执行 run 函数
45
+ * @param opts
46
+ * @returns 是否获取到锁
47
+ */
48
+ async tryLock(opts: {
49
+ /**
50
+ * 竞争锁的标识,相同的 key 会处于竞争关系,从而按顺序执行
51
+ */
52
+ key: string
53
+ /**
54
+ * 等待秒数,如果没有获取锁,要等待的时间,单位秒。
55
+ * 不设置的情况下则不会等待,获取不到锁就立即返回。
56
+ */
57
+ waitSeconds?: number
58
+ /**
59
+ * 运行函数,成功获取锁就会执行
60
+ * @returns
61
+ */
62
+ run: () => Promise<void>
63
+ /**
64
+ * 过期时间,单位秒。目的是防止一个程序长期占用锁,导致其它程序获取不到锁一直不能被执行
65
+ * 导致的死锁问题。锁一旦过期,当前程序就不再拥有锁,其它程序就可以获取到锁。默认 60 秒。
66
+ */
67
+ expiresInSeconds?: number
68
+ }): Promise<boolean> {
69
+ const value = randomUUID().toString()
70
+ const expiresInSeconds =
71
+ typeof opts.expiresInSeconds === 'number' && opts.expiresInSeconds > 0
72
+ ? opts.expiresInSeconds
73
+ : 60
74
+ const expiresAt = Date.now() + expiresInSeconds * 1000
75
+ const waitSeconds =
76
+ typeof opts.waitSeconds === 'number' && opts.waitSeconds > 0 ? opts.waitSeconds : 0
77
+ const res = await this.waitLock({
78
+ key: opts.key,
79
+ value,
80
+ expiresAt,
81
+ waitSeconds
82
+ })
83
+ if (!res) {
84
+ return false
85
+ }
86
+ try {
87
+ await opts.run()
88
+ } finally {
89
+ // 解锁
90
+ const info = this.lockMap.get(opts.key)
91
+ if (info && info.value === value) {
92
+ this.lockMap.delete(opts.key)
93
+ }
94
+ }
95
+ return true
96
+ }
97
+ /**
98
+ * 等待锁
99
+ * @param opts
100
+ */
101
+ private async waitLock(opts: {
102
+ /**
103
+ * 竞争锁的标识,相同的 key 会处于竞争关系,从而按顺序执行
104
+ */
105
+ key: string
106
+ /**
107
+ * 值
108
+ */
109
+ value: string
110
+ /**
111
+ * 等待秒数,如果没有获取锁,要等待的时间,单位秒。
112
+ */
113
+ waitSeconds: number
114
+ /**
115
+ * 过期时间
116
+ */
117
+ expiresAt: number
118
+ }): Promise<boolean> {
119
+ let start = Date.now()
120
+ while (true) {
121
+ const info = this.lockMap.get(opts.key)
122
+ // 锁不存在或已经过期
123
+ if (!info || info.expiresAt < Date.now()) {
124
+ // 成功获取到锁
125
+ this.lockMap.set(opts.key, {
126
+ value: opts.value,
127
+ expiresAt: opts.expiresAt
128
+ })
129
+ return true
130
+ }
131
+ if (info.value === opts.value) {
132
+ return true
133
+ }
134
+ if (Date.now() - start > opts.waitSeconds * 1000) {
135
+ break
136
+ }
137
+ await this.sleep()
138
+ }
139
+ return false
140
+ }
141
+ /**
142
+ * 沉睡
143
+ * @returns
144
+ */
145
+ private sleep() {
146
+ return new Promise<void>((resolve, reject) => {
147
+ setTimeout(resolve, 0)
148
+ })
149
+ }
150
+ }
151
+
152
+ let lockManager: ServerLockManager | undefined
153
+
154
+ /**
155
+ * 获取锁管理器。锁管理器提供一个简单的异步并发控制,用于将不确定的顺序的有冲突的异步操作顺序执行,
156
+ * 防止异步流程庞大穿插执行造成的数据混乱和错误,常见于请求的处理。
157
+ * @returns
158
+ */
159
+ export function getLockManager(): ServerLockManager {
160
+ if (!lockManager) {
161
+ lockManager = new ServerLockManager()
162
+ }
163
+ return lockManager
164
+ }
@@ -0,0 +1,71 @@
1
+ import { isAbsolute, resolve } from 'path'
2
+ import { registerConfig } from '../config'
3
+ import { min, notBlank, notNull } from '../validation'
4
+ import { LogLevel, parseLogLevel } from './level'
5
+
6
+ /**
7
+ * 日志配置的定义
8
+ */
9
+ interface EnvConfig {
10
+ /**
11
+ * 是否输出日志到控制台
12
+ */
13
+ console: boolean
14
+ /**
15
+ * 输出日志的格式
16
+ */
17
+ format: 'text' | 'json'
18
+ /**
19
+ * 是否输出到文件,如果为 true ,则会在根目录下生成 logs 目录存放日志文件.
20
+ */
21
+ file: boolean
22
+ /**
23
+ * 文件目录
24
+ */
25
+ fileDir: string
26
+ /**
27
+ * 文件最大保存天数.需要开启文件才有效.
28
+ */
29
+ fileMaxDays: number
30
+ /**
31
+ * 要输出的日志级别.
32
+ */
33
+ level: string
34
+ }
35
+
36
+ const envConfig = registerConfig<EnvConfig>(
37
+ {
38
+ console: true,
39
+ format: 'text',
40
+ file: false,
41
+ fileDir: 'logs',
42
+ fileMaxDays: 30,
43
+ level: 'INFO'
44
+ },
45
+ 'LOG',
46
+ {
47
+ console: [notNull()],
48
+ format: [notNull()],
49
+ file: [notNull()],
50
+ fileDir: [notBlank()],
51
+ fileMaxDays: [min(1)],
52
+ level: [notBlank()]
53
+ }
54
+ )
55
+
56
+ export type LogConfig = Omit<EnvConfig, 'level'> & { level: LogLevel }
57
+
58
+ let { fileDir, level } = envConfig
59
+ // 目录处理
60
+ if (!isAbsolute(fileDir)) {
61
+ fileDir = resolve(process.cwd(), fileDir)
62
+ }
63
+
64
+ export const config: LogConfig = Object.freeze({
65
+ file: envConfig.file,
66
+ fileDir,
67
+ fileMaxDays: envConfig.fileMaxDays,
68
+ level: parseLogLevel(level),
69
+ console: envConfig.console,
70
+ format: envConfig.format
71
+ })
@@ -0,0 +1,19 @@
1
+ export function currentDateTimeStr() {
2
+ return formatDateTime(new Date())
3
+ }
4
+
5
+ export function formatDateTime(date: Date) {
6
+ return (
7
+ date.toLocaleString('zh-CN', {
8
+ timeZone: 'Asia/Shanghai',
9
+ year: 'numeric',
10
+ month: '2-digit',
11
+ day: '2-digit',
12
+ hour: '2-digit',
13
+ minute: '2-digit',
14
+ second: '2-digit',
15
+ hour12: false,
16
+ hourCycle: 'h23'
17
+ }) + `.${date.getMilliseconds()}`
18
+ )
19
+ }
@@ -0,0 +1,215 @@
1
+ import { existsSync, statSync } from 'fs'
2
+ import { readdir, rm, appendFile, mkdir } from 'fs/promises'
3
+ import { EOL } from 'os'
4
+ import { dirname, resolve, isAbsolute } from 'path'
5
+ import { config, LogConfig } from './config'
6
+ import { formatLogJson, formatLogText, Log } from './log'
7
+
8
+ // 日志队列
9
+ let LOG_QUEUE: Log[] = []
10
+ // 最大缓冲数量
11
+ const MAX_QUEUE_SIZE = 1024
12
+ // 写入定时器
13
+ let WRITE_TIMER: NodeJS.Timeout | null = null
14
+ // 延迟写入时间(毫秒)
15
+ const WRITE_DELAY = 100
16
+ // 是否已经安排了清理任务
17
+ let CLEANUP_SCHEDULED = false
18
+ // 清理任务定时器
19
+ let CLEANUP_TIMER: NodeJS.Timeout | null = null
20
+
21
+ /**
22
+ * 文件存储.
23
+ * @param log 日志对象
24
+ * @param logConfig 日志配置
25
+ */
26
+ export function fileStore(log: Log, logConfig: LogConfig): void {
27
+ // 将日志添加到队列
28
+ LOG_QUEUE.push(log)
29
+
30
+ // 如果队列超过最大缓冲数量,立即写入
31
+ if (LOG_QUEUE.length >= MAX_QUEUE_SIZE) {
32
+ writeLogs(logConfig).catch(e => console.error('Writing log file failed', e))
33
+
34
+ // 在写入前检查是否需要安排清理任务
35
+ if (!CLEANUP_SCHEDULED) {
36
+ scheduleCleanupTask(logConfig)
37
+ }
38
+ return
39
+ }
40
+
41
+ // 安排延迟写入
42
+ if (!WRITE_TIMER) {
43
+ WRITE_TIMER = setTimeout(() => {
44
+ WRITE_TIMER = null
45
+ writeLogs(logConfig).catch(e => console.error('Writing log file failed', e))
46
+ }, WRITE_DELAY)
47
+ }
48
+
49
+ // 如果启用了文件存储并且还没有安排清理任务,则安排清理任务
50
+ if (!CLEANUP_SCHEDULED) {
51
+ scheduleCleanupTask(logConfig)
52
+ }
53
+ }
54
+
55
+ /**
56
+ * 根据日期构建日志文件路径
57
+ * @param logConfig 日志配置
58
+ * @param dateKey 数字键 (格式:年*10000 + 月*100 + 日)
59
+ * @returns 日志文件路径
60
+ */
61
+ function buildFilePathByDate(logConfig: LogConfig, dateKey: number): string {
62
+ const fileName = `${dateKey}.log`
63
+ // 确保目录是绝对路径
64
+ let fileDir = logConfig.fileDir
65
+ if (!isAbsolute(fileDir)) {
66
+ fileDir = resolve(process.cwd(), fileDir)
67
+ }
68
+ return resolve(fileDir, fileName)
69
+ }
70
+
71
+ /**
72
+ * 根据日期对象计算数字键
73
+ * @param date 日期对象
74
+ * @returns 数字键 (格式:年*10000 + 月*100 + 日)
75
+ */
76
+ function calculateDateKey(date: Date): number {
77
+ const year = date.getFullYear()
78
+ const month = date.getMonth() + 1 // 转换为1-12
79
+ const day = date.getDate()
80
+ return year * 10000 + month * 100 + day
81
+ }
82
+
83
+ /**
84
+ * 写入日志到文件
85
+ * @param logConfig 日志配置
86
+ */
87
+ async function writeLogs(logConfig: LogConfig): Promise<void> {
88
+ if (!LOG_QUEUE.length || !logConfig.file) {
89
+ return
90
+ }
91
+
92
+ // 复制队列并清空原始队列
93
+ const logsToWrite = [...LOG_QUEUE]
94
+ LOG_QUEUE = []
95
+
96
+ // 按日期对日志进行分组 - 使用数字键提升性能
97
+ const logsByDate = new Map<number, Log[]>()
98
+
99
+ logsToWrite.forEach(log => {
100
+ const logDate = new Date(log.time)
101
+ // 直接使用日期对象计算数字键
102
+ const dateKey = calculateDateKey(logDate)
103
+ const dateLogs = logsByDate.get(dateKey)
104
+ if (dateLogs) {
105
+ dateLogs.push(log)
106
+ } else {
107
+ logsByDate.set(dateKey, [log])
108
+ }
109
+ })
110
+
111
+ // 为每个日期组写入对应的日志文件
112
+ for (const [dateKey, dateLogs] of logsByDate.entries()) {
113
+ // 直接使用数字键构建文件路径
114
+ const filePath = buildFilePathByDate(logConfig, dateKey)
115
+ const dir = dirname(filePath)
116
+
117
+ // 确保目录存在
118
+ if (!existsSync(dir)) {
119
+ await mkdir(dir, { recursive: true })
120
+ }
121
+
122
+ // 格式化并写入该日期的所有日志
123
+ const lines = dateLogs
124
+ .map(log => (logConfig.format === 'json' ? formatLogJson(log) : formatLogText(log)))
125
+ .join(EOL)
126
+
127
+ try {
128
+ await appendFile(filePath, lines)
129
+ } catch (error) {
130
+ console.error(`Failed to write logs for date ${dateKey}:`, error)
131
+ // 继续处理下一个日期的日志,不中断整个写入过程
132
+ }
133
+ }
134
+ }
135
+
136
+ /**
137
+ * 执行日志清理任务
138
+ * @param logConfig 日志配置
139
+ */
140
+ async function performCleanupTask(logConfig: LogConfig): Promise<void> {
141
+ try {
142
+ let dir = logConfig.fileDir
143
+ if (!isAbsolute(dir)) {
144
+ dir = resolve(process.cwd(), dir)
145
+ }
146
+
147
+ // 确保目录存在
148
+ if (!existsSync(dir)) {
149
+ return
150
+ }
151
+
152
+ const files = await readdir(dir)
153
+ const now = new Date().getTime()
154
+ const maxAge = logConfig.fileMaxDays * 24 * 3600 * 1000
155
+
156
+ for (const file of files) {
157
+ try {
158
+ // 获取文件的完整路径
159
+ const filePath = resolve(dir, file)
160
+
161
+ // 获取文件的最后修改时间
162
+ const fileStats = statSync(filePath)
163
+ const lastModifiedTime = fileStats.mtime.getTime()
164
+
165
+ // 检查文件是否过期(最后修改时间早于最大保留天数)
166
+ if (lastModifiedTime + maxAge < now) {
167
+ console.warn(`Remove log file: ${file}`)
168
+ await rm(filePath)
169
+ }
170
+ } catch (error) {
171
+ console.error(`Failed to process log file ${file}:`, error)
172
+ // 继续处理下一个文件,不中断清理过程
173
+ continue
174
+ }
175
+ }
176
+ } catch (error) {
177
+ console.error('Error during log cleanup:', error)
178
+ } finally {
179
+ // 清理完成后,重置清理任务安排状态
180
+ CLEANUP_SCHEDULED = false
181
+ }
182
+ }
183
+
184
+ /**
185
+ * 安排日志清理任务
186
+ * @param logConfig 日志配置
187
+ */
188
+ function scheduleCleanupTask(logConfig: LogConfig): void {
189
+ CLEANUP_SCHEDULED = true
190
+
191
+ // 清除现有的清理定时器
192
+ if (CLEANUP_TIMER) {
193
+ clearTimeout(CLEANUP_TIMER)
194
+ }
195
+
196
+ // 设置清理任务在一天后执行
197
+ const delay = 24 * 60 * 60 * 1000
198
+ CLEANUP_TIMER = setTimeout(() => {
199
+ CLEANUP_TIMER = null
200
+ performCleanupTask(logConfig).catch(e => console.error('Cleanup task failed', e))
201
+ }, delay)
202
+ }
203
+
204
+ /**
205
+ * 确保所有日志都被写入文件
206
+ * 可以在应用程序关闭时调用
207
+ */
208
+ export async function flushLogsToFile(): Promise<void> {
209
+ if (WRITE_TIMER) {
210
+ clearTimeout(WRITE_TIMER)
211
+ WRITE_TIMER = null
212
+ }
213
+
214
+ await writeLogs(config)
215
+ }
@@ -0,0 +1,136 @@
1
+ import { config } from './config'
2
+ import { fileStore } from './file'
3
+ import { LogLevel } from './level'
4
+ import { formatLogJson, formatLogText, Log } from './log'
5
+ import { getLogStore, setLogStore } from './store'
6
+
7
+ /**
8
+ * 文件存储
9
+ */
10
+ if (config.file) {
11
+ setLogStore(fileStore)
12
+ }
13
+
14
+ class Logger {
15
+ constructor(private prefix?: string) {}
16
+
17
+ /**
18
+ * 输出日志
19
+ * @param level
20
+ * @param message
21
+ * @param error
22
+ */
23
+ private log(level: LogLevel, message: string, error?: any) {
24
+ if (level < config.level) {
25
+ return
26
+ }
27
+ const log: Log = {
28
+ level,
29
+ content: message,
30
+ time: new Date(),
31
+ prefix: this.prefix,
32
+ error
33
+ }
34
+ // 控制台输出日志
35
+ if (config.console) {
36
+ // const msg = config.format === 'text' ? formatLogText(log, true) : formatLogJson(log, true)
37
+ // 控制台强制使用 text 格式,json 格式只在文件中输出
38
+ const msg = formatLogText(log, true)
39
+ switch (level) {
40
+ case LogLevel.DEBUG:
41
+ console.debug(msg)
42
+ break
43
+ case LogLevel.INFO:
44
+ console.info(msg)
45
+ break
46
+ case LogLevel.WARN:
47
+ console.warn(msg)
48
+ break
49
+ case LogLevel.ERROR:
50
+ console.error(msg)
51
+ break
52
+ }
53
+ if (error) {
54
+ console.error(error)
55
+ }
56
+ }
57
+ // 自定义存储中输出日志
58
+ const store = getLogStore()
59
+ if (store) {
60
+ store(log, config)
61
+ }
62
+ }
63
+ /**
64
+ * debug 日志
65
+ */
66
+ debug(message: string) {
67
+ this.log(LogLevel.DEBUG, message)
68
+ }
69
+
70
+ isDebugEnabled() {
71
+ return LogLevel.DEBUG >= config.level
72
+ }
73
+ /**
74
+ * info 日志
75
+ * @param message
76
+ */
77
+ info(message: string) {
78
+ this.log(LogLevel.INFO, message)
79
+ }
80
+
81
+ isInfoEnabled() {
82
+ return LogLevel.INFO >= config.level
83
+ }
84
+ /**
85
+ * 警告日志
86
+ * @param message
87
+ * @param error
88
+ */
89
+ warn(message: string, error?: any) {
90
+ this.log(LogLevel.WARN, message, error)
91
+ }
92
+ /**
93
+ * 等同于 warn
94
+ * @param message
95
+ * @param error
96
+ */
97
+ warning(message: string, error?: any) {
98
+ this.log(LogLevel.WARN, message, error)
99
+ }
100
+
101
+ isWarnEnabled() {
102
+ return LogLevel.WARN >= config.level
103
+ }
104
+ /**
105
+ * 错误日志
106
+ * @param message
107
+ * @param error
108
+ */
109
+ error(message: string, error?: any) {
110
+ this.log(LogLevel.ERROR, message, error)
111
+ }
112
+
113
+ isErrorEnabled() {
114
+ return LogLevel.ERROR >= config.level
115
+ }
116
+ }
117
+
118
+ const defaultLogger = new Logger()
119
+
120
+ /**
121
+ * 获取日志对象.
122
+ *
123
+ * @param prefix 日志前缀,如果有值,每条日志前都会加上前缀信息
124
+ * @returns
125
+ */
126
+ export function getLogger(prefix?: string) {
127
+ if (prefix) {
128
+ return new Logger(prefix)
129
+ }
130
+ return defaultLogger
131
+ }
132
+
133
+ export * from './config'
134
+ export * from './level'
135
+ export * from './log'
136
+ export { setLogStore } from './store'