Skip to content

Commit dbd0a23

Browse files
committed
Merge branch 'feat/axios-1.x'
2 parents dba3af7 + a77047c commit dbd0a23

25 files changed

Lines changed: 1227 additions & 2908 deletions

.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ out
8989

9090
# Nuxt.js build / generate output
9191
.nuxt
92+
.output
9293
dist
9394

9495
# Gatsby files

.github/workflows/ci.yml

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,26 @@ on:
1111
merge_group:
1212
types: [checks_requested]
1313

14+
env:
15+
NODE_VERSION: 20
16+
1417
jobs:
1518
analyze:
16-
runs-on: ${{ matrix.os }}
19+
runs-on: ubuntu-latest
1720

1821
permissions:
1922
actions: read
2023
contents: read
2124
security-events: write
2225

23-
strategy:
24-
fail-fast: false
25-
matrix:
26-
os:
27-
- ubuntu-latest
28-
language:
29-
- javascript
30-
3126
steps:
3227
- name: Git Checkout
3328
uses: actions/checkout@v3
3429

3530
- name: Initialize CodeQL
3631
uses: github/codeql-action/init@v2
3732
with:
38-
languages: ${{ matrix.language }}
33+
languages: javascript
3934

4035
- name: Autobuild
4136
uses: github/codeql-action/autobuild@v2
@@ -44,15 +39,7 @@ jobs:
4439
uses: github/codeql-action/analyze@v2
4540

4641
build:
47-
runs-on: ${{ matrix.os }}
48-
49-
strategy:
50-
fail-fast: false
51-
matrix:
52-
os:
53-
- ubuntu-latest
54-
node-version:
55-
- 18
42+
runs-on: ubuntu-latest
5643

5744
steps:
5845
- name: Git Checkout
@@ -73,10 +60,10 @@ jobs:
7360
restore-keys: |
7461
${{ runner.os }}-yarn-
7562
76-
- name: Use Node.js ${{ matrix.node-version }}
63+
- name: Use Node.js ${{ env.NODE_VERSION }}
7764
uses: actions/setup-node@v4
7865
with:
79-
node-version: ${{ matrix.node-version }}
66+
node-version: ${{ env.NODE_VERSION }}
8067
cache: "yarn"
8168

8269
- name: Install Deps

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ out
8989

9090
# Nuxt.js build / generate output
9191
.nuxt
92+
.output
9293
dist
9394

9495
# Gatsby files

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
18
1+
20

.yarn/releases/yarn-3.8.3.cjs

Lines changed: 0 additions & 875 deletions
This file was deleted.

README.md

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Find and replace all on all files (CMD+SHIFT+F):
2424

2525
<!-- Highlight some of the features your module provide here -->
2626
- ✅ Using Fetch instead of XHR
27-
- ✅ Built-in adapter for Dedupe, and Priority Queue request.
27+
- ✅ Built-in adapter for Retry, Dedupe, and Priority Queue request.
2828
- ✅ Composable hook for Axios interceptors.
2929

3030
## Compabilities
@@ -133,26 +133,80 @@ onResponseError(async (error) => {
133133

134134
## Queue
135135

136-
All request per instance will be add into queue before sent with priority `1`.
136+
All request per instance will be add into queue before sent with priority MEDIUM (`20`).
137137
If you want to send your request first before the others, you can set using option `priority`. The higher priority will run first.
138138

139139
```ts
140+
import { QueuePriority } from '@privyid/nuapi/core'
141+
140142
useApi().get('/document/load', {
141-
priority: 2,
143+
// Using presets
144+
priority: QueuePriority.HIGH,
145+
// Or using number
146+
priority: 50,
142147
})
143148
```
144149

145150
## Dedupe
146151

147152
Sometime, you want to cancel request with same endpoint like when you working with searching or filter.
148153

149-
NuAPI has built in function for this case. Just set `requestId`, multiple sent request with same id will cancel last request before.
154+
NuAPI has built in function for this case. Just set `requestkey`, multiple sent request with same id will cancel last request before.
150155

151156
```ts
152157
useApi().get('/document/load', {
153-
requestId: 'document-load',
158+
requestkey: 'document-load',
154159
})
155160
```
161+
162+
### Cancel Manually
163+
164+
Cancel spesific request by `requestKey` using `.cancel()`
165+
166+
```ts
167+
useApi().cancel('document-load')
168+
```
169+
170+
Or cancel all requests that have `requestKey` using `.cancelAll()`
171+
172+
```ts
173+
useApi().cancelAll()
174+
```
175+
176+
## Retry
177+
178+
NuAPI automatically retries request when got an error with status code:
179+
180+
- 408 - Request Timeout
181+
- 409 - Conflict
182+
- 425 - Too Early
183+
- 429 - Too Many Requests
184+
- 500 - Internal Server Error
185+
- 502 - Bad Gateway
186+
- 503 - Service Unavailable
187+
- 504 - Gateway Timeout
188+
189+
By default will retries `3` times (except for `PATCH`, `POST`, `PUT`, `DELETE`) can be changed using option `retry`.
190+
191+
```ts
192+
useApi().get('/document/load', {
193+
retry: 5,
194+
})
195+
```
196+
197+
### Customize Retry Condition
198+
199+
You can customize when request should retries using `retryOn`
200+
201+
```ts
202+
useApi().get('/document/load', {
203+
retryOn (error) {
204+
return getCode(error) === 423
205+
&& error.config.retryCount < 3
206+
},
207+
})
208+
```
209+
156210
## API
157211

158212
👉 You can learn more about usage in [JSDocs Documentation](https://www.jsdocs.io/package/@privyid/nuapi).

msw.setup.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ const server = setupServer(
1919
await delay(2)
2020
}),
2121

22+
http.all(`${BASE_URL}/api/echo`, async ({ request }) => {
23+
return HttpResponse.json({
24+
method : request.method,
25+
headers: request.headers,
26+
})
27+
}),
28+
2229
http.get(`${BASE_URL}/api/ping`, () => {
2330
return HttpResponse.json({ message: 'Pong' })
2431
}),
@@ -55,8 +62,20 @@ const server = setupServer(
5562
}, { status: 422 })
5663
}),
5764

58-
http.get(`${BASE_URL}/api/error/500`, () => {
59-
return new HttpResponse(undefined, { status: 500 })
65+
http.all(`${BASE_URL}/api/error/500`, () => {
66+
return HttpResponse.json({}, { status: 500 })
67+
}),
68+
69+
http.get(`${BASE_URL}/api/error/unstable`, async function * () {
70+
let count = 0
71+
72+
while (count < 2) {
73+
yield HttpResponse.json({ data: { count } }, { status: 500 })
74+
75+
count++
76+
}
77+
78+
return HttpResponse.json({ message: 'Pong', data: { count } })
6079
}),
6180
)
6281

package.json

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@privyid/nuapi",
3-
"version": "0.3.0-alpha.4",
3+
"version": "0.3.0-alpha.6",
44
"description": "Nuxt HTTP Client module",
55
"packageManager": "yarn@4.4.0",
66
"repository": {
@@ -36,7 +36,7 @@
3636
],
3737
"scripts": {
3838
"prepack": "yarn build",
39-
"build": "nuxt-module-build",
39+
"build": "nuxt-module-build build",
4040
"dev": "nuxi dev playground",
4141
"dev:build": "nuxi build playground",
4242
"dev:prepare": "nuxt-module-build --stub && nuxi prepare playground",
@@ -47,11 +47,14 @@
4747
"coverage": "vitest run src --coverage --config ./vitest.config.ts"
4848
},
4949
"dependencies": {
50-
"@nuxt/kit": "^3.7.4",
50+
"@nuxt/kit": "^3.12.4",
5151
"axios": "^1.7.2",
52-
"defu": "^6.1.2",
53-
"ofetch": "^1.3.3",
54-
"ufo": "^1.3.1"
52+
"defu": "^6.1.4",
53+
"ofetch": "^1.3.4",
54+
"ufo": "^1.5.4"
55+
},
56+
"peerDependencies": {
57+
"nuxt": ">=3.4.0"
5558
},
5659
"devDependencies": {
5760
"@nuxt/eslint-config": "0.5.0",
@@ -62,25 +65,23 @@
6265
"@privyid/nhp": "1.0.0",
6366
"@typescript-eslint/eslint-plugin": "5.62.0",
6467
"@typescript-eslint/parser": "5.62.0",
65-
"@vitest/coverage-c8": "0.30.1",
68+
"@vitest/coverage-v8": "^2.0.5",
6669
"@vue/eslint-config-typescript": "13.0.0",
67-
"axios-mock-adapter": "1.22.0",
6870
"changelogen": "0.5.5",
6971
"eslint": "8.57.0",
7072
"eslint-config-standard-with-typescript": "34.0.1",
7173
"eslint-formatter-pretty": "5.0.0",
7274
"eslint-plugin-align-assignments": "1.1.2",
7375
"eslint-plugin-import": "2.29.1",
7476
"eslint-plugin-n": "15.7.0",
75-
"eslint-plugin-n": "14.0.0",
7677
"eslint-plugin-promise": "6.6.0",
7778
"eslint-plugin-unicorn": "46.0.1",
7879
"eslint-plugin-varspacing": "1.2.2",
7980
"eslint-plugin-vue": "9.27.0",
8081
"msw": "2.3.5",
8182
"nuxt": "3.12.4",
8283
"typescript": "5.5.4",
83-
"vitest": "0.30.1"
84+
"vitest": "2.0.5"
8485
},
8586
"publishConfig": {
8687
"access": "public"

playground/nuxt.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { fileURLToPath } from 'node:url'
2+
import MyModule from '../src/module'
23

34
export default defineNuxtConfig({
4-
modules : ['@privyid/nhp', '../src/module'],
5+
modules : ['@privyid/nhp', MyModule],
56
alias : { '@privyid/nuapi/core': fileURLToPath(new URL('../src/core/', import.meta.url)) },
67
nuapi : {},
78
typescript: {

src/core/dedupe.spec.ts

Lines changed: 14 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,25 @@
1-
import { http, HttpResponse } from 'msw'
2-
import { setupServer } from 'msw/node'
1+
import { useApi } from '.'
32
import {
4-
useApi,
5-
createApi,
6-
setApi,
7-
} from '.'
8-
import {
9-
beforeAll,
10-
afterEach,
113
describe,
124
it,
135
expect,
14-
afterAll,
156
} from 'vitest'
167

17-
const BASE_URL = 'http://localhost:3000'
18-
19-
const server = setupServer(
20-
http.get(`${BASE_URL}/api/ping`, () => {
21-
return HttpResponse.json({ message: 'Pong' })
22-
}),
23-
)
24-
25-
beforeAll(() => {
26-
server.listen()
27-
28-
setApi(createApi({ baseURL: BASE_URL }))
29-
})
30-
31-
afterEach(() => {
32-
server.resetHandlers()
33-
})
34-
35-
afterAll(() => {
36-
server.close()
37-
})
38-
398
describe('DedupeAdapter', () => {
40-
it('should cancel previous request with same requestId', async () => {
9+
it('should cancel previous request with same requestKey', async () => {
4110
const api = useApi()
42-
const a = api.get('/api/ping', { requestId: 'ping' })
43-
const b = api.get('/api/ping', { requestId: 'ping' })
11+
const a = api.get('/api/ping', { requestKey: 'ping' })
12+
const b = api.get('/api/ping', { requestKey: 'ping' })
4413
const result = await Promise.allSettled([a, b])
4514

4615
expect(result[0].status).toBe('rejected')
4716
expect(result[1].status).toBe('fulfilled')
4817
})
4918

50-
it('should do nothing if requestId is different', async () => {
19+
it('should do nothing if requestKey is different', async () => {
5120
const api = useApi()
52-
const a = api.get('/api/ping', { requestId: 'ping/a' })
53-
const b = api.get('/api/ping', { requestId: 'ping/b' })
21+
const a = api.get('/api/ping', { requestKey: 'ping/a' })
22+
const b = api.get('/api/ping', { requestKey: 'ping/b' })
5423
const result = await Promise.allSettled([a, b])
5524

5625
expect(result[0].status).toBe('fulfilled')
@@ -62,8 +31,8 @@ describe('DedupeAdapter', () => {
6231
const controller = new AbortController()
6332
const signal = controller.signal
6433

65-
const a = api.get('/api/ping', { requestId: 'ping/d', signal })
66-
const b = api.get('/api/ping', { requestId: 'ping/e' })
34+
const a = api.get('/api/ping', { requestKey: 'ping/d', signal })
35+
const b = api.get('/api/ping', { requestKey: 'ping/e' })
6736

6837
controller.abort()
6938

@@ -75,10 +44,10 @@ describe('DedupeAdapter', () => {
7544
})
7645

7746
describe('cancel', () => {
78-
it('should be cancel request only specific requestId', async () => {
47+
it('should be cancel request only specific requestKey', async () => {
7948
const api = useApi()
80-
const a = api.get('/api/ping', { requestId: 'ping/i' })
81-
const b = api.get('/api/ping', { requestId: 'ping/j' })
49+
const a = api.get('/api/ping', { requestKey: 'ping/i' })
50+
const b = api.get('/api/ping', { requestKey: 'ping/j' })
8251

8352
api.cancel('ping/i')
8453

@@ -92,8 +61,8 @@ describe('cancel', () => {
9261
describe('cancelAll', () => {
9362
it('should be cancel all active request', async () => {
9463
const api = useApi()
95-
const a = api.get('/api/ping', { requestId: 'ping/x' })
96-
const b = api.get('/api/ping', { requestId: 'ping/y' })
64+
const a = api.get('/api/ping', { requestKey: 'ping/x' })
65+
const b = api.get('/api/ping', { requestKey: 'ping/y' })
9766

9867
api.cancelAll()
9968

0 commit comments

Comments
 (0)