paperclip/packages/adapters/hermes/scripts/prepare-publish-package.mjs

107 lines
3.1 KiB
JavaScript

#!/usr/bin/env node
import { existsSync, readFileSync, readdirSync, renameSync, writeFileSync } from "node:fs";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const scriptDir = dirname(fileURLToPath(import.meta.url));
const packageDir = resolve(scriptDir, "..");
const packageJsonPath = join(packageDir, "package.json");
const devPackageJsonPath = join(packageDir, "package.dev.json");
function findRepoRoot(startDir) {
let current = startDir;
while (current !== dirname(current)) {
if (existsSync(join(current, "pnpm-workspace.yaml"))) {
return current;
}
current = dirname(current);
}
return null;
}
function readJson(filePath) {
return JSON.parse(readFileSync(filePath, "utf8"));
}
function collectWorkspaceVersions(repoRoot) {
const roots = ["packages", "server", "ui", "cli"];
const versions = new Map();
function walk(relDir) {
const absDir = join(repoRoot, relDir);
if (!existsSync(absDir)) return;
const pkgPath = join(absDir, "package.json");
if (existsSync(pkgPath)) {
const pkg = readJson(pkgPath);
if (pkg.name && pkg.version) {
versions.set(pkg.name, pkg.version);
}
return;
}
for (const entry of readdirSync(absDir, { withFileTypes: true })) {
if (!entry.isDirectory()) continue;
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === ".git") continue;
walk(join(relDir, entry.name));
}
}
for (const root of roots) {
walk(root);
}
return versions;
}
function rewriteWorkspaceDeps(deps, workspaceVersions) {
if (!deps) return deps;
return Object.fromEntries(
Object.entries(deps).map(([name, version]) => {
if (typeof version !== "string" || !version.startsWith("workspace:")) {
return [name, version];
}
const resolvedVersion = workspaceVersions.get(name);
if (!resolvedVersion) {
throw new Error(`Cannot resolve workspace dependency ${name} for publish package`);
}
return [name, resolvedVersion];
}),
);
}
const pkg = readJson(packageJsonPath);
const publishConfig = pkg.publishConfig ?? {};
if (existsSync(devPackageJsonPath)) {
throw new Error(`Refusing to overwrite existing ${devPackageJsonPath}`);
}
if (!publishConfig.exports) {
throw new Error(`${pkg.name} is missing publishConfig.exports`);
}
const repoRoot = findRepoRoot(packageDir);
const workspaceVersions = repoRoot ? collectWorkspaceVersions(repoRoot) : new Map();
renameSync(packageJsonPath, devPackageJsonPath);
const nextPublishConfig = { ...publishConfig };
delete nextPublishConfig.exports;
delete nextPublishConfig.main;
delete nextPublishConfig.types;
const publishPkg = {
...pkg,
exports: publishConfig.exports,
main: publishConfig.main,
types: publishConfig.types,
publishConfig: nextPublishConfig,
dependencies: rewriteWorkspaceDeps(pkg.dependencies, workspaceVersions),
optionalDependencies: rewriteWorkspaceDeps(pkg.optionalDependencies, workspaceVersions),
peerDependencies: rewriteWorkspaceDeps(pkg.peerDependencies, workspaceVersions),
};
writeFileSync(packageJsonPath, `${JSON.stringify(publishPkg, null, 2)}\n`);