Create CommonResourceService and OrderBuilder
[arvados-workbench2.git] / src / common / api / common-resource-service.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import * as _ from "lodash";
6 import FilterBuilder from "./filter-builder";
7 import OrderBuilder from "./order-builder";
8 import { AxiosInstance } from "axios";
9
10 export interface Resource {
11     uuid: string;
12     ownerUuid: string;
13     createdAt: string;
14     modifiedByClientUuid: string;
15     modifiedByUserUuid: string;
16     modifiedAt: string;
17     href: string;
18     kind: string;
19     etag: string;
20 }
21
22 export interface ListArguments {
23     limit: number;
24     offset: number;
25     filters?: FilterBuilder;
26     order?: OrderBuilder;
27     select?: string[];
28     distinct?: boolean;
29     count?: string;
30 }
31
32 export interface ListResults<T> {
33     kind: string;
34     offset: number;
35     limit: number;
36     items: T[];
37     itemsAvailable: number;
38 }
39
40 export default class CommonResourceService<T extends Resource> {
41
42     serverApi: AxiosInstance;
43     resourceType: string;
44
45     static mapResponseKeys = (response: any): Promise<any> =>
46         CommonResourceService.mapKeys(_.camelCase)(response.data)
47
48     static mapKeys = (mapFn: (key: string) => string) =>
49         (value: any): any => {
50             switch (true) {
51                 case _.isPlainObject(value):
52                     return Object
53                         .keys(value)
54                         .map(key => [key, mapFn(key)])
55                         .reduce((newValue, [key, newKey]) => ({
56                             ...newValue,
57                             [newKey]: CommonResourceService.mapKeys(mapFn)(value[key])
58                         }), {});
59                 case _.isArray(value):
60                     return value.map(CommonResourceService.mapKeys(mapFn));
61                 default:
62                     return value;
63             }
64         }
65
66     constructor(serverApi: AxiosInstance, resourceType: string) {
67         this.serverApi = serverApi;
68         this.resourceType = "/" + resourceType;
69     }
70
71     create() {
72         throw new Error("Not implemented");
73     }
74
75     delete(uuid: string): Promise<T> {
76         return this.serverApi
77             .delete(this.resourceType + "/" + uuid)
78             .then(CommonResourceService.mapResponseKeys);
79     }
80
81     get(uuid: string) {
82         return this.serverApi
83             .get<T>(this.resourceType + "/" + uuid)
84             .then(CommonResourceService.mapResponseKeys);
85     }
86
87     list(args: ListArguments): Promise<ListResults<T>> {
88         const { filters, order, ...other } = args;
89         const params = {
90             ...other,
91             filters: filters ? filters.get() : undefined,
92             order: order ? order.get() : undefined
93         };
94         return this.serverApi
95             .get(this.resourceType, {
96                 params: CommonResourceService.mapKeys(_.snakeCase)(params)
97             })
98             .then(CommonResourceService.mapResponseKeys);
99     }
100
101     update(uuid: string) {
102         throw new Error("Not implemented");
103     }
104
105 }
106