@alexaegis/standard-version
Version:
Standard version
165 lines (164 loc) • 7.05 kB
JavaScript
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
let node_path = require("node:path");
let glob = require("glob");
let js_yaml = require("js-yaml");
let node_fs = require("node:fs");
//#region src/workspace/collect-packages.ts
var PACKAGE_JSON_NAME = "package.json";
var PACKAGE_JSON_DEPENDENCY_FIELDS = [
"dependencies",
"devDependencies",
"optionalDependencies",
"peerDependencies"
];
/**
* The functions found in this file are copied from @alexaegis/workspace-tools
* to be a sync, non-esm (globby is only esm) variant that could be invoked
* from a CJS based configuration file.
*
* ? Once standard-version/commit-and-version is migrated to ESM, this can be removed
*/
var collectPackages = () => {
const workspaceRoot = getWorkspaceRoot();
if (!workspaceRoot) throw new Error("not in a workspace");
const pnpmWorkspace = (0, js_yaml.load)((0, node_fs.readFileSync)((0, node_path.join)(workspaceRoot, "pnpm-workspace.yaml"), { encoding: "utf8" }));
const workspacePackageJsonPath = (0, node_path.join)(workspaceRoot, PACKAGE_JSON_NAME);
const workspacePackageJson = JSON.parse((0, node_fs.readFileSync)(workspacePackageJsonPath, { encoding: "utf8" }));
let workspaces = normalizePackageJsonWorkspacesField(workspacePackageJson.workspaces);
if (pnpmWorkspace.packages) workspaces = [...workspaces, ...pnpmWorkspace.packages];
const packagePaths = (0, glob.globSync)(workspaces, {
ignore: ["node_modules"],
cwd: workspaceRoot,
absolute: true
}).filter((path) => (0, node_fs.statSync)(path).isDirectory());
return {
workspacePackage: {
packageKind: "root",
packagePath: workspaceRoot,
packageJson: workspacePackageJson,
packageJsonPath: workspacePackageJsonPath,
workspacePackagePatterns: workspaces,
packagePathFromRootPackage: "."
},
subPackages: packagePaths.map((packagePath) => {
const packageJsonPath = (0, node_path.join)(packagePath, PACKAGE_JSON_NAME);
try {
return {
packageKind: "regular",
packagePath: packagePath.toString(),
packageJsonPath,
packageJson: JSON.parse((0, node_fs.readFileSync)(packageJsonPath, { encoding: "utf8" })),
packagePathFromRootPackage: (0, node_path.relative)(workspaceRoot, (0, node_path.dirname)(packageJsonPath))
};
} catch {
return;
}
}).filter((pkg) => !!pkg)
};
};
var getWorkspaceRoot = (cwd = process.cwd()) => {
return collectPackageJsonPathsUpDirectoryTree(cwd)[0];
};
var collectPackageJsonPathsUpDirectoryTree = (cwd = process.cwd()) => {
return collectPackageJsonPathsUpDirectoryTreeInternal(cwd);
};
var collectPackageJsonPathsUpDirectoryTreeInternal = (cwd, collection = []) => {
const path = (0, node_path.normalize)(cwd);
if ((0, node_fs.existsSync)((0, node_path.join)(path, "package.json"))) collection.unshift(path);
const parentPath = (0, node_path.join)(path, "..");
if (parentPath !== path) return collectPackageJsonPathsUpDirectoryTreeInternal(parentPath, collection);
return collection;
};
var normalizePackageJsonWorkspacesField = (packageJsonWorkspaces) => {
if (Array.isArray(packageJsonWorkspaces)) return packageJsonWorkspaces;
else if (packageJsonWorkspaces) return [...packageJsonWorkspaces.packages ?? [], ...packageJsonWorkspaces.nohoist ?? []];
else return [];
};
//#endregion
//#region src/workspace/generic-updater.ts
/**
* This updater also updates all local dependencies too that were updated
* While it's mainly used for packageJson files, it does not assume the file to
* be valid JSON, so it can be used with any file that contains lines like
* "version": "0.0.0", like examples in readme files.
*
* It also replaces everything that looks like a `packageName@version`
*/
var createGenericUpdater = (packages) => {
return {
readVersion: (contents) => {
return [...contents.matchAll(/"version": "(.*)"/g)][0]?.[1] ?? "0.0.0";
},
writeVersion: (contents, version) => {
return packages.map((localPackage) => localPackage.packageJson.name).filter((name) => !!name).reduce((r, localPackageName) => r.replaceAll(new RegExp(`"${localPackageName}": "(workspace:)([~^])?.*"`, "g"), `"${localPackageName}": "$1$2"`).replaceAll(new RegExp(`"${localPackageName}": "(?!workspace:)([~^])?.*"`, "g"), `"${localPackageName}": "$1${version}"`).replaceAll(new RegExp(`${localPackageName}@([^s\t\n\r]+)`, "g"), `${localPackageName}@${version}`), contents.replace(/"version": ".*"/, `"version": "${version}"`));
}
};
};
//#endregion
//#region src/workspace/package-json-updater.ts
var workspaceDependencyVersionRegexp = /^(workspace:)([\^~])?.*$/g;
var nonWorkspaceDependencyVersionRegexp = /^(?!workspace:)([\^~])?.*$/g;
/**
* This updater also updates all local dependencies too that were updated
* While it's mainly used for packageJson files, it does not assume the file to
* be valid JSON, so it can be used with any file that contains lines like
* "version": "0.0.0", like examples in readme files.
*
* It also replaces everything that looks like a `packageName@version`
*/
var createPackageJsonUpdater = (packages) => {
return {
readVersion: (contents) => {
return [...contents.matchAll(/"version": "(.*)"/g)][0]?.[1] ?? "0.0.0";
},
writeVersion: (contents, version) => {
const packageJson = JSON.parse(contents);
const indent = " ";
const newline = contents.includes("\r\n") ? "\r\n" : "\n";
packageJson.version = version;
for (const localPackageName of packages.map((localPackage) => localPackage.packageJson.name).filter((name) => !!name)) for (const dependencyField of PACKAGE_JSON_DEPENDENCY_FIELDS) {
const dependencies = packageJson[dependencyField];
const localDependency = dependencies?.[localPackageName];
if (dependencies && localDependency) dependencies[localPackageName] = localDependency.replaceAll(workspaceDependencyVersionRegexp, "$1$2").replaceAll(nonWorkspaceDependencyVersionRegexp, `$1${version}`);
}
const json = JSON.stringify(packageJson, void 0, indent);
if (newline === "\r\n") return json.replaceAll("\n", "\r\n") + "\r\n";
return json + "\n";
}
};
};
//#endregion
//#region src/config/config.ts
var createStandardVersionConfig = () => {
const { workspacePackage, subPackages } = collectPackages();
const packageJsonUpdater = createPackageJsonUpdater(subPackages);
const genericUpdater = createGenericUpdater(subPackages);
return {
scripts: {
postbump: "pnpm install",
prechangelog: "git add pnpm-lock.yaml"
},
bumpFiles: [
{
filename: workspacePackage.packageJsonPath,
updater: packageJsonUpdater
},
{
filename: (0, node_path.join)(workspacePackage.packagePath, "readme.md"),
updater: genericUpdater
},
...subPackages.map((pkg) => ({
filename: pkg.packageJsonPath,
updater: packageJsonUpdater
})),
...subPackages.map((pkg) => ({
filename: (0, node_path.join)(pkg.packagePath, "readme.md"),
updater: genericUpdater
}))
]
};
};
//#endregion
exports.collectPackages = collectPackages;
exports.createStandardVersionConfig = createStandardVersionConfig;
//# sourceMappingURL=index.cjs.map