All files / app/codeCharta/services/loadInitialFile urlExtractor.ts

97.56% Statements 40/41
100% Branches 17/17
100% Functions 9/9
97.56% Lines 40/41

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  7x   7x   7x   7x 15x     4x 4x 4x   4x 1x   3x 1x   2x       2x 2x   2x 1x     1x 2x 2x           9x 2x   7x 1x   6x       1x     1x 1x 1x 1x 1x   1x           6x   6x 5x 5x 5x   5x   1x       6x      
import { HttpClient, HttpResponse } from "@angular/common/http"
import { firstValueFrom } from "rxjs"
import { NameDataPair } from "../../codeCharta.model"
import { getCCFileAndDecorateFileChecksum } from "../../util/fileHelper"
import { ExportCCFile, ExportWrappedCCFile } from "../../codeCharta.api.model"
import { ungzip } from "pako"
 
export class UrlExtractor {
    constructor(private httpClient: HttpClient) {}
 
    getParameterByName(name: string) {
        const sanitizedName = name.replaceAll(/[[\]]/g, "\\$&")
        const regex = new RegExp(`[?&]${sanitizedName}(=([^&#]*)|&|#|$)`),
            results = regex.exec(window.location.href)
 
        if (!results) {
            return null
        }
        if (!results[2]) {
            return ""
        }
        return decodeURIComponent(results[2].replaceAll("+", " "))
    }
 
    async getFileDataFromQueryParam() {
        const queryParameters = new URLSearchParams(window.location.search)
        const fileNames = queryParameters.getAll("file")
 
        if (fileNames.length === 0) {
            throw new Error("Filename is missing")
        }
 
        return Promise.all(
            fileNames.map(async fileName => {
                return this.getFileDataFromFile(fileName)
            })
        )
    }
 
    async getFileDataFromFile(fileName: string): Promise<NameDataPair> {
        if (!fileName) {
            throw new Error(`Filename is missing`)
        }
        if (fileName.endsWith(".gz")) {
            return this.getUnzippedFile(fileName)
        }
        return this.getFile(fileName)
    }
 
    private async getUnzippedFile(fileName: string): Promise<NameDataPair> {
        const response: HttpResponse<ArrayBuffer> = await firstValueFrom(
            this.httpClient.get(fileName, { responseType: "arraybuffer", observe: "response" })
        )
        if (response.status >= 200 && response.status < 300) {
            const data = response.body
            const responseData: string | ExportCCFile | ExportWrappedCCFile = ungzip(data, { to: "string" })
            const content = getCCFileAndDecorateFileChecksum(responseData)
            const parsedFileName = this.getFileName(fileName, content.projectName)
            // see #3111 and PR #3110 for reason of hard coded file size
            return { fileName: parsedFileName, fileSize: 13, content }
        }
        throw new Error(`Could not load file "${fileName}"`)
    }
 
    private async getFile(fileName: string): Promise<NameDataPair> {
        const response = await firstValueFrom(this.httpClient.get(fileName, { observe: "response" }))
 
        if (response.status >= 200 && response.status < 300) {
            const responseData = response.body as string | ExportCCFile | ExportWrappedCCFile
            const content: ExportCCFile = getCCFileAndDecorateFileChecksum(responseData)
            fileName = this.getFileName(fileName, content.projectName)
            // see #3111 and PR #3110 for reason of hard coded file size
            return { fileName, fileSize: 15, content }
        }
        throw new Error(`Could not load file "${fileName}"`)
    }
 
    getFileName(oldFileName: string, projectName: string): string {
        return projectName?.trim() || oldFileName.split("/").pop()
    }
}