wok-server 0.5.0 → 0.7.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 (380) 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 +278 -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 +381 -356
  80. package/dist/mysql/manager/ops/delete.js +59 -65
  81. package/dist/mysql/manager/ops/exist.js +26 -26
  82. package/dist/mysql/manager/ops/find.js +149 -169
  83. package/dist/mysql/manager/ops/index.js +16 -14
  84. package/dist/mysql/manager/ops/insert.js +132 -106
  85. package/dist/mysql/manager/ops/modify.js +10 -10
  86. package/dist/mysql/manager/ops/order-by.js +28 -0
  87. package/dist/mysql/manager/ops/paginate.js +48 -23
  88. package/dist/mysql/manager/ops/query.js +9 -9
  89. package/dist/mysql/manager/ops/update.js +222 -216
  90. package/dist/mysql/manager/ops/upsert.js +178 -0
  91. package/dist/mysql/manager/ops/utils.js +28 -24
  92. package/dist/mysql/manager/tx-strict.js +103 -103
  93. package/dist/mysql/manager/tx.js +30 -30
  94. package/dist/mysql/manager/utils.js +56 -56
  95. package/dist/mysql/migration.js +136 -136
  96. package/dist/mysql/table-info.js +8 -8
  97. package/dist/task/daily.js +59 -59
  98. package/dist/task/fixed-delay.js +38 -38
  99. package/dist/task/fixed-rate.js +42 -42
  100. package/dist/task/index.js +9 -9
  101. package/dist/task/task.js +56 -56
  102. package/dist/validation/exception.js +36 -36
  103. package/dist/validation/index.js +40 -40
  104. package/dist/validation/validator/array.js +34 -34
  105. package/dist/validation/validator/enum.js +28 -28
  106. package/dist/validation/validator/index.js +14 -14
  107. package/dist/validation/validator/length.js +40 -40
  108. package/dist/validation/validator/max-length.js +35 -35
  109. package/dist/validation/validator/max.js +29 -29
  110. package/dist/validation/validator/min-length.js +33 -33
  111. package/dist/validation/validator/min.js +29 -29
  112. package/dist/validation/validator/not-blank.js +33 -33
  113. package/dist/validation/validator/not-null.js +21 -21
  114. package/dist/validation/validator/plain-obj.js +32 -32
  115. package/dist/validation/validator/regexp.js +34 -34
  116. package/documentation/en/cache.md +56 -0
  117. package/documentation/en/config.md +96 -0
  118. package/documentation/en/engineering.md +256 -0
  119. package/documentation/en/http-client.md +32 -0
  120. package/documentation/en/i18n.md +143 -0
  121. package/documentation/en/index.md +24 -0
  122. package/documentation/en/lock.md +51 -0
  123. package/documentation/en/log.md +109 -0
  124. package/documentation/en/mongodb.md +256 -0
  125. package/documentation/en/mvc.md +688 -0
  126. package/documentation/en/mysql.md +682 -0
  127. package/documentation/en/task.md +45 -0
  128. package/documentation/en/test.md +56 -0
  129. package/documentation/en/validate.md +130 -0
  130. package/documentation/zh-cn/mvc.md +66 -24
  131. package/documentation/zh-cn/mysql.md +146 -17
  132. package/package.json +4 -1
  133. package/skills/wok-server-api-rules/SKILL.md +350 -0
  134. package/skills/wok-server-cache/SKILL.md +216 -0
  135. package/skills/wok-server-code-navigation/SKILL.md +153 -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 +388 -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 +332 -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 +446 -0
  232. package/src/mysql/manager/ops/delete.ts +91 -0
  233. package/src/mysql/manager/ops/exist.ts +41 -0
  234. package/src/mysql/manager/ops/find.ts +209 -0
  235. package/src/mysql/manager/ops/index.ts +13 -0
  236. package/src/mysql/manager/ops/insert.ts +158 -0
  237. package/src/mysql/manager/ops/modify.ts +14 -0
  238. package/src/mysql/manager/ops/order-by.ts +58 -0
  239. package/src/mysql/manager/ops/paginate.ts +100 -0
  240. package/src/mysql/manager/ops/query.ts +13 -0
  241. package/src/mysql/manager/ops/update.ts +318 -0
  242. package/src/mysql/manager/ops/upsert.ts +224 -0
  243. package/src/mysql/manager/ops/utils.ts +24 -0
  244. package/src/mysql/manager/tx-strict.ts +138 -0
  245. package/src/mysql/manager/tx.ts +31 -0
  246. package/src/mysql/manager/utils.ts +75 -0
  247. package/src/mysql/migration.ts +149 -0
  248. package/src/mysql/table-info.ts +41 -0
  249. package/src/task/daily.ts +70 -0
  250. package/src/task/fixed-delay.ts +45 -0
  251. package/src/task/fixed-rate.ts +49 -0
  252. package/src/task/index.ts +4 -0
  253. package/src/task/task.ts +70 -0
  254. package/src/validation/exception.ts +27 -0
  255. package/src/validation/index.ts +61 -0
  256. package/src/validation/validator/array.ts +32 -0
  257. package/src/validation/validator/enum.ts +25 -0
  258. package/src/validation/validator/index.ts +11 -0
  259. package/src/validation/validator/length.ts +42 -0
  260. package/src/validation/validator/max-length.ts +33 -0
  261. package/src/validation/validator/max.ts +26 -0
  262. package/src/validation/validator/min-length.ts +31 -0
  263. package/src/validation/validator/min.ts +26 -0
  264. package/src/validation/validator/not-blank.ts +31 -0
  265. package/src/validation/validator/not-null.ts +19 -0
  266. package/src/validation/validator/plain-obj.ts +30 -0
  267. package/src/validation/validator/regexp.ts +32 -0
  268. package/types/cache/cache.d.ts +52 -52
  269. package/types/cache/config.d.ts +32 -32
  270. package/types/cache/index.d.ts +2 -2
  271. package/types/cache/purge-task.d.ts +11 -11
  272. package/types/cache/stat.d.ts +26 -26
  273. package/types/config/convert.d.ts +6 -6
  274. package/types/config/exception.d.ts +7 -7
  275. package/types/config/index.d.ts +25 -25
  276. package/types/http-client/index.d.ts +71 -71
  277. package/types/i18n/ar.d.ts +2 -2
  278. package/types/i18n/de.d.ts +2 -2
  279. package/types/i18n/en-us.d.ts +2 -2
  280. package/types/i18n/es.d.ts +2 -2
  281. package/types/i18n/fr.d.ts +2 -2
  282. package/types/i18n/i18n.d.ts +102 -102
  283. package/types/i18n/index.d.ts +9 -9
  284. package/types/i18n/ja.d.ts +2 -2
  285. package/types/i18n/ko.d.ts +2 -2
  286. package/types/i18n/msg.d.ts +50 -50
  287. package/types/i18n/pt.d.ts +2 -2
  288. package/types/i18n/ru.d.ts +2 -2
  289. package/types/i18n/tag.d.ts +11 -11
  290. package/types/i18n/zh-HK.d.ts +2 -2
  291. package/types/i18n/zh-TW.d.ts +2 -2
  292. package/types/i18n/zh-cn.d.ts +2 -2
  293. package/types/index.d.ts +11 -11
  294. package/types/lock/index.d.ts +64 -64
  295. package/types/log/config.d.ts +35 -35
  296. package/types/log/date.d.ts +2 -2
  297. package/types/log/file.d.ts +13 -13
  298. package/types/log/index.d.ts +53 -53
  299. package/types/log/level.d.ts +14 -14
  300. package/types/log/log.d.ts +40 -40
  301. package/types/log/store.d.ts +19 -19
  302. package/types/mongodb/collection.d.ts +25 -25
  303. package/types/mongodb/config.d.ts +45 -45
  304. package/types/mongodb/doc.d.ts +11 -11
  305. package/types/mongodb/exception.d.ts +7 -7
  306. package/types/mongodb/index.d.ts +29 -29
  307. package/types/mongodb/manager/base.d.ts +188 -188
  308. package/types/mongodb/manager/index.d.ts +38 -38
  309. package/types/mongodb/manager/tx-strict.d.ts +41 -41
  310. package/types/mongodb/manager/tx.d.ts +21 -21
  311. package/types/mongodb/migration.d.ts +12 -12
  312. package/types/mvc/access-log.d.ts +7 -7
  313. package/types/mvc/config.d.ts +42 -42
  314. package/types/mvc/exchange.d.ts +72 -72
  315. package/types/mvc/handler/index.d.ts +4 -3
  316. package/types/mvc/handler/json.d.ts +44 -44
  317. package/types/mvc/handler/restful.d.ts +11 -11
  318. package/types/mvc/handler/sse.d.ts +34 -0
  319. package/types/mvc/handler/upload.d.ts +36 -36
  320. package/types/mvc/index.d.ts +22 -22
  321. package/types/mvc/interceptor.d.ts +11 -11
  322. package/types/mvc/query.d.ts +13 -13
  323. package/types/mvc/render/file.d.ts +10 -10
  324. package/types/mvc/render/html/html.d.ts +98 -98
  325. package/types/mvc/render/html/index.d.ts +11 -11
  326. package/types/mvc/render/html/style.d.ts +1201 -1201
  327. package/types/mvc/render/index.d.ts +4 -4
  328. package/types/mvc/render/json.d.ts +17 -17
  329. package/types/mvc/render/text.d.ts +10 -10
  330. package/types/mvc/router.d.ts +11 -11
  331. package/types/mvc/server.d.ts +90 -90
  332. package/types/mvc/static/header.d.ts +27 -27
  333. package/types/mvc/static/index.d.ts +3 -3
  334. package/types/mvc/static/mime-type.d.ts +2 -2
  335. package/types/mvc/static/server-cache-config.d.ts +30 -30
  336. package/types/mvc/static/server-cache.d.ts +76 -76
  337. package/types/mvc/static/static-handler.d.ts +77 -77
  338. package/types/mysql/config.d.ts +90 -90
  339. package/types/mysql/exception.d.ts +7 -7
  340. package/types/mysql/index.d.ts +16 -16
  341. package/types/mysql/manager/base.d.ts +196 -165
  342. package/types/mysql/manager/index.d.ts +36 -36
  343. package/types/mysql/manager/ops/count.d.ts +13 -13
  344. package/types/mysql/manager/ops/criteria.d.ts +144 -134
  345. package/types/mysql/manager/ops/delete.d.ts +47 -46
  346. package/types/mysql/manager/ops/exist.d.ts +6 -6
  347. package/types/mysql/manager/ops/find.d.ts +87 -86
  348. package/types/mysql/manager/ops/index.d.ts +12 -10
  349. package/types/mysql/manager/ops/insert.d.ts +32 -18
  350. package/types/mysql/manager/ops/modify.d.ts +3 -3
  351. package/types/mysql/manager/ops/order-by.d.ts +38 -0
  352. package/types/mysql/manager/ops/paginate.d.ts +53 -36
  353. package/types/mysql/manager/ops/query.d.ts +3 -3
  354. package/types/mysql/manager/ops/update.d.ts +99 -76
  355. package/types/mysql/manager/ops/upsert.d.ts +36 -0
  356. package/types/mysql/manager/ops/utils.d.ts +5 -5
  357. package/types/mysql/manager/tx-strict.d.ts +36 -36
  358. package/types/mysql/manager/tx.d.ts +15 -15
  359. package/types/mysql/manager/utils.d.ts +17 -17
  360. package/types/mysql/migration.d.ts +8 -8
  361. package/types/mysql/table-info.d.ts +36 -36
  362. package/types/task/daily.d.ts +16 -16
  363. package/types/task/fixed-delay.d.ts +9 -9
  364. package/types/task/fixed-rate.d.ts +9 -9
  365. package/types/task/index.d.ts +4 -4
  366. package/types/task/task.d.ts +34 -34
  367. package/types/validation/exception.d.ts +38 -38
  368. package/types/validation/index.d.ts +32 -32
  369. package/types/validation/validator/array.d.ts +5 -5
  370. package/types/validation/validator/enum.d.ts +8 -8
  371. package/types/validation/validator/index.d.ts +11 -11
  372. package/types/validation/validator/length.d.ts +10 -10
  373. package/types/validation/validator/max-length.d.ts +8 -8
  374. package/types/validation/validator/max.d.ts +7 -7
  375. package/types/validation/validator/min-length.d.ts +6 -6
  376. package/types/validation/validator/min.d.ts +7 -7
  377. package/types/validation/validator/not-blank.d.ts +7 -7
  378. package/types/validation/validator/not-null.d.ts +6 -6
  379. package/types/validation/validator/plain-obj.d.ts +7 -7
  380. package/types/validation/validator/regexp.d.ts +8 -8
@@ -0,0 +1,45 @@
1
+ # Task Scheduling
2
+
3
+ Task scheduling provides functionality to initiate periodic tasks, meeting basic needs.
4
+
5
+ ## Environment Variables
6
+
7
+ | Function Name | Description |
8
+ | :----------------------- | :-------------------------------------------------------------------------- |
9
+ | scheduleWithFixedRate | Execute task at fixed rate |
10
+ | scheduleWithFixedDelay | Execute task with fixed delay, i.e., wait for specified interval after each task completion |
11
+ | scheduleDailyTask | Execute task at fixed time daily |
12
+
13
+ ## Usage Examples
14
+
15
+ ```ts
16
+ // Start a fixed delay task, first execution after 10 seconds, then every minute
17
+ const controller = scheduleWithFixedDelay(10, 60, {
18
+ name: 'Record online users',
19
+ async run() {
20
+ const count = await countAuth()
21
+ await createPcu({
22
+ count,
23
+ time: new Date()
24
+ })
25
+ }
26
+ })
27
+ // Stop the task when necessary through the returned controller
28
+ controller.stop()
29
+ ```
30
+
31
+ The scheduleWithFixedRate function has the same parameters as scheduleWithFixedDelay. The difference is that scheduleWithFixedRate uses the task start time as the cycle, and the interval between each task's start time is consistent. If the task execution time exceeds the cycle, the next task will execute immediately. scheduleWithFixedDelay waits for the specified interval after each task completes before executing the next one.
32
+
33
+ ```ts
34
+ // Start a task that runs daily at 1:30
35
+ const controller = scheduleDailyTask(1, 30, {
36
+ name: 'Study report',
37
+ async run() {
38
+ // Logic omitted
39
+ }
40
+ })
41
+ ```
42
+
43
+ ## Difference from Built-in Timers
44
+
45
+ If requirements are not high, you can also use Node.js's built-in setTimeout and setInterval for periodic tasks. The task component is more convenient to use, with commonly used functions already encapsulated, and the run method is an async function. It automatically records task start time and exception information, and logs execution time for long-running tasks.
@@ -0,0 +1,56 @@
1
+ # Unit Testing
2
+
3
+ To run the project's unit tests, you need to start the database services first, then run the tests.
4
+
5
+ ## Start Database Services
6
+
7
+ The project source code provides scripts to start local database services for testing. The services need to run in Docker, so you must install docker-desktop locally first. Docker installation is not covered here; you can visit the official website for documentation.
8
+
9
+ First, start the MySQL service. This is simple - run docker-mysql.bat or docker-mysql.sh in the script directory.
10
+
11
+ ```
12
+ ./script/docker-mysql.sh
13
+ ```
14
+
15
+ Then start the MongoDB service for testing. Run docker-mongo.bat or docker-mongo.sh in the script directory.
16
+
17
+ ```
18
+ ./script/docker-mongo.sh
19
+ ```
20
+
21
+ Starting MongoDB alone is not sufficient. The service must be configured as a replica set to support transactions.
22
+
23
+ Run mongosh in the MongoDB container:
24
+
25
+ ```
26
+ docker exec -it mongo_test mongosh
27
+ ```
28
+
29
+ In mongosh, execute the following script to initialize as a replica set:
30
+
31
+ ```js
32
+ rs.initiate({
33
+ _id: 'rs0',
34
+ members: [{ _id: 0, host: '127.0.0.1:27017' }]
35
+ })
36
+ ```
37
+
38
+ Create a test user:
39
+
40
+ ```js
41
+ db.createUser({
42
+ user: 'test',
43
+ pwd: 'abc123',
44
+ roles: [{ role: 'readWrite', db: 'test' }]
45
+ })
46
+ ```
47
+
48
+ After completing the above steps, the MongoDB service is ready for testing.
49
+
50
+ ## Run Tests
51
+
52
+ Run the following script in the project root directory:
53
+
54
+ ```
55
+ npm run test
56
+ ```
@@ -0,0 +1,130 @@
1
+ # Validation
2
+
3
+ The validation component provides a validate function to validate objects with many built-in validation rules. The component supports internationalization, and error messages depend on the current language. See the internationalization section for details.
4
+
5
+ Here is a simple usage example:
6
+
7
+ ```ts
8
+ validate(
9
+ // Object to validate
10
+ { name: 'tom' },
11
+ // Validation rules, multiple rules per property
12
+ {
13
+ name: [notNull(), length({ min: 2, max: 16 })]
14
+ }
15
+ )
16
+ ```
17
+
18
+ Built-in validation rule functions:
19
+
20
+ | Function | Description |
21
+ | :------------ | :----------------------------------------------------------------------- |
22
+ | notNull | Not null validation, cannot be null or undefined |
23
+ | notBlank | Not blank validation, cannot be null, undefined, or blank string |
24
+ | min | Validate minimum number value |
25
+ | max | Validate maximum number value |
26
+ | length | Validate length, applicable to strings and arrays |
27
+ | maxLength | Check maximum length, applicable to strings and arrays |
28
+ | minLength | Check minimum length, applicable to strings and arrays |
29
+ | regexp | Regular expression validation |
30
+ | enumerate | Enumeration validation, value must be one of the specified list |
31
+ | array | Array validation, set element validation rules to validate each element |
32
+ | plainObject | Object validation, validate nested object properties |
33
+
34
+ Here is an example of nested object and array validation:
35
+
36
+ ```ts
37
+ interface Tag {
38
+ id: string
39
+ name: string
40
+ permissinos: { edit?: boolean; read?: boolean }
41
+ }
42
+ interface User {
43
+ profile: {
44
+ theme: string
45
+ }
46
+ tags: Tag[]
47
+ }
48
+ validate<User>(
49
+ {
50
+ profile: {
51
+ theme: 'light'
52
+ },
53
+ tags: [
54
+ { id: '001', name: 'basketball', permissinos: { edit: true, read: true } },
55
+ { id: '002', name: 'soccer', permissinos: { edit: true } }
56
+ ]
57
+ },
58
+ {
59
+ profile: [
60
+ notNull(),
61
+ plainObject({
62
+ theme: [notBlank()]
63
+ })
64
+ ],
65
+ tags: [
66
+ // Maximum 5 tags
67
+ maxLength(5),
68
+ // Tags list cannot be null
69
+ notNull(),
70
+ // Validate tag array elements
71
+ array([
72
+ // Element cannot be null
73
+ notNull(),
74
+ // Element property validation
75
+ plainObject({
76
+ id: [notBlank()],
77
+ name: [notBlank()],
78
+ permissinos: [
79
+ notNull(),
80
+ plainObject({
81
+ edit: [notNull()],
82
+ read: [notNull()]
83
+ })
84
+ ]
85
+ })
86
+ ])
87
+ ]
88
+ }
89
+ )
90
+ ```
91
+
92
+ In actual development, it's recommended to keep validation at most one level deep, without nesting, otherwise the program will be difficult to maintain.
93
+
94
+ ## Custom Validation Rules
95
+
96
+ If the built-in validation rules cannot meet your needs, you can write custom validation rules.
97
+
98
+ ```ts
99
+ /**
100
+ * Custom validation
101
+ * @returns Property validator
102
+ */
103
+ function customValidate(): PropValidator {
104
+ // Validator name for tracking
105
+ const validator = 'custom'
106
+ const message = 'Cannot start with t'
107
+ return val => {
108
+ // Skip null validation
109
+ if (!val) {
110
+ return { ok: true }
111
+ }
112
+ if (typeof val !== 'string') {
113
+ return { ok: false, validator, message: 'Value is not a string' }
114
+ }
115
+ if (val.startsWith('t')) {
116
+ return { ok: false, validator, message }
117
+ }
118
+ return { ok: true }
119
+ }
120
+ }
121
+
122
+ validate(
123
+ { name: 'tim' },
124
+ {
125
+ name: [customValidate()]
126
+ }
127
+ )
128
+ ```
129
+
130
+ Built-in validation rules have internationalization support. If you need internationalization for custom validation rules, you need to handle it yourself. See the internationalization chapter for details.
@@ -632,36 +632,78 @@ await startWebServer({
632
632
 
633
633
  ### Server-Sent Events
634
634
 
635
- 组件本身没有直接提供对 SSE(Server-Sent Events) 的支持,可以在路由的处理函数中适当的进行处理来实现。
635
+ 0.6.0 版本开始,MVC 组件内置了 `createSseHandler`,封装了 SSE 协议细节,大幅简化服务端推送实现。
636
636
 
637
637
  ```ts
638
- // 启动服务
638
+ import { createSseHandler } from 'wok-server'
639
+
639
640
  await startWebServer({
640
- // 路由配置
641
641
  routers: {
642
- '/sse': async exchange => {
643
- const { response } = exchange
644
- // 设置消息头
645
- response.setHeader('Content-Type', 'text/event-stream')
646
- response.setHeader('Cache-Control', 'no-cache')
647
- response.setHeader('Connection', 'keep-alive')
648
- // 模拟异步操作更新多条消息
649
- let counter = 0
650
- for (let i = 0; i < 10; i++) {
651
- // 沉睡一秒,模拟异步业务处理
652
- await new Promise<void>((resolve, reject) => {
653
- setTimeout(resolve, 1000)
654
- })
655
- counter++
656
- // 写数据到响应信息中,前端在 EventSource 的 message 事件中处理
657
- response.write(`data: ${JSON.stringify({ message: '实时更新', count: counter })}\n\n`)
658
- if (counter >= 10) {
659
- break
642
+ '/sse': createSseHandler({
643
+ async handle(ctx) {
644
+ let counter = 0
645
+ for (let i = 0; i < 10; i++) {
646
+ await new Promise<void>(resolve => setTimeout(resolve, 1000))
647
+ counter++
648
+ ctx.send({ message: '实时更新', count: counter })
649
+ if (counter >= 10) {
650
+ break
651
+ }
660
652
  }
653
+ ctx.close()
661
654
  }
662
- // 最后结束响应
663
- response.end()
664
- }
655
+ })
656
+ }
657
+ })
658
+ ```
659
+
660
+ `handle` 函数接收一个 `SseContext` 对象,提供以下能力:
661
+
662
+ | 方法/属性 | 说明 |
663
+ | :---------------------------------------- | :----------------------------------------------------------- |
664
+ | `ctx.send(data, event?, id?)` | 发送 SSE 事件,`data` 会被 JSON 序列化。`event` 指定事件名(前端用 `addEventListener` 监听),`id` 设置事件 ID(用于断线重连的 `Last-Event-ID`) |
665
+ | `ctx.close()` | 显式结束 SSE 连接。`handle` 返回或抛异常时连接也会自动关闭 |
666
+ | `ctx.request` | 原始 `IncomingMessage`,可读取请求头等信息 |
667
+ | `ctx.response` | 原始 `ServerResponse`,高级场景下使用 |
668
+
669
+ #### 命名事件
670
+
671
+ 通过 `event` 参数发送命名事件,前端可按事件类型分别处理:
672
+
673
+ ```ts
674
+ createSseHandler({
675
+ async handle(ctx) {
676
+ ctx.send({ title: '新消息' }, 'notification')
677
+ ctx.send({ progress: 50 }, 'progress')
665
678
  }
666
679
  })
667
680
  ```
681
+
682
+ 前端:
683
+
684
+ ```ts
685
+ const es = new EventSource('/sse')
686
+ es.addEventListener('notification', e => {
687
+ const data = JSON.parse(e.data)
688
+ console.log('收到通知:', data.title)
689
+ })
690
+ ```
691
+
692
+ #### 断线重连
693
+
694
+ 通过 `id` 参数设置事件 ID,前端断线重连时浏览器会自动发送 `Last-Event-ID` 请求头:
695
+
696
+ ```ts
697
+ createSseHandler({
698
+ async handle(ctx) {
699
+ const lastId = ctx.request.headers['last-event-id']
700
+ // 根据 lastId 确定从何处恢复推送
701
+ }
702
+ })
703
+ ```
704
+
705
+ #### 连接生命周期
706
+
707
+ - `handle` 开始执行时,SSE 消息头已发送,连接已建立
708
+ - 客户端断开连接时,`ctx.send()` 调用变为空操作(自动忽略)
709
+ - `handle` 返回或抛异常时,连接自动关闭
@@ -228,12 +228,32 @@ await manager.insert(tableUser, {
228
228
  nickname: '小明',
229
229
  balance: 1
230
230
  })
231
+ // 插入时使用表达式
232
+ await manager.insert(tableUser, {
233
+ id: 'in002',
234
+ nickname: '小红',
235
+ balance: ['expr', '?? * ?', ['score', 2]],
236
+ createAt: ['now']
237
+ })
231
238
  // 批量插入
232
239
  await manager.insertMany(tableUser, [
233
240
  { id: 'im001', nickname: '张飞', balance: 0 },
234
241
  { id: 'im002', nickname: '关羽', balance: 2 },
235
242
  { id: 'im003', nickname: '刘备', balance: 5 }
236
243
  ])
244
+ // Upsert 单条,id 冲突则更新
245
+ await manager.upsert(tableUser, { id: 'us001', nickname: '赵云', balance: 10 })
246
+ // Upsert 批量
247
+ await manager.upsertMany(tableUser, [
248
+ { id: 'us002', nickname: '马超', balance: 20 },
249
+ { id: 'us003', nickname: '黄忠', balance: 30 }
250
+ ])
251
+ // Upsert 单条,冲突时自定义更新(如递增余额)
252
+ await manager.upsertWithUpdater(
253
+ tableUser,
254
+ { id: 'us001', nickname: '赵云', balance: 10 },
255
+ { balance: ['inc', 5], nickname: '赵云-updated' }
256
+ )
237
257
  // 根据指定的条件查询第一条符合的记录
238
258
  const user = await manager.findFirst(tableUser, c =>
239
259
  c.like('nickname', 'ff0%').gt('balance', 75).lt('balance', 77)
@@ -254,6 +274,18 @@ await manager.find({
254
274
  limit: 10,
255
275
  orderBy: [['balance', 'asc']]
256
276
  })
277
+ // 自定义排序表达式:按 balance * 2 降序
278
+ await manager.find({
279
+ table: tableUser,
280
+ criteria: c => c.like('nickname', 'ff0%'),
281
+ orderBy: [['expr', '?? * ?', ['balance', 2], 'desc']]
282
+ })
283
+ // 自定义查询条件表达式:balance * 2 > 50
284
+ await manager.find({
285
+ table: tableUser,
286
+ criteria: c => c.like('id', 'critex%').expr('?? * ? > ?', ['balance', 2, 50]),
287
+ orderBy: [['balance', 'asc']]
288
+ })
257
289
  // 统计符合条件的记录数量
258
290
  const count = await manager.count(tableUser, c => c.like('id', 'c00%').like('nickname', '李%'))
259
291
  // 分页查询
@@ -294,18 +326,99 @@ await manager.modify(`update user set nickname='无名' where nickname='佚名'`
294
326
  | deleteMany | 按指定条件删除,危险操作,建议尽可能设置 limit 参数来限制数量 |
295
327
  | findAll | 查询表下所有记录,危险操作,建议只对数据量非常小的表使用 |
296
328
  | findFirst | 查询符合条件的第一条记录 |
297
- | insert | 插入记录 |
298
- | insertMany | 一次性插入多条记录 |
299
- | update | 更新记录,需要完整信息 |
300
- | partialUpdate | 局部更新,只提供 id 和需要更新的字段信息 |
301
- | updateOne | 只更新指定条件的第一条记录,必须是相等条件,不支持范围条件 |
302
- | updateMany | 更新所有符合条件的记录,危险操作,建议对条件严加限制,控制受影响的范围 |
303
- | find | 按条件查询所有符合条件的记录,危险操作,建议尽可能设置 limit 参数来限制数量 |
304
- | findSelect | 指定字段进行条件查询,与 find 唯一的不同的是多一个参数 select 可以用来指定要返回的列 |
305
- | count | 统计符合条件的记录数量,危险操作,建议严格限制条件,注意索引的利用 |
306
- | paginate | 分页查询 ,危险操作,基于 find 和 count |
307
- | query | 自定义 sql 查询,返回记录列表,支持预编译 sql |
308
- | modify | 执行自定义 sql,返回操作记录数 ,支持预编译 sql |
329
+ | insert | 插入记录 |
330
+ | insertMany | 一次性插入多条记录 |
331
+ | upsert | 插入记录,主键冲突则更新 |
332
+ | upsertMany | 批量 upsert |
333
+ | upsertWithUpdater | upsert 单条,主键冲突时使用自定义更新器(Updater) |
334
+ | update | 更新记录,需要完整信息 |
335
+ | partialUpdate | 局部更新,只提供 id 和需要更新的字段信息 |
336
+ | updateOne | 只更新指定条件的第一条记录,必须是相等条件,不支持范围条件 |
337
+ | updateMany | 更新所有符合条件的记录,危险操作,建议对条件严加限制,控制受影响的范围 |
338
+ | find | 按条件查询所有符合条件的记录,危险操作,建议尽可能设置 limit 参数来限制数量 |
339
+ | findSelect | 指定字段进行条件查询,与 find 唯一的不同的是多一个参数 select 可以用来指定要返回的列 |
340
+ | count | 统计符合条件的记录数量,危险操作,建议严格限制条件,注意索引的利用 |
341
+ | paginate | 分页查询 ,危险操作,基于 find 和 count |
342
+ | paginateSelect | 指定字段进行分页查询,在 paginate 基础上增加了 select 参数 |
343
+ | query | 自定义 sql 查询,返回记录列表,支持预编译 sql |
344
+ | modify | 执行自定义 sql,返回操作记录数 ,支持预编译 sql |
345
+
346
+ ### 插入表达式
347
+
348
+ 从 0.7.0 版本开始,`insert`、`insertMany`、`upsert` 等插入方法的 data 参数支持 `InsertValue` 类型,
349
+ 可以在 VALUES 子句中使用表达式:
350
+
351
+ ```ts
352
+ await manager.insert(tableUser, {
353
+ id: 'in001',
354
+ nickname: '小明',
355
+ // 设置为 NOW()
356
+ createAt: ['now'],
357
+ // 解决冲突:将字段设置为 ['setNull'] 这个数组值(而非执行 setNull 操作)
358
+ extra: ['set', ['setNull']],
359
+ // 自定义表达式:balance = score * 2
360
+ balance: ['expr', '?? * ?', ['score', 2]],
361
+ // 无参数表达式
362
+ balance2: ['expr', 'RAND() * 100']
363
+ })
364
+ ```
365
+
366
+ ### 排序表达式
367
+
368
+ 从 0.7.0 版本开始,`orderBy` 参数升级为 `OrderBy<T>` 类型,除了普通列排序外,还支持自定义表达式排序。
369
+ 该类型向后兼容,原有的列排序写法不受影响:
370
+
371
+ ```ts
372
+ await manager.find({
373
+ table: tableUser,
374
+ criteria: c => c.like('nickname', 'ob%'),
375
+ // 普通列排序(与旧版兼容)
376
+ orderBy: [['balance', 'asc']]
377
+ })
378
+
379
+ // 自定义表达式排序:按 balance * 2 降序
380
+ // SQL: ORDER BY `balance` * 2 desc
381
+ await manager.find({
382
+ table: tableUser,
383
+ criteria: c => c.like('nickname', 'ob%'),
384
+ orderBy: [['expr', '?? * ?', ['balance', 2], 'desc']]
385
+ })
386
+
387
+ // 按名称长度排序:CHAR_LENGTH(name) desc
388
+ // SQL: ORDER BY CHAR_LENGTH(`name`) desc
389
+ await manager.find({
390
+ table: tableBook,
391
+ criteria: c => c.like('name', 'ob%'),
392
+ orderBy: [['expr', 'CHAR_LENGTH(??)', ['name'], 'desc']]
393
+ })
394
+
395
+ // 混合使用:普通列 + 表达式
396
+ orderBy: [
397
+ ['active', 'asc'],
398
+ ['expr', '?? * ?', ['balance', 2], 'desc']
399
+ ]
400
+ // SQL: ORDER BY `active` asc , `balance` * 2 desc
401
+ ```
402
+
403
+ ### 条件表达式
404
+
405
+ 从 0.7.0 版本开始,`MysqlCriteria` 新增 `expr()` 方法,可在 WHERE 子句中插入自定义 SQL 表达式:
406
+
407
+ ```ts
408
+ // balance * 2 > 50
409
+ // SQL: where ... and `balance` * 2 > 50
410
+ await manager.find({
411
+ table: tableUser,
412
+ criteria: c => c.like('id', 'critex%').expr('?? * ? > ?', ['balance', 2, 50])
413
+ })
414
+
415
+ // 全文搜索
416
+ // SQL: where ... and MATCH(`title`, `content`) AGAINST (? IN BOOLEAN MODE)
417
+ await manager.find({
418
+ table: tableBook,
419
+ criteria: c => c.expr('MATCH(??, ??) AGAINST(? IN BOOLEAN MODE)', ['title', 'content', keyword])
420
+ })
421
+ ```
309
422
 
310
423
  ### json 类型
311
424
 
@@ -431,24 +544,40 @@ partialUpdate 和 updateMany 方法支持局部修改一些字段,并且支持
431
544
  await manager.updateMany(tableUser, c => c.between('balance', 23, 24), {
432
545
  // 将 balance 增加 2
433
546
  balance: ['inc', 2],
547
+ // 将 balance 增加 1(省略第二个参数,默认 +1)
548
+ visits: ['inc'],
434
549
  // 将 consume_type 置空
435
- consume_type:['setNull']
550
+ consume_type: ['setNull'],
551
+ // 设置为 NOW()
552
+ last_login_at: ['now'],
553
+ // NULL 安全的字符串追加:col = CONCAT(IFNULL(col, ''), ?)
554
+ nickname: ['concat', '-suffix'],
555
+ // 自定义表达式:score = score * 2
556
+ score: ['expr', '?? * ?', ['score', 2]]
436
557
  })
437
558
  ```
438
559
 
439
- 如果将一个字段的值设置为 null 也可以置空,但是这要求设置 ts 类型支持。
560
+ > **注意**:0.7.0 版本已移除 `['func']`,请使用 `['expr']` 替代。
561
+ > 如 `['func', 'NOW()']` → `['expr', 'NOW()']`。
562
+
563
+ 从 **0.7.0 版本**开始,`null` 和 `undefined` 一样会被忽略更新。**如需将字段设置为 NULL,必须使用 `['setNull']`**。
440
564
 
441
565
  ```ts
442
566
  interface User {
443
567
  id: string
444
- // 将 role 的类型设置包含 null
445
568
  role: string | null
446
569
  }
447
570
 
571
+ // 正确:使用 ['setNull'] 将字段置空
572
+ await manager.partialUpdate(tableUser, {
573
+ id: '001',
574
+ role: ['setNull']
575
+ })
576
+
577
+ // 错误:0.7.0 版本开始,null 会被忽略,不会更新字段
448
578
  await manager.partialUpdate(tableUser, {
449
579
  id: '001',
450
- // 等同于 role:['setNull']
451
- role: null
580
+ role: null // 此操作不会生效
452
581
  })
453
582
  ```
454
583
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wok-server",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "packageManager": "pnpm@8.9.0",
5
5
  "description": "一个基于 NodeJs 和 TypeScript 的后端框架,轻量级、克制、简洁。A lightweight, restrained, and concise backend framework based on Node.js and TypeScript.",
6
6
  "scripts": {
@@ -19,6 +19,9 @@
19
19
  "dist/",
20
20
  "docs/",
21
21
  "documentation/",
22
+ "skills/",
23
+ "src/",
24
+ "README.en.md",
22
25
  "README.md"
23
26
  ],
24
27
  "author": "peak",