@dscodotco/theme-cli
Version:
A CLI tool for developing Shopify themes
75 lines (74 loc) • 2.9 kB
JavaScript
/**
* @module utils/zip
* @description Utilities for working with zip files
*/
import AdmZip from "adm-zip";
import fs from "fs";
import path from "path";
import { createLogger } from "./logger.js";
const logger = createLogger("zip");
/**
* Extracts a zip file to a specified directory
*
* @param zipBuffer - The zip file as a buffer
* @param targetDir - The directory to extract to
* @param stripFirstDir - Whether to strip the first directory level from the zip
*
* @example
* ```typescript
* // Extract a zip file
* const zipData = await downloadFile('https://example.com/file.zip');
* extractZip(Buffer.from(zipData), './target-dir');
*
* // Extract a zip file and strip the first directory level
* extractZip(Buffer.from(zipData), './target-dir', true);
* ```
*
* @throws Will throw an error if the extraction fails
*/
export function extractZip(zipBuffer, targetDir, stripFirstDir = false) {
try {
logger.info(`Extracting zip to ${targetDir}`);
const zip = new AdmZip(zipBuffer);
// Create target directory if it doesn't exist
if (!fs.existsSync(targetDir)) {
fs.mkdirSync(targetDir, { recursive: true });
}
if (stripFirstDir) {
// Get zip entries and filter out directories
const entries = zip.getEntries().filter((entry) => !entry.isDirectory);
// Get the first directory name to strip
const firstDirName = entries.length > 0 ? entries[0].entryName.split("/")[0] + "/" : null;
if (firstDirName) {
logger.info(`Stripping first directory: ${firstDirName}`);
for (const entry of entries) {
if (entry.entryName.startsWith(firstDirName)) {
const newEntryName = entry.entryName.substring(firstDirName.length);
if (newEntryName.length > 0) {
const filePath = path.join(targetDir, newEntryName);
const fileDir = path.dirname(filePath);
// Create directory structure if it doesn't exist
if (!fs.existsSync(fileDir)) {
fs.mkdirSync(fileDir, { recursive: true });
}
fs.writeFileSync(filePath, entry.getData());
}
}
}
}
else {
logger.warn("No first directory found to strip, extracting as-is");
zip.extractAllTo(targetDir, true);
}
}
else {
// Extract without stripping
zip.extractAllTo(targetDir, true);
}
logger.success(`Extraction complete to ${targetDir}`);
}
catch (error) {
logger.error(`Extraction failed: ${error.message}`);
throw error;
}
}