UNPKG

@jsreport/exceljs

Version:

Excel Workbook Manager - Read and Write xlsx and csv Files.

1,552 lines (1,508 loc) 2.01 MB
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.ExcelJS = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ (function (Buffer){(function (){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CsvFormatterStream = void 0; const stream_1 = require("stream"); const formatter_1 = require("./formatter"); class CsvFormatterStream extends stream_1.Transform { constructor(formatterOptions) { super({ writableObjectMode: formatterOptions.objectMode }); this.hasWrittenBOM = false; this.formatterOptions = formatterOptions; this.rowFormatter = new formatter_1.RowFormatter(formatterOptions); // if writeBOM is false then set to true // if writeBOM is true then set to false by default so it is written out this.hasWrittenBOM = !formatterOptions.writeBOM; } transform(transformFunction) { this.rowFormatter.rowTransform = transformFunction; return this; } _transform(row, encoding, cb) { let cbCalled = false; try { if (!this.hasWrittenBOM) { this.push(this.formatterOptions.BOM); this.hasWrittenBOM = true; } this.rowFormatter.format(row, (err, rows) => { if (err) { cbCalled = true; return cb(err); } if (rows) { rows.forEach(r => { this.push(Buffer.from(r, 'utf8')); }); } cbCalled = true; return cb(); }); } catch (e) { if (cbCalled) { throw e; } cb(e); } } _flush(cb) { this.rowFormatter.finish((err, rows) => { if (err) { return cb(err); } if (rows) { rows.forEach(r => { this.push(Buffer.from(r, 'utf8')); }); } return cb(); }); } } exports.CsvFormatterStream = CsvFormatterStream; }).call(this)}).call(this,require("buffer").Buffer) },{"./formatter":5,"buffer":85,"stream":237}],2:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FormatterOptions = void 0; class FormatterOptions { constructor() { let opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var _a; this.objectMode = true; this.delimiter = ','; this.rowDelimiter = '\n'; this.quote = '"'; this.escape = this.quote; this.quoteColumns = false; this.quoteHeaders = this.quoteColumns; this.headers = null; this.includeEndRowDelimiter = false; this.writeBOM = false; this.BOM = '\ufeff'; this.alwaysWriteHeaders = false; Object.assign(this, opts || {}); if (typeof (opts === null || opts === void 0 ? void 0 : opts.quoteHeaders) === 'undefined') { this.quoteHeaders = this.quoteColumns; } if ((opts === null || opts === void 0 ? void 0 : opts.quote) === true) { this.quote = '"'; } else if ((opts === null || opts === void 0 ? void 0 : opts.quote) === false) { this.quote = ''; } if (typeof (opts === null || opts === void 0 ? void 0 : opts.escape) !== 'string') { this.escape = this.quote; } this.shouldWriteHeaders = !!this.headers && ((_a = opts.writeHeaders) !== null && _a !== void 0 ? _a : true); this.headers = Array.isArray(this.headers) ? this.headers : null; this.escapedQuote = "".concat(this.escape).concat(this.quote); } } exports.FormatterOptions = FormatterOptions; },{}],3:[function(require,module,exports){ "use strict"; var __importDefault = void 0 && (void 0).__importDefault || function (mod) { return mod && mod.__esModule ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.FieldFormatter = void 0; const lodash_isboolean_1 = __importDefault(require("lodash.isboolean")); const lodash_isnil_1 = __importDefault(require("lodash.isnil")); const lodash_escaperegexp_1 = __importDefault(require("lodash.escaperegexp")); class FieldFormatter { constructor(formatterOptions) { this._headers = null; this.formatterOptions = formatterOptions; if (formatterOptions.headers !== null) { this.headers = formatterOptions.headers; } this.REPLACE_REGEXP = new RegExp(formatterOptions.quote, 'g'); const escapePattern = "[".concat(formatterOptions.delimiter).concat(lodash_escaperegexp_1.default(formatterOptions.rowDelimiter), "|\r|\n]"); this.ESCAPE_REGEXP = new RegExp(escapePattern); } set headers(headers) { this._headers = headers; } shouldQuote(fieldIndex, isHeader) { const quoteConfig = isHeader ? this.formatterOptions.quoteHeaders : this.formatterOptions.quoteColumns; if (lodash_isboolean_1.default(quoteConfig)) { return quoteConfig; } if (Array.isArray(quoteConfig)) { return quoteConfig[fieldIndex]; } if (this._headers !== null) { return quoteConfig[this._headers[fieldIndex]]; } return false; } format(field, fieldIndex, isHeader) { const preparedField = "".concat(lodash_isnil_1.default(field) ? '' : field).replace(/\0/g, ''); const { formatterOptions } = this; if (formatterOptions.quote !== '') { const shouldEscape = preparedField.indexOf(formatterOptions.quote) !== -1; if (shouldEscape) { return this.quoteField(preparedField.replace(this.REPLACE_REGEXP, formatterOptions.escapedQuote)); } } const hasEscapeCharacters = preparedField.search(this.ESCAPE_REGEXP) !== -1; if (hasEscapeCharacters || this.shouldQuote(fieldIndex, isHeader)) { return this.quoteField(preparedField); } return preparedField; } quoteField(field) { const { quote } = this.formatterOptions; return "".concat(quote).concat(field).concat(quote); } } exports.FieldFormatter = FieldFormatter; },{"lodash.escaperegexp":144,"lodash.isboolean":146,"lodash.isnil":149}],4:[function(require,module,exports){ "use strict"; var __importDefault = void 0 && (void 0).__importDefault || function (mod) { return mod && mod.__esModule ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RowFormatter = void 0; const lodash_isfunction_1 = __importDefault(require("lodash.isfunction")); const lodash_isequal_1 = __importDefault(require("lodash.isequal")); const FieldFormatter_1 = require("./FieldFormatter"); const types_1 = require("../types"); class RowFormatter { constructor(formatterOptions) { this.rowCount = 0; this.formatterOptions = formatterOptions; this.fieldFormatter = new FieldFormatter_1.FieldFormatter(formatterOptions); this.headers = formatterOptions.headers; this.shouldWriteHeaders = formatterOptions.shouldWriteHeaders; this.hasWrittenHeaders = false; if (this.headers !== null) { this.fieldFormatter.headers = this.headers; } if (formatterOptions.transform) { this.rowTransform = formatterOptions.transform; } } static isRowHashArray(row) { if (Array.isArray(row)) { return Array.isArray(row[0]) && row[0].length === 2; } return false; } static isRowArray(row) { return Array.isArray(row) && !this.isRowHashArray(row); } // get headers from a row item static gatherHeaders(row) { if (RowFormatter.isRowHashArray(row)) { // lets assume a multi-dimesional array with item 0 being the header return row.map(it => it[0]); } if (Array.isArray(row)) { return row; } return Object.keys(row); } // eslint-disable-next-line @typescript-eslint/no-shadow static createTransform(transformFunction) { if (types_1.isSyncTransform(transformFunction)) { return (row, cb) => { let transformedRow = null; try { transformedRow = transformFunction(row); } catch (e) { return cb(e); } return cb(null, transformedRow); }; } return (row, cb) => { transformFunction(row, cb); }; } set rowTransform(transformFunction) { if (!lodash_isfunction_1.default(transformFunction)) { throw new TypeError('The transform should be a function'); } this._rowTransform = RowFormatter.createTransform(transformFunction); } format(row, cb) { this.callTransformer(row, (err, transformedRow) => { if (err) { return cb(err); } if (!row) { return cb(null); } const rows = []; if (transformedRow) { const { shouldFormatColumns, headers } = this.checkHeaders(transformedRow); if (this.shouldWriteHeaders && headers && !this.hasWrittenHeaders) { rows.push(this.formatColumns(headers, true)); this.hasWrittenHeaders = true; } if (shouldFormatColumns) { const columns = this.gatherColumns(transformedRow); rows.push(this.formatColumns(columns, false)); } } return cb(null, rows); }); } finish(cb) { const rows = []; // check if we should write headers and we didnt get any rows if (this.formatterOptions.alwaysWriteHeaders && this.rowCount === 0) { if (!this.headers) { return cb(new Error('`alwaysWriteHeaders` option is set to true but `headers` option not provided.')); } rows.push(this.formatColumns(this.headers, true)); } if (this.formatterOptions.includeEndRowDelimiter) { rows.push(this.formatterOptions.rowDelimiter); } return cb(null, rows); } // check if we need to write header return true if we should also write a row // could be false if headers is true and the header row(first item) is passed in checkHeaders(row) { if (this.headers) { // either the headers were provided by the user or we have already gathered them. return { shouldFormatColumns: true, headers: this.headers }; } const headers = RowFormatter.gatherHeaders(row); this.headers = headers; this.fieldFormatter.headers = headers; if (!this.shouldWriteHeaders) { // if we are not supposed to write the headers then // always format the columns return { shouldFormatColumns: true, headers: null }; } // if the row is equal to headers dont format return { shouldFormatColumns: !lodash_isequal_1.default(headers, row), headers }; } // todo change this method to unknown[] gatherColumns(row) { if (this.headers === null) { throw new Error('Headers is currently null'); } if (!Array.isArray(row)) { return this.headers.map(header => row[header]); } if (RowFormatter.isRowHashArray(row)) { return this.headers.map((header, i) => { const col = row[i]; if (col) { return col[1]; } return ''; }); } // if its a one dimensional array and headers were not provided // then just return the row if (RowFormatter.isRowArray(row) && !this.shouldWriteHeaders) { return row; } return this.headers.map((header, i) => row[i]); } callTransformer(row, cb) { if (!this._rowTransform) { return cb(null, row); } return this._rowTransform(row, cb); } formatColumns(columns, isHeadersRow) { const formattedCols = columns.map((field, i) => this.fieldFormatter.format(field, i, isHeadersRow)).join(this.formatterOptions.delimiter); const { rowCount } = this; this.rowCount += 1; if (rowCount) { return [this.formatterOptions.rowDelimiter, formattedCols].join(''); } return formattedCols; } } exports.RowFormatter = RowFormatter; },{"../types":7,"./FieldFormatter":3,"lodash.isequal":147,"lodash.isfunction":148}],5:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FieldFormatter = exports.RowFormatter = void 0; var RowFormatter_1 = require("./RowFormatter"); Object.defineProperty(exports, "RowFormatter", { enumerable: true, get: function () { return RowFormatter_1.RowFormatter; } }); var FieldFormatter_1 = require("./FieldFormatter"); Object.defineProperty(exports, "FieldFormatter", { enumerable: true, get: function () { return FieldFormatter_1.FieldFormatter; } }); },{"./FieldFormatter":3,"./RowFormatter":4}],6:[function(require,module,exports){ (function (Buffer){(function (){ "use strict"; var __createBinding = void 0 && (void 0).__createBinding || (Object.create ? function (o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } }); } : function (o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = void 0 && (void 0).__setModuleDefault || (Object.create ? function (o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function (o, v) { o["default"] = v; }); var __importStar = void 0 && (void 0).__importStar || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __exportStar = void 0 && (void 0).__exportStar || function (m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.writeToPath = exports.writeToString = exports.writeToBuffer = exports.writeToStream = exports.write = exports.format = exports.FormatterOptions = exports.CsvFormatterStream = void 0; const util_1 = require("util"); const stream_1 = require("stream"); const fs = __importStar(require("fs")); const FormatterOptions_1 = require("./FormatterOptions"); const CsvFormatterStream_1 = require("./CsvFormatterStream"); __exportStar(require("./types"), exports); var CsvFormatterStream_2 = require("./CsvFormatterStream"); Object.defineProperty(exports, "CsvFormatterStream", { enumerable: true, get: function () { return CsvFormatterStream_2.CsvFormatterStream; } }); var FormatterOptions_2 = require("./FormatterOptions"); Object.defineProperty(exports, "FormatterOptions", { enumerable: true, get: function () { return FormatterOptions_2.FormatterOptions; } }); exports.format = options => new CsvFormatterStream_1.CsvFormatterStream(new FormatterOptions_1.FormatterOptions(options)); exports.write = (rows, options) => { const csvStream = exports.format(options); const promiseWrite = util_1.promisify((row, cb) => { csvStream.write(row, undefined, cb); }); rows.reduce((prev, row) => prev.then(() => promiseWrite(row)), Promise.resolve()).then(() => csvStream.end()).catch(err => { csvStream.emit('error', err); }); return csvStream; }; exports.writeToStream = (ws, rows, options) => exports.write(rows, options).pipe(ws); exports.writeToBuffer = function (rows) { let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; const buffers = []; const ws = new stream_1.Writable({ write(data, enc, writeCb) { buffers.push(data); writeCb(); } }); return new Promise((res, rej) => { ws.on('error', rej).on('finish', () => res(Buffer.concat(buffers))); exports.write(rows, opts).pipe(ws); }); }; exports.writeToString = (rows, options) => exports.writeToBuffer(rows, options).then(buffer => buffer.toString()); exports.writeToPath = (path, rows, options) => { const stream = fs.createWriteStream(path, { encoding: 'utf8' }); return exports.write(rows, options).pipe(stream); }; }).call(this)}).call(this,require("buffer").Buffer) },{"./CsvFormatterStream":1,"./FormatterOptions":2,"./types":7,"buffer":85,"fs":84,"stream":237,"util":242}],7:[function(require,module,exports){ "use strict"; /* eslint-disable @typescript-eslint/no-explicit-any */ Object.defineProperty(exports, "__esModule", { value: true }); exports.isSyncTransform = void 0; exports.isSyncTransform = transform => transform.length === 1; },{}],8:[function(require,module,exports){ (function (setImmediate){(function (){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CsvParserStream = void 0; const string_decoder_1 = require("string_decoder"); const stream_1 = require("stream"); const transforms_1 = require("./transforms"); const parser_1 = require("./parser"); class CsvParserStream extends stream_1.Transform { constructor(parserOptions) { super({ objectMode: parserOptions.objectMode }); this.lines = ''; this.rowCount = 0; this.parsedRowCount = 0; this.parsedLineCount = 0; this.endEmitted = false; this.headersEmitted = false; this.parserOptions = parserOptions; this.parser = new parser_1.Parser(parserOptions); this.headerTransformer = new transforms_1.HeaderTransformer(parserOptions); this.decoder = new string_decoder_1.StringDecoder(parserOptions.encoding); this.rowTransformerValidator = new transforms_1.RowTransformerValidator(); } get hasHitRowLimit() { return this.parserOptions.limitRows && this.rowCount >= this.parserOptions.maxRows; } get shouldEmitRows() { return this.parsedRowCount > this.parserOptions.skipRows; } get shouldSkipLine() { return this.parsedLineCount <= this.parserOptions.skipLines; } transform(transformFunction) { this.rowTransformerValidator.rowTransform = transformFunction; return this; } validate(validateFunction) { this.rowTransformerValidator.rowValidator = validateFunction; return this; } // eslint-disable-next-line @typescript-eslint/no-explicit-any emit(event) { if (event === 'end') { if (!this.endEmitted) { this.endEmitted = true; super.emit('end', this.rowCount); } return false; } for (var _len = arguments.length, rest = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { rest[_key - 1] = arguments[_key]; } return super.emit(event, ...rest); } _transform(data, encoding, done) { // if we have hit our maxRows parsing limit then skip parsing if (this.hasHitRowLimit) { return done(); } const wrappedCallback = CsvParserStream.wrapDoneCallback(done); try { const { lines } = this; const newLine = lines + this.decoder.write(data); const rows = this.parse(newLine, true); return this.processRows(rows, wrappedCallback); } catch (e) { return wrappedCallback(e); } } _flush(done) { const wrappedCallback = CsvParserStream.wrapDoneCallback(done); // if we have hit our maxRows parsing limit then skip parsing if (this.hasHitRowLimit) { return wrappedCallback(); } try { const newLine = this.lines + this.decoder.end(); const rows = this.parse(newLine, false); return this.processRows(rows, wrappedCallback); } catch (e) { return wrappedCallback(e); } } parse(data, hasMoreData) { if (!data) { return []; } const { line, rows } = this.parser.parse(data, hasMoreData); this.lines = line; return rows; } processRows(rows, cb) { const rowsLength = rows.length; const iterate = i => { const callNext = err => { if (err) { return cb(err); } if (i % 100 === 0) { // incase the transform are sync insert a next tick to prevent stack overflow setImmediate(() => iterate(i + 1)); return undefined; } return iterate(i + 1); }; this.checkAndEmitHeaders(); // if we have emitted all rows or we have hit the maxRows limit option // then end if (i >= rowsLength || this.hasHitRowLimit) { return cb(); } this.parsedLineCount += 1; if (this.shouldSkipLine) { return callNext(); } const row = rows[i]; this.rowCount += 1; this.parsedRowCount += 1; const nextRowCount = this.rowCount; return this.transformRow(row, (err, transformResult) => { if (err) { this.rowCount -= 1; return callNext(err); } if (!transformResult) { return callNext(new Error('expected transform result')); } if (!transformResult.isValid) { this.emit('data-invalid', transformResult.row, nextRowCount, transformResult.reason); } else if (transformResult.row) { return this.pushRow(transformResult.row, callNext); } return callNext(); }); }; iterate(0); } transformRow(parsedRow, cb) { try { this.headerTransformer.transform(parsedRow, (err, withHeaders) => { if (err) { return cb(err); } if (!withHeaders) { return cb(new Error('Expected result from header transform')); } if (!withHeaders.isValid) { if (this.shouldEmitRows) { return cb(null, { isValid: false, row: parsedRow }); } // skipped because of skipRows option remove from total row count return this.skipRow(cb); } if (withHeaders.row) { if (this.shouldEmitRows) { return this.rowTransformerValidator.transformAndValidate(withHeaders.row, cb); } // skipped because of skipRows option remove from total row count return this.skipRow(cb); } // this is a header row dont include in the rowCount or parsedRowCount this.rowCount -= 1; this.parsedRowCount -= 1; return cb(null, { row: null, isValid: true }); }); } catch (e) { cb(e); } } checkAndEmitHeaders() { if (!this.headersEmitted && this.headerTransformer.headers) { this.headersEmitted = true; this.emit('headers', this.headerTransformer.headers); } } skipRow(cb) { // skipped because of skipRows option remove from total row count this.rowCount -= 1; return cb(null, { row: null, isValid: true }); } pushRow(row, cb) { try { if (!this.parserOptions.objectMode) { this.push(JSON.stringify(row)); } else { this.push(row); } cb(); } catch (e) { cb(e); } } static wrapDoneCallback(done) { let errorCalled = false; // eslint-disable-next-line @typescript-eslint/no-explicit-any return function (err) { if (err) { if (errorCalled) { throw err; } errorCalled = true; done(err); return; } for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { args[_key2 - 1] = arguments[_key2]; } done(...args); }; } } exports.CsvParserStream = CsvParserStream; }).call(this)}).call(this,require("timers").setImmediate) },{"./parser":20,"./transforms":23,"stream":237,"string_decoder":87,"timers":238}],9:[function(require,module,exports){ "use strict"; var __importDefault = void 0 && (void 0).__importDefault || function (mod) { return mod && mod.__esModule ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ParserOptions = void 0; const lodash_escaperegexp_1 = __importDefault(require("lodash.escaperegexp")); const lodash_isnil_1 = __importDefault(require("lodash.isnil")); class ParserOptions { constructor(opts) { var _a; this.objectMode = true; this.delimiter = ','; this.ignoreEmpty = false; this.quote = '"'; this.escape = null; this.escapeChar = this.quote; this.comment = null; this.supportsComments = false; this.ltrim = false; this.rtrim = false; this.trim = false; this.headers = null; this.renameHeaders = false; this.strictColumnHandling = false; this.discardUnmappedColumns = false; this.carriageReturn = '\r'; this.encoding = 'utf8'; this.limitRows = false; this.maxRows = 0; this.skipLines = 0; this.skipRows = 0; Object.assign(this, opts || {}); if (this.delimiter.length > 1) { throw new Error('delimiter option must be one character long'); } this.escapedDelimiter = lodash_escaperegexp_1.default(this.delimiter); this.escapeChar = (_a = this.escape) !== null && _a !== void 0 ? _a : this.quote; this.supportsComments = !lodash_isnil_1.default(this.comment); this.NEXT_TOKEN_REGEXP = new RegExp("([^\\s]|\\r\\n|\\n|\\r|".concat(this.escapedDelimiter, ")")); if (this.maxRows > 0) { this.limitRows = true; } } } exports.ParserOptions = ParserOptions; },{"lodash.escaperegexp":144,"lodash.isnil":149}],10:[function(require,module,exports){ "use strict"; var __createBinding = void 0 && (void 0).__createBinding || (Object.create ? function (o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } }); } : function (o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; }); var __setModuleDefault = void 0 && (void 0).__setModuleDefault || (Object.create ? function (o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); } : function (o, v) { o["default"] = v; }); var __importStar = void 0 && (void 0).__importStar || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __exportStar = void 0 && (void 0).__exportStar || function (m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseString = exports.parseFile = exports.parseStream = exports.parse = exports.ParserOptions = exports.CsvParserStream = void 0; const fs = __importStar(require("fs")); const stream_1 = require("stream"); const ParserOptions_1 = require("./ParserOptions"); const CsvParserStream_1 = require("./CsvParserStream"); __exportStar(require("./types"), exports); var CsvParserStream_2 = require("./CsvParserStream"); Object.defineProperty(exports, "CsvParserStream", { enumerable: true, get: function () { return CsvParserStream_2.CsvParserStream; } }); var ParserOptions_2 = require("./ParserOptions"); Object.defineProperty(exports, "ParserOptions", { enumerable: true, get: function () { return ParserOptions_2.ParserOptions; } }); exports.parse = args => new CsvParserStream_1.CsvParserStream(new ParserOptions_1.ParserOptions(args)); exports.parseStream = (stream, options) => stream.pipe(new CsvParserStream_1.CsvParserStream(new ParserOptions_1.ParserOptions(options))); exports.parseFile = function (location) { let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return fs.createReadStream(location).pipe(new CsvParserStream_1.CsvParserStream(new ParserOptions_1.ParserOptions(options))); }; exports.parseString = (string, options) => { const rs = new stream_1.Readable(); rs.push(string); rs.push(null); return rs.pipe(new CsvParserStream_1.CsvParserStream(new ParserOptions_1.ParserOptions(options))); }; },{"./CsvParserStream":8,"./ParserOptions":9,"./types":24,"fs":84,"stream":237}],11:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Parser = void 0; const Scanner_1 = require("./Scanner"); const RowParser_1 = require("./RowParser"); const Token_1 = require("./Token"); class Parser { constructor(parserOptions) { this.parserOptions = parserOptions; this.rowParser = new RowParser_1.RowParser(this.parserOptions); } static removeBOM(line) { // Catches EFBBBF (UTF-8 BOM) because the buffer-to-string // conversion translates it to FEFF (UTF-16 BOM) if (line && line.charCodeAt(0) === 0xfeff) { return line.slice(1); } return line; } parse(line, hasMoreData) { const scanner = new Scanner_1.Scanner({ line: Parser.removeBOM(line), parserOptions: this.parserOptions, hasMoreData }); if (this.parserOptions.supportsComments) { return this.parseWithComments(scanner); } return this.parseWithoutComments(scanner); } parseWithoutComments(scanner) { const rows = []; let shouldContinue = true; while (shouldContinue) { shouldContinue = this.parseRow(scanner, rows); } return { line: scanner.line, rows }; } parseWithComments(scanner) { const { parserOptions } = this; const rows = []; for (let nextToken = scanner.nextCharacterToken; nextToken !== null; nextToken = scanner.nextCharacterToken) { if (Token_1.Token.isTokenComment(nextToken, parserOptions)) { const cursor = scanner.advancePastLine(); if (cursor === null) { return { line: scanner.lineFromCursor, rows }; } if (!scanner.hasMoreCharacters) { return { line: scanner.lineFromCursor, rows }; } scanner.truncateToCursor(); } else if (!this.parseRow(scanner, rows)) { break; } } return { line: scanner.line, rows }; } parseRow(scanner, rows) { const nextToken = scanner.nextNonSpaceToken; if (!nextToken) { return false; } const row = this.rowParser.parse(scanner); if (row === null) { return false; } if (this.parserOptions.ignoreEmpty && RowParser_1.RowParser.isEmptyRow(row)) { return true; } rows.push(row); return true; } } exports.Parser = Parser; },{"./RowParser":12,"./Scanner":13,"./Token":14}],12:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RowParser = void 0; const column_1 = require("./column"); const Token_1 = require("./Token"); const EMPTY_STRING = ''; class RowParser { constructor(parserOptions) { this.parserOptions = parserOptions; this.columnParser = new column_1.ColumnParser(parserOptions); } static isEmptyRow(row) { return row.join(EMPTY_STRING).replace(/\s+/g, EMPTY_STRING) === EMPTY_STRING; } parse(scanner) { const { parserOptions } = this; const { hasMoreData } = scanner; const currentScanner = scanner; const columns = []; let currentToken = this.getStartToken(currentScanner, columns); while (currentToken) { if (Token_1.Token.isTokenRowDelimiter(currentToken)) { currentScanner.advancePastToken(currentToken); // if ends with CR and there is more data, keep unparsed due to possible // coming LF in CRLF if (!currentScanner.hasMoreCharacters && Token_1.Token.isTokenCarriageReturn(currentToken, parserOptions) && hasMoreData) { return null; } currentScanner.truncateToCursor(); return columns; } if (!this.shouldSkipColumnParse(currentScanner, currentToken, columns)) { const item = this.columnParser.parse(currentScanner); if (item === null) { return null; } columns.push(item); } currentToken = currentScanner.nextNonSpaceToken; } if (!hasMoreData) { currentScanner.truncateToCursor(); return columns; } return null; } getStartToken(scanner, columns) { const currentToken = scanner.nextNonSpaceToken; if (currentToken !== null && Token_1.Token.isTokenDelimiter(currentToken, this.parserOptions)) { columns.push(''); return scanner.nextNonSpaceToken; } return currentToken; } shouldSkipColumnParse(scanner, currentToken, columns) { const { parserOptions } = this; if (Token_1.Token.isTokenDelimiter(currentToken, parserOptions)) { scanner.advancePastToken(currentToken); // if the delimiter is at the end of a line const nextToken = scanner.nextCharacterToken; if (!scanner.hasMoreCharacters || nextToken !== null && Token_1.Token.isTokenRowDelimiter(nextToken)) { columns.push(''); return true; } if (nextToken !== null && Token_1.Token.isTokenDelimiter(nextToken, parserOptions)) { columns.push(''); return true; } } return false; } } exports.RowParser = RowParser; },{"./Token":14,"./column":19}],13:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Scanner = void 0; const Token_1 = require("./Token"); const ROW_DELIMITER = /((?:\r\n)|\n|\r)/; class Scanner { constructor(args) { this.cursor = 0; this.line = args.line; this.lineLength = this.line.length; this.parserOptions = args.parserOptions; this.hasMoreData = args.hasMoreData; this.cursor = args.cursor || 0; } get hasMoreCharacters() { return this.lineLength > this.cursor; } get nextNonSpaceToken() { const { lineFromCursor } = this; const regex = this.parserOptions.NEXT_TOKEN_REGEXP; if (lineFromCursor.search(regex) === -1) { return null; } const match = regex.exec(lineFromCursor); if (match == null) { return null; } const token = match[1]; const startCursor = this.cursor + (match.index || 0); return new Token_1.Token({ token, startCursor, endCursor: startCursor + token.length - 1 }); } get nextCharacterToken() { const { cursor, lineLength } = this; if (lineLength <= cursor) { return null; } return new Token_1.Token({ token: this.line[cursor], startCursor: cursor, endCursor: cursor }); } get lineFromCursor() { return this.line.substr(this.cursor); } advancePastLine() { const match = ROW_DELIMITER.exec(this.lineFromCursor); if (!match) { if (this.hasMoreData) { return null; } this.cursor = this.lineLength; return this; } this.cursor += (match.index || 0) + match[0].length; return this; } advanceTo(cursor) { this.cursor = cursor; return this; } advanceToToken(token) { this.cursor = token.startCursor; return this; } advancePastToken(token) { this.cursor = token.endCursor + 1; return this; } truncateToCursor() { this.line = this.lineFromCursor; this.lineLength = this.line.length; this.cursor = 0; return this; } } exports.Scanner = Scanner; },{"./Token":14}],14:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Token = void 0; class Token { constructor(tokenArgs) { this.token = tokenArgs.token; this.startCursor = tokenArgs.startCursor; this.endCursor = tokenArgs.endCursor; } static isTokenRowDelimiter(token) { const content = token.token; return content === '\r' || content === '\n' || content === '\r\n'; } static isTokenCarriageReturn(token, parserOptions) { return token.token === parserOptions.carriageReturn; } static isTokenComment(token, parserOptions) { return parserOptions.supportsComments && !!token && token.token === parserOptions.comment; } static isTokenEscapeCharacter(token, parserOptions) { return token.token === parserOptions.escapeChar; } static isTokenQuote(token, parserOptions) { return token.token === parserOptions.quote; } static isTokenDelimiter(token, parserOptions) { return token.token === parserOptions.delimiter; } } exports.Token = Token; },{}],15:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ColumnFormatter = void 0; class ColumnFormatter { constructor(parserOptions) { if (parserOptions.trim) { this.format = col => col.trim(); } else if (parserOptions.ltrim) { this.format = col => col.trimLeft(); } else if (parserOptions.rtrim) { this.format = col => col.trimRight(); } else { this.format = col => col; } } } exports.ColumnFormatter = ColumnFormatter; },{}],16:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ColumnParser = void 0; const NonQuotedColumnParser_1 = require("./NonQuotedColumnParser"); const QuotedColumnParser_1 = require("./QuotedColumnParser"); const Token_1 = require("../Token"); class ColumnParser { constructor(parserOptions) { this.parserOptions = parserOptions; this.quotedColumnParser = new QuotedColumnParser_1.QuotedColumnParser(parserOptions); this.nonQuotedColumnParser = new NonQuotedColumnParser_1.NonQuotedColumnParser(parserOptions); } parse(scanner) { const { nextNonSpaceToken } = scanner; if (nextNonSpaceToken !== null && Token_1.Token.isTokenQuote(nextNonSpaceToken, this.parserOptions)) { scanner.advanceToToken(nextNonSpaceToken); return this.quotedColumnParser.parse(scanner); } return this.nonQuotedColumnParser.parse(scanner); } } exports.ColumnParser = ColumnParser; },{"../Token":14,"./NonQuotedColumnParser":17,"./QuotedColumnParser":18}],17:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NonQuotedColumnParser = void 0; const ColumnFormatter_1 = require("./ColumnFormatter"); const Token_1 = require("../Token"); class NonQuotedColumnParser { constructor(parserOptions) { this.parserOptions = parserOptions; this.columnFormatter = new ColumnFormatter_1.ColumnFormatter(parserOptions); } parse(scanner) { if (!scanner.hasMoreCharacters) { return null; } const { parserOptions } = this; const characters = []; let nextToken = scanner.nextCharacterToken; for (; nextToken; nextToken = scanner.nextCharacterToken) { if (Token_1.Token.isTokenDelimiter(nextToken, parserOptions) || Token_1.Token.isTokenRowDelimiter(nextToken)) { break; } characters.push(nextToken.token); scanner.advancePastToken(nextToken); } return this.columnFormatter.format(characters.join('')); } } exports.NonQuotedColumnParser = NonQuotedColumnParser; },{"../Token":14,"./ColumnFormatter":15}],18:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.QuotedColumnParser = void 0; const ColumnFormatter_1 = require("./ColumnFormatter"); const Token_1 = require("../Token"); class QuotedColumnParser { constructor(parserOptions) { this.parserOptions = parserOptions; this.columnFormatter = new ColumnFormatter_1.ColumnFormatter(parserOptions); } parse(scanner) { if (!scanner.hasMoreCharacters) { return null; } const originalCursor = scanner.cursor; const { foundClosingQuote, col } = this.gatherDataBetweenQuotes(scanner); if (!foundClosingQuote) { // reset the cursor to the original scanner.advanceTo(originalCursor); // if we didnt find a closing quote but we potentially have more data then skip the parsing // and return the original scanner. if (!scanner.hasMoreData) { throw new Error("Parse Error: missing closing: '".concat(this.parserOptions.quote || '', "' in line: at '").concat(scanner.lineFromCursor.replace(/[\r\n]/g, "\\n'"), "'")); } return null; } this.checkForMalformedColumn(scanner); return col; } gatherDataBetweenQuotes(scanner) { const { parserOptions } = this; let foundStartingQuote = false; let foundClosingQuote = false; const characters = []; let nextToken = scanner.nextCharacterToken; for (; !foundClosingQuote && nextToken !== null; nextToken = scanner.nextCharacterToken) { const isQuote = Token_1.Token.isTokenQuote(nextToken, parserOptions); // ignore first quote if (!foundStartingQuote && isQuote) { foundStartingQuote = true; } else if (foundStartingQuote) { if (Token_1.Token.isTokenEscapeCharacter(nextToken, parserOptions)) { // advance past the escape character so we can get the next one in line scanner.advancePastToken(nextToken); const tokenFollowingEscape = scanner.nextCharacterToken; // if the character following the escape is a quote character then just add // the quote and advance to that character if (tokenFollowingEscape !== null && (Token_1.Token.isTokenQuote(tokenFollowingEscape, parserOptions) || Token_1.Token.isTokenEscapeCharacter(tokenFollowingEscape, parserOptions))) { characters.push(tokenFollowingEscape.token); nextToken = tokenFollowingEscape; } else if (isQuote) { // if the escape is also a quote then we found our closing quote and finish early foundClosingQuote = true; } else { // other wise add the escape token to the characters since it wast escaping anything characters.push(nextToken.token); } } else if (isQuote) { // we found our closing quote! foundClosingQuote = true; } else { // add the token to the characters characters.push(nextToken.token); } } scanner.advancePastToken(nextToken); } return { col: this.columnFormatter.format(characters.join('')), foundClosingQuote }; } checkForMalformedColumn(scanner) { const { parserOptions } = this; const { nextNonSpaceToken } = scanner; if (nextNonSpaceToken) { const isNextTokenADelimiter = Token_1.Token.isTokenDelimiter(nextNonSpaceToken, parserOptions); const isNextTokenARowDelimiter = Token_1.Token.isTokenRowDelimiter(nextNonSpaceToken); if (!(isNextTokenADelimiter || isNextTokenARowDelimiter)) { // if the final quote was NOT followed by a column (,) or row(\n) delimiter then its a bad column // tldr: only part of the column was quoted const linePreview = scanner.lineFromCursor.substr(0, 10).replace(/[\r\n]/g, "\\n'"); throw new Error("Parse Error: expected: '".concat(parserOptions.escapedDelimiter, "' OR new line got: '").concat(nextNonSpaceToken.token, "'. at '").concat(linePreview)); } scanner.advanceToToken(nextNonSpaceToken); } else if (!scanner.hasMoreData) { scanner.advancePastLine(); } } } exports.QuotedColumnParser = QuotedColumnParser; },{"../Token":14,"./ColumnFormatter":15}],19:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ColumnFormatter = exports.QuotedColumnParser = exports.NonQuotedColumnParser = exports.ColumnParser = void 0; var ColumnParser_1 = require("./ColumnParser"); Object.defineProperty(exports, "ColumnParser", { enumerable: true, get: function () { return ColumnParser_1.ColumnParser; } }); var NonQuotedColumnParser_1 = require("./NonQuotedColumnParser"); Object.defineProperty(exports, "NonQuotedColumnParser", { enumerable: true, get: function () { return NonQuotedColumnParser_1.NonQuotedColumnParser; } }); var QuotedColumnParser_1 = require("./QuotedColumnParser"); Object.defineProperty(exports, "QuotedColumnParser", { enumerable: true, get: function () { return QuotedColumnParser_1.QuotedColumnParser; } }); var ColumnFormatter_1 = require("./ColumnFormatter"); Object.defineProperty(exports, "ColumnFormatter", { enumerable: true, get: function () { return ColumnFormatter_1.ColumnFormatter; } }); },{"./ColumnFormatter":15,"./ColumnParser":16,"./NonQuotedColumnParser":17,"./QuotedColumnParser":18}],20:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.QuotedColumnParser = exports.NonQuotedColumnParser = exports.ColumnParser = exports.Token = exports.Scanner = exports.RowParser = exports.Parser = void 0; var Parser_1 = require("./Parser"); Object.defineProperty(exports, "Parser", { enumerable: true, get: function () { return Parser_1.Parser; } }); var RowParser_1 = require("./RowParser"); Object.defineProperty(exports, "RowParser", { enumerable: true, get: function () { return RowParser_1.RowParser; } }); var Scanner_1 = require("./Scanner"); Object.defineProperty(exports, "Scanner", { enumerable: true, get: function () { return Scanner_1.Scanner; } }); var Token_1 = require("./Token"); Object.defineProperty(exports, "Token", { enumerable: true, get: function () { return Token_1.Token; } }); var column_1 = require("./column"); Object.defineProperty(exports, "ColumnParser", { enumerable: true, get: function () { return column_1.ColumnParser; } }); Object.defineProperty(exports, "NonQuotedColumnParser", { enumerable: true, get: function () { return column_1.NonQuotedColumnParser; } }); Object.defineProperty(exports, "QuotedColumnParser", { enumerable: true, get: function () { return column_1.QuotedColumnParser; } }); },{"./Parser":11,"./RowParser":12,"./Scanner":13,"./Token":14,"./column":19}],21:[function(require,module,exports){ "use strict"; var __importDefault = void 0 && (void 0).__importDefault || function (mod) { return mod && mod.__esModule ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.HeaderTransformer = void 0; const lodash_isundefined_1 = __importDefault(require("lodash.isundefined")); const lodash_isfunction_1 = __importDefault(require("lodash.isfunction")); const lodash_uniq_1 = __importDefault(require("lodash.uniq")); const lodash_groupby_1 = __importDefault(require("lodash.groupby")); class HeaderTransformer { constructor(parserOptions) { this.headers = null; this.receivedHeaders = false; this.shouldUseFirstRow = false; this.processedFirstRow = false; this.headersLength = 0; this.parserOptions = parserOptions; if (parserOptions.headers === true) { this.shouldUseFirstRow = true; } else if (Array.isArray(parserOptions.headers)) { this.setHeaders(parserOptions.headers); } else if (lodash_isfunction_1.default(parserOptions.headers)) { this.headersTransform = parserOptions.headers; } } transform(row, cb) { if (!this.shouldMapRow(row)) { return cb(null, { row: null, isValid: true }); } return cb(null, this.processRow(row)); } shouldMapRow(row) { const { parserOptions } = this; if (!this.headersTransform && parserOptions.renameHeaders && !this.processedFirstRow) { if (!this.receivedHeaders) { throw new Error('Error renaming headers: new headers must be provided in an array'); } this.processedFirstRow = true; return false; } if (!this.receivedHeaders && Array.isArray(row)) { if (this.headersTransform) { this.setHeaders(this.headersTransform(row)); } else if (this.shouldUseFirstRow) { this.setHeaders(row); } else { // dont do anything with the headers if we didnt receive a transform or shouldnt use the first row. return true; } return false; } return true; } processRow(row) { if (!this.headers) { return { row: row, isValid: true }; } const { parserOptions } = this; if (!parserOptions.discardUnmappedColumns && row.length > this.headersLength) { if (!parserOptions.strictColumnHandling) { throw new Error("Unexpected Error: column header mismatch expected: ".concat(this.headersLength, " columns got: ").concat(row.length)); } return { row: row, isValid: false, reason: "Column header mismatch expected: ".concat(this.headersLength, " columns got: ").concat(row.length) }; } if (parserOptions.strictColumnHandling && row.length < this.headersLength) { return { row: row, isValid: false, reason: "Column header mismatch expected: ".concat(this.headersLength, " columns got: ").concat(row.length) }; } return { row: this.mapHeaders(row), isValid: true }; } mapHeaders(row) { const rowMap = {}; const { headers, headersLength } = this; for (let i = 0; i < headersLength; i += 1) { const header = headers[i]; if (!lodash_isundefined_1.default(header)) { const val = row[i]; // eslint-disable-next-line no-param-reassign if (lodash_isundefined_1.default(val)) { rowMap[header] = ''; } else { rowMap[header] = val; } } } return rowMap; } setHe