// (C) 2007-2021 GoodData Corporation import { Application } from "express"; import { get, isPlainObject, flatMap, has, isEmpty, isEqual } from "lodash"; import * as HttpStatusCodes from "http-status-codes"; import { IMockProject } from "../../model/MockProject"; import { IDateDataSet, IWrappedDateDataSet } from "../../model/DateDataSet"; import { filterAvailable } from "../helpers/filtering"; import { filterByTags, getWrappedMetadataObject } from "../helpers/metadataObjects"; import { getGroups } from "../helpers/groups"; import { ValidationError } from "../ValidationError"; import * as dateDataSetsErrors from "../../constants/DateDataSetsErrors"; import { ILoadDateDatasetsRequest, ILoadDateDatasetsResponse } from "../../model/endPoints/LoadDateDatasets"; function validate(request: ILoadDateDatasetsRequest): void { if (Object.keys(request).length !== 1) { throw new ValidationError(dateDataSetsErrors.WRONG_STRUCTURE); } if (!has(request, "dateDataSetsRequest")) { throw new ValidationError(dateDataSetsErrors.STRUCTURE_NOT_DEFINED); } if (!isPlainObject(request.dateDataSetsRequest)) { throw new ValidationError(dateDataSetsErrors.INVALID_STRUCTURE); } } function findMockedResponse( project: IMockProject, request: ILoadDateDatasetsRequest, ): ILoadDateDatasetsResponse { if (!has(project, "endPoints.loadDateDatasetsMocks")) { return null; } const { loadDateDatasetsMocks } = project.endPoints; const matchedMock = loadDateDatasetsMocks.find(mock => isEqual(mock.request, request)); return !isEmpty(matchedMock) ? matchedMock.response : null; } function filterDateDataSets(project: IMockProject, request: ILoadDateDatasetsRequest): IDateDataSet[] { const requestSelector = request.dateDataSetsRequest.requiredDataSets; const items = flatMap(getGroups(requestSelector, project), group => group.dateDataSets); return filterByTags(request.dateDataSetsRequest, items); } function generateResponse( project: IMockProject, request: ILoadDateDatasetsRequest, ): ILoadDateDatasetsResponse { const dateDataSetsItems = filterDateDataSets(project, request); const requestGranularities = get(request, "dateDataSetsRequest.includeDateGranularities", []); const granularities = [ "GDC.time.date", "GDC.time.month", "GDC.time.quarter", "GDC.time.week_us", "GDC.time.year", ...requestGranularities, ]; const dateDataSetsItemsFiltered = filterAvailable( project, request.dateDataSetsRequest.bucketItems, dateDataSetsItems, ) as IDateDataSet[]; const dateDataSetsItemsFilteredByGranularities = dateDataSetsItemsFiltered.map(dateDataset => ({ ...dateDataset, availableDateAttributes: dateDataset.availableDateAttributes.filter(attribute => granularities.includes(attribute.type), ), })); return { dateDataSetsResponse: { dateDataSets: dateDataSetsItemsFilteredByGranularities.map( getWrappedMetadataObject, ) as IWrappedDateDataSet[], unavailableDateDataSetsCount: dateDataSetsItems.length - dateDataSetsItemsFilteredByGranularities.length, }, }; } export const dateDataSets = { register(app: Application, project: IMockProject) { app.post(`/gdc/internal/projects/${project.project.meta.identifier}/loadDateDataSets`, (req, res) => { const request: ILoadDateDatasetsRequest = req.body; try { validate(request); const mockedResponse = findMockedResponse(project, request); const body = mockedResponse !== null ? mockedResponse : generateResponse(project, request); res.status(HttpStatusCodes.OK).json(body); } catch (error) { if (error instanceof ValidationError) { res.status(HttpStatusCodes.BAD_REQUEST).json(error.getValidationError()); } else { res.status(HttpStatusCodes.INTERNAL_SERVER_ERROR).json(error); } } }); return app; }, };