RocketChat/Rocket.Chat

View on GitHub
apps/meteor/client/lib/download.ts

Summary

Maintainability
A
0 mins
Test Coverage
export const download = (href: string, filename: string): void => {
    const anchorElement = document.createElement('a');
    anchorElement.download = filename;
    anchorElement.href = href;
    anchorElement.target = '_blank';
    document.body.appendChild(anchorElement);
    anchorElement.click();
    document.body.removeChild(anchorElement);
};

const hasMsSaveOrOpenBlob = (navigator: Navigator): navigator is Navigator & { msSaveOrOpenBlob: (blob: Blob) => void } =>
    'msSaveOrOpenBlob' in navigator;

export const downloadAs = ({ data, ...options }: { data: BlobPart[] } & BlobPropertyBag, filename: string): void => {
    const blob = new Blob(data, options);

    if (hasMsSaveOrOpenBlob(navigator)) {
        navigator.msSaveOrOpenBlob(blob);
        return;
    }

    const URL = window.webkitURL ?? window.URL;
    const blobUrl = URL.createObjectURL(blob);

    download(blobUrl, filename);

    URL.revokeObjectURL(blobUrl);
};

export const downloadJsonAs = (jsonObject: unknown, basename: string): void => {
    downloadAs(
        {
            data: [decodeURIComponent(encodeURI(JSON.stringify(jsonObject, null, 2)))],
            type: 'application/json;charset=utf-8',
        },
        `${basename}.json`,
    );
};

export const downloadCsvAs = (csvData: readonly (readonly unknown[])[], basename: string): void => {
    const escapeCell = (cell: unknown): string => `"${String(cell).replace(/"/g, '""')}"`;
    const content = csvData.reduce((content, row) => `${content + row.map(escapeCell).join(';')}\n`, '');

    downloadAs(
        {
            data: [decodeURIComponent(encodeURI(content))],
            type: 'text/csv;charset=utf-8',
            endings: 'native',
        },
        `${basename}.csv`,
    );
};