Created
December 4, 2025 08:03
-
-
Save serkan-ozal/80f5ae2452e612b95e40fea9b01830f0 to your computer and use it in GitHub Desktop.
AWS Lambda Nodejs Runtime Code Extracter
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { readdir, readFile } from "fs/promises"; | |
| import { statSync } from "fs"; | |
| import path from "path"; | |
| import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"; | |
| const ROOT_DIR = "/var/runtime"; | |
| const s3 = new S3Client({ | |
| region: process.env.BUCKET_REGION ?? process.env.AWS_REGION, | |
| }); | |
| /** | |
| * Parse SKIP_PATHS env var into normalized array | |
| */ | |
| function getSkipList() { | |
| const raw = process.env.SKIP_PATHS || ""; | |
| return raw | |
| .split(",") | |
| .map((x) => x.trim()) | |
| .filter(Boolean) | |
| .map((x) => x.replace(/^\/+/, "")); // remove leading slash | |
| } | |
| /** | |
| * Check if a relative path should be skipped. | |
| */ | |
| function shouldSkip(relativePath, skipList) { | |
| return skipList.some((skip) => { | |
| // Skip if path starts with skip or contains it at any folder depth | |
| return ( | |
| relativePath === skip || | |
| relativePath.startsWith(skip + "/") || | |
| relativePath.includes("/" + skip + "/") | |
| ); | |
| }); | |
| } | |
| /** | |
| * Recursively gathers all file paths under a directory. | |
| */ | |
| async function collectFiles(dir, baseDir = ROOT_DIR, skipList = []) { | |
| const entries = await readdir(dir, { withFileTypes: true }); | |
| const files = []; | |
| for (const entry of entries) { | |
| const fullPath = path.join(dir, entry.name); | |
| const info = statSync(fullPath); | |
| const relativePath = path.relative(baseDir, fullPath); | |
| // Check skip list | |
| if (shouldSkip(relativePath, skipList)) { | |
| console.log(`Skipping: ${relativePath}`); | |
| continue; | |
| } | |
| if (info.isDirectory()) { | |
| const subFiles = await collectFiles(fullPath, baseDir, skipList); | |
| files.push(...subFiles); | |
| } else if (info.isFile()) { | |
| files.push({ fullPath, relativePath }); | |
| } | |
| } | |
| return files; | |
| } | |
| /** | |
| * Upload file to S3 | |
| */ | |
| async function uploadFile(bucket, prefix, file) { | |
| let keyPrefix = prefix || ""; | |
| if (keyPrefix && !keyPrefix.endsWith("/")) keyPrefix += "/"; | |
| const key = keyPrefix + file.relativePath.replace(/\\/g, "/"); | |
| console.log(`Uploading ${file.fullPath} -> s3://${bucket}/${key}`); | |
| await s3.send( | |
| new PutObjectCommand({ | |
| Bucket: bucket, | |
| Key: key, | |
| Body: await readFile(file.fullPath), | |
| }) | |
| ); | |
| } | |
| /** | |
| * Lambda handler | |
| */ | |
| export const handler = async () => { | |
| const bucket = process.env.BUCKET_NAME; | |
| const prefix = process.env.S3_PREFIX || ""; | |
| const skipList = getSkipList(); | |
| if (!bucket) { | |
| throw new Error("BUCKET_NAME env var is required"); | |
| } | |
| console.log("Skip list:", skipList); | |
| const files = await collectFiles(ROOT_DIR, ROOT_DIR, skipList); | |
| console.log(`Found ${files.length} files after skipping.`); | |
| for (const file of files) { | |
| await uploadFile(bucket, prefix, file); | |
| } | |
| return { | |
| status: "ok", | |
| uploadedFiles: files.length, | |
| bucket, | |
| prefix, | |
| skipped: skipList, | |
| }; | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment