diff --git a/packages/lib/src/zip_ops.ts b/packages/lib/src/zip_ops.ts index 492d2072..1c96a6b8 100644 --- a/packages/lib/src/zip_ops.ts +++ b/packages/lib/src/zip_ops.ts @@ -3,31 +3,25 @@ import type JSZip from "jszip"; /** * Returns the root folder in the zip file * - * Returns the name of the folder that all files in the zip file is - * contained in. Throws an error if there are multiple such folders. + * Returns the name of the folder that the first entry in the zip file is + * contained in. Throws an error if this is not in a folder. + * + * This matches the logic Factorio uses when determining the folder to look + * for content in a zip file. * * @param zip - Zip to search through. * @returns name of the root folder. */ export function findRoot(zip: JSZip) { - let root: undefined | string; - zip.forEach((relativePath, file) => { - let index = relativePath.indexOf("/"); - if (index === -1) { - throw new Error(`Zip contains file '${relativePath}' in root dir`); - } - - let pathRoot = relativePath.slice(0, index); - if (root === undefined) { - root = pathRoot; - } else if (root !== pathRoot) { - throw new Error("Zip contains multiple root folders"); - } - }); - - if (root === undefined) { + const relativePath = Object.keys(zip.files)[0]; + if (relativePath === undefined) { throw new Error("Empty zip file"); } - return root; + let index = relativePath.indexOf("/"); + if (index === -1) { + throw new Error(`Zip contains file '${relativePath}' in root dir`); + } + + return relativePath.slice(0, index); } diff --git a/test/lib/zip_ops.js b/test/lib/zip_ops.js index 76b28dd1..f9227021 100644 --- a/test/lib/zip_ops.js +++ b/test/lib/zip_ops.js @@ -15,10 +15,10 @@ describe("lib/factorio", function() { assert.equal(findRoot(zip), "root"); }); - it("should throw if files are at the root of the zip", function() { + it("should throw if the first file is at the root of the zip", function() { let zip = new JSZip(); - zip.file("root/foo.txt", ""); zip.file("bar.txt", ""); + zip.file("root/foo.txt", ""); assert.throws( () => findRoot(zip), @@ -26,15 +26,12 @@ describe("lib/factorio", function() { ); }); - it("should throw if there are multiple root dirs", function() { + it("should return directory of first file if there are multiple root dirs", function() { let zip = new JSZip(); zip.file("root-1/foo.txt", ""); zip.file("root-2/bar.txt", ""); - assert.throws( - () => findRoot(zip), - new Error("Zip contains multiple root folders") - ); + assert.equal(findRoot(zip), "root-1"); }); it("should throw if given an empty zip file", function() {