@darkobits/re-pack
Version:
Utility for managing NPM package contents.
108 lines (107 loc) • 3.8 kB
JavaScript
import path from "path";
import adeiu from "@darkobits/adeiu";
import AsyncLock from "async-lock";
import chokidar from "chokidar";
import fs from "fs-extra";
import * as R from "ramda";
import { DEFAULT_OPTIONS } from "../etc/constants.js";
import log from "./log.js";
import { getPackList, linkPackage } from "./npm.js";
import { getPackageInfo, createPackDir, rewritePackageJson } from "./utils.js";
async function packToPublishDir({ pkgRoot, hoistDir, destDir }) {
const srcFiles = await getPackList(pkgRoot);
await Promise.all(srcFiles.map(async (srcFile) => {
if (path.basename(srcFile) === "package.json") {
return;
}
const resolvedSrcFile = path.resolve(pkgRoot, srcFile);
const resolvedDestFile = path.resolve(destDir, srcFile.replace(new RegExp(`^${hoistDir}${path.sep}`), ""));
log.trace(log.chalk.cyan.dim("packToPublishDir"), `Copy ${log.chalk.green(resolvedSrcFile)} => ${log.chalk.green(resolvedDestFile)}`);
await fs.copy(resolvedSrcFile, resolvedDestFile, { overwrite: true });
}));
}
async function rePack(userOptions) {
const runTime = log.chronograph();
const prefix = log.chalk.cyan.dim("pack");
const opts = R.mergeAll([DEFAULT_OPTIONS, userOptions]);
const resolvedCwd = path.resolve(opts.cwd);
log.verbose(prefix, `cwd: ${log.chalk.green(resolvedCwd)}`);
const resolvedHoistDir = path.resolve(opts.hoistDir);
let [pkg, resolvedPackDir] = await Promise.all([
// Gather information about the host package.
getPackageInfo(resolvedCwd),
// Compute the absolute path to the publish workspace, create the
// directory if needed, and ensure it is empty.
createPackDir(opts.packDir)
]);
let hasLinkedPackage = false;
const preparePackage = async () => {
log.info(prefix, `${log.chalk.bold("Re-packing:")} ${log.chalk.green(pkg.json.name)}`);
if (opts.watch)
pkg = await getPackageInfo(resolvedCwd);
await rewritePackageJson({
pkgJson: pkg.json,
hoistDir: opts.hoistDir,
packDir: resolvedPackDir
});
await packToPublishDir({
pkgRoot: pkg.root,
hoistDir: opts.hoistDir,
destDir: resolvedPackDir
});
if (typeof opts.afterRepack === "function") {
try {
await opts.afterRepack({ fs, packDir: resolvedPackDir });
} catch (err) {
err.message = `${prefix} ${err.message}`;
throw err;
}
}
if (opts.link && !hasLinkedPackage) {
await linkPackage(resolvedPackDir);
hasLinkedPackage = true;
}
};
let watcher;
if (opts.watch) {
const lock = new AsyncLock();
await lock.acquire("re-pack", preparePackage);
const filesToWatch = [
path.resolve(pkg.root, "package.json"),
resolvedHoistDir
];
watcher = chokidar.watch(filesToWatch, {
// cwd: pkg.root,
ignoreInitial: true,
// Ignore source-maps and declaration files.
ignored: ["**/*.js.map", "**/*.d.ts"],
interval: 250
});
watcher.on("ready", () => {
log.info(log.chalk.cyan.dim("watch"), `Watching directory: ${log.chalk.green(resolvedHoistDir)}`);
});
watcher.on("all", (event, changed) => {
log.info(log.chalk.cyan.dim("watch"), `${log.chalk.gray(`${event}:`)} ${log.chalk.green(changed)}`);
void lock.acquire("re-pack", preparePackage);
});
} else {
await preparePackage();
}
return new Promise((resolve) => {
if (opts.watch) {
adeiu(async () => {
await watcher.close();
resolve(resolvedPackDir);
});
return;
}
log.info(prefix, `=> ${log.chalk.gray(resolvedPackDir)}`);
log.info(prefix, log.chalk.bold(`Done in ${log.chalk.yellow(runTime)}.`));
resolve(resolvedPackDir);
});
}
export {
rePack as default,
packToPublishDir
};
//# sourceMappingURL=re-pack.js.map