/
rds-catalog.ts
113 lines (106 loc) · 3.95 KB
/
rds-catalog.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import { Catalog } from '@mtna/pojo-consumer-ui';
import { AsyncResource } from './models/async/async-resource';
import { DataSetMetadata } from './models/data-set-metadata';
import { HttpResponse } from './models/http-response';
import { RdsDataProduct } from './rds-data-product';
import { RdsServer } from './rds-server';
import { HttpUtil } from './utils/http';
/**
* An instance of a RDS Catalog.
* A basic building block to interact with a RDS API.
* Includes methods to query catalog related information.
*
* @example
* ```ts
* const covidServer = new RdsServer('https://covid19.richdataservices.com/rds');
* const covidCatalog = new RdsCatalog(covidServer, 'int');
* covidCatalog
* .getMetadata()
* .then(
* res => console.log('Catalog metadata:', res.parsedBody),
* error => console.error('Oh no!', error)
* );
* ```
*/
export interface RdsCatalog extends Catalog {}
export class RdsCatalog extends AsyncResource {
/** The url to the RDS API */
get apiUrl(): string {
return this.server.apiUrl;
}
/** The url for catalog related API endpoints */
get catalogUrl(): string {
return `${this.server.apiUrl}/api/catalog/${this.catalogId}`;
}
/**
* Create a new RdsCatalog which provides
* methods to interact with catalog-related
* endpoints on the RDS API.
*
* @param server the RDS API server on which this catalog exists
* @param catalogId the ID of this specific catalog
* @param resolve whether to automatically start resolving all the catalog's own properties, defaults to false
*/
constructor(protected readonly server: RdsServer, public readonly catalogId: string, resolve = false) {
super(resolve);
}
/**
* Create and get an instance of a RDS Data Product that exists on
* this RdsCatalog. This is a convenience method, these two code snippets
* are equivalent:
* ```ts
* const dataProduct = new RdsServer('https://covid19.richdataservices.com/rds')
* .getCatalog('int')
* .getDataProduct('jhu_country');
* ```
* and
* ```ts
* const server = new RdsServer('https://covid19.richdataservices.com/rds');
* const catalog = new RdsCatalog(server, 'int');
* const dataProduct = new RdsDataProduct(catalog, 'jhu_country');
* ```
* @param dataProductId the ID of the specific data product
* @param resolve whether to automatically start resolving all the data product's own properties, defaults to false
* @returns a new RdsDataProduct
*/
getDataProduct(dataProductId: string, resolve = false): RdsDataProduct {
return new RdsDataProduct(this, dataProductId, resolve);
}
/**
* Get catalog metadata.
* This will retrieve the metadata for all of the data products
* that are in the specified catalog. For each data product there
* will be a record layout with its variables along with any
* classifications that are referenced by the variables.
*
* @returns metadata about the specified catalog
*/
async getMetadata(): Promise<HttpResponse<DataSetMetadata>> {
return HttpUtil.get<DataSetMetadata>(`${this.catalogUrl}/metadata`);
}
/**
* Resolve this catalog.
* This allows a more specific view of a catalog and
* its data products, it is a subset of the root catalog
* and holds no additional information to what can be
* found in the broader get catalog endpoint.
*
* @returns a promise that completes once the catalog is resolved
*/
async resolve(): Promise<void> {
this.setResolving(true);
return new Promise<void>((resolve, reject) => {
HttpUtil.get<Catalog>(`${this.catalogUrl}`)
.then((res: HttpResponse<Catalog>) => {
if (res?.parsedBody) {
// Assign all properties from the api response to this resource
Object.assign(this, res.parsedBody);
}
this.setResolved(true);
resolve();
})
.finally(() => this.setResolving(false))
.catch(error => reject(error));
});
}
}