Releases: AckeeCZ/antonio
v5.0.0
v4.1.1
v4.0.12
4.0.12 (2022-06-28)
Changed
- ⬆️ Bump semver-regex from 3.1.3 to 3.1.4 [4267e43]
- ⬆️ Bump trim-off-newlines from 1.0.1 to 1.0.3 [0874d18]
- ⬆️ Bump node-fetch from 2.6.1 to 2.6.7 [fd0dd47]
- ⬆️ Bump nanoid from 3.1.23 to 3.3.4 [8b02ab9]
- ⬆️ Bump minimist from 1.2.5 to 1.2.6 [c265ece]
- ⬆️ Bump shelljs from 0.8.4 to 0.8.5 [9183b52]
Fixed
- 🐛 Fix takeLatestRequest [26468fc]
Packages
- @ackee/antonio-auth@4.0.12
- @ackee/antonio-core@4.0.12
- @ackee/antonio-utils@4.0.12
v4.0.10
v4.0.0
@ackee/antonio
has been written from the scratch on top of the fetch
API in Typescript and transformed to a monorepo containing:
- @ackee/antonio-core - The HTTP client.
- @ackee/antonio-utils - Custom redux-saga effects for canceling request.
- @ackee/antonio-auth - A request interceptor which sets the
Authorization
header to access token obtained from @ackee/petrus.
✨ What's new
-
No more 401 errors.
The req. interceptor from
@ackee/antonio-auth
obtains access token from@ackee/petrus
withgetAccessToken
and sets the
Authorization
header for each req. ThegetAccessToken
won't resolve until the access token is valid or when there's no auth session active. -
xhr
->fetch
@ackee/antonio-core
is self-independent HTTP client. There's no dependency on axios or other HTTP clients.- Service Worker supports only
fetch
(notxhr
), so now we can finally cache API requests.
-
Everything is in Typescript
-
@ackee/antonio-core
doesn't depend onredux-saga
Even though it supports generator functions, it doesn't require
redux-saga
at all but it's compatible with it.
Backwards compatibility with @ackee/antonio@3.x
I've tried to mimic the axios API as much as possible to simplify upgrading. But if a given property is redundant, it's been deprecated and is going to be removed in the next major release (i.e. v5.0.0
). You can see these properties in the 6. Step.
Browsers support
The source code is transpiled based on @ackee/browserslist-config
.
⬆️ How to upgrade
Required steps
-
Step - installation
yarn remove @ackee/antonio && yarn add @ackee/antonio-core -S
If you're using
@ackee/petrus
:yarn add @ackee/antonio-auth -S
And if upgrade
@ackee/petrus
to at least5.2.2
version.yarn add @ackee/petrus@5.2.2 -S
If you're using custom redux-saga effects for canceling API req.:
yarn add @ackee/antonio-utils -S
-
Step - instance creating
I've let theauthApi
var. reducing the number of changes, but it's redundant and can be removed.- import { create } from '@ackee/antonio'; + import { Antonio } from '@ackee/antonio-core'; - const { api, authApi, saga } = create({ + export const api = new Antonio({ baseURL: Config.api.base, }); - export { api, authApi, saga }; + export const authApi = new Antonio({ baseURL: Config.api.base, });
Also, disconnect the
saga
. -
Step - setting the
Authorization
header-
If you're using
@ackee/petrus
:- applyAccessTokenExternally: true, + applyAccessTokenExternally: false,
import { requestAuthHeaderInterceptor } from '@ackee/antonio-auth'; // Using the created instance from above authApi.interceptors.request.use(null, requestAuthHeaderInterceptor);
-
If you set the
Authorization
header manually and you have your own implementation ofgetAccessToken
:- applyAccessTokenExternally: true, + applyAccessTokenExternally: false,
import { setAuthHeader } from '@ackee/antonio-utils'; authApi.interceptors.request.use(null, function* (request) { const accessToken = yield getAccessToken(); setAuthHeader(requst.headers, accessToken); return request; });
-
-
Step - custom redux-saga effects
- export { takeLatestRequest, takeRequest } from '@ackee/antonio/es/saga-effects'; + export { takeLatestRequest, takeRequest } from '@ackee/antonio-utils';
-
Step -
responseData
->responseDataType
authApi.get('/file', { - responseType: 'blob', + responseDataType: 'blob', });
Optional steps
-
Step - enable TS autocompletion
- Replace
yield api.
withyield* api.
. - Replace
yield authApi.
withyield* authApi.
.
- Replace
-
Step - migrate from deprecated properties
- Change
cancelToken
tosignal
in each request:
- function* fetchUsers(action, cancelToken) { + function* fetchUsers(action, signal) { try { const { data, response } = yield* api.get(config.api.users, { - cancelToken, + signal, });
-
Change following properties in request result:
status
->response.status
statusText
->response.statusText
headers
->response.headers
config
->request
- const { data, response, request, status, statusText, headers, config } = yield api.get(config.api.users); + const { data, response: { status, statusText, headers }, request } = yield* api.get(config.api.users);
Example of
totalCount
header extraction:- const { data, headers } = yield api.get(config.api.users); - const totalCount = Number.parseInt(headers['x-total-count'], 10), + const { data, response: { headers } } = yield api.get(config.api.users); + const totalCount = Number.parseInt(headers.get('x-total-count'), 10),
- Change
-
Step - error handling
-
Change
- `error.response.data` + `error.data`
-
An
AntonioError
looks like:interface AntonioError<TErrorData> { name: 'AntonioError'; request: Request; response: Response; data: TErrorData; isAntonioError: true; }
so you can easily check it's an API error and get typed shaped of error data:
interface User { // ... } type Users = User[]; interface UsersErrorData { // ... } function* fetchUsers() { try { const { data } = yield* api.get<Users, UsersErrorData>('/users'); } catch (e) { if (isAntonioError(e)) { console.log(e.data); // is UsersErrorData interface } } }
-
🎉 You've finished it! Congrats. 👏
Maintainability & Contribution
From #47 each PR is going to have available sandbox env. built with CodeSandbox CI, so it can be manually tested before merging. And issues can be easily reproduced.