351 lines
10 KiB
TypeScript
351 lines
10 KiB
TypeScript
/* eslint-disable jsx-a11y/anchor-is-valid */
|
|
import { Activity } from '../interfaces/activity.interface';
|
|
import {
|
|
Dataset,
|
|
DatasetListQueryOptions,
|
|
PackageSearchOptions,
|
|
Resource,
|
|
Tag,
|
|
} from '../interfaces/dataset.interface';
|
|
import { ResourceInfo, TableMetadata } from '../interfaces/datastore.interface';
|
|
import { Group } from '../interfaces/group.interface';
|
|
import { Organization } from '../interfaces/organization.interface';
|
|
import { User } from '../interfaces/user.interface';
|
|
import fetchRetry from './utils';
|
|
|
|
export default class CKAN {
|
|
DMS: string;
|
|
|
|
constructor(DMS: string) {
|
|
this.DMS = DMS;
|
|
}
|
|
|
|
async getDatasetsList() {
|
|
const response = await fetchRetry(
|
|
`${this.DMS}/api/3/action/package_list`,
|
|
3
|
|
);
|
|
const responseData = await response.json();
|
|
return responseData.result;
|
|
}
|
|
|
|
async getDatasetsListWithDetails(options: DatasetListQueryOptions) {
|
|
const response = await fetchRetry(
|
|
`${this.DMS}/api/3/action/current_package_list_with_resources?offset=${options.offset}&limit=${options.limit}`,
|
|
3
|
|
);
|
|
const responseData = await response.json();
|
|
const datasets: Array<Dataset> = responseData.result;
|
|
return datasets;
|
|
}
|
|
|
|
async packageSearch(
|
|
options: PackageSearchOptions,
|
|
reqOptions: Partial<RequestInit> = {}
|
|
): Promise<{ datasets: Dataset[]; count: number }> {
|
|
function buildGroupsQuery(groups: Array<string>) {
|
|
if (groups.length > 0) {
|
|
return `groups:(${groups.join(' OR ')})`;
|
|
}
|
|
return '';
|
|
}
|
|
function buildOrgsQuery(orgs: Array<string>) {
|
|
if (orgs.length > 0) {
|
|
return `organization:(${orgs.join(' OR ')})`;
|
|
}
|
|
return '';
|
|
}
|
|
function buildTagsQuery(tags: Array<string>) {
|
|
if (tags.length > 0) {
|
|
return `tags:(${tags.join(' OR ')})`;
|
|
}
|
|
return '';
|
|
}
|
|
|
|
function buildResFormatQuery(resFormat: Array<string>) {
|
|
if (resFormat?.length > 0) {
|
|
return `res_format:(${resFormat.join(' OR ')})`;
|
|
}
|
|
return '';
|
|
}
|
|
|
|
function buildFq(
|
|
tags: Array<string>,
|
|
orgs: Array<string>,
|
|
groups: Array<string>,
|
|
resFormat: Array<string>
|
|
) {
|
|
//TODO; this query builder is not very robust
|
|
// convertToCkanSearchQuery function should be
|
|
//copied over from the old portals utils
|
|
const fq = [
|
|
buildGroupsQuery(groups),
|
|
buildOrgsQuery(orgs),
|
|
buildTagsQuery(tags),
|
|
buildResFormatQuery(resFormat),
|
|
].filter((str) => str !== '');
|
|
if (fq.length > 0) {
|
|
return '&fq=' + fq.join('+');
|
|
}
|
|
return null;
|
|
}
|
|
|
|
const fq = buildFq(
|
|
options.tags,
|
|
options.orgs,
|
|
options.groups,
|
|
options?.resFormat
|
|
);
|
|
|
|
let url = `${this.DMS}/api/3/action/package_search?`;
|
|
url += `start=${options.offset}`;
|
|
url += `&rows=${options.limit}`;
|
|
url += fq ? fq : '';
|
|
url += options.query ? '&q=' + options.query : '';
|
|
url += options.sort ? '&sort=' + options.sort : '';
|
|
url += options.include_private
|
|
? '&include_private=' + options.include_private
|
|
: '';
|
|
|
|
const response = await fetchRetry(url, 3, reqOptions);
|
|
const responseData = await response.json();
|
|
const datasets: Array<Dataset> = responseData.result.results;
|
|
return { datasets, count: responseData.result.count };
|
|
}
|
|
|
|
async getDatasetDetails(datasetName: string) {
|
|
const response = await fetchRetry(
|
|
`${this.DMS}/api/3/action/package_show?id=${datasetName}`,
|
|
1
|
|
);
|
|
const responseData = await response.json();
|
|
if (responseData.success === false) {
|
|
throw 'Could not find dataset';
|
|
}
|
|
const dataset: Dataset = responseData.result;
|
|
return dataset;
|
|
}
|
|
|
|
async getDatasetActivityStream(datasetName: string) {
|
|
const response = await fetchRetry(
|
|
`${this.DMS}/api/3/action/package_activity_list?id=${datasetName}`,
|
|
3
|
|
);
|
|
const responseData = await response.json();
|
|
const activitiesWithoutUserData: Array<Activity> = responseData.result;
|
|
const activities = await Promise.all(
|
|
activitiesWithoutUserData.map(async (item) => {
|
|
let user_data: User | null = await this.getUser(item.user_id);
|
|
user_data = user_data === undefined ? null : user_data;
|
|
return { ...item, user_data };
|
|
})
|
|
);
|
|
return activities;
|
|
}
|
|
|
|
async getUser(userId: string) {
|
|
try {
|
|
const response = await fetchRetry(
|
|
`${this.DMS}/api/3/action/user_show?id=${userId}`,
|
|
3
|
|
);
|
|
const responseData = await response.json();
|
|
const user: User | null =
|
|
responseData.success === true ? responseData.result : null;
|
|
return user;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async getGroupList() {
|
|
const response = await fetchRetry(`${this.DMS}/api/3/action/group_list`, 3);
|
|
const responseData = await response.json();
|
|
const groups: Array<string> = responseData.result;
|
|
return groups;
|
|
}
|
|
|
|
async getGroupsWithDetails() {
|
|
const response = await fetchRetry(
|
|
`${this.DMS}/api/3/action/group_list?all_fields=True`,
|
|
3
|
|
);
|
|
const responseData = await response.json();
|
|
const groups: Array<Group> = responseData.result;
|
|
return groups;
|
|
}
|
|
|
|
async getGroupDetails(groupName: string) {
|
|
const response = await fetchRetry(
|
|
`${this.DMS}/api/3/action/group_show?id=${groupName}&include_datasets=True`,
|
|
3
|
|
);
|
|
const responseData = await response.json();
|
|
const group: Group = responseData.result;
|
|
return group;
|
|
}
|
|
|
|
async getGroupActivityStream(groupName: string) {
|
|
const response = await fetchRetry(
|
|
`${this.DMS}/api/3/action/group_activity_list?id=${groupName}`,
|
|
3
|
|
);
|
|
const responseData = await response.json();
|
|
const activitiesWithoutUserData: Array<Activity> = responseData.result;
|
|
const activities = await Promise.all(
|
|
activitiesWithoutUserData.map(async (item) => {
|
|
const user_data = await this.getUser(item.user_id);
|
|
return { ...item, user_data };
|
|
})
|
|
);
|
|
return activities;
|
|
}
|
|
|
|
async getOrgList() {
|
|
const response = await fetchRetry(
|
|
`${this.DMS}/api/3/action/organization_list`,
|
|
3
|
|
);
|
|
const responseData = await response.json();
|
|
const organizations: Array<string> = responseData.result;
|
|
return organizations;
|
|
}
|
|
|
|
async getOrgsWithDetails(accrossPages?: boolean) {
|
|
if (!accrossPages) {
|
|
const response = await fetchRetry(
|
|
`${this.DMS}/api/3/action/organization_list?all_fields=True`,
|
|
3
|
|
);
|
|
const responseData = await response.json();
|
|
const organizations: Array<Organization> = responseData.result;
|
|
return organizations;
|
|
}
|
|
|
|
const organizations = [];
|
|
const orgListResponse = await fetchRetry(
|
|
`${this.DMS}/api/3/action/organization_list`,
|
|
3
|
|
);
|
|
const orgList = await orgListResponse.json();
|
|
const orgLen = orgList.result.length;
|
|
const pages = Math.ceil(orgLen / 25);
|
|
|
|
for (let i = 0; i < pages; i++) {
|
|
let allOrgListResponse = await fetchRetry(
|
|
`${this.DMS}/api/3/action/organization_list?all_fields=True&offset=${
|
|
i * 25
|
|
}&limit=25`,
|
|
3
|
|
);
|
|
const responseData = await allOrgListResponse.json();
|
|
const result: Array<Organization> = responseData.result;
|
|
organizations.push(...result);
|
|
}
|
|
return organizations.sort((a, b) => b.package_count - a.package_count);
|
|
}
|
|
|
|
async getOrgDetails(orgName: string) {
|
|
const response = await fetchRetry(
|
|
`${this.DMS}/api/3/action/organization_show?id=${orgName}&include_datasets=True`,
|
|
3
|
|
);
|
|
const responseData = await response.json();
|
|
const organization: Organization = responseData.result;
|
|
return organization;
|
|
}
|
|
|
|
async getOrgActivityStream(orgName: string) {
|
|
const response = await fetchRetry(
|
|
`${this.DMS}/api/3/action/organization_activity_list?id=${orgName}`,
|
|
3
|
|
);
|
|
const responseData = await response.json();
|
|
const activitiesWithoutUserData: Array<Activity> = responseData.result;
|
|
const activities = await Promise.all(
|
|
activitiesWithoutUserData.map(async (item) => {
|
|
const user_data = await this.getUser(item.user_id);
|
|
return { ...item, user_data };
|
|
})
|
|
);
|
|
return activities;
|
|
}
|
|
|
|
async getAllTags() {
|
|
const response = await fetchRetry(
|
|
`${this.DMS}/api/3/action/tag_list?all_fields=True`,
|
|
3
|
|
);
|
|
const responseData = await response.json();
|
|
const tags: Array<Tag> = responseData.result;
|
|
return tags;
|
|
}
|
|
|
|
async getResourcesWithAliasList() {
|
|
const response = await fetch(`${this.DMS}/api/3/action/datastore_search`, {
|
|
method: 'POST',
|
|
headers: {
|
|
Accept: 'application/json',
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
id: '_table_metadata',
|
|
limit: '32000',
|
|
}),
|
|
});
|
|
const responseData = await response.json();
|
|
const tableMetadata: Array<TableMetadata> = responseData.result.records;
|
|
return tableMetadata.filter((item) => item.alias_of);
|
|
}
|
|
|
|
async datastoreSearch(resourceId: string) {
|
|
const response = await fetch(`${this.DMS}/api/3/action/datastore_search`, {
|
|
method: 'POST',
|
|
headers: {
|
|
Accept: 'application/json',
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({
|
|
id: resourceId,
|
|
limit: '32000',
|
|
}),
|
|
});
|
|
const responseData = await response.json();
|
|
return responseData.result.records;
|
|
}
|
|
|
|
async getResourceMetadata(resourceId: string) {
|
|
const response = await fetchRetry(
|
|
`${this.DMS}/api/3/action/resource_show?id=${resourceId}`,
|
|
3
|
|
);
|
|
const responseData = await response.json();
|
|
const resourceMetadata: Resource = responseData.result;
|
|
return resourceMetadata;
|
|
}
|
|
|
|
async getResourceInfo(resourceId: string) {
|
|
const response = await fetch(`${this.DMS}/api/3/action/datastore_info`, {
|
|
method: 'POST',
|
|
headers: {
|
|
Accept: 'application/json',
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({ resource_id: resourceId }),
|
|
});
|
|
const responseData = await response.json();
|
|
const resourceInfo: Array<ResourceInfo> = responseData.result;
|
|
return resourceInfo;
|
|
}
|
|
|
|
async getFacetFields(field: 'res_format' | 'tags') {
|
|
const response = await fetchRetry(
|
|
`${this.DMS}/api/3/action/package_search?facet.field=["${field}"]&rows=0`,
|
|
3
|
|
);
|
|
const responseData = await response.json();
|
|
const result = responseData.result?.facets?.[field];
|
|
return Object.keys(result);
|
|
}
|
|
}
|