diff --git a/axios.d.ts b/axios.d.ts index 6ceaeaaea96986b15cd7811931ea0f4284022511..5895c015db9fc973e23061542716fb905994d707 100644 --- a/axios.d.ts +++ b/axios.d.ts @@ -6,18 +6,26 @@ declare var axios: axios.AxiosStatic declare module axios { - interface AxiosStatic { - (options: axios.RequestOptions): axios.Promise; + interface AxiosRequestMethods { get(url: string, config?: any): axios.Promise; delete(url: string, config?: any): axios.Promise; head(url: string, config?: any): axios.Promise; post(url: string, data: any, config?: any): axios.Promise; put(url: string, data: any, config?: any): axios.Promise; patch(url: string, data: any, config?: any): axios.Promise; + } + + interface AxiosStatic extends AxiosRequestMethods { + (options: axios.RequestOptions): axios.Promise; + create(defaultOptions?: axios.InstanceOptions): AxiosInstance; all(iterable: any): axios.Promise; spread(callback: any): axios.Promise; } - + + interface AxiosInstance extends AxiosRequestMethods { + request(options: axios.RequestOptions): axios.Promise; + } + interface Response { data?: any; status?: number; @@ -31,18 +39,23 @@ declare module axios { catch(onRejected:(response: axios.Response) => void): axios.Promise; } - interface RequestOptions { - url: string; - method?: string; + interface InstanceOptions { transformRequest?: (data: any) => any; + transformResponse?: (data: any) => any; headers?: any; - params?: any; - data?: any; + timeout?: number; withCredentials?: boolean; responseType?: string; xsrfCookieName?: string; xsrfHeaderName?: string; } + + interface RequestOptions extends InstanceOptions { + url: string; + method?: string; + params?: any; + data?: any; + } } declare module "axios" { diff --git a/lib/axios.js b/lib/axios.js index 6937894386b9d0d191a29e4882514f0bb81854b5..5c2727a8366a91f9deb3f737a57d0cf4da2f11f6 100644 --- a/lib/axios.js +++ b/lib/axios.js @@ -5,7 +5,21 @@ var utils = require('./utils'); var dispatchRequest = require('./core/dispatchRequest'); var InterceptorManager = require('./core/InterceptorManager'); -var axios = module.exports = function (config) { +function Axios (defaultConfig) { + this.defaultConfig = utils.merge({ + headers: {}, + timeout: defaults.timeout, + transformRequest: defaults.transformRequest, + transformResponse: defaults.transformResponse + }, defaultConfig); + + this.interceptors = { + request: new InterceptorManager(), + response: new InterceptorManager() + }; +} + +Axios.prototype.request = function (config) { // Allow for axios('example/url'[, config]) a la fetch API if (typeof config === 'string') { config = utils.merge({ @@ -13,13 +27,7 @@ var axios = module.exports = function (config) { }, arguments[1]); } - config = utils.merge({ - method: 'get', - headers: {}, - timeout: defaults.timeout, - transformRequest: defaults.transformRequest, - transformResponse: defaults.transformResponse - }, config); + config = utils.merge(this.defaultConfig, { method: 'get' }, config); // Don't allow overriding defaults.withCredentials config.withCredentials = config.withCredentials || defaults.withCredentials; @@ -28,11 +36,11 @@ var axios = module.exports = function (config) { var chain = [dispatchRequest, undefined]; var promise = Promise.resolve(config); - axios.interceptors.request.forEach(function (interceptor) { + this.interceptors.request.forEach(function (interceptor) { chain.unshift(interceptor.fulfilled, interceptor.rejected); }); - axios.interceptors.response.forEach(function (interceptor) { + this.interceptors.response.forEach(function (interceptor) { chain.push(interceptor.fulfilled, interceptor.rejected); }); @@ -43,6 +51,14 @@ var axios = module.exports = function (config) { return promise; }; +var defaultInstance = new Axios(); + +var axios = module.exports = bind(Axios.prototype.request, defaultInstance); + +axios.create = function (defaultConfig) { + return new Axios(defaultConfig); +}; + // Expose defaults axios.defaults = defaults; @@ -53,36 +69,42 @@ axios.all = function (promises) { axios.spread = require('./helpers/spread'); // Expose interceptors -axios.interceptors = { - request: new InterceptorManager(), - response: new InterceptorManager() -}; +axios.interceptors = defaultInstance.interceptors; // Provide aliases for supported request methods (function () { function createShortMethods() { utils.forEach(arguments, function (method) { - axios[method] = function (url, config) { - return axios(utils.merge(config || {}, { + Axios.prototype[method] = function (url, config) { + return this.request(utils.merge(config || {}, { method: method, url: url })); }; + axios[method] = bind(Axios.prototype[method], defaultInstance); }); } function createShortMethodsWithData() { utils.forEach(arguments, function (method) { - axios[method] = function (url, data, config) { - return axios(utils.merge(config || {}, { + Axios.prototype[method] = function (url, data, config) { + return this.request(utils.merge(config || {}, { method: method, url: url, data: data })); }; + axios[method] = bind(Axios.prototype[method], defaultInstance); }); } createShortMethods('delete', 'get', 'head'); createShortMethodsWithData('post', 'put', 'patch'); })(); + +// Helpers +function bind (fn, thisArg) { + return function () { + return fn.apply(thisArg, Array.prototype.slice.call(arguments)); + }; +} diff --git a/test/specs/api.spec.js b/test/specs/api.spec.js index abfd286b4b5bce637171d38258a47439d6689f4a..583b2bfb0dc3c236c69366602994f64c1896900e 100644 --- a/test/specs/api.spec.js +++ b/test/specs/api.spec.js @@ -1,6 +1,6 @@ var axios = require('../../index'); -describe('api', function () { +describe('static api', function () { it('should have request method helpers', function () { expect(typeof axios.get).toEqual('function'); expect(typeof axios.head).toEqual('function'); @@ -22,8 +22,36 @@ describe('api', function () { expect(typeof axios.defaults.headers).toEqual('object'); }); + it('should have interceptors', function () { + expect(typeof axios.interceptors.request).toEqual('object'); + expect(typeof axios.interceptors.response).toEqual('object'); + }); + it('should have all/spread helpers', function () { expect(typeof axios.all).toEqual('function'); expect(typeof axios.spread).toEqual('function'); }); + + it('should have factory method', function () { + expect(typeof axios.create).toEqual('function'); + }); +}); + +describe('instance api', function () { + var instance = axios.create(); + + it('should have request methods', function () { + expect(typeof instance.request).toEqual('function'); + expect(typeof instance.get).toEqual('function'); + expect(typeof instance.head).toEqual('function'); + expect(typeof instance.delete).toEqual('function'); + expect(typeof instance.post).toEqual('function'); + expect(typeof instance.put).toEqual('function'); + expect(typeof instance.patch).toEqual('function'); + }); + + it('should have interceptors', function () { + expect(typeof instance.interceptors.request).toEqual('object'); + expect(typeof instance.interceptors.response).toEqual('object'); + }); }); diff --git a/test/specs/instance.spec.js b/test/specs/instance.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..99c93d6817bc47b9bf00b8ea9743048b9ce01952 --- /dev/null +++ b/test/specs/instance.spec.js @@ -0,0 +1,41 @@ +var axios = require('../../index'); + +describe('instance', function () { + beforeEach(function () { + jasmine.Ajax.install(); + }); + + afterEach(function () { + jasmine.Ajax.uninstall(); + }); + + it('should make an http request', function (done) { + var instance = axios.create(); + + instance.request({ + url: '/foo' + }); + + setTimeout(function () { + request = jasmine.Ajax.requests.mostRecent(); + + expect(request.url).toBe('/foo'); + done(); + }, 0); + }); + + it('should use instance options', function (done) { + var instance = axios.create({ timeout: 1000 }); + + instance.request({ + url: '/foo' + }); + + setTimeout(function () { + request = jasmine.Ajax.requests.mostRecent(); + + expect(request.timeout).toBe(1000); + done(); + }, 0); + }); +}); diff --git a/test/typescript/axios.ts b/test/typescript/axios.ts index e957b50e5f40cadb0c80ca0cce4e0e5757f19469..83146a63cb1da2bd438ff1b6185075b14940d368 100644 --- a/test/typescript/axios.ts +++ b/test/typescript/axios.ts @@ -4,11 +4,11 @@ import axios = require('axios'); axios.get('/user?ID=12345') .then(function (response) { - console.log(response); - }) + console.log(response); + }) .catch(function (response) { - console.log(response); - }); + console.log(response); + }); axios.get('/user', { params: { @@ -96,16 +96,64 @@ axios({ }); axios({ - url: "hi", - headers: {'X-Requested-With': 'XMLHttpRequest'}, + url: "hi", + headers: {'X-Requested-With': 'XMLHttpRequest'}, + params: { + ID: 12345 + }, + data: { + firstName: 'Fred' + }, + withCredentials: false, // default + responseType: 'json', // default + xsrfCookieName: 'XSRF-TOKEN', // default + xsrfHeaderName: 'X-XSRF-TOKEN' // default +}); + +var instance = axios.create(); + +axios.create({ + transformRequest: (data) => { + return data.doSomething(); + }, + transformResponse: (data) => { + return data.doSomethingElse(); + }, + headers: {'X-Requested-With': 'XMLHttpRequest'}, + timeout: 1000, + withCredentials: false, // default + responseType: 'json', // default + xsrfCookieName: 'XSRF-TOKEN', // default + xsrfHeaderName: 'X-XSRF-TOKEN' // default +}); + +instance.request({ + method: 'get', + url: '/user/12345' + }) + .then(function (response) { + console.log(response); + }) + .catch(function (response) { + console.log(response); + }); + +instance.get('/user?ID=12345') + .then(function (response) { + console.log(response); + }) + .catch(function (response) { + console.log(response); + }); + +instance.get('/user', { params: { ID: 12345 - }, - data: { - firstName: 'Fred' - }, - withCredentials: false, // default - responseType: 'json', // default - xsrfCookieName: 'XSRF-TOKEN', // default - xsrfHeaderName: 'X-XSRF-TOKEN' // default -}); + } + }) + .then(function (response) { + console.log(response); + }) + .catch(function (response) { + console.log(response); + });