This repository was archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhandler.ts
More file actions
141 lines (116 loc) · 5.17 KB
/
handler.ts
File metadata and controls
141 lines (116 loc) · 5.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import { S3Client, ListObjectsV2Command, GetObjectCommand, PutObjectCommand } from "@aws-sdk/client-s3";
import { Readable } from "stream";
import { marked } from "marked";
import { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda";
export const handler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
console.log("Lambda function invoked with event:", JSON.stringify(event, null, 2));
const s3Client = new S3Client();
try {
// Validate and parse input
if (!event.body) {
console.error("Error: Missing request body");
return {
statusCode: 400,
body: JSON.stringify({ error: "Missing request body" }),
};
}
const requestBody = JSON.parse(event.body);
console.log("Parsed request body:", requestBody);
if (!requestBody.inputBucketName || !requestBody.folderPrefix || !requestBody.outputBucketName) {
console.error("Error: Missing or invalid parameters in request body");
return {
statusCode: 400,
body: JSON.stringify({ error: "Missing or invalid parameters in request body" }),
};
}
const inputBucketName = requestBody.inputBucketName;
const folderPrefix = requestBody.folderPrefix.endsWith("/") ? requestBody.folderPrefix : requestBody.folderPrefix + "/";
const outputBucketName = requestBody.outputBucketName;
console.log(`Fetching objects from S3: Bucket=${inputBucketName}, Prefix=${folderPrefix}`);
// List objects in the specified folder
const listCommand = new ListObjectsV2Command({
Bucket: inputBucketName,
Prefix: folderPrefix,
});
const listResponse = await s3Client.send(listCommand);
console.log(`S3 ListObjects response: ${JSON.stringify(listResponse, null, 2)}`);
if (!listResponse.Contents || listResponse.Contents.length === 0) {
console.warn(`No files found in the specified folder: ${folderPrefix}`);
return {
statusCode: 404,
body: JSON.stringify({ error: "No files found in the specified folder" }),
};
}
for (const file of listResponse.Contents) {
if (!file.Key) {
console.warn("Skipping file with no Key.");
continue;
}
console.log(`Processing file: ${file.Key}`);
// Get object from S3
const readCommand = new GetObjectCommand({ Bucket: inputBucketName, Key: file.Key });
const readResponse = await s3Client.send(readCommand);
console.log(`S3 GetObject response for ${file.Key}:`, readResponse);
if (!readResponse.Body || !(readResponse.Body instanceof Readable)) {
console.error(`Invalid response from S3: Body is not a readable stream for file ${file.Key}`);
throw new Error(`Invalid response from S3: Body is not a readable stream for file ${file.Key}`);
}
// Convert stream to string and transform
console.log(`Reading markdown content from ${file.Key}`);
const markdown = await streamToString(readResponse.Body);
console.log(`Markdown content for ${file.Key}:`, markdown);
console.log(`Converting markdown to HTML for ${file.Key}`);
const outputAfterMarkdown = await marked(markdown);
console.log(`Converted HTML for ${file.Key}:`, outputAfterMarkdown);
const outputText = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${file.Key}</title>
</head>
<body>
${outputAfterMarkdown}
</body>
</html>`;
// Extracting the relative path by removing the first folder from file.Key
const keyParts = file.Key.split("/");
const newKey = keyParts.length > 1 ? keyParts.slice(1).join("/").replace(/\.md$/, ".html") : file.Key.replace(/\.md$/, ".html");
console.log(`Original key: ${file.Key}, Modified key: ${newKey}`);
// Write processed content back to output S3 bucket with the same folder structure
const writeCommand = new PutObjectCommand({
Body: outputText,
Bucket: outputBucketName,
Key: newKey,
ContentType: "text/html"
});
console.log(`Uploading transformed content to ${outputBucketName}/${file.Key}`);
await s3Client.send(writeCommand);
console.log(`File ${file.Key} successfully uploaded to ${outputBucketName}.`);
}
// Success response
console.log("All files in the folder processed successfully!");
return {
statusCode: 200,
body: JSON.stringify({
message: "All files in the folder processed successfully!",
}),
};
} catch (error) {
console.error("Error processing request:", error);
return {
statusCode: 500,
body: JSON.stringify({ error: error instanceof Error ? error.message : "Internal Server Error" }),
};
}
};
// Helper function to convert a stream to a string
async function streamToString(stream: Readable): Promise<string> {
const chunks: Buffer[] = [];
for await (const chunk of stream) {
chunks.push(Buffer.from(chunk));
}
const result = Buffer.concat(chunks).toString("utf-8");
console.log("Stream converted to string:", result);
return result;
}