Skip to content

Commit

Permalink
Merge pull request #254 from contentful/chore/update-dependencies
Browse files Browse the repository at this point in the history
chore/update dependencies

BREAKING CHANGE: the interface of direct dependency `axios` changed
  • Loading branch information
marcolink authored Feb 9, 2022
2 parents 16e2114 + da75c71 commit e49871d
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 47 deletions.
24 changes: 13 additions & 11 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "contentful-sdk-core",
"version": "0.0.1-determined-by-semantic-release",
"version": "0.0.0-determined-by-semantic-release",
"description": "Core modules for the Contentful JS SDKs",
"homepage": "https://www.contentful.com/developers/docs/javascript/",
"main": "dist/index.js",
Expand All @@ -23,9 +23,9 @@
"build": "npm run clean && npm run build:types && npm run build:js",
"lint": "eslint src test --ext '.ts,.js'",
"pretest": "npm run lint",
"test": "tsdx test",
"test:watch": "tsdx test --watch",
"test:cover": "tsdx test --coverage",
"test": "jest",
"test:watch": "jest --watch",
"test:cover": "jest --coverage",
"browser-coverage": "npm run test:cover && opener coverage/lcov-report/index.html",
"prepublish": "in-publish && npm run build || not-in-publish",
"semantic-release": "semantic-release",
Expand All @@ -41,7 +41,7 @@
"bin"
],
"engines": {
"node": ">=6"
"node": ">=12"
},
"dependencies": {
"fast-copy": "^2.1.0",
Expand All @@ -64,13 +64,14 @@
"@semantic-release/npm": "^7.1.3",
"@semantic-release/release-notes-generator": "^9.0.3",
"@types/chai": "^4.2.21",
"@types/jest": "^27.4.0",
"@types/lodash.isplainobject": "^4.0.6",
"@types/lodash.isstring": "^4.0.6",
"@types/qs": "^6.9.5",
"@typescript-eslint/eslint-plugin": "4.33.0",
"@typescript-eslint/parser": "4.31.2",
"axios": "^0.21.0",
"axios-mock-adapter": "^1.15.0",
"@typescript-eslint/eslint-plugin": "^5.11.0",
"@typescript-eslint/parser": "^5.11.0",
"axios": "^0.25.0",
"axios-mock-adapter": "^1.20.0",
"babel-eslint": "^10.1.0",
"bundlesize": "^0.18.1",
"chai": "^4.3.4",
Expand All @@ -86,6 +87,7 @@
"eslint-plugin-standard": "^5.0.0",
"husky": "^7.0.0",
"in-publish": "^2.0.0",
"jest": "^27.5.1",
"lint-staged": "^12.0.2",
"mkdirp": "^1.0.4",
"moxios": "^0.4.0",
Expand All @@ -97,9 +99,9 @@
"rollup": "^2.34.0",
"rollup-plugin-babel": "^4.4.0",
"semantic-release": "^17.0.7",
"tsdx": "^0.14.1",
"ts-jest": "^27.1.3",
"tslib": "^2.0.3",
"typescript": "3.9.10"
"typescript": "^4.5.5"
},
"bundlesize": [
{
Expand Down
3 changes: 2 additions & 1 deletion src/create-http-client.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { AxiosRequestHeaders } from 'axios'
import copy from 'fast-copy'
import qs from 'qs'
import type { AxiosStatic } from 'axios'
Expand Down Expand Up @@ -38,7 +39,7 @@ export default function createHttpClient(
console.log(`[${level}] ${data}`)
},
// Passed to axios
headers: {} as Record<string, unknown>,
headers: {} as AxiosRequestHeaders,
httpAgent: false as const,
httpsAgent: false as const,
timeout: 30000,
Expand Down
2 changes: 1 addition & 1 deletion src/error-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function errorHandler(errorResponse: AxiosError): never {

// Obscure the Management token
if (config && config.headers && config.headers['Authorization']) {
const token = `...${config.headers['Authorization'].substr(-5)}`
const token = `...${config.headers['Authorization'].toString().substr(-5)}`
config.headers['Authorization'] = `Bearer ${token}`
}

Expand Down
9 changes: 1 addition & 8 deletions src/to-plain-object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,7 @@ import copy from 'fast-copy'
* @param data - Any plain JSON response returned from the API
* @return Enhanced object with toPlainObject method
*/
export default function toPlainObject<T = Record<string, unknown>, R = T>(
data: T
): T & {
/**
* Returns this entity as a plain JS object
*/
toPlainObject(): R
} {
export default function toPlainObject(data: unknown) {
return Object.defineProperty(data, 'toPlainObject', {
enumerable: false,
configurable: false,
Expand Down
3 changes: 2 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import { AxiosRequestHeaders } from 'axios'
import type {
AxiosInstance as OriginalAxiosInstance,
AxiosRequestConfig,
Expand Down Expand Up @@ -61,7 +62,7 @@ export type CreateHttpClientParams = {
logHandler?: DefaultOptions['logHandler']

/** Optional additional headers */
headers?: Record<string, unknown>
headers?: AxiosRequestHeaders

defaultHostname?: string

Expand Down
12 changes: 7 additions & 5 deletions test/unit/create-http-client-integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ it('should retrieve token asynchronously', async () => {
expect(instance.defaults.headers.Authorization).not.toBeDefined()

await instance.get('/test-endpoint')
expect(mock.history.get[0].headers.Authorization).toEqual('Bearer async-token')
expect(mock.history.get[0].headers?.Authorization).toEqual('Bearer async-token')
})

describe('custom interceptors', () => {
Expand All @@ -45,10 +45,10 @@ describe('custom interceptors', () => {
mock.onGet('/test-endpoint').replyOnce(200)

await instance.get('/test-endpoint')
expect(mock.history.get[0].headers['custom-header']).toEqual('custom-header-value')
expect(mock.history.get[0].headers?.['custom-header']).toEqual('custom-header-value')
})

it('is able to intercept responce codes', async () => {
it('is able to intercept response codes', async () => {
let accessToken = 'invalid-token'

const refreshToken = () => {
Expand All @@ -63,6 +63,8 @@ describe('custom interceptors', () => {
if (error.response.status === 403 && !originalRequest._retry403) {
originalRequest._retry403 = true
const newToken = await refreshToken()
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
axios.defaults.headers.Authorization = 'Bearer ' + newToken
return instance(originalRequest)
}
Expand All @@ -75,7 +77,7 @@ describe('custom interceptors', () => {

await instance.get('/test-endpoint')

expect(mock.history.get[0].headers.Authorization).toEqual('Bearer invalid-token')
expect(mock.history.get[1].headers.Authorization).toEqual('Bearer valid-token')
expect(mock.history.get[0].headers?.Authorization).toEqual('Bearer invalid-token')
expect(mock.history.get[1].headers?.Authorization).toEqual('Bearer valid-token')
})
})
22 changes: 12 additions & 10 deletions test/unit/create-http-client-test.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import createHttpClient from '../../src/create-http-client'

import axios, { AxiosAdapter } from 'axios'
Expand Down Expand Up @@ -84,25 +86,25 @@ it('Calls axios based on passed headers', () => {

const [callConfig] = mockedAxios.create.mock.calls[0]
expect(callConfig?.baseURL)
expect(callConfig?.headers['X-Custom-Header']).toEqual('example')
expect(callConfig?.headers.Authorization).toEqual('Basic customAuth')
expect(callConfig?.headers?.['X-Custom-Header']).toEqual('example')
expect(callConfig?.headers?.Authorization).toEqual('Basic customAuth')
})

it('Calls axios with reques/response logger', () => {
const requestloggerStub = jest.fn()
const responseloggerStub = jest.fn()
it('Calls axios with request/response logger', () => {
const requestLoggerStub = jest.fn()
const responseLoggerStub = jest.fn()
createHttpClient(axios, {
accessToken: 'clientAccessToken',
host: 'contentful.com',
insecure: true,
requestLogger: requestloggerStub,
responseLogger: responseloggerStub,
requestLogger: requestLoggerStub,
responseLogger: responseLoggerStub,
})

const [callConfig] = mockedAxios.create.mock.calls[0]
expect(callConfig?.baseURL).toEqual('http://contentful.com:80/spaces/')
expect(requestloggerStub).not.toHaveBeenCalled()
expect(responseloggerStub).not.toHaveBeenCalled()
expect(requestLoggerStub).not.toHaveBeenCalled()
expect(responseLoggerStub).not.toHaveBeenCalled()
})

it('Fails with missing access token', () => {
Expand All @@ -111,7 +113,7 @@ it('Fails with missing access token', () => {
createHttpClient(axios, {
logHandler: logHandlerStub,
})
} catch (err) {
} catch (err: any) {
expect(err instanceof TypeError).toBeTruthy()
expect(err.message).toEqual('Expected parameter accessToken')
expect(logHandlerStub).toHaveBeenCalledTimes(1)
Expand Down
12 changes: 7 additions & 5 deletions test/unit/error-handler-test.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import errorHandler from '../../src/error-handler'
import { errorMock } from './mocks'
import { expect } from 'chai'
Expand All @@ -21,7 +23,7 @@ describe('A errorHandler', () => {

try {
errorHandler(error)
} catch (err) {
} catch (err: any) {
const parsedMessage = JSON.parse(err.message)
expect(err.name).equals('SpecificError', 'error name')
expect(parsedMessage.request.url).equals('requesturl', 'request url')
Expand All @@ -46,7 +48,7 @@ describe('A errorHandler', () => {

try {
errorHandler(error)
} catch (err) {
} catch (err: any) {
const parsedMessage = JSON.parse(err.message)
expect(err.name).equals('500 Internal', 'error name defaults to status code and text')
expect(parsedMessage.request.url).equals('requesturl', 'request url')
Expand All @@ -61,7 +63,7 @@ describe('A errorHandler', () => {

try {
errorHandler(error)
} catch (err) {
} catch (err: any) {
const parsedMessage = JSON.parse(err.message)
expect(err.name).equals(
'500 Everything is on fire',
Expand All @@ -79,7 +81,7 @@ describe('A errorHandler', () => {

try {
errorHandler(responseError)
} catch (err) {
} catch (err: any) {
const parsedMessage = JSON.parse(err.message)
expect(parsedMessage.request.headers.Authorization).equals(
'Bearer ...token',
Expand All @@ -105,7 +107,7 @@ describe('A errorHandler', () => {

try {
errorHandler(requestError)
} catch (err) {
} catch (err: any) {
expect(err.config.headers.Authorization).equals('Bearer ...token', 'Obscures token')
}
})
Expand Down
12 changes: 7 additions & 5 deletions test/unit/rate-limit-test.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import axios from 'axios'
import MockAdapter from 'axios-mock-adapter'

Expand Down Expand Up @@ -89,7 +91,7 @@ it('Retry on network error', async () => {

try {
await client.get('/rate-limit-me')
} catch (error) {
} catch (error: any) {
// logs two attempts, one initial and one retry
expect(error.attempts).toEqual(2)
}
Expand All @@ -105,7 +107,7 @@ it('no retry when automatic handling flag is disabled', async () => {
expect.assertions(6)
try {
await client.get('/rate-limit-me')
} catch (error) {
} catch (error: any) {
expect(error.response.status).toEqual(500)
expect(error.response.headers['x-contentful-request-id']).toEqual(3)
expect(error.response.data).toEqual('Mocked 500 Error')
Expand All @@ -124,7 +126,7 @@ it('Should Fail if it hits maxRetries', async () => {
expect.assertions(5)
try {
await client.get('/error')
} catch (error) {
} catch (error: any) {
// returned error since maxRetries was reached
expect(error.response.data).toEqual('error attempt #2')
expect(logHandlerStub).toHaveBeenCalledTimes(1)
Expand All @@ -144,7 +146,7 @@ it('Retry on responses when X-Contentful-Request-Id header is missing', async ()

try {
await client.get('/error')
} catch (error) {
} catch (error: any) {
expect(error.response.data).toEqual('error attempt 2')
expect(logHandlerStub).toHaveBeenCalledTimes(1)
expect(logHandlerStub.mock.calls[0][0]).toEqual('warning')
Expand All @@ -161,7 +163,7 @@ it('Rejects errors with strange status codes', async () => {
expect.assertions(2)
try {
await client.get('/error')
} catch (error) {
} catch (error: any) {
expect(error.response.data).toEqual('error attempt')
// did not log anything
expect(logHandlerStub).toBeCalledTimes(0)
Expand Down

0 comments on commit e49871d

Please sign in to comment.