ffc-pay-etl-framework 0.0.10 → 0.0.11
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/README.md +51 -21
- package/dist/cjs/destinations/csvFileDestination.js +10 -0
- package/dist/cjs/destinations/postgresDestination.js +10 -0
- package/dist/cjs/lib/index.js +1 -1
- package/dist/cjs/loaders/csvloader.js +4 -1
- package/dist/cjs/types/destinations/csvFileDestination.d.ts.map +1 -1
- package/dist/cjs/types/destinations/postgresDestination.d.ts.map +1 -1
- package/dist/cjs/types/loaders/csvloader.d.ts.map +1 -1
- package/dist/esm/destinations/csvFileDestination.js +10 -0
- package/dist/esm/destinations/postgresDestination.js +10 -0
- package/dist/esm/lib/index.js +1 -1
- package/dist/esm/loaders/csvloader.js +4 -1
- package/dist/esm/types/destinations/csvFileDestination.d.ts.map +1 -1
- package/dist/esm/types/destinations/postgresDestination.d.ts.map +1 -1
- package/dist/esm/types/loaders/csvloader.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
## 🚀 Features
|
|
2
|
+
|
|
2
3
|
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
|
4
|
+
|
|
3
5
|
[](#contributors-)
|
|
6
|
+
|
|
4
7
|
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
|
8
|
+
|
|
5
9
|
- 💾 CSV Source and Destination
|
|
6
10
|
- 👮 Validators
|
|
7
11
|
- 🤖 Transformers
|
|
8
12
|
- 🚨 Error Checking
|
|
9
13
|
- 🐘 Write directly to Postgres
|
|
10
|
-
- 👨⚕️ Intellisense
|
|
14
|
+
- 👨⚕️ Intellisense
|
|
11
15
|
|
|
12
16
|
## 📦 Install
|
|
17
|
+
|
|
13
18
|
```bash
|
|
14
19
|
npm install --save-dev ffc-pay-etl-framework
|
|
15
20
|
```
|
|
@@ -18,30 +23,56 @@ npm install --save-dev ffc-pay-etl-framework
|
|
|
18
23
|
|
|
19
24
|
```js
|
|
20
25
|
// ESM
|
|
21
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
Etl,
|
|
28
|
+
Loaders,
|
|
29
|
+
Validators,
|
|
30
|
+
Transformers,
|
|
31
|
+
Destinations,
|
|
32
|
+
} from "ffc-pay-etl-framework";
|
|
22
33
|
|
|
23
34
|
// CJS
|
|
24
|
-
const {
|
|
35
|
+
const {
|
|
36
|
+
Etl,
|
|
37
|
+
Loaders,
|
|
38
|
+
Validators,
|
|
39
|
+
Transformers,
|
|
40
|
+
Destinations,
|
|
41
|
+
} = require("ffc-pay-etl-framework");
|
|
25
42
|
|
|
26
|
-
let csvFile = `${process.cwd()}/test/fixtures/SoilType.csv
|
|
43
|
+
let csvFile = `${process.cwd()}/test/fixtures/SoilType.csv`;
|
|
44
|
+
const spinner = new pkg.Spinner().start("Running ETL Pipeline");
|
|
27
45
|
|
|
28
|
-
const etl = new Etl.Etl()
|
|
46
|
+
const etl = new Etl.Etl();
|
|
29
47
|
|
|
30
48
|
etl
|
|
31
|
-
.loader(Loaders.CSVLoader({path: csvFile, columns: columns}))
|
|
32
|
-
.transform(
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
.
|
|
49
|
+
.loader(Loaders.CSVLoader({ path: csvFile, columns: columns }))
|
|
50
|
+
.transform(
|
|
51
|
+
Transformers.FakerTransformer({
|
|
52
|
+
columns: [
|
|
53
|
+
{
|
|
54
|
+
name: "Dist Name",
|
|
55
|
+
faker: "location.city",
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
})
|
|
59
|
+
)
|
|
60
|
+
.destination(
|
|
61
|
+
Destinations.CSVFileDestination({
|
|
62
|
+
fileName: "SoilType_Output.csv",
|
|
63
|
+
headers: true,
|
|
64
|
+
includeErrors: false,
|
|
65
|
+
quotationMarks: true,
|
|
66
|
+
})
|
|
67
|
+
)
|
|
68
|
+
.pump()
|
|
69
|
+
.on("finish", () => {
|
|
70
|
+
//Update spinner
|
|
71
|
+
spinner.succeed("ETL Pipeline - succeeded");
|
|
72
|
+
})
|
|
73
|
+
.on("result", (data) => {
|
|
74
|
+
console.log(data); // emits the last row with error information
|
|
75
|
+
});
|
|
45
76
|
```
|
|
46
77
|
|
|
47
78
|
## 📢 Shout outs
|
|
@@ -56,7 +87,6 @@ etl
|
|
|
56
87
|
|
|
57
88
|
Please make sure to read the [Contributing Guide](https://github.com/DEFRA/ffc-pay-etl-framework/blob/next/CONTRIBUTING.md) before making a pull request.
|
|
58
89
|
|
|
59
|
-
|
|
60
90
|
## Contributors ✨
|
|
61
91
|
|
|
62
92
|
Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):
|
|
@@ -87,4 +117,4 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d
|
|
|
87
117
|
|
|
88
118
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
|
89
119
|
|
|
90
|
-
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
|
120
|
+
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const EventEmitter = require('node:events');
|
|
2
|
+
const util = require('node:util');
|
|
1
3
|
const { Writable } = require("node:stream");
|
|
2
4
|
const fs = require("fs");
|
|
3
5
|
/**
|
|
@@ -10,6 +12,8 @@ const fs = require("fs");
|
|
|
10
12
|
* @returns Writable
|
|
11
13
|
*/
|
|
12
14
|
function CSVFileDestination(options) {
|
|
15
|
+
EventEmitter.call(this);
|
|
16
|
+
let lastChunk;
|
|
13
17
|
const fileName = options.fileName;
|
|
14
18
|
const headers = options.headers;
|
|
15
19
|
const includeErrors = options.includeErrors;
|
|
@@ -39,10 +43,16 @@ function CSVFileDestination(options) {
|
|
|
39
43
|
fs.writeFileSync(fileHandle, `${chunk.map(c => `"${c}"`).join(",")}\n`);
|
|
40
44
|
}
|
|
41
45
|
}
|
|
46
|
+
lastChunk = chunk;
|
|
47
|
+
callback();
|
|
48
|
+
},
|
|
49
|
+
final(callback) {
|
|
50
|
+
this.emit('result', lastChunk);
|
|
42
51
|
callback();
|
|
43
52
|
}
|
|
44
53
|
});
|
|
45
54
|
}
|
|
55
|
+
util.inherits(CSVFileDestination, EventEmitter);
|
|
46
56
|
module.exports = {
|
|
47
57
|
CSVFileDestination
|
|
48
58
|
};
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const EventEmitter = require('node:events');
|
|
2
|
+
const util = require('node:util');
|
|
1
3
|
const { Transform } = require('node:stream');
|
|
2
4
|
const { Sequelize } = require('sequelize');
|
|
3
5
|
const debug = require('debug')('destination');
|
|
@@ -16,6 +18,7 @@ const DEFAULT_PORT = 5432;
|
|
|
16
18
|
* @returns Transform
|
|
17
19
|
*/
|
|
18
20
|
function PostgresDestination(options) {
|
|
21
|
+
EventEmitter.call(this);
|
|
19
22
|
const table = options.table;
|
|
20
23
|
const username = options.username;
|
|
21
24
|
const password = options.password;
|
|
@@ -24,6 +27,7 @@ function PostgresDestination(options) {
|
|
|
24
27
|
const port = options.port || DEFAULT_PORT;
|
|
25
28
|
const mapping = options.mapping;
|
|
26
29
|
const includeErrors = options.includeErrors;
|
|
30
|
+
let lastChunk;
|
|
27
31
|
const sequelize = new Sequelize(database, username, password, {
|
|
28
32
|
host: host,
|
|
29
33
|
port: port,
|
|
@@ -91,11 +95,13 @@ function PostgresDestination(options) {
|
|
|
91
95
|
.then(result => {
|
|
92
96
|
debug('result %o', result);
|
|
93
97
|
chunk._result = result;
|
|
98
|
+
lastChunk = chunk;
|
|
94
99
|
// @ts-ignore
|
|
95
100
|
callback(null, chunk);
|
|
96
101
|
}).catch(error => {
|
|
97
102
|
debug('error %o', error);
|
|
98
103
|
chunk.errors.push(error);
|
|
104
|
+
lastChunk = chunk;
|
|
99
105
|
// @ts-ignore
|
|
100
106
|
callback(null, chunk);
|
|
101
107
|
});
|
|
@@ -103,6 +109,10 @@ function PostgresDestination(options) {
|
|
|
103
109
|
else {
|
|
104
110
|
debug('Chunk has errors %o', chunk);
|
|
105
111
|
}
|
|
112
|
+
},
|
|
113
|
+
final(callback) {
|
|
114
|
+
this.emit('result', lastChunk);
|
|
115
|
+
callback();
|
|
106
116
|
}
|
|
107
117
|
});
|
|
108
118
|
}
|
package/dist/cjs/lib/index.js
CHANGED
|
@@ -28,7 +28,7 @@ function Etl() {
|
|
|
28
28
|
this.pump = () => {
|
|
29
29
|
this.loader
|
|
30
30
|
.pump(this.loader)
|
|
31
|
-
.pipe(compose(RowMetaData(), ...self.validatorList, ...self.transformationList, ...self.destinationList)
|
|
31
|
+
.pipe(compose(RowMetaData(), ...self.validatorList, ...self.transformationList, ...self.destinationList.map(dl => dl.on('result', (data) => self.emit('result', data))))
|
|
32
32
|
// @ts-ignore
|
|
33
33
|
).on('finish', (data) => self.emit('finish', data));
|
|
34
34
|
return self;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const fs = require("fs");
|
|
3
3
|
const { Transform } = require("stream");
|
|
4
4
|
const { parse } = require("csv-parse");
|
|
5
|
-
const { stdout } = require("process");
|
|
5
|
+
const { stdout, stderr } = require("process");
|
|
6
6
|
/**
|
|
7
7
|
*
|
|
8
8
|
* @param {Object} options
|
|
@@ -11,6 +11,7 @@ const { stdout } = require("process");
|
|
|
11
11
|
*/
|
|
12
12
|
function CSVLoader(options) {
|
|
13
13
|
let csvLoader = fs.createReadStream(options.path);
|
|
14
|
+
let lineCount = 1;
|
|
14
15
|
csvLoader._columns = options.columns;
|
|
15
16
|
csvLoader.pump = (csvLoader) => {
|
|
16
17
|
return csvLoader
|
|
@@ -21,6 +22,8 @@ function CSVLoader(options) {
|
|
|
21
22
|
emitClose: true,
|
|
22
23
|
transform(chunk, _, callback) {
|
|
23
24
|
chunk["_columns"] = options.columns;
|
|
25
|
+
chunk["_linecount"] = lineCount;
|
|
26
|
+
lineCount += 1;
|
|
24
27
|
callback(null, chunk);
|
|
25
28
|
}
|
|
26
29
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"csvFileDestination.d.ts","sourceRoot":"","sources":["../../../../src/destinations/csvFileDestination.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"csvFileDestination.d.ts","sourceRoot":"","sources":["../../../../src/destinations/csvFileDestination.js"],"names":[],"mappings":"AAKA;;;;;;;;GAQG;AACH,4CANG;IAAwB,QAAQ;IACP,OAAO;IACP,aAAa;IACb,cAAc;CACvC,YAwCF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgresDestination.d.ts","sourceRoot":"","sources":["../../../../src/destinations/postgresDestination.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"postgresDestination.d.ts","sourceRoot":"","sources":["../../../../src/destinations/postgresDestination.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;GAYG;AACH,6CAVG;IAAwB,KAAK;IACL,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,IAAI;IACJ,IAAI;IACJ,OAAO;IACP,aAAa;CACrC,aAoGF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"csvloader.d.ts","sourceRoot":"","sources":["../../../../src/loaders/csvloader.js"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,mCAHG;IAAwB,IAAI;CAC5B,
|
|
1
|
+
{"version":3,"file":"csvloader.d.ts","sourceRoot":"","sources":["../../../../src/loaders/csvloader.js"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,mCAHG;IAAwB,IAAI;CAC5B,iBAuBF"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
const EventEmitter = require('node:events');
|
|
3
|
+
const util = require('node:util');
|
|
2
4
|
const { Writable } = require("node:stream");
|
|
3
5
|
const fs = require("fs");
|
|
4
6
|
/**
|
|
@@ -11,6 +13,8 @@ const fs = require("fs");
|
|
|
11
13
|
* @returns Writable
|
|
12
14
|
*/
|
|
13
15
|
function CSVFileDestination(options) {
|
|
16
|
+
EventEmitter.call(this);
|
|
17
|
+
let lastChunk;
|
|
14
18
|
const fileName = options.fileName;
|
|
15
19
|
const headers = options.headers;
|
|
16
20
|
const includeErrors = options.includeErrors;
|
|
@@ -40,10 +44,16 @@ function CSVFileDestination(options) {
|
|
|
40
44
|
fs.writeFileSync(fileHandle, `${chunk.map(c => `"${c}"`).join(",")}\n`);
|
|
41
45
|
}
|
|
42
46
|
}
|
|
47
|
+
lastChunk = chunk;
|
|
48
|
+
callback();
|
|
49
|
+
},
|
|
50
|
+
final(callback) {
|
|
51
|
+
this.emit('result', lastChunk);
|
|
43
52
|
callback();
|
|
44
53
|
}
|
|
45
54
|
});
|
|
46
55
|
}
|
|
56
|
+
util.inherits(CSVFileDestination, EventEmitter);
|
|
47
57
|
module.exports = {
|
|
48
58
|
CSVFileDestination
|
|
49
59
|
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
const EventEmitter = require('node:events');
|
|
3
|
+
const util = require('node:util');
|
|
2
4
|
const { Transform } = require('node:stream');
|
|
3
5
|
const { Sequelize } = require('sequelize');
|
|
4
6
|
const debug = require('debug')('destination');
|
|
@@ -17,6 +19,7 @@ const DEFAULT_PORT = 5432;
|
|
|
17
19
|
* @returns Transform
|
|
18
20
|
*/
|
|
19
21
|
function PostgresDestination(options) {
|
|
22
|
+
EventEmitter.call(this);
|
|
20
23
|
const table = options.table;
|
|
21
24
|
const username = options.username;
|
|
22
25
|
const password = options.password;
|
|
@@ -25,6 +28,7 @@ function PostgresDestination(options) {
|
|
|
25
28
|
const port = options.port || DEFAULT_PORT;
|
|
26
29
|
const mapping = options.mapping;
|
|
27
30
|
const includeErrors = options.includeErrors;
|
|
31
|
+
let lastChunk;
|
|
28
32
|
const sequelize = new Sequelize(database, username, password, {
|
|
29
33
|
host: host,
|
|
30
34
|
port: port,
|
|
@@ -92,11 +96,13 @@ function PostgresDestination(options) {
|
|
|
92
96
|
.then(result => {
|
|
93
97
|
debug('result %o', result);
|
|
94
98
|
chunk._result = result;
|
|
99
|
+
lastChunk = chunk;
|
|
95
100
|
// @ts-ignore
|
|
96
101
|
callback(null, chunk);
|
|
97
102
|
}).catch(error => {
|
|
98
103
|
debug('error %o', error);
|
|
99
104
|
chunk.errors.push(error);
|
|
105
|
+
lastChunk = chunk;
|
|
100
106
|
// @ts-ignore
|
|
101
107
|
callback(null, chunk);
|
|
102
108
|
});
|
|
@@ -104,6 +110,10 @@ function PostgresDestination(options) {
|
|
|
104
110
|
else {
|
|
105
111
|
debug('Chunk has errors %o', chunk);
|
|
106
112
|
}
|
|
113
|
+
},
|
|
114
|
+
final(callback) {
|
|
115
|
+
this.emit('result', lastChunk);
|
|
116
|
+
callback();
|
|
107
117
|
}
|
|
108
118
|
});
|
|
109
119
|
}
|
package/dist/esm/lib/index.js
CHANGED
|
@@ -29,7 +29,7 @@ function Etl() {
|
|
|
29
29
|
this.pump = () => {
|
|
30
30
|
this.loader
|
|
31
31
|
.pump(this.loader)
|
|
32
|
-
.pipe(compose(RowMetaData(), ...self.validatorList, ...self.transformationList, ...self.destinationList)
|
|
32
|
+
.pipe(compose(RowMetaData(), ...self.validatorList, ...self.transformationList, ...self.destinationList.map(dl => dl.on('result', (data) => self.emit('result', data))))
|
|
33
33
|
// @ts-ignore
|
|
34
34
|
).on('finish', (data) => self.emit('finish', data));
|
|
35
35
|
return self;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const fs = require("fs");
|
|
4
4
|
const { Transform } = require("stream");
|
|
5
5
|
const { parse } = require("csv-parse");
|
|
6
|
-
const { stdout } = require("process");
|
|
6
|
+
const { stdout, stderr } = require("process");
|
|
7
7
|
/**
|
|
8
8
|
*
|
|
9
9
|
* @param {Object} options
|
|
@@ -12,6 +12,7 @@ const { stdout } = require("process");
|
|
|
12
12
|
*/
|
|
13
13
|
function CSVLoader(options) {
|
|
14
14
|
let csvLoader = fs.createReadStream(options.path);
|
|
15
|
+
let lineCount = 1;
|
|
15
16
|
csvLoader._columns = options.columns;
|
|
16
17
|
csvLoader.pump = (csvLoader) => {
|
|
17
18
|
return csvLoader
|
|
@@ -22,6 +23,8 @@ function CSVLoader(options) {
|
|
|
22
23
|
emitClose: true,
|
|
23
24
|
transform(chunk, _, callback) {
|
|
24
25
|
chunk["_columns"] = options.columns;
|
|
26
|
+
chunk["_linecount"] = lineCount;
|
|
27
|
+
lineCount += 1;
|
|
25
28
|
callback(null, chunk);
|
|
26
29
|
}
|
|
27
30
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"csvFileDestination.d.ts","sourceRoot":"","sources":["../../../../src/destinations/csvFileDestination.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"csvFileDestination.d.ts","sourceRoot":"","sources":["../../../../src/destinations/csvFileDestination.js"],"names":[],"mappings":"AAKA;;;;;;;;GAQG;AACH,4CANG;IAAwB,QAAQ;IACP,OAAO;IACP,aAAa;IACb,cAAc;CACvC,YAwCF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgresDestination.d.ts","sourceRoot":"","sources":["../../../../src/destinations/postgresDestination.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"postgresDestination.d.ts","sourceRoot":"","sources":["../../../../src/destinations/postgresDestination.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;GAYG;AACH,6CAVG;IAAwB,KAAK;IACL,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,IAAI;IACJ,IAAI;IACJ,OAAO;IACP,aAAa;CACrC,aAoGF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"csvloader.d.ts","sourceRoot":"","sources":["../../../../src/loaders/csvloader.js"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,mCAHG;IAAwB,IAAI;CAC5B,
|
|
1
|
+
{"version":3,"file":"csvloader.d.ts","sourceRoot":"","sources":["../../../../src/loaders/csvloader.js"],"names":[],"mappings":"AAMA;;;;;GAKG;AACH,mCAHG;IAAwB,IAAI;CAC5B,iBAuBF"}
|