@mx-space/api-client 0.6.3 → 0.7.1

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 (334) hide show
  1. package/adaptors/axios.ts +38 -0
  2. package/adaptors/umi-request.ts +33 -0
  3. package/build/index.cjs.js +28 -27
  4. package/build/index.cjs.js.map +1 -1
  5. package/build/index.cjs.min.js +1 -1
  6. package/build/index.cjs.min.js.map +1 -1
  7. package/build/index.esm.js +29 -27
  8. package/build/index.esm.js.map +1 -1
  9. package/build/index.esm.min.js +1 -1
  10. package/build/index.esm.min.js.map +1 -1
  11. package/build/index.umd.js +28 -27
  12. package/build/index.umd.js.map +1 -1
  13. package/build/index.umd.min.js +1 -1
  14. package/build/index.umd.min.js.map +1 -1
  15. package/controllers/aggregate.ts +69 -0
  16. package/controllers/base.ts +32 -0
  17. package/controllers/category.ts +118 -0
  18. package/controllers/comment.ts +68 -0
  19. package/controllers/index.ts +66 -0
  20. package/controllers/link.ts +28 -0
  21. package/controllers/note.ts +96 -0
  22. package/controllers/page.ts +64 -0
  23. package/controllers/post.ts +94 -0
  24. package/controllers/project.ts +27 -0
  25. package/controllers/recently.ts +53 -0
  26. package/controllers/say.ts +40 -0
  27. package/controllers/search.ts +108 -0
  28. package/controllers/snippet.ts +36 -0
  29. package/controllers/user.ts +51 -0
  30. package/core/attach-request.ts +43 -0
  31. package/core/client.ts +239 -0
  32. package/core/error.ts +10 -0
  33. package/core/index.ts +2 -0
  34. package/coverage/clover.xml +570 -0
  35. package/coverage/coverage-final.json +30 -0
  36. package/coverage/lcov-report/adaptors/axios.ts.html +199 -0
  37. package/coverage/lcov-report/adaptors/index.html +131 -0
  38. package/coverage/lcov-report/adaptors/umi-request.ts.html +184 -0
  39. package/coverage/lcov-report/auto-bind.ts.html +229 -0
  40. package/coverage/lcov-report/base.css +224 -0
  41. package/coverage/lcov-report/block-navigation.js +87 -0
  42. package/coverage/lcov-report/controllers/aggregate.ts.html +292 -0
  43. package/coverage/lcov-report/controllers/base.ts.html +181 -0
  44. package/coverage/lcov-report/controllers/category.ts.html +439 -0
  45. package/coverage/lcov-report/controllers/comment.ts.html +289 -0
  46. package/coverage/lcov-report/controllers/index.html +326 -0
  47. package/coverage/lcov-report/controllers/index.ts.html +283 -0
  48. package/coverage/lcov-report/controllers/link.ts.html +169 -0
  49. package/coverage/lcov-report/controllers/note.ts.html +373 -0
  50. package/coverage/lcov-report/controllers/page.ts.html +277 -0
  51. package/coverage/lcov-report/controllers/post.ts.html +367 -0
  52. package/coverage/lcov-report/controllers/project.ts.html +166 -0
  53. package/coverage/lcov-report/controllers/recently.ts.html +244 -0
  54. package/coverage/lcov-report/controllers/say.ts.html +205 -0
  55. package/coverage/lcov-report/controllers/search.ts.html +409 -0
  56. package/coverage/lcov-report/controllers/snippet.ts.html +193 -0
  57. package/coverage/lcov-report/controllers/user.ts.html +238 -0
  58. package/coverage/lcov-report/core/attach-request.ts.html +214 -0
  59. package/coverage/lcov-report/core/client.ts.html +802 -0
  60. package/coverage/lcov-report/core/error.ts.html +115 -0
  61. package/coverage/lcov-report/core/index.html +161 -0
  62. package/coverage/lcov-report/core/index.ts.html +91 -0
  63. package/coverage/lcov-report/favicon.png +0 -0
  64. package/coverage/lcov-report/index.html +191 -0
  65. package/coverage/lcov-report/index.ts.html +244 -0
  66. package/coverage/lcov-report/models/aggregate.ts.html +298 -0
  67. package/coverage/lcov-report/models/category.ts.html +160 -0
  68. package/coverage/lcov-report/models/index.html +131 -0
  69. package/coverage/lcov-report/prettify.css +1 -0
  70. package/coverage/lcov-report/prettify.js +2 -0
  71. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  72. package/coverage/lcov-report/sorter.js +196 -0
  73. package/coverage/lcov-report/utils/auto-bind.ts.html +229 -0
  74. package/coverage/lcov-report/utils/index.html +131 -0
  75. package/coverage/lcov-report/utils/index.ts.html +244 -0
  76. package/coverage/lcov.info +1164 -0
  77. package/dtos/comment.ts +9 -0
  78. package/esm/adaptors/axios.d.ts +3 -3
  79. package/esm/adaptors/axios.js +5 -17
  80. package/esm/adaptors/axios.js.map +1 -1
  81. package/esm/adaptors/umi-request.d.ts +3 -3
  82. package/esm/adaptors/umi-request.js +1 -0
  83. package/esm/adaptors/umi-request.js.map +1 -1
  84. package/esm/controllers/aggregate.d.ts +32 -10
  85. package/esm/controllers/aggregate.js +2 -2
  86. package/esm/controllers/aggregate.js.map +1 -1
  87. package/esm/controllers/base.d.ts +19 -7
  88. package/esm/controllers/base.js +1 -1
  89. package/esm/controllers/base.js.map +1 -1
  90. package/esm/controllers/category.d.ts +68 -12
  91. package/esm/controllers/category.js +3 -3
  92. package/esm/controllers/category.js.map +1 -1
  93. package/esm/controllers/comment.d.ts +49 -12
  94. package/esm/controllers/comment.js +1 -1
  95. package/esm/controllers/comment.js.map +1 -1
  96. package/esm/controllers/index.js.map +1 -1
  97. package/esm/controllers/link.d.ts +9 -2
  98. package/esm/controllers/link.js +1 -1
  99. package/esm/controllers/link.js.map +1 -1
  100. package/esm/controllers/note.d.ts +48 -13
  101. package/esm/controllers/note.js +2 -2
  102. package/esm/controllers/note.js.map +1 -1
  103. package/esm/controllers/page.d.ts +28 -9
  104. package/esm/controllers/page.js +2 -2
  105. package/esm/controllers/page.js.map +1 -1
  106. package/esm/controllers/post.d.ts +30 -12
  107. package/esm/controllers/post.js +2 -2
  108. package/esm/controllers/post.js.map +1 -1
  109. package/esm/controllers/project.d.ts +8 -2
  110. package/esm/controllers/project.js +1 -1
  111. package/esm/controllers/project.js.map +1 -1
  112. package/esm/controllers/recently.d.ts +35 -7
  113. package/esm/controllers/recently.js +1 -1
  114. package/esm/controllers/recently.js.map +1 -1
  115. package/esm/controllers/say.d.ts +20 -5
  116. package/esm/controllers/say.js +1 -1
  117. package/esm/controllers/say.js.map +1 -1
  118. package/esm/controllers/search.d.ts +178 -14
  119. package/esm/controllers/search.js +3 -3
  120. package/esm/controllers/search.js.map +1 -1
  121. package/esm/controllers/snippet.d.ts +21 -6
  122. package/esm/controllers/snippet.js +1 -1
  123. package/esm/controllers/snippet.js.map +1 -1
  124. package/esm/controllers/user.d.ts +33 -7
  125. package/esm/controllers/user.js +1 -1
  126. package/esm/controllers/user.js.map +1 -1
  127. package/esm/core/attach-request.d.ts +1 -1
  128. package/esm/core/attach-request.js.map +1 -1
  129. package/esm/core/client.d.ts +12 -28
  130. package/esm/core/client.js +23 -21
  131. package/esm/core/client.js.map +1 -1
  132. package/esm/core/error.js.map +1 -1
  133. package/esm/core/index.js.map +1 -1
  134. package/esm/dtos/comment.js.map +1 -1
  135. package/esm/index.d.ts +2 -1
  136. package/esm/index.js +1 -1
  137. package/esm/index.js.map +1 -1
  138. package/esm/interfaces/adapter.d.ts +9 -8
  139. package/esm/interfaces/adapter.js.map +1 -1
  140. package/esm/interfaces/client.d.ts +1 -1
  141. package/esm/interfaces/client.js.map +1 -1
  142. package/esm/interfaces/controller.js.map +1 -1
  143. package/esm/interfaces/instance.js.map +1 -1
  144. package/esm/interfaces/options.js.map +1 -1
  145. package/esm/interfaces/params.js.map +1 -1
  146. package/esm/interfaces/request.d.ts +22 -13
  147. package/esm/interfaces/request.js.map +1 -1
  148. package/esm/interfaces/types.d.ts +2 -0
  149. package/esm/interfaces/types.js +2 -0
  150. package/esm/interfaces/types.js.map +1 -0
  151. package/esm/models/aggregate.js.map +1 -1
  152. package/esm/models/base.js.map +1 -1
  153. package/esm/models/category.js.map +1 -1
  154. package/esm/models/comment.js.map +1 -1
  155. package/esm/models/index.js.map +1 -1
  156. package/esm/models/link.js.map +1 -1
  157. package/esm/models/note.js.map +1 -1
  158. package/esm/models/page.js.map +1 -1
  159. package/esm/models/post.js.map +1 -1
  160. package/esm/models/project.js.map +1 -1
  161. package/esm/models/recently.js.map +1 -1
  162. package/esm/models/say.js.map +1 -1
  163. package/esm/models/setting.js.map +1 -1
  164. package/esm/models/snippet.js.map +1 -1
  165. package/esm/models/user.js.map +1 -1
  166. package/esm/utils/auto-bind.js.map +1 -1
  167. package/esm/utils/index.d.ts +1 -1
  168. package/esm/utils/index.js +2 -2
  169. package/esm/utils/index.js.map +1 -1
  170. package/index.ts +13 -0
  171. package/interfaces/adapter.ts +35 -0
  172. package/interfaces/client.ts +6 -0
  173. package/interfaces/controller.ts +5 -0
  174. package/interfaces/instance.ts +8 -0
  175. package/interfaces/options.ts +1 -0
  176. package/interfaces/params.ts +4 -0
  177. package/interfaces/request.ts +82 -0
  178. package/interfaces/types.ts +3 -0
  179. package/jest.config.js +12 -0
  180. package/lib/adaptors/axios.d.ts +3 -3
  181. package/lib/adaptors/axios.js +5 -17
  182. package/lib/adaptors/axios.js.map +1 -1
  183. package/lib/adaptors/umi-request.d.ts +3 -3
  184. package/lib/adaptors/umi-request.js +1 -0
  185. package/lib/adaptors/umi-request.js.map +1 -1
  186. package/lib/controllers/aggregate.d.ts +32 -10
  187. package/lib/controllers/aggregate.js.map +1 -1
  188. package/lib/controllers/base.d.ts +19 -7
  189. package/lib/controllers/base.js.map +1 -1
  190. package/lib/controllers/category.d.ts +68 -12
  191. package/lib/controllers/category.js +1 -1
  192. package/lib/controllers/category.js.map +1 -1
  193. package/lib/controllers/comment.d.ts +49 -12
  194. package/lib/controllers/comment.js.map +1 -1
  195. package/lib/controllers/index.js.map +1 -1
  196. package/lib/controllers/link.d.ts +9 -2
  197. package/lib/controllers/link.js.map +1 -1
  198. package/lib/controllers/note.d.ts +48 -13
  199. package/lib/controllers/note.js +1 -1
  200. package/lib/controllers/note.js.map +1 -1
  201. package/lib/controllers/page.d.ts +28 -9
  202. package/lib/controllers/page.js +1 -1
  203. package/lib/controllers/page.js.map +1 -1
  204. package/lib/controllers/post.d.ts +30 -12
  205. package/lib/controllers/post.js +1 -1
  206. package/lib/controllers/post.js.map +1 -1
  207. package/lib/controllers/project.d.ts +8 -2
  208. package/lib/controllers/project.js.map +1 -1
  209. package/lib/controllers/recently.d.ts +35 -7
  210. package/lib/controllers/recently.js.map +1 -1
  211. package/lib/controllers/say.d.ts +20 -5
  212. package/lib/controllers/say.js.map +1 -1
  213. package/lib/controllers/search.d.ts +178 -14
  214. package/lib/controllers/search.js +2 -2
  215. package/lib/controllers/search.js.map +1 -1
  216. package/lib/controllers/snippet.d.ts +21 -6
  217. package/lib/controllers/snippet.js.map +1 -1
  218. package/lib/controllers/user.d.ts +33 -7
  219. package/lib/controllers/user.js.map +1 -1
  220. package/lib/core/attach-request.d.ts +1 -1
  221. package/lib/core/attach-request.js.map +1 -1
  222. package/lib/core/client.d.ts +12 -28
  223. package/lib/core/client.js +21 -20
  224. package/lib/core/client.js.map +1 -1
  225. package/lib/core/error.js.map +1 -1
  226. package/lib/core/index.js.map +1 -1
  227. package/lib/dtos/comment.js.map +1 -1
  228. package/lib/index.d.ts +2 -1
  229. package/lib/index.js +1 -2
  230. package/lib/index.js.map +1 -1
  231. package/lib/interfaces/adapter.d.ts +9 -8
  232. package/lib/interfaces/adapter.js.map +1 -1
  233. package/lib/interfaces/client.d.ts +1 -1
  234. package/lib/interfaces/client.js.map +1 -1
  235. package/lib/interfaces/controller.js.map +1 -1
  236. package/lib/interfaces/instance.js.map +1 -1
  237. package/lib/interfaces/options.js.map +1 -1
  238. package/lib/interfaces/params.js.map +1 -1
  239. package/lib/interfaces/request.d.ts +22 -13
  240. package/lib/interfaces/request.js.map +1 -1
  241. package/lib/interfaces/types.d.ts +2 -0
  242. package/lib/interfaces/types.js +3 -0
  243. package/lib/interfaces/types.js.map +1 -0
  244. package/lib/models/aggregate.js.map +1 -1
  245. package/lib/models/base.js.map +1 -1
  246. package/lib/models/category.js.map +1 -1
  247. package/lib/models/comment.js.map +1 -1
  248. package/lib/models/index.js.map +1 -1
  249. package/lib/models/link.js.map +1 -1
  250. package/lib/models/note.js.map +1 -1
  251. package/lib/models/page.js.map +1 -1
  252. package/lib/models/post.js.map +1 -1
  253. package/lib/models/project.js.map +1 -1
  254. package/lib/models/recently.js.map +1 -1
  255. package/lib/models/say.js.map +1 -1
  256. package/lib/models/setting.js.map +1 -1
  257. package/lib/models/snippet.js.map +1 -1
  258. package/lib/models/user.js.map +1 -1
  259. package/lib/utils/auto-bind.js.map +1 -1
  260. package/lib/utils/index.d.ts +1 -1
  261. package/lib/utils/index.js +2 -2
  262. package/lib/utils/index.js.map +1 -1
  263. package/models/aggregate.ts +71 -0
  264. package/models/base.ts +43 -0
  265. package/models/category.ts +25 -0
  266. package/models/comment.ts +37 -0
  267. package/models/index.ts +14 -0
  268. package/models/link.ts +23 -0
  269. package/models/note.ts +37 -0
  270. package/models/page.ts +20 -0
  271. package/models/post.ts +16 -0
  272. package/models/project.ts +12 -0
  273. package/models/recently.ts +7 -0
  274. package/models/say.ts +7 -0
  275. package/models/setting.ts +68 -0
  276. package/models/snippet.ts +18 -0
  277. package/models/user.ts +27 -0
  278. package/package.json +10 -44
  279. package/tsconfig.build.json +6 -0
  280. package/tsconfig.cjs.json +7 -0
  281. package/tsconfig.json +13 -11
  282. package/tsconfig.types.json +18 -0
  283. package/types/adaptors/axios.d.ts +3 -0
  284. package/types/adaptors/umi-request.d.ts +3 -0
  285. package/types/controllers/aggregate.d.ts +64 -0
  286. package/types/controllers/base.d.ts +39 -0
  287. package/types/controllers/category.d.ts +114 -0
  288. package/types/controllers/comment.d.ts +81 -0
  289. package/types/controllers/index.d.ts +16 -0
  290. package/types/controllers/link.d.ts +16 -0
  291. package/types/controllers/note.d.ts +94 -0
  292. package/types/controllers/page.d.ts +59 -0
  293. package/types/controllers/post.d.ts +72 -0
  294. package/types/controllers/project.d.ts +15 -0
  295. package/types/controllers/recently.d.ts +61 -0
  296. package/types/controllers/say.d.ts +37 -0
  297. package/types/controllers/search.d.ts +247 -0
  298. package/types/controllers/snippet.d.ts +33 -0
  299. package/types/controllers/user.d.ts +54 -0
  300. package/types/core/attach-request.d.ts +2 -0
  301. package/types/core/client.d.ts +29 -0
  302. package/types/core/error.d.ts +6 -0
  303. package/types/core/index.d.ts +2 -0
  304. package/types/dtos/comment.d.ts +6 -0
  305. package/types/index.d.ts +7 -0
  306. package/types/interfaces/adapter.d.ts +14 -0
  307. package/types/interfaces/client.d.ts +5 -0
  308. package/types/interfaces/controller.d.ts +4 -0
  309. package/types/interfaces/instance.d.ts +7 -0
  310. package/types/interfaces/options.d.ts +1 -0
  311. package/types/interfaces/params.d.ts +4 -0
  312. package/types/interfaces/request.d.ts +43 -0
  313. package/types/interfaces/types.d.ts +2 -0
  314. package/types/models/aggregate.d.ts +53 -0
  315. package/types/models/base.d.ts +37 -0
  316. package/types/models/category.d.ts +22 -0
  317. package/types/models/comment.d.ts +34 -0
  318. package/types/models/index.d.ts +14 -0
  319. package/types/models/link.d.ts +20 -0
  320. package/types/models/note.d.ts +30 -0
  321. package/types/models/page.d.ts +14 -0
  322. package/types/models/post.d.ts +15 -0
  323. package/types/models/project.d.ts +11 -0
  324. package/types/models/recently.d.ts +6 -0
  325. package/types/models/say.d.ts +6 -0
  326. package/types/models/setting.d.ts +66 -0
  327. package/types/models/snippet.d.ts +16 -0
  328. package/types/models/user.d.ts +21 -0
  329. package/types/utils/auto-bind.d.ts +4 -0
  330. package/types/utils/index.d.ts +5 -0
  331. package/utils/auto-bind.ts +48 -0
  332. package/utils/index.ts +53 -0
  333. package/build/index.d.ts +0 -932
  334. package/readme.md +0 -84
@@ -0,0 +1,94 @@
1
+ import { IRequestAdapter } from '~/interfaces/adapter'
2
+ import { IController } from '~/interfaces/controller'
3
+ import { IRequestHandler, RequestProxyResult } from '~/interfaces/request'
4
+ import { SelectFields } from '~/interfaces/types'
5
+ import { PaginateResult } from '~/models/base'
6
+ import { PostModel } from '~/models/post'
7
+ import { autoBind } from '~/utils/auto-bind'
8
+ import { HTTPClient } from '../core/client'
9
+
10
+ declare module '../core/client' {
11
+ interface HTTPClient<
12
+ T extends IRequestAdapter = IRequestAdapter,
13
+ ResponseWrapper = unknown,
14
+ > {
15
+ post: PostController<ResponseWrapper>
16
+ }
17
+ }
18
+
19
+ export type PostListOptions = {
20
+ select?: SelectFields<keyof PostModel>
21
+ year?: number
22
+ sortBy?: 'categoryId' | 'title' | 'created' | 'modified'
23
+ sortOrder?: 1 | -1
24
+ }
25
+
26
+ export class PostController<ResponseWrapper> implements IController {
27
+ constructor(private client: HTTPClient) {
28
+ autoBind(this)
29
+ }
30
+
31
+ base = 'posts'
32
+
33
+ name = 'post'
34
+
35
+ public get proxy(): IRequestHandler<ResponseWrapper> {
36
+ return this.client.proxy(this.base)
37
+ }
38
+
39
+ /**
40
+ * 获取文章列表分页
41
+ * @param page
42
+ * @param perPage
43
+ * @returns
44
+ */
45
+ getList(page = 1, perPage = 10, options: PostListOptions = {}) {
46
+ const { select, sortBy, sortOrder, year } = options
47
+ return this.proxy.get<PaginateResult<PostModel>>({
48
+ params: {
49
+ page,
50
+ size: perPage,
51
+ select: select?.join(' '),
52
+ sortBy,
53
+ sortOrder,
54
+ year,
55
+ },
56
+ })
57
+ }
58
+
59
+ /**
60
+ * 根据分类和路径查找文章
61
+ * @param categoryName
62
+ * @param slug
63
+ */
64
+ getPost(
65
+ categoryName: string,
66
+ slug: string,
67
+ ): RequestProxyResult<PostModel, ResponseWrapper>
68
+ /**
69
+ * 根据 ID 查找文章
70
+ * @param id
71
+ */
72
+ getPost(id: string): RequestProxyResult<PostModel, ResponseWrapper>
73
+ getPost(idOrCategoryName: string, slug?: string): any {
74
+ if (arguments.length == 1) {
75
+ return this.proxy(idOrCategoryName).get<PostModel>()
76
+ } else {
77
+ return this.proxy(idOrCategoryName)(slug).get<PostModel>()
78
+ }
79
+ }
80
+
81
+ /**
82
+ * 获取最新的文章
83
+ */
84
+ getLatest() {
85
+ return this.proxy.latest.get<PostModel>()
86
+ }
87
+
88
+ /**
89
+ * 点赞
90
+ */
91
+ thumbsUp(id: string) {
92
+ return this.proxy('_thumbs-up').get<void>({ params: { id } })
93
+ }
94
+ }
@@ -0,0 +1,27 @@
1
+ import { IRequestAdapter } from '~/interfaces/adapter'
2
+ import { ProjectModel } from '~/models/project'
3
+ import { autoBind } from '~/utils/auto-bind'
4
+ import { HTTPClient } from '../core'
5
+ import { BaseCrudController } from './base'
6
+
7
+ declare module '../core/client' {
8
+ interface HTTPClient<
9
+ T extends IRequestAdapter = IRequestAdapter,
10
+ ResponseWrapper = unknown,
11
+ > {
12
+ project: ProjectController<ResponseWrapper>
13
+ }
14
+ }
15
+
16
+ export class ProjectController<ResponseWrapper> extends BaseCrudController<
17
+ ProjectModel,
18
+ ResponseWrapper
19
+ > {
20
+ constructor(protected readonly client: HTTPClient) {
21
+ super(client)
22
+ autoBind(this)
23
+ }
24
+
25
+ base = 'projects'
26
+ name = 'project'
27
+ }
@@ -0,0 +1,53 @@
1
+ import { IRequestAdapter } from '~/interfaces/adapter'
2
+ import { IController } from '~/interfaces/controller'
3
+ import { IRequestHandler } from '~/interfaces/request'
4
+ import { RecentlyModel } from '~/models/recently'
5
+ import { autoBind } from '~/utils/auto-bind'
6
+ import { HTTPClient } from '../core'
7
+
8
+ declare module '../core/client' {
9
+ interface HTTPClient<
10
+ T extends IRequestAdapter = IRequestAdapter,
11
+ ResponseWrapper = unknown,
12
+ > {
13
+ recently: RecentlyController<ResponseWrapper>
14
+ shorthand: RecentlyController<ResponseWrapper>
15
+ }
16
+ }
17
+
18
+ export class RecentlyController<ResponseWrapper> implements IController {
19
+ base = 'recently'
20
+ name = ['recently', 'shorthand']
21
+
22
+ constructor(private readonly client: HTTPClient) {
23
+ autoBind(this)
24
+ }
25
+
26
+ get proxy(): IRequestHandler<ResponseWrapper> {
27
+ return this.client.proxy(this.base)
28
+ }
29
+ /**
30
+ * 获取最新一条
31
+ */
32
+ getLatestOne() {
33
+ return this.proxy.latest.get<RecentlyModel>()
34
+ }
35
+
36
+ getAll() {
37
+ return this.proxy.all.get<{ data: RecentlyModel[] }>()
38
+ }
39
+
40
+ getList(
41
+ before?: string | undefined,
42
+ after?: string | undefined,
43
+ size?: number | number,
44
+ ) {
45
+ return this.proxy.get<{ data: RecentlyModel[] }>({
46
+ params: {
47
+ before,
48
+ after,
49
+ size,
50
+ },
51
+ })
52
+ }
53
+ }
@@ -0,0 +1,40 @@
1
+ import { IRequestAdapter } from '~/interfaces/adapter'
2
+ import { IController } from '~/interfaces/controller'
3
+ import { IRequestHandler } from '~/interfaces/request'
4
+ import { SayModel } from '~/models/say'
5
+ import { autoBind } from '~/utils/auto-bind'
6
+ import { HTTPClient } from '../core'
7
+ import { BaseCrudController } from './base'
8
+
9
+ declare module '../core/client' {
10
+ interface HTTPClient<
11
+ T extends IRequestAdapter = IRequestAdapter,
12
+ ResponseWrapper = unknown,
13
+ > {
14
+ say: SayController<ResponseWrapper>
15
+ }
16
+ }
17
+
18
+ export class SayController<ResponseWrapper>
19
+ extends BaseCrudController<SayModel, ResponseWrapper>
20
+ implements IController
21
+ {
22
+ base = 'says'
23
+ name = 'say'
24
+
25
+ constructor(protected client: HTTPClient) {
26
+ super(client)
27
+ autoBind(this)
28
+ }
29
+
30
+ public get proxy(): IRequestHandler<ResponseWrapper> {
31
+ return this.client.proxy(this.base)
32
+ }
33
+
34
+ /**
35
+ * 获取随机一条
36
+ */
37
+ getRandom() {
38
+ return this.proxy.random.get<{ data: SayModel | null }>()
39
+ }
40
+ }
@@ -0,0 +1,108 @@
1
+ import { IRequestAdapter } from '~/interfaces/adapter'
2
+ import { IController } from '~/interfaces/controller'
3
+ import { IRequestHandler, RequestProxyResult } from '~/interfaces/request'
4
+ import { PaginateResult } from '~/models/base'
5
+ import { NoteModel } from '~/models/note'
6
+ import { PostModel } from '~/models/post'
7
+ import { autoBind } from '~/utils/auto-bind'
8
+ import { PageModel } from '..'
9
+ import { HTTPClient } from '../core'
10
+
11
+ declare module '../core/client' {
12
+ interface HTTPClient<
13
+ T extends IRequestAdapter = IRequestAdapter,
14
+ ResponseWrapper = unknown,
15
+ > {
16
+ search: SearchController<ResponseWrapper>
17
+ }
18
+ }
19
+
20
+ export type SearchType = 'post' | 'note'
21
+
22
+ export type SearchOption = {
23
+ orderBy?: string
24
+ order?: number
25
+ rawAlgolia?: boolean
26
+ }
27
+ export class SearchController<ResponseWrapper> implements IController {
28
+ base = 'search'
29
+ name = 'search'
30
+
31
+ constructor(private readonly client: HTTPClient) {
32
+ autoBind(this)
33
+ }
34
+
35
+ get proxy(): IRequestHandler<ResponseWrapper> {
36
+ return this.client.proxy(this.base)
37
+ }
38
+
39
+ search(
40
+ type: 'note',
41
+ keyword: string,
42
+ options?: Omit<SearchOption, 'rawAlgolia'>,
43
+ ): Promise<
44
+ RequestProxyResult<
45
+ PaginateResult<
46
+ Pick<NoteModel, 'modified' | 'id' | 'title' | 'created' | 'nid'>
47
+ >,
48
+ ResponseWrapper
49
+ >
50
+ >
51
+ search(
52
+ type: 'post',
53
+ keyword: string,
54
+ options?: Omit<SearchOption, 'rawAlgolia'>,
55
+ ): Promise<
56
+ RequestProxyResult<
57
+ PaginateResult<
58
+ Pick<
59
+ PostModel,
60
+ 'modified' | 'id' | 'title' | 'created' | 'slug' | 'category'
61
+ >
62
+ >,
63
+ ResponseWrapper
64
+ >
65
+ >
66
+ search(
67
+ type: SearchType,
68
+ keyword: string,
69
+ options: Omit<SearchOption, 'rawAlgolia'> = {},
70
+ ): any {
71
+ return this.proxy(type).get({
72
+ params: { keyword, ...options },
73
+ })
74
+ }
75
+ /**
76
+ * 从 algolya 搜索
77
+ * https://www.algolia.com/doc/api-reference/api-methods/search/
78
+ * @param keyword
79
+ * @param options
80
+ * @returns
81
+ */
82
+ searchByAlgolia(keyword: string, options?: SearchOption) {
83
+ return this.proxy('algolia').get<
84
+ RequestProxyResult<
85
+ PaginateResult<
86
+ | (Pick<
87
+ PostModel,
88
+ 'modified' | 'id' | 'title' | 'created' | 'slug' | 'category'
89
+ > & { type: 'post' })
90
+ | (Pick<
91
+ NoteModel,
92
+ 'id' | 'created' | 'id' | 'modified' | 'title' | 'nid'
93
+ > & { type: 'note' })
94
+ | (Pick<
95
+ PageModel,
96
+ 'id' | 'title' | 'created' | 'modified' | 'slug'
97
+ > & { type: 'page' })
98
+ > & {
99
+ /**
100
+ * @see: algoliasearch <https://www.algolia.com/doc/api-reference/api-methods/search/>
101
+ */
102
+ raw?: any
103
+ },
104
+ ResponseWrapper
105
+ >
106
+ >({ params: { keyword, ...options } })
107
+ }
108
+ }
@@ -0,0 +1,36 @@
1
+ import { IRequestAdapter } from '~/interfaces/adapter'
2
+ import { IController } from '~/interfaces/controller'
3
+ import { IRequestHandler } from '~/interfaces/request'
4
+ import { SnippetModel } from '~/models/snippet'
5
+ import { autoBind } from '~/utils/auto-bind'
6
+ import { HTTPClient } from '../core'
7
+
8
+ declare module '../core/client' {
9
+ interface HTTPClient<
10
+ T extends IRequestAdapter = IRequestAdapter,
11
+ ResponseWrapper = unknown,
12
+ > {
13
+ snippet: SnippetController<ResponseWrapper>
14
+ }
15
+ }
16
+
17
+ export class SnippetController<ResponseWrapper> implements IController {
18
+ base = 'snippets'
19
+ name = 'snippet'
20
+
21
+ constructor(protected client: HTTPClient) {
22
+ autoBind(this)
23
+ }
24
+
25
+ get proxy(): IRequestHandler<ResponseWrapper> {
26
+ return this.client.proxy(this.base)
27
+ }
28
+
29
+ getById<T = unknown>(id: string) {
30
+ return this.proxy(id).get<SnippetModel<T>>()
31
+ }
32
+
33
+ getByReferenceAndName<T = unknown>(reference: string, name: string) {
34
+ return this.proxy(reference)(name).get<T>()
35
+ }
36
+ }
@@ -0,0 +1,51 @@
1
+ import { IRequestAdapter } from '~/interfaces/adapter'
2
+ import { IController } from '~/interfaces/controller'
3
+ import { IRequestHandler } from '~/interfaces/request'
4
+ import { TLogin, UserModel } from '~/models/user'
5
+ import { autoBind } from '~/utils/auto-bind'
6
+ import { HTTPClient } from '../core'
7
+
8
+ declare module '../core/client' {
9
+ interface HTTPClient<
10
+ T extends IRequestAdapter = IRequestAdapter,
11
+ ResponseWrapper = unknown,
12
+ > {
13
+ user: UserController<ResponseWrapper>
14
+ master: UserController<ResponseWrapper>
15
+ }
16
+ }
17
+
18
+ export class UserController<ResponseWrapper> implements IController {
19
+ constructor(private readonly client: HTTPClient) {
20
+ autoBind(this)
21
+ }
22
+
23
+ base = 'master'
24
+
25
+ name = ['user', 'master']
26
+
27
+ public get proxy(): IRequestHandler<ResponseWrapper> {
28
+ return this.client.proxy(this.base)
29
+ }
30
+
31
+ getMasterInfo() {
32
+ return this.proxy.get<UserModel>()
33
+ }
34
+
35
+ login(username: string, password: string) {
36
+ return this.proxy.login.post<TLogin>({
37
+ data: {
38
+ username,
39
+ password,
40
+ },
41
+ })
42
+ }
43
+
44
+ checkTokenValid(token: string) {
45
+ return this.proxy.check_logged.get<{ ok: number; isGuest: boolean }>({
46
+ params: {
47
+ token: 'bearer ' + token.replace(/^Bearer\s/i, ''),
48
+ },
49
+ })
50
+ }
51
+ }
@@ -0,0 +1,43 @@
1
+ import type { HTTPClient } from '.'
2
+
3
+ export function attachRequestMethod<T extends HTTPClient<any, any>>(target: T) {
4
+ Object.defineProperty(target, '$$get', {
5
+ value: function (url: string, options?: any) {
6
+ // HINT: method get only accept search params;
7
+ const { params = {} } = options
8
+ const qs = handleSearchParams(params)
9
+
10
+ return target.instance.get(url + `${qs ? `${'?' + qs}` : ''}`)
11
+ },
12
+ })
13
+ ;(['put', 'post', 'patch', 'delete'] as const).forEach((method) => {
14
+ Object.defineProperty(target, '$$' + method, {
15
+ value: function (path: string, options?: any) {
16
+ return target.instance[method](path, options)
17
+ },
18
+ })
19
+ })
20
+ }
21
+ // FIXME: only support string value
22
+ function handleSearchParams(obj: URLSearchParams | Record<string, string>) {
23
+ if (!obj && typeof obj !== 'object') {
24
+ throw new TypeError('params must be object.')
25
+ }
26
+
27
+ if (obj instanceof URLSearchParams) {
28
+ return obj.toString()
29
+ }
30
+ const search = new URLSearchParams()
31
+
32
+ Object.entries<any>(obj).forEach(([k, v]) => {
33
+ if (
34
+ typeof v === 'undefined' ||
35
+ Object.prototype.toString.call(v) === '[object Null]'
36
+ ) {
37
+ return
38
+ }
39
+ search.set(k, v)
40
+ })
41
+
42
+ return search.toString()
43
+ }
package/core/client.ts ADDED
@@ -0,0 +1,239 @@
1
+ import camelcaseKeys from 'camelcase-keys'
2
+ import {
3
+ IAdaptorRequestResponseType,
4
+ IRequestAdapter,
5
+ } from '~/interfaces/adapter'
6
+ import { ClientOptions } from '~/interfaces/client'
7
+ import { IController } from '~/interfaces/controller'
8
+ import { RequestOptions } from '~/interfaces/instance'
9
+ import { IRequestHandler, Method } from '~/interfaces/request'
10
+ import { Class } from '~/interfaces/types'
11
+ import { isPlainObject } from '~/utils'
12
+ import { allContollerNames } from '../controllers'
13
+ import { attachRequestMethod } from './attach-request'
14
+ import { RequestError } from './error'
15
+
16
+ const methodPrefix = '_$'
17
+ export type { HTTPClient }
18
+ class HTTPClient<
19
+ T extends IRequestAdapter = IRequestAdapter,
20
+ ResponseWrapper = unknown,
21
+ > {
22
+ private _proxy: IRequestHandler<ResponseWrapper>
23
+
24
+ constructor(private _endpoint: string, private _adaptor: T) {
25
+ this._endpoint = _endpoint
26
+ .replace(/\/*$/, '')
27
+ .replace('localhost', '127.0.0.1')
28
+ this._proxy = this.buildRoute(this)()
29
+
30
+ this.initGetClient()
31
+
32
+ attachRequestMethod(this)
33
+ }
34
+
35
+ private initGetClient() {
36
+ for (const name of allContollerNames) {
37
+ Object.defineProperty(this, name, {
38
+ get() {
39
+ const client = Reflect.get(this, `${methodPrefix}${name}`)
40
+ if (!client) {
41
+ throw new ReferenceError(
42
+ `${
43
+ name.charAt(0).toUpperCase() + name.slice(1)
44
+ } Client not inject yet, please inject with client.injectClients(...)`,
45
+ )
46
+ }
47
+ return client
48
+ },
49
+ configurable: false,
50
+ enumerable: false,
51
+ })
52
+ }
53
+ }
54
+
55
+ public injectControllers(...Controller: Class<IController>[]): void
56
+ public injectControllers(Controller: Class<IController>[]): void
57
+ public injectControllers(Controller: any, ...rest: any[]) {
58
+ Controller = Array.isArray(Controller) ? Controller : [Controller, ...rest]
59
+ for (const Client of Controller) {
60
+ const cl = new Client(this)
61
+
62
+ if (Array.isArray(cl.name)) {
63
+ for (const name of cl.name) {
64
+ attach.call(this, name, cl)
65
+ }
66
+ } else {
67
+ attach.call(this, cl.name, cl)
68
+ }
69
+ }
70
+
71
+ function attach(this: any, name: string, cl: IController) {
72
+ Object.defineProperty(this, `${methodPrefix}${name.toLowerCase()}`, {
73
+ get() {
74
+ return cl
75
+ },
76
+ enumerable: false,
77
+ configurable: false,
78
+ })
79
+ }
80
+ }
81
+
82
+ get endpoint() {
83
+ return this._endpoint
84
+ }
85
+
86
+ get instance() {
87
+ return this._adaptor
88
+ }
89
+
90
+ public request(options: {
91
+ url: string
92
+ method?: string
93
+ data?: any
94
+ params?: any
95
+ }) {
96
+ return (this as any)['$$' + String(options.method || 'get').toLowerCase()](
97
+ options.url,
98
+ options,
99
+ ) as Promise<IAdaptorRequestResponseType<any>>
100
+ }
101
+
102
+ public get proxy() {
103
+ return this._proxy
104
+ }
105
+
106
+ private resolveFullPath(path: string) {
107
+ if (!path.startsWith('/')) {
108
+ path = '/' + path
109
+ }
110
+ return `${this.endpoint}${path}`
111
+ }
112
+
113
+ private buildRoute(manager: this): () => IRequestHandler<ResponseWrapper> {
114
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
115
+ const noop = () => {}
116
+ const methods = ['get', 'post', 'delete', 'patch', 'put']
117
+ const reflectors = [
118
+ 'toString',
119
+ 'valueOf',
120
+ 'inspect',
121
+ 'constructor',
122
+ Symbol.toPrimitive,
123
+ ]
124
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
125
+ const that = this
126
+
127
+ return () => {
128
+ const route = ['']
129
+
130
+ const handler: any = {
131
+ get(target: any, name: Method) {
132
+ if (reflectors.includes(name))
133
+ return (withBase?: boolean) => {
134
+ if (withBase) {
135
+ const path = that.resolveFullPath(route.join('/'))
136
+ route.length = 0
137
+ return path
138
+ } else {
139
+ const path = route.join('/')
140
+ route.length = 0
141
+ return path.startsWith('/') ? path : '/' + path
142
+ }
143
+ }
144
+ if (methods.includes(name)) {
145
+ return async (options: RequestOptions) => {
146
+ const url = that.resolveFullPath(route.join('/'))
147
+ route.length = 0
148
+ let res: Record<string, any> & { data: any }
149
+ try {
150
+ res = await manager.request({
151
+ method: name,
152
+ ...options,
153
+ url,
154
+ })
155
+ } catch (e: any) {
156
+ throw new RequestError(
157
+ e.message,
158
+ e.code ||
159
+ e.status ||
160
+ e.statusCode ||
161
+ e.response?.status ||
162
+ e.response?.statusCode ||
163
+ e.response?.code ||
164
+ 500,
165
+ url,
166
+ e,
167
+ )
168
+ }
169
+
170
+ const data = res.data
171
+ if (!data) {
172
+ return null
173
+ }
174
+
175
+ const transform =
176
+ Array.isArray(data) || isPlainObject(data)
177
+ ? camelcaseKeys(data, { deep: true })
178
+ : data
179
+
180
+ if (transform && typeof transform === 'object') {
181
+ Object.defineProperty(transform, '$raw', {
182
+ get() {
183
+ return res
184
+ },
185
+ enumerable: false,
186
+ configurable: false,
187
+ })
188
+
189
+ // attach request config onto response
190
+
191
+ Object.defineProperty(transform, '$request', {
192
+ get() {
193
+ return {
194
+ url,
195
+ method: name,
196
+ options,
197
+ }
198
+ },
199
+ enumerable: false,
200
+ })
201
+ }
202
+
203
+ return transform
204
+ }
205
+ }
206
+ route.push(name)
207
+ return new Proxy(noop, handler)
208
+ },
209
+ // @ts-ignore
210
+ apply(target: any, _, args) {
211
+ route.push(...args.filter((x: string) => x !== null))
212
+ return new Proxy(noop, handler)
213
+ },
214
+ }
215
+
216
+ return new Proxy(noop, handler) as any
217
+ }
218
+ }
219
+ }
220
+
221
+ export function createClient<T extends IRequestAdapter>(adapter: T) {
222
+ return <
223
+ ResponseWrapper = T extends { responseWrapper: infer Type }
224
+ ? Type extends undefined
225
+ ? unknown
226
+ : Type
227
+ : unknown,
228
+ >(
229
+ endpoint: string,
230
+ options?: ClientOptions,
231
+ ) => {
232
+ const client = new HTTPClient<T, ResponseWrapper>(endpoint, adapter)
233
+ const { controllers } = options || {}
234
+ if (controllers) {
235
+ client.injectControllers(controllers)
236
+ }
237
+ return client
238
+ }
239
+ }
package/core/error.ts ADDED
@@ -0,0 +1,10 @@
1
+ export class RequestError extends Error {
2
+ constructor(
3
+ message: string,
4
+ public status: number,
5
+ public path: string,
6
+ public raw: any,
7
+ ) {
8
+ super(message)
9
+ }
10
+ }