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