ffc-pay-etl-framework 0.0.1
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/LICENSE.md +24 -0
- package/README.md +55 -0
- package/dist/cjs/destinations/consoleDestination.js +21 -0
- package/dist/cjs/destinations/csvFileDestination.js +48 -0
- package/dist/cjs/destinations/index.js +11 -0
- package/dist/cjs/destinations/postgresDestination.js +67 -0
- package/dist/cjs/destinations/sqlFileDestination.js +64 -0
- package/dist/cjs/index.js +12 -0
- package/dist/cjs/lib/index.js +46 -0
- package/dist/cjs/lib/rowMetaData.js +23 -0
- package/dist/cjs/loaders/csvloader.js +31 -0
- package/dist/cjs/loaders/index.js +4 -0
- package/dist/cjs/transformers/fakerTransformer.js +39 -0
- package/dist/cjs/transformers/index.js +6 -0
- package/dist/cjs/transformers/toUpperCaseTransformer.js +24 -0
- package/dist/cjs/types/destinations/consoleDestination.d.ts +11 -0
- package/dist/cjs/types/destinations/consoleDestination.d.ts.map +1 -0
- package/dist/cjs/types/destinations/csvFileDestination.d.ts +17 -0
- package/dist/cjs/types/destinations/csvFileDestination.d.ts.map +1 -0
- package/dist/cjs/types/destinations/index.d.ts +7 -0
- package/dist/cjs/types/destinations/index.d.ts.map +1 -0
- package/dist/cjs/types/destinations/postgresDestination.d.ts +23 -0
- package/dist/cjs/types/destinations/postgresDestination.d.ts.map +1 -0
- package/dist/cjs/types/destinations/sqlFileDestination.d.ts +24 -0
- package/dist/cjs/types/destinations/sqlFileDestination.d.ts.map +1 -0
- package/dist/cjs/types/index.d.ts +7 -0
- package/dist/cjs/types/index.d.ts.map +1 -0
- package/dist/cjs/types/lib/index.d.ts +25 -0
- package/dist/cjs/types/lib/index.d.ts.map +1 -0
- package/dist/cjs/types/lib/rowMetaData.d.ts +3 -0
- package/dist/cjs/types/lib/rowMetaData.d.ts.map +1 -0
- package/dist/cjs/types/loaders/csvloader.d.ts +11 -0
- package/dist/cjs/types/loaders/csvloader.d.ts.map +1 -0
- package/dist/cjs/types/loaders/index.d.ts +3 -0
- package/dist/cjs/types/loaders/index.d.ts.map +1 -0
- package/dist/cjs/types/transformers/fakerTransformer.d.ts +37 -0
- package/dist/cjs/types/transformers/fakerTransformer.d.ts.map +1 -0
- package/dist/cjs/types/transformers/index.d.ts +4 -0
- package/dist/cjs/types/transformers/index.d.ts.map +1 -0
- package/dist/cjs/types/transformers/toUpperCaseTransformer.d.ts +23 -0
- package/dist/cjs/types/transformers/toUpperCaseTransformer.d.ts.map +1 -0
- package/dist/cjs/types/validators/index.d.ts +5 -0
- package/dist/cjs/types/validators/index.d.ts.map +1 -0
- package/dist/cjs/types/validators/multiToolValidator.d.ts +23 -0
- package/dist/cjs/types/validators/multiToolValidator.d.ts.map +1 -0
- package/dist/cjs/types/validators/requiredValidator.d.ts +13 -0
- package/dist/cjs/types/validators/requiredValidator.d.ts.map +1 -0
- package/dist/cjs/types/validators/uniqueValidator.d.ts +29 -0
- package/dist/cjs/types/validators/uniqueValidator.d.ts.map +1 -0
- package/dist/cjs/validators/index.js +8 -0
- package/dist/cjs/validators/multiToolValidator.js +48 -0
- package/dist/cjs/validators/requiredValidator.js +33 -0
- package/dist/cjs/validators/uniqueValidator.js +40 -0
- package/dist/esm/destinations/consoleDestination.js +22 -0
- package/dist/esm/destinations/csvFileDestination.js +49 -0
- package/dist/esm/destinations/index.js +12 -0
- package/dist/esm/destinations/postgresDestination.js +68 -0
- package/dist/esm/destinations/sqlFileDestination.js +65 -0
- package/dist/esm/index.mjs +13 -0
- package/dist/esm/lib/index.js +47 -0
- package/dist/esm/lib/rowMetaData.js +24 -0
- package/dist/esm/loaders/csvloader.js +32 -0
- package/dist/esm/loaders/index.js +5 -0
- package/dist/esm/transformers/fakerTransformer.js +40 -0
- package/dist/esm/transformers/index.js +7 -0
- package/dist/esm/transformers/toUpperCaseTransformer.js +25 -0
- package/dist/esm/types/destinations/consoleDestination.d.ts +11 -0
- package/dist/esm/types/destinations/consoleDestination.d.ts.map +1 -0
- package/dist/esm/types/destinations/csvFileDestination.d.ts +17 -0
- package/dist/esm/types/destinations/csvFileDestination.d.ts.map +1 -0
- package/dist/esm/types/destinations/index.d.ts +7 -0
- package/dist/esm/types/destinations/index.d.ts.map +1 -0
- package/dist/esm/types/destinations/postgresDestination.d.ts +23 -0
- package/dist/esm/types/destinations/postgresDestination.d.ts.map +1 -0
- package/dist/esm/types/destinations/sqlFileDestination.d.ts +24 -0
- package/dist/esm/types/destinations/sqlFileDestination.d.ts.map +1 -0
- package/dist/esm/types/index.d.ts +7 -0
- package/dist/esm/types/index.d.ts.map +1 -0
- package/dist/esm/types/lib/index.d.ts +25 -0
- package/dist/esm/types/lib/index.d.ts.map +1 -0
- package/dist/esm/types/lib/rowMetaData.d.ts +3 -0
- package/dist/esm/types/lib/rowMetaData.d.ts.map +1 -0
- package/dist/esm/types/loaders/csvloader.d.ts +11 -0
- package/dist/esm/types/loaders/csvloader.d.ts.map +1 -0
- package/dist/esm/types/loaders/index.d.ts +3 -0
- package/dist/esm/types/loaders/index.d.ts.map +1 -0
- package/dist/esm/types/transformers/fakerTransformer.d.ts +37 -0
- package/dist/esm/types/transformers/fakerTransformer.d.ts.map +1 -0
- package/dist/esm/types/transformers/index.d.ts +4 -0
- package/dist/esm/types/transformers/index.d.ts.map +1 -0
- package/dist/esm/types/transformers/toUpperCaseTransformer.d.ts +23 -0
- package/dist/esm/types/transformers/toUpperCaseTransformer.d.ts.map +1 -0
- package/dist/esm/types/validators/index.d.ts +5 -0
- package/dist/esm/types/validators/index.d.ts.map +1 -0
- package/dist/esm/types/validators/multiToolValidator.d.ts +23 -0
- package/dist/esm/types/validators/multiToolValidator.d.ts.map +1 -0
- package/dist/esm/types/validators/requiredValidator.d.ts +13 -0
- package/dist/esm/types/validators/requiredValidator.d.ts.map +1 -0
- package/dist/esm/types/validators/uniqueValidator.d.ts +29 -0
- package/dist/esm/types/validators/uniqueValidator.d.ts.map +1 -0
- package/dist/esm/validators/index.js +9 -0
- package/dist/esm/validators/multiToolValidator.js +49 -0
- package/dist/esm/validators/requiredValidator.js +34 -0
- package/dist/esm/validators/uniqueValidator.js +41 -0
- package/package.json +56 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/loaders/index.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {Object} options
|
|
4
|
+
* @param {Array} options.columns {
|
|
5
|
+
* columns: [
|
|
6
|
+
* {
|
|
7
|
+
* name: "column-name",
|
|
8
|
+
* faker: "company.name"
|
|
9
|
+
* }
|
|
10
|
+
* ]
|
|
11
|
+
* }
|
|
12
|
+
* @returns StreamReader
|
|
13
|
+
*/
|
|
14
|
+
export function FakerTransformer(options: {
|
|
15
|
+
columns: any[];
|
|
16
|
+
}): Transform;
|
|
17
|
+
export class FakerTransformer {
|
|
18
|
+
/**
|
|
19
|
+
*
|
|
20
|
+
* @param {Object} options
|
|
21
|
+
* @param {Array} options.columns {
|
|
22
|
+
* columns: [
|
|
23
|
+
* {
|
|
24
|
+
* name: "column-name",
|
|
25
|
+
* faker: "company.name"
|
|
26
|
+
* }
|
|
27
|
+
* ]
|
|
28
|
+
* }
|
|
29
|
+
* @returns StreamReader
|
|
30
|
+
*/
|
|
31
|
+
constructor(options: {
|
|
32
|
+
columns: any[];
|
|
33
|
+
});
|
|
34
|
+
columns: any[];
|
|
35
|
+
}
|
|
36
|
+
import { Transform } from "stream";
|
|
37
|
+
//# sourceMappingURL=fakerTransformer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fakerTransformer.d.ts","sourceRoot":"","sources":["../../../../src/transformers/fakerTransformer.js"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,0CAVG;IAAuB,OAAO;CAQ9B,aAsBF;;IAjCD;;;;;;;;;;;;OAYG;IACH,qBAVG;QAAuB,OAAO;KAQ9B,EAsBF;IAlBG,eAA8B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/transformers/index.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {Object} options
|
|
4
|
+
* @param {String} options.column
|
|
5
|
+
* @returns Writable
|
|
6
|
+
*/
|
|
7
|
+
export function ToUpperCaseTransformer(options: {
|
|
8
|
+
column: string;
|
|
9
|
+
}): Transform;
|
|
10
|
+
export class ToUpperCaseTransformer {
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param {Object} options
|
|
14
|
+
* @param {String} options.column
|
|
15
|
+
* @returns Writable
|
|
16
|
+
*/
|
|
17
|
+
constructor(options: {
|
|
18
|
+
column: string;
|
|
19
|
+
});
|
|
20
|
+
column: string;
|
|
21
|
+
}
|
|
22
|
+
import { Transform } from "stream";
|
|
23
|
+
//# sourceMappingURL=toUpperCaseTransformer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toUpperCaseTransformer.d.ts","sourceRoot":"","sources":["../../../../src/transformers/toUpperCaseTransformer.js"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,gDAHG;IAAwB,MAAM;CAC9B,aAgBF;;IApBD;;;;;OAKG;IACH,qBAHG;QAAwB,MAAM;KAC9B,EAgBF;IAZG,eAA4B"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { RequiredValidator } from "./requiredValidator";
|
|
2
|
+
import { UniqueValidator } from "./uniqueValidator";
|
|
3
|
+
import { MultiToolValidator } from "./multiToolValidator";
|
|
4
|
+
export { RequiredValidator, UniqueValidator, MultiToolValidator };
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/validators/index.js"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {Object} options
|
|
4
|
+
* @param {Array} options.columns { columns: [
|
|
5
|
+
* {
|
|
6
|
+
* name: "column-name",
|
|
7
|
+
* validator: "isAlphanumeric",
|
|
8
|
+
* args: {
|
|
9
|
+
* locale: "en-GB",
|
|
10
|
+
* options: {
|
|
11
|
+
* ignore: "-;%/ "
|
|
12
|
+
* }
|
|
13
|
+
* }
|
|
14
|
+
* }
|
|
15
|
+
* ]
|
|
16
|
+
* }
|
|
17
|
+
* @returns Writable
|
|
18
|
+
*/
|
|
19
|
+
export function MultiToolValidator(options: {
|
|
20
|
+
columns: any[];
|
|
21
|
+
}): Transform;
|
|
22
|
+
import { Transform } from "stream";
|
|
23
|
+
//# sourceMappingURL=multiToolValidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multiToolValidator.d.ts","sourceRoot":"","sources":["../../../../src/validators/multiToolValidator.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;GAiBG;AACH,4CAfG;IAAuB,OAAO;CAa9B,aAyBF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {Object} options
|
|
4
|
+
* @param {String} options.message
|
|
5
|
+
* @param {Array} options.columns
|
|
6
|
+
* @returns Transform
|
|
7
|
+
*/
|
|
8
|
+
export function RequiredValidator(options: {
|
|
9
|
+
message: string;
|
|
10
|
+
columns: any[];
|
|
11
|
+
}): Transform;
|
|
12
|
+
import { Transform } from "stream";
|
|
13
|
+
//# sourceMappingURL=requiredValidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requiredValidator.d.ts","sourceRoot":"","sources":["../../../../src/validators/requiredValidator.js"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,2CAJG;IAAwB,OAAO;IACR,OAAO;CAC9B,aAsBF"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {Object} options
|
|
4
|
+
* @param {String} options.message
|
|
5
|
+
* @param {String} options.column
|
|
6
|
+
* @returns Transform
|
|
7
|
+
*/
|
|
8
|
+
export function UniqueValidator(options: {
|
|
9
|
+
message: string;
|
|
10
|
+
column: string;
|
|
11
|
+
}): Transform;
|
|
12
|
+
export class UniqueValidator {
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param {Object} options
|
|
16
|
+
* @param {String} options.message
|
|
17
|
+
* @param {String} options.column
|
|
18
|
+
* @returns Transform
|
|
19
|
+
*/
|
|
20
|
+
constructor(options: {
|
|
21
|
+
message: string;
|
|
22
|
+
column: string;
|
|
23
|
+
});
|
|
24
|
+
column: string;
|
|
25
|
+
message: string;
|
|
26
|
+
uniqueColumnRows: any[];
|
|
27
|
+
}
|
|
28
|
+
import { Transform } from "stream";
|
|
29
|
+
//# sourceMappingURL=uniqueValidator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uniqueValidator.d.ts","sourceRoot":"","sources":["../../../../src/validators/uniqueValidator.js"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,yCAJG;IAAwB,OAAO;IACP,MAAM;CAC9B,aA6BF;;IAlCD;;;;;;OAMG;IACH,qBAJG;QAAwB,OAAO;QACP,MAAM;KAC9B,EA6BF;IAzBG,eAA4B;IAC5B,gBAAwF;IACxF,wBAA0B"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
const { RequiredValidator } = require("./requiredValidator");
|
|
2
|
+
const { UniqueValidator } = require("./uniqueValidator");
|
|
3
|
+
const { MultiToolValidator } = require("./multiToolValidator");
|
|
4
|
+
module.exports = {
|
|
5
|
+
RequiredValidator,
|
|
6
|
+
UniqueValidator,
|
|
7
|
+
MultiToolValidator
|
|
8
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
const { Transform } = require("stream");
|
|
3
|
+
const validator = require('validator');
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} options
|
|
7
|
+
* @param {Array} options.columns { columns: [
|
|
8
|
+
* {
|
|
9
|
+
* name: "column-name",
|
|
10
|
+
* validator: "isAlphanumeric",
|
|
11
|
+
* args: {
|
|
12
|
+
* locale: "en-GB",
|
|
13
|
+
* options: {
|
|
14
|
+
* ignore: "-;%/ "
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
* }
|
|
18
|
+
* ]
|
|
19
|
+
* }
|
|
20
|
+
* @returns Writable
|
|
21
|
+
*/
|
|
22
|
+
function MultiToolValidator(options) {
|
|
23
|
+
function getValidator(validatorType) {
|
|
24
|
+
return validator[validatorType];
|
|
25
|
+
}
|
|
26
|
+
return new Transform({
|
|
27
|
+
readableObjectMode: true,
|
|
28
|
+
writableObjectMode: true,
|
|
29
|
+
decodeStrings: false,
|
|
30
|
+
construct(callback) {
|
|
31
|
+
this.columns = options.columns;
|
|
32
|
+
callback();
|
|
33
|
+
},
|
|
34
|
+
transform(chunk, _, callback) {
|
|
35
|
+
const { _columns } = chunk;
|
|
36
|
+
this.columns.forEach(column => {
|
|
37
|
+
const colIndex = _columns.indexOf(column.name);
|
|
38
|
+
const vtr = getValidator(column.validator);
|
|
39
|
+
if (!vtr(chunk[colIndex], ...Object.values(column.args)))
|
|
40
|
+
chunk.errors.push(`${column.validator} returned invalid status in column ${colIndex}`);
|
|
41
|
+
});
|
|
42
|
+
callback(null, chunk);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
module.exports = {
|
|
47
|
+
MultiToolValidator
|
|
48
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
const { Transform } = require("stream");
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {Object} options
|
|
6
|
+
* @param {String} options.message
|
|
7
|
+
* @param {Array} options.columns
|
|
8
|
+
* @returns Transform
|
|
9
|
+
*/
|
|
10
|
+
function RequiredValidator(options) {
|
|
11
|
+
return new Transform({
|
|
12
|
+
readableObjectMode: true,
|
|
13
|
+
writableObjectMode: true,
|
|
14
|
+
decodeStrings: false,
|
|
15
|
+
construct(callback) {
|
|
16
|
+
this.message = options.message ? options.message : "Required value is null";
|
|
17
|
+
this.requiredColumns = options.columns;
|
|
18
|
+
callback();
|
|
19
|
+
},
|
|
20
|
+
transform(chunk, _, callback) {
|
|
21
|
+
this.requiredColumns.forEach(column => {
|
|
22
|
+
let requiredVal = chunk[column];
|
|
23
|
+
if (requiredVal === undefined || requiredVal === '') {
|
|
24
|
+
chunk.errors.push(`${this.message} in column ${column}`);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
callback(null, chunk);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
module.exports = {
|
|
32
|
+
RequiredValidator
|
|
33
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const { Transform } = require("node:stream");
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* @param {Object} options
|
|
5
|
+
* @param {String} options.message
|
|
6
|
+
* @param {String} options.column
|
|
7
|
+
* @returns Transform
|
|
8
|
+
*/
|
|
9
|
+
function UniqueValidator(options) {
|
|
10
|
+
let self = this;
|
|
11
|
+
self.column = options.column;
|
|
12
|
+
self.message = options.message ? options.message : "Expected unique value is not unique";
|
|
13
|
+
self.uniqueColumnRows = [];
|
|
14
|
+
function checkIsUnique(data) {
|
|
15
|
+
return self.uniqueColumnRows.indexOf(data) === -1;
|
|
16
|
+
}
|
|
17
|
+
return new Transform({
|
|
18
|
+
readableObjectMode: true,
|
|
19
|
+
writableObjectMode: true,
|
|
20
|
+
decodeStrings: false,
|
|
21
|
+
construct(callback) {
|
|
22
|
+
callback();
|
|
23
|
+
},
|
|
24
|
+
transform(chunk, _, callback) {
|
|
25
|
+
const { _columns } = chunk;
|
|
26
|
+
const colIndex = _columns.indexOf(self.column);
|
|
27
|
+
const uniqueValue = chunk[colIndex];
|
|
28
|
+
if (checkIsUnique(uniqueValue)) {
|
|
29
|
+
self.uniqueColumnRows.push(uniqueValue);
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
chunk.errors.push(`${self.message} ${self.column}`);
|
|
33
|
+
}
|
|
34
|
+
callback(null, chunk);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
module.exports = {
|
|
39
|
+
UniqueValidator
|
|
40
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const { Writable } = require("node:stream");
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {Object} options
|
|
6
|
+
* @param {String} options.includeErrors
|
|
7
|
+
* @returns Writable
|
|
8
|
+
*/
|
|
9
|
+
function ConsoleDestination(options) {
|
|
10
|
+
const includeErrors = options.includeErrors;
|
|
11
|
+
return new Writable({
|
|
12
|
+
objectMode: true,
|
|
13
|
+
write(chunk, _, callback) {
|
|
14
|
+
if (chunk.errors.length === 0 || includeErrors)
|
|
15
|
+
console.log(chunk);
|
|
16
|
+
callback();
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
module.exports = {
|
|
21
|
+
ConsoleDestination
|
|
22
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const { Writable } = require("node:stream");
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} options
|
|
7
|
+
* @param {String} options.fileName
|
|
8
|
+
* @param {Boolean} options.headers
|
|
9
|
+
* @param {Boolean} options.includeErrors
|
|
10
|
+
* @param {Boolean} options.quotationMarks
|
|
11
|
+
* @returns Writable
|
|
12
|
+
*/
|
|
13
|
+
function CSVFileDestination(options) {
|
|
14
|
+
const fileName = options.fileName;
|
|
15
|
+
const headers = options.headers;
|
|
16
|
+
const includeErrors = options.includeErrors;
|
|
17
|
+
const quotationMarks = options.quotationMarks;
|
|
18
|
+
let fileHandle;
|
|
19
|
+
fs.open(fileName, 'w+', ((error, fd) => {
|
|
20
|
+
fileHandle = fd;
|
|
21
|
+
}));
|
|
22
|
+
let headersWritten = false;
|
|
23
|
+
return new Writable({
|
|
24
|
+
objectMode: true,
|
|
25
|
+
write(chunk, _, callback) {
|
|
26
|
+
if (!headersWritten && headers) {
|
|
27
|
+
if (quotationMarks) {
|
|
28
|
+
fs.writeFileSync(fileHandle, `${chunk._columns.map(c => `"${c}"`).join(",")}\n`);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
fs.writeFileSync(fileHandle, `${chunk._columns.join(",")}\n`);
|
|
32
|
+
}
|
|
33
|
+
headersWritten = true;
|
|
34
|
+
}
|
|
35
|
+
if (chunk.errors.length === 0 || includeErrors) {
|
|
36
|
+
if (quotationMarks) {
|
|
37
|
+
fs.writeFileSync(fileHandle, `${chunk.map(c => `"${c}"`).join(",")}\n`);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
fs.writeFileSync(fileHandle, `${chunk.map(c => `"${c}"`).join(",")}\n`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
callback();
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
module.exports = {
|
|
48
|
+
CSVFileDestination
|
|
49
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const { ConsoleDestination } = require("./consoleDestination");
|
|
3
|
+
const { SQLFileDestination, SQL_MODE } = require("./sqlFileDestination");
|
|
4
|
+
const { CSVFileDestination } = require("./csvFileDestination");
|
|
5
|
+
const { PostgresDestination } = require("./postgresDestination");
|
|
6
|
+
module.exports = {
|
|
7
|
+
ConsoleDestination,
|
|
8
|
+
SQLFileDestination,
|
|
9
|
+
SQL_MODE,
|
|
10
|
+
CSVFileDestination,
|
|
11
|
+
PostgresDestination
|
|
12
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const { Transform } = require("node:stream");
|
|
3
|
+
const { Sequelize } = require('sequelize');
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} options
|
|
7
|
+
* @param {Object} options.table
|
|
8
|
+
* @param {Object} options.username
|
|
9
|
+
* @param {Object} options.password
|
|
10
|
+
* @param {Object} options.database
|
|
11
|
+
* @param {Object} options.host
|
|
12
|
+
* @param {Object} options.mapping
|
|
13
|
+
* @param {Object} options.includeErrors
|
|
14
|
+
* @returns Transform
|
|
15
|
+
*/
|
|
16
|
+
function PostgresDestination(options) {
|
|
17
|
+
const table = options.table;
|
|
18
|
+
const username = options.username;
|
|
19
|
+
const password = options.password;
|
|
20
|
+
const database = options.database;
|
|
21
|
+
const host = options.host;
|
|
22
|
+
const mapping = options.mapping;
|
|
23
|
+
const includeErrors = options.includeErrors;
|
|
24
|
+
const sequelize = new Sequelize(database, username, password, {
|
|
25
|
+
host: host,
|
|
26
|
+
dialect: 'postgres',
|
|
27
|
+
logging: false
|
|
28
|
+
});
|
|
29
|
+
sequelize.authenticate();
|
|
30
|
+
function getMappingForColumn(column) {
|
|
31
|
+
const [map] = mapping.filter(m => m.column === column);
|
|
32
|
+
return map;
|
|
33
|
+
}
|
|
34
|
+
function writeInsertStatement(chunk) {
|
|
35
|
+
let statement = `INSERT INTO ${table} (${chunk._columns.map(column => {
|
|
36
|
+
let mapping = getMappingForColumn(column);
|
|
37
|
+
return mapping ? mapping.targetColumn : column;
|
|
38
|
+
})
|
|
39
|
+
.join(",")}) VALUES (${chunk._columns.map((column, index) => {
|
|
40
|
+
let mapping = getMappingForColumn(column);
|
|
41
|
+
if (mapping.targetType === "varchar" || mapping.targetType === "char")
|
|
42
|
+
return `'${chunk[index]}'`;
|
|
43
|
+
return chunk[index];
|
|
44
|
+
})})`;
|
|
45
|
+
return statement;
|
|
46
|
+
}
|
|
47
|
+
return new Transform({
|
|
48
|
+
objectMode: true,
|
|
49
|
+
transform(chunk, _, callback) {
|
|
50
|
+
let insertStatement;
|
|
51
|
+
// @ts-ignore
|
|
52
|
+
if (chunk.errors.length === 0 | options.includeErrors) {
|
|
53
|
+
insertStatement = writeInsertStatement(chunk);
|
|
54
|
+
sequelize.query(insertStatement)
|
|
55
|
+
.then(result => {
|
|
56
|
+
chunk._result = result;
|
|
57
|
+
callback(null, chunk);
|
|
58
|
+
}).catch(error => {
|
|
59
|
+
chunk.errors.push(error);
|
|
60
|
+
callback(null, chunk);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
module.exports = {
|
|
67
|
+
PostgresDestination
|
|
68
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const { Writable } = require("node:stream");
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
/**
|
|
5
|
+
* @enum {number}
|
|
6
|
+
*/
|
|
7
|
+
const SQL_MODE = {
|
|
8
|
+
"INSERT_MODE": 1,
|
|
9
|
+
"UPDATE_MODE": 2
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param {Object} options
|
|
14
|
+
* @param {String} options.fileName
|
|
15
|
+
* @param {SQL_MODE} options.mode
|
|
16
|
+
* @param {String} options.table
|
|
17
|
+
* @param {Array} options.mapping
|
|
18
|
+
* @param {Boolean} options.includeErrors
|
|
19
|
+
* @returns Transform
|
|
20
|
+
*/
|
|
21
|
+
function SQLFileDestination(options) {
|
|
22
|
+
const fileName = options.fileName;
|
|
23
|
+
const sqlMode = options.mode;
|
|
24
|
+
const table = options.table;
|
|
25
|
+
const mapping = options.mapping;
|
|
26
|
+
const includeErrors = options.includeErrors;
|
|
27
|
+
function writeInsertStatement(chunk) {
|
|
28
|
+
let statement = `INSERT INTO ${table} (${mapping.map(m => m.targetColumn)
|
|
29
|
+
.join(",")}) VALUES (${mapping.map((m) => {
|
|
30
|
+
const srcColumnIndex = chunk._columns.indexOf(m.column);
|
|
31
|
+
if (m.targetType === "string")
|
|
32
|
+
return `'${chunk[srcColumnIndex]}'`;
|
|
33
|
+
return chunk[srcColumnIndex];
|
|
34
|
+
})});\n`;
|
|
35
|
+
fs.writeFileSync(fileName, statement, {
|
|
36
|
+
encoding: "utf8",
|
|
37
|
+
flag: "a+"
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function writeUpdateStatement(chunk) {
|
|
41
|
+
}
|
|
42
|
+
return new Writable({
|
|
43
|
+
objectMode: true,
|
|
44
|
+
write(chunk, _, callback) {
|
|
45
|
+
if (chunk.errors.length === 0)
|
|
46
|
+
if (sqlMode === SQL_MODE.INSERT_MODE) {
|
|
47
|
+
// @ts-ignore
|
|
48
|
+
if (chunk.errors.length === 0 | includeErrors) {
|
|
49
|
+
writeInsertStatement(chunk);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else if (sqlMode === SQL_MODE.UPDATE_MODE) {
|
|
53
|
+
// @ts-ignore
|
|
54
|
+
if (chunk.errors.length === 0 | includeErrors) {
|
|
55
|
+
writeUpdateStatement(chunk);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
callback();
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
module.exports = {
|
|
63
|
+
SQLFileDestination,
|
|
64
|
+
SQL_MODE
|
|
65
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const Validators = require("./validators");
|
|
3
|
+
const Transformers = require("./transformers");
|
|
4
|
+
const Loaders = require("./loaders");
|
|
5
|
+
const Destinations = require("./destinations");
|
|
6
|
+
const Etl = require("./lib");
|
|
7
|
+
module.exports = {
|
|
8
|
+
Etl,
|
|
9
|
+
Validators,
|
|
10
|
+
Transformers,
|
|
11
|
+
Loaders,
|
|
12
|
+
Destinations,
|
|
13
|
+
};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
const { RowMetaData } = require("./rowMetaData");
|
|
4
|
+
const { compose } = require("node:stream");
|
|
5
|
+
/**
|
|
6
|
+
* @typedef {Object} Etl
|
|
7
|
+
* @function loader
|
|
8
|
+
* @function pump
|
|
9
|
+
* @function validator
|
|
10
|
+
* @function destination
|
|
11
|
+
* @function transform
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @returns Etl
|
|
16
|
+
*/
|
|
17
|
+
function Etl() {
|
|
18
|
+
let self = this;
|
|
19
|
+
self.validatorList = [];
|
|
20
|
+
self.transformationList = [];
|
|
21
|
+
self.destinationList = [];
|
|
22
|
+
this.loader = (loader) => {
|
|
23
|
+
self.loader = loader;
|
|
24
|
+
return self;
|
|
25
|
+
};
|
|
26
|
+
this.pump = () => {
|
|
27
|
+
this.loader
|
|
28
|
+
.pump(this.loader)
|
|
29
|
+
.pipe(compose(RowMetaData, ...self.validatorList, ...self.transformationList, ...self.destinationList));
|
|
30
|
+
};
|
|
31
|
+
this.validator = (validator) => {
|
|
32
|
+
self.validatorList.push(validator);
|
|
33
|
+
return self;
|
|
34
|
+
};
|
|
35
|
+
this.destination = (destination) => {
|
|
36
|
+
self.destinationList.push(destination);
|
|
37
|
+
return self;
|
|
38
|
+
};
|
|
39
|
+
this.transform = (transform) => {
|
|
40
|
+
self.transformationList.push(transform);
|
|
41
|
+
return self;
|
|
42
|
+
};
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
module.exports = {
|
|
46
|
+
Etl
|
|
47
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
const { Transform } = require("stream");
|
|
4
|
+
const util = require("util");
|
|
5
|
+
function RowMetaData(options) {
|
|
6
|
+
return new Transform({
|
|
7
|
+
readableObjectMode: true,
|
|
8
|
+
writableObjectMode: true,
|
|
9
|
+
decodeStrings: false,
|
|
10
|
+
construct(callback) {
|
|
11
|
+
this.rowId = 0;
|
|
12
|
+
callback();
|
|
13
|
+
},
|
|
14
|
+
transform(chunk, _, callback) {
|
|
15
|
+
chunk['_rowId'] = this.rowId;
|
|
16
|
+
chunk['errors'] = [];
|
|
17
|
+
this.rowId += 1;
|
|
18
|
+
callback(null, chunk);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
module.exports = {
|
|
23
|
+
RowMetaData
|
|
24
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// @ts-nocheck
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const { Transform } = require("stream");
|
|
5
|
+
const { parse } = require("csv-parse");
|
|
6
|
+
const { stdout } = require("process");
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @param {Object} options
|
|
10
|
+
* @param {String} options.path
|
|
11
|
+
* @returns StreamReader
|
|
12
|
+
*/
|
|
13
|
+
function CSVLoader(options) {
|
|
14
|
+
let csvLoader = fs.createReadStream(options.path);
|
|
15
|
+
csvLoader._columns = options.columns;
|
|
16
|
+
csvLoader.pump = (csvLoader) => {
|
|
17
|
+
return csvLoader
|
|
18
|
+
.pipe(parse({ delimiter: ",", from_line: 2 }))
|
|
19
|
+
.pipe(new Transform({
|
|
20
|
+
readableObjectMode: true,
|
|
21
|
+
writableObjectMode: true,
|
|
22
|
+
transform(chunk, _, callback) {
|
|
23
|
+
chunk["_columns"] = options.columns;
|
|
24
|
+
callback(null, chunk);
|
|
25
|
+
}
|
|
26
|
+
}));
|
|
27
|
+
};
|
|
28
|
+
return csvLoader;
|
|
29
|
+
}
|
|
30
|
+
module.exports = {
|
|
31
|
+
CSVLoader
|
|
32
|
+
};
|