All files / app/codeCharta/util fileDownloader.ts

78.72% Statements 37/47
75% Branches 12/16
90.9% Functions 10/11
78.26% Lines 36/46

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 114 115 116 117 118 119 120 121 122 123 124 12524x                     24x   24x 24x 24x       24x               5x 5x 5x                 5x                               5x   5x 1x   1x         5x 1x   5x       1x     1x       1x     1x       4x       5x 5x 25x 25x 25x 25x 25x 10x   15x     5x       1x 1x 3x   1x                              
import {
    AttributeDescriptors,
    AttributeTypes,
    BlacklistItem,
    BlacklistType,
    CodeMapNode,
    Edge,
    FileMeta,
    FileSettings,
    NodeType
} from "../codeCharta.model"
import { LoadFileService } from "../services/loadFile/loadFile.service"
import { ExportCCFile } from "../codeCharta.api.model"
import { hierarchy } from "d3-hierarchy"
import { clone } from "./clone"
import { UNARY_METRIC } from "../state/selectors/accumulatedData/metricData/nodeMetricData.calculator"
 
export type DownloadableSetting = "Nodes" | "AttributeTypes" | "AttributeDescriptors" | "Edges" | "Excludes" | "Flattens" | "MarkedPackages"
 
export class FileDownloader {
    static downloadCurrentMap(
        map: CodeMapNode,
        fileMeta: FileMeta,
        fileSettings: FileSettings,
        downloadSettings: DownloadableSetting[],
        fileName: string
    ) {
        const exportCCFile = this.getProjectDataAsCCJsonFormat(map, fileMeta, fileSettings, downloadSettings)
        const newFileNameWithExtension = fileName + LoadFileService.CC_FILE_EXTENSION
        this.downloadData(JSON.stringify(exportCCFile), newFileNameWithExtension)
    }
 
    private static getProjectDataAsCCJsonFormat(
        map: CodeMapNode,
        fileMeta: FileMeta,
        fileSettings: FileSettings,
        downloadSettings: DownloadableSetting[]
    ): ExportCCFile {
        return {
            projectName: fileMeta.projectName,
            apiVersion: fileMeta.apiVersion,
            fileChecksum: fileMeta.fileChecksum,
            nodes: [this.undecorateMap(map)],
            attributeTypes: downloadSettings.includes("AttributeTypes") ? this.getAttributeTypesForJSON(fileSettings.attributeTypes) : {},
            attributeDescriptors: downloadSettings.includes("AttributeDescriptors")
                ? this.getAttributeDescriptorsForJSON(fileSettings.attributeDescriptors)
                : {},
            edges: downloadSettings.includes("Edges") ? this.undecorateEdges(fileSettings.edges) : [],
            markedPackages: downloadSettings.includes("MarkedPackages") ? fileSettings.markedPackages : [],
            blacklist: this.getBlacklistToDownload(downloadSettings, fileSettings.blacklist)
        }
    }
 
    private static getBlacklistToDownload(downloadSettings: DownloadableSetting[], blacklist: BlacklistItem[]) {
        const mergedBlacklist = []
 
        if (downloadSettings.includes("Flattens")) {
            mergedBlacklist.push(
                ...this.getFilteredBlacklist(blacklist, "flatten").map(x => {
                    return { path: x.path, type: "hide" }
                })
            )
        }
 
        if (downloadSettings.includes("Excludes")) {
            mergedBlacklist.push(...this.getFilteredBlacklist(blacklist, "exclude"))
        }
        return mergedBlacklist
    }
 
    private static getAttributeTypesForJSON(attributeTypes: AttributeTypes) {
        Iif (Object.keys(attributeTypes.edges).length === 0 && Object.keys(attributeTypes.nodes).length === 0) {
            return {}
        }
        return attributeTypes
    }
 
    private static getAttributeDescriptorsForJSON(attributeDescriptors: AttributeDescriptors) {
        Iif (Object.keys(attributeDescriptors).length === 0) {
            return {}
        }
        return attributeDescriptors
    }
 
    private static getFilteredBlacklist(blacklist: BlacklistItem[], type: BlacklistType): BlacklistItem[] {
        return blacklist.filter(x => x.type === type)
    }
 
    private static undecorateMap(map: CodeMapNode) {
        const copy = clone(map)
        for (const { data } of hierarchy(copy)) {
            delete data.isExcluded
            delete data.isFlattened
            delete data.edgeAttributes
            delete data.path
            if (data.type === NodeType.FOLDER) {
                data.attributes = {}
            } else {
                delete data.attributes[UNARY_METRIC]
            }
        }
        return copy
    }
 
    private static undecorateEdges(edges: Edge[]) {
        const copy = clone(edges)
        for (const edge of copy) {
            delete edge.visible
        }
        return copy
    }
 
    static downloadData(data: string, fileName: string) {
        const blob = new Blob([data], { type: "text/json" })
        const mouseEvent = document.createEvent("MouseEvents")
        const link = document.createElement("a")
 
        link.download = fileName
        link.href = window.URL.createObjectURL(blob)
        link.dataset.downloadurl = ["text/json", link.download, link.href].join(":")
        mouseEvent.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
        link.dispatchEvent(mouseEvent)
    }
}