mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-20 08:56:00 +00:00
SYNC: Merge pull request #3 from dbgate/feature/zip
This commit is contained in:
77
packages/api/src/utility/extractSingleFileFromZip.js
Normal file
77
packages/api/src/utility/extractSingleFileFromZip.js
Normal file
@@ -0,0 +1,77 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user