or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

archive-creation.mdarchive-manipulation.mdarchive-reading.mdcomments-metadata.mdfile-extraction.mdindex.md
tile.json

file-extraction.mddocs/

File Extraction

Comprehensive functionality for extracting files and directories from ZIP archives to disk with various options for path handling, permissions, and extraction modes.

Capabilities

Extract Single Entry

Extract individual files or directories from the archive to a target location with fine-grained control over the extraction process.

/**
 * Extract single entry to target path
 * @param {string|ZipEntry} entry - Entry name or ZipEntry object to extract
 * @param {string} targetPath - Target extraction directory
 * @param {boolean} [maintainEntryPath] - Keep original directory structure (default: true)
 * @param {boolean} [overwrite] - Overwrite existing files (default: false)
 * @param {boolean} [keepOriginalPermission] - Preserve file permissions (default: false)
 * @param {string} [outFileName] - Custom output filename (files only)
 * @returns {boolean} True if extraction succeeded
 */
extractEntryTo(entry, targetPath, maintainEntryPath, overwrite, keepOriginalPermission, outFileName);

Usage Examples:

const AdmZip = require("adm-zip");
const zip = new AdmZip("./archive.zip");

// Basic file extraction
zip.extractEntryTo("documents/report.pdf", "./extracted/");
// Result: ./extracted/documents/report.pdf

// Extract file to root without directory structure
zip.extractEntryTo("documents/report.pdf", "./extracted/", false);
// Result: ./extracted/report.pdf

// Extract with custom filename
zip.extractEntryTo("data/config.json", "./settings/", false, true, false, "app-config.json");
// Result: ./settings/app-config.json

// Extract directory and all its contents
zip.extractEntryTo("images/", "./extracted/", true, true);
// Result: ./extracted/images/... (all files in images folder)

// Extract with permission preservation (Unix/Linux)
zip.extractEntryTo("scripts/deploy.sh", "./bin/", false, true, true);
// Preserves executable permissions

// Extract using ZipEntry object
const entry = zip.getEntry("important.txt");
if (entry) {
    zip.extractEntryTo(entry, "./backup/", true, false);
}

Extract Entire Archive

Extract all contents of the archive to a target directory with global options.

/**
 * Extract entire archive to target directory
 * @param {string} targetPath - Target extraction directory
 * @param {boolean} [overwrite] - Overwrite existing files (default: false)
 * @param {boolean} [keepOriginalPermission] - Preserve file permissions (default: false)
 * @param {string|Buffer} [pass] - Password for encrypted archives
 */
extractAllTo(targetPath, overwrite, keepOriginalPermission, pass);

Usage Examples:

const zip = new AdmZip("./archive.zip");

// Basic full extraction
zip.extractAllTo("./extracted/");

// Extract with overwrite enabled
zip.extractAllTo("./extracted/", true);

// Extract preserving permissions
zip.extractAllTo("./extracted/", true, true);

// Extract password-protected archive
zip.extractAllTo("./extracted/", true, false, "secretpassword");

// Extract to absolute path
zip.extractAllTo("/home/user/backup/", true);

// Conditional extraction based on archive contents
const entries = zip.getEntries();
const hasImportantFiles = entries.some(entry => entry.entryName.includes('important'));

if (hasImportantFiles) {
    zip.extractAllTo("./priority-extraction/", true, true);
} else {
    zip.extractAllTo("./regular-extraction/", false);
}

Extract Entire Archive Async

Extract all archive contents asynchronously with callback or Promise support for large archives.

/**
 * Extract entire archive asynchronously
 * @param {string} targetPath - Target extraction directory
 * @param {boolean} [overwrite] - Overwrite existing files (default: false)
 * @param {boolean} [keepOriginalPermission] - Preserve file permissions (default: false)
 * @param {function} [callback] - Callback function (error). If omitted, returns Promise
 * @returns {Promise|void} Promise if no callback provided
 */
extractAllToAsync(targetPath, overwrite, keepOriginalPermission, callback);

Usage Examples:

const zip = new AdmZip("./large-archive.zip");

// Async extraction with callback
zip.extractAllToAsync("./extracted/", true, false, function(error) {
    if (error) {
        console.error("Extraction failed:", error);
    } else {
        console.log("Extraction completed successfully");
    }
});

// Promise-based extraction
zip.extractAllToAsync("./extracted/", true, true)
    .then(() => {
        console.log("Archive extracted successfully");
        // Continue with post-extraction tasks
    })
    .catch(error => {
        console.error("Extraction error:", error);
    });

// Using async/await
async function extractArchive() {
    try {
        await zip.extractAllToAsync("./target/", true, true);
        console.log("Extraction complete");
        
        // Verify extraction
        const fs = require("fs");
        const extractedFiles = fs.readdirSync("./target/");
        console.log(`Extracted ${extractedFiles.length} items`);
        
    } catch (error) {
        console.error("Failed to extract:", error);
    }
}

// Extract with progress monitoring
zip.extractAllToAsync("./progress-extraction/", true, false, function(error) {
    if (error) {
        console.error("Extraction failed:", error.message);
        if (error.message.includes("Unable to create folder")) {
            console.log("Check directory permissions");
        }
        if (error.message.includes("Unable to write file")) {
            console.log("Check available disk space");
        }
    } else {
        console.log("All files extracted successfully");
    }
});

Selective Extraction

Extract specific files based on patterns or conditions using entry filtering.

Usage Examples:

const zip = new AdmZip("./project.zip");
const entries = zip.getEntries();

// Extract only JavaScript files
entries.forEach(entry => {
    if (entry.entryName.endsWith('.js') && !entry.isDirectory) {
        zip.extractEntryTo(entry, "./js-files/", false, true);
    }
});

// Extract files from specific directory
entries.forEach(entry => {
    if (entry.entryName.startsWith('src/') && !entry.isDirectory) {
        zip.extractEntryTo(entry, "./source/", true, true);
    }
});

// Extract files by size (smaller than 1MB)
entries.forEach(entry => {
    if (entry.header.size < 1024 * 1024 && !entry.isDirectory) {
        zip.extractEntryTo(entry, "./small-files/", false, true);
        console.log(`Extracted: ${entry.entryName} (${entry.header.size} bytes)`);
    }
});

// Extract files modified after specific date
const cutoffDate = new Date('2023-01-01');
entries.forEach(entry => {
    if (entry.header.time > cutoffDate && !entry.isDirectory) {
        zip.extractEntryTo(entry, "./recent-files/", true, true);
    }
});

// Extract with custom naming scheme
entries.forEach(entry => {
    if (entry.entryName.endsWith('.log') && !entry.isDirectory) {
        const timestamp = new Date().toISOString().slice(0, 19).replace(/:/g, '-');
        const customName = `${timestamp}_${entry.entryName.replace('/', '_')}`;
        zip.extractEntryTo(entry, "./logs/", false, true, false, customName);
    }
});

Extraction with Validation

Extract files with content validation and error handling.

Usage Examples:

const zip = new AdmZip("./data.zip");
const path = require("path");
const fs = require("fs");

// Extract with content validation
function extractWithValidation(entryName, targetPath) {
    try {
        const entry = zip.getEntry(entryName);
        if (!entry) {
            console.log(`Entry not found: ${entryName}`);
            return false;
        }
        
        // Check if it's a valid file (not too large)
        if (entry.header.size > 100 * 1024 * 1024) { // 100MB limit
            console.log(`File too large: ${entryName} (${entry.header.size} bytes)`);
            return false;
        }
        
        // Extract the file
        const success = zip.extractEntryTo(entry, targetPath, true, true);
        
        if (success) {
            // Verify extraction
            const extractedPath = path.join(targetPath, entry.entryName);
            if (fs.existsSync(extractedPath)) {
                const extractedSize = fs.statSync(extractedPath).size;
                if (extractedSize === entry.header.size) {
                    console.log(`Successfully extracted: ${entryName}`);
                    return true;
                } else {
                    console.log(`Size mismatch for: ${entryName}`);
                    return false;
                }
            }
        }
        
        return false;
    } catch (error) {
        console.error(`Error extracting ${entryName}:`, error);
        return false;
    }
}

// Extract important files with validation
const importantFiles = ['config.json', 'data/users.csv', 'assets/logo.png'];
importantFiles.forEach(file => {
    extractWithValidation(file, './verified-extraction/');
});

// Batch extraction with error tracking
function extractBatch() {
    const entries = zip.getEntries();
    const results = { success: 0, failed: 0, errors: [] };
    
    entries.forEach(entry => {
        if (!entry.isDirectory) {
            try {
                const success = zip.extractEntryTo(entry, './batch-extraction/', true, true);
                if (success) {
                    results.success++;
                } else {
                    results.failed++;
                    results.errors.push(`Failed to extract: ${entry.entryName}`);
                }
            } catch (error) {
                results.failed++;
                results.errors.push(`Error extracting ${entry.entryName}: ${error.message}`);
            }
        }
    });
    
    console.log(`Extraction complete: ${results.success} success, ${results.failed} failed`);
    if (results.errors.length > 0) {
        console.log("Errors:", results.errors);
    }
    
    return results;
}

const batchResults = extractBatch();

Platform-Specific Extraction

Handle different file systems and path conventions during extraction.

Usage Examples:

const zip = new AdmZip("./cross-platform.zip");
const path = require("path");
const os = require("os");

// Platform-aware extraction
function extractForPlatform(targetDir) {
    const entries = zip.getEntries();
    
    entries.forEach(entry => {
        if (!entry.isDirectory) {
            // Normalize path separators for current platform
            let normalizedPath = entry.entryName.replace(/\\/g, '/');
            
            // Handle platform-specific restrictions
            if (os.platform() === 'win32') {
                // Windows: handle reserved names and long paths
                const invalidChars = /[<>:"|?*]/g;
                normalizedPath = normalizedPath.replace(invalidChars, '_');
                
                // Avoid reserved names like CON, PRN, etc.
                const parts = normalizedPath.split('/');
                const fileName = parts[parts.length - 1];
                const reservedNames = ['CON', 'PRN', 'AUX', 'NUL', 'COM1', 'LPT1'];
                if (reservedNames.includes(fileName.toUpperCase().split('.')[0])) {
                    parts[parts.length - 1] = '_' + fileName;
                    normalizedPath = parts.join('/');
                }
            }
            
            // Create safe target path
            const targetPath = path.join(targetDir, normalizedPath);
            const targetDirectory = path.dirname(targetPath);
            
            // Ensure target directory exists
            const fs = require("fs");
            fs.mkdirSync(targetDirectory, { recursive: true });
            
            // Extract with appropriate permissions
            const keepPermissions = os.platform() !== 'win32';
            zip.extractEntryTo(entry, targetDir, true, true, keepPermissions);
        }
    });
}

extractForPlatform('./platform-safe-extraction/');