diff --git a/src/services/abstractService.ts b/src/services/abstractService.ts index 78caa0d0b..0b3002ce3 100644 --- a/src/services/abstractService.ts +++ b/src/services/abstractService.ts @@ -1,8 +1,17 @@ -import axios from 'axios' +import axios, {Method} from 'axios' import {objectToSnakeCase} from '@/helpers/case' import {getToken} from '@/helpers/auth' +import AbstractModel from '@/models/abstractModel' -function convertObject(o) { +interface Paths { + create : string + get : string + getAll : string + update : string + delete : string +} + +function convertObject(o: Record) { if (o instanceof Date) { return o.toISOString() } @@ -10,7 +19,7 @@ function convertObject(o) { return o } -function prepareParams(params) { +function prepareParams(params: Record) { if (typeof params !== 'object') { return params } @@ -27,16 +36,16 @@ function prepareParams(params) { return objectToSnakeCase(params) } -export default class AbstractService { +export default class AbstractService { ///////////////////////////// // Initial variable definitions /////////////////////////// - http = null + http loading = false uploadProgress = 0 - paths = { + paths: Paths = { create: '', get: '', getAll: '', @@ -53,14 +62,12 @@ export default class AbstractService { /** * The abstract constructor. - * @param [paths] An object with all paths. Default values are specified above. + * @param [paths] An object with all paths. */ - constructor(paths) { + constructor(paths : Partial = {}) { this.http = axios.create({ baseURL: window.API_URL, - headers: { - 'Content-Type': 'application/json', - }, + headers: { 'Content-Type': 'application/json' }, }) // Set the interceptors to process every request @@ -94,38 +101,28 @@ export default class AbstractService { this.http.defaults.headers.common['Authorization'] = `Bearer ${token}` } - if (paths) { - this.paths = { - create: paths.create !== undefined ? paths.create : '', - get: paths.get !== undefined ? paths.get : '', - getAll: paths.getAll !== undefined ? paths.getAll : '', - update: paths.update !== undefined ? paths.update : '', - delete: paths.delete !== undefined ? paths.delete : '', - } - } + + Object.assign(this.paths, paths) } /** * Whether or not to use the create interceptor which processes a request payload into json - * @returns {boolean} */ - useCreateInterceptor() { + useCreateInterceptor(): boolean { return true } /** * Whether or not to use the update interceptor which processes a request payload into json - * @returns {boolean} */ - useUpdateInterceptor() { + useUpdateInterceptor(): boolean { return true } /** * Whether or not to use the delete interceptor which processes a request payload into json - * @returns {boolean} */ - useDeleteInterceptor() { + useDeleteInterceptor(): boolean { return true } @@ -135,11 +132,9 @@ export default class AbstractService { /** * Returns an object with all route parameters and their values. - * @param route - * @returns object */ - getRouteReplacements(route, parameters = {}) { - const replace$$1 = {} + getRouteReplacements(route : string, parameters = {}) { + const replace$$1: {} = {} let pattern = this.getRouteParameterPattern() pattern = new RegExp(pattern instanceof RegExp ? pattern.source : pattern, 'g') @@ -152,22 +147,18 @@ export default class AbstractService { /** * Holds the replacement pattern for url paths, can be overwritten by implementations. - * @return {RegExp} */ - getRouteParameterPattern() { + getRouteParameterPattern(): RegExp { return /{([^}]+)}/ } /** * Returns a fully-ready-ready-to-make-a-request-to route with replaced parameters. - * @param path - * @param pathparams - * @return string */ - getReplacedRoute(path, pathparams) { + getReplacedRoute(path : string, pathparams : {}) : string { const replacements = this.getRouteReplacements(path, pathparams) return Object.entries(replacements).reduce( - (result, [parameter, value]) => result.replace(parameter, value), + (result, [parameter, value]) => result.replace(parameter, value as string), path, ) } @@ -178,9 +169,8 @@ export default class AbstractService { * case the api returns a response in < 100ms. * But because the timeout is created using setTimeout, it will still trigger even if the request is * already finished, so we return a method to call in that case. - * @returns {Function} */ - setLoading() { + setLoading(): Function { const timeout = setTimeout(() => { this.loading = true }, 100) @@ -200,46 +190,36 @@ export default class AbstractService { /** * The modelFactory returns an model from an object. * This one here is the default one, usually the service definitions for a model will override this. - * @param data - * @returns {*} */ - modelFactory(data) { - return data + modelFactory(data : Partial) { + return new AbstractModel(data) } /** * This is the model factory for get requests. - * @param data - * @return {*} */ - modelGetFactory(data) { + modelGetFactory(data : Partial) { return this.modelFactory(data) } /** * This is the model factory for get all requests. - * @param data - * @return {*} */ - modelGetAllFactory(data) { + modelGetAllFactory(data : Partial) { return this.modelFactory(data) } /** * This is the model factory for create requests. - * @param data - * @return {*} */ - modelCreateFactory(data) { + modelCreateFactory(data : Partial) { return this.modelFactory(data) } /** * This is the model factory for update requests. - * @param data - * @return {*} */ - modelUpdateFactory(data) { + modelUpdateFactory(data : Partial) { return this.modelFactory(data) } @@ -249,37 +229,29 @@ export default class AbstractService { /** * Default preprocessor for get requests - * @param model - * @return {*} */ - beforeGet(model) { + beforeGet(model : Model) { return model } /** * Default preprocessor for create requests - * @param model - * @return {*} */ - beforeCreate(model) { + beforeCreate(model : Model) { return model } /** * Default preprocessor for update requests - * @param model - * @return {*} */ - beforeUpdate(model) { + beforeUpdate(model : Model) { return model } /** * Default preprocessor for delete requests - * @param model - * @return {*} */ - beforeDelete(model) { + beforeDelete(model : Model) { return model } @@ -291,9 +263,8 @@ export default class AbstractService { * Performs a get request to the url specified before. * @param model The model to use. The request path is built using the values from the model. * @param params Optional query parameters - * @returns {Q.Promise} */ - get(model, params = {}) { + get(model : Model, params = {}) { if (this.paths.get === '') { throw new Error('This model is not able to get data.') } @@ -304,12 +275,8 @@ export default class AbstractService { /** * This is a more abstract implementation which only does a get request. * Services which need more flexibility can use this. - * @param url - * @param model - * @param params - * @returns {Q.Promise} */ - async getM(url, model = {}, params = {}) { + async getM(url : string, model = new AbstractModel({}), params = {}) { const cancel = this.setLoading() model = this.beforeGet(model) @@ -325,12 +292,12 @@ export default class AbstractService { } } - async getBlobUrl(url, method = 'GET', data = {}) { + async getBlobUrl(url : string, method = 'GET' as Method, data = {}) { const response = await this.http({ - url: url, - method: method, + url, + method, responseType: 'blob', - data: data, + data, }) return window.URL.createObjectURL(new Blob([response.data])) } @@ -341,9 +308,8 @@ export default class AbstractService { * @param model The model to use. The request path is built using the values from the model. * @param params Optional query parameters * @param page The page to get - * @returns {Q.Promise} */ - async getAll(model = {}, params = {}, page = 1) { + async getAll(model : Model = new AbstractModel({}), params = {}, page = 1) { if (this.paths.getAll === '') { throw new Error('This model is not able to get data.') } @@ -374,10 +340,9 @@ export default class AbstractService { /** * Performs a put request to the url specified before - * @param model * @returns {Promise} */ - async create(model) { + async create(model : Model) { if (this.paths.create === '') { throw new Error('This model is not able to create data.') } @@ -400,11 +365,8 @@ export default class AbstractService { /** * An abstract implementation to send post requests. * Services can use this to implement functions to do post requests other than using the update method. - * @param url - * @param model - * @returns {Q.Promise} */ - async post(url, model) { + async post(url : string, model : Model) { const cancel = this.setLoading() try { @@ -421,10 +383,8 @@ export default class AbstractService { /** * Performs a post request to the update url - * @param model - * @returns {Q.Promise} */ - update(model) { + update(model : Model) { if (this.paths.update === '') { throw new Error('This model is not able to update data.') } @@ -435,10 +395,8 @@ export default class AbstractService { /** * Performs a delete request to the update url - * @param model - * @returns {Q.Promise} */ - async delete(model) { + async delete(model : Model) { if (this.paths.delete === '') { throw new Error('This model is not able to delete data.') } @@ -459,21 +417,15 @@ export default class AbstractService { * @param url * @param file * @param fieldName The name of the field the file is uploaded to. - * @returns {Q.Promise} */ - uploadFile(url, file, fieldName) { + uploadFile(url : string, file, fieldName : string) { return this.uploadBlob(url, new Blob([file]), fieldName, file.name) } /** * Uploads a blob to a url. - * @param url - * @param blob - * @param fieldName - * @param filename - * @returns {Q.Promise} */ - uploadBlob(url, blob, fieldName, filename) { + uploadBlob(url : string, blob: Blob, fieldName: string, filename : string) { const data = new FormData() data.append(fieldName, blob, filename) return this.uploadFormData(url, data) @@ -481,11 +433,8 @@ export default class AbstractService { /** * Uploads a form data object. - * @param url - * @param formData - * @returns {Q.Promise} */ - async uploadFormData(url, formData) { + async uploadFormData(url : string, formData: Record) { const cancel = this.setLoading() try { const response = await this.http.put(