fetch data from api app
This commit is contained in:
1 parent
68ee164b6b
commit
27619cca33
775 files changed
+142208
No files matched your search
+58
@@ -0,0 +1,58 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [1.6.0] - 2020-01-18
|
||||
### Added
|
||||
- Support for specifying values in nested objects. [#34](https://github.com/ryu1kn/csv-writer/pull/34)
|
||||
|
||||
## [1.5.0] - 2019-07-13
|
||||
### Added
|
||||
- Added `alwaysQuote` flag to always double-quote all fields. [#21](https://github.com/ryu1kn/csv-writer/pull/21)
|
||||
|
||||
## [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
|
||||
### Changed
|
||||
- Changed project language from JavaScript to TypeScript.
|
||||
|
||||
### Added
|
||||
- Made TypeScript type definitions accessible. Thanks to @coyotte508.
|
||||
[PR #23](https://github.com/ryu1kn/csv-writer/pull/23)
|
||||
|
||||
## [1.2.0] - 2018-08-22
|
||||
### Added
|
||||
- CSV records are now not limited to an array but can be an iterable object. Thanks to @pineapplemachine.
|
||||
[PR #11](https://github.com/ryu1kn/csv-writer/pull/11)
|
||||
|
||||
## [1.1.0] - 2018-08-20
|
||||
### Added
|
||||
- Allow semicolon as a field delimiter as it is commonly used in CSV in some regions. Thanks to @HKskn.
|
||||
[PR #8](https://github.com/ryu1kn/csv-writer/pull/8), [#6](https://github.com/ryu1kn/csv-writer/pull/6)
|
||||
|
||||
## [1.0.1] - 2018-08-09
|
||||
### Fixed
|
||||
- Fixed the issue that coverage report badge on README shows question mark.
|
||||
Use Coveralls instead of CodeClimate to get code coverage.
|
||||
|
||||
## [1.0.0] - 2018-02-28
|
||||
### Added
|
||||
- Support for adding CSV records to already existing files. Thanks to @jonmelcher. [PR #4](https://github.com/ryu1kn/csv-writer/pull/4)
|
||||
|
||||
## [0.0.3] - 2016-11-09
|
||||
### Fixed
|
||||
- Fixed the bug that fields were not always surrounded by double quotes
|
||||
- Fixed the bug that white space characters on the edge of fields were trimmed
|
||||
|
||||
## [0.0.2] - 2016-10-15
|
||||
### Fixed
|
||||
- Fixed the bug that field values were not quoted when they have newline characters
|
||||
|
||||
## [0.0.1] - 2016-09-09
|
||||
### Added
|
||||
- Initial release of csv-writer
|
||||
+328
@@ -0,0 +1,328 @@
|
||||
[](https://travis-ci.org/ryu1kn/csv-writer)
|
||||
[](https://coveralls.io/github/ryu1kn/csv-writer?branch=master)
|
||||
[](https://codeclimate.com/github/ryu1kn/csv-writer)
|
||||
|
||||
# CSV Writer
|
||||
|
||||
Convert objects/arrays into a CSV string or write them into a file.
|
||||
It respects [RFC 4180](https://tools.ietf.org/html/rfc4180) for the output CSV format.
|
||||
|
||||
## Prerequisite
|
||||
|
||||
* Node version 4 or above
|
||||
|
||||
## Usage
|
||||
|
||||
The example below shows how you can write records defined as the array of objects into a file.
|
||||
|
||||
```js
|
||||
const createCsvWriter = require('csv-writer').createObjectCsvWriter;
|
||||
const csvWriter = createCsvWriter({
|
||||
path: 'path/to/file.csv',
|
||||
header: [
|
||||
{id: 'name', title: 'NAME'},
|
||||
{id: 'lang', title: 'LANGUAGE'}
|
||||
]
|
||||
});
|
||||
|
||||
const records = [
|
||||
{name: 'Bob', lang: 'French, English'},
|
||||
{name: 'Mary', lang: 'English'}
|
||||
];
|
||||
|
||||
csvWriter.writeRecords(records) // returns a promise
|
||||
.then(() => {
|
||||
console.log('...Done');
|
||||
});
|
||||
|
||||
// This will produce a file path/to/file.csv with following contents:
|
||||
//
|
||||
// NAME,LANGUAGE
|
||||
// Bob,"French, English"
|
||||
// Mary,English
|
||||
```
|
||||
|
||||
You can keep writing records into the same file by calling `writeRecords` multiple times
|
||||
(but need to wait for the fulfillment of the `promise` of the previous `writeRecords` call).
|
||||
|
||||
```js
|
||||
// In an `async` function
|
||||
await csvWriter.writeRecords(records1)
|
||||
await csvWriter.writeRecords(records2)
|
||||
...
|
||||
```
|
||||
|
||||
However, if you need to keep writing large data to a certain file, you would want to create
|
||||
node's transform stream and use `CsvStringifier`, which is explained later, inside it
|
||||
, and pipe the stream into a file write stream.
|
||||
|
||||
If you don't want to write a header line, don't give `title` to header elements and just give field IDs as a string.
|
||||
|
||||
```js
|
||||
const createCsvWriter = require('csv-writer').createObjectCsvWriter;
|
||||
const csvWriter = createCsvWriter({
|
||||
path: 'path/to/file.csv',
|
||||
header: ['name', 'lang']
|
||||
});
|
||||
```
|
||||
|
||||
If each record is defined as an array, use `createArrayCsvWriter` to get an `csvWriter`.
|
||||
|
||||
```js
|
||||
const createCsvWriter = require('csv-writer').createArrayCsvWriter;
|
||||
const csvWriter = createCsvWriter({
|
||||
header: ['NAME', 'LANGUAGE'],
|
||||
path: 'path/to/file.csv'
|
||||
});
|
||||
|
||||
const records = [
|
||||
['Bob', 'French, English'],
|
||||
['Mary', 'English']
|
||||
];
|
||||
|
||||
csvWriter.writeRecords(records) // returns a promise
|
||||
.then(() => {
|
||||
console.log('...Done');
|
||||
});
|
||||
|
||||
// This will produce a file path/to/file.csv with following contents:
|
||||
//
|
||||
// NAME,LANGUAGE
|
||||
// Bob,"French, English"
|
||||
// Mary,English
|
||||
```
|
||||
|
||||
If you just want to get a CSV string but don't want to write into a file,
|
||||
you can use `createObjectCsvStringifier` (or `createArrayCsvStringifier`)
|
||||
to get an `csvStringifier`.
|
||||
|
||||
```js
|
||||
const createCsvStringifier = require('csv-writer').createObjectCsvStringifier;
|
||||
const csvStringifier = createCsvStringifier({
|
||||
header: [
|
||||
{id: 'name', title: 'NAME'},
|
||||
{id: 'lang', title: 'LANGUAGE'}
|
||||
]
|
||||
});
|
||||
|
||||
const records = [
|
||||
{name: 'Bob', lang: 'French, English'},
|
||||
{name: 'Mary', lang: 'English'}
|
||||
];
|
||||
|
||||
console.log(csvStringifier.getHeaderString());
|
||||
// => 'NAME,LANGUAGE\n'
|
||||
|
||||
console.log(csvStringifier.stringifyRecords(records));
|
||||
// => 'Bob,"French, English"\nMary,English\n'
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### createObjectCsvWriter(params)
|
||||
|
||||
##### Parameters:
|
||||
|
||||
* params `<Object>`
|
||||
* path `<string>`
|
||||
|
||||
Path to a write file
|
||||
|
||||
* header `<Array<{id, title}|string>>`
|
||||
|
||||
Array of objects (`id` and `title` properties) or strings (field IDs).
|
||||
A header line will be written to the file only if given as an array of objects.
|
||||
|
||||
* fieldDelimiter `<string>` (optional)
|
||||
|
||||
Default: `,`. Only either comma `,` or semicolon `;` is allowed.
|
||||
|
||||
* recordDelimiter `<string>` (optional)
|
||||
|
||||
Default: `\n`. Only either LF (`\n`) or CRLF (`\r\n`) is allowed.
|
||||
|
||||
* headerIdDelimiter `<string>` (optional)
|
||||
|
||||
Default: `undefined`. Give this value to specify a path to a value in a nested object.
|
||||
|
||||
* alwaysQuote `<boolean>` (optional)
|
||||
|
||||
Default: `false`. Set it to `true` to double-quote all fields regardless of their values.
|
||||
|
||||
* encoding `<string>` (optional)
|
||||
|
||||
Default: `utf8`.
|
||||
|
||||
* append `<boolean>` (optional)
|
||||
|
||||
Default: `false`. When `true`, it will append CSV records to the specified file.
|
||||
If the file doesn't exist, it will create one.
|
||||
|
||||
**NOTE:** A header line will not be written to the file if `true` is given.
|
||||
|
||||
##### Returns:
|
||||
|
||||
* `<CsvWriter>`
|
||||
|
||||
|
||||
### createArrayCsvWriter(params)
|
||||
|
||||
##### Parameters:
|
||||
|
||||
* params `<Object>`
|
||||
* path `<string>`
|
||||
|
||||
Path to a write file
|
||||
|
||||
* header `<Array<string>>` (optional)
|
||||
|
||||
Array of field titles
|
||||
|
||||
* fieldDelimiter `<string>` (optional)
|
||||
|
||||
Default: `,`. Only either comma `,` or semicolon `;` is allowed.
|
||||
|
||||
* recordDelimiter `<string>` (optional)
|
||||
|
||||
Default: `\n`. Only either LF (`\n`) or CRLF (`\r\n`) is allowed.
|
||||
|
||||
* alwaysQuote `<boolean>` (optional)
|
||||
|
||||
Default: `false`. Set it to `true` to double-quote all fields regardless of their values.
|
||||
|
||||
* encoding `<string>` (optional)
|
||||
|
||||
Default: `utf8`.
|
||||
|
||||
* append `<boolean>` (optional)
|
||||
|
||||
Default: `false`. When `true`, it will append CSV records to the specified file.
|
||||
If the file doesn't exist, it will create one.
|
||||
|
||||
**NOTE:** A header line will not be written to the file if `true` is given.
|
||||
|
||||
##### Returns:
|
||||
|
||||
* `<CsvWriter>`
|
||||
|
||||
|
||||
### CsvWriter#writeRecords(records)
|
||||
|
||||
##### Parameters:
|
||||
|
||||
* records `<Iterator<Object|Array>>`
|
||||
|
||||
Depending on which function was used to create a `csvWriter` (i.e. `createObjectCsvWriter` or `createArrayCsvWriter`),
|
||||
records will be either a collection of objects or arrays. As long as the collection is iterable, it doesn't need to be an array.
|
||||
|
||||
##### Returns:
|
||||
|
||||
* `<Promise>`
|
||||
|
||||
|
||||
### createObjectCsvStringifier(params)
|
||||
|
||||
##### Parameters:
|
||||
|
||||
* params `<Object>`
|
||||
* header `<Array<{id, title}|string>>`
|
||||
|
||||
Array of objects (`id` and `title` properties) or strings (field IDs)
|
||||
|
||||
* fieldDelimiter `<string>` (optional)
|
||||
|
||||
Default: `,`. Only either comma `,` or semicolon `;` is allowed.
|
||||
|
||||
* recordDelimiter `<string>` (optional)
|
||||
|
||||
Default: `\n`. Only either LF (`\n`) or CRLF (`\r\n`) is allowed.
|
||||
|
||||
* headerIdDelimiter `<string>` (optional)
|
||||
|
||||
Default: `undefined`. Give this value to specify a path to a value in a nested object.
|
||||
|
||||
* alwaysQuote `<boolean>` (optional)
|
||||
|
||||
Default: `false`. Set it to `true` to double-quote all fields regardless of their values.
|
||||
|
||||
##### Returns:
|
||||
|
||||
* `<ObjectCsvStringifier>`
|
||||
|
||||
### ObjectCsvStringifier#getHeaderString()
|
||||
|
||||
##### Returns:
|
||||
|
||||
* `<string>`
|
||||
|
||||
### ObjectCsvStringifier#stringifyRecords(records)
|
||||
|
||||
##### Parameters:
|
||||
|
||||
* records `<Array<Object>>`
|
||||
|
||||
##### Returns:
|
||||
|
||||
* `<string>`
|
||||
|
||||
### createArrayCsvStringifier(params)
|
||||
|
||||
##### Parameters:
|
||||
|
||||
* params `<Object>`
|
||||
* header `<Array<string>>` (optional)
|
||||
|
||||
Array of field titles
|
||||
|
||||
* fieldDelimiter `<string>` (optional)
|
||||
|
||||
Default: `,`. Only either comma `,` or semicolon `;` is allowed.
|
||||
|
||||
* recordDelimiter `<string>` (optional)
|
||||
|
||||
Default: `\n`. Only either LF (`\n`) or CRLF (`\r\n`) is allowed.
|
||||
|
||||
* alwaysQuote `<boolean>` (optional)
|
||||
|
||||
Default: `false`. Set it to `true` to double-quote all fields regardless of their values.
|
||||
|
||||
##### Returns:
|
||||
|
||||
* `<ArrayCsvStringifier>`
|
||||
|
||||
### ArrayCsvStringifier#getHeaderString()
|
||||
|
||||
##### Returns:
|
||||
|
||||
* `<string>`
|
||||
|
||||
### ArrayCsvStringifier#stringifyRecords(records)
|
||||
|
||||
##### Parameters:
|
||||
|
||||
* records `<Array<Array<string>>>`
|
||||
|
||||
##### Returns:
|
||||
|
||||
* `<string>`
|
||||
|
||||
|
||||
## Request Features or Report Bugs
|
||||
|
||||
Feature requests and bug reports are very welcome: https://github.com/ryu1kn/csv-writer/issues
|
||||
|
||||
A couple of requests from me when you raise an issue on GitHub.
|
||||
|
||||
* **Requesting a feature:** Please try to provide the context of why you want the feature. Such as,
|
||||
in what situation the feature could help you and how, or how the lack of the feature is causing an inconvenience to you.
|
||||
I can't start thinking of introducing it until I understand how it helps you 🙂
|
||||
* **Reporting a bug:** If you could provide a runnable code snippet that reproduces the bug, it would be very helpful!
|
||||
|
||||
|
||||
## Development
|
||||
|
||||
### Prerequisite
|
||||
|
||||
* Node version 8 or above
|
||||
* Docker
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
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
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,yEAIuC;AACvC,+DAAuG;AAEvG,IAAM,qBAAqB,GAAG,IAAI,+CAAqB,EAAE,CAAC;AAC1D,IAAM,gBAAgB,GAAG,IAAI,qCAAgB,CAAC,qBAAqB,CAAC,CAAC;AAExD,QAAA,yBAAyB,GAAG,UAAC,MAAiC;IACnE,OAAA,qBAAqB,CAAC,yBAAyB,CAAC,MAAM,CAAC;AAAvD,CAAuD,CAAC;AAEnD,QAAA,0BAA0B,GAAG,UAAC,MAAkC;IACrE,OAAA,qBAAqB,CAAC,0BAA0B,CAAC,MAAM,CAAC;AAAxD,CAAwD,CAAC;AAEpD,QAAA,oBAAoB,GAAG,UAAC,MAA4B;IACzD,OAAA,gBAAgB,CAAC,oBAAoB,CAAC,MAAM,CAAC;AAA7C,CAA6C,CAAC;AAEzC,QAAA,qBAAqB,GAAG,UAAC,MAA6B;IAC3D,OAAA,gBAAgB,CAAC,qBAAqB,CAAC,MAAM,CAAC;AAA9C,CAA8C,CAAC"}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var array_1 = require("./csv-stringifiers/array");
|
||||
var field_stringifier_1 = require("./field-stringifier");
|
||||
var object_1 = require("./csv-stringifiers/object");
|
||||
var CsvStringifierFactory = /** @class */ (function () {
|
||||
function CsvStringifierFactory() {
|
||||
}
|
||||
CsvStringifierFactory.prototype.createArrayCsvStringifier = function (params) {
|
||||
var fieldStringifier = field_stringifier_1.createFieldStringifier(params.fieldDelimiter, params.alwaysQuote);
|
||||
return new array_1.ArrayCsvStringifier(fieldStringifier, params.recordDelimiter, params.header);
|
||||
};
|
||||
CsvStringifierFactory.prototype.createObjectCsvStringifier = function (params) {
|
||||
var fieldStringifier = field_stringifier_1.createFieldStringifier(params.fieldDelimiter, params.alwaysQuote);
|
||||
return new object_1.ObjectCsvStringifier(fieldStringifier, params.header, params.recordDelimiter, params.headerIdDelimiter);
|
||||
};
|
||||
return CsvStringifierFactory;
|
||||
}());
|
||||
exports.CsvStringifierFactory = CsvStringifierFactory;
|
||||
//# sourceMappingURL=csv-stringifier-factory.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"csv-stringifier-factory.js","sourceRoot":"","sources":["../../src/lib/csv-stringifier-factory.ts"],"names":[],"mappings":";;AAAA,kDAA6D;AAC7D,yDAA2D;AAC3D,oDAA+D;AAkB/D;IAAA;IAYA,CAAC;IAVG,yDAAyB,GAAzB,UAA0B,MAAiC;QACvD,IAAM,gBAAgB,GAAG,0CAAsB,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;QAC3F,OAAO,IAAI,2BAAmB,CAAC,gBAAgB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5F,CAAC;IAED,0DAA0B,GAA1B,UAA2B,MAAkC;QACzD,IAAM,gBAAgB,GAAG,0CAAsB,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;QAC3F,OAAO,IAAI,6BAAoB,CAAC,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACvH,CAAC;IAEL,4BAAC;AAAD,CAAC,AAZD,IAYC;AAZY,sDAAqB"}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var DEFAULT_RECORD_DELIMITER = '\n';
|
||||
var VALID_RECORD_DELIMITERS = [DEFAULT_RECORD_DELIMITER, '\r\n'];
|
||||
var CsvStringifier = /** @class */ (function () {
|
||||
function CsvStringifier(fieldStringifier, recordDelimiter) {
|
||||
if (recordDelimiter === void 0) { recordDelimiter = DEFAULT_RECORD_DELIMITER; }
|
||||
this.fieldStringifier = fieldStringifier;
|
||||
this.recordDelimiter = recordDelimiter;
|
||||
_validateRecordDelimiter(recordDelimiter);
|
||||
}
|
||||
CsvStringifier.prototype.getHeaderString = function () {
|
||||
var headerRecord = this.getHeaderRecord();
|
||||
return headerRecord ? this.joinRecords([this.getCsvLine(headerRecord)]) : null;
|
||||
};
|
||||
CsvStringifier.prototype.stringifyRecords = function (records) {
|
||||
var _this = this;
|
||||
var csvLines = Array.from(records, function (record) { return _this.getCsvLine(_this.getRecordAsArray(record)); });
|
||||
return this.joinRecords(csvLines);
|
||||
};
|
||||
CsvStringifier.prototype.getCsvLine = function (record) {
|
||||
var _this = this;
|
||||
return record
|
||||
.map(function (fieldValue) { return _this.fieldStringifier.stringify(fieldValue); })
|
||||
.join(this.fieldStringifier.fieldDelimiter);
|
||||
};
|
||||
CsvStringifier.prototype.joinRecords = function (records) {
|
||||
return records.join(this.recordDelimiter) + this.recordDelimiter;
|
||||
};
|
||||
return CsvStringifier;
|
||||
}());
|
||||
exports.CsvStringifier = CsvStringifier;
|
||||
function _validateRecordDelimiter(delimiter) {
|
||||
if (VALID_RECORD_DELIMITERS.indexOf(delimiter) === -1) {
|
||||
throw new Error("Invalid record delimiter `" + delimiter + "` is specified");
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=abstract.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"abstract.js","sourceRoot":"","sources":["../../../src/lib/csv-stringifiers/abstract.ts"],"names":[],"mappings":";;AAGA,IAAM,wBAAwB,GAAG,IAAI,CAAC;AACtC,IAAM,uBAAuB,GAAG,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC;AAEnE;IAEI,wBAA6B,gBAAkC,EAClC,eAA0C;QAA1C,gCAAA,EAAA,0CAA0C;QAD1C,qBAAgB,GAAhB,gBAAgB,CAAkB;QAClC,oBAAe,GAAf,eAAe,CAA2B;QACnE,wBAAwB,CAAC,eAAe,CAAC,CAAC;IAC9C,CAAC;IAED,wCAAe,GAAf;QACI,IAAM,YAAY,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;QAC5C,OAAO,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACnF,CAAC;IAED,yCAAgB,GAAhB,UAAiB,OAAkC;QAAnD,iBAGC;QAFG,IAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,UAAA,MAAM,IAAI,OAAA,KAAI,CAAC,UAAU,CAAC,KAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,EAA9C,CAA8C,CAAC,CAAC;QAC/F,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACtC,CAAC;IAMO,mCAAU,GAAlB,UAAmB,MAAe;QAAlC,iBAIC;QAHG,OAAO,MAAM;aACR,GAAG,CAAC,UAAA,UAAU,IAAI,OAAA,KAAI,CAAC,gBAAgB,CAAC,SAAS,CAAC,UAAU,CAAC,EAA3C,CAA2C,CAAC;aAC9D,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;IACpD,CAAC;IAEO,oCAAW,GAAnB,UAAoB,OAAiB;QACjC,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC;IACrE,CAAC;IACL,qBAAC;AAAD,CAAC,AA9BD,IA8BC;AA9BqB,wCAAc;AAgCpC,SAAS,wBAAwB,CAAC,SAAiB;IAC/C,IAAI,uBAAuB,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE;QACnD,MAAM,IAAI,KAAK,CAAC,+BAA8B,SAAS,mBAAiB,CAAC,CAAC;KAC7E;AACL,CAAC"}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
"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 });
|
||||
var abstract_1 = require("./abstract");
|
||||
var ArrayCsvStringifier = /** @class */ (function (_super) {
|
||||
__extends(ArrayCsvStringifier, _super);
|
||||
function ArrayCsvStringifier(fieldStringifier, recordDelimiter, header) {
|
||||
var _this = _super.call(this, fieldStringifier, recordDelimiter) || this;
|
||||
_this.header = header;
|
||||
return _this;
|
||||
}
|
||||
ArrayCsvStringifier.prototype.getHeaderRecord = function () {
|
||||
return this.header;
|
||||
};
|
||||
ArrayCsvStringifier.prototype.getRecordAsArray = function (record) {
|
||||
return record;
|
||||
};
|
||||
return ArrayCsvStringifier;
|
||||
}(abstract_1.CsvStringifier));
|
||||
exports.ArrayCsvStringifier = ArrayCsvStringifier;
|
||||
//# sourceMappingURL=array.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"array.js","sourceRoot":"","sources":["../../../src/lib/csv-stringifiers/array.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,uCAA0C;AAI1C;IAAyC,uCAAuB;IAE5D,6BAAY,gBAAkC,EAClC,eAAwB,EACP,MAAiB;QAF9C,YAGI,kBAAM,gBAAgB,EAAE,eAAe,CAAC,SAC3C;QAF4B,YAAM,GAAN,MAAM,CAAW;;IAE9C,CAAC;IAES,6CAAe,GAAzB;QACI,OAAO,IAAI,CAAC,MAAM,CAAC;IACvB,CAAC;IAES,8CAAgB,GAA1B,UAA2B,MAAe;QACtC,OAAO,MAAM,CAAC;IAClB,CAAC;IACL,0BAAC;AAAD,CAAC,AAfD,CAAyC,yBAAc,GAetD;AAfY,kDAAmB"}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
"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 });
|
||||
var abstract_1 = require("./abstract");
|
||||
var object_1 = require("../lang/object");
|
||||
var ObjectCsvStringifier = /** @class */ (function (_super) {
|
||||
__extends(ObjectCsvStringifier, _super);
|
||||
function ObjectCsvStringifier(fieldStringifier, header, recordDelimiter, headerIdDelimiter) {
|
||||
var _this = _super.call(this, fieldStringifier, recordDelimiter) || this;
|
||||
_this.header = header;
|
||||
_this.headerIdDelimiter = headerIdDelimiter;
|
||||
return _this;
|
||||
}
|
||||
ObjectCsvStringifier.prototype.getHeaderRecord = function () {
|
||||
if (!this.isObjectHeader)
|
||||
return null;
|
||||
return this.header.map(function (field) { return field.title; });
|
||||
};
|
||||
ObjectCsvStringifier.prototype.getRecordAsArray = function (record) {
|
||||
var _this = this;
|
||||
return this.fieldIds.map(function (fieldId) { return _this.getNestedValue(record, fieldId); });
|
||||
};
|
||||
ObjectCsvStringifier.prototype.getNestedValue = function (obj, key) {
|
||||
if (!this.headerIdDelimiter)
|
||||
return obj[key];
|
||||
return key.split(this.headerIdDelimiter).reduce(function (subObj, keyPart) { return (subObj || {})[keyPart]; }, obj);
|
||||
};
|
||||
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 object_1.isObject(this.header && this.header[0]);
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
return ObjectCsvStringifier;
|
||||
}(abstract_1.CsvStringifier));
|
||||
exports.ObjectCsvStringifier = ObjectCsvStringifier;
|
||||
//# sourceMappingURL=object.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"object.js","sourceRoot":"","sources":["../../../src/lib/csv-stringifiers/object.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,uCAA0C;AAG1C,yCAAmD;AAEnD;IAA0C,wCAAgC;IAEtE,8BAAY,gBAAkC,EACjB,MAA+B,EAChD,eAAwB,EACP,iBAA0B;QAHvD,YAII,kBAAM,gBAAgB,EAAE,eAAe,CAAC,SAC3C;QAJ4B,YAAM,GAAN,MAAM,CAAyB;QAE/B,uBAAiB,GAAjB,iBAAiB,CAAS;;IAEvD,CAAC;IAES,8CAAe,GAAzB;QACI,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO,IAAI,CAAC;QACtC,OAAQ,IAAI,CAAC,MAA6B,CAAC,GAAG,CAAC,UAAA,KAAK,IAAI,OAAA,KAAK,CAAC,KAAK,EAAX,CAAW,CAAC,CAAC;IACzE,CAAC;IAES,+CAAgB,GAA1B,UAA2B,MAAwB;QAAnD,iBAEC;QADG,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAA,OAAO,IAAI,OAAA,KAAI,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,EAApC,CAAoC,CAAC,CAAC;IAC9E,CAAC;IAEO,6CAAc,GAAtB,UAAuB,GAAqB,EAAE,GAAW;QACrD,IAAI,CAAC,IAAI,CAAC,iBAAiB;YAAE,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7C,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC,UAAC,MAAM,EAAE,OAAO,IAAK,OAAA,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,EAAvB,CAAuB,EAAE,GAAG,CAAC,CAAC;IACvG,CAAC;IAED,sBAAY,0CAAQ;aAApB;YACI,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,CAAE,IAAI,CAAC,MAA6B,CAAC,GAAG,CAAC,UAAA,MAAM,IAAI,OAAA,MAAM,CAAC,EAAE,EAAT,CAAS,CAAC,CAAC,CAAC,CAAE,IAAI,CAAC,MAAmB,CAAC;QAC1H,CAAC;;;OAAA;IAED,sBAAY,gDAAc;aAA1B;YACI,OAAO,iBAAQ,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC;;;OAAA;IACL,2BAAC;AAAD,CAAC,AA9BD,CAA0C,yBAAc,GA8BvD;AA9BY,oDAAoB"}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var csv_writer_1 = require("./csv-writer");
|
||||
var CsvWriterFactory = /** @class */ (function () {
|
||||
function CsvWriterFactory(csvStringifierFactory) {
|
||||
this.csvStringifierFactory = csvStringifierFactory;
|
||||
}
|
||||
CsvWriterFactory.prototype.createArrayCsvWriter = function (params) {
|
||||
var csvStringifier = this.csvStringifierFactory.createArrayCsvStringifier({
|
||||
header: params.header,
|
||||
fieldDelimiter: params.fieldDelimiter,
|
||||
recordDelimiter: params.recordDelimiter,
|
||||
alwaysQuote: params.alwaysQuote
|
||||
});
|
||||
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,
|
||||
recordDelimiter: params.recordDelimiter,
|
||||
headerIdDelimiter: params.headerIdDelimiter,
|
||||
alwaysQuote: params.alwaysQuote
|
||||
});
|
||||
return new csv_writer_1.CsvWriter(csvStringifier, params.path, params.encoding, params.append);
|
||||
};
|
||||
return CsvWriterFactory;
|
||||
}());
|
||||
exports.CsvWriterFactory = CsvWriterFactory;
|
||||
//# sourceMappingURL=csv-writer-factory.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"csv-writer-factory.js","sourceRoot":"","sources":["../../src/lib/csv-writer-factory.ts"],"names":[],"mappings":";;AAAA,2CAAuC;AAyBvC;IACI,0BAA6B,qBAA4C;QAA5C,0BAAqB,GAArB,qBAAqB,CAAuB;IAAG,CAAC;IAE7E,+CAAoB,GAApB,UAAqB,MAA4B;QAC7C,IAAM,cAAc,GAAG,IAAI,CAAC,qBAAqB,CAAC,yBAAyB,CAAC;YACxE,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,WAAW,EAAE,MAAM,CAAC,WAAW;SAClC,CAAC,CAAC;QACH,OAAO,IAAI,sBAAS,CAAC,cAAc,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACtF,CAAC;IAED,gDAAqB,GAArB,UAAsB,MAA6B;QAC/C,IAAM,cAAc,GAAG,IAAI,CAAC,qBAAqB,CAAC,0BAA0B,CAAC;YACzE,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;YAC3C,WAAW,EAAE,MAAM,CAAC,WAAW;SAClC,CAAC,CAAC;QACH,OAAO,IAAI,sBAAS,CAAC,cAAc,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACtF,CAAC;IACL,uBAAC;AAAD,CAAC,AAvBD,IAuBC;AAvBY,4CAAgB"}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
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 });
|
||||
var file_writer_1 = require("./file-writer");
|
||||
var DEFAULT_INITIAL_APPEND_FLAG = false;
|
||||
var CsvWriter = /** @class */ (function () {
|
||||
function CsvWriter(csvStringifier, path, encoding, append) {
|
||||
if (append === void 0) { append = DEFAULT_INITIAL_APPEND_FLAG; }
|
||||
this.csvStringifier = csvStringifier;
|
||||
this.append = append;
|
||||
this.fileWriter = new file_writer_1.FileWriter(path, this.append, encoding);
|
||||
}
|
||||
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*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
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
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"csv-writer.js","sourceRoot":"","sources":["../../src/lib/csv-writer.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,6CAAyC;AAEzC,IAAM,2BAA2B,GAAG,KAAK,CAAC;AAE1C;IAGI,mBAA6B,cAAiC,EAClD,IAAY,EACZ,QAAiB,EACT,MAAoC;QAApC,uBAAA,EAAA,oCAAoC;QAH3B,mBAAc,GAAd,cAAc,CAAmB;QAG1C,WAAM,GAAN,MAAM,CAA8B;QACpD,IAAI,CAAC,UAAU,GAAG,IAAI,wBAAU,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAClE,CAAC;IAEK,gCAAY,GAAlB,UAAmB,OAAY;;;;;;wBACrB,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;wBAC9D,WAAW,GAAG,IAAI,CAAC,YAAY,GAAG,aAAa,CAAC;wBACtD,qBAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,WAAW,CAAC,EAAA;;wBAAxC,SAAwC,CAAC;wBACzC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;;;;;KACtB;IAED,sBAAY,mCAAY;aAAxB;YACI,IAAM,YAAY,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC;YAC3E,OAAO,YAAY,IAAI,EAAE,CAAC;QAC9B,CAAC;;;OAAA;IACL,gBAAC;AAAD,CAAC,AArBD,IAqBC;AArBY,8BAAS"}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
"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 });
|
||||
var DEFAULT_FIELD_DELIMITER = ',';
|
||||
var VALID_FIELD_DELIMITERS = [DEFAULT_FIELD_DELIMITER, ';'];
|
||||
var FieldStringifier = /** @class */ (function () {
|
||||
function FieldStringifier(fieldDelimiter) {
|
||||
this.fieldDelimiter = fieldDelimiter;
|
||||
}
|
||||
FieldStringifier.prototype.isEmpty = function (value) {
|
||||
return typeof value === 'undefined' || value === null || value === '';
|
||||
};
|
||||
FieldStringifier.prototype.quoteField = function (field) {
|
||||
return "\"" + field.replace(/"/g, '""') + "\"";
|
||||
};
|
||||
return FieldStringifier;
|
||||
}());
|
||||
exports.FieldStringifier = FieldStringifier;
|
||||
var DefaultFieldStringifier = /** @class */ (function (_super) {
|
||||
__extends(DefaultFieldStringifier, _super);
|
||||
function DefaultFieldStringifier() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
DefaultFieldStringifier.prototype.stringify = function (value) {
|
||||
if (this.isEmpty(value))
|
||||
return '';
|
||||
var str = String(value);
|
||||
return this.needsQuote(str) ? this.quoteField(str) : str;
|
||||
};
|
||||
DefaultFieldStringifier.prototype.needsQuote = function (str) {
|
||||
return str.includes(this.fieldDelimiter) || str.includes('\n') || str.includes('"');
|
||||
};
|
||||
return DefaultFieldStringifier;
|
||||
}(FieldStringifier));
|
||||
var ForceQuoteFieldStringifier = /** @class */ (function (_super) {
|
||||
__extends(ForceQuoteFieldStringifier, _super);
|
||||
function ForceQuoteFieldStringifier() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
ForceQuoteFieldStringifier.prototype.stringify = function (value) {
|
||||
return this.isEmpty(value) ? '' : this.quoteField(String(value));
|
||||
};
|
||||
return ForceQuoteFieldStringifier;
|
||||
}(FieldStringifier));
|
||||
function createFieldStringifier(fieldDelimiter, alwaysQuote) {
|
||||
if (fieldDelimiter === void 0) { fieldDelimiter = DEFAULT_FIELD_DELIMITER; }
|
||||
if (alwaysQuote === void 0) { alwaysQuote = false; }
|
||||
_validateFieldDelimiter(fieldDelimiter);
|
||||
return alwaysQuote ? new ForceQuoteFieldStringifier(fieldDelimiter) : new DefaultFieldStringifier(fieldDelimiter);
|
||||
}
|
||||
exports.createFieldStringifier = createFieldStringifier;
|
||||
function _validateFieldDelimiter(delimiter) {
|
||||
if (VALID_FIELD_DELIMITERS.indexOf(delimiter) === -1) {
|
||||
throw new Error("Invalid field delimiter `" + delimiter + "` is specified");
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=field-stringifier.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"field-stringifier.js","sourceRoot":"","sources":["../../src/lib/field-stringifier.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAEA,IAAM,uBAAuB,GAAG,GAAG,CAAC;AACpC,IAAM,sBAAsB,GAAG,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;AAE9D;IACI,0BAA4B,cAAsB;QAAtB,mBAAc,GAAd,cAAc,CAAQ;IAAG,CAAC;IAI5C,kCAAO,GAAjB,UAAkB,KAAa;QAC3B,OAAO,OAAO,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;IAC1E,CAAC;IAES,qCAAU,GAApB,UAAqB,KAAa;QAC9B,OAAO,OAAI,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,OAAG,CAAC;IAC5C,CAAC;IACL,uBAAC;AAAD,CAAC,AAZD,IAYC;AAZqB,4CAAgB;AActC;IAAsC,2CAAgB;IAAtD;;IAUA,CAAC;IATG,2CAAS,GAAT,UAAU,KAAa;QACnB,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACnC,IAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC7D,CAAC;IAEO,4CAAU,GAAlB,UAAmB,GAAW;QAC1B,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACxF,CAAC;IACL,8BAAC;AAAD,CAAC,AAVD,CAAsC,gBAAgB,GAUrD;AAED;IAAyC,8CAAgB;IAAzD;;IAIA,CAAC;IAHG,8CAAS,GAAT,UAAU,KAAa;QACnB,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACrE,CAAC;IACL,iCAAC;AAAD,CAAC,AAJD,CAAyC,gBAAgB,GAIxD;AAED,SAAgB,sBAAsB,CAAC,cAAgD,EAAE,WAAmB;IAArE,+BAAA,EAAA,wCAAgD;IAAE,4BAAA,EAAA,mBAAmB;IACxG,uBAAuB,CAAC,cAAc,CAAC,CAAC;IACxC,OAAO,WAAW,CAAC,CAAC,CAAC,IAAI,0BAA0B,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,uBAAuB,CAAC,cAAc,CAAC,CAAC;AACtH,CAAC;AAHD,wDAGC;AAED,SAAS,uBAAuB,CAAC,SAAiB;IAC9C,IAAI,sBAAsB,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE;QAClD,MAAM,IAAI,KAAK,CAAC,8BAA6B,SAAS,mBAAiB,CAAC,CAAC;KAC5E;AACL,CAAC"}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
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 });
|
||||
var promise_1 = require("./lang/promise");
|
||||
var fs_1 = require("fs");
|
||||
var writeFilePromise = promise_1.promisify(fs_1.writeFile);
|
||||
var DEFAULT_ENCODING = 'utf8';
|
||||
var FileWriter = /** @class */ (function () {
|
||||
function FileWriter(path, append, encoding) {
|
||||
if (encoding === void 0) { encoding = DEFAULT_ENCODING; }
|
||||
this.path = path;
|
||||
this.append = append;
|
||||
this.encoding = encoding;
|
||||
}
|
||||
FileWriter.prototype.write = function (string) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writeFilePromise(this.path, string, this.getWriteOption())];
|
||||
case 1:
|
||||
_a.sent();
|
||||
this.append = true;
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
FileWriter.prototype.getWriteOption = function () {
|
||||
return {
|
||||
encoding: this.encoding,
|
||||
flag: this.append ? 'a' : 'w'
|
||||
};
|
||||
};
|
||||
return FileWriter;
|
||||
}());
|
||||
exports.FileWriter = FileWriter;
|
||||
//# sourceMappingURL=file-writer.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"file-writer.js","sourceRoot":"","sources":["../../src/lib/file-writer.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,0CAAyC;AACzC,yBAA6B;AAE7B,IAAM,gBAAgB,GAAG,mBAAS,CAAC,cAAS,CAAC,CAAC;AAE9C,IAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC;IAEI,oBAA6B,IAAY,EACrB,MAAe,EACN,QAA2B;QAA3B,yBAAA,EAAA,2BAA2B;QAF3B,SAAI,GAAJ,IAAI,CAAQ;QACrB,WAAM,GAAN,MAAM,CAAS;QACN,aAAQ,GAAR,QAAQ,CAAmB;IACxD,CAAC;IAEK,0BAAK,GAAX,UAAY,MAAc;;;;4BACtB,qBAAM,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,EAAA;;wBAAhE,SAAgE,CAAC;wBACjE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;;;;;KACtB;IAEO,mCAAc,GAAtB;QACI,OAAO;YACH,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;SAChC,CAAC;IACN,CAAC;IACL,iBAAC;AAAD,CAAC,AAlBD,IAkBC;AAlBY,gCAAU"}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isObject = function (value) {
|
||||
return Object.prototype.toString.call(value) === '[object Object]';
|
||||
};
|
||||
//# sourceMappingURL=object.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"object.js","sourceRoot":"","sources":["../../../src/lib/lang/object.ts"],"names":[],"mappings":";;AAAa,QAAA,QAAQ,GAAG,UAAC,KAAU;IAC/B,OAAA,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,iBAAiB;AAA3D,CAA2D,CAAC"}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
"use strict";
|
||||
var __spreadArrays = (this && this.__spreadArrays) || function () {
|
||||
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
|
||||
for (var r = Array(s), k = 0, i = 0; i < il; i++)
|
||||
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
|
||||
r[k] = a[j];
|
||||
return r;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
function promisify(fn) {
|
||||
return function () {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
return new Promise(function (resolve, reject) {
|
||||
var nodeCallback = function (err, result) {
|
||||
if (err)
|
||||
reject(err);
|
||||
else
|
||||
resolve(result);
|
||||
};
|
||||
fn.apply(null, __spreadArrays(args, [nodeCallback]));
|
||||
});
|
||||
};
|
||||
}
|
||||
exports.promisify = promisify;
|
||||
//# sourceMappingURL=promise.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"promise.js","sourceRoot":"","sources":["../../../src/lib/lang/promise.ts"],"names":[],"mappings":";;;;;;;;;AAGA,SAAgB,SAAS,CAAC,EAA4B;IAClD,OAAO;QAAC,cAAc;aAAd,UAAc,EAAd,qBAAc,EAAd,IAAc;YAAd,yBAAc;;QAClB,OAAO,IAAI,OAAO,CAAC,UAAC,OAAO,EAAE,MAAM;YAC/B,IAAM,YAAY,GAAG,UAAC,GAAkB,EAAE,MAAW;gBACjD,IAAI,GAAG;oBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;;oBAChB,OAAO,CAAC,MAAM,CAAC,CAAC;YACzB,CAAC,CAAC;YACF,EAAE,CAAC,KAAK,CAAC,IAAI,iBAAM,IAAI,GAAE,YAAY,GAAE,CAAC;QAC5C,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC;AAVD,8BAUC"}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=record.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"record.js","sourceRoot":"","sources":["../../src/lib/record.ts"],"names":[],"mappings":""}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
"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 });
|
||||
var delimiter_1 = require("../helper/delimiter");
|
||||
var index_1 = require("../../index");
|
||||
var assert_1 = require("assert");
|
||||
describe('ArrayCsvStringifier', function () {
|
||||
var records = [
|
||||
['FIELD_A1', 'FIELD_B1'],
|
||||
['FIELD_A2', 'FIELD_B2']
|
||||
];
|
||||
describe('When field delimiter is comma', generateTestCases());
|
||||
describe('When field delimiter is semicolon', generateTestCases(';'));
|
||||
describe('When field delimiter is neither comma nor semicolon', function () {
|
||||
it('throws an exception', function () {
|
||||
assert_1.throws(function () {
|
||||
index_1.createArrayCsvStringifier({ fieldDelimiter: '/' });
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('When record delimiter is neither LF nor CR+LF', function () {
|
||||
it('throws an exception', function () {
|
||||
assert_1.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() {
|
||||
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', function () {
|
||||
assert_1.strictEqual(stringifier.stringifyRecords(recordGenerator()), 'FIELD_A1,FIELD_B1\nFIELD_A2,FIELD_B2\n');
|
||||
});
|
||||
});
|
||||
describe('When `alwaysQuote` flag is set', function () {
|
||||
var stringifier = index_1.createArrayCsvStringifier({
|
||||
header: ['TITLE_A', 'TITLE_B'],
|
||||
alwaysQuote: true
|
||||
});
|
||||
it('quotes all header fields', function () {
|
||||
assert_1.strictEqual(stringifier.getHeaderString(), '"TITLE_A","TITLE_B"\n');
|
||||
});
|
||||
it('quotes all data fields', function () {
|
||||
assert_1.strictEqual(stringifier.stringifyRecords(records), '"FIELD_A1","FIELD_B1"\n"FIELD_A2","FIELD_B2"\n');
|
||||
});
|
||||
});
|
||||
function generateTestCases(fieldDelimiter) {
|
||||
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
|
||||
});
|
||||
it("returns a header line with field separated by \"" + delim + "\"", function () {
|
||||
assert_1.strictEqual(stringifier.getHeaderString(), "TITLE_A" + delim + "TITLE_B\n");
|
||||
});
|
||||
it("converts given data records into CSV lines with field separated by \"" + delim + "\"", function () {
|
||||
assert_1.strictEqual(stringifier.stringifyRecords(records), "FIELD_A1" + delim + "FIELD_B1\nFIELD_A2" + delim + "FIELD_B2\n");
|
||||
});
|
||||
});
|
||||
describe('header is not specified', function () {
|
||||
var stringifier = index_1.createArrayCsvStringifier({ fieldDelimiter: fieldDelimiter });
|
||||
it('returns null for header line', function () {
|
||||
assert_1.strictEqual(stringifier.getHeaderString(), null);
|
||||
});
|
||||
it("converts given data records into CSV lines with field separated by \"" + delim + "\"", function () {
|
||||
assert_1.strictEqual(stringifier.stringifyRecords(records), "FIELD_A1" + delim + "FIELD_B1\nFIELD_A2" + delim + "FIELD_B2\n");
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=array.test.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"array.test.js","sourceRoot":"","sources":["../../../src/test/csv-stringifiers/array.test.ts"],"names":[],"mappings":"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"}
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
"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 });
|
||||
var delimiter_1 = require("../helper/delimiter");
|
||||
var index_1 = require("../../index");
|
||||
var assert_1 = require("assert");
|
||||
describe('ObjectCsvStringifier', function () {
|
||||
var records = [
|
||||
{ FIELD_A: 'VALUE_A1', FIELD_B: 'VALUE_B1' },
|
||||
{ FIELD_A: 'VALUE_A2', FIELD_B: 'VALUE_B2', OTHERS: { FIELD_C: 'VALUE_C2' } }
|
||||
];
|
||||
describe('When field delimiter is comma', generateTestCases());
|
||||
describe('When field delimiter is semicolon', generateTestCases(';'));
|
||||
describe('When field delimiter is neither comma nor semicolon', function () {
|
||||
it('throws an exception', function () {
|
||||
assert_1.throws(function () {
|
||||
index_1.createObjectCsvStringifier({
|
||||
header: ['FIELD_A', 'FIELD_B'],
|
||||
fieldDelimiter: '/'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('When record delimiter is neither LF nor CR+LF', function () {
|
||||
it('throws an exception', function () {
|
||||
assert_1.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() {
|
||||
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', function () {
|
||||
assert_1.strictEqual(stringifier.stringifyRecords(recordGenerator()), 'VALUE_A1,VALUE_B1\nVALUE_A2,VALUE_B2\n');
|
||||
});
|
||||
});
|
||||
describe('When `alwaysQuote` flag is set', function () {
|
||||
var stringifier = index_1.createObjectCsvStringifier({
|
||||
header: [
|
||||
{ id: 'FIELD_A', title: 'TITLE_A' },
|
||||
{ id: 'FIELD_B', title: 'TITLE_B' }
|
||||
],
|
||||
alwaysQuote: true
|
||||
});
|
||||
it('quotes all header fields', function () {
|
||||
assert_1.strictEqual(stringifier.getHeaderString(), '"TITLE_A","TITLE_B"\n');
|
||||
});
|
||||
it('quotes all data fields', function () {
|
||||
assert_1.strictEqual(stringifier.stringifyRecords(records), '"VALUE_A1","VALUE_B1"\n"VALUE_A2","VALUE_B2"\n');
|
||||
});
|
||||
});
|
||||
describe('When `headerIdDelimiter` is set', function () {
|
||||
var stringifier = index_1.createObjectCsvStringifier({
|
||||
header: [
|
||||
{ id: 'FIELD_A', title: 'TITLE_A' },
|
||||
{ id: 'OTHERS/FIELD_C', title: 'TITLE_C' }
|
||||
],
|
||||
headerIdDelimiter: '/'
|
||||
});
|
||||
it('uses the title as is', function () {
|
||||
assert_1.strictEqual(stringifier.getHeaderString(), 'TITLE_A,TITLE_C\n');
|
||||
});
|
||||
it('picks up a value in nested objects', function () {
|
||||
assert_1.strictEqual(stringifier.stringifyRecords(records), 'VALUE_A1,\nVALUE_A2,VALUE_C2\n');
|
||||
});
|
||||
});
|
||||
function generateTestCases(fieldDelimiter) {
|
||||
var delim = delimiter_1.resolveDelimiterChar(fieldDelimiter);
|
||||
return function () {
|
||||
describe('header is specified with title', function () {
|
||||
var stringifier = index_1.createObjectCsvStringifier({
|
||||
header: [
|
||||
{ id: 'FIELD_A', title: 'TITLE_A' },
|
||||
{ id: 'FIELD_B', title: 'TITLE_B' }
|
||||
],
|
||||
fieldDelimiter: fieldDelimiter
|
||||
});
|
||||
it("returns a header line with field separated by \"" + delim + "\"", function () {
|
||||
assert_1.strictEqual(stringifier.getHeaderString(), "TITLE_A" + delim + "TITLE_B\n");
|
||||
});
|
||||
it("converts given data records into CSV lines with field separated by \"" + delim + "\"", function () {
|
||||
assert_1.strictEqual(stringifier.stringifyRecords(records), "VALUE_A1" + delim + "VALUE_B1\nVALUE_A2" + delim + "VALUE_B2\n");
|
||||
});
|
||||
});
|
||||
describe('header is specified without title', function () {
|
||||
var stringifier = index_1.createObjectCsvStringifier({
|
||||
header: ['FIELD_A', 'FIELD_B'],
|
||||
fieldDelimiter: fieldDelimiter
|
||||
});
|
||||
it('returns null for header line', function () {
|
||||
assert_1.strictEqual(stringifier.getHeaderString(), null);
|
||||
});
|
||||
it("converts given data records into CSV lines with field separated by \"" + delim + "\"", function () {
|
||||
assert_1.strictEqual(stringifier.stringifyRecords(records), "VALUE_A1" + delim + "VALUE_B1\nVALUE_A2" + delim + "VALUE_B2\n");
|
||||
});
|
||||
});
|
||||
describe('header columns are given with reverse order', function () {
|
||||
var stringifier = index_1.createObjectCsvStringifier({
|
||||
header: [
|
||||
{ id: 'FIELD_B', title: 'TITLE_B' },
|
||||
{ id: 'FIELD_A', title: 'TITLE_A' }
|
||||
],
|
||||
fieldDelimiter: fieldDelimiter
|
||||
});
|
||||
it("layouts fields with the order of headers given with field separated by \"" + delim + "\"", function () {
|
||||
assert_1.strictEqual(stringifier.stringifyRecords(records), "VALUE_B1" + delim + "VALUE_A1\nVALUE_B2" + delim + "VALUE_A2\n");
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=object.test.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"object.test.js","sourceRoot":"","sources":["../../../src/test/csv-stringifiers/object.test.ts"],"names":[],"mappings":"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"}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var delimiter_1 = require("./helper/delimiter");
|
||||
var field_stringifier_1 = require("../lib/field-stringifier");
|
||||
var assert_1 = require("assert");
|
||||
describe('DefaultFieldStringifier', function () {
|
||||
describe('When field delimiter is comma', generateTestCases(','));
|
||||
describe('When field delimiter is semicolon', generateTestCases(';'));
|
||||
describe('When all fields needs to be quoted', function () {
|
||||
var stringifier = field_stringifier_1.createFieldStringifier(',', true);
|
||||
it('quotes a field', function () {
|
||||
assert_1.strictEqual(stringifier.stringify('VALUE'), '"VALUE"');
|
||||
});
|
||||
it('does not quote a field of value undefined', function () {
|
||||
assert_1.strictEqual(stringifier.stringify(), '');
|
||||
});
|
||||
it('does not quote a field of value null', function () {
|
||||
assert_1.strictEqual(stringifier.stringify(null), '');
|
||||
});
|
||||
it('does not quote a field of value empty string', function () {
|
||||
assert_1.strictEqual(stringifier.stringify(''), '');
|
||||
});
|
||||
});
|
||||
function generateTestCases(fieldDelimiter) {
|
||||
var delim = delimiter_1.resolveDelimiterChar(fieldDelimiter);
|
||||
return function () {
|
||||
var stringifier = field_stringifier_1.createFieldStringifier(fieldDelimiter);
|
||||
it('returns the same string', function () {
|
||||
assert_1.strictEqual(stringifier.stringify('VALUE'), 'VALUE');
|
||||
});
|
||||
it('preserves the whitespace characters', function () {
|
||||
assert_1.strictEqual(stringifier.stringify(' VALUE\tA '), ' VALUE\tA ');
|
||||
});
|
||||
it("wraps a field value with double quotes if the field contains \"" + delim + "\"", function () {
|
||||
assert_1.strictEqual(stringifier.stringify("VALUE" + delim + "A"), "\"VALUE" + delim + "A\"");
|
||||
});
|
||||
it('wraps a field value with double quotes if the field contains newline', function () {
|
||||
assert_1.strictEqual(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', function () {
|
||||
assert_1.strictEqual(stringifier.stringify('VALUE"A'), '"VALUE""A"');
|
||||
});
|
||||
it('escapes double quotes even if double quotes are only on the both edges of the field', function () {
|
||||
assert_1.strictEqual(stringifier.stringify('"VALUE"'), '"""VALUE"""');
|
||||
});
|
||||
it('converts a number into a string', function () {
|
||||
assert_1.strictEqual(stringifier.stringify(1), '1');
|
||||
});
|
||||
it('converts undefined into an empty string', function () {
|
||||
assert_1.strictEqual(stringifier.stringify(), '');
|
||||
});
|
||||
it('converts null into an empty string', function () {
|
||||
assert_1.strictEqual(stringifier.stringify(null), '');
|
||||
});
|
||||
it('converts an object into toString-ed value', function () {
|
||||
var obj = {
|
||||
name: 'OBJECT_NAME',
|
||||
toString: function () { return "Name: " + this.name; }
|
||||
};
|
||||
assert_1.strictEqual(stringifier.stringify(obj), 'Name: OBJECT_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_1.strictEqual(stringifier.stringify(obj), "\"Name: OBJECT" + delim + "NAME\"");
|
||||
});
|
||||
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; }
|
||||
};
|
||||
assert_1.strictEqual(stringifier.stringify(obj), '"Name: OBJECT_NAME"""');
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
//# sourceMappingURL=field-stringifier.test.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"field-stringifier.test.js","sourceRoot":"","sources":["../../src/test/field-stringifier.test.ts"],"names":[],"mappings":"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"}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var assert_1 = require("assert");
|
||||
var fs_1 = require("fs");
|
||||
exports.testFilePath = function (id) { return "./test-tmp/" + id + ".csv"; };
|
||||
exports.assertFile = function (path, expectedContents, encoding) {
|
||||
var actualContents = fs_1.readFileSync(path, encoding || 'utf8');
|
||||
assert_1.strictEqual(actualContents, expectedContents);
|
||||
};
|
||||
exports.assertRejected = function (p, message) {
|
||||
return p.then(function () { return new Error('Should not have been called'); }, function (e) { assert_1.strictEqual(e.message, message); });
|
||||
};
|
||||
//# sourceMappingURL=helper.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../../src/test/helper.ts"],"names":[],"mappings":";;AAAA,iCAAmC;AACnC,yBAAgC;AAEnB,QAAA,YAAY,GAAG,UAAC,EAAU,IAAK,OAAA,gBAAc,EAAE,SAAM,EAAtB,CAAsB,CAAC;AAEtD,QAAA,UAAU,GAAG,UAAC,IAAY,EAAE,gBAAwB,EAAE,QAAiB;IAChF,IAAM,cAAc,GAAG,iBAAY,CAAC,IAAI,EAAE,QAAQ,IAAI,MAAM,CAAC,CAAC;IAC9D,oBAAW,CAAC,cAAc,EAAE,gBAAgB,CAAC,CAAC;AAClD,CAAC,CAAC;AAEW,QAAA,cAAc,GAAG,UAAC,CAAe,EAAE,OAAe;IAC3D,OAAO,CAAC,CAAC,IAAI,CACT,cAAM,OAAA,IAAI,KAAK,CAAC,6BAA6B,CAAC,EAAxC,CAAwC,EAC9C,UAAC,CAAQ,IAAO,oBAAW,CAAC,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CACrD,CAAC;AACN,CAAC,CAAC"}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.resolveDelimiterChar = function (char) {
|
||||
if (char === ',' || char === ';')
|
||||
return char;
|
||||
if (typeof char === 'undefined')
|
||||
return ',';
|
||||
throw new Error('Invalid field delimiter');
|
||||
};
|
||||
//# sourceMappingURL=delimiter.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"delimiter.js","sourceRoot":"","sources":["../../../src/test/helper/delimiter.ts"],"names":[],"mappings":";;AACa,QAAA,oBAAoB,GAAG,UAAC,IAAa;IAC9C,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,OAAO,IAAI,KAAK,WAAW;QAAE,OAAO,GAAG,CAAC;IAC5C,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;AAC/C,CAAC,CAAC"}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
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 });
|
||||
var promise_1 = require("../../lib/lang/promise");
|
||||
var assert_1 = require("assert");
|
||||
var helper_1 = require("../helper");
|
||||
describe('Promise', function () {
|
||||
var greetAsync = function (name, callback) {
|
||||
setTimeout(function () {
|
||||
if (name === 'foo')
|
||||
callback(null, "Hello, " + name + "!");
|
||||
else
|
||||
callback(new Error("We don't know " + name));
|
||||
}, 0);
|
||||
};
|
||||
var promisifiedFn = promise_1.promisify(greetAsync);
|
||||
it('promisify node style callback', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
var _a;
|
||||
return __generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0:
|
||||
_a = assert_1.strictEqual;
|
||||
return [4 /*yield*/, promisifiedFn('foo')];
|
||||
case 1:
|
||||
_a.apply(void 0, [_b.sent(), 'Hello, foo!']);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('raise an error for error', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, helper_1.assertRejected(promisifiedFn('bar'), "We don't know bar")];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
});
|
||||
//# sourceMappingURL=promise.test.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"promise.test.js","sourceRoot":"","sources":["../../../src/test/lang/promise.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAAiD;AACjD,iCAAmC;AACnC,oCAAyC;AAEzC,QAAQ,CAAC,SAAS,EAAE;IAChB,IAAM,UAAU,GAAG,UAAC,IAAY,EAAE,QAAsD;QACpF,UAAU,CAAC;YACP,IAAI,IAAI,KAAK,KAAK;gBAAE,QAAQ,CAAC,IAAI,EAAE,YAAU,IAAI,MAAG,CAAC,CAAC;;gBACjD,QAAQ,CAAC,IAAI,KAAK,CAAC,mBAAiB,IAAM,CAAC,CAAC,CAAC;QACtD,CAAC,EAAE,CAAC,CAAC,CAAC;IACV,CAAC,CAAC;IACF,IAAM,aAAa,GAAG,mBAAS,CAAC,UAAU,CAAC,CAAC;IAE5C,EAAE,CAAC,+BAA+B,EAAE;;;;;oBAChC,KAAA,oBAAW,CAAA;oBAAC,qBAAM,aAAa,CAAC,KAAK,CAAC,EAAA;;oBAAtC,kBAAY,SAA0B,EAAE,aAAa,EAAC,CAAC;;;;SAC1D,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE;;;wBAC3B,qBAAM,uBAAc,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,mBAAmB,CAAC,EAAA;;oBAA/D,SAA+D,CAAC;;;;SACnE,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
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 });
|
||||
var helper_1 = require("./helper");
|
||||
var fs_1 = require("fs");
|
||||
var index_1 = require("../index");
|
||||
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', function () {
|
||||
var filePath = makeFilePath('minimum');
|
||||
var writer;
|
||||
beforeEach(function () {
|
||||
writer = index_1.createArrayCsvWriter({ path: filePath });
|
||||
});
|
||||
it('writes records to a new file', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writer.writeRecords(records)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
helper_1.assertFile(filePath, 'Bob,French\nMary,English\n');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('appends records when requested to write to the same file', function () { return __awaiter(void 0, 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', function () {
|
||||
var filePath = makeFilePath('header');
|
||||
var writer;
|
||||
beforeEach(function () {
|
||||
writer = index_1.createArrayCsvWriter({
|
||||
path: filePath,
|
||||
header: ['NAME', 'LANGUAGE']
|
||||
});
|
||||
});
|
||||
it('writes a header', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writer.writeRecords(records)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
helper_1.assertFile(filePath, 'NAME,LANGUAGE\nBob,French\nMary,English\n');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('appends records without headers', function () { return __awaiter(void 0, 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', function () {
|
||||
var filePath = makeFilePath('append');
|
||||
fs_1.writeFileSync(filePath, 'Mike,German\n', 'utf8');
|
||||
var writer = index_1.createArrayCsvWriter({
|
||||
path: filePath,
|
||||
append: true
|
||||
});
|
||||
it('do not overwrite the existing contents and appends records to them', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writer.writeRecords([records[1]])];
|
||||
case 1:
|
||||
_a.sent();
|
||||
helper_1.assertFile(filePath, 'Mike,German\nMary,English\n');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
});
|
||||
describe('When encoding is specified', function () {
|
||||
var filePath = makeFilePath('encoding');
|
||||
var writer = index_1.createArrayCsvWriter({
|
||||
path: filePath,
|
||||
encoding: 'utf16le'
|
||||
});
|
||||
it('writes to a file with the specified encoding', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writer.writeRecords(records)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
helper_1.assertFile(filePath, 'Bob,French\nMary,English\n', 'utf16le');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
});
|
||||
describe('When semicolon is specified as a field delimiter', function () {
|
||||
var filePath = makeFilePath('field-delimiter');
|
||||
var writer = index_1.createArrayCsvWriter({
|
||||
path: filePath,
|
||||
header: ['NAME', 'LANGUAGE'],
|
||||
fieldDelimiter: ';'
|
||||
});
|
||||
it('uses semicolon instead of comma to separate fields', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writer.writeRecords(records)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
helper_1.assertFile(filePath, 'NAME;LANGUAGE\nBob;French\nMary;English\n');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
});
|
||||
describe('When newline is specified', function () {
|
||||
var filePath = makeFilePath('newline');
|
||||
var writer = index_1.createArrayCsvWriter({
|
||||
path: filePath,
|
||||
recordDelimiter: '\r\n'
|
||||
});
|
||||
it('writes to a file with the specified newline character', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writer.writeRecords(records)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
helper_1.assertFile(filePath, 'Bob,French\r\nMary,English\r\n');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
});
|
||||
describe('When `alwaysQuote` flag is set', function () {
|
||||
var filePath = makeFilePath('always-quote');
|
||||
var writer = index_1.createArrayCsvWriter({
|
||||
path: filePath,
|
||||
header: ['NAME', 'LANGUAGE'],
|
||||
alwaysQuote: true
|
||||
});
|
||||
it('quotes all fields', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writer.writeRecords(records)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
helper_1.assertFile(filePath, '"NAME","LANGUAGE"\n"Bob","French"\n"Mary","English"\n');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
});
|
||||
});
|
||||
//# sourceMappingURL=write-array-records.test.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"write-array-records.test.js","sourceRoot":"","sources":["../../src/test/write-array-records.test.ts"],"names":[],"mappings":"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"}
|
||||
+252
@@ -0,0 +1,252 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
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 });
|
||||
var helper_1 = require("./helper");
|
||||
var fs_1 = require("fs");
|
||||
var index_1 = require("../index");
|
||||
describe('Write object records into CSV', function () {
|
||||
var makeFilePath = function (id) { return helper_1.testFilePath("object-" + id); };
|
||||
var records = [
|
||||
{ name: 'Bob', lang: 'French', address: { country: 'France' } },
|
||||
{ name: 'Mary', lang: 'English' }
|
||||
];
|
||||
describe('When only path and header ids are given', function () {
|
||||
var filePath = makeFilePath('minimum');
|
||||
var writer;
|
||||
beforeEach(function () {
|
||||
writer = index_1.createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: ['name', 'lang']
|
||||
});
|
||||
});
|
||||
it('writes records to a new file', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writer.writeRecords(records)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
helper_1.assertFile(filePath, 'Bob,French\nMary,English\n');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('appends records when requested to write to the same file', function () { return __awaiter(void 0, 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', function () {
|
||||
var filePath = makeFilePath('column-order');
|
||||
var writer = index_1.createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: ['lang', 'name']
|
||||
});
|
||||
it('also writes columns with reverse order', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writer.writeRecords(records)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
helper_1.assertFile(filePath, 'French,Bob\nEnglish,Mary\n');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
});
|
||||
describe('When field header is given with titles', function () {
|
||||
var filePath = makeFilePath('header');
|
||||
var writer;
|
||||
beforeEach(function () {
|
||||
writer = index_1.createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: [{ id: 'name', title: 'NAME' }, { id: 'lang', title: 'LANGUAGE' }]
|
||||
});
|
||||
});
|
||||
it('writes a header', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writer.writeRecords(records)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
helper_1.assertFile(filePath, 'NAME,LANGUAGE\nBob,French\nMary,English\n');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('appends records without headers', function () { return __awaiter(void 0, 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', function () {
|
||||
var filePath = makeFilePath('append');
|
||||
fs_1.writeFileSync(filePath, 'Mike,German\n', 'utf8');
|
||||
var writer = index_1.createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: ['name', 'lang'],
|
||||
append: true
|
||||
});
|
||||
it('do not overwrite the existing contents and appends records to them', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writer.writeRecords([records[1]])];
|
||||
case 1:
|
||||
_a.sent();
|
||||
helper_1.assertFile(filePath, 'Mike,German\nMary,English\n');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
});
|
||||
describe('When encoding is specified', function () {
|
||||
var filePath = makeFilePath('encoding');
|
||||
var writer = index_1.createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: ['name', 'lang'],
|
||||
encoding: 'utf16le'
|
||||
});
|
||||
it('writes to a file with the specified encoding', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writer.writeRecords(records)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
helper_1.assertFile(filePath, 'Bob,French\nMary,English\n', 'utf16le');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
});
|
||||
describe('When semicolon is specified as a field delimiter', function () {
|
||||
var filePath = makeFilePath('field-delimiter');
|
||||
var writer = index_1.createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: [{ id: 'name', title: 'NAME' }, { id: 'lang', title: 'LANGUAGE' }],
|
||||
fieldDelimiter: ';'
|
||||
});
|
||||
it('uses semicolon instead of comma to separate fields', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writer.writeRecords(records)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
helper_1.assertFile(filePath, 'NAME;LANGUAGE\nBob;French\nMary;English\n');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
});
|
||||
describe('When newline is specified', function () {
|
||||
var filePath = makeFilePath('newline');
|
||||
var writer = index_1.createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: ['name', 'lang'],
|
||||
recordDelimiter: '\r\n'
|
||||
});
|
||||
it('writes to a file with the specified newline character', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writer.writeRecords(records)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
helper_1.assertFile(filePath, 'Bob,French\r\nMary,English\r\n');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
});
|
||||
describe('When `alwaysQuote` flag is set', function () {
|
||||
var filePath = makeFilePath('always-quote');
|
||||
var writer = index_1.createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: [{ id: 'name', title: 'NAME' }, { id: 'lang', title: 'LANGUAGE' }],
|
||||
alwaysQuote: true
|
||||
});
|
||||
it('quotes all fields', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writer.writeRecords(records)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
helper_1.assertFile(filePath, '"NAME","LANGUAGE"\n"Bob","French"\n"Mary","English"\n');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
});
|
||||
describe('When `headerIdDelimiter` flag is set', function () {
|
||||
var filePath = makeFilePath('nested');
|
||||
var writer = index_1.createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: [{ id: 'name', title: 'NAME' }, { id: 'address.country', title: 'COUNTRY' }],
|
||||
headerIdDelimiter: '.'
|
||||
});
|
||||
it('breaks keys into key paths', function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, writer.writeRecords(records)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
helper_1.assertFile(filePath, 'NAME,COUNTRY\nBob,France\nMary,\n');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
});
|
||||
});
|
||||
//# sourceMappingURL=write-object-records.test.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"write-object-records.test.js","sourceRoot":"","sources":["../../src/test/write-object-records.test.ts"],"names":[],"mappings":"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"}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "csv-writer",
|
||||
"version": "1.6.0",
|
||||
"description": "Convert objects/arrays into a CSV string or write them into a CSV file",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
"scripts": {
|
||||
"compile": "tsc -p ./",
|
||||
"test": "npm run test:unit && npm run test:it",
|
||||
"pretest:unit": "rm -rf test-tmp && mkdir test-tmp",
|
||||
"test:unit": "mocha --require ts-node/register --recursive 'src/test/**/*.ts'",
|
||||
"test:it": "test-integration/test.sh",
|
||||
"coverage": "nyc npm run test:unit",
|
||||
"lint": "tslint -p .",
|
||||
"prepare": "npm run compile"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/ryu1kn/csv-writer.git"
|
||||
},
|
||||
"keywords": [
|
||||
"csv",
|
||||
"writer",
|
||||
"stringify"
|
||||
],
|
||||
"author": "Ryuichi Inagaki",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/ryu1kn/csv-writer/issues"
|
||||
},
|
||||
"homepage": "https://github.com/ryu1kn/csv-writer#readme",
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "^12.12.25",
|
||||
"codeclimate-test-reporter": "^0.5.1",
|
||||
"coveralls": "^3.0.9",
|
||||
"mocha": "^7.0.0",
|
||||
"nyc": "^15.0.0",
|
||||
"ts-node": "^8.6.2",
|
||||
"tslint": "^5.20.1",
|
||||
"typescript": "^3.7.5"
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import {
|
||||
ArrayCsvStringifierParams,
|
||||
CsvStringifierFactory,
|
||||
ObjectCsvStringifierParams
|
||||
} from './lib/csv-stringifier-factory';
|
||||
import {ArrayCsvWriterParams, CsvWriterFactory, ObjectCsvWriterParams} from './lib/csv-writer-factory';
|
||||
|
||||
const csvStringifierFactory = new CsvStringifierFactory();
|
||||
const csvWriterFactory = new CsvWriterFactory(csvStringifierFactory);
|
||||
|
||||
export const createArrayCsvStringifier = (params: ArrayCsvStringifierParams) =>
|
||||
csvStringifierFactory.createArrayCsvStringifier(params);
|
||||
|
||||
export const createObjectCsvStringifier = (params: ObjectCsvStringifierParams) =>
|
||||
csvStringifierFactory.createObjectCsvStringifier(params);
|
||||
|
||||
export const createArrayCsvWriter = (params: ArrayCsvWriterParams) =>
|
||||
csvWriterFactory.createArrayCsvWriter(params);
|
||||
|
||||
export const createObjectCsvWriter = (params: ObjectCsvWriterParams) =>
|
||||
csvWriterFactory.createObjectCsvWriter(params);
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
import {ArrayCsvStringifier} from './csv-stringifiers/array';
|
||||
import {createFieldStringifier} from './field-stringifier';
|
||||
import {ObjectCsvStringifier} from './csv-stringifiers/object';
|
||||
import {ObjectStringifierHeader} from './record';
|
||||
|
||||
export interface ArrayCsvStringifierParams {
|
||||
header?: string[];
|
||||
fieldDelimiter?: string;
|
||||
recordDelimiter?: string;
|
||||
alwaysQuote?: boolean;
|
||||
}
|
||||
|
||||
export interface ObjectCsvStringifierParams {
|
||||
header: ObjectStringifierHeader;
|
||||
fieldDelimiter?: string;
|
||||
recordDelimiter?: string;
|
||||
headerIdDelimiter?: string;
|
||||
alwaysQuote?: boolean;
|
||||
}
|
||||
|
||||
export class CsvStringifierFactory {
|
||||
|
||||
createArrayCsvStringifier(params: ArrayCsvStringifierParams) {
|
||||
const fieldStringifier = createFieldStringifier(params.fieldDelimiter, params.alwaysQuote);
|
||||
return new ArrayCsvStringifier(fieldStringifier, params.recordDelimiter, params.header);
|
||||
}
|
||||
|
||||
createObjectCsvStringifier(params: ObjectCsvStringifierParams) {
|
||||
const fieldStringifier = createFieldStringifier(params.fieldDelimiter, params.alwaysQuote);
|
||||
return new ObjectCsvStringifier(fieldStringifier, params.header, params.recordDelimiter, params.headerIdDelimiter);
|
||||
}
|
||||
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
import {FieldStringifier} from '../field-stringifier';
|
||||
import {Field} from '../record';
|
||||
|
||||
const DEFAULT_RECORD_DELIMITER = '\n';
|
||||
const VALID_RECORD_DELIMITERS = [DEFAULT_RECORD_DELIMITER, '\r\n'];
|
||||
|
||||
export abstract class CsvStringifier<T> {
|
||||
|
||||
constructor(private readonly fieldStringifier: FieldStringifier,
|
||||
private readonly recordDelimiter = DEFAULT_RECORD_DELIMITER) {
|
||||
_validateRecordDelimiter(recordDelimiter);
|
||||
}
|
||||
|
||||
getHeaderString(): string | null {
|
||||
const headerRecord = this.getHeaderRecord();
|
||||
return headerRecord ? this.joinRecords([this.getCsvLine(headerRecord)]) : null;
|
||||
}
|
||||
|
||||
stringifyRecords(records: IterableIterator<T> | T[]): string {
|
||||
const csvLines = Array.from(records, record => this.getCsvLine(this.getRecordAsArray(record)));
|
||||
return this.joinRecords(csvLines);
|
||||
}
|
||||
|
||||
protected abstract getRecordAsArray(_record: T): Field[];
|
||||
|
||||
protected abstract getHeaderRecord(): string[] | null | undefined;
|
||||
|
||||
private getCsvLine(record: Field[]): string {
|
||||
return record
|
||||
.map(fieldValue => this.fieldStringifier.stringify(fieldValue))
|
||||
.join(this.fieldStringifier.fieldDelimiter);
|
||||
}
|
||||
|
||||
private joinRecords(records: string[]) {
|
||||
return records.join(this.recordDelimiter) + this.recordDelimiter;
|
||||
}
|
||||
}
|
||||
|
||||
function _validateRecordDelimiter(delimiter: string): void {
|
||||
if (VALID_RECORD_DELIMITERS.indexOf(delimiter) === -1) {
|
||||
throw new Error(`Invalid record delimiter \`${delimiter}\` is specified`);
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
import {CsvStringifier} from './abstract';
|
||||
import {FieldStringifier} from '../field-stringifier';
|
||||
import {Field} from '../record';
|
||||
|
||||
export class ArrayCsvStringifier extends CsvStringifier<Field[]> {
|
||||
|
||||
constructor(fieldStringifier: FieldStringifier,
|
||||
recordDelimiter?: string,
|
||||
private readonly header?: string[]) {
|
||||
super(fieldStringifier, recordDelimiter);
|
||||
}
|
||||
|
||||
protected getHeaderRecord() {
|
||||
return this.header;
|
||||
}
|
||||
|
||||
protected getRecordAsArray(record: Field[]): Field[] {
|
||||
return record;
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
import {CsvStringifier} from './abstract';
|
||||
import {FieldStringifier} from '../field-stringifier';
|
||||
import {Field, ObjectHeaderItem, ObjectStringifierHeader} from '../record';
|
||||
import {isObject, ObjectMap} from '../lang/object';
|
||||
|
||||
export class ObjectCsvStringifier extends CsvStringifier<ObjectMap<Field>> {
|
||||
|
||||
constructor(fieldStringifier: FieldStringifier,
|
||||
private readonly header: ObjectStringifierHeader,
|
||||
recordDelimiter?: string,
|
||||
private readonly headerIdDelimiter?: string) {
|
||||
super(fieldStringifier, recordDelimiter);
|
||||
}
|
||||
|
||||
protected getHeaderRecord(): string[] | null {
|
||||
if (!this.isObjectHeader) return null;
|
||||
return (this.header as ObjectHeaderItem[]).map(field => field.title);
|
||||
}
|
||||
|
||||
protected getRecordAsArray(record: ObjectMap<Field>): Field[] {
|
||||
return this.fieldIds.map(fieldId => this.getNestedValue(record, fieldId));
|
||||
}
|
||||
|
||||
private getNestedValue(obj: ObjectMap<Field>, key: string) {
|
||||
if (!this.headerIdDelimiter) return obj[key];
|
||||
return key.split(this.headerIdDelimiter).reduce((subObj, keyPart) => (subObj || {})[keyPart], obj);
|
||||
}
|
||||
|
||||
private get fieldIds(): string[] {
|
||||
return this.isObjectHeader ? (this.header as ObjectHeaderItem[]).map(column => column.id) : (this.header as string[]);
|
||||
}
|
||||
|
||||
private get isObjectHeader(): boolean {
|
||||
return isObject(this.header && this.header[0]);
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
import {CsvWriter} from './csv-writer';
|
||||
import {CsvStringifierFactory} from './csv-stringifier-factory';
|
||||
import {ObjectStringifierHeader} from './record';
|
||||
|
||||
export interface ArrayCsvWriterParams {
|
||||
path: string;
|
||||
header?: string[];
|
||||
fieldDelimiter?: string;
|
||||
recordDelimiter?: string;
|
||||
alwaysQuote?: boolean;
|
||||
encoding?: string;
|
||||
append?: boolean;
|
||||
}
|
||||
|
||||
export interface ObjectCsvWriterParams {
|
||||
path: string;
|
||||
header: ObjectStringifierHeader;
|
||||
fieldDelimiter?: string;
|
||||
recordDelimiter?: string;
|
||||
headerIdDelimiter?: string;
|
||||
alwaysQuote?: boolean;
|
||||
encoding?: string;
|
||||
append?: boolean;
|
||||
}
|
||||
|
||||
export class CsvWriterFactory {
|
||||
constructor(private readonly csvStringifierFactory: CsvStringifierFactory) {}
|
||||
|
||||
createArrayCsvWriter(params: ArrayCsvWriterParams) {
|
||||
const csvStringifier = this.csvStringifierFactory.createArrayCsvStringifier({
|
||||
header: params.header,
|
||||
fieldDelimiter: params.fieldDelimiter,
|
||||
recordDelimiter: params.recordDelimiter,
|
||||
alwaysQuote: params.alwaysQuote
|
||||
});
|
||||
return new CsvWriter(csvStringifier, params.path, params.encoding, params.append);
|
||||
}
|
||||
|
||||
createObjectCsvWriter(params: ObjectCsvWriterParams) {
|
||||
const csvStringifier = this.csvStringifierFactory.createObjectCsvStringifier({
|
||||
header: params.header,
|
||||
fieldDelimiter: params.fieldDelimiter,
|
||||
recordDelimiter: params.recordDelimiter,
|
||||
headerIdDelimiter: params.headerIdDelimiter,
|
||||
alwaysQuote: params.alwaysQuote
|
||||
});
|
||||
return new CsvWriter(csvStringifier, params.path, params.encoding, params.append);
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
import {CsvStringifier} from './csv-stringifiers/abstract';
|
||||
import {FileWriter} from './file-writer';
|
||||
|
||||
const DEFAULT_INITIAL_APPEND_FLAG = false;
|
||||
|
||||
export class CsvWriter<T> {
|
||||
private readonly fileWriter: FileWriter;
|
||||
|
||||
constructor(private readonly csvStringifier: CsvStringifier<T>,
|
||||
path: string,
|
||||
encoding?: string,
|
||||
private append = DEFAULT_INITIAL_APPEND_FLAG) {
|
||||
this.fileWriter = new FileWriter(path, this.append, encoding);
|
||||
}
|
||||
|
||||
async writeRecords(records: T[]): Promise<void> {
|
||||
const recordsString = this.csvStringifier.stringifyRecords(records);
|
||||
const writeString = this.headerString + recordsString;
|
||||
await this.fileWriter.write(writeString);
|
||||
this.append = true;
|
||||
}
|
||||
|
||||
private get headerString(): string {
|
||||
const headerString = !this.append && this.csvStringifier.getHeaderString();
|
||||
return headerString || '';
|
||||
}
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
import {Field} from './record';
|
||||
|
||||
const DEFAULT_FIELD_DELIMITER = ',';
|
||||
const VALID_FIELD_DELIMITERS = [DEFAULT_FIELD_DELIMITER, ';'];
|
||||
|
||||
export abstract class FieldStringifier {
|
||||
constructor(public readonly fieldDelimiter: string) {}
|
||||
|
||||
abstract stringify(value?: Field): string;
|
||||
|
||||
protected isEmpty(value?: Field): boolean {
|
||||
return typeof value === 'undefined' || value === null || value === '';
|
||||
}
|
||||
|
||||
protected quoteField(field: string): string {
|
||||
return `"${field.replace(/"/g, '""')}"`;
|
||||
}
|
||||
}
|
||||
|
||||
class DefaultFieldStringifier extends FieldStringifier {
|
||||
stringify(value?: Field): string {
|
||||
if (this.isEmpty(value)) return '';
|
||||
const str = String(value);
|
||||
return this.needsQuote(str) ? this.quoteField(str) : str;
|
||||
}
|
||||
|
||||
private needsQuote(str: string): boolean {
|
||||
return str.includes(this.fieldDelimiter) || str.includes('\n') || str.includes('"');
|
||||
}
|
||||
}
|
||||
|
||||
class ForceQuoteFieldStringifier extends FieldStringifier {
|
||||
stringify(value?: Field): string {
|
||||
return this.isEmpty(value) ? '' : this.quoteField(String(value));
|
||||
}
|
||||
}
|
||||
|
||||
export function createFieldStringifier(fieldDelimiter: string = DEFAULT_FIELD_DELIMITER, alwaysQuote = false) {
|
||||
_validateFieldDelimiter(fieldDelimiter);
|
||||
return alwaysQuote ? new ForceQuoteFieldStringifier(fieldDelimiter) : new DefaultFieldStringifier(fieldDelimiter);
|
||||
}
|
||||
|
||||
function _validateFieldDelimiter(delimiter: string): void {
|
||||
if (VALID_FIELD_DELIMITERS.indexOf(delimiter) === -1) {
|
||||
throw new Error(`Invalid field delimiter \`${delimiter}\` is specified`);
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
import {promisify} from './lang/promise';
|
||||
import {writeFile} from 'fs';
|
||||
|
||||
const writeFilePromise = promisify(writeFile);
|
||||
|
||||
const DEFAULT_ENCODING = 'utf8';
|
||||
|
||||
export class FileWriter {
|
||||
|
||||
constructor(private readonly path: string,
|
||||
private append: boolean,
|
||||
private readonly encoding = DEFAULT_ENCODING) {
|
||||
}
|
||||
|
||||
async write(string: string): Promise<void> {
|
||||
await writeFilePromise(this.path, string, this.getWriteOption());
|
||||
this.append = true;
|
||||
}
|
||||
|
||||
private getWriteOption() {
|
||||
return {
|
||||
encoding: this.encoding,
|
||||
flag: this.append ? 'a' : 'w'
|
||||
};
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
export const isObject = (value: any) =>
|
||||
Object.prototype.toString.call(value) === '[object Object]';
|
||||
|
||||
export interface ObjectMap<T> {
|
||||
[k: string]: T;
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
|
||||
type NullableError = Error | null;
|
||||
|
||||
export function promisify(fn: (...args: any[]) => void): (...args: any[]) => any {
|
||||
return (...args: any[]) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const nodeCallback = (err: NullableError, result: any) => {
|
||||
if (err) reject(err);
|
||||
else resolve(result);
|
||||
};
|
||||
fn.apply(null, [...args, nodeCallback]);
|
||||
});
|
||||
};
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
|
||||
export type Field = any;
|
||||
|
||||
export type ObjectHeaderItem = { id: string; title: string };
|
||||
export type ObjectStringifierHeader = ObjectHeaderItem[] | string[];
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
import {resolveDelimiterChar} from '../helper/delimiter';
|
||||
import {createArrayCsvStringifier} from '../../index';
|
||||
import {strictEqual, throws} from 'assert';
|
||||
|
||||
describe('ArrayCsvStringifier', () => {
|
||||
const records = [
|
||||
['FIELD_A1', 'FIELD_B1'],
|
||||
['FIELD_A2', 'FIELD_B2']
|
||||
];
|
||||
|
||||
describe('When field delimiter is comma', generateTestCases());
|
||||
|
||||
describe('When field delimiter is semicolon', generateTestCases(';'));
|
||||
|
||||
describe('When field delimiter is neither comma nor semicolon', () => {
|
||||
it('throws an exception', () => {
|
||||
throws(() => {
|
||||
createArrayCsvStringifier({fieldDelimiter: '/'});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When record delimiter is neither LF nor CR+LF', () => {
|
||||
it('throws an exception', () => {
|
||||
throws(() => {
|
||||
createArrayCsvStringifier({recordDelimiter: '\r'});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When records input is an iterable other than an array', () => {
|
||||
const stringifier = createArrayCsvStringifier({
|
||||
header: ['TITLE_A', 'TITLE_B']
|
||||
});
|
||||
function * recordGenerator() {
|
||||
yield records[0];
|
||||
yield records[1];
|
||||
}
|
||||
|
||||
it('converts the records into CSV', () => {
|
||||
strictEqual(
|
||||
stringifier.stringifyRecords(recordGenerator()),
|
||||
'FIELD_A1,FIELD_B1\nFIELD_A2,FIELD_B2\n'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When `alwaysQuote` flag is set', () => {
|
||||
const stringifier = createArrayCsvStringifier({
|
||||
header: ['TITLE_A', 'TITLE_B'],
|
||||
alwaysQuote: true
|
||||
});
|
||||
|
||||
it('quotes all header fields', () => {
|
||||
strictEqual(stringifier.getHeaderString(), '"TITLE_A","TITLE_B"\n');
|
||||
});
|
||||
|
||||
it('quotes all data fields', () => {
|
||||
strictEqual(stringifier.stringifyRecords(records), '"FIELD_A1","FIELD_B1"\n"FIELD_A2","FIELD_B2"\n');
|
||||
});
|
||||
});
|
||||
|
||||
function generateTestCases(fieldDelimiter?: string) {
|
||||
const delim = resolveDelimiterChar(fieldDelimiter);
|
||||
return () => {
|
||||
describe('header is specified as a list of column titles', () => {
|
||||
const stringifier = createArrayCsvStringifier({
|
||||
header: ['TITLE_A', 'TITLE_B'],
|
||||
fieldDelimiter
|
||||
});
|
||||
|
||||
it(`returns a header line with field separated by "${delim}"`, () => {
|
||||
strictEqual(stringifier.getHeaderString(), `TITLE_A${delim}TITLE_B\n`);
|
||||
});
|
||||
|
||||
it(`converts given data records into CSV lines with field separated by "${delim}"`, () => {
|
||||
strictEqual(
|
||||
stringifier.stringifyRecords(records),
|
||||
`FIELD_A1${delim}FIELD_B1\nFIELD_A2${delim}FIELD_B2\n`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('header is not specified', () => {
|
||||
const stringifier = createArrayCsvStringifier({fieldDelimiter});
|
||||
|
||||
it('returns null for header line', () => {
|
||||
strictEqual(stringifier.getHeaderString(), null);
|
||||
});
|
||||
|
||||
it(`converts given data records into CSV lines with field separated by "${delim}"`, () => {
|
||||
strictEqual(
|
||||
stringifier.stringifyRecords(records),
|
||||
`FIELD_A1${delim}FIELD_B1\nFIELD_A2${delim}FIELD_B2\n`
|
||||
);
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
import {resolveDelimiterChar} from '../helper/delimiter';
|
||||
import {createObjectCsvStringifier} from '../../index';
|
||||
import {strictEqual, throws} from 'assert';
|
||||
|
||||
describe('ObjectCsvStringifier', () => {
|
||||
const records = [
|
||||
{FIELD_A: 'VALUE_A1', FIELD_B: 'VALUE_B1'},
|
||||
{FIELD_A: 'VALUE_A2', FIELD_B: 'VALUE_B2', OTHERS: {FIELD_C: 'VALUE_C2'}}
|
||||
];
|
||||
|
||||
describe('When field delimiter is comma', generateTestCases());
|
||||
|
||||
describe('When field delimiter is semicolon', generateTestCases(';'));
|
||||
|
||||
describe('When field delimiter is neither comma nor semicolon', () => {
|
||||
it('throws an exception', () => {
|
||||
throws(() => {
|
||||
createObjectCsvStringifier({
|
||||
header: ['FIELD_A', 'FIELD_B'],
|
||||
fieldDelimiter: '/'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When record delimiter is neither LF nor CR+LF', () => {
|
||||
it('throws an exception', () => {
|
||||
throws(() => {
|
||||
createObjectCsvStringifier({
|
||||
header: ['FIELD_A', 'FIELD_B'],
|
||||
recordDelimiter: '\r'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('When records input is an iterable other than an array', () => {
|
||||
const stringifier = createObjectCsvStringifier({
|
||||
header: ['FIELD_A', 'FIELD_B']
|
||||
});
|
||||
function * recordGenerator() {
|
||||
yield records[0];
|
||||
yield records[1];
|
||||
}
|
||||
|
||||
it('converts the records into CSV', () => {
|
||||
strictEqual(
|
||||
stringifier.stringifyRecords(recordGenerator()),
|
||||
'VALUE_A1,VALUE_B1\nVALUE_A2,VALUE_B2\n'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When `alwaysQuote` flag is set', () => {
|
||||
const stringifier = createObjectCsvStringifier({
|
||||
header: [
|
||||
{id: 'FIELD_A', title: 'TITLE_A'},
|
||||
{id: 'FIELD_B', title: 'TITLE_B'}
|
||||
],
|
||||
alwaysQuote: true
|
||||
});
|
||||
|
||||
it('quotes all header fields', () => {
|
||||
strictEqual(stringifier.getHeaderString(), '"TITLE_A","TITLE_B"\n');
|
||||
});
|
||||
|
||||
it('quotes all data fields', () => {
|
||||
strictEqual(stringifier.stringifyRecords(records), '"VALUE_A1","VALUE_B1"\n"VALUE_A2","VALUE_B2"\n');
|
||||
});
|
||||
});
|
||||
|
||||
describe('When `headerIdDelimiter` is set', () => {
|
||||
const stringifier = createObjectCsvStringifier({
|
||||
header: [
|
||||
{id: 'FIELD_A', title: 'TITLE_A'},
|
||||
{id: 'OTHERS/FIELD_C', title: 'TITLE_C'}
|
||||
],
|
||||
headerIdDelimiter: '/'
|
||||
});
|
||||
|
||||
it('uses the title as is', () => {
|
||||
strictEqual(stringifier.getHeaderString(), 'TITLE_A,TITLE_C\n');
|
||||
});
|
||||
|
||||
it('picks up a value in nested objects', () => {
|
||||
strictEqual(stringifier.stringifyRecords(records), 'VALUE_A1,\nVALUE_A2,VALUE_C2\n');
|
||||
});
|
||||
});
|
||||
|
||||
function generateTestCases(fieldDelimiter?: string) {
|
||||
const delim = resolveDelimiterChar(fieldDelimiter);
|
||||
return () => {
|
||||
describe('header is specified with title', () => {
|
||||
const stringifier = createObjectCsvStringifier({
|
||||
header: [
|
||||
{id: 'FIELD_A', title: 'TITLE_A'},
|
||||
{id: 'FIELD_B', title: 'TITLE_B'}
|
||||
],
|
||||
fieldDelimiter
|
||||
});
|
||||
|
||||
it(`returns a header line with field separated by "${delim}"`, () => {
|
||||
strictEqual(stringifier.getHeaderString(), `TITLE_A${delim}TITLE_B\n`);
|
||||
});
|
||||
|
||||
it(`converts given data records into CSV lines with field separated by "${delim}"`, () => {
|
||||
strictEqual(
|
||||
stringifier.stringifyRecords(records),
|
||||
`VALUE_A1${delim}VALUE_B1\nVALUE_A2${delim}VALUE_B2\n`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('header is specified without title', () => {
|
||||
const stringifier = createObjectCsvStringifier({
|
||||
header: ['FIELD_A', 'FIELD_B'],
|
||||
fieldDelimiter
|
||||
});
|
||||
|
||||
it('returns null for header line', () => {
|
||||
strictEqual(stringifier.getHeaderString(), null);
|
||||
});
|
||||
|
||||
it(`converts given data records into CSV lines with field separated by "${delim}"`, () => {
|
||||
strictEqual(
|
||||
stringifier.stringifyRecords(records),
|
||||
`VALUE_A1${delim}VALUE_B1\nVALUE_A2${delim}VALUE_B2\n`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('header columns are given with reverse order', () => {
|
||||
const stringifier = createObjectCsvStringifier({
|
||||
header: [
|
||||
{id: 'FIELD_B', title: 'TITLE_B'},
|
||||
{id: 'FIELD_A', title: 'TITLE_A'}
|
||||
],
|
||||
fieldDelimiter
|
||||
});
|
||||
|
||||
it(`layouts fields with the order of headers given with field separated by "${delim}"`, () => {
|
||||
strictEqual(
|
||||
stringifier.stringifyRecords(records),
|
||||
`VALUE_B1${delim}VALUE_A1\nVALUE_B2${delim}VALUE_A2\n`
|
||||
);
|
||||
});
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
import {resolveDelimiterChar} from './helper/delimiter';
|
||||
import {createFieldStringifier} from '../lib/field-stringifier';
|
||||
import {strictEqual} from 'assert';
|
||||
|
||||
describe('DefaultFieldStringifier', () => {
|
||||
|
||||
describe('When field delimiter is comma', generateTestCases(','));
|
||||
|
||||
describe('When field delimiter is semicolon', generateTestCases(';'));
|
||||
|
||||
describe('When all fields needs to be quoted', () => {
|
||||
const stringifier = createFieldStringifier(',', true);
|
||||
|
||||
it('quotes a field', () => {
|
||||
strictEqual(stringifier.stringify('VALUE'), '"VALUE"');
|
||||
});
|
||||
|
||||
it('does not quote a field of value undefined', () => {
|
||||
strictEqual(stringifier.stringify(), '');
|
||||
});
|
||||
|
||||
it('does not quote a field of value null', () => {
|
||||
strictEqual(stringifier.stringify(null), '');
|
||||
});
|
||||
|
||||
it('does not quote a field of value empty string', () => {
|
||||
strictEqual(stringifier.stringify(''), '');
|
||||
});
|
||||
});
|
||||
|
||||
function generateTestCases(fieldDelimiter: string) {
|
||||
const delim = resolveDelimiterChar(fieldDelimiter);
|
||||
return () => {
|
||||
const stringifier = createFieldStringifier(fieldDelimiter);
|
||||
|
||||
it('returns the same string', () => {
|
||||
strictEqual(stringifier.stringify('VALUE'), 'VALUE');
|
||||
});
|
||||
|
||||
it('preserves the whitespace characters', () => {
|
||||
strictEqual(stringifier.stringify(' VALUE\tA '), ' VALUE\tA ');
|
||||
});
|
||||
|
||||
it(`wraps a field value with double quotes if the field contains "${delim}"`, () => {
|
||||
strictEqual(stringifier.stringify(`VALUE${delim}A`), `"VALUE${delim}A"`);
|
||||
});
|
||||
|
||||
it('wraps a field value with double quotes if the field contains newline', () => {
|
||||
strictEqual(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', () => {
|
||||
strictEqual(stringifier.stringify('VALUE"A'), '"VALUE""A"');
|
||||
});
|
||||
|
||||
it('escapes double quotes even if double quotes are only on the both edges of the field', () => {
|
||||
strictEqual(stringifier.stringify('"VALUE"'), '"""VALUE"""');
|
||||
});
|
||||
|
||||
it('converts a number into a string', () => {
|
||||
strictEqual(stringifier.stringify(1), '1');
|
||||
});
|
||||
|
||||
it('converts undefined into an empty string', () => {
|
||||
strictEqual(stringifier.stringify(), '');
|
||||
});
|
||||
|
||||
it('converts null into an empty string', () => {
|
||||
strictEqual(stringifier.stringify(null), '');
|
||||
});
|
||||
|
||||
it('converts an object into toString-ed value', () => {
|
||||
const obj = {
|
||||
name: 'OBJECT_NAME',
|
||||
toString: function () { return `Name: ${this.name}`; }
|
||||
};
|
||||
strictEqual(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}`; }
|
||||
};
|
||||
strictEqual(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 = {
|
||||
name: 'OBJECT_NAME"',
|
||||
toString: function () { return `Name: ${this.name}`; }
|
||||
};
|
||||
strictEqual(stringifier.stringify(obj), '"Name: OBJECT_NAME"""');
|
||||
});
|
||||
};
|
||||
}
|
||||
});
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import {strictEqual} from 'assert';
|
||||
import {readFileSync} from 'fs';
|
||||
|
||||
export const testFilePath = (id: string) => `./test-tmp/${id}.csv`;
|
||||
|
||||
export const assertFile = (path: string, expectedContents: string, encoding?: string) => {
|
||||
const actualContents = readFileSync(path, encoding || 'utf8');
|
||||
strictEqual(actualContents, expectedContents);
|
||||
};
|
||||
|
||||
export const assertRejected = (p: Promise<any>, message: string) => {
|
||||
return p.then(
|
||||
() => new Error('Should not have been called'),
|
||||
(e: Error) => { strictEqual(e.message, message); }
|
||||
);
|
||||
};
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
|
||||
export const resolveDelimiterChar = (char?: string) => {
|
||||
if (char === ',' || char === ';') return char;
|
||||
if (typeof char === 'undefined') return ',';
|
||||
throw new Error('Invalid field delimiter');
|
||||
};
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
import {promisify} from '../../lib/lang/promise';
|
||||
import {strictEqual} from 'assert';
|
||||
import {assertRejected} from '../helper';
|
||||
|
||||
describe('Promise', () => {
|
||||
const greetAsync = (name: string, callback: (err: Error | null, result?: string) => void) => {
|
||||
setTimeout(() => {
|
||||
if (name === 'foo') callback(null, `Hello, ${name}!`);
|
||||
else callback(new Error(`We don't know ${name}`));
|
||||
}, 0);
|
||||
};
|
||||
const promisifiedFn = promisify(greetAsync);
|
||||
|
||||
it('promisify node style callback', async () => {
|
||||
strictEqual(await promisifiedFn('foo'), 'Hello, foo!');
|
||||
});
|
||||
|
||||
it('raise an error for error', async () => {
|
||||
await assertRejected(promisifiedFn('bar'), "We don't know bar");
|
||||
});
|
||||
});
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
import {assertFile, testFilePath} from './helper';
|
||||
import {CsvWriter} from '../lib/csv-writer';
|
||||
import {writeFileSync} from 'fs';
|
||||
import {createArrayCsvWriter} from '../index';
|
||||
|
||||
describe('Write array records into CSV', () => {
|
||||
|
||||
const makeFilePath = (id: string) => testFilePath(`array-${id}`);
|
||||
const records = [
|
||||
['Bob', 'French'],
|
||||
['Mary', 'English']
|
||||
];
|
||||
|
||||
describe('When only path is specified', () => {
|
||||
const filePath = makeFilePath('minimum');
|
||||
let writer: CsvWriter<string[]>;
|
||||
|
||||
beforeEach(() => {
|
||||
writer = createArrayCsvWriter({path: filePath});
|
||||
});
|
||||
|
||||
it('writes records to a new file', async () => {
|
||||
await writer.writeRecords(records);
|
||||
assertFile(filePath, 'Bob,French\nMary,English\n');
|
||||
});
|
||||
|
||||
it('appends records when requested to write to the same file', async () => {
|
||||
await writer.writeRecords([records[0]]);
|
||||
await writer.writeRecords([records[1]]);
|
||||
assertFile(filePath, 'Bob,French\nMary,English\n');
|
||||
});
|
||||
});
|
||||
|
||||
describe('When field header is given', () => {
|
||||
const filePath = makeFilePath('header');
|
||||
let writer: CsvWriter<string[]>;
|
||||
|
||||
beforeEach(() => {
|
||||
writer = createArrayCsvWriter({
|
||||
path: filePath,
|
||||
header: ['NAME', 'LANGUAGE']
|
||||
});
|
||||
});
|
||||
|
||||
it('writes a header', async () => {
|
||||
await writer.writeRecords(records);
|
||||
assertFile(filePath, 'NAME,LANGUAGE\nBob,French\nMary,English\n');
|
||||
});
|
||||
|
||||
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');
|
||||
});
|
||||
});
|
||||
|
||||
describe('When `append` flag is specified', () => {
|
||||
const filePath = makeFilePath('append');
|
||||
writeFileSync(filePath, 'Mike,German\n', 'utf8');
|
||||
const writer = createArrayCsvWriter({
|
||||
path: filePath,
|
||||
append: true
|
||||
});
|
||||
|
||||
it('do not overwrite the existing contents and appends records to them', async () => {
|
||||
await writer.writeRecords([records[1]]);
|
||||
assertFile(filePath, 'Mike,German\nMary,English\n');
|
||||
});
|
||||
});
|
||||
|
||||
describe('When encoding is specified', () => {
|
||||
const filePath = makeFilePath('encoding');
|
||||
const writer = createArrayCsvWriter({
|
||||
path: filePath,
|
||||
encoding: 'utf16le'
|
||||
});
|
||||
|
||||
it('writes to a file with the specified encoding', async () => {
|
||||
await writer.writeRecords(records);
|
||||
assertFile(filePath, 'Bob,French\nMary,English\n', 'utf16le');
|
||||
});
|
||||
});
|
||||
|
||||
describe('When semicolon is specified as a field delimiter', () => {
|
||||
const filePath = makeFilePath('field-delimiter');
|
||||
const writer = createArrayCsvWriter({
|
||||
path: filePath,
|
||||
header: ['NAME', 'LANGUAGE'],
|
||||
fieldDelimiter: ';'
|
||||
});
|
||||
|
||||
it('uses semicolon instead of comma to separate fields', async () => {
|
||||
await writer.writeRecords(records);
|
||||
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', async () => {
|
||||
await writer.writeRecords(records);
|
||||
assertFile(filePath, 'Bob,French\r\nMary,English\r\n');
|
||||
});
|
||||
});
|
||||
|
||||
describe('When `alwaysQuote` flag is set', () => {
|
||||
const filePath = makeFilePath('always-quote');
|
||||
const writer = createArrayCsvWriter({
|
||||
path: filePath,
|
||||
header: ['NAME', 'LANGUAGE'],
|
||||
alwaysQuote: true
|
||||
});
|
||||
|
||||
it('quotes all fields', async () => {
|
||||
await writer.writeRecords(records);
|
||||
assertFile(filePath, '"NAME","LANGUAGE"\n"Bob","French"\n"Mary","English"\n');
|
||||
});
|
||||
});
|
||||
});
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
import {assertFile, testFilePath} from './helper';
|
||||
import {CsvWriter} from '../lib/csv-writer';
|
||||
import {writeFileSync} from 'fs';
|
||||
import {createObjectCsvWriter} from '../index';
|
||||
import {ObjectMap} from '../lib/lang/object';
|
||||
|
||||
describe('Write object records into CSV', () => {
|
||||
|
||||
const makeFilePath = (id: string) => testFilePath(`object-${id}`);
|
||||
const records = [
|
||||
{name: 'Bob', lang: 'French', address: {country: 'France'}},
|
||||
{name: 'Mary', lang: 'English'}
|
||||
];
|
||||
|
||||
describe('When only path and header ids are given', () => {
|
||||
const filePath = makeFilePath('minimum');
|
||||
let writer: CsvWriter<ObjectMap<any>>;
|
||||
|
||||
beforeEach(() => {
|
||||
writer = createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: ['name', 'lang']
|
||||
});
|
||||
});
|
||||
|
||||
it('writes records to a new file', async () => {
|
||||
await writer.writeRecords(records);
|
||||
assertFile(filePath, 'Bob,French\nMary,English\n');
|
||||
});
|
||||
|
||||
it('appends records when requested to write to the same file', async () => {
|
||||
await writer.writeRecords([records[0]]);
|
||||
await writer.writeRecords([records[1]]);
|
||||
assertFile(filePath, 'Bob,French\nMary,English\n');
|
||||
});
|
||||
});
|
||||
|
||||
describe('When header ids are given with reverse order', () => {
|
||||
const filePath = makeFilePath('column-order');
|
||||
const writer = createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: ['lang', 'name']
|
||||
});
|
||||
|
||||
it('also writes columns with reverse order', async () => {
|
||||
await writer.writeRecords(records);
|
||||
assertFile(filePath, 'French,Bob\nEnglish,Mary\n');
|
||||
});
|
||||
});
|
||||
|
||||
describe('When field header is given with titles', () => {
|
||||
const filePath = makeFilePath('header');
|
||||
let writer: CsvWriter<ObjectMap<any>>;
|
||||
|
||||
beforeEach(() => {
|
||||
writer = createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: [{id: 'name', title: 'NAME'}, {id: 'lang', title: 'LANGUAGE'}]
|
||||
});
|
||||
});
|
||||
|
||||
it('writes a header', async () => {
|
||||
await writer.writeRecords(records);
|
||||
assertFile(filePath, 'NAME,LANGUAGE\nBob,French\nMary,English\n');
|
||||
});
|
||||
|
||||
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');
|
||||
});
|
||||
});
|
||||
|
||||
describe('When `append` flag is specified', () => {
|
||||
const filePath = makeFilePath('append');
|
||||
writeFileSync(filePath, 'Mike,German\n', 'utf8');
|
||||
const writer = createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: ['name', 'lang'],
|
||||
append: true
|
||||
});
|
||||
|
||||
it('do not overwrite the existing contents and appends records to them', async () => {
|
||||
await writer.writeRecords([records[1]]);
|
||||
assertFile(filePath, 'Mike,German\nMary,English\n');
|
||||
});
|
||||
});
|
||||
|
||||
describe('When encoding is specified', () => {
|
||||
const filePath = makeFilePath('encoding');
|
||||
const writer = createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: ['name', 'lang'],
|
||||
encoding: 'utf16le'
|
||||
});
|
||||
|
||||
it('writes to a file with the specified encoding', async () => {
|
||||
await writer.writeRecords(records);
|
||||
assertFile(filePath, 'Bob,French\nMary,English\n', 'utf16le');
|
||||
});
|
||||
});
|
||||
|
||||
describe('When semicolon is specified as a field delimiter', () => {
|
||||
const filePath = makeFilePath('field-delimiter');
|
||||
const writer = createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: [{id: 'name', title: 'NAME'}, {id: 'lang', title: 'LANGUAGE'}],
|
||||
fieldDelimiter: ';'
|
||||
});
|
||||
|
||||
it('uses semicolon instead of comma to separate fields', async () => {
|
||||
await writer.writeRecords(records);
|
||||
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', async () => {
|
||||
await writer.writeRecords(records);
|
||||
assertFile(filePath, 'Bob,French\r\nMary,English\r\n');
|
||||
});
|
||||
});
|
||||
|
||||
describe('When `alwaysQuote` flag is set', () => {
|
||||
const filePath = makeFilePath('always-quote');
|
||||
const writer = createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: [{id: 'name', title: 'NAME'}, {id: 'lang', title: 'LANGUAGE'}],
|
||||
alwaysQuote: true
|
||||
});
|
||||
|
||||
it('quotes all fields', async () => {
|
||||
await writer.writeRecords(records);
|
||||
assertFile(filePath, '"NAME","LANGUAGE"\n"Bob","French"\n"Mary","English"\n');
|
||||
});
|
||||
});
|
||||
|
||||
describe('When `headerIdDelimiter` flag is set', () => {
|
||||
const filePath = makeFilePath('nested');
|
||||
const writer = createObjectCsvWriter({
|
||||
path: filePath,
|
||||
header: [{id: 'name', title: 'NAME'}, {id: 'address.country', title: 'COUNTRY'}],
|
||||
headerIdDelimiter: '.'
|
||||
});
|
||||
|
||||
it('breaks keys into key paths', async () => {
|
||||
await writer.writeRecords(records);
|
||||
assertFile(filePath, 'NAME,COUNTRY\nBob,France\nMary,\n');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user