From 2e90cf62abb499227fb6d51f61ca8928115ee3a4 Mon Sep 17 00:00:00 2001 From: "Zach A. Thomas" Date: Fri, 5 Jan 2024 11:12:49 -0500 Subject: [PATCH] add Lambda function to respond to S3 put events and add json files --- .../excelToJson/excelToJson.scenarios.ts | 8 +++ .../functions/excelToJson/excelToJson.test.ts | 54 +++++++++++++++++++ api/src/functions/excelToJson/excelToJson.ts | 49 +++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 api/src/functions/excelToJson/excelToJson.scenarios.ts create mode 100644 api/src/functions/excelToJson/excelToJson.test.ts create mode 100644 api/src/functions/excelToJson/excelToJson.ts diff --git a/api/src/functions/excelToJson/excelToJson.scenarios.ts b/api/src/functions/excelToJson/excelToJson.scenarios.ts new file mode 100644 index 00000000..d24ff747 --- /dev/null +++ b/api/src/functions/excelToJson/excelToJson.scenarios.ts @@ -0,0 +1,8 @@ +import type { ScenarioData } from '@redwoodjs/testing/api' + +export const standard = defineScenario({ + // Define the "fixture" to write into your test database here + // See guide: https://redwoodjs.com/docs/testing#scenarios +}) + +export type StandardScenario = ScenarioData diff --git a/api/src/functions/excelToJson/excelToJson.test.ts b/api/src/functions/excelToJson/excelToJson.test.ts new file mode 100644 index 00000000..a93c00ca --- /dev/null +++ b/api/src/functions/excelToJson/excelToJson.test.ts @@ -0,0 +1,54 @@ +// import { S3EventRecord } from 'aws-lambda' + +// import { handler } from './excelToJson' + +// Improve this test with help from the Redwood Testing Doc: +// https://redwoodjs.com/docs/testing#testing-functions + +describe('excelToJson function', () => { + // it('Should respond with 200', async () => { + // const record: S3EventRecord = { + // eventVersion: '2.0', + // eventSource: 'aws:s3', + // eventName: 'ObjectCreated:Put', + // eventTime: '1970-01-01T00:00:00.000Z', + // userIdentity: { principalId: 'test-principalId' }, + // requestParameters: { sourceIPAddress: 'test-sourceIPAddress' }, + // responseElements: { + // 'x-amz-request-id': 'test-x-amz-request-id', + // 'x-amz-id-2': 'test-x-amz-id-2', + // }, + // awsRegion: 'us-east-1', + // s3: { + // s3SchemaVersion: '1.0', + // configurationId: 'test-configurationId', + // bucket: { + // name: 'test-bucket', + // arn: 'test-arn', + // ownerIdentity: { + // principalId: 'test-principalId', + // }, + // }, + // object: { + // key: 'test-key', + // size: 1234, + // eTag: 'test-etag', + // sequencer: 'test-sequencer', + // }, + // }, + // } + // const s3Event = { + // Records: [record], + // } + // const response = await handler(s3Event, null, null) + // const { data } = JSON.parse(response.body) + // expect(response.statusCode).toBe(200) + // expect(data).toBe('excelToJson function') +}) + +// You can also use scenarios to test your api functions +// See guide here: https://redwoodjs.com/docs/testing#scenarios +// +// scenario('Scenario test', async () => { +// +// }) diff --git a/api/src/functions/excelToJson/excelToJson.ts b/api/src/functions/excelToJson/excelToJson.ts new file mode 100644 index 00000000..337d4035 --- /dev/null +++ b/api/src/functions/excelToJson/excelToJson.ts @@ -0,0 +1,49 @@ +import { + S3Client, + GetObjectCommand, + PutObjectCommand, +} from '@aws-sdk/client-s3' +import { NodeJsClient } from '@smithy/types' +import { S3Event, S3Handler } from 'aws-lambda' +import { Workbook } from 'exceljs' + +import { logger } from 'src/lib/logger' + +const s3 = new S3Client({}) as NodeJsClient + +export const handler: S3Handler = async (event: S3Event): Promise => { + try { + const bucket = event.Records[0].s3.bucket.name + const key = event.Records[0].s3.object.key + + // Download the Excel file from S3 + const getObjectResponse = await s3.send( + new GetObjectCommand({ Bucket: bucket, Key: key }) + ) + + if (getObjectResponse.Body) { + new Workbook().xlsx.read(getObjectResponse.Body) + const workbook = new Workbook() + + const worksheet = workbook.worksheets[0] + const jsonData = worksheet.getSheetValues() + + // Write JSON data to a file + const jsonFileName = `${key}.json` // Use the same key with .json extension + const jsonFileContent = JSON.stringify(jsonData) + + // Upload the JSON file to the same bucket + s3.send( + new PutObjectCommand({ + Bucket: bucket, + Key: jsonFileName, + Body: jsonFileContent, + ContentType: 'application/json', + }) + ) + } + } catch (error) { + logger.error('Error processing S3 event:', error) + throw error + } +}