Skip to content

Commit

Permalink
improved zip support for non-flat folder types
Browse files Browse the repository at this point in the history
inlife committed Nov 18, 2024
1 parent fe5546a commit cbc10a5
Showing 2 changed files with 87 additions and 2 deletions.
21 changes: 19 additions & 2 deletions packages/nexrender-action-decompress/index.js
Original file line number Diff line number Diff line change
@@ -13,7 +13,25 @@ const decompress = (job, settings, asset, action) => {
switch (action.format) {
case 'zip':
const zip = new AdmZip(asset.dest);
zip.extractAllTo(job.workpath, action.overwrite || false);
const entries = zip.getEntries();

// Check if zip has a single root folder
const rootFolders = new Set(entries.map(entry => entry.entryName.split('/')[0]));
const hasSingleRootFolder = rootFolders.size === 1 && entries.every(entry => entry.entryName.startsWith([...rootFolders][0] + '/'));

if (hasSingleRootFolder) {
// Extract all files, removing the root folder from paths
const rootFolder = [...rootFolders][0];
entries.forEach(entry => {
if (!entry.isDirectory) {
const relativePath = entry.entryName.substring(rootFolder.length + 1);
zip.extractEntryTo(entry.entryName, job.workpath, false, true, false, relativePath);
}
});
} else {
// Default behavior - extract all files
zip.extractAllTo(job.workpath, action.overwrite || false);
}
break;
}

@@ -23,7 +41,6 @@ const decompress = (job, settings, asset, action) => {
}

return Promise.resolve();

}

module.exports = (job, settings, action, type) => {
68 changes: 68 additions & 0 deletions packages/nexrender-action-decompress/test.js
Original file line number Diff line number Diff line change
@@ -27,6 +27,11 @@ describe('actions/decompress', function() {
zip2.writeZip(path.join(workpath, 'asset.zip'));

fs.writeFileSync(path.join(workpath, 'non-archive.jpg'), 'hello there 4');

// create "asset with root folder" zip file
const zip3 = new AdmZip();
zip3.addFile("root-folder/nested.jpg", Buffer.from("hello there 5"));
zip3.writeZip(path.join(workpath, 'asset-with-root.zip'));
});

// Cleanup after tests
@@ -39,6 +44,8 @@ describe('actions/decompress', function() {
fs.unlinkSync(path.join(workpath, 'asset.jpg'));
fs.rmdirSync(path.join(workpath, '(Footage)'));
fs.unlinkSync(path.join(workpath, 'non-archive.jpg'));
fs.unlinkSync(path.join(workpath, 'asset-with-root.zip'));
fs.unlinkSync(path.join(workpath, 'nested.jpg'));

// Remove test workpath directory
fs.rmdirSync(workpath);
@@ -110,4 +117,65 @@ describe('actions/decompress', function() {
})
.catch(done);
});

it('should handle zip files with a single root folder', function(done) {
const job = {
workpath: workpath,
template: {
dest: path.join(workpath, 'asset-with-root.zip'),
decompressed: 'nested.jpg',
},
assets: []
};

decompressAction(job, {}, { format: 'zip' }, 'prerender')
.then(() => {
// ensure file is extracted from nested folder
assert(fs.existsSync(path.join(workpath, 'nested.jpg')));
assert.strictEqual(fs.readFileSync(path.join(workpath, 'nested.jpg'), 'utf8'), 'hello there 5');
assert.strictEqual(job.template.dest, path.join(workpath, 'nested.jpg'));
done();
})
.catch(done);
});

it('should automatically flatten zip files with a single root folder', function(done) {
// Create a zip with a single root folder structure
const zipWithRoot = new AdmZip();
zipWithRoot.addFile("root-folder/template2.aep", Buffer.from("nested template"));
zipWithRoot.addFile("root-folder/assets/image.jpg", Buffer.from("nested image"));
zipWithRoot.writeZip(path.join(workpath, 'nested-structure.zip'));

const job = {
workpath: workpath,
template: {
dest: path.join(workpath, 'nested-structure.zip'),
decompressed: 'template2.aep',
},
assets: []
};

decompressAction(job, {}, { format: 'zip' }, 'prerender')
.then(() => {
// Files should be extracted without the root-folder prefix
assert(fs.existsSync(path.join(workpath, 'template2.aep')));
assert(fs.existsSync(path.join(workpath, 'assets', 'image.jpg')));

// Verify content
assert.strictEqual(fs.readFileSync(path.join(workpath, 'template2.aep'), 'utf8'), 'nested template');
assert.strictEqual(fs.readFileSync(path.join(workpath, 'assets', 'image.jpg'), 'utf8'), 'nested image');

// Verify the root folder itself is not created
assert(!fs.existsSync(path.join(workpath, 'root-folder')));

// Cleanup the additional test files
fs.unlinkSync(path.join(workpath, 'template2.aep'));
fs.unlinkSync(path.join(workpath, 'assets', 'image.jpg'));
fs.rmdirSync(path.join(workpath, 'assets'));
fs.unlinkSync(path.join(workpath, 'nested-structure.zip'));

done();
})
.catch(done);
});
});

0 comments on commit cbc10a5

Please sign in to comment.