@snail-js/api 0.1.27 → 1.0.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 (313) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +125 -605
  3. package/dist/adapter/plain.d.ts +12 -0
  4. package/dist/adapter/plain.d.ts.map +1 -0
  5. package/dist/adapter/react.d.ts +14 -0
  6. package/dist/adapter/react.d.ts.map +1 -0
  7. package/dist/adapter/registry.d.ts +16 -0
  8. package/dist/adapter/registry.d.ts.map +1 -0
  9. package/dist/adapter/vue.d.ts +15 -0
  10. package/dist/adapter/vue.d.ts.map +1 -0
  11. package/dist/chunks/custom-UchOSg_s.js +466 -0
  12. package/dist/chunks/custom-UchOSg_s.js.map +1 -0
  13. package/dist/chunks/download-lBC7oOTT.js +160 -0
  14. package/dist/chunks/download-lBC7oOTT.js.map +1 -0
  15. package/dist/chunks/object-Ct0w-h4i.js +74 -0
  16. package/dist/chunks/object-Ct0w-h4i.js.map +1 -0
  17. package/dist/chunks/plugin-D3RDffDG.js +742 -0
  18. package/dist/chunks/plugin-D3RDffDG.js.map +1 -0
  19. package/dist/chunks/react-C1em-gxy.js +62 -0
  20. package/dist/chunks/react-C1em-gxy.js.map +1 -0
  21. package/dist/chunks/request-qeRhihEF.js +40 -0
  22. package/dist/chunks/request-qeRhihEF.js.map +1 -0
  23. package/dist/chunks/response-D-ubkAFl.js +127 -0
  24. package/dist/chunks/response-D-ubkAFl.js.map +1 -0
  25. package/dist/chunks/use-download-FAjtdJ58.js +1816 -0
  26. package/dist/chunks/use-download-FAjtdJ58.js.map +1 -0
  27. package/dist/chunks/vue-Dd9EhkQ3.js +34 -0
  28. package/dist/chunks/vue-Dd9EhkQ3.js.map +1 -0
  29. package/dist/core/args.d.ts +54 -0
  30. package/dist/core/args.d.ts.map +1 -0
  31. package/dist/core/connection.d.ts +15 -0
  32. package/dist/core/connection.d.ts.map +1 -0
  33. package/dist/core/context.d.ts +124 -0
  34. package/dist/core/context.d.ts.map +1 -0
  35. package/dist/core/http-stream.d.ts +28 -0
  36. package/dist/core/http-stream.d.ts.map +1 -0
  37. package/dist/core/logger.d.ts +22 -0
  38. package/dist/core/logger.d.ts.map +1 -0
  39. package/dist/core/metadata.d.ts +92 -0
  40. package/dist/core/metadata.d.ts.map +1 -0
  41. package/dist/core/metadata.keys.d.ts +41 -0
  42. package/dist/core/metadata.keys.d.ts.map +1 -0
  43. package/dist/core/method.d.ts +177 -0
  44. package/dist/core/method.d.ts.map +1 -0
  45. package/dist/core/plugin-manager.d.ts +106 -0
  46. package/dist/core/plugin-manager.d.ts.map +1 -0
  47. package/dist/core/plugin.d.ts +113 -0
  48. package/dist/core/plugin.d.ts.map +1 -0
  49. package/dist/core/reconnect.d.ts +22 -0
  50. package/dist/core/reconnect.d.ts.map +1 -0
  51. package/dist/core/resolve-stream.d.ts +45 -0
  52. package/dist/core/resolve-stream.d.ts.map +1 -0
  53. package/dist/core/resolve.d.ts +50 -0
  54. package/dist/core/resolve.d.ts.map +1 -0
  55. package/dist/core/response.d.ts +60 -0
  56. package/dist/core/response.d.ts.map +1 -0
  57. package/dist/core/server.d.ts +132 -0
  58. package/dist/core/server.d.ts.map +1 -0
  59. package/dist/core/sse.d.ts +27 -0
  60. package/dist/core/sse.d.ts.map +1 -0
  61. package/dist/core/state-bag.d.ts +36 -0
  62. package/dist/core/state-bag.d.ts.map +1 -0
  63. package/dist/core/websocket.d.ts +29 -0
  64. package/dist/core/websocket.d.ts.map +1 -0
  65. package/dist/decorators/api.d.ts +24 -4
  66. package/dist/decorators/api.d.ts.map +1 -0
  67. package/dist/decorators/args.d.ts +77 -14
  68. package/dist/decorators/args.d.ts.map +1 -0
  69. package/dist/decorators/custom.d.ts +81 -0
  70. package/dist/decorators/custom.d.ts.map +1 -0
  71. package/dist/decorators/header.d.ts +22 -0
  72. package/dist/decorators/header.d.ts.map +1 -0
  73. package/dist/decorators/index.d.ts +17 -0
  74. package/dist/decorators/index.d.ts.map +1 -0
  75. package/dist/decorators/methods.d.ts +33 -0
  76. package/dist/decorators/methods.d.ts.map +1 -0
  77. package/dist/decorators/progress.d.ts +24 -6
  78. package/dist/decorators/progress.d.ts.map +1 -0
  79. package/dist/decorators/server.d.ts +28 -7
  80. package/dist/decorators/server.d.ts.map +1 -0
  81. package/dist/decorators/stream.d.ts +113 -0
  82. package/dist/decorators/stream.d.ts.map +1 -0
  83. package/dist/default/options.d.ts +19 -0
  84. package/dist/default/options.d.ts.map +1 -0
  85. package/dist/error/base.d.ts +20 -0
  86. package/dist/error/base.d.ts.map +1 -0
  87. package/dist/error/decorator.d.ts +14 -0
  88. package/dist/error/decorator.d.ts.map +1 -0
  89. package/dist/error/hook.d.ts +14 -0
  90. package/dist/error/hook.d.ts.map +1 -0
  91. package/dist/error/index.d.ts +8 -0
  92. package/dist/error/index.d.ts.map +1 -0
  93. package/dist/error/options.d.ts +12 -0
  94. package/dist/error/options.d.ts.map +1 -0
  95. package/dist/error/plugin.d.ts +11 -0
  96. package/dist/error/plugin.d.ts.map +1 -0
  97. package/dist/error/request.d.ts +29 -0
  98. package/dist/error/request.d.ts.map +1 -0
  99. package/dist/error/response.d.ts +36 -0
  100. package/dist/error/response.d.ts.map +1 -0
  101. package/dist/index.d.ts +56 -11
  102. package/dist/index.d.ts.map +1 -0
  103. package/dist/index.js +2034 -0
  104. package/dist/index.js.map +1 -0
  105. package/dist/locale/en.d.ts +5 -0
  106. package/dist/locale/en.d.ts.map +1 -0
  107. package/dist/locale/index.d.ts +57 -0
  108. package/dist/locale/index.d.ts.map +1 -0
  109. package/dist/locale/types.d.ts +11 -0
  110. package/dist/locale/types.d.ts.map +1 -0
  111. package/dist/locale/zh.d.ts +5 -0
  112. package/dist/locale/zh.d.ts.map +1 -0
  113. package/dist/plugins/cache/adapters/indexeddb.d.ts +52 -0
  114. package/dist/plugins/cache/adapters/indexeddb.d.ts.map +1 -0
  115. package/dist/plugins/cache/adapters/memory.d.ts +60 -0
  116. package/dist/plugins/cache/adapters/memory.d.ts.map +1 -0
  117. package/dist/plugins/cache/adapters/web-storage.d.ts +43 -0
  118. package/dist/plugins/cache/adapters/web-storage.d.ts.map +1 -0
  119. package/dist/plugins/cache/decorators.d.ts +62 -0
  120. package/dist/plugins/cache/decorators.d.ts.map +1 -0
  121. package/dist/plugins/cache/index.d.ts +41 -0
  122. package/dist/plugins/cache/index.d.ts.map +1 -0
  123. package/dist/plugins/cache/key.d.ts +48 -0
  124. package/dist/plugins/cache/key.d.ts.map +1 -0
  125. package/dist/plugins/cache/manager.d.ts +124 -0
  126. package/dist/plugins/cache/manager.d.ts.map +1 -0
  127. package/dist/plugins/cache/plugin.d.ts +64 -0
  128. package/dist/plugins/cache/plugin.d.ts.map +1 -0
  129. package/dist/plugins/cache/type.d.ts +116 -0
  130. package/dist/plugins/cache/type.d.ts.map +1 -0
  131. package/dist/plugins/index.d.ts +75 -0
  132. package/dist/plugins/index.d.ts.map +1 -0
  133. package/dist/plugins/index.js +2265 -0
  134. package/dist/plugins/index.js.map +1 -0
  135. package/dist/plugins/interceptor/decorators.d.ts +44 -0
  136. package/dist/plugins/interceptor/decorators.d.ts.map +1 -0
  137. package/dist/plugins/interceptor/index.d.ts +31 -0
  138. package/dist/plugins/interceptor/index.d.ts.map +1 -0
  139. package/dist/plugins/interceptor/manager.d.ts +27 -0
  140. package/dist/plugins/interceptor/manager.d.ts.map +1 -0
  141. package/dist/plugins/interceptor/plugin.d.ts +65 -0
  142. package/dist/plugins/interceptor/plugin.d.ts.map +1 -0
  143. package/dist/plugins/interceptor/type.d.ts +45 -0
  144. package/dist/plugins/interceptor/type.d.ts.map +1 -0
  145. package/dist/plugins/pool/index.d.ts +26 -0
  146. package/dist/plugins/pool/index.d.ts.map +1 -0
  147. package/dist/plugins/pool/plugin.d.ts +83 -0
  148. package/dist/plugins/pool/plugin.d.ts.map +1 -0
  149. package/dist/plugins/pool/scheduler.d.ts +153 -0
  150. package/dist/plugins/pool/scheduler.d.ts.map +1 -0
  151. package/dist/plugins/pool/type.d.ts +38 -0
  152. package/dist/plugins/pool/type.d.ts.map +1 -0
  153. package/dist/plugins/react/index.d.ts +20 -0
  154. package/dist/plugins/react/index.d.ts.map +1 -0
  155. package/dist/plugins/react/index.js +145 -0
  156. package/dist/plugins/react/index.js.map +1 -0
  157. package/dist/plugins/react/plugin.d.ts +33 -0
  158. package/dist/plugins/react/plugin.d.ts.map +1 -0
  159. package/dist/plugins/react/type.d.ts +32 -0
  160. package/dist/plugins/react/type.d.ts.map +1 -0
  161. package/dist/plugins/transform/decorators.d.ts +54 -0
  162. package/dist/plugins/transform/decorators.d.ts.map +1 -0
  163. package/dist/plugins/transform/hydrate.d.ts +47 -0
  164. package/dist/plugins/transform/hydrate.d.ts.map +1 -0
  165. package/dist/plugins/transform/index.d.ts +41 -0
  166. package/dist/plugins/transform/index.d.ts.map +1 -0
  167. package/dist/plugins/transform/plugin.d.ts +20 -0
  168. package/dist/plugins/transform/plugin.d.ts.map +1 -0
  169. package/dist/plugins/transform/type.d.ts +67 -0
  170. package/dist/plugins/transform/type.d.ts.map +1 -0
  171. package/dist/plugins/validate/decorators.d.ts +24 -0
  172. package/dist/plugins/validate/decorators.d.ts.map +1 -0
  173. package/dist/plugins/validate/index.d.ts +40 -0
  174. package/dist/plugins/validate/index.d.ts.map +1 -0
  175. package/dist/plugins/validate/plugin.d.ts +13 -0
  176. package/dist/plugins/validate/plugin.d.ts.map +1 -0
  177. package/dist/plugins/validate/type.d.ts +54 -0
  178. package/dist/plugins/validate/type.d.ts.map +1 -0
  179. package/dist/plugins/version/decorators.d.ts +22 -0
  180. package/dist/plugins/version/decorators.d.ts.map +1 -0
  181. package/dist/plugins/version/index.d.ts +23 -0
  182. package/dist/plugins/version/index.d.ts.map +1 -0
  183. package/dist/plugins/version/plugin.d.ts +13 -0
  184. package/dist/plugins/version/plugin.d.ts.map +1 -0
  185. package/dist/plugins/version/type.d.ts +47 -0
  186. package/dist/plugins/version/type.d.ts.map +1 -0
  187. package/dist/plugins/vue/index.d.ts +21 -0
  188. package/dist/plugins/vue/index.d.ts.map +1 -0
  189. package/dist/plugins/vue/index.js +114 -0
  190. package/dist/plugins/vue/index.js.map +1 -0
  191. package/dist/plugins/vue/plugin.d.ts +15 -0
  192. package/dist/plugins/vue/plugin.d.ts.map +1 -0
  193. package/dist/plugins/vue/type.d.ts +34 -0
  194. package/dist/plugins/vue/type.d.ts.map +1 -0
  195. package/dist/strategies/index.d.ts +2 -0
  196. package/dist/strategies/index.d.ts.map +1 -0
  197. package/dist/strategies/index.js +29 -0
  198. package/dist/strategies/index.js.map +1 -0
  199. package/dist/strategies/plain.d.ts +2 -0
  200. package/dist/strategies/plain.d.ts.map +1 -0
  201. package/dist/strategies/plain.js +23 -0
  202. package/dist/strategies/plain.js.map +1 -0
  203. package/dist/strategies/react.d.ts +2 -0
  204. package/dist/strategies/react.d.ts.map +1 -0
  205. package/dist/strategies/react.js +30 -0
  206. package/dist/strategies/react.js.map +1 -0
  207. package/dist/strategies/shared/adapter.d.ts +23 -0
  208. package/dist/strategies/shared/adapter.d.ts.map +1 -0
  209. package/dist/strategies/shared/dom.d.ts +53 -0
  210. package/dist/strategies/shared/dom.d.ts.map +1 -0
  211. package/dist/strategies/shared/error.d.ts +30 -0
  212. package/dist/strategies/shared/error.d.ts.map +1 -0
  213. package/dist/strategies/shared/method.d.ts +51 -0
  214. package/dist/strategies/shared/method.d.ts.map +1 -0
  215. package/dist/strategies/shared/public.d.ts +33 -0
  216. package/dist/strategies/shared/public.d.ts.map +1 -0
  217. package/dist/strategies/shared/queue.d.ts +30 -0
  218. package/dist/strategies/shared/queue.d.ts.map +1 -0
  219. package/dist/strategies/shared/retry.d.ts +51 -0
  220. package/dist/strategies/shared/retry.d.ts.map +1 -0
  221. package/dist/strategies/shared/state.d.ts +117 -0
  222. package/dist/strategies/shared/state.d.ts.map +1 -0
  223. package/dist/strategies/shared/timing.d.ts +53 -0
  224. package/dist/strategies/shared/timing.d.ts.map +1 -0
  225. package/dist/strategies/shared/watcher.d.ts +37 -0
  226. package/dist/strategies/shared/watcher.d.ts.map +1 -0
  227. package/dist/strategies/use-auto-request.d.ts +77 -0
  228. package/dist/strategies/use-auto-request.d.ts.map +1 -0
  229. package/dist/strategies/use-download.d.ts +103 -0
  230. package/dist/strategies/use-download.d.ts.map +1 -0
  231. package/dist/strategies/use-fetcher.d.ts +52 -0
  232. package/dist/strategies/use-fetcher.d.ts.map +1 -0
  233. package/dist/strategies/use-pagination.d.ts +101 -0
  234. package/dist/strategies/use-pagination.d.ts.map +1 -0
  235. package/dist/strategies/use-request.d.ts +50 -0
  236. package/dist/strategies/use-request.d.ts.map +1 -0
  237. package/dist/strategies/use-retriable-request.d.ts +46 -0
  238. package/dist/strategies/use-retriable-request.d.ts.map +1 -0
  239. package/dist/strategies/use-sse.d.ts +103 -0
  240. package/dist/strategies/use-sse.d.ts.map +1 -0
  241. package/dist/strategies/use-token-auth.d.ts +88 -0
  242. package/dist/strategies/use-token-auth.d.ts.map +1 -0
  243. package/dist/strategies/use-uploader.d.ts +88 -0
  244. package/dist/strategies/use-uploader.d.ts.map +1 -0
  245. package/dist/strategies/use-watcher.d.ts +69 -0
  246. package/dist/strategies/use-watcher.d.ts.map +1 -0
  247. package/dist/typings/adapter.d.ts +61 -0
  248. package/dist/typings/adapter.d.ts.map +1 -0
  249. package/dist/typings/api.d.ts +122 -0
  250. package/dist/typings/api.d.ts.map +1 -0
  251. package/dist/typings/args.d.ts +51 -0
  252. package/dist/typings/args.d.ts.map +1 -0
  253. package/dist/typings/index.d.ts +8 -12
  254. package/dist/typings/index.d.ts.map +1 -0
  255. package/dist/typings/meta.d.ts +44 -0
  256. package/dist/typings/meta.d.ts.map +1 -0
  257. package/dist/typings/plugin.d.ts +114 -0
  258. package/dist/typings/plugin.d.ts.map +1 -0
  259. package/dist/typings/response.d.ts +118 -0
  260. package/dist/typings/response.d.ts.map +1 -0
  261. package/dist/typings/server.d.ts +83 -0
  262. package/dist/typings/server.d.ts.map +1 -0
  263. package/dist/typings/stream.d.ts +150 -0
  264. package/dist/typings/stream.d.ts.map +1 -0
  265. package/dist/utils/download.d.ts +97 -0
  266. package/dist/utils/download.d.ts.map +1 -0
  267. package/dist/utils/emitter.d.ts +36 -0
  268. package/dist/utils/emitter.d.ts.map +1 -0
  269. package/dist/utils/index.d.ts +6 -1
  270. package/dist/utils/index.d.ts.map +1 -0
  271. package/dist/utils/is.d.ts +22 -0
  272. package/dist/utils/is.d.ts.map +1 -0
  273. package/dist/utils/object.d.ts +44 -0
  274. package/dist/utils/object.d.ts.map +1 -0
  275. package/dist/utils/url.d.ts +44 -0
  276. package/dist/utils/url.d.ts.map +1 -0
  277. package/package.json +90 -27
  278. package/README_EN.md +0 -607
  279. package/dist/cache/index.d.ts +0 -9
  280. package/dist/cache/indexDBCache.d.ts +0 -13
  281. package/dist/cache/localstorageCache.d.ts +0 -10
  282. package/dist/cache/memoryCache.d.ts +0 -11
  283. package/dist/core/index.d.ts +0 -4
  284. package/dist/core/snailApi.d.ts +0 -22
  285. package/dist/core/snailMethod.d.ts +0 -49
  286. package/dist/core/snailServer.d.ts +0 -35
  287. package/dist/core/snailSse.d.ts +0 -20
  288. package/dist/decorators/cache.d.ts +0 -15
  289. package/dist/decorators/method.d.ts +0 -38
  290. package/dist/decorators/sse.d.ts +0 -30
  291. package/dist/decorators/strategy.d.ts +0 -10
  292. package/dist/decorators/versioning.d.ts +0 -16
  293. package/dist/eventEmmit/index.d.ts +0 -1
  294. package/dist/eventEmmit/snail.event.d.ts +0 -10
  295. package/dist/snail-api.js +0 -4868
  296. package/dist/snail-api.umd.cjs +0 -4872
  297. package/dist/strategies/jwtStrategy.d.ts +0 -4
  298. package/dist/typings/api.option.d.ts +0 -10
  299. package/dist/typings/apiProxy.d.ts +0 -8
  300. package/dist/typings/cache.management.option.d.ts +0 -25
  301. package/dist/typings/cache.type.d.ts +0 -23
  302. package/dist/typings/content.type.d.ts +0 -5
  303. package/dist/typings/request.body.d.ts +0 -3
  304. package/dist/typings/response.data.d.ts +0 -13
  305. package/dist/typings/snail.event.d.ts +0 -6
  306. package/dist/typings/snail.method.d.ts +0 -14
  307. package/dist/typings/snail.option.d.ts +0 -16
  308. package/dist/typings/sse.d.ts +0 -15
  309. package/dist/typings/strategy.d.ts +0 -5
  310. package/dist/typings/versioning.option.d.ts +0 -30
  311. package/dist/utils/function.d.ts +0 -31
  312. package/dist/versioning/index.d.ts +0 -1
  313. package/dist/versioning/versioning.d.ts +0 -12
package/README.md CHANGED
@@ -1,678 +1,198 @@
1
- <p>
2
- <img src="https://img.shields.io/badge/TypeScript-1e80ff"></img>
3
- <img src="https://img.shields.io/npm/v/axios?label=axios&labelColor=1e80ff&color=67C23A"></img>
4
- <img src="https://img.shields.io/npm/v/reflect-metadata?label=reflect-metadata&labelColor=1e80ff&color=67C23A"></img>
5
- </p>
1
+ # @snail-js/api
6
2
 
7
- 中文文档|<a href='https://github.com/limingchang/snail/blob/master/packages/api/README_EN.md'>English Document</a>
3
+ > 装饰器驱动、一切皆插件的 TypeScript 请求管理库,仅基于 [axios](https://axios-http.com/)。
8
4
 
9
- ## 项目介绍
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-7.0-1e80ff)](https://www.typescriptlang.org/)
6
+ [![axios](https://img.shields.io/badge/axios-1.20-67C23A)](https://axios-http.com/)
7
+ [![license](https://img.shields.io/badge/license-MIT-blue)](./LICENSE)
10
8
 
11
- - 基于 Axios 二次封装
12
- - 使用`reflect-metadata`创建和处理元数据
13
- - 提供装饰器定义请求请求的方式,支持所有请求方法和 SSE
9
+ - **装饰器驱动** `@Server` / `@Api` / `@Get` 定义请求,设计思想来自 Nest.js
10
+ - **一切皆插件** — 缓存、拦截器、请求池、版本、校验、转换、框架适配全部是插件,核心只做三件事
11
+ - **零运行时依赖** — `dependencies` 是空的;axios 是 peer 依赖,也不需要 `reflect-metadata`
12
+ - **完整的类型推断** — 从方法声明的返回类型推断 `data` 类型,无需手写泛型
13
+ - **请求策略** — alova 风格的 `useRequest` / `usePagination` / `useRetriableRequest` / `useDownload` 等 hook
14
+ - **浏览器与服务端皆可** — 核心只用平台能力,没有 DOM 依赖;SSR 与 Node 服务同样适用
14
15
 
15
16
  ## 安装
16
17
 
17
- `npm install @snail-js/api`
18
+ ```bash
19
+ pnpm add @snail-js/api axios
20
+ ```
21
+
22
+ `vue`、`react`、`zod` 都是**可选**的 peer 依赖,只有用到对应插件/策略时才需要安装。
18
23
 
19
- ## 使用
24
+ ## 快速开始
20
25
 
21
- 1. 请开启`TypeScript`相关装饰器配置
26
+ ### 1. 配置 TypeScript
22
27
 
23
28
  ```json
24
- // tsconfig.json
25
29
  {
26
- "module": "ESNext",
27
- // 模块解析策略
28
- "moduleResolution": "node",
29
- "baseUrl": ".",
30
- // target 必须大于ES6
31
- "target": "ESNext",
32
- // lib 需要包含大于ES6的ES版本
33
- "lib": ["ESNext", "DOM"],
34
- // 包含reflect-metadata类型
35
- "types": ["reflect-metadata"],
36
- "emitDecoratorMetadata": true,
37
- "experimentalDecorators": true,
38
-
39
- "skipLibCheck": true,
40
- "strictNullChecks": false
30
+ "compilerOptions": {
31
+ "experimentalDecorators": true
32
+ }
41
33
  }
42
34
  ```
43
35
 
44
- 2. 创建`Snail`后端基本配置实例
36
+ > **不需要** `reflect-metadata`,也**不需要** `emitDecoratorMetadata`。
37
+ > TypeScript 7 已不再产出 `design:*` 元数据,本库使用自己的元数据存储。
38
+ > 如果你从旧版本迁移,请参照[迁移指南](https://snail-js.github.io/api/guide/migration)。
39
+
40
+ ### 2. 定义服务
45
41
 
46
- ```typescript
42
+ ```ts
47
43
  // service.ts
48
- import { SnailServer, Server } from "@snail-js/api";
44
+ import { Server, SnailServer } from "@snail-js/api";
49
45
 
50
- @Server({
51
- baseURL: "/api",
52
- timeout: 5000,
53
- })
46
+ @Server({ baseURL: "/api", timeout: 5000 })
54
47
  class BackEnd extends SnailServer {}
55
48
 
56
- export const Service = new BackEnd();
57
- ```
58
-
59
- 3. 创建 Api 实例
60
-
61
- ```typescript
62
- // user.ts
63
- import { Api, Get, Post, Query, Data, SnailApi } from "@snail-js/api";
64
-
65
- import { Service } from "./service";
66
-
67
- @Api("user")
68
- class UserApi extends SnailApi {
69
- @Get()
70
- get(@Query("id") id: string) {}
71
-
72
- @Post()
73
- create(@Data() user: User) {}
74
- }
75
- // 创建并导出api
76
- export const userApi = Service.createApi(UserApi);
77
- ```
78
-
79
- 3. 发送请求
80
-
81
- ```typescript
82
- import { userApi } from "./user";
83
-
84
- const { send:getUser, onSuccess, onError, onHitCache } = await userApi.get();
85
-
86
- const data = await getUser("1");
49
+ export const service = new BackEnd();
87
50
  ```
88
51
 
89
- ## `SnailMethod` 实例
90
-
91
- - 调用`Service.createApi(ApiInstance)`后会为`ApiInstance`内被`RequestMethod`(如:@Get、@Post...)装饰的方法创建一个代理,返回一个函数,此函数包含请求参数,调用此函数返回`SnailMethod` 实例
92
-
93
- ### `SnailMethod` 实例方法
94
-
95
- - `send` 发送请求
96
- _异步函数,发送当前请求_
97
- - `onSuccess` 请求成功回调
98
- _注册请求成功事件_
99
- - `onError` 请求失败回调
100
- _注册请求失败事件_
101
- - `onHitCache` 请求命中缓存回调
102
- _注册请求命中缓存事件_
103
- - `onFinish` 请求完成回调
104
- _注册请求完成事件_
105
- - `registerStrategies` 注册策略
106
- _注册方法级策略_
107
-
108
-
109
- ### `SnailMethod` 实例属性
110
-
111
- - response : AxiosResponse
112
- - request : AxiosRequestConfig ,最终请求的 request,这个 request 是被 Versioning 和 Strategy 处理过的
113
- - version : string,最终请求的版本,如果没有开启 Versioning 则为 undefine
114
- - name : string,完整的 SnailMethod 名称,格式为`ServerName.ApiName.MethodName`
115
- - error : Error | null,请求失败的错误信息,无错误为 null
116
-
117
- ### Server 配置
118
-
119
- <table>
120
- <tr>
121
- <th>配置项</th>
122
- <th>类型</th>
123
- <th>是否必须</th>
124
- <th>默认值</th>
125
- <th>说明</th>
126
- </tr>
127
- <tr>
128
- <td>name</td>
129
- <td>string</td>
130
- <td>否</td>
131
- <td>默认使用继承`SnailServer`的类名作为name</td>
132
- <td>server实例唯一标识,请勿与其他server重复</td>
133
- </tr>
134
- <tr>
135
- <td>baseUrl</td>
136
- <td>string</td>
137
- <td>否</td>
138
- <td>'\'</td>
139
- <td>请求后端的api地址前缀,同`axios`的baseUrl</td>
140
- </tr>
141
- <tr>
142
- <td>Versioning</td>
143
- <td><a href="#versioningoption">VersioningOption</a></td>
144
- <td>否</td>
145
- <td>undefine</td>
146
- <td>版本管理器配置,默认不开启</td>
147
- </tr>
148
- <tr>
149
- <td>timeout</td>
150
- <td>number</td>
151
- <td>否</td>
152
- <td>5000</td>
153
- <td>单位:毫秒;全局超时时间,会被 Api 的 timeout 值覆盖</td>
154
- </tr>
155
- <tr>
156
- <td>cacheManage</td>
157
- <td>{type:CacheType,ttl:number}</td>
158
- <td>否</td>
159
- <td>{
160
- type: CacheType.Memory,
161
- ttl: 500
162
- }</td>
163
- <td>缓存管理器,ttl单位为秒</td>
164
- </tr>
165
- <tr>
166
- <td>cacheFor</td>
167
- <td>RequestMethod | RequestMethod[] | 'All' | 'all' </td>
168
- <td>否</td>
169
- <td>Get</td>
170
- <td>要启用缓存的方法,默认仅开启Get缓存</td>
171
- </tr>
172
- <tr>
173
- <td>serverStatusCodeRule</td>
174
- <td><a href="#SnailServerStatusCodeRuleOptions">SnailServerStatusCodeRuleOptions</a></td>
175
- <td>否</td>
176
- <td>undefined</td>
177
- <td>服务端状态码规则,若配置此项,rule函数返回false时会触发错误</td>
178
- </tr>
179
- <tr>
180
- <td>enableLog</td>
181
- <td>boolean</td>
182
- <td>否</td>
183
- <td>false</td>
184
- <td>是否开启日志,用于调试</td>
185
- </tr>
186
- </table>
187
-
188
- ### Api 配置
189
-
190
- - 请使用`@Api()`装饰自定义 Api 类并继承`SnailApi`
191
-
192
- <table>
193
- <tr>
194
- <th>配置项</th>
195
- <th>类型</th>
196
- <th>是否必须</th>
197
- <th>默认值</th>
198
- <th>说明</th>
199
- </tr>
200
- <tr>
201
- <td>name</td>
202
- <td>string</td>
203
- <td>否</td>
204
- <td>默认使用继承`SnailApi`的类名作为name</td>
205
- <td>api实例唯一标识,请勿与其他api重复</td>
206
- </tr>
207
- <tr>
208
- <td>timeout</td>
209
- <td>number</td>
210
- <td>否</td>
211
- <td></td>
212
- <td>请求超时时间;会覆盖Server的timeout设置</td>
213
- </tr>
214
- <tr>
215
- <td>version</td>
216
- <td>string</td>
217
- <td>否</td>
218
- <td></td>
219
- <td>api版本号,会覆盖server的`defaultVersion`配置</td>
220
- </tr>
221
- </table>
222
-
223
- ## 请求方法装饰器
224
-
225
- - 在`Api`类中使用,用于标记请求方法
226
- - 提供 axios 的全部请求方法`Get,Post,Head,Put,Delete,Patch,Options`
227
- - 参数: `path?: string`; 请求端点路径,与`baseUrl,api.url`共同拼接组成最终请求路径
228
-
229
- ## 参数装饰器
230
-
231
- ### 查询参数 `@Query`
232
-
233
- - `@Query(key?:string)`
234
-
235
- - 单个参数使用
236
-
237
- ```typescript
238
- @Api("user")
239
- class UserApi {
240
- @Get()
241
- get(@Query("id") id: string, @Query("sign") sign: string) {}
242
- }
243
- ```
244
-
245
- > 传入 key,标记单个查询参数,拼接到请求`?k1=v1&k2=v2`
246
-
247
- ### 路由参数 `@Params`
248
-
249
- - `@Params(key?:string)`
250
-
251
- - 单个参数使用
252
-
253
- ```typescript
254
- @Api("user/:id/:sign")
255
- class UserApi {
256
- @Get()
257
- get(@Params("id") id: string, @Params("sign") sign: string) {}
258
- }
259
- ```
260
-
261
- > 传入 key,标记单个查询参数,拼接到请求`?k1=v1&k2=v2`
52
+ ### 3. 定义 API
262
53
 
263
- - 对象参数使用
54
+ ```ts
55
+ // user.api.ts
56
+ import { Api, Data, Get, Params, Post, Query } from "@snail-js/api";
57
+ import { service } from "./service";
264
58
 
265
- ```typescript
266
- class RouteParams {
267
- id: string;
268
- sign: string;
269
- }
270
-
271
- @Api("user/:id/:sign")
272
- class UserApi {
273
- @Get()
274
- get(@Params() params: RouteParams) {}
275
- }
276
- ```
277
-
278
- > 不传入 key,会被标记为对象类型查询参数;也能自动拼接到请求
279
-
280
- - 混合使用
281
-
282
- ```typescript
283
- class RouteParams {
284
- id: string;
285
- sign: string;
59
+ export interface User {
60
+ id: number;
61
+ name: string;
286
62
  }
287
63
 
288
- @Api("user/:id/:sign")
64
+ @Api("/user")
289
65
  class UserApi {
290
- @Get()
291
- get(@Params() params: Query, @Params("a") a: number) {}
292
- }
293
- ```
294
-
295
- ### 请求数据
296
-
297
- - `@Data(key?:string)`
298
- - 使用方式和`@Params`相同,也支持混合使用
299
-
300
- ## 策略装饰器`@UseStrategy`
301
-
302
- - `@UseStrategy(...Strategy[])`
303
-
304
- ### 请求策略
305
-
306
- - 在请求发送前执行,后面的策略返回结果会覆盖前面的策略
307
- - 若返回处理后的 request,则使用处理后的 request 发送请求,否则使用原始 request 或上一个策略返回的 request 发送请求
308
-
309
- ```typescript
310
- class CustomStrategy extends Strategy {
311
- applyRequest(request: AxiosRequestConfig) {
312
- request.headers["Access-Token"] = "abcde";
313
- return request;
66
+ /** 方法体永远不会执行,它只用来声明参数类型和返回类型 */
67
+ @Get("/:id")
68
+ getUser(@Params("id") id: string, @Query("withProfile") withProfile?: boolean): Promise<User> {
69
+ return null!;
314
70
  }
315
- }
316
71
 
317
- // 用在Snail,全局的请求策略
318
-
319
- @Server({
320
- baseURL: "/api",
321
- timeout: 5000,
322
- })
323
- @UseStrategy(CustomStrategy)
324
- class BackEnd extends Snail<ShanheResponse> {}
325
- export const Service = new BackEnd();
326
- // 创建Service实例后再注册策略
327
- Service.registerStrategies(CustomStrategy);
328
-
329
- // 用在Api, 当Api下的方法请求时生效
330
- @Api("test")
331
- @UseStrategy(CustomStrategy)
332
- class Test {}
333
- const TestApi = Service.createApi(Test);
334
- // 创建Api实例后再注册策略
335
- TestApi.registerStrategies(CustomStrategy);
336
-
337
- // 用在方法,此方法请求时生效
338
- @Api("test")
339
- @UseStrategy(CustomStrategy)
340
- class Test {
341
- @Get()
342
- @UseStrategy(CustomStrategy)
343
- get() {}
344
- }
345
- // 发送请求前注册策略
346
- const TestApi = Service.createApi(Test);
347
- const getSomething = TestApi.get();
348
- { send, registerStrategies } = getSomething;
349
- getSomething.registerStrategies(CustomStrategy);
350
-
351
-
352
- ```
353
-
354
- ### 响应策略
355
-
356
- - 在收到服务器响应后执行
357
- - 若返回处理后的 response,则使用处理后的 response 进行下一个策略或返回,否则使用原始 response 或上一个策略返回的 response 返回
358
-
359
- ```typescript
360
- // 如何定义
361
- class CustomStrategy extends Strategy {
362
- applyResponse(response: AxiosResponse) {
363
- const { status } = response;
364
- if (status == 200) {
365
- // do something
366
- }
367
- return response;
72
+ @Post("/")
73
+ createUser(@Data() payload: Omit<User, "id">): Promise<User> {
74
+ return null!;
368
75
  }
369
76
  }
370
- ```
371
77
 
372
- ## 版本管理装饰器`@Versioning`和`@Version`
373
-
374
- ### 版本管理器`@Versioning(VersioningOption)`
375
-
376
- - 全局管理版本
377
-
378
- ```typescript
379
- @Server({
380
- baseURL: "/api",
381
- timeout: 5000,
382
- })
383
- @Versioning({
384
- type: VersioningType.Header,
385
- defaultVersion: "0.1.0",
386
- })
387
- class BackEnd extends Snail<ShanheResponse> {}
388
-
389
- export const Service = new BackEnd();
78
+ export const userApi = service.createApi(UserApi);
390
79
  ```
391
80
 
392
- #### <a id="versioningoption">`VersioningOption`</a>类型
81
+ ### 4. 发起请求
393
82
 
394
- ```typescript
395
- export enum VersioningType {
396
- Uri,
397
- Header,
398
- Query,
399
- Custom,
400
- }
401
-
402
- interface VersioningCommonOption {
403
- defaultVersion: string;
404
- }
83
+ ```ts
84
+ // 调用被装饰的方法不会发送请求,它只创建一个待发送的请求对象
85
+ const method = userApi.getUser("1");
86
+ const { data, code, message, fromCache } = await method.send();
405
87
 
406
- export interface VersioningUriOption extends VersioningCommonOption {
407
- type: VersioningType.Uri;
408
- prefix?: string;
409
- }
410
-
411
- export interface VersioningHeaderOption extends VersioningCommonOption {
412
- type: VersioningType.Header;
413
- header?: string;
414
- }
415
-
416
- export interface VersioningQueryOption extends VersioningCommonOption {
417
- type: VersioningType.Query;
418
- key?: string;
419
- }
420
-
421
- export interface VersioningCustomOption extends VersioningCommonOption {
422
- type: VersioningType.Custom;
423
- extractor: (requestOptions: unknown) => {
424
- url: string;
425
- headers: Record<string, any>;
426
- };
427
- }
428
-
429
- export type VersioningOption =
430
- | VersioningUriOption
431
- | VersioningHeaderOption
432
- | VersioningQueryOption
433
- | VersioningCustomOption;
88
+ // data 已经被推断为 User —— 无需手写泛型,也不会有 any
89
+ console.log(data.name);
434
90
  ```
435
91
 
436
- ### <a id="SnailServerStatusCodeRuleOptions">SnailServerStatusCodeRuleOptions</a> 类型
92
+ 单个方法实例可以重复使用,参数可以在 `send()` 时覆盖:
437
93
 
438
- ```typescript
439
- export class SnailServerStatusCodeRuleOptions {
440
- // 通常服务端会返回一个状态码,当状态码不符合预期时,会抛出错误
441
- // 可以使用此选项来定义服务端状态码的规则
442
- // 当rule函数返回false时,会触发错误
443
- rule: (statusCode: number) => boolean;
444
- // response.data中服务端状态码的key,默认为code
445
- key?: string;
446
- }
447
- ```
448
-
449
- ### 临时版本修改器`@Version`
450
-
451
- - 临时改变方法请求的版本
452
-
453
- ```typescript
454
- @Api("test")
455
- class Test {
456
- @Get("HelloWorld")
457
- @Version("0.2.0")
458
- test() {}
459
- }
94
+ ```ts
95
+ const method = userApi.getUser();
96
+ await method.send("1");
97
+ await method.send("2");
460
98
  ```
461
99
 
462
- > 临时改变 api 版本,便于测试
463
-
464
- ### 缓存装饰器`@HitSource`
465
-
466
- - `@HitSource(name:string)`
467
- - 为被装饰的方法设置缓存失效源,当设置的名称方法被调用且正常响应时,被装饰的方法缓存失效
468
- - name 格式为:`serverName:apiName:methodName`
469
- > 注意:若您配置了 SnailServer/SnailApi 的 name 选项,请使用此 name 作为名称,否则使用类名作为名称
100
+ ## 返回结构
470
101
 
471
- ```typescript
472
- @Api("test", { name: "api1" })
473
- @HitSource("api1")
474
- class Test {
475
- @Get("HelloWorld")
476
- @HitSource("api1.test2")
477
- test1() {}
102
+ 后端返回的数据默认遵循下面的结构:
478
103
 
479
- @Post()
480
- test2() {}
481
-
482
- @Get()
483
- // Test类下任何请求成功,这个方法的缓存都会失效
484
- @HitSource("api1")
485
- test3() {}
486
- }
104
+ ```json
105
+ { "code": 0, "message": "ok", "data": {} }
487
106
  ```
488
107
 
489
- > 当请求`[Post]test`成功时,`[Get]test/HelloWorld`的缓存失效
490
- > 默认仅 Get 方法会进行缓存 ing 缓存,若要开启其他方法的缓存,请使用`@Server({cacheFor:'all'})`配置
491
-
492
- > `test3`方法请求成功时,不缓存
493
-
494
- > 注意:要使用缓存,请配置`@Server({CacheManage})`缓存管理器
495
-
496
- ### 上传进度装饰器`@UploadProgress`
497
-
498
- - `@UploadProgress((progressEvent: AxiosProgressEvent) => void)`
499
-
500
- ### 下载进度装饰器`@DownloadProgress`
501
-
502
- - `@DownloadProgress((progressEvent: AxiosProgressEvent) => void)`
503
-
504
- ## Server Send Event 服务端推送
505
-
506
- ### 创建 sse 端点
507
-
508
- ```typescript
509
- @Sse("sse")
510
- class ServerSend extend SnailSse {
511
-
512
- @OnSseOpen()
513
- handleOpen(event: Event) {
514
- console.log("sse-open:", event);
515
- }
516
-
517
- @OnSseError()
518
- handleError(event: Event) {
519
- console.log("sse-error:", event);
520
- }
521
-
522
- // 处理默认message事件
523
- @SseEvent()
524
- handleEvent(event: MessageEvent) {
525
- console.log("sse-event[message]:", event.data);
526
- }
108
+ 三个字段名都可以通过 `@Server({ codeKey, messageKey, dataKey })` 修改;
109
+ 结构本身可以通过 `declare module` 重定义:
527
110
 
528
- // 处理自定义名称事件
529
- @SseEvent("chunk")
530
- handleEvent(event: Event) {
531
- console.log("sse-event[chunk]:", event);
111
+ ```ts
112
+ declare module "@snail-js/api" {
113
+ interface SnailEnvelopeSchema {
114
+ status: number;
115
+ msg: string;
116
+ result: unknown;
532
117
  }
533
118
  }
534
-
535
- export const Sse = Service.createSse(ServerSend);
536
119
  ```
537
120
 
538
- ### 服务端推送装饰器`@Sse`
539
-
540
- - `@Sse(path:string,options?:{withCredentials?: boolean,version?: string;})`
541
- - 创建一个服务端推送连接,返回一个函数,用于打开 sse 连接
542
- - 返回的打开函数调用后会返回`{eventSource:EventSource,close:function}`
543
- - eventSource: sse 连接实例
544
- - close: 关闭此 sse 连接的方法
545
-
546
- ### 注册`onopen`装饰器`@OnSseOpen`
547
-
548
- - 当`@Sse`装饰的方法被调用时,将`@OnSseOpen`装饰的方法注册为`@Sse`装饰的方法返回的`EventSource`实例`onopen`处理函数
549
-
550
- ### 注册`onerror`装饰器`@OnSseError`
121
+ `send()` 返回一个 `SnailResult`,而不是裸的信封:
551
122
 
552
- - 当`@Sse`装饰的方法被调用时,将`@OnSseError`装饰的方法注册为`@Sse`装饰的方法返回的`EventSource`实例`onerror`处理函数
123
+ | 字段 | 说明 |
124
+ | --- | --- |
125
+ | `data` | **已解包**的业务数据,绝大多数情况下你只需要它 |
126
+ | `envelope` | 完整信封 `{ code, message, data }` |
127
+ | `response` | 原始 axios 响应 |
128
+ | `code` / `message` | 业务状态码与消息 |
129
+ | `fromCache` | 是否来自缓存 |
130
+ | `config` | 最终生效的请求配置 |
553
131
 
554
- ### 事件处理装饰器`@SseEvent`
132
+ ## 插件
555
133
 
556
- - `@SseEvent(eventName?:string)`
557
- - 未传入`eventName`,默认注册为`message`事件处理器
558
- - 传入`eventName`,注册为对应名称的事件处理器
134
+ 插件从子路径按需引入,未使用的插件会被打包器完全剔除:
559
135
 
560
- ---
136
+ ```ts
137
+ import { Cache, Interceptor, RequestPool, Versioning } from "@snail-js/api/plugins";
561
138
 
562
- ## TypeScript 支持
563
-
564
- ### 默认返回类型
565
-
566
- ```typescript
567
- export type StandardResponseData<
568
- T extends ResponseJsonData = Record<string, any>
569
- > = {
570
- code: number;
571
- message: string;
572
- data: T;
573
- };
139
+ service
140
+ .use(Interceptor())
141
+ .use(Versioning({ type: "header", defaultVersion: "1.0.0" }))
142
+ .use(Cache({ ttl: 60, l2: "localStorage" }))
143
+ .use(RequestPool({ concurrency: 4, maxQueue: 50, queueTimeout: 10000 }));
574
144
  ```
575
145
 
576
- ### 定义返回类型
146
+ `use()` 是同步且可链式调用的,插件名重复或依赖缺失会在调用时立即抛错。
577
147
 
578
- 1. 定义后端标准数据格式
579
-
580
- ```typescript
581
- export class CustomResponse {
582
- status_code: number;
583
- msg: string;
584
- }
585
- ```
148
+ 请求池用来给并发设上限:浏览器的队列是先进先出、不可见、无法排优先级的,
149
+ 一个页面的并发爆发会把用户真正在等的那条请求挤到后面。它排在缓存**之后**,
150
+ 所以缓存能答的请求不会占用并发额度。
586
151
 
587
- 2. 创建时应用格式
152
+ ## 请求策略
588
153
 
589
- ```typescript
590
- // service.ts
591
- import { SnailServer, Server } from "@snail-js/api";
154
+ ```ts
155
+ import { useDownload, useRequest } from "@snail-js/api/strategies";
592
156
 
593
- @Server({
594
- baseURL: "/api",
595
- timeout: 5000,
596
- })
597
- class BackEnd extends SnailServer<CustomResponse> {}
157
+ const { loading, data, error, send, bind } = useRequest(userApi.getUser);
158
+ await send("1");
598
159
 
599
- export const Service = new BackEnd();
160
+ // 下载:只 await「换取临时链接」的那次请求,文件本身交给浏览器原生下载
161
+ const { download } = useDownload(reportApi.create);
162
+ await download({ from: "2026-01-01" });
600
163
  ```
601
164
 
602
- 3. 调用 API 时携带数据格式
165
+ 默认适配 Vue 的响应式状态(`ref`);React 用户请从
166
+ `@snail-js/api/strategies/react` 引入,无框架场景请从
167
+ `@snail-js/api/strategies/plain` 引入。
603
168
 
604
- ```typescript
605
- import { userApi } from "./user";
169
+ 不想把整个文件读进 JavaScript 内存时用 `useDownload`:它 await 的只是让服务端
170
+ 生成临时下载链接的那次请求,随后用 `<a>` 触发浏览器原生下载 —— 有进度、可断点
171
+ 续传、不占内存。`useDownload` 属于策略而非插件,因为它是一次明确的用户动作,
172
+ 而不是作用于所有请求的横切关注点。
606
173
 
607
- class User {
608
- id: number;
609
- name: string;
610
- tel: string;
611
- age: number;
612
- }
613
-
614
- const getUser = userApi.get<User>();
615
- const { send } = getUser;
616
-
617
- const res = await send("1");
618
-
619
- // 默认情况,以data为key存储数据
620
- // res.data => CustomResponse & { data : User}
621
- ```
622
-
623
- > API 被调用的返回格式
174
+ ## 文档
624
175
 
625
- ```typescript
626
- const getUser = userApi.get<User>();
627
- const { send } = getUser;
628
- const res = await send("1");
176
+ 完整文档:<https://snail-js.github.io/api>
629
177
 
630
- // res.data => CustomResponse & { data: User }
631
-
632
- const getUser = userApi.get<Blob>();
633
- const { send } = getUser;
634
- const res = await send("1");
635
- // res => AxiosResponse<Blob>
636
- ```
637
-
638
- > `data: T`,后端响应数据;默认为`ResponseData<T = any>`类型;可由用户自定义修改
639
-
640
- > `error: null | Error` ; 请求过程中的错误包含在此,可先判断 error 是否为 null 再进行数据处理
641
-
642
- > `hitCache?: boolean`; 标识请求是否击中缓存;若从缓存获得数据,则不会发送请求。
643
-
644
- 4. 若后端返回数据不是以 data 为 key 包含数据
645
-
646
- ```typescript
647
- @Server({
648
- baseURL: "/api",
649
- timeout: 5000,
650
- })
651
- class BackEnd extends Snail<CustomResponse, "records"> {}
652
-
653
- const res = await userApi.get<User>();
654
- // 自定义数据key
655
- // res.data => CustomResponse & { records : User}
656
- ```
178
+ - [快速开始](https://snail-js.github.io/api/guide/getting-started)
179
+ - [装饰器参考](https://snail-js.github.io/api/guide/decorators)
180
+ - [插件生命周期](https://snail-js.github.io/api/guide/plugin-lifecycle)([English](https://snail-js.github.io/api/guide/plugin-lifecycle_EN)
181
+ - [编写插件](https://snail-js.github.io/api/guide/plugin-authoring)
182
+ - [从 0.1.x 迁移](https://snail-js.github.io/api/guide/migration)
657
183
 
658
- ### 非 json 数据的返回
184
+ ## 设计说明
659
185
 
660
- - 若后端返回的 content-type 不是 json 类型,send 方法返回的将是`AxiosResponse`
661
- - 若后端返回的 content-type 是 json 类型,send 方法返回的将是`AxiosResponse.data`
186
+ 核心只负责三件事,其余全部是插件:
662
187
 
663
- ### 代码仓库
188
+ 1. 装饰器写入的元数据;
189
+ 2. 请求管线;
190
+ 3. 插件生命周期(Koa 风格中间件 + 双向洋葱模型)。
664
191
 
665
- <p>
666
- <a href="https://gitee.com/limich/snail">
667
- <img src="https://img.shields.io/badge/snail-js?style=flat&label=gitee&labelColor=F56C6C&link=https%3A%2F%2Fgitee.com%2Flimich%2Fsnail"></img>
668
- </a>
669
- </p>
670
- <p>
671
- <a href="https://github.com/limingchang/snail">
672
- <img src="https://img.shields.io/badge/snail-js?style=flat&label=github&labelColor=F56C6C&link=https%3A%2F%2Fgihub.com%2Flimingchang%2Fsnail"></img>
673
- </a>
674
- </p>
192
+ 内置插件使用的公开 API 与第三方插件完全相同 —— 不存在内部特权通道。如果你在编写插件,
193
+ 请阅读[插件生命周期](https://snail-js.github.io/api/guide/plugin-lifecycle)(英文原文见
194
+ [Plugin lifecycle](https://snail-js.github.io/api/guide/plugin-lifecycle_EN))。
675
195
 
676
- ### 作者
196
+ ## License
677
197
 
678
- - mc.lee
198
+ [MIT](./LICENSE)