mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-20 00:46:01 +00:00
78 lines
2.5 KiB
JavaScript
78 lines
2.5 KiB
JavaScript
const yauzl = require('yauzl');
|
|
const fs = require('fs');
|
|
const { getLogger, extractErrorLogData } = require('dbgate-tools');
|
|
const logger = getLogger('extractSingleFileFromZip');
|
|
/**
|
|
* Extracts a single file from a ZIP using yauzl.
|
|
* Stops reading the rest of the archive once the file is found.
|
|
*
|
|
* @param {string} zipPath - Path to the ZIP file on disk.
|
|
* @param {string} fileInZip - The file path *inside* the ZIP to extract.
|
|
* @param {string} outputPath - Where to write the extracted file on disk.
|
|
* @returns {Promise<boolean>} - Resolves with a success message or a "not found" message.
|
|
*/
|
|
function extractSingleFileFromZip(zipPath, fileInZip, outputPath) {
|
|
return new Promise((resolve, reject) => {
|
|
yauzl.open(zipPath, { lazyEntries: true }, (err, zipFile) => {
|
|
if (err) return reject(err);
|
|
|
|
let fileFound = false;
|
|
|
|
// Start reading the first entry
|
|
zipFile.readEntry();
|
|
|
|
zipFile.on('entry', entry => {
|
|
// Compare the entry name to the file we want
|
|
if (entry.fileName === fileInZip) {
|
|
fileFound = true;
|
|
|
|
// Open a read stream for this entry
|
|
zipFile.openReadStream(entry, (err, readStream) => {
|
|
if (err) return reject(err);
|
|
|
|
// Create a write stream to outputPath
|
|
const writeStream = fs.createWriteStream(outputPath);
|
|
readStream.pipe(writeStream);
|
|
|
|
// When the read stream ends, we can close the zipFile
|
|
readStream.on('end', () => {
|
|
// We won't read further entries
|
|
zipFile.close();
|
|
});
|
|
|
|
// When the file is finished writing, resolve
|
|
writeStream.on('finish', () => {
|
|
logger.info(`File "${fileInZip}" extracted to "${outputPath}".`);
|
|
resolve(true);
|
|
});
|
|
|
|
// Handle write errors
|
|
writeStream.on('error', writeErr => {
|
|
logger.error(extractErrorLogData(writeErr), `Error extracting "${fileInZip}" from "${zipPath}".`);
|
|
reject(writeErr);
|
|
});
|
|
});
|
|
} else {
|
|
// Not the file we want; skip to the next entry
|
|
zipFile.readEntry();
|
|
}
|
|
});
|
|
|
|
// If we reach the end without finding the file
|
|
zipFile.on('end', () => {
|
|
if (!fileFound) {
|
|
resolve(false);
|
|
}
|
|
});
|
|
|
|
// Handle general errors
|
|
zipFile.on('error', err => {
|
|
logger.error(extractErrorLogData(err), `ZIP file error in ${zipPath}.`);
|
|
reject(err);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
module.exports = extractSingleFileFromZip;
|