Skip to content

Commit

Permalink
Linting (#55)
Browse files Browse the repository at this point in the history
* Adding eslint

* Linter remediation

* refactoring with async/await

* Adding more explicit types that are not 'any'
  • Loading branch information
eebbesen authored Nov 29, 2023
1 parent e56b310 commit c33d69f
Show file tree
Hide file tree
Showing 18 changed files with 8,775 additions and 3,165 deletions.
31 changes: 31 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module.exports = {
"env": {
"browser": true,
"commonjs": true,
"es2021": true
},
"extends": "standard-with-typescript",
"overrides": [
{
"env": {
"node": true
},
"files": [
".eslintrc.{js,cjs}"
],
"parserOptions": {
"sourceType": "script"
}
}
],
"parserOptions": {
"ecmaVersion": "latest"
},
"ignorePatterns": [
".eslintrc.js"
],
"rules": {
"semi": "off",
"@typescript-eslint/semi": "warn"
}
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ out
# Nuxt.js build / generate output
.nuxt
dist
distProd

# Gatsby files
.cache/
Expand Down
11,150 changes: 8,317 additions & 2,833 deletions package-lock.json

Large diffs are not rendered by default.

25 changes: 23 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"name": "eulagy",
"version": "3.2.0",
"version": "3.2.1",
"description": "EULAgy takes a text file, converts it to an mp3 and generates a csv based on the Amazon Comprehend findings",
"main": "src/app.ts",
"scripts": {
"lint": "eslint --ext .js,.ts",
"test": "jest safe",
"liveTest": "jest",
"zpack_x": "bash ./scripts/package.sh;"
Expand All @@ -15,14 +16,34 @@
"@aws-sdk/client-comprehend": "^3.454.0",
"@aws-sdk/client-polly": "^3.454.0",
"@aws-sdk/client-s3": "^3.456.0",
"@types/aws-lambda": "^8.10.129",
"@types/jest": "^29.5.10",
"@typescript-eslint/eslint-plugin": "^6.4.0",
"@typescript-eslint/parser": "^6.13.1",
"eslint": "^8.0.1",
"eslint-config-standard-with-typescript": "^40.0.0",
"eslint-plugin-import": "^2.25.2",
"eslint-plugin-n": "^15.0.0",
"jest": "^29.7.0",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"typescript": "^5.3.2"
},
"dependencies": {
"npm-cli": "^0.1.0",
"typescript-logging": "^2.1.0",
"typescript-logging-log4ts-style": "^2.1.0"
}
},
"directories": {
"doc": "docs",
"test": "test"
},
"repository": {
"type": "git",
"url": "git+https://github.com/eebbesen/eulagy.git"
},
"bugs": {
"url": "https://github.com/eebbesen/eulagy/issues"
},
"homepage": "https://github.com/eebbesen/eulagy#readme"
}
7 changes: 4 additions & 3 deletions scripts/package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
echo 'removing node_modules'
rm -rf node_modules/*
npm install --omit=dev
echo 'running tsc to generate .js files'
tsc
echo 'running tsc to generate .js files for prod only'
rm -rf distProd/*
tsc -p tsconfig.prod.json
export VER=`grep version package.json | perl -nle 'print $& if m{\\d.\\d.\\d}'`
zip -r builds/eulagy-$VER.zip package.json node_modules
zip -j builds/eulagy-$VER.zip dist/*.js
zip -j builds/eulagy-$VER.zip distProd/*.js
npm install
94 changes: 48 additions & 46 deletions src/app.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,62 @@
import * as BucketUtils from './bucketUtils';
import * as Utils from './utils';
import * as PollyUtils from './pollyUtils';
import * as ComprehendUtils from './comprehendUtils';
import { StartSpeechSynthesisTaskOutput } from '@aws-sdk/client-polly';
import { log4TSProvider } from './config/LogConfig';
import * as BucketUtils from './bucketUtils'
import * as Utils from './utils'
import * as PollyUtils from './pollyUtils'
import * as ComprehendUtils from './comprehendUtils'
import { type StartSpeechSynthesisTaskCommandOutput } from '@aws-sdk/client-polly'
import { type DeleteObjectCommandOutput, type GetObjectCommandOutput, type PutObjectCommandOutput } from '@aws-sdk/client-s3'
import { type DetectKeyPhrasesCommandOutput } from '@aws-sdk/client-comprehend'
import { type S3Event } from 'aws-lambda'

const log = log4TSProvider.getLogger('App');
import { log4TSProvider } from './config/LogConfig'

export function handler(event: any) {
log.info('incoming event', JSON.stringify(event));
const rec: any = event.Records[0];
const fileName: string = rec.s3.object.key;
log.info('processing file', fileName);
const log = log4TSProvider.getLogger('App')

let text: string | undefined;
let createDetailsMp3: any;
let createDetailsCsv: any;
export async function handler (event: S3Event): Promise<StartSpeechSynthesisTaskCommandOutput> {
log.info('incoming event', JSON.stringify(event))
const rec: S3Event['Records'] = event.Records
const fileName: string = rec[0].s3.object.key
log.info('processing file', fileName)

return BucketUtils.downloadFile(fileName)
.then((data: any) => {
return data?.Body?.transformToString();
let text: string | undefined
let createDetailsMp3: StartSpeechSynthesisTaskCommandOutput
let createDetailsCsv: PutObjectCommandOutput

return await BucketUtils.downloadFile(fileName)
.then(async (data: GetObjectCommandOutput) => {
return await data?.Body?.transformToString()
})
.then((eulaText: string | undefined) => {
log.debug('EULA text is', eulaText);
.then(async (eulaText: string | undefined) => {
log.debug('EULA text is', eulaText)
if (eulaText?.length === 0) {
throw new Error(`No content for file ${fileName}`);
throw new Error(`No content for file ${fileName}`)
}
text = eulaText;
// raise Exception unless eulaText has value
// const chunks: RegExpMatchArray | null | undefined = eulaText?.match(/[\s\S]{1,2999}/g)
const chunks: any = eulaText?.match(/[\s\S]{1,2999}/g);
return PollyUtils.startSynthesizeSpeech(chunks);
text = eulaText
const chunks: RegExpMatchArray = Utils.chunkText(eulaText, 2999)
return await PollyUtils.startSynthesizeSpeech(chunks)
})
.then((mp3Generation: StartSpeechSynthesisTaskOutput | null) => {
createDetailsMp3 = mp3Generation;
log.debug('mp3 file location', JSON.stringify(mp3Generation));
.then((mp3Generation: StartSpeechSynthesisTaskCommandOutput) => {
createDetailsMp3 = mp3Generation
log.debug('mp3 file location', JSON.stringify(mp3Generation))
})
.then((ret: any) => {
const chunks: RegExpMatchArray | null | undefined = text?.match(/[\s\S]{1,4900}/g);
.then(async () => {
const chunks: RegExpMatchArray = Utils.chunkText(text, 4900)
// raise error if chunks has no value
return ComprehendUtils.detectKeyPhrases(chunks);
return await ComprehendUtils.detectKeyPhrases(chunks)
})
.then(async (kp: DetectKeyPhrasesCommandOutput) => {
const vals = Utils.sortEntriesByValues(kp.KeyPhrases)
const csv = Utils.mapToCsv(vals)
return await BucketUtils
.uploadFile(`uploaded/${fileName.replace('txt', 'csv')}`, csv)
})
.then((kp: any) => {
const vals = Utils.sortEntriesByValues(kp?.KeyPhrases);
const csv = Utils.mapToCsv(vals);
return BucketUtils
.uploadFile(`uploaded/${fileName.replace('txt', 'csv')}`, csv);
.then(async (uploadCsv: PutObjectCommandOutput) => {
createDetailsCsv = uploadCsv
log.debug('uploaded CSV file', JSON.stringify(uploadCsv))
return await BucketUtils.deleteFile(fileName)
})
.then((uploadCsv: any) => {
createDetailsCsv = uploadCsv;
log.debug('uploaded CSV file', JSON.stringify(uploadCsv));
return BucketUtils.deleteFile(fileName);
.then((cdMp3: DeleteObjectCommandOutput) => {
console.log('mp3 file details', JSON.stringify(createDetailsMp3))
console.log('CSV file details', JSON.stringify(createDetailsCsv))
return createDetailsMp3
})
.then((cdMp3: any) => {
console.log('mp3 file details', JSON.stringify(createDetailsMp3));
console.log('CSV file details', JSON.stringify(createDetailsCsv));
return createDetailsMp3;
});
};
96 changes: 39 additions & 57 deletions src/bucketUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,87 +2,69 @@ import {
S3Client,
CreateBucketCommand,
DeleteObjectCommand,
DeleteObjectCommandOutput,
type DeleteObjectCommandOutput,
GetObjectCommand,
GetObjectCommandOutput,
type GetObjectCommandOutput,
ListBucketsCommand,
ListBucketsCommandOutput,
type ListBucketsCommandOutput,
ListObjectsCommand,
ListObjectsCommandOutput,
type ListObjectsCommandOutput,
PutObjectCommand,
PutObjectCommandOutput
} from '@aws-sdk/client-s3';
import FsPromises from 'fs/promises';
import { log4TSProvider } from './config/LogConfig';
type PutObjectCommandOutput
} from '@aws-sdk/client-s3'
import { log4TSProvider } from './config/LogConfig'

const log = log4TSProvider.getLogger('BucketUtils');
const client = new S3Client({});
const log = log4TSProvider.getLogger('BucketUtils')
const client = new S3Client({})

export function listBuckets(): Promise<ListBucketsCommandOutput> {
return client.send(new ListBucketsCommand({}));
export async function listBuckets (): Promise<ListBucketsCommandOutput> {
return await client.send(new ListBucketsCommand({}))
};

export function createBucket(name: string): void {
const bucketName = name || 'eulagy';
export function createBucket (name: string): void {
const bucketName = (name.length > 0) ? name : 'eulagy'

listBuckets()
.then(bs => {
bs['Buckets']?.forEach(b => {
if (b['Name'] === bucketName) {
log.warn(`${bucketName} already exists!`);
return true;
bs.Buckets?.forEach(b => {
if (b.Name === bucketName) {
log.warn(`${bucketName} already exists!`)
return true
}
});
})

log.info(`Will create ${bucketName}`);
log.info(`Will create ${bucketName}`)
})
.then(() => {
const createBucketCommand = new CreateBucketCommand({ Bucket: bucketName });
.then(async () => {
const createBucketCommand = new CreateBucketCommand({ Bucket: bucketName })

client.send(createBucketCommand);
return await client.send(createBucketCommand)
})
.catch((error: Error) => {
log.error(error.message)
})
.catch((error: any) => {
log.error(error);
});
};

// lists files in S3 bucket
export function listBucketFiles(name: string): Promise<ListObjectsCommandOutput> {
const bucketName = name || 'eulagy';
const listObjectsCommand = new ListObjectsCommand({ Bucket: bucketName });
return client.send(listObjectsCommand);
export async function listBucketFiles (name: string): Promise<ListObjectsCommandOutput> {
const bucketName = (name.length > 0) ? name : 'eulagy'
const listObjectsCommand = new ListObjectsCommand({ Bucket: bucketName })
return await client.send(listObjectsCommand)
};

export function downloadFile(name: string): Promise<GetObjectCommandOutput> {
const getObjectCommand = new GetObjectCommand({ Bucket: 'eulagy', Key: name, RequestPayer: 'requester' });
return client.send(getObjectCommand);
export async function downloadFile (name: string): Promise<GetObjectCommandOutput> {
const getObjectCommand = new GetObjectCommand({ Bucket: 'eulagy', Key: name, RequestPayer: 'requester' })
return await client.send(getObjectCommand)
}

export function deleteFile(name: string): Promise<DeleteObjectCommandOutput> {
const deleteObjectCommand = new DeleteObjectCommand({ Bucket: 'eulagy', Key: name });
return client.send(deleteObjectCommand);
export async function deleteFile (name: string): Promise<DeleteObjectCommandOutput> {
const deleteObjectCommand = new DeleteObjectCommand({ Bucket: 'eulagy', Key: name })
return await client.send(deleteObjectCommand)
};

// uploads one file to S3 bucket
export function uploadFile(name: string, data: any): Promise<PutObjectCommandOutput> {
log.debug(`file ${name} size is ${data.readableLength}`);
const putObjectCommand = new PutObjectCommand({ Bucket: 'eulagy', Key: name, Body: data, ContentLength: data.readableLength });
return client.send(putObjectCommand);
export async function uploadFile (name: string, data: string): Promise<PutObjectCommandOutput> {
log.debug(`file ${name} size is ${data.length}`)
const putObjectCommand = new PutObjectCommand({ Bucket: 'eulagy', Key: name, Body: data, ContentLength: data.length })
return await client.send(putObjectCommand)
}

// uploads all files in a dir to S3 bucket
export function uploadFiles(): Promise<void | string[]> {
return FsPromises.readdir('output')
.then((files: any) => {
files.forEach((f: any) => {
FsPromises.readFile(`output/${f}`)
.then((buffer: Buffer) => {
uploadFile(f, buffer)
.then(() => { console.log(`Uploaded ${f}`); });
});
})
.catch((error: any) => {
log.error(error);
});
});
};
32 changes: 16 additions & 16 deletions src/comprehendUtils.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
import {
ComprehendClient,
DetectKeyPhrasesCommand,
DetectKeyPhrasesCommandOutput,
type DetectKeyPhrasesCommandOutput,
DetectSentimentCommand,
DetectSentimentCommandOutput
} from '@aws-sdk/client-comprehend';
type DetectSentimentCommandOutput
} from '@aws-sdk/client-comprehend'

const comprehendClient = new ComprehendClient({});
const comprehendClient = new ComprehendClient({})

export function detectSentiment(text: RegExpMatchArray | null): Promise<DetectSentimentCommandOutput> | null {
if (!text) {
throw new Error('Empty text');
export async function detectSentiment (text: RegExpMatchArray): Promise<DetectSentimentCommandOutput> {
if (text == null) {
throw new Error('Empty text in detectSentiment')
}
const command = new DetectSentimentCommand({
LanguageCode: 'en',
Text: text![0]
});
return comprehendClient.send(command);
Text: text[0]
})
return await comprehendClient.send(command)
};

export function detectKeyPhrases(text: RegExpMatchArray | null | undefined): Promise<DetectKeyPhrasesCommandOutput> | null {
if (!text) {
throw new Error('Empty text');
export async function detectKeyPhrases (text: RegExpMatchArray): Promise<DetectKeyPhrasesCommandOutput> {
if (text == null) {
throw new Error('Empty text in detectKeyPhrases')
}
const command = new DetectKeyPhrasesCommand({
LanguageCode: 'en',
Text: text![0]
});
return comprehendClient.send(command);
Text: text[0]
})
return await comprehendClient.send(command)
};
Loading

0 comments on commit c33d69f

Please sign in to comment.