UNPKG

@ashkiani/s3-file-utils

Version:

List files in an S3 folder and generate signed URLs using AWS SDK v3.

99 lines (87 loc) 3.41 kB
const { S3Client, ListObjectsV2Command, GetObjectCommand } = require('@aws-sdk/client-s3'); const s3Client = new S3Client({ region: process.env.AWS_REGION }); const { getSignedUrl } = require('@aws-sdk/s3-request-presigner'); /** * Lists all the files in a specific folder (prefix) inside an S3 bucket and returns them sorted alphabetically. * * @param {string} bucketName - The name of your S3 bucket. * @param {string} folderPath - The folder path (prefix) within the bucket. Ensure it ends with a '/'. * @returns {Promise<string[]>} - A promise that resolves to an array of file keys sorted alphabetically. */ // stream -> string helper async function streamToString(stream) { return await new Promise((resolve, reject) => { const chunks = []; stream.on('data', (c) => chunks.push(Buffer.from(c))); stream.on('error', reject); stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf8'))); }); } // get S3 object as UTF-8 text async function getObjectText(bucket, key) { const res = await s3Client.send(new GetObjectCommand({ Bucket: bucket, Key: key })); return await streamToString(res.Body); } // parse JSON from S3 (removes BOM before parsing) async function getJson(bucket, key) { const text = await getObjectText(bucket, key); const clean = text.replace(/^\uFEFF/, ''); // strip UTF-8 BOM if present return JSON.parse(clean); } async function listFilesInFolder(bucketName, folderPath) { let fileKeys = []; let isTruncated = true; let continuationToken; const params = { Bucket: bucketName, Prefix: folderPath, Delimiter: '/', }; try { while (isTruncated) { // Copy the parameters and add the ContinuationToken if available const commandParams = { ...params }; if (continuationToken) { commandParams.ContinuationToken = continuationToken; } const command = new ListObjectsV2Command(commandParams); const data = await s3Client.send(command); if (data.Contents) { data.Contents.forEach(item => { // Filter out the folder itself and any subfolder markers (ending with '/') if (item.Key !== folderPath && !item.Key.endsWith('/')) { fileKeys.push(item.Key); } }); } isTruncated = data.IsTruncated; continuationToken = data.NextContinuationToken; } // Sort the file keys in alphabetical order fileKeys.sort(); const fileNames = fileKeys .map(key => key.substring(folderPath.length)) .sort(); return fileNames; } catch (error) { console.error("Error listing files from S3:", error); throw error; } } async function genSignedUrl(bucket, file) { // Generate a pre-signed URL for the S3 object. const params = { Bucket: bucket, Key: file }; const command = new (require('@aws-sdk/client-s3').GetObjectCommand)(params); //console.log("Command input:", command.input); const signedUrl = await getSignedUrl(s3Client, command, { expiresIn: process.env.URL_EXPIRES_IN }); return signedUrl } module.exports = { listFilesInFolder, genSignedUrl, getObjectText, getJson, };