rollup-plugin-zipdir
Version:
Rollup plugin to zip the entire output directory
62 lines (53 loc) • 2.21 kB
JavaScript
;
var colorette = require('colorette');
var fflate = require('fflate');
var filesize = require('filesize');
var promises = require('node:fs/promises');
var node_path = require('node:path');
var node_util = require('node:util');
/**
* filetree-to-object method I adapted from https://stackoverflow.com/a/64092495/8396479
* @returns {Promise<object>}
*/
async function walkDir(dir) {
async function* tokenize(path) {
yield { dir: path };
for (const dirent of await promises.readdir(path, { withFileTypes: true }))
if (dirent.isDirectory()) yield* tokenize(node_path.join(path, dirent.name));
else yield { file: node_path.join(path, dirent.name) };
yield { endDir: path };
}
const r = [{}];
for await (const e of tokenize(dir))
if (e.dir) r.unshift({});
else if (e.file) r[0][node_path.basename(e.file)] = await promises.readFile(e.file);
else if (e.endDir) r[1][node_path.basename(e.endDir)] = r.shift();
return r[0][node_path.basename(dir)];
}
const parseFileName = function ({ name }) {
if (!!name) return name.endsWith('.zip') ? name : `${name}.zip`;
const { npm_package_name = 'bundle', npm_package_version } = process.env;
return !!npm_package_version ? `${npm_package_name}-${npm_package_version}.zip` : `${npm_package_name}.zip`;
};
function zipDir(options) {
return {
name: 'zipDir',
writeBundle: {
sequential: true,
order: 'post',
handler: async function (_options) {
const [output_dir, input_dir, name] = [
options?.outputDir ?? _options?.dir ?? process.cwd(),
_options?.dir ?? process.cwd(),
parseFileName(options),
];
const data = await node_util.promisify(fflate.zip)(await walkDir(input_dir));
//create dir if it does not exist
await promises.mkdir(`.${node_path.sep}${node_path.relative(process.cwd(), output_dir)}`, { recursive: true });
await promises.writeFile(`.${node_path.sep}${node_path.relative(process.cwd(), output_dir)}${node_path.sep}${name}`, data);
console.log(colorette.green(`zipped to ${colorette.bold(`${output_dir}${node_path.sep}${name}`)} (${filesize.filesize(data.byteLength)})`));
},
},
};
}
module.exports = zipDir;