diff --git a/packages/lib/factorio/patch.js b/packages/lib/factorio/patch.js index f96e931a..7f92232f 100644 --- a/packages/lib/factorio/patch.js +++ b/packages/lib/factorio/patch.js @@ -8,6 +8,7 @@ const path = require("path"); const semver = require("semver"); const libHash = require("../hash"); +const { findRoot } = require("../zip_ops"); const knownScenarios = { @@ -21,42 +22,6 @@ const knownScenarios = { }, }; -/** - * 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. - * - * @param {JSZip} zip - Zip to search through. - * @returns {string} name of the root folder. - * @memberof module:lib/factorio - * @private - * @inner - */ -function findRoot(zip) { - let root = null; - 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 === null) { - root = pathRoot; - } else if (root !== pathRoot) { - throw new Error("Zip contains multiple root folders"); - } - }); - - if (root === null) { - throw new Error("Empty zip file"); - } - - return root; -} - - /** * Generates control.lua code for loading the Clusterio modules * @@ -295,7 +260,6 @@ module.exports = { patch, // For testing only - _findRoot: findRoot, _generateLoader: generateLoader, _reorderDependencies: reorderDependencies, }; diff --git a/packages/lib/index.js b/packages/lib/index.js index 0c89ef93..37777950 100644 --- a/packages/lib/index.js +++ b/packages/lib/index.js @@ -18,6 +18,7 @@ const libPrometheus = require("./prometheus"); const libSchema = require("./schema"); const libSharedCommands = require("./shared_commands"); const libUsers = require("./users"); +const libZipOps = require("./zip_ops"); const ExponentialBackoff = require("./ExponentialBackoff"); const RateLimiter = require("./RateLimiter"); @@ -43,6 +44,7 @@ module.exports = { libSchema, libSharedCommands, libUsers, + libZipOps, ExponentialBackoff, RateLimiter, diff --git a/packages/lib/zip_ops.js b/packages/lib/zip_ops.js new file mode 100644 index 00000000..f05c09b5 --- /dev/null +++ b/packages/lib/zip_ops.js @@ -0,0 +1,40 @@ +"use strict"; + +/** + * 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. + * + * @param {JSZip} zip - Zip to search through. + * @returns {string} name of the root folder. + * @memberof module:lib/factorio + * @private + * @inner + */ +function findRoot(zip) { + let root = null; + 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 === null) { + root = pathRoot; + } else if (root !== pathRoot) { + throw new Error("Zip contains multiple root folders"); + } + }); + + if (root === null) { + throw new Error("Empty zip file"); + } + + return root; +} + +module.exports = { + findRoot, +}; diff --git a/test/lib/factorio/patch.js b/test/lib/factorio/patch.js index 00850590..e301d583 100644 --- a/test/lib/factorio/patch.js +++ b/test/lib/factorio/patch.js @@ -8,47 +8,6 @@ const libFactorio = require("@clusterio/lib/factorio"); describe("lib/factorio", function() { - describe("findRoot()", function() { - it("should find the root of a zip", function() { - let zip = new JSZip(); - zip.file("root/foo.txt", ""); - zip.file("root/bar.txt", ""); - - assert.equal(libFactorio._findRoot(zip), "root"); - }); - - it("should throw if files are at the root of the zip", function() { - let zip = new JSZip(); - zip.file("root/foo.txt", ""); - zip.file("bar.txt", ""); - - assert.throws( - () => libFactorio._findRoot(zip), - new Error("Zip contains file 'bar.txt' in root dir") - ); - }); - - it("should throw 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( - () => libFactorio._findRoot(zip), - new Error("Zip contains multiple root folders") - ); - }); - - it("should throw if given an empty zip file", function() { - let zip = new JSZip(); - - assert.throws( - () => libFactorio._findRoot(zip), - new Error("Empty zip file") - ); - }); - }); - describe("generateLoader()", function() { let reference = [ "-- Auto generated scenario module loader created by Clusterio", diff --git a/test/lib/zip_ops.js b/test/lib/zip_ops.js new file mode 100644 index 00000000..622c65ae --- /dev/null +++ b/test/lib/zip_ops.js @@ -0,0 +1,49 @@ +"use strict"; +const assert = require("assert").strict; +const JSZip = require("jszip"); + +const { findRoot } = require("@clusterio/lib/zip_ops"); + + +describe("lib/factorio", function() { + describe("findRoot()", function() { + it("should find the root of a zip", function() { + let zip = new JSZip(); + zip.file("root/foo.txt", ""); + zip.file("root/bar.txt", ""); + + assert.equal(findRoot(zip), "root"); + }); + + it("should throw if files are at the root of the zip", function() { + let zip = new JSZip(); + zip.file("root/foo.txt", ""); + zip.file("bar.txt", ""); + + assert.throws( + () => findRoot(zip), + new Error("Zip contains file 'bar.txt' in root dir") + ); + }); + + it("should throw 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") + ); + }); + + it("should throw if given an empty zip file", function() { + let zip = new JSZip(); + + assert.throws( + () => findRoot(zip), + new Error("Empty zip file") + ); + }); + }); +});