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,157 @@
1
+ # 响应 HTML
2
+
3
+ MVC 组件提供了两种 HTML 响应方式:框架内置的结构化 HTML 构建和第三方模板引擎。
4
+
5
+ ## 内置 HTML 构建
6
+
7
+ `ServerExchange.respondHtml()` 接收 `HtmlStuct` 对象或 HTML 字符串,自动渲染并设置 `Content-Type: text/html; charset=utf-8`。
8
+
9
+ ### HtmlStuct 结构
10
+
11
+ ```ts
12
+ interface HtmlStuct {
13
+ lang?: string // <html lang="zh">
14
+ head: SubElementsOpt // <head> 子元素
15
+ body: SubElementsOpt | { attrs?: HtmlAttrs; children: SubElementsOpt } // <body> 子元素及属性
16
+ }
17
+
18
+ type SubElementsOpt = Array<HtmlTag | string> | ((add: (...child) => void) => void)
19
+ ```
20
+
21
+ `SubElementsOpt` 既可以是静态数组,也可以是一个函数,通过回调参数 `add` 动态添加子元素,配合循环和分支语句实现动态渲染。
22
+
23
+ ### HtmlTag 标签定义
24
+
25
+ ```ts
26
+ interface HtmlTag {
27
+ tag: string // 标签名,如 'div'、'span'、'h1'
28
+ selfClosing?: boolean // 是否自闭合,如 <br/>、<img/>
29
+ attrs?: HtmlAttrs // 属性(有类型推断,支持 id、class、style 等全局属性)
30
+ children?: SubElementsOpt // 子元素
31
+ }
32
+ ```
33
+
34
+ ### 完整示例
35
+
36
+ ```ts
37
+ await startWebServer({
38
+ routers: {
39
+ '/profile': async exchange => {
40
+ const user = await getUser(exchange.headers.authorization)
41
+ exchange.respondHtml({
42
+ lang: 'zh',
43
+ head: [
44
+ { tag: 'title', children: ['个人中心'] },
45
+ { tag: 'script', attrs: { type: 'module', src: 'main.js' } }
46
+ ],
47
+ body: {
48
+ attrs: { style: { 'background-color': 'white' } },
49
+ children: add => {
50
+ add({ tag: 'h1', children: ['个人中心'] })
51
+ if (user) {
52
+ add({ tag: 'p', children: [`用户名:${user.account}`] })
53
+ } else {
54
+ add({
55
+ tag: 'p',
56
+ children: [
57
+ '请登录后查看',
58
+ { tag: 'a', attrs: { href: '/login' }, children: ['点击进行登录'] }
59
+ ]
60
+ })
61
+ }
62
+ add(footer())
63
+ }
64
+ }
65
+ })
66
+ }
67
+ }
68
+ })
69
+ ```
70
+
71
+ ### 提取可复用组件
72
+
73
+ 常用的标签组合可封装为函数,返回 `HtmlTag` 类型:
74
+
75
+ ```ts
76
+ function footer(): HtmlTag {
77
+ return {
78
+ tag: 'div',
79
+ attrs: { class: 'footer' },
80
+ children: [
81
+ { tag: 'a', attrs: { href: '/about' }, children: ['关于我们'] },
82
+ { tag: 'a', attrs: { href: '/call' }, children: ['联系我们'] },
83
+ { tag: 'a', attrs: { href: '/privacy' }, children: ['隐私协议'] }
84
+ ]
85
+ }
86
+ }
87
+ ```
88
+
89
+ ### 快捷方法
90
+
91
+ 除了 `respondHtml()`,也可直接传入 HTML 字符串:
92
+
93
+ ```ts
94
+ exchange.respondHtml('<h1>Hello World</h1>')
95
+ ```
96
+
97
+ 等价于设置 `Content-Type: text/html` 并输出给定字符串。
98
+
99
+ ---
100
+
101
+ ## 第三方模板引擎
102
+
103
+ 如果不喜欢内置的结构化构建方式,也可以使用第三方模板库,渲染后将 HTML 字符串传给 `respondHtml()`。
104
+
105
+ ### Handlebars
106
+
107
+ ```ts
108
+ import { compile } from 'handlebars'
109
+
110
+ await startWebServer({
111
+ routers: {
112
+ '/html': async exchange => {
113
+ const template = compile(`
114
+ <!DOCTYPE html>
115
+ <html>
116
+ <head><title>Handlebars Example</title></head>
117
+ <body>
118
+ <p>Hello, my name is {{name}}.</p>
119
+ <ul>{{#kids}}<li>{{name}} is {{age}}</li>{{/kids}}</ul>
120
+ </body>
121
+ </html>
122
+ `)
123
+ const data = {
124
+ name: 'Alan',
125
+ kids: [{ name: 'Jimmy', age: '12' }, { name: 'Sally', age: '4' }]
126
+ }
127
+ exchange.respondHtml(template(data))
128
+ }
129
+ }
130
+ })
131
+ ```
132
+
133
+ ### Vue 3.x SSR
134
+
135
+ ```ts
136
+ import { createSSRApp } from 'vue'
137
+ import { renderToString } from 'vue/server-renderer'
138
+
139
+ await startWebServer({
140
+ routers: {
141
+ '/html': async exchange => {
142
+ const app = createSSRApp({
143
+ data: () => ({ count: 1 }),
144
+ template: `<button>{{ count }}</button>`
145
+ })
146
+ const html = await renderToString(app)
147
+ exchange.respondHtml(`<!DOCTYPE html>
148
+ <html>
149
+ <head><title>Vue SSR</title></head>
150
+ <body><div id="app">${html}</div></body>
151
+ </html>`)
152
+ }
153
+ }
154
+ })
155
+ ```
156
+
157
+ > **提示:** 无论使用哪种方式,最终调用 `exchange.respondHtml()` 即可正确设置响应头与状态码。
@@ -0,0 +1,121 @@
1
+ # Server-Sent Events (SSE)
2
+
3
+ 从 0.4.0 版本开始,MVC 组件内置了 `createSseHandler`,封装了 SSE 协议细节,大幅简化服务端推送实现。
4
+
5
+ ## 内置 SSE Handler
6
+
7
+ ```ts
8
+ import { createSseHandler } from 'wok-server'
9
+
10
+ await startWebServer({
11
+ routers: {
12
+ '/sse': createSseHandler({
13
+ async handle(ctx) {
14
+ let counter = 0
15
+ for (let i = 0; i < 10; i++) {
16
+ await new Promise<void>(resolve => setTimeout(resolve, 1000))
17
+ counter++
18
+ // ctx.send 自动处理 SSE 协议格式
19
+ ctx.send({ message: '实时更新', count: counter })
20
+ if (counter >= 10) {
21
+ break
22
+ }
23
+ }
24
+ // 显式关闭连接(不调用也会在 handle 结束时自动关闭)
25
+ ctx.close()
26
+ }
27
+ })
28
+ }
29
+ })
30
+ ```
31
+
32
+ ### SseContext
33
+
34
+ `handle` 函数接收的 `ctx` 对象提供以下属性与方法:
35
+
36
+ | 属性/方法 | 说明 |
37
+ | :--------------------------------------- | :----------------------------------------------------------- |
38
+ | `ctx.send(data, event?, id?)` | 发送 SSE 事件,`data` 会被 JSON 序列化。`event` 指定事件名(前端用 `addEventListener` 监听),`id` 设置事件 ID(用于断线重连的 `Last-Event-ID`) |
39
+ | `ctx.close()` | 显式结束 SSE 连接。`handle` 结束时连接也会自动关闭 |
40
+ | `ctx.request` | 原始 `IncomingMessage`,可读取请求头等信息 |
41
+ | `ctx.response` | 原始 `ServerResponse`,高级场景下使用 |
42
+
43
+ ### 命名事件
44
+
45
+ 通过 `event` 参数发送命名事件,前端可按事件类型分别处理:
46
+
47
+ ```ts
48
+ createSseHandler({
49
+ async handle(ctx) {
50
+ ctx.send({ title: '新消息' }, 'notification')
51
+ ctx.send({ progress: 50 }, 'progress')
52
+ }
53
+ })
54
+ ```
55
+
56
+ 前端:
57
+
58
+ ```ts
59
+ const es = new EventSource('/sse')
60
+ es.addEventListener('notification', e => {
61
+ const data = JSON.parse(e.data)
62
+ console.log('收到通知:', data.title)
63
+ })
64
+ es.addEventListener('progress', e => {
65
+ const data = JSON.parse(e.data)
66
+ console.log('进度:', data.progress)
67
+ })
68
+ ```
69
+
70
+ ### 断线重连
71
+
72
+ 通过 `id` 参数设置事件 ID,前端断线重连时浏览器会自动发送 `Last-Event-ID` 请求头:
73
+
74
+ ```ts
75
+ createSseHandler({
76
+ async handle(ctx) {
77
+ const lastId = ctx.request.headers['last-event-id']
78
+ // 根据 lastId 确定从何处恢复推送
79
+ for (const event of events) {
80
+ ctx.send(event, undefined, event.id)
81
+ }
82
+ }
83
+ })
84
+ ```
85
+
86
+ ### 连接生命周期
87
+
88
+ - `handle` 开始执行时,SSE 消息头已发送,连接已建立
89
+ - 客户端断开连接时,`ctx.send()` 调用变为空操作(自动忽略)
90
+ - `handle` 返回或抛异常时,连接自动关闭
91
+ - 手动调用 `ctx.close()` 可提前结束连接
92
+
93
+ ---
94
+
95
+ ## 手动实现(高级用法)
96
+
97
+ 如需完全控制底层行为,仍可在普通路由处理器中手动操作 `response` 对象:
98
+
99
+ ```ts
100
+ await startWebServer({
101
+ routers: {
102
+ '/sse': async exchange => {
103
+ const { response } = exchange
104
+ response.setHeader('Content-Type', 'text/event-stream')
105
+ response.setHeader('Cache-Control', 'no-cache')
106
+ response.setHeader('Connection', 'keep-alive')
107
+
108
+ let counter = 0
109
+ for (let i = 0; i < 10; i++) {
110
+ await new Promise<void>(resolve => setTimeout(resolve, 1000))
111
+ counter++
112
+ response.write(`data: ${JSON.stringify({ message: '实时更新', count: counter })}\n\n`)
113
+ if (counter >= 10) {
114
+ break
115
+ }
116
+ }
117
+ response.end()
118
+ }
119
+ }
120
+ })
121
+ ```
@@ -0,0 +1,47 @@
1
+ # 静态文件
2
+
3
+ 通过 `startWebServer` 的 `static` 参数设置静态文件目录映射,将文件系统目录映射到请求路径。
4
+
5
+ ## 基本配置
6
+
7
+ ```ts
8
+ await startWebServer({
9
+ static: {
10
+ '/a': { dir: '/path/to/files', cacheAge: 300 },
11
+ '/a/b': { dir: '/path/to/other', cacheAge: 150 },
12
+ '/b': { dir: 'static', cacheAge: 0 }
13
+ },
14
+ routers: {}
15
+ })
16
+ ```
17
+
18
+ | 参数 | 说明 |
19
+ | :-------- | :----------------------------------------------- |
20
+ | `dir` | 映射的文件目录,支持绝对路径和相对路径(相对进程当前目录) |
21
+ | `cacheAge` | 缓存时间(秒),大于 0 则生成 `Cache-Control` 消息头 |
22
+
23
+ ## 路径匹配规则
24
+
25
+ - 仅支持**前缀匹配**,不支持通配符。例如 `/a/demo.html` 匹配 `/a` 路径配置。
26
+ - 路径配置有**优先级**:更详细的路径优先匹配。例如访问 `/a/b/music.mp3` 会匹配 `/a/b` 而非 `/a`。
27
+ - 匹配失败不会降级尝试:如果 `/a/b` 目录下找不到文件,不会再去 `/a` 目录查找。
28
+ - 支持**主页自动映射**:访问 `/a/b/c` 时,会先找文件 `c`,找不到则尝试目录 `c` 下的 `index.html`。
29
+
30
+ ## 服务器端缓存
31
+
32
+ 从 0.3.0 版本开始,支持静态文件服务器端缓存。通过以下环境变量配置:
33
+
34
+ | 环境变量 | 说明 | 默认值 |
35
+ | :--------------------------------- | :-------------------------------------------- | :----- |
36
+ | `SERVER_STATIC_CACHE_ENABLE` | 是否启用服务器缓存 | false |
37
+ | `SERVER_STATIC_CACHE_MAX_AGE` | 服务器缓存时间(秒) | 600 |
38
+ | `SERVER_STATIC_CACHE_MAX_FILE_SIZE` | 最大可缓存的文件大小,支持语义化格式(如 10m、100k) | 10m |
39
+ | `SERVER_STATIC_CACHE_MAX_SIZE` | 缓存最大空间,超出后清理,支持语义化格式 | 100m |
40
+
41
+ 0.3.2 版本新增 `removeServerStaticCache` 函数,可主动清除指定路径的静态文件缓存:
42
+
43
+ ```ts
44
+ import { removeServerStaticCache } from 'wok-server'
45
+
46
+ removeServerStaticCache('/assets/index.js')
47
+ ```
@@ -0,0 +1,62 @@
1
+ # 文件上传
2
+
3
+ ## 二进制(Binary)上传
4
+
5
+ 二进制上传即 `application/octet-stream` 格式的上传,请求正文仅为文件内容,不包含其他信息。由 `createUploadHandler` 函数创建路由处理器,响应 JSON 格式。
6
+
7
+ 这种形式的优势是简单、性能高——服务器端拿到请求正文即是文件,无需解析。但额外参数只能通过 QueryString 或 Header 传递,且一次只能传一个文件。
8
+
9
+ ```ts
10
+ import { createUploadHandler } from 'wok-server'
11
+
12
+ interface Resp {
13
+ url: string
14
+ }
15
+
16
+ export const uploadAvatar = createUploadHandler<Resp>({
17
+ async handle(body, exchange) {
18
+ const userId = exchange.query.getStr('userId') as string
19
+ if (body.byteLength > 2 * 1024 * 1024) {
20
+ throw new BusinessException('文件大小不得超过 2MB')
21
+ }
22
+ const key = `users/${userId}/avatar`
23
+ await oss.putObject(key, body)
24
+ return { url: oss.getUrl(key) }
25
+ }
26
+ })
27
+ ```
28
+
29
+ 如需更高自由度(如不返回 JSON),使用普通路由处理器,通过 `exchange.bodyBuffer()` 读取请求正文:
30
+
31
+ ```ts
32
+ export const uploadAvatar: RouterHandler = async exchange => {
33
+ const file = await exchange.bodyBuffer()
34
+ const query = exchange.parseQueryString()
35
+ const userId = query.getStr('userId')
36
+ // 校验参数和存储文件等流程省略...
37
+ }
38
+ ```
39
+
40
+ ## multipart/form-data 格式上传
41
+
42
+ 组件目前尚未内置对 multipart/form-data 类型请求的处理,可通过第三方库(如 formidable)解析。
43
+
44
+ ```ts
45
+ import formidable from 'formidable'
46
+
47
+ await startWebServer({
48
+ routers: {
49
+ '/cover': async exchange => {
50
+ const form = formidable({})
51
+ const [fields, files] = await form.parse(exchange.request)
52
+ // todo 继续业务处理
53
+ }
54
+ }
55
+ })
56
+ ```
57
+
58
+ ### 注意事项
59
+
60
+ - 使用了第三方库读取 `request` 内容后,不能再使用 `exchange` 中的 `bodyXxx` 系列方法,调用时会抛出异常。
61
+ - 同样,调用了 `bodyXxx` 系列方法后也不能再用第三方库读取内容,否则将读取不到完整内容或引发异常。
62
+ - `bodyXxx` 系列方法之间可以重复调用,不会产生错误。例如调用 `bodyText()` 后再调用 `bodyJson()` 是允许的。
@@ -0,0 +1,30 @@
1
+ # WebSocket
2
+
3
+ MVC 组件本身未内置 WebSocket 处理,但通过 `startWebServer` 的 `preHandler` 参数可整合支持原生 `http` 模块的 WebSocket 库(如 socket.io)。
4
+
5
+ `preHandler` 在服务启动前执行,接收原生 `http.Server` 实例,可在此时挂载 WebSocket 服务。
6
+
7
+ ```ts
8
+ import { Server } from 'socket.io'
9
+
10
+ await startWebServer({
11
+ routers: {
12
+ // 路由配置省略...
13
+ },
14
+ preHandler: async server => {
15
+ const io = new Server(server)
16
+ io.of('/chat').on('connection', socket => {
17
+ socket.on('message', data => {
18
+ /* 处理自定义事件 */
19
+ })
20
+ socket.on('disconnect', () => {
21
+ /* 连接断开处理 */
22
+ })
23
+ })
24
+ }
25
+ })
26
+ ```
27
+
28
+ ### 注意事项
29
+
30
+ - WebSocket 路径(如 `/chat`)与路由路径不会冲突。客户端以 HTTP 协议请求时走路由处理,以 WebSocket 协议请求时走 socket.io 处理。但不推荐使用相同的路径。