Socket
Socket
Sign inDemoInstall

csv-writer

Package Overview
Dependencies
0
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.3.0 to 1.4.0

dist/lib/file-writer.js

4

CHANGELOG.md

@@ -8,2 +8,6 @@ # Changelog

## [1.4.0] - 2019-06-19
### Added
- Allow CRLF as a record delimiter. [#27](https://github.com/ryu1kn/csv-writer/pull/27)
## [1.3.0] - 2019-04-19

@@ -10,0 +14,0 @@ ### Changed

24

dist/index.js
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const csv_stringifier_factory_1 = require("./lib/csv-stringifier-factory");
const csv_writer_factory_1 = require("./lib/csv-writer-factory");
const csvStringifierFactory = new csv_stringifier_factory_1.CsvStringifierFactory();
const csvWriterFactory = new csv_writer_factory_1.CsvWriterFactory(csvStringifierFactory);
exports.createArrayCsvStringifier = (params) => csvStringifierFactory.createArrayCsvStringifier(params);
exports.createObjectCsvStringifier = (params) => csvStringifierFactory.createObjectCsvStringifier(params);
exports.createArrayCsvWriter = (params) => csvWriterFactory.createArrayCsvWriter(params);
exports.createObjectCsvWriter = (params) => csvWriterFactory.createObjectCsvWriter(params);
var csv_stringifier_factory_1 = require("./lib/csv-stringifier-factory");
var csv_writer_factory_1 = require("./lib/csv-writer-factory");
var csvStringifierFactory = new csv_stringifier_factory_1.CsvStringifierFactory();
var csvWriterFactory = new csv_writer_factory_1.CsvWriterFactory(csvStringifierFactory);
exports.createArrayCsvStringifier = function (params) {
return csvStringifierFactory.createArrayCsvStringifier(params);
};
exports.createObjectCsvStringifier = function (params) {
return csvStringifierFactory.createObjectCsvStringifier(params);
};
exports.createArrayCsvWriter = function (params) {
return csvWriterFactory.createArrayCsvWriter(params);
};
exports.createObjectCsvWriter = function (params) {
return csvWriterFactory.createObjectCsvWriter(params);
};
//# sourceMappingURL=index.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const array_1 = require("./csv-stringifiers/array");
const field_stringifier_1 = require("./field-stringifier");
const object_1 = require("./csv-stringifiers/object");
const DEFAULT_FIELD_DELIMITER = ',';
const VALID_FIELD_DELIMITERS = [DEFAULT_FIELD_DELIMITER, ';'];
class CsvStringifierFactory {
createArrayCsvStringifier(params) {
const fieldDelimiter = params.fieldDelimiter || DEFAULT_FIELD_DELIMITER;
_validateFieldDelimiter(fieldDelimiter);
const fieldStringifier = new field_stringifier_1.FieldStringifier(fieldDelimiter);
return new array_1.ArrayCsvStringifier(fieldStringifier, fieldDelimiter, params.header);
var array_1 = require("./csv-stringifiers/array");
var field_stringifier_1 = require("./field-stringifier");
var object_1 = require("./csv-stringifiers/object");
var DEFAULT_FIELD_DELIMITER = ',';
var VALID_FIELD_DELIMITERS = [DEFAULT_FIELD_DELIMITER, ';'];
var CsvStringifierFactory = /** @class */ (function () {
function CsvStringifierFactory() {
}
createObjectCsvStringifier(params) {
const fieldDelimiter = params.fieldDelimiter || DEFAULT_FIELD_DELIMITER;
CsvStringifierFactory.prototype.createArrayCsvStringifier = function (params) {
var fieldDelimiter = params.fieldDelimiter || DEFAULT_FIELD_DELIMITER;
_validateFieldDelimiter(fieldDelimiter);
const fieldStringifier = new field_stringifier_1.FieldStringifier(fieldDelimiter);
return new object_1.ObjectCsvStringifier(fieldStringifier, fieldDelimiter, params.header);
}
}
var fieldStringifier = new field_stringifier_1.FieldStringifier(fieldDelimiter);
return new array_1.ArrayCsvStringifier(fieldStringifier, fieldDelimiter, params.recordDelimiter, params.header);
};
CsvStringifierFactory.prototype.createObjectCsvStringifier = function (params) {
var fieldDelimiter = params.fieldDelimiter || DEFAULT_FIELD_DELIMITER;
_validateFieldDelimiter(fieldDelimiter);
var fieldStringifier = new field_stringifier_1.FieldStringifier(fieldDelimiter);
return new object_1.ObjectCsvStringifier(fieldStringifier, fieldDelimiter, params.header, params.recordDelimiter);
};
return CsvStringifierFactory;
}());
exports.CsvStringifierFactory = CsvStringifierFactory;
function _validateFieldDelimiter(delimiter) {
if (VALID_FIELD_DELIMITERS.indexOf(delimiter) === -1) {
throw new Error(`Invalid field delimiter \`${delimiter}\` is specified`);
throw new Error("Invalid field delimiter `" + delimiter + "` is specified");
}
}
//# sourceMappingURL=csv-stringifier-factory.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const RECORD_DELIMITER = '\n';
class CsvStringifier {
constructor(fieldStringifier, fieldDelimiter) {
var DEFAULT_RECORD_DELIMITER = '\n';
var VALID_RECORD_DELIMITERS = [DEFAULT_RECORD_DELIMITER, '\r\n'];
var CsvStringifier = /** @class */ (function () {
function CsvStringifier(fieldStringifier, fieldDelimiter, recordDelimiter) {
this.fieldStringifier = fieldStringifier;
this.fieldDelimiter = fieldDelimiter;
this.recordDelimiter = recordDelimiter || DEFAULT_RECORD_DELIMITER;
_validateRecordDelimiter(this.recordDelimiter);
}
getHeaderString() {
const headerRecord = this.getHeaderRecord();
CsvStringifier.prototype.getHeaderString = function () {
var headerRecord = this.getHeaderRecord();
return headerRecord ? this.stringifyRecords([headerRecord]) : null;
}
stringifyRecords(records) {
const csvLines = Array.from(records, record => this.getCsvLine(this.getRecordAsArray(record)));
return csvLines.join(RECORD_DELIMITER) + RECORD_DELIMITER;
}
getCsvLine(record) {
};
CsvStringifier.prototype.stringifyRecords = function (records) {
var _this = this;
var csvLines = Array.from(records, function (record) { return _this.getCsvLine(_this.getRecordAsArray(record)); });
return csvLines.join(this.recordDelimiter) + this.recordDelimiter;
};
CsvStringifier.prototype.getCsvLine = function (record) {
var _this = this;
return record
.map(fieldValue => this.fieldStringifier.stringify(fieldValue))
.map(function (fieldValue) { return _this.fieldStringifier.stringify(fieldValue); })
.join(this.fieldDelimiter);
};
return CsvStringifier;
}());
exports.CsvStringifier = CsvStringifier;
function _validateRecordDelimiter(delimiter) {
if (VALID_RECORD_DELIMITERS.indexOf(delimiter) === -1) {
throw new Error("Invalid record delimiter `" + delimiter + "` is specified");
}
}
exports.CsvStringifier = CsvStringifier;
//# sourceMappingURL=abstract.js.map
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const abstract_1 = require("./abstract");
class ArrayCsvStringifier extends abstract_1.CsvStringifier {
constructor(fieldStringifier, fieldDelimiter, header) {
super(fieldStringifier, fieldDelimiter);
this.header = header;
var abstract_1 = require("./abstract");
var ArrayCsvStringifier = /** @class */ (function (_super) {
__extends(ArrayCsvStringifier, _super);
function ArrayCsvStringifier(fieldStringifier, fieldDelimiter, recordDelimiter, header) {
var _this = _super.call(this, fieldStringifier, fieldDelimiter, recordDelimiter) || this;
_this.header = header;
return _this;
}
getHeaderRecord() {
ArrayCsvStringifier.prototype.getHeaderRecord = function () {
return this.header;
}
getRecordAsArray(record) {
};
ArrayCsvStringifier.prototype.getRecordAsArray = function (record) {
return record;
}
}
};
return ArrayCsvStringifier;
}(abstract_1.CsvStringifier));
exports.ArrayCsvStringifier = ArrayCsvStringifier;
//# sourceMappingURL=array.js.map
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const abstract_1 = require("./abstract");
class ObjectCsvStringifier extends abstract_1.CsvStringifier {
constructor(fieldStringifier, fieldDelimiter, header) {
super(fieldStringifier, fieldDelimiter);
this.header = header;
var abstract_1 = require("./abstract");
var ObjectCsvStringifier = /** @class */ (function (_super) {
__extends(ObjectCsvStringifier, _super);
function ObjectCsvStringifier(fieldStringifier, fieldDelimiter, header, recordDelimiter) {
var _this = _super.call(this, fieldStringifier, fieldDelimiter, recordDelimiter) || this;
_this.header = header;
return _this;
}
getHeaderRecord() {
ObjectCsvStringifier.prototype.getHeaderRecord = function () {
if (!this.isObjectHeader)
return null;
return this.header.reduce((memo, field) => Object.assign({}, memo, { [field.id]: field.title }), {});
}
getRecordAsArray(record) {
return this.fieldIds.map(field => record[field]);
}
get fieldIds() {
return this.isObjectHeader ? this.header.map(column => column.id) : this.header;
}
get isObjectHeader() {
return isObject(this.header && this.header[0]);
}
}
return this.header.reduce(function (memo, field) {
var _a;
return Object.assign({}, memo, (_a = {}, _a[field.id] = field.title, _a));
}, {});
};
ObjectCsvStringifier.prototype.getRecordAsArray = function (record) {
return this.fieldIds.map(function (field) { return record[field]; });
};
Object.defineProperty(ObjectCsvStringifier.prototype, "fieldIds", {
get: function () {
return this.isObjectHeader ? this.header.map(function (column) { return column.id; }) : this.header;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ObjectCsvStringifier.prototype, "isObjectHeader", {
get: function () {
return isObject(this.header && this.header[0]);
},
enumerable: true,
configurable: true
});
return ObjectCsvStringifier;
}(abstract_1.CsvStringifier));
exports.ObjectCsvStringifier = ObjectCsvStringifier;

@@ -25,0 +52,0 @@ function isObject(value) {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const csv_writer_1 = require("./csv-writer");
const fs = require("fs");
class CsvWriterFactory {
constructor(csvStringifierFactory) {
var csv_writer_1 = require("./csv-writer");
var CsvWriterFactory = /** @class */ (function () {
function CsvWriterFactory(csvStringifierFactory) {
this.csvStringifierFactory = csvStringifierFactory;
}
createArrayCsvWriter(params) {
const csvStringifier = this.csvStringifierFactory.createArrayCsvStringifier({
CsvWriterFactory.prototype.createArrayCsvWriter = function (params) {
var csvStringifier = this.csvStringifierFactory.createArrayCsvStringifier({
header: params.header,
fieldDelimiter: params.fieldDelimiter
fieldDelimiter: params.fieldDelimiter,
recordDelimiter: params.recordDelimiter
});
return new csv_writer_1.CsvWriter(csvStringifier, params.path, fs, params.encoding, params.append);
}
createObjectCsvWriter(params) {
const csvStringifier = this.csvStringifierFactory.createObjectCsvStringifier({
return new csv_writer_1.CsvWriter(csvStringifier, params.path, params.encoding, params.append);
};
CsvWriterFactory.prototype.createObjectCsvWriter = function (params) {
var csvStringifier = this.csvStringifierFactory.createObjectCsvStringifier({
header: params.header,
fieldDelimiter: params.fieldDelimiter
fieldDelimiter: params.fieldDelimiter,
recordDelimiter: params.recordDelimiter
});
return new csv_writer_1.CsvWriter(csvStringifier, params.path, fs, params.encoding, params.append);
}
}
return new csv_writer_1.CsvWriter(csvStringifier, params.path, params.encoding, params.append);
};
return CsvWriterFactory;
}());
exports.CsvWriterFactory = CsvWriterFactory;
//# sourceMappingURL=csv-writer-factory.js.map

@@ -10,41 +10,66 @@ "use strict";

};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
const DEFAULT_ENCODING = 'utf8';
const DEFAULT_INITIAL_APPEND_FLAG = false;
class CsvWriter {
constructor(csvStringifier, path, fs, encoding, append) {
this.fs = fs;
this.path = path;
var file_writer_1 = require("./file-writer");
var DEFAULT_INITIAL_APPEND_FLAG = false;
var CsvWriter = /** @class */ (function () {
function CsvWriter(csvStringifier, path, encoding, append) {
this.append = append || DEFAULT_INITIAL_APPEND_FLAG;
this.fileWriter = new file_writer_1.FileWriter(path, this.append, encoding);
this.csvStringifier = csvStringifier;
this.encoding = encoding || DEFAULT_ENCODING;
this.append = append || DEFAULT_INITIAL_APPEND_FLAG;
}
writeRecords(records) {
return __awaiter(this, void 0, void 0, function* () {
const headerString = !this.append && this.csvStringifier.getHeaderString();
const recordsString = this.csvStringifier.stringifyRecords(records);
const writeString = (headerString || '') + recordsString;
const option = this.getWriteOption();
yield this.write(writeString, option);
this.append = true;
});
}
write(string, options) {
return new Promise((resolve, reject) => {
this.fs.writeFile(this.path, string, options, (err) => {
if (err)
reject(err);
else
resolve();
CsvWriter.prototype.writeRecords = function (records) {
return __awaiter(this, void 0, void 0, function () {
var recordsString, writeString;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
recordsString = this.csvStringifier.stringifyRecords(records);
writeString = this.headerString + recordsString;
return [4 /*yield*/, this.fileWriter.write(writeString)];
case 1:
_a.sent();
this.append = true;
return [2 /*return*/];
}
});
});
}
getWriteOption() {
return {
encoding: this.encoding,
flag: this.append ? 'a' : 'w'
};
}
}
};
Object.defineProperty(CsvWriter.prototype, "headerString", {
get: function () {
var headerString = !this.append && this.csvStringifier.getHeaderString();
return headerString || '';
},
enumerable: true,
configurable: true
});
return CsvWriter;
}());
exports.CsvWriter = CsvWriter;
//# sourceMappingURL=csv-writer.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class FieldStringifier {
constructor(fieldDelimiter) {
var FieldStringifier = /** @class */ (function () {
function FieldStringifier(fieldDelimiter) {
this.fieldDelimiter = fieldDelimiter;
}
stringify(value) {
FieldStringifier.prototype.stringify = function (value) {
if (typeof value === 'undefined' || value === null)
return '';
const str = String(value);
return this.needsQuote(str) ? `"${str.replace(/"/g, '""')}"` : str;
}
needsQuote(str) {
var str = String(value);
return this.needsQuote(str) ? "\"" + str.replace(/"/g, '""') + "\"" : str;
};
FieldStringifier.prototype.needsQuote = function (str) {
return str.includes(this.fieldDelimiter) || str.includes('\n') || str.includes('"');
}
}
};
return FieldStringifier;
}());
exports.FieldStringifier = FieldStringifier;
//# sourceMappingURL=field-stringifier.js.map
"use strict";
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const delimiter_1 = require("../helper/delimiter");
const index_1 = require("../../index");
describe('ArrayCsvStringifier', () => {
const records = [
var assert = require("assert");
var delimiter_1 = require("../helper/delimiter");
var index_1 = require("../../index");
describe('ArrayCsvStringifier', function () {
var records = [
['FIELD_A1', 'FIELD_B1'],

@@ -13,5 +40,5 @@ ['FIELD_A2', 'FIELD_B2']

describe('When field delimiter is semicolon', generateTestCases(';'));
describe('When field delimiter is neither comma nor semicolon', () => {
it('throws an exception', () => {
assert.throws(() => {
describe('When field delimiter is neither comma nor semicolon', function () {
it('throws an exception', function () {
assert.throws(function () {
index_1.createArrayCsvStringifier({ fieldDelimiter: '/' });

@@ -21,11 +48,27 @@ });

});
describe('When records input is an iterable other than an array', () => {
const stringifier = index_1.createArrayCsvStringifier({
describe('When record delimiter is neither LF nor CR+LF', function () {
it('throws an exception', function () {
assert.throws(function () {
index_1.createArrayCsvStringifier({ recordDelimiter: '\r' });
});
});
});
describe('When records input is an iterable other than an array', function () {
var stringifier = index_1.createArrayCsvStringifier({
header: ['TITLE_A', 'TITLE_B']
});
function* recordGenerator() {
yield records[0];
yield records[1];
function recordGenerator() {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, records[0]];
case 1:
_a.sent();
return [4 /*yield*/, records[1]];
case 2:
_a.sent();
return [2 /*return*/];
}
});
}
it('converts the records into CSV', () => {
it('converts the records into CSV', function () {
assert.equal(stringifier.stringifyRecords(recordGenerator()), 'FIELD_A1,FIELD_B1\nFIELD_A2,FIELD_B2\n');

@@ -35,23 +78,23 @@ });

function generateTestCases(fieldDelimiter) {
const delim = delimiter_1.resolveDelimiterChar(fieldDelimiter);
return () => {
describe('header is specified as a list of column titles', () => {
const stringifier = index_1.createArrayCsvStringifier({
var delim = delimiter_1.resolveDelimiterChar(fieldDelimiter);
return function () {
describe('header is specified as a list of column titles', function () {
var stringifier = index_1.createArrayCsvStringifier({
header: ['TITLE_A', 'TITLE_B'],
fieldDelimiter
fieldDelimiter: fieldDelimiter
});
it(`returns a header line with field separated by "${delim}"`, () => {
assert.equal(stringifier.getHeaderString(), `TITLE_A${delim}TITLE_B\n`);
it("returns a header line with field separated by \"" + delim + "\"", function () {
assert.equal(stringifier.getHeaderString(), "TITLE_A" + delim + "TITLE_B\n");
});
it(`converts given data records into CSV lines with field separated by "${delim}"`, () => {
assert.equal(stringifier.stringifyRecords(records), `FIELD_A1${delim}FIELD_B1\nFIELD_A2${delim}FIELD_B2\n`);
it("converts given data records into CSV lines with field separated by \"" + delim + "\"", function () {
assert.equal(stringifier.stringifyRecords(records), "FIELD_A1" + delim + "FIELD_B1\nFIELD_A2" + delim + "FIELD_B2\n");
});
});
describe('header is not specified', () => {
const stringifier = index_1.createArrayCsvStringifier({ fieldDelimiter });
it('returns null for header line', () => {
describe('header is not specified', function () {
var stringifier = index_1.createArrayCsvStringifier({ fieldDelimiter: fieldDelimiter });
it('returns null for header line', function () {
assert.equal(stringifier.getHeaderString(), null);
});
it(`converts given data records into CSV lines with field separated by "${delim}"`, () => {
assert.equal(stringifier.stringifyRecords(records), `FIELD_A1${delim}FIELD_B1\nFIELD_A2${delim}FIELD_B2\n`);
it("converts given data records into CSV lines with field separated by \"" + delim + "\"", function () {
assert.equal(stringifier.stringifyRecords(records), "FIELD_A1" + delim + "FIELD_B1\nFIELD_A2" + delim + "FIELD_B2\n");
});

@@ -58,0 +101,0 @@ });

"use strict";
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const delimiter_1 = require("../helper/delimiter");
const index_1 = require("../../index");
describe('ObjectCsvStringifier', () => {
const records = [
var assert = require("assert");
var delimiter_1 = require("../helper/delimiter");
var index_1 = require("../../index");
describe('ObjectCsvStringifier', function () {
var records = [
{ FIELD_A: 'VALUE_A1', FIELD_B: 'VALUE_B1' },

@@ -13,5 +40,5 @@ { FIELD_A: 'VALUE_A2', FIELD_B: 'VALUE_B2' }

describe('When field delimiter is semicolon', generateTestCases(';'));
describe('When field delimiter is neither comma nor semicolon', () => {
it('throws an exception', () => {
assert.throws(() => {
describe('When field delimiter is neither comma nor semicolon', function () {
it('throws an exception', function () {
assert.throws(function () {
index_1.createObjectCsvStringifier({

@@ -24,11 +51,30 @@ header: ['FIELD_A', 'FIELD_B'],

});
describe('When records input is an iterable other than an array', () => {
const stringifier = index_1.createObjectCsvStringifier({
describe('When record delimiter is neither LF nor CR+LF', function () {
it('throws an exception', function () {
assert.throws(function () {
index_1.createObjectCsvStringifier({
header: ['FIELD_A', 'FIELD_B'],
recordDelimiter: '\r'
});
});
});
});
describe('When records input is an iterable other than an array', function () {
var stringifier = index_1.createObjectCsvStringifier({
header: ['FIELD_A', 'FIELD_B']
});
function* recordGenerator() {
yield records[0];
yield records[1];
function recordGenerator() {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, records[0]];
case 1:
_a.sent();
return [4 /*yield*/, records[1]];
case 2:
_a.sent();
return [2 /*return*/];
}
});
}
it('converts the records into CSV', () => {
it('converts the records into CSV', function () {
assert.equal(stringifier.stringifyRecords(recordGenerator()), 'VALUE_A1,VALUE_B1\nVALUE_A2,VALUE_B2\n');

@@ -38,6 +84,6 @@ });

function generateTestCases(fieldDelimiter) {
const delim = delimiter_1.resolveDelimiterChar(fieldDelimiter);
return () => {
describe('header is specified with title', () => {
const stringifier = index_1.createObjectCsvStringifier({
var delim = delimiter_1.resolveDelimiterChar(fieldDelimiter);
return function () {
describe('header is specified with title', function () {
var stringifier = index_1.createObjectCsvStringifier({
header: [

@@ -47,25 +93,25 @@ { id: 'FIELD_A', title: 'TITLE_A' },

],
fieldDelimiter
fieldDelimiter: fieldDelimiter
});
it(`returns a header line with field separated by "${delim}"`, () => {
assert.equal(stringifier.getHeaderString(), `TITLE_A${delim}TITLE_B\n`);
it("returns a header line with field separated by \"" + delim + "\"", function () {
assert.equal(stringifier.getHeaderString(), "TITLE_A" + delim + "TITLE_B\n");
});
it(`converts given data records into CSV lines with field separated by "${delim}"`, () => {
assert.equal(stringifier.stringifyRecords(records), `VALUE_A1${delim}VALUE_B1\nVALUE_A2${delim}VALUE_B2\n`);
it("converts given data records into CSV lines with field separated by \"" + delim + "\"", function () {
assert.equal(stringifier.stringifyRecords(records), "VALUE_A1" + delim + "VALUE_B1\nVALUE_A2" + delim + "VALUE_B2\n");
});
});
describe('header is specified without title', () => {
const stringifier = index_1.createObjectCsvStringifier({
describe('header is specified without title', function () {
var stringifier = index_1.createObjectCsvStringifier({
header: ['FIELD_A', 'FIELD_B'],
fieldDelimiter
fieldDelimiter: fieldDelimiter
});
it('returns null for header line', () => {
it('returns null for header line', function () {
assert.equal(stringifier.getHeaderString(), null);
});
it(`converts given data records into CSV lines with field separated by "${delim}"`, () => {
assert.equal(stringifier.stringifyRecords(records), `VALUE_A1${delim}VALUE_B1\nVALUE_A2${delim}VALUE_B2\n`);
it("converts given data records into CSV lines with field separated by \"" + delim + "\"", function () {
assert.equal(stringifier.stringifyRecords(records), "VALUE_A1" + delim + "VALUE_B1\nVALUE_A2" + delim + "VALUE_B2\n");
});
});
describe('header columns are given with reverse order', () => {
const stringifier = index_1.createObjectCsvStringifier({
describe('header columns are given with reverse order', function () {
var stringifier = index_1.createObjectCsvStringifier({
header: [

@@ -75,6 +121,6 @@ { id: 'FIELD_B', title: 'TITLE_B' },

],
fieldDelimiter
fieldDelimiter: fieldDelimiter
});
it(`layouts fields with the order of headers given with field separated by "${delim}"`, () => {
assert.equal(stringifier.stringifyRecords(records), `VALUE_B1${delim}VALUE_A1\nVALUE_B2${delim}VALUE_A2\n`);
it("layouts fields with the order of headers given with field separated by \"" + delim + "\"", function () {
assert.equal(stringifier.stringifyRecords(records), "VALUE_B1" + delim + "VALUE_A1\nVALUE_B2" + delim + "VALUE_A2\n");
});

@@ -81,0 +127,0 @@ });

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const delimiter_1 = require("./helper/delimiter");
const field_stringifier_1 = require("../lib/field-stringifier");
describe('FieldStringifier', () => {
var assert = require("assert");
var delimiter_1 = require("./helper/delimiter");
var field_stringifier_1 = require("../lib/field-stringifier");
describe('FieldStringifier', function () {
describe('When field delimiter is comma', generateTestCases(','));
describe('When field delimiter is semicolon', generateTestCases(';'));
function generateTestCases(fieldDelimiter) {
const delim = delimiter_1.resolveDelimiterChar(fieldDelimiter);
return () => {
const stringifier = new field_stringifier_1.FieldStringifier(fieldDelimiter);
it('returns the same string', () => {
var delim = delimiter_1.resolveDelimiterChar(fieldDelimiter);
return function () {
var stringifier = new field_stringifier_1.FieldStringifier(fieldDelimiter);
it('returns the same string', function () {
assert.equal(stringifier.stringify('VALUE'), 'VALUE');
});
it('preserves the whitespace characters', () => {
it('preserves the whitespace characters', function () {
assert.equal(stringifier.stringify(' VALUE\tA '), ' VALUE\tA ');
});
it(`wraps a field value with double quotes if the field contains "${delim}"`, () => {
assert.equal(stringifier.stringify(`VALUE${delim}A`), `"VALUE${delim}A"`);
it("wraps a field value with double quotes if the field contains \"" + delim + "\"", function () {
assert.equal(stringifier.stringify("VALUE" + delim + "A"), "\"VALUE" + delim + "A\"");
});
it('wraps a field value with double quotes if the field contains newline', () => {
it('wraps a field value with double quotes if the field contains newline', function () {
assert.equal(stringifier.stringify('VALUE\nA'), '"VALUE\nA"');
});
it('wraps a field value with double quotes and escape the double quotes if they are used in the field', () => {
it('wraps a field value with double quotes and escape the double quotes if they are used in the field', function () {
assert.equal(stringifier.stringify('VALUE"A'), '"VALUE""A"');
});
it('escapes double quotes even if double quotes are only on the both edges of the field', () => {
it('escapes double quotes even if double quotes are only on the both edges of the field', function () {
assert.equal(stringifier.stringify('"VALUE"'), '"""VALUE"""');
});
it('converts a number into a string', () => {
it('converts a number into a string', function () {
assert.equal(stringifier.stringify(1), '1');
});
it('converts undefined into an empty string', () => {
it('converts undefined into an empty string', function () {
assert.equal(stringifier.stringify(), '');
});
it('converts null into an empty string', () => {
it('converts null into an empty string', function () {
assert.equal(stringifier.stringify(null), '');
});
it('converts an object into toString-ed value', () => {
const obj = {
it('converts an object into toString-ed value', function () {
var obj = {
name: 'OBJECT_NAME',
toString: function () { return `Name: ${this.name}`; }
toString: function () { return "Name: " + this.name; }
};
assert.equal(stringifier.stringify(obj), 'Name: OBJECT_NAME');
});
it(`wraps a toString-ed field value with double quote if the value contains "${delim}"`, () => {
const obj = {
name: `OBJECT${delim}NAME`,
toString: function () { return `Name: ${this.name}`; }
it("wraps a toString-ed field value with double quote if the value contains \"" + delim + "\"", function () {
var obj = {
name: "OBJECT" + delim + "NAME",
toString: function () { return "Name: " + this.name; }
};
assert.equal(stringifier.stringify(obj), `"Name: OBJECT${delim}NAME"`);
assert.equal(stringifier.stringify(obj), "\"Name: OBJECT" + delim + "NAME\"");
});
it('escapes double quotes in a toString-ed field value if the value has double quotes', () => {
const obj = {
it('escapes double quotes in a toString-ed field value if the value has double quotes', function () {
var obj = {
name: 'OBJECT_NAME"',
toString: function () { return `Name: ${this.name}`; }
toString: function () { return "Name: " + this.name; }
};

@@ -59,0 +59,0 @@ assert.equal(stringifier.stringify(obj), '"Name: OBJECT_NAME"""');

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const assert = require("assert");
const fs = require('fs');
exports.testFilePath = (id) => `./test-tmp/${id}.csv`;
exports.assertFile = (path, expectedContents, encoding) => {
const actualContents = fs.readFileSync(path, encoding || 'utf8');
var assert = require("assert");
var fs = require('fs');
exports.testFilePath = function (id) { return "./test-tmp/" + id + ".csv"; };
exports.assertFile = function (path, expectedContents, encoding) {
var actualContents = fs.readFileSync(path, encoding || 'utf8');
assert.equal(actualContents, expectedContents);
};
exports.assertContain = (expectedSubstring, actualString) => {
assert.ok(expectedSubstring.includes(actualString), `${actualString} does not contain ${expectedSubstring}`);
exports.assertContain = function (expectedSubstring, actualString) {
assert.ok(expectedSubstring.includes(actualString), actualString + " does not contain " + expectedSubstring);
};

@@ -13,0 +13,0 @@ function mockType(params) {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveDelimiterChar = (char) => {
exports.resolveDelimiterChar = function (char) {
if (char === ',' || char === ';')

@@ -5,0 +5,0 @@ return char;

@@ -10,51 +10,105 @@ "use strict";

};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var _this = this;
Object.defineProperty(exports, "__esModule", { value: true });
const helper_1 = require("./helper");
const fs = require('fs');
const createArrayCsvWriter = require('../index').createArrayCsvWriter;
describe('Write array records into CSV', () => {
const makeFilePath = (id) => helper_1.testFilePath(`array-${id}`);
const records = [
var helper_1 = require("./helper");
var fs = require('fs');
var createArrayCsvWriter = require('../index').createArrayCsvWriter;
describe('Write array records into CSV', function () {
var makeFilePath = function (id) { return helper_1.testFilePath("array-" + id); };
var records = [
['Bob', 'French'],
['Mary', 'English']
];
describe('When only path is specified', () => {
describe('When only path is specified', function () {
'use strict';
const filePath = makeFilePath('minimum');
let writer;
beforeEach(() => {
var filePath = makeFilePath('minimum');
var writer;
beforeEach(function () {
writer = createArrayCsvWriter({ path: filePath });
});
it('writes records to a new file', () => {
return writer.writeRecords(records).then(() => {
it('writes records to a new file', function () {
return writer.writeRecords(records).then(function () {
helper_1.assertFile(filePath, 'Bob,French\nMary,English\n');
});
});
it('appends records when requested to write to the same file', () => __awaiter(this, void 0, void 0, function* () {
yield writer.writeRecords([records[0]]);
yield writer.writeRecords([records[1]]);
helper_1.assertFile(filePath, 'Bob,French\nMary,English\n');
}));
it('appends records when requested to write to the same file', function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, writer.writeRecords([records[0]])];
case 1:
_a.sent();
return [4 /*yield*/, writer.writeRecords([records[1]])];
case 2:
_a.sent();
helper_1.assertFile(filePath, 'Bob,French\nMary,English\n');
return [2 /*return*/];
}
});
}); });
});
describe('When field header is given', () => {
const filePath = makeFilePath('header');
const writer = createArrayCsvWriter({
path: filePath,
header: ['NAME', 'LANGUAGE']
describe('When field header is given', function () {
var filePath = makeFilePath('header');
var writer;
beforeEach(function () {
writer = createArrayCsvWriter({
path: filePath,
header: ['NAME', 'LANGUAGE']
});
});
it('writes a header', () => {
return writer.writeRecords(records).then(() => {
it('writes a header', function () {
return writer.writeRecords(records).then(function () {
helper_1.assertFile(filePath, 'NAME,LANGUAGE\nBob,French\nMary,English\n');
});
});
it('appends records without headers', function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, writer.writeRecords([records[0]])];
case 1:
_a.sent();
return [4 /*yield*/, writer.writeRecords([records[1]])];
case 2:
_a.sent();
helper_1.assertFile(filePath, 'NAME,LANGUAGE\nBob,French\nMary,English\n');
return [2 /*return*/];
}
});
}); });
});
describe('When `append` flag is specified', () => {
const filePath = makeFilePath('append');
describe('When `append` flag is specified', function () {
var filePath = makeFilePath('append');
fs.writeFileSync(filePath, 'Mike,German\n', 'utf8');
const writer = createArrayCsvWriter({
var writer = createArrayCsvWriter({
path: filePath,
append: true
});
it('do not overwrite the existing contents and appends records to them', () => {
return writer.writeRecords([records[1]]).then(() => {
it('do not overwrite the existing contents and appends records to them', function () {
return writer.writeRecords([records[1]]).then(function () {
helper_1.assertFile(filePath, 'Mike,German\nMary,English\n');

@@ -64,10 +118,10 @@ });

});
describe('When encoding is specified', () => {
const filePath = makeFilePath('encoding');
const writer = createArrayCsvWriter({
describe('When encoding is specified', function () {
var filePath = makeFilePath('encoding');
var writer = createArrayCsvWriter({
path: filePath,
encoding: 'utf16le'
});
it('writes to a file with the specified encoding', () => {
return writer.writeRecords(records).then(() => {
it('writes to a file with the specified encoding', function () {
return writer.writeRecords(records).then(function () {
helper_1.assertFile(filePath, 'Bob,French\nMary,English\n', 'utf16le');

@@ -77,5 +131,5 @@ });

});
describe('When semicolon is specified as a field delimiter', () => {
const filePath = makeFilePath('field-delimiter');
const writer = createArrayCsvWriter({
describe('When semicolon is specified as a field delimiter', function () {
var filePath = makeFilePath('field-delimiter');
var writer = createArrayCsvWriter({
path: filePath,

@@ -85,4 +139,4 @@ header: ['NAME', 'LANGUAGE'],

});
it('writes to a file with the specified encoding', () => {
return writer.writeRecords(records).then(() => {
it('uses semicolon instead of comma to separate fields', function () {
return writer.writeRecords(records).then(function () {
helper_1.assertFile(filePath, 'NAME;LANGUAGE\nBob;French\nMary;English\n');

@@ -92,3 +146,15 @@ });

});
describe('When newline is specified', function () {
var filePath = makeFilePath('newline');
var writer = createArrayCsvWriter({
path: filePath,
recordDelimiter: '\r\n'
});
it('writes to a file with the specified newline character', function () {
return writer.writeRecords(records).then(function () {
helper_1.assertFile(filePath, 'Bob,French\r\nMary,English\r\n');
});
});
});
});
//# sourceMappingURL=write-array-records.test.js.map

@@ -10,17 +10,45 @@ "use strict";

};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var _this = this;
Object.defineProperty(exports, "__esModule", { value: true });
const helper_1 = require("./helper");
const fs = require('fs');
const createObjectCsvWriter = require('../index').createObjectCsvWriter;
describe('Write object records into CSV', () => {
const makeFilePath = (id) => helper_1.testFilePath(`object-${id}`);
const records = [
var helper_1 = require("./helper");
var fs = require('fs');
var createObjectCsvWriter = require('../index').createObjectCsvWriter;
describe('Write object records into CSV', function () {
var makeFilePath = function (id) { return helper_1.testFilePath("object-" + id); };
var records = [
{ name: 'Bob', lang: 'French' },
{ name: 'Mary', lang: 'English' }
];
describe('When only path and header ids are given', () => {
describe('When only path and header ids are given', function () {
'use strict';
const filePath = makeFilePath('minimum');
let writer;
beforeEach(() => {
var filePath = makeFilePath('minimum');
var writer;
beforeEach(function () {
writer = createObjectCsvWriter({

@@ -31,21 +59,30 @@ path: filePath,

});
it('writes records to a new file', () => {
return writer.writeRecords(records).then(() => {
it('writes records to a new file', function () {
return writer.writeRecords(records).then(function () {
helper_1.assertFile(filePath, 'Bob,French\nMary,English\n');
});
});
it('appends records when requested to write to the same file', () => __awaiter(this, void 0, void 0, function* () {
yield writer.writeRecords([records[0]]);
yield writer.writeRecords([records[1]]);
helper_1.assertFile(filePath, 'Bob,French\nMary,English\n');
}));
it('appends records when requested to write to the same file', function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, writer.writeRecords([records[0]])];
case 1:
_a.sent();
return [4 /*yield*/, writer.writeRecords([records[1]])];
case 2:
_a.sent();
helper_1.assertFile(filePath, 'Bob,French\nMary,English\n');
return [2 /*return*/];
}
});
}); });
});
describe('When header ids are given with reverse order', () => {
const filePath = makeFilePath('column-order');
const writer = createObjectCsvWriter({
describe('When header ids are given with reverse order', function () {
var filePath = makeFilePath('column-order');
var writer = createObjectCsvWriter({
path: filePath,
header: ['lang', 'name']
});
it('also writes columns with reverse order', () => {
return writer.writeRecords(records).then(() => {
it('also writes columns with reverse order', function () {
return writer.writeRecords(records).then(function () {
helper_1.assertFile(filePath, 'French,Bob\nEnglish,Mary\n');

@@ -55,18 +92,35 @@ });

});
describe('When field header is given with titles', () => {
const filePath = makeFilePath('header');
const writer = createObjectCsvWriter({
path: filePath,
header: [{ id: 'name', title: 'NAME' }, { id: 'lang', title: 'LANGUAGE' }]
describe('When field header is given with titles', function () {
var filePath = makeFilePath('header');
var writer;
beforeEach(function () {
writer = createObjectCsvWriter({
path: filePath,
header: [{ id: 'name', title: 'NAME' }, { id: 'lang', title: 'LANGUAGE' }]
});
});
it('writes a header', () => {
return writer.writeRecords(records).then(() => {
it('writes a header', function () {
return writer.writeRecords(records).then(function () {
helper_1.assertFile(filePath, 'NAME,LANGUAGE\nBob,French\nMary,English\n');
});
});
it('appends records without headers', function () { return __awaiter(_this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, writer.writeRecords([records[0]])];
case 1:
_a.sent();
return [4 /*yield*/, writer.writeRecords([records[1]])];
case 2:
_a.sent();
helper_1.assertFile(filePath, 'NAME,LANGUAGE\nBob,French\nMary,English\n');
return [2 /*return*/];
}
});
}); });
});
describe('When `append` flag is specified', () => {
const filePath = makeFilePath('append');
describe('When `append` flag is specified', function () {
var filePath = makeFilePath('append');
fs.writeFileSync(filePath, 'Mike,German\n', 'utf8');
const writer = createObjectCsvWriter({
var writer = createObjectCsvWriter({
path: filePath,

@@ -76,4 +130,4 @@ header: ['name', 'lang'],

});
it('do not overwrite the existing contents and appends records to them', () => {
return writer.writeRecords([records[1]]).then(() => {
it('do not overwrite the existing contents and appends records to them', function () {
return writer.writeRecords([records[1]]).then(function () {
helper_1.assertFile(filePath, 'Mike,German\nMary,English\n');

@@ -83,5 +137,5 @@ });

});
describe('When encoding is specified', () => {
const filePath = makeFilePath('encoding');
const writer = createObjectCsvWriter({
describe('When encoding is specified', function () {
var filePath = makeFilePath('encoding');
var writer = createObjectCsvWriter({
path: filePath,

@@ -91,4 +145,4 @@ header: ['name', 'lang'],

});
it('writes to a file with the specified encoding', () => {
return writer.writeRecords(records).then(() => {
it('writes to a file with the specified encoding', function () {
return writer.writeRecords(records).then(function () {
helper_1.assertFile(filePath, 'Bob,French\nMary,English\n', 'utf16le');

@@ -98,5 +152,5 @@ });

});
describe('When semicolon is specified as a field delimiter', () => {
const filePath = makeFilePath('field-delimiter');
const writer = createObjectCsvWriter({
describe('When semicolon is specified as a field delimiter', function () {
var filePath = makeFilePath('field-delimiter');
var writer = createObjectCsvWriter({
path: filePath,

@@ -106,4 +160,4 @@ header: [{ id: 'name', title: 'NAME' }, { id: 'lang', title: 'LANGUAGE' }],

});
it('writes to a file with the specified encoding', () => {
return writer.writeRecords(records).then(() => {
it('uses semicolon instead of comma to separate fields', function () {
return writer.writeRecords(records).then(function () {
helper_1.assertFile(filePath, 'NAME;LANGUAGE\nBob;French\nMary;English\n');

@@ -113,3 +167,16 @@ });

});
describe('When newline is specified', function () {
var filePath = makeFilePath('newline');
var writer = createObjectCsvWriter({
path: filePath,
header: ['name', 'lang'],
recordDelimiter: '\r\n'
});
it('writes to a file with the specified newline character', function () {
return writer.writeRecords(records).then(function () {
helper_1.assertFile(filePath, 'Bob,French\r\nMary,English\r\n');
});
});
});
});
//# sourceMappingURL=write-object-records.test.js.map
{
"name": "csv-writer",
"version": "1.3.0",
"version": "1.4.0",
"description": "Convert objects/arrays into a CSV string or write them into a CSV file",

@@ -33,12 +33,12 @@ "main": "dist/index.js",

"devDependencies": {
"@types/mocha": "^5.2.6",
"@types/node": "^8.10.40",
"@types/mocha": "^5.2.7",
"@types/node": "^12.0.7",
"codeclimate-test-reporter": "^0.5.0",
"coveralls": "^3.0.0",
"mocha": "^6.0.2",
"nyc": "^13.3.0",
"ts-node": "^8.0.2",
"tslint": "^5.13.1",
"typescript": "^3.3.3333"
"coveralls": "^3.0.4",
"mocha": "^6.1.4",
"nyc": "^14.1.1",
"ts-node": "^8.2.0",
"tslint": "^5.17.0",
"typescript": "^3.5.1"
}
}

@@ -141,2 +141,6 @@ [![Build Status](https://travis-ci.org/ryu1kn/csv-writer.svg?branch=master)](https://travis-ci.org/ryu1kn/csv-writer)

* recordDelimiter `<string>` (optional)
Default: `\n`. Only either LF (`\n`) or CRLF (`\r\n`) is allowed.
* encoding `<string>` (optional)

@@ -175,2 +179,6 @@

* recordDelimiter `<string>` (optional)
Default: `\n`. Only either LF (`\n`) or CRLF (`\r\n`) is allowed.
* encoding `<string>` (optional)

@@ -219,2 +227,6 @@

* recordDelimiter `<string>` (optional)
Default: `\n`. Only either LF (`\n`) or CRLF (`\r\n`) is allowed.
##### Returns:

@@ -253,2 +265,6 @@

* recordDelimiter `<string>` (optional)
Default: `\n`. Only either LF (`\n`) or CRLF (`\r\n`) is allowed.
##### Returns:

@@ -255,0 +271,0 @@

@@ -12,2 +12,3 @@ import {ArrayCsvStringifier} from './csv-stringifiers/array';

fieldDelimiter?: string;
recordDelimiter?: string;
}

@@ -18,2 +19,3 @@

fieldDelimiter?: string;
recordDelimiter?: string;
}

@@ -27,3 +29,3 @@

const fieldStringifier = new FieldStringifier(fieldDelimiter);
return new ArrayCsvStringifier(fieldStringifier, fieldDelimiter, params.header);
return new ArrayCsvStringifier(fieldStringifier, fieldDelimiter, params.recordDelimiter, params.header);
}

@@ -35,3 +37,3 @@

const fieldStringifier = new FieldStringifier(fieldDelimiter);
return new ObjectCsvStringifier(fieldStringifier, fieldDelimiter, params.header);
return new ObjectCsvStringifier(fieldStringifier, fieldDelimiter, params.header, params.recordDelimiter);
}

@@ -38,0 +40,0 @@

import {FieldStringifier} from '../field-stringifier';
import {Field} from '../record';
const RECORD_DELIMITER = '\n';
const DEFAULT_RECORD_DELIMITER = '\n';
const VALID_RECORD_DELIMITERS = [DEFAULT_RECORD_DELIMITER, '\r\n'];

@@ -9,6 +10,9 @@ export abstract class CsvStringifier<T> {

private readonly fieldDelimiter: string;
private readonly recordDelimiter: string;
constructor(fieldStringifier: FieldStringifier, fieldDelimiter: string) {
constructor(fieldStringifier: FieldStringifier, fieldDelimiter: string, recordDelimiter?: string) {
this.fieldStringifier = fieldStringifier;
this.fieldDelimiter = fieldDelimiter;
this.recordDelimiter = recordDelimiter || DEFAULT_RECORD_DELIMITER;
_validateRecordDelimiter(this.recordDelimiter);
}

@@ -23,3 +27,3 @@

const csvLines = Array.from(records, record => this.getCsvLine(this.getRecordAsArray(record)));
return csvLines.join(RECORD_DELIMITER) + RECORD_DELIMITER;
return csvLines.join(this.recordDelimiter) + this.recordDelimiter;
}

@@ -37,1 +41,7 @@

}
function _validateRecordDelimiter(delimiter: string): void {
if (VALID_RECORD_DELIMITERS.indexOf(delimiter) === -1) {
throw new Error(`Invalid record delimiter \`${delimiter}\` is specified`);
}
}

@@ -8,4 +8,4 @@ import {CsvStringifier} from './abstract';

constructor(fieldStringifier: FieldStringifier, fieldDelimiter: string, header?: string[]) {
super(fieldStringifier, fieldDelimiter);
constructor(fieldStringifier: FieldStringifier, fieldDelimiter: string, recordDelimiter?: string, header?: string[]) {
super(fieldStringifier, fieldDelimiter, recordDelimiter);
this.header = header;

@@ -12,0 +12,0 @@ }

@@ -9,4 +9,4 @@ import {CsvStringifier} from './abstract';

constructor(fieldStringifier: FieldStringifier, fieldDelimiter: string, header: ObjectStringifierHeader) {
super(fieldStringifier, fieldDelimiter);
constructor(fieldStringifier: FieldStringifier, fieldDelimiter: string, header: ObjectStringifierHeader, recordDelimiter?: string) {
super(fieldStringifier, fieldDelimiter, recordDelimiter);
this.header = header;

@@ -13,0 +13,0 @@ }

import {CsvWriter} from './csv-writer';
import {CsvStringifierFactory} from './csv-stringifier-factory';
import {ObjectStringifierHeader} from './record';
import * as fs from 'fs';

@@ -10,2 +9,3 @@ export interface ArrayCsvWriterParams {

fieldDelimiter?: string;
recordDelimiter?: string;
encoding?: string;

@@ -19,2 +19,3 @@ append?: boolean;

fieldDelimiter?: string;
recordDelimiter?: string;
encoding?: string;

@@ -34,5 +35,6 @@ append?: boolean;

header: params.header,
fieldDelimiter: params.fieldDelimiter
fieldDelimiter: params.fieldDelimiter,
recordDelimiter: params.recordDelimiter
});
return new CsvWriter(csvStringifier, params.path, fs, params.encoding, params.append);
return new CsvWriter(csvStringifier, params.path, params.encoding, params.append);
}

@@ -43,6 +45,7 @@

header: params.header,
fieldDelimiter: params.fieldDelimiter
fieldDelimiter: params.fieldDelimiter,
recordDelimiter: params.recordDelimiter
});
return new CsvWriter(csvStringifier, params.path, fs, params.encoding, params.append);
return new CsvWriter(csvStringifier, params.path, params.encoding, params.append);
}
}
import {CsvStringifier} from './csv-stringifiers/abstract';
import {FileWriter} from './file-writer';
interface FileWriteOption {
encoding?: string | null;
mode?: number | string;
flag?: string;
}
const DEFAULT_ENCODING = 'utf8';
const DEFAULT_INITIAL_APPEND_FLAG = false;
export class CsvWriter<T> {
private readonly fs: any;
private readonly path: string;
private readonly csvStringifier: CsvStringifier<T>;
private readonly encoding: string;
private readonly fileWriter: FileWriter;
private append: boolean;
constructor(csvStringifier: CsvStringifier<T>, path: string, fs: any, encoding?: string, append?: boolean) {
this.fs = fs;
this.path = path;
constructor(csvStringifier: CsvStringifier<T>, path: string, encoding?: string, append?: boolean) {
this.append = append || DEFAULT_INITIAL_APPEND_FLAG;
this.fileWriter = new FileWriter(path, this.append, encoding);
this.csvStringifier = csvStringifier;
this.encoding = encoding || DEFAULT_ENCODING;
this.append = append || DEFAULT_INITIAL_APPEND_FLAG;
}
async writeRecords(records: T[]): Promise<void> {
const headerString = !this.append && this.csvStringifier.getHeaderString();
const recordsString = this.csvStringifier.stringifyRecords(records);
const writeString = (headerString || '') + recordsString;
const option = this.getWriteOption();
await this.write(writeString, option);
const writeString = this.headerString + recordsString;
await this.fileWriter.write(writeString);
this.append = true;
}
private write(string: string, options: FileWriteOption) {
return new Promise((resolve, reject) => {
this.fs.writeFile(this.path, string, options, (err: Error) => {
if (err) reject(err);
else resolve();
});
});
private get headerString(): string {
const headerString = !this.append && this.csvStringifier.getHeaderString();
return headerString || '';
}
private getWriteOption() {
return {
encoding: this.encoding,
flag: this.append ? 'a' : 'w'
};
}
}

@@ -23,2 +23,10 @@ import * as assert from 'assert';

describe('When record delimiter is neither LF nor CR+LF', () => {
it('throws an exception', () => {
assert.throws(() => {
createArrayCsvStringifier({recordDelimiter: '\r'});
});
});
});
describe('When records input is an iterable other than an array', () => {

@@ -25,0 +33,0 @@ const stringifier = createArrayCsvStringifier({

@@ -26,2 +26,13 @@ import * as assert from 'assert';

describe('When record delimiter is neither LF nor CR+LF', () => {
it('throws an exception', () => {
assert.throws(() => {
createObjectCsvStringifier({
header: ['FIELD_A', 'FIELD_B'],
recordDelimiter: '\r'
});
});
});
});
describe('When records input is an iterable other than an array', () => {

@@ -28,0 +39,0 @@ const stringifier = createObjectCsvStringifier({

@@ -40,5 +40,9 @@ import {assertFile, testFilePath} from './helper';

const filePath = makeFilePath('header');
const writer = createArrayCsvWriter({
path: filePath,
header: ['NAME', 'LANGUAGE']
let writer: CsvWriter<string[]>;
beforeEach(() => {
writer = createArrayCsvWriter({
path: filePath,
header: ['NAME', 'LANGUAGE']
});
});

@@ -51,2 +55,8 @@

});
it('appends records without headers', async () => {
await writer.writeRecords([records[0]]);
await writer.writeRecords([records[1]]);
assertFile(filePath, 'NAME,LANGUAGE\nBob,French\nMary,English\n');
});
});

@@ -91,3 +101,3 @@

it('writes to a file with the specified encoding', () => {
it('uses semicolon instead of comma to separate fields', () => {
return writer.writeRecords(records).then(() => {

@@ -98,2 +108,16 @@ assertFile(filePath, 'NAME;LANGUAGE\nBob;French\nMary;English\n');

});
describe('When newline is specified', () => {
const filePath = makeFilePath('newline');
const writer = createArrayCsvWriter({
path: filePath,
recordDelimiter: '\r\n'
});
it('writes to a file with the specified newline character', () => {
return writer.writeRecords(records).then(() => {
assertFile(filePath, 'Bob,French\r\nMary,English\r\n');
});
});
});
});

@@ -57,5 +57,9 @@ import {assertFile, testFilePath} from './helper';

const filePath = makeFilePath('header');
const writer = createObjectCsvWriter({
path: filePath,
header: [{id: 'name', title: 'NAME'}, {id: 'lang', title: 'LANGUAGE'}]
let writer: CsvWriter<{[k: string]: string}>;
beforeEach(() => {
writer = createObjectCsvWriter({
path: filePath,
header: [{id: 'name', title: 'NAME'}, {id: 'lang', title: 'LANGUAGE'}]
});
});

@@ -68,2 +72,8 @@

});
it('appends records without headers', async () => {
await writer.writeRecords([records[0]]);
await writer.writeRecords([records[1]]);
assertFile(filePath, 'NAME,LANGUAGE\nBob,French\nMary,English\n');
});
});

@@ -110,3 +120,3 @@

it('writes to a file with the specified encoding', () => {
it('uses semicolon instead of comma to separate fields', () => {
return writer.writeRecords(records).then(() => {

@@ -117,2 +127,17 @@ assertFile(filePath, 'NAME;LANGUAGE\nBob;French\nMary;English\n');

});
describe('When newline is specified', () => {
const filePath = makeFilePath('newline');
const writer = createObjectCsvWriter({
path: filePath,
header: ['name', 'lang'],
recordDelimiter: '\r\n'
});
it('writes to a file with the specified newline character', () => {
return writer.writeRecords(records).then(() => {
assertFile(filePath, 'Bob,French\r\nMary,English\r\n');
});
});
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc