@woocommerce/csv-export
Advanced tools
Comparing version 1.3.2 to 1.4.0
@@ -1,3 +0,4 @@ | ||
export default `Date,Orders,Description,"Total Sales",Refunds,Coupons,Taxes,Shipping,"Net Sales","Negative Number" | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.default = `Date,Orders,Description,"Total Sales",Refunds,Coupons,Taxes,Shipping,"Net Sales","Negative Number" | ||
2018-04-29T00:00:00,30,"Lorem, ""ipsum""",200,19,19,100,19,200,"\t-123"`; | ||
//# sourceMappingURL=mock-csv-data.js.map |
@@ -1,32 +0,44 @@ | ||
export default [{ | ||
label: 'Date', | ||
key: 'date_start' | ||
}, { | ||
label: 'Orders', | ||
key: 'orders_count' | ||
}, { | ||
label: 'Description', | ||
key: 'description' | ||
}, { | ||
label: 'Total Sales', | ||
key: 'total_sales' | ||
}, { | ||
label: 'Refunds', | ||
key: 'refunds' | ||
}, { | ||
label: 'Coupons', | ||
key: 'coupons' | ||
}, { | ||
label: 'Taxes', | ||
key: 'taxes' | ||
}, { | ||
label: 'Shipping', | ||
key: 'shipping' | ||
}, { | ||
label: 'Net Sales', | ||
key: 'net_revenue' | ||
}, { | ||
label: 'Negative Number', | ||
key: 'neg_num' | ||
}]; | ||
//# sourceMappingURL=mock-headers.js.map | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.default = [ | ||
{ | ||
label: 'Date', | ||
key: 'date_start', | ||
}, | ||
{ | ||
label: 'Orders', | ||
key: 'orders_count', | ||
}, | ||
{ | ||
label: 'Description', | ||
key: 'description', | ||
}, | ||
{ | ||
label: 'Total Sales', | ||
key: 'total_sales', | ||
}, | ||
{ | ||
label: 'Refunds', | ||
key: 'refunds', | ||
}, | ||
{ | ||
label: 'Coupons', | ||
key: 'coupons', | ||
}, | ||
{ | ||
label: 'Taxes', | ||
key: 'taxes', | ||
}, | ||
{ | ||
label: 'Shipping', | ||
key: 'shipping', | ||
}, | ||
{ | ||
label: 'Net Sales', | ||
key: 'net_revenue', | ||
}, | ||
{ | ||
label: 'Negative Number', | ||
key: 'neg_num', | ||
}, | ||
]; |
@@ -1,32 +0,46 @@ | ||
export default [[{ | ||
display: '04/29/2018', | ||
value: '2018-04-29T00:00:00' | ||
}, { | ||
display: 'Product 30', | ||
value: '30' | ||
}, { | ||
display: 'Lorem, "ipsum"', | ||
value: 'Lorem, "ipsum"' | ||
}, { | ||
display: '€200.00', | ||
value: 200 | ||
}, { | ||
display: '€19.00', | ||
value: 19 | ||
}, { | ||
display: '€19.00', | ||
value: 19 | ||
}, { | ||
display: '€100.00', | ||
value: 100 | ||
}, { | ||
display: '€19.00', | ||
value: 19 | ||
}, { | ||
display: '€200.00', | ||
value: 200 | ||
}, { | ||
display: '-123', | ||
value: -123 | ||
}]]; | ||
//# sourceMappingURL=mock-rows.js.map | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.default = [ | ||
[ | ||
{ | ||
display: '04/29/2018', | ||
value: '2018-04-29T00:00:00', | ||
}, | ||
{ | ||
display: 'Product 30', | ||
value: '30', | ||
}, | ||
{ | ||
display: 'Lorem, "ipsum"', | ||
value: 'Lorem, "ipsum"', | ||
}, | ||
{ | ||
display: '€200.00', | ||
value: 200, | ||
}, | ||
{ | ||
display: '€19.00', | ||
value: 19, | ||
}, | ||
{ | ||
display: '€19.00', | ||
value: 19, | ||
}, | ||
{ | ||
display: '€100.00', | ||
value: 100, | ||
}, | ||
{ | ||
display: '€19.00', | ||
value: 19, | ||
}, | ||
{ | ||
display: '€200.00', | ||
value: 200, | ||
}, | ||
{ | ||
display: '-123', | ||
value: -123, | ||
}, | ||
], | ||
]; |
@@ -0,33 +1,46 @@ | ||
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.downloadCSVFile = exports.generateCSVFileName = exports.generateCSVDataFromTable = void 0; | ||
/** | ||
* External dependencies | ||
*/ | ||
import moment from 'moment'; | ||
import { saveAs } from 'browser-filesaver'; | ||
const moment_1 = __importDefault(require("moment")); | ||
const browser_filesaver_1 = require("browser-filesaver"); | ||
function escapeCSVValue(value) { | ||
let stringValue = value.toString(); // Prevent CSV injection. | ||
// See: http://www.contextis.com/resources/blog/comma-separated-vulnerabilities/ | ||
// See: WC_CSV_Exporter::escape_data() | ||
if (['=', '+', '-', '@'].includes(stringValue.charAt(0))) { | ||
stringValue = '"\t' + stringValue + '"'; | ||
} else if (stringValue.match(/[,"\s]/)) { | ||
stringValue = '"' + stringValue.replace(/"/g, '""') + '"'; | ||
} | ||
return stringValue; | ||
let stringValue = value.toString(); | ||
// Prevent CSV injection. | ||
// See: http://www.contextis.com/resources/blog/comma-separated-vulnerabilities/ | ||
// See: WC_CSV_Exporter::escape_data() | ||
if (['=', '+', '-', '@'].includes(stringValue.charAt(0))) { | ||
stringValue = '"\t' + stringValue + '"'; | ||
} | ||
else if (stringValue.match(/[,"\s]/)) { | ||
stringValue = '"' + stringValue.replace(/"/g, '""') + '"'; | ||
} | ||
return stringValue; | ||
} | ||
function getCSVHeaders(headers) { | ||
return Array.isArray(headers) ? headers.map(header => escapeCSVValue(header.label)).join(',') : []; | ||
return Array.isArray(headers) | ||
? headers | ||
.map((header) => escapeCSVValue(header.label)) | ||
.join(',') | ||
: []; | ||
} | ||
function getCSVRows(rows) { | ||
return Array.isArray(rows) ? rows.map(row => row.map(rowItem => { | ||
if (undefined === rowItem.value || rowItem.value === null) { | ||
return ''; | ||
} | ||
return escapeCSVValue(rowItem.value); | ||
}).join(',')).join('\n') : []; | ||
return Array.isArray(rows) | ||
? rows | ||
.map((row) => row | ||
.map((rowItem) => { | ||
if (undefined === rowItem.value || | ||
rowItem.value === null) { | ||
return ''; | ||
} | ||
return escapeCSVValue(rowItem.value); | ||
}) | ||
.join(',')) | ||
.join('\n') | ||
: []; | ||
} | ||
@@ -41,7 +54,8 @@ /** | ||
*/ | ||
export function generateCSVDataFromTable(headers, rows) { | ||
return [getCSVHeaders(headers), getCSVRows(rows)].filter(text => text.length).join('\n'); | ||
function generateCSVDataFromTable(headers, rows) { | ||
return [getCSVHeaders(headers), getCSVRows(rows)] | ||
.filter((text) => text.length) | ||
.join('\n'); | ||
} | ||
exports.generateCSVDataFromTable = generateCSVDataFromTable; | ||
/** | ||
@@ -55,7 +69,17 @@ * Generates a file name for CSV files based on the provided name, the current date | ||
*/ | ||
export function generateCSVFileName(name = '', params = {}) { | ||
const fileNameSections = [name.toLowerCase().replace(/[^a-z0-9]/g, '-'), moment().format('YYYY-MM-DD'), Object.keys(params).map(key => key.toLowerCase().replace(/[^a-z0-9]/g, '-') + '-' + decodeURIComponent(params[key]).toLowerCase().replace(/[^a-z0-9]/g, '-')).join('_')].filter(text => text.length); | ||
return fileNameSections.join('_') + '.csv'; | ||
function generateCSVFileName(name = '', params = {}) { | ||
const fileNameSections = [ | ||
name.toLowerCase().replace(/[^a-z0-9]/g, '-'), | ||
moment_1.default().format('YYYY-MM-DD'), | ||
Object.keys(params) | ||
.map((key) => key.toLowerCase().replace(/[^a-z0-9]/g, '-') + | ||
'-' + | ||
decodeURIComponent(params[key]) | ||
.toLowerCase() | ||
.replace(/[^a-z0-9]/g, '-')) | ||
.join('_'), | ||
].filter((text) => text.length); | ||
return fileNameSections.join('_') + '.csv'; | ||
} | ||
exports.generateCSVFileName = generateCSVFileName; | ||
/** | ||
@@ -67,10 +91,7 @@ * Downloads a CSV file with the given file name and contents | ||
*/ | ||
export function downloadCSVFile(fileName, content) { | ||
// eslint-disable-next-line no-undef | ||
const blob = new Blob([content], { | ||
type: 'text/csv;charset=utf-8' | ||
}); | ||
saveAs(blob, fileName); | ||
function downloadCSVFile(fileName, content) { | ||
// eslint-disable-next-line no-undef | ||
const blob = new Blob([content], { type: 'text/csv;charset=utf-8' }); | ||
browser_filesaver_1.saveAs(blob, fileName); | ||
} | ||
//# sourceMappingURL=index.js.map | ||
exports.downloadCSVFile = downloadCSVFile; |
@@ -0,1 +1,4 @@ | ||
# 1.4.0 | ||
- Fix commonjs module build, allow package to be built in isolation. #7286 | ||
# 1.3.2 | ||
@@ -2,0 +5,0 @@ |
{ | ||
"name": "@woocommerce/csv-export", | ||
"version": "1.3.2", | ||
"version": "1.4.0", | ||
"description": "WooCommerce utility library to convert data to CSV files.", | ||
@@ -30,3 +30,12 @@ "author": "Automattic", | ||
}, | ||
"gitHead": "2a2a046171c31009f7db02cae68b5c23ae9f6a3e" | ||
"scripts": { | ||
"clean": "npx rimraf build build-*", | ||
"build": "tsc --build ./tsconfig.json ./tsconfig-cjs.json", | ||
"start": "tsc --build --watch", | ||
"prepack": "npm run clean && npm run build", | ||
"test": "lerna run build && npm run test:nobuild", | ||
"test:nobuild": "jest --config ./jest.config.json", | ||
"test-staged": "jest --bail --config ./jest.config.json --findRelatedTests" | ||
}, | ||
"gitHead": "f29f789cb9b668b286e41325e36aa369c5bccffd" | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
760687
18
477