fix: rewrite workspace deps before npm publish

This commit is contained in:
Miguel Ángel
2026-03-26 14:29:27 -04:00
parent 36c91cecbb
commit 98a7211fc1
3 changed files with 89 additions and 0 deletions
+1
View File
@@ -23,6 +23,7 @@ jobs:
registry-url: "https://registry.npmjs.org"
- run: bun install --frozen-lockfile
- run: bun run build
- run: bun run prepare:publish-manifests
- name: Publish @hyperframes/core
continue-on-error: true
+1
View File
@@ -12,6 +12,7 @@
"studio": "bun run --filter @hyperframes/studio dev",
"build:hyperframes-runtime": "bun run --filter @hyperframes/core build:hyperframes-runtime",
"build:hyperframes-runtime:modular": "bun run --filter @hyperframes/core build:hyperframes-runtime:modular",
"prepare:publish-manifests": "tsx scripts/prepare-publish-manifests.ts",
"set-version": "tsx scripts/set-version.ts",
"lint": "oxlint .",
"lint:fix": "oxlint --fix .",
+87
View File
@@ -0,0 +1,87 @@
#!/usr/bin/env tsx
import { readdirSync, readFileSync, writeFileSync } from "fs";
import { join } from "path";
const ROOT = join(import.meta.dirname, "..");
const PACKAGES_DIR = join(ROOT, "packages");
const DEP_FIELDS = [
"dependencies",
"devDependencies",
"peerDependencies",
"optionalDependencies",
] as const;
type DepField = (typeof DEP_FIELDS)[number];
type PackageJson = {
name: string;
version: string;
[key: string]: unknown;
} & Partial<Record<DepField, Record<string, string>>>;
function listPackageJsonPaths() {
return readdirSync(PACKAGES_DIR).map((dir) => join(PACKAGES_DIR, dir, "package.json"));
}
function loadPackageJson(path: string): PackageJson {
return JSON.parse(readFileSync(path, "utf8")) as PackageJson;
}
function resolveWorkspaceSpec(spec: string, version: string) {
const workspaceSpec = spec.slice("workspace:".length);
if (workspaceSpec === "" || workspaceSpec === "*") return version;
if (workspaceSpec === "^") return `^${version}`;
if (workspaceSpec === "~") return `~${version}`;
if (workspaceSpec.startsWith("^")) return `^${version}`;
if (workspaceSpec.startsWith("~")) return `~${version}`;
return workspaceSpec;
}
function main() {
const packageJsonPaths = listPackageJsonPaths();
const packageVersions = new Map(
packageJsonPaths.map((path) => {
const pkg = loadPackageJson(path);
return [pkg.name, pkg.version] as const;
}),
);
let rewrites = 0;
for (const path of packageJsonPaths) {
const pkg = loadPackageJson(path);
let changed = false;
for (const field of DEP_FIELDS) {
const deps = pkg[field];
if (!deps) continue;
for (const [depName, spec] of Object.entries(deps)) {
if (!spec.startsWith("workspace:")) continue;
const depVersion = packageVersions.get(depName);
if (!depVersion) {
throw new Error(`Cannot resolve workspace dependency ${depName} in ${path}`);
}
const resolvedSpec = resolveWorkspaceSpec(spec, depVersion);
if (resolvedSpec === spec) continue;
deps[depName] = resolvedSpec;
rewrites += 1;
changed = true;
console.log(`${pkg.name} ${field} ${depName}: ${spec} -> ${resolvedSpec}`);
}
}
if (changed) {
writeFileSync(path, `${JSON.stringify(pkg, null, 2)}\n`);
}
}
console.log(`Rewrote ${rewrites} workspace dependency reference(s) for publish.`);
}
main();