mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-01 19:42:03 +00:00
## Summary - rewrite workspace protocol dependencies to publish-safe semver ranges before the npm publish workflow runs - keep workspace protocol references in source manifests for normal monorepo development - ensure the published `@hyperframes/producer` manifest no longer ships unresolved `workspace:` deps ## Why The internal repo hit a Docker build failure because the published `@hyperframes/producer` metadata still contained `workspace:^` dependencies for `@hyperframes/core` and `@hyperframes/engine`. `npm install` cannot resolve those outside the monorepo, so the published package itself was the root cause. ## Validation - `bun install --frozen-lockfile` - `bun run build:producer` - `bun run prepare:publish-manifests` - `npm pack --workspace packages/core` - `npm pack --workspace packages/engine` - `npm pack --workspace packages/producer` - installed the three tarballs together in a clean temp project with `npm install --ignore-scripts` - extracted the producer tarball and verified its `package.json` contains `^0.1.3` for `@hyperframes/core` and `@hyperframes/engine`, not `workspace:^`
76 lines
2.2 KiB
JavaScript
76 lines
2.2 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
import { execFileSync } from "node:child_process";
|
|
import { existsSync, mkdtempSync, readdirSync, readFileSync, rmSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
import { tmpdir } from "node:os";
|
|
|
|
const ROOT = join(import.meta.dirname, "..");
|
|
const PACKAGES_DIR = join(ROOT, "packages");
|
|
const DEP_FIELDS = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
|
|
|
|
function listWorkspacePackageDirs() {
|
|
return readdirSync(PACKAGES_DIR)
|
|
.map((dir) => join("packages", dir))
|
|
.filter((dir) => existsSync(join(ROOT, dir, "package.json")));
|
|
}
|
|
|
|
function listWorkspaceRefs(pkg) {
|
|
const refs = [];
|
|
|
|
for (const field of DEP_FIELDS) {
|
|
for (const [depName, spec] of Object.entries(pkg[field] || {})) {
|
|
if (String(spec).startsWith("workspace:")) {
|
|
refs.push(`${field}:${depName}=${spec}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
return refs;
|
|
}
|
|
|
|
function parsePackJson(output, workspace) {
|
|
try {
|
|
const parsed = JSON.parse(output);
|
|
return Array.isArray(parsed) ? parsed : [parsed];
|
|
} catch {
|
|
throw new Error(`Could not parse pnpm pack JSON output for ${workspace}`);
|
|
}
|
|
}
|
|
|
|
function main() {
|
|
for (const workspace of listWorkspacePackageDirs()) {
|
|
const sourcePackageJson = JSON.parse(
|
|
readFileSync(join(ROOT, workspace, "package.json"), "utf8"),
|
|
);
|
|
if (listWorkspaceRefs(sourcePackageJson).length === 0) continue;
|
|
|
|
const packDir = mkdtempSync(join(tmpdir(), "hyperframes-pack-"));
|
|
const packOutput = execFileSync("pnpm", ["pack", "--json", "--pack-destination", packDir], {
|
|
cwd: join(ROOT, workspace),
|
|
encoding: "utf8",
|
|
});
|
|
const [{ filename }] = parsePackJson(packOutput, workspace);
|
|
|
|
try {
|
|
const packedPackageJson = execFileSync("tar", ["-xOf", filename, "package/package.json"], {
|
|
cwd: ROOT,
|
|
encoding: "utf8",
|
|
});
|
|
const packedRefs = listWorkspaceRefs(JSON.parse(packedPackageJson));
|
|
|
|
if (packedRefs.length > 0) {
|
|
throw new Error(
|
|
`Packed manifest for ${workspace} still contains workspace refs: ${packedRefs.join(", ")}`,
|
|
);
|
|
}
|
|
|
|
console.log(`Verified ${workspace}: packed manifest is publish-safe.`);
|
|
} finally {
|
|
rmSync(packDir, { force: true, recursive: true });
|
|
}
|
|
}
|
|
}
|
|
|
|
main();
|