csv-sort 5.0.16 → 6.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,297 +0,0 @@
1
- /**
2
- * @name csv-sort
3
- * @fileoverview Sorts double-entry bookkeeping CSV coming from internet banking
4
- * @version 5.0.16
5
- * @author Roy Revelt, Codsen Ltd
6
- * @license MIT
7
- * {@link https://codsen.com/os/csv-sort/}
8
- */
9
-
10
- 'use strict';
11
-
12
- Object.defineProperty(exports, '__esModule', { value: true });
13
-
14
- var _typeof = require('@babel/runtime/helpers/typeof');
15
- var pull = require('lodash.pull');
16
- var csvSplitEasy = require('csv-split-easy');
17
- var currency = require('currency.js');
18
-
19
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
20
-
21
- var _typeof__default = /*#__PURE__*/_interopDefaultLegacy(_typeof);
22
- var pull__default = /*#__PURE__*/_interopDefaultLegacy(pull);
23
- var currency__default = /*#__PURE__*/_interopDefaultLegacy(currency);
24
-
25
- function isNumeric(str) {
26
- if (!str.trim()) {
27
- return false;
28
- }
29
- return Number(str) === Number(str);
30
- }
31
- var currencySigns = ["د.إ", "؋", "L", "֏", "ƒ", "Kz", "$", "ƒ", "₼", "KM", "৳", "лв", ".د.ب", "FBu", "$b", "R$", "฿", "Nu.", "P", "p.", "BZ$", "FC", "CHF", "¥", "₡", "₱", "Kč", "Fdj", "kr", "RD$", "دج", "kr", "Nfk", "Br", "Ξ", "€", "₾", "₵", "GH₵", "D", "FG", "Q", "L", "kn", "G", "Ft", "Rp", "₪", "₹", "ع.د", "﷼", "kr", "J$", "JD", "¥", "KSh", "лв", "៛", "CF", "₩", "₩", "KD", "лв", "₭", "₨", "M", "Ł", "Lt", "Ls", "LD", "MAD", "lei", "Ar", "ден", "K", "₮", "MOP$", "UM", "₨", "Rf", "MK", "RM", "MT", "₦", "C$", "kr", "₨", "﷼", "B/.", "S/.", "K", "₱", "₨", "zł", "Gs", "﷼", "¥", "lei", "Дин.", "₽", "R₣", "﷼", "₨", "ج.س.", "kr", "£", "Le", "S", "Db", "E", "฿", "SM", "T", "د.ت", "T$", "₤", "₺", "TT$", "NT$", "TSh", "₴", "USh", "$U", "лв", "Bs", "₫", "VT", "WS$", "FCFA", "Ƀ", "CFA", "₣", "﷼", "R", "Z$"];
32
- function findType(something) {
33
- /* istanbul ignore next */
34
- if (typeof something !== "string") {
35
- throw new Error("csv-sort/util/findType(): input must be string! Currently it's: ".concat(_typeof__default['default'](something)));
36
- }
37
- if (isNumeric(something)) {
38
- return "numeric";
39
- }
40
- /* istanbul ignore next */
41
- if (currencySigns.some(function (singleSign) {
42
- return (
43
- isNumeric(something.replace(singleSign, "").replace(/[,.]/g, ""))
44
- );
45
- })) {
46
- return "numeric";
47
- }
48
- if (!something.trim()) {
49
- return "empty";
50
- }
51
- return "text";
52
- }
53
-
54
- function sort(input) {
55
- var msgContent = null;
56
- var msgType = null;
57
- if (typeof input !== "string") {
58
- throw new TypeError("csv-sort/csvSort(): [THROW_ID_01] The input is of a wrong type! We accept either string of array of arrays. We got instead: ".concat(_typeof__default['default'](input), ", equal to:\n").concat(JSON.stringify(input, null, 4)));
59
- } else if (!input.trim()) {
60
- return {
61
- res: [[""]],
62
- msgContent: msgContent,
63
- msgType: msgType
64
- };
65
- }
66
- var content = csvSplitEasy.splitEasy(input);
67
- var schema = [];
68
- var stateHeaderRowPresent = false;
69
- var stateDataColumnRowLengthIsConsistent = true;
70
- var stateColumnsContainingSameValueEverywhere = [];
71
- var indexAtWhichEmptyCellsStart = null;
72
- for (var i = content.length - 1; i >= 0; i--) {
73
- if (!schema.length) {
74
- /* istanbul ignore next */
75
- if (content[i].length !== 1 || content[i][0] !== "") {
76
- for (var y = 0, len = content[i].length; y < len; y++) {
77
- schema.push(findType(content[i][y].trim()));
78
- if (indexAtWhichEmptyCellsStart === null && findType(content[i][y].trim()) === "empty") {
79
- indexAtWhichEmptyCellsStart = y;
80
- }
81
- if (indexAtWhichEmptyCellsStart !== null && findType(content[i][y].trim()) !== "empty") {
82
- indexAtWhichEmptyCellsStart = null;
83
- }
84
- }
85
- }
86
- } else {
87
- if (i === 0) {
88
- stateHeaderRowPresent = content[i].every(function (el) {
89
- return findType(el) === "text" || findType(el) === "empty";
90
- });
91
- }
92
- /* istanbul ignore else */
93
- if (!stateHeaderRowPresent && schema.length !== content[i].length) {
94
- stateDataColumnRowLengthIsConsistent = false;
95
- }
96
- var perRowIndexAtWhichEmptyCellsStart = null;
97
- for (var _y = 0, _len = content[i].length; _y < _len; _y++) {
98
- /* istanbul ignore else */
99
- if (perRowIndexAtWhichEmptyCellsStart === null && findType(content[i][_y].trim()) === "empty") {
100
- perRowIndexAtWhichEmptyCellsStart = _y;
101
- }
102
- /* istanbul ignore else */
103
- if (perRowIndexAtWhichEmptyCellsStart !== null && findType(content[i][_y].trim()) !== "empty") {
104
- perRowIndexAtWhichEmptyCellsStart = null;
105
- }
106
- /* istanbul ignore else */
107
- if (findType(content[i][_y].trim()) !== schema[_y] && !stateHeaderRowPresent) {
108
- var toAdd = findType(content[i][_y].trim());
109
- /* istanbul ignore else */
110
- if (Array.isArray(schema[_y])) {
111
- if (!schema[_y].includes(toAdd)) {
112
- schema[_y].push(findType(content[i][_y].trim()));
113
- }
114
- } else if (schema[_y] !== toAdd) {
115
- var temp = schema[_y];
116
- schema[_y] = [];
117
- schema[_y].push(temp);
118
- schema[_y].push(toAdd);
119
- }
120
- }
121
- }
122
- /* istanbul ignore next */
123
- if (indexAtWhichEmptyCellsStart !== null && perRowIndexAtWhichEmptyCellsStart !== null && perRowIndexAtWhichEmptyCellsStart > indexAtWhichEmptyCellsStart && (!stateHeaderRowPresent || stateHeaderRowPresent && i !== 0)) {
124
- indexAtWhichEmptyCellsStart = perRowIndexAtWhichEmptyCellsStart;
125
- }
126
- }
127
- }
128
- /* istanbul ignore else */
129
- if (!indexAtWhichEmptyCellsStart) {
130
- indexAtWhichEmptyCellsStart = schema.length;
131
- }
132
- var nonEmptyColsStartAt = 0;
133
- for (var _i = 0, _len2 = schema.length; _i < _len2; _i++) {
134
- if (schema[_i] === "empty") {
135
- nonEmptyColsStartAt = _i;
136
- } else {
137
- break;
138
- }
139
- }
140
- /* istanbul ignore else */
141
- if (nonEmptyColsStartAt !== 0) {
142
- content = content.map(function (arr) {
143
- return arr.slice(nonEmptyColsStartAt + 1, indexAtWhichEmptyCellsStart);
144
- });
145
- schema = schema.slice(nonEmptyColsStartAt + 1, indexAtWhichEmptyCellsStart);
146
- }
147
- var numericSchemaColumns = [];
148
- var balanceColumnIndex;
149
- schema.forEach(function (colType, i) {
150
- if (colType === "numeric") {
151
- numericSchemaColumns.push(i);
152
- }
153
- });
154
- var traverseUpToThisIndexAtTheTop = stateHeaderRowPresent ? 1 : 0;
155
- if (numericSchemaColumns.length === 1) {
156
- balanceColumnIndex = numericSchemaColumns[0];
157
- } else if (numericSchemaColumns.length === 0) {
158
- throw new Error('csv-sort/csvSort(): [THROW_ID_03] Your CSV file does not contain numeric-only columns and computer was not able to detect the "Balance" column!');
159
- } else {
160
- var potentialBalanceColumnIndexesList = Array.from(numericSchemaColumns);
161
- var deleteFromPotentialBalanceColumnIndexesList = [];
162
- for (var _i2 = 0, _len3 = potentialBalanceColumnIndexesList.length; _i2 < _len3; _i2++) {
163
- var suspectedBalanceColumnsIndexNumber = potentialBalanceColumnIndexesList[_i2];
164
- var previousValue = void 0;
165
- var lookForTwoEqualAndConsecutive = true;
166
- var firstValue = void 0;
167
- var lookForAllTheSame = true;
168
- for (var rowNum = traverseUpToThisIndexAtTheTop, len2 = content.length; rowNum < len2; rowNum++) {
169
- /* istanbul ignore else */
170
- if (lookForTwoEqualAndConsecutive) {
171
- if (previousValue == null) {
172
- previousValue = content[rowNum][suspectedBalanceColumnsIndexNumber];
173
- } else if (previousValue === content[rowNum][suspectedBalanceColumnsIndexNumber]) {
174
- deleteFromPotentialBalanceColumnIndexesList.push(suspectedBalanceColumnsIndexNumber);
175
- lookForTwoEqualAndConsecutive = false;
176
- } else {
177
- previousValue = content[rowNum][suspectedBalanceColumnsIndexNumber];
178
- }
179
- }
180
- /* istanbul ignore else */
181
- if (lookForAllTheSame) {
182
- if (firstValue == null) {
183
- firstValue = content[rowNum][suspectedBalanceColumnsIndexNumber];
184
- } else if (content[rowNum][suspectedBalanceColumnsIndexNumber] !== firstValue) {
185
- lookForAllTheSame = false;
186
- }
187
- }
188
- if (!lookForTwoEqualAndConsecutive) {
189
- break;
190
- }
191
- }
192
- /* istanbul ignore else */
193
- if (lookForAllTheSame) {
194
- stateColumnsContainingSameValueEverywhere.push(suspectedBalanceColumnsIndexNumber);
195
- }
196
- }
197
- potentialBalanceColumnIndexesList = pull__default['default'].apply(void 0, [potentialBalanceColumnIndexesList].concat(deleteFromPotentialBalanceColumnIndexesList));
198
- /* istanbul ignore else */
199
- if (potentialBalanceColumnIndexesList.length === 1) {
200
- balanceColumnIndex = potentialBalanceColumnIndexesList[0];
201
- } else if (potentialBalanceColumnIndexesList.length === 0) {
202
- throw new Error('csv-sort/csvSort(): [THROW_ID_04] The computer can\'t find the "Balance" column! It saw some numeric-only columns, but they all seem to have certain rows with the same values as rows right below/above them!');
203
- } else ;
204
- }
205
- if (!balanceColumnIndex) {
206
- throw new Error("csv-sort/csvSort(): [THROW_ID_05] Sadly computer couldn't find its way in this CSV and had to stop working on it.");
207
- }
208
- var potentialCreditDebitColumns = pull__default['default'].apply(void 0, [Array.from(schema.reduce(function (result, el, index) {
209
- if (typeof el === "string" && el === "numeric" || Array.isArray(el) && el.includes("numeric")) {
210
- result.push(index);
211
- }
212
- return result;
213
- }, [])), balanceColumnIndex].concat(stateColumnsContainingSameValueEverywhere));
214
- var resContent = [];
215
- resContent.push(content[content.length - 1].slice(0, indexAtWhichEmptyCellsStart));
216
- var usedUpRows = [];
217
- var bottom = stateHeaderRowPresent ? 1 : 0;
218
- for (var _y2 = content.length - 2; _y2 >= bottom; _y2--) {
219
- for (var suspectedRowsIndex = content.length - 2; suspectedRowsIndex >= bottom; suspectedRowsIndex--) {
220
- if (!usedUpRows.includes(suspectedRowsIndex)) {
221
- var thisRowIsDone = false;
222
- for (var suspectedColIndex = 0, _len4 = potentialCreditDebitColumns.length; suspectedColIndex < _len4; suspectedColIndex++) {
223
- var diffVal = null;
224
- if (content[suspectedRowsIndex][potentialCreditDebitColumns[suspectedColIndex]] !== "") {
225
- diffVal = currency__default['default'](content[suspectedRowsIndex][potentialCreditDebitColumns[suspectedColIndex]]);
226
- }
227
- var totalVal = null;
228
- /* istanbul ignore else */
229
- if (content[suspectedRowsIndex][balanceColumnIndex] !== "") {
230
- totalVal = currency__default['default'](content[suspectedRowsIndex][balanceColumnIndex]);
231
- }
232
- var topmostResContentBalance = null;
233
- /* istanbul ignore else */
234
- if (resContent[0][balanceColumnIndex] !== "") {
235
- topmostResContentBalance = currency__default['default'](resContent[0][balanceColumnIndex]).format();
236
- }
237
- var currentRowsDiffVal = null;
238
- /* istanbul ignore else */
239
- if (resContent[resContent.length - 1][potentialCreditDebitColumns[suspectedColIndex]] !== "") {
240
- currentRowsDiffVal = currency__default['default'](resContent[resContent.length - 1][potentialCreditDebitColumns[suspectedColIndex]]).format();
241
- }
242
- var lastResContentRowsBalance = null;
243
- /* istanbul ignore else */
244
- if (resContent[resContent.length - 1][balanceColumnIndex] !== "") {
245
- lastResContentRowsBalance = currency__default['default'](resContent[resContent.length - 1][balanceColumnIndex]);
246
- }
247
- /* istanbul ignore else */
248
- if (diffVal && totalVal.add(diffVal).format() === topmostResContentBalance) {
249
- resContent.unshift(content[suspectedRowsIndex].slice(0, indexAtWhichEmptyCellsStart));
250
- usedUpRows.push(suspectedRowsIndex);
251
- thisRowIsDone = true;
252
- break;
253
- } else if (diffVal && totalVal.subtract(diffVal).format() === topmostResContentBalance) {
254
- resContent.unshift(content[suspectedRowsIndex].slice(0, indexAtWhichEmptyCellsStart));
255
- usedUpRows.push(suspectedRowsIndex);
256
- thisRowIsDone = true;
257
- break;
258
- } else if (currentRowsDiffVal && lastResContentRowsBalance.add(currentRowsDiffVal).format() === totalVal.format()) {
259
- resContent.push(content[suspectedRowsIndex].slice(0, indexAtWhichEmptyCellsStart));
260
- usedUpRows.push(suspectedRowsIndex);
261
- thisRowIsDone = true;
262
- break;
263
- } else if (currentRowsDiffVal && lastResContentRowsBalance.subtract(currentRowsDiffVal).format() === totalVal.format()) {
264
- resContent.push(content[suspectedRowsIndex].slice(0, indexAtWhichEmptyCellsStart));
265
- usedUpRows.push(suspectedRowsIndex);
266
- thisRowIsDone = true;
267
- break;
268
- }
269
- }
270
- /* istanbul ignore else */
271
- if (thisRowIsDone) {
272
- thisRowIsDone = false;
273
- break;
274
- }
275
- }
276
- }
277
- }
278
- /* istanbul ignore else */
279
- if (stateHeaderRowPresent) {
280
- if (stateDataColumnRowLengthIsConsistent && content[0].length > schema.length) {
281
- content[0].length = schema.length;
282
- }
283
- resContent.unshift(content[0].slice(0, indexAtWhichEmptyCellsStart));
284
- }
285
- /* istanbul ignore else */
286
- if (content.length - (stateHeaderRowPresent ? 2 : 1) !== usedUpRows.length) {
287
- msgContent = "Not all rows were recognised!";
288
- msgType = "alert";
289
- }
290
- return {
291
- res: resContent,
292
- msgContent: msgContent,
293
- msgType: msgType
294
- };
295
- }
296
-
297
- exports.sort = sort;