@bitblit/ratchet-aws-node-only 4.0.115-alpha → 4.0.119-alpha

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,115 +0,0 @@
1
- import fs from 'fs';
2
- import walk from 'walk';
3
- import { S3Client } from '@aws-sdk/client-s3';
4
- import path from 'path';
5
- import mime from 'mime-types';
6
- import { Logger } from '@bitblit/ratchet-common/lib/logger/logger.js';
7
- import { Upload } from '@aws-sdk/lib-storage';
8
- export class SiteUploader {
9
- srcDir;
10
- bucketName;
11
- config;
12
- s3 = new S3Client({ region: 'us-east-1' });
13
- constructor(srcDir, bucketName, configFile) {
14
- this.srcDir = srcDir;
15
- this.bucketName = bucketName;
16
- this.config = JSON.parse(fs.readFileSync(configFile).toString('ascii'));
17
- }
18
- static createFromArgs(args) {
19
- if (args && args.length === 3) {
20
- const src = args[0];
21
- const bucket = args[1];
22
- const configFile = args[2];
23
- return new SiteUploader(src, bucket, configFile);
24
- }
25
- else {
26
- console.log('Usage : node ratchet-site-uploader {srcDir} {bucket} {configFile} (Found ' + args + ' arguments, need 3)');
27
- return null;
28
- }
29
- }
30
- static async runFromCliArgs(args) {
31
- const inst = SiteUploader.createFromArgs(args);
32
- return inst.runPump();
33
- }
34
- findMatch(prefix, fileName, config) {
35
- let found = null;
36
- if (prefix != null && fileName != null && config != null && config.mapping != null) {
37
- config.mapping.forEach((entry) => {
38
- if (found == null) {
39
- if (entry.prefixMatch == null || prefix.match(entry.prefixMatch)) {
40
- if (entry.fileMatch == null || fileName.match(entry.fileMatch)) {
41
- found = entry;
42
- }
43
- }
44
- }
45
- });
46
- }
47
- return found;
48
- }
49
- findMime(fileName, config) {
50
- let found = null;
51
- if (config != null && config.customMimeTypeMapping != null) {
52
- Object.keys(config.customMimeTypeMapping).forEach((k) => {
53
- if (found == null && fileName.endsWith(k)) {
54
- found = config.customMimeTypeMapping[k];
55
- }
56
- });
57
- }
58
- if (found == null) {
59
- found = mime.lookup(fileName);
60
- }
61
- if (found == null) {
62
- found = 'binary/octet-stream';
63
- }
64
- return found;
65
- }
66
- runPump() {
67
- return new Promise((resolve, reject) => {
68
- Logger.info('Uploading contents of %s to %s using %j as config', this.srcDir, this.bucketName, this.config);
69
- const options = {};
70
- const walker = walk.walk(this.srcDir, options);
71
- walker.on('file', function (root, fileStats, next) {
72
- Logger.info('Processing %j', fileStats.name);
73
- const prefix = root == this.srcDir ? '' : root.substring(this.srcDir.length + 1) + '/';
74
- const proc = this.findMatch(prefix, fileStats.name, this.config);
75
- const key = prefix + fileStats.name;
76
- Logger.info('Uploading file : %s/%s to key %s with %j', root, fileStats.name, key, proc);
77
- const params = proc && proc.putParams ? JSON.parse(JSON.stringify(proc.putParams)) : {};
78
- params.Bucket = this.bucketName;
79
- params.Key = key;
80
- params.Body = fs.readFileSync(path.join(root, fileStats.name));
81
- if (!params.ContentType) {
82
- params.ContentType = this.findMime(fileStats.name, this.config);
83
- }
84
- const upload = new Upload({
85
- client: this.s3,
86
- params: params,
87
- tags: [],
88
- queueSize: 4,
89
- partSize: 1024 * 1024 * 5,
90
- leavePartsOnError: false,
91
- });
92
- upload.on('httpUploadProgress', (progress) => {
93
- Logger.info('Uploading : %s', progress);
94
- });
95
- upload
96
- .done()
97
- .then((result) => {
98
- Logger.info('Finished upload of %s: %j', key, result);
99
- next();
100
- })
101
- .catch((err) => {
102
- Logger.warn('%s failed to upload : %s : Continuing', key, err);
103
- next();
104
- });
105
- }.bind(this));
106
- walker.on('errors', function (root, nodeStatsArray, next) {
107
- next();
108
- });
109
- walker.on('end', function () {
110
- Logger.info('All done');
111
- resolve(true);
112
- });
113
- });
114
- }
115
- }
@@ -1,68 +0,0 @@
1
- import { Logger } from '@bitblit/ratchet-common/lib/logger/logger.js';
2
- import { Ec2Ratchet } from '@bitblit/ratchet-aws/lib/ec2/ec2-ratchet.js';
3
- import { spawnSync } from 'child_process';
4
- import fs from 'fs';
5
- import os from 'os';
6
- import path from 'path';
7
- export class StartInstanceAndSsh {
8
- instanceId;
9
- publicKeyFile;
10
- instanceOsUser;
11
- region;
12
- availabilityZone;
13
- ec2Ratchet;
14
- constructor(instanceId, publicKeyFile = path.join(os.homedir(), '.ssh', 'id_rsa.pub'), instanceOsUser = 'ec2-user', region = 'us-east-1', availabilityZone = 'us-east-1a') {
15
- this.instanceId = instanceId;
16
- this.publicKeyFile = publicKeyFile;
17
- this.instanceOsUser = instanceOsUser;
18
- this.region = region;
19
- this.availabilityZone = availabilityZone;
20
- this.ec2Ratchet = new Ec2Ratchet(this.region, this.availabilityZone);
21
- }
22
- static createFromArgs(args) {
23
- if (args?.length === 1 || args?.length === 2) {
24
- const instanceId = args[0];
25
- return new StartInstanceAndSsh(instanceId);
26
- }
27
- else {
28
- Logger.info('Usage : ratchet-start-instance-and-ssh {instanceId} {publicKeyFile} (Found %s arguments, need 1 or 2)', args);
29
- return null;
30
- }
31
- }
32
- static async runFromCliArgs(args) {
33
- const inst = StartInstanceAndSsh.createFromArgs(args);
34
- return inst.run();
35
- }
36
- async run() {
37
- let instance = await this.ec2Ratchet.describeInstance(this.instanceId);
38
- if (!!instance) {
39
- let launched = false;
40
- if (instance.State.Code == 16) {
41
- Logger.info('Instance is already running...');
42
- launched = true;
43
- }
44
- else {
45
- Logger.info('Instance is not running... starting up : %s', this.instanceId);
46
- launched = await this.ec2Ratchet.launchInstance(this.instanceId, 1000 * 30);
47
- }
48
- if (launched) {
49
- Logger.info('Uploading public key...');
50
- const publicKeyText = fs.readFileSync(this.publicKeyFile).toString();
51
- const publicKeyResponse = await this.ec2Ratchet.sendPublicKeyToEc2Instance(this.instanceId, publicKeyText, this.instanceOsUser);
52
- Logger.info('Key response : %j', publicKeyResponse);
53
- instance = instance && instance.PublicIpAddress ? instance : await this.ec2Ratchet.describeInstance(this.instanceId);
54
- Logger.info('Instance IP address is %s', instance.PublicIpAddress);
55
- const ret = spawnSync('ssh', [this.instanceOsUser + '@' + instance.PublicIpAddress], {
56
- stdio: 'inherit',
57
- });
58
- Logger.info('%j', ret);
59
- }
60
- else {
61
- Logger.info('Instance could not start - check logs');
62
- }
63
- }
64
- else {
65
- Logger.info('No such instance found - check your AWS keys? : %s', this.instanceId);
66
- }
67
- }
68
- }
package/lib/index.js DELETED
@@ -1 +0,0 @@
1
- export {};
@@ -1,89 +0,0 @@
1
- import { RequireRatchet } from '@bitblit/ratchet-common/lib/lang/require-ratchet.js';
2
- import { Logger } from '@bitblit/ratchet-common/lib/logger/logger.js';
3
- import { MultiStream } from '@bitblit/ratchet-common/lib/stream/multi-stream.js';
4
- import unzipper from 'unzipper';
5
- import { CsvRatchet } from '@bitblit/ratchet-node-only/lib/csv/csv-ratchet.js';
6
- import { DateTime } from 'luxon';
7
- export class EmailToDbInsertProcessor {
8
- canProcess(mail) {
9
- return true;
10
- }
11
- async processEmail(msg) {
12
- const rval = [];
13
- try {
14
- RequireRatchet.notNullOrUndefined(msg, 'msg');
15
- Logger.info('Processing Broadsign reach inbound inventory email');
16
- const data = msg.attachments[0].content;
17
- Logger.info('Unzipping attachment');
18
- const rs = new MultiStream(data);
19
- let wBuf = null;
20
- const prom = rs
21
- .pipe(unzipper.Parse())
22
- .on('entry', async (entry) => {
23
- if (entry.path.toLowerCase().endsWith('csv')) {
24
- wBuf = await entry.buffer();
25
- }
26
- else {
27
- Logger.info('Pass: %s', entry.path);
28
- entry.autodrain();
29
- }
30
- })
31
- .promise();
32
- await prom;
33
- const csvParsed = await CsvRatchet.stringParse(wBuf.toString(), (o) => o, {
34
- columns: false,
35
- skip_empty_lines: true,
36
- });
37
- if (csvParsed.length > 1) {
38
- const dropTable = 'drop table if exists sample';
39
- let createTable = 'create table sample (pump_date varchar(255),';
40
- const colNames = csvParsed[0];
41
- let insertPrefix = 'insert into sample (pump_date,';
42
- let insertQ = '?,';
43
- for (let i = 0; i < colNames.length; i++) {
44
- if (i > 0) {
45
- createTable += ', ';
46
- insertPrefix += ', ';
47
- insertQ += ', ';
48
- }
49
- const kOut = colNames[i].toLowerCase().split(' ').join('_');
50
- insertPrefix += kOut;
51
- insertQ += '?';
52
- createTable += kOut + ' varchar(255)';
53
- if (kOut === 'id') {
54
- createTable += ' primary key';
55
- }
56
- else if (kOut === 'device_id') {
57
- createTable += ' unique';
58
- }
59
- }
60
- createTable += ')';
61
- insertPrefix += ') values ';
62
- Logger.info('Recreating table');
63
- const dropRes = rval.push({ statement: dropTable });
64
- const createRes = rval.push({ statement: createTable });
65
- const pumpDate = DateTime.utc().toISO();
66
- let insertStmt = insertPrefix;
67
- let insertParams = [];
68
- for (let i = 1; i < csvParsed.length; i++) {
69
- if (insertStmt > insertPrefix) {
70
- insertStmt += ',';
71
- }
72
- insertStmt += '(' + insertQ + ')';
73
- insertParams = insertParams.concat(pumpDate, csvParsed[i]);
74
- if (i % 25 === 0 || i === csvParsed.length - 1) {
75
- rval.push({ statement: insertStmt, params: insertParams });
76
- insertStmt = insertPrefix;
77
- insertParams = [];
78
- Logger.info('Inserted %d of %d rows', i, csvParsed.length);
79
- }
80
- }
81
- Logger.info('Finished insertion of %d rows', csvParsed.length);
82
- }
83
- }
84
- catch (err) {
85
- Logger.error('Failure: %s : %j', err, rval, err);
86
- }
87
- return rval;
88
- }
89
- }
@@ -1,41 +0,0 @@
1
- import { simpleParser } from 'mailparser';
2
- import { Logger } from '@bitblit/ratchet-common/lib/logger/logger.js';
3
- import { RequireRatchet } from '@bitblit/ratchet-common/lib/lang/require-ratchet.js';
4
- export class InboundEmailRatchet {
5
- cache;
6
- processors;
7
- constructor(cache, processors) {
8
- this.cache = cache;
9
- this.processors = processors;
10
- RequireRatchet.notNullOrUndefined(this.cache, 'cache');
11
- RequireRatchet.notNullOrUndefined(this.cache.getDefaultBucket(), 'cache.defaultBucket');
12
- }
13
- async processEmailFromS3(key) {
14
- const rval = false;
15
- if (await this.cache.fileExists(key)) {
16
- const data = await this.cache.fetchCacheFileAsString(key);
17
- return this.processEmailFromBuffer(new Buffer(data));
18
- }
19
- else {
20
- Logger.warn('Cannot process inbound email - no such key : %s', key);
21
- }
22
- return rval;
23
- }
24
- async processEmailFromBuffer(buf) {
25
- const rval = false;
26
- RequireRatchet.notNullOrUndefined(buf, 'buf');
27
- Logger.info('Processing inbound email - size %d bytes', buf.length);
28
- const message = await simpleParser(buf);
29
- Logger.info('Found mail from "%s" subject "%s" with %d attachments', message?.from?.text, message?.subject, message?.attachments?.length);
30
- let procd = false;
31
- for (let i = 0; i < this.processors.length && !procd; i++) {
32
- if (this.processors[i].canProcess(message)) {
33
- Logger.info('Processing message with processor %d', i);
34
- const result = await this.processors[i].processEmail(message);
35
- Logger.info('Result was : %j', result);
36
- procd = true;
37
- }
38
- }
39
- return procd;
40
- }
41
- }
@@ -1,18 +0,0 @@
1
- import { InboundEmailRatchet } from './inbound-email-ratchet.js';
2
- import { JestRatchet } from '@bitblit/ratchet-jest/lib/jest/jest-ratchet.js';
3
- import { jest } from '@jest/globals';
4
- import { SampleEmailProcessor } from './sample-email-processor.js';
5
- let mockS3CR;
6
- describe('#inboundEmailService', () => {
7
- beforeEach(() => {
8
- mockS3CR = JestRatchet.mock(jest.fn);
9
- });
10
- it('should process an email from S3', async () => {
11
- mockS3CR.getDefaultBucket.mockReturnValueOnce('TEST-BUCKET');
12
- mockS3CR.fileExists.mockResolvedValueOnce(true);
13
- mockS3CR.fetchCacheFileAsString.mockResolvedValue('TEST');
14
- const svc = new InboundEmailRatchet(mockS3CR, [new SampleEmailProcessor()]);
15
- const res = await svc.processEmailFromS3('some-key');
16
- expect(res).not.toBeUndefined();
17
- });
18
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,8 +0,0 @@
1
- export class SampleEmailProcessor {
2
- canProcess(mail) {
3
- return true;
4
- }
5
- async processEmail(msg) {
6
- return msg.body;
7
- }
8
- }