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> {
30 itemsAvailable: number;
33 export class CommonService<T> {
34 protected serverApi: AxiosInstance;
35 protected resourceType: string;
36 protected actions: ApiActions;
38 constructor(serverApi: AxiosInstance, resourceType: string, actions: ApiActions) {
39 this.serverApi = serverApi;
40 this.resourceType = '/' + resourceType + '/';
41 this.actions = actions;
44 static mapResponseKeys = (response: { data: any }) =>
45 CommonService.mapKeys(_.camelCase)(response.data)
47 static mapKeys = (mapFn: (key: string) => string) =>
48 (value: any): any => {
50 case _.isPlainObject(value):
53 .map(key => [key, mapFn(key)])
54 .reduce((newValue, [key, newKey]) => ({
56 [newKey]: CommonService.mapKeys(mapFn)(value[key])
58 case _.isArray(value):
59 return value.map(CommonService.mapKeys(mapFn));
65 static defaultResponse<R>(promise: AxiosPromise<R>, actions: ApiActions, mapKeys = true): Promise<R> {
67 actions.progressFn(reqId, true);
70 actions.progressFn(reqId, false);
73 .then((response: { data: any }) => {
74 return mapKeys ? CommonService.mapResponseKeys(response) : response.data;
76 .catch(({ response }) => {
77 actions.progressFn(reqId, false);
78 const errors = CommonService.mapResponseKeys(response) as Errors;
79 actions.errorFn(reqId, errors);
84 create(data?: Partial<T>) {
85 return CommonService.defaultResponse(
87 .post<T>(this.resourceType, data && CommonService.mapKeys(_.snakeCase)(data)),
92 delete(uuid: string): Promise<T> {
93 return CommonService.defaultResponse(
95 .delete(this.resourceType + uuid),
101 return CommonService.defaultResponse(
103 .get<T>(this.resourceType + uuid),
108 list(args: ListArguments = {}): Promise<ListResults<T>> {
109 const { filters, order, ...other } = args;
112 filters: filters ? `[${filters}]` : undefined,
113 order: order ? order : undefined
115 return CommonService.defaultResponse(
117 .get(this.resourceType, {
118 params: CommonService.mapKeys(_.snakeCase)(params)
124 update(uuid: string, data: Partial<T>) {
125 return CommonService.defaultResponse(
127 .put<T>(this.resourceType + uuid, data && CommonService.mapKeys(_.snakeCase)(data)),