@varlet/axle 0.13.2 → 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.
package/README.md CHANGED
@@ -1,30 +1,49 @@
1
- <span>English</span> |
2
- <a href="https://github.com/varletjs/axle/blob/main/README.zh-CN.md">中文</a>
1
+ <div align="center">
2
+ <a href="https://axle.varletjs.org">
3
+ <img src="https://raw.githubusercontent.com/varletjs/axle/main/packages/docs/public/logo.svg" width="150">
4
+ </a>
5
+ <h1>AXLE</h1>
6
+ <p>Progressive request tool based on axios.</p>
7
+ <p>
8
+ <a href="https://axle.varletjs.org">Documentation</a> |
9
+ <a href="https://github.com/varletjs/axle/blob/main/README.zh-CN.md">中文介绍</a>
10
+ </p>
11
+ <p>
12
+ <img src="https://img.shields.io/npm/v/@varlet/axle?style=flat-square" alt="version">
13
+ <img src="https://img.shields.io/github/stars/varletjs/axle" alt="stars">
14
+ <img src="https://img.shields.io/badge/vue-v3.2.0%2B-%23407fbc" alt="vue">
15
+ <img src="https://img.shields.io/npm/l/@varlet/axle.svg" alt="license">
16
+ </p>
17
+ </div>
18
+
19
+ ---
3
20
 
4
21
  ### Intro
5
22
 
6
- Progressive request tool based on axios. It does not destroy the original abilities of axios, and helps you process requests more easily.
23
+ Progressive request tool based on [axios](https://axios-http.com/). It does not destroy the original abilities of axios, and helps you process requests more easily.
7
24
 
8
- ### QuickStart
25
+ ### Features
9
26
 
10
- #### Install
27
+ - 🚀 &nbsp; Normalized request functions with expanded methods for different response types
28
+ - 💪 &nbsp; Vue Composition API support with loading status, error status, upload/download progress, lifecycle, and more
29
+ - 🛠️ &nbsp; Built-in practical request/response interceptors
30
+ - 💡 &nbsp; Enhanced API definition with `createApi`
31
+ - 🌍 &nbsp; Full compatibility with axios configuration
11
32
 
12
- ```shell
13
- # Install with npm, yarn or pnpm
33
+ ### Install
14
34
 
35
+ ```shell
15
36
  # npm
16
37
  npm i @varlet/axle -S
17
38
 
18
- #yarn
39
+ # yarn
19
40
  yarn add @varlet/axle
20
41
 
21
- #pnpm
42
+ # pnpm
22
43
  pnpm add @varlet/axle
23
44
  ```
24
45
 
25
- #### Send Request
26
-
27
- Axle normalizes the parameters of the request function, and expands more request functions for different interface requirements. Here is a simple example.
46
+ ### Basic Usage
28
47
 
29
48
  ```js
30
49
  import { createAxle } from '@varlet/axle'
@@ -35,521 +54,6 @@ axle.get('/url', { current: 1, pageSize: 10 }, { headers: {} })
35
54
  axle.post('/url', { name: 'Axle' }, { headers: {} })
36
55
  ```
37
56
 
38
- ### Config
39
-
40
- Axle fully supports all configuration abilities of axios.
41
-
42
- ```js
43
- const axle = createAxle(/** @see https://axios-http.com **/)
44
- // The built-in axios of the axle, the usage is exactly the same as that of axios, and shares the configuration with the axle.
45
- const { axios } = axle
46
-
47
- axios.defaults.baseURL = 'https://api.example.com'
48
- axios.defaults.headers.common['TOKEN'] = TOKEN
49
- axios.defaults.timeout = 2500
50
-
51
- // Add a request interceptor
52
- axios.interceptors.request.use(
53
- (config) => {
54
- // Do something before request is sent
55
- return config
56
- },
57
- (error) => {
58
- // Do something with request error
59
- return Promise.reject(error)
60
- },
61
- )
62
-
63
- // Add a response interceptor
64
- axios.interceptors.response.use(
65
- (response) => {
66
- // Any status code that lie within the range of 2xx cause this function to trigger
67
- // Do something with response data
68
- return response
69
- },
70
- (error) => {
71
- // Any status codes that falls outside the range of 2xx cause this function to trigger
72
- // Do something with response error
73
- return Promise.reject(error)
74
- },
75
- )
76
- ```
77
-
78
- ## Axle & Axios Request Functions
79
-
80
- The request function provided by Axle can help you send requests more easily. Here are some examples including comparison with axios.
81
- Tips: Take `get` and `post` as examples below, Axle also supports `options`, `head`, `delete`, `patch` , `put` methods.
82
-
83
- ### get
84
-
85
- #### JSON
86
-
87
- ```js
88
- // axios
89
- axios.get('/url', { params: { id: 1 } })
90
- // axle
91
- axle.get('/url', { id: 1 })
92
- ```
93
-
94
- #### Blob
95
-
96
- ```js
97
- // axios
98
- axios.get('/url', { params: { id: 1 }, responseType: 'blob' })
99
- // axle
100
- axle.getBlob('/url', { id: 1 })
101
- ```
102
-
103
- #### Text
104
-
105
- ```js
106
- // axios
107
- axios.get('/url', { params: { id: 1 }, responseType: 'text' })
108
- // axle
109
- axle.getText('/url', { id: 1 })
110
- ```
111
-
112
- #### Document
113
-
114
- ```js
115
- // axios
116
- axios.get('/url', { params: { id: 1 }, responseType: 'document' })
117
- // axle
118
- axle.getDocument('/url', { id: 1 })
119
- ```
120
-
121
- #### ArrayBuffer
122
-
123
- ```js
124
- // axios
125
- axios.get('/url', { params: { id: 1 }, responseType: 'arraybuffer' })
126
- // axle
127
- axle.getArrayBuffer('/url', { id: 1 })
128
- ```
129
-
130
- #### Stream
131
-
132
- ```js
133
- // axios
134
- axios.get('/url', { params: { id: 1 }, responseType: 'stream' })
135
- // axle
136
- axle.getStream('/url', { id: 1 })
137
- ```
57
+ ### Documentation
138
58
 
139
- ### post
140
-
141
- #### JSON
142
-
143
- Same with axios.
144
-
145
- ```js
146
- // axios
147
- axios.post('/url', { name: 'foo' })
148
- // axle
149
- axle.post('/url', { name: 'foo' })
150
- ```
151
-
152
- #### application/x-www-form-urlencoded
153
-
154
- ```js
155
- // axios
156
- axios.post('/url', qs.stringify({ name: 'foo' }), {
157
- headers: {
158
- 'Content-Type': 'application/x-www-form-urlencoded',
159
- },
160
- })
161
- // axle
162
- axle.postUrlEncode('/url', { name: 'foo' })
163
- ```
164
-
165
- #### multipart/form-data
166
-
167
- ```js
168
- // axios
169
- const formData = new FormData()
170
- formData.append('name', 'foo')
171
- formData.append('file', new File())
172
-
173
- axios.post('/url', formData, {
174
- headers: {
175
- 'Content-Type': 'multipart/form-data',
176
- },
177
- })
178
- // axle
179
- axle.postMultipart('/url', { name: 'foo', file: new File() })
180
- ```
181
-
182
- ## Utils
183
-
184
- #### Notify the browser to download the file
185
-
186
- ```js
187
- import { download } from '@varlet/axle'
188
-
189
- download(await axle.getBlob('/url', { id: 1 }), 'filename')
190
- ```
191
-
192
- #### Return both a success response and an error response
193
-
194
- ```js
195
- import { withResponse } from '@varlet/axle'
196
-
197
- const { response, errorResponse } = await withResponse(axle.get('/url'))
198
- ```
199
-
200
- #### Common Header Operate
201
-
202
- ```js
203
- const headers = axle.getHeaders()
204
- axle.setHeader('TOKEN', TOKEN)
205
- axle.removeHeader('TOKEN')
206
- ```
207
-
208
- ## Built-in interceptor
209
-
210
- axle provides some practical requests/response interceptors, and is compatible with `axle` and `axios`.
211
-
212
- ### axios
213
-
214
- ```ts
215
- import { requestHeadersInterceptor, responseTimeoutInterceptor } from '@varlet/axle'
216
-
217
- const headersInterceptor = requestHeadersInterceptor({
218
- headers: () => ({
219
- token: localStorage.getItem('token'),
220
- 'Axle-Custom-Header': 'Axle-Custom-Header',
221
- }),
222
- })
223
-
224
- const retryInterceptor = responseRetryInterceptor({ count: 3 })
225
-
226
- axios.interceptors.request.use(
227
- headersInterceptor.onFulfilled,
228
- headersInterceptor.onRejected,
229
- headersInterceptor.options,
230
- )
231
- axios.interceptors.response.use(retryInterceptor.onFulfilled, retryInterceptor.onRejected, retryInterceptor.options)
232
- ```
233
-
234
- ### axle
235
-
236
- ```ts
237
- import { requestHeadersInterceptor, responseTimeoutInterceptor } from '@varlet/axle'
238
-
239
- axle.useRequestInterceptor(
240
- requestHeadersInterceptor({
241
- headers: () => ({
242
- token: localStorage.getItem('token'),
243
- 'Axle-Custom-Header': 'Axle-Custom-Header',
244
- }),
245
- }),
246
- )
247
-
248
- axle.useResponseInterceptor(responseRetryInterceptor({ count: 3 }))
249
- ```
250
-
251
- ### General parameter of the interceptor
252
-
253
- Each built-in interceptor supports `include` `exclude` `axiosInterceptorOptions (same with Axios interceptor)`.
254
-
255
- #### include & exclude
256
-
257
- It is used to request filtering to determine what request should apply the interceptor and support specifying the `method`、 `glob` syntax or `status` code. The usage method is as follows.
258
-
259
- ```ts
260
- axle.useResponseInterceptor(
261
- responseRetryInterceptor({
262
- count: 3,
263
- include: ['method:put', 'method:post', 'status:500'],
264
- exclude: ['/system/**', '/user/addUser', 'status:400'],
265
- }),
266
- )
267
- ```
268
-
269
- ### List of built-in interceptor
270
-
271
- | Name | Description |
272
- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
273
- | [requestHeadersInterceptor](https://github.com/varletjs/axle/blob/main/packages/axle/src/interceptors/examples/requestHeadersInterceptor.md) | Used to customize the request header |
274
- | [requestMockInterceptor](https://github.com/varletjs/axle/blob/main/packages/axle/src/interceptors/examples/requestMockInterceptor.md) | Used to mock data |
275
- | [requestMd5Interceptor](https://github.com/varletjs/axle/blob/main/packages/axle/src/interceptors/examples/requestMd5Interceptor.md) | Used for md encryption of parameters and headers |
276
- | [responseRetryInterceptor](https://github.com/varletjs/axle/blob/main/packages/axle/src/interceptors/examples/responseRetryInterceptor.md) | Used to realize the request abnormal retry |
277
- | [responseStatusInterceptor](https://github.com/varletjs/axle/blob/main/packages/axle/src/interceptors/examples/responseStatusInterceptor.md) | Used to intercept status code |
278
- | [responseBlobInterceptor](https://github.com/varletjs/axle/blob/main/packages/axle/src/interceptors/examples/responseBlobInterceptor.md) | Used to intercept blob type |
279
- | [responseTimeoutInterceptor](https://github.com/varletjs/axle/blob/main/packages/axle/src/interceptors/examples/responseTimeoutInterceptor.md) | Used to abnormal timeout |
280
-
281
- ## Vue Composition API
282
-
283
- Axle provides the usage of Vue Composition API style, which encapsulates the `loading status`, `error status`, `upload and download progress` of the request, `return data`, `lifecycle`, etc., And inherit all the configuration of `axios`.
284
-
285
- ```html
286
- <script setup>
287
- import { createAxle } from '@varlet/axle'
288
- import { createUseAxle } from '@varlet/axle/use'
289
-
290
- const axle = createAxle(/** @see https://axios-http.com **/)
291
-
292
- const useAxle = createUseAxle({
293
- axle,
294
- // Optional value: Default immediate of the useAxle, defaults true
295
- immediate: false,
296
- // Optional value: Default onTransform of the useAxle
297
- onTransform: (response) => response,
298
- })
299
-
300
- const id = ref('1')
301
-
302
- const [
303
- users,
304
- // request runner/invoker
305
- getUsers,
306
- // extra properties
307
- { loading, error, uploadProgress, downloadProgress, abort, resetValue },
308
- ] = useAxle({
309
- // Request initial value
310
- value: [],
311
- // Request method
312
- method: 'get',
313
- // Request url can be a getter function
314
- url: '/user',
315
- // Whether to send the request immediately, defaults true
316
- immediate: false,
317
- // Automatically reload when reactive parameters change
318
- // When set to true, watch all parameters (params, config, pathParams)
319
- // When set to an object, watch specific parameters:
320
- // - params: true - watch params changes
321
- // - pathParams: true - watch pathParams changes (for API definitions)
322
- // - config: true - watch config changes
323
- watch: true,
324
- // Whether the value needs to be reset before requesting, defaults false
325
- resetValue: true,
326
- // Whether to clone when resetting value, defaults false
327
- // When set to true, use JSON.parse(JSON.stringify(value)) cloned
328
- // When set to a function, the set function will be used as the clone function, such as v => _.cloneDeep(v)
329
- cloneResetValue: true,
330
- // Request params, defaults {}, can be a getter function
331
- params: { current: 1, pageSize: 10 },
332
- // Axios config, see https://axios-http.com can be a getter function
333
- config: { headers: {} },
334
- // lifecycle
335
- onBefore(refs) {
336
- const { data, loading, error, uploadProgress, downloadProgress } = refs
337
- console.log(data.value, loading.value, error.value, uploadProgress.value, downloadProgress.value)
338
- // Do request before
339
- },
340
- onTransform(response, refs) {
341
- // Handle data transform, The transformed data will be the value of users.
342
- return response.data
343
- },
344
- onSuccess(response, refs) {
345
- // Do request success
346
- },
347
- onError(error, refs) {
348
- // Do request error
349
- },
350
- onAfter(refs) {
351
- // Do request after
352
- },
353
- })
354
- </script>
355
-
356
- <template>
357
- <span>{{ users }}</span>
358
- <span>{{ loading }}</span>
359
- <span>{{ error }}</span>
360
- <span>{{ uploadProgress }}</span>
361
- <span>{{ downloadProgress }}</span>
362
- <button @click="getUsers">Send Request</button>
363
- <button @click="abort">Abort Request</button>
364
- </template>
365
- ```
366
-
367
- ### Parallel Utils
368
-
369
- Axle provides some parallel request processing tools, please refer to the following examples.
370
-
371
- ```html
372
- <script setup>
373
- import { createAxle } from '@varlet/axle'
374
- import { createUseAxle, useAverageProgress, useHasLoading, useValues } from '@varlet/axle/use'
375
-
376
- const axle = createAxle(/** @see https://axios-http.com **/)
377
-
378
- const useAxle = createUseAxle({ axle })
379
-
380
- const [users, getUsers, { loading: isUsersLoading, downloadProgress: usersDownloadProgress }] = useAxle({
381
- method: 'get',
382
- url: '/user',
383
- })
384
-
385
- const [roles, getRoles, { loading: isRolesLoading, downloadProgress: rolesDownloadProgress }] = useAxle({
386
- method: 'get',
387
- url: '/role',
388
- })
389
-
390
- // At the end of all requests, loading is false
391
- const loading = useHasLoading(isUsersLoading, isRolesLoading)
392
- // At the end of all requests, downloadProgress is 1
393
- const downloadProgress = useAverageProgress(usersDownloadProgress, rolesDownloadProgress)
394
- // Ref<[
395
- // [{ name: 'foo' }, { name: 'bar' }],
396
- // [{ role: 'admin' }, { role: 'user' }]
397
- // ]> <-
398
- // [
399
- // Ref<[{ name: 'foo' }, { name: 'bar' }]>,
400
- // Ref<[{ role: 'admin' }, { role: 'user' }]>
401
- // ]
402
- const usersRoles = useValues(users, roles)
403
-
404
- function sendAllRequest() {
405
- // parallel
406
- getUsers()
407
- getRoles()
408
- }
409
- </script>
410
-
411
- <template>
412
- <span>{{ usersRoles }}</span>
413
- <span>{{ loading }}</span>
414
- <span>{{ downloadProgress }}</span>
415
- <button @click="sendAllRequest">Send All Request</button>
416
- </template>
417
- ```
418
-
419
- ### API Definition Enhancement
420
-
421
- `createApi` is supported since `v0.9.0`, which is used to define APIs.
422
-
423
- #### Define APIs
424
-
425
- ```ts
426
- import { createAxle } from '@varlet/axle'
427
- import { createApi } from '@varlet/axle/api'
428
- import { createUseAxle } from '@varlet/axle/use'
429
-
430
- const axle = createAxle({
431
- baseURL: '/api',
432
- })
433
-
434
- const useAxle = createUseAxle({
435
- axle,
436
- })
437
-
438
- const api = createApi(axle, useAxle)
439
-
440
- export const apiGetUsers = api<Response<User[]>>('/user', 'get')
441
-
442
- export const apiGetUser = api<Response<User>>('/user/:id', 'get')
443
-
444
- export const apiCreateUser = api<Response<User>, CreateUser>('/user', 'post')
445
-
446
- export const apiUpdateUser = api<Response<User>, UpdateUser>('/user/:id', 'put')
447
-
448
- export const apiDeleteUser = api<Response<User>>('/user/:id', 'delete')
449
-
450
- export type Response<T> = {
451
- data: T
452
- code: number
453
- message: string
454
- success: boolean
455
- }
456
-
457
- export interface User {
458
- id: string
459
- name: string
460
- }
461
-
462
- export interface CreateUser {
463
- name: string
464
- }
465
-
466
- export interface UpdateUser {
467
- name: string
468
- }
469
- ```
470
-
471
- #### Invoke APIs
472
-
473
- ```ts
474
- const route = useRoute()
475
-
476
- const [users, getUsers] = apiGetUsers.use<Response<User[]>>(/** same as useAxle and extends pathParams **/)
477
-
478
- const [user, getUser] = apiGetUser.use<Response<User>>({
479
- pathParams: () => ({ id: route.params.id }),
480
- })
481
-
482
- async function handleCreate(params: CreateUser) {
483
- const { success } = await apiCreateUser.load(params)
484
-
485
- if (success) {
486
- getUsers()
487
- }
488
- }
489
-
490
- async function handleUpdate(params: UpdateUser, id: string) {
491
- const { success } = await apiUpdateUser.load(params, { id })
492
-
493
- if (success) {
494
- getUsers()
495
- }
496
- }
497
-
498
- async function handleDelete(id: string) {
499
- const { success } = await apiDeleteUser.load({}, { id })
500
-
501
- if (success) {
502
- getUsers()
503
- }
504
- }
505
- ```
506
-
507
- ### Runner Enhancement
508
-
509
- Since `v0.10.0`, the `runner` will include all the extra properties, so we can further simplify the work.
510
-
511
- before:
512
-
513
- ```html
514
- <script setup>
515
- const [users, getUsers, { loading: isUsersLoading }] = useAxle({
516
- method: 'get',
517
- url: '/user',
518
- })
519
-
520
- const [posts, getPosts, { loading: isPostsLoading }] = useAxle({
521
- method: 'get',
522
- url: '/post',
523
- })
524
- </script>
525
-
526
- <template>
527
- <span>{{ isUsersLoading ? 'loading...' : users }}</span>
528
- <span>{{ isPostsLoading ? 'loading...' : posts }}</span>
529
- <button @click="getUsers">Send Request</button>
530
- <button @click="getPosts">Send Request</button>
531
- </template>
532
- ```
533
-
534
- after:
535
-
536
- ```html
537
- <script setup>
538
- const [users, getUsers] = useAxle({
539
- method: 'get',
540
- url: '/user',
541
- })
542
-
543
- const [posts, getPosts] = useAxle({
544
- method: 'get',
545
- url: '/post',
546
- })
547
- </script>
548
-
549
- <template>
550
- <span>{{ getUsers.loading.value ? 'loading...' : users }}</span>
551
- <span>{{ getPosts.loading.value ? 'loading...' : posts }}</span>
552
- <button @click="getUsers">Send Request</button>
553
- <button @click="getPosts">Send Request</button>
554
- </template>
555
- ```
59
+ For full documentation, please visit the [documentation site](https://axle.varletjs.org).