gooddata-js v13.5.0

File: src/report/report.ts

                        // (C) 2007-2019 GoodData Corporation
                        import { AFM, ExecuteAFM } from "@gooddata/typings";
                        import compact from "lodash/compact";
                        import isEmpty from "lodash/isEmpty";
                        import { ERROR_RESTRICTED_CODE, ERROR_RESTRICTED_MESSAGE } from "../constants/errors";
                        import {
                            convertAbsoluteDateFilter,
                            convertRelativeDateFilter,
                        } from "../DataLayer/converters/FilterConverter";
                        import { convertFilter as convertAttributeFilter } from "../execution/execute-afm.convert";
                        import { IBaseExportConfig, IExportConfig, IExportResponse } from "../interfaces";
                        import { ApiResponseError, XhrModule, ApiResponse } from "../xhr";
                        import { handleHeadPolling, IPollingOptions } from "../util";
                        import { isExportFinished } from "../utils/export";
                        
                        interface IExtendedExportConfig extends IBaseExportConfig {
                            showFilters?: boolean;
                            afm?: ExecuteAFM.IAfm;
                        }
                        
                        interface IResultExport {
                            executionResult: string;
                            exportConfig: IExtendedExportConfig;
                        }
                        
                        interface IExportResultPayload {
                            resultExport: IResultExport;
                        }
                        
                        /**
                         * Functions for working with reports
                         *
                         * @Class report
                         * @module report
                         */
                        export class ReportModule {
                            constructor(private xhr: XhrModule) {}
                        
                            /**
                             * exportResult
                             * request new result export
                             * request new export of existing AFM execution
                             *
                             * @experimental
                             * @method exportResult
                             * @param {String} projectId GoodData projectId
                             * @param {String} executionResult report which should be exported
                             * @param {IExportConfig} exportConfig requested export options
                             * @param {Object} pollingOptions for polling (maxAttempts, pollStep)
                             * @return {Promise} Resolves if export successfully,
                             *                   Reject if export has error (network error, api error)
                             */
                            public exportResult(
                                projectId: string,
                                executionResult: string,
                                exportConfig: IExportConfig = {},
                                pollingOptions: IPollingOptions = {},
                            ): Promise<IExportResponse> {
                                const requestPayload: IExportResultPayload = {
                                    resultExport: {
                                        executionResult,
                                        exportConfig: {
                                            ...exportConfig,
                                            ...this.sanitizeExportConfig(exportConfig),
                                        },
                                    },
                                };
                        
                                return this.xhr
                                    .post(`/gdc/internal/projects/${projectId}/exportResult`, { body: requestPayload })
                                    .then((response: ApiResponse) => response.getData())
                                    .then((data: IExportResponse) =>
                                        handleHeadPolling(this.xhr.get.bind(this.xhr), data.uri, isExportFinished, pollingOptions),
                                    )
                                    .catch(this.handleExportResultError);
                            }
                        
                            private sanitizeExportConfig(exportConfig: IExportConfig): IExtendedExportConfig {
                                const { afm } = exportConfig;
                        
                                if (afm && !isEmpty(afm.filters)) {
                                    const sanitizedAfm: ExecuteAFM.IAfm = {
                                        ...afm,
                                        filters: this.sanitizeFilters(afm.filters),
                                    };
                                    return {
                                        ...exportConfig,
                                        afm: sanitizedAfm,
                                    };
                                }
                                return exportConfig;
                            }
                        
                            private handleExportResultError = (error: ApiResponseError | Error): Promise<Error> => {
                                if (
                                    this.isApiResponseError(error) &&
                                    error.response.status === 400 &&
                                    error.responseBody.indexOf(ERROR_RESTRICTED_CODE) !== -1
                                ) {
                                    return Promise.reject({
                                        ...error,
                                        message: ERROR_RESTRICTED_MESSAGE,
                                    });
                                }
                                return Promise.reject(error);
                            };
                        
                            private isApiResponseError(error: ApiResponseError | Error): error is ApiResponseError {
                                return (error as ApiResponseError).response !== undefined;
                            }
                        
                            private sanitizeFilters(filters?: AFM.CompatibilityFilter[]): ExecuteAFM.CompatibilityFilter[] {
                                return filters ? compact(filters.map(this.sanitizeFilter)) : [];
                            }
                        
                            private sanitizeFilter(filter: AFM.CompatibilityFilter): ExecuteAFM.CompatibilityFilter | null {
                                if (AFM.isAttributeFilter(filter)) {
                                    return convertAttributeFilter(filter);
                                } else if (AFM.isAbsoluteDateFilter(filter)) {
                                    return convertAbsoluteDateFilter(filter);
                                } else if (AFM.isRelativeDateFilter(filter)) {
                                    return convertRelativeDateFilter(filter);
                                }
                                return filter;
                            }
                        }