From 6cc8b95c2d80ca3d1cc0c5cd24df53ab47037bdc Mon Sep 17 00:00:00 2001 From: Joren Broekema Date: Thu, 12 Nov 2020 15:21:02 +0100 Subject: [PATCH] feat: add types for ajax --- .changeset/heavy-actors-retire.md | 5 + packages/ajax/package.json | 2 +- packages/ajax/src/AjaxClass.js | 116 ++++++++++++------ packages/ajax/src/ajax.js | 2 +- packages/ajax/src/interceptors.js | 25 +++- packages/ajax/src/transformers.js | 5 +- .../ajax/test/AjaxClass.interceptors.test.js | 31 ++++- .../ajax/test/AjaxClass.languages.test.js | 14 ++- packages/ajax/test/AjaxClass.test.js | 14 ++- .../ajax/test/AjaxClass.transformers.test.js | 18 ++- packages/ajax/test/ajax.test.js | 9 +- tsconfig.json | 1 - 12 files changed, 176 insertions(+), 66 deletions(-) create mode 100644 .changeset/heavy-actors-retire.md diff --git a/.changeset/heavy-actors-retire.md b/.changeset/heavy-actors-retire.md new file mode 100644 index 000000000..b3a6218ad --- /dev/null +++ b/.changeset/heavy-actors-retire.md @@ -0,0 +1,5 @@ +--- +'@lion/ajax': patch +--- + +Added types for ajax package, although they are mostly quite butchered. This is due to the complexity of interceptor factories and bundled-es-modules/axios not exporting types, which makes it really difficult to type it properly. diff --git a/packages/ajax/package.json b/packages/ajax/package.json index 68b56f519..dcd08c0bf 100644 --- a/packages/ajax/package.json +++ b/packages/ajax/package.json @@ -23,7 +23,7 @@ "types" ], "scripts": { - "debug": "cd ../../ && npm run -- --debug ajax", + "debug": "cd ../../ && npm run debug -- --group ajax", "debug:firefox": "cd ../../ && npm run debug:firefox -- --group ajax", "debug:webkit": "cd ../../ && npm run debug:webkit -- --group ajax", "prepublishOnly": "../../scripts/npm-prepublish.js", diff --git a/packages/ajax/src/AjaxClass.js b/packages/ajax/src/AjaxClass.js index 42b18366e..2ce97cc9a 100644 --- a/packages/ajax/src/AjaxClass.js +++ b/packages/ajax/src/AjaxClass.js @@ -1,3 +1,4 @@ +// @ts-ignore no types for bundled-es-modules/axios import { axios } from '@bundled-es-modules/axios'; import { cancelInterceptorFactory, @@ -6,6 +7,21 @@ import { } from './interceptors.js'; import { jsonPrefixTransformerFactory } from './transformers.js'; +/** + * @typedef {(config: {[key:string]: ?}) => { transformRequest: (data: string, headers: { [key: string]: any; }) => any;}} RequestInterceptor + * @typedef {(config: {[key:string]: ?}) => Response} ResponseInterceptor + * + * @typedef {Object} AjaxConfig + * @property {string} [jsonPrefix] prefixing the JSON string in this manner is used to help + * prevent JSON Hijacking. The prefix renders the string syntactically invalid as a script so + * that it cannot be hijacked. This prefix should be stripped before parsing the string as JSON. + * @property {string} [lang] language + * @property {boolean} [languageHeader] the Accept-Language request HTTP header advertises + * which languages the client is able to understand, and which locale variant is preferred. + * @property {boolean} [cancelable] if request can be canceled + * @property {boolean} [cancelPreviousOnNewRequest] prevents concurrent requests + */ + /** * `AjaxClass` creates the singleton instance {@link:ajax}. It is a promise based system for * fetching data, based on [axios](https://github.com/axios/axios). @@ -16,15 +32,7 @@ export class AjaxClass { */ /** - * @param {Object} config configuration for the AjaxClass instance - * @param {string} config.jsonPrefix prefixing the JSON string in this manner is used to help - * prevent JSON Hijacking. The prefix renders the string syntactically invalid as a script so - * that it cannot be hijacked. This prefix should be stripped before parsing the string as JSON. - * @param {string} config.lang language - * @param {string} config.languageHeader the Accept-Language request HTTP header advertises - * which languages the client is able to understand, and which locale variant is preferred. - * @param {string} config.cancelable if request can be canceled - * @param {string} config.cancelPreviousOnNewRequest prevents concurrent requests + * @param {AjaxConfig} [config] configuration for the AjaxClass instance */ constructor(config) { this.__config = { @@ -34,33 +42,41 @@ export class AjaxClass { cancelPreviousOnNewRequest: false, ...config, }; - this.proxy = axios.create(this.__config); this.__setupInterceptors(); + /** @type {Array.} */ this.requestInterceptors = []; + /** @type {Array.} */ this.requestErrorInterceptors = []; - - this.requestDataTransformers = []; - this.requestDataErrorTransformers = []; - - this.responseDataTransformers = []; - this.responseDataErrorTransformers = []; - - this.responseInterceptors = []; + /** @type {Array.} */ this.responseErrorInterceptors = []; + /** @type {Array.} */ + this.responseInterceptors = []; + + /** @type {Array.<(data: string, headers?: {[key:string]: ?}) => string>} */ + this.requestDataTransformers = []; + /** @type {Array.<(data: string, headers?: {[key:string]: ?}) => string>} */ + this.requestDataErrorTransformers = []; + /** @type {Array.<(data: string, headers?: {[key:string]: ?}) => string>} */ + this.responseDataErrorTransformers = []; + /** @type {Array.<(data: string, headers?: {[key:string]: ?}) => string>} */ + this.responseDataTransformers = []; this.__isInterceptorsSetup = false; if (this.__config.languageHeader) { + // @ts-ignore butchered something here.. this.requestInterceptors.push(addAcceptLanguageHeaderInterceptorFactory(this.__config.lang)); } if (this.__config.cancelable) { + // @ts-ignore butchered something here.. this.requestInterceptors.push(cancelInterceptorFactory(this)); } if (this.__config.cancelPreviousOnNewRequest) { + // @ts-ignore butchered something here.. this.requestInterceptors.push(cancelPreviousOnNewRequestInterceptorFactory()); } @@ -72,30 +88,38 @@ export class AjaxClass { /** * Sets the config for the instance + * @param {AjaxConfig} config configuration for the AjaxClass instance */ set options(config) { + // @ts-ignore butchered something here.. this.__config = config; } get options() { + // @ts-ignore butchered something here.. return this.__config; } /** * Dispatches a request * @see https://github.com/axios/axios - * @param {AxiosRequestConfig} config the config specific for this request - * @returns {AxiosResponseSchema} + * @param {string} url + * @param {{[key:string]: ?}} [config] the config specific for this request + * @returns {?} */ request(url, config) { return this.proxy.request.apply(this, [url, { ...this.__config, ...config }]); } + /** @param {string} msg */ + // eslint-disable-next-line class-methods-use-this, no-unused-vars + cancel(msg) {} + /** * Dispatches a {@link AxiosRequestConfig} with method 'get' predefined * @param {string} url the endpoint location - * @param {AxiosRequestConfig} config the config specific for this request - * @returns {AxiosResponseSchema} + * @param {{[key:string]: ?}} [config] the config specific for this request + * @returns {?} */ get(url, config) { return this.proxy.get.apply(this, [url, { ...this.__config, ...config }]); @@ -104,8 +128,8 @@ export class AjaxClass { /** * Dispatches a {@link AxiosRequestConfig} with method 'delete' predefined * @param {string} url the endpoint location - * @param {AxiosRequestConfig} config the config specific for this request - * @returns {AxiosResponseSchema} + * @param {{[key:string]: ?}} [config] the config specific for this request + * @returns {?} */ delete(url, config) { return this.proxy.delete.apply(this, [url, { ...this.__config, ...config }]); @@ -114,8 +138,8 @@ export class AjaxClass { /** * Dispatches a {@link AxiosRequestConfig} with method 'head' predefined * @param {string} url the endpoint location - * @param {AxiosRequestConfig} config the config specific for this request - * @returns {AxiosResponseSchema} + * @param {{[key:string]: ?}} [config] the config specific for this request + * @returns {?} */ head(url, config) { return this.proxy.head.apply(this, [url, { ...this.__config, ...config }]); @@ -124,8 +148,8 @@ export class AjaxClass { /** * Dispatches a {@link AxiosRequestConfig} with method 'options' predefined * @param {string} url the endpoint location - * @param {AxiosRequestConfig} config the config specific for this request - * @returns {AxiosResponseSchema} + * @param {{[key:string]: ?}} [config] the config specific for this request + * @returns {?} */ // options(url, config) { // return this.proxy.options.apply(this, [url, { ...this.__config, ...config }]); @@ -134,9 +158,9 @@ export class AjaxClass { /** * Dispatches a {@link AxiosRequestConfig} with method 'post' predefined * @param {string} url the endpoint location - * @param {Object} data the data to be sent to the endpoint - * @param {AxiosRequestConfig} config the config specific for this request - * @returns {AxiosResponseSchema} + * @param {Object} [data] the data to be sent to the endpoint + * @param {{[key:string]: ?}} [config] the config specific for this request + * @returns {?} */ post(url, data, config) { return this.proxy.post.apply(this, [url, data, { ...this.__config, ...config }]); @@ -145,9 +169,9 @@ export class AjaxClass { /** * Dispatches a {@link AxiosRequestConfig} with method 'put' predefined * @param {string} url the endpoint location - * @param {Object} data the data to be sent to the endpoint - * @param {AxiosRequestConfig} config the config specific for this request - * @returns {AxiosResponseSchema} + * @param {Object} [data] the data to be sent to the endpoint + * @param {{[key:string]: ?}} [config] the config specific for this request + * @returns {?} */ put(url, data, config) { return this.proxy.put.apply(this, [url, data, { ...this.__config, ...config }]); @@ -157,9 +181,9 @@ export class AjaxClass { * Dispatches a {@link AxiosRequestConfig} with method 'patch' predefined * @see https://github.com/axios/axios (Request Config) * @param {string} url the endpoint location - * @param {Object} data the data to be sent to the endpoint - * @param {Object} config the config specific for this request. - * @returns {AxiosResponseSchema} + * @param {Object} [data] the data to be sent to the endpoint + * @param {Object} [config] the config specific for this request. + * @returns {?} */ patch(url, data, config) { return this.proxy.patch.apply(this, [url, data, { ...this.__config, ...config }]); @@ -167,30 +191,39 @@ export class AjaxClass { __setupInterceptors() { this.proxy.interceptors.request.use( - config => { + /** @param {{[key:string]: unknown}} config */ config => { const configWithTransformers = this.__setupTransformers(config); + // @ts-ignore I dont know.... return this.requestInterceptors.reduce((c, i) => i(c), configWithTransformers); }, - error => { + /** @param {Error} error */ error => { this.requestErrorInterceptors.forEach(i => i(error)); return Promise.reject(error); }, ); this.proxy.interceptors.response.use( + /** + * @param {Response} response + */ response => this.responseInterceptors.reduce((r, i) => i(r), response), - error => { + /** @param {Error} error */ error => { this.responseErrorInterceptors.forEach(i => i(error)); return Promise.reject(error); }, ); } + /** @param {{[key:string]: ?}} config */ __setupTransformers(config) { const axiosTransformRequest = config.transformRequest[0]; const axiosTransformResponse = config.transformResponse[0]; return { ...config, + /** + * @param {string} data + * @param {{[key:string]: ?}} headers + */ transformRequest: (data, headers) => { try { const ourData = this.requestDataTransformers.reduce((d, t) => t(d, headers), data); @@ -202,6 +235,9 @@ export class AjaxClass { throw error; } }, + /** + * @param {string} data + */ transformResponse: data => { try { // axios does a lot of smart things with the response that people rely on diff --git a/packages/ajax/src/ajax.js b/packages/ajax/src/ajax.js index 540f690c5..3bcf1cf54 100644 --- a/packages/ajax/src/ajax.js +++ b/packages/ajax/src/ajax.js @@ -2,7 +2,7 @@ import { singletonManager } from 'singleton-manager'; import { AjaxClass } from './AjaxClass.js'; /** - * @typedef {ajax} ajax the global instance for handling all ajax requests + * */ export let ajax = singletonManager.get('@lion/ajax::ajax::0.3.x') || new AjaxClass(); // eslint-disable-line import/no-mutable-exports diff --git a/packages/ajax/src/interceptors.js b/packages/ajax/src/interceptors.js index 6bd785f66..42f5a58c7 100644 --- a/packages/ajax/src/interceptors.js +++ b/packages/ajax/src/interceptors.js @@ -1,7 +1,14 @@ +// @ts-ignore no types for bundled-es-modules/axios import { axios } from '@bundled-es-modules/axios'; +/** + * @param {string} [lang] + * @return {(config: {[key:string]: ?}) => {[key:string]: ?}} + */ export function addAcceptLanguageHeaderInterceptorFactory(lang) { - return config => { + console.log('add language header'); + console.log(lang); + return /** @param {{[key:string]: ?}} config */ config => { const result = config; if (typeof lang === 'string' && lang !== '') { if (typeof result.headers !== 'object') { @@ -14,23 +21,35 @@ export function addAcceptLanguageHeaderInterceptorFactory(lang) { }; } +/** + * @param {import('./AjaxClass').AjaxClass} ajaxInstance + * @return {(config: {[key:string]: ?}) => {[key:string]: ?}} + */ export function cancelInterceptorFactory(ajaxInstance) { + /** @type {unknown[]} */ const cancelSources = []; - return config => { + return /** @param {{[key:string]: ?}} config */ config => { const source = axios.CancelToken.source(); cancelSources.push(source); /* eslint-disable-next-line no-param-reassign */ ajaxInstance.cancel = (message = 'Operation canceled by the user.') => { + // @ts-ignore axios is untyped so we don't know the type for the source cancelSources.forEach(s => s.cancel(message)); }; return { ...config, cancelToken: source.token }; }; } +/** + * @return {(config: {[key:string]: ?}) => {[key:string]: ?}} + */ export function cancelPreviousOnNewRequestInterceptorFactory() { + // @ts-ignore axios is untyped so we don't know the type for the source let prevCancelSource; - return config => { + return /** @param {{[key:string]: ?}} config */ config => { + // @ts-ignore axios is untyped so we don't know the type for the source if (prevCancelSource) { + // @ts-ignore prevCancelSource.cancel('Concurrent requests not allowed.'); } const source = axios.CancelToken.source(); diff --git a/packages/ajax/src/transformers.js b/packages/ajax/src/transformers.js index d02a823f6..d5a43b44b 100644 --- a/packages/ajax/src/transformers.js +++ b/packages/ajax/src/transformers.js @@ -1,5 +1,8 @@ +/** + * @param {string} prefix + */ export function jsonPrefixTransformerFactory(prefix) { - return data => { + return /** @param {string} data */ data => { let result = data; if (typeof result === 'string') { if (prefix.length > 0 && result.indexOf(prefix) === 0) { diff --git a/packages/ajax/test/AjaxClass.interceptors.test.js b/packages/ajax/test/AjaxClass.interceptors.test.js index 18c0c9442..9df4893ea 100644 --- a/packages/ajax/test/AjaxClass.interceptors.test.js +++ b/packages/ajax/test/AjaxClass.interceptors.test.js @@ -4,8 +4,20 @@ import sinon from 'sinon'; import { AjaxClass } from '../src/AjaxClass.js'; describe('AjaxClass interceptors', () => { + /** @type {import('sinon').SinonFakeServer} */ let server; + /** + * @param {Object} [cfg] configuration for the AjaxClass instance + * @param {string} cfg.jsonPrefix prefixing the JSON string in this manner is used to help + * prevent JSON Hijacking. The prefix renders the string syntactically invalid as a script so + * that it cannot be hijacked. This prefix should be stripped before parsing the string as JSON. + * @param {string} cfg.lang language + * @param {boolean} cfg.languageHeader the Accept-Language request HTTP header advertises + * which languages the client is able to understand, and which locale variant is preferred. + * @param {boolean} cfg.cancelable if request can be canceled + * @param {boolean} cfg.cancelPreviousOnNewRequest prevents concurrent requests + */ function getInstance(cfg) { return new AjaxClass(cfg); } @@ -62,7 +74,7 @@ describe('AjaxClass interceptors', () => { ajax[type].push(myInterceptor); await ajax.get('data.json'); - ajax[type] = ajax[type].filter(item => item !== myInterceptor); + ajax[type] = ajax[type].filter(/** @param {?} item */ item => item !== myInterceptor); await ajax.get('data.json'); expect(myInterceptor.callCount).to.eql(1); @@ -73,12 +85,14 @@ describe('AjaxClass interceptors', () => { it('has access to provided instance config(options) on requestInterceptors', async () => { server.respondWith('GET', 'data.json', [200, { 'Content-Type': 'application/json' }, '{}']); const ajax = getInstance(); + // @ts-ignore setting a prop that isn't existing on options ajax.options.myCustomValue = 'foo'; let customValueAccess = false; - const myInterceptor = config => { + const myInterceptor = /** @param {{[key: string]: ?}} config */ config => { customValueAccess = config.myCustomValue === 'foo'; return config; }; + // @ts-ignore butchered something here.. ajax.requestInterceptors.push(myInterceptor); await ajax.get('data.json'); expect(customValueAccess).to.eql(true); @@ -97,8 +111,12 @@ describe('AjaxClass interceptors', () => { { 'Content-Type': 'application/json' }, '{ "method": "put" }', ]); - const enforcePutInterceptor = config => ({ ...config, method: 'PUT' }); + const enforcePutInterceptor = /** @param {{[key: string]: ?}} config */ config => ({ + ...config, + method: 'PUT', + }); const myAjax = getInstance(); + // @ts-ignore butchered something here.. myAjax.requestInterceptors.push(enforcePutInterceptor); const response = await myAjax.post('data.json'); expect(response.data).to.deep.equal({ method: 'put' }); @@ -112,11 +130,12 @@ describe('AjaxClass interceptors', () => { { 'Content-Type': 'application/json' }, '{ "method": "get" }', ]); - const addDataInterceptor = response => ({ - ...response, - data: { ...response.data, foo: 'bar' }, + const addDataInterceptor = /** @param {{[key: string]: ?}} config */ config => ({ + ...config, + data: { ...config.data, foo: 'bar' }, }); const myAjax = getInstance(); + // @ts-ignore I probably butchered the types here or adding data like above is simply not allowed in Response objects myAjax.responseInterceptors.push(addDataInterceptor); const response = await myAjax.get('data.json'); expect(response.data).to.deep.equal({ method: 'get', foo: 'bar' }); diff --git a/packages/ajax/test/AjaxClass.languages.test.js b/packages/ajax/test/AjaxClass.languages.test.js index c453bde27..823c546f2 100644 --- a/packages/ajax/test/AjaxClass.languages.test.js +++ b/packages/ajax/test/AjaxClass.languages.test.js @@ -4,7 +4,9 @@ import sinon from 'sinon'; import { AjaxClass } from '../src/AjaxClass.js'; describe('AjaxClass languages', () => { + /** @type {import('sinon').SinonFakeXMLHttpRequestStatic} */ let fakeXhr; + /** @type {import('sinon').SinonFakeXMLHttpRequest[]} */ let requests; beforeEach(() => { @@ -21,10 +23,12 @@ describe('AjaxClass languages', () => { }); it('sets "Accept-Language" header to "en-GB" for one request if ', async () => { + console.log('setting lang'); document.documentElement.lang = 'en-GB'; + console.log('after setting lang'); const req = new AjaxClass(); req.get('data.json'); - await aTimeout(); + await aTimeout(0); expect(requests.length).to.equal(1); expect(requests[0].requestHeaders['Accept-Language']).to.equal('en-GB'); }); @@ -36,7 +40,7 @@ describe('AjaxClass languages', () => { req.post('data2.json'); req.put('data3.json'); req.delete('data4.json'); - await aTimeout(); + await aTimeout(0); expect(requests.length).to.equal(4); requests.forEach(request => { expect(request.requestHeaders['Accept-Language']).to.equal('en-GB'); @@ -47,7 +51,7 @@ describe('AjaxClass languages', () => { document.documentElement.lang = 'nl-NL'; const req = new AjaxClass(); req.get('data.json'); - await aTimeout(); + await aTimeout(0); expect(requests.length).to.equal(1); expect(requests[0].requestHeaders['Accept-Language']).to.equal('nl-NL'); }); @@ -59,7 +63,7 @@ describe('AjaxClass languages', () => { req.post('data2.json'); req.put('data3.json'); req.delete('data4.json'); - await aTimeout(); + await aTimeout(0); expect(requests.length).to.equal(4); requests.forEach(request => { expect(request.requestHeaders['Accept-Language']).to.equal('nl-NL'); @@ -70,7 +74,7 @@ describe('AjaxClass languages', () => { document.documentElement.lang = ''; const req = new AjaxClass(); req.get('data.json'); - await aTimeout(); + await aTimeout(0); expect(requests.length).to.equal(1); expect(requests[0].requestHeaders['Accept-Language']).to.equal(undefined); }); diff --git a/packages/ajax/test/AjaxClass.test.js b/packages/ajax/test/AjaxClass.test.js index 5738d9dd2..109018fd7 100644 --- a/packages/ajax/test/AjaxClass.test.js +++ b/packages/ajax/test/AjaxClass.test.js @@ -5,8 +5,20 @@ import { AjaxClass } from '../src/AjaxClass.js'; import { ajax } from '../src/ajax.js'; describe('AjaxClass', () => { + /** @type {import('sinon').SinonFakeServer} */ let server; + /** + * @param {Object} [cfg] configuration for the AjaxClass instance + * @param {string} [cfg.jsonPrefix] prefixing the JSON string in this manner is used to help + * prevent JSON Hijacking. The prefix renders the string syntactically invalid as a script so + * that it cannot be hijacked. This prefix should be stripped before parsing the string as JSON. + * @param {string} [cfg.lang] language + * @param {boolean} [cfg.languageHeader] the Accept-Language request HTTP header advertises + * which languages the client is able to understand, and which locale variant is preferred. + * @param {boolean} [cfg.cancelable] if request can be canceled + * @param {boolean} [cfg.cancelPreviousOnNewRequest] prevents concurrent requests + */ function getInstance(cfg) { return new AjaxClass(cfg); } @@ -200,7 +212,7 @@ describe('AjaxClass', () => { '{ "method": "get" }', ]); - const makeRequest = async url => { + const makeRequest = /** @param {string} url */ async url => { try { await myAjax.get(url); throw new Error('is resolved'); diff --git a/packages/ajax/test/AjaxClass.transformers.test.js b/packages/ajax/test/AjaxClass.transformers.test.js index 847e9f42c..f8180ba1b 100644 --- a/packages/ajax/test/AjaxClass.transformers.test.js +++ b/packages/ajax/test/AjaxClass.transformers.test.js @@ -4,8 +4,20 @@ import sinon from 'sinon'; import { AjaxClass } from '../src/AjaxClass.js'; describe('AjaxClass transformers', () => { + /** @type {import('sinon').SinonFakeServer} */ let server; + /** + * @param {Object} [cfg] configuration for the AjaxClass instance + * @param {string} [cfg.jsonPrefix] prefixing the JSON string in this manner is used to help + * prevent JSON Hijacking. The prefix renders the string syntactically invalid as a script so + * that it cannot be hijacked. This prefix should be stripped before parsing the string as JSON. + * @param {string} [cfg.lang] language + * @param {boolean} [cfg.languageHeader] the Accept-Language request HTTP header advertises + * which languages the client is able to understand, and which locale variant is preferred. + * @param {boolean} [cfg.cancelable] if request can be canceled + * @param {boolean} [cfg.cancelPreviousOnNewRequest] prevents concurrent requests + */ function getInstance(cfg) { return new AjaxClass(cfg); } @@ -62,7 +74,7 @@ describe('AjaxClass transformers', () => { ajax[type].push(myTransformer); await ajax.get('data.json'); - ajax[type] = ajax[type].filter(item => item !== myTransformer); + ajax[type] = ajax[type].filter(/** @param {?} item */ item => item !== myTransformer); await ajax.get('data.json'); expect(myTransformer.callCount).to.eql(1); @@ -78,7 +90,7 @@ describe('AjaxClass transformers', () => { { 'Content-Type': 'application/json' }, '{ "method": "post" }', ]); - const addBarTransformer = data => ({ ...data, bar: 'bar' }); + const addBarTransformer = /** @param {?} data */ data => ({ ...data, bar: 'bar' }); const myAjax = getInstance(); myAjax.requestDataTransformers.push(addBarTransformer); const response = await myAjax.post('data.json', { foo: 'foo' }); @@ -96,7 +108,7 @@ describe('AjaxClass transformers', () => { { 'Content-Type': 'application/json' }, '{ "method": "get" }', ]); - const addBarTransformer = data => ({ ...data, bar: 'bar' }); + const addBarTransformer = /** @param {?} data */ data => ({ ...data, bar: 'bar' }); const myAjax = getInstance(); myAjax.responseDataTransformers.push(addBarTransformer); const response = await myAjax.get('data.json'); diff --git a/packages/ajax/test/ajax.test.js b/packages/ajax/test/ajax.test.js index 86d79e2f9..b3fb262c3 100644 --- a/packages/ajax/test/ajax.test.js +++ b/packages/ajax/test/ajax.test.js @@ -4,6 +4,7 @@ import sinon from 'sinon'; import { ajax } from '../src/ajax.js'; describe('ajax', () => { + /** @type {import('sinon').SinonFakeServer} */ let server; beforeEach(() => { @@ -32,7 +33,7 @@ describe('ajax', () => { { 'Content-Type': 'application/json' }, '{"success": true}', ]); - const makeRequest = async method => { + const makeRequest = /** @param {string} method */ async method => { const response = await ajax[method]('data.json', { foo: 'bar' }); expect(response.status).to.equal(200); expect(response.data).to.deep.equal({ success: true }); @@ -46,7 +47,7 @@ describe('ajax', () => { { 'Content-Type': 'application/json' }, '{"success": true}', ]); - const makeRequest = async method => { + const makeRequest = /** @param {string} method */ async method => { const response = await ajax[method]('data.json', { data: 'foobar' }, { foo: 'bar' }); expect(response.status).to.equal(200); expect(response.data).to.deep.equal({ success: true }); @@ -62,7 +63,7 @@ describe('ajax', () => { '{"success": true}', ]); - const makeRequest = async method => { + const makeRequest = /** @param {string} method */ async method => { const response = await ajax[method]('data.json'); expect(response.config.headers['X-XSRF-TOKEN']).to.equal('test'); expect(response.status).to.equal(200); @@ -82,7 +83,7 @@ describe('ajax', () => { '{"success": true}', ]); - const makeRequest = async method => { + const makeRequest = /** @param {string} method */ async method => { const response = await ajax[method]('data.json'); expect(response.config.headers['X-XSRF-TOKEN']).to.equal(undefined); expect(response.status).to.equal(200); diff --git a/tsconfig.json b/tsconfig.json index 5d9493e95..e5394d49b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -29,7 +29,6 @@ "packages/overlays/test/utils-tests/**/*.js", // TODO: Needs to get typed! "packages/form-integrations/test/**/*.js", // TODO: Needs to get typed! "packages/combobox/test/**/*.js", // TODO: Needs to get typed! - "packages/ajax/**/*.js", // Deprecated because we will move to redaxios soon. // ignore test/demos for singleton manager until overlays are typed as it's used in there "packages/singleton-manager/demo/", "packages/singleton-manager/test/"