Skip to content

Commit b416509

Browse files
author
Weffe
committed
Merge branch 'dev'
2 parents 119a41f + 72fdca2 commit b416509

18 files changed

+18843
-1173
lines changed

.gitignore

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
node_modules/
22
*.log
3-
dist/
3+
dist/
4+
.DS_Store
5+
.rts2_cache_cjs
6+
.rts2_cache_es
7+
.rts2_cache_esm
8+
.rts2_cache_umd

package-lock.json

Lines changed: 15143 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 65 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,70 @@
11
{
2-
"name": "axios-api-versioning",
3-
"author": "Rogelio Negrete (Weffe)",
4-
"version": "2.1.0",
5-
"description": "Adds api versioning for axios",
6-
"main": "dist/lib/index.js",
7-
"module": "dist/esm/index.js",
8-
"jsnext:main": "dist/esm/index.js",
9-
"types": "dist/lib/index.d.ts",
10-
"sideEffects": false,
11-
"scripts": {
12-
"prestart": "run-s clean",
13-
"start": "tsc --watch",
14-
"build": "run-s clean build:cjs build:esm build:types",
15-
"build:cjs": "tsc",
16-
"build:esm": "tsc -p tsconfig.esm.json",
17-
"build:types": "tsc -p tsconfig.types.json",
18-
"sandbox": "tsc -p sandbox/tsconfig.sandbox.json",
19-
"clean": "rimraf dist/",
20-
"release": "standard-version",
21-
"docs": "docsify serve docs -o --port 2065",
22-
"test": "jest"
23-
},
24-
"keywords": [
25-
"axios",
26-
"api versioning"
27-
],
28-
"license": "MIT",
29-
"repository": {
30-
"type": "git",
31-
"url": "https://github.com/Weffe/axios-api-versioning"
32-
},
33-
"bugs": {
34-
"url": "https://github.com/Weffe/axios-api-versioning/issues"
35-
},
36-
"homepage": "https://github.com/Weffe/axios-api-versioning",
37-
"peerDependencies": {
38-
"axios": "^0.18.0"
39-
},
40-
"devDependencies": {
41-
"@types/jest": "^24.0.11",
42-
"axios": "^0.19.0",
43-
"axios-mock-adapter": "^1.16.0",
44-
"docsify-cli": "^4.3.0",
45-
"http-status-codes": "^1.3.2",
46-
"jest": "^24.1.0",
47-
"npm-run-all": "^4.1.5",
48-
"rimraf": "^2.6.3",
49-
"standard-version": "^6.0.1",
50-
"ts-jest": "^24.0.2",
51-
"typescript": "^3.3.3333"
52-
},
53-
"dependencies": {
54-
"tslib": "^1.9.3"
55-
},
56-
"files": [
57-
"dist",
58-
"README.md",
59-
"LICENSE"
60-
],
61-
"jest": {
62-
"roots": [
63-
"<rootDir>/src"
2+
"name": "axios-api-versioning",
3+
"author": "Rogelio Negrete (Weffe)",
4+
"version": "2.1.0",
5+
"description": "Adds api versioning for axios",
6+
"main": "dist/index.js",
7+
"module": "dist/axios-api-versioning.esm.js",
8+
"typings": "dist/index.d.ts",
9+
"sideEffects": false,
10+
"scripts": {
11+
"start": "tsdx watch",
12+
"build": "tsdx build",
13+
"test": "tsdx test",
14+
"sandbox": "tsc -p sandbox/tsconfig.sandbox.json",
15+
"prettier": "pretty-quick",
16+
"prerelease": "run-s test build",
17+
"release": "standard-version",
18+
"docs": "docsify serve docs -o --port 2065"
19+
},
20+
"keywords": [
21+
"axios",
22+
"api versioning"
6423
],
65-
"moduleFileExtensions": [
66-
"ts",
67-
"tsx",
68-
"js",
69-
"jsx",
70-
"json",
71-
"node"
24+
"license": "MIT",
25+
"repository": {
26+
"type": "git",
27+
"url": "https://github.com/Weffe/axios-api-versioning"
28+
},
29+
"bugs": {
30+
"url": "https://github.com/Weffe/axios-api-versioning/issues"
31+
},
32+
"homepage": "https://github.com/Weffe/axios-api-versioning",
33+
"peerDependencies": {
34+
"axios": "^0.18.0"
35+
},
36+
"devDependencies": {
37+
"@types/jest": "^25.1.2",
38+
"axios": "^0.19.2",
39+
"axios-mock-adapter": "^1.17.0",
40+
"docsify-cli": "^4.3.0",
41+
"http-status-codes": "^1.3.2",
42+
"husky": "^4.2.1",
43+
"npm-run-all": "^4.1.5",
44+
"prettier": "^1.19.1",
45+
"pretty-quick": "^2.0.1",
46+
"standard-version": "^7.1.0",
47+
"ts-jest": "^25.2.0",
48+
"tsdx": "^0.12.3",
49+
"typescript": "^3.7.5"
50+
},
51+
"files": [
52+
"dist",
53+
"README.md",
54+
"LICENSE"
7255
],
73-
"transform": {
74-
"^.+\\.ts$": "ts-jest"
56+
"husky": {
57+
"hooks": {
58+
"pre-commit": "pretty-quick --staged"
59+
}
7560
},
76-
"testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.ts$"
77-
}
61+
"prettier": {
62+
"printWidth": 130,
63+
"trailingComma": "es5",
64+
"tabWidth": 4,
65+
"useTabs": false,
66+
"singleQuote": true,
67+
"arrowParens": "always",
68+
"endOfLine": "lf"
69+
}
7870
}
Lines changed: 0 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +0,0 @@
1-
import axios from 'axios';
2-
import MockAdapter from 'axios-mock-adapter';
3-
import * as status from 'http-status-codes';
4-
import { withVersioning } from '../axios-api-versioning';
5-
import { IWithVersioningConfig, VersioningStrategy } from '../types';
6-
import { AxiosInstanceWithVersioning } from '../types/axios';
7-
8-
const test_url = 'http://localhost:3000';
9-
const MOCK_RES = 'hello_world';
10-
let mock: MockAdapter;
11-
let instance: AxiosInstanceWithVersioning;
12-
13-
describe('Testing correct response config of "QueryString" strategy', () => {
14-
let versioningConfig: IWithVersioningConfig = {
15-
apiVersion: '1.0',
16-
versioningStrategy: VersioningStrategy.QueryString
17-
};
18-
19-
beforeAll(() => {
20-
instance = withVersioning(axios, versioningConfig);
21-
mock = new MockAdapter(instance);
22-
})
23-
24-
test('it should have the "apiVersion" as a query param in the response config', async () => {
25-
mock.onGet(test_url)
26-
.reply(status.OK, MOCK_RES);
27-
28-
const res = await instance.get(test_url);
29-
const { params } = res.config;
30-
31-
expect(params).toHaveProperty('api-version');
32-
expect(params['api-version']).toBe(versioningConfig.apiVersion);
33-
})
34-
})
35-
36-
describe('Testing correct response config of "MediaType" strategy', () => {
37-
let versioningConfig: IWithVersioningConfig = {
38-
apiVersion: '1.0',
39-
versioningStrategy: VersioningStrategy.MediaType
40-
};
41-
42-
beforeAll(() => {
43-
instance = withVersioning(axios, versioningConfig);
44-
mock = new MockAdapter(instance);
45-
})
46-
47-
test('it should have the "apiVersion" as an accept-param in the Accept header', async () => {
48-
mock.onGet(test_url)
49-
.reply(status.OK, MOCK_RES);
50-
51-
const res = await instance.get(test_url);
52-
const { headers } = res.config;
53-
54-
expect(headers).toHaveProperty('Accept');
55-
expect(headers['Accept']).toMatch(`v=${versioningConfig.apiVersion}`)
56-
})
57-
})
58-
59-
describe('Testing correct response config of "UrlPath" strategy', () => {
60-
let versioningConfig: IWithVersioningConfig = {
61-
apiVersion: '1',
62-
versioningStrategy: VersioningStrategy.UrlPath
63-
};
64-
65-
const blank_test_url = test_url + "/v{apiVersion}";
66-
const versioned_test_url = test_url + `/v${versioningConfig.apiVersion}`;
67-
68-
beforeAll(() => {
69-
instance = withVersioning(axios, versioningConfig);
70-
mock = new MockAdapter(instance);
71-
})
72-
73-
test('it should have the "apiVersion" as a url param in the url', async () => {
74-
mock.onGet(versioned_test_url)
75-
.reply(status.OK, MOCK_RES);
76-
77-
const res = await instance.get(blank_test_url);
78-
const { url } = res.config;
79-
80-
expect(url).toBe(versioned_test_url);
81-
})
82-
})

src/axios-api-versioning-interceptor.ts

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { AxiosInstance } from 'axios';
2-
import { VersioningStrategy, IVersioningConfig, } from './types'
3-
import { AxiosRequestConfigWithVersioning } from './types/axios';
2+
import { VersioningStrategy, IVersioningConfig, AxiosRequestConfigWithVersioning } from './types';
43

54
function replaceUrlPathWithVersion(url: string, apiVersion: string) {
65
// the template name of the api version must be "apiVersion"
76
return url.replace('{apiVersion}', apiVersion);
87
}
98

10-
function enhanceConfigByVersioningStrategy(requestConfig: AxiosRequestConfigWithVersioning, versioningConfig: IVersioningConfig): AxiosRequestConfigWithVersioning {
11-
9+
function enhanceConfigByVersioningStrategy(
10+
requestConfig: AxiosRequestConfigWithVersioning,
11+
versioningConfig: IVersioningConfig
12+
): AxiosRequestConfigWithVersioning {
1213
// we prioritize the apiVersion passed via the RequestConfig first
1314
// then use the initial versioningConfig last
1415
const apiVersion = requestConfig['apiVersion'] || versioningConfig['apiVersion'];
@@ -19,13 +20,13 @@ function enhanceConfigByVersioningStrategy(requestConfig: AxiosRequestConfigWith
1920
if (versioningStrategy === VersioningStrategy.QueryString) {
2021
requestConfig.params = {
2122
...requestConfig.params,
22-
[versioningConfig.queryStringKeyName]: apiVersion
23+
[versioningConfig.queryStringKeyName]: apiVersion,
2324
};
2425
}
2526

2627
if (versioningStrategy === VersioningStrategy.MediaType) {
27-
const defaultAcceptHeader: string = requestConfig.headers.common["Accept"];
28-
const reqAcceptHeader: string | undefined = requestConfig.headers["Accept"] || undefined;
28+
const defaultAcceptHeader: string = requestConfig.headers.common['Accept'];
29+
const reqAcceptHeader: string | undefined = requestConfig.headers['Accept'] || undefined;
2930

3031
// we prioritize an accept header passed in the RequestConfig but default to the
3132
// the common default accept header value axios provides
@@ -35,24 +36,31 @@ function enhanceConfigByVersioningStrategy(requestConfig: AxiosRequestConfigWith
3536
const formattedAcceptHeader = versioningConfig.mediaTypeFormatter({
3637
apiVersion,
3738
acceptHeader,
38-
mediaTypeKeyName: versioningConfig.mediaTypeKeyName
39-
})
39+
mediaTypeKeyName: versioningConfig.mediaTypeKeyName,
40+
});
4041

4142
requestConfig.headers = {
4243
...requestConfig.headers,
43-
["Accept"]: formattedAcceptHeader
44-
}
45-
}
46-
else {
44+
['Accept']: formattedAcceptHeader,
45+
};
46+
} else {
4747
requestConfig.headers = {
4848
...requestConfig.headers,
49-
["Accept"]: acceptHeader + `;${versioningConfig.mediaTypeKeyName}=${apiVersion}`
50-
}
49+
['Accept']: acceptHeader + `;${versioningConfig.mediaTypeKeyName}=${apiVersion}`,
50+
};
5151
}
5252
}
5353

5454
if (versioningStrategy === VersioningStrategy.UrlPath) {
55-
requestConfig.url = replaceUrlPathWithVersion(requestConfig.url!, apiVersion);
55+
const { url, baseURL } = requestConfig;
56+
57+
if (url) {
58+
requestConfig.url = replaceUrlPathWithVersion(url, apiVersion);
59+
}
60+
61+
if (baseURL) {
62+
requestConfig.baseURL = replaceUrlPathWithVersion(baseURL, apiVersion);
63+
}
5664
}
5765

5866
return requestConfig;

src/axios-api-versioning.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import axios, { AxiosInstance, AxiosStatic } from 'axios';
22
import { AxiosInstanceWithVersioning } from './types/axios';
3-
import { IWithVersioningConfig, IVersioningConfig } from './types'
4-
import { injectApiVersioningInterceptor } from './axios-api-versioning-interceptor'
3+
import { IWithVersioningConfig, IVersioningConfig } from './types';
4+
import { injectApiVersioningInterceptor } from './axios-api-versioning-interceptor';
55
import { defaultWithVersioningConfig } from './defaultConfig';
66

77
export function withVersioning(instance: AxiosInstance | AxiosStatic, config: IWithVersioningConfig) {
@@ -15,4 +15,4 @@ export function withVersioning(instance: AxiosInstance | AxiosStatic, config: IW
1515
injectApiVersioningInterceptor(clonedInstance, versioningConfig);
1616

1717
return clonedInstance as AxiosInstanceWithVersioning;
18-
}
18+
}

src/defaultConfig.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { IVersioningConfig, PickPartial } from './types';
22

3-
export const defaultWithVersioningConfig: PickPartial<IVersioningConfig, "apiVersion" | "versioningStrategy"> = {
3+
export const defaultWithVersioningConfig: PickPartial<IVersioningConfig, 'apiVersion' | 'versioningStrategy'> = {
44
mediaTypeKeyName: 'v',
55
queryStringKeyName: 'api-version',
6-
}
6+
};

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export { withVersioning } from './axios-api-versioning';
22
export { VersioningStrategy, IWithVersioningConfig, MediaTypeFormatterFn } from './types';
3+
export * from './types/axios';

src/types/axios/axios.types.ts

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
// Matching type definitions for axios 0.18
22

3-
import {
4-
AxiosRequestConfig,
5-
AxiosPromise,
6-
AxiosInterceptorManager,
7-
AxiosResponse,
8-
} from 'axios';
3+
import { AxiosRequestConfig, AxiosPromise, AxiosInterceptorManager, AxiosResponse } from 'axios';
94

105
/**
116
* In order to only expose the apiVersion and versioningStrategy to axios instances with
@@ -44,15 +39,27 @@ export interface AxiosInstanceWithVersioning {
4439
get<T = any, R = AxiosResponseWithVersioning<T>>(url: string, config?: AxiosRequestConfigWithVersioning): Promise<R>;
4540
delete<T = any, R = AxiosResponseWithVersioning<T>>(url: string, config?: AxiosRequestConfigWithVersioning): Promise<R>;
4641
head<T = any, R = AxiosResponseWithVersioning<T>>(url: string, config?: AxiosRequestConfigWithVersioning): Promise<R>;
47-
post<T = any, R = AxiosResponseWithVersioning<T>>(url: string, data?: any, config?: AxiosRequestConfigWithVersioning): Promise<R>;
48-
put<T = any, R = AxiosResponseWithVersioning<T>>(url: string, data?: any, config?: AxiosRequestConfigWithVersioning): Promise<R>;
49-
patch<T = any, R = AxiosResponseWithVersioning<T>>(url: string, data?: any, config?: AxiosRequestConfigWithVersioning): Promise<R>;
42+
post<T = any, R = AxiosResponseWithVersioning<T>>(
43+
url: string,
44+
data?: any,
45+
config?: AxiosRequestConfigWithVersioning
46+
): Promise<R>;
47+
put<T = any, R = AxiosResponseWithVersioning<T>>(
48+
url: string,
49+
data?: any,
50+
config?: AxiosRequestConfigWithVersioning
51+
): Promise<R>;
52+
patch<T = any, R = AxiosResponseWithVersioning<T>>(
53+
url: string,
54+
data?: any,
55+
config?: AxiosRequestConfigWithVersioning
56+
): Promise<R>;
5057
}
5158

5259
export default interface AxiosTypes {
53-
AxiosRequestConfigWithVersioning: AxiosRequestConfigWithVersioning,
54-
AxiosAdapterWithVersioning: AxiosAdapterWithVersioning,
55-
AxiosResponseWithVersioning: AxiosResponseWithVersioning,
56-
AxiosErrorWithVersioning: AxiosErrorWithVersioning,
57-
AxiosInstanceWithVersioning: AxiosInstanceWithVersioning,
58-
}
60+
AxiosRequestConfigWithVersioning: AxiosRequestConfigWithVersioning;
61+
AxiosAdapterWithVersioning: AxiosAdapterWithVersioning;
62+
AxiosResponseWithVersioning: AxiosResponseWithVersioning;
63+
AxiosErrorWithVersioning: AxiosErrorWithVersioning;
64+
AxiosInstanceWithVersioning: AxiosInstanceWithVersioning;
65+
}

0 commit comments

Comments
 (0)