@ellipticltd/aml-utils 0.14.4 → 0.15.0-SCR-882
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.
- package/.nyc_output/cd455ec6-4d73-4c5e-871e-7f0609bd11b8.json +1 -0
- package/.nyc_output/d6cd0f05-9810-4f97-8faa-8753f10b9d2d.json +1 -0
- package/.nyc_output/processinfo/3974a52e-3acc-45e4-a312-2dae8e2da051.json +1 -0
- package/.nyc_output/processinfo/3bbc21ec-7576-45f9-bc87-b6a79588c265.json +1 -0
- package/.nyc_output/processinfo/{50aa63d7-9c6e-46d3-8501-30960c84bde4.json → cd455ec6-4d73-4c5e-871e-7f0609bd11b8.json} +1 -1
- package/.nyc_output/processinfo/{a9f60314-7478-419f-9797-03e94060b169.json → d6cd0f05-9810-4f97-8faa-8753f10b9d2d.json} +1 -1
- package/.nyc_output/processinfo/index.json +1 -1
- package/coverage/errors/errors.js.html +1 -1
- package/coverage/errors/errors.spec.js.html +1 -1
- package/coverage/errors/index.html +1 -1
- package/coverage/file-parser/__tests/file-parser.spec.js.html +1 -1
- package/coverage/file-parser/__tests/index.html +1 -1
- package/coverage/file-parser/__tests/parse-row.spec.js.html +1 -1
- package/coverage/file-parser/__tests/sanitize-rows.spec.js.html +1 -1
- package/coverage/formatting/formatting.js.html +1 -1
- package/coverage/formatting/formatting.spec.js.html +1 -1
- package/coverage/formatting/index.html +1 -1
- package/coverage/index.html +18 -18
- package/coverage/middleware/index.html +1 -1
- package/coverage/middleware/middleware.js.html +1 -1
- package/coverage/orm-helpers/index.html +1 -1
- package/coverage/orm-helpers/ormHelpers.js.html +1 -1
- package/coverage/orm-helpers/ormHelpers.spec.js.html +1 -1
- package/coverage/types/index.html +1 -1
- package/coverage/types/types.js.html +1 -1
- package/coverage/validations/index.html +24 -24
- package/coverage/validations/validations.js.html +59 -11
- package/coverage/validations/validations.spec.js.html +121 -7
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/structured-file-parser/errors.d.ts +12 -0
- package/dist/structured-file-parser/errors.js +32 -0
- package/dist/structured-file-parser/parse-row.d.ts +2 -0
- package/dist/structured-file-parser/parse-row.js +39 -0
- package/dist/structured-file-parser/sanitize-rows.d.ts +2 -0
- package/dist/structured-file-parser/sanitize-rows.js +15 -0
- package/dist/structured-file-parser/structured-file-parser.d.ts +10 -0
- package/dist/structured-file-parser/structured-file-parser.js +108 -0
- package/lib/index.ts +2 -0
- package/lib/structured-file-parser/errors.ts +25 -0
- package/lib/structured-file-parser/parse-row.ts +52 -0
- package/lib/structured-file-parser/sanitize-rows.ts +24 -0
- package/lib/structured-file-parser/structured-file-parser.ts +155 -0
- package/package.json +2 -2
- package/.nyc_output/50aa63d7-9c6e-46d3-8501-30960c84bde4.json +0 -1
- package/.nyc_output/a9f60314-7478-419f-9797-03e94060b169.json +0 -1
- package/.nyc_output/processinfo/61b1d936-f243-4d58-9e37-4fd5d0780ba5.json +0 -1
- package/.nyc_output/processinfo/ef70e198-cb3a-45b9-9f97-cd7e9ee29fea.json +0 -1
- /package/.nyc_output/{61b1d936-f243-4d58-9e37-4fd5d0780ba5.json → 3974a52e-3acc-45e4-a312-2dae8e2da051.json} +0 -0
- /package/.nyc_output/{ef70e198-cb3a-45b9-9f97-cd7e9ee29fea.json → 3bbc21ec-7576-45f9-bc87-b6a79588c265.json} +0 -0
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
</h1>
|
|
21
21
|
<div class='clearfix'>
|
|
22
22
|
<div class='fl pad1y space-right2'>
|
|
23
|
-
<span class="strong">99.
|
|
23
|
+
<span class="strong">99.23% </span>
|
|
24
24
|
<span class="quiet">Statements</span>
|
|
25
|
-
<span class='fraction'>
|
|
25
|
+
<span class='fraction'>385/388</span>
|
|
26
26
|
</div>
|
|
27
27
|
<div class='fl pad1y space-right2'>
|
|
28
28
|
<span class="strong">83.33% </span>
|
|
@@ -30,14 +30,14 @@
|
|
|
30
30
|
<span class='fraction'>20/24</span>
|
|
31
31
|
</div>
|
|
32
32
|
<div class='fl pad1y space-right2'>
|
|
33
|
-
<span class="strong">98.
|
|
33
|
+
<span class="strong">98.69% </span>
|
|
34
34
|
<span class="quiet">Functions</span>
|
|
35
|
-
<span class='fraction'>
|
|
35
|
+
<span class='fraction'>226/229</span>
|
|
36
36
|
</div>
|
|
37
37
|
<div class='fl pad1y space-right2'>
|
|
38
38
|
<span class="strong">100% </span>
|
|
39
39
|
<span class="quiet">Lines</span>
|
|
40
|
-
<span class='fraction'>
|
|
40
|
+
<span class='fraction'>255/255</span>
|
|
41
41
|
</div>
|
|
42
42
|
</div>
|
|
43
43
|
<p class="quiet">
|
|
@@ -497,7 +497,45 @@
|
|
|
497
497
|
<a name='L449'></a><a href='#L449'>449</a>
|
|
498
498
|
<a name='L450'></a><a href='#L450'>450</a>
|
|
499
499
|
<a name='L451'></a><a href='#L451'>451</a>
|
|
500
|
-
<a name='L452'></a><a href='#L452'>452</a
|
|
500
|
+
<a name='L452'></a><a href='#L452'>452</a>
|
|
501
|
+
<a name='L453'></a><a href='#L453'>453</a>
|
|
502
|
+
<a name='L454'></a><a href='#L454'>454</a>
|
|
503
|
+
<a name='L455'></a><a href='#L455'>455</a>
|
|
504
|
+
<a name='L456'></a><a href='#L456'>456</a>
|
|
505
|
+
<a name='L457'></a><a href='#L457'>457</a>
|
|
506
|
+
<a name='L458'></a><a href='#L458'>458</a>
|
|
507
|
+
<a name='L459'></a><a href='#L459'>459</a>
|
|
508
|
+
<a name='L460'></a><a href='#L460'>460</a>
|
|
509
|
+
<a name='L461'></a><a href='#L461'>461</a>
|
|
510
|
+
<a name='L462'></a><a href='#L462'>462</a>
|
|
511
|
+
<a name='L463'></a><a href='#L463'>463</a>
|
|
512
|
+
<a name='L464'></a><a href='#L464'>464</a>
|
|
513
|
+
<a name='L465'></a><a href='#L465'>465</a>
|
|
514
|
+
<a name='L466'></a><a href='#L466'>466</a>
|
|
515
|
+
<a name='L467'></a><a href='#L467'>467</a>
|
|
516
|
+
<a name='L468'></a><a href='#L468'>468</a>
|
|
517
|
+
<a name='L469'></a><a href='#L469'>469</a>
|
|
518
|
+
<a name='L470'></a><a href='#L470'>470</a>
|
|
519
|
+
<a name='L471'></a><a href='#L471'>471</a>
|
|
520
|
+
<a name='L472'></a><a href='#L472'>472</a>
|
|
521
|
+
<a name='L473'></a><a href='#L473'>473</a>
|
|
522
|
+
<a name='L474'></a><a href='#L474'>474</a>
|
|
523
|
+
<a name='L475'></a><a href='#L475'>475</a>
|
|
524
|
+
<a name='L476'></a><a href='#L476'>476</a>
|
|
525
|
+
<a name='L477'></a><a href='#L477'>477</a>
|
|
526
|
+
<a name='L478'></a><a href='#L478'>478</a>
|
|
527
|
+
<a name='L479'></a><a href='#L479'>479</a>
|
|
528
|
+
<a name='L480'></a><a href='#L480'>480</a>
|
|
529
|
+
<a name='L481'></a><a href='#L481'>481</a>
|
|
530
|
+
<a name='L482'></a><a href='#L482'>482</a>
|
|
531
|
+
<a name='L483'></a><a href='#L483'>483</a>
|
|
532
|
+
<a name='L484'></a><a href='#L484'>484</a>
|
|
533
|
+
<a name='L485'></a><a href='#L485'>485</a>
|
|
534
|
+
<a name='L486'></a><a href='#L486'>486</a>
|
|
535
|
+
<a name='L487'></a><a href='#L487'>487</a>
|
|
536
|
+
<a name='L488'></a><a href='#L488'>488</a>
|
|
537
|
+
<a name='L489'></a><a href='#L489'>489</a>
|
|
538
|
+
<a name='L490'></a><a href='#L490'>490</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
|
|
501
539
|
<span class="cline-any cline-neutral"> </span>
|
|
502
540
|
<span class="cline-any cline-yes">1x</span>
|
|
503
541
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -948,6 +986,44 @@
|
|
|
948
986
|
<span class="cline-any cline-neutral"> </span>
|
|
949
987
|
<span class="cline-any cline-neutral"> </span>
|
|
950
988
|
<span class="cline-any cline-neutral"> </span>
|
|
989
|
+
<span class="cline-any cline-yes">1x</span>
|
|
990
|
+
<span class="cline-any cline-yes">1x</span>
|
|
991
|
+
<span class="cline-any cline-yes">1x</span>
|
|
992
|
+
<span class="cline-any cline-neutral"> </span>
|
|
993
|
+
<span class="cline-any cline-yes">1x</span>
|
|
994
|
+
<span class="cline-any cline-neutral"> </span>
|
|
995
|
+
<span class="cline-any cline-yes">1x</span>
|
|
996
|
+
<span class="cline-any cline-neutral"> </span>
|
|
997
|
+
<span class="cline-any cline-neutral"> </span>
|
|
998
|
+
<span class="cline-any cline-yes">1x</span>
|
|
999
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1000
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1001
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1002
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1003
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1004
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1005
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1006
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1007
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1008
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1009
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1010
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1011
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1012
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1013
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1014
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1015
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1016
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1017
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1018
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1019
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1020
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1021
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1022
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1023
|
+
<span class="cline-any cline-yes">1x</span>
|
|
1024
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1025
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1026
|
+
<span class="cline-any cline-neutral"> </span>
|
|
951
1027
|
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import validations from './validations';
|
|
952
1028
|
|
|
953
1029
|
const chai = require('chai');
|
|
@@ -1398,6 +1474,44 @@ describe('Validations', () => {
|
|
|
1398
1474
|
it('should correctly validate an incorrect BSC hash', () => validations.binanceSmartChain.isTxHash('0x1a17145af3bec32f653d8ebd4c2c1b800214b17').should.be.false);
|
|
1399
1475
|
});
|
|
1400
1476
|
});
|
|
1477
|
+
|
|
1478
|
+
describe('Polygon', () => {
|
|
1479
|
+
describe('isAddress', () => {
|
|
1480
|
+
it('should correctly validate valid Polygon addresses', () => validations.polygon.isAddress('0x286c2bd6e0585f396647cbfdbfe14b92600365bb').should.be.true);
|
|
1481
|
+
|
|
1482
|
+
it('should correctly validate an incorrect Polygon address', () => validations.polygon.isAddress('0xz286c2bd6e0585f396647cbfdbfe14b92600365bb').should.be.false);
|
|
1483
|
+
|
|
1484
|
+
it('should correctly validate an incorrect (too long) Polygon address', () => validations.polygon.isAddress('0x286c2bd6e0585f396647cbfdbfe14b92600365bba').should.be.false);
|
|
1485
|
+
});
|
|
1486
|
+
|
|
1487
|
+
describe('isTxHash', () => {
|
|
1488
|
+
it('should correctly validate a valid Polygon hash', () => validations.polygon.isTxHash('0x45a491048477568dd2047a0a9b6be9cc491382e74823ea1bd53bbc67db54a867').should.be.true);
|
|
1489
|
+
|
|
1490
|
+
it('should correctly validate an incorrect Polygon hash', () => validations.polygon.isTxHash('0x45a491048477568dd2047a0a9b6be9cc491382e74823e').should.be.false);
|
|
1491
|
+
});
|
|
1492
|
+
});
|
|
1493
|
+
|
|
1494
|
+
describe('Filecoin', () => {
|
|
1495
|
+
describe('isAddress', () => {
|
|
1496
|
+
it('should correctly validate a valid Filecoin f0 address', () => validations.filecoin.isAddress('f01825161').should.be.true);
|
|
1497
|
+
|
|
1498
|
+
it('should correctly validate a valid Filecoin f1 address', () => validations.filecoin.isAddress('f1xafi3wsh7q553efnumhgeomathrehwwd2mye7oy').should.be.true);
|
|
1499
|
+
|
|
1500
|
+
it('should correctly validate a valid Filecoin f2 address', () => validations.filecoin.isAddress('f2vrab2ft4qc22mgfxgdrphd7ovvz6zs3nq3fv4oy').should.be.true);
|
|
1501
|
+
|
|
1502
|
+
it('should correctly validate a valid Filecoin f3 address', () => validations.filecoin.isAddress('f3ug2ti4finql5bxyl5q56udn5lt462miuadjg3ur467wrj6bvbrksglxyv65zoxyz4mgte3joyce3oxkk4q7q').should.be.true);
|
|
1503
|
+
|
|
1504
|
+
it('should correctly validate an invalid Filecoin address', () => validations.filecoin.isAddress('f4zvcxzvcxzvczvcasdgwere').should.be.false);
|
|
1505
|
+
});
|
|
1506
|
+
|
|
1507
|
+
describe('isTxHash', () => {
|
|
1508
|
+
it('should correctly validate a valid Filecoin hash', () => validations.filecoin.isTxHash('bafy2bzacedcrpcs76f2ws445wnjix2kktsgca4vv6qbd7zua7pc5mnkpveg7m').should.be.true);
|
|
1509
|
+
|
|
1510
|
+
it('should correctly validate an invalid Filecoin hash', () => validations.filecoin.isTxHash('bafy2bzacedcrpcs76f2ws445wnjix2kktsgca4vv6qbd7zua7pc5mnkpveg7').should.be.false);
|
|
1511
|
+
|
|
1512
|
+
it('should correctly validate an invalid Filecoin hash', () => validations.filecoin.isTxHash('fafy2bzacedcrpcs76f2ws445wnjix2kktsgca4vv6qbd7zua7pc5mnkpveg7m').should.be.false);
|
|
1513
|
+
});
|
|
1514
|
+
});
|
|
1401
1515
|
});
|
|
1402
1516
|
</pre></td></tr>
|
|
1403
1517
|
</table></pre>
|
|
@@ -1405,7 +1519,7 @@ describe('Validations', () => {
|
|
|
1405
1519
|
</div><!-- /wrapper -->
|
|
1406
1520
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
1407
1521
|
Code coverage
|
|
1408
|
-
generated by <a href="https://istanbul.js.org/" target="_blank">istanbul</a> at
|
|
1522
|
+
generated by <a href="https://istanbul.js.org/" target="_blank">istanbul</a> at Tue Oct 18 2022 17:03:56 GMT+0200 (CEST)
|
|
1409
1523
|
</div>
|
|
1410
1524
|
</div>
|
|
1411
1525
|
<script src="../prettify.js"></script>
|
package/dist/index.d.ts
CHANGED
|
@@ -5,4 +5,5 @@ import formatting from './formatting/formatting';
|
|
|
5
5
|
import middleware from './middleware/middleware';
|
|
6
6
|
import ormHelpers from './orm-helpers/ormHelpers';
|
|
7
7
|
import fileParser from './file-parser/file-parser';
|
|
8
|
-
|
|
8
|
+
import structuredFileParser from './structured-file-parser/structured-file-parser';
|
|
9
|
+
export { types, validations, errors, formatting, fileParser, structuredFileParser, middleware, ormHelpers, };
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ormHelpers = exports.middleware = exports.fileParser = exports.formatting = exports.errors = exports.validations = exports.types = void 0;
|
|
6
|
+
exports.ormHelpers = exports.middleware = exports.structuredFileParser = exports.fileParser = exports.formatting = exports.errors = exports.validations = exports.types = void 0;
|
|
7
7
|
const types_1 = __importDefault(require("./types/types"));
|
|
8
8
|
exports.types = types_1.default;
|
|
9
9
|
const validations_1 = __importDefault(require("./validations/validations"));
|
|
@@ -18,3 +18,5 @@ const ormHelpers_1 = __importDefault(require("./orm-helpers/ormHelpers"));
|
|
|
18
18
|
exports.ormHelpers = ormHelpers_1.default;
|
|
19
19
|
const file_parser_1 = __importDefault(require("./file-parser/file-parser"));
|
|
20
20
|
exports.fileParser = file_parser_1.default;
|
|
21
|
+
const structured_file_parser_1 = __importDefault(require("./structured-file-parser/structured-file-parser"));
|
|
22
|
+
exports.structuredFileParser = structured_file_parser_1.default;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class InvalidFileError extends Error {
|
|
2
|
+
constructor();
|
|
3
|
+
}
|
|
4
|
+
export declare class TooManyRowsError extends Error {
|
|
5
|
+
constructor();
|
|
6
|
+
}
|
|
7
|
+
export declare class NoRowsError extends Error {
|
|
8
|
+
constructor();
|
|
9
|
+
}
|
|
10
|
+
export declare class InvalidHeadersError extends Error {
|
|
11
|
+
constructor();
|
|
12
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InvalidHeadersError = exports.NoRowsError = exports.TooManyRowsError = exports.InvalidFileError = void 0;
|
|
4
|
+
/* eslint-disable max-classes-per-file */
|
|
5
|
+
class InvalidFileError extends Error {
|
|
6
|
+
constructor() {
|
|
7
|
+
super('Invalid file type');
|
|
8
|
+
this.name = 'InvalidFileError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.InvalidFileError = InvalidFileError;
|
|
12
|
+
class TooManyRowsError extends Error {
|
|
13
|
+
constructor() {
|
|
14
|
+
super('More than configured number of rows imported');
|
|
15
|
+
this.name = 'TooManyRowsError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.TooManyRowsError = TooManyRowsError;
|
|
19
|
+
class NoRowsError extends Error {
|
|
20
|
+
constructor() {
|
|
21
|
+
super('No rows');
|
|
22
|
+
this.name = 'NoRowsError';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
exports.NoRowsError = NoRowsError;
|
|
26
|
+
class InvalidHeadersError extends Error {
|
|
27
|
+
constructor() {
|
|
28
|
+
super('Invalid or incomplete headers list');
|
|
29
|
+
this.name = 'InvalidHeadersError';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.InvalidHeadersError = InvalidHeadersError;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const fp_1 = require("lodash/fp");
|
|
4
|
+
const parseRow = (row) => {
|
|
5
|
+
const trySplitByTab = (line) => {
|
|
6
|
+
if (typeof line === 'string' && line.match('\t')) {
|
|
7
|
+
return line.split('\t');
|
|
8
|
+
}
|
|
9
|
+
return line;
|
|
10
|
+
};
|
|
11
|
+
const trySplitByComa = (line) => {
|
|
12
|
+
if (typeof line === 'string' && line.match(',')) {
|
|
13
|
+
return line.split(',');
|
|
14
|
+
}
|
|
15
|
+
return line;
|
|
16
|
+
};
|
|
17
|
+
const trySplitByMultipleSpaces = (line) => {
|
|
18
|
+
if (typeof line === 'string' && line.match(/ {3,}/)) {
|
|
19
|
+
return line.split(/ {3,}/);
|
|
20
|
+
}
|
|
21
|
+
return line;
|
|
22
|
+
};
|
|
23
|
+
const trySplitBySpace = (line) => {
|
|
24
|
+
if (typeof line === 'string' && line.match(' ')) {
|
|
25
|
+
return line.split(' ');
|
|
26
|
+
}
|
|
27
|
+
return line;
|
|
28
|
+
};
|
|
29
|
+
const trySplitByNothing = (line) => {
|
|
30
|
+
if (typeof line === 'string') {
|
|
31
|
+
return [line];
|
|
32
|
+
}
|
|
33
|
+
return line;
|
|
34
|
+
};
|
|
35
|
+
const splitRow = fp_1.pipe(trySplitByTab, trySplitByComa, trySplitByMultipleSpaces, trySplitBySpace, trySplitByNothing);
|
|
36
|
+
const cells = splitRow(row);
|
|
37
|
+
return cells.map((c) => c.trim());
|
|
38
|
+
};
|
|
39
|
+
exports.default = parseRow;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const sensicalRowCheck = (cells) => (cells.some((cell) => !!cell));
|
|
4
|
+
function sanitizeRows(parsedRows) {
|
|
5
|
+
const firstSensicalRowIndex = parsedRows.findIndex(sensicalRowCheck);
|
|
6
|
+
const lastSensicalRowIndex = [...parsedRows]
|
|
7
|
+
.reverse()
|
|
8
|
+
.findIndex(sensicalRowCheck);
|
|
9
|
+
if (firstSensicalRowIndex < 0) {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
const sanitizedRows = [...parsedRows].splice(firstSensicalRowIndex, parsedRows.length - firstSensicalRowIndex - lastSensicalRowIndex);
|
|
13
|
+
return sanitizedRows;
|
|
14
|
+
}
|
|
15
|
+
exports.default = sanitizeRows;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare type ProcessingEntry = {
|
|
2
|
+
isValid: boolean;
|
|
3
|
+
};
|
|
4
|
+
declare type Dependencies<T extends ProcessingEntry> = {
|
|
5
|
+
processRow: (cells: string[], headers: string[]) => T;
|
|
6
|
+
};
|
|
7
|
+
export declare const hasHeaderRow: (rows: string[][], requiredHeaderNames: string[]) => boolean;
|
|
8
|
+
export declare const isHeaderRowValid: (rows: string[][], requiredHeaderNames: string[]) => boolean;
|
|
9
|
+
declare function parseFile<T extends ProcessingEntry>(fileContent: string, maxRows: number, requiredHeaderNames: string[], dependencies: Dependencies<T>): Promise<T[]>;
|
|
10
|
+
export default parseFile;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.isHeaderRowValid = exports.hasHeaderRow = void 0;
|
|
16
|
+
/* eslint-disable no-await-in-loop */
|
|
17
|
+
/* eslint-disable no-restricted-syntax */
|
|
18
|
+
const parse_row_1 = __importDefault(require("./parse-row"));
|
|
19
|
+
const errors_1 = require("./errors");
|
|
20
|
+
const sanitize_rows_1 = __importDefault(require("./sanitize-rows"));
|
|
21
|
+
function chunk(array, size) {
|
|
22
|
+
if (!array.length) {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
const head = array.slice(0, size);
|
|
26
|
+
const tail = array.slice(size);
|
|
27
|
+
return [head, ...chunk(tail, size)];
|
|
28
|
+
}
|
|
29
|
+
function processChunk(parsedRows, dependencies) {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
const { processRow, headers } = dependencies;
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
setTimeout(() => {
|
|
35
|
+
try {
|
|
36
|
+
const processedRows = parsedRows.map((row) => processRow(row, headers));
|
|
37
|
+
resolve(processedRows);
|
|
38
|
+
}
|
|
39
|
+
catch (ex) {
|
|
40
|
+
// @ts-ignore
|
|
41
|
+
reject(ex);
|
|
42
|
+
}
|
|
43
|
+
}, 0);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
// a row is said to contain headers if two valid header names are present
|
|
48
|
+
exports.hasHeaderRow = (rows, requiredHeaderNames) => {
|
|
49
|
+
const firstRow = rows[0];
|
|
50
|
+
if (!firstRow) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
const foundIndex = firstRow.findIndex((value) => requiredHeaderNames.includes(value.toLowerCase()));
|
|
54
|
+
if (foundIndex < 0) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
const containsSecondHeader = firstRow
|
|
58
|
+
.filter((_val, i) => i !== foundIndex)
|
|
59
|
+
.some((value) => requiredHeaderNames.includes(value.toLowerCase()));
|
|
60
|
+
return containsSecondHeader;
|
|
61
|
+
};
|
|
62
|
+
exports.isHeaderRowValid = (rows, requiredHeaderNames) => {
|
|
63
|
+
const firstRow = rows[0];
|
|
64
|
+
if (!firstRow) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
return (requiredHeaderNames.every((header) => firstRow.map((value) => value.toLowerCase()).includes(header)) && requiredHeaderNames.length === firstRow.length);
|
|
68
|
+
};
|
|
69
|
+
function parseFile(fileContent, maxRows, requiredHeaderNames, dependencies) {
|
|
70
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
if (fileContent === 'invalidFileType') {
|
|
72
|
+
throw new errors_1.InvalidFileError();
|
|
73
|
+
}
|
|
74
|
+
const rows = fileContent.split('\n');
|
|
75
|
+
const parsedRows = rows.map(parse_row_1.default);
|
|
76
|
+
const sanitizedRows = sanitize_rows_1.default(parsedRows);
|
|
77
|
+
if (sanitizedRows.length > maxRows) {
|
|
78
|
+
throw new errors_1.TooManyRowsError();
|
|
79
|
+
}
|
|
80
|
+
if (sanitizedRows.length === 0) {
|
|
81
|
+
throw new errors_1.NoRowsError();
|
|
82
|
+
}
|
|
83
|
+
const containsHeaders = exports.hasHeaderRow(sanitizedRows, requiredHeaderNames);
|
|
84
|
+
if (containsHeaders
|
|
85
|
+
&& !exports.isHeaderRowValid(sanitizedRows, requiredHeaderNames)) {
|
|
86
|
+
throw new errors_1.InvalidHeadersError();
|
|
87
|
+
}
|
|
88
|
+
const firstSanitizedRow = sanitizedRows[0];
|
|
89
|
+
if (!firstSanitizedRow) {
|
|
90
|
+
throw new errors_1.NoRowsError();
|
|
91
|
+
}
|
|
92
|
+
const headers = containsHeaders
|
|
93
|
+
? firstSanitizedRow.map((value) => value.toLowerCase())
|
|
94
|
+
: requiredHeaderNames;
|
|
95
|
+
const dataRows = containsHeaders ? sanitizedRows.splice(1) : sanitizedRows;
|
|
96
|
+
if (dataRows.length === 0) {
|
|
97
|
+
throw new errors_1.NoRowsError();
|
|
98
|
+
}
|
|
99
|
+
const parsedRowChunks = chunk(dataRows, 30);
|
|
100
|
+
let results = [];
|
|
101
|
+
for (const currentRowChunk of parsedRowChunks) {
|
|
102
|
+
const chunkResult = yield processChunk(currentRowChunk, Object.assign(Object.assign({}, dependencies), { headers }));
|
|
103
|
+
results = results.concat(chunkResult);
|
|
104
|
+
}
|
|
105
|
+
return results;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
exports.default = parseFile;
|
package/lib/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import formatting from './formatting/formatting';
|
|
|
5
5
|
import middleware from './middleware/middleware';
|
|
6
6
|
import ormHelpers from './orm-helpers/ormHelpers';
|
|
7
7
|
import fileParser from './file-parser/file-parser';
|
|
8
|
+
import structuredFileParser from './structured-file-parser/structured-file-parser';
|
|
8
9
|
|
|
9
10
|
export {
|
|
10
11
|
types,
|
|
@@ -12,6 +13,7 @@ export {
|
|
|
12
13
|
errors,
|
|
13
14
|
formatting,
|
|
14
15
|
fileParser,
|
|
16
|
+
structuredFileParser,
|
|
15
17
|
middleware,
|
|
16
18
|
ormHelpers,
|
|
17
19
|
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/* eslint-disable max-classes-per-file */
|
|
2
|
+
export class InvalidFileError extends Error {
|
|
3
|
+
constructor() {
|
|
4
|
+
super('Invalid file type');
|
|
5
|
+
this.name = 'InvalidFileError';
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export class TooManyRowsError extends Error {
|
|
9
|
+
constructor() {
|
|
10
|
+
super('More than configured number of rows imported');
|
|
11
|
+
this.name = 'TooManyRowsError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class NoRowsError extends Error {
|
|
15
|
+
constructor() {
|
|
16
|
+
super('No rows');
|
|
17
|
+
this.name = 'NoRowsError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class InvalidHeadersError extends Error {
|
|
21
|
+
constructor() {
|
|
22
|
+
super('Invalid or incomplete headers list');
|
|
23
|
+
this.name = 'InvalidHeadersError';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { pipe } from 'lodash/fp';
|
|
2
|
+
|
|
3
|
+
const parseRow = (row: string): string[] => {
|
|
4
|
+
const trySplitByTab = (line: string | string[]): string | string[] => {
|
|
5
|
+
if (typeof line === 'string' && line.match('\t')) {
|
|
6
|
+
return line.split('\t');
|
|
7
|
+
}
|
|
8
|
+
return line;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const trySplitByComa = (line: string | string[]): string | string[] => {
|
|
12
|
+
if (typeof line === 'string' && line.match(',')) {
|
|
13
|
+
return line.split(',');
|
|
14
|
+
}
|
|
15
|
+
return line;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const trySplitByMultipleSpaces = (line: string | string[]): string | string[] => {
|
|
19
|
+
if (typeof line === 'string' && line.match(/ {3,}/)) {
|
|
20
|
+
return line.split(/ {3,}/);
|
|
21
|
+
}
|
|
22
|
+
return line;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const trySplitBySpace = (line: string | string[]): string | string[] => {
|
|
26
|
+
if (typeof line === 'string' && line.match(' ')) {
|
|
27
|
+
return line.split(' ');
|
|
28
|
+
}
|
|
29
|
+
return line;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const trySplitByNothing = (line: string | string[]): string[] => {
|
|
33
|
+
if (typeof line === 'string') {
|
|
34
|
+
return [line];
|
|
35
|
+
}
|
|
36
|
+
return line;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const splitRow = pipe(
|
|
40
|
+
trySplitByTab,
|
|
41
|
+
trySplitByComa,
|
|
42
|
+
trySplitByMultipleSpaces,
|
|
43
|
+
trySplitBySpace,
|
|
44
|
+
trySplitByNothing,
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const cells = splitRow(row);
|
|
48
|
+
|
|
49
|
+
return cells.map((c: string) => c.trim());
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export default parseRow;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const sensicalRowCheck = (cells: string[]): boolean => (
|
|
2
|
+
cells.some((cell: string) => !!cell)
|
|
3
|
+
);
|
|
4
|
+
|
|
5
|
+
function sanitizeRows(parsedRows: string[][]): string[][] {
|
|
6
|
+
const firstSensicalRowIndex = parsedRows.findIndex(sensicalRowCheck);
|
|
7
|
+
|
|
8
|
+
const lastSensicalRowIndex = [...parsedRows]
|
|
9
|
+
.reverse()
|
|
10
|
+
.findIndex(sensicalRowCheck);
|
|
11
|
+
|
|
12
|
+
if (firstSensicalRowIndex < 0) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const sanitizedRows = [...parsedRows].splice(
|
|
17
|
+
firstSensicalRowIndex,
|
|
18
|
+
parsedRows.length - firstSensicalRowIndex - lastSensicalRowIndex,
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
return sanitizedRows;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default sanitizeRows;
|