mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-03 04:38:33 +00:00
feat(cli): add project-pin rewrite helper
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
rewriteProjectPinnedScripts,
|
||||
readPinnedHyperframesVersions,
|
||||
HYPERFRAMES_PIN_RE,
|
||||
} from "./projectPin.js";
|
||||
|
||||
describe("HYPERFRAMES_PIN_RE", () => {
|
||||
it("matches a hyperframes@<semver> token and captures the version", () => {
|
||||
const match = "npx --yes hyperframes@1.2.3 render".match(HYPERFRAMES_PIN_RE);
|
||||
expect(match?.[0]).toBe("hyperframes@1.2.3");
|
||||
});
|
||||
});
|
||||
|
||||
describe("rewriteProjectPinnedScripts", () => {
|
||||
const scripts = {
|
||||
dev: "npx --yes hyperframes@0.7.48 preview",
|
||||
check: "npx --yes hyperframes@0.7.48 check",
|
||||
render: "npx --yes hyperframes@0.7.48 render",
|
||||
unrelated: "echo hi",
|
||||
unpinned: "npx hyperframes render",
|
||||
};
|
||||
|
||||
it("bumps every pinned hyperframes script to the target, leaving others untouched", () => {
|
||||
const r = rewriteProjectPinnedScripts(scripts, "0.7.55");
|
||||
expect(r.changed).toBe(true);
|
||||
expect(r.fromVersions).toEqual(["0.7.48"]);
|
||||
expect(r.scripts.render).toBe("npx --yes hyperframes@0.7.55 render");
|
||||
expect(r.scripts.dev).toBe("npx --yes hyperframes@0.7.55 preview");
|
||||
expect(r.scripts.unrelated).toBe("echo hi");
|
||||
expect(r.scripts.unpinned).toBe("npx hyperframes render");
|
||||
});
|
||||
|
||||
it("is a no-op when already at target", () => {
|
||||
const at = rewriteProjectPinnedScripts(
|
||||
{ render: "npx --yes hyperframes@0.7.55 render" },
|
||||
"0.7.55",
|
||||
);
|
||||
expect(at.changed).toBe(false);
|
||||
expect(at.fromVersions).toEqual([]);
|
||||
});
|
||||
|
||||
it("refuses an unsafe target version (no rewrite)", () => {
|
||||
const r = rewriteProjectPinnedScripts(scripts, "0.7.55; rm -rf /");
|
||||
expect(r.changed).toBe(false);
|
||||
expect(r.scripts.render).toBe(scripts.render);
|
||||
});
|
||||
|
||||
it("reads distinct pinned versions across scripts", () => {
|
||||
expect(
|
||||
readPinnedHyperframesVersions({
|
||||
a: "npx --yes hyperframes@0.7.48 render",
|
||||
b: "npx hyperframes@0.7.50 check",
|
||||
c: "npx hyperframes render",
|
||||
}),
|
||||
).toEqual(["0.7.48", "0.7.50"]);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
import { isSafeVersion } from "./updateCheck.js";
|
||||
|
||||
// Matches `hyperframes@<semver>` as a whole token inside a script string. The
|
||||
// version class mirrors isSafeVersion's semver shape; capturing group 1 is the
|
||||
// old version. `(?=\s|$)` keeps it from matching a longer package name.
|
||||
export const HYPERFRAMES_PIN_RE =
|
||||
/\bhyperframes@([0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?)(?=\s|$)/g;
|
||||
|
||||
export interface PinRewriteResult {
|
||||
changed: boolean;
|
||||
scripts: Record<string, string>;
|
||||
fromVersions: string[];
|
||||
}
|
||||
|
||||
export function readPinnedHyperframesVersions(scripts: Record<string, string>): string[] {
|
||||
const found = new Set<string>();
|
||||
for (const cmd of Object.values(scripts ?? {})) {
|
||||
for (const m of cmd.matchAll(HYPERFRAMES_PIN_RE)) if (m[1]) found.add(m[1]);
|
||||
}
|
||||
return [...found].sort();
|
||||
}
|
||||
|
||||
export function rewriteProjectPinnedScripts(
|
||||
scripts: Record<string, string>,
|
||||
targetVersion: string,
|
||||
): PinRewriteResult {
|
||||
// Never emit an unverified version into a script the user (or npx) will run.
|
||||
if (!isSafeVersion(targetVersion)) {
|
||||
return { changed: false, scripts: { ...scripts }, fromVersions: [] };
|
||||
}
|
||||
const fromVersions = new Set<string>();
|
||||
const next: Record<string, string> = {};
|
||||
for (const [name, cmd] of Object.entries(scripts ?? {})) {
|
||||
next[name] = cmd.replace(HYPERFRAMES_PIN_RE, (_full, version: string) => {
|
||||
if (version !== targetVersion) fromVersions.add(version);
|
||||
return `hyperframes@${targetVersion}`;
|
||||
});
|
||||
}
|
||||
return {
|
||||
changed: [...fromVersions].length > 0,
|
||||
scripts: next,
|
||||
fromVersions: [...fromVersions].sort(),
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user