1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as _ from "lodash";
6 import { AxiosInstance, AxiosPromise } from "axios";
7 import * as uuid from "uuid/v4";
8 import { ApiActions } from "~/services/api/api-actions";
15 export interface ListArguments {
25 export interface ListResults<T> {
31 itemsAvailable: number;
34 export class CommonService<T> {
35 protected serverApi: AxiosInstance;
36 protected resourceType: string;
37 protected actions: ApiActions;
39 constructor(serverApi: AxiosInstance, resourceType: string, actions: ApiActions) {
40 this.serverApi = serverApi;
41 this.resourceType = '/' + resourceType + '/';
42 this.actions = actions;
45 static mapResponseKeys = (response: { data: any }) =>
46 CommonService.mapKeys(_.camelCase)(response.data)
48 static mapKeys = (mapFn: (key: string) => string) =>
49 (value: any): any => {
51 case _.isPlainObject(value):
54 .map(key => [key, mapFn(key)])
55 .reduce((newValue, [key, newKey]) => ({
57 [newKey]: CommonService.mapKeys(mapFn)(value[key])
59 case _.isArray(value):
60 return value.map(CommonService.mapKeys(mapFn));
66 static defaultResponse<R>(promise: AxiosPromise<R>, actions: ApiActions, mapKeys = true): Promise<R> {
68 actions.progressFn(reqId, true);
71 actions.progressFn(reqId, false);
74 .then((response: { data: any }) => {
75 return mapKeys ? CommonService.mapResponseKeys(response) : response.data;
77 .catch(({ response }) => {
78 actions.progressFn(reqId, false);
79 const errors = CommonService.mapResponseKeys(response) as Errors;
80 actions.errorFn(reqId, errors);
85 create(data?: Partial<T>) {
86 return CommonService.defaultResponse(
88 .post<T>(this.resourceType, data && CommonService.mapKeys(_.snakeCase)(data)),
93 delete(uuid: string): Promise<T> {
94 return CommonService.defaultResponse(
96 .delete(this.resourceType + uuid),
102 return CommonService.defaultResponse(
104 .get<T>(this.resourceType + uuid),
109 list(args: ListArguments = {}): Promise<ListResults<T>> {
110 const { filters, order, ...other } = args;
113 filters: filters ? `[${filters}]` : undefined,
114 order: order ? order : undefined
116 return CommonService.defaultResponse(
118 .get(this.resourceType, {
119 params: CommonService.mapKeys(_.snakeCase)(params)
125 update(uuid: string, data: Partial<T>) {
126 return CommonService.defaultResponse(
128 .put<T>(this.resourceType + uuid, data && CommonService.mapKeys(_.snakeCase)(data)),