lerna
Version:
Lerna is a fast, modern build system for managing and publishing multiple JavaScript/TypeScript packages from the same repository
1,364 lines (1,341 loc) • 404 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// libs/core/src/lib/add-dependencies.ts
function addDependencies(projects, projectGraph) {
const projectsLookup = new Set(projects.map((p) => p.name));
const dependencies = projectGraph.localPackageDependencies;
const collected = /* @__PURE__ */ new Set();
projects.forEach((currentNode) => {
if (dependencies[currentNode.name] && dependencies[currentNode.name].length === 0) {
return;
}
const queue2 = [currentNode];
const seen = /* @__PURE__ */ new Set();
while (queue2.length) {
const node = queue2.shift();
dependencies[node.name]?.forEach(({ target }) => {
if (seen.has(target)) {
return;
}
seen.add(target);
if (target === currentNode.name || projectsLookup.has(target)) {
return;
}
const dependencyNode = projectGraph.nodes[target];
collected.add(dependencyNode);
queue2.push(dependencyNode);
});
}
});
return Array.from(/* @__PURE__ */ new Set([...projects, ...collected]));
}
var init_add_dependencies = __esm({
"libs/core/src/lib/add-dependencies.ts"() {
"use strict";
}
});
// libs/core/src/lib/add-dependents.ts
function addDependents(projects, projectGraph) {
const projectsLookup = new Set(projects.map((p) => p.name));
const dependents = (0, import_lodash.flatten)(
Object.values(projectGraph.localPackageDependencies)
).reduce(
(prev, next) => ({
...prev,
[next.target]: [...prev[next.target] || [], next.source]
}),
{}
);
const collected = /* @__PURE__ */ new Set();
projects.forEach((currentNode) => {
if (dependents[currentNode.name] && dependents[currentNode.name].length === 0) {
return;
}
const queue2 = [currentNode];
const seen = /* @__PURE__ */ new Set();
while (queue2.length) {
const node = queue2.shift();
dependents[node.name]?.forEach((dep) => {
if (seen.has(dep)) {
return;
}
seen.add(dep);
if (dep === currentNode.name || projectsLookup.has(dep)) {
return;
}
const dependentNode = projectGraph.nodes[dep];
collected.add(dependentNode);
queue2.push(dependentNode);
});
}
});
return Array.from(/* @__PURE__ */ new Set([...projects, ...collected]));
}
var import_lodash;
var init_add_dependents = __esm({
"libs/core/src/lib/add-dependents.ts"() {
"use strict";
import_lodash = require("lodash");
}
});
// libs/child-process/src/set-exit-code.ts
function setExitCode(code) {
process.exitCode = code;
}
var init_set_exit_code = __esm({
"libs/child-process/src/set-exit-code.ts"() {
"use strict";
}
});
// libs/child-process/src/index.ts
var src_exports = {};
__export(src_exports, {
exec: () => exec,
execSync: () => execSync,
getChildProcessCount: () => getChildProcessCount,
getExitCode: () => getExitCode,
spawn: () => spawn,
spawnStreaming: () => spawnStreaming
});
function exec(command, args, opts) {
const options = Object.assign({ stdio: "pipe" }, opts);
const spawned = spawnProcess(command, args, options);
return wrapError(spawned);
}
function execSync(command, args, opts) {
return import_execa.default.sync(command, args, opts).stdout;
}
function spawn(command, args, opts) {
const options = Object.assign({}, opts, { stdio: "inherit" });
const spawned = spawnProcess(command, args, options);
return wrapError(spawned);
}
function spawnStreaming(command, args, opts, prefix) {
const options = Object.assign({}, opts);
options.stdio = ["ignore", "pipe", "pipe"];
const spawned = spawnProcess(command, args, options);
const stdoutOpts = {};
const stderrOpts = {};
if (prefix) {
const colorName = colorWheel[currentColor % NUM_COLORS];
const color = colorName;
currentColor += 1;
stdoutOpts.tag = `${color.bold(prefix)}:`;
stderrOpts.tag = `${color(prefix)}:`;
}
if (children.size > process.stdout.listenerCount("close")) {
process.stdout.setMaxListeners(children.size);
process.stderr.setMaxListeners(children.size);
}
spawned.stdout?.pipe((0, import_strong_log_transformer.default)(stdoutOpts)).pipe(process.stdout);
spawned.stderr?.pipe((0, import_strong_log_transformer.default)(stderrOpts)).pipe(process.stderr);
return wrapError(spawned);
}
function getChildProcessCount() {
return children.size;
}
function getExitCode(result) {
if (result.exitCode) {
return result.exitCode;
}
if (typeof result.code === "number") {
return result.code;
}
if (typeof result.code === "string") {
return import_os.default.constants.errno[result.code];
}
return process.exitCode;
}
function spawnProcess(command, args, opts) {
const child = (0, import_execa.default)(command, args, opts);
const drain = (exitCode, signal) => {
children.delete(child);
if (signal === void 0) {
child.removeListener("exit", drain);
}
if (exitCode) {
setExitCode(exitCode);
}
};
child.once("exit", drain);
child.once("error", drain);
if (opts?.pkg) {
child.pkg = opts.pkg;
}
children.add(child);
return child;
}
function wrapError(spawned) {
if (spawned.pkg) {
return spawned.catch((err) => {
err.exitCode = getExitCode(err);
err.pkg = spawned.pkg;
throw err;
});
}
return spawned;
}
var import_os, import_chalk, import_execa, import_strong_log_transformer, children, colorWheel, NUM_COLORS, currentColor;
var init_src = __esm({
"libs/child-process/src/index.ts"() {
"use strict";
import_os = __toESM(require("os"));
import_chalk = __toESM(require("chalk"));
import_execa = __toESM(require("execa"));
import_strong_log_transformer = __toESM(require("strong-log-transformer"));
init_set_exit_code();
children = /* @__PURE__ */ new Set();
colorWheel = [import_chalk.default.cyan, import_chalk.default.magenta, import_chalk.default.blue, import_chalk.default.yellow, import_chalk.default.green, import_chalk.default.blueBright];
NUM_COLORS = colorWheel.length;
currentColor = 0;
}
});
// libs/core/src/lib/collect-uncommitted.ts
function collectUncommitted({ cwd, log: log64 = import_npmlog.default }) {
log64.silly("collect-uncommitted", "git status --porcelain (async)");
return childProcess.exec("git", ["status", "--porcelain"], { cwd }).then(({ stdout }) => transformOutput(stdout));
}
var import_chalk2, import_npmlog, childProcess, maybeColorize, cRed, cGreen, replaceStatus, colorizeStats, splitOnNewLine, filterEmpty, o, transformOutput;
var init_collect_uncommitted = __esm({
"libs/core/src/lib/collect-uncommitted.ts"() {
"use strict";
import_chalk2 = __toESM(require("chalk"));
import_npmlog = __toESM(require("npmlog"));
childProcess = (init_src(), __toCommonJS(src_exports));
maybeColorize = (colorize) => (s) => s !== " " ? colorize(s) : s;
cRed = maybeColorize(import_chalk2.default.red);
cGreen = maybeColorize(import_chalk2.default.green);
replaceStatus = (_, maybeGreen, maybeRed) => `${cGreen(maybeGreen)}${cRed(maybeRed)}`;
colorizeStats = (stats) => stats.replace(/^([^U]| )([A-Z]| )/gm, replaceStatus).replace(/^\?{2}|U{2}/gm, cRed("$&"));
splitOnNewLine = (str) => str.split("\n");
filterEmpty = (lines) => lines.filter((line) => line.length);
o = (l, r) => (x) => l(r(x));
transformOutput = o(filterEmpty, o(splitOnNewLine, colorizeStats));
}
});
// libs/core/src/lib/describe-ref.ts
function getArgs(options, includeMergedTags = false) {
let args = [
"describe",
// fallback to short sha if no tags located
"--always",
// always return full result, helps identify existing release
"--long",
// annotate if uncommitted changes present
"--dirty",
// prefer tags originating on upstream branch
"--first-parent"
];
if (options.match) {
args.push("--match", options.match);
}
if (includeMergedTags) {
args = args.filter((arg) => arg !== "--first-parent");
}
return args;
}
function describeRef(options = {}, includeMergedTags) {
const promise = childProcess2.exec("git", getArgs(options, includeMergedTags), options);
return promise.then(({ stdout }) => {
const result = parse(stdout, options.cwd);
import_npmlog2.default.verbose("git-describe", "%j => %j", options && options.match, stdout);
import_npmlog2.default.silly("git-describe", "parsed => %j", result);
return result;
});
}
function describeRefSync(options = {}, includeMergedTags) {
const stdout = childProcess2.execSync("git", getArgs(options, includeMergedTags), options);
const result = parse(stdout, options.cwd);
import_npmlog2.default.silly("git-describe.sync", "%j => %j", stdout, result);
return result;
}
function parse(stdout, cwd) {
const minimalShaRegex = /^([0-9a-f]{7,40})(-dirty)?$/;
if (minimalShaRegex.test(stdout)) {
const [, sha2, isDirty2] = minimalShaRegex.exec(stdout);
const refCount2 = childProcess2.execSync("git", ["rev-list", "--count", sha2], { cwd });
return { refCount: refCount2, sha: sha2, isDirty: Boolean(isDirty2) };
}
const [, lastTagName, lastVersion, refCount, sha, isDirty] = /^((?:.*@)?(.*))-(\d+)-g([0-9a-f]+)(-dirty)?$/.exec(stdout) || [];
return { lastTagName, lastVersion, refCount, sha, isDirty: Boolean(isDirty) };
}
var import_npmlog2, childProcess2;
var init_describe_ref = __esm({
"libs/core/src/lib/describe-ref.ts"() {
"use strict";
import_npmlog2 = __toESM(require("npmlog"));
childProcess2 = (init_src(), __toCommonJS(src_exports));
}
});
// libs/core/src/lib/validation-error.ts
var import_npmlog3, ValidationError;
var init_validation_error = __esm({
"libs/core/src/lib/validation-error.ts"() {
"use strict";
import_npmlog3 = __toESM(require("npmlog"));
ValidationError = class extends Error {
constructor(prefix, message, ...rest) {
super(message);
this.name = "ValidationError";
this.prefix = prefix;
import_npmlog3.default.resume();
import_npmlog3.default.error(prefix, message, ...rest);
}
};
}
});
// libs/core/src/lib/check-working-tree.ts
function checkWorkingTree({ cwd } = {}) {
let chain = Promise.resolve();
chain = chain.then(() => describeRef({ cwd }));
const tests = [
// prevent duplicate versioning
chain.then(throwIfReleased),
// prevent publish of uncommitted changes
chain.then(mkThrowIfUncommitted({ cwd }))
];
return chain.then((result) => Promise.all(tests).then(() => result));
}
function throwIfReleased({ refCount }) {
if (refCount === "0") {
throw new ValidationError(
"ERELEASED",
"The current commit has already been released. Please make new commits before continuing."
);
}
}
function mkThrowIfUncommitted(options = {}) {
return function throwIfUncommitted2(opts) {
if (opts.isDirty) {
return collectUncommitted(options).then((uncommitted) => {
throw new ValidationError("EUNCOMMIT", `${EUNCOMMIT_MSG}${uncommitted.join("\n")}`);
});
}
};
}
var EUNCOMMIT_MSG, throwIfUncommitted;
var init_check_working_tree = __esm({
"libs/core/src/lib/check-working-tree.ts"() {
"use strict";
init_collect_uncommitted();
init_describe_ref();
init_validation_error();
EUNCOMMIT_MSG = "Working tree has uncommitted changes, please commit or remove the following changes before continuing:\n";
throwIfUncommitted = mkThrowIfUncommitted();
}
});
// libs/core/src/lib/cli.ts
function lernaCLI(argv, cwd) {
const cli = (0, import_yargs.default)(argv, cwd);
return globalOptions(cli).usage("Usage: $0 <command> [options]").demandCommand(1, "A command is required. Pass --help to see all available commands and options.").recommendCommands().strict().fail((msg, err) => {
const actual = err || new Error(msg);
if (actual.name !== "ValidationError" && !actual.pkg) {
if (/Did you mean/.test(actual.message)) {
import_npmlog4.default.error("lerna", `Unknown command "${cli.parsed.argv._[0]}"`);
}
import_npmlog4.default.error("lerna", actual.message);
}
cli.exit(actual.exitCode > 0 ? actual.exitCode : 1, actual);
}).alias("h", "help").alias("v", "version").wrap(cli.terminalWidth()).epilogue(import_dedent.default`
When a command fails, all logs are written to lerna-debug.log in the current working directory.
For more information, check out the docs at https://lerna.js.org/docs/introduction
`);
}
function globalOptions(argv) {
const opts = {
loglevel: {
defaultDescription: "info",
describe: "What level of logs to report.",
type: "string"
},
concurrency: {
defaultDescription: String(import_os2.default.cpus().length),
describe: "How many processes to use when lerna parallelizes tasks.",
type: "number",
requiresArg: true
},
"reject-cycles": {
describe: "Fail if a cycle is detected among dependencies.",
type: "boolean"
},
"no-progress": {
describe: "Disable progress bars. (Always off in CI)",
type: "boolean"
},
progress: {
// proxy for --no-progress
hidden: true,
type: "boolean"
},
"no-sort": {
describe: "Do not sort packages topologically (dependencies before dependents).",
type: "boolean"
},
sort: {
// proxy for --no-sort
hidden: true,
type: "boolean"
},
"max-buffer": {
describe: "Set max-buffer (in bytes) for subcommand execution",
type: "number",
requiresArg: true
}
};
const globalKeys = Object.keys(opts).concat(["help", "version"]);
return argv.options(opts).group(globalKeys, "Global Options:").option("ci", {
hidden: true,
type: "boolean"
});
}
var import_dedent, import_npmlog4, import_os2, import_yargs;
var init_cli = __esm({
"libs/core/src/lib/cli.ts"() {
"use strict";
import_dedent = __toESM(require("dedent"));
import_npmlog4 = __toESM(require("npmlog"));
import_os2 = __toESM(require("os"));
import_yargs = __toESM(require("yargs"));
}
});
// libs/core/src/lib/get-packages-for-option.ts
function getPackagesForOption(option) {
let inputs = null;
if (option === true) {
inputs = ["*"];
} else if (typeof option === "string") {
inputs = option.split(",");
} else if (Array.isArray(option)) {
inputs = [...option];
}
return new Set(inputs);
}
var init_get_packages_for_option = __esm({
"libs/core/src/lib/get-packages-for-option.ts"() {
"use strict";
}
});
// libs/core/src/lib/prerelease-id-from-version.ts
function prereleaseIdFromVersion(version) {
return (import_semver.default.prerelease(version) || []).shift();
}
var import_semver;
var init_prerelease_id_from_version = __esm({
"libs/core/src/lib/prerelease-id-from-version.ts"() {
"use strict";
import_semver = __toESM(require("semver"));
}
});
// libs/core/src/lib/project-graph-with-packages.ts
function getPackage(project) {
if (!project.package) {
throw new Error(`Failed attempting to find package for project ${project.name}`);
}
return project.package;
}
var isExternalNpmDependency;
var init_project_graph_with_packages = __esm({
"libs/core/src/lib/project-graph-with-packages.ts"() {
"use strict";
isExternalNpmDependency = (dep) => dep.startsWith("npm:");
}
});
// libs/core/src/lib/collect-updates/has-tags.ts
function hasTags(opts) {
import_npmlog5.default.silly("hasTags");
let result = false;
try {
result = !!childProcess3.execSync("git", ["tag"], opts);
} catch (err) {
import_npmlog5.default.warn("ENOTAGS", "No git tags were reachable from this branch!");
import_npmlog5.default.verbose("hasTags error", err);
}
import_npmlog5.default.verbose("hasTags", result);
return result;
}
var import_npmlog5, childProcess3;
var init_has_tags = __esm({
"libs/core/src/lib/collect-updates/has-tags.ts"() {
"use strict";
import_npmlog5 = __toESM(require("npmlog"));
childProcess3 = (init_src(), __toCommonJS(src_exports));
}
});
// libs/core/src/lib/collect-updates/make-diff-predicate.ts
function makeDiffPredicate(committish, execOpts, ignorePatterns = []) {
const ignoreFilters = new Set(
ignorePatterns.map(
(p) => import_minimatch.default.filter(`!${p}`, {
matchBase: true,
// dotfiles inside ignored directories should also match
dot: true
})
)
);
if (ignoreFilters.size) {
import_npmlog6.default.info("ignoring diff in paths matching", ignorePatterns);
}
return function hasDiffSinceThatIsntIgnored(node) {
const diff = diffSinceIn(committish, getPackage(node).location, execOpts);
if (diff === "") {
import_npmlog6.default.silly("", "no diff found in %s", node.name);
return false;
}
import_npmlog6.default.silly("found diff in", diff);
let changedFiles = diff.split("\n");
if (ignoreFilters.size) {
for (const ignored of ignoreFilters) {
changedFiles = changedFiles.filter(ignored);
}
}
if (changedFiles.length) {
import_npmlog6.default.verbose("filtered diff", changedFiles);
} else {
import_npmlog6.default.verbose("", "no diff found in %s (after filtering)", node.name);
}
return changedFiles.length > 0;
};
}
function diffSinceIn(committish, location, opts) {
const args = ["diff", "--name-only", committish];
const formattedLocation = (0, import_slash.default)((0, import_path.relative)(opts.cwd, location));
if (formattedLocation) {
args.push("--", formattedLocation);
}
import_npmlog6.default.silly("checking diff", formattedLocation);
return execSync2("git", args, opts);
}
var import_minimatch, import_npmlog6, import_path, import_slash, execSync2;
var init_make_diff_predicate = __esm({
"libs/core/src/lib/collect-updates/make-diff-predicate.ts"() {
"use strict";
import_minimatch = __toESM(require("minimatch"));
import_npmlog6 = __toESM(require("npmlog"));
import_path = require("path");
import_slash = __toESM(require("slash"));
init_project_graph_with_packages();
({ execSync: execSync2 } = (init_src(), __toCommonJS(src_exports)));
}
});
// libs/core/src/lib/collect-updates/collect-project-updates.ts
function collectProjectUpdates(filteredProjects, projectGraph, execOpts, commandOptions) {
const {
forcePublish,
conventionalCommits,
forceConventionalGraduate,
conventionalGraduate,
excludeDependents
} = commandOptions;
const useConventionalGraduate = conventionalCommits && (conventionalGraduate || forceConventionalGraduate);
const forced = getPackagesForOption(useConventionalGraduate ? conventionalGraduate : forcePublish);
let committish = commandOptions.since ?? "";
if (hasTags(execOpts)) {
const { sha, refCount, lastTagName } = describeRefSync(execOpts, commandOptions.includeMergedTags);
if (refCount === "0" && forced.size === 0 && !committish) {
import_npmlog7.default.notice("", "Current HEAD is already released, skipping change detection.");
return [];
}
if (commandOptions.canary) {
committish = `${sha}^..${sha}`;
} else if (!committish) {
committish = lastTagName;
}
}
if (forced.size) {
import_npmlog7.default.warn(
useConventionalGraduate ? "conventional-graduate" : "force-publish",
forced.has("*") ? "all packages" : Array.from(forced.values()).join("\n")
);
}
if (useConventionalGraduate) {
if (forced.has("*")) {
import_npmlog7.default.info("", "Graduating all prereleased packages");
} else {
import_npmlog7.default.info("", "Graduating prereleased packages");
}
} else if (!committish || forced.has("*")) {
import_npmlog7.default.info("", "Assuming all packages changed");
return collectProjects(filteredProjects, projectGraph, {
onInclude: (name) => import_npmlog7.default.verbose("updated", name),
excludeDependents
});
}
import_npmlog7.default.info("", `Looking for changed packages since ${committish}`);
const hasDiff = makeDiffPredicate(committish, execOpts, commandOptions.ignoreChanges);
const needsBump = !commandOptions.bump || commandOptions.bump.startsWith("pre") ? () => false : (
/* skip packages that have not been previously prereleased */
(node) => !!prereleaseIdFromVersion(getPackage(node).version)
);
const isForced = (node, name) => !!((forced.has("*") || forced.has(name)) && ((useConventionalGraduate ? prereleaseIdFromVersion(getPackage(node).version) : true) || forceConventionalGraduate));
return collectProjects(filteredProjects, projectGraph, {
isCandidate: (node, name) => isForced(node, name) || needsBump(node) || hasDiff(node),
onInclude: (name) => import_npmlog7.default.verbose("updated", name),
excludeDependents
});
}
function collectProjects(projects, projectGraph, { isCandidate = () => true, onInclude, excludeDependents } = {}) {
const candidates = {};
projects.forEach((node) => {
if (isCandidate(node, getPackage(node).name)) {
candidates[node.name] = node;
}
});
if (!excludeDependents) {
collectDependents(candidates, projectGraph).forEach((node) => candidates[node.name] = node);
}
const updates = [];
projects.forEach((node) => {
if (candidates[node.name]) {
if (onInclude) {
onInclude(getPackage(node).name);
}
updates.push(node);
}
});
return updates;
}
function collectDependents(nodes, projectGraph) {
const dependents = (0, import_lodash2.flatten)(
Object.values(projectGraph.localPackageDependencies)
).reduce(
(prev, next) => ({
...prev,
[next.target]: [...prev[next.target] || [], next.source]
}),
{}
);
const collected = /* @__PURE__ */ new Set();
Object.values(nodes).forEach((currentNode) => {
if (dependents[currentNode.name] && dependents[currentNode.name].length === 0) {
return;
}
const queue2 = [currentNode];
const seen = /* @__PURE__ */ new Set();
while (queue2.length) {
const node = queue2.shift();
dependents[node.name]?.forEach((dep) => {
if (seen.has(dep)) {
return;
}
seen.add(dep);
if (dep === currentNode.name || nodes[dep]) {
return;
}
const dependentNode = projectGraph.nodes[dep];
collected.add(dependentNode);
queue2.push(dependentNode);
});
}
});
return collected;
}
var import_lodash2, import_npmlog7;
var init_collect_project_updates = __esm({
"libs/core/src/lib/collect-updates/collect-project-updates.ts"() {
"use strict";
import_lodash2 = require("lodash");
import_npmlog7 = __toESM(require("npmlog"));
init_describe_ref();
init_get_packages_for_option();
init_prerelease_id_from_version();
init_project_graph_with_packages();
init_has_tags();
init_make_diff_predicate();
}
});
// libs/core/src/lib/collect-updates/index.ts
var init_collect_updates = __esm({
"libs/core/src/lib/collect-updates/index.ts"() {
"use strict";
init_collect_project_updates();
}
});
// libs/core/src/lib/package.ts
function binSafeName({ name, scope }) {
return scope ? name.substring(scope.length + 1) : name;
}
function shallowCopy(json) {
return Object.keys(json).reduce((obj, key) => {
const val = json[key];
if (Array.isArray(val)) {
obj[key] = val.slice();
} else if (val && typeof val === "object") {
obj[key] = Object.assign({}, val);
} else {
obj[key] = val;
}
return obj;
}, {});
}
var import_devkit, import_fs, import_load_json_file, import_npm_package_arg, import_path2, import_write_pkg, PKG, _location, _resolved, _rootPath, _scripts, _contents, Package;
var init_package = __esm({
"libs/core/src/lib/package.ts"() {
"use strict";
import_devkit = require("@nx/devkit");
import_fs = __toESM(require("fs"));
import_load_json_file = __toESM(require("load-json-file"));
import_npm_package_arg = __toESM(require("npm-package-arg"));
import_path2 = __toESM(require("path"));
import_write_pkg = __toESM(require("write-pkg"));
PKG = Symbol("pkg");
_location = Symbol("location");
_resolved = Symbol("resolved");
_rootPath = Symbol("rootPath");
_scripts = Symbol("scripts");
_contents = Symbol("contents");
Package = class _Package {
static {
PKG, _location, _resolved, _rootPath, _scripts, _contents;
}
/**
* Create a Package instance from parameters, possibly reusing existing instance.
* @param ref A path to a package.json file, Package instance, or JSON object
* @param [dir] If `ref` is a JSON object, this is the location of the manifest
*/
static lazy(ref, dir = ".") {
if (typeof ref === "string") {
const location = import_path2.default.resolve(import_path2.default.basename(ref) === "package.json" ? import_path2.default.dirname(ref) : ref);
const manifest = import_load_json_file.default.sync(import_path2.default.join(location, "package.json"));
return new _Package(manifest, location);
}
if ("__isLernaPackage" in ref) {
return ref;
}
return new _Package(ref, dir);
}
constructor(pkg2, location, rootPath = location) {
const resolved = import_npm_package_arg.default.resolve(pkg2.name, `file:${import_path2.default.relative(rootPath, location)}`, rootPath);
this.name = pkg2.name;
this[PKG] = pkg2;
Object.defineProperty(this, PKG, { enumerable: false, writable: true });
this[_location] = location;
this[_resolved] = resolved;
this[_rootPath] = rootPath;
this[_scripts] = { ...pkg2.scripts };
}
// readonly getters
get location() {
return this[_location];
}
get private() {
return Boolean(this[PKG].private);
}
set private(isPrivate) {
this[PKG].private = isPrivate;
}
get resolved() {
return this[_resolved];
}
get rootPath() {
return this[_rootPath];
}
get scripts() {
return this[_scripts];
}
get lernaConfig() {
return this[PKG].lerna;
}
set lernaConfig(config) {
this[PKG].lerna = config;
}
get bin() {
const pkg2 = this[PKG];
return typeof pkg2.bin === "string" ? {
// See note on function implementation
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
[binSafeName(this.resolved)]: pkg2.bin
} : Object.assign({}, pkg2.bin);
}
get binLocation() {
return import_path2.default.join(this.location, "node_modules", ".bin");
}
get manifestLocation() {
return import_path2.default.join(this.location, "package.json");
}
get nodeModulesLocation() {
return import_path2.default.join(this.location, "node_modules");
}
// eslint-disable-next-line class-methods-use-this
get __isLernaPackage() {
return true;
}
// accessors
get version() {
return this[PKG].version;
}
set version(version) {
this[PKG].version = version;
}
get contents() {
if (this[_contents]) {
return this[_contents];
}
if (this[PKG].publishConfig && this[PKG].publishConfig.directory) {
return import_path2.default.join(this.location, this[PKG].publishConfig.directory);
}
return this.location;
}
set contents(subDirectory) {
const _workspaceRoot = process.env["NX_WORKSPACE_ROOT_PATH"] || import_devkit.workspaceRoot;
if (subDirectory.startsWith(_workspaceRoot)) {
this[_contents] = subDirectory;
return;
}
this[_contents] = import_path2.default.join(this.location, subDirectory);
}
// "live" collections
get dependencies() {
return this[PKG].dependencies;
}
get devDependencies() {
return this[PKG].devDependencies;
}
get optionalDependencies() {
return this[PKG].optionalDependencies;
}
get peerDependencies() {
return this[PKG].peerDependencies;
}
/**
* Map-like retrieval of arbitrary values
*/
get(key) {
return this[PKG][key];
}
/**
* Map-like storage of arbitrary values
*/
set(key, val) {
this[PKG][key] = val;
return this;
}
/**
* Provide shallow copy for munging elsewhere
*/
toJSON() {
return shallowCopy(this[PKG]);
}
/**
* Refresh internal state from disk (e.g., changed by external lifecycles)
*/
refresh() {
return (0, import_load_json_file.default)(this.manifestLocation).then((pkg2) => {
this[PKG] = pkg2;
return this;
});
}
/**
* Write manifest changes to disk
* @returns {Promise} resolves when write finished
*/
serialize() {
return (0, import_write_pkg.default)(this.manifestLocation, this[PKG]).then(() => this);
}
/**
* Sync dist manifest version
*/
async syncDistVersion(doSync) {
if (doSync) {
const distPkg = import_path2.default.join(this.contents, "package.json");
if (distPkg !== this.manifestLocation && import_fs.default.existsSync(distPkg)) {
const pkg2 = await (0, import_load_json_file.default)(distPkg);
pkg2.version = this[PKG].version;
await (0, import_write_pkg.default)(distPkg, pkg2);
}
}
return this;
}
getLocalDependency(depName) {
if (this.dependencies && this.dependencies[depName]) {
return {
collection: "dependencies",
spec: this.dependencies[depName]
};
}
if (this.devDependencies && this.devDependencies[depName]) {
return {
collection: "devDependencies",
spec: this.devDependencies[depName]
};
}
if (this.optionalDependencies && this.optionalDependencies[depName]) {
return {
collection: "optionalDependencies",
spec: this.optionalDependencies[depName]
};
}
return null;
}
/**
* Mutate local dependency spec according to type
* @param resolved npa metadata
* @param depVersion semver
* @param savePrefix npm_config_save_prefix
*/
updateLocalDependency(resolved, depVersion, savePrefix, options = { retainWorkspacePrefix: true }) {
const depName = resolved.name;
let depCollection = this.dependencies;
if (!depCollection || !depCollection[depName]) {
depCollection = this.optionalDependencies;
}
if (!depCollection || !depCollection[depName]) {
depCollection = this.devDependencies;
}
if (resolved.workspaceSpec && options.retainWorkspacePrefix) {
if (!resolved.workspaceAlias) {
const workspacePrefix = resolved.workspaceSpec.match(/^(workspace:[*~^]?)/)[0];
depCollection[depName] = `${workspacePrefix}${depVersion}`;
}
} else if (resolved.registry || resolved.type === "directory") {
depCollection[depName] = `${savePrefix}${depVersion}`;
} else if (resolved.gitCommittish) {
const [tagPrefix] = /^\D*/.exec(resolved.gitCommittish);
const { hosted } = resolved;
hosted.committish = `${tagPrefix}${depVersion}`;
depCollection[depName] = hosted.toString({ noGitPlus: false, noCommittish: false });
} else if (resolved.gitRange) {
const { hosted } = resolved;
hosted.committish = `semver:${savePrefix}${depVersion}`;
depCollection[depName] = hosted.toString({ noGitPlus: false, noCommittish: false });
}
}
/**
* Remove the private property, effectively making the package public.
*/
removePrivate() {
delete this[PKG].private;
}
};
}
});
// libs/core/src/lib/project/shallow-extend.ts
function shallowExtend(json, defaults = {}) {
return Object.keys(json).reduce((obj, key) => {
const val = json[key];
if (Array.isArray(val)) {
obj[key] = val.slice();
} else if (val && typeof val === "object") {
obj[key] = shallowExtend(val, obj[key]);
} else {
obj[key] = val;
}
return obj;
}, defaults);
}
var init_shallow_extend = __esm({
"libs/core/src/lib/project/shallow-extend.ts"() {
"use strict";
}
});
// libs/core/src/lib/project/apply-extends.ts
function applyExtends(config, cwd, seen = /* @__PURE__ */ new Set()) {
let defaultConfig = {};
if ("extends" in config) {
let pathToDefault;
try {
pathToDefault = (0, import_resolve_from.default)(cwd, config.extends);
} catch (err) {
throw new ValidationError("ERESOLVED", "Config .extends must be locally-resolvable", err);
}
if (seen.has(pathToDefault)) {
throw new ValidationError("ECIRCULAR", "Config .extends cannot be circular", seen);
}
seen.add(pathToDefault);
defaultConfig = require(pathToDefault);
delete config.extends;
defaultConfig = applyExtends(defaultConfig, import_path3.default.dirname(pathToDefault), seen);
}
return shallowExtend(config, defaultConfig);
}
var import_path3, import_resolve_from;
var init_apply_extends = __esm({
"libs/core/src/lib/project/apply-extends.ts"() {
"use strict";
import_path3 = __toESM(require("path"));
import_resolve_from = __toESM(require("resolve-from"));
init_validation_error();
init_shallow_extend();
}
});
// libs/core/src/lib/project/make-file-finder.ts
function normalize(results) {
return results.map((fp) => import_path4.default.normalize(fp));
}
function getGlobOpts(rootPath, packageConfigs) {
const globOpts = {
cwd: rootPath,
absolute: true,
expandDirectories: false,
followSymbolicLinks: false
};
if (packageConfigs.some((cfg) => cfg.indexOf("**") > -1)) {
if (packageConfigs.some((cfg) => cfg.indexOf("node_modules") > -1)) {
throw new ValidationError(
"EPKGCONFIG",
"An explicit node_modules package path does not allow globstars (**)"
);
}
globOpts.ignore = [
// allow globs like "packages/**",
// but avoid picking up node_modules/**/package.json
"**/node_modules/**"
];
}
return globOpts;
}
function makeFileFinder(rootPath, packageConfigs) {
const globOpts = getGlobOpts(rootPath, packageConfigs);
return (fileName, fileMapper, customGlobOpts) => {
const options = Object.assign({}, customGlobOpts, globOpts);
const promise = (0, import_p_map.default)(
Array.from(packageConfigs).sort(),
(globPath) => {
let chain = (0, import_globby.default)(import_path4.default.posix.join(globPath, fileName), options);
chain = chain.then((results) => results.sort());
chain = chain.then(normalize);
if (fileMapper) {
chain = chain.then(fileMapper);
}
return chain;
},
{ concurrency: 4 }
);
return promise.then((results) => results.reduce((acc, result) => acc.concat(result), []));
};
}
function makeSyncFileFinder(rootPath, packageConfigs) {
const globOpts = getGlobOpts(rootPath, packageConfigs);
return (fileName, fileMapper) => {
const patterns = packageConfigs.map((globPath) => import_path4.default.posix.join(globPath, fileName)).sort();
let results = import_globby.default.sync(patterns, globOpts);
results = normalize(results);
return results.map((res) => fileMapper(res));
};
}
var import_globby, import_p_map, import_path4;
var init_make_file_finder = __esm({
"libs/core/src/lib/project/make-file-finder.ts"() {
"use strict";
import_globby = __toESM(require("globby"));
import_p_map = __toESM(require("p-map"));
import_path4 = __toESM(require("path"));
init_validation_error();
}
});
// libs/core/src/lib/project/index.ts
var import_devkit2, import_cosmiconfig, import_dedent2, import_fs2, import_glob_parent, import_globby2, import_js_yaml, import_load_json_file2, import_npmlog8, import_p_map2, import_path5, LICENSE_GLOB, Project, getPackages, getPackagesSync;
var init_project = __esm({
"libs/core/src/lib/project/index.ts"() {
"use strict";
import_devkit2 = require("@nx/devkit");
import_cosmiconfig = require("cosmiconfig");
import_dedent2 = __toESM(require("dedent"));
import_fs2 = __toESM(require("fs"));
import_glob_parent = __toESM(require("glob-parent"));
import_globby2 = __toESM(require("globby"));
import_js_yaml = require("js-yaml");
import_load_json_file2 = __toESM(require("load-json-file"));
import_npmlog8 = __toESM(require("npmlog"));
import_p_map2 = __toESM(require("p-map"));
import_path5 = __toESM(require("path"));
init_package();
init_validation_error();
init_apply_extends();
init_make_file_finder();
LICENSE_GLOB = "LICEN{S,C}E{,.*}";
Project = class _Project {
/**
* @deprecated Only used in legacy core utilities
* TODO: remove in v8
*/
static getPackages(cwd) {
return new _Project(cwd).getPackages();
}
/**
* @deprecated Only used in legacy core utilities
* TODO: remove in v8
*/
static getPackagesSync(cwd) {
return new _Project(cwd).getPackagesSync();
}
constructor(cwd, options) {
const { config, configNotFound, filepath } = this.#resolveLernaConfig(cwd);
this.config = config;
this.configNotFound = configNotFound || false;
this.rootConfigLocation = filepath;
this.rootPath = import_path5.default.dirname(filepath);
this.manifest = this.#resolveRootPackageJson();
if (this.configNotFound) {
throw new ValidationError("ENOLERNA", "`lerna.json` does not exist, have you run `lerna init`?");
}
if (!options?.skipLernaConfigValidations) {
this.#validateLernaConfig(config);
}
this.packageConfigs = this.#resolvePackageConfigs();
import_npmlog8.default.verbose("rootPath", this.rootPath);
}
get version() {
return this.config.version;
}
set version(val) {
this.config.version = val;
}
get packageParentDirs() {
return this.packageConfigs.map((packagePattern) => (0, import_glob_parent.default)(packagePattern)).map((parentDir) => import_path5.default.resolve(this.rootPath, parentDir));
}
get licensePath() {
let licensePath;
try {
const search = import_globby2.default.sync(LICENSE_GLOB, {
cwd: this.rootPath,
absolute: true,
caseSensitiveMatch: false,
// Project license is always a sibling of the root manifest
deep: 0
});
licensePath = search.shift();
if (licensePath) {
licensePath = import_path5.default.normalize(licensePath);
Object.defineProperty(this, "licensePath", {
value: licensePath
});
}
} catch (err) {
throw new ValidationError(err.name, err.message);
}
return licensePath;
}
get fileFinder() {
const finder = makeFileFinder(this.rootPath, this.packageConfigs);
Object.defineProperty(this, "fileFinder", {
value: finder
});
return finder;
}
/**
* A promise resolving to a list of Package instances
*/
getPackages() {
const mapper = (packageConfigPath) => (0, import_load_json_file2.default)(packageConfigPath).then(
(packageJson) => new Package(packageJson, import_path5.default.dirname(packageConfigPath), this.rootPath)
);
return this.fileFinder("package.json", (filePaths) => (0, import_p_map2.default)(filePaths, mapper, { concurrency: 50 }));
}
/**
* A list of Package instances
*/
getPackagesSync() {
const syncFileFinder = makeSyncFileFinder(this.rootPath, this.packageConfigs);
return syncFileFinder("package.json", (packageConfigPath) => {
return new Package(
import_load_json_file2.default.sync(packageConfigPath),
import_path5.default.dirname(packageConfigPath),
this.rootPath
);
});
}
getPackageLicensePaths() {
return this.fileFinder(LICENSE_GLOB, null, { caseSensitiveMatch: false });
}
isIndependent() {
return this.version === "independent";
}
serializeConfig() {
(0, import_devkit2.writeJsonFile)(this.rootConfigLocation, this.config, { spaces: 2 });
return this.rootConfigLocation;
}
#resolveRootPackageJson() {
try {
const manifestLocation = import_path5.default.join(this.rootPath, "package.json");
const packageJson = import_load_json_file2.default.sync(manifestLocation);
if (!packageJson.name) {
packageJson.name = import_path5.default.basename(import_path5.default.dirname(manifestLocation));
}
return new Package(packageJson, this.rootPath);
} catch (err) {
if (err instanceof Error && err?.name === "JSONError") {
throw new ValidationError(err.name, err.message);
}
throw new ValidationError("ENOPKG", "`package.json` does not exist, have you run `lerna init`?");
}
}
#resolveLernaConfig(cwd) {
try {
const explorer = (0, import_cosmiconfig.cosmiconfigSync)("lerna", {
loaders: {
...import_cosmiconfig.defaultLoaders,
".json": (filepath, content) => {
if (!filepath.endsWith("lerna.json")) {
return import_cosmiconfig.defaultLoaders[".json"](filepath, content);
}
try {
return (0, import_devkit2.parseJson)(content);
} catch (err) {
if (err instanceof Error) {
err.name = "JSONError";
err.message = `Error in: ${filepath}
${err.message}`;
}
throw err;
}
}
},
searchPlaces: ["lerna.json", "package.json"],
transform(obj) {
if (!obj) {
const configNotFoundResult = {
// No need to distinguish between missing and empty,
// saves a lot of noisy guards elsewhere
config: {},
configNotFound: true,
// path.resolve(".", ...) starts from process.cwd()
filepath: import_path5.default.resolve(cwd || ".", "lerna.json")
};
return configNotFoundResult;
}
obj.config = applyExtends(obj.config, import_path5.default.dirname(obj.filepath));
return obj;
}
});
return explorer.search(cwd);
} catch (err) {
if (err.name === "JSONError") {
throw new ValidationError(err.name, err.message);
}
throw err;
}
}
#validateLernaConfig(config) {
if (!this.version) {
throw new ValidationError("ENOVERSION", "Required property version does not exist in `lerna.json`");
}
if (config.useWorkspaces !== void 0) {
throw new ValidationError(
"ECONFIGWORKSPACES",
`The "useWorkspaces" option has been removed. By default lerna will resolve your packages using your package manager's workspaces configuration. Alternatively, you can manually provide a list of package globs to be used instead via the "packages" option in lerna.json.`
);
}
}
#resolvePnpmWorkspaceConfig() {
let config;
try {
const configLocation = import_path5.default.join(this.rootPath, "pnpm-workspace.yaml");
const configContent = import_fs2.default.readFileSync(configLocation, { encoding: "utf8" });
config = (0, import_js_yaml.load)(configContent);
} catch (err) {
if (err.message.includes("ENOENT: no such file or directory")) {
throw new ValidationError(
"ENOENT",
"No pnpm-workspace.yaml found. See https://pnpm.io/workspaces for help configuring workspaces in pnpm."
);
}
throw new ValidationError(err.name, err.message);
}
return config;
}
/**
* By default, the user's package manager workspaces configuration will be used to resolve packages.
* However, they can optionally specify an explicit set of package globs to be used instead.
*
* NOTE: This does not impact the project graph creation process, which will still ultimately use
* the package manager workspaces configuration to construct a full graph, it will only impact which
* of the packages in that graph will be considered when running commands.
*/
#resolvePackageConfigs() {
if (this.config.packages) {
import_npmlog8.default.verbose(
"packageConfigs",
`Explicit "packages" configuration found in lerna.json. Resolving packages using the configured glob(s): ${JSON.stringify(
this.config.packages
)}`
);
return this.config.packages;
}
if (this.config.npmClient === "pnpm") {
import_npmlog8.default.verbose(
"packageConfigs",
'Package manager "pnpm" detected. Resolving packages using `pnpm-workspace.yaml`.'
);
const workspaces2 = this.#resolvePnpmWorkspaceConfig().packages;
if (!workspaces2) {
throw new ValidationError(
"EWORKSPACES",
'No "packages" property found in `pnpm-workspace.yaml`. See https://pnpm.io/workspaces for help configuring workspaces in pnpm.'
);
}
return workspaces2;
}
const workspaces = this.manifest?.get("workspaces");
const isYarnClassicWorkspacesObjectConfig = Boolean(
workspaces && typeof workspaces === "object" && Array.isArray(workspaces.packages)
);
const isValidWorkspacesConfig = Array.isArray(workspaces) || isYarnClassicWorkspacesObjectConfig;
if (!workspaces || !isValidWorkspacesConfig) {
throw new ValidationError(
"EWORKSPACES",
import_dedent2.default`
Lerna is expecting to able to resolve the "workspaces" configuration from your package manager in order to determine what packages to work on, but no "workspaces" config was found.
(A) Did you mean to specify a "packages" config manually in lerna.json instead of using your workspaces config?
(B) Alternatively, if you are using pnpm as your package manager, make sure you set "npmClient": "pnpm" in your lerna.json so that lerna knows to read from the "pnpm-workspace.yaml" file instead of package.json.
See: https://lerna.js.org/docs/getting-started
`
);
}
import_npmlog8.default.verbose("packageConfigs", `Resolving packages based on package.json "workspaces" configuration.`);
if (isYarnClassicWorkspacesObjectConfig) {
return workspaces.packages;
}
return workspaces;
}
};
getPackages = Project.getPackages;
getPackagesSync = Project.getPackagesSync;
}
});
// libs/core/src/lib/write-log-file.ts
function writeLogFile(cwd) {
let logOutput = "";
import_npmlog9.default.record.forEach((m) => {
let pref = [m.id, m.level];
if (m.prefix) {
pref.push(m.prefix);
}
pref = pref.join(" ");
m.message.trim().split(/\r?\n/).map((line) => `${pref} ${line}`.trim()).forEach((line) => {
logOutput += line + import_os3.default.EOL;
});
});
import_write_file_atomic.default