I have the following class I am trying to make into a Lambda Layer in Nodejs.
import { Athena } from "aws-sdk";
export class AthenaHelper {
private athena = new Athena();
public queryAthena = async (
databaseParams: Athena.StartQueryExecutionInput
) => {
const { QueryExecutionId: queryExecutionId } =
(await this.athena.startQueryExecution(databaseParams).promise()) ?? {};
if (!queryExecutionId) {
throw new Error("No query execution ID");
}
const params = {
QueryExecutionId: queryExecutionId,
};
// Wait for the query to complete
await this.waitForQueryCompletion(queryExecutionId);
// Retrieve the results from Athena in JSON format
const results = await this.getQueryResultsInJsonFormat(params);
return results;
};
private waitForQueryCompletion = async (
queryExecutionId: string | undefined
) => {
try {
if (!queryExecutionId) {
throw new Error("No query execution ID");
}
let state: string | null | undefined = null;
while (
state !== "SUCCEEDED" &&
state !== "FAILED" &&
state !== "CANCELLED"
) {
await new Promise((res) => setTimeout(res, 1000));
const { QueryExecution } = await this.athena
.getQueryExecution({
QueryExecutionId: queryExecutionId,
})
.promise();
state = QueryExecution?.Status?.State;
}
return state;
} catch (error) {
throw error;
}
};
private getQueryResultsInJsonFormat = async (
params: Athena.GetQueryResultsInput
): Promise<Record<string, string | null>[]> => {
const result: Athena.GetQueryResultsOutput = await this.athena
.getQueryResults(params)
.promise();
const columnInfo: Athena.ColumnInfo[] =
result.ResultSet?.ResultSetMetadata?.ColumnInfo || [];
const rows =
// The column names are returned in the first result set, this strips them out
result.ResultSet?.Rows?.slice(1).map((row) => {
const rowData: Record<string, string | null> = {};
row.Data?.forEach((data, index) => {
rowData[columnInfo[index].Name] = data?.VarCharValue || null;
});
return rowData;
}) || [];
return rows;
};
public helloWorld() {
console.log("Hello World");
}
}
I use the tsc
command to compile it to vanilla Javascript and I uploaded it to Lambda Layers.
I than run my lambda function that looks as follows:
exports.handler = async (event, context) => {
try {
const AthenaHelper = require('/opt/nodejs/AthenaHelper');
const athenaHelper = new AthenaHelper()
athenaHelper.helloWorld()
return {
statusCode: 200,
body: 'Hello, World!'
};
} catch (error) {
console.log('error', JSON.stringify(error))
}
};
upon running the code I get the following error:
{
"errorType": "ReferenceError",
"errorMessage": "exports is not defined in ES module scope",
}
Any suggestions here? Has anyone made a custom class in Typescript and tried to export it to a Lambda Layer? Any advice would be appreciated.
TS Config
{ "compilerOptions": { "lib": ["es2018", "dom"] } }