diff --git a/packages/alexa/package.json b/packages/alexa/package.json index 5bcada3..f9e9c3d 100644 --- a/packages/alexa/package.json +++ b/packages/alexa/package.json @@ -13,7 +13,6 @@ "ask-sdk-core": "^2.11.0", "ask-sdk-express-adapter": "^2.14.0", "ask-sdk-model": "^1.36.1", - "aws-sdk": "^2.950.0", "date-fns": "4.1.0", "graphql": "^16.11.0", "graphql-request": "^7.2.0", diff --git a/packages/backend/package.json b/packages/backend/package.json index ce509bc..e267764 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -12,10 +12,13 @@ "test": "jest" }, "dependencies": { + "@aws-sdk/client-dynamodb": "3.864.0", + "@aws-sdk/client-lambda": "3.864.0", + "@aws-sdk/lib-dynamodb": "3.864.0", + "@aws-sdk/util-dynamodb": "3.864.0", "@graphql-tools/schema": "^10.0.25", "@lara/api": "^1.0.0", "apollo-server-lambda": "^3.13.0", - "aws-sdk": "^2.950.0", "casual": "^1.6.2", "cors": "^2.8.5", "date-fns": "4.1.0", diff --git a/packages/backend/src/aws/lambda.ts b/packages/backend/src/aws/lambda.ts index f925265..fc151eb 100644 --- a/packages/backend/src/aws/lambda.ts +++ b/packages/backend/src/aws/lambda.ts @@ -1,5 +1,5 @@ import { EmailPayload, PrintPayload } from '@lara/api' -import { Lambda } from 'aws-sdk' +import { Lambda } from '@aws-sdk/client-lambda' const { IS_OFFLINE, PRINT_FUNCTION, EMAIL_FUNCTION } = process.env @@ -31,11 +31,9 @@ type LambdaOptions = { functionName: 'email'; payload: EmailPayload } | { functi * @param functionName Defines between print and email Lambda */ export const invokeLambda = async ({ functionName, payload }: LambdaOptions): Promise => { - await lambda - .invoke({ - FunctionName: functionNameMapping[functionName], - InvocationType: 'Event', - Payload: JSON.stringify(payload), - }) - .promise() + await lambda.invoke({ + FunctionName: functionNameMapping[functionName], + InvocationType: 'Event', + Payload: JSON.stringify(payload), + }) } diff --git a/packages/backend/src/aws/s3.ts b/packages/backend/src/aws/s3.ts index d2ab741..f41ff9a 100644 --- a/packages/backend/src/aws/s3.ts +++ b/packages/backend/src/aws/s3.ts @@ -1,5 +1,4 @@ -import { S3, Endpoint, AWSError } from 'aws-sdk' -import { PromiseResult } from 'aws-sdk/lib/request' +import { S3Client, PutObjectCommand, PutObjectCommandOutput } from '@aws-sdk/client-s3' const { IS_OFFLINE, EXPORT_BUCKET } = process.env @@ -7,23 +6,25 @@ if (!EXPORT_BUCKET) { throw new Error("Missing env Var: 'EXPORT_BUCKET'") } -const s3Client = new S3( +const s3Client = new S3Client( IS_OFFLINE ? { - s3ForcePathStyle: true, - accessKeyId: 'S3RVER', // This specific key is required when working offline - secretAccessKey: 'S3RVER', - endpoint: new Endpoint('http://localhost:8181'), + forcePathStyle: true, + credentials: { + accessKeyId: 'S3RVER', // This specific key is required when working offline + secretAccessKey: 'S3RVER', + }, + endpoint: 'http://localhost:8181', } : { region: 'eu-central-1' } ) -export const saveExport = (key: string, body: string): Promise> => { - return s3Client - .putObject({ - Bucket: EXPORT_BUCKET, - Key: key, - Body: body, - }) - .promise() +export const saveExport = async (key: string, body: string): Promise => { + const command = new PutObjectCommand({ + Bucket: EXPORT_BUCKET, + Key: key, + Body: body, + }) + + return await s3Client.send(command) } diff --git a/packages/backend/src/db/batch.ts b/packages/backend/src/db/batch.ts index 8cdb188..1458ba1 100644 --- a/packages/backend/src/db/batch.ts +++ b/packages/backend/src/db/batch.ts @@ -1,4 +1,4 @@ -import { DocumentClient } from 'aws-sdk/clients/dynamodb' +import { BatchWriteCommand, BatchWriteCommandInput } from '@aws-sdk/lib-dynamodb' import { dbClient } from './ddb' @@ -9,12 +9,22 @@ import { dbClient } from './ddb' * @param items max. 25 request items * @returns true if success */ -export const batchWriteItem = async (items: DocumentClient.BatchWriteItemInput['RequestItems']): Promise => { - const res = await dbClient().batchWrite({ RequestItems: items }).promise() +export const batchWriteItem = async (items: BatchWriteCommandInput['RequestItems']): Promise => { + const client = dbClient() + try { + const res = await client.send( + new BatchWriteCommand({ + RequestItems: items, + }) + ) - if (res.$response.error) { + if (res.UnprocessedItems && Object.keys(res.UnprocessedItems).length > 0) { + console.warn('Some items were unprocessed:', res.UnprocessedItems) + } + + return true + } catch (err) { + console.error('Error batch writing to DB:', err) throw new Error('Error batch writing to DB') } - - return true } diff --git a/packages/backend/src/db/ddb.ts b/packages/backend/src/db/ddb.ts index a0d7cab..af51d19 100644 --- a/packages/backend/src/db/ddb.ts +++ b/packages/backend/src/db/ddb.ts @@ -1,4 +1,5 @@ -import { DocumentClient } from 'aws-sdk/clients/dynamodb' +import { DynamoDBClient } from '@aws-sdk/client-dynamodb' +import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb' const { IS_OFFLINE } = process.env @@ -11,19 +12,19 @@ const params = IS_OFFLINE } : {} -let cacheClient: DocumentClient +let cachedClient: DynamoDBDocumentClient /** * Creates a new DB client or returns the * already created client * @returns The DB client */ -export const dbClient = (): DocumentClient => { - if (!cacheClient) { - cacheClient = new DocumentClient(params) +export const dbClient = (): DynamoDBDocumentClient => { + if (!cachedClient) { + cachedClient = DynamoDBDocumentClient.from(new DynamoDBClient(params)) } - return cacheClient + return cachedClient } /** diff --git a/packages/backend/src/db/delete.ts b/packages/backend/src/db/delete.ts index 7b769c3..d5eb612 100644 --- a/packages/backend/src/db/delete.ts +++ b/packages/backend/src/db/delete.ts @@ -1,4 +1,4 @@ -import { DocumentClient } from 'aws-sdk/clients/dynamodb' +import { DeleteCommand, DeleteCommandInput } from '@aws-sdk/lib-dynamodb' import { dbClient } from './ddb' @@ -9,12 +9,18 @@ import { dbClient } from './ddb' * @param key Key of DDB item * @returns true if success */ -export const deleteItem = async (tableName: string, key: DocumentClient.Key): Promise => { - const res = await dbClient().delete({ TableName: tableName, Key: key }).promise() - - if (res.$response.error) { +export const deleteItem = async (tableName: string, key: DeleteCommandInput['Key']): Promise => { + const client = dbClient() + try { + await client.send( + new DeleteCommand({ + TableName: tableName, + Key: key, + }) + ) + return true + } catch (err) { + console.error('Error deleting item from DB:', err) throw new Error('Error deleting item from DB') } - - return true } diff --git a/packages/backend/src/db/get.ts b/packages/backend/src/db/get.ts index 7ceb6e0..e185bb0 100644 --- a/packages/backend/src/db/get.ts +++ b/packages/backend/src/db/get.ts @@ -1,4 +1,4 @@ -import { DocumentClient } from 'aws-sdk/clients/dynamodb' +import { GetCommand, GetCommandInput } from '@aws-sdk/lib-dynamodb' import { dbClient } from './ddb' @@ -9,12 +9,18 @@ import { dbClient } from './ddb' * @param key Identifier of the DDB item * @returns Item from DB */ -export const getItem = async (tablename: string, key: DocumentClient.Key): Promise => { - const res = await dbClient().get({ TableName: tablename, Key: key }).promise() - - if (res.$response.error || !res.Item) { +export const getItem = async (tablename: string, key: GetCommandInput['Key']): Promise => { + const client = dbClient() + try { + const res = await client.send( + new GetCommand({ + TableName: tablename, + Key: key, + }) + ) + return res.Item as T | undefined + } catch (err) { + console.error('Error fetching item from DDB:', err) return undefined } - - return res.Item as T } diff --git a/packages/backend/src/db/put.ts b/packages/backend/src/db/put.ts index f02c475..50307ed 100644 --- a/packages/backend/src/db/put.ts +++ b/packages/backend/src/db/put.ts @@ -1,4 +1,4 @@ -import { DocumentClient } from 'aws-sdk/clients/dynamodb' +import { PutCommand } from '@aws-sdk/lib-dynamodb' import { dbClient } from './ddb' @@ -9,12 +9,18 @@ import { dbClient } from './ddb' * @param input DDB put options * @returns The input if successfull */ -export const putItem = async (tableName: string, input: DocumentClient.PutItemInputAttributeMap): Promise => { - const res = await dbClient().put({ TableName: tableName, Item: input }).promise() - - if (res.$response.error) { - throw new Error('Error putting into DB') +export const putItem = async >(tableName: string, input: T): Promise => { + const client = dbClient() + try { + await client.send( + new PutCommand({ + TableName: tableName, + Item: input, + }) + ) + return input + } catch (error) { + console.error('Error putting Item into DB', error) + throw new Error('Error putting Item into DB') } - - return input as T } diff --git a/packages/backend/src/db/query.ts b/packages/backend/src/db/query.ts index 354b0ea..4b86a1f 100644 --- a/packages/backend/src/db/query.ts +++ b/packages/backend/src/db/query.ts @@ -1,4 +1,4 @@ -import { DocumentClient } from 'aws-sdk/clients/dynamodb' +import { QueryCommand, QueryCommandInput } from '@aws-sdk/lib-dynamodb' import { Keys } from '../utils/object' import { @@ -15,15 +15,17 @@ import { * @param options DDB Query Options * @returns Queried items */ -const queryItems = async ( - tablename: string, - options: Omit -): Promise => { - const res = await dbClient() - .query({ ...options, TableName: tablename }) - .promise() +const queryItems = async (tablename: string, options: Omit): Promise => { + const client = dbClient() + + const res = await client.send( + new QueryCommand({ + TableName: tablename, + ...options, + }) + ) - if (res.$response.error || !res.Items) { + if (!res.Items) { return [] } diff --git a/packages/backend/src/db/scan.ts b/packages/backend/src/db/scan.ts index 2704a25..4240d75 100644 --- a/packages/backend/src/db/scan.ts +++ b/packages/backend/src/db/scan.ts @@ -1,4 +1,4 @@ -import { DocumentClient } from 'aws-sdk/clients/dynamodb' +import { ScanCommand, ScanCommandInput } from '@aws-sdk/lib-dynamodb' import { dbClient } from './ddb' @@ -12,23 +12,33 @@ import { dbClient } from './ddb' */ export const scanItems = async ( tablename: string, - additionalInput?: Omit + additionalInput?: Omit ): Promise => { - const res = await dbClient() - .scan({ TableName: tablename, ...additionalInput }) - .promise() + const client = dbClient() - if (res.$response.error || !res.Items) { - return [] - } - - // scan the database until 'LastEvaluatedKey' is empty - const paginatedResults = res.LastEvaluatedKey - ? await scanItems(tablename, { + try { + const res = await client.send( + new ScanCommand({ + TableName: tablename, ...additionalInput, - ExclusiveStartKey: res.LastEvaluatedKey, }) - : [] + ) + + if (!res.Items) { + return [] + } - return [...paginatedResults, ...res.Items] as T[] + // scan the database until 'LastEvaluatedKey' is empty + const paginatedResults = res.LastEvaluatedKey + ? await scanItems(tablename, { + ...additionalInput, + ExclusiveStartKey: res.LastEvaluatedKey, + }) + : [] + + return [...paginatedResults, ...res.Items] as T[] + } catch (error) { + console.error('Error while scanning the DB:', error) + throw new Error('Error while scanning the DB:') + } } diff --git a/packages/backend/src/db/update.ts b/packages/backend/src/db/update.ts index ee6ed2a..fecc1a4 100644 --- a/packages/backend/src/db/update.ts +++ b/packages/backend/src/db/update.ts @@ -1,4 +1,4 @@ -import { DocumentClient } from 'aws-sdk/clients/dynamodb' +import { UpdateCommand, UpdateCommandInput } from '@aws-sdk/lib-dynamodb' import { Keys } from '../utils/object' import { @@ -15,19 +15,22 @@ import { * @param input DDB input options * @returns Boolean if sucess */ -const updateItem = async ( - tableName: string, - input: Omit -): Promise => { - const res = await dbClient() - .update({ TableName: tableName, ...input }) - .promise() - - if (res.$response.error) { +const updateItem = async (tableName: string, input: Omit): Promise => { + const client = dbClient() + + try { + await client.send( + new UpdateCommand({ + TableName: tableName, + ...input, + }) + ) + + return true + } catch (error) { + console.error('Error updating into DB:', error) throw new Error('Error updating into DB') } - - return true } /** diff --git a/packages/backend/src/repositories/report.repo.ts b/packages/backend/src/repositories/report.repo.ts index 4269fee..7c2ff46 100644 --- a/packages/backend/src/repositories/report.repo.ts +++ b/packages/backend/src/repositories/report.repo.ts @@ -1,5 +1,5 @@ -import { DocumentClient } from 'aws-sdk/clients/dynamodb' - +import { WriteRequest } from '@aws-sdk/client-dynamodb' +import { marshall } from '@aws-sdk/util-dynamodb' import { Report } from '@lara/api' import { @@ -23,11 +23,11 @@ export const saveReport = (report: Report): Promise => { } export const deleteReports = async (reports: Report[]): Promise => { - const deleteRequests: DocumentClient.WriteRequests = reports.map((report) => ({ + const deleteRequests: WriteRequest[] = reports.map((report) => ({ DeleteRequest: { - Key: { + Key: marshall({ id: report.id, - }, + }), }, })) diff --git a/packages/backend/src/repositories/trainer.repo.ts b/packages/backend/src/repositories/trainer.repo.ts index 550b20d..2b3e54f 100644 --- a/packages/backend/src/repositories/trainer.repo.ts +++ b/packages/backend/src/repositories/trainer.repo.ts @@ -1,5 +1,5 @@ -import { DocumentClient } from 'aws-sdk/clients/dynamodb' - +import { WriteRequest } from '@aws-sdk/client-dynamodb' +import { marshall } from '@aws-sdk/util-dynamodb' import { Trainer } from '@lara/api' import { queryObjects, userTableName, userTypeIndex, batchWriteItem } from '../db' @@ -19,12 +19,12 @@ export const trainerById = async (id: string): Promise => { export const deleteTrainerReferences = async (trainer: Trainer): Promise => { const trainees = await traineesByTrainerId(trainer.id) - const putRequests: DocumentClient.WriteRequests = trainees.map((trainee) => ({ + const putRequests: WriteRequest[] = trainees.map((trainee) => ({ PutRequest: { - Item: { + Item: marshall({ ...trainee, trainerId: undefined, - }, + }), }, })) diff --git a/packages/backend/src/repositories/user.repo.ts b/packages/backend/src/repositories/user.repo.ts index 1de9c93..6333465 100644 --- a/packages/backend/src/repositories/user.repo.ts +++ b/packages/backend/src/repositories/user.repo.ts @@ -15,13 +15,12 @@ import { userTableName, } from '../db' import { TokensResponse } from '../services/oauth.service' -import { DocumentClient } from 'aws-sdk/clients/dynamodb' export const allUsers = (): Promise => { return scanItems(userTableName) } -export const saveUser = (user: T): Promise => { +export const saveUser = (user: T): Promise => { return putItem(userTableName, user) } diff --git a/packages/components/tsconfig.json b/packages/components/tsconfig.json index 4dc369b..e02d9c8 100644 --- a/packages/components/tsconfig.json +++ b/packages/components/tsconfig.json @@ -6,8 +6,8 @@ "outDir": "lib", "rootDir": "src", "strictNullChecks": true, - "moduleResolution": "bundler", - "module": "es2020" + "moduleResolution": "node", + "module": "commonjs" }, "include": ["src/**/*"] } diff --git a/packages/email/assets/index.mjml b/packages/email/assets/index.mjml index 7315e05..1fc51a5 100644 --- a/packages/email/assets/index.mjml +++ b/packages/email/assets/index.mjml @@ -13,12 +13,25 @@ font-weight="600" inner-padding="12px 32px" line-height="1" + color="#FFFFFF" /> - + - .box-shadow a { box-shadow: rgb(0 0 0 / 20%) 0px 4px 9px; } + + :root, + body, + table, + td, + p, + span { + color: #000000 !important; + } + .box-shadow a { + box-shadow: rgb(0 0 0 / 20%) 0px 4px 9px; + } + diff --git a/packages/email/package.json b/packages/email/package.json index 94ea98c..1829486 100644 --- a/packages/email/package.json +++ b/packages/email/package.json @@ -10,8 +10,9 @@ "debug": "node lib/mock.js" }, "dependencies": { + "@aws-sdk/client-s3": "3.864.0", + "@aws-sdk/client-sesv2": "3.864.0", "@lara/api": "^1.0.0", - "aws-sdk": "^2.938.0", "handlebars": "^4.7.7", "mjml": "^4.11.0", "nodemailer": "^7.0.5" diff --git a/packages/email/src/handler.ts b/packages/email/src/handler.ts index 1700c62..013eb08 100644 --- a/packages/email/src/handler.ts +++ b/packages/email/src/handler.ts @@ -1,8 +1,8 @@ import { Handler } from 'aws-lambda' -import { SES } from 'aws-sdk' +import { SESv2Client, SendEmailCommand } from '@aws-sdk/client-sesv2' import { mkdirSync, writeFileSync } from 'fs' import { compile } from 'handlebars' -import { createTransport } from 'nodemailer' +import nodemailer from 'nodemailer' import { Attachment } from 'nodemailer/lib/mailer' import { MailOptions } from 'nodemailer/lib/ses-transport' import { resolve } from 'path' @@ -10,7 +10,9 @@ import { resolve } from 'path' import { EmailPayload } from '@lara/api' import { generateEmailTemplate } from './mail-template' -import { getAttachements } from './s3' +import { getAttachments } from './s3' + +import { Readable } from 'stream' const { IS_OFFLINE, SES_EMAIL, SES_REGION } = process.env @@ -22,12 +24,22 @@ if (!SES_REGION) { throw new Error("Missing Environment Variable: 'SES_REGION'") } -const transporter = createTransport({ - SES: new SES({ region: SES_REGION }), +const ses = new SESv2Client({ region: SES_REGION }) + +const transporter = nodemailer.createTransport({ + SES: { ses, SendEmailCommand }, }) type Response = 'success' | 'error' +const streamToBuffer = async (stream: Readable): Promise => { + const chunks: Uint8Array[] = [] + for await (const chunk of stream) { + chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk) + } + return Buffer.concat(chunks) +} + const handleGettingAttachements = async (payload: EmailPayload): Promise => { if (payload.emailType !== 'reportExport') { return [] @@ -35,12 +47,12 @@ const handleGettingAttachements = async (payload: EmailPayload): Promise = async (payload) => { diff --git a/packages/email/src/s3.ts b/packages/email/src/s3.ts index d9d8eb0..f3b430c 100644 --- a/packages/email/src/s3.ts +++ b/packages/email/src/s3.ts @@ -1,4 +1,4 @@ -import { S3, Endpoint } from 'aws-sdk' +import { S3Client, GetObjectCommand, GetObjectCommandOutput } from '@aws-sdk/client-s3' const { IS_OFFLINE, EXPORT_BUCKET } = process.env @@ -6,24 +6,28 @@ if (!EXPORT_BUCKET) { throw new Error("Missing env Var: 'EXPORT_BUCKET'") } -const s3Client = new S3( +const s3Client = new S3Client( IS_OFFLINE ? { - s3ForcePathStyle: true, - accessKeyId: 'S3RVER', // This specific key is required when working offline - secretAccessKey: 'S3RVER', - endpoint: new Endpoint('http://localhost:8181'), + forcePathStyle: true, + credentials: { + accessKeyId: 'S3RVER', // This specific key is required when working offline + secretAccessKey: 'S3RVER', + }, + endpoint: 'http://localhost:8181', } : { region: 'eu-central-1' } ) -export const getAttachements = async (key: string): Promise => { - const s3Object = await s3Client - .getObject({ +export const getAttachments = async (key: string): Promise => { + try { + const command = new GetObjectCommand({ Bucket: EXPORT_BUCKET, Key: key, }) - .promise() - - return s3Object.Body as Buffer + return await s3Client.send(command) + } catch (e) { + console.error('Error while fetching attachment from S3: ', e) + return undefined + } } diff --git a/packages/print/package.json b/packages/print/package.json index bcc12e7..6632942 100644 --- a/packages/print/package.json +++ b/packages/print/package.json @@ -10,11 +10,12 @@ "debug": "node lib/mock.js" }, "dependencies": { + "@aws-sdk/client-s3": "3.864.0", + "@aws-sdk/types": "3.862.0", "@lara/api": "^1.0.0", "@lara/components": "^1.0.0", "@sparticuz/chromium": "^138.0.2", "adm-zip": "^0.5.10", - "aws-sdk": "^2.950.0", "puppeteer-core": "^24.16.0", "react": "^19.1.1", "react-dom": "^19.1.1", diff --git a/packages/print/src/handler.ts b/packages/print/src/handler.ts index cf8afd5..2820fa7 100644 --- a/packages/print/src/handler.ts +++ b/packages/print/src/handler.ts @@ -1,4 +1,4 @@ -import { Lambda } from 'aws-sdk' +import { Lambda } from '@aws-sdk/client-lambda' import AdmZip from 'adm-zip' import { Handler } from 'aws-lambda' import chromium from '@sparticuz/chromium' @@ -6,8 +6,8 @@ import { launch, Browser, Page } from 'puppeteer-core' import { EmailPayload, PrintData, PrintPayload } from '@lara/api' -import { createPDF } from './create-pdf' import { getExport, saveAttachments } from './s3' +import { createPDF } from './create-pdf' const { IS_OFFLINE, EMAIL_FUNCTION, FRONTEND_URL } = process.env @@ -95,29 +95,25 @@ export const handler: Handler = async (payloa translations: emailTranslations, } - await lambda - .invoke({ - FunctionName: EMAIL_FUNCTION, - InvocationType: 'RequestResponse', - Payload: JSON.stringify(emailPayload), - }) - .promise() + await lambda.invoke({ + FunctionName: EMAIL_FUNCTION, + InvocationType: 'RequestResponse', + Payload: JSON.stringify(emailPayload), + }) return 'success' } catch (e) { console.error('Error while rendering PDF: ', e) - await lambda - .invoke({ - FunctionName: EMAIL_FUNCTION, - InvocationType: 'RequestResponse', - Payload: JSON.stringify({ - emailType: 'error', - userData, - translations: emailTranslations, - }), - }) - .promise() + await lambda.invoke({ + FunctionName: EMAIL_FUNCTION, + InvocationType: 'RequestResponse', + Payload: JSON.stringify({ + emailType: 'error', + userData, + translations: emailTranslations, + }), + }) return 'error' } finally { diff --git a/packages/print/src/s3.ts b/packages/print/src/s3.ts index 7e54c5c..71de6d8 100644 --- a/packages/print/src/s3.ts +++ b/packages/print/src/s3.ts @@ -1,5 +1,11 @@ -import { S3, Endpoint, AWSError } from 'aws-sdk' -import { PromiseResult } from 'aws-sdk/lib/request' +import { + S3Client, + GetObjectCommand, + PutObjectCommand, + GetObjectCommandOutput, + PutObjectCommandOutput, +} from '@aws-sdk/client-s3' +import { Readable } from 'stream' import { PrintData } from '@lara/api' @@ -9,36 +15,55 @@ if (!EXPORT_BUCKET) { throw new Error("Missing env Var: 'EXPORT_BUCKET'") } -const s3Client = new S3( +const s3Client = new S3Client( IS_OFFLINE ? { - s3ForcePathStyle: true, - accessKeyId: 'S3RVER', // This specific key is required when working offline - secretAccessKey: 'S3RVER', - endpoint: new Endpoint('http://localhost:8181'), + forcePathStyle: true, + credentials: { + accessKeyId: 'S3RVER', // This specific key is required when working offline + secretAccessKey: 'S3RVER', + }, + endpoint: 'http://localhost:8181', } : { region: 'eu-central-1' } ) -export const getExport = (key: string): Promise => { - return s3Client - .getObject({ +const streamToString = async (stream: Readable): Promise => { + const chunks: Uint8Array[] = [] + for await (const chunk of stream) { + chunks.push(typeof chunk === 'string' ? Buffer.from(chunk) : chunk) + } + return Buffer.concat(chunks).toString('utf-8') +} + +export const getExport = async (key: string): Promise => { + try { + const command = new GetObjectCommand({ Bucket: EXPORT_BUCKET, Key: key, }) - .promise() - .then((res) => res.Body && JSON.parse(res.Body.toString('utf-8'))) - .catch((e) => { - console.error('Error while trying to get Data from S3 Bucket: ', e) - }) + const res: GetObjectCommandOutput = await s3Client.send(command) + + if (res.Body && res.Body instanceof Readable) { + const bodyStr = await streamToString(res.Body) + return JSON.parse(bodyStr) + } else return undefined + } catch (e) { + console.error('Error while trying to get Data from S3 Bucket: ', e) + return undefined + } } -export const saveAttachments = (key: string, body: Buffer): Promise> => { - return s3Client - .putObject({ +export const saveAttachments = async (key: string, body: Buffer): Promise => { + try { + const command = new PutObjectCommand({ Bucket: EXPORT_BUCKET, Key: key, Body: body, }) - .promise() + return await s3Client.send(command) + } catch (e) { + console.error('Error while saving attachment to S3: ', e) + return undefined + } } diff --git a/packages/print/tsconfig.json b/packages/print/tsconfig.json index 149d782..0e208fc 100644 --- a/packages/print/tsconfig.json +++ b/packages/print/tsconfig.json @@ -6,7 +6,7 @@ "rootDir": "src", "strict": true, "strictNullChecks": true, - "target": "ESNext", + "target": "ESNEXT", "lib": ["ESNEXT", "DOM"], "esModuleInterop": true, "moduleResolution": "node", diff --git a/yarn.lock b/yarn.lock index 4393cfa..d2004af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -407,7 +407,7 @@ "@smithy/util-utf8" "^4.0.0" tslib "^2.6.2" -"@aws-sdk/client-dynamodb@^3.428.0", "@aws-sdk/client-dynamodb@^3.693.0": +"@aws-sdk/client-dynamodb@3.864.0", "@aws-sdk/client-dynamodb@^3.428.0", "@aws-sdk/client-dynamodb@^3.693.0": version "3.864.0" resolved "https://registry.yarnpkg.com/@aws-sdk/client-dynamodb/-/client-dynamodb-3.864.0.tgz#50b76a6751ea11676809bc52bd71d8ac34d2d895" integrity sha512-Z+8qCU8A8RKI/vaMZx3bUG3ZIvEBZzYRIEZA06Qx0QHttkDV/i2Q31Bs98Za/UV0aMXJYsgpHCvXeRgR7r8hYA== @@ -548,6 +548,56 @@ "@smithy/util-waiter" "^4.0.7" tslib "^2.6.2" +"@aws-sdk/client-lambda@3.864.0": + version "3.864.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-lambda/-/client-lambda-3.864.0.tgz#e2337b7d3c0240a3b10f827af21bcf0057ffe273" + integrity sha512-K+jSyCBu9jU+E5TPBrzDVcpW5VR1hUnt+iOTvb5M4Uko+alhpenbJDF0kKgC8E2cAMoxRI/X9YjqqAvtYESL+g== + dependencies: + "@aws-crypto/sha256-browser" "5.2.0" + "@aws-crypto/sha256-js" "5.2.0" + "@aws-sdk/core" "3.864.0" + "@aws-sdk/credential-provider-node" "3.864.0" + "@aws-sdk/middleware-host-header" "3.862.0" + "@aws-sdk/middleware-logger" "3.862.0" + "@aws-sdk/middleware-recursion-detection" "3.862.0" + "@aws-sdk/middleware-user-agent" "3.864.0" + "@aws-sdk/region-config-resolver" "3.862.0" + "@aws-sdk/types" "3.862.0" + "@aws-sdk/util-endpoints" "3.862.0" + "@aws-sdk/util-user-agent-browser" "3.862.0" + "@aws-sdk/util-user-agent-node" "3.864.0" + "@smithy/config-resolver" "^4.1.5" + "@smithy/core" "^3.8.0" + "@smithy/eventstream-serde-browser" "^4.0.5" + "@smithy/eventstream-serde-config-resolver" "^4.1.3" + "@smithy/eventstream-serde-node" "^4.0.5" + "@smithy/fetch-http-handler" "^5.1.1" + "@smithy/hash-node" "^4.0.5" + "@smithy/invalid-dependency" "^4.0.5" + "@smithy/middleware-content-length" "^4.0.5" + "@smithy/middleware-endpoint" "^4.1.18" + "@smithy/middleware-retry" "^4.1.19" + "@smithy/middleware-serde" "^4.0.9" + "@smithy/middleware-stack" "^4.0.5" + "@smithy/node-config-provider" "^4.1.4" + "@smithy/node-http-handler" "^4.1.1" + "@smithy/protocol-http" "^5.1.3" + "@smithy/smithy-client" "^4.4.10" + "@smithy/types" "^4.3.2" + "@smithy/url-parser" "^4.0.5" + "@smithy/util-base64" "^4.0.0" + "@smithy/util-body-length-browser" "^4.0.0" + "@smithy/util-body-length-node" "^4.0.0" + "@smithy/util-defaults-mode-browser" "^4.0.26" + "@smithy/util-defaults-mode-node" "^4.0.26" + "@smithy/util-endpoints" "^3.0.7" + "@smithy/util-middleware" "^4.0.5" + "@smithy/util-retry" "^4.0.7" + "@smithy/util-stream" "^4.2.4" + "@smithy/util-utf8" "^4.0.0" + "@smithy/util-waiter" "^4.0.7" + tslib "^2.6.2" + "@aws-sdk/client-lambda@^3.588.0", "@aws-sdk/client-lambda@^3.636.0": version "3.865.0" resolved "https://registry.yarnpkg.com/@aws-sdk/client-lambda/-/client-lambda-3.865.0.tgz#3e98b87aa814c419c815e3f5c2f8f1d95c00b335" @@ -598,7 +648,7 @@ "@smithy/util-waiter" "^4.0.7" tslib "^2.6.2" -"@aws-sdk/client-s3@^3.53.1", "@aws-sdk/client-s3@^3.588.0": +"@aws-sdk/client-s3@3.864.0", "@aws-sdk/client-s3@^3.53.1", "@aws-sdk/client-s3@^3.588.0": version "3.864.0" resolved "https://registry.yarnpkg.com/@aws-sdk/client-s3/-/client-s3-3.864.0.tgz#ffbcbf0ba861fad711261b4174da3be19b1c7d5f" integrity sha512-QGYi9bWliewxumsvbJLLyx9WC0a4DP4F+utygBcq0zwPxaM0xDfBspQvP1dsepi7mW5aAjZmJ2+Xb7X0EhzJ/g== @@ -662,6 +712,52 @@ tslib "^2.6.2" uuid "^9.0.1" +"@aws-sdk/client-sesv2@3.864.0": + version "3.864.0" + resolved "https://registry.yarnpkg.com/@aws-sdk/client-sesv2/-/client-sesv2-3.864.0.tgz#5f843ec1241fa55d6d9a03a107ba50405dc539b6" + integrity sha512-pwn4/3bs7ccucS9sYpMbzptEhEFQQy8TXtmKNzmyY7OIDBGTiJrxsWYDTULO4nxsMmGXi39mSEowlK4QUCyC+w== + dependencies: + "@aws-crypto/sha256-browser" "5.2.0" + "@aws-crypto/sha256-js" "5.2.0" + "@aws-sdk/core" "3.864.0" + "@aws-sdk/credential-provider-node" "3.864.0" + "@aws-sdk/middleware-host-header" "3.862.0" + "@aws-sdk/middleware-logger" "3.862.0" + "@aws-sdk/middleware-recursion-detection" "3.862.0" + "@aws-sdk/middleware-user-agent" "3.864.0" + "@aws-sdk/region-config-resolver" "3.862.0" + "@aws-sdk/signature-v4-multi-region" "3.864.0" + "@aws-sdk/types" "3.862.0" + "@aws-sdk/util-endpoints" "3.862.0" + "@aws-sdk/util-user-agent-browser" "3.862.0" + "@aws-sdk/util-user-agent-node" "3.864.0" + "@smithy/config-resolver" "^4.1.5" + "@smithy/core" "^3.8.0" + "@smithy/fetch-http-handler" "^5.1.1" + "@smithy/hash-node" "^4.0.5" + "@smithy/invalid-dependency" "^4.0.5" + "@smithy/middleware-content-length" "^4.0.5" + "@smithy/middleware-endpoint" "^4.1.18" + "@smithy/middleware-retry" "^4.1.19" + "@smithy/middleware-serde" "^4.0.9" + "@smithy/middleware-stack" "^4.0.5" + "@smithy/node-config-provider" "^4.1.4" + "@smithy/node-http-handler" "^4.1.1" + "@smithy/protocol-http" "^5.1.3" + "@smithy/smithy-client" "^4.4.10" + "@smithy/types" "^4.3.2" + "@smithy/url-parser" "^4.0.5" + "@smithy/util-base64" "^4.0.0" + "@smithy/util-body-length-browser" "^4.0.0" + "@smithy/util-body-length-node" "^4.0.0" + "@smithy/util-defaults-mode-browser" "^4.0.26" + "@smithy/util-defaults-mode-node" "^4.0.26" + "@smithy/util-endpoints" "^3.0.7" + "@smithy/util-middleware" "^4.0.5" + "@smithy/util-retry" "^4.0.7" + "@smithy/util-utf8" "^4.0.0" + tslib "^2.6.2" + "@aws-sdk/client-sso@3.864.0": version "3.864.0" resolved "https://registry.yarnpkg.com/@aws-sdk/client-sso/-/client-sso-3.864.0.tgz#4099313516d61ed61791551c6f0683259b9cbf5e" @@ -882,7 +978,7 @@ mnemonist "0.38.3" tslib "^2.6.2" -"@aws-sdk/lib-dynamodb@^3.428.0", "@aws-sdk/lib-dynamodb@^3.693.0": +"@aws-sdk/lib-dynamodb@3.864.0", "@aws-sdk/lib-dynamodb@^3.428.0", "@aws-sdk/lib-dynamodb@^3.693.0": version "3.864.0" resolved "https://registry.yarnpkg.com/@aws-sdk/lib-dynamodb/-/lib-dynamodb-3.864.0.tgz#353134660f380b92fb55e907327e9cd31510df8d" integrity sha512-arPH8sFUlF7Ul0xui6lr+eilpxnJ60yoF+oxu2TnGZ9NHsy1q+IAH0oJYuoxDlAGsbBtmdaZZZeKtYl6AyMYbw== @@ -6388,7 +6484,7 @@ aws-dynamodb-local@^0.0.11: dependencies: tar "^6.2.0" -aws-sdk@^2.1404.0, aws-sdk@^2.346.0, aws-sdk@^2.938.0, aws-sdk@^2.950.0: +aws-sdk@^2.1404.0, aws-sdk@^2.346.0, aws-sdk@^2.938.0: version "2.1692.0" resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1692.0.tgz#9dac5f7bfcc5ab45825cc8591b12753aa7d2902c" integrity sha512-x511uiJ/57FIsbgUe5csJ13k3uzu25uWQE+XqfBis/sB0SFoiElJWXRkgEAUh0U6n40eT3ay5Ue4oPkRMu1LYw==