blob: 14329b3c0b6e53fa65c0bfe1fab1354f27af7e5b [file] [log] [blame]
Adrià Vilanova Martínezf19ea432024-01-23 20:20:52 +01001// Copyright 2019 The Chromium Authors
Copybara854996b2021-09-07 19:36:02 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/** @const {string} CSV download link's data href prefix, RFC 4810 Section 3 */
6export const CSV_DATA_HREF_PREFIX = 'data:text/csv;charset=utf-8,';
7
8/**
9 * Format array into plaintext csv
10 * @param {Array<Array>} data
11 * @return {string}
12 */
13export const convertListContentToCsv = (data) => {
14 const result = data.reduce((acc, row) => {
15 return `${acc}\r\n${row.map(preventCSVInjectionAndStringify).join(',')}`;
16 }, '');
17 // Remove leading /r and /n
18 return result.slice(2);
19};
20
21/**
22 * Prevent CSV injection, escape double quotes, and wrap with double quotes
23 * See owasp.org/index.php/CSV_Injection
24 * @param {string} cell
25 * @return {string}
26 */
27export const preventCSVInjectionAndStringify = (cell) => {
28 // Prepend all double quotes with another double quote, RFC 4810 Section 2.7
29 let escaped = cell.replace(/"/g, '""');
30
31 // prevent CSV injection: owasp.org/index.php/CSV_Injection
32 if (cell[0] === '=' ||
33 cell[0] === '+' ||
34 cell[0] === '-' ||
35 cell[0] === '@') {
36 escaped = `'${escaped}`;
37 }
38
39 // Wrap cell with double quotes, RFC 4810 Section 2.7
40 return `"${escaped}"`;
41};
42
43/**
44 * Prepare data for csv download by converting array of array into csv string
45 * @param {Array<Array<string>>} data
46 * @param {Array<string>=} headers Column headers
47 * @return {string} CSV formatted string
48 */
49export const prepareDataForDownload = (data, headers = []) => {
50 const mainContent = [headers, ...data];
51
52 return `${convertListContentToCsv(mainContent)}`;
53};
54
55/**
56 * Constructs download link url from csv string data.
57 * @param {string} data CSV data
58 * @return {string}
59 */
60export const constructHref = (data = '') => {
61 return `${CSV_DATA_HREF_PREFIX}${encodeURIComponent(data)}`;
62};